fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / svx / source / gallery2 / galbrws1.cxx
blobfaa108dbc88be63d8501c41df9a4361c4c1feb2f
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 <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>
29 #include "helpid.hrc"
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"
36 #include <algorithm>
37 #include <svx/dialogs.hrc>
38 #include <svx/dialmgr.hxx>
40 #include <svx/svxdlg.hxx>
41 #include <boost/scoped_ptr.hpp>
43 // - Namespaces -
45 using namespace ::com::sun::star;
47 // - GalleryButton -
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 )
65 InitSettings();
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 ) )
78 InitSettings();
79 else
80 ListBox::DataChanged( rDCEvt );
83 bool GalleryThemeListBox::PreNotify( NotifyEvent& rNEvt )
85 bool bDone = false;
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();
98 if( pKEvt )
99 bDone = static_cast< GalleryBrowser1* >( GetParent() )->KeyInput( *pKEvt, this );
102 return( bDone || ListBox::PreNotify( rNEvt ) );
105 // - GalleryBrowser1 -
107 GalleryBrowser1::GalleryBrowser1(
108 vcl::Window* pParent,
109 Gallery* pGallery,
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()
149 disposeOnce();
152 void GalleryBrowser1::dispose()
154 EndListening( *mpGallery );
155 mpThemes.disposeAndClear();
156 delete mpExchangeData;
157 mpExchangeData = NULL;
158 maNewTheme.disposeAndClear();
159 Control::dispose();
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 ) )
170 const Image* pImage;
172 if( pEntry->IsReadOnly() )
173 pImage = &aImgReadOnly;
174 else if( pEntry->IsDefault() )
175 pImage = &aImgDefault;
176 else
177 pImage = &aImgNormal;
179 nRet = mpThemes->InsertEntry( pEntry->GetThemeName(), *pImage );
182 return nRet;
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 );
229 if( pTheme )
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;
241 else
242 bUpdateAllowed = bRenameAllowed = bRemoveAllowed = true;
244 if( bUpdateAllowed && pTheme->GetObjectCount() )
245 o_aExec.push_back( MN_ACTUALIZE );
247 if( bRenameAllowed )
248 o_aExec.push_back( MN_RENAME );
250 if( bRemoveAllowed )
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!");
275 if ( bCreateNew )
277 pThemeProps->StartExecuteModal(
278 LINK( this, GalleryBrowser1, EndNewThemePropertiesDlgHdl ) );
280 else
282 pThemeProps->StartExecuteModal(
283 LINK( this, GalleryBrowser1, EndThemePropertiesDlgHdl ) );
287 void GalleryBrowser1::ImplEndGalleryThemeProperties( VclAbstractDialog2* pDialog, bool bCreateNew )
289 long nRet = pDialog->GetResult();
291 if( nRet == RET_OK )
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;
304 aTitle += " ";
305 aTitle += OUString::number( nCount );
308 mpGallery->RenameTheme( aOldName, aTitle );
311 if ( bCreateNew )
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 );
333 return 0L;
336 IMPL_LINK( GalleryBrowser1, EndThemePropertiesDlgHdl, VclAbstractDialog2*, pDialog )
338 ImplEndGalleryThemeProperties( pDialog, false );
339 return 0L;
342 IMPL_LINK( GalleryBrowser1, DestroyThemePropertiesDlgHdl, VclAbstractDialog2*, pDialog )
344 delete pDialog;
345 delete mpThemePropsDlgItemSet;
346 mpThemePropsDlgItemSet = 0;
347 return 0L;
350 void GalleryBrowser1::ImplExecute( sal_uInt16 nId )
352 switch( nId )
354 case( MN_ACTUALIZE ):
356 GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
358 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
359 if(pFact)
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 );
369 break;
371 case( MN_DELETE ):
373 if( ScopedVclPtrInstance<MessageDialog>::Create( nullptr, "QueryDeleteThemeDialog","svx/ui/querydeletethemedialog.ui")->Execute() == RET_YES )
374 mpGallery->RemoveTheme( mpThemes->GetSelectEntry() );
376 break;
378 case( MN_RENAME ):
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 ) )
399 aName = aNewName;
400 aName += " ";
401 aName += OUString::number( nCount );
404 mpGallery->RenameTheme( aOldName, aName );
407 mpGallery->ReleaseTheme( pTheme, *this );
409 break;
411 case( MN_ASSIGN_ID ):
413 GalleryTheme* pTheme = mpGallery->AcquireTheme( GetSelectedTheme(), *this );
415 if (pTheme && !pTheme->IsReadOnly())
418 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
419 if(pFact)
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 );
431 break;
433 case( MN_PROPERTIES ):
435 ImplGalleryThemeProperties( GetSelectedTheme(), false );
437 break;
441 void GalleryBrowser1::Resize()
443 Control::Resize();
444 ImplAdjustControls();
447 void GalleryBrowser1::GetFocus()
449 Control::GetFocus();
450 if( mpThemes )
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() ) );
462 break;
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 );
478 break;
480 case( GalleryHintType::THEME_REMOVED ):
482 mpThemes->RemoveEntry( rGalleryHint.GetThemeName() );
484 break;
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 );
497 else
498 mpThemes->SetNoSelection();
500 SelectThemeHdl( NULL );
503 break;
505 default:
506 break;
510 void GalleryBrowser1::ShowContextMenu()
512 Application::PostUserEvent( LINK( this, GalleryBrowser1, ShowContextMenuHdl ), this, true );
515 bool GalleryBrowser1::KeyInput( const KeyEvent& rKEvt, vcl::Window* pWindow )
517 bool bRet = false;
518 if (maKeyInputHandler)
519 bRet = maKeyInputHandler(rKEvt, pWindow);
521 if( !bRet )
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() )
530 case( KEY_INSERT ):
531 ClickNewThemeHdl( NULL );
532 break;
534 case( KEY_I ):
536 if( bMod1 )
537 ClickNewThemeHdl( NULL );
539 break;
541 case( KEY_U ):
543 if( bMod1 )
544 nExecuteId = MN_ACTUALIZE;
546 break;
548 case( KEY_DELETE ):
549 nExecuteId = MN_DELETE;
550 break;
552 case( KEY_D ):
554 if( bMod1 )
555 nExecuteId = MN_DELETE;
557 break;
559 case( KEY_R ):
561 if( bMod1 )
562 nExecuteId = MN_RENAME;
564 break;
566 case( KEY_RETURN ):
568 if( bMod1 )
569 nExecuteId = MN_PROPERTIES;
571 break;
574 if( nExecuteId && ( ::std::find( aExecVector.begin(), aExecVector.end(), nExecuteId ) != aExecVector.end() ) )
576 ImplExecute( nExecuteId );
577 bRet = true;
581 return bRet;
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 );
610 return 0L;
613 IMPL_LINK( GalleryBrowser1, PopupMenuHdl, Menu*, pMenu )
615 ImplExecute( pMenu->GetCurItemId() );
616 return 0L;
619 IMPL_LINK_NOARG(GalleryBrowser1, SelectThemeHdl)
621 if (maThemeSlectionHandler)
622 maThemeSlectionHandler();
623 return 0L;
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 ) )
634 aName = aNewTheme;
635 aName += " ";
636 aName += OUString::number( nCount );
639 if( !mpGallery->HasTheme( aName ) && mpGallery->CreateTheme( aName ) )
641 ImplGalleryThemeProperties( aName, true );
644 return 0L;
647 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */