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 <sal/config.h>
22 #include <tools/datetime.hxx>
23 #include <tools/wldcrd.hxx>
25 #include <vcl/commandevent.hxx>
26 #include <vcl/event.hxx>
27 #include <vcl/svapp.hxx>
28 #include <vcl/weld.hxx>
29 #include <vcl/graphicfilter.hxx>
30 #include <vcl/virdev.hxx>
31 #include <com/sun/star/ucb/ContentCreationException.hpp>
32 #include <sfx2/app.hxx>
33 #include <sfx2/viewfrm.hxx>
34 #include <sfx2/bindings.hxx>
36 #include <svx/svxids.hrc>
37 #include <svx/gallery1.hxx>
38 #include <svx/galtheme.hxx>
39 #include <svx/galmisc.hxx>
40 #include <svx/galctrl.hxx>
41 #include <galbrws1.hxx>
42 #include <svx/strings.hrc>
44 #include <svx/dialmgr.hxx>
45 #include <svx/galleryitem.hxx>
46 #include <comphelper/dispatchcommand.hxx>
47 #include <comphelper/propertyvalue.hxx>
48 #include <com/sun/star/beans/PropertyValue.hpp>
49 #include <comphelper/processfactory.hxx>
50 #include <com/sun/star/frame/FrameSearchFlag.hpp>
51 #include <com/sun/star/frame/XDispatchProvider.hpp>
52 #include <com/sun/star/frame/XFrame.hpp>
53 #include <com/sun/star/gallery/GalleryItemType.hpp>
54 #include <com/sun/star/graphic/XGraphic.hpp>
55 #include <com/sun/star/lang/XComponent.hpp>
56 #include <com/sun/star/style/GraphicLocation.hpp>
57 #include <svx/svxdlg.hxx>
59 #include <bitmaps.hlst>
60 #include <osl/diagnose.h>
61 #include <o3tl/string_view.hxx>
63 using namespace ::com::sun::star
;
70 css::util::URL TargetURL
;
71 css::uno::Sequence
< css::beans::PropertyValue
> Arguments
;
72 css::uno::Reference
< css::frame::XDispatch
> Dispatch
;
78 css::uno::Reference
< css::frame::XDispatch
> Dispatch
;
80 explicit CommandInfo( const OUString
&rURL
)
86 class GalleryThemePopup
: public ::cppu::WeakImplHelper
< css::frame::XStatusListener
>
89 const GalleryTheme
* mpTheme
;
90 sal_uInt32 mnObjectPos
;
92 std::unique_ptr
<weld::Builder
> mxBuilder
;
93 std::unique_ptr
<weld::Menu
> mxPopupMenu
;
94 std::unique_ptr
<weld::Menu
> mxBackgroundPopup
;
95 GalleryBrowser1
* mpBrowser
;
97 typedef std::map
< int, CommandInfo
> CommandInfoMap
;
98 CommandInfoMap m_aCommandInfo
;
100 static void Execute( const CommandInfo
&rCmdInfo
,
101 const css::uno::Sequence
< css::beans::PropertyValue
> &rArguments
);
103 void MenuSelectHdl(std::u16string_view rIdent
);
104 void BackgroundMenuSelectHdl(sal_uInt16 nId
);
106 GalleryThemePopup(weld::Widget
* pParent
,
107 const GalleryTheme
* pTheme
,
108 sal_uInt32 nObjectPos
,
110 GalleryBrowser1
* pBrowser
);
112 void ExecutePopup(weld::Widget
* pParent
, const ::Point
&rPos
);
114 virtual void SAL_CALL
statusChanged( const css::frame::FeatureStateEvent
&rEvent
) override
;
115 virtual void SAL_CALL
disposing( const css::lang::EventObject
&rSource
) override
;
120 GalleryBrowser1::GalleryBrowser1(
121 weld::Builder
& rBuilder
,
122 Gallery
* pGallery
)//,
123 //std::function<void ()> aThemeSelectionHandler)
125 mxNewTheme(rBuilder
.weld_button(u
"insert"_ustr
)),
126 mxThemes(rBuilder
.weld_tree_view(u
"themelist"_ustr
)),
127 mxMoreGalleries(rBuilder
.weld_button(u
"btnMoreGalleries"_ustr
)),
128 mpGallery ( pGallery
),
129 mpExchangeData ( new ExchangeData
),
130 aImgNormal ( RID_SVXBMP_THEME_NORMAL
),
131 aImgDefault ( RID_SVXBMP_THEME_DEFAULT
),
132 aImgReadOnly ( RID_SVXBMP_THEME_READONLY
)
133 //maThemeSelectionHandler(std::move(aThemeSelectionHandler))
134 , mpCurTheme(nullptr)
135 , mxIconView(new GalleryIconView(this, rBuilder
.weld_scrolled_window(u
"galleryscroll"_ustr
, true)))
136 , mxIconViewWin(new weld::CustomWeld(rBuilder
, u
"gallery"_ustr
, *mxIconView
))
137 , mxListView(rBuilder
.weld_tree_view(u
"gallerylist"_ustr
))
138 , mxPreview(new GalleryPreview(this, rBuilder
.weld_scrolled_window(u
"previewscroll"_ustr
)))
139 , mxPreviewWin(new weld::CustomWeld(rBuilder
, u
"preview"_ustr
, *mxPreview
))
140 , mxIconButton(rBuilder
.weld_toggle_button(u
"icon"_ustr
))
141 , mxListButton(rBuilder
.weld_toggle_button(u
"list"_ustr
))
142 , mxSearchField(rBuilder
.weld_entry(u
"search"_ustr
))
143 , mxInfoBar(rBuilder
.weld_label(u
"label"_ustr
))
144 , maPreviewSize(28, 28)
145 , mnCurActionPos ( 0xffffffff )
146 , meMode ( GALLERYBROWSERMODE_NONE
)
147 , meLastMode ( GALLERYBROWSERMODE_NONE
)
148 , m_aCharacterClassficator( ::comphelper::getProcessComponentContext(), SvtSysLocale().GetLanguageTag() )
150 mxNewTheme
->connect_clicked( LINK( this, GalleryBrowser1
, ClickNewThemeHdl
) );
152 mxThemes
->make_sorted();
153 mxThemes
->connect_selection_changed(LINK(this, GalleryBrowser1
, SelectThemeHdl
));
154 mxThemes
->connect_popup_menu(LINK(this, GalleryBrowser1
, PopupMenuHdl1
));
155 mxThemes
->connect_key_press(LINK(this, GalleryBrowser1
, KeyInputHdl1
));
156 mxThemes
->set_size_request(-1, mxThemes
->get_height_rows(6));
158 mxMoreGalleries
->connect_clicked(LINK(this, GalleryBrowser1
, OnMoreGalleriesClick
));
160 // disable creation of new themes if a writable directory is not available
161 if( mpGallery
->GetUserURL().GetProtocol() == INetProtocol::NotValid
)
162 mxNewTheme
->set_sensitive(false);
164 StartListening( *mpGallery
);
166 for (size_t i
= 0, nCount
= mpGallery
->GetThemeCount(); i
< nCount
; ++i
)
167 ImplInsertThemeEntry( mpGallery
->GetThemeInfo( i
) );
169 m_xContext
.set( ::comphelper::getProcessComponentContext() );
171 int nHeight
= mxListView
->get_height_rows(10);
172 mxListView
->set_size_request(-1, nHeight
);
173 mxIconView
->set_size_request(-1, nHeight
);
176 m_xContext
->getServiceManager()->createInstanceWithContext(
177 u
"com.sun.star.util.URLTransformer"_ustr
, m_xContext
),
178 css::uno::UNO_QUERY
);
180 mxIconButton
->connect_toggled( LINK( this, GalleryBrowser1
, SelectTbxHdl
) );
181 mxListButton
->connect_toggled( LINK( this, GalleryBrowser1
, SelectTbxHdl
) );
183 mxIconView
->SetSelectHdl( LINK( this, GalleryBrowser1
, SelectObjectValueSetHdl
) );
184 mxListView
->connect_visible_range_changed(LINK(this, GalleryBrowser1
, VisRowsScrolledHdl
));
185 mxListView
->connect_size_allocate(LINK(this, GalleryBrowser1
, SizeAllocHdl
));
186 mxListView
->connect_selection_changed(LINK(this, GalleryBrowser1
, SelectObjectHdl
));
187 mxListView
->connect_popup_menu(LINK(this, GalleryBrowser1
, PopupMenuHdl2
));
188 mxListView
->connect_key_press(LINK(this, GalleryBrowser1
, KeyInputHdl2
));
189 mxListView
->connect_row_activated(LINK(this, GalleryBrowser1
, RowActivatedHdl
));
190 mxDragDropTargetHelper
.reset(new GalleryDragDrop(this, mxListView
->get_drop_target()));
191 mxListView
->connect_drag_begin(LINK(this, GalleryBrowser1
, DragBeginHdl
));
192 mxSearchField
->connect_changed( LINK( this, GalleryBrowser1
, SearchHdl
));
194 SetMode( ( GALLERYBROWSERMODE_PREVIEW
!= GalleryBrowser1::meInitMode
) ? GalleryBrowser1::meInitMode
: GALLERYBROWSERMODE_ICON
);
199 GalleryBrowser1::~GalleryBrowser1()
201 EndListening( *mpGallery
);
202 mpExchangeData
.reset();
204 mpGallery
->ReleaseTheme( mpCurTheme
, *this );
207 void GalleryBrowser1::ImplInsertThemeEntry( const GalleryThemeEntry
* pEntry
)
209 static const bool bShowHiddenThemes
= ( getenv( "GALLERY_SHOW_HIDDEN_THEMES" ) != nullptr );
211 if( !(pEntry
&& ( !pEntry
->IsHidden() || bShowHiddenThemes
)) )
214 const OUString
* pImage
;
216 if( pEntry
->IsReadOnly() )
217 pImage
= &aImgReadOnly
;
218 else if( pEntry
->IsDefault() )
219 pImage
= &aImgDefault
;
221 pImage
= &aImgNormal
;
223 mxThemes
->append(u
""_ustr
, pEntry
->GetThemeName(), *pImage
);
226 void GalleryBrowser1::ImplFillExchangeData(const GalleryTheme
& rThm
, ExchangeData
& rData
)
228 rData
.pTheme
= const_cast<GalleryTheme
*>(&rThm
);
229 rData
.aEditedTitle
= rThm
.GetName();
233 DateTime
aDateTime(rThm
.getModificationDate());
235 rData
.aThemeChangeDate
= aDateTime
;
236 rData
.aThemeChangeTime
= aDateTime
;
238 catch( const ucb::ContentCreationException
& )
241 catch( const uno::RuntimeException
& )
244 catch( const uno::Exception
& )
249 void GalleryBrowser1::ImplGetExecuteVector(std::vector
<OUString
>& o_aExec
)
251 GalleryTheme
* pTheme
= mpGallery
->AcquireTheme( GetSelectedTheme(), maLocalListener
);
256 bool bUpdateAllowed
, bRenameAllowed
, bRemoveAllowed
;
257 static const bool bIdDialog
= ( getenv( "GALLERY_ENABLE_ID_DIALOG" ) != nullptr );
259 if( pTheme
->IsReadOnly() )
260 bUpdateAllowed
= bRenameAllowed
= bRemoveAllowed
= false;
261 else if( pTheme
->IsDefault() )
263 bUpdateAllowed
= bRenameAllowed
= true;
264 bRemoveAllowed
= false;
267 bUpdateAllowed
= bRenameAllowed
= bRemoveAllowed
= true;
269 if( bUpdateAllowed
&& pTheme
->GetObjectCount() )
270 o_aExec
.emplace_back("update");
273 o_aExec
.emplace_back("rename");
276 o_aExec
.emplace_back("delete");
278 if( bIdDialog
&& !pTheme
->IsReadOnly() )
279 o_aExec
.emplace_back("assign");
281 o_aExec
.emplace_back("properties");
283 mpGallery
->ReleaseTheme( pTheme
, maLocalListener
);
286 void GalleryBrowser1::ImplGalleryThemeProperties( std::u16string_view rThemeName
, bool bCreateNew
)
288 DBG_ASSERT(!mpThemePropsDlgItemSet
, "mpThemePropsDlgItemSet already set!");
289 mpThemePropsDlgItemSet
.reset(new SfxItemSet( SfxGetpApp()->GetPool() ));
290 GalleryTheme
* pTheme
= mpGallery
->AcquireTheme( rThemeName
, maLocalListener
);
293 SAL_WARN("svx", "failed to acquire theme: " << OUString(rThemeName
));
297 ImplFillExchangeData(*pTheme
, *mpExchangeData
);
299 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
300 VclPtr
<VclAbstractDialog
> xThemePropertiesDialog
= pFact
->CreateGalleryThemePropertiesDialog(mxThemes
.get(), mpExchangeData
.get(), mpThemePropsDlgItemSet
.get());
304 xThemePropertiesDialog
->StartExecuteAsync([xThemePropertiesDialog
, this](sal_Int32 nResult
){
305 EndNewThemePropertiesDlgHdl(nResult
);
306 xThemePropertiesDialog
->disposeOnce();
311 xThemePropertiesDialog
->StartExecuteAsync([xThemePropertiesDialog
, this](sal_Int32 nResult
){
312 EndThemePropertiesDlgHdl(nResult
);
313 xThemePropertiesDialog
->disposeOnce();
318 void GalleryBrowser1::ImplEndGalleryThemeProperties(bool bCreateNew
, sal_Int32 nRet
)
322 OUString
aName( mpExchangeData
->pTheme
->GetName() );
324 if( !mpExchangeData
->aEditedTitle
.isEmpty() && aName
!= mpExchangeData
->aEditedTitle
)
326 OUString
aTitle( mpExchangeData
->aEditedTitle
);
327 sal_uInt16 nCount
= 0;
329 while( mpGallery
->HasTheme( aTitle
) && ( nCount
++ < 16000 ) )
331 aTitle
= mpExchangeData
->aEditedTitle
+ " " + OUString::number( nCount
);
334 mpGallery
->RenameTheme( aName
, aTitle
);
339 mxThemes
->select_text( mpExchangeData
->pTheme
->GetName() );
340 SelectThemeHdl( *mxThemes
);
344 OUString
aThemeName( mpExchangeData
->pTheme
->GetName() );
345 mpGallery
->ReleaseTheme( mpExchangeData
->pTheme
, maLocalListener
);
347 if ( bCreateNew
&& ( nRet
!= RET_OK
) )
349 mpGallery
->RemoveTheme( aThemeName
);
353 void GalleryBrowser1::EndNewThemePropertiesDlgHdl(sal_Int32 nResult
)
355 ImplEndGalleryThemeProperties(true, nResult
);
358 void GalleryBrowser1::EndThemePropertiesDlgHdl(sal_Int32 nResult
)
360 ImplEndGalleryThemeProperties(false, nResult
);
363 void GalleryBrowser1::ImplExecute(std::u16string_view rIdent
)
365 if (rIdent
== u
"update")
367 if (GalleryTheme
* pTheme
= mpGallery
->AcquireTheme( GetSelectedTheme(), maLocalListener
))
369 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
370 ScopedVclPtr
<VclAbstractDialog
> aActualizeProgress(pFact
->CreateActualizeProgressDialog(mxThemes
.get(), pTheme
));
372 aActualizeProgress
->Execute();
373 mpGallery
->ReleaseTheme( pTheme
, maLocalListener
);
376 else if (rIdent
== u
"delete")
378 std::unique_ptr
<weld::Builder
> xBuilder(Application::CreateBuilder(mxThemes
.get(), u
"svx/ui/querydeletethemedialog.ui"_ustr
));
379 std::unique_ptr
<weld::MessageDialog
> xQuery(xBuilder
->weld_message_dialog(u
"QueryDeleteThemeDialog"_ustr
));
380 if (xQuery
->run() == RET_YES
)
381 mpGallery
->RemoveTheme( mxThemes
->get_selected_text() );
383 else if (rIdent
== u
"rename")
385 if (GalleryTheme
* pTheme
= mpGallery
->AcquireTheme(GetSelectedTheme(), maLocalListener
))
387 const OUString
aOldName( pTheme
->GetName() );
389 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
390 ScopedVclPtr
<AbstractTitleDialog
> aDlg(pFact
->CreateTitleDialog(mxThemes
.get(), aOldName
));
392 if( aDlg
->Execute() == RET_OK
)
394 const OUString
aNewName( aDlg
->GetTitle() );
396 if( !aNewName
.isEmpty() && ( aNewName
!= aOldName
) )
398 OUString
aName( aNewName
);
399 sal_uInt16 nCount
= 0;
401 while( mpGallery
->HasTheme( aName
) && ( nCount
++ < 16000 ) )
403 aName
= aNewName
+ " " + OUString::number( nCount
);
406 mpGallery
->RenameTheme( aOldName
, aName
);
409 mpGallery
->ReleaseTheme( pTheme
, maLocalListener
);
412 else if (rIdent
== u
"assign")
414 if (GalleryTheme
* pTheme
= mpGallery
->AcquireTheme( GetSelectedTheme(), maLocalListener
))
416 if (!pTheme
->IsReadOnly())
418 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
419 ScopedVclPtr
<AbstractGalleryIdDialog
> aDlg(pFact
->CreateGalleryIdDialog(mxThemes
.get(), pTheme
));
420 if( aDlg
->Execute() == RET_OK
)
421 pTheme
->SetId( aDlg
->GetId(), true );
424 mpGallery
->ReleaseTheme( pTheme
, maLocalListener
);
427 else if (rIdent
== u
"properties")
429 ImplGalleryThemeProperties( GetSelectedTheme(), false );
433 //TODO Duplicate method
434 void GalleryBrowser1::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
436 const GalleryHint
& rGalleryHint
= static_cast<const GalleryHint
&>(rHint
);
438 switch( rGalleryHint
.GetType() )
440 case GalleryHintType::THEME_CREATED
:
441 ImplInsertThemeEntry( mpGallery
->GetThemeInfo( rGalleryHint
.GetThemeName() ) );
444 case GalleryHintType::THEME_RENAMED
:
446 const sal_Int32 nCurSelectPos
= mxThemes
->get_selected_index();
447 const sal_Int32 nRenameEntryPos
= mxThemes
->find_text( rGalleryHint
.GetThemeName() );
449 mxThemes
->remove_text( rGalleryHint
.GetThemeName() );
450 ImplInsertThemeEntry( mpGallery
->GetThemeInfo( rGalleryHint
.GetStringData() ) );
452 if( nCurSelectPos
== nRenameEntryPos
)
454 mxThemes
->select_text( rGalleryHint
.GetStringData() );
455 SelectThemeHdl( *mxThemes
);
460 case GalleryHintType::THEME_REMOVED
:
462 mxThemes
->remove_text( rGalleryHint
.GetThemeName() );
466 case GalleryHintType::CLOSE_THEME
:
468 const sal_Int32 nCurSelectPos
= mxThemes
->get_selected_index();
469 const sal_Int32 nCloseEntryPos
= mxThemes
->find_text( rGalleryHint
.GetThemeName() );
471 if( nCurSelectPos
== nCloseEntryPos
)
473 if( nCurSelectPos
< ( mxThemes
->n_children() - 1 ) )
474 mxThemes
->select( nCurSelectPos
+ 1 );
475 else if( nCurSelectPos
)
476 mxThemes
->select( nCurSelectPos
- 1 );
478 mxThemes
->select(-1);
480 SelectThemeHdl( *mxThemes
);
485 case GalleryHintType::THEME_UPDATEVIEW
:
487 if( GALLERYBROWSERMODE_PREVIEW
== GetMode() )
488 SetMode( meLastMode
);
490 ImplUpdateViews( reinterpret_cast<size_t>(rGalleryHint
.GetData1()) + 1 );
500 IMPL_STATIC_LINK_NOARG( GalleryBrowser1
, OnMoreGalleriesClick
, weld::Button
&, void)
502 css::uno::Sequence
<css::beans::PropertyValue
> aArgs
{
503 comphelper::makePropertyValue(u
"AdditionsTag"_ustr
, u
"Gallery"_ustr
)
505 comphelper::dispatchCommand(u
".uno:AdditionsDialog"_ustr
, aArgs
);
508 IMPL_LINK(GalleryBrowser1
, KeyInputHdl1
, const KeyEvent
&, rKEvt
, bool)
512 std::vector
<OUString
> aExecVector
;
513 ImplGetExecuteVector(aExecVector
);
514 OUString sExecuteIdent
;
515 bool bMod1
= rKEvt
.GetKeyCode().IsMod1();
517 switch( rKEvt
.GetKeyCode().GetCode() )
520 ClickNewThemeHdl(*mxNewTheme
);
526 ClickNewThemeHdl(*mxNewTheme
);
533 sExecuteIdent
= "update";
538 sExecuteIdent
= "delete";
544 sExecuteIdent
= "delete";
551 sExecuteIdent
= "rename";
558 sExecuteIdent
= "properties";
563 if (!sExecuteIdent
.isEmpty() && (std::find( aExecVector
.begin(), aExecVector
.end(), sExecuteIdent
) != aExecVector
.end()))
565 ImplExecute(sExecuteIdent
);
572 IMPL_LINK(GalleryBrowser1
, PopupMenuHdl1
, const CommandEvent
&, rCEvt
, bool)
574 if (rCEvt
.GetCommand() != CommandEventId::ContextMenu
)
577 std::vector
<OUString
> aExecVector
;
578 ImplGetExecuteVector(aExecVector
);
580 if (aExecVector
.empty())
583 std::unique_ptr
<weld::Builder
> xBuilder(Application::CreateBuilder(mxThemes
.get(), u
"svx/ui/gallerymenu1.ui"_ustr
));
584 std::unique_ptr
<weld::Menu
> xMenu(xBuilder
->weld_menu(u
"menu"_ustr
));
586 xMenu
->set_visible(u
"update"_ustr
, std::find( aExecVector
.begin(), aExecVector
.end(), "update" ) != aExecVector
.end());
587 xMenu
->set_visible(u
"rename"_ustr
, std::find( aExecVector
.begin(), aExecVector
.end(), "rename" ) != aExecVector
.end());
588 xMenu
->set_visible(u
"delete"_ustr
, std::find( aExecVector
.begin(), aExecVector
.end(), "delete" ) != aExecVector
.end());
589 xMenu
->set_visible(u
"assign"_ustr
, std::find( aExecVector
.begin(), aExecVector
.end(), "assign" ) != aExecVector
.end());
590 xMenu
->set_visible(u
"properties"_ustr
, std::find( aExecVector
.begin(), aExecVector
.end(), "properties" ) != aExecVector
.end());
592 OUString
sCommand(xMenu
->popup_at_rect(mxThemes
.get(), tools::Rectangle(rCEvt
.GetMousePosPixel(), Size(1,1))));
593 ImplExecute(sCommand
);
598 IMPL_LINK_NOARG(GalleryBrowser1
, SelectThemeHdl
, weld::TreeView
&, void)
600 SelectTheme(GetSelectedTheme());
603 IMPL_LINK_NOARG(GalleryBrowser1
, ClickNewThemeHdl
, weld::Button
&, void)
605 OUString
aNewTheme( SvxResId(RID_SVXSTR_GALLERY_NEWTHEME
) );
606 OUString
aName( aNewTheme
);
607 sal_uInt16 nCount
= 0;
609 while( mpGallery
->HasTheme( aName
) && ( nCount
++ < 16000 ) )
611 aName
= aNewTheme
+ " " + OUString::number( nCount
);
614 if( !mpGallery
->HasTheme( aName
) && mpGallery
->CreateTheme( aName
) )
616 ImplGalleryThemeProperties( aName
, true );
620 GalleryBrowserMode
GalleryBrowser1::meInitMode
= GALLERYBROWSERMODE_ICON
;
622 IMPL_STATIC_LINK( GalleryBrowser1
, AsyncDispatch_Impl
, void*, p
, void )
624 DispatchInfo
* pDispatchInfo
= static_cast<DispatchInfo
*>(p
);
625 if ( pDispatchInfo
&& pDispatchInfo
->Dispatch
.is() )
629 pDispatchInfo
->Dispatch
->dispatch( pDispatchInfo
->TargetURL
,
630 pDispatchInfo
->Arguments
);
632 catch ( const css::uno::Exception
& )
637 delete pDispatchInfo
;
640 IMPL_LINK(GalleryBrowser1
, PopupMenuHdl2
, const CommandEvent
&, rCEvt
, bool)
642 if (rCEvt
.GetCommand() != CommandEventId::ContextMenu
)
644 ShowContextMenu(rCEvt
);
648 IMPL_LINK(GalleryBrowser1
, KeyInputHdl2
, const KeyEvent
&, rKEvt
, bool)
650 return KeyInput(rKEvt
);
653 IMPL_LINK_NOARG(GalleryBrowser1
, RowActivatedHdl
, weld::TreeView
&, bool)
659 sal_Int8
GalleryBrowser1::AcceptDrop( const DropTargetHelper
& rTarget
)
661 sal_Int8 nRet
= DND_ACTION_NONE
;
663 if( mpCurTheme
&& !mpCurTheme
->IsReadOnly() )
665 if( !mpCurTheme
->IsDragging() )
667 if( rTarget
.IsDropFormatSupported( SotClipboardFormatId::DRAWING
) ||
668 rTarget
.IsDropFormatSupported( SotClipboardFormatId::FILE_LIST
) ||
669 rTarget
.IsDropFormatSupported( SotClipboardFormatId::SIMPLE_FILE
) ||
670 rTarget
.IsDropFormatSupported( SotClipboardFormatId::SVXB
) ||
671 rTarget
.IsDropFormatSupported( SotClipboardFormatId::GDIMETAFILE
) ||
672 rTarget
.IsDropFormatSupported( SotClipboardFormatId::BITMAP
) )
674 nRet
= DND_ACTION_COPY
;
678 nRet
= DND_ACTION_COPY
;
684 sal_Int8
GalleryBrowser1::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
686 sal_Int8 nRet
= DND_ACTION_NONE
;
691 const sal_uInt32 nItemId
= ImplGetSelectedItemId( &rEvt
.maPosPixel
, aSelPos
);
692 const sal_uInt32 nInsertPos
= (nItemId
? (nItemId
- 1) : mpCurTheme
->GetObjectCount());
694 if( mpCurTheme
->IsDragging() )
695 mpCurTheme
->ChangeObjectPos( mpCurTheme
->GetDragPos(), nInsertPos
);
697 nRet
= mpCurTheme
->InsertTransferable( rEvt
.maDropEvent
.Transferable
, nInsertPos
) ? 1 : 0;
703 bool GalleryBrowser1::StartDrag()
707 return m_xHelper
->StartDrag();
710 IMPL_LINK(GalleryBrowser1
, DragBeginHdl
, bool&, rUnsetDragIcon
, bool)
712 rUnsetDragIcon
= false;
716 void GalleryBrowser1::TogglePreview()
718 SetMode( ( GALLERYBROWSERMODE_PREVIEW
!= GetMode() ) ? GALLERYBROWSERMODE_PREVIEW
: meLastMode
);
719 GetViewWindow()->grab_focus();
722 bool GalleryBrowser1::ShowContextMenu(const CommandEvent
& rCEvt
)
724 Point aMousePos
= rCEvt
.GetMousePosPixel();
726 const sal_uInt32 nItemId
= ImplGetSelectedItemId( rCEvt
.IsMouseEvent() ? &aMousePos
: nullptr, aSelPos
);
728 if( !(mpCurTheme
&& nItemId
&& ( nItemId
<= mpCurTheme
->GetObjectCount() )) )
731 ImplSelectItemId( nItemId
);
733 css::uno::Reference
< css::frame::XFrame
> xFrame( GetFrame() );
737 weld::Widget
* pParent
= GetViewWindow();
738 mnCurActionPos
= nItemId
- 1;
739 rtl::Reference
< GalleryThemePopup
> xPopup(
740 new GalleryThemePopup(
744 GALLERYBROWSERMODE_PREVIEW
== GetMode(),
746 xPopup
->ExecutePopup(pParent
, aSelPos
);
750 bool GalleryBrowser1::ViewBoxHasFocus() const
752 return mxIconButton
->has_focus() || mxListButton
->has_focus();
755 bool GalleryBrowser1::KeyInput(const KeyEvent
& rKEvt
)
758 const sal_uInt32 nItemId
= ImplGetSelectedItemId( nullptr, aSelPos
);
761 if (!ViewBoxHasFocus() && nItemId
&& mpCurTheme
)
763 OUString sExecuteIdent
;
766 mpCurTheme
->GetURL( nItemId
- 1, aURL
);
768 const bool bValidURL
= ( aURL
.GetProtocol() != INetProtocol::NotValid
);
769 bool bPreview
= bValidURL
;
770 bool bDelete
= false;
773 if( !mpCurTheme
->IsReadOnly() && mpCurTheme
->GetObjectCount() )
775 bDelete
= ( GALLERYBROWSERMODE_PREVIEW
!= GetMode() );
779 switch( rKEvt
.GetKeyCode().GetCode() )
796 // Inserting a gallery item in the document must be dispatched
799 DispatchAdd(css::uno::Reference
<css::frame::XDispatch
>(), css::util::URL());
809 sExecuteIdent
= "delete";
816 sExecuteIdent
= "title";
824 if (!sExecuteIdent
.isEmpty())
826 Execute(sExecuteIdent
);
834 void GalleryBrowser1::SelectTheme( std::u16string_view rThemeName
)
837 mpGallery
->ReleaseTheme( mpCurTheme
, *this );
839 if (rThemeName
.empty())
841 mxIconButton
->set_sensitive(false);
842 mxListButton
->set_sensitive(false);
845 mpCurTheme
= nullptr;
849 mpCurTheme
= mpGallery
->AcquireTheme( rThemeName
, *this );
851 m_xHelper
.set(new GalleryTransferable(mpCurTheme
, 0, true));
852 rtl::Reference
<TransferDataContainer
> xHelper(m_xHelper
);
853 mxListView
->enable_drag_source(xHelper
, DND_ACTION_COPY
| DND_ACTION_LINK
);
854 mxIconView
->SetDragDataTransferable(xHelper
, DND_ACTION_COPY
| DND_ACTION_LINK
);
855 mxPreview
->SetDragDataTransferable(xHelper
, DND_ACTION_COPY
| DND_ACTION_LINK
);
857 mxIconView
->SetTheme(mpCurTheme
);
858 mxPreview
->SetTheme(mpCurTheme
);
860 if( GALLERYBROWSERMODE_PREVIEW
== GetMode() )
863 ImplUpdateViews( 1 );
865 bool bIconMode
= (GALLERYBROWSERMODE_ICON
== GetMode());
866 mxIconButton
->set_sensitive(true);
867 mxListButton
->set_sensitive(true);
868 mxIconButton
->set_active(bIconMode
);
869 mxListButton
->set_active(!bIconMode
);
873 void GalleryBrowser1::SetMode( GalleryBrowserMode eMode
)
875 if( GetMode() == eMode
)
878 meLastMode
= GetMode();
882 case GALLERYBROWSERMODE_ICON
:
887 mxPreview
->SetGraphic( Graphic() );
888 GalleryPreview::PreviewMedia( INetURLObject() );
892 mxIconButton
->set_sensitive(true);
893 mxListButton
->set_sensitive(true);
895 mxIconButton
->set_active(true);
896 mxListButton
->set_active(false);
900 case GALLERYBROWSERMODE_LIST
:
905 mxPreview
->SetGraphic( Graphic() );
906 GalleryPreview::PreviewMedia( INetURLObject() );
911 mxIconButton
->set_sensitive(true);
912 mxListButton
->set_sensitive(true);
914 mxIconButton
->set_active(false);
915 mxListButton
->set_active(true);
919 case GALLERYBROWSERMODE_PREVIEW
:
923 const sal_uInt32 nItemId
= ImplGetSelectedItemId( nullptr, aSelPos
);
927 const sal_uInt32 nPos
= nItemId
- 1;
933 mpCurTheme
->GetGraphic( nPos
, aGraphic
);
935 mxPreview
->SetGraphic( aGraphic
);
938 if( mpCurTheme
&& mpCurTheme
->GetObjectKind( nPos
) == SgaObjKind::Sound
)
939 GalleryPreview::PreviewMedia( mpCurTheme
->GetObjectURL( nPos
) );
941 mxIconButton
->set_sensitive(false);
942 mxListButton
->set_sensitive(false);
951 GalleryBrowser1::meInitMode
= meMode
= eMode
;
954 weld::Widget
* GalleryBrowser1::GetViewWindow() const
960 case GALLERYBROWSERMODE_LIST
: pRet
= mxListView
.get(); break;
961 case GALLERYBROWSERMODE_PREVIEW
: pRet
= mxPreview
->GetDrawingArea(); break;
964 pRet
= mxIconView
->GetDrawingArea();
971 void GalleryBrowser1::Travel( GalleryBrowserTravel eTravel
)
977 const sal_uInt32 nItemId
= ImplGetSelectedItemId( nullptr, aSelPos
);
982 sal_uInt32 nNewItemId
= nItemId
;
986 case GalleryBrowserTravel::First
: nNewItemId
= 1; break;
987 case GalleryBrowserTravel::Last
: nNewItemId
= mpCurTheme
->GetObjectCount(); break;
988 case GalleryBrowserTravel::Previous
: nNewItemId
--; break;
989 case GalleryBrowserTravel::Next
: nNewItemId
++; break;
996 else if( nNewItemId
> mpCurTheme
->GetObjectCount() )
997 nNewItemId
= mpCurTheme
->GetObjectCount();
999 if( nNewItemId
== nItemId
)
1002 ImplSelectItemId( nNewItemId
);
1003 ImplUpdateInfoBar();
1005 if( GALLERYBROWSERMODE_PREVIEW
!= GetMode() )
1009 const sal_uInt32 nPos
= nNewItemId
- 1;
1011 mpCurTheme
->GetGraphic( nPos
, aGraphic
);
1012 mxPreview
->SetGraphic( aGraphic
);
1014 if( SgaObjKind::Sound
== mpCurTheme
->GetObjectKind( nPos
) )
1015 GalleryPreview::PreviewMedia( mpCurTheme
->GetObjectURL( nPos
) );
1017 mxPreview
->Invalidate();
1020 void GalleryBrowser1::ImplUpdateViews( sal_uInt16 nSelectionId
)
1026 mxIconView
->Clear();
1027 mxListView
->clear();
1031 const int nAlwaysUpToDate
= 15;
1033 mxListView
->freeze();
1034 OUString aThemeName
= mpCurTheme
->GetName();
1035 sal_Int32 inserted
= 0;
1036 for (GalleryThemeEntries::const_iterator aFoundIter
= maFoundThemeEntries
.begin(); aFoundIter
!= maFoundThemeEntries
.end(); ++aFoundIter
)
1038 if (aFoundIter
->maThemeName
== aThemeName
)
1040 mxIconView
->InsertItem(aFoundIter
->mnIdInTheme
+ 1); // skip reserved id 0
1041 mxListView
->append(OUString::number(aFoundIter
->mnIdInTheme
),u
""_ustr
); // create on-demand in VisRowsScrolledHdl
1043 if (inserted
== nAlwaysUpToDate
) // fill in the first block
1049 /* sal_uInt32 nCount = mpCurTheme->GetObjectCount();
1050 for (sal_uInt32 i = 0; i < nCount; ++i)
1052 mxIconView->InsertItem(i + 1); // skip reserved id 0
1053 mxListView->append(OUString::number(i), ""); // create on-demand in VisRowsScrolledHdl
1055 if (i == nAlwaysUpToDate) // fill in the first block
1059 if (inserted
< nAlwaysUpToDate
) // if less than block size, fill in all of them
1064 ImplSelectItemId( std::min
<sal_uInt16
>( nSelectionId
, mpCurTheme
->GetObjectCount() ) );
1069 case GALLERYBROWSERMODE_ICON
: mxIconView
->Show(); break;
1070 case GALLERYBROWSERMODE_LIST
:
1074 case GALLERYBROWSERMODE_PREVIEW
: mxPreview
->Show(); break;
1080 ImplUpdateInfoBar();
1083 void GalleryBrowser1::UpdateRows(bool bVisibleOnly
)
1085 auto lambda
= [this](weld::TreeIter
& rEntry
){
1086 // id is non-null if the preview is pending creation
1087 OUString
sId(mxListView
->get_id(rEntry
));
1091 // get the icon for the listview
1095 OUString sItemTextTitle
;
1096 OUString sItemTextPath
;
1098 sal_Int32 i
= sId
.toUInt32();
1099 mpCurTheme
->GetPreviewBitmapExAndStrings(i
, aBitmapEx
, aPreparedSize
, sItemTextTitle
, sItemTextPath
);
1101 bool bNeedToCreate(aBitmapEx
.IsEmpty());
1102 if (!bNeedToCreate
&& (sItemTextTitle
.isEmpty() || aPreparedSize
!= maPreviewSize
))
1103 bNeedToCreate
= true;
1107 std::unique_ptr
<SgaObject
> xObj
= mpCurTheme
->AcquireObject(i
);
1110 aBitmapEx
= xObj
->createPreviewBitmapEx(maPreviewSize
);
1111 sItemTextTitle
= GalleryBrowser1::GetItemText(*xObj
, GalleryItemFlags::Title
);
1112 sItemTextPath
= GalleryBrowser1::GetItemText(*xObj
, GalleryItemFlags::Path
);
1114 mpCurTheme
->SetPreviewBitmapExAndStrings(i
, aBitmapEx
, maPreviewSize
, sItemTextTitle
, sItemTextPath
);
1118 ScopedVclPtr
<VirtualDevice
> xDev(mxListView
->create_virtual_device());
1119 xDev
->SetOutputSizePixel(maPreviewSize
);
1121 if (!aBitmapEx
.IsEmpty())
1123 const Size
aBitmapExSizePixel(aBitmapEx
.GetSizePixel());
1125 ((maPreviewSize
.Width() - aBitmapExSizePixel
.Width()) >> 1),
1126 ((maPreviewSize
.Height() - aBitmapExSizePixel
.Height()) >> 1));
1128 if (aBitmapEx
.IsAlpha())
1130 // draw checkered background
1131 GalleryIconView::drawTransparenceBackground(*xDev
, aPos
, aBitmapExSizePixel
);
1134 xDev
->DrawBitmapEx(aPos
, aBitmapEx
);
1137 mxListView
->set_text(rEntry
, sItemTextTitle
);
1138 mxListView
->set_image(rEntry
, *xDev
);
1139 mxListView
->set_id(rEntry
, OUString());
1146 // ensure all visible entries are up to date
1147 mxListView
->visible_foreach(lambda
);
1148 // and ensure all selected entries are up to date
1149 mxListView
->selected_foreach(lambda
);
1153 mxListView
->all_foreach(lambda
);
1156 IMPL_LINK_NOARG(GalleryBrowser1
, VisRowsScrolledHdl
, weld::TreeView
&, void)
1161 IMPL_LINK_NOARG(GalleryBrowser1
, SizeAllocHdl
, const Size
&, void)
1166 void GalleryBrowser1::ImplUpdateInfoBar()
1170 mxInfoBar
->set_label( mpCurTheme
->GetName() );
1173 void GalleryBrowser1::ImplUpdateSelection()
1177 auto nSelectedObject
= (GALLERYBROWSERMODE_ICON
== GetMode()) ? (mxIconView
->GetSelectedItemId() - 1) : mxListView
->get_selected_index();
1178 m_xHelper
->SelectObject(nSelectedObject
);
1181 sal_uInt32
GalleryBrowser1::ImplGetSelectedItemId( const Point
* pSelPos
, Point
& rSelPos
)
1183 sal_uInt32 nRet
= 0;
1185 if( GALLERYBROWSERMODE_PREVIEW
== GetMode() )
1187 nRet
= ( ( GALLERYBROWSERMODE_ICON
== meLastMode
) ? mxIconView
->GetSelectedItemId() : ( mxListView
->get_selected_index() + 1 ) );
1193 Size
aOutputSizePixel(mxPreview
->GetOutputSizePixel());
1194 rSelPos
= Point( aOutputSizePixel
.Width() >> 1, aOutputSizePixel
.Height() >> 1 );
1197 else if (GALLERYBROWSERMODE_ICON
== GetMode())
1201 nRet
= mxIconView
->GetItemId( *pSelPos
);
1206 nRet
= mxIconView
->GetSelectedItemId();
1207 rSelPos
= mxIconView
->GetItemRect(nRet
).Center();
1212 std::unique_ptr
<weld::TreeIter
> xIter
= mxListView
->make_iterator();
1215 if (mxListView
->get_dest_row_at_pos(*pSelPos
, xIter
.get(), false))
1216 nRet
= mxListView
->get_iter_index_in_parent(*xIter
) + 1;
1221 if (mxListView
->get_selected(xIter
.get()))
1223 nRet
= mxListView
->get_iter_index_in_parent(*xIter
) + 1;
1224 rSelPos
= mxListView
->get_row_area(*xIter
).Center();
1229 if( nRet
&& ( !mpCurTheme
|| ( nRet
> mpCurTheme
->GetObjectCount() ) ) )
1237 void GalleryBrowser1::ImplSelectItemId(sal_uInt32 nItemId
)
1241 mxIconView
->SelectItem(nItemId
);
1242 mxListView
->select( nItemId
- 1 );
1243 ImplUpdateSelection();
1247 css::uno::Reference
< css::frame::XFrame
>
1248 GalleryBrowser1::GetFrame()
1250 css::uno::Reference
< css::frame::XFrame
> xFrame
;
1251 SfxViewFrame
* pCurrentViewFrame
= SfxViewFrame::Current();
1252 if ( pCurrentViewFrame
)
1254 SfxBindings
& rBindings
= pCurrentViewFrame
->GetBindings();
1255 xFrame
.set( rBindings
.GetActiveFrame() );
1261 void GalleryBrowser1::DispatchAdd(
1262 const css::uno::Reference
< css::frame::XDispatch
> &rxDispatch
,
1263 const css::util::URL
&rURL
)
1266 const sal_uInt32 nItemId
= ImplGetSelectedItemId( nullptr, aSelPos
);
1268 if( !mpCurTheme
|| !nItemId
)
1271 mnCurActionPos
= nItemId
- 1;
1273 css::uno::Reference
< css::frame::XDispatch
> xDispatch( rxDispatch
);
1274 css::util::URL aURL
= rURL
;
1276 if ( !xDispatch
.is() )
1278 css::uno::Reference
< css::frame::XDispatchProvider
> xDispatchProvider(
1279 GetFrame(), css::uno::UNO_QUERY
);
1280 if ( !xDispatchProvider
.is() || !m_xTransformer
.is() )
1283 aURL
.Complete
= ".uno:InsertGalleryPic";
1284 m_xTransformer
->parseStrict( aURL
);
1285 xDispatch
= xDispatchProvider
->queryDispatch(
1288 css::frame::FrameSearchFlag::SELF
);
1291 if ( !xDispatch
.is() )
1295 OUString aFilterName
;
1296 css::uno::Reference
< css::lang::XComponent
> xDrawing
;
1297 css::uno::Reference
< css::graphic::XGraphic
> xGraphic
;
1299 aFilterName
= GetFilterName();
1301 switch( mpCurTheme
->GetObjectKind( mnCurActionPos
) )
1303 case SgaObjKind::Bitmap
:
1304 case SgaObjKind::Animation
:
1305 case SgaObjKind::Inet
:
1306 // TODO drawing objects are inserted as drawings only via drag&drop
1307 case SgaObjKind::SvDraw
:
1308 nType
= css::gallery::GalleryItemType::GRAPHIC
;
1311 case SgaObjKind::Sound
:
1312 nType
= css::gallery::GalleryItemType::MEDIA
;
1316 nType
= css::gallery::GalleryItemType::EMPTY
;
1321 bool bGraphic
= mpCurTheme
->GetGraphic( mnCurActionPos
, aGraphic
);
1322 if ( bGraphic
&& !aGraphic
.IsNone() )
1323 xGraphic
.set( aGraphic
.GetXGraphic() );
1324 OSL_ENSURE( xGraphic
.is(), "gallery item is graphic, but the reference is invalid!" );
1326 css::uno::Sequence
< css::beans::PropertyValue
> aSeq
{
1327 comphelper::makePropertyValue(SVXGALLERYITEM_TYPE
, nType
),
1328 comphelper::makePropertyValue(SVXGALLERYITEM_URL
, OUString()),
1329 comphelper::makePropertyValue(SVXGALLERYITEM_FILTER
, aFilterName
),
1330 comphelper::makePropertyValue(SVXGALLERYITEM_DRAWING
, xDrawing
),
1331 comphelper::makePropertyValue(SVXGALLERYITEM_GRAPHIC
, xGraphic
)
1333 assert(aSeq
.getLength() == SVXGALLERYITEM_PARAMS
);
1335 css::uno::Sequence
< css::beans::PropertyValue
> aArgs
{ comphelper::makePropertyValue(
1336 SVXGALLERYITEM_ARGNAME
, aSeq
) };
1338 std::unique_ptr
<DispatchInfo
> pInfo(new DispatchInfo
);
1339 pInfo
->TargetURL
= std::move(aURL
);
1340 pInfo
->Arguments
= std::move(aArgs
);
1341 pInfo
->Dispatch
= std::move(xDispatch
);
1343 if ( Application::PostUserEvent(
1344 LINK( nullptr, GalleryBrowser1
, AsyncDispatch_Impl
), pInfo
.get() ) )
1348 void GalleryBrowser1::Execute(std::u16string_view rIdent
)
1351 const sal_uInt32 nItemId
= ImplGetSelectedItemId( nullptr, aSelPos
);
1353 if( !(mpCurTheme
&& nItemId
) )
1356 mnCurActionPos
= nItemId
- 1;
1358 if (rIdent
== u
"preview")
1359 SetMode( ( GALLERYBROWSERMODE_PREVIEW
!= GetMode() ) ? GALLERYBROWSERMODE_PREVIEW
: meLastMode
);
1360 else if (rIdent
== u
"delete")
1362 if (!mpCurTheme
->IsReadOnly())
1364 std::unique_ptr
<weld::Builder
> xBuilder(Application::CreateBuilder(GetViewWindow(), u
"svx/ui/querydeleteobjectdialog.ui"_ustr
));
1365 std::unique_ptr
<weld::MessageDialog
> xQuery(xBuilder
->weld_message_dialog(u
"QueryDeleteObjectDialog"_ustr
));
1366 if (xQuery
->run() == RET_YES
)
1368 mpCurTheme
->RemoveObject( mnCurActionPos
);
1372 else if (rIdent
== u
"title")
1374 std::unique_ptr
<SgaObject
> pObj
= mpCurTheme
->AcquireObject( mnCurActionPos
);
1378 const OUString
aOldTitle( GetItemText( *pObj
, GalleryItemFlags::Title
) );
1380 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
1381 ScopedVclPtr
<AbstractTitleDialog
> aDlg(pFact
->CreateTitleDialog(GetViewWindow(), aOldTitle
));
1382 if( aDlg
->Execute() == RET_OK
)
1384 OUString
aNewTitle( aDlg
->GetTitle() );
1386 if( ( aNewTitle
.isEmpty() && !pObj
->GetTitle().isEmpty() ) || ( aNewTitle
!= aOldTitle
) )
1388 if( aNewTitle
.isEmpty() )
1389 aNewTitle
= "__<empty>__";
1391 pObj
->SetTitle( aNewTitle
);
1392 mpCurTheme
->InsertObject( *pObj
);
1397 else if (rIdent
== u
"copy")
1399 mpCurTheme
->CopyToClipboard(*GetViewWindow(), mnCurActionPos
);
1401 else if (rIdent
== u
"paste")
1403 if( !mpCurTheme
->IsReadOnly() )
1405 weld::Widget
* pParent
= GetViewWindow();
1406 TransferableDataHelper
aDataHelper(TransferableDataHelper::CreateFromClipboard(pParent
->get_clipboard()));
1407 mpCurTheme
->InsertTransferable( aDataHelper
.GetTransferable(), mnCurActionPos
);
1412 OUString
GalleryBrowser1::GetItemText( const SgaObject
& rObj
, GalleryItemFlags nItemTextFlags
)
1416 const INetURLObject
& aURL(rObj
.GetURL());
1418 if( nItemTextFlags
& GalleryItemFlags::Title
)
1420 OUString
aTitle( rObj
.GetTitle() );
1422 if( aTitle
.isEmpty() )
1423 aTitle
= aURL
.getBase( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DecodeMechanism::Unambiguous
);
1425 if( aTitle
.isEmpty() )
1427 aTitle
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous
);
1428 aTitle
= aTitle
.copy( aTitle
.lastIndexOf('/')+1 );
1434 if( nItemTextFlags
& GalleryItemFlags::Path
)
1436 const OUString
aPath( aURL
.getFSysPath( FSysStyle::Detect
) );
1438 if( !aPath
.isEmpty() && ( nItemTextFlags
& GalleryItemFlags::Title
) )
1441 aRet
+= aURL
.getFSysPath( FSysStyle::Detect
);
1443 if( !aPath
.isEmpty() && ( nItemTextFlags
& GalleryItemFlags::Title
) )
1450 INetURLObject
GalleryBrowser1::GetURL() const
1454 if( mpCurTheme
&& mnCurActionPos
!= 0xffffffff )
1455 aURL
= mpCurTheme
->GetObjectURL( mnCurActionPos
);
1460 OUString
GalleryBrowser1::GetFilterName() const
1462 OUString aFilterName
;
1464 if( mpCurTheme
&& mnCurActionPos
!= 0xffffffff )
1466 const SgaObjKind eObjKind
= mpCurTheme
->GetObjectKind( mnCurActionPos
);
1468 if( ( SgaObjKind::Bitmap
== eObjKind
) || ( SgaObjKind::Animation
== eObjKind
) )
1470 GraphicFilter
& rFilter
= GraphicFilter::GetGraphicFilter();
1472 mpCurTheme
->GetURL( mnCurActionPos
, aURL
);
1473 sal_uInt16 nFilter
= rFilter
.GetImportFormatNumberForShortName(aURL
.GetFileExtension());
1475 if( GRFILTER_FORMAT_DONTKNOW
!= nFilter
)
1476 aFilterName
= rFilter
.GetImportFormatName( nFilter
);
1483 IMPL_LINK_NOARG(GalleryBrowser1
, SelectObjectValueSetHdl
, ValueSet
*, void)
1485 ImplUpdateSelection();
1488 IMPL_LINK_NOARG(GalleryBrowser1
, SelectObjectHdl
, weld::TreeView
&, void)
1490 ImplUpdateSelection();
1493 IMPL_LINK(GalleryBrowser1
, SelectTbxHdl
, weld::Toggleable
&, rBox
, void)
1495 if (&rBox
== mxIconButton
.get())
1496 SetMode(rBox
.get_active() ? GALLERYBROWSERMODE_ICON
: GALLERYBROWSERMODE_LIST
);
1497 else if (&rBox
== mxListButton
.get())
1498 SetMode(rBox
.get_active() ? GALLERYBROWSERMODE_LIST
: GALLERYBROWSERMODE_ICON
);
1501 void GalleryBrowser1::FillThemeEntries()
1503 for (size_t i
= 0, nCount
= mpGallery
->GetThemeCount(); i
< nCount
; ++i
)
1505 const GalleryThemeEntry
* pThemeInfo
= mpGallery
->GetThemeInfo( i
);
1506 OUString aThemeName
= pThemeInfo
->GetThemeName();
1507 //sal_uInt32 nId = pThemeInfo->GetId();
1508 if (GalleryTheme
* pTheme
= mpGallery
->AcquireTheme(aThemeName
, maLocalListener
))
1510 sal_uInt32 nObjectCount
= pTheme
->GetObjectCount();
1511 for (size_t nObject
= 0; nObject
< nObjectCount
; ++nObject
)
1513 if (std::unique_ptr
<SgaObject
> xSgaObject
= pTheme
->AcquireObject(nObject
))
1515 OUString aTitle
= GetItemText(*xSgaObject
, GalleryItemFlags::Title
);
1516 maAllThemeEntries
.push_back(ThemeEntry(aThemeName
, aTitle
, nObject
));
1519 mpGallery
->ReleaseTheme(pTheme
, maLocalListener
);
1522 maFoundThemeEntries
.assign(maAllThemeEntries
.begin(), maAllThemeEntries
.end());
1524 IMPL_LINK(GalleryBrowser1
, SearchHdl
, weld::Entry
&, searchEdit
, void)
1526 OUString search
= searchEdit
.get_text().trim();
1527 OUString curThemeName
;
1528 ::std::set
<OUString
> aFoundThemes
;
1531 curThemeName
= mpCurTheme
->GetName();
1533 if (search
.isEmpty())
1535 maFoundThemeEntries
.assign(maAllThemeEntries
.begin(), maAllThemeEntries
.end());
1536 if (maAllThemeEntries
.begin() != maAllThemeEntries
.end())
1537 curThemeName
= maAllThemeEntries
.begin()->maThemeName
;
1541 search
= "*" + search
+ "*";
1542 WildCard
aSearchExpression(m_aCharacterClassficator
.lowercase(search
));
1543 bool currentThemeFound
= false;
1544 maFoundThemeEntries
.clear();
1545 for (GalleryThemeEntries::const_iterator allIter
= maAllThemeEntries
.begin(); allIter
!= maAllThemeEntries
.end(); ++allIter
)
1547 if (aSearchExpression
.Matches(m_aCharacterClassficator
.lowercase(allIter
->maEntryTitle
)))
1549 maFoundThemeEntries
.push_back(*allIter
);
1550 aFoundThemes
.insert(allIter
->maThemeName
);
1551 if (curThemeName
== allIter
->maThemeName
)
1552 currentThemeFound
= true;
1555 if (!currentThemeFound
)
1557 if (maFoundThemeEntries
.begin() != maFoundThemeEntries
.end())
1558 curThemeName
= maFoundThemeEntries
.begin()->maThemeName
;
1560 curThemeName
.clear();
1564 if (search
.isEmpty())
1566 for (size_t i
= 0, nCount
= mpGallery
->GetThemeCount(); i
< nCount
; ++i
)
1567 ImplInsertThemeEntry( mpGallery
->GetThemeInfo( i
) );
1571 for(std::set
<OUString
>::iterator foundIter
= aFoundThemes
.begin(); foundIter
!= aFoundThemes
.end(); ++foundIter
)
1572 ImplInsertThemeEntry(mpGallery
->GetThemeInfo(*foundIter
));
1574 mxThemes
->select_text(curThemeName
);
1575 SelectTheme(curThemeName
);
1581 GalleryThemePopup::GalleryThemePopup(
1582 weld::Widget
* pParent
,
1583 const GalleryTheme
* pTheme
,
1584 sal_uInt32 nObjectPos
,
1586 GalleryBrowser1
* pBrowser
)
1588 , mnObjectPos( nObjectPos
)
1589 , mbPreview( bPreview
)
1590 , mxBuilder(Application::CreateBuilder(pParent
, u
"svx/ui/gallerymenu2.ui"_ustr
))
1591 , mxPopupMenu(mxBuilder
->weld_menu(u
"menu"_ustr
))
1592 , mxBackgroundPopup(mxBuilder
->weld_menu(u
"backgroundmenu"_ustr
))
1593 , mpBrowser( pBrowser
)
1595 // SID_GALLERY_ENABLE_ADDCOPY
1596 m_aCommandInfo
.emplace(
1597 SID_GALLERY_ENABLE_ADDCOPY
,
1598 CommandInfo( u
".uno:GalleryEnableAddCopy"_ustr
));
1599 // SID_GALLERY_BG_BRUSH
1600 m_aCommandInfo
.emplace(
1601 SID_GALLERY_BG_BRUSH
,
1602 CommandInfo( u
".uno:BackgroundImage"_ustr
));
1603 // SID_GALLERY_FORMATS
1604 m_aCommandInfo
.emplace(
1605 SID_GALLERY_FORMATS
,
1606 CommandInfo( u
".uno:InsertGalleryPic"_ustr
));
1610 void SAL_CALL
GalleryThemePopup::statusChanged(
1611 const css::frame::FeatureStateEvent
&rEvent
)
1613 const OUString
&rURL
= rEvent
.FeatureURL
.Complete
;
1614 if ( rURL
== ".uno:GalleryEnableAddCopy" )
1616 if ( !rEvent
.IsEnabled
)
1618 mxPopupMenu
->set_visible(u
"add"_ustr
, false);
1621 else if ( rURL
== ".uno:BackgroundImage" )
1623 mxBackgroundPopup
->clear();
1624 if ( rEvent
.IsEnabled
)
1627 css::uno::Sequence
< OUString
> sItems
;
1628 if ( ( rEvent
.State
>>= sItem
) && sItem
.getLength() )
1630 mxBackgroundPopup
->append(OUString::number(1), sItem
);
1632 else if ( ( rEvent
.State
>>= sItems
) && sItems
.hasElements() )
1635 for (const OUString
& rStr
: sItems
)
1637 mxBackgroundPopup
->append(OUString::number(nId
), rStr
);
1645 void SAL_CALL
GalleryThemePopup::disposing(
1646 const css::lang::EventObject
&/*rSource*/)
1650 void GalleryThemePopup::Execute(
1651 const CommandInfo
&rCmdInfo
,
1652 const css::uno::Sequence
< css::beans::PropertyValue
> &rArguments
)
1654 if ( rCmdInfo
.Dispatch
.is() )
1656 std::unique_ptr
<DispatchInfo
> pInfo(new DispatchInfo
);
1657 pInfo
->TargetURL
= rCmdInfo
.URL
;
1658 pInfo
->Arguments
= rArguments
;
1659 pInfo
->Dispatch
= rCmdInfo
.Dispatch
;
1661 if ( Application::PostUserEvent(
1662 LINK( nullptr, GalleryBrowser1
, AsyncDispatch_Impl
), pInfo
.get() ) )
1667 void GalleryThemePopup::ExecutePopup(weld::Widget
* pParent
, const ::Point
&rPos
)
1669 css::uno::Reference
< css::frame::XStatusListener
> xThis( this );
1671 const SgaObjKind eObjKind
= mpTheme
->GetObjectKind( mnObjectPos
);
1674 mpTheme
->GetURL(mnObjectPos
, aURL
);
1675 const bool bValidURL
= ( aURL
.GetProtocol() != INetProtocol::NotValid
);
1677 mxPopupMenu
->set_visible(u
"add"_ustr
, bValidURL
&& SgaObjKind::Sound
!= eObjKind
);
1679 mxPopupMenu
->set_visible(u
"preview"_ustr
, bValidURL
);
1680 mxPopupMenu
->set_active(u
"preview"_ustr
, mbPreview
);
1682 if( mpTheme
->IsReadOnly() || !mpTheme
->GetObjectCount() )
1684 mxPopupMenu
->set_visible(u
"delete"_ustr
, false);
1685 mxPopupMenu
->set_visible(u
"title"_ustr
, false);
1686 if (mpTheme
->IsReadOnly())
1687 mxPopupMenu
->set_visible(u
"paste"_ustr
, false);
1689 if (!mpTheme
->GetObjectCount())
1690 mxPopupMenu
->set_visible(u
"copy"_ustr
, false);
1694 mxPopupMenu
->set_visible(u
"delete"_ustr
, !mbPreview
);
1695 mxPopupMenu
->set_visible(u
"title"_ustr
, true);
1696 mxPopupMenu
->set_visible(u
"copy"_ustr
, true);
1697 mxPopupMenu
->set_visible(u
"paste"_ustr
, true);
1701 css::uno::Reference
< css::frame::XDispatchProvider
> xDispatchProvider(
1702 GalleryBrowser1::GetFrame(), css::uno::UNO_QUERY
);
1703 css::uno::Reference
< css::util::XURLTransformer
> xTransformer(
1704 mpBrowser
->GetURLTransformer() );
1705 for ( auto& rInfo
: m_aCommandInfo
)
1709 CommandInfo
&rCmdInfo
= rInfo
.second
;
1710 if ( xTransformer
.is() )
1711 xTransformer
->parseStrict( rCmdInfo
.URL
);
1713 if ( xDispatchProvider
.is() )
1715 rCmdInfo
.Dispatch
= xDispatchProvider
->queryDispatch(
1718 css::frame::FrameSearchFlag::SELF
);
1721 if ( rCmdInfo
.Dispatch
.is() )
1723 rCmdInfo
.Dispatch
->addStatusListener( this, rCmdInfo
.URL
);
1724 rCmdInfo
.Dispatch
->removeStatusListener( this, rCmdInfo
.URL
);
1731 if( !mxBackgroundPopup
->n_children() || ( eObjKind
== SgaObjKind::SvDraw
) || ( eObjKind
== SgaObjKind::Sound
) )
1732 mxPopupMenu
->set_visible(u
"background"_ustr
, false);
1734 mxPopupMenu
->set_visible(u
"background"_ustr
, true);
1736 MenuSelectHdl(mxPopupMenu
->popup_at_rect(pParent
, tools::Rectangle(rPos
, Size(1,1))));
1739 void GalleryThemePopup::MenuSelectHdl(std::u16string_view rIdent
)
1744 sal_uInt16 nSubMenuId
= o3tl::toUInt32(rIdent
);
1747 BackgroundMenuSelectHdl(nSubMenuId
-1);
1751 if (rIdent
== u
"add")
1753 const CommandInfoMap::const_iterator it
= m_aCommandInfo
.find( SID_GALLERY_FORMATS
);
1754 if (it
!= m_aCommandInfo
.end())
1755 mpBrowser
->DispatchAdd(it
->second
.Dispatch
, it
->second
.URL
);
1758 mpBrowser
->Execute(rIdent
);
1761 void GalleryThemePopup::BackgroundMenuSelectHdl(sal_uInt16 nPos
)
1763 OUString
aURL( mpBrowser
->GetURL().GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
1764 OUString
aFilterName( mpBrowser
->GetFilterName() );
1766 css::uno::Sequence
< css::beans::PropertyValue
> aArgs
{
1767 comphelper::makePropertyValue(u
"Background.Transparent"_ustr
, sal_Int32( 0 )), // 0 - 100
1768 comphelper::makePropertyValue(u
"Background.BackColor"_ustr
, sal_Int32( - 1 )),
1769 comphelper::makePropertyValue(u
"Background.URL"_ustr
, aURL
),
1770 comphelper::makePropertyValue(u
"Background.Filtername"_ustr
, aFilterName
), // FIXME name should be FilterName
1771 comphelper::makePropertyValue(u
"Background.Position"_ustr
, css::style::GraphicLocation_TILED
),
1772 comphelper::makePropertyValue(u
"Position"_ustr
, nPos
)
1775 const CommandInfoMap::const_iterator it
= m_aCommandInfo
.find( SID_GALLERY_BG_BRUSH
);
1776 if ( it
!= m_aCommandInfo
.end() )
1777 Execute( it
->second
, aArgs
);
1780 } // end anonymous namespace
1783 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */