LCOV - code coverage report
Current view: top level - sd/source/ui/slidesorter/controller - SlsClipboard.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 386 0.0 %
Date: 2014-04-14 Functions: 0 31 0.0 %
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(SD_RESSTR(STRING_DRAG_AND_DROP_PAGES));
     125             :             else
     126           0 :                 mpDocument->BegUndo(SD_RESSTR(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 :     rtl::Reference<FuPoor> 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, 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<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<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<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           0 :             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 :             pTransferable->StartDrag (pActionWindow, DND_ACTION_COPY | DND_ACTION_MOVE);
     501             :         }
     502             :         else
     503           0 :             pTransferable->CopyToClipboard (pActionWindow);
     504           0 :     }
     505           0 : }
     506             : 
     507             : 
     508             : 
     509             : 
     510           0 : ::boost::shared_ptr<SdTransferable::UserData> Clipboard::CreateTransferableUserData (SdTransferable* pTransferable)
     511             : {
     512             :     do
     513             :     {
     514             :         SdPageObjsTLB::SdPageObjsTransferable* pTreeListBoxTransferable
     515           0 :             = dynamic_cast<SdPageObjsTLB::SdPageObjsTransferable*>(pTransferable);
     516           0 :         if (pTreeListBoxTransferable == NULL)
     517           0 :             break;
     518             : 
     519             :         // Find view shell for the document of the transferable.
     520             :         ::sd::ViewShell* pViewShell
     521           0 :               = SdPageObjsTLB::GetViewShellForDocShell(pTreeListBoxTransferable->GetDocShell());
     522           0 :         if (pViewShell == NULL)
     523           0 :             break;
     524             : 
     525             :         // Find slide sorter for the document of the transferable.
     526             :         SlideSorterViewShell* pSlideSorterViewShell
     527           0 :             = SlideSorterViewShell::GetSlideSorter(pViewShell->GetViewShellBase());
     528           0 :         if (pSlideSorterViewShell == NULL)
     529           0 :             break;
     530           0 :         SlideSorter& rSlideSorter (pSlideSorterViewShell->GetSlideSorter());
     531             : 
     532             :         // Get bookmark from transferable.
     533           0 :         TransferableDataHelper  aDataHelper (pTransferable);
     534           0 :         INetBookmark aINetBookmark;
     535           0 :         if ( ! aDataHelper.GetINetBookmark(SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, aINetBookmark))
     536           0 :             break;
     537           0 :         const OUString sURL (aINetBookmark.GetURL());
     538           0 :         const sal_Int32 nIndex (sURL.indexOf((sal_Unicode)'#'));
     539           0 :         if (nIndex == -1)
     540           0 :             break;
     541           0 :         OUString sBookmark (sURL.copy(nIndex+1));
     542             : 
     543             :         // Make sure that the bookmark points to a page.
     544           0 :         SdDrawDocument* pTransferableDocument = rSlideSorter.GetModel().GetDocument();
     545           0 :         if (pTransferableDocument == NULL)
     546           0 :             break;
     547           0 :         sal_Bool bIsMasterPage = sal_False;
     548           0 :         const sal_uInt16 nPageIndex (pTransferableDocument->GetPageByName(sBookmark, bIsMasterPage));
     549           0 :         if (nPageIndex == SDRPAGE_NOTFOUND)
     550           0 :             break;
     551             : 
     552             :         // Create preview.
     553           0 :         ::std::vector<TransferableData::Representative> aRepresentatives;
     554           0 :         aRepresentatives.reserve(1);
     555             :         ::boost::shared_ptr<cache::PageCache> pPreviewCache (
     556           0 :             rSlideSorter.GetView().GetPreviewCache());
     557           0 :         model::SharedPageDescriptor pDescriptor (rSlideSorter.GetModel().GetPageDescriptor((nPageIndex-1)/2));
     558           0 :         if ( ! pDescriptor || pDescriptor->GetPage()==NULL)
     559           0 :             break;
     560           0 :         Bitmap aPreview (pPreviewCache->GetPreviewBitmap(pDescriptor->GetPage(), false));
     561             :         aRepresentatives.push_back(TransferableData::Representative(
     562             :                 aPreview,
     563           0 :                 pDescriptor->HasState(model::PageDescriptor::ST_Excluded)));
     564             : 
     565             :         // Remember the page in maPagesToRemove so that it can be removed
     566             :         // when drag and drop action is "move".
     567           0 :         Clipboard& rOtherClipboard (pSlideSorterViewShell->GetSlideSorter().GetController().GetClipboard());
     568           0 :         rOtherClipboard.maPagesToRemove.clear();
     569           0 :         rOtherClipboard.maPagesToRemove.push_back(pDescriptor->GetPage());
     570             : 
     571             :         // Create the new transferable.
     572             :         ::boost::shared_ptr<SdTransferable::UserData> pNewTransferable (
     573             :             new TransferableData(
     574             :                 pSlideSorterViewShell,
     575           0 :                 aRepresentatives));
     576             :         pTransferable->SetWorkDocument( dynamic_cast<SdDrawDocument*>(
     577           0 :                 pTreeListBoxTransferable->GetSourceDoc()->AllocModel()));
     578             :         //        pTransferable->SetView(&mrSlideSorter.GetView());
     579             : 
     580             :         // Set page bookmark list.
     581           0 :         std::vector<OUString> aPageBookmarks;
     582           0 :         aPageBookmarks.push_back(sBookmark);
     583           0 :         pTransferable->SetPageBookmarks(aPageBookmarks, false);
     584             : 
     585             :         // Replace the view referenced by the transferable with the
     586             :         // corresponding slide sorter view.
     587           0 :         pTransferable->SetView(&pSlideSorterViewShell->GetSlideSorter().GetView());
     588             : 
     589           0 :         return pNewTransferable;
     590             :     }
     591             :     while (false);
     592             : 
     593           0 :     return ::boost::shared_ptr<SdTransferable::UserData>();
     594             : }
     595             : 
     596             : 
     597             : 
     598             : 
     599           0 : void Clipboard::StartDrag (
     600             :     const Point& rPosition,
     601             :     ::Window* pWindow)
     602             : {
     603           0 :     maPagesToRemove.clear();
     604           0 :     maPagesToSelect.clear();
     605           0 :     mbUpdateSelectionPending = false;
     606           0 :     CreateSlideTransferable(pWindow, true);
     607             : 
     608             :     mrController.GetInsertionIndicatorHandler()->UpdatePosition(
     609             :         rPosition,
     610           0 :         InsertionIndicatorHandler::UnknownMode);
     611           0 : }
     612             : 
     613             : 
     614             : 
     615             : 
     616           0 : void Clipboard::DragFinished (sal_Int8 nDropAction)
     617             : {
     618           0 :     if (mnDragFinishedUserEventId == 0)
     619             :     {
     620           0 :         if ( ! Application::PostUserEvent(
     621             :             mnDragFinishedUserEventId,
     622             :             LINK(this, Clipboard, ProcessDragFinished),
     623           0 :             reinterpret_cast<void*>(nDropAction)))
     624             :         {
     625           0 :             mnDragFinishedUserEventId = 0;
     626             :         }
     627             :     }
     628           0 : }
     629             : 
     630             : 
     631             : 
     632             : 
     633           0 : IMPL_LINK(Clipboard, ProcessDragFinished, void*, pUserData)
     634             : {
     635           0 :     const sal_Int8 nDropAction (static_cast<sal_Int8>(reinterpret_cast<sal_IntPtr>(pUserData)));
     636             : 
     637           0 :     mnDragFinishedUserEventId = 0;
     638             : 
     639             :     // Hide the substitution display and insertion indicator.
     640           0 :     ::rtl::Reference<SelectionFunction> pFunction (mrController.GetCurrentSelectionFunction());
     641           0 :     if (pFunction.is())
     642           0 :         pFunction->NotifyDragFinished();
     643             : 
     644           0 :     PageSelector& rSelector (mrController.GetPageSelector());
     645           0 :     if ((nDropAction & DND_ACTION_MOVE) != 0
     646           0 :         && ! maPagesToRemove.empty())
     647             :     {
     648             :         // Remove the pages that have been moved to another place (possibly
     649             :         // in the same document.)
     650           0 :         rSelector.DeselectAllPages();
     651           0 :         PageList::iterator aDraggedPage;
     652           0 :         for (aDraggedPage=maPagesToRemove.begin();
     653           0 :              aDraggedPage!=maPagesToRemove.end();
     654             :              ++aDraggedPage)
     655             :         {
     656           0 :             rSelector.SelectPage(*aDraggedPage);
     657             :         }
     658           0 :         mrController.GetSelectionManager()->DeleteSelectedPages();
     659             :     }
     660           0 :     mpUndoContext.reset();
     661           0 :     mpSelectionObserverContext.reset();
     662             : 
     663           0 :     return 1;
     664             : }
     665             : 
     666             : 
     667             : 
     668             : 
     669           0 : sal_Int8 Clipboard::AcceptDrop (
     670             :     const AcceptDropEvent& rEvent,
     671             :     DropTargetHelper& rTargetHelper,
     672             :     ::sd::Window* pTargetWindow,
     673             :     sal_uInt16 nPage,
     674             :     sal_uInt16 nLayer)
     675             : {
     676           0 :     sal_Int8 nAction (DND_ACTION_NONE);
     677             : 
     678           0 :     const Clipboard::DropType eDropType (IsDropAccepted(rTargetHelper));
     679             : 
     680           0 :     switch (eDropType)
     681             :     {
     682             :         case DT_PAGE:
     683             :         case DT_PAGE_FROM_NAVIGATOR:
     684             :         {
     685             :             // Accept a drop.
     686           0 :             nAction = rEvent.mnAction;
     687             : 
     688             :             // Use the copy action when the drop action is the default, i.e. not
     689             :             // explicitly set to move or link, and when the source and
     690             :             // target models are not the same.
     691           0 :             SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
     692           0 :             if (pDragTransferable != NULL
     693           0 :                 && pDragTransferable->IsPageTransferable()
     694           0 :                 && ((rEvent.maDragEvent.DropAction
     695           0 :                         & ::com::sun::star::datatransfer::dnd::DNDConstants::ACTION_DEFAULT) != 0)
     696           0 :                 && (mrSlideSorter.GetModel().GetDocument()->GetDocSh()
     697           0 :                     != pDragTransferable->GetPageDocShell()))
     698             :             {
     699           0 :                 nAction = DND_ACTION_COPY;
     700             :             }
     701           0 :             else if (IsInsertionTrivial(pDragTransferable, nAction))
     702             :             {
     703           0 :                 nAction = DND_ACTION_NONE;
     704             :             }
     705             : 
     706             :             // Show the insertion marker and the substitution for a drop.
     707             :             SelectionFunction* pSelectionFunction = dynamic_cast<SelectionFunction*>(
     708           0 :                 mrSlideSorter.GetViewShell()->GetCurrentFunction().get());
     709           0 :             if (pSelectionFunction != NULL)
     710           0 :                 pSelectionFunction->MouseDragged(rEvent, nAction);
     711             : 
     712             :             // Scroll the window when the mouse reaches the window border.
     713             :             //            mrController.GetScrollBarManager().AutoScroll (rEvent.maPosPixel);
     714             :         }
     715           0 :         break;
     716             : 
     717             :         case DT_SHAPE:
     718             :             nAction = ExecuteOrAcceptShapeDrop(
     719             :                 DC_ACCEPT,
     720             :                 rEvent.maPosPixel,
     721             :                 &rEvent,
     722             :                 rTargetHelper,
     723             :                 pTargetWindow,
     724             :                 nPage,
     725           0 :                 nLayer);
     726           0 :             break;
     727             : 
     728             :         default:
     729             :         case DT_NONE:
     730           0 :             nAction = DND_ACTION_NONE;
     731           0 :             break;
     732             :     }
     733             : 
     734           0 :     return nAction;
     735             : }
     736             : 
     737             : 
     738             : 
     739             : 
     740           0 : sal_Int8 Clipboard::ExecuteDrop (
     741             :     const ExecuteDropEvent& rEvent,
     742             :     DropTargetHelper& rTargetHelper,
     743             :     ::sd::Window* pTargetWindow,
     744             :     sal_uInt16 nPage,
     745             :     sal_uInt16 nLayer)
     746             : {
     747           0 :     sal_Int8 nResult = DND_ACTION_NONE;
     748           0 :     mpUndoContext.reset();
     749           0 :     const Clipboard::DropType eDropType (IsDropAccepted(rTargetHelper));
     750             : 
     751           0 :     switch (eDropType)
     752             :     {
     753             :         case DT_PAGE:
     754             :         case DT_PAGE_FROM_NAVIGATOR:
     755             :         {
     756           0 :             SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
     757             :             const Point aEventModelPosition (
     758           0 :                 pTargetWindow->PixelToLogic (rEvent.maPosPixel));
     759           0 :             const sal_Int32 nXOffset (labs (pDragTransferable->GetStartPos().X()
     760           0 :                 - aEventModelPosition.X()));
     761           0 :             const sal_Int32 nYOffset (labs (pDragTransferable->GetStartPos().Y()
     762           0 :                 - aEventModelPosition.Y()));
     763             :             bool bContinue =
     764           0 :                 ( pDragTransferable->GetView() != &mrSlideSorter.GetView() )
     765           0 :                 || ( nXOffset >= 2 && nYOffset >= 2 );
     766             : 
     767             :             ::boost::shared_ptr<InsertionIndicatorHandler> pInsertionIndicatorHandler(
     768           0 :                         mrController.GetInsertionIndicatorHandler());
     769             :             // Get insertion position and then turn off the insertion indicator.
     770           0 :             pInsertionIndicatorHandler->UpdatePosition(aEventModelPosition, rEvent.mnAction);
     771             :             //            sal_uInt16 nIndex = DetermineInsertPosition(*pDragTransferable);
     772             : 
     773             :             // Do not process the insertion when it is trivial,
     774             :             // i.e. would insert pages at their original place.
     775           0 :             if (IsInsertionTrivial(pDragTransferable, rEvent.mnAction))
     776           0 :                 bContinue = false;
     777             : 
     778             :             // Tell the insertion indicator handler to hide before the model
     779             :             // is modified.  Doing it later may result in page objects whose
     780             :             // animation state is not properly reset because they are then
     781             :             // in another run then before the model change.
     782           0 :             pInsertionIndicatorHandler->End(Animator::AM_Immediate);
     783             : 
     784           0 :             if (bContinue)
     785             :             {
     786           0 :                 SlideSorterController::ModelChangeLock aModelChangeLock (mrController);
     787             : 
     788             :                 // Handle a general drop operation.
     789             :                 mpUndoContext.reset(new UndoContext (
     790           0 :                     mrSlideSorter.GetModel().GetDocument(),
     791           0 :                     mrSlideSorter.GetViewShell()->GetViewShellBase().GetMainViewShell()));
     792           0 :                 mpSelectionObserverContext.reset(new SelectionObserver::Context(mrSlideSorter));
     793             : 
     794           0 :                 HandlePageDrop(*pDragTransferable);
     795           0 :                 nResult = rEvent.mnAction;
     796             : 
     797             :                 // We leave the undo context alive for when moving or
     798             :                 // copying inside one view then the actions in
     799             :                 // NotifyDragFinished should be covered as well as
     800             :                 // well as the ones above.
     801             :             }
     802             : 
     803             :             // When the pages originated in another slide sorter then
     804             :             // only that is notified automatically about the drag
     805             :             // operation being finished.  Because the target slide sorter
     806             :             // has be notified, too, add a callback for that.
     807             :             ::boost::shared_ptr<TransferableData> pSlideSorterTransferable (
     808           0 :                 TransferableData::GetFromTransferable(pDragTransferable));
     809             :             BOOST_ASSERT(pSlideSorterTransferable);
     810           0 :             if (pSlideSorterTransferable
     811           0 :                 && pSlideSorterTransferable->GetSourceViewShell() != mrSlideSorter.GetViewShell())
     812             :             {
     813           0 :                 DragFinished(nResult);
     814             :             }
     815             : 
     816             :             // Notify the receiving selection function that drag-and-drop is
     817             :             // finished and the substitution handler can be released.
     818             :             ::rtl::Reference<SelectionFunction> pFunction (
     819           0 :                 mrController.GetCurrentSelectionFunction());
     820           0 :             if (pFunction.is())
     821           0 :                 pFunction->NotifyDragFinished();
     822             :         }
     823           0 :         break;
     824             : 
     825             :         case DT_SHAPE:
     826             :             nResult = ExecuteOrAcceptShapeDrop(
     827             :                 DC_EXECUTE,
     828             :                 rEvent.maPosPixel,
     829             :                 &rEvent,
     830             :                 rTargetHelper,
     831             :                 pTargetWindow,
     832             :                 nPage,
     833           0 :                 nLayer);
     834           0 :             break;
     835             : 
     836             :         default:
     837             :         case DT_NONE:
     838           0 :             break;
     839             :     }
     840             : 
     841           0 :     return nResult;
     842             : }
     843             : 
     844             : 
     845             : 
     846             : 
     847           0 : bool Clipboard::IsInsertionTrivial (
     848             :     SdTransferable* pTransferable,
     849             :     const sal_Int8 nDndAction) const
     850             : {
     851             :     ::boost::shared_ptr<TransferableData> pSlideSorterTransferable (
     852           0 :         TransferableData::GetFromTransferable(pTransferable));
     853           0 :     if (pSlideSorterTransferable
     854           0 :         && pSlideSorterTransferable->GetSourceViewShell() != mrSlideSorter.GetViewShell())
     855           0 :         return false;
     856           0 :     return mrController.GetInsertionIndicatorHandler()->IsInsertionTrivial(nDndAction);
     857             : }
     858             : 
     859             : 
     860             : 
     861             : 
     862           0 : void Clipboard::Abort (void)
     863             : {
     864           0 :     if (mpSelectionObserverContext)
     865             :     {
     866           0 :         mpSelectionObserverContext->Abort();
     867           0 :         mpSelectionObserverContext.reset();
     868             :     }
     869           0 : }
     870             : 
     871             : 
     872             : 
     873             : 
     874           0 : sal_uInt16 Clipboard::DetermineInsertPosition (const SdTransferable& )
     875             : {
     876             :     // Tell the model to move the dragged pages behind the one with the
     877             :     // index nInsertionIndex which first has to be transformed into an index
     878             :     // understandable by the document.
     879             :     const sal_Int32 nInsertionIndex (
     880           0 :         mrController.GetInsertionIndicatorHandler()->GetInsertionPageIndex());
     881             : 
     882             :     // Convert to insertion index to that of an SdModel.
     883           0 :     if (nInsertionIndex >= 0)
     884           0 :         return mrSlideSorter.GetModel().GetCoreIndex(nInsertionIndex);
     885             :     else
     886           0 :         return 0;
     887             : }
     888             : 
     889             : 
     890             : 
     891             : 
     892           0 : sal_uInt16 Clipboard::InsertSlides (
     893             :     const SdTransferable& rTransferable,
     894             :     sal_uInt16 nInsertPosition)
     895             : {
     896             :     sal_uInt16 nInsertedPageCount = ViewClipboard::InsertSlides (
     897             :         rTransferable,
     898           0 :         nInsertPosition);
     899             : 
     900             :     // Remember the inserted pages so that they can be selected when the
     901             :     // operation is finished.
     902           0 :     maPagesToSelect.clear();
     903           0 :     SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument();
     904           0 :     if (pDocument != NULL)
     905           0 :         for (sal_Int32 i=0; i<=nInsertedPageCount; i+=2)
     906             :             maPagesToSelect.push_back(
     907           0 :                 dynamic_cast<SdPage*>(pDocument->GetPage(nInsertPosition+i)));
     908             : 
     909           0 :     mbUpdateSelectionPending |= (nInsertedPageCount>0);
     910             : 
     911           0 :     return nInsertedPageCount;
     912             : }
     913             : 
     914             : 
     915             : 
     916             : 
     917           0 : Clipboard::DropType Clipboard::IsDropAccepted (DropTargetHelper&) const
     918             : {
     919           0 :     const SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
     920           0 :     if (pDragTransferable == NULL)
     921           0 :         return DT_NONE;
     922             : 
     923           0 :     if (pDragTransferable->IsPageTransferable())
     924             :     {
     925           0 :         if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE)
     926           0 :             return DT_PAGE;
     927             :         else
     928           0 :             return DT_NONE;
     929             :     }
     930             : 
     931             :     const SdPageObjsTLB::SdPageObjsTransferable* pPageObjsTransferable
     932           0 :         = dynamic_cast<const SdPageObjsTLB::SdPageObjsTransferable*>(pDragTransferable);
     933           0 :     if (pPageObjsTransferable != NULL)
     934           0 :         return DT_PAGE_FROM_NAVIGATOR;
     935             : 
     936           0 :     return DT_SHAPE;
     937             : }
     938             : 
     939             : 
     940             : 
     941             : 
     942           0 : sal_Int8 Clipboard::ExecuteOrAcceptShapeDrop (
     943             :     DropCommand eCommand,
     944             :     const Point& rPosition,
     945             :     const void* pDropEvent,
     946             :     DropTargetHelper& rTargetHelper,
     947             :     ::sd::Window* pTargetWindow,
     948             :     sal_uInt16 nPage,
     949             :     sal_uInt16 nLayer)
     950             : {
     951           0 :     sal_Int8 nResult = 0;
     952             : 
     953             :     // The dropping of a shape is accepted or executed only when there is
     954             :     // DrawViewShell available to which we can forward this call.  This has
     955             :     // technical reasons:  The actual code to accept or execute a shape drop
     956             :     // is implemented in the ViewShell class and uses the page view of the
     957             :     // main edit view.  This is not possible without a DrawViewShell.
     958           0 :     ::boost::shared_ptr<DrawViewShell> pDrawViewShell;
     959           0 :     if (mrSlideSorter.GetViewShell() != NULL)
     960           0 :         pDrawViewShell = ::boost::dynamic_pointer_cast<DrawViewShell>(
     961           0 :             mrSlideSorter.GetViewShell()->GetViewShellBase().GetMainViewShell());
     962           0 :     if (pDrawViewShell.get() != NULL
     963           0 :         && (pDrawViewShell->GetShellType() == ViewShell::ST_IMPRESS
     964           0 :             || pDrawViewShell->GetShellType() == ViewShell::ST_DRAW))
     965             :     {
     966             :         // The drop is only accepted or executed when it takes place over a
     967             :         // page object.  Therefore we replace a missing page number by the
     968             :         // number of the page under the mouse.
     969           0 :         if (nPage == SDRPAGE_NOTFOUND)
     970             :         {
     971             :             model::SharedPageDescriptor pDescriptor (
     972           0 :                 mrSlideSorter.GetModel().GetPageDescriptor(
     973           0 :                     mrSlideSorter.GetView().GetPageIndexAtPoint(rPosition)));
     974           0 :             if (pDescriptor)
     975           0 :                 nPage = pDescriptor->GetPageIndex();
     976             :         }
     977             : 
     978             :         // Now comes the code that is different for the Execute and Accept:
     979             :         // We simply forward the call to the AcceptDrop() or ExecuteDrop()
     980             :         // methods of the DrawViewShell in the center pane.
     981           0 :         if (nPage != SDRPAGE_NOTFOUND)
     982           0 :             switch (eCommand)
     983             :             {
     984             :                 case DC_ACCEPT:
     985           0 :                     nResult = pDrawViewShell->AcceptDrop(
     986             :                         *reinterpret_cast<const AcceptDropEvent*>(pDropEvent),
     987             :                         rTargetHelper,
     988             :                         pTargetWindow,
     989             :                         nPage,
     990           0 :                         nLayer);
     991           0 :                     break;
     992             : 
     993             :                 case DC_EXECUTE:
     994           0 :                     nResult = pDrawViewShell->ExecuteDrop(
     995             :                         *reinterpret_cast<const ExecuteDropEvent*>(pDropEvent),
     996             :                         rTargetHelper,
     997             :                         pTargetWindow,
     998             :                         nPage,
     999           0 :                         nLayer);
    1000           0 :                     break;
    1001             :             }
    1002             :     }
    1003             : 
    1004           0 :     return nResult;
    1005             : }
    1006             : 
    1007             : 
    1008             : 
    1009           0 : } } } // end of namespace ::sd::slidesorter::controller
    1010             : 
    1011             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10