122de8995SAndre Fischer /**************************************************************
222de8995SAndre Fischer  *
322de8995SAndre Fischer  * Licensed to the Apache Software Foundation (ASF) under one
422de8995SAndre Fischer  * or more contributor license agreements.  See the NOTICE file
522de8995SAndre Fischer  * distributed with this work for additional information
622de8995SAndre Fischer  * regarding copyright ownership.  The ASF licenses this file
722de8995SAndre Fischer  * to you under the Apache License, Version 2.0 (the
822de8995SAndre Fischer  * "License"); you may not use this file except in compliance
922de8995SAndre Fischer  * with the License.  You may obtain a copy of the License at
1022de8995SAndre Fischer  *
1122de8995SAndre Fischer  *   http://www.apache.org/licenses/LICENSE-2.0
1222de8995SAndre Fischer  *
1322de8995SAndre Fischer  * Unless required by applicable law or agreed to in writing,
1422de8995SAndre Fischer  * software distributed under the License is distributed on an
1522de8995SAndre Fischer  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1622de8995SAndre Fischer  * KIND, either express or implied.  See the License for the
1722de8995SAndre Fischer  * specific language governing permissions and limitations
1822de8995SAndre Fischer  * under the License.
1922de8995SAndre Fischer  *
2022de8995SAndre Fischer  *************************************************************/
2122de8995SAndre Fischer 
2222de8995SAndre Fischer #include "precompiled_sfx2.hxx"
2322de8995SAndre Fischer 
2422de8995SAndre Fischer #include "SidebarController.hxx"
2522de8995SAndre Fischer #include "Deck.hxx"
26ff12d537SAndre Fischer #include "DeckConfiguration.hxx"
2722de8995SAndre Fischer #include "Panel.hxx"
28b9e67834SAndre Fischer #include "SidebarPanel.hxx"
29ff12d537SAndre Fischer #include "SidebarResource.hxx"
3022de8995SAndre Fischer #include "TitleBar.hxx"
3122de8995SAndre Fischer #include "TabBar.hxx"
32b9e67834SAndre Fischer #include "sfx2/sidebar/Theme.hxx"
33ff12d537SAndre Fischer 
3422de8995SAndre Fischer #include "sfxresid.hxx"
3522de8995SAndre Fischer #include "sfx2/sfxsids.hrc"
36b9e67834SAndre Fischer #include "sfx2/dockwin.hxx"
37ff12d537SAndre Fischer #include "sfxlocal.hrc"
38ff12d537SAndre Fischer #include <vcl/floatwin.hxx>
39ff12d537SAndre Fischer #include <vcl/dockwin.hxx>
40*95a18594SAndre Fischer #include <svl/smplhint.hxx>
41*95a18594SAndre Fischer #include <tools/link.hxx>
42ff12d537SAndre Fischer #include <comphelper/componentfactory.hxx>
43*95a18594SAndre Fischer #include <comphelper/processfactory.hxx>
44ff12d537SAndre Fischer #include <comphelper/componentcontext.hxx>
45ff12d537SAndre Fischer #include <comphelper/namedvaluecollection.hxx>
4622de8995SAndre Fischer 
4722de8995SAndre Fischer #include <com/sun/star/ui/ContextChangeEventMultiplexer.hpp>
4822de8995SAndre Fischer #include <com/sun/star/ui/ContextChangeEventObject.hpp>
49*95a18594SAndre Fischer #include <com/sun/star/ui/XUIElementFactory.hpp>
50*95a18594SAndre Fischer #include <com/sun/star/lang/XInitialization.hpp>
5122de8995SAndre Fischer 
5222de8995SAndre Fischer #include <boost/bind.hpp>
53ff12d537SAndre Fischer #include <boost/foreach.hpp>
5422de8995SAndre Fischer 
5522de8995SAndre Fischer 
5622de8995SAndre Fischer using namespace css;
5722de8995SAndre Fischer using namespace cssu;
58*95a18594SAndre Fischer using ::rtl::OUString;
5922de8995SAndre Fischer 
6022de8995SAndre Fischer #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
6122de8995SAndre Fischer 
62ff12d537SAndre Fischer namespace sfx2 { namespace sidebar {
6322de8995SAndre Fischer 
64ff12d537SAndre Fischer namespace {
65ff12d537SAndre Fischer     enum MenuId
66ff12d537SAndre Fischer     {
67ff12d537SAndre Fischer         MID_UNLOCK_TASK_PANEL = 1,
68ff12d537SAndre Fischer         MID_LOCK_TASK_PANEL,
69ff12d537SAndre Fischer         MID_CUSTOMIZATION,
70ff12d537SAndre Fischer         MID_RESTORE_DEFAULT,
71ff12d537SAndre Fischer         MID_FIRST_PANEL,
72ff12d537SAndre Fischer         MID_FIRST_HIDE = 1000
73ff12d537SAndre Fischer     };
74ff12d537SAndre Fischer }
7522de8995SAndre Fischer 
7622de8995SAndre Fischer 
7722de8995SAndre Fischer SidebarController::SidebarController (
78ff12d537SAndre Fischer     DockingWindow* pParentWindow,
7922de8995SAndre Fischer     const cssu::Reference<css::frame::XFrame>& rxFrame)
8022de8995SAndre Fischer     : SidebarControllerInterfaceBase(m_aMutex),
8122de8995SAndre Fischer       mpCurrentConfiguration(),
8222de8995SAndre Fischer       mpParentWindow(pParentWindow),
83ff12d537SAndre Fischer       mpTabBar(new TabBar(
84ff12d537SAndre Fischer               mpParentWindow,
85ff12d537SAndre Fischer               rxFrame,
86ff12d537SAndre Fischer               ::boost::bind(&SidebarController::SwitchToDeck, this, _1),
87*95a18594SAndre Fischer               ::boost::bind(&SidebarController::ShowPopupMenu, this, _1,_2,_3))),
88*95a18594SAndre Fischer       mxFrame(rxFrame),
89*95a18594SAndre Fischer       maCurrentContext(
90*95a18594SAndre Fischer           EnumContext::Application_Unknown,
91*95a18594SAndre Fischer           EnumContext::Context_Unknown),
92*95a18594SAndre Fischer       msCurrentDeckId(A2S("PropertyDeck")),
93*95a18594SAndre Fischer       maPropertyChangeForwarder(::boost::bind(&SidebarController::BroadcastPropertyChange, this))
9422de8995SAndre Fischer {
9522de8995SAndre Fischer     if (pParentWindow == NULL)
9622de8995SAndre Fischer     {
9722de8995SAndre Fischer         OSL_ASSERT(pParentWindow!=NULL);
9822de8995SAndre Fischer             return;
9922de8995SAndre Fischer     }
10022de8995SAndre Fischer 
10122de8995SAndre Fischer     // Listen for context change events.
10222de8995SAndre Fischer     cssu::Reference<css::ui::XContextChangeEventMultiplexer> xMultiplexer (
10322de8995SAndre Fischer         css::ui::ContextChangeEventMultiplexer::get(
10422de8995SAndre Fischer             ::comphelper::getProcessComponentContext()));
10522de8995SAndre Fischer     if (xMultiplexer.is())
10622de8995SAndre Fischer         xMultiplexer->addContextChangeEventListener(
10722de8995SAndre Fischer             static_cast<css::ui::XContextChangeEventListener*>(this),
108*95a18594SAndre Fischer             mxFrame->getController());
10922de8995SAndre Fischer 
11022de8995SAndre Fischer     // Listen for window events.
11122de8995SAndre Fischer     mpParentWindow->AddEventListener(LINK(this, SidebarController, WindowEventHandler));
112b9e67834SAndre Fischer 
113b9e67834SAndre Fischer     // Listen for theme property changes.
114b9e67834SAndre Fischer     Theme::GetPropertySet()->addPropertyChangeListener(
115b9e67834SAndre Fischer         A2S(""),
116b9e67834SAndre Fischer         static_cast<css::beans::XPropertyChangeListener*>(this));
11722de8995SAndre Fischer }
11822de8995SAndre Fischer 
11922de8995SAndre Fischer 
12022de8995SAndre Fischer 
12122de8995SAndre Fischer 
12222de8995SAndre Fischer SidebarController::~SidebarController (void)
12322de8995SAndre Fischer {
12422de8995SAndre Fischer }
12522de8995SAndre Fischer 
12622de8995SAndre Fischer 
12722de8995SAndre Fischer 
12822de8995SAndre Fischer 
12922de8995SAndre Fischer void SAL_CALL SidebarController::disposing (void)
13022de8995SAndre Fischer {
13122de8995SAndre Fischer     cssu::Reference<css::ui::XContextChangeEventMultiplexer> xMultiplexer (
13222de8995SAndre Fischer         css::ui::ContextChangeEventMultiplexer::get(
13322de8995SAndre Fischer             ::comphelper::getProcessComponentContext()));
13422de8995SAndre Fischer     if (xMultiplexer.is())
13522de8995SAndre Fischer         xMultiplexer->removeAllContextChangeEventListeners(
13622de8995SAndre Fischer             static_cast<css::ui::XContextChangeEventListener*>(this));
13722de8995SAndre Fischer 
13822de8995SAndre Fischer     if (mpParentWindow != NULL)
13922de8995SAndre Fischer     {
14022de8995SAndre Fischer         mpParentWindow->RemoveEventListener(LINK(this, SidebarController, WindowEventHandler));
14122de8995SAndre Fischer         mpParentWindow = NULL;
14222de8995SAndre Fischer     }
143b9e67834SAndre Fischer 
144b9e67834SAndre Fischer     if (mpCurrentConfiguration)
145b9e67834SAndre Fischer     {
146*95a18594SAndre Fischer         mpCurrentConfiguration->Dispose();
147b9e67834SAndre Fischer         mpCurrentConfiguration.reset();
148b9e67834SAndre Fischer     }
149b9e67834SAndre Fischer 
150b9e67834SAndre Fischer     Theme::GetPropertySet()->removePropertyChangeListener(
151b9e67834SAndre Fischer         A2S(""),
152b9e67834SAndre Fischer         static_cast<css::beans::XPropertyChangeListener*>(this));
15322de8995SAndre Fischer }
15422de8995SAndre Fischer 
15522de8995SAndre Fischer 
15622de8995SAndre Fischer 
15722de8995SAndre Fischer 
15822de8995SAndre Fischer void SAL_CALL SidebarController::notifyContextChangeEvent (const css::ui::ContextChangeEventObject& rEvent)
15922de8995SAndre Fischer     throw(cssu::RuntimeException)
16022de8995SAndre Fischer {
161*95a18594SAndre Fischer     UpdateConfigurations(
162*95a18594SAndre Fischer         EnumContext(
163*95a18594SAndre Fischer             rEvent.ApplicationName,
164*95a18594SAndre Fischer             rEvent.ContextName));
16522de8995SAndre Fischer }
16622de8995SAndre Fischer 
16722de8995SAndre Fischer 
16822de8995SAndre Fischer 
16922de8995SAndre Fischer 
17022de8995SAndre Fischer void SAL_CALL SidebarController::disposing (const css::lang::EventObject& rEventObject)
17122de8995SAndre Fischer     throw(cssu::RuntimeException)
17222de8995SAndre Fischer {
173*95a18594SAndre Fischer     (void)rEventObject;
174*95a18594SAndre Fischer 
17522de8995SAndre Fischer     if (mpCurrentConfiguration)
17622de8995SAndre Fischer     {
177*95a18594SAndre Fischer         mpCurrentConfiguration->Dispose();
17822de8995SAndre Fischer         mpCurrentConfiguration.reset();
17922de8995SAndre Fischer     }
18022de8995SAndre Fischer     if (mpTabBar != NULL)
18122de8995SAndre Fischer     {
18222de8995SAndre Fischer         mpTabBar->Hide();
18322de8995SAndre Fischer         delete mpTabBar;
18422de8995SAndre Fischer         mpTabBar = NULL;
18522de8995SAndre Fischer     }
18622de8995SAndre Fischer }
18722de8995SAndre Fischer 
18822de8995SAndre Fischer 
18922de8995SAndre Fischer 
19022de8995SAndre Fischer 
191b9e67834SAndre Fischer void SAL_CALL SidebarController::propertyChange (const css::beans::PropertyChangeEvent& rEvent)
192b9e67834SAndre Fischer     throw(cssu::RuntimeException)
193*95a18594SAndre Fischer {
194*95a18594SAndre Fischer     (void)rEvent;
195*95a18594SAndre Fischer 
196*95a18594SAndre Fischer     maPropertyChangeForwarder.RequestCall();
197*95a18594SAndre Fischer }
198*95a18594SAndre Fischer 
199*95a18594SAndre Fischer 
200*95a18594SAndre Fischer 
201*95a18594SAndre Fischer 
202*95a18594SAndre Fischer void SidebarController::BroadcastPropertyChange (void)
203b9e67834SAndre Fischer {
204b9e67834SAndre Fischer     DataChangedEvent aEvent (DATACHANGED_USER);
205b9e67834SAndre Fischer     mpParentWindow->NotifyAllChilds(aEvent);
206b9e67834SAndre Fischer     mpParentWindow->Invalidate(INVALIDATE_CHILDREN);
207b9e67834SAndre Fischer }
208b9e67834SAndre Fischer 
209b9e67834SAndre Fischer 
210b9e67834SAndre Fischer 
211b9e67834SAndre Fischer 
21222de8995SAndre Fischer void SidebarController::NotifyResize (void)
21322de8995SAndre Fischer {
214*95a18594SAndre Fischer     if (mpTabBar == NULL)
215*95a18594SAndre Fischer     {
216*95a18594SAndre Fischer         OSL_ASSERT(mpTabBar!=NULL);
217*95a18594SAndre Fischer         return;
218*95a18594SAndre Fischer     }
219*95a18594SAndre Fischer 
220*95a18594SAndre Fischer     Window* pParentWindow = mpTabBar->GetParent();
221*95a18594SAndre Fischer 
222*95a18594SAndre Fischer     const sal_Int32 nWidth (pParentWindow->GetSizePixel().Width());
223*95a18594SAndre Fischer     const sal_Int32 nHeight (pParentWindow->GetSizePixel().Height());
224*95a18594SAndre Fischer 
22522de8995SAndre Fischer     if (mpCurrentConfiguration != NULL)
22622de8995SAndre Fischer     {
227*95a18594SAndre Fischer         if (mpCurrentConfiguration->mpDeck==NULL)
228ff12d537SAndre Fischer         {
229*95a18594SAndre Fischer             OSL_ASSERT(mpCurrentConfiguration->mpDeck!=NULL);
230ff12d537SAndre Fischer         }
231ff12d537SAndre Fischer         else
232ff12d537SAndre Fischer         {
233ff12d537SAndre Fischer             mpCurrentConfiguration->mpDeck->SetPosSizePixel(0,0, nWidth-TabBar::GetDefaultWidth(), nHeight);
234ff12d537SAndre Fischer             mpCurrentConfiguration->mpDeck->Show();
235ff12d537SAndre Fischer             mpCurrentConfiguration->mpDeck->RequestLayout();
236ff12d537SAndre Fischer         }
23722de8995SAndre Fischer     }
238*95a18594SAndre Fischer 
239*95a18594SAndre Fischer     mpTabBar->SetPosSizePixel(nWidth-TabBar::GetDefaultWidth(),0,TabBar::GetDefaultWidth(),nHeight);
240*95a18594SAndre Fischer     mpTabBar->Show();
24122de8995SAndre Fischer }
24222de8995SAndre Fischer 
24322de8995SAndre Fischer 
24422de8995SAndre Fischer 
24522de8995SAndre Fischer 
246*95a18594SAndre Fischer void SidebarController::UpdateConfigurations (const EnumContext& rContext)
24722de8995SAndre Fischer {
248*95a18594SAndre Fischer     if (maCurrentContext != rContext)
249*95a18594SAndre Fischer     {
250*95a18594SAndre Fischer         maCurrentContext = rContext;
251*95a18594SAndre Fischer 
252*95a18594SAndre Fischer         // Notify the tab bar about the updated set of decks.
253*95a18594SAndre Fischer         ResourceManager::IdContainer aDeckIds;
254*95a18594SAndre Fischer         ResourceManager::Instance().GetMatchingDecks (
255*95a18594SAndre Fischer             aDeckIds,
256*95a18594SAndre Fischer             rContext,
257*95a18594SAndre Fischer             mxFrame);
258*95a18594SAndre Fischer         mpTabBar->SetDecks(aDeckIds);
259*95a18594SAndre Fischer 
260*95a18594SAndre Fischer         // Check if the current deck is among the matching decks.
261*95a18594SAndre Fischer         bool bCurrentDeckMatches (false);
262*95a18594SAndre Fischer         for (ResourceManager::IdContainer::const_iterator
263*95a18594SAndre Fischer                  iDeck(aDeckIds.begin()),
264*95a18594SAndre Fischer                  iEnd(aDeckIds.end());
265*95a18594SAndre Fischer              iDeck!=iEnd;
266*95a18594SAndre Fischer              ++iDeck)
267*95a18594SAndre Fischer         {
268*95a18594SAndre Fischer             if (iDeck->equals(msCurrentDeckId))
269*95a18594SAndre Fischer             {
270*95a18594SAndre Fischer                 bCurrentDeckMatches = true;
271*95a18594SAndre Fischer                 break;
272*95a18594SAndre Fischer             }
273*95a18594SAndre Fischer         }
274ff12d537SAndre Fischer 
275*95a18594SAndre Fischer         DeckDescriptor const* pDeckDescriptor = NULL;
276*95a18594SAndre Fischer         if ( ! bCurrentDeckMatches)
277*95a18594SAndre Fischer         {
278*95a18594SAndre Fischer             pDeckDescriptor = ResourceManager::Instance().GetBestMatchingDeck(rContext, mxFrame);
279*95a18594SAndre Fischer             msCurrentDeckId = pDeckDescriptor->msId;
280*95a18594SAndre Fischer         }
281*95a18594SAndre Fischer         else
282*95a18594SAndre Fischer             pDeckDescriptor = ResourceManager::Instance().GetDeckDescriptor(msCurrentDeckId);
283*95a18594SAndre Fischer         if (pDeckDescriptor != NULL)
284*95a18594SAndre Fischer         {
285*95a18594SAndre Fischer             msCurrentDeckId = pDeckDescriptor->msId;
286*95a18594SAndre Fischer             SwitchToDeck(*pDeckDescriptor, rContext);
287*95a18594SAndre Fischer         }
288*95a18594SAndre Fischer     }
289ff12d537SAndre Fischer }
290ff12d537SAndre Fischer 
291ff12d537SAndre Fischer 
29222de8995SAndre Fischer 
293ff12d537SAndre Fischer 
294ff12d537SAndre Fischer void SidebarController::SwitchToDeck (
295*95a18594SAndre Fischer     const ::rtl::OUString& rsDeckId)
296ff12d537SAndre Fischer {
297*95a18594SAndre Fischer     if ( ! msCurrentDeckId.equals(rsDeckId))
298*95a18594SAndre Fischer     {
299*95a18594SAndre Fischer         const DeckDescriptor* pDeckDescriptor = ResourceManager::Instance().GetDeckDescriptor(rsDeckId);
300*95a18594SAndre Fischer         if (pDeckDescriptor != NULL)
301*95a18594SAndre Fischer             SwitchToDeck(*pDeckDescriptor, maCurrentContext);
302*95a18594SAndre Fischer     }
30322de8995SAndre Fischer }
30422de8995SAndre Fischer 
30522de8995SAndre Fischer 
30622de8995SAndre Fischer 
30722de8995SAndre Fischer 
308ff12d537SAndre Fischer void SidebarController::SwitchToDeck (
30922de8995SAndre Fischer     const DeckDescriptor& rDeckDescriptor,
310*95a18594SAndre Fischer     const EnumContext& rContext)
31122de8995SAndre Fischer {
312*95a18594SAndre Fischer     if ( ! msCurrentDeckId.equals(rDeckDescriptor.msId))
313*95a18594SAndre Fischer     {
314*95a18594SAndre Fischer         // When the deck changes then destroy the deck and all panels
315*95a18594SAndre Fischer         // and create everything new.
316*95a18594SAndre Fischer         if (mpCurrentConfiguration)
317*95a18594SAndre Fischer         {
318*95a18594SAndre Fischer             mpCurrentConfiguration->Dispose();
319*95a18594SAndre Fischer             mpCurrentConfiguration.reset();
320*95a18594SAndre Fischer         }
321*95a18594SAndre Fischer 
322*95a18594SAndre Fischer         msCurrentDeckId = rDeckDescriptor.msId;
323*95a18594SAndre Fischer     }
324*95a18594SAndre Fischer 
325ff12d537SAndre Fischer     // Determine the panels to display in the deck.
326*95a18594SAndre Fischer     ResourceManager::IdContainer aPanelIds;
327ff12d537SAndre Fischer     ResourceManager::Instance().GetMatchingPanels(
328*95a18594SAndre Fischer         aPanelIds,
329ff12d537SAndre Fischer         rContext,
330ff12d537SAndre Fischer         rDeckDescriptor.msId,
331ff12d537SAndre Fischer         mxFrame);
332ff12d537SAndre Fischer 
333*95a18594SAndre Fischer     // Provide a configuration and Deck object.
334*95a18594SAndre Fischer     if ( ! mpCurrentConfiguration)
33522de8995SAndre Fischer     {
336*95a18594SAndre Fischer         mpCurrentConfiguration.reset(new DeckConfiguration);
337*95a18594SAndre Fischer         mpCurrentConfiguration->mpDeck = new Deck(rDeckDescriptor, mpParentWindow);
338*95a18594SAndre Fischer     }
339ff12d537SAndre Fischer 
340*95a18594SAndre Fischer     // Update the panel list.
341*95a18594SAndre Fischer     const sal_Int32 nNewPanelCount (aPanelIds.size());
342*95a18594SAndre Fischer     ::std::vector<Panel*> aNewPanels;
343*95a18594SAndre Fischer     ::std::vector<Panel*> aCurrentPanels;
344*95a18594SAndre Fischer     if (mpCurrentConfiguration)
345*95a18594SAndre Fischer         aCurrentPanels.swap(mpCurrentConfiguration->maPanels);
346*95a18594SAndre Fischer     aNewPanels.resize(nNewPanelCount);
347*95a18594SAndre Fischer     for (sal_Int32 nIndex=0; nIndex<nNewPanelCount; ++nIndex)
348*95a18594SAndre Fischer     {
349*95a18594SAndre Fischer         const OUString& rsPanelId (aPanelIds[nIndex]);
350*95a18594SAndre Fischer 
351*95a18594SAndre Fischer         // Find the corresponding panel among the currently active
352*95a18594SAndre Fischer         // panels.
353*95a18594SAndre Fischer         ::std::vector<Panel*>::iterator iPanel (::std::find_if(
354*95a18594SAndre Fischer                 aCurrentPanels.begin(),
355*95a18594SAndre Fischer                 aCurrentPanels.end(),
356*95a18594SAndre Fischer                 ::boost::bind(&Panel::HasIdPredicate, _1, ::boost::cref(rsPanelId))));
357*95a18594SAndre Fischer         if (iPanel != aCurrentPanels.end())
358ff12d537SAndre Fischer         {
359*95a18594SAndre Fischer             // Panel already exists in current configuration.  Move it
360*95a18594SAndre Fischer             // to new configuration.
361*95a18594SAndre Fischer             aNewPanels[nIndex] = *iPanel;
362*95a18594SAndre Fischer             aCurrentPanels[::std::distance(aCurrentPanels.begin(), iPanel)] = NULL;
363ff12d537SAndre Fischer         }
364ff12d537SAndre Fischer         else
365ff12d537SAndre Fischer         {
366*95a18594SAndre Fischer             // Panel does not yet exist.  Create it.
367*95a18594SAndre Fischer             aNewPanels[nIndex] = CreatePanel(rsPanelId, mpCurrentConfiguration->mpDeck);
368ff12d537SAndre Fischer         }
36922de8995SAndre Fischer     }
37022de8995SAndre Fischer 
371*95a18594SAndre Fischer     // Destroy all panels that are not used in the new configuration.
372*95a18594SAndre Fischer     for (::std::vector<Panel*>::const_iterator iPanel(aCurrentPanels.begin()),iEnd(aCurrentPanels.end());
373*95a18594SAndre Fischer          iPanel!=iEnd;
374*95a18594SAndre Fischer          ++iPanel)
375*95a18594SAndre Fischer     {
376*95a18594SAndre Fischer         if (*iPanel != NULL)
377*95a18594SAndre Fischer             (*iPanel)->Dispose();
378*95a18594SAndre Fischer     }
379*95a18594SAndre Fischer 
380*95a18594SAndre Fischer     // Activate the deck and the new set of panels.
381*95a18594SAndre Fischer     mpCurrentConfiguration->maPanels.swap(aNewPanels);
382*95a18594SAndre Fischer     mpCurrentConfiguration->mpDeck->SetPosSizePixel(
383*95a18594SAndre Fischer         0,
384*95a18594SAndre Fischer         0,
385*95a18594SAndre Fischer         mpParentWindow->GetSizePixel().Width()-TabBar::GetDefaultWidth(),
386*95a18594SAndre Fischer         mpParentWindow->GetSizePixel().Height());
387*95a18594SAndre Fischer     mpCurrentConfiguration->mpDeck->SetPanels(mpCurrentConfiguration->maPanels);
388*95a18594SAndre Fischer     mpCurrentConfiguration->mpDeck->Show();
389ff12d537SAndre Fischer 
390ff12d537SAndre Fischer     // Tell the tab bar to highlight the button associated with the
391ff12d537SAndre Fischer     // deck.
392ff12d537SAndre Fischer     mpTabBar->HighlightDeck(rDeckDescriptor.msId);
39322de8995SAndre Fischer }
39422de8995SAndre Fischer 
39522de8995SAndre Fischer 
39622de8995SAndre Fischer 
39722de8995SAndre Fischer 
398*95a18594SAndre Fischer Panel* SidebarController::CreatePanel (
399*95a18594SAndre Fischer     const OUString& rsPanelId,
400*95a18594SAndre Fischer     Deck* pDeck) const
401*95a18594SAndre Fischer {
402*95a18594SAndre Fischer     const PanelDescriptor* pPanelDescriptor = ResourceManager::Instance().GetPanelDescriptor(rsPanelId);
403*95a18594SAndre Fischer     if (pPanelDescriptor == NULL)
404*95a18594SAndre Fischer         return NULL;
405*95a18594SAndre Fischer 
406*95a18594SAndre Fischer     // Create the panel which is the parent window of the UIElement.
407*95a18594SAndre Fischer     Panel* pPanel = new Panel(
408*95a18594SAndre Fischer         *pPanelDescriptor,
409*95a18594SAndre Fischer         pDeck,
410*95a18594SAndre Fischer         ::boost::bind(&Deck::RequestLayout,pDeck));
411*95a18594SAndre Fischer 
412*95a18594SAndre Fischer     // Create the XUIElement.
413*95a18594SAndre Fischer     Reference<ui::XUIElement> xUIElement (CreateUIElement(
414*95a18594SAndre Fischer             pPanel->GetComponentInterface(),
415*95a18594SAndre Fischer             pPanelDescriptor->msImplementationURL,
416*95a18594SAndre Fischer             pPanel));
417*95a18594SAndre Fischer     if (xUIElement.is())
418*95a18594SAndre Fischer     {
419*95a18594SAndre Fischer         // Initialize the panel and add it to the active deck.
420*95a18594SAndre Fischer         pPanel->SetUIElement(xUIElement);
421*95a18594SAndre Fischer     }
422*95a18594SAndre Fischer     else
423*95a18594SAndre Fischer     {
424*95a18594SAndre Fischer         delete pPanel;
425*95a18594SAndre Fischer         pPanel = NULL;
426*95a18594SAndre Fischer     }
427*95a18594SAndre Fischer 
428*95a18594SAndre Fischer     return pPanel;
429*95a18594SAndre Fischer }
430*95a18594SAndre Fischer 
431*95a18594SAndre Fischer 
432*95a18594SAndre Fischer 
433*95a18594SAndre Fischer 
434ff12d537SAndre Fischer Reference<ui::XUIElement> SidebarController::CreateUIElement (
435ff12d537SAndre Fischer     const Reference<awt::XWindowPeer>& rxWindow,
436b9e67834SAndre Fischer     const ::rtl::OUString& rsImplementationURL,
437b9e67834SAndre Fischer     Panel* pPanel) const
43822de8995SAndre Fischer {
43922de8995SAndre Fischer     try
44022de8995SAndre Fischer     {
44122de8995SAndre Fischer         const ::comphelper::ComponentContext aComponentContext (::comphelper::getProcessServiceFactory());
44222de8995SAndre Fischer         const Reference<ui::XUIElementFactory> xUIElementFactory (
44322de8995SAndre Fischer             aComponentContext.createComponent("com.sun.star.ui.UIElementFactoryManager"),
44422de8995SAndre Fischer             UNO_QUERY_THROW);
445ff12d537SAndre Fischer 
446ff12d537SAndre Fischer 
447ff12d537SAndre Fischer         // Create the XUIElement.
44822de8995SAndre Fischer         ::comphelper::NamedValueCollection aCreationArguments;
44922de8995SAndre Fischer         aCreationArguments.put("Frame", makeAny(mxFrame));
450ff12d537SAndre Fischer         aCreationArguments.put("ParentWindow", makeAny(rxWindow));
451b9e67834SAndre Fischer         SfxDockingWindow* pSfxDockingWindow = dynamic_cast<SfxDockingWindow*>(mpParentWindow);
452b9e67834SAndre Fischer         if (pSfxDockingWindow != NULL)
453b9e67834SAndre Fischer             aCreationArguments.put("SfxBindings", makeAny(sal_uInt64(&pSfxDockingWindow->GetBindings())));
454*95a18594SAndre Fischer         const Sequence<beans::PropertyValue> aProperties (aCreationArguments.getPropertyValues());
455b9e67834SAndre Fischer         Reference<ui::XUIElement> xUIElement(
456ff12d537SAndre Fischer             xUIElementFactory->createUIElement(
457ff12d537SAndre Fischer                 rsImplementationURL,
458*95a18594SAndre Fischer                 aProperties),
459ff12d537SAndre Fischer             UNO_QUERY_THROW);
460b9e67834SAndre Fischer 
461b9e67834SAndre Fischer         // Provide the new ui element with the XSidebarPanel object
462b9e67834SAndre Fischer         // that gives access to a canvas, screen coordinates of the
463b9e67834SAndre Fischer         // panel or the theme properties.
464b9e67834SAndre Fischer         if (xUIElement.is())
465b9e67834SAndre Fischer         {
466b9e67834SAndre Fischer             Reference<lang::XInitialization> xInitialization(xUIElement->getRealInterface(), UNO_QUERY);
467b9e67834SAndre Fischer             if (xInitialization.is())
468b9e67834SAndre Fischer             {
469b9e67834SAndre Fischer                 Sequence<Any> aArguments (1);
470b9e67834SAndre Fischer                 Reference<ui::XSidebarPanel> xPanel (SidebarPanel::Create(pPanel));
471b9e67834SAndre Fischer                 aArguments[0] = Any(xPanel);
472b9e67834SAndre Fischer                 xInitialization->initialize(aArguments);
473b9e67834SAndre Fischer             }
474b9e67834SAndre Fischer         }
475b9e67834SAndre Fischer 
476b9e67834SAndre Fischer         return xUIElement;
47722de8995SAndre Fischer     }
47822de8995SAndre Fischer     catch(Exception& rException)
47922de8995SAndre Fischer     {
48022de8995SAndre Fischer         OSL_TRACE("caught exception: %s",
48122de8995SAndre Fischer             OUStringToOString(rException.Message, RTL_TEXTENCODING_ASCII_US).getStr());
48222de8995SAndre Fischer         // For some reason we can not create the actual panel.
48322de8995SAndre Fischer         // Probably because its factory was not properly registered.
48422de8995SAndre Fischer         // TODO: provide feedback to developer to better pinpoint the
48522de8995SAndre Fischer         // source of the error.
486ff12d537SAndre Fischer 
487ff12d537SAndre Fischer         return NULL;
48822de8995SAndre Fischer     }
48922de8995SAndre Fischer }
49022de8995SAndre Fischer 
49122de8995SAndre Fischer 
49222de8995SAndre Fischer 
49322de8995SAndre Fischer 
49422de8995SAndre Fischer IMPL_LINK(SidebarController, WindowEventHandler, VclWindowEvent*, pEvent)
49522de8995SAndre Fischer {
49622de8995SAndre Fischer     if (pEvent != NULL)
49722de8995SAndre Fischer     {
49822de8995SAndre Fischer         switch (pEvent->GetId())
49922de8995SAndre Fischer         {
50022de8995SAndre Fischer             case VCLEVENT_WINDOW_GETFOCUS:
50122de8995SAndre Fischer             case VCLEVENT_WINDOW_LOSEFOCUS:
50222de8995SAndre Fischer                 break;
50322de8995SAndre Fischer 
50422de8995SAndre Fischer             case VCLEVENT_WINDOW_SHOW:
50522de8995SAndre Fischer             case VCLEVENT_WINDOW_RESIZE:
50622de8995SAndre Fischer                 NotifyResize();
50722de8995SAndre Fischer                 break;
50822de8995SAndre Fischer 
509ff12d537SAndre Fischer             case VCLEVENT_WINDOW_DATACHANGED:
510ff12d537SAndre Fischer                 // Force an update of deck and tab bar to reflect
511ff12d537SAndre Fischer                 // changes in theme (high contrast mode).
512ff12d537SAndre Fischer                 Theme::HandleDataChange();
513ff12d537SAndre Fischer                 mpParentWindow->Invalidate();
514ff12d537SAndre Fischer                 break;
515ff12d537SAndre Fischer 
51622de8995SAndre Fischer             case SFX_HINT_DYING:
51722de8995SAndre Fischer                 dispose();
51822de8995SAndre Fischer                 break;
51922de8995SAndre Fischer 
52022de8995SAndre Fischer             default:
52122de8995SAndre Fischer                 break;
52222de8995SAndre Fischer         }
52322de8995SAndre Fischer     }
52422de8995SAndre Fischer 
52522de8995SAndre Fischer     return sal_True;
52622de8995SAndre Fischer }
52722de8995SAndre Fischer 
52822de8995SAndre Fischer 
52922de8995SAndre Fischer 
53022de8995SAndre Fischer 
531*95a18594SAndre Fischer void SidebarController::ShowPopupMenu (
532*95a18594SAndre Fischer     const Rectangle& rButtonBox,
533*95a18594SAndre Fischer     const ::std::vector<TabBar::DeckMenuData>& rDeckSelectionData,
534*95a18594SAndre Fischer     const ::std::vector<TabBar::DeckMenuData>& rDeckShowData) const
53522de8995SAndre Fischer {
536*95a18594SAndre Fischer     ::boost::shared_ptr<PopupMenu> pMenu = CreatePopupMenu(rDeckSelectionData, rDeckShowData);
537ff12d537SAndre Fischer     pMenu->SetSelectHdl(LINK(this, SidebarController, OnMenuItemSelected));
538ff12d537SAndre Fischer 
539ff12d537SAndre Fischer     // pass toolbox button rect so the menu can stay open on button up
540ff12d537SAndre Fischer     Rectangle aBox (rButtonBox);
541ff12d537SAndre Fischer     aBox.Move(mpTabBar->GetPosPixel().X(), 0);
542ff12d537SAndre Fischer     pMenu->Execute(mpParentWindow, aBox, POPUPMENU_EXECUTE_DOWN);
54322de8995SAndre Fischer }
54422de8995SAndre Fischer 
54522de8995SAndre Fischer 
54622de8995SAndre Fischer 
54722de8995SAndre Fischer 
548*95a18594SAndre Fischer ::boost::shared_ptr<PopupMenu> SidebarController::CreatePopupMenu (
549*95a18594SAndre Fischer     const ::std::vector<TabBar::DeckMenuData>& rDeckSelectionData,
550*95a18594SAndre Fischer     const ::std::vector<TabBar::DeckMenuData>& rDeckShowData) const
55122de8995SAndre Fischer {
552ff12d537SAndre Fischer     ::boost::shared_ptr<PopupMenu> pMenu (new PopupMenu());
553ff12d537SAndre Fischer     FloatingWindow* pMenuWindow = dynamic_cast<FloatingWindow*>(pMenu->GetWindow());
554ff12d537SAndre Fischer     if (pMenuWindow != NULL)
555ff12d537SAndre Fischer     {
556ff12d537SAndre Fischer         pMenuWindow->SetPopupModeFlags(pMenuWindow->GetPopupModeFlags() | FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE);
557ff12d537SAndre Fischer     }
558ff12d537SAndre Fischer 
559ff12d537SAndre Fischer     SidebarResource aLocalResource;
560ff12d537SAndre Fischer 
561ff12d537SAndre Fischer     // Add one entry for every tool panel element to individually make
562ff12d537SAndre Fischer     // them visible or hide them.
56322de8995SAndre Fischer     {
564*95a18594SAndre Fischer         sal_Int32 nIndex (MID_FIRST_PANEL);
565*95a18594SAndre Fischer         for(::std::vector<TabBar::DeckMenuData>::const_iterator
566*95a18594SAndre Fischer                 iItem(rDeckSelectionData.begin()),
567*95a18594SAndre Fischer                 iEnd(rDeckSelectionData.end());
568*95a18594SAndre Fischer             iItem!=iEnd;
569*95a18594SAndre Fischer             ++iItem)
570*95a18594SAndre Fischer         {
571*95a18594SAndre Fischer             pMenu->InsertItem(nIndex, iItem->get<0>(), MIB_RADIOCHECK);
572*95a18594SAndre Fischer             pMenu->CheckItem(nIndex, iItem->get<2>());
573*95a18594SAndre Fischer             ++nIndex;
574*95a18594SAndre Fischer         }
57522de8995SAndre Fischer     }
57622de8995SAndre Fischer 
577*95a18594SAndre Fischer     pMenu->InsertSeparator();
578*95a18594SAndre Fischer 
579ff12d537SAndre Fischer     // Add entry for docking or un-docking the tool panel.
580ff12d537SAndre Fischer     if (mpParentWindow->IsFloatingMode())
581ff12d537SAndre Fischer         pMenu->InsertItem(MID_LOCK_TASK_PANEL, String(SfxResId(STR_SFX_DOCK)));
582ff12d537SAndre Fischer     else
583ff12d537SAndre Fischer         pMenu->InsertItem(MID_UNLOCK_TASK_PANEL, String(SfxResId(STR_SFX_UNDOCK)));
584ff12d537SAndre Fischer 
585ff12d537SAndre Fischer     // Add sub menu for customization (hiding of deck tabs.)
586ff12d537SAndre Fischer     PopupMenu* pCustomizationMenu = new PopupMenu();
587*95a18594SAndre Fischer     {
588*95a18594SAndre Fischer         sal_Int32 nIndex (MID_FIRST_HIDE);
589*95a18594SAndre Fischer         for(::std::vector<TabBar::DeckMenuData>::const_iterator
590*95a18594SAndre Fischer                 iItem(rDeckShowData.begin()),
591*95a18594SAndre Fischer                 iEnd(rDeckShowData.end());
592*95a18594SAndre Fischer             iItem!=iEnd;
593*95a18594SAndre Fischer             ++iItem)
594*95a18594SAndre Fischer         {
595*95a18594SAndre Fischer             pCustomizationMenu->InsertItem(nIndex, iItem->get<0>(), MIB_CHECKABLE);
596*95a18594SAndre Fischer             pCustomizationMenu->CheckItem(nIndex, iItem->get<2>());
597*95a18594SAndre Fischer             ++nIndex;
598*95a18594SAndre Fischer         }
599*95a18594SAndre Fischer     }
600*95a18594SAndre Fischer 
601ff12d537SAndre Fischer     pCustomizationMenu->InsertSeparator();
602ff12d537SAndre Fischer     pCustomizationMenu->InsertItem(MID_RESTORE_DEFAULT, String(SfxResId(STRING_RESTORE)));
603ff12d537SAndre Fischer 
604ff12d537SAndre Fischer     pMenu->InsertItem(MID_CUSTOMIZATION, String(SfxResId(STRING_CUSTOMIZATION)));
605ff12d537SAndre Fischer     pMenu->SetPopupMenu(MID_CUSTOMIZATION, pCustomizationMenu);
606ff12d537SAndre Fischer 
607ff12d537SAndre Fischer     pMenu->RemoveDisabledEntries(sal_False, sal_False);
608ff12d537SAndre Fischer 
609ff12d537SAndre Fischer     return pMenu;
61022de8995SAndre Fischer }
61122de8995SAndre Fischer 
61222de8995SAndre Fischer 
61322de8995SAndre Fischer 
61422de8995SAndre Fischer 
615ff12d537SAndre Fischer IMPL_LINK(SidebarController, OnMenuItemSelected, Menu*, pMenu)
61622de8995SAndre Fischer {
617ff12d537SAndre Fischer     if (pMenu == NULL)
618ff12d537SAndre Fischer     {
619ff12d537SAndre Fischer         OSL_ENSURE(pMenu!=NULL, "TaskPaneController_Impl::OnMenuItemSelected: illegal menu!");
620ff12d537SAndre Fischer         return 0;
621ff12d537SAndre Fischer     }
62222de8995SAndre Fischer 
623ff12d537SAndre Fischer     pMenu->Deactivate();
624ff12d537SAndre Fischer     const sal_Int32 nIndex (pMenu->GetCurItemId());
625ff12d537SAndre Fischer     switch (nIndex)
62622de8995SAndre Fischer     {
627ff12d537SAndre Fischer         case MID_UNLOCK_TASK_PANEL:
628ff12d537SAndre Fischer             mpParentWindow->SetFloatingMode(sal_True);
629ff12d537SAndre Fischer             break;
630ff12d537SAndre Fischer 
631ff12d537SAndre Fischer         case MID_LOCK_TASK_PANEL:
632ff12d537SAndre Fischer             mpParentWindow->SetFloatingMode(sal_False);
633ff12d537SAndre Fischer             break;
634ff12d537SAndre Fischer 
635ff12d537SAndre Fischer         case MID_RESTORE_DEFAULT:
636ff12d537SAndre Fischer             mpTabBar->RestoreHideFlags();
637ff12d537SAndre Fischer             break;
638ff12d537SAndre Fischer 
639ff12d537SAndre Fischer         default:
640ff12d537SAndre Fischer         {
641ff12d537SAndre Fischer             try
642ff12d537SAndre Fischer             {
643ff12d537SAndre Fischer                 if (nIndex >= MID_FIRST_PANEL && nIndex<MID_FIRST_HIDE)
644*95a18594SAndre Fischer                     SwitchToDeck(mpTabBar->GetDeckIdForIndex(nIndex - MID_FIRST_PANEL));
645ff12d537SAndre Fischer                 else if (nIndex >=MID_FIRST_HIDE)
646ff12d537SAndre Fischer                     mpTabBar->ToggleHideFlag(nIndex-MID_FIRST_HIDE);
647ff12d537SAndre Fischer             }
648ff12d537SAndre Fischer             catch (RuntimeException&)
649ff12d537SAndre Fischer             {
650ff12d537SAndre Fischer             }
651ff12d537SAndre Fischer         }
652ff12d537SAndre Fischer         break;
65322de8995SAndre Fischer     }
654ff12d537SAndre Fischer 
655ff12d537SAndre Fischer     return 1;
65622de8995SAndre Fischer }
65722de8995SAndre Fischer 
65822de8995SAndre Fischer 
659ff12d537SAndre Fischer 
660ff12d537SAndre Fischer 
661ff12d537SAndre Fischer 
662ff12d537SAndre Fischer } } // end of namespace sfx2::sidebar
663