1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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
)
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
))
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()
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);
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
);
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
);
183 aPageSize
= OutputDevice::LogicToLogic(
184 Size( CM_1_TO_TWIP
, CM_1_TO_TWIP
),
185 MapMode( MapUnit::MapTwip
),
186 MapMode( rSet
->GetPool()->GetMetric( nW
) ) );
190 if( SfxItemState::SET
== rSet
->GetItemState( SID_ATTR_GRAF_GRAPHIC
, false, &pItem
) )
193 SfxStringItem
const * it
= static_cast<SfxStringItem
const *>(
194 rSet
->GetItem(SID_REFERER
));
196 referer
= it
->GetValue();
198 const Graphic
* pGrf
= static_cast<const SvxBrushItem
*>(pItem
)->GetGraphic(referer
);
201 aOrigSize
= GetGrfOrigSize( *pGrf
);
202 if (pGrf
->GetType() == GraphicType::Bitmap
&& aOrigSize
.Width() && aOrigSize
.Height())
204 aOrigPixelSize
= pGrf
->GetSizePixel();
207 if( aOrigSize
.Width() && aOrigSize
.Height() )
210 m_aExampleWN
.SetGraphic( *pGrf
);
211 m_aExampleWN
.SetFrameSize( aOrigSize
);
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()));
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
);
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() ) );
288 void SvxGrfCropPage::ActivatePage(const SfxItemSet
& rSet
)
291 SfxItemPool
* pPool
= GetItemSet().GetPool();
292 DBG_ASSERT( pPool
, "Where is the pool?" );
295 bSetOrigSize
= false;
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();
325 SfxStringItem
const * it
= static_cast<SfxStringItem
const *>(
326 rSet
.GetItem(SID_REFERER
));
328 referer
= it
->GetValue();
330 const Graphic
* pGrf
= rBrush
.GetGraphic(referer
);
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() );
343 GraphicHasChanged( false );
349 DeactivateRC
SvxGrfCropPage::DeactivatePage(SfxItemSet
*_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),
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) ,
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
) );
406 sal_uInt16 nZoom
= static_cast<sal_uInt16
>( aSize
.Width() * 100 / nWidth
);
407 m_xWidthZoomMF
->set_value(nZoom
, FieldUnit::NONE
);
411 long nHeight
= aOrigSize
.Height() -
412 ( lcl_GetValue(*m_xTopMF
, eUnit
) +
413 lcl_GetValue(*m_xBottomMF
, eUnit
));
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
);
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
);
461 m_aExampleWN
.SetLeft(nLeft
);
462 m_aExampleWN
.SetRight(nRight
);
466 // scale stays, recompute width
467 ZoomHdl(*m_xWidthZoomMF
);
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
);
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
);
496 // scale stays, recompute height
497 ZoomHdl(*m_xHeightZoomMF
);
500 m_aExampleWN
.Invalidate();
501 // size and border changed -> recompute scale
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
);
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;
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);
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
)
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));
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
);
678 aSize
= OutputDevice::LogicToLogic( aSize
,
679 rGrf
.GetPrefMapMode(), aMapTwip
);
683 /*****************************************************************/
685 SvxCropExample::SvxCropExample()
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),
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
)
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
)
750 m_aMapMode
.SetScaleX(aXScale
);
751 m_aMapMode
.SetScaleY(aXScale
);
756 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */