merge the formfield patch from ooo-build
[ooovba.git] / svtools / source / dialogs / wizdlg.cxx
blob19473ac1e7590ad1553b9180e9485be93eccd63a
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 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 )
324 return;
326 TabPage* pOldTabPage = mpCurTabPage;
327 if ( pOldTabPage )
328 pOldTabPage->DeactivatePage();
330 mpCurTabPage = pTabPage;
331 if ( pTabPage )
333 ImplPosTabPage();
334 pTabPage->ActivatePage();
335 pTabPage->Show();
338 if ( pOldTabPage )
339 pOldTabPage->Hide();
342 // -----------------------------------------------------------------------
344 TabPage* WizardDialog::ImplGetPage( USHORT nLevel ) const
346 USHORT nTempLevel = 0;
347 ImplWizPageData* pPageData = mpFirstPage;
348 while ( pPageData )
350 if ( (nTempLevel == nLevel) || !pPageData->mpNext )
351 break;
353 nTempLevel++;
354 pPageData = pPageData->mpNext;
357 if ( pPageData )
358 return pPageData->mpPage;
359 return NULL;
362 // =======================================================================
364 WizardDialog::WizardDialog( Window* pParent, WinBits nStyle ) :
365 ModalDialog( pParent, nStyle )
367 ImplInitData();
370 // -----------------------------------------------------------------------
372 WizardDialog::WizardDialog( Window* pParent, const ResId& rResId ) :
373 ModalDialog( pParent, rResId )
375 ImplInitData();
378 // -----------------------------------------------------------------------
380 WizardDialog::~WizardDialog()
382 if ( mpFixedLine )
383 delete mpFixedLine;
385 // Remove all buttons
386 while ( mpFirstBtn )
387 RemoveButton( mpFirstBtn->mpButton );
389 // Remove all pages
390 while ( mpFirstPage )
391 RemovePage( mpFirstPage->mpPage );
394 // -----------------------------------------------------------------------
396 void WizardDialog::Resize()
398 if ( IsReallyShown() && !IsInInitShow() )
400 ImplPosCtrls();
401 ImplPosTabPage();
404 Dialog::Resize();
407 // -----------------------------------------------------------------------
409 void WizardDialog::StateChanged( StateChangedType nType )
411 if ( nType == STATE_CHANGE_INITSHOW )
413 if ( IsDefaultSize() )
415 Size aDlgSize = GetPageSizePixel();
416 if ( !aDlgSize.Width() || !aDlgSize.Height() )
418 ImplWizPageData* pPageData = mpFirstPage;
419 while ( pPageData )
421 if ( pPageData->mpPage )
423 Size aPageSize = pPageData->mpPage->GetSizePixel();
424 if ( aPageSize.Width() > aDlgSize.Width() )
425 aDlgSize.Width() = aPageSize.Width();
426 if ( aPageSize.Height() > aDlgSize.Height() )
427 aDlgSize.Height() = aPageSize.Height();
430 pPageData = pPageData->mpNext;
433 ImplCalcSize( aDlgSize );
434 SetOutputSizePixel( aDlgSize );
437 ImplPosCtrls();
438 ImplPosTabPage();
439 ImplShowTabPage( ImplGetPage( mnCurLevel ) );
442 Dialog::StateChanged( nType );
445 // -----------------------------------------------------------------------
447 long WizardDialog::Notify( NotifyEvent& rNEvt )
449 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && mpPrevBtn && mpNextBtn )
451 const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
452 KeyCode aKeyCode = pKEvt->GetKeyCode();
453 USHORT nKeyCode = aKeyCode.GetCode();
455 if ( aKeyCode.IsMod1() )
457 if ( aKeyCode.IsShift() || (nKeyCode == KEY_PAGEUP) )
459 if ( (nKeyCode == KEY_TAB) || (nKeyCode == KEY_PAGEUP) )
461 if ( mpPrevBtn->IsVisible() &&
462 mpPrevBtn->IsEnabled() && mpPrevBtn->IsInputEnabled() )
464 mpPrevBtn->SetPressed( TRUE );
465 mpPrevBtn->SetPressed( FALSE );
466 mpPrevBtn->Click();
468 return TRUE;
471 else
473 if ( (nKeyCode == KEY_TAB) || (nKeyCode == KEY_PAGEDOWN) )
475 if ( mpNextBtn->IsVisible() &&
476 mpNextBtn->IsEnabled() && mpNextBtn->IsInputEnabled() )
478 mpNextBtn->SetPressed( TRUE );
479 mpNextBtn->SetPressed( FALSE );
480 mpNextBtn->Click();
482 return TRUE;
488 return Dialog::Notify( rNEvt );
491 // -----------------------------------------------------------------------
493 void WizardDialog::ActivatePage()
495 maActivateHdl.Call( this );
498 // -----------------------------------------------------------------------
500 long WizardDialog::DeactivatePage()
502 if ( maDeactivateHdl.IsSet() )
503 return maDeactivateHdl.Call( this );
504 else
505 return TRUE;
508 // -----------------------------------------------------------------------
510 BOOL WizardDialog::ShowNextPage()
512 return ShowPage( mnCurLevel+1 );
515 // -----------------------------------------------------------------------
517 BOOL WizardDialog::ShowPrevPage()
519 if ( !mnCurLevel )
520 return FALSE;
521 return ShowPage( mnCurLevel-1 );
524 // -----------------------------------------------------------------------
526 BOOL WizardDialog::ShowPage( USHORT nLevel )
528 if ( DeactivatePage() )
530 mnCurLevel = nLevel;
531 ActivatePage();
532 ImplShowTabPage( ImplGetPage( mnCurLevel ) );
533 return TRUE;
535 else
536 return FALSE;
539 // -----------------------------------------------------------------------
541 BOOL WizardDialog::Finnish( long nResult )
543 if ( DeactivatePage() )
545 if ( mpCurTabPage )
546 mpCurTabPage->DeactivatePage();
548 if ( IsInExecute() )
549 EndDialog( nResult );
550 else if ( GetStyle() & WB_CLOSEABLE )
551 Close();
552 return TRUE;
554 else
555 return FALSE;
558 // -----------------------------------------------------------------------
560 void WizardDialog::AddPage( TabPage* pPage )
562 ImplWizPageData* pNewPageData = new ImplWizPageData;
563 pNewPageData->mpNext = NULL;
564 pNewPageData->mpPage = pPage;
566 if ( !mpFirstPage )
567 mpFirstPage = pNewPageData;
568 else
570 ImplWizPageData* pPageData = mpFirstPage;
571 while ( pPageData->mpNext )
572 pPageData = pPageData->mpNext;
573 pPageData->mpNext = pNewPageData;
577 // -----------------------------------------------------------------------
579 void WizardDialog::RemovePage( TabPage* pPage )
581 ImplWizPageData* pPrevPageData = NULL;
582 ImplWizPageData* pPageData = mpFirstPage;
583 while ( pPageData )
585 if ( pPageData->mpPage == pPage )
587 if ( pPrevPageData )
588 pPrevPageData->mpNext = pPageData->mpNext;
589 else
590 mpFirstPage = pPageData->mpNext;
591 if ( pPage == mpCurTabPage )
592 mpCurTabPage = NULL;
593 delete pPageData;
594 return;
597 pPrevPageData = pPageData;
598 pPageData = pPageData->mpNext;
601 DBG_ERROR( "WizardDialog::RemovePage() - Page not in list" );
604 // -----------------------------------------------------------------------
606 void WizardDialog::SetPage( USHORT nLevel, TabPage* pPage )
608 USHORT nTempLevel = 0;
609 ImplWizPageData* pPageData = mpFirstPage;
610 while ( pPageData )
612 if ( (nTempLevel == nLevel) || !pPageData->mpNext )
613 break;
615 nTempLevel++;
616 pPageData = pPageData->mpNext;
619 if ( pPageData )
621 if ( pPageData->mpPage == mpCurTabPage )
622 mpCurTabPage = NULL;
623 pPageData->mpPage = pPage;
627 // -----------------------------------------------------------------------
629 TabPage* WizardDialog::GetPage( USHORT nLevel ) const
631 USHORT nTempLevel = 0;
632 ImplWizPageData* pPageData = mpFirstPage;
633 while ( pPageData )
635 if ( nTempLevel == nLevel )
636 return pPageData->mpPage;
638 nTempLevel++;
639 pPageData = pPageData->mpNext;
642 return NULL;
645 // -----------------------------------------------------------------------
647 void WizardDialog::AddButton( Button* pButton, long nOffset )
649 ImplWizButtonData* pNewBtnData = new ImplWizButtonData;
650 pNewBtnData->mpNext = NULL;
651 pNewBtnData->mpButton = pButton;
652 pNewBtnData->mnOffset = nOffset;
654 if ( !mpFirstBtn )
655 mpFirstBtn = pNewBtnData;
656 else
658 ImplWizButtonData* pBtnData = mpFirstBtn;
659 while ( pBtnData->mpNext )
660 pBtnData = pBtnData->mpNext;
661 pBtnData->mpNext = pNewBtnData;
665 // -----------------------------------------------------------------------
667 void WizardDialog::RemoveButton( Button* pButton )
669 ImplWizButtonData* pPrevBtnData = NULL;
670 ImplWizButtonData* pBtnData = mpFirstBtn;
671 while ( pBtnData )
673 if ( pBtnData->mpButton == pButton )
675 if ( pPrevBtnData )
676 pPrevBtnData->mpNext = pBtnData->mpNext;
677 else
678 mpFirstBtn = pBtnData->mpNext;
679 delete pBtnData;
680 return;
683 pPrevBtnData = pBtnData;
684 pBtnData = pBtnData->mpNext;
687 DBG_ERROR( "WizardDialog::RemoveButton() - Button not in list" );
690 // -----------------------------------------------------------------------
692 void WizardDialog::ShowButtonFixedLine( BOOL bVisible )
694 if ( !mpFixedLine )
696 if ( !bVisible )
697 return;
699 mpFixedLine = new FixedLine( this );
702 mpFixedLine->Show( bVisible );
705 // -----------------------------------------------------------------------
707 BOOL WizardDialog::IsButtonFixedLineVisible()
709 return (mpFixedLine && mpFixedLine->IsVisible());