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