1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_features.h>
22 #include <vcl/svapp.hxx>
23 #include <sfx2/viewfrm.hxx>
24 #include <sfx2/dispatch.hxx>
25 #include <sfx2/sfxsids.hrc>
26 #include <avmedia/mediaplayer.hxx>
28 #include <galbrws2.hxx>
29 #include <svx/dialmgr.hxx>
30 #include <svx/galtheme.hxx>
31 #include <svx/galmisc.hxx>
32 #include <svx/galctrl.hxx>
33 #include <editeng/AccessibleStringWrap.hxx>
34 #include <editeng/svxfont.hxx>
36 #include <avmedia/mediawindow.hxx>
37 #include <svx/strings.hrc>
38 #include <vcl/event.hxx>
39 #include <vcl/commandevent.hxx>
40 #include <vcl/graphicfilter.hxx>
41 #include <vcl/settings.hxx>
42 #include <bitmaps.hlst>
44 #define GALLERY_BRWBOX_TITLE 1
46 GalleryPreview::GalleryPreview(vcl::Window
* pParent
, WinBits nStyle
, GalleryTheme
* pTheme
)
47 : Window(pParent
, nStyle
)
48 , DropTargetHelper(this)
49 , DragSourceHelper(this)
52 SetHelpId( HID_GALLERY_WINDOW
);
56 Size
GalleryPreview::GetOptimalSize() const
58 return LogicToPixel(Size(70, 88), MapMode(MapUnit::MapAppFont
));
61 void GalleryPreview::InitSettings()
63 SetBackground( Wallpaper( GALLERY_BG_COLOR
) );
64 SetControlBackground( GALLERY_BG_COLOR
);
65 SetControlForeground( GALLERY_FG_COLOR
);
68 void GalleryPreview::DataChanged( const DataChangedEvent
& rDCEvt
)
70 if ( ( rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) && ( rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
73 Window::DataChanged( rDCEvt
);
76 bool GalleryPreview::ImplGetGraphicCenterRect( const Graphic
& rGraphic
, tools::Rectangle
& rResultRect
) const
78 const Size
aWinSize( GetOutputSizePixel() );
79 Size
aNewSize( LogicToPixel( rGraphic
.GetPrefSize(), rGraphic
.GetPrefMapMode() ) );
82 if( aNewSize
.Width() && aNewSize
.Height() )
84 // scale to fit window
85 const double fGrfWH
= static_cast<double>(aNewSize
.Width()) / aNewSize
.Height();
86 const double fWinWH
= static_cast<double>(aWinSize
.Width()) / aWinSize
.Height();
88 if ( fGrfWH
< fWinWH
)
90 aNewSize
.setWidth( static_cast<long>( aWinSize
.Height() * fGrfWH
) );
91 aNewSize
.setHeight( aWinSize
.Height() );
95 aNewSize
.setWidth( aWinSize
.Width() );
96 aNewSize
.setHeight( static_cast<long>( aWinSize
.Width() / fGrfWH
) );
99 const Point
aNewPos( ( aWinSize
.Width() - aNewSize
.Width() ) >> 1,
100 ( aWinSize
.Height() - aNewSize
.Height() ) >> 1 );
102 rResultRect
= tools::Rectangle( aNewPos
, aNewSize
);
109 void GalleryPreview::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
)
111 Window::Paint(rRenderContext
, rRect
);
113 if (ImplGetGraphicCenterRect(aGraphicObj
.GetGraphic(), aPreviewRect
))
115 const Point
aPos( aPreviewRect
.TopLeft() );
116 const Size
aSize( aPreviewRect
.GetSize() );
118 if( aGraphicObj
.IsAnimated() )
119 aGraphicObj
.StartAnimation(&rRenderContext
, aPos
, aSize
);
121 aGraphicObj
.Draw(&rRenderContext
, aPos
, aSize
);
125 void GalleryPreview::MouseButtonDown(const MouseEvent
& rMEvt
)
127 if (mpTheme
&& (rMEvt
.GetClicks() == 2))
128 static_cast<GalleryBrowser2
*>(GetParent())->TogglePreview();
131 void GalleryPreview::Command(const CommandEvent
& rCEvt
)
133 Window::Command(rCEvt
);
135 if (mpTheme
&& (rCEvt
.GetCommand() == CommandEventId::ContextMenu
))
137 GalleryBrowser2
* pGalleryBrowser
= static_cast<GalleryBrowser2
*>(GetParent());
138 pGalleryBrowser
->ShowContextMenu(rCEvt
.IsMouseEvent() ? &rCEvt
.GetMousePosPixel() : nullptr);
142 void GalleryPreview::KeyInput(const KeyEvent
& rKEvt
)
146 GalleryBrowser2
* pBrowser
= static_cast< GalleryBrowser2
* >( GetParent() );
148 switch( rKEvt
.GetKeyCode().GetCode() )
151 pBrowser
->TogglePreview();
155 pBrowser
->Travel( GalleryBrowserTravel::First
);
159 pBrowser
->Travel( GalleryBrowserTravel::Last
);
164 pBrowser
->Travel( GalleryBrowserTravel::Previous
);
169 pBrowser
->Travel( GalleryBrowserTravel::Next
);
174 if (!pBrowser
->KeyInput(rKEvt
, this))
175 Window::KeyInput(rKEvt
);
182 Window::KeyInput(rKEvt
);
186 sal_Int8
GalleryPreview::AcceptDrop( const AcceptDropEvent
& /*rEvt*/ )
191 nRet
= static_cast<GalleryBrowser2
*>(GetParent())->AcceptDrop(*this);
193 nRet
= DND_ACTION_NONE
;
198 sal_Int8
GalleryPreview::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
203 nRet
= static_cast<GalleryBrowser2
*>(GetParent())->ExecuteDrop(rEvt
);
205 nRet
= DND_ACTION_NONE
;
210 void GalleryPreview::StartDrag( sal_Int8
, const Point
& )
213 static_cast<GalleryBrowser2
*>(GetParent())->StartDrag();
216 void GalleryPreview::PreviewMedia( const INetURLObject
& rURL
)
218 #if HAVE_FEATURE_AVMEDIA
219 if (rURL
.GetProtocol() != INetProtocol::NotValid
)
221 ::avmedia::MediaFloater
* pFloater
= avmedia::getMediaFloater();
225 SfxViewFrame::Current()->GetBindings().GetDispatcher()->Execute( SID_AVMEDIA_PLAYER
, SfxCallMode::SYNCHRON
);
226 pFloater
= avmedia::getMediaFloater();
230 pFloater
->setURL( rURL
.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous
), "", true );
237 SvxGalleryPreview::SvxGalleryPreview()
241 void SvxGalleryPreview::SetDrawingArea(weld::DrawingArea
* pDrawingArea
)
243 CustomWidgetController::SetDrawingArea(pDrawingArea
);
244 Size
aSize(pDrawingArea
->get_ref_device().LogicToPixel(Size(70, 88), MapMode(MapUnit::MapAppFont
)));
245 pDrawingArea
->set_size_request(aSize
.Width(), aSize
.Height());
246 pDrawingArea
->set_help_id(HID_GALLERY_WINDOW
);
249 bool SvxGalleryPreview::SetGraphic( const INetURLObject
& _aURL
)
253 #if HAVE_FEATURE_AVMEDIA
254 if( ::avmedia::MediaWindow::isMediaURL( _aURL
.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous
), "" ) )
256 aGraphic
= BitmapEx(RID_SVXBMP_GALLERY_MEDIA
);
261 GraphicFilter
& rFilter
= GraphicFilter::GetGraphicFilter();
262 GalleryProgress
aProgress( &rFilter
);
263 if( rFilter
.ImportGraphic( aGraphic
, _aURL
) )
267 SetGraphic( aGraphic
);
272 bool SvxGalleryPreview::ImplGetGraphicCenterRect( const Graphic
& rGraphic
, tools::Rectangle
& rResultRect
) const
274 const Size
aWinSize(GetOutputSizePixel());
275 Size
aNewSize(GetDrawingArea()->get_ref_device().LogicToPixel(rGraphic
.GetPrefSize(), rGraphic
.GetPrefMapMode()));
278 if( aNewSize
.Width() && aNewSize
.Height() )
280 // scale to fit window
281 const double fGrfWH
= static_cast<double>(aNewSize
.Width()) / aNewSize
.Height();
282 const double fWinWH
= static_cast<double>(aWinSize
.Width()) / aWinSize
.Height();
284 if ( fGrfWH
< fWinWH
)
286 aNewSize
.setWidth( static_cast<long>( aWinSize
.Height() * fGrfWH
) );
287 aNewSize
.setHeight( aWinSize
.Height() );
291 aNewSize
.setWidth( aWinSize
.Width() );
292 aNewSize
.setHeight( static_cast<long>( aWinSize
.Width() / fGrfWH
) );
295 const Point
aNewPos( ( aWinSize
.Width() - aNewSize
.Width() ) >> 1,
296 ( aWinSize
.Height() - aNewSize
.Height() ) >> 1 );
298 rResultRect
= tools::Rectangle( aNewPos
, aNewSize
);
305 void SvxGalleryPreview::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
&)
307 rRenderContext
.SetBackground(Wallpaper(GALLERY_BG_COLOR
));
309 if (ImplGetGraphicCenterRect(aGraphicObj
.GetGraphic(), aPreviewRect
))
311 const Point
aPos( aPreviewRect
.TopLeft() );
312 const Size
aSize( aPreviewRect
.GetSize() );
314 if( aGraphicObj
.IsAnimated() )
315 aGraphicObj
.StartAnimation(&rRenderContext
, aPos
, aSize
);
317 aGraphicObj
.Draw(&rRenderContext
, aPos
, aSize
);
321 static void drawTransparenceBackground(vcl::RenderContext
& rOut
, const Point
& rPos
, const Size
& rSize
)
324 // draw checkered background
325 static const sal_uInt32
nLen(8);
326 static const Color
aW(COL_WHITE
);
327 static const Color
aG(0xef, 0xef, 0xef);
329 rOut
.DrawCheckered(rPos
, rSize
, nLen
, aW
, aG
);
332 GalleryIconView::GalleryIconView( GalleryBrowser2
* pParent
, GalleryTheme
* pTheme
) :
333 ValueSet( pParent
, WB_TABSTOP
| WB_3DLOOK
| WB_BORDER
| WB_ITEMBORDER
| WB_DOUBLEBORDER
| WB_VSCROLL
| WB_FLATVALUESET
),
334 DropTargetHelper( this ),
335 DragSourceHelper( this ),
339 EnableFullItemMode( false );
341 SetHelpId( HID_GALLERY_WINDOW
);
343 SetExtraSpacing( 2 );
344 SetItemWidth( S_THUMB
+ 6 );
345 SetItemHeight( S_THUMB
+ 6 );
348 void GalleryIconView::InitSettings()
350 SetBackground( Wallpaper( GALLERY_BG_COLOR
) );
351 SetControlBackground( GALLERY_BG_COLOR
);
352 SetControlForeground( GALLERY_FG_COLOR
);
353 SetColor( GALLERY_BG_COLOR
);
356 void GalleryIconView::DataChanged( const DataChangedEvent
& rDCEvt
)
358 if ( ( rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) && ( rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
361 ValueSet::DataChanged( rDCEvt
);
364 void GalleryIconView::UserDraw(const UserDrawEvent
& rUDEvt
)
366 const sal_uInt16 nId
= rUDEvt
.GetItemId();
368 if (!nId
|| !mpTheme
)
371 const tools::Rectangle
& rRect
= rUDEvt
.GetRect();
372 const Size
aSize(rRect
.GetWidth(), rRect
.GetHeight());
375 OUString aItemTextTitle
;
376 OUString aItemTextPath
;
378 mpTheme
->GetPreviewBitmapExAndStrings(nId
- 1, aBitmapEx
, aPreparedSize
, aItemTextTitle
, aItemTextPath
);
380 bool bNeedToCreate(aBitmapEx
.IsEmpty());
382 if (!bNeedToCreate
&& aItemTextTitle
.isEmpty())
384 bNeedToCreate
= true;
387 if (!bNeedToCreate
&& aPreparedSize
!= aSize
)
389 bNeedToCreate
= true;
394 std::unique_ptr
<SgaObject
> pObj
= mpTheme
->AcquireObject(nId
- 1);
398 aBitmapEx
= pObj
->createPreviewBitmapEx(aSize
);
399 aItemTextTitle
= GalleryBrowser2::GetItemText(*pObj
, GalleryItemFlags::Title
);
401 mpTheme
->SetPreviewBitmapExAndStrings(nId
- 1, aBitmapEx
, aSize
, aItemTextTitle
, aItemTextPath
);
405 if (!aBitmapEx
.IsEmpty())
407 const Size
aBitmapExSizePixel(aBitmapEx
.GetSizePixel());
409 ((aSize
.Width() - aBitmapExSizePixel
.Width()) >> 1) + rRect
.Left(),
410 ((aSize
.Height() - aBitmapExSizePixel
.Height()) >> 1) + rRect
.Top());
411 OutputDevice
* pDev
= rUDEvt
.GetRenderContext();
413 if(aBitmapEx
.IsTransparent())
415 // draw checkered background for full rectangle.
416 drawTransparenceBackground(*pDev
, rRect
.TopLeft(), rRect
.GetSize());
419 pDev
->DrawBitmapEx(aPos
, aBitmapEx
);
422 SetItemText(nId
, aItemTextTitle
);
425 void GalleryIconView::MouseButtonDown(const MouseEvent
& rMEvt
)
427 ValueSet::MouseButtonDown(rMEvt
);
429 if (rMEvt
.GetClicks() == 2)
430 static_cast<GalleryBrowser2
*>(GetParent())->TogglePreview();
433 void GalleryIconView::Command(const CommandEvent
& rCEvt
)
435 ValueSet::Command(rCEvt
);
437 if (rCEvt
.GetCommand() == CommandEventId::ContextMenu
)
439 GalleryBrowser2
* pGalleryBrowser
= static_cast<GalleryBrowser2
*>(GetParent());
440 pGalleryBrowser
->ShowContextMenu(rCEvt
.IsMouseEvent() ? &rCEvt
.GetMousePosPixel() : nullptr);
444 void GalleryIconView::KeyInput(const KeyEvent
& rKEvt
)
446 if (!mpTheme
|| !static_cast<GalleryBrowser2
*>(GetParent())->KeyInput(rKEvt
, this))
447 ValueSet::KeyInput(rKEvt
);
450 sal_Int8
GalleryIconView::AcceptDrop(const AcceptDropEvent
& /*rEvt*/)
452 return static_cast<GalleryBrowser2
*>(GetParent())->AcceptDrop(*this);
455 sal_Int8
GalleryIconView::ExecuteDrop(const ExecuteDropEvent
& rEvt
)
457 return static_cast<GalleryBrowser2
*>(GetParent())->ExecuteDrop(rEvt
);
460 void GalleryIconView::StartDrag(sal_Int8
, const Point
&)
462 const CommandEvent
aEvt(GetPointerPosPixel(), CommandEventId::StartDrag
, true);
465 // call this to initiate dragging for ValueSet
466 ValueSet::StartDrag(aEvt
, aRegion
);
467 static_cast<GalleryBrowser2
*>(GetParent())->StartDrag();
470 GalleryListView::GalleryListView( GalleryBrowser2
* pParent
, GalleryTheme
* pTheme
) :
471 BrowseBox( pParent
, WB_TABSTOP
| WB_3DLOOK
| WB_BORDER
),
476 SetHelpId( HID_GALLERY_WINDOW
);
480 SetMode( BrowserMode::AUTO_VSCROLL
| BrowserMode::AUTOSIZE_LASTCOL
| BrowserMode::AUTO_HSCROLL
);
481 SetDataRowHeight( 28 );
482 InsertDataColumn( GALLERY_BRWBOX_TITLE
, SvxResId(RID_SVXSTR_GALLERY_TITLE
), 256 );
485 void GalleryListView::InitSettings()
487 SetBackground( Wallpaper( GALLERY_BG_COLOR
) );
488 SetControlBackground( GALLERY_BG_COLOR
);
489 SetControlForeground( GALLERY_FG_COLOR
);
492 void GalleryListView::DataChanged( const DataChangedEvent
& rDCEvt
)
494 if ( ( rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) && ( rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
497 BrowseBox::DataChanged( rDCEvt
);
500 bool GalleryListView::SeekRow( long nRow
)
506 OUString
GalleryListView::GetCellText(long _nRow
, sal_uInt16
/*nColumnId*/) const
509 if( mpTheme
&& ( _nRow
< static_cast< long >( mpTheme
->GetObjectCount() ) ) )
511 std::unique_ptr
<SgaObject
> pObj
= mpTheme
->AcquireObject( _nRow
);
515 sRet
= GalleryBrowser2::GetItemText( *pObj
, GalleryItemFlags::Title
);
522 tools::Rectangle
GalleryListView::GetFieldCharacterBounds(sal_Int32 _nRow
,sal_Int32 _nColumnPos
,sal_Int32 nIndex
)
524 DBG_ASSERT(_nColumnPos
>= 0 && _nColumnPos
<= SAL_MAX_UINT16
, "GalleryListView::GetFieldCharacterBounds: _nColumnId overflow");
525 tools::Rectangle aRect
;
526 if ( SeekRow(_nRow
) )
528 SvxFont
aFont( GetFont() );
529 AccessibleStringWrap
aStringWrap( *this, aFont
, GetCellText(_nRow
, sal::static_int_cast
<sal_uInt16
>( GetColumnId( sal::static_int_cast
<sal_uInt16
>(_nColumnPos
) ) ) ) );
531 // get the bounds inside the string
532 aStringWrap
.GetCharacterBounds(nIndex
, aRect
);
539 sal_Int32
GalleryListView::GetFieldIndexAtPoint(sal_Int32 _nRow
,sal_Int32 _nColumnPos
,const Point
& _rPoint
)
541 DBG_ASSERT(_nColumnPos
>= 0 && _nColumnPos
<= SAL_MAX_UINT16
, "GalleryListView::GetFieldIndexAtPoint: _nColumnId overflow");
543 if ( SeekRow(_nRow
) )
545 SvxFont
aFont( GetFont() );
546 AccessibleStringWrap
aStringWrap( *this, aFont
, GetCellText(_nRow
, sal::static_int_cast
<sal_uInt16
>(GetColumnId(sal::static_int_cast
<sal_uInt16
>(_nColumnPos
)))) );
547 nRet
= aStringWrap
.GetIndexAtPoint(_rPoint
);
552 void GalleryListView::PaintField(vcl::RenderContext
& rDev
, const tools::Rectangle
& rRect
, sal_uInt16
/*nColumnId*/) const
554 rDev
.Push( PushFlags::CLIPREGION
);
555 rDev
.IntersectClipRegion( rRect
);
557 if( mpTheme
&& ( mnCurRow
< mpTheme
->GetObjectCount() ) )
559 const Size
aSize(rRect
.GetHeight(), rRect
.GetHeight());
562 OUString aItemTextTitle
;
563 OUString aItemTextPath
;
565 mpTheme
->GetPreviewBitmapExAndStrings(mnCurRow
, aBitmapEx
, aPreparedSize
, aItemTextTitle
, aItemTextPath
);
567 bool bNeedToCreate(aBitmapEx
.IsEmpty());
569 if(!bNeedToCreate
&& (aItemTextTitle
.isEmpty() || aPreparedSize
!= aSize
))
570 bNeedToCreate
= true;
574 std::unique_ptr
<SgaObject
> pObj
= mpTheme
->AcquireObject(mnCurRow
);
578 aBitmapEx
= pObj
->createPreviewBitmapEx(aSize
);
579 aItemTextTitle
= GalleryBrowser2::GetItemText(*pObj
, GalleryItemFlags::Title
);
580 aItemTextPath
= GalleryBrowser2::GetItemText(*pObj
, GalleryItemFlags::Path
);
582 mpTheme
->SetPreviewBitmapExAndStrings(mnCurRow
, aBitmapEx
, aSize
, aItemTextTitle
, aItemTextPath
);
586 const long nTextPosY(rRect
.Top() + ((rRect
.GetHeight() - rDev
.GetTextHeight()) >> 1));
588 if(!aBitmapEx
.IsEmpty())
590 const Size
aBitmapExSizePixel(aBitmapEx
.GetSizePixel());
592 ((aSize
.Width() - aBitmapExSizePixel
.Width()) >> 1) + rRect
.Left(),
593 ((aSize
.Height() - aBitmapExSizePixel
.Height()) >> 1) + rRect
.Top());
595 if(aBitmapEx
.IsTransparent())
597 // draw checkered background
598 drawTransparenceBackground(rDev
, aPos
, aBitmapExSizePixel
);
601 rDev
.DrawBitmapEx(aPos
, aBitmapEx
);
604 rDev
.DrawText(Point(rRect
.Left() + rRect
.GetHeight() + 6, nTextPosY
), aItemTextTitle
);
610 void GalleryListView::Command( const CommandEvent
& rCEvt
)
612 BrowseBox::Command( rCEvt
);
614 if( rCEvt
.GetCommand() == CommandEventId::ContextMenu
)
616 const Point
* pPos
= nullptr;
618 if( rCEvt
.IsMouseEvent() && ( GetRowAtYPosPixel( rCEvt
.GetMousePosPixel().Y() ) != BROWSER_ENDOFSELECTION
) )
619 pPos
= &rCEvt
.GetMousePosPixel();
621 static_cast<GalleryBrowser2
*>( GetParent() )->ShowContextMenu( pPos
);
625 void GalleryListView::KeyInput( const KeyEvent
& rKEvt
)
627 if( !mpTheme
|| !static_cast< GalleryBrowser2
* >( GetParent() )->KeyInput( rKEvt
, this ) )
628 BrowseBox::KeyInput( rKEvt
);
631 void GalleryListView::DoubleClick( const BrowserMouseEvent
& rEvt
)
633 BrowseBox::DoubleClick( rEvt
);
635 if( rEvt
.GetRow() != BROWSER_ENDOFSELECTION
)
636 static_cast<GalleryBrowser2
*>( GetParent() )->TogglePreview();
639 void GalleryListView::Select()
641 maSelectHdl
.Call( this );
644 sal_Int8
GalleryListView::AcceptDrop( const BrowserAcceptDropEvent
& )
646 sal_Int8 nRet
= DND_ACTION_NONE
;
648 if( mpTheme
&& !mpTheme
->IsReadOnly() )
649 nRet
= DND_ACTION_COPY
;
654 sal_Int8
GalleryListView::ExecuteDrop( const BrowserExecuteDropEvent
& rEvt
)
656 ExecuteDropEvent
aEvt( rEvt
);
658 aEvt
.maPosPixel
.AdjustY(GetTitleHeight() );
660 return static_cast<GalleryBrowser2
*>( GetParent() )->ExecuteDrop( aEvt
);
663 void GalleryListView::StartDrag( sal_Int8
, const Point
& rPosPixel
)
665 static_cast<GalleryBrowser2
*>( GetParent() )->StartDrag( &rPosPixel
);
668 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */