2009-06-17 13:48:12 +0200 aw r273068 : #99385# corrected small error in SCs selection visualisation 2009-06-16 15:45:28 +0200 wg r273021 : i102838 2009-06-16 12:46:07 +0200 wg r273016 : i102833 2009-06-11 17:40:29 +0200 aw r272895 : #i98870# added implementation for getPageCount helper 2009-06-11 16:39:54 +0200 aw r272885 : #i102663#, #i102667#, #i98870# incluide file typo corrected 2009-06-11 16:24:07 +0200 aw r272881 : #i102663#, #i102667#, #i98870# changes to SdrText, it's usage in SdrTextPrimitive2D and to OverlayObject base implementation. Also support for PageCountField added 2009-06-11 16:23:52 +0200 aw r272880 : #i102663#, #i102667#, #i98870# changes to SdrText, it's usage in SdrTextPrimitive2D and to OverlayObject base implementation. Also support for PageCountField added 2009-06-09 13:50:29 +0200 aw r272769 : #i98917# added support for the OverlayHatchRectanglePrimitive to follow rotation with it's hatch; simplified OverlayHatchRect 2009-06-09 13:04:06 +0200 aw r272766 : #i98870# re-added PageNumber identification in SdrTextPrimitive2D::get2DDecomposition 2009-06-08 18:56:05 +0200 aw r272744 : #i99385# added some last corrections to OverlayObjects in SD (had to do some merges on resync, needed to optically check and correct) 2009-06-08 11:17:57 +0200 aw r272725 : cws aw065: corrections after resync 2009-06-08 11:02:25 +0200 aw r272723 : cws aw065: corrections after resync 2009-06-08 10:36:22 +0200 aw r272722 : cws aw065: corrections after resync 2009-06-05 18:57:06 +0200 aw r272712 : CWS-TOOLING: rebase CWS aw065 to trunk@272291 (milestone: DEV300:m49) 2009-06-05 14:56:34 +0200 aw r272690 : #i89784# stripped old stuff no longer needed due to text-to-polygon conversion using primitives 2009-06-05 14:50:07 +0200 aw r272688 : #102091# removed on-model-lock suppression for SdrObject::ActionChanged() 2009-06-05 14:47:29 +0200 aw r272687 : #102091# corrected local value buffering in ScenePrimitive2D::get2DDecomposition 2009-06-03 17:53:32 +0200 aw r272599 : #i89784# version before stripping 2009-06-03 17:52:18 +0200 aw r272598 : #i89784# version before stripping 2009-05-28 17:15:47 +0200 aw r272420 : #i101872# old stuff removed/stripped 2009-05-28 17:15:32 +0200 aw r272419 : #i101872# old stuff removed/stripped 2009-05-28 17:15:15 +0200 aw r272418 : #i101872# old stuff removed/stripped 2009-05-28 17:14:45 +0200 aw r272417 : #i101872# old stuff removed/stripped 2009-05-28 12:13:56 +0200 aw r272396 : #i101872# stable hybrid state 2009-05-28 12:13:46 +0200 aw r272395 : #i101872# stable hybrid state 2009-05-28 12:13:35 +0200 aw r272394 : #i101872# stable hybrid state 2009-05-28 12:13:20 +0200 aw r272393 : #i101872# stable hybrid state 2009-05-28 12:13:05 +0200 aw r272392 : #i101872# stable hybrid state 2009-05-28 12:12:51 +0200 aw r272391 : #i101872# stable hybrid state 2009-05-15 16:56:02 +0200 aw r271952 : #i101872# HitTest unifications 2009-05-15 16:55:22 +0200 aw r271951 : #i101872# HitTest unifications 2009-05-15 16:55:12 +0200 aw r271950 : #i101872# HitTest unifications 2009-05-15 16:55:01 +0200 aw r271949 : #i101872# HitTest unifications 2009-05-15 16:54:51 +0200 aw r271948 : #i101872# HitTest unifications 2009-05-15 16:54:35 +0200 aw r271947 : #i101872# HitTest unifications 2009-05-15 16:54:22 +0200 aw r271946 : #i101872# HitTest unifications 2009-05-12 19:08:38 +0200 aw r271834 : #i101684# corrected AutoShape's preparation of text transformation due to different definitions in TextBounds 2009-05-12 15:44:49 +0200 aw r271827 : #i89784# expanded TextLayouterDevice::getTextOutlines() to support DXArray and X-Font scaling 2009-05-11 19:40:40 +0200 aw r271790 : #i99385# extended HitTest primitive usage, removed IsHdlHit implementations; prepared further HitTest simplifications 2009-05-11 19:40:25 +0200 aw r271789 : #i99385# extended HitTest primitive usage, removed IsHdlHit implementations; prepared further HitTest simplifications 2009-05-11 19:40:12 +0200 aw r271788 : #i99385# extended HitTest primitive usage, removed IsHdlHit implementations; prepared further HitTest simplifications 2009-05-11 13:01:53 +0200 aw r271765 : #i99385# corrections and optimizations 2009-05-08 14:48:40 +0200 aw r271718 : #i1016180# added optimizations in model operations when model is locked 2009-05-08 14:11:45 +0200 aw r271716 : #i101679# added flush() calls to OverlayManager when interaction step is prepared 2009-05-07 17:44:03 +0200 aw r271689 : #i99385# last corrections/changes 2009-05-07 17:43:47 +0200 aw r271688 : #i99385# last corrections/changes 2009-05-07 13:20:09 +0200 aw r271654 : #i99385# added changes from WFH 2009-05-07 13:19:38 +0200 aw r271653 : #i99385# added changes from WFH 2009-05-07 13:19:11 +0200 aw r271652 : #i99385# added changes from WFH 2009-05-07 11:33:17 +0200 aw r271643 : #i99385# corrections after resync 2009-05-07 11:17:31 +0200 aw r271642 : #i99385# corrections after resync 2009-05-06 18:46:53 +0200 aw r271609 : CWS-TOOLING: rebase CWS aw065 to trunk@271427 (milestone: DEV300:m47) 2009-05-05 18:24:03 +0200 aw r271548 : #i101443# force new text decomposition when TextBackgroundColor has changed 2009-05-05 17:44:42 +0200 aw r271542 : #i99385# 3rd round, simplifications and corrections done 2009-05-05 17:44:32 +0200 aw r271541 : #i99385# 3rd round, simplifications and corrections done 2009-05-05 17:44:20 +0200 aw r271540 : #i99385# 3rd round, simplifications and corrections done 2009-05-05 17:44:09 +0200 aw r271539 : #i99385# 3rd round, simplifications and corrections done 2009-05-05 15:48:38 +0200 aw r271527 : #i99385# 2nd round, usages checked and corrected 2009-05-05 15:48:15 +0200 aw r271526 : #i99385# 2nd round, usages checked and corrected 2009-05-05 15:48:03 +0200 aw r271525 : #i99385# 2nd round, usages checked and corrected 2009-05-05 15:47:51 +0200 aw r271524 : #i99385# 2nd round, usages checked and corrected 2009-04-27 18:33:10 +0200 aw r271300 : #i99385# state commit after all implementations are done 2009-04-27 15:36:53 +0200 aw r271283 : #i99385# state commit after all implementations are done 2009-04-27 15:27:49 +0200 aw r271280 : #i99385# state commit after all implementations are done 2009-04-27 15:27:33 +0200 aw r271279 : #i99385# state commit after all implementations are done 2009-04-27 15:27:00 +0200 aw r271278 : #i99385# state commit after all implementations are done 2009-04-27 15:26:15 +0200 aw r271277 : #i99385# state commit after all implementations are done 2009-04-27 15:25:40 +0200 aw r271275 : #i99385# state commit after all implementations are done 2009-04-27 15:25:19 +0200 aw r271274 : #i99385# state commit after all implementations are done 2009-04-27 15:24:00 +0200 aw r271272 : #i99385# state commit after all implementations are done 2009-03-19 17:12:00 +0100 aw r269757 : #i100360# corrected bitmap's PefSize calculation for bitmap filled objects when Bitmap is Pixel-based on it's mapping 2009-02-19 17:09:47 +0100 aw r268298 : #i98917# corrected attributes 2009-02-19 17:09:30 +0100 aw r268297 : #i98917# corrected attributes 2009-02-19 17:08:22 +0100 aw r268296 : #i98917# corrected attributes 2009-02-19 11:56:25 +0100 aw r268268 : #i98870# added extra code to react on PageNumber change 2009-02-18 16:57:24 +0100 aw r268243 : #i98917# in OverlayHatchRect::getGeometry the rotation was not applied to the TopLeft of the centered rectangle, but to the already extended one, thus the visualisation was rotating around the wrong edge
782 lines
24 KiB
C++
782 lines
24 KiB
C++
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2008 by Sun Microsystems, Inc.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* $RCSfile: SlsClipboard.cxx,v $
|
|
* $Revision: 1.27 $
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
#include "precompiled_sd.hxx"
|
|
|
|
#include "controller/SlsClipboard.hxx"
|
|
|
|
#include "SlideSorterViewShell.hxx"
|
|
#include "SlideSorter.hxx"
|
|
#include "model/SlideSorterModel.hxx"
|
|
#include "model/SlsPageDescriptor.hxx"
|
|
#include "model/SlsPageEnumerationProvider.hxx"
|
|
#include "view/SlideSorterView.hxx"
|
|
#include "view/SlsViewOverlay.hxx"
|
|
#include "view/SlsPageObject.hxx"
|
|
#include "controller/SlideSorterController.hxx"
|
|
#include "controller/SlsPageSelector.hxx"
|
|
#include "controller/SlsSelectionFunction.hxx"
|
|
#include "controller/SlsCurrentSlideManager.hxx"
|
|
#include "controller/SlsScrollBarManager.hxx"
|
|
#include "controller/SlsFocusManager.hxx"
|
|
#include "controller/SlsSelectionManager.hxx"
|
|
#include "SlsTransferable.hxx"
|
|
|
|
#include "ViewShellBase.hxx"
|
|
#include "DrawViewShell.hxx"
|
|
#include "Window.hxx"
|
|
#include "fupoor.hxx"
|
|
#include "fuslhide.hxx"
|
|
#include "fuzoom.hxx"
|
|
#include "fucushow.hxx"
|
|
#include "fusldlg.hxx"
|
|
#include "fuexpand.hxx"
|
|
#include "fusumry.hxx"
|
|
#include "app.hrc"
|
|
#include "glob.hrc"
|
|
#include "strings.hrc"
|
|
#include "sdresid.hxx"
|
|
#include "sdxfer.hxx"
|
|
#include "sdmod.hxx"
|
|
#include "sddll.hxx"
|
|
#include "ins_paste.hxx"
|
|
#include "drawdoc.hxx"
|
|
#include "DrawDocShell.hxx"
|
|
#include "sdpage.hxx"
|
|
|
|
#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
|
|
#include <sfx2/request.hxx>
|
|
#include <sfx2/viewfrm.hxx>
|
|
#include <sfx2/bindings.hxx>
|
|
#include <sfx2/docfile.hxx>
|
|
#include <svx/svxids.hrc>
|
|
#include <vcl/msgbox.hxx>
|
|
#include <tools/urlobj.hxx>
|
|
#include <rtl/ustring.hxx>
|
|
#include <vos/mutex.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
|
|
namespace sd { namespace slidesorter { namespace controller {
|
|
|
|
|
|
Clipboard::Clipboard (SlideSorter& rSlideSorter)
|
|
: ViewClipboard(rSlideSorter.GetView()),
|
|
mrSlideSorter(rSlideSorter),
|
|
mrController(mrSlideSorter.GetController()),
|
|
maPagesToRemove(),
|
|
maPagesToSelect(),
|
|
mbUpdateSelectionPending(false)
|
|
{
|
|
}
|
|
|
|
|
|
|
|
|
|
Clipboard::~Clipboard (void)
|
|
{
|
|
}
|
|
|
|
|
|
|
|
|
|
/** With the current implementation the forwarded calls to the current
|
|
function will come back eventually to call the local Do(Cut|Copy|Paste)
|
|
methods. A shortcut is possible but would be an unclean hack.
|
|
*/
|
|
void Clipboard::HandleSlotCall (SfxRequest& rRequest)
|
|
{
|
|
ViewShell* pViewShell = mrSlideSorter.GetViewShell();
|
|
FunctionReference xFunc;
|
|
if (pViewShell != NULL)
|
|
xFunc = pViewShell->GetCurrentFunction();
|
|
switch (rRequest.GetSlot())
|
|
{
|
|
case SID_CUT:
|
|
if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE)
|
|
{
|
|
if(xFunc.is())
|
|
xFunc->DoCut();
|
|
else
|
|
DoCut();
|
|
}
|
|
rRequest.Done();
|
|
break;
|
|
|
|
case SID_COPY:
|
|
if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE)
|
|
{
|
|
if(xFunc.is())
|
|
xFunc->DoCopy();
|
|
else
|
|
DoCopy();
|
|
}
|
|
rRequest.Done();
|
|
break;
|
|
|
|
case SID_PASTE:
|
|
// Prevent redraws while inserting pages from the clipboard
|
|
// because the intermediate inconsistent state might lead to
|
|
// a crash.
|
|
if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE)
|
|
{
|
|
mrSlideSorter.GetView().LockRedraw (TRUE);
|
|
if(xFunc.is())
|
|
xFunc->DoPaste();
|
|
else
|
|
DoPaste();
|
|
mrController.GetSelectionManager()->MakeSelectionVisible();
|
|
mrSlideSorter.GetView().LockRedraw(FALSE);
|
|
}
|
|
rRequest.Done();
|
|
break;
|
|
|
|
case SID_DELETE:
|
|
DoDelete();
|
|
rRequest.Done();
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void Clipboard::DoCut (::Window* pWindow)
|
|
{
|
|
if (mrSlideSorter.GetModel().GetPageCount() > 1)
|
|
{
|
|
DoCopy(pWindow);
|
|
DoDelete(pWindow);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void Clipboard::DoDelete (::Window* )
|
|
{
|
|
if (mrSlideSorter.GetModel().GetPageCount() > 1)
|
|
{
|
|
mrController.GetSelectionManager()->DeleteSelectedPages();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void Clipboard::DoCopy (::Window* pWindow )
|
|
{
|
|
CreateSlideTransferable( pWindow, FALSE );
|
|
}
|
|
|
|
|
|
|
|
|
|
void Clipboard::DoPaste (::Window* pWindow)
|
|
{
|
|
SdTransferable* pClipTransferable = SD_MOD()->pTransferClip;
|
|
|
|
if (pClipTransferable!=NULL && pClipTransferable->IsPageTransferable())
|
|
{
|
|
sal_Int32 nInsertPosition = GetInsertionPosition(pWindow);
|
|
|
|
if (nInsertPosition >= 0)
|
|
{
|
|
// Paste the pages from the clipboard.
|
|
sal_Int32 nInsertPageCount = PasteTransferable(nInsertPosition);
|
|
// Select the pasted pages and make the first of them the
|
|
// current page.
|
|
mrSlideSorter.GetView().GetWindow()->GrabFocus();
|
|
SelectPageRange(nInsertPosition, nInsertPageCount);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
sal_Int32 Clipboard::GetInsertionPosition (::Window* pWindow)
|
|
{
|
|
sal_Int32 nInsertPosition = -1;
|
|
|
|
// Determine the insertion position:
|
|
// a) When the insertion indicator is visible, then at that position.
|
|
// b) When the focus indicator is visible, then before or after the
|
|
// focused page, depending on user input to a dialog.
|
|
// c) When there is a selection but no focus, then after the
|
|
// selection.
|
|
// d) After the last page when there is no selection and no focus.
|
|
|
|
view::InsertionIndicatorOverlay& rInsertionIndicatorOverlay (
|
|
mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay());
|
|
if (rInsertionIndicatorOverlay.isVisible())
|
|
{
|
|
nInsertPosition = rInsertionIndicatorOverlay.GetInsertionPageIndex();
|
|
}
|
|
else if (mrController.GetFocusManager().IsFocusShowing())
|
|
{
|
|
SdInsertPasteDlg aDialog (pWindow);
|
|
if (aDialog.Execute() == RET_OK)
|
|
{
|
|
nInsertPosition = mrController.GetFocusManager().GetFocusedPageIndex();
|
|
if ( ! aDialog.IsInsertBefore())
|
|
nInsertPosition ++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
nInsertPosition = mrController.GetSelectionManager()->GetInsertionPosition();
|
|
}
|
|
|
|
return nInsertPosition;
|
|
}
|
|
|
|
|
|
|
|
|
|
sal_Int32 Clipboard::PasteTransferable (sal_Int32 nInsertPosition)
|
|
{
|
|
SdTransferable* pClipTransferable = SD_MOD()->pTransferClip;
|
|
bool bMergeMasterPages = !pClipTransferable->HasSourceDoc (
|
|
mrSlideSorter.GetModel().GetDocument());
|
|
USHORT nInsertIndex ((USHORT)(nInsertPosition * 2 + 1));
|
|
sal_Int32 nInsertPageCount (0);
|
|
if (pClipTransferable->HasPageBookmarks())
|
|
{
|
|
const List& rBookmarkList = pClipTransferable->GetPageBookmarks();
|
|
const ::vos::OGuard aGuard (Application::GetSolarMutex());
|
|
|
|
nInsertPageCount = (USHORT) rBookmarkList.Count();
|
|
mrSlideSorter.GetModel().GetDocument()->InsertBookmarkAsPage(
|
|
const_cast<List*>(&rBookmarkList),
|
|
NULL,
|
|
FALSE,
|
|
FALSE,
|
|
nInsertIndex,
|
|
FALSE,
|
|
pClipTransferable->GetPageDocShell(),
|
|
TRUE,
|
|
bMergeMasterPages,
|
|
FALSE);
|
|
}
|
|
else
|
|
{
|
|
SfxObjectShell* pShell = pClipTransferable->GetDocShell();
|
|
DrawDocShell* pDataDocSh = (DrawDocShell*)pShell;
|
|
SdDrawDocument* pDataDoc = pDataDocSh->GetDoc();
|
|
|
|
if (pDataDoc!=NULL
|
|
&& pDataDoc->GetSdPageCount(PK_STANDARD))
|
|
{
|
|
const ::vos::OGuard aGuard (Application::GetSolarMutex());
|
|
|
|
bMergeMasterPages = (pDataDoc != mrSlideSorter.GetModel().GetDocument());
|
|
nInsertPageCount = pDataDoc->GetSdPageCount( PK_STANDARD );
|
|
mrSlideSorter.GetModel().GetDocument()->InsertBookmarkAsPage(
|
|
NULL,
|
|
NULL,
|
|
FALSE,
|
|
FALSE,
|
|
nInsertIndex,
|
|
FALSE,
|
|
pDataDocSh,
|
|
TRUE,
|
|
bMergeMasterPages,
|
|
FALSE);
|
|
}
|
|
}
|
|
mrController.HandleModelChange();
|
|
return nInsertPageCount;
|
|
}
|
|
|
|
|
|
|
|
|
|
void Clipboard::SelectPageRange (sal_Int32 nFirstIndex, sal_Int32 nPageCount)
|
|
{
|
|
// Select the newly inserted pages. That are the nInsertPageCount pages
|
|
// after the nInsertIndex position.
|
|
PageSelector& rSelector (mrController.GetPageSelector());
|
|
rSelector.DeselectAllPages();
|
|
for (USHORT i=0; i<nPageCount; i++)
|
|
{
|
|
model::SharedPageDescriptor pDescriptor (
|
|
mrSlideSorter.GetModel().GetPageDescriptor(nFirstIndex + i));
|
|
if (pDescriptor.get() != NULL)
|
|
{
|
|
rSelector.SelectPage(pDescriptor);
|
|
// The first page of the new selection is made the current page.
|
|
if (i == 0)
|
|
{
|
|
mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);
|
|
mrController.GetFocusManager().SetFocusedPage(pDescriptor);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void Clipboard::CreateSlideTransferable (
|
|
::Window* pWindow,
|
|
bool bDrag)
|
|
{
|
|
List aBookmarkList;
|
|
|
|
// Insert all selected pages into a bookmark list and remember them in
|
|
// maPagesToRemove for possible later removal.
|
|
model::PageEnumeration aSelectedPages
|
|
(model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
|
|
mrSlideSorter.GetModel()));
|
|
while (aSelectedPages.HasMoreElements())
|
|
{
|
|
model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
|
|
aBookmarkList.Insert (
|
|
new String(pDescriptor->GetPage()->GetName()),
|
|
LIST_APPEND);
|
|
maPagesToRemove.push_back (pDescriptor->GetPage());
|
|
}
|
|
|
|
if (aBookmarkList.Count() > 0)
|
|
{
|
|
mrSlideSorter.GetView().BrkAction();
|
|
SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument();
|
|
SdTransferable* pTransferable = new Transferable (
|
|
pDocument,
|
|
NULL,
|
|
FALSE,
|
|
dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell()));
|
|
|
|
if (bDrag)
|
|
SD_MOD()->pTransferDrag = pTransferable;
|
|
else
|
|
SD_MOD()->pTransferClip = pTransferable;
|
|
|
|
pDocument->CreatingDataObj (pTransferable);
|
|
pTransferable->SetWorkDocument( dynamic_cast<SdDrawDocument*>(pDocument->AllocModel()) );
|
|
pDocument->CreatingDataObj (NULL);
|
|
TransferableObjectDescriptor aObjDesc;
|
|
pTransferable->GetWorkDocument()->GetDocSh()
|
|
->FillTransferableObjectDescriptor (aObjDesc);
|
|
|
|
if (pDocument->GetDocSh() != NULL)
|
|
aObjDesc.maDisplayName = pDocument->GetDocSh()
|
|
->GetMedium()->GetURLObject().GetURLNoPass();
|
|
|
|
::Window* pActionWindow = pWindow;
|
|
if (pActionWindow == NULL)
|
|
{
|
|
ViewShell* pViewShell = mrSlideSorter.GetViewShell();
|
|
if (pViewShell != NULL)
|
|
pActionWindow = pViewShell->GetActiveWindow();
|
|
}
|
|
|
|
pTransferable->SetStartPos (pActionWindow->PixelToLogic(
|
|
pActionWindow->GetPointerPosPixel()));
|
|
pTransferable->SetObjectDescriptor (aObjDesc);
|
|
pTransferable->SetPageBookmarks (aBookmarkList, !bDrag);
|
|
|
|
for (void* p=aBookmarkList.First(); p!=NULL; p=aBookmarkList.Next())
|
|
delete static_cast<String*>(p);
|
|
|
|
if (bDrag)
|
|
{
|
|
pTransferable->SetView (&mrSlideSorter.GetView());
|
|
sal_Int8 nDragSourceActions (DND_ACTION_COPY);
|
|
// The move action is available only when not all pages would be
|
|
// moved. Otherwise an empty document would remain. Crash.
|
|
sal_Int32 nRemainingPages = mrSlideSorter.GetModel().GetPageCount() - aBookmarkList.Count();
|
|
if (nRemainingPages > 0)
|
|
nDragSourceActions |= DND_ACTION_MOVE;
|
|
pTransferable->StartDrag (pActionWindow, nDragSourceActions);
|
|
}
|
|
else
|
|
pTransferable->CopyToClipboard (pActionWindow);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void Clipboard::StartDrag (
|
|
const Point&,
|
|
::Window* pWindow)
|
|
{
|
|
maPagesToRemove.clear();
|
|
maPagesToSelect.clear();
|
|
mbUpdateSelectionPending = false;
|
|
CreateSlideTransferable (pWindow, TRUE);
|
|
}
|
|
|
|
|
|
|
|
|
|
void Clipboard::DragFinished (sal_Int8 nDropAction)
|
|
{
|
|
// Hide the substitution display and insertion indicator.
|
|
mrSlideSorter.GetView().GetOverlay().GetSubstitutionOverlay().setVisible(false);
|
|
mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay().setVisible(false);
|
|
|
|
SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
|
|
|
|
if (pDragTransferable != NULL)
|
|
pDragTransferable->SetView (NULL);
|
|
|
|
PageSelector& rSelector (mrController.GetPageSelector());
|
|
if ((nDropAction & DND_ACTION_MOVE) != 0
|
|
&& ! maPagesToRemove.empty())
|
|
{
|
|
// Remove the pages that have been moved to another place (possibly
|
|
// in the same document.)
|
|
rSelector.DeselectAllPages();
|
|
PageList::iterator aDraggedPage;
|
|
for (aDraggedPage=maPagesToRemove.begin();
|
|
aDraggedPage!=maPagesToRemove.end();
|
|
aDraggedPage++)
|
|
{
|
|
rSelector.SelectPage (*aDraggedPage);
|
|
}
|
|
mrController.GetSelectionManager()->DeleteSelectedPages ();
|
|
}
|
|
|
|
SelectPages();
|
|
}
|
|
|
|
|
|
|
|
|
|
void Clipboard::SelectPages (void)
|
|
{
|
|
PageSelector& rSelector (mrController.GetPageSelector());
|
|
|
|
// Select the dropped pages.
|
|
PageList::iterator iPage;
|
|
rSelector.DeselectAllPages();
|
|
for (iPage=maPagesToSelect.begin(); iPage!=maPagesToSelect.end(); ++iPage)
|
|
{
|
|
rSelector.SelectPage(*iPage);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
sal_Int8 Clipboard::AcceptDrop (
|
|
const AcceptDropEvent& rEvent,
|
|
DropTargetHelper& rTargetHelper,
|
|
::sd::Window* pTargetWindow,
|
|
USHORT nPage,
|
|
USHORT nLayer)
|
|
{
|
|
sal_Int8 nResult = DND_ACTION_NONE;
|
|
|
|
switch (IsDropAccepted())
|
|
{
|
|
case DT_PAGE:
|
|
{
|
|
// Accept a drop.
|
|
nResult = rEvent.mnAction;
|
|
|
|
// Use the copy action when the drop action is the default, i.e. not
|
|
// explicitly set to move or link, and when the source and
|
|
// target models are not the same.
|
|
const SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
|
|
if (pDragTransferable != NULL
|
|
&& pDragTransferable->IsPageTransferable()
|
|
&& ((rEvent.maDragEvent.DropAction
|
|
& ::com::sun::star::datatransfer::dnd::DNDConstants::ACTION_DEFAULT) != 0)
|
|
&& (mrSlideSorter.GetModel().GetDocument()->GetDocSh()
|
|
!= pDragTransferable->GetPageDocShell()))
|
|
{
|
|
nResult = DND_ACTION_COPY;
|
|
}
|
|
|
|
// Show the insertion marker and the substitution for a drop.
|
|
Point aPosition = pTargetWindow->PixelToLogic (rEvent.maPosPixel);
|
|
view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
|
|
rOverlay.GetInsertionIndicatorOverlay().SetPosition (aPosition);
|
|
rOverlay.GetInsertionIndicatorOverlay().setVisible(true);
|
|
rOverlay.GetSubstitutionOverlay().SetPosition (aPosition);
|
|
|
|
// Scroll the window when the mouse reaches the window border.
|
|
mrController.GetScrollBarManager().AutoScroll (rEvent.maPosPixel);
|
|
}
|
|
break;
|
|
|
|
case DT_SHAPE:
|
|
nResult = ExecuteOrAcceptShapeDrop(
|
|
DC_ACCEPT,
|
|
rEvent.maPosPixel,
|
|
&rEvent,
|
|
rTargetHelper,
|
|
pTargetWindow,
|
|
nPage,
|
|
nLayer);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return nResult;
|
|
}
|
|
|
|
|
|
|
|
|
|
sal_Int8 Clipboard::ExecuteDrop (
|
|
const ExecuteDropEvent& rEvent,
|
|
DropTargetHelper& rTargetHelper,
|
|
::sd::Window* pTargetWindow,
|
|
USHORT nPage,
|
|
USHORT nLayer)
|
|
{
|
|
sal_Int8 nResult = DND_ACTION_NONE;
|
|
|
|
switch (IsDropAccepted())
|
|
{
|
|
case DT_PAGE:
|
|
{
|
|
const SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
|
|
const Point aEventModelPosition (
|
|
pTargetWindow->PixelToLogic (rEvent.maPosPixel));
|
|
long int nXOffset = labs (pDragTransferable->GetStartPos().X()
|
|
- aEventModelPosition.X());
|
|
long int nYOffset = labs (pDragTransferable->GetStartPos().Y()
|
|
- aEventModelPosition.Y());
|
|
const bool bContinue =
|
|
( pDragTransferable->GetView() != &mrSlideSorter.GetView() )
|
|
|| ( nXOffset >= 2 && nYOffset >= 2 );
|
|
|
|
// Get insertion position and then turn off the insertion indicator.
|
|
view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
|
|
rOverlay.GetInsertionIndicatorOverlay().SetPosition(
|
|
aEventModelPosition);
|
|
USHORT nIndex = DetermineInsertPosition (*pDragTransferable);
|
|
OSL_TRACE ("Clipboard::AcceptDrop() called for index %d",
|
|
nIndex);
|
|
rOverlay.GetInsertionIndicatorOverlay().setVisible(false);
|
|
|
|
if (bContinue)
|
|
{
|
|
SlideSorterController::ModelChangeLock aModelChangeLock (mrController);
|
|
|
|
if (pDragTransferable->GetView() == &mrSlideSorter.GetView()
|
|
&& rEvent.mnAction == DND_ACTION_MOVE)
|
|
{
|
|
// We are asked to move pages inside one view. For this we
|
|
// call MoveSelectedPages() which is faster than going the
|
|
// generic way.
|
|
|
|
// Remember to select the moved pages afterwards.
|
|
maPagesToRemove.swap(maPagesToSelect);
|
|
maPagesToRemove.clear();
|
|
|
|
USHORT nSdrModelIndex;
|
|
if (nIndex != SDRPAGE_NOTFOUND)
|
|
nSdrModelIndex = nIndex / 2 - 1;
|
|
else
|
|
nSdrModelIndex = SDRPAGE_NOTFOUND;
|
|
mrController.GetSelectionManager()->MoveSelectedPages(nSdrModelIndex);
|
|
mbUpdateSelectionPending = true;
|
|
nResult = DND_ACTION_NONE;
|
|
}
|
|
else
|
|
{
|
|
// Handle a general drop operation.
|
|
HandlePageDrop (*pDragTransferable);
|
|
nResult = rEvent.mnAction;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DT_SHAPE:
|
|
nResult = ExecuteOrAcceptShapeDrop(
|
|
DC_EXECUTE,
|
|
rEvent.maPosPixel,
|
|
&rEvent,
|
|
rTargetHelper,
|
|
pTargetWindow,
|
|
nPage,
|
|
nLayer);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return nResult;
|
|
}
|
|
|
|
|
|
|
|
|
|
USHORT Clipboard::DetermineInsertPosition (const SdTransferable& )
|
|
{
|
|
USHORT nInsertPosition = SDRPAGE_NOTFOUND;
|
|
|
|
// Tell the model to move the dragged pages behind the one with the
|
|
// index nInsertionIndex which first has to be transformed into an index
|
|
// understandable by the document.
|
|
view::InsertionIndicatorOverlay& rOverlay (
|
|
mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay());
|
|
sal_Int32 nInsertionIndex (rOverlay.GetInsertionPageIndex());
|
|
|
|
// The index returned by the overlay starts with 1 for the first slide.
|
|
// This is now converted that to an SdModel index that also starts with 1.
|
|
if (nInsertionIndex >= 0)
|
|
nInsertPosition = (USHORT)nInsertionIndex * 2 + 1;
|
|
|
|
return nInsertPosition;
|
|
}
|
|
|
|
|
|
|
|
|
|
USHORT Clipboard::InsertSlides (
|
|
const SdTransferable& rTransferable,
|
|
USHORT nInsertPosition)
|
|
{
|
|
USHORT nInsertedPageCount = ViewClipboard::InsertSlides (
|
|
rTransferable,
|
|
nInsertPosition);
|
|
|
|
// Remember the inserted pages so that they can be selected when the
|
|
// operation is finished.
|
|
int nDocumentIndex = nInsertPosition / 2 - 1;
|
|
for (USHORT i=1; i<=nInsertedPageCount; i++)
|
|
{
|
|
model::SharedPageDescriptor pDescriptor (
|
|
mrSlideSorter.GetModel().GetPageDescriptor(nDocumentIndex + i));
|
|
if (pDescriptor.get() != NULL)
|
|
maPagesToSelect.push_back (pDescriptor->GetPage());
|
|
}
|
|
|
|
mbUpdateSelectionPending |= (nInsertedPageCount>0);
|
|
|
|
return nInsertedPageCount;
|
|
}
|
|
|
|
|
|
|
|
|
|
Clipboard::DropType Clipboard::IsDropAccepted (void) const
|
|
{
|
|
DropType eResult (DT_NONE);
|
|
|
|
const SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
|
|
if (pDragTransferable != NULL)
|
|
{
|
|
if (pDragTransferable->IsPageTransferable())
|
|
{
|
|
if (mrSlideSorter.GetModel().GetEditMode() != EM_MASTERPAGE)
|
|
eResult = DT_PAGE;
|
|
}
|
|
else
|
|
{
|
|
eResult = DT_SHAPE;
|
|
}
|
|
}
|
|
|
|
return eResult;
|
|
}
|
|
|
|
|
|
|
|
|
|
sal_Int8 Clipboard::ExecuteOrAcceptShapeDrop (
|
|
DropCommand eCommand,
|
|
const Point& rPosition,
|
|
const void* pDropEvent,
|
|
DropTargetHelper& rTargetHelper,
|
|
::sd::Window* pTargetWindow,
|
|
USHORT nPage,
|
|
USHORT nLayer)
|
|
{
|
|
sal_Int8 nResult = 0;
|
|
|
|
// The dropping of a shape is accepted or executed only when there is
|
|
// DrawViewShell available to which we can forward this call. This has
|
|
// technical reasons: The actual code to accept or execute a shape drop
|
|
// is implemented in the ViewShell class and uses the page view of the
|
|
// main edit view. This is not possible without a DrawViewShell.
|
|
::boost::shared_ptr<DrawViewShell> pDrawViewShell;
|
|
if (mrSlideSorter.GetViewShell() != NULL)
|
|
pDrawViewShell = ::boost::dynamic_pointer_cast<DrawViewShell>(
|
|
mrSlideSorter.GetViewShell()->GetViewShellBase().GetMainViewShell());
|
|
if (pDrawViewShell.get() != NULL
|
|
&& (pDrawViewShell->GetShellType() == ViewShell::ST_IMPRESS
|
|
|| pDrawViewShell->GetShellType() == ViewShell::ST_DRAW))
|
|
{
|
|
// The drop is only accepted or executed when it takes place over a
|
|
// page object. Therefore we replace a missing page number by the
|
|
// number of the page under the mouse.
|
|
if (nPage == SDRPAGE_NOTFOUND)
|
|
{
|
|
model::SharedPageDescriptor pDescriptor (
|
|
mrSlideSorter.GetModel().GetPageDescriptor(
|
|
mrSlideSorter.GetView().GetPageIndexAtPoint(rPosition)));
|
|
if (pDescriptor.get() != NULL && pDescriptor->GetPage()!=NULL)
|
|
nPage = (pDescriptor->GetPage()->GetPageNum() - 1) / 2;
|
|
}
|
|
|
|
// Now comes the code that is different for the Execute and Accept:
|
|
// We simply forward the call to the AcceptDrop() or ExecuteDrop()
|
|
// methods of the DrawViewShell in the center pane.
|
|
if (nPage != SDRPAGE_NOTFOUND)
|
|
switch (eCommand)
|
|
{
|
|
case DC_ACCEPT:
|
|
nResult = pDrawViewShell->AcceptDrop(
|
|
*reinterpret_cast<const AcceptDropEvent*>(pDropEvent),
|
|
rTargetHelper,
|
|
pTargetWindow,
|
|
nPage,
|
|
nLayer);
|
|
break;
|
|
|
|
case DC_EXECUTE:
|
|
nResult = pDrawViewShell->ExecuteDrop(
|
|
*reinterpret_cast<const ExecuteDropEvent*>(pDropEvent),
|
|
rTargetHelper,
|
|
pTargetWindow,
|
|
nPage,
|
|
nLayer);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return nResult;
|
|
}
|
|
|
|
|
|
|
|
} } } // end of namespace ::sd::slidesorter::controller
|
|
|