update dev300-m58
[ooovba.git] / svtools / source / dialogs / wizdlg.cxx
blobf558053358acfbdbfe6c2a485b23c55e441d8ca6
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: wizdlg.cxx,v $
10 * $Revision: 1.12 $
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>
38 #endif
39 #ifndef _VCL_BUTTON_HXX
40 #include <vcl/button.hxx>
41 #endif
42 #ifndef _VCL_TABPAGE_HXX
43 #include <vcl/tabpage.hxx>
44 #endif
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;
59 TabPage* mpPage;
62 // -----------------------------------------------------------------------
64 struct ImplWizButtonData
66 ImplWizButtonData* mpNext;
67 Button* mpButton;
68 long mnOffset;
71 // =======================================================================
73 void WizardDialog::ImplInitData()
75 mpFirstPage = NULL;
76 mpFirstBtn = NULL;
77 mpFixedLine = NULL;
78 mpCurTabPage = NULL;
79 mpPrevBtn = NULL;
80 mpNextBtn = NULL;
81 mpViewWindow = NULL;
82 mnCurLevel = 0;
83 meViewAlign = WINDOWALIGN_LEFT;
84 mbEmptyViewMargin = false;
85 mnLeftAlignCount = 0;
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
106 long nMaxHeight = 0;
107 ImplWizButtonData* pBtnData = mpFirstBtn;
108 while ( pBtnData )
110 long nBtnHeight = pBtnData->mpButton->GetSizePixel().Height();
111 if ( nBtnHeight > nMaxHeight )
112 nMaxHeight = nBtnHeight;
113 pBtnData = pBtnData->mpNext;
115 if ( nMaxHeight )
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();
141 long nBtnWidth = 0;
142 long nMaxHeight = 0;
143 long nOffY = aDlgSize.Height();
145 ImplWizButtonData* pBtnData = mpFirstBtn;
146 int j = 0;
147 while ( pBtnData )
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;
159 j++;
162 if ( nMaxHeight )
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;
169 int i = 0;
170 while ( pBtnData )
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;
180 else
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;
189 i++;
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() )
204 long nViewOffX = 0;
205 long nViewOffY = 0;
206 long nViewWidth = 0;
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 )
221 nViewOffX = 0;
222 nViewOffY = 0;
223 nViewHeight = nDlgHeight;
225 else
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,
249 nViewPosFlags );
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()
265 if ( !mpCurTabPage )
266 return;
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() )
273 return;
276 // ButtonBar-Hoehe berechnen
277 long nMaxHeight = 0;
278 ImplWizButtonData* pBtnData = mpFirstBtn;
279 while ( pBtnData )
281 long nBtnHeight = pBtnData->mpButton->GetSizePixel().Height();
282 if ( nBtnHeight > nMaxHeight )
283 nMaxHeight = nBtnHeight;
284 pBtnData = pBtnData->mpNext;
286 if ( nMaxHeight )
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;
294 long nOffX = 0;
295 long nOffY = 0;
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 )
323 return;
325 TabPage* pOldTabPage = mpCurTabPage;
326 if ( pOldTabPage )
327 pOldTabPage->DeactivatePage();
329 mpCurTabPage = pTabPage;
330 if ( pTabPage )
332 ImplPosTabPage();
333 pTabPage->ActivatePage();
334 pTabPage->Show();
337 if ( pOldTabPage )
338 pOldTabPage->Hide();
341 // -----------------------------------------------------------------------
343 TabPage* WizardDialog::ImplGetPage( USHORT nLevel ) const
345 USHORT nTempLevel = 0;
346 ImplWizPageData* pPageData = mpFirstPage;
347 while ( pPageData )
349 if ( (nTempLevel == nLevel) || !pPageData->mpNext )
350 break;
352 nTempLevel++;
353 pPageData = pPageData->mpNext;
356 if ( pPageData )
357 return pPageData->mpPage;
358 return NULL;
361 // =======================================================================
363 WizardDialog::WizardDialog( Window* pParent, WinBits nStyle ) :
364 ModalDialog( pParent, nStyle )
366 ImplInitData();
369 // -----------------------------------------------------------------------
371 WizardDialog::WizardDialog( Window* pParent, const ResId& rResId ) :
372 ModalDialog( pParent, rResId )
374 ImplInitData();
377 // -----------------------------------------------------------------------
379 WizardDialog::~WizardDialog()
381 if ( mpFixedLine )
382 delete mpFixedLine;
384 // Remove all buttons
385 while ( mpFirstBtn )
386 RemoveButton( mpFirstBtn->mpButton );
388 // Remove all pages
389 while ( mpFirstPage )
390 RemovePage( mpFirstPage->mpPage );
393 // -----------------------------------------------------------------------
395 void WizardDialog::Resize()
397 if ( IsReallyShown() && !IsInInitShow() )
399 ImplPosCtrls();
400 ImplPosTabPage();
403 Dialog::Resize();
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;
418 while ( pPageData )
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 );
436 ImplPosCtrls();
437 ImplPosTabPage();
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 );
465 mpPrevBtn->Click();
467 return TRUE;
470 else
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 );
479 mpNextBtn->Click();
481 return TRUE;
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 );
503 else
504 return TRUE;
507 // -----------------------------------------------------------------------
509 BOOL WizardDialog::ShowNextPage()
511 return ShowPage( mnCurLevel+1 );
514 // -----------------------------------------------------------------------
516 BOOL WizardDialog::ShowPrevPage()
518 if ( !mnCurLevel )
519 return FALSE;
520 return ShowPage( mnCurLevel-1 );
523 // -----------------------------------------------------------------------
525 BOOL WizardDialog::ShowPage( USHORT nLevel )
527 if ( DeactivatePage() )
529 mnCurLevel = nLevel;
530 ActivatePage();
531 ImplShowTabPage( ImplGetPage( mnCurLevel ) );
532 return TRUE;
534 else
535 return FALSE;
538 // -----------------------------------------------------------------------
540 BOOL WizardDialog::Finnish( long nResult )
542 if ( DeactivatePage() )
544 if ( mpCurTabPage )
545 mpCurTabPage->DeactivatePage();
547 if ( IsInExecute() )
548 EndDialog( nResult );
549 else if ( GetStyle() & WB_CLOSEABLE )
550 Close();
551 return TRUE;
553 else
554 return FALSE;
557 // -----------------------------------------------------------------------
559 void WizardDialog::AddPage( TabPage* pPage )
561 ImplWizPageData* pNewPageData = new ImplWizPageData;
562 pNewPageData->mpNext = NULL;
563 pNewPageData->mpPage = pPage;
565 if ( !mpFirstPage )
566 mpFirstPage = pNewPageData;
567 else
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;
582 while ( pPageData )
584 if ( pPageData->mpPage == pPage )
586 if ( pPrevPageData )
587 pPrevPageData->mpNext = pPageData->mpNext;
588 else
589 mpFirstPage = pPageData->mpNext;
590 if ( pPage == mpCurTabPage )
591 mpCurTabPage = NULL;
592 delete pPageData;
593 return;
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;
609 while ( pPageData )
611 if ( (nTempLevel == nLevel) || !pPageData->mpNext )
612 break;
614 nTempLevel++;
615 pPageData = pPageData->mpNext;
618 if ( pPageData )
620 if ( pPageData->mpPage == mpCurTabPage )
621 mpCurTabPage = NULL;
622 pPageData->mpPage = pPage;
626 // -----------------------------------------------------------------------
628 TabPage* WizardDialog::GetPage( USHORT nLevel ) const
630 USHORT nTempLevel = 0;
631 ImplWizPageData* pPageData = mpFirstPage;
632 while ( pPageData )
634 if ( nTempLevel == nLevel )
635 return pPageData->mpPage;
637 nTempLevel++;
638 pPageData = pPageData->mpNext;
641 return NULL;
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;
653 if ( !mpFirstBtn )
654 mpFirstBtn = pNewBtnData;
655 else
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;
670 while ( pBtnData )
672 if ( pBtnData->mpButton == pButton )
674 if ( pPrevBtnData )
675 pPrevBtnData->mpNext = pBtnData->mpNext;
676 else
677 mpFirstBtn = pBtnData->mpNext;
678 delete pBtnData;
679 return;
682 pPrevBtnData = pBtnData;
683 pBtnData = pBtnData->mpNext;
686 DBG_ERROR( "WizardDialog::RemoveButton() - Button not in list" );
689 // -----------------------------------------------------------------------
691 void WizardDialog::ShowButtonFixedLine( BOOL bVisible )
693 if ( !mpFixedLine )
695 if ( !bVisible )
696 return;
698 mpFixedLine = new FixedLine( this );
701 mpFixedLine->Show( bVisible );
704 // -----------------------------------------------------------------------
706 BOOL WizardDialog::IsButtonFixedLineVisible()
708 return (mpFixedLine && mpFixedLine->IsVisible());