LibreOffice Module sd (master) 1
SlsClipboard.cxx
Go to the documentation of this file.
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#include <sal/config.h>
21
22#include <cassert>
23
25
27#include <SlideSorter.hxx>
31#include <utility>
44
45#include <ViewShellBase.hxx>
46#include <DrawViewShell.hxx>
47#include <Window.hxx>
48#include <fupoor.hxx>
49#include <strings.hrc>
50#include <sdresid.hxx>
51#include <sdxfer.hxx>
52#include <sdmod.hxx>
53#include <ins_paste.hxx>
54#include <drawdoc.hxx>
55#include <DrawDocShell.hxx>
56#include <sdpage.hxx>
57#include <sdtreelb.hxx>
58
59#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
60#include <sfx2/request.hxx>
61#include <sfx2/viewfrm.hxx>
62#include <sfx2/bindings.hxx>
63#include <sfx2/docfile.hxx>
64#include <svx/svxids.hrc>
65#include <tools/urlobj.hxx>
66#include <rtl/ustring.hxx>
67#include <vcl/svapp.hxx>
68
70
71namespace {
78class TemporarySlideTrackingDeactivator
79{
80public:
81 explicit TemporarySlideTrackingDeactivator (SlideSorterController& rController)
82 : mrController(rController),
84 mrController.GetVisibleAreaManager().IsCurrentSlideTrackingActive())
85 {
87 mrController.GetVisibleAreaManager().DeactivateCurrentSlideTracking();
88 }
89 ~TemporarySlideTrackingDeactivator()
90 {
92 mrController.GetVisibleAreaManager().ActivateCurrentSlideTracking();
93 }
94
95private:
96 SlideSorterController& mrController;
98};
99} // end of anonymous namespace
100
102{
103public:
105 SdDrawDocument* pDocument,
106 std::shared_ptr<ViewShell> pMainViewShell)
107 : mpDocument(pDocument),
108 mpMainViewShell(std::move(pMainViewShell))
109 {
110 if (mpDocument!=nullptr && mpDocument->IsUndoEnabled())
111 {
112 if (mpMainViewShell && mpMainViewShell->GetShellType() == ViewShell::ST_DRAW)
113 mpDocument->BegUndo(SdResId(STRING_DRAG_AND_DROP_PAGES));
114 else
115 mpDocument->BegUndo(SdResId(STRING_DRAG_AND_DROP_SLIDES));
116 }
117 }
118
120 {
121 if (mpDocument!=nullptr && mpDocument->IsUndoEnabled())
123 if (mpMainViewShell && mpMainViewShell->GetViewFrame()!=nullptr)
124 {
125 SfxBindings& rBindings = mpMainViewShell->GetViewFrame()->GetBindings();
126 rBindings.Invalidate(SID_UNDO);
127 rBindings.Invalidate(SID_REDO);
128 }
129 }
130private:
132 std::shared_ptr<ViewShell> mpMainViewShell;
133};
134
136 : ViewClipboard(rSlideSorter.GetView()),
137 mrSlideSorter(rSlideSorter),
139 mnDragFinishedUserEventId(nullptr)
140{
141}
142
144{
145 if (mnDragFinishedUserEventId != nullptr)
147}
148
154{
155 ViewShell* pViewShell = mrSlideSorter.GetViewShell();
157 if (pViewShell != nullptr)
158 xFunc = pViewShell->GetCurrentFunction();
159 switch (rRequest.GetSlot())
160 {
161 case SID_CUT:
163 {
164 if(xFunc.is())
165 xFunc->DoCut();
166 else
167 DoCut();
168 }
169 rRequest.Done();
170 break;
171
172 case SID_COPY:
174 {
175 if(xFunc.is())
176 xFunc->DoCopy();
177 else
178 DoCopy();
179 }
180 rRequest.Done();
181 break;
182
183 case SID_PASTE:
184 // Prevent redraws while inserting pages from the clipboard
185 // because the intermediate inconsistent state might lead to
186 // a crash.
188 {
191 if(xFunc.is())
192 xFunc->DoPaste();
193 else
194 DoPaste();
195 }
196 rRequest.Done();
197 break;
198
199 case SID_DELETE:
200 DoDelete();
201 rRequest.Done();
202 break;
203 }
204}
205
207{
209 {
210 DoCopy();
211 DoDelete();
212 }
213}
214
216{
218 {
219 mrController.GetSelectionManager()->DeleteSelectedPages();
220 }
221}
222
224{
225 CreateSlideTransferable( nullptr, false );
226}
227
229{
230 SdTransferable* pClipTransferable = SD_MOD()->pTransferClip;
231
232 if (pClipTransferable==nullptr || !pClipTransferable->IsPageTransferable())
233 return;
234
235 sal_Int32 nInsertPosition = GetInsertionPosition();
236
237 if (nInsertPosition >= 0)
238 {
239 // Paste the pages from the clipboard.
240 sal_Int32 nInsertPageCount = PasteTransferable(nInsertPosition);
241 // Select the pasted pages and make the first of them the
242 // current page.
243 mrSlideSorter.GetContentWindow()->GrabFocus();
244 SelectPageRange(nInsertPosition, nInsertPageCount);
245 }
246}
247
249{
250 sal_Int32 nInsertPosition = -1;
251
252 // Determine the insertion position:
253 // a) When the insertion indicator is visible, then at that position.
254 // b) When the focus indicator is visible, then before or after the
255 // focused page, depending on user input to a dialog.
256 // c) When there is a selection but no focus, then after the
257 // selection.
258 // d) After the last page when there is no selection and no focus.
259
260 std::shared_ptr<controller::InsertionIndicatorHandler> pInsertionIndicatorHandler (
262 if (pInsertionIndicatorHandler->IsActive())
263 {
264 // Use the insertion index of an active insertion indicator.
265 nInsertPosition = pInsertionIndicatorHandler->GetInsertionPageIndex();
266 }
267 else if (mrController.GetSelectionManager()->GetInsertionPosition() >= 0)
268 {
269 // Use the insertion index of an insertion indicator that has been
270 // deactivated a short while ago.
271 nInsertPosition = mrController.GetSelectionManager()->GetInsertionPosition();
272 }
274 {
275 // Use the focus to determine the insertion position.
277 SdInsertPasteDlg aDialog(pWin ? pWin->GetFrameWeld() : nullptr);
278 if (aDialog.run() == RET_OK)
279 {
281 if (!aDialog.IsInsertBefore())
282 nInsertPosition ++;
283 }
284 }
285
286 return nInsertPosition;
287}
288
289sal_Int32 Clipboard::PasteTransferable (sal_Int32 nInsertPosition)
290{
291 SdTransferable* pClipTransferable = SD_MOD()->pTransferClip;
293 bool bMergeMasterPages = !pClipTransferable->HasSourceDoc (rModel.GetDocument());
294 sal_uInt16 nInsertIndex (rModel.GetCoreIndex(nInsertPosition));
295 sal_Int32 nInsertPageCount (0);
296 if (pClipTransferable->HasPageBookmarks())
297 {
298 const std::vector<OUString> &rBookmarkList = pClipTransferable->GetPageBookmarks();
299 const SolarMutexGuard aGuard;
300
301 nInsertPageCount = static_cast<sal_uInt16>(rBookmarkList.size());
303 rBookmarkList,
304 nullptr,
305 false,
306 false,
307 nInsertIndex,
308 false,
309 pClipTransferable->GetPageDocShell(),
310 true,
311 bMergeMasterPages,
312 false);
313 }
314 else
315 {
316 SfxObjectShell* pShell = pClipTransferable->GetDocShell().get();
317 DrawDocShell* pDataDocSh = static_cast<DrawDocShell*>(pShell);
318 SdDrawDocument* pDataDoc = pDataDocSh->GetDoc();
319
320 if (pDataDoc!=nullptr
322 {
323 const SolarMutexGuard aGuard;
324
325 bMergeMasterPages = (pDataDoc != rModel.GetDocument());
326 nInsertPageCount = pDataDoc->GetSdPageCount( PageKind::Standard );
328 std::vector<OUString>(),
329 nullptr,
330 false,
331 false,
332 nInsertIndex,
333 false,
334 pDataDocSh,
335 true,
336 bMergeMasterPages,
337 false);
338 }
339 }
341 return nInsertPageCount;
342}
343
344void Clipboard::SelectPageRange (sal_Int32 nFirstIndex, sal_Int32 nPageCount)
345{
346 // Select the newly inserted pages. That are the nInsertPageCount pages
347 // after the nInsertIndex position.
349 rSelector.DeselectAllPages();
350 for (sal_Int32 i=0; i<nPageCount; i++)
351 {
352 model::SharedPageDescriptor pDescriptor (
353 mrSlideSorter.GetModel().GetPageDescriptor(nFirstIndex + i));
354 if (pDescriptor)
355 {
356 rSelector.SelectPage(pDescriptor);
357 // The first page of the new selection is made the current page.
358 if (i == 0)
359 {
360 mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);
361 }
362 }
363 }
364}
365
367 vcl::Window* pWindow,
368 bool bDrag)
369{
370 std::vector<OUString> aBookmarkList;
371
372 // Insert all selected pages into a bookmark list and remember them in
373 // maPagesToRemove for possible later removal.
374 model::PageEnumeration aSelectedPages
377 SdDrawDocument* const pDocument = mrSlideSorter.GetModel().GetDocument();
378 DrawDocShell* const pDataDocSh = pDocument->GetDocSh();
379
380 sal_Int32 nUniqueID = 0;
381 while (aSelectedPages.HasMoreElements())
382 {
383 model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
384
385 //ensure that the slides have unique names
386 const OUString sOrigName = pDescriptor->GetPage()->GetName();
387 if ( pDataDocSh && !pDataDocSh->IsPageNameUnique( sOrigName ) )
388 {
389 OUString sUniqueName;
390 bool bUnique = false;
391 while ( !bUnique )
392 {
393 sUniqueName = sOrigName + "_clipboard" + OUString::number(nUniqueID++);
394 bUnique = pDataDocSh->IsNewPageNameValid( sUniqueName );
395 if ( bUnique )
396 pDescriptor->GetPage()->SetName(sUniqueName);
397 }
398 }
399
400 aBookmarkList.push_back(pDescriptor->GetPage()->GetName());
401 maPagesToRemove.push_back (pDescriptor->GetPage());
402 }
403
404 // Create a small set of representatives of the selection for which
405 // previews are included into the transferable so that an insertion
406 // indicator can be rendered.
407 aSelectedPages.Rewind();
408 ::std::vector<TransferableData::Representative> aRepresentatives;
409 aRepresentatives.reserve(3);
410 std::shared_ptr<cache::PageCache> pPreviewCache (
412 while (aSelectedPages.HasMoreElements())
413 {
414 model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
415 if ( ! pDescriptor || pDescriptor->GetPage()==nullptr)
416 continue;
417 BitmapEx aPreview (pPreviewCache->GetPreviewBitmap(pDescriptor->GetPage(), false));
418 aRepresentatives.emplace_back(
419 aPreview,
420 pDescriptor->HasState(model::PageDescriptor::ST_Excluded));
421 if (aRepresentatives.size() >= 3)
422 break;
423 }
424
425 if (aBookmarkList.empty())
426 return;
427
430 pDocument,
432 std::move(aRepresentatives));
433
434 if (bDrag)
435 SD_MOD()->pTransferDrag = pTransferable.get();
436 else
437 SD_MOD()->pTransferClip = pTransferable.get();
438
439 pDocument->CreatingDataObj (pTransferable.get());
440 pTransferable->SetWorkDocument(pDocument->AllocSdDrawDocument());
441 std::unique_ptr<TransferableObjectDescriptor> pObjDesc(new TransferableObjectDescriptor);
442 pTransferable->GetWorkDocument()->GetDocSh()
443 ->FillTransferableObjectDescriptor (*pObjDesc);
444
445 if (pDataDocSh != nullptr)
446 pObjDesc->maDisplayName = pDataDocSh->GetMedium()->GetURLObject().GetURLNoPass();
447
448 vcl::Window* pActionWindow = pWindow;
449 if (pActionWindow == nullptr)
450 {
451 ViewShell* pViewShell = mrSlideSorter.GetViewShell();
452 if (pViewShell != nullptr)
453 pActionWindow = pViewShell->GetActiveWindow();
454 }
455
456 assert(pActionWindow);
457
458 pTransferable->SetStartPos (pActionWindow->PixelToLogic(
459 pActionWindow->GetPointerPosPixel()));
460 pTransferable->SetObjectDescriptor (std::move(pObjDesc));
461
462 {
463 TemporarySlideTrackingDeactivator aDeactivator (mrController);
464 pTransferable->SetPageBookmarks (std::move(aBookmarkList), !bDrag);
465 }
466
467 if (bDrag)
468 {
469 pTransferable->SetView (&mrSlideSorter.GetView());
470 pTransferable->StartDrag (pActionWindow, DND_ACTION_COPY | DND_ACTION_MOVE);
471 }
472 else
473 pTransferable->CopyToClipboard (pActionWindow);
474
475 pDocument->CreatingDataObj(nullptr);
476}
477
478std::shared_ptr<SdTransferable::UserData> Clipboard::CreateTransferableUserData (SdTransferable* pTransferable)
479{
480 do
481 {
482 SdPageObjsTLV::SdPageObjsTransferable* pTreeListBoxTransferable
483 = dynamic_cast<SdPageObjsTLV::SdPageObjsTransferable*>(pTransferable);
484 if (pTreeListBoxTransferable == nullptr)
485 break;
486
487 // Find view shell for the document of the transferable.
488 ::sd::ViewShell* pViewShell
489 = SdPageObjsTLV::GetViewShellForDocShell(pTreeListBoxTransferable->GetDocShell());
490 if (pViewShell == nullptr)
491 break;
492
493 // Find slide sorter for the document of the transferable.
494 SlideSorterViewShell* pSlideSorterViewShell
496 if (pSlideSorterViewShell == nullptr)
497 break;
498 SlideSorter& rSlideSorter (pSlideSorterViewShell->GetSlideSorter());
499
500 // Get bookmark from transferable.
501 TransferableDataHelper aDataHelper (pTransferable);
502 INetBookmark aINetBookmark;
503 if ( ! aDataHelper.GetINetBookmark(SotClipboardFormatId::NETSCAPE_BOOKMARK, aINetBookmark))
504 break;
505 const OUString sURL (aINetBookmark.GetURL());
506 const sal_Int32 nIndex (sURL.indexOf('#'));
507 if (nIndex == -1)
508 break;
509 OUString sBookmark (sURL.copy(nIndex+1));
510
511 // Make sure that the bookmark points to a page.
512 SdDrawDocument* pTransferableDocument = rSlideSorter.GetModel().GetDocument();
513 if (pTransferableDocument == nullptr)
514 break;
515 bool bIsMasterPage = false;
516 const sal_uInt16 nPageIndex (pTransferableDocument->GetPageByName(sBookmark, bIsMasterPage));
517 if (nPageIndex == SDRPAGE_NOTFOUND)
518 break;
519
520 // Create preview.
521 ::std::vector<TransferableData::Representative> aRepresentatives;
522 aRepresentatives.reserve(1);
523 std::shared_ptr<cache::PageCache> pPreviewCache (
524 rSlideSorter.GetView().GetPreviewCache());
525 model::SharedPageDescriptor pDescriptor (rSlideSorter.GetModel().GetPageDescriptor((nPageIndex-1)/2));
526 if ( ! pDescriptor || pDescriptor->GetPage()==nullptr)
527 break;
528 BitmapEx aPreview (pPreviewCache->GetPreviewBitmap(pDescriptor->GetPage(), false));
529 aRepresentatives.emplace_back(
530 aPreview,
531 pDescriptor->HasState(model::PageDescriptor::ST_Excluded));
532
533 // Remember the page in maPagesToRemove so that it can be removed
534 // when drag and drop action is "move".
535 Clipboard& rOtherClipboard (pSlideSorterViewShell->GetSlideSorter().GetController().GetClipboard());
536 rOtherClipboard.maPagesToRemove.clear();
537 rOtherClipboard.maPagesToRemove.push_back(pDescriptor->GetPage());
538
539 // Create the new transferable.
540 std::shared_ptr<SdTransferable::UserData> pNewTransferable =
541 std::make_shared<TransferableData>(
542 pSlideSorterViewShell,
543 std::move(aRepresentatives));
544 pTransferable->SetWorkDocument(pTreeListBoxTransferable->GetSourceDoc()->AllocSdDrawDocument());
545 // pTransferable->SetView(&mrSlideSorter.GetView());
546
547 // Set page bookmark list.
548 std::vector<OUString> aPageBookmarks { sBookmark };
549 pTransferable->SetPageBookmarks(std::move(aPageBookmarks), false);
550
551 // Replace the view referenced by the transferable with the
552 // corresponding slide sorter view.
553 pTransferable->SetView(&pSlideSorterViewShell->GetSlideSorter().GetView());
554
555 return pNewTransferable;
556 }
557 while (false);
558
559 return std::shared_ptr<SdTransferable::UserData>();
560}
561
563 const Point& rPosition,
564 vcl::Window* pWindow)
565{
566 maPagesToRemove.clear();
567 CreateSlideTransferable(pWindow, true);
568
570 rPosition,
572}
573
575{
576 if (mnDragFinishedUserEventId == nullptr)
577 {
579 LINK(this, Clipboard, ProcessDragFinished),
580 reinterpret_cast<void*>(nDropAction));
581 }
582}
583
584IMPL_LINK(Clipboard, ProcessDragFinished, void*, pUserData, void)
585{
586 const sal_Int8 nDropAction (static_cast<sal_Int8>(reinterpret_cast<sal_IntPtr>(pUserData)));
587
588 mnDragFinishedUserEventId = nullptr;
589
590 // Hide the substitution display and insertion indicator.
592 if (pFunction.is())
593 pFunction->NotifyDragFinished();
594
596 if ((nDropAction & DND_ACTION_MOVE) != 0
597 && ! maPagesToRemove.empty())
598 {
599 // Remove the pages that have been moved to another place (possibly
600 // in the same document.)
601 rSelector.DeselectAllPages();
602 for (const auto& rpDraggedPage : maPagesToRemove)
603 {
604 rSelector.SelectPage(rpDraggedPage);
605 }
606 mrController.GetSelectionManager()->DeleteSelectedPages();
607 }
608 mxUndoContext.reset();
609 mxSelectionObserverContext.reset();
610}
611
613 const AcceptDropEvent& rEvent,
614 DropTargetHelper& rTargetHelper,
615 ::sd::Window* pTargetWindow,
616 sal_uInt16 nPage,
617 SdrLayerID nLayer)
618{
619 sal_Int8 nAction (DND_ACTION_NONE);
620
621 const Clipboard::DropType eDropType (IsDropAccepted());
622
623 switch (eDropType)
624 {
625 case DT_PAGE:
627 {
628 // Accept a drop.
629 nAction = rEvent.mnAction;
630
631 // Use the copy action when the drop action is the default, i.e. not
632 // explicitly set to move or link, and when the source and
633 // target models are not the same.
634 SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
635 if (pDragTransferable != nullptr
636 && pDragTransferable->IsPageTransferable()
637 && ((rEvent.maDragEvent.DropAction
638 & css::datatransfer::dnd::DNDConstants::ACTION_DEFAULT) != 0)
640 != pDragTransferable->GetPageDocShell()))
641 {
642 nAction = DND_ACTION_COPY;
643 }
644 else if (IsInsertionTrivial(pDragTransferable, nAction))
645 {
646 nAction = DND_ACTION_NONE;
647 }
648
649 // Show the insertion marker and the substitution for a drop.
650 SelectionFunction* pSelectionFunction = dynamic_cast<SelectionFunction*>(
652 if (pSelectionFunction != nullptr)
653 pSelectionFunction->MouseDragged(rEvent, nAction);
654
655 // Scroll the window when the mouse reaches the window border.
656 // mrController.GetScrollBarManager().AutoScroll (rEvent.maPosPixel);
657 }
658 break;
659
660 case DT_SHAPE:
661 nAction = ExecuteOrAcceptShapeDrop(
662 DC_ACCEPT,
663 rEvent.maPosPixel,
664 &rEvent,
665 rTargetHelper,
666 pTargetWindow,
667 nPage,
668 nLayer);
669 break;
670
671 default:
672 case DT_NONE:
673 nAction = DND_ACTION_NONE;
674 break;
675 }
676
677 return nAction;
678}
679
681 const ExecuteDropEvent& rEvent,
682 DropTargetHelper& rTargetHelper,
683 ::sd::Window* pTargetWindow,
684 sal_uInt16 nPage,
685 SdrLayerID nLayer)
686{
687 sal_Int8 nResult = DND_ACTION_NONE;
688 mxUndoContext.reset();
689 const Clipboard::DropType eDropType (IsDropAccepted());
690
691 switch (eDropType)
692 {
693 case DT_PAGE:
695 {
696 SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
697 const Point aEventModelPosition (
698 pTargetWindow->PixelToLogic (rEvent.maPosPixel));
699 const sal_Int32 nXOffset (std::abs (pDragTransferable->GetStartPos().X()
700 - aEventModelPosition.X()));
701 const sal_Int32 nYOffset (std::abs (pDragTransferable->GetStartPos().Y()
702 - aEventModelPosition.Y()));
703 bool bContinue =
704 ( pDragTransferable->GetView() != &mrSlideSorter.GetView() )
705 || ( nXOffset >= 2 && nYOffset >= 2 );
706
707 std::shared_ptr<InsertionIndicatorHandler> pInsertionIndicatorHandler(
709 // Get insertion position and then turn off the insertion indicator.
710 pInsertionIndicatorHandler->UpdatePosition(aEventModelPosition, rEvent.mnAction);
711 // sal_uInt16 nIndex = DetermineInsertPosition(*pDragTransferable);
712
713 // Do not process the insertion when it is trivial,
714 // i.e. would insert pages at their original place.
715 if (IsInsertionTrivial(pDragTransferable, rEvent.mnAction))
716 bContinue = false;
717
718 // Tell the insertion indicator handler to hide before the model
719 // is modified. Doing it later may result in page objects whose
720 // animation state is not properly reset because they are then
721 // in another run then before the model change.
722 pInsertionIndicatorHandler->End(Animator::AM_Immediate);
723
724 if (bContinue)
725 {
727
728 // Handle a general drop operation.
729 mxUndoContext.reset(new UndoContext (
733
734 if (rEvent.mnAction == DND_ACTION_MOVE)
735 {
737 const bool bDoesMakePageObjectsNamesUnique = pDoc->DoesMakePageObjectsNamesUnique();
738 pDoc->DoMakePageObjectsNamesUnique(false);
739 HandlePageDrop(*pDragTransferable);
740 pDoc->DoMakePageObjectsNamesUnique(bDoesMakePageObjectsNamesUnique);
741 }
742 else
743 HandlePageDrop(*pDragTransferable);
744
745 nResult = rEvent.mnAction;
746
747 // We leave the undo context alive for when moving or
748 // copying inside one view then the actions in
749 // NotifyDragFinished should be covered as well as
750 // well as the ones above.
751 }
752
753 // When the pages originated in another slide sorter then
754 // only that is notified automatically about the drag
755 // operation being finished. Because the target slide sorter
756 // has be notified, too, add a callback for that.
757 std::shared_ptr<TransferableData> pSlideSorterTransferable (
758 TransferableData::GetFromTransferable(pDragTransferable));
759 assert(pSlideSorterTransferable);
760 if (pSlideSorterTransferable
761 && pSlideSorterTransferable->GetSourceViewShell() != mrSlideSorter.GetViewShell())
762 {
763 DragFinished(nResult);
764 }
765
766 // Notify the receiving selection function that drag-and-drop is
767 // finished and the substitution handler can be released.
770 if (pFunction.is())
771 pFunction->NotifyDragFinished();
772 }
773 break;
774
775 case DT_SHAPE:
776 nResult = ExecuteOrAcceptShapeDrop(
778 rEvent.maPosPixel,
779 &rEvent,
780 rTargetHelper,
781 pTargetWindow,
782 nPage,
783 nLayer);
784 break;
785
786 default:
787 case DT_NONE:
788 break;
789 }
790
791 return nResult;
792}
793
795 SdTransferable const * pTransferable,
796 const sal_Int8 nDndAction) const
797{
798 std::shared_ptr<TransferableData> pSlideSorterTransferable (
800 if (pSlideSorterTransferable
801 && pSlideSorterTransferable->GetSourceViewShell() != mrSlideSorter.GetViewShell())
802 return false;
803 return mrController.GetInsertionIndicatorHandler()->IsInsertionTrivial(nDndAction);
804}
805
807{
809 {
812 }
813}
814
816{
817 // Tell the model to move the dragged pages behind the one with the
818 // index nInsertionIndex which first has to be transformed into an index
819 // understandable by the document.
820 const sal_Int32 nInsertionIndex (
821 mrController.GetInsertionIndicatorHandler()->GetInsertionPageIndex());
822
823 // Convert to insertion index to that of an SdModel.
824 if (nInsertionIndex >= 0)
825 return mrSlideSorter.GetModel().GetCoreIndex(nInsertionIndex);
826 else
827 return 0;
828}
829
831{
832 const SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
833 if (pDragTransferable == nullptr)
834 return DT_NONE;
835
836 if (pDragTransferable->IsPageTransferable())
837 {
839 return DT_PAGE;
840 else
841 return DT_NONE;
842 }
843
844 const SdPageObjsTLV::SdPageObjsTransferable* pPageObjsTransferable
845 = dynamic_cast<const SdPageObjsTLV::SdPageObjsTransferable*>(pDragTransferable);
846 if (pPageObjsTransferable != nullptr)
848
849 return DT_SHAPE;
850}
851
853 DropCommand eCommand,
854 const Point& rPosition,
855 const void* pDropEvent,
856 DropTargetHelper& rTargetHelper,
857 ::sd::Window* pTargetWindow,
858 sal_uInt16 nPage,
859 SdrLayerID nLayer)
860{
861 sal_Int8 nResult = 0;
862
863 // The dropping of a shape is accepted or executed only when there is
864 // DrawViewShell available to which we can forward this call. This has
865 // technical reasons: The actual code to accept or execute a shape drop
866 // is implemented in the ViewShell class and uses the page view of the
867 // main edit view. This is not possible without a DrawViewShell.
868 std::shared_ptr<DrawViewShell> pDrawViewShell;
869 if (mrSlideSorter.GetViewShell() != nullptr)
870 pDrawViewShell = std::dynamic_pointer_cast<DrawViewShell>(
872 if (pDrawViewShell != nullptr
873 && (pDrawViewShell->GetShellType() == ViewShell::ST_IMPRESS
874 || pDrawViewShell->GetShellType() == ViewShell::ST_DRAW))
875 {
876 // The drop is only accepted or executed when it takes place over a
877 // page object. Therefore we replace a missing page number by the
878 // number of the page under the mouse.
879 if (nPage == SDRPAGE_NOTFOUND)
880 {
881 model::SharedPageDescriptor pDescriptor (
884 if (pDescriptor)
885 nPage = pDescriptor->GetPageIndex();
886 }
887
888 // Now comes the code that is different for the Execute and Accept:
889 // We simply forward the call to the AcceptDrop() or ExecuteDrop()
890 // methods of the DrawViewShell in the center pane.
891 if (nPage != SDRPAGE_NOTFOUND)
892 switch (eCommand)
893 {
894 case DC_ACCEPT:
895 nResult = pDrawViewShell->AcceptDrop(
896 *static_cast<const AcceptDropEvent*>(pDropEvent),
897 rTargetHelper,
898 pTargetWindow,
899 nPage,
900 nLayer);
901 break;
902
903 case DC_EXECUTE:
904 nResult = pDrawViewShell->ExecuteDrop(
905 *static_cast<const ExecuteDropEvent*>(pDropEvent),
906 rTargetHelper,
907 pTargetWindow,
908 nPage,
909 nLayer);
910 break;
911 }
912 }
913
914 return nResult;
915}
916
917} // end of namespace ::sd::slidesorter::controller
918
919/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SlideSorterController & mrController
const bool mbIsCurrentSlideTrackingActive
SlideSorter & mrSlideSorter
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
const OUString & GetURL() const
OUString GetURLNoPass(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
constexpr tools::Long Y() const
constexpr tools::Long X() const
SAL_DLLPRIVATE bool InsertBookmarkAsPage(const std::vector< OUString > &rBookmarkList, std::vector< OUString > *pExchangeList, bool bLink, bool bReplace, sal_uInt16 nPgPos, bool bNoDialogs, ::sd::DrawDocShell *pBookmarkDocSh, bool bCopy, bool bMergeMasterPages, bool bPreservePageNames)
Insert pages into this document.
Definition: drawdoc3.cxx:375
SAL_DLLPRIVATE void CreatingDataObj(SdTransferable *pTransferable)
Definition: drawdoc.hxx:255
SAL_DLLPRIVATE sal_uInt16 GetPageByName(std::u16string_view rPgName, bool &rbIsMasterPage) const
Return the first page that has the given name.
Definition: drawdoc2.cxx:126
SAL_DLLPRIVATE::sd::DrawDocShell * GetDocSh() const
Definition: drawdoc.hxx:242
SAL_DLLPRIVATE SdDrawDocument * AllocSdDrawDocument() const
Definition: drawdoc.cxx:581
sal_uInt16 GetSdPageCount(PageKind ePgKind) const
Definition: drawdoc2.cxx:212
bool IsInsertBefore() const
Definition: ins_paste.cxx:32
::sd::DrawDocShell & GetDocShell() const
Definition: sdtreelb.hxx:431
::sd::ViewShell * GetViewShellForDocShell(::sd::DrawDocShell &rDocShell)
Return the view shell that is linked to the given doc shell.
Definition: sdtreelb.cxx:677
const SfxObjectShellRef & GetDocShell() const
Definition: sdxfer.hxx:48
bool IsPageTransferable() const
Definition: sdxfer.hxx:67
const ::sd::View * GetView() const
Definition: sdxfer.hxx:54
void SetWorkDocument(const SdDrawDocument *pWorkDoc)
Definition: sdxfer.hxx:50
const Point & GetStartPos() const
Definition: sdxfer.hxx:59
bool HasPageBookmarks() const
Definition: sdxfer.hxx:68
::sd::DrawDocShell * GetPageDocShell() const
Definition: sdxfer.hxx:70
const std::vector< OUString > & GetPageBookmarks() const
Definition: sdxfer.hxx:69
SdDrawDocument * GetSourceDoc() const
Definition: sdxfer.hxx:80
bool HasSourceDoc(const SdDrawDocument *pDoc) const
Definition: sdxfer.hxx:64
void SetView(const ::sd::View *pView)
Definition: sdxfer.cxx:754
void SetPageBookmarks(std::vector< OUString > &&rPageBookmarks, bool bPersistent)
Definition: sdxfer.cxx:664
virtual void BrkAction() override
void BegUndo()
bool DoesMakePageObjectsNamesUnique() const
void DoMakePageObjectsNamesUnique(bool bDo)
bool IsUndoEnabled() const
void EndUndo()
void Invalidate(sal_uInt16 nId)
const INetURLObject & GetURLObject() const
SfxMedium * GetMedium() const
sal_uInt16 GetSlot() const
void Done(bool bRemove=false)
bool GetINetBookmark(SotClipboardFormatId nFormat, INetBookmark &rBmk) const
bool IsPageNameUnique(std::u16string_view rPagName) const
checks, if the given name is a unique name for an existing slide
Definition: docshel2.cxx:407
bool IsNewPageNameValid(OUString &rInOutPageName, bool bResetStringIfStandardName=false)
checks, if the given name is a valid new name for a slide
Definition: docshel2.cxx:304
SdDrawDocument * GetDoc()
Handle clipboard related tasks for the draw view.
void HandlePageDrop(const SdTransferable &rTransferable)
Handle the drop of a drag-and-drop action where the transferable contains a set of pages.
std::shared_ptr< ViewShell > GetMainViewShell() const
Return the main view shell stacked on the called ViewShellBase object.
Base class of the stacked shell hierarchy.
Definition: ViewShell.hxx:92
const rtl::Reference< FuPoor > & GetCurrentFunction() const
Definition: ViewShell.hxx:250
::sd::Window * GetActiveWindow() const
The active window is usually the mpContentWindow.
Definition: ViewShell.hxx:155
::sd::View * GetView() const
Definition: ViewShell.hxx:144
SD_DLLPUBLIC ViewShellBase & GetViewShellBase() const
Definition: viewshel.cxx:1397
An SdWindow contains the actual working area of ViewShell.
Definition: Window.hxx:45
SD_DLLPUBLIC SlideSorter & GetSlideSorter() const
static SD_DLLPUBLIC SlideSorterViewShell * GetSlideSorter(ViewShellBase &rBase)
Return a slide sorter that is currently displayed in one of the panes that belong to the given ViewSh...
Show previews for all the slides in a document and allow the user to insert or delete slides and modi...
Definition: SlideSorter.hxx:62
ViewShell * GetViewShell() const
Return the view shell that was given at construction.
const VclPtr< sd::Window > & GetContentWindow() const
Return the content window.
Definition: SlideSorter.hxx:99
model::SlideSorterModel & GetModel() const
view::SlideSorterView & GetView() const
UndoContext(SdDrawDocument *pDocument, std::shared_ptr< ViewShell > pMainViewShell)
PageList maPagesToRemove
Remember the pages that are dragged to another document or to another place in the same document so t...
virtual sal_uInt16 DetermineInsertPosition() override
Return an index of a page after which the pages of the transferable are to be inserted into the targe...
void HandleSlotCall(SfxRequest &rRequest)
With the current implementation the forwarded calls to the current function will come back eventually...
SlideSorterController & mrController
void StartDrag(const Point &rDragPt, vcl::Window *pWindow)
void DragFinished(sal_Int8 nDropAction)
sal_Int8 ExecuteDrop(const ExecuteDropEvent &rEvt, DropTargetHelper &rTargetHelper, ::sd::Window *pTargetWindow, sal_uInt16 nPage, SdrLayerID nLayer)
std::unique_ptr< UndoContext > mxUndoContext
void SelectPageRange(sal_Int32 nFirstIndex, sal_Int32 nPageCount)
Select a range of pages of the model.
DropCommand
This method contains the code for AcceptDrop() and ExecuteDrop() shapes.
sal_Int32 PasteTransferable(sal_Int32 nInsertPosition)
Paste the pages of the transferable of the sd module at the given position.
void CreateSlideTransferable(vcl::Window *pWindow, bool bDrag)
bool IsInsertionTrivial(SdTransferable const *pTransferable, const sal_Int8 nDndAction) const
Return whether the insertion defined by the transferable is trivial, ie would not change either sourc...
sal_Int8 AcceptDrop(const AcceptDropEvent &rEvt, DropTargetHelper &rTargetHelper, ::sd::Window *pTargetWindow, sal_uInt16 nPage, SdrLayerID nLayer)
DropType
Return <TRUE> when the current transferable in the current state of the slidesorter is acceptable to ...
sal_Int32 GetInsertionPosition()
Determine the position of where to insert the pages in the current transferable of the sd module.
Clipboard(SlideSorter &rSlideSorter)
sal_Int8 ExecuteOrAcceptShapeDrop(DropCommand eCommand, const Point &rPosition, const void *pDropEvent, DropTargetHelper &rTargetHelper, ::sd::Window *pTargetWindow, sal_uInt16 nPage, SdrLayerID nLayer)
std::unique_ptr< SelectionObserver::Context, o3tl::default_delete< SelectionObserver::Context > > mxSelectionObserverContext
static std::shared_ptr< SdTransferable::UserData > CreateTransferableUserData(SdTransferable *pTransferable)
Create a slide sorter transferable from the given sd transferable.
bool IsFocusShowing() const
Return <TRUE> when the focus indicator is currently shown.
sal_Int32 GetFocusedPageIndex() const
Return the index of the page that currently has the focus as it is accepted by the slide sorter model...
A sub-controller that handles page selection of the slide browser.
void SelectPage(int nPageIndex)
Select the specified descriptor.
void MouseDragged(const AcceptDropEvent &rEvent, const sal_Int8 nDragAction)
Use this little class instead of calling StartObservation and EndObservation directly so that EndObse...
Create an object of this inner class to prevent updates due to model changes.
void HandleModelChange()
Handle a change of the model, that is, handle the removal and insertion of whole pages or a change of...
::rtl::Reference< SelectionFunction > GetCurrentSelectionFunction() const
When the current function of the view shell is the slide sorter selection function then return a refe...
std::shared_ptr< CurrentSlideManager > const & GetCurrentSlideManager() const
std::shared_ptr< SelectionManager > const & GetSelectionManager() const
std::shared_ptr< InsertionIndicatorHandler > const & GetInsertionIndicatorHandler() const
static rtl::Reference< SdTransferable > CreateTransferable(SdDrawDocument *pSrcDoc, SlideSorterViewShell *pViewShell, ::std::vector< TransferableData::Representative > &&rRepresentatives)
static std::shared_ptr< TransferableData > GetFromTransferable(const SdTransferable *pTransferable)
static PageEnumeration CreateSelectedPagesEnumeration(const SlideSorterModel &rModel)
The returned enumeration of slides iterates over the currently selected slides of the given model.
Public class of page enumerations that delegates its calls to an implementation object that can filte...
virtual SharedPageDescriptor GetNextElement() override
Return the next element of the enumeration.
virtual bool HasMoreElements() const override
Return <TRUE> when the enumeration has more elements, i.e.
virtual void Rewind() override
Rewind the enumeration so that the next call to GetNextElement() will return its first element.
The model of the slide sorter gives access to the slides that are to be displayed in the slide sorter...
SdDrawDocument * GetDocument()
This method is present to let the view create a ShowView for displaying slides.
sal_Int32 GetPageCount() const
Return the number of slides in the document regardless of whether they are visible or not or whether ...
SharedPageDescriptor GetPageDescriptor(const sal_Int32 nPageIndex, const bool bCreate=true) const
Return a page descriptor for the page with the specified index.
sal_uInt16 GetCoreIndex(const sal_Int32 nIndex) const
Return an index for accessing an SdrModel that corresponds to the given SlideSorterModel index.
sal_Int32 GetPageIndexAtPoint(const Point &rPosition) const
Return the index of the page that is rendered at the given position.
std::shared_ptr< cache::PageCache > const & GetPreviewCache()
T * get() const
Point PixelToLogic(const Point &rDevicePt) const
Point GetPointerPosPixel()
weld::Window * GetFrameWeld() const
virtual short run()
virtual std::shared_ptr< SfxDialogController > GetController() override
sal_Int32 nIndex
int i
IMPL_LINK(SlideSorterController, ApplicationEventHandler, VclSimpleEvent &, rEvent, void)
std::shared_ptr< PageDescriptor > SharedPageDescriptor
OUString SdResId(TranslateId aId)
Definition: sdmod.cxx:83
#define SD_MOD()
Definition: sdmod.hxx:184
sal_Int8 mnAction
const css::datatransfer::dnd::DropTargetDragEvent maDragEvent
#define SDRPAGE_NOTFOUND
#define DND_ACTION_MOVE
#define DND_ACTION_COPY
#define DND_ACTION_NONE
signed char sal_Int8
RET_OK