/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sfx2.hxx" // include --------------------------------------------------------------- #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "sfx2/sfxhelp.hxx" #include "workwin.hxx" #include "sfx2/sfxresid.hxx" #include "dialog.hrc" using namespace ::com::sun::star::uno; using namespace ::rtl; #define USERITEM_NAME OUString::createFromAscii( "UserItem" ) class SfxModelessDialog_Impl : public SfxListener { public: ByteString aWinState; SfxChildWindow* pMgr; sal_Bool bConstructed; void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); Timer aMoveTimer; }; void SfxModelessDialog_Impl::Notify( SfxBroadcaster&, const SfxHint& rHint ) { if ( rHint.IsA(TYPE(SfxSimpleHint)) ) { switch( ( (SfxSimpleHint&) rHint ).GetId() ) { case SFX_HINT_DYING: pMgr->Destroy(); break; } } } class SfxFloatingWindow_Impl : public SfxListener { public: ByteString aWinState; SfxChildWindow* pMgr; sal_Bool bConstructed; Timer aMoveTimer; void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); }; void SfxFloatingWindow_Impl::Notify( SfxBroadcaster&, const SfxHint& rHint ) { if ( rHint.IsA(TYPE(SfxSimpleHint)) ) { switch( ( (SfxSimpleHint&) rHint ).GetId() ) { case SFX_HINT_DYING: pMgr->Destroy(); break; } } } // class SfxModalDefParentHelper ----------------------------------------- SfxModalDefParentHelper::SfxModalDefParentHelper( Window *pWindow) { pOld = Application::GetDefDialogParent(); Application::SetDefDialogParent( pWindow ); } // ----------------------------------------------------------------------- SfxModalDefParentHelper::~SfxModalDefParentHelper() { Application::SetDefDialogParent( pOld ); } // ----------------------------------------------------------------------- void SfxModalDialog::SetDialogData_Impl() { // save settings (position and user data) SvtViewOptions aDlgOpt( E_DIALOG, String::CreateFromInt32( nUniqId ) ); aDlgOpt.SetWindowState( OUString::createFromAscii( GetWindowState( WINDOWSTATE_MASK_POS ).GetBuffer() ) ); if ( aExtraData.Len() ) aDlgOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aExtraData ) ) ); } // ----------------------------------------------------------------------- void SfxModalDialog::GetDialogData_Impl() /* [Beschreibung] Hilfsfunktion; liest die Dialogposition aus der Ini-Datei und setzt diese am "ubergebenen Window. */ { SvtViewOptions aDlgOpt( E_DIALOG, String::CreateFromInt32( nUniqId ) ); if ( aDlgOpt.Exists() ) { // load settings SetWindowState( ByteString( aDlgOpt.GetWindowState().getStr(), RTL_TEXTENCODING_ASCII_US ) ); Any aUserItem = aDlgOpt.GetUserItem( USERITEM_NAME ); OUString aTemp; if ( aUserItem >>= aTemp ) aExtraData = String( aTemp ); } } // ----------------------------------------------------------------------- void SfxModalDialog::init() { GetDialogData_Impl(); } // ----------------------------------------------------------------------- SfxModalDialog::SfxModalDialog(Window* pParent, const ResId &rResId ) /* [Beschreibung] Konstruktor der allgemeinen Basisklasse f"ur modale Dialoge; ResId wird als ID im ini-file verwendet. Die dort gespeicherte Position wird gesetzt. */ : ModalDialog(pParent, rResId), nUniqId(rResId.GetId()), pInputSet(0), pOutputSet(0) { init(); } // ----------------------------------------------------------------------- SfxModalDialog::SfxModalDialog(Window* pParent, sal_uInt32 nUniqueId, WinBits nWinStyle) : /* [Beschreibung] Konstruktor der allgemeinen Basisklasse f"ur modale Dialoge; ID f"ur das ini-file wird explizit "ubergeben. Die dort gespeicherte Position wird gesetzt. */ ModalDialog(pParent, nWinStyle), nUniqId(nUniqueId), pInputSet(0), pOutputSet(0) { init(); } // ----------------------------------------------------------------------- SfxModalDialog::~SfxModalDialog() /* [Beschreibung] Dtor; schreibt Dialogposition in das ini-file */ { SetDialogData_Impl(); delete pOutputSet; } void SfxModalDialog::CreateOutputItemSet( SfxItemPool& rPool ) { DBG_ASSERT( !pOutputSet, "Double creation of OutputSet!" ); if (!pOutputSet) pOutputSet = new SfxAllItemSet( rPool ); } // ----------------------------------------------------------------------- void SfxModalDialog::CreateOutputItemSet( const SfxItemSet& rSet ) { DBG_ASSERT( !pOutputSet, "Double creation of OutputSet!" ); if (!pOutputSet) { pOutputSet = new SfxItemSet( rSet ); pOutputSet->ClearItem(); } } //------------------------------------------------------------------------- void SfxModelessDialog::StateChanged( StateChangedType nStateChange ) { if ( nStateChange == STATE_CHANGE_INITSHOW ) { if ( pImp->aWinState.Len() ) { SetWindowState( pImp->aWinState ); } else { Point aPos = GetPosPixel(); if ( !aPos.X() ) { aSize = GetSizePixel(); Size aParentSize = GetParent()->GetOutputSizePixel(); Size aDlgSize = GetSizePixel(); aPos.X() += ( aParentSize.Width() - aDlgSize.Width() ) / 2; aPos.Y() += ( aParentSize.Height() - aDlgSize.Height() ) / 2; Point aPoint; Rectangle aRect = GetDesktopRectPixel(); aPoint.X() = aRect.Right() - aDlgSize.Width(); aPoint.Y() = aRect.Bottom() - aDlgSize.Height(); aPoint = OutputToScreenPixel( aPoint ); if ( aPos.X() > aPoint.X() ) aPos.X() = aPoint.X() ; if ( aPos.Y() > aPoint.Y() ) aPos.Y() = aPoint.Y(); if ( aPos.X() < 0 ) aPos.X() = 0; if ( aPos.Y() < 0 ) aPos.Y() = 0; SetPosPixel( aPos ); } } pImp->bConstructed = sal_True; } ModelessDialog::StateChanged( nStateChange ); } void SfxModelessDialog::Initialize(SfxChildWinInfo *pInfo) /* [Beschreibung] Initialisierung der Klasse SfxModelessDialog "uber ein SfxChildWinInfo. Die Initialisierung erfolgt erst in einem 2.Schritt nach dem ctor und sollte vom ctor der abgeleiteten Klasse oder von dem des SfxChildWindows aufgerufen werden. */ { pImp->aWinState = pInfo->aWinState; } void SfxModelessDialog::Resize() /* [Beschreibung] Diese virtuelle Methode der Klasse FloatingWindow merkt sich ggf. eine ver"anderte Gr"o\se. Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s auch SfxFloatingWindow::Resize() gerufen werden. */ { ModelessDialog::Resize(); if ( pImp->bConstructed && pImp->pMgr ) { // start timer for saving window status information pImp->aMoveTimer.Start(); } } void SfxModelessDialog::Move() { ModelessDialog::Move(); if ( pImp->bConstructed && pImp->pMgr && IsReallyVisible() ) { // start timer for saving window status information pImp->aMoveTimer.Start(); } } /* Implements a timer event that is triggered by a move or resize of the window This will save config information to Views.xcu with a small delay */ IMPL_LINK( SfxModelessDialog, TimerHdl, Timer*, EMPTYARG) { pImp->aMoveTimer.Stop(); if ( pImp->bConstructed && pImp->pMgr ) { if ( !IsRollUp() ) aSize = GetSizePixel(); sal_uIntPtr nMask = WINDOWSTATE_MASK_POS | WINDOWSTATE_MASK_STATE; if ( GetStyle() & WB_SIZEABLE ) nMask |= ( WINDOWSTATE_MASK_WIDTH | WINDOWSTATE_MASK_HEIGHT ); pImp->aWinState = GetWindowState( nMask ); GetBindings().GetWorkWindow_Impl()->ConfigChild_Impl( SFX_CHILDWIN_DOCKINGWINDOW, SFX_ALIGNDOCKINGWINDOW, pImp->pMgr->GetType() ); } return 0; } // ----------------------------------------------------------------------- SfxModelessDialog::SfxModelessDialog( SfxBindings *pBindinx, SfxChildWindow *pCW, Window* pParent, WinBits nWinBits ) : ModelessDialog (pParent, nWinBits), pBindings(pBindinx), pImp( new SfxModelessDialog_Impl ) { pImp->pMgr = pCW; pImp->bConstructed = sal_False; SetUniqueId( GetHelpId() ); SetHelpId(""); if ( pBindinx ) pImp->StartListening( *pBindinx ); pImp->aMoveTimer.SetTimeout(50); pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxModelessDialog,TimerHdl)); } // ----------------------------------------------------------------------- SfxModelessDialog::SfxModelessDialog( SfxBindings *pBindinx, SfxChildWindow *pCW, Window *pParent, const ResId& rResId ) : ModelessDialog(pParent, rResId), pBindings(pBindinx), pImp( new SfxModelessDialog_Impl ) { pImp->pMgr = pCW; pImp->bConstructed = sal_False; SetUniqueId( GetHelpId() ); SetHelpId(""); if ( pBindinx ) pImp->StartListening( *pBindinx ); pImp->aMoveTimer.SetTimeout(50); pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxModelessDialog,TimerHdl)); } // ----------------------------------------------------------------------- long SfxModelessDialog::Notify( NotifyEvent& rEvt ) /* [Beschreibung] Wenn ein ModelessDialog aktiviert wird, wird sein ViewFrame aktiviert. Notwendig ist das bei PlugInFrames. */ { if ( rEvt.GetType() == EVENT_GETFOCUS ) { pBindings->SetActiveFrame( pImp->pMgr->GetFrame() ); pImp->pMgr->Activate_Impl(); Window* pWindow = rEvt.GetWindow(); rtl::OString sHelpId; while ( !sHelpId.getLength() && pWindow ) { sHelpId = pWindow->GetHelpId(); pWindow = pWindow->GetParent(); } if ( sHelpId.getLength() ) SfxHelp::OpenHelpAgent( &pBindings->GetDispatcher_Impl()->GetFrame()->GetFrame(), sHelpId ); } else if ( rEvt.GetType() == EVENT_LOSEFOCUS && !HasChildPathFocus() ) { pBindings->SetActiveFrame( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > () ); pImp->pMgr->Deactivate_Impl(); } else if( rEvt.GetType() == EVENT_KEYINPUT ) { // KeyInput zuerst f"ur Dialogfunktionen zulassen ( TAB etc. ) if ( !ModelessDialog::Notify( rEvt ) && SfxViewShell::Current() ) // dann auch global g"ultige Acceleratoren verwenden return SfxViewShell::Current()->GlobalKeyInput_Impl( *rEvt.GetKeyEvent() ); return sal_True; } return ModelessDialog::Notify( rEvt ); } // ----------------------------------------------------------------------- SfxModelessDialog::~SfxModelessDialog() /* [Beschreibung] Dtor */ { if ( pImp->pMgr->GetFrame().is() && pImp->pMgr->GetFrame() == pBindings->GetActiveFrame() ) pBindings->SetActiveFrame( NULL ); delete pImp; } //------------------------------------------------------------------------- sal_Bool SfxModelessDialog::Close() /* [Beschreibung] Das Fenster wird geschlossen, indem das ChildWindow durch Ausf"uhren des ChildWindow-Slots zerst"ort wird. Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s danach SfxModelessDialogWindow::Close() gerufen werden, wenn nicht das Close() mit "return sal_False" abgebrochen wird. */ { // Execute mit Parametern, da Toggle von einigen ChildWindows ignoriert // werden kann SfxBoolItem aValue( pImp->pMgr->GetType(), sal_False); pBindings->GetDispatcher_Impl()->Execute( pImp->pMgr->GetType(), SFX_CALLMODE_RECORD|SFX_CALLMODE_SYNCHRON, &aValue, 0L ); return sal_True; } //------------------------------------------------------------------------- void SfxModelessDialog::FillInfo(SfxChildWinInfo& rInfo) const /* [Beschreibung] F"ullt ein SfxChildWinInfo mit f"ur SfxModelessDialof spezifischen Daten, damit sie in die INI-Datei geschrieben werden koennen. Es wird angenommen, da\s rInfo alle anderen evt. relevanten Daten in der ChildWindow-Klasse erh"alt. ModelessDialogs haben keine spezifischen Informationen, so dass die Basisimplementierung nichts tut und daher nicht gerufen werden mu\s. */ { rInfo.aSize = aSize; if ( IsRollUp() ) rInfo.nFlags |= SFX_CHILDWIN_ZOOMIN; } // ----------------------------------------------------------------------- long SfxFloatingWindow::Notify( NotifyEvent& rEvt ) /* [Beschreibung] Wenn ein ModelessDialog aktiviert wird, wird sein ViewFrame aktiviert. Notwendig ist das bei PlugInFrames. */ { if ( rEvt.GetType() == EVENT_GETFOCUS ) { pBindings->SetActiveFrame( pImp->pMgr->GetFrame() ); pImp->pMgr->Activate_Impl(); Window* pWindow = rEvt.GetWindow(); rtl::OString sHelpId; while ( !sHelpId.getLength() && pWindow ) { sHelpId = pWindow->GetHelpId(); pWindow = pWindow->GetParent(); } if ( sHelpId.getLength() ) SfxHelp::OpenHelpAgent( &pBindings->GetDispatcher_Impl()->GetFrame()->GetFrame(), sHelpId ); } else if ( rEvt.GetType() == EVENT_LOSEFOCUS ) { if ( !HasChildPathFocus() ) { pBindings->SetActiveFrame( NULL ); pImp->pMgr->Deactivate_Impl(); } } else if( rEvt.GetType() == EVENT_KEYINPUT ) { // KeyInput zuerst f"ur Dialogfunktionen zulassen if ( !FloatingWindow::Notify( rEvt ) && SfxViewShell::Current() ) // dann auch global g"ultige Acceleratoren verwenden return SfxViewShell::Current()->GlobalKeyInput_Impl( *rEvt.GetKeyEvent() ); return sal_True; } return FloatingWindow::Notify( rEvt ); } // ----------------------------------------------------------------------- SfxFloatingWindow::SfxFloatingWindow( SfxBindings *pBindinx, SfxChildWindow *pCW, Window* pParent, WinBits nWinBits) : FloatingWindow (pParent, nWinBits), pBindings(pBindinx), pImp( new SfxFloatingWindow_Impl ) { pImp->pMgr = pCW; pImp->bConstructed = sal_False; SetUniqueId( GetHelpId() ); SetHelpId(""); if ( pBindinx ) pImp->StartListening( *pBindinx ); pImp->aMoveTimer.SetTimeout(50); pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxFloatingWindow,TimerHdl)); } // ----------------------------------------------------------------------- SfxFloatingWindow::SfxFloatingWindow( SfxBindings *pBindinx, SfxChildWindow *pCW, Window* pParent, const ResId& rResId) : FloatingWindow(pParent, rResId), pBindings(pBindinx), pImp( new SfxFloatingWindow_Impl ) { pImp->pMgr = pCW; pImp->bConstructed = sal_False; SetUniqueId( GetHelpId() ); SetHelpId(""); if ( pBindinx ) pImp->StartListening( *pBindinx ); pImp->aMoveTimer.SetTimeout(50); pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxFloatingWindow,TimerHdl)); } //------------------------------------------------------------------------- sal_Bool SfxFloatingWindow::Close() /* [Beschreibung] Das Fenster wird geschlossen, indem das ChildWindow durch Ausf"uhren des ChildWindow-Slots zerst"ort wird. Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s danach SfxFloatingWindow::Close() gerufen werden, wenn nicht das Close() mit "return sal_False" abgebrochen wird. */ { // Execute mit Parametern, da Toggle von einigen ChildWindows ignoriert // werden kann SfxBoolItem aValue( pImp->pMgr->GetType(), sal_False); pBindings->GetDispatcher_Impl()->Execute( pImp->pMgr->GetType(), SFX_CALLMODE_RECORD|SFX_CALLMODE_SYNCHRON, &aValue, 0L ); return sal_True; } // ----------------------------------------------------------------------- SfxFloatingWindow::~SfxFloatingWindow() /* [Beschreibung] Dtor */ { if ( pImp->pMgr->GetFrame() == pBindings->GetActiveFrame() ) pBindings->SetActiveFrame( NULL ); delete pImp; } //------------------------------------------------------------------------- void SfxFloatingWindow::Resize() /* [Beschreibung] Diese virtuelle Methode der Klasse FloatingWindow merkt sich ggf. eine ver"anderte Gr"o\se. Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s auch SfxFloatingWindow::Resize() gerufen werden. */ { FloatingWindow::Resize(); if ( pImp->bConstructed && pImp->pMgr ) { // start timer for saving window status information pImp->aMoveTimer.Start(); } } void SfxFloatingWindow::Move() { FloatingWindow::Move(); if ( pImp->bConstructed && pImp->pMgr ) { // start timer for saving window status information pImp->aMoveTimer.Start(); } } /* Implements a timer event that is triggered by a move or resize of the window This will save config information to Views.xcu with a small delay */ IMPL_LINK( SfxFloatingWindow, TimerHdl, Timer*, EMPTYARG) { pImp->aMoveTimer.Stop(); if ( pImp->bConstructed && pImp->pMgr ) { if ( !IsRollUp() ) aSize = GetSizePixel(); sal_uIntPtr nMask = WINDOWSTATE_MASK_POS | WINDOWSTATE_MASK_STATE; if ( GetStyle() & WB_SIZEABLE ) nMask |= ( WINDOWSTATE_MASK_WIDTH | WINDOWSTATE_MASK_HEIGHT ); pImp->aWinState = GetWindowState( nMask ); GetBindings().GetWorkWindow_Impl()->ConfigChild_Impl( SFX_CHILDWIN_DOCKINGWINDOW, SFX_ALIGNDOCKINGWINDOW, pImp->pMgr->GetType() ); } return 0; } //------------------------------------------------------------------------- void SfxFloatingWindow::StateChanged( StateChangedType nStateChange ) { if ( nStateChange == STATE_CHANGE_INITSHOW ) { // FloatingWindows are not centered by default if ( pImp->aWinState.Len() ) SetWindowState( pImp->aWinState ); pImp->bConstructed = sal_True; } FloatingWindow::StateChanged( nStateChange ); } void SfxFloatingWindow::Initialize(SfxChildWinInfo *pInfo) /* [Beschreibung] Initialisierung der Klasse SfxFloatingWindow "uber ein SfxChildWinInfo. Die Initialisierung erfolgt erst in einem 2.Schritt nach dem ctor und sollte vom ctor der abgeleiteten Klasse oder von dem des SfxChildWindows aufgerufen werden. */ { pImp->aWinState = pInfo->aWinState; } //------------------------------------------------------------------------- void SfxFloatingWindow::FillInfo(SfxChildWinInfo& rInfo) const /* [Beschreibung] F"ullt ein SfxChildWinInfo mit f"ur SfxFloatingWindow spezifischen Daten, damit sie in die INI-Datei geschrieben werden koennen. Es wird angenommen, da\s rInfo alle anderen evt. relevanten Daten in der ChildWindow-Klasse erh"alt. Eingetragen werden hier gemerkte Gr"o\se und das ZoomIn-Flag. Wird diese Methode "uberschrieben, mu\s zuerst die Basisimplementierung gerufen werden. */ { rInfo.aSize = aSize; if ( IsRollUp() ) rInfo.nFlags |= SFX_CHILDWIN_ZOOMIN; } // SfxSingleTabDialog ---------------------------------------------------- IMPL_LINK( SfxSingleTabDialog, OKHdl_Impl, Button *, EMPTYARG ) /* [Beschreibung] Ok_Handler; f"ur die gesetzte Page wird FillItemSet() gerufen. */ { if ( !GetInputItemSet() ) { // TabPage without ItemSet EndDialog( RET_OK ); return 1; } if ( !GetOutputItemSet() ) { CreateOutputItemSet( *GetInputItemSet() ); } sal_Bool bModified = sal_False; if ( pImpl->m_pSfxPage->HasExchangeSupport() ) { int nRet = pImpl->m_pSfxPage->DeactivatePage( GetOutputSetImpl() ); if ( nRet != SfxTabPage::LEAVE_PAGE ) return 0; else bModified = ( GetOutputItemSet()->Count() > 0 ); } else bModified = pImpl->m_pSfxPage->FillItemSet( *GetOutputSetImpl() ); if ( bModified ) { // auch noch schnell User-Daten im IniManager abspeichern pImpl->m_pSfxPage->FillUserData(); String sData( pImpl->m_pSfxPage->GetUserData() ); SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( GetUniqId() ) ); aPageOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( sData ) ) ); EndDialog( RET_OK ); } else EndDialog( RET_CANCEL ); return 0; } // ----------------------------------------------------------------------- SfxSingleTabDialog::SfxSingleTabDialog ( Window *pParent, const SfxItemSet& rSet, sal_uInt16 nUniqueId ) : /* [Beschreibung] Konstruktor der allgemeinen Basisklasse f"ur SingleTab-Dialoge; ID f"ur das ini-file wird "ubergeben. */ SfxModalDialog( pParent, nUniqueId, WinBits( WB_STDMODAL | WB_3DLOOK ) ), pOKBtn ( 0 ), pCancelBtn ( 0 ), pHelpBtn ( 0 ), pImpl ( new SingleTabDlgImpl ) { DBG_WARNING( "please use the ctor with ViewFrame" ); SetInputSet( &rSet ); } // ----------------------------------------------------------------------- SfxSingleTabDialog::SfxSingleTabDialog ( Window* pParent, sal_uInt16 nUniqueId, const SfxItemSet* pInSet ) /* [Beschreibung] Konstruktor der allgemeinen Basisklasse f"ur SingleTab-Dialoge; ID f"ur das ini-file wird "ubergeben. Sollte nicht mehr benutzt werden. */ : SfxModalDialog( pParent, nUniqueId, WinBits( WB_STDMODAL | WB_3DLOOK ) ), pOKBtn ( 0 ), pCancelBtn ( 0 ), pHelpBtn ( 0 ), pImpl ( new SingleTabDlgImpl ) { DBG_WARNING( "bitte den Ctor mit ViewFrame verwenden" ); SetInputSet( pInSet ); } // ----------------------------------------------------------------------- SfxSingleTabDialog::SfxSingleTabDialog ( Window* pParent, sal_uInt16 nUniqueId, const String& rInfoURL ) /* [Beschreibung] Konstruktor der allgemeinen Basisklasse f"ur SingleTab-Dialoge; ID f"ur das ini-file wird "ubergeben. */ : SfxModalDialog( pParent, nUniqueId, WinBits( WB_STDMODAL | WB_3DLOOK ) ), pOKBtn ( NULL ), pCancelBtn ( NULL ), pHelpBtn ( NULL ), pImpl ( new SingleTabDlgImpl ) { pImpl->m_sInfoURL = rInfoURL; } // ----------------------------------------------------------------------- SfxSingleTabDialog::~SfxSingleTabDialog() { delete pOKBtn; delete pCancelBtn; delete pHelpBtn; delete pImpl->m_pTabPage; delete pImpl->m_pSfxPage; delete pImpl->m_pLine; delete pImpl->m_pInfoImage; delete pImpl; } // ----------------------------------------------------------------------- void SfxSingleTabDialog::SetPage( TabPage* pNewPage ) { if ( !pImpl->m_pLine ) pImpl->m_pLine = new FixedLine( this ); if ( !pOKBtn ) { pOKBtn = new OKButton( this, WB_DEFBUTTON ); pOKBtn->SetClickHdl( LINK( this, SfxSingleTabDialog, OKHdl_Impl ) ); } if ( pImpl->m_sInfoURL.Len() > 0 && !pImpl->m_pInfoImage ) { pImpl->m_pInfoImage = new ::svt::FixedHyperlinkImage( this ); Image aInfoImage = Image( SfxResId( IMG_INFO ) ); Size aImageSize = aInfoImage.GetSizePixel(); aImageSize.Width() += 4; aImageSize.Height() += 4; pImpl->m_pInfoImage->SetSizePixel( aImageSize ); pImpl->m_pInfoImage->SetImage( aInfoImage ); pImpl->m_pInfoImage->SetURL( pImpl->m_sInfoURL ); pImpl->m_pInfoImage->SetClickHdl( pImpl->m_aInfoLink ); } if ( pImpl->m_pTabPage ) delete pImpl->m_pTabPage; if ( pImpl->m_pSfxPage ) delete pImpl->m_pSfxPage; pImpl->m_pTabPage = pNewPage; if ( pImpl->m_pTabPage ) { // Gr"ossen und Positionen anpassen pImpl->m_pTabPage->SetPosPixel( Point() ); Size aOutSz( pImpl->m_pTabPage->GetSizePixel() ); Size aOffSz = LogicToPixel( Size( RSC_SP_CTRL_X, RSC_SP_CTRL_Y ), MAP_APPFONT ); Size aFLSz = LogicToPixel( Size( aOutSz.Width(), RSC_CD_FIXEDLINE_HEIGHT ) ); Size aBtnSz = LogicToPixel( Size( RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT ), MAP_APPFONT ); Point aPnt( 0, aOutSz.Height() ); pImpl->m_pLine->SetPosSizePixel( aPnt, aFLSz ); aPnt.X() = aOutSz.Width() - aOffSz.Width() - aBtnSz.Width(); aPnt.Y() += aFLSz.Height() + ( aOffSz.Height() / 2 ); pOKBtn->SetPosSizePixel( aPnt, aBtnSz ); if ( pImpl->m_pInfoImage ) { aPnt.X() = aOffSz.Width(); long nDelta = ( pImpl->m_pInfoImage->GetSizePixel().Height() - aBtnSz.Height() ) / 2; aPnt.Y() -= nDelta; pImpl->m_pInfoImage->SetPosPixel( aPnt ); pImpl->m_pInfoImage->Show(); } aOutSz.Height() += aFLSz.Height() + ( aOffSz.Height() / 2 ) + aBtnSz.Height() + aOffSz.Height(); SetOutputSizePixel( aOutSz ); pImpl->m_pLine->Show(); pOKBtn->Show(); pImpl->m_pTabPage->Show(); // Text der TabPage in den Dialog setzen SetText( pImpl->m_pTabPage->GetText() ); // Dialog bekommt HelpId der TabPage SetHelpId( pImpl->m_pTabPage->GetHelpId() ); SetUniqueId( pImpl->m_pTabPage->GetUniqueId() ); } } // ----------------------------------------------------------------------- void SfxSingleTabDialog::SetTabPage( SfxTabPage* pTabPage, GetTabPageRanges pRangesFunc ) /* [Beschreibung] Setzen einer (neuen) TabPage; eine bereits vorhandene Page wird gel"oscht. Die "ubergebene Page wird durch Aufruf von Reset() mit dem initial "ubergebenen Itemset initialisiert. */ { if ( !pOKBtn ) { pOKBtn = new OKButton( this, WB_DEFBUTTON ); pOKBtn->SetClickHdl( LINK( this, SfxSingleTabDialog, OKHdl_Impl ) ); } if ( !pCancelBtn ) pCancelBtn = new CancelButton( this ); if ( !pHelpBtn ) pHelpBtn = new HelpButton( this ); if ( pImpl->m_pTabPage ) delete pImpl->m_pTabPage; if ( pImpl->m_pSfxPage ) delete pImpl->m_pSfxPage; pImpl->m_pSfxPage = pTabPage; fnGetRanges = pRangesFunc; if ( pImpl->m_pSfxPage ) { // erstmal die User-Daten besorgen, dann erst Reset() SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( GetUniqId() ) ); String sUserData; Any aUserItem = aPageOpt.GetUserItem( USERITEM_NAME ); OUString aTemp; if ( aUserItem >>= aTemp ) sUserData = String( aTemp ); pImpl->m_pSfxPage->SetUserData( sUserData ); pImpl->m_pSfxPage->Reset( *GetInputItemSet() ); pImpl->m_pSfxPage->Show(); // Gr"ossen und Positionen anpassen pImpl->m_pSfxPage->SetPosPixel( Point() ); Size aOutSz( pImpl->m_pSfxPage->GetSizePixel() ); Size aBtnSiz = LogicToPixel( Size( 50, 14 ), MAP_APPFONT ); Point aPnt( aOutSz.Width(), LogicToPixel( Point( 0, 6 ), MAP_APPFONT ).Y() ); aOutSz.Width() += aBtnSiz.Width() + LogicToPixel( Size( 6, 0 ), MAP_APPFONT ).Width(); SetOutputSizePixel( aOutSz ); pOKBtn->SetPosSizePixel( aPnt, aBtnSiz ); pOKBtn->Show(); aPnt.Y() = LogicToPixel( Point( 0, 23 ), MAP_APPFONT ).Y(); pCancelBtn->SetPosSizePixel( aPnt, aBtnSiz ); pCancelBtn->Show(); aPnt.Y() = LogicToPixel( Point( 0, 43 ), MAP_APPFONT ).Y(); pHelpBtn->SetPosSizePixel( aPnt, aBtnSiz ); if ( Help::IsContextHelpEnabled() ) pHelpBtn->Show(); // Text der TabPage in den Dialog setzen SetText( pImpl->m_pSfxPage->GetText() ); // Dialog bekommt HelpId der TabPage SetHelpId( pImpl->m_pSfxPage->GetHelpId() ); SetUniqueId( pImpl->m_pSfxPage->GetUniqueId() ); } } // ----------------------------------------------------------------------- void SfxSingleTabDialog::SetInfoLink( const Link& rLink ) { pImpl->m_aInfoLink = rLink; } //-------------------------------------------------------------------- // Vergleichsfunktion fuer qsort #ifdef WNT int __cdecl BaseDlgsCmpUS_Impl( const void* p1, const void* p2 ) #else #if defined(OS2) && defined(ICC) int _Optlink BaseDlgsCmpUS_Impl( const void* p1, const void* p2 ) #else extern "C" int BaseDlgsCmpUS_Impl( const void* p1, const void* p2 ) #endif #endif { return *(sal_uInt16*)p1 - *(sal_uInt16*)p2; } // ----------------------------------------------------------------------- /* Bildet das Set "uber die Ranges der Page. Die Page muss die statische Methode f"ur das Erfragen ihrer Ranges bei SetTabPage angegeben haben, liefert also ihr Set onDemand. */ const sal_uInt16* SfxSingleTabDialog::GetInputRanges( const SfxItemPool& rPool ) { if ( GetInputItemSet() ) { DBG_ERROR( "Set bereits vorhanden!" ); return GetInputItemSet()->GetRanges(); } if ( pRanges ) return pRanges; SvUShorts aUS(16, 16); if ( fnGetRanges) { const sal_uInt16 *pTmpRanges = (fnGetRanges)(); const sal_uInt16 *pIter = pTmpRanges; sal_uInt16 nLen; for ( nLen = 0; *pIter; ++nLen, ++pIter ) ; aUS.Insert( pTmpRanges, nLen, aUS.Count() ); } //! Doppelte Ids entfernen? sal_uInt16 nCount = aUS.Count(); for ( sal_uInt16 i = 0; i < nCount; ++i ) aUS[i] = rPool.GetWhich( aUS[i]) ; // sortieren if ( aUS.Count() > 1 ) qsort( (void*)aUS.GetData(), aUS.Count(), sizeof(sal_uInt16), BaseDlgsCmpUS_Impl ); pRanges = new sal_uInt16[aUS.Count() + 1]; memcpy( pRanges, aUS.GetData(), sizeof(sal_uInt16) * aUS.Count() ); pRanges[aUS.Count()] = 0; return pRanges; }