renaissance1: #i107215# Improved drag and drop.

This commit is contained in:
Andre Fischer
2010-02-23 16:56:05 +01:00
parent 2318e08d02
commit 3c7bf4b67d
26 changed files with 800 additions and 320 deletions

View File

@@ -440,7 +440,9 @@ bool SlideSorterController::Command (
// indicator so that the user knows where a page insertion // indicator so that the user knows where a page insertion
// would take place. // would take place.
GetInsertionIndicatorHandler()->Start( GetInsertionIndicatorHandler()->Start(
pWindow->PixelToLogic(rEvent.GetMousePosPixel())); pWindow->PixelToLogic(rEvent.GetMousePosPixel()),
InsertionIndicatorHandler::MoveMode,
false);
} }
pWindow->ReleaseMouse(); pWindow->ReleaseMouse();
@@ -863,6 +865,15 @@ FunctionReference SlideSorterController::CreateSelectionFunction (SfxRequest& rR
::rtl::Reference<SelectionFunction> SlideSorterController::GetCurrentSelectionFunction (void)
{
FunctionReference pFunction (mrSlideSorter.GetViewShell()->GetCurrentFunction());
return ::rtl::Reference<SelectionFunction>(dynamic_cast<SelectionFunction*>(pFunction.get()));
}
void SlideSorterController::PrepareEditModeChange (void) void SlideSorterController::PrepareEditModeChange (void)
{ {
// Before we throw away the page descriptors we prepare for selecting // Before we throw away the page descriptors we prepare for selecting
@@ -1041,6 +1052,8 @@ void SlideSorterController::SetDocumentSlides (const Reference<container::XIndex
void SlideSorterController::CheckForMasterPageAssignment (void) void SlideSorterController::CheckForMasterPageAssignment (void)
{ {
if (mrModel.GetPageCount()%2==0)
return;
PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(mrModel)); PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(mrModel));
while (aAllPages.HasMoreElements()) while (aAllPages.HasMoreElements())
{ {

View File

@@ -194,9 +194,15 @@ void Animator::RemoveAnimation (const Animator::AnimationId nId)
maAnimations.erase(iAnimation); maAnimations.erase(iAnimation);
} }
// Reset the animation id when we can.
if (maAnimations.empty()) if (maAnimations.empty())
{
// Reset the animation id when we can.
mnNextAnimationId = 0; mnNextAnimationId = 0;
// No more animations => we do not have to suppress painting
// anymore.
mpDrawLock.reset();
}
} }

View File

@@ -367,11 +367,17 @@ void Clipboard::CreateSlideTransferable (
{ {
mrSlideSorter.GetView().BrkAction(); mrSlideSorter.GetView().BrkAction();
SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument(); SdDrawDocument* pDocument = mrSlideSorter.GetModel().GetDocument();
::boost::shared_ptr<SubstitutionHandler> pSubstitutionHandler;
::rtl::Reference<SelectionFunction> pSelectionFunction (
mrSlideSorter.GetController().GetCurrentSelectionFunction());
if (pSelectionFunction.is())
pSubstitutionHandler = pSelectionFunction->GetSubstitutionHandler();
SdTransferable* pTransferable = new Transferable ( SdTransferable* pTransferable = new Transferable (
pDocument, pDocument,
NULL, NULL,
FALSE, FALSE,
dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell())); dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell()),
pSubstitutionHandler);
if (bDrag) if (bDrag)
SD_MOD()->pTransferDrag = pTransferable; SD_MOD()->pTransferDrag = pTransferable;
@@ -433,7 +439,9 @@ void Clipboard::StartDrag (
mbUpdateSelectionPending = false; mbUpdateSelectionPending = false;
CreateSlideTransferable(pWindow, TRUE); CreateSlideTransferable(pWindow, TRUE);
mrController.GetInsertionIndicatorHandler()->UpdatePosition(rPosition); mrController.GetInsertionIndicatorHandler()->UpdatePosition(
rPosition,
InsertionIndicatorHandler::UnknownMode);
} }
@@ -442,8 +450,9 @@ void Clipboard::StartDrag (
void Clipboard::DragFinished (sal_Int8 nDropAction) void Clipboard::DragFinished (sal_Int8 nDropAction)
{ {
// Hide the substitution display and insertion indicator. // Hide the substitution display and insertion indicator.
mrSlideSorter.GetView().GetOverlay().GetSubstitutionOverlay()->SetIsVisible(false); ::rtl::Reference<SelectionFunction> pFunction (mrController.GetCurrentSelectionFunction());
mrSlideSorter.GetController().GetInsertionIndicatorHandler()->End(); if (pFunction.is())
pFunction->NotifyDragFinished();
SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag; SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
@@ -467,7 +476,8 @@ void Clipboard::DragFinished (sal_Int8 nDropAction)
mrController.GetSelectionManager()->DeleteSelectedPages (); mrController.GetSelectionManager()->DeleteSelectedPages ();
} }
SelectPages(); if (nDropAction != DND_ACTION_NONE)
SelectPages();
} }
@@ -527,7 +537,9 @@ sal_Int8 Clipboard::AcceptDrop (
// Show the insertion marker and the substitution for a drop. // Show the insertion marker and the substitution for a drop.
Point aPosition = pTargetWindow->PixelToLogic (rEvent.maPosPixel); Point aPosition = pTargetWindow->PixelToLogic (rEvent.maPosPixel);
view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
mrController.GetInsertionIndicatorHandler()->UpdatePosition(aPosition); mrController.GetInsertionIndicatorHandler()->UpdatePosition(
aPosition,
rEvent.maDragEvent.DropAction);
rOverlay.GetSubstitutionOverlay()->SetPosition(aPosition); rOverlay.GetSubstitutionOverlay()->SetPosition(aPosition);
// Scroll the window when the mouse reaches the window border. // Scroll the window when the mouse reaches the window border.
@@ -580,10 +592,10 @@ sal_Int8 Clipboard::ExecuteDrop (
|| ( nXOffset >= 2 && nYOffset >= 2 ); || ( nXOffset >= 2 && nYOffset >= 2 );
// Get insertion position and then turn off the insertion indicator. // Get insertion position and then turn off the insertion indicator.
mrController.GetInsertionIndicatorHandler()->UpdatePosition(aEventModelPosition); mrController.GetInsertionIndicatorHandler()->UpdatePosition(
aEventModelPosition,
rEvent.mnAction);
USHORT nIndex = DetermineInsertPosition(*pDragTransferable); USHORT nIndex = DetermineInsertPosition(*pDragTransferable);
OSL_TRACE ("Clipboard::AcceptDrop() called for index %d",
nIndex);
mrController.GetInsertionIndicatorHandler()->End(); mrController.GetInsertionIndicatorHandler()->End();
if (bContinue) if (bContinue)
@@ -617,6 +629,13 @@ sal_Int8 Clipboard::ExecuteDrop (
nResult = rEvent.mnAction; nResult = rEvent.mnAction;
} }
} }
// Notify the receiving selection function that drag-and-drop is
// finished and the substitution handler can be released.
::rtl::Reference<SelectionFunction> pFunction (
mrController.GetCurrentSelectionFunction());
if (pFunction.is())
pFunction->NotifyDragFinished();
} }
break; break;

View File

@@ -134,7 +134,7 @@ void CurrentSlideManager::SwitchCurrentSlide (const sal_Int32 nSlideIndex)
void CurrentSlideManager::SwitchCurrentSlide (const SharedPageDescriptor& rpDescriptor) void CurrentSlideManager::SwitchCurrentSlide (const SharedPageDescriptor& rpDescriptor)
{ {
if (rpDescriptor.get() != NULL) if (rpDescriptor.get() != NULL && mpCurrentSlide!=rpDescriptor)
{ {
ReleaseCurrentSlide(); ReleaseCurrentSlide();
AcquireCurrentSlide((rpDescriptor->GetPage()->GetPageNum()-1)/2); AcquireCurrentSlide((rpDescriptor->GetPage()->GetPageNum()-1)/2);

View File

@@ -37,9 +37,11 @@
#include "view/SlsLayouter.hxx" #include "view/SlsLayouter.hxx"
#include "model/SlideSorterModel.hxx" #include "model/SlideSorterModel.hxx"
#include "model/SlsPageEnumerationProvider.hxx" #include "model/SlsPageEnumerationProvider.hxx"
#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
#include "SlideSorter.hxx" #include "SlideSorter.hxx"
using namespace ::com::sun::star::datatransfer::dnd::DNDConstants;
namespace sd { namespace slidesorter { namespace controller { namespace sd { namespace slidesorter { namespace controller {
@@ -51,8 +53,10 @@ InsertionIndicatorHandler::InsertionIndicatorHandler (SlideSorter& rSlideSorter)
mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay()), mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay()),
mnInsertionIndex(-1), mnInsertionIndex(-1),
mbIsBeforePage(false), mbIsBeforePage(false),
meMode(MoveMode),
mbIsActive(false), mbIsActive(false),
mbIsReadOnly(mrSlideSorter.GetModel().IsReadOnly()) mbIsReadOnly(mrSlideSorter.GetModel().IsReadOnly()),
mbIsOverSourceView(true)
{ {
} }
@@ -66,7 +70,10 @@ InsertionIndicatorHandler::~InsertionIndicatorHandler (void)
void InsertionIndicatorHandler::Start (const Point& rMouseModelPosition) void InsertionIndicatorHandler::Start (
const Point& rMouseModelPosition,
const Mode eMode,
const bool bIsOverSourceView)
{ {
if (mbIsActive) if (mbIsActive)
{ {
@@ -77,15 +84,32 @@ void InsertionIndicatorHandler::Start (const Point& rMouseModelPosition)
if (mbIsReadOnly) if (mbIsReadOnly)
return; return;
SetPosition(rMouseModelPosition); SetPosition(rMouseModelPosition, eMode);
mbIsActive = true; mbIsActive = true;
mbIsOverSourceView = bIsOverSourceView;
} }
void InsertionIndicatorHandler::UpdatePosition (const Point& rMouseModelPosition) InsertionIndicatorHandler::Mode InsertionIndicatorHandler::GetModeFromDndAction (
const sal_Int8 nDndAction)
{
switch (nDndAction & (ACTION_COPY | ACTION_MOVE | ACTION_LINK))
{
case ACTION_COPY: return CopyMode;
case ACTION_MOVE: return MoveMode;
default: return UnknownMode;
}
}
void InsertionIndicatorHandler::UpdatePosition (
const Point& rMouseModelPosition,
const Mode eMode)
{ {
if ( ! mbIsActive) if ( ! mbIsActive)
return; return;
@@ -93,7 +117,17 @@ void InsertionIndicatorHandler::UpdatePosition (const Point& rMouseModelPosition
if (mbIsReadOnly) if (mbIsReadOnly)
return; return;
SetPosition(rMouseModelPosition); SetPosition(rMouseModelPosition, eMode);
}
void InsertionIndicatorHandler::UpdatePosition (
const Point& rMouseModelPosition,
const sal_Int8 nDndAction)
{
UpdatePosition(rMouseModelPosition, GetModeFromDndAction(nDndAction));
} }
@@ -136,7 +170,9 @@ sal_Int32 InsertionIndicatorHandler::GetInsertionPageIndex (void) const
void InsertionIndicatorHandler::SetPosition (const Point& rPoint) void InsertionIndicatorHandler::SetPosition (
const Point& rPoint,
const Mode eMode)
{ {
static const bool bAllowHorizontalInsertMarker = true; static const bool bAllowHorizontalInsertMarker = true;
view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter()); view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter());
@@ -183,11 +219,14 @@ void InsertionIndicatorHandler::SetPosition (const Point& rPoint)
nInsertionIndex += 1; nInsertionIndex += 1;
} }
if (mnInsertionIndex!=nInsertionIndex || mbIsBeforePage!=bIsBeforePage) if (mnInsertionIndex!=nInsertionIndex
|| mbIsBeforePage!=bIsBeforePage
|| meMode!=eMode)
{ {
mnInsertionIndex = nInsertionIndex; mnInsertionIndex = nInsertionIndex;
mbIsBeforePage = bIsBeforePage; mbIsBeforePage = bIsBeforePage;
mbIsInsertionTrivial = IsInsertionTrivial(); meMode = eMode;
mbIsInsertionTrivial = IsInsertionTrivial(eMode);
mpInsertionIndicatorOverlay->SetLocation( mpInsertionIndicatorOverlay->SetLocation(
rLayouter.GetInsertionMarkerLocation ( rLayouter.GetInsertionMarkerLocation (
@@ -223,8 +262,16 @@ void InsertionIndicatorHandler::SetPosition (const Point& rPoint)
bool InsertionIndicatorHandler::IsInsertionTrivial (void) const bool InsertionIndicatorHandler::IsInsertionTrivial (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 // Iterate over all selected pages and check whether there are
// holes. While we do this we remember the indices of the first and // holes. While we do this we remember the indices of the first and
// last selected page as preparation for the next step. // last selected page as preparation for the next step.

View File

@@ -57,6 +57,7 @@ using namespace ::com::sun::star::uno;
using namespace ::sd::slidesorter::model; using namespace ::sd::slidesorter::model;
using namespace ::sd::slidesorter::view; using namespace ::sd::slidesorter::view;
namespace sd { namespace slidesorter { namespace controller { namespace sd { namespace slidesorter { namespace controller {
PageSelector::PageSelector (SlideSorter& rSlideSorter) PageSelector::PageSelector (SlideSorter& rSlideSorter)
@@ -69,7 +70,8 @@ PageSelector::PageSelector (SlideSorter& rSlideSorter)
mpMostRecentlySelectedPage(), mpMostRecentlySelectedPage(),
mpSelectionAnchor(), mpSelectionAnchor(),
mpCurrentPage(), mpCurrentPage(),
mnUpdateLockCount(0) mnUpdateLockCount(0),
mbIsUpdateCurrentPagePending(false)
{ {
CountSelectedPages (); CountSelectedPages ();
} }
@@ -82,7 +84,6 @@ void PageSelector::SelectAllPages (void)
int nPageCount = mrModel.GetPageCount(); int nPageCount = mrModel.GetPageCount();
for (int nPageIndex=0; nPageIndex<nPageCount; nPageIndex++) for (int nPageIndex=0; nPageIndex<nPageCount; nPageIndex++)
SelectPage (nPageIndex); SelectPage (nPageIndex);
UpdateCurrentPage();
} }
@@ -359,34 +360,41 @@ void PageSelector::SetPageSelection (
void PageSelector::UpdateCurrentPage (void) void PageSelector::UpdateCurrentPage (const bool bUpdateOnlyWhenPending)
{ {
// Make the first selected page the current page. if (mnUpdateLockCount > 0)
if (mnUpdateLockCount == 0)
{ {
const sal_Int32 nPageCount (GetPageCount()); mbIsUpdateCurrentPagePending = true;
for (sal_Int32 nIndex=0; nIndex<nPageCount; ++nIndex) return;
}
if ( ! mbIsUpdateCurrentPagePending && bUpdateOnlyWhenPending)
return;
mbIsUpdateCurrentPagePending = false;
// Make the first selected page the current page.
const sal_Int32 nPageCount (GetPageCount());
for (sal_Int32 nIndex=0; nIndex<nPageCount; ++nIndex)
{
SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex));
if (pDescriptor && pDescriptor->HasState(PageDescriptor::ST_Selected))
{ {
SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex)); // Switching the current slide normally sets also the selection
if (pDescriptor && pDescriptor->HasState(PageDescriptor::ST_Selected)) // to just the new current slide. To prevent that here we store
{ // and at the end of this scope restore the current selection.
// Switching the current slide normally sets also the ::boost::shared_ptr<PageSelection> pSelection (GetPageSelection());
// selection to just the new current slide. To prevent that SharedPageDescriptor pRecentSelection (GetMostRecentlySelectedPage());
// here we store and at the end of this scope restore the
// current selection.
::boost::shared_ptr<PageSelection> pSelection (GetPageSelection());
SharedPageDescriptor pRecentSelection (GetMostRecentlySelectedPage());
mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor); mrController.GetCurrentSlideManager()->SwitchCurrentSlide(pDescriptor);
// Restore the selection and prevent a recursive call to // Restore the selection and prevent a recursive call to
// UpdateCurrentPage(). // UpdateCurrentPage().
SetPageSelection(pSelection, false); SetPageSelection(pSelection, false);
// Restore the most recently selected page. Important for // Restore the most recently selected page. Important for
// making the right part of the selection visible. // making the right part of the selection visible.
mpMostRecentlySelectedPage = pRecentSelection; mpMostRecentlySelectedPage = pRecentSelection;
return; return;
}
} }
} }
@@ -412,7 +420,7 @@ PageSelector::UpdateLock::~UpdateLock (void)
--mrSelector.mnUpdateLockCount; --mrSelector.mnUpdateLockCount;
OSL_ASSERT(mrSelector.mnUpdateLockCount >= 0); OSL_ASSERT(mrSelector.mnUpdateLockCount >= 0);
if (mrSelector.mnUpdateLockCount == 0) if (mrSelector.mnUpdateLockCount == 0)
mrSelector.UpdateCurrentPage(); mrSelector.UpdateCurrentPage(true);
} }

View File

@@ -34,6 +34,8 @@
#include "SlideSorter.hxx" #include "SlideSorter.hxx"
#include "SlideSorterViewShell.hxx" #include "SlideSorterViewShell.hxx"
#include "SlsSubstitutionHandler.hxx"
#include "SlsTransferable.hxx"
#include "controller/SlideSorterController.hxx" #include "controller/SlideSorterController.hxx"
#include "controller/SlsPageSelector.hxx" #include "controller/SlsPageSelector.hxx"
#include "controller/SlsFocusManager.hxx" #include "controller/SlsFocusManager.hxx"
@@ -43,6 +45,7 @@
#include "controller/SlsInsertionIndicatorHandler.hxx" #include "controller/SlsInsertionIndicatorHandler.hxx"
#include "controller/SlsSelectionManager.hxx" #include "controller/SlsSelectionManager.hxx"
#include "controller/SlsProperties.hxx" #include "controller/SlsProperties.hxx"
#include "controller/SlsProperties.hxx"
#include "model/SlideSorterModel.hxx" #include "model/SlideSorterModel.hxx"
#include "model/SlsPageDescriptor.hxx" #include "model/SlsPageDescriptor.hxx"
#include "model/SlsPageEnumerationProvider.hxx" #include "model/SlsPageEnumerationProvider.hxx"
@@ -57,6 +60,8 @@
#include "Window.hxx" #include "Window.hxx"
#include "sdpage.hxx" #include "sdpage.hxx"
#include "drawdoc.hxx" #include "drawdoc.hxx"
#include "DrawDocShell.hxx"
#include "sdxfer.hxx"
#include "ViewShell.hxx" #include "ViewShell.hxx"
#include "ViewShellBase.hxx" #include "ViewShellBase.hxx"
#include "FrameView.hxx" #include "FrameView.hxx"
@@ -108,49 +113,6 @@ static const sal_uInt32 MODIFIER_MASK (SHIFT_MODIFIER | CONTROL_MODIF
namespace sd { namespace slidesorter { namespace controller { namespace sd { namespace slidesorter { namespace controller {
/** A SubstitutionHandler object handles the display of a number of selected
slides at the mouse position and the insertion or (with or without
removing the pages at their original position) when the object is
destoyed.
*/
class SelectionFunction::SubstitutionHandler
{
public:
/** Create a substitution display of the currently selected pages and
use the given position as the anchor point.
*/
SubstitutionHandler (
SlideSorter& rSlideSorter,
const model::SharedPageDescriptor& rpHitDescriptor,
const Point& rMouseModelPosition);
~SubstitutionHandler (void);
/** Call this method (for example as reaction to ESC key press) to avoid
processing (ie moving or inserting) the substition when the called
SubstitutionHandler object is destroyed.
*/
void Dispose (void);
/** Move the substitution display by the distance the mouse has
travelled since the last call to this method or to
CreateSubstitution(). The given point becomes the new anchor.
*/
void UpdatePosition (
const Point& rMousePosition,
const bool bAllowAutoScroll = true);
private:
SlideSorter& mrSlideSorter;
model::SharedPageDescriptor mpHitDescriptor;
sal_Int32 mnInsertionIndex;
/** Move the substitution display of the currently selected pages.
*/
void Process (void);
};
class SelectionFunction::MouseMultiSelector class SelectionFunction::MouseMultiSelector
{ {
@@ -241,13 +203,13 @@ namespace {
class SelectionFunction::EventDescriptor class SelectionFunction::EventDescriptor
{ {
public: public:
Point maMousePosition; Point maMousePosition;
Point maMouseModelPosition; Point maMouseModelPosition;
::boost::weak_ptr<model::PageDescriptor> mpHitDescriptor; ::boost::weak_ptr<model::PageDescriptor> mpHitDescriptor;
SdrPage* mpHitPage; SdrPage* mpHitPage;
sal_uInt32 mnEventCode; sal_uInt32 mnEventCode;
sal_Int32 mnButtonIndex; sal_Int32 mnButtonIndex;
InsertionIndicatorHandler::Mode meDragMode;
EventDescriptor ( EventDescriptor (
sal_uInt32 nEventType, sal_uInt32 nEventType,
@@ -260,6 +222,8 @@ public:
const AcceptDropEvent& rEvent, const AcceptDropEvent& rEvent,
SlideSorter& rSlideSorter); SlideSorter& rSlideSorter);
EventDescriptor (const EventDescriptor& rDescriptor); EventDescriptor (const EventDescriptor& rDescriptor);
void SetDragMode (const InsertionIndicatorHandler::Mode eMode);
}; };
@@ -290,6 +254,9 @@ SelectionFunction::SelectionFunction (
aDragTimer.SetTimeoutHdl(LINK(this, SelectionFunction, DragSlideHdl)); aDragTimer.SetTimeoutHdl(LINK(this, SelectionFunction, DragSlideHdl));
} }
SelectionFunction::~SelectionFunction (void) SelectionFunction::~SelectionFunction (void)
{ {
aDragTimer.Stop(); aDragTimer.Stop();
@@ -353,14 +320,18 @@ BOOL SelectionFunction::MouseMove (const MouseEvent& rEvent)
(rEvent.GetButtons() & MOUSE_LEFT)!=0); (rEvent.GetButtons() & MOUSE_LEFT)!=0);
} }
if (rEvent.IsLeaveWindow()) // Detect the mouse leaving the window. When not button is pressed then
// we can call IsLeaveWindow at the event. Otherwise we have to make an
// explicit test.
if (rEvent.IsLeaveWindow()
|| ! Rectangle(Point(0,0),mpWindow->GetOutputSizePixel()).IsInside(aMousePosition))
{ {
// Rectangle aRectangle (Point(0,0),mpWindow->GetOutputSizePixel());
// if ( ! aRectangle.IsInside(aMousePosition)
if (mpSubstitutionHandler) if (mpSubstitutionHandler)
{ {
// Mouse left the window with pressed left button. Make it a drag. // Mouse left the window with pressed left button. Make it a drag.
StartDrag(aMousePosition); StartDrag(aMousePosition, InsertionIndicatorHandler::MoveMode);
mpSubstitutionHandler->Hide();
mpSubstitutionHandler.reset();
} }
mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor()); mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor());
} }
@@ -404,18 +375,59 @@ BOOL SelectionFunction::MouseButtonUp (const MouseEvent& rEvent)
void SelectionFunction::MouseDragged (const AcceptDropEvent& rEvent) void SelectionFunction::MouseDragged (const AcceptDropEvent& rEvent)
{ {
if (rEvent.mbLeaving)
{
if (mpSubstitutionHandler)
{
// Disconnect the substitution handler from this selection function.
mpSubstitutionHandler->Hide();
mpSubstitutionHandler->SetTargetSlideSorter();
mpSubstitutionHandler.reset();
}
}
else if ( ! mpSubstitutionHandler)
{
const SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
const Transferable* pSlideSorterTransferable
= dynamic_cast<const Transferable*>(pDragTransferable);
if (pSlideSorterTransferable != NULL)
{
// Connect the substitution handler to this selection function.
mpSubstitutionHandler = pSlideSorterTransferable->GetSubstitutionHandler();
if (mpSubstitutionHandler)
{
mpSubstitutionHandler->SetTargetSlideSorter(
&mrSlideSorter,
rEvent.maPosPixel,
InsertionIndicatorHandler::GetModeFromDndAction(rEvent.mnAction),
pSlideSorterTransferable->GetView() == &mrSlideSorter.GetView());
mpSubstitutionHandler->Show();
}
}
else
mpSubstitutionHandler.reset(
new SubstitutionHandler(
mrSlideSorter,
mrSlideSorter.GetController().GetPageAt(rEvent.maPosPixel),
rEvent.maPosPixel));
}
// 1. Compute some frequently used values relating to the event. // 1. Compute some frequently used values relating to the event.
::std::auto_ptr<EventDescriptor> pEventDescriptor ( ::std::auto_ptr<EventDescriptor> pEventDescriptor (
new EventDescriptor(rEvent, mrSlideSorter)); new EventDescriptor(rEvent, mrSlideSorter));
// 2. Detect whether we are dragging pages or dragging a selection rectangle. // 2. Detect whether we are dragging pages or dragging a selection rectangle.
view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay()); view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
if (rOverlay.GetSubstitutionOverlay()->IsVisible()) if (mpSubstitutionHandler)
pEventDescriptor->mnEventCode |= SUBSTITUTION_VISIBLE; pEventDescriptor->mnEventCode |= SUBSTITUTION_VISIBLE;
if (mpMouseMultiSelector) if (mpMouseMultiSelector)
pEventDescriptor->mnEventCode |= RECTANGLE_VISIBLE; pEventDescriptor->mnEventCode |= RECTANGLE_VISIBLE;
// 3. Process the event. // 3. Set the drag mode.
pEventDescriptor->SetDragMode(
InsertionIndicatorHandler::GetModeFromDndAction(rEvent.mnAction));
// 4. Process the event.
EventPreprocessing(*pEventDescriptor); EventPreprocessing(*pEventDescriptor);
if ( ! EventProcessing(*pEventDescriptor)) if ( ! EventProcessing(*pEventDescriptor))
{ {
@@ -427,6 +439,27 @@ void SelectionFunction::MouseDragged (const AcceptDropEvent& rEvent)
void SelectionFunction::NotifyDragFinished (void)
{
if (mpSubstitutionHandler)
{
mpSubstitutionHandler->Dispose();
mpSubstitutionHandler.reset();
}
mrController.GetInsertionIndicatorHandler()->End();
}
::boost::shared_ptr<SubstitutionHandler> SelectionFunction::GetSubstitutionHandler (void) const
{
return mpSubstitutionHandler;
}
BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent) BOOL SelectionFunction::KeyInput (const KeyEvent& rEvent)
{ {
PageSelector::UpdateLock aLock (mrSlideSorter); PageSelector::UpdateLock aLock (mrSlideSorter);
@@ -717,14 +750,16 @@ void SelectionFunction::StartDragTimer (void)
IMPL_LINK( SelectionFunction, DragSlideHdl, Timer*, EMPTYARG ) IMPL_LINK( SelectionFunction, DragSlideHdl, Timer*, EMPTYARG )
{ {
StartDrag(aMDPos); StartDrag(aMDPos, InsertionIndicatorHandler::MoveMode);
return 0; return 0;
} }
void SelectionFunction::StartDrag (const Point& rMousePosition) void SelectionFunction::StartDrag (
const Point& rMousePosition,
const InsertionIndicatorHandler::Mode eMode)
{ {
if (mbPageHit if (mbPageHit
&& ! mrSlideSorter.GetProperties()->IsUIReadOnly()) && ! mrSlideSorter.GetProperties()->IsUIReadOnly())
@@ -736,7 +771,9 @@ void SelectionFunction::StartDrag (const Point& rMousePosition)
mrSlideSorter.GetController().GetPageAt(rMousePosition), mrSlideSorter.GetController().GetPageAt(rMousePosition),
rMousePosition)); rMousePosition));
else else
mpSubstitutionHandler->UpdatePosition(rMousePosition); mpSubstitutionHandler->UpdatePosition(
rMousePosition,
eMode);
mbPageHit = false; mbPageHit = false;
mpWindow->ReleaseMouse(); mpWindow->ReleaseMouse();
@@ -1053,16 +1090,21 @@ bool SelectionFunction::EventProcessing (const EventDescriptor& rDescriptor)
switch (rDescriptor.mnEventCode & (SUBSTITUTION_VISIBLE | RECTANGLE_VISIBLE)) switch (rDescriptor.mnEventCode & (SUBSTITUTION_VISIBLE | RECTANGLE_VISIBLE))
{ {
case SUBSTITUTION_VISIBLE: case SUBSTITUTION_VISIBLE:
OSL_ASSERT(mpSubstitutionHandler);
// The substitution is visible. Handle events accordingly. // The substitution is visible. Handle events accordingly.
if (Match(rDescriptor.mnEventCode, MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK)) if (Match(rDescriptor.mnEventCode, MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK))
{ {
if ((rDescriptor.mnEventCode & CONTROL_MODIFIER) != 0) if ((rDescriptor.mnEventCode & CONTROL_MODIFIER) != 0)
StartDrag(rDescriptor.maMousePosition); StartDrag(rDescriptor.maMousePosition, InsertionIndicatorHandler::CopyMode);
mpSubstitutionHandler->UpdatePosition(rDescriptor.maMousePosition); mpSubstitutionHandler->UpdatePosition(
rDescriptor.maMousePosition,
rDescriptor.meDragMode);
} }
else if (Match(rDescriptor.mnEventCode, MOUSE_DRAG)) else if (Match(rDescriptor.mnEventCode, MOUSE_DRAG))
{ {
mpSubstitutionHandler->UpdatePosition(rDescriptor.maMousePosition); mpSubstitutionHandler->UpdatePosition(
rDescriptor.maMousePosition,
rDescriptor.meDragMode);
} }
else if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON)) else if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON))
{ {
@@ -1395,7 +1437,8 @@ SelectionFunction::EventDescriptor::EventDescriptor (
mpHitDescriptor(), mpHitDescriptor(),
mpHitPage(), mpHitPage(),
mnEventCode(0), mnEventCode(0),
mnButtonIndex(-1) mnButtonIndex(-1),
meDragMode(InsertionIndicatorHandler::MoveMode)
{ {
model::SharedPageDescriptor pHitDescriptor ( model::SharedPageDescriptor pHitDescriptor (
rSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor()); rSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor());
@@ -1418,7 +1461,8 @@ SelectionFunction::EventDescriptor::EventDescriptor (
mpHitDescriptor(), mpHitDescriptor(),
mpHitPage(), mpHitPage(),
mnEventCode(MOUSE_DRAG), mnEventCode(MOUSE_DRAG),
mnButtonIndex(-1) mnButtonIndex(-1),
meDragMode(InsertionIndicatorHandler::MoveMode)
{ {
SharedSdWindow pWindow (rSlideSorter.GetContentWindow()); SharedSdWindow pWindow (rSlideSorter.GetContentWindow());
@@ -1441,132 +1485,17 @@ SelectionFunction::EventDescriptor::EventDescriptor (const EventDescriptor& rDes
mpHitDescriptor(rDescriptor.mpHitDescriptor), mpHitDescriptor(rDescriptor.mpHitDescriptor),
mpHitPage(rDescriptor.mpHitPage), mpHitPage(rDescriptor.mpHitPage),
mnEventCode(rDescriptor.mnEventCode), mnEventCode(rDescriptor.mnEventCode),
mnButtonIndex(rDescriptor.mnButtonIndex) mnButtonIndex(rDescriptor.mnButtonIndex),
meDragMode(InsertionIndicatorHandler::MoveMode)
{ {
} }
//===== SubstitutionHandler =================================================== void SelectionFunction::EventDescriptor::SetDragMode (const InsertionIndicatorHandler::Mode eMode)
SelectionFunction::SubstitutionHandler::SubstitutionHandler (
SlideSorter& rSlideSorter,
const model::SharedPageDescriptor& rpHitDescriptor,
const Point& rMouseModelPosition)
: mrSlideSorter(rSlideSorter),
mpHitDescriptor(rpHitDescriptor),
mnInsertionIndex(-1)
{ {
mnInsertionIndex = -1; meDragMode = eMode;
// No Drag-and-Drop for master pages.
if (mrSlideSorter.GetModel().GetEditMode() != EM_PAGE)
return;
if (mrSlideSorter.GetProperties()->IsUIReadOnly())
return;
view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
if ( ! rOverlay.GetSubstitutionOverlay()->IsVisible())
{
// Show a new substitution for the selected page objects.
model::PageEnumeration aSelectedPages(
model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
mrSlideSorter.GetModel()));
rOverlay.GetSubstitutionOverlay()->Create(
aSelectedPages,
rMouseModelPosition,
mpHitDescriptor);
rOverlay.GetSubstitutionOverlay()->SetIsVisible(true);
mrSlideSorter.GetController().GetInsertionIndicatorHandler()->Start(rMouseModelPosition);
}
}
SelectionFunction::SubstitutionHandler::~SubstitutionHandler (void)
{
Process();
view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
rOverlay.GetSubstitutionOverlay()->SetIsVisible(false);
rOverlay.GetSubstitutionOverlay()->Clear();
mrSlideSorter.GetController().GetInsertionIndicatorHandler()->End();
mpHitDescriptor.reset();
}
void SelectionFunction::SubstitutionHandler::Dispose (void)
{
mnInsertionIndex = -1;
}
void SelectionFunction::SubstitutionHandler::UpdatePosition (
const Point& rMousePosition,
const bool bAllowAutoScroll)
{
if (mrSlideSorter.GetProperties()->IsUIReadOnly())
return;
// Convert window coordinates into model coordinates (we need the
// window coordinates for auto-scrolling because that remains
// constant while scrolling.)
SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition));
if ( ! (bAllowAutoScroll && mrSlideSorter.GetController().GetScrollBarManager().AutoScroll(
rMousePosition,
::boost::bind(
&SelectionFunction::SubstitutionHandler::UpdatePosition,
this,
rMousePosition,
false))))
{
view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
// Move the existing substitution to the new position.
rOverlay.GetSubstitutionOverlay()->SetPosition(aMouseModelPosition);
mrSlideSorter.GetController().GetInsertionIndicatorHandler()->UpdatePosition(
aMouseModelPosition);
// Remember the new insertion index.
if (mrSlideSorter.GetController().GetInsertionIndicatorHandler()->IsInsertionTrivial())
mnInsertionIndex = -1;
else
mnInsertionIndex = mrSlideSorter.GetController().GetInsertionIndicatorHandler()
->GetInsertionPageIndex();
}
}
void SelectionFunction::SubstitutionHandler::Process (void)
{
if (mrSlideSorter.GetProperties()->IsUIReadOnly())
return;
if (mnInsertionIndex >= 0)
{
// Tell the model to move the selected pages behind the one with the
// index mnInsertionIndex which first has to transformed into an index
// understandable by the document.
USHORT nDocumentIndex = (USHORT)mnInsertionIndex-1;
mrSlideSorter.GetController().GetSelectionManager()->MoveSelectedPages(nDocumentIndex);
ViewShell* pViewShell = mrSlideSorter.GetViewShell();
if (pViewShell != NULL)
pViewShell->GetViewFrame()->GetBindings().Invalidate(SID_STATUS_PAGE);
}
} }
@@ -1849,11 +1778,14 @@ void RangeSelector::UpdateSelection (void)
{ {
view::SlideSorterView::DrawLock aLock (mrSlideSorter); view::SlideSorterView::DrawLock aLock (mrSlideSorter);
model::SlideSorterModel& rModel (mrSlideSorter.GetModel());
const sal_Int32 nPageCount (rModel.GetPageCount());
const sal_Int32 nIndexUnderMouse ( const sal_Int32 nIndexUnderMouse (
mrSlideSorter.GetView().GetLayouter().GetIndexAtPoint ( mrSlideSorter.GetView().GetLayouter().GetIndexAtPoint (
maSecondCorner, maSecondCorner,
false)); false));
if (nIndexUnderMouse >= 0) if (nIndexUnderMouse>=0 && nIndexUnderMouse<nPageCount)
{ {
if (mnAnchorIndex < 0) if (mnAnchorIndex < 0)
mnAnchorIndex = nIndexUnderMouse; mnAnchorIndex = nIndexUnderMouse;
@@ -1862,8 +1794,7 @@ void RangeSelector::UpdateSelection (void)
Range aRange (mnAnchorIndex, mnSecondIndex); Range aRange (mnAnchorIndex, mnSecondIndex);
aRange.Justify(); aRange.Justify();
model::SlideSorterModel& rModel (mrSlideSorter.GetModel()); for (sal_Int32 nIndex=0; nIndex<nPageCount; ++nIndex)
for (sal_Int32 nIndex=0,nCount(rModel.GetPageCount()); nIndex<nCount; ++nIndex)
{ {
model::SharedPageDescriptor pDescriptor (rModel.GetPageDescriptor(nIndex)); model::SharedPageDescriptor pDescriptor (rModel.GetPageDescriptor(nIndex));

View File

@@ -0,0 +1,240 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: SlsSelectionFunction.cxx,v $
* $Revision: 1.37 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#include "precompiled_sd.hxx"
#include "SlsSubstitutionHandler.hxx"
#include "SlideSorter.hxx"
#include "model/SlideSorterModel.hxx"
#include "model/SlsPageEnumerationProvider.hxx"
#include "view/SlideSorterView.hxx"
#include "view/SlsViewOverlay.hxx"
#include "controller/SlideSorterController.hxx"
#include "controller/SlsInsertionIndicatorHandler.hxx"
#include "controller/SlsScrollBarManager.hxx"
#include "controller/SlsProperties.hxx"
#include "controller/SlsSelectionFunction.hxx"
#include "controller/SlsSelectionManager.hxx"
#include "app.hrc"
#include <sfx2/bindings.hxx>
#include <boost/bind.hpp>
namespace sd { namespace slidesorter { namespace controller {
SubstitutionHandler::SubstitutionHandler (
SlideSorter& rSlideSorter,
const model::SharedPageDescriptor& rpHitDescriptor,
const Point& rMouseModelPosition)
: mpTargetSlideSorter(&rSlideSorter),
mpHitDescriptor(rpHitDescriptor),
mnInsertionIndex(-1)
{
// No Drag-and-Drop for master pages.
if (rSlideSorter.GetModel().GetEditMode() != EM_PAGE)
return;
view::ViewOverlay& rOverlay (rSlideSorter.GetView().GetOverlay());
if ( ! rOverlay.GetSubstitutionOverlay()->IsVisible())
{
// Show a new substitution for the selected page objects.
model::PageEnumeration aSelectedPages(
model::PageEnumerationProvider::CreateSelectedPagesEnumeration(
rSlideSorter.GetModel()));
rOverlay.GetSubstitutionOverlay()->Create(
aSelectedPages,
rMouseModelPosition,
mpHitDescriptor);
rOverlay.GetSubstitutionOverlay()->SetIsVisible(true);
rSlideSorter.GetController().GetInsertionIndicatorHandler()->Start(
rMouseModelPosition,
InsertionIndicatorHandler::MoveMode,
true);
}
}
SubstitutionHandler::~SubstitutionHandler (void)
{
if (mpTargetSlideSorter != NULL)
mpTargetSlideSorter->GetController().GetScrollBarManager().StopAutoScroll();
Process();
if (mpTargetSlideSorter != NULL)
{
view::ViewOverlay& rOverlay (mpTargetSlideSorter->GetView().GetOverlay());
rOverlay.GetSubstitutionOverlay()->SetIsVisible(false);
rOverlay.GetSubstitutionOverlay()->Clear();
mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->End();
}
mpHitDescriptor.reset();
}
void SubstitutionHandler::Dispose (void)
{
mnInsertionIndex = -1;
}
void SubstitutionHandler::UpdatePosition (
const Point& rMousePosition,
const InsertionIndicatorHandler::Mode eMode,
const bool bAllowAutoScroll)
{
if (mpTargetSlideSorter == NULL)
return;
if (mpTargetSlideSorter->GetProperties()->IsUIReadOnly())
return;
// Convert window coordinates into model coordinates (we need the
// window coordinates for auto-scrolling because that remains
// constant while scrolling.)
SharedSdWindow pWindow (mpTargetSlideSorter->GetContentWindow());
const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition));
if ( ! (bAllowAutoScroll
&& mpTargetSlideSorter->GetController().GetScrollBarManager().AutoScroll(
rMousePosition,
::boost::bind(
&SubstitutionHandler::UpdatePosition,
this,
rMousePosition,
eMode,
false))))
{
view::ViewOverlay& rOverlay (mpTargetSlideSorter->GetView().GetOverlay());
// Move the existing substitution to the new position.
rOverlay.GetSubstitutionOverlay()->SetPosition(aMouseModelPosition);
mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->UpdatePosition(
aMouseModelPosition,
eMode);
// Remember the new insertion index.
if (mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->IsInsertionTrivial(eMode))
mnInsertionIndex = -1;
else
mnInsertionIndex = mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()
->GetInsertionPageIndex();
}
}
void SubstitutionHandler::Process (void)
{
if (mpTargetSlideSorter == NULL)
return;
if (mpTargetSlideSorter->GetProperties()->IsUIReadOnly())
return;
if (mnInsertionIndex >= 0)
{
// Tell the model to move the selected pages behind the one with the
// index mnInsertionIndex which first has to transformed into an index
// understandable by the document.
USHORT nDocumentIndex = (USHORT)mnInsertionIndex-1;
mpTargetSlideSorter->GetController().GetSelectionManager()->MoveSelectedPages(nDocumentIndex);
ViewShell* pViewShell = mpTargetSlideSorter->GetViewShell();
if (pViewShell != NULL)
pViewShell->GetViewFrame()->GetBindings().Invalidate(SID_STATUS_PAGE);
}
}
void SubstitutionHandler::Show (void)
{
if (mpTargetSlideSorter != NULL)
{
view::ViewOverlay& rOverlay (mpTargetSlideSorter->GetView().GetOverlay());
rOverlay.GetSubstitutionOverlay()->SetIsVisible(true);
}
}
void SubstitutionHandler::Hide (void)
{
if (mpTargetSlideSorter != NULL)
{
view::ViewOverlay& rOverlay (mpTargetSlideSorter->GetView().GetOverlay());
rOverlay.GetSubstitutionOverlay()->SetIsVisible(false);
}
}
void SubstitutionHandler::SetTargetSlideSorter (
SlideSorter* pSlideSorter,
const Point aMousePosition,
const InsertionIndicatorHandler::Mode eMode,
const bool bIsOverSourceView)
{
if (mpTargetSlideSorter != NULL)
{
mpOverlayState = mpTargetSlideSorter->GetView().GetOverlay().GetSubstitutionOverlay()
->GetInternalState();
mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->End();
}
mpTargetSlideSorter = pSlideSorter;
if (mpTargetSlideSorter != NULL)
{
mpTargetSlideSorter->GetView().GetOverlay().GetSubstitutionOverlay()->SetInternalState(
mpOverlayState);
mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler()->Start(
aMousePosition,
eMode,
bIsOverSourceView);
}
}
} } } // end of namespace ::sd::slidesorter::controller

View File

@@ -0,0 +1,104 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: SlsSelectionFunction.cxx,v $
* $Revision: 1.37 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef SD_SLIDESORTER_SUBSTITUTION_HANDLER_HXX
#define SD_SLIDESORTER_SUBSTITUTION_HANDLER_HXX
#include <tools/gen.hxx>
#include "model/SlsSharedPageDescriptor.hxx"
#include "view/SlsViewOverlay.hxx"
#include "controller/SlsInsertionIndicatorHandler.hxx"
namespace sd { namespace slidesorter {
class SlideSorter;
} }
namespace sd { namespace slidesorter { namespace controller {
/** A SubstitutionHandler object handles the display of a number of selected
slides at the mouse position and the insertion or (with or without
removing the pages at their original position) when the object is
destoyed.
*/
class SubstitutionHandler
{
public:
/** Create a substitution display of the currently selected pages and
use the given position as the anchor point.
*/
SubstitutionHandler (
SlideSorter& rSlideSorter,
const model::SharedPageDescriptor& rpHitDescriptor,
const Point& rMouseModelPosition);
~SubstitutionHandler (void);
/** Call this method (for example as reaction to ESC key press) to avoid
processing (ie moving or inserting) the substition when the called
SubstitutionHandler object is destroyed.
*/
void Dispose (void);
/** Move the substitution display by the distance the mouse has
travelled since the last call to this method or to
CreateSubstitution(). The given point becomes the new anchor.
*/
void UpdatePosition (
const Point& rMousePosition,
const InsertionIndicatorHandler::Mode eMode,
const bool bAllowAutoScroll = true);
void Show (void);
void Hide (void);
void SetTargetSlideSorter (
SlideSorter* pSlideSorter = NULL,
const Point aMousePosition = Point(0,0),
const InsertionIndicatorHandler::Mode eMode = InsertionIndicatorHandler::UnknownMode,
const bool bIsOverSourceView = false);
private:
SlideSorter* mpTargetSlideSorter;
view::SubstitutionOverlay::SharedInternalState mpOverlayState;
model::SharedPageDescriptor mpHitDescriptor;
sal_Int32 mnInsertionIndex;
/** Move the substitution display of the currently selected pages.
*/
void Process (void);
};
} } } // end of namespace ::sd::slidesorter::controller
#endif

View File

@@ -42,9 +42,11 @@ Transferable::Transferable (
SdDrawDocument* pSrcDoc, SdDrawDocument* pSrcDoc,
::sd::View* pWorkView, ::sd::View* pWorkView,
BOOL bInitOnGetData, BOOL bInitOnGetData,
SlideSorterViewShell* pViewShell) SlideSorterViewShell* pViewShell,
const ::boost::shared_ptr<SubstitutionHandler>& rpSubstitutionHandler)
: SdTransferable (pSrcDoc, pWorkView, bInitOnGetData), : SdTransferable (pSrcDoc, pWorkView, bInitOnGetData),
mpViewShell(pViewShell) mpViewShell(pViewShell),
mpSubstitutionHandler(rpSubstitutionHandler)
{ {
if (mpViewShell != NULL) if (mpViewShell != NULL)
StartListening(*mpViewShell); StartListening(*mpViewShell);
@@ -52,6 +54,7 @@ Transferable::Transferable (
Transferable::~Transferable (void) Transferable::~Transferable (void)
{ {
if (mpViewShell != NULL) if (mpViewShell != NULL)
@@ -65,6 +68,7 @@ void Transferable::DragFinished (sal_Int8 nDropAction)
{ {
if (mpViewShell != NULL) if (mpViewShell != NULL)
mpViewShell->DragFinished(nDropAction); mpViewShell->DragFinished(nDropAction);
mpSubstitutionHandler.reset();
} }
@@ -92,4 +96,11 @@ void Transferable::Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint)
::boost::shared_ptr<SubstitutionHandler> Transferable::GetSubstitutionHandler (void) const
{
return mpSubstitutionHandler;
}
} } } // end of namespace ::sd::slidesorter::controller } } } // end of namespace ::sd::slidesorter::controller

View File

@@ -45,6 +45,9 @@ namespace sd
namespace sd { namespace slidesorter { namespace controller { namespace sd { namespace slidesorter { namespace controller {
class SubstitutionHandler;
/** This class exists to have DragFinished call the correct object: the /** This class exists to have DragFinished call the correct object: the
SlideSorterViewShell instead of the old SlideView. SlideSorterViewShell instead of the old SlideView.
*/ */
@@ -56,14 +59,18 @@ public:
SdDrawDocument* pSrcDoc, SdDrawDocument* pSrcDoc,
::sd::View* pWorkView, ::sd::View* pWorkView,
BOOL bInitOnGetData, BOOL bInitOnGetData,
SlideSorterViewShell* pViewShell); SlideSorterViewShell* pViewShell,
const ::boost::shared_ptr<SubstitutionHandler>& rpSubstitutionHandler);
virtual ~Transferable (void); virtual ~Transferable (void);
virtual void DragFinished (sal_Int8 nDropAction); virtual void DragFinished (sal_Int8 nDropAction);
::boost::shared_ptr<SubstitutionHandler> GetSubstitutionHandler (void) const;
private: private:
SlideSorterViewShell* mpViewShell; SlideSorterViewShell* mpViewShell;
::boost::shared_ptr<SubstitutionHandler> mpSubstitutionHandler;
virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint); virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint);
}; };

View File

@@ -62,11 +62,9 @@ SLOFILES = \
$(SLO)$/SlsSelectionFunction.obj \ $(SLO)$/SlsSelectionFunction.obj \
$(SLO)$/SlsSelectionManager.obj \ $(SLO)$/SlsSelectionManager.obj \
$(SLO)$/SlsSlotManager.obj \ $(SLO)$/SlsSlotManager.obj \
$(SLO)$/SlsSubstitutionHandler.obj \
$(SLO)$/SlsTransferable.obj $(SLO)$/SlsTransferable.obj
EXCEPTIONSFILES= \
$(SLO)$/SlideSorterController.obj
# --- Tagets ------------------------------------------------------- # --- Tagets -------------------------------------------------------
.INCLUDE : target.mk .INCLUDE : target.mk

View File

@@ -68,6 +68,7 @@ class InsertionIndicatorHandler;
class Listener; class Listener;
class PageSelector; class PageSelector;
class ScrollBarManager; class ScrollBarManager;
class SelectionFunction;
class SelectionManager; class SelectionManager;
class SlotManager; class SlotManager;
@@ -207,6 +208,12 @@ public:
*/ */
virtual FunctionReference CreateSelectionFunction (SfxRequest& rRequest); virtual FunctionReference CreateSelectionFunction (SfxRequest& rRequest);
/** When the current function of the view shell is the slide sorter
selection function then return a reference to it. Otherwise return
an empty reference.
*/
::rtl::Reference<SelectionFunction> GetCurrentSelectionFunction (void);
/** Prepare for a change of the edit mode. Depending on the current /** Prepare for a change of the edit mode. Depending on the current
edit mode we may save the selection so that it can be restored when edit mode we may save the selection so that it can be restored when
later changing back to the current edit mode. later changing back to the current edit mode.

View File

@@ -52,13 +52,24 @@ public:
InsertionIndicatorHandler (SlideSorter& rSlideSorter); InsertionIndicatorHandler (SlideSorter& rSlideSorter);
~InsertionIndicatorHandler (void); ~InsertionIndicatorHandler (void);
enum Mode { CopyMode, MoveMode, UnknownMode };
static Mode GetModeFromDndAction (const sal_Int8 nMode);
/** Activate the insertion marker at the given coordinates. /** Activate the insertion marker at the given coordinates.
*/ */
void Start (const Point& rMouseModelPosition); void Start (
const Point& rMouseModelPosition,
const Mode eMode,
const bool bIsOverSourceView);
/** Set the position of the insertion marker to the given coordinates. /** Set the position of the insertion marker to the given coordinates.
*/ */
void UpdatePosition (const Point& rMouseModelPosition); void UpdatePosition (
const Point& rMouseModelPosition,
const Mode eMode);
void UpdatePosition (
const Point& rMouseModelPosition,
const sal_Int8 nDndAction);
/** Deactivate the insertion marker. /** Deactivate the insertion marker.
*/ */
@@ -73,12 +84,13 @@ public:
*/ */
sal_Int32 GetInsertionPageIndex (void) const; sal_Int32 GetInsertionPageIndex (void) const;
/** Determine whether moving the current selection to the current /** Determine whether moving the current selection to the current
position of the insertion marker would alter the document. This position of the insertion marker would alter the document. This
would be the case when the selection is not consecutive or would be would be the case when the selection is not consecutive or would be
moved to a position outside and not adjacent to the selection. moved to a position outside and not adjacent to the selection.
*/ */
bool IsInsertionTrivial (void) const; bool IsInsertionTrivial (const Mode eMode) const;
private: private:
SlideSorter& mrSlideSorter; SlideSorter& mrSlideSorter;
@@ -86,11 +98,15 @@ private:
::boost::shared_ptr<view::InsertionIndicatorOverlay> mpInsertionIndicatorOverlay; ::boost::shared_ptr<view::InsertionIndicatorOverlay> mpInsertionIndicatorOverlay;
sal_Int32 mnInsertionIndex; sal_Int32 mnInsertionIndex;
bool mbIsBeforePage; bool mbIsBeforePage;
Mode meMode;
bool mbIsInsertionTrivial; bool mbIsInsertionTrivial;
bool mbIsActive; bool mbIsActive;
bool mbIsReadOnly; bool mbIsReadOnly;
bool mbIsOverSourceView;
void SetPosition (const Point& rPoint); void SetPosition (
const Point& rPoint,
const Mode eMode);
::boost::shared_ptr<view::InsertAnimator> GetInsertAnimator (void); ::boost::shared_ptr<view::InsertAnimator> GetInsertAnimator (void);
}; };

View File

@@ -201,9 +201,10 @@ private:
model::SharedPageDescriptor mpSelectionAnchor; model::SharedPageDescriptor mpSelectionAnchor;
model::SharedPageDescriptor mpCurrentPage; model::SharedPageDescriptor mpCurrentPage;
sal_Int32 mnUpdateLockCount; sal_Int32 mnUpdateLockCount;
bool mbIsUpdateCurrentPagePending;
void CountSelectedPages (void); void CountSelectedPages (void);
void UpdateCurrentPage (void); void UpdateCurrentPage (const bool bUpdateOnlyWhenPending = false);
}; };
} } } // end of namespace ::sd::slidesorter::controller } } } // end of namespace ::sd::slidesorter::controller

View File

@@ -33,6 +33,7 @@
#include "model/SlsSharedPageDescriptor.hxx" #include "model/SlsSharedPageDescriptor.hxx"
#include "controller/SlsFocusManager.hxx" #include "controller/SlsFocusManager.hxx"
#include "controller/SlsInsertionIndicatorHandler.hxx"
#include "fupoor.hxx" #include "fupoor.hxx"
#include <svtools/transfer.hxx> #include <svtools/transfer.hxx>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
@@ -51,6 +52,8 @@ class SlideSorter;
namespace sd { namespace slidesorter { namespace controller { namespace sd { namespace slidesorter { namespace controller {
class SlideSorterController; class SlideSorterController;
class SubstitutionHandler;
class SelectionFunction class SelectionFunction
: public FuPoor, : public FuPoor,
@@ -93,6 +96,12 @@ public:
void MouseDragged (const AcceptDropEvent& rEvent); void MouseDragged (const AcceptDropEvent& rEvent);
/** Turn of substitution display and insertion indicator.
*/
void NotifyDragFinished (void);
::boost::shared_ptr<SubstitutionHandler> GetSubstitutionHandler (void) const;
class MouseMultiSelector; class MouseMultiSelector;
protected: protected:
@@ -106,7 +115,6 @@ protected:
virtual ~SelectionFunction(); virtual ~SelectionFunction();
private: private:
class SubstitutionHandler;
class EventDescriptor; class EventDescriptor;
/// Set in MouseButtonDown this flag indicates that a page has been hit. /// Set in MouseButtonDown this flag indicates that a page has been hit.
@@ -127,7 +135,7 @@ private:
*/ */
bool mbProcessingMouseButtonDown; bool mbProcessingMouseButtonDown;
::boost::scoped_ptr<SubstitutionHandler> mpSubstitutionHandler; ::boost::shared_ptr<SubstitutionHandler> mpSubstitutionHandler;
::boost::scoped_ptr<MouseMultiSelector> mpMouseMultiSelector; ::boost::scoped_ptr<MouseMultiSelector> mpMouseMultiSelector;
/** Remember where the left mouse button was pressed. /** Remember where the left mouse button was pressed.
@@ -143,7 +151,9 @@ private:
sal_Int32 mnShiftKeySelectionAnchor; sal_Int32 mnShiftKeySelectionAnchor;
DECL_LINK( DragSlideHdl, Timer* ); DECL_LINK( DragSlideHdl, Timer* );
void StartDrag (const Point& rMousePosition); void StartDrag (
const Point& rMousePosition,
const InsertionIndicatorHandler::Mode eMode);
/** Set the selection to exactly the specified page and also set it as /** Set the selection to exactly the specified page and also set it as
the current page. the current page.

View File

@@ -40,23 +40,12 @@
#include <memory> #include <memory>
#include <boost/enable_shared_from_this.hpp> #include <boost/enable_shared_from_this.hpp>
#include <boost/scoped_ptr.hpp>
class SdPage; class SdPage;
class SdrPage; class SdrPage;
namespace sdr { namespace contact {
class ObjectContact;
} }
namespace sd { namespace slidesorter { namespace view {
class PageObject;
class PageObjectViewObjectContact;
} } }
namespace sd { namespace slidesorter { namespace controller {
class PageObjectFactory;
} } }
namespace sd { namespace slidesorter { namespace model { namespace sd { namespace slidesorter { namespace model {
class SlideRenderer; class SlideRenderer;
@@ -141,6 +130,7 @@ private:
SdPage* mpPage; SdPage* mpPage;
css::uno::Reference<css::drawing::XDrawPage> mxPage; css::uno::Reference<css::drawing::XDrawPage> mxPage;
SdrPage const* mpMasterPage; SdrPage const* mpMasterPage;
/** This index is displayed as page number in the view. It may or may /** This index is displayed as page number in the view. It may or may
not be the actual page index. not be the actual page index.
*/ */

View File

@@ -77,8 +77,7 @@ public:
MouseOverColor, MouseOverColor,
PageNumberBorder, PageNumberBorder,
PageNumberColor, PageNumberColor,
Selection, Selection
PreviewBorder
}; };
ColorData GetColor (const ColorType eType); ColorData GetColor (const ColorType eType);

View File

@@ -126,9 +126,11 @@ public:
*/ */
void Create ( void Create (
model::PageEnumeration& rSelection, model::PageEnumeration& rSelection,
const Point& rPosition, const Point& rAnchor,
const model::SharedPageDescriptor& rpHitDescriptor); const model::SharedPageDescriptor& rpHitDescriptor);
void SetAnchor (const Point& rAnchor);
/** Clear the substitution display. Until the next call of Create() no /** Clear the substitution display. Until the next call of Create() no
substution is painted. substution is painted.
*/ */
@@ -136,7 +138,7 @@ public:
/** Move the substitution display by the given amount of pixels. /** Move the substitution display by the given amount of pixels.
*/ */
void Move (const Point& rOffset); void Move (const Point& rPositionOffset);
void SetPosition (const Point& rPosition); void SetPosition (const Point& rPosition);
Point GetPosition (void) const; Point GetPosition (void) const;
@@ -144,12 +146,19 @@ public:
OutputDevice& rDevice, OutputDevice& rDevice,
const Rectangle& rRepaintArea); const Rectangle& rRepaintArea);
class InternalState;
typedef ::boost::shared_ptr<InternalState> SharedInternalState;
SharedInternalState GetInternalState (void) const;
void SetInternalState (const SharedInternalState& rpState);
protected: protected:
virtual Rectangle GetBoundingBox (void) const; virtual Rectangle GetBoundingBox (void) const;
private: private:
/** The current position can be set by calling SetPosition() or Move().
*/
Point maPosition; Point maPosition;
Point maTranslation;
/** The substitution paints only the page object under the mouse and the /** The substitution paints only the page object under the mouse and the
8-neighborhood around it. It uses different levels of transparency 8-neighborhood around it. It uses different levels of transparency
for the center and the four elements at its sides and the four for the center and the four elements at its sides and the four
@@ -160,16 +169,7 @@ private:
static const sal_Int32 mnSideTransparency; static const sal_Int32 mnSideTransparency;
static const sal_Int32 mnCornerTransparency; static const sal_Int32 mnCornerTransparency;
class ItemDescriptor SharedInternalState mpState;
{
public:
BitmapEx maImage;
Point maLocation;
double mnTransparency;
basegfx::B2DPolygon maShape;
};
::std::vector<ItemDescriptor> maItems;
Rectangle maBoundingBox;
}; };

View File

@@ -39,12 +39,14 @@
#include <svx/svdopage.hxx> #include <svx/svdopage.hxx>
#include <svx/svdpagv.hxx> #include <svx/svdpagv.hxx>
#include <svx/sdr/contact/viewcontact.hxx> #include <svx/sdr/contact/viewcontact.hxx>
#include <svx/sdr/contact/viewobjectcontact.hxx>
using namespace ::com::sun::star::uno; using namespace ::com::sun::star::uno;
using namespace ::com::sun::star; using namespace ::com::sun::star;
namespace sd { namespace slidesorter { namespace model { namespace sd { namespace slidesorter { namespace model {
PageDescriptor::PageDescriptor ( PageDescriptor::PageDescriptor (
const Reference<drawing::XDrawPage>& rxPage, const Reference<drawing::XDrawPage>& rxPage,
SdPage* pPage, SdPage* pPage,
@@ -64,7 +66,7 @@ PageDescriptor::PageDescriptor (
{ {
OSL_ASSERT(mpPage); OSL_ASSERT(mpPage);
OSL_ASSERT(mpPage == SdPage::getImplementation(rxPage)); OSL_ASSERT(mpPage == SdPage::getImplementation(rxPage));
if (mpPage!=NULL && !mpPage->IsMasterPage()) if (mpPage!=NULL && mpPage->TRG_HasMasterPage())
mpMasterPage = &mpPage->TRG_GetMasterPage(); mpMasterPage = &mpPage->TRG_GetMasterPage();
} }
@@ -105,7 +107,7 @@ sal_Int32 PageDescriptor::GetPageIndex (void) const
bool PageDescriptor::UpdateMasterPage (void) bool PageDescriptor::UpdateMasterPage (void)
{ {
const SdrPage* pMaster = NULL; const SdrPage* pMaster = NULL;
if (mpPage!=NULL && !mpPage->IsMasterPage()) if (mpPage!=NULL && mpPage->TRG_HasMasterPage())
pMaster = &mpPage->TRG_GetMasterPage(); pMaster = &mpPage->TRG_GetMasterPage();
if (mpMasterPage != pMaster) if (mpMasterPage != pMaster)
{ {

View File

@@ -601,7 +601,7 @@ void SlideSorterViewShell::ReadFrameViewData (FrameView* pFrameView)
// sorter is displayed in a side pane then we ignore the value // sorter is displayed in a side pane then we ignore the value
// of the frame view and adapt the number of columns // of the frame view and adapt the number of columns
// automatically to the window width. // automatically to the window width.
rView.GetLayouter().SetColumnCount(1,5); rView.GetLayouter().SetColumnCount(1,1);
} }
else else
rView.GetLayouter().SetColumnCount(nSlidesPerRow,nSlidesPerRow); rView.GetLayouter().SetColumnCount(nSlidesPerRow,nSlidesPerRow);

View File

@@ -40,21 +40,21 @@ namespace sd { namespace slidesorter { namespace view {
Layouter::Layouter (const SharedSdWindow& rpWindow) Layouter::Layouter (const SharedSdWindow& rpWindow)
: mpWindow(rpWindow), : mpWindow(rpWindow),
mnRequestedLeftBorder(35), mnRequestedLeftBorder(5),
mnRequestedRightBorder(35), mnRequestedRightBorder(5),
mnRequestedTopBorder(10), mnRequestedTopBorder(5),
mnRequestedBottomBorder(10), mnRequestedBottomBorder(5),
mnLeftBorder(30), mnLeftBorder(5),
mnRightBorder(30), mnRightBorder(5),
mnTopBorder(10), mnTopBorder(5),
mnBottomBorder(10), mnBottomBorder(5),
mnVerticalGap (10), mnVerticalGap (10),
mnHorizontalGap (10), mnHorizontalGap(10),
mnMinimalWidth (100), mnMinimalWidth(100),
mnPreferredWidth (200), mnPreferredWidth(200),
mnMaximalWidth (300), mnMaximalWidth(300),
mnMinimalColumnCount (1), mnMinimalColumnCount(1),
mnMaximalColumnCount (5), mnMaximalColumnCount(1),
mnPageCount(0), mnPageCount(0),
mnColumnCount(1), mnColumnCount(1),
mnRowCount(0), mnRowCount(0),

View File

@@ -43,7 +43,7 @@ namespace {
const static sal_Int32 gnPageNumberOffset = 5; const static sal_Int32 gnPageNumberOffset = 5;
const static sal_Int32 gnPageNumberFrameHorizontalOffset = 2; const static sal_Int32 gnPageNumberFrameHorizontalOffset = 2;
const static sal_Int32 gnPageNumberFrameVerticalOffset = 1; const static sal_Int32 gnPageNumberFrameVerticalOffset = 1;
const static sal_Int32 gnOuterBorderWidth = 6; const static sal_Int32 gnOuterBorderWidth = 5;
const static sal_Int32 gnInfoAreaMinWidth = 26; const static sal_Int32 gnInfoAreaMinWidth = 26;
const static Size gaButtonSize (32,32); const static Size gaButtonSize (32,32);
const static sal_Int32 gnButtonGap (5); const static sal_Int32 gnButtonGap (5);

View File

@@ -580,11 +580,9 @@ Bitmap PageObjectPainter::CreateBackgroundBitmap(
mpShadowPainter->PaintFrame(aBitmapDevice, aFrameBox); mpShadowPainter->PaintFrame(aBitmapDevice, aFrameBox);
// Clear the area where the preview will later be painted. // Clear the area where the preview will later be painted.
/*
aBitmapDevice.SetFillColor(mpTheme->GetColor(Theme::Background)); aBitmapDevice.SetFillColor(mpTheme->GetColor(Theme::Background));
aBitmapDevice.SetLineColor(mpTheme->GetColor(Theme::PreviewBorder)); aBitmapDevice.SetLineColor(mpTheme->GetColor(Theme::Background));
aBitmapDevice.DrawRect(aFrameBox); aBitmapDevice.DrawRect(aBox);
*/
return aBitmapDevice.GetBitmap (Point(0,0),aSize); return aBitmapDevice.GetBitmap (Point(0,0),aSize);
} }

View File

@@ -214,9 +214,6 @@ ColorData Theme::GetColor (const ColorType eType)
case Selection: case Selection:
return StellaBlue; return StellaBlue;
case PreviewBorder:
return 0x000000;
} }
return 0; return 0;
} }

View File

@@ -105,6 +105,41 @@ Rectangle ConvertRectangle (const B2DRectangle& rBox)
namespace sd { namespace slidesorter { namespace view { namespace sd { namespace slidesorter { namespace view {
//===== SubstitutionOverlay::InternalState ====================================
class ItemDescriptor
{
public:
BitmapEx maImage;
Point maLocation;
double mnTransparency;
basegfx::B2DPolygon maShape;
};
class SubstitutionOverlay::InternalState
{
public:
/** The set of items that is displayed as substitution of the selected
pages. Note that the number of items may differ from the number of
selected pages because only the selected pages in the neighborhood
of the anchor page are included.
*/
::std::vector<ItemDescriptor> maItems;
/** Bounding box of all items in maItems at their original location.
*/
Rectangle maBoundingBox;
/** The anchor position of the substitution is the paint that, after
translation, is mapped onto the current position.
*/
Point maAnchor;
};
//===== ViewOverlay ========================================================= //===== ViewOverlay =========================================================
ViewOverlay::ViewOverlay ( ViewOverlay::ViewOverlay (
@@ -293,9 +328,7 @@ SubstitutionOverlay::SubstitutionOverlay (
const sal_Int32 nLayerIndex) const sal_Int32 nLayerIndex)
: OverlayBase(rViewOverlay, nLayerIndex), : OverlayBase(rViewOverlay, nLayerIndex),
maPosition(0,0), maPosition(0,0),
maTranslation(0,0), mpState(new InternalState())
maItems(),
maBoundingBox()
{ {
} }
@@ -311,11 +344,13 @@ SubstitutionOverlay::~SubstitutionOverlay (void)
void SubstitutionOverlay::Create ( void SubstitutionOverlay::Create (
model::PageEnumeration& rSelection, model::PageEnumeration& rSelection,
const Point& rPosition, const Point& rAnchor,
const model::SharedPageDescriptor& rpHitDescriptor) const model::SharedPageDescriptor& rpHitDescriptor)
{ {
maPosition = rPosition; OSL_ASSERT(mpState);
maTranslation = Point(0,0);
mpState->maAnchor = rAnchor;
maPosition = rAnchor;
::boost::shared_ptr<cache::PageCache> pPreviewCache ( ::boost::shared_ptr<cache::PageCache> pPreviewCache (
mrViewOverlay.GetSlideSorter().GetView().GetPreviewCache()); mrViewOverlay.GetSlideSorter().GetView().GetPreviewCache());
@@ -330,7 +365,7 @@ void SubstitutionOverlay::Create (
? rLayouter.GetColumn(rpHitDescriptor->GetPageIndex()) ? rLayouter.GetColumn(rpHitDescriptor->GetPageIndex())
: -1); : -1);
maItems.clear(); mpState->maItems.clear();
while (rSelection.HasMoreElements()) while (rSelection.HasMoreElements())
{ {
model::SharedPageDescriptor pDescriptor (rSelection.GetNextElement()); model::SharedPageDescriptor pDescriptor (rSelection.GetNextElement());
@@ -357,7 +392,7 @@ void SubstitutionOverlay::Create (
} }
const Rectangle aBox (pDescriptor->GetBoundingBox()); const Rectangle aBox (pDescriptor->GetBoundingBox());
maBoundingBox.Union(aBox); mpState->maBoundingBox.Union(aBox);
basegfx::B2DRectangle aB2DBox( basegfx::B2DRectangle aB2DBox(
aBox.Left(), aBox.Left(),
aBox.Top(), aBox.Top(),
@@ -367,19 +402,20 @@ void SubstitutionOverlay::Create (
const Bitmap aBitmap (pPreviewCache->GetPreviewBitmap(pDescriptor->GetPage()).GetBitmap()); const Bitmap aBitmap (pPreviewCache->GetPreviewBitmap(pDescriptor->GetPage()).GetBitmap());
AlphaMask aMask (aBitmap.GetSizePixel()); AlphaMask aMask (aBitmap.GetSizePixel());
aMask.Erase(nTransparency); aMask.Erase(nTransparency);
maItems.push_back(ItemDescriptor()); mpState->maItems.push_back(ItemDescriptor());
maItems.back().maImage = BitmapEx( ItemDescriptor& rNewItem (mpState->maItems.back());
rNewItem.maImage = BitmapEx(
aBitmap, aBitmap,
aMask); aMask);
maItems.back().maLocation = pPageObjectLayouter->GetBoundingBox( rNewItem.maLocation = pPageObjectLayouter->GetBoundingBox(
pDescriptor, pDescriptor,
PageObjectLayouter::Preview, PageObjectLayouter::Preview,
PageObjectLayouter::WindowCoordinateSystem).TopLeft(); PageObjectLayouter::WindowCoordinateSystem).TopLeft();
maItems.back().mnTransparency = nTransparency/255.0; rNewItem.mnTransparency = nTransparency/255.0;
maItems.back().maShape = basegfx::tools::createPolygonFromRect(aB2DBox); rNewItem.maShape = basegfx::tools::createPolygonFromRect(aB2DBox);
} }
SetIsVisible(maItems.size() > 0); SetIsVisible(mpState->maItems.size() > 0);
} }
@@ -388,7 +424,20 @@ void SubstitutionOverlay::Create (
void SubstitutionOverlay::Clear (void) void SubstitutionOverlay::Clear (void)
{ {
SetIsVisible(false); SetIsVisible(false);
maItems.clear(); mpState.reset(new InternalState());
}
void SubstitutionOverlay::SetAnchor (const Point& rAnchor)
{
OSL_ASSERT(mpState);
if (mpState->maAnchor != rAnchor)
{
Invalidator aInvalidator (*this);
mpState->maAnchor = rAnchor;
}
} }
@@ -396,11 +445,11 @@ void SubstitutionOverlay::Clear (void)
void SubstitutionOverlay::Move (const Point& rOffset) void SubstitutionOverlay::Move (const Point& rOffset)
{ {
Invalidator aInvalidator (*this); if (rOffset != Point(0,0))
{
maPosition += rOffset; Invalidator aInvalidator (*this);
maTranslation += rOffset; maPosition += rOffset;
maBoundingBox.Move(rOffset.X(), rOffset.Y()); }
} }
@@ -408,7 +457,11 @@ void SubstitutionOverlay::Move (const Point& rOffset)
void SubstitutionOverlay::SetPosition (const Point& rPosition) void SubstitutionOverlay::SetPosition (const Point& rPosition)
{ {
Move(rPosition - GetPosition()); if (maPosition != rPosition)
{
Invalidator aInvalidator (*this);
maPosition = rPosition;
}
} }
@@ -427,26 +480,28 @@ void SubstitutionOverlay::Paint (
const Rectangle& rRepaintArea) const Rectangle& rRepaintArea)
{ {
(void)rRepaintArea; (void)rRepaintArea;
OSL_ASSERT(mpState);
if ( ! IsVisible()) if ( ! IsVisible())
return; return;
const Point aOffset (maPosition - mpState->maAnchor);
basegfx::B2DHomMatrix aTranslation; basegfx::B2DHomMatrix aTranslation;
aTranslation.translate(maTranslation.X(), maTranslation.Y()); aTranslation.translate(aOffset.X(), aOffset.Y());
rDevice.SetFillColor(Color(AirForceBlue)); rDevice.SetFillColor(Color(AirForceBlue));
rDevice.SetLineColor(); rDevice.SetLineColor();
for (::std::vector<ItemDescriptor>::const_iterator for (::std::vector<ItemDescriptor>::const_iterator
iItem(maItems.begin()), iItem(mpState->maItems.begin()),
iEnd(maItems.end()); iEnd(mpState->maItems.end());
iItem!=iEnd; iItem!=iEnd;
++iItem) ++iItem)
{ {
::basegfx::B2DPolyPolygon aPolygon (iItem->maShape); ::basegfx::B2DPolyPolygon aPolygon (iItem->maShape);
aPolygon.transform(aTranslation); aPolygon.transform(aTranslation);
rDevice.DrawTransparent(aPolygon, iItem->mnTransparency); rDevice.DrawTransparent(aPolygon, iItem->mnTransparency);
rDevice.DrawBitmapEx(iItem->maLocation+maTranslation, iItem->maImage); rDevice.DrawBitmapEx(iItem->maLocation+aOffset, iItem->maImage);
} }
} }
@@ -455,7 +510,28 @@ void SubstitutionOverlay::Paint (
Rectangle SubstitutionOverlay::GetBoundingBox (void) const Rectangle SubstitutionOverlay::GetBoundingBox (void) const
{ {
return maBoundingBox; OSL_ASSERT(mpState);
Rectangle aBox (mpState->maBoundingBox);
aBox.Move(maPosition.X() - mpState->maAnchor.X(), maPosition.Y() - mpState->maAnchor.Y());
return aBox;
}
SubstitutionOverlay::SharedInternalState SubstitutionOverlay::GetInternalState (void) const
{
return mpState;
}
void SubstitutionOverlay::SetInternalState (const SharedInternalState& rpState)
{
if (rpState)
mpState = rpState;
} }