blob: 45eb2440e98a80e21fcb1f9332cbe8faa23fea22 [file] [log] [blame]
/**************************************************************
*
* 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_svtools.hxx"
#define _SVT_WIZDLG_CXX
#include <tools/debug.hxx>
#ifndef _VCL_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
#ifndef _VCL_BUTTON_HXX
#include <vcl/button.hxx>
#endif
#ifndef _VCL_TABPAGE_HXX
#include <vcl/tabpage.hxx>
#endif
#include <svtools/wizdlg.hxx>
// =======================================================================
#define WIZARDDIALOG_BUTTON_OFFSET_Y 6
#define WIZARDDIALOG_BUTTON_DLGOFFSET_X 6
#define WIZARDDIALOG_VIEW_DLGOFFSET_X 6
#define WIZARDDIALOG_VIEW_DLGOFFSET_Y 6
// =======================================================================
struct ImplWizPageData
{
ImplWizPageData* mpNext;
TabPage* mpPage;
};
// -----------------------------------------------------------------------
struct ImplWizButtonData
{
ImplWizButtonData* mpNext;
Button* mpButton;
long mnOffset;
};
// =======================================================================
void WizardDialog::ImplInitData()
{
mpFirstPage = NULL;
mpFirstBtn = NULL;
mpFixedLine = NULL;
mpCurTabPage = NULL;
mpPrevBtn = NULL;
mpNextBtn = NULL;
mpViewWindow = NULL;
mnCurLevel = 0;
meViewAlign = WINDOWALIGN_LEFT;
mbEmptyViewMargin = false;
mnLeftAlignCount = 0;
}
// -----------------------------------------------------------------------
void WizardDialog::SetLeftAlignedButtonCount( sal_Int16 _nCount )
{
mnLeftAlignCount = _nCount;
}
// -----------------------------------------------------------------------
void WizardDialog::SetEmptyViewMargin()
{
mbEmptyViewMargin = true;
}
// -----------------------------------------------------------------------
void WizardDialog::ImplCalcSize( Size& rSize )
{
// ButtonBar-Hoehe berechnen
long nMaxHeight = 0;
ImplWizButtonData* pBtnData = mpFirstBtn;
while ( pBtnData )
{
long nBtnHeight = pBtnData->mpButton->GetSizePixel().Height();
if ( nBtnHeight > nMaxHeight )
nMaxHeight = nBtnHeight;
pBtnData = pBtnData->mpNext;
}
if ( nMaxHeight )
nMaxHeight += WIZARDDIALOG_BUTTON_OFFSET_Y*2;
if ( mpFixedLine && mpFixedLine->IsVisible() )
nMaxHeight += mpFixedLine->GetSizePixel().Height();
rSize.Height() += nMaxHeight;
// View-Window-Groesse dazurechnen
if ( mpViewWindow && mpViewWindow->IsVisible() )
{
Size aViewSize = mpViewWindow->GetSizePixel();
if ( meViewAlign == WINDOWALIGN_TOP )
rSize.Height() += aViewSize.Height();
else if ( meViewAlign == WINDOWALIGN_LEFT )
rSize.Width() += aViewSize.Width();
else if ( meViewAlign == WINDOWALIGN_BOTTOM )
rSize.Height() += aViewSize.Height();
else if ( meViewAlign == WINDOWALIGN_RIGHT )
rSize.Width() += aViewSize.Width();
}
}
// -----------------------------------------------------------------------
void WizardDialog::ImplPosCtrls()
{
Size aDlgSize = GetOutputSizePixel();
long nBtnWidth = 0;
long nMaxHeight = 0;
long nOffY = aDlgSize.Height();
ImplWizButtonData* pBtnData = mpFirstBtn;
int j = 0;
while ( pBtnData )
{
if (j >= mnLeftAlignCount)
{
Size aBtnSize = pBtnData->mpButton->GetSizePixel();
long nBtnHeight = aBtnSize.Height();
if ( nBtnHeight > nMaxHeight )
nMaxHeight = nBtnHeight;
nBtnWidth += aBtnSize.Width();
nBtnWidth += pBtnData->mnOffset;
}
pBtnData = pBtnData->mpNext;
j++;
}
if ( nMaxHeight )
{
long nOffX = aDlgSize.Width()-nBtnWidth-WIZARDDIALOG_BUTTON_DLGOFFSET_X;
long nOffLeftAlignX = LogicalCoordinateToPixel(6);
nOffY -= WIZARDDIALOG_BUTTON_OFFSET_Y+nMaxHeight;
pBtnData = mpFirstBtn;
int i = 0;
while ( pBtnData )
{
Size aBtnSize = pBtnData->mpButton->GetSizePixel();
if (i >= mnLeftAlignCount)
{
Point aPos( nOffX, nOffY+((nMaxHeight-aBtnSize.Height())/2) );
pBtnData->mpButton->SetPosPixel( aPos );
nOffX += aBtnSize.Width();
nOffX += pBtnData->mnOffset;
}
else
{
Point aPos( nOffLeftAlignX, nOffY+((nMaxHeight-aBtnSize.Height())/2) );
pBtnData->mpButton->SetPosPixel( aPos );
nOffLeftAlignX += aBtnSize.Width();
nOffLeftAlignX += pBtnData->mnOffset;
}
pBtnData = pBtnData->mpNext;
i++;
}
nOffY -= WIZARDDIALOG_BUTTON_OFFSET_Y;
}
if ( mpFixedLine && mpFixedLine->IsVisible() )
{
nOffY -= mpFixedLine->GetSizePixel().Height();
mpFixedLine->SetPosSizePixel( 0, nOffY, aDlgSize.Width(), 0,
WINDOW_POSSIZE_POS | WINDOW_POSSIZE_WIDTH );
}
if ( mpViewWindow && mpViewWindow->IsVisible() )
{
long nViewOffX = 0;
long nViewOffY = 0;
long nViewWidth = 0;
long nViewHeight = 0;
long nDlgHeight = nOffY;
sal_uInt16 nViewPosFlags = WINDOW_POSSIZE_POS;
if ( meViewAlign == WINDOWALIGN_TOP )
{
nViewOffX = WIZARDDIALOG_VIEW_DLGOFFSET_X;
nViewOffY = WIZARDDIALOG_VIEW_DLGOFFSET_Y;
nViewWidth = aDlgSize.Width()-(WIZARDDIALOG_VIEW_DLGOFFSET_X*2);
nViewPosFlags |= WINDOW_POSSIZE_WIDTH;
}
else if ( meViewAlign == WINDOWALIGN_LEFT )
{
if ( mbEmptyViewMargin )
{
nViewOffX = 0;
nViewOffY = 0;
nViewHeight = nDlgHeight;
}
else
{
nViewOffX = WIZARDDIALOG_VIEW_DLGOFFSET_X;
nViewOffY = WIZARDDIALOG_VIEW_DLGOFFSET_Y;
nViewHeight = nDlgHeight-(WIZARDDIALOG_VIEW_DLGOFFSET_Y*2);
}
nViewPosFlags |= WINDOW_POSSIZE_HEIGHT;
}
else if ( meViewAlign == WINDOWALIGN_BOTTOM )
{
nViewOffX = WIZARDDIALOG_VIEW_DLGOFFSET_X;
nViewOffY = nDlgHeight-mpViewWindow->GetSizePixel().Height()-WIZARDDIALOG_VIEW_DLGOFFSET_Y;
nViewWidth = aDlgSize.Width()-(WIZARDDIALOG_VIEW_DLGOFFSET_X*2);
nViewPosFlags |= WINDOW_POSSIZE_WIDTH;
}
else if ( meViewAlign == WINDOWALIGN_RIGHT )
{
nViewOffX = aDlgSize.Width()-mpViewWindow->GetSizePixel().Width()-WIZARDDIALOG_VIEW_DLGOFFSET_X;
nViewOffY = WIZARDDIALOG_VIEW_DLGOFFSET_Y;
nViewHeight = nDlgHeight-(WIZARDDIALOG_VIEW_DLGOFFSET_Y*2);
nViewPosFlags |= WINDOW_POSSIZE_HEIGHT;
}
mpViewWindow->SetPosSizePixel( nViewOffX, nViewOffY,
nViewWidth, nViewHeight,
nViewPosFlags );
}
}
long WizardDialog::LogicalCoordinateToPixel(int iCoordinate){
Size aLocSize = LogicToPixel(Size( iCoordinate, 0 ), MAP_APPFONT );
int iPixelCoordinate = aLocSize.Width();
return iPixelCoordinate;
}
// -----------------------------------------------------------------------
void WizardDialog::ImplPosTabPage()
{
if ( !mpCurTabPage )
return;
if ( !IsInInitShow() )
{
// #100199# - On Unix initial size is equal to screen size, on Windows
// it's 0,0. One cannot calculate the size unless dialog is visible.
if ( !IsReallyVisible() )
return;
}
// ButtonBar-Hoehe berechnen
long nMaxHeight = 0;
ImplWizButtonData* pBtnData = mpFirstBtn;
while ( pBtnData )
{
long nBtnHeight = pBtnData->mpButton->GetSizePixel().Height();
if ( nBtnHeight > nMaxHeight )
nMaxHeight = nBtnHeight;
pBtnData = pBtnData->mpNext;
}
if ( nMaxHeight )
nMaxHeight += WIZARDDIALOG_BUTTON_OFFSET_Y*2;
if ( mpFixedLine && mpFixedLine->IsVisible() )
nMaxHeight += mpFixedLine->GetSizePixel().Height();
// TabPage positionieren
Size aDlgSize = GetOutputSizePixel();
aDlgSize.Height() -= nMaxHeight;
long nOffX = 0;
long nOffY = 0;
if ( mpViewWindow && mpViewWindow->IsVisible() )
{
Size aViewSize = mpViewWindow->GetSizePixel();
if ( meViewAlign == WINDOWALIGN_TOP )
{
nOffY += aViewSize.Height()+WIZARDDIALOG_VIEW_DLGOFFSET_Y;
aDlgSize.Height() -= aViewSize.Height()+WIZARDDIALOG_VIEW_DLGOFFSET_Y;
}
else if ( meViewAlign == WINDOWALIGN_LEFT )
{
long nViewOffset = mbEmptyViewMargin ? 0 : WIZARDDIALOG_VIEW_DLGOFFSET_X;
nOffX += aViewSize.Width() + nViewOffset;
aDlgSize.Width() -= nOffX;
}
else if ( meViewAlign == WINDOWALIGN_BOTTOM )
aDlgSize.Height() -= aViewSize.Height()+WIZARDDIALOG_VIEW_DLGOFFSET_Y;
else if ( meViewAlign == WINDOWALIGN_RIGHT )
aDlgSize.Width() -= aViewSize.Width()+WIZARDDIALOG_VIEW_DLGOFFSET_X;
}
Point aPos( nOffX, nOffY );
mpCurTabPage->SetPosSizePixel( aPos, aDlgSize );
}
// -----------------------------------------------------------------------
void WizardDialog::ImplShowTabPage( TabPage* pTabPage )
{
if ( mpCurTabPage == pTabPage )
return;
TabPage* pOldTabPage = mpCurTabPage;
if ( pOldTabPage )
pOldTabPage->DeactivatePage();
mpCurTabPage = pTabPage;
if ( pTabPage )
{
ImplPosTabPage();
pTabPage->ActivatePage();
pTabPage->Show();
}
if ( pOldTabPage )
pOldTabPage->Hide();
}
// -----------------------------------------------------------------------
TabPage* WizardDialog::ImplGetPage( sal_uInt16 nLevel ) const
{
sal_uInt16 nTempLevel = 0;
ImplWizPageData* pPageData = mpFirstPage;
while ( pPageData )
{
if ( (nTempLevel == nLevel) || !pPageData->mpNext )
break;
nTempLevel++;
pPageData = pPageData->mpNext;
}
if ( pPageData )
return pPageData->mpPage;
return NULL;
}
// =======================================================================
WizardDialog::WizardDialog( Window* pParent, WinBits nStyle ) :
ModalDialog( pParent, nStyle )
{
ImplInitData();
}
// -----------------------------------------------------------------------
WizardDialog::WizardDialog( Window* pParent, const ResId& rResId ) :
ModalDialog( pParent, rResId )
{
ImplInitData();
}
// -----------------------------------------------------------------------
WizardDialog::~WizardDialog()
{
if ( mpFixedLine )
delete mpFixedLine;
// Remove all buttons
while ( mpFirstBtn )
RemoveButton( mpFirstBtn->mpButton );
// Remove all pages
while ( mpFirstPage )
RemovePage( mpFirstPage->mpPage );
}
// -----------------------------------------------------------------------
void WizardDialog::Resize()
{
if ( IsReallyShown() && !IsInInitShow() )
{
ImplPosCtrls();
ImplPosTabPage();
}
Dialog::Resize();
}
// -----------------------------------------------------------------------
void WizardDialog::StateChanged( StateChangedType nType )
{
if ( nType == STATE_CHANGE_INITSHOW )
{
if ( IsDefaultSize() )
{
Size aDlgSize = GetPageSizePixel();
if ( !aDlgSize.Width() || !aDlgSize.Height() )
{
ImplWizPageData* pPageData = mpFirstPage;
while ( pPageData )
{
if ( pPageData->mpPage )
{
Size aPageSize = pPageData->mpPage->GetSizePixel();
if ( aPageSize.Width() > aDlgSize.Width() )
aDlgSize.Width() = aPageSize.Width();
if ( aPageSize.Height() > aDlgSize.Height() )
aDlgSize.Height() = aPageSize.Height();
}
pPageData = pPageData->mpNext;
}
}
ImplCalcSize( aDlgSize );
SetOutputSizePixel( aDlgSize );
}
ImplPosCtrls();
ImplPosTabPage();
ImplShowTabPage( ImplGetPage( mnCurLevel ) );
}
Dialog::StateChanged( nType );
}
// -----------------------------------------------------------------------
long WizardDialog::Notify( NotifyEvent& rNEvt )
{
if ( (rNEvt.GetType() == EVENT_KEYINPUT) && mpPrevBtn && mpNextBtn )
{
const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
KeyCode aKeyCode = pKEvt->GetKeyCode();
sal_uInt16 nKeyCode = aKeyCode.GetCode();
if ( aKeyCode.IsMod1() )
{
if ( aKeyCode.IsShift() || (nKeyCode == KEY_PAGEUP) )
{
if ( (nKeyCode == KEY_TAB) || (nKeyCode == KEY_PAGEUP) )
{
if ( mpPrevBtn->IsVisible() &&
mpPrevBtn->IsEnabled() && mpPrevBtn->IsInputEnabled() )
{
mpPrevBtn->SetPressed( sal_True );
mpPrevBtn->SetPressed( sal_False );
mpPrevBtn->Click();
}
return sal_True;
}
}
else
{
if ( (nKeyCode == KEY_TAB) || (nKeyCode == KEY_PAGEDOWN) )
{
if ( mpNextBtn->IsVisible() &&
mpNextBtn->IsEnabled() && mpNextBtn->IsInputEnabled() )
{
mpNextBtn->SetPressed( sal_True );
mpNextBtn->SetPressed( sal_False );
mpNextBtn->Click();
}
return sal_True;
}
}
}
}
return Dialog::Notify( rNEvt );
}
// -----------------------------------------------------------------------
void WizardDialog::ActivatePage()
{
maActivateHdl.Call( this );
}
// -----------------------------------------------------------------------
long WizardDialog::DeactivatePage()
{
if ( maDeactivateHdl.IsSet() )
return maDeactivateHdl.Call( this );
else
return sal_True;
}
// -----------------------------------------------------------------------
sal_Bool WizardDialog::ShowNextPage()
{
return ShowPage( mnCurLevel+1 );
}
// -----------------------------------------------------------------------
sal_Bool WizardDialog::ShowPrevPage()
{
if ( !mnCurLevel )
return sal_False;
return ShowPage( mnCurLevel-1 );
}
// -----------------------------------------------------------------------
sal_Bool WizardDialog::ShowPage( sal_uInt16 nLevel )
{
if ( DeactivatePage() )
{
mnCurLevel = nLevel;
ActivatePage();
ImplShowTabPage( ImplGetPage( mnCurLevel ) );
return sal_True;
}
else
return sal_False;
}
// -----------------------------------------------------------------------
sal_Bool WizardDialog::Finnish( long nResult )
{
if ( DeactivatePage() )
{
if ( mpCurTabPage )
mpCurTabPage->DeactivatePage();
if ( IsInExecute() )
EndDialog( nResult );
else if ( GetStyle() & WB_CLOSEABLE )
Close();
return sal_True;
}
else
return sal_False;
}
// -----------------------------------------------------------------------
void WizardDialog::AddPage( TabPage* pPage )
{
ImplWizPageData* pNewPageData = new ImplWizPageData;
pNewPageData->mpNext = NULL;
pNewPageData->mpPage = pPage;
if ( !mpFirstPage )
mpFirstPage = pNewPageData;
else
{
ImplWizPageData* pPageData = mpFirstPage;
while ( pPageData->mpNext )
pPageData = pPageData->mpNext;
pPageData->mpNext = pNewPageData;
}
}
// -----------------------------------------------------------------------
void WizardDialog::RemovePage( TabPage* pPage )
{
ImplWizPageData* pPrevPageData = NULL;
ImplWizPageData* pPageData = mpFirstPage;
while ( pPageData )
{
if ( pPageData->mpPage == pPage )
{
if ( pPrevPageData )
pPrevPageData->mpNext = pPageData->mpNext;
else
mpFirstPage = pPageData->mpNext;
if ( pPage == mpCurTabPage )
mpCurTabPage = NULL;
delete pPageData;
return;
}
pPrevPageData = pPageData;
pPageData = pPageData->mpNext;
}
DBG_ERROR( "WizardDialog::RemovePage() - Page not in list" );
}
// -----------------------------------------------------------------------
void WizardDialog::SetPage( sal_uInt16 nLevel, TabPage* pPage )
{
sal_uInt16 nTempLevel = 0;
ImplWizPageData* pPageData = mpFirstPage;
while ( pPageData )
{
if ( (nTempLevel == nLevel) || !pPageData->mpNext )
break;
nTempLevel++;
pPageData = pPageData->mpNext;
}
if ( pPageData )
{
if ( pPageData->mpPage == mpCurTabPage )
mpCurTabPage = NULL;
pPageData->mpPage = pPage;
}
}
// -----------------------------------------------------------------------
TabPage* WizardDialog::GetPage( sal_uInt16 nLevel ) const
{
sal_uInt16 nTempLevel = 0;
ImplWizPageData* pPageData = mpFirstPage;
while ( pPageData )
{
if ( nTempLevel == nLevel )
return pPageData->mpPage;
nTempLevel++;
pPageData = pPageData->mpNext;
}
return NULL;
}
// -----------------------------------------------------------------------
void WizardDialog::AddButton( Button* pButton, long nOffset )
{
ImplWizButtonData* pNewBtnData = new ImplWizButtonData;
pNewBtnData->mpNext = NULL;
pNewBtnData->mpButton = pButton;
pNewBtnData->mnOffset = nOffset;
if ( !mpFirstBtn )
mpFirstBtn = pNewBtnData;
else
{
ImplWizButtonData* pBtnData = mpFirstBtn;
while ( pBtnData->mpNext )
pBtnData = pBtnData->mpNext;
pBtnData->mpNext = pNewBtnData;
}
}
// -----------------------------------------------------------------------
void WizardDialog::RemoveButton( Button* pButton )
{
ImplWizButtonData* pPrevBtnData = NULL;
ImplWizButtonData* pBtnData = mpFirstBtn;
while ( pBtnData )
{
if ( pBtnData->mpButton == pButton )
{
if ( pPrevBtnData )
pPrevBtnData->mpNext = pBtnData->mpNext;
else
mpFirstBtn = pBtnData->mpNext;
delete pBtnData;
return;
}
pPrevBtnData = pBtnData;
pBtnData = pBtnData->mpNext;
}
DBG_ERROR( "WizardDialog::RemoveButton() - Button not in list" );
}
// -----------------------------------------------------------------------
void WizardDialog::ShowButtonFixedLine( sal_Bool bVisible )
{
if ( !mpFixedLine )
{
if ( !bVisible )
return;
mpFixedLine = new FixedLine( this );
}
mpFixedLine->Show( bVisible );
}
// -----------------------------------------------------------------------
sal_Bool WizardDialog::IsButtonFixedLineVisible()
{
return (mpFixedLine && mpFixedLine->IsVisible());
}