1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
36 #include <com/sun/star/frame/XFrame.hpp>
37 #include <sfx2/imagemgr.hxx>
38 #include <sfx2/viewfrm.hxx>
39 #include <sfx2/bindings.hxx>
40 #include <sfx2/app.hxx>
41 #include <sfx2/request.hxx>
42 #include <sfx2/dispatch.hxx>
44 #include <tools/rcid.h>
46 #include <vcl/help.hxx>
47 #include <vcl/imagerepository.hxx>
48 #include <vcl/lazydelete.hxx>
50 #include <svx/sdrpagewindow.hxx>
51 #include <svx/sdrpaintwindow.hxx>
52 #include <svx/sdr/overlay/overlayanimatedbitmapex.hxx>
53 #include <svx/sdr/overlay/overlaybitmapex.hxx>
54 #include <svx/sdr/overlay/overlaymanager.hxx>
55 #include <svx/svxids.hrc>
57 #include "view/viewoverlaymanager.hxx"
59 #include "res_bmp.hrc"
60 #include "DrawDocShell.hxx"
61 #include "DrawViewShell.hxx"
62 #include "DrawController.hxx"
64 #include "strings.hrc"
65 #include "sdresid.hxx"
66 #include "EventMultiplexer.hxx"
67 #include "ViewShellManager.hxx"
70 #include "drawdoc.hxx"
71 #include "smarttag.hxx"
73 using ::rtl::OUString
;
74 using namespace ::com::sun::star::uno
;
75 using namespace ::com::sun::star::frame
;
81 // --------------------------------------------------------------------
83 static sal_uInt16 gButtonSlots
[] = { SID_INSERT_TABLE
, SID_INSERT_DIAGRAM
, SID_INSERT_GRAPHIC
, SID_INSERT_AVMEDIA
};
84 static sal_uInt16 gButtonToolTips
[] = { STR_INSERT_TABLE
, STR_INSERT_CHART
, STR_INSERT_PICTURE
, STR_INSERT_MOVIE
};
86 // --------------------------------------------------------------------
88 static BitmapEx
loadImageResource( sal_uInt16 nId
)
90 SdResId
aResId( nId
);
91 aResId
.SetRT( RSC_BITMAP
);
93 return BitmapEx( aResId
);
96 // --------------------------------------------------------------------
98 static BitmapEx
* getButtonImage( int index
, bool large
)
100 static vcl::DeleteOnDeinit
< BitmapEx
> gSmallButtonImages
[BMP_PLACEHOLDER_SMALL_END
- BMP_PLACEHOLDER_SMALL_START
] = { 0, 0, 0, 0, 0, 0, 0, 0 };
101 static vcl::DeleteOnDeinit
< BitmapEx
> gLargeButtonImages
[BMP_PLACEHOLDER_LARGE_END
- BMP_PLACEHOLDER_LARGE_START
] = { 0, 0, 0, 0, 0, 0, 0, 0 };
103 if( !gSmallButtonImages
[0].get() )
105 for( sal_uInt16 i
= 0; i
< (BMP_PLACEHOLDER_SMALL_END
-BMP_PLACEHOLDER_SMALL_START
); i
++ )
107 gSmallButtonImages
[i
].set( new BitmapEx( loadImageResource( BMP_PLACEHOLDER_SMALL_START
+ i
) ) );
108 gLargeButtonImages
[i
].set( new BitmapEx( loadImageResource( BMP_PLACEHOLDER_LARGE_START
+ i
) ) );
114 return gLargeButtonImages
[index
].get();
118 return gSmallButtonImages
[index
].get();
122 // --------------------------------------------------------------------
124 const sal_uInt32 SMART_TAG_HDL_NUM
= SAL_MAX_UINT32
;
126 class ChangePlaceholderTag
: public SmartTag
128 friend class ImageButtonHdl
;
130 ChangePlaceholderTag( ViewOverlayManager
& rManager
, ::sd::View
& rView
, SdrObject
& rPlaceholderObj
);
131 virtual ~ChangePlaceholderTag();
133 /** returns true if the SmartTag handled the event. */
134 virtual bool MouseButtonDown( const MouseEvent
&, SmartHdl
& );
136 /** returns true if the SmartTag consumes this event. */
137 virtual bool KeyInput( const KeyEvent
& rKEvt
);
139 BitmapEx
createOverlayImage( int nHighlight
= -1 );
142 virtual void addCustomHandles( SdrHdlList
& rHandlerList
);
143 virtual void disposing();
144 virtual void select();
145 virtual void deselect();
148 ViewOverlayManager
& mrManager
;
149 SdrObjectWeakRef mxPlaceholderObj
;
152 class ImageButtonHdl
: public SmartHdl
155 ImageButtonHdl( const SmartTagReference
& xTag
, /* sal_uInt16 nSID, const Image& rImage, const Image& rImageMO, */ const Point
& rPnt
);
156 virtual ~ImageButtonHdl();
157 virtual void CreateB2dIAObject();
158 virtual sal_Bool
IsFocusHdl() const;
159 virtual Pointer
GetPointer() const;
160 virtual bool isMarkable() const;
162 virtual void onMouseEnter(const MouseEvent
& rMEvt
);
163 virtual void onMouseLeave();
165 int getHighlightId() const { return mnHighlightId
; }
170 rtl::Reference
< ChangePlaceholderTag
> mxTag
;
177 // --------------------------------------------------------------------
179 ImageButtonHdl::ImageButtonHdl( const SmartTagReference
& xTag
/*, sal_uInt16 nSID, const Image& rImage, const Image& rImageMO*/, const Point
& rPnt
)
180 : SmartHdl( xTag
, rPnt
)
181 , mxTag( dynamic_cast< ChangePlaceholderTag
* >( xTag
.get() ) )
182 , mnHighlightId( -1 )
183 , maImageSize( 42, 42 )
188 // --------------------------------------------------------------------
190 ImageButtonHdl::~ImageButtonHdl()
195 // --------------------------------------------------------------------
197 void ImageButtonHdl::HideTip()
201 Help::HideTip( mnTip
);
206 // --------------------------------------------------------------------
208 extern ::rtl::OUString
ImplRetrieveLabelFromCommand( const Reference
< XFrame
>& xFrame
, const OUString
& aCmdURL
);
210 void ImageButtonHdl::onMouseEnter(const MouseEvent
& rMEvt
)
212 int nHighlightId
= 0;
214 if( pHdlList
&& pHdlList
->GetView())
216 OutputDevice
* pDev
= pHdlList
->GetView()->GetFirstOutputDevice();
218 pDev
= Application::GetDefaultDevice();
220 Point
aMDPos( rMEvt
.GetPosPixel() );
221 aMDPos
-= pDev
->LogicToPixel( GetPos() );
223 nHighlightId
+= aMDPos
.X() > maImageSize
.Width() ? 1 : 0;
224 nHighlightId
+= aMDPos
.Y() > maImageSize
.Height() ? 2 : 0;
226 if( mnHighlightId
!= nHighlightId
)
230 mnHighlightId
= nHighlightId
;
234 SdResId
aResId( gButtonToolTips
[mnHighlightId
] );
235 aResId
.SetRT( RSC_STRING
);
237 String
aHelpText( aResId
);
238 Rectangle
aScreenRect( pDev
->LogicToPixel( GetPos() ), maImageSize
);
239 mnTip
= Help::ShowTip( static_cast< ::Window
* >( pHdlList
->GetView()->GetFirstOutputDevice() ), aScreenRect
, aHelpText
, 0 ) ;
246 // --------------------------------------------------------------------
248 void ImageButtonHdl::onMouseLeave()
255 // --------------------------------------------------------------------
257 void ImageButtonHdl::CreateB2dIAObject()
259 // first throw away old one
262 const Point
aTagPos( GetPos() );
263 basegfx::B2DPoint
aPosition( aTagPos
.X(), aTagPos
.Y() );
265 BitmapEx
aBitmapEx( mxTag
->createOverlayImage( mnHighlightId
) ); // maImageMO.GetBitmapEx() : maImage.GetBitmapEx() );
266 maImageSize
= aBitmapEx
.GetSizePixel();
267 maImageSize
.Width() >>= 1;
268 maImageSize
.Height() >>= 1;
272 SdrMarkView
* pView
= pHdlList
->GetView();
274 if(pView
&& !pView
->areMarkHandlesHidden())
276 SdrPageView
* pPageView
= pView
->GetSdrPageView();
280 for(sal_uInt32 b
= 0; b
< pPageView
->PageWindowCount(); b
++)
282 const SdrPageWindow
& rPageWindow
= *pPageView
->GetPageWindow(b
);
284 SdrPaintWindow
& rPaintWindow
= rPageWindow
.GetPaintWindow();
285 if(rPaintWindow
.OutputToWindow() && rPageWindow
.GetOverlayManager() )
287 ::sdr::overlay::OverlayObject
* pOverlayObject
= 0;
289 pOverlayObject
= new ::sdr::overlay::OverlayBitmapEx( aPosition
, aBitmapEx
, 0, 0 );
290 rPageWindow
.GetOverlayManager()->add(*pOverlayObject
);
291 maOverlayGroup
.append(*pOverlayObject
);
299 // --------------------------------------------------------------------
301 sal_Bool
ImageButtonHdl::IsFocusHdl() const
306 // --------------------------------------------------------------------
308 bool ImageButtonHdl::isMarkable() const
313 // --------------------------------------------------------------------
315 Pointer
ImageButtonHdl::GetPointer() const
317 return Pointer( POINTER_ARROW
);
320 // ====================================================================
322 ChangePlaceholderTag::ChangePlaceholderTag( ViewOverlayManager
& rManager
, ::sd::View
& rView
, SdrObject
& rPlaceholderObj
)
324 , mrManager( rManager
)
325 , mxPlaceholderObj( &rPlaceholderObj
)
329 // --------------------------------------------------------------------
331 ChangePlaceholderTag::~ChangePlaceholderTag()
335 // --------------------------------------------------------------------
337 /** returns true if the ChangePlaceholderTag handled the event. */
338 bool ChangePlaceholderTag::MouseButtonDown( const MouseEvent
& /*rMEvt*/, SmartHdl
& rHdl
)
340 int nHighlightId
= static_cast< ImageButtonHdl
& >(rHdl
).getHighlightId();
341 if( nHighlightId
>= 0 )
343 sal_uInt16 nSID
= gButtonSlots
[nHighlightId
];
345 if( mxPlaceholderObj
.get() )
347 // mark placeholder if it is not currently marked (or if also others are marked)
348 if( !mrView
.IsObjMarked( mxPlaceholderObj
.get() ) || (mrView
.GetMarkedObjectList().GetMarkCount() != 1) )
350 SdrPageView
* pPV
= mrView
.GetSdrPageView();
351 mrView
.UnmarkAllObj(pPV
);
352 mrView
.MarkObj(mxPlaceholderObj
.get(), pPV
, sal_False
);
356 mrView
.GetViewShell()->GetViewFrame()->GetDispatcher()->Execute( nSID
, SFX_CALLMODE_ASYNCHRON
);
361 // --------------------------------------------------------------------
363 /** returns true if the SmartTag consumes this event. */
364 bool ChangePlaceholderTag::KeyInput( const KeyEvent
& rKEvt
)
366 sal_uInt16 nCode
= rKEvt
.GetKeyCode().GetCode();
382 // --------------------------------------------------------------------
384 BitmapEx
ChangePlaceholderTag::createOverlayImage( int nHighlight
)
387 if( mxPlaceholderObj
.is() )
389 SdrObject
* pPlaceholder
= mxPlaceholderObj
.get();
390 SmartTagReference
xThis( this );
391 const Rectangle
& rSnapRect
= pPlaceholder
->GetSnapRect();
394 OutputDevice
* pDev
= mrView
.GetFirstOutputDevice();
396 pDev
= Application::GetDefaultDevice();
398 Size aShapeSizePix
= pDev
->LogicToPixel(rSnapRect
.GetSize());
399 long nShapeSizePix
= std::min(aShapeSizePix
.Width(),aShapeSizePix
.Height());
401 bool bLarge
= nShapeSizePix
> 250;
403 Size
aSize( getButtonImage( 0, bLarge
)->GetSizePixel() );
405 aRet
.SetSizePixel( Size( aSize
.Width() << 1, aSize
.Height() << 1 ) );
407 const Rectangle
aRectSrc( Point( 0, 0 ), aSize
);
409 aRet
= *(getButtonImage((nHighlight
== 0) ? 4 : 0, bLarge
));
410 aRet
.Expand( aSize
.Width(), aSize
.Height(), NULL
, sal_True
);
412 aRet
.CopyPixel( Rectangle( Point( aSize
.Width(), 0 ), aSize
), aRectSrc
, getButtonImage((nHighlight
== 1) ? 5 : 1, bLarge
) );
413 aRet
.CopyPixel( Rectangle( Point( 0, aSize
.Height() ), aSize
), aRectSrc
, getButtonImage((nHighlight
== 2) ? 6 : 2, bLarge
) );
414 aRet
.CopyPixel( Rectangle( Point( aSize
.Width(), aSize
.Height() ), aSize
), aRectSrc
, getButtonImage((nHighlight
== 3) ? 7 : 3, bLarge
) );
420 void ChangePlaceholderTag::addCustomHandles( SdrHdlList
& rHandlerList
)
422 if( mxPlaceholderObj
.is() )
424 SdrObject
* pPlaceholder
= mxPlaceholderObj
.get();
425 SmartTagReference
xThis( this );
426 const Rectangle
& rSnapRect
= pPlaceholder
->GetSnapRect();
429 OutputDevice
* pDev
= mrView
.GetFirstOutputDevice();
431 pDev
= Application::GetDefaultDevice();
433 Size aShapeSizePix
= pDev
->LogicToPixel(rSnapRect
.GetSize());
434 long nShapeSizePix
= std::min(aShapeSizePix
.Width(),aShapeSizePix
.Height());
435 if( 50 > nShapeSizePix
)
438 bool bLarge
= nShapeSizePix
> 250;
440 Size
aButtonSize( pDev
->PixelToLogic( getButtonImage(0, bLarge
)->GetSizePixel()) );
442 const int nColumns
= 2;
445 long all_width
= nColumns
* aButtonSize
.Width();
446 long all_height
= nRows
* aButtonSize
.Height();
448 Point
aPos( rSnapRect
.Center() );
449 aPos
.X() -= all_width
>> 1;
450 aPos
.Y() -= all_height
>> 1;
452 ImageButtonHdl
* pHdl
= new ImageButtonHdl( xThis
, aPoint
);
453 pHdl
->SetObjHdlNum( SMART_TAG_HDL_NUM
);
454 pHdl
->SetPageView( mrView
.GetSdrPageView() );
456 pHdl
->SetPos( aPos
);
458 rHandlerList
.AddHdl( pHdl
);
462 // --------------------------------------------------------------------
464 void ChangePlaceholderTag::disposing()
466 SmartTag::disposing();
469 // --------------------------------------------------------------------
471 void ChangePlaceholderTag::select()
476 // --------------------------------------------------------------------
478 void ChangePlaceholderTag::deselect()
480 SmartTag::deselect();
483 // --------------------------------------------------------------------
485 ViewOverlayManager::ViewOverlayManager( ViewShellBase
& rViewShellBase
)
486 : mrBase( rViewShellBase
)
487 , mnUpdateTagsEvent( 0 )
489 Link
aLink( LINK(this,ViewOverlayManager
,EventMultiplexerListener
) );
490 mrBase
.GetEventMultiplexer()->AddEventListener(aLink
, tools::EventMultiplexerEvent::EID_CURRENT_PAGE
491 | tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
492 | tools::EventMultiplexerEvent::EID_VIEW_ADDED
493 | tools::EventMultiplexerEvent::EID_BEGIN_TEXT_EDIT
494 | tools::EventMultiplexerEvent::EID_END_TEXT_EDIT
);
496 StartListening( *mrBase
.GetDocShell() );
499 // --------------------------------------------------------------------
501 ViewOverlayManager::~ViewOverlayManager()
503 Link
aLink( LINK(this,ViewOverlayManager
,EventMultiplexerListener
) );
504 mrBase
.GetEventMultiplexer()->RemoveEventListener( aLink
);
506 if( mnUpdateTagsEvent
)
508 Application::RemoveUserEvent( mnUpdateTagsEvent
);
509 mnUpdateTagsEvent
= 0;
515 // --------------------------------------------------------------------
517 void ViewOverlayManager::Notify(SfxBroadcaster
&, const SfxHint
& rHint
)
519 const SfxSimpleHint
* pSimpleHint
= dynamic_cast<const SfxSimpleHint
*>(&rHint
);
520 if (pSimpleHint
!= NULL
)
522 if (pSimpleHint
->GetId() == SFX_HINT_DOCCHANGED
)
529 void ViewOverlayManager::onZoomChanged()
531 if( !maTagVector
.empty() )
537 void ViewOverlayManager::UpdateTags()
539 if( !mnUpdateTagsEvent
)
540 mnUpdateTagsEvent
= Application::PostUserEvent( LINK( this, ViewOverlayManager
, UpdateTagsHdl
) );
543 IMPL_LINK(ViewOverlayManager
,UpdateTagsHdl
, void *, EMPTYARG
)
545 OSL_TRACE("ViewOverlayManager::UpdateTagsHdl");
547 mnUpdateTagsEvent
= 0;
548 bool bChanges
= DisposeTags();
549 bChanges
|= CreateTags();
551 if( bChanges
&& mrBase
.GetDrawView() )
552 static_cast< ::sd::View
* >( mrBase
.GetDrawView() )->updateHandles();
556 bool ViewOverlayManager::CreateTags()
558 bool bChanges
= false;
560 SdPage
* pPage
= mrBase
.GetMainViewShell()->getCurrentPage();
562 if( pPage
&& !pPage
->IsMasterPage() && (pPage
->GetPageKind() == PK_STANDARD
) )
564 const std::list
< SdrObject
* >& rShapes
= pPage
->GetPresentationShapeList().getList();
566 for( std::list
< SdrObject
* >::const_iterator
iter( rShapes
.begin() ); iter
!= rShapes
.end(); iter
++ )
568 if( (*iter
)->IsEmptyPresObj() && ((*iter
)->GetObjIdentifier() == OBJ_OUTLINETEXT
) && (mrBase
.GetDrawView()->GetTextEditObject() != (*iter
)) )
570 rtl::Reference
< SmartTag
> xTag( new ChangePlaceholderTag( *this, *mrBase
.GetMainViewShell()->GetView(), *(*iter
) ) );
571 maTagVector
.push_back(xTag
);
580 // --------------------------------------------------------------------
582 bool ViewOverlayManager::DisposeTags()
584 if( !maTagVector
.empty() )
587 vec
.swap( maTagVector
);
589 ViewTagVector::iterator iter
= vec
.begin();
592 (*iter
++)->Dispose();
594 while( iter
!= vec
.end() );
601 // --------------------------------------------------------------------
603 IMPL_LINK(ViewOverlayManager
,EventMultiplexerListener
,
604 tools::EventMultiplexerEvent
*,pEvent
)
606 switch (pEvent
->meEventId
)
608 case tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
:
609 case tools::EventMultiplexerEvent::EID_VIEW_ADDED
:
610 case tools::EventMultiplexerEvent::EID_BEGIN_TEXT_EDIT
:
611 case tools::EventMultiplexerEvent::EID_END_TEXT_EDIT
:
612 case tools::EventMultiplexerEvent::EID_CURRENT_PAGE
: