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
)
260 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
262 if (rStyleSettings
.GetPreviewUsesCheckeredBackground())
264 // draw checkered background
265 static const sal_uInt32
nLen(8);
266 static const Color
aW(COL_WHITE
);
267 static const Color
aG(0xef, 0xef, 0xef);
269 rOut
.DrawCheckered(rPos
, rSize
, nLen
, aW
, aG
);
274 rOut
.SetFillColor(rStyleSettings
.GetFieldColor());
275 rOut
.DrawRect(Rectangle(rPos
, rSize
));
279 GalleryIconView::GalleryIconView( GalleryBrowser2
* pParent
, GalleryTheme
* pTheme
) :
280 ValueSet( pParent
, WB_TABSTOP
| WB_3DLOOK
| WB_BORDER
| WB_ITEMBORDER
| WB_DOUBLEBORDER
| WB_VSCROLL
| WB_FLATVALUESET
),
281 DropTargetHelper( this ),
282 DragSourceHelper( this ),
286 EnableFullItemMode( false );
288 SetHelpId( HID_GALLERY_WINDOW
);
290 SetExtraSpacing( 2 );
291 SetItemWidth( S_THUMB
+ 6 );
292 SetItemHeight( S_THUMB
+ 6 );
295 void GalleryIconView::InitSettings()
297 SetBackground( Wallpaper( GALLERY_BG_COLOR
) );
298 SetControlBackground( GALLERY_BG_COLOR
);
299 SetControlForeground( GALLERY_FG_COLOR
);
300 SetColor( GALLERY_BG_COLOR
);
303 void GalleryIconView::DataChanged( const DataChangedEvent
& rDCEvt
)
305 if ( ( rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) && ( rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
308 ValueSet::DataChanged( rDCEvt
);
311 void GalleryIconView::UserDraw(const UserDrawEvent
& rUDEvt
)
313 const sal_uInt16 nId
= rUDEvt
.GetItemId();
317 const Rectangle
& rRect
= rUDEvt
.GetRect();
318 const Size
aSize(rRect
.GetWidth(), rRect
.GetHeight());
321 OUString aItemTextTitle
;
322 OUString aItemTextPath
;
324 mpTheme
->GetPreviewBitmapExAndStrings(nId
- 1, aBitmapEx
, aPreparedSize
, aItemTextTitle
, aItemTextPath
);
326 bool bNeedToCreate(aBitmapEx
.IsEmpty());
328 if (!bNeedToCreate
&& aItemTextTitle
.isEmpty())
330 bNeedToCreate
= true;
333 if (!bNeedToCreate
&& aPreparedSize
!= aSize
)
335 bNeedToCreate
= true;
340 SgaObject
* pObj
= mpTheme
->AcquireObject(nId
- 1);
344 aBitmapEx
= pObj
->createPreviewBitmapEx(aSize
);
345 aItemTextTitle
= GalleryBrowser2::GetItemText(*mpTheme
, *pObj
, GALLERY_ITEM_TITLE
);
347 mpTheme
->SetPreviewBitmapExAndStrings(nId
- 1, aBitmapEx
, aSize
, aItemTextTitle
, aItemTextPath
);
348 GalleryTheme::ReleaseObject(pObj
);
352 if (!aBitmapEx
.IsEmpty())
354 const Size
aBitmapExSizePixel(aBitmapEx
.GetSizePixel());
356 ((aSize
.Width() - aBitmapExSizePixel
.Width()) >> 1) + rRect
.Left(),
357 ((aSize
.Height() - aBitmapExSizePixel
.Height()) >> 1) + rRect
.Top());
358 OutputDevice
* pDev
= rUDEvt
.GetDevice();
360 if(aBitmapEx
.IsTransparent())
362 // draw checkered background for full rectangle.
363 drawTransparenceBackground(*pDev
, rRect
.TopLeft(), rRect
.GetSize());
366 pDev
->DrawBitmapEx(aPos
, aBitmapEx
);
369 SetItemText(nId
, aItemTextTitle
);
373 void GalleryIconView::MouseButtonDown(const MouseEvent
& rMEvt
)
375 ValueSet::MouseButtonDown(rMEvt
);
377 if (rMEvt
.GetClicks() == 2)
378 static_cast<GalleryBrowser2
*>(GetParent())->TogglePreview(this, &rMEvt
.GetPosPixel());
381 void GalleryIconView::Command(const CommandEvent
& rCEvt
)
383 ValueSet::Command(rCEvt
);
385 if (rCEvt
.GetCommand() == CommandEventId::ContextMenu
)
387 GalleryBrowser2
* pGalleryBrowser
= static_cast<GalleryBrowser2
*>(GetParent());
388 pGalleryBrowser
->ShowContextMenu(this, (rCEvt
.IsMouseEvent() ? &rCEvt
.GetMousePosPixel() : nullptr));
392 void GalleryIconView::KeyInput(const KeyEvent
& rKEvt
)
394 if (!mpTheme
|| !static_cast<GalleryBrowser2
*>(GetParent())->KeyInput(rKEvt
, this))
395 ValueSet::KeyInput(rKEvt
);
398 sal_Int8
GalleryIconView::AcceptDrop(const AcceptDropEvent
& rEvt
)
400 return(static_cast<GalleryBrowser2
*>(GetParent())->AcceptDrop(*this, rEvt
));
403 sal_Int8
GalleryIconView::ExecuteDrop(const ExecuteDropEvent
& rEvt
)
405 return(static_cast<GalleryBrowser2
*>(GetParent())->ExecuteDrop(*this, rEvt
));
408 void GalleryIconView::StartDrag(sal_Int8
, const Point
&)
410 const CommandEvent
aEvt(GetPointerPosPixel(), CommandEventId::StartDrag
, true);
413 // call this to initiate dragging for ValueSet
414 ValueSet::StartDrag(aEvt
, aRegion
);
415 static_cast<GalleryBrowser2
*>(GetParent())->StartDrag(this);
418 GalleryListView::GalleryListView( GalleryBrowser2
* pParent
, GalleryTheme
* pTheme
) :
419 BrowseBox( pParent
, WB_TABSTOP
| WB_3DLOOK
| WB_BORDER
),
424 SetHelpId( HID_GALLERY_WINDOW
);
428 SetMode( BrowserMode::AUTO_VSCROLL
| BrowserMode::AUTOSIZE_LASTCOL
| BrowserMode::AUTO_HSCROLL
);
429 SetDataRowHeight( 28 );
430 InsertDataColumn( GALLERY_BRWBOX_TITLE
, GAL_RESSTR(RID_SVXSTR_GALLERY_TITLE
), 256 );
433 void GalleryListView::InitSettings()
435 SetBackground( Wallpaper( GALLERY_BG_COLOR
) );
436 SetControlBackground( GALLERY_BG_COLOR
);
437 SetControlForeground( GALLERY_FG_COLOR
);
440 void GalleryListView::DataChanged( const DataChangedEvent
& rDCEvt
)
442 if ( ( rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) && ( rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
445 BrowseBox::DataChanged( rDCEvt
);
448 bool GalleryListView::SeekRow( long nRow
)
454 OUString
GalleryListView::GetCellText(long _nRow
, sal_uInt16
/*nColumnId*/) const
457 if( mpTheme
&& ( _nRow
< static_cast< long >( mpTheme
->GetObjectCount() ) ) )
459 SgaObject
* pObj
= mpTheme
->AcquireObject( _nRow
);
463 sRet
= GalleryBrowser2::GetItemText( *mpTheme
, *pObj
, GALLERY_ITEM_TITLE
);
464 GalleryTheme::ReleaseObject( pObj
);
471 Rectangle
GalleryListView::GetFieldCharacterBounds(sal_Int32 _nRow
,sal_Int32 _nColumnPos
,sal_Int32 nIndex
)
473 DBG_ASSERT(_nColumnPos
>= 0 && _nColumnPos
<= USHRT_MAX
, "GalleryListView::GetFieldCharacterBounds: _nColumnId overflow");
475 if ( SeekRow(_nRow
) )
477 SvxFont
aFont( GetFont() );
478 AccessibleStringWrap
aStringWrap( *this, aFont
, GetCellText(_nRow
, sal::static_int_cast
<sal_uInt16
>( GetColumnId( sal::static_int_cast
<sal_uInt16
>(_nColumnPos
) ) ) ) );
480 // get the bounds inside the string
481 aStringWrap
.GetCharacterBounds(nIndex
, aRect
);
488 sal_Int32
GalleryListView::GetFieldIndexAtPoint(sal_Int32 _nRow
,sal_Int32 _nColumnPos
,const Point
& _rPoint
)
490 DBG_ASSERT(_nColumnPos
>= 0 && _nColumnPos
<= USHRT_MAX
, "GalleryListView::GetFieldIndexAtPoint: _nColumnId overflow");
492 if ( SeekRow(_nRow
) )
494 SvxFont
aFont( GetFont() );
495 AccessibleStringWrap
aStringWrap( *this, aFont
, GetCellText(_nRow
, sal::static_int_cast
<sal_uInt16
>(GetColumnId(sal::static_int_cast
<sal_uInt16
>(_nColumnPos
)))) );
496 nRet
= aStringWrap
.GetIndexAtPoint(_rPoint
);
501 void GalleryListView::PaintField(vcl::RenderContext
& rDev
, const Rectangle
& rRect
, sal_uInt16
/*nColumnId*/) const
503 rDev
.Push( PushFlags::CLIPREGION
);
504 rDev
.IntersectClipRegion( rRect
);
506 if( mpTheme
&& ( static_cast<size_t>(mnCurRow
) < mpTheme
->GetObjectCount() ) )
508 const Size
aSize(rRect
.GetHeight(), rRect
.GetHeight());
511 OUString aItemTextTitle
;
512 OUString aItemTextPath
;
514 mpTheme
->GetPreviewBitmapExAndStrings(mnCurRow
, aBitmapEx
, aPreparedSize
, aItemTextTitle
, aItemTextPath
);
516 bool bNeedToCreate(aBitmapEx
.IsEmpty());
518 if(!bNeedToCreate
&& (aItemTextTitle
.isEmpty() || aPreparedSize
!= aSize
))
519 bNeedToCreate
= true;
523 SgaObject
* pObj
= mpTheme
->AcquireObject(mnCurRow
);
527 aBitmapEx
= pObj
->createPreviewBitmapEx(aSize
);
528 aItemTextTitle
= GalleryBrowser2::GetItemText(*mpTheme
, *pObj
, GALLERY_ITEM_TITLE
);
529 aItemTextPath
= GalleryBrowser2::GetItemText(*mpTheme
, *pObj
, GALLERY_ITEM_PATH
);
531 mpTheme
->SetPreviewBitmapExAndStrings(mnCurRow
, aBitmapEx
, aSize
, aItemTextTitle
, aItemTextPath
);
532 GalleryTheme::ReleaseObject(pObj
);
536 const long nTextPosY(rRect
.Top() + ((rRect
.GetHeight() - rDev
.GetTextHeight()) >> 1));
538 if(!aBitmapEx
.IsEmpty())
540 const Size
aBitmapExSizePixel(aBitmapEx
.GetSizePixel());
542 ((aSize
.Width() - aBitmapExSizePixel
.Width()) >> 1) + rRect
.Left(),
543 ((aSize
.Height() - aBitmapExSizePixel
.Height()) >> 1) + rRect
.Top());
545 if(aBitmapEx
.IsTransparent())
547 // draw checkered background
548 drawTransparenceBackground(rDev
, aPos
, aBitmapExSizePixel
);
551 rDev
.DrawBitmapEx(aPos
, aBitmapEx
);
554 rDev
.DrawText(Point(rRect
.Left() + rRect
.GetHeight() + 6, nTextPosY
), aItemTextTitle
);
560 void GalleryListView::Command( const CommandEvent
& rCEvt
)
562 BrowseBox::Command( rCEvt
);
564 if( rCEvt
.GetCommand() == CommandEventId::ContextMenu
)
566 const Point
* pPos
= NULL
;
568 if( rCEvt
.IsMouseEvent() && ( GetRowAtYPosPixel( rCEvt
.GetMousePosPixel().Y() ) != BROWSER_ENDOFSELECTION
) )
569 pPos
= &rCEvt
.GetMousePosPixel();
571 static_cast<GalleryBrowser2
*>( GetParent() )->ShowContextMenu( this, pPos
);
575 void GalleryListView::KeyInput( const KeyEvent
& rKEvt
)
577 if( !mpTheme
|| !static_cast< GalleryBrowser2
* >( GetParent() )->KeyInput( rKEvt
, this ) )
578 BrowseBox::KeyInput( rKEvt
);
581 void GalleryListView::DoubleClick( const BrowserMouseEvent
& rEvt
)
583 BrowseBox::DoubleClick( rEvt
);
585 if( rEvt
.GetRow() != BROWSER_ENDOFSELECTION
)
586 static_cast<GalleryBrowser2
*>( GetParent() )->TogglePreview( this, &rEvt
.GetPosPixel() );
589 void GalleryListView::Select()
591 if( maSelectHdl
.IsSet() )
592 maSelectHdl
.Call( this );
595 sal_Int8
GalleryListView::AcceptDrop( const BrowserAcceptDropEvent
& )
597 sal_Int8 nRet
= DND_ACTION_NONE
;
599 if( mpTheme
&& !mpTheme
->IsReadOnly() )
600 nRet
= DND_ACTION_COPY
;
605 sal_Int8
GalleryListView::ExecuteDrop( const BrowserExecuteDropEvent
& rEvt
)
607 ExecuteDropEvent
aEvt( rEvt
);
609 aEvt
.maPosPixel
.Y() += GetTitleHeight();
611 return( static_cast<GalleryBrowser2
*>( GetParent() )->ExecuteDrop( *this, aEvt
) );
614 void GalleryListView::StartDrag( sal_Int8
, const Point
& rPosPixel
)
616 static_cast<GalleryBrowser2
*>( GetParent() )->StartDrag( this, &rPosPixel
);
619 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */