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