1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: wizdlg.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
34 #define _SVT_WIZDLG_CXX
35 #include <tools/debug.hxx>
36 #ifndef _VCL_FIXED_HXX
37 #include <vcl/fixed.hxx>
39 #ifndef _VCL_BUTTON_HXX
40 #include <vcl/button.hxx>
42 #ifndef _VCL_TABPAGE_HXX
43 #include <vcl/tabpage.hxx>
45 #include <svtools/wizdlg.hxx>
47 // =======================================================================
49 #define WIZARDDIALOG_BUTTON_OFFSET_Y 6
50 #define WIZARDDIALOG_BUTTON_DLGOFFSET_X 6
51 #define WIZARDDIALOG_VIEW_DLGOFFSET_X 6
52 #define WIZARDDIALOG_VIEW_DLGOFFSET_Y 6
54 // =======================================================================
56 struct ImplWizPageData
58 ImplWizPageData
* mpNext
;
62 // -----------------------------------------------------------------------
64 struct ImplWizButtonData
66 ImplWizButtonData
* mpNext
;
71 // =======================================================================
73 void WizardDialog::ImplInitData()
83 meViewAlign
= WINDOWALIGN_LEFT
;
84 mbEmptyViewMargin
= false;
88 // -----------------------------------------------------------------------
89 void WizardDialog::SetLeftAlignedButtonCount( sal_Int16 _nCount
)
91 mnLeftAlignCount
= _nCount
;
94 // -----------------------------------------------------------------------
96 void WizardDialog::SetEmptyViewMargin()
98 mbEmptyViewMargin
= true;
101 // -----------------------------------------------------------------------
103 void WizardDialog::ImplCalcSize( Size
& rSize
)
105 // ButtonBar-Hoehe berechnen
107 ImplWizButtonData
* pBtnData
= mpFirstBtn
;
110 long nBtnHeight
= pBtnData
->mpButton
->GetSizePixel().Height();
111 if ( nBtnHeight
> nMaxHeight
)
112 nMaxHeight
= nBtnHeight
;
113 pBtnData
= pBtnData
->mpNext
;
116 nMaxHeight
+= WIZARDDIALOG_BUTTON_OFFSET_Y
*2;
117 if ( mpFixedLine
&& mpFixedLine
->IsVisible() )
118 nMaxHeight
+= mpFixedLine
->GetSizePixel().Height();
119 rSize
.Height() += nMaxHeight
;
121 // View-Window-Groesse dazurechnen
122 if ( mpViewWindow
&& mpViewWindow
->IsVisible() )
124 Size aViewSize
= mpViewWindow
->GetSizePixel();
125 if ( meViewAlign
== WINDOWALIGN_TOP
)
126 rSize
.Height() += aViewSize
.Height();
127 else if ( meViewAlign
== WINDOWALIGN_LEFT
)
128 rSize
.Width() += aViewSize
.Width();
129 else if ( meViewAlign
== WINDOWALIGN_BOTTOM
)
130 rSize
.Height() += aViewSize
.Height();
131 else if ( meViewAlign
== WINDOWALIGN_RIGHT
)
132 rSize
.Width() += aViewSize
.Width();
136 // -----------------------------------------------------------------------
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 USHORT 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 nOffX
+= aViewSize
.Width()+WIZARDDIALOG_VIEW_DLGOFFSET_X
;
307 aDlgSize
.Width() -= aViewSize
.Width()+WIZARDDIALOG_VIEW_DLGOFFSET_X
;
309 else if ( meViewAlign
== WINDOWALIGN_BOTTOM
)
310 aDlgSize
.Height() -= aViewSize
.Height()+WIZARDDIALOG_VIEW_DLGOFFSET_Y
;
311 else if ( meViewAlign
== WINDOWALIGN_RIGHT
)
312 aDlgSize
.Width() -= aViewSize
.Width()+WIZARDDIALOG_VIEW_DLGOFFSET_X
;
314 Point
aPos( nOffX
, nOffY
);
315 mpCurTabPage
->SetPosSizePixel( aPos
, aDlgSize
);
318 // -----------------------------------------------------------------------
320 void WizardDialog::ImplShowTabPage( TabPage
* pTabPage
)
322 if ( mpCurTabPage
== pTabPage
)
325 TabPage
* pOldTabPage
= mpCurTabPage
;
327 pOldTabPage
->DeactivatePage();
329 mpCurTabPage
= pTabPage
;
333 pTabPage
->ActivatePage();
341 // -----------------------------------------------------------------------
343 TabPage
* WizardDialog::ImplGetPage( USHORT nLevel
) const
345 USHORT nTempLevel
= 0;
346 ImplWizPageData
* pPageData
= mpFirstPage
;
349 if ( (nTempLevel
== nLevel
) || !pPageData
->mpNext
)
353 pPageData
= pPageData
->mpNext
;
357 return pPageData
->mpPage
;
361 // =======================================================================
363 WizardDialog::WizardDialog( Window
* pParent
, WinBits nStyle
) :
364 ModalDialog( pParent
, nStyle
)
369 // -----------------------------------------------------------------------
371 WizardDialog::WizardDialog( Window
* pParent
, const ResId
& rResId
) :
372 ModalDialog( pParent
, rResId
)
377 // -----------------------------------------------------------------------
379 WizardDialog::~WizardDialog()
384 // Remove all buttons
386 RemoveButton( mpFirstBtn
->mpButton
);
389 while ( mpFirstPage
)
390 RemovePage( mpFirstPage
->mpPage
);
393 // -----------------------------------------------------------------------
395 void WizardDialog::Resize()
397 if ( IsReallyShown() && !IsInInitShow() )
406 // -----------------------------------------------------------------------
408 void WizardDialog::StateChanged( StateChangedType nType
)
410 if ( nType
== STATE_CHANGE_INITSHOW
)
412 if ( IsDefaultSize() )
414 Size aDlgSize
= GetPageSizePixel();
415 if ( !aDlgSize
.Width() || !aDlgSize
.Height() )
417 ImplWizPageData
* pPageData
= mpFirstPage
;
420 if ( pPageData
->mpPage
)
422 Size aPageSize
= pPageData
->mpPage
->GetSizePixel();
423 if ( aPageSize
.Width() > aDlgSize
.Width() )
424 aDlgSize
.Width() = aPageSize
.Width();
425 if ( aPageSize
.Height() > aDlgSize
.Height() )
426 aDlgSize
.Height() = aPageSize
.Height();
429 pPageData
= pPageData
->mpNext
;
432 ImplCalcSize( aDlgSize
);
433 SetOutputSizePixel( aDlgSize
);
438 ImplShowTabPage( ImplGetPage( mnCurLevel
) );
441 Dialog::StateChanged( nType
);
444 // -----------------------------------------------------------------------
446 long WizardDialog::Notify( NotifyEvent
& rNEvt
)
448 if ( (rNEvt
.GetType() == EVENT_KEYINPUT
) && mpPrevBtn
&& mpNextBtn
)
450 const KeyEvent
* pKEvt
= rNEvt
.GetKeyEvent();
451 KeyCode aKeyCode
= pKEvt
->GetKeyCode();
452 USHORT nKeyCode
= aKeyCode
.GetCode();
454 if ( aKeyCode
.IsMod1() )
456 if ( aKeyCode
.IsShift() || (nKeyCode
== KEY_PAGEUP
) )
458 if ( (nKeyCode
== KEY_TAB
) || (nKeyCode
== KEY_PAGEUP
) )
460 if ( mpPrevBtn
->IsVisible() &&
461 mpPrevBtn
->IsEnabled() && mpPrevBtn
->IsInputEnabled() )
463 mpPrevBtn
->SetPressed( TRUE
);
464 mpPrevBtn
->SetPressed( FALSE
);
472 if ( (nKeyCode
== KEY_TAB
) || (nKeyCode
== KEY_PAGEDOWN
) )
474 if ( mpNextBtn
->IsVisible() &&
475 mpNextBtn
->IsEnabled() && mpNextBtn
->IsInputEnabled() )
477 mpNextBtn
->SetPressed( TRUE
);
478 mpNextBtn
->SetPressed( FALSE
);
487 return Dialog::Notify( rNEvt
);
490 // -----------------------------------------------------------------------
492 void WizardDialog::ActivatePage()
494 maActivateHdl
.Call( this );
497 // -----------------------------------------------------------------------
499 long WizardDialog::DeactivatePage()
501 if ( maDeactivateHdl
.IsSet() )
502 return maDeactivateHdl
.Call( this );
507 // -----------------------------------------------------------------------
509 BOOL
WizardDialog::ShowNextPage()
511 return ShowPage( mnCurLevel
+1 );
514 // -----------------------------------------------------------------------
516 BOOL
WizardDialog::ShowPrevPage()
520 return ShowPage( mnCurLevel
-1 );
523 // -----------------------------------------------------------------------
525 BOOL
WizardDialog::ShowPage( USHORT nLevel
)
527 if ( DeactivatePage() )
531 ImplShowTabPage( ImplGetPage( mnCurLevel
) );
538 // -----------------------------------------------------------------------
540 BOOL
WizardDialog::Finnish( long nResult
)
542 if ( DeactivatePage() )
545 mpCurTabPage
->DeactivatePage();
548 EndDialog( nResult
);
549 else if ( GetStyle() & WB_CLOSEABLE
)
557 // -----------------------------------------------------------------------
559 void WizardDialog::AddPage( TabPage
* pPage
)
561 ImplWizPageData
* pNewPageData
= new ImplWizPageData
;
562 pNewPageData
->mpNext
= NULL
;
563 pNewPageData
->mpPage
= pPage
;
566 mpFirstPage
= pNewPageData
;
569 ImplWizPageData
* pPageData
= mpFirstPage
;
570 while ( pPageData
->mpNext
)
571 pPageData
= pPageData
->mpNext
;
572 pPageData
->mpNext
= pNewPageData
;
576 // -----------------------------------------------------------------------
578 void WizardDialog::RemovePage( TabPage
* pPage
)
580 ImplWizPageData
* pPrevPageData
= NULL
;
581 ImplWizPageData
* pPageData
= mpFirstPage
;
584 if ( pPageData
->mpPage
== pPage
)
587 pPrevPageData
->mpNext
= pPageData
->mpNext
;
589 mpFirstPage
= pPageData
->mpNext
;
590 if ( pPage
== mpCurTabPage
)
596 pPrevPageData
= pPageData
;
597 pPageData
= pPageData
->mpNext
;
600 DBG_ERROR( "WizardDialog::RemovePage() - Page not in list" );
603 // -----------------------------------------------------------------------
605 void WizardDialog::SetPage( USHORT nLevel
, TabPage
* pPage
)
607 USHORT nTempLevel
= 0;
608 ImplWizPageData
* pPageData
= mpFirstPage
;
611 if ( (nTempLevel
== nLevel
) || !pPageData
->mpNext
)
615 pPageData
= pPageData
->mpNext
;
620 if ( pPageData
->mpPage
== mpCurTabPage
)
622 pPageData
->mpPage
= pPage
;
626 // -----------------------------------------------------------------------
628 TabPage
* WizardDialog::GetPage( USHORT nLevel
) const
630 USHORT nTempLevel
= 0;
631 ImplWizPageData
* pPageData
= mpFirstPage
;
634 if ( nTempLevel
== nLevel
)
635 return pPageData
->mpPage
;
638 pPageData
= pPageData
->mpNext
;
644 // -----------------------------------------------------------------------
646 void WizardDialog::AddButton( Button
* pButton
, long nOffset
)
648 ImplWizButtonData
* pNewBtnData
= new ImplWizButtonData
;
649 pNewBtnData
->mpNext
= NULL
;
650 pNewBtnData
->mpButton
= pButton
;
651 pNewBtnData
->mnOffset
= nOffset
;
654 mpFirstBtn
= pNewBtnData
;
657 ImplWizButtonData
* pBtnData
= mpFirstBtn
;
658 while ( pBtnData
->mpNext
)
659 pBtnData
= pBtnData
->mpNext
;
660 pBtnData
->mpNext
= pNewBtnData
;
664 // -----------------------------------------------------------------------
666 void WizardDialog::RemoveButton( Button
* pButton
)
668 ImplWizButtonData
* pPrevBtnData
= NULL
;
669 ImplWizButtonData
* pBtnData
= mpFirstBtn
;
672 if ( pBtnData
->mpButton
== pButton
)
675 pPrevBtnData
->mpNext
= pBtnData
->mpNext
;
677 mpFirstBtn
= pBtnData
->mpNext
;
682 pPrevBtnData
= pBtnData
;
683 pBtnData
= pBtnData
->mpNext
;
686 DBG_ERROR( "WizardDialog::RemoveButton() - Button not in list" );
689 // -----------------------------------------------------------------------
691 void WizardDialog::ShowButtonFixedLine( BOOL bVisible
)
698 mpFixedLine
= new FixedLine( this );
701 mpFixedLine
->Show( bVisible
);
704 // -----------------------------------------------------------------------
706 BOOL
WizardDialog::IsButtonFixedLineVisible()
708 return (mpFixedLine
&& mpFixedLine
->IsVisible());