Files
odfstudio/cui/source/tabpages/tpline.cxx
T
Armin Le Grand (collabora) 760394bbad Remove XFillAttrSetItem and XLineAttrSetItem
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>
2026-10-08 08:56:42 +02:00

1722 lines
61 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 <editeng/sizeitem.hxx>
#include <o3tl/untaint.hxx>
#include <osl/file.hxx>
#include <tools/debug.hxx>
#include <tools/urlobj.hxx>
#include <strings.hrc>
#include <svx/colorbox.hxx>
#include <svx/dlgctrl.hxx>
#include <svx/xlineit0.hxx>
#include <svx/xlinjoit.hxx>
#include <svx/xlncapit.hxx>
#include <svx/xlndsit.hxx>
#include <svx/xlnwtit.hxx>
#include <svx/xlnstwit.hxx>
#include <svx/xlnedwit.hxx>
#include <svx/xlnclit.hxx>
#include <svx/xlnstit.hxx>
#include <svx/xlnedit.hxx>
#include <svx/xlnstcit.hxx>
#include <svx/xlnedcit.hxx>
#include <svx/tabline.hxx>
#include <svx/xtable.hxx>
#include <svx/drawitem.hxx>
#include <cuitabline.hxx>
#include <dialmgr.hxx>
#include <svx/dlgutil.hxx>
#include <svx/svxgraphicitem.hxx>
#include <svx/ofaitem.hxx>
#include <svx/svdobj.hxx>
#include <svx/svdpage.hxx>
#include <svx/svdview.hxx>
#include <svx/svdmodel.hxx>
#include <svx/xlntrit.hxx>
#include <svx/xfltrit.hxx>
#include <editeng/numitem.hxx>
#include <editeng/brushitem.hxx>
#include <svx/gallery.hxx>
#include <sfx2/opengrf.hxx>
#include <svx/dialmgr.hxx>
#include <svx/svxids.hrc>
#include <svx/strings.hrc>
#include <cuitabarea.hxx>
#include <svtools/unitconv.hxx>
#include <vcl/weld/Dialog.hxx>
#include <comphelper/lok.hxx>
#include <o3tl/string_view.hxx>
#include <vcl/weld/Builder.hxx>
#include <vcl/weld/WaitObject.hxx>
#define MAX_BMP_WIDTH 16
#define MAX_BMP_HEIGHT 16
using namespace com::sun::star;
// static ----------------------------------------------------------------
const WhichRangesContainer SvxLineTabPage::pLineRanges(svl::Items<
XATTR_LINETRANSPARENCE, XATTR_LINETRANSPARENCE,
SID_ATTR_LINE_STYLE, SID_ATTR_LINE_ENDCENTER
>);
SvxLineTabPage::SvxLineTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
: SfxTabPage(pPage, pController, u"cui/ui/linetabpage.ui"_ustr, u"LineTabPage"_ustr, &rInAttrs)
, m_pSymbolList(nullptr)
, m_bNewSize(false)
, m_nSymbolType(SVX_SYMBOLTYPE_UNKNOWN) // unknown respectively unchanged
, m_bLastWidthModified(false)
, m_aSymbolLastSize(Size(0,0))
, m_bSymbols(false)
, m_rOutAttrs(rInAttrs)
, m_bObjSelected(false)
, m_aLineAttributeSet(rInAttrs.getPool(), WhichRangesContainer(XATTR_LINE_FIRST, XATTR_LINE_LAST))
, m_pnLineEndListState(nullptr)
, m_pnDashListState(nullptr)
, m_pnColorListState(nullptr)
, m_nPageType(PageType::Area)
, m_nDlgType(0)
, m_pPosDashLb(nullptr)
, m_pPosLineEndLb(nullptr)
, m_xBoxColor(m_xBuilder->weld_widget(u"boxCOLOR"_ustr))
, m_xLbLineStyle(new SvxLineLB(m_xBuilder->weld_combo_box(u"LB_LINE_STYLE"_ustr)))
, m_xLbColor(new ColorListBox(m_xBuilder->weld_menu_button(u"LB_COLOR"_ustr),
[this]{ return GetDialogController()->getDialog(); }))
, m_xBoxWidth(m_xBuilder->weld_widget(u"boxWIDTH"_ustr))
, m_xMtrLineWidth(m_xBuilder->weld_metric_spin_button(u"MTR_FLD_LINE_WIDTH"_ustr, FieldUnit::CM))
, m_xBoxTransparency(m_xBuilder->weld_widget(u"boxTRANSPARENCY"_ustr))
, m_xMtrTransparent(m_xBuilder->weld_metric_spin_button(u"MTR_LINE_TRANSPARENT"_ustr, FieldUnit::PERCENT))
, m_xFlLineEnds(m_xBuilder->weld_widget(u"FL_LINE_ENDS"_ustr))
, m_xBoxArrowStyles(m_xBuilder->weld_widget(u"boxARROW_STYLES"_ustr))
, m_xLbStartStyle(new SvxLineEndLB(m_xBuilder->weld_combo_box(u"LB_START_STYLE"_ustr)))
, m_xBoxStart(m_xBuilder->weld_widget(u"boxSTART"_ustr))
, m_xMtrStartWidth(m_xBuilder->weld_metric_spin_button(u"MTR_FLD_START_WIDTH"_ustr, FieldUnit::CM))
, m_xTsbCenterStart(m_xBuilder->weld_check_button(u"TSB_CENTER_START"_ustr))
, m_xBoxEnd(m_xBuilder->weld_widget(u"boxEND"_ustr))
, m_xLbEndStyle(new SvxLineEndLB(m_xBuilder->weld_combo_box(u"LB_END_STYLE"_ustr)))
, m_xMtrEndWidth(m_xBuilder->weld_metric_spin_button(u"MTR_FLD_END_WIDTH"_ustr, FieldUnit::CM))
, m_xTsbCenterEnd(m_xBuilder->weld_check_button(u"TSB_CENTER_END"_ustr))
, m_xCbxSynchronize(m_xBuilder->weld_check_button(u"CBX_SYNCHRONIZE"_ustr))
, m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, u"CTL_PREVIEW"_ustr, m_aCtlPreview))
, m_xFLEdgeStyle(m_xBuilder->weld_widget(u"FL_EDGE_STYLE"_ustr))
, m_xGridEdgeCaps(m_xBuilder->weld_widget(u"gridEDGE_CAPS"_ustr))
, m_xLBEdgeStyle(m_xBuilder->weld_combo_box(u"LB_EDGE_STYLE"_ustr))
, m_xLBCapStyle(m_xBuilder->weld_combo_box(u"LB_CAP_STYLE"_ustr)) // LineCaps
, m_xFlSymbol(m_xBuilder->weld_widget(u"FL_SYMBOL_FORMAT"_ustr)) //#58425# Symbols on a line (e.g. StarChart)
, m_xGridIconSize(m_xBuilder->weld_widget(u"gridICON_SIZE"_ustr))
, m_xSymbolMB(m_xBuilder->weld_menu_button(u"MB_SYMBOL_BITMAP"_ustr))
, m_xSymbolWidthMF(m_xBuilder->weld_metric_spin_button(u"MF_SYMBOL_WIDTH"_ustr, FieldUnit::CM))
, m_xSymbolHeightMF(m_xBuilder->weld_metric_spin_button(u"MF_SYMBOL_HEIGHT"_ustr, FieldUnit::CM))
, m_xSymbolRatioCB(m_xBuilder->weld_check_button(u"CB_SYMBOL_RATIO"_ustr))
{
// This Page requires ExchangeSupport
SetExchangeSupport();
// Metric set
FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
switch ( eFUnit )
{
case FieldUnit::M:
case FieldUnit::KM:
eFUnit = FieldUnit::MM;
[[fallthrough]]; // we now have mm
case FieldUnit::MM:
m_xMtrLineWidth->set_increments(50, 500, FieldUnit::NONE);
m_xMtrStartWidth->set_increments(50, 500, FieldUnit::NONE);
m_xMtrEndWidth->set_increments(50, 500, FieldUnit::NONE);
break;
case FieldUnit::INCH:
m_xMtrLineWidth->set_increments(2, 20, FieldUnit::NONE);
m_xMtrStartWidth->set_increments(2, 20, FieldUnit::NONE);
m_xMtrEndWidth->set_increments(2, 20, FieldUnit::NONE);
break;
default: ;// prevent warning
}
SetFieldUnit( *m_xMtrLineWidth, eFUnit );
SetFieldUnit( *m_xMtrStartWidth, eFUnit );
SetFieldUnit( *m_xMtrEndWidth, eFUnit );
// determine PoolUnit
SfxItemPool* pPool = m_rOutAttrs.GetPool();
assert(pPool && "Where is the pool?");
m_ePoolUnit = pPool->GetMetric( SID_ATTR_LINE_WIDTH );
m_xLbLineStyle->connect_changed(LINK(this, SvxLineTabPage, ClickInvisibleHdl_Impl));
m_xLbColor->SetSelectHdl( LINK( this, SvxLineTabPage, ChangePreviewListBoxHdl_Impl ) );
m_xMtrLineWidth->connect_value_changed(LINK(this, SvxLineTabPage, ChangePreviewModifyHdl_Impl));
m_xMtrTransparent->connect_value_changed(LINK( this, SvxLineTabPage, ChangeTransparentHdl_Impl));
m_xLbStartStyle->connect_changed(LINK(this, SvxLineTabPage, ChangeStartListBoxHdl_Impl));
m_xLbEndStyle->connect_changed(LINK(this, SvxLineTabPage, ChangeEndListBoxHdl_Impl));
m_xMtrStartWidth->connect_value_changed(LINK(this, SvxLineTabPage, ChangeStartModifyHdl_Impl));
m_xMtrEndWidth->connect_value_changed(LINK( this, SvxLineTabPage, ChangeEndModifyHdl_Impl));
m_xTsbCenterStart->connect_toggled(LINK(this, SvxLineTabPage, ChangeStartClickHdl_Impl));
m_xTsbCenterEnd->connect_toggled(LINK(this, SvxLineTabPage, ChangeEndClickHdl_Impl));
Link<weld::ComboBox&,void> aEdgeStyle = LINK(this, SvxLineTabPage, ChangeEdgeStyleHdl_Impl);
m_xLBEdgeStyle->connect_changed(aEdgeStyle);
// LineCaps
Link<weld::ComboBox&,void> aCapStyle = LINK(this, SvxLineTabPage, ChangeCapStyleHdl_Impl);
m_xLBCapStyle->connect_changed(aCapStyle);
// Symbols on a line (eg star charts), MB-handler set
m_xSymbolMB->connect_selected(LINK(this, SvxLineTabPage, GraphicHdl_Impl));
m_xSymbolWidthMF->connect_value_changed(LINK(this, SvxLineTabPage, SizeHdl_Impl));
m_xSymbolHeightMF->connect_value_changed(LINK(this, SvxLineTabPage, SizeHdl_Impl));
m_xSymbolRatioCB->connect_toggled(LINK(this, SvxLineTabPage, RatioHdl_Impl));
m_xSymbolRatioCB->set_active(true);
ShowSymbolControls(false);
m_nActLineWidth = -1;
}
void SvxLineTabPage::ShowSymbolControls(bool bOn)
{
// Symbols on a line (e.g. StarCharts), symbol-enable controls
m_bSymbols=bOn;
m_xFlSymbol->set_visible(bOn);
m_aCtlPreview.ShowSymbol(bOn);
}
SvxLineTabPage::~SvxLineTabPage()
{
m_xCtlPreview.reset();
m_xLbEndStyle.reset();
m_xLbStartStyle.reset();
m_xLbColor.reset();
m_xLbLineStyle.reset();
m_aGalleryBrushItems.clear();
m_aSymbolBrushItems.clear();
}
void SvxLineTabPage::Construct()
{
FillListboxes();
PopulateMenus();
}
void SvxLineTabPage::FillListboxes()
{
// Line styles
auto nOldSelect = m_xLbLineStyle->get_active();
// aLbLineStyle.FillStyles();
m_xLbLineStyle->Fill( m_pDashList );
m_xLbLineStyle->set_active( nOldSelect );
// Line end style
OUString sNone( comphelper::LibreOfficeKit::isActive() ? SvxResId( RID_SVXSTR_INVISIBLE )
: SvxResId( RID_SVXSTR_NONE ) );
nOldSelect = m_xLbStartStyle->get_active();
m_xLbStartStyle->clear();
m_xLbStartStyle->append_text(sNone);
m_xLbStartStyle->Fill(m_pLineEndList);
m_xLbStartStyle->set_active(nOldSelect);
nOldSelect = m_xLbEndStyle->get_active();
m_xLbEndStyle->clear();
m_xLbEndStyle->append_text(sNone);
m_xLbEndStyle->Fill(m_pLineEndList, false);
m_xLbEndStyle->set_active(nOldSelect);
}
void SvxLineTabPage::ActivatePage( const SfxItemSet& rSet )
{
const SfxUInt16Item* pPageTypeItem = rSet.GetItem<SfxUInt16Item>(SID_PAGE_TYPE, false);
if (pPageTypeItem)
SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
if( m_nDlgType == 0 && m_pDashList.is() )
{
sal_Int32 nPos;
sal_Int32 nCount;
// Dash list
if( ( *m_pnDashListState & ChangeType::MODIFIED ) ||
( *m_pnDashListState & ChangeType::CHANGED ) )
{
if( *m_pnDashListState & ChangeType::CHANGED )
m_pDashList = static_cast<SvxLineTabDialog*>(GetDialogController() )->GetNewDashList();
*m_pnDashListState = ChangeType::NONE;
// Style list
nPos = m_xLbLineStyle->get_active();
m_xLbLineStyle->clear();
m_xLbLineStyle->append_text(SvxResId(RID_SVXSTR_INVISIBLE));
m_xLbLineStyle->append_text(SvxResId(RID_SVXSTR_SOLID));
m_xLbLineStyle->Fill(m_pDashList);
nCount = m_xLbLineStyle->get_count();
if ( nCount == 0 )
; // This case should never occur
else if( nCount <= nPos )
m_xLbLineStyle->set_active(0);
else
m_xLbLineStyle->set_active(nPos);
}
INetURLObject aDashURL( m_pDashList->GetPath() );
aDashURL.Append( m_pDashList->GetName() );
DBG_ASSERT( aDashURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
// LineEnd list
if( ( *m_pnLineEndListState & ChangeType::MODIFIED ) || ( *m_pnLineEndListState & ChangeType::CHANGED ) )
{
if( *m_pnLineEndListState & ChangeType::CHANGED )
m_pLineEndList = static_cast<SvxLineTabDialog*>(GetDialogController())->GetNewLineEndList();
*m_pnLineEndListState = ChangeType::NONE;
OUString sNone( comphelper::LibreOfficeKit::isActive() ? SvxResId( RID_SVXSTR_INVISIBLE )
: SvxResId( RID_SVXSTR_NONE ) );
auto sActiveStyle = m_xLbStartStyle->get_active_text();
m_xLbStartStyle->clear();
m_xLbStartStyle->append_text(sNone);
m_xLbStartStyle->Fill( m_pLineEndList );
// tdf#126040 - load previously selected start line style index
auto nStylePos = m_xLbStartStyle->find_text(sActiveStyle);
m_xLbStartStyle->set_active(nStylePos == -1 ? 0 : nStylePos);
sActiveStyle = m_xLbEndStyle->get_active_text();
m_xLbEndStyle->clear();
m_xLbEndStyle->append_text(sNone);
m_xLbEndStyle->Fill( m_pLineEndList, false );
// tdf#126040 - load previously selected end line style index
nStylePos = m_xLbEndStyle->find_text(sActiveStyle);
m_xLbEndStyle->set_active(nStylePos == -1 ? 0 : nStylePos);
}
INetURLObject aLineURL( m_pLineEndList->GetPath() );
aLineURL.Append( m_pLineEndList->GetName() );
DBG_ASSERT( aLineURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
// Evaluate if another TabPage set another fill type
if( m_xLbLineStyle->get_active() != 0 )
{
if( m_nPageType == PageType::Hatch ) // 1
{
m_xLbLineStyle->set_active(*m_pPosDashLb + 2); // +2 due to SOLID and INVISIBLE
ChangePreviewHdl_Impl( nullptr );
}
if( m_nPageType == PageType::Bitmap )
{
m_xLbStartStyle->set_active(*m_pPosLineEndLb + 1);// +1 due to SOLID
m_xLbEndStyle->set_active(*m_pPosLineEndLb + 1);// +1 due to SOLID
ChangePreviewHdl_Impl( nullptr );
}
}
// ColorList
if( *m_pnColorListState != ChangeType::NONE )
{
ChangePreviewHdl_Impl( nullptr );
}
m_nPageType = PageType::Area;
}
// Page does not yet exist in the ctor, that's why we do it here!
else if (m_nDlgType == 1101) // nNoArrowNoShadowDlg from chart2/source/controller/dialogs/dlg_ObjectProperties.cxx
{
m_xFlLineEnds->hide();
m_xFLEdgeStyle->hide();
}
}
DeactivateRC SvxLineTabPage::DeactivatePage( SfxItemSet* _pSet )
{
if( m_nDlgType == 0 ) // Line dialog
{
m_nPageType = PageType::Gradient; // possibly for extensions
*m_pPosDashLb = m_xLbLineStyle->get_active() - 2;// First entry SOLID!!!
sal_Int32 nPos = m_xLbStartStyle->get_active();
if (nPos != -1)
nPos--;
*m_pPosLineEndLb = nPos;
}
if( _pSet )
FillItemSet( _pSet );
return DeactivateRC::LeavePage;
}
bool SvxLineTabPage::FillItemSet( SfxItemSet* rAttrs )
{
const SfxPoolItem* pOld = nullptr;
sal_Int32 nPos;
bool bModified = false;
// To prevent modifications to the list, we do not set other page's items.
if( m_nDlgType != 0 || m_nPageType != PageType::Hatch )
{
nPos = m_xLbLineStyle->get_active();
if( nPos != -1 &&
m_xLbLineStyle->get_value_changed_from_saved() )
{
std::unique_ptr<XLineStyleItem> pStyleItem;
if( nPos == 0 )
pStyleItem.reset(new XLineStyleItem( drawing::LineStyle_NONE ));
else if( nPos == 1 )
pStyleItem.reset(new XLineStyleItem( drawing::LineStyle_SOLID ));
else
{
pStyleItem.reset(new XLineStyleItem( drawing::LineStyle_DASH ));
// For added security
if( m_pDashList->Count() > static_cast<tools::Long>( nPos - 2 ) )
{
XLineDashItem aDashItem( m_xLbLineStyle->get_active_text(),
m_pDashList->GetDash( nPos - 2 )->GetDash() );
pOld = GetOldItem( *rAttrs, XATTR_LINEDASH );
if ( !pOld || !( *static_cast<const XLineDashItem*>(pOld) == aDashItem ) )
{
rAttrs->Put( aDashItem );
bModified = true;
}
}
}
pOld = GetOldItem( *rAttrs, XATTR_LINESTYLE );
if ( !pOld || !( *static_cast<const XLineStyleItem*>(pOld) == *pStyleItem ) )
{
rAttrs->Put( std::move(pStyleItem) );
bModified = true;
}
}
}
// Line width
// GetSavedValue() returns OUString!
if( m_xMtrLineWidth->get_value_changed_from_saved() )
{
XLineWidthItem aItem( GetCoreValue( *m_xMtrLineWidth, m_ePoolUnit ) );
pOld = GetOldItem( *rAttrs, XATTR_LINEWIDTH );
if ( !pOld || !( *static_cast<const XLineWidthItem*>(pOld) == aItem ) )
{
rAttrs->Put( aItem );
bModified = true;
}
}
// Width line start
if( m_xMtrStartWidth->get_value_changed_from_saved() )
{
XLineStartWidthItem aItem( GetCoreValue( *m_xMtrStartWidth, m_ePoolUnit ) );
pOld = GetOldItem( *rAttrs, XATTR_LINESTARTWIDTH );
if ( !pOld || !( *static_cast<const XLineStartWidthItem*>(pOld) == aItem ) )
{
rAttrs->Put( aItem );
bModified = true;
}
}
// Width line end
if( m_xMtrEndWidth->get_value_changed_from_saved() )
{
XLineEndWidthItem aItem( GetCoreValue( *m_xMtrEndWidth, m_ePoolUnit ) );
pOld = GetOldItem( *rAttrs, XATTR_LINEENDWIDTH );
if ( !pOld || !( *static_cast<const XLineEndWidthItem*>(pOld) == aItem ) )
{
rAttrs->Put( aItem );
bModified = true;
}
}
// Line color
if (m_xLbColor->IsValueChangedFromSaved())
{
NamedColor aNamedColor = m_xLbColor->GetSelectedEntry();
XLineColorItem aItem(aNamedColor.m_aName, aNamedColor.m_aColor);
aItem.setComplexColor(aNamedColor.getComplexColor());
pOld = GetOldItem( *rAttrs, XATTR_LINECOLOR );
if ( !pOld || !( *static_cast<const XLineColorItem*>(pOld) == aItem ) )
{
rAttrs->Put( aItem );
bModified = true;
}
}
if( m_nDlgType != 0 || m_nPageType != PageType::Bitmap )
{
// Line start
nPos = m_xLbStartStyle->get_active();
if( nPos != -1 && m_xLbStartStyle->get_value_changed_from_saved() )
{
std::unique_ptr<XLineStartItem> pItem;
if( nPos == 0 )
pItem.reset(new XLineStartItem());
else if( m_pLineEndList->Count() > static_cast<tools::Long>( nPos - 1 ) )
pItem.reset(new XLineStartItem( m_xLbStartStyle->get_active_text(), m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ));
pOld = GetOldItem( *rAttrs, XATTR_LINESTART );
if( pItem && ( !pOld || *pOld != *pItem ) )
{
rAttrs->Put( std::move(pItem) );
bModified = true;
}
}
// Line end
nPos = m_xLbEndStyle->get_active();
if( nPos != -1 && m_xLbEndStyle->get_value_changed_from_saved() )
{
std::unique_ptr<XLineEndItem> pItem;
if( nPos == 0 )
pItem.reset(new XLineEndItem());
else if( m_pLineEndList->Count() > static_cast<tools::Long>( nPos - 1 ) )
pItem.reset(new XLineEndItem( m_xLbEndStyle->get_active_text(), m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ));
pOld = GetOldItem( *rAttrs, XATTR_LINEEND );
if( pItem &&
( !pOld || !( *static_cast<const XLineEndItem*>(pOld) == *pItem ) ) )
{
rAttrs->Put( std::move(pItem) );
bModified = true;
}
}
}
// Centered line end
TriState eState = m_xTsbCenterStart->get_state();
if( m_xTsbCenterStart->get_state_changed_from_saved() )
{
XLineStartCenterItem aItem( eState != TRISTATE_FALSE );
pOld = GetOldItem( *rAttrs, XATTR_LINESTARTCENTER );
if ( !pOld || !( *static_cast<const XLineStartCenterItem*>(pOld) == aItem ) )
{
rAttrs->Put( aItem );
bModified = true;
}
}
eState = m_xTsbCenterEnd->get_state();
if( m_xTsbCenterEnd->get_state_changed_from_saved() )
{
XLineEndCenterItem aItem( eState != TRISTATE_FALSE );
pOld = GetOldItem( *rAttrs, XATTR_LINEENDCENTER );
if ( !pOld || !( *static_cast<const XLineEndCenterItem*>(pOld) == aItem ) )
{
rAttrs->Put( aItem );
bModified = true;
}
}
// Transparency
if( m_xMtrTransparent->get_value_changed_from_saved() )
{
XLineTransparenceItem aItem(m_xMtrTransparent->get_value(FieldUnit::PERCENT));
pOld = GetOldItem( *rAttrs, XATTR_LINETRANSPARENCE );
if ( !pOld || !( *static_cast<const XLineTransparenceItem*>(pOld) == aItem ) )
{
rAttrs->Put( aItem );
bModified = true;
}
}
nPos = m_xLBEdgeStyle->get_active();
if (nPos != -1 && m_xLBEdgeStyle->get_value_changed_from_saved())
{
std::unique_ptr<XLineJointItem> pNew;
switch(nPos)
{
case 0: // Rounded, default
{
pNew.reset(new XLineJointItem(css::drawing::LineJoint_ROUND));
break;
}
case 1: // - none -
{
pNew.reset(new XLineJointItem(css::drawing::LineJoint_NONE));
break;
}
case 2: // Miter
{
pNew.reset(new XLineJointItem(css::drawing::LineJoint_MITER));
break;
}
case 3: // Bevel
{
pNew.reset(new XLineJointItem(css::drawing::LineJoint_BEVEL));
break;
}
}
if(pNew)
{
pOld = GetOldItem( *rAttrs, XATTR_LINEJOINT );
if(!pOld || !(*static_cast<const XLineJointItem*>(pOld) == *pNew))
{
rAttrs->Put( std::move(pNew) );
bModified = true;
}
}
}
// LineCaps
nPos = m_xLBCapStyle->get_active();
if (nPos != -1 && m_xLBCapStyle->get_value_changed_from_saved())
{
std::unique_ptr<XLineCapItem> pNew;
switch(nPos)
{
case 0: // Butt (=Flat), default
{
pNew.reset(new XLineCapItem(css::drawing::LineCap_BUTT));
break;
}
case 1: // Round
{
pNew.reset(new XLineCapItem(css::drawing::LineCap_ROUND));
break;
}
case 2: // Square
{
pNew.reset(new XLineCapItem(css::drawing::LineCap_SQUARE));
break;
}
}
if(pNew)
{
pOld = GetOldItem( *rAttrs, XATTR_LINECAP );
if(!pOld || !(*static_cast<const XLineCapItem*>(pOld) == *pNew))
{
rAttrs->Put( std::move(pNew) );
bModified = true;
}
}
}
if(m_nSymbolType!=SVX_SYMBOLTYPE_UNKNOWN || m_bNewSize)
{
// Was set by selection or the size is different
SvxSizeItem aSItem(rAttrs->GetPool()->GetWhichIDFromSlotID(SID_ATTR_SYMBOLSIZE),m_aSymbolSize);
const SfxPoolItem* pSOld = GetOldItem( *rAttrs, rAttrs->GetPool()->GetWhichIDFromSlotID(SID_ATTR_SYMBOLSIZE) );
m_bNewSize = pSOld ? *static_cast<const SvxSizeItem *>(pSOld) != aSItem : m_bNewSize ;
if(m_bNewSize)
{
rAttrs->Put(aSItem);
bModified=true;
}
SfxInt32Item aTItem(rAttrs->GetPool()->GetWhichIDFromSlotID(SID_ATTR_SYMBOLTYPE),m_nSymbolType);
const SfxPoolItem* pTOld = GetOldItem( *rAttrs, rAttrs->GetPool()->GetWhichIDFromSlotID(SID_ATTR_SYMBOLTYPE) );
bool bNewType = pTOld == nullptr || *static_cast<const SfxInt32Item*>(pTOld) != aTItem;
if(bNewType && m_nSymbolType==SVX_SYMBOLTYPE_UNKNOWN)
bNewType=false; // a small fix, type wasn't set -> don't create a type item after all!
if(bNewType)
{
rAttrs->Put(aTItem);
bModified=true;
}
if(m_nSymbolType!=SVX_SYMBOLTYPE_NONE)
{
SvxBrushItem aBItem(m_aSymbolGraphic,GPOS_MM,rAttrs->GetPool()->GetWhichIDFromSlotID(SID_ATTR_BRUSH));
const SfxPoolItem* pBOld = GetOldItem( *rAttrs, rAttrs->GetPool()->GetWhichIDFromSlotID(SID_ATTR_BRUSH) );
bool bNewBrush =
pBOld == nullptr || *static_cast<const SvxBrushItem*>(pBOld) != aBItem;
if(bNewBrush)
{
rAttrs->Put(aBItem);
bModified=true;
}
}
}
rAttrs->Put (CntUInt16Item(SID_PAGE_TYPE, static_cast<sal_uInt16>(m_nPageType)));
return bModified;
}
void SvxLineTabPage::FillXLSet_Impl()
{
sal_Int32 nPos;
if (m_xLbLineStyle->get_active() == -1)
{
m_aLineAttributeSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
}
else if (m_xLbLineStyle->get_active() == 0)
m_aLineAttributeSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
else if (m_xLbLineStyle->get_active() == 1)
m_aLineAttributeSet.Put( XLineStyleItem( drawing::LineStyle_SOLID ) );
else
{
m_aLineAttributeSet.Put( XLineStyleItem( drawing::LineStyle_DASH ) );
nPos = m_xLbLineStyle->get_active();
if (nPos != -1)
{
m_aLineAttributeSet.Put( XLineDashItem( m_xLbLineStyle->get_active_text(),
m_pDashList->GetDash( nPos - 2 )->GetDash() ) );
}
}
nPos = m_xLbStartStyle->get_active();
if (nPos != -1)
{
if( nPos == 0 )
m_aLineAttributeSet.Put( XLineStartItem() );
else
m_aLineAttributeSet.Put( XLineStartItem( m_xLbStartStyle->get_active_text(),
m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ) );
}
nPos = m_xLbEndStyle->get_active();
if (nPos != -1)
{
if( nPos == 0 )
m_aLineAttributeSet.Put( XLineEndItem() );
else
m_aLineAttributeSet.Put( XLineEndItem( m_xLbEndStyle->get_active_text(),
m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ) );
}
nPos = m_xLBEdgeStyle->get_active();
if (nPos != -1)
{
switch(nPos)
{
case 0: // Rounded, default
{
m_aLineAttributeSet.Put(XLineJointItem(css::drawing::LineJoint_ROUND));
break;
}
case 1: // - none -
{
m_aLineAttributeSet.Put(XLineJointItem(css::drawing::LineJoint_NONE));
break;
}
case 2: // Miter
{
m_aLineAttributeSet.Put(XLineJointItem(css::drawing::LineJoint_MITER));
break;
}
case 3: // Bevel
{
m_aLineAttributeSet.Put(XLineJointItem(css::drawing::LineJoint_BEVEL));
break;
}
}
}
// LineCaps
nPos = m_xLBCapStyle->get_active();
if (nPos != -1)
{
switch(nPos)
{
case 0: // Butt (=Flat), default
{
m_aLineAttributeSet.Put(XLineCapItem(css::drawing::LineCap_BUTT));
break;
}
case 1: // Round
{
m_aLineAttributeSet.Put(XLineCapItem(css::drawing::LineCap_ROUND));
break;
}
case 2: // Square
{
m_aLineAttributeSet.Put(XLineCapItem(css::drawing::LineCap_SQUARE));
break;
}
}
}
m_aLineAttributeSet.Put( XLineStartWidthItem( GetCoreValue( *m_xMtrStartWidth, m_ePoolUnit ) ) );
m_aLineAttributeSet.Put( XLineEndWidthItem( GetCoreValue( *m_xMtrEndWidth, m_ePoolUnit ) ) );
m_aLineAttributeSet.Put( XLineWidthItem( GetCoreValue( *m_xMtrLineWidth, m_ePoolUnit ) ) );
NamedColor aNamedColor = m_xLbColor->GetSelectedEntry();
XLineColorItem aLineColor(aNamedColor.m_aName, aNamedColor.m_aColor);
aLineColor.setComplexColor(aNamedColor.getComplexColor());
m_aLineAttributeSet.Put(aLineColor);
// Centered line end
if( m_xTsbCenterStart->get_state() == TRISTATE_TRUE )
m_aLineAttributeSet.Put( XLineStartCenterItem( true ) );
else if( m_xTsbCenterStart->get_state() == TRISTATE_FALSE )
m_aLineAttributeSet.Put( XLineStartCenterItem( false ) );
if( m_xTsbCenterEnd->get_state() == TRISTATE_TRUE )
m_aLineAttributeSet.Put( XLineEndCenterItem( true ) );
else if( m_xTsbCenterEnd->get_state() == TRISTATE_FALSE )
m_aLineAttributeSet.Put( XLineEndCenterItem( false ) );
// Transparency
sal_uInt16 nVal = o3tl::sanitizing_cast<sal_uInt16>(m_xMtrTransparent->get_value(FieldUnit::PERCENT));
m_aLineAttributeSet.Put( XLineTransparenceItem( nVal ) );
m_aCtlPreview.SetLineAttributes(m_aLineAttributeSet);
}
void SvxLineTabPage::Reset( const SfxItemSet* rAttrs )
{
drawing::LineStyle eXLS; // drawing::LineStyle_NONE, drawing::LineStyle_SOLID, drawing::LineStyle_DASH
// Line style
tools::Long nSymType=SVX_SYMBOLTYPE_UNKNOWN;
bool bPrevSym=false;
bool bEnable=true;
bool bIgnoreGraphic=false;
bool bIgnoreSize=false;
if(const SfxInt32Item* pSymbolTypeItem = rAttrs->GetItemIfSet(rAttrs->GetPool()->GetWhichIDFromSlotID(SID_ATTR_SYMBOLTYPE)))
{
nSymType = pSymbolTypeItem->GetValue();
}
if(nSymType == SVX_SYMBOLTYPE_AUTO)
{
m_aSymbolGraphic=m_aAutoSymbolGraphic;
m_aSymbolSize=m_aSymbolLastSize=m_aAutoSymbolGraphic.GetPrefSize();
bPrevSym=true;
}
else if(nSymType == SVX_SYMBOLTYPE_NONE)
{
bEnable=false;
bIgnoreGraphic=true;
bIgnoreSize=true;
}
else if(nSymType >= 0)
{
ScopedVclPtrInstance< VirtualDevice > pVDev;
pVDev->SetMapMode(MapMode(MapUnit::Map100thMM));
std::unique_ptr<SdrModel> pModel(
new SdrModel(nullptr, nullptr, true));
rtl::Reference<SdrPage> pPage = new SdrPage( *pModel, false );
pPage->SetSize(Size(1000,1000));
pModel->InsertPage( pPage.get(), 0 );
{
SdrView aView( *pModel, pVDev );
aView.hideMarkHandles();
aView.ShowSdrPage(pPage.get());
size_t nSymTmp = static_cast<size_t>(nSymType);
if(m_pSymbolList)
{
if(m_pSymbolList->GetObjCount())
{
nSymTmp %= m_pSymbolList->GetObjCount(); // Treat list as cyclic!
rtl::Reference<SdrObject> pObj=m_pSymbolList->GetObj(nSymTmp);
if(pObj)
{
// directly clone to target SdrModel
pObj = pObj->CloneSdrObject(*pModel);
if(m_xSymbolAttr)
{
pObj->SetMergedItemSet(*m_xSymbolAttr);
}
else
{
pObj->SetMergedItemSet(m_rOutAttrs);
}
pPage->NbcInsertObject(pObj.get());
// Generate invisible square to give all symbol types a
// bitmap size, which is independent from specific glyph
rtl::Reference<SdrObject> pInvisibleSquare(m_pSymbolList->GetObj(0));
// directly clone to target SdrModel
pInvisibleSquare = pInvisibleSquare->CloneSdrObject(*pModel);
pPage->NbcInsertObject(pInvisibleSquare.get());
pInvisibleSquare->SetMergedItem(XFillTransparenceItem(100));
pInvisibleSquare->SetMergedItem(XLineTransparenceItem(100));
aView.MarkAll();
GDIMetaFile aMeta(aView.GetMarkedObjMetaFile());
m_aSymbolGraphic=Graphic(aMeta);
m_aSymbolSize=pObj->GetSnapRect().GetSize();
m_aSymbolGraphic.SetPrefSize(pInvisibleSquare->GetSnapRect().GetSize());
m_aSymbolGraphic.SetPrefMapMode(MapMode(MapUnit::Map100thMM));
bPrevSym=true;
bEnable=true;
bIgnoreGraphic=true;
aView.UnmarkAll();
pPage->RemoveObject(1);
pInvisibleSquare.clear();
pPage->RemoveObject(0);
pObj.clear();
}
}
}
}
}
if(const SvxBrushItem* pBrushItem = rAttrs->GetItemIfSet(rAttrs->GetPool()->GetWhichIDFromSlotID(SID_ATTR_BRUSH)))
{
const Graphic* pGraphic = pBrushItem->GetGraphic();
if( pGraphic )
{
if(!bIgnoreGraphic)
{
m_aSymbolGraphic=*pGraphic;
}
if(!bIgnoreSize)
{
m_aSymbolSize=OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
pGraphic->GetPrefMapMode(),
MapMode(MapUnit::Map100thMM));
}
bPrevSym=true;
}
}
if(const SvxSizeItem* pSymbolSizeItem = rAttrs->GetItemIfSet(rAttrs->GetPool()->GetWhichIDFromSlotID(SID_ATTR_SYMBOLSIZE)))
{
m_aSymbolSize = pSymbolSizeItem->GetSize();
}
m_xGridIconSize->set_sensitive(bEnable);
if(bPrevSym)
{
SetMetricValue(*m_xSymbolWidthMF, m_aSymbolSize.Width(), m_ePoolUnit);
SetMetricValue(*m_xSymbolHeightMF, m_aSymbolSize.Height(),m_ePoolUnit);
m_aCtlPreview.SetSymbol(&m_aSymbolGraphic,m_aSymbolSize);
m_aSymbolLastSize=m_aSymbolSize;
}
// LineStyle
if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTYLE ) == SfxItemState::DEFAULT )
{
m_xLbLineStyle->set_sensitive(false);
}
else if( rAttrs->GetItemState( XATTR_LINESTYLE ) != SfxItemState::INVALID )
{
eXLS = rAttrs->Get( XATTR_LINESTYLE ).GetValue();
switch( eXLS )
{
case drawing::LineStyle_NONE:
m_xLbLineStyle->set_active(0);
break;
case drawing::LineStyle_SOLID:
m_xLbLineStyle->set_active(1);
break;
case drawing::LineStyle_DASH:
m_xLbLineStyle->set_active(-1);
m_xLbLineStyle->set_active_text(rAttrs->Get( XATTR_LINEDASH ).GetName());
break;
default:
break;
}
}
else
{
m_xLbLineStyle->set_active(-1);
}
// Line strength
if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEWIDTH ) == SfxItemState::DEFAULT )
{
m_xBoxWidth->set_sensitive(false);
m_xMtrLineWidth->set_sensitive(false);
}
else if( rAttrs->GetItemState( XATTR_LINEWIDTH ) != SfxItemState::INVALID )
{
SetMetricValue( *m_xMtrLineWidth, rAttrs->Get( XATTR_LINEWIDTH ).GetValue(), m_ePoolUnit );
}
else
m_xMtrLineWidth->set_text(u""_ustr);
// Line color
m_xLbColor->SetNoSelection();
if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINECOLOR ) == SfxItemState::DEFAULT )
{
m_xBoxColor->set_sensitive(false);
m_xLbColor->set_sensitive(false);
}
else if ( rAttrs->GetItemState( XATTR_LINECOLOR ) != SfxItemState::INVALID )
{
Color aCol = rAttrs->Get( XATTR_LINECOLOR ).GetColorValue();
m_xLbColor->SelectEntry( aCol );
}
// Line start
bool bArrowStylesActive(true);
if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTART ) == SfxItemState::DEFAULT )
{
m_xLbStartStyle->set_sensitive(false);
bArrowStylesActive = false;
}
else if( rAttrs->GetItemState( XATTR_LINESTART ) != SfxItemState::INVALID )
{
// #86265# select entry using list and polygon, not string
bool bSelected(false);
const basegfx::B2DPolyPolygon& rItemPolygon = rAttrs->Get(XATTR_LINESTART).GetLineStartValue();
for(tools::Long a(0);!bSelected && a < m_pLineEndList->Count(); a++)
{
const XLineEndEntry* pEntry = m_pLineEndList->GetLineEnd(a);
const basegfx::B2DPolyPolygon& rEntryPolygon = pEntry->GetLineEnd();
if(rItemPolygon == rEntryPolygon)
{
// select this entry
m_xLbStartStyle->set_active(a + 1);
bSelected = true;
}
}
if(!bSelected)
m_xLbStartStyle->set_active(0);
}
else
{
m_xLbStartStyle->set_active(-1);
}
// Line end
if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEEND ) == SfxItemState::DEFAULT )
{
m_xLbEndStyle->set_sensitive(false);
bArrowStylesActive = false;
}
else if( rAttrs->GetItemState( XATTR_LINEEND ) != SfxItemState::INVALID )
{
// #86265# select entry using list and polygon, not string
bool bSelected(false);
const basegfx::B2DPolyPolygon& rItemPolygon = rAttrs->Get(XATTR_LINEEND).GetLineEndValue();
for(tools::Long a(0);!bSelected && a < m_pLineEndList->Count(); a++)
{
const XLineEndEntry* pEntry = m_pLineEndList->GetLineEnd(a);
const basegfx::B2DPolyPolygon& rEntryPolygon = pEntry->GetLineEnd();
if(rItemPolygon == rEntryPolygon)
{
// select this entry
m_xLbEndStyle->set_active(a + 1);
bSelected = true;
}
}
if(!bSelected)
m_xLbEndStyle->set_active(0);
}
else
{
m_xLbEndStyle->set_active(-1);
}
// Line start strength
if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTARTWIDTH ) == SfxItemState::DEFAULT )
{
m_xBoxStart->set_sensitive(false);
m_xMtrStartWidth->set_sensitive(false);
}
else if( rAttrs->GetItemState( XATTR_LINESTARTWIDTH ) != SfxItemState::INVALID )
{
SetMetricValue( *m_xMtrStartWidth,
rAttrs->Get( XATTR_LINESTARTWIDTH ).GetValue(),
m_ePoolUnit );
}
else
m_xMtrStartWidth->set_text( u""_ustr );
// Line end strength
if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEENDWIDTH ) == SfxItemState::DEFAULT )
{
m_xBoxEnd->set_sensitive(false);
m_xMtrEndWidth->set_sensitive(false);
}
else if( rAttrs->GetItemState( XATTR_LINEENDWIDTH ) != SfxItemState::INVALID )
{
SetMetricValue( *m_xMtrEndWidth,
rAttrs->Get( XATTR_LINEENDWIDTH ).GetValue(),
m_ePoolUnit );
}
else
m_xMtrEndWidth->set_text(u""_ustr);
// Centered line end (start)
if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTARTCENTER ) == SfxItemState::DEFAULT )
{
m_xTsbCenterStart->set_sensitive(false);
}
else if( rAttrs->GetItemState( XATTR_LINESTARTCENTER ) != SfxItemState::INVALID )
{
if( rAttrs->Get( XATTR_LINESTARTCENTER ).GetValue() )
m_xTsbCenterStart->set_state(TRISTATE_TRUE);
else
m_xTsbCenterStart->set_state(TRISTATE_FALSE);
}
else
{
m_xTsbCenterStart->set_state(TRISTATE_INDET);
}
// Centered line end (end)
if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEENDCENTER ) == SfxItemState::DEFAULT )
{
m_xTsbCenterEnd->set_sensitive(false);
}
else if( rAttrs->GetItemState( XATTR_LINEENDCENTER ) != SfxItemState::INVALID )
{
if( rAttrs->Get( XATTR_LINEENDCENTER ).GetValue() )
m_xTsbCenterEnd->set_state(TRISTATE_TRUE);
else
m_xTsbCenterEnd->set_state(TRISTATE_FALSE);
}
else
{
m_xTsbCenterEnd->set_state(TRISTATE_INDET);
}
// Transparency
if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINETRANSPARENCE ) == SfxItemState::DEFAULT )
{
m_xBoxTransparency->set_sensitive(false);
m_xMtrTransparent->set_sensitive(false);
}
else if( rAttrs->GetItemState( XATTR_LINETRANSPARENCE ) != SfxItemState::INVALID )
{
sal_uInt16 nTransp = rAttrs->Get( XATTR_LINETRANSPARENCE ).GetValue();
m_xMtrTransparent->set_value(nTransp, FieldUnit::PERCENT);
ChangeTransparentHdl_Impl(*m_xMtrTransparent);
}
else
m_xMtrTransparent->set_text( u""_ustr );
if( !m_xLbStartStyle->get_sensitive() &&
!m_xLbEndStyle->get_sensitive() &&
!m_xMtrStartWidth->get_sensitive() &&
!m_xMtrEndWidth->get_sensitive() &&
!m_xTsbCenterStart->get_sensitive()&&
!m_xTsbCenterEnd->get_sensitive() )
{
m_xCbxSynchronize->set_sensitive(false);
m_xFlLineEnds->set_sensitive(false);
}
// Synchronize
// We get the value from the INI file now
OUString aStr = GetUserData();
m_xCbxSynchronize->set_active(aStr.toInt32() != 0);
if (!bArrowStylesActive)
{
m_xCbxSynchronize->set_sensitive(false);
}
if(m_bObjSelected && SfxItemState::DEFAULT == rAttrs->GetItemState(XATTR_LINEJOINT))
{
// maFTEdgeStyle.set_sensitive(false);
m_xLBEdgeStyle->set_sensitive(false);
}
else if(SfxItemState::INVALID != rAttrs->GetItemState(XATTR_LINEJOINT))
{
const css::drawing::LineJoint eLineJoint = rAttrs->Get(XATTR_LINEJOINT).GetValue();
switch(eLineJoint)
{
case css::drawing::LineJoint::LineJoint_MAKE_FIXED_SIZE: // fallback to round, unused value
case css::drawing::LineJoint_ROUND : m_xLBEdgeStyle->set_active(0); break;
case css::drawing::LineJoint_NONE : m_xLBEdgeStyle->set_active(1); break;
case css::drawing::LineJoint_MIDDLE : // fallback to mitre, unused value
case css::drawing::LineJoint_MITER : m_xLBEdgeStyle->set_active(2); break;
case css::drawing::LineJoint_BEVEL : m_xLBEdgeStyle->set_active(3); break;
}
}
else
{
m_xLBEdgeStyle->set_active(-1);
}
// fdo#43209
if(m_bObjSelected && SfxItemState::DEFAULT == rAttrs->GetItemState(XATTR_LINECAP))
{
m_xLBCapStyle->set_sensitive(false);
}
else if(SfxItemState::INVALID != rAttrs->GetItemState(XATTR_LINECAP))
{
const css::drawing::LineCap eLineCap(rAttrs->Get(XATTR_LINECAP).GetValue());
switch(eLineCap)
{
case css::drawing::LineCap_ROUND: m_xLBCapStyle->set_active(1); break;
case css::drawing::LineCap_SQUARE : m_xLBCapStyle->set_active(2); break;
default /*css::drawing::LineCap_BUTT*/: m_xLBCapStyle->set_active(0); break;
}
}
else
{
m_xLBCapStyle->set_active(-1);
}
// Save values
m_xLbLineStyle->save_value();
m_xMtrLineWidth->save_value();
m_xLbColor->SaveValue();
m_xLbStartStyle->save_value();
m_xLbEndStyle->save_value();
m_xMtrStartWidth->save_value();
m_xMtrEndWidth->save_value();
m_xTsbCenterStart->save_state();
m_xTsbCenterEnd->save_state();
m_xMtrTransparent->save_value();
m_xLBEdgeStyle->save_value();
// LineCaps
m_xLBCapStyle->save_value();
ClickInvisibleHdl_Impl();
ChangePreviewHdl_Impl( nullptr );
}
std::unique_ptr<SfxTabPage> SvxLineTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
const SfxItemSet* rAttrs)
{
return std::make_unique<SvxLineTabPage>(pPage, pController, *rAttrs);
}
IMPL_LINK_NOARG(SvxLineTabPage, ChangePreviewListBoxHdl_Impl, ColorListBox&, void)
{
ChangePreviewHdl_Impl(nullptr);
}
IMPL_LINK(SvxLineTabPage, ChangePreviewModifyHdl_Impl, weld::MetricSpinButton&, rEdit, void)
{
ChangePreviewHdl_Impl(&rEdit);
}
void SvxLineTabPage::ChangePreviewHdl_Impl(const weld::MetricSpinButton* pCntrl)
{
if (pCntrl == m_xMtrLineWidth.get())
{
// Line width and start end width
sal_Int32 nNewLineWidth = GetCoreValue( *m_xMtrLineWidth, m_ePoolUnit );
if(m_nActLineWidth == -1)
{
// Don't initialize yet, get the start value
const SfxPoolItem* pOld = GetOldItem( m_aLineAttributeSet, XATTR_LINEWIDTH );
sal_Int32 nStartLineWidth = 0;
if(pOld)
nStartLineWidth = static_cast<const XLineWidthItem *>(pOld)->GetValue();
m_nActLineWidth = nStartLineWidth;
}
if(m_nActLineWidth != nNewLineWidth)
{
// Adapt start/end width
sal_Int32 nValAct = GetCoreValue( *m_xMtrStartWidth, m_ePoolUnit );
sal_Int32 nValNew = nValAct + (((nNewLineWidth - m_nActLineWidth) * 15) / 10);
if(nValNew < 0)
nValNew = 0;
SetMetricValue( *m_xMtrStartWidth, nValNew, m_ePoolUnit );
nValAct = GetCoreValue( *m_xMtrEndWidth, m_ePoolUnit );
nValNew = nValAct + (((nNewLineWidth - m_nActLineWidth) * 15) / 10);
if(nValNew < 0)
nValNew = 0;
SetMetricValue( *m_xMtrEndWidth, nValNew, m_ePoolUnit );
}
// Remember current value
m_nActLineWidth = nNewLineWidth;
}
FillXLSet_Impl();
m_aCtlPreview.Invalidate();
// Make transparency accessible accordingly
if( m_xLbLineStyle->get_active() == 0 ) // invisible
{
m_xBoxTransparency->set_sensitive(false);
}
else
{
m_xBoxTransparency->set_sensitive(true);
}
const bool bHasLineStyle = m_xLbLineStyle->get_active() !=0;
const bool bHasLineStart = m_xLbStartStyle->get_active() != 0;
m_xBoxStart->set_sensitive(bHasLineStart && bHasLineStyle);
const bool bHasLineEnd = m_xLbEndStyle->get_active() != 0;
m_xBoxEnd->set_sensitive(bHasLineEnd && bHasLineStyle);
}
IMPL_LINK_NOARG(SvxLineTabPage, ChangeStartClickHdl_Impl, weld::Toggleable&, void)
{
if (m_xCbxSynchronize->get_active())
m_xTsbCenterEnd->set_state(m_xTsbCenterStart->get_state());
ChangePreviewHdl_Impl(nullptr);
}
IMPL_LINK_NOARG(SvxLineTabPage, ChangeStartListBoxHdl_Impl, weld::ComboBox&, void)
{
if (m_xCbxSynchronize->get_active())
m_xLbEndStyle->set_active(m_xLbStartStyle->get_active());
ChangePreviewHdl_Impl(nullptr);
}
IMPL_LINK_NOARG(SvxLineTabPage, ChangeStartModifyHdl_Impl, weld::MetricSpinButton&, void)
{
if (m_xCbxSynchronize->get_active())
m_xMtrEndWidth->set_value(m_xMtrStartWidth->get_value(FieldUnit::NONE), FieldUnit::NONE);
ChangePreviewHdl_Impl(nullptr);
}
IMPL_LINK_NOARG(SvxLineTabPage, ChangeEdgeStyleHdl_Impl, weld::ComboBox&, void)
{
ChangePreviewHdl_Impl( nullptr );
}
// fdo#43209
IMPL_LINK_NOARG(SvxLineTabPage, ChangeCapStyleHdl_Impl, weld::ComboBox&, void)
{
ChangePreviewHdl_Impl( nullptr );
}
IMPL_LINK_NOARG(SvxLineTabPage, ClickInvisibleHdl_Impl, weld::ComboBox&, void)
{
ClickInvisibleHdl_Impl();
}
void SvxLineTabPage::ClickInvisibleHdl_Impl()
{
if( m_xLbLineStyle->get_active() == 0 ) // invisible
{
if(!m_bSymbols)
m_xBoxColor->set_sensitive(false);
m_xBoxWidth->set_sensitive(false);
if( m_xFlLineEnds->get_sensitive() )
{
m_xBoxStart->set_sensitive(false);
m_xBoxArrowStyles->set_sensitive(false);
m_xGridEdgeCaps->set_sensitive(false);
}
}
else
{
// set cap style associated to the line style
sal_Int32 nPos = m_xLbLineStyle->get_active();
if( nPos > 1 && m_pDashList->Count() > static_cast<tools::Long>( nPos - 2 ) )
{
css::drawing::DashStyle eStyle =
m_pDashList->GetDash( nPos - 2 )->GetDash().GetDashStyle();
if ( eStyle == drawing::DashStyle_RECT || eStyle == drawing::DashStyle_RECTRELATIVE)
m_xLBCapStyle->set_active(0);
else
m_xLBCapStyle->set_active(1);
}
m_xBoxColor->set_sensitive(true);
m_xBoxWidth->set_sensitive(true);
if (m_xFlLineEnds->get_sensitive())
{
m_xBoxArrowStyles->set_sensitive(true);
m_xGridEdgeCaps->set_sensitive(true);
}
}
ChangePreviewHdl_Impl( nullptr );
}
IMPL_LINK_NOARG(SvxLineTabPage, ChangeEndClickHdl_Impl, weld::Toggleable&, void)
{
if (m_xCbxSynchronize->get_active())
m_xTsbCenterStart->set_state(m_xTsbCenterEnd->get_state());
ChangePreviewHdl_Impl(nullptr);
}
IMPL_LINK_NOARG(SvxLineTabPage, ChangeEndListBoxHdl_Impl, weld::ComboBox&, void)
{
if (m_xCbxSynchronize->get_active())
m_xLbStartStyle->set_active(m_xLbEndStyle->get_active());
ChangePreviewHdl_Impl(nullptr);
}
IMPL_LINK_NOARG(SvxLineTabPage, ChangeEndModifyHdl_Impl, weld::MetricSpinButton&, void)
{
if (m_xCbxSynchronize->get_active())
m_xMtrStartWidth->set_value(m_xMtrEndWidth->get_value(FieldUnit::NONE), FieldUnit::NONE);
ChangePreviewHdl_Impl(nullptr);
}
IMPL_LINK_NOARG(SvxLineTabPage, ChangeTransparentHdl_Impl, weld::MetricSpinButton&, void)
{
sal_uInt16 nVal = o3tl::sanitizing_cast<sal_uInt16>(m_xMtrTransparent->get_value(FieldUnit::PERCENT));
m_aLineAttributeSet.Put(XLineTransparenceItem(nVal));
FillXLSet_Impl();
m_aCtlPreview.Invalidate();
}
void SvxLineTabPage::FillUserData()
{
// Write the synched value to the INI file
OUString aStrUserData = OUString::boolean(m_xCbxSynchronize->get_active());
SetUserData( aStrUserData );
}
// #58425# Symbols on a list (e.g. StarChart)
void SvxLineTabPage::PopulateMenus()
{
ScopedVclPtrInstance< VirtualDevice > pVD;
// Initialize popup
if (!m_xGalleryMenu)
{
m_xGalleryMenu = m_xBuilder->weld_menu(u"gallerysubmenu"_ustr);
weld::WaitObject aWait(GetFrameWeld());
// Get gallery entries
GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, m_aGrfNames);
sal_uInt32 i = 0;
for (auto const& grfName : m_aGrfNames)
{
const OUString *pUIName = &grfName;
// Convert URL encodings to UI characters (e.g. %20 for spaces)
OUString aPhysicalName;
if (osl::FileBase::getSystemPathFromFileURL(grfName, aPhysicalName)
== osl::FileBase::E_None)
{
pUIName = &aPhysicalName;
}
SvxBmpItemInfo* pInfo = new SvxBmpItemInfo;
pInfo->pBrushItem.reset(new SvxBrushItem(grfName, u""_ustr, GPOS_AREA, SID_ATTR_BRUSH));
pInfo->sItemId = "gallery" + OUString::number(i);
m_aGalleryBrushItems.emplace_back(pInfo);
const Graphic* pGraphic = pInfo->pBrushItem->GetGraphic();
if(pGraphic)
{
Bitmap aBitmap(pGraphic->GetBitmap());
Size aSize(aBitmap.GetSizePixel());
if(aSize.Width() > MAX_BMP_WIDTH || aSize.Height() > MAX_BMP_HEIGHT)
{
bool bWidth = aSize.Width() > aSize.Height();
double nScale = bWidth ?
double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()):
double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
aBitmap.Scale(nScale, nScale);
}
pVD->SetOutputSizePixel(aBitmap.GetSizePixel());
pVD->DrawBitmap(Point(), aBitmap);
m_xGalleryMenu->append(pInfo->sItemId, *pUIName, *pVD);
}
else
{
m_xGalleryMenu->append(pInfo->sItemId, *pUIName);
}
++i;
}
if (m_aGrfNames.empty())
m_xSymbolMB->set_item_sensitive(u"gallery"_ustr, false);
}
if (m_xSymbolsMenu || !m_pSymbolList)
return;
m_xSymbolsMenu = m_xBuilder->weld_menu(u"symbolssubmenu"_ustr);
ScopedVclPtrInstance< VirtualDevice > pVDev;
pVDev->SetMapMode(MapMode(MapUnit::Map100thMM));
std::unique_ptr<SdrModel> pModel(
new SdrModel(nullptr, nullptr, true));
// Page
rtl::Reference<SdrPage> pPage = new SdrPage( *pModel, false );
pPage->SetSize(Size(1000,1000));
pModel->InsertPage( pPage.get(), 0 );
{
// 3D View
SdrView aView( *pModel, pVDev );
aView.hideMarkHandles();
aView.ShowSdrPage(pPage.get());
// Generate invisible square to give all symbols a
// bitmap size, which is independent from specific glyph
rtl::Reference<SdrObject> pInvisibleSquare=m_pSymbolList->GetObj(0);
// directly clone to target SdrModel
pInvisibleSquare = pInvisibleSquare->CloneSdrObject(*pModel);
pPage->NbcInsertObject(pInvisibleSquare.get());
pInvisibleSquare->SetMergedItem(XFillTransparenceItem(100));
pInvisibleSquare->SetMergedItem(XLineTransparenceItem(100));
for(size_t i=0; i < m_pSymbolList->GetObjCount(); ++i)
{
rtl::Reference<SdrObject> pObj=m_pSymbolList->GetObj(i);
assert(pObj);
// directly clone to target SdrModel
pObj = pObj->CloneSdrObject(*pModel);
m_aGrfNames.emplace_back("");
pPage->NbcInsertObject(pObj.get());
if(m_xSymbolAttr)
{
pObj->SetMergedItemSet(*m_xSymbolAttr);
}
else
{
pObj->SetMergedItemSet(m_rOutAttrs);
}
aView.MarkAll();
Bitmap aBitmap(aView.GetMarkedObjBitmap());
GDIMetaFile aMeta(aView.GetMarkedObjMetaFile());
aView.UnmarkAll();
pPage->RemoveObject(1);
pObj.clear();
SvxBmpItemInfo* pInfo = new SvxBmpItemInfo;
pInfo->pBrushItem.reset(new SvxBrushItem(Graphic(aMeta), GPOS_AREA, SID_ATTR_BRUSH));
pInfo->sItemId = "symbol" + OUString::number(i);
m_aSymbolBrushItems.emplace_back(pInfo);
Size aSize(aBitmap.GetSizePixel());
if(aSize.Width() > MAX_BMP_WIDTH || aSize.Height() > MAX_BMP_HEIGHT)
{
bool bWidth = aSize.Width() > aSize.Height();
double nScale = bWidth ?
double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()):
double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
aBitmap.Scale(nScale, nScale);
}
pVD->SetOutputSizePixel(aBitmap.GetSizePixel());
pVD->DrawBitmap(Point(), aBitmap);
m_xSymbolsMenu->append(pInfo->sItemId, u""_ustr, *pVD);
}
pPage->RemoveObject(0);
pInvisibleSquare.clear();
if (m_aGrfNames.empty())
m_xSymbolMB->set_item_sensitive(u"symbols"_ustr, false);
}
}
// #58425# Symbols on a list (e.g. StarChart)
// Handler for menu button
IMPL_LINK(SvxLineTabPage, GraphicHdl_Impl, const OUString&, rIdent, void)
{
const Graphic* pGraphic = nullptr;
Graphic aGraphic;
bool bResetSize = false;
bool bEnable = true;
tools::Long nPreviousSymbolType = m_nSymbolType;
std::u16string_view sNumber;
if (rIdent.startsWith("gallery", &sNumber))
{
SvxBmpItemInfo* pInfo = m_aGalleryBrushItems[o3tl::toUInt32(sNumber)].get();
pGraphic = pInfo->pBrushItem->GetGraphic();
m_nSymbolType = SVX_SYMBOLTYPE_BRUSHITEM;
}
else if (rIdent.startsWith("symbol", &sNumber))
{
m_nSymbolType = o3tl::toUInt32(sNumber);
SvxBmpItemInfo* pInfo = m_aSymbolBrushItems[m_nSymbolType].get();
pGraphic = pInfo->pBrushItem->GetGraphic();
}
else if (rIdent == "automatic")
{
pGraphic=&m_aAutoSymbolGraphic;
m_aAutoSymbolGraphic.SetPrefSize( Size(253,253) );
m_nSymbolType=SVX_SYMBOLTYPE_AUTO;
}
else if (rIdent == "none")
{
m_nSymbolType=SVX_SYMBOLTYPE_NONE;
pGraphic=nullptr;
bEnable = false;
}
else if (rIdent == "file")
{
SvxOpenGraphicDialog aGrfDlg(CuiResId(RID_CUISTR_EDIT_GRAPHIC), GetFrameWeld());
aGrfDlg.EnableLink(false);
aGrfDlg.AsLink(false);
if( !aGrfDlg.Execute() )
{
// Remember selected filters
if( !aGrfDlg.GetGraphic(aGraphic) )
{
m_nSymbolType=SVX_SYMBOLTYPE_BRUSHITEM;
pGraphic = &aGraphic;
bResetSize = true;
}
}
if( !pGraphic )
return;
}
if (pGraphic)
{
Size aSize = SvxNumberFormat::GetGraphicSizeMM100(pGraphic);
aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(m_ePoolUnit));
m_aSymbolGraphic=*pGraphic;
if( bResetSize )
{
m_aSymbolSize=aSize;
}
else if( nPreviousSymbolType == SVX_SYMBOLTYPE_BRUSHITEM )
{ //#i31097# Data Point Symbol size changes when a different symbol is chosen(maoyg)
if( m_aSymbolSize.Width() != m_aSymbolSize.Height() )
{
aSize.setWidth( static_cast<tools::Long>( m_aSymbolSize.Width() + m_aSymbolSize.Height() )/2 );
aSize.setHeight( static_cast<tools::Long>( m_aSymbolSize.Width() + m_aSymbolSize.Height() )/2 );
m_aSymbolSize = aSize;
}
}
m_aCtlPreview.SetSymbol(&m_aSymbolGraphic,m_aSymbolSize);
}
else
{
m_aSymbolGraphic=Graphic();
m_aCtlPreview.SetSymbol(nullptr,m_aSymbolSize);
bEnable = false;
}
m_aSymbolLastSize=m_aSymbolSize;
SetMetricValue(*m_xSymbolWidthMF, m_aSymbolSize.Width(), m_ePoolUnit);
SetMetricValue(*m_xSymbolHeightMF, m_aSymbolSize.Height(), m_ePoolUnit);
m_xGridIconSize->set_sensitive(bEnable);
m_aCtlPreview.Invalidate();
}
IMPL_LINK( SvxLineTabPage, SizeHdl_Impl, weld::MetricSpinButton&, rField, void)
{
m_bNewSize = true;
bool bWidth = &rField == m_xSymbolWidthMF.get();
m_bLastWidthModified = bWidth;
bool bRatio = m_xSymbolRatioCB->get_active();
tools::Long nWidthVal = static_cast<tools::Long>(m_xSymbolWidthMF->denormalize(m_xSymbolWidthMF->get_value(FieldUnit::MM_100TH)));
tools::Long nHeightVal= static_cast<tools::Long>(m_xSymbolHeightMF->denormalize(m_xSymbolHeightMF->get_value(FieldUnit::MM_100TH)));
nWidthVal = OutputDevice::LogicToLogic(nWidthVal,MapUnit::Map100thMM, m_ePoolUnit );
nHeightVal = OutputDevice::LogicToLogic(nHeightVal,MapUnit::Map100thMM, m_ePoolUnit);
m_aSymbolSize = Size(nWidthVal,nHeightVal);
double fSizeRatio = double(1);
if(bRatio)
{
if (m_aSymbolLastSize.Height() && m_aSymbolLastSize.Width())
fSizeRatio = static_cast<double>(m_aSymbolLastSize.Width()) / m_aSymbolLastSize.Height();
}
if (bWidth)
{
tools::Long nDelta = nWidthVal - m_aSymbolLastSize.Width();
m_aSymbolSize.setWidth( nWidthVal );
if (bRatio)
{
m_aSymbolSize.setHeight( m_aSymbolLastSize.Height() + static_cast<tools::Long>(static_cast<double>(nDelta) / fSizeRatio) );
m_aSymbolSize.setHeight( OutputDevice::LogicToLogic( m_aSymbolSize.Height(), m_ePoolUnit, MapUnit::Map100thMM ) );
//TODO m_xSymbolHeightMF->SetUserValue(m_xSymbolHeightMF->normalize(m_aSymbolSize.Height()), FieldUnit::MM_100TH);
m_xSymbolHeightMF->set_value(m_xSymbolHeightMF->normalize(m_aSymbolSize.Height()), FieldUnit::MM_100TH);
}
}
else
{
tools::Long nDelta = nHeightVal - m_aSymbolLastSize.Height();
m_aSymbolSize.setHeight( nHeightVal );
if (bRatio)
{
m_aSymbolSize.setWidth( m_aSymbolLastSize.Width() + static_cast<tools::Long>(static_cast<double>(nDelta) * fSizeRatio) );
m_aSymbolSize.setWidth( OutputDevice::LogicToLogic( m_aSymbolSize.Width(), m_ePoolUnit, MapUnit::Map100thMM ) );
//TODO m_xSymbolWidthMF->SetUserValue(m_xSymbolWidthMF->normalize(m_aSymbolSize.Width()), FieldUnit::MM_100TH);
m_xSymbolWidthMF->set_value(m_xSymbolWidthMF->normalize(m_aSymbolSize.Width()), FieldUnit::MM_100TH);
}
}
m_aCtlPreview.ResizeSymbol(m_aSymbolSize);
m_aSymbolLastSize=m_aSymbolSize;
}
IMPL_LINK(SvxLineTabPage, RatioHdl_Impl, weld::Toggleable&, rBox, void)
{
if (rBox.get_active())
{
if (m_bLastWidthModified)
SizeHdl_Impl(*m_xSymbolWidthMF);
else
SizeHdl_Impl(*m_xSymbolHeightMF);
}
}
void SvxLineTabPage::PageCreated(const SfxAllItemSet& aSet)
{
const SvxDashListItem* pDashListItem = aSet.GetItem<SvxDashListItem>(SID_DASH_LIST, false);
const SvxLineEndListItem* pLineEndListItem = aSet.GetItem<SvxLineEndListItem>(SID_LINEEND_LIST, false);
const SfxUInt16Item* pPageTypeItem = aSet.GetItem<SfxUInt16Item>(SID_PAGE_TYPE, false);
const SfxUInt16Item* pDlgTypeItem = aSet.GetItem<SfxUInt16Item>(SID_DLG_TYPE, false);
const OfaPtrItem* pSdrObjListItem = aSet.GetItem<OfaPtrItem>(SID_OBJECT_LIST, false);
const SfxTabDialogItem* pSymbolAttrItem = aSet.GetItem<SfxTabDialogItem>(SID_ATTR_SET, false);
const SvxGraphicItem* pGraphicItem = aSet.GetItem<SvxGraphicItem>(SID_GRAPHIC, false);
if (pDashListItem)
SetDashList(pDashListItem->GetDashList());
if (pLineEndListItem)
SetLineEndList(pLineEndListItem->GetLineEndList());
if (pPageTypeItem)
SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
if (pDlgTypeItem)
SetDlgType(pDlgTypeItem->GetValue());
if(pSdrObjListItem) //symbols
{
ShowSymbolControls(true);
m_pSymbolList = static_cast<SdrObjList*>(pSdrObjListItem->GetValue());
if (pSymbolAttrItem)
m_xSymbolAttr.reset(new SfxItemSet(pSymbolAttrItem->GetItemSet()));
if(pGraphicItem)
m_aAutoSymbolGraphic = pGraphicItem->GetGraphic();
}
Construct();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */