LCOV - code coverage report
Current view: top level - vcl/source/window - dockmgr.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 88 703 12.5 %
Date: 2015-06-13 12:38:46 Functions: 20 82 24.4 %
Legend: Lines: hit not hit

          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 <tools/time.hxx>
      21             : #include <tools/rc.h>
      22             : 
      23             : #include <brdwin.hxx>
      24             : #include <svdata.hxx>
      25             : #include <salframe.hxx>
      26             : #include <window.h>
      27             : 
      28             : #include <vcl/event.hxx>
      29             : #include <vcl/floatwin.hxx>
      30             : #include <vcl/dockwin.hxx>
      31             : #include <vcl/toolbox.hxx>
      32             : #include <vcl/svapp.hxx>
      33             : #include <vcl/timer.hxx>
      34             : #include <vcl/idle.hxx>
      35             : #include <vcl/lineinfo.hxx>
      36             : #include <vcl/unowrap.hxx>
      37             : #include <vcl/settings.hxx>
      38             : 
      39             : #define DOCKWIN_FLOATSTYLES         (WB_SIZEABLE | WB_MOVEABLE | WB_CLOSEABLE | WB_STANDALONE | WB_PINABLE | WB_ROLLABLE )
      40             : 
      41             : class ImplDockFloatWin2 : public FloatingWindow
      42             : {
      43             : private:
      44             :     ImplDockingWindowWrapper*  mpDockWin;
      45             :     sal_uInt64      mnLastTicks;
      46             :     Idle            maDockIdle;
      47             :     Idle            maEndDockIdle;
      48             :     Point           maDockPos;
      49             :     Rectangle       maDockRect;
      50             :     bool            mbInMove;
      51             :     ImplSVEvent *   mnLastUserEvent;
      52             : 
      53             :     DECL_LINK(DockingHdl, void *);
      54             :     DECL_LINK_TYPED(DockTimerHdl, Idle *, void);
      55             :     DECL_LINK_TYPED(EndDockTimerHdl, Idle *, void);
      56             : public:
      57             :     ImplDockFloatWin2( vcl::Window* pParent, WinBits nWinBits,
      58             :                       ImplDockingWindowWrapper* pDockingWin );
      59             :     virtual ~ImplDockFloatWin2();
      60             :     virtual void dispose() SAL_OVERRIDE;
      61             : 
      62             :     virtual void    Move() SAL_OVERRIDE;
      63             :     virtual void    Resize() SAL_OVERRIDE;
      64             :     virtual void    TitleButtonClick( TitleButton nButton ) SAL_OVERRIDE;
      65             :     virtual void    Pin() SAL_OVERRIDE;
      66             :     virtual void    Roll() SAL_OVERRIDE;
      67             :     virtual void    PopupModeEnd() SAL_OVERRIDE;
      68             :     virtual void    Resizing( Size& rSize ) SAL_OVERRIDE;
      69             :     virtual bool    Close() SAL_OVERRIDE;
      70             : };
      71             : 
      72           0 : ImplDockFloatWin2::ImplDockFloatWin2( vcl::Window* pParent, WinBits nWinBits,
      73             :                                     ImplDockingWindowWrapper* pDockingWin ) :
      74             :         FloatingWindow( pParent, nWinBits ),
      75             :         mpDockWin( pDockingWin ),
      76           0 :         mnLastTicks( tools::Time::GetSystemTicks() ),
      77             :         mbInMove( false ),
      78           0 :         mnLastUserEvent( 0 )
      79             : {
      80             :     // copy state of DockingWindow
      81           0 :     if ( pDockingWin )
      82             :     {
      83           0 :         SetSettings( pDockingWin->GetWindow()->GetSettings() );
      84           0 :         Enable( pDockingWin->GetWindow()->IsEnabled(), false );
      85           0 :         EnableInput( pDockingWin->GetWindow()->IsInputEnabled(), false );
      86           0 :         AlwaysEnableInput( pDockingWin->GetWindow()->IsAlwaysEnableInput(), false );
      87           0 :         EnableAlwaysOnTop( pDockingWin->GetWindow()->IsAlwaysOnTopEnabled() );
      88           0 :         SetActivateMode( pDockingWin->GetWindow()->GetActivateMode() );
      89             :     }
      90             : 
      91           0 :     SetBackground( GetSettings().GetStyleSettings().GetFaceColor() );
      92             : 
      93           0 :     maDockIdle.SetIdleHdl( LINK( this, ImplDockFloatWin2, DockTimerHdl ) );
      94           0 :     maDockIdle.SetPriority( SchedulerPriority::MEDIUM );
      95           0 :     maEndDockIdle.SetIdleHdl( LINK( this, ImplDockFloatWin2, EndDockTimerHdl ) );
      96           0 :     maEndDockIdle.SetPriority( SchedulerPriority::MEDIUM );
      97           0 : }
      98             : 
      99           0 : ImplDockFloatWin2::~ImplDockFloatWin2()
     100             : {
     101           0 :     disposeOnce();
     102           0 : }
     103             : 
     104           0 : void ImplDockFloatWin2::dispose()
     105             : {
     106           0 :     if( mnLastUserEvent )
     107           0 :         Application::RemoveUserEvent( mnLastUserEvent );
     108           0 :     FloatingWindow::dispose();
     109           0 : }
     110             : 
     111           0 : IMPL_LINK_NOARG_TYPED(ImplDockFloatWin2, DockTimerHdl, Idle *, void)
     112             : {
     113             :     DBG_ASSERT( mpDockWin->IsFloatingMode(), "docktimer called but not floating" );
     114             : 
     115           0 :     maDockIdle.Stop();
     116           0 :     PointerState aState = GetPointerState();
     117             : 
     118           0 :     if( aState.mnState & KEY_MOD1 )
     119             :     {
     120             :         // i43499 CTRL disables docking now
     121           0 :         mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->HideTracking();
     122           0 :         if( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) )
     123           0 :             maDockIdle.Start();
     124             :     }
     125           0 :     else if( ! ( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) )
     126             :     {
     127           0 :         mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->HideTracking();
     128           0 :         mpDockWin->EndDocking( maDockRect, false );
     129             :     }
     130             :     else
     131             :     {
     132           0 :         mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->ShowTracking( maDockRect, SHOWTRACK_BIG | SHOWTRACK_WINDOW );
     133           0 :         maDockIdle.Start();
     134             :     }
     135           0 : }
     136             : 
     137           0 : IMPL_LINK_NOARG_TYPED(ImplDockFloatWin2, EndDockTimerHdl, Idle *, void)
     138             : {
     139             :     DBG_ASSERT( mpDockWin->IsFloatingMode(), "enddocktimer called but not floating" );
     140             : 
     141           0 :     maEndDockIdle.Stop();
     142           0 :     PointerState aState = GetPointerState();
     143           0 :     if( ! ( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) )
     144             :     {
     145           0 :         mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->HideTracking();
     146           0 :         mpDockWin->EndDocking( maDockRect, true );
     147             :     }
     148             :     else
     149             :     {
     150           0 :         maEndDockIdle.Start();
     151             :     }
     152           0 : }
     153             : 
     154           0 : IMPL_LINK_NOARG(ImplDockFloatWin2, DockingHdl)
     155             : {
     156             :     // called during move of a floating window
     157           0 :     mnLastUserEvent = 0;
     158             : 
     159           0 :     vcl::Window *pDockingArea = mpDockWin->GetWindow()->GetParent();
     160           0 :     PointerState aState = pDockingArea->GetPointerState();
     161             : 
     162           0 :     bool bRealMove = true;
     163           0 :     if( GetStyle() & WB_OWNERDRAWDECORATION )
     164             :     {
     165             :         // for windows with ownerdraw decoration
     166             :         // we allow docking only when the window was moved
     167             :         // by dragging its caption
     168             :         // and ignore move request due to resizing
     169           0 :         vcl::Window *pBorder = GetWindow( GetWindowType::Border );
     170           0 :         if( pBorder != this )
     171             :         {
     172           0 :             Point aPt;
     173           0 :             Rectangle aBorderRect( aPt, pBorder->GetSizePixel() );
     174             :             sal_Int32 nLeft, nTop, nRight, nBottom;
     175           0 :             GetBorder( nLeft, nTop, nRight, nBottom );
     176             :             // limit borderrect to the caption part only and without the resizing borders
     177           0 :             aBorderRect.Bottom() = aBorderRect.Top() + nTop;
     178           0 :             aBorderRect.Left() += nLeft;
     179           0 :             aBorderRect.Right() -= nRight;
     180             : 
     181           0 :             PointerState aBorderState = pBorder->GetPointerState();
     182           0 :             if( aBorderRect.IsInside( aBorderState.maPos ) )
     183           0 :                 bRealMove = true;
     184             :             else
     185           0 :                 bRealMove = false;
     186             :         }
     187             :     }
     188             : 
     189           0 :     if( mpDockWin->IsDockable() &&
     190           0 :         mpDockWin->GetWindow()->IsVisible() &&
     191           0 :         (tools::Time::GetSystemTicks() - mnLastTicks > 500) &&
     192           0 :         ( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) &&
     193           0 :         !(aState.mnState & KEY_MOD1) && // i43499 CTRL disables docking now
     194             :         bRealMove )
     195             :     {
     196           0 :         maDockPos = Point( pDockingArea->OutputToScreenPixel( pDockingArea->AbsoluteScreenToOutputPixel( OutputToAbsoluteScreenPixel( Point() ) ) ) );
     197           0 :         maDockRect = Rectangle( maDockPos, mpDockWin->GetSizePixel() );
     198             : 
     199             :         // mouse pos in screen pixels
     200           0 :         Point aMousePos = pDockingArea->OutputToScreenPixel( aState.maPos );
     201             : 
     202           0 :         if( ! mpDockWin->IsDocking() )
     203           0 :             mpDockWin->StartDocking( aMousePos, maDockRect );
     204             : 
     205           0 :         bool bFloatMode = mpDockWin->Docking( aMousePos, maDockRect );
     206             : 
     207           0 :         if( ! bFloatMode )
     208             :         {
     209             :             // indicates that the window could be docked at maDockRect
     210             :             maDockRect.SetPos( mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->ScreenToOutputPixel(
     211           0 :                  maDockRect.TopLeft() ) );
     212           0 :             mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->ShowTracking( maDockRect, SHOWTRACK_BIG | SHOWTRACK_WINDOW );
     213           0 :             maEndDockIdle.Stop();
     214           0 :             DockTimerHdl( nullptr );
     215             :         }
     216             :         else
     217             :         {
     218           0 :             mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->HideTracking();
     219           0 :             maDockIdle.Stop();
     220           0 :             EndDockTimerHdl( nullptr );
     221             :         }
     222             :     }
     223           0 :     mbInMove = false;
     224           0 :     return 0;
     225             : }
     226             : 
     227           0 : void ImplDockFloatWin2::Move()
     228             : {
     229           0 :     if( mbInMove )
     230           0 :         return;
     231             : 
     232           0 :     mbInMove = true;
     233           0 :     FloatingWindow::Move();
     234           0 :     mpDockWin->GetWindow()->Move();
     235             : 
     236             :     /*
     237             :      *  note: the window should only dock if KEY_MOD1 is pressed
     238             :      *  and the user releases all mouse buttons. The real problem here
     239             :      *  is that we don't get mouse events (at least not on X)
     240             :      *  if the mouse is on the decoration. So we have to start an
     241             :      *  awkward timer based process that polls the modifier/buttons
     242             :      *  to see whether they are in the right condition shortly after the
     243             :      *  last Move message.
     244             :      */
     245           0 :     if( ! mnLastUserEvent )
     246           0 :         mnLastUserEvent = Application::PostUserEvent( LINK( this, ImplDockFloatWin2, DockingHdl ), NULL, true );
     247             : }
     248             : 
     249           0 : void ImplDockFloatWin2::Resize()
     250             : {
     251             :     // forwarding of resize only required if we have no borderwindow ( GetWindow() then returns 'this' )
     252           0 :     if( GetWindow( GetWindowType::Border ) == this )
     253             :     {
     254           0 :         FloatingWindow::Resize();
     255           0 :         Size aSize( GetSizePixel() );
     256           0 :         mpDockWin->GetWindow()->ImplPosSizeWindow( 0, 0, aSize.Width(), aSize.Height(), PosSizeFlags::PosSize ); // TODO: is this needed ???
     257             :     }
     258           0 : }
     259             : 
     260           0 : void ImplDockFloatWin2::TitleButtonClick( TitleButton nButton )
     261             : {
     262           0 :     FloatingWindow::TitleButtonClick( nButton );
     263           0 :     mpDockWin->TitleButtonClick( nButton );
     264           0 : }
     265             : 
     266           0 : void ImplDockFloatWin2::Pin()
     267             : {
     268           0 :     FloatingWindow::Pin();
     269           0 : }
     270             : 
     271           0 : void ImplDockFloatWin2::Roll()
     272             : {
     273           0 :     FloatingWindow::Roll();
     274           0 : }
     275             : 
     276           0 : void ImplDockFloatWin2::PopupModeEnd()
     277             : {
     278           0 :     FloatingWindow::PopupModeEnd();
     279           0 : }
     280             : 
     281           0 : void ImplDockFloatWin2::Resizing( Size& rSize )
     282             : {
     283           0 :     FloatingWindow::Resizing( rSize );
     284           0 :     mpDockWin->Resizing( rSize );
     285           0 : }
     286             : 
     287           0 : bool ImplDockFloatWin2::Close()
     288             : {
     289           0 :     return true;
     290             : }
     291             : 
     292         212 : DockingManager::DockingManager()
     293             : {
     294         212 : }
     295             : 
     296         420 : DockingManager::~DockingManager()
     297             : {
     298         210 :     ::std::vector< ImplDockingWindowWrapper* >::iterator p;
     299         210 :     p = mDockingWindows.begin();
     300         222 :     for(; p != mDockingWindows.end(); ++p )
     301             :     {
     302          12 :         delete (*p);
     303             :     }
     304         210 :     mDockingWindows.clear();
     305         210 : }
     306             : 
     307     3799598 : ImplDockingWindowWrapper* DockingManager::GetDockingWindowWrapper( const vcl::Window *pWindow )
     308             : {
     309     3799598 :     ::std::vector< ImplDockingWindowWrapper* >::iterator p;
     310     3799598 :     p = mDockingWindows.begin();
     311    15673796 :     while( p != mDockingWindows.end() )
     312             :     {
     313     9416542 :         if( (*p)->mpDockingWindow == pWindow )
     314     1341942 :             return (*p);
     315             :         else
     316     8074600 :             ++p;
     317             :     }
     318     2457656 :     return NULL;
     319             : }
     320             : 
     321      489912 : bool DockingManager::IsDockable( const vcl::Window *pWindow )
     322             : {
     323      489912 :     ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
     324             : 
     325             :     /*
     326             :     if( pWindow->HasDockingHandler() )
     327             :         return true;
     328             :     */
     329      489912 :     return (pWrapper != NULL);
     330             : }
     331             : 
     332       17721 : bool DockingManager::IsFloating( const vcl::Window *pWindow )
     333             : {
     334       17721 :     ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
     335       17721 :     if( pWrapper )
     336       17721 :         return pWrapper->IsFloatingMode();
     337             :     else
     338           0 :         return false;
     339             : }
     340             : 
     341           0 : bool DockingManager::IsLocked( const vcl::Window *pWindow )
     342             : {
     343           0 :     ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
     344           0 :     if( pWrapper && pWrapper->IsLocked() )
     345           0 :         return true;
     346             :     else
     347           0 :         return false;
     348             : }
     349             : 
     350           0 : void DockingManager::Lock( const vcl::Window *pWindow )
     351             : {
     352           0 :     ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
     353           0 :     if( pWrapper )
     354           0 :         pWrapper->Lock();
     355           0 : }
     356             : 
     357           0 : void DockingManager::Unlock( const vcl::Window *pWindow )
     358             : {
     359           0 :     ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
     360           0 :     if( pWrapper )
     361           0 :         pWrapper->Unlock();
     362           0 : }
     363             : 
     364        9522 : void DockingManager::SetFloatingMode( const vcl::Window *pWindow, bool bFloating )
     365             : {
     366        9522 :     ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
     367        9522 :     if( pWrapper )
     368        9522 :         pWrapper->SetFloatingMode( bFloating );
     369        9522 : }
     370             : 
     371           0 : void DockingManager::StartPopupMode( ToolBox *pParentToolBox, const vcl::Window *pWindow, FloatWinPopupFlags nFlags )
     372             : {
     373           0 :     ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
     374           0 :     if( pWrapper )
     375           0 :         pWrapper->StartPopupMode( pParentToolBox, nFlags );
     376           0 : }
     377             : 
     378           0 : void DockingManager::StartPopupMode( ToolBox *pParentToolBox, const vcl::Window *pWindow )
     379             : {
     380             :     StartPopupMode( pParentToolBox, pWindow, FloatWinPopupFlags::AllowTearOff         |
     381             :                     FloatWinPopupFlags::NoFocusClose         |
     382           0 :                     FloatWinPopupFlags::AllMouseButtonClose  |
     383           0 :                     FloatWinPopupFlags::NoMouseUpClose );
     384           0 : }
     385             : 
     386           0 : bool DockingManager::IsInPopupMode( const vcl::Window *pWindow )
     387             : {
     388           0 :     ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
     389           0 :     if( pWrapper && pWrapper->IsInPopupMode() )
     390           0 :         return true;
     391             :     else
     392           0 :         return false;
     393             : }
     394             : 
     395           0 : void DockingManager::EndPopupMode( const vcl::Window *pWin )
     396             : {
     397           0 :     ImplDockingWindowWrapper *pWrapper = GetDockingWindowWrapper( pWin );
     398           0 :     if( pWrapper && pWrapper->GetFloatingWindow() && pWrapper->GetFloatingWindow()->IsInPopupMode() )
     399           0 :         pWrapper->GetFloatingWindow()->EndPopupMode();
     400           0 : }
     401             : 
     402       12262 : void DockingManager::AddWindow( const vcl::Window *pWindow )
     403             : {
     404       12262 :     ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
     405       12262 :     if( pWrapper )
     406       12262 :         return;
     407             :     else
     408       12262 :         pWrapper = new ImplDockingWindowWrapper( pWindow );
     409             : 
     410       12262 :     mDockingWindows.push_back( pWrapper );
     411             : }
     412             : 
     413      270153 : void DockingManager::RemoveWindow( const vcl::Window *pWindow )
     414             : {
     415      270153 :     ::std::vector< ImplDockingWindowWrapper* >::iterator p;
     416      270153 :     p = mDockingWindows.begin();
     417     1342995 :     while( p != mDockingWindows.end() )
     418             :     {
     419      814938 :         if( (*p)->mpDockingWindow == pWindow )
     420             :         {
     421       12249 :             delete (*p);
     422       12249 :             mDockingWindows.erase( p );
     423       12249 :             break;
     424             :         }
     425             :         else
     426      802689 :             ++p;
     427             :     }
     428      270153 : }
     429             : 
     430        9522 : void DockingManager::SetPosSizePixel( vcl::Window *pWindow, long nX, long nY,
     431             :                                     long nWidth, long nHeight,
     432             :                                     PosSizeFlags nFlags )
     433             : {
     434        9522 :     ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
     435        9522 :     if( pWrapper )
     436        9522 :         pWrapper->setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
     437        9522 : }
     438             : 
     439       22041 : Rectangle DockingManager::GetPosSizePixel( const vcl::Window *pWindow )
     440             : {
     441       22041 :     Rectangle aRect;
     442       22041 :     ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
     443       22041 :     if( pWrapper )
     444       22041 :         aRect = Rectangle( pWrapper->GetPosPixel(), pWrapper->GetSizePixel() );
     445             : 
     446       22041 :     return aRect;
     447             : }
     448             : 
     449             : // special floating window for popup mode
     450             : // main purpose: provides tear-off area for undocking
     451             : 
     452             : // if TEAROFF_DASHED defined a single dashed line is used
     453             : // otherwise multiple smaller lines will be painted
     454             : //#define TEAROFF_DASHED
     455             : 
     456             : // size of the drag area
     457             : #ifdef TEAROFF_DASHED
     458             : #define POPUP_DRAGBORDER    2
     459             : #define POPUP_DRAGGRIP      5
     460             : #else
     461             : #define POPUP_DRAGBORDER    3
     462             : #define POPUP_DRAGGRIP      5
     463             : #endif
     464             : #define POPUP_DRAGHEIGHT    (POPUP_DRAGGRIP+POPUP_DRAGBORDER+POPUP_DRAGBORDER)
     465             : #define POPUP_DRAGWIDTH     20
     466             : 
     467             : class ImplPopupFloatWin : public FloatingWindow
     468             : {
     469             : private:
     470             :     ImplDockingWindowWrapper*   mpDockingWin;
     471             :     bool                        mbHighlight;
     472             :     bool                        mbMoving;
     473             :     bool                        mbTrackingEnabled;
     474             :     Point                       maDelta;
     475             :     Point                       maTearOffPosition;
     476             :     bool                        mbGripAtBottom;
     477             :     bool                        mbHasGrip;
     478             :     void                        ImplSetBorder();
     479             : 
     480             : public:
     481             :     ImplPopupFloatWin( vcl::Window* pParent, ImplDockingWindowWrapper* pDockingWin, bool bHasGrip );
     482             :     virtual ~ImplPopupFloatWin();
     483             :     virtual void dispose() SAL_OVERRIDE;
     484             : 
     485             :     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible() SAL_OVERRIDE;
     486             :     virtual void        Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect) SAL_OVERRIDE;
     487             :     virtual void        MouseMove( const MouseEvent& rMEvt ) SAL_OVERRIDE;
     488             :     virtual void        MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE;
     489             :     virtual void        MouseButtonUp( const MouseEvent& rMEvt ) SAL_OVERRIDE;
     490             :     virtual void        Tracking( const TrackingEvent& rTEvt ) SAL_OVERRIDE;
     491             :     virtual void        Resize() SAL_OVERRIDE;
     492             :     virtual vcl::Window*     GetPreferredKeyInputWindow() SAL_OVERRIDE;
     493             : 
     494             :     Rectangle           GetDragRect() const;
     495             :     Point               GetToolboxPosition() const;
     496             :     Point               GetTearOffPosition() const;
     497             :     void                DrawGrip(vcl::RenderContext& rRenderContext);
     498             :     void                DrawBorder(vcl::RenderContext& rRenderContext);
     499             : 
     500           0 :     bool                hasGrip() const { return mbHasGrip; }
     501             : };
     502             : 
     503           0 : ImplPopupFloatWin::ImplPopupFloatWin( vcl::Window* pParent, ImplDockingWindowWrapper* pDockingWin, bool bHasGrip ) :
     504           0 :     FloatingWindow( pParent, WB_NOBORDER | WB_SYSTEMWINDOW | WB_NOSHADOW)
     505             : {
     506           0 :     mpWindowImpl->mbToolbarFloatingWindow = true;   // indicate window type, required for accessibility
     507             :                                                     // which should not see this window as a toplevel window
     508           0 :     mpDockingWin = pDockingWin;
     509           0 :     mbHighlight = false;
     510           0 :     mbMoving = false;
     511           0 :     mbTrackingEnabled = false;
     512           0 :     mbGripAtBottom = true;
     513           0 :     mbHasGrip = bHasGrip;
     514             : 
     515           0 :     ImplSetBorder();
     516           0 : }
     517             : 
     518           0 : ImplPopupFloatWin::~ImplPopupFloatWin()
     519             : {
     520           0 :     disposeOnce();
     521           0 : }
     522             : 
     523           0 : void ImplPopupFloatWin::dispose()
     524             : {
     525           0 :     mpDockingWin = NULL;
     526           0 :     FloatingWindow::dispose();
     527           0 : }
     528             : 
     529           0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > ImplPopupFloatWin::CreateAccessible()
     530             : {
     531             :     // switch off direct accessibilty support for this window
     532             : 
     533             :     // this is to avoid appearance of this window as standalone window in the accessibility hierarchy
     534             :     // as this window is only used as a helper for subtoolbars that are not teared-off, the parent toolbar
     535             :     // has to provide accessibility support (as implemented in the toolkit)
     536             :     // so the contained toolbar should appear as child of the correponsing toolbar item of the parent toolbar
     537           0 :     return ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >();
     538             : }
     539             : 
     540           0 : vcl::Window* ImplPopupFloatWin::GetPreferredKeyInputWindow()
     541             : {
     542           0 :     if( mpWindowImpl->mpClientWindow )
     543           0 :         return mpWindowImpl->mpClientWindow;
     544             :     else
     545           0 :         return FloatingWindow::GetPreferredKeyInputWindow();
     546             : }
     547             : 
     548           0 : void ImplPopupFloatWin::ImplSetBorder()
     549             : {
     550             :     // although we have no border in the sense of a borderwindow
     551             :     //  we're using a special border for the grip
     552             :     // by setting those members the method SetOutputSizePixel() can
     553             :     //  be used to set the proper window size
     554           0 :     mpWindowImpl->mnTopBorder     = 1;
     555           0 :     if( hasGrip() )
     556           0 :         mpWindowImpl->mnTopBorder += POPUP_DRAGHEIGHT+2;
     557           0 :     mpWindowImpl->mnBottomBorder  = 1;
     558           0 :     mpWindowImpl->mnLeftBorder    = 1;
     559           0 :     mpWindowImpl->mnRightBorder   = 1;
     560           0 : }
     561             : 
     562           0 : void ImplPopupFloatWin::Resize()
     563             : {
     564             :     // the borderview overwrites the border during resize so restore it
     565           0 :     ImplSetBorder();
     566           0 : }
     567             : 
     568           0 : Rectangle ImplPopupFloatWin::GetDragRect() const
     569             : {
     570           0 :     Rectangle aRect;
     571           0 :     if( hasGrip() )
     572             :     {
     573           0 :         aRect = Rectangle( 1,1, GetOutputSizePixel().Width()-1, 2+POPUP_DRAGHEIGHT );
     574           0 :         if( mbGripAtBottom )
     575             :         {
     576           0 :             int height = GetOutputSizePixel().Height();
     577           0 :             aRect.Top() = height - 3 - POPUP_DRAGHEIGHT;
     578           0 :             aRect.Bottom() = aRect.Top() + 1 + POPUP_DRAGHEIGHT;
     579             :         }
     580             :     }
     581           0 :     return aRect;
     582             : }
     583             : 
     584           0 : Point ImplPopupFloatWin::GetToolboxPosition() const
     585             : {
     586             :     // return inner position where a toolbox could be placed
     587           0 :     Point aPt( 1, 1 + ((mbGripAtBottom || !hasGrip()) ? 0 : GetDragRect().getHeight()) );    // grip + border
     588             : 
     589           0 :     return aPt;
     590             : }
     591             : 
     592           0 : Point ImplPopupFloatWin::GetTearOffPosition() const
     593             : {
     594           0 :     Point aPt( maTearOffPosition );
     595             :     //aPt += GetToolboxPosition();    // remove 'decoration'
     596           0 :     return aPt;
     597             : }
     598             : 
     599           0 : void ImplPopupFloatWin::DrawBorder(vcl::RenderContext& rRenderContext)
     600             : {
     601           0 :     rRenderContext.SetFillColor();
     602           0 :     Point aPt;
     603           0 :     Rectangle aRect( aPt, GetOutputSizePixel() );
     604             : 
     605           0 :     vcl::Region oldClipRgn( GetClipRegion( ) );
     606           0 :     vcl::Region aClipRgn( aRect );
     607           0 :     Rectangle aItemClipRect( ImplGetItemEdgeClipRect() );
     608           0 :     if( !aItemClipRect.IsEmpty() )
     609             :     {
     610           0 :         aItemClipRect.SetPos( AbsoluteScreenToOutputPixel( aItemClipRect.TopLeft() ) );
     611             : 
     612             :         // draw the excluded border part with the background color of a toolbox
     613           0 :         rRenderContext.SetClipRegion( vcl::Region( aItemClipRect ) );
     614           0 :         rRenderContext.SetLineColor( GetSettings().GetStyleSettings().GetFaceColor() );
     615           0 :         rRenderContext.DrawRect( aRect );
     616             : 
     617           0 :         aClipRgn.Exclude( aItemClipRect );
     618           0 :         SetClipRegion( aClipRgn );
     619             :     }
     620           0 :     rRenderContext.SetLineColor( rRenderContext.GetSettings().GetStyleSettings().GetShadowColor() );
     621           0 :     rRenderContext.DrawRect( aRect );
     622           0 :     rRenderContext.SetClipRegion( oldClipRgn );
     623           0 : }
     624             : 
     625           0 : void ImplPopupFloatWin::DrawGrip(vcl::RenderContext& rRenderContext)
     626             : {
     627           0 :     bool bLinecolor     = rRenderContext.IsLineColor();
     628           0 :     Color aLinecolor    = rRenderContext.GetLineColor();
     629           0 :     bool bFillcolor     = rRenderContext.IsFillColor();
     630           0 :     Color aFillcolor    = rRenderContext.GetFillColor();
     631             : 
     632             :     // draw background
     633           0 :     Rectangle aRect(GetDragRect());
     634           0 :     aRect.Top() += POPUP_DRAGBORDER;
     635           0 :     aRect.Bottom() -= POPUP_DRAGBORDER;
     636           0 :     aRect.Left() += 3;
     637           0 :     aRect.Right() -= 3;
     638             : 
     639           0 :     if (mbHighlight)
     640             :     {
     641           0 :         rRenderContext.Erase(aRect);
     642           0 :         vcl::RenderTools::DrawSelectionBackground(rRenderContext, *this, aRect, 2, false, true, false);
     643             :     }
     644             :     else
     645             :     {
     646           0 :         rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetFaceColor());
     647           0 :         rRenderContext.SetLineColor();
     648           0 :         rRenderContext.DrawRect(aRect);
     649             :     }
     650             : 
     651           0 :     if (!ToolBox::AlwaysLocked())  // no grip if toolboxes are locked
     652             :     {
     653             : #ifdef TEAROFF_DASHED
     654             :         // draw single dashed line
     655             :         LineInfo aLineInfo(LINE_DASH);
     656             :         aLineInfo.SetDistance(4);
     657             :         aLineInfo.SetDashLen(12);
     658             :         aLineInfo.SetDashCount(1);
     659             : 
     660             :         aRect.Left() += 2;
     661             :         aRect.Right()-= 2;
     662             : 
     663             :         aRect.Top()   += 2;
     664             :         aRect.Bottom() = aRect.Top();
     665             :         rRenderContext.SetLineColor(rRenderContext.GetSettings().GetStyleSettings().GetDarkShadowColor());
     666             :         rRenderContext.DrawLine(aRect.TopLeft(), aRect.TopRight(), aLineInfo);
     667             : 
     668             :         if (!mbHighlight)
     669             :         {
     670             :             ++aRect.Top();
     671             :             ++aRect.Bottom();
     672             :             rRenderContext.SetLineColor(rRenderContext.GetSettings().GetStyleSettings().GetLightColor());
     673             :             rRenderContext.DrawLine(aRect.TopLeft(), aRect.TopRight(), aLineInfo);
     674             :         }
     675             : 
     676             : #else
     677             :         // draw several grip lines
     678           0 :         rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetShadowColor());
     679           0 :         aRect.Top()++;
     680           0 :         aRect.Bottom() = aRect.Top();
     681             : 
     682           0 :         int width = POPUP_DRAGWIDTH;
     683           0 :         while(width >= aRect.getWidth())
     684             :         {
     685           0 :             width -= 4;
     686             :         }
     687           0 :         if (width <= 0)
     688           0 :             width = aRect.getWidth();
     689             :         //aRect.nLeft = aRect.nLeft + (aRect.getWidth() - width) / 2;
     690           0 :         aRect.Left() = (aRect.Left() + aRect.Right() - width) / 2;
     691           0 :         aRect.Right() = aRect.Left() + width;
     692             : 
     693           0 :         int i = 0;
     694           0 :         while (i < POPUP_DRAGGRIP)
     695             :         {
     696           0 :             rRenderContext.DrawRect(aRect);
     697           0 :             aRect.Top() += 2;
     698           0 :             aRect.Bottom() += 2;
     699           0 :             i += 2;
     700             :         }
     701             : #endif
     702             :     }
     703             : 
     704           0 :     if (bLinecolor)
     705           0 :         rRenderContext.SetLineColor(aLinecolor);
     706             :     else
     707           0 :         rRenderContext.SetLineColor();
     708           0 :     if (bFillcolor)
     709           0 :         rRenderContext.SetFillColor(aFillcolor);
     710             :     else
     711           0 :         rRenderContext.SetFillColor();
     712           0 : }
     713             : 
     714           0 : void ImplPopupFloatWin::Paint(vcl::RenderContext& rRenderContext, const Rectangle&)
     715             : {
     716           0 :     Rectangle aRect(Point(), rRenderContext.GetOutputSizePixel());
     717           0 :     rRenderContext.DrawWallpaper(aRect, Wallpaper(rRenderContext.GetSettings().GetStyleSettings().GetFaceGradientColor()));
     718           0 :     DrawBorder(rRenderContext);
     719           0 :     if (hasGrip())
     720           0 :         DrawGrip(rRenderContext);
     721           0 : }
     722             : 
     723           0 : void ImplPopupFloatWin::MouseMove( const MouseEvent& rMEvt )
     724             : {
     725           0 :     Point aMousePos = rMEvt.GetPosPixel();
     726             : 
     727           0 :     if( !ToolBox::AlwaysLocked() )  // no tear off if locking is enabled
     728             :     {
     729           0 :         if( mbTrackingEnabled && rMEvt.IsLeft() && GetDragRect().IsInside( aMousePos ) )
     730             :         {
     731             :             // start window move
     732           0 :             mbMoving = true;
     733           0 :             StartTracking( StartTrackingFlags::NoKeyCancel );
     734           0 :             return;
     735             :         }
     736           0 :         if( !mbHighlight && GetDragRect().IsInside( aMousePos ) )
     737             :         {
     738           0 :             mbHighlight = true;
     739           0 :             Invalidate();
     740             :         }
     741           0 :         if (mbHighlight && ( rMEvt.IsLeaveWindow() || !GetDragRect().IsInside( aMousePos ) ) )
     742             :         {
     743           0 :             mbHighlight = false;
     744           0 :             Invalidate();
     745             :         }
     746             :     }
     747             : }
     748             : 
     749           0 : void ImplPopupFloatWin::MouseButtonUp( const MouseEvent& rMEvt )
     750             : {
     751           0 :     mbTrackingEnabled = false;
     752           0 :     FloatingWindow::MouseButtonUp( rMEvt );
     753           0 : }
     754             : 
     755           0 : void ImplPopupFloatWin::MouseButtonDown( const MouseEvent& rMEvt )
     756             : {
     757           0 :     Point aMousePos = rMEvt.GetPosPixel();
     758           0 :     if( GetDragRect().IsInside( aMousePos ) )
     759             :     {
     760             :         // get mouse pos at a static window to have a fixed reference point
     761           0 :         PointerState aState = GetParent()->GetPointerState();
     762           0 :         if (HasMirroredGraphics() && IsRTLEnabled())
     763           0 :             ImplMirrorFramePos(aState.maPos);
     764           0 :         maTearOffPosition = GetWindow( GetWindowType::Border )->GetPosPixel();
     765           0 :         maDelta = aState.maPos - maTearOffPosition;
     766           0 :         mbTrackingEnabled = true;
     767             :     }
     768             :     else
     769             :     {
     770           0 :         mbTrackingEnabled = false;
     771             :     }
     772           0 : }
     773             : 
     774           0 : void ImplPopupFloatWin::Tracking( const TrackingEvent& rTEvt )
     775             : {
     776           0 :     if( mbMoving )
     777             :     {
     778           0 :         if ( rTEvt.IsTrackingEnded() )
     779             :         {
     780           0 :             mbMoving = false;
     781           0 :             EndPopupMode( FloatWinPopupEndFlags::TearOff );
     782             :         }
     783           0 :         else if ( !rTEvt.GetMouseEvent().IsSynthetic() )
     784             :         {
     785             :             // move the window according to mouse pos
     786           0 :             PointerState aState = GetParent()->GetPointerState();
     787           0 :             const OutputDevice *pOutDev = GetOutDev();
     788           0 :             if (pOutDev->HasMirroredGraphics() && IsRTLEnabled())
     789           0 :                 ImplMirrorFramePos(aState.maPos);
     790           0 :             maTearOffPosition = aState.maPos - maDelta;
     791           0 :             GetWindow( GetWindowType::Border )->SetPosPixel( maTearOffPosition );
     792             :         }
     793             :     }
     794           0 : }
     795             : 
     796       12262 : ImplDockingWindowWrapper::ImplDockingWindowWrapper( const vcl::Window *pWindow )
     797             :     : mpDockingWindow(const_cast<vcl::Window*>(pWindow))
     798             :     , mpFloatWin(NULL)
     799             :     , mpOldBorderWin(NULL)
     800             :     , mpParent(pWindow->GetParent())
     801             :     , maMaxOutSize( SHRT_MAX, SHRT_MAX )
     802             :     , mnTrackX(0)
     803             :     , mnTrackY(0)
     804             :     , mnTrackWidth(0)
     805             :     , mnTrackHeight(0)
     806             :     , mnDockLeft(0)
     807             :     , mnDockTop(0)
     808             :     , mnDockRight(0)
     809             :     , mnDockBottom(0)
     810       12262 :     , mnFloatBits(WB_BORDER | WB_CLOSEABLE | WB_SIZEABLE | (pWindow->GetStyle() & DOCKWIN_FLOATSTYLES))
     811             :     , mbDockCanceled(false)
     812             :     , mbFloatPrevented(false)
     813             :     , mbDockable(true)
     814             :     , mbDocking(false)
     815             :     , mbDragFull(false)
     816             :     , mbLastFloatMode(false)
     817             :     , mbStartFloat(false)
     818             :     , mbTrackDock(false)
     819             :     , mbPinned(false)
     820             :     , mbRollUp(false)
     821             :     , mbDockBtn(false)
     822             :     , mbHideBtn(false)
     823             :     // must be enabled in Window::Notify to prevent permanent docking during mouse move
     824             :     , mbStartDockingEnabled(false)
     825       24524 :     , mbLocked(false)
     826             : {
     827       12262 :     DockingWindow *pDockWin = dynamic_cast< DockingWindow* > ( mpDockingWindow.get() );
     828       12262 :     if( pDockWin )
     829       12262 :         mnFloatBits = pDockWin->GetFloatStyle();
     830       12262 : }
     831             : 
     832       36783 : ImplDockingWindowWrapper::~ImplDockingWindowWrapper()
     833             : {
     834       12261 :     if ( IsFloatingMode() )
     835             :     {
     836           0 :         GetWindow()->Show( false, ShowFlags::NoFocusChange );
     837           0 :         SetFloatingMode( false );
     838             :     }
     839       24522 : }
     840             : 
     841           0 : bool ImplDockingWindowWrapper::ImplStartDocking( const Point& rPos )
     842             : {
     843           0 :     if ( !mbDockable )
     844           0 :         return false;
     845             : 
     846           0 :     if( !mbStartDockingEnabled )
     847           0 :         return false;
     848             : 
     849           0 :     maMouseOff      = rPos;
     850           0 :     maMouseStart    = maMouseOff;
     851           0 :     mbDocking       = true;
     852           0 :     mbLastFloatMode = IsFloatingMode();
     853           0 :     mbStartFloat    = mbLastFloatMode;
     854             : 
     855             :     // calculate FloatingBorder
     856           0 :     VclPtr<FloatingWindow> pWin;
     857           0 :     if ( mpFloatWin )
     858           0 :         pWin = mpFloatWin;
     859             :     else
     860           0 :         pWin = VclPtr<ImplDockFloatWin2>::Create( mpParent, mnFloatBits, nullptr );
     861           0 :     pWin->GetBorder( mnDockLeft, mnDockTop, mnDockRight, mnDockBottom );
     862           0 :     if ( !mpFloatWin )
     863           0 :         pWin.disposeAndClear();
     864             : 
     865           0 :     Point   aPos    = GetWindow()->ImplOutputToFrame( Point() );
     866           0 :     Size    aSize   = GetWindow()->GetOutputSizePixel();
     867           0 :     mnTrackX        = aPos.X();
     868           0 :     mnTrackY        = aPos.Y();
     869           0 :     mnTrackWidth    = aSize.Width();
     870           0 :     mnTrackHeight   = aSize.Height();
     871             : 
     872           0 :     if ( mbLastFloatMode )
     873             :     {
     874           0 :         maMouseOff.X()  += mnDockLeft;
     875           0 :         maMouseOff.Y()  += mnDockTop;
     876           0 :         mnTrackX        -= mnDockLeft;
     877           0 :         mnTrackY        -= mnDockTop;
     878           0 :         mnTrackWidth    += mnDockLeft+mnDockRight;
     879           0 :         mnTrackHeight   += mnDockTop+mnDockBottom;
     880             :     }
     881             : 
     882           0 :     vcl::Window *pDockingArea = GetWindow()->GetParent();
     883           0 :     vcl::Window::PointerState aState = pDockingArea->GetPointerState();
     884             : 
     885             :     // mouse pos in screen pixels
     886           0 :     Point aMousePos = pDockingArea->OutputToScreenPixel( aState.maPos );
     887           0 :     Point aDockPos = Point( pDockingArea->AbsoluteScreenToOutputPixel( GetWindow()->OutputToAbsoluteScreenPixel( GetWindow()->GetPosPixel() ) ) );
     888           0 :     Rectangle aDockRect( aDockPos, GetWindow()->GetSizePixel() );
     889           0 :     StartDocking( aMousePos, aDockRect );
     890             : 
     891           0 :     GetWindow()->ImplUpdateAll();
     892           0 :     GetWindow()->ImplGetFrameWindow()->ImplUpdateAll();
     893             : 
     894           0 :     GetWindow()->StartTracking( StartTrackingFlags::KeyMod );
     895           0 :     return true;
     896             : }
     897             : 
     898           0 : void ImplDockingWindowWrapper::Tracking( const TrackingEvent& rTEvt )
     899             : {
     900             :     // used during docking of a currently docked window
     901           0 :     if ( mbDocking )
     902             :     {
     903           0 :         if ( rTEvt.IsTrackingEnded() )
     904             :         {
     905           0 :             mbDocking = false;
     906           0 :             GetWindow()->HideTracking();
     907           0 :             if ( rTEvt.IsTrackingCanceled() )
     908             :             {
     909           0 :                 mbDockCanceled = true;
     910           0 :                 EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode );
     911           0 :                 mbDockCanceled = false;
     912             :             }
     913             :             else
     914           0 :                 EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode );
     915             :         }
     916             :         // Docking only upon non-synthetic MouseEvents
     917           0 :         else if ( !rTEvt.GetMouseEvent().IsSynthetic() || rTEvt.GetMouseEvent().IsModifierChanged() )
     918             :         {
     919           0 :             Point   aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
     920           0 :             Point   aFrameMousePos = GetWindow()->ImplOutputToFrame( aMousePos );
     921           0 :             Size    aFrameSize = GetWindow()->ImplGetFrameWindow()->GetOutputSizePixel();
     922           0 :             if ( aFrameMousePos.X() < 0 )
     923           0 :                 aFrameMousePos.X() = 0;
     924           0 :             if ( aFrameMousePos.Y() < 0 )
     925           0 :                 aFrameMousePos.Y() = 0;
     926           0 :             if ( aFrameMousePos.X() > aFrameSize.Width()-1 )
     927           0 :                 aFrameMousePos.X() = aFrameSize.Width()-1;
     928           0 :             if ( aFrameMousePos.Y() > aFrameSize.Height()-1 )
     929           0 :                 aFrameMousePos.Y() = aFrameSize.Height()-1;
     930           0 :             aMousePos = GetWindow()->ImplFrameToOutput( aFrameMousePos );
     931           0 :             aMousePos.X() -= maMouseOff.X();
     932           0 :             aMousePos.Y() -= maMouseOff.Y();
     933           0 :             Point aPos = GetWindow()->ImplOutputToFrame( aMousePos );
     934           0 :             Rectangle aTrackRect( aPos, Size( mnTrackWidth, mnTrackHeight ) );
     935           0 :             Rectangle aCompRect = aTrackRect;
     936           0 :             aPos.X()    += maMouseOff.X();
     937           0 :             aPos.Y()    += maMouseOff.Y();
     938             : 
     939           0 :             bool bFloatMode = Docking( aPos, aTrackRect );
     940             : 
     941           0 :             mbFloatPrevented = false;
     942           0 :             if ( mbLastFloatMode != bFloatMode )
     943             :             {
     944           0 :                 if ( bFloatMode )
     945             :                 {
     946           0 :                     aTrackRect.Left()   -= mnDockLeft;
     947           0 :                     aTrackRect.Top()    -= mnDockTop;
     948           0 :                     aTrackRect.Right()  += mnDockRight;
     949           0 :                     aTrackRect.Bottom() += mnDockBottom;
     950             :                 }
     951             :                 else
     952             :                 {
     953           0 :                     if ( aCompRect == aTrackRect )
     954             :                     {
     955           0 :                         aTrackRect.Left()   += mnDockLeft;
     956           0 :                         aTrackRect.Top()    += mnDockTop;
     957           0 :                         aTrackRect.Right()  -= mnDockRight;
     958           0 :                         aTrackRect.Bottom() -= mnDockBottom;
     959             :                     }
     960             :                 }
     961           0 :                 mbLastFloatMode = bFloatMode;
     962             :             }
     963             : 
     964             :             sal_uInt16 nTrackStyle;
     965           0 :             if ( bFloatMode )
     966           0 :                 nTrackStyle = SHOWTRACK_OBJECT;
     967             :             else
     968           0 :                 nTrackStyle = SHOWTRACK_BIG;
     969           0 :             Rectangle aShowTrackRect = aTrackRect;
     970           0 :             aShowTrackRect.SetPos( GetWindow()->ImplFrameToOutput( aShowTrackRect.TopLeft() ) );
     971             : 
     972           0 :             GetWindow()->ShowTracking( aShowTrackRect, nTrackStyle );
     973             : 
     974             :             // calculate mouse offset again, as the rectangle was changed
     975           0 :             maMouseOff.X()  = aPos.X() - aTrackRect.Left();
     976           0 :             maMouseOff.Y()  = aPos.Y() - aTrackRect.Top();
     977             : 
     978           0 :             mnTrackX        = aTrackRect.Left();
     979           0 :             mnTrackY        = aTrackRect.Top();
     980           0 :             mnTrackWidth    = aTrackRect.GetWidth();
     981           0 :             mnTrackHeight   = aTrackRect.GetHeight();
     982             :         }
     983             :     }
     984           0 : }
     985             : 
     986           0 : void ImplDockingWindowWrapper::StartDocking( const Point& rPoint, Rectangle& rRect )
     987             : {
     988           0 :     DockingData data( rPoint, rRect, IsFloatingMode() );
     989             : 
     990           0 :     GetWindow()->CallEventListeners( VCLEVENT_WINDOW_STARTDOCKING, &data );
     991           0 :     mbDocking = true;
     992           0 : }
     993             : 
     994           0 : bool ImplDockingWindowWrapper::Docking( const Point& rPoint, Rectangle& rRect )
     995             : {
     996           0 :     DockingData data( rPoint, rRect, IsFloatingMode() );
     997             : 
     998           0 :     GetWindow()->CallEventListeners( VCLEVENT_WINDOW_DOCKING, &data );
     999           0 :     rRect = data.maTrackRect;
    1000           0 :     return data.mbFloating;
    1001             : }
    1002             : 
    1003           0 : void ImplDockingWindowWrapper::EndDocking( const Rectangle& rRect, bool bFloatMode )
    1004             : {
    1005           0 :     Rectangle aRect( rRect );
    1006             : 
    1007           0 :     if ( !IsDockingCanceled() )
    1008             :     {
    1009           0 :         bool bShow = false;
    1010           0 :         if ( bFloatMode != IsFloatingMode() )
    1011             :         {
    1012           0 :             GetWindow()->Show( false, ShowFlags::NoFocusChange );
    1013           0 :             SetFloatingMode( bFloatMode );
    1014           0 :             bShow = true;
    1015           0 :             if ( bFloatMode )
    1016             :             {
    1017             :                 // #i44800# always use outputsize - as in all other places
    1018           0 :                 mpFloatWin->SetOutputSizePixel( aRect.GetSize() );
    1019           0 :                 mpFloatWin->SetPosPixel( aRect.TopLeft() );
    1020             :             }
    1021             :         }
    1022           0 :         if ( !bFloatMode )
    1023             :         {
    1024           0 :             Point aPos = aRect.TopLeft();
    1025           0 :             aPos = GetWindow()->GetParent()->ScreenToOutputPixel( aPos );
    1026           0 :             GetWindow()->SetPosSizePixel( aPos, aRect.GetSize() );
    1027             :         }
    1028             : 
    1029           0 :         if ( bShow )
    1030           0 :             GetWindow()->Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate );
    1031             :     }
    1032             : 
    1033           0 :     EndDockingData data( aRect, IsFloatingMode(), IsDockingCanceled() );
    1034           0 :     GetWindow()->CallEventListeners( VCLEVENT_WINDOW_ENDDOCKING, &data );
    1035             : 
    1036           0 :     mbDocking = false;
    1037             : 
    1038             :     // must be enabled in Window::Notify to prevent permanent docking during mouse move
    1039           0 :     mbStartDockingEnabled = false;
    1040           0 : }
    1041             : 
    1042           0 : bool ImplDockingWindowWrapper::PrepareToggleFloatingMode()
    1043             : {
    1044           0 :     bool bFloating = true;
    1045           0 :     GetWindow()->CallEventListeners( VCLEVENT_WINDOW_PREPARETOGGLEFLOATING, &bFloating );
    1046           0 :     return bFloating;
    1047             : }
    1048             : 
    1049           0 : void ImplDockingWindowWrapper::ToggleFloatingMode()
    1050             : {
    1051             :     // notify dockingwindow/toolbox
    1052             :     // note: this must be done *before* notifying the
    1053             :     //       listeners to have the toolbox in the proper state
    1054           0 :     if( GetWindow()->IsDockingWindow() )
    1055           0 :         static_cast<DockingWindow*>(GetWindow())->ToggleFloatingMode();
    1056             : 
    1057             :     // now notify listeners
    1058           0 :     GetWindow()->CallEventListeners( VCLEVENT_WINDOW_TOGGLEFLOATING );
    1059             : 
    1060             :     // must be enabled in Window::Notify to prevent permanent docking during mouse move
    1061           0 :     mbStartDockingEnabled = false;
    1062           0 : }
    1063             : 
    1064           0 : void ImplDockingWindowWrapper::TitleButtonClick( TitleButton nType )
    1065             : {
    1066           0 :     if( nType == TitleButton::Menu )
    1067             :     {
    1068           0 :         ToolBox *pToolBox = dynamic_cast< ToolBox* >( GetWindow() );
    1069           0 :         if( pToolBox )
    1070             :         {
    1071           0 :             pToolBox->ExecuteCustomMenu();
    1072             :         }
    1073             :     }
    1074           0 :     if( nType == TitleButton::Docking )
    1075             :     {
    1076           0 :         SetFloatingMode( !IsFloatingMode() );
    1077             :     }
    1078           0 : }
    1079             : 
    1080           0 : void ImplDockingWindowWrapper::Resizing( Size& rSize )
    1081             : {
    1082             :     // TODO: add virtual Resizing() to class Window, so we can get rid of class DockingWindow
    1083           0 :     DockingWindow *pDockingWindow = dynamic_cast< DockingWindow* >( GetWindow() );
    1084           0 :     if( pDockingWindow )
    1085           0 :         pDockingWindow->Resizing( rSize );
    1086           0 : }
    1087             : 
    1088           0 : void ImplDockingWindowWrapper::ShowTitleButton( TitleButton nButton, bool bVisible )
    1089             : {
    1090           0 :     if ( mpFloatWin )
    1091           0 :         mpFloatWin->ShowTitleButton( nButton, bVisible );
    1092             :     else
    1093             :     {
    1094           0 :         if ( nButton == TitleButton::Docking )
    1095           0 :             mbDockBtn = bVisible;
    1096             :         else // if ( nButton == TitleButton::Hide )
    1097           0 :             mbHideBtn = bVisible;
    1098             :     }
    1099           0 : }
    1100             : 
    1101           0 : void ImplDockingWindowWrapper::StartPopupMode( ToolBox *pParentToolBox, FloatWinPopupFlags nFlags )
    1102             : {
    1103             :     // do nothing if window is floating
    1104           0 :     if( IsFloatingMode() )
    1105           0 :         return;
    1106             : 
    1107           0 :     GetWindow()->Show( false, ShowFlags::NoFocusChange );
    1108             : 
    1109             :     // prepare reparenting
    1110           0 :     vcl::Window* pRealParent = GetWindow()->GetWindow( GetWindowType::Parent );
    1111           0 :     mpOldBorderWin = GetWindow()->GetWindow( GetWindowType::Border );
    1112           0 :     if( mpOldBorderWin.get() == GetWindow() )
    1113           0 :         mpOldBorderWin = NULL;  // no border window found
    1114             : 
    1115             :     // the new parent for popup mode
    1116           0 :     VclPtrInstance<ImplPopupFloatWin> pWin( mpParent, this, bool(nFlags & FloatWinPopupFlags::AllowTearOff) );
    1117             : 
    1118           0 :     pWin->SetPopupModeEndHdl( LINK( this, ImplDockingWindowWrapper, PopupModeEnd ) );
    1119           0 :     pWin->SetText( GetWindow()->GetText() );
    1120             : 
    1121           0 :     pWin->SetOutputSizePixel( GetWindow()->GetSizePixel() );
    1122             : 
    1123           0 :     GetWindow()->mpWindowImpl->mpBorderWindow  = NULL;
    1124           0 :     GetWindow()->mpWindowImpl->mnLeftBorder    = 0;
    1125           0 :     GetWindow()->mpWindowImpl->mnTopBorder     = 0;
    1126           0 :     GetWindow()->mpWindowImpl->mnRightBorder   = 0;
    1127           0 :     GetWindow()->mpWindowImpl->mnBottomBorder  = 0;
    1128             : 
    1129             :     // position toolbox below dragrect
    1130           0 :     GetWindow()->SetPosPixel( pWin->GetToolboxPosition() );
    1131             : 
    1132             :     // reparent borderwindow and window
    1133           0 :     if ( mpOldBorderWin )
    1134           0 :         mpOldBorderWin->SetParent( pWin );
    1135           0 :     GetWindow()->SetParent( pWin );
    1136             : 
    1137             :     // correct border window pointers
    1138           0 :     GetWindow()->mpWindowImpl->mpBorderWindow = pWin;
    1139           0 :     pWin->mpWindowImpl->mpClientWindow = GetWindow();
    1140           0 :     GetWindow()->mpWindowImpl->mpRealParent = pRealParent;
    1141             : 
    1142             :     // set mpFloatWin not until all window positioning is done !!!
    1143             :     // (SetPosPixel etc. check for valid mpFloatWin pointer)
    1144           0 :     mpFloatWin = pWin;
    1145             : 
    1146             :     // if the subtoolbar was opened via keyboard make sure that key events
    1147             :     // will go into subtoolbar
    1148           0 :     if( pParentToolBox->IsKeyEvent() )
    1149           0 :         nFlags |= FloatWinPopupFlags::GrabFocus;
    1150             : 
    1151           0 :     mpFloatWin->StartPopupMode( pParentToolBox, nFlags );
    1152           0 :     GetWindow()->Show();
    1153             : 
    1154           0 :     if( pParentToolBox->IsKeyEvent() )
    1155             :     {
    1156             :         // send HOME key to subtoolbar in order to select first item
    1157           0 :         KeyEvent aEvent( 0, vcl::KeyCode( KEY_HOME ) );
    1158           0 :         mpFloatWin->GetPreferredKeyInputWindow()->KeyInput( aEvent );
    1159           0 :     }
    1160             : }
    1161             : 
    1162           0 : IMPL_LINK_NOARG(ImplDockingWindowWrapper, PopupModeEnd)
    1163             : {
    1164           0 :     GetWindow()->Show( false, ShowFlags::NoFocusChange );
    1165             : 
    1166             :     // set parameter for handler before destroying floating window
    1167           0 :     ImplPopupFloatWin *pPopupFloatWin = static_cast<ImplPopupFloatWin*>(mpFloatWin.get());
    1168           0 :     EndPopupModeData aData( pPopupFloatWin->GetTearOffPosition(), mpFloatWin->IsPopupModeTearOff() );
    1169             : 
    1170             :     // before deleting change parent back, so we can delete the floating window alone
    1171           0 :     vcl::Window* pRealParent = GetWindow()->GetWindow( GetWindowType::Parent );
    1172           0 :     GetWindow()->mpWindowImpl->mpBorderWindow = NULL;
    1173           0 :     if ( mpOldBorderWin )
    1174             :     {
    1175           0 :         GetWindow()->SetParent( mpOldBorderWin );
    1176           0 :         static_cast<ImplBorderWindow*>(mpOldBorderWin.get())->GetBorder(
    1177           0 :             GetWindow()->mpWindowImpl->mnLeftBorder, GetWindow()->mpWindowImpl->mnTopBorder,
    1178           0 :             GetWindow()->mpWindowImpl->mnRightBorder, GetWindow()->mpWindowImpl->mnBottomBorder );
    1179           0 :         mpOldBorderWin->Resize();
    1180             :     }
    1181           0 :     GetWindow()->mpWindowImpl->mpBorderWindow = mpOldBorderWin;
    1182           0 :     GetWindow()->SetParent( pRealParent );
    1183           0 :     GetWindow()->mpWindowImpl->mpRealParent = pRealParent;
    1184             : 
    1185           0 :     mpFloatWin.disposeAndClear();
    1186             : 
    1187             :     // call handler - which will destroy the window and thus the wrapper as well !
    1188           0 :     GetWindow()->CallEventListeners( VCLEVENT_WINDOW_ENDPOPUPMODE, &aData );
    1189             : 
    1190           0 :     return 0;
    1191             : }
    1192             : 
    1193           0 : bool ImplDockingWindowWrapper::IsInPopupMode() const
    1194             : {
    1195           0 :     if( GetFloatingWindow() )
    1196           0 :         return GetFloatingWindow()->IsInPopupMode();
    1197             :     else
    1198           0 :         return false;
    1199             : }
    1200             : 
    1201        9522 : void ImplDockingWindowWrapper::SetFloatingMode( bool bFloatMode )
    1202             : {
    1203             :     // do nothing if window is docked and locked
    1204        9522 :     if( !IsFloatingMode() && IsLocked() )
    1205        9522 :         return;
    1206             : 
    1207        9522 :     if ( IsFloatingMode() != bFloatMode )
    1208             :     {
    1209           0 :         if ( PrepareToggleFloatingMode() )
    1210             :         {
    1211           0 :             bool bVisible = GetWindow()->IsVisible();
    1212             : 
    1213           0 :             if ( bFloatMode )
    1214             :             {
    1215           0 :                 GetWindow()->Show( false, ShowFlags::NoFocusChange );
    1216             : 
    1217           0 :                 maDockPos = GetWindow()->GetPosPixel();
    1218             : 
    1219           0 :                 vcl::Window* pRealParent = GetWindow()->GetWindow( GetWindowType::Parent );
    1220           0 :                 mpOldBorderWin = GetWindow()->GetWindow( GetWindowType::Border );
    1221           0 :                 if( mpOldBorderWin == mpDockingWindow )
    1222           0 :                     mpOldBorderWin = NULL;  // no border window found
    1223             : 
    1224             :                 ImplDockFloatWin2* pWin =
    1225             :                     VclPtr<ImplDockFloatWin2>::Create(
    1226             : 
    1227             :                                          mpParent,
    1228           0 :                                          mnFloatBits & ( WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE ) ?
    1229             :                                           mnFloatBits | WB_SYSTEMWINDOW
    1230           0 :                                           | WB_OWNERDRAWDECORATION
    1231             :                                           : mnFloatBits,
    1232           0 :                                          this );
    1233             : 
    1234           0 :                 GetWindow()->mpWindowImpl->mpBorderWindow  = NULL;
    1235           0 :                 GetWindow()->mpWindowImpl->mnLeftBorder    = 0;
    1236           0 :                 GetWindow()->mpWindowImpl->mnTopBorder     = 0;
    1237           0 :                 GetWindow()->mpWindowImpl->mnRightBorder   = 0;
    1238           0 :                 GetWindow()->mpWindowImpl->mnBottomBorder  = 0;
    1239             : 
    1240             :                 // if the parent gets destroyed, we also have to reset the parent of the BorderWindow
    1241           0 :                 if ( mpOldBorderWin )
    1242           0 :                     mpOldBorderWin->SetParent( pWin );
    1243           0 :                 GetWindow()->SetParent( pWin );
    1244           0 :                 pWin->SetPosPixel( Point() );
    1245             : 
    1246           0 :                 GetWindow()->mpWindowImpl->mpBorderWindow = pWin;
    1247           0 :                 pWin->mpWindowImpl->mpClientWindow = mpDockingWindow;
    1248           0 :                 GetWindow()->mpWindowImpl->mpRealParent = pRealParent;
    1249             : 
    1250           0 :                 pWin->SetText( GetWindow()->GetText() );
    1251           0 :                 pWin->SetOutputSizePixel( GetWindow()->GetSizePixel() );
    1252           0 :                 pWin->SetPosPixel( maFloatPos );
    1253             :                 // pass on DockingData to FloatingWindow
    1254           0 :                 pWin->ShowTitleButton( TitleButton::Docking, mbDockBtn );
    1255           0 :                 pWin->ShowTitleButton( TitleButton::Hide, mbHideBtn );
    1256           0 :                 pWin->SetPin( mbPinned );
    1257           0 :                 if ( mbRollUp )
    1258           0 :                     pWin->RollUp();
    1259             :                 else
    1260           0 :                     pWin->RollDown();
    1261           0 :                 pWin->SetRollUpOutputSizePixel( maRollUpOutSize );
    1262           0 :                 pWin->SetMinOutputSizePixel( maMinOutSize );
    1263           0 :                 pWin->SetMaxOutputSizePixel( maMaxOutSize );
    1264             : 
    1265           0 :                 mpFloatWin      = pWin;
    1266             : 
    1267           0 :                 if ( bVisible )
    1268           0 :                     GetWindow()->Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate );
    1269             : 
    1270           0 :                 ToggleFloatingMode();
    1271             :             }
    1272             :             else
    1273             :             {
    1274           0 :                 GetWindow()->Show( false, ShowFlags::NoFocusChange );
    1275             : 
    1276             :                 // store FloatingData in FloatingWindow
    1277           0 :                 maFloatPos      = mpFloatWin->GetPosPixel();
    1278           0 :                 mbDockBtn       = mpFloatWin->IsTitleButtonVisible( TitleButton::Docking );
    1279           0 :                 mbHideBtn       = mpFloatWin->IsTitleButtonVisible( TitleButton::Hide );
    1280           0 :                 mbPinned         = mpFloatWin->IsPinned();
    1281           0 :                 mbRollUp        = mpFloatWin->IsRollUp();
    1282           0 :                 maRollUpOutSize = mpFloatWin->GetRollUpOutputSizePixel();
    1283           0 :                 maMinOutSize    = mpFloatWin->GetMinOutputSizePixel();
    1284           0 :                 maMaxOutSize    = mpFloatWin->GetMaxOutputSizePixel();
    1285             : 
    1286           0 :                 vcl::Window* pRealParent = GetWindow()->GetWindow( GetWindowType::Parent ); //mpWindowImpl->mpRealParent;
    1287           0 :                 GetWindow()->mpWindowImpl->mpBorderWindow = NULL;
    1288           0 :                 if ( mpOldBorderWin )
    1289             :                 {
    1290           0 :                     GetWindow()->SetParent( mpOldBorderWin );
    1291           0 :                     static_cast<ImplBorderWindow*>(mpOldBorderWin.get())->GetBorder(
    1292           0 :                         GetWindow()->mpWindowImpl->mnLeftBorder, GetWindow()->mpWindowImpl->mnTopBorder,
    1293           0 :                         GetWindow()->mpWindowImpl->mnRightBorder, GetWindow()->mpWindowImpl->mnBottomBorder );
    1294           0 :                     mpOldBorderWin->Resize();
    1295             :                 }
    1296           0 :                 GetWindow()->mpWindowImpl->mpBorderWindow = mpOldBorderWin;
    1297           0 :                 GetWindow()->SetParent( pRealParent );
    1298           0 :                 GetWindow()->mpWindowImpl->mpRealParent = pRealParent;
    1299             : 
    1300           0 :                 mpFloatWin.disposeAndClear();
    1301           0 :                 GetWindow()->SetPosPixel( maDockPos );
    1302             : 
    1303           0 :                 if ( bVisible )
    1304           0 :                     GetWindow()->Show();
    1305             : 
    1306           0 :                 ToggleFloatingMode();
    1307             : 
    1308             :             }
    1309             :         }
    1310             :     }
    1311             : }
    1312             : 
    1313           9 : void ImplDockingWindowWrapper::SetFloatStyle( WinBits nStyle )
    1314             : {
    1315           9 :     mnFloatBits = nStyle;
    1316           9 : }
    1317             : 
    1318             : 
    1319        9522 : void ImplDockingWindowWrapper::setPosSizePixel( long nX, long nY,
    1320             :                                      long nWidth, long nHeight,
    1321             :                                      PosSizeFlags nFlags )
    1322             : {
    1323        9522 :     if ( mpFloatWin )
    1324           0 :         mpFloatWin->setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
    1325             :     else
    1326        9522 :         GetWindow()->setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
    1327        9522 : }
    1328             : 
    1329       22041 : Point ImplDockingWindowWrapper::GetPosPixel() const
    1330             : {
    1331       22041 :     if ( mpFloatWin )
    1332           0 :         return mpFloatWin->GetPosPixel();
    1333             :     else
    1334       22041 :         return mpDockingWindow->GetPosPixel();
    1335             : }
    1336             : 
    1337       22041 : Size ImplDockingWindowWrapper::GetSizePixel() const
    1338             : {
    1339       22041 :     if ( mpFloatWin )
    1340           0 :         return mpFloatWin->GetSizePixel();
    1341             :     else
    1342       22041 :         return mpDockingWindow->GetSizePixel();
    1343             : }
    1344             : 
    1345             : // old inlines from DockingWindow
    1346             : 
    1347           0 : void ImplDockingWindowWrapper::SetMinOutputSizePixel( const Size& rSize )
    1348             : {
    1349           0 :     if ( mpFloatWin )
    1350           0 :         mpFloatWin->SetMinOutputSizePixel( rSize );
    1351           0 :     maMinOutSize = rSize;
    1352           0 : }
    1353             : 
    1354           0 : void ImplDockingWindowWrapper::SetMaxOutputSizePixel( const Size& rSize )
    1355             : {
    1356           0 :     if ( mpFloatWin )
    1357           0 :         mpFloatWin->SetMaxOutputSizePixel( rSize );
    1358           0 :     maMaxOutSize = rSize;
    1359           0 : }
    1360             : 
    1361      809491 : bool ImplDockingWindowWrapper::IsFloatingMode() const
    1362             : {
    1363      809491 :     return (mpFloatWin != nullptr);
    1364             : }
    1365             : 
    1366        6803 : void    ImplDockingWindowWrapper::SetDragArea( const Rectangle& rRect )
    1367             : {
    1368        6803 :     maDragArea = rRect;
    1369        6803 : }
    1370             : 
    1371             : 
    1372           0 : void ImplDockingWindowWrapper::Lock()
    1373             : {
    1374           0 :     mbLocked = true;
    1375             :     // only toolbars support locking
    1376           0 :     ToolBox *pToolBox = dynamic_cast< ToolBox * >( GetWindow() );
    1377           0 :     if( pToolBox )
    1378           0 :         pToolBox->Lock( mbLocked );
    1379           0 : }
    1380             : 
    1381           0 : void ImplDockingWindowWrapper::Unlock()
    1382             : {
    1383           0 :     mbLocked = false;
    1384             :     // only toolbars support locking
    1385           0 :     ToolBox *pToolBox = dynamic_cast< ToolBox * >( GetWindow() );
    1386           0 :     if( pToolBox )
    1387           0 :         pToolBox->Lock( mbLocked );
    1388           0 : }
    1389             : 
    1390             : 
    1391             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11