| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sd.hxx" |
| |
| #include <com/sun/star/util/XChangesNotifier.hpp> |
| |
| #include <vcl/help.hxx> |
| #include <vcl/svapp.hxx> |
| |
| #include <sfx2/viewfrm.hxx> |
| #include <sfx2/dispatch.hxx> |
| |
| #include <svx/sdr/overlay/overlaymanager.hxx> |
| #include <svx/sdr/overlay/overlayanimatedbitmapex.hxx> |
| #include <svx/sdr/overlay/overlaybitmapex.hxx> |
| #include <svx/svdpagv.hxx> |
| #include <svx/sdrpagewindow.hxx> |
| #include <svx/sdrpaintwindow.hxx> |
| #include <svx/svddrgmt.hxx> |
| |
| #include "View.hxx" |
| #include "sdresid.hxx" |
| #include "annotations.hrc" |
| #include "annotationmanagerimpl.hxx" |
| #include "annotationwindow.hxx" |
| #include "annotationtag.hxx" |
| #include "sdpage.hxx" |
| #include "ViewShell.hxx" |
| #include "app.hrc" |
| #include "Window.hxx" |
| #include "drawdoc.hxx" |
| |
| using ::rtl::OUString; |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::lang; |
| //using namespace ::com::sun::star::util; |
| using namespace ::com::sun::star::drawing; |
| using namespace ::com::sun::star::office; |
| using namespace ::com::sun::star::geometry; |
| |
| namespace sd |
| { |
| |
| const sal_uInt32 SMART_TAG_HDL_NUM = SAL_MAX_UINT32; |
| static const int DRGPIX = 2; // Drag MinMove in Pixel |
| |
| // -------------------------------------------------------------------- |
| |
| static OUString getInitials( const OUString& rName ) |
| { |
| OUString sInitials; |
| |
| const sal_Unicode * pStr = rName.getStr(); |
| sal_Int32 nLength = rName.getLength(); |
| |
| while( nLength ) |
| { |
| // skip whitespace |
| while( nLength && (*pStr <= ' ') ) |
| { |
| nLength--; pStr++; |
| } |
| |
| // take letter |
| if( nLength ) |
| { |
| sInitials += OUString( *pStr ); |
| nLength--; pStr++; |
| } |
| |
| // skip letters until whitespace |
| while( nLength && (*pStr > ' ') ) |
| { |
| nLength--; pStr++; |
| } |
| } |
| |
| return sInitials; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| // -------------------------------------------------------------------- |
| |
| class AnnotationDragMove : public SdrDragMove |
| { |
| public: |
| AnnotationDragMove(SdrDragView& rNewView, const rtl::Reference <AnnotationTag >& xTag); |
| virtual bool BeginSdrDrag(); |
| virtual bool EndSdrDrag(bool bCopy); |
| virtual void MoveSdrDrag(const Point& rNoSnapPnt); |
| virtual void CancelSdrDrag(); |
| |
| private: |
| rtl::Reference <AnnotationTag > mxTag; |
| Point maOrigin; |
| }; |
| |
| AnnotationDragMove::AnnotationDragMove(SdrDragView& rNewView, const rtl::Reference <AnnotationTag >& xTag) |
| : SdrDragMove(rNewView) |
| , mxTag( xTag ) |
| { |
| } |
| |
| bool AnnotationDragMove::BeginSdrDrag() |
| { |
| DragStat().Ref1()=GetDragHdl()->GetPos(); |
| DragStat().SetShown(!DragStat().IsShown()); |
| |
| maOrigin = GetDragHdl()->GetPos(); |
| DragStat().SetActionRect(Rectangle(maOrigin,maOrigin)); |
| |
| return true; |
| } |
| |
| void AnnotationDragMove::MoveSdrDrag(const Point& rNoSnapPnt) |
| { |
| Point aPnt(rNoSnapPnt); |
| |
| if (DragStat().CheckMinMoved(rNoSnapPnt)) |
| { |
| if (aPnt!=DragStat().GetNow()) |
| { |
| Hide(); |
| DragStat().NextMove(aPnt); |
| GetDragHdl()->SetPos( maOrigin + Point( DragStat().GetDX(), DragStat().GetDY() ) ); |
| Show(); |
| DragStat().SetActionRect(Rectangle(aPnt,aPnt)); |
| } |
| } |
| } |
| |
| bool AnnotationDragMove::EndSdrDrag(bool /*bCopy*/) |
| { |
| Hide(); |
| if( mxTag.is() ) |
| mxTag->Move( DragStat().GetDX(), DragStat().GetDY() ); |
| return sal_True; |
| } |
| |
| void AnnotationDragMove::CancelSdrDrag() |
| { |
| Hide(); |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| class AnnotationHdl : public SmartHdl |
| { |
| public: |
| AnnotationHdl( const SmartTagReference& xTag, const Reference< XAnnotation >& xAnnotation, const Point& rPnt ); |
| virtual ~AnnotationHdl(); |
| virtual void CreateB2dIAObject(); |
| virtual sal_Bool IsFocusHdl() const; |
| virtual Pointer GetSdrDragPointer() const; |
| virtual bool isMarkable() const; |
| |
| |
| private: |
| Reference< XAnnotation > mxAnnotation; |
| rtl::Reference< AnnotationTag > mxTag; |
| }; |
| |
| // -------------------------------------------------------------------- |
| |
| AnnotationHdl::AnnotationHdl( const SmartTagReference& xTag, const Reference< XAnnotation >& xAnnotation, const Point& rPnt ) |
| : SmartHdl( xTag, rPnt ) |
| , mxAnnotation( xAnnotation ) |
| , mxTag( dynamic_cast< AnnotationTag* >( xTag.get() ) ) |
| { |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| AnnotationHdl::~AnnotationHdl() |
| { |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void AnnotationHdl::CreateB2dIAObject() |
| { |
| // first throw away old one |
| GetRidOfIAObject(); |
| |
| if( mxAnnotation.is() ) |
| { |
| const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); |
| |
| const Point aTagPos( GetPos() ); |
| basegfx::B2DPoint aPosition( aTagPos.X(), aTagPos.Y() ); |
| |
| const bool bFocused = IsFocusHdl() && pHdlList && (pHdlList->GetFocusHdl() == this); |
| |
| BitmapEx aBitmapEx( mxTag->CreateAnnotationBitmap(mxTag->isSelected()) ); |
| BitmapEx aBitmapEx2; |
| if( bFocused ) |
| aBitmapEx2 = mxTag->CreateAnnotationBitmap(!mxTag->isSelected() ); |
| |
| if(pHdlList) |
| { |
| SdrMarkView* pView = pHdlList->GetView(); |
| |
| if(pView && !pView->areMarkHandlesHidden()) |
| { |
| SdrPageView* pPageView = pView->GetSdrPageView(); |
| |
| if(pPageView) |
| { |
| for(sal_uInt32 b = 0; b < pPageView->PageWindowCount(); b++) |
| { |
| // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b]; |
| const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b); |
| |
| SdrPaintWindow& rPaintWindow = rPageWindow.GetPaintWindow(); |
| if(rPaintWindow.OutputToWindow() && rPageWindow.GetOverlayManager() ) |
| { |
| ::sdr::overlay::OverlayObject* pOverlayObject = 0; |
| |
| // animate focused handles |
| if(bFocused) |
| { |
| const sal_uInt32 nBlinkTime = sal::static_int_cast<sal_uInt32>(rStyleSettings.GetCursorBlinkTime()); |
| |
| pOverlayObject = new ::sdr::overlay::OverlayAnimatedBitmapEx(aPosition, aBitmapEx, aBitmapEx2, nBlinkTime, 0, 0, 0, 0 ); |
| /* |
| (sal_uInt16)(aBitmapEx.GetSizePixel().Width() - 1) >> 1, |
| (sal_uInt16)(aBitmapEx.GetSizePixel().Height() - 1) >> 1, |
| (sal_uInt16)(aBitmapEx2.GetSizePixel().Width() - 1) >> 1, |
| (sal_uInt16)(aBitmapEx2.GetSizePixel().Height() - 1) >> 1); |
| */ |
| } |
| else |
| { |
| pOverlayObject = new ::sdr::overlay::OverlayBitmapEx( aPosition, aBitmapEx, 0, 0 ); |
| } |
| |
| rPageWindow.GetOverlayManager()->add(*pOverlayObject); |
| maOverlayGroup.append(*pOverlayObject); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| sal_Bool AnnotationHdl::IsFocusHdl() const |
| { |
| return sal_True; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| bool AnnotationHdl::isMarkable() const |
| { |
| return false; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| Pointer AnnotationHdl::GetSdrDragPointer() const |
| { |
| PointerStyle eStyle = POINTER_NOTALLOWED; |
| if( mxTag.is() ) |
| { |
| if( mxTag->isSelected() ) |
| { |
| eStyle = POINTER_MOVE; |
| } |
| else |
| { |
| eStyle = POINTER_ARROW; |
| |
| } |
| } |
| return Pointer( eStyle ); |
| } |
| |
| // ==================================================================== |
| |
| AnnotationTag::AnnotationTag( AnnotationManagerImpl& rManager, ::sd::View& rView, const Reference< XAnnotation >& xAnnotation, Color& rColor, int nIndex, const Font& rFont ) |
| : SmartTag( rView ) |
| , mrManager( rManager ) |
| , mxAnnotation( xAnnotation ) |
| , maColor( rColor ) |
| , mnIndex( nIndex ) |
| , mrFont( rFont ) |
| , mnClosePopupEvent( 0 ) |
| , mpListenWindow( 0 ) |
| { |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| AnnotationTag::~AnnotationTag() |
| { |
| DBG_ASSERT( !mxAnnotation.is(), "sd::AnnotationTag::~AnnotationTag(), dispose me first!" ); |
| Dispose(); |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| /** returns true if the AnnotationTag handled the event. */ |
| bool AnnotationTag::MouseButtonDown( const MouseEvent& rMEvt, SmartHdl& /*rHdl*/ ) |
| { |
| if( !mxAnnotation.is() ) |
| return false; |
| |
| bool bRet = false; |
| if( !isSelected() ) |
| { |
| SmartTagReference xTag( this ); |
| mrView.getSmartTags().select( xTag ); |
| bRet = true; |
| } |
| /* |
| if( rMEvt.IsLeft() && (rMEvt.GetClicks() == 2) ) |
| { |
| // double click; |
| return true; |
| } |
| else */ |
| if( rMEvt.IsLeft() && !rMEvt.IsRight() ) |
| { |
| Window* pWindow = mrView.GetViewShell()->GetActiveWindow(); |
| if( pWindow ) |
| { |
| maMouseDownPos = pWindow->PixelToLogic( rMEvt.GetPosPixel() ); |
| |
| if( mpListenWindow ) |
| mpListenWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler)); |
| |
| mpListenWindow = pWindow; |
| mpListenWindow->AddEventListener( LINK(this, AnnotationTag, WindowEventHandler)); |
| } |
| |
| bRet = true; |
| } |
| |
| return bRet; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| /** returns true if the SmartTag consumes this event. */ |
| bool AnnotationTag::KeyInput( const KeyEvent& rKEvt ) |
| { |
| if( !mxAnnotation.is() ) |
| return false; |
| |
| sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode(); |
| switch( nCode ) |
| { |
| case KEY_DELETE: |
| mrManager.DeleteAnnotation( mxAnnotation ); |
| return true; |
| |
| case KEY_DOWN: |
| case KEY_UP: |
| case KEY_LEFT: |
| case KEY_RIGHT: |
| return OnMove( rKEvt ); |
| |
| case KEY_ESCAPE: |
| { |
| SmartTagReference xThis( this ); |
| mrView.getSmartTags().deselect(); |
| return true; |
| } |
| |
| case KEY_TAB: |
| mrManager.SelectNextAnnotation(!rKEvt.GetKeyCode().IsShift()); |
| return true; |
| |
| case KEY_RETURN: |
| case KEY_SPACE: |
| OpenPopup( true ); |
| return true; |
| |
| default: |
| return false; |
| } |
| } |
| |
| /** returns true if the SmartTag consumes this event. */ |
| bool AnnotationTag::RequestHelp( const HelpEvent& /*rHEvt*/ ) |
| { |
| /* |
| ::Window* pWindow = mrView.GetViewShell()->GetActiveWindow(); |
| if( mxAnnotation.is() && pWindow ) |
| { |
| OUString aHelpText( mrManager.GetHelpText( mxAnnotation ) ); |
| |
| RealPoint2D aPosition( mxAnnotation->getPosition() ); |
| Point aPos( pWindow->LogicToPixel( Point( static_cast<long>(aPosition.X * 100.0), static_cast<long>(aPosition.Y * 100.0) ) ) ); |
| |
| Rectangle aRect( aPos, maSize ); |
| |
| if (Help::IsBalloonHelpEnabled()) |
| Help::ShowBalloon( pWindow, aPos, aRect, aHelpText); |
| else if (Help::IsQuickHelpEnabled()) |
| Help::ShowQuickHelp( pWindow, aRect, aHelpText); |
| |
| return true; |
| } |
| */ |
| return false; |
| } |
| |
| /** returns true if the SmartTag consumes this event. */ |
| bool AnnotationTag::Command( const CommandEvent& rCEvt ) |
| { |
| if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU ) |
| { |
| ::Window* pWindow = mrView.GetViewShell()->GetActiveWindow(); |
| if( pWindow ) |
| { |
| Rectangle aContextRect(rCEvt.GetMousePosPixel(),Size(1,1)); |
| mrManager.ExecuteAnnotationContextMenu( mxAnnotation, pWindow, aContextRect ); |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| void AnnotationTag::Move( int nDX, int nDY ) |
| { |
| if( mxAnnotation.is() ) |
| { |
| if( mrManager.GetDoc()->IsUndoEnabled() ) |
| mrManager.GetDoc()->BegUndo( String( SdResId( STR_ANNOTATION_UNDO_MOVE ) ) ); |
| |
| RealPoint2D aPosition( mxAnnotation->getPosition() ); |
| aPosition.X += (double)nDX / 100.0; |
| aPosition.Y += (double)nDY / 100.0; |
| mxAnnotation->setPosition( aPosition ); |
| |
| if( mrManager.GetDoc()->IsUndoEnabled() ) |
| mrManager.GetDoc()->EndUndo(); |
| |
| mrView.updateHandles(); |
| } |
| } |
| |
| bool AnnotationTag::OnMove( const KeyEvent& rKEvt ) |
| { |
| long nX = 0; |
| long nY = 0; |
| |
| switch( rKEvt.GetKeyCode().GetCode() ) |
| { |
| case KEY_UP: nY = -1; break; |
| case KEY_DOWN: nY = 1; break; |
| case KEY_LEFT: nX = -1; break; |
| case KEY_RIGHT: nX = 1; break; |
| default: break; |
| } |
| |
| if(rKEvt.GetKeyCode().IsMod2()) |
| { |
| OutputDevice* pOut = mrView.GetViewShell()->GetActiveWindow(); |
| Size aLogicSizeOnePixel = (pOut) ? pOut->PixelToLogic(Size(1,1)) : Size(100, 100); |
| nX *= aLogicSizeOnePixel.Width(); |
| nY *= aLogicSizeOnePixel.Height(); |
| } |
| else |
| { |
| // old, fixed move distance |
| nX *= 100; |
| nY *= 100; |
| } |
| |
| if( nX || nY ) |
| { |
| // move the annotation |
| Move( nX, nY ); |
| } |
| |
| return true; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void AnnotationTag::CheckPossibilities() |
| { |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| sal_uLong AnnotationTag::GetMarkablePointCount() const |
| { |
| return 0; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| sal_uLong AnnotationTag::GetMarkedPointCount() const |
| { |
| return 0; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| sal_Bool AnnotationTag::MarkPoint(SdrHdl& /*rHdl*/, sal_Bool /*bUnmark*/ ) |
| { |
| sal_Bool bRet=sal_False; |
| return bRet; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| sal_Bool AnnotationTag::MarkPoints(const Rectangle* /*pRect*/, sal_Bool /*bUnmark*/ ) |
| { |
| sal_Bool bChgd=sal_False; |
| return bChgd; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| bool AnnotationTag::getContext( SdrViewContext& /*rContext*/ ) |
| { |
| return false; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void AnnotationTag::addCustomHandles( SdrHdlList& rHandlerList ) |
| { |
| if( mxAnnotation.is() ) |
| { |
| SmartTagReference xThis( this ); |
| Point aPoint; |
| AnnotationHdl* pHdl = new AnnotationHdl( xThis, mxAnnotation, aPoint ); |
| pHdl->SetObjHdlNum( SMART_TAG_HDL_NUM ); |
| pHdl->SetPageView( mrView.GetSdrPageView() ); |
| |
| RealPoint2D aPosition( mxAnnotation->getPosition() ); |
| Point aBasePos( static_cast<long>(aPosition.X * 100.0), static_cast<long>(aPosition.Y * 100.0) ); |
| pHdl->SetPos( aBasePos ); |
| |
| rHandlerList.AddHdl( pHdl ); |
| } |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void AnnotationTag::disposing() |
| { |
| if( mpListenWindow ) |
| { |
| mpListenWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler)); |
| } |
| |
| if( mnClosePopupEvent ) |
| { |
| Application::RemoveUserEvent( mnClosePopupEvent ); |
| mnClosePopupEvent = 0; |
| } |
| |
| mxAnnotation.clear(); |
| ClosePopup(); |
| SmartTag::disposing(); |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void AnnotationTag::select() |
| { |
| SmartTag::select(); |
| |
| mrManager.onTagSelected( *this ); |
| |
| Window* pWindow = mrView.GetViewShell()->GetActiveWindow(); |
| if( pWindow ) |
| { |
| RealPoint2D aPosition( mxAnnotation->getPosition() ); |
| Point aPos( static_cast<long>(aPosition.X * 100.0), static_cast<long>(aPosition.Y * 100.0) ); |
| |
| Rectangle aVisRect( aPos, pWindow->PixelToLogic(maSize) ); |
| mrView.MakeVisible(aVisRect, *pWindow); |
| } |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void AnnotationTag::deselect() |
| { |
| SmartTag::deselect(); |
| |
| ClosePopup(); |
| |
| mrManager.onTagDeselected( *this ); |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| BitmapEx AnnotationTag::CreateAnnotationBitmap( bool bSelected ) |
| { |
| VirtualDevice aVDev; |
| |
| OUString sAuthor( getInitials( mxAnnotation->getAuthor() ) ); |
| sAuthor += OUString( sal_Unicode( ' ' ) ); |
| sAuthor += OUString::valueOf( (sal_Int32)mnIndex ); |
| |
| aVDev.SetFont( mrFont ); |
| |
| const int BORDER_X = 4; // pixels |
| const int BORDER_Y = 4; // pixels |
| |
| maSize = Size( aVDev.GetTextWidth( sAuthor ) + 2*BORDER_X, aVDev.GetTextHeight() + 2*BORDER_Y ); |
| aVDev.SetOutputSizePixel( maSize, sal_False ); |
| |
| Color aBorderColor( maColor ); |
| |
| if( bSelected ) |
| { |
| aBorderColor.Invert(); |
| } |
| else |
| { |
| if( maColor.IsDark() ) |
| { |
| aBorderColor.IncreaseLuminance( 32 ); |
| } |
| else |
| { |
| aBorderColor.DecreaseLuminance( 32 ); |
| } |
| } |
| |
| Point aPos; |
| Rectangle aBorderRect( aPos, maSize ); |
| aVDev.SetLineColor(aBorderColor); |
| aVDev.SetFillColor(maColor); |
| aVDev.DrawRect( aBorderRect ); |
| |
| aVDev.SetTextColor( maColor.IsDark() ? COL_WHITE : COL_BLACK ); |
| aVDev.DrawText( Point( BORDER_X, BORDER_Y ), sAuthor ); |
| |
| return aVDev.GetBitmapEx( aPos, maSize ); |
| } |
| |
| void AnnotationTag::OpenPopup( bool bEdit ) |
| { |
| if( !mxAnnotation.is() ) |
| return; |
| |
| if( !mpAnnotationWindow.get() ) |
| { |
| ::Window* pWindow = dynamic_cast< ::Window* >( getView().GetFirstOutputDevice() ); |
| if( pWindow ) |
| { |
| RealPoint2D aPosition( mxAnnotation->getPosition() ); |
| Point aPos( pWindow->OutputToScreenPixel( pWindow->LogicToPixel( Point( static_cast<long>(aPosition.X * 100.0), static_cast<long>(aPosition.Y * 100.0) ) ) ) ); |
| |
| aPos.X() += 4; // magic! |
| aPos.Y() += 1; |
| |
| Rectangle aRect( aPos, maSize ); |
| |
| mpAnnotationWindow.reset( new AnnotationWindow( mrManager, mrView.GetDocSh(), pWindow->GetWindow(WINDOW_FRAME) ) ); |
| mpAnnotationWindow->InitControls(); |
| mpAnnotationWindow->setAnnotation(mxAnnotation); |
| |
| sal_uInt16 nArrangeIndex = 0; |
| Point aPopupPos( FloatingWindow::CalcFloatingPosition( mpAnnotationWindow.get(), aRect, FLOATWIN_POPUPMODE_RIGHT, nArrangeIndex ) ); |
| Size aPopupSize( 320, 240 ); |
| |
| mpAnnotationWindow->SetPosSizePixel( aPopupPos, aPopupSize ); |
| mpAnnotationWindow->DoResize(); |
| |
| mpAnnotationWindow->Show(); |
| mpAnnotationWindow->GrabFocus(); |
| mpAnnotationWindow->AddEventListener( LINK(this, AnnotationTag, WindowEventHandler)); |
| } |
| } |
| |
| if( bEdit && mpAnnotationWindow.get() ) |
| mpAnnotationWindow->StartEdit(); |
| } |
| |
| void AnnotationTag::ClosePopup() |
| { |
| if( mpAnnotationWindow.get() ) |
| { |
| mpAnnotationWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler)); |
| mpAnnotationWindow->Deactivate(); |
| mpAnnotationWindow.reset(); |
| } |
| } |
| |
| IMPL_LINK(AnnotationTag, WindowEventHandler, VclWindowEvent*, pEvent) |
| { |
| if( pEvent != NULL ) |
| { |
| ::Window* pWindow = pEvent->GetWindow(); |
| |
| if( pWindow ) |
| { |
| if( pWindow == mpAnnotationWindow.get() ) |
| { |
| if( pEvent->GetId() == VCLEVENT_WINDOW_DEACTIVATE ) |
| { |
| if( mnClosePopupEvent ) |
| Application::RemoveUserEvent( mnClosePopupEvent ); |
| |
| mnClosePopupEvent = Application::PostUserEvent( LINK( this, AnnotationTag, ClosePopupHdl ) ); |
| } |
| } |
| else if( pWindow == mpListenWindow ) |
| { |
| switch( pEvent->GetId() ) |
| { |
| case VCLEVENT_WINDOW_MOUSEBUTTONUP: |
| { |
| // if we stop pressing the button without a mouse move we open the popup |
| mpListenWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler)); |
| mpListenWindow = 0; |
| if( mpAnnotationWindow.get() == 0 ) |
| OpenPopup(false); |
| } |
| break; |
| case VCLEVENT_WINDOW_MOUSEMOVE: |
| { |
| // if we move the mouse after a button down we wan't to start draging |
| mpListenWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler)); |
| mpListenWindow = 0; |
| |
| SdrHdl* pHdl = mrView.PickHandle(maMouseDownPos); |
| if( pHdl ) |
| { |
| mrView.BrkAction(); |
| const sal_uInt16 nDrgLog = (sal_uInt16)pWindow->PixelToLogic(Size(DRGPIX,0)).Width(); |
| |
| rtl::Reference< AnnotationTag > xTag( this ); |
| |
| SdrDragMethod* pDragMethod = new AnnotationDragMove( mrView, xTag ); |
| mrView.BegDragObj(maMouseDownPos, NULL, pHdl, nDrgLog, pDragMethod ); |
| } |
| } |
| break; |
| case VCLEVENT_OBJECT_DYING: |
| mpListenWindow = 0; |
| break; |
| } |
| } |
| } |
| } |
| return sal_True; |
| } |
| |
| IMPL_LINK( AnnotationTag, ClosePopupHdl, void *, EMPTYARG ) |
| { |
| mnClosePopupEvent = 0; |
| ClosePopup(); |
| return 0; |
| } |
| |
| } // end of namespace sd |
| |