LibreOffice Module cui (master)  1
grfpage.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 <memory>
21 #include <svl/eitem.hxx>
22 #include <svl/stritem.hxx>
23 #include <dialmgr.hxx>
24 #include <svx/dlgutil.hxx>
25 #include <editeng/sizeitem.hxx>
26 #include <editeng/brushitem.hxx>
27 #include <grfpage.hxx>
28 #include <svx/grfcrop.hxx>
29 #include <rtl/ustring.hxx>
30 #include <tools/debug.hxx>
31 #include <tools/fract.hxx>
32 #include <svx/svxids.hrc>
33 #include <strings.hrc>
34 #include <vcl/fieldvalues.hxx>
35 #include <vcl/settings.hxx>
36 #include <vcl/svapp.hxx>
37 #include <svtools/unitconv.hxx>
41 
42 #define CM_1_TO_TWIP 567
43 #define TWIP_TO_INCH 1440
44 
45 
46 static int lcl_GetValue(const weld::MetricSpinButton& rMetric, FieldUnit eUnit)
47 {
48  return rMetric.denormalize(rMetric.get_value(eUnit));
49 }
50 
51 /*--------------------------------------------------------------------
52  description: crop graphic
53  --------------------------------------------------------------------*/
54 
56  : SfxTabPage(pPage, pController, "cui/ui/croppage.ui", "CropPage", &rSet)
57  , nOldWidth(0)
58  , nOldHeight(0)
59  , bSetOrigSize(false)
60  , m_xCropFrame(m_xBuilder->weld_widget("cropframe"))
61  , m_xZoomConstRB(m_xBuilder->weld_radio_button("keepscale"))
62  , m_xSizeConstRB(m_xBuilder->weld_radio_button("keepsize"))
63  , m_xLeftMF(m_xBuilder->weld_metric_spin_button("left", FieldUnit::CM))
64  , m_xRightMF(m_xBuilder->weld_metric_spin_button("right", FieldUnit::CM))
65  , m_xTopMF(m_xBuilder->weld_metric_spin_button("top", FieldUnit::CM))
66  , m_xBottomMF(m_xBuilder->weld_metric_spin_button("bottom", FieldUnit::CM))
67  , m_xScaleFrame(m_xBuilder->weld_widget("scaleframe"))
68  , m_xWidthZoomMF(m_xBuilder->weld_metric_spin_button("widthzoom", FieldUnit::PERCENT))
69  , m_xHeightZoomMF(m_xBuilder->weld_metric_spin_button("heightzoom", FieldUnit::PERCENT))
70  , m_xSizeFrame(m_xBuilder->weld_widget("sizeframe"))
71  , m_xWidthMF(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM))
72  , m_xHeightMF(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM))
73  , m_xOrigSizeGrid(m_xBuilder->weld_widget("origsizegrid"))
74  , m_xOrigSizeFT(m_xBuilder->weld_label("origsizeft"))
75  , m_xOrigSizePB(m_xBuilder->weld_button("origsize"))
76  , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, "preview", m_aExampleWN))
77 {
79 
80  // set the correct metric
81  const FieldUnit eMetric = GetModuleFieldUnit( rSet );
82 
83  SetFieldUnit( *m_xWidthMF, eMetric );
84  SetFieldUnit( *m_xHeightMF, eMetric );
85  SetFieldUnit( *m_xLeftMF, eMetric );
86  SetFieldUnit( *m_xRightMF, eMetric );
87  SetFieldUnit( *m_xTopMF , eMetric );
88  SetFieldUnit( *m_xBottomMF, eMetric );
89 
91  m_xWidthMF->connect_value_changed( aLk );
92  m_xHeightMF->connect_value_changed( aLk );
93 
94  aLk = LINK(this, SvxGrfCropPage, ZoomHdl);
95  m_xWidthZoomMF->connect_value_changed( aLk );
96  m_xHeightZoomMF->connect_value_changed( aLk );
97 
98  aLk = LINK(this, SvxGrfCropPage, CropModifyHdl);
99  m_xLeftMF->connect_value_changed( aLk );
100  m_xRightMF->connect_value_changed( aLk );
101  m_xTopMF->connect_value_changed( aLk );
102  m_xBottomMF->connect_value_changed( aLk );
103 
104  m_xOrigSizePB->connect_clicked(LINK(this, SvxGrfCropPage, OrigSizeHdl));
105 }
106 
108 {
109  m_xExampleWN.reset();
110 }
111 
112 std::unique_ptr<SfxTabPage> SvxGrfCropPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
113 {
114  return std::make_unique<SvxGrfCropPage>(pPage, pController, *rSet);
115 }
116 
118 {
119  const SfxPoolItem* pItem;
120  const SfxItemPool& rPool = *rSet->GetPool();
121 
122  if(SfxItemState::SET == rSet->GetItemState( rPool.GetWhich(
123  SID_ATTR_GRAF_KEEP_ZOOM ), true, &pItem ))
124  {
125  if( static_cast<const SfxBoolItem*>(pItem)->GetValue() )
126  m_xZoomConstRB->set_active(true);
127  else
128  m_xSizeConstRB->set_active(true);
129  m_xZoomConstRB->save_state();
130  }
131 
132  sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_CROP );
133  if( SfxItemState::SET == rSet->GetItemState( nW, true, &pItem))
134  {
135  FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
136 
137  const SvxGrfCrop* pCrop = static_cast<const SvxGrfCrop*>(pItem);
138 
139  m_aExampleWN.SetLeft(pCrop->GetLeft());
140  m_aExampleWN.SetRight(pCrop->GetRight());
141  m_aExampleWN.SetTop(pCrop->GetTop());
142  m_aExampleWN.SetBottom(pCrop->GetBottom());
143 
144  m_xLeftMF->set_value( m_xLeftMF->normalize( pCrop->GetLeft()), eUnit );
145  m_xRightMF->set_value( m_xRightMF->normalize( pCrop->GetRight()), eUnit );
146  m_xTopMF->set_value( m_xTopMF->normalize( pCrop->GetTop()), eUnit );
147  m_xBottomMF->set_value( m_xBottomMF->normalize( pCrop->GetBottom()), eUnit );
148  }
149  else
150  {
151  m_xLeftMF->set_value(0, FieldUnit::NONE);
152  m_xRightMF->set_value(0, FieldUnit::NONE);
153  m_xTopMF->set_value(0, FieldUnit::NONE);
154  m_xBottomMF->set_value(0, FieldUnit::NONE);
155  }
156 
157  m_xLeftMF->save_value();
158  m_xRightMF->save_value();
159  m_xTopMF->save_value();
160  m_xBottomMF->save_value();
161 
162  nW = rPool.GetWhich( SID_ATTR_PAGE_SIZE );
163  if ( SfxItemState::SET == rSet->GetItemState( nW, false, &pItem ) )
164  {
165  // orientation and size from the PageItem
166  FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
167 
168  aPageSize = static_cast<const SvxSizeItem*>(pItem)->GetSize();
169 
170  auto nMin = m_xWidthMF->normalize( 23 );
171  auto nMax = m_xHeightMF->normalize(aPageSize.Height());
172  m_xHeightMF->set_range(nMin, nMax, eUnit);
173  nMax = m_xWidthMF->normalize(aPageSize.Width());
174  m_xWidthMF->set_range(nMin, nMax, eUnit);
175  }
176  else
177  {
180  MapMode( MapUnit::MapTwip ),
181  MapMode( rSet->GetPool()->GetMetric( nW ) ) );
182  }
183 
184  bool bFound = false;
185  if( SfxItemState::SET == rSet->GetItemState( SID_ATTR_GRAF_GRAPHIC, false, &pItem ) )
186  {
187  OUString referer;
188  SfxStringItem const * it = static_cast<SfxStringItem const *>(
189  rSet->GetItem(SID_REFERER));
190  if (it != nullptr) {
191  referer = it->GetValue();
192  }
193  const Graphic* pGrf = static_cast<const SvxBrushItem*>(pItem)->GetGraphic(referer);
194  if( pGrf )
195  {
196  aOrigSize = GetGrfOrigSize( *pGrf );
197  if (pGrf->GetType() == GraphicType::Bitmap && aOrigSize.Width() && aOrigSize.Height())
198  {
199  aOrigPixelSize = pGrf->GetSizePixel();
200  }
201 
202  if( aOrigSize.Width() && aOrigSize.Height() )
203  {
205  m_aExampleWN.SetGraphic( *pGrf );
207 
208  bFound = true;
209  if( !static_cast<const SvxBrushItem*>(pItem)->GetGraphicLink().isEmpty() )
210  aGraphicName = static_cast<const SvxBrushItem*>(pItem)->GetGraphicLink();
211  }
212  }
213  }
214 
215  GraphicHasChanged( bFound );
216  ActivatePage( *rSet );
217 }
218 
220 {
221  const SfxItemPool& rPool = *rSet->GetPool();
222  bool bModified = false;
223  if( m_xWidthMF->get_value_changed_from_saved() ||
224  m_xHeightMF->get_value_changed_from_saved() )
225  {
226  sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_FRMSIZE );
227  FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
228 
229  std::shared_ptr<SvxSizeItem> aSz(std::make_shared<SvxSizeItem>(nW));
230 
231  // size could already have been set from another page
232  const SfxItemSet* pExSet = GetDialogExampleSet();
233  const SfxPoolItem* pItem = nullptr;
234  if( pExSet && SfxItemState::SET ==pExSet->GetItemState( nW, false, &pItem ) )
235  {
236  aSz.reset(static_cast< SvxSizeItem*>(pItem->Clone()));
237  }
238  else
239  {
240  aSz.reset(static_cast< SvxSizeItem*>(GetItemSet().Get(nW).Clone()));
241  }
242 
243  Size aTmpSz( aSz->GetSize() );
244  if( m_xWidthMF->get_value_changed_from_saved() )
245  aTmpSz.setWidth( lcl_GetValue( *m_xWidthMF, eUnit ) );
246  if( m_xHeightMF->get_value_changed_from_saved() )
247  aTmpSz.setHeight( lcl_GetValue( *m_xHeightMF, eUnit ) );
248  aSz->SetSize( aTmpSz );
249  m_xWidthMF->save_value();
250  m_xHeightMF->save_value();
251 
252  bModified |= nullptr != rSet->Put( *aSz );
253 
254  if( bSetOrigSize )
255  {
256  bModified |= nullptr != rSet->Put( SvxSizeItem( rPool.GetWhich(
257  SID_ATTR_GRAF_FRMSIZE_PERCENT ), Size( 0, 0 )) );
258  }
259  }
260  if( m_xLeftMF->get_value_changed_from_saved() || m_xRightMF->get_value_changed_from_saved() ||
261  m_xTopMF->get_value_changed_from_saved() || m_xBottomMF->get_value_changed_from_saved() )
262  {
263  sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_CROP );
264  FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
265  std::unique_ptr<SvxGrfCrop> pNew(static_cast<SvxGrfCrop*>(rSet->Get( nW ).Clone()));
266 
267  pNew->SetLeft( lcl_GetValue( *m_xLeftMF, eUnit ) );
268  pNew->SetRight( lcl_GetValue( *m_xRightMF, eUnit ) );
269  pNew->SetTop( lcl_GetValue( *m_xTopMF, eUnit ) );
270  pNew->SetBottom( lcl_GetValue( *m_xBottomMF, eUnit ) );
271  bModified |= nullptr != rSet->Put( *pNew );
272  }
273 
274  if( m_xZoomConstRB->get_state_changed_from_saved() )
275  {
276  bModified |= nullptr != rSet->Put( SfxBoolItem( rPool.GetWhich(
277  SID_ATTR_GRAF_KEEP_ZOOM), m_xZoomConstRB->get_active() ) );
278  }
279 
280  return bModified;
281 }
282 
284 {
285 #ifdef DBG_UTIL
286  SfxItemPool* pPool = GetItemSet().GetPool();
287  DBG_ASSERT( pPool, "Where is the pool?" );
288 #endif
289 
290  bSetOrigSize = false;
291 
292  // Size
293  Size aSize;
294  const SfxPoolItem* pItem;
295  if( SfxItemState::SET == rSet.GetItemState( SID_ATTR_GRAF_FRMSIZE, false, &pItem ) )
296  aSize = static_cast<const SvxSizeItem*>(pItem)->GetSize();
297 
298  nOldWidth = aSize.Width();
299  nOldHeight = aSize.Height();
300 
301  auto nWidth = m_xWidthMF->normalize(nOldWidth);
302  auto nHeight = m_xHeightMF->normalize(nOldHeight);
303 
304  if (nWidth != m_xWidthMF->get_value(FieldUnit::TWIP))
305  m_xWidthMF->set_value(nWidth, FieldUnit::TWIP);
306  m_xWidthMF->save_value();
307 
308  if (nHeight != m_xHeightMF->get_value(FieldUnit::TWIP))
309  m_xHeightMF->set_value(nHeight, FieldUnit::TWIP);
310  m_xHeightMF->save_value();
311 
312  if( SfxItemState::SET == rSet.GetItemState( SID_ATTR_GRAF_GRAPHIC, false, &pItem ) )
313  {
314  const SvxBrushItem& rBrush = *static_cast<const SvxBrushItem*>(pItem);
315  if( !rBrush.GetGraphicLink().isEmpty() &&
316  aGraphicName != rBrush.GetGraphicLink() )
317  aGraphicName = rBrush.GetGraphicLink();
318 
319  OUString referer;
320  SfxStringItem const * it = static_cast<SfxStringItem const *>(
321  rSet.GetItem(SID_REFERER));
322  if (it != nullptr) {
323  referer = it->GetValue();
324  }
325  const Graphic* pGrf = rBrush.GetGraphic(referer);
326  if( pGrf )
327  {
328  m_aExampleWN.SetGraphic( *pGrf );
329  aOrigSize = GetGrfOrigSize( *pGrf );
330  if (pGrf->GetType() == GraphicType::Bitmap && aOrigSize.Width() > 1 && aOrigSize.Height() > 1) {
331  aOrigPixelSize = pGrf->GetSizePixel();
332  }
336  }
337  else
338  GraphicHasChanged( false );
339  }
340 
341  CalcZoom();
342 }
343 
345 {
346  if ( _pSet )
347  FillItemSet( _pSet );
348  return DeactivateRC::LeavePage;
349 }
350 
351 /*--------------------------------------------------------------------
352  description: scale changed, adjust size
353  --------------------------------------------------------------------*/
354 
356 {
357  SfxItemPool* pPool = GetItemSet().GetPool();
358  DBG_ASSERT( pPool, "Where is the pool?" );
359  FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
360  SID_ATTR_GRAF_CROP ) ) );
361 
362  if (&rField == m_xWidthZoomMF.get())
363  {
364  long nLRBorders = lcl_GetValue(*m_xLeftMF, eUnit)
365  +lcl_GetValue(*m_xRightMF, eUnit);
366  m_xWidthMF->set_value( m_xWidthMF->normalize(
367  ((aOrigSize.Width() - nLRBorders) * rField.get_value(FieldUnit::NONE))/100),
368  eUnit);
369  }
370  else
371  {
372  long nULBorders = lcl_GetValue(*m_xTopMF, eUnit)
373  +lcl_GetValue(*m_xBottomMF, eUnit);
374  m_xHeightMF->set_value( m_xHeightMF->normalize(
375  ((aOrigSize.Height() - nULBorders ) * rField.get_value(FieldUnit::NONE))/100) ,
376  eUnit );
377  }
378 }
379 
380 /*--------------------------------------------------------------------
381  description: change size, adjust scale
382  --------------------------------------------------------------------*/
383 
385 {
386  SfxItemPool* pPool = GetItemSet().GetPool();
387  DBG_ASSERT( pPool, "Where is the pool?" );
388  FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
389  SID_ATTR_GRAF_CROP ) ) );
390 
391  Size aSize( lcl_GetValue(*m_xWidthMF, eUnit),
392  lcl_GetValue(*m_xHeightMF, eUnit) );
393 
394  if(&rField == m_xWidthMF.get())
395  {
396  long nWidth = aOrigSize.Width() -
397  ( lcl_GetValue(*m_xLeftMF, eUnit) +
398  lcl_GetValue(*m_xRightMF, eUnit) );
399  if(!nWidth)
400  nWidth++;
401  sal_uInt16 nZoom = static_cast<sal_uInt16>( aSize.Width() * 100 / nWidth);
402  m_xWidthZoomMF->set_value(nZoom, FieldUnit::NONE);
403  }
404  else
405  {
406  long nHeight = aOrigSize.Height() -
407  ( lcl_GetValue(*m_xTopMF, eUnit) +
408  lcl_GetValue(*m_xBottomMF, eUnit));
409  if(!nHeight)
410  nHeight++;
411  sal_uInt16 nZoom = static_cast<sal_uInt16>( aSize.Height() * 100 / nHeight);
412  m_xHeightZoomMF->set_value(nZoom, FieldUnit::NONE);
413  }
414 }
415 
416 /*--------------------------------------------------------------------
417  description: evaluate border
418  --------------------------------------------------------------------*/
419 
420 IMPL_LINK( SvxGrfCropPage, CropModifyHdl, weld::MetricSpinButton&, rField, void )
421 {
422  SfxItemPool* pPool = GetItemSet().GetPool();
423  DBG_ASSERT( pPool, "Where is the pool?" );
424  FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
425  SID_ATTR_GRAF_CROP ) ) );
426 
427  bool bZoom = m_xZoomConstRB->get_active();
428  if (&rField == m_xLeftMF.get() || &rField == m_xRightMF.get())
429  {
430  long nLeft = lcl_GetValue( *m_xLeftMF, eUnit );
431  long nRight = lcl_GetValue( *m_xRightMF, eUnit );
432  long nWidthZoom = static_cast<long>(m_xWidthZoomMF->get_value(FieldUnit::NONE));
433  if (bZoom && nWidthZoom != 0 && ( ( ( aOrigSize.Width() - (nLeft + nRight )) * nWidthZoom )
434  / 100 >= aPageSize.Width() ) )
435  {
436  if (&rField == m_xLeftMF.get())
437  {
438  nLeft = aOrigSize.Width() -
439  ( aPageSize.Width() * 100 / nWidthZoom + nRight );
440  m_xLeftMF->set_value( m_xLeftMF->normalize( nLeft ), eUnit );
441  }
442  else
443  {
444  nRight = aOrigSize.Width() -
445  ( aPageSize.Width() * 100 / nWidthZoom + nLeft );
446  m_xRightMF->set_value( m_xRightMF->normalize( nRight ), eUnit );
447  }
448  }
450  {
451  m_aExampleWN.SetLeft(nRight);
452  m_aExampleWN.SetRight(nLeft);
453  }
454  else
455  {
456  m_aExampleWN.SetLeft(nLeft);
457  m_aExampleWN.SetRight(nRight);
458  }
459  if(bZoom)
460  {
461  // scale stays, recompute width
462  ZoomHdl(*m_xWidthZoomMF);
463  }
464  }
465  else
466  {
467  long nTop = lcl_GetValue( *m_xTopMF, eUnit );
468  long nBottom = lcl_GetValue( *m_xBottomMF, eUnit );
469  long nHeightZoom = static_cast<long>(m_xHeightZoomMF->get_value(FieldUnit::NONE));
470  if(bZoom && ( ( ( aOrigSize.Height() - (nTop + nBottom )) * nHeightZoom)
471  / 100 >= aPageSize.Height()))
472  {
473  assert(nHeightZoom && "div-by-zero");
474  if(&rField == m_xTopMF.get())
475  {
476  nTop = aOrigSize.Height() -
477  ( aPageSize.Height() * 100 / nHeightZoom + nBottom);
478  m_xTopMF->set_value( m_xWidthMF->normalize( nTop ), eUnit );
479  }
480  else
481  {
482  nBottom = aOrigSize.Height() -
483  ( aPageSize.Height() * 100 / nHeightZoom + nTop);
484  m_xBottomMF->set_value( m_xWidthMF->normalize( nBottom ), eUnit );
485  }
486  }
487  m_aExampleWN.SetTop( nTop );
488  m_aExampleWN.SetBottom( nBottom );
489  if(bZoom)
490  {
491  // scale stays, recompute height
492  ZoomHdl(*m_xHeightZoomMF);
493  }
494  }
495  m_aExampleWN.Invalidate();
496  // size and border changed -> recompute scale
497  if(!bZoom)
498  CalcZoom();
499  CalcMinMaxBorder();
500 }
501 /*--------------------------------------------------------------------
502  description: set original size
503  --------------------------------------------------------------------*/
504 
506 {
507  SfxItemPool* pPool = GetItemSet().GetPool();
508  DBG_ASSERT( pPool, "Where is the pool?" );
509  FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
510  SID_ATTR_GRAF_CROP ) ) );
511 
512  long nWidth = aOrigSize.Width() -
513  lcl_GetValue( *m_xLeftMF, eUnit ) -
514  lcl_GetValue( *m_xRightMF, eUnit );
515  m_xWidthMF->set_value( m_xWidthMF->normalize( nWidth ), eUnit );
516  long nHeight = aOrigSize.Height() -
517  lcl_GetValue( *m_xTopMF, eUnit ) -
518  lcl_GetValue( *m_xBottomMF, eUnit );
519  m_xHeightMF->set_value( m_xHeightMF->normalize( nHeight ), eUnit );
520  m_xWidthZoomMF->set_value(100, FieldUnit::NONE);
521  m_xHeightZoomMF->set_value(100, FieldUnit::NONE);
522  bSetOrigSize = true;
523 }
524 /*--------------------------------------------------------------------
525  description: compute scale
526  --------------------------------------------------------------------*/
527 
529 {
530  SfxItemPool* pPool = GetItemSet().GetPool();
531  DBG_ASSERT( pPool, "Where is the pool?" );
532  FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
533  SID_ATTR_GRAF_CROP ) ) );
534 
535  long nWidth = lcl_GetValue( *m_xWidthMF, eUnit );
536  long nHeight = lcl_GetValue( *m_xHeightMF, eUnit );
537  long nLRBorders = lcl_GetValue( *m_xLeftMF, eUnit ) +
538  lcl_GetValue( *m_xRightMF, eUnit );
539  long nULBorders = lcl_GetValue( *m_xTopMF, eUnit ) +
540  lcl_GetValue( *m_xBottomMF, eUnit );
541  sal_uInt16 nZoom = 0;
542  long nDen;
543  if( (nDen = aOrigSize.Width() - nLRBorders) > 0)
544  nZoom = static_cast<sal_uInt16>((( nWidth * 1000 / nDen )+5)/10);
545  m_xWidthZoomMF->set_value(nZoom, FieldUnit::NONE);
546  if( (nDen = aOrigSize.Height() - nULBorders) > 0)
547  nZoom = static_cast<sal_uInt16>((( nHeight * 1000 / nDen )+5)/10);
548  else
549  nZoom = 0;
550  m_xHeightZoomMF->set_value(nZoom, FieldUnit::NONE);
551 }
552 
553 /*--------------------------------------------------------------------
554  description: set minimum/maximum values for the margins
555  --------------------------------------------------------------------*/
556 
558 {
559  SfxItemPool* pPool = GetItemSet().GetPool();
560  DBG_ASSERT( pPool, "Where is the pool?" );
561  FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
562  SID_ATTR_GRAF_CROP ) ) );
563  long nR = lcl_GetValue(*m_xRightMF, eUnit );
564  long nMinWidth = (aOrigSize.Width() * 10) /11;
565  long nMin = nMinWidth - (nR >= 0 ? nR : 0);
566  m_xLeftMF->set_max( m_xLeftMF->normalize(nMin), eUnit );
567 
568  long nL = lcl_GetValue(*m_xLeftMF, eUnit );
569  nMin = nMinWidth - (nL >= 0 ? nL : 0);
570  m_xRightMF->set_max( m_xRightMF->normalize(nMin), eUnit );
571 
572  long nUp = lcl_GetValue( *m_xTopMF, eUnit );
573  long nMinHeight = (aOrigSize.Height() * 10) /11;
574  nMin = nMinHeight - (nUp >= 0 ? nUp : 0);
575  m_xBottomMF->set_max( m_xBottomMF->normalize(nMin), eUnit );
576 
577  long nLow = lcl_GetValue(*m_xBottomMF, eUnit );
578  nMin = nMinHeight - (nLow >= 0 ? nLow : 0);
579  m_xTopMF->set_max( m_xTopMF->normalize(nMin), eUnit );
580 }
581 /*--------------------------------------------------------------------
582  description: set spinsize to 1/20 of the original size,
583  fill FixedText with the original size
584  --------------------------------------------------------------------*/
585 
587 {
588  if( bFound )
589  {
590  SfxItemPool* pPool = GetItemSet().GetPool();
591  DBG_ASSERT( pPool, "Where is the pool?" );
592  FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
593  SID_ATTR_GRAF_CROP ) ));
594 
595  sal_Int64 nSpin = m_xLeftMF->normalize(aOrigSize.Width()) / 20;
596  nSpin = vcl::ConvertValue( nSpin, aOrigSize.Width(), 0,
597  eUnit, m_xLeftMF->get_unit());
598 
599  // if the margin is too big, it is set to 1/3 on both pages
600  long nR = lcl_GetValue( *m_xRightMF, eUnit );
601  long nL = lcl_GetValue( *m_xLeftMF, eUnit );
602  if((nL + nR) < - aOrigSize.Width())
603  {
604  long nVal = aOrigSize.Width() / -3;
605  m_xRightMF->set_value( m_xRightMF->normalize( nVal ), eUnit );
606  m_xLeftMF->set_value( m_xLeftMF->normalize( nVal ), eUnit );
607  m_aExampleWN.SetLeft(nVal);
608  m_aExampleWN.SetRight(nVal);
609  }
610  long nUp = lcl_GetValue(*m_xTopMF, eUnit );
611  long nLow = lcl_GetValue(*m_xBottomMF, eUnit );
612  if((nUp + nLow) < - aOrigSize.Height())
613  {
614  long nVal = aOrigSize.Height() / -3;
615  m_xTopMF->set_value( m_xTopMF->normalize( nVal ), eUnit );
616  m_xBottomMF->set_value( m_xBottomMF->normalize( nVal ), eUnit );
617  m_aExampleWN.SetTop(nVal);
618  m_aExampleWN.SetBottom(nVal);
619  }
620 
621  m_xLeftMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
622  m_xRightMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
623  nSpin = m_xTopMF->normalize(aOrigSize.Height()) / 20;
624  nSpin = vcl::ConvertValue( nSpin, aOrigSize.Width(), 0,
625  eUnit, m_xLeftMF->get_unit() );
626  m_xTopMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
627  m_xBottomMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
628 
629  // display original size
630  const FieldUnit eMetric = GetModuleFieldUnit( GetItemSet() );
631 
632  OUString sTemp;
633  {
634  std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/spinbox.ui"));
635  std::unique_ptr<weld::MetricSpinButton> xFld(xBuilder->weld_metric_spin_button("spin", FieldUnit::CM));
636  SetFieldUnit( *xFld, eMetric );
637  xFld->set_digits(m_xWidthMF->get_digits());
638  xFld->set_max(INT_MAX - 1, FieldUnit::NONE);
639 
640  xFld->set_value(xFld->normalize(aOrigSize.Width()), eUnit);
641  sTemp = xFld->get_text();
642  xFld->set_value(xFld->normalize(aOrigSize.Height()), eUnit);
643  // multiplication sign (U+00D7)
644  sTemp += u"\u00D7" + xFld->get_text();
645  }
646 
647  if ( aOrigPixelSize.Width() && aOrigPixelSize.Height() ) {
648  sal_Int32 ax = sal_Int32(floor(static_cast<float>(aOrigPixelSize.Width()) /
649  (static_cast<float>(aOrigSize.Width())/TWIP_TO_INCH)+0.5));
650  sal_Int32 ay = sal_Int32(floor(static_cast<float>(aOrigPixelSize.Height()) /
651  (static_cast<float>(aOrigSize.Height())/TWIP_TO_INCH)+0.5));
652  sTemp += " " + CuiResId( RID_SVXSTR_PPI );
653  OUString sPPI = OUString::number(ax);
654  if (abs(ax - ay) > 1) {
655  sPPI += u"\u00D7" + OUString::number(ay);
656  }
657  sTemp = sTemp.replaceAll("%1", sPPI);
658  }
659  m_xOrigSizeFT->set_label(sTemp);
660  }
661 
662  m_xCropFrame->set_sensitive(bFound);
663  m_xScaleFrame->set_sensitive(bFound);
664  m_xSizeFrame->set_sensitive(bFound);
665  m_xOrigSizeGrid->set_sensitive(bFound);
666  m_xZoomConstRB->set_sensitive(bFound);
667 }
668 
670 {
671  const MapMode aMapTwip( MapUnit::MapTwip );
672  Size aSize( rGrf.GetPrefSize() );
673  if( MapUnit::MapPixel == rGrf.GetPrefMapMode().GetMapUnit() )
674  aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMapTwip);
675  else
676  aSize = OutputDevice::LogicToLogic( aSize,
677  rGrf.GetPrefMapMode(), aMapTwip );
678  return aSize;
679 }
680 
681 /*****************************************************************/
682 
684  : m_aTopLeft(0, 0)
685  , m_aBottomRight(0, 0)
686 {
687 }
688 
690 {
691  CustomWidgetController::SetDrawingArea(pDrawingArea);
692  OutputDevice& rDevice = pDrawingArea->get_ref_device();
693  Size aSize(rDevice.LogicToPixel(Size(78, 78), MapMode(MapUnit::MapAppFont)));
694  pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
695 
696  m_aMapMode = rDevice.GetMapMode();
698  Size(CM_1_TO_TWIP / 2, CM_1_TO_TWIP / 2),
699  MapMode(MapUnit::MapTwip), m_aMapMode);
700 }
701 
702 void SvxCropExample::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&)
703 {
704  rRenderContext.Push(PushFlags::MAPMODE);
705  rRenderContext.SetMapMode(m_aMapMode);
706 
707  // Win BG
708  const Size aWinSize(rRenderContext.PixelToLogic(GetOutputSizePixel()));
709  rRenderContext.SetLineColor();
710  rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetWindowColor());
711  rRenderContext.DrawRect(::tools::Rectangle(Point(), aWinSize));
712 
713  // use AA, the Graphic may be a metafile/svg and would then look ugly
714  rRenderContext.SetAntialiasing(AntialiasingFlags::EnableB2dDraw);
715 
716  // draw Graphic
717  ::tools::Rectangle aRect(
718  Point((aWinSize.Width() - m_aFrameSize.Width())/2, (aWinSize.Height() - m_aFrameSize.Height())/2),
719  m_aFrameSize);
720  m_aGrf.Draw(&rRenderContext, aRect.TopLeft(), aRect.GetSize());
721 
722  // Remove one more case that uses XOR paint (RasterOp::Invert).
723  // Get colors and logic DashLength from settings, use equal to
724  // PolygonMarkerPrimitive2D, may be changed to that primitive later.
725  // Use this to guarantee good visibility - that was the purpose of
726  // the former used XOR paint.
727  const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
728  const Color aColA(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor());
729  const Color aColB(aSvtOptionsDrawinglayer.GetStripeColorB().getBColor());
730  const double fStripeLength(aSvtOptionsDrawinglayer.GetStripeLength());
731  const basegfx::B2DVector aDashVector(rRenderContext.GetInverseViewTransformation() * basegfx::B2DVector(fStripeLength, 0.0));
732  const double fLogicDashLength(aDashVector.getX());
733 
734  // apply current crop settings
735  aRect.AdjustLeft(m_aTopLeft.Y());
736  aRect.AdjustTop(m_aTopLeft.X());
737  aRect.AdjustRight(-m_aBottomRight.Y());
738  aRect.AdjustBottom(-m_aBottomRight.X());
739 
740  // apply dash with direct paint callbacks
743  basegfx::B2DRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom())),
744  std::vector< double >(2, fLogicDashLength),
745  [&aColA,&rRenderContext](const basegfx::B2DPolygon& rSnippet)
746  {
747  rRenderContext.SetLineColor(aColA);
748  rRenderContext.DrawPolyLine(rSnippet);
749  },
750  [&aColB,&rRenderContext](const basegfx::B2DPolygon& rSnippet)
751  {
752  rRenderContext.SetLineColor(aColB);
753  rRenderContext.DrawPolyLine(rSnippet);
754  },
755  2.0 * fLogicDashLength);
756 
757  rRenderContext.Pop();
758 }
759 
761 {
763 }
764 
766 {
767  m_aFrameSize = rSz;
768  if (!m_aFrameSize.Width())
769  m_aFrameSize.setWidth( 1 );
770  if (!m_aFrameSize.Height())
771  m_aFrameSize.setHeight( 1 );
772  Size aWinSize( GetOutputSizePixel() );
773  Fraction aXScale( aWinSize.Width() * 4, m_aFrameSize.Width() * 5 );
774  Fraction aYScale( aWinSize.Height() * 4, m_aFrameSize.Height() * 5 );
775 
776  if( aYScale < aXScale )
777  aXScale = aYScale;
778 
779  m_aMapMode.SetScaleX(aXScale);
780  m_aMapMode.SetScaleY(aXScale);
781 
782  Invalidate();
783 }
784 
785 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Color GetStripeColorA() const
basegfx::B2DHomMatrix GetInverseViewTransformation() const
long Width() const
void SetFieldUnit(weld::MetricSpinButton &rField, FieldUnit eUnit, bool bAll)
Point m_aTopLeft
Definition: grfpage.hxx:31
virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override
Definition: grfpage.cxx:344
FieldUnit
void SetAntialiasing(AntialiasingFlags nMode)
Graphic m_aGrf
Definition: grfpage.hxx:32
MapMode m_aMapMode
Definition: grfpage.hxx:29
Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
Size GetSizePixel(const OutputDevice *pRefDevice=nullptr) const
Size aOrigPixelSize
Definition: grfpage.hxx:55
long Height() const
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const =0
virtual void ActivatePage(const SfxItemSet &rSet) override
Definition: grfpage.cxx:283
IMPL_LINK(SvxGrfCropPage, ZoomHdl, weld::MetricSpinButton &, rField, void)
Definition: grfpage.cxx:355
void SetTop(long nVal)
Definition: grfpage.hxx:41
const StyleSettings & GetStyleSettings() const
void DrawPolyLine(const tools::Polygon &rPoly)
std::unique_ptr< weld::MetricSpinButton > m_xLeftMF
Definition: grfpage.hxx:66
virtual void Paint(vcl::RenderContext &rRenderContext, const ::tools::Rectangle &rRect) override
Definition: grfpage.cxx:702
const MapMode & GetMapMode() const
void SetLeft(long nVal)
Definition: grfpage.hxx:43
Color GetStripeColorB() const
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea) override
Definition: grfpage.cxx:689
std::unique_ptr< weld::MetricSpinButton > m_xTopMF
Definition: grfpage.hxx:68
std::unique_ptr< weld::Widget > m_xScaleFrame
Definition: grfpage.hxx:71
void SetMapMode()
bool bSetOrigSize
Definition: grfpage.hxx:59
Size const & GetOutputSizePixel() const
FieldUnit GetModuleFieldUnit(const SfxItemSet &rSet)
static OutputDevice * GetDefaultDevice()
SvxGrfCropPage(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet &rSet)
Definition: grfpage.cxx:55
virtual MapUnit GetMetric(sal_uInt16 nWhich) const
#define TWIP_TO_INCH
Definition: grfpage.cxx:43
std::unique_ptr< weld::Widget > m_xCropFrame
Definition: grfpage.hxx:63
long nOldWidth
Definition: grfpage.hxx:57
static Size GetGrfOrigSize(const Graphic &)
Definition: grfpage.cxx:669
std::unique_ptr< weld::MetricSpinButton > m_xBottomMF
Definition: grfpage.hxx:69
virtual bool FillItemSet(SfxItemSet *rSet) override
Definition: grfpage.cxx:219
void SetExchangeSupport()
Size aPageSize
Definition: grfpage.hxx:56
Size m_aFrameSize
Definition: grfpage.hxx:30
std::unique_ptr< weld::MetricSpinButton > m_xRightMF
Definition: grfpage.hxx:67
const Graphic * GetGraphic(OUString const &referer=OUString()) const
virtual OutputDevice & get_ref_device()=0
void CalcZoom()
Definition: grfpage.cxx:528
virtual ~SvxGrfCropPage() override
Definition: grfpage.cxx:107
std::unique_ptr< weld::MetricSpinButton > m_xHeightZoomMF
Definition: grfpage.hxx:73
void DrawRect(const tools::Rectangle &rRect)
const SfxItemSet & GetItemSet() const
std::unique_ptr< weld::CustomWeld > m_xExampleWN
Definition: grfpage.hxx:84
void applyLineDashing(const B2DPolygon &rCandidate, const std::vector< double > &rDotDashArray, B2DPolyPolygon *pLineTarget, B2DPolyPolygon *pGapTarget, double fDotDashLength)
void SetLineColor()
void SetScaleX(const Fraction &rScaleX)
void Draw(OutputDevice *pOutDev, const Point &rDestPt) const
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
#define DBG_ASSERT(sCon, aError)
Reference< XAnimationNode > Clone(const Reference< XAnimationNode > &xSourceNode, const SdPage *pSource, const SdPage *pTarget)
GraphicType GetType() const
Size aOrigSize
Definition: grfpage.hxx:54
void CalcMinMaxBorder()
Definition: grfpage.cxx:557
std::unique_ptr< weld::Button > m_xOrigSizePB
Definition: grfpage.hxx:81
B2DPolygon createPolygonFromRect(const B2DRectangle &rRect, double fRadiusX, double fRadiusY)
const OUString & GetValue() const
void SetFillColor()
const SfxItemSet * GetItemSet(const SfxPoolItem &rAttr)
float u
static bool GetLayoutRTL()
void SetScaleY(const Fraction &rScaleY)
const AllSettings & GetSettings() const
MapUnit GetMapUnit() const
SfxItemPool * GetPool() const
const SfxItemSet * GetDialogExampleSet() const
OUString CuiResId(const char *pKey)
Definition: cuiresmgr.cxx:23
#define CM_1_TO_TWIP
Definition: grfpage.cxx:42
void SetFrameSize(const Size &rSz)
Definition: grfpage.cxx:765
Point PixelToLogic(const Point &rDevicePt) const
Point LogicToPixel(const Point &rLogicPt) const
Size GetPrefSize() const
std::unique_ptr< weld::MetricSpinButton > m_xHeightMF
Definition: grfpage.hxx:77
std::unique_ptr< weld::Widget > m_xSizeFrame
Definition: grfpage.hxx:75
const OUString & GetGraphicLink() const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
weld::Window * GetFrameWeld() const
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *rSet)
Definition: grfpage.cxx:112
static int lcl_GetValue(const weld::MetricSpinButton &rMetric, FieldUnit eUnit)
Definition: grfpage.cxx:46
std::unique_ptr< weld::MetricSpinButton > m_xWidthZoomMF
Definition: grfpage.hxx:72
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
sal_uInt16 GetWhich(sal_uInt16 nSlot, bool bDeep=true) const
MapMode GetPrefMapMode() const
std::unique_ptr< weld::RadioButton > m_xSizeConstRB
Definition: grfpage.hxx:65
long nOldHeight
Definition: grfpage.hxx:58
SvxCropExample m_aExampleWN
Definition: grfpage.hxx:61
virtual void Resize() override
Definition: grfpage.cxx:760
OUString aGraphicName
Definition: grfpage.hxx:53
const OUString PERCENT("Percent")
const Color & GetWindowColor() const
std::unique_ptr< weld::RadioButton > m_xZoomConstRB
Definition: grfpage.hxx:64
void SetRight(long nVal)
Definition: grfpage.hxx:44
basegfx::BColor getBColor() const
DeactivateRC
sal_Int64 ConvertValue(sal_Int64 nValue, sal_Int64 mnBaseValue, sal_uInt16 nDecDigits, FieldUnit eInUnit, FieldUnit eOutUnit)
FieldUnit MapToFieldUnit(const MapUnit eUnit)
virtual void Reset(const SfxItemSet *rSet) override
Definition: grfpage.cxx:117
int get_value(FieldUnit eDestUnit) const
static weld::Builder * CreateBuilder(weld::Widget *pParent, const OUString &rUIFile)
SVXCORE_DLLPUBLIC MSO_SPT Get(const OUString &)
std::unique_ptr< weld::MetricSpinButton > m_xWidthMF
Definition: grfpage.hxx:76
std::unique_ptr< weld::Label > m_xOrigSizeFT
Definition: grfpage.hxx:80
sal_uInt16 GetStripeLength() const
Point m_aBottomRight
Definition: grfpage.hxx:31
void GraphicHasChanged(bool bFound)
Definition: grfpage.cxx:586
virtual void set_size_request(int nWidth, int nHeight)=0
void SetGraphic(const Graphic &rGrf)
Definition: grfpage.hxx:46
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
void Push(PushFlags nFlags=PushFlags::ALL)
std::unique_ptr< weld::Widget > m_xOrigSizeGrid
Definition: grfpage.hxx:79
void setWidth(long nWidth)
IMPL_LINK_NOARG(SvxGrfCropPage, OrigSizeHdl, weld::Button &, void)
Definition: grfpage.cxx:505
int denormalize(int nValue) const
void SetBottom(long nVal)
Definition: grfpage.hxx:42
void setHeight(long nHeight)