xref: /AOO41X/main/sd/source/ui/annotations/annotationtag.cxx (revision 79aad27f7f29270c03e208e3d687e8e3850af11d)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sd.hxx"
26 
27 #include <com/sun/star/util/XChangesNotifier.hpp>
28 
29 #include <vcl/help.hxx>
30 #include <vcl/svapp.hxx>
31 
32 #include <sfx2/viewfrm.hxx>
33 #include <sfx2/dispatch.hxx>
34 
35 #include <svx/sdr/overlay/overlaymanager.hxx>
36 #include <svx/sdr/overlay/overlayanimatedbitmapex.hxx>
37 #include <svx/sdr/overlay/overlaybitmapex.hxx>
38 #include <svx/svdpagv.hxx>
39 #include <svx/sdrpagewindow.hxx>
40 #include <svx/sdrpaintwindow.hxx>
41 #include <svx/svddrgmt.hxx>
42 
43 #include "View.hxx"
44 #include "sdresid.hxx"
45 #include "annotations.hrc"
46 #include "annotationmanagerimpl.hxx"
47 #include "annotationwindow.hxx"
48 #include "annotationtag.hxx"
49 #include "sdpage.hxx"
50 #include "ViewShell.hxx"
51 #include "app.hrc"
52 #include "Window.hxx"
53 #include "drawdoc.hxx"
54 
55 using ::rtl::OUString;
56 using namespace ::com::sun::star::uno;
57 using namespace ::com::sun::star::lang;
58 //using namespace ::com::sun::star::util;
59 using namespace ::com::sun::star::drawing;
60 using namespace ::com::sun::star::office;
61 using namespace ::com::sun::star::geometry;
62 
63 namespace sd
64 {
65 
66 const sal_uInt32 SMART_TAG_HDL_NUM = SAL_MAX_UINT32;
67 static const int DRGPIX     = 2;                               // Drag MinMove in Pixel
68 
69 // --------------------------------------------------------------------
70 
getInitials(const OUString & rName)71 static OUString getInitials( const OUString& rName )
72 {
73     OUString sInitials;
74 
75     const sal_Unicode * pStr = rName.getStr();
76     sal_Int32 nLength = rName.getLength();
77 
78     while( nLength )
79     {
80         // skip whitespace
81         while( nLength && (*pStr <= ' ') )
82         {
83             nLength--; pStr++;
84         }
85 
86         // take letter
87         if( nLength )
88         {
89             sInitials += OUString( *pStr );
90             nLength--; pStr++;
91         }
92 
93         // skip letters until whitespace
94         while( nLength && (*pStr > ' ') )
95         {
96             nLength--; pStr++;
97         }
98     }
99 
100     return sInitials;
101 }
102 
103 // --------------------------------------------------------------------
104 
105 // --------------------------------------------------------------------
106 
107 class AnnotationDragMove : public SdrDragMove
108 {
109 public:
110     AnnotationDragMove(SdrDragView& rNewView, const rtl::Reference <AnnotationTag >& xTag);
111     virtual bool BeginSdrDrag();
112     virtual bool EndSdrDrag(bool bCopy);
113     virtual void MoveSdrDrag(const Point& rNoSnapPnt);
114     virtual void CancelSdrDrag();
115 
116 private:
117     rtl::Reference <AnnotationTag > mxTag;
118     Point maOrigin;
119 };
120 
AnnotationDragMove(SdrDragView & rNewView,const rtl::Reference<AnnotationTag> & xTag)121 AnnotationDragMove::AnnotationDragMove(SdrDragView& rNewView, const rtl::Reference <AnnotationTag >& xTag)
122 : SdrDragMove(rNewView)
123 , mxTag( xTag )
124 {
125 }
126 
BeginSdrDrag()127 bool AnnotationDragMove::BeginSdrDrag()
128 {
129     DragStat().Ref1()=GetDragHdl()->GetPos();
130     DragStat().SetShown(!DragStat().IsShown());
131 
132     maOrigin = GetDragHdl()->GetPos();
133     DragStat().SetActionRect(Rectangle(maOrigin,maOrigin));
134 
135     return true;
136 }
137 
MoveSdrDrag(const Point & rNoSnapPnt)138 void AnnotationDragMove::MoveSdrDrag(const Point& rNoSnapPnt)
139 {
140     Point aPnt(rNoSnapPnt);
141 
142     if (DragStat().CheckMinMoved(rNoSnapPnt))
143     {
144         if (aPnt!=DragStat().GetNow())
145         {
146             Hide();
147             DragStat().NextMove(aPnt);
148             GetDragHdl()->SetPos( maOrigin + Point( DragStat().GetDX(), DragStat().GetDY() ) );
149             Show();
150             DragStat().SetActionRect(Rectangle(aPnt,aPnt));
151         }
152     }
153 }
154 
EndSdrDrag(bool)155 bool AnnotationDragMove::EndSdrDrag(bool /*bCopy*/)
156 {
157     Hide();
158     if( mxTag.is() )
159         mxTag->Move( DragStat().GetDX(), DragStat().GetDY() );
160     return sal_True;
161 }
162 
CancelSdrDrag()163 void AnnotationDragMove::CancelSdrDrag()
164 {
165     Hide();
166 }
167 
168 // --------------------------------------------------------------------
169 
170 class AnnotationHdl : public SmartHdl
171 {
172 public:
173     AnnotationHdl( const SmartTagReference& xTag, const Reference< XAnnotation >& xAnnotation, const Point& rPnt );
174     virtual ~AnnotationHdl();
175     virtual void CreateB2dIAObject();
176     virtual sal_Bool IsFocusHdl() const;
177     virtual Pointer GetSdrDragPointer() const;
178     virtual bool isMarkable() const;
179 
180 
181 private:
182     Reference< XAnnotation > mxAnnotation;
183     rtl::Reference< AnnotationTag > mxTag;
184 };
185 
186 // --------------------------------------------------------------------
187 
AnnotationHdl(const SmartTagReference & xTag,const Reference<XAnnotation> & xAnnotation,const Point & rPnt)188 AnnotationHdl::AnnotationHdl( const SmartTagReference& xTag, const Reference< XAnnotation >& xAnnotation, const Point& rPnt )
189 : SmartHdl( xTag, rPnt )
190 , mxAnnotation( xAnnotation )
191 , mxTag( dynamic_cast< AnnotationTag* >( xTag.get() ) )
192 {
193 }
194 
195 // --------------------------------------------------------------------
196 
~AnnotationHdl()197 AnnotationHdl::~AnnotationHdl()
198 {
199 }
200 
201 // --------------------------------------------------------------------
202 
CreateB2dIAObject()203 void AnnotationHdl::CreateB2dIAObject()
204 {
205     // first throw away old one
206     GetRidOfIAObject();
207 
208     if( mxAnnotation.is() )
209     {
210         const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
211 
212         const Point aTagPos( GetPos() );
213         basegfx::B2DPoint aPosition( aTagPos.X(), aTagPos.Y() );
214 
215         const bool bFocused = IsFocusHdl() && pHdlList && (pHdlList->GetFocusHdl() == this);
216 
217         BitmapEx aBitmapEx( mxTag->CreateAnnotationBitmap(mxTag->isSelected()) );
218         BitmapEx aBitmapEx2;
219         if( bFocused )
220             aBitmapEx2 = mxTag->CreateAnnotationBitmap(!mxTag->isSelected() );
221 
222         if(pHdlList)
223         {
224             SdrMarkView* pView = pHdlList->GetView();
225 
226             if(pView && !pView->areMarkHandlesHidden())
227             {
228                 SdrPageView* pPageView = pView->GetSdrPageView();
229 
230                 if(pPageView)
231                 {
232                     for(sal_uInt32 b = 0; b < pPageView->PageWindowCount(); b++)
233                     {
234                         // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
235                         const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
236 
237                         SdrPaintWindow& rPaintWindow = rPageWindow.GetPaintWindow();
238                         if(rPaintWindow.OutputToWindow() && rPageWindow.GetOverlayManager() )
239                         {
240                             ::sdr::overlay::OverlayObject* pOverlayObject = 0;
241 
242                             // animate focused handles
243                             if(bFocused)
244                             {
245                                 const sal_uInt32 nBlinkTime = sal::static_int_cast<sal_uInt32>(rStyleSettings.GetCursorBlinkTime());
246 
247                                 pOverlayObject = new ::sdr::overlay::OverlayAnimatedBitmapEx(aPosition, aBitmapEx, aBitmapEx2, nBlinkTime, 0, 0, 0, 0 );
248 /*
249                                     (sal_uInt16)(aBitmapEx.GetSizePixel().Width() - 1) >> 1,
250                                     (sal_uInt16)(aBitmapEx.GetSizePixel().Height() - 1) >> 1,
251                                     (sal_uInt16)(aBitmapEx2.GetSizePixel().Width() - 1) >> 1,
252                                     (sal_uInt16)(aBitmapEx2.GetSizePixel().Height() - 1) >> 1);
253 */
254                             }
255                             else
256                             {
257                                 pOverlayObject = new ::sdr::overlay::OverlayBitmapEx( aPosition, aBitmapEx, 0, 0 );
258                             }
259 
260                             rPageWindow.GetOverlayManager()->add(*pOverlayObject);
261                             maOverlayGroup.append(*pOverlayObject);
262                         }
263                     }
264                 }
265             }
266         }
267     }
268 }
269 
270 // --------------------------------------------------------------------
271 
IsFocusHdl() const272 sal_Bool AnnotationHdl::IsFocusHdl() const
273 {
274     return sal_True;
275 }
276 
277 // --------------------------------------------------------------------
278 
isMarkable() const279 bool AnnotationHdl::isMarkable() const
280 {
281     return false;
282 }
283 
284 // --------------------------------------------------------------------
285 
GetSdrDragPointer() const286 Pointer AnnotationHdl::GetSdrDragPointer() const
287 {
288     PointerStyle eStyle = POINTER_NOTALLOWED;
289     if( mxTag.is() )
290     {
291         if( mxTag->isSelected() )
292         {
293             eStyle = POINTER_MOVE;
294         }
295         else
296         {
297             eStyle = POINTER_ARROW;
298 
299         }
300     }
301     return Pointer( eStyle );
302 }
303 
304 // ====================================================================
305 
AnnotationTag(AnnotationManagerImpl & rManager,::sd::View & rView,const Reference<XAnnotation> & xAnnotation,Color & rColor,int nIndex,const Font & rFont)306 AnnotationTag::AnnotationTag( AnnotationManagerImpl& rManager, ::sd::View& rView, const Reference< XAnnotation >& xAnnotation, Color& rColor, int nIndex, const Font& rFont )
307 : SmartTag( rView )
308 , mrManager( rManager )
309 , mxAnnotation( xAnnotation )
310 , maColor( rColor )
311 , mnIndex( nIndex )
312 , mrFont( rFont )
313 , mnClosePopupEvent( 0 )
314 , mpListenWindow( 0 )
315 {
316 }
317 
318 // --------------------------------------------------------------------
319 
~AnnotationTag()320 AnnotationTag::~AnnotationTag()
321 {
322     DBG_ASSERT( !mxAnnotation.is(), "sd::AnnotationTag::~AnnotationTag(), dispose me first!" );
323     Dispose();
324 }
325 
326 // --------------------------------------------------------------------
327 
328 /** returns true if the AnnotationTag handled the event. */
MouseButtonDown(const MouseEvent & rMEvt,SmartHdl &)329 bool AnnotationTag::MouseButtonDown( const MouseEvent& rMEvt, SmartHdl& /*rHdl*/ )
330 {
331     if( !mxAnnotation.is() )
332         return false;
333 
334     bool bRet = false;
335     if( !isSelected() )
336     {
337         SmartTagReference xTag( this );
338         mrView.getSmartTags().select( xTag );
339         bRet = true;
340     }
341     /*
342     if( rMEvt.IsLeft() && (rMEvt.GetClicks() == 2) )
343     {
344         // double click;
345         return true;
346     }
347     else */
348     if( rMEvt.IsLeft() && !rMEvt.IsRight() )
349     {
350         Window* pWindow = mrView.GetViewShell()->GetActiveWindow();
351         if( pWindow )
352         {
353             maMouseDownPos = pWindow->PixelToLogic( rMEvt.GetPosPixel() );
354 
355             if( mpListenWindow )
356                 mpListenWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler));
357 
358             mpListenWindow = pWindow;
359             mpListenWindow->AddEventListener( LINK(this, AnnotationTag, WindowEventHandler));
360         }
361 
362         bRet = true;
363     }
364 
365     return bRet;
366 }
367 
368 // --------------------------------------------------------------------
369 
370 /** returns true if the SmartTag consumes this event. */
KeyInput(const KeyEvent & rKEvt)371 bool AnnotationTag::KeyInput( const KeyEvent& rKEvt )
372 {
373     if( !mxAnnotation.is() )
374         return false;
375 
376     sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
377     switch( nCode )
378     {
379     case KEY_DELETE:
380         mrManager.DeleteAnnotation( mxAnnotation );
381         return true;
382 
383     case KEY_DOWN:
384     case KEY_UP:
385     case KEY_LEFT:
386     case KEY_RIGHT:
387         return OnMove( rKEvt );
388 
389     case KEY_ESCAPE:
390     {
391         SmartTagReference xThis( this );
392         mrView.getSmartTags().deselect();
393         return true;
394     }
395 
396     case KEY_TAB:
397         mrManager.SelectNextAnnotation(!rKEvt.GetKeyCode().IsShift());
398         return true;
399 
400     case KEY_RETURN:
401     case KEY_SPACE:
402         OpenPopup( true );
403         return true;
404 
405     default:
406         return false;
407     }
408 }
409 
410 /** returns true if the SmartTag consumes this event. */
RequestHelp(const HelpEvent &)411 bool AnnotationTag::RequestHelp( const HelpEvent& /*rHEvt*/ )
412 {
413 /*
414     ::Window* pWindow = mrView.GetViewShell()->GetActiveWindow();
415     if( mxAnnotation.is() && pWindow )
416     {
417         OUString aHelpText( mrManager.GetHelpText( mxAnnotation ) );
418 
419         RealPoint2D aPosition( mxAnnotation->getPosition() );
420         Point aPos( pWindow->LogicToPixel( Point( static_cast<long>(aPosition.X * 100.0), static_cast<long>(aPosition.Y * 100.0) ) ) );
421 
422         Rectangle aRect( aPos, maSize );
423 
424         if (Help::IsBalloonHelpEnabled())
425             Help::ShowBalloon( pWindow, aPos, aRect, aHelpText);
426         else if (Help::IsQuickHelpEnabled())
427             Help::ShowQuickHelp( pWindow, aRect, aHelpText);
428 
429         return true;
430    }
431 */
432    return false;
433 }
434 
435 /** returns true if the SmartTag consumes this event. */
Command(const CommandEvent & rCEvt)436 bool AnnotationTag::Command( const CommandEvent& rCEvt )
437 {
438     if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
439     {
440         ::Window* pWindow = mrView.GetViewShell()->GetActiveWindow();
441         if( pWindow )
442         {
443             Rectangle aContextRect(rCEvt.GetMousePosPixel(),Size(1,1));
444             mrManager.ExecuteAnnotationContextMenu( mxAnnotation, pWindow, aContextRect );
445             return true;
446         }
447     }
448 
449     return false;
450 }
451 
Move(int nDX,int nDY)452 void AnnotationTag::Move( int nDX, int nDY )
453 {
454     if( mxAnnotation.is() )
455     {
456         if( mrManager.GetDoc()->IsUndoEnabled() )
457             mrManager.GetDoc()->BegUndo( String( SdResId( STR_ANNOTATION_UNDO_MOVE ) ) );
458 
459         RealPoint2D aPosition( mxAnnotation->getPosition() );
460         aPosition.X += (double)nDX / 100.0;
461         aPosition.Y += (double)nDY / 100.0;
462         mxAnnotation->setPosition( aPosition );
463 
464         if( mrManager.GetDoc()->IsUndoEnabled() )
465             mrManager.GetDoc()->EndUndo();
466 
467         mrView.updateHandles();
468     }
469 }
470 
OnMove(const KeyEvent & rKEvt)471 bool AnnotationTag::OnMove( const KeyEvent& rKEvt )
472 {
473     long nX = 0;
474     long nY = 0;
475 
476     switch( rKEvt.GetKeyCode().GetCode() )
477     {
478     case KEY_UP:    nY = -1; break;
479     case KEY_DOWN:  nY =  1; break;
480     case KEY_LEFT:  nX = -1; break;
481     case KEY_RIGHT: nX =  1; break;
482     default: break;
483     }
484 
485     if(rKEvt.GetKeyCode().IsMod2())
486     {
487         OutputDevice* pOut = mrView.GetViewShell()->GetActiveWindow();
488         Size aLogicSizeOnePixel = (pOut) ? pOut->PixelToLogic(Size(1,1)) : Size(100, 100);
489         nX *= aLogicSizeOnePixel.Width();
490         nY *= aLogicSizeOnePixel.Height();
491     }
492     else
493     {
494         // old, fixed move distance
495         nX *= 100;
496         nY *= 100;
497     }
498 
499     if( nX || nY )
500     {
501         // move the annotation
502         Move( nX, nY );
503     }
504 
505     return true;
506 }
507 
508 // --------------------------------------------------------------------
509 
CheckPossibilities()510 void AnnotationTag::CheckPossibilities()
511 {
512 }
513 
514 // --------------------------------------------------------------------
515 
GetMarkablePointCount() const516 sal_uLong AnnotationTag::GetMarkablePointCount() const
517 {
518     return 0;
519 }
520 
521 // --------------------------------------------------------------------
522 
GetMarkedPointCount() const523 sal_uLong AnnotationTag::GetMarkedPointCount() const
524 {
525     return 0;
526 }
527 
528 // --------------------------------------------------------------------
529 
MarkPoint(SdrHdl &,sal_Bool)530 sal_Bool AnnotationTag::MarkPoint(SdrHdl& /*rHdl*/, sal_Bool /*bUnmark*/ )
531 {
532     sal_Bool bRet=sal_False;
533     return bRet;
534 }
535 
536 // --------------------------------------------------------------------
537 
MarkPoints(const Rectangle *,sal_Bool)538 sal_Bool AnnotationTag::MarkPoints(const Rectangle* /*pRect*/, sal_Bool /*bUnmark*/ )
539 {
540     sal_Bool bChgd=sal_False;
541     return bChgd;
542 }
543 
544 // --------------------------------------------------------------------
545 
getContext(SdrViewContext &)546 bool AnnotationTag::getContext( SdrViewContext& /*rContext*/ )
547 {
548     return false;
549 }
550 
551 // --------------------------------------------------------------------
552 
addCustomHandles(SdrHdlList & rHandlerList)553 void AnnotationTag::addCustomHandles( SdrHdlList& rHandlerList )
554 {
555     if( mxAnnotation.is() )
556     {
557         SmartTagReference xThis( this );
558         Point aPoint;
559         AnnotationHdl* pHdl = new AnnotationHdl( xThis, mxAnnotation, aPoint );
560         pHdl->SetObjHdlNum( SMART_TAG_HDL_NUM );
561         pHdl->SetPageView( mrView.GetSdrPageView() );
562 
563         RealPoint2D aPosition( mxAnnotation->getPosition() );
564         Point aBasePos( static_cast<long>(aPosition.X * 100.0), static_cast<long>(aPosition.Y * 100.0) );
565         pHdl->SetPos( aBasePos );
566 
567         rHandlerList.AddHdl( pHdl );
568     }
569 }
570 
571 // --------------------------------------------------------------------
572 
disposing()573 void AnnotationTag::disposing()
574 {
575     if( mpListenWindow )
576     {
577         mpListenWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler));
578     }
579 
580     if( mnClosePopupEvent )
581     {
582         Application::RemoveUserEvent( mnClosePopupEvent );
583         mnClosePopupEvent = 0;
584     }
585 
586     mxAnnotation.clear();
587     ClosePopup();
588     SmartTag::disposing();
589 }
590 
591 // --------------------------------------------------------------------
592 
select()593 void AnnotationTag::select()
594 {
595     SmartTag::select();
596 
597     mrManager.onTagSelected( *this );
598 
599     Window* pWindow = mrView.GetViewShell()->GetActiveWindow();
600     if( pWindow )
601     {
602         RealPoint2D aPosition( mxAnnotation->getPosition() );
603         Point aPos( static_cast<long>(aPosition.X * 100.0), static_cast<long>(aPosition.Y * 100.0) );
604 
605         Rectangle aVisRect( aPos, pWindow->PixelToLogic(maSize) );
606         mrView.MakeVisible(aVisRect, *pWindow);
607     }
608 }
609 
610 // --------------------------------------------------------------------
611 
deselect()612 void AnnotationTag::deselect()
613 {
614     SmartTag::deselect();
615 
616     ClosePopup();
617 
618     mrManager.onTagDeselected( *this );
619 }
620 
621 // --------------------------------------------------------------------
622 
CreateAnnotationBitmap(bool bSelected)623 BitmapEx AnnotationTag::CreateAnnotationBitmap( bool bSelected )
624 {
625     VirtualDevice aVDev;
626 
627     OUString sAuthor( getInitials( mxAnnotation->getAuthor() ) );
628     sAuthor += OUString( sal_Unicode( ' ' ) );
629     sAuthor += OUString::valueOf( (sal_Int32)mnIndex );
630 
631     aVDev.SetFont( mrFont );
632 
633     const int BORDER_X = 4; // pixels
634     const int BORDER_Y = 4; // pixels
635 
636     maSize = Size( aVDev.GetTextWidth( sAuthor ) + 2*BORDER_X, aVDev.GetTextHeight() + 2*BORDER_Y );
637     aVDev.SetOutputSizePixel( maSize, sal_False );
638 
639     Color aBorderColor( maColor );
640 
641     if( bSelected )
642     {
643         aBorderColor.Invert();
644     }
645     else
646     {
647         if( maColor.IsDark() )
648         {
649             aBorderColor.IncreaseLuminance( 32 );
650         }
651         else
652         {
653             aBorderColor.DecreaseLuminance( 32 );
654         }
655     }
656 
657     Point aPos;
658     Rectangle aBorderRect( aPos, maSize );
659     aVDev.SetLineColor(aBorderColor);
660     aVDev.SetFillColor(maColor);
661     aVDev.DrawRect( aBorderRect );
662 
663     aVDev.SetTextColor( maColor.IsDark() ? COL_WHITE : COL_BLACK );
664     aVDev.DrawText( Point( BORDER_X, BORDER_Y ), sAuthor );
665 
666     return aVDev.GetBitmapEx( aPos, maSize );
667 }
668 
OpenPopup(bool bEdit)669 void AnnotationTag::OpenPopup( bool bEdit )
670 {
671     if( !mxAnnotation.is() )
672         return;
673 
674     if( !mpAnnotationWindow.get() )
675     {
676         ::Window* pWindow = dynamic_cast< ::Window* >( getView().GetFirstOutputDevice() );
677         if( pWindow )
678         {
679             RealPoint2D aPosition( mxAnnotation->getPosition() );
680             Point aPos( pWindow->OutputToScreenPixel( pWindow->LogicToPixel( Point( static_cast<long>(aPosition.X * 100.0), static_cast<long>(aPosition.Y * 100.0) ) ) ) );
681 
682             aPos.X() += 4; // magic!
683             aPos.Y() += 1;
684 
685             Rectangle aRect( aPos, maSize );
686 
687             mpAnnotationWindow.reset( new AnnotationWindow( mrManager, mrView.GetDocSh(), pWindow->GetWindow(WINDOW_FRAME) ) );
688             mpAnnotationWindow->InitControls();
689             mpAnnotationWindow->setAnnotation(mxAnnotation);
690 
691             sal_uInt16 nArrangeIndex = 0;
692             Point aPopupPos( FloatingWindow::CalcFloatingPosition( mpAnnotationWindow.get(), aRect, FLOATWIN_POPUPMODE_RIGHT, nArrangeIndex ) );
693             Size aPopupSize( 320, 240 );
694 
695             mpAnnotationWindow->SetPosSizePixel( aPopupPos, aPopupSize );
696             mpAnnotationWindow->DoResize();
697 
698             mpAnnotationWindow->Show();
699             mpAnnotationWindow->GrabFocus();
700             mpAnnotationWindow->AddEventListener( LINK(this, AnnotationTag, WindowEventHandler));
701         }
702     }
703 
704     if( bEdit && mpAnnotationWindow.get() )
705         mpAnnotationWindow->StartEdit();
706 }
707 
ClosePopup()708 void AnnotationTag::ClosePopup()
709 {
710     if( mpAnnotationWindow.get() )
711     {
712         mpAnnotationWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler));
713         mpAnnotationWindow->Deactivate();
714         mpAnnotationWindow.reset();
715     }
716 }
717 
IMPL_LINK(AnnotationTag,WindowEventHandler,VclWindowEvent *,pEvent)718 IMPL_LINK(AnnotationTag, WindowEventHandler, VclWindowEvent*, pEvent)
719 {
720     if( pEvent != NULL )
721     {
722         ::Window* pWindow = pEvent->GetWindow();
723 
724         if( pWindow )
725         {
726             if( pWindow == mpAnnotationWindow.get() )
727             {
728                 if( pEvent->GetId() == VCLEVENT_WINDOW_DEACTIVATE )
729                 {
730                     if( mnClosePopupEvent )
731                         Application::RemoveUserEvent( mnClosePopupEvent );
732 
733                     mnClosePopupEvent = Application::PostUserEvent( LINK( this, AnnotationTag, ClosePopupHdl ) );
734                 }
735             }
736             else if( pWindow == mpListenWindow )
737             {
738                 switch( pEvent->GetId() )
739                 {
740                 case VCLEVENT_WINDOW_MOUSEBUTTONUP:
741                     {
742                         // if we stop pressing the button without a mouse move we open the popup
743                         mpListenWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler));
744                         mpListenWindow = 0;
745                         if( mpAnnotationWindow.get() == 0 )
746                             OpenPopup(false);
747                     }
748                     break;
749                 case VCLEVENT_WINDOW_MOUSEMOVE:
750                     {
751                         // if we move the mouse after a button down we wan't to start draging
752                         mpListenWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler));
753                         mpListenWindow = 0;
754 
755                         SdrHdl* pHdl = mrView.PickHandle(maMouseDownPos);
756                         if( pHdl )
757                         {
758                             mrView.BrkAction();
759                             const sal_uInt16 nDrgLog = (sal_uInt16)pWindow->PixelToLogic(Size(DRGPIX,0)).Width();
760 
761                             rtl::Reference< AnnotationTag > xTag( this );
762 
763                             SdrDragMethod* pDragMethod = new AnnotationDragMove( mrView, xTag );
764                             mrView.BegDragObj(maMouseDownPos, NULL, pHdl, nDrgLog, pDragMethod );
765                         }
766                     }
767                     break;
768                 case VCLEVENT_OBJECT_DYING:
769                     mpListenWindow = 0;
770                     break;
771                 }
772             }
773         }
774     }
775     return sal_True;
776 }
777 
IMPL_LINK(AnnotationTag,ClosePopupHdl,void *,EMPTYARG)778 IMPL_LINK( AnnotationTag, ClosePopupHdl, void *, EMPTYARG )
779 {
780     mnClosePopupEvent = 0;
781     ClosePopup();
782     return 0;
783 }
784 
785 } // end of namespace sd
786 
787