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 .
25 #include <appdata.hxx>
26 #include <comphelper/lok.hxx>
27 #include <sfxtypes.hxx>
28 #include <sfx2/tabdlg.hxx>
29 #include <sfx2/viewfrm.hxx>
30 #include <sfx2/app.hxx>
31 #include <sfx2/sfxresid.hxx>
32 #include <sfx2/sfxhelp.hxx>
33 #include <sfx2/ctrlitem.hxx>
34 #include <sfx2/bindings.hxx>
35 #include <sfx2/sfxdlg.hxx>
36 #include <sfx2/itemconnect.hxx>
37 #include <sfx2/viewsh.hxx>
38 #include <uitest/sfx_uiobject.hxx>
39 #include <unotools/viewoptions.hxx>
40 #include <vcl/builder.hxx>
41 #include <vcl/msgbox.hxx>
42 #include <vcl/IDialogRenderable.hxx>
44 #include <sfx2/strings.hrc>
47 using namespace ::com::sun::star::uno
;
49 #define USERITEM_NAME "UserItem"
55 sfx::ItemConnectionArray maItemConn
;
56 css::uno::Reference
< css::frame::XFrame
> mxFrame
;
58 TabPageImpl() : mbStandard( false ) {}
63 sal_uInt16 nId
; // The ID
64 CreateTabPage fnCreatePage
; // Pointer to Factory
65 GetTabPageRanges fnGetRanges
; // Pointer to Ranges-Function
66 VclPtr
<SfxTabPage
> pTabPage
; // The TabPage itself
67 bool bRefresh
; // Flag: Page must be re-initialized
70 Data_Impl( sal_uInt16 Id
, CreateTabPage fnPage
,
71 GetTabPageRanges fnRanges
) :
74 fnCreatePage( fnPage
),
75 fnGetRanges ( fnRanges
),
81 SfxAbstractDialogFactory
* pFact
= SfxAbstractDialogFactory::Create();
84 fnCreatePage
= pFact
->GetTabPageCreatorFunc( nId
);
85 fnGetRanges
= pFact
->GetTabPageRangesFunc( nId
);
91 SfxTabDialogItem::SfxTabDialogItem( const SfxTabDialogItem
& rAttr
, SfxItemPool
* pItemPool
)
92 : SfxSetItem( rAttr
, pItemPool
)
96 SfxTabDialogItem::SfxTabDialogItem( sal_uInt16 nId
, const SfxItemSet
& rItemSet
)
97 : SfxSetItem( nId
, rItemSet
)
101 SfxPoolItem
* SfxTabDialogItem::Clone(SfxItemPool
* pToPool
) const
103 return new SfxTabDialogItem( *this, pToPool
);
106 SfxPoolItem
* SfxTabDialogItem::Create(SvStream
& /*rStream*/, sal_uInt16
/*nVersion*/) const
108 OSL_FAIL( "Use it only in UI!" );
112 typedef std::vector
<Data_Impl
*> SfxTabDlgData_Impl
;
118 SfxTabDlgData_Impl aData
;
120 explicit TabDlg_Impl( sal_uInt8 nCnt
) :
122 bHideResetBtn ( false )
124 aData
.reserve( nCnt
);
129 static Data_Impl
* Find( const SfxTabDlgData_Impl
& rArr
, sal_uInt16 nId
, sal_uInt16
* pPos
= nullptr)
131 const sal_uInt16 nCount
= rArr
.size();
133 for ( sal_uInt16 i
= 0; i
< nCount
; ++i
)
135 Data_Impl
* pObj
= rArr
[i
];
137 if ( pObj
->nId
== nId
)
147 void SfxTabPage::SetFrame(const css::uno::Reference
< css::frame::XFrame
>& xFrame
)
150 pImpl
->mxFrame
= xFrame
;
153 css::uno::Reference
< css::frame::XFrame
> SfxTabPage::GetFrame()
156 return pImpl
->mxFrame
;
157 return css::uno::Reference
< css::frame::XFrame
>();
160 SfxTabPage::SfxTabPage(vcl::Window
*pParent
, const OString
& rID
, const OUString
& rUIXMLDescription
, const SfxItemSet
*rAttrSet
)
161 : TabPage(pParent
, rID
, rUIXMLDescription
)
163 , bHasExchangeSupport ( false )
164 , pImpl ( new TabPageImpl
)
168 SfxTabPage::~SfxTabPage()
173 void SfxTabPage::dispose()
179 bool SfxTabPage::FillItemSet( SfxItemSet
* rSet
)
181 return pImpl
->maItemConn
.DoFillItemSet( *rSet
, GetItemSet() );
184 void SfxTabPage::Reset( const SfxItemSet
* rSet
)
186 pImpl
->maItemConn
.DoApplyFlags( rSet
);
187 pImpl
->maItemConn
.DoReset( rSet
);
190 void SfxTabPage::ActivatePage( const SfxItemSet
& )
193 Default implementation of the virtual ActivatePage method. This method is
194 called when a page of dialogue supports the exchange of data between pages.
195 <SfxTabPage::DeactivatePage(SfxItemSet *)>
200 DeactivateRC
SfxTabPage::DeactivatePage( SfxItemSet
* )
204 Default implementation of the virtual DeactivatePage method. This method is
205 called by Sfx when leaving a page; the application can, through the return
206 value, control whether to leave the page. If the page is displayed through
207 bHasExchangeSupport which supports data exchange between pages, then a
208 pointer to the exchange set is passed as parameter. This takes on data for
209 the exchange, then the set is available as a parameter in
210 <SfxTabPage::ActivatePage(const SfxItemSet &)>.
214 DeactivateRC::LeavePage; Allow leaving the page
218 return DeactivateRC::LeavePage
;
222 void SfxTabPage::FillUserData()
226 Virtual method is called by the base class in the destructor to save
227 specific information of the TabPage in the ini-file. When overriding a
228 string must be compiled, which is then flushed with the <SetUserData()>.
235 bool SfxTabPage::IsReadOnly() const
241 const SfxPoolItem
* SfxTabPage::GetItem( const SfxItemSet
& rSet
, sal_uInt16 nSlot
, bool bDeep
)
245 static Method: hereby are the implementations of the TabPage code
250 const SfxItemPool
* pPool
= rSet
.GetPool();
251 sal_uInt16 nWh
= pPool
->GetWhich( nSlot
, bDeep
);
252 const SfxPoolItem
* pItem
= nullptr;
253 rSet
.GetItemState( nWh
, true, &pItem
);
255 if ( !pItem
&& nWh
!= nSlot
)
256 pItem
= &pPool
->GetDefaultItem( nWh
);
261 const SfxPoolItem
* SfxTabPage::GetOldItem( const SfxItemSet
& rSet
,
262 sal_uInt16 nSlot
, bool bDeep
)
266 This method returns an attribute for comparison of the old value.
270 const SfxItemSet
& rOldSet
= GetItemSet();
271 sal_uInt16 nWh
= GetWhich( nSlot
, bDeep
);
272 const SfxPoolItem
* pItem
= nullptr;
274 if ( pImpl
->mbStandard
&& rOldSet
.GetParent() )
275 pItem
= GetItem( *rOldSet
.GetParent(), nSlot
);
276 else if ( rSet
.GetParent() &&
277 SfxItemState::DONTCARE
== rSet
.GetItemState( nWh
) )
278 pItem
= GetItem( *rSet
.GetParent(), nSlot
);
280 pItem
= GetItem( rOldSet
, nSlot
);
284 void SfxTabPage::PageCreated( const SfxAllItemSet
& /*aSet*/ )
286 SAL_WARN( "sfx.dialog", "SfxTabPage::PageCreated should not be called");
289 void SfxTabPage::ChangesApplied()
293 void SfxTabPage::AddItemConnection( sfx::ItemConnectionBase
* pConnection
)
295 pImpl
->maItemConn
.AddConnection( pConnection
);
298 SfxTabDialog
* SfxTabPage::GetTabDialog() const
300 return dynamic_cast<SfxTabDialog
*>(GetParentDialog());
304 SfxTabDialog::SfxTabDialog
308 Constructor, temporary without Frame
312 vcl::Window
* pParent
, // Parent Window
313 const OUString
& rID
, const OUString
& rUIXMLDescription
, //Dialog Name, Dialog .ui path
314 const SfxItemSet
* pItemSet
, // Itemset with the data;
315 // can be NULL, when Pages are onDemand
316 bool bEditFmt
// when yes -> additional Button for standard
318 : TabDialog(pParent
, rID
, rUIXMLDescription
)
319 , m_pSet(pItemSet
? new SfxItemSet(*pItemSet
) : nullptr)
322 , m_nAppPageId(USHRT_MAX
)
323 , m_bStandardPushed(false)
324 , m_pExampleSet(nullptr)
328 sal_uInt16 nPageCount
= m_pTabCtrl
->GetPageCount();
329 for (sal_uInt16 nPage
= 0; nPage
< nPageCount
; ++nPage
)
331 sal_uInt16 nPageId
= m_pTabCtrl
->GetPageId(nPage
);
332 m_pTabCtrl
->SetTabPage(nPageId
, nullptr);
336 SfxTabDialog::~SfxTabDialog()
341 void SfxTabDialog::dispose()
345 for ( SfxTabDlgData_Impl::const_iterator it
= m_pImpl
->aData
.begin(); it
!= m_pImpl
->aData
.end(); ++it
)
347 Data_Impl
* pDataObject
= *it
;
349 if ( pDataObject
->pTabPage
)
351 // save settings of all pages (user data)
352 pDataObject
->pTabPage
->FillUserData();
353 OUString
aPageData( pDataObject
->pTabPage
->GetUserData() );
354 if ( !aPageData
.isEmpty() )
356 // save settings of all pages (user data)
357 OUString sConfigId
= OStringToOUString(pDataObject
->pTabPage
->GetConfigId(),
358 RTL_TEXTENCODING_UTF8
);
359 if (sConfigId
.isEmpty())
361 SAL_WARN("sfx.dialog", "Tabpage needs to be converted to .ui format");
362 sConfigId
= OUString::number(pDataObject
->nId
);
365 SvtViewOptions
aPageOpt(EViewType::TabPage
, sConfigId
);
366 aPageOpt
.SetUserItem( USERITEM_NAME
, makeAny( aPageData
) );
369 pDataObject
->pTabPage
.disposeAndClear();
372 pDataObject
= nullptr;
380 delete m_pExampleSet
;
381 m_pExampleSet
= nullptr;
385 if (m_bOwnsBaseFmtBtn
)
386 m_pBaseFmtBtn
.disposeAndClear();
388 m_pResetBtn
.disposeAndClear();
390 m_pHelpBtn
.disposeAndClear();
391 if (m_bOwnsCancelBtn
)
392 m_pCancelBtn
.disposeAndClear();
394 m_pOKBtn
.disposeAndClear();
400 m_pCancelBtn
.clear();
403 m_pBaseFmtBtn
.clear();
404 m_pActionArea
.clear();
406 TabDialog::dispose();
409 void SfxTabDialog::Init_Impl(bool bFmtFlag
)
412 internal initialization of the dialogue
415 m_pBox
= get_content_area();
417 m_pUIBuilder
->get(m_pTabCtrl
, "tabcontrol");
419 m_pImpl
.reset( new TabDlg_Impl(m_pTabCtrl
->GetPageCount()) );
421 m_pActionArea
= get_action_area();
422 assert(m_pActionArea
);
424 m_pOKBtn
= m_pUIBuilder
->get
<PushButton
>("ok");
425 m_bOwnsOKBtn
= m_pOKBtn
== nullptr;
427 m_pOKBtn
= VclPtr
<OKButton
>::Create(m_pActionArea
);
429 m_pApplyBtn
= m_pUIBuilder
->get
<PushButton
>("apply");
430 m_pUserBtn
= m_pUIBuilder
->get
<PushButton
>("user");
431 m_pCancelBtn
= m_pUIBuilder
->get
<CancelButton
>("cancel");
432 m_bOwnsCancelBtn
= m_pCancelBtn
== nullptr;
433 if (m_bOwnsCancelBtn
)
434 m_pCancelBtn
= VclPtr
<CancelButton
>::Create(m_pActionArea
);
436 m_pHelpBtn
= m_pUIBuilder
->get
<HelpButton
>("help");
437 m_bOwnsHelpBtn
= m_pHelpBtn
== nullptr;
439 m_pHelpBtn
= VclPtr
<HelpButton
>::Create(m_pActionArea
);
441 m_pResetBtn
= m_pUIBuilder
->get
<PushButton
>("reset");
442 m_bOwnsResetBtn
= m_pResetBtn
== nullptr;
445 m_pResetBtn
= VclPtr
<PushButton
>::Create(m_pActionArea
.get());
446 m_pResetBtn
->set_id("reset");
449 m_pImpl
->bHideResetBtn
= !m_pResetBtn
->IsVisible();
451 m_pBaseFmtBtn
= m_pUIBuilder
->get
<PushButton
>("standard");
452 m_bOwnsBaseFmtBtn
= m_pBaseFmtBtn
== nullptr;
453 if (m_bOwnsBaseFmtBtn
)
455 m_pBaseFmtBtn
= VclPtr
<PushButton
>::Create(m_pActionArea
.get());
456 m_pBaseFmtBtn
->set_id("standard");
459 m_pOKBtn
->SetClickHdl( LINK( this, SfxTabDialog
, OkHdl
) );
460 m_pCancelBtn
->SetClickHdl( LINK( this, SfxTabDialog
, CancelHdl
) );
461 m_pResetBtn
->SetClickHdl( LINK( this, SfxTabDialog
, ResetHdl
) );
462 m_pResetBtn
->SetText( SfxResId( STR_RESET
) );
463 m_pTabCtrl
->SetActivatePageHdl(
464 LINK( this, SfxTabDialog
, ActivatePageHdl
) );
465 m_pTabCtrl
->SetDeactivatePageHdl(
466 LINK( this, SfxTabDialog
, DeactivatePageHdl
) );
467 m_pActionArea
->Show();
471 m_pCancelBtn
->Show();
474 m_pResetBtn
->SetHelpId( HID_TABDLG_RESET_BTN
);
478 m_pUserBtn
->SetClickHdl( LINK( this, SfxTabDialog
, UserHdl
) );
484 m_pBaseFmtBtn
->SetText( SfxResId( STR_STANDARD_SHORTCUT
) );
485 m_pBaseFmtBtn
->SetClickHdl( LINK( this, SfxTabDialog
, BaseFmtHdl
) );
486 m_pBaseFmtBtn
->SetHelpId( HID_TABDLG_STANDARD_BTN
);
487 m_pBaseFmtBtn
->Show();
492 m_pExampleSet
= new SfxItemSet( *m_pSet
);
493 m_pOutSet
= new SfxItemSet( *m_pSet
->GetPool(), m_pSet
->GetRanges() );
497 void SfxTabDialog::RemoveResetButton()
500 m_pImpl
->bHideResetBtn
= true;
503 void SfxTabDialog::RemoveStandardButton()
505 m_pBaseFmtBtn
->Hide();
508 short SfxTabDialog::Execute()
510 if ( !m_pTabCtrl
->GetPageCount() )
514 return TabDialog::Execute();
517 bool SfxTabDialog::StartExecuteAsync( VclAbstractDialog::AsyncContext
&rCtx
)
519 if ( !m_pTabCtrl
->GetPageCount() )
521 rCtx
.mxOwner
.disposeAndClear();
525 return TabDialog::StartExecuteAsync( rCtx
);
528 void SfxTabDialog::StartExecuteModal( const Link
<Dialog
&,void>& rEndDialogHdl
)
530 if ( !m_pTabCtrl
->GetPageCount() )
533 TabDialog::StartExecuteModal( rEndDialogHdl
);
537 void SfxTabDialog::Start()
539 m_pImpl
->bModal
= false;
544 if ( IsVisible() && ( !HasChildPathFocus() || HasFocus() ) )
545 GrabFocusToFirstControl();
549 void SfxTabDialog::SetApplyHandler(const Link
<Button
*, void>& _rHdl
)
551 DBG_ASSERT( m_pApplyBtn
, "SfxTabDialog::GetApplyHandler: no apply button enabled!" );
553 m_pApplyBtn
->SetClickHdl( _rHdl
);
557 void SfxTabDialog::Start_Impl()
559 assert(m_pImpl
->aData
.size() == m_pTabCtrl
->GetPageCount()
560 && "not all pages registered");
561 sal_uInt16 nActPage
= m_pTabCtrl
->GetPageId( 0 );
563 // load old settings, when exists
564 SvtViewOptions
aDlgOpt(EViewType::TabDialog
, OStringToOUString(GetHelpId(),RTL_TEXTENCODING_UTF8
));
565 if ( aDlgOpt
.Exists() )
567 SetWindowState(OUStringToOString(aDlgOpt
.GetWindowState(), RTL_TEXTENCODING_ASCII_US
));
569 // initial TabPage from Program/Help/config
570 nActPage
= static_cast<sal_uInt16
>(aDlgOpt
.GetPageID());
572 if ( USHRT_MAX
!= m_nAppPageId
)
573 nActPage
= m_nAppPageId
;
575 if ( TAB_PAGE_NOTFOUND
== m_pTabCtrl
->GetPagePos( nActPage
) )
576 nActPage
= m_pTabCtrl
->GetPageId( 0 );
578 else if ( USHRT_MAX
!= m_nAppPageId
&& TAB_PAGE_NOTFOUND
!= m_pTabCtrl
->GetPagePos( m_nAppPageId
) )
579 nActPage
= m_nAppPageId
;
581 m_pTabCtrl
->SetCurPageId( nActPage
);
582 ActivatePageHdl( m_pTabCtrl
);
585 void SfxTabDialog::AddTabPage( sal_uInt16 nId
, const OUString
&rRiderText
)
587 AddTabPage( nId
, rRiderText
, nullptr, nullptr );
591 Adds a page to the dialog. The Name must correspond to a entry in the
592 TabControl in the dialog .ui
594 sal_uInt16
SfxTabDialog::AddTabPage
596 const OString
&rName
, // Page ID
597 CreateTabPage pCreateFunc
, // Pointer to the Factory Method
598 GetTabPageRanges pRangesFunc
// Pointer to the Method for querying
602 sal_uInt16 nId
= m_pTabCtrl
->GetPageId(rName
);
603 m_pImpl
->aData
.push_back(
604 new Data_Impl( nId
, pCreateFunc
, pRangesFunc
) );
609 Adds a page to the dialog. The Name must correspond to a entry in the
610 TabControl in the dialog .ui
612 sal_uInt16
SfxTabDialog::AddTabPage
614 const OString
&rName
, // Page ID
615 sal_uInt16 nPageCreateId
// Identifier of the Factory Method to create the page
618 SfxAbstractDialogFactory
* pFact
= SfxAbstractDialogFactory::Create();
620 CreateTabPage pCreateFunc
= pFact
->GetTabPageCreatorFunc(nPageCreateId
);
622 GetTabPageRanges pRangesFunc
= pFact
->GetTabPageRangesFunc(nPageCreateId
);
623 sal_uInt16 nPageId
= m_pTabCtrl
->GetPageId(rName
);
624 m_pImpl
->aData
.push_back(new Data_Impl(nPageId
, pCreateFunc
, pRangesFunc
));
629 void SfxTabDialog::AddTabPage
633 Add a page to the dialog. The Rider text is passed on, the page has no
634 counterpart in the TabControl in the resource of the dialogue.
639 const OUString
& rRiderText
,
640 CreateTabPage pCreateFunc
,
641 GetTabPageRanges pRangesFunc
,
645 DBG_ASSERT( TAB_PAGE_NOTFOUND
== m_pTabCtrl
->GetPagePos( nId
),
646 "Double Page-Ids in the Tabpage" );
647 m_pTabCtrl
->InsertPage( nId
, rRiderText
, nPos
);
648 m_pImpl
->aData
.push_back( new Data_Impl( nId
, pCreateFunc
, pRangesFunc
) );
651 void SfxTabDialog::RemoveTabPage( sal_uInt16 nId
)
655 Delete the TabPage with ID nId
660 m_pTabCtrl
->RemovePage( nId
);
661 Data_Impl
* pDataObject
= Find( m_pImpl
->aData
, nId
, &nPos
);
665 if ( pDataObject
->pTabPage
)
667 pDataObject
->pTabPage
->FillUserData();
668 OUString
aPageData( pDataObject
->pTabPage
->GetUserData() );
669 if ( !aPageData
.isEmpty() )
671 // save settings of this page (user data)
672 OUString sConfigId
= OStringToOUString(pDataObject
->pTabPage
->GetConfigId(),
673 RTL_TEXTENCODING_UTF8
);
674 if (sConfigId
.isEmpty())
676 SAL_WARN("sfx.dialog", "Tabpage needs to be converted to .ui format");
677 sConfigId
= OUString::number(pDataObject
->nId
);
680 SvtViewOptions
aPageOpt(EViewType::TabPage
, sConfigId
);
681 aPageOpt
.SetUserItem( USERITEM_NAME
, makeAny( aPageData
) );
684 pDataObject
->pTabPage
.disposeAndClear();
688 m_pImpl
->aData
.erase( m_pImpl
->aData
.begin() + nPos
);
692 SAL_INFO( "sfx.dialog", "TabPage-Id not known" );
696 void SfxTabDialog::RemoveTabPage(const OString
&rName
)
698 RemoveTabPage(m_pTabCtrl
->GetPageId(rName
));
702 void SfxTabDialog::PageCreated
706 Default implementation of the virtual method. This is called immediately
707 after creating a page. Here the dialogue can call the TabPage Method
712 sal_uInt16
, // Id of the created page
713 SfxTabPage
& // Reference to the created page
719 SfxItemSet
* SfxTabDialog::GetInputSetImpl()
723 Derived classes may create new storage for the InputSet. This has to be
724 released in the Destructor. To do this, this method must be called.
732 SfxTabPage
* SfxTabDialog::GetTabPage( sal_uInt16 nPageId
) const
736 Return TabPage with the specified Id.
741 Data_Impl
* pDataObject
= Find( m_pImpl
->aData
, nPageId
, &nPos
);
744 return pDataObject
->pTabPage
;
748 void SfxTabDialog::SavePosAndId()
750 // save settings (screen position and current page)
751 SvtViewOptions
aDlgOpt(EViewType::TabDialog
, OStringToOUString(GetHelpId(),RTL_TEXTENCODING_UTF8
));
752 aDlgOpt
.SetWindowState(OStringToOUString(GetWindowState(WindowStateMask::Pos
),RTL_TEXTENCODING_ASCII_US
));
753 // to-do replace with name of page when all pages are converted to .ui
754 aDlgOpt
.SetPageID( m_pTabCtrl
->GetCurPageId() );
758 short SfxTabDialog::Ok()
762 Ok handler for the Dialogue.
764 Dialog's current location and current page are saved for the next time
767 The OutputSet is created and for each page this or the special OutputSet
768 is set by calling the method <SfxTabPage::FillItemSet(SfxItemSet &)>, to
769 insert the entered data by the user into the set.
773 RET_OK: if at least one page has returned from FillItemSet,
774 otherwise RET_CANCEL.
777 SavePosAndId(); //See fdo#38828 "Apply" resetting window position
781 if ( !m_pExampleSet
&& m_pSet
)
782 m_pOutSet
= m_pSet
->Clone( false ); // without Items
783 else if ( m_pExampleSet
)
784 m_pOutSet
= new SfxItemSet( *m_pExampleSet
);
786 bool bModified
= false;
788 for ( SfxTabDlgData_Impl::const_iterator it
= m_pImpl
->aData
.begin(); it
!= m_pImpl
->aData
.end(); ++it
)
790 Data_Impl
* pDataObject
= *it
;
791 SfxTabPage
* pTabPage
= pDataObject
->pTabPage
;
795 if ( m_pSet
&& !pTabPage
->HasExchangeSupport() )
797 SfxItemSet
aTmp( *m_pSet
->GetPool(), m_pSet
->GetRanges() );
799 if ( pTabPage
->FillItemSet( &aTmp
) )
803 m_pExampleSet
->Put( aTmp
);
804 m_pOutSet
->Put( aTmp
);
810 if ( m_pOutSet
&& m_pOutSet
->Count() > 0 )
813 if (m_bStandardPushed
)
815 return bModified
? RET_OK
: RET_CANCEL
;
818 IMPL_LINK_NOARG(SfxTabDialog
, CancelHdl
, Button
*, void)
820 EndDialog( RET_USER_CANCEL
);
824 SfxItemSet
* SfxTabDialog::CreateInputItemSet( sal_uInt16
)
828 Default implementation of the virtual Method.
829 This is called when pages create their sets onDemand.
833 SAL_WARN( "sfx.dialog", "CreateInputItemSet not implemented" );
834 return new SfxAllItemSet( SfxGetpApp()->GetPool() );
838 void SfxTabDialog::RefreshInputSet()
842 Default implementation of the virtual Method.
843 This is called, when <SfxTabPage::DeactivatePage(SfxItemSet *)>
844 returns <DeactivateRC::RefreshSet>.
848 SAL_INFO ( "sfx.dialog", "RefreshInputSet not implemented" );
852 IMPL_LINK_NOARG(SfxTabDialog
, OkHdl
, Button
*, void)
856 Handler of the Ok-Buttons
857 This calls the current page <SfxTabPage::DeactivatePage(SfxItemSet *)>.
858 Returns <DeactivateRC::LeavePage>, <SfxTabDialog::Ok()> is called
859 and the Dialog is ended.
863 if (PrepareLeaveCurrentPage())
865 if ( m_pImpl
->bModal
)
875 bool SfxTabDialog::Apply()
877 bool bApplied
= false;
878 if (PrepareLeaveCurrentPage())
880 bApplied
= (Ok() == RET_OK
);
881 //let the pages update their saved values
882 GetInputSetImpl()->Put(*GetOutputItemSet());
883 sal_uInt16 pageCount
= m_pTabCtrl
->GetPageCount();
884 for (sal_uInt16 pageIdx
= 0; pageIdx
< pageCount
; ++pageIdx
)
886 SfxTabPage
* pPage
= dynamic_cast<SfxTabPage
*> (m_pTabCtrl
->GetTabPage(m_pTabCtrl
->GetPageId(pageIdx
)));
888 pPage
->ChangesApplied();
895 bool SfxTabDialog::PrepareLeaveCurrentPage()
897 sal_uInt16
const nId
= m_pTabCtrl
->GetCurPageId();
898 SfxTabPage
* pPage
= dynamic_cast<SfxTabPage
*> (m_pTabCtrl
->GetTabPage( nId
));
903 DeactivateRC nRet
= DeactivateRC::LeavePage
;
906 SfxItemSet
aTmp( *m_pSet
->GetPool(), m_pSet
->GetRanges() );
908 if ( pPage
->HasExchangeSupport() )
909 nRet
= pPage
->DeactivatePage( &aTmp
);
911 nRet
= pPage
->DeactivatePage( nullptr );
913 if ( ( DeactivateRC::LeavePage
& nRet
) == DeactivateRC::LeavePage
916 m_pExampleSet
->Put( aTmp
);
917 m_pOutSet
->Put( aTmp
);
921 nRet
= pPage
->DeactivatePage( nullptr );
922 bEnd
= nRet
!= DeactivateRC::KeepPage
;
929 IMPL_LINK_NOARG(SfxTabDialog
, UserHdl
, Button
*, void)
933 Handler of the User-Buttons
934 This calls the current page <SfxTabPage::DeactivatePage(SfxItemSet *)>.
935 returns this <DeactivateRC::LeavePage> and <SfxTabDialog::Ok()> is called.
936 Then the Dialog is ended with the Return value <SfxTabDialog::Ok()>
940 if ( PrepareLeaveCurrentPage () )
944 if ( RET_OK
== nRet
)
947 nRet
= RET_USER_CANCEL
;
953 IMPL_LINK_NOARG(SfxTabDialog
, ResetHdl
, Button
*, void)
957 Handler behind the reset button.
958 The Current Page is new initialized with their initial data, all the
959 settings that the user has made on this page are repealed.
963 const sal_uInt16 nId
= m_pTabCtrl
->GetCurPageId();
964 Data_Impl
* pDataObject
= Find( m_pImpl
->aData
, nId
);
965 DBG_ASSERT( pDataObject
, "Id not known" );
967 pDataObject
->pTabPage
->Reset( m_pSet
);
971 IMPL_LINK_NOARG(SfxTabDialog
, BaseFmtHdl
, Button
*, void)
975 Handler behind the Standard-Button.
976 This button is available when editing style sheets. All the set attributes
977 in the edited stylesheet are deleted.
981 m_bStandardPushed
= true;
983 const sal_uInt16 nId
= m_pTabCtrl
->GetCurPageId();
984 Data_Impl
* pDataObject
= Find( m_pImpl
->aData
, nId
);
985 DBG_ASSERT( pDataObject
, "Id not known" );
987 if ( pDataObject
->fnGetRanges
)
989 if ( !m_pExampleSet
)
990 m_pExampleSet
= new SfxItemSet( *m_pSet
);
992 const SfxItemPool
* pPool
= m_pSet
->GetPool();
993 const sal_uInt16
* pTmpRanges
= (pDataObject
->fnGetRanges
)();
994 SfxItemSet
aTmpSet( *m_pExampleSet
);
996 while ( *pTmpRanges
)
998 const sal_uInt16
* pU
= pTmpRanges
+ 1;
1000 if ( *pTmpRanges
== *pU
)
1002 // Range which two identical values -> only set one Item
1003 sal_uInt16 nWh
= pPool
->GetWhich( *pTmpRanges
);
1004 m_pExampleSet
->ClearItem( nWh
);
1005 aTmpSet
.ClearItem( nWh
);
1006 // At the Outset of InvalidateItem,
1007 // so that the change takes effect
1008 m_pOutSet
->InvalidateItem( nWh
);
1012 // Correct Range with multiple values
1013 sal_uInt16 nTmp
= *pTmpRanges
, nTmpEnd
= *pU
;
1014 DBG_ASSERT( nTmp
<= nTmpEnd
, "Range is sorted the wrong way" );
1016 if ( nTmp
> nTmpEnd
)
1018 // If really sorted wrongly, then set new
1019 sal_uInt16 nTmp1
= nTmp
;
1024 while ( nTmp
<= nTmpEnd
)
1026 // Iterate over the Range and set the Items
1027 sal_uInt16 nWh
= pPool
->GetWhich( nTmp
);
1028 m_pExampleSet
->ClearItem( nWh
);
1029 aTmpSet
.ClearItem( nWh
);
1030 // At the Outset of InvalidateItem,
1031 // so that the change takes effect
1032 m_pOutSet
->InvalidateItem( nWh
);
1036 // Go to the next pair
1039 // Set all Items as new -> the call the current Page Reset()
1040 DBG_ASSERT( pDataObject
->pTabPage
, "the Page is gone" );
1041 pDataObject
->pTabPage
->Reset( &aTmpSet
);
1042 pDataObject
->pTabPage
->pImpl
->mbStandard
= true;
1047 IMPL_LINK( SfxTabDialog
, ActivatePageHdl
, TabControl
*, pTabCtrl
, void )
1051 Handler that is called by StarView for switching to a different page.
1052 If the page not exist yet then it is created and the virtual Method
1053 <SfxTabDialog::PageCreated( sal_uInt16, SfxTabPage &)> is called. If the page
1054 exist, then the if possible the <SfxTabPage::Reset(const SfxItemSet &)> or
1055 <SfxTabPage::ActivatePage(const SfxItemSet &)> is called.
1059 sal_uInt16 nId
= pTabCtrl
->GetCurPageId();
1061 DBG_ASSERT( m_pImpl
->aData
.size(), "no Pages registered" );
1063 // Tab Page already there?
1064 VclPtr
<SfxTabPage
> pTabPage
= dynamic_cast<SfxTabPage
*> (pTabCtrl
->GetTabPage( nId
));
1065 Data_Impl
* pDataObject
= Find( m_pImpl
->aData
, nId
);
1067 // fallback to 1st page when requested one does not exist
1068 if(!pDataObject
&& pTabCtrl
->GetPageCount())
1070 pTabCtrl
->SetCurPageId(pTabCtrl
->GetPageId(0));
1071 nId
= pTabCtrl
->GetCurPageId();
1072 pTabPage
= dynamic_cast< SfxTabPage
* >(pTabCtrl
->GetTabPage(nId
));
1073 pDataObject
= Find(m_pImpl
->aData
, nId
);
1078 SAL_WARN("sfx.dialog", "Tab Page ID not known, this is pretty serious and needs investigation");
1082 // Create TabPage if possible:
1086 pTabPage
= (pDataObject
->fnCreatePage
)( pTabCtrl
, m_pSet
);
1088 pTabPage
= (pDataObject
->fnCreatePage
)
1089 ( pTabCtrl
, CreateInputItemSet( nId
) );
1090 DBG_ASSERT( nullptr == pDataObject
->pTabPage
, "create TabPage more than once" );
1091 pDataObject
->pTabPage
= pTabPage
;
1093 OUString sConfigId
= OStringToOUString(pTabPage
->GetConfigId(), RTL_TEXTENCODING_UTF8
);
1094 if (sConfigId
.isEmpty())
1096 SAL_WARN("sfx.dialog", "Tabpage needs to be converted to .ui format");
1097 sConfigId
= OUString::number(pDataObject
->nId
);
1099 SvtViewOptions
aPageOpt(EViewType::TabPage
, sConfigId
);
1101 Any aUserItem
= aPageOpt
.GetUserItem( USERITEM_NAME
);
1103 if ( aUserItem
>>= aTemp
)
1105 pTabPage
->SetUserData( sUserData
);
1106 Size aSiz
= pTabPage
->GetSizePixel();
1108 Size aCtrlSiz
= pTabCtrl
->GetTabPageSizePixel();
1109 // Only set Size on TabControl when < as TabPage
1110 if ( aCtrlSiz
.Width() < aSiz
.Width() ||
1111 aCtrlSiz
.Height() < aSiz
.Height() )
1113 pTabCtrl
->SetTabPageSizePixel( aSiz
);
1116 PageCreated( nId
, *pTabPage
);
1118 pTabPage
->Reset( m_pSet
);
1120 pTabCtrl
->SetTabPage( nId
, pTabPage
);
1122 else if ( pDataObject
->bRefresh
)
1123 pTabPage
->Reset( m_pSet
);
1124 pDataObject
->bRefresh
= false;
1126 if ( m_pExampleSet
)
1127 pTabPage
->ActivatePage( *m_pExampleSet
);
1129 if ( pTabPage
->IsReadOnly() || m_pImpl
->bHideResetBtn
)
1130 m_pResetBtn
->Hide();
1132 m_pResetBtn
->Show();
1136 IMPL_LINK( SfxTabDialog
, DeactivatePageHdl
, TabControl
*, pTabCtrl
, bool )
1140 Handler that is called by StarView before leaving a page.
1144 <SfxTabPage::DeactivatePage(SfxItemSet *)>
1148 sal_uInt16 nId
= pTabCtrl
->GetCurPageId();
1149 SfxTabPage
*pPage
= dynamic_cast<SfxTabPage
*> (pTabCtrl
->GetTabPage( nId
));
1150 DBG_ASSERT( pPage
, "no active Page" );
1154 Data_Impl
* pDataObject
= Find( m_pImpl
->aData
, pTabCtrl
->GetCurPageId() );
1155 DBG_ASSERT( pDataObject
, "no Data structure for current page" );
1158 DeactivateRC nRet
= DeactivateRC::LeavePage
;
1160 if ( !m_pExampleSet
&& pPage
->HasExchangeSupport() && m_pSet
)
1161 m_pExampleSet
= new SfxItemSet( *m_pSet
->GetPool(), m_pSet
->GetRanges() );
1165 SfxItemSet
aTmp( *m_pSet
->GetPool(), m_pSet
->GetRanges() );
1167 if ( pPage
->HasExchangeSupport() )
1168 nRet
= pPage
->DeactivatePage( &aTmp
);
1170 nRet
= pPage
->DeactivatePage( nullptr );
1171 if ( ( DeactivateRC::LeavePage
& nRet
) == DeactivateRC::LeavePage
&&
1172 aTmp
.Count() && m_pExampleSet
)
1174 m_pExampleSet
->Put( aTmp
);
1175 m_pOutSet
->Put( aTmp
);
1180 if ( pPage
->HasExchangeSupport() ) //!!!
1182 if ( !m_pExampleSet
)
1184 SfxItemPool
* pPool
= pPage
->GetItemSet().GetPool();
1186 new SfxItemSet( *pPool
, GetInputRanges( *pPool
) );
1188 nRet
= pPage
->DeactivatePage( m_pExampleSet
);
1191 nRet
= pPage
->DeactivatePage( nullptr );
1194 if ( nRet
& DeactivateRC::RefreshSet
)
1197 // Flag all Pages as to be initialized as new
1199 for ( SfxTabDlgData_Impl::const_iterator it
= m_pImpl
->aData
.begin(); it
!= m_pImpl
->aData
.end(); ++it
)
1201 Data_Impl
* pObj
= *it
;
1203 if ( pObj
->pTabPage
.get() != pPage
) // Do not refresh own Page anymore
1204 pObj
->bRefresh
= true;
1206 pObj
->bRefresh
= false;
1209 return static_cast<bool>(nRet
& DeactivateRC::LeavePage
);
1213 void SfxTabDialog::ShowPage( sal_uInt16 nId
)
1217 The TabPage is activated with the specified Id.
1221 m_pTabCtrl
->SetCurPageId( nId
);
1222 ActivatePageHdl( m_pTabCtrl
);
1225 OString
SfxTabDialog::GetScreenshotId() const
1227 SfxTabPage
*pActiveTabPage
= GetCurTabPage();
1228 OString aScreenshotId
= GetHelpId();
1230 if ( pActiveTabPage
)
1232 vcl::Window
* pToplevelBox
= pActiveTabPage
->GetWindow( GetWindowType::FirstChild
);
1235 aScreenshotId
= pToplevelBox
->GetHelpId();
1238 return aScreenshotId
;
1241 const sal_uInt16
* SfxTabDialog::GetInputRanges( const SfxItemPool
& rPool
)
1245 Makes the set over the range of all pages of the dialogue. Pages have the
1246 static method for querying their range in AddTabPage, ie deliver their
1251 Pointer to a null-terminated array of sal_uInt16. This array belongs to the
1252 dialog and is deleted when the dialogue is destroy.
1256 <SfxTabDialog::AddTabPage(sal_uInt16, CreateTabPage, GetTabPageRanges, bool)>
1257 <SfxTabDialog::AddTabPage(sal_uInt16, const String &, CreateTabPage, GetTabPageRanges, bool, sal_uInt16)>
1258 <SfxTabDialog::AddTabPage(sal_uInt16, const Bitmap &, CreateTabPage, GetTabPageRanges, bool, sal_uInt16)>
1264 SAL_WARN( "sfx.dialog", "Set already exists!" );
1265 return m_pSet
->GetRanges();
1270 std::vector
<sal_uInt16
> aUS
;
1272 for ( SfxTabDlgData_Impl::const_iterator it
= m_pImpl
->aData
.begin(); it
!= m_pImpl
->aData
.end(); ++it
)
1274 Data_Impl
* pDataObject
= *it
;
1276 if ( pDataObject
->fnGetRanges
)
1278 const sal_uInt16
* pTmpRanges
= (pDataObject
->fnGetRanges
)();
1279 const sal_uInt16
* pIter
= pTmpRanges
;
1282 for( nLen
= 0; *pIter
; ++nLen
, ++pIter
)
1284 aUS
.insert( aUS
.end(), pTmpRanges
, pTmpRanges
+ nLen
);
1288 //! Remove duplicated Ids?
1290 sal_uInt16 nCount
= aUS
.size();
1291 for ( sal_uInt16 i
= 0; i
< nCount
; ++i
)
1292 aUS
[i
] = rPool
.GetWhich( aUS
[i
] );
1296 if ( aUS
.size() > 1 )
1298 std::sort( aUS
.begin(), aUS
.end() );
1301 m_pRanges
= new sal_uInt16
[aUS
.size() + 1];
1302 std::copy( aUS
.begin(), aUS
.end(), m_pRanges
);
1303 m_pRanges
[aUS
.size()] = 0;
1308 void SfxTabDialog::SetInputSet( const SfxItemSet
* pInSet
)
1312 With this method the Input-Set can subsequently be set initially or re-set.
1316 bool bSet
= ( m_pSet
!= nullptr );
1318 m_pSet
= pInSet
? new SfxItemSet(*pInSet
) : nullptr;
1320 if (!bSet
&& !m_pExampleSet
&& !m_pOutSet
&& m_pSet
)
1322 m_pExampleSet
= new SfxItemSet( *m_pSet
);
1323 m_pOutSet
= new SfxItemSet( *m_pSet
->GetPool(), m_pSet
->GetRanges() );
1327 FactoryFunction
SfxTabDialog::GetUITestFactory() const
1329 return SfxTabDialogUIObject::create
;
1332 std::vector
<OString
> SfxTabDialog::getAllPageUIXMLDescriptions() const
1334 std::vector
<OString
> aRetval
;
1336 for (SfxTabDlgData_Impl::const_iterator it
= m_pImpl
->aData
.begin(); it
!= m_pImpl
->aData
.end(); ++it
)
1338 SfxTabPage
* pCandidate
= GetTabPage((*it
)->nId
);
1342 // force SfxTabPage creation
1343 const_cast<SfxTabDialog
*>(this)->ShowPage((*it
)->nId
);
1344 pCandidate
= GetTabPage((*it
)->nId
);
1349 // use UIXMLDescription (without '.ui', with '/')
1350 aRetval
.push_back(pCandidate
->getUIFile());
1357 bool SfxTabDialog::selectPageByUIXMLDescription(const OString
& rUIXMLDescription
)
1359 for (SfxTabDlgData_Impl::const_iterator it
= m_pImpl
->aData
.begin(); it
!= m_pImpl
->aData
.end(); ++it
)
1361 SfxTabPage
* pCandidate
= (*it
)->pTabPage
;
1365 // force SfxTabPage creation
1366 ShowPage((*it
)->nId
);
1367 pCandidate
= GetTabPage((*it
)->nId
);
1370 if (pCandidate
&& pCandidate
->getUIFile() == rUIXMLDescription
)
1372 ShowPage((*it
)->nId
);
1380 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */