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