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>
38 #include <com/sun/star/beans/PropertyValue.hpp>
39 #include <svx/svxdlg.hxx>
40 #include <memory>
41 #include <bitmaps.hlst>
42 
43 using namespace ::com::sun::star;
44 
46  weld::Builder& rBuilder,
47  Gallery* pGallery,
48  const std::function<void ()>& rThemeSelectionHandler)
49  :
50  mxNewTheme(rBuilder.weld_button("insert")),
51  mxThemes(rBuilder.weld_tree_view("themelist")),
52  mxMoreGalleries(rBuilder.weld_button("btnMoreGalleries")),
53  mpGallery ( pGallery ),
54  mpExchangeData ( new ExchangeData ),
55  aImgNormal ( RID_SVXBMP_THEME_NORMAL ),
56  aImgDefault ( RID_SVXBMP_THEME_DEFAULT ),
57  aImgReadOnly ( RID_SVXBMP_THEME_READONLY ),
58  maThemeSelectionHandler(rThemeSelectionHandler)
59 {
60  mxNewTheme->set_help_id(HID_GALLERY_NEWTHEME);
61  mxNewTheme->connect_clicked( LINK( this, GalleryBrowser1, ClickNewThemeHdl ) );
62 
63  mxThemes->make_sorted();
64  mxThemes->set_help_id( HID_GALLERY_THEMELIST );
65  mxThemes->connect_changed( LINK( this, GalleryBrowser1, SelectThemeHdl ) );
66  mxThemes->connect_popup_menu(LINK(this, GalleryBrowser1, PopupMenuHdl));
67  mxThemes->connect_key_press(LINK(this, GalleryBrowser1, KeyInputHdl));
68  mxThemes->set_size_request(-1, mxThemes->get_height_rows(6));
69 
70  mxMoreGalleries->set_from_icon_name("cmd/sc_additionsdialog.png");
71  mxMoreGalleries->connect_clicked(LINK(this, GalleryBrowser1, OnMoreGalleriesClick));
72 
73  // disable creation of new themes if a writable directory is not available
74  if( mpGallery->GetUserURL().GetProtocol() == INetProtocol::NotValid )
75  mxNewTheme->set_sensitive(false);
76 
78 
79  for (size_t i = 0, nCount = mpGallery->GetThemeCount(); i < nCount; ++i)
81 }
82 
84 {
86  mpExchangeData.reset();
87 }
88 
90 {
91  static const bool bShowHiddenThemes = ( getenv( "GALLERY_SHOW_HIDDEN_THEMES" ) != nullptr );
92 
93  if( !(pEntry && ( !pEntry->IsHidden() || bShowHiddenThemes )) )
94  return;
95 
96  const OUString* pImage;
97 
98  if( pEntry->IsReadOnly() )
99  pImage = &aImgReadOnly;
100  else if( pEntry->IsDefault() )
101  pImage = &aImgDefault;
102  else
103  pImage = &aImgNormal;
104 
105  mxThemes->append("", pEntry->GetThemeName(), *pImage);
106 }
107 
109 {
110  rData.pTheme = const_cast<GalleryTheme*>(pThm);
111  rData.aEditedTitle = pThm->GetName();
112 
113  try
114  {
115  DateTime aDateTime(pThm->getModificationDate());
116 
117  rData.aThemeChangeDate = aDateTime;
118  rData.aThemeChangeTime = aDateTime;
119  }
120  catch( const ucb::ContentCreationException& )
121  {
122  }
123  catch( const uno::RuntimeException& )
124  {
125  }
126  catch( const uno::Exception& )
127  {
128  }
129 }
130 
131 void GalleryBrowser1::ImplGetExecuteVector(std::vector<OString>& o_aExec)
132 {
133  GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
134 
135  if( !pTheme )
136  return;
137 
138  bool bUpdateAllowed, bRenameAllowed, bRemoveAllowed;
139  static const bool bIdDialog = ( getenv( "GALLERY_ENABLE_ID_DIALOG" ) != nullptr );
140 
141  if( pTheme->IsReadOnly() )
142  bUpdateAllowed = bRenameAllowed = bRemoveAllowed = false;
143  else if( pTheme->IsDefault() )
144  {
145  bUpdateAllowed = bRenameAllowed = true;
146  bRemoveAllowed = false;
147  }
148  else
149  bUpdateAllowed = bRenameAllowed = bRemoveAllowed = true;
150 
151  if( bUpdateAllowed && pTheme->GetObjectCount() )
152  o_aExec.emplace_back("update");
153 
154  if( bRenameAllowed )
155  o_aExec.emplace_back("rename");
156 
157  if( bRemoveAllowed )
158  o_aExec.emplace_back("delete");
159 
160  if( bIdDialog && !pTheme->IsReadOnly() )
161  o_aExec.emplace_back("assign");
162 
163  o_aExec.emplace_back("properties");
164 
165  mpGallery->ReleaseTheme( pTheme, *this );
166 }
167 
168 void GalleryBrowser1::ImplGalleryThemeProperties( std::u16string_view rThemeName, bool bCreateNew )
169 {
170  DBG_ASSERT(!mpThemePropsDlgItemSet, "mpThemePropsDlgItemSet already set!");
171  mpThemePropsDlgItemSet.reset(new SfxItemSet( SfxGetpApp()->GetPool() ));
172  GalleryTheme* pTheme = mpGallery->AcquireTheme( rThemeName, *this );
173 
175 
178 
179  if ( bCreateNew )
180  {
181  xThemePropertiesDialog->StartExecuteAsync([xThemePropertiesDialog, this](sal_Int32 nResult){
183  xThemePropertiesDialog->disposeOnce();
184  });
185  }
186  else
187  {
188  xThemePropertiesDialog->StartExecuteAsync([xThemePropertiesDialog, this](sal_Int32 nResult){
189  EndThemePropertiesDlgHdl(nResult);
190  xThemePropertiesDialog->disposeOnce();
191  });
192  }
193 }
194 
195 void GalleryBrowser1::ImplEndGalleryThemeProperties(bool bCreateNew, sal_Int32 nRet)
196 {
197  if( nRet == RET_OK )
198  {
199  OUString aName( mpExchangeData->pTheme->GetName() );
200 
201  if( !mpExchangeData->aEditedTitle.isEmpty() && aName != mpExchangeData->aEditedTitle )
202  {
203  OUString aTitle( mpExchangeData->aEditedTitle );
204  sal_uInt16 nCount = 0;
205 
206  while( mpGallery->HasTheme( aTitle ) && ( nCount++ < 16000 ) )
207  {
208  aTitle = mpExchangeData->aEditedTitle + " " + OUString::number( nCount );
209  }
210 
211  mpGallery->RenameTheme( aName, aTitle );
212  }
213 
214  if ( bCreateNew )
215  {
216  mxThemes->select_text( mpExchangeData->pTheme->GetName() );
217  SelectThemeHdl( *mxThemes );
218  }
219  }
220 
221  OUString aThemeName( mpExchangeData->pTheme->GetName() );
222  mpGallery->ReleaseTheme( mpExchangeData->pTheme, *this );
223 
224  if ( bCreateNew && ( nRet != RET_OK ) )
225  {
226  mpGallery->RemoveTheme( aThemeName );
227  }
228 }
229 
231 {
232  ImplEndGalleryThemeProperties(true, nResult);
233 }
234 
236 {
237  ImplEndGalleryThemeProperties(false, nResult);
238 }
239 
240 void GalleryBrowser1::ImplExecute(std::string_view rIdent)
241 {
242  if (rIdent == "update")
243  {
244  GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
245 
247  ScopedVclPtr<VclAbstractDialog> aActualizeProgress(pFact->CreateActualizeProgressDialog(mxThemes.get(), pTheme));
248 
249  aActualizeProgress->Execute();
250  mpGallery->ReleaseTheme( pTheme, *this );
251  }
252  else if (rIdent == "delete")
253  {
254  std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(mxThemes.get(), "svx/ui/querydeletethemedialog.ui"));
255  std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("QueryDeleteThemeDialog"));
256  if (xQuery->run() == RET_YES)
257  mpGallery->RemoveTheme( mxThemes->get_selected_text() );
258  }
259  else if (rIdent == "rename")
260  {
261  GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
262  const OUString aOldName( pTheme->GetName() );
263 
265  ScopedVclPtr<AbstractTitleDialog> aDlg(pFact->CreateTitleDialog(mxThemes.get(), aOldName));
266 
267  if( aDlg->Execute() == RET_OK )
268  {
269  const OUString aNewName( aDlg->GetTitle() );
270 
271  if( !aNewName.isEmpty() && ( aNewName != aOldName ) )
272  {
273  OUString aName( aNewName );
274  sal_uInt16 nCount = 0;
275 
276  while( mpGallery->HasTheme( aName ) && ( nCount++ < 16000 ) )
277  {
278  aName = aNewName + " " + OUString::number( nCount );
279  }
280 
281  mpGallery->RenameTheme( aOldName, aName );
282  }
283  }
284  mpGallery->ReleaseTheme( pTheme, *this );
285  }
286  else if (rIdent == "assign")
287  {
288  GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
289 
290  if (pTheme && !pTheme->IsReadOnly())
291  {
292 
295  if( aDlg->Execute() == RET_OK )
296  pTheme->SetId( aDlg->GetId(), true );
297  }
298 
299  mpGallery->ReleaseTheme( pTheme, *this );
300  }
301  else if (rIdent == "properties")
302  {
304  }
305 }
306 
308 {
309  if (mxNewTheme->get_sensitive())
310  return mxNewTheme.get();
311  else
312  return mxThemes.get();
313 }
314 
316 {
318 }
319 
321 {
322  const GalleryHint& rGalleryHint = static_cast<const GalleryHint&>(rHint);
323 
324  switch( rGalleryHint.GetType() )
325  {
328  break;
329 
331  {
332  const sal_Int32 nCurSelectPos = mxThemes->get_selected_index();
333  const sal_Int32 nRenameEntryPos = mxThemes->find_text( rGalleryHint.GetThemeName() );
334 
335  mxThemes->remove_text( rGalleryHint.GetThemeName() );
337 
338  if( nCurSelectPos == nRenameEntryPos )
339  {
340  mxThemes->select_text( rGalleryHint.GetStringData() );
341  SelectThemeHdl( *mxThemes );
342  }
343  }
344  break;
345 
347  {
348  mxThemes->remove_text( rGalleryHint.GetThemeName() );
349  }
350  break;
351 
353  {
354  const sal_Int32 nCurSelectPos = mxThemes->get_selected_index();
355  const sal_Int32 nCloseEntryPos = mxThemes->find_text( rGalleryHint.GetThemeName() );
356 
357  if( nCurSelectPos == nCloseEntryPos )
358  {
359  if( nCurSelectPos < ( mxThemes->n_children() - 1 ) )
360  mxThemes->select( nCurSelectPos + 1 );
361  else if( nCurSelectPos )
362  mxThemes->select( nCurSelectPos - 1 );
363  else
364  mxThemes->select(-1);
365 
366  SelectThemeHdl( *mxThemes );
367  }
368  }
369  break;
370 
371  default:
372  break;
373  }
374 }
375 
376 IMPL_STATIC_LINK_NOARG( GalleryBrowser1, OnMoreGalleriesClick, weld::Button&, void)
377 {
378  css::uno::Sequence<css::beans::PropertyValue> aArgs(1);
379  aArgs[0].Name = "AdditionsTag";
380  aArgs[0].Value <<= OUString("Gallery");
381  comphelper::dispatchCommand(".uno:AdditionsDialog", aArgs);
382 }
383 
384 IMPL_LINK(GalleryBrowser1, KeyInputHdl, const KeyEvent&, rKEvt, bool)
385 {
386  bool bRet = false;
387 
388  std::vector<OString> aExecVector;
389  ImplGetExecuteVector(aExecVector);
390  OString sExecuteIdent;
391  bool bMod1 = rKEvt.GetKeyCode().IsMod1();
392 
393  switch( rKEvt.GetKeyCode().GetCode() )
394  {
395  case KEY_INSERT:
396  ClickNewThemeHdl(*mxNewTheme);
397  break;
398 
399  case KEY_I:
400  {
401  if( bMod1 )
402  ClickNewThemeHdl(*mxNewTheme);
403  }
404  break;
405 
406  case KEY_U:
407  {
408  if( bMod1 )
409  sExecuteIdent = "update";
410  }
411  break;
412 
413  case KEY_DELETE:
414  sExecuteIdent = "delete";
415  break;
416 
417  case KEY_D:
418  {
419  if( bMod1 )
420  sExecuteIdent = "delete";
421  }
422  break;
423 
424  case KEY_R:
425  {
426  if( bMod1 )
427  sExecuteIdent = "rename";
428  }
429  break;
430 
431  case KEY_RETURN:
432  {
433  if( bMod1 )
434  sExecuteIdent = "properties";
435  }
436  break;
437  }
438 
439  if (!sExecuteIdent.isEmpty() && (std::find( aExecVector.begin(), aExecVector.end(), sExecuteIdent) != aExecVector.end()))
440  {
441  ImplExecute(sExecuteIdent);
442  bRet = true;
443  }
444 
445  return bRet;
446 }
447 
448 IMPL_LINK(GalleryBrowser1, PopupMenuHdl, const CommandEvent&, rCEvt, bool)
449 {
450  if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
451  return false;
452 
453  std::vector<OString> aExecVector;
454  ImplGetExecuteVector(aExecVector);
455 
456  if (aExecVector.empty())
457  return true;
458 
459  std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(mxThemes.get(), "svx/ui/gallerymenu1.ui"));
460  std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu("menu"));
461 
462  xMenu->set_visible("update", std::find( aExecVector.begin(), aExecVector.end(), "update" ) != aExecVector.end());
463  xMenu->set_visible("rename", std::find( aExecVector.begin(), aExecVector.end(), "rename" ) != aExecVector.end());
464  xMenu->set_visible("delete", std::find( aExecVector.begin(), aExecVector.end(), "delete" ) != aExecVector.end());
465  xMenu->set_visible("assign", std::find( aExecVector.begin(), aExecVector.end(), "assign" ) != aExecVector.end());
466  xMenu->set_visible("properties", std::find( aExecVector.begin(), aExecVector.end(), "properties" ) != aExecVector.end());
467 
468  OString sCommand(xMenu->popup_at_rect(mxThemes.get(), tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1))));
469  ImplExecute(sCommand);
470 
471  return true;
472 }
473 
475 {
476  if (maThemeSelectionHandler)
477  maThemeSelectionHandler();
478 }
479 
480 IMPL_LINK_NOARG(GalleryBrowser1, ClickNewThemeHdl, weld::Button&, void)
481 {
482  OUString aNewTheme( SvxResId(RID_SVXSTR_GALLERY_NEWTHEME) );
483  OUString aName( aNewTheme );
484  sal_uInt16 nCount = 0;
485 
486  while( mpGallery->HasTheme( aName ) && ( nCount++ < 16000 ) )
487  {
488  aName = aNewTheme + " " + OUString::number( nCount );
489  }
490 
491  if( !mpGallery->HasTheme( aName ) && mpGallery->CreateTheme( aName ) )
492  {
493  ImplGalleryThemeProperties( aName, true );
494  }
495 }
496 
497 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: galbrws1.cxx:320
bool IsDefault() const
Definition: galtheme.cxx:773
virtual VclPtr< VclAbstractDialog > CreateActualizeProgressDialog(weld::Widget *pParent, GalleryTheme *pThm)=0
#define HID_GALLERY_NEWTHEME
Definition: helpids.h:30
void GrabFocus()
Definition: galbrws1.cxx:315
static SvxAbstractDialogFactory * Create()
Definition: svxdlg.cxx:22
void ImplEndGalleryThemeProperties(bool bCreateNew, sal_Int32 nResult)
Definition: galbrws1.cxx:195
static weld::Builder * CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false)
virtual OUString GetTitle() const =0
#define HID_GALLERY_THEMELIST
Definition: helpids.h:31
void ImplGetExecuteVector(std::vector< OString > &o_aExec)
Definition: galbrws1.cxx:131
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:384
SfxApplication * SfxGetpApp()
bool HasTheme(std::u16string_view rThemeName)
Definition: gallery1.cxx:569
size_t GetThemeCount() const
Definition: gallery1.hxx:123
RET_YES
OUString aImgReadOnly
Definition: galbrws1.hxx:56
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:25
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:595
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
const OUString & GetThemeName() const
Definition: galmisc.hxx:193
bool RemoveTheme(const OUString &rThemeName)
Definition: gallery1.cxx:618
void ImplGalleryThemeProperties(std::u16string_view rThemeName, bool bCreateNew)
Definition: galbrws1.cxx:168
bool IsHidden() const
Definition: gallery1.hxx:69
constexpr sal_uInt16 KEY_R
Gallery * mpGallery
Definition: galbrws1.hxx:50
GalleryHintType GetType() const
Definition: galmisc.hxx:192
void EndNewThemePropertiesDlgHdl(sal_Int32 nResult)
Definition: galbrws1.cxx:230
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:43
OUString GetSelectedTheme() const
Definition: galbrws1.hxx:88
SAL_DLLPRIVATE sal_uInt32 GetObjectCount() const
Definition: galtheme.hxx:84
GalleryBrowser1(weld::Builder &rBuilder, Gallery *pGallery, const ::std::function< void()> &rThemeSelectionHandler)
Definition: galbrws1.cxx:45
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:46
bool IsDefault() const
Definition: gallery1.cxx:718
DateTime getModificationDate() const
Definition: galtheme.cxx:634
void EndThemePropertiesDlgHdl(sal_Int32 nResult)
Definition: galbrws1.cxx:235
virtual sal_uInt32 GetId() const =0
OUString aImgNormal
Definition: galbrws1.hxx:54
const OUString & GetStringData() const
Definition: galmisc.hxx:194
Date aThemeChangeDate
Definition: galmisc.hxx:45
void ReleaseTheme(GalleryTheme *pTheme, SfxListener &rListener)
Definition: gallery1.cxx:707
static void ImplFillExchangeData(const GalleryTheme *pThm, ExchangeData &rData)
Definition: galbrws1.cxx:108
virtual void grab_focus()=0
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:376
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:240
std::unique_ptr< weld::Button > mxNewTheme
Definition: galbrws1.hxx:47
weld::Widget * GetInitialFocusWidget()
Definition: galbrws1.cxx:307
void ImplInsertThemeEntry(const GalleryThemeEntry *pEntry)
Definition: galbrws1.cxx:89
SAL_DLLPRIVATE void SetId(sal_uInt32 nNewId, bool bResetThemeName)
Definition: galtheme.cxx:771
constexpr sal_uInt16 KEY_I
const OUString & GetName() const
Definition: galtheme.cxx:775
constexpr sal_uInt16 KEY_DELETE
IMPL_LINK_NOARG(GalleryBrowser1, SelectThemeHdl, weld::TreeView &, void)
Definition: galbrws1.cxx:474
bool IsReadOnly() const
Definition: galtheme.cxx:772
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:693
const OUString & GetThemeName() const
Definition: gallery1.hxx:64
OUString aEditedTitle
Definition: galmisc.hxx:44