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