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 <vcl/commandevent.hxx>
24 #include <vcl/event.hxx>
25 #include <vcl/svapp.hxx>
26 #include <vcl/weld.hxx>
27 #include <com/sun/star/ucb/ContentCreationException.hpp>
28 #include <sfx2/app.hxx>
29 #include <helpids.h>
30 #include <svx/gallery1.hxx>
31 #include <svx/galtheme.hxx>
32 #include <svx/galmisc.hxx>
33 #include "galbrws1.hxx"
34 #include <svx/strings.hrc>
35 #include <algorithm>
36 #include <svx/dialmgr.hxx>
39 #include <com/sun/star/beans/PropertyValue.hpp>
40 #include <svx/svxdlg.hxx>
41 #include <memory>
42 #include <bitmaps.hlst>
43 
44 using namespace ::com::sun::star;
45 
47  weld::Builder& rBuilder,
48  Gallery* pGallery,
49  const std::function<void ()>& rThemeSelectionHandler)
50  :
51  mxNewTheme(rBuilder.weld_button("insert")),
52  mxThemes(rBuilder.weld_tree_view("themelist")),
53  mxMoreGalleries(rBuilder.weld_button("btnMoreGalleries")),
54  mpGallery ( pGallery ),
55  mpExchangeData ( new ExchangeData ),
56  aImgNormal ( RID_SVXBMP_THEME_NORMAL ),
57  aImgDefault ( RID_SVXBMP_THEME_DEFAULT ),
58  aImgReadOnly ( RID_SVXBMP_THEME_READONLY ),
59  maThemeSelectionHandler(rThemeSelectionHandler)
60 {
61  mxNewTheme->set_help_id(HID_GALLERY_NEWTHEME);
62  mxNewTheme->connect_clicked( LINK( this, GalleryBrowser1, ClickNewThemeHdl ) );
63 
64  mxThemes->make_sorted();
65  mxThemes->set_help_id( HID_GALLERY_THEMELIST );
66  mxThemes->connect_changed( LINK( this, GalleryBrowser1, SelectThemeHdl ) );
67  mxThemes->connect_popup_menu(LINK(this, GalleryBrowser1, PopupMenuHdl));
68  mxThemes->connect_key_press(LINK(this, GalleryBrowser1, KeyInputHdl));
69  mxThemes->set_size_request(-1, mxThemes->get_height_rows(6));
70 
71  mxMoreGalleries->set_from_icon_name("cmd/sc_additionsdialog.png");
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 
132 void GalleryBrowser1::ImplGetExecuteVector(std::vector<OString>& o_aExec)
133 {
134  GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
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 
169 void 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){
190  EndThemePropertiesDlgHdl(nResult);
191  xThemePropertiesDialog->disposeOnce();
192  });
193  }
194 }
195 
196 void 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 
241 void GalleryBrowser1::ImplExecute(std::string_view rIdent)
242 {
243  if (rIdent == "update")
244  {
245  GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
246 
248  ScopedVclPtr<VclAbstractDialog> aActualizeProgress(pFact->CreateActualizeProgressDialog(mxThemes.get(), pTheme));
249 
250  aActualizeProgress->Execute();
251  mpGallery->ReleaseTheme( pTheme, *this );
252  }
253  else if (rIdent == "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 == "rename")
261  {
262  GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
263  const OUString aOldName( pTheme->GetName() );
264 
266  ScopedVclPtr<AbstractTitleDialog> aDlg(pFact->CreateTitleDialog(mxThemes.get(), aOldName));
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 == "assign")
288  {
289  GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
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 == "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 
364 IMPL_STATIC_LINK_NOARG( GalleryBrowser1, OnMoreGalleriesClick, weld::Button&, void)
365 {
366  css::uno::Sequence<css::beans::PropertyValue> aArgs{
367  comphelper::makePropertyValue("AdditionsTag", OUString("Gallery"))
368  };
369  comphelper::dispatchCommand(".uno:AdditionsDialog", aArgs);
370 }
371 
372 IMPL_LINK(GalleryBrowser1, KeyInputHdl, const KeyEvent&, rKEvt, bool)
373 {
374  bool bRet = false;
375 
376  std::vector<OString> aExecVector;
377  ImplGetExecuteVector(aExecVector);
378  OString 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 
436 IMPL_LINK(GalleryBrowser1, PopupMenuHdl, const CommandEvent&, rCEvt, bool)
437 {
438  if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
439  return false;
440 
441  std::vector<OString> 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  OString 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 
468 IMPL_LINK_NOARG(GalleryBrowser1, ClickNewThemeHdl, weld::Button&, void)
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: */
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: galbrws1.cxx:308
bool IsDefault() const
Definition: galtheme.cxx:776
virtual VclPtr< VclAbstractDialog > CreateActualizeProgressDialog(weld::Widget *pParent, GalleryTheme *pThm)=0
static SvxAbstractDialogFactory * Create()
Definition: svxdlg.cxx:22
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
void ImplEndGalleryThemeProperties(bool bCreateNew, sal_Int32 nResult)
Definition: galbrws1.cxx:196
virtual OUString GetTitle() const =0
void ImplGetExecuteVector(std::vector< OString > &o_aExec)
Definition: galbrws1.cxx:132
bool IsReadOnly() const
Definition: gallery1.hxx:66
virtual short Execute()=0
OUString aImgDefault
Definition: galbrws1.hxx:55
IMPL_LINK(GalleryBrowser1, KeyInputHdl, const KeyEvent &, rKEvt, bool)
Definition: galbrws1.cxx:372
SfxApplication * SfxGetpApp()
bool HasTheme(std::u16string_view rThemeName)
Definition: gallery1.cxx:570
size_t GetThemeCount() const
Definition: gallery1.hxx:123
RET_YES
OUString aImgReadOnly
Definition: galbrws1.hxx:56
std::unique_ptr< ExchangeData > mpExchangeData
Definition: galbrws1.hxx:51
std::unique_ptr< weld::Button > mxMoreGalleries
Definition: galbrws1.hxx:49
void RenameTheme(const OUString &rOldName, const OUString &rNewName)
Definition: gallery1.cxx:596
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)
constexpr sal_uInt16 KEY_D
int nCount
OUString SvxResId(TranslateId aId)
Definition: dialmgr.cxx:24
constexpr OStringLiteral HID_GALLERY_THEMELIST
Definition: helpids.h:33
const OUString & GetThemeName() const
Definition: galmisc.hxx:192
bool RemoveTheme(const OUString &rThemeName)
Definition: gallery1.cxx:619
void ImplGalleryThemeProperties(std::u16string_view rThemeName, bool bCreateNew)
Definition: galbrws1.cxx:169
bool IsHidden() const
Definition: gallery1.hxx:69
constexpr sal_uInt16 KEY_R
Gallery * mpGallery
Definition: galbrws1.hxx:50
GalleryHintType GetType() const
Definition: galmisc.hxx:191
void EndNewThemePropertiesDlgHdl(sal_Int32 nResult)
Definition: galbrws1.cxx:231
SAL_DLLPRIVATE const INetURLObject & GetUserURL() const
Definition: gallery1.hxx:140
#define DBG_ASSERT(sCon, aError)
int i
virtual VclPtr< AbstractGalleryIdDialog > CreateGalleryIdDialog(weld::Widget *pParent, GalleryTheme *pThm)=0
GalleryTheme * pTheme
Definition: galmisc.hxx:42
OUString GetSelectedTheme() const
Definition: galbrws1.hxx:88
SAL_DLLPRIVATE sal_uInt32 GetObjectCount() const
Definition: galtheme.hxx:82
GalleryBrowser1(weld::Builder &rBuilder, Gallery *pGallery, const ::std::function< void()> &rThemeSelectionHandler)
Definition: galbrws1.cxx:46
std::unique_ptr< SfxItemSet > mpThemePropsDlgItemSet
Definition: galbrws1.hxx:52
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
bool StartExecuteAsync(const std::function< void(sal_Int32)> &rEndDialogFn)
constexpr sal_uInt16 KEY_RETURN
tools::Time aThemeChangeTime
Definition: galmisc.hxx:45
bool IsDefault() const
Definition: gallery1.cxx:719
DateTime getModificationDate() const
Definition: galtheme.cxx:637
void EndThemePropertiesDlgHdl(sal_Int32 nResult)
Definition: galbrws1.cxx:236
virtual sal_uInt32 GetId() const =0
OUString aImgNormal
Definition: galbrws1.hxx:54
const OUString & GetStringData() const
Definition: galmisc.hxx:193
Date aThemeChangeDate
Definition: galmisc.hxx:44
void ReleaseTheme(GalleryTheme *pTheme, SfxListener &rListener)
Definition: gallery1.cxx:708
static void ImplFillExchangeData(const GalleryTheme *pThm, ExchangeData &rData)
Definition: galbrws1.cxx:109
constexpr OStringLiteral HID_GALLERY_NEWTHEME
Definition: helpids.h:32
OUString aName
SAL_DLLPRIVATE const GalleryThemeEntry * GetThemeInfo(size_t nPos)
Definition: gallery1.hxx:124
INetProtocol GetProtocol() const
RET_OK
IMPL_STATIC_LINK_NOARG(GalleryBrowser1, OnMoreGalleriesClick, weld::Button &, void)
Definition: galbrws1.cxx:364
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
std::unique_ptr< weld::TreeView > mxThemes
Definition: galbrws1.hxx:48
constexpr sal_uInt16 KEY_U
void ImplExecute(std::string_view rIdent)
Definition: galbrws1.cxx:241
std::unique_ptr< weld::Button > mxNewTheme
Definition: galbrws1.hxx:47
void ImplInsertThemeEntry(const GalleryThemeEntry *pEntry)
Definition: galbrws1.cxx:90
SAL_DLLPRIVATE void SetId(sal_uInt32 nNewId, bool bResetThemeName)
Definition: galtheme.cxx:774
constexpr sal_uInt16 KEY_I
const OUString & GetName() const
Definition: galtheme.cxx:778
constexpr sal_uInt16 KEY_DELETE
IMPL_LINK_NOARG(GalleryBrowser1, SelectThemeHdl, weld::TreeView &, void)
Definition: galbrws1.cxx:462
bool IsReadOnly() const
Definition: galtheme.cxx:775
constexpr sal_uInt16 KEY_INSERT
virtual VclPtr< VclAbstractDialog > CreateGalleryThemePropertiesDialog(weld::Widget *pParent, ExchangeData *pData, SfxItemSet *pItemSet)=0
GalleryTheme * AcquireTheme(std::u16string_view rThemeName, SfxListener &rListener)
Definition: gallery1.cxx:694
const OUString & GetThemeName() const
Definition: gallery1.hxx:64
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
OUString aEditedTitle
Definition: galmisc.hxx:43