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