LCOV - code coverage report
Current view: top level - libreoffice/sd/source/ui/slidesorter/controller - SlsClipboard.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1 378 0.3 %
Date: 2012-12-27 Functions: 2 31 6.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : 
      21             : #include "controller/SlsClipboard.hxx"
      22             : 
      23             : #include "SlideSorterViewShell.hxx"
      24             : #include "SlideSorter.hxx"
      25             : #include "model/SlideSorterModel.hxx"
      26             : #include "model/SlsPageDescriptor.hxx"
      27             : #include "model/SlsPageEnumerationProvider.hxx"
      28             : #include "view/SlideSorterView.hxx"
      29             : #include "view/SlsTheme.hxx"
      30             : #include "controller/SlideSorterController.hxx"
      31             : #include "controller/SlsInsertionIndicatorHandler.hxx"
      32             : #include "controller/SlsPageSelector.hxx"
      33             : #include "controller/SlsSelectionFunction.hxx"
      34             : #include "controller/SlsCurrentSlideManager.hxx"
      35             : #include "controller/SlsScrollBarManager.hxx"
      36             : #include "controller/SlsFocusManager.hxx"
      37             : #include "controller/SlsSelectionManager.hxx"
      38             : #include "controller/SlsTransferableData.hxx"
      39             : #include "controller/SlsSelectionObserver.hxx"
      40             : #include "controller/SlsVisibleAreaManager.hxx"
      41             : #include "cache/SlsPageCache.hxx"
      42             : 
      43             : #include "ViewShellBase.hxx"
      44             : #include "View.hxx"
      45             : #include "DrawViewShell.hxx"
      46             : #include "Window.hxx"
      47             : #include "fupoor.hxx"
      48             : #include "fuzoom.hxx"
      49             : #include "fucushow.hxx"
      50             : #include "fusldlg.hxx"
      51             : #include "fuexpand.hxx"
      52             : #include "fusumry.hxx"
      53             : #include "app.hrc"
      54             : #include "glob.hrc"
      55             : #include "strings.hrc"
      56             : #include "sdresid.hxx"
      57             : #include "sdxfer.hxx"
      58             : #include "sdmod.hxx"
      59             : #include "ins_paste.hxx"
      60             : #include "drawdoc.hxx"
      61             : #include "DrawDocShell.hxx"
      62             : #include "sdpage.hxx"
      63             : #include "sdtreelb.hxx"
      64             : 
      65             : #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
      66             : #include <sfx2/request.hxx>
      67             : #include <sfx2/viewfrm.hxx>
      68             : #include <sfx2/bindings.hxx>
      69             : #include <sfx2/docfile.hxx>
      70             : #include <svx/svxids.hrc>
      71             : #include <svx/svdstr.hrc>
      72             : #include <vcl/msgbox.hxx>
      73             : #include <tools/urlobj.hxx>
      74             : #include <rtl/ustring.hxx>
      75             : #include <osl/mutex.hxx>
      76             : #include <vcl/svapp.hxx>
      77             : #include <boost/bind.hpp>
      78             : 
      79             : 
      80             : namespace sd { namespace slidesorter { namespace controller {
      81             : 
      82             : namespace {
      83             : /** Temporarily deactivate slide tracking of the VisibleAreaManager.
      84             :     This is used as a workaround to avoid unwanted repositioning of
      85             :     the visible area when the selection of slides is copied to the
      86             :     clipboard (cloning of slides leads to model change notifications
      87             :     for the original model.)
      88             : */
      89             : class TemporarySlideTrackingDeactivator
      90             : {
      91             : public:
      92           0 :     TemporarySlideTrackingDeactivator (SlideSorterController& rController)
      93             :         : mrController(rController),
      94             :           mbIsCurrentSlideTrackingActive (
      95           0 :               mrController.GetVisibleAreaManager().IsCurrentSlideTrackingActive())
      96             :     {
      97           0 :         if (mbIsCurrentSlideTrackingActive)
      98           0 :             mrController.GetVisibleAreaManager().DeactivateCurrentSlideTracking();
      99           0 :     }
     100           0 :     ~TemporarySlideTrackingDeactivator (void)
     101             :     {
     102           0 :         if (mbIsCurrentSlideTrackingActive)
     103           0 :             mrController.GetVisibleAreaManager().ActivateCurrentSlideTracking();
     104           0 :     }
     105             : 
     106             : private:
     107             :     SlideSorterController& mrController;
     108             :     const bool mbIsCurrentSlideTrackingActive;
     109             : };
     110             : } // end of anonymous namespace
     111             : 
     112             : class Clipboard::UndoContext
     113             : {
     114             : public:
     115           0 :     UndoContext (
     116             :         SdDrawDocument* pDocument,
     117             :         const ::boost::shared_ptr<ViewShell>& rpMainViewShell)
     118             :         : mpDocument(pDocument),
     119           0 :           mpMainViewShell(rpMainViewShell)
     120             :     {
     121           0 :         if (mpDocument!=NULL && mpDocument->IsUndoEnabled())
     122             :         {
     123           0 :             if (mpMainViewShell && mpMainViewShell->GetShellType() == ViewShell::ST_DRAW)
     124           0 :                 mpDocument->BegUndo(String(SdResId(STRING_DRAG_AND_DROP_PAGES)));
     125             :             else
     126           0 :                 mpDocument->BegUndo(String(SdResId(STRING_DRAG_AND_DROP_SLIDES)));
     127             :         }
     128           0 :     }
     129             : 
     130           0 :     ~UndoContext (void)
     131           0 :     {
     132           0 :         if (mpDocument!=NULL && mpDocument->IsUndoEnabled())
     133           0 :             mpDocument->EndUndo();
     134           0 :         if (mpMainViewShell && mpMainViewShell->GetViewFrame()!=NULL)
     135             :         {
     136           0 :             SfxBindings& rBindings = mpMainViewShell->GetViewFrame()->GetBindings();
     137           0 :             rBindings.Invalidate(SID_UNDO);
     138           0 :             rBindings.Invalidate(SID_REDO);
     139             :         }
     140           0 :     }
     141             : private:
     142             :     SdDrawDocument* mpDocument;
     143             :     ::boost::shared_ptr<ViewShell> mpMainViewShell;
     144             : };
     145             : 
     146             : 
     147             : 
     148             : 
     149           0 : Clipboard::Clipboard (SlideSorter& rSlideSorter)
     150           0 :     : ViewClipboard(rSlideSorter.GetView()),
     151             :       mrSlideSorter(rSlideSorter),
     152           0 :       mrController(mrSlideSorter.GetController()),
     153             :       maPagesToRemove(),
     154             :       maPagesToSelect(),
     155             :       mbUpdateSelectionPending(false),
     156             :       mpUndoContext(),
     157             :       mpSelectionObserverContext(),
     158           0 :       mnDragFinishedUserEventId(0)
     159             : {
     160           0 : }
     161             : 
     162             : 
     163             : 
     164             : 
     165           0 : Clipboard::~Clipboard (void)
     166             : {
     167           0 :     if (mnDragFinishedUserEventId != 0)
     168           0 :         Application::RemoveUserEvent(mnDragFinishedUserEventId);
     169           0 : }
     170             : 
     171             : 
     172             : 
     173             : 
     174             : /** With the current implementation the forwarded calls to the current
     175             :     function will come back eventually to call the local Do(Cut|Copy|Paste)
     176             :     methods.  A shortcut is possible but would be an unclean hack.
     177             : */
     178           0 : void Clipboard::HandleSlotCall (SfxRequest& rRequest)
     179             : {
     180           0 :     ViewShell* pViewShell = mrSlideSorter.GetViewShell();
     181           0 :     FunctionReference xFunc;
     182           0 :     if (pViewShell != NULL)
     183           0 :         xFunc = pViewShell->GetCurrentFunction();
     184           0 :     switch (rRequest.GetSlot())
     185             :     {
     186             :         case SID_CUT:
     187           0 :             if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE)
     188             :             {
     189           0 :                 if(xFunc.is())
     190           0 :                     xFunc->DoCut();
     191             :                 else
     192           0 :                     DoCut();
     193             :             }
     194           0 :             rRequest.Done();
     195           0 :             break;
     196             : 
     197             :         case SID_COPY:
     198           0 :             if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE)
     199             :             {
     200           0 :                 if(xFunc.is())
     201           0 :                     xFunc->DoCopy();
     202             :                 else
     203           0 :                     DoCopy();
     204             :             }
     205           0 :             rRequest.Done();
     206           0 :             break;
     207             : 
     208             :         case SID_PASTE:
     209             :             // Prevent redraws while inserting pages from the clipboard
     210             :             // because the intermediate inconsistent state might lead to
     211             :             // a crash.
     212           0 :             if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE)
     213             :             {
     214           0 :                 view::SlideSorterView::DrawLock aLock (mrSlideSorter);
     215           0 :                 SelectionObserver::Context aContext (mrSlideSorter);
     216           0 :                 if(xFunc.is())
     217           0 :                     xFunc->DoPaste();
     218             :                 else
     219           0 :                     DoPaste();
     220             :             }
     221           0 :             rRequest.Done();
     222           0 :             break;
     223             : 
     224             :         case SID_DELETE:
     225           0 :             DoDelete();
     226           0 :             rRequest.Done();
     227           0 :             break;
     228           0 :     }
     229           0 : }
     230             : 
     231             : 
     232             : 
     233             : 
     234           0 : void Clipboard::DoCut (::Window* pWindow)
     235             : {
     236           0 :     if (mrSlideSorter.GetModel().GetPageCount() > 1)
     237             :     {
     238           0 :         DoCopy(pWindow);
     239           0 :         DoDelete(pWindow);
     240             :     }
     241           0 : }
     242             : 
     243             : 
     244             : 
     245             : 
     246           0 : void Clipboard::DoDelete (::Window* )
     247             : {
     248           0 :     if (mrSlideSorter.GetModel().GetPageCount() > 1)
     249             :     {
     250           0 :         mrController.GetSelectionManager()->DeleteSelectedPages();
     251             :     }
     252           0 : }
     253             : 
     254             : 
     255             : 
     256             : 
     257           0 : void Clipboard::DoCopy (::Window* pWindow )
     258             : {
     259           0 :     CreateSlideTransferable( pWindow, sal_False );
     260           0 : }
     261             : 
     262             : 
     263             : 
     264             : 
     265           0 : void Clipboard::DoPaste (::Window* pWindow)
     266             : {
     267           0 :     SdTransferable* pClipTransferable = SD_MOD()->pTransferClip;
     268             : 
     269           0 :     if (pClipTransferable!=NULL && pClipTransferable->IsPageTransferable())
     270             :     {
     271           0 :         sal_Int32 nInsertPosition = GetInsertionPosition(pWindow);
     272             : 
     273           0 :         if (nInsertPosition >= 0)
     274             :         {
     275             :             // Paste the pages from the clipboard.
     276           0 :             sal_Int32 nInsertPageCount = PasteTransferable(nInsertPosition);
     277             :             // Select the pasted pages and make the first of them the
     278             :             // current page.
     279           0 :             mrSlideSorter.GetContentWindow()->GrabFocus();
     280           0 :             SelectPageRange(nInsertPosition, nInsertPageCount);
     281             :         }
     282             :     }
     283           0 : }
     284             : 
     285             : 
     286             : 
     287             : 
     288           0 : sal_Int32 Clipboard::GetInsertionPosition (::Window* pWindow)
     289             : {
     290           0 :     sal_Int32 nInsertPosition = -1;
     291             : 
     292             :     // Determine the insertion position:
     293             :     // a) When the insertion indicator is visible, then at that position.
     294             :     // b) When the focus indicator is visible, then before or after the
     295             :     // focused page, depending on user input to a dialog.
     296             :     // c) When there is a selection but no focus, then after the
     297             :     // selection.
     298             :     // d) After the last page when there is no selection and no focus.
     299             : 
     300             :     ::boost::shared_ptr<controller::InsertionIndicatorHandler> pInsertionIndicatorHandler (
     301           0 :         mrController.GetInsertionIndicatorHandler());
     302           0 :     if (pInsertionIndicatorHandler->IsActive())
     303             :     {
     304             :         // Use the insertion index of an active insertion indicator.
     305           0 :         nInsertPosition = pInsertionIndicatorHandler->GetInsertionPageIndex();
     306             :     }
     307           0 :     else if (mrController.GetSelectionManager()->GetInsertionPosition() >= 0)
     308             :     {
     309             :         // Use the insertion index of an insertion indicator that has been
     310             :         // deactivated a short while ago.
     311           0 :         nInsertPosition = mrController.GetSelectionManager()->GetInsertionPosition();
     312             :     }
     313           0 :     else if (mrController.GetFocusManager().IsFocusShowing())
     314             :     {
     315             :         // Use the focus to determine the insertion position.
     316           0 :         SdInsertPasteDlg aDialog (pWindow);
     317           0 :         if (aDialog.Execute() == RET_OK)
     318             :         {
     319           0 :             nInsertPosition = mrController.GetFocusManager().GetFocusedPageIndex();
     320           0 :             if ( ! aDialog.IsInsertBefore())
     321           0 :                 nInsertPosition ++;
     322           0 :         }
     323             :     }
     324             : 
     325           0 :     return nInsertPosition;
     326             : }
     327             : 
     328             : 
     329             : 
     330             : 
     331           0 : sal_Int32 Clipboard::PasteTransferable (sal_Int32 nInsertPosition)
     332             : {
     333           0 :     SdTransferable* pClipTransferable = SD_MOD()->pTransferClip;
     334           0 :     model::SlideSorterModel& rModel (mrSlideSorter.GetModel());
     335           0 :     bool bMergeMasterPages = !pClipTransferable->HasSourceDoc (rModel.GetDocument());
     336           0 :     sal_uInt16 nInsertIndex (rModel.GetCoreIndex(nInsertPosition));
     337           0 :     sal_Int32 nInsertPageCount (0);
     338           0 :     if (pClipTransferable->HasPageBookmarks())
     339             :     {
     340           0 :         const std::vector<rtl::OUString> &rBookmarkList = pClipTransferable->GetPageBookmarks();
     341           0 :         const SolarMutexGuard aGuard;
     342             : 
     343           0 :         nInsertPageCount = (sal_uInt16) rBookmarkList.size();
     344             :         rModel.GetDocument()->InsertBookmarkAsPage(
     345             :             rBookmarkList,
     346             :             NULL,
     347             :             sal_False,
     348             :             sal_False,
     349             :             nInsertIndex,
     350             :             sal_False,
     351             :             pClipTransferable->GetPageDocShell(),
     352             :             sal_True,
     353             :             bMergeMasterPages,
     354           0 :             sal_False);
     355             :     }
     356             :     else
     357             :     {
     358           0 :         SfxObjectShell* pShell = pClipTransferable->GetDocShell();
     359           0 :         DrawDocShell* pDataDocSh = (DrawDocShell*)pShell;
     360           0 :         SdDrawDocument* pDataDoc = pDataDocSh->GetDoc();
     361             : 
     362           0 :         if (pDataDoc!=NULL
     363           0 :             && pDataDoc->GetSdPageCount(PK_STANDARD))
     364             :         {
     365           0 :             const SolarMutexGuard aGuard;
     366             : 
     367           0 :             bMergeMasterPages = (pDataDoc != rModel.GetDocument());
     368           0 :             nInsertPageCount = pDataDoc->GetSdPageCount( PK_STANDARD );
     369             :             rModel.GetDocument()->InsertBookmarkAsPage(
     370             :                 std::vector<rtl::OUString>(),
     371             :                 NULL,
     372             :                 sal_False,
     373             :                 sal_False,
     374             :                 nInsertIndex,
     375             :                 sal_False,
     376             :                 pDataDocSh,
     377             :                 sal_True,
     378             :                 bMergeMasterPages,
     379           0 :                 sal_False);
     380             :         }
     381             :     }
     382           0 :     mrController.HandleModelChange();
     383           0 :     return nInsertPageCount;
     384             : }
     385             : 
     386             : 
     387             : 
     388             : 
     389           0 : void Clipboard::SelectPageRange (sal_Int32 nFirstIndex, sal_Int32 nPageCount)
     390             : {
     391             :     // Select the newly inserted pages.  That are the nInsertPageCount pages
     392             :     // after the nInsertIndex position.
     393           0 :     PageSelector& rSelector (mrController.GetPageSelector());
     394           0 :     rSelector.DeselectAllPages();
     395           0 :     for (sal_uInt16 i=0; i<nPageCount; i++)
     396             :     {
     397             :         model::SharedPageDescriptor pDescriptor (
     398           0 :             mrSlideSorter.GetModel().GetPageDescriptor(nFirstIndex + i));
     399           0 :         if (pDescriptor.get() != NULL)
     400             :         {
     401           0 :             rSelector.SelectPage(pDescriptor);
     402             :             // The first page of the new selection is made the current page.
     403           0 :             if (i == 0)
     404             :             {
     405           0 :                 mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);
     406             :             }
     407             :         }
     408           0 :     }
     409           0 : }
     410             : 
     411             : 
     412             : 
     413             : 
     414           0 : void Clipboard::CreateSlideTransferable (
     415             :     ::Window* pWindow,
     416             :     bool bDrag)
     417             : {
     418           0 :     std::vector<rtl::OUString> aBookmarkList;
     419             : 
     420             :     // Insert all selected pages into a bookmark list and remember them in
     421             :     // maPagesToRemove for possible later removal.
     422             :     model::PageEnumeration aSelectedPages
     423             :         (model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
     424           0 :             mrSlideSorter.GetModel()));
     425           0 :     while (aSelectedPages.HasMoreElements())
     426             :     {
     427           0 :         model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
     428           0 :         aBookmarkList.push_back(pDescriptor->GetPage()->GetName());
     429           0 :         maPagesToRemove.push_back (pDescriptor->GetPage());
     430           0 :     }
     431             : 
     432             :     // Create a small set of representatives of the selection for which
     433             :     // previews are included into the transferable so that an insertion
     434             :     // indicator can be rendered.
     435           0 :     aSelectedPages.Rewind();
     436           0 :     ::std::vector<TransferableData::Representative> aRepresentatives;
     437           0 :     aRepresentatives.reserve(3);
     438             :     ::boost::shared_ptr<cache::PageCache> pPreviewCache (
     439           0 :         mrSlideSorter.GetView().GetPreviewCache());
     440           0 :     while (aSelectedPages.HasMoreElements())
     441             :     {
     442           0 :         model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
     443           0 :         if ( ! pDescriptor || pDescriptor->GetPage()==NULL)
     444           0 :             continue;
     445           0 :         Bitmap aPreview (pPreviewCache->GetPreviewBitmap(pDescriptor->GetPage(), false));
     446             :         aRepresentatives.push_back(TransferableData::Representative(
     447             :             aPreview,
     448           0 :             pDescriptor->HasState(model::PageDescriptor::ST_Excluded)));
     449           0 :         if (aRepresentatives.size() >= 3)
     450             :             break;
     451           0 :     }
     452             : 
     453           0 :     if (!aBookmarkList.empty())
     454             :     {
     455           0 :         mrSlideSorter.GetView().BrkAction();
     456           0 :         SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument();
     457             :         SdTransferable* pTransferable = TransferableData::CreateTransferable (
     458             :             pDocument,
     459             :             NULL,
     460             :             sal_False,
     461           0 :             dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell()),
     462           0 :             aRepresentatives);
     463             : 
     464           0 :         if (bDrag)
     465           0 :             SD_MOD()->pTransferDrag = pTransferable;
     466             :         else
     467           0 :             SD_MOD()->pTransferClip = pTransferable;
     468             : 
     469           0 :         pDocument->CreatingDataObj (pTransferable);
     470           0 :         pTransferable->SetWorkDocument( dynamic_cast<SdDrawDocument*>(pDocument->AllocModel()) );
     471           0 :         pDocument->CreatingDataObj (NULL);
     472           0 :         TransferableObjectDescriptor aObjDesc;
     473           0 :         pTransferable->GetWorkDocument()->GetDocSh()
     474           0 :             ->FillTransferableObjectDescriptor (aObjDesc);
     475             : 
     476           0 :         if (pDocument->GetDocSh() != NULL)
     477           0 :             aObjDesc.maDisplayName = pDocument->GetDocSh()
     478           0 :                 ->GetMedium()->GetURLObject().GetURLNoPass();
     479             : 
     480           0 :         ::Window* pActionWindow = pWindow;
     481           0 :         if (pActionWindow == NULL)
     482             :         {
     483           0 :             ViewShell* pViewShell = mrSlideSorter.GetViewShell();
     484           0 :             if (pViewShell != NULL)
     485           0 :                 pActionWindow = pViewShell->GetActiveWindow();
     486             :         }
     487             : 
     488             :         pTransferable->SetStartPos (pActionWindow->PixelToLogic(
     489           0 :             pActionWindow->GetPointerPosPixel()));
     490           0 :         pTransferable->SetObjectDescriptor (aObjDesc);
     491             : 
     492             :         {
     493           0 :             TemporarySlideTrackingDeactivator aDeactivator (mrController);
     494           0 :             pTransferable->SetPageBookmarks (aBookmarkList, !bDrag);
     495             :         }
     496             : 
     497           0 :         if (bDrag)
     498             :         {
     499           0 :             pTransferable->SetView (&mrSlideSorter.GetView());
     500           0 :             sal_Int8 nDragSourceActions (DND_ACTION_COPY);
     501             :             // The move action is available only when not all pages would be
     502             :             // moved.  Otherwise an empty document would remain.  Crash.
     503           0 :             sal_Int32 nRemainingPages = mrSlideSorter.GetModel().GetPageCount() - aBookmarkList.size();
     504           0 :             if (nRemainingPages > 0)
     505           0 :                 nDragSourceActions |= DND_ACTION_MOVE;
     506           0 :             pTransferable->StartDrag (pActionWindow, nDragSourceActions);
     507             :         }
     508             :         else
     509           0 :             pTransferable->CopyToClipboard (pActionWindow);
     510           0 :     }
     511           0 : }
     512             : 
     513             : 
     514             : 
     515             : 
     516           0 : ::boost::shared_ptr<SdTransferable::UserData> Clipboard::CreateTransferableUserData (SdTransferable* pTransferable)
     517             : {
     518             :     do
     519             :     {
     520             :         SdPageObjsTLB::SdPageObjsTransferable* pTreeListBoxTransferable
     521           0 :             = dynamic_cast<SdPageObjsTLB::SdPageObjsTransferable*>(pTransferable);
     522           0 :         if (pTreeListBoxTransferable == NULL)
     523             :             break;
     524             : 
     525             :         // Find view shell for the document of the transferable.
     526             :         ::sd::ViewShell* pViewShell
     527           0 :               = SdPageObjsTLB::GetViewShellForDocShell(pTreeListBoxTransferable->GetDocShell());
     528           0 :         if (pViewShell == NULL)
     529             :             break;
     530             : 
     531             :         // Find slide sorter for the document of the transferable.
     532             :         SlideSorterViewShell* pSlideSorterViewShell
     533           0 :             = SlideSorterViewShell::GetSlideSorter(pViewShell->GetViewShellBase());
     534           0 :         if (pSlideSorterViewShell == NULL)
     535             :             break;
     536           0 :         SlideSorter& rSlideSorter (pSlideSorterViewShell->GetSlideSorter());
     537             : 
     538             :         // Get bookmark from transferable.
     539           0 :         TransferableDataHelper  aDataHelper (pTransferable);
     540           0 :         INetBookmark aINetBookmark;
     541           0 :         if ( ! aDataHelper.GetINetBookmark(SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, aINetBookmark))
     542             :             break;
     543           0 :         const rtl::OUString sURL (aINetBookmark.GetURL());
     544           0 :         const sal_Int32 nIndex (sURL.indexOf((sal_Unicode)'#'));
     545           0 :         if (nIndex == -1)
     546             :             break;
     547           0 :         String sBookmark (sURL.copy(nIndex+1));
     548             : 
     549             :         // Make sure that the bookmark points to a page.
     550           0 :         SdDrawDocument* pTransferableDocument = rSlideSorter.GetModel().GetDocument();
     551           0 :         if (pTransferableDocument == NULL)
     552             :             break;
     553           0 :         sal_Bool bIsMasterPage = sal_False;
     554           0 :         const sal_uInt16 nPageIndex (pTransferableDocument->GetPageByName(sBookmark, bIsMasterPage));
     555           0 :         if (nPageIndex == SDRPAGE_NOTFOUND)
     556             :             break;
     557             : 
     558             :         // Create preview.
     559           0 :         ::std::vector<TransferableData::Representative> aRepresentatives;
     560           0 :         aRepresentatives.reserve(1);
     561             :         ::boost::shared_ptr<cache::PageCache> pPreviewCache (
     562           0 :             rSlideSorter.GetView().GetPreviewCache());
     563           0 :         model::SharedPageDescriptor pDescriptor (rSlideSorter.GetModel().GetPageDescriptor((nPageIndex-1)/2));
     564           0 :         if ( ! pDescriptor || pDescriptor->GetPage()==NULL)
     565             :             break;
     566           0 :         Bitmap aPreview (pPreviewCache->GetPreviewBitmap(pDescriptor->GetPage(), false));
     567             :         aRepresentatives.push_back(TransferableData::Representative(
     568             :                 aPreview,
     569           0 :                 pDescriptor->HasState(model::PageDescriptor::ST_Excluded)));
     570             : 
     571             :         // Remember the page in maPagesToRemove so that it can be removed
     572             :         // when drag and drop action is "move".
     573           0 :         Clipboard& rOtherClipboard (pSlideSorterViewShell->GetSlideSorter().GetController().GetClipboard());
     574           0 :         rOtherClipboard.maPagesToRemove.clear();
     575           0 :         rOtherClipboard.maPagesToRemove.push_back(pDescriptor->GetPage());
     576             : 
     577             :         // Create the new transferable.
     578             :         ::boost::shared_ptr<SdTransferable::UserData> pNewTransferable (
     579             :             new TransferableData(
     580             :                 pSlideSorterViewShell,
     581           0 :                 aRepresentatives));
     582             :         pTransferable->SetWorkDocument( dynamic_cast<SdDrawDocument*>(
     583           0 :                 pTreeListBoxTransferable->GetSourceDoc()->AllocModel()));
     584             :         //        pTransferable->SetView(&mrSlideSorter.GetView());
     585             : 
     586             :         // Set page bookmark list.
     587           0 :         std::vector<rtl::OUString> aPageBookmarks;
     588           0 :         aPageBookmarks.push_back(sBookmark);
     589           0 :         pTransferable->SetPageBookmarks(aPageBookmarks, false);
     590             : 
     591             :         // Replace the view referenced by the transferable with the
     592             :         // corresponding slide sorter view.
     593           0 :         pTransferable->SetView(&pSlideSorterViewShell->GetSlideSorter().GetView());
     594             : 
     595           0 :         return pNewTransferable;
     596             :     }
     597             :     while (false);
     598             : 
     599           0 :     return ::boost::shared_ptr<SdTransferable::UserData>();
     600             : }
     601             : 
     602             : 
     603             : 
     604             : 
     605           0 : void Clipboard::StartDrag (
     606             :     const Point& rPosition,
     607             :     ::Window* pWindow)
     608             : {
     609           0 :     maPagesToRemove.clear();
     610           0 :     maPagesToSelect.clear();
     611           0 :     mbUpdateSelectionPending = false;
     612           0 :     CreateSlideTransferable(pWindow, sal_True);
     613             : 
     614             :     mrController.GetInsertionIndicatorHandler()->UpdatePosition(
     615             :         rPosition,
     616           0 :         InsertionIndicatorHandler::UnknownMode);
     617           0 : }
     618             : 
     619             : 
     620             : 
     621             : 
     622           0 : void Clipboard::DragFinished (sal_Int8 nDropAction)
     623             : {
     624           0 :     if (mnDragFinishedUserEventId == 0)
     625             :     {
     626           0 :         if ( ! Application::PostUserEvent(
     627             :             mnDragFinishedUserEventId,
     628             :             LINK(this, Clipboard, ProcessDragFinished),
     629           0 :             reinterpret_cast<void*>(nDropAction)))
     630             :         {
     631           0 :             mnDragFinishedUserEventId = 0;
     632             :         }
     633             :     }
     634           0 : }
     635             : 
     636             : 
     637             : 
     638             : 
     639           0 : IMPL_LINK(Clipboard, ProcessDragFinished, void*, pUserData)
     640             : {
     641           0 :     const sal_Int8 nDropAction (static_cast<sal_Int8>(reinterpret_cast<sal_IntPtr>(pUserData)));
     642             : 
     643           0 :     mnDragFinishedUserEventId = 0;
     644             : 
     645             :     // Hide the substitution display and insertion indicator.
     646           0 :     ::rtl::Reference<SelectionFunction> pFunction (mrController.GetCurrentSelectionFunction());
     647           0 :     if (pFunction.is())
     648           0 :         pFunction->NotifyDragFinished();
     649             : 
     650           0 :     PageSelector& rSelector (mrController.GetPageSelector());
     651           0 :     if ((nDropAction & DND_ACTION_MOVE) != 0
     652           0 :         && ! maPagesToRemove.empty())
     653             :     {
     654             :         // Remove the pages that have been moved to another place (possibly
     655             :         // in the same document.)
     656           0 :         rSelector.DeselectAllPages();
     657           0 :         PageList::iterator aDraggedPage;
     658           0 :         for (aDraggedPage=maPagesToRemove.begin();
     659           0 :              aDraggedPage!=maPagesToRemove.end();
     660             :              ++aDraggedPage)
     661             :         {
     662           0 :             rSelector.SelectPage(*aDraggedPage);
     663             :         }
     664           0 :         mrController.GetSelectionManager()->DeleteSelectedPages();
     665             :     }
     666           0 :     mpUndoContext.reset();
     667           0 :     mpSelectionObserverContext.reset();
     668             : 
     669           0 :     return 1;
     670             : }
     671             : 
     672             : 
     673             : 
     674             : 
     675           0 : sal_Int8 Clipboard::AcceptDrop (
     676             :     const AcceptDropEvent& rEvent,
     677             :     DropTargetHelper& rTargetHelper,
     678             :     ::sd::Window* pTargetWindow,
     679             :     sal_uInt16 nPage,
     680             :     sal_uInt16 nLayer)
     681             : {
     682           0 :     sal_Int8 nAction (DND_ACTION_NONE);
     683             : 
     684           0 :     const Clipboard::DropType eDropType (IsDropAccepted(rTargetHelper));
     685             : 
     686           0 :     switch (eDropType)
     687             :     {
     688             :         case DT_PAGE:
     689             :         case DT_PAGE_FROM_NAVIGATOR:
     690             :         {
     691             :             // Accept a drop.
     692           0 :             nAction = rEvent.mnAction;
     693             : 
     694             :             // Use the copy action when the drop action is the default, i.e. not
     695             :             // explicitly set to move or link, and when the source and
     696             :             // target models are not the same.
     697           0 :             SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
     698           0 :             if (pDragTransferable != NULL
     699           0 :                 && pDragTransferable->IsPageTransferable()
     700             :                 && ((rEvent.maDragEvent.DropAction
     701             :                         & ::com::sun::star::datatransfer::dnd::DNDConstants::ACTION_DEFAULT) != 0)
     702           0 :                 && (mrSlideSorter.GetModel().GetDocument()->GetDocSh()
     703           0 :                     != pDragTransferable->GetPageDocShell()))
     704             :             {
     705           0 :                 nAction = DND_ACTION_COPY;
     706             :             }
     707           0 :             else if (IsInsertionTrivial(pDragTransferable, nAction))
     708             :             {
     709           0 :                 nAction = DND_ACTION_NONE;
     710             :             }
     711             : 
     712             :             // Show the insertion marker and the substitution for a drop.
     713             :             SelectionFunction* pSelectionFunction = dynamic_cast<SelectionFunction*>(
     714           0 :                 mrSlideSorter.GetViewShell()->GetCurrentFunction().get());
     715           0 :             if (pSelectionFunction != NULL)
     716           0 :                 pSelectionFunction->MouseDragged(rEvent, nAction);
     717             : 
     718             :             // Scroll the window when the mouse reaches the window border.
     719             :             //            mrController.GetScrollBarManager().AutoScroll (rEvent.maPosPixel);
     720             :         }
     721           0 :         break;
     722             : 
     723             :         case DT_SHAPE:
     724             :             nAction = ExecuteOrAcceptShapeDrop(
     725             :                 DC_ACCEPT,
     726             :                 rEvent.maPosPixel,
     727             :                 &rEvent,
     728             :                 rTargetHelper,
     729             :                 pTargetWindow,
     730             :                 nPage,
     731           0 :                 nLayer);
     732           0 :             break;
     733             : 
     734             :         default:
     735             :         case DT_NONE:
     736           0 :             nAction = DND_ACTION_NONE;
     737           0 :             break;
     738             :     }
     739             : 
     740           0 :     return nAction;
     741             : }
     742             : 
     743             : 
     744             : 
     745             : 
     746           0 : sal_Int8 Clipboard::ExecuteDrop (
     747             :     const ExecuteDropEvent& rEvent,
     748             :     DropTargetHelper& rTargetHelper,
     749             :     ::sd::Window* pTargetWindow,
     750             :     sal_uInt16 nPage,
     751             :     sal_uInt16 nLayer)
     752             : {
     753           0 :     sal_Int8 nResult = DND_ACTION_NONE;
     754           0 :     mpUndoContext.reset();
     755           0 :     const Clipboard::DropType eDropType (IsDropAccepted(rTargetHelper));
     756             : 
     757           0 :     switch (eDropType)
     758             :     {
     759             :         case DT_PAGE:
     760             :         case DT_PAGE_FROM_NAVIGATOR:
     761             :         {
     762           0 :             SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
     763             :             const Point aEventModelPosition (
     764           0 :                 pTargetWindow->PixelToLogic (rEvent.maPosPixel));
     765           0 :             const sal_Int32 nXOffset (labs (pDragTransferable->GetStartPos().X()
     766           0 :                 - aEventModelPosition.X()));
     767           0 :             const sal_Int32 nYOffset (labs (pDragTransferable->GetStartPos().Y()
     768           0 :                 - aEventModelPosition.Y()));
     769             :             bool bContinue =
     770           0 :                 ( pDragTransferable->GetView() != &mrSlideSorter.GetView() )
     771           0 :                 || ( nXOffset >= 2 && nYOffset >= 2 );
     772             : 
     773             :             ::boost::shared_ptr<InsertionIndicatorHandler> pInsertionIndicatorHandler(
     774           0 :                         mrController.GetInsertionIndicatorHandler());
     775             :             // Get insertion position and then turn off the insertion indicator.
     776           0 :             pInsertionIndicatorHandler->UpdatePosition(aEventModelPosition, rEvent.mnAction);
     777             :             //            sal_uInt16 nIndex = DetermineInsertPosition(*pDragTransferable);
     778             : 
     779             :             // Do not process the insertion when it is trivial,
     780             :             // i.e. would insert pages at their original place.
     781           0 :             if (IsInsertionTrivial(pDragTransferable, rEvent.mnAction))
     782           0 :                 bContinue = false;
     783             : 
     784             :             // Tell the insertion indicator handler to hide before the model
     785             :             // is modified.  Doing it later may result in page objects whose
     786             :             // animation state is not properly reset because they are then
     787             :             // in another run then before the model change.
     788           0 :             pInsertionIndicatorHandler->End(Animator::AM_Immediate);
     789             : 
     790           0 :             if (bContinue)
     791             :             {
     792           0 :                 SlideSorterController::ModelChangeLock aModelChangeLock (mrController);
     793             : 
     794             :                 // Handle a general drop operation.
     795             :                 mpUndoContext.reset(new UndoContext (
     796           0 :                     mrSlideSorter.GetModel().GetDocument(),
     797           0 :                     mrSlideSorter.GetViewShell()->GetViewShellBase().GetMainViewShell()));
     798           0 :                 mpSelectionObserverContext.reset(new SelectionObserver::Context(mrSlideSorter));
     799             : 
     800           0 :                 HandlePageDrop(*pDragTransferable);
     801           0 :                 nResult = rEvent.mnAction;
     802             : 
     803             :                 // We leave the undo context alive for when moving or
     804             :                 // copying inside one view then the actions in
     805             :                 // NotifyDragFinished should be covered as well as
     806             :                 // well as the ones above.
     807             :             }
     808             : 
     809             :             // When the pages originated in another slide sorter then
     810             :             // only that is notified automatically about the drag
     811             :             // operation being finished.  Because the target slide sorter
     812             :             // has be notified, too, add a callback for that.
     813             :             ::boost::shared_ptr<TransferableData> pSlideSorterTransferable (
     814           0 :                 TransferableData::GetFromTransferable(pDragTransferable));
     815             :             BOOST_ASSERT(pSlideSorterTransferable);
     816           0 :             if (pSlideSorterTransferable
     817           0 :                 && pSlideSorterTransferable->GetSourceViewShell() != mrSlideSorter.GetViewShell())
     818             :             {
     819           0 :                 DragFinished(nResult);
     820             :             }
     821             : 
     822             :             // Notify the receiving selection function that drag-and-drop is
     823             :             // finished and the substitution handler can be released.
     824             :             ::rtl::Reference<SelectionFunction> pFunction (
     825           0 :                 mrController.GetCurrentSelectionFunction());
     826           0 :             if (pFunction.is())
     827           0 :                 pFunction->NotifyDragFinished();
     828             :         }
     829           0 :         break;
     830             : 
     831             :         case DT_SHAPE:
     832             :             nResult = ExecuteOrAcceptShapeDrop(
     833             :                 DC_EXECUTE,
     834             :                 rEvent.maPosPixel,
     835             :                 &rEvent,
     836             :                 rTargetHelper,
     837             :                 pTargetWindow,
     838             :                 nPage,
     839           0 :                 nLayer);
     840           0 :             break;
     841             : 
     842             :         default:
     843             :         case DT_NONE:
     844           0 :             break;
     845             :     }
     846             : 
     847           0 :     return nResult;
     848             : }
     849             : 
     850             : 
     851             : 
     852             : 
     853           0 : bool Clipboard::IsInsertionTrivial (
     854             :     SdTransferable* pTransferable,
     855             :     const sal_Int8 nDndAction) const
     856             : {
     857             :     ::boost::shared_ptr<TransferableData> pSlideSorterTransferable (
     858           0 :         TransferableData::GetFromTransferable(pTransferable));
     859           0 :     if (pSlideSorterTransferable
     860           0 :         && pSlideSorterTransferable->GetSourceViewShell() != mrSlideSorter.GetViewShell())
     861           0 :         return false;
     862           0 :     return mrController.GetInsertionIndicatorHandler()->IsInsertionTrivial(nDndAction);
     863             : }
     864             : 
     865             : 
     866             : 
     867             : 
     868           0 : void Clipboard::Abort (void)
     869             : {
     870           0 :     if (mpSelectionObserverContext)
     871             :     {
     872           0 :         mpSelectionObserverContext->Abort();
     873           0 :         mpSelectionObserverContext.reset();
     874             :     }
     875           0 : }
     876             : 
     877             : 
     878             : 
     879             : 
     880           0 : sal_uInt16 Clipboard::DetermineInsertPosition (const SdTransferable& )
     881             : {
     882             :     // Tell the model to move the dragged pages behind the one with the
     883             :     // index nInsertionIndex which first has to be transformed into an index
     884             :     // understandable by the document.
     885             :     const sal_Int32 nInsertionIndex (
     886           0 :         mrController.GetInsertionIndicatorHandler()->GetInsertionPageIndex());
     887             : 
     888             :     // Convert to insertion index to that of an SdModel.
     889           0 :     if (nInsertionIndex >= 0)
     890           0 :         return mrSlideSorter.GetModel().GetCoreIndex(nInsertionIndex);
     891             :     else
     892           0 :         return 0;
     893             : }
     894             : 
     895             : 
     896             : 
     897             : 
     898           0 : sal_uInt16 Clipboard::InsertSlides (
     899             :     const SdTransferable& rTransferable,
     900             :     sal_uInt16 nInsertPosition)
     901             : {
     902             :     sal_uInt16 nInsertedPageCount = ViewClipboard::InsertSlides (
     903             :         rTransferable,
     904           0 :         nInsertPosition);
     905             : 
     906             :     // Remember the inserted pages so that they can be selected when the
     907             :     // operation is finished.
     908           0 :     maPagesToSelect.clear();
     909           0 :     SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument();
     910           0 :     if (pDocument != NULL)
     911           0 :         for (sal_Int32 i=0; i<=nInsertedPageCount; i+=2)
     912             :             maPagesToSelect.push_back(
     913           0 :                 dynamic_cast<SdPage*>(pDocument->GetPage(nInsertPosition+i)));
     914             : 
     915           0 :     mbUpdateSelectionPending |= (nInsertedPageCount>0);
     916             : 
     917           0 :     return nInsertedPageCount;
     918             : }
     919             : 
     920             : 
     921             : 
     922             : 
     923           0 : Clipboard::DropType Clipboard::IsDropAccepted (DropTargetHelper&) const
     924             : {
     925           0 :     const SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
     926           0 :     if (pDragTransferable == NULL)
     927           0 :         return DT_NONE;
     928             : 
     929           0 :     if (pDragTransferable->IsPageTransferable())
     930             :     {
     931           0 :         if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE)
     932           0 :             return DT_PAGE;
     933             :         else
     934           0 :             return DT_NONE;
     935             :     }
     936             : 
     937             :     const SdPageObjsTLB::SdPageObjsTransferable* pPageObjsTransferable
     938           0 :         = dynamic_cast<const SdPageObjsTLB::SdPageObjsTransferable*>(pDragTransferable);
     939           0 :     if (pPageObjsTransferable != NULL)
     940           0 :         return DT_PAGE_FROM_NAVIGATOR;
     941             : 
     942           0 :     return DT_SHAPE;
     943             : }
     944             : 
     945             : 
     946             : 
     947             : 
     948           0 : sal_Int8 Clipboard::ExecuteOrAcceptShapeDrop (
     949             :     DropCommand eCommand,
     950             :     const Point& rPosition,
     951             :     const void* pDropEvent,
     952             :     DropTargetHelper& rTargetHelper,
     953             :     ::sd::Window* pTargetWindow,
     954             :     sal_uInt16 nPage,
     955             :     sal_uInt16 nLayer)
     956             : {
     957           0 :     sal_Int8 nResult = 0;
     958             : 
     959             :     // The dropping of a shape is accepted or executed only when there is
     960             :     // DrawViewShell available to which we can forward this call.  This has
     961             :     // technical reasons:  The actual code to accept or execute a shape drop
     962             :     // is implemented in the ViewShell class and uses the page view of the
     963             :     // main edit view.  This is not possible without a DrawViewShell.
     964           0 :     ::boost::shared_ptr<DrawViewShell> pDrawViewShell;
     965           0 :     if (mrSlideSorter.GetViewShell() != NULL)
     966             :         pDrawViewShell = ::boost::dynamic_pointer_cast<DrawViewShell>(
     967           0 :             mrSlideSorter.GetViewShell()->GetViewShellBase().GetMainViewShell());
     968           0 :     if (pDrawViewShell.get() != NULL
     969           0 :         && (pDrawViewShell->GetShellType() == ViewShell::ST_IMPRESS
     970           0 :             || pDrawViewShell->GetShellType() == ViewShell::ST_DRAW))
     971             :     {
     972             :         // The drop is only accepted or executed when it takes place over a
     973             :         // page object.  Therefore we replace a missing page number by the
     974             :         // number of the page under the mouse.
     975           0 :         if (nPage == SDRPAGE_NOTFOUND)
     976             :         {
     977             :             model::SharedPageDescriptor pDescriptor (
     978           0 :                 mrSlideSorter.GetModel().GetPageDescriptor(
     979           0 :                     mrSlideSorter.GetView().GetPageIndexAtPoint(rPosition)));
     980           0 :             if (pDescriptor)
     981           0 :                 nPage = pDescriptor->GetPageIndex();
     982             :         }
     983             : 
     984             :         // Now comes the code that is different for the Execute and Accept:
     985             :         // We simply forward the call to the AcceptDrop() or ExecuteDrop()
     986             :         // methods of the DrawViewShell in the center pane.
     987           0 :         if (nPage != SDRPAGE_NOTFOUND)
     988           0 :             switch (eCommand)
     989             :             {
     990             :                 case DC_ACCEPT:
     991           0 :                     nResult = pDrawViewShell->AcceptDrop(
     992             :                         *reinterpret_cast<const AcceptDropEvent*>(pDropEvent),
     993             :                         rTargetHelper,
     994             :                         pTargetWindow,
     995             :                         nPage,
     996           0 :                         nLayer);
     997           0 :                     break;
     998             : 
     999             :                 case DC_EXECUTE:
    1000           0 :                     nResult = pDrawViewShell->ExecuteDrop(
    1001             :                         *reinterpret_cast<const ExecuteDropEvent*>(pDropEvent),
    1002             :                         rTargetHelper,
    1003             :                         pTargetWindow,
    1004             :                         nPage,
    1005           0 :                         nLayer);
    1006           0 :                     break;
    1007             :             }
    1008             :     }
    1009             : 
    1010           0 :     return nResult;
    1011             : }
    1012             : 
    1013             : 
    1014             : 
    1015           9 : } } } // end of namespace ::sd::slidesorter::controller
    1016             : 
    1017             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10