blob: 0aa6b541bf2c695674ace7653490dab796106890 [file] [log] [blame]
/**************************************************************
*
* 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 <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
#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<view::InsertAnimator> 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<nFirstIndex || 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<InsertionIndicatorHandler>& rpHandler)
: mpHandler(rpHandler)
{
mpHandler->ForceShow();
}
InsertionIndicatorHandler::ForceShowContext::~ForceShowContext (void)
{
mpHandler->ForceEnd();
}
} } } // end of namespace ::sd::slidesorter::controller