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
// would take place.
GetInsertionIndicatorHandler()->Start(
pWindow->PixelToLogic(rEvent.GetMousePosPixel()));
pWindow->PixelToLogic(rEvent.GetMousePosPixel()),
InsertionIndicatorHandler::MoveMode,
false);
}
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)
{
// 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)
{
if (mrModel.GetPageCount()%2==0)
return;
PageEnumeration aAllPages (PageEnumerationProvider::CreateAllPagesEnumeration(mrModel));
while (aAllPages.HasMoreElements())
{

View File

@ -194,9 +194,15 @@ void Animator::RemoveAnimation (const Animator::AnimationId nId)
maAnimations.erase(iAnimation);
}
// Reset the animation id when we can.
if (maAnimations.empty())
{
// Reset the animation id when we can.
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();
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 (
pDocument,
NULL,
FALSE,
dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell()));
dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell()),
pSubstitutionHandler);
if (bDrag)
SD_MOD()->pTransferDrag = pTransferable;
@ -433,7 +439,9 @@ void Clipboard::StartDrag (
mbUpdateSelectionPending = false;
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)
{
// Hide the substitution display and insertion indicator.
mrSlideSorter.GetView().GetOverlay().GetSubstitutionOverlay()->SetIsVisible(false);
mrSlideSorter.GetController().GetInsertionIndicatorHandler()->End();
::rtl::Reference<SelectionFunction> pFunction (mrController.GetCurrentSelectionFunction());
if (pFunction.is())
pFunction->NotifyDragFinished();
SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
@ -467,7 +476,8 @@ void Clipboard::DragFinished (sal_Int8 nDropAction)
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.
Point aPosition = pTargetWindow->PixelToLogic (rEvent.maPosPixel);
view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
mrController.GetInsertionIndicatorHandler()->UpdatePosition(aPosition);
mrController.GetInsertionIndicatorHandler()->UpdatePosition(
aPosition,
rEvent.maDragEvent.DropAction);
rOverlay.GetSubstitutionOverlay()->SetPosition(aPosition);
// Scroll the window when the mouse reaches the window border.
@ -580,10 +592,10 @@ sal_Int8 Clipboard::ExecuteDrop (
|| ( nXOffset >= 2 && nYOffset >= 2 );
// Get insertion position and then turn off the insertion indicator.
mrController.GetInsertionIndicatorHandler()->UpdatePosition(aEventModelPosition);
mrController.GetInsertionIndicatorHandler()->UpdatePosition(
aEventModelPosition,
rEvent.mnAction);
USHORT nIndex = DetermineInsertPosition(*pDragTransferable);
OSL_TRACE ("Clipboard::AcceptDrop() called for index %d",
nIndex);
mrController.GetInsertionIndicatorHandler()->End();
if (bContinue)
@ -617,6 +629,13 @@ sal_Int8 Clipboard::ExecuteDrop (
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;

View File

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

View File

@ -37,9 +37,11 @@
#include "view/SlsLayouter.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 {
@ -51,8 +53,10 @@ InsertionIndicatorHandler::InsertionIndicatorHandler (SlideSorter& rSlideSorter)
mrSlideSorter.GetView().GetOverlay().GetInsertionIndicatorOverlay()),
mnInsertionIndex(-1),
mbIsBeforePage(false),
meMode(MoveMode),
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)
{
@ -77,15 +84,32 @@ void InsertionIndicatorHandler::Start (const Point& rMouseModelPosition)
if (mbIsReadOnly)
return;
SetPosition(rMouseModelPosition);
SetPosition(rMouseModelPosition, eMode);
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)
return;
@ -93,7 +117,17 @@ void InsertionIndicatorHandler::UpdatePosition (const Point& rMouseModelPosition
if (mbIsReadOnly)
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;
view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter());
@ -183,11 +219,14 @@ void InsertionIndicatorHandler::SetPosition (const Point& rPoint)
nInsertionIndex += 1;
}
if (mnInsertionIndex!=nInsertionIndex || mbIsBeforePage!=bIsBeforePage)
if (mnInsertionIndex!=nInsertionIndex
|| mbIsBeforePage!=bIsBeforePage
|| meMode!=eMode)
{
mnInsertionIndex = nInsertionIndex;
mbIsBeforePage = bIsBeforePage;
mbIsInsertionTrivial = IsInsertionTrivial();
meMode = eMode;
mbIsInsertionTrivial = IsInsertionTrivial(eMode);
mpInsertionIndicatorOverlay->SetLocation(
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
// holes. While we do this we remember the indices of the first and
// 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::view;
namespace sd { namespace slidesorter { namespace controller {
PageSelector::PageSelector (SlideSorter& rSlideSorter)
@ -69,7 +70,8 @@ PageSelector::PageSelector (SlideSorter& rSlideSorter)
mpMostRecentlySelectedPage(),
mpSelectionAnchor(),
mpCurrentPage(),
mnUpdateLockCount(0)
mnUpdateLockCount(0),
mbIsUpdateCurrentPagePending(false)
{
CountSelectedPages ();
}
@ -82,7 +84,6 @@ void PageSelector::SelectAllPages (void)
int nPageCount = mrModel.GetPageCount();
for (int nPageIndex=0; nPageIndex<nPageCount; 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());
for (sal_Int32 nIndex=0; nIndex<nPageCount; ++nIndex)
mbIsUpdateCurrentPagePending = true;
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));
if (pDescriptor && pDescriptor->HasState(PageDescriptor::ST_Selected))
{
// Switching the current slide normally sets also the
// selection to just the new current slide. To prevent that
// here we store and at the end of this scope restore the
// current selection.
::boost::shared_ptr<PageSelection> pSelection (GetPageSelection());
SharedPageDescriptor pRecentSelection (GetMostRecentlySelectedPage());
// Switching the current slide normally sets also the selection
// to just the new current slide. To prevent that 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
// UpdateCurrentPage().
SetPageSelection(pSelection, false);
// Restore the most recently selected page. Important for
// making the right part of the selection visible.
mpMostRecentlySelectedPage = pRecentSelection;
return;
}
// Restore the selection and prevent a recursive call to
// UpdateCurrentPage().
SetPageSelection(pSelection, false);
// Restore the most recently selected page. Important for
// making the right part of the selection visible.
mpMostRecentlySelectedPage = pRecentSelection;
return;
}
}
@ -412,7 +420,7 @@ PageSelector::UpdateLock::~UpdateLock (void)
--mrSelector.mnUpdateLockCount;
OSL_ASSERT(mrSelector.mnUpdateLockCount >= 0);
if (mrSelector.mnUpdateLockCount == 0)
mrSelector.UpdateCurrentPage();
mrSelector.UpdateCurrentPage(true);
}

View File

@ -34,6 +34,8 @@
#include "SlideSorter.hxx"
#include "SlideSorterViewShell.hxx"
#include "SlsSubstitutionHandler.hxx"
#include "SlsTransferable.hxx"
#include "controller/SlideSorterController.hxx"
#include "controller/SlsPageSelector.hxx"
#include "controller/SlsFocusManager.hxx"
@ -43,6 +45,7 @@
#include "controller/SlsInsertionIndicatorHandler.hxx"
#include "controller/SlsSelectionManager.hxx"
#include "controller/SlsProperties.hxx"
#include "controller/SlsProperties.hxx"
#include "model/SlideSorterModel.hxx"
#include "model/SlsPageDescriptor.hxx"
#include "model/SlsPageEnumerationProvider.hxx"
@ -57,6 +60,8 @@
#include "Window.hxx"
#include "sdpage.hxx"
#include "drawdoc.hxx"
#include "DrawDocShell.hxx"
#include "sdxfer.hxx"
#include "ViewShell.hxx"
#include "ViewShellBase.hxx"
#include "FrameView.hxx"
@ -108,49 +113,6 @@ static const sal_uInt32 MODIFIER_MASK (SHIFT_MODIFIER | CONTROL_MODIF
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
{
@ -241,13 +203,13 @@ namespace {
class SelectionFunction::EventDescriptor
{
public:
Point maMousePosition;
Point maMouseModelPosition;
::boost::weak_ptr<model::PageDescriptor> mpHitDescriptor;
SdrPage* mpHitPage;
sal_uInt32 mnEventCode;
sal_Int32 mnButtonIndex;
InsertionIndicatorHandler::Mode meDragMode;
EventDescriptor (
sal_uInt32 nEventType,
@ -260,6 +222,8 @@ public:
const AcceptDropEvent& rEvent,
SlideSorter& rSlideSorter);
EventDescriptor (const EventDescriptor& rDescriptor);
void SetDragMode (const InsertionIndicatorHandler::Mode eMode);
};
@ -290,6 +254,9 @@ SelectionFunction::SelectionFunction (
aDragTimer.SetTimeoutHdl(LINK(this, SelectionFunction, DragSlideHdl));
}
SelectionFunction::~SelectionFunction (void)
{
aDragTimer.Stop();
@ -353,14 +320,18 @@ BOOL SelectionFunction::MouseMove (const MouseEvent& rEvent)
(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)
{
// 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());
}
@ -404,18 +375,59 @@ BOOL SelectionFunction::MouseButtonUp (const MouseEvent& 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.
::std::auto_ptr<EventDescriptor> pEventDescriptor (
new EventDescriptor(rEvent, mrSlideSorter));
// 2. Detect whether we are dragging pages or dragging a selection rectangle.
view::ViewOverlay& rOverlay (mrSlideSorter.GetView().GetOverlay());
if (rOverlay.GetSubstitutionOverlay()->IsVisible())
if (mpSubstitutionHandler)
pEventDescriptor->mnEventCode |= SUBSTITUTION_VISIBLE;
if (mpMouseMultiSelector)
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);
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)
{
PageSelector::UpdateLock aLock (mrSlideSorter);
@ -717,14 +750,16 @@ void SelectionFunction::StartDragTimer (void)
IMPL_LINK( SelectionFunction, DragSlideHdl, Timer*, EMPTYARG )
{
StartDrag(aMDPos);
StartDrag(aMDPos, InsertionIndicatorHandler::MoveMode);
return 0;
}
void SelectionFunction::StartDrag (const Point& rMousePosition)
void SelectionFunction::StartDrag (
const Point& rMousePosition,
const InsertionIndicatorHandler::Mode eMode)
{
if (mbPageHit
&& ! mrSlideSorter.GetProperties()->IsUIReadOnly())
@ -736,7 +771,9 @@ void SelectionFunction::StartDrag (const Point& rMousePosition)
mrSlideSorter.GetController().GetPageAt(rMousePosition),
rMousePosition));
else
mpSubstitutionHandler->UpdatePosition(rMousePosition);
mpSubstitutionHandler->UpdatePosition(
rMousePosition,
eMode);
mbPageHit = false;
mpWindow->ReleaseMouse();
@ -1053,16 +1090,21 @@ bool SelectionFunction::EventProcessing (const EventDescriptor& rDescriptor)
switch (rDescriptor.mnEventCode & (SUBSTITUTION_VISIBLE | RECTANGLE_VISIBLE))
{
case SUBSTITUTION_VISIBLE:
OSL_ASSERT(mpSubstitutionHandler);
// The substitution is visible. Handle events accordingly.
if (Match(rDescriptor.mnEventCode, MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK))
{
if ((rDescriptor.mnEventCode & CONTROL_MODIFIER) != 0)
StartDrag(rDescriptor.maMousePosition);
mpSubstitutionHandler->UpdatePosition(rDescriptor.maMousePosition);
StartDrag(rDescriptor.maMousePosition, InsertionIndicatorHandler::CopyMode);
mpSubstitutionHandler->UpdatePosition(
rDescriptor.maMousePosition,
rDescriptor.meDragMode);
}
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))
{
@ -1395,7 +1437,8 @@ SelectionFunction::EventDescriptor::EventDescriptor (
mpHitDescriptor(),
mpHitPage(),
mnEventCode(0),
mnButtonIndex(-1)
mnButtonIndex(-1),
meDragMode(InsertionIndicatorHandler::MoveMode)
{
model::SharedPageDescriptor pHitDescriptor (
rSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor());
@ -1418,7 +1461,8 @@ SelectionFunction::EventDescriptor::EventDescriptor (
mpHitDescriptor(),
mpHitPage(),
mnEventCode(MOUSE_DRAG),
mnButtonIndex(-1)
mnButtonIndex(-1),
meDragMode(InsertionIndicatorHandler::MoveMode)
{
SharedSdWindow pWindow (rSlideSorter.GetContentWindow());
@ -1441,132 +1485,17 @@ SelectionFunction::EventDescriptor::EventDescriptor (const EventDescriptor& rDes
mpHitDescriptor(rDescriptor.mpHitDescriptor),
mpHitPage(rDescriptor.mpHitPage),
mnEventCode(rDescriptor.mnEventCode),
mnButtonIndex(rDescriptor.mnButtonIndex)
mnButtonIndex(rDescriptor.mnButtonIndex),
meDragMode(InsertionIndicatorHandler::MoveMode)
{
}
//===== SubstitutionHandler ===================================================
SelectionFunction::SubstitutionHandler::SubstitutionHandler (
SlideSorter& rSlideSorter,
const model::SharedPageDescriptor& rpHitDescriptor,
const Point& rMouseModelPosition)
: mrSlideSorter(rSlideSorter),
mpHitDescriptor(rpHitDescriptor),
mnInsertionIndex(-1)
void SelectionFunction::EventDescriptor::SetDragMode (const InsertionIndicatorHandler::Mode eMode)
{
mnInsertionIndex = -1;
// 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);
}
meDragMode = eMode;
}
@ -1849,11 +1778,14 @@ void RangeSelector::UpdateSelection (void)
{
view::SlideSorterView::DrawLock aLock (mrSlideSorter);
model::SlideSorterModel& rModel (mrSlideSorter.GetModel());
const sal_Int32 nPageCount (rModel.GetPageCount());
const sal_Int32 nIndexUnderMouse (
mrSlideSorter.GetView().GetLayouter().GetIndexAtPoint (
maSecondCorner,
false));
if (nIndexUnderMouse >= 0)
if (nIndexUnderMouse>=0 && nIndexUnderMouse<nPageCount)
{
if (mnAnchorIndex < 0)
mnAnchorIndex = nIndexUnderMouse;
@ -1862,8 +1794,7 @@ void RangeSelector::UpdateSelection (void)
Range aRange (mnAnchorIndex, mnSecondIndex);
aRange.Justify();
model::SlideSorterModel& rModel (mrSlideSorter.GetModel());
for (sal_Int32 nIndex=0,nCount(rModel.GetPageCount()); nIndex<nCount; ++nIndex)
for (sal_Int32 nIndex=0; nIndex<nPageCount; ++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,
::sd::View* pWorkView,
BOOL bInitOnGetData,
SlideSorterViewShell* pViewShell)
SlideSorterViewShell* pViewShell,
const ::boost::shared_ptr<SubstitutionHandler>& rpSubstitutionHandler)
: SdTransferable (pSrcDoc, pWorkView, bInitOnGetData),
mpViewShell(pViewShell)
mpViewShell(pViewShell),
mpSubstitutionHandler(rpSubstitutionHandler)
{
if (mpViewShell != NULL)
StartListening(*mpViewShell);
@ -52,6 +54,7 @@ Transferable::Transferable (
Transferable::~Transferable (void)
{
if (mpViewShell != NULL)
@ -65,6 +68,7 @@ void Transferable::DragFinished (sal_Int8 nDropAction)
{
if (mpViewShell != NULL)
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

View File

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

View File

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

View File

@ -68,6 +68,7 @@ class InsertionIndicatorHandler;
class Listener;
class PageSelector;
class ScrollBarManager;
class SelectionFunction;
class SelectionManager;
class SlotManager;
@ -207,6 +208,12 @@ public:
*/
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
edit mode we may save the selection so that it can be restored when
later changing back to the current edit mode.

View File

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

View File

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

View File

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

View File

@ -40,23 +40,12 @@
#include <memory>
#include <boost/enable_shared_from_this.hpp>
#include <boost/scoped_ptr.hpp>
class SdPage;
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 {
class SlideRenderer;
@ -141,6 +130,7 @@ private:
SdPage* mpPage;
css::uno::Reference<css::drawing::XDrawPage> mxPage;
SdrPage const* mpMasterPage;
/** This index is displayed as page number in the view. It may or may
not be the actual page index.
*/

View File

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

View File

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

View File

@ -39,12 +39,14 @@
#include <svx/svdopage.hxx>
#include <svx/svdpagv.hxx>
#include <svx/sdr/contact/viewcontact.hxx>
#include <svx/sdr/contact/viewobjectcontact.hxx>
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star;
namespace sd { namespace slidesorter { namespace model {
PageDescriptor::PageDescriptor (
const Reference<drawing::XDrawPage>& rxPage,
SdPage* pPage,
@ -64,7 +66,7 @@ PageDescriptor::PageDescriptor (
{
OSL_ASSERT(mpPage);
OSL_ASSERT(mpPage == SdPage::getImplementation(rxPage));
if (mpPage!=NULL && !mpPage->IsMasterPage())
if (mpPage!=NULL && mpPage->TRG_HasMasterPage())
mpMasterPage = &mpPage->TRG_GetMasterPage();
}
@ -105,7 +107,7 @@ sal_Int32 PageDescriptor::GetPageIndex (void) const
bool PageDescriptor::UpdateMasterPage (void)
{
const SdrPage* pMaster = NULL;
if (mpPage!=NULL && !mpPage->IsMasterPage())
if (mpPage!=NULL && mpPage->TRG_HasMasterPage())
pMaster = &mpPage->TRG_GetMasterPage();
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
// of the frame view and adapt the number of columns
// automatically to the window width.
rView.GetLayouter().SetColumnCount(1,5);
rView.GetLayouter().SetColumnCount(1,1);
}
else
rView.GetLayouter().SetColumnCount(nSlidesPerRow,nSlidesPerRow);

View File

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

View File

@ -43,7 +43,7 @@ namespace {
const static sal_Int32 gnPageNumberOffset = 5;
const static sal_Int32 gnPageNumberFrameHorizontalOffset = 2;
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 Size gaButtonSize (32,32);
const static sal_Int32 gnButtonGap (5);

View File

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

View File

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

View File

@ -105,6 +105,41 @@ Rectangle ConvertRectangle (const B2DRectangle& rBox)
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 (
@ -293,9 +328,7 @@ SubstitutionOverlay::SubstitutionOverlay (
const sal_Int32 nLayerIndex)
: OverlayBase(rViewOverlay, nLayerIndex),
maPosition(0,0),
maTranslation(0,0),
maItems(),
maBoundingBox()
mpState(new InternalState())
{
}
@ -311,11 +344,13 @@ SubstitutionOverlay::~SubstitutionOverlay (void)
void SubstitutionOverlay::Create (
model::PageEnumeration& rSelection,
const Point& rPosition,
const Point& rAnchor,
const model::SharedPageDescriptor& rpHitDescriptor)
{
maPosition = rPosition;
maTranslation = Point(0,0);
OSL_ASSERT(mpState);
mpState->maAnchor = rAnchor;
maPosition = rAnchor;
::boost::shared_ptr<cache::PageCache> pPreviewCache (
mrViewOverlay.GetSlideSorter().GetView().GetPreviewCache());
@ -330,7 +365,7 @@ void SubstitutionOverlay::Create (
? rLayouter.GetColumn(rpHitDescriptor->GetPageIndex())
: -1);
maItems.clear();
mpState->maItems.clear();
while (rSelection.HasMoreElements())
{
model::SharedPageDescriptor pDescriptor (rSelection.GetNextElement());
@ -357,7 +392,7 @@ void SubstitutionOverlay::Create (
}
const Rectangle aBox (pDescriptor->GetBoundingBox());
maBoundingBox.Union(aBox);
mpState->maBoundingBox.Union(aBox);
basegfx::B2DRectangle aB2DBox(
aBox.Left(),
aBox.Top(),
@ -367,19 +402,20 @@ void SubstitutionOverlay::Create (
const Bitmap aBitmap (pPreviewCache->GetPreviewBitmap(pDescriptor->GetPage()).GetBitmap());
AlphaMask aMask (aBitmap.GetSizePixel());
aMask.Erase(nTransparency);
maItems.push_back(ItemDescriptor());
maItems.back().maImage = BitmapEx(
mpState->maItems.push_back(ItemDescriptor());
ItemDescriptor& rNewItem (mpState->maItems.back());
rNewItem.maImage = BitmapEx(
aBitmap,
aMask);
maItems.back().maLocation = pPageObjectLayouter->GetBoundingBox(
rNewItem.maLocation = pPageObjectLayouter->GetBoundingBox(
pDescriptor,
PageObjectLayouter::Preview,
PageObjectLayouter::WindowCoordinateSystem).TopLeft();
maItems.back().mnTransparency = nTransparency/255.0;
maItems.back().maShape = basegfx::tools::createPolygonFromRect(aB2DBox);
rNewItem.mnTransparency = nTransparency/255.0;
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)
{
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)
{
Invalidator aInvalidator (*this);
maPosition += rOffset;
maTranslation += rOffset;
maBoundingBox.Move(rOffset.X(), rOffset.Y());
if (rOffset != Point(0,0))
{
Invalidator aInvalidator (*this);
maPosition += rOffset;
}
}
@ -408,7 +457,11 @@ void SubstitutionOverlay::Move (const Point& rOffset)
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)
{
(void)rRepaintArea;
OSL_ASSERT(mpState);
if ( ! IsVisible())
return;
const Point aOffset (maPosition - mpState->maAnchor);
basegfx::B2DHomMatrix aTranslation;
aTranslation.translate(maTranslation.X(), maTranslation.Y());
aTranslation.translate(aOffset.X(), aOffset.Y());
rDevice.SetFillColor(Color(AirForceBlue));
rDevice.SetLineColor();
for (::std::vector<ItemDescriptor>::const_iterator
iItem(maItems.begin()),
iEnd(maItems.end());
iItem(mpState->maItems.begin()),
iEnd(mpState->maItems.end());
iItem!=iEnd;
++iItem)
{
::basegfx::B2DPolyPolygon aPolygon (iItem->maShape);
aPolygon.transform(aTranslation);
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
{
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;
}