summaryrefslogtreecommitdiff
path: root/sd/source/ui/slidesorter/controller/SlsClipboard.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sd/source/ui/slidesorter/controller/SlsClipboard.cxx')
-rw-r--r--sd/source/ui/slidesorter/controller/SlsClipboard.cxx778
1 files changed, 778 insertions, 0 deletions
diff --git a/sd/source/ui/slidesorter/controller/SlsClipboard.cxx b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx
new file mode 100644
index 000000000000..d226a8c2e294
--- /dev/null
+++ b/sd/source/ui/slidesorter/controller/SlsClipboard.cxx
@@ -0,0 +1,778 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_sd.hxx"
+
+#include "controller/SlsClipboard.hxx"
+
+#include "SlideSorterViewShell.hxx"
+#include "SlideSorter.hxx"
+#include "model/SlideSorterModel.hxx"
+#include "model/SlsPageDescriptor.hxx"
+#include "model/SlsPageEnumerationProvider.hxx"
+#include "view/SlideSorterView.hxx"
+#include "view/SlsViewOverlay.hxx"
+#include "view/SlsPageObject.hxx"
+#include "controller/SlideSorterController.hxx"
+#include "controller/SlsPageSelector.hxx"
+#include "controller/SlsSelectionFunction.hxx"
+#include "controller/SlsCurrentSlideManager.hxx"
+#include "controller/SlsScrollBarManager.hxx"
+#include "controller/SlsFocusManager.hxx"
+#include "controller/SlsSelectionManager.hxx"
+#include "SlsTransferable.hxx"
+
+#include "ViewShellBase.hxx"
+#include "DrawViewShell.hxx"
+#include "Window.hxx"
+#include "fupoor.hxx"
+#include "fuslhide.hxx"
+#include "fuzoom.hxx"
+#include "fucushow.hxx"
+#include "fusldlg.hxx"
+#include "fuexpand.hxx"
+#include "fusumry.hxx"
+#include "app.hrc"
+#include "glob.hrc"
+#include "strings.hrc"
+#include "sdresid.hxx"
+#include "sdxfer.hxx"
+#include "sdmod.hxx"
+#include "sddll.hxx"
+#include "ins_paste.hxx"
+#include "drawdoc.hxx"
+#include "DrawDocShell.hxx"
+#include "sdpage.hxx"
+
+#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/docfile.hxx>
+#include <svx/svxids.hrc>
+#include <vcl/msgbox.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustring.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+namespace sd { namespace slidesorter { namespace controller {
+
+
+Clipboard::Clipboard (SlideSorter& rSlideSorter)
+ : ViewClipboard(rSlideSorter.GetView()),
+ mrSlideSorter(rSlideSorter),
+ mrController(mrSlideSorter.GetController()),
+ maPagesToRemove(),
+ maPagesToSelect(),
+ mbUpdateSelectionPending(false)
+{
+}
+
+
+
+
+Clipboard::~Clipboard (void)
+{
+}
+
+
+
+
+/** With the current implementation the forwarded calls to the current
+ function will come back eventually to call the local Do(Cut|Copy|Paste)
+ methods. A shortcut is possible but would be an unclean hack.
+*/
+void Clipboard::HandleSlotCall (SfxRequest& rRequest)
+{
+ ViewShell* pViewShell = mrSlideSorter.GetViewShell();
+ FunctionReference xFunc;
+ if (pViewShell != NULL)
+ xFunc = pViewShell->GetCurrentFunction();
+ switch (rRequest.GetSlot())
+ {
+ case SID_CUT:
+ if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE)
+ {
+ if(xFunc.is())
+ xFunc->DoCut();
+ else
+ DoCut();
+ }
+ rRequest.Done();
+ break;
+
+ case SID_COPY:
+ if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE)
+ {
+ if(xFunc.is())
+ xFunc->DoCopy();
+ else
+ DoCopy();
+ }
+ rRequest.Done();
+ break;
+
+ case SID_PASTE:
+ // Prevent redraws while inserting pages from the clipboard
+ // because the intermediate inconsistent state might lead to
+ // a crash.
+ if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE)
+ {
+ mrSlideSorter.GetView().LockRedraw (TRUE);
+ if(xFunc.is())
+ xFunc->DoPaste();
+ else
+ DoPaste();
+ mrController.GetSelectionManager()->MakeSelectionVisible();
+ mrSlideSorter.GetView().LockRedraw(FALSE);
+ }
+ rRequest.Done();
+ break;
+
+ case SID_DELETE:
+ DoDelete();
+ rRequest.Done();
+ break;
+ }
+}
+
+
+
+
+void Clipboard::DoCut (::Window* pWindow)
+{
+ if (mrSlideSorter.GetModel().GetPageCount() > 1)
+ {
+ DoCopy(pWindow);
+ DoDelete(pWindow);
+ }
+}
+
+
+
+
+void Clipboard::DoDelete (::Window* )
+{
+ if (mrSlideSorter.GetModel().GetPageCount() > 1)
+ {
+ mrController.GetSelectionManager()->DeleteSelectedPages();
+ }
+}
+
+
+
+
+void Clipboard::DoCopy (::Window* pWindow )
+{
+ CreateSlideTransferable( pWindow, FALSE );
+}
+
+
+
+
+void Clipboard::DoPaste (::Window* pWindow)
+{
+ SdTransferable* pClipTransferable = SD_MOD()->pTransferClip;
+
+ if (pClipTransferable!=NULL && pClipTransferable->IsPageTransferable())
+ {
+ sal_Int32 nInsertPosition = GetInsertionPosition(pWindow);
+
+ if (nInsertPosition >= 0)
+ {
+ // Paste the pages from the clipboard.
+ sal_Int32 nInsertPageCount = PasteTransferable(nInsertPosition);
+ // Select the pasted pages and make the first of them the
+ // current page.
+ mrSlideSorter.GetView().GetWindow()->GrabFocus();
+ SelectPageRange(nInsertPosition, nInsertPageCount);
+ }
+ }
+}
+
+
+
+
+sal_Int32 Clipboard::GetInsertionPosition (::Window* pWindow)
+{
+ sal_Int32 nInsertPosition = -1;
+
+ // Determine the insertion position:
+ // a) When the insertion indicator is visible, then at that position.
+ // b) When the focus indicator is visible, then before or after the
+ // focused page, depending on user input to a dialog.
+ // c) When there is a selection but no focus, then after the
+ // selection.
+ // d) After the last page when there is no selection and no focus.
+
+ view::InsertionIndicatorOverlay& rInsertionIndicatorOverlay (
+ mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay());
+ if (rInsertionIndicatorOverlay.isVisible())
+ {
+ nInsertPosition = rInsertionIndicatorOverlay.GetInsertionPageIndex();
+ }
+ else if (mrController.GetFocusManager().IsFocusShowing())
+ {
+ SdInsertPasteDlg aDialog (pWindow);
+ if (aDialog.Execute() == RET_OK)
+ {
+ nInsertPosition = mrController.GetFocusManager().GetFocusedPageIndex();
+ if ( ! aDialog.IsInsertBefore())
+ nInsertPosition ++;
+ }
+ }
+ else
+ {
+ nInsertPosition = mrController.GetSelectionManager()->GetInsertionPosition();
+ }
+
+ return nInsertPosition;
+}
+
+
+
+
+sal_Int32 Clipboard::PasteTransferable (sal_Int32 nInsertPosition)
+{
+ SdTransferable* pClipTransferable = SD_MOD()->pTransferClip;
+ bool bMergeMasterPages = !pClipTransferable->HasSourceDoc (
+ mrSlideSorter.GetModel().GetDocument());
+ USHORT nInsertIndex ((USHORT)(nInsertPosition * 2 + 1));
+ sal_Int32 nInsertPageCount (0);
+ if (pClipTransferable->HasPageBookmarks())
+ {
+ const List& rBookmarkList = pClipTransferable->GetPageBookmarks();
+ const ::vos::OGuard aGuard (Application::GetSolarMutex());
+
+ nInsertPageCount = (USHORT) rBookmarkList.Count();
+ mrSlideSorter.GetModel().GetDocument()->InsertBookmarkAsPage(
+ const_cast<List*>(&rBookmarkList),
+ NULL,
+ FALSE,
+ FALSE,
+ nInsertIndex,
+ FALSE,
+ pClipTransferable->GetPageDocShell(),
+ TRUE,
+ bMergeMasterPages,
+ FALSE);
+ }
+ else
+ {
+ SfxObjectShell* pShell = pClipTransferable->GetDocShell();
+ DrawDocShell* pDataDocSh = (DrawDocShell*)pShell;
+ SdDrawDocument* pDataDoc = pDataDocSh->GetDoc();
+
+ if (pDataDoc!=NULL
+ && pDataDoc->GetSdPageCount(PK_STANDARD))
+ {
+ const ::vos::OGuard aGuard (Application::GetSolarMutex());
+
+ bMergeMasterPages = (pDataDoc != mrSlideSorter.GetModel().GetDocument());
+ nInsertPageCount = pDataDoc->GetSdPageCount( PK_STANDARD );
+ mrSlideSorter.GetModel().GetDocument()->InsertBookmarkAsPage(
+ NULL,
+ NULL,
+ FALSE,
+ FALSE,
+ nInsertIndex,
+ FALSE,
+ pDataDocSh,
+ TRUE,
+ bMergeMasterPages,
+ FALSE);
+ }
+ }
+ mrController.HandleModelChange();
+ return nInsertPageCount;
+}
+
+
+
+
+void Clipboard::SelectPageRange (sal_Int32 nFirstIndex, sal_Int32 nPageCount)
+{
+ // Select the newly inserted pages. That are the nInsertPageCount pages
+ // after the nInsertIndex position.
+ PageSelector& rSelector (mrController.GetPageSelector());
+ rSelector.DeselectAllPages();
+ for (USHORT i=0; i<nPageCount; i++)
+ {
+ model::SharedPageDescriptor pDescriptor (
+ mrSlideSorter.GetModel().GetPageDescriptor(nFirstIndex + i));
+ if (pDescriptor.get() != NULL)
+ {
+ rSelector.SelectPage(pDescriptor);
+ // The first page of the new selection is made the current page.
+ if (i == 0)
+ {
+ mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);
+ mrController.GetFocusManager().SetFocusedPage(pDescriptor);
+ }
+ }
+ }
+}
+
+
+
+
+void Clipboard::CreateSlideTransferable (
+ ::Window* pWindow,
+ bool bDrag)
+{
+ List aBookmarkList;
+
+ // Insert all selected pages into a bookmark list and remember them in
+ // maPagesToRemove for possible later removal.
+ model::PageEnumeration aSelectedPages
+ (model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
+ mrSlideSorter.GetModel()));
+ while (aSelectedPages.HasMoreElements())
+ {
+ model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
+ aBookmarkList.Insert (
+ new String(pDescriptor->GetPage()->GetName()),
+ LIST_APPEND);
+ maPagesToRemove.push_back (pDescriptor->GetPage());
+ }
+
+ if (aBookmarkList.Count() > 0)
+ {
+ mrSlideSorter.GetView().BrkAction();
+ SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument();
+ SdTransferable* pTransferable = new Transferable (
+ pDocument,
+ NULL,
+ FALSE,
+ dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell()));
+
+ if (bDrag)
+ SD_MOD()->pTransferDrag = pTransferable;
+ else
+ SD_MOD()->pTransferClip = pTransferable;
+
+ pDocument->CreatingDataObj (pTransferable);
+ pTransferable->SetWorkDocument( dynamic_cast<SdDrawDocument*>(pDocument->AllocModel()) );
+ pDocument->CreatingDataObj (NULL);
+ TransferableObjectDescriptor aObjDesc;
+ pTransferable->GetWorkDocument()->GetDocSh()
+ ->FillTransferableObjectDescriptor (aObjDesc);
+
+ if (pDocument->GetDocSh() != NULL)
+ aObjDesc.maDisplayName = pDocument->GetDocSh()
+ ->GetMedium()->GetURLObject().GetURLNoPass();
+
+ ::Window* pActionWindow = pWindow;
+ if (pActionWindow == NULL)
+ {
+ ViewShell* pViewShell = mrSlideSorter.GetViewShell();
+ if (pViewShell != NULL)
+ pActionWindow = pViewShell->GetActiveWindow();
+ }
+
+ pTransferable->SetStartPos (pActionWindow->PixelToLogic(
+ pActionWindow->GetPointerPosPixel()));
+ pTransferable->SetObjectDescriptor (aObjDesc);
+ pTransferable->SetPageBookmarks (aBookmarkList, !bDrag);
+
+ for (void* p=aBookmarkList.First(); p!=NULL; p=aBookmarkList.Next())
+ delete static_cast<String*>(p);
+
+ if (bDrag)
+ {
+ pTransferable->SetView (&mrSlideSorter.GetView());
+ sal_Int8 nDragSourceActions (DND_ACTION_COPY);
+ // The move action is available only when not all pages would be
+ // moved. Otherwise an empty document would remain. Crash.
+ sal_Int32 nRemainingPages = mrSlideSorter.GetModel().GetPageCount() - aBookmarkList.Count();
+ if (nRemainingPages > 0)
+ nDragSourceActions |= DND_ACTION_MOVE;
+ pTransferable->StartDrag (pActionWindow, nDragSourceActions);
+ }
+ else
+ pTransferable->CopyToClipboard (pActionWindow);
+ }
+}
+
+
+
+
+void Clipboard::StartDrag (
+ const Point&,
+ ::Window* pWindow)
+{
+ maPagesToRemove.clear();
+ maPagesToSelect.clear();
+ mbUpdateSelectionPending = false;
+ CreateSlideTransferable (pWindow, TRUE);
+}
+
+
+
+
+void Clipboard::DragFinished (sal_Int8 nDropAction)
+{
+ // Hide the substitution display and insertion indicator.
+ mrSlideSorter.GetView().GetOverlay().GetSubstitutionOverlay().setVisible(false);
+ mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay().setVisible(false);
+
+ SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
+
+ if (pDragTransferable != NULL)
+ pDragTransferable->SetView (NULL);
+
+ PageSelector& rSelector (mrController.GetPageSelector());
+ if ((nDropAction & DND_ACTION_MOVE) != 0
+ && ! maPagesToRemove.empty())
+ {
+ // Remove the pages that have been moved to another place (possibly
+ // in the same document.)
+ rSelector.DeselectAllPages();
+ PageList::iterator aDraggedPage;
+ for (aDraggedPage=maPagesToRemove.begin();
+ aDraggedPage!=maPagesToRemove.end();
+ aDraggedPage++)
+ {
+ rSelector.SelectPage (*aDraggedPage);
+ }
+ mrController.GetSelectionManager()->DeleteSelectedPages ();
+ }
+
+ SelectPages();
+}
+
+
+
+
+void Clipboard::SelectPages (void)
+{
+ PageSelector& rSelector (mrController.GetPageSelector());
+
+ // Select the dropped pages.
+ PageList::iterator iPage;
+ rSelector.DeselectAllPages();
+ for (iPage=maPagesToSelect.begin(); iPage!=maPagesToSelect.end(); ++iPage)
+ {
+ rSelector.SelectPage(*iPage);
+ }
+}
+
+
+
+
+sal_Int8 Clipboard::AcceptDrop (
+ const AcceptDropEvent& rEvent,
+ DropTargetHelper& rTargetHelper,
+ ::sd::Window* pTargetWindow,
+ USHORT nPage,
+ USHORT nLayer)
+{
+ sal_Int8 nResult = DND_ACTION_NONE;
+
+ switch (IsDropAccepted())
+ {
+ case DT_PAGE:
+ {
+ // Accept a drop.
+ nResult = rEvent.mnAction;
+
+ // Use the copy action when the drop action is the default, i.e. not
+ // explicitly set to move or link, and when the source and
+ // target models are not the same.
+ const SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
+ if (pDragTransferable != NULL
+ && pDragTransferable->IsPageTransferable()
+ && ((rEvent.maDragEvent.DropAction
+ & ::com::sun::star::datatransfer::dnd::DNDConstants::ACTION_DEFAULT) != 0)
+ && (mrSlideSorter.GetModel().GetDocument()->GetDocSh()
+ != pDragTransferable->GetPageDocShell()))
+ {
+ nResult = DND_ACTION_COPY;
+ }
+
+ // Show the insertion marker and the substitution for a drop.
+ Point aPosition = pTargetWindow->PixelToLogic (rEvent.maPosPixel);
+ view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
+ rOverlay.GetInsertionIndicatorOverlay().SetPosition (aPosition);
+ rOverlay.GetInsertionIndicatorOverlay().setVisible(true);
+ rOverlay.GetSubstitutionOverlay().SetPosition (aPosition);
+
+ // Scroll the window when the mouse reaches the window border.
+ mrController.GetScrollBarManager().AutoScroll (rEvent.maPosPixel);
+ }
+ break;
+
+ case DT_SHAPE:
+ nResult = ExecuteOrAcceptShapeDrop(
+ DC_ACCEPT,
+ rEvent.maPosPixel,
+ &rEvent,
+ rTargetHelper,
+ pTargetWindow,
+ nPage,
+ nLayer);
+ break;
+ default:
+ break;
+ }
+
+ return nResult;
+}
+
+
+
+
+sal_Int8 Clipboard::ExecuteDrop (
+ const ExecuteDropEvent& rEvent,
+ DropTargetHelper& rTargetHelper,
+ ::sd::Window* pTargetWindow,
+ USHORT nPage,
+ USHORT nLayer)
+{
+ sal_Int8 nResult = DND_ACTION_NONE;
+
+ switch (IsDropAccepted())
+ {
+ case DT_PAGE:
+ {
+ const SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
+ const Point aEventModelPosition (
+ pTargetWindow->PixelToLogic (rEvent.maPosPixel));
+ long int nXOffset = labs (pDragTransferable->GetStartPos().X()
+ - aEventModelPosition.X());
+ long int nYOffset = labs (pDragTransferable->GetStartPos().Y()
+ - aEventModelPosition.Y());
+ const bool bContinue =
+ ( pDragTransferable->GetView() != &mrSlideSorter.GetView() )
+ || ( nXOffset >= 2 && nYOffset >= 2 );
+
+ // Get insertion position and then turn off the insertion indicator.
+ view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
+ rOverlay.GetInsertionIndicatorOverlay().SetPosition(
+ aEventModelPosition);
+ USHORT nIndex = DetermineInsertPosition (*pDragTransferable);
+ OSL_TRACE ("Clipboard::AcceptDrop() called for index %d",
+ nIndex);
+ rOverlay.GetInsertionIndicatorOverlay().setVisible(false);
+
+ if (bContinue)
+ {
+ SlideSorterController::ModelChangeLock aModelChangeLock (mrController);
+
+ if (pDragTransferable->GetView() == &mrSlideSorter.GetView()
+ && rEvent.mnAction == DND_ACTION_MOVE)
+ {
+ // We are asked to move pages inside one view. For this we
+ // call MoveSelectedPages() which is faster than going the
+ // generic way.
+
+ // Remember to select the moved pages afterwards.
+ maPagesToRemove.swap(maPagesToSelect);
+ maPagesToRemove.clear();
+
+ USHORT nSdrModelIndex;
+ if (nIndex != SDRPAGE_NOTFOUND)
+ nSdrModelIndex = nIndex / 2 - 1;
+ else
+ nSdrModelIndex = SDRPAGE_NOTFOUND;
+ mrController.GetSelectionManager()->MoveSelectedPages(nSdrModelIndex);
+ mbUpdateSelectionPending = true;
+ nResult = DND_ACTION_NONE;
+ }
+ else
+ {
+ // Handle a general drop operation.
+ HandlePageDrop (*pDragTransferable);
+ nResult = rEvent.mnAction;
+ }
+ }
+ }
+ break;
+
+ case DT_SHAPE:
+ nResult = ExecuteOrAcceptShapeDrop(
+ DC_EXECUTE,
+ rEvent.maPosPixel,
+ &rEvent,
+ rTargetHelper,
+ pTargetWindow,
+ nPage,
+ nLayer);
+ break;
+ default:
+ break;
+ }
+
+ return nResult;
+}
+
+
+
+
+USHORT Clipboard::DetermineInsertPosition (const SdTransferable& )
+{
+ USHORT nInsertPosition = SDRPAGE_NOTFOUND;
+
+ // Tell the model to move the dragged pages behind the one with the
+ // index nInsertionIndex which first has to be transformed into an index
+ // understandable by the document.
+ view::InsertionIndicatorOverlay& rOverlay (
+ mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay());
+ sal_Int32 nInsertionIndex (rOverlay.GetInsertionPageIndex());
+
+ // The index returned by the overlay starts with 1 for the first slide.
+ // This is now converted that to an SdModel index that also starts with 1.
+ if (nInsertionIndex >= 0)
+ nInsertPosition = (USHORT)nInsertionIndex * 2 + 1;
+
+ return nInsertPosition;
+}
+
+
+
+
+USHORT Clipboard::InsertSlides (
+ const SdTransferable& rTransferable,
+ USHORT nInsertPosition)
+{
+ USHORT nInsertedPageCount = ViewClipboard::InsertSlides (
+ rTransferable,
+ nInsertPosition);
+
+ // Remember the inserted pages so that they can be selected when the
+ // operation is finished.
+ int nDocumentIndex = nInsertPosition / 2 - 1;
+ for (USHORT i=1; i<=nInsertedPageCount; i++)
+ {
+ model::SharedPageDescriptor pDescriptor (
+ mrSlideSorter.GetModel().GetPageDescriptor(nDocumentIndex + i));
+ if (pDescriptor.get() != NULL)
+ maPagesToSelect.push_back (pDescriptor->GetPage());
+ }
+
+ mbUpdateSelectionPending |= (nInsertedPageCount>0);
+
+ return nInsertedPageCount;
+}
+
+
+
+
+Clipboard::DropType Clipboard::IsDropAccepted (void) const
+{
+ DropType eResult (DT_NONE);
+
+ const SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
+ if (pDragTransferable != NULL)
+ {
+ if (pDragTransferable->IsPageTransferable())
+ {
+ if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE)
+ eResult = DT_PAGE;
+ }
+ else
+ {
+ eResult = DT_SHAPE;
+ }
+ }
+
+ return eResult;
+}
+
+
+
+
+sal_Int8 Clipboard::ExecuteOrAcceptShapeDrop (
+ DropCommand eCommand,
+ const Point& rPosition,
+ const void* pDropEvent,
+ DropTargetHelper& rTargetHelper,
+ ::sd::Window* pTargetWindow,
+ USHORT nPage,
+ USHORT nLayer)
+{
+ sal_Int8 nResult = 0;
+
+ // The dropping of a shape is accepted or executed only when there is
+ // DrawViewShell available to which we can forward this call. This has
+ // technical reasons: The actual code to accept or execute a shape drop
+ // is implemented in the ViewShell class and uses the page view of the
+ // main edit view. This is not possible without a DrawViewShell.
+ ::boost::shared_ptr<DrawViewShell> pDrawViewShell;
+ if (mrSlideSorter.GetViewShell() != NULL)
+ pDrawViewShell = ::boost::dynamic_pointer_cast<DrawViewShell>(
+ mrSlideSorter.GetViewShell()->GetViewShellBase().GetMainViewShell());
+ if (pDrawViewShell.get() != NULL
+ && (pDrawViewShell->GetShellType() == ViewShell::ST_IMPRESS
+ || pDrawViewShell->GetShellType() == ViewShell::ST_DRAW))
+ {
+ // The drop is only accepted or executed when it takes place over a
+ // page object. Therefore we replace a missing page number by the
+ // number of the page under the mouse.
+ if (nPage == SDRPAGE_NOTFOUND)
+ {
+ model::SharedPageDescriptor pDescriptor (
+ mrSlideSorter.GetModel().GetPageDescriptor(
+ mrSlideSorter.GetView().GetPageIndexAtPoint(rPosition)));
+ if (pDescriptor.get() != NULL && pDescriptor->GetPage()!=NULL)
+ nPage = (pDescriptor->GetPage()->GetPageNum() - 1) / 2;
+ }
+
+ // Now comes the code that is different for the Execute and Accept:
+ // We simply forward the call to the AcceptDrop() or ExecuteDrop()
+ // methods of the DrawViewShell in the center pane.
+ if (nPage != SDRPAGE_NOTFOUND)
+ switch (eCommand)
+ {
+ case DC_ACCEPT:
+ nResult = pDrawViewShell->AcceptDrop(
+ *reinterpret_cast<const AcceptDropEvent*>(pDropEvent),
+ rTargetHelper,
+ pTargetWindow,
+ nPage,
+ nLayer);
+ break;
+
+ case DC_EXECUTE:
+ nResult = pDrawViewShell->ExecuteDrop(
+ *reinterpret_cast<const ExecuteDropEvent*>(pDropEvent),
+ rTargetHelper,
+ pTargetWindow,
+ nPage,
+ nLayer);
+ break;
+ }
+ }
+
+ return nResult;
+}
+
+
+
+} } } // end of namespace ::sd::slidesorter::controller
+