Both are derived from SfxSetItem which means they contain a SfxItemSet themselves. That leads to problems since at their construction time a SfxItemPool has to be known and it *should* not be different to the one of the ItemSet that Item gets added later - that leads to the 2nd class of problems. In the long therm we should get rid of all SfxSetItems. This change simplifies already some stuff, including that the standard Items for DrawObjects reduces by two (and more due to containing a whole ItemSet) and e.g. the problem that these Items had to be converted to hard attributes in the done fixes for copy/pasting Slides. Signed-off-by: Armin Le Grand (collabora) <Armin.LeGrand@collabora.com> Change-Id: I8b1c6cabdaa43ed6062811b5508ab3dece47a755 Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/6795 Reviewed-by: Armin Le Grand <armin.legrand@collabora.com> Tested-by: Jenkins CPCI <releng@collaboraoffice.com> (cherry picked from commit e67458a9b769fe7a3a7ee0739ed6d5c46dbc0692) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/211734 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
855 lines
31 KiB
C++
855 lines
31 KiB
C++
/* -*- 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 <stdlib.h>
|
|
#include <o3tl/untaint.hxx>
|
|
#include <tools/urlobj.hxx>
|
|
#include <svx/drawitem.hxx>
|
|
#include <svx/xbtmpit.hxx>
|
|
#include <svx/svxids.hrc>
|
|
#include <strings.hrc>
|
|
#include <svtools/dlgname.hxx>
|
|
#include <svx/xfillit0.hxx>
|
|
#include <svx/xtable.hxx>
|
|
#include <svx/xflbmsxy.hxx>
|
|
#include <svx/xflbmtit.hxx>
|
|
#include <svx/xflbstit.hxx>
|
|
#include <svx/xflbmsli.hxx>
|
|
#include <svx/xflbmpit.hxx>
|
|
#include <svx/xflboxy.hxx>
|
|
#include <svx/xflbtoxy.hxx>
|
|
#include <cuitabarea.hxx>
|
|
#include <dialmgr.hxx>
|
|
#include <svx/dlgutil.hxx>
|
|
#include <svl/intitem.hxx>
|
|
#include <sfx2/bindings.hxx>
|
|
#include <sfx2/objsh.hxx>
|
|
#include <sfx2/opengrf.hxx>
|
|
#include <sfx2/viewfrm.hxx>
|
|
#include <vcl/image.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
#include <vcl/weld/MessageDialog.hxx>
|
|
#include <sfx2/viewsh.hxx>
|
|
#include <sfx2/dialoghelper.hxx>
|
|
#include <sal/log.hxx>
|
|
#include <comphelper/lok.hxx>
|
|
#include <svtools/unitconv.hxx>
|
|
#include <tools/debug.hxx>
|
|
#include <vcl/weld/Builder.hxx>
|
|
#include <vcl/weld/ScrolledWindow.hxx>
|
|
#include <vcl/weld/WaitObject.hxx>
|
|
|
|
using namespace com::sun::star;
|
|
|
|
namespace {
|
|
|
|
enum BitmapStyle
|
|
{
|
|
CUSTOM,
|
|
TILED,
|
|
STRETCHED
|
|
};
|
|
|
|
enum TileOffset
|
|
{
|
|
ROW,
|
|
COLUMN
|
|
};
|
|
|
|
}
|
|
|
|
SvxBitmapTabPage::SvxBitmapTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
|
|
: SfxTabPage(pPage, pController, u"cui/ui/imagetabpage.ui"_ustr, u"ImageTabPage"_ustr, &rInAttrs)
|
|
, m_rOutAttrs(rInAttrs)
|
|
, m_nBitmapListState(ChangeType::NONE)
|
|
, m_fObjectWidth(0.0)
|
|
, m_fObjectHeight(0.0)
|
|
, m_bLogicalSize(false)
|
|
, m_aFillAttributeSet(rInAttrs.getPool(), WhichRangesContainer(XATTR_FILL_FIRST, XATTR_FILL_LAST))
|
|
, mpView(nullptr)
|
|
, m_xBitmapsPresets(m_xBuilder->weld_icon_view(u"images"_ustr))
|
|
, m_xBitmapLB(new SvxPresetListBox(*m_xBitmapsPresets))
|
|
, m_xBitmapStyleLB(m_xBuilder->weld_combo_box(u"imagestyle"_ustr))
|
|
, m_xSizeBox(m_xBuilder->weld_container(u"sizebox"_ustr))
|
|
, m_xTsbScale(m_xBuilder->weld_check_button(u"scaletsb"_ustr))
|
|
, m_xBitmapWidth(m_xBuilder->weld_metric_spin_button(u"width"_ustr, FieldUnit::PERCENT))
|
|
, m_xBitmapHeight(m_xBuilder->weld_metric_spin_button(u"height"_ustr, FieldUnit::PERCENT))
|
|
, m_xPositionBox(m_xBuilder->weld_container(u"posbox"_ustr))
|
|
, m_xPositionLB(m_xBuilder->weld_combo_box(u"positionlb"_ustr))
|
|
, m_xPositionOffBox(m_xBuilder->weld_container(u"posoffbox"_ustr))
|
|
, m_xPositionOffX(m_xBuilder->weld_metric_spin_button(u"posoffx"_ustr, FieldUnit::PERCENT))
|
|
, m_xPositionOffY(m_xBuilder->weld_metric_spin_button(u"posoffy"_ustr, FieldUnit::PERCENT))
|
|
, m_xTileOffBox(m_xBuilder->weld_container(u"tileoffbox"_ustr))
|
|
, m_xTileOffLB(m_xBuilder->weld_combo_box(u"tileofflb"_ustr))
|
|
, m_xTileOffset(m_xBuilder->weld_metric_spin_button(u"tileoffmtr"_ustr, FieldUnit::PERCENT))
|
|
, m_xBtnImport(m_xBuilder->weld_button(u"BTN_IMPORT"_ustr))
|
|
, m_xCtlBitmapPreview(new weld::CustomWeld(*m_xBuilder, u"CTL_IMAGE_PREVIEW"_ustr, m_aCtlBitmapPreview))
|
|
{
|
|
// setting the output device
|
|
m_aFillAttributeSet.Put( XFillStyleItem(drawing::FillStyle_BITMAP) );
|
|
m_aFillAttributeSet.Put( XFillBitmapItem(OUString(), Graphic()) );
|
|
m_aCtlBitmapPreview.SetAttributes(m_aFillAttributeSet);
|
|
|
|
m_xBitmapsPresets->connect_item_activated(LINK(this, SvxBitmapTabPage, ModifyBitmapHdl));
|
|
m_xBitmapLB->SetRenameHdl( LINK(this, SvxBitmapTabPage, ClickRenameHdl) );
|
|
m_xBitmapLB->SetDeleteHdl( LINK(this, SvxBitmapTabPage, ClickDeleteHdl) );
|
|
m_xBitmapStyleLB->connect_changed( LINK(this, SvxBitmapTabPage, ModifyBitmapStyleHdl) );
|
|
Link<weld::MetricSpinButton&, void> aLink1( LINK(this, SvxBitmapTabPage, ModifyBitmapSizeHdl) );
|
|
m_xBitmapWidth->connect_value_changed( aLink1 );
|
|
m_xBitmapHeight->connect_value_changed( aLink1 );
|
|
m_xTsbScale->connect_toggled(LINK(this, SvxBitmapTabPage, ClickScaleHdl));
|
|
m_xPositionLB->connect_changed( LINK( this, SvxBitmapTabPage, ModifyBitmapPositionHdl ) );
|
|
Link<weld::MetricSpinButton&, void> aLink( LINK( this, SvxBitmapTabPage, ModifyPositionOffsetHdl ) );
|
|
m_xPositionOffX->connect_value_changed(aLink);
|
|
m_xPositionOffY->connect_value_changed(aLink);
|
|
m_xTileOffset->connect_value_changed( LINK( this, SvxBitmapTabPage, ModifyTileOffsetHdl ) );
|
|
m_xBtnImport->connect_clicked( LINK(this, SvxBitmapTabPage, ClickImportHdl) );
|
|
if (comphelper::LibreOfficeKit::isActive())
|
|
m_xBtnImport->hide();
|
|
|
|
// Calculate size of display boxes
|
|
Size aSize = getDrawPreviewOptimalSize(m_aCtlBitmapPreview.GetDrawingArea()->get_ref_device());
|
|
m_xCtlBitmapPreview->set_size_request(aSize.Width(), aSize.Height());
|
|
|
|
SfxItemPool* pPool = m_aFillAttributeSet.GetPool();
|
|
mePoolUnit = pPool->GetMetric( XATTR_FILLBMP_SIZEX );
|
|
meFieldUnit = GetModuleFieldUnit( rInAttrs );
|
|
SetFieldUnit( *m_xBitmapWidth, meFieldUnit, true );
|
|
SetFieldUnit( *m_xBitmapHeight, meFieldUnit, true );
|
|
|
|
SfxViewShell* pViewShell = SfxViewShell::Current();
|
|
if( pViewShell )
|
|
mpView = pViewShell->GetDrawView();
|
|
DBG_ASSERT( mpView, "no valid view (!)" );
|
|
}
|
|
|
|
SvxBitmapTabPage::~SvxBitmapTabPage()
|
|
{
|
|
m_xBitmapLB.reset();
|
|
m_xCtlBitmapPreview.reset();
|
|
|
|
if (m_nBitmapListState & ChangeType::MODIFIED)
|
|
{
|
|
m_pBitmapList->SetPath(AreaTabHelper::GetPalettePath());
|
|
m_pBitmapList->Save();
|
|
|
|
// ToolBoxControls are informed:
|
|
SfxObjectShell* pShell = SfxObjectShell::Current();
|
|
if (pShell)
|
|
pShell->PutItem(SvxBitmapListItem(m_pBitmapList, SID_BITMAP_LIST));
|
|
}
|
|
}
|
|
|
|
void SvxBitmapTabPage::Construct()
|
|
{
|
|
m_xBitmapLB->FillPresetListBox( *m_pBitmapList );
|
|
}
|
|
|
|
void SvxBitmapTabPage::ActivatePage( const SfxItemSet& rSet )
|
|
{
|
|
const XFillBitmapItem& aItem( rSet.Get(XATTR_FILLBITMAP) );
|
|
|
|
sal_Int32 nPos( 0 );
|
|
if ( !aItem.isPattern() )
|
|
{
|
|
const GraphicObject& aGraphicObj = aItem.GetGraphicObject();
|
|
if (aGraphicObj.GetType() != GraphicType::Bitmap)
|
|
return;
|
|
|
|
nPos = SearchBitmapList(aGraphicObj);
|
|
if (nPos == -1)
|
|
nPos = AddBitmap(aGraphicObj, aItem.GetName(), /*OnlyForThisDocument=*/true);
|
|
}
|
|
else
|
|
{
|
|
m_xBitmapWidth->set_value( 100, FieldUnit::NONE );
|
|
m_xBitmapHeight->set_value( 100, FieldUnit::NONE );
|
|
const_cast<SfxItemSet&>(rSet).Put( XFillBmpSizeXItem( GetCoreValue( *m_xBitmapWidth, mePoolUnit ) ) );
|
|
const_cast<SfxItemSet&>(rSet).Put( XFillBmpSizeYItem( GetCoreValue( *m_xBitmapHeight, mePoolUnit ) ) );
|
|
}
|
|
|
|
m_xBitmapsPresets->select(nPos);
|
|
}
|
|
|
|
DeactivateRC SvxBitmapTabPage::DeactivatePage( SfxItemSet* _pSet )
|
|
{
|
|
if( _pSet )
|
|
FillItemSet( _pSet );
|
|
|
|
return DeactivateRC::LeavePage;
|
|
}
|
|
|
|
|
|
bool SvxBitmapTabPage::FillItemSet( SfxItemSet* rAttrs )
|
|
{
|
|
rAttrs->Put(XFillStyleItem(drawing::FillStyle_BITMAP));
|
|
const int nPos = m_xBitmapsPresets->get_selected_index();
|
|
if (nPos >= 0)
|
|
{
|
|
const XBitmapEntry* pXBitmapEntry = m_pBitmapList->GetBitmap(nPos);
|
|
const OUString aString(m_xBitmapsPresets->get_item_tooltip_text(nPos));
|
|
rAttrs->Put(XFillBitmapItem(aString, pXBitmapEntry->GetGraphicObject()));
|
|
}
|
|
|
|
BitmapStyle eStylePos = static_cast<BitmapStyle>(m_xBitmapStyleLB->get_active());
|
|
bool bIsStretched( eStylePos == STRETCHED );
|
|
bool bIsTiled( eStylePos == TILED );
|
|
|
|
rAttrs->Put( XFillBmpTileItem(bIsTiled) );
|
|
rAttrs->Put( XFillBmpStretchItem(bIsStretched) );
|
|
|
|
if(!bIsStretched)
|
|
{
|
|
Size aSetBitmapSize;
|
|
switch(eStylePos)
|
|
{
|
|
case CUSTOM:
|
|
case TILED:
|
|
{
|
|
sal_Int64 nWidthPercent = m_xBitmapWidth->get_value(FieldUnit::NONE);
|
|
sal_Int64 nHeightPercent = m_xBitmapHeight->get_value(FieldUnit::NONE);
|
|
if (m_xTsbScale->get_sensitive() && m_xTsbScale->get_state() == TRISTATE_TRUE)
|
|
{
|
|
aSetBitmapSize.setWidth(o3tl::saturating_toggle_sign(nWidthPercent));
|
|
aSetBitmapSize.setHeight(o3tl::saturating_toggle_sign(nHeightPercent));
|
|
}
|
|
else if (!m_bLogicalSize)
|
|
{
|
|
aSetBitmapSize.setWidth( GetCoreValue(*m_xBitmapWidth, mePoolUnit) );
|
|
aSetBitmapSize.setHeight( GetCoreValue(*m_xBitmapHeight, mePoolUnit) );
|
|
}
|
|
else
|
|
{
|
|
rAttrs->Put( XFillBmpSizeLogItem(true) );
|
|
aSetBitmapSize.setWidth( 0 );
|
|
aSetBitmapSize.setHeight( 0 );
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
rAttrs->Put( XFillBmpSizeXItem( aSetBitmapSize.Width() ) );
|
|
rAttrs->Put( XFillBmpSizeYItem( aSetBitmapSize.Height() ) );
|
|
}
|
|
|
|
if (m_xPositionLB->get_sensitive())
|
|
rAttrs->Put( XFillBmpPosItem( static_cast<RectPoint>( m_xPositionLB->get_active() ) ) );
|
|
if (m_xPositionOffX->get_sensitive())
|
|
rAttrs->Put( XFillBmpPosOffsetXItem(m_xPositionOffX->get_value(FieldUnit::PERCENT)));
|
|
if (m_xPositionOffY->get_sensitive())
|
|
rAttrs->Put( XFillBmpPosOffsetYItem(m_xPositionOffY->get_value(FieldUnit::PERCENT)));
|
|
if (m_xTileOffBox->get_sensitive())
|
|
{
|
|
TileOffset eValue = static_cast<TileOffset>(m_xTileOffLB->get_active());
|
|
sal_uInt16 nOffsetValue = static_cast<sal_uInt16>(m_xTileOffset->get_value(FieldUnit::PERCENT));
|
|
sal_uInt16 nRowOff = (eValue == ROW) ? nOffsetValue : 0;
|
|
sal_uInt16 nColOff = (eValue == COLUMN) ? nOffsetValue : 0;
|
|
rAttrs->Put( XFillBmpTileOffsetXItem(nRowOff) );
|
|
rAttrs->Put( XFillBmpTileOffsetYItem(nColOff) );
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
void SvxBitmapTabPage::Reset( const SfxItemSet* rAttrs )
|
|
{
|
|
double transfWidth = 0.0;
|
|
double transfHeight = 0.0;
|
|
double fUIScale = 1.0;
|
|
if (mpView)
|
|
{
|
|
double fModelUIScale = mpView->GetModel().GetUIScale();
|
|
if (fModelUIScale == 0)
|
|
SAL_WARN("cui.tabpages", "zero UIScale");
|
|
else
|
|
fUIScale = fModelUIScale;
|
|
|
|
if (mpView->GetMarkedObjectList().GetMarkCount() != 0)
|
|
{
|
|
SfxItemSet rGeoAttr(mpView->GetGeoAttrFromMarked());
|
|
transfWidth = static_cast<double>(GetItem( rGeoAttr, SID_ATTR_TRANSFORM_WIDTH )->GetValue());
|
|
transfHeight= static_cast<double>(GetItem( rGeoAttr, SID_ATTR_TRANSFORM_HEIGHT )->GetValue());
|
|
}
|
|
}
|
|
m_fObjectWidth = std::max( transfWidth, 1.0 );
|
|
m_fObjectHeight = std::max( transfHeight, 1.0 );
|
|
double fTmpWidth((OutputDevice::LogicToLogic(static_cast<sal_Int32>(m_fObjectWidth), mePoolUnit, MapUnit::Map100thMM )) / fUIScale);
|
|
m_fObjectWidth = fTmpWidth;
|
|
|
|
double fTmpHeight((OutputDevice::LogicToLogic(static_cast<sal_Int32>(m_fObjectHeight), mePoolUnit, MapUnit::Map100thMM )) / fUIScale);
|
|
m_fObjectHeight = fTmpHeight;
|
|
|
|
const XFillBitmapItem& aItem( rAttrs->Get(XATTR_FILLBITMAP) );
|
|
|
|
if(!aItem.isPattern())
|
|
{
|
|
m_aFillAttributeSet.Put( aItem );
|
|
m_aCtlBitmapPreview.SetAttributes(m_aFillAttributeSet);
|
|
m_aCtlBitmapPreview.Invalidate();
|
|
}
|
|
else
|
|
m_xCtlBitmapPreview->set_sensitive(false);
|
|
|
|
std::unique_ptr<GraphicObject> pGraphicObject;
|
|
pGraphicObject.reset( new GraphicObject(aItem.GetGraphicObject()) );
|
|
|
|
Bitmap aBmp(pGraphicObject->GetGraphic().GetBitmap());
|
|
Size aTempBitmapSize = aBmp.GetSizePixel();
|
|
m_aBitmapSize = Application::GetDefaultDevice()->PixelToLogic(aTempBitmapSize,
|
|
MapMode(MapUnit::Map100thMM));
|
|
CalculateBitmapPresetSize();
|
|
|
|
bool bTiled = false; bool bStretched = false;
|
|
if(rAttrs->GetItemState( XATTR_FILLBMP_TILE ) != SfxItemState::INVALID)
|
|
bTiled = rAttrs->Get( XATTR_FILLBMP_TILE ).GetValue();
|
|
if(rAttrs->GetItemState( XATTR_FILLBMP_STRETCH ) != SfxItemState::INVALID)
|
|
bStretched = rAttrs->Get( XATTR_FILLBMP_STRETCH ).GetValue();
|
|
|
|
if (bTiled)
|
|
m_xBitmapStyleLB->set_active(static_cast<sal_Int32>(TILED));
|
|
else if (bStretched)
|
|
m_xBitmapStyleLB->set_active(static_cast<sal_Int32>(STRETCHED));
|
|
else
|
|
m_xBitmapStyleLB->set_active(static_cast<sal_Int32>(CUSTOM));
|
|
|
|
tools::Long nWidth = 0;
|
|
tools::Long nHeight = 0;
|
|
|
|
if(rAttrs->GetItemState(XATTR_FILLBMP_SIZELOG) != SfxItemState::INVALID)
|
|
{
|
|
if (rAttrs->Get( XATTR_FILLBMP_SIZELOG ).GetValue())
|
|
m_xTsbScale->set_state(TRISTATE_FALSE);
|
|
else
|
|
m_xTsbScale->set_state(TRISTATE_TRUE);
|
|
}
|
|
else
|
|
m_xTsbScale->set_state(TRISTATE_INDET);
|
|
|
|
TriState eRelative = TRISTATE_FALSE;
|
|
if(rAttrs->GetItemState(XATTR_FILLBMP_SIZEX) != SfxItemState::INVALID)
|
|
{
|
|
nWidth = static_cast<const XFillBmpSizeXItem&>( rAttrs->Get( XATTR_FILLBMP_SIZEX ) ).GetValue();
|
|
if(nWidth == 0)
|
|
nWidth = m_aBitmapSize.Width();
|
|
else if(nWidth < 0)
|
|
{
|
|
m_bLogicalSize = true;
|
|
eRelative = TRISTATE_TRUE;
|
|
nWidth = std::abs(nWidth);
|
|
}
|
|
}
|
|
|
|
if(rAttrs->GetItemState( XATTR_FILLBMP_SIZEY ) != SfxItemState::INVALID)
|
|
{
|
|
nHeight = rAttrs->Get( XATTR_FILLBMP_SIZEY ).GetValue();
|
|
if(nHeight == 0)
|
|
nHeight = m_aBitmapSize.Height();
|
|
else if(nHeight < 0)
|
|
{
|
|
m_bLogicalSize = true;
|
|
eRelative = TRISTATE_TRUE;
|
|
nHeight = std::abs(nHeight);
|
|
}
|
|
}
|
|
m_xTsbScale->set_state(eRelative);
|
|
ClickScaleHdl(*m_xTsbScale);
|
|
|
|
if (!m_aBitmapSize.IsEmpty())
|
|
{
|
|
if (eRelative == TRISTATE_TRUE)
|
|
{
|
|
m_xBitmapWidth->set_value(nWidth, FieldUnit::NONE);
|
|
m_xBitmapHeight->set_value(nHeight, FieldUnit::NONE);
|
|
}
|
|
else
|
|
{
|
|
SetMetricValue(*m_xBitmapWidth, nWidth, mePoolUnit);
|
|
SetMetricValue(*m_xBitmapHeight, nHeight, mePoolUnit);
|
|
}
|
|
}
|
|
|
|
if( rAttrs->GetItemState( XATTR_FILLBMP_POS ) != SfxItemState::INVALID )
|
|
{
|
|
RectPoint eValue = rAttrs->Get( XATTR_FILLBMP_POS ).GetValue();
|
|
m_xPositionLB->set_active( static_cast< sal_Int32 >(eValue) );
|
|
}
|
|
|
|
if( rAttrs->GetItemState( XATTR_FILLBMP_POSOFFSETX ) != SfxItemState::INVALID )
|
|
{
|
|
sal_Int32 nValue = rAttrs->Get( XATTR_FILLBMP_POSOFFSETX ).GetValue();
|
|
m_xPositionOffX->set_value(nValue, FieldUnit::PERCENT);
|
|
}
|
|
else
|
|
m_xPositionOffX->set_text(u""_ustr);
|
|
|
|
if( rAttrs->GetItemState( XATTR_FILLBMP_POSOFFSETY ) != SfxItemState::INVALID )
|
|
{
|
|
sal_Int32 nValue = rAttrs->Get( XATTR_FILLBMP_POSOFFSETY ).GetValue();
|
|
m_xPositionOffY->set_value(nValue, FieldUnit::PERCENT);
|
|
}
|
|
else
|
|
m_xPositionOffY->set_text(u""_ustr);
|
|
|
|
if( rAttrs->GetItemState( XATTR_FILLBMP_TILEOFFSETX ) != SfxItemState::INVALID)
|
|
{
|
|
sal_Int32 nValue = rAttrs->Get( XATTR_FILLBMP_TILEOFFSETX ).GetValue();
|
|
if(nValue > 0)
|
|
{
|
|
m_xTileOffLB->set_active(static_cast<sal_Int32>(ROW));
|
|
m_xTileOffset->set_value(nValue, FieldUnit::PERCENT);
|
|
}
|
|
}
|
|
|
|
if( rAttrs->GetItemState( XATTR_FILLBMP_TILEOFFSETY ) != SfxItemState::INVALID )
|
|
{
|
|
sal_Int32 nValue = rAttrs->Get( XATTR_FILLBMP_TILEOFFSETY ).GetValue();
|
|
if(nValue > 0)
|
|
{
|
|
m_xTileOffLB->set_active(static_cast<sal_Int32>(COLUMN));
|
|
m_xTileOffset->set_value(nValue, FieldUnit::PERCENT);
|
|
}
|
|
}
|
|
|
|
m_xBitmapsPresets->set_sensitive(true);
|
|
m_xCtlBitmapPreview->set_sensitive(true);
|
|
|
|
UpdateBitmap();
|
|
}
|
|
|
|
std::unique_ptr<SvxBitmapTabPage> SvxBitmapTabPage::Create(weld::Container* pPage,
|
|
weld::DialogController* pController,
|
|
const SfxItemSet& rAttrs)
|
|
{
|
|
return std::make_unique<SvxBitmapTabPage>(pPage, pController, rAttrs);
|
|
}
|
|
|
|
void SvxBitmapTabPage::CalculateBitmapPresetSize()
|
|
{
|
|
if (m_aBitmapSize.IsEmpty())
|
|
return;
|
|
|
|
tools::Long nObjectWidth = static_cast<tools::Long>(m_fObjectWidth);
|
|
tools::Long nObjectHeight = static_cast<tools::Long>(m_fObjectHeight);
|
|
|
|
if (std::abs(m_aBitmapSize.Width() - nObjectWidth)
|
|
< std::abs(m_aBitmapSize.Height() - nObjectHeight))
|
|
{
|
|
m_aFilledSize.setWidth(nObjectWidth);
|
|
m_aFilledSize.setHeight(m_aBitmapSize.Height() * nObjectWidth / m_aBitmapSize.Width());
|
|
m_aZoomedSize.setWidth(m_aBitmapSize.Width() * nObjectHeight / m_aBitmapSize.Height());
|
|
m_aZoomedSize.setHeight(nObjectHeight);
|
|
}
|
|
else
|
|
{
|
|
m_aFilledSize.setWidth(m_aBitmapSize.Width() * nObjectHeight / m_aBitmapSize.Height());
|
|
m_aFilledSize.setHeight(nObjectHeight);
|
|
m_aZoomedSize.setWidth(nObjectWidth);
|
|
m_aZoomedSize.setHeight(m_aBitmapSize.Height() * nObjectWidth / m_aBitmapSize.Width());
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyBitmapHdl, const weld::TreeIter&, bool)
|
|
{
|
|
UpdateBitmap();
|
|
return true;
|
|
}
|
|
|
|
void SvxBitmapTabPage::UpdateBitmap()
|
|
{
|
|
std::unique_ptr<GraphicObject> pGraphicObject;
|
|
const int nPos = m_xBitmapsPresets->get_selected_index();
|
|
|
|
if (nPos >= 0)
|
|
{
|
|
pGraphicObject.reset(new GraphicObject(m_pBitmapList->GetBitmap(nPos)->GetGraphicObject()));
|
|
}
|
|
else
|
|
{
|
|
if(const XFillStyleItem* pFillStyleItem = m_rOutAttrs.GetItemIfSet(GetWhich(XATTR_FILLSTYLE)))
|
|
{
|
|
const drawing::FillStyle eXFS(pFillStyleItem->GetValue());
|
|
|
|
const XFillBitmapItem* pBitmapItem;
|
|
if((drawing::FillStyle_BITMAP == eXFS) && (pBitmapItem = m_rOutAttrs.GetItemIfSet(GetWhich(XATTR_FILLBITMAP))))
|
|
{
|
|
pGraphicObject.reset(new GraphicObject(pBitmapItem->GetGraphicObject()));
|
|
}
|
|
}
|
|
|
|
if (!pGraphicObject && m_xBitmapsPresets->n_children() > 0)
|
|
{
|
|
m_xBitmapsPresets->select(0);
|
|
pGraphicObject.reset(new GraphicObject(m_pBitmapList->GetBitmap(0)->GetGraphicObject()));
|
|
}
|
|
}
|
|
|
|
if(pGraphicObject)
|
|
{
|
|
Bitmap aBmp(pGraphicObject->GetGraphic().GetBitmap());
|
|
Size aTempBitmapSize = aBmp.GetSizePixel();
|
|
const double fUIScale = mpView ? mpView->GetModel().GetUIScale() : 1.0;
|
|
Size aBitmapSize100mm = o3tl::convert(aTempBitmapSize, o3tl::Length::pt, o3tl::Length::mm100);
|
|
|
|
m_aBitmapSize.setWidth(aBitmapSize100mm.Width() / fUIScale);
|
|
m_aBitmapSize.setHeight(aBitmapSize100mm.Height() / fUIScale);
|
|
CalculateBitmapPresetSize();
|
|
ModifyBitmapStyleHdl( *m_xBitmapStyleLB );
|
|
ModifyBitmapPositionHdl( *m_xPositionLB );
|
|
|
|
m_aFillAttributeSet.ClearItem(XATTR_FILLBITMAP);
|
|
m_aFillAttributeSet.Put(XFillStyleItem(drawing::FillStyle_BITMAP));
|
|
m_aFillAttributeSet.Put(XFillBitmapItem(OUString(), *pGraphicObject));
|
|
|
|
m_aCtlBitmapPreview.SetAttributes(m_aFillAttributeSet);
|
|
m_aCtlBitmapPreview.Invalidate();
|
|
}
|
|
else
|
|
{
|
|
SAL_WARN("cui.tabpages", "SvxBitmapTabPage::UpdateBitmap(): null pGraphicObject");
|
|
}
|
|
}
|
|
|
|
IMPL_LINK(SvxBitmapTabPage, ClickRenameHdl, int, nPos, void)
|
|
{
|
|
if (nPos < 0)
|
|
return;
|
|
|
|
OUString aDesc( CuiResId( RID_CUISTR_DESC_NEW_BITMAP ) );
|
|
OUString aName( m_pBitmapList->GetBitmap( nPos )->GetName() );
|
|
|
|
SvxNameDialog aDlg(GetFrameWeld(), aName, aDesc);
|
|
|
|
bool bLoop = true;
|
|
while (bLoop && aDlg.run() == RET_OK)
|
|
{
|
|
aName = aDlg.GetName();
|
|
sal_Int32 nBitmapPos = SearchBitmapList( aName );
|
|
bool bValidBitmapName = (nBitmapPos == static_cast<sal_Int32>(nPos) ) || (nBitmapPos == -1);
|
|
|
|
if(bValidBitmapName)
|
|
{
|
|
bLoop = false;
|
|
m_pBitmapList->GetBitmap(nPos)->SetName(aName);
|
|
|
|
m_xBitmapsPresets->set_item_accessible_name(nPos, aName);
|
|
m_xBitmapsPresets->set_item_tooltip_text(nPos, aName);
|
|
|
|
m_nBitmapListState |= ChangeType::MODIFIED;
|
|
}
|
|
else
|
|
{
|
|
std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), u"cui/ui/queryduplicatedialog.ui"_ustr));
|
|
std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog(u"DuplicateNameDialog"_ustr));
|
|
xBox->run();
|
|
}
|
|
}
|
|
}
|
|
|
|
IMPL_LINK(SvxBitmapTabPage, ClickDeleteHdl, int, nPos, void)
|
|
{
|
|
if (nPos < 0)
|
|
return;
|
|
|
|
std::unique_ptr<weld::Builder> xBuilder(
|
|
Application::CreateBuilder(GetFrameWeld(), u"cui/ui/querydeletebitmapdialog.ui"_ustr));
|
|
std::unique_ptr<weld::MessageDialog> xQueryBox(
|
|
xBuilder->weld_message_dialog(u"AskDelBitmapDialog"_ustr));
|
|
|
|
if (xQueryBox->run() != RET_YES)
|
|
return;
|
|
|
|
int nNextPos = m_xBitmapsPresets->get_selected_index();
|
|
const bool bDeletingSelectedItem(nPos == nNextPos);
|
|
if (bDeletingSelectedItem)
|
|
{
|
|
nNextPos += 1;
|
|
if (nNextPos >= m_xBitmapsPresets->n_children())
|
|
nNextPos = nPos - 1;
|
|
}
|
|
|
|
m_pBitmapList->Remove(static_cast<sal_uInt16>(nPos));
|
|
m_xBitmapsPresets->remove(nPos);
|
|
|
|
if (bDeletingSelectedItem)
|
|
{
|
|
m_xBitmapsPresets->select(nNextPos);
|
|
m_aCtlBitmapPreview.Invalidate();
|
|
}
|
|
UpdateBitmap();
|
|
m_nBitmapListState |= ChangeType::MODIFIED;
|
|
}
|
|
|
|
IMPL_LINK_NOARG( SvxBitmapTabPage, ModifyBitmapSizeHdl, weld::MetricSpinButton&, void )
|
|
{
|
|
m_bLogicalSize = false;
|
|
if (m_xTsbScale->get_state() != TRISTATE_TRUE && static_cast<BitmapStyle>(m_xBitmapStyleLB->get_active()) != TILED)
|
|
{
|
|
sal_Int64 nWidthPercent = m_xBitmapWidth->denormalize(m_xBitmapWidth->get_value(FieldUnit::NONE));
|
|
sal_Int64 nHeightPercent = m_xBitmapHeight->denormalize(m_xBitmapHeight->get_value(FieldUnit::NONE));
|
|
if (nWidthPercent == 100 && nHeightPercent == 100)
|
|
m_xBitmapStyleLB->set_active(static_cast<sal_Int32>(CUSTOM));
|
|
}
|
|
ModifyBitmapStyleHdl(*m_xBitmapStyleLB);
|
|
|
|
m_aCtlBitmapPreview.SetAttributes(m_aFillAttributeSet);
|
|
m_aCtlBitmapPreview.Invalidate();
|
|
}
|
|
|
|
IMPL_LINK_NOARG( SvxBitmapTabPage, ClickScaleHdl, weld::Toggleable&, void )
|
|
{
|
|
if (m_xTsbScale->get_state() == TRISTATE_TRUE)
|
|
{
|
|
m_xBitmapWidth->set_digits( 0 );
|
|
m_xBitmapWidth->set_unit(FieldUnit::PERCENT);
|
|
m_xBitmapWidth->set_value(100, FieldUnit::NONE);
|
|
m_xBitmapWidth->set_range(0, 100, FieldUnit::NONE);
|
|
|
|
m_xBitmapHeight->set_digits( 0 );
|
|
m_xBitmapHeight->set_unit(FieldUnit::PERCENT);
|
|
m_xBitmapHeight->set_value(100, FieldUnit::NONE);
|
|
m_xBitmapHeight->set_range(0, 100, FieldUnit::NONE);
|
|
}
|
|
else
|
|
{
|
|
m_xBitmapWidth->set_digits( 2 );
|
|
m_xBitmapWidth->set_unit(meFieldUnit);
|
|
m_xBitmapWidth->set_value(100, FieldUnit::NONE);
|
|
m_xBitmapWidth->set_range(0, 999900, FieldUnit::NONE);
|
|
|
|
m_xBitmapHeight->set_digits( 2 );
|
|
m_xBitmapHeight->set_unit(meFieldUnit);
|
|
m_xBitmapHeight->set_value(100, FieldUnit::NONE);
|
|
m_xBitmapHeight->set_range(0, 999900, FieldUnit::NONE);
|
|
}
|
|
|
|
ModifyBitmapStyleHdl( *m_xBitmapStyleLB );
|
|
}
|
|
|
|
IMPL_LINK_NOARG( SvxBitmapTabPage, ModifyBitmapStyleHdl, weld::ComboBox&, void )
|
|
{
|
|
BitmapStyle eStylePos = static_cast<BitmapStyle>(m_xBitmapStyleLB->get_active());
|
|
bool bIsStretched( eStylePos == STRETCHED );
|
|
bool bIsTiled( eStylePos == TILED );
|
|
|
|
m_xSizeBox->set_sensitive( !bIsStretched );
|
|
m_xPositionBox->set_sensitive( !bIsStretched );
|
|
m_xPositionOffBox->set_sensitive( bIsTiled );
|
|
m_xTileOffBox->set_sensitive( bIsTiled );
|
|
|
|
m_aFillAttributeSet.Put( XFillBmpTileItem( bIsTiled ) );
|
|
m_aFillAttributeSet.Put( XFillBmpStretchItem( bIsStretched ) );
|
|
|
|
if(!bIsStretched)
|
|
{
|
|
Size aSetBitmapSize;
|
|
switch(eStylePos)
|
|
{
|
|
case CUSTOM:
|
|
case TILED:
|
|
{
|
|
if (m_xTsbScale->get_sensitive() && m_xTsbScale->get_state() == TRISTATE_TRUE)
|
|
{
|
|
aSetBitmapSize.setWidth(o3tl::saturating_toggle_sign(m_xBitmapWidth->get_value(FieldUnit::NONE)));
|
|
aSetBitmapSize.setHeight(o3tl::saturating_toggle_sign(m_xBitmapHeight->get_value(FieldUnit::NONE)));
|
|
}
|
|
else
|
|
{
|
|
aSetBitmapSize.setWidth( GetCoreValue( *m_xBitmapWidth, mePoolUnit ) );
|
|
aSetBitmapSize.setHeight( GetCoreValue( *m_xBitmapHeight, mePoolUnit ) );
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
m_aFillAttributeSet.Put( XFillBmpSizeXItem( aSetBitmapSize.Width() ) );
|
|
m_aFillAttributeSet.Put( XFillBmpSizeYItem( aSetBitmapSize.Height() ) );
|
|
}
|
|
|
|
m_aCtlBitmapPreview.SetAttributes(m_aFillAttributeSet);
|
|
m_aCtlBitmapPreview.Invalidate();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyBitmapPositionHdl, weld::ComboBox&, void)
|
|
{
|
|
if (m_xPositionLB->get_sensitive())
|
|
m_aFillAttributeSet.Put( XFillBmpPosItem( static_cast< RectPoint >( m_xPositionLB->get_active() ) ) );
|
|
|
|
m_aCtlBitmapPreview.SetAttributes(m_aFillAttributeSet);
|
|
m_aCtlBitmapPreview.Invalidate();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyPositionOffsetHdl, weld::MetricSpinButton&, void)
|
|
{
|
|
if (m_xPositionOffX->get_sensitive())
|
|
m_aFillAttributeSet.Put( XFillBmpPosOffsetXItem( m_xPositionOffX->get_value(FieldUnit::PERCENT) ) );
|
|
|
|
if (m_xPositionOffY->get_sensitive())
|
|
m_aFillAttributeSet.Put( XFillBmpPosOffsetYItem( m_xPositionOffY->get_value(FieldUnit::PERCENT) ) );
|
|
|
|
m_aCtlBitmapPreview.SetAttributes(m_aFillAttributeSet);
|
|
m_aCtlBitmapPreview.Invalidate();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyTileOffsetHdl, weld::MetricSpinButton&, void)
|
|
{
|
|
sal_uInt16 nTileXOff = 0;
|
|
sal_uInt16 nTileYOff = 0;
|
|
|
|
if(m_xTileOffLB->get_active() == static_cast<sal_Int32>(ROW))
|
|
nTileXOff = o3tl::sanitizing_cast<sal_uInt16>(m_xTileOffset->get_value(FieldUnit::PERCENT));
|
|
|
|
if(m_xTileOffLB->get_active() == static_cast<sal_Int32>(COLUMN))
|
|
nTileYOff = o3tl::sanitizing_cast<sal_uInt16>(m_xTileOffset->get_value(FieldUnit::PERCENT));
|
|
|
|
m_aFillAttributeSet.Put( XFillBmpTileOffsetXItem(nTileXOff) );
|
|
m_aFillAttributeSet.Put( XFillBmpTileOffsetYItem(nTileYOff) );
|
|
|
|
m_aCtlBitmapPreview.SetAttributes(m_aFillAttributeSet);
|
|
m_aCtlBitmapPreview.Invalidate();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SvxBitmapTabPage, ClickImportHdl, weld::Button&, void)
|
|
{
|
|
weld::Window* pDialogFrameWeld = GetFrameWeld();
|
|
|
|
SvxOpenGraphicDialog aDlg(CuiResId(RID_CUISTR_ADD_IMAGE), pDialogFrameWeld);
|
|
aDlg.EnableLink(false);
|
|
tools::Long nCount = m_pBitmapList->Count();
|
|
|
|
if( aDlg.Execute() )
|
|
return;
|
|
|
|
Graphic aGraphic;
|
|
|
|
std::unique_ptr<weld::WaitObject> xWait(new weld::WaitObject(pDialogFrameWeld));
|
|
ErrCode nError = aDlg.GetGraphic( aGraphic );
|
|
xWait.reset();
|
|
|
|
if( !nError )
|
|
{
|
|
OUString aDesc(CuiResId(RID_CUISTR_DESC_EXT_BITMAP));
|
|
|
|
// convert file URL to UI name
|
|
OUString aName;
|
|
INetURLObject aURL( aDlg.GetPath() );
|
|
SvxNameDialog aNameDlg(pDialogFrameWeld, aURL.GetLastName().getToken(0, '.'), aDesc);
|
|
nError = ErrCode(1);
|
|
|
|
while (aNameDlg.run() == RET_OK)
|
|
{
|
|
aName = aNameDlg.GetName();
|
|
|
|
bool bDifferent = true;
|
|
|
|
for( tools::Long i = 0; i < nCount && bDifferent; i++ )
|
|
if( aName == m_pBitmapList->GetBitmap( i )->GetName() )
|
|
bDifferent = false;
|
|
|
|
if( bDifferent ) {
|
|
nError = ERRCODE_NONE;
|
|
break;
|
|
}
|
|
|
|
std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pDialogFrameWeld, u"cui/ui/queryduplicatedialog.ui"_ustr));
|
|
std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog(u"DuplicateNameDialog"_ustr));
|
|
if (xBox->run() != RET_OK)
|
|
break;
|
|
}
|
|
|
|
if( !nError )
|
|
AddBitmap(std::move(aGraphic), aName);
|
|
}
|
|
else
|
|
{
|
|
// graphic couldn't be loaded
|
|
std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pDialogFrameWeld, u"cui/ui/querynoloadedfiledialog.ui"_ustr));
|
|
std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog(u"NoLoadedFileDialog"_ustr));
|
|
xBox->run();
|
|
}
|
|
}
|
|
|
|
sal_Int32 SvxBitmapTabPage::SearchBitmapList(const GraphicObject& rGraphicObject)
|
|
{
|
|
tools::Long nCount = m_pBitmapList->Count();
|
|
sal_Int32 nPos = -1;
|
|
|
|
for(tools::Long i = 0;i < nCount;i++)
|
|
{
|
|
if(rGraphicObject.GetUniqueID() == m_pBitmapList->GetBitmap( i )->GetGraphicObject().GetUniqueID())
|
|
{
|
|
nPos = i;
|
|
break;
|
|
}
|
|
}
|
|
return nPos;
|
|
}
|
|
|
|
sal_Int32 SvxBitmapTabPage::SearchBitmapList(std::u16string_view rBitmapName)
|
|
{
|
|
tools::Long nCount = m_pBitmapList->Count();
|
|
bool bValidBitmapName = true;
|
|
sal_Int32 nPos = -1;
|
|
|
|
for(tools::Long i = 0;i < nCount && bValidBitmapName;i++)
|
|
{
|
|
if(rBitmapName == m_pBitmapList->GetBitmap( i )->GetName())
|
|
{
|
|
nPos = i;
|
|
bValidBitmapName = false;
|
|
}
|
|
}
|
|
return nPos;
|
|
}
|
|
|
|
tools::Long SvxBitmapTabPage::AddBitmap(const GraphicObject& rGraphicObject, const OUString& rName,
|
|
bool bOnlyForThisDocument)
|
|
{
|
|
const tools::Long nLastPos = m_pBitmapList->Count();
|
|
|
|
auto xBitmapEntry = std::make_unique<XBitmapEntry>(rGraphicObject, rName);
|
|
if (bOnlyForThisDocument)
|
|
xBitmapEntry->SetSavingAllowed(false);
|
|
m_pBitmapList->Insert(std::move(xBitmapEntry), nLastPos);
|
|
|
|
Bitmap aBitmap = m_pBitmapList->CreateBitmap(nLastPos, m_xBitmapLB->GetIconSize());
|
|
|
|
m_xBitmapsPresets->insert(nLastPos, nullptr, nullptr, &aBitmap, nullptr);
|
|
m_xBitmapsPresets->set_item_accessible_name(nLastPos, rName);
|
|
m_xBitmapsPresets->set_item_tooltip_text(nLastPos, rName);
|
|
m_xBitmapsPresets->select(nLastPos);
|
|
m_nBitmapListState |= ChangeType::MODIFIED;
|
|
|
|
UpdateBitmap();
|
|
|
|
// inform sidebar, etc. that the list of images has changed.
|
|
SfxViewFrame* pViewFrame = SfxViewFrame::Current();
|
|
if (pViewFrame)
|
|
pViewFrame->GetBindings().Invalidate(SID_ATTR_PAGE_BITMAP, /*ClearCacheStatus=*/true);
|
|
|
|
return nLastPos;
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|