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;
65 maWizardLayoutTimer
.SetTimeout(50);
66 maWizardLayoutTimer
.SetTimeoutHdl( LINK( this, WizardDialog
, ImplHandleWizardLayoutTimerHdl
) );
69 // -----------------------------------------------------------------------
70 void WizardDialog::SetLeftAlignedButtonCount( sal_Int16 _nCount
)
72 mnLeftAlignCount
= _nCount
;
75 // -----------------------------------------------------------------------
77 void WizardDialog::SetEmptyViewMargin()
79 mbEmptyViewMargin
= true;
82 // -----------------------------------------------------------------------
84 void WizardDialog::ImplCalcSize( Size
& rSize
)
86 // ButtonBar-Hoehe berechnen
88 ImplWizButtonData
* pBtnData
= mpFirstBtn
;
91 long nBtnHeight
= pBtnData
->mpButton
->GetSizePixel().Height();
92 if ( nBtnHeight
> nMaxHeight
)
93 nMaxHeight
= nBtnHeight
;
94 pBtnData
= pBtnData
->mpNext
;
97 nMaxHeight
+= WIZARDDIALOG_BUTTON_OFFSET_Y
*2;
98 if ( mpFixedLine
&& mpFixedLine
->IsVisible() )
99 nMaxHeight
+= mpFixedLine
->GetSizePixel().Height();
100 rSize
.Height() += nMaxHeight
;
102 // View-Window-Groesse dazurechnen
103 if ( mpViewWindow
&& mpViewWindow
->IsVisible() )
105 Size aViewSize
= mpViewWindow
->GetSizePixel();
106 if ( meViewAlign
== WINDOWALIGN_TOP
)
107 rSize
.Height() += aViewSize
.Height();
108 else if ( meViewAlign
== WINDOWALIGN_LEFT
)
109 rSize
.Width() += aViewSize
.Width();
110 else if ( meViewAlign
== WINDOWALIGN_BOTTOM
)
111 rSize
.Height() += aViewSize
.Height();
112 else if ( meViewAlign
== WINDOWALIGN_RIGHT
)
113 rSize
.Width() += aViewSize
.Width();
117 bool WizardDialog::hasWizardPendingLayout() const
119 return maWizardLayoutTimer
.IsActive();
122 void WizardDialog::queue_resize()
124 if (hasWizardPendingLayout())
128 maWizardLayoutTimer
.Start();
131 IMPL_LINK( WizardDialog
, ImplHandleWizardLayoutTimerHdl
, void*, EMPTYARG
)
138 void WizardDialog::ImplPosCtrls()
140 Size aDlgSize
= GetOutputSizePixel();
143 long nOffY
= aDlgSize
.Height();
145 ImplWizButtonData
* pBtnData
= mpFirstBtn
;
149 if (j
>= mnLeftAlignCount
)
151 Size aBtnSize
= pBtnData
->mpButton
->GetSizePixel();
152 long nBtnHeight
= aBtnSize
.Height();
153 if ( nBtnHeight
> nMaxHeight
)
154 nMaxHeight
= nBtnHeight
;
155 nBtnWidth
+= aBtnSize
.Width();
156 nBtnWidth
+= pBtnData
->mnOffset
;
158 pBtnData
= pBtnData
->mpNext
;
164 long nOffX
= aDlgSize
.Width()-nBtnWidth
-WIZARDDIALOG_BUTTON_DLGOFFSET_X
;
165 long nOffLeftAlignX
= LogicalCoordinateToPixel(6);
166 nOffY
-= WIZARDDIALOG_BUTTON_OFFSET_Y
+nMaxHeight
;
168 pBtnData
= mpFirstBtn
;
172 Size aBtnSize
= pBtnData
->mpButton
->GetSizePixel();
173 if (i
>= mnLeftAlignCount
)
175 Point
aPos( nOffX
, nOffY
+((nMaxHeight
-aBtnSize
.Height())/2) );
176 pBtnData
->mpButton
->SetPosPixel( aPos
);
177 nOffX
+= aBtnSize
.Width();
178 nOffX
+= pBtnData
->mnOffset
;
182 Point
aPos( nOffLeftAlignX
, nOffY
+((nMaxHeight
-aBtnSize
.Height())/2) );
183 pBtnData
->mpButton
->SetPosPixel( aPos
);
184 nOffLeftAlignX
+= aBtnSize
.Width();
185 nOffLeftAlignX
+= pBtnData
->mnOffset
;
188 pBtnData
= pBtnData
->mpNext
;
192 nOffY
-= WIZARDDIALOG_BUTTON_OFFSET_Y
;
195 if ( mpFixedLine
&& mpFixedLine
->IsVisible() )
197 nOffY
-= mpFixedLine
->GetSizePixel().Height();
198 mpFixedLine
->setPosSizePixel( 0, nOffY
, aDlgSize
.Width(), 0,
199 WINDOW_POSSIZE_POS
| WINDOW_POSSIZE_WIDTH
);
202 if ( mpViewWindow
&& mpViewWindow
->IsVisible() )
207 long nViewHeight
= 0;
208 long nDlgHeight
= nOffY
;
209 sal_uInt16 nViewPosFlags
= WINDOW_POSSIZE_POS
;
210 if ( meViewAlign
== WINDOWALIGN_TOP
)
212 nViewOffX
= WIZARDDIALOG_VIEW_DLGOFFSET_X
;
213 nViewOffY
= WIZARDDIALOG_VIEW_DLGOFFSET_Y
;
214 nViewWidth
= aDlgSize
.Width()-(WIZARDDIALOG_VIEW_DLGOFFSET_X
*2);
215 nViewPosFlags
|= WINDOW_POSSIZE_WIDTH
;
217 else if ( meViewAlign
== WINDOWALIGN_LEFT
)
219 if ( mbEmptyViewMargin
)
223 nViewHeight
= nDlgHeight
;
227 nViewOffX
= WIZARDDIALOG_VIEW_DLGOFFSET_X
;
228 nViewOffY
= WIZARDDIALOG_VIEW_DLGOFFSET_Y
;
229 nViewHeight
= nDlgHeight
-(WIZARDDIALOG_VIEW_DLGOFFSET_Y
*2);
231 nViewPosFlags
|= WINDOW_POSSIZE_HEIGHT
;
233 else if ( meViewAlign
== WINDOWALIGN_BOTTOM
)
235 nViewOffX
= WIZARDDIALOG_VIEW_DLGOFFSET_X
;
236 nViewOffY
= nDlgHeight
-mpViewWindow
->GetSizePixel().Height()-WIZARDDIALOG_VIEW_DLGOFFSET_Y
;
237 nViewWidth
= aDlgSize
.Width()-(WIZARDDIALOG_VIEW_DLGOFFSET_X
*2);
238 nViewPosFlags
|= WINDOW_POSSIZE_WIDTH
;
240 else if ( meViewAlign
== WINDOWALIGN_RIGHT
)
242 nViewOffX
= aDlgSize
.Width()-mpViewWindow
->GetSizePixel().Width()-WIZARDDIALOG_VIEW_DLGOFFSET_X
;
243 nViewOffY
= WIZARDDIALOG_VIEW_DLGOFFSET_Y
;
244 nViewHeight
= nDlgHeight
-(WIZARDDIALOG_VIEW_DLGOFFSET_Y
*2);
245 nViewPosFlags
|= WINDOW_POSSIZE_HEIGHT
;
247 mpViewWindow
->setPosSizePixel( nViewOffX
, nViewOffY
,
248 nViewWidth
, nViewHeight
,
254 long WizardDialog::LogicalCoordinateToPixel(int iCoordinate
){
255 Size aLocSize
= LogicToPixel(Size( iCoordinate
, 0 ), MAP_APPFONT
);
256 int iPixelCoordinate
= aLocSize
.Width();
257 return iPixelCoordinate
;
261 // -----------------------------------------------------------------------
263 void WizardDialog::ImplPosTabPage()
268 if ( !IsInInitShow() )
270 // #100199# - On Unix initial size is equal to screen size, on Windows
271 // it's 0,0. One cannot calculate the size unless dialog is visible.
272 if ( !IsReallyVisible() )
276 // ButtonBar-Hoehe berechnen
278 ImplWizButtonData
* pBtnData
= mpFirstBtn
;
281 long nBtnHeight
= pBtnData
->mpButton
->GetSizePixel().Height();
282 if ( nBtnHeight
> nMaxHeight
)
283 nMaxHeight
= nBtnHeight
;
284 pBtnData
= pBtnData
->mpNext
;
287 nMaxHeight
+= WIZARDDIALOG_BUTTON_OFFSET_Y
*2;
288 if ( mpFixedLine
&& mpFixedLine
->IsVisible() )
289 nMaxHeight
+= mpFixedLine
->GetSizePixel().Height();
291 // TabPage positionieren
292 Size aDlgSize
= GetOutputSizePixel();
293 aDlgSize
.Height() -= nMaxHeight
;
296 if ( mpViewWindow
&& mpViewWindow
->IsVisible() )
298 Size aViewSize
= mpViewWindow
->GetSizePixel();
299 if ( meViewAlign
== WINDOWALIGN_TOP
)
301 nOffY
+= aViewSize
.Height()+WIZARDDIALOG_VIEW_DLGOFFSET_Y
;
302 aDlgSize
.Height() -= aViewSize
.Height()+WIZARDDIALOG_VIEW_DLGOFFSET_Y
;
304 else if ( meViewAlign
== WINDOWALIGN_LEFT
)
306 long nViewOffset
= mbEmptyViewMargin
? 0 : WIZARDDIALOG_VIEW_DLGOFFSET_X
;
307 nOffX
+= aViewSize
.Width() + nViewOffset
;
308 aDlgSize
.Width() -= nOffX
;
310 else if ( meViewAlign
== WINDOWALIGN_BOTTOM
)
311 aDlgSize
.Height() -= aViewSize
.Height()+WIZARDDIALOG_VIEW_DLGOFFSET_Y
;
312 else if ( meViewAlign
== WINDOWALIGN_RIGHT
)
313 aDlgSize
.Width() -= aViewSize
.Width()+WIZARDDIALOG_VIEW_DLGOFFSET_X
;
315 Point
aPos( nOffX
, nOffY
);
316 mpCurTabPage
->SetPosSizePixel( aPos
, aDlgSize
);
319 // -----------------------------------------------------------------------
321 void WizardDialog::ImplShowTabPage( TabPage
* pTabPage
)
323 if ( mpCurTabPage
== pTabPage
)
326 TabPage
* pOldTabPage
= mpCurTabPage
;
328 pOldTabPage
->DeactivatePage();
330 mpCurTabPage
= pTabPage
;
334 pTabPage
->ActivatePage();
342 // -----------------------------------------------------------------------
344 TabPage
* WizardDialog::ImplGetPage( sal_uInt16 nLevel
) const
346 sal_uInt16 nTempLevel
= 0;
347 ImplWizPageData
* pPageData
= mpFirstPage
;
350 if ( (nTempLevel
== nLevel
) || !pPageData
->mpNext
)
354 pPageData
= pPageData
->mpNext
;
358 return pPageData
->mpPage
;
362 // =======================================================================
364 WizardDialog::WizardDialog( Window
* pParent
, WinBits nStyle
) :
365 ModalDialog( pParent
, nStyle
)
370 // -----------------------------------------------------------------------
372 WizardDialog::WizardDialog( Window
* pParent
, const ResId
& rResId
) :
373 ModalDialog( pParent
, rResId
)
378 // -----------------------------------------------------------------------
380 WizardDialog::~WizardDialog()
382 maWizardLayoutTimer
.Stop();
386 // Remove all buttons
388 RemoveButton( mpFirstBtn
->mpButton
);
391 while ( mpFirstPage
)
392 RemovePage( mpFirstPage
->mpPage
);
395 // -----------------------------------------------------------------------
397 void WizardDialog::Resize()
399 if ( IsReallyShown() && !IsInInitShow() )
408 // -----------------------------------------------------------------------
410 void WizardDialog::StateChanged( StateChangedType nType
)
412 if ( nType
== STATE_CHANGE_INITSHOW
)
414 if ( IsDefaultSize() )
416 Size aDlgSize
= GetPageSizePixel();
417 if ( !aDlgSize
.Width() || !aDlgSize
.Height() )
419 ImplWizPageData
* pPageData
= mpFirstPage
;
422 if ( pPageData
->mpPage
)
424 Size aPageSize
= pPageData
->mpPage
->GetSizePixel();
425 if ( aPageSize
.Width() > aDlgSize
.Width() )
426 aDlgSize
.Width() = aPageSize
.Width();
427 if ( aPageSize
.Height() > aDlgSize
.Height() )
428 aDlgSize
.Height() = aPageSize
.Height();
431 pPageData
= pPageData
->mpNext
;
434 ImplCalcSize( aDlgSize
);
435 SetOutputSizePixel( aDlgSize
);
440 ImplShowTabPage( ImplGetPage( mnCurLevel
) );
443 Dialog::StateChanged( nType
);
446 // -----------------------------------------------------------------------
448 long WizardDialog::Notify( NotifyEvent
& rNEvt
)
450 if ( (rNEvt
.GetType() == EVENT_KEYINPUT
) && mpPrevBtn
&& mpNextBtn
)
452 const KeyEvent
* pKEvt
= rNEvt
.GetKeyEvent();
453 KeyCode aKeyCode
= pKEvt
->GetKeyCode();
454 sal_uInt16 nKeyCode
= aKeyCode
.GetCode();
456 if ( aKeyCode
.IsMod1() )
458 if ( aKeyCode
.IsShift() || (nKeyCode
== KEY_PAGEUP
) )
460 if ( (nKeyCode
== KEY_TAB
) || (nKeyCode
== KEY_PAGEUP
) )
462 if ( mpPrevBtn
->IsVisible() &&
463 mpPrevBtn
->IsEnabled() && mpPrevBtn
->IsInputEnabled() )
465 mpPrevBtn
->SetPressed( sal_True
);
466 mpPrevBtn
->SetPressed( sal_False
);
474 if ( (nKeyCode
== KEY_TAB
) || (nKeyCode
== KEY_PAGEDOWN
) )
476 if ( mpNextBtn
->IsVisible() &&
477 mpNextBtn
->IsEnabled() && mpNextBtn
->IsInputEnabled() )
479 mpNextBtn
->SetPressed( sal_True
);
480 mpNextBtn
->SetPressed( sal_False
);
489 return Dialog::Notify( rNEvt
);
492 // -----------------------------------------------------------------------
494 void WizardDialog::ActivatePage()
496 maActivateHdl
.Call( this );
499 // -----------------------------------------------------------------------
501 long WizardDialog::DeactivatePage()
503 if ( maDeactivateHdl
.IsSet() )
504 return maDeactivateHdl
.Call( this );
509 // -----------------------------------------------------------------------
511 sal_Bool
WizardDialog::ShowNextPage()
513 return ShowPage( mnCurLevel
+1 );
516 // -----------------------------------------------------------------------
518 sal_Bool
WizardDialog::ShowPrevPage()
522 return ShowPage( mnCurLevel
-1 );
525 // -----------------------------------------------------------------------
527 sal_Bool
WizardDialog::ShowPage( sal_uInt16 nLevel
)
529 if ( DeactivatePage() )
533 ImplShowTabPage( ImplGetPage( mnCurLevel
) );
540 // -----------------------------------------------------------------------
542 sal_Bool
WizardDialog::Finnish( long nResult
)
544 if ( DeactivatePage() )
547 mpCurTabPage
->DeactivatePage();
550 EndDialog( nResult
);
551 else if ( GetStyle() & WB_CLOSEABLE
)
559 // -----------------------------------------------------------------------
561 void WizardDialog::AddPage( TabPage
* pPage
)
563 ImplWizPageData
* pNewPageData
= new ImplWizPageData
;
564 pNewPageData
->mpNext
= NULL
;
565 pNewPageData
->mpPage
= pPage
;
568 mpFirstPage
= pNewPageData
;
571 ImplWizPageData
* pPageData
= mpFirstPage
;
572 while ( pPageData
->mpNext
)
573 pPageData
= pPageData
->mpNext
;
574 pPageData
->mpNext
= pNewPageData
;
578 // -----------------------------------------------------------------------
580 void WizardDialog::RemovePage( TabPage
* pPage
)
582 ImplWizPageData
* pPrevPageData
= NULL
;
583 ImplWizPageData
* pPageData
= mpFirstPage
;
586 if ( pPageData
->mpPage
== pPage
)
589 pPrevPageData
->mpNext
= pPageData
->mpNext
;
591 mpFirstPage
= pPageData
->mpNext
;
592 if ( pPage
== mpCurTabPage
)
598 pPrevPageData
= pPageData
;
599 pPageData
= pPageData
->mpNext
;
602 OSL_FAIL( "WizardDialog::RemovePage() - Page not in list" );
605 // -----------------------------------------------------------------------
607 void WizardDialog::SetPage( sal_uInt16 nLevel
, TabPage
* pPage
)
609 sal_uInt16 nTempLevel
= 0;
610 ImplWizPageData
* pPageData
= mpFirstPage
;
613 if ( (nTempLevel
== nLevel
) || !pPageData
->mpNext
)
617 pPageData
= pPageData
->mpNext
;
622 if ( pPageData
->mpPage
== mpCurTabPage
)
624 pPageData
->mpPage
= pPage
;
628 // -----------------------------------------------------------------------
630 TabPage
* WizardDialog::GetPage( sal_uInt16 nLevel
) const
632 sal_uInt16 nTempLevel
= 0;
633 ImplWizPageData
* pPageData
= mpFirstPage
;
636 if ( nTempLevel
== nLevel
)
637 return pPageData
->mpPage
;
640 pPageData
= pPageData
->mpNext
;
646 // -----------------------------------------------------------------------
648 void WizardDialog::AddButton( Button
* pButton
, long nOffset
)
650 ImplWizButtonData
* pNewBtnData
= new ImplWizButtonData
;
651 pNewBtnData
->mpNext
= NULL
;
652 pNewBtnData
->mpButton
= pButton
;
653 pNewBtnData
->mnOffset
= nOffset
;
656 mpFirstBtn
= pNewBtnData
;
659 ImplWizButtonData
* pBtnData
= mpFirstBtn
;
660 while ( pBtnData
->mpNext
)
661 pBtnData
= pBtnData
->mpNext
;
662 pBtnData
->mpNext
= pNewBtnData
;
666 // -----------------------------------------------------------------------
668 void WizardDialog::RemoveButton( Button
* pButton
)
670 ImplWizButtonData
* pPrevBtnData
= NULL
;
671 ImplWizButtonData
* pBtnData
= mpFirstBtn
;
674 if ( pBtnData
->mpButton
== pButton
)
677 pPrevBtnData
->mpNext
= pBtnData
->mpNext
;
679 mpFirstBtn
= pBtnData
->mpNext
;
684 pPrevBtnData
= pBtnData
;
685 pBtnData
= pBtnData
->mpNext
;
688 OSL_FAIL( "WizardDialog::RemoveButton() - Button not in list" );
691 // -----------------------------------------------------------------------
693 void WizardDialog::ShowButtonFixedLine( sal_Bool bVisible
)
700 mpFixedLine
= new FixedLine( this );
703 mpFixedLine
->Show( bVisible
);
706 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */