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 <sot/formats.hxx>
22 #include <svl/urlbmk.hxx>
23 #include <svl/stritem.hxx>
24 #include <svl/intitem.hxx>
25 #include <svl/eitem.hxx>
26 #include <vcl/transfer.hxx>
27 #include <sfx2/bindings.hxx>
28 #include <sfx2/dispatch.hxx>
29 #include <sfx2/viewfrm.hxx>
30 #include <sfx2/sfxsids.hrc>
31 #include <vcl/graphicfilter.hxx>
32 #include <editeng/brushitem.hxx>
34 #include <svx/gallery.hxx>
35 #include <svx/svxids.hrc>
37 #include <svx/gallery1.hxx>
38 #include <svx/galtheme.hxx>
39 #include <svx/galctrl.hxx>
40 #include <svx/galmisc.hxx>
41 #include <galbrws2.hxx>
42 #include <vcl/svapp.hxx>
43 #include <vcl/settings.hxx>
44 #include <vcl/weld.hxx>
45 #include <svx/fmmodel.hxx>
46 #include <svx/dialmgr.hxx>
47 #include <svx/svxdlg.hxx>
48 #include <svx/strings.hrc>
49 #include <GalleryControl.hxx>
50 #include <bitmaps.hlst>
51 #include <svx/galleryitem.hxx>
52 #include <comphelper/processfactory.hxx>
53 #include <com/sun/star/frame/FrameSearchFlag.hpp>
54 #include <com/sun/star/frame/XDispatchProvider.hpp>
55 #include <com/sun/star/gallery/GalleryItemType.hpp>
56 #include <com/sun/star/graphic/XGraphic.hpp>
57 #include <com/sun/star/style/GraphicLocation.hpp>
60 #include <cppuhelper/implbase.hxx>
62 #undef GALLERY_USE_CLIPBOARD
67 GalleryBrowserMode
GalleryBrowser2::meInitMode
= GALLERYBROWSERMODE_ICON
;
71 css::util::URL TargetURL
;
72 css::uno::Sequence
< css::beans::PropertyValue
> Arguments
;
73 css::uno::Reference
< css::frame::XDispatch
> Dispatch
;
76 IMPL_STATIC_LINK( GalleryBrowser2
, AsyncDispatch_Impl
, void*, p
, void )
78 DispatchInfo
* pDispatchInfo
= static_cast<DispatchInfo
*>(p
);
79 if ( pDispatchInfo
&& pDispatchInfo
->Dispatch
.is() )
83 pDispatchInfo
->Dispatch
->dispatch( pDispatchInfo
->TargetURL
,
84 pDispatchInfo
->Arguments
);
86 catch ( const css::uno::Exception
& )
100 css::uno::Reference
< css::frame::XDispatch
> Dispatch
;
102 explicit CommandInfo( const OUString
&rURL
)
108 class GalleryThemePopup
: public ::cppu::WeakImplHelper
< css::frame::XStatusListener
>
111 const GalleryTheme
* mpTheme
;
112 sal_uInt32
const mnObjectPos
;
113 bool const mbPreview
;
114 VclBuilder maBuilder
;
115 VclPtr
<PopupMenu
> mpPopupMenu
;
116 VclPtr
<PopupMenu
> mpBackgroundPopup
;
117 VclPtr
<GalleryBrowser2
> mpBrowser
;
119 typedef std::map
< int, CommandInfo
> CommandInfoMap
;
120 CommandInfoMap m_aCommandInfo
;
122 static void Execute( const CommandInfo
&rCmdInfo
,
123 const css::uno::Sequence
< css::beans::PropertyValue
> &rArguments
);
125 DECL_LINK( MenuSelectHdl
, Menu
*, bool );
126 DECL_LINK( BackgroundMenuSelectHdl
, Menu
*, bool );
128 GalleryThemePopup( const GalleryTheme
* pTheme
,
129 sal_uInt32 nObjectPos
,
131 GalleryBrowser2
* pBrowser
);
133 void ExecutePopup( vcl::Window
*pParent
, const ::Point
&aPos
);
135 virtual void SAL_CALL
statusChanged( const css::frame::FeatureStateEvent
&rEvent
) override
;
136 virtual void SAL_CALL
disposing( const css::lang::EventObject
&rSource
) override
;
140 GalleryThemePopup::GalleryThemePopup(
141 const GalleryTheme
* pTheme
,
142 sal_uInt32 nObjectPos
,
144 GalleryBrowser2
* pBrowser
)
146 , mnObjectPos( nObjectPos
)
147 , mbPreview( bPreview
)
148 , maBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "svx/ui/gallerymenu2.ui", "")
149 , mpPopupMenu(maBuilder
.get_menu("menu"))
150 , mpBackgroundPopup( VclPtr
<PopupMenu
>::Create() )
151 , mpBrowser( pBrowser
)
153 mpPopupMenu
->SetPopupMenu(mpPopupMenu
->GetItemId("background"), mpBackgroundPopup
);
155 // SID_GALLERY_ENABLE_ADDCOPY
156 m_aCommandInfo
.emplace(
157 SID_GALLERY_ENABLE_ADDCOPY
,
158 CommandInfo( ".uno:GalleryEnableAddCopy" ));
159 // SID_GALLERY_BG_BRUSH
160 m_aCommandInfo
.emplace(
161 SID_GALLERY_BG_BRUSH
,
162 CommandInfo( ".uno:BackgroundImage" ));
163 // SID_GALLERY_FORMATS
164 m_aCommandInfo
.emplace(
166 CommandInfo( ".uno:InsertGalleryPic" ));
170 void SAL_CALL
GalleryThemePopup::statusChanged(
171 const css::frame::FeatureStateEvent
&rEvent
)
173 const OUString
&rURL
= rEvent
.FeatureURL
.Complete
;
174 if ( rURL
== ".uno:GalleryEnableAddCopy" )
176 if ( !rEvent
.IsEnabled
)
178 mpPopupMenu
->EnableItem(mpPopupMenu
->GetItemId("add"), false);
181 else if ( rURL
== ".uno:BackgroundImage" )
183 mpBackgroundPopup
->Clear();
184 if ( rEvent
.IsEnabled
)
187 css::uno::Sequence
< OUString
> sItems
;
188 if ( ( rEvent
.State
>>= sItem
) && sItem
.getLength() )
190 mpBackgroundPopup
->InsertItem( 1, sItem
);
192 else if ( ( rEvent
.State
>>= sItems
) && sItems
.hasElements() )
195 for ( const OUString
& rStr
: std::as_const(sItems
) )
197 mpBackgroundPopup
->InsertItem( nId
, rStr
);
205 void SAL_CALL
GalleryThemePopup::disposing(
206 const css::lang::EventObject
&/*rSource*/)
210 void GalleryThemePopup::Execute(
211 const CommandInfo
&rCmdInfo
,
212 const css::uno::Sequence
< css::beans::PropertyValue
> &rArguments
)
214 if ( rCmdInfo
.Dispatch
.is() )
216 std::unique_ptr
<DispatchInfo
> pInfo(new DispatchInfo
);
217 pInfo
->TargetURL
= rCmdInfo
.URL
;
218 pInfo
->Arguments
= rArguments
;
219 pInfo
->Dispatch
= rCmdInfo
.Dispatch
;
221 if ( Application::PostUserEvent(
222 LINK( nullptr, GalleryBrowser2
, AsyncDispatch_Impl
), pInfo
.get() ) )
227 void GalleryThemePopup::ExecutePopup( vcl::Window
*pWindow
, const ::Point
&aPos
)
229 css::uno::Reference
< css::frame::XStatusListener
> xThis( this );
231 const SgaObjKind eObjKind
= mpTheme
->GetObjectKind( mnObjectPos
);
234 const_cast< GalleryTheme
* >( mpTheme
)->GetURL( mnObjectPos
, aURL
);
235 const bool bValidURL
= ( aURL
.GetProtocol() != INetProtocol::NotValid
);
237 mpPopupMenu
->EnableItem(mpPopupMenu
->GetItemId("add"), bValidURL
&& SgaObjKind::Sound
!= eObjKind
);
239 mpPopupMenu
->EnableItem(mpPopupMenu
->GetItemId("preview"), bValidURL
);
240 mpPopupMenu
->CheckItem("preview", mbPreview
);
242 if( mpTheme
->IsReadOnly() || !mpTheme
->GetObjectCount() )
244 mpPopupMenu
->EnableItem(mpPopupMenu
->GetItemId("delete"), false);
245 mpPopupMenu
->EnableItem(mpPopupMenu
->GetItemId("title"), false);
246 if (mpTheme
->IsReadOnly())
247 mpPopupMenu
->EnableItem(mpPopupMenu
->GetItemId("paste"), false);
249 if (!mpTheme
->GetObjectCount())
250 mpPopupMenu
->EnableItem(mpPopupMenu
->GetItemId("copy"), false);
254 mpPopupMenu
->EnableItem(mpPopupMenu
->GetItemId("delete"), !mbPreview
);
255 mpPopupMenu
->EnableItem(mpPopupMenu
->GetItemId("title"));
256 mpPopupMenu
->EnableItem(mpPopupMenu
->GetItemId("copy"));
257 mpPopupMenu
->EnableItem(mpPopupMenu
->GetItemId("paste"));
261 css::uno::Reference
< css::frame::XDispatchProvider
> xDispatchProvider(
262 GalleryBrowser2::GetFrame(), css::uno::UNO_QUERY
);
263 css::uno::Reference
< css::util::XURLTransformer
> xTransformer(
264 mpBrowser
->GetURLTransformer() );
265 for ( auto& rInfo
: m_aCommandInfo
)
269 CommandInfo
&rCmdInfo
= rInfo
.second
;
270 if ( xTransformer
.is() )
271 xTransformer
->parseStrict( rCmdInfo
.URL
);
273 if ( xDispatchProvider
.is() )
275 rCmdInfo
.Dispatch
= xDispatchProvider
->queryDispatch(
278 css::frame::FrameSearchFlag::SELF
);
281 if ( rCmdInfo
.Dispatch
.is() )
283 rCmdInfo
.Dispatch
->addStatusListener( this, rCmdInfo
.URL
);
284 rCmdInfo
.Dispatch
->removeStatusListener( this, rCmdInfo
.URL
);
291 if( !mpBackgroundPopup
->GetItemCount() || ( eObjKind
== SgaObjKind::SvDraw
) || ( eObjKind
== SgaObjKind::Sound
) )
292 mpPopupMenu
->EnableItem(mpPopupMenu
->GetItemId("background"), false);
295 mpPopupMenu
->EnableItem(mpPopupMenu
->GetItemId("background"));
296 mpBackgroundPopup
->SetSelectHdl( LINK( this, GalleryThemePopup
, BackgroundMenuSelectHdl
) );
299 mpPopupMenu
->RemoveDisabledEntries();
301 mpPopupMenu
->SetSelectHdl( LINK( this, GalleryThemePopup
, MenuSelectHdl
) );
302 mpPopupMenu
->Execute( pWindow
, aPos
);
305 IMPL_LINK( GalleryThemePopup
, MenuSelectHdl
, Menu
*, pMenu
, bool )
310 OString
sIdent(pMenu
->GetCurItemIdent());
313 const CommandInfoMap::const_iterator it
= m_aCommandInfo
.find( SID_GALLERY_FORMATS
);
314 if (it
!= m_aCommandInfo
.end())
315 mpBrowser
->DispatchAdd(it
->second
.Dispatch
, it
->second
.URL
);
318 mpBrowser
->Execute(sIdent
);
323 IMPL_LINK( GalleryThemePopup
, BackgroundMenuSelectHdl
, Menu
*, pMenu
, bool )
328 sal_uInt16
nPos( pMenu
->GetCurItemId() - 1 );
329 OUString
aURL( mpBrowser
->GetURL().GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
330 OUString
aFilterName( mpBrowser
->GetFilterName() );
332 css::uno::Sequence
< css::beans::PropertyValue
> aArgs( 6 );
333 aArgs
[0].Name
= "Background.Transparent";
334 aArgs
[0].Value
<<= sal_Int32( 0 ); // 0 - 100
335 aArgs
[1].Name
= "Background.BackColor";
336 aArgs
[1].Value
<<= sal_Int32( - 1 );
337 aArgs
[2].Name
= "Background.URL";
338 aArgs
[2].Value
<<= aURL
;
339 aArgs
[3].Name
= "Background.Filtername"; // FIXME should be FilterName
340 aArgs
[3].Value
<<= aFilterName
;
341 aArgs
[4].Name
= "Background.Position";
342 aArgs
[4].Value
<<= css::style::GraphicLocation_TILED
;
343 aArgs
[5].Name
= "Position";
344 aArgs
[5].Value
<<= nPos
;
346 const CommandInfoMap::const_iterator it
= m_aCommandInfo
.find( SID_GALLERY_BG_BRUSH
);
347 if ( it
!= m_aCommandInfo
.end() )
348 Execute( it
->second
, aArgs
);
353 } // end anonymous namespace
356 GalleryToolBox::GalleryToolBox( GalleryBrowser2
* pParent
) :
357 ToolBox( pParent
, WB_TABSTOP
)
361 void GalleryToolBox::KeyInput( const KeyEvent
& rKEvt
)
363 if( !static_cast< GalleryBrowser2
* >( GetParent() )->KeyInput( rKEvt
, this ) )
365 if( KEY_ESCAPE
!= rKEvt
.GetKeyCode().GetCode() )
366 ToolBox::KeyInput(rKEvt
);
371 GalleryBrowser2::GalleryBrowser2( vcl::Window
* pParent
, Gallery
* pGallery
) :
372 Control ( pParent
, WB_TABSTOP
),
373 mpGallery ( pGallery
),
374 mpCurTheme ( nullptr ),
375 mpIconView ( VclPtr
<GalleryIconView
>::Create( this, nullptr ) ),
376 mpListView ( VclPtr
<GalleryListView
>::Create( this, nullptr ) ),
377 mpPreview ( VclPtr
<GalleryPreview
>::Create(this) ),
378 maViewBox ( VclPtr
<GalleryToolBox
>::Create(this) ),
379 maSeparator ( VclPtr
<FixedLine
>::Create(this, WB_VERT
) ),
380 maInfoBar ( VclPtr
<FixedText
>::Create(this, WB_LEFT
| WB_VCENTER
) ),
381 mnCurActionPos ( 0xffffffff ),
382 meMode ( GALLERYBROWSERMODE_NONE
),
383 meLastMode ( GALLERYBROWSERMODE_NONE
)
386 m_xContext
.set( ::comphelper::getProcessComponentContext() );
389 m_xContext
->getServiceManager()->createInstanceWithContext(
390 "com.sun.star.util.URLTransformer", m_xContext
),
391 css::uno::UNO_QUERY
);
394 vcl::Font
aInfoFont( maInfoBar
->GetControlFont() );
396 maMiscOptions
.AddListenerLink( LINK( this, GalleryBrowser2
, MiscHdl
) );
398 maViewBox
->InsertItem( TBX_ID_ICON
, aDummyImage
);
399 maViewBox
->SetItemBits( TBX_ID_ICON
, ToolBoxItemBits::RADIOCHECK
| ToolBoxItemBits::AUTOCHECK
);
400 maViewBox
->SetHelpId( TBX_ID_ICON
, HID_GALLERY_ICONVIEW
);
401 maViewBox
->SetQuickHelpText( TBX_ID_ICON
, SvxResId(RID_SVXSTR_GALLERY_ICONVIEW
) );
403 maViewBox
->InsertItem( TBX_ID_LIST
, aDummyImage
);
404 maViewBox
->SetItemBits( TBX_ID_LIST
, ToolBoxItemBits::RADIOCHECK
| ToolBoxItemBits::AUTOCHECK
);
405 maViewBox
->SetHelpId( TBX_ID_LIST
, HID_GALLERY_LISTVIEW
);
406 maViewBox
->SetQuickHelpText( TBX_ID_LIST
, SvxResId(RID_SVXSTR_GALLERY_LISTVIEW
) );
409 maViewBox
->SetSelectHdl( LINK( this, GalleryBrowser2
, SelectTbxHdl
) );
412 mpIconView
->SetAccessibleName(SvxResId(RID_SVXSTR_GALLERY_THEMEITEMS
));
413 mpListView
->SetAccessibleName(SvxResId(RID_SVXSTR_GALLERY_THEMEITEMS
));
418 mpIconView
->SetSelectHdl( LINK( this, GalleryBrowser2
, SelectObjectValueSetHdl
) );
419 mpListView
->SetSelectHdl( LINK( this, GalleryBrowser2
, SelectObjectHdl
) );
423 SetMode( ( GALLERYBROWSERMODE_PREVIEW
!= GalleryBrowser2::meInitMode
) ? GalleryBrowser2::meInitMode
: GALLERYBROWSERMODE_ICON
);
425 if(maInfoBar
->GetText().isEmpty())
426 mpIconView
->SetAccessibleRelationLabeledBy(mpIconView
);
428 mpIconView
->SetAccessibleRelationLabeledBy(maInfoBar
.get());
431 GalleryBrowser2::~GalleryBrowser2()
436 void GalleryBrowser2::dispose()
438 maMiscOptions
.RemoveListenerLink( LINK( this, GalleryBrowser2
, MiscHdl
) );
440 mpPreview
.disposeAndClear();
441 mpListView
.disposeAndClear();
442 mpIconView
.disposeAndClear();
445 mpGallery
->ReleaseTheme( mpCurTheme
, *this );
446 maSeparator
.disposeAndClear();
447 maInfoBar
.disposeAndClear();
448 maViewBox
.disposeAndClear();
452 void GalleryBrowser2::InitSettings()
454 vcl::Font
aInfoFont( maInfoBar
->GetControlFont() );
456 aInfoFont
.SetWeight( WEIGHT_BOLD
);
457 aInfoFont
.SetColor( GALLERY_FG_COLOR
);
458 maInfoBar
->SetControlFont( aInfoFont
);
460 maInfoBar
->SetBackground( Wallpaper( GALLERY_DLG_COLOR
) );
461 maInfoBar
->SetControlBackground( GALLERY_DLG_COLOR
);
463 maSeparator
->SetBackground( Wallpaper( GALLERY_BG_COLOR
) );
464 maSeparator
->SetControlBackground( GALLERY_BG_COLOR
);
465 maSeparator
->SetControlForeground( GALLERY_FG_COLOR
);
468 void GalleryBrowser2::DataChanged( const DataChangedEvent
& rDCEvt
)
470 if ( ( rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) && ( rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
473 Control::DataChanged( rDCEvt
);
476 void GalleryBrowser2::Resize()
484 const Size
aOutSize( GetOutputSizePixel() );
485 const Size
aBoxSize( maViewBox
->GetOutputSizePixel() );
486 const long nOffset
= 2, nSepWidth
= 2;
487 const long nInfoBarX
= aBoxSize
.Width() + ( nOffset
* 3 ) + nSepWidth
;
488 const Point
aPt( 0, aBoxSize
.Height() + 3 );
489 const Size
aSz( aOutSize
.Width(), aOutSize
.Height() - aPt
.Y() );
491 maSeparator
->SetPosSizePixel( Point( aBoxSize
.Width() + nOffset
, 0 ), Size( nSepWidth
, aBoxSize
.Height() ) );
492 maInfoBar
->SetPosSizePixel( Point( nInfoBarX
, 0 ), Size( aOutSize
.Width() - nInfoBarX
, aBoxSize
.Height() ) );
494 mpIconView
->SetPosSizePixel( aPt
, aSz
);
495 mpListView
->SetPosSizePixel( aPt
, aSz
);
496 mpPreview
->SetPosSizePixel( aPt
, aSz
);
500 case GALLERYBROWSERMODE_ICON
: mpIconView
->Show(); break;
501 case GALLERYBROWSERMODE_LIST
: mpListView
->Show(); break;
502 case GALLERYBROWSERMODE_PREVIEW
: mpPreview
->Show(); break;
509 void GalleryBrowser2::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
511 const GalleryHint
& rGalleryHint
= static_cast<const GalleryHint
&>(rHint
);
513 switch( rGalleryHint
.GetType() )
515 case GalleryHintType::THEME_UPDATEVIEW
:
517 if( GALLERYBROWSERMODE_PREVIEW
== GetMode() )
518 SetMode( meLastMode
);
520 ImplUpdateViews( reinterpret_cast<size_t>(rGalleryHint
.GetData1()) + 1 );
529 sal_Int8
GalleryBrowser2::AcceptDrop( DropTargetHelper
& rTarget
)
531 sal_Int8 nRet
= DND_ACTION_NONE
;
533 if( mpCurTheme
&& !mpCurTheme
->IsReadOnly() )
535 if( !mpCurTheme
->IsDragging() )
537 if( rTarget
.IsDropFormatSupported( SotClipboardFormatId::DRAWING
) ||
538 rTarget
.IsDropFormatSupported( SotClipboardFormatId::FILE_LIST
) ||
539 rTarget
.IsDropFormatSupported( SotClipboardFormatId::SIMPLE_FILE
) ||
540 rTarget
.IsDropFormatSupported( SotClipboardFormatId::SVXB
) ||
541 rTarget
.IsDropFormatSupported( SotClipboardFormatId::GDIMETAFILE
) ||
542 rTarget
.IsDropFormatSupported( SotClipboardFormatId::BITMAP
) )
544 nRet
= DND_ACTION_COPY
;
548 nRet
= DND_ACTION_COPY
;
554 sal_Int8
GalleryBrowser2::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
556 sal_Int8 nRet
= DND_ACTION_NONE
;
561 const sal_uInt32 nItemId
= ImplGetSelectedItemId( &rEvt
.maPosPixel
, aSelPos
);
562 const sal_uInt32 nInsertPos
= (nItemId
? (nItemId
- 1) : mpCurTheme
->GetObjectCount());
564 if( mpCurTheme
->IsDragging() )
565 mpCurTheme
->ChangeObjectPos( mpCurTheme
->GetDragPos(), nInsertPos
);
567 nRet
= mpCurTheme
->InsertTransferable( rEvt
.maDropEvent
.Transferable
, nInsertPos
) ? 1 : 0;
573 void GalleryBrowser2::StartDrag( const Point
* pDragPoint
)
578 const sal_uInt32 nItemId
= ImplGetSelectedItemId( pDragPoint
, aSelPos
);
581 mpCurTheme
->StartDrag( this, nItemId
- 1 );
585 void GalleryBrowser2::TogglePreview()
587 SetMode( ( GALLERYBROWSERMODE_PREVIEW
!= GetMode() ) ? GALLERYBROWSERMODE_PREVIEW
: meLastMode
);
588 GetViewWindow()->GrabFocus();
591 void GalleryBrowser2::ShowContextMenu( const Point
* pContextPoint
)
594 const sal_uInt32 nItemId
= ImplGetSelectedItemId( pContextPoint
, aSelPos
);
596 if( mpCurTheme
&& nItemId
&& ( nItemId
<= mpCurTheme
->GetObjectCount() ) )
598 ImplSelectItemId( nItemId
);
600 css::uno::Reference
< css::frame::XFrame
> xFrame( GetFrame() );
603 mnCurActionPos
= nItemId
- 1;
604 rtl::Reference
< GalleryThemePopup
> rPopup(
605 new GalleryThemePopup(
608 GALLERYBROWSERMODE_PREVIEW
== GetMode(),
610 rPopup
->ExecutePopup( this, aSelPos
);
615 bool GalleryBrowser2::KeyInput( const KeyEvent
& rKEvt
, vcl::Window
* /*pWindow*/ )
618 const sal_uInt32 nItemId
= ImplGetSelectedItemId( nullptr, aSelPos
);
620 svx::sidebar::GalleryControl
* pParentControl
= dynamic_cast<svx::sidebar::GalleryControl
*>(GetParent());
621 if (pParentControl
!= nullptr)
622 bRet
= pParentControl
->GalleryKeyInput(rKEvt
);
624 if( !bRet
&& !maViewBox
->HasFocus() && nItemId
&& mpCurTheme
)
626 OString sExecuteIdent
;
629 mpCurTheme
->GetURL( nItemId
- 1, aURL
);
631 const bool bValidURL
= ( aURL
.GetProtocol() != INetProtocol::NotValid
);
632 bool bPreview
= bValidURL
;
633 bool bDelete
= false;
636 if( !mpCurTheme
->IsReadOnly() && mpCurTheme
->GetObjectCount() )
638 bDelete
= ( GALLERYBROWSERMODE_PREVIEW
!= GetMode() );
642 switch( rKEvt
.GetKeyCode().GetCode() )
659 // Inserting a gallery item in the document must be dispatched
662 DispatchAdd(css::uno::Reference
<css::frame::XDispatch
>(), css::util::URL());
672 sExecuteIdent
= "delete";
679 sExecuteIdent
= "title";
687 if (!sExecuteIdent
.isEmpty())
689 Execute(sExecuteIdent
);
697 void GalleryBrowser2::SelectTheme( const OUString
& rThemeName
)
699 mpIconView
.disposeAndClear();
700 mpListView
.disposeAndClear();
701 mpPreview
.disposeAndClear();
704 mpGallery
->ReleaseTheme( mpCurTheme
, *this );
706 mpCurTheme
= mpGallery
->AcquireTheme( rThemeName
, *this );
708 mpIconView
= VclPtr
<GalleryIconView
>::Create( this, mpCurTheme
);
709 mpListView
= VclPtr
<GalleryListView
>::Create( this, mpCurTheme
);
710 mpPreview
= VclPtr
<GalleryPreview
>::Create( this, WB_TABSTOP
| WB_BORDER
, mpCurTheme
);
712 mpIconView
->SetAccessibleName(SvxResId(RID_SVXSTR_GALLERY_THEMEITEMS
));
713 mpListView
->SetAccessibleName(SvxResId(RID_SVXSTR_GALLERY_THEMEITEMS
));
714 mpPreview
->SetAccessibleName(SvxResId(RID_SVXSTR_GALLERY_PREVIEW
));
716 mpIconView
->SetSelectHdl( LINK( this, GalleryBrowser2
, SelectObjectValueSetHdl
) );
717 mpListView
->SetSelectHdl( LINK( this, GalleryBrowser2
, SelectObjectHdl
) );
719 if( GALLERYBROWSERMODE_PREVIEW
== GetMode() )
723 ImplUpdateViews( 1 );
725 maViewBox
->EnableItem( TBX_ID_ICON
);
726 maViewBox
->EnableItem( TBX_ID_LIST
);
727 maViewBox
->CheckItem( ( GALLERYBROWSERMODE_ICON
== GetMode() ) ? TBX_ID_ICON
: TBX_ID_LIST
);
729 if(maInfoBar
->GetText().isEmpty())
730 mpIconView
->SetAccessibleRelationLabeledBy(mpIconView
);
732 mpIconView
->SetAccessibleRelationLabeledBy(maInfoBar
.get());
735 void GalleryBrowser2::SetMode( GalleryBrowserMode eMode
)
737 if( GetMode() != eMode
)
739 meLastMode
= GetMode();
743 case GALLERYBROWSERMODE_ICON
:
748 mpPreview
->SetGraphic( Graphic() );
749 GalleryPreview::PreviewMedia( INetURLObject() );
753 maViewBox
->EnableItem( TBX_ID_ICON
);
754 maViewBox
->EnableItem( TBX_ID_LIST
);
756 maViewBox
->CheckItem( TBX_ID_ICON
);
757 maViewBox
->CheckItem( TBX_ID_LIST
, false );
761 case GALLERYBROWSERMODE_LIST
:
766 mpPreview
->SetGraphic( Graphic() );
767 GalleryPreview::PreviewMedia( INetURLObject() );
771 maViewBox
->EnableItem( TBX_ID_ICON
);
772 maViewBox
->EnableItem( TBX_ID_LIST
);
774 maViewBox
->CheckItem( TBX_ID_ICON
, false );
775 maViewBox
->CheckItem( TBX_ID_LIST
);
779 case GALLERYBROWSERMODE_PREVIEW
:
783 const sal_uInt32 nItemId
= ImplGetSelectedItemId( nullptr, aSelPos
);
787 const sal_uInt32 nPos
= nItemId
- 1;
793 mpCurTheme
->GetGraphic( nPos
, aGraphic
);
795 mpPreview
->SetGraphic( aGraphic
);
798 if( mpCurTheme
&& mpCurTheme
->GetObjectKind( nPos
) == SgaObjKind::Sound
)
799 GalleryPreview::PreviewMedia( mpCurTheme
->GetObjectURL( nPos
) );
801 maViewBox
->EnableItem( TBX_ID_ICON
, false );
802 maViewBox
->EnableItem( TBX_ID_LIST
, false );
811 GalleryBrowser2::meInitMode
= meMode
= eMode
;
815 vcl::Window
* GalleryBrowser2::GetViewWindow() const
821 case GALLERYBROWSERMODE_LIST
: pRet
= mpListView
; break;
822 case GALLERYBROWSERMODE_PREVIEW
: pRet
= mpPreview
; break;
832 void GalleryBrowser2::Travel( GalleryBrowserTravel eTravel
)
837 const sal_uInt32 nItemId
= ImplGetSelectedItemId( nullptr, aSelPos
);
841 sal_uInt32 nNewItemId
= nItemId
;
845 case GalleryBrowserTravel::First
: nNewItemId
= 1; break;
846 case GalleryBrowserTravel::Last
: nNewItemId
= mpCurTheme
->GetObjectCount(); break;
847 case GalleryBrowserTravel::Previous
: nNewItemId
--; break;
848 case GalleryBrowserTravel::Next
: nNewItemId
++; break;
855 else if( nNewItemId
> mpCurTheme
->GetObjectCount() )
856 nNewItemId
= mpCurTheme
->GetObjectCount();
858 if( nNewItemId
!= nItemId
)
860 ImplSelectItemId( nNewItemId
);
863 if( GALLERYBROWSERMODE_PREVIEW
== GetMode() )
866 const sal_uInt32 nPos
= nNewItemId
- 1;
868 mpCurTheme
->GetGraphic( nPos
, aGraphic
);
869 mpPreview
->SetGraphic( aGraphic
);
871 if( SgaObjKind::Sound
== mpCurTheme
->GetObjectKind( nPos
) )
872 GalleryPreview::PreviewMedia( mpCurTheme
->GetObjectURL( nPos
) );
874 mpPreview
->Invalidate();
881 void GalleryBrowser2::ImplUpdateViews( sal_uInt16 nSelectionId
)
892 for (sal_uInt32 i
= 0, nCount
= mpCurTheme
->GetObjectCount(); i
< nCount
;)
894 mpListView
->RowInserted( i
++ );
895 mpIconView
->InsertItem( static_cast<sal_uInt16
>(i
) );
898 ImplSelectItemId( std::min
<sal_uInt16
>( nSelectionId
, mpCurTheme
->GetObjectCount() ) );
903 case GALLERYBROWSERMODE_ICON
: mpIconView
->Show(); break;
904 case GALLERYBROWSERMODE_LIST
: mpListView
->Show(); break;
905 case GALLERYBROWSERMODE_PREVIEW
: mpPreview
->Show(); break;
914 void GalleryBrowser2::ImplUpdateInfoBar()
917 maInfoBar
->SetText( mpCurTheme
->GetName() );
920 sal_uInt32
GalleryBrowser2::ImplGetSelectedItemId( const Point
* pSelPos
, Point
& rSelPos
)
922 const Size
aOutputSizePixel( GetOutputSizePixel() );
925 if( GALLERYBROWSERMODE_PREVIEW
== GetMode() )
927 nRet
= ( ( GALLERYBROWSERMODE_ICON
== meLastMode
) ? mpIconView
->GetSelectedItemId() : ( mpListView
->FirstSelectedRow() + 1 ) );
930 rSelPos
= GetPointerPosPixel();
932 rSelPos
= Point( aOutputSizePixel
.Width() >> 1, aOutputSizePixel
.Height() >> 1 );
934 else if( GALLERYBROWSERMODE_ICON
== GetMode() )
938 nRet
= mpIconView
->GetItemId( *pSelPos
);
939 rSelPos
= GetPointerPosPixel();
943 nRet
= mpIconView
->GetSelectedItemId();
944 rSelPos
= mpIconView
->GetItemRect(nRet
).Center();
951 nRet
= mpListView
->GetRowAtYPosPixel( pSelPos
->Y() ) + 1;
952 rSelPos
= GetPointerPosPixel();
956 nRet
= mpListView
->FirstSelectedRow() + 1;
957 rSelPos
= mpListView
->GetFieldRectPixel( static_cast<sal_uInt16
>(nRet
), 1 ).Center();
961 rSelPos
.setX( std::max( std::min( rSelPos
.X(), aOutputSizePixel
.Width() - 1 ), 0L ) );
962 rSelPos
.setY( std::max( std::min( rSelPos
.Y(), aOutputSizePixel
.Height() - 1 ), 0L ) );
964 if( nRet
&& ( !mpCurTheme
|| ( nRet
> mpCurTheme
->GetObjectCount() ) ) )
972 void GalleryBrowser2::ImplSelectItemId(sal_uInt32 nItemId
)
977 mpIconView
->SelectItem(nItemId
);
978 mpListView
->SelectRow( nItemId
- 1 );
982 css::uno::Reference
< css::frame::XFrame
>
983 GalleryBrowser2::GetFrame()
985 css::uno::Reference
< css::frame::XFrame
> xFrame
;
986 SfxViewFrame
* pCurrentViewFrame
= SfxViewFrame::Current();
987 if ( pCurrentViewFrame
)
989 SfxBindings
& rBindings
= pCurrentViewFrame
->GetBindings();
990 xFrame
.set( rBindings
.GetActiveFrame() );
996 void GalleryBrowser2::DispatchAdd(
997 const css::uno::Reference
< css::frame::XDispatch
> &rxDispatch
,
998 const css::util::URL
&rURL
)
1001 const sal_uInt32 nItemId
= ImplGetSelectedItemId( nullptr, aSelPos
);
1003 if( !mpCurTheme
|| !nItemId
)
1006 mnCurActionPos
= nItemId
- 1;
1008 css::uno::Reference
< css::frame::XDispatch
> xDispatch( rxDispatch
);
1009 css::util::URL aURL
= rURL
;
1011 if ( !xDispatch
.is() )
1013 css::uno::Reference
< css::frame::XDispatchProvider
> xDispatchProvider(
1014 GetFrame(), css::uno::UNO_QUERY
);
1015 if ( !xDispatchProvider
.is() || !m_xTransformer
.is() )
1018 aURL
.Complete
= ".uno:InsertGalleryPic";
1019 m_xTransformer
->parseStrict( aURL
);
1020 xDispatch
= xDispatchProvider
->queryDispatch(
1023 css::frame::FrameSearchFlag::SELF
);
1026 if ( !xDispatch
.is() )
1030 OUString aFilterName
;
1031 css::uno::Reference
< css::lang::XComponent
> xDrawing
;
1032 css::uno::Reference
< css::graphic::XGraphic
> xGraphic
;
1034 aFilterName
= GetFilterName();
1036 switch( mpCurTheme
->GetObjectKind( mnCurActionPos
) )
1038 case SgaObjKind::Bitmap
:
1039 case SgaObjKind::Animation
:
1040 case SgaObjKind::Inet
:
1041 // TODO drawing objects are inserted as drawings only via drag&drop
1042 case SgaObjKind::SvDraw
:
1043 nType
= css::gallery::GalleryItemType::GRAPHIC
;
1046 case SgaObjKind::Sound
:
1047 nType
= css::gallery::GalleryItemType::MEDIA
;
1051 nType
= css::gallery::GalleryItemType::EMPTY
;
1056 bool bGraphic
= mpCurTheme
->GetGraphic( mnCurActionPos
, aGraphic
);
1057 if ( bGraphic
&& !aGraphic
.IsNone() )
1058 xGraphic
.set( aGraphic
.GetXGraphic() );
1059 OSL_ENSURE( xGraphic
.is(), "gallery item is graphic, but the reference is invalid!" );
1061 css::uno::Sequence
< css::beans::PropertyValue
> aSeq( SVXGALLERYITEM_PARAMS
);
1063 aSeq
[0].Name
= SVXGALLERYITEM_TYPE
;
1064 aSeq
[0].Value
<<= nType
;
1065 aSeq
[1].Name
= SVXGALLERYITEM_URL
;
1066 aSeq
[1].Value
<<= OUString();
1067 aSeq
[2].Name
= SVXGALLERYITEM_FILTER
;
1068 aSeq
[2].Value
<<= aFilterName
;
1069 aSeq
[3].Name
= SVXGALLERYITEM_DRAWING
;
1070 aSeq
[3].Value
<<= xDrawing
;
1071 aSeq
[4].Name
= SVXGALLERYITEM_GRAPHIC
;
1072 aSeq
[4].Value
<<= xGraphic
;
1074 css::uno::Sequence
< css::beans::PropertyValue
> aArgs( 1 );
1075 aArgs
[0].Name
= SVXGALLERYITEM_ARGNAME
;
1076 aArgs
[0].Value
<<= aSeq
;
1078 std::unique_ptr
<DispatchInfo
> pInfo(new DispatchInfo
);
1079 pInfo
->TargetURL
= aURL
;
1080 pInfo
->Arguments
= aArgs
;
1081 pInfo
->Dispatch
= xDispatch
;
1083 if ( Application::PostUserEvent(
1084 LINK( nullptr, GalleryBrowser2
, AsyncDispatch_Impl
), pInfo
.get() ) )
1088 void GalleryBrowser2::Execute(const OString
&rIdent
)
1091 const sal_uInt32 nItemId
= ImplGetSelectedItemId( nullptr, aSelPos
);
1093 if( mpCurTheme
&& nItemId
)
1095 mnCurActionPos
= nItemId
- 1;
1097 if (rIdent
== "preview")
1098 SetMode( ( GALLERYBROWSERMODE_PREVIEW
!= GetMode() ) ? GALLERYBROWSERMODE_PREVIEW
: meLastMode
);
1099 else if (rIdent
== "delete")
1101 if (!mpCurTheme
->IsReadOnly())
1103 std::unique_ptr
<weld::Builder
> xBuilder(Application::CreateBuilder(GetFrameWeld(), "svx/ui/querydeleteobjectdialog.ui"));
1104 std::unique_ptr
<weld::MessageDialog
> xQuery(xBuilder
->weld_message_dialog("QueryDeleteObjectDialog"));
1105 if (xQuery
->run() == RET_YES
)
1107 mpCurTheme
->RemoveObject( mnCurActionPos
);
1111 else if (rIdent
== "title")
1113 std::unique_ptr
<SgaObject
> pObj
= mpCurTheme
->AcquireObject( mnCurActionPos
);
1117 const OUString
aOldTitle( GetItemText( *pObj
, GalleryItemFlags::Title
) );
1119 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
1120 ScopedVclPtr
<AbstractTitleDialog
> aDlg(pFact
->CreateTitleDialog(GetFrameWeld(), aOldTitle
));
1121 if( aDlg
->Execute() == RET_OK
)
1123 OUString
aNewTitle( aDlg
->GetTitle() );
1125 if( ( aNewTitle
.isEmpty() && !pObj
->GetTitle().isEmpty() ) || ( aNewTitle
!= aOldTitle
) )
1127 if( aNewTitle
.isEmpty() )
1128 aNewTitle
= "__<empty>__";
1130 pObj
->SetTitle( aNewTitle
);
1131 mpCurTheme
->InsertObject( *pObj
);
1136 else if (rIdent
== "copy")
1138 vcl::Window
* pWindow
;
1142 case GALLERYBROWSERMODE_ICON
: pWindow
= mpIconView
; break;
1143 case GALLERYBROWSERMODE_LIST
: pWindow
= mpListView
; break;
1144 case GALLERYBROWSERMODE_PREVIEW
: pWindow
= mpPreview
; break;
1151 mpCurTheme
->CopyToClipboard( pWindow
, mnCurActionPos
);
1153 else if (rIdent
== "paste")
1155 if( !mpCurTheme
->IsReadOnly() )
1157 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( this ) );
1158 mpCurTheme
->InsertTransferable( aDataHelper
.GetTransferable(), mnCurActionPos
);
1164 OUString
GalleryBrowser2::GetItemText( const SgaObject
& rObj
, GalleryItemFlags nItemTextFlags
)
1168 const INetURLObject
& aURL(rObj
.GetURL());
1170 if( nItemTextFlags
& GalleryItemFlags::Title
)
1172 OUString
aTitle( rObj
.GetTitle() );
1174 if( aTitle
.isEmpty() )
1175 aTitle
= aURL
.getBase( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DecodeMechanism::Unambiguous
);
1177 if( aTitle
.isEmpty() )
1179 aTitle
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous
);
1180 aTitle
= aTitle
.copy( aTitle
.lastIndexOf('/')+1 );
1186 if( nItemTextFlags
& GalleryItemFlags::Path
)
1188 const OUString
aPath( aURL
.getFSysPath( FSysStyle::Detect
) );
1190 if( !aPath
.isEmpty() && ( nItemTextFlags
& GalleryItemFlags::Title
) )
1193 aRet
+= aURL
.getFSysPath( FSysStyle::Detect
);
1195 if( !aPath
.isEmpty() && ( nItemTextFlags
& GalleryItemFlags::Title
) )
1202 INetURLObject
GalleryBrowser2::GetURL() const
1206 if( mpCurTheme
&& mnCurActionPos
!= 0xffffffff )
1207 aURL
= mpCurTheme
->GetObjectURL( mnCurActionPos
);
1212 OUString
GalleryBrowser2::GetFilterName() const
1214 OUString aFilterName
;
1216 if( mpCurTheme
&& mnCurActionPos
!= 0xffffffff )
1218 const SgaObjKind eObjKind
= mpCurTheme
->GetObjectKind( mnCurActionPos
);
1220 if( ( SgaObjKind::Bitmap
== eObjKind
) || ( SgaObjKind::Animation
== eObjKind
) )
1222 GraphicFilter
& rFilter
= GraphicFilter::GetGraphicFilter();
1224 mpCurTheme
->GetURL( mnCurActionPos
, aURL
);
1225 sal_uInt16 nFilter
= rFilter
.GetImportFormatNumberForShortName(aURL
.GetFileExtension());
1227 if( GRFILTER_FORMAT_DONTKNOW
!= nFilter
)
1228 aFilterName
= rFilter
.GetImportFormatName( nFilter
);
1236 IMPL_LINK_NOARG(GalleryBrowser2
, SelectObjectValueSetHdl
, ValueSet
*, void)
1238 ImplUpdateInfoBar();
1241 IMPL_LINK_NOARG(GalleryBrowser2
, SelectObjectHdl
, GalleryListView
*, void)
1243 ImplUpdateInfoBar();
1246 IMPL_LINK( GalleryBrowser2
, SelectTbxHdl
, ToolBox
*, pBox
, void )
1248 if( pBox
->GetCurItemId() == TBX_ID_ICON
)
1249 SetMode( GALLERYBROWSERMODE_ICON
);
1250 else if( pBox
->GetCurItemId() == TBX_ID_LIST
)
1251 SetMode( GALLERYBROWSERMODE_LIST
);
1254 IMPL_LINK_NOARG(GalleryBrowser2
, MiscHdl
, LinkParamNone
*, void)
1256 maViewBox
->SetOutStyle( maMiscOptions
.GetToolboxStyle() );
1258 BitmapEx
aIconBmpEx(RID_SVXBMP_GALLERY_VIEW_ICON
);
1259 BitmapEx
aListBmpEx(RID_SVXBMP_GALLERY_VIEW_LIST
);
1261 if( maMiscOptions
.AreCurrentSymbolsLarge() )
1263 const Size
aLargeSize( 24, 24);
1265 aIconBmpEx
.Scale( aLargeSize
);
1266 aListBmpEx
.Scale( aLargeSize
);
1269 maViewBox
->SetItemImage(TBX_ID_ICON
, Image(aIconBmpEx
));
1270 maViewBox
->SetItemImage(TBX_ID_LIST
, Image(aListBmpEx
));
1271 maViewBox
->SetSizePixel( maViewBox
->CalcWindowSizePixel() );
1276 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */