LCOV - code coverage report
Current view: top level - svx/source/dialog - frmsel.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1 668 0.1 %
Date: 2014-11-03 Functions: 2 97 2.1 %
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 <svx/frmsel.hxx>
      21             : #include <vcl/builder.hxx>
      22             : 
      23             : #include <algorithm>
      24             : #include <math.h>
      25             : #include "frmselimpl.hxx"
      26             : #include "AccessibleFrameSelector.hxx"
      27             : #include <svx/dialmgr.hxx>
      28             : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
      29             : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
      30             : #include <vcl/settings.hxx>
      31             : 
      32             : #include <svx/dialogs.hrc>
      33             : #include "frmsel.hrc"
      34             : 
      35             : #include <tools/rcid.h>
      36             : 
      37             : using namespace ::com::sun::star;
      38             : using namespace ::editeng;
      39             : 
      40             : namespace svx {
      41             : 
      42             : using ::com::sun::star::uno::Reference;
      43             : using ::com::sun::star::uno::Any;
      44             : using ::com::sun::star::accessibility::XAccessible;
      45             : using namespace ::com::sun::star::accessibility;
      46             : 
      47             : // global functions from framebordertype.hxx
      48             : 
      49           0 : FrameBorderType GetFrameBorderTypeFromIndex( size_t nIndex )
      50             : {
      51             :     DBG_ASSERT( nIndex < (size_t)FRAMEBORDERTYPE_COUNT,
      52             :         "svx::GetFrameBorderTypeFromIndex - invalid index" );
      53           0 :     return static_cast< FrameBorderType >( nIndex + 1 );
      54             : }
      55             : 
      56           0 : size_t GetIndexFromFrameBorderType( FrameBorderType eBorder )
      57             : {
      58             :     DBG_ASSERT( eBorder != FRAMEBORDER_NONE,
      59             :         "svx::GetIndexFromFrameBorderType - invalid frame border type" );
      60           0 :     return static_cast< size_t >( eBorder ) - 1;
      61             : }
      62             : 
      63             : 
      64             : 
      65             : namespace {
      66             : 
      67             : /** Space between outer control border and any graphical element of the control. */
      68             : const long FRAMESEL_GEOM_OUTER    = 2;
      69             : 
      70             : /** Space between arrows and usable inner area. */
      71             : const long FRAMESEL_GEOM_INNER    = 3;
      72             : 
      73             : /** Maximum width to draw a frame border style. */
      74             : const long FRAMESEL_GEOM_WIDTH    = 9;
      75             : 
      76             : /** Additional margin for click area of outer lines. */
      77             : const long FRAMESEL_GEOM_ADD_CLICK_OUTER = 5;
      78             : 
      79             : /** Additional margin for click area of inner lines. */
      80             : const long FRAMESEL_GEOM_ADD_CLICK_INNER = 2;
      81             : 
      82             : 
      83             : 
      84             : /** Returns the corresponding flag for a frame border. */
      85           0 : FrameSelFlags lclGetFlagFromType( FrameBorderType eBorder )
      86             : {
      87           0 :     switch( eBorder )
      88             :     {
      89           0 :         case FRAMEBORDER_LEFT:      return FRAMESEL_LEFT;
      90           0 :         case FRAMEBORDER_RIGHT:     return FRAMESEL_RIGHT;
      91           0 :         case FRAMEBORDER_TOP:       return FRAMESEL_TOP;
      92           0 :         case FRAMEBORDER_BOTTOM:    return FRAMESEL_BOTTOM;
      93           0 :         case FRAMEBORDER_HOR:       return FRAMESEL_INNER_HOR;
      94           0 :         case FRAMEBORDER_VER:       return FRAMESEL_INNER_VER;
      95           0 :         case FRAMEBORDER_TLBR:      return FRAMESEL_DIAG_TLBR;
      96           0 :         case FRAMEBORDER_BLTR:      return FRAMESEL_DIAG_BLTR;
      97           0 :         case FRAMEBORDER_NONE : break;
      98             :     }
      99           0 :     return FRAMESEL_NONE;
     100             : }
     101             : 
     102             : /** Merges the rSource polypolygon into the rDest polypolygon. */
     103           0 : inline void lclPolyPolyUnion( tools::PolyPolygon& rDest, const tools::PolyPolygon& rSource )
     104             : {
     105           0 :     const tools::PolyPolygon aTmp( rDest );
     106           0 :     aTmp.GetUnion( rSource, rDest );
     107           0 : }
     108             : 
     109             : } // namespace
     110             : 
     111           0 : FrameBorder::FrameBorder( FrameBorderType eType ) :
     112             :     meType( eType ),
     113             :     meState( FRAMESTATE_HIDE ),
     114             :     meKeyLeft( FRAMEBORDER_NONE ),
     115             :     meKeyRight( FRAMEBORDER_NONE ),
     116             :     meKeyTop( FRAMEBORDER_NONE ),
     117             :     meKeyBottom( FRAMEBORDER_NONE ),
     118             :     mbEnabled( false ),
     119           0 :     mbSelected( false )
     120             : {
     121           0 : }
     122             : 
     123           0 : void FrameBorder::Enable( FrameSelFlags nFlags )
     124             : {
     125           0 :     mbEnabled = (nFlags & lclGetFlagFromType( meType )) != 0;
     126           0 :     if( !mbEnabled )
     127           0 :         SetState( FRAMESTATE_HIDE );
     128           0 : }
     129             : 
     130           0 : void FrameBorder::SetCoreStyle( const SvxBorderLine* pStyle )
     131             : {
     132           0 :     if( pStyle )
     133           0 :         maCoreStyle = *pStyle;
     134             :     else
     135           0 :         maCoreStyle = SvxBorderLine();
     136             : 
     137             :     // from twips to points
     138           0 :     maUIStyle.Set( maCoreStyle, 0.05, FRAMESEL_GEOM_WIDTH );
     139           0 :     meState = maUIStyle.Prim() ? FRAMESTATE_SHOW : FRAMESTATE_HIDE;
     140           0 : }
     141             : 
     142           0 : void FrameBorder::SetState( FrameBorderState eState )
     143             : {
     144           0 :     meState = eState;
     145           0 :     switch( meState )
     146             :     {
     147             :         case FRAMESTATE_SHOW:
     148             :             SAL_WARN( "svx.dialog", "svx::FrameBorder::SetState - use SetCoreStyle to make border visible" );
     149           0 :         break;
     150             :         case FRAMESTATE_HIDE:
     151           0 :             maCoreStyle = SvxBorderLine();
     152           0 :             maUIStyle.Clear();
     153           0 :         break;
     154             :         case FRAMESTATE_DONTCARE:
     155           0 :             maCoreStyle = SvxBorderLine();
     156           0 :             maUIStyle = frame::Style(3, 0, 0, table::BorderLineStyle::SOLID); //OBJ_FRAMESTYLE_DONTCARE
     157           0 :         break;
     158             :     }
     159           0 : }
     160             : 
     161           0 : void FrameBorder::AddFocusPolygon( const Polygon& rFocus )
     162             : {
     163           0 :     lclPolyPolyUnion( maFocusArea, rFocus );
     164           0 : }
     165             : 
     166           0 : void FrameBorder::MergeFocusToPolyPolygon( tools::PolyPolygon& rPPoly ) const
     167             : {
     168           0 :     lclPolyPolyUnion( rPPoly, maFocusArea );
     169           0 : }
     170             : 
     171           0 : void FrameBorder::AddClickRect( const Rectangle& rRect )
     172             : {
     173           0 :     lclPolyPolyUnion( maClickArea, Polygon( rRect ) );
     174           0 : }
     175             : 
     176           0 : bool FrameBorder::ContainsClickPoint( const Point& rPos ) const
     177             : {
     178           0 :     return vcl::Region( maClickArea ).IsInside( rPos );
     179             : }
     180             : 
     181           0 : Rectangle FrameBorder::GetClickBoundRect() const
     182             : {
     183           0 :     return maClickArea.GetBoundRect();
     184             : }
     185             : 
     186           0 : void FrameBorder::SetKeyboardNeighbors(
     187             :         FrameBorderType eLeft, FrameBorderType eRight, FrameBorderType eTop, FrameBorderType eBottom )
     188             : {
     189           0 :     meKeyLeft = eLeft;
     190           0 :     meKeyRight = eRight;
     191           0 :     meKeyTop = eTop;
     192           0 :     meKeyBottom = eBottom;
     193           0 : }
     194             : 
     195           0 : FrameBorderType FrameBorder::GetKeyboardNeighbor( sal_uInt16 nKeyCode ) const
     196             : {
     197           0 :     FrameBorderType eBorder = FRAMEBORDER_NONE;
     198           0 :     switch( nKeyCode )
     199             :     {
     200           0 :         case KEY_LEFT:  eBorder = meKeyLeft;      break;
     201           0 :         case KEY_RIGHT: eBorder = meKeyRight;     break;
     202           0 :         case KEY_UP:    eBorder = meKeyTop;       break;
     203           0 :         case KEY_DOWN:  eBorder = meKeyBottom;    break;
     204             :         default:        SAL_WARN( "svx.dialog", "svx::FrameBorder::GetKeyboardNeighbor - unknown key code" );
     205             :     }
     206           0 :     return eBorder;
     207             : }
     208             : 
     209           0 : FrameSelectorImpl::FrameSelectorImpl( FrameSelector& rFrameSel ) :
     210           0 :     Resource( SVX_RES( RID_SVXSTR_BORDER_CONTROL ) ),
     211             :     mrFrameSel( rFrameSel ),
     212             :     maILArrows( 16 ),
     213             :     maLeft( FRAMEBORDER_LEFT ),
     214             :     maRight( FRAMEBORDER_RIGHT ),
     215             :     maTop( FRAMEBORDER_TOP ),
     216             :     maBottom( FRAMEBORDER_BOTTOM ),
     217             :     maHor( FRAMEBORDER_HOR ),
     218             :     maVer( FRAMEBORDER_VER ),
     219             :     maTLBR( FRAMEBORDER_TLBR ),
     220             :     maBLTR( FRAMEBORDER_BLTR ),
     221             :     mnFlags( FRAMESEL_OUTER ),
     222             :     mnCtrlSize( 0 ),
     223             :     mnArrowSize( 0 ),
     224             :     mnLine1( 0 ),
     225             :     mnLine2( 0 ),
     226             :     mnLine3( 0 ),
     227             :     mnFocusOffs( 0 ),
     228             :     mbHor( false ),
     229             :     mbVer( false ),
     230             :     mbTLBR( false ),
     231             :     mbBLTR( false ),
     232             :     mbFullRepaint( true ),
     233             :     mbAutoSelect( true ),
     234             :     mbClicked( false ),
     235             :     mbHCMode( false ),
     236             :     mpAccess( 0 ),
     237             :     maChildVec( 8, static_cast< a11y::AccFrameSelector* >( 0 ) ),
     238           0 :     mxChildVec( 8 )
     239             : {
     240           0 :     FreeResource();
     241             : 
     242           0 :     maAllBorders.resize( FRAMEBORDERTYPE_COUNT, 0 );
     243           0 :     maAllBorders[ GetIndexFromFrameBorderType( FRAMEBORDER_LEFT   ) ] = &maLeft;
     244           0 :     maAllBorders[ GetIndexFromFrameBorderType( FRAMEBORDER_RIGHT  ) ] = &maRight;
     245           0 :     maAllBorders[ GetIndexFromFrameBorderType( FRAMEBORDER_TOP    ) ] = &maTop;
     246           0 :     maAllBorders[ GetIndexFromFrameBorderType( FRAMEBORDER_BOTTOM ) ] = &maBottom;
     247           0 :     maAllBorders[ GetIndexFromFrameBorderType( FRAMEBORDER_HOR    ) ] = &maHor;
     248           0 :     maAllBorders[ GetIndexFromFrameBorderType( FRAMEBORDER_VER    ) ] = &maVer;
     249           0 :     maAllBorders[ GetIndexFromFrameBorderType( FRAMEBORDER_TLBR   ) ] = &maTLBR;
     250           0 :     maAllBorders[ GetIndexFromFrameBorderType( FRAMEBORDER_BLTR   ) ] = &maBLTR;
     251             : #if OSL_DEBUG_LEVEL >= 2
     252             :     {
     253             :         bool bOk = true;
     254             :         for( FrameBorderCIter aIt( maAllBorders ); bOk && aIt.Is(); bOk = (*aIt != 0), ++aIt );
     255             :         DBG_ASSERT( bOk, "svx::FrameSelectorImpl::FrameSelectorImpl - missing entry in maAllBorders" );
     256             :     }
     257             : #endif
     258             :     //                             left neighbor     right neighbor     upper neighbor    lower neighbor
     259           0 :     maLeft.SetKeyboardNeighbors(   FRAMEBORDER_NONE, FRAMEBORDER_TLBR,  FRAMEBORDER_TOP,  FRAMEBORDER_BOTTOM );
     260           0 :     maRight.SetKeyboardNeighbors(  FRAMEBORDER_BLTR, FRAMEBORDER_NONE,  FRAMEBORDER_TOP,  FRAMEBORDER_BOTTOM );
     261           0 :     maTop.SetKeyboardNeighbors(    FRAMEBORDER_LEFT, FRAMEBORDER_RIGHT, FRAMEBORDER_NONE, FRAMEBORDER_TLBR );
     262           0 :     maBottom.SetKeyboardNeighbors( FRAMEBORDER_LEFT, FRAMEBORDER_RIGHT, FRAMEBORDER_BLTR, FRAMEBORDER_NONE );
     263           0 :     maHor.SetKeyboardNeighbors(    FRAMEBORDER_LEFT, FRAMEBORDER_RIGHT, FRAMEBORDER_TLBR, FRAMEBORDER_BLTR );
     264           0 :     maVer.SetKeyboardNeighbors(    FRAMEBORDER_TLBR, FRAMEBORDER_BLTR,  FRAMEBORDER_TOP,  FRAMEBORDER_BOTTOM );
     265           0 :     maTLBR.SetKeyboardNeighbors(   FRAMEBORDER_LEFT, FRAMEBORDER_VER,   FRAMEBORDER_TOP,  FRAMEBORDER_HOR );
     266           0 :     maBLTR.SetKeyboardNeighbors(   FRAMEBORDER_VER,  FRAMEBORDER_RIGHT, FRAMEBORDER_HOR,  FRAMEBORDER_BOTTOM );
     267             : 
     268           0 :     Initialize(mnFlags);
     269           0 : }
     270             : 
     271           0 : FrameSelectorImpl::~FrameSelectorImpl()
     272             : {
     273           0 :     if( mpAccess )
     274           0 :         mpAccess->Invalidate();
     275           0 :     for( AccessibleImplVec::iterator aIt = maChildVec.begin(), aEnd = maChildVec.end(); aIt != aEnd; ++aIt )
     276           0 :         if( *aIt )
     277           0 :             (*aIt)->Invalidate();
     278           0 : }
     279             : 
     280             : // initialization
     281           0 : void FrameSelectorImpl::Initialize( FrameSelFlags nFlags )
     282             : {
     283           0 :     mnFlags = nFlags;
     284             : 
     285           0 :     maEnabBorders.clear();
     286           0 :     for( FrameBorderIter aIt( maAllBorders ); aIt.Is(); ++aIt )
     287             :     {
     288           0 :         (*aIt)->Enable( mnFlags );
     289           0 :         if( (*aIt)->IsEnabled() )
     290           0 :             maEnabBorders.push_back( *aIt );
     291             :     }
     292           0 :     mbHor = maHor.IsEnabled();
     293           0 :     mbVer = maVer.IsEnabled();
     294           0 :     mbTLBR = maTLBR.IsEnabled();
     295           0 :     mbBLTR = maBLTR.IsEnabled();
     296             : 
     297           0 :     InitVirtualDevice();
     298           0 : }
     299             : 
     300           0 : void FrameSelectorImpl::InitColors()
     301             : {
     302           0 :     const StyleSettings& rSett = mrFrameSel.GetSettings().GetStyleSettings();
     303           0 :     maBackCol = rSett.GetFieldColor();
     304           0 :     mbHCMode = rSett.GetHighContrastMode();
     305           0 :     maArrowCol = rSett.GetFieldTextColor();
     306           0 :     maMarkCol.operator=( maBackCol ).Merge( maArrowCol, mbHCMode ? 0x80 : 0xC0 );
     307           0 :     maHCLineCol = rSett.GetLabelTextColor();
     308           0 : }
     309             : 
     310           0 : void FrameSelectorImpl::InitArrowImageList()
     311             : {
     312             :     /* Build the arrow images bitmap with current colors. */
     313           0 :     Color pColorAry1[3];
     314           0 :     Color pColorAry2[3];
     315           0 :     pColorAry1[0] = Color( 0, 0, 0 );
     316           0 :     pColorAry2[0] = maArrowCol;       // black -> arrow color
     317           0 :     pColorAry1[1] = Color( 0, 255, 0 );
     318           0 :     pColorAry2[1] = maMarkCol;        // green -> marker color
     319           0 :     pColorAry1[2] = Color( 255, 0, 255 );
     320           0 :     pColorAry2[2] = maBackCol;       // magenta -> background
     321             : 
     322           0 :     GetRes( SVX_RES( RID_SVXSTR_BORDER_CONTROL ).SetRT( RSC_RESOURCE ) );
     323             :     maILArrows.InsertFromHorizontalBitmap(
     324           0 :         SVX_RES( BMP_FRMSEL_ARROWS ), 16, NULL, pColorAry1, pColorAry2, 3);
     325           0 :     FreeResource();
     326             :     DBG_ASSERT( maILArrows.GetImageSize().Height() == maILArrows.GetImageSize().Width(),
     327             :         "svx::FrameSelectorImpl::InitArrowImageList - images are not squarish" );
     328           0 :     mnArrowSize = maILArrows.GetImageSize().Height();
     329           0 : }
     330             : 
     331           0 : void FrameSelectorImpl::InitGlobalGeometry()
     332             : {
     333           0 :     Size aCtrlSize( mrFrameSel.CalcOutputSize( mrFrameSel.GetSizePixel() ) );
     334             :     /*  nMinSize is the lower of width and height (control will always be squarish).
     335             :         FRAMESEL_GEOM_OUTER is the minimal distance between inner control border
     336             :         and any element. */
     337           0 :     long nMinSize = std::min( aCtrlSize.Width(), aCtrlSize.Height() ) - 2 * FRAMESEL_GEOM_OUTER;
     338             :     /*  nFixedSize is the size all existing elements need in one direction:
     339             :         the diag. arrow, space betw. arrow and frame border, outer frame border,
     340             :         inner frame border, other outer frame border, space betw. frame border
     341             :         and arrow, the other arrow. */
     342           0 :     long nFixedSize = 2 * mnArrowSize + 2 * FRAMESEL_GEOM_INNER + 3 * FRAMESEL_GEOM_WIDTH;
     343             :     /*  nBetwBordersSize contains the size between an outer and inner frame border (made odd). */
     344           0 :     long nBetwBordersSize = (((nMinSize - nFixedSize) / 2) - 1) | 1;
     345             : 
     346             :     /*  The final size of the usable area. */
     347           0 :     mnCtrlSize = 2 * nBetwBordersSize + nFixedSize;
     348           0 :     maVirDev.SetOutputSizePixel( Size( mnCtrlSize, mnCtrlSize ) );
     349             : 
     350             :     /*  Center the virtual device in the control. */
     351           0 :     maVirDevPos = Point( (aCtrlSize.Width() - mnCtrlSize) / 2, (aCtrlSize.Height() - mnCtrlSize) / 2 );
     352           0 : }
     353             : 
     354           0 : void FrameSelectorImpl::InitBorderGeometry()
     355             : {
     356             :     size_t nCol, nCols, nRow, nRows;
     357             : 
     358             :     // Global border geometry values
     359             :     /*  mnLine* is the middle point inside a frame border (i.e. mnLine1 is mid X inside left border). */
     360           0 :     mnLine1 = mnArrowSize + FRAMESEL_GEOM_INNER + FRAMESEL_GEOM_WIDTH / 2;
     361           0 :     mnLine2 = mnCtrlSize / 2;
     362           0 :     mnLine3 = 2 * mnLine2 - mnLine1;
     363             : 
     364             :     // Frame helper array
     365           0 :     maArray.Initialize( mbVer ? 2 : 1, mbHor ? 2 : 1 );
     366           0 :     maArray.SetUseDiagDoubleClipping( true );
     367             : 
     368           0 :     maArray.SetXOffset( mnLine1 );
     369           0 :     maArray.SetAllColWidths( (mbVer ? mnLine2 : mnLine3) - mnLine1 );
     370             : 
     371           0 :     maArray.SetYOffset( mnLine1 );
     372           0 :     maArray.SetAllRowHeights( (mbHor ? mnLine2 : mnLine3) - mnLine1 );
     373             : 
     374             :     // Focus polygons
     375             :     /*  Width for focus rectangles from center of frame borders. */
     376           0 :     mnFocusOffs = FRAMESEL_GEOM_WIDTH / 2 + 1;
     377             : 
     378           0 :     maLeft.ClearFocusArea();
     379           0 :     maVer.ClearFocusArea();
     380           0 :     maRight.ClearFocusArea();
     381           0 :     maTop.ClearFocusArea();
     382           0 :     maHor.ClearFocusArea();
     383           0 :     maBottom.ClearFocusArea();
     384             : 
     385           0 :     maLeft.AddFocusPolygon(   Rectangle( mnLine1 - mnFocusOffs, mnLine1 - mnFocusOffs, mnLine1 + mnFocusOffs, mnLine3 + mnFocusOffs ) );
     386           0 :     maVer.AddFocusPolygon(    Rectangle( mnLine2 - mnFocusOffs, mnLine1 - mnFocusOffs, mnLine2 + mnFocusOffs, mnLine3 + mnFocusOffs ) );
     387           0 :     maRight.AddFocusPolygon(  Rectangle( mnLine3 - mnFocusOffs, mnLine1 - mnFocusOffs, mnLine3 + mnFocusOffs, mnLine3 + mnFocusOffs ) );
     388           0 :     maTop.AddFocusPolygon(    Rectangle( mnLine1 - mnFocusOffs, mnLine1 - mnFocusOffs, mnLine3 + mnFocusOffs, mnLine1 + mnFocusOffs ) );
     389           0 :     maHor.AddFocusPolygon(    Rectangle( mnLine1 - mnFocusOffs, mnLine2 - mnFocusOffs, mnLine3 + mnFocusOffs, mnLine2 + mnFocusOffs ) );
     390           0 :     maBottom.AddFocusPolygon( Rectangle( mnLine1 - mnFocusOffs, mnLine3 - mnFocusOffs, mnLine3 + mnFocusOffs, mnLine3 + mnFocusOffs ) );
     391             : 
     392           0 :     for( nCol = 0, nCols = maArray.GetColCount(); nCol < nCols; ++nCol )
     393             :     {
     394           0 :         for( nRow = 0, nRows = maArray.GetRowCount(); nRow < nRows; ++nRow )
     395             :         {
     396           0 :             Rectangle aRect( maArray.GetCellRect( nCol, nRow ) );
     397           0 :             long nDiagFocusOffsX = frame::GetTLDiagOffset( -mnFocusOffs, mnFocusOffs, maArray.GetHorDiagAngle( nCol, nRow ) );
     398           0 :             long nDiagFocusOffsY = frame::GetTLDiagOffset( -mnFocusOffs, mnFocusOffs, maArray.GetVerDiagAngle( nCol, nRow ) );
     399             : 
     400           0 :             std::vector< Point > aFocusVec;
     401           0 :             aFocusVec.push_back( Point( aRect.Left()  - mnFocusOffs,     aRect.Top()    + nDiagFocusOffsY ) );
     402           0 :             aFocusVec.push_back( Point( aRect.Left()  - mnFocusOffs,     aRect.Top()    - mnFocusOffs     ) );
     403           0 :             aFocusVec.push_back( Point( aRect.Left()  + nDiagFocusOffsX, aRect.Top()    - mnFocusOffs     ) );
     404           0 :             aFocusVec.push_back( Point( aRect.Right() + mnFocusOffs,     aRect.Bottom() - nDiagFocusOffsY ) );
     405           0 :             aFocusVec.push_back( Point( aRect.Right() + mnFocusOffs,     aRect.Bottom() + mnFocusOffs     ) );
     406           0 :             aFocusVec.push_back( Point( aRect.Right() - nDiagFocusOffsX, aRect.Bottom() + mnFocusOffs     ) );
     407           0 :             maTLBR.AddFocusPolygon( Polygon( static_cast< sal_uInt16 >( aFocusVec.size() ), &aFocusVec[ 0 ] ) );
     408             : 
     409           0 :             aFocusVec.clear();
     410           0 :             aFocusVec.push_back( Point( aRect.Right() + mnFocusOffs,     aRect.Top()    + nDiagFocusOffsY ) );
     411           0 :             aFocusVec.push_back( Point( aRect.Right() + mnFocusOffs,     aRect.Top()    - mnFocusOffs     ) );
     412           0 :             aFocusVec.push_back( Point( aRect.Right() - nDiagFocusOffsX, aRect.Top()    - mnFocusOffs     ) );
     413           0 :             aFocusVec.push_back( Point( aRect.Left()  - mnFocusOffs,     aRect.Bottom() - nDiagFocusOffsY ) );
     414           0 :             aFocusVec.push_back( Point( aRect.Left()  - mnFocusOffs,     aRect.Bottom() + mnFocusOffs     ) );
     415           0 :             aFocusVec.push_back( Point( aRect.Left()  + nDiagFocusOffsX, aRect.Bottom() + mnFocusOffs     ) );
     416           0 :             maBLTR.AddFocusPolygon( Polygon( static_cast< sal_uInt16 >( aFocusVec.size() ), &aFocusVec[ 0 ] ) );
     417           0 :         }
     418             :     }
     419             : 
     420             :     // Click areas
     421           0 :     for( FrameBorderIter aIt( maAllBorders ); aIt.Is(); ++aIt )
     422           0 :         (*aIt)->ClearClickArea();
     423             : 
     424             :     /*  Additional space for click area: is added to the space available to draw
     425             :         the frame borders. For instance left frame border:
     426             :         - To left, top, and bottom always big additional space (outer area).
     427             :         - To right: Dependent on existence of inner vertical frame border
     428             :             (if enabled, use less space).
     429             :      */
     430           0 :     long nClO = FRAMESEL_GEOM_WIDTH / 2 + FRAMESEL_GEOM_ADD_CLICK_OUTER;
     431           0 :     long nClI = (mbTLBR && mbBLTR) ? (FRAMESEL_GEOM_WIDTH / 2 + FRAMESEL_GEOM_ADD_CLICK_INNER) : nClO;
     432           0 :     long nClH = mbHor ? nClI : nClO;            // additional space dependent of horizontal inner border
     433           0 :     long nClV = mbVer ? nClI : nClO;            // additional space dependent of vertical inner border
     434             : 
     435           0 :     maLeft.AddClickRect(   Rectangle( mnLine1 - nClO, mnLine1 - nClO, mnLine1 + nClV, mnLine3 + nClO ) );
     436           0 :     maVer.AddClickRect(    Rectangle( mnLine2 - nClI, mnLine1 - nClO, mnLine2 + nClI, mnLine3 + nClO ) );
     437           0 :     maRight.AddClickRect(  Rectangle( mnLine3 - nClV, mnLine1 - nClO, mnLine3 + nClO, mnLine3 + nClO ) );
     438           0 :     maTop.AddClickRect(    Rectangle( mnLine1 - nClO, mnLine1 - nClO, mnLine3 + nClO, mnLine1 + nClH ) );
     439           0 :     maHor.AddClickRect(    Rectangle( mnLine1 - nClO, mnLine2 - nClI, mnLine3 + nClO, mnLine2 + nClI ) );
     440           0 :     maBottom.AddClickRect( Rectangle( mnLine1 - nClO, mnLine3 - nClH, mnLine3 + nClO, mnLine3 + nClO ) );
     441             : 
     442             :     /*  Diagonal frame borders use the remaining space between outer and inner frame borders. */
     443           0 :     if( mbTLBR || mbBLTR )
     444             :     {
     445           0 :         for( nCol = 0, nCols = maArray.GetColCount(); nCol < nCols; ++nCol )
     446             :         {
     447           0 :             for( nRow = 0, nRows = maArray.GetRowCount(); nRow < nRows; ++nRow )
     448             :             {
     449             :                 // the usable area between horizonal/vertical frame borders of current quadrant
     450           0 :                 Rectangle aRect( maArray.GetCellRect( nCol, nRow ) );
     451           0 :                 aRect.Left() += nClV + 1;
     452           0 :                 aRect.Right() -= nClV + 1;
     453           0 :                 aRect.Top() += nClH + 1;
     454           0 :                 aRect.Bottom() -= nClH + 1;
     455             : 
     456             :                 /*  Both diagonal frame borders enabled. */
     457           0 :                 if( mbTLBR && mbBLTR )
     458             :                 {
     459             :                     // single areas
     460           0 :                     Point aMid( aRect.Center() );
     461           0 :                     maTLBR.AddClickRect( Rectangle( aRect.TopLeft(), aMid ) );
     462           0 :                     maTLBR.AddClickRect( Rectangle( aMid + Point( 1, 1 ), aRect.BottomRight() ) );
     463           0 :                     maBLTR.AddClickRect( Rectangle( aRect.Left(), aMid.Y() + 1, aMid.X(), aRect.Bottom() ) );
     464           0 :                     maBLTR.AddClickRect( Rectangle( aMid.X() + 1, aRect.Top(), aRect.Right(), aMid.Y() ) );
     465             :                     // centered rectangle for both frame borders
     466           0 :                     Rectangle aMidRect( aRect.TopLeft(), Size( aRect.GetWidth() / 3, aRect.GetHeight() / 3 ) );
     467           0 :                     aMidRect.Move( (aRect.GetWidth() - aMidRect.GetWidth()) / 2, (aRect.GetHeight() - aMidRect.GetHeight()) / 2 );
     468           0 :                     maTLBR.AddClickRect( aMidRect );
     469           0 :                     maBLTR.AddClickRect( aMidRect );
     470             :                 }
     471             :                 /*  One of the diagonal frame borders enabled - use entire rectangle. */
     472           0 :                 else if( mbTLBR && !mbBLTR )    // top-left to bottom-right only
     473           0 :                     maTLBR.AddClickRect( aRect );
     474           0 :                 else if( !mbTLBR && mbBLTR )    // bottom-left to top-right only
     475           0 :                     maBLTR.AddClickRect( aRect );
     476             :             }
     477             :         }
     478             :     }
     479           0 : }
     480             : 
     481           0 : void FrameSelectorImpl::InitVirtualDevice()
     482             : {
     483             :     // initialize resources
     484           0 :     InitColors();
     485           0 :     InitArrowImageList();
     486             : 
     487           0 :     sizeChanged();
     488           0 : }
     489             : 
     490           0 : void FrameSelectorImpl::sizeChanged()
     491             : {
     492             :     // initialize geometry
     493           0 :     InitGlobalGeometry();
     494           0 :     InitBorderGeometry();
     495             : 
     496             :     // correct background around the used area
     497           0 :     mrFrameSel.SetBackground( Wallpaper( maBackCol ) );
     498           0 :     DoInvalidate( true );
     499           0 : }
     500             : 
     501             : // frame border access
     502           0 : const FrameBorder& FrameSelectorImpl::GetBorder( FrameBorderType eBorder ) const
     503             : {
     504           0 :     size_t nIndex = GetIndexFromFrameBorderType( eBorder );
     505           0 :     if( nIndex < maAllBorders.size() )
     506           0 :         return *maAllBorders[ nIndex ];
     507             :     SAL_WARN( "svx.dialog", "svx::FrameSelectorImpl::GetBorder - unknown border type" );
     508           0 :     return maTop;
     509             : }
     510             : 
     511           0 : FrameBorder& FrameSelectorImpl::GetBorderAccess( FrameBorderType eBorder )
     512             : {
     513           0 :     return const_cast< FrameBorder& >( GetBorder( eBorder ) );
     514             : }
     515             : 
     516             : // drawing
     517           0 : void FrameSelectorImpl::DrawBackground()
     518             : {
     519             :     // clear the area
     520           0 :     maVirDev.SetLineColor();
     521           0 :     maVirDev.SetFillColor( maBackCol );
     522           0 :     maVirDev.DrawRect( Rectangle( Point( 0, 0 ), maVirDev.GetOutputSizePixel() ) );
     523             : 
     524             :     // draw the inner gray (or whatever color) rectangle
     525           0 :     maVirDev.SetLineColor();
     526           0 :     maVirDev.SetFillColor( maMarkCol );
     527             :     maVirDev.DrawRect( Rectangle(
     528           0 :         mnLine1 - mnFocusOffs, mnLine1 - mnFocusOffs, mnLine3 + mnFocusOffs, mnLine3 + mnFocusOffs ) );
     529             : 
     530             :     // draw the white space for enabled frame borders
     531           0 :     tools::PolyPolygon aPPoly;
     532           0 :     for( FrameBorderCIter aIt( maEnabBorders ); aIt.Is(); ++aIt )
     533           0 :         (*aIt)->MergeFocusToPolyPolygon( aPPoly );
     534           0 :     aPPoly.Optimize( POLY_OPTIMIZE_CLOSE );
     535           0 :     maVirDev.SetLineColor( maBackCol );
     536           0 :     maVirDev.SetFillColor( maBackCol );
     537           0 :     maVirDev.DrawPolyPolygon( aPPoly );
     538           0 : }
     539             : 
     540           0 : void FrameSelectorImpl::DrawArrows( const FrameBorder& rBorder )
     541             : {
     542             :     DBG_ASSERT( rBorder.IsEnabled(), "svx::FrameSelectorImpl::DrawArrows - access to disabled border" );
     543             : 
     544           0 :     long nLinePos = 0;
     545           0 :     switch( rBorder.GetType() )
     546             :     {
     547             :         case FRAMEBORDER_LEFT:
     548           0 :         case FRAMEBORDER_TOP:       nLinePos = mnLine1; break;
     549             :         case FRAMEBORDER_VER:
     550           0 :         case FRAMEBORDER_HOR:       nLinePos = mnLine2; break;
     551             :         case FRAMEBORDER_RIGHT:
     552           0 :         case FRAMEBORDER_BOTTOM:    nLinePos = mnLine3; break;
     553             :         default: ; //prevent warning
     554             :     }
     555           0 :     nLinePos -= mnArrowSize / 2;
     556             : 
     557           0 :     long nTLPos = 0;
     558           0 :     long nBRPos = mnCtrlSize - mnArrowSize;
     559           0 :     Point aPos1, aPos2;
     560           0 :     sal_uInt16 nImgId1 = 0, nImgId2 = 0;
     561           0 :     switch( rBorder.GetType() )
     562             :     {
     563             :         case FRAMEBORDER_LEFT:
     564             :         case FRAMEBORDER_RIGHT:
     565             :         case FRAMEBORDER_VER:
     566           0 :             aPos1 = Point( nLinePos, nTLPos ); nImgId1 = 1;
     567           0 :             aPos2 = Point( nLinePos, nBRPos ); nImgId2 = 2;
     568           0 :         break;
     569             : 
     570             :         case FRAMEBORDER_TOP:
     571             :         case FRAMEBORDER_BOTTOM:
     572             :         case FRAMEBORDER_HOR:
     573           0 :             aPos1 = Point( nTLPos, nLinePos ); nImgId1 = 3;
     574           0 :             aPos2 = Point( nBRPos, nLinePos ); nImgId2 = 4;
     575           0 :         break;
     576             : 
     577             :         case FRAMEBORDER_TLBR:
     578           0 :             aPos1 = Point( nTLPos, nTLPos ); nImgId1 = 5;
     579           0 :             aPos2 = Point( nBRPos, nBRPos ); nImgId2 = 6;
     580           0 :         break;
     581             :         case FRAMEBORDER_BLTR:
     582           0 :             aPos1 = Point( nTLPos, nBRPos ); nImgId1 = 7;
     583           0 :             aPos2 = Point( nBRPos, nTLPos ); nImgId2 = 8;
     584           0 :         break;
     585             :         default: ; //prevent warning
     586             :     }
     587             : 
     588             :     // Arrow or marker? Do not draw arrows into disabled control.
     589           0 :     sal_uInt16 nSelectAdd = (mrFrameSel.IsEnabled() && rBorder.IsSelected()) ? 0 : 8;
     590           0 :     maVirDev.DrawImage( aPos1, maILArrows.GetImage( nImgId1 + nSelectAdd ) );
     591           0 :     maVirDev.DrawImage( aPos2, maILArrows.GetImage( nImgId2 + nSelectAdd ) );
     592           0 : }
     593             : 
     594           0 : void FrameSelectorImpl::DrawAllArrows()
     595             : {
     596           0 :     for( FrameBorderCIter aIt( maEnabBorders ); aIt.Is(); ++aIt )
     597           0 :         DrawArrows( **aIt );
     598           0 : }
     599             : 
     600           0 : Color FrameSelectorImpl::GetDrawLineColor( const Color& rColor ) const
     601             : {
     602           0 :     Color aColor( mbHCMode ? maHCLineCol : rColor );
     603           0 :     if( aColor == maBackCol )
     604           0 :         aColor.Invert();
     605           0 :     return aColor;
     606             : }
     607             : 
     608           0 : void FrameSelectorImpl::DrawAllFrameBorders()
     609             : {
     610             :     // Translate core colors to current UI colors (regards current background and HC mode).
     611           0 :     for( FrameBorderIter aIt( maEnabBorders ); aIt.Is(); ++aIt )
     612             :     {
     613           0 :         Color aCoreColorPrim = ((*aIt)->GetState() == FRAMESTATE_DONTCARE) ? maMarkCol : (*aIt)->GetCoreStyle().GetColorOut();
     614           0 :         Color aCoreColorSecn = ((*aIt)->GetState() == FRAMESTATE_DONTCARE) ? maMarkCol : (*aIt)->GetCoreStyle().GetColorIn();
     615           0 :         (*aIt)->SetUIColorPrim( GetDrawLineColor( aCoreColorPrim ) );
     616           0 :         (*aIt)->SetUIColorSecn( GetDrawLineColor( aCoreColorSecn ) );
     617             :     }
     618             : 
     619             :     // Copy all frame border styles to the helper array
     620           0 :     maArray.SetColumnStyleLeft( 0, maLeft.GetUIStyle() );
     621           0 :     if( mbVer ) maArray.SetColumnStyleLeft( 1, maVer.GetUIStyle() );
     622             : 
     623             :     // Invert the style for the right line
     624           0 :     const frame::Style rRightStyle = maRight.GetUIStyle( );
     625           0 :     frame::Style rInvertedRight( rRightStyle.GetColorPrim(),
     626           0 :             rRightStyle.GetColorSecn(), rRightStyle.GetColorGap(),
     627           0 :             rRightStyle.UseGapColor(),
     628             :             rRightStyle.Secn(), rRightStyle.Dist(), rRightStyle.Prim( ),
     629           0 :             rRightStyle.Type( ) );
     630           0 :     maArray.SetColumnStyleRight( mbVer ? 1 : 0, rInvertedRight );
     631             : 
     632           0 :     maArray.SetRowStyleTop( 0, maTop.GetUIStyle() );
     633           0 :     if( mbHor )
     634             :     {
     635             :         // Invert the style for the hor line to match the real borders
     636           0 :         const frame::Style rHorStyle = maHor.GetUIStyle();
     637           0 :         frame::Style rInvertedHor( rHorStyle.GetColorPrim(),
     638           0 :             rHorStyle.GetColorSecn(), rHorStyle.GetColorGap(),
     639           0 :             rHorStyle.UseGapColor(),
     640             :             rHorStyle.Secn(), rHorStyle.Dist(), rHorStyle.Prim( ),
     641           0 :             rHorStyle.Type() );
     642           0 :         maArray.SetRowStyleTop( 1, rInvertedHor );
     643             :     }
     644             : 
     645             :     // Invert the style for the bottom line
     646           0 :     const frame::Style rBottomStyle = maBottom.GetUIStyle( );
     647           0 :     frame::Style rInvertedBottom( rBottomStyle.GetColorPrim(),
     648           0 :             rBottomStyle.GetColorSecn(), rBottomStyle.GetColorGap(),
     649           0 :             rBottomStyle.UseGapColor(),
     650             :             rBottomStyle.Secn(), rBottomStyle.Dist(), rBottomStyle.Prim( ),
     651           0 :             rBottomStyle.Type() );
     652           0 :     maArray.SetRowStyleBottom( mbHor ? 1 : 0, rInvertedBottom );
     653             : 
     654           0 :     for( size_t nCol = 0; nCol < maArray.GetColCount(); ++nCol )
     655           0 :         for( size_t nRow = 0; nRow < maArray.GetRowCount(); ++nRow )
     656           0 :             maArray.SetCellStyleDiag( nCol, nRow, maTLBR.GetUIStyle(), maBLTR.GetUIStyle() );
     657             : 
     658             :     // Let the helper array draw itself
     659           0 :     maArray.DrawArray( maVirDev );
     660           0 : }
     661             : 
     662           0 : void FrameSelectorImpl::DrawVirtualDevice()
     663             : {
     664           0 :     DrawBackground();
     665           0 :     DrawAllArrows();
     666           0 :     DrawAllFrameBorders();
     667           0 :     mbFullRepaint = false;
     668           0 : }
     669             : 
     670           0 : void FrameSelectorImpl::CopyVirDevToControl()
     671             : {
     672           0 :     if( mbFullRepaint )
     673           0 :         DrawVirtualDevice();
     674           0 :     mrFrameSel.DrawBitmap( maVirDevPos, maVirDev.GetBitmap( Point( 0, 0 ), maVirDev.GetOutputSizePixel() ) );
     675           0 : }
     676             : 
     677           0 : void FrameSelectorImpl::DrawAllTrackingRects()
     678             : {
     679           0 :     tools::PolyPolygon aPPoly;
     680           0 :     if( mrFrameSel.IsAnyBorderSelected() )
     681             :     {
     682           0 :         for( SelFrameBorderCIter aIt( maEnabBorders ); aIt.Is(); ++aIt )
     683           0 :             (*aIt)->MergeFocusToPolyPolygon( aPPoly );
     684           0 :         aPPoly.Move( maVirDevPos.X(), maVirDevPos.Y() );
     685             :     }
     686             :     else
     687             :         // no frame border selected -> draw tracking rectangle around entire control
     688           0 :         aPPoly.Insert( Polygon( Rectangle( maVirDevPos, maVirDev.GetOutputSizePixel() ) ) );
     689             : 
     690           0 :     aPPoly.Optimize( POLY_OPTIMIZE_CLOSE );
     691           0 :     for( sal_uInt16 nIdx = 0, nCount = aPPoly.Count(); nIdx < nCount; ++nIdx )
     692           0 :         mrFrameSel.InvertTracking( aPPoly.GetObject( nIdx ), SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
     693           0 : }
     694             : 
     695           0 : Point FrameSelectorImpl::GetDevPosFromMousePos( const Point& rMousePos ) const
     696             : {
     697           0 :     return rMousePos - maVirDevPos;
     698             : }
     699             : 
     700           0 : void FrameSelectorImpl::DoInvalidate( bool bFullRepaint )
     701             : {
     702           0 :     mbFullRepaint |= bFullRepaint;
     703           0 :     mrFrameSel.Invalidate( INVALIDATE_NOERASE );
     704           0 : }
     705             : 
     706             : // frame border state and style
     707           0 : void FrameSelectorImpl::SetBorderState( FrameBorder& rBorder, FrameBorderState eState )
     708             : {
     709             :     DBG_ASSERT( rBorder.IsEnabled(), "svx::FrameSelectorImpl::SetBorderState - access to disabled border" );
     710           0 :     Any aOld;
     711           0 :     Any aNew;
     712           0 :     Any& rMod = eState == FRAMESTATE_SHOW ? aNew : aOld;
     713           0 :     rMod <<= AccessibleStateType::CHECKED;
     714           0 :     Reference< XAccessible > xRet;
     715           0 :     size_t nVecIdx = static_cast< size_t >( rBorder.GetType() );
     716           0 :     if( GetBorder(rBorder.GetType()).IsEnabled() && (1 <= nVecIdx) && (nVecIdx <= maChildVec.size()) )
     717           0 :         xRet = mxChildVec[ --nVecIdx ];
     718           0 :     a11y::AccFrameSelector* pFrameSelector = static_cast<a11y::AccFrameSelector*>(xRet.get());
     719             : 
     720           0 :     if( eState == FRAMESTATE_SHOW )
     721           0 :         SetBorderCoreStyle( rBorder, &maCurrStyle );
     722             :     else
     723           0 :         rBorder.SetState( eState );
     724           0 :     if (pFrameSelector)
     725           0 :             pFrameSelector->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOld, aNew );
     726           0 :     DoInvalidate( true );
     727           0 : }
     728             : 
     729           0 : void FrameSelectorImpl::SetBorderCoreStyle( FrameBorder& rBorder, const SvxBorderLine* pStyle )
     730             : {
     731             :     DBG_ASSERT( rBorder.IsEnabled(), "svx::FrameSelectorImpl::SetBorderCoreStyle - access to disabled border" );
     732           0 :     rBorder.SetCoreStyle( pStyle );
     733           0 :     DoInvalidate( true );
     734           0 : }
     735             : 
     736           0 : void FrameSelectorImpl::ToggleBorderState( FrameBorder& rBorder )
     737             : {
     738           0 :     bool bDontCare = mrFrameSel.SupportsDontCareState();
     739           0 :     switch( rBorder.GetState() )
     740             :     {
     741             :         // same order as tristate check box: visible -> don't care -> hidden
     742             :         case FRAMESTATE_SHOW:
     743           0 :             SetBorderState( rBorder, bDontCare ? FRAMESTATE_DONTCARE : FRAMESTATE_HIDE );
     744           0 :         break;
     745             :         case FRAMESTATE_HIDE:
     746           0 :             SetBorderState( rBorder, FRAMESTATE_SHOW );
     747           0 :         break;
     748             :         case FRAMESTATE_DONTCARE:
     749           0 :             SetBorderState( rBorder, FRAMESTATE_HIDE );
     750           0 :         break;
     751             :     }
     752           0 : }
     753             : 
     754             : // frame border selection
     755           0 : void FrameSelectorImpl::SelectBorder( FrameBorder& rBorder, bool bSelect )
     756             : {
     757             :     DBG_ASSERT( rBorder.IsEnabled(), "svx::FrameSelectorImpl::SelectBorder - access to disabled border" );
     758           0 :     rBorder.Select( bSelect );
     759           0 :     DrawArrows( rBorder );
     760           0 :     DoInvalidate( false );
     761           0 : }
     762             : 
     763           0 : void FrameSelectorImpl::SilentGrabFocus()
     764             : {
     765           0 :     bool bOldAuto = mbAutoSelect;
     766           0 :     mbAutoSelect = false;
     767           0 :     mrFrameSel.GrabFocus();
     768           0 :     mbAutoSelect = bOldAuto;
     769           0 : }
     770             : 
     771           0 : bool FrameSelectorImpl::SelectedBordersEqual() const
     772             : {
     773           0 :     bool bEqual = true;
     774           0 :     SelFrameBorderCIter aIt( maEnabBorders );
     775           0 :     if( aIt.Is() )
     776             :     {
     777           0 :         const SvxBorderLine& rFirstStyle = (*aIt)->GetCoreStyle();
     778           0 :         for( ++aIt; bEqual && aIt.Is(); ++aIt )
     779           0 :             bEqual = ((*aIt)->GetCoreStyle() == rFirstStyle);
     780             :     }
     781           0 :     return bEqual;
     782             : }
     783             : 
     784           0 : FrameSelector::FrameSelector(vcl::Window* pParent)
     785           0 :     : Control(pParent, WB_BORDER|WB_TABSTOP)
     786             : {
     787             :     // not in c'tor init list (avoid warning about usage of *this)
     788           0 :     mxImpl.reset( new FrameSelectorImpl( *this ) );
     789           0 :     EnableRTL( false ); // #107808# don't mirror the mouse handling
     790           0 : }
     791             : 
     792           0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeSvxFrameSelector(vcl::Window *pParent, VclBuilder::stringmap &)
     793             : {
     794           0 :     return new FrameSelector(pParent);
     795             : }
     796             : 
     797           0 : FrameSelector::~FrameSelector()
     798             : {
     799           0 : }
     800             : 
     801           0 : void FrameSelector::Initialize( FrameSelFlags nFlags )
     802             : {
     803           0 :     mxImpl->Initialize( nFlags );
     804           0 :     Show();
     805           0 : }
     806             : 
     807             : // enabled frame borders
     808           0 : bool FrameSelector::IsBorderEnabled( FrameBorderType eBorder ) const
     809             : {
     810           0 :     return mxImpl->GetBorder( eBorder ).IsEnabled();
     811             : }
     812             : 
     813           0 : sal_Int32 FrameSelector::GetEnabledBorderCount() const
     814             : {
     815           0 :     return static_cast< sal_Int32 >( mxImpl->maEnabBorders.size() );
     816             : }
     817             : 
     818           0 : FrameBorderType FrameSelector::GetEnabledBorderType( sal_Int32 nIndex ) const
     819             : {
     820           0 :     FrameBorderType eBorder = FRAMEBORDER_NONE;
     821           0 :     if( nIndex >= 0 )
     822             :     {
     823           0 :         size_t nVecIdx = static_cast< size_t >( nIndex );
     824           0 :         if( nVecIdx < mxImpl->maEnabBorders.size() )
     825           0 :             eBorder = mxImpl->maEnabBorders[ nVecIdx ]->GetType();
     826             :     }
     827           0 :     return eBorder;
     828             : }
     829             : 
     830           0 : sal_Int32 FrameSelector::GetEnabledBorderIndex( FrameBorderType eBorder ) const
     831             : {
     832           0 :     sal_Int32 nIndex = 0;
     833           0 :     for( FrameBorderCIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt, ++nIndex )
     834           0 :         if( (*aIt)->GetType() == eBorder )
     835           0 :             return nIndex;
     836           0 :     return -1;
     837             : }
     838             : 
     839             : // frame border state and style
     840           0 : bool FrameSelector::SupportsDontCareState() const
     841             : {
     842           0 :     return (mxImpl->mnFlags & FRAMESEL_DONTCARE) != 0;
     843             : }
     844             : 
     845           0 : FrameBorderState FrameSelector::GetFrameBorderState( FrameBorderType eBorder ) const
     846             : {
     847           0 :     return mxImpl->GetBorder( eBorder ).GetState();
     848             : }
     849             : 
     850           0 : const SvxBorderLine* FrameSelector::GetFrameBorderStyle( FrameBorderType eBorder ) const
     851             : {
     852           0 :     const SvxBorderLine& rStyle = mxImpl->GetBorder( eBorder ).GetCoreStyle();
     853             :     // rest of the world uses null pointer for invisible frame border
     854           0 :     return rStyle.GetOutWidth() ? &rStyle : 0;
     855             : }
     856             : 
     857           0 : void FrameSelector::ShowBorder( FrameBorderType eBorder, const SvxBorderLine* pStyle )
     858             : {
     859           0 :     mxImpl->SetBorderCoreStyle( mxImpl->GetBorderAccess( eBorder ), pStyle );
     860           0 : }
     861             : 
     862           0 : void FrameSelector::SetBorderDontCare( FrameBorderType eBorder )
     863             : {
     864           0 :     mxImpl->SetBorderState( mxImpl->GetBorderAccess( eBorder ), FRAMESTATE_DONTCARE );
     865           0 : }
     866             : 
     867           0 : bool FrameSelector::IsAnyBorderVisible() const
     868             : {
     869           0 :     bool bIsSet = false;
     870           0 :     for( FrameBorderCIter aIt( mxImpl->maEnabBorders ); !bIsSet && aIt.Is(); ++aIt )
     871           0 :         bIsSet = ((*aIt)->GetState() == FRAMESTATE_SHOW);
     872           0 :     return bIsSet;
     873             : }
     874             : 
     875           0 : void FrameSelector::HideAllBorders()
     876             : {
     877           0 :     for( FrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
     878           0 :         mxImpl->SetBorderState( **aIt, FRAMESTATE_HIDE );
     879           0 : }
     880             : 
     881           0 : bool FrameSelector::GetVisibleWidth( long& rnWidth, SvxBorderStyle& rnStyle ) const
     882             : {
     883           0 :     VisFrameBorderCIter aIt( mxImpl->maEnabBorders );
     884           0 :     if( !aIt.Is() )
     885           0 :         return false;
     886             : 
     887           0 :     const SvxBorderLine& rStyle = (*aIt)->GetCoreStyle();
     888           0 :     bool bFound = true;
     889           0 :     for( ++aIt; bFound && aIt.Is(); ++aIt )
     890             :     {
     891             :         bFound =
     892           0 :             (rStyle.GetWidth() == (*aIt)->GetCoreStyle().GetWidth()) &&
     893           0 :             (rStyle.GetBorderLineStyle() ==
     894           0 :                 (*aIt)->GetCoreStyle().GetBorderLineStyle());
     895             :     }
     896             : 
     897           0 :     if( bFound )
     898             :     {
     899           0 :         rnWidth = rStyle.GetWidth();
     900           0 :         rnStyle = rStyle.GetBorderLineStyle();
     901             :     }
     902           0 :     return bFound;
     903             : }
     904             : 
     905           0 : bool FrameSelector::GetVisibleColor( Color& rColor ) const
     906             : {
     907           0 :     VisFrameBorderCIter aIt( mxImpl->maEnabBorders );
     908           0 :     if( !aIt.Is() )
     909           0 :         return false;
     910             : 
     911           0 :     const SvxBorderLine& rStyle = (*aIt)->GetCoreStyle();
     912           0 :     bool bFound = true;
     913           0 :     for( ++aIt; bFound && aIt.Is(); ++aIt )
     914           0 :         bFound = (rStyle.GetColor() == (*aIt)->GetCoreStyle().GetColor());
     915             : 
     916           0 :     if( bFound )
     917           0 :         rColor = rStyle.GetColor();
     918           0 :     return bFound;
     919             : }
     920             : 
     921             : // frame border selection
     922           0 : const Link& FrameSelector::GetSelectHdl() const
     923             : {
     924           0 :     return mxImpl->maSelectHdl;
     925             : }
     926             : 
     927           0 : void FrameSelector::SetSelectHdl( const Link& rHdl )
     928             : {
     929           0 :     mxImpl->maSelectHdl = rHdl;
     930           0 : }
     931             : 
     932           0 : bool FrameSelector::IsBorderSelected( FrameBorderType eBorder ) const
     933             : {
     934           0 :     return mxImpl->GetBorder( eBorder ).IsSelected();
     935             : }
     936             : 
     937           0 : void FrameSelector::SelectBorder( FrameBorderType eBorder, bool bSelect /*, bool bFocus */ )
     938             : {
     939           0 :     mxImpl->SelectBorder( mxImpl->GetBorderAccess( eBorder ), bSelect );
     940             :     // MT: bFireFox as API parameter is ugly...
     941             :     // if (bFocus)
     942             :     {
     943           0 :         Reference< XAccessible > xRet = GetChildAccessible(eBorder);
     944           0 :         a11y::AccFrameSelector* pFrameSelector = static_cast<a11y::AccFrameSelector*>(xRet.get());
     945           0 :         if (pFrameSelector)
     946             :         {
     947           0 :             Any aOldValue, aNewValue;
     948           0 :             aNewValue <<= AccessibleStateType::FOCUSED;
     949           0 :             pFrameSelector->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
     950           0 :         }
     951             :     }
     952           0 : }
     953             : 
     954           0 : bool FrameSelector::IsAnyBorderSelected() const
     955             : {
     956             :     // Construct an iterator for selected borders. If it is valid, there is a selected border.
     957           0 :     return SelFrameBorderCIter( mxImpl->maEnabBorders ).Is();
     958             : }
     959             : 
     960           0 : void FrameSelector::SelectAllBorders( bool bSelect )
     961             : {
     962           0 :     for( FrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
     963           0 :         mxImpl->SelectBorder( **aIt, bSelect );
     964           0 : }
     965             : 
     966           0 : void FrameSelector::SelectAllVisibleBorders( bool bSelect )
     967             : {
     968           0 :     for( VisFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
     969           0 :         mxImpl->SelectBorder( **aIt, bSelect );
     970           0 : }
     971             : 
     972           0 : void FrameSelector::SetStyleToSelection( long nWidth, SvxBorderStyle nStyle )
     973             : {
     974           0 :     mxImpl->maCurrStyle.SetBorderLineStyle( nStyle );
     975           0 :     mxImpl->maCurrStyle.SetWidth( nWidth );
     976           0 :     for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
     977           0 :         mxImpl->SetBorderState( **aIt, FRAMESTATE_SHOW );
     978           0 : }
     979             : 
     980           0 : void FrameSelector::SetColorToSelection( const Color& rColor )
     981             : {
     982           0 :     mxImpl->maCurrStyle.SetColor( rColor );
     983           0 :     for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
     984           0 :         mxImpl->SetBorderState( **aIt, FRAMESTATE_SHOW );
     985           0 : }
     986             : 
     987             : // accessibility
     988           0 : Reference< XAccessible > FrameSelector::CreateAccessible()
     989             : {
     990           0 :     if( !mxImpl->mxAccess.is() )
     991           0 :         mxImpl->mxAccess = mxImpl->mpAccess =
     992           0 :             new a11y::AccFrameSelector( *this, FRAMEBORDER_NONE );
     993           0 :     return mxImpl->mxAccess;
     994             : }
     995             : 
     996           0 : Reference< XAccessible > FrameSelector::GetChildAccessible( FrameBorderType eBorder )
     997             : {
     998           0 :     Reference< XAccessible > xRet;
     999           0 :     size_t nVecIdx = static_cast< size_t >( eBorder );
    1000           0 :     if( IsBorderEnabled( eBorder ) && (1 <= nVecIdx) && (nVecIdx <= mxImpl->maChildVec.size()) )
    1001             :     {
    1002           0 :         --nVecIdx;
    1003           0 :         if( !mxImpl->maChildVec[ nVecIdx ] )
    1004           0 :             mxImpl->mxChildVec[ nVecIdx ] = mxImpl->maChildVec[ nVecIdx ] =
    1005           0 :                 new a11y::AccFrameSelector( *this, eBorder );
    1006           0 :         xRet = mxImpl->mxChildVec[ nVecIdx ];
    1007             :     }
    1008           0 :     return xRet;
    1009             : }
    1010             : 
    1011           0 : Reference< XAccessible > FrameSelector::GetChildAccessible( sal_Int32 nIndex )
    1012             : {
    1013           0 :     return GetChildAccessible( GetEnabledBorderType( nIndex ) );
    1014             : }
    1015             : 
    1016           0 : Reference< XAccessible > FrameSelector::GetChildAccessible( const Point& rPos )
    1017             : {
    1018           0 :     Reference< XAccessible > xRet;
    1019           0 :     for( FrameBorderCIter aIt( mxImpl->maEnabBorders ); !xRet.is() && aIt.Is(); ++aIt )
    1020           0 :         if( (*aIt)->ContainsClickPoint( rPos ) )
    1021           0 :             xRet = GetChildAccessible( (*aIt)->GetType() );
    1022           0 :     return xRet;
    1023             : }
    1024             : 
    1025           0 : bool FrameSelector::ContainsClickPoint( const Point& rPos ) const
    1026             : {
    1027           0 :     bool bContains = false;
    1028           0 :     for( FrameBorderCIter aIt( mxImpl->maEnabBorders ); !bContains && aIt.Is(); ++aIt )
    1029           0 :         bContains = (*aIt)->ContainsClickPoint( rPos );
    1030           0 :     return bContains;
    1031             : }
    1032             : 
    1033           0 : Rectangle FrameSelector::GetClickBoundRect( FrameBorderType eBorder ) const
    1034             : {
    1035           0 :     Rectangle aRect;
    1036           0 :     const FrameBorder& rBorder = mxImpl->GetBorder( eBorder );
    1037           0 :     if( rBorder.IsEnabled() )
    1038           0 :         aRect = rBorder.GetClickBoundRect();
    1039           0 :     return aRect;
    1040             : }
    1041             : 
    1042             : // virtual functions from base class
    1043           0 : void FrameSelector::Paint( const Rectangle& )
    1044             : {
    1045           0 :     mxImpl->CopyVirDevToControl();
    1046           0 :     if( HasFocus() )
    1047           0 :         mxImpl->DrawAllTrackingRects();
    1048           0 : }
    1049             : 
    1050           0 : void FrameSelector::MouseButtonDown( const MouseEvent& rMEvt )
    1051             : {
    1052             :     /*  Mouse handling:
    1053             :         * Click on an unselected frame border:
    1054             :             Set current style/color, make frame border visible, deselect all
    1055             :             other frame borders.
    1056             :         * Click on a selected frame border:
    1057             :             Toggle state of the frame border (visible -> don't care -> hidden),
    1058             :             deselect all other frame borders.
    1059             :         * SHIFT+Click or CTRL+Click on an unselected frame border:
    1060             :             Extend selection, set current style/color to all selected frame
    1061             :             borders independent of the state/style/color of the borders.
    1062             :         * SHIFT+Click or CTRL+Click on a selected frame border:
    1063             :             If all frame borders have same style/color, toggle state of all
    1064             :             borders (see above), otherwise set current style/color to all
    1065             :             borders.
    1066             :         * Click on unused area: Do not modify selection and selected frame
    1067             :             borders.
    1068             :      */
    1069             : 
    1070             :     // #107394# do not auto-select a frame border
    1071           0 :     mxImpl->SilentGrabFocus();
    1072             : 
    1073           0 :     if( rMEvt.IsLeft() )
    1074             :     {
    1075           0 :         Point aPos( mxImpl->GetDevPosFromMousePos( rMEvt.GetPosPixel() ) );
    1076           0 :         FrameBorderPtrVec aDeselectBorders;
    1077             : 
    1078           0 :         bool bAnyClicked = false;   // Any frame border clicked?
    1079           0 :         bool bNewSelected = false;  // Any unselected frame border selected?
    1080             : 
    1081             :         /*  If frame borders are set to "don't care" and the control does not
    1082             :             support this state, hide them on first mouse click.
    1083             :             DR 2004-01-30: Why are the borders set to "don't care" then?!? */
    1084           0 :         bool bHideDontCare = !mxImpl->mbClicked && !SupportsDontCareState();
    1085             : 
    1086           0 :         for( FrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
    1087             :         {
    1088           0 :             if( (*aIt)->ContainsClickPoint( aPos ) )
    1089             :             {
    1090             :                 // frame border is clicked
    1091           0 :                 bAnyClicked = true;
    1092           0 :                 if( !(*aIt)->IsSelected() )
    1093             :                 {
    1094           0 :                     bNewSelected = true;
    1095             :                     //mxImpl->SelectBorder( **aIt, true );
    1096           0 :                     SelectBorder((**aIt).GetType(), true);
    1097             :                 }
    1098             :             }
    1099             :             else
    1100             :             {
    1101             :                 // hide a "don't care" frame border only if it is not clicked
    1102           0 :                 if( bHideDontCare && ((*aIt)->GetState() == FRAMESTATE_DONTCARE) )
    1103           0 :                     mxImpl->SetBorderState( **aIt, FRAMESTATE_HIDE );
    1104             : 
    1105             :                 // deselect frame borders not clicked (if SHIFT or CTRL are not pressed)
    1106           0 :                 if( !rMEvt.IsShift() && !rMEvt.IsMod1() )
    1107           0 :                     aDeselectBorders.push_back( *aIt );
    1108             :             }
    1109             :         }
    1110             : 
    1111           0 :         if( bAnyClicked )
    1112             :         {
    1113             :             // any valid frame border clicked? -> deselect other frame borders
    1114           0 :             for( FrameBorderIter aIt( aDeselectBorders ); aIt.Is(); ++aIt )
    1115           0 :                 mxImpl->SelectBorder( **aIt, false );
    1116             : 
    1117           0 :             if( bNewSelected || !mxImpl->SelectedBordersEqual() )
    1118             :             {
    1119             :                 // new frame border selected, selection extended, or selected borders different? -> show
    1120           0 :                 for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
    1121             :                     // SetBorderState() sets current style and color to the frame border
    1122           0 :                     mxImpl->SetBorderState( **aIt, FRAMESTATE_SHOW );
    1123             :             }
    1124             :             else
    1125             :             {
    1126             :                 // all selected frame borders are equal -> toggle state
    1127           0 :                 for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
    1128           0 :                     mxImpl->ToggleBorderState( **aIt );
    1129             :             }
    1130             : 
    1131           0 :             GetSelectHdl().Call( this );
    1132           0 :         }
    1133             :     }
    1134           0 : }
    1135             : 
    1136           0 : void FrameSelector::KeyInput( const KeyEvent& rKEvt )
    1137             : {
    1138           0 :     bool bHandled = false;
    1139           0 :     vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
    1140           0 :     if( !aKeyCode.GetModifier() )
    1141             :     {
    1142           0 :         sal_uInt16 nCode = aKeyCode.GetCode();
    1143           0 :         switch( nCode )
    1144             :         {
    1145             :             case KEY_SPACE:
    1146             :             {
    1147           0 :                 for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
    1148           0 :                     mxImpl->ToggleBorderState( **aIt );
    1149           0 :                 bHandled = true;
    1150             :             }
    1151           0 :             break;
    1152             : 
    1153             :             case KEY_UP:
    1154             :             case KEY_DOWN:
    1155             :             case KEY_LEFT:
    1156             :             case KEY_RIGHT:
    1157             :             {
    1158           0 :                 if( !mxImpl->maEnabBorders.empty() )
    1159             :                 {
    1160             :                     // start from first selected frame border
    1161           0 :                     SelFrameBorderCIter aIt( mxImpl->maEnabBorders );
    1162           0 :                     FrameBorderType eBorder = aIt.Is() ? (*aIt)->GetType() : mxImpl->maEnabBorders.front()->GetType();
    1163             : 
    1164             :                     // search for next enabled frame border
    1165           0 :                     do
    1166             :                     {
    1167           0 :                         eBorder = mxImpl->GetBorder( eBorder ).GetKeyboardNeighbor( nCode );
    1168             :                     }
    1169           0 :                     while( (eBorder != FRAMEBORDER_NONE) && !IsBorderEnabled( eBorder ) );
    1170             : 
    1171             :                     // select the frame border
    1172           0 :                     if( eBorder != FRAMEBORDER_NONE )
    1173             :                     {
    1174           0 :                         DeselectAllBorders();
    1175           0 :                         SelectBorder( eBorder );
    1176             :                     }
    1177             :                 }
    1178             :             }
    1179           0 :             break;
    1180             :         }
    1181             :     }
    1182           0 :     if( !bHandled )
    1183           0 :         Window::KeyInput(rKEvt);
    1184           0 : }
    1185             : 
    1186           0 : void FrameSelector::GetFocus()
    1187             : {
    1188             :     // auto-selection of a frame border, if focus reaches control, and nothing is selected
    1189           0 :     if( mxImpl->mbAutoSelect && !IsAnyBorderSelected() && !mxImpl->maEnabBorders.empty() )
    1190           0 :         mxImpl->SelectBorder( *mxImpl->maEnabBorders.front(), true );
    1191             : 
    1192           0 :     mxImpl->DoInvalidate( false );
    1193           0 :     if( mxImpl->mxAccess.is() )
    1194           0 :         mxImpl->mpAccess->NotifyFocusListeners( true );
    1195           0 :     if (IsAnyBorderSelected())
    1196             :     {
    1197           0 :         FrameBorderType borderType = FRAMEBORDER_NONE;
    1198           0 :         if (mxImpl->maLeft.IsSelected())
    1199           0 :             borderType = FRAMEBORDER_LEFT;
    1200           0 :         else if (mxImpl->maRight.IsSelected())
    1201           0 :             borderType = FRAMEBORDER_RIGHT;
    1202           0 :         else if (mxImpl->maTop.IsSelected())
    1203           0 :             borderType = FRAMEBORDER_TOP;
    1204           0 :         else if (mxImpl->maBottom.IsSelected())
    1205           0 :             borderType = FRAMEBORDER_BOTTOM;
    1206           0 :         else if (mxImpl->maHor.IsSelected())
    1207           0 :             borderType = FRAMEBORDER_HOR;
    1208           0 :         else if (mxImpl->maVer.IsSelected())
    1209           0 :             borderType = FRAMEBORDER_VER;
    1210           0 :         else if (mxImpl->maTLBR.IsSelected())
    1211           0 :             borderType = FRAMEBORDER_TLBR;
    1212           0 :         else if (mxImpl->maBLTR.IsSelected())
    1213           0 :             borderType = FRAMEBORDER_BLTR;
    1214           0 :         SelectBorder(borderType);
    1215             :     }
    1216           0 :     for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
    1217           0 :             mxImpl->SetBorderState( **aIt, FRAMESTATE_SHOW );
    1218           0 :     Control::GetFocus();
    1219           0 : }
    1220             : 
    1221           0 : void FrameSelector::LoseFocus()
    1222             : {
    1223           0 :     mxImpl->DoInvalidate( false );
    1224           0 :     if( mxImpl->mxAccess.is() )
    1225           0 :         mxImpl->mpAccess->NotifyFocusListeners( false );
    1226           0 :     Control::LoseFocus();
    1227           0 : }
    1228             : 
    1229           0 : void FrameSelector::DataChanged( const DataChangedEvent& rDCEvt )
    1230             : {
    1231           0 :     Control::DataChanged( rDCEvt );
    1232           0 :     if( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
    1233           0 :         mxImpl->InitVirtualDevice();
    1234           0 : }
    1235             : 
    1236           0 : void FrameSelector::Resize()
    1237             : {
    1238           0 :     Control::Resize();
    1239           0 :     mxImpl->sizeChanged();
    1240           0 : }
    1241             : 
    1242           0 : Size FrameSelector::GetOptimalSize() const
    1243             : {
    1244           0 :     return LogicToPixel(Size(61, 65), MAP_APPFONT);
    1245             : }
    1246             : 
    1247             : 
    1248             : 
    1249             : template< typename Cont, typename Iter, typename Pred >
    1250           0 : FrameBorderIterBase< Cont, Iter, Pred >::FrameBorderIterBase( container_type& rCont ) :
    1251             :     maIt( rCont.begin() ),
    1252           0 :     maEnd( rCont.end() )
    1253             : {
    1254           0 :     while( Is() && !maPred( *maIt ) ) ++maIt;
    1255           0 : }
    1256             : 
    1257             : template< typename Cont, typename Iter, typename Pred >
    1258           0 : FrameBorderIterBase< Cont, Iter, Pred >& FrameBorderIterBase< Cont, Iter, Pred >::operator++()
    1259             : {
    1260           0 :     do { ++maIt; } while( Is() && !maPred( *maIt ) );
    1261           0 :     return *this;
    1262             : }
    1263             : 
    1264             : 
    1265             : 
    1266         594 : } // namespace svx
    1267             : 
    1268             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10