1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <comphelper/processfactory.hxx>
23 #include <tools/datetime.hxx>
24 #include <unotools/datetime.hxx>
25 #include <vcl/msgbox.hxx>
26 #include <vcl/settings.hxx>
27 #include <ucbhelper/content.hxx>
28 #include <sfx2/app.hxx>
30 #include "svx/gallery1.hxx"
31 #include "svx/galtheme.hxx"
32 #include "svx/galmisc.hxx"
33 #include "galbrws1.hxx"
34 #include <com/sun/star/util/DateTime.hpp>
35 #include "gallery.hrc"
37 #include <svx/dialogs.hrc>
38 #include <svx/dialmgr.hxx>
40 #include <svx/svxdlg.hxx>
41 #include <boost/scoped_ptr.hpp>
45 using namespace ::com::sun::star
;
49 GalleryButton::GalleryButton( GalleryBrowser1
* pParent
, WinBits nWinBits
) :
50 PushButton( pParent
, nWinBits
)
54 void GalleryButton::KeyInput( const KeyEvent
& rKEvt
)
56 if( !static_cast< GalleryBrowser1
* >( GetParent() )->KeyInput( rKEvt
, this ) )
57 PushButton::KeyInput( rKEvt
);
60 // - GalleryThemeListBox -
62 GalleryThemeListBox::GalleryThemeListBox( GalleryBrowser1
* pParent
, WinBits nWinBits
) :
63 ListBox( pParent
, nWinBits
)
68 void GalleryThemeListBox::InitSettings()
70 SetBackground( Wallpaper( GALLERY_BG_COLOR
) );
71 SetControlBackground( GALLERY_BG_COLOR
);
72 SetControlForeground( GALLERY_FG_COLOR
);
75 void GalleryThemeListBox::DataChanged( const DataChangedEvent
& rDCEvt
)
77 if ( ( rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) && ( rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
80 ListBox::DataChanged( rDCEvt
);
83 bool GalleryThemeListBox::PreNotify( NotifyEvent
& rNEvt
)
87 if( rNEvt
.GetType() == MouseNotifyEvent::COMMAND
)
89 const CommandEvent
* pCEvt
= rNEvt
.GetCommandEvent();
91 if( pCEvt
&& pCEvt
->GetCommand() == CommandEventId::ContextMenu
)
92 static_cast< GalleryBrowser1
* >( GetParent() )->ShowContextMenu();
94 else if( rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
)
96 const KeyEvent
* pKEvt
= rNEvt
.GetKeyEvent();
99 bDone
= static_cast< GalleryBrowser1
* >( GetParent() )->KeyInput( *pKEvt
, this );
102 return( bDone
|| ListBox::PreNotify( rNEvt
) );
105 // - GalleryBrowser1 -
107 GalleryBrowser1::GalleryBrowser1(
108 vcl::Window
* pParent
,
110 const ::boost::function
<sal_Bool(const KeyEvent
&,Window
*)>& rKeyInputHandler
,
111 const ::boost::function
<void()>& rThemeSlectionHandler
)
113 Control ( pParent
, WB_TABSTOP
),
114 maNewTheme ( VclPtr
<GalleryButton
>::Create(this, WB_3DLOOK
) ),
115 mpThemes ( VclPtr
<GalleryThemeListBox
>::Create( this, WB_TABSTOP
| WB_3DLOOK
| WB_BORDER
| WB_HSCROLL
| WB_VSCROLL
| WB_AUTOHSCROLL
| WB_SORT
) ),
116 mpGallery ( pGallery
),
117 mpExchangeData ( new ExchangeData
),
118 mpThemePropsDlgItemSet( NULL
),
119 aImgNormal ( GalleryResGetBitmapEx( RID_SVXBMP_THEME_NORMAL
) ),
120 aImgDefault ( GalleryResGetBitmapEx( RID_SVXBMP_THEME_DEFAULT
) ),
121 aImgReadOnly ( GalleryResGetBitmapEx( RID_SVXBMP_THEME_READONLY
) ),
122 maKeyInputHandler(rKeyInputHandler
),
123 maThemeSlectionHandler(rThemeSlectionHandler
)
125 StartListening( *mpGallery
);
127 maNewTheme
->SetHelpId( HID_GALLERY_NEWTHEME
);
128 maNewTheme
->SetText( GAL_RESSTR(RID_SVXSTR_GALLERY_CREATETHEME
));
129 maNewTheme
->SetClickHdl( LINK( this, GalleryBrowser1
, ClickNewThemeHdl
) );
131 // disable creation of new themes if a writable directory is not available
132 if( mpGallery
->GetUserURL().GetProtocol() == INetProtocol::NotValid
)
133 maNewTheme
->Disable();
135 mpThemes
->SetHelpId( HID_GALLERY_THEMELIST
);
136 mpThemes
->SetSelectHdl( LINK( this, GalleryBrowser1
, SelectThemeHdl
) );
137 mpThemes
->SetAccessibleName(SVX_RESSTR(RID_SVXSTR_GALLERYPROPS_GALTHEME
));
139 for( sal_uIntPtr i
= 0, nCount
= mpGallery
->GetThemeCount(); i
< nCount
; i
++ )
140 ImplInsertThemeEntry( mpGallery
->GetThemeInfo( i
) );
142 ImplAdjustControls();
143 maNewTheme
->Show( true );
144 mpThemes
->Show( true );
147 GalleryBrowser1::~GalleryBrowser1()
152 void GalleryBrowser1::dispose()
154 EndListening( *mpGallery
);
155 mpThemes
.disposeAndClear();
156 delete mpExchangeData
;
157 mpExchangeData
= NULL
;
158 maNewTheme
.disposeAndClear();
162 sal_uIntPtr
GalleryBrowser1::ImplInsertThemeEntry( const GalleryThemeEntry
* pEntry
)
164 static const bool bShowHiddenThemes
= ( getenv( "GALLERY_SHOW_HIDDEN_THEMES" ) != NULL
);
166 sal_uIntPtr nRet
= LISTBOX_ENTRY_NOTFOUND
;
168 if( pEntry
&& ( !pEntry
->IsHidden() || bShowHiddenThemes
) )
172 if( pEntry
->IsReadOnly() )
173 pImage
= &aImgReadOnly
;
174 else if( pEntry
->IsDefault() )
175 pImage
= &aImgDefault
;
177 pImage
= &aImgNormal
;
179 nRet
= mpThemes
->InsertEntry( pEntry
->GetThemeName(), *pImage
);
185 void GalleryBrowser1::ImplAdjustControls()
187 const Size
aOutSize( GetOutputSizePixel() );
188 const long nNewThemeHeight
= LogicToPixel( Size( 0, 14 ), MAP_APPFONT
).Height();
189 const long nStartY
= nNewThemeHeight
+ 4;
191 maNewTheme
->SetPosSizePixel( Point(),
192 Size( aOutSize
.Width(), nNewThemeHeight
) );
194 mpThemes
->SetPosSizePixel( Point( 0, nStartY
),
195 Size( aOutSize
.Width(), aOutSize
.Height() - nStartY
) );
198 void GalleryBrowser1::ImplFillExchangeData( const GalleryTheme
* pThm
, ExchangeData
& rData
)
200 rData
.pTheme
= const_cast<GalleryTheme
*>(pThm
);
201 rData
.aEditedTitle
= pThm
->GetName();
205 ::ucbhelper::Content
aCnt( pThm
->GetThmURL().GetMainURL( INetURLObject::NO_DECODE
), uno::Reference
< ucb::XCommandEnvironment
>(), comphelper::getProcessComponentContext() );
206 util::DateTime aDateTimeModified
;
207 DateTime
aDateTime( DateTime::EMPTY
);
209 aCnt
.getPropertyValue("DateModified") >>= aDateTimeModified
;
210 ::utl::typeConvert( aDateTimeModified
, aDateTime
);
211 rData
.aThemeChangeDate
= aDateTime
;
212 rData
.aThemeChangeTime
= aDateTime
;
214 catch( const ucb::ContentCreationException
& )
217 catch( const uno::RuntimeException
& )
220 catch( const uno::Exception
& )
225 void GalleryBrowser1::ImplGetExecuteVector(::std::vector
< sal_uInt16
>& o_aExec
)
227 GalleryTheme
* pTheme
= mpGallery
->AcquireTheme( GetSelectedTheme(), *this );
231 bool bUpdateAllowed
, bRenameAllowed
, bRemoveAllowed
;
232 static const bool bIdDialog
= ( getenv( "GALLERY_ENABLE_ID_DIALOG" ) != NULL
);
234 if( pTheme
->IsReadOnly() )
235 bUpdateAllowed
= bRenameAllowed
= bRemoveAllowed
= false;
236 else if( pTheme
->IsDefault() )
238 bUpdateAllowed
= bRenameAllowed
= true;
239 bRemoveAllowed
= false;
242 bUpdateAllowed
= bRenameAllowed
= bRemoveAllowed
= true;
244 if( bUpdateAllowed
&& pTheme
->GetObjectCount() )
245 o_aExec
.push_back( MN_ACTUALIZE
);
248 o_aExec
.push_back( MN_RENAME
);
251 o_aExec
.push_back( MN_DELETE
);
253 if( bIdDialog
&& !pTheme
->IsReadOnly() )
254 o_aExec
.push_back( MN_ASSIGN_ID
);
256 o_aExec
.push_back( MN_PROPERTIES
);
258 mpGallery
->ReleaseTheme( pTheme
, *this );
262 void GalleryBrowser1::ImplGalleryThemeProperties( const OUString
& rThemeName
, bool bCreateNew
)
264 DBG_ASSERT(!mpThemePropsDlgItemSet
, "mpThemePropsDlgItemSet already set!");
265 mpThemePropsDlgItemSet
= new SfxItemSet( SfxGetpApp()->GetPool() );
266 GalleryTheme
* pTheme
= mpGallery
->AcquireTheme( rThemeName
, *this );
268 ImplFillExchangeData( pTheme
, *mpExchangeData
);
270 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
271 assert(pFact
&& "Got no AbstractDialogFactory!");
272 VclAbstractDialog2
* pThemeProps
= pFact
->CreateGalleryThemePropertiesDialog( NULL
, mpExchangeData
, mpThemePropsDlgItemSet
);
273 assert(pThemeProps
&& "Got no GalleryThemePropertiesDialog!");
277 pThemeProps
->StartExecuteModal(
278 LINK( this, GalleryBrowser1
, EndNewThemePropertiesDlgHdl
) );
282 pThemeProps
->StartExecuteModal(
283 LINK( this, GalleryBrowser1
, EndThemePropertiesDlgHdl
) );
287 void GalleryBrowser1::ImplEndGalleryThemeProperties( VclAbstractDialog2
* pDialog
, bool bCreateNew
)
289 long nRet
= pDialog
->GetResult();
293 OUString
aName( mpExchangeData
->pTheme
->GetName() );
295 if( !mpExchangeData
->aEditedTitle
.isEmpty() && aName
!= mpExchangeData
->aEditedTitle
)
297 const OUString
aOldName( aName
);
298 OUString
aTitle( mpExchangeData
->aEditedTitle
);
299 sal_uInt16 nCount
= 0;
301 while( mpGallery
->HasTheme( aTitle
) && ( nCount
++ < 16000 ) )
303 aTitle
= mpExchangeData
->aEditedTitle
;
305 aTitle
+= OUString::number( nCount
);
308 mpGallery
->RenameTheme( aOldName
, aTitle
);
313 mpThemes
->SelectEntry( mpExchangeData
->pTheme
->GetName() );
314 SelectThemeHdl( NULL
);
318 OUString
aThemeName( mpExchangeData
->pTheme
->GetName() );
319 mpGallery
->ReleaseTheme( mpExchangeData
->pTheme
, *this );
321 if ( bCreateNew
&& ( nRet
!= RET_OK
) )
323 mpGallery
->RemoveTheme( aThemeName
);
326 // destroy mpThemeProps asynchronously
327 Application::PostUserEvent( LINK( this, GalleryBrowser1
, DestroyThemePropertiesDlgHdl
), pDialog
, true );
330 IMPL_LINK( GalleryBrowser1
, EndNewThemePropertiesDlgHdl
, VclAbstractDialog2
*, pDialog
)
332 ImplEndGalleryThemeProperties( pDialog
, true );
336 IMPL_LINK( GalleryBrowser1
, EndThemePropertiesDlgHdl
, VclAbstractDialog2
*, pDialog
)
338 ImplEndGalleryThemeProperties( pDialog
, false );
342 IMPL_LINK( GalleryBrowser1
, DestroyThemePropertiesDlgHdl
, VclAbstractDialog2
*, pDialog
)
345 delete mpThemePropsDlgItemSet
;
346 mpThemePropsDlgItemSet
= 0;
350 void GalleryBrowser1::ImplExecute( sal_uInt16 nId
)
354 case( MN_ACTUALIZE
):
356 GalleryTheme
* pTheme
= mpGallery
->AcquireTheme( GetSelectedTheme(), *this );
358 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
361 boost::scoped_ptr
<VclAbstractRefreshableDialog
> aActualizeProgress(pFact
->CreateActualizeProgressDialog( this, pTheme
));
362 DBG_ASSERT(aActualizeProgress
, "Dialog creation failed!");
364 aActualizeProgress
->Update();
365 aActualizeProgress
->Execute();
366 mpGallery
->ReleaseTheme( pTheme
, *this );
373 if( ScopedVclPtrInstance
<MessageDialog
>::Create( nullptr, "QueryDeleteThemeDialog","svx/ui/querydeletethemedialog.ui")->Execute() == RET_YES
)
374 mpGallery
->RemoveTheme( mpThemes
->GetSelectEntry() );
380 GalleryTheme
* pTheme
= mpGallery
->AcquireTheme( GetSelectedTheme(), *this );
381 const OUString
aOldName( pTheme
->GetName() );
383 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
384 DBG_ASSERT(pFact
, "Dialog creation failed!");
385 boost::scoped_ptr
<AbstractTitleDialog
> aDlg(pFact
->CreateTitleDialog( this, aOldName
));
386 DBG_ASSERT(aDlg
, "Dialog creation failed!");
388 if( aDlg
->Execute() == RET_OK
)
390 const OUString
aNewName( aDlg
->GetTitle() );
392 if( !aNewName
.isEmpty() && ( aNewName
!= aOldName
) )
394 OUString
aName( aNewName
);
395 sal_uInt16 nCount
= 0;
397 while( mpGallery
->HasTheme( aName
) && ( nCount
++ < 16000 ) )
401 aName
+= OUString::number( nCount
);
404 mpGallery
->RenameTheme( aOldName
, aName
);
407 mpGallery
->ReleaseTheme( pTheme
, *this );
411 case( MN_ASSIGN_ID
):
413 GalleryTheme
* pTheme
= mpGallery
->AcquireTheme( GetSelectedTheme(), *this );
415 if (pTheme
&& !pTheme
->IsReadOnly())
418 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
421 boost::scoped_ptr
<AbstractGalleryIdDialog
> aDlg(pFact
->CreateGalleryIdDialog( this, pTheme
));
422 DBG_ASSERT(aDlg
, "Dialog creation failed!");
424 if( aDlg
->Execute() == RET_OK
)
425 pTheme
->SetId( aDlg
->GetId(), true );
429 mpGallery
->ReleaseTheme( pTheme
, *this );
433 case( MN_PROPERTIES
):
435 ImplGalleryThemeProperties( GetSelectedTheme(), false );
441 void GalleryBrowser1::Resize()
444 ImplAdjustControls();
447 void GalleryBrowser1::GetFocus()
451 mpThemes
->GrabFocus();
454 void GalleryBrowser1::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
456 const GalleryHint
& rGalleryHint
= static_cast<const GalleryHint
&>(rHint
);
458 switch( rGalleryHint
.GetType() )
460 case( GalleryHintType::THEME_CREATED
):
461 ImplInsertThemeEntry( mpGallery
->GetThemeInfo( rGalleryHint
.GetThemeName() ) );
464 case( GalleryHintType::THEME_RENAMED
):
466 const sal_uInt16 nCurSelectPos
= mpThemes
->GetSelectEntryPos();
467 const sal_uInt16 nRenameEntryPos
= mpThemes
->GetEntryPos( rGalleryHint
.GetThemeName() );
469 mpThemes
->RemoveEntry( rGalleryHint
.GetThemeName() );
470 ImplInsertThemeEntry( mpGallery
->GetThemeInfo( rGalleryHint
.GetStringData() ) );
472 if( nCurSelectPos
== nRenameEntryPos
)
474 mpThemes
->SelectEntry( rGalleryHint
.GetStringData() );
475 SelectThemeHdl( NULL
);
480 case( GalleryHintType::THEME_REMOVED
):
482 mpThemes
->RemoveEntry( rGalleryHint
.GetThemeName() );
486 case( GalleryHintType::CLOSE_THEME
):
488 const sal_uInt16 nCurSelectPos
= mpThemes
->GetSelectEntryPos();
489 const sal_uInt16 nCloseEntryPos
= mpThemes
->GetEntryPos( rGalleryHint
.GetThemeName() );
491 if( nCurSelectPos
== nCloseEntryPos
)
493 if( nCurSelectPos
< ( mpThemes
->GetEntryCount() - 1 ) )
494 mpThemes
->SelectEntryPos( nCurSelectPos
+ 1 );
495 else if( nCurSelectPos
)
496 mpThemes
->SelectEntryPos( nCurSelectPos
- 1 );
498 mpThemes
->SetNoSelection();
500 SelectThemeHdl( NULL
);
510 void GalleryBrowser1::ShowContextMenu()
512 Application::PostUserEvent( LINK( this, GalleryBrowser1
, ShowContextMenuHdl
), this, true );
515 bool GalleryBrowser1::KeyInput( const KeyEvent
& rKEvt
, vcl::Window
* pWindow
)
518 if (maKeyInputHandler
)
519 bRet
= maKeyInputHandler(rKEvt
, pWindow
);
523 ::std::vector
< sal_uInt16
> aExecVector
;
524 ImplGetExecuteVector(aExecVector
);
525 sal_uInt16 nExecuteId
= 0;
526 bool bMod1
= rKEvt
.GetKeyCode().IsMod1();
528 switch( rKEvt
.GetKeyCode().GetCode() )
531 ClickNewThemeHdl( NULL
);
537 ClickNewThemeHdl( NULL
);
544 nExecuteId
= MN_ACTUALIZE
;
549 nExecuteId
= MN_DELETE
;
555 nExecuteId
= MN_DELETE
;
562 nExecuteId
= MN_RENAME
;
569 nExecuteId
= MN_PROPERTIES
;
574 if( nExecuteId
&& ( ::std::find( aExecVector
.begin(), aExecVector
.end(), nExecuteId
) != aExecVector
.end() ) )
576 ImplExecute( nExecuteId
);
584 IMPL_LINK_NOARG(GalleryBrowser1
, ShowContextMenuHdl
)
586 ::std::vector
< sal_uInt16
> aExecVector
;
587 ImplGetExecuteVector(aExecVector
);
589 if( !aExecVector
.empty() )
591 PopupMenu
aMenu( GAL_RES( RID_SVXMN_GALLERY1
) );
593 aMenu
.EnableItem( MN_ACTUALIZE
, ::std::find( aExecVector
.begin(), aExecVector
.end(), MN_ACTUALIZE
) != aExecVector
.end() );
594 aMenu
.EnableItem( MN_RENAME
, ::std::find( aExecVector
.begin(), aExecVector
.end(), MN_RENAME
) != aExecVector
.end() );
595 aMenu
.EnableItem( MN_DELETE
, ::std::find( aExecVector
.begin(), aExecVector
.end(), MN_DELETE
) != aExecVector
.end() );
596 aMenu
.EnableItem( MN_ASSIGN_ID
, ::std::find( aExecVector
.begin(), aExecVector
.end(), MN_ASSIGN_ID
) != aExecVector
.end() );
597 aMenu
.EnableItem( MN_PROPERTIES
, ::std::find( aExecVector
.begin(), aExecVector
.end(), MN_PROPERTIES
) != aExecVector
.end() );
598 aMenu
.SetSelectHdl( LINK( this, GalleryBrowser1
, PopupMenuHdl
) );
599 aMenu
.RemoveDisabledEntries();
601 const Rectangle
aThemesRect( mpThemes
->GetPosPixel(), mpThemes
->GetOutputSizePixel() );
602 Point
aSelPos( mpThemes
->GetBoundingRectangle( mpThemes
->GetSelectEntryPos() ).Center() );
604 aSelPos
.X() = std::max( std::min( aSelPos
.X(), aThemesRect
.Right() ), aThemesRect
.Left() );
605 aSelPos
.Y() = std::max( std::min( aSelPos
.Y(), aThemesRect
.Bottom() ), aThemesRect
.Top() );
607 aMenu
.Execute( this, aSelPos
);
613 IMPL_LINK( GalleryBrowser1
, PopupMenuHdl
, Menu
*, pMenu
)
615 ImplExecute( pMenu
->GetCurItemId() );
619 IMPL_LINK_NOARG(GalleryBrowser1
, SelectThemeHdl
)
621 if (maThemeSlectionHandler
)
622 maThemeSlectionHandler();
626 IMPL_LINK_NOARG(GalleryBrowser1
, ClickNewThemeHdl
)
628 OUString
aNewTheme( GAL_RESSTR(RID_SVXSTR_GALLERY_NEWTHEME
) );
629 OUString
aName( aNewTheme
);
630 sal_uIntPtr nCount
= 0;
632 while( mpGallery
->HasTheme( aName
) && ( nCount
++ < 16000 ) )
636 aName
+= OUString::number( nCount
);
639 if( !mpGallery
->HasTheme( aName
) && mpGallery
->CreateTheme( aName
) )
641 ImplGalleryThemeProperties( aName
, true );
647 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */