1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
33 #include <vcl/msgbox.hxx>
34 #include <unotools/viewoptions.hxx>
36 #include "appdata.hxx"
37 #include "sfxtypes.hxx"
38 #include <sfx2/minarray.hxx>
39 #include <sfx2/tabdlg.hxx>
40 #include <sfx2/viewfrm.hxx>
41 #include <sfx2/app.hxx>
42 #include "sfx2/sfxresid.hxx"
43 #include "sfx2/sfxhelp.hxx"
44 #include <sfx2/ctrlitem.hxx>
45 #include <sfx2/bindings.hxx>
46 #include <sfx2/sfxdlg.hxx>
47 #include <sfx2/itemconnect.hxx>
52 using namespace ::com::sun::star::uno
;
53 using namespace ::rtl
;
55 #define USERITEM_NAME OUString("UserItem")
57 TYPEINIT1(SfxTabDialogItem
,SfxSetItem
);
62 sfx::ItemConnectionArray maItemConn
;
63 ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XFrame
> mxFrame
;
65 TabPageImpl() : mbStandard( sal_False
) {}
70 sal_uInt16 nId
; // The ID
71 CreateTabPage fnCreatePage
; // Pointer to Factory
72 GetTabPageRanges fnGetRanges
; // Pointer to Ranges-Function
73 SfxTabPage
* pTabPage
; // The TabPage itself
74 sal_Bool bOnDemand
; // Flag: ItemSet onDemand
75 sal_Bool bRefresh
; // Flag: Page must be re-initialized
78 Data_Impl( sal_uInt16 Id
, CreateTabPage fnPage
,
79 GetTabPageRanges fnRanges
, sal_Bool bDemand
) :
82 fnCreatePage( fnPage
),
83 fnGetRanges ( fnRanges
),
85 bOnDemand ( bDemand
),
86 bRefresh ( sal_False
)
90 SfxAbstractDialogFactory
* pFact
= SfxAbstractDialogFactory::Create();
93 fnCreatePage
= pFact
->GetTabPageCreatorFunc( nId
);
94 fnGetRanges
= pFact
->GetTabPageRangesFunc( nId
);
100 SfxTabDialogItem::SfxTabDialogItem( const SfxTabDialogItem
& rAttr
, SfxItemPool
* pItemPool
)
101 : SfxSetItem( rAttr
, pItemPool
)
105 SfxTabDialogItem::SfxTabDialogItem( sal_uInt16 nId
, const SfxItemSet
& rItemSet
)
106 : SfxSetItem( nId
, rItemSet
)
110 SfxPoolItem
* SfxTabDialogItem::Clone(SfxItemPool
* pToPool
) const
112 return new SfxTabDialogItem( *this, pToPool
);
115 SfxPoolItem
* SfxTabDialogItem::Create(SvStream
& /*rStream*/, sal_uInt16
/*nVersion*/) const
117 OSL_FAIL( "Use it only in UI!" );
121 class SfxTabDialogController
: public SfxControllerItem
123 SfxTabDialog
* pDialog
;
124 const SfxItemSet
* pSet
;
126 SfxTabDialogController( sal_uInt16 nSlotId
, SfxBindings
& rBindings
, SfxTabDialog
* pDlg
)
127 : SfxControllerItem( nSlotId
, rBindings
)
132 ~SfxTabDialogController();
134 virtual void StateChanged( sal_uInt16 nSID
, SfxItemState eState
, const SfxPoolItem
* pState
);
137 SfxTabDialogController::~SfxTabDialogController()
142 void SfxTabDialogController::StateChanged( sal_uInt16
/*nSID*/, SfxItemState
/*eState*/, const SfxPoolItem
* pState
)
144 const SfxSetItem
* pSetItem
= PTR_CAST( SfxSetItem
, pState
);
147 pSet
= pDialog
->pSet
= pSetItem
->GetItemSet().Clone();
148 sal_Bool bDialogStarted
= sal_False
;
149 for ( sal_uInt16 n
=0; n
<pDialog
->aTabCtrl
.GetPageCount(); n
++ )
151 sal_uInt16 nPageId
= pDialog
->aTabCtrl
.GetPageId( n
);
152 SfxTabPage
* pTabPage
= dynamic_cast<SfxTabPage
*> (pDialog
->aTabCtrl
.GetTabPage( nPageId
));
155 pTabPage
->Reset( pSetItem
->GetItemSet() );
156 bDialogStarted
= sal_True
;
160 if ( bDialogStarted
)
167 DECL_PTRARRAY(SfxTabDlgData_Impl
, Data_Impl
*, 4,4)
171 sal_Bool bModified
: 1,
175 SfxTabDlgData_Impl
* pData
;
177 PushButton
* pApplyButton
;
178 SfxTabDialogController
* pController
;
180 TabDlg_Impl( sal_uInt8 nCnt
) :
182 bModified ( sal_False
),
185 bHideResetBtn ( sal_False
),
186 pData ( new SfxTabDlgData_Impl( nCnt
) ),
187 pApplyButton ( NULL
),
192 Data_Impl
* Find( SfxTabDlgData_Impl
& rArr
, sal_uInt16 nId
, sal_uInt16
* pPos
= 0 );
194 Data_Impl
* Find( SfxTabDlgData_Impl
& rArr
, sal_uInt16 nId
, sal_uInt16
* pPos
)
196 const sal_uInt16 nCount
= rArr
.Count();
198 for ( sal_uInt16 i
= 0; i
< nCount
; ++i
)
200 Data_Impl
* pObj
= rArr
[i
];
202 if ( pObj
->nId
== nId
)
212 void SfxTabPage::SetFrame(const ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XFrame
>& xFrame
)
215 pImpl
->mxFrame
= xFrame
;
218 ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XFrame
> SfxTabPage::GetFrame()
221 return pImpl
->mxFrame
;
222 return ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XFrame
>();
225 SfxTabPage::SfxTabPage( Window
*pParent
,
226 const ResId
&rResId
, const SfxItemSet
&rAttrSet
) :
233 TabPage( pParent
, rResId
),
236 bHasExchangeSupport ( sal_False
),
238 pImpl ( new TabPageImpl
)
242 // -----------------------------------------------------------------------
243 SfxTabPage:: SfxTabPage( Window
*pParent
, WinBits nStyle
, const SfxItemSet
&rAttrSet
) :
244 TabPage(pParent
, nStyle
),
246 bHasExchangeSupport ( sal_False
),
248 pImpl ( new TabPageImpl
)
251 // -----------------------------------------------------------------------
253 SfxTabPage::~SfxTabPage()
264 // -----------------------------------------------------------------------
266 sal_Bool
SfxTabPage::FillItemSet( SfxItemSet
& rSet
)
268 return pImpl
->maItemConn
.DoFillItemSet( rSet
, GetItemSet() );
271 // -----------------------------------------------------------------------
273 void SfxTabPage::Reset( const SfxItemSet
& rSet
)
275 pImpl
->maItemConn
.DoApplyFlags( rSet
);
276 pImpl
->maItemConn
.DoReset( rSet
);
279 // -----------------------------------------------------------------------
281 void SfxTabPage::ActivatePage( const SfxItemSet
& )
285 Default implementation of the virtual ActivatePage method. This method is
286 called when a page of dialogue supports the exchange of data between pages.
287 <SfxTabPage::DeactivatePage(SfxItemSet *)>
293 // -----------------------------------------------------------------------
295 int SfxTabPage::DeactivatePage( SfxItemSet
* )
299 Default implementation of the virtual DeactivatePage method. This method is
300 called by Sfx when leaving a page; the application can, through the return
301 value, control whether to leave the page. If the page is displayed through
302 bHasExchangeSupport which supports data exchange between pages, then a
303 pointer to the exchange set is passed as parameter. This takes on data for
304 the exchange, then the set is available as a parameter in
305 <SfxTabPage::ActivatePage(const SfxItemSet &)>.
309 LEAVE_PAGE; Allow leaving the page
316 // -----------------------------------------------------------------------
318 void SfxTabPage::FillUserData()
322 Virtual method is called by the base class in the destructor to save
323 specific information of the TabPage in the ini-file. When overloading a
324 string must be compiled, which is then flushed with the <SetUserData()>.
330 // -----------------------------------------------------------------------
332 sal_Bool
SfxTabPage::IsReadOnly() const
337 // -----------------------------------------------------------------------
339 const SfxPoolItem
* SfxTabPage::GetItem( const SfxItemSet
& rSet
, sal_uInt16 nSlot
, sal_Bool bDeep
)
343 static Method: hereby are the implementations of the TabPage code
348 const SfxItemPool
* pPool
= rSet
.GetPool();
349 sal_uInt16 nWh
= pPool
->GetWhich( nSlot
, bDeep
);
350 const SfxPoolItem
* pItem
= 0;
351 rSet
.GetItemState( nWh
, sal_True
, &pItem
);
353 if ( !pItem
&& nWh
!= nSlot
)
354 pItem
= &pPool
->GetDefaultItem( nWh
);
358 // -----------------------------------------------------------------------
360 const SfxPoolItem
* SfxTabPage::GetOldItem( const SfxItemSet
& rSet
,
361 sal_uInt16 nSlot
, sal_Bool bDeep
)
365 This method returns an attribute for comparison of the old value.
369 const SfxItemSet
& rOldSet
= GetItemSet();
370 sal_uInt16 nWh
= GetWhich( nSlot
, bDeep
);
371 const SfxPoolItem
* pItem
= 0;
373 if ( pImpl
->mbStandard
&& rOldSet
.GetParent() )
374 pItem
= GetItem( *rOldSet
.GetParent(), nSlot
);
375 else if ( rSet
.GetParent() &&
376 SFX_ITEM_DONTCARE
== rSet
.GetItemState( nWh
) )
377 pItem
= GetItem( *rSet
.GetParent(), nSlot
);
379 pItem
= GetItem( rOldSet
, nSlot
);
383 void SfxTabPage::PageCreated( SfxAllItemSet
/*aSet*/ )
385 DBG_ASSERT(0, "SfxTabPage::PageCreated should not be called");
388 // -----------------------------------------------------------------------
390 void SfxTabPage::AddItemConnection( sfx::ItemConnectionBase
* pConnection
)
392 pImpl
->maItemConn
.AddConnection( pConnection
);
395 #define INI_LIST(ItemSetPtr) \
396 aTabCtrl ( this, ResId(ID_TABCONTROL,*rResId.GetResMgr() ) ),\
398 pUserBtn ( pUserButtonText? new PushButton(this): 0 ),\
399 aCancelBtn ( this ),\
402 aBaseFmtBtn ( this ),\
403 pSet ( ItemSetPtr ),\
405 pImpl ( new TabDlg_Impl( (sal_uInt8)aTabCtrl.GetPageCount() ) ), \
407 nResId ( rResId.GetId() ), \
408 nAppPageId ( USHRT_MAX ), \
409 bItemsReset ( sal_False ),\
413 // -----------------------------------------------------------------------
415 SfxTabDialog::SfxTabDialog
423 SfxViewFrame
* pViewFrame
, // Frame, to which the Dialog belongs
424 Window
* pParent
, // Parent Window
425 const ResId
& rResId
, // ResourceId
426 const SfxItemSet
* pItemSet
, // Itemset with the data;
427 // can be NULL, when Pages are onDemand
428 sal_Bool bEditFmt
, // Flag: templates are processed
429 // when yes -> additional Button for standard
430 const String
* pUserButtonText
// Text for UserButton;
431 // if != 0, the UserButton is created
433 TabDialog( pParent
, rResId
),
434 pFrame( pViewFrame
),
437 Init_Impl( bFmt
, pUserButtonText
);
440 // -----------------------------------------------------------------------
442 SfxTabDialog::SfxTabDialog
446 Constructor, temporary without Frame
450 Window
* pParent
, // Parent Window
451 const ResId
& rResId
, // ResourceId
452 const SfxItemSet
* pItemSet
, // Itemset with the data;
453 // can be NULL, when Pages are onDemand
454 sal_Bool bEditFmt
, // Flag: templates are processed
455 // when yes -> additional Button for standard
456 const String
* pUserButtonText
// Text for UserButton;
457 // if != 0, the UserButton is created
459 TabDialog( pParent
, rResId
),
463 Init_Impl( bFmt
, pUserButtonText
);
464 DBG_WARNING( "Please use the Construtor with the ViewFrame" );
467 // -----------------------------------------------------------------------
469 SfxTabDialog::~SfxTabDialog()
471 // save settings (screen position and current page)
472 SvtViewOptions
aDlgOpt( E_TABDIALOG
, String::CreateFromInt32( nResId
) );
473 aDlgOpt
.SetWindowState(OStringToOUString(GetWindowState(WINDOWSTATE_MASK_POS
),RTL_TEXTENCODING_ASCII_US
));
474 aDlgOpt
.SetPageID( aTabCtrl
.GetCurPageId() );
476 const sal_uInt16 nCount
= pImpl
->pData
->Count();
477 for ( sal_uInt16 i
= 0; i
< nCount
; ++i
)
479 Data_Impl
* pDataObject
= pImpl
->pData
->GetObject(i
);
481 if ( pDataObject
->pTabPage
)
483 // save settings of all pages (user data)
484 pDataObject
->pTabPage
->FillUserData();
485 String
aPageData( pDataObject
->pTabPage
->GetUserData() );
486 if ( aPageData
.Len() )
488 // save settings of all pages (user data)
489 SvtViewOptions
aPageOpt( E_TABPAGE
, String::CreateFromInt32( pDataObject
->nId
) );
490 aPageOpt
.SetUserItem( USERITEM_NAME
, makeAny( OUString( aPageData
) ) );
493 if ( pDataObject
->bOnDemand
)
494 delete (SfxItemSet
*)&pDataObject
->pTabPage
->GetItemSet();
495 delete pDataObject
->pTabPage
;
500 delete pImpl
->pController
;
501 delete pImpl
->pApplyButton
;
510 // -----------------------------------------------------------------------
512 void SfxTabDialog::Init_Impl( sal_Bool bFmtFlag
, const String
* pUserButtonText
)
516 internal initialization of the dialogue
520 aOKBtn
.SetClickHdl( LINK( this, SfxTabDialog
, OkHdl
) );
521 aCancelBtn
.SetClickHdl( LINK( this, SfxTabDialog
, CancelHdl
) );
522 aResetBtn
.SetClickHdl( LINK( this, SfxTabDialog
, ResetHdl
) );
523 aResetBtn
.SetText( String( SfxResId( STR_RESET
) ) );
524 aTabCtrl
.SetActivatePageHdl(
525 LINK( this, SfxTabDialog
, ActivatePageHdl
) );
526 aTabCtrl
.SetDeactivatePageHdl(
527 LINK( this, SfxTabDialog
, DeactivatePageHdl
) );
533 aResetBtn
.SetHelpId( HID_TABDLG_RESET_BTN
);
537 pUserBtn
->SetText( *pUserButtonText
);
538 pUserBtn
->SetClickHdl( LINK( this, SfxTabDialog
, UserHdl
) );
542 /* TODO: Check what is up with bFmt/bFmtFlag. Comment below suggests a
543 different behavior than implemented!! */
546 String
aStd( SfxResId( STR_STANDARD_SHORTCUT
) );
547 aBaseFmtBtn
.SetText( aStd
);
548 aBaseFmtBtn
.SetClickHdl( LINK( this, SfxTabDialog
, BaseFmtHdl
) );
549 aBaseFmtBtn
.SetHelpId( HID_TABDLG_STANDARD_BTN
);
551 // bFmt = temporary Flag passed on in the Constructor(),
552 // if bFmt == 2, then also sal_True,
553 // additional suppression of the standard button,
554 // after the Initializing set to sal_True again
563 pExampleSet
= new SfxItemSet( *pSet
);
564 pOutSet
= new SfxItemSet( *pSet
->GetPool(), pSet
->GetRanges() );
567 aOKBtn
.SetAccessibleRelationMemberOf( &aOKBtn
);
568 aCancelBtn
.SetAccessibleRelationMemberOf( &aCancelBtn
);
569 aHelpBtn
.SetAccessibleRelationMemberOf( &aHelpBtn
);
570 aResetBtn
.SetAccessibleRelationMemberOf( &aResetBtn
);
573 // -----------------------------------------------------------------------
575 void SfxTabDialog::RemoveResetButton()
578 pImpl
->bHideResetBtn
= sal_True
;
581 // -----------------------------------------------------------------------
583 short SfxTabDialog::Execute()
585 if ( !aTabCtrl
.GetPageCount() )
588 return TabDialog::Execute();
591 // -----------------------------------------------------------------------
593 void SfxTabDialog::StartExecuteModal( const Link
& rEndDialogHdl
)
595 if ( !aTabCtrl
.GetPageCount() )
598 TabDialog::StartExecuteModal( rEndDialogHdl
);
601 // -----------------------------------------------------------------------
603 void SfxTabDialog::Start( sal_Bool bShow
)
605 pImpl
->bModal
= sal_False
;
612 // -----------------------------------------------------------------------
614 void SfxTabDialog::SetApplyHandler(const Link
& _rHdl
)
616 DBG_ASSERT( pImpl
->pApplyButton
, "SfxTabDialog::GetApplyHandler: no apply button enabled!" );
617 if ( pImpl
->pApplyButton
)
618 pImpl
->pApplyButton
->SetClickHdl( _rHdl
);
621 // -----------------------------------------------------------------------
623 void SfxTabDialog::EnableApplyButton(sal_Bool bEnable
)
625 if ( IsApplyButtonEnabled() == bEnable
)
629 // create or remove the apply button
632 pImpl
->pApplyButton
= new PushButton( this );
633 // in the z-order, the apply button should be behind the ok button, thus appearing at the right side of it
634 pImpl
->pApplyButton
->SetZOrder(&aOKBtn
, WINDOW_ZORDER_BEHIND
);
635 pImpl
->pApplyButton
->SetText( String( SfxResId( STR_APPLY
) ) );
636 pImpl
->pApplyButton
->Show();
638 pImpl
->pApplyButton
->SetHelpId( HID_TABDLG_APPLY_BTN
);
642 delete pImpl
->pApplyButton
;
643 pImpl
->pApplyButton
= NULL
;
651 // -----------------------------------------------------------------------
653 sal_Bool
SfxTabDialog::IsApplyButtonEnabled() const
655 return ( NULL
!= pImpl
->pApplyButton
);
658 // -----------------------------------------------------------------------
660 void SfxTabDialog::Start_Impl()
662 DBG_ASSERT( pImpl
->pData
->Count() == aTabCtrl
.GetPageCount(), "not all pages registered" );
663 sal_uInt16 nActPage
= aTabCtrl
.GetPageId( 0 );
665 // load old settings, when exists
666 SvtViewOptions
aDlgOpt( E_TABDIALOG
, String::CreateFromInt32( nResId
) );
667 if ( aDlgOpt
.Exists() )
669 SetWindowState(rtl::OUStringToOString(aDlgOpt
.GetWindowState().getStr(), RTL_TEXTENCODING_ASCII_US
));
671 // initial TabPage from Program/Help/config
672 nActPage
= (sal_uInt16
)aDlgOpt
.GetPageID();
674 if ( USHRT_MAX
!= nAppPageId
)
675 nActPage
= nAppPageId
;
678 sal_uInt16 nAutoTabPageId
= SFX_APP()->Get_Impl()->nAutoTabPageId
;
679 if ( nAutoTabPageId
)
680 nActPage
= nAutoTabPageId
;
683 if ( TAB_PAGE_NOTFOUND
== aTabCtrl
.GetPagePos( nActPage
) )
684 nActPage
= aTabCtrl
.GetPageId( 0 );
686 else if ( USHRT_MAX
!= nAppPageId
&& TAB_PAGE_NOTFOUND
!= aTabCtrl
.GetPagePos( nAppPageId
) )
687 nActPage
= nAppPageId
;
689 aTabCtrl
.SetCurPageId( nActPage
);
690 ActivatePageHdl( &aTabCtrl
);
693 void SfxTabDialog::AddTabPage( sal_uInt16 nId
, sal_Bool bItemsOnDemand
)
695 AddTabPage( nId
, 0, 0, bItemsOnDemand
);
698 void SfxTabDialog::AddTabPage( sal_uInt16 nId
, const String
&rRiderText
, sal_Bool bItemsOnDemand
, sal_uInt16 nPos
)
700 AddTabPage( nId
, rRiderText
, 0, 0, bItemsOnDemand
, nPos
);
703 #ifdef SV_HAS_RIDERBITMAPS
705 void SfxTabDialog::AddTabPage( sal_uInt16 nId
, const Bitmap
&rRiderBitmap
, sal_Bool bItemsOnDemand
, sal_uInt16 nPos
)
707 AddTabPage( nId
, rRiderBitmap
, 0, 0, bItemsOnDemand
, nPos
);
712 // -----------------------------------------------------------------------
714 void SfxTabDialog::AddTabPage
718 Adding a page to the dialogue. Must correspond to a entry in the
719 TabControl in the resource of the dialogue.
723 sal_uInt16 nId
, // Page ID
724 CreateTabPage pCreateFunc
, // Pointer to the Factory Method
725 GetTabPageRanges pRangesFunc
, // Pointer to the Method for quering
727 sal_Bool bItemsOnDemand
// indicates whether the set of this page is
728 // requested when created
731 pImpl
->pData
->Append(
732 new Data_Impl( nId
, pCreateFunc
, pRangesFunc
, bItemsOnDemand
) );
735 // -----------------------------------------------------------------------
737 void SfxTabDialog::AddTabPage
741 Add a page to the dialog. The Rider text is passed on, the page has no
742 counterpart in the TabControl in the resource of the dialogue.
747 const String
& rRiderText
,
748 CreateTabPage pCreateFunc
,
749 GetTabPageRanges pRangesFunc
,
750 sal_Bool bItemsOnDemand
,
754 DBG_ASSERT( TAB_PAGE_NOTFOUND
== aTabCtrl
.GetPagePos( nId
),
755 "Double Page-Ids in the Tabpage" );
756 aTabCtrl
.InsertPage( nId
, rRiderText
, nPos
);
757 pImpl
->pData
->Append(
758 new Data_Impl( nId
, pCreateFunc
, pRangesFunc
, bItemsOnDemand
) );
761 // -----------------------------------------------------------------------
762 #ifdef SV_HAS_RIDERBITMAPS
764 void SfxTabDialog::AddTabPage
768 Add a page to the dialog. The riders bitmap is passed on, the page has no
769 counterpart in the TabControl in the resource of the dialogue.
774 const Bitmap
&rRiderBitmap
,
775 CreateTabPage pCreateFunc
,
776 GetTabPageRanges pRangesFunc
,
777 sal_Bool bItemsOnDemand
,
781 DBG_ASSERT( TAB_PAGE_NOTFOUND
== aTabCtrl
.GetPagePos( nId
),
782 "Duplicate Page-Ids in the Tabpage" );
783 aTabCtrl
.InsertPage( nId
, rRiderBitmap
, nPos
);
784 pImpl
->pData
->Append(
785 new Data_Impl( nId
, pCreateFunc
, pRangesFunc
, bItemsOnDemand
) );
789 // -----------------------------------------------------------------------
791 void SfxTabDialog::RemoveTabPage( sal_uInt16 nId
)
795 Delete the TabPage with ID nId
800 aTabCtrl
.RemovePage( nId
);
801 Data_Impl
* pDataObject
= Find( *pImpl
->pData
, nId
, &nPos
);
805 if ( pDataObject
->pTabPage
)
807 pDataObject
->pTabPage
->FillUserData();
808 String
aPageData( pDataObject
->pTabPage
->GetUserData() );
809 if ( aPageData
.Len() )
811 // save settings of this page (user data)
812 SvtViewOptions
aPageOpt( E_TABPAGE
, String::CreateFromInt32( pDataObject
->nId
) );
813 aPageOpt
.SetUserItem( USERITEM_NAME
, makeAny( OUString( aPageData
) ) );
816 if ( pDataObject
->bOnDemand
)
817 delete (SfxItemSet
*)&pDataObject
->pTabPage
->GetItemSet();
818 delete pDataObject
->pTabPage
;
822 pImpl
->pData
->Remove( nPos
);
826 SAL_INFO( "sfx2.dialog", "TabPage-Id not known" );
830 // -----------------------------------------------------------------------
832 void SfxTabDialog::PageCreated
836 Default implemetation of the virtual method. This is called immediately
837 after creating a page. Here the dialogue can call the TabPage Method
842 sal_uInt16
, // Id of the created page
843 SfxTabPage
& // Reference to the created page
848 // -----------------------------------------------------------------------
850 SfxItemSet
* SfxTabDialog::GetInputSetImpl()
854 Derived classes may create new storage for the InputSet. This has to be
855 released in the Destructor. To do this, this method must be called.
859 return (SfxItemSet
*)pSet
;
862 // -----------------------------------------------------------------------
864 SfxTabPage
* SfxTabDialog::GetTabPage( sal_uInt16 nPageId
) const
868 Return TabPage with the specified Id.
873 Data_Impl
* pDataObject
= Find( *pImpl
->pData
, nPageId
, &nPos
);
876 return pDataObject
->pTabPage
;
880 // -----------------------------------------------------------------------
882 short SfxTabDialog::Ok()
886 Ok handler for the Dialogue.
887 The OutputSet is created and for each page this or the special OutputSet
888 is set by calling the method <SfxTabPage::FillItemSet(SfxItemSet &)>, to
889 insert the entered data by the user into the set.
893 RET_OK: if at least one page has returned from FillItemSet,
894 otherwise RET_CANCEL.
898 pImpl
->bInOK
= sal_True
;
902 if ( !pExampleSet
&& pSet
)
903 pOutSet
= pSet
->Clone( sal_False
); // without Items
904 else if ( pExampleSet
)
905 pOutSet
= new SfxItemSet( *pExampleSet
);
907 sal_Bool bModified
= sal_False
;
909 const sal_uInt16 nCount
= pImpl
->pData
->Count();
911 for ( sal_uInt16 i
= 0; i
< nCount
; ++i
)
913 Data_Impl
* pDataObject
= pImpl
->pData
->GetObject(i
);
914 SfxTabPage
* pTabPage
= pDataObject
->pTabPage
;
918 if ( pDataObject
->bOnDemand
)
920 SfxItemSet
& rSet
= (SfxItemSet
&)pTabPage
->GetItemSet();
922 bModified
|= pTabPage
->FillItemSet( rSet
);
924 else if ( pSet
&& !pTabPage
->HasExchangeSupport() )
926 SfxItemSet
aTmp( *pSet
->GetPool(), pSet
->GetRanges() );
928 if ( pTabPage
->FillItemSet( aTmp
) )
930 bModified
|= sal_True
;
931 pExampleSet
->Put( aTmp
);
932 pOutSet
->Put( aTmp
);
938 if ( pImpl
->bModified
|| ( pOutSet
&& pOutSet
->Count() > 0 ) )
939 bModified
|= sal_True
;
942 bModified
|= sal_True
;
943 return bModified
? RET_OK
: RET_CANCEL
;
946 // -----------------------------------------------------------------------
948 IMPL_LINK_NOARG(SfxTabDialog
, CancelHdl
)
950 EndDialog( RET_USER_CANCEL
);
954 // -----------------------------------------------------------------------
956 SfxItemSet
* SfxTabDialog::CreateInputItemSet( sal_uInt16
)
960 Default implemetation of the virtual Method.
961 This is called when pages create their sets onDenamd.
965 SAL_WARN( "sfx2.dialog", "CreateInputItemSet not implemented" );
966 return new SfxAllItemSet( SFX_APP()->GetPool() );
969 // -----------------------------------------------------------------------
971 const SfxItemSet
* SfxTabDialog::GetRefreshedSet()
975 Default implemetation of the virtual Method.
976 This is called, when <SfxTabPage::DeactivatePage(SfxItemSet *)>
977 returns <SfxTabPage::REFRESH_SET>.
981 SAL_INFO ( "sfx2.dialog", "GetRefreshedSet not implemented" );
985 // -----------------------------------------------------------------------
987 IMPL_LINK_NOARG(SfxTabDialog
, OkHdl
)
991 Handler of the Ok-Buttons
992 This calls the current page <SfxTabPage::DeactivatePage(SfxItemSet *)>.
993 Returns <SfxTabPage::LEAVE_PAGE>, <SfxTabDialog::Ok()> is called
994 anf the Dialog is ended.
998 pImpl
->bInOK
= sal_True
;
1002 if ( pImpl
->bModal
)
1013 // -----------------------------------------------------------------------
1015 bool SfxTabDialog::PrepareLeaveCurrentPage()
1017 sal_uInt16
const nId
= aTabCtrl
.GetCurPageId();
1018 SfxTabPage
* pPage
= dynamic_cast<SfxTabPage
*> (aTabCtrl
.GetTabPage( nId
));
1023 int nRet
= SfxTabPage::LEAVE_PAGE
;
1026 SfxItemSet
aTmp( *pSet
->GetPool(), pSet
->GetRanges() );
1028 if ( pPage
->HasExchangeSupport() )
1029 nRet
= pPage
->DeactivatePage( &aTmp
);
1031 nRet
= pPage
->DeactivatePage( NULL
);
1033 if ( ( SfxTabPage::LEAVE_PAGE
& nRet
) == SfxTabPage::LEAVE_PAGE
1036 pExampleSet
->Put( aTmp
);
1037 pOutSet
->Put( aTmp
);
1041 nRet
= pPage
->DeactivatePage( NULL
);
1049 // -----------------------------------------------------------------------
1051 IMPL_LINK_NOARG(SfxTabDialog
, UserHdl
)
1055 Handler of the User-Buttons
1056 This calls the current page <SfxTabPage::DeactivatePage(SfxItemSet *)>.
1057 returns this <SfxTabPage::LEAVE_PAGE> and <SfxTabDialog::Ok()> is called.
1058 Then the Dialog is ended with the Return value <SfxTabDialog::Ok()>
1062 if ( PrepareLeaveCurrentPage () )
1066 if ( RET_OK
== nRet
)
1069 nRet
= RET_USER_CANCEL
;
1075 // -----------------------------------------------------------------------
1077 IMPL_LINK_NOARG(SfxTabDialog
, ResetHdl
)
1081 Handler behind the reset button.
1082 The Current Page is new initialized with their initial data, all the
1083 settings that the user has made on this page are repealed.
1087 const sal_uInt16 nId
= aTabCtrl
.GetCurPageId();
1088 Data_Impl
* pDataObject
= Find( *pImpl
->pData
, nId
);
1089 DBG_ASSERT( pDataObject
, "Id not known" );
1091 if ( pDataObject
->bOnDemand
)
1093 // CSet on AIS has problems here, thus separated
1094 const SfxItemSet
* pItemSet
= &pDataObject
->pTabPage
->GetItemSet();
1095 pDataObject
->pTabPage
->Reset( *(SfxItemSet
*)pItemSet
);
1098 pDataObject
->pTabPage
->Reset( *pSet
);
1102 // -----------------------------------------------------------------------
1104 IMPL_LINK_NOARG(SfxTabDialog
, BaseFmtHdl
)
1108 Handler behind the Standard-Button.
1109 This button is available when editing style sheets. All the set attributes
1110 in the edited stylesheet are deleted.
1114 const sal_uInt16 nId
= aTabCtrl
.GetCurPageId();
1115 Data_Impl
* pDataObject
= Find( *pImpl
->pData
, nId
);
1116 DBG_ASSERT( pDataObject
, "Id not known" );
1119 if ( pDataObject
->fnGetRanges
)
1122 pExampleSet
= new SfxItemSet( *pSet
);
1124 const SfxItemPool
* pPool
= pSet
->GetPool();
1125 const sal_uInt16
* pTmpRanges
= (pDataObject
->fnGetRanges
)();
1126 SfxItemSet
aTmpSet( *pExampleSet
);
1128 while ( *pTmpRanges
)
1130 const sal_uInt16
* pU
= pTmpRanges
+ 1;
1132 if ( *pTmpRanges
== *pU
)
1134 // Range which two identical values -> only set one Item
1135 sal_uInt16 nWh
= pPool
->GetWhich( *pTmpRanges
);
1136 pExampleSet
->ClearItem( nWh
);
1137 aTmpSet
.ClearItem( nWh
);
1138 // At the Outset of InvalidateItem,
1139 // so that the change takes effect
1140 pOutSet
->InvalidateItem( nWh
);
1144 // Correct Range with multiple values
1145 sal_uInt16 nTmp
= *pTmpRanges
, nTmpEnd
= *pU
;
1146 DBG_ASSERT( nTmp
<= nTmpEnd
, "Range is sorted the wrong way" );
1148 if ( nTmp
> nTmpEnd
)
1150 // If really sorted wrongly, then set new
1151 sal_uInt16 nTmp1
= nTmp
;
1156 while ( nTmp
<= nTmpEnd
)
1158 // Iterate over the Range and set the Items
1159 sal_uInt16 nWh
= pPool
->GetWhich( nTmp
);
1160 pExampleSet
->ClearItem( nWh
);
1161 aTmpSet
.ClearItem( nWh
);
1162 // At the Outset of InvalidateItem,
1163 // so that the change takes effect
1164 pOutSet
->InvalidateItem( nWh
);
1168 // Go to the next pair
1171 // Set all Items as new -> the call the current Page Reset()
1172 DBG_ASSERT( pDataObject
->pTabPage
, "the Page is gone" );
1173 pDataObject
->pTabPage
->Reset( aTmpSet
);
1174 pDataObject
->pTabPage
->pImpl
->mbStandard
= sal_True
;
1179 // -----------------------------------------------------------------------
1181 IMPL_LINK( SfxTabDialog
, ActivatePageHdl
, TabControl
*, pTabCtrl
)
1185 Handler that is called by StarView for switching to a different page.
1186 If the page not exist yet then it is created and the virtual Method
1187 <SfxTabDialog::PageCreated( sal_uInt16, SfxTabPage &)> is called. If the page
1188 exist, then the if possible the <SfxTabPage::Reset(const SfxItemSet &)> or
1189 <SfxTabPage::ActivatePage(const SfxItemSet &)> is called.
1193 sal_uInt16
const nId
= pTabCtrl
->GetCurPageId();
1195 DBG_ASSERT( pImpl
->pData
->Count(), "no Pages registered" );
1198 // Tab Page schon da?
1199 SfxTabPage
* pTabPage
= dynamic_cast<SfxTabPage
*> (pTabCtrl
->GetTabPage( nId
));
1200 Data_Impl
* pDataObject
= Find( *pImpl
->pData
, nId
);
1201 DBG_ASSERT( pDataObject
, "Id not known" );
1203 // Create TabPage if possible:
1206 const SfxItemSet
* pTmpSet
= 0;
1210 if ( bItemsReset
&& pSet
->GetParent() )
1211 pTmpSet
= pSet
->GetParent();
1216 if ( pTmpSet
&& !pDataObject
->bOnDemand
)
1217 pTabPage
= (pDataObject
->fnCreatePage
)( pTabCtrl
, *pTmpSet
);
1219 pTabPage
= (pDataObject
->fnCreatePage
)
1220 ( pTabCtrl
, *CreateInputItemSet( nId
) );
1221 DBG_ASSERT( NULL
== pDataObject
->pTabPage
, "create TabPage more than once" );
1222 pDataObject
->pTabPage
= pTabPage
;
1224 pDataObject
->pTabPage
->SetTabDialog( this );
1225 SvtViewOptions
aPageOpt( E_TABPAGE
, String::CreateFromInt32( pDataObject
->nId
) );
1227 Any aUserItem
= aPageOpt
.GetUserItem( USERITEM_NAME
);
1229 if ( aUserItem
>>= aTemp
)
1230 sUserData
= String( aTemp
);
1231 pTabPage
->SetUserData( sUserData
);
1232 Size aSiz
= pTabPage
->GetSizePixel();
1234 Size aCtrlSiz
= pTabCtrl
->GetTabPageSizePixel();
1235 // Only set Size on TabControl when < as TabPage
1236 if ( aCtrlSiz
.Width() < aSiz
.Width() ||
1237 aCtrlSiz
.Height() < aSiz
.Height() )
1239 pTabCtrl
->SetTabPageSizePixel( aSiz
);
1242 PageCreated( nId
, *pTabPage
);
1244 if ( pDataObject
->bOnDemand
)
1245 pTabPage
->Reset( (SfxItemSet
&)pTabPage
->GetItemSet() );
1247 pTabPage
->Reset( *pSet
);
1249 pTabCtrl
->SetTabPage( nId
, pTabPage
);
1251 else if ( pDataObject
->bRefresh
)
1252 pTabPage
->Reset( *pSet
);
1253 pDataObject
->bRefresh
= sal_False
;
1256 pTabPage
->ActivatePage( *pExampleSet
);
1257 sal_Bool bReadOnly
= pTabPage
->IsReadOnly();
1258 ( bReadOnly
|| pImpl
->bHideResetBtn
) ? aResetBtn
.Hide() : aResetBtn
.Show();
1262 // -----------------------------------------------------------------------
1264 IMPL_LINK( SfxTabDialog
, DeactivatePageHdl
, TabControl
*, pTabCtrl
)
1268 Handler that is called by StarView before leaving a page.
1272 <SfxTabPage::DeactivatePage(SfxItemSet *)>
1276 sal_uInt16 nId
= pTabCtrl
->GetCurPageId();
1278 SfxTabPage
*pPage
= dynamic_cast<SfxTabPage
*> (pTabCtrl
->GetTabPage( nId
));
1279 DBG_ASSERT( pPage
, "no active Page" );
1281 Data_Impl
* pDataObject
= Find( *pImpl
->pData
, pTabCtrl
->GetCurPageId() );
1282 DBG_ASSERT( pDataObject
, "no Data structur for current page" );
1283 if ( pPage
->HasExchangeSupport() && pDataObject
->bOnDemand
)
1285 DBG_WARNING( "Data exchange in ItemsOnDemand is not desired!" );
1289 int nRet
= SfxTabPage::LEAVE_PAGE
;
1291 if ( !pExampleSet
&& pPage
->HasExchangeSupport() && pSet
)
1292 pExampleSet
= new SfxItemSet( *pSet
->GetPool(), pSet
->GetRanges() );
1296 SfxItemSet
aTmp( *pSet
->GetPool(), pSet
->GetRanges() );
1298 if ( pPage
->HasExchangeSupport() )
1299 nRet
= pPage
->DeactivatePage( &aTmp
);
1301 nRet
= pPage
->DeactivatePage( NULL
);
1302 if ( ( SfxTabPage::LEAVE_PAGE
& nRet
) == SfxTabPage::LEAVE_PAGE
&&
1305 pExampleSet
->Put( aTmp
);
1306 pOutSet
->Put( aTmp
);
1311 if ( pPage
->HasExchangeSupport() ) //!!!
1315 SfxItemPool
* pPool
= pPage
->GetItemSet().GetPool();
1317 new SfxItemSet( *pPool
, GetInputRanges( *pPool
) );
1319 nRet
= pPage
->DeactivatePage( pExampleSet
);
1322 nRet
= pPage
->DeactivatePage( NULL
);
1325 if ( nRet
& SfxTabPage::REFRESH_SET
)
1327 pSet
= GetRefreshedSet();
1328 DBG_ASSERT( pSet
, "GetRefreshedSet() returns NULL" );
1329 // Flag all Pages as to be initialized as new
1330 const sal_uInt16 nCount
= pImpl
->pData
->Count();
1332 for ( sal_uInt16 i
= 0; i
< nCount
; ++i
)
1334 Data_Impl
* pObj
= (*pImpl
->pData
)[i
];
1336 if ( pObj
->pTabPage
!= pPage
) // Do not refresh own Page anymore
1337 pObj
->bRefresh
= sal_True
;
1339 pObj
->bRefresh
= sal_False
;
1342 if ( nRet
& SfxTabPage::LEAVE_PAGE
)
1348 // -----------------------------------------------------------------------
1350 void SfxTabDialog::ShowPage( sal_uInt16 nId
)
1354 The TabPage is activated with the specified Id.
1358 aTabCtrl
.SetCurPageId( nId
);
1359 ActivatePageHdl( &aTabCtrl
);
1362 // -----------------------------------------------------------------------
1364 const sal_uInt16
* SfxTabDialog::GetInputRanges( const SfxItemPool
& rPool
)
1368 Makes the set over the range of all pages of the dialogue. Pages have the
1369 static method for querying their range in AddTabPage, ie deliver their
1374 Pointer to a null-terminated array of sal_uInt16. This array belongs to the
1375 dialog and is deleted when the dialogue is destroy.
1379 <SfxTabDialog::AddTabPage(sal_uInt16, CreateTabPage, GetTabPageRanges, sal_Bool)>
1380 <SfxTabDialog::AddTabPage(sal_uInt16, const String &, CreateTabPage, GetTabPageRanges, sal_Bool, sal_uInt16)>
1381 <SfxTabDialog::AddTabPage(sal_uInt16, const Bitmap &, CreateTabPage, GetTabPageRanges, sal_Bool, sal_uInt16)>
1387 SAL_WARN( "sfx2.dialog", "Set already exists!" );
1388 return pSet
->GetRanges();
1393 std::vector
<sal_uInt16
> aUS
;
1394 sal_uInt16 nCount
= pImpl
->pData
->Count();
1397 for ( i
= 0; i
< nCount
; ++i
)
1399 Data_Impl
* pDataObject
= pImpl
->pData
->GetObject(i
);
1401 if ( pDataObject
->fnGetRanges
)
1403 const sal_uInt16
* pTmpRanges
= (pDataObject
->fnGetRanges
)();
1404 const sal_uInt16
* pIter
= pTmpRanges
;
1407 for( nLen
= 0; *pIter
; ++nLen
, ++pIter
)
1409 aUS
.insert( aUS
.end(), pTmpRanges
, pTmpRanges
+ nLen
);
1413 //! Remove duplicated Ids?
1415 nCount
= aUS
.size();
1417 for ( i
= 0; i
< nCount
; ++i
)
1418 aUS
[i
] = rPool
.GetWhich( aUS
[i
] );
1422 if ( aUS
.size() > 1 )
1424 std::sort( aUS
.begin(), aUS
.end() );
1427 pRanges
= new sal_uInt16
[aUS
.size() + 1];
1428 std::copy( aUS
.begin(), aUS
.end(), pRanges
);
1429 pRanges
[aUS
.size()] = 0;
1433 // -----------------------------------------------------------------------
1435 void SfxTabDialog::SetInputSet( const SfxItemSet
* pInSet
)
1439 With this method the Input-Set can subsequently be set initally or re-set.
1443 bool bSet
= ( pSet
!= NULL
);
1447 if ( !bSet
&& !pExampleSet
&& !pOutSet
)
1449 pExampleSet
= new SfxItemSet( *pSet
);
1450 pOutSet
= new SfxItemSet( *pSet
->GetPool(), pSet
->GetRanges() );
1454 long SfxTabDialog::Notify( NotifyEvent
& rNEvt
)
1456 if ( rNEvt
.GetType() == EVENT_GETFOCUS
)
1458 SfxViewFrame
* pViewFrame
= GetViewFrame() ? GetViewFrame() : SfxViewFrame::Current();
1461 Window
* pWindow
= rNEvt
.GetWindow();
1462 rtl::OString sHelpId
;
1463 while ( sHelpId
.isEmpty() && pWindow
)
1465 sHelpId
= pWindow
->GetHelpId();
1466 pWindow
= pWindow
->GetParent();
1469 if ( !sHelpId
.isEmpty() )
1470 SfxHelp::OpenHelpAgent( &pViewFrame
->GetFrame(), sHelpId
);
1474 return TabDialog::Notify( rNEvt
);
1477 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */