diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
commit | 940b4d1848e8c70ab7642901a68594e8016caffc (patch) | |
tree | eb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /cui/source/tabpages/grfpage.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip |
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'cui/source/tabpages/grfpage.cxx')
-rw-r--r-- | cui/source/tabpages/grfpage.cxx | 785 |
1 files changed, 785 insertions, 0 deletions
diff --git a/cui/source/tabpages/grfpage.cxx b/cui/source/tabpages/grfpage.cxx new file mode 100644 index 000000000..7f334e2f1 --- /dev/null +++ b/cui/source/tabpages/grfpage.cxx @@ -0,0 +1,785 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <memory> +#include <svl/eitem.hxx> +#include <svl/stritem.hxx> +#include <dialmgr.hxx> +#include <svx/dlgutil.hxx> +#include <editeng/sizeitem.hxx> +#include <editeng/brushitem.hxx> +#include <grfpage.hxx> +#include <svx/grfcrop.hxx> +#include <rtl/ustring.hxx> +#include <tools/debug.hxx> +#include <tools/fract.hxx> +#include <svx/svxids.hrc> +#include <strings.hrc> +#include <vcl/fieldvalues.hxx> +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> +#include <svtools/unitconv.hxx> +#include <svtools/optionsdrawinglayer.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> + +#define CM_1_TO_TWIP 567 +#define TWIP_TO_INCH 1440 + + +static int lcl_GetValue(const weld::MetricSpinButton& rMetric, FieldUnit eUnit) +{ + return rMetric.denormalize(rMetric.get_value(eUnit)); +} + +/*-------------------------------------------------------------------- + description: crop graphic + --------------------------------------------------------------------*/ + +SvxGrfCropPage::SvxGrfCropPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet) + : SfxTabPage(pPage, pController, "cui/ui/croppage.ui", "CropPage", &rSet) + , nOldWidth(0) + , nOldHeight(0) + , bSetOrigSize(false) + , m_xCropFrame(m_xBuilder->weld_widget("cropframe")) + , m_xZoomConstRB(m_xBuilder->weld_radio_button("keepscale")) + , m_xSizeConstRB(m_xBuilder->weld_radio_button("keepsize")) + , m_xLeftMF(m_xBuilder->weld_metric_spin_button("left", FieldUnit::CM)) + , m_xRightMF(m_xBuilder->weld_metric_spin_button("right", FieldUnit::CM)) + , m_xTopMF(m_xBuilder->weld_metric_spin_button("top", FieldUnit::CM)) + , m_xBottomMF(m_xBuilder->weld_metric_spin_button("bottom", FieldUnit::CM)) + , m_xScaleFrame(m_xBuilder->weld_widget("scaleframe")) + , m_xWidthZoomMF(m_xBuilder->weld_metric_spin_button("widthzoom", FieldUnit::PERCENT)) + , m_xHeightZoomMF(m_xBuilder->weld_metric_spin_button("heightzoom", FieldUnit::PERCENT)) + , m_xSizeFrame(m_xBuilder->weld_widget("sizeframe")) + , m_xWidthMF(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM)) + , m_xHeightMF(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM)) + , m_xOrigSizeGrid(m_xBuilder->weld_widget("origsizegrid")) + , m_xOrigSizeFT(m_xBuilder->weld_label("origsizeft")) + , m_xOrigSizePB(m_xBuilder->weld_button("origsize")) + , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, "preview", m_aExampleWN)) +{ + SetExchangeSupport(); + + // set the correct metric + const FieldUnit eMetric = GetModuleFieldUnit( rSet ); + + SetFieldUnit( *m_xWidthMF, eMetric ); + SetFieldUnit( *m_xHeightMF, eMetric ); + SetFieldUnit( *m_xLeftMF, eMetric ); + SetFieldUnit( *m_xRightMF, eMetric ); + SetFieldUnit( *m_xTopMF , eMetric ); + SetFieldUnit( *m_xBottomMF, eMetric ); + + Link<weld::MetricSpinButton&,void> aLk = LINK(this, SvxGrfCropPage, SizeHdl); + m_xWidthMF->connect_value_changed( aLk ); + m_xHeightMF->connect_value_changed( aLk ); + + aLk = LINK(this, SvxGrfCropPage, ZoomHdl); + m_xWidthZoomMF->connect_value_changed( aLk ); + m_xHeightZoomMF->connect_value_changed( aLk ); + + aLk = LINK(this, SvxGrfCropPage, CropModifyHdl); + m_xLeftMF->connect_value_changed( aLk ); + m_xRightMF->connect_value_changed( aLk ); + m_xTopMF->connect_value_changed( aLk ); + m_xBottomMF->connect_value_changed( aLk ); + + m_xOrigSizePB->connect_clicked(LINK(this, SvxGrfCropPage, OrigSizeHdl)); +} + +SvxGrfCropPage::~SvxGrfCropPage() +{ + m_xExampleWN.reset(); +} + +std::unique_ptr<SfxTabPage> SvxGrfCropPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet) +{ + return std::make_unique<SvxGrfCropPage>(pPage, pController, *rSet); +} + +void SvxGrfCropPage::Reset( const SfxItemSet *rSet ) +{ + const SfxPoolItem* pItem; + const SfxItemPool& rPool = *rSet->GetPool(); + + if(SfxItemState::SET == rSet->GetItemState( rPool.GetWhich( + SID_ATTR_GRAF_KEEP_ZOOM ), true, &pItem )) + { + if( static_cast<const SfxBoolItem*>(pItem)->GetValue() ) + m_xZoomConstRB->set_active(true); + else + m_xSizeConstRB->set_active(true); + m_xZoomConstRB->save_state(); + } + + sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_CROP ); + if( SfxItemState::SET == rSet->GetItemState( nW, true, &pItem)) + { + FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW )); + + const SvxGrfCrop* pCrop = static_cast<const SvxGrfCrop*>(pItem); + + m_aExampleWN.SetLeft(pCrop->GetLeft()); + m_aExampleWN.SetRight(pCrop->GetRight()); + m_aExampleWN.SetTop(pCrop->GetTop()); + m_aExampleWN.SetBottom(pCrop->GetBottom()); + + m_xLeftMF->set_value( m_xLeftMF->normalize( pCrop->GetLeft()), eUnit ); + m_xRightMF->set_value( m_xRightMF->normalize( pCrop->GetRight()), eUnit ); + m_xTopMF->set_value( m_xTopMF->normalize( pCrop->GetTop()), eUnit ); + m_xBottomMF->set_value( m_xBottomMF->normalize( pCrop->GetBottom()), eUnit ); + } + else + { + m_xLeftMF->set_value(0, FieldUnit::NONE); + m_xRightMF->set_value(0, FieldUnit::NONE); + m_xTopMF->set_value(0, FieldUnit::NONE); + m_xBottomMF->set_value(0, FieldUnit::NONE); + } + + m_xLeftMF->save_value(); + m_xRightMF->save_value(); + m_xTopMF->save_value(); + m_xBottomMF->save_value(); + + nW = rPool.GetWhich( SID_ATTR_PAGE_SIZE ); + if ( SfxItemState::SET == rSet->GetItemState( nW, false, &pItem ) ) + { + // orientation and size from the PageItem + FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW )); + + aPageSize = static_cast<const SvxSizeItem*>(pItem)->GetSize(); + + auto nMin = m_xWidthMF->normalize( 23 ); + auto nMax = m_xHeightMF->normalize(aPageSize.Height()); + m_xHeightMF->set_range(nMin, nMax, eUnit); + nMax = m_xWidthMF->normalize(aPageSize.Width()); + m_xWidthMF->set_range(nMin, nMax, eUnit); + } + else + { + aPageSize = OutputDevice::LogicToLogic( + Size( CM_1_TO_TWIP, CM_1_TO_TWIP ), + MapMode( MapUnit::MapTwip ), + MapMode( rSet->GetPool()->GetMetric( nW ) ) ); + } + + bool bFound = false; + if( SfxItemState::SET == rSet->GetItemState( SID_ATTR_GRAF_GRAPHIC, false, &pItem ) ) + { + OUString referer; + SfxStringItem const * it = static_cast<SfxStringItem const *>( + rSet->GetItem(SID_REFERER)); + if (it != nullptr) { + referer = it->GetValue(); + } + const Graphic* pGrf = static_cast<const SvxBrushItem*>(pItem)->GetGraphic(referer); + if( pGrf ) + { + aOrigSize = GetGrfOrigSize( *pGrf ); + if (pGrf->GetType() == GraphicType::Bitmap && aOrigSize.Width() && aOrigSize.Height()) + { + aOrigPixelSize = pGrf->GetSizePixel(); + } + + if( aOrigSize.Width() && aOrigSize.Height() ) + { + CalcMinMaxBorder(); + m_aExampleWN.SetGraphic( *pGrf ); + m_aExampleWN.SetFrameSize( aOrigSize ); + + bFound = true; + if( !static_cast<const SvxBrushItem*>(pItem)->GetGraphicLink().isEmpty() ) + aGraphicName = static_cast<const SvxBrushItem*>(pItem)->GetGraphicLink(); + } + } + } + + GraphicHasChanged( bFound ); + ActivatePage( *rSet ); +} + +bool SvxGrfCropPage::FillItemSet(SfxItemSet *rSet) +{ + const SfxItemPool& rPool = *rSet->GetPool(); + bool bModified = false; + if( m_xWidthMF->get_value_changed_from_saved() || + m_xHeightMF->get_value_changed_from_saved() ) + { + sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_FRMSIZE ); + FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW )); + + std::shared_ptr<SvxSizeItem> aSz(std::make_shared<SvxSizeItem>(nW)); + + // size could already have been set from another page + const SfxItemSet* pExSet = GetDialogExampleSet(); + const SfxPoolItem* pItem = nullptr; + if( pExSet && SfxItemState::SET ==pExSet->GetItemState( nW, false, &pItem ) ) + { + aSz.reset(static_cast< SvxSizeItem*>(pItem->Clone())); + } + else + { + aSz.reset(static_cast< SvxSizeItem*>(GetItemSet().Get(nW).Clone())); + } + + Size aTmpSz( aSz->GetSize() ); + if( m_xWidthMF->get_value_changed_from_saved() ) + aTmpSz.setWidth( lcl_GetValue( *m_xWidthMF, eUnit ) ); + if( m_xHeightMF->get_value_changed_from_saved() ) + aTmpSz.setHeight( lcl_GetValue( *m_xHeightMF, eUnit ) ); + aSz->SetSize( aTmpSz ); + m_xWidthMF->save_value(); + m_xHeightMF->save_value(); + + bModified |= nullptr != rSet->Put( *aSz ); + + if( bSetOrigSize ) + { + bModified |= nullptr != rSet->Put( SvxSizeItem( rPool.GetWhich( + SID_ATTR_GRAF_FRMSIZE_PERCENT ), Size( 0, 0 )) ); + } + } + if( m_xLeftMF->get_value_changed_from_saved() || m_xRightMF->get_value_changed_from_saved() || + m_xTopMF->get_value_changed_from_saved() || m_xBottomMF->get_value_changed_from_saved() ) + { + sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_CROP ); + FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW )); + std::unique_ptr<SvxGrfCrop> pNew(static_cast<SvxGrfCrop*>(rSet->Get( nW ).Clone())); + + pNew->SetLeft( lcl_GetValue( *m_xLeftMF, eUnit ) ); + pNew->SetRight( lcl_GetValue( *m_xRightMF, eUnit ) ); + pNew->SetTop( lcl_GetValue( *m_xTopMF, eUnit ) ); + pNew->SetBottom( lcl_GetValue( *m_xBottomMF, eUnit ) ); + bModified |= nullptr != rSet->Put( *pNew ); + } + + if( m_xZoomConstRB->get_state_changed_from_saved() ) + { + bModified |= nullptr != rSet->Put( SfxBoolItem( rPool.GetWhich( + SID_ATTR_GRAF_KEEP_ZOOM), m_xZoomConstRB->get_active() ) ); + } + + return bModified; +} + +void SvxGrfCropPage::ActivatePage(const SfxItemSet& rSet) +{ +#ifdef DBG_UTIL + SfxItemPool* pPool = GetItemSet().GetPool(); + DBG_ASSERT( pPool, "Where is the pool?" ); +#endif + + bSetOrigSize = false; + + // Size + Size aSize; + const SfxPoolItem* pItem; + if( SfxItemState::SET == rSet.GetItemState( SID_ATTR_GRAF_FRMSIZE, false, &pItem ) ) + aSize = static_cast<const SvxSizeItem*>(pItem)->GetSize(); + + nOldWidth = aSize.Width(); + nOldHeight = aSize.Height(); + + auto nWidth = m_xWidthMF->normalize(nOldWidth); + auto nHeight = m_xHeightMF->normalize(nOldHeight); + + if (nWidth != m_xWidthMF->get_value(FieldUnit::TWIP)) + m_xWidthMF->set_value(nWidth, FieldUnit::TWIP); + m_xWidthMF->save_value(); + + if (nHeight != m_xHeightMF->get_value(FieldUnit::TWIP)) + m_xHeightMF->set_value(nHeight, FieldUnit::TWIP); + m_xHeightMF->save_value(); + + if( SfxItemState::SET == rSet.GetItemState( SID_ATTR_GRAF_GRAPHIC, false, &pItem ) ) + { + const SvxBrushItem& rBrush = *static_cast<const SvxBrushItem*>(pItem); + if( !rBrush.GetGraphicLink().isEmpty() && + aGraphicName != rBrush.GetGraphicLink() ) + aGraphicName = rBrush.GetGraphicLink(); + + OUString referer; + SfxStringItem const * it = static_cast<SfxStringItem const *>( + rSet.GetItem(SID_REFERER)); + if (it != nullptr) { + referer = it->GetValue(); + } + const Graphic* pGrf = rBrush.GetGraphic(referer); + if( pGrf ) + { + m_aExampleWN.SetGraphic( *pGrf ); + aOrigSize = GetGrfOrigSize( *pGrf ); + if (pGrf->GetType() == GraphicType::Bitmap && aOrigSize.Width() > 1 && aOrigSize.Height() > 1) { + aOrigPixelSize = pGrf->GetSizePixel(); + } + m_aExampleWN.SetFrameSize(aOrigSize); + GraphicHasChanged( aOrigSize.Width() && aOrigSize.Height() ); + CalcMinMaxBorder(); + } + else + GraphicHasChanged( false ); + } + + CalcZoom(); +} + +DeactivateRC SvxGrfCropPage::DeactivatePage(SfxItemSet *_pSet) +{ + if ( _pSet ) + FillItemSet( _pSet ); + return DeactivateRC::LeavePage; +} + +/*-------------------------------------------------------------------- + description: scale changed, adjust size + --------------------------------------------------------------------*/ + +IMPL_LINK( SvxGrfCropPage, ZoomHdl, weld::MetricSpinButton&, rField, void ) +{ + SfxItemPool* pPool = GetItemSet().GetPool(); + DBG_ASSERT( pPool, "Where is the pool?" ); + FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich( + SID_ATTR_GRAF_CROP ) ) ); + + if (&rField == m_xWidthZoomMF.get()) + { + long nLRBorders = lcl_GetValue(*m_xLeftMF, eUnit) + +lcl_GetValue(*m_xRightMF, eUnit); + m_xWidthMF->set_value( m_xWidthMF->normalize( + ((aOrigSize.Width() - nLRBorders) * rField.get_value(FieldUnit::NONE))/100), + eUnit); + } + else + { + long nULBorders = lcl_GetValue(*m_xTopMF, eUnit) + +lcl_GetValue(*m_xBottomMF, eUnit); + m_xHeightMF->set_value( m_xHeightMF->normalize( + ((aOrigSize.Height() - nULBorders ) * rField.get_value(FieldUnit::NONE))/100) , + eUnit ); + } +} + +/*-------------------------------------------------------------------- + description: change size, adjust scale + --------------------------------------------------------------------*/ + +IMPL_LINK( SvxGrfCropPage, SizeHdl, weld::MetricSpinButton&, rField, void ) +{ + SfxItemPool* pPool = GetItemSet().GetPool(); + DBG_ASSERT( pPool, "Where is the pool?" ); + FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich( + SID_ATTR_GRAF_CROP ) ) ); + + Size aSize( lcl_GetValue(*m_xWidthMF, eUnit), + lcl_GetValue(*m_xHeightMF, eUnit) ); + + if(&rField == m_xWidthMF.get()) + { + long nWidth = aOrigSize.Width() - + ( lcl_GetValue(*m_xLeftMF, eUnit) + + lcl_GetValue(*m_xRightMF, eUnit) ); + if(!nWidth) + nWidth++; + sal_uInt16 nZoom = static_cast<sal_uInt16>( aSize.Width() * 100 / nWidth); + m_xWidthZoomMF->set_value(nZoom, FieldUnit::NONE); + } + else + { + long nHeight = aOrigSize.Height() - + ( lcl_GetValue(*m_xTopMF, eUnit) + + lcl_GetValue(*m_xBottomMF, eUnit)); + if(!nHeight) + nHeight++; + sal_uInt16 nZoom = static_cast<sal_uInt16>( aSize.Height() * 100 / nHeight); + m_xHeightZoomMF->set_value(nZoom, FieldUnit::NONE); + } +} + +/*-------------------------------------------------------------------- + description: evaluate border + --------------------------------------------------------------------*/ + +IMPL_LINK( SvxGrfCropPage, CropModifyHdl, weld::MetricSpinButton&, rField, void ) +{ + SfxItemPool* pPool = GetItemSet().GetPool(); + DBG_ASSERT( pPool, "Where is the pool?" ); + FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich( + SID_ATTR_GRAF_CROP ) ) ); + + bool bZoom = m_xZoomConstRB->get_active(); + if (&rField == m_xLeftMF.get() || &rField == m_xRightMF.get()) + { + long nLeft = lcl_GetValue( *m_xLeftMF, eUnit ); + long nRight = lcl_GetValue( *m_xRightMF, eUnit ); + long nWidthZoom = static_cast<long>(m_xWidthZoomMF->get_value(FieldUnit::NONE)); + if (bZoom && nWidthZoom != 0 && ( ( ( aOrigSize.Width() - (nLeft + nRight )) * nWidthZoom ) + / 100 >= aPageSize.Width() ) ) + { + if (&rField == m_xLeftMF.get()) + { + nLeft = aOrigSize.Width() - + ( aPageSize.Width() * 100 / nWidthZoom + nRight ); + m_xLeftMF->set_value( m_xLeftMF->normalize( nLeft ), eUnit ); + } + else + { + nRight = aOrigSize.Width() - + ( aPageSize.Width() * 100 / nWidthZoom + nLeft ); + m_xRightMF->set_value( m_xRightMF->normalize( nRight ), eUnit ); + } + } + if (AllSettings::GetLayoutRTL()) + { + m_aExampleWN.SetLeft(nRight); + m_aExampleWN.SetRight(nLeft); + } + else + { + m_aExampleWN.SetLeft(nLeft); + m_aExampleWN.SetRight(nRight); + } + if(bZoom) + { + // scale stays, recompute width + ZoomHdl(*m_xWidthZoomMF); + } + } + else + { + long nTop = lcl_GetValue( *m_xTopMF, eUnit ); + long nBottom = lcl_GetValue( *m_xBottomMF, eUnit ); + long nHeightZoom = static_cast<long>(m_xHeightZoomMF->get_value(FieldUnit::NONE)); + if(bZoom && ( ( ( aOrigSize.Height() - (nTop + nBottom )) * nHeightZoom) + / 100 >= aPageSize.Height())) + { + assert(nHeightZoom && "div-by-zero"); + if(&rField == m_xTopMF.get()) + { + nTop = aOrigSize.Height() - + ( aPageSize.Height() * 100 / nHeightZoom + nBottom); + m_xTopMF->set_value( m_xWidthMF->normalize( nTop ), eUnit ); + } + else + { + nBottom = aOrigSize.Height() - + ( aPageSize.Height() * 100 / nHeightZoom + nTop); + m_xBottomMF->set_value( m_xWidthMF->normalize( nBottom ), eUnit ); + } + } + m_aExampleWN.SetTop( nTop ); + m_aExampleWN.SetBottom( nBottom ); + if(bZoom) + { + // scale stays, recompute height + ZoomHdl(*m_xHeightZoomMF); + } + } + m_aExampleWN.Invalidate(); + // size and border changed -> recompute scale + if(!bZoom) + CalcZoom(); + CalcMinMaxBorder(); +} +/*-------------------------------------------------------------------- + description: set original size + --------------------------------------------------------------------*/ + +IMPL_LINK_NOARG(SvxGrfCropPage, OrigSizeHdl, weld::Button&, void) +{ + SfxItemPool* pPool = GetItemSet().GetPool(); + DBG_ASSERT( pPool, "Where is the pool?" ); + FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich( + SID_ATTR_GRAF_CROP ) ) ); + + long nWidth = aOrigSize.Width() - + lcl_GetValue( *m_xLeftMF, eUnit ) - + lcl_GetValue( *m_xRightMF, eUnit ); + m_xWidthMF->set_value( m_xWidthMF->normalize( nWidth ), eUnit ); + long nHeight = aOrigSize.Height() - + lcl_GetValue( *m_xTopMF, eUnit ) - + lcl_GetValue( *m_xBottomMF, eUnit ); + m_xHeightMF->set_value( m_xHeightMF->normalize( nHeight ), eUnit ); + m_xWidthZoomMF->set_value(100, FieldUnit::NONE); + m_xHeightZoomMF->set_value(100, FieldUnit::NONE); + bSetOrigSize = true; +} +/*-------------------------------------------------------------------- + description: compute scale + --------------------------------------------------------------------*/ + +void SvxGrfCropPage::CalcZoom() +{ + SfxItemPool* pPool = GetItemSet().GetPool(); + DBG_ASSERT( pPool, "Where is the pool?" ); + FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich( + SID_ATTR_GRAF_CROP ) ) ); + + long nWidth = lcl_GetValue( *m_xWidthMF, eUnit ); + long nHeight = lcl_GetValue( *m_xHeightMF, eUnit ); + long nLRBorders = lcl_GetValue( *m_xLeftMF, eUnit ) + + lcl_GetValue( *m_xRightMF, eUnit ); + long nULBorders = lcl_GetValue( *m_xTopMF, eUnit ) + + lcl_GetValue( *m_xBottomMF, eUnit ); + sal_uInt16 nZoom = 0; + long nDen; + if( (nDen = aOrigSize.Width() - nLRBorders) > 0) + nZoom = static_cast<sal_uInt16>((( nWidth * 1000 / nDen )+5)/10); + m_xWidthZoomMF->set_value(nZoom, FieldUnit::NONE); + if( (nDen = aOrigSize.Height() - nULBorders) > 0) + nZoom = static_cast<sal_uInt16>((( nHeight * 1000 / nDen )+5)/10); + else + nZoom = 0; + m_xHeightZoomMF->set_value(nZoom, FieldUnit::NONE); +} + +/*-------------------------------------------------------------------- + description: set minimum/maximum values for the margins + --------------------------------------------------------------------*/ + +void SvxGrfCropPage::CalcMinMaxBorder() +{ + SfxItemPool* pPool = GetItemSet().GetPool(); + DBG_ASSERT( pPool, "Where is the pool?" ); + FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich( + SID_ATTR_GRAF_CROP ) ) ); + long nR = lcl_GetValue(*m_xRightMF, eUnit ); + long nMinWidth = (aOrigSize.Width() * 10) /11; + long nMin = nMinWidth - (nR >= 0 ? nR : 0); + m_xLeftMF->set_max( m_xLeftMF->normalize(nMin), eUnit ); + + long nL = lcl_GetValue(*m_xLeftMF, eUnit ); + nMin = nMinWidth - (nL >= 0 ? nL : 0); + m_xRightMF->set_max( m_xRightMF->normalize(nMin), eUnit ); + + long nUp = lcl_GetValue( *m_xTopMF, eUnit ); + long nMinHeight = (aOrigSize.Height() * 10) /11; + nMin = nMinHeight - (nUp >= 0 ? nUp : 0); + m_xBottomMF->set_max( m_xBottomMF->normalize(nMin), eUnit ); + + long nLow = lcl_GetValue(*m_xBottomMF, eUnit ); + nMin = nMinHeight - (nLow >= 0 ? nLow : 0); + m_xTopMF->set_max( m_xTopMF->normalize(nMin), eUnit ); +} +/*-------------------------------------------------------------------- + description: set spinsize to 1/20 of the original size, + fill FixedText with the original size + --------------------------------------------------------------------*/ + +void SvxGrfCropPage::GraphicHasChanged( bool bFound ) +{ + if( bFound ) + { + SfxItemPool* pPool = GetItemSet().GetPool(); + DBG_ASSERT( pPool, "Where is the pool?" ); + FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich( + SID_ATTR_GRAF_CROP ) )); + + sal_Int64 nSpin = m_xLeftMF->normalize(aOrigSize.Width()) / 20; + nSpin = vcl::ConvertValue( nSpin, aOrigSize.Width(), 0, + eUnit, m_xLeftMF->get_unit()); + + // if the margin is too big, it is set to 1/3 on both pages + long nR = lcl_GetValue( *m_xRightMF, eUnit ); + long nL = lcl_GetValue( *m_xLeftMF, eUnit ); + if((nL + nR) < - aOrigSize.Width()) + { + long nVal = aOrigSize.Width() / -3; + m_xRightMF->set_value( m_xRightMF->normalize( nVal ), eUnit ); + m_xLeftMF->set_value( m_xLeftMF->normalize( nVal ), eUnit ); + m_aExampleWN.SetLeft(nVal); + m_aExampleWN.SetRight(nVal); + } + long nUp = lcl_GetValue(*m_xTopMF, eUnit ); + long nLow = lcl_GetValue(*m_xBottomMF, eUnit ); + if((nUp + nLow) < - aOrigSize.Height()) + { + long nVal = aOrigSize.Height() / -3; + m_xTopMF->set_value( m_xTopMF->normalize( nVal ), eUnit ); + m_xBottomMF->set_value( m_xBottomMF->normalize( nVal ), eUnit ); + m_aExampleWN.SetTop(nVal); + m_aExampleWN.SetBottom(nVal); + } + + m_xLeftMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE); + m_xRightMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE); + nSpin = m_xTopMF->normalize(aOrigSize.Height()) / 20; + nSpin = vcl::ConvertValue( nSpin, aOrigSize.Width(), 0, + eUnit, m_xLeftMF->get_unit() ); + m_xTopMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE); + m_xBottomMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE); + + // display original size + const FieldUnit eMetric = GetModuleFieldUnit( GetItemSet() ); + + OUString sTemp; + { + std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/spinbox.ui")); + std::unique_ptr<weld::MetricSpinButton> xFld(xBuilder->weld_metric_spin_button("spin", FieldUnit::CM)); + SetFieldUnit( *xFld, eMetric ); + xFld->set_digits(m_xWidthMF->get_digits()); + xFld->set_max(INT_MAX - 1, FieldUnit::NONE); + + xFld->set_value(xFld->normalize(aOrigSize.Width()), eUnit); + sTemp = xFld->get_text(); + xFld->set_value(xFld->normalize(aOrigSize.Height()), eUnit); + // multiplication sign (U+00D7) + sTemp += u"\u00D7" + xFld->get_text(); + } + + if ( aOrigPixelSize.Width() && aOrigPixelSize.Height() ) { + sal_Int32 ax = sal_Int32(floor(static_cast<float>(aOrigPixelSize.Width()) / + (static_cast<float>(aOrigSize.Width())/TWIP_TO_INCH)+0.5)); + sal_Int32 ay = sal_Int32(floor(static_cast<float>(aOrigPixelSize.Height()) / + (static_cast<float>(aOrigSize.Height())/TWIP_TO_INCH)+0.5)); + sTemp += " " + CuiResId( RID_SVXSTR_PPI ); + OUString sPPI = OUString::number(ax); + if (abs(ax - ay) > 1) { + sPPI += u"\u00D7" + OUString::number(ay); + } + sTemp = sTemp.replaceAll("%1", sPPI); + } + m_xOrigSizeFT->set_label(sTemp); + } + + m_xCropFrame->set_sensitive(bFound); + m_xScaleFrame->set_sensitive(bFound); + m_xSizeFrame->set_sensitive(bFound); + m_xOrigSizeGrid->set_sensitive(bFound); + m_xZoomConstRB->set_sensitive(bFound); +} + +Size SvxGrfCropPage::GetGrfOrigSize(const Graphic& rGrf) +{ + const MapMode aMapTwip( MapUnit::MapTwip ); + Size aSize( rGrf.GetPrefSize() ); + if( MapUnit::MapPixel == rGrf.GetPrefMapMode().GetMapUnit() ) + aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMapTwip); + else + aSize = OutputDevice::LogicToLogic( aSize, + rGrf.GetPrefMapMode(), aMapTwip ); + return aSize; +} + +/*****************************************************************/ + +SvxCropExample::SvxCropExample() + : m_aTopLeft(0, 0) + , m_aBottomRight(0, 0) +{ +} + +void SvxCropExample::SetDrawingArea(weld::DrawingArea* pDrawingArea) +{ + CustomWidgetController::SetDrawingArea(pDrawingArea); + OutputDevice& rDevice = pDrawingArea->get_ref_device(); + Size aSize(rDevice.LogicToPixel(Size(78, 78), MapMode(MapUnit::MapAppFont))); + pDrawingArea->set_size_request(aSize.Width(), aSize.Height()); + + m_aMapMode = rDevice.GetMapMode(); + m_aFrameSize = OutputDevice::LogicToLogic( + Size(CM_1_TO_TWIP / 2, CM_1_TO_TWIP / 2), + MapMode(MapUnit::MapTwip), m_aMapMode); +} + +void SvxCropExample::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&) +{ + rRenderContext.Push(PushFlags::MAPMODE); + rRenderContext.SetMapMode(m_aMapMode); + + // Win BG + const Size aWinSize(rRenderContext.PixelToLogic(GetOutputSizePixel())); + rRenderContext.SetLineColor(); + rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetWindowColor()); + rRenderContext.DrawRect(::tools::Rectangle(Point(), aWinSize)); + + // use AA, the Graphic may be a metafile/svg and would then look ugly + rRenderContext.SetAntialiasing(AntialiasingFlags::EnableB2dDraw); + + // draw Graphic + ::tools::Rectangle aRect( + Point((aWinSize.Width() - m_aFrameSize.Width())/2, (aWinSize.Height() - m_aFrameSize.Height())/2), + m_aFrameSize); + m_aGrf.Draw(&rRenderContext, aRect.TopLeft(), aRect.GetSize()); + + // Remove one more case that uses XOR paint (RasterOp::Invert). + // Get colors and logic DashLength from settings, use equal to + // PolygonMarkerPrimitive2D, may be changed to that primitive later. + // Use this to guarantee good visibility - that was the purpose of + // the former used XOR paint. + const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; + const Color aColA(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor()); + const Color aColB(aSvtOptionsDrawinglayer.GetStripeColorB().getBColor()); + const double fStripeLength(aSvtOptionsDrawinglayer.GetStripeLength()); + const basegfx::B2DVector aDashVector(rRenderContext.GetInverseViewTransformation() * basegfx::B2DVector(fStripeLength, 0.0)); + const double fLogicDashLength(aDashVector.getX()); + + // apply current crop settings + aRect.AdjustLeft(m_aTopLeft.Y()); + aRect.AdjustTop(m_aTopLeft.X()); + aRect.AdjustRight(-m_aBottomRight.Y()); + aRect.AdjustBottom(-m_aBottomRight.X()); + + // apply dash with direct paint callbacks + basegfx::utils::applyLineDashing( + basegfx::utils::createPolygonFromRect( + basegfx::B2DRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom())), + std::vector< double >(2, fLogicDashLength), + [&aColA,&rRenderContext](const basegfx::B2DPolygon& rSnippet) + { + rRenderContext.SetLineColor(aColA); + rRenderContext.DrawPolyLine(rSnippet); + }, + [&aColB,&rRenderContext](const basegfx::B2DPolygon& rSnippet) + { + rRenderContext.SetLineColor(aColB); + rRenderContext.DrawPolyLine(rSnippet); + }, + 2.0 * fLogicDashLength); + + rRenderContext.Pop(); +} + +void SvxCropExample::Resize() +{ + SetFrameSize(m_aFrameSize); +} + +void SvxCropExample::SetFrameSize( const Size& rSz ) +{ + m_aFrameSize = rSz; + if (!m_aFrameSize.Width()) + m_aFrameSize.setWidth( 1 ); + if (!m_aFrameSize.Height()) + m_aFrameSize.setHeight( 1 ); + Size aWinSize( GetOutputSizePixel() ); + Fraction aXScale( aWinSize.Width() * 4, m_aFrameSize.Width() * 5 ); + Fraction aYScale( aWinSize.Height() * 4, m_aFrameSize.Height() * 5 ); + + if( aYScale < aXScale ) + aXScale = aYScale; + + m_aMapMode.SetScaleX(aXScale); + m_aMapMode.SetScaleY(aXScale); + + Invalidate(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |