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

Generated by: LCOV version 1.10