Bump version to 6.4.7.2.M8
[LibreOffice.git] / cui / source / tabpages / grfpage.cxx
blob586f9806ce8d7b2339a46bb7f83ce41954c80f84
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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/field.hxx>
35 #include <vcl/settings.hxx>
36 #include <vcl/svapp.hxx>
37 #include <svtools/unitconv.hxx>
39 #define CM_1_TO_TWIP 567
40 #define TWIP_TO_INCH 1440
43 static int lcl_GetValue(const weld::MetricSpinButton& rMetric, FieldUnit eUnit)
45 return rMetric.denormalize(rMetric.get_value(eUnit));
48 /*--------------------------------------------------------------------
49 description: crop graphic
50 --------------------------------------------------------------------*/
52 SvxGrfCropPage::SvxGrfCropPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
53 : SfxTabPage(pPage, pController, "cui/ui/croppage.ui", "CropPage", &rSet)
54 , nOldWidth(0)
55 , nOldHeight(0)
56 , bSetOrigSize(false)
57 , m_xCropFrame(m_xBuilder->weld_widget("cropframe"))
58 , m_xZoomConstRB(m_xBuilder->weld_radio_button("keepscale"))
59 , m_xSizeConstRB(m_xBuilder->weld_radio_button("keepsize"))
60 , m_xLeftMF(m_xBuilder->weld_metric_spin_button("left", FieldUnit::CM))
61 , m_xRightMF(m_xBuilder->weld_metric_spin_button("right", FieldUnit::CM))
62 , m_xTopMF(m_xBuilder->weld_metric_spin_button("top", FieldUnit::CM))
63 , m_xBottomMF(m_xBuilder->weld_metric_spin_button("bottom", FieldUnit::CM))
64 , m_xScaleFrame(m_xBuilder->weld_widget("scaleframe"))
65 , m_xWidthZoomMF(m_xBuilder->weld_metric_spin_button("widthzoom", FieldUnit::PERCENT))
66 , m_xHeightZoomMF(m_xBuilder->weld_metric_spin_button("heightzoom", FieldUnit::PERCENT))
67 , m_xSizeFrame(m_xBuilder->weld_widget("sizeframe"))
68 , m_xWidthMF(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM))
69 , m_xHeightMF(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM))
70 , m_xOrigSizeGrid(m_xBuilder->weld_widget("origsizegrid"))
71 , m_xOrigSizeFT(m_xBuilder->weld_label("origsizeft"))
72 , m_xOrigSizePB(m_xBuilder->weld_button("origsize"))
73 , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, "preview", m_aExampleWN))
75 SetExchangeSupport();
77 // set the correct metric
78 const FieldUnit eMetric = GetModuleFieldUnit( rSet );
80 SetFieldUnit( *m_xWidthMF, eMetric );
81 SetFieldUnit( *m_xHeightMF, eMetric );
82 SetFieldUnit( *m_xLeftMF, eMetric );
83 SetFieldUnit( *m_xRightMF, eMetric );
84 SetFieldUnit( *m_xTopMF , eMetric );
85 SetFieldUnit( *m_xBottomMF, eMetric );
87 Link<weld::MetricSpinButton&,void> aLk = LINK(this, SvxGrfCropPage, SizeHdl);
88 m_xWidthMF->connect_value_changed( aLk );
89 m_xHeightMF->connect_value_changed( aLk );
91 aLk = LINK(this, SvxGrfCropPage, ZoomHdl);
92 m_xWidthZoomMF->connect_value_changed( aLk );
93 m_xHeightZoomMF->connect_value_changed( aLk );
95 aLk = LINK(this, SvxGrfCropPage, CropModifyHdl);
96 m_xLeftMF->connect_value_changed( aLk );
97 m_xRightMF->connect_value_changed( aLk );
98 m_xTopMF->connect_value_changed( aLk );
99 m_xBottomMF->connect_value_changed( aLk );
101 m_xOrigSizePB->connect_clicked(LINK(this, SvxGrfCropPage, OrigSizeHdl));
104 SvxGrfCropPage::~SvxGrfCropPage()
106 m_xExampleWN.reset();
109 std::unique_ptr<SfxTabPage> SvxGrfCropPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
111 return std::make_unique<SvxGrfCropPage>(pPage, pController, *rSet);
114 void SvxGrfCropPage::Reset( const SfxItemSet *rSet )
116 const SfxPoolItem* pItem;
117 const SfxItemPool& rPool = *rSet->GetPool();
119 if(SfxItemState::SET == rSet->GetItemState( rPool.GetWhich(
120 SID_ATTR_GRAF_KEEP_ZOOM ), true, &pItem ))
122 if( static_cast<const SfxBoolItem*>(pItem)->GetValue() )
123 m_xZoomConstRB->set_active(true);
124 else
125 m_xSizeConstRB->set_active(true);
126 m_xZoomConstRB->save_state();
129 sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_CROP );
130 if( SfxItemState::SET == rSet->GetItemState( nW, true, &pItem))
132 FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
134 const SvxGrfCrop* pCrop = static_cast<const SvxGrfCrop*>(pItem);
136 m_aExampleWN.SetLeft(pCrop->GetLeft());
137 m_aExampleWN.SetRight(pCrop->GetRight());
138 m_aExampleWN.SetTop(pCrop->GetTop());
139 m_aExampleWN.SetBottom(pCrop->GetBottom());
141 m_xLeftMF->set_value( m_xLeftMF->normalize( pCrop->GetLeft()), eUnit );
142 m_xRightMF->set_value( m_xRightMF->normalize( pCrop->GetRight()), eUnit );
143 m_xTopMF->set_value( m_xTopMF->normalize( pCrop->GetTop()), eUnit );
144 m_xBottomMF->set_value( m_xBottomMF->normalize( pCrop->GetBottom()), eUnit );
146 else
148 m_xLeftMF->set_value(0, FieldUnit::NONE);
149 m_xRightMF->set_value(0, FieldUnit::NONE);
150 m_xTopMF->set_value(0, FieldUnit::NONE);
151 m_xBottomMF->set_value(0, FieldUnit::NONE);
154 m_xLeftMF->save_value();
155 m_xRightMF->save_value();
156 m_xTopMF->save_value();
157 m_xBottomMF->save_value();
159 nW = rPool.GetWhich( SID_ATTR_PAGE_SIZE );
160 if ( SfxItemState::SET == rSet->GetItemState( nW, false, &pItem ) )
162 // orientation and size from the PageItem
163 FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
165 aPageSize = static_cast<const SvxSizeItem*>(pItem)->GetSize();
167 auto nMin = m_xWidthMF->normalize( 23 );
168 auto nMax = m_xHeightMF->normalize(aPageSize.Height());
169 m_xHeightMF->set_range(nMin, nMax, eUnit);
170 nMax = m_xWidthMF->normalize(aPageSize.Width());
171 m_xWidthMF->set_range(nMin, nMax, eUnit);
173 else
175 aPageSize = OutputDevice::LogicToLogic(
176 Size( CM_1_TO_TWIP, CM_1_TO_TWIP ),
177 MapMode( MapUnit::MapTwip ),
178 MapMode( rSet->GetPool()->GetMetric( nW ) ) );
181 bool bFound = false;
182 if( SfxItemState::SET == rSet->GetItemState( SID_ATTR_GRAF_GRAPHIC, false, &pItem ) )
184 OUString referer;
185 SfxStringItem const * it = static_cast<SfxStringItem const *>(
186 rSet->GetItem(SID_REFERER));
187 if (it != nullptr) {
188 referer = it->GetValue();
190 const Graphic* pGrf = static_cast<const SvxBrushItem*>(pItem)->GetGraphic(referer);
191 if( pGrf )
193 aOrigSize = GetGrfOrigSize( *pGrf );
194 if (pGrf->GetType() == GraphicType::Bitmap && aOrigSize.Width() && aOrigSize.Height())
196 aOrigPixelSize = pGrf->GetSizePixel();
199 if( aOrigSize.Width() && aOrigSize.Height() )
201 CalcMinMaxBorder();
202 m_aExampleWN.SetGraphic( *pGrf );
203 m_aExampleWN.SetFrameSize( aOrigSize );
205 bFound = true;
206 if( !static_cast<const SvxBrushItem*>(pItem)->GetGraphicLink().isEmpty() )
207 aGraphicName = static_cast<const SvxBrushItem*>(pItem)->GetGraphicLink();
212 GraphicHasChanged( bFound );
213 ActivatePage( *rSet );
216 bool SvxGrfCropPage::FillItemSet(SfxItemSet *rSet)
218 const SfxItemPool& rPool = *rSet->GetPool();
219 bool bModified = false;
220 if( m_xWidthMF->get_value_changed_from_saved() ||
221 m_xHeightMF->get_value_changed_from_saved() )
223 sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_FRMSIZE );
224 FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
226 std::shared_ptr<SvxSizeItem> aSz(std::make_shared<SvxSizeItem>(nW));
228 // size could already have been set from another page
229 const SfxItemSet* pExSet = GetDialogExampleSet();
230 const SfxPoolItem* pItem = nullptr;
231 if( pExSet && SfxItemState::SET ==pExSet->GetItemState( nW, false, &pItem ) )
233 aSz.reset(static_cast< SvxSizeItem*>(pItem->Clone()));
235 else
237 aSz.reset(static_cast< SvxSizeItem*>(GetItemSet().Get(nW).Clone()));
240 Size aTmpSz( aSz->GetSize() );
241 if( m_xWidthMF->get_value_changed_from_saved() )
242 aTmpSz.setWidth( lcl_GetValue( *m_xWidthMF, eUnit ) );
243 if( m_xHeightMF->get_value_changed_from_saved() )
244 aTmpSz.setHeight( lcl_GetValue( *m_xHeightMF, eUnit ) );
245 aSz->SetSize( aTmpSz );
246 m_xWidthMF->save_value();
247 m_xHeightMF->save_value();
249 bModified |= nullptr != rSet->Put( *aSz );
251 if( bSetOrigSize )
253 bModified |= nullptr != rSet->Put( SvxSizeItem( rPool.GetWhich(
254 SID_ATTR_GRAF_FRMSIZE_PERCENT ), Size( 0, 0 )) );
257 if( m_xLeftMF->get_value_changed_from_saved() || m_xRightMF->get_value_changed_from_saved() ||
258 m_xTopMF->get_value_changed_from_saved() || m_xBottomMF->get_value_changed_from_saved() )
260 sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_CROP );
261 FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
262 std::unique_ptr<SvxGrfCrop> pNew(static_cast<SvxGrfCrop*>(rSet->Get( nW ).Clone()));
264 pNew->SetLeft( lcl_GetValue( *m_xLeftMF, eUnit ) );
265 pNew->SetRight( lcl_GetValue( *m_xRightMF, eUnit ) );
266 pNew->SetTop( lcl_GetValue( *m_xTopMF, eUnit ) );
267 pNew->SetBottom( lcl_GetValue( *m_xBottomMF, eUnit ) );
268 bModified |= nullptr != rSet->Put( *pNew );
271 if( m_xZoomConstRB->get_state_changed_from_saved() )
273 bModified |= nullptr != rSet->Put( SfxBoolItem( rPool.GetWhich(
274 SID_ATTR_GRAF_KEEP_ZOOM), m_xZoomConstRB->get_active() ) );
277 return bModified;
280 void SvxGrfCropPage::ActivatePage(const SfxItemSet& rSet)
282 #ifdef DBG_UTIL
283 SfxItemPool* pPool = GetItemSet().GetPool();
284 DBG_ASSERT( pPool, "Where is the pool?" );
285 #endif
287 bSetOrigSize = false;
289 // Size
290 Size aSize;
291 const SfxPoolItem* pItem;
292 if( SfxItemState::SET == rSet.GetItemState( SID_ATTR_GRAF_FRMSIZE, false, &pItem ) )
293 aSize = static_cast<const SvxSizeItem*>(pItem)->GetSize();
295 nOldWidth = aSize.Width();
296 nOldHeight = aSize.Height();
298 auto nWidth = m_xWidthMF->normalize(nOldWidth);
299 auto nHeight = m_xHeightMF->normalize(nOldHeight);
301 if (nWidth != m_xWidthMF->get_value(FieldUnit::TWIP))
302 m_xWidthMF->set_value(nWidth, FieldUnit::TWIP);
303 m_xWidthMF->save_value();
305 if (nHeight != m_xHeightMF->get_value(FieldUnit::TWIP))
306 m_xHeightMF->set_value(nHeight, FieldUnit::TWIP);
307 m_xHeightMF->save_value();
309 if( SfxItemState::SET == rSet.GetItemState( SID_ATTR_GRAF_GRAPHIC, false, &pItem ) )
311 const SvxBrushItem& rBrush = *static_cast<const SvxBrushItem*>(pItem);
312 if( !rBrush.GetGraphicLink().isEmpty() &&
313 aGraphicName != rBrush.GetGraphicLink() )
314 aGraphicName = rBrush.GetGraphicLink();
316 OUString referer;
317 SfxStringItem const * it = static_cast<SfxStringItem const *>(
318 rSet.GetItem(SID_REFERER));
319 if (it != nullptr) {
320 referer = it->GetValue();
322 const Graphic* pGrf = rBrush.GetGraphic(referer);
323 if( pGrf )
325 m_aExampleWN.SetGraphic( *pGrf );
326 aOrigSize = GetGrfOrigSize( *pGrf );
327 if (pGrf->GetType() == GraphicType::Bitmap && aOrigSize.Width() > 1 && aOrigSize.Height() > 1) {
328 aOrigPixelSize = pGrf->GetSizePixel();
330 m_aExampleWN.SetFrameSize(aOrigSize);
331 GraphicHasChanged( aOrigSize.Width() && aOrigSize.Height() );
332 CalcMinMaxBorder();
334 else
335 GraphicHasChanged( false );
338 CalcZoom();
341 DeactivateRC SvxGrfCropPage::DeactivatePage(SfxItemSet *_pSet)
343 if ( _pSet )
344 FillItemSet( _pSet );
345 return DeactivateRC::LeavePage;
348 /*--------------------------------------------------------------------
349 description: scale changed, adjust size
350 --------------------------------------------------------------------*/
352 IMPL_LINK( SvxGrfCropPage, ZoomHdl, weld::MetricSpinButton&, rField, void )
354 SfxItemPool* pPool = GetItemSet().GetPool();
355 DBG_ASSERT( pPool, "Where is the pool?" );
356 FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
357 SID_ATTR_GRAF_CROP ) ) );
359 if (&rField == m_xWidthZoomMF.get())
361 long nLRBorders = lcl_GetValue(*m_xLeftMF, eUnit)
362 +lcl_GetValue(*m_xRightMF, eUnit);
363 m_xWidthMF->set_value( m_xWidthMF->normalize(
364 ((aOrigSize.Width() - nLRBorders) * rField.get_value(FieldUnit::NONE))/100),
365 eUnit);
367 else
369 long nULBorders = lcl_GetValue(*m_xTopMF, eUnit)
370 +lcl_GetValue(*m_xBottomMF, eUnit);
371 m_xHeightMF->set_value( m_xHeightMF->normalize(
372 ((aOrigSize.Height() - nULBorders ) * rField.get_value(FieldUnit::NONE))/100) ,
373 eUnit );
377 /*--------------------------------------------------------------------
378 description: change size, adjust scale
379 --------------------------------------------------------------------*/
381 IMPL_LINK( SvxGrfCropPage, SizeHdl, weld::MetricSpinButton&, rField, void )
383 SfxItemPool* pPool = GetItemSet().GetPool();
384 DBG_ASSERT( pPool, "Where is the pool?" );
385 FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
386 SID_ATTR_GRAF_CROP ) ) );
388 Size aSize( lcl_GetValue(*m_xWidthMF, eUnit),
389 lcl_GetValue(*m_xHeightMF, eUnit) );
391 if(&rField == m_xWidthMF.get())
393 long nWidth = aOrigSize.Width() -
394 ( lcl_GetValue(*m_xLeftMF, eUnit) +
395 lcl_GetValue(*m_xRightMF, eUnit) );
396 if(!nWidth)
397 nWidth++;
398 sal_uInt16 nZoom = static_cast<sal_uInt16>( aSize.Width() * 100 / nWidth);
399 m_xWidthZoomMF->set_value(nZoom, FieldUnit::NONE);
401 else
403 long nHeight = aOrigSize.Height() -
404 ( lcl_GetValue(*m_xTopMF, eUnit) +
405 lcl_GetValue(*m_xBottomMF, eUnit));
406 if(!nHeight)
407 nHeight++;
408 sal_uInt16 nZoom = static_cast<sal_uInt16>( aSize.Height() * 100 / nHeight);
409 m_xHeightZoomMF->set_value(nZoom, FieldUnit::NONE);
413 /*--------------------------------------------------------------------
414 description: evaluate border
415 --------------------------------------------------------------------*/
417 IMPL_LINK( SvxGrfCropPage, CropModifyHdl, weld::MetricSpinButton&, rField, void )
419 SfxItemPool* pPool = GetItemSet().GetPool();
420 DBG_ASSERT( pPool, "Where is the pool?" );
421 FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
422 SID_ATTR_GRAF_CROP ) ) );
424 bool bZoom = m_xZoomConstRB->get_active();
425 if (&rField == m_xLeftMF.get() || &rField == m_xRightMF.get())
427 long nLeft = lcl_GetValue( *m_xLeftMF, eUnit );
428 long nRight = lcl_GetValue( *m_xRightMF, eUnit );
429 long nWidthZoom = static_cast<long>(m_xWidthZoomMF->get_value(FieldUnit::NONE));
430 if (bZoom && nWidthZoom != 0 && ( ( ( aOrigSize.Width() - (nLeft + nRight )) * nWidthZoom )
431 / 100 >= aPageSize.Width() ) )
433 if (&rField == m_xLeftMF.get())
435 nLeft = aOrigSize.Width() -
436 ( aPageSize.Width() * 100 / nWidthZoom + nRight );
437 m_xLeftMF->set_value( m_xLeftMF->normalize( nLeft ), eUnit );
439 else
441 nRight = aOrigSize.Width() -
442 ( aPageSize.Width() * 100 / nWidthZoom + nLeft );
443 m_xRightMF->set_value( m_xRightMF->normalize( nRight ), eUnit );
446 if (AllSettings::GetLayoutRTL())
448 m_aExampleWN.SetLeft(nRight);
449 m_aExampleWN.SetRight(nLeft);
451 else
453 m_aExampleWN.SetLeft(nLeft);
454 m_aExampleWN.SetRight(nRight);
456 if(bZoom)
458 // scale stays, recompute width
459 ZoomHdl(*m_xWidthZoomMF);
462 else
464 long nTop = lcl_GetValue( *m_xTopMF, eUnit );
465 long nBottom = lcl_GetValue( *m_xBottomMF, eUnit );
466 long nHeightZoom = static_cast<long>(m_xHeightZoomMF->get_value(FieldUnit::NONE));
467 if(bZoom && ( ( ( aOrigSize.Height() - (nTop + nBottom )) * nHeightZoom)
468 / 100 >= aPageSize.Height()))
470 assert(nHeightZoom && "div-by-zero");
471 if(&rField == m_xTopMF.get())
473 nTop = aOrigSize.Height() -
474 ( aPageSize.Height() * 100 / nHeightZoom + nBottom);
475 m_xTopMF->set_value( m_xWidthMF->normalize( nTop ), eUnit );
477 else
479 nBottom = aOrigSize.Height() -
480 ( aPageSize.Height() * 100 / nHeightZoom + nTop);
481 m_xBottomMF->set_value( m_xWidthMF->normalize( nBottom ), eUnit );
484 m_aExampleWN.SetTop( nTop );
485 m_aExampleWN.SetBottom( nBottom );
486 if(bZoom)
488 // scale stays, recompute height
489 ZoomHdl(*m_xHeightZoomMF);
492 m_aExampleWN.Invalidate();
493 // size and border changed -> recompute scale
494 if(!bZoom)
495 CalcZoom();
496 CalcMinMaxBorder();
498 /*--------------------------------------------------------------------
499 description: set original size
500 --------------------------------------------------------------------*/
502 IMPL_LINK_NOARG(SvxGrfCropPage, OrigSizeHdl, weld::Button&, void)
504 SfxItemPool* pPool = GetItemSet().GetPool();
505 DBG_ASSERT( pPool, "Where is the pool?" );
506 FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
507 SID_ATTR_GRAF_CROP ) ) );
509 long nWidth = aOrigSize.Width() -
510 lcl_GetValue( *m_xLeftMF, eUnit ) -
511 lcl_GetValue( *m_xRightMF, eUnit );
512 m_xWidthMF->set_value( m_xWidthMF->normalize( nWidth ), eUnit );
513 long nHeight = aOrigSize.Height() -
514 lcl_GetValue( *m_xTopMF, eUnit ) -
515 lcl_GetValue( *m_xBottomMF, eUnit );
516 m_xHeightMF->set_value( m_xHeightMF->normalize( nHeight ), eUnit );
517 m_xWidthZoomMF->set_value(100, FieldUnit::NONE);
518 m_xHeightZoomMF->set_value(100, FieldUnit::NONE);
519 bSetOrigSize = true;
521 /*--------------------------------------------------------------------
522 description: compute scale
523 --------------------------------------------------------------------*/
525 void SvxGrfCropPage::CalcZoom()
527 SfxItemPool* pPool = GetItemSet().GetPool();
528 DBG_ASSERT( pPool, "Where is the pool?" );
529 FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
530 SID_ATTR_GRAF_CROP ) ) );
532 long nWidth = lcl_GetValue( *m_xWidthMF, eUnit );
533 long nHeight = lcl_GetValue( *m_xHeightMF, eUnit );
534 long nLRBorders = lcl_GetValue( *m_xLeftMF, eUnit ) +
535 lcl_GetValue( *m_xRightMF, eUnit );
536 long nULBorders = lcl_GetValue( *m_xTopMF, eUnit ) +
537 lcl_GetValue( *m_xBottomMF, eUnit );
538 sal_uInt16 nZoom = 0;
539 long nDen;
540 if( (nDen = aOrigSize.Width() - nLRBorders) > 0)
541 nZoom = static_cast<sal_uInt16>((( nWidth * 1000 / nDen )+5)/10);
542 m_xWidthZoomMF->set_value(nZoom, FieldUnit::NONE);
543 if( (nDen = aOrigSize.Height() - nULBorders) > 0)
544 nZoom = static_cast<sal_uInt16>((( nHeight * 1000 / nDen )+5)/10);
545 else
546 nZoom = 0;
547 m_xHeightZoomMF->set_value(nZoom, FieldUnit::NONE);
550 /*--------------------------------------------------------------------
551 description: set minimum/maximum values for the margins
552 --------------------------------------------------------------------*/
554 void SvxGrfCropPage::CalcMinMaxBorder()
556 SfxItemPool* pPool = GetItemSet().GetPool();
557 DBG_ASSERT( pPool, "Where is the pool?" );
558 FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
559 SID_ATTR_GRAF_CROP ) ) );
560 long nR = lcl_GetValue(*m_xRightMF, eUnit );
561 long nMinWidth = (aOrigSize.Width() * 10) /11;
562 long nMin = nMinWidth - (nR >= 0 ? nR : 0);
563 m_xLeftMF->set_max( m_xLeftMF->normalize(nMin), eUnit );
565 long nL = lcl_GetValue(*m_xLeftMF, eUnit );
566 nMin = nMinWidth - (nL >= 0 ? nL : 0);
567 m_xRightMF->set_max( m_xRightMF->normalize(nMin), eUnit );
569 long nUp = lcl_GetValue( *m_xTopMF, eUnit );
570 long nMinHeight = (aOrigSize.Height() * 10) /11;
571 nMin = nMinHeight - (nUp >= 0 ? nUp : 0);
572 m_xBottomMF->set_max( m_xBottomMF->normalize(nMin), eUnit );
574 long nLow = lcl_GetValue(*m_xBottomMF, eUnit );
575 nMin = nMinHeight - (nLow >= 0 ? nLow : 0);
576 m_xTopMF->set_max( m_xTopMF->normalize(nMin), eUnit );
578 /*--------------------------------------------------------------------
579 description: set spinsize to 1/20 of the original size,
580 fill FixedText with the original size
581 --------------------------------------------------------------------*/
583 void SvxGrfCropPage::GraphicHasChanged( bool bFound )
585 if( bFound )
587 SfxItemPool* pPool = GetItemSet().GetPool();
588 DBG_ASSERT( pPool, "Where is the pool?" );
589 FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
590 SID_ATTR_GRAF_CROP ) ));
592 sal_Int64 nSpin = m_xLeftMF->normalize(aOrigSize.Width()) / 20;
593 nSpin = MetricField::ConvertValue( nSpin, aOrigSize.Width(), 0,
594 eUnit, m_xLeftMF->get_unit());
596 // if the margin is too big, it is set to 1/3 on both pages
597 long nR = lcl_GetValue( *m_xRightMF, eUnit );
598 long nL = lcl_GetValue( *m_xLeftMF, eUnit );
599 if((nL + nR) < - aOrigSize.Width())
601 long nVal = aOrigSize.Width() / -3;
602 m_xRightMF->set_value( m_xRightMF->normalize( nVal ), eUnit );
603 m_xLeftMF->set_value( m_xLeftMF->normalize( nVal ), eUnit );
604 m_aExampleWN.SetLeft(nVal);
605 m_aExampleWN.SetRight(nVal);
607 long nUp = lcl_GetValue(*m_xTopMF, eUnit );
608 long nLow = lcl_GetValue(*m_xBottomMF, eUnit );
609 if((nUp + nLow) < - aOrigSize.Height())
611 long nVal = aOrigSize.Height() / -3;
612 m_xTopMF->set_value( m_xTopMF->normalize( nVal ), eUnit );
613 m_xBottomMF->set_value( m_xBottomMF->normalize( nVal ), eUnit );
614 m_aExampleWN.SetTop(nVal);
615 m_aExampleWN.SetBottom(nVal);
618 m_xLeftMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
619 m_xRightMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
620 nSpin = m_xTopMF->normalize(aOrigSize.Height()) / 20;
621 nSpin = MetricField::ConvertValue( nSpin, aOrigSize.Width(), 0,
622 eUnit, m_xLeftMF->get_unit() );
623 m_xTopMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
624 m_xBottomMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
626 // display original size
627 const FieldUnit eMetric = GetModuleFieldUnit( GetItemSet() );
629 ScopedVclPtrInstance< MetricField > aFld(Application::GetDefDialogParent(), WB_HIDE);
630 SetFieldUnit( *aFld, eMetric );
631 aFld->SetDecimalDigits(m_xWidthMF->get_digits());
632 aFld->SetMax( LONG_MAX - 1 );
634 aFld->SetValue( aFld->Normalize( aOrigSize.Width() ), eUnit );
635 OUString sTemp = aFld->GetText();
636 aFld->SetValue( aFld->Normalize( aOrigSize.Height() ), eUnit );
637 // multiplication sign (U+00D7)
638 sTemp += u"\u00D7" + aFld->GetText();
640 if ( aOrigPixelSize.Width() && aOrigPixelSize.Height() ) {
641 sal_Int32 ax = sal_Int32(floor(static_cast<float>(aOrigPixelSize.Width()) /
642 (static_cast<float>(aOrigSize.Width())/TWIP_TO_INCH)+0.5));
643 sal_Int32 ay = sal_Int32(floor(static_cast<float>(aOrigPixelSize.Height()) /
644 (static_cast<float>(aOrigSize.Height())/TWIP_TO_INCH)+0.5));
645 sTemp += " " + CuiResId( RID_SVXSTR_PPI );
646 OUString sPPI = OUString::number(ax);
647 if (abs(ax - ay) > 1) {
648 sPPI += u"\u00D7" + OUString::number(ay);
650 sTemp = sTemp.replaceAll("%1", sPPI);
652 m_xOrigSizeFT->set_label(sTemp);
655 m_xCropFrame->set_sensitive(bFound);
656 m_xScaleFrame->set_sensitive(bFound);
657 m_xSizeFrame->set_sensitive(bFound);
658 m_xOrigSizeGrid->set_sensitive(bFound);
659 m_xZoomConstRB->set_sensitive(bFound);
662 Size SvxGrfCropPage::GetGrfOrigSize(const Graphic& rGrf)
664 const MapMode aMapTwip( MapUnit::MapTwip );
665 Size aSize( rGrf.GetPrefSize() );
666 if( MapUnit::MapPixel == rGrf.GetPrefMapMode().GetMapUnit() )
667 aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMapTwip);
668 else
669 aSize = OutputDevice::LogicToLogic( aSize,
670 rGrf.GetPrefMapMode(), aMapTwip );
671 return aSize;
674 /*****************************************************************/
676 SvxCropExample::SvxCropExample()
677 : m_aTopLeft(0, 0)
678 , m_aBottomRight(0, 0)
682 void SvxCropExample::SetDrawingArea(weld::DrawingArea* pDrawingArea)
684 CustomWidgetController::SetDrawingArea(pDrawingArea);
685 OutputDevice& rDevice = pDrawingArea->get_ref_device();
686 Size aSize(rDevice.LogicToPixel(Size(78, 78), MapMode(MapUnit::MapAppFont)));
687 pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
689 m_aMapMode = rDevice.GetMapMode();
690 m_aFrameSize = OutputDevice::LogicToLogic(
691 Size(CM_1_TO_TWIP / 2, CM_1_TO_TWIP / 2),
692 MapMode(MapUnit::MapTwip), m_aMapMode);
695 void SvxCropExample::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&)
697 rRenderContext.Push(PushFlags::MAPMODE | PushFlags::RASTEROP);
698 rRenderContext.SetMapMode(m_aMapMode);
700 Size aWinSize(rRenderContext.PixelToLogic(GetOutputSizePixel()));
701 rRenderContext.SetLineColor();
702 rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetWindowColor());
703 rRenderContext.DrawRect(::tools::Rectangle(Point(), aWinSize));
705 rRenderContext.SetLineColor(COL_WHITE);
706 ::tools::Rectangle aRect(Point((aWinSize.Width() - m_aFrameSize.Width())/2,
707 (aWinSize.Height() - m_aFrameSize.Height())/2),
708 m_aFrameSize);
709 m_aGrf.Draw(&rRenderContext, aRect.TopLeft(), aRect.GetSize());
711 rRenderContext.SetFillColor(COL_TRANSPARENT);
712 rRenderContext.SetRasterOp(RasterOp::Invert);
713 aRect.AdjustLeft(m_aTopLeft.Y() );
714 aRect.AdjustTop(m_aTopLeft.X() );
715 aRect.AdjustRight(-m_aBottomRight.Y());
716 aRect.AdjustBottom(-m_aBottomRight.X());
717 rRenderContext.DrawRect(aRect);
719 rRenderContext.Pop();
722 void SvxCropExample::Resize()
724 SetFrameSize(m_aFrameSize);
727 void SvxCropExample::SetFrameSize( const Size& rSz )
729 m_aFrameSize = rSz;
730 if (!m_aFrameSize.Width())
731 m_aFrameSize.setWidth( 1 );
732 if (!m_aFrameSize.Height())
733 m_aFrameSize.setHeight( 1 );
734 Size aWinSize( GetOutputSizePixel() );
735 Fraction aXScale( aWinSize.Width() * 4, m_aFrameSize.Width() * 5 );
736 Fraction aYScale( aWinSize.Height() * 4, m_aFrameSize.Height() * 5 );
738 if( aYScale < aXScale )
739 aXScale = aYScale;
741 m_aMapMode.SetScaleX(aXScale);
742 m_aMapMode.SetScaleY(aXScale);
744 Invalidate();
747 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */