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