LibreOffice Module svx (master)  1
frmsel.cxx
Go to the documentation of this file.
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 <sal/config.h>
21 
22 #include <o3tl/safeint.hxx>
23 #include <svx/frmsel.hxx>
24 #include <vcl/event.hxx>
25 #include <sal/log.hxx>
26 #include <tools/debug.hxx>
27 
28 #include <algorithm>
29 #include <math.h>
30 #include <string_view>
31 
32 #include <frmselimpl.hxx>
34 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
35 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
36 #include <vcl/settings.hxx>
37 #include <vcl/svapp.hxx>
40 
41 #include <bitmaps.hlst>
42 
43 using namespace ::com::sun::star;
44 using namespace ::editeng;
45 
46 namespace svx {
47 
48 using ::com::sun::star::uno::Reference;
49 using ::com::sun::star::uno::Any;
50 using ::com::sun::star::accessibility::XAccessible;
51 using namespace ::com::sun::star::accessibility;
52 
53 // global functions from framebordertype.hxx
54 
56 {
58  "svx::GetFrameBorderTypeFromIndex - invalid index" );
59  return static_cast< FrameBorderType >( nIndex + 1 );
60 }
61 
63 {
65  "svx::GetIndexFromFrameBorderType - invalid frame border type" );
66  return static_cast< size_t >( eBorder ) - 1;
67 }
68 
69 namespace
70 {
71 
73 const long FRAMESEL_GEOM_OUTER = 2;
74 
76 const long FRAMESEL_GEOM_INNER = 3;
77 
79 const long FRAMESEL_GEOM_WIDTH = 9;
80 
82 const long FRAMESEL_GEOM_ADD_CLICK_OUTER = 5;
83 
85 const long FRAMESEL_GEOM_ADD_CLICK_INNER = 2;
86 
87 
89 FrameSelFlags lclGetFlagFromType( FrameBorderType eBorder )
90 {
91  switch( eBorder )
92  {
101  case FrameBorderType::NONE : break;
102  }
103  return FrameSelFlags::NONE;
104 }
105 
107 void lclPolyPolyUnion( tools::PolyPolygon& rDest, const tools::PolyPolygon& rSource )
108 {
109  const tools::PolyPolygon aTmp( rDest );
110  aTmp.GetUnion( rSource, rDest );
111 }
112 
113 } // namespace
114 
116  meType( eType ),
117  meState( FrameBorderState::Hide ),
118  meKeyLeft( FrameBorderType::NONE ),
119  meKeyRight( FrameBorderType::NONE ),
120  meKeyTop( FrameBorderType::NONE ),
121  meKeyBottom( FrameBorderType::NONE ),
122  mbEnabled( false ),
123  mbSelected( false )
124 {
125 }
126 
128 {
129  mbEnabled = bool(nFlags & lclGetFlagFromType( meType ));
130  if( !mbEnabled )
132 }
133 
134 void FrameBorder::SetCoreStyle( const SvxBorderLine* pStyle )
135 {
136  if( pStyle )
137  maCoreStyle = *pStyle;
138  else
139  maCoreStyle = SvxBorderLine();
140 
141  // from twips to points
142  maUIStyle.Set( &maCoreStyle, FrameBorder::GetDefaultPatternScale(), FRAMESEL_GEOM_WIDTH );
144 }
145 
147 {
148  meState = eState;
149  switch( meState )
150  {
152  SAL_WARN( "svx.dialog", "svx::FrameBorder::SetState - use SetCoreStyle to make border visible" );
153  break;
155  maCoreStyle = SvxBorderLine();
156  maUIStyle.Clear();
157  break;
159  maCoreStyle = SvxBorderLine();
160  maUIStyle = frame::Style(3, 0, 0, SvxBorderLineStyle::SOLID, FrameBorder::GetDefaultPatternScale()); //OBJ_FRAMESTYLE_DONTCARE
161  break;
162  }
163 }
164 
166 {
167  lclPolyPolyUnion( maFocusArea, rFocus );
168 }
169 
171 {
172  lclPolyPolyUnion( rPPoly, maFocusArea );
173 }
174 
176 {
177  lclPolyPolyUnion( maClickArea, tools::Polygon( rRect ) );
178 }
179 
180 bool FrameBorder::ContainsClickPoint( const Point& rPos ) const
181 {
182  return vcl::Region( maClickArea ).IsInside( rPos );
183 }
184 
186 {
187  return maClickArea.GetBoundRect();
188 }
189 
191  FrameBorderType eLeft, FrameBorderType eRight, FrameBorderType eTop, FrameBorderType eBottom )
192 {
193  meKeyLeft = eLeft;
194  meKeyRight = eRight;
195  meKeyTop = eTop;
196  meKeyBottom = eBottom;
197 }
198 
200 {
202  switch( nKeyCode )
203  {
204  case KEY_LEFT: eBorder = meKeyLeft; break;
205  case KEY_RIGHT: eBorder = meKeyRight; break;
206  case KEY_UP: eBorder = meKeyTop; break;
207  case KEY_DOWN: eBorder = meKeyBottom; break;
208  default: SAL_WARN( "svx.dialog", "svx::FrameBorder::GetKeyboardNeighbor - unknown key code" );
209  }
210  return eBorder;
211 }
212 
214  mrFrameSel( rFrameSel ),
215  mpVirDev( VclPtr<VirtualDevice>::Create() ),
220  maHor( FrameBorderType::Horizontal ),
221  maVer( FrameBorderType::Vertical ),
225  mnCtrlSize( 0 ),
226  mnArrowSize( 0 ),
227  mnLine1( 0 ),
228  mnLine2( 0 ),
229  mnLine3( 0 ),
230  mnFocusOffs( 0 ),
231  mbHor( false ),
232  mbVer( false ),
233  mbTLBR( false ),
234  mbBLTR( false ),
235  mbFullRepaint( true ),
236  mbAutoSelect( true ),
237  mbHCMode( false ),
238  maChildVec( 8 )
239 {
240  maAllBorders.resize( FRAMEBORDERTYPE_COUNT, nullptr );
249 #if OSL_DEBUG_LEVEL >= 2
250  {
251  bool bOk = true;
252  for( FrameBorderCIter aIt( maAllBorders ); bOk && aIt.Is(); bOk = (*aIt != 0), ++aIt );
253  DBG_ASSERT( bOk, "svx::FrameSelectorImpl::FrameSelectorImpl - missing entry in maAllBorders" );
254  }
255 #endif
256  // left neighbor right neighbor upper neighbor lower neighbor
265 
267 }
268 
270 
271 {
272  for( auto& rpChild : maChildVec )
273  if( rpChild.is() )
274  rpChild->Invalidate();
275 }
276 
277 // initialization
279 {
280  mnFlags = nFlags;
281 
282  maEnabBorders.clear();
283  for( FrameBorderIter aIt( maAllBorders ); aIt.Is(); ++aIt )
284  {
285  (*aIt)->Enable( mnFlags );
286  if( (*aIt)->IsEnabled() )
287  maEnabBorders.push_back( *aIt );
288  }
289  mbHor = maHor.IsEnabled();
290  mbVer = maVer.IsEnabled();
291  mbTLBR = maTLBR.IsEnabled();
292  mbBLTR = maBLTR.IsEnabled();
293 
295 }
296 
298 {
300  maBackCol = rSettings.GetFieldColor();
301  mbHCMode = rSettings.GetHighContrastMode();
302  maArrowCol = rSettings.GetFieldTextColor();
303  maMarkCol.operator=(maBackCol).Merge(maArrowCol, mbHCMode ? 0x80 : 0xC0);
304  maHCLineCol = rSettings.GetLabelTextColor();
305 }
306 
307 const std::u16string_view aImageIds[] =
308 {
309  u"" RID_SVXBMP_FRMSEL_ARROW1,
310  u"" RID_SVXBMP_FRMSEL_ARROW2,
311  u"" RID_SVXBMP_FRMSEL_ARROW3,
312  u"" RID_SVXBMP_FRMSEL_ARROW4,
313  u"" RID_SVXBMP_FRMSEL_ARROW5,
314  u"" RID_SVXBMP_FRMSEL_ARROW6,
315  u"" RID_SVXBMP_FRMSEL_ARROW7,
316  u"" RID_SVXBMP_FRMSEL_ARROW8,
317  u"" RID_SVXBMP_FRMSEL_ARROW9,
318  u"" RID_SVXBMP_FRMSEL_ARROW10,
319  u"" RID_SVXBMP_FRMSEL_ARROW11,
320  u"" RID_SVXBMP_FRMSEL_ARROW12,
321  u"" RID_SVXBMP_FRMSEL_ARROW13,
322  u"" RID_SVXBMP_FRMSEL_ARROW14,
323  u"" RID_SVXBMP_FRMSEL_ARROW15,
324  u"" RID_SVXBMP_FRMSEL_ARROW16
325 };
326 
328 {
329  maArrows.clear();
330 
331  /* Build the arrow images bitmap with current colors. */
332  Color pColorAry1[3];
333  Color pColorAry2[3];
334  pColorAry1[0] = Color( 0, 0, 0 );
335  pColorAry2[0] = maArrowCol; // black -> arrow color
336  pColorAry1[1] = Color( 0, 255, 0 );
337  pColorAry2[1] = maMarkCol; // green -> marker color
338  pColorAry1[2] = Color( 255, 0, 255 );
339  pColorAry2[2] = maBackCol; // magenta -> background
340 
341  assert(SAL_N_ELEMENTS(aImageIds) == 16);
342  for (size_t i = 0; i < SAL_N_ELEMENTS(aImageIds); ++i)
343  {
344  BitmapEx aBmpEx(aImageIds[i]);
345  aBmpEx.Replace(pColorAry1, pColorAry2, 3);
346  maArrows.emplace_back(aBmpEx);
347  }
348  assert(maArrows.size() == 16);
349 
350  mnArrowSize = maArrows[0].GetSizePixel().Height();
351 }
352 
354 {
355  Size aCtrlSize(mrFrameSel.GetOutputSizePixel());
356  /* nMinSize is the lower of width and height (control will always be squarish).
357  FRAMESEL_GEOM_OUTER is the minimal distance between inner control border
358  and any element. */
359  long nMinSize = std::min( aCtrlSize.Width(), aCtrlSize.Height() ) - 2 * FRAMESEL_GEOM_OUTER;
360  /* nFixedSize is the size all existing elements need in one direction:
361  the diag. arrow, space betw. arrow and frame border, outer frame border,
362  inner frame border, other outer frame border, space betw. frame border
363  and arrow, the other arrow. */
364  long nFixedSize = 2 * mnArrowSize + 2 * FRAMESEL_GEOM_INNER + 3 * FRAMESEL_GEOM_WIDTH;
365  /* nBetwBordersSize contains the size between an outer and inner frame border (made odd). */
366  long nBetwBordersSize = (((nMinSize - nFixedSize) / 2) - 1) | 1;
367 
368  /* The final size of the usable area. At least do not get negative */
369  mnCtrlSize = 2 * nBetwBordersSize + nFixedSize;
370  mnCtrlSize = std::max(mnCtrlSize, static_cast<long>(0));
371  mpVirDev->SetOutputSizePixel( Size( mnCtrlSize, mnCtrlSize ) );
372 
373  /* Center the virtual device in the control. */
374  maVirDevPos = Point( (aCtrlSize.Width() - mnCtrlSize) / 2, (aCtrlSize.Height() - mnCtrlSize) / 2 );
375 }
376 
378 {
379  size_t nCol, nCols, nRow, nRows;
380 
381  // Global border geometry values
382  /* mnLine* is the middle point inside a frame border (i.e. mnLine1 is mid X inside left border). */
383  mnLine1 = mnArrowSize + FRAMESEL_GEOM_INNER + FRAMESEL_GEOM_WIDTH / 2;
384  mnLine2 = mnCtrlSize / 2;
385  mnLine3 = 2 * mnLine2 - mnLine1;
386 
387  // Frame helper array
388  maArray.Initialize( mbVer ? 2 : 1, mbHor ? 2 : 1 );
389 
390  maArray.SetXOffset( mnLine1 );
391  maArray.SetAllColWidths( (mbVer ? mnLine2 : mnLine3) - mnLine1 );
392 
393  maArray.SetYOffset( mnLine1 );
394  maArray.SetAllRowHeights( (mbHor ? mnLine2 : mnLine3) - mnLine1 );
395 
396  // Focus polygons
397  /* Width for focus rectangles from center of frame borders. */
398  mnFocusOffs = FRAMESEL_GEOM_WIDTH / 2 + 1;
399 
406 
407  maLeft.AddFocusPolygon( tools::Rectangle( mnLine1 - mnFocusOffs, mnLine1 - mnFocusOffs, mnLine1 + mnFocusOffs, mnLine3 + mnFocusOffs ) );
409  maRight.AddFocusPolygon( tools::Rectangle( mnLine3 - mnFocusOffs, mnLine1 - mnFocusOffs, mnLine3 + mnFocusOffs, mnLine3 + mnFocusOffs ) );
410  maTop.AddFocusPolygon( tools::Rectangle( mnLine1 - mnFocusOffs, mnLine1 - mnFocusOffs, mnLine3 + mnFocusOffs, mnLine1 + mnFocusOffs ) );
412  maBottom.AddFocusPolygon( tools::Rectangle( mnLine1 - mnFocusOffs, mnLine3 - mnFocusOffs, mnLine3 + mnFocusOffs, mnLine3 + mnFocusOffs ) );
413 
414  for( nCol = 0, nCols = maArray.GetColCount(); nCol < nCols; ++nCol )
415  {
416  for( nRow = 0, nRows = maArray.GetRowCount(); nRow < nRows; ++nRow )
417  {
418  const basegfx::B2DRange aCellRange(maArray.GetCellRange( nCol, nRow, true ));
419  const tools::Rectangle aRect(
420  basegfx::fround(aCellRange.getMinX()), basegfx::fround(aCellRange.getMinY()),
421  basegfx::fround(aCellRange.getMaxX()), basegfx::fround(aCellRange.getMaxY()));
422  const double fHorDiagAngle(atan2(fabs(aCellRange.getHeight()), fabs(aCellRange.getWidth())));
423  const double fVerDiagAngle(fHorDiagAngle > 0.0 ? F_PI2 - fHorDiagAngle : 0.0);
424  const long nDiagFocusOffsX(basegfx::fround(-mnFocusOffs / tan(fHorDiagAngle) + mnFocusOffs / sin(fHorDiagAngle)));
425  const long nDiagFocusOffsY(basegfx::fround(-mnFocusOffs / tan(fVerDiagAngle) + mnFocusOffs / sin(fVerDiagAngle)));
426 
427  std::vector< Point > aFocusVec;
428  aFocusVec.emplace_back( aRect.Left() - mnFocusOffs, aRect.Top() + nDiagFocusOffsY );
429  aFocusVec.emplace_back( aRect.Left() - mnFocusOffs, aRect.Top() - mnFocusOffs );
430  aFocusVec.emplace_back( aRect.Left() + nDiagFocusOffsX, aRect.Top() - mnFocusOffs );
431  aFocusVec.emplace_back( aRect.Right() + mnFocusOffs, aRect.Bottom() - nDiagFocusOffsY );
432  aFocusVec.emplace_back( aRect.Right() + mnFocusOffs, aRect.Bottom() + mnFocusOffs );
433  aFocusVec.emplace_back( aRect.Right() - nDiagFocusOffsX, aRect.Bottom() + mnFocusOffs );
434  maTLBR.AddFocusPolygon( tools::Polygon( static_cast< sal_uInt16 >( aFocusVec.size() ), aFocusVec.data() ) );
435 
436  aFocusVec.clear();
437  aFocusVec.emplace_back( aRect.Right() + mnFocusOffs, aRect.Top() + nDiagFocusOffsY );
438  aFocusVec.emplace_back( aRect.Right() + mnFocusOffs, aRect.Top() - mnFocusOffs );
439  aFocusVec.emplace_back( aRect.Right() - nDiagFocusOffsX, aRect.Top() - mnFocusOffs );
440  aFocusVec.emplace_back( aRect.Left() - mnFocusOffs, aRect.Bottom() - nDiagFocusOffsY );
441  aFocusVec.emplace_back( aRect.Left() - mnFocusOffs, aRect.Bottom() + mnFocusOffs );
442  aFocusVec.emplace_back( aRect.Left() + nDiagFocusOffsX, aRect.Bottom() + mnFocusOffs );
443  maBLTR.AddFocusPolygon( tools::Polygon( static_cast< sal_uInt16 >( aFocusVec.size() ), aFocusVec.data() ) );
444  }
445  }
446 
447  // Click areas
448  for( FrameBorderIter aIt( maAllBorders ); aIt.Is(); ++aIt )
449  (*aIt)->ClearClickArea();
450 
451  /* Additional space for click area: is added to the space available to draw
452  the frame borders. For instance left frame border:
453  - To left, top, and bottom always big additional space (outer area).
454  - To right: Dependent on existence of inner vertical frame border
455  (if enabled, use less space).
456  */
457  long nClO = FRAMESEL_GEOM_WIDTH / 2 + FRAMESEL_GEOM_ADD_CLICK_OUTER;
458  long nClI = (mbTLBR && mbBLTR) ? (FRAMESEL_GEOM_WIDTH / 2 + FRAMESEL_GEOM_ADD_CLICK_INNER) : nClO;
459  long nClH = mbHor ? nClI : nClO; // additional space dependent of horizontal inner border
460  long nClV = mbVer ? nClI : nClO; // additional space dependent of vertical inner border
461 
462  maLeft.AddClickRect( tools::Rectangle( mnLine1 - nClO, mnLine1 - nClO, mnLine1 + nClV, mnLine3 + nClO ) );
463  maVer.AddClickRect( tools::Rectangle( mnLine2 - nClI, mnLine1 - nClO, mnLine2 + nClI, mnLine3 + nClO ) );
464  maRight.AddClickRect( tools::Rectangle( mnLine3 - nClV, mnLine1 - nClO, mnLine3 + nClO, mnLine3 + nClO ) );
465  maTop.AddClickRect( tools::Rectangle( mnLine1 - nClO, mnLine1 - nClO, mnLine3 + nClO, mnLine1 + nClH ) );
466  maHor.AddClickRect( tools::Rectangle( mnLine1 - nClO, mnLine2 - nClI, mnLine3 + nClO, mnLine2 + nClI ) );
467  maBottom.AddClickRect( tools::Rectangle( mnLine1 - nClO, mnLine3 - nClH, mnLine3 + nClO, mnLine3 + nClO ) );
468 
469  /* Diagonal frame borders use the remaining space between outer and inner frame borders. */
470  if( !(mbTLBR || mbBLTR) )
471  return;
472 
473  for( nCol = 0, nCols = maArray.GetColCount(); nCol < nCols; ++nCol )
474  {
475  for( nRow = 0, nRows = maArray.GetRowCount(); nRow < nRows; ++nRow )
476  {
477  // the usable area between horizontal/vertical frame borders of current quadrant
478  const basegfx::B2DRange aCellRange(maArray.GetCellRange( nCol, nRow, true ));
479  const tools::Rectangle aRect(
480  basegfx::fround(aCellRange.getMinX()) + nClV + 1, basegfx::fround(aCellRange.getMinY()) + nClH + 1,
481  basegfx::fround(aCellRange.getMaxX()) - nClV + 1, basegfx::fround(aCellRange.getMaxY()) - nClH + 1);
482 
483  /* Both diagonal frame borders enabled. */
484  if( mbTLBR && mbBLTR )
485  {
486  // single areas
487  Point aMid( aRect.Center() );
488  maTLBR.AddClickRect( tools::Rectangle( aRect.TopLeft(), aMid ) );
489  maTLBR.AddClickRect( tools::Rectangle( aMid + Point( 1, 1 ), aRect.BottomRight() ) );
490  maBLTR.AddClickRect( tools::Rectangle( aRect.Left(), aMid.Y() + 1, aMid.X(), aRect.Bottom() ) );
491  maBLTR.AddClickRect( tools::Rectangle( aMid.X() + 1, aRect.Top(), aRect.Right(), aMid.Y() ) );
492  // centered rectangle for both frame borders
493  tools::Rectangle aMidRect( aRect.TopLeft(), Size( aRect.GetWidth() / 3, aRect.GetHeight() / 3 ) );
494  aMidRect.Move( (aRect.GetWidth() - aMidRect.GetWidth()) / 2, (aRect.GetHeight() - aMidRect.GetHeight()) / 2 );
495  maTLBR.AddClickRect( aMidRect );
496  maBLTR.AddClickRect( aMidRect );
497  }
498  /* One of the diagonal frame borders enabled - use entire rectangle. */
499  else if( mbTLBR && !mbBLTR ) // top-left to bottom-right only
500  maTLBR.AddClickRect( aRect );
501  else if( !mbTLBR && mbBLTR ) // bottom-left to top-right only
502  maBLTR.AddClickRect( aRect );
503  }
504  }
505 }
506 
508 {
509  // initialize resources
510  InitColors();
512 
513  sizeChanged();
514 }
515 
517 {
518  // initialize geometry
521 
522  DoInvalidate( true );
523 }
524 
525 // frame border access
527 {
528  size_t nIndex = GetIndexFromFrameBorderType( eBorder );
529  if( nIndex < maAllBorders.size() )
530  return *maAllBorders[ nIndex ];
531  SAL_WARN( "svx.dialog", "svx::FrameSelectorImpl::GetBorder - unknown border type" );
532  return maTop;
533 }
534 
536 {
537  return const_cast< FrameBorder& >( GetBorder( eBorder ) );
538 }
539 
540 // drawing
542 {
543  // clear the area
544  mpVirDev->SetLineColor();
545  mpVirDev->SetFillColor( maBackCol );
546  mpVirDev->DrawRect( tools::Rectangle( Point( 0, 0 ), mpVirDev->GetOutputSizePixel() ) );
547 
548  // draw the inner gray (or whatever color) rectangle
549  mpVirDev->SetLineColor();
550  mpVirDev->SetFillColor( maMarkCol );
551  mpVirDev->DrawRect( tools::Rectangle(
553 
554  // draw the white space for enabled frame borders
555  tools::PolyPolygon aPPoly;
556  for( FrameBorderCIter aIt( maEnabBorders ); aIt.Is(); ++aIt )
557  (*aIt)->MergeFocusToPolyPolygon( aPPoly );
558  aPPoly.Optimize( PolyOptimizeFlags::CLOSE );
559  mpVirDev->SetLineColor( maBackCol );
560  mpVirDev->SetFillColor( maBackCol );
561  mpVirDev->DrawPolyPolygon( aPPoly );
562 }
563 
565 {
566  DBG_ASSERT( rBorder.IsEnabled(), "svx::FrameSelectorImpl::DrawArrows - access to disabled border" );
567 
568  long nLinePos = 0;
569  switch( rBorder.GetType() )
570  {
572  case FrameBorderType::Top: nLinePos = mnLine1; break;
574  case FrameBorderType::Horizontal: nLinePos = mnLine2; break;
576  case FrameBorderType::Bottom: nLinePos = mnLine3; break;
577  default: ; //prevent warning
578  }
579  nLinePos -= mnArrowSize / 2;
580 
581  long nTLPos = 0;
582  long nBRPos = mnCtrlSize - mnArrowSize;
583  Point aPos1, aPos2;
584  int nImgIndex1 = -1, nImgIndex2 = -1;
585  switch( rBorder.GetType() )
586  {
590  aPos1 = Point( nLinePos, nTLPos ); nImgIndex1 = 0;
591  aPos2 = Point( nLinePos, nBRPos ); nImgIndex2 = 1;
592  break;
593 
597  aPos1 = Point( nTLPos, nLinePos ); nImgIndex1 = 2;
598  aPos2 = Point( nBRPos, nLinePos ); nImgIndex2 = 3;
599  break;
600 
602  aPos1 = Point( nTLPos, nTLPos ); nImgIndex1 = 4;
603  aPos2 = Point( nBRPos, nBRPos ); nImgIndex2 = 5;
604  break;
606  aPos1 = Point( nTLPos, nBRPos ); nImgIndex1 = 6;
607  aPos2 = Point( nBRPos, nTLPos ); nImgIndex2 = 7;
608  break;
609  default: ; //prevent warning
610  }
611 
612  // Arrow or marker? Do not draw arrows into disabled control.
613  sal_uInt16 nSelectAdd = (mrFrameSel.IsEnabled() && rBorder.IsSelected()) ? 0 : 8;
614  if (nImgIndex1 >= 0)
615  mpVirDev->DrawImage(aPos1, maArrows[nImgIndex1 + nSelectAdd]);
616  if (nImgIndex2 >= 0)
617  mpVirDev->DrawImage(aPos2, maArrows[nImgIndex2 + nSelectAdd]);
618 }
619 
621 {
622  Color aColor( mbHCMode ? maHCLineCol : rColor );
623  if( aColor == maBackCol )
624  aColor.Invert();
625  return aColor;
626 }
627 
629 {
630  // Translate core colors to current UI colors (regards current background and HC mode).
631  for( FrameBorderIter aIt( maEnabBorders ); aIt.Is(); ++aIt )
632  {
633  Color aCoreColorPrim = ((*aIt)->GetState() == FrameBorderState::DontCare) ? maMarkCol : (*aIt)->GetCoreStyle().GetColorOut();
634  Color aCoreColorSecn = ((*aIt)->GetState() == FrameBorderState::DontCare) ? maMarkCol : (*aIt)->GetCoreStyle().GetColorIn();
635  (*aIt)->SetUIColorPrim( GetDrawLineColor( aCoreColorPrim ) );
636  (*aIt)->SetUIColorSecn( GetDrawLineColor( aCoreColorSecn ) );
637  }
638 
639  // Copy all frame border styles to the helper array
642 
643  // Invert the style for the right line
644  const frame::Style rRightStyle = maRight.GetUIStyle( );
645  frame::Style rInvertedRight( rRightStyle.GetColorPrim(),
646  rRightStyle.GetColorSecn(), rRightStyle.GetColorGap(),
647  rRightStyle.UseGapColor(),
648  rRightStyle.Secn(), rRightStyle.Dist(), rRightStyle.Prim( ),
649  rRightStyle.Type( ), rRightStyle.PatternScale() );
650  maArray.SetColumnStyleRight( mbVer ? 1 : 0, rInvertedRight );
651 
653  if( mbHor )
654  {
655  // Invert the style for the hor line to match the real borders
656  const frame::Style rHorStyle = maHor.GetUIStyle();
657  frame::Style rInvertedHor( rHorStyle.GetColorPrim(),
658  rHorStyle.GetColorSecn(), rHorStyle.GetColorGap(),
659  rHorStyle.UseGapColor(),
660  rHorStyle.Secn(), rHorStyle.Dist(), rHorStyle.Prim( ),
661  rHorStyle.Type(), rHorStyle.PatternScale() );
662  maArray.SetRowStyleTop( 1, rInvertedHor );
663  }
664 
665  // Invert the style for the bottom line
666  const frame::Style rBottomStyle = maBottom.GetUIStyle( );
667  frame::Style rInvertedBottom( rBottomStyle.GetColorPrim(),
668  rBottomStyle.GetColorSecn(), rBottomStyle.GetColorGap(),
669  rBottomStyle.UseGapColor(),
670  rBottomStyle.Secn(), rBottomStyle.Dist(), rBottomStyle.Prim( ),
671  rBottomStyle.Type(), rBottomStyle.PatternScale() );
672  maArray.SetRowStyleBottom( mbHor ? 1 : 0, rInvertedBottom );
673 
674  for( size_t nCol = 0; nCol < maArray.GetColCount(); ++nCol )
675  for( size_t nRow = 0; nRow < maArray.GetRowCount(); ++nRow )
677 
678  // This is used in the dialog/control for 'Border' attributes. When using
679  // the original paint below instead of primitives, the advantage currently
680  // is the correct visualization of diagonal line(s) including overlaying,
681  // but the rest is bad. Since the edit views use primitives and the preview
682  // should be 'real' I opt for also changing this to primitives. I will
683  // keep the old solution and add a switch (above) based on a static bool so
684  // that interested people may test this out in the debugger.
685  // This is one more hint to enhance the primitive visualization further to
686  // support diagonals better - that's the way to go.
687  const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D;
688  std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D(
690  *mpVirDev,
691  aNewViewInformation2D));
692 
693  if (pProcessor2D)
694  {
695  pProcessor2D->process(maArray.CreateB2DPrimitiveArray());
696  pProcessor2D.reset();
697  }
698 }
699 
701 {
702  DrawBackground();
703  for(FrameBorderCIter aIt(maEnabBorders); aIt.Is(); ++aIt)
704  DrawArrows(**aIt);
706  mbFullRepaint = false;
707 }
708 
710 {
711  if (mbFullRepaint)
713  rRenderContext.DrawBitmapEx(maVirDevPos, mpVirDev->GetBitmapEx(Point(0, 0), mpVirDev->GetOutputSizePixel()));
714 }
715 
717 {
718  tools::PolyPolygon aPPoly;
720  {
721  for(SelFrameBorderCIter aIt( maEnabBorders ); aIt.Is(); ++aIt)
722  (*aIt)->MergeFocusToPolyPolygon(aPPoly);
723  aPPoly.Move(maVirDevPos.X(), maVirDevPos.Y());
724  }
725  else
726  // no frame border selected -> draw tracking rectangle around entire control
727  aPPoly.Insert( tools::Polygon(tools::Rectangle(maVirDevPos, mpVirDev->GetOutputSizePixel())));
728 
729  aPPoly.Optimize(PolyOptimizeFlags::CLOSE);
730 
731  for(sal_uInt16 nIdx = 0, nCount = aPPoly.Count(); nIdx < nCount; ++nIdx)
732  rRenderContext.Invert(aPPoly.GetObject(nIdx), InvertFlags::TrackFrame);
733 }
734 
735 Point FrameSelectorImpl::GetDevPosFromMousePos( const Point& rMousePos ) const
736 {
737  return rMousePos - maVirDevPos;
738 }
739 
740 void FrameSelectorImpl::DoInvalidate( bool bFullRepaint )
741 {
742  mbFullRepaint |= bFullRepaint;
744 }
745 
746 // frame border state and style
748 {
749  DBG_ASSERT( rBorder.IsEnabled(), "svx::FrameSelectorImpl::SetBorderState - access to disabled border" );
750  Any aOld;
751  Any aNew;
752  Any& rMod = eState == FrameBorderState::Show ? aNew : aOld;
753  rMod <<= AccessibleStateType::CHECKED;
755  size_t nVecIdx = static_cast< size_t >( rBorder.GetType() );
756  if( GetBorder(rBorder.GetType()).IsEnabled() && (1 <= nVecIdx) && (nVecIdx <= maChildVec.size()) )
757  xRet = maChildVec[ --nVecIdx ].get();
758 
759  if( eState == FrameBorderState::Show )
760  SetBorderCoreStyle( rBorder, &maCurrStyle );
761  else
762  rBorder.SetState( eState );
763  if (xRet.is())
764  xRet->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOld, aNew );
765  DoInvalidate( true );
766 }
767 
768 void FrameSelectorImpl::SetBorderCoreStyle( FrameBorder& rBorder, const SvxBorderLine* pStyle )
769 {
770  DBG_ASSERT( rBorder.IsEnabled(), "svx::FrameSelectorImpl::SetBorderCoreStyle - access to disabled border" );
771  rBorder.SetCoreStyle( pStyle );
772  DoInvalidate( true );
773 }
774 
776 {
777  bool bDontCare = mrFrameSel.SupportsDontCareState();
778  switch( rBorder.GetState() )
779  {
780  // same order as tristate check box: visible -> don't care -> hidden
783  break;
784  case FrameBorderState::Hide:
786  break;
788  SetBorderState( rBorder, FrameBorderState::Hide );
789  break;
790  }
791 }
792 
793 // frame border selection
794 void FrameSelectorImpl::SelectBorder( FrameBorder& rBorder, bool bSelect )
795 {
796  DBG_ASSERT( rBorder.IsEnabled(), "svx::FrameSelectorImpl::SelectBorder - access to disabled border" );
797  rBorder.Select( bSelect );
798  DrawArrows( rBorder );
799  DoInvalidate( false );
800 }
801 
803 {
804  bool bOldAuto = mbAutoSelect;
805  mbAutoSelect = false;
807  mbAutoSelect = bOldAuto;
808 }
809 
811 {
812  bool bEqual = true;
814  if( aIt.Is() )
815  {
816  const SvxBorderLine& rFirstStyle = (*aIt)->GetCoreStyle();
817  for( ++aIt; bEqual && aIt.Is(); ++aIt )
818  bEqual = ((*aIt)->GetCoreStyle() == rFirstStyle);
819  }
820  return bEqual;
821 }
822 
824 {
825 }
826 
828 {
829  CustomWidgetController::SetDrawingArea(pDrawingArea);
830  Size aPrefSize = pDrawingArea->get_ref_device().LogicToPixel(Size(61, 65), MapMode(MapUnit::MapAppFont));
831  pDrawingArea->set_size_request(aPrefSize.Width(), aPrefSize.Height());
832  mxImpl.reset( new FrameSelectorImpl( *this ) );
833  EnableRTL( false ); // #107808# don't mirror the mouse handling
834 }
835 
837 {
838  if( mxAccess.is() )
839  mxAccess->Invalidate();
840 }
841 
843 {
844  mxImpl->Initialize( nFlags );
845  Show();
846 }
847 
848 // enabled frame borders
850 {
851  return mxImpl->GetBorder( eBorder ).IsEnabled();
852 }
853 
855 {
856  return static_cast< sal_Int32 >( mxImpl->maEnabBorders.size() );
857 }
858 
860 {
862  if( nIndex >= 0 )
863  {
864  size_t nVecIdx = static_cast< size_t >( nIndex );
865  if( nVecIdx < mxImpl->maEnabBorders.size() )
866  eBorder = mxImpl->maEnabBorders[ nVecIdx ]->GetType();
867  }
868  return eBorder;
869 }
870 
871 // frame border state and style
873 {
874  return bool(mxImpl->mnFlags & FrameSelFlags::DontCare);
875 }
876 
878 {
879  return mxImpl->GetBorder( eBorder ).GetState();
880 }
881 
882 const SvxBorderLine* FrameSelector::GetFrameBorderStyle( FrameBorderType eBorder ) const
883 {
884  const SvxBorderLine& rStyle = mxImpl->GetBorder( eBorder ).GetCoreStyle();
885  // rest of the world uses null pointer for invisible frame border
886  return rStyle.GetOutWidth() ? &rStyle : nullptr;
887 }
888 
889 void FrameSelector::ShowBorder( FrameBorderType eBorder, const SvxBorderLine* pStyle )
890 {
891  mxImpl->SetBorderCoreStyle( mxImpl->GetBorderAccess( eBorder ), pStyle );
892 }
893 
895 {
896  mxImpl->SetBorderState( mxImpl->GetBorderAccess( eBorder ), FrameBorderState::DontCare );
897 }
898 
900 {
901  bool bIsSet = false;
902  for( FrameBorderCIter aIt( mxImpl->maEnabBorders ); !bIsSet && aIt.Is(); ++aIt )
903  bIsSet = ((*aIt)->GetState() == FrameBorderState::Show);
904  return bIsSet;
905 }
906 
908 {
909  for( FrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
910  mxImpl->SetBorderState( **aIt, FrameBorderState::Hide );
911 }
912 
913 bool FrameSelector::GetVisibleWidth( long& rnWidth, SvxBorderLineStyle& rnStyle ) const
914 {
915  VisFrameBorderCIter aIt( mxImpl->maEnabBorders );
916  if( !aIt.Is() )
917  return false;
918 
919  const SvxBorderLine& rStyle = (*aIt)->GetCoreStyle();
920  bool bFound = true;
921  for( ++aIt; bFound && aIt.Is(); ++aIt )
922  {
923  bFound =
924  (rStyle.GetWidth() == (*aIt)->GetCoreStyle().GetWidth()) &&
925  (rStyle.GetBorderLineStyle() ==
926  (*aIt)->GetCoreStyle().GetBorderLineStyle());
927  }
928 
929  if( bFound )
930  {
931  rnWidth = rStyle.GetWidth();
932  rnStyle = rStyle.GetBorderLineStyle();
933  }
934  return bFound;
935 }
936 
938 {
939  VisFrameBorderCIter aIt( mxImpl->maEnabBorders );
940  if( !aIt.Is() )
941  return false;
942 
943  const SvxBorderLine& rStyle = (*aIt)->GetCoreStyle();
944  bool bFound = true;
945  for( ++aIt; bFound && aIt.Is(); ++aIt )
946  bFound = (rStyle.GetColor() == (*aIt)->GetCoreStyle().GetColor());
947 
948  if( bFound )
949  rColor = rStyle.GetColor();
950  return bFound;
951 }
952 
953 // frame border selection
955 {
956  return mxImpl->maSelectHdl;
957 }
958 
960 {
961  mxImpl->maSelectHdl = rHdl;
962 }
963 
965 {
966  return mxImpl->GetBorder( eBorder ).IsSelected();
967 }
968 
970 {
971  mxImpl->SelectBorder( mxImpl->GetBorderAccess( eBorder ), true/*bSelect*/ );
972  // MT: bFireFox as API parameter is ugly...
973  // if (bFocus)
974  {
976  if (xRet.is())
977  {
978  Any aOldValue, aNewValue;
979  aNewValue <<= AccessibleStateType::FOCUSED;
980  xRet->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
981  }
982  }
983 }
984 
986 {
987  // Construct an iterator for selected borders. If it is valid, there is a selected border.
988  return SelFrameBorderCIter( mxImpl->maEnabBorders ).Is();
989 }
990 
992 {
993  for( FrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
994  mxImpl->SelectBorder( **aIt, bSelect );
995 }
996 
998 {
999  for( VisFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
1000  mxImpl->SelectBorder( **aIt, true/*bSelect*/ );
1001 }
1002 
1004 {
1005  mxImpl->maCurrStyle.SetBorderLineStyle( nStyle );
1006  mxImpl->maCurrStyle.SetWidth( nWidth );
1007  for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
1008  mxImpl->SetBorderState( **aIt, FrameBorderState::Show );
1009 }
1010 
1012 {
1013  mxImpl->maCurrStyle.SetColor( rColor );
1014  for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
1015  mxImpl->SetBorderState( **aIt, FrameBorderState::Show );
1016 }
1017 
1018 // accessibility
1019 Reference< XAccessible > FrameSelector::CreateAccessible()
1020 {
1021  if( !mxAccess.is() )
1022  mxAccess = new a11y::AccFrameSelector(*this);
1023  return mxAccess.get();
1024 }
1025 
1027 {
1029  size_t nVecIdx = static_cast< size_t >( eBorder );
1030  if( IsBorderEnabled( eBorder ) && (1 <= nVecIdx) && (nVecIdx <= mxImpl->maChildVec.size()) )
1031  {
1032  --nVecIdx;
1033  if( !mxImpl->maChildVec[ nVecIdx ].is() )
1034  mxImpl->maChildVec[ nVecIdx ] = new a11y::AccFrameSelectorChild( *this, eBorder );
1035  xRet = mxImpl->maChildVec[ nVecIdx ].get();
1036  }
1037  return xRet;
1038 }
1039 
1040 Reference< XAccessible > FrameSelector::GetChildAccessible( sal_Int32 nIndex )
1041 {
1042  return GetChildAccessible( GetEnabledBorderType( nIndex ) ).get();
1043 }
1044 
1045 Reference< XAccessible > FrameSelector::GetChildAccessible( const Point& rPos )
1046 {
1047  Reference< XAccessible > xRet;
1048  for( FrameBorderCIter aIt( mxImpl->maEnabBorders ); !xRet.is() && aIt.Is(); ++aIt )
1049  if( (*aIt)->ContainsClickPoint( rPos ) )
1050  xRet = GetChildAccessible( (*aIt)->GetType() ).get();
1051  return xRet;
1052 }
1053 
1055 {
1056  tools::Rectangle aRect;
1057  const FrameBorder& rBorder = mxImpl->GetBorder( eBorder );
1058  if( rBorder.IsEnabled() )
1059  aRect = rBorder.GetClickBoundRect();
1060  return aRect;
1061 }
1062 
1063 // virtual functions from base class
1065 {
1066  mxImpl->CopyVirDevToControl(rRenderContext);
1067  if (HasFocus())
1068  mxImpl->DrawAllTrackingRects(rRenderContext);
1069 }
1070 
1072 {
1073  /* Mouse handling:
1074  * Click on an unselected frame border:
1075  Set current style/color, make frame border visible, deselect all
1076  other frame borders.
1077  * Click on a selected frame border:
1078  Toggle state of the frame border (visible -> don't care -> hidden),
1079  deselect all other frame borders.
1080  * SHIFT+Click or CTRL+Click on an unselected frame border:
1081  Extend selection, set current style/color to all selected frame
1082  borders independent of the state/style/color of the borders.
1083  * SHIFT+Click or CTRL+Click on a selected frame border:
1084  If all frame borders have same style/color, toggle state of all
1085  borders (see above), otherwise set current style/color to all
1086  borders.
1087  * Click on unused area: Do not modify selection and selected frame
1088  borders.
1089  */
1090 
1091  // #107394# do not auto-select a frame border
1092  mxImpl->SilentGrabFocus();
1093 
1094  if( rMEvt.IsLeft() )
1095  {
1096  Point aPos( mxImpl->GetDevPosFromMousePos( rMEvt.GetPosPixel() ) );
1097  FrameBorderPtrVec aDeselectBorders;
1098 
1099  bool bAnyClicked = false; // Any frame border clicked?
1100  bool bNewSelected = false; // Any unselected frame border selected?
1101 
1102  /* If frame borders are set to "don't care" and the control does not
1103  support this state, hide them on first mouse click.
1104  DR 2004-01-30: Why are the borders set to "don't care" then?!? */
1105  bool bHideDontCare = !SupportsDontCareState();
1106 
1107  for( FrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
1108  {
1109  if( (*aIt)->ContainsClickPoint( aPos ) )
1110  {
1111  // frame border is clicked
1112  bAnyClicked = true;
1113  if( !(*aIt)->IsSelected() )
1114  {
1115  bNewSelected = true;
1116  //mxImpl->SelectBorder( **aIt, true );
1117  SelectBorder((**aIt).GetType());
1118  }
1119  }
1120  else
1121  {
1122  // hide a "don't care" frame border only if it is not clicked
1123  if( bHideDontCare && ((*aIt)->GetState() == FrameBorderState::DontCare) )
1124  mxImpl->SetBorderState( **aIt, FrameBorderState::Hide );
1125 
1126  // deselect frame borders not clicked (if SHIFT or CTRL are not pressed)
1127  if( !rMEvt.IsShift() && !rMEvt.IsMod1() )
1128  aDeselectBorders.push_back( *aIt );
1129  }
1130  }
1131 
1132  if( bAnyClicked )
1133  {
1134  // any valid frame border clicked? -> deselect other frame borders
1135  for( FrameBorderIter aIt( aDeselectBorders ); aIt.Is(); ++aIt )
1136  mxImpl->SelectBorder( **aIt, false );
1137 
1138  if( bNewSelected || !mxImpl->SelectedBordersEqual() )
1139  {
1140  // new frame border selected, selection extended, or selected borders different? -> show
1141  for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
1142  // SetBorderState() sets current style and color to the frame border
1143  mxImpl->SetBorderState( **aIt, FrameBorderState::Show );
1144  }
1145  else
1146  {
1147  // all selected frame borders are equal -> toggle state
1148  for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
1149  mxImpl->ToggleBorderState( **aIt );
1150  }
1151 
1152  GetSelectHdl().Call( nullptr );
1153  }
1154  }
1155 
1156  return true;
1157 }
1158 
1159 bool FrameSelector::KeyInput( const KeyEvent& rKEvt )
1160 {
1161  bool bHandled = false;
1162  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
1163  if( !aKeyCode.GetModifier() )
1164  {
1165  sal_uInt16 nCode = aKeyCode.GetCode();
1166  switch( nCode )
1167  {
1168  case KEY_SPACE:
1169  {
1170  for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
1171  mxImpl->ToggleBorderState( **aIt );
1172  bHandled = true;
1173  }
1174  break;
1175 
1176  case KEY_UP:
1177  case KEY_DOWN:
1178  case KEY_LEFT:
1179  case KEY_RIGHT:
1180  {
1181  if( !mxImpl->maEnabBorders.empty() )
1182  {
1183  // start from first selected frame border
1184  SelFrameBorderCIter aIt( mxImpl->maEnabBorders );
1185  FrameBorderType eBorder = aIt.Is() ? (*aIt)->GetType() : mxImpl->maEnabBorders.front()->GetType();
1186 
1187  // search for next enabled frame border
1188  do
1189  {
1190  eBorder = mxImpl->GetBorder( eBorder ).GetKeyboardNeighbor( nCode );
1191  }
1192  while( (eBorder != FrameBorderType::NONE) && !IsBorderEnabled( eBorder ) );
1193 
1194  // select the frame border
1195  if( eBorder != FrameBorderType::NONE )
1196  {
1198  SelectBorder( eBorder );
1199  }
1200  bHandled = true;
1201  }
1202  }
1203  break;
1204  }
1205  }
1206  if (bHandled)
1207  return true;
1208  return CustomWidgetController::KeyInput(rKEvt);
1209 }
1210 
1212 {
1213  // auto-selection of a frame border, if focus reaches control, and nothing is selected
1214  if( mxImpl->mbAutoSelect && !IsAnyBorderSelected() && !mxImpl->maEnabBorders.empty() )
1215  mxImpl->SelectBorder( *mxImpl->maEnabBorders.front(), true );
1216 
1217  mxImpl->DoInvalidate( false );
1218  if (IsAnyBorderSelected())
1219  {
1221  if (mxImpl->maLeft.IsSelected())
1222  borderType = FrameBorderType::Left;
1223  else if (mxImpl->maRight.IsSelected())
1224  borderType = FrameBorderType::Right;
1225  else if (mxImpl->maTop.IsSelected())
1226  borderType = FrameBorderType::Top;
1227  else if (mxImpl->maBottom.IsSelected())
1228  borderType = FrameBorderType::Bottom;
1229  else if (mxImpl->maHor.IsSelected())
1230  borderType = FrameBorderType::Horizontal;
1231  else if (mxImpl->maVer.IsSelected())
1232  borderType = FrameBorderType::Vertical;
1233  else if (mxImpl->maTLBR.IsSelected())
1234  borderType = FrameBorderType::TLBR;
1235  else if (mxImpl->maBLTR.IsSelected())
1236  borderType = FrameBorderType::BLTR;
1237  SelectBorder(borderType);
1238  }
1239  for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
1240  mxImpl->SetBorderState( **aIt, FrameBorderState::Show );
1241  CustomWidgetController::GetFocus();
1242 }
1243 
1245 {
1246  mxImpl->DoInvalidate( false );
1247  CustomWidgetController::LoseFocus();
1248 }
1249 
1251 {
1252  mxImpl->InitVirtualDevice();
1253  CustomWidgetController::StyleUpdated();
1254 }
1255 
1257 {
1258  CustomWidgetController::Resize();
1259  mxImpl->sizeChanged();
1260 }
1261 
1262 template< typename Cont, typename Iter, typename Pred >
1264  maIt( rCont.begin() ),
1265  maEnd( rCont.end() )
1266 {
1267  while( Is() && !maPred( *maIt ) ) ++maIt;
1268 }
1269 
1270 template< typename Cont, typename Iter, typename Pred >
1272 {
1273  do { ++maIt; } while( Is() && !maPred( *maIt ) );
1274  return *this;
1275 }
1276 
1277 }
1278 
1279 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void MergeFocusToPolyPolygon(tools::PolyPolygon &rPPoly) const
Definition: frmsel.cxx:170
static double GetDefaultPatternScale()
Definition: frmselimpl.hxx:41
sal_uInt16 Count() const
FrameBorderPtrVec maAllBorders
Flags for enabled frame borders.
Definition: frmselimpl.hxx:124
bool mbAutoSelect
Used for repainting (false = only copy virtual device).
Definition: frmselimpl.hxx:140
void SetAllColWidths(long nWidth)
Sets the same output width for all columns.
void ClearFocusArea()
Definition: frmselimpl.hxx:70
FrameBorderType GetFrameBorderTypeFromIndex(size_t nIndex)
Returns the frame border type from a 0-based integer index.
Definition: frmsel.cxx:55
std::vector< FrameBorder * > FrameBorderPtrVec
Definition: frmselimpl.hxx:99
If set, the top frame border is enabled.
const frame::Style & GetUIStyle() const
Definition: frmselimpl.hxx:68
bool IsSelected() const
Definition: frmselimpl.hxx:60
FrameBorderPtrVec maEnabBorders
Pointers to all frame borders.
Definition: frmselimpl.hxx:125
sal_Int32 nIndex
double Dist() const
Definition: framelink.hxx:131
bool GetVisibleWidth(long &rnWidth, SvxBorderLineStyle &rnStyle) const
Returns true, if all visible frame borders have equal widths.
Definition: frmsel.cxx:913
void InitGlobalGeometry()
Initializes global coordinates.
Definition: frmsel.cxx:353
const tools::Polygon & GetObject(sal_uInt16 nPos) const
Color maHCLineCol
Selection marker color.
Definition: frmselimpl.hxx:109
void DrawBackground()
Draws the background of the entire control (the gray areas between borders).
Definition: frmsel.cxx:541
Color maBackCol
Arrows in current system colors.
Definition: frmselimpl.hxx:106
void SetBorderCoreStyle(FrameBorder &rBorder, const editeng::SvxBorderLine *pStyle)
Sets the core style of the specified frame border, or hides the frame border, if pStyle is 0...
Definition: frmsel.cxx:768
void SetXOffset(long nXOffset)
Sets the X output coordinate of the left column.
If set, the inner horizontal frame border is enabled.
ScopedVclPtr< VirtualDevice > mpVirDev
The control itself.
Definition: frmselimpl.hxx:104
void Replace(const Color &rSearchColor, const Color &rReplaceColor)
void InitBorderGeometry()
Initializes coordinates of all frame borders.
Definition: frmsel.cxx:377
editeng::SvxBorderLine maCurrStyle
All data of bottom-left to top-right frame border.
Definition: frmselimpl.hxx:120
tools::Rectangle GetClickBoundRect(FrameBorderType eBorder) const
Returns the bounding rectangle of the specified frame border (if enabled).
Definition: frmsel.cxx:1054
void Initialize(FrameSelFlags nFlags)
Initializes the control, enables/disables frame borders according to flags.
Definition: frmsel.cxx:278
this_type & operator++()
Definition: frmsel.cxx:1271
If set, the right frame border is enabled.
void DrawBitmapEx(const Point &rDestPt, const BitmapEx &rBitmapEx)
Color maMarkCol
Selection arrow color.
Definition: frmselimpl.hxx:108
void Create(SwFormatVertOrient &rItem, SvStream &rStrm, sal_uInt16 nVersionAbusedAsSize)
FrameBorderType meKeyLeft
Internal style to draw lines.
Definition: frmselimpl.hxx:88
If set, the inner vertical frame border is enabled.
bool mbFullRepaint
true = Bottom-left to top-right frame border enabled.
Definition: frmselimpl.hxx:139
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
long mnLine1
Size of an arrow image.
Definition: frmselimpl.hxx:130
void CopyVirDevToControl(vcl::RenderContext &rRenderContext)
Copies contents of the virtual device to the control.
Definition: frmsel.cxx:709
Inner horizontal frame border.
void SetColorToSelection(const Color &rColor)
Sets the passed color to all selected frame borders.
Definition: frmsel.cxx:1011
SvxBorderLineStyle Type() const
Definition: framelink.hxx:134
basegfx::B2DRange GetCellRange(size_t nCol, size_t nRow, bool bExpandMerged) const
Returns the output range of the cell (nCol,nRow).
#define F_PI2
bool mbEnabled
Mouse click areas.
Definition: frmselimpl.hxx:94
bool IsShift() const
If set, the bottom-left to top-right diagonal frame border is enabled.
sal_uInt16 GetCode() const
Color GetColorSecn() const
Definition: framelink.hxx:127
tools::Long GetWidth() const
size_t GetRowCount() const
Returns the number of rows in the array.
long mnLine3
Middle of inner frame borders.
Definition: frmselimpl.hxx:132
Point maVirDevPos
High contrast line color.
Definition: frmselimpl.hxx:110
const Color & GetLabelTextColor() const
bool IsAnyBorderSelected() const
Returns true, if any of the enabled frame borders is selected.
Definition: frmsel.cxx:985
void sizeChanged()
call this to recalculate based on parent size
Definition: frmsel.cxx:516
constexpr sal_uInt16 KEY_SPACE
virtual bool KeyInput(const KeyEvent &rKEvt) override
Definition: frmsel.cxx:1159
Color GetColorGap() const
Definition: framelink.hxx:128
long mnFocusOffs
Middle of right/bottom frame borders.
Definition: frmselimpl.hxx:133
const Color & GetFieldTextColor() const
bool IsUsed() const
Check if this style is used - this depends on it having any width definition.
Definition: framelink.hxx:138
constexpr sal_uInt16 KEY_UP
void SetKeyboardNeighbors(FrameBorderType eLeft, FrameBorderType eRight, FrameBorderType eTop, FrameBorderType eBottom)
Definition: frmsel.cxx:190
Size const & GetOutputSizePixel() const
NONE
void SetSelectHdl(const Link< LinkParamNone *, void > &rHdl)
Sets the passed handler that is called if the selection of the control changes.
Definition: frmsel.cxx:959
bool UseGapColor() const
Definition: framelink.hxx:129
FrameBorderState meState
Frame border type (position in control).
Definition: frmselimpl.hxx:85
void Initialize(FrameSelFlags nFlags)
Initializes the control, enables/disables frame borders according to flags.
Definition: frmsel.cxx:842
FrameBorderType meKeyBottom
Upper neighbor for keyboard control.
Definition: frmselimpl.hxx:91
void ToggleBorderState(FrameBorder &rBorder)
Changes the state of a frame border after a control event (mouse/keyboard).
Definition: frmsel.cxx:775
SvxBorderLineStyle
FuncFlags mnFlags
bool mbBLTR
true = Top-left to bottom-right frame border enabled.
Definition: frmselimpl.hxx:138
void SetYOffset(long nYOffset)
Sets the Y output coordinate of the top row.
Frame border has a visible style.
void Invert(const tools::Rectangle &rRect, InvertFlags nFlags=InvertFlags::NONE)
FrameBorderState
All possible states of a frame border.
Definition: frmsel.hxx:69
const FrameBorderType meType
Definition: frmselimpl.hxx:84
enumrange< T >::Iterator begin(enumrange< T >)
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
const std::u16string_view aImageIds[]
Definition: frmsel.cxx:307
tools::Rectangle GetClickBoundRect() const
Definition: frmsel.cxx:185
void SetRowStyleTop(size_t nRow, const Style &rStyle)
Sets the top frame style of the specified row.
frame::Style maUIStyle
Core style from application.
Definition: frmselimpl.hxx:87
virtual void GetFocus() override
Definition: frmsel.cxx:1211
void SetCoreStyle(const editeng::SvxBorderLine *pStyle)
Definition: frmsel.cxx:134
int nCount
void DrawAllFrameBorders()
Draws all frame borders.
Definition: frmsel.cxx:628
FrameBorderState GetState() const
Definition: frmselimpl.hxx:54
bool GetHighContrastMode() const
bool IsAnyBorderVisible() const
Returns true, if any enabled frame border has a visible style (not "don't care"). ...
Definition: frmsel.cxx:899
void Insert(const tools::Polygon &rPoly, sal_uInt16 nPos=POLYPOLY_APPEND)
sal_uInt16 GetModifier() const
const FrameBorder & GetBorder(FrameBorderType eBorder) const
Returns the object representing the specified frame border.
Definition: frmsel.cxx:526
Frame border is hidden (off).
void Enable(FrameSelFlags nFlags)
Definition: frmsel.cxx:127
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea) override
Definition: frmsel.cxx:827
If set, the top-left to bottom-right diagonal frame border is enabled.
Is
Inner vertical frame border.
Style maTop
FrameBorder maTLBR
All data of inner vertical frame border.
Definition: frmselimpl.hxx:118
Color GetDrawLineColor(const Color &rColor) const
Returns the color that has to be used to draw a frame border.
Definition: frmsel.cxx:620
virtual OutputDevice & get_ref_device()=0
FrameBorder maBLTR
All data of top-left to bottom-right frame border.
Definition: frmselimpl.hxx:119
virtual bool MouseButtonDown(const MouseEvent &rMEvt) override
Definition: frmsel.cxx:1071
void InitColors()
Fills all color members from current style settings.
Definition: frmsel.cxx:297
sal_uInt16 nCode
void AddClickRect(const tools::Rectangle &rRect)
Definition: frmsel.cxx:175
B2IRange fround(const B2DRange &rRange)
void Clear()
Sets the frame style to invisible state.
Definition: framelink.cxx:65
void InitArrowImageList()
Creates the image list with selection arrows regarding current style settings.
Definition: frmsel.cxx:327
std::unique_ptr< FrameSelectorImpl > mxImpl
Pointer to accessibility object of the control.
Definition: frmsel.hxx:185
const Link< LinkParamNone *, void > & GetSelectHdl() const
Returns the current selection handler.
Definition: frmsel.cxx:954
Right frame border.
#define SAL_N_ELEMENTS(arr)
void AddFocusPolygon(const tools::Polygon &rFocus)
Definition: frmsel.cxx:165
DocumentType eType
bool SupportsDontCareState() const
Returns true, if the control supports the "don't care" frame border state.
Definition: frmsel.cxx:872
tools::PolyPolygon maFocusArea
Lower neighbor for keyboard control.
Definition: frmselimpl.hxx:92
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: frmsel.cxx:1064
void Invert()
std::unique_ptr< BaseProcessor2D > createPixelProcessor2DFromOutputDevice(OutputDevice &rTargetOutDev, const drawinglayer::geometry::ViewInformation2D &rViewInformation2D)
constexpr sal_uInt16 KEY_DOWN
double Secn() const
Definition: framelink.hxx:132
void SetCellStyleDiag(size_t nCol, size_t nRow, const Style &rTLBR, const Style &rBLTR)
Sets both diagonal frame styles of the specified cell (nCol,nRow).
virtual void Resize() override
Definition: frmsel.cxx:1256
void Optimize(PolyOptimizeFlags nOptimizeFlags)
Template class for all types of frame border iterators.
Definition: frmselimpl.hxx:238
Right
virtual ~FrameSelector() override
Definition: frmsel.cxx:836
drawinglayer::primitive2d::Primitive2DContainer CreateB2DPrimitiveArray() const
Draws the part of the array, that is inside the clipping range.
std::vector< rtl::Reference< a11y::AccFrameSelectorChild > > maChildVec
true = High contrast mode.
Definition: frmselimpl.hxx:144
No border (special state).
#define DBG_ASSERT(sCon, aError)
int i
editeng::SvxBorderLine maCoreStyle
Frame border state (on/off/don't care).
Definition: frmselimpl.hxx:86
tools::PolyPolygon maClickArea
Focus drawing areas.
Definition: frmselimpl.hxx:93
void SetColumnStyleRight(size_t nCol, const Style &rStyle)
Sets the right frame style of the specified column.
std::vector< Image > maArrows
For all buffered drawing operations.
Definition: frmselimpl.hxx:105
bool IsBorderEnabled(FrameBorderType eBorder) const
Returns true, if the specified frame border is enabled.
Definition: frmsel.cxx:849
virtual css::uno::Reference< css::accessibility::XAccessible > CreateAccessible() override
Definition: frmsel.cxx:1019
tools::Long Width() const
If set, the bottom frame border is enabled.
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
const Color & GetFieldColor() const
Style maLeft
float u
FrameBorderType
Enumerates all borders a frame selection control can contain.
void Move(tools::Long nHorzMove, tools::Long nVertMove)
FrameBorderType GetType() const
Definition: frmselimpl.hxx:43
bool ContainsClickPoint(const Point &rPos) const
Definition: frmsel.cxx:180
void Initialize(size_t nWidth, size_t nHeight)
Reinitializes the array with the specified size.
Style maRight
bool IsEnabled() const
Definition: frmselimpl.hxx:48
bool mbTLBR
true = Inner vertical frame border enabled.
Definition: frmselimpl.hxx:137
void SelectBorder(FrameBorderType eBorder)
Selects or deselects the specified frame border.
Definition: frmsel.cxx:969
const editeng::SvxBorderLine * GetFrameBorderStyle(FrameBorderType eBorder) const
Returns the style of the specified frame border, if it is visible.
Definition: frmsel.cxx:882
const Point maEnd
bool IsInside(const Point &rPoint) const
FrameBorderType meKeyRight
Left neighbor for keyboard control.
Definition: frmselimpl.hxx:89
enumrange< T >::Iterator end(enumrange< T >)
double PatternScale() const
Definition: framelink.hxx:133
Top-left to bottom-right frame border.
bool GetVisibleColor(Color &rColor) const
Returns true, if all visible frame borders have equal color.
Definition: frmsel.cxx:937
bool IsBorderSelected(FrameBorderType eBorder) const
Returns true, if the specified frame border is selected.
Definition: frmsel.cxx:964
void SilentGrabFocus()
Grabs focus without auto-selection of a frame border, if no border selected.
Definition: frmsel.cxx:802
constexpr sal_uInt16 KEY_RIGHT
Point LogicToPixel(const Point &rLogicPt) const
void DoInvalidate(bool bFullRepaint)
Invalidates the control.
Definition: frmsel.cxx:740
void SetAllRowHeights(long nHeight)
Sets the same output height for all rows.
void SelectAllVisibleBorders()
Selects or deselects all visible frame borders (ignores hidden and "don't care" borders).
Definition: frmsel.cxx:997
FrameBorderIterBase< const FrameBorderPtrVec, FrameBorderPtrVec::const_iterator, FrameBorderSelected_Pred > SelFrameBorderCIter
Iterator for constant svx::FrameBorder containers, iterates over selected borders.
Definition: frmselimpl.hxx:275
FrameSelFlags
Definition: frmsel.hxx:32
void ShowBorder(FrameBorderType eBorder, const editeng::SvxBorderLine *pStyle)
Shows the specified frame border using the passed style, or hides it, if pStyle is 0...
Definition: frmsel.cxx:889
FrameBorderType GetKeyboardNeighbor(sal_uInt16 nKeyCode) const
Definition: frmsel.cxx:199
const vcl::KeyCode & GetKeyCode() const
void DrawVirtualDevice()
Draws all contents of the control.
Definition: frmsel.cxx:700
FrameSelectorImpl(FrameSelector &rFrameSel)
Pointers to accessibility objects for frame borders.
Definition: frmsel.cxx:213
frame::Array maArray
Current style and color for new borders.
Definition: frmselimpl.hxx:121
Color GetColorPrim() const
Definition: framelink.hxx:126
If set, all four outer frame borders are enabled.
FrameSelector & mrFrameSel
Definition: frmselimpl.hxx:103
long mnCtrlSize
Selection handler.
Definition: frmselimpl.hxx:128
void Select(bool bSelect)
Definition: frmselimpl.hxx:61
bool SelectedBordersEqual() const
Returns true, if all selected frame borders are equal (or if nothing is selected).
Definition: frmsel.cxx:810
virtual void StyleUpdated() override
Definition: frmsel.cxx:1250
void SelectBorder(FrameBorder &rBorder, bool bSelect)
Selects a frame border and schedules redraw.
Definition: frmsel.cxx:794
FrameBorderIterBase(container_type &rCont)
Definition: frmsel.cxx:1263
FrameBorder maRight
All data of left frame border.
Definition: frmselimpl.hxx:113
void SetState(FrameBorderState eState)
Definition: frmsel.cxx:146
FrameBorder maVer
All data of inner horizontal frame border.
Definition: frmselimpl.hxx:117
Left frame border.
size_t GetColCount() const
Returns the number of columns in the array.
bool mbVer
true = Inner horizontal frame border enabled.
Definition: frmselimpl.hxx:136
bool IsLeft() const
FrameBorderType meKeyTop
Right neighbor for keyboard control.
Definition: frmselimpl.hxx:90
void DrawArrows(const FrameBorder &rBorder)
Draws selection arrows for the specified frame border.
Definition: frmsel.cxx:564
const int FRAMEBORDERTYPE_COUNT
The number of valid frame border types (excluding FrameBorderType::NONE).
tools::Long Height() const
Contains the widths of primary and secondary line of a frame style.
Definition: framelink.hxx:100
void SelectAllBorders(bool bSelect)
Selects or deselects all frame borders.
Definition: frmsel.cxx:991
void InitVirtualDevice()
Draws the entire control into the internal virtual device.
Definition: frmsel.cxx:507
FrameBorderType GetEnabledBorderType(sal_Int32 nIndex) const
Returns the border type from the passed index (counts only enabled frame borders).
Definition: frmsel.cxx:859
void HideAllBorders()
Hides all enabled frame borders.
Definition: frmsel.cxx:907
const Point & GetPosPixel() const
If set, the left frame border is enabled.
sal_Int32 GetEnabledBorderCount() const
Returns the number of enabled frame borders.
Definition: frmsel.cxx:854
Point GetDevPosFromMousePos(const Point &rMousePos) const
Converts a mouse position to the virtual device position.
Definition: frmsel.cxx:735
long mnArrowSize
Size of the control (always square).
Definition: frmselimpl.hxx:129
void SetBorderState(FrameBorder &rBorder, FrameBorderState eState)
Sets the state of the specified frame border.
Definition: frmsel.cxx:747
void Set(double nP, double nD, double nS)
Sets the frame style to the passed line widths.
Definition: framelink.cxx:80
tools::Long GetHeight() const
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
FrameSelFlags mnFlags
Frame link array to draw an array of frame borders.
Definition: frmselimpl.hxx:123
void SetColumnStyleLeft(size_t nCol, const Style &rStyle)
Sets the left frame style of the specified column.
FrameBorderState GetFrameBorderState(FrameBorderType eBorder) const
Returns the state (visible/hidden/don't care) of the specified frame border.
Definition: frmsel.cxx:877
tools::Rectangle GetBoundRect() const
virtual void LoseFocus() override
Definition: frmsel.cxx:1244
#define SAL_WARN(area, stream)
constexpr sal_uInt16 KEY_LEFT
Left
FrameBorder maTop
All data of right frame border.
Definition: frmselimpl.hxx:114
rtl::Reference< a11y::AccFrameSelector > mxAccess
Definition: frmsel.hxx:184
bool mbHor
Offset from frame border middle to draw focus.
Definition: frmselimpl.hxx:135
void SetBorderDontCare(FrameBorderType eBorder)
Sets the specified frame border to "don't care" state.
Definition: frmsel.cxx:894
Color maArrowCol
Background color.
Definition: frmselimpl.hxx:107
Style maTLBR
void DrawAllTrackingRects(vcl::RenderContext &rRenderContext)
Draws tracking rectangles for all selected frame borders.
Definition: frmsel.cxx:716
rtl::Reference< a11y::AccFrameSelectorChild > GetChildAccessible(FrameBorderType eBorder)
Returns the accessibility child object of the specified frame border (if enabled).
Definition: frmsel.cxx:1026
size_t GetIndexFromFrameBorderType(FrameBorderType eBorder)
Returns the zero-based index of a valid frame border type.
Definition: frmsel.cxx:62
virtual void set_size_request(int nWidth, int nHeight)=0
double Prim() const
Definition: framelink.hxx:130
RedlineType meType
FrameBorder & GetBorderAccess(FrameBorderType eBorder)
Returns the object representing the specified frame border (write access).
Definition: frmsel.cxx:535
Style maBLTR
void DeselectAllBorders()
Deselects all frame borders.
Definition: frmsel.hxx:146
void SetRowStyleBottom(size_t nRow, const Style &rStyle)
Sets the bottom frame style of the specified row.
bool mbHCMode
true = Auto select a frame border, if focus reaches control.
Definition: frmselimpl.hxx:141
FrameBorder maHor
All data of bottom frame border.
Definition: frmselimpl.hxx:116
FrameBorder maLeft
Position of virtual device in the control.
Definition: frmselimpl.hxx:112
FrameBorder(FrameBorderType eType)
Definition: frmsel.cxx:115
Style maBottom
void SetStyleToSelection(long nWidth, SvxBorderLineStyle nStyle)
Sets the passed line widths to all selected frame borders (in twips).
Definition: frmsel.cxx:1003
bool IsMod1() const
void EnableRTL(bool bEnable)
FrameBorder maBottom
All data of top frame border.
Definition: frmselimpl.hxx:115
long mnLine2
Middle of left/top frame borders.
Definition: frmselimpl.hxx:131