Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <config_features.h>
21 :
22 : #include <com/sun/star/beans/XPropertySet.hpp>
23 : #include <com/sun/star/util/thePathSettings.hpp>
24 : #include <comphelper/processfactory.hxx>
25 : #include <osl/file.hxx>
26 :
27 : #include <tools/debug.hxx>
28 :
29 : #include <tools/rc.h>
30 : #include <svdata.hxx>
31 : #include <window.h>
32 : #include <brdwin.hxx>
33 :
34 : #include <rtl/strbuf.hxx>
35 : #include <sal/log.hxx>
36 :
37 : #include <vcl/builder.hxx>
38 : #include <vcl/layout.hxx>
39 : #include <vcl/svapp.hxx>
40 : #include <vcl/event.hxx>
41 : #include <vcl/wrkwin.hxx>
42 : #include <vcl/button.hxx>
43 : #include <vcl/mnemonic.hxx>
44 : #include <vcl/dialog.hxx>
45 : #include <vcl/decoview.hxx>
46 : #include <vcl/msgbox.hxx>
47 : #include <vcl/unowrap.hxx>
48 : #include <vcl/settings.hxx>
49 :
50 : #include <iostream>
51 :
52 : #if !HAVE_FEATURE_DESKTOP
53 : #include <touch/touch.h>
54 : #endif
55 :
56 0 : static OString ImplGetDialogText( Dialog* pDialog )
57 : {
58 : OStringBuffer aErrorStr(OUStringToOString(
59 0 : pDialog->GetText(), RTL_TEXTENCODING_UTF8));
60 0 : if ( (pDialog->GetType() == WINDOW_MESSBOX) ||
61 0 : (pDialog->GetType() == WINDOW_INFOBOX) ||
62 0 : (pDialog->GetType() == WINDOW_WARNINGBOX) ||
63 0 : (pDialog->GetType() == WINDOW_ERRORBOX) ||
64 0 : (pDialog->GetType() == WINDOW_QUERYBOX) )
65 : {
66 0 : aErrorStr.append(", ");
67 : aErrorStr.append(OUStringToOString(
68 0 : ((MessBox*)pDialog)->GetMessText(), RTL_TEXTENCODING_UTF8));
69 : }
70 0 : return aErrorStr.makeStringAndClear();
71 : }
72 :
73 0 : static bool ImplIsMnemonicCtrl( Window* pWindow )
74 : {
75 0 : if( ! pWindow->GetSettings().GetStyleSettings().GetAutoMnemonic() )
76 0 : return false;
77 :
78 0 : if ( (pWindow->GetType() == WINDOW_RADIOBUTTON) ||
79 0 : (pWindow->GetType() == WINDOW_CHECKBOX) ||
80 0 : (pWindow->GetType() == WINDOW_TRISTATEBOX) ||
81 0 : (pWindow->GetType() == WINDOW_PUSHBUTTON) )
82 0 : return true;
83 :
84 0 : if ( pWindow->GetType() == WINDOW_FIXEDTEXT )
85 : {
86 0 : FixedText *pText = static_cast<FixedText*>(pWindow);
87 0 : if (pText->get_mnemonic_widget())
88 0 : return true;
89 : //This is the legacy pre-layout logic which we retain
90 : //until we can be sure we can remove it
91 0 : if ( pWindow->GetStyle() & (WB_INFO | WB_NOLABEL) )
92 0 : return false;
93 0 : Window* pNextWindow = pWindow->GetWindow( WINDOW_NEXT );
94 0 : if ( !pNextWindow )
95 0 : return false;
96 0 : pNextWindow = pNextWindow->GetWindow( WINDOW_CLIENT );
97 0 : if ( !(pNextWindow->GetStyle() & WB_TABSTOP) ||
98 0 : (pNextWindow->GetType() == WINDOW_FIXEDTEXT) ||
99 0 : (pNextWindow->GetType() == WINDOW_GROUPBOX) ||
100 0 : (pNextWindow->GetType() == WINDOW_RADIOBUTTON) ||
101 0 : (pNextWindow->GetType() == WINDOW_CHECKBOX) ||
102 0 : (pNextWindow->GetType() == WINDOW_TRISTATEBOX) ||
103 0 : (pNextWindow->GetType() == WINDOW_PUSHBUTTON) )
104 0 : return false;
105 :
106 0 : return true;
107 : }
108 :
109 0 : return false;
110 : }
111 :
112 : // Called by native error dialog popup implementations
113 0 : void ImplHideSplash()
114 : {
115 0 : ImplSVData* pSVData = ImplGetSVData();
116 0 : if( pSVData->mpIntroWindow )
117 0 : pSVData->mpIntroWindow->Hide();
118 0 : }
119 :
120 : //Get next window after pChild of a pTopLevel window as
121 : //if any intermediate layout widgets didn't exist
122 0 : Window * nextLogicalChildOfParent(Window *pTopLevel, Window *pChild)
123 : {
124 0 : Window *pLastChild = pChild;
125 :
126 0 : if (isContainerWindow(*pChild))
127 0 : pChild = pChild->GetWindow(WINDOW_FIRSTCHILD);
128 : else
129 0 : pChild = pChild->GetWindow(WINDOW_NEXT);
130 :
131 0 : while (!pChild)
132 : {
133 0 : Window *pParent = pLastChild->GetParent();
134 0 : if (!pParent)
135 0 : return NULL;
136 0 : if (pParent == pTopLevel)
137 0 : return NULL;
138 0 : pLastChild = pParent;
139 0 : pChild = pParent->GetWindow(WINDOW_NEXT);
140 : }
141 :
142 0 : if (pChild && isContainerWindow(*pChild))
143 0 : pChild = nextLogicalChildOfParent(pTopLevel, pChild);
144 :
145 0 : return pChild;
146 : }
147 :
148 0 : Window * prevLogicalChildOfParent(Window *pTopLevel, Window *pChild)
149 : {
150 0 : Window *pLastChild = pChild;
151 :
152 0 : if (isContainerWindow(*pChild))
153 0 : pChild = pChild->GetWindow(WINDOW_LASTCHILD);
154 : else
155 0 : pChild = pChild->GetWindow(WINDOW_PREV);
156 :
157 0 : while (!pChild)
158 : {
159 0 : Window *pParent = pLastChild->GetParent();
160 0 : if (!pParent)
161 0 : return NULL;
162 0 : if (pParent == pTopLevel)
163 0 : return NULL;
164 0 : pLastChild = pParent;
165 0 : pChild = pParent->GetWindow(WINDOW_PREV);
166 : }
167 :
168 0 : if (pChild && isContainerWindow(*pChild))
169 0 : pChild = prevLogicalChildOfParent(pTopLevel, pChild);
170 :
171 0 : return pChild;
172 : }
173 :
174 : //Get first window of a pTopLevel window as
175 : //if any intermediate layout widgets didn't exist
176 0 : Window * firstLogicalChildOfParent(Window *pTopLevel)
177 : {
178 0 : Window *pChild = pTopLevel->GetWindow(WINDOW_FIRSTCHILD);
179 0 : if (pChild && isContainerWindow(*pChild))
180 0 : pChild = nextLogicalChildOfParent(pTopLevel, pChild);
181 0 : return pChild;
182 : }
183 :
184 0 : void ImplWindowAutoMnemonic( Window* pWindow )
185 : {
186 0 : MnemonicGenerator aMnemonicGenerator;
187 : Window* pGetChild;
188 : Window* pChild;
189 :
190 : // register the assigned mnemonics
191 0 : pGetChild = pWindow->GetWindow( WINDOW_FIRSTCHILD );
192 0 : while ( pGetChild )
193 : {
194 0 : pChild = pGetChild->ImplGetWindow();
195 0 : aMnemonicGenerator.RegisterMnemonic( pChild->GetText() );
196 0 : pGetChild = nextLogicalChildOfParent(pWindow, pGetChild);
197 : }
198 :
199 : // take the Controls of the dialog into account for TabPages
200 0 : if ( pWindow->GetType() == WINDOW_TABPAGE )
201 : {
202 0 : Window* pParent = pWindow->GetParent();
203 0 : if ( pParent->GetType() == WINDOW_TABCONTROL )
204 0 : pParent = pParent->GetParent();
205 :
206 0 : if ( (pParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) == WB_DIALOGCONTROL )
207 : {
208 0 : pGetChild = pParent->GetWindow( WINDOW_FIRSTCHILD );
209 0 : while ( pGetChild )
210 : {
211 0 : pChild = pGetChild->ImplGetWindow();
212 0 : aMnemonicGenerator.RegisterMnemonic( pChild->GetText() );
213 0 : pGetChild = nextLogicalChildOfParent(pWindow, pGetChild);
214 : }
215 : }
216 : }
217 :
218 : // assign mnemonics to Controls which have none
219 0 : pGetChild = pWindow->GetWindow( WINDOW_FIRSTCHILD );
220 0 : while ( pGetChild )
221 : {
222 0 : pChild = pGetChild->ImplGetWindow();
223 0 : if ( ImplIsMnemonicCtrl( pChild ) )
224 : {
225 0 : OUString aText = pChild->GetText();
226 0 : OUString aNewText = aMnemonicGenerator.CreateMnemonic( aText );
227 0 : if ( aText != aNewText )
228 0 : pChild->SetText( aNewText );
229 : }
230 :
231 0 : pGetChild = nextLogicalChildOfParent(pWindow, pGetChild);
232 0 : }
233 0 : }
234 :
235 0 : static VclButtonBox* getActionArea(Dialog *pDialog)
236 : {
237 0 : VclButtonBox *pButtonBox = NULL;
238 0 : if (pDialog->isLayoutEnabled())
239 : {
240 0 : Window *pBox = pDialog->GetWindow(WINDOW_FIRSTCHILD);
241 0 : Window *pChild = pBox->GetWindow(WINDOW_LASTCHILD);
242 0 : while (pChild)
243 : {
244 0 : pButtonBox = dynamic_cast<VclButtonBox*>(pChild);
245 0 : if (pButtonBox)
246 0 : break;
247 0 : pChild = pChild->GetWindow(WINDOW_PREV);
248 : }
249 : }
250 0 : return pButtonBox;
251 : }
252 :
253 0 : static Window* getActionAreaButtonList(Dialog *pDialog)
254 : {
255 0 : VclButtonBox* pButtonBox = getActionArea(pDialog);
256 0 : if (pButtonBox)
257 0 : return pButtonBox->GetWindow(WINDOW_FIRSTCHILD);
258 0 : return pDialog->GetWindow(WINDOW_FIRSTCHILD);
259 : }
260 :
261 0 : static PushButton* ImplGetDefaultButton( Dialog* pDialog )
262 : {
263 0 : Window* pChild = getActionAreaButtonList(pDialog);
264 0 : while ( pChild )
265 : {
266 0 : if ( pChild->ImplIsPushButton() )
267 : {
268 0 : PushButton* pPushButton = (PushButton*)pChild;
269 0 : if ( pPushButton->ImplIsDefButton() )
270 0 : return pPushButton;
271 : }
272 :
273 0 : pChild = pChild->GetWindow( WINDOW_NEXT );
274 : }
275 :
276 0 : return NULL;
277 : }
278 :
279 0 : static PushButton* ImplGetOKButton( Dialog* pDialog )
280 : {
281 0 : Window* pChild = getActionAreaButtonList(pDialog);
282 0 : while ( pChild )
283 : {
284 0 : if ( pChild->GetType() == WINDOW_OKBUTTON )
285 0 : return (PushButton*)pChild;
286 :
287 0 : pChild = pChild->GetWindow( WINDOW_NEXT );
288 : }
289 :
290 0 : return NULL;
291 : }
292 :
293 0 : static PushButton* ImplGetCancelButton( Dialog* pDialog )
294 : {
295 0 : Window* pChild = getActionAreaButtonList(pDialog);
296 :
297 0 : while ( pChild )
298 : {
299 0 : if ( pChild->GetType() == WINDOW_CANCELBUTTON )
300 0 : return (PushButton*)pChild;
301 :
302 0 : pChild = pChild->GetWindow( WINDOW_NEXT );
303 : }
304 :
305 0 : return NULL;
306 : }
307 :
308 0 : static void ImplMouseAutoPos( Dialog* pDialog )
309 : {
310 0 : sal_uLong nMouseOptions = pDialog->GetSettings().GetMouseSettings().GetOptions();
311 0 : if ( nMouseOptions & MOUSE_OPTION_AUTOCENTERPOS )
312 : {
313 0 : Size aSize = pDialog->GetOutputSizePixel();
314 0 : pDialog->SetPointerPosPixel( Point( aSize.Width()/2, aSize.Height()/2 ) );
315 : }
316 0 : else if ( nMouseOptions & MOUSE_OPTION_AUTODEFBTNPOS )
317 : {
318 0 : Window* pWindow = ImplGetDefaultButton( pDialog );
319 0 : if ( !pWindow )
320 0 : pWindow = ImplGetOKButton( pDialog );
321 0 : if ( !pWindow )
322 0 : pWindow = ImplGetCancelButton( pDialog );
323 0 : if ( !pWindow )
324 0 : pWindow = pDialog;
325 0 : Size aSize = pWindow->GetOutputSizePixel();
326 0 : pWindow->SetPointerPosPixel( Point( aSize.Width()/2, aSize.Height()/2 ) );
327 : }
328 0 : }
329 :
330 : struct DialogImpl
331 : {
332 : long mnResult;
333 : bool mbStartedModal;
334 : Link maEndDialogHdl;
335 :
336 0 : DialogImpl() : mnResult( -1 ), mbStartedModal( false ) {}
337 : };
338 :
339 0 : void Dialog::ImplInitDialogData()
340 : {
341 0 : mpWindowImpl->mbDialog = true;
342 0 : mpDialogParent = NULL;
343 0 : mpPrevExecuteDlg = NULL;
344 0 : mbInExecute = false;
345 0 : mbOldSaveBack = false;
346 0 : mbInClose = false;
347 0 : mbModalMode = false;
348 0 : mpContentArea = NULL;
349 0 : mpActionArea = NULL;
350 0 : mbIsCalculatingInitialLayoutSize = false;
351 0 : mnMousePositioned = 0;
352 0 : mpDialogImpl = new DialogImpl;
353 :
354 : //To-Do, reuse maResizeTimer
355 0 : maLayoutTimer.SetTimeout(50);
356 0 : maLayoutTimer.SetTimeoutHdl( LINK( this, Dialog, ImplHandleLayoutTimerHdl ) );
357 0 : }
358 :
359 0 : void Dialog::ImplInit( Window* pParent, WinBits nStyle )
360 : {
361 0 : sal_uInt16 nSysWinMode = Application::GetSystemWindowMode();
362 :
363 0 : if ( !(nStyle & WB_NODIALOGCONTROL) )
364 0 : nStyle |= WB_DIALOGCONTROL;
365 0 : nStyle |= WB_ROLLABLE;
366 :
367 : // Now, all Dialogs are per default system windows !!!
368 0 : nStyle |= WB_SYSTEMWINDOW;
369 :
370 : // parent is NULL: get the default Dialog parent
371 0 : if ( !pParent )
372 : {
373 0 : pParent = Application::GetDefDialogParent();
374 0 : if ( !pParent && !(nStyle & WB_SYSTEMWINDOW) )
375 0 : pParent = ImplGetSVData()->maWinData.mpAppWin;
376 :
377 : // If Parent is disabled, then we search for a modal dialog
378 : // in this frame
379 0 : if ( pParent && (!pParent->IsInputEnabled() || pParent->IsInModalMode()) )
380 : {
381 0 : ImplSVData* pSVData = ImplGetSVData();
382 0 : Dialog* pExeDlg = pSVData->maWinData.mpLastExecuteDlg;
383 0 : while ( pExeDlg )
384 : {
385 : // only if visible and enabled
386 0 : if ( pParent->ImplGetFirstOverlapWindow()->IsWindowOrChild( pExeDlg, true ) &&
387 0 : pExeDlg->IsReallyVisible() &&
388 0 : pExeDlg->IsEnabled() && pExeDlg->IsInputEnabled() && !pExeDlg->IsInModalMode() )
389 : {
390 0 : pParent = pExeDlg;
391 0 : break;
392 : }
393 :
394 0 : pExeDlg = pExeDlg->mpPrevExecuteDlg;
395 : }
396 : }
397 : }
398 : // DIALOG_NO_PARENT: explicitly don't have a parent for this Dialog
399 0 : else if( pParent == DIALOG_NO_PARENT )
400 0 : pParent = NULL;
401 :
402 0 : if ( !pParent || (nStyle & WB_SYSTEMWINDOW) ||
403 0 : (pParent->mpWindowImpl->mpFrameData->mbNeedSysWindow && !(nSysWinMode & SYSTEMWINDOW_MODE_NOAUTOMODE)) ||
404 0 : (nSysWinMode & SYSTEMWINDOW_MODE_DIALOG) )
405 : {
406 : // create window with a small border ?
407 0 : if ( (nStyle & (WB_BORDER | WB_NOBORDER | WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE)) == WB_BORDER )
408 : {
409 0 : ImplBorderWindow* pBorderWin = new ImplBorderWindow( pParent, nStyle, BORDERWINDOW_STYLE_FRAME );
410 0 : SystemWindow::ImplInit( pBorderWin, nStyle & ~WB_BORDER, NULL );
411 0 : pBorderWin->mpWindowImpl->mpClientWindow = this;
412 0 : pBorderWin->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
413 0 : mpWindowImpl->mpBorderWindow = pBorderWin;
414 0 : mpWindowImpl->mpRealParent = pParent;
415 : }
416 : else
417 : {
418 0 : mpWindowImpl->mbFrame = true;
419 0 : mpWindowImpl->mbOverlapWin = true;
420 0 : SystemWindow::ImplInit( pParent, (nStyle & (WB_MOVEABLE | WB_SIZEABLE | WB_ROLLABLE | WB_CLOSEABLE | WB_STANDALONE)) | WB_CLOSEABLE, NULL );
421 : // Now set all style bits
422 0 : mpWindowImpl->mnStyle = nStyle;
423 0 : }
424 : }
425 : else
426 : {
427 0 : ImplBorderWindow* pBorderWin = new ImplBorderWindow( pParent, nStyle, BORDERWINDOW_STYLE_OVERLAP | BORDERWINDOW_STYLE_BORDER );
428 0 : SystemWindow::ImplInit( pBorderWin, nStyle & ~WB_BORDER, NULL );
429 0 : pBorderWin->mpWindowImpl->mpClientWindow = this;
430 0 : pBorderWin->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
431 0 : mpWindowImpl->mpBorderWindow = pBorderWin;
432 0 : mpWindowImpl->mpRealParent = pParent;
433 : }
434 :
435 0 : SetActivateMode( ACTIVATE_MODE_GRABFOCUS );
436 :
437 0 : ImplInitSettings();
438 0 : }
439 :
440 0 : void Dialog::ImplInitSettings()
441 : {
442 : // user override
443 0 : if ( IsControlBackground() )
444 0 : SetBackground( GetControlBackground() );
445 : // NWF background
446 0 : else if( IsNativeControlSupported( CTRL_WINDOW_BACKGROUND, PART_BACKGROUND_DIALOG ) )
447 : {
448 0 : mpWindowImpl->mnNativeBackground = PART_BACKGROUND_DIALOG;
449 0 : EnableChildTransparentMode( true );
450 : }
451 : // fallback to settings color
452 : else
453 0 : SetBackground( GetSettings().GetStyleSettings().GetDialogColor() );
454 0 : }
455 :
456 0 : Dialog::Dialog( WindowType nType )
457 : : SystemWindow( nType )
458 0 : , mbIsDefferedInit(false)
459 : {
460 0 : ImplInitDialogData();
461 0 : }
462 :
463 0 : OUString VclBuilderContainer::getUIRootDir()
464 : {
465 : /*to-do, check if user config has an override before using shared one, etc*/
466 : css::uno::Reference< css::util::XPathSettings > xPathSettings = css::util::thePathSettings::get(
467 0 : ::comphelper::getProcessComponentContext() );
468 :
469 0 : OUString sShareLayer = xPathSettings->getBasePathShareLayer();
470 :
471 : // "UIConfig" is a "multi path" ... use first part only here!
472 0 : sal_Int32 nPos = sShareLayer.indexOf(';');
473 0 : if (nPos > 0)
474 0 : sShareLayer = sShareLayer.copy(0, nPos);
475 :
476 : // Note: May be an user uses URLs without a final slash! Check it ...
477 0 : if (!sShareLayer.endsWith("/"))
478 0 : sShareLayer += "/";
479 :
480 0 : sShareLayer += "soffice.cfg/";
481 : /*to-do, can we merge all this foo with existing soffice.cfg finding code, etc*/
482 0 : return sShareLayer;
483 : }
484 :
485 : //we can't change sizeable after the fact, so need to defer until we know and then
486 : //do the init. Find the real parent stashed in mpDialogParent.
487 0 : void Dialog::doDeferredInit(bool bResizable)
488 : {
489 0 : WinBits nBits = WB_3DLOOK|WB_CLOSEABLE|WB_MOVEABLE;
490 0 : if (bResizable)
491 0 : nBits |= WB_SIZEABLE;
492 0 : Window *pParent = mpDialogParent;
493 0 : mpDialogParent = NULL;
494 0 : ImplInit(pParent, nBits);
495 0 : mbIsDefferedInit = false;
496 0 : }
497 :
498 0 : Dialog::Dialog(Window* pParent, const OString& rID, const OUString& rUIXMLDescription)
499 : : SystemWindow( WINDOW_DIALOG )
500 0 : , mbIsDefferedInit(true)
501 : {
502 0 : ImplInitDialogData();
503 0 : mpDialogParent = pParent; //will be unset in doDeferredInit
504 0 : m_pUIBuilder = new VclBuilder(this, getUIRootDir(), rUIXMLDescription, rID);
505 0 : }
506 :
507 0 : Dialog::Dialog(Window* pParent, const OString& rID, const OUString& rUIXMLDescription, WindowType nType)
508 : : SystemWindow( nType )
509 0 : , mbIsDefferedInit(true)
510 : {
511 0 : ImplInitDialogData();
512 0 : mpDialogParent = pParent; //will be unset in doDeferredInit
513 0 : m_pUIBuilder = new VclBuilder(this, getUIRootDir(), rUIXMLDescription, rID);
514 0 : }
515 :
516 0 : Dialog::Dialog( Window* pParent, WinBits nStyle )
517 : : SystemWindow( WINDOW_DIALOG )
518 0 : , mbIsDefferedInit(false)
519 : {
520 0 : ImplInitDialogData();
521 0 : ImplInit( pParent, nStyle );
522 0 : }
523 :
524 0 : WinBits Dialog::init(Window *pParent, const ResId& rResId)
525 : {
526 0 : WinBits nStyle = ImplInitRes( rResId );
527 :
528 0 : ImplInit( pParent, nStyle );
529 0 : ImplLoadRes( rResId );
530 :
531 0 : return nStyle;
532 : }
533 :
534 0 : VclButtonBox* Dialog::get_action_area()
535 : {
536 0 : return mpActionArea;
537 : }
538 :
539 0 : void Dialog::set_action_area(VclButtonBox* pActionArea)
540 : {
541 0 : mpActionArea = pActionArea;
542 0 : }
543 :
544 0 : VclBox* Dialog::get_content_area()
545 : {
546 0 : return mpContentArea;
547 : }
548 :
549 0 : void Dialog::set_content_area(VclBox* pContentArea)
550 : {
551 0 : mpContentArea = pContentArea;
552 0 : }
553 :
554 0 : Dialog::~Dialog()
555 : {
556 0 : maLayoutTimer.Stop();
557 0 : delete mpDialogImpl;
558 0 : mpDialogImpl = NULL;
559 0 : }
560 :
561 0 : IMPL_LINK_NOARG(Dialog, ImplAsyncCloseHdl)
562 : {
563 0 : Close();
564 0 : return 0;
565 : }
566 :
567 0 : bool Dialog::Notify( NotifyEvent& rNEvt )
568 : {
569 : // first call the base class due to Tab control
570 0 : bool nRet = SystemWindow::Notify( rNEvt );
571 0 : if ( !nRet )
572 : {
573 0 : if ( rNEvt.GetType() == EVENT_KEYINPUT )
574 : {
575 0 : const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
576 0 : KeyCode aKeyCode = pKEvt->GetKeyCode();
577 0 : sal_uInt16 nKeyCode = aKeyCode.GetCode();
578 :
579 0 : if ( (nKeyCode == KEY_ESCAPE) &&
580 0 : ((GetStyle() & WB_CLOSEABLE) || ImplGetCancelButton( this ) || ImplGetOKButton( this )) )
581 : {
582 : // #i89505# for the benefit of slightly mentally challenged implementations
583 : // like e.g. SfxModelessDialog which destroy themselves inside Close()
584 : // post this Close asynchronous so we can leave our key handler before
585 : // we get destroyed
586 0 : PostUserEvent( LINK( this, Dialog, ImplAsyncCloseHdl ), this );
587 0 : return true;
588 : }
589 : }
590 0 : else if ( rNEvt.GetType() == EVENT_GETFOCUS )
591 : {
592 : // make sure the dialog is still modal
593 : // changing focus between application frames may
594 : // have re-enabled input for our parent
595 0 : if( mbInExecute && mbModalMode )
596 : {
597 : // do not change modal counter (pSVData->maAppData.mnModalDialog)
598 0 : SetModalInputMode( false );
599 0 : SetModalInputMode( true );
600 :
601 : // #93022# def-button might have changed after show
602 0 : if( !mnMousePositioned )
603 : {
604 0 : mnMousePositioned = 1;
605 0 : ImplMouseAutoPos( this );
606 : }
607 :
608 : }
609 : }
610 : }
611 :
612 0 : return nRet;
613 : }
614 :
615 : //What we really want here is something that gives the available width and
616 : //height of a users screen, taking away the space taken up the OS
617 : //taskbar, menus, etc.
618 0 : Size bestmaxFrameSizeForScreenSize(const Size &rScreenSize)
619 : {
620 0 : long w = rScreenSize.Width();
621 0 : if (w <= 800)
622 0 : w -= 15;
623 0 : else if (w <= 1024)
624 0 : w -= 65;
625 : else
626 0 : w -= 115;
627 :
628 0 : long h = rScreenSize.Height();
629 0 : if (h <= 768)
630 0 : h -= 50;
631 : else
632 0 : h -= 100;
633 :
634 0 : return Size(w, h);
635 : }
636 :
637 0 : void Dialog::setOptimalLayoutSize()
638 : {
639 0 : maLayoutTimer.Stop();
640 :
641 : //resize dialog to fit requisition on initial show
642 0 : VclBox *pBox = static_cast<VclBox*>(GetWindow(WINDOW_FIRSTCHILD));
643 :
644 : const DialogStyle& rDialogStyle =
645 0 : GetSettings().GetStyleSettings().GetDialogStyle();
646 0 : pBox->set_border_width(rDialogStyle.content_area_border);
647 0 : pBox->set_spacing(pBox->get_spacing() +
648 0 : rDialogStyle.content_area_spacing);
649 :
650 0 : VclButtonBox *pActionArea = getActionArea(this);
651 0 : if (pActionArea)
652 : {
653 0 : pActionArea->set_border_width(rDialogStyle.action_area_border);
654 0 : pActionArea->set_spacing(rDialogStyle.button_spacing);
655 : }
656 :
657 0 : Size aSize = get_preferred_size();
658 :
659 0 : Size aMax(bestmaxFrameSizeForScreenSize(GetDesktopRectPixel().GetSize()));
660 :
661 0 : aSize.Width() = std::min(aMax.Width(), aSize.Width());
662 0 : aSize.Height() = std::min(aMax.Height(), aSize.Height());
663 :
664 0 : SetMinOutputSizePixel(aSize);
665 0 : SetSizePixel(aSize);
666 0 : setPosSizeOnContainee(aSize, *pBox);
667 0 : }
668 :
669 0 : void Dialog::StateChanged( StateChangedType nType )
670 : {
671 0 : SystemWindow::StateChanged( nType );
672 :
673 0 : if ( nType == STATE_CHANGE_INITSHOW )
674 : {
675 0 : if ( GetSettings().GetStyleSettings().GetAutoMnemonic() )
676 0 : ImplWindowAutoMnemonic( this );
677 :
678 0 : if (isLayoutEnabled())
679 : {
680 0 : mbIsCalculatingInitialLayoutSize = true;
681 0 : setDeferredProperties();
682 0 : setOptimalLayoutSize();
683 0 : mbIsCalculatingInitialLayoutSize = false;
684 : }
685 :
686 0 : if ( !HasChildPathFocus() || HasFocus() )
687 0 : GrabFocusToFirstControl();
688 0 : if ( !(GetStyle() & WB_CLOSEABLE) )
689 : {
690 0 : if ( ImplGetCancelButton( this ) || ImplGetOKButton( this ) )
691 : {
692 0 : if ( ImplGetBorderWindow() )
693 0 : ((ImplBorderWindow*)ImplGetBorderWindow())->SetCloser();
694 : }
695 : }
696 :
697 0 : ImplMouseAutoPos( this );
698 : }
699 0 : else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
700 : {
701 0 : ImplInitSettings();
702 0 : Invalidate();
703 : }
704 0 : }
705 :
706 0 : void Dialog::DataChanged( const DataChangedEvent& rDCEvt )
707 : {
708 0 : SystemWindow::DataChanged( rDCEvt );
709 :
710 0 : if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
711 0 : (rDCEvt.GetFlags() & SETTINGS_STYLE) )
712 : {
713 0 : ImplInitSettings();
714 0 : Invalidate();
715 : }
716 0 : }
717 :
718 0 : bool Dialog::Close()
719 : {
720 0 : ImplDelData aDelData;
721 0 : ImplAddDel( &aDelData );
722 0 : ImplCallEventListeners( VCLEVENT_WINDOW_CLOSE );
723 0 : if ( aDelData.IsDead() )
724 0 : return false;
725 0 : ImplRemoveDel( &aDelData );
726 :
727 0 : if ( mpWindowImpl->mxWindowPeer.is() && IsCreatedWithToolkit() && !IsInExecute() )
728 0 : return false;
729 :
730 0 : mbInClose = true;
731 :
732 0 : if ( !(GetStyle() & WB_CLOSEABLE) )
733 : {
734 0 : bool bRet = true;
735 0 : ImplAddDel( &aDelData );
736 0 : PushButton* pButton = ImplGetCancelButton( this );
737 0 : if ( pButton )
738 0 : pButton->Click();
739 : else
740 : {
741 0 : pButton = ImplGetOKButton( this );
742 0 : if ( pButton )
743 0 : pButton->Click();
744 : else
745 0 : bRet = false;
746 : }
747 0 : if ( aDelData.IsDead() )
748 0 : return true;
749 0 : ImplRemoveDel( &aDelData );
750 0 : return bRet;
751 : }
752 :
753 0 : if ( IsInExecute() )
754 : {
755 0 : EndDialog( RET_CANCEL );
756 0 : mbInClose = false;
757 0 : return true;
758 : }
759 : else
760 : {
761 0 : mbInClose = false;
762 0 : return SystemWindow::Close();
763 0 : }
764 : }
765 :
766 0 : bool Dialog::ImplStartExecuteModal()
767 : {
768 0 : if ( mbInExecute )
769 : {
770 : #ifdef DBG_UTIL
771 : OStringBuffer aErrorStr;
772 : aErrorStr.append("Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): ");
773 : aErrorStr.append(ImplGetDialogText(this));
774 : OSL_FAIL(aErrorStr.getStr());
775 : #endif
776 0 : return false;
777 : }
778 :
779 0 : switch ( Application::GetDialogCancelMode() )
780 : {
781 : case Application::DIALOG_CANCEL_OFF:
782 0 : break;
783 : case Application::DIALOG_CANCEL_SILENT:
784 : SAL_INFO(
785 : "vcl",
786 : "Dialog \"" << ImplGetDialogText(this).getStr()
787 : << "\"cancelled in silent mode");
788 0 : return false;
789 : default:
790 : assert(false); // this cannot happen
791 : // fall through
792 : case Application::DIALOG_CANCEL_FATAL:
793 0 : std::abort();
794 : }
795 :
796 : #ifdef DBG_UTIL
797 : Window* pParent = GetParent();
798 : if ( pParent )
799 : {
800 : pParent = pParent->ImplGetFirstOverlapWindow();
801 : DBG_ASSERT( pParent->IsReallyVisible(),
802 : "Dialog::StartExecuteModal() - Parent not visible" );
803 : DBG_ASSERT( pParent->IsInputEnabled(),
804 : "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" );
805 : DBG_ASSERT( ! pParent->IsInModalMode(),
806 : "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" );
807 :
808 : }
809 : #endif
810 :
811 0 : ImplSVData* pSVData = ImplGetSVData();
812 :
813 : // link all dialogs which are being executed
814 0 : mpPrevExecuteDlg = pSVData->maWinData.mpLastExecuteDlg;
815 0 : pSVData->maWinData.mpLastExecuteDlg = this;
816 :
817 : // stop capturing, in order to have control over the dialog
818 0 : if ( pSVData->maWinData.mpTrackWin )
819 0 : pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL );
820 0 : if ( pSVData->maWinData.mpCaptureWin )
821 0 : pSVData->maWinData.mpCaptureWin->ReleaseMouse();
822 0 : EnableInput( true, true );
823 :
824 0 : if ( GetParent() )
825 : {
826 0 : NotifyEvent aNEvt( EVENT_EXECUTEDIALOG, this );
827 0 : GetParent()->Notify( aNEvt );
828 : }
829 0 : mbInExecute = true;
830 0 : SetModalInputMode( true );
831 0 : mbOldSaveBack = IsSaveBackgroundEnabled();
832 0 : EnableSaveBackground();
833 :
834 : // FIXME: no layouting, workaround some clipping issues
835 0 : ImplAdjustNWFSizes();
836 :
837 0 : Show();
838 :
839 0 : pSVData->maAppData.mnModalMode++;
840 0 : return true;
841 : }
842 :
843 0 : void Dialog::ImplEndExecuteModal()
844 : {
845 0 : ImplSVData* pSVData = ImplGetSVData();
846 0 : pSVData->maAppData.mnModalMode--;
847 0 : }
848 :
849 0 : short Dialog::Execute()
850 : {
851 : #if HAVE_FEATURE_DESKTOP
852 :
853 0 : setDeferredProperties();
854 :
855 0 : if ( !ImplStartExecuteModal() )
856 0 : return 0;
857 :
858 0 : ImplDelData aDelData;
859 0 : ImplAddDel( &aDelData );
860 :
861 : #ifdef DBG_UTIL
862 : ImplDelData aParentDelData;
863 : Window* pDialogParent = mpDialogParent;
864 : if( pDialogParent )
865 : pDialogParent->ImplAddDel( &aParentDelData );
866 : #endif
867 :
868 : // Yield util EndDialog is called or dialog gets destroyed
869 : // (the latter should not happen, but better safe than sorry
870 0 : while ( !aDelData.IsDead() && mbInExecute )
871 0 : Application::Yield();
872 :
873 0 : ImplEndExecuteModal();
874 :
875 : #ifdef DBG_UTIL
876 : if( pDialogParent )
877 : {
878 : if( ! aParentDelData.IsDead() )
879 : pDialogParent->ImplRemoveDel( &aParentDelData );
880 : else
881 : OSL_FAIL( "Dialog::Execute() - Parent of dialog destroyed in Execute()" );
882 : }
883 : #endif
884 0 : if ( !aDelData.IsDead() )
885 0 : ImplRemoveDel( &aDelData );
886 : #ifdef DBG_UTIL
887 : else
888 : {
889 : OSL_FAIL( "Dialog::Execute() - Dialog destroyed in Execute()" );
890 : }
891 : #endif
892 :
893 0 : long nRet = mpDialogImpl->mnResult;
894 0 : mpDialogImpl->mnResult = -1;
895 0 : return (short)nRet;
896 :
897 : #else
898 :
899 : MLODialogKind kind;
900 :
901 : switch (GetType())
902 : {
903 : case WINDOW_MESSBOX:
904 : kind = MLODialogMessage;
905 : break;
906 : case WINDOW_INFOBOX:
907 : kind = MLODialogInformation;
908 : break;
909 : case WINDOW_WARNINGBOX:
910 : kind = MLODialogWarning;
911 : break;
912 : case WINDOW_ERRORBOX:
913 : kind = MLODialogError;
914 : break;
915 : case WINDOW_QUERYBOX:
916 : kind = MLODialogQuery;
917 : break;
918 : default:
919 : SAL_WARN("vcl", "Dialog::Execute: Unhandled window type %d" << GetType());
920 : kind = MLODialogInformation;
921 : break;
922 : }
923 :
924 : MLODialogResult result = touch_ui_dialog_modal(kind, ImplGetDialogText(this).getStr());
925 :
926 : switch (result)
927 : {
928 : case MLODialogOK:
929 : return RET_OK;
930 : case MLODialogCancel:
931 : return RET_CANCEL;
932 : case MLODialogNo:
933 : return RET_NO;
934 : case MLODialogYes:
935 : return RET_YES;
936 : case MLODialogRetry:
937 : return RET_RETRY;
938 : case MLODialogIgnore:
939 : return RET_IGNORE;
940 : default:
941 : SAL_WARN("vcl", "Dialog::Execute: Unhandled dialog result %d" << result);
942 : return RET_OK;
943 : }
944 :
945 : #endif
946 : }
947 :
948 : // virtual
949 0 : void Dialog::StartExecuteModal( const Link& rEndDialogHdl )
950 : {
951 0 : if ( !ImplStartExecuteModal() )
952 0 : return;
953 :
954 0 : mpDialogImpl->maEndDialogHdl = rEndDialogHdl;
955 0 : mpDialogImpl->mbStartedModal = true;
956 : }
957 :
958 0 : void Dialog::EndDialog( long nResult )
959 : {
960 0 : if ( mbInExecute )
961 : {
962 0 : SetModalInputMode( false );
963 :
964 : // remove dialog from the list of dialogs which are being executed
965 0 : ImplSVData* pSVData = ImplGetSVData();
966 0 : Dialog* pExeDlg = pSVData->maWinData.mpLastExecuteDlg;
967 0 : while ( pExeDlg )
968 : {
969 0 : if ( pExeDlg == this )
970 : {
971 0 : pSVData->maWinData.mpLastExecuteDlg = mpPrevExecuteDlg;
972 0 : break;
973 : }
974 0 : pExeDlg = pExeDlg->mpPrevExecuteDlg;
975 : }
976 : // set focus to previous modal dialogue if it is modal for
977 : // the same frame parent (or NULL)
978 0 : if( mpPrevExecuteDlg )
979 : {
980 0 : Window* pFrameParent = ImplGetFrameWindow()->ImplGetParent();
981 0 : Window* pPrevFrameParent = mpPrevExecuteDlg->ImplGetFrameWindow()->ImplGetParent();
982 0 : if( ( !pFrameParent && !pPrevFrameParent ) ||
983 0 : ( pFrameParent && pPrevFrameParent && pFrameParent->ImplGetFrame() == pPrevFrameParent->ImplGetFrame() )
984 : )
985 : {
986 0 : mpPrevExecuteDlg->GrabFocus();
987 : }
988 : }
989 0 : mpPrevExecuteDlg = NULL;
990 :
991 0 : Hide();
992 0 : EnableSaveBackground( mbOldSaveBack );
993 0 : if ( GetParent() )
994 : {
995 0 : NotifyEvent aNEvt( EVENT_ENDEXECUTEDIALOG, this );
996 0 : GetParent()->Notify( aNEvt );
997 : }
998 :
999 0 : mpDialogImpl->mnResult = nResult;
1000 :
1001 0 : if ( mpDialogImpl->mbStartedModal )
1002 : {
1003 0 : ImplEndExecuteModal();
1004 0 : mpDialogImpl->maEndDialogHdl.Call( this );
1005 :
1006 0 : mpDialogImpl->maEndDialogHdl = Link();
1007 0 : mpDialogImpl->mbStartedModal = false;
1008 0 : mpDialogImpl->mnResult = -1;
1009 : }
1010 0 : mbInExecute = false;
1011 : }
1012 0 : }
1013 :
1014 0 : long Dialog::GetResult() const
1015 : {
1016 0 : return mpDialogImpl->mnResult;
1017 : }
1018 :
1019 0 : void Dialog::EndAllDialogs( Window* pParent )
1020 : {
1021 0 : ImplSVData* pSVData = ImplGetSVData();
1022 : Dialog* pTempModDialog;
1023 0 : Dialog* pModDialog = pSVData->maWinData.mpLastExecuteDlg;
1024 0 : while ( pModDialog )
1025 : {
1026 0 : pTempModDialog = pModDialog->mpPrevExecuteDlg;
1027 0 : if( !pParent || ( pParent && pParent->IsWindowOrChild( pModDialog, true ) ) )
1028 : {
1029 0 : pModDialog->EndDialog( RET_CANCEL );
1030 0 : pModDialog->PostUserEvent( Link() );
1031 : }
1032 0 : pModDialog = pTempModDialog;
1033 : }
1034 0 : }
1035 :
1036 0 : void Dialog::SetModalInputMode( bool bModal )
1037 : {
1038 0 : if ( bModal == mbModalMode )
1039 0 : return;
1040 :
1041 0 : ImplSVData* pSVData = ImplGetSVData();
1042 0 : mbModalMode = bModal;
1043 0 : if ( bModal )
1044 : {
1045 0 : pSVData->maAppData.mnModalDialog++;
1046 :
1047 : // Diable the prev Modal Dialog, because our dialog must close at first,
1048 : // before the other dialog can be closed (because the other dialog
1049 : // is on stack since our dialog returns)
1050 0 : if ( mpPrevExecuteDlg && !mpPrevExecuteDlg->IsWindowOrChild( this, true ) )
1051 0 : mpPrevExecuteDlg->EnableInput( false, true, true, this );
1052 :
1053 : // determine next overlap dialog parent
1054 0 : Window* pParent = GetParent();
1055 0 : if ( pParent )
1056 : {
1057 : // #103716# dialogs should always be modal to the whole frame window
1058 : // #115933# disable the whole frame hierarchie, useful if our parent
1059 : // is a modeless dialog
1060 0 : mpDialogParent = pParent->mpWindowImpl->mpFrameWindow;
1061 0 : mpDialogParent->ImplIncModalCount();
1062 : }
1063 :
1064 : }
1065 : else
1066 : {
1067 0 : pSVData->maAppData.mnModalDialog--;
1068 :
1069 0 : if ( mpDialogParent )
1070 : {
1071 : // #115933# re-enable the whole frame hierarchie again (see above)
1072 : // note that code in getfocus assures that we do not accidentally enable
1073 : // windows that were disabled before
1074 0 : mpDialogParent->ImplDecModalCount();
1075 : }
1076 :
1077 : // Enable the prev Modal Dialog
1078 0 : if ( mpPrevExecuteDlg && !mpPrevExecuteDlg->IsWindowOrChild( this, true ) )
1079 : {
1080 0 : mpPrevExecuteDlg->EnableInput( true, true, true, this );
1081 : // ensure continued modality of prev dialog
1082 : // do not change modality counter
1083 :
1084 : // #i119994# need find the last modal dialog before reactive it
1085 0 : Dialog * pPrevModalDlg = mpPrevExecuteDlg;
1086 :
1087 0 : while( pPrevModalDlg && !pPrevModalDlg->IsModalInputMode() )
1088 0 : pPrevModalDlg = pPrevModalDlg->mpPrevExecuteDlg;
1089 :
1090 0 : if( pPrevModalDlg &&
1091 0 : ( pPrevModalDlg == mpPrevExecuteDlg
1092 0 : || !pPrevModalDlg->IsWindowOrChild( this, true ) ) )
1093 : {
1094 0 : mpPrevExecuteDlg->SetModalInputMode( false );
1095 0 : mpPrevExecuteDlg->SetModalInputMode( true );
1096 : }
1097 : }
1098 : }
1099 : }
1100 :
1101 0 : void Dialog::SetModalInputMode( bool bModal, bool bSubModalDialogs )
1102 : {
1103 0 : if ( bSubModalDialogs )
1104 : {
1105 0 : Window* pOverlap = ImplGetFirstOverlapWindow();
1106 0 : pOverlap = pOverlap->mpWindowImpl->mpFirstOverlap;
1107 0 : while ( pOverlap )
1108 : {
1109 0 : if ( pOverlap->IsDialog() )
1110 0 : ((Dialog*)pOverlap)->SetModalInputMode( bModal, true );
1111 0 : pOverlap = pOverlap->mpWindowImpl->mpNext;
1112 : }
1113 : }
1114 :
1115 0 : SetModalInputMode( bModal );
1116 0 : }
1117 :
1118 0 : void Dialog::GrabFocusToFirstControl()
1119 : {
1120 : Window* pFocusControl;
1121 :
1122 : // find focus control, even if the dialog has focus
1123 0 : if ( HasFocus() )
1124 0 : pFocusControl = NULL;
1125 : else
1126 : {
1127 : // prefer a child window which had focus before
1128 0 : pFocusControl = ImplGetFirstOverlapWindow()->mpWindowImpl->mpLastFocusWindow;
1129 : // find the control out of the dialog control
1130 0 : if ( pFocusControl )
1131 0 : pFocusControl = ImplFindDlgCtrlWindow( pFocusControl );
1132 : }
1133 : // no control had the focus before or the control is not
1134 : // part of the tab-control, now give focus to the
1135 : // first control in the tab-control
1136 0 : if ( !pFocusControl ||
1137 0 : !(pFocusControl->GetStyle() & WB_TABSTOP) ||
1138 0 : !isVisibleInLayout(pFocusControl) ||
1139 0 : !isEnabledInLayout(pFocusControl) || !pFocusControl->IsInputEnabled() )
1140 : {
1141 0 : sal_uInt16 n = 0;
1142 0 : pFocusControl = ImplGetDlgWindow( n, DLGWINDOW_FIRST );
1143 : }
1144 0 : if ( pFocusControl )
1145 0 : pFocusControl->ImplControlFocus( GETFOCUS_INIT );
1146 0 : }
1147 :
1148 0 : void Dialog::GetDrawWindowBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder, sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
1149 : {
1150 0 : ImplBorderWindow aImplWin( (Window*)this, WB_BORDER|WB_STDWORK, BORDERWINDOW_STYLE_OVERLAP );
1151 0 : aImplWin.GetBorder( rLeftBorder, rTopBorder, rRightBorder, rBottomBorder );
1152 0 : }
1153 :
1154 0 : void Dialog::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong )
1155 : {
1156 0 : Point aPos = pDev->LogicToPixel( rPos );
1157 0 : Size aSize = pDev->LogicToPixel( rSize );
1158 :
1159 0 : Wallpaper aWallpaper = GetBackground();
1160 0 : if ( !aWallpaper.IsBitmap() )
1161 0 : ImplInitSettings();
1162 :
1163 0 : pDev->Push();
1164 0 : pDev->SetMapMode();
1165 0 : pDev->SetLineColor();
1166 :
1167 0 : if ( aWallpaper.IsBitmap() )
1168 0 : pDev->DrawBitmapEx( aPos, aSize, aWallpaper.GetBitmap() );
1169 : else
1170 : {
1171 0 : pDev->SetFillColor( aWallpaper.GetColor() );
1172 0 : pDev->DrawRect( Rectangle( aPos, aSize ) );
1173 : }
1174 :
1175 0 : if (!( GetStyle() & WB_NOBORDER ))
1176 : {
1177 0 : ImplBorderWindow aImplWin( this, WB_BORDER|WB_STDWORK, BORDERWINDOW_STYLE_OVERLAP );
1178 0 : aImplWin.SetText( GetText() );
1179 0 : aImplWin.setPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height() );
1180 0 : aImplWin.SetDisplayActive( true );
1181 0 : aImplWin.InitView();
1182 :
1183 0 : aImplWin.Draw( Rectangle( aPos, aSize ), pDev, aPos );
1184 : }
1185 :
1186 0 : pDev->Pop();
1187 0 : }
1188 :
1189 0 : bool Dialog::isLayoutEnabled() const
1190 : {
1191 : //pre dtor called, and single child is a container => we're layout enabled
1192 0 : return mpDialogImpl ? ::isLayoutEnabled(this) : false;
1193 : }
1194 :
1195 0 : Size Dialog::GetOptimalSize() const
1196 : {
1197 0 : if (!isLayoutEnabled())
1198 0 : return SystemWindow::GetOptimalSize();
1199 :
1200 0 : Size aSize = VclContainer::getLayoutRequisition(*GetWindow(WINDOW_FIRSTCHILD));
1201 :
1202 0 : sal_Int32 nBorderWidth = get_border_width();
1203 :
1204 0 : aSize.Height() += mpWindowImpl->mnLeftBorder + mpWindowImpl->mnRightBorder
1205 0 : + 2*nBorderWidth;
1206 0 : aSize.Width() += mpWindowImpl->mnTopBorder + mpWindowImpl->mnBottomBorder
1207 0 : + 2*nBorderWidth;
1208 :
1209 0 : return Window::CalcWindowSize(aSize);
1210 : }
1211 :
1212 0 : void Dialog::setPosSizeOnContainee(Size aSize, VclContainer &rBox)
1213 : {
1214 0 : sal_Int32 nBorderWidth = get_border_width();
1215 :
1216 0 : aSize.Width() -= mpWindowImpl->mnLeftBorder + mpWindowImpl->mnRightBorder
1217 0 : + 2 * nBorderWidth;
1218 0 : aSize.Height() -= mpWindowImpl->mnTopBorder + mpWindowImpl->mnBottomBorder
1219 0 : + 2 * nBorderWidth;
1220 :
1221 : Point aPos(mpWindowImpl->mnLeftBorder + nBorderWidth,
1222 0 : mpWindowImpl->mnTopBorder + nBorderWidth);
1223 :
1224 0 : VclContainer::setLayoutAllocation(rBox, aPos, aSize);
1225 0 : }
1226 :
1227 0 : IMPL_LINK( Dialog, ImplHandleLayoutTimerHdl, void*, EMPTYARG )
1228 : {
1229 0 : if (!isLayoutEnabled())
1230 : {
1231 : SAL_WARN("vcl.layout", "Dialog has become non-layout because extra children have been added directly to it.");
1232 0 : return 0;
1233 : }
1234 :
1235 0 : VclBox *pBox = static_cast<VclBox*>(GetWindow(WINDOW_FIRSTCHILD));
1236 : assert(pBox);
1237 0 : setPosSizeOnContainee(GetSizePixel(), *pBox);
1238 0 : return 0;
1239 : }
1240 :
1241 0 : void Dialog::queue_resize()
1242 : {
1243 0 : if (hasPendingLayout() || isCalculatingInitialLayoutSize())
1244 0 : return;
1245 0 : if (IsInClose())
1246 0 : return;
1247 0 : if (!isLayoutEnabled())
1248 0 : return;
1249 0 : maLayoutTimer.Start();
1250 : }
1251 :
1252 0 : void Dialog::Resize()
1253 : {
1254 0 : queue_resize();
1255 0 : }
1256 :
1257 0 : bool Dialog::set_property(const OString &rKey, const OString &rValue)
1258 : {
1259 0 : if (rKey == "border-width")
1260 0 : set_border_width(rValue.toInt32());
1261 : else
1262 0 : return SystemWindow::set_property(rKey, rValue);
1263 0 : return true;
1264 : }
1265 :
1266 0 : void Dialog::SetText(const OUString& rStr)
1267 : {
1268 0 : setDeferredProperties();
1269 0 : SystemWindow::SetText(rStr);
1270 0 : }
1271 :
1272 0 : OUString Dialog::GetText() const
1273 : {
1274 0 : const_cast<Dialog*>(this)->setDeferredProperties();
1275 0 : return SystemWindow::GetText();
1276 : }
1277 :
1278 0 : VclBuilderContainer::VclBuilderContainer()
1279 0 : : m_pUIBuilder(NULL)
1280 : {
1281 0 : }
1282 :
1283 0 : VclBuilderContainer::~VclBuilderContainer()
1284 : {
1285 0 : delete m_pUIBuilder;
1286 0 : }
1287 :
1288 0 : ModelessDialog::ModelessDialog( Window* pParent, const ResId& rResId ) :
1289 0 : Dialog( WINDOW_MODELESSDIALOG )
1290 : {
1291 0 : rResId.SetRT( RSC_MODELESSDIALOG );
1292 :
1293 0 : WinBits nStyle = init( pParent, rResId );
1294 :
1295 0 : if ( !(nStyle & WB_HIDE) )
1296 0 : Show();
1297 0 : }
1298 :
1299 0 : ModelessDialog::ModelessDialog( Window* pParent, const OString& rID, const OUString& rUIXMLDescription ) :
1300 0 : Dialog(pParent, rID, rUIXMLDescription, WINDOW_MODELESSDIALOG)
1301 : {
1302 0 : }
1303 :
1304 0 : ModalDialog::ModalDialog( Window* pParent, WinBits nStyle ) :
1305 0 : Dialog( WINDOW_MODALDIALOG )
1306 : {
1307 0 : ImplInit( pParent, nStyle );
1308 0 : }
1309 :
1310 0 : ModalDialog::ModalDialog( Window* pParent, const ResId& rResId ) :
1311 0 : Dialog( WINDOW_MODALDIALOG )
1312 : {
1313 0 : rResId.SetRT( RSC_MODALDIALOG );
1314 0 : init( pParent, rResId );
1315 0 : }
1316 :
1317 0 : ModalDialog::ModalDialog( Window* pParent, const OString& rID, const OUString& rUIXMLDescription ) :
1318 0 : Dialog(pParent, rID, rUIXMLDescription, WINDOW_MODALDIALOG)
1319 : {
1320 3 : }
1321 :
1322 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|