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