[Libreoffice-commits] core.git: sw/source
Mike Kaganski (via logerrit)
logerrit at kemper.freedesktop.org
Sat Aug 1 16:50:54 UTC 2020
sw/source/ui/vba/vbalistformat.cxx | 173 ++++++++++++++++++++++++++++++++++++-
1 file changed, 172 insertions(+), 1 deletion(-)
New commits:
commit dc5d8d39e229b2fb1091c179942e6dae9d160101
Author: Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Fri Jul 31 11:01:32 2020 +0300
Commit: Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Sat Aug 1 18:50:11 2020 +0200
Implement VBA's ListFormat.ConvertNumbersToText
This only handles lists with PositionAndSpaceMode::LABEL_ALIGNMENT.
TODO: handle PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION.
TODO: handle NumberingType::BITMAP.
It doesn't align number according to Adjust, since that requires to
use a tab stop at the number position with appropriate alignment, and
it's unclear how would that interact with LabelFollowedBy modes other
than LISTTAB.
When first tab stop position is greater than ParaLeftMargin, Writer
uses left margin as implicit tab stop position, thus in this case
list appearance is different from processed text appearance.
In case of justified paragraphs, space after number (which does not
participate in justification when part of numbering) becomes part
of justification after conversion to text.
Change-Id: I88ad6617f8a09307ecad9d28edee92a59c68a4d4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99939
Tested-by: Mike Kaganski <mike.kaganski at collabora.com>
Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
diff --git a/sw/source/ui/vba/vbalistformat.cxx b/sw/source/ui/vba/vbalistformat.cxx
index 9ad18ebfcf33..d8642cb7fab0 100644
--- a/sw/source/ui/vba/vbalistformat.cxx
+++ b/sw/source/ui/vba/vbalistformat.cxx
@@ -20,11 +20,23 @@
#include <vbahelper/vbahelper.hxx>
#include <ooo/vba/word/WdListApplyTo.hpp>
#include <ooo/vba/word/WdDefaultListBehavior.hpp>
+#include <com/sun/star/awt/FontDescriptor.hpp>
#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/document/XUndoManagerSupplier.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/style/TabStop.hpp>
+#include <com/sun/star/text/PositionAndSpaceMode.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <comphelper/sequence.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/scopeguard.hxx>
+#include <editeng/numitem.hxx>
#include "vbalisttemplate.hxx"
+#include <vector>
+
using namespace ::ooo::vba;
using namespace ::com::sun::star;
@@ -88,7 +100,166 @@ void SAL_CALL SwVbaListFormat::ApplyListTemplate( const css::uno::Reference< wor
void SAL_CALL SwVbaListFormat::ConvertNumbersToText( )
{
- throw uno::RuntimeException("Not implemented" );
+ css::uno::Reference<css::frame::XModel> xModel(getThisWordDoc(mxContext));
+ css::uno::Reference<css::document::XUndoManagerSupplier> xUndoSupplier(
+ xModel, css::uno::UNO_QUERY_THROW);
+ css::uno::Reference<css::document::XUndoManager> xUndoManager(xUndoSupplier->getUndoManager());
+ xUndoManager->enterUndoContext("ConvertNumbersToText");
+ xModel->lockControllers();
+ comphelper::ScopeGuard g([xModel, xUndoManager]() {
+ xModel->unlockControllers();
+ xUndoManager->leaveUndoContext();
+ });
+
+ css::uno::Reference<css::container::XEnumerationAccess> xEnumAccess(mxTextRange,
+ css::uno::UNO_QUERY_THROW);
+ auto xEnum = xEnumAccess->createEnumeration();
+ if (!xEnum->hasMoreElements())
+ return;
+
+ std::vector<css::uno::Reference<css::beans::XPropertySet>> aParagraphs;
+ while (xEnum->hasMoreElements())
+ aParagraphs.emplace_back(xEnum->nextElement(), css::uno::UNO_QUERY_THROW);
+
+ // in reverse order, to get proper label strings
+ for (auto it = aParagraphs.rbegin(); it != aParagraphs.rend(); ++it)
+ {
+ if (bool bNumber; ((*it)->getPropertyValue("NumberingIsNumber") >>= bNumber) && bNumber)
+ {
+ css::uno::Reference<css::text::XTextRange> xRange(*it, css::uno::UNO_QUERY_THROW);
+ OUString sLabelString;
+ (*it)->getPropertyValue("ListLabelString") >>= sLabelString;
+ // sal_Int16 nAdjust = SAL_MAX_INT16; // TODO?
+ sal_Int16 nNumberingType = SAL_MAX_INT16; // css::style::NumberingType
+ sal_Int16 nPositionAndSpaceMode = SAL_MAX_INT16;
+ sal_Int16 nLabelFollowedBy = SAL_MAX_INT16;
+ sal_Int32 nListtabStopPosition = SAL_MAX_INT32;
+ sal_Int32 nFirstLineIndent = SAL_MAX_INT32;
+ sal_Int32 nIndentAt = SAL_MAX_INT32;
+ OUString sCharStyleName, sBulletChar;
+ css::awt::FontDescriptor aBulletFont;
+ bool bHasFont;
+ css::util::Color aBulletColor = css::util::Color(COL_AUTO);
+ bool bHasColor;
+
+ {
+ sal_uInt16 nLevel = SAL_MAX_UINT16;
+ (*it)->getPropertyValue("NumberingLevel") >>= nLevel;
+ css::uno::Reference<css::container::XIndexAccess> xNumberingRules;
+ (*it)->getPropertyValue("NumberingRules") >>= xNumberingRules;
+ comphelper::SequenceAsHashMap aLevelRule(xNumberingRules->getByIndex(nLevel));
+
+ // See offapi/com/sun/star/text/NumberingLevel.idl
+ aLevelRule["CharStyleName"] >>= sCharStyleName;
+ aLevelRule["NumberingType"] >>= nNumberingType;
+ // TODO: aLevelRule["Adjust"] >>= nAdjust; // HoriOrientation::LEFT/RIGHT/CENTER
+ aLevelRule["PositionAndSpaceMode"] >>= nPositionAndSpaceMode;
+ aLevelRule["LabelFollowedBy"] >>= nLabelFollowedBy;
+ aLevelRule["ListtabStopPosition"] >>= nListtabStopPosition;
+ aLevelRule["FirstLineIndent"] >>= nFirstLineIndent;
+ aLevelRule["IndentAt"] >>= nIndentAt;
+ aLevelRule["BulletChar"] >>= sBulletChar;
+ bHasFont = (aLevelRule["BulletFont"] >>= aBulletFont);
+ bHasColor = (aLevelRule["BulletColor"] >>= aBulletColor);
+ }
+
+ if (nPositionAndSpaceMode == css::text::PositionAndSpaceMode::LABEL_ALIGNMENT
+ && nNumberingType != css::style::NumberingType::BITMAP) // TODO
+ {
+ switch (nLabelFollowedBy)
+ {
+ case SvxNumberFormat::LabelFollowedBy::LISTTAB:
+ sLabelString += "\t";
+ break;
+ case SvxNumberFormat::LabelFollowedBy::SPACE:
+ sLabelString += " ";
+ break;
+ case SvxNumberFormat::LabelFollowedBy::NEWLINE:
+ sLabelString += "\n";
+ break;
+ }
+
+ css::uno::Reference<css::text::XTextRange> xNumberText(xRange->getStart());
+ xNumberText->setString(sLabelString);
+ css::uno::Reference<css::beans::XPropertySet> xNumberProps(
+ xNumberText, css::uno::UNO_QUERY_THROW);
+ if (!sCharStyleName.isEmpty())
+ xNumberProps->setPropertyValue("CharStyleName", css::uno::Any(sCharStyleName));
+
+ if (nNumberingType == css::style::NumberingType::CHAR_SPECIAL)
+ {
+ css::uno::Reference<css::text::XTextRange> xBulletText(xNumberText->getStart());
+ xBulletText->setString(sBulletChar);
+
+ std::unordered_map<OUString, css::uno::Any> aNameValues;
+ if (bHasFont)
+ {
+ aNameValues.insert({
+ { "CharFontName", css::uno::Any(aBulletFont.Name) },
+ { "CharFontStyleName", css::uno::Any(aBulletFont.StyleName) },
+ { "CharFontFamily", css::uno::Any(aBulletFont.Family) },
+ { "CharFontCharSet", css::uno::Any(aBulletFont.CharSet) },
+ { "CharWeight", css::uno::Any(aBulletFont.Weight) },
+ { "CharUnderline", css::uno::Any(aBulletFont.Underline) },
+ { "CharStrikeout", css::uno::Any(aBulletFont.Strikeout) },
+ { "CharAutoKerning", css::uno::Any(aBulletFont.Kerning) },
+ { "CharFontPitch", css::uno::Any(aBulletFont.Pitch) },
+ { "CharWordMode", css::uno::Any(aBulletFont.WordLineMode) },
+ { "CharRotation", css::uno::Any(static_cast<sal_Int16>(
+ std::round(aBulletFont.Orientation * 10))) },
+ });
+ if (aBulletFont.Height)
+ aNameValues["CharHeight"] <<= aBulletFont.Height;
+ }
+ if (bHasColor)
+ {
+ aNameValues["CharColor"] <<= aBulletColor;
+ }
+
+ if (css::uno::Reference<css::beans::XMultiPropertySet> xBulletMultiProps{
+ xBulletText, css::uno::UNO_QUERY })
+ {
+ xBulletMultiProps->setPropertyValues(
+ comphelper::mapKeysToSequence(aNameValues),
+ comphelper::mapValuesToSequence(aNameValues));
+ }
+ else
+ {
+ css::uno::Reference<css::beans::XPropertySet> xBulletProps(
+ xBulletText, css::uno::UNO_QUERY_THROW);
+ for (const auto& [rName, rVal] : aNameValues)
+ xBulletProps->setPropertyValue(rName, rVal);
+ }
+ }
+ else
+ {
+ // TODO: css::style::NumberingType::BITMAP
+ }
+
+ (*it)->setPropertyValue("ParaLeftMargin", css::uno::Any(nIndentAt));
+ (*it)->setPropertyValue("ParaFirstLineIndent", css::uno::Any(nFirstLineIndent));
+ if (nLabelFollowedBy == SvxNumberFormat::LabelFollowedBy::LISTTAB)
+ {
+ css::uno::Sequence<css::style::TabStop> stops;
+ (*it)->getPropertyValue("ParaTabStops") >>= stops;
+ css::style::TabStop tabStop{};
+ tabStop.Position = nListtabStopPosition - nIndentAt;
+ tabStop.Alignment = com::sun::star::style::TabAlign::TabAlign_LEFT;
+ tabStop.FillChar = ' ';
+ (*it)->setPropertyValue(
+ "ParaTabStops",
+ css::uno::Any(comphelper::combineSequences({ tabStop }, stops)));
+ // FIXME: What if added tap stop is greater than already defined ones?
+ }
+ }
+ else
+ {
+ // TODO: css::text::PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION
+ continue; // for now, keep such lists as is
+ }
+ (*it)->setPropertyValue("NumberingRules", css::uno::Any());
+ }
+ }
}
OUString
More information about the Libreoffice-commits
mailing list