update dev300-m58
[ooovba.git] / vcl / source / window / dialog.cxx
blobcb71e0c3dc37fb8294b5658d0897a0d42485db5e
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: dialog.cxx,v $
10 * $Revision: 1.46 $
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_vcl.hxx"
33 #include <tools/debug.hxx>
35 #ifndef _SV_RC_H
36 #include <tools/rc.h>
37 #endif
38 #include <vcl/svdata.hxx>
39 #include <vcl/svapp.hxx>
40 #include <vcl/window.h>
41 #include <vcl/event.hxx>
42 #include <vcl/brdwin.hxx>
43 #include <vcl/wrkwin.hxx>
44 #include <vcl/button.hxx>
45 #include <vcl/mnemonic.hxx>
46 #include <vcl/dialog.hxx>
47 #include <vcl/decoview.hxx>
49 #ifdef DBG_UTIL
50 #include <vcl/msgbox.hxx>
51 #endif
53 #include <vcl/unowrap.hxx>
57 // =======================================================================
59 #ifdef DBG_UTIL
61 static ByteString ImplGetDialogText( Dialog* pDialog )
63 ByteString aErrorStr( pDialog->GetText(), RTL_TEXTENCODING_UTF8 );
64 if ( (pDialog->GetType() == WINDOW_MESSBOX) ||
65 (pDialog->GetType() == WINDOW_INFOBOX) ||
66 (pDialog->GetType() == WINDOW_WARNINGBOX) ||
67 (pDialog->GetType() == WINDOW_ERRORBOX) ||
68 (pDialog->GetType() == WINDOW_QUERYBOX) )
70 aErrorStr += ", ";
71 aErrorStr += ByteString( ((MessBox*)pDialog)->GetMessText(), RTL_TEXTENCODING_UTF8 );
73 return aErrorStr;
76 #endif
78 // =======================================================================
80 static BOOL ImplIsMnemonicCtrl( Window* pWindow )
82 if( ! pWindow->GetSettings().GetStyleSettings().GetAutoMnemonic() )
83 return FALSE;
85 if ( (pWindow->GetType() == WINDOW_RADIOBUTTON) ||
86 (pWindow->GetType() == WINDOW_CHECKBOX) ||
87 (pWindow->GetType() == WINDOW_TRISTATEBOX) ||
88 (pWindow->GetType() == WINDOW_PUSHBUTTON) )
89 return TRUE;
91 if ( pWindow->GetType() == WINDOW_FIXEDTEXT )
93 if ( pWindow->GetStyle() & (WB_INFO | WB_NOLABEL) )
94 return FALSE;
95 Window* pNextWindow = pWindow->GetWindow( WINDOW_NEXT );
96 if ( !pNextWindow )
97 return FALSE;
98 pNextWindow = pNextWindow->GetWindow( WINDOW_CLIENT );
99 if ( !(pNextWindow->GetStyle() & WB_TABSTOP) ||
100 (pNextWindow->GetType() == WINDOW_FIXEDTEXT) ||
101 (pNextWindow->GetType() == WINDOW_GROUPBOX) ||
102 (pNextWindow->GetType() == WINDOW_RADIOBUTTON) ||
103 (pNextWindow->GetType() == WINDOW_CHECKBOX) ||
104 (pNextWindow->GetType() == WINDOW_TRISTATEBOX) ||
105 (pNextWindow->GetType() == WINDOW_PUSHBUTTON) )
106 return FALSE;
108 return TRUE;
111 return FALSE;
114 // -----------------------------------------------------------------------
116 void ImplWindowAutoMnemonic( Window* pWindow )
118 MnemonicGenerator aMnemonicGenerator;
119 Window* pGetChild;
120 Window* pChild;
122 // Die schon vergebenen Mnemonics registieren
123 pGetChild = pWindow->GetWindow( WINDOW_FIRSTCHILD );
124 while ( pGetChild )
126 pChild = pGetChild->ImplGetWindow();
127 aMnemonicGenerator.RegisterMnemonic( pChild->GetText() );
128 pGetChild = pGetChild->GetWindow( WINDOW_NEXT );
131 // Bei TabPages auch noch die Controls vom Dialog beruecksichtigen
132 if ( pWindow->GetType() == WINDOW_TABPAGE )
134 Window* pParent = pWindow->GetParent();
135 if ( pParent->GetType() == WINDOW_TABCONTROL )
136 pParent = pParent->GetParent();
138 if ( (pParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) == WB_DIALOGCONTROL )
140 pGetChild = pParent->GetWindow( WINDOW_FIRSTCHILD );
141 while ( pGetChild )
143 pChild = pGetChild->ImplGetWindow();
144 aMnemonicGenerator.RegisterMnemonic( pChild->GetText() );
145 pGetChild = pGetChild->GetWindow( WINDOW_NEXT );
150 // Die Mnemonics an die Controls vergeben, die noch keinen haben
151 pGetChild = pWindow->GetWindow( WINDOW_FIRSTCHILD );
152 while ( pGetChild )
154 pChild = pGetChild->ImplGetWindow();
155 if ( ImplIsMnemonicCtrl( pChild ) )
157 XubString aText = pChild->GetText();
158 if ( aMnemonicGenerator.CreateMnemonic( aText ) )
159 pChild->SetText( aText );
162 pGetChild = pGetChild->GetWindow( WINDOW_NEXT );
166 // =======================================================================
168 static PushButton* ImplGetDefaultButton( Dialog* pDialog )
170 Window* pChild = pDialog->GetWindow( WINDOW_FIRSTCHILD );
171 while ( pChild )
173 if ( pChild->ImplIsPushButton() )
175 PushButton* pPushButton = (PushButton*)pChild;
176 if ( pPushButton->ImplIsDefButton() )
177 return pPushButton;
180 pChild = pChild->GetWindow( WINDOW_NEXT );
183 return NULL;
186 // -----------------------------------------------------------------------
188 static PushButton* ImplGetOKButton( Dialog* pDialog )
190 Window* pChild = pDialog->GetWindow( WINDOW_FIRSTCHILD );
191 while ( pChild )
193 if ( pChild->GetType() == WINDOW_OKBUTTON )
194 return (PushButton*)pChild;
196 pChild = pChild->GetWindow( WINDOW_NEXT );
199 return NULL;
202 // -----------------------------------------------------------------------
204 static PushButton* ImplGetCancelButton( Dialog* pDialog )
206 Window* pChild = pDialog->GetWindow( WINDOW_FIRSTCHILD );
207 while ( pChild )
209 if ( pChild->GetType() == WINDOW_CANCELBUTTON )
210 return (PushButton*)pChild;
212 pChild = pChild->GetWindow( WINDOW_NEXT );
215 return NULL;
218 // -----------------------------------------------------------------------
220 static void ImplMouseAutoPos( Dialog* pDialog )
222 ULONG nMouseOptions = pDialog->GetSettings().GetMouseSettings().GetOptions();
223 if ( nMouseOptions & MOUSE_OPTION_AUTOCENTERPOS )
225 Size aSize = pDialog->GetOutputSizePixel();
226 pDialog->SetPointerPosPixel( Point( aSize.Width()/2, aSize.Height()/2 ) );
228 else if ( nMouseOptions & MOUSE_OPTION_AUTODEFBTNPOS )
230 Window* pWindow = ImplGetDefaultButton( pDialog );
231 if ( !pWindow )
232 pWindow = ImplGetOKButton( pDialog );
233 if ( !pWindow )
234 pWindow = ImplGetCancelButton( pDialog );
235 if ( !pWindow )
236 pWindow = pDialog;
237 Size aSize = pWindow->GetOutputSizePixel();
238 pWindow->SetPointerPosPixel( Point( aSize.Width()/2, aSize.Height()/2 ) );
242 // =======================================================================
244 struct DialogImpl
246 long mnResult;
247 bool mbStartedModal;
248 Link maEndDialogHdl;
250 DialogImpl() : mnResult( -1 ), mbStartedModal( false ) {}
253 // =======================================================================
255 void Dialog::ImplInitDialogData()
257 mpWindowImpl->mbDialog = TRUE;
258 mpDialogParent = NULL;
259 mpPrevExecuteDlg = NULL;
260 mbInExecute = FALSE;
261 mbOldSaveBack = FALSE;
262 mbInClose = FALSE;
263 mbModalMode = FALSE;
264 mnMousePositioned = 0;
265 mpDialogImpl = new DialogImpl;
268 // -----------------------------------------------------------------------
270 void Dialog::ImplInit( Window* pParent, WinBits nStyle )
272 USHORT nSysWinMode = Application::GetSystemWindowMode();
274 if ( !(nStyle & WB_NODIALOGCONTROL) )
275 nStyle |= WB_DIALOGCONTROL;
276 nStyle |= WB_ROLLABLE;
278 // Now, all Dialogs are per default system windows !!!
279 nStyle |= WB_SYSTEMWINDOW;
282 // parent is NULL: get the default Dialog parent
283 if ( !pParent )
285 pParent = Application::GetDefDialogParent();
286 if ( !pParent && !(nStyle & WB_SYSTEMWINDOW) )
287 pParent = ImplGetSVData()->maWinData.mpAppWin;
289 // If Parent is disabled, then we search for a modal dialog
290 // in this frame
291 if ( pParent && (!pParent->IsInputEnabled() || pParent->IsInModalMode()) )
293 ImplSVData* pSVData = ImplGetSVData();
294 Dialog* pExeDlg = pSVData->maWinData.mpLastExecuteDlg;
295 while ( pExeDlg )
297 // Nur wenn er sichtbar und enabled ist
298 if ( pParent->ImplGetFirstOverlapWindow()->IsWindowOrChild( pExeDlg, TRUE ) &&
299 pExeDlg->IsReallyVisible() &&
300 pExeDlg->IsEnabled() && pExeDlg->IsInputEnabled() && !pExeDlg->IsInModalMode() )
302 pParent = pExeDlg;
303 break;
306 pExeDlg = pExeDlg->mpPrevExecuteDlg;
310 // DIALOG_NO_PARENT: explicitly don't have a parent for this Dialog
311 else if( pParent == DIALOG_NO_PARENT )
312 pParent = NULL;
315 // Now, all Dialogs are per default system windows !!!
316 if ( pParent && !(nSysWinMode & SYSTEMWINDOW_MODE_NOAUTOMODE) )
318 if ( !pParent->mpWindowImpl->mpFrameWindow->IsVisible() )
319 pParent = NULL;
320 else
322 if ( pParent->mpWindowImpl->mpFrameWindow->IsDialog() )
324 Size aOutSize = pParent->mpWindowImpl->mpFrameWindow->GetOutputSizePixel();
325 if ( (aOutSize.Width() < 210) ||(aOutSize.Height() < 160) )
326 nStyle |= WB_SYSTEMWINDOW;
332 if ( !pParent || (nStyle & WB_SYSTEMWINDOW) ||
333 (pParent->mpWindowImpl->mpFrameData->mbNeedSysWindow && !(nSysWinMode & SYSTEMWINDOW_MODE_NOAUTOMODE)) ||
334 (nSysWinMode & SYSTEMWINDOW_MODE_DIALOG) )
336 // create window with a small border ?
337 if ( (nStyle & (WB_BORDER | WB_NOBORDER | WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE)) == WB_BORDER )
339 ImplBorderWindow* pBorderWin = new ImplBorderWindow( pParent, nStyle, BORDERWINDOW_STYLE_FRAME );
340 SystemWindow::ImplInit( pBorderWin, nStyle & ~WB_BORDER, NULL );
341 pBorderWin->mpWindowImpl->mpClientWindow = this;
342 pBorderWin->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
343 mpWindowImpl->mpBorderWindow = pBorderWin;
344 mpWindowImpl->mpRealParent = pParent;
346 else
348 mpWindowImpl->mbFrame = TRUE;
349 mpWindowImpl->mbOverlapWin = TRUE;
350 SystemWindow::ImplInit( pParent, (nStyle & (WB_MOVEABLE | WB_SIZEABLE | WB_ROLLABLE | WB_CLOSEABLE | WB_STANDALONE)) | WB_CLOSEABLE, NULL );
351 // Now set all style bits
352 mpWindowImpl->mnStyle = nStyle;
355 else
357 ImplBorderWindow* pBorderWin = new ImplBorderWindow( pParent, nStyle, BORDERWINDOW_STYLE_OVERLAP | BORDERWINDOW_STYLE_BORDER );
358 SystemWindow::ImplInit( pBorderWin, nStyle & ~WB_BORDER, NULL );
359 pBorderWin->mpWindowImpl->mpClientWindow = this;
360 pBorderWin->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
361 mpWindowImpl->mpBorderWindow = pBorderWin;
362 mpWindowImpl->mpRealParent = pParent;
365 SetActivateMode( ACTIVATE_MODE_GRABFOCUS );
367 ImplInitSettings();
370 // -----------------------------------------------------------------------
372 void Dialog::ImplInitSettings()
374 // user override
375 if ( IsControlBackground() )
376 SetBackground( GetControlBackground() );
377 // NWF background
378 else if( IsNativeControlSupported( CTRL_WINDOW_BACKGROUND, PART_BACKGROUND_DIALOG ) )
380 mpWindowImpl->mnNativeBackground = PART_BACKGROUND_DIALOG;
381 EnableChildTransparentMode( TRUE );
383 // fallback to settings color
384 else
385 SetBackground( GetSettings().GetStyleSettings().GetDialogColor() );
389 // -----------------------------------------------------------------------
391 void Dialog::ImplCenterDialog()
393 Rectangle aDeskRect = ImplGetFrameWindow()->GetDesktopRectPixel();
394 Point aDeskPos = aDeskRect.TopLeft();
395 Size aDeskSize = aDeskRect.GetSize();
396 Size aWinSize = GetSizePixel();
397 Window *pWindow = this;
398 while ( pWindow->mpWindowImpl->mpBorderWindow )
399 pWindow = pWindow->mpWindowImpl->mpBorderWindow;
400 Point aWinPos( ((aDeskSize.Width() - aWinSize.Width()) / 2) + aDeskPos.X(),
401 ((aDeskSize.Height() - aWinSize.Height()) / 2) + aDeskPos.Y() );
403 // Pruefen, ob Dialogbox ausserhalb des Desks liegt
404 if ( (aWinPos.X() + aWinSize.Width()) > (aDeskPos.X()+aDeskSize.Width()) )
405 aWinPos.X() = aDeskPos.X()+aDeskSize.Width() - aWinSize.Width();
406 if ( (aWinPos.Y()+aWinSize.Height()) > (aDeskPos.Y()+aDeskSize.Height()) )
407 aWinPos.Y() = aDeskPos.Y()+aDeskSize.Height() - aWinSize.Height();
408 // Linke Ecke bevorzugen, da Titelbar oben ist
409 if ( aWinPos.X() < aDeskPos.X() )
410 aWinPos.X() = aDeskPos.X();
411 if ( aWinPos.Y() < aDeskPos.Y() )
412 aWinPos.Y() = aDeskPos.Y();
414 //SetPosPixel( aWinPos );
415 SetPosPixel( pWindow->ScreenToOutputPixel( aWinPos ) );
418 // -----------------------------------------------------------------------
420 Dialog::Dialog( WindowType nType ) :
421 SystemWindow( nType )
423 ImplInitDialogData();
426 // -----------------------------------------------------------------------
428 Dialog::Dialog( Window* pParent, WinBits nStyle ) :
429 SystemWindow( WINDOW_DIALOG )
431 ImplInitDialogData();
432 ImplInit( pParent, nStyle );
435 // -----------------------------------------------------------------------
437 Dialog::Dialog( Window* pParent, const ResId& rResId ) :
438 SystemWindow( WINDOW_DIALOG )
440 ImplInitDialogData();
441 rResId.SetRT( RSC_DIALOG );
442 ImplInit( pParent, ImplInitRes( rResId ) );
443 ImplLoadRes( rResId );
446 // -----------------------------------------------------------------------
448 Dialog::~Dialog()
450 delete mpDialogImpl;
451 mpDialogImpl = NULL;
454 // -----------------------------------------------------------------------
456 long Dialog::Notify( NotifyEvent& rNEvt )
458 // Zuerst Basisklasse rufen wegen TabSteuerung
459 long nRet = SystemWindow::Notify( rNEvt );
460 if ( !nRet )
462 if ( rNEvt.GetType() == EVENT_KEYINPUT )
464 const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
465 KeyCode aKeyCode = pKEvt->GetKeyCode();
466 USHORT nKeyCode = aKeyCode.GetCode();
468 if ( (nKeyCode == KEY_ESCAPE) &&
469 ((GetStyle() & WB_CLOSEABLE) || ImplGetCancelButton( this ) || ImplGetOKButton( this )) )
471 Close();
472 return TRUE;
475 else if ( rNEvt.GetType() == EVENT_GETFOCUS )
477 // make sure the dialog is still modal
478 // changing focus between application frames may
479 // have re-enabled input for our parent
480 if( mbInExecute && mbModalMode )
482 // do not change modal counter (pSVData->maAppData.mnModalDialog)
483 SetModalInputMode( FALSE );
484 SetModalInputMode( TRUE );
486 // #93022# def-button might have changed after show
487 if( !mnMousePositioned )
489 mnMousePositioned = 1;
490 ImplMouseAutoPos( this );
497 return nRet;
500 // -----------------------------------------------------------------------
502 void Dialog::StateChanged( StateChangedType nType )
504 SystemWindow::StateChanged( nType );
506 if ( nType == STATE_CHANGE_INITSHOW )
508 if ( GetSettings().GetStyleSettings().GetAutoMnemonic() )
509 ImplWindowAutoMnemonic( this );
511 //if ( IsDefaultPos() && !mpWindowImpl->mbFrame )
512 // ImplCenterDialog();
513 if ( !HasChildPathFocus() || HasFocus() )
514 GrabFocusToFirstControl();
515 if ( !(GetStyle() & WB_CLOSEABLE) )
517 if ( ImplGetCancelButton( this ) || ImplGetOKButton( this ) )
519 if ( ImplGetBorderWindow() )
520 ((ImplBorderWindow*)ImplGetBorderWindow())->SetCloser();
524 ImplMouseAutoPos( this );
526 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
528 ImplInitSettings();
529 Invalidate();
533 // -----------------------------------------------------------------------
535 void Dialog::DataChanged( const DataChangedEvent& rDCEvt )
537 SystemWindow::DataChanged( rDCEvt );
539 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
540 (rDCEvt.GetFlags() & SETTINGS_STYLE) )
542 ImplInitSettings();
543 Invalidate();
547 // -----------------------------------------------------------------------
549 BOOL Dialog::Close()
551 ImplDelData aDelData;
552 ImplAddDel( &aDelData );
553 //liuchen 2009-7-22, support Excel VBA UserForm_QueryClose event
554 mnCancelClose = 0;
555 ImplCallEventListeners( VCLEVENT_WINDOW_CLOSE );
556 if (mnCancelClose == 1)
558 return FALSE;
560 //liuchen 2009-7-22
561 if ( aDelData.IsDelete() )
562 return FALSE;
563 ImplRemoveDel( &aDelData );
565 if ( mpWindowImpl->mxWindowPeer.is() && IsCreatedWithToolkit() && !IsInExecute() )
566 return FALSE;
568 mbInClose = TRUE;
570 if ( !(GetStyle() & WB_CLOSEABLE) )
572 BOOL bRet = TRUE;
573 ImplAddDel( &aDelData );
574 PushButton* pButton = ImplGetCancelButton( this );
575 if ( pButton )
576 pButton->Click();
577 else
579 pButton = ImplGetOKButton( this );
580 if ( pButton )
581 pButton->Click();
582 else
583 bRet = FALSE;
585 if ( aDelData.IsDelete() )
586 return TRUE;
587 ImplRemoveDel( &aDelData );
588 return bRet;
591 if ( IsInExecute() )
593 EndDialog( FALSE );
594 mbInClose = FALSE;
595 return TRUE;
597 else
599 mbInClose = FALSE;
600 return SystemWindow::Close();
604 // -----------------------------------------------------------------------
606 BOOL Dialog::ImplStartExecuteModal()
608 if ( mbInExecute )
610 #ifdef DBG_UTIL
611 ByteString aErrorStr( "Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): " );
612 aErrorStr += ImplGetDialogText( this );
613 DBG_ERROR( aErrorStr.GetBuffer() );
614 #endif
615 return FALSE;
618 if ( Application::IsDialogCancelEnabled() )
620 #ifdef DBG_UTIL
621 ByteString aErrorStr( "Dialog::StartExecuteModal() is called in a none UI application: " );
622 aErrorStr += ImplGetDialogText( this );
623 DBG_ERROR( aErrorStr.GetBuffer() );
624 #endif
625 return FALSE;
628 #ifdef DBG_UTIL
629 Window* pParent = GetParent();
630 if ( pParent )
632 pParent = pParent->ImplGetFirstOverlapWindow();
633 DBG_ASSERT( pParent->IsReallyVisible(),
634 "Dialog::StartExecuteModal() - Parent not visible" );
635 DBG_ASSERT( pParent->IsInputEnabled(),
636 "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" );
637 DBG_ASSERT( ! pParent->IsInModalMode(),
638 "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" );
641 #endif
643 ImplSVData* pSVData = ImplGetSVData();
645 // Dialoge, die sich in Execute befinden, miteinander verketten
646 mpPrevExecuteDlg = pSVData->maWinData.mpLastExecuteDlg;
647 pSVData->maWinData.mpLastExecuteDlg = this;
649 // Capture beenden, damit der Dialog bedient werden kann
650 if ( pSVData->maWinData.mpTrackWin )
651 pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL );
652 if ( pSVData->maWinData.mpCaptureWin )
653 pSVData->maWinData.mpCaptureWin->ReleaseMouse();
654 EnableInput( TRUE, TRUE );
656 if ( GetParent() )
658 NotifyEvent aNEvt( EVENT_EXECUTEDIALOG, this );
659 GetParent()->Notify( aNEvt );
661 mbInExecute = TRUE;
662 SetModalInputMode( TRUE );
663 mbOldSaveBack = IsSaveBackgroundEnabled();
664 EnableSaveBackground();
666 // FIXME: no layouting, workaround some clipping issues
667 ImplAdjustNWFSizes();
669 Show();
671 pSVData->maAppData.mnModalMode++;
672 return TRUE;
675 // -----------------------------------------------------------------------
677 void Dialog::ImplEndExecuteModal()
679 ImplSVData* pSVData = ImplGetSVData();
680 pSVData->maAppData.mnModalMode--;
683 // -----------------------------------------------------------------------
685 short Dialog::Execute()
687 if ( !ImplStartExecuteModal() )
688 return 0;
690 ImplDelData aDelData;
691 ImplAddDel( &aDelData );
693 #ifdef DBG_UTIL
694 ImplDelData aParentDelData;
695 Window* pDialogParent = mpDialogParent;
696 if( pDialogParent )
697 pDialogParent->ImplAddDel( &aParentDelData );
698 #endif
700 // Yield util EndDialog is called or dialog gets destroyed
701 // (the latter should not happen, but better safe than sorry
702 while ( !aDelData.IsDelete() && mbInExecute )
703 Application::Yield();
705 ImplEndExecuteModal();
707 #ifdef DBG_UTIL
708 if( pDialogParent )
710 if( ! aParentDelData.IsDelete() )
711 pDialogParent->ImplRemoveDel( &aParentDelData );
712 else
713 DBG_ERROR( "Dialog::Execute() - Parent of dialog destroyed in Execute()" );
715 #endif
716 if ( !aDelData.IsDelete() )
717 ImplRemoveDel( &aDelData );
718 #ifdef DBG_UTIL
719 else
721 DBG_ERROR( "Dialog::Execute() - Dialog destroyed in Execute()" );
723 #endif
725 long nRet = mpDialogImpl->mnResult;
726 mpDialogImpl->mnResult = -1;
727 return (short)nRet;
730 // -----------------------------------------------------------------------
732 // virtual
733 void Dialog::StartExecuteModal( const Link& rEndDialogHdl )
735 if ( !ImplStartExecuteModal() )
736 return;
738 mpDialogImpl->maEndDialogHdl = rEndDialogHdl;
739 mpDialogImpl->mbStartedModal = true;
742 // -----------------------------------------------------------------------
744 BOOL Dialog::IsStartedModal() const
746 return mpDialogImpl->mbStartedModal;
749 // -----------------------------------------------------------------------
751 void Dialog::EndDialog( long nResult )
753 if ( mbInExecute )
755 SetModalInputMode( FALSE );
757 // Dialog aus der Kette der Dialoge die in Execute stehen entfernen
758 ImplSVData* pSVData = ImplGetSVData();
759 Dialog* pExeDlg = pSVData->maWinData.mpLastExecuteDlg;
760 while ( pExeDlg )
762 if ( pExeDlg == this )
764 pSVData->maWinData.mpLastExecuteDlg = mpPrevExecuteDlg;
765 break;
767 pExeDlg = pExeDlg->mpPrevExecuteDlg;
769 // set focus to previous modal dialogue if it is modal for
770 // the same frame parent (or NULL)
771 if( mpPrevExecuteDlg )
773 Window* pFrameParent = ImplGetFrameWindow()->ImplGetParent();
774 Window* pPrevFrameParent = mpPrevExecuteDlg->ImplGetFrameWindow()->ImplGetParent();
775 if( ( !pFrameParent && !pPrevFrameParent ) ||
776 ( pFrameParent && pPrevFrameParent && pFrameParent->ImplGetFrame() == pPrevFrameParent->ImplGetFrame() )
779 mpPrevExecuteDlg->GrabFocus();
782 mpPrevExecuteDlg = NULL;
784 Hide();
785 EnableSaveBackground( mbOldSaveBack );
786 if ( GetParent() )
788 NotifyEvent aNEvt( EVENT_ENDEXECUTEDIALOG, this );
789 GetParent()->Notify( aNEvt );
792 mpDialogImpl->mnResult = nResult;
794 if ( mpDialogImpl->mbStartedModal )
796 ImplEndExecuteModal();
797 mpDialogImpl->maEndDialogHdl.Call( this );
799 mpDialogImpl->maEndDialogHdl = Link();
800 mpDialogImpl->mbStartedModal = false;
801 mpDialogImpl->mnResult = -1;
803 mbInExecute = FALSE;
807 // -----------------------------------------------------------------------
809 long Dialog::GetResult() const
811 return mpDialogImpl->mnResult;
814 // -----------------------------------------------------------------------
816 void Dialog::EndAllDialogs( Window* pParent )
818 ImplSVData* pSVData = ImplGetSVData();
819 Dialog* pTempModDialog;
820 Dialog* pModDialog = pSVData->maWinData.mpLastExecuteDlg;
821 while ( pModDialog )
823 pTempModDialog = pModDialog->mpPrevExecuteDlg;
824 if( !pParent || ( pParent && pParent->IsWindowOrChild( pModDialog, TRUE ) ) )
826 pModDialog->EndDialog( FALSE );
827 pModDialog->PostUserEvent( Link() );
829 pModDialog = pTempModDialog;
833 // -----------------------------------------------------------------------
835 void Dialog::SetModalInputMode( BOOL bModal )
837 if ( bModal == mbModalMode )
838 return;
840 ImplSVData* pSVData = ImplGetSVData();
841 mbModalMode = bModal;
842 if ( bModal )
844 pSVData->maAppData.mnModalDialog++;
846 // Diable the prev Modal Dialog, because our dialog must close at first,
847 // before the other dialog can be closed (because the other dialog
848 // is on stack since our dialog returns)
849 if ( mpPrevExecuteDlg && !mpPrevExecuteDlg->IsWindowOrChild( this, TRUE ) )
850 mpPrevExecuteDlg->EnableInput( FALSE, TRUE, TRUE, this );
852 // determine next overlap dialog parent
853 Window* pParent = GetParent();
854 if ( pParent )
856 // #103716# dialogs should always be modal to the whole frame window
857 // #115933# disable the whole frame hierarchie, useful if our parent
858 // is a modeless dialog
859 mpDialogParent = pParent->mpWindowImpl->mpFrameWindow;
860 mpDialogParent->ImplIncModalCount();
864 else
866 pSVData->maAppData.mnModalDialog--;
868 if ( mpDialogParent )
870 // #115933# re-enable the whole frame hierarchie again (see above)
871 // note that code in getfocus assures that we do not accidentally enable
872 // windows that were disabled before
873 mpDialogParent->ImplDecModalCount();
876 // Enable the prev Modal Dialog
877 if ( mpPrevExecuteDlg && !mpPrevExecuteDlg->IsWindowOrChild( this, TRUE ) )
879 mpPrevExecuteDlg->EnableInput( TRUE, TRUE, TRUE, this );
880 // ensure continued modality of prev dialog
881 // do not change modality counter
882 mpPrevExecuteDlg->SetModalInputMode( FALSE );
883 mpPrevExecuteDlg->SetModalInputMode( TRUE );
888 // -----------------------------------------------------------------------
890 void Dialog::SetModalInputMode( BOOL bModal, BOOL bSubModalDialogs )
892 if ( bSubModalDialogs )
894 Window* pOverlap = ImplGetFirstOverlapWindow();
895 pOverlap = pOverlap->mpWindowImpl->mpFirstOverlap;
896 while ( pOverlap )
898 if ( pOverlap->IsDialog() )
899 ((Dialog*)pOverlap)->SetModalInputMode( bModal, TRUE );
900 pOverlap = pOverlap->mpWindowImpl->mpNext;
904 SetModalInputMode( bModal );
907 // -----------------------------------------------------------------------
909 void Dialog::GrabFocusToFirstControl()
911 Window* pFocusControl;
913 // Wenn Dialog den Focus hat, versuchen wr trotzdem
914 // ein Focus-Control zu finden
915 if ( HasFocus() )
916 pFocusControl = NULL;
917 else
919 // Wenn schon ein Child-Fenster mal den Focus hatte,
920 // dann dieses bevorzugen
921 pFocusControl = ImplGetFirstOverlapWindow()->mpWindowImpl->mpLastFocusWindow;
922 // Control aus der Dialog-Steuerung suchen
923 if ( pFocusControl )
924 pFocusControl = ImplFindDlgCtrlWindow( pFocusControl );
926 // Kein Control hatte vorher den Focus, oder das Control
927 // befindet sich nicht in der Tab-Steuerung, dann das erste
928 // Control in der TabSteuerung den Focus geben
929 if ( !pFocusControl ||
930 !(pFocusControl->GetStyle() & WB_TABSTOP) ||
931 !pFocusControl->IsVisible() ||
932 !pFocusControl->IsEnabled() || !pFocusControl->IsInputEnabled() )
934 USHORT n = 0;
935 pFocusControl = ImplGetDlgWindow( n, DLGWINDOW_FIRST );
937 if ( pFocusControl )
938 pFocusControl->ImplControlFocus( GETFOCUS_INIT );
941 void Dialog::GetDrawWindowBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder, sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
943 ImplBorderWindow aImplWin( (Window*)this, WB_BORDER|WB_STDWORK, BORDERWINDOW_STYLE_OVERLAP );
944 // aImplWin.SetText( GetText() );
945 // aImplWin.SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height() );
946 // aImplWin.SetDisplayActive( TRUE );
947 // aImplWin.InitView();
948 aImplWin.GetBorder( rLeftBorder, rTopBorder, rRightBorder, rBottomBorder );
952 void Dialog::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, ULONG )
954 Point aPos = pDev->LogicToPixel( rPos );
955 Size aSize = pDev->LogicToPixel( rSize );
957 Wallpaper aWallpaper = GetBackground();
958 if ( !aWallpaper.IsBitmap() )
959 ImplInitSettings();
961 pDev->Push();
962 pDev->SetMapMode();
963 pDev->SetLineColor();
965 if ( aWallpaper.IsBitmap() )
966 pDev->DrawBitmapEx( aPos, aSize, aWallpaper.GetBitmap() );
967 else
969 pDev->SetFillColor( aWallpaper.GetColor() );
970 pDev->DrawRect( Rectangle( aPos, aSize ) );
973 if (!( GetStyle() & WB_NOBORDER ))
975 ImplBorderWindow aImplWin( this, WB_BORDER|WB_STDWORK, BORDERWINDOW_STYLE_OVERLAP );
976 aImplWin.SetText( GetText() );
977 aImplWin.SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height() );
978 aImplWin.SetDisplayActive( TRUE );
979 aImplWin.InitView();
981 aImplWin.Draw( Rectangle( aPos, aSize ), pDev, aPos );
984 pDev->Pop();
988 // =======================================================================
990 ModelessDialog::ModelessDialog( Window* pParent, WinBits nStyle ) :
991 Dialog( WINDOW_MODELESSDIALOG )
993 ImplInit( pParent, nStyle );
996 // -----------------------------------------------------------------------
998 ModelessDialog::ModelessDialog( Window* pParent, const ResId& rResId ) :
999 Dialog( WINDOW_MODELESSDIALOG )
1001 rResId.SetRT( RSC_MODELESSDIALOG );
1002 WinBits nStyle = ImplInitRes( rResId );
1003 ImplInit( pParent, nStyle );
1004 ImplLoadRes( rResId );
1006 if ( !(nStyle & WB_HIDE) )
1007 Show();
1010 // =======================================================================
1012 ModalDialog::ModalDialog( Window* pParent, WinBits nStyle ) :
1013 Dialog( WINDOW_MODALDIALOG )
1015 ImplInit( pParent, nStyle );
1018 // -----------------------------------------------------------------------
1020 ModalDialog::ModalDialog( Window* pParent, const ResId& rResId ) :
1021 Dialog( WINDOW_MODALDIALOG )
1023 rResId.SetRT( RSC_MODALDIALOG );
1024 ImplInit( pParent, ImplInitRes( rResId ) );
1025 ImplLoadRes( rResId );