office-gobmx/sw/inc/autostyle_helper.hxx

32 lines
942 B
C++
Raw Normal View History

tdf#141969: use paragraph autostyle to mimic Word's table style Word's table styles may define paragraph and character properties. They are handled in DomainMapperTableHandler::ApplyParagraphPropertiesFromTableStyle. When setting such a character property using setPropertyValue, it may apply to the text runs inside the paragraph, overriding values from character style and direct formatting, which must be kept. To fix that, this change creates a *paragraph* autostyle first, containing the properties; and then applies only this autostyle to the paragraph; the autostyle can't apply to runs, so the properties apply at paragraph level. Sadly, it is impossible to create a useful autostyle in writerfilter using UNO, because of the same problem that caused tdf#155945. UNO properties may define only parts of complex SfxPoolItem; setting them without having already applied values of such SfxPoolItem's would create wrong values for properties that weren't set by the UNO properties, but happen to share the same SfxPoolItem. To workaround that in writerfilter, a map of UNO names to sets of UNO names defining the complex property would be required, and then maintained. Instead, introduce a hidded 'ParaAutoStyleDef' property of SwXTextCursor, taking the same PropertyValue sequence as in XAutoStyleFamily::insertStyle. Implement it similarly to SwUnoCursorHelper::SetPropertyValues: first, build a WhichRangesContainer for specific WIDs needed for the properties; then obtain the actual values for these WIDs from the paragraph; and then set properties from the PropertyValue sequence. To create the autostyle properly, the code from SwXAutoStyleFamily::insertStyle is reused. There are more "proper" ways to fix this in part or as a whole, e.g.: * Split all complex SfxPoolItem's to simple ones, as done for one of them in commit db115bec9254417ef7a3faf687478fe5424ab378 (tdf#78510 sw,cui: split SvxLRSpaceItem for SwTextNode, SwTextFormatColl, 2023-02-24); * Rewrite writerfilter in sw; * Implement the missing proper table styles with paragraph and character properties, having the same precedence. But I don't feel crazy enough for any of these :D Change-Id: I07142cb23e8ec51f0e8ac8609f367ba247d94438 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153947 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
2023-07-04 00:14:02 -05:00
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* 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/.
*/
#pragma once
#include <sal/config.h>
#include <memory>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/uno/Sequence.hxx>
#include <svl/itemset.hxx>
#include "istyleaccess.hxx"
#include "swatrset.hxx"
class SwDoc;
std::shared_ptr<SfxItemSet>
PropValuesToAutoStyleItemSet(SwDoc& rDoc, IStyleAccess::SwAutoStyleFamily eFamily,
const css::uno::Sequence<css::beans::PropertyValue>& Values,
Related: tdf#141969 Make sure to use SwAttrSet for paragraph autostyles See https://gerrit.libreoffice.org/c/core/+/153947/8#message-45a748bf68235bf143bec07cda2d704abb2b140f > This started to cause e.g. CppunitTest_sw_rtfexport3 to fail with > /sw/inc/node.hxx:493:53: runtime error: downcast of address 0x606000617540 which does not point to an object of type 'const SwAttrSet' > 0x606000617540: note: object is of type 'SfxItemSet' > 00 00 00 00 30 15 0f a9 a6 7f 00 00 50 6a 4a 01 40 60 00 00 c8 98 0f 00 30 61 00 00 80 30 6c 00 > ^~~~~~~~~~~~~~~~~~~~~~~ > vptr for 'SfxItemSet' > #0 0x7fa671d1b765 in SwContentNode::GetpSwAttrSet() const /sw/inc/node.hxx:493:53 > #1 0x7fa671d7159e in SwContentNode::GetSwAttrSet() const /sw/inc/node.hxx:729:25 > #2 0x7fa673be6c4a in SwDoc::TextToTable(std::__debug::vector<std::__debug::vector<SwNodeRange, std::allocator<SwNodeRange> >, std::allocator<std::__debug::vector<SwNodeRange, std::allocator<SwNodeRange> > > > const&) /sw/source/core/docnode/ndtbl.cxx:1236:51 > #3 0x7fa6775f46a5 in SwXText::convertToTable(com::sun::star::uno::Sequence<com::sun::star::uno::Sequence<com::sun::star::uno::Sequence<com::sun::star::uno::Reference<com::sun::star::text::XTextRange> > > > const&, com::sun::star::uno::Sequence<com::sun::star::uno::Sequence<com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> > > const&, com::sun::star::uno::Sequence<com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> > const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&) /sw/source/core/unocore/unotext.cxx:2279:51 > #4 0x7fa6775fba56 in non-virtual thunk to SwXText::convertToTable(com::sun::star::uno::Sequence<com::sun::star::uno::Sequence<com::sun::star::uno::Sequence<com::sun::star::uno::Reference<com::sun::star::text::XTextRange> > > > const&, com::sun::star::uno::Sequence<com::sun::star::uno::Sequence<com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> > > const&, com::sun::star::uno::Sequence<com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> > const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&) /sw/source/core/unocore/unotext.cxx > #5 0x7fa61c596a81 in writerfilter::dmapper::DomainMapperTableHandler::endTable(unsigned int, bool) /writerfilter/source/dmapper/DomainMapperTableHandler.cxx:1481:35 > #6 0x7fa61cf2fdee in writerfilter::dmapper::TableManager::resolveCurrentTable() /writerfilter/source/dmapper/TableManager.cxx:409:33 > #7 0x7fa61cf30bb1 in writerfilter::dmapper::TableManager::endLevel() /writerfilter/source/dmapper/TableManager.cxx:427:9 > #8 0x7fa61c642f37 in writerfilter::dmapper::DomainMapperTableManager::endLevel() /writerfilter/source/dmapper/DomainMapperTableManager.cxx:496:19 > #9 0x7fa61cf2cae1 in writerfilter::dmapper::TableManager::endParagraphGroup() /writerfilter/source/dmapper/TableManager.cxx:338:9 > (<https://ci.libreoffice.org//job/lo_ubsan/2836/>) Regression after commit b036e563e699595fa7625888f11ab0c76f1abd66 (tdf#141969: use paragraph autostyle to mimic Word's table style, 2023-07-04). Change-Id: Idc905cdea35bd0c5f3cfbd562d63894f44e64446 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154106 Tested-by: Mike Kaganski <mike.kaganski@collabora.com> Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
2023-07-06 06:04:12 -05:00
SwAttrSet& rSet);
tdf#141969: use paragraph autostyle to mimic Word's table style Word's table styles may define paragraph and character properties. They are handled in DomainMapperTableHandler::ApplyParagraphPropertiesFromTableStyle. When setting such a character property using setPropertyValue, it may apply to the text runs inside the paragraph, overriding values from character style and direct formatting, which must be kept. To fix that, this change creates a *paragraph* autostyle first, containing the properties; and then applies only this autostyle to the paragraph; the autostyle can't apply to runs, so the properties apply at paragraph level. Sadly, it is impossible to create a useful autostyle in writerfilter using UNO, because of the same problem that caused tdf#155945. UNO properties may define only parts of complex SfxPoolItem; setting them without having already applied values of such SfxPoolItem's would create wrong values for properties that weren't set by the UNO properties, but happen to share the same SfxPoolItem. To workaround that in writerfilter, a map of UNO names to sets of UNO names defining the complex property would be required, and then maintained. Instead, introduce a hidded 'ParaAutoStyleDef' property of SwXTextCursor, taking the same PropertyValue sequence as in XAutoStyleFamily::insertStyle. Implement it similarly to SwUnoCursorHelper::SetPropertyValues: first, build a WhichRangesContainer for specific WIDs needed for the properties; then obtain the actual values for these WIDs from the paragraph; and then set properties from the PropertyValue sequence. To create the autostyle properly, the code from SwXAutoStyleFamily::insertStyle is reused. There are more "proper" ways to fix this in part or as a whole, e.g.: * Split all complex SfxPoolItem's to simple ones, as done for one of them in commit db115bec9254417ef7a3faf687478fe5424ab378 (tdf#78510 sw,cui: split SvxLRSpaceItem for SwTextNode, SwTextFormatColl, 2023-02-24); * Rewrite writerfilter in sw; * Implement the missing proper table styles with paragraph and character properties, having the same precedence. But I don't feel crazy enough for any of these :D Change-Id: I07142cb23e8ec51f0e8ac8609f367ba247d94438 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153947 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
2023-07-04 00:14:02 -05:00
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */