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 <sal/config.h>
21 :
22 : #include <cstdlib>
23 :
24 : #include <tools/debug.hxx>
25 :
26 : #include <vcl/svapp.hxx>
27 : #include <vcl/menu.hxx>
28 : #include <vcl/event.hxx>
29 : #include <vcl/syswin.hxx>
30 : #include <vcl/taskpanelist.hxx>
31 : #include <vcl/unowrap.hxx>
32 :
33 : #include <rtl/strbuf.hxx>
34 :
35 : #include <salframe.hxx>
36 : #include <svdata.hxx>
37 : #include <brdwin.hxx>
38 : #include <window.h>
39 :
40 : using namespace ::com::sun::star::uno;
41 : using namespace ::com::sun::star::lang;
42 :
43 : class SystemWindow::ImplData
44 : {
45 : public:
46 : ImplData();
47 : ~ImplData();
48 :
49 : TaskPaneList* mpTaskPaneList;
50 : Size maMaxOutSize;
51 : OUString maRepresentedURL;
52 : Link maCloseHdl;
53 : };
54 :
55 4597 : SystemWindow::ImplData::ImplData()
56 : {
57 4597 : mpTaskPaneList = NULL;
58 4597 : maMaxOutSize = Size( SHRT_MAX, SHRT_MAX );
59 4597 : }
60 :
61 9040 : SystemWindow::ImplData::~ImplData()
62 : {
63 4520 : if( mpTaskPaneList )
64 2056 : delete mpTaskPaneList;
65 4520 : }
66 :
67 4597 : SystemWindow::SystemWindow( WindowType nType ) :
68 4597 : Window( nType )
69 : {
70 4597 : mpImplData = new ImplData;
71 4597 : mpWindowImpl->mbSysWin = true;
72 4597 : mpWindowImpl->mnActivateMode = ACTIVATE_MODE_GRABFOCUS;
73 :
74 4597 : mpMenuBar = NULL;
75 4597 : mbPinned = false;
76 4597 : mbRollUp = false;
77 4597 : mbRollFunc = false;
78 4597 : mbDockBtn = false;
79 4597 : mbHideBtn = false;
80 4597 : mbSysChild = false;
81 4597 : mnMenuBarMode = MENUBAR_MODE_NORMAL;
82 4597 : mnIcon = 0;
83 4597 : }
84 :
85 9040 : SystemWindow::~SystemWindow()
86 : {
87 4520 : delete mpImplData;
88 4520 : mpImplData = NULL;
89 4520 : }
90 :
91 45841 : bool SystemWindow::Notify( NotifyEvent& rNEvt )
92 : {
93 : // capture KeyEvents for menu handling
94 45841 : if ( rNEvt.GetType() == EVENT_KEYINPUT )
95 : {
96 0 : MenuBar* pMBar = mpMenuBar;
97 0 : if ( !pMBar && ( GetType() == WINDOW_FLOATINGWINDOW ) )
98 : {
99 0 : Window* pWin = ImplGetFrameWindow()->ImplGetWindow();
100 0 : if( pWin && pWin->IsSystemWindow() )
101 0 : pMBar = ((SystemWindow*)pWin)->GetMenuBar();
102 : }
103 0 : if ( pMBar && pMBar->ImplHandleKeyEvent( *rNEvt.GetKeyEvent(), false ) )
104 0 : return true;
105 : }
106 :
107 45841 : return Window::Notify( rNEvt );
108 : }
109 :
110 20638 : bool SystemWindow::PreNotify( NotifyEvent& rNEvt )
111 : {
112 : // capture KeyEvents for taskpane cycling
113 20638 : if ( rNEvt.GetType() == EVENT_KEYINPUT )
114 : {
115 0 : if( rNEvt.GetKeyEvent()->GetKeyCode().GetCode() == KEY_F6 &&
116 0 : rNEvt.GetKeyEvent()->GetKeyCode().IsMod1() &&
117 0 : !rNEvt.GetKeyEvent()->GetKeyCode().IsShift() )
118 : {
119 : // Ctrl-F6 goes directly to the document
120 0 : GrabFocusToDocument();
121 0 : return true;
122 : }
123 : else
124 : {
125 0 : TaskPaneList *pTList = mpImplData->mpTaskPaneList;
126 0 : if( !pTList && ( GetType() == WINDOW_FLOATINGWINDOW ) )
127 : {
128 0 : Window* pWin = ImplGetFrameWindow()->ImplGetWindow();
129 0 : if( pWin && pWin->IsSystemWindow() )
130 0 : pTList = ((SystemWindow*)pWin)->mpImplData->mpTaskPaneList;
131 : }
132 0 : if( !pTList )
133 : {
134 : // search topmost system window which is the one to handle dialog/toolbar cycling
135 0 : SystemWindow *pSysWin = this;
136 0 : Window *pWin = this;
137 0 : while( pWin )
138 : {
139 0 : pWin = pWin->GetParent();
140 0 : if( pWin && pWin->IsSystemWindow() )
141 0 : pSysWin = (SystemWindow*) pWin;
142 : }
143 0 : pTList = pSysWin->mpImplData->mpTaskPaneList;
144 : }
145 0 : if( pTList && pTList->HandleKeyEvent( *rNEvt.GetKeyEvent() ) )
146 0 : return true;
147 : }
148 : }
149 20638 : return Window::PreNotify( rNEvt );
150 : }
151 :
152 17816 : TaskPaneList* SystemWindow::GetTaskPaneList()
153 : {
154 17816 : if( mpImplData->mpTaskPaneList )
155 15751 : return mpImplData->mpTaskPaneList ;
156 : else
157 : {
158 2065 : mpImplData->mpTaskPaneList = new TaskPaneList();
159 2065 : MenuBar* pMBar = mpMenuBar;
160 2065 : if ( !pMBar && ( GetType() == WINDOW_FLOATINGWINDOW ) )
161 : {
162 0 : Window* pWin = ImplGetFrameWindow()->ImplGetWindow();
163 0 : if ( pWin && pWin->IsSystemWindow() )
164 0 : pMBar = ((SystemWindow*)pWin)->GetMenuBar();
165 : }
166 2065 : if( pMBar )
167 75 : mpImplData->mpTaskPaneList->AddWindow( pMBar->ImplGetWindow() );
168 2065 : return mpImplData->mpTaskPaneList;
169 : }
170 : }
171 :
172 0 : bool SystemWindow::Close()
173 : {
174 0 : ImplDelData aDelData;
175 0 : ImplAddDel( &aDelData );
176 0 : ImplCallEventListeners( VCLEVENT_WINDOW_CLOSE );
177 0 : if ( aDelData.IsDead() )
178 0 : return false;
179 0 : ImplRemoveDel( &aDelData );
180 :
181 0 : if ( mpWindowImpl->mxWindowPeer.is() && IsCreatedWithToolkit() )
182 0 : return false;
183 :
184 : // Is Window not closeable, ignore close
185 0 : Window* pBorderWin = ImplGetBorderWindow();
186 : WinBits nStyle;
187 0 : if ( pBorderWin )
188 0 : nStyle = pBorderWin->GetStyle();
189 : else
190 0 : nStyle = GetStyle();
191 0 : if ( !(nStyle & WB_CLOSEABLE) )
192 0 : return false;
193 :
194 0 : Hide();
195 :
196 0 : return true;
197 : }
198 :
199 0 : void SystemWindow::TitleButtonClick( sal_uInt16 )
200 : {
201 0 : }
202 :
203 0 : void SystemWindow::Pin()
204 : {
205 0 : }
206 :
207 0 : void SystemWindow::Roll()
208 : {
209 0 : }
210 :
211 0 : void SystemWindow::Resizing( Size& )
212 : {
213 0 : }
214 :
215 4176 : void SystemWindow::SetRepresentedURL( const OUString& i_rURL )
216 : {
217 4176 : bool bChanged = (i_rURL != mpImplData->maRepresentedURL);
218 4176 : mpImplData->maRepresentedURL = i_rURL;
219 4176 : if ( !mbSysChild && bChanged )
220 : {
221 1391 : const Window* pWindow = this;
222 4173 : while ( pWindow->mpWindowImpl->mpBorderWindow )
223 1391 : pWindow = pWindow->mpWindowImpl->mpBorderWindow;
224 :
225 1391 : if ( pWindow->mpWindowImpl->mbFrame )
226 1391 : pWindow->mpWindowImpl->mpFrame->SetRepresentedURL( i_rURL );
227 : }
228 4176 : }
229 :
230 6254 : void SystemWindow::SetIcon( sal_uInt16 nIcon )
231 : {
232 6254 : if ( mnIcon == nIcon )
233 10422 : return;
234 :
235 2086 : mnIcon = nIcon;
236 :
237 2086 : if ( !mbSysChild )
238 : {
239 2086 : const Window* pWindow = this;
240 6258 : while ( pWindow->mpWindowImpl->mpBorderWindow )
241 2086 : pWindow = pWindow->mpWindowImpl->mpBorderWindow;
242 :
243 2086 : if ( pWindow->mpWindowImpl->mbFrame )
244 2086 : pWindow->mpWindowImpl->mpFrame->SetIcon( nIcon );
245 : }
246 : }
247 :
248 2304 : void SystemWindow::EnableSaveBackground( bool bSave )
249 : {
250 2304 : if( ImplGetSVData()->maWinData.mbNoSaveBackground )
251 0 : bSave = false;
252 :
253 2304 : Window* pWindow = this;
254 6912 : while ( pWindow->mpWindowImpl->mpBorderWindow )
255 2304 : pWindow = pWindow->mpWindowImpl->mpBorderWindow;
256 2304 : if ( pWindow->mpWindowImpl->mbOverlapWin && !pWindow->mpWindowImpl->mbFrame )
257 : {
258 0 : pWindow->mpWindowImpl->mpOverlapData->mbSaveBack = bSave;
259 0 : if ( !bSave )
260 0 : pWindow->ImplDeleteOverlapBackground();
261 : }
262 2304 : }
263 :
264 12 : bool SystemWindow::IsSaveBackgroundEnabled() const
265 : {
266 12 : const Window* pWindow = this;
267 36 : while ( pWindow->mpWindowImpl->mpBorderWindow )
268 12 : pWindow = pWindow->mpWindowImpl->mpBorderWindow;
269 12 : if ( pWindow->mpWindowImpl->mpOverlapData )
270 12 : return pWindow->mpWindowImpl->mpOverlapData->mbSaveBack;
271 : else
272 0 : return false;
273 : }
274 :
275 0 : void SystemWindow::ShowTitleButton( sal_uInt16 nButton, bool bVisible )
276 : {
277 0 : if ( nButton == TITLE_BUTTON_DOCKING )
278 : {
279 0 : if ( mbDockBtn != bVisible )
280 : {
281 0 : mbDockBtn = bVisible;
282 0 : if ( mpWindowImpl->mpBorderWindow )
283 0 : ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetDockButton( bVisible );
284 : }
285 : }
286 0 : else if ( nButton == TITLE_BUTTON_HIDE )
287 : {
288 0 : if ( mbHideBtn != bVisible )
289 : {
290 0 : mbHideBtn = bVisible;
291 0 : if ( mpWindowImpl->mpBorderWindow )
292 0 : ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetHideButton( bVisible );
293 : }
294 : }
295 0 : else if ( nButton == TITLE_BUTTON_MENU )
296 : {
297 0 : if ( mpWindowImpl->mpBorderWindow )
298 0 : ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetMenuButton( bVisible );
299 : }
300 : else
301 0 : return;
302 : }
303 :
304 0 : bool SystemWindow::IsTitleButtonVisible( sal_uInt16 nButton ) const
305 : {
306 0 : if ( nButton == TITLE_BUTTON_DOCKING )
307 0 : return mbDockBtn;
308 : else /* if ( nButton == TITLE_BUTTON_HIDE ) */
309 0 : return mbHideBtn;
310 : }
311 :
312 0 : void SystemWindow::SetPin( bool bPin )
313 : {
314 0 : if ( bPin != mbPinned )
315 : {
316 0 : mbPinned = bPin;
317 0 : if ( mpWindowImpl->mpBorderWindow )
318 0 : ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetPin( bPin );
319 : }
320 0 : }
321 :
322 0 : void SystemWindow::RollUp()
323 : {
324 0 : if ( !mbRollUp )
325 : {
326 0 : maOrgSize = GetOutputSizePixel();
327 0 : mbRollFunc = true;
328 0 : Size aSize = maRollUpOutSize;
329 0 : if ( !aSize.Width() )
330 0 : aSize.Width() = GetOutputSizePixel().Width();
331 0 : mbRollUp = true;
332 0 : if ( mpWindowImpl->mpBorderWindow )
333 0 : ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetRollUp( true, aSize );
334 : else
335 0 : SetOutputSizePixel( aSize );
336 0 : mbRollFunc = false;
337 : }
338 0 : }
339 :
340 0 : void SystemWindow::RollDown()
341 : {
342 0 : if ( mbRollUp )
343 : {
344 0 : mbRollUp = false;
345 0 : if ( mpWindowImpl->mpBorderWindow )
346 0 : ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetRollUp( false, maOrgSize );
347 : else
348 0 : SetOutputSizePixel( maOrgSize );
349 : }
350 0 : }
351 :
352 1 : void SystemWindow::SetMinOutputSizePixel( const Size& rSize )
353 : {
354 1 : maMinOutSize = rSize;
355 1 : if ( mpWindowImpl->mpBorderWindow )
356 : {
357 1 : ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetMinOutputSize( rSize.Width(), rSize.Height() );
358 1 : if ( mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame )
359 1 : mpWindowImpl->mpBorderWindow->mpWindowImpl->mpFrame->SetMinClientSize( rSize.Width(), rSize.Height() );
360 : }
361 0 : else if ( mpWindowImpl->mbFrame )
362 0 : mpWindowImpl->mpFrame->SetMinClientSize( rSize.Width(), rSize.Height() );
363 1 : }
364 :
365 0 : void SystemWindow::SetMaxOutputSizePixel( const Size& rSize )
366 : {
367 0 : Size aSize( rSize );
368 0 : if( aSize.Width() > SHRT_MAX || aSize.Width() <= 0 )
369 0 : aSize.Width() = SHRT_MAX;
370 0 : if( aSize.Height() > SHRT_MAX || aSize.Height() <= 0 )
371 0 : aSize.Height() = SHRT_MAX;
372 :
373 0 : mpImplData->maMaxOutSize = aSize;
374 0 : if ( mpWindowImpl->mpBorderWindow )
375 : {
376 0 : ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetMaxOutputSize( aSize.Width(), aSize.Height() );
377 0 : if ( mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame )
378 0 : mpWindowImpl->mpBorderWindow->mpWindowImpl->mpFrame->SetMaxClientSize( aSize.Width(), aSize.Height() );
379 : }
380 0 : else if ( mpWindowImpl->mbFrame )
381 0 : mpWindowImpl->mpFrame->SetMaxClientSize( aSize.Width(), aSize.Height() );
382 0 : }
383 :
384 97 : const Size& SystemWindow::GetMaxOutputSizePixel() const
385 : {
386 97 : return mpImplData->maMaxOutSize;
387 : }
388 :
389 0 : Size SystemWindow::GetResizeOutputSizePixel() const
390 : {
391 0 : Size aSize = GetOutputSizePixel();
392 0 : if ( aSize.Width() < maMinOutSize.Width() )
393 0 : aSize.Width() = maMinOutSize.Width();
394 0 : if ( aSize.Height() < maMinOutSize.Height() )
395 0 : aSize.Height() = maMinOutSize.Height();
396 0 : return aSize;
397 : }
398 :
399 2108 : static void ImplWindowStateFromStr(WindowStateData& rData,
400 : const OString& rStr)
401 : {
402 2108 : sal_uLong nValidMask = 0;
403 2108 : sal_Int32 nIndex = 0;
404 2108 : OString aTokenStr;
405 :
406 2108 : aTokenStr = rStr.getToken(0, ',', nIndex);
407 2108 : if (!aTokenStr.isEmpty())
408 : {
409 2026 : rData.SetX(aTokenStr.toInt32());
410 2026 : if( rData.GetX() > -16384 && rData.GetX() < 16384 )
411 2026 : nValidMask |= WINDOWSTATE_MASK_X;
412 : else
413 0 : rData.SetX( 0 );
414 : }
415 : else
416 82 : rData.SetX( 0 );
417 2108 : aTokenStr = rStr.getToken(0, ',', nIndex);
418 2108 : if (!aTokenStr.isEmpty())
419 : {
420 2026 : rData.SetY(aTokenStr.toInt32());
421 2026 : if( rData.GetY() > -16384 && rData.GetY() < 16384 )
422 2026 : nValidMask |= WINDOWSTATE_MASK_Y;
423 : else
424 0 : rData.SetY( 0 );
425 : }
426 : else
427 82 : rData.SetY( 0 );
428 2108 : aTokenStr = rStr.getToken(0, ',', nIndex);
429 2108 : if (!aTokenStr.isEmpty())
430 : {
431 1996 : rData.SetWidth(aTokenStr.toInt32());
432 1996 : if( rData.GetWidth() > 0 && rData.GetWidth() < 16384 )
433 1996 : nValidMask |= WINDOWSTATE_MASK_WIDTH;
434 : else
435 0 : rData.SetWidth( 0 );
436 : }
437 : else
438 112 : rData.SetWidth( 0 );
439 2108 : aTokenStr = rStr.getToken(0, ';', nIndex);
440 2108 : if (!aTokenStr.isEmpty())
441 : {
442 1996 : rData.SetHeight(aTokenStr.toInt32());
443 1996 : if( rData.GetHeight() > 0 && rData.GetHeight() < 16384 )
444 1996 : nValidMask |= WINDOWSTATE_MASK_HEIGHT;
445 : else
446 0 : rData.SetHeight( 0 );
447 : }
448 : else
449 112 : rData.SetHeight( 0 );
450 2108 : aTokenStr = rStr.getToken(0, ';', nIndex);
451 2108 : if (!aTokenStr.isEmpty())
452 : {
453 : // #94144# allow Minimize again, should be masked out when read from configuration
454 : // 91625 - ignore Minimize
455 2108 : sal_uInt32 nState = (sal_uInt32)aTokenStr.toInt32();
456 : //nState &= ~(WINDOWSTATE_STATE_MINIMIZED);
457 2108 : rData.SetState( nState );
458 2108 : nValidMask |= WINDOWSTATE_MASK_STATE;
459 : }
460 : else
461 0 : rData.SetState( 0 );
462 :
463 : // read maximized pos/size
464 2108 : aTokenStr = rStr.getToken(0, ',', nIndex);
465 2108 : if (!aTokenStr.isEmpty())
466 : {
467 1996 : rData.SetMaximizedX(aTokenStr.toInt32());
468 1996 : if( rData.GetMaximizedX() > -16384 && rData.GetMaximizedX() < 16384 )
469 1996 : nValidMask |= WINDOWSTATE_MASK_MAXIMIZED_X;
470 : else
471 0 : rData.SetMaximizedX( 0 );
472 : }
473 : else
474 112 : rData.SetMaximizedX( 0 );
475 2108 : aTokenStr = rStr.getToken(0, ',', nIndex);
476 2108 : if (!aTokenStr.isEmpty())
477 : {
478 1996 : rData.SetMaximizedY(aTokenStr.toInt32());
479 1996 : if( rData.GetMaximizedY() > -16384 && rData.GetMaximizedY() < 16384 )
480 1996 : nValidMask |= WINDOWSTATE_MASK_MAXIMIZED_Y;
481 : else
482 0 : rData.SetMaximizedY( 0 );
483 : }
484 : else
485 112 : rData.SetMaximizedY( 0 );
486 2108 : aTokenStr = rStr.getToken(0, ',', nIndex);
487 2108 : if (!aTokenStr.isEmpty())
488 : {
489 1996 : rData.SetMaximizedWidth(aTokenStr.toInt32());
490 1996 : if( rData.GetMaximizedWidth() > 0 && rData.GetMaximizedWidth() < 16384 )
491 0 : nValidMask |= WINDOWSTATE_MASK_MAXIMIZED_WIDTH;
492 : else
493 1996 : rData.SetMaximizedWidth( 0 );
494 : }
495 : else
496 112 : rData.SetMaximizedWidth( 0 );
497 2108 : aTokenStr = rStr.getToken(0, ';', nIndex);
498 2108 : if (!aTokenStr.isEmpty())
499 : {
500 1996 : rData.SetMaximizedHeight(aTokenStr.toInt32());
501 1996 : if( rData.GetMaximizedHeight() > 0 && rData.GetMaximizedHeight() < 16384 )
502 0 : nValidMask |= WINDOWSTATE_MASK_MAXIMIZED_HEIGHT;
503 : else
504 1996 : rData.SetMaximizedHeight( 0 );
505 : }
506 : else
507 112 : rData.SetMaximizedHeight( 0 );
508 :
509 : // mark valid fields
510 2108 : rData.SetMask( nValidMask );
511 2108 : }
512 :
513 4106 : static OString ImplWindowStateToStr(const WindowStateData& rData)
514 : {
515 4106 : sal_uLong nValidMask = rData.GetMask();
516 4106 : if ( !nValidMask )
517 0 : return OString();
518 :
519 4106 : OStringBuffer rStrBuf;
520 :
521 4106 : if ( nValidMask & WINDOWSTATE_MASK_X )
522 4106 : rStrBuf.append(static_cast<sal_Int32>(rData.GetX()));
523 4106 : rStrBuf.append(',');
524 4106 : if ( nValidMask & WINDOWSTATE_MASK_Y )
525 4106 : rStrBuf.append(static_cast<sal_Int32>(rData.GetY()));
526 4106 : rStrBuf.append(',');
527 4106 : if ( nValidMask & WINDOWSTATE_MASK_WIDTH )
528 4061 : rStrBuf.append(static_cast<sal_Int32>(rData.GetWidth()));
529 4106 : rStrBuf.append(',');
530 4106 : if ( nValidMask & WINDOWSTATE_MASK_HEIGHT )
531 4061 : rStrBuf.append(static_cast<sal_Int32>(rData.GetHeight()));
532 4106 : rStrBuf.append( ';' );
533 4106 : if ( nValidMask & WINDOWSTATE_MASK_STATE )
534 : {
535 : // #94144# allow Minimize again, should be masked out when read from configuration
536 : // 91625 - ignore Minimize
537 4106 : sal_uInt32 nState = rData.GetState();
538 4106 : rStrBuf.append(static_cast<sal_Int32>(nState));
539 : }
540 4106 : rStrBuf.append(';');
541 4106 : if ( nValidMask & WINDOWSTATE_MASK_MAXIMIZED_X )
542 4061 : rStrBuf.append(static_cast<sal_Int32>(rData.GetMaximizedX()));
543 4106 : rStrBuf.append(',');
544 4106 : if ( nValidMask & WINDOWSTATE_MASK_MAXIMIZED_Y )
545 4061 : rStrBuf.append(static_cast<sal_Int32>(rData.GetMaximizedY()));
546 4106 : rStrBuf.append( ',' );
547 4106 : if ( nValidMask & WINDOWSTATE_MASK_MAXIMIZED_WIDTH )
548 4061 : rStrBuf.append(static_cast<sal_Int32>(rData.GetMaximizedWidth()));
549 4106 : rStrBuf.append(',');
550 4106 : if ( nValidMask & WINDOWSTATE_MASK_MAXIMIZED_HEIGHT )
551 4061 : rStrBuf.append(static_cast<sal_Int32>(rData.GetMaximizedHeight()));
552 4106 : rStrBuf.append(';');
553 :
554 4106 : return rStrBuf.makeStringAndClear();
555 : }
556 :
557 4216 : void SystemWindow::ImplMoveToScreen( long& io_rX, long& io_rY, long i_nWidth, long i_nHeight, Window* i_pConfigureWin )
558 : {
559 4216 : Rectangle aScreenRect;
560 4216 : if( !Application::IsUnifiedDisplay() )
561 0 : aScreenRect = Application::GetScreenPosSizePixel( GetScreenNumber() );
562 : else
563 : {
564 4216 : aScreenRect = Application::GetScreenPosSizePixel( 0 );
565 4216 : for( unsigned int i = 1; i < Application::GetScreenCount(); i++ )
566 0 : aScreenRect.Union( Application::GetScreenPosSizePixel( i ) );
567 : }
568 : // unfortunately most of the time width and height are not really known
569 4216 : if( i_nWidth < 1 )
570 2220 : i_nWidth = 50;
571 4216 : if( i_nHeight < 1 )
572 2220 : i_nHeight = 50;
573 :
574 : // check left border
575 4216 : bool bMove = false;
576 4216 : if( io_rX + i_nWidth < aScreenRect.Left() )
577 : {
578 0 : bMove = true;
579 0 : io_rX = aScreenRect.Left();
580 : }
581 : // check right border
582 4216 : if( io_rX > aScreenRect.Right() - i_nWidth )
583 : {
584 0 : bMove = true;
585 0 : io_rX = aScreenRect.Right() - i_nWidth;
586 : }
587 : // check top border
588 4216 : if( io_rY + i_nHeight < aScreenRect.Top() )
589 : {
590 0 : bMove = true;
591 0 : io_rY = aScreenRect.Top();
592 : }
593 : // check bottom border
594 4216 : if( io_rY > aScreenRect.Bottom() - i_nHeight )
595 : {
596 0 : bMove = true;
597 0 : io_rY = aScreenRect.Bottom() - i_nHeight;
598 : }
599 4216 : Window* pParent = i_pConfigureWin->GetParent();
600 4216 : if( bMove && pParent )
601 : {
602 : // calculate absolute screen pos here, since that is what is contained in WindowState
603 0 : Point aParentAbsPos( pParent->OutputToAbsoluteScreenPixel( Point(0,0) ) );
604 0 : Size aParentSizePixel( pParent->GetOutputSizePixel() );
605 0 : Point aPos( (aParentSizePixel.Width() - i_nWidth) / 2,
606 0 : (aParentSizePixel.Height() - i_nHeight) / 2 );
607 0 : io_rX = aParentAbsPos.X() + aPos.X();
608 0 : io_rY = aParentAbsPos.Y() + aPos.Y();
609 : }
610 4216 : }
611 :
612 2108 : void SystemWindow::SetWindowStateData( const WindowStateData& rData )
613 : {
614 2108 : sal_uLong nValidMask = rData.GetMask();
615 2108 : if ( !nValidMask )
616 0 : return;
617 :
618 2108 : if ( mbSysChild )
619 0 : return;
620 :
621 2108 : Window* pWindow = this;
622 6294 : while ( pWindow->mpWindowImpl->mpBorderWindow )
623 2078 : pWindow = pWindow->mpWindowImpl->mpBorderWindow;
624 :
625 2108 : if ( pWindow->mpWindowImpl->mbFrame )
626 : {
627 2108 : sal_uLong nState = rData.GetState();
628 : SalFrameState aState;
629 2108 : aState.mnMask = rData.GetMask();
630 2108 : aState.mnX = rData.GetX();
631 2108 : aState.mnY = rData.GetY();
632 2108 : aState.mnWidth = rData.GetWidth();
633 2108 : aState.mnHeight = rData.GetHeight();
634 :
635 2108 : if( rData.GetMask() & (WINDOWSTATE_MASK_WIDTH|WINDOWSTATE_MASK_HEIGHT) )
636 : {
637 : // #i43799# adjust window state sizes if a minimial output size was set
638 : // otherwise the frame and the client might get different sizes
639 1996 : if( maMinOutSize.Width() > aState.mnWidth )
640 0 : aState.mnWidth = maMinOutSize.Width();
641 1996 : if( maMinOutSize.Height() > aState.mnHeight )
642 0 : aState.mnHeight = maMinOutSize.Height();
643 : }
644 :
645 2108 : aState.mnMaximizedX = rData.GetMaximizedX();
646 2108 : aState.mnMaximizedY = rData.GetMaximizedY();
647 2108 : aState.mnMaximizedWidth = rData.GetMaximizedWidth();
648 2108 : aState.mnMaximizedHeight = rData.GetMaximizedHeight();
649 : // #94144# allow Minimize again, should be masked out when read from configuration
650 : // 91625 - ignore Minimize
651 : //nState &= ~(WINDOWSTATE_STATE_MINIMIZED);
652 2108 : aState.mnState = nState & WINDOWSTATE_STATE_SYSTEMMASK;
653 :
654 : // normalize window positions onto screen
655 2108 : ImplMoveToScreen( aState.mnX, aState.mnY, aState.mnWidth, aState.mnHeight, pWindow );
656 2108 : ImplMoveToScreen( aState.mnMaximizedX, aState.mnMaximizedY, aState.mnMaximizedWidth, aState.mnMaximizedHeight, pWindow );
657 :
658 : // #96568# avoid having multiple frames at the same screen location
659 : // do the check only if not maximized
660 2108 : if( !((rData.GetMask() & WINDOWSTATE_MASK_STATE) && (nState & WINDOWSTATE_STATE_MAXIMIZED)) )
661 2026 : if( rData.GetMask() & (WINDOWSTATE_MASK_POS|WINDOWSTATE_MASK_WIDTH|WINDOWSTATE_MASK_HEIGHT) )
662 : {
663 2026 : Rectangle aDesktop = GetDesktopRectPixel();
664 2026 : ImplSVData *pSVData = ImplGetSVData();
665 2026 : Window *pWin = pSVData->maWinData.mpFirstFrame;
666 2026 : bool bWrapped = false;
667 8770 : while( pWin )
668 : {
669 14786 : if( !pWin->ImplIsRealParentPath( this ) && ( pWin != this ) &&
670 10038 : pWin->ImplGetWindow()->IsTopWindow() && pWin->mpWindowImpl->mbReallyVisible )
671 : {
672 196 : SalFrameGeometry g = pWin->mpWindowImpl->mpFrame->GetGeometry();
673 196 : if( std::abs(g.nX-aState.mnX) < 2 && std::abs(g.nY-aState.mnY) < 5 )
674 : {
675 52 : long displacement = g.nTopDecoration ? g.nTopDecoration : 20;
676 104 : if( (unsigned long) (aState.mnX + displacement + aState.mnWidth + g.nRightDecoration) > (unsigned long) aDesktop.Right() ||
677 52 : (unsigned long) (aState.mnY + displacement + aState.mnHeight + g.nBottomDecoration) > (unsigned long) aDesktop.Bottom() )
678 : {
679 : // displacing would leave screen
680 0 : aState.mnX = g.nLeftDecoration ? g.nLeftDecoration : 10; // should result in (0,0)
681 0 : aState.mnY = displacement;
682 0 : if( bWrapped ||
683 0 : (unsigned long) (aState.mnX + displacement + aState.mnWidth + g.nRightDecoration) > (unsigned long) aDesktop.Right() ||
684 0 : (unsigned long) (aState.mnY + displacement + aState.mnHeight + g.nBottomDecoration) > (unsigned long) aDesktop.Bottom() )
685 0 : break; // further displacement not possible -> break
686 : // avoid endless testing
687 0 : bWrapped = true;
688 : }
689 : else
690 : {
691 : // displace
692 52 : aState.mnX += displacement;
693 52 : aState.mnY += displacement;
694 : }
695 52 : pWin = pSVData->maWinData.mpFirstFrame; // check new pos again
696 : }
697 : }
698 4718 : pWin = pWin->mpWindowImpl->mpFrameData->mpNextFrame;
699 : }
700 : }
701 :
702 2108 : mpWindowImpl->mpFrame->SetWindowState( &aState );
703 :
704 : // do a synchronous resize for layout reasons
705 : // but use rData only when the window is not to be maximized (#i38089#)
706 : // otherwise we have no useful size information
707 2108 : if( (rData.GetMask() & WINDOWSTATE_MASK_STATE) && (nState & WINDOWSTATE_STATE_MAXIMIZED) )
708 : {
709 : // query maximized size from frame
710 82 : SalFrameGeometry aGeometry = mpWindowImpl->mpFrame->GetGeometry();
711 :
712 : // but use it only if it is different from the restore size (rData)
713 : // as currently only on windows the exact size of a maximized window
714 : // can be computed without actually showing the window
715 82 : if( aGeometry.nWidth != rData.GetWidth() || aGeometry.nHeight != rData.GetHeight() )
716 82 : ImplHandleResize( pWindow, aGeometry.nWidth, aGeometry.nHeight );
717 : }
718 : else
719 2026 : if( rData.GetMask() & (WINDOWSTATE_MASK_WIDTH|WINDOWSTATE_MASK_HEIGHT) )
720 1996 : ImplHandleResize( pWindow, aState.mnWidth, aState.mnHeight ); // #i43799# use aState and not rData, see above
721 : }
722 : else
723 : {
724 0 : sal_uInt16 nPosSize = 0;
725 0 : if ( nValidMask & WINDOWSTATE_MASK_X )
726 0 : nPosSize |= WINDOW_POSSIZE_X;
727 0 : if ( nValidMask & WINDOWSTATE_MASK_Y )
728 0 : nPosSize |= WINDOW_POSSIZE_Y;
729 0 : if ( nValidMask & WINDOWSTATE_MASK_WIDTH )
730 0 : nPosSize |= WINDOW_POSSIZE_WIDTH;
731 0 : if ( nValidMask & WINDOWSTATE_MASK_HEIGHT )
732 0 : nPosSize |= WINDOW_POSSIZE_HEIGHT;
733 :
734 0 : if( IsRollUp() )
735 0 : RollDown();
736 :
737 0 : long nX = rData.GetX();
738 0 : long nY = rData.GetY();
739 0 : long nWidth = rData.GetWidth();
740 0 : long nHeight = rData.GetHeight();
741 0 : const SalFrameGeometry& rGeom = pWindow->mpWindowImpl->mpFrame->GetGeometry();
742 0 : if( nX < 0 )
743 0 : nX = 0;
744 0 : if( nX + nWidth > (long) rGeom.nWidth )
745 0 : nX = rGeom.nWidth - nWidth;
746 0 : if( nY < 0 )
747 0 : nY = 0;
748 0 : if( nY + nHeight > (long) rGeom.nHeight )
749 0 : nY = rGeom.nHeight - nHeight;
750 0 : setPosSizePixel( nX, nY, nWidth, nHeight, nPosSize );
751 0 : maOrgSize = Size( nWidth, nHeight );
752 :
753 : // 91625 - ignore Minimize
754 0 : if ( nValidMask & WINDOWSTATE_MASK_STATE )
755 : {
756 0 : sal_uLong nState = rData.GetState();
757 0 : if ( nState & WINDOWSTATE_STATE_ROLLUP )
758 0 : RollUp();
759 : else
760 0 : RollDown();
761 : }
762 : }
763 : }
764 :
765 4106 : void SystemWindow::GetWindowStateData( WindowStateData& rData ) const
766 : {
767 4106 : sal_uLong nValidMask = rData.GetMask();
768 4106 : if ( !nValidMask )
769 0 : return;
770 :
771 4106 : if ( mbSysChild )
772 0 : return;
773 :
774 4106 : const Window* pWindow = this;
775 12273 : while ( pWindow->mpWindowImpl->mpBorderWindow )
776 4061 : pWindow = pWindow->mpWindowImpl->mpBorderWindow;
777 :
778 4106 : if ( pWindow->mpWindowImpl->mbFrame )
779 : {
780 : SalFrameState aState;
781 4106 : aState.mnMask = 0xFFFFFFFF;
782 4106 : if ( mpWindowImpl->mpFrame->GetWindowState( &aState ) )
783 : {
784 4106 : if ( nValidMask & WINDOWSTATE_MASK_X )
785 4106 : rData.SetX( aState.mnX );
786 4106 : if ( nValidMask & WINDOWSTATE_MASK_Y )
787 4106 : rData.SetY( aState.mnY );
788 4106 : if ( nValidMask & WINDOWSTATE_MASK_WIDTH )
789 4061 : rData.SetWidth( aState.mnWidth );
790 4106 : if ( nValidMask & WINDOWSTATE_MASK_HEIGHT )
791 4061 : rData.SetHeight( aState.mnHeight );
792 4106 : if ( aState.mnMask & WINDOWSTATE_MASK_MAXIMIZED_X )
793 : {
794 0 : rData.SetMaximizedX( aState.mnMaximizedX );
795 0 : nValidMask |= WINDOWSTATE_MASK_MAXIMIZED_X;
796 : }
797 4106 : if ( aState.mnMask & WINDOWSTATE_MASK_MAXIMIZED_Y )
798 : {
799 0 : rData.SetMaximizedY( aState.mnMaximizedY );
800 0 : nValidMask |= WINDOWSTATE_MASK_MAXIMIZED_Y;
801 : }
802 4106 : if ( aState.mnMask & WINDOWSTATE_MASK_MAXIMIZED_WIDTH )
803 : {
804 0 : rData.SetMaximizedWidth( aState.mnMaximizedWidth );
805 0 : nValidMask |= WINDOWSTATE_MASK_MAXIMIZED_WIDTH;
806 : }
807 4106 : if ( aState.mnMask & WINDOWSTATE_MASK_MAXIMIZED_HEIGHT )
808 : {
809 0 : rData.SetMaximizedHeight( aState.mnMaximizedHeight );
810 0 : nValidMask |= WINDOWSTATE_MASK_MAXIMIZED_HEIGHT;
811 : }
812 4106 : if ( nValidMask & WINDOWSTATE_MASK_STATE )
813 : {
814 : // #94144# allow Minimize again, should be masked out when read from configuration
815 : // 91625 - ignore Minimize
816 4106 : if ( !(nValidMask&WINDOWSTATE_MASK_MINIMIZED) )
817 2094 : aState.mnState &= ~(WINDOWSTATE_STATE_MINIMIZED);
818 4106 : rData.SetState( aState.mnState );
819 : }
820 4106 : rData.SetMask( nValidMask );
821 : }
822 : else
823 0 : rData.SetMask( 0 );
824 : }
825 : else
826 : {
827 0 : Point aPos = GetPosPixel();
828 0 : Size aSize = GetSizePixel();
829 0 : sal_uLong nState = 0;
830 :
831 0 : if ( IsRollUp() )
832 : {
833 0 : aSize.Height() += maOrgSize.Height();
834 0 : nState |= WINDOWSTATE_STATE_ROLLUP;
835 : }
836 :
837 0 : if ( nValidMask & WINDOWSTATE_MASK_X )
838 0 : rData.SetX( aPos.X() );
839 0 : if ( nValidMask & WINDOWSTATE_MASK_Y )
840 0 : rData.SetY( aPos.Y() );
841 0 : if ( nValidMask & WINDOWSTATE_MASK_WIDTH )
842 0 : rData.SetWidth( aSize.Width() );
843 0 : if ( nValidMask & WINDOWSTATE_MASK_HEIGHT )
844 0 : rData.SetHeight( aSize.Height() );
845 0 : if ( nValidMask & WINDOWSTATE_MASK_STATE )
846 0 : rData.SetState( nState );
847 : }
848 : }
849 :
850 2108 : void SystemWindow::SetWindowState(const OString& rStr)
851 : {
852 2108 : if (rStr.isEmpty())
853 2108 : return;
854 :
855 2108 : WindowStateData aData;
856 2108 : ImplWindowStateFromStr( aData, rStr );
857 2108 : SetWindowStateData( aData );
858 : }
859 :
860 4106 : OString SystemWindow::GetWindowState( sal_uLong nMask ) const
861 : {
862 4106 : WindowStateData aData;
863 4106 : aData.SetMask( nMask );
864 4106 : GetWindowStateData( aData );
865 :
866 4106 : return ImplWindowStateToStr(aData);
867 : }
868 :
869 6935 : void SystemWindow::SetMenuBar( MenuBar* pMenuBar )
870 : {
871 6935 : if ( mpMenuBar != pMenuBar )
872 : {
873 4077 : MenuBar* pOldMenuBar = mpMenuBar;
874 4077 : Window* pOldWindow = NULL;
875 4077 : Window* pNewWindow=NULL;
876 4077 : mpMenuBar = pMenuBar;
877 :
878 4077 : if ( mpWindowImpl->mpBorderWindow && (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) )
879 : {
880 4077 : if ( pOldMenuBar )
881 2035 : pOldWindow = pOldMenuBar->ImplGetWindow();
882 : else
883 2042 : pOldWindow = NULL;
884 4077 : if ( pOldWindow )
885 : {
886 2035 : ImplCallEventListeners( VCLEVENT_WINDOW_MENUBARREMOVED, (void*) pOldMenuBar );
887 2035 : pOldWindow->SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >() );
888 : }
889 4077 : if ( pMenuBar )
890 : {
891 : DBG_ASSERT( !pMenuBar->pWindow, "SystemWindow::SetMenuBar() - MenuBars can only set in one SystemWindow at time" );
892 2043 : ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetMenuBarWindow( pNewWindow = MenuBar::ImplCreate( mpWindowImpl->mpBorderWindow, pOldWindow, pMenuBar ) );
893 2043 : ImplCallEventListeners( VCLEVENT_WINDOW_MENUBARADDED, (void*) pMenuBar );
894 : }
895 : else
896 2034 : ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetMenuBarWindow( NULL );
897 4077 : ImplToBottomChild();
898 4077 : if ( pOldMenuBar )
899 : {
900 2035 : bool bDelete = (pMenuBar == 0) ? true : false;
901 2035 : if( bDelete && pOldWindow )
902 : {
903 2034 : if( mpImplData->mpTaskPaneList )
904 2034 : mpImplData->mpTaskPaneList->RemoveWindow( pOldWindow );
905 : }
906 2035 : MenuBar::ImplDestroy( pOldMenuBar, bDelete );
907 2035 : if( bDelete )
908 2034 : pOldWindow = NULL; // will be deleted in MenuBar::ImplDestroy,
909 : }
910 :
911 : }
912 : else
913 : {
914 0 : if( pMenuBar )
915 0 : pNewWindow = pMenuBar->ImplGetWindow();
916 0 : if( pOldMenuBar )
917 0 : pOldWindow = pOldMenuBar->ImplGetWindow();
918 : }
919 :
920 : // update taskpane list to make menubar accessible
921 4077 : if( mpImplData->mpTaskPaneList )
922 : {
923 4002 : if( pOldWindow )
924 1 : mpImplData->mpTaskPaneList->RemoveWindow( pOldWindow );
925 4002 : if( pNewWindow )
926 1968 : mpImplData->mpTaskPaneList->AddWindow( pNewWindow );
927 : }
928 : }
929 6935 : }
930 :
931 0 : void SystemWindow::SetMenuBarMode( sal_uInt16 nMode )
932 : {
933 0 : if ( mnMenuBarMode != nMode )
934 : {
935 0 : mnMenuBarMode = nMode;
936 0 : if ( mpWindowImpl->mpBorderWindow && (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) )
937 : {
938 0 : if ( nMode == MENUBAR_MODE_HIDE )
939 0 : ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetMenuBarMode( true );
940 : else
941 0 : ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetMenuBarMode( false );
942 : }
943 : }
944 0 : }
945 :
946 14280 : bool SystemWindow::ImplIsInTaskPaneList( Window* pWin )
947 : {
948 14280 : if( mpImplData && mpImplData->mpTaskPaneList )
949 9616 : return mpImplData->mpTaskPaneList->IsInList( pWin );
950 4664 : return false;
951 : }
952 :
953 0 : unsigned int SystemWindow::GetScreenNumber() const
954 : {
955 0 : return mpWindowImpl->mpFrame->maGeometry.nDisplayScreenNumber;
956 : }
957 :
958 0 : void SystemWindow::SetScreenNumber(unsigned int nDisplayScreen)
959 : {
960 0 : mpWindowImpl->mpFrame->SetScreenNumber( nDisplayScreen );
961 0 : }
962 :
963 6236 : void SystemWindow::SetApplicationID(const OUString &rApplicationID)
964 : {
965 6236 : mpWindowImpl->mpFrame->SetApplicationID( rApplicationID );
966 6236 : }
967 :
968 16 : void SystemWindow::SetCloseHdl(const Link& rLink)
969 : {
970 16 : mpImplData->maCloseHdl = rLink;
971 16 : }
972 :
973 2 : const Link& SystemWindow::GetCloseHdl() const
974 : {
975 2 : return mpImplData->maCloseHdl;
976 : }
977 :
978 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|