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 .
21 #include <vcl/svapp.hxx>
22 #include <sfx2/viewfrm.hxx>
23 #include <sfx2/dispatch.hxx>
24 #include <avmedia/mediaplayer.hxx>
26 #include "galbrws2.hxx"
27 #include "svx/galtheme.hxx"
28 #include "svx/galmisc.hxx"
29 #include "svx/galctrl.hxx"
30 #include "editeng/AccessibleStringWrap.hxx"
31 #include <editeng/svxfont.hxx>
33 #include <avmedia/mediawindow.hxx>
34 #include "gallery.hrc"
35 #include <vcl/graphicfilter.hxx>
36 #include <vcl/settings.hxx>
37 #include <vcl/builderfactory.hxx>
39 #define GALLERY_BRWBOX_TITLE 1
41 GalleryPreview::GalleryPreview(vcl::Window
* pParent
, WinBits nStyle
, GalleryTheme
* pTheme
)
42 : Window(pParent
, nStyle
)
43 , DropTargetHelper(this)
44 , DragSourceHelper(this)
47 SetHelpId( HID_GALLERY_WINDOW
);
51 VCL_BUILDER_DECL_FACTORY(GalleryPreview
)
53 WinBits nWinBits
= WB_TABSTOP
;
54 OString sBorder
= VclBuilder::extractCustomProperty(rMap
);
55 if (!sBorder
.isEmpty())
56 nWinBits
|= WB_BORDER
;
57 rRet
= VclPtr
<GalleryPreview
>::Create(pParent
, nWinBits
);
60 Size
GalleryPreview::GetOptimalSize() const
62 return LogicToPixel(Size(70, 88), MAP_APPFONT
);
65 bool GalleryPreview::SetGraphic( const INetURLObject
& _aURL
)
69 if( ::avmedia::MediaWindow::isMediaURL( _aURL
.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS
), "" ) )
71 aGraphic
= BitmapEx( GAL_RES( RID_SVXBMP_GALLERY_MEDIA
) );
75 GraphicFilter
& rFilter
= GraphicFilter::GetGraphicFilter();
76 GalleryProgress
aProgress( &rFilter
);
77 if( rFilter
.ImportGraphic( aGraphic
, _aURL
, GRFILTER_FORMAT_DONTKNOW
) )
81 SetGraphic( aGraphic
);
86 void GalleryPreview::InitSettings()
88 SetBackground( Wallpaper( GALLERY_BG_COLOR
) );
89 SetControlBackground( GALLERY_BG_COLOR
);
90 SetControlForeground( GALLERY_FG_COLOR
);
93 void GalleryPreview::DataChanged( const DataChangedEvent
& rDCEvt
)
95 if ( ( rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) && ( rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
98 Window::DataChanged( rDCEvt
);
101 bool GalleryPreview::ImplGetGraphicCenterRect( const Graphic
& rGraphic
, Rectangle
& rResultRect
) const
103 const Size
aWinSize( GetOutputSizePixel() );
104 Size
aNewSize( LogicToPixel( rGraphic
.GetPrefSize(), rGraphic
.GetPrefMapMode() ) );
107 if( aNewSize
.Width() && aNewSize
.Height() )
109 // scale to fit window
110 const double fGrfWH
= (double) aNewSize
.Width() / aNewSize
.Height();
111 const double fWinWH
= (double) aWinSize
.Width() / aWinSize
.Height();
113 if ( fGrfWH
< fWinWH
)
115 aNewSize
.Width() = (long) ( aWinSize
.Height() * fGrfWH
);
116 aNewSize
.Height()= aWinSize
.Height();
120 aNewSize
.Width() = aWinSize
.Width();
121 aNewSize
.Height()= (long) ( aWinSize
.Width() / fGrfWH
);
124 const Point
aNewPos( ( aWinSize
.Width() - aNewSize
.Width() ) >> 1,
125 ( aWinSize
.Height() - aNewSize
.Height() ) >> 1 );
127 rResultRect
= Rectangle( aNewPos
, aNewSize
);
134 void GalleryPreview::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
& rRect
)
136 Window::Paint(rRenderContext
, rRect
);
138 if (ImplGetGraphicCenterRect(aGraphicObj
.GetGraphic(), aPreviewRect
))
140 const Point
aPos( aPreviewRect
.TopLeft() );
141 const Size
aSize( aPreviewRect
.GetSize() );
143 if( aGraphicObj
.IsAnimated() )
144 aGraphicObj
.StartAnimation(&rRenderContext
, aPos
, aSize
);
146 aGraphicObj
.Draw(&rRenderContext
, aPos
, aSize
);
150 void GalleryPreview::MouseButtonDown(const MouseEvent
& rMEvt
)
152 if (mpTheme
&& (rMEvt
.GetClicks() == 2))
153 static_cast<GalleryBrowser2
*>(GetParent())->TogglePreview(this);
156 void GalleryPreview::Command(const CommandEvent
& rCEvt
)
158 Window::Command(rCEvt
);
160 if (mpTheme
&& (rCEvt
.GetCommand() == CommandEventId::ContextMenu
))
162 GalleryBrowser2
* pGalleryBrowser
= static_cast<GalleryBrowser2
*>(GetParent());
163 pGalleryBrowser
->ShowContextMenu(this, (rCEvt
.IsMouseEvent() ? &rCEvt
.GetMousePosPixel() : NULL
));
167 void GalleryPreview::KeyInput(const KeyEvent
& rKEvt
)
171 GalleryBrowser2
* pBrowser
= static_cast< GalleryBrowser2
* >( GetParent() );
173 switch( rKEvt
.GetKeyCode().GetCode() )
175 case( KEY_BACKSPACE
):
176 pBrowser
->TogglePreview( this );
180 pBrowser
->Travel( GALLERYBROWSERTRAVEL_FIRST
);
184 pBrowser
->Travel( GALLERYBROWSERTRAVEL_LAST
);
189 pBrowser
->Travel( GALLERYBROWSERTRAVEL_PREVIOUS
);
194 pBrowser
->Travel( GALLERYBROWSERTRAVEL_NEXT
);
199 if (!pBrowser
->KeyInput(rKEvt
, this))
200 Window::KeyInput(rKEvt
);
207 Window::KeyInput(rKEvt
);
211 sal_Int8
GalleryPreview::AcceptDrop( const AcceptDropEvent
& rEvt
)
216 nRet
= static_cast<GalleryBrowser2
*>(GetParent())->AcceptDrop(*this, rEvt
);
218 nRet
= DND_ACTION_NONE
;
223 sal_Int8
GalleryPreview::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
228 nRet
= static_cast<GalleryBrowser2
*>(GetParent())->ExecuteDrop(*this, rEvt
);
230 nRet
= DND_ACTION_NONE
;
235 void GalleryPreview::StartDrag( sal_Int8
, const Point
& )
238 static_cast<GalleryBrowser2
*>(GetParent())->StartDrag(this);
241 void GalleryPreview::PreviewMedia( const INetURLObject
& rURL
)
243 if (rURL
.GetProtocol() != INetProtocol::NotValid
)
245 ::avmedia::MediaFloater
* pFloater
= avmedia::getMediaFloater();
249 SfxViewFrame::Current()->GetBindings().GetDispatcher()->Execute( SID_AVMEDIA_PLAYER
, SfxCallMode::SYNCHRON
);
250 pFloater
= avmedia::getMediaFloater();
254 pFloater
->setURL( rURL
.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS
), "", true );
258 void drawTransparenceBackground(vcl::RenderContext
& rOut
, const Point
& rPos
, const Size
& rSize
)
261 // draw checkered background
262 static const sal_uInt32
nLen(8);
263 static const Color
aW(COL_WHITE
);
264 static const Color
aG(0xef, 0xef, 0xef);
266 rOut
.DrawCheckered(rPos
, rSize
, nLen
, aW
, aG
);
269 GalleryIconView::GalleryIconView( GalleryBrowser2
* pParent
, GalleryTheme
* pTheme
) :
270 ValueSet( pParent
, WB_TABSTOP
| WB_3DLOOK
| WB_BORDER
| WB_ITEMBORDER
| WB_DOUBLEBORDER
| WB_VSCROLL
| WB_FLATVALUESET
),
271 DropTargetHelper( this ),
272 DragSourceHelper( this ),
276 EnableFullItemMode( false );
278 SetHelpId( HID_GALLERY_WINDOW
);
280 SetExtraSpacing( 2 );
281 SetItemWidth( S_THUMB
+ 6 );
282 SetItemHeight( S_THUMB
+ 6 );
285 void GalleryIconView::InitSettings()
287 SetBackground( Wallpaper( GALLERY_BG_COLOR
) );
288 SetControlBackground( GALLERY_BG_COLOR
);
289 SetControlForeground( GALLERY_FG_COLOR
);
290 SetColor( GALLERY_BG_COLOR
);
293 void GalleryIconView::DataChanged( const DataChangedEvent
& rDCEvt
)
295 if ( ( rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) && ( rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
298 ValueSet::DataChanged( rDCEvt
);
301 void GalleryIconView::UserDraw(const UserDrawEvent
& rUDEvt
)
303 const sal_uInt16 nId
= rUDEvt
.GetItemId();
307 const Rectangle
& rRect
= rUDEvt
.GetRect();
308 const Size
aSize(rRect
.GetWidth(), rRect
.GetHeight());
311 OUString aItemTextTitle
;
312 OUString aItemTextPath
;
314 mpTheme
->GetPreviewBitmapExAndStrings(nId
- 1, aBitmapEx
, aPreparedSize
, aItemTextTitle
, aItemTextPath
);
316 bool bNeedToCreate(aBitmapEx
.IsEmpty());
318 if (!bNeedToCreate
&& aItemTextTitle
.isEmpty())
320 bNeedToCreate
= true;
323 if (!bNeedToCreate
&& aPreparedSize
!= aSize
)
325 bNeedToCreate
= true;
330 SgaObject
* pObj
= mpTheme
->AcquireObject(nId
- 1);
334 aBitmapEx
= pObj
->createPreviewBitmapEx(aSize
);
335 aItemTextTitle
= GalleryBrowser2::GetItemText(*mpTheme
, *pObj
, GALLERY_ITEM_TITLE
);
337 mpTheme
->SetPreviewBitmapExAndStrings(nId
- 1, aBitmapEx
, aSize
, aItemTextTitle
, aItemTextPath
);
338 GalleryTheme::ReleaseObject(pObj
);
342 if (!aBitmapEx
.IsEmpty())
344 const Size
aBitmapExSizePixel(aBitmapEx
.GetSizePixel());
346 ((aSize
.Width() - aBitmapExSizePixel
.Width()) >> 1) + rRect
.Left(),
347 ((aSize
.Height() - aBitmapExSizePixel
.Height()) >> 1) + rRect
.Top());
348 OutputDevice
* pDev
= rUDEvt
.GetRenderContext();
350 if(aBitmapEx
.IsTransparent())
352 // draw checkered background for full rectangle.
353 drawTransparenceBackground(*pDev
, rRect
.TopLeft(), rRect
.GetSize());
356 pDev
->DrawBitmapEx(aPos
, aBitmapEx
);
359 SetItemText(nId
, aItemTextTitle
);
363 void GalleryIconView::MouseButtonDown(const MouseEvent
& rMEvt
)
365 ValueSet::MouseButtonDown(rMEvt
);
367 if (rMEvt
.GetClicks() == 2)
368 static_cast<GalleryBrowser2
*>(GetParent())->TogglePreview(this, &rMEvt
.GetPosPixel());
371 void GalleryIconView::Command(const CommandEvent
& rCEvt
)
373 ValueSet::Command(rCEvt
);
375 if (rCEvt
.GetCommand() == CommandEventId::ContextMenu
)
377 GalleryBrowser2
* pGalleryBrowser
= static_cast<GalleryBrowser2
*>(GetParent());
378 pGalleryBrowser
->ShowContextMenu(this, (rCEvt
.IsMouseEvent() ? &rCEvt
.GetMousePosPixel() : nullptr));
382 void GalleryIconView::KeyInput(const KeyEvent
& rKEvt
)
384 if (!mpTheme
|| !static_cast<GalleryBrowser2
*>(GetParent())->KeyInput(rKEvt
, this))
385 ValueSet::KeyInput(rKEvt
);
388 sal_Int8
GalleryIconView::AcceptDrop(const AcceptDropEvent
& rEvt
)
390 return(static_cast<GalleryBrowser2
*>(GetParent())->AcceptDrop(*this, rEvt
));
393 sal_Int8
GalleryIconView::ExecuteDrop(const ExecuteDropEvent
& rEvt
)
395 return(static_cast<GalleryBrowser2
*>(GetParent())->ExecuteDrop(*this, rEvt
));
398 void GalleryIconView::StartDrag(sal_Int8
, const Point
&)
400 const CommandEvent
aEvt(GetPointerPosPixel(), CommandEventId::StartDrag
, true);
403 // call this to initiate dragging for ValueSet
404 ValueSet::StartDrag(aEvt
, aRegion
);
405 static_cast<GalleryBrowser2
*>(GetParent())->StartDrag(this);
408 GalleryListView::GalleryListView( GalleryBrowser2
* pParent
, GalleryTheme
* pTheme
) :
409 BrowseBox( pParent
, WB_TABSTOP
| WB_3DLOOK
| WB_BORDER
),
414 SetHelpId( HID_GALLERY_WINDOW
);
418 SetMode( BrowserMode::AUTO_VSCROLL
| BrowserMode::AUTOSIZE_LASTCOL
| BrowserMode::AUTO_HSCROLL
);
419 SetDataRowHeight( 28 );
420 InsertDataColumn( GALLERY_BRWBOX_TITLE
, GAL_RESSTR(RID_SVXSTR_GALLERY_TITLE
), 256 );
423 void GalleryListView::InitSettings()
425 SetBackground( Wallpaper( GALLERY_BG_COLOR
) );
426 SetControlBackground( GALLERY_BG_COLOR
);
427 SetControlForeground( GALLERY_FG_COLOR
);
430 void GalleryListView::DataChanged( const DataChangedEvent
& rDCEvt
)
432 if ( ( rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) && ( rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
435 BrowseBox::DataChanged( rDCEvt
);
438 bool GalleryListView::SeekRow( long nRow
)
444 OUString
GalleryListView::GetCellText(long _nRow
, sal_uInt16
/*nColumnId*/) const
447 if( mpTheme
&& ( _nRow
< static_cast< long >( mpTheme
->GetObjectCount() ) ) )
449 SgaObject
* pObj
= mpTheme
->AcquireObject( _nRow
);
453 sRet
= GalleryBrowser2::GetItemText( *mpTheme
, *pObj
, GALLERY_ITEM_TITLE
);
454 GalleryTheme::ReleaseObject( pObj
);
461 Rectangle
GalleryListView::GetFieldCharacterBounds(sal_Int32 _nRow
,sal_Int32 _nColumnPos
,sal_Int32 nIndex
)
463 DBG_ASSERT(_nColumnPos
>= 0 && _nColumnPos
<= USHRT_MAX
, "GalleryListView::GetFieldCharacterBounds: _nColumnId overflow");
465 if ( SeekRow(_nRow
) )
467 SvxFont
aFont( GetFont() );
468 AccessibleStringWrap
aStringWrap( *this, aFont
, GetCellText(_nRow
, sal::static_int_cast
<sal_uInt16
>( GetColumnId( sal::static_int_cast
<sal_uInt16
>(_nColumnPos
) ) ) ) );
470 // get the bounds inside the string
471 aStringWrap
.GetCharacterBounds(nIndex
, aRect
);
478 sal_Int32
GalleryListView::GetFieldIndexAtPoint(sal_Int32 _nRow
,sal_Int32 _nColumnPos
,const Point
& _rPoint
)
480 DBG_ASSERT(_nColumnPos
>= 0 && _nColumnPos
<= USHRT_MAX
, "GalleryListView::GetFieldIndexAtPoint: _nColumnId overflow");
482 if ( SeekRow(_nRow
) )
484 SvxFont
aFont( GetFont() );
485 AccessibleStringWrap
aStringWrap( *this, aFont
, GetCellText(_nRow
, sal::static_int_cast
<sal_uInt16
>(GetColumnId(sal::static_int_cast
<sal_uInt16
>(_nColumnPos
)))) );
486 nRet
= aStringWrap
.GetIndexAtPoint(_rPoint
);
491 void GalleryListView::PaintField(vcl::RenderContext
& rDev
, const Rectangle
& rRect
, sal_uInt16
/*nColumnId*/) const
493 rDev
.Push( PushFlags::CLIPREGION
);
494 rDev
.IntersectClipRegion( rRect
);
496 if( mpTheme
&& ( static_cast<size_t>(mnCurRow
) < mpTheme
->GetObjectCount() ) )
498 const Size
aSize(rRect
.GetHeight(), rRect
.GetHeight());
501 OUString aItemTextTitle
;
502 OUString aItemTextPath
;
504 mpTheme
->GetPreviewBitmapExAndStrings(mnCurRow
, aBitmapEx
, aPreparedSize
, aItemTextTitle
, aItemTextPath
);
506 bool bNeedToCreate(aBitmapEx
.IsEmpty());
508 if(!bNeedToCreate
&& (aItemTextTitle
.isEmpty() || aPreparedSize
!= aSize
))
509 bNeedToCreate
= true;
513 SgaObject
* pObj
= mpTheme
->AcquireObject(mnCurRow
);
517 aBitmapEx
= pObj
->createPreviewBitmapEx(aSize
);
518 aItemTextTitle
= GalleryBrowser2::GetItemText(*mpTheme
, *pObj
, GALLERY_ITEM_TITLE
);
519 aItemTextPath
= GalleryBrowser2::GetItemText(*mpTheme
, *pObj
, GALLERY_ITEM_PATH
);
521 mpTheme
->SetPreviewBitmapExAndStrings(mnCurRow
, aBitmapEx
, aSize
, aItemTextTitle
, aItemTextPath
);
522 GalleryTheme::ReleaseObject(pObj
);
526 const long nTextPosY(rRect
.Top() + ((rRect
.GetHeight() - rDev
.GetTextHeight()) >> 1));
528 if(!aBitmapEx
.IsEmpty())
530 const Size
aBitmapExSizePixel(aBitmapEx
.GetSizePixel());
532 ((aSize
.Width() - aBitmapExSizePixel
.Width()) >> 1) + rRect
.Left(),
533 ((aSize
.Height() - aBitmapExSizePixel
.Height()) >> 1) + rRect
.Top());
535 if(aBitmapEx
.IsTransparent())
537 // draw checkered background
538 drawTransparenceBackground(rDev
, aPos
, aBitmapExSizePixel
);
541 rDev
.DrawBitmapEx(aPos
, aBitmapEx
);
544 rDev
.DrawText(Point(rRect
.Left() + rRect
.GetHeight() + 6, nTextPosY
), aItemTextTitle
);
550 void GalleryListView::Command( const CommandEvent
& rCEvt
)
552 BrowseBox::Command( rCEvt
);
554 if( rCEvt
.GetCommand() == CommandEventId::ContextMenu
)
556 const Point
* pPos
= NULL
;
558 if( rCEvt
.IsMouseEvent() && ( GetRowAtYPosPixel( rCEvt
.GetMousePosPixel().Y() ) != BROWSER_ENDOFSELECTION
) )
559 pPos
= &rCEvt
.GetMousePosPixel();
561 static_cast<GalleryBrowser2
*>( GetParent() )->ShowContextMenu( this, pPos
);
565 void GalleryListView::KeyInput( const KeyEvent
& rKEvt
)
567 if( !mpTheme
|| !static_cast< GalleryBrowser2
* >( GetParent() )->KeyInput( rKEvt
, this ) )
568 BrowseBox::KeyInput( rKEvt
);
571 void GalleryListView::DoubleClick( const BrowserMouseEvent
& rEvt
)
573 BrowseBox::DoubleClick( rEvt
);
575 if( rEvt
.GetRow() != BROWSER_ENDOFSELECTION
)
576 static_cast<GalleryBrowser2
*>( GetParent() )->TogglePreview( this, &rEvt
.GetPosPixel() );
579 void GalleryListView::Select()
581 if( maSelectHdl
.IsSet() )
582 maSelectHdl
.Call( this );
585 sal_Int8
GalleryListView::AcceptDrop( const BrowserAcceptDropEvent
& )
587 sal_Int8 nRet
= DND_ACTION_NONE
;
589 if( mpTheme
&& !mpTheme
->IsReadOnly() )
590 nRet
= DND_ACTION_COPY
;
595 sal_Int8
GalleryListView::ExecuteDrop( const BrowserExecuteDropEvent
& rEvt
)
597 ExecuteDropEvent
aEvt( rEvt
);
599 aEvt
.maPosPixel
.Y() += GetTitleHeight();
601 return( static_cast<GalleryBrowser2
*>( GetParent() )->ExecuteDrop( *this, aEvt
) );
604 void GalleryListView::StartDrag( sal_Int8
, const Point
& rPosPixel
)
606 static_cast<GalleryBrowser2
*>( GetParent() )->StartDrag( this, &rPosPixel
);
609 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */