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

Generated by: LCOV version 1.10