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