bump product version to 6.3.0.0.beta1
[LibreOffice.git] / cui / source / tabpages / grfpage.cxx
blob46d3966a91ecab24f3ca9e2fda8d626387f7eeac
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 <sfx2/app.hxx>
24 #include <sfx2/module.hxx>
25 #include <sfx2/sfxsids.hrc>
26 #include <dialmgr.hxx>
27 #include <svx/dlgutil.hxx>
28 #include <editeng/sizeitem.hxx>
29 #include <editeng/brushitem.hxx>
30 #include <grfpage.hxx>
31 #include <svx/grfcrop.hxx>
32 #include <rtl/ustring.hxx>
33 #include <tools/fract.hxx>
34 #include <svx/dialogs.hrc>
35 #include <svx/svxids.hrc>
36 #include <strings.hrc>
37 #include <vcl/field.hxx>
38 #include <vcl/settings.hxx>
39 #include <svtools/unitconv.hxx>
41 #define CM_1_TO_TWIP 567
42 #define TWIP_TO_INCH 1440
45 static int lcl_GetValue(const weld::MetricSpinButton& rMetric, FieldUnit eUnit)
47 return rMetric.denormalize(rMetric.get_value(eUnit));
50 /*--------------------------------------------------------------------
51 description: crop graphic
52 --------------------------------------------------------------------*/
54 SvxGrfCropPage::SvxGrfCropPage(TabPageParent pParent, const SfxItemSet &rSet)
55 : SfxTabPage(pParent, "cui/ui/croppage.ui", "CropPage", &rSet)
56 , nOldWidth(0)
57 , nOldHeight(0)
58 , bSetOrigSize(false)
59 , m_xCropFrame(m_xBuilder->weld_widget("cropframe"))
60 , m_xZoomConstRB(m_xBuilder->weld_radio_button("keepscale"))
61 , m_xSizeConstRB(m_xBuilder->weld_radio_button("keepsize"))
62 , m_xLeftMF(m_xBuilder->weld_metric_spin_button("left", FieldUnit::CM))
63 , m_xRightMF(m_xBuilder->weld_metric_spin_button("right", FieldUnit::CM))
64 , m_xTopMF(m_xBuilder->weld_metric_spin_button("top", FieldUnit::CM))
65 , m_xBottomMF(m_xBuilder->weld_metric_spin_button("bottom", FieldUnit::CM))
66 , m_xScaleFrame(m_xBuilder->weld_widget("scaleframe"))
67 , m_xWidthZoomMF(m_xBuilder->weld_metric_spin_button("widthzoom", FieldUnit::PERCENT))
68 , m_xHeightZoomMF(m_xBuilder->weld_metric_spin_button("heightzoom", FieldUnit::PERCENT))
69 , m_xSizeFrame(m_xBuilder->weld_widget("sizeframe"))
70 , m_xWidthMF(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM))
71 , m_xHeightMF(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM))
72 , m_xOrigSizeGrid(m_xBuilder->weld_widget("origsizegrid"))
73 , m_xOrigSizeFT(m_xBuilder->weld_label("origsizeft"))
74 , m_xOrigSizePB(m_xBuilder->weld_button("origsize"))
75 , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, "preview", m_aExampleWN))
77 SetExchangeSupport();
79 // set the correct metric
80 const FieldUnit eMetric = GetModuleFieldUnit( rSet );
82 SetFieldUnit( *m_xWidthMF, eMetric );
83 SetFieldUnit( *m_xHeightMF, eMetric );
84 SetFieldUnit( *m_xLeftMF, eMetric );
85 SetFieldUnit( *m_xRightMF, eMetric );
86 SetFieldUnit( *m_xTopMF , eMetric );
87 SetFieldUnit( *m_xBottomMF, eMetric );
89 Link<weld::MetricSpinButton&,void> aLk = LINK(this, SvxGrfCropPage, SizeHdl);
90 m_xWidthMF->connect_value_changed( aLk );
91 m_xHeightMF->connect_value_changed( aLk );
93 aLk = LINK(this, SvxGrfCropPage, ZoomHdl);
94 m_xWidthZoomMF->connect_value_changed( aLk );
95 m_xHeightZoomMF->connect_value_changed( aLk );
97 aLk = LINK(this, SvxGrfCropPage, CropModifyHdl);
98 m_xLeftMF->connect_value_changed( aLk );
99 m_xRightMF->connect_value_changed( aLk );
100 m_xTopMF->connect_value_changed( aLk );
101 m_xBottomMF->connect_value_changed( aLk );
103 m_xOrigSizePB->connect_clicked(LINK(this, SvxGrfCropPage, OrigSizeHdl));
106 SvxGrfCropPage::~SvxGrfCropPage()
108 disposeOnce();
111 void SvxGrfCropPage::dispose()
113 m_xExampleWN.reset();
114 SfxTabPage::dispose();
117 VclPtr<SfxTabPage> SvxGrfCropPage::Create(TabPageParent pParent, const SfxItemSet *rSet)
119 return VclPtr<SvxGrfCropPage>::Create(pParent, *rSet);
122 void SvxGrfCropPage::Reset( const SfxItemSet *rSet )
124 const SfxPoolItem* pItem;
125 const SfxItemPool& rPool = *rSet->GetPool();
127 if(SfxItemState::SET == rSet->GetItemState( rPool.GetWhich(
128 SID_ATTR_GRAF_KEEP_ZOOM ), true, &pItem ))
130 if( static_cast<const SfxBoolItem*>(pItem)->GetValue() )
131 m_xZoomConstRB->set_active(true);
132 else
133 m_xSizeConstRB->set_active(true);
134 m_xZoomConstRB->save_state();
137 sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_CROP );
138 if( SfxItemState::SET == rSet->GetItemState( nW, true, &pItem))
140 FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
142 const SvxGrfCrop* pCrop = static_cast<const SvxGrfCrop*>(pItem);
144 m_aExampleWN.SetLeft(pCrop->GetLeft());
145 m_aExampleWN.SetRight(pCrop->GetRight());
146 m_aExampleWN.SetTop(pCrop->GetTop());
147 m_aExampleWN.SetBottom(pCrop->GetBottom());
149 m_xLeftMF->set_value( m_xLeftMF->normalize( pCrop->GetLeft()), eUnit );
150 m_xRightMF->set_value( m_xRightMF->normalize( pCrop->GetRight()), eUnit );
151 m_xTopMF->set_value( m_xTopMF->normalize( pCrop->GetTop()), eUnit );
152 m_xBottomMF->set_value( m_xBottomMF->normalize( pCrop->GetBottom()), eUnit );
154 else
156 m_xLeftMF->set_value(0, FieldUnit::NONE);
157 m_xRightMF->set_value(0, FieldUnit::NONE);
158 m_xTopMF->set_value(0, FieldUnit::NONE);
159 m_xBottomMF->set_value(0, FieldUnit::NONE);
162 m_xLeftMF->save_value();
163 m_xRightMF->save_value();
164 m_xTopMF->save_value();
165 m_xBottomMF->save_value();
167 nW = rPool.GetWhich( SID_ATTR_PAGE_SIZE );
168 if ( SfxItemState::SET == rSet->GetItemState( nW, false, &pItem ) )
170 // orientation and size from the PageItem
171 FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
173 aPageSize = static_cast<const SvxSizeItem*>(pItem)->GetSize();
175 auto nMin = m_xWidthMF->normalize( 23 );
176 auto nMax = m_xHeightMF->normalize(aPageSize.Height());
177 m_xHeightMF->set_range(nMin, nMax, eUnit);
178 nMax = m_xWidthMF->normalize(aPageSize.Width());
179 m_xWidthMF->set_range(nMin, nMax, eUnit);
181 else
183 aPageSize = OutputDevice::LogicToLogic(
184 Size( CM_1_TO_TWIP, CM_1_TO_TWIP ),
185 MapMode( MapUnit::MapTwip ),
186 MapMode( rSet->GetPool()->GetMetric( nW ) ) );
189 bool bFound = false;
190 if( SfxItemState::SET == rSet->GetItemState( SID_ATTR_GRAF_GRAPHIC, false, &pItem ) )
192 OUString referer;
193 SfxStringItem const * it = static_cast<SfxStringItem const *>(
194 rSet->GetItem(SID_REFERER));
195 if (it != nullptr) {
196 referer = it->GetValue();
198 const Graphic* pGrf = static_cast<const SvxBrushItem*>(pItem)->GetGraphic(referer);
199 if( pGrf )
201 aOrigSize = GetGrfOrigSize( *pGrf );
202 if (pGrf->GetType() == GraphicType::Bitmap && aOrigSize.Width() && aOrigSize.Height())
204 aOrigPixelSize = pGrf->GetSizePixel();
207 if( aOrigSize.Width() && aOrigSize.Height() )
209 CalcMinMaxBorder();
210 m_aExampleWN.SetGraphic( *pGrf );
211 m_aExampleWN.SetFrameSize( aOrigSize );
213 bFound = true;
214 if( !static_cast<const SvxBrushItem*>(pItem)->GetGraphicLink().isEmpty() )
215 aGraphicName = static_cast<const SvxBrushItem*>(pItem)->GetGraphicLink();
220 GraphicHasChanged( bFound );
221 ActivatePage( *rSet );
224 bool SvxGrfCropPage::FillItemSet(SfxItemSet *rSet)
226 const SfxItemPool& rPool = *rSet->GetPool();
227 bool bModified = false;
228 if( m_xWidthMF->get_value_changed_from_saved() ||
229 m_xHeightMF->get_value_changed_from_saved() )
231 sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_FRMSIZE );
232 FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
234 std::shared_ptr<SvxSizeItem> aSz(std::make_shared<SvxSizeItem>(nW));
236 // size could already have been set from another page
237 const SfxItemSet* pExSet = GetDialogExampleSet();
238 const SfxPoolItem* pItem = nullptr;
239 if( pExSet && SfxItemState::SET ==pExSet->GetItemState( nW, false, &pItem ) )
241 aSz.reset(static_cast< SvxSizeItem*>(pItem->Clone()));
243 else
245 aSz.reset(static_cast< SvxSizeItem*>(GetItemSet().Get(nW).Clone()));
248 Size aTmpSz( aSz->GetSize() );
249 if( m_xWidthMF->get_value_changed_from_saved() )
250 aTmpSz.setWidth( lcl_GetValue( *m_xWidthMF, eUnit ) );
251 if( m_xHeightMF->get_value_changed_from_saved() )
252 aTmpSz.setHeight( lcl_GetValue( *m_xHeightMF, eUnit ) );
253 aSz->SetSize( aTmpSz );
254 m_xWidthMF->save_value();
255 m_xHeightMF->save_value();
257 bModified |= nullptr != rSet->Put( *aSz );
259 if( bSetOrigSize )
261 bModified |= nullptr != rSet->Put( SvxSizeItem( rPool.GetWhich(
262 SID_ATTR_GRAF_FRMSIZE_PERCENT ), Size( 0, 0 )) );
265 if( m_xLeftMF->get_value_changed_from_saved() || m_xRightMF->get_value_changed_from_saved() ||
266 m_xTopMF->get_value_changed_from_saved() || m_xBottomMF->get_value_changed_from_saved() )
268 sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_CROP );
269 FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
270 std::unique_ptr<SvxGrfCrop> pNew(static_cast<SvxGrfCrop*>(rSet->Get( nW ).Clone()));
272 pNew->SetLeft( lcl_GetValue( *m_xLeftMF, eUnit ) );
273 pNew->SetRight( lcl_GetValue( *m_xRightMF, eUnit ) );
274 pNew->SetTop( lcl_GetValue( *m_xTopMF, eUnit ) );
275 pNew->SetBottom( lcl_GetValue( *m_xBottomMF, eUnit ) );
276 bModified |= nullptr != rSet->Put( *pNew );
279 if( m_xZoomConstRB->get_state_changed_from_saved() )
281 bModified |= nullptr != rSet->Put( SfxBoolItem( rPool.GetWhich(
282 SID_ATTR_GRAF_KEEP_ZOOM), m_xZoomConstRB->get_active() ) );
285 return bModified;
288 void SvxGrfCropPage::ActivatePage(const SfxItemSet& rSet)
290 #ifdef DBG_UTIL
291 SfxItemPool* pPool = GetItemSet().GetPool();
292 DBG_ASSERT( pPool, "Where is the pool?" );
293 #endif
295 bSetOrigSize = false;
297 // Size
298 Size aSize;
299 const SfxPoolItem* pItem;
300 if( SfxItemState::SET == rSet.GetItemState( SID_ATTR_GRAF_FRMSIZE, false, &pItem ) )
301 aSize = static_cast<const SvxSizeItem*>(pItem)->GetSize();
303 nOldWidth = aSize.Width();
304 nOldHeight = aSize.Height();
306 auto nWidth = m_xWidthMF->normalize(nOldWidth);
307 auto nHeight = m_xHeightMF->normalize(nOldHeight);
309 if (nWidth != m_xWidthMF->get_value(FieldUnit::TWIP))
310 m_xWidthMF->set_value(nWidth, FieldUnit::TWIP);
311 m_xWidthMF->save_value();
313 if (nHeight != m_xHeightMF->get_value(FieldUnit::TWIP))
314 m_xHeightMF->set_value(nHeight, FieldUnit::TWIP);
315 m_xHeightMF->save_value();
317 if( SfxItemState::SET == rSet.GetItemState( SID_ATTR_GRAF_GRAPHIC, false, &pItem ) )
319 const SvxBrushItem& rBrush = *static_cast<const SvxBrushItem*>(pItem);
320 if( !rBrush.GetGraphicLink().isEmpty() &&
321 aGraphicName != rBrush.GetGraphicLink() )
322 aGraphicName = rBrush.GetGraphicLink();
324 OUString referer;
325 SfxStringItem const * it = static_cast<SfxStringItem const *>(
326 rSet.GetItem(SID_REFERER));
327 if (it != nullptr) {
328 referer = it->GetValue();
330 const Graphic* pGrf = rBrush.GetGraphic(referer);
331 if( pGrf )
333 m_aExampleWN.SetGraphic( *pGrf );
334 aOrigSize = GetGrfOrigSize( *pGrf );
335 if (pGrf->GetType() == GraphicType::Bitmap && aOrigSize.Width() > 1 && aOrigSize.Height() > 1) {
336 aOrigPixelSize = pGrf->GetSizePixel();
338 m_aExampleWN.SetFrameSize(aOrigSize);
339 GraphicHasChanged( aOrigSize.Width() && aOrigSize.Height() );
340 CalcMinMaxBorder();
342 else
343 GraphicHasChanged( false );
346 CalcZoom();
349 DeactivateRC SvxGrfCropPage::DeactivatePage(SfxItemSet *_pSet)
351 if ( _pSet )
352 FillItemSet( _pSet );
353 return DeactivateRC::LeavePage;
356 /*--------------------------------------------------------------------
357 description: scale changed, adjust size
358 --------------------------------------------------------------------*/
360 IMPL_LINK( SvxGrfCropPage, ZoomHdl, weld::MetricSpinButton&, rField, void )
362 SfxItemPool* pPool = GetItemSet().GetPool();
363 DBG_ASSERT( pPool, "Where is the pool?" );
364 FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
365 SID_ATTR_GRAF_CROP ) ) );
367 if (&rField == m_xWidthZoomMF.get())
369 long nLRBorders = lcl_GetValue(*m_xLeftMF, eUnit)
370 +lcl_GetValue(*m_xRightMF, eUnit);
371 m_xWidthMF->set_value( m_xWidthMF->normalize(
372 ((aOrigSize.Width() - nLRBorders) * rField.get_value(FieldUnit::NONE))/100),
373 eUnit);
375 else
377 long nULBorders = lcl_GetValue(*m_xTopMF, eUnit)
378 +lcl_GetValue(*m_xBottomMF, eUnit);
379 m_xHeightMF->set_value( m_xHeightMF->normalize(
380 ((aOrigSize.Height() - nULBorders ) * rField.get_value(FieldUnit::NONE))/100) ,
381 eUnit );
385 /*--------------------------------------------------------------------
386 description: change size, adjust scale
387 --------------------------------------------------------------------*/
389 IMPL_LINK( SvxGrfCropPage, SizeHdl, weld::MetricSpinButton&, rField, void )
391 SfxItemPool* pPool = GetItemSet().GetPool();
392 DBG_ASSERT( pPool, "Where is the pool?" );
393 FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
394 SID_ATTR_GRAF_CROP ) ) );
396 Size aSize( lcl_GetValue(*m_xWidthMF, eUnit),
397 lcl_GetValue(*m_xHeightMF, eUnit) );
399 if(&rField == m_xWidthMF.get())
401 long nWidth = aOrigSize.Width() -
402 ( lcl_GetValue(*m_xLeftMF, eUnit) +
403 lcl_GetValue(*m_xRightMF, eUnit) );
404 if(!nWidth)
405 nWidth++;
406 sal_uInt16 nZoom = static_cast<sal_uInt16>( aSize.Width() * 100 / nWidth);
407 m_xWidthZoomMF->set_value(nZoom, FieldUnit::NONE);
409 else
411 long nHeight = aOrigSize.Height() -
412 ( lcl_GetValue(*m_xTopMF, eUnit) +
413 lcl_GetValue(*m_xBottomMF, eUnit));
414 if(!nHeight)
415 nHeight++;
416 sal_uInt16 nZoom = static_cast<sal_uInt16>( aSize.Height() * 100 / nHeight);
417 m_xHeightZoomMF->set_value(nZoom, FieldUnit::NONE);
421 /*--------------------------------------------------------------------
422 description: evaluate border
423 --------------------------------------------------------------------*/
425 IMPL_LINK( SvxGrfCropPage, CropModifyHdl, weld::MetricSpinButton&, rField, void )
427 SfxItemPool* pPool = GetItemSet().GetPool();
428 DBG_ASSERT( pPool, "Where is the pool?" );
429 FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
430 SID_ATTR_GRAF_CROP ) ) );
432 bool bZoom = m_xZoomConstRB->get_active();
433 if (&rField == m_xLeftMF.get() || &rField == m_xRightMF.get())
435 long nLeft = lcl_GetValue( *m_xLeftMF, eUnit );
436 long nRight = lcl_GetValue( *m_xRightMF, eUnit );
437 long nWidthZoom = static_cast<long>(m_xWidthZoomMF->get_value(FieldUnit::NONE));
438 if (bZoom && nWidthZoom != 0 && ( ( ( aOrigSize.Width() - (nLeft + nRight )) * nWidthZoom )
439 / 100 >= aPageSize.Width() ) )
441 if (&rField == m_xLeftMF.get())
443 nLeft = aOrigSize.Width() -
444 ( aPageSize.Width() * 100 / nWidthZoom + nRight );
445 m_xLeftMF->set_value( m_xLeftMF->normalize( nLeft ), eUnit );
447 else
449 nRight = aOrigSize.Width() -
450 ( aPageSize.Width() * 100 / nWidthZoom + nLeft );
451 m_xRightMF->set_value( m_xRightMF->normalize( nRight ), eUnit );
454 if (AllSettings::GetLayoutRTL())
456 m_aExampleWN.SetLeft(nRight);
457 m_aExampleWN.SetRight(nLeft);
459 else
461 m_aExampleWN.SetLeft(nLeft);
462 m_aExampleWN.SetRight(nRight);
464 if(bZoom)
466 // scale stays, recompute width
467 ZoomHdl(*m_xWidthZoomMF);
470 else
472 long nTop = lcl_GetValue( *m_xTopMF, eUnit );
473 long nBottom = lcl_GetValue( *m_xBottomMF, eUnit );
474 long nHeightZoom = static_cast<long>(m_xHeightZoomMF->get_value(FieldUnit::NONE));
475 if(bZoom && ( ( ( aOrigSize.Height() - (nTop + nBottom )) * nHeightZoom)
476 / 100 >= aPageSize.Height()))
478 assert(nHeightZoom && "div-by-zero");
479 if(&rField == m_xTopMF.get())
481 nTop = aOrigSize.Height() -
482 ( aPageSize.Height() * 100 / nHeightZoom + nBottom);
483 m_xTopMF->set_value( m_xWidthMF->normalize( nTop ), eUnit );
485 else
487 nBottom = aOrigSize.Height() -
488 ( aPageSize.Height() * 100 / nHeightZoom + nTop);
489 m_xBottomMF->set_value( m_xWidthMF->normalize( nBottom ), eUnit );
492 m_aExampleWN.SetTop( nTop );
493 m_aExampleWN.SetBottom( nBottom );
494 if(bZoom)
496 // scale stays, recompute height
497 ZoomHdl(*m_xHeightZoomMF);
500 m_aExampleWN.Invalidate();
501 // size and border changed -> recompute scale
502 if(!bZoom)
503 CalcZoom();
504 CalcMinMaxBorder();
506 /*--------------------------------------------------------------------
507 description: set original size
508 --------------------------------------------------------------------*/
510 IMPL_LINK_NOARG(SvxGrfCropPage, OrigSizeHdl, weld::Button&, void)
512 SfxItemPool* pPool = GetItemSet().GetPool();
513 DBG_ASSERT( pPool, "Where is the pool?" );
514 FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
515 SID_ATTR_GRAF_CROP ) ) );
517 long nWidth = aOrigSize.Width() -
518 lcl_GetValue( *m_xLeftMF, eUnit ) -
519 lcl_GetValue( *m_xRightMF, eUnit );
520 m_xWidthMF->set_value( m_xWidthMF->normalize( nWidth ), eUnit );
521 long nHeight = aOrigSize.Height() -
522 lcl_GetValue( *m_xTopMF, eUnit ) -
523 lcl_GetValue( *m_xBottomMF, eUnit );
524 m_xHeightMF->set_value( m_xHeightMF->normalize( nHeight ), eUnit );
525 m_xWidthZoomMF->set_value(100, FieldUnit::NONE);
526 m_xHeightZoomMF->set_value(100, FieldUnit::NONE);
527 bSetOrigSize = true;
529 /*--------------------------------------------------------------------
530 description: compute scale
531 --------------------------------------------------------------------*/
533 void SvxGrfCropPage::CalcZoom()
535 SfxItemPool* pPool = GetItemSet().GetPool();
536 DBG_ASSERT( pPool, "Where is the pool?" );
537 FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
538 SID_ATTR_GRAF_CROP ) ) );
540 long nWidth = lcl_GetValue( *m_xWidthMF, eUnit );
541 long nHeight = lcl_GetValue( *m_xHeightMF, eUnit );
542 long nLRBorders = lcl_GetValue( *m_xLeftMF, eUnit ) +
543 lcl_GetValue( *m_xRightMF, eUnit );
544 long nULBorders = lcl_GetValue( *m_xTopMF, eUnit ) +
545 lcl_GetValue( *m_xBottomMF, eUnit );
546 sal_uInt16 nZoom = 0;
547 long nDen;
548 if( (nDen = aOrigSize.Width() - nLRBorders) > 0)
549 nZoom = static_cast<sal_uInt16>((( nWidth * 1000 / nDen )+5)/10);
550 m_xWidthZoomMF->set_value(nZoom, FieldUnit::NONE);
551 if( (nDen = aOrigSize.Height() - nULBorders) > 0)
552 nZoom = static_cast<sal_uInt16>((( nHeight * 1000 / nDen )+5)/10);
553 else
554 nZoom = 0;
555 m_xHeightZoomMF->set_value(nZoom, FieldUnit::NONE);
558 /*--------------------------------------------------------------------
559 description: set minimum/maximum values for the margins
560 --------------------------------------------------------------------*/
562 void SvxGrfCropPage::CalcMinMaxBorder()
564 SfxItemPool* pPool = GetItemSet().GetPool();
565 DBG_ASSERT( pPool, "Where is the pool?" );
566 FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
567 SID_ATTR_GRAF_CROP ) ) );
568 long nR = lcl_GetValue(*m_xRightMF, eUnit );
569 long nMinWidth = (aOrigSize.Width() * 10) /11;
570 long nMin = nMinWidth - (nR >= 0 ? nR : 0);
571 m_xLeftMF->set_max( m_xLeftMF->normalize(nMin), eUnit );
573 long nL = lcl_GetValue(*m_xLeftMF, eUnit );
574 nMin = nMinWidth - (nL >= 0 ? nL : 0);
575 m_xRightMF->set_max( m_xRightMF->normalize(nMin), eUnit );
577 long nUp = lcl_GetValue( *m_xTopMF, eUnit );
578 long nMinHeight = (aOrigSize.Height() * 10) /11;
579 nMin = nMinHeight - (nUp >= 0 ? nUp : 0);
580 m_xBottomMF->set_max( m_xBottomMF->normalize(nMin), eUnit );
582 long nLow = lcl_GetValue(*m_xBottomMF, eUnit );
583 nMin = nMinHeight - (nLow >= 0 ? nLow : 0);
584 m_xTopMF->set_max( m_xTopMF->normalize(nMin), eUnit );
586 /*--------------------------------------------------------------------
587 description: set spinsize to 1/20 of the original size,
588 fill FixedText with the original size
589 --------------------------------------------------------------------*/
591 void SvxGrfCropPage::GraphicHasChanged( bool bFound )
593 if( bFound )
595 SfxItemPool* pPool = GetItemSet().GetPool();
596 DBG_ASSERT( pPool, "Where is the pool?" );
597 FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
598 SID_ATTR_GRAF_CROP ) ));
600 sal_Int64 nSpin = m_xLeftMF->normalize(aOrigSize.Width()) / 20;
601 nSpin = MetricField::ConvertValue( nSpin, aOrigSize.Width(), 0,
602 eUnit, m_xLeftMF->get_unit());
604 // if the margin is too big, it is set to 1/3 on both pages
605 long nR = lcl_GetValue( *m_xRightMF, eUnit );
606 long nL = lcl_GetValue( *m_xLeftMF, eUnit );
607 if((nL + nR) < - aOrigSize.Width())
609 long nVal = aOrigSize.Width() / -3;
610 m_xRightMF->set_value( m_xRightMF->normalize( nVal ), eUnit );
611 m_xLeftMF->set_value( m_xLeftMF->normalize( nVal ), eUnit );
612 m_aExampleWN.SetLeft(nVal);
613 m_aExampleWN.SetRight(nVal);
615 long nUp = lcl_GetValue(*m_xTopMF, eUnit );
616 long nLow = lcl_GetValue(*m_xBottomMF, eUnit );
617 if((nUp + nLow) < - aOrigSize.Height())
619 long nVal = aOrigSize.Height() / -3;
620 m_xTopMF->set_value( m_xTopMF->normalize( nVal ), eUnit );
621 m_xBottomMF->set_value( m_xBottomMF->normalize( nVal ), eUnit );
622 m_aExampleWN.SetTop(nVal);
623 m_aExampleWN.SetBottom(nVal);
626 m_xLeftMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
627 m_xRightMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
628 nSpin = m_xTopMF->normalize(aOrigSize.Height()) / 20;
629 nSpin = MetricField::ConvertValue( nSpin, aOrigSize.Width(), 0,
630 eUnit, m_xLeftMF->get_unit() );
631 m_xTopMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
632 m_xBottomMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
634 // display original size
635 const FieldUnit eMetric = GetModuleFieldUnit( GetItemSet() );
637 ScopedVclPtrInstance< MetricField > aFld(this, WB_HIDE);
638 SetFieldUnit( *aFld, eMetric );
639 aFld->SetDecimalDigits(m_xWidthMF->get_digits());
640 aFld->SetMax( LONG_MAX - 1 );
642 aFld->SetValue( aFld->Normalize( aOrigSize.Width() ), eUnit );
643 OUString sTemp = aFld->GetText();
644 aFld->SetValue( aFld->Normalize( aOrigSize.Height() ), eUnit );
645 // multiplication sign (U+00D7)
646 sTemp += OUStringLiteral1(0x00D7) + aFld->GetText();
648 if ( aOrigPixelSize.Width() && aOrigPixelSize.Height() ) {
649 sal_Int32 ax = sal_Int32(floor(static_cast<float>(aOrigPixelSize.Width()) /
650 (static_cast<float>(aOrigSize.Width())/TWIP_TO_INCH)+0.5));
651 sal_Int32 ay = sal_Int32(floor(static_cast<float>(aOrigPixelSize.Height()) /
652 (static_cast<float>(aOrigSize.Height())/TWIP_TO_INCH)+0.5));
653 sTemp += " ";
654 sTemp += CuiResId( RID_SVXSTR_PPI );
655 OUString sPPI = OUString::number(ax);
656 if (abs(ax - ay) > 1) {
657 sPPI += OUStringLiteral1(0x00D7) + OUString::number(ay);
659 sTemp = sTemp.replaceAll("%1", sPPI);
661 m_xOrigSizeFT->set_label(sTemp);
664 m_xCropFrame->set_sensitive(bFound);
665 m_xScaleFrame->set_sensitive(bFound);
666 m_xSizeFrame->set_sensitive(bFound);
667 m_xOrigSizeGrid->set_sensitive(bFound);
668 m_xZoomConstRB->set_sensitive(bFound);
671 Size SvxGrfCropPage::GetGrfOrigSize( const Graphic& rGrf ) const
673 const MapMode aMapTwip( MapUnit::MapTwip );
674 Size aSize( rGrf.GetPrefSize() );
675 if( MapUnit::MapPixel == rGrf.GetPrefMapMode().GetMapUnit() )
676 aSize = PixelToLogic( aSize, aMapTwip );
677 else
678 aSize = OutputDevice::LogicToLogic( aSize,
679 rGrf.GetPrefMapMode(), aMapTwip );
680 return aSize;
683 /*****************************************************************/
685 SvxCropExample::SvxCropExample()
686 : m_aTopLeft(0, 0)
687 , m_aBottomRight(0, 0)
691 void SvxCropExample::SetDrawingArea(weld::DrawingArea* pDrawingArea)
693 CustomWidgetController::SetDrawingArea(pDrawingArea);
694 OutputDevice& rDevice = pDrawingArea->get_ref_device();
695 Size aSize(rDevice.LogicToPixel(Size(78, 78), MapMode(MapUnit::MapAppFont)));
696 pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
698 m_aMapMode = rDevice.GetMapMode();
699 m_aFrameSize = OutputDevice::LogicToLogic(
700 Size(CM_1_TO_TWIP / 2, CM_1_TO_TWIP / 2),
701 MapMode(MapUnit::MapTwip), m_aMapMode);
704 void SvxCropExample::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&)
706 rRenderContext.Push(PushFlags::MAPMODE | PushFlags::RASTEROP);
707 rRenderContext.SetMapMode(m_aMapMode);
709 Size aWinSize(rRenderContext.PixelToLogic(GetOutputSizePixel()));
710 rRenderContext.SetLineColor();
711 rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetWindowColor());
712 rRenderContext.DrawRect(::tools::Rectangle(Point(), aWinSize));
714 rRenderContext.SetLineColor(COL_WHITE);
715 ::tools::Rectangle aRect(Point((aWinSize.Width() - m_aFrameSize.Width())/2,
716 (aWinSize.Height() - m_aFrameSize.Height())/2),
717 m_aFrameSize);
718 m_aGrf.Draw(&rRenderContext, aRect.TopLeft(), aRect.GetSize());
720 rRenderContext.SetFillColor(COL_TRANSPARENT);
721 rRenderContext.SetRasterOp(RasterOp::Invert);
722 aRect.AdjustLeft(m_aTopLeft.Y() );
723 aRect.AdjustTop(m_aTopLeft.X() );
724 aRect.AdjustRight(-m_aBottomRight.Y());
725 aRect.AdjustBottom(-m_aBottomRight.X());
726 rRenderContext.DrawRect(aRect);
728 rRenderContext.Pop();
731 void SvxCropExample::Resize()
733 SetFrameSize(m_aFrameSize);
736 void SvxCropExample::SetFrameSize( const Size& rSz )
738 m_aFrameSize = rSz;
739 if (!m_aFrameSize.Width())
740 m_aFrameSize.setWidth( 1 );
741 if (!m_aFrameSize.Height())
742 m_aFrameSize.setHeight( 1 );
743 Size aWinSize( GetOutputSizePixel() );
744 Fraction aXScale( aWinSize.Width() * 4, m_aFrameSize.Width() * 5 );
745 Fraction aYScale( aWinSize.Height() * 4, m_aFrameSize.Height() * 5 );
747 if( aYScale < aXScale )
748 aXScale = aYScale;
750 m_aMapMode.SetScaleX(aXScale);
751 m_aMapMode.SetScaleY(aXScale);
753 Invalidate();
756 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */