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->set_from_icon_name("cmd/sc_additionsdialog.png");
73 mxMoreGalleries->connect_clicked(LINK(this, GalleryBrowser1, OnMoreGalleriesClick));
74
75 // disable creation of new themes if a writable directory is not available
76 if( mpGallery->GetUserURL().GetProtocol() == INetProtocol::NotValid )
77 mxNewTheme->set_sensitive(false);
78
80
81 for (size_t i = 0, nCount = mpGallery->GetThemeCount(); i < nCount; ++i)
83}
84
86{
88 mpExchangeData.reset();
89}
90
92{
93 static const bool bShowHiddenThemes = ( getenv( "GALLERY_SHOW_HIDDEN_THEMES" ) != nullptr );
94
95 if( !(pEntry && ( !pEntry->IsHidden() || bShowHiddenThemes )) )
96 return;
97
98 const OUString* pImage;
99
100 if( pEntry->IsReadOnly() )
101 pImage = &aImgReadOnly;
102 else if( pEntry->IsDefault() )
103 pImage = &aImgDefault;
104 else
105 pImage = &aImgNormal;
106
107 mxThemes->append("", pEntry->GetThemeName(), *pImage);
108}
109
111{
112 rData.pTheme = const_cast<GalleryTheme*>(pThm);
113 rData.aEditedTitle = pThm->GetName();
114
115 try
116 {
117 DateTime aDateTime(pThm->getModificationDate());
118
119 rData.aThemeChangeDate = aDateTime;
120 rData.aThemeChangeTime = aDateTime;
121 }
122 catch( const ucb::ContentCreationException& )
123 {
124 }
125 catch( const uno::RuntimeException& )
126 {
127 }
128 catch( const uno::Exception& )
129 {
130 }
131}
132
133void GalleryBrowser1::ImplGetExecuteVector(std::vector<OString>& o_aExec)
134{
136
137 if( !pTheme )
138 return;
139
140 bool bUpdateAllowed, bRenameAllowed, bRemoveAllowed;
141 static const bool bIdDialog = ( getenv( "GALLERY_ENABLE_ID_DIALOG" ) != nullptr );
142
143 if( pTheme->IsReadOnly() )
144 bUpdateAllowed = bRenameAllowed = bRemoveAllowed = false;
145 else if( pTheme->IsDefault() )
146 {
147 bUpdateAllowed = bRenameAllowed = true;
148 bRemoveAllowed = false;
149 }
150 else
151 bUpdateAllowed = bRenameAllowed = bRemoveAllowed = true;
152
153 if( bUpdateAllowed && pTheme->GetObjectCount() )
154 o_aExec.emplace_back("update");
155
156 if( bRenameAllowed )
157 o_aExec.emplace_back("rename");
158
159 if( bRemoveAllowed )
160 o_aExec.emplace_back("delete");
161
162 if( bIdDialog && !pTheme->IsReadOnly() )
163 o_aExec.emplace_back("assign");
164
165 o_aExec.emplace_back("properties");
166
167 mpGallery->ReleaseTheme( pTheme, *this );
168}
169
170void GalleryBrowser1::ImplGalleryThemeProperties( std::u16string_view rThemeName, bool bCreateNew )
171{
172 DBG_ASSERT(!mpThemePropsDlgItemSet, "mpThemePropsDlgItemSet already set!");
173 mpThemePropsDlgItemSet.reset(new SfxItemSet( SfxGetpApp()->GetPool() ));
174 GalleryTheme* pTheme = mpGallery->AcquireTheme( rThemeName, *this );
175
177
180
181 if ( bCreateNew )
182 {
183 xThemePropertiesDialog->StartExecuteAsync([xThemePropertiesDialog, this](sal_Int32 nResult){
185 xThemePropertiesDialog->disposeOnce();
186 });
187 }
188 else
189 {
190 xThemePropertiesDialog->StartExecuteAsync([xThemePropertiesDialog, this](sal_Int32 nResult){
192 xThemePropertiesDialog->disposeOnce();
193 });
194 }
195}
196
197void GalleryBrowser1::ImplEndGalleryThemeProperties(bool bCreateNew, sal_Int32 nRet)
198{
199 if( nRet == RET_OK )
200 {
201 OUString aName( mpExchangeData->pTheme->GetName() );
202
203 if( !mpExchangeData->aEditedTitle.isEmpty() && aName != mpExchangeData->aEditedTitle )
204 {
205 OUString aTitle( mpExchangeData->aEditedTitle );
206 sal_uInt16 nCount = 0;
207
208 while( mpGallery->HasTheme( aTitle ) && ( nCount++ < 16000 ) )
209 {
210 aTitle = mpExchangeData->aEditedTitle + " " + OUString::number( nCount );
211 }
212
213 mpGallery->RenameTheme( aName, aTitle );
214 }
215
216 if ( bCreateNew )
217 {
218 mxThemes->select_text( mpExchangeData->pTheme->GetName() );
219 SelectThemeHdl( *mxThemes );
220 }
221 }
222
223 OUString aThemeName( mpExchangeData->pTheme->GetName() );
224 mpGallery->ReleaseTheme( mpExchangeData->pTheme, *this );
225
226 if ( bCreateNew && ( nRet != RET_OK ) )
227 {
228 mpGallery->RemoveTheme( aThemeName );
229 }
230}
231
233{
234 ImplEndGalleryThemeProperties(true, nResult);
235}
236
238{
239 ImplEndGalleryThemeProperties(false, nResult);
240}
241
242void GalleryBrowser1::ImplExecute(std::string_view rIdent)
243{
244 if (rIdent == "update")
245 {
247
249 ScopedVclPtr<VclAbstractDialog> aActualizeProgress(pFact->CreateActualizeProgressDialog(mxThemes.get(), pTheme));
250
251 aActualizeProgress->Execute();
252 mpGallery->ReleaseTheme( pTheme, *this );
253 }
254 else if (rIdent == "delete")
255 {
256 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(mxThemes.get(), "svx/ui/querydeletethemedialog.ui"));
257 std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("QueryDeleteThemeDialog"));
258 if (xQuery->run() == RET_YES)
259 mpGallery->RemoveTheme( mxThemes->get_selected_text() );
260 }
261 else if (rIdent == "rename")
262 {
264 const OUString aOldName( pTheme->GetName() );
265
268
269 if( aDlg->Execute() == RET_OK )
270 {
271 const OUString aNewName( aDlg->GetTitle() );
272
273 if( !aNewName.isEmpty() && ( aNewName != aOldName ) )
274 {
275 OUString aName( aNewName );
276 sal_uInt16 nCount = 0;
277
278 while( mpGallery->HasTheme( aName ) && ( nCount++ < 16000 ) )
279 {
280 aName = aNewName + " " + OUString::number( nCount );
281 }
282
283 mpGallery->RenameTheme( aOldName, aName );
284 }
285 }
286 mpGallery->ReleaseTheme( pTheme, *this );
287 }
288 else if (rIdent == "assign")
289 {
291
292 if (pTheme && !pTheme->IsReadOnly())
293 {
294
297 if( aDlg->Execute() == RET_OK )
298 pTheme->SetId( aDlg->GetId(), true );
299 }
300
301 mpGallery->ReleaseTheme( pTheme, *this );
302 }
303 else if (rIdent == "properties")
304 {
306 }
307}
308
310{
311 const GalleryHint& rGalleryHint = static_cast<const GalleryHint&>(rHint);
312
313 switch( rGalleryHint.GetType() )
314 {
317 break;
318
320 {
321 const sal_Int32 nCurSelectPos = mxThemes->get_selected_index();
322 const sal_Int32 nRenameEntryPos = mxThemes->find_text( rGalleryHint.GetThemeName() );
323
324 mxThemes->remove_text( rGalleryHint.GetThemeName() );
326
327 if( nCurSelectPos == nRenameEntryPos )
328 {
329 mxThemes->select_text( rGalleryHint.GetStringData() );
330 SelectThemeHdl( *mxThemes );
331 }
332 }
333 break;
334
336 {
337 mxThemes->remove_text( rGalleryHint.GetThemeName() );
338 }
339 break;
340
342 {
343 const sal_Int32 nCurSelectPos = mxThemes->get_selected_index();
344 const sal_Int32 nCloseEntryPos = mxThemes->find_text( rGalleryHint.GetThemeName() );
345
346 if( nCurSelectPos == nCloseEntryPos )
347 {
348 if( nCurSelectPos < ( mxThemes->n_children() - 1 ) )
349 mxThemes->select( nCurSelectPos + 1 );
350 else if( nCurSelectPos )
351 mxThemes->select( nCurSelectPos - 1 );
352 else
353 mxThemes->select(-1);
354
355 SelectThemeHdl( *mxThemes );
356 }
357 }
358 break;
359
360 default:
361 break;
362 }
363}
364
366{
367 css::uno::Sequence<css::beans::PropertyValue> aArgs{
368 comphelper::makePropertyValue("AdditionsTag", OUString("Gallery"))
369 };
370 comphelper::dispatchCommand(".uno:AdditionsDialog", aArgs);
371}
372
373IMPL_LINK(GalleryBrowser1, KeyInputHdl, const KeyEvent&, rKEvt, bool)
374{
375 bool bRet = false;
376
377 std::vector<OString> aExecVector;
378 ImplGetExecuteVector(aExecVector);
379 OString sExecuteIdent;
380 bool bMod1 = rKEvt.GetKeyCode().IsMod1();
381
382 switch( rKEvt.GetKeyCode().GetCode() )
383 {
384 case KEY_INSERT:
385 ClickNewThemeHdl(*mxNewTheme);
386 break;
387
388 case KEY_I:
389 {
390 if( bMod1 )
391 ClickNewThemeHdl(*mxNewTheme);
392 }
393 break;
394
395 case KEY_U:
396 {
397 if( bMod1 )
398 sExecuteIdent = "update";
399 }
400 break;
401
402 case KEY_DELETE:
403 sExecuteIdent = "delete";
404 break;
405
406 case KEY_D:
407 {
408 if( bMod1 )
409 sExecuteIdent = "delete";
410 }
411 break;
412
413 case KEY_R:
414 {
415 if( bMod1 )
416 sExecuteIdent = "rename";
417 }
418 break;
419
420 case KEY_RETURN:
421 {
422 if( bMod1 )
423 sExecuteIdent = "properties";
424 }
425 break;
426 }
427
428 if (!sExecuteIdent.isEmpty() && (std::find( aExecVector.begin(), aExecVector.end(), sExecuteIdent) != aExecVector.end()))
429 {
430 ImplExecute(sExecuteIdent);
431 bRet = true;
432 }
433
434 return bRet;
435}
436
437IMPL_LINK(GalleryBrowser1, PopupMenuHdl, const CommandEvent&, rCEvt, bool)
438{
439 if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
440 return false;
441
442 std::vector<OString> aExecVector;
443 ImplGetExecuteVector(aExecVector);
444
445 if (aExecVector.empty())
446 return true;
447
448 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(mxThemes.get(), "svx/ui/gallerymenu1.ui"));
449 std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu("menu"));
450
451 xMenu->set_visible("update", std::find( aExecVector.begin(), aExecVector.end(), "update" ) != aExecVector.end());
452 xMenu->set_visible("rename", std::find( aExecVector.begin(), aExecVector.end(), "rename" ) != aExecVector.end());
453 xMenu->set_visible("delete", std::find( aExecVector.begin(), aExecVector.end(), "delete" ) != aExecVector.end());
454 xMenu->set_visible("assign", std::find( aExecVector.begin(), aExecVector.end(), "assign" ) != aExecVector.end());
455 xMenu->set_visible("properties", std::find( aExecVector.begin(), aExecVector.end(), "properties" ) != aExecVector.end());
456
457 OString sCommand(xMenu->popup_at_rect(mxThemes.get(), tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1))));
458 ImplExecute(sCommand);
459
460 return true;
461}
462
464{
465 if (maThemeSelectionHandler)
466 maThemeSelectionHandler();
467}
468
470{
471 OUString aNewTheme( SvxResId(RID_SVXSTR_GALLERY_NEWTHEME) );
472 OUString aName( aNewTheme );
473 sal_uInt16 nCount = 0;
474
475 while( mpGallery->HasTheme( aName ) && ( nCount++ < 16000 ) )
476 {
477 aName = aNewTheme + " " + OUString::number( nCount );
478 }
479
480 if( !mpGallery->HasTheme( aName ) && mpGallery->CreateTheme( aName ) )
481 {
482 ImplGalleryThemeProperties( aName, true );
483 }
484}
485
486/* 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:237
OUString aImgNormal
Definition: galbrws1.hxx:54
void ImplGalleryThemeProperties(std::u16string_view rThemeName, bool bCreateNew)
Definition: galbrws1.cxx:170
void ImplEndGalleryThemeProperties(bool bCreateNew, sal_Int32 nResult)
Definition: galbrws1.cxx:197
static void ImplFillExchangeData(const GalleryTheme *pThm, ExchangeData &rData)
Definition: galbrws1.cxx:110
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
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:91
std::unique_ptr< weld::TreeView > mxThemes
Definition: galbrws1.hxx:48
std::unique_ptr< weld::Button > mxNewTheme
Definition: galbrws1.hxx:47
void ImplGetExecuteVector(std::vector< OString > &o_aExec)
Definition: galbrws1.cxx:133
void ImplExecute(std::string_view rIdent)
Definition: galbrws1.cxx:242
void EndNewThemePropertiesDlgHdl(sal_Int32 nResult)
Definition: galbrws1.cxx:232
std::unique_ptr< ExchangeData > mpExchangeData
Definition: galbrws1.hxx:51
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: galbrws1.cxx:309
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:719
bool IsHidden() const
Definition: gallery1.hxx:69
const OUString & GetName() const
Definition: galtheme.cxx:778
SAL_DLLPRIVATE void SetId(sal_uInt32 nNewId, bool bResetThemeName)
Definition: galtheme.cxx:774
bool IsReadOnly() const
Definition: galtheme.cxx:775
SAL_DLLPRIVATE sal_uInt32 GetObjectCount() const
Definition: galtheme.hxx:82
DateTime getModificationDate() const
Definition: galtheme.cxx:637
bool IsDefault() const
Definition: galtheme.cxx:776
void ReleaseTheme(GalleryTheme *pTheme, SfxListener &rListener)
Definition: gallery1.cxx:708
SAL_DLLPRIVATE const INetURLObject & GetUserURL() const
Definition: gallery1.hxx:140
bool HasTheme(std::u16string_view rThemeName)
Definition: gallery1.cxx:570
void RenameTheme(const OUString &rOldName, const OUString &rNewName)
Definition: gallery1.cxx:596
bool RemoveTheme(const OUString &rThemeName)
Definition: gallery1.cxx:619
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:694
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
IMPL_STATIC_LINK_NOARG(GalleryBrowser1, OnMoreGalleriesClick, weld::Button &, void)
Definition: galbrws1.cxx:365
IMPL_LINK(GalleryBrowser1, KeyInputHdl, const KeyEvent &, rKEvt, bool)
Definition: galbrws1.cxx:373
IMPL_LINK_NOARG(GalleryBrowser1, SelectThemeHdl, weld::TreeView &, void)
Definition: galbrws1.cxx:463
constexpr OStringLiteral HID_GALLERY_THEMELIST
Definition: helpids.h:33
constexpr OStringLiteral 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