bump product version to 7.2.5.1
[LibreOffice.git] / svx / source / gallery2 / galbrws1.cxx
blob6d8cc179c53bf979bb2e2f4e7453754a5c9154fc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <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>
37 #include <comphelper/dispatchcommand.hxx>
38 #include <com/sun/star/beans/PropertyValue.hpp>
39 #include <svx/svxdlg.hxx>
40 #include <memory>
41 #include <bitmaps.hlst>
43 using namespace ::com::sun::star;
45 GalleryBrowser1::GalleryBrowser1(
46 weld::Builder& rBuilder,
47 Gallery* pGallery,
48 const std::function<void ()>& rThemeSelectionHandler)
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)
60 mxNewTheme->set_help_id(HID_GALLERY_NEWTHEME);
61 mxNewTheme->connect_clicked( LINK( this, GalleryBrowser1, ClickNewThemeHdl ) );
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));
70 mxMoreGalleries->set_from_icon_name("cmd/sc_additionsdialog.png");
71 mxMoreGalleries->connect_clicked(LINK(this, GalleryBrowser1, OnMoreGalleriesClick));
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);
77 StartListening( *mpGallery );
79 for (size_t i = 0, nCount = mpGallery->GetThemeCount(); i < nCount; ++i)
80 ImplInsertThemeEntry( mpGallery->GetThemeInfo( i ) );
83 GalleryBrowser1::~GalleryBrowser1()
85 EndListening( *mpGallery );
86 mpExchangeData.reset();
89 void GalleryBrowser1::ImplInsertThemeEntry( const GalleryThemeEntry* pEntry )
91 static const bool bShowHiddenThemes = ( getenv( "GALLERY_SHOW_HIDDEN_THEMES" ) != nullptr );
93 if( !(pEntry && ( !pEntry->IsHidden() || bShowHiddenThemes )) )
94 return;
96 const OUString* pImage;
98 if( pEntry->IsReadOnly() )
99 pImage = &aImgReadOnly;
100 else if( pEntry->IsDefault() )
101 pImage = &aImgDefault;
102 else
103 pImage = &aImgNormal;
105 mxThemes->append("", pEntry->GetThemeName(), *pImage);
108 void GalleryBrowser1::ImplFillExchangeData( const GalleryTheme* pThm, ExchangeData& rData )
110 rData.pTheme = const_cast<GalleryTheme*>(pThm);
111 rData.aEditedTitle = pThm->GetName();
115 DateTime aDateTime(pThm->getModificationDate());
117 rData.aThemeChangeDate = aDateTime;
118 rData.aThemeChangeTime = aDateTime;
120 catch( const ucb::ContentCreationException& )
123 catch( const uno::RuntimeException& )
126 catch( const uno::Exception& )
131 void GalleryBrowser1::ImplGetExecuteVector(std::vector<OString>& o_aExec)
133 GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
135 if( !pTheme )
136 return;
138 bool bUpdateAllowed, bRenameAllowed, bRemoveAllowed;
139 static const bool bIdDialog = ( getenv( "GALLERY_ENABLE_ID_DIALOG" ) != nullptr );
141 if( pTheme->IsReadOnly() )
142 bUpdateAllowed = bRenameAllowed = bRemoveAllowed = false;
143 else if( pTheme->IsDefault() )
145 bUpdateAllowed = bRenameAllowed = true;
146 bRemoveAllowed = false;
148 else
149 bUpdateAllowed = bRenameAllowed = bRemoveAllowed = true;
151 if( bUpdateAllowed && pTheme->GetObjectCount() )
152 o_aExec.emplace_back("update");
154 if( bRenameAllowed )
155 o_aExec.emplace_back("rename");
157 if( bRemoveAllowed )
158 o_aExec.emplace_back("delete");
160 if( bIdDialog && !pTheme->IsReadOnly() )
161 o_aExec.emplace_back("assign");
163 o_aExec.emplace_back("properties");
165 mpGallery->ReleaseTheme( pTheme, *this );
168 void GalleryBrowser1::ImplGalleryThemeProperties( std::u16string_view rThemeName, bool bCreateNew )
170 DBG_ASSERT(!mpThemePropsDlgItemSet, "mpThemePropsDlgItemSet already set!");
171 mpThemePropsDlgItemSet.reset(new SfxItemSet( SfxGetpApp()->GetPool() ));
172 GalleryTheme* pTheme = mpGallery->AcquireTheme( rThemeName, *this );
174 ImplFillExchangeData( pTheme, *mpExchangeData );
176 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
177 VclPtr<VclAbstractDialog> xThemePropertiesDialog = pFact->CreateGalleryThemePropertiesDialog(mxThemes.get(), mpExchangeData.get(), mpThemePropsDlgItemSet.get());
179 if ( bCreateNew )
181 xThemePropertiesDialog->StartExecuteAsync([xThemePropertiesDialog, this](sal_Int32 nResult){
182 EndNewThemePropertiesDlgHdl(nResult);
183 xThemePropertiesDialog->disposeOnce();
186 else
188 xThemePropertiesDialog->StartExecuteAsync([xThemePropertiesDialog, this](sal_Int32 nResult){
189 EndThemePropertiesDlgHdl(nResult);
190 xThemePropertiesDialog->disposeOnce();
195 void GalleryBrowser1::ImplEndGalleryThemeProperties(bool bCreateNew, sal_Int32 nRet)
197 if( nRet == RET_OK )
199 OUString aName( mpExchangeData->pTheme->GetName() );
201 if( !mpExchangeData->aEditedTitle.isEmpty() && aName != mpExchangeData->aEditedTitle )
203 OUString aTitle( mpExchangeData->aEditedTitle );
204 sal_uInt16 nCount = 0;
206 while( mpGallery->HasTheme( aTitle ) && ( nCount++ < 16000 ) )
208 aTitle = mpExchangeData->aEditedTitle + " " + OUString::number( nCount );
211 mpGallery->RenameTheme( aName, aTitle );
214 if ( bCreateNew )
216 mxThemes->select_text( mpExchangeData->pTheme->GetName() );
217 SelectThemeHdl( *mxThemes );
221 OUString aThemeName( mpExchangeData->pTheme->GetName() );
222 mpGallery->ReleaseTheme( mpExchangeData->pTheme, *this );
224 if ( bCreateNew && ( nRet != RET_OK ) )
226 mpGallery->RemoveTheme( aThemeName );
230 void GalleryBrowser1::EndNewThemePropertiesDlgHdl(sal_Int32 nResult)
232 ImplEndGalleryThemeProperties(true, nResult);
235 void GalleryBrowser1::EndThemePropertiesDlgHdl(sal_Int32 nResult)
237 ImplEndGalleryThemeProperties(false, nResult);
240 void GalleryBrowser1::ImplExecute(std::string_view rIdent)
242 if (rIdent == "update")
244 GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
246 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
247 ScopedVclPtr<VclAbstractDialog> aActualizeProgress(pFact->CreateActualizeProgressDialog(mxThemes.get(), pTheme));
249 aActualizeProgress->Execute();
250 mpGallery->ReleaseTheme( pTheme, *this );
252 else if (rIdent == "delete")
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() );
259 else if (rIdent == "rename")
261 GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
262 const OUString aOldName( pTheme->GetName() );
264 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
265 ScopedVclPtr<AbstractTitleDialog> aDlg(pFact->CreateTitleDialog(mxThemes.get(), aOldName));
267 if( aDlg->Execute() == RET_OK )
269 const OUString aNewName( aDlg->GetTitle() );
271 if( !aNewName.isEmpty() && ( aNewName != aOldName ) )
273 OUString aName( aNewName );
274 sal_uInt16 nCount = 0;
276 while( mpGallery->HasTheme( aName ) && ( nCount++ < 16000 ) )
278 aName = aNewName + " " + OUString::number( nCount );
281 mpGallery->RenameTheme( aOldName, aName );
284 mpGallery->ReleaseTheme( pTheme, *this );
286 else if (rIdent == "assign")
288 GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
290 if (pTheme && !pTheme->IsReadOnly())
293 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
294 ScopedVclPtr<AbstractGalleryIdDialog> aDlg(pFact->CreateGalleryIdDialog(mxThemes.get(), pTheme));
295 if( aDlg->Execute() == RET_OK )
296 pTheme->SetId( aDlg->GetId(), true );
299 mpGallery->ReleaseTheme( pTheme, *this );
301 else if (rIdent == "properties")
303 ImplGalleryThemeProperties( GetSelectedTheme(), false );
307 void GalleryBrowser1::Notify( SfxBroadcaster&, const SfxHint& rHint )
309 const GalleryHint& rGalleryHint = static_cast<const GalleryHint&>(rHint);
311 switch( rGalleryHint.GetType() )
313 case GalleryHintType::THEME_CREATED:
314 ImplInsertThemeEntry( mpGallery->GetThemeInfo( rGalleryHint.GetThemeName() ) );
315 break;
317 case GalleryHintType::THEME_RENAMED:
319 const sal_Int32 nCurSelectPos = mxThemes->get_selected_index();
320 const sal_Int32 nRenameEntryPos = mxThemes->find_text( rGalleryHint.GetThemeName() );
322 mxThemes->remove_text( rGalleryHint.GetThemeName() );
323 ImplInsertThemeEntry( mpGallery->GetThemeInfo( rGalleryHint.GetStringData() ) );
325 if( nCurSelectPos == nRenameEntryPos )
327 mxThemes->select_text( rGalleryHint.GetStringData() );
328 SelectThemeHdl( *mxThemes );
331 break;
333 case GalleryHintType::THEME_REMOVED:
335 mxThemes->remove_text( rGalleryHint.GetThemeName() );
337 break;
339 case GalleryHintType::CLOSE_THEME:
341 const sal_Int32 nCurSelectPos = mxThemes->get_selected_index();
342 const sal_Int32 nCloseEntryPos = mxThemes->find_text( rGalleryHint.GetThemeName() );
344 if( nCurSelectPos == nCloseEntryPos )
346 if( nCurSelectPos < ( mxThemes->n_children() - 1 ) )
347 mxThemes->select( nCurSelectPos + 1 );
348 else if( nCurSelectPos )
349 mxThemes->select( nCurSelectPos - 1 );
350 else
351 mxThemes->select(-1);
353 SelectThemeHdl( *mxThemes );
356 break;
358 default:
359 break;
363 IMPL_STATIC_LINK_NOARG( GalleryBrowser1, OnMoreGalleriesClick, weld::Button&, void)
365 css::uno::Sequence<css::beans::PropertyValue> aArgs(1);
366 aArgs[0].Name = "AdditionsTag";
367 aArgs[0].Value <<= OUString("Gallery");
368 comphelper::dispatchCommand(".uno:AdditionsDialog", aArgs);
371 IMPL_LINK(GalleryBrowser1, KeyInputHdl, const KeyEvent&, rKEvt, bool)
373 bool bRet = false;
375 std::vector<OString> aExecVector;
376 ImplGetExecuteVector(aExecVector);
377 OString sExecuteIdent;
378 bool bMod1 = rKEvt.GetKeyCode().IsMod1();
380 switch( rKEvt.GetKeyCode().GetCode() )
382 case KEY_INSERT:
383 ClickNewThemeHdl(*mxNewTheme);
384 break;
386 case KEY_I:
388 if( bMod1 )
389 ClickNewThemeHdl(*mxNewTheme);
391 break;
393 case KEY_U:
395 if( bMod1 )
396 sExecuteIdent = "update";
398 break;
400 case KEY_DELETE:
401 sExecuteIdent = "delete";
402 break;
404 case KEY_D:
406 if( bMod1 )
407 sExecuteIdent = "delete";
409 break;
411 case KEY_R:
413 if( bMod1 )
414 sExecuteIdent = "rename";
416 break;
418 case KEY_RETURN:
420 if( bMod1 )
421 sExecuteIdent = "properties";
423 break;
426 if (!sExecuteIdent.isEmpty() && (std::find( aExecVector.begin(), aExecVector.end(), sExecuteIdent) != aExecVector.end()))
428 ImplExecute(sExecuteIdent);
429 bRet = true;
432 return bRet;
435 IMPL_LINK(GalleryBrowser1, PopupMenuHdl, const CommandEvent&, rCEvt, bool)
437 if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
438 return false;
440 std::vector<OString> aExecVector;
441 ImplGetExecuteVector(aExecVector);
443 if (aExecVector.empty())
444 return true;
446 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(mxThemes.get(), "svx/ui/gallerymenu1.ui"));
447 std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu("menu"));
449 xMenu->set_visible("update", std::find( aExecVector.begin(), aExecVector.end(), "update" ) != aExecVector.end());
450 xMenu->set_visible("rename", std::find( aExecVector.begin(), aExecVector.end(), "rename" ) != aExecVector.end());
451 xMenu->set_visible("delete", std::find( aExecVector.begin(), aExecVector.end(), "delete" ) != aExecVector.end());
452 xMenu->set_visible("assign", std::find( aExecVector.begin(), aExecVector.end(), "assign" ) != aExecVector.end());
453 xMenu->set_visible("properties", std::find( aExecVector.begin(), aExecVector.end(), "properties" ) != aExecVector.end());
455 OString sCommand(xMenu->popup_at_rect(mxThemes.get(), tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1))));
456 ImplExecute(sCommand);
458 return true;
461 IMPL_LINK_NOARG(GalleryBrowser1, SelectThemeHdl, weld::TreeView&, void)
463 if (maThemeSelectionHandler)
464 maThemeSelectionHandler();
467 IMPL_LINK_NOARG(GalleryBrowser1, ClickNewThemeHdl, weld::Button&, void)
469 OUString aNewTheme( SvxResId(RID_SVXSTR_GALLERY_NEWTHEME) );
470 OUString aName( aNewTheme );
471 sal_uInt16 nCount = 0;
473 while( mpGallery->HasTheme( aName ) && ( nCount++ < 16000 ) )
475 aName = aNewTheme + " " + OUString::number( nCount );
478 if( !mpGallery->HasTheme( aName ) && mpGallery->CreateTheme( aName ) )
480 ImplGalleryThemeProperties( aName, true );
484 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */