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: dialog.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_vcl.hxx"
33 #include <tools/debug.hxx>
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>
50 #include <vcl/msgbox.hxx>
53 #include <vcl/unowrap.hxx>
57 // =======================================================================
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
) )
71 aErrorStr
+= ByteString( ((MessBox
*)pDialog
)->GetMessText(), RTL_TEXTENCODING_UTF8
);
78 // =======================================================================
80 static BOOL
ImplIsMnemonicCtrl( Window
* pWindow
)
82 if( ! pWindow
->GetSettings().GetStyleSettings().GetAutoMnemonic() )
85 if ( (pWindow
->GetType() == WINDOW_RADIOBUTTON
) ||
86 (pWindow
->GetType() == WINDOW_CHECKBOX
) ||
87 (pWindow
->GetType() == WINDOW_TRISTATEBOX
) ||
88 (pWindow
->GetType() == WINDOW_PUSHBUTTON
) )
91 if ( pWindow
->GetType() == WINDOW_FIXEDTEXT
)
93 if ( pWindow
->GetStyle() & (WB_INFO
| WB_NOLABEL
) )
95 Window
* pNextWindow
= pWindow
->GetWindow( WINDOW_NEXT
);
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
) )
114 // -----------------------------------------------------------------------
116 void ImplWindowAutoMnemonic( Window
* pWindow
)
118 MnemonicGenerator aMnemonicGenerator
;
122 // Die schon vergebenen Mnemonics registieren
123 pGetChild
= pWindow
->GetWindow( WINDOW_FIRSTCHILD
);
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
);
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
);
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
);
173 if ( pChild
->ImplIsPushButton() )
175 PushButton
* pPushButton
= (PushButton
*)pChild
;
176 if ( pPushButton
->ImplIsDefButton() )
180 pChild
= pChild
->GetWindow( WINDOW_NEXT
);
186 // -----------------------------------------------------------------------
188 static PushButton
* ImplGetOKButton( Dialog
* pDialog
)
190 Window
* pChild
= pDialog
->GetWindow( WINDOW_FIRSTCHILD
);
193 if ( pChild
->GetType() == WINDOW_OKBUTTON
)
194 return (PushButton
*)pChild
;
196 pChild
= pChild
->GetWindow( WINDOW_NEXT
);
202 // -----------------------------------------------------------------------
204 static PushButton
* ImplGetCancelButton( Dialog
* pDialog
)
206 Window
* pChild
= pDialog
->GetWindow( WINDOW_FIRSTCHILD
);
209 if ( pChild
->GetType() == WINDOW_CANCELBUTTON
)
210 return (PushButton
*)pChild
;
212 pChild
= pChild
->GetWindow( WINDOW_NEXT
);
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
);
232 pWindow
= ImplGetOKButton( pDialog
);
234 pWindow
= ImplGetCancelButton( pDialog
);
237 Size aSize
= pWindow
->GetOutputSizePixel();
238 pWindow
->SetPointerPosPixel( Point( aSize
.Width()/2, aSize
.Height()/2 ) );
242 // =======================================================================
250 DialogImpl() : mnResult( -1 ), mbStartedModal( false ) {}
253 // =======================================================================
255 void Dialog::ImplInitDialogData()
257 mpWindowImpl
->mbDialog
= TRUE
;
258 mpDialogParent
= NULL
;
259 mpPrevExecuteDlg
= NULL
;
261 mbOldSaveBack
= 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
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
291 if ( pParent
&& (!pParent
->IsInputEnabled() || pParent
->IsInModalMode()) )
293 ImplSVData
* pSVData
= ImplGetSVData();
294 Dialog
* pExeDlg
= pSVData
->maWinData
.mpLastExecuteDlg
;
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() )
306 pExeDlg
= pExeDlg
->mpPrevExecuteDlg
;
310 // DIALOG_NO_PARENT: explicitly don't have a parent for this Dialog
311 else if( pParent
== DIALOG_NO_PARENT
)
315 // Now, all Dialogs are per default system windows !!!
316 if ( pParent && !(nSysWinMode & SYSTEMWINDOW_MODE_NOAUTOMODE) )
318 if ( !pParent->mpWindowImpl->mpFrameWindow->IsVisible() )
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
;
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
;
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
);
370 // -----------------------------------------------------------------------
372 void Dialog::ImplInitSettings()
375 if ( IsControlBackground() )
376 SetBackground( GetControlBackground() );
378 else if( IsNativeControlSupported( CTRL_WINDOW_BACKGROUND
, PART_BACKGROUND_DIALOG
) )
380 mpWindowImpl
->mnNativeBackground
= PART_BACKGROUND_DIALOG
;
381 EnableChildTransparentMode( TRUE
);
383 // fallback to settings color
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 // -----------------------------------------------------------------------
454 // -----------------------------------------------------------------------
456 long Dialog::Notify( NotifyEvent
& rNEvt
)
458 // Zuerst Basisklasse rufen wegen TabSteuerung
459 long nRet
= SystemWindow::Notify( rNEvt
);
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 )) )
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 );
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
)
533 // -----------------------------------------------------------------------
535 void Dialog::DataChanged( const DataChangedEvent
& rDCEvt
)
537 SystemWindow::DataChanged( rDCEvt
);
539 if ( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
540 (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
547 // -----------------------------------------------------------------------
551 ImplDelData aDelData
;
552 ImplAddDel( &aDelData
);
553 //liuchen 2009-7-22, support Excel VBA UserForm_QueryClose event
555 ImplCallEventListeners( VCLEVENT_WINDOW_CLOSE
);
556 if (mnCancelClose
== 1)
561 if ( aDelData
.IsDelete() )
563 ImplRemoveDel( &aDelData
);
565 if ( mpWindowImpl
->mxWindowPeer
.is() && IsCreatedWithToolkit() && !IsInExecute() )
570 if ( !(GetStyle() & WB_CLOSEABLE
) )
573 ImplAddDel( &aDelData
);
574 PushButton
* pButton
= ImplGetCancelButton( this );
579 pButton
= ImplGetOKButton( this );
585 if ( aDelData
.IsDelete() )
587 ImplRemoveDel( &aDelData
);
600 return SystemWindow::Close();
604 // -----------------------------------------------------------------------
606 BOOL
Dialog::ImplStartExecuteModal()
611 ByteString
aErrorStr( "Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): " );
612 aErrorStr
+= ImplGetDialogText( this );
613 DBG_ERROR( aErrorStr
.GetBuffer() );
618 if ( Application::IsDialogCancelEnabled() )
621 ByteString
aErrorStr( "Dialog::StartExecuteModal() is called in a none UI application: " );
622 aErrorStr
+= ImplGetDialogText( this );
623 DBG_ERROR( aErrorStr
.GetBuffer() );
629 Window
* pParent
= GetParent();
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!" );
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
);
658 NotifyEvent
aNEvt( EVENT_EXECUTEDIALOG
, this );
659 GetParent()->Notify( aNEvt
);
662 SetModalInputMode( TRUE
);
663 mbOldSaveBack
= IsSaveBackgroundEnabled();
664 EnableSaveBackground();
666 // FIXME: no layouting, workaround some clipping issues
667 ImplAdjustNWFSizes();
671 pSVData
->maAppData
.mnModalMode
++;
675 // -----------------------------------------------------------------------
677 void Dialog::ImplEndExecuteModal()
679 ImplSVData
* pSVData
= ImplGetSVData();
680 pSVData
->maAppData
.mnModalMode
--;
683 // -----------------------------------------------------------------------
685 short Dialog::Execute()
687 if ( !ImplStartExecuteModal() )
690 ImplDelData aDelData
;
691 ImplAddDel( &aDelData
);
694 ImplDelData aParentDelData
;
695 Window
* pDialogParent
= mpDialogParent
;
697 pDialogParent
->ImplAddDel( &aParentDelData
);
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();
710 if( ! aParentDelData
.IsDelete() )
711 pDialogParent
->ImplRemoveDel( &aParentDelData
);
713 DBG_ERROR( "Dialog::Execute() - Parent of dialog destroyed in Execute()" );
716 if ( !aDelData
.IsDelete() )
717 ImplRemoveDel( &aDelData
);
721 DBG_ERROR( "Dialog::Execute() - Dialog destroyed in Execute()" );
725 long nRet
= mpDialogImpl
->mnResult
;
726 mpDialogImpl
->mnResult
= -1;
730 // -----------------------------------------------------------------------
733 void Dialog::StartExecuteModal( const Link
& rEndDialogHdl
)
735 if ( !ImplStartExecuteModal() )
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
)
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
;
762 if ( pExeDlg
== this )
764 pSVData
->maWinData
.mpLastExecuteDlg
= mpPrevExecuteDlg
;
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
;
785 EnableSaveBackground( mbOldSaveBack
);
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;
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
;
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
)
840 ImplSVData
* pSVData
= ImplGetSVData();
841 mbModalMode
= 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();
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();
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
;
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
916 pFocusControl
= NULL
;
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
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() )
935 pFocusControl
= ImplGetDlgWindow( n
, DLGWINDOW_FIRST
);
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() )
963 pDev
->SetLineColor();
965 if ( aWallpaper
.IsBitmap() )
966 pDev
->DrawBitmapEx( aPos
, aSize
, aWallpaper
.GetBitmap() );
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
);
981 aImplWin
.Draw( Rectangle( aPos
, aSize
), pDev
, aPos
);
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
) )
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
);