/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #include "precompiled_sd.hxx" #include "controller/SlsInsertionIndicatorHandler.hxx" #include "controller/SlsProperties.hxx" #include "view/SlideSorterView.hxx" #include "view/SlsLayouter.hxx" #include "view/SlsInsertionIndicatorOverlay.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageEnumerationProvider.hxx" #include #include "SlideSorter.hxx" using namespace ::com::sun::star::datatransfer::dnd::DNDConstants; namespace sd { namespace slidesorter { namespace controller { InsertionIndicatorHandler::InsertionIndicatorHandler (SlideSorter& rSlideSorter) : mrSlideSorter(rSlideSorter), mpInsertAnimator(), mpInsertionIndicatorOverlay(new view::InsertionIndicatorOverlay(rSlideSorter)), maInsertPosition(), meMode(MoveMode), mbIsActive(false), mbIsReadOnly(mrSlideSorter.GetModel().IsReadOnly()), mbIsOverSourceView(true), maIconSize(0,0), mbIsForcedShow(false) { } InsertionIndicatorHandler::~InsertionIndicatorHandler (void) { } void InsertionIndicatorHandler::Start (const bool bIsOverSourceView) { if (mbIsActive) { OSL_ASSERT(!mbIsActive); } mbIsReadOnly = mrSlideSorter.GetModel().IsReadOnly(); if (mbIsReadOnly) return; mbIsActive = true; mbIsOverSourceView = bIsOverSourceView; } void InsertionIndicatorHandler::End (const controller::Animator::AnimationMode eMode) { if (mbIsForcedShow || ! mbIsActive || mbIsReadOnly) return; GetInsertAnimator()->Reset(eMode); mbIsActive = false; // maInsertPosition = view::InsertPosition(); meMode = UnknownMode; mpInsertionIndicatorOverlay->Hide(); mpInsertionIndicatorOverlay.reset(new view::InsertionIndicatorOverlay(mrSlideSorter)); } void InsertionIndicatorHandler::ForceShow (void) { mbIsForcedShow = true; } void InsertionIndicatorHandler::ForceEnd (void) { mbIsForcedShow = false; End(Animator::AM_Immediate); } void InsertionIndicatorHandler::UpdateIndicatorIcon (const SdTransferable* pTransferable) { mpInsertionIndicatorOverlay->Create(pTransferable); maIconSize = mpInsertionIndicatorOverlay->GetSize(); } InsertionIndicatorHandler::Mode InsertionIndicatorHandler::GetModeFromDndAction ( const sal_Int8 nDndAction) { if ((nDndAction & ACTION_MOVE) != 0) return MoveMode; else if ((nDndAction & ACTION_COPY) != 0) return CopyMode; else return UnknownMode; } void InsertionIndicatorHandler::UpdatePosition ( const Point& rMouseModelPosition, const Mode eMode) { if ( ! mbIsActive) return; if (mbIsReadOnly) return; SetPosition(rMouseModelPosition, eMode); } void InsertionIndicatorHandler::UpdatePosition ( const Point& rMouseModelPosition, const sal_Int8 nDndAction) { UpdatePosition(rMouseModelPosition, GetModeFromDndAction(nDndAction)); } bool InsertionIndicatorHandler::IsActive (void) const { return mbIsActive; } sal_Int32 InsertionIndicatorHandler::GetInsertionPageIndex (void) const { if (mbIsReadOnly) return -1; else return maInsertPosition.GetIndex(); } void InsertionIndicatorHandler::SetPosition ( const Point& rPoint, const Mode eMode) { view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter()); const view::InsertPosition aInsertPosition (rLayouter.GetInsertPosition( rPoint, maIconSize, mrSlideSorter.GetModel())); static sal_Int32 TargetIndex (1); if (aInsertPosition.GetIndex() == TargetIndex) { const view::InsertPosition aPosition (rLayouter.GetInsertPosition( rPoint, maIconSize, mrSlideSorter.GetModel())); const view::InsertPosition aPosition2 (rLayouter.GetInsertPosition( rPoint, maIconSize, mrSlideSorter.GetModel())); } if (maInsertPosition != aInsertPosition || meMode != eMode // || ! mpInsertionIndicatorOverlay->IsVisible() ) { maInsertPosition = aInsertPosition; meMode = eMode; mbIsInsertionTrivial = IsInsertionTrivial(maInsertPosition.GetIndex(), eMode); if (maInsertPosition.GetIndex()>=0 && ! mbIsInsertionTrivial) { mpInsertionIndicatorOverlay->SetLocation(maInsertPosition.GetLocation()); GetInsertAnimator()->SetInsertPosition(maInsertPosition); mpInsertionIndicatorOverlay->Show(); } else { GetInsertAnimator()->Reset(Animator::AM_Animated); mpInsertionIndicatorOverlay->Hide(); } } } ::boost::shared_ptr InsertionIndicatorHandler::GetInsertAnimator (void) { if ( ! mpInsertAnimator) mpInsertAnimator.reset(new view::InsertAnimator(mrSlideSorter)); return mpInsertAnimator; } bool InsertionIndicatorHandler::IsInsertionTrivial ( const sal_Int32 nInsertionIndex, const Mode eMode) const { if (eMode == CopyMode) return false; else if (eMode == UnknownMode) return true; if ( ! mbIsOverSourceView) return false; // Iterate over all selected pages and check whether there are // holes. While we do this we remember the indices of the first and // last selected page as preparation for the next step. sal_Int32 nCurrentIndex = -1; sal_Int32 nFirstIndex = -1; sal_Int32 nLastIndex = -1; model::PageEnumeration aSelectedPages ( model::PageEnumerationProvider::CreateSelectedPagesEnumeration( mrSlideSorter.GetModel())); while (aSelectedPages.HasMoreElements()) { model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement()); // Get the page number and compare it to the last one. const sal_Int32 nPageNumber (pDescriptor->GetPageIndex()); if (nCurrentIndex>=0 && nPageNumber>(nCurrentIndex+1)) return false; else nCurrentIndex = nPageNumber; // Remember indices of the first and last page of the selection. if (nFirstIndex == -1) nFirstIndex = nPageNumber; nLastIndex = nPageNumber; } // When we come here then the selection has no holes. We still have // to check that the insertion position is not directly in front or // directly behind the selection and thus moving the selection there // would not change the model. if (nInsertionIndex(nLastIndex+1)) return false; return true; } bool InsertionIndicatorHandler::IsInsertionTrivial (const sal_Int8 nDndAction) { return IsInsertionTrivial(GetInsertionPageIndex(), GetModeFromDndAction(nDndAction)); } //===== InsertionIndicatorHandler::ForceShowContext =========================== InsertionIndicatorHandler::ForceShowContext::ForceShowContext ( const ::boost::shared_ptr& rpHandler) : mpHandler(rpHandler) { mpHandler->ForceShow(); } InsertionIndicatorHandler::ForceShowContext::~ForceShowContext (void) { mpHandler->ForceEnd(); } } } } // end of namespace ::sd::slidesorter::controller