Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "controller/SlsInsertionIndicatorHandler.hxx"
21 : #include "controller/SlsProperties.hxx"
22 : #include "view/SlideSorterView.hxx"
23 : #include "view/SlsLayouter.hxx"
24 : #include "view/SlsInsertionIndicatorOverlay.hxx"
25 : #include "model/SlideSorterModel.hxx"
26 : #include "model/SlsPageEnumerationProvider.hxx"
27 : #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
28 :
29 : #include "SlideSorter.hxx"
30 :
31 : using namespace ::com::sun::star::datatransfer::dnd::DNDConstants;
32 :
33 : namespace sd { namespace slidesorter { namespace controller {
34 :
35 64 : InsertionIndicatorHandler::InsertionIndicatorHandler (SlideSorter& rSlideSorter)
36 : : mrSlideSorter(rSlideSorter),
37 : mpInsertAnimator(),
38 64 : mpInsertionIndicatorOverlay(new view::InsertionIndicatorOverlay(rSlideSorter)),
39 : maInsertPosition(),
40 : meMode(MoveMode),
41 : mbIsInsertionTrivial(false),
42 : mbIsActive(false),
43 64 : mbIsReadOnly(mrSlideSorter.GetModel().IsReadOnly()),
44 : mbIsOverSourceView(true),
45 : maIconSize(0,0),
46 192 : mbIsForcedShow(false)
47 : {
48 64 : }
49 :
50 64 : InsertionIndicatorHandler::~InsertionIndicatorHandler()
51 : {
52 64 : }
53 :
54 0 : void InsertionIndicatorHandler::Start (const bool bIsOverSourceView)
55 : {
56 0 : if (mbIsActive)
57 : {
58 : OSL_ASSERT(!mbIsActive);
59 : }
60 :
61 0 : mbIsReadOnly = mrSlideSorter.GetModel().IsReadOnly();
62 0 : if (mbIsReadOnly)
63 0 : return;
64 :
65 0 : mbIsActive = true;
66 0 : mbIsOverSourceView = bIsOverSourceView;
67 : }
68 :
69 64 : void InsertionIndicatorHandler::End (const controller::Animator::AnimationMode eMode)
70 : {
71 64 : if (mbIsForcedShow || ! mbIsActive || mbIsReadOnly)
72 128 : return;
73 :
74 0 : GetInsertAnimator()->Reset(eMode);
75 :
76 0 : mbIsActive = false;
77 : // maInsertPosition = view::InsertPosition();
78 0 : meMode = UnknownMode;
79 :
80 0 : mpInsertionIndicatorOverlay->Hide();
81 0 : mpInsertionIndicatorOverlay.reset(new view::InsertionIndicatorOverlay(mrSlideSorter));
82 : }
83 :
84 0 : void InsertionIndicatorHandler::ForceShow()
85 : {
86 0 : mbIsForcedShow = true;
87 0 : }
88 :
89 0 : void InsertionIndicatorHandler::ForceEnd()
90 : {
91 0 : mbIsForcedShow = false;
92 0 : End(Animator::AM_Immediate);
93 0 : }
94 :
95 0 : void InsertionIndicatorHandler::UpdateIndicatorIcon (const SdTransferable* pTransferable)
96 : {
97 0 : mpInsertionIndicatorOverlay->Create(pTransferable);
98 0 : maIconSize = mpInsertionIndicatorOverlay->GetSize();
99 0 : }
100 :
101 0 : InsertionIndicatorHandler::Mode InsertionIndicatorHandler::GetModeFromDndAction (
102 : const sal_Int8 nDndAction)
103 : {
104 0 : if ((nDndAction & ACTION_MOVE) != 0)
105 0 : return MoveMode;
106 0 : else if ((nDndAction & ACTION_COPY) != 0)
107 0 : return CopyMode;
108 : else
109 0 : return UnknownMode;
110 : }
111 :
112 0 : void InsertionIndicatorHandler::UpdatePosition (
113 : const Point& rMouseModelPosition,
114 : const Mode eMode)
115 : {
116 0 : if ( ! mbIsActive)
117 0 : return;
118 :
119 0 : if (mbIsReadOnly)
120 0 : return;
121 :
122 0 : SetPosition(rMouseModelPosition, eMode);
123 : }
124 :
125 0 : void InsertionIndicatorHandler::UpdatePosition (
126 : const Point& rMouseModelPosition,
127 : const sal_Int8 nDndAction)
128 : {
129 0 : UpdatePosition(rMouseModelPosition, GetModeFromDndAction(nDndAction));
130 0 : }
131 :
132 0 : sal_Int32 InsertionIndicatorHandler::GetInsertionPageIndex() const
133 : {
134 0 : if (mbIsReadOnly)
135 0 : return -1;
136 : else
137 0 : return maInsertPosition.GetIndex();
138 : }
139 :
140 0 : void InsertionIndicatorHandler::SetPosition (
141 : const Point& rPoint,
142 : const Mode eMode)
143 : {
144 0 : view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter());
145 :
146 : const view::InsertPosition aInsertPosition (rLayouter.GetInsertPosition(
147 : rPoint,
148 : maIconSize,
149 0 : mrSlideSorter.GetModel()));
150 :
151 0 : if (maInsertPosition != aInsertPosition
152 0 : || meMode != eMode
153 : // || ! mpInsertionIndicatorOverlay->IsVisible()
154 : )
155 : {
156 0 : maInsertPosition = aInsertPosition;
157 0 : meMode = eMode;
158 0 : mbIsInsertionTrivial = IsInsertionTrivial(maInsertPosition.GetIndex(), eMode);
159 0 : if (maInsertPosition.GetIndex()>=0 && ! mbIsInsertionTrivial)
160 : {
161 0 : mpInsertionIndicatorOverlay->SetLocation(maInsertPosition.GetLocation());
162 :
163 0 : GetInsertAnimator()->SetInsertPosition(maInsertPosition);
164 0 : mpInsertionIndicatorOverlay->Show();
165 : }
166 : else
167 : {
168 0 : GetInsertAnimator()->Reset(Animator::AM_Animated);
169 0 : mpInsertionIndicatorOverlay->Hide();
170 : }
171 : }
172 0 : }
173 :
174 0 : ::boost::shared_ptr<view::InsertAnimator> InsertionIndicatorHandler::GetInsertAnimator()
175 : {
176 0 : if ( ! mpInsertAnimator)
177 0 : mpInsertAnimator.reset(new view::InsertAnimator(mrSlideSorter));
178 0 : return mpInsertAnimator;
179 : }
180 :
181 0 : bool InsertionIndicatorHandler::IsInsertionTrivial (
182 : const sal_Int32 nInsertionIndex,
183 : const Mode eMode) const
184 : {
185 0 : if (eMode == CopyMode)
186 0 : return false;
187 0 : else if (eMode == UnknownMode)
188 0 : return true;
189 :
190 0 : if ( ! mbIsOverSourceView)
191 0 : return false;
192 :
193 : // Iterate over all selected pages and check whether there are
194 : // holes. While we do this we remember the indices of the first and
195 : // last selected page as preparation for the next step.
196 0 : sal_Int32 nCurrentIndex = -1;
197 0 : sal_Int32 nFirstIndex = -1;
198 0 : sal_Int32 nLastIndex = -1;
199 : model::PageEnumeration aSelectedPages (
200 : model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
201 0 : mrSlideSorter.GetModel()));
202 0 : while (aSelectedPages.HasMoreElements())
203 : {
204 0 : model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
205 :
206 : // Get the page number and compare it to the last one.
207 0 : const sal_Int32 nPageNumber (pDescriptor->GetPageIndex());
208 0 : if (nCurrentIndex>=0 && nPageNumber>(nCurrentIndex+1))
209 0 : return false;
210 : else
211 0 : nCurrentIndex = nPageNumber;
212 :
213 : // Remember indices of the first and last page of the selection.
214 0 : if (nFirstIndex == -1)
215 0 : nFirstIndex = nPageNumber;
216 0 : nLastIndex = nPageNumber;
217 0 : }
218 :
219 : // When we come here then the selection has no holes. We still have
220 : // to check that the insertion position is not directly in front or
221 : // directly behind the selection and thus moving the selection there
222 : // would not change the model.
223 0 : if (nInsertionIndex<nFirstIndex || nInsertionIndex>(nLastIndex+1))
224 0 : return false;
225 :
226 0 : return true;
227 : }
228 :
229 0 : bool InsertionIndicatorHandler::IsInsertionTrivial (const sal_Int8 nDndAction)
230 : {
231 0 : return IsInsertionTrivial(GetInsertionPageIndex(), GetModeFromDndAction(nDndAction));
232 : }
233 :
234 : //===== InsertionIndicatorHandler::ForceShowContext ===========================
235 :
236 0 : InsertionIndicatorHandler::ForceShowContext::ForceShowContext (
237 : const ::boost::shared_ptr<InsertionIndicatorHandler>& rpHandler)
238 0 : : mpHandler(rpHandler)
239 : {
240 0 : mpHandler->ForceShow();
241 0 : }
242 :
243 0 : InsertionIndicatorHandler::ForceShowContext::~ForceShowContext()
244 : {
245 0 : mpHandler->ForceEnd();
246 0 : }
247 :
248 66 : } } } // end of namespace ::sd::slidesorter::controller
249 :
250 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|