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 .
24 #include <vcl/builder.hxx>
25 #include <vcl/msgbox.hxx>
26 #include <unotools/viewoptions.hxx>
28 #include "appdata.hxx"
29 #include "sfxtypes.hxx"
30 #include <sfx2/tabdlg.hxx>
31 #include <sfx2/viewfrm.hxx>
32 #include <sfx2/app.hxx>
33 #include <sfx2/sfxresid.hxx>
34 #include <sfx2/sfxhelp.hxx>
35 #include <sfx2/ctrlitem.hxx>
36 #include <sfx2/bindings.hxx>
37 #include <sfx2/sfxdlg.hxx>
38 #include <sfx2/itemconnect.hxx>
43 using namespace ::com::sun::star::uno
;
45 #define USERITEM_NAME OUString("UserItem")
47 TYPEINIT1(SfxTabDialogItem
,SfxSetItem
);
52 sfx::ItemConnectionArray maItemConn
;
53 ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XFrame
> mxFrame
;
55 TabPageImpl() : mbStandard( false ) {}
60 sal_uInt16 nId
; // The ID
61 CreateTabPage fnCreatePage
; // Pointer to Factory
62 GetTabPageRanges fnGetRanges
; // Pointer to Ranges-Function
63 VclPtr
<SfxTabPage
> pTabPage
; // The TabPage itself
64 bool bOnDemand
; // Flag: ItemSet onDemand
65 bool bRefresh
; // Flag: Page must be re-initialized
68 Data_Impl( sal_uInt16 Id
, CreateTabPage fnPage
,
69 GetTabPageRanges fnRanges
, bool bDemand
) :
72 fnCreatePage( fnPage
),
73 fnGetRanges ( fnRanges
),
75 bOnDemand ( bDemand
),
80 SfxAbstractDialogFactory
* pFact
= SfxAbstractDialogFactory::Create();
83 fnCreatePage
= pFact
->GetTabPageCreatorFunc( nId
);
84 fnGetRanges
= pFact
->GetTabPageRangesFunc( nId
);
90 SfxTabDialogItem::SfxTabDialogItem( const SfxTabDialogItem
& rAttr
, SfxItemPool
* pItemPool
)
91 : SfxSetItem( rAttr
, pItemPool
)
95 SfxTabDialogItem::SfxTabDialogItem( sal_uInt16 nId
, const SfxItemSet
& rItemSet
)
96 : SfxSetItem( nId
, rItemSet
)
100 SfxPoolItem
* SfxTabDialogItem::Clone(SfxItemPool
* pToPool
) const
102 return new SfxTabDialogItem( *this, pToPool
);
105 SfxPoolItem
* SfxTabDialogItem::Create(SvStream
& /*rStream*/, sal_uInt16
/*nVersion*/) const
107 OSL_FAIL( "Use it only in UI!" );
111 typedef std::vector
<Data_Impl
*> SfxTabDlgData_Impl
;
118 SfxTabDlgData_Impl aData
;
120 TabDlg_Impl( sal_uInt8 nCnt
) :
124 bHideResetBtn ( false )
126 aData
.reserve( nCnt
);
134 static Data_Impl
* Find( const SfxTabDlgData_Impl
& rArr
, sal_uInt16 nId
, sal_uInt16
* pPos
= 0)
136 const sal_uInt16 nCount
= rArr
.size();
138 for ( sal_uInt16 i
= 0; i
< nCount
; ++i
)
140 Data_Impl
* pObj
= rArr
[i
];
142 if ( pObj
->nId
== nId
)
152 void SfxTabPage::SetFrame(const ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XFrame
>& xFrame
)
155 pImpl
->mxFrame
= xFrame
;
158 ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XFrame
> SfxTabPage::GetFrame()
161 return pImpl
->mxFrame
;
162 return ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XFrame
>();
165 SfxTabPage::SfxTabPage(vcl::Window
*pParent
, const OString
& rID
, const OUString
& rUIXMLDescription
, const SfxItemSet
*rAttrSet
)
166 : TabPage(pParent
, rID
, rUIXMLDescription
)
168 , bHasExchangeSupport ( false )
169 , pImpl ( new TabPageImpl
)
173 SfxTabPage::~SfxTabPage()
178 void SfxTabPage::dispose()
185 bool SfxTabPage::FillItemSet( SfxItemSet
* rSet
)
187 return pImpl
->maItemConn
.DoFillItemSet( *rSet
, GetItemSet() );
190 void SfxTabPage::Reset( const SfxItemSet
* rSet
)
192 pImpl
->maItemConn
.DoApplyFlags( *rSet
);
193 pImpl
->maItemConn
.DoReset( *rSet
);
196 void SfxTabPage::ActivatePage( const SfxItemSet
& )
199 Default implementation of the virtual ActivatePage method. This method is
200 called when a page of dialogue supports the exchange of data between pages.
201 <SfxTabPage::DeactivatePage(SfxItemSet *)>
206 SfxTabPage::sfxpg
SfxTabPage::DeactivatePage( SfxItemSet
* )
210 Default implementation of the virtual DeactivatePage method. This method is
211 called by Sfx when leaving a page; the application can, through the return
212 value, control whether to leave the page. If the page is displayed through
213 bHasExchangeSupport which supports data exchange between pages, then a
214 pointer to the exchange set is passed as parameter. This takes on data for
215 the exchange, then the set is available as a parameter in
216 <SfxTabPage::ActivatePage(const SfxItemSet &)>.
220 LEAVE_PAGE; Allow leaving the page
229 void SfxTabPage::FillUserData()
233 Virtual method is called by the base class in the destructor to save
234 specific information of the TabPage in the ini-file. When overriding a
235 string must be compiled, which is then flushed with the <SetUserData()>.
243 bool SfxTabPage::IsReadOnly() const
250 const SfxPoolItem
* SfxTabPage::GetItem( const SfxItemSet
& rSet
, sal_uInt16 nSlot
, bool bDeep
)
254 static Method: hereby are the implementations of the TabPage code
259 const SfxItemPool
* pPool
= rSet
.GetPool();
260 sal_uInt16 nWh
= pPool
->GetWhich( nSlot
, bDeep
);
261 const SfxPoolItem
* pItem
= 0;
262 rSet
.GetItemState( nWh
, true, &pItem
);
264 if ( !pItem
&& nWh
!= nSlot
)
265 pItem
= &pPool
->GetDefaultItem( nWh
);
271 const SfxPoolItem
* SfxTabPage::GetOldItem( const SfxItemSet
& rSet
,
272 sal_uInt16 nSlot
, bool bDeep
)
276 This method returns an attribute for comparison of the old value.
280 const SfxItemSet
& rOldSet
= GetItemSet();
281 sal_uInt16 nWh
= GetWhich( nSlot
, bDeep
);
282 const SfxPoolItem
* pItem
= 0;
284 if ( pImpl
->mbStandard
&& rOldSet
.GetParent() )
285 pItem
= GetItem( *rOldSet
.GetParent(), nSlot
);
286 else if ( rSet
.GetParent() &&
287 SfxItemState::DONTCARE
== rSet
.GetItemState( nWh
) )
288 pItem
= GetItem( *rSet
.GetParent(), nSlot
);
290 pItem
= GetItem( rOldSet
, nSlot
);
294 void SfxTabPage::PageCreated( const SfxAllItemSet
& /*aSet*/ )
296 DBG_ASSERT(false, "SfxTabPage::PageCreated should not be called");
301 void SfxTabPage::AddItemConnection( sfx::ItemConnectionBase
* pConnection
)
303 pImpl
->maItemConn
.AddConnection( pConnection
);
306 SfxTabDialog
* SfxTabPage::GetTabDialog() const
308 return dynamic_cast<SfxTabDialog
*>(GetParentDialog());
313 SfxTabDialog::SfxTabDialog
315 SfxViewFrame
* pViewFrame
, // Frame, to which the Dialog belongs
316 vcl::Window
* pParent
, // Parent Window
317 const OUString
& rID
, const OUString
& rUIXMLDescription
, //Dialog Name, Dialog .ui path
318 const SfxItemSet
* pItemSet
, // Itemset with the data;
319 // can be NULL, when Pages are onDemand
320 bool bEditFmt
// when yes -> additional Button for standard
322 : TabDialog(pParent
, rID
, rUIXMLDescription
)
324 , pSet(pItemSet
? new SfxItemSet(*pItemSet
) : 0)
327 , nAppPageId(USHRT_MAX
)
329 , bStandardPushed(false)
337 SfxTabDialog::SfxTabDialog
341 Constructor, temporary without Frame
345 vcl::Window
* pParent
, // Parent Window
346 const OUString
& rID
, const OUString
& rUIXMLDescription
, //Dialog Name, Dialog .ui path
347 const SfxItemSet
* pItemSet
, // Itemset with the data;
348 // can be NULL, when Pages are onDemand
349 bool bEditFmt
// when yes -> additional Button for standard
351 : TabDialog(pParent
, rID
, rUIXMLDescription
)
353 , pSet(pItemSet
? new SfxItemSet(*pItemSet
) : 0)
356 , nAppPageId(USHRT_MAX
)
358 , bStandardPushed(false)
362 DBG_WARNING( "Please use the Construtor with the ViewFrame" );
367 SfxTabDialog::~SfxTabDialog()
372 void SfxTabDialog::dispose()
376 for ( SfxTabDlgData_Impl::const_iterator it
= pImpl
->aData
.begin(); it
!= pImpl
->aData
.end(); ++it
)
378 Data_Impl
* pDataObject
= *it
;
380 if ( pDataObject
->pTabPage
)
382 // save settings of all pages (user data)
383 pDataObject
->pTabPage
->FillUserData();
384 OUString
aPageData( pDataObject
->pTabPage
->GetUserData() );
385 if ( !aPageData
.isEmpty() )
387 // save settings of all pages (user data)
388 OUString sConfigId
= OStringToOUString(pDataObject
->pTabPage
->GetConfigId(),
389 RTL_TEXTENCODING_UTF8
);
390 if (sConfigId
.isEmpty())
392 SAL_WARN("sfx.config", "Tabpage needs to be converted to .ui format");
393 sConfigId
= OUString::number(pDataObject
->nId
);
396 SvtViewOptions
aPageOpt(E_TABPAGE
, sConfigId
);
397 aPageOpt
.SetUserItem( USERITEM_NAME
, makeAny( OUString( aPageData
) ) );
400 if ( pDataObject
->bOnDemand
)
401 delete &pDataObject
->pTabPage
->GetItemSet();
402 pDataObject
->pTabPage
.disposeAndClear();
419 if (m_bOwnsBaseFmtBtn
)
420 m_pBaseFmtBtn
.disposeAndClear();
422 m_pResetBtn
.disposeAndClear();
424 m_pHelpBtn
.disposeAndClear();
425 if (m_bOwnsCancelBtn
)
426 m_pCancelBtn
.disposeAndClear();
428 m_pOKBtn
.disposeAndClear();
434 m_pCancelBtn
.clear();
437 m_pBaseFmtBtn
.clear();
438 m_pActionArea
.clear();
440 TabDialog::dispose();
443 void SfxTabDialog::Init_Impl(bool bFmtFlag
)
446 internal initialization of the dialogue
449 m_pBox
= get_content_area();
451 m_pUIBuilder
->get(m_pTabCtrl
, "tabcontrol");
453 pImpl
= new TabDlg_Impl(m_pTabCtrl
->GetPageCount());
455 m_pActionArea
= get_action_area();
456 assert(m_pActionArea
);
458 m_pOKBtn
= m_pUIBuilder
->get
<PushButton
>("ok");
459 m_bOwnsOKBtn
= m_pOKBtn
== nullptr;
461 m_pOKBtn
= VclPtr
<OKButton
>::Create(m_pActionArea
);
463 m_pApplyBtn
= m_pUIBuilder
->get
<PushButton
>("apply");
464 m_pUserBtn
= m_pUIBuilder
->get
<PushButton
>("user");
465 m_pCancelBtn
= m_pUIBuilder
->get
<CancelButton
>("cancel");
466 m_bOwnsCancelBtn
= m_pCancelBtn
== nullptr;
467 if (m_bOwnsCancelBtn
)
468 m_pCancelBtn
= VclPtr
<CancelButton
>::Create(m_pActionArea
);
470 m_pHelpBtn
= m_pUIBuilder
->get
<HelpButton
>("help");
471 m_bOwnsHelpBtn
= m_pHelpBtn
== nullptr;
473 m_pHelpBtn
= VclPtr
<HelpButton
>::Create(m_pActionArea
);
475 m_pResetBtn
= m_pUIBuilder
->get
<PushButton
>("reset");
476 m_bOwnsResetBtn
= m_pResetBtn
== nullptr;
478 m_pResetBtn
= VclPtr
<PushButton
>::Create(m_pActionArea
.get());
480 pImpl
->bHideResetBtn
= !m_pResetBtn
->IsVisible();
482 m_pBaseFmtBtn
= m_pUIBuilder
->get
<PushButton
>("standard");
483 m_bOwnsBaseFmtBtn
= m_pBaseFmtBtn
== nullptr;
484 if (m_bOwnsBaseFmtBtn
)
485 m_pBaseFmtBtn
= VclPtr
<PushButton
>::Create(m_pActionArea
.get());
487 m_pOKBtn
->SetClickHdl( LINK( this, SfxTabDialog
, OkHdl
) );
488 m_pCancelBtn
->SetClickHdl( LINK( this, SfxTabDialog
, CancelHdl
) );
489 m_pResetBtn
->SetClickHdl( LINK( this, SfxTabDialog
, ResetHdl
) );
490 m_pResetBtn
->SetText( SfxResId( STR_RESET
).toString() );
491 m_pTabCtrl
->SetActivatePageHdl(
492 LINK( this, SfxTabDialog
, ActivatePageHdl
) );
493 m_pTabCtrl
->SetDeactivatePageHdl(
494 LINK( this, SfxTabDialog
, DeactivatePageHdl
) );
495 m_pActionArea
->Show();
499 m_pCancelBtn
->Show();
502 m_pResetBtn
->SetHelpId( HID_TABDLG_RESET_BTN
);
506 m_pUserBtn
->SetClickHdl( LINK( this, SfxTabDialog
, UserHdl
) );
512 m_pBaseFmtBtn
->SetText( SfxResId( STR_STANDARD_SHORTCUT
).toString() );
513 m_pBaseFmtBtn
->SetClickHdl( LINK( this, SfxTabDialog
, BaseFmtHdl
) );
514 m_pBaseFmtBtn
->SetHelpId( HID_TABDLG_STANDARD_BTN
);
515 m_pBaseFmtBtn
->Show();
520 pExampleSet
= new SfxItemSet( *pSet
);
521 pOutSet
= new SfxItemSet( *pSet
->GetPool(), pSet
->GetRanges() );
525 void SfxTabDialog::RemoveResetButton()
528 pImpl
->bHideResetBtn
= true;
531 void SfxTabDialog::RemoveStandardButton()
533 m_pBaseFmtBtn
->Hide();
536 short SfxTabDialog::Execute()
538 if ( !m_pTabCtrl
->GetPageCount() )
541 return TabDialog::Execute();
546 void SfxTabDialog::StartExecuteModal( const Link
<>& rEndDialogHdl
)
548 if ( !m_pTabCtrl
->GetPageCount() )
551 TabDialog::StartExecuteModal( rEndDialogHdl
);
556 void SfxTabDialog::Start( bool bShow
)
558 pImpl
->bModal
= false;
564 if ( IsVisible() && ( !HasChildPathFocus() || HasFocus() ) )
565 GrabFocusToFirstControl();
570 void SfxTabDialog::SetApplyHandler(const Link
<>& _rHdl
)
572 DBG_ASSERT( m_pApplyBtn
, "SfxTabDialog::GetApplyHandler: no apply button enabled!" );
574 m_pApplyBtn
->SetClickHdl( _rHdl
);
579 void SfxTabDialog::Start_Impl()
581 assert(pImpl
->aData
.size() == m_pTabCtrl
->GetPageCount()
582 && "not all pages registered");
583 sal_uInt16 nActPage
= m_pTabCtrl
->GetPageId( 0 );
585 // load old settings, when exists
586 SvtViewOptions
aDlgOpt(E_TABDIALOG
, OStringToOUString(GetHelpId(),RTL_TEXTENCODING_UTF8
));
587 if ( aDlgOpt
.Exists() )
589 SetWindowState(OUStringToOString(aDlgOpt
.GetWindowState().getStr(), RTL_TEXTENCODING_ASCII_US
));
591 // initial TabPage from Program/Help/config
592 nActPage
= (sal_uInt16
)aDlgOpt
.GetPageID();
594 if ( USHRT_MAX
!= nAppPageId
)
595 nActPage
= nAppPageId
;
598 sal_uInt16 nAutoTabPageId
= SfxGetpApp()->Get_Impl()->nAutoTabPageId
;
599 if ( nAutoTabPageId
)
600 nActPage
= nAutoTabPageId
;
603 if ( TAB_PAGE_NOTFOUND
== m_pTabCtrl
->GetPagePos( nActPage
) )
604 nActPage
= m_pTabCtrl
->GetPageId( 0 );
606 else if ( USHRT_MAX
!= nAppPageId
&& TAB_PAGE_NOTFOUND
!= m_pTabCtrl
->GetPagePos( nAppPageId
) )
607 nActPage
= nAppPageId
;
609 m_pTabCtrl
->SetCurPageId( nActPage
);
610 ActivatePageHdl( m_pTabCtrl
);
613 void SfxTabDialog::AddTabPage( sal_uInt16 nId
, const OUString
&rRiderText
, bool bItemsOnDemand
, sal_uInt16 nPos
)
615 AddTabPage( nId
, rRiderText
, 0, 0, bItemsOnDemand
, nPos
);
619 Adds a page to the dialog. The Name must correspond to a entry in the
620 TabControl in the dialog .ui
622 sal_uInt16
SfxTabDialog::AddTabPage
624 const OString
&rName
, // Page ID
625 CreateTabPage pCreateFunc
, // Pointer to the Factory Method
626 GetTabPageRanges pRangesFunc
, // Pointer to the Method for quering
628 bool bItemsOnDemand
// indicates whether the set of this page is
629 // requested when created
632 sal_uInt16 nId
= m_pTabCtrl
->GetPageId(rName
);
633 pImpl
->aData
.push_back(
634 new Data_Impl( nId
, pCreateFunc
, pRangesFunc
, bItemsOnDemand
) );
639 Adds a page to the dialog. The Name must correspond to a entry in the
640 TabControl in the dialog .ui
642 sal_uInt16
SfxTabDialog::AddTabPage
644 const OString
&rName
, // Page ID
645 sal_uInt16 nPageCreateId
// Identifier of the Factory Method to create the page
648 SfxAbstractDialogFactory
* pFact
= SfxAbstractDialogFactory::Create();
650 CreateTabPage pCreateFunc
= pFact
->GetTabPageCreatorFunc(nPageCreateId
);
652 GetTabPageRanges pRangesFunc
= pFact
->GetTabPageRangesFunc(nPageCreateId
);
653 sal_uInt16 nPageId
= m_pTabCtrl
->GetPageId(rName
);
654 pImpl
->aData
.push_back(new Data_Impl(nPageId
, pCreateFunc
, pRangesFunc
, false));
660 void SfxTabDialog::AddTabPage
664 Add a page to the dialog. The Rider text is passed on, the page has no
665 counterpart in the TabControl in the resource of the dialogue.
670 const OUString
& rRiderText
,
671 CreateTabPage pCreateFunc
,
672 GetTabPageRanges pRangesFunc
,
677 DBG_ASSERT( TAB_PAGE_NOTFOUND
== m_pTabCtrl
->GetPagePos( nId
),
678 "Double Page-Ids in the Tabpage" );
679 m_pTabCtrl
->InsertPage( nId
, rRiderText
, nPos
);
680 pImpl
->aData
.push_back(
681 new Data_Impl( nId
, pCreateFunc
, pRangesFunc
, bItemsOnDemand
) );
684 void SfxTabDialog::RemoveTabPage( sal_uInt16 nId
)
688 Delete the TabPage with ID nId
693 m_pTabCtrl
->RemovePage( nId
);
694 Data_Impl
* pDataObject
= Find( pImpl
->aData
, nId
, &nPos
);
698 if ( pDataObject
->pTabPage
)
700 pDataObject
->pTabPage
->FillUserData();
701 OUString
aPageData( pDataObject
->pTabPage
->GetUserData() );
702 if ( !aPageData
.isEmpty() )
704 // save settings of this page (user data)
705 OUString sConfigId
= OStringToOUString(pDataObject
->pTabPage
->GetConfigId(),
706 RTL_TEXTENCODING_UTF8
);
707 if (sConfigId
.isEmpty())
709 SAL_WARN("sfx.config", "Tabpage needs to be converted to .ui format");
710 sConfigId
= OUString::number(pDataObject
->nId
);
713 SvtViewOptions
aPageOpt(E_TABPAGE
, sConfigId
);
714 aPageOpt
.SetUserItem( USERITEM_NAME
, makeAny( OUString( aPageData
) ) );
717 if ( pDataObject
->bOnDemand
)
718 delete &pDataObject
->pTabPage
->GetItemSet();
719 pDataObject
->pTabPage
.disposeAndClear();
723 pImpl
->aData
.erase( pImpl
->aData
.begin() + nPos
);
727 SAL_INFO( "sfx.dialog", "TabPage-Id not known" );
731 void SfxTabDialog::RemoveTabPage(const OString
&rName
)
733 RemoveTabPage(m_pTabCtrl
->GetPageId(rName
));
738 void SfxTabDialog::PageCreated
742 Default implementation of the virtual method. This is called immediately
743 after creating a page. Here the dialogue can call the TabPage Method
748 sal_uInt16
, // Id of the created page
749 SfxTabPage
& // Reference to the created page
756 SfxItemSet
* SfxTabDialog::GetInputSetImpl()
760 Derived classes may create new storage for the InputSet. This has to be
761 released in the Destructor. To do this, this method must be called.
770 SfxTabPage
* SfxTabDialog::GetTabPage( sal_uInt16 nPageId
) const
774 Return TabPage with the specified Id.
779 Data_Impl
* pDataObject
= Find( pImpl
->aData
, nPageId
, &nPos
);
782 return pDataObject
->pTabPage
;
786 void SfxTabDialog::SavePosAndId()
788 // save settings (screen position and current page)
789 SvtViewOptions
aDlgOpt(E_TABDIALOG
, OStringToOUString(GetHelpId(),RTL_TEXTENCODING_UTF8
));
790 aDlgOpt
.SetWindowState(OStringToOUString(GetWindowState(WINDOWSTATE_MASK_POS
),RTL_TEXTENCODING_ASCII_US
));
791 // to-do replace with name of page when all pages are converted to .ui
792 aDlgOpt
.SetPageID( m_pTabCtrl
->GetCurPageId() );
797 short SfxTabDialog::Ok()
801 Ok handler for the Dialogue.
803 Dialog's current location and current page are saved for the next time
806 The OutputSet is created and for each page this or the special OutputSet
807 is set by calling the method <SfxTabPage::FillItemSet(SfxItemSet &)>, to
808 insert the entered data by the user into the set.
812 RET_OK: if at least one page has returned from FillItemSet,
813 otherwise RET_CANCEL.
816 SavePosAndId(); //See fdo#38828 "Apply" resetting window position
820 if ( !pExampleSet
&& pSet
)
821 pOutSet
= pSet
->Clone( false ); // without Items
822 else if ( pExampleSet
)
823 pOutSet
= new SfxItemSet( *pExampleSet
);
825 bool bModified
= false;
827 for ( SfxTabDlgData_Impl::const_iterator it
= pImpl
->aData
.begin(); it
!= pImpl
->aData
.end(); ++it
)
829 Data_Impl
* pDataObject
= *it
;
830 SfxTabPage
* pTabPage
= pDataObject
->pTabPage
;
834 if ( pDataObject
->bOnDemand
)
836 SfxItemSet
& rSet
= (SfxItemSet
&)pTabPage
->GetItemSet();
838 bModified
|= pTabPage
->FillItemSet( &rSet
);
840 else if ( pSet
&& !pTabPage
->HasExchangeSupport() )
842 SfxItemSet
aTmp( *pSet
->GetPool(), pSet
->GetRanges() );
844 if ( pTabPage
->FillItemSet( &aTmp
) )
848 pExampleSet
->Put( aTmp
);
849 pOutSet
->Put( aTmp
);
855 if ( pImpl
->bModified
|| ( pOutSet
&& pOutSet
->Count() > 0 ) )
860 return bModified
? RET_OK
: RET_CANCEL
;
863 IMPL_LINK_NOARG(SfxTabDialog
, CancelHdl
)
865 EndDialog( RET_USER_CANCEL
);
871 SfxItemSet
* SfxTabDialog::CreateInputItemSet( sal_uInt16
)
875 Default implementation of the virtual Method.
876 This is called when pages create their sets onDemand.
880 SAL_WARN( "sfx.dialog", "CreateInputItemSet not implemented" );
881 return new SfxAllItemSet( SfxGetpApp()->GetPool() );
886 void SfxTabDialog::RefreshInputSet()
890 Default implementation of the virtual Method.
891 This is called, when <SfxTabPage::DeactivatePage(SfxItemSet *)>
892 returns <SfxTabPage::REFRESH_SET>.
896 SAL_INFO ( "sfx.dialog", "RefreshInputSet not implemented" );
901 IMPL_LINK_NOARG(SfxTabDialog
, OkHdl
)
905 Handler of the Ok-Buttons
906 This calls the current page <SfxTabPage::DeactivatePage(SfxItemSet *)>.
907 Returns <SfxTabPage::LEAVE_PAGE>, <SfxTabDialog::Ok()> is called
908 and the Dialog is ended.
912 if (PrepareLeaveCurrentPage())
925 bool SfxTabDialog::Apply()
927 bool bApplied
= false;
928 if (PrepareLeaveCurrentPage())
929 bApplied
= (Ok() == RET_OK
);
935 bool SfxTabDialog::PrepareLeaveCurrentPage()
937 sal_uInt16
const nId
= m_pTabCtrl
->GetCurPageId();
938 SfxTabPage
* pPage
= dynamic_cast<SfxTabPage
*> (m_pTabCtrl
->GetTabPage( nId
));
943 int nRet
= SfxTabPage::LEAVE_PAGE
;
946 SfxItemSet
aTmp( *pSet
->GetPool(), pSet
->GetRanges() );
948 if ( pPage
->HasExchangeSupport() )
949 nRet
= pPage
->DeactivatePage( &aTmp
);
951 nRet
= pPage
->DeactivatePage( NULL
);
953 if ( ( SfxTabPage::LEAVE_PAGE
& nRet
) == SfxTabPage::LEAVE_PAGE
956 pExampleSet
->Put( aTmp
);
957 pOutSet
->Put( aTmp
);
961 nRet
= pPage
->DeactivatePage( NULL
);
971 IMPL_LINK_NOARG(SfxTabDialog
, UserHdl
)
975 Handler of the User-Buttons
976 This calls the current page <SfxTabPage::DeactivatePage(SfxItemSet *)>.
977 returns this <SfxTabPage::LEAVE_PAGE> and <SfxTabDialog::Ok()> is called.
978 Then the Dialog is ended with the Return value <SfxTabDialog::Ok()>
982 if ( PrepareLeaveCurrentPage () )
986 if ( RET_OK
== nRet
)
989 nRet
= RET_USER_CANCEL
;
997 IMPL_LINK_NOARG(SfxTabDialog
, ResetHdl
)
1001 Handler behind the reset button.
1002 The Current Page is new initialized with their initial data, all the
1003 settings that the user has made on this page are repealed.
1007 const sal_uInt16 nId
= m_pTabCtrl
->GetCurPageId();
1008 Data_Impl
* pDataObject
= Find( pImpl
->aData
, nId
);
1009 DBG_ASSERT( pDataObject
, "Id not known" );
1011 if ( pDataObject
->bOnDemand
)
1013 // CSet on AIS has problems here, thus separated
1014 const SfxItemSet
* pItemSet
= &pDataObject
->pTabPage
->GetItemSet();
1015 pDataObject
->pTabPage
->Reset( pItemSet
);
1018 pDataObject
->pTabPage
->Reset( pSet
);
1024 IMPL_LINK_NOARG(SfxTabDialog
, BaseFmtHdl
)
1028 Handler behind the Standard-Button.
1029 This button is available when editing style sheets. All the set attributes
1030 in the edited stylesheet are deleted.
1034 bStandardPushed
= true;
1036 const sal_uInt16 nId
= m_pTabCtrl
->GetCurPageId();
1037 Data_Impl
* pDataObject
= Find( pImpl
->aData
, nId
);
1038 DBG_ASSERT( pDataObject
, "Id not known" );
1040 if ( pDataObject
->fnGetRanges
)
1043 pExampleSet
= new SfxItemSet( *pSet
);
1045 const SfxItemPool
* pPool
= pSet
->GetPool();
1046 const sal_uInt16
* pTmpRanges
= (pDataObject
->fnGetRanges
)();
1047 SfxItemSet
aTmpSet( *pExampleSet
);
1049 while ( *pTmpRanges
)
1051 const sal_uInt16
* pU
= pTmpRanges
+ 1;
1053 if ( *pTmpRanges
== *pU
)
1055 // Range which two identical values -> only set one Item
1056 sal_uInt16 nWh
= pPool
->GetWhich( *pTmpRanges
);
1057 pExampleSet
->ClearItem( nWh
);
1058 aTmpSet
.ClearItem( nWh
);
1059 // At the Outset of InvalidateItem,
1060 // so that the change takes effect
1061 pOutSet
->InvalidateItem( nWh
);
1065 // Correct Range with multiple values
1066 sal_uInt16 nTmp
= *pTmpRanges
, nTmpEnd
= *pU
;
1067 DBG_ASSERT( nTmp
<= nTmpEnd
, "Range is sorted the wrong way" );
1069 if ( nTmp
> nTmpEnd
)
1071 // If really sorted wrongly, then set new
1072 sal_uInt16 nTmp1
= nTmp
;
1077 while ( nTmp
<= nTmpEnd
)
1079 // Iterate over the Range and set the Items
1080 sal_uInt16 nWh
= pPool
->GetWhich( nTmp
);
1081 pExampleSet
->ClearItem( nWh
);
1082 aTmpSet
.ClearItem( nWh
);
1083 // At the Outset of InvalidateItem,
1084 // so that the change takes effect
1085 pOutSet
->InvalidateItem( nWh
);
1089 // Go to the next pair
1092 // Set all Items as new -> the call the current Page Reset()
1093 DBG_ASSERT( pDataObject
->pTabPage
, "the Page is gone" );
1094 pDataObject
->pTabPage
->Reset( &aTmpSet
);
1095 pDataObject
->pTabPage
->pImpl
->mbStandard
= true;
1102 IMPL_LINK( SfxTabDialog
, ActivatePageHdl
, TabControl
*, pTabCtrl
)
1106 Handler that is called by StarView for switching to a different page.
1107 If the page not exist yet then it is created and the virtual Method
1108 <SfxTabDialog::PageCreated( sal_uInt16, SfxTabPage &)> is called. If the page
1109 exist, then the if possible the <SfxTabPage::Reset(const SfxItemSet &)> or
1110 <SfxTabPage::ActivatePage(const SfxItemSet &)> is called.
1114 sal_uInt16 nId
= pTabCtrl
->GetCurPageId();
1116 DBG_ASSERT( pImpl
->aData
.size(), "no Pages registered" );
1119 // Tab Page schon da?
1120 VclPtr
<SfxTabPage
> pTabPage
= dynamic_cast<SfxTabPage
*> (pTabCtrl
->GetTabPage( nId
));
1121 Data_Impl
* pDataObject
= Find( pImpl
->aData
, nId
);
1123 //UUUU fallback to 1st page when requested one does not exist
1124 if(!pDataObject
&& pTabCtrl
->GetPageCount())
1126 pTabCtrl
->SetCurPageId(pTabCtrl
->GetPageId(0));
1127 nId
= pTabCtrl
->GetCurPageId();
1128 pTabPage
= dynamic_cast< SfxTabPage
* >(pTabCtrl
->GetTabPage(nId
));
1129 pDataObject
= Find(pImpl
->aData
, nId
);
1134 SAL_WARN("sfx.config", "Tab Page ID not known, this is pretty serious and needs investigation");
1138 // Create TabPage if possible:
1141 const SfxItemSet
* pTmpSet
= 0;
1145 if ( bItemsReset
&& pSet
->GetParent() )
1146 pTmpSet
= pSet
->GetParent();
1151 if ( pTmpSet
&& !pDataObject
->bOnDemand
)
1152 pTabPage
= (pDataObject
->fnCreatePage
)( pTabCtrl
, pTmpSet
);
1154 pTabPage
= (pDataObject
->fnCreatePage
)
1155 ( pTabCtrl
, CreateInputItemSet( nId
) );
1156 DBG_ASSERT( nullptr == pDataObject
->pTabPage
, "create TabPage more than once" );
1157 pDataObject
->pTabPage
= pTabPage
;
1159 OUString sConfigId
= OStringToOUString(pTabPage
->GetConfigId(), RTL_TEXTENCODING_UTF8
);
1160 if (sConfigId
.isEmpty())
1162 SAL_WARN("sfx.config", "Tabpage needs to be converted to .ui format");
1163 sConfigId
= OUString::number(pDataObject
->nId
);
1165 SvtViewOptions
aPageOpt(E_TABPAGE
, sConfigId
);
1167 Any aUserItem
= aPageOpt
.GetUserItem( USERITEM_NAME
);
1169 if ( aUserItem
>>= aTemp
)
1171 pTabPage
->SetUserData( sUserData
);
1172 Size aSiz
= pTabPage
->GetSizePixel();
1174 Size aCtrlSiz
= pTabCtrl
->GetTabPageSizePixel();
1175 // Only set Size on TabControl when < as TabPage
1176 if ( aCtrlSiz
.Width() < aSiz
.Width() ||
1177 aCtrlSiz
.Height() < aSiz
.Height() )
1179 pTabCtrl
->SetTabPageSizePixel( aSiz
);
1182 PageCreated( nId
, *pTabPage
);
1184 if ( pDataObject
->bOnDemand
)
1185 pTabPage
->Reset( &pTabPage
->GetItemSet() );
1187 pTabPage
->Reset( pSet
);
1189 pTabCtrl
->SetTabPage( nId
, pTabPage
);
1191 else if ( pDataObject
->bRefresh
)
1192 pTabPage
->Reset( pSet
);
1193 pDataObject
->bRefresh
= false;
1196 pTabPage
->ActivatePage( *pExampleSet
);
1197 bool bReadOnly
= pTabPage
->IsReadOnly();
1198 ( bReadOnly
|| pImpl
->bHideResetBtn
) ? m_pResetBtn
->Hide() : m_pResetBtn
->Show();
1204 IMPL_LINK_TYPED( SfxTabDialog
, DeactivatePageHdl
, TabControl
*, pTabCtrl
, bool )
1208 Handler that is called by StarView before leaving a page.
1212 <SfxTabPage::DeactivatePage(SfxItemSet *)>
1216 sal_uInt16 nId
= pTabCtrl
->GetCurPageId();
1218 SfxTabPage
*pPage
= dynamic_cast<SfxTabPage
*> (pTabCtrl
->GetTabPage( nId
));
1219 DBG_ASSERT( pPage
, "no active Page" );
1223 Data_Impl
* pDataObject
= Find( pImpl
->aData
, pTabCtrl
->GetCurPageId() );
1224 DBG_ASSERT( pDataObject
, "no Data structure for current page" );
1225 if ( pPage
->HasExchangeSupport() && pDataObject
->bOnDemand
)
1227 DBG_WARNING( "Data exchange in ItemsOnDemand is not desired!" );
1231 int nRet
= SfxTabPage::LEAVE_PAGE
;
1233 if ( !pExampleSet
&& pPage
->HasExchangeSupport() && pSet
)
1234 pExampleSet
= new SfxItemSet( *pSet
->GetPool(), pSet
->GetRanges() );
1238 SfxItemSet
aTmp( *pSet
->GetPool(), pSet
->GetRanges() );
1240 if ( pPage
->HasExchangeSupport() )
1241 nRet
= pPage
->DeactivatePage( &aTmp
);
1243 nRet
= pPage
->DeactivatePage( NULL
);
1244 if ( ( SfxTabPage::LEAVE_PAGE
& nRet
) == SfxTabPage::LEAVE_PAGE
&&
1247 pExampleSet
->Put( aTmp
);
1248 pOutSet
->Put( aTmp
);
1253 if ( pPage
->HasExchangeSupport() ) //!!!
1257 SfxItemPool
* pPool
= pPage
->GetItemSet().GetPool();
1259 new SfxItemSet( *pPool
, GetInputRanges( *pPool
) );
1261 nRet
= pPage
->DeactivatePage( pExampleSet
);
1264 nRet
= pPage
->DeactivatePage( NULL
);
1267 if ( nRet
& SfxTabPage::REFRESH_SET
)
1270 // Flag all Pages as to be initialized as new
1272 for ( SfxTabDlgData_Impl::const_iterator it
= pImpl
->aData
.begin(); it
!= pImpl
->aData
.end(); ++it
)
1274 Data_Impl
* pObj
= *it
;
1276 if ( pObj
->pTabPage
.get() != pPage
) // Do not refresh own Page anymore
1277 pObj
->bRefresh
= true;
1279 pObj
->bRefresh
= false;
1282 if ( nRet
& SfxTabPage::LEAVE_PAGE
)
1290 void SfxTabDialog::ShowPage( sal_uInt16 nId
)
1294 The TabPage is activated with the specified Id.
1298 m_pTabCtrl
->SetCurPageId( nId
);
1299 ActivatePageHdl( m_pTabCtrl
);
1304 const sal_uInt16
* SfxTabDialog::GetInputRanges( const SfxItemPool
& rPool
)
1308 Makes the set over the range of all pages of the dialogue. Pages have the
1309 static method for querying their range in AddTabPage, ie deliver their
1314 Pointer to a null-terminated array of sal_uInt16. This array belongs to the
1315 dialog and is deleted when the dialogue is destroy.
1319 <SfxTabDialog::AddTabPage(sal_uInt16, CreateTabPage, GetTabPageRanges, bool)>
1320 <SfxTabDialog::AddTabPage(sal_uInt16, const String &, CreateTabPage, GetTabPageRanges, bool, sal_uInt16)>
1321 <SfxTabDialog::AddTabPage(sal_uInt16, const Bitmap &, CreateTabPage, GetTabPageRanges, bool, sal_uInt16)>
1327 SAL_WARN( "sfx.dialog", "Set already exists!" );
1328 return pSet
->GetRanges();
1333 std::vector
<sal_uInt16
> aUS
;
1335 for ( SfxTabDlgData_Impl::const_iterator it
= pImpl
->aData
.begin(); it
!= pImpl
->aData
.end(); ++it
)
1337 Data_Impl
* pDataObject
= *it
;
1339 if ( pDataObject
->fnGetRanges
)
1341 const sal_uInt16
* pTmpRanges
= (pDataObject
->fnGetRanges
)();
1342 const sal_uInt16
* pIter
= pTmpRanges
;
1345 for( nLen
= 0; *pIter
; ++nLen
, ++pIter
)
1347 aUS
.insert( aUS
.end(), pTmpRanges
, pTmpRanges
+ nLen
);
1351 //! Remove duplicated Ids?
1353 sal_uInt16 nCount
= aUS
.size();
1354 for ( sal_uInt16 i
= 0; i
< nCount
; ++i
)
1355 aUS
[i
] = rPool
.GetWhich( aUS
[i
] );
1359 if ( aUS
.size() > 1 )
1361 std::sort( aUS
.begin(), aUS
.end() );
1364 pRanges
= new sal_uInt16
[aUS
.size() + 1];
1365 std::copy( aUS
.begin(), aUS
.end(), pRanges
);
1366 pRanges
[aUS
.size()] = 0;
1372 void SfxTabDialog::SetInputSet( const SfxItemSet
* pInSet
)
1376 With this method the Input-Set can subsequently be set initially or re-set.
1380 bool bSet
= ( pSet
!= NULL
);
1382 pSet
= pInSet
? new SfxItemSet(*pInSet
) : 0;
1384 if (!bSet
&& !pExampleSet
&& !pOutSet
&& pSet
)
1386 pExampleSet
= new SfxItemSet( *pSet
);
1387 pOutSet
= new SfxItemSet( *pSet
->GetPool(), pSet
->GetRanges() );
1391 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */