LCOV - code coverage report
Current view: top level - vcl/source/window - taskpanelist.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 30 137 21.9 %
Date: 2012-08-25 Functions: 5 12 41.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 25 272 9.2 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <tools/rcid.h>
      31                 :            : 
      32                 :            : #include <vcl/dockwin.hxx>
      33                 :            : #include <vcl/taskpanelist.hxx>
      34                 :            : 
      35                 :            : #include <svdata.hxx>
      36                 :            : 
      37                 :            : #include <functional>
      38                 :            : #include <algorithm>
      39                 :            : 
      40                 :            : // can't have static linkage because SUNPRO 5.2 complains
      41                 :          0 : Point ImplTaskPaneListGetPos( const Window *w )
      42                 :            : {
      43                 :          0 :     Point pos;
      44         [ #  # ]:          0 :     if( w->ImplIsDockingWindow() )
      45                 :            :     {
      46                 :          0 :         pos = ((DockingWindow*)w)->GetPosPixel();
      47                 :          0 :         Window *pF = ((DockingWindow*)w)->GetFloatingWindow();
      48         [ #  # ]:          0 :         if( pF )
      49         [ #  # ]:          0 :             pos = pF->OutputToAbsoluteScreenPixel( pF->ScreenToOutputPixel( pos ) );
      50                 :            :         else
      51                 :          0 :             pos = w->OutputToAbsoluteScreenPixel( pos );
      52                 :            :     }
      53                 :            :     else
      54         [ #  # ]:          0 :         pos = w->OutputToAbsoluteScreenPixel( w->GetPosPixel() );
      55                 :            : 
      56                 :          0 :     return pos;
      57                 :            : }
      58                 :            : 
      59                 :            : // compares window pos left-to-right
      60                 :            : struct LTRSort : public ::std::binary_function< const Window*, const Window*, bool >
      61                 :            : {
      62                 :          0 :     bool operator()( const Window* w1, const Window* w2 ) const
      63                 :            :     {
      64         [ #  # ]:          0 :         Point pos1(ImplTaskPaneListGetPos( w1 ));
      65         [ #  # ]:          0 :         Point pos2(ImplTaskPaneListGetPos( w2 ));
      66                 :            : 
      67         [ #  # ]:          0 :         if( pos1.X() == pos2.X() )
      68                 :          0 :             return ( pos1.Y() < pos2.Y() );
      69                 :            :         else
      70                 :          0 :             return ( pos1.X() < pos2.X() );
      71                 :            :     }
      72                 :            : };
      73                 :            : struct LTRSortBackward : public ::std::binary_function< const Window*, const Window*, bool >
      74                 :            : {
      75                 :          0 :     bool operator()( const Window* w2, const Window* w1 ) const
      76                 :            :     {
      77         [ #  # ]:          0 :         Point pos1(ImplTaskPaneListGetPos( w1 ));
      78         [ #  # ]:          0 :         Point pos2(ImplTaskPaneListGetPos( w2 ));
      79                 :            : 
      80         [ #  # ]:          0 :         if( pos1.X() == pos2.X() )
      81                 :          0 :             return ( pos1.Y() < pos2.Y() );
      82                 :            :         else
      83                 :          0 :             return ( pos1.X() < pos2.X() );
      84                 :            :     }
      85                 :            : };
      86                 :            : 
      87                 :            : // --------------------------------------------------
      88                 :            : 
      89                 :          0 : static void ImplTaskPaneListGrabFocus( Window *pWindow )
      90                 :            : {
      91                 :            :     // put focus in child of floating windows which is typically a toolbar
      92                 :            :     // that can deal with the focus
      93 [ #  # ][ #  # ]:          0 :     if( pWindow->ImplIsFloatingWindow() && pWindow->GetWindow( WINDOW_FIRSTCHILD ) )
                 [ #  # ]
      94                 :          0 :         pWindow = pWindow->GetWindow( WINDOW_FIRSTCHILD );
      95                 :          0 :     pWindow->GrabFocus();
      96                 :          0 : }
      97                 :            : 
      98                 :            : // --------------------------------------------------
      99                 :            : 
     100                 :       1723 : TaskPaneList::TaskPaneList()
     101                 :            : {
     102                 :       1723 : }
     103                 :            : 
     104                 :       1632 : TaskPaneList::~TaskPaneList()
     105                 :            : {
     106                 :       1632 : }
     107                 :            : 
     108                 :            : // --------------------------------------------------
     109                 :            : 
     110                 :       6457 : void TaskPaneList::AddWindow( Window *pWindow )
     111                 :            : {
     112         [ +  - ]:       6457 :     if( pWindow )
     113                 :            :     {
     114                 :       6457 :         ::std::vector< Window* >::iterator insertionPos = mTaskPanes.end();
     115   [ +  -  +  - ]:      33072 :         for ( ::std::vector< Window* >::iterator p = mTaskPanes.begin();
                 [ +  + ]
     116                 :      16536 :               p != mTaskPanes.end();
     117                 :            :               ++p
     118                 :            :             )
     119                 :            :         {
     120 [ +  - ][ +  - ]:      10083 :             if ( *p == pWindow )
     121                 :            :                 // avoid duplicates
     122                 :       6457 :                 return;
     123                 :            : 
     124                 :            :             // If the new window is the child of an existing pane window, or vice versa,
     125                 :            :             // ensure that in our pane list, *first* the child window appears, *then*
     126                 :            :             // the ancestor window.
     127                 :            :             // This is necessary for HandleKeyEvent: There, the list is traveled from the
     128                 :            :             // beginning, until the first window is found which has the ChildPathFocus. Now
     129                 :            :             // if this would be the ancestor window of another pane window, this would fudge
     130                 :            :             // the result
     131 [ +  - ][ +  - ]:      10083 :             if ( pWindow->IsWindowOrChild( *p ) )
                 [ -  + ]
     132                 :            :             {
     133         [ #  # ]:          0 :                 insertionPos = p + 1;
     134                 :          0 :                 break;
     135                 :            :             }
     136 [ +  - ][ +  - ]:      10083 :             if ( (*p)->IsWindowOrChild( pWindow ) )
                 [ +  + ]
     137                 :            :             {
     138                 :          4 :                 insertionPos = p;
     139                 :          4 :                 break;
     140                 :            :             }
     141                 :            :         }
     142                 :            : 
     143         [ +  - ]:       6457 :         mTaskPanes.insert( insertionPos, pWindow );
     144         [ +  - ]:       6457 :         pWindow->ImplIsInTaskPaneList( sal_True );
     145                 :            :     }
     146                 :            : }
     147                 :            : 
     148                 :            : // --------------------------------------------------
     149                 :            : 
     150                 :       6172 : void TaskPaneList::RemoveWindow( Window *pWindow )
     151                 :            : {
     152                 :       6172 :     ::std::vector< Window* >::iterator p;
     153         [ +  - ]:       6172 :     p = ::std::find( mTaskPanes.begin(), mTaskPanes.end(), pWindow );
     154 [ +  - ][ +  - ]:       6172 :     if( p != mTaskPanes.end() )
     155                 :            :     {
     156         [ +  - ]:       6172 :         mTaskPanes.erase( p );
     157         [ +  - ]:       6172 :         pWindow->ImplIsInTaskPaneList( sal_False );
     158                 :            :     }
     159                 :       6172 : }
     160                 :            : 
     161                 :            : // --------------------------------------------------
     162                 :            : 
     163                 :      11691 : sal_Bool TaskPaneList::IsInList( Window *pWindow )
     164                 :            : {
     165                 :      11691 :     ::std::vector< Window* >::iterator p;
     166         [ +  - ]:      11691 :     p = ::std::find( mTaskPanes.begin(), mTaskPanes.end(), pWindow );
     167 [ +  - ][ +  + ]:      11691 :     if( p != mTaskPanes.end() )
     168                 :       3701 :         return sal_True;
     169                 :            :     else
     170                 :      11691 :         return sal_False;
     171                 :            : }
     172                 :            : 
     173                 :            : // --------------------------------------------------
     174                 :            : 
     175                 :          0 : sal_Bool TaskPaneList::HandleKeyEvent( KeyEvent aKeyEvent )
     176                 :            : {
     177                 :            : 
     178                 :            :     // F6 cycles through everything and works always
     179                 :            : 
     180                 :            :     // MAV, #i104204#
     181                 :            :     // The old design was the following one:
     182                 :            :     // < Ctrl-TAB cycles through Menubar, Toolbars and Floatingwindows only and is
     183                 :            :     // < only active if one of those items has the focus
     184                 :            :     //
     185                 :            :     // Since the design of Ctrl-Tab looks to be inconsistent ( non-modal dialogs are not reachable
     186                 :            :     // and the shortcut conflicts with tab-control shortcut ), it is no more supported
     187                 :          0 :     sal_Bool bSplitterOnly = sal_False;
     188                 :          0 :     sal_Bool bFocusInList = sal_False;
     189                 :          0 :     KeyCode aKeyCode = aKeyEvent.GetKeyCode();
     190                 :          0 :     sal_Bool bForward = !aKeyCode.IsShift();
     191 [ #  # ][ #  # ]:          0 :     if( aKeyCode.GetCode() == KEY_F6 && ! aKeyCode.IsMod2() ) // F6
                 [ #  # ]
     192                 :            :     {
     193 [ #  # ][ #  # ]:          0 :         bSplitterOnly = aKeyCode.IsMod1() && aKeyCode.IsShift();
     194                 :            : 
     195                 :            :         // is the focus in the list ?
     196                 :          0 :         ::std::vector< Window* >::iterator p = mTaskPanes.begin();
     197 [ #  # ][ #  # ]:          0 :         while( p != mTaskPanes.end() )
     198                 :            :         {
     199         [ #  # ]:          0 :             Window *pWin = *p;
     200 [ #  # ][ #  # ]:          0 :             if( pWin->HasChildPathFocus( sal_True ) )
     201                 :            :             {
     202                 :          0 :                 bFocusInList = sal_True;
     203                 :            : 
     204                 :            :                 // Ctrl-F6 goes directly to the document
     205 [ #  # ][ #  # ]:          0 :                 if( !pWin->IsDialog() && aKeyCode.IsMod1() && !aKeyCode.IsShift() )
         [ #  # ][ #  # ]
                 [ #  # ]
     206                 :            :                 {
     207         [ #  # ]:          0 :                     pWin->GrabFocusToDocument();
     208                 :          0 :                     return sal_True;
     209                 :            :                 }
     210                 :            : 
     211                 :            :                 // activate next task pane
     212                 :          0 :                 Window *pNextWin = NULL;
     213                 :            : 
     214         [ #  # ]:          0 :                 if( bSplitterOnly )
     215 [ #  # ][ #  # ]:          0 :                     pNextWin = FindNextSplitter( *p, sal_True );
     216                 :            :                 else
     217 [ #  # ][ #  # ]:          0 :                     pNextWin = FindNextFloat( *p, bForward );
     218                 :            : 
     219         [ #  # ]:          0 :                 if( pNextWin != pWin )
     220                 :            :                 {
     221         [ #  # ]:          0 :                     ImplGetSVData()->maWinData.mbNoSaveFocus = sal_True;
     222         [ #  # ]:          0 :                     ImplTaskPaneListGrabFocus( pNextWin );
     223         [ #  # ]:          0 :                     ImplGetSVData()->maWinData.mbNoSaveFocus = sal_False;
     224                 :            :                 }
     225                 :            :                 else
     226                 :            :                 {
     227                 :            :                     // forward key if no splitter found
     228         [ #  # ]:          0 :                     if( bSplitterOnly )
     229                 :          0 :                         return sal_False;
     230                 :            : 
     231                 :            :                     // we did not find another taskpane, so
     232                 :            :                     // put focus back into document
     233         [ #  # ]:          0 :                     pWin->GrabFocusToDocument();
     234                 :            :                 }
     235                 :            : 
     236                 :          0 :                 return sal_True;
     237                 :            :             }
     238                 :            :             else
     239         [ #  # ]:          0 :                 ++p;
     240                 :            :         }
     241                 :            : 
     242                 :            :         // the focus is not in the list: activate first float if F6 was pressed
     243         [ #  # ]:          0 :         if( !bFocusInList )
     244                 :            :         {
     245                 :            :             Window *pWin;
     246         [ #  # ]:          0 :             if( bSplitterOnly )
     247         [ #  # ]:          0 :                 pWin = FindNextSplitter( NULL, sal_True );
     248                 :            :             else
     249         [ #  # ]:          0 :                 pWin = FindNextFloat( NULL, bForward );
     250         [ #  # ]:          0 :             if( pWin )
     251                 :            :             {
     252         [ #  # ]:          0 :                 ImplTaskPaneListGrabFocus( pWin );
     253                 :          0 :                 return sal_True;
     254                 :            :             }
     255                 :            :         }
     256                 :            :     }
     257                 :            : 
     258                 :          0 :     return sal_False;
     259                 :            : }
     260                 :            : 
     261                 :            : // --------------------------------------------------
     262                 :            : 
     263                 :            : // returns next splitter
     264                 :          0 : Window* TaskPaneList::FindNextSplitter( Window *pWindow, sal_Bool bForward )
     265                 :            : {
     266         [ #  # ]:          0 :     if( bForward )
     267         [ #  # ]:          0 :         ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSort() );
     268                 :            :     else
     269         [ #  # ]:          0 :         ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSortBackward() );
     270                 :            : 
     271                 :          0 :     ::std::vector< Window* >::iterator p = mTaskPanes.begin();
     272 [ #  # ][ #  # ]:          0 :     while( p != mTaskPanes.end() )
     273                 :            :     {
     274 [ #  # ][ #  # ]:          0 :         if( !pWindow || *p == pWindow )
         [ #  # ][ #  # ]
     275                 :            :         {
     276                 :          0 :             unsigned n = mTaskPanes.size();
     277         [ #  # ]:          0 :             while( --n )
     278                 :            :             {
     279         [ #  # ]:          0 :                 if( pWindow )   // increment before test
     280         [ #  # ]:          0 :                     ++p;
     281 [ #  # ][ #  # ]:          0 :                 if( p == mTaskPanes.end() )
     282                 :          0 :                     p = mTaskPanes.begin();
     283 [ #  # ][ #  # ]:          0 :                 if( (*p)->ImplIsSplitter() && (*p)->IsReallyVisible() && !(*p)->IsDialog() && (*p)->GetParent()->HasChildPathFocus() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     284                 :            :                 {
     285         [ #  # ]:          0 :                     pWindow = *p;
     286                 :          0 :                     break;
     287                 :            :                 }
     288         [ #  # ]:          0 :                 if( !pWindow )  // increment after test, otherwise first element is skipped
     289         [ #  # ]:          0 :                     ++p;
     290                 :            :             }
     291                 :          0 :             break;
     292                 :            :         }
     293                 :            :         else
     294         [ #  # ]:          0 :             ++p;
     295                 :            :     }
     296                 :            : 
     297                 :          0 :     return pWindow;
     298                 :            : }
     299                 :            : 
     300                 :            : // --------------------------------------------------
     301                 :            : 
     302                 :            : // returns first valid item (regardless of type) if pWindow==0, otherwise returns next valid float
     303                 :          0 : Window* TaskPaneList::FindNextFloat( Window *pWindow, sal_Bool bForward )
     304                 :            : {
     305         [ #  # ]:          0 :     if( bForward )
     306         [ #  # ]:          0 :         ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSort() );
     307                 :            :     else
     308         [ #  # ]:          0 :         ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSortBackward() );
     309                 :            : 
     310                 :          0 :     ::std::vector< Window* >::iterator p = mTaskPanes.begin();
     311 [ #  # ][ #  # ]:          0 :     while( p != mTaskPanes.end() )
     312                 :            :     {
     313 [ #  # ][ #  # ]:          0 :         if( !pWindow || *p == pWindow )
         [ #  # ][ #  # ]
     314                 :            :         {
     315 [ #  # ][ #  # ]:          0 :             while( p != mTaskPanes.end() )
     316                 :            :             {
     317         [ #  # ]:          0 :                 if( pWindow )   // increment before test
     318         [ #  # ]:          0 :                     ++p;
     319 [ #  # ][ #  # ]:          0 :                 if( p == mTaskPanes.end() )
     320                 :          0 :                     break; // do not wrap, send focus back to document at end of list
     321                 :            :                 /* #i83908# do not use the menubar if it is native and invisible
     322                 :            :                    this relies on MenuBar::ImplCreate setting the height of the menubar
     323                 :            :                    to 0 in this case
     324                 :            :                 */
     325 [ #  # ][ #  # ]:          0 :                 if( (*p)->IsReallyVisible() && !(*p)->ImplIsSplitter() &&
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  # ]
                 [ #  # ]
     326 [ #  # ][ #  # ]:          0 :                     ( (*p)->GetType() != WINDOW_MENUBARWINDOW || (*p)->GetSizePixel().Height() > 0 )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     327                 :            :                     )
     328                 :            :                 {
     329         [ #  # ]:          0 :                     pWindow = *p;
     330                 :          0 :                     break;
     331                 :            :                 }
     332         [ #  # ]:          0 :                 if( !pWindow )  // increment after test, otherwise first element is skipped
     333         [ #  # ]:          0 :                     ++p;
     334                 :            :             }
     335                 :          0 :             break;
     336                 :            :         }
     337                 :            :         else
     338         [ #  # ]:          0 :             ++p;
     339                 :            :     }
     340                 :            : 
     341                 :          0 :     return pWindow;
     342                 :            : }
     343                 :            : 
     344                 :            : // --------------------------------------------------
     345                 :            : 
     346                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10