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 .
20 #include <vcl/fixed.hxx>
21 #include <vcl/button.hxx>
22 #include <vcl/tabpage.hxx>
23 #include <svtools/wizdlg.hxx>
25 // =======================================================================
27 #define WIZARDDIALOG_BUTTON_OFFSET_Y 6
28 #define WIZARDDIALOG_BUTTON_DLGOFFSET_X 6
29 #define WIZARDDIALOG_VIEW_DLGOFFSET_X 6
30 #define WIZARDDIALOG_VIEW_DLGOFFSET_Y 6
32 // =======================================================================
34 struct ImplWizPageData
36 ImplWizPageData
* mpNext
;
40 // -----------------------------------------------------------------------
42 struct ImplWizButtonData
44 ImplWizButtonData
* mpNext
;
49 // =======================================================================
51 void WizardDialog::ImplInitData()
61 meViewAlign
= WINDOWALIGN_LEFT
;
62 mbEmptyViewMargin
= false;
66 // -----------------------------------------------------------------------
67 void WizardDialog::SetLeftAlignedButtonCount( sal_Int16 _nCount
)
69 mnLeftAlignCount
= _nCount
;
72 // -----------------------------------------------------------------------
74 void WizardDialog::SetEmptyViewMargin()
76 mbEmptyViewMargin
= true;
79 // -----------------------------------------------------------------------
81 void WizardDialog::ImplCalcSize( Size
& rSize
)
83 // ButtonBar-Hoehe berechnen
85 ImplWizButtonData
* pBtnData
= mpFirstBtn
;
88 long nBtnHeight
= pBtnData
->mpButton
->GetSizePixel().Height();
89 if ( nBtnHeight
> nMaxHeight
)
90 nMaxHeight
= nBtnHeight
;
91 pBtnData
= pBtnData
->mpNext
;
94 nMaxHeight
+= WIZARDDIALOG_BUTTON_OFFSET_Y
*2;
95 if ( mpFixedLine
&& mpFixedLine
->IsVisible() )
96 nMaxHeight
+= mpFixedLine
->GetSizePixel().Height();
97 rSize
.Height() += nMaxHeight
;
99 // View-Window-Groesse dazurechnen
100 if ( mpViewWindow
&& mpViewWindow
->IsVisible() )
102 Size aViewSize
= mpViewWindow
->GetSizePixel();
103 if ( meViewAlign
== WINDOWALIGN_TOP
)
104 rSize
.Height() += aViewSize
.Height();
105 else if ( meViewAlign
== WINDOWALIGN_LEFT
)
106 rSize
.Width() += aViewSize
.Width();
107 else if ( meViewAlign
== WINDOWALIGN_BOTTOM
)
108 rSize
.Height() += aViewSize
.Height();
109 else if ( meViewAlign
== WINDOWALIGN_RIGHT
)
110 rSize
.Width() += aViewSize
.Width();
114 // -----------------------------------------------------------------------
116 void WizardDialog::ImplPosCtrls()
118 Size aDlgSize
= GetOutputSizePixel();
121 long nOffY
= aDlgSize
.Height();
123 ImplWizButtonData
* pBtnData
= mpFirstBtn
;
127 if (j
>= mnLeftAlignCount
)
129 Size aBtnSize
= pBtnData
->mpButton
->GetSizePixel();
130 long nBtnHeight
= aBtnSize
.Height();
131 if ( nBtnHeight
> nMaxHeight
)
132 nMaxHeight
= nBtnHeight
;
133 nBtnWidth
+= aBtnSize
.Width();
134 nBtnWidth
+= pBtnData
->mnOffset
;
136 pBtnData
= pBtnData
->mpNext
;
142 long nOffX
= aDlgSize
.Width()-nBtnWidth
-WIZARDDIALOG_BUTTON_DLGOFFSET_X
;
143 long nOffLeftAlignX
= LogicalCoordinateToPixel(6);
144 nOffY
-= WIZARDDIALOG_BUTTON_OFFSET_Y
+nMaxHeight
;
146 pBtnData
= mpFirstBtn
;
150 Size aBtnSize
= pBtnData
->mpButton
->GetSizePixel();
151 if (i
>= mnLeftAlignCount
)
153 Point
aPos( nOffX
, nOffY
+((nMaxHeight
-aBtnSize
.Height())/2) );
154 pBtnData
->mpButton
->SetPosPixel( aPos
);
155 nOffX
+= aBtnSize
.Width();
156 nOffX
+= pBtnData
->mnOffset
;
160 Point
aPos( nOffLeftAlignX
, nOffY
+((nMaxHeight
-aBtnSize
.Height())/2) );
161 pBtnData
->mpButton
->SetPosPixel( aPos
);
162 nOffLeftAlignX
+= aBtnSize
.Width();
163 nOffLeftAlignX
+= pBtnData
->mnOffset
;
166 pBtnData
= pBtnData
->mpNext
;
170 nOffY
-= WIZARDDIALOG_BUTTON_OFFSET_Y
;
173 if ( mpFixedLine
&& mpFixedLine
->IsVisible() )
175 nOffY
-= mpFixedLine
->GetSizePixel().Height();
176 mpFixedLine
->setPosSizePixel( 0, nOffY
, aDlgSize
.Width(), 0,
177 WINDOW_POSSIZE_POS
| WINDOW_POSSIZE_WIDTH
);
180 if ( mpViewWindow
&& mpViewWindow
->IsVisible() )
185 long nViewHeight
= 0;
186 long nDlgHeight
= nOffY
;
187 sal_uInt16 nViewPosFlags
= WINDOW_POSSIZE_POS
;
188 if ( meViewAlign
== WINDOWALIGN_TOP
)
190 nViewOffX
= WIZARDDIALOG_VIEW_DLGOFFSET_X
;
191 nViewOffY
= WIZARDDIALOG_VIEW_DLGOFFSET_Y
;
192 nViewWidth
= aDlgSize
.Width()-(WIZARDDIALOG_VIEW_DLGOFFSET_X
*2);
193 nViewPosFlags
|= WINDOW_POSSIZE_WIDTH
;
195 else if ( meViewAlign
== WINDOWALIGN_LEFT
)
197 if ( mbEmptyViewMargin
)
201 nViewHeight
= nDlgHeight
;
205 nViewOffX
= WIZARDDIALOG_VIEW_DLGOFFSET_X
;
206 nViewOffY
= WIZARDDIALOG_VIEW_DLGOFFSET_Y
;
207 nViewHeight
= nDlgHeight
-(WIZARDDIALOG_VIEW_DLGOFFSET_Y
*2);
209 nViewPosFlags
|= WINDOW_POSSIZE_HEIGHT
;
211 else if ( meViewAlign
== WINDOWALIGN_BOTTOM
)
213 nViewOffX
= WIZARDDIALOG_VIEW_DLGOFFSET_X
;
214 nViewOffY
= nDlgHeight
-mpViewWindow
->GetSizePixel().Height()-WIZARDDIALOG_VIEW_DLGOFFSET_Y
;
215 nViewWidth
= aDlgSize
.Width()-(WIZARDDIALOG_VIEW_DLGOFFSET_X
*2);
216 nViewPosFlags
|= WINDOW_POSSIZE_WIDTH
;
218 else if ( meViewAlign
== WINDOWALIGN_RIGHT
)
220 nViewOffX
= aDlgSize
.Width()-mpViewWindow
->GetSizePixel().Width()-WIZARDDIALOG_VIEW_DLGOFFSET_X
;
221 nViewOffY
= WIZARDDIALOG_VIEW_DLGOFFSET_Y
;
222 nViewHeight
= nDlgHeight
-(WIZARDDIALOG_VIEW_DLGOFFSET_Y
*2);
223 nViewPosFlags
|= WINDOW_POSSIZE_HEIGHT
;
225 mpViewWindow
->setPosSizePixel( nViewOffX
, nViewOffY
,
226 nViewWidth
, nViewHeight
,
232 long WizardDialog::LogicalCoordinateToPixel(int iCoordinate
){
233 Size aLocSize
= LogicToPixel(Size( iCoordinate
, 0 ), MAP_APPFONT
);
234 int iPixelCoordinate
= aLocSize
.Width();
235 return iPixelCoordinate
;
239 // -----------------------------------------------------------------------
241 void WizardDialog::ImplPosTabPage()
246 if ( !IsInInitShow() )
248 // #100199# - On Unix initial size is equal to screen size, on Windows
249 // it's 0,0. One cannot calculate the size unless dialog is visible.
250 if ( !IsReallyVisible() )
254 // ButtonBar-Hoehe berechnen
256 ImplWizButtonData
* pBtnData
= mpFirstBtn
;
259 long nBtnHeight
= pBtnData
->mpButton
->GetSizePixel().Height();
260 if ( nBtnHeight
> nMaxHeight
)
261 nMaxHeight
= nBtnHeight
;
262 pBtnData
= pBtnData
->mpNext
;
265 nMaxHeight
+= WIZARDDIALOG_BUTTON_OFFSET_Y
*2;
266 if ( mpFixedLine
&& mpFixedLine
->IsVisible() )
267 nMaxHeight
+= mpFixedLine
->GetSizePixel().Height();
269 // TabPage positionieren
270 Size aDlgSize
= GetOutputSizePixel();
271 aDlgSize
.Height() -= nMaxHeight
;
274 if ( mpViewWindow
&& mpViewWindow
->IsVisible() )
276 Size aViewSize
= mpViewWindow
->GetSizePixel();
277 if ( meViewAlign
== WINDOWALIGN_TOP
)
279 nOffY
+= aViewSize
.Height()+WIZARDDIALOG_VIEW_DLGOFFSET_Y
;
280 aDlgSize
.Height() -= aViewSize
.Height()+WIZARDDIALOG_VIEW_DLGOFFSET_Y
;
282 else if ( meViewAlign
== WINDOWALIGN_LEFT
)
284 long nViewOffset
= mbEmptyViewMargin
? 0 : WIZARDDIALOG_VIEW_DLGOFFSET_X
;
285 nOffX
+= aViewSize
.Width() + nViewOffset
;
286 aDlgSize
.Width() -= nOffX
;
288 else if ( meViewAlign
== WINDOWALIGN_BOTTOM
)
289 aDlgSize
.Height() -= aViewSize
.Height()+WIZARDDIALOG_VIEW_DLGOFFSET_Y
;
290 else if ( meViewAlign
== WINDOWALIGN_RIGHT
)
291 aDlgSize
.Width() -= aViewSize
.Width()+WIZARDDIALOG_VIEW_DLGOFFSET_X
;
293 Point
aPos( nOffX
, nOffY
);
294 mpCurTabPage
->SetPosSizePixel( aPos
, aDlgSize
);
297 // -----------------------------------------------------------------------
299 void WizardDialog::ImplShowTabPage( TabPage
* pTabPage
)
301 if ( mpCurTabPage
== pTabPage
)
304 TabPage
* pOldTabPage
= mpCurTabPage
;
306 pOldTabPage
->DeactivatePage();
308 mpCurTabPage
= pTabPage
;
312 pTabPage
->ActivatePage();
320 // -----------------------------------------------------------------------
322 TabPage
* WizardDialog::ImplGetPage( sal_uInt16 nLevel
) const
324 sal_uInt16 nTempLevel
= 0;
325 ImplWizPageData
* pPageData
= mpFirstPage
;
328 if ( (nTempLevel
== nLevel
) || !pPageData
->mpNext
)
332 pPageData
= pPageData
->mpNext
;
336 return pPageData
->mpPage
;
340 // =======================================================================
342 WizardDialog::WizardDialog( Window
* pParent
, WinBits nStyle
) :
343 ModalDialog( pParent
, nStyle
)
348 // -----------------------------------------------------------------------
350 WizardDialog::WizardDialog( Window
* pParent
, const ResId
& rResId
) :
351 ModalDialog( pParent
, rResId
)
356 // -----------------------------------------------------------------------
358 WizardDialog::~WizardDialog()
363 // Remove all buttons
365 RemoveButton( mpFirstBtn
->mpButton
);
368 while ( mpFirstPage
)
369 RemovePage( mpFirstPage
->mpPage
);
372 // -----------------------------------------------------------------------
374 void WizardDialog::Resize()
376 if ( IsReallyShown() && !IsInInitShow() )
385 // -----------------------------------------------------------------------
387 void WizardDialog::StateChanged( StateChangedType nType
)
389 if ( nType
== STATE_CHANGE_INITSHOW
)
391 if ( IsDefaultSize() )
393 Size aDlgSize
= GetPageSizePixel();
394 if ( !aDlgSize
.Width() || !aDlgSize
.Height() )
396 ImplWizPageData
* pPageData
= mpFirstPage
;
399 if ( pPageData
->mpPage
)
401 Size aPageSize
= pPageData
->mpPage
->GetSizePixel();
402 if ( aPageSize
.Width() > aDlgSize
.Width() )
403 aDlgSize
.Width() = aPageSize
.Width();
404 if ( aPageSize
.Height() > aDlgSize
.Height() )
405 aDlgSize
.Height() = aPageSize
.Height();
408 pPageData
= pPageData
->mpNext
;
411 ImplCalcSize( aDlgSize
);
412 SetOutputSizePixel( aDlgSize
);
417 ImplShowTabPage( ImplGetPage( mnCurLevel
) );
420 Dialog::StateChanged( nType
);
423 // -----------------------------------------------------------------------
425 long WizardDialog::Notify( NotifyEvent
& rNEvt
)
427 if ( (rNEvt
.GetType() == EVENT_KEYINPUT
) && mpPrevBtn
&& mpNextBtn
)
429 const KeyEvent
* pKEvt
= rNEvt
.GetKeyEvent();
430 KeyCode aKeyCode
= pKEvt
->GetKeyCode();
431 sal_uInt16 nKeyCode
= aKeyCode
.GetCode();
433 if ( aKeyCode
.IsMod1() )
435 if ( aKeyCode
.IsShift() || (nKeyCode
== KEY_PAGEUP
) )
437 if ( (nKeyCode
== KEY_TAB
) || (nKeyCode
== KEY_PAGEUP
) )
439 if ( mpPrevBtn
->IsVisible() &&
440 mpPrevBtn
->IsEnabled() && mpPrevBtn
->IsInputEnabled() )
442 mpPrevBtn
->SetPressed( sal_True
);
443 mpPrevBtn
->SetPressed( sal_False
);
451 if ( (nKeyCode
== KEY_TAB
) || (nKeyCode
== KEY_PAGEDOWN
) )
453 if ( mpNextBtn
->IsVisible() &&
454 mpNextBtn
->IsEnabled() && mpNextBtn
->IsInputEnabled() )
456 mpNextBtn
->SetPressed( sal_True
);
457 mpNextBtn
->SetPressed( sal_False
);
466 return Dialog::Notify( rNEvt
);
469 // -----------------------------------------------------------------------
471 void WizardDialog::ActivatePage()
473 maActivateHdl
.Call( this );
476 // -----------------------------------------------------------------------
478 long WizardDialog::DeactivatePage()
480 if ( maDeactivateHdl
.IsSet() )
481 return maDeactivateHdl
.Call( this );
486 // -----------------------------------------------------------------------
488 sal_Bool
WizardDialog::ShowNextPage()
490 return ShowPage( mnCurLevel
+1 );
493 // -----------------------------------------------------------------------
495 sal_Bool
WizardDialog::ShowPrevPage()
499 return ShowPage( mnCurLevel
-1 );
502 // -----------------------------------------------------------------------
504 sal_Bool
WizardDialog::ShowPage( sal_uInt16 nLevel
)
506 if ( DeactivatePage() )
510 ImplShowTabPage( ImplGetPage( mnCurLevel
) );
517 // -----------------------------------------------------------------------
519 sal_Bool
WizardDialog::Finnish( long nResult
)
521 if ( DeactivatePage() )
524 mpCurTabPage
->DeactivatePage();
527 EndDialog( nResult
);
528 else if ( GetStyle() & WB_CLOSEABLE
)
536 // -----------------------------------------------------------------------
538 void WizardDialog::AddPage( TabPage
* pPage
)
540 ImplWizPageData
* pNewPageData
= new ImplWizPageData
;
541 pNewPageData
->mpNext
= NULL
;
542 pNewPageData
->mpPage
= pPage
;
545 mpFirstPage
= pNewPageData
;
548 ImplWizPageData
* pPageData
= mpFirstPage
;
549 while ( pPageData
->mpNext
)
550 pPageData
= pPageData
->mpNext
;
551 pPageData
->mpNext
= pNewPageData
;
555 // -----------------------------------------------------------------------
557 void WizardDialog::RemovePage( TabPage
* pPage
)
559 ImplWizPageData
* pPrevPageData
= NULL
;
560 ImplWizPageData
* pPageData
= mpFirstPage
;
563 if ( pPageData
->mpPage
== pPage
)
566 pPrevPageData
->mpNext
= pPageData
->mpNext
;
568 mpFirstPage
= pPageData
->mpNext
;
569 if ( pPage
== mpCurTabPage
)
575 pPrevPageData
= pPageData
;
576 pPageData
= pPageData
->mpNext
;
579 OSL_FAIL( "WizardDialog::RemovePage() - Page not in list" );
582 // -----------------------------------------------------------------------
584 void WizardDialog::SetPage( sal_uInt16 nLevel
, TabPage
* pPage
)
586 sal_uInt16 nTempLevel
= 0;
587 ImplWizPageData
* pPageData
= mpFirstPage
;
590 if ( (nTempLevel
== nLevel
) || !pPageData
->mpNext
)
594 pPageData
= pPageData
->mpNext
;
599 if ( pPageData
->mpPage
== mpCurTabPage
)
601 pPageData
->mpPage
= pPage
;
605 // -----------------------------------------------------------------------
607 TabPage
* WizardDialog::GetPage( sal_uInt16 nLevel
) const
609 sal_uInt16 nTempLevel
= 0;
610 ImplWizPageData
* pPageData
= mpFirstPage
;
613 if ( nTempLevel
== nLevel
)
614 return pPageData
->mpPage
;
617 pPageData
= pPageData
->mpNext
;
623 // -----------------------------------------------------------------------
625 void WizardDialog::AddButton( Button
* pButton
, long nOffset
)
627 ImplWizButtonData
* pNewBtnData
= new ImplWizButtonData
;
628 pNewBtnData
->mpNext
= NULL
;
629 pNewBtnData
->mpButton
= pButton
;
630 pNewBtnData
->mnOffset
= nOffset
;
633 mpFirstBtn
= pNewBtnData
;
636 ImplWizButtonData
* pBtnData
= mpFirstBtn
;
637 while ( pBtnData
->mpNext
)
638 pBtnData
= pBtnData
->mpNext
;
639 pBtnData
->mpNext
= pNewBtnData
;
643 // -----------------------------------------------------------------------
645 void WizardDialog::RemoveButton( Button
* pButton
)
647 ImplWizButtonData
* pPrevBtnData
= NULL
;
648 ImplWizButtonData
* pBtnData
= mpFirstBtn
;
651 if ( pBtnData
->mpButton
== pButton
)
654 pPrevBtnData
->mpNext
= pBtnData
->mpNext
;
656 mpFirstBtn
= pBtnData
->mpNext
;
661 pPrevBtnData
= pBtnData
;
662 pBtnData
= pBtnData
->mpNext
;
665 OSL_FAIL( "WizardDialog::RemoveButton() - Button not in list" );
668 // -----------------------------------------------------------------------
670 void WizardDialog::ShowButtonFixedLine( sal_Bool bVisible
)
677 mpFixedLine
= new FixedLine( this );
680 mpFixedLine
->Show( bVisible
);
683 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */