Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / svx / source / gallery2 / galbrws1.cxx
blob7054bf0f1aaa05f8c302dc8f644a6997eeec96d4
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 <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>
38 #include <comphelper/dispatchcommand.hxx>
39 #include <comphelper/propertyvalue.hxx>
40 #include <com/sun/star/beans/PropertyValue.hpp>
41 #include <svx/svxdlg.hxx>
42 #include <memory>
43 #include <bitmaps.hlst>
45 using namespace ::com::sun::star;
47 GalleryBrowser1::GalleryBrowser1(
48 weld::Builder& rBuilder,
49 Gallery* pGallery,
50 std::function<void ()> aThemeSelectionHandler)
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))
62 mxNewTheme->set_help_id(HID_GALLERY_NEWTHEME);
63 mxNewTheme->connect_clicked( LINK( this, GalleryBrowser1, ClickNewThemeHdl ) );
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));
72 mxMoreGalleries->connect_clicked(LINK(this, GalleryBrowser1, OnMoreGalleriesClick));
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);
78 StartListening( *mpGallery );
80 for (size_t i = 0, nCount = mpGallery->GetThemeCount(); i < nCount; ++i)
81 ImplInsertThemeEntry( mpGallery->GetThemeInfo( i ) );
84 GalleryBrowser1::~GalleryBrowser1()
86 EndListening( *mpGallery );
87 mpExchangeData.reset();
90 void GalleryBrowser1::ImplInsertThemeEntry( const GalleryThemeEntry* pEntry )
92 static const bool bShowHiddenThemes = ( getenv( "GALLERY_SHOW_HIDDEN_THEMES" ) != nullptr );
94 if( !(pEntry && ( !pEntry->IsHidden() || bShowHiddenThemes )) )
95 return;
97 const OUString* pImage;
99 if( pEntry->IsReadOnly() )
100 pImage = &aImgReadOnly;
101 else if( pEntry->IsDefault() )
102 pImage = &aImgDefault;
103 else
104 pImage = &aImgNormal;
106 mxThemes->append("", pEntry->GetThemeName(), *pImage);
109 void GalleryBrowser1::ImplFillExchangeData( const GalleryTheme* pThm, ExchangeData& rData )
111 rData.pTheme = const_cast<GalleryTheme*>(pThm);
112 rData.aEditedTitle = pThm->GetName();
116 DateTime aDateTime(pThm->getModificationDate());
118 rData.aThemeChangeDate = aDateTime;
119 rData.aThemeChangeTime = aDateTime;
121 catch( const ucb::ContentCreationException& )
124 catch( const uno::RuntimeException& )
127 catch( const uno::Exception& )
132 void GalleryBrowser1::ImplGetExecuteVector(std::vector<OUString>& o_aExec)
134 GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
136 if( !pTheme )
137 return;
139 bool bUpdateAllowed, bRenameAllowed, bRemoveAllowed;
140 static const bool bIdDialog = ( getenv( "GALLERY_ENABLE_ID_DIALOG" ) != nullptr );
142 if( pTheme->IsReadOnly() )
143 bUpdateAllowed = bRenameAllowed = bRemoveAllowed = false;
144 else if( pTheme->IsDefault() )
146 bUpdateAllowed = bRenameAllowed = true;
147 bRemoveAllowed = false;
149 else
150 bUpdateAllowed = bRenameAllowed = bRemoveAllowed = true;
152 if( bUpdateAllowed && pTheme->GetObjectCount() )
153 o_aExec.emplace_back("update");
155 if( bRenameAllowed )
156 o_aExec.emplace_back("rename");
158 if( bRemoveAllowed )
159 o_aExec.emplace_back("delete");
161 if( bIdDialog && !pTheme->IsReadOnly() )
162 o_aExec.emplace_back("assign");
164 o_aExec.emplace_back("properties");
166 mpGallery->ReleaseTheme( pTheme, *this );
169 void GalleryBrowser1::ImplGalleryThemeProperties( std::u16string_view rThemeName, bool bCreateNew )
171 DBG_ASSERT(!mpThemePropsDlgItemSet, "mpThemePropsDlgItemSet already set!");
172 mpThemePropsDlgItemSet.reset(new SfxItemSet( SfxGetpApp()->GetPool() ));
173 GalleryTheme* pTheme = mpGallery->AcquireTheme( rThemeName, *this );
175 ImplFillExchangeData( pTheme, *mpExchangeData );
177 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
178 VclPtr<VclAbstractDialog> xThemePropertiesDialog = pFact->CreateGalleryThemePropertiesDialog(mxThemes.get(), mpExchangeData.get(), mpThemePropsDlgItemSet.get());
180 if ( bCreateNew )
182 xThemePropertiesDialog->StartExecuteAsync([xThemePropertiesDialog, this](sal_Int32 nResult){
183 EndNewThemePropertiesDlgHdl(nResult);
184 xThemePropertiesDialog->disposeOnce();
187 else
189 xThemePropertiesDialog->StartExecuteAsync([xThemePropertiesDialog, this](sal_Int32 nResult){
190 EndThemePropertiesDlgHdl(nResult);
191 xThemePropertiesDialog->disposeOnce();
196 void GalleryBrowser1::ImplEndGalleryThemeProperties(bool bCreateNew, sal_Int32 nRet)
198 if( nRet == RET_OK )
200 OUString aName( mpExchangeData->pTheme->GetName() );
202 if( !mpExchangeData->aEditedTitle.isEmpty() && aName != mpExchangeData->aEditedTitle )
204 OUString aTitle( mpExchangeData->aEditedTitle );
205 sal_uInt16 nCount = 0;
207 while( mpGallery->HasTheme( aTitle ) && ( nCount++ < 16000 ) )
209 aTitle = mpExchangeData->aEditedTitle + " " + OUString::number( nCount );
212 mpGallery->RenameTheme( aName, aTitle );
215 if ( bCreateNew )
217 mxThemes->select_text( mpExchangeData->pTheme->GetName() );
218 SelectThemeHdl( *mxThemes );
222 OUString aThemeName( mpExchangeData->pTheme->GetName() );
223 mpGallery->ReleaseTheme( mpExchangeData->pTheme, *this );
225 if ( bCreateNew && ( nRet != RET_OK ) )
227 mpGallery->RemoveTheme( aThemeName );
231 void GalleryBrowser1::EndNewThemePropertiesDlgHdl(sal_Int32 nResult)
233 ImplEndGalleryThemeProperties(true, nResult);
236 void GalleryBrowser1::EndThemePropertiesDlgHdl(sal_Int32 nResult)
238 ImplEndGalleryThemeProperties(false, nResult);
241 void GalleryBrowser1::ImplExecute(std::u16string_view rIdent)
243 if (rIdent == u"update")
245 GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
247 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
248 ScopedVclPtr<VclAbstractDialog> aActualizeProgress(pFact->CreateActualizeProgressDialog(mxThemes.get(), pTheme));
250 aActualizeProgress->Execute();
251 mpGallery->ReleaseTheme( pTheme, *this );
253 else if (rIdent == u"delete")
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() );
260 else if (rIdent == u"rename")
262 GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
263 const OUString aOldName( pTheme->GetName() );
265 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
266 ScopedVclPtr<AbstractTitleDialog> aDlg(pFact->CreateTitleDialog(mxThemes.get(), aOldName));
268 if( aDlg->Execute() == RET_OK )
270 const OUString aNewName( aDlg->GetTitle() );
272 if( !aNewName.isEmpty() && ( aNewName != aOldName ) )
274 OUString aName( aNewName );
275 sal_uInt16 nCount = 0;
277 while( mpGallery->HasTheme( aName ) && ( nCount++ < 16000 ) )
279 aName = aNewName + " " + OUString::number( nCount );
282 mpGallery->RenameTheme( aOldName, aName );
285 mpGallery->ReleaseTheme( pTheme, *this );
287 else if (rIdent == u"assign")
289 GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
291 if (pTheme && !pTheme->IsReadOnly())
294 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
295 ScopedVclPtr<AbstractGalleryIdDialog> aDlg(pFact->CreateGalleryIdDialog(mxThemes.get(), pTheme));
296 if( aDlg->Execute() == RET_OK )
297 pTheme->SetId( aDlg->GetId(), true );
300 mpGallery->ReleaseTheme( pTheme, *this );
302 else if (rIdent == u"properties")
304 ImplGalleryThemeProperties( GetSelectedTheme(), false );
308 void GalleryBrowser1::Notify( SfxBroadcaster&, const SfxHint& rHint )
310 const GalleryHint& rGalleryHint = static_cast<const GalleryHint&>(rHint);
312 switch( rGalleryHint.GetType() )
314 case GalleryHintType::THEME_CREATED:
315 ImplInsertThemeEntry( mpGallery->GetThemeInfo( rGalleryHint.GetThemeName() ) );
316 break;
318 case GalleryHintType::THEME_RENAMED:
320 const sal_Int32 nCurSelectPos = mxThemes->get_selected_index();
321 const sal_Int32 nRenameEntryPos = mxThemes->find_text( rGalleryHint.GetThemeName() );
323 mxThemes->remove_text( rGalleryHint.GetThemeName() );
324 ImplInsertThemeEntry( mpGallery->GetThemeInfo( rGalleryHint.GetStringData() ) );
326 if( nCurSelectPos == nRenameEntryPos )
328 mxThemes->select_text( rGalleryHint.GetStringData() );
329 SelectThemeHdl( *mxThemes );
332 break;
334 case GalleryHintType::THEME_REMOVED:
336 mxThemes->remove_text( rGalleryHint.GetThemeName() );
338 break;
340 case GalleryHintType::CLOSE_THEME:
342 const sal_Int32 nCurSelectPos = mxThemes->get_selected_index();
343 const sal_Int32 nCloseEntryPos = mxThemes->find_text( rGalleryHint.GetThemeName() );
345 if( nCurSelectPos == nCloseEntryPos )
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);
354 SelectThemeHdl( *mxThemes );
357 break;
359 default:
360 break;
364 IMPL_STATIC_LINK_NOARG( GalleryBrowser1, OnMoreGalleriesClick, weld::Button&, void)
366 css::uno::Sequence<css::beans::PropertyValue> aArgs{
367 comphelper::makePropertyValue("AdditionsTag", OUString("Gallery"))
369 comphelper::dispatchCommand(".uno:AdditionsDialog", aArgs);
372 IMPL_LINK(GalleryBrowser1, KeyInputHdl, const KeyEvent&, rKEvt, bool)
374 bool bRet = false;
376 std::vector<OUString> aExecVector;
377 ImplGetExecuteVector(aExecVector);
378 OUString sExecuteIdent;
379 bool bMod1 = rKEvt.GetKeyCode().IsMod1();
381 switch( rKEvt.GetKeyCode().GetCode() )
383 case KEY_INSERT:
384 ClickNewThemeHdl(*mxNewTheme);
385 break;
387 case KEY_I:
389 if( bMod1 )
390 ClickNewThemeHdl(*mxNewTheme);
392 break;
394 case KEY_U:
396 if( bMod1 )
397 sExecuteIdent = "update";
399 break;
401 case KEY_DELETE:
402 sExecuteIdent = "delete";
403 break;
405 case KEY_D:
407 if( bMod1 )
408 sExecuteIdent = "delete";
410 break;
412 case KEY_R:
414 if( bMod1 )
415 sExecuteIdent = "rename";
417 break;
419 case KEY_RETURN:
421 if( bMod1 )
422 sExecuteIdent = "properties";
424 break;
427 if (!sExecuteIdent.isEmpty() && (std::find( aExecVector.begin(), aExecVector.end(), sExecuteIdent) != aExecVector.end()))
429 ImplExecute(sExecuteIdent);
430 bRet = true;
433 return bRet;
436 IMPL_LINK(GalleryBrowser1, PopupMenuHdl, const CommandEvent&, rCEvt, bool)
438 if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
439 return false;
441 std::vector<OUString> aExecVector;
442 ImplGetExecuteVector(aExecVector);
444 if (aExecVector.empty())
445 return true;
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"));
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());
456 OUString sCommand(xMenu->popup_at_rect(mxThemes.get(), tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1))));
457 ImplExecute(sCommand);
459 return true;
462 IMPL_LINK_NOARG(GalleryBrowser1, SelectThemeHdl, weld::TreeView&, void)
464 if (maThemeSelectionHandler)
465 maThemeSelectionHandler();
468 IMPL_LINK_NOARG(GalleryBrowser1, ClickNewThemeHdl, weld::Button&, void)
470 OUString aNewTheme( SvxResId(RID_SVXSTR_GALLERY_NEWTHEME) );
471 OUString aName( aNewTheme );
472 sal_uInt16 nCount = 0;
474 while( mpGallery->HasTheme( aName ) && ( nCount++ < 16000 ) )
476 aName = aNewTheme + " " + OUString::number( nCount );
479 if( !mpGallery->HasTheme( aName ) && mpGallery->CreateTheme( aName ) )
481 ImplGalleryThemeProperties( aName, true );
485 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */