LibreOffice Module svx (master) 1
galbrws1.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include <tools/datetime.hxx>
23#include <utility>
24#include <vcl/commandevent.hxx>
25#include <vcl/event.hxx>
26#include <vcl/svapp.hxx>
27#include <vcl/weld.hxx>
28#include <com/sun/star/ucb/ContentCreationException.hpp>
29#include <sfx2/app.hxx>
30#include <helpids.h>
31#include <svx/gallery1.hxx>
32#include <svx/galtheme.hxx>
33#include <svx/galmisc.hxx>
34#include "galbrws1.hxx"
35#include <svx/strings.hrc>
36#include <algorithm>
37#include <svx/dialmgr.hxx>
40#include <com/sun/star/beans/PropertyValue.hpp>
41#include <svx/svxdlg.hxx>
42#include <memory>
43#include <bitmaps.hlst>
44
45using namespace ::com::sun::star;
46
48 weld::Builder& rBuilder,
49 Gallery* pGallery,
50 std::function<void ()> aThemeSelectionHandler)
51 :
52 mxNewTheme(rBuilder.weld_button("insert")),
53 mxThemes(rBuilder.weld_tree_view("themelist")),
54 mxMoreGalleries(rBuilder.weld_button("btnMoreGalleries")),
55 mpGallery ( pGallery ),
56 mpExchangeData ( new ExchangeData ),
57 aImgNormal ( RID_SVXBMP_THEME_NORMAL ),
58 aImgDefault ( RID_SVXBMP_THEME_DEFAULT ),
59 aImgReadOnly ( RID_SVXBMP_THEME_READONLY ),
60 maThemeSelectionHandler(std::move(aThemeSelectionHandler))
61{
62 mxNewTheme->set_help_id(HID_GALLERY_NEWTHEME);
63 mxNewTheme->connect_clicked( LINK( this, GalleryBrowser1, ClickNewThemeHdl ) );
64
65 mxThemes->make_sorted();
66 mxThemes->set_help_id( HID_GALLERY_THEMELIST );
67 mxThemes->connect_changed( LINK( this, GalleryBrowser1, SelectThemeHdl ) );
68 mxThemes->connect_popup_menu(LINK(this, GalleryBrowser1, PopupMenuHdl));
69 mxThemes->connect_key_press(LINK(this, GalleryBrowser1, KeyInputHdl));
70 mxThemes->set_size_request(-1, mxThemes->get_height_rows(6));
71
72 mxMoreGalleries->connect_clicked(LINK(this, GalleryBrowser1, OnMoreGalleriesClick));
73
74 // disable creation of new themes if a writable directory is not available
75 if( mpGallery->GetUserURL().GetProtocol() == INetProtocol::NotValid )
76 mxNewTheme->set_sensitive(false);
77
79
80 for (size_t i = 0, nCount = mpGallery->GetThemeCount(); i < nCount; ++i)
82}
83
85{
87 mpExchangeData.reset();
88}
89
91{
92 static const bool bShowHiddenThemes = ( getenv( "GALLERY_SHOW_HIDDEN_THEMES" ) != nullptr );
93
94 if( !(pEntry && ( !pEntry->IsHidden() || bShowHiddenThemes )) )
95 return;
96
97 const OUString* pImage;
98
99 if( pEntry->IsReadOnly() )
100 pImage = &aImgReadOnly;
101 else if( pEntry->IsDefault() )
102 pImage = &aImgDefault;
103 else
104 pImage = &aImgNormal;
105
106 mxThemes->append("", pEntry->GetThemeName(), *pImage);
107}
108
110{
111 rData.pTheme = const_cast<GalleryTheme*>(pThm);
112 rData.aEditedTitle = pThm->GetName();
113
114 try
115 {
116 DateTime aDateTime(pThm->getModificationDate());
117
118 rData.aThemeChangeDate = aDateTime;
119 rData.aThemeChangeTime = aDateTime;
120 }
121 catch( const ucb::ContentCreationException& )
122 {
123 }
124 catch( const uno::RuntimeException& )
125 {
126 }
127 catch( const uno::Exception& )
128 {
129 }
130}
131
132void GalleryBrowser1::ImplGetExecuteVector(std::vector<OUString>& o_aExec)
133{
135
136 if( !pTheme )
137 return;
138
139 bool bUpdateAllowed, bRenameAllowed, bRemoveAllowed;
140 static const bool bIdDialog = ( getenv( "GALLERY_ENABLE_ID_DIALOG" ) != nullptr );
141
142 if( pTheme->IsReadOnly() )
143 bUpdateAllowed = bRenameAllowed = bRemoveAllowed = false;
144 else if( pTheme->IsDefault() )
145 {
146 bUpdateAllowed = bRenameAllowed = true;
147 bRemoveAllowed = false;
148 }
149 else
150 bUpdateAllowed = bRenameAllowed = bRemoveAllowed = true;
151
152 if( bUpdateAllowed && pTheme->GetObjectCount() )
153 o_aExec.emplace_back("update");
154
155 if( bRenameAllowed )
156 o_aExec.emplace_back("rename");
157
158 if( bRemoveAllowed )
159 o_aExec.emplace_back("delete");
160
161 if( bIdDialog && !pTheme->IsReadOnly() )
162 o_aExec.emplace_back("assign");
163
164 o_aExec.emplace_back("properties");
165
166 mpGallery->ReleaseTheme( pTheme, *this );
167}
168
169void GalleryBrowser1::ImplGalleryThemeProperties( std::u16string_view rThemeName, bool bCreateNew )
170{
171 DBG_ASSERT(!mpThemePropsDlgItemSet, "mpThemePropsDlgItemSet already set!");
172 mpThemePropsDlgItemSet.reset(new SfxItemSet( SfxGetpApp()->GetPool() ));
173 GalleryTheme* pTheme = mpGallery->AcquireTheme( rThemeName, *this );
174
176
179
180 if ( bCreateNew )
181 {
182 xThemePropertiesDialog->StartExecuteAsync([xThemePropertiesDialog, this](sal_Int32 nResult){
184 xThemePropertiesDialog->disposeOnce();
185 });
186 }
187 else
188 {
189 xThemePropertiesDialog->StartExecuteAsync([xThemePropertiesDialog, this](sal_Int32 nResult){
191 xThemePropertiesDialog->disposeOnce();
192 });
193 }
194}
195
196void GalleryBrowser1::ImplEndGalleryThemeProperties(bool bCreateNew, sal_Int32 nRet)
197{
198 if( nRet == RET_OK )
199 {
200 OUString aName( mpExchangeData->pTheme->GetName() );
201
202 if( !mpExchangeData->aEditedTitle.isEmpty() && aName != mpExchangeData->aEditedTitle )
203 {
204 OUString aTitle( mpExchangeData->aEditedTitle );
205 sal_uInt16 nCount = 0;
206
207 while( mpGallery->HasTheme( aTitle ) && ( nCount++ < 16000 ) )
208 {
209 aTitle = mpExchangeData->aEditedTitle + " " + OUString::number( nCount );
210 }
211
212 mpGallery->RenameTheme( aName, aTitle );
213 }
214
215 if ( bCreateNew )
216 {
217 mxThemes->select_text( mpExchangeData->pTheme->GetName() );
218 SelectThemeHdl( *mxThemes );
219 }
220 }
221
222 OUString aThemeName( mpExchangeData->pTheme->GetName() );
223 mpGallery->ReleaseTheme( mpExchangeData->pTheme, *this );
224
225 if ( bCreateNew && ( nRet != RET_OK ) )
226 {
227 mpGallery->RemoveTheme( aThemeName );
228 }
229}
230
232{
233 ImplEndGalleryThemeProperties(true, nResult);
234}
235
237{
238 ImplEndGalleryThemeProperties(false, nResult);
239}
240
241void GalleryBrowser1::ImplExecute(std::u16string_view rIdent)
242{
243 if (rIdent == u"update")
244 {
246
248 ScopedVclPtr<VclAbstractDialog> aActualizeProgress(pFact->CreateActualizeProgressDialog(mxThemes.get(), pTheme));
249
250 aActualizeProgress->Execute();
251 mpGallery->ReleaseTheme( pTheme, *this );
252 }
253 else if (rIdent == u"delete")
254 {
255 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(mxThemes.get(), "svx/ui/querydeletethemedialog.ui"));
256 std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("QueryDeleteThemeDialog"));
257 if (xQuery->run() == RET_YES)
258 mpGallery->RemoveTheme( mxThemes->get_selected_text() );
259 }
260 else if (rIdent == u"rename")
261 {
263 const OUString aOldName( pTheme->GetName() );
264
267
268 if( aDlg->Execute() == RET_OK )
269 {
270 const OUString aNewName( aDlg->GetTitle() );
271
272 if( !aNewName.isEmpty() && ( aNewName != aOldName ) )
273 {
274 OUString aName( aNewName );
275 sal_uInt16 nCount = 0;
276
277 while( mpGallery->HasTheme( aName ) && ( nCount++ < 16000 ) )
278 {
279 aName = aNewName + " " + OUString::number( nCount );
280 }
281
282 mpGallery->RenameTheme( aOldName, aName );
283 }
284 }
285 mpGallery->ReleaseTheme( pTheme, *this );
286 }
287 else if (rIdent == u"assign")
288 {
290
291 if (pTheme && !pTheme->IsReadOnly())
292 {
293
296 if( aDlg->Execute() == RET_OK )
297 pTheme->SetId( aDlg->GetId(), true );
298 }
299
300 mpGallery->ReleaseTheme( pTheme, *this );
301 }
302 else if (rIdent == u"properties")
303 {
305 }
306}
307
309{
310 const GalleryHint& rGalleryHint = static_cast<const GalleryHint&>(rHint);
311
312 switch( rGalleryHint.GetType() )
313 {
316 break;
317
319 {
320 const sal_Int32 nCurSelectPos = mxThemes->get_selected_index();
321 const sal_Int32 nRenameEntryPos = mxThemes->find_text( rGalleryHint.GetThemeName() );
322
323 mxThemes->remove_text( rGalleryHint.GetThemeName() );
325
326 if( nCurSelectPos == nRenameEntryPos )
327 {
328 mxThemes->select_text( rGalleryHint.GetStringData() );
329 SelectThemeHdl( *mxThemes );
330 }
331 }
332 break;
333
335 {
336 mxThemes->remove_text( rGalleryHint.GetThemeName() );
337 }
338 break;
339
341 {
342 const sal_Int32 nCurSelectPos = mxThemes->get_selected_index();
343 const sal_Int32 nCloseEntryPos = mxThemes->find_text( rGalleryHint.GetThemeName() );
344
345 if( nCurSelectPos == nCloseEntryPos )
346 {
347 if( nCurSelectPos < ( mxThemes->n_children() - 1 ) )
348 mxThemes->select( nCurSelectPos + 1 );
349 else if( nCurSelectPos )
350 mxThemes->select( nCurSelectPos - 1 );
351 else
352 mxThemes->select(-1);
353
354 SelectThemeHdl( *mxThemes );
355 }
356 }
357 break;
358
359 default:
360 break;
361 }
362}
363
365{
366 css::uno::Sequence<css::beans::PropertyValue> aArgs{
367 comphelper::makePropertyValue("AdditionsTag", OUString("Gallery"))
368 };
369 comphelper::dispatchCommand(".uno:AdditionsDialog", aArgs);
370}
371
372IMPL_LINK(GalleryBrowser1, KeyInputHdl, const KeyEvent&, rKEvt, bool)
373{
374 bool bRet = false;
375
376 std::vector<OUString> aExecVector;
377 ImplGetExecuteVector(aExecVector);
378 OUString sExecuteIdent;
379 bool bMod1 = rKEvt.GetKeyCode().IsMod1();
380
381 switch( rKEvt.GetKeyCode().GetCode() )
382 {
383 case KEY_INSERT:
384 ClickNewThemeHdl(*mxNewTheme);
385 break;
386
387 case KEY_I:
388 {
389 if( bMod1 )
390 ClickNewThemeHdl(*mxNewTheme);
391 }
392 break;
393
394 case KEY_U:
395 {
396 if( bMod1 )
397 sExecuteIdent = "update";
398 }
399 break;
400
401 case KEY_DELETE:
402 sExecuteIdent = "delete";
403 break;
404
405 case KEY_D:
406 {
407 if( bMod1 )
408 sExecuteIdent = "delete";
409 }
410 break;
411
412 case KEY_R:
413 {
414 if( bMod1 )
415 sExecuteIdent = "rename";
416 }
417 break;
418
419 case KEY_RETURN:
420 {
421 if( bMod1 )
422 sExecuteIdent = "properties";
423 }
424 break;
425 }
426
427 if (!sExecuteIdent.isEmpty() && (std::find( aExecVector.begin(), aExecVector.end(), sExecuteIdent) != aExecVector.end()))
428 {
429 ImplExecute(sExecuteIdent);
430 bRet = true;
431 }
432
433 return bRet;
434}
435
436IMPL_LINK(GalleryBrowser1, PopupMenuHdl, const CommandEvent&, rCEvt, bool)
437{
438 if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
439 return false;
440
441 std::vector<OUString> aExecVector;
442 ImplGetExecuteVector(aExecVector);
443
444 if (aExecVector.empty())
445 return true;
446
447 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(mxThemes.get(), "svx/ui/gallerymenu1.ui"));
448 std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu("menu"));
449
450 xMenu->set_visible("update", std::find( aExecVector.begin(), aExecVector.end(), "update" ) != aExecVector.end());
451 xMenu->set_visible("rename", std::find( aExecVector.begin(), aExecVector.end(), "rename" ) != aExecVector.end());
452 xMenu->set_visible("delete", std::find( aExecVector.begin(), aExecVector.end(), "delete" ) != aExecVector.end());
453 xMenu->set_visible("assign", std::find( aExecVector.begin(), aExecVector.end(), "assign" ) != aExecVector.end());
454 xMenu->set_visible("properties", std::find( aExecVector.begin(), aExecVector.end(), "properties" ) != aExecVector.end());
455
456 OUString sCommand(xMenu->popup_at_rect(mxThemes.get(), tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1))));
457 ImplExecute(sCommand);
458
459 return true;
460}
461
463{
464 if (maThemeSelectionHandler)
465 maThemeSelectionHandler();
466}
467
469{
470 OUString aNewTheme( SvxResId(RID_SVXSTR_GALLERY_NEWTHEME) );
471 OUString aName( aNewTheme );
472 sal_uInt16 nCount = 0;
473
474 while( mpGallery->HasTheme( aName ) && ( nCount++ < 16000 ) )
475 {
476 aName = aNewTheme + " " + OUString::number( nCount );
477 }
478
479 if( !mpGallery->HasTheme( aName ) && mpGallery->CreateTheme( aName ) )
480 {
481 ImplGalleryThemeProperties( aName, true );
482 }
483}
484
485/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SfxApplication * SfxGetpApp()
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
OUString aImgDefault
Definition: galbrws1.hxx:55
Gallery * mpGallery
Definition: galbrws1.hxx:50
void EndThemePropertiesDlgHdl(sal_Int32 nResult)
Definition: galbrws1.cxx:236
OUString aImgNormal
Definition: galbrws1.hxx:54
void ImplGalleryThemeProperties(std::u16string_view rThemeName, bool bCreateNew)
Definition: galbrws1.cxx:169
void ImplEndGalleryThemeProperties(bool bCreateNew, sal_Int32 nResult)
Definition: galbrws1.cxx:196
static void ImplFillExchangeData(const GalleryTheme *pThm, ExchangeData &rData)
Definition: galbrws1.cxx:109
std::unique_ptr< weld::Button > mxMoreGalleries
Definition: galbrws1.hxx:49
std::unique_ptr< SfxItemSet > mpThemePropsDlgItemSet
Definition: galbrws1.hxx:52
OUString GetSelectedTheme() const
Definition: galbrws1.hxx:88
void ImplExecute(std::u16string_view rIdent)
Definition: galbrws1.cxx:241
GalleryBrowser1(weld::Builder &rBuilder, Gallery *pGallery, ::std::function< void()> aThemeSelectionHandler)
Definition: galbrws1.cxx:47
OUString aImgReadOnly
Definition: galbrws1.hxx:56
void ImplInsertThemeEntry(const GalleryThemeEntry *pEntry)
Definition: galbrws1.cxx:90
std::unique_ptr< weld::TreeView > mxThemes
Definition: galbrws1.hxx:48
std::unique_ptr< weld::Button > mxNewTheme
Definition: galbrws1.hxx:47
void ImplGetExecuteVector(std::vector< OUString > &o_aExec)
Definition: galbrws1.cxx:132
void EndNewThemePropertiesDlgHdl(sal_Int32 nResult)
Definition: galbrws1.cxx:231
std::unique_ptr< ExchangeData > mpExchangeData
Definition: galbrws1.hxx:51
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: galbrws1.cxx:308
const OUString & GetThemeName() const
Definition: galmisc.hxx:193
const OUString & GetStringData() const
Definition: galmisc.hxx:194
GalleryHintType GetType() const
Definition: galmisc.hxx:192
const OUString & GetThemeName() const
Definition: gallery1.hxx:64
bool IsReadOnly() const
Definition: gallery1.hxx:66
bool IsDefault() const
Definition: gallery1.cxx:722
bool IsHidden() const
Definition: gallery1.hxx:69
const OUString & GetName() const
Definition: galtheme.cxx:777
SAL_DLLPRIVATE void SetId(sal_uInt32 nNewId, bool bResetThemeName)
Definition: galtheme.cxx:773
bool IsReadOnly() const
Definition: galtheme.cxx:774
SAL_DLLPRIVATE sal_uInt32 GetObjectCount() const
Definition: galtheme.hxx:83
DateTime getModificationDate() const
Definition: galtheme.cxx:637
bool IsDefault() const
Definition: galtheme.cxx:775
void ReleaseTheme(GalleryTheme *pTheme, SfxListener &rListener)
Definition: gallery1.cxx:711
SAL_DLLPRIVATE const INetURLObject & GetUserURL() const
Definition: gallery1.hxx:140
bool HasTheme(std::u16string_view rThemeName)
Definition: gallery1.cxx:573
void RenameTheme(const OUString &rOldName, const OUString &rNewName)
Definition: gallery1.cxx:599
bool RemoveTheme(const OUString &rThemeName)
Definition: gallery1.cxx:622
size_t GetThemeCount() const
Definition: gallery1.hxx:123
SAL_DLLPRIVATE const GalleryThemeEntry * GetThemeInfo(size_t nPos)
Definition: gallery1.hxx:124
GalleryTheme * AcquireTheme(std::u16string_view rThemeName, SfxListener &rListener)
Definition: gallery1.cxx:697
INetProtocol GetProtocol() const
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
virtual VclPtr< VclAbstractDialog > CreateActualizeProgressDialog(weld::Widget *pParent, GalleryTheme *pThm)=0
virtual VclPtr< AbstractGalleryIdDialog > CreateGalleryIdDialog(weld::Widget *pParent, GalleryTheme *pThm)=0
static SvxAbstractDialogFactory * Create()
Definition: svxdlg.cxx:22
virtual VclPtr< VclAbstractDialog > CreateGalleryThemePropertiesDialog(weld::Widget *pParent, ExchangeData *pData, SfxItemSet *pItemSet)=0
virtual VclPtr< AbstractTitleDialog > CreateTitleDialog(weld::Widget *pParent, const OUString &rOldText)=0
int nCount
#define DBG_ASSERT(sCon, aError)
OUString SvxResId(TranslateId aId)
Definition: dialmgr.cxx:24
float u
IMPL_STATIC_LINK_NOARG(GalleryBrowser1, OnMoreGalleriesClick, weld::Button &, void)
Definition: galbrws1.cxx:364
IMPL_LINK(GalleryBrowser1, KeyInputHdl, const KeyEvent &, rKEvt, bool)
Definition: galbrws1.cxx:372
IMPL_LINK_NOARG(GalleryBrowser1, SelectThemeHdl, weld::TreeView &, void)
Definition: galbrws1.cxx:462
constexpr OUStringLiteral HID_GALLERY_THEMELIST
Definition: helpids.h:33
constexpr OUStringLiteral HID_GALLERY_NEWTHEME
Definition: helpids.h:32
OUString aName
constexpr sal_uInt16 KEY_RETURN
constexpr sal_uInt16 KEY_R
constexpr sal_uInt16 KEY_I
constexpr sal_uInt16 KEY_U
constexpr sal_uInt16 KEY_D
constexpr sal_uInt16 KEY_DELETE
constexpr sal_uInt16 KEY_INSERT
bool dispatchCommand(const OUString &rCommand, const uno::Reference< css::frame::XFrame > &rFrame, const css::uno::Sequence< css::beans::PropertyValue > &rArguments, const uno::Reference< css::frame::XDispatchResultListener > &rListener)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
int i
GalleryTheme * pTheme
Definition: galmisc.hxx:43
OUString aEditedTitle
Definition: galmisc.hxx:44
tools::Time aThemeChangeTime
Definition: galmisc.hxx:46
Date aThemeChangeDate
Definition: galmisc.hxx:45
RET_OK
RET_YES