summaryrefslogtreecommitdiff
path: root/sd/source/ui/sidebar/CurrentMasterPagesSelector.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sd/source/ui/sidebar/CurrentMasterPagesSelector.cxx')
-rw-r--r--sd/source/ui/sidebar/CurrentMasterPagesSelector.cxx352
1 files changed, 352 insertions, 0 deletions
diff --git a/sd/source/ui/sidebar/CurrentMasterPagesSelector.cxx b/sd/source/ui/sidebar/CurrentMasterPagesSelector.cxx
new file mode 100644
index 000000000000..a5fc7ed9b21c
--- /dev/null
+++ b/sd/source/ui/sidebar/CurrentMasterPagesSelector.cxx
@@ -0,0 +1,352 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "CurrentMasterPagesSelector.hxx"
+#include "PreviewValueSet.hxx"
+#include "ViewShellBase.hxx"
+#include "SidebarShellManager.hxx"
+#include "DrawViewShell.hxx"
+#include "drawdoc.hxx"
+#include "sdpage.hxx"
+#include "MasterPageContainer.hxx"
+#include "MasterPageDescriptor.hxx"
+#include "EventMultiplexer.hxx"
+#include "app.hrc"
+#include "DrawDocShell.hxx"
+#include "res_bmp.hrc"
+#include "sdresid.hxx"
+#include "helpids.h"
+
+#include <vcl/image.hxx>
+#include <svx/svdmodel.hxx>
+#include <sfx2/request.hxx>
+
+#include <set>
+
+
+using namespace ::com::sun::star;
+
+namespace sd { namespace sidebar {
+
+MasterPagesSelector* CurrentMasterPagesSelector::Create (
+ ::Window* pParent,
+ ViewShellBase& rViewShellBase,
+ const cssu::Reference<css::ui::XSidebar>& rxSidebar)
+{
+ SdDrawDocument* pDocument = rViewShellBase.GetDocument();
+ if (pDocument == NULL)
+ return NULL;
+
+ ::boost::shared_ptr<MasterPageContainer> pContainer (new MasterPageContainer());
+
+ MasterPagesSelector* pSelector(
+ new CurrentMasterPagesSelector (
+ pParent,
+ *pDocument,
+ rViewShellBase,
+ pContainer,
+ rxSidebar));
+ pSelector->LateInit();
+ pSelector->SetHelpId( HID_SD_TASK_PANE_PREVIEW_CURRENT );
+
+ return pSelector;
+}
+
+
+
+
+CurrentMasterPagesSelector::CurrentMasterPagesSelector (
+ ::Window* pParent,
+ SdDrawDocument& rDocument,
+ ViewShellBase& rBase,
+ const ::boost::shared_ptr<MasterPageContainer>& rpContainer,
+ const cssu::Reference<css::ui::XSidebar>& rxSidebar)
+ : MasterPagesSelector (pParent, rDocument, rBase, rpContainer, rxSidebar)
+{
+ // For this master page selector only we change the default action for
+ // left clicks.
+ mnDefaultClickAction = SID_TP_APPLY_TO_SELECTED_SLIDES;
+
+ Link aLink (LINK(this,CurrentMasterPagesSelector,EventMultiplexerListener));
+ rBase.GetEventMultiplexer()->AddEventListener(aLink,
+ sd::tools::EventMultiplexerEvent::EID_CURRENT_PAGE
+ | sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_NORMAL
+ | sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_MASTER
+ | sd::tools::EventMultiplexerEvent::EID_PAGE_ORDER
+ | sd::tools::EventMultiplexerEvent::EID_SHAPE_CHANGED
+ | sd::tools::EventMultiplexerEvent::EID_SHAPE_INSERTED
+ | sd::tools::EventMultiplexerEvent::EID_SHAPE_REMOVED);
+}
+
+
+
+
+CurrentMasterPagesSelector::~CurrentMasterPagesSelector (void)
+{
+ if (mrDocument.GetDocSh() != NULL)
+ {
+ EndListening(*mrDocument.GetDocSh());
+ }
+ else
+ {
+ OSL_ASSERT(mrDocument.GetDocSh() != NULL);
+ }
+
+ Link aLink (LINK(this,CurrentMasterPagesSelector,EventMultiplexerListener));
+ mrBase.GetEventMultiplexer()->RemoveEventListener(aLink);
+}
+
+
+
+
+void CurrentMasterPagesSelector::LateInit (void)
+{
+ MasterPagesSelector::LateInit();
+ MasterPagesSelector::Fill();
+ if (mrDocument.GetDocSh() != NULL)
+ {
+ StartListening(*mrDocument.GetDocSh());
+ }
+ else
+ {
+ OSL_ASSERT(mrDocument.GetDocSh() != NULL);
+ }
+}
+
+
+
+
+void CurrentMasterPagesSelector::Fill (ItemList& rItemList)
+{
+ sal_uInt16 nPageCount = mrDocument.GetMasterSdPageCount(PK_STANDARD);
+ SdPage* pMasterPage;
+ // Remember the names of the master pages that have been inserted to
+ // avoid double insertion.
+ ::std::set<String> aMasterPageNames;
+ for (sal_uInt16 nIndex=0; nIndex<nPageCount; nIndex++)
+ {
+ pMasterPage = mrDocument.GetMasterSdPage (nIndex, PK_STANDARD);
+ if (pMasterPage == NULL)
+ continue;
+
+ // Use the name of the master page to avoid duplicate entries.
+ String sName (pMasterPage->GetName());
+ if (aMasterPageNames.find(sName)!=aMasterPageNames.end())
+ continue;
+ aMasterPageNames.insert (sName);
+
+ // Look up the master page in the container and, when it is not yet
+ // in it, insert it.
+ MasterPageContainer::Token aToken = mpContainer->GetTokenForPageObject(pMasterPage);
+ if (aToken == MasterPageContainer::NIL_TOKEN)
+ {
+ SharedMasterPageDescriptor pDescriptor (new MasterPageDescriptor(
+ MasterPageContainer::MASTERPAGE,
+ nIndex,
+ String(),
+ pMasterPage->GetName(),
+ String(),
+ pMasterPage->IsPrecious(),
+ ::boost::shared_ptr<PageObjectProvider>(new ExistingPageProvider(pMasterPage)),
+ ::boost::shared_ptr<PreviewProvider>(new PagePreviewProvider())));
+ aToken = mpContainer->PutMasterPage(pDescriptor);
+ }
+
+ rItemList.push_back(aToken);
+ }
+}
+
+
+
+
+ResId CurrentMasterPagesSelector::GetContextMenuResId (void) const
+{
+ return SdResId(RID_TASKPANE_CURRENT_MASTERPAGESSELECTOR_POPUP);
+}
+
+
+
+
+void CurrentMasterPagesSelector::UpdateSelection (void)
+{
+ // Iterate over all pages and for the selected ones put the name of
+ // their master page into a set.
+ sal_uInt16 nPageCount = mrDocument.GetSdPageCount(PK_STANDARD);
+ SdPage* pPage;
+ ::std::set<String> aNames;
+ sal_uInt16 nIndex;
+ bool bLoop (true);
+ for (nIndex=0; nIndex<nPageCount && bLoop; nIndex++)
+ {
+ pPage = mrDocument.GetSdPage (nIndex, PK_STANDARD);
+ if (pPage != NULL && pPage->IsSelected())
+ {
+ if ( ! pPage->TRG_HasMasterPage())
+ {
+ // One of the pages has no master page. This is an
+ // indicator for that this method is called in the middle of
+ // a document change and that the model is not in a valid
+ // state. Therefore we stop update the selection and wait
+ // for another call to UpdateSelection when the model is
+ // valid again.
+ bLoop = false;
+ }
+ else
+ {
+ SdrPage& rMasterPage (pPage->TRG_GetMasterPage());
+ SdPage* pMasterPage = static_cast<SdPage*>(&rMasterPage);
+ if (pMasterPage != NULL)
+ aNames.insert (pMasterPage->GetName());
+ }
+ }
+ }
+
+ // Find the items for the master pages in the set.
+ sal_uInt16 nItemCount (PreviewValueSet::GetItemCount());
+ for (nIndex=1; nIndex<=nItemCount && bLoop; nIndex++)
+ {
+ String sName (PreviewValueSet::GetItemText (nIndex));
+ if (aNames.find(sName) != aNames.end())
+ {
+ PreviewValueSet::SelectItem (nIndex);
+ }
+ }
+}
+
+
+
+
+void CurrentMasterPagesSelector::ExecuteCommand (const sal_Int32 nCommandId)
+{
+ if (nCommandId == SID_DELETE_MASTER_PAGE)
+ {
+ // Check once again that the master page can safely be deleted,
+ // i.e. is not used.
+ SdPage* pMasterPage = GetSelectedMasterPage();
+ if (pMasterPage != NULL
+ && mrDocument.GetMasterPageUserCount(pMasterPage) == 0)
+ {
+ // Removing the precious flag so that the following call to
+ // RemoveUnnessesaryMasterPages() will remove this master page.
+ pMasterPage->SetPrecious(false);
+ mrDocument.RemoveUnnecessaryMasterPages(pMasterPage, sal_False, sal_True);
+ }
+ }
+ else
+ MasterPagesSelector::ExecuteCommand(nCommandId);
+}
+
+
+
+
+void CurrentMasterPagesSelector::ProcessPopupMenu (Menu& rMenu)
+{
+ // Disable the SID_DELTE_MASTER slot when there is only one master page.
+ if (mrDocument.GetMasterPageUserCount(GetSelectedMasterPage()) > 0)
+ {
+ if (rMenu.GetItemPos(SID_DELETE_MASTER_PAGE) != MENU_ITEM_NOTFOUND)
+ rMenu.EnableItem(SID_DELETE_MASTER_PAGE, sal_False);
+ }
+
+ ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
+ ::boost::dynamic_pointer_cast<DrawViewShell>(mrBase.GetMainViewShell()));
+ if (pDrawViewShell
+ && pDrawViewShell->GetEditMode() == EM_MASTERPAGE)
+ {
+ if (rMenu.GetItemPos(SID_TP_EDIT_MASTER) != MENU_ITEM_NOTFOUND)
+ rMenu.EnableItem(SID_TP_EDIT_MASTER, sal_False);
+ }
+
+ MasterPagesSelector::ProcessPopupMenu(rMenu);
+}
+
+
+
+
+
+
+IMPL_LINK(CurrentMasterPagesSelector,EventMultiplexerListener,
+ sd::tools::EventMultiplexerEvent*,pEvent)
+{
+ if (pEvent != NULL)
+ {
+ switch (pEvent->meEventId)
+ {
+ case sd::tools::EventMultiplexerEvent::EID_CURRENT_PAGE:
+ case sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_NORMAL:
+ case sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_MASTER:
+ case sd::tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION:
+ UpdateSelection();
+ break;
+
+ case sd::tools::EventMultiplexerEvent::EID_PAGE_ORDER:
+ // This is tricky. If a master page is removed, moved, or
+ // added we have to wait until both the notes master page
+ // and the standard master page have been removed, moved,
+ // or added. We do this by looking at the number of master
+ // pages which has to be odd in the consistent state (the
+ // handout master page is always present). If the number is
+ // even we ignore the hint.
+ if (mrBase.GetDocument()->GetMasterPageCount()%2 == 1)
+ MasterPagesSelector::Fill();
+ break;
+
+ case sd::tools::EventMultiplexerEvent::EID_SHAPE_CHANGED:
+ case sd::tools::EventMultiplexerEvent::EID_SHAPE_INSERTED:
+ case sd::tools::EventMultiplexerEvent::EID_SHAPE_REMOVED:
+ InvalidatePreview((const SdPage*)pEvent->mpUserData);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+
+
+void CurrentMasterPagesSelector::NotifyHint (SfxBroadcaster&, const SfxHint& rHint)
+{
+ const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
+ if (pSimpleHint != NULL)
+ {
+ if (pSimpleHint->GetId() == SFX_HINT_DOCCHANGED)
+ {
+ // Is the edit view visible in the center pane?
+ ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
+ ::boost::dynamic_pointer_cast<DrawViewShell>(mrBase.GetMainViewShell()));
+ if (pDrawViewShell.get() != NULL)
+ {
+ // Is the edit view in master page mode?
+ if (pDrawViewShell->GetEditMode() == EM_MASTERPAGE)
+ {
+ // Mark the currently edited master page as precious.
+ SdPage* pCurrentMasterPage = pDrawViewShell->getCurrentPage();
+ if (pCurrentMasterPage != NULL)
+ pCurrentMasterPage->SetPrecious(true);
+ }
+ }
+ }
+ }
+}
+
+
+} } // end of namespace sd::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */