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 <comphelper/processfactory.hxx>
23 #include <tools/datetime.hxx>
24 #include <unotools/datetime.hxx>
25 #include <vcl/commandevent.hxx>
26 #include <vcl/event.hxx>
27 #include <vcl/settings.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/weld.hxx>
30 #include <ucbhelper/content.hxx>
31 #include <com/sun/star/ucb/ContentCreationException.hpp>
32 #include <sfx2/app.hxx>
33 #include <helpids.h>
34 #include <svx/gallery1.hxx>
35 #include <svx/galtheme.hxx>
36 #include <svx/galmisc.hxx>
37 #include "galbrws1.hxx"
38 #include <com/sun/star/util/DateTime.hpp>
39 #include <svx/strings.hrc>
40 #include <algorithm>
41 #include <svx/dialmgr.hxx>
42 
43 #include <svx/svxdlg.hxx>
44 #include <memory>
45 #include <bitmaps.hlst>
46 
47 using namespace ::com::sun::star;
48 
49 
GalleryButton(GalleryBrowser1 * pParent,WinBits nWinBits)50 GalleryButton::GalleryButton( GalleryBrowser1* pParent, WinBits nWinBits ) :
51     PushButton( pParent, nWinBits )
52 {
53 }
54 
KeyInput(const KeyEvent & rKEvt)55 void GalleryButton::KeyInput( const KeyEvent& rKEvt )
56 {
57     if( !static_cast< GalleryBrowser1* >( GetParent() )->KeyInput( rKEvt, this ) )
58         PushButton::KeyInput( rKEvt );
59 }
60 
61 
GalleryThemeListBox(GalleryBrowser1 * pParent,WinBits nWinBits)62 GalleryThemeListBox::GalleryThemeListBox( GalleryBrowser1* pParent, WinBits nWinBits ) :
63     ListBox( pParent, nWinBits )
64 {
65     InitSettings();
66 }
67 
InitSettings()68 void GalleryThemeListBox::InitSettings()
69 {
70     SetBackground( Wallpaper( GALLERY_BG_COLOR ) );
71     SetControlBackground( GALLERY_BG_COLOR );
72     SetControlForeground( GALLERY_FG_COLOR );
73 }
74 
DataChanged(const DataChangedEvent & rDCEvt)75 void GalleryThemeListBox::DataChanged( const DataChangedEvent& rDCEvt )
76 {
77     if ( ( rDCEvt.GetType() == DataChangedEventType::SETTINGS ) && ( rDCEvt.GetFlags() & AllSettingsFlags::STYLE ) )
78         InitSettings();
79     else
80         ListBox::DataChanged( rDCEvt );
81 }
82 
PreNotify(NotifyEvent & rNEvt)83 bool GalleryThemeListBox::PreNotify( NotifyEvent& rNEvt )
84 {
85     bool bDone = false;
86 
87     if( rNEvt.GetType() == MouseNotifyEvent::COMMAND )
88     {
89         const CommandEvent* pCEvt = rNEvt.GetCommandEvent();
90 
91         if( pCEvt && pCEvt->GetCommand() == CommandEventId::ContextMenu )
92             static_cast< GalleryBrowser1* >( GetParent() )->ShowContextMenu();
93     }
94     else if( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
95     {
96         const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
97 
98         if( pKEvt )
99             bDone = static_cast< GalleryBrowser1* >( GetParent() )->KeyInput( *pKEvt, this );
100     }
101 
102     return( bDone || ListBox::PreNotify( rNEvt ) );
103 }
104 
105 
GalleryBrowser1(vcl::Window * pParent,Gallery * pGallery,const std::function<sal_Bool (const KeyEvent &,Window *)> & rKeyInputHandler,const std::function<void ()> & rThemeSlectionHandler)106 GalleryBrowser1::GalleryBrowser1(
107     vcl::Window* pParent,
108     Gallery* pGallery,
109     const std::function<sal_Bool (const KeyEvent&,Window*)>& rKeyInputHandler,
110     const std::function<void ()>& rThemeSlectionHandler)
111     :
112     Control               ( pParent, WB_TABSTOP ),
113     maNewTheme            ( VclPtr<GalleryButton>::Create(this, WB_3DLOOK) ),
114     mpThemes              ( VclPtr<GalleryThemeListBox>::Create( this, WB_TABSTOP | WB_3DLOOK | WB_BORDER | WB_HSCROLL | WB_VSCROLL | WB_AUTOHSCROLL | WB_SORT ) ),
115     mpGallery             ( pGallery ),
116     mpExchangeData        ( new ExchangeData ),
117     aImgNormal            ( GalleryResGetBitmapEx( RID_SVXBMP_THEME_NORMAL ) ),
118     aImgDefault           ( GalleryResGetBitmapEx( RID_SVXBMP_THEME_DEFAULT ) ),
119     aImgReadOnly          ( GalleryResGetBitmapEx( RID_SVXBMP_THEME_READONLY ) ),
120     maKeyInputHandler(rKeyInputHandler),
121     maThemeSlectionHandler(rThemeSlectionHandler)
122 {
123     StartListening( *mpGallery );
124 
125     maNewTheme->SetHelpId( HID_GALLERY_NEWTHEME );
126     maNewTheme->SetText( SvxResId(RID_SVXSTR_GALLERY_CREATETHEME));
127     maNewTheme->SetClickHdl( LINK( this, GalleryBrowser1, ClickNewThemeHdl ) );
128 
129     // disable creation of new themes if a writable directory is not available
130     if( mpGallery->GetUserURL().GetProtocol() == INetProtocol::NotValid )
131         maNewTheme->Disable();
132 
133     mpThemes->SetHelpId( HID_GALLERY_THEMELIST );
134     mpThemes->SetSelectHdl( LINK( this, GalleryBrowser1, SelectThemeHdl ) );
135     mpThemes->SetAccessibleName(SvxResId(RID_SVXSTR_GALLERYPROPS_GALTHEME));
136 
137     for( sal_uIntPtr i = 0, nCount = mpGallery->GetThemeCount(); i < nCount; i++ )
138         ImplInsertThemeEntry( mpGallery->GetThemeInfo( i ) );
139 
140     ImplAdjustControls();
141     maNewTheme->Show();
142     mpThemes->Show();
143 }
144 
~GalleryBrowser1()145 GalleryBrowser1::~GalleryBrowser1()
146 {
147     disposeOnce();
148 }
149 
dispose()150 void GalleryBrowser1::dispose()
151 {
152     EndListening( *mpGallery );
153     mpThemePropertiesDialog.clear();
154     mpThemes.disposeAndClear();
155     mpExchangeData.reset();
156     maNewTheme.disposeAndClear();
157     Control::dispose();
158 }
159 
ImplInsertThemeEntry(const GalleryThemeEntry * pEntry)160 sal_uIntPtr GalleryBrowser1::ImplInsertThemeEntry( const GalleryThemeEntry* pEntry )
161 {
162     static const bool bShowHiddenThemes = ( getenv( "GALLERY_SHOW_HIDDEN_THEMES" ) != nullptr );
163 
164     sal_uIntPtr nRet = LISTBOX_ENTRY_NOTFOUND;
165 
166     if( pEntry && ( !pEntry->IsHidden() || bShowHiddenThemes ) )
167     {
168         const Image* pImage;
169 
170         if( pEntry->IsReadOnly() )
171             pImage = &aImgReadOnly;
172         else if( pEntry->IsDefault() )
173             pImage = &aImgDefault;
174         else
175             pImage = &aImgNormal;
176 
177         nRet = mpThemes->InsertEntry( pEntry->GetThemeName(), *pImage );
178     }
179 
180     return nRet;
181 }
182 
ImplAdjustControls()183 void GalleryBrowser1::ImplAdjustControls()
184 {
185     const Size  aOutSize( GetOutputSizePixel() );
186     const long  nNewThemeHeight = LogicToPixel(Size(0, 14), MapMode(MapUnit::MapAppFont)).Height();
187     const long  nStartY = nNewThemeHeight + 4;
188 
189     maNewTheme->SetPosSizePixel( Point(),
190                                 Size( aOutSize.Width(), nNewThemeHeight ) );
191 
192     mpThemes->SetPosSizePixel( Point( 0, nStartY ),
193                                Size( aOutSize.Width(), aOutSize.Height() - nStartY ) );
194 }
195 
ImplFillExchangeData(const GalleryTheme * pThm,ExchangeData & rData)196 void GalleryBrowser1::ImplFillExchangeData( const GalleryTheme* pThm, ExchangeData& rData )
197 {
198     rData.pTheme = const_cast<GalleryTheme*>(pThm);
199     rData.aEditedTitle = pThm->GetName();
200 
201     try
202     {
203         ::ucbhelper::Content aCnt( pThm->GetThmURL().GetMainURL( INetURLObject::DecodeMechanism::NONE ), uno::Reference< ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
204         util::DateTime  aDateTimeModified;
205         DateTime        aDateTime( DateTime::EMPTY );
206 
207         aCnt.getPropertyValue("DateModified") >>= aDateTimeModified;
208         ::utl::typeConvert( aDateTimeModified, aDateTime );
209         rData.aThemeChangeDate = aDateTime;
210         rData.aThemeChangeTime = aDateTime;
211     }
212     catch( const ucb::ContentCreationException& )
213     {
214     }
215     catch( const uno::RuntimeException& )
216     {
217     }
218     catch( const uno::Exception& )
219     {
220     }
221 }
222 
ImplGetExecuteVector(std::vector<OString> & o_aExec)223 void GalleryBrowser1::ImplGetExecuteVector(std::vector<OString>& o_aExec)
224 {
225     GalleryTheme*           pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
226 
227     if( pTheme )
228     {
229         bool                bUpdateAllowed, bRenameAllowed, bRemoveAllowed;
230         static const bool   bIdDialog = ( getenv( "GALLERY_ENABLE_ID_DIALOG" ) != nullptr );
231 
232         if( pTheme->IsReadOnly() )
233             bUpdateAllowed = bRenameAllowed = bRemoveAllowed = false;
234         else if( pTheme->IsDefault() )
235         {
236             bUpdateAllowed = bRenameAllowed = true;
237             bRemoveAllowed = false;
238         }
239         else
240             bUpdateAllowed = bRenameAllowed = bRemoveAllowed = true;
241 
242         if( bUpdateAllowed && pTheme->GetObjectCount() )
243             o_aExec.emplace_back("update");
244 
245         if( bRenameAllowed )
246             o_aExec.emplace_back("rename");
247 
248         if( bRemoveAllowed )
249             o_aExec.emplace_back("delete");
250 
251         if( bIdDialog && !pTheme->IsReadOnly() )
252             o_aExec.emplace_back("assign");
253 
254         o_aExec.emplace_back("properties");
255 
256         mpGallery->ReleaseTheme( pTheme, *this );
257     }
258 }
259 
ImplGalleryThemeProperties(const OUString & rThemeName,bool bCreateNew)260 void GalleryBrowser1::ImplGalleryThemeProperties( const OUString & rThemeName, bool bCreateNew )
261 {
262     DBG_ASSERT(!mpThemePropsDlgItemSet, "mpThemePropsDlgItemSet already set!");
263     mpThemePropsDlgItemSet.reset(new SfxItemSet( SfxGetpApp()->GetPool() ));
264     GalleryTheme*   pTheme = mpGallery->AcquireTheme( rThemeName, *this );
265 
266     ImplFillExchangeData( pTheme, *mpExchangeData );
267 
268     SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
269     mpThemePropertiesDialog = pFact->CreateGalleryThemePropertiesDialog(GetFrameWeld(), mpExchangeData.get(), mpThemePropsDlgItemSet.get());
270 
271     if ( bCreateNew )
272     {
273         mpThemePropertiesDialog->StartExecuteAsync([this](sal_Int32 nResult){
274             EndNewThemePropertiesDlgHdl(nResult);
275         });
276     }
277     else
278     {
279         mpThemePropertiesDialog->StartExecuteAsync([this](sal_Int32 nResult){
280             EndThemePropertiesDlgHdl(nResult);
281         });
282     }
283 }
284 
ImplEndGalleryThemeProperties(bool bCreateNew,sal_Int32 nRet)285 void GalleryBrowser1::ImplEndGalleryThemeProperties(bool bCreateNew, sal_Int32 nRet)
286 {
287     if( nRet == RET_OK )
288     {
289         OUString aName( mpExchangeData->pTheme->GetName() );
290 
291         if( !mpExchangeData->aEditedTitle.isEmpty() && aName != mpExchangeData->aEditedTitle )
292         {
293             OUString            aTitle( mpExchangeData->aEditedTitle );
294             sal_uInt16          nCount = 0;
295 
296             while( mpGallery->HasTheme( aTitle ) && ( nCount++ < 16000 ) )
297             {
298                 aTitle = mpExchangeData->aEditedTitle + " " + OUString::number( nCount );
299             }
300 
301             mpGallery->RenameTheme( aName, aTitle );
302         }
303 
304         if ( bCreateNew )
305         {
306             mpThemes->SelectEntry( mpExchangeData->pTheme->GetName() );
307             SelectThemeHdl( *mpThemes );
308         }
309     }
310 
311     OUString aThemeName( mpExchangeData->pTheme->GetName() );
312     mpGallery->ReleaseTheme( mpExchangeData->pTheme, *this );
313 
314     if ( bCreateNew && ( nRet != RET_OK ) )
315     {
316         mpGallery->RemoveTheme( aThemeName );
317     }
318 
319     // destroy mpThemeProps asynchronously
320     Application::PostUserEvent( LINK( this, GalleryBrowser1, DestroyThemePropertiesDlgHdl ), nullptr, true );
321 }
322 
EndNewThemePropertiesDlgHdl(sal_Int32 nResult)323 void GalleryBrowser1::EndNewThemePropertiesDlgHdl(sal_Int32 nResult)
324 {
325     ImplEndGalleryThemeProperties(true, nResult);
326 }
327 
EndThemePropertiesDlgHdl(sal_Int32 nResult)328 void GalleryBrowser1::EndThemePropertiesDlgHdl(sal_Int32 nResult)
329 {
330     ImplEndGalleryThemeProperties(false, nResult);
331 }
332 
333 IMPL_LINK( GalleryBrowser1, DestroyThemePropertiesDlgHdl, void*, /*p*/, void )
334 {
335     mpThemePropertiesDialog.disposeAndClear();
336     mpThemePropsDlgItemSet.reset();
337 }
338 
ImplExecute(const OString & rIdent)339 void GalleryBrowser1::ImplExecute(const OString &rIdent)
340 {
341     if (rIdent == "update")
342     {
343         GalleryTheme*       pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
344 
345         SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
346         ScopedVclPtr<VclAbstractDialog> aActualizeProgress(pFact->CreateActualizeProgressDialog(GetFrameWeld(), pTheme));
347 
348         aActualizeProgress->Execute();
349         mpGallery->ReleaseTheme( pTheme, *this );
350     }
351     else if (rIdent == "delete")
352     {
353         std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "svx/ui/querydeletethemedialog.ui"));
354         std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("QueryDeleteThemeDialog"));
355         if (xQuery->run() == RET_YES)
356             mpGallery->RemoveTheme( mpThemes->GetSelectedEntry() );
357     }
358     else if (rIdent == "rename")
359     {
360         GalleryTheme*   pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
361         const OUString  aOldName( pTheme->GetName() );
362 
363         SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
364         ScopedVclPtr<AbstractTitleDialog> aDlg(pFact->CreateTitleDialog(GetFrameWeld(), aOldName));
365 
366         if( aDlg->Execute() == RET_OK )
367         {
368             const OUString aNewName( aDlg->GetTitle() );
369 
370             if( !aNewName.isEmpty() && ( aNewName != aOldName ) )
371             {
372                 OUString  aName( aNewName );
373                 sal_uInt16  nCount = 0;
374 
375                 while( mpGallery->HasTheme( aName ) && ( nCount++ < 16000 ) )
376                 {
377                     aName = aNewName + " " + OUString::number( nCount );
378                 }
379 
380                 mpGallery->RenameTheme( aOldName, aName );
381             }
382         }
383         mpGallery->ReleaseTheme( pTheme, *this );
384     }
385     else if (rIdent == "assign")
386     {
387         GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
388 
389         if (pTheme && !pTheme->IsReadOnly())
390         {
391 
392             SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
393             ScopedVclPtr<AbstractGalleryIdDialog> aDlg(pFact->CreateGalleryIdDialog(GetFrameWeld(), pTheme));
394             if( aDlg->Execute() == RET_OK )
395                 pTheme->SetId( aDlg->GetId(), true );
396         }
397 
398         mpGallery->ReleaseTheme( pTheme, *this );
399     }
400     else if (rIdent == "properties")
401     {
402         ImplGalleryThemeProperties( GetSelectedTheme(), false );
403     }
404 }
405 
Resize()406 void GalleryBrowser1::Resize()
407 {
408     Control::Resize();
409     ImplAdjustControls();
410 }
411 
GetFocus()412 void GalleryBrowser1::GetFocus()
413 {
414     Control::GetFocus();
415     if( maNewTheme->IsEnabled() )
416         maNewTheme->GrabFocus();
417     else
418         mpThemes->GrabFocus();
419 }
420 
Notify(SfxBroadcaster &,const SfxHint & rHint)421 void GalleryBrowser1::Notify( SfxBroadcaster&, const SfxHint& rHint )
422 {
423     const GalleryHint& rGalleryHint = static_cast<const GalleryHint&>(rHint);
424 
425     switch( rGalleryHint.GetType() )
426     {
427         case GalleryHintType::THEME_CREATED:
428             ImplInsertThemeEntry( mpGallery->GetThemeInfo( rGalleryHint.GetThemeName() ) );
429         break;
430 
431         case GalleryHintType::THEME_RENAMED:
432         {
433             const sal_Int32 nCurSelectPos = mpThemes->GetSelectedEntryPos();
434             const sal_Int32 nRenameEntryPos = mpThemes->GetEntryPos( rGalleryHint.GetThemeName() );
435 
436             mpThemes->RemoveEntry( rGalleryHint.GetThemeName() );
437             ImplInsertThemeEntry( mpGallery->GetThemeInfo( rGalleryHint.GetStringData() ) );
438 
439             if( nCurSelectPos == nRenameEntryPos )
440             {
441                 mpThemes->SelectEntry( rGalleryHint.GetStringData() );
442                 SelectThemeHdl( *mpThemes );
443             }
444         }
445         break;
446 
447         case GalleryHintType::THEME_REMOVED:
448         {
449             mpThemes->RemoveEntry( rGalleryHint.GetThemeName() );
450         }
451         break;
452 
453         case GalleryHintType::CLOSE_THEME:
454         {
455             const sal_Int32 nCurSelectPos = mpThemes->GetSelectedEntryPos();
456             const sal_Int32 nCloseEntryPos = mpThemes->GetEntryPos( rGalleryHint.GetThemeName() );
457 
458             if( nCurSelectPos == nCloseEntryPos )
459             {
460                 if( nCurSelectPos < ( mpThemes->GetEntryCount() - 1 ) )
461                     mpThemes->SelectEntryPos( nCurSelectPos + 1 );
462                 else if( nCurSelectPos )
463                     mpThemes->SelectEntryPos( nCurSelectPos - 1 );
464                 else
465                     mpThemes->SetNoSelection();
466 
467                 SelectThemeHdl( *mpThemes );
468             }
469         }
470         break;
471 
472         default:
473         break;
474     }
475 }
476 
ShowContextMenu()477 void GalleryBrowser1::ShowContextMenu()
478 {
479     Application::PostUserEvent( LINK( this, GalleryBrowser1, ShowContextMenuHdl ), this, true );
480 }
481 
KeyInput(const KeyEvent & rKEvt,vcl::Window * pWindow)482 bool GalleryBrowser1::KeyInput( const KeyEvent& rKEvt, vcl::Window* pWindow )
483 {
484     bool bRet = false;
485     if (maKeyInputHandler)
486         bRet = maKeyInputHandler(rKEvt, pWindow);
487 
488     if( !bRet )
489     {
490         std::vector<OString> aExecVector;
491         ImplGetExecuteVector(aExecVector);
492         OString sExecuteIdent;
493         bool bMod1 = rKEvt.GetKeyCode().IsMod1();
494 
495         switch( rKEvt.GetKeyCode().GetCode() )
496         {
497             case KEY_INSERT:
498                 ClickNewThemeHdl( nullptr );
499             break;
500 
501             case KEY_I:
502             {
503                 if( bMod1 )
504                    ClickNewThemeHdl( nullptr );
505             }
506             break;
507 
508             case KEY_U:
509             {
510                 if( bMod1 )
511                     sExecuteIdent = "update";
512             }
513             break;
514 
515             case KEY_DELETE:
516                 sExecuteIdent = "delete";
517             break;
518 
519             case KEY_D:
520             {
521                 if( bMod1 )
522                     sExecuteIdent = "delete";
523             }
524             break;
525 
526             case KEY_R:
527             {
528                 if( bMod1 )
529                     sExecuteIdent = "rename";
530             }
531             break;
532 
533             case KEY_RETURN:
534             {
535                 if( bMod1 )
536                     sExecuteIdent = "properties";
537             }
538             break;
539         }
540 
541         if (!sExecuteIdent.isEmpty() && (std::find( aExecVector.begin(), aExecVector.end(), sExecuteIdent) != aExecVector.end()))
542         {
543             ImplExecute(sExecuteIdent);
544             bRet = true;
545         }
546     }
547 
548     return bRet;
549 }
550 
IMPL_LINK_NOARG(GalleryBrowser1,ShowContextMenuHdl,void *,void)551 IMPL_LINK_NOARG(GalleryBrowser1, ShowContextMenuHdl, void*, void)
552 {
553     std::vector<OString> aExecVector;
554     ImplGetExecuteVector(aExecVector);
555 
556     if( aExecVector.empty() )
557         return;
558 
559     VclBuilder aBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "svx/ui/gallerymenu1.ui", "");
560     VclPtr<PopupMenu> aMenu(aBuilder.get_menu("menu"));
561 
562     aMenu->EnableItem( aMenu->GetItemId("update"), std::find( aExecVector.begin(), aExecVector.end(), "update" ) != aExecVector.end() );
563     aMenu->EnableItem( aMenu->GetItemId("rename"), std::find( aExecVector.begin(), aExecVector.end(), "rename" ) != aExecVector.end() );
564     aMenu->EnableItem( aMenu->GetItemId("delete"), std::find( aExecVector.begin(), aExecVector.end(), "delete" ) != aExecVector.end() );
565     aMenu->EnableItem( aMenu->GetItemId("assign"), std::find( aExecVector.begin(), aExecVector.end(), "assign" ) != aExecVector.end() );
566     aMenu->EnableItem( aMenu->GetItemId("properties"), std::find( aExecVector.begin(), aExecVector.end(), "properties" ) != aExecVector.end() );
567     aMenu->SetSelectHdl( LINK( this, GalleryBrowser1, PopupMenuHdl ) );
568     aMenu->RemoveDisabledEntries();
569 
570     const tools::Rectangle aThemesRect( mpThemes->GetPosPixel(), mpThemes->GetOutputSizePixel() );
571     Point           aSelPos( mpThemes->GetBoundingRectangle( mpThemes->GetSelectedEntryPos() ).Center() );
572 
573     aSelPos.setX( std::max( std::min( aSelPos.X(), aThemesRect.Right() ), aThemesRect.Left() ) );
574     aSelPos.setY( std::max( std::min( aSelPos.Y(), aThemesRect.Bottom() ), aThemesRect.Top() ) );
575 
576     aMenu->Execute( this, aSelPos );
577 }
578 
IMPL_LINK(GalleryBrowser1,PopupMenuHdl,Menu *,pMenu,bool)579 IMPL_LINK( GalleryBrowser1, PopupMenuHdl, Menu*, pMenu, bool )
580 {
581     ImplExecute(pMenu->GetCurItemIdent());
582     return false;
583 }
584 
IMPL_LINK_NOARG(GalleryBrowser1,SelectThemeHdl,ListBox &,void)585 IMPL_LINK_NOARG(GalleryBrowser1, SelectThemeHdl, ListBox&, void)
586 {
587     if (maThemeSlectionHandler)
588         maThemeSlectionHandler();
589 }
590 
IMPL_LINK_NOARG(GalleryBrowser1,ClickNewThemeHdl,Button *,void)591 IMPL_LINK_NOARG(GalleryBrowser1, ClickNewThemeHdl, Button*, void)
592 {
593     OUString  aNewTheme( SvxResId(RID_SVXSTR_GALLERY_NEWTHEME) );
594     OUString  aName( aNewTheme );
595     sal_uIntPtr nCount = 0;
596 
597     while( mpGallery->HasTheme( aName ) && ( nCount++ < 16000 ) )
598     {
599         aName = aNewTheme + " " + OUString::number( nCount );
600     }
601 
602     if( !mpGallery->HasTheme( aName ) && mpGallery->CreateTheme( aName ) )
603     {
604         ImplGalleryThemeProperties( aName, true );
605     }
606 }
607 
608 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
609