1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include "precompiled_sd.hxx"
25
26 #include "controller/SlsInsertionIndicatorHandler.hxx"
27 #include "controller/SlsProperties.hxx"
28 #include "view/SlideSorterView.hxx"
29 #include "view/SlsLayouter.hxx"
30 #include "view/SlsInsertionIndicatorOverlay.hxx"
31 #include "model/SlideSorterModel.hxx"
32 #include "model/SlsPageEnumerationProvider.hxx"
33 #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
34
35 #include "SlideSorter.hxx"
36
37 using namespace ::com::sun::star::datatransfer::dnd::DNDConstants;
38
39 namespace sd { namespace slidesorter { namespace controller {
40
41
InsertionIndicatorHandler(SlideSorter & rSlideSorter)42 InsertionIndicatorHandler::InsertionIndicatorHandler (SlideSorter& rSlideSorter)
43 : mrSlideSorter(rSlideSorter),
44 mpInsertAnimator(),
45 mpInsertionIndicatorOverlay(new view::InsertionIndicatorOverlay(rSlideSorter)),
46 maInsertPosition(),
47 meMode(MoveMode),
48 mbIsActive(false),
49 mbIsReadOnly(mrSlideSorter.GetModel().IsReadOnly()),
50 mbIsOverSourceView(true),
51 maIconSize(0,0),
52 mbIsForcedShow(false)
53 {
54 }
55
56
57
58
~InsertionIndicatorHandler(void)59 InsertionIndicatorHandler::~InsertionIndicatorHandler (void)
60 {
61 }
62
63
64
65
Start(const bool bIsOverSourceView)66 void InsertionIndicatorHandler::Start (const bool bIsOverSourceView)
67 {
68 if (mbIsActive)
69 {
70 OSL_ASSERT(!mbIsActive);
71 }
72
73 mbIsReadOnly = mrSlideSorter.GetModel().IsReadOnly();
74 if (mbIsReadOnly)
75 return;
76
77 mbIsActive = true;
78 mbIsOverSourceView = bIsOverSourceView;
79 }
80
81
82
83
End(const controller::Animator::AnimationMode eMode)84 void InsertionIndicatorHandler::End (const controller::Animator::AnimationMode eMode)
85 {
86 if (mbIsForcedShow || ! mbIsActive || mbIsReadOnly)
87 return;
88
89 GetInsertAnimator()->Reset(eMode);
90
91 mbIsActive = false;
92 // maInsertPosition = view::InsertPosition();
93 meMode = UnknownMode;
94
95 mpInsertionIndicatorOverlay->Hide();
96 mpInsertionIndicatorOverlay.reset(new view::InsertionIndicatorOverlay(mrSlideSorter));
97 }
98
99
100
101
ForceShow(void)102 void InsertionIndicatorHandler::ForceShow (void)
103 {
104 mbIsForcedShow = true;
105 }
106
107
108
109
ForceEnd(void)110 void InsertionIndicatorHandler::ForceEnd (void)
111 {
112 mbIsForcedShow = false;
113 End(Animator::AM_Immediate);
114 }
115
116
117
118
UpdateIndicatorIcon(const SdTransferable * pTransferable)119 void InsertionIndicatorHandler::UpdateIndicatorIcon (const SdTransferable* pTransferable)
120 {
121 mpInsertionIndicatorOverlay->Create(pTransferable);
122 maIconSize = mpInsertionIndicatorOverlay->GetSize();
123 }
124
125
126
127
GetModeFromDndAction(const sal_Int8 nDndAction)128 InsertionIndicatorHandler::Mode InsertionIndicatorHandler::GetModeFromDndAction (
129 const sal_Int8 nDndAction)
130 {
131 if ((nDndAction & ACTION_MOVE) != 0)
132 return MoveMode;
133 else if ((nDndAction & ACTION_COPY) != 0)
134 return CopyMode;
135 else
136 return UnknownMode;
137 }
138
139
140
141
UpdatePosition(const Point & rMouseModelPosition,const Mode eMode)142 void InsertionIndicatorHandler::UpdatePosition (
143 const Point& rMouseModelPosition,
144 const Mode eMode)
145 {
146 if ( ! mbIsActive)
147 return;
148
149 if (mbIsReadOnly)
150 return;
151
152 SetPosition(rMouseModelPosition, eMode);
153 }
154
155
156
157
UpdatePosition(const Point & rMouseModelPosition,const sal_Int8 nDndAction)158 void InsertionIndicatorHandler::UpdatePosition (
159 const Point& rMouseModelPosition,
160 const sal_Int8 nDndAction)
161 {
162 UpdatePosition(rMouseModelPosition, GetModeFromDndAction(nDndAction));
163 }
164
165
166
167
IsActive(void) const168 bool InsertionIndicatorHandler::IsActive (void) const
169 {
170 return mbIsActive;
171 }
172
173
174
175
GetInsertionPageIndex(void) const176 sal_Int32 InsertionIndicatorHandler::GetInsertionPageIndex (void) const
177 {
178 if (mbIsReadOnly)
179 return -1;
180 else
181 return maInsertPosition.GetIndex();
182 }
183
184
185
186
SetPosition(const Point & rPoint,const Mode eMode)187 void InsertionIndicatorHandler::SetPosition (
188 const Point& rPoint,
189 const Mode eMode)
190 {
191 view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter());
192
193 const view::InsertPosition aInsertPosition (rLayouter.GetInsertPosition(
194 rPoint,
195 maIconSize,
196 mrSlideSorter.GetModel()));
197
198 static sal_Int32 TargetIndex (1);
199 if (aInsertPosition.GetIndex() == TargetIndex)
200 {
201 const view::InsertPosition aPosition (rLayouter.GetInsertPosition(
202 rPoint,
203 maIconSize,
204 mrSlideSorter.GetModel()));
205 const view::InsertPosition aPosition2 (rLayouter.GetInsertPosition(
206 rPoint,
207 maIconSize,
208 mrSlideSorter.GetModel()));
209 }
210
211 if (maInsertPosition != aInsertPosition
212 || meMode != eMode
213 // || ! mpInsertionIndicatorOverlay->IsVisible()
214 )
215 {
216 maInsertPosition = aInsertPosition;
217 meMode = eMode;
218 mbIsInsertionTrivial = IsInsertionTrivial(maInsertPosition.GetIndex(), eMode);
219 if (maInsertPosition.GetIndex()>=0 && ! mbIsInsertionTrivial)
220 {
221 mpInsertionIndicatorOverlay->SetLocation(maInsertPosition.GetLocation());
222
223 GetInsertAnimator()->SetInsertPosition(maInsertPosition);
224 mpInsertionIndicatorOverlay->Show();
225 }
226 else
227 {
228 GetInsertAnimator()->Reset(Animator::AM_Animated);
229 mpInsertionIndicatorOverlay->Hide();
230 }
231 }
232 }
233
234
235
236
GetInsertAnimator(void)237 ::boost::shared_ptr<view::InsertAnimator> InsertionIndicatorHandler::GetInsertAnimator (void)
238 {
239 if ( ! mpInsertAnimator)
240 mpInsertAnimator.reset(new view::InsertAnimator(mrSlideSorter));
241 return mpInsertAnimator;
242 }
243
244
245
246
IsInsertionTrivial(const sal_Int32 nInsertionIndex,const Mode eMode) const247 bool InsertionIndicatorHandler::IsInsertionTrivial (
248 const sal_Int32 nInsertionIndex,
249 const Mode eMode) const
250 {
251 if (eMode == CopyMode)
252 return false;
253 else if (eMode == UnknownMode)
254 return true;
255
256 if ( ! mbIsOverSourceView)
257 return false;
258
259 // Iterate over all selected pages and check whether there are
260 // holes. While we do this we remember the indices of the first and
261 // last selected page as preparation for the next step.
262 sal_Int32 nCurrentIndex = -1;
263 sal_Int32 nFirstIndex = -1;
264 sal_Int32 nLastIndex = -1;
265 model::PageEnumeration aSelectedPages (
266 model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
267 mrSlideSorter.GetModel()));
268 while (aSelectedPages.HasMoreElements())
269 {
270 model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement());
271
272 // Get the page number and compare it to the last one.
273 const sal_Int32 nPageNumber (pDescriptor->GetPageIndex());
274 if (nCurrentIndex>=0 && nPageNumber>(nCurrentIndex+1))
275 return false;
276 else
277 nCurrentIndex = nPageNumber;
278
279 // Remember indices of the first and last page of the selection.
280 if (nFirstIndex == -1)
281 nFirstIndex = nPageNumber;
282 nLastIndex = nPageNumber;
283 }
284
285 // When we come here then the selection has no holes. We still have
286 // to check that the insertion position is not directly in front or
287 // directly behind the selection and thus moving the selection there
288 // would not change the model.
289 if (nInsertionIndex<nFirstIndex || nInsertionIndex>(nLastIndex+1))
290 return false;
291
292 return true;
293 }
294
295
296
297
IsInsertionTrivial(const sal_Int8 nDndAction)298 bool InsertionIndicatorHandler::IsInsertionTrivial (const sal_Int8 nDndAction)
299 {
300 return IsInsertionTrivial(GetInsertionPageIndex(), GetModeFromDndAction(nDndAction));
301 }
302
303
304
305
306 //===== InsertionIndicatorHandler::ForceShowContext ===========================
307
ForceShowContext(const::boost::shared_ptr<InsertionIndicatorHandler> & rpHandler)308 InsertionIndicatorHandler::ForceShowContext::ForceShowContext (
309 const ::boost::shared_ptr<InsertionIndicatorHandler>& rpHandler)
310 : mpHandler(rpHandler)
311 {
312 mpHandler->ForceShow();
313 }
314
315
316
317
~ForceShowContext(void)318 InsertionIndicatorHandler::ForceShowContext::~ForceShowContext (void)
319 {
320 mpHandler->ForceEnd();
321 }
322
323 } } } // end of namespace ::sd::slidesorter::controller
324