summaryrefslogtreecommitdiffstats
path: root/sw/source/uibase/uno
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/uibase/uno')
-rw-r--r--sw/source/uibase/uno/SwXDocumentSettings.cxx1635
-rw-r--r--sw/source/uibase/uno/SwXDocumentSettings.hxx78
-rw-r--r--sw/source/uibase/uno/SwXFilterOptions.cxx147
-rw-r--r--sw/source/uibase/uno/dlelstnr.cxx134
-rw-r--r--sw/source/uibase/uno/unoatxt.cxx1018
-rw-r--r--sw/source/uibase/uno/unodefaults.cxx46
-rw-r--r--sw/source/uibase/uno/unodefaults.hxx36
-rw-r--r--sw/source/uibase/uno/unodispatch.cxx387
-rw-r--r--sw/source/uibase/uno/unodoc.cxx93
-rw-r--r--sw/source/uibase/uno/unomailmerge.cxx1168
-rw-r--r--sw/source/uibase/uno/unomod.cxx976
-rw-r--r--sw/source/uibase/uno/unomodule.cxx150
-rw-r--r--sw/source/uibase/uno/unomodule.hxx74
-rw-r--r--sw/source/uibase/uno/unotxdoc.cxx4707
-rw-r--r--sw/source/uibase/uno/unotxvw.cxx1784
15 files changed, 12433 insertions, 0 deletions
diff --git a/sw/source/uibase/uno/SwXDocumentSettings.cxx b/sw/source/uibase/uno/SwXDocumentSettings.cxx
new file mode 100644
index 000000000..985598ec4
--- /dev/null
+++ b/sw/source/uibase/uno/SwXDocumentSettings.cxx
@@ -0,0 +1,1635 @@
+/* -*- 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 <config_features.h>
+#include <config_fuzzers.h>
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include <utility>
+
+#include <o3tl/any.hxx>
+#include "SwXDocumentSettings.hxx"
+#include <comphelper/MasterPropertySetInfo.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/i18n/XForbiddenCharacters.hpp>
+#include <com/sun/star/document/PrinterIndependentLayout.hpp>
+#include <doc.hxx>
+#include <IDocumentSettingAccess.hxx>
+#include <IDocumentDeviceAccess.hxx>
+#include <IDocumentRedlineAccess.hxx>
+#include <docsh.hxx>
+#include <fldupde.hxx>
+#include <linkenum.hxx>
+#include <sfx2/printer.hxx>
+#include <editsh.hxx>
+#include <unotxdoc.hxx>
+#include <cmdid.h>
+#include <unomod.hxx>
+#include <vcl/svapp.hxx>
+#include <svl/asiancfg.hxx>
+#include <tools/stream.hxx>
+
+#include <cfgitems.hxx>
+#include <dbmgr.hxx>
+
+using namespace comphelper;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::i18n;
+
+namespace {
+
+enum SwDocumentSettingsPropertyHandles
+{
+ HANDLE_FORBIDDEN_CHARS,
+ HANDLE_LINK_UPDATE_MODE,
+ HANDLE_FIELD_AUTO_UPDATE,
+ HANDLE_CHART_AUTO_UPDATE,
+ HANDLE_ADD_PARA_TABLE_SPACING,
+ HANDLE_ADD_PARA_TABLE_SPACING_AT_START,
+ HANDLE_ALIGN_TAB_STOP_POSITION,
+ HANDLE_PRINTER_NAME,
+ HANDLE_PRINTER_SETUP,
+ HANDLE_PRINTER_PAPER,
+ HANDLE_IS_KERN_ASIAN_PUNCTUATION,
+ HANDLE_CHARACTER_COMPRESSION_TYPE,
+ HANDLE_APPLY_USER_DATA,
+ HANDLE_SAVE_THUMBNAIL,
+ HANDLE_SAVE_GLOBAL_DOCUMENT_LINKS,
+ HANDLE_CURRENT_DATABASE_DATA_SOURCE,
+ HANDLE_CURRENT_DATABASE_COMMAND,
+ HANDLE_CURRENT_DATABASE_COMMAND_TYPE,
+ HANDLE_EMBEDDED_DATABASE_NAME,
+ HANDLE_SAVE_VERSION_ON_CLOSE,
+ HANDLE_UPDATE_FROM_TEMPLATE,
+ HANDLE_PRINTER_INDEPENDENT_LAYOUT,
+ HANDLE_IS_LABEL_DOC,
+ HANDLE_IS_ADD_FLY_OFFSET,
+ HANDLE_IS_ADD_VERTICAL_FLY_OFFSET,
+ HANDLE_IS_ADD_EXTERNAL_LEADING,
+ HANDLE_OLD_NUMBERING,
+ HANDLE_OUTLINELEVEL_YIELDS_NUMBERING,
+ /* Stampit It disable the print cancel button of the shown progress dialog. */
+ HANDLE_ALLOW_PRINTJOB_CANCEL,
+ HANDLE_USE_FORMER_LINE_SPACING,
+ HANDLE_ADD_PARA_SPACING_TO_TABLE_CELLS,
+ HANDLE_ADD_PARA_LINE_SPACING_TO_TABLE_CELLS,
+ HANDLE_USE_FORMER_OBJECT_POSITIONING,
+ HANDLE_USE_FORMER_TEXT_WRAPPING,
+ HANDLE_CHANGES_PASSWORD,
+ HANDLE_CONSIDER_WRAP_ON_OBJPOS,
+ HANDLE_IGNORE_FIRST_LINE_INDENT_IN_NUMBERING,
+ HANDLE_DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK,
+ HANDLE_DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT,
+ HANDLE_TABLE_ROW_KEEP,
+ HANDLE_IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION,
+ HANDLE_LOAD_READONLY,
+ HANDLE_DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE,
+ HANDLE_CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAMES,
+ HANDLE_UNIX_FORCE_ZERO_EXT_LEADING,
+ HANDLE_USE_OLD_PRINTER_METRICS,
+ HANDLE_PROTECT_FORM,
+ HANDLE_MS_WORD_COMP_TRAILING_BLANKS,
+ HANDLE_MS_WORD_COMP_MIN_LINE_HEIGHT_BY_FLY,
+ HANDLE_TABS_RELATIVE_TO_INDENT,
+ HANDLE_RSID,
+ HANDLE_RSID_ROOT,
+ HANDLE_TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST,
+ HANDLE_MODIFYPASSWORDINFO,
+ HANDLE_MATH_BASELINE_ALIGNMENT,
+ HANDLE_INVERT_BORDER_SPACING,
+ HANDLE_COLLAPSE_EMPTY_CELL_PARA,
+ HANDLE_SMALL_CAPS_PERCENTAGE_66,
+ HANDLE_TAB_OVERFLOW,
+ HANDLE_UNBREAKABLE_NUMBERINGS,
+ HANDLE_STYLES_NODEFAULT,
+ HANDLE_FLOATTABLE_NOMARGINS,
+ HANDLE_CLIPPED_PICTURES,
+ HANDLE_BACKGROUND_PARA_OVER_DRAWINGS,
+ HANDLE_EMBED_FONTS,
+ HANDLE_EMBED_USED_FONTS,
+ HANDLE_EMBED_LATIN_SCRIPT_FONTS,
+ HANDLE_EMBED_ASIAN_SCRIPT_FONTS,
+ HANDLE_EMBED_COMPLEX_SCRIPT_FONTS,
+ HANDLE_EMBED_SYSTEM_FONTS,
+ HANDLE_TAB_OVER_MARGIN,
+ HANDLE_TAB_OVER_SPACING,
+ HANDLE_TREAT_SINGLE_COLUMN_BREAK_AS_PAGE_BREAK,
+ HANDLE_SURROUND_TEXT_WRAP_SMALL,
+ HANDLE_APPLY_PARAGRAPH_MARK_FORMAT_TO_NUMBERING,
+ HANDLE_PROP_LINE_SPACING_SHRINKS_FIRST_LINE,
+ HANDLE_SUBTRACT_FLYS,
+ HANDLE_DISABLE_OFF_PAGE_POSITIONING,
+ HANDLE_EMPTY_DB_FIELD_HIDES_PARA,
+ HANDLE_CONTINUOUS_ENDNOTES,
+ HANDLE_PROTECT_BOOKMARKS,
+ HANDLE_PROTECT_FIELDS,
+ HANDLE_HEADER_SPACING_BELOW_LAST_PARA,
+ HANDLE_FRAME_AUTOWIDTH_WITH_MORE_PARA,
+ HANDLE_GUTTER_AT_TOP,
+ HANDLE_FOOTNOTE_IN_COLUMN_TO_PAGEEND,
+ HANDLE_IMAGE_PREFERRED_DPI,
+ HANDLE_AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE,
+ HANDLE_WORD_LIKE_WRAP_FOR_AS_CHAR_FLYS,
+ HANDLE_NO_NUMBERING_SHOW_FOLLOWBY
+};
+
+}
+
+static rtl::Reference<MasterPropertySetInfo> lcl_createSettingsInfo()
+{
+ static PropertyInfo const aWriterSettingsInfoMap[] =
+ {
+ { OUString("ForbiddenCharacters"), HANDLE_FORBIDDEN_CHARS, cppu::UnoType<css::i18n::XForbiddenCharacters>::get(), 0},
+ { OUString("LinkUpdateMode"), HANDLE_LINK_UPDATE_MODE, cppu::UnoType<sal_Int16>::get(), 0},
+ { OUString("FieldAutoUpdate"), HANDLE_FIELD_AUTO_UPDATE, cppu::UnoType<bool>::get(), 0},
+ { OUString("ChartAutoUpdate"), HANDLE_CHART_AUTO_UPDATE, cppu::UnoType<bool>::get(), 0},
+ { OUString("AddParaTableSpacing"), HANDLE_ADD_PARA_TABLE_SPACING, cppu::UnoType<bool>::get(), 0},
+ { OUString("AddParaTableSpacingAtStart"), HANDLE_ADD_PARA_TABLE_SPACING_AT_START, cppu::UnoType<bool>::get(), 0},
+ { OUString("AlignTabStopPosition"), HANDLE_ALIGN_TAB_STOP_POSITION, cppu::UnoType<bool>::get(), 0},
+ { OUString("PrinterName"), HANDLE_PRINTER_NAME, cppu::UnoType<OUString>::get(), 0},
+ { OUString("PrinterSetup"), HANDLE_PRINTER_SETUP, cppu::UnoType< cppu::UnoSequenceType<sal_Int8> >::get(), 0},
+ { OUString("PrinterPaperFromSetup"), HANDLE_PRINTER_PAPER, cppu::UnoType<bool>::get(), 0},
+ { OUString("IsKernAsianPunctuation"), HANDLE_IS_KERN_ASIAN_PUNCTUATION, cppu::UnoType<bool>::get(), 0},
+ { OUString("CharacterCompressionType"), HANDLE_CHARACTER_COMPRESSION_TYPE, cppu::UnoType<sal_Int16>::get(), 0},
+ { OUString("ApplyUserData"), HANDLE_APPLY_USER_DATA, cppu::UnoType<bool>::get(), 0 },
+ { OUString("SaveThumbnail"), HANDLE_SAVE_THUMBNAIL, cppu::UnoType<bool>::get(), 0 },
+ { OUString("SaveGlobalDocumentLinks"), HANDLE_SAVE_GLOBAL_DOCUMENT_LINKS, cppu::UnoType<bool>::get(), 0},
+ { OUString("CurrentDatabaseDataSource"), HANDLE_CURRENT_DATABASE_DATA_SOURCE, cppu::UnoType<OUString>::get(), 0},
+ { OUString("CurrentDatabaseCommand"), HANDLE_CURRENT_DATABASE_COMMAND, cppu::UnoType<OUString>::get(), 0},
+ { OUString("CurrentDatabaseCommandType"), HANDLE_CURRENT_DATABASE_COMMAND_TYPE, cppu::UnoType<sal_Int32>::get(), 0},
+ { OUString("EmbeddedDatabaseName"), HANDLE_EMBEDDED_DATABASE_NAME, cppu::UnoType<OUString>::get(), 0},
+ { OUString("SaveVersionOnClose"), HANDLE_SAVE_VERSION_ON_CLOSE, cppu::UnoType<bool>::get(), 0},
+ { OUString("UpdateFromTemplate"), HANDLE_UPDATE_FROM_TEMPLATE, cppu::UnoType<bool>::get(), 0},
+
+ { OUString("PrinterIndependentLayout"), HANDLE_PRINTER_INDEPENDENT_LAYOUT, cppu::UnoType<sal_Int16>::get(), 0},
+ { OUString("IsLabelDocument"), HANDLE_IS_LABEL_DOC, cppu::UnoType<bool>::get(), 0},
+ { OUString("AddFrameOffsets"), HANDLE_IS_ADD_FLY_OFFSET, cppu::UnoType<bool>::get(), 0},
+ { OUString("AddVerticalFrameOffsets"), HANDLE_IS_ADD_VERTICAL_FLY_OFFSET, cppu::UnoType<bool>::get(), 0},
+ { OUString("AddExternalLeading"), HANDLE_IS_ADD_EXTERNAL_LEADING, cppu::UnoType<bool>::get(), 0},
+ { OUString("UseOldNumbering"), HANDLE_OLD_NUMBERING, cppu::UnoType<bool>::get(), 0},
+ { OUString("OutlineLevelYieldsNumbering"), HANDLE_OUTLINELEVEL_YIELDS_NUMBERING, cppu::UnoType<bool>::get(), 0},
+ /* Stampit It disable the print cancel button of the shown progress dialog. */
+ { OUString("AllowPrintJobCancel"), HANDLE_ALLOW_PRINTJOB_CANCEL, cppu::UnoType<bool>::get(), 0},
+ { OUString("UseFormerLineSpacing"), HANDLE_USE_FORMER_LINE_SPACING, cppu::UnoType<bool>::get(), 0},
+ { OUString("AddParaSpacingToTableCells"), HANDLE_ADD_PARA_SPACING_TO_TABLE_CELLS, cppu::UnoType<bool>::get(), 0},
+ { OUString("AddParaLineSpacingToTableCells"), HANDLE_ADD_PARA_LINE_SPACING_TO_TABLE_CELLS, cppu::UnoType<bool>::get(), 0},
+ { OUString("UseFormerObjectPositioning"), HANDLE_USE_FORMER_OBJECT_POSITIONING, cppu::UnoType<bool>::get(), 0},
+ { OUString("UseFormerTextWrapping"), HANDLE_USE_FORMER_TEXT_WRAPPING, cppu::UnoType<bool>::get(), 0},
+ { OUString("RedlineProtectionKey"), HANDLE_CHANGES_PASSWORD, cppu::UnoType< cppu::UnoSequenceType<sal_Int8> >::get(), 0},
+ { OUString("ConsiderTextWrapOnObjPos"), HANDLE_CONSIDER_WRAP_ON_OBJPOS, cppu::UnoType<bool>::get(), 0},
+ { OUString("IgnoreFirstLineIndentInNumbering"), HANDLE_IGNORE_FIRST_LINE_INDENT_IN_NUMBERING, cppu::UnoType<bool>::get(), 0},
+ { OUString("DoNotJustifyLinesWithManualBreak"), HANDLE_DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, cppu::UnoType<bool>::get(), 0},
+ { OUString("DoNotResetParaAttrsForNumFont"), HANDLE_DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT, cppu::UnoType<bool>::get(), 0},
+ { OUString("TableRowKeep"), HANDLE_TABLE_ROW_KEEP, cppu::UnoType<bool>::get(), 0},
+ { OUString("IgnoreTabsAndBlanksForLineCalculation"), HANDLE_IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION, cppu::UnoType<bool>::get(), 0},
+ { OUString("LoadReadonly"), HANDLE_LOAD_READONLY, cppu::UnoType<bool>::get(), 0},
+ { OUString("DoNotCaptureDrawObjsOnPage"), HANDLE_DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE, cppu::UnoType<bool>::get(), 0},
+ { OUString("ClipAsCharacterAnchoredWriterFlyFrames"), HANDLE_CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAMES, cppu::UnoType<bool>::get(), 0},
+ { OUString("UnxForceZeroExtLeading"), HANDLE_UNIX_FORCE_ZERO_EXT_LEADING, cppu::UnoType<bool>::get(), 0},
+ { OUString("UseOldPrinterMetrics"), HANDLE_USE_OLD_PRINTER_METRICS, cppu::UnoType<bool>::get(), 0},
+ { OUString("TabsRelativeToIndent"), HANDLE_TABS_RELATIVE_TO_INDENT, cppu::UnoType<bool>::get(), 0},
+ { OUString("Rsid"), HANDLE_RSID, cppu::UnoType<sal_Int32>::get(), 0},
+ { OUString("RsidRoot"), HANDLE_RSID_ROOT, cppu::UnoType<sal_Int32>::get(), 0},
+ { OUString("ProtectForm"), HANDLE_PROTECT_FORM, cppu::UnoType<bool>::get(), 0},
+ { OUString("MsWordCompTrailingBlanks"), HANDLE_MS_WORD_COMP_TRAILING_BLANKS, cppu::UnoType<bool>::get(), 0 },
+ { OUString("MsWordCompMinLineHeightByFly"), HANDLE_MS_WORD_COMP_MIN_LINE_HEIGHT_BY_FLY, cppu::UnoType<bool>::get(), 0 },
+ { OUString("TabAtLeftIndentForParagraphsInList"), HANDLE_TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST, cppu::UnoType<bool>::get(), 0},
+ { OUString("ModifyPasswordInfo"), HANDLE_MODIFYPASSWORDINFO, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), 0},
+ { OUString("MathBaselineAlignment"), HANDLE_MATH_BASELINE_ALIGNMENT, cppu::UnoType<bool>::get(), 0},
+ { OUString("InvertBorderSpacing"), HANDLE_INVERT_BORDER_SPACING, cppu::UnoType<bool>::get(), 0},
+ { OUString("CollapseEmptyCellPara"), HANDLE_COLLAPSE_EMPTY_CELL_PARA, cppu::UnoType<bool>::get(), 0},
+ { OUString("SmallCapsPercentage66"), HANDLE_SMALL_CAPS_PERCENTAGE_66, cppu::UnoType<bool>::get(), 0},
+ { OUString("TabOverflow"), HANDLE_TAB_OVERFLOW, cppu::UnoType<bool>::get(), 0},
+ { OUString("UnbreakableNumberings"), HANDLE_UNBREAKABLE_NUMBERINGS, cppu::UnoType<bool>::get(), 0},
+ { OUString("StylesNoDefault"), HANDLE_STYLES_NODEFAULT, cppu::UnoType<bool>::get(), 0},
+ { OUString("FloattableNomargins"), HANDLE_FLOATTABLE_NOMARGINS, cppu::UnoType<bool>::get(), 0},
+ { OUString("ClippedPictures"), HANDLE_CLIPPED_PICTURES, cppu::UnoType<bool>::get(), 0},
+ { OUString("BackgroundParaOverDrawings"), HANDLE_BACKGROUND_PARA_OVER_DRAWINGS, cppu::UnoType<bool>::get(), 0},
+ { OUString("EmbedFonts"), HANDLE_EMBED_FONTS, cppu::UnoType<bool>::get(), 0},
+ { OUString("EmbedOnlyUsedFonts"), HANDLE_EMBED_USED_FONTS, cppu::UnoType<bool>::get(), 0},
+ { OUString("EmbedLatinScriptFonts"), HANDLE_EMBED_LATIN_SCRIPT_FONTS, cppu::UnoType<bool>::get(), 0},
+ { OUString("EmbedAsianScriptFonts"), HANDLE_EMBED_ASIAN_SCRIPT_FONTS, cppu::UnoType<bool>::get(), 0},
+ { OUString("EmbedComplexScriptFonts"), HANDLE_EMBED_COMPLEX_SCRIPT_FONTS, cppu::UnoType<bool>::get(), 0},
+ { OUString("EmbedSystemFonts"), HANDLE_EMBED_SYSTEM_FONTS, cppu::UnoType<bool>::get(), 0},
+ { OUString("TabOverMargin"), HANDLE_TAB_OVER_MARGIN, cppu::UnoType<bool>::get(), 0},
+ { OUString("TabOverSpacing"), HANDLE_TAB_OVER_SPACING, cppu::UnoType<bool>::get(), 0},
+ { OUString("TreatSingleColumnBreakAsPageBreak"), HANDLE_TREAT_SINGLE_COLUMN_BREAK_AS_PAGE_BREAK, cppu::UnoType<bool>::get(), 0},
+ { OUString("SurroundTextWrapSmall"), HANDLE_SURROUND_TEXT_WRAP_SMALL, cppu::UnoType<bool>::get(), 0},
+ { OUString("ApplyParagraphMarkFormatToNumbering"), HANDLE_APPLY_PARAGRAPH_MARK_FORMAT_TO_NUMBERING, cppu::UnoType<bool>::get(), 0},
+ { OUString("PropLineSpacingShrinksFirstLine"), HANDLE_PROP_LINE_SPACING_SHRINKS_FIRST_LINE, cppu::UnoType<bool>::get(), 0},
+ { OUString("SubtractFlysAnchoredAtFlys"), HANDLE_SUBTRACT_FLYS, cppu::UnoType<bool>::get(), 0},
+ { OUString("DisableOffPagePositioning"), HANDLE_DISABLE_OFF_PAGE_POSITIONING, cppu::UnoType<bool>::get(), 0},
+ { OUString("EmptyDbFieldHidesPara"), HANDLE_EMPTY_DB_FIELD_HIDES_PARA, cppu::UnoType<bool>::get(), 0 },
+ { OUString("ContinuousEndnotes"), HANDLE_CONTINUOUS_ENDNOTES, cppu::UnoType<bool>::get(), 0 },
+ { OUString("ProtectBookmarks"), HANDLE_PROTECT_BOOKMARKS, cppu::UnoType<bool>::get(), 0 },
+ { OUString("ProtectFields"), HANDLE_PROTECT_FIELDS, cppu::UnoType<bool>::get(), 0 },
+ { OUString("HeaderSpacingBelowLastPara"), HANDLE_HEADER_SPACING_BELOW_LAST_PARA, cppu::UnoType<bool>::get(), 0 },
+ { OUString("FrameAutowidthWithMorePara"), HANDLE_FRAME_AUTOWIDTH_WITH_MORE_PARA, cppu::UnoType<bool>::get(), 0 },
+ { OUString("GutterAtTop"), HANDLE_GUTTER_AT_TOP, cppu::UnoType<bool>::get(), 0 },
+ { OUString("FootnoteInColumnToPageEnd"), HANDLE_FOOTNOTE_IN_COLUMN_TO_PAGEEND, cppu::UnoType<bool>::get(), 0 },
+ { OUString("ImagePreferredDPI"), HANDLE_IMAGE_PREFERRED_DPI, cppu::UnoType<sal_Int32>::get(), 0 },
+ { OUString("AutoFirstLineIndentDisregardLineSpace"), HANDLE_AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE, cppu::UnoType<bool>::get(), 0 },
+ { OUString("WordLikeWrapForAsCharFlys"), HANDLE_WORD_LIKE_WRAP_FOR_AS_CHAR_FLYS, cppu::UnoType<bool>::get(), 0 },
+ { OUString("NoNumberingShowFollowBy"), HANDLE_NO_NUMBERING_SHOW_FOLLOWBY, cppu::UnoType<bool>::get(), 0 },
+
+/*
+ * As OS said, we don't have a view when we need to set this, so I have to
+ * find another solution before adding them to this property set - MTG
+ { OUString("IsGridVisible"), HANDLE_IS_GRID_VISIBLE, cppu::UnoType<bool>::get(), 0, 0},
+ { OUString("IsSnapToGrid"), HANDLE_IS_SNAP_TO_GRID, cppu::UnoType<bool>::get(), 0, 0},
+ { OUString("IsSynchroniseAxes"), HANDLE_IS_SYNCHRONISE_AXES, cppu::UnoType<bool>::get(), 0, 0},
+ { OUString("HorizontalGridResolution"), HANDLE_HORIZONTAL_GRID_RESOLUTION, cppu::UnoType<sal_Int32>::get(), 0, 0},
+ { OUString("HorizontalGridSubdivision"), HANDLE_HORIZONTAL_GRID_SUBDIVISION, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { OUString("VerticalGridResolution"), HANDLE_VERTICAL_GRID_RESOLUTION, cppu::UnoType<sal_Int32>::get(), 0, 0},
+ { OUString("VerticalGridSubdivision"), HANDLE_VERTICAL_GRID_SUBDIVISION, cppu::UnoType<sal_Int16>::get(), 0, 0},
+
+ { OUString("ShowParagraphEnd"), HANDLE_SHOW_PARAGRAPH_END, cppu::UnoType<bool>::get(), 0, 0},
+ { OUString("ShowOptionalHyphens"), HANDLE_SHOW_OPTIONAL_HYPHENS, cppu::UnoType<bool>::get(), 0, 0},
+ { OUString("ShowSpaces"), HANDLE_SHOW_SPACES, cppu::UnoType<bool>::get(), 0, 0},
+ { OUString("ShowTabs"), HANDLE_SHOW_TABS, cppu::UnoType<bool>::get(), 0, 0},
+ { OUString("ShowBreaks"), HANDLE_SHOW_BREAKS, cppu::UnoType<bool>::get(), 0, 0},
+ { OUString("ShowHiddenText"), HANDLE_SHOW_HIDDEN_TEXT, cppu::UnoType<bool>::get(), 0, 0},
+ { OUString("ShowHiddenParagraphs"), HANDLE_SHOW_HIDDEN_PARAGRAPHS, cppu::UnoType<bool>::get(), 0, 0},
+
+ { OUString("ShowTextLimitGuide"), HANDLE_SHOW_TEXT_LIMIT_GUIDE, cppu::UnoType<bool>::get(), 0, 0},
+ { OUString("ShowTableLimitGuide"), HANDLE_SHOW_TABLE_LIMIT_GUIDE, cppu::UnoType<bool>::get(), 0, 0},
+ { OUString("ShowSectionLimitGuide"), HANDLE_SHOW_SECTION_LIMIT_GUIDE, cppu::UnoType<bool>::get(), 0, 0},
+ { OUString("ShowGuidesWhileMoving"), HANDLE_SHOW_GUIDES_WHILE_MOVING, cppu::UnoType<bool>::get(), 0, 0},
+*/
+ { OUString(), 0, css::uno::Type(), 0}
+ };
+ return new MasterPropertySetInfo ( aWriterSettingsInfoMap );
+}
+
+SwXDocumentSettings::SwXDocumentSettings ( SwXTextDocument * pModel )
+: MasterPropertySet ( lcl_createSettingsInfo().get(),
+ &Application::GetSolarMutex () )
+, mpModel ( pModel )
+, mpDocSh ( nullptr )
+, mpDoc ( nullptr )
+, mpPrinter( nullptr )
+, mbPreferPrinterPapersize( false )
+{
+ registerSlave ( new SwXPrintSettings ( SwXPrintSettingsType::Document, mpModel->GetDocShell()->GetDoc() ) );
+}
+
+SwXDocumentSettings::~SwXDocumentSettings()
+ noexcept
+{
+}
+
+Any SAL_CALL SwXDocumentSettings::queryInterface( const Type& rType )
+{
+ return ::cppu::queryInterface(rType,
+ // OWeakObject interfaces
+ &dynamic_cast<XInterface&>(dynamic_cast<OWeakObject&>(*this)),
+ &dynamic_cast<XWeak&>(*this),
+ // my own interfaces
+ &dynamic_cast<XPropertySet&>(*this),
+ &dynamic_cast<XPropertyState&>(*this),
+ &dynamic_cast<XMultiPropertySet&>(*this),
+ &dynamic_cast<XServiceInfo&>(*this),
+ &dynamic_cast<XTypeProvider&>(*this));
+}
+void SwXDocumentSettings::acquire ()
+ noexcept
+{
+ OWeakObject::acquire();
+}
+void SwXDocumentSettings::release ()
+ noexcept
+{
+ OWeakObject::release();
+}
+
+uno::Sequence< uno::Type > SAL_CALL SwXDocumentSettings::getTypes( )
+{
+ static const uno::Sequence< uno::Type > aTypes {
+ // from MasterPropertySet
+ cppu::UnoType<XPropertySet>::get(),
+ cppu::UnoType<XPropertyState>::get(),
+ cppu::UnoType<XMultiPropertySet>::get(),
+ cppu::UnoType<XServiceInfo>::get(),
+ cppu::UnoType<XTypeProvider>::get(),
+ };
+ return aTypes;
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL SwXDocumentSettings::getImplementationId( )
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+void SwXDocumentSettings::_preSetValues ()
+{
+ mpDocSh = mpModel->GetDocShell();
+ if (nullptr == mpDocSh)
+ throw UnknownPropertyException();
+
+ mpDoc = mpDocSh->GetDoc();
+ if (nullptr == mpDoc)
+ throw UnknownPropertyException();
+}
+
+void SwXDocumentSettings::_setSingleValue( const comphelper::PropertyInfo & rInfo, const uno::Any &rValue )
+{
+ if (rInfo.mnAttributes & PropertyAttribute::READONLY)
+ throw PropertyVetoException ("Property is read-only: " + rInfo.maName, static_cast < cppu::OWeakObject * > ( nullptr ) );
+
+ switch( rInfo.mnHandle )
+ {
+ case HANDLE_FORBIDDEN_CHARS:
+ break;
+ case HANDLE_LINK_UPDATE_MODE:
+ {
+ sal_Int16 nMode = 0;
+ rValue >>= nMode;
+ switch (nMode)
+ {
+ case NEVER:
+ case MANUAL:
+ case AUTOMATIC:
+ case GLOBALSETTING:
+ break;
+ default:
+ throw IllegalArgumentException();
+ }
+ mpDoc->getIDocumentSettingAccess().setLinkUpdateMode(nMode);
+ }
+ break;
+ case HANDLE_FIELD_AUTO_UPDATE:
+ {
+ bool bUpdateField = *o3tl::doAccess<bool>(rValue);
+ SwFieldUpdateFlags nFlag = mpDoc->getIDocumentSettingAccess().getFieldUpdateFlags(true);
+ mpDoc->getIDocumentSettingAccess().setFieldUpdateFlags( bUpdateField ?
+ nFlag == AUTOUPD_FIELD_AND_CHARTS ?
+ AUTOUPD_FIELD_AND_CHARTS :
+ AUTOUPD_FIELD_ONLY :
+ AUTOUPD_OFF );
+ }
+ break;
+ case HANDLE_CHART_AUTO_UPDATE:
+ {
+ bool bUpdateChart = *o3tl::doAccess<bool>(rValue);
+ SwFieldUpdateFlags nFlag = mpDoc->getIDocumentSettingAccess().getFieldUpdateFlags(true);
+ mpDoc->getIDocumentSettingAccess().setFieldUpdateFlags( (nFlag == AUTOUPD_FIELD_ONLY || nFlag == AUTOUPD_FIELD_AND_CHARTS ) ?
+ bUpdateChart ?
+ AUTOUPD_FIELD_AND_CHARTS :
+ AUTOUPD_FIELD_ONLY :
+ AUTOUPD_OFF );
+ }
+ break;
+ case HANDLE_ADD_PARA_TABLE_SPACING:
+ {
+ bool bParaSpace = false;
+ rValue >>= bParaSpace;
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::PARA_SPACE_MAX, bParaSpace );
+ }
+ break;
+ case HANDLE_ADD_PARA_TABLE_SPACING_AT_START:
+ {
+ bool bParaSpacePage = false;
+ rValue >>= bParaSpacePage;
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::PARA_SPACE_MAX_AT_PAGES, bParaSpacePage );
+ }
+ break;
+ case HANDLE_ALIGN_TAB_STOP_POSITION:
+ {
+ bool bAlignTab = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::TAB_COMPAT, bAlignTab);
+ }
+ break;
+ case HANDLE_PRINTER_NAME:
+ {
+ //the printer must be created
+ OUString sPrinterName;
+ if( !(rValue >>= sPrinterName) )
+ throw IllegalArgumentException();
+
+ if( !mpPrinter && !sPrinterName.isEmpty() && mpDocSh->GetCreateMode() != SfxObjectCreateMode::EMBEDDED )
+ {
+ SfxPrinter* pPrinter = mpDoc->getIDocumentDeviceAccess().getPrinter( true );
+ if ( pPrinter->GetName() != sPrinterName )
+ {
+ VclPtrInstance<SfxPrinter> pNewPrinter( pPrinter->GetOptions().Clone(), sPrinterName );
+ assert (! pNewPrinter->isDisposed() );
+ if( pNewPrinter->IsKnown() )
+ {
+ // set printer only once; in _postSetValues
+ mpPrinter = pNewPrinter;
+ }
+ else
+ {
+ pNewPrinter.disposeAndClear();
+ }
+ }
+ }
+
+ }
+ break;
+ case HANDLE_PRINTER_SETUP:
+ {
+ Sequence < sal_Int8 > aSequence;
+ if ( !(rValue >>= aSequence) )
+ throw IllegalArgumentException();
+
+ sal_uInt32 nSize = aSequence.getLength();
+ if( nSize > 0 )
+ {
+ SvMemoryStream aStream (aSequence.getArray(), nSize,
+ StreamMode::READ );
+ aStream.Seek ( STREAM_SEEK_TO_BEGIN );
+ auto pItemSet = std::make_unique<SfxItemSetFixed<
+ SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN,
+ SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC,
+ SID_HTML_MODE, SID_HTML_MODE,
+ FN_PARAM_ADDPRINTER, FN_PARAM_ADDPRINTER>>( mpDoc->GetAttrPool() );
+ VclPtr<SfxPrinter> pPrinter = SfxPrinter::Create ( aStream, std::move(pItemSet) );
+ assert (! pPrinter->isDisposed() );
+ // set printer only once; in _postSetValues
+ mpPrinter.disposeAndClear();
+ mpPrinter = pPrinter;
+ }
+
+ }
+ break;
+ case HANDLE_PRINTER_PAPER:
+ {
+ bool bPreferPrinterPapersize = {}; // spurious -Werror=maybe-uninitialized
+ if(!(rValue >>= bPreferPrinterPapersize))
+ throw IllegalArgumentException();
+ mbPreferPrinterPapersize = bPreferPrinterPapersize;
+ }
+ break;
+ case HANDLE_IS_KERN_ASIAN_PUNCTUATION:
+ {
+ bool bIsKern = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::KERN_ASIAN_PUNCTUATION, bIsKern);
+ if (SwEditShell* pEditSh = mpDoc->GetEditShell())
+ pEditSh->ChgHyphenation();
+ }
+ break;
+ case HANDLE_CHARACTER_COMPRESSION_TYPE:
+ {
+ sal_Int16 nMode = 0;
+ rValue >>= nMode;
+ switch (static_cast<CharCompressType>(nMode))
+ {
+ case CharCompressType::NONE:
+ case CharCompressType::PunctuationOnly:
+ case CharCompressType::PunctuationAndKana:
+ break;
+ default:
+ throw IllegalArgumentException();
+ }
+ mpDoc->getIDocumentSettingAccess().setCharacterCompressionType(static_cast<CharCompressType>(nMode));
+ }
+ break;
+ case HANDLE_APPLY_USER_DATA:
+ {
+ mpDocSh->SetUseUserData(*o3tl::doAccess<bool>(rValue));
+ }
+ break;
+ case HANDLE_SAVE_THUMBNAIL:
+ {
+ mpDocSh->SetUseThumbnailSave(*o3tl::doAccess<bool>(rValue));
+ }
+ break;
+ case HANDLE_SAVE_GLOBAL_DOCUMENT_LINKS:
+ {
+ bool bSaveGlobal = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::GLOBAL_DOCUMENT_SAVE_LINKS, bSaveGlobal );
+ }
+ break;
+ case HANDLE_CURRENT_DATABASE_DATA_SOURCE:
+ {
+ SwDBData aData = mpDoc->GetDBData();
+ if ( rValue >>= aData.sDataSource )
+ mpDoc->ChgDBData( aData );
+ }
+ break;
+ case HANDLE_CURRENT_DATABASE_COMMAND:
+ {
+ SwDBData aData = mpDoc->GetDBData();
+
+ if ( rValue >>= aData.sCommand )
+ mpDoc->ChgDBData( aData );
+
+ SAL_WARN_IF( aData.sDataSource.isEmpty() && !aData.sCommand.isEmpty(), "sw.uno",
+ "\"CurrentDatabaseCommand\" property possibly set before \"CurrentDatabaseDataSource\"" );
+ }
+ break;
+ case HANDLE_CURRENT_DATABASE_COMMAND_TYPE:
+ {
+ SwDBData aData = mpDoc->GetDBData();
+ if ( rValue >>= aData.nCommandType )
+ mpDoc->ChgDBData( aData );
+ SAL_WARN_IF( aData.nCommandType && aData.sDataSource.isEmpty(), "sw.uno",
+ "\"CurrentDatabaseCommandType\" property possibly set before \"CurrentDatabaseDataSource\"" );
+ SAL_WARN_IF( aData.nCommandType && aData.sCommand.isEmpty(), "sw.uno",
+ "\"CurrentDatabaseCommandType\" property possibly set before \"CurrentDatabaseCommand\"" );
+ }
+ break;
+ case HANDLE_EMBEDDED_DATABASE_NAME:
+ {
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ OUString sEmbeddedName;
+ if (rValue >>= sEmbeddedName)
+ mpDoc->GetDBManager()->setEmbeddedName(sEmbeddedName, *mpDocSh);
+#endif
+ }
+ break;
+ case HANDLE_SAVE_VERSION_ON_CLOSE:
+ {
+ mpDocSh->SetSaveVersionOnClose( *o3tl::doAccess<bool>(rValue) );
+ }
+ break;
+ case HANDLE_UPDATE_FROM_TEMPLATE:
+ {
+ mpDocSh->SetQueryLoadTemplate( *o3tl::doAccess<bool>(rValue) );
+ }
+ break;
+ case HANDLE_PRINTER_INDEPENDENT_LAYOUT:
+ {
+ sal_Int16 nTmp = 0;
+ rValue >>= nTmp;
+
+ bool bUseVirDev = true;
+ bool bHiResVirDev = true;
+ if( nTmp == document::PrinterIndependentLayout::DISABLED )
+ bUseVirDev = false;
+ else if ( nTmp == document::PrinterIndependentLayout::LOW_RESOLUTION )
+ bHiResVirDev = false;
+ else if ( nTmp != document::PrinterIndependentLayout::HIGH_RESOLUTION )
+ throw IllegalArgumentException();
+
+ mpDoc->getIDocumentDeviceAccess().setReferenceDeviceType( bUseVirDev, bHiResVirDev );
+ }
+ break;
+ case HANDLE_IS_LABEL_DOC :
+ {
+ bool bSet = false;
+ if(!(rValue >>= bSet))
+ throw IllegalArgumentException();
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::LABEL_DOCUMENT, bSet);
+ }
+ break;
+ case HANDLE_IS_ADD_FLY_OFFSET:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::ADD_FLY_OFFSETS, bTmp);
+ }
+ break;
+ case HANDLE_IS_ADD_VERTICAL_FLY_OFFSET:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::ADD_VERTICAL_FLY_OFFSETS, bTmp);
+ }
+ break;
+ case HANDLE_IS_ADD_EXTERNAL_LEADING:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::ADD_EXT_LEADING, bTmp);
+ }
+ break;
+ case HANDLE_OLD_NUMBERING:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::OLD_NUMBERING, bTmp);
+ }
+ break;
+ case HANDLE_OUTLINELEVEL_YIELDS_NUMBERING:
+ {
+ // ignore - this is a dead property
+ }
+ break;
+ case HANDLE_ALLOW_PRINTJOB_CANCEL:
+ {
+ bool bState = false;
+ if (!(rValue >>= bState))
+ throw IllegalArgumentException();
+ mpDocSh->Stamp_SetPrintCancelState(bState);
+ }
+ break;
+ case HANDLE_USE_FORMER_LINE_SPACING:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::OLD_LINE_SPACING, bTmp);
+ }
+ break;
+ case HANDLE_ADD_PARA_SPACING_TO_TABLE_CELLS:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::ADD_PARA_SPACING_TO_TABLE_CELLS, bTmp);
+ }
+ break;
+ case HANDLE_ADD_PARA_LINE_SPACING_TO_TABLE_CELLS:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::ADD_PARA_LINE_SPACING_TO_TABLE_CELLS, bTmp);
+ }
+ break;
+ case HANDLE_USE_FORMER_OBJECT_POSITIONING:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::USE_FORMER_OBJECT_POS, bTmp);
+ }
+ break;
+ case HANDLE_USE_FORMER_TEXT_WRAPPING:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::USE_FORMER_TEXT_WRAPPING, bTmp);
+ }
+ break;
+ case HANDLE_CHANGES_PASSWORD:
+ {
+ Sequence <sal_Int8> aNew;
+ if(rValue >>= aNew)
+ {
+ mpDoc->getIDocumentRedlineAccess().SetRedlinePassword(aNew);
+ if(aNew.hasElements())
+ {
+ RedlineFlags eMode = mpDoc->getIDocumentRedlineAccess().GetRedlineFlags();
+ eMode |= RedlineFlags::On;
+ mpDoc->getIDocumentRedlineAccess().SetRedlineFlags( eMode );
+ }
+ }
+ }
+ break;
+ case HANDLE_CONSIDER_WRAP_ON_OBJPOS:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION, bTmp );
+ }
+ break;
+ case HANDLE_IGNORE_FIRST_LINE_INDENT_IN_NUMBERING:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING, bTmp);
+ }
+ break;
+ case HANDLE_DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, bTmp);
+ }
+ break;
+ case HANDLE_DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT, bTmp);
+ }
+ break;
+ case HANDLE_TABLE_ROW_KEEP:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::TABLE_ROW_KEEP, bTmp);
+ }
+ break;
+ case HANDLE_IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION, bTmp);
+ }
+ break;
+ case HANDLE_LOAD_READONLY:
+ {
+ mpDocSh->SetLoadReadonly( *o3tl::doAccess<bool>(rValue) );
+ }
+ break;
+ case HANDLE_DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE, bTmp);
+ }
+ break;
+ case HANDLE_CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAMES:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAME, bTmp);
+ }
+ break;
+ case HANDLE_UNIX_FORCE_ZERO_EXT_LEADING:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::UNIX_FORCE_ZERO_EXT_LEADING, bTmp);
+ }
+ break;
+ case HANDLE_USE_OLD_PRINTER_METRICS:
+ // ignore - this is a dead property
+ break;
+ case HANDLE_TABS_RELATIVE_TO_INDENT:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::TABS_RELATIVE_TO_INDENT, bTmp);
+ }
+ break;
+ case HANDLE_RSID:
+ {
+ sal_uInt32 nTmp = 0;
+ rValue >>= nTmp;
+ mpDoc->setRsid( nTmp );
+ }
+ break;
+ case HANDLE_RSID_ROOT:
+ {
+ sal_uInt32 nTmp = 0;
+ rValue >>= nTmp;
+ mpDoc->setRsidRoot( nTmp );
+ }
+ break;
+ case HANDLE_PROTECT_FORM:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::PROTECT_FORM, bTmp);
+ }
+ break;
+ case HANDLE_MS_WORD_COMP_TRAILING_BLANKS:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS, bTmp);
+ }
+ break;
+ case HANDLE_MS_WORD_COMP_MIN_LINE_HEIGHT_BY_FLY:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::MS_WORD_COMP_MIN_LINE_HEIGHT_BY_FLY, bTmp);
+ }
+ break;
+ case HANDLE_TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST, bTmp);
+ }
+ break;
+ case HANDLE_MODIFYPASSWORDINFO:
+ {
+ uno::Sequence< beans::PropertyValue > aInfo;
+ if ( !( rValue >>= aInfo ) )
+ throw lang::IllegalArgumentException(
+ "Value of type Sequence<PropertyValue> expected!",
+ uno::Reference< uno::XInterface >(),
+ 2 );
+
+ if ( !mpDocSh->SetModifyPasswordInfo( aInfo ) )
+ throw beans::PropertyVetoException(
+ "The hash is not allowed to be changed now!",
+ uno::Reference< uno::XInterface >() );
+ }
+ break;
+ case HANDLE_MATH_BASELINE_ALIGNMENT:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set( DocumentSettingId::MATH_BASELINE_ALIGNMENT, bTmp );
+ }
+ break;
+ case HANDLE_INVERT_BORDER_SPACING:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::INVERT_BORDER_SPACING, bTmp);
+ }
+ break;
+ case HANDLE_COLLAPSE_EMPTY_CELL_PARA:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::COLLAPSE_EMPTY_CELL_PARA, bTmp);
+ }
+ break;
+ case HANDLE_SMALL_CAPS_PERCENTAGE_66:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::SMALL_CAPS_PERCENTAGE_66, bTmp);
+ }
+ break;
+ case HANDLE_TAB_OVERFLOW:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::TAB_OVERFLOW, bTmp);
+ }
+ break;
+ case HANDLE_UNBREAKABLE_NUMBERINGS:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::UNBREAKABLE_NUMBERINGS, bTmp);
+ }
+ break;
+ case HANDLE_STYLES_NODEFAULT:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::STYLES_NODEFAULT, bTmp);
+ }
+ break;
+ case HANDLE_FLOATTABLE_NOMARGINS:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::FLOATTABLE_NOMARGINS, bTmp);
+ }
+ break;
+ case HANDLE_CLIPPED_PICTURES:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::CLIPPED_PICTURES, bTmp);
+ }
+ break;
+ case HANDLE_BACKGROUND_PARA_OVER_DRAWINGS:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::BACKGROUND_PARA_OVER_DRAWINGS, bTmp);
+ }
+ break;
+ case HANDLE_EMBED_FONTS:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::EMBED_FONTS, bTmp);
+ }
+ break;
+ case HANDLE_EMBED_USED_FONTS:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::EMBED_USED_FONTS, bTmp);
+ }
+ break;
+ case HANDLE_EMBED_LATIN_SCRIPT_FONTS:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::EMBED_LATIN_SCRIPT_FONTS, bTmp);
+ }
+ break;
+ case HANDLE_EMBED_ASIAN_SCRIPT_FONTS:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::EMBED_ASIAN_SCRIPT_FONTS, bTmp);
+ }
+ break;
+ case HANDLE_EMBED_COMPLEX_SCRIPT_FONTS:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::EMBED_COMPLEX_SCRIPT_FONTS, bTmp);
+ }
+ break;
+ case HANDLE_EMBED_SYSTEM_FONTS:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::EMBED_SYSTEM_FONTS, bTmp);
+ }
+ break;
+ case HANDLE_TAB_OVER_MARGIN:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::TAB_OVER_MARGIN, bTmp);
+ }
+ break;
+ case HANDLE_TAB_OVER_SPACING:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::TAB_OVER_SPACING, bTmp);
+ }
+ break;
+ case HANDLE_TREAT_SINGLE_COLUMN_BREAK_AS_PAGE_BREAK:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::TREAT_SINGLE_COLUMN_BREAK_AS_PAGE_BREAK, bTmp);
+ }
+ break;
+ case HANDLE_SURROUND_TEXT_WRAP_SMALL:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::SURROUND_TEXT_WRAP_SMALL, bTmp);
+ }
+ break;
+ case HANDLE_APPLY_PARAGRAPH_MARK_FORMAT_TO_NUMBERING:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(rValue);
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::APPLY_PARAGRAPH_MARK_FORMAT_TO_NUMBERING, bTmp);
+ }
+ break;
+ case HANDLE_PROP_LINE_SPACING_SHRINKS_FIRST_LINE:
+ {
+ bool bTmp;
+ if (rValue >>= bTmp)
+ {
+ mpDoc->getIDocumentSettingAccess().set(
+ DocumentSettingId::PROP_LINE_SPACING_SHRINKS_FIRST_LINE, bTmp);
+ }
+ }
+ break;
+ case HANDLE_SUBTRACT_FLYS:
+ {
+ bool bTmp;
+ if (rValue >>= bTmp)
+ {
+ mpDoc->getIDocumentSettingAccess().set(
+ DocumentSettingId::SUBTRACT_FLYS, bTmp);
+ }
+ }
+ break;
+ case HANDLE_DISABLE_OFF_PAGE_POSITIONING:
+ {
+ bool bTmp;
+ if (rValue >>= bTmp)
+ {
+ mpDoc->getIDocumentSettingAccess().set(
+ DocumentSettingId::DISABLE_OFF_PAGE_POSITIONING, bTmp);
+ }
+ }
+ break;
+ case HANDLE_EMPTY_DB_FIELD_HIDES_PARA:
+ {
+ bool bTmp;
+ if (rValue >>= bTmp)
+ {
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA,
+ bTmp);
+ }
+ }
+ break;
+ case HANDLE_CONTINUOUS_ENDNOTES:
+ {
+ bool bTmp;
+ if (rValue >>= bTmp)
+ {
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::CONTINUOUS_ENDNOTES,
+ bTmp);
+ }
+ }
+ break;
+ case HANDLE_PROTECT_BOOKMARKS:
+ {
+ bool bTmp;
+ if (rValue >>= bTmp)
+ {
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::PROTECT_BOOKMARKS,
+ bTmp);
+ }
+ }
+ break;
+ case HANDLE_PROTECT_FIELDS:
+ {
+ bool bTmp;
+ if (rValue >>= bTmp)
+ {
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::PROTECT_FIELDS,
+ bTmp);
+ }
+ }
+ break;
+ case HANDLE_HEADER_SPACING_BELOW_LAST_PARA:
+ {
+ bool bTmp;
+ if (rValue >>= bTmp)
+ {
+ mpDoc->getIDocumentSettingAccess().set(
+ DocumentSettingId::HEADER_SPACING_BELOW_LAST_PARA, bTmp);
+ }
+ }
+ break;
+ case HANDLE_FRAME_AUTOWIDTH_WITH_MORE_PARA:
+ {
+ bool bTmp;
+ if (rValue >>= bTmp)
+ {
+ mpDoc->getIDocumentSettingAccess().set(
+ DocumentSettingId::FRAME_AUTOWIDTH_WITH_MORE_PARA, bTmp);
+ }
+ }
+ break;
+ case HANDLE_GUTTER_AT_TOP:
+ {
+ bool bTmp;
+ if (rValue >>= bTmp)
+ {
+ mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::GUTTER_AT_TOP, bTmp);
+ }
+ }
+ break;
+ case HANDLE_FOOTNOTE_IN_COLUMN_TO_PAGEEND:
+ {
+ bool bTmp;
+ if (rValue >>= bTmp)
+ {
+ mpDoc->getIDocumentSettingAccess().set(
+ DocumentSettingId::FOOTNOTE_IN_COLUMN_TO_PAGEEND, bTmp);
+ }
+ }
+ break;
+ case HANDLE_IMAGE_PREFERRED_DPI:
+ {
+ sal_uInt32 nValue = 0;
+ if (rValue >>= nValue)
+ {
+ mpDoc->getIDocumentSettingAccess().setImagePreferredDPI(nValue);
+ }
+ }
+ break;
+ case HANDLE_AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE:
+ {
+ bool bTmp;
+ if (rValue >>= bTmp)
+ {
+ mpDoc->getIDocumentSettingAccess().set(
+ DocumentSettingId::AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE, bTmp);
+ }
+ }
+ break;
+ case HANDLE_WORD_LIKE_WRAP_FOR_AS_CHAR_FLYS:
+ {
+ bool bValue = false;
+ if (rValue >>= bValue)
+ mpDoc->getIDocumentSettingAccess().set(
+ DocumentSettingId::WRAP_AS_CHAR_FLYS_LIKE_IN_OOXML, bValue);
+ }
+ break;
+ case HANDLE_NO_NUMBERING_SHOW_FOLLOWBY:
+ {
+ bool bValue = false;
+ if (rValue >>= bValue)
+ mpDoc->getIDocumentSettingAccess().set(
+ DocumentSettingId::NO_NUMBERING_SHOW_FOLLOWBY, bValue);
+ }
+ break;
+ default:
+ throw UnknownPropertyException(OUString::number(rInfo.mnHandle));
+ }
+}
+
+void SwXDocumentSettings::_postSetValues ()
+{
+ // set printer only once, namely here!
+ if( mpPrinter != nullptr )
+ {
+ // #i86352# the printer is also used as container for options by sfx
+ // when setting a printer it should have decent default options
+ SfxItemSet aOptions( mpPrinter->GetOptions() );
+ SwPrintData aPrtData( mpDoc->getIDocumentDeviceAccess().getPrintData() );
+ SwAddPrinterItem aAddPrinterItem (aPrtData);
+ aOptions.Put(aAddPrinterItem);
+ mpPrinter->SetOptions( aOptions );
+ mpPrinter->SetPrinterSettingsPreferred( mbPreferPrinterPapersize );
+
+ mpDoc->getIDocumentDeviceAccess().setPrinter( mpPrinter, true, true );
+ }
+
+ mpPrinter = nullptr;
+ mpDocSh = nullptr;
+ mpDoc = nullptr;
+}
+
+void SwXDocumentSettings::_preGetValues ()
+{
+ mpDocSh = mpModel->GetDocShell();
+ if (nullptr == mpDocSh)
+ throw UnknownPropertyException();
+ mpDoc = mpDocSh->GetDoc();
+ if (nullptr == mpDoc)
+ throw UnknownPropertyException();
+}
+
+void SwXDocumentSettings::_getSingleValue( const comphelper::PropertyInfo & rInfo, uno::Any & rValue )
+{
+ switch( rInfo.mnHandle )
+ {
+ case HANDLE_FORBIDDEN_CHARS:
+ {
+ Reference<XForbiddenCharacters> xRet(*mpModel->GetPropertyHelper(), UNO_QUERY);
+ rValue <<= xRet;
+ }
+ break;
+ case HANDLE_LINK_UPDATE_MODE:
+ {
+ rValue <<= static_cast < sal_Int16 > ( mpDoc->getIDocumentSettingAccess().getLinkUpdateMode(true) );
+ }
+ break;
+ case HANDLE_FIELD_AUTO_UPDATE:
+ {
+ SwFieldUpdateFlags nFlags = mpDoc->getIDocumentSettingAccess().getFieldUpdateFlags(true);
+ rValue <<= nFlags == AUTOUPD_FIELD_ONLY || nFlags == AUTOUPD_FIELD_AND_CHARTS;
+ }
+ break;
+ case HANDLE_CHART_AUTO_UPDATE:
+ {
+ SwFieldUpdateFlags nFlags = mpDoc->getIDocumentSettingAccess().getFieldUpdateFlags(true);
+ rValue <<= nFlags == AUTOUPD_FIELD_AND_CHARTS;
+ }
+ break;
+ case HANDLE_ADD_PARA_TABLE_SPACING:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::PARA_SPACE_MAX);
+ }
+ break;
+ case HANDLE_ADD_PARA_TABLE_SPACING_AT_START:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::PARA_SPACE_MAX_AT_PAGES);
+ }
+ break;
+ case HANDLE_ALIGN_TAB_STOP_POSITION:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::TAB_COMPAT);
+ }
+ break;
+ case HANDLE_PRINTER_NAME:
+ {
+ SfxPrinter *pPrinter = mpDoc->getIDocumentDeviceAccess().getPrinter( false );
+ rValue <<= pPrinter ? pPrinter->GetName() : OUString();
+ }
+ break;
+ case HANDLE_PRINTER_SETUP:
+ {
+ SfxPrinter *pPrinter = mpDoc->getIDocumentDeviceAccess().getPrinter( false );
+ if (pPrinter)
+ {
+ SvMemoryStream aStream;
+ pPrinter->Store( aStream );
+ sal_uInt32 nSize = aStream.TellEnd();
+ aStream.Seek ( STREAM_SEEK_TO_BEGIN );
+ Sequence < sal_Int8 > aSequence( nSize );
+ aStream.ReadBytes(aSequence.getArray(), nSize);
+ rValue <<= aSequence;
+ }
+ else
+ {
+ Sequence < sal_Int8 > aSequence ( 0 );
+ rValue <<= aSequence;
+ }
+ }
+ break;
+ case HANDLE_PRINTER_PAPER:
+ {
+ SfxPrinter *pTempPrinter = mpDoc->getIDocumentDeviceAccess().getPrinter( false );
+ rValue <<= pTempPrinter && pTempPrinter->GetPrinterSettingsPreferred();
+ }
+ break;
+ case HANDLE_IS_KERN_ASIAN_PUNCTUATION:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::KERN_ASIAN_PUNCTUATION);
+ }
+ break;
+ case HANDLE_APPLY_USER_DATA:
+ {
+ rValue <<= mpDocSh->IsUseUserData();
+ }
+ break;
+ case HANDLE_SAVE_THUMBNAIL:
+ {
+ rValue <<= mpDocSh->IsUseThumbnailSave();
+ }
+ break;
+ case HANDLE_CHARACTER_COMPRESSION_TYPE:
+ {
+ rValue <<= static_cast < sal_Int16 > (mpDoc->getIDocumentSettingAccess().getCharacterCompressionType());
+ }
+ break;
+ case HANDLE_SAVE_GLOBAL_DOCUMENT_LINKS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT_SAVE_LINKS);
+ }
+ break;
+ case HANDLE_CURRENT_DATABASE_DATA_SOURCE:
+ {
+ const SwDBData& rData = mpDoc->GetDBData();
+ rValue <<= rData.sDataSource;
+ }
+ break;
+ case HANDLE_CURRENT_DATABASE_COMMAND:
+ {
+ const SwDBData& rData = mpDoc->GetDBData();
+ rValue <<= rData.sCommand;
+ }
+ break;
+ case HANDLE_CURRENT_DATABASE_COMMAND_TYPE:
+ {
+ const SwDBData& rData = mpDoc->GetDBData();
+ rValue <<= rData.nCommandType;
+ }
+ break;
+ case HANDLE_EMBEDDED_DATABASE_NAME:
+ {
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ rValue <<= mpDoc->GetDBManager()->getEmbeddedName();
+#else
+ rValue = uno::Any();
+#endif
+ }
+ break;
+ case HANDLE_SAVE_VERSION_ON_CLOSE:
+ {
+ rValue <<= mpDocSh->IsSaveVersionOnClose();
+ }
+ break;
+ case HANDLE_UPDATE_FROM_TEMPLATE:
+ {
+ rValue <<= mpDocSh->IsQueryLoadTemplate();
+ }
+ break;
+ case HANDLE_PRINTER_INDEPENDENT_LAYOUT:
+ {
+ // returns short (see css.document.PrinterIndependentLayout)
+ sal_Int16 nVirDevType = mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::USE_VIRTUAL_DEVICE) ?
+ ( mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::USE_HIRES_VIRTUAL_DEVICE) ?
+ document::PrinterIndependentLayout::HIGH_RESOLUTION :
+ document::PrinterIndependentLayout::LOW_RESOLUTION ) :
+ document::PrinterIndependentLayout::DISABLED;
+ rValue <<= nVirDevType;
+ }
+ break;
+ case HANDLE_IS_LABEL_DOC:
+ {
+ bool bLabel = mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::LABEL_DOCUMENT);
+ rValue <<= bLabel;
+ }
+ break;
+ case HANDLE_IS_ADD_FLY_OFFSET:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::ADD_FLY_OFFSETS);
+ }
+ break;
+ case HANDLE_IS_ADD_VERTICAL_FLY_OFFSET:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::ADD_VERTICAL_FLY_OFFSETS);
+ }
+ break;
+ case HANDLE_IS_ADD_EXTERNAL_LEADING:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::ADD_EXT_LEADING);
+ }
+ break;
+ case HANDLE_OLD_NUMBERING:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::OLD_NUMBERING);
+ }
+ break;
+ case HANDLE_OUTLINELEVEL_YIELDS_NUMBERING:
+ {
+ rValue <<= false;
+ }
+ break;
+ case HANDLE_ALLOW_PRINTJOB_CANCEL:
+ {
+ rValue <<= mpDocSh->Stamp_GetPrintCancelState();
+ }
+ break;
+ case HANDLE_USE_FORMER_LINE_SPACING:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::OLD_LINE_SPACING);
+ }
+ break;
+ case HANDLE_ADD_PARA_SPACING_TO_TABLE_CELLS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::ADD_PARA_SPACING_TO_TABLE_CELLS);
+ }
+ break;
+ case HANDLE_ADD_PARA_LINE_SPACING_TO_TABLE_CELLS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::ADD_PARA_LINE_SPACING_TO_TABLE_CELLS);
+ }
+ break;
+ case HANDLE_USE_FORMER_OBJECT_POSITIONING:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::USE_FORMER_OBJECT_POS);
+ }
+ break;
+ case HANDLE_USE_FORMER_TEXT_WRAPPING:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING);
+ }
+ break;
+ case HANDLE_CHANGES_PASSWORD:
+ {
+ rValue <<= mpDoc->getIDocumentRedlineAccess().GetRedlinePassword();
+ }
+ break;
+ case HANDLE_CONSIDER_WRAP_ON_OBJPOS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION);
+ }
+ break;
+ case HANDLE_IGNORE_FIRST_LINE_INDENT_IN_NUMBERING:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING);
+ }
+ break;
+ case HANDLE_DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK);
+ }
+ break;
+ case HANDLE_DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT);
+ }
+ break;
+ case HANDLE_TABLE_ROW_KEEP :
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::TABLE_ROW_KEEP);
+ }
+ break;
+ case HANDLE_IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION);
+ }
+ break;
+ case HANDLE_LOAD_READONLY:
+ {
+ rValue <<= mpDocSh->IsLoadReadonly();
+ }
+ break;
+ case HANDLE_DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE);
+ }
+ break;
+ case HANDLE_CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAMES:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAME);
+ }
+ break;
+ case HANDLE_UNIX_FORCE_ZERO_EXT_LEADING:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::UNIX_FORCE_ZERO_EXT_LEADING);
+ }
+ break;
+ case HANDLE_USE_OLD_PRINTER_METRICS:
+ {
+ rValue <<= false;
+ }
+ break;
+ case HANDLE_TABS_RELATIVE_TO_INDENT:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::TABS_RELATIVE_TO_INDENT);
+ }
+ break;
+ case HANDLE_RSID:
+ {
+ rValue <<= static_cast < sal_Int32 > ( mpDoc->getRsid() );
+ }
+ break;
+ case HANDLE_RSID_ROOT:
+ {
+ rValue <<= static_cast < sal_Int32 > ( mpDoc->getRsidRoot() );
+ }
+ break;
+ case HANDLE_PROTECT_FORM:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_FORM);
+ }
+ break;
+ case HANDLE_MS_WORD_COMP_TRAILING_BLANKS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS);
+ }
+ break;
+ case HANDLE_MS_WORD_COMP_MIN_LINE_HEIGHT_BY_FLY:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::MS_WORD_COMP_MIN_LINE_HEIGHT_BY_FLY);
+ }
+ break;
+ case HANDLE_TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST);
+ }
+ break;
+ case HANDLE_MODIFYPASSWORDINFO:
+ {
+ rValue <<= mpDocSh->GetModifyPasswordInfo();
+ }
+ break;
+ case HANDLE_MATH_BASELINE_ALIGNMENT:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::MATH_BASELINE_ALIGNMENT );
+ }
+ break;
+ case HANDLE_INVERT_BORDER_SPACING:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::INVERT_BORDER_SPACING);
+ }
+ break;
+ case HANDLE_COLLAPSE_EMPTY_CELL_PARA:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::COLLAPSE_EMPTY_CELL_PARA );
+ }
+ break;
+ case HANDLE_SMALL_CAPS_PERCENTAGE_66:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::SMALL_CAPS_PERCENTAGE_66 );
+ }
+ break;
+ case HANDLE_TAB_OVERFLOW:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::TAB_OVERFLOW );
+ }
+ break;
+ case HANDLE_UNBREAKABLE_NUMBERINGS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::UNBREAKABLE_NUMBERINGS );
+ }
+ break;
+ case HANDLE_STYLES_NODEFAULT:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::STYLES_NODEFAULT );
+ }
+ break;
+ case HANDLE_FLOATTABLE_NOMARGINS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::FLOATTABLE_NOMARGINS );
+ }
+ break;
+ case HANDLE_CLIPPED_PICTURES:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::CLIPPED_PICTURES );
+ }
+ break;
+ case HANDLE_BACKGROUND_PARA_OVER_DRAWINGS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::BACKGROUND_PARA_OVER_DRAWINGS );
+ }
+ break;
+ case HANDLE_EMBED_FONTS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::EMBED_FONTS );
+ }
+ break;
+ case HANDLE_EMBED_USED_FONTS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::EMBED_USED_FONTS );
+ }
+ break;
+ case HANDLE_EMBED_LATIN_SCRIPT_FONTS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::EMBED_LATIN_SCRIPT_FONTS );
+ }
+ break;
+ case HANDLE_EMBED_ASIAN_SCRIPT_FONTS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::EMBED_ASIAN_SCRIPT_FONTS );
+ }
+ break;
+ case HANDLE_EMBED_COMPLEX_SCRIPT_FONTS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::EMBED_COMPLEX_SCRIPT_FONTS );
+ }
+ break;
+ case HANDLE_EMBED_SYSTEM_FONTS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::EMBED_SYSTEM_FONTS );
+ }
+ break;
+ case HANDLE_TAB_OVER_MARGIN:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::TAB_OVER_MARGIN );
+ }
+ break;
+ case HANDLE_TAB_OVER_SPACING:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::TAB_OVER_SPACING);
+ }
+ break;
+ case HANDLE_TREAT_SINGLE_COLUMN_BREAK_AS_PAGE_BREAK:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::TREAT_SINGLE_COLUMN_BREAK_AS_PAGE_BREAK );
+ }
+ break;
+ case HANDLE_SURROUND_TEXT_WRAP_SMALL:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::SURROUND_TEXT_WRAP_SMALL );
+ }
+ break;
+ case HANDLE_APPLY_PARAGRAPH_MARK_FORMAT_TO_NUMBERING:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get( DocumentSettingId::APPLY_PARAGRAPH_MARK_FORMAT_TO_NUMBERING );
+ }
+ break;
+ case HANDLE_PROP_LINE_SPACING_SHRINKS_FIRST_LINE:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::PROP_LINE_SPACING_SHRINKS_FIRST_LINE);
+ }
+ break;
+ case HANDLE_SUBTRACT_FLYS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::SUBTRACT_FLYS);
+ }
+ break;
+ case HANDLE_DISABLE_OFF_PAGE_POSITIONING:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::DISABLE_OFF_PAGE_POSITIONING);
+ }
+ break;
+ case HANDLE_EMPTY_DB_FIELD_HIDES_PARA:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(
+ DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA);
+ }
+ break;
+ case HANDLE_CONTINUOUS_ENDNOTES:
+ {
+ rValue
+ <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::CONTINUOUS_ENDNOTES);
+ }
+ break;
+ case HANDLE_PROTECT_BOOKMARKS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(
+ DocumentSettingId::PROTECT_BOOKMARKS);
+ }
+ break;
+ case HANDLE_PROTECT_FIELDS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(
+ DocumentSettingId::PROTECT_FIELDS);
+ }
+ break;
+ case HANDLE_HEADER_SPACING_BELOW_LAST_PARA:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(
+ DocumentSettingId::HEADER_SPACING_BELOW_LAST_PARA);
+ }
+ break;
+ case HANDLE_FRAME_AUTOWIDTH_WITH_MORE_PARA:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(
+ DocumentSettingId::FRAME_AUTOWIDTH_WITH_MORE_PARA);
+ }
+ break;
+ case HANDLE_GUTTER_AT_TOP:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::GUTTER_AT_TOP);
+ }
+ break;
+ case HANDLE_FOOTNOTE_IN_COLUMN_TO_PAGEEND:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(
+ DocumentSettingId::FOOTNOTE_IN_COLUMN_TO_PAGEEND);
+ }
+ break;
+ case HANDLE_IMAGE_PREFERRED_DPI:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().getImagePreferredDPI();
+ }
+ break;
+ case HANDLE_AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(
+ DocumentSettingId::AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE);
+ }
+ break;
+ case HANDLE_WORD_LIKE_WRAP_FOR_AS_CHAR_FLYS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(
+ DocumentSettingId::WRAP_AS_CHAR_FLYS_LIKE_IN_OOXML);
+ }
+ break;
+ case HANDLE_NO_NUMBERING_SHOW_FOLLOWBY:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(
+ DocumentSettingId::NO_NUMBERING_SHOW_FOLLOWBY);
+ }
+ break;
+ default:
+ throw UnknownPropertyException(OUString::number(rInfo.mnHandle));
+ }
+}
+
+void SwXDocumentSettings::_postGetValues ()
+{
+ mpDocSh = nullptr;
+ mpDoc = nullptr;
+}
+
+// XServiceInfo
+OUString SAL_CALL SwXDocumentSettings::getImplementationName( )
+{
+ return "SwXDocumentSettings";
+}
+
+sal_Bool SAL_CALL SwXDocumentSettings::supportsService( const OUString& ServiceName )
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+Sequence< OUString > SAL_CALL SwXDocumentSettings::getSupportedServiceNames( )
+{
+ return { "com.sun.star.document.Settings", "com.sun.star.text.DocumentSettings", "com.sun.star.text.PrintSettings" };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/uno/SwXDocumentSettings.hxx b/sw/source/uibase/uno/SwXDocumentSettings.hxx
new file mode 100644
index 000000000..3d722e40b
--- /dev/null
+++ b/sw/source/uibase/uno/SwXDocumentSettings.hxx
@@ -0,0 +1,78 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <comphelper/MasterPropertySet.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <cppuhelper/weak.hxx>
+#include <vcl/vclptr.hxx>
+
+class SwXTextDocument;
+class SwDocShell;
+class SwDoc;
+class SfxPrinter;
+
+class SwXDocumentSettings final :
+ public comphelper::MasterPropertySet,
+ public css::lang::XServiceInfo,
+ public css::lang::XTypeProvider,
+ public cppu::OWeakObject
+{
+ SwXTextDocument* mpModel;
+ SwDocShell* mpDocSh;
+ SwDoc* mpDoc;
+
+ /** the printer should be set only once; since there are several
+ * printer-related properties, remember the last printer and set it in
+ * _postSetValues */
+ VclPtr<SfxPrinter> mpPrinter;
+ bool mbPreferPrinterPapersize;
+
+ virtual void _preSetValues () override;
+ virtual void _setSingleValue( const comphelper::PropertyInfo & rInfo, const css::uno::Any &rValue ) override;
+ virtual void _postSetValues () override;
+
+ virtual void _preGetValues () override;
+ virtual void _getSingleValue( const comphelper::PropertyInfo & rInfo, css::uno::Any & rValue ) override;
+ virtual void _postGetValues () override;
+ virtual ~SwXDocumentSettings()
+ noexcept override;
+public:
+ SwXDocumentSettings( SwXTextDocument* pModel );
+
+ // XInterface
+ virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) override;
+ virtual void SAL_CALL acquire( )
+ noexcept override;
+ virtual void SAL_CALL release( )
+ noexcept override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName( ) override;
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
+
+ // XTypeProvider
+ virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes( ) override;
+ virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/uno/SwXFilterOptions.cxx b/sw/source/uibase/uno/SwXFilterOptions.cxx
new file mode 100644
index 000000000..124b8abf8
--- /dev/null
+++ b/sw/source/uibase/uno/SwXFilterOptions.cxx
@@ -0,0 +1,147 @@
+/* -*- 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 <SwXFilterOptions.hxx>
+#include <shellio.hxx>
+#include <swdll.hxx>
+#include <vcl/svapp.hxx>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <comphelper/namedvaluecollection.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotxdoc.hxx>
+
+#include <swabstdlg.hxx>
+#include <memory>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::lang;
+
+constexpr OUStringLiteral FILTER_OPTIONS_NAME = u"FilterOptions";
+
+SwXFilterOptions::SwXFilterOptions()
+{
+}
+
+SwXFilterOptions::~SwXFilterOptions()
+{
+}
+
+uno::Sequence< beans::PropertyValue > SwXFilterOptions::getPropertyValues()
+{
+ return comphelper::InitPropertySequence({
+ { FILTER_OPTIONS_NAME, uno::Any(m_sFilterOptions) }
+ });
+}
+
+void SwXFilterOptions::setPropertyValues( const uno::Sequence<beans::PropertyValue >& aProps )
+{
+ for (const beans::PropertyValue& rProp : aProps)
+ {
+ OUString aPropName = rProp.Name;
+
+ if ( aPropName == FILTER_OPTIONS_NAME )
+ rProp.Value >>= m_sFilterOptions;
+ else if ( aPropName == "InputStream" )
+ rProp.Value >>= m_xInputStream;
+ }
+}
+
+void SwXFilterOptions::setTitle( const OUString& /*rTitle*/ )
+{
+}
+
+sal_Int16 SwXFilterOptions::execute()
+{
+ sal_Int16 nRet = ui::dialogs::ExecutableDialogResults::CANCEL;
+
+ std::unique_ptr<SvStream> pInStream;
+ if ( m_xInputStream.is() )
+ pInStream = utl::UcbStreamHelper::CreateStream( m_xInputStream );
+
+ SwDocShell* pDocShell = nullptr;
+ if (auto pXDoc = comphelper::getFromUnoTunnel<SwXTextDocument>(m_xModel); pXDoc)
+ pDocShell = pXDoc->GetDocShell();
+
+ if(pDocShell)
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSwAsciiFilterDlg> pAsciiDlg(pFact->CreateSwAsciiFilterDlg(Application::GetFrameWeld(m_xDialogParent), *pDocShell,
+ pInStream.get()));
+ if(RET_OK == pAsciiDlg->Execute())
+ {
+ SwAsciiOptions aOptions;
+ pAsciiDlg->FillOptions( aOptions );
+ aOptions.WriteUserData(m_sFilterOptions);
+ nRet = ui::dialogs::ExecutableDialogResults::OK;
+ }
+ }
+
+ return nRet;
+}
+
+void SwXFilterOptions::setTargetDocument( const uno::Reference< XComponent >& xDoc )
+{
+ m_xModel = xDoc;
+}
+
+void SwXFilterOptions::setSourceDocument( const uno::Reference<XComponent >& xDoc )
+{
+ m_xModel = xDoc;
+}
+
+void SAL_CALL SwXFilterOptions::initialize(const uno::Sequence<uno::Any>& rArguments)
+{
+ ::comphelper::NamedValueCollection aProperties(rArguments);
+ if (aProperties.has("ParentWindow"))
+ aProperties.get("ParentWindow") >>= m_xDialogParent;
+}
+
+OUString SwXFilterOptions::getImplementationName()
+{
+ return "com.sun.star.comp.Writer.FilterOptionsDialog";
+}
+
+sal_Bool SwXFilterOptions::supportsService( const OUString& rServiceName )
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SwXFilterOptions::getSupportedServiceNames()
+{
+ return { "com.sun.star.ui.dialogs.FilterOptionsDialog" };
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+com_sun_star_comp_Writer_FilterOptionsDialog_get_implementation(css::uno::XComponentContext*,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ SolarMutexGuard aGuard;
+
+ //the module may not be loaded
+ SwGlobals::ensure();
+ return cppu::acquire(new SwXFilterOptions());
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/uno/dlelstnr.cxx b/sw/source/uibase/uno/dlelstnr.cxx
new file mode 100644
index 000000000..60b11fc4d
--- /dev/null
+++ b/sw/source/uibase/uno/dlelstnr.cxx
@@ -0,0 +1,134 @@
+/* -*- 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 <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/linguistic2/LinguServiceManager.hpp>
+#include <com/sun/star/linguistic2/XLinguServiceEventBroadcaster.hpp>
+#include <com/sun/star/linguistic2/XProofreadingIterator.hpp>
+#include <com/sun/star/linguistic2/LinguServiceEventFlags.hpp>
+
+#include <unotools/lingucfg.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <com/sun/star/uno/Reference.h>
+#include <comphelper/processfactory.hxx>
+#include <vcl/svapp.hxx>
+#include <dlelstnr.hxx>
+#include <proofreadingiterator.hxx>
+#include <swmodule.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::linguistic2;
+using namespace ::com::sun::star::linguistic2::LinguServiceEventFlags;
+
+SwLinguServiceEventListener::SwLinguServiceEventListener()
+{
+ Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
+ try
+ {
+ m_xDesktop = frame::Desktop::create(xContext);
+ m_xDesktop->addTerminateListener( this );
+
+ m_xLngSvcMgr = LinguServiceManager::create(xContext);
+ m_xLngSvcMgr->addLinguServiceManagerListener( static_cast<XLinguServiceEventListener *>(this) );
+
+ if (SvtLinguConfig().HasGrammarChecker())
+ {
+ m_xGCIterator = sw::proofreadingiterator::get(xContext);
+ Reference< XLinguServiceEventBroadcaster > xBC( m_xGCIterator, UNO_QUERY );
+ if (xBC.is())
+ xBC->addLinguServiceEventListener( static_cast<XLinguServiceEventListener *>(this) );
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "sw", "SwLinguServiceEventListener c-tor" );
+ }
+}
+
+SwLinguServiceEventListener::~SwLinguServiceEventListener()
+{
+}
+
+void SAL_CALL SwLinguServiceEventListener::processLinguServiceEvent(
+ const LinguServiceEvent& rLngSvcEvent )
+{
+ SolarMutexGuard aGuard;
+
+ bool bIsSpellWrong = 0 != (rLngSvcEvent.nEvent & SPELL_WRONG_WORDS_AGAIN);
+ bool bIsSpellAll = 0 != (rLngSvcEvent.nEvent & SPELL_CORRECT_WORDS_AGAIN);
+ if (0 != (rLngSvcEvent.nEvent & PROOFREAD_AGAIN))
+ bIsSpellWrong = bIsSpellAll = true; // have all spelling and grammar checked...
+ if (bIsSpellWrong || bIsSpellAll)
+ {
+ SwModule::CheckSpellChanges( false, bIsSpellWrong, bIsSpellAll, false );
+ }
+ if (!(rLngSvcEvent.nEvent & HYPHENATE_AGAIN))
+ return;
+
+ SwView *pSwView = SwModule::GetFirstView();
+
+ //!! since this function may be called within the ctor of
+ //!! SwView (during formatting) where the WrtShell is not yet
+ //!! created, we have to check for the WrtShellPtr to see
+ //!! if it is already available
+ while (pSwView && pSwView->GetWrtShellPtr())
+ {
+ pSwView->GetWrtShell().ChgHyphenation();
+ pSwView = SwModule::GetNextView( pSwView );
+ }
+}
+
+void SAL_CALL SwLinguServiceEventListener::disposing(
+ const EventObject& rEventObj )
+{
+ SolarMutexGuard aGuard;
+
+ if (m_xLngSvcMgr.is() && rEventObj.Source == m_xLngSvcMgr)
+ m_xLngSvcMgr = nullptr;
+ if (m_xLngSvcMgr.is() && rEventObj.Source == m_xGCIterator)
+ m_xGCIterator = nullptr;
+}
+
+void SAL_CALL SwLinguServiceEventListener::queryTermination(
+ const EventObject& /*rEventObj*/ )
+{
+}
+
+void SAL_CALL SwLinguServiceEventListener::notifyTermination(
+ const EventObject& rEventObj )
+{
+ SolarMutexGuard aGuard;
+
+ if (m_xDesktop.is() && rEventObj.Source == m_xDesktop)
+ {
+ if (m_xLngSvcMgr.is())
+ m_xLngSvcMgr = nullptr;
+ if (m_xGCIterator.is())
+ m_xGCIterator = nullptr;
+ m_xDesktop = nullptr;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/uno/unoatxt.cxx b/sw/source/uibase/uno/unoatxt.cxx
new file mode 100644
index 000000000..e9036718b
--- /dev/null
+++ b/sw/source/uibase/uno/unoatxt.cxx
@@ -0,0 +1,1018 @@
+/* -*- 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 <sal/config.h>
+
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/container/ElementExistException.hpp>
+#include <o3tl/safeint.hxx>
+#include <osl/diagnose.h>
+#include <rtl/character.hxx>
+#include <vcl/svapp.hxx>
+#include <svtools/unoevent.hxx>
+#include <sfx2/event.hxx>
+#include <glosdoc.hxx>
+#include <shellio.hxx>
+#include <initui.hxx>
+#include <gloslst.hxx>
+#include <unoatxt.hxx>
+#include <unomap.hxx>
+#include <unotextbodyhf.hxx>
+#include <unotextrange.hxx>
+#include <TextCursorHelper.hxx>
+#include <doc.hxx>
+#include <IDocumentContentOperations.hxx>
+#include <IDocumentRedlineAccess.hxx>
+#include <IDocumentFieldsAccess.hxx>
+#include <IDocumentState.hxx>
+#include <docsh.hxx>
+#include <swdll.hxx>
+#include <svl/hint.hxx>
+#include <tools/urlobj.hxx>
+#include <svl/macitem.hxx>
+#include <editeng/acorrcfg.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/supportsservice.hxx>
+
+#include <memory>
+
+using namespace ::com::sun::star;
+
+SwXAutoTextContainer::SwXAutoTextContainer()
+{
+ m_pGlossaries = ::GetGlossaries();
+
+}
+
+SwXAutoTextContainer::~SwXAutoTextContainer()
+{
+
+}
+
+sal_Int32 SwXAutoTextContainer::getCount()
+{
+ OSL_ENSURE(m_pGlossaries->GetGroupCnt() < o3tl::make_unsigned(SAL_MAX_INT32),
+ "SwXAutoTextContainer::getCount: too many items");
+ return static_cast<sal_Int32>(m_pGlossaries->GetGroupCnt());
+}
+
+uno::Any SwXAutoTextContainer::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ const size_t nCount = m_pGlossaries->GetGroupCnt();
+ if ( nIndex < 0 || o3tl::make_unsigned(nIndex) >= nCount )
+ throw lang::IndexOutOfBoundsException();
+ return getByName(m_pGlossaries->GetGroupName( static_cast<size_t>(nIndex) ));
+}
+
+uno::Type SwXAutoTextContainer::getElementType()
+{
+ return cppu::UnoType<text::XAutoTextGroup>::get();
+
+}
+
+sal_Bool SwXAutoTextContainer::hasElements()
+{
+ // At least standard should always exists!
+ return true;
+}
+
+uno::Any SwXAutoTextContainer::getByName(const OUString& GroupName)
+{
+ SolarMutexGuard aGuard;
+
+ uno::Reference< text::XAutoTextGroup > xGroup;
+ if ( m_pGlossaries && hasByName( GroupName ) ) // group name already known?
+ // true = create group if not already available
+ xGroup = m_pGlossaries->GetAutoTextGroup( GroupName );
+
+ if ( !xGroup.is() )
+ throw container::NoSuchElementException();
+
+ return css::uno::Any( xGroup );
+}
+
+uno::Sequence< OUString > SwXAutoTextContainer::getElementNames()
+{
+ SolarMutexGuard aGuard;
+ const size_t nCount = m_pGlossaries->GetGroupCnt();
+ OSL_ENSURE(nCount < o3tl::make_unsigned(SAL_MAX_INT32),
+ "SwXAutoTextContainer::getElementNames: too many groups");
+
+ uno::Sequence< OUString > aGroupNames(static_cast<sal_Int32>(nCount));
+ OUString *pArr = aGroupNames.getArray();
+
+ for ( size_t i = 0; i < nCount; ++i )
+ {
+ // The names will be passed without a path extension.
+ pArr[i] = m_pGlossaries->GetGroupName(i).getToken(0, GLOS_DELIM);
+ }
+ return aGroupNames;
+}
+// Finds group names with or without path index.
+sal_Bool SwXAutoTextContainer::hasByName(const OUString& Name)
+{
+ SolarMutexGuard aGuard;
+ OUString sGroupName( m_pGlossaries->GetCompleteGroupName( Name ) );
+ if(!sGroupName.isEmpty())
+ return true;
+ return false;
+}
+
+uno::Reference< text::XAutoTextGroup > SwXAutoTextContainer::insertNewByName(
+ const OUString& aGroupName)
+{
+ SolarMutexGuard aGuard;
+ if(hasByName(aGroupName))
+ throw container::ElementExistException();
+ //check for non-ASCII characters
+ if(aGroupName.isEmpty())
+ {
+ lang::IllegalArgumentException aIllegal;
+ aIllegal.Message = "group name must not be empty";
+ throw aIllegal;
+ }
+ for(sal_Int32 nPos = 0; nPos < aGroupName.getLength(); nPos++)
+ {
+ sal_Unicode cChar = aGroupName[nPos];
+ if (rtl::isAsciiAlphanumeric(cChar) ||
+ (cChar == '_') ||
+ (cChar == 0x20) ||
+ (cChar == GLOS_DELIM) )
+ {
+ continue;
+ }
+ lang::IllegalArgumentException aIllegal;
+ aIllegal.Message = "group name must contain a-z, A-z, '_', ' ' only";
+ throw aIllegal;
+ }
+ OUString sGroup(aGroupName);
+ if (sGroup.indexOf(GLOS_DELIM)<0)
+ {
+ sGroup += OUStringChar(GLOS_DELIM) + "0";
+ }
+ m_pGlossaries->NewGroupDoc(sGroup, sGroup.getToken(0, GLOS_DELIM));
+
+ uno::Reference< text::XAutoTextGroup > xGroup = m_pGlossaries->GetAutoTextGroup( sGroup );
+ OSL_ENSURE( xGroup.is(), "SwXAutoTextContainer::insertNewByName: no UNO object created? How this?" );
+ // We just inserted the group into the glossaries, so why doesn't it exist?
+
+ return xGroup;
+}
+
+void SwXAutoTextContainer::removeByName(const OUString& aGroupName)
+{
+ SolarMutexGuard aGuard;
+ // At first find the name with path extension
+ OUString sGroupName = m_pGlossaries->GetCompleteGroupName( aGroupName );
+ if(sGroupName.isEmpty())
+ throw container::NoSuchElementException();
+ m_pGlossaries->DelGroupDoc(sGroupName);
+}
+
+OUString SwXAutoTextContainer::getImplementationName()
+{
+ return "SwXAutoTextContainer";
+}
+
+sal_Bool SwXAutoTextContainer::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SwXAutoTextContainer::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.AutoTextContainer" };
+}
+
+const uno::Sequence< sal_Int8 > & SwXAutoTextGroup::getUnoTunnelId()
+{
+ static const comphelper::UnoIdInit theSwXAutoTextGroupUnoTunnelId;
+ return theSwXAutoTextGroupUnoTunnelId.getSeq();
+}
+
+sal_Int64 SAL_CALL SwXAutoTextGroup::getSomething( const uno::Sequence< sal_Int8 >& rId )
+{
+ return comphelper::getSomethingImpl(rId, this);
+}
+
+SwXAutoTextGroup::SwXAutoTextGroup(const OUString& rName,
+ SwGlossaries* pGlos) :
+ m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_AUTO_TEXT_GROUP)),
+ m_pGlossaries(pGlos),
+ m_sName(rName),
+ m_sGroupName(rName)
+{
+ OSL_ENSURE( -1 != rName.indexOf( GLOS_DELIM ),
+ "SwXAutoTextGroup::SwXAutoTextGroup: to be constructed with a complete name only!" );
+}
+
+SwXAutoTextGroup::~SwXAutoTextGroup()
+{
+}
+
+uno::Sequence< OUString > SwXAutoTextGroup::getTitles()
+{
+ SolarMutexGuard aGuard;
+ std::unique_ptr<SwTextBlocks> pGlosGroup(m_pGlossaries ? m_pGlossaries->GetGroupDoc(m_sGroupName) : nullptr);
+ if (!pGlosGroup || pGlosGroup->GetError())
+ throw uno::RuntimeException();
+ const sal_uInt16 nCount = pGlosGroup->GetCount();
+
+ uno::Sequence< OUString > aEntryTitles(nCount);
+ OUString *pArr = aEntryTitles.getArray();
+
+ for ( sal_uInt16 i = 0; i < nCount; i++ )
+ pArr[i] = pGlosGroup->GetLongName(i);
+ return aEntryTitles;
+}
+
+void SwXAutoTextGroup::renameByName(const OUString& aElementName,
+ const OUString& aNewElementName, const OUString& aNewElementTitle)
+{
+ SolarMutexGuard aGuard;
+ // throw exception only if the programmatic name is to be changed into an existing name
+ if(aNewElementName != aElementName && hasByName(aNewElementName))
+ throw container::ElementExistException();
+ std::unique_ptr<SwTextBlocks> pGlosGroup(m_pGlossaries ? m_pGlossaries->GetGroupDoc(m_sGroupName) : nullptr);
+ if(!pGlosGroup || pGlosGroup->GetError())
+ throw uno::RuntimeException();
+
+ const sal_uInt16 nIdx = pGlosGroup->GetIndex( aElementName);
+ if(USHRT_MAX == nIdx)
+ throw lang::IllegalArgumentException();
+ OUString aNewShort(aNewElementName);
+ OUString aNewName(aNewElementTitle);
+ sal_uInt16 nOldLongIdx = pGlosGroup->GetLongIndex( aNewShort );
+ sal_uInt16 nOldIdx = pGlosGroup->GetIndex( aNewName );
+
+ if ((nOldLongIdx == USHRT_MAX || nOldLongIdx == nIdx)
+ && (nOldIdx == USHRT_MAX || nOldIdx == nIdx))
+ {
+ pGlosGroup->Rename( nIdx, &aNewShort, &aNewName );
+ if(pGlosGroup->GetError() != ERRCODE_NONE)
+ throw io::IOException();
+ }
+
+}
+
+static bool lcl_CopySelToDoc(SwDoc& rInsDoc, OTextCursorHelper* pxCursor, SwXTextRange* pxRange)
+{
+ SwNodes& rNds = rInsDoc.GetNodes();
+
+ SwNodeIndex aIdx( rNds.GetEndOfContent(), -1 );
+ SwContentNode * pNd = aIdx.GetNode().GetContentNode();
+ SwPosition aPos(aIdx, SwIndex(pNd, pNd ? pNd->Len() : 0));
+
+ bool bRet = false;
+ rInsDoc.getIDocumentFieldsAccess().LockExpFields();
+ {
+ SwDoc *const pDoc(pxCursor ? pxCursor->GetDoc() : &pxRange->GetDoc());
+ SwPaM aPam(pDoc->GetNodes());
+ SwPaM * pPam(nullptr);
+ if(pxCursor)
+ {
+ pPam = pxCursor->GetPaM();
+ }
+ else
+ {
+ if (pxRange->GetPositions(aPam))
+ {
+ pPam = & aPam;
+ }
+ }
+ if (!pPam) { return false; }
+ bRet = pDoc->getIDocumentContentOperations().CopyRange(*pPam, aPos, SwCopyFlags::CheckPosInFly)
+ || bRet;
+ }
+
+ rInsDoc.getIDocumentFieldsAccess().UnlockExpFields();
+ if( !rInsDoc.getIDocumentFieldsAccess().IsExpFieldsLocked() )
+ rInsDoc.getIDocumentFieldsAccess().UpdateExpFields(nullptr, true);
+
+ return bRet;
+}
+
+uno::Reference< text::XAutoTextEntry > SwXAutoTextGroup::insertNewByName(const OUString& aName,
+ const OUString& aTitle, const uno::Reference< text::XTextRange > & xTextRange)
+{
+ SolarMutexGuard aGuard;
+ if(hasByName(aName))
+ throw container::ElementExistException();
+ if(!xTextRange.is())
+ throw uno::RuntimeException();
+
+ std::unique_ptr<SwTextBlocks> pGlosGroup;
+ if (m_pGlossaries)
+ pGlosGroup = m_pGlossaries->GetGroupDoc(m_sGroupName);
+ const OUString& sShortName(aName);
+ const OUString& sLongName(aTitle);
+ if (pGlosGroup && !pGlosGroup->GetError())
+ {
+ uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
+ SwXTextRange* pxRange = comphelper::getFromUnoTunnel<SwXTextRange>(xRangeTunnel);
+ OTextCursorHelper* pxCursor = comphelper::getFromUnoTunnel<OTextCursorHelper>(xRangeTunnel);
+
+ OUString sOnlyText;
+ OUString* pOnlyText = nullptr;
+ bool bNoAttr = !pxCursor && !pxRange;
+ if(bNoAttr)
+ {
+ sOnlyText = xTextRange->getString();
+ pOnlyText = &sOnlyText;
+ }
+
+ const SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
+
+ SwDoc* pGDoc = pGlosGroup->GetDoc();
+
+ // Until there is an option for that, delete base util::URL
+ if(rCfg.IsSaveRelFile())
+ {
+ INetURLObject aTemp(pGlosGroup->GetFileName());
+ pGlosGroup->SetBaseURL( aTemp.GetMainURL(INetURLObject::DecodeMechanism::NONE));
+ }
+ else
+ pGlosGroup->SetBaseURL( OUString() );
+
+ sal_uInt16 nRet = USHRT_MAX;
+ if( pOnlyText )
+ nRet = pGlosGroup->PutText( sShortName, sLongName, *pOnlyText );
+ else
+ {
+ pGlosGroup->ClearDoc();
+ if( pGlosGroup->BeginPutDoc( sShortName, sLongName ) )
+ {
+ pGDoc->getIDocumentRedlineAccess().SetRedlineFlags_intern( RedlineFlags::DeleteRedlines );
+ lcl_CopySelToDoc(*pGDoc, pxCursor, pxRange);
+ pGDoc->getIDocumentRedlineAccess().SetRedlineFlags_intern(RedlineFlags::NONE);
+ nRet = pGlosGroup->PutDoc();
+ }
+ }
+
+ if (nRet == USHRT_MAX)
+ {
+ throw uno::RuntimeException();
+ }
+ }
+ pGlosGroup.reset();
+
+ uno::Reference< text::XAutoTextEntry > xEntry;
+
+ try
+ {
+ xEntry = m_pGlossaries ?
+ m_pGlossaries->GetAutoTextEntry( m_sGroupName, m_sName, sShortName ) :
+ uno::Reference< text::XAutoTextEntry >();
+ OSL_ENSURE( xEntry.is(), "SwXAutoTextGroup::insertNewByName: no UNO object created? How this?" );
+ // we just inserted the entry into the group, so why doesn't it exist?
+ }
+ catch (const container::ElementExistException&)
+ {
+ throw;
+ }
+ catch (const uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const uno::Exception&)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw css::lang::WrappedTargetRuntimeException(
+ "Error Getting AutoText!",
+ static_cast < OWeakObject * > ( this ),
+ anyEx );
+ }
+
+ return xEntry;
+}
+
+void SwXAutoTextGroup::removeByName(const OUString& aEntryName)
+{
+ SolarMutexGuard aGuard;
+ std::unique_ptr<SwTextBlocks> pGlosGroup(m_pGlossaries ? m_pGlossaries->GetGroupDoc(m_sGroupName) : nullptr);
+ if(!pGlosGroup || pGlosGroup->GetError())
+ throw container::NoSuchElementException();
+
+ sal_uInt16 nIdx = pGlosGroup->GetIndex(aEntryName);
+ if ( nIdx == USHRT_MAX )
+ throw container::NoSuchElementException();
+
+ pGlosGroup->Delete(nIdx);
+}
+
+OUString SwXAutoTextGroup::getName()
+{
+ SolarMutexGuard aGuard;
+ return m_sName;
+}
+
+void SwXAutoTextGroup::setName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ if( !m_pGlossaries )
+ throw uno::RuntimeException();
+
+ sal_Int32 nNewDelimPos = rName.lastIndexOf( GLOS_DELIM );
+ sal_Int32 nOldDelimPos = m_sName.lastIndexOf( GLOS_DELIM );
+
+ OUString aNewSuffix;
+ if (nNewDelimPos > -1)
+ aNewSuffix = rName.copy( nNewDelimPos + 1 );
+ OUString aOldSuffix;
+ if (nOldDelimPos > -1)
+ aOldSuffix = m_sName.copy( nOldDelimPos + 1 );
+
+ sal_Int32 nNewNumeric = aNewSuffix.toInt32();
+ sal_Int32 nOldNumeric = aOldSuffix.toInt32();
+
+ OUString aNewPrefix( (nNewDelimPos > 1) ? rName.copy( 0, nNewDelimPos ) : rName );
+ OUString aOldPrefix( (nOldDelimPos > 1) ? m_sName.copy( 0, nOldDelimPos ) : m_sName );
+
+ if ( m_sName == rName ||
+ ( nNewNumeric == nOldNumeric && aNewPrefix == aOldPrefix ) )
+ return;
+ OUString sNewGroup(rName);
+ if (sNewGroup.indexOf(GLOS_DELIM)<0)
+ {
+ sNewGroup += OUStringChar(GLOS_DELIM) + "0";
+ }
+
+ //the name must be saved, the group may be invalidated while in RenameGroupDoc()
+ SwGlossaries* pTempGlossaries = m_pGlossaries;
+
+ OUString sPreserveTitle( m_pGlossaries->GetGroupTitle( m_sName ) );
+ if ( !m_pGlossaries->RenameGroupDoc( m_sName, sNewGroup, sPreserveTitle ) )
+ throw uno::RuntimeException();
+ m_sName = rName;
+ m_sGroupName = sNewGroup;
+ m_pGlossaries = pTempGlossaries;
+}
+
+sal_Int32 SwXAutoTextGroup::getCount()
+{
+ SolarMutexGuard aGuard;
+ std::unique_ptr<SwTextBlocks> pGlosGroup(m_pGlossaries ? m_pGlossaries->GetGroupDoc(m_sGroupName) : nullptr);
+ if (!pGlosGroup || pGlosGroup->GetError())
+ throw uno::RuntimeException();
+ return static_cast<sal_Int32>(pGlosGroup->GetCount());
+}
+
+uno::Any SwXAutoTextGroup::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ if (!m_pGlossaries)
+ throw uno::RuntimeException();
+ std::unique_ptr<SwTextBlocks> pGlosGroup(m_pGlossaries->GetGroupDoc(m_sGroupName));
+ if (!pGlosGroup || pGlosGroup->GetError())
+ throw uno::RuntimeException();
+ const sal_uInt16 nCount = pGlosGroup->GetCount();
+ if (nIndex < 0 || o3tl::make_unsigned(nIndex) >= nCount)
+ throw lang::IndexOutOfBoundsException();
+ return getByName(pGlosGroup->GetShortName(o3tl::narrowing<sal_uInt16>(nIndex)));
+}
+
+uno::Type SwXAutoTextGroup::getElementType()
+{
+ return cppu::UnoType<text::XAutoTextEntry>::get();
+
+}
+
+sal_Bool SwXAutoTextGroup::hasElements()
+{
+ SolarMutexGuard aGuard;
+ std::unique_ptr<SwTextBlocks> pGlosGroup(m_pGlossaries ? m_pGlossaries->GetGroupDoc(m_sGroupName) : nullptr);
+ if (!pGlosGroup || pGlosGroup->GetError())
+ throw uno::RuntimeException();
+ return pGlosGroup->GetCount() > 0;
+
+}
+
+uno::Any SwXAutoTextGroup::getByName(const OUString& _rName)
+{
+ SolarMutexGuard aGuard;
+ uno::Reference< text::XAutoTextEntry > xEntry = m_pGlossaries->GetAutoTextEntry( m_sGroupName, m_sName, _rName );
+ OSL_ENSURE( xEntry.is(), "SwXAutoTextGroup::getByName: GetAutoTextEntry is fractious!" );
+ // we told it to create the object, so why didn't it?
+ return css::uno::Any( xEntry );
+}
+
+uno::Sequence< OUString > SwXAutoTextGroup::getElementNames()
+{
+ SolarMutexGuard aGuard;
+ std::unique_ptr<SwTextBlocks> pGlosGroup(m_pGlossaries ? m_pGlossaries->GetGroupDoc(m_sGroupName) : nullptr);
+ if (!pGlosGroup || pGlosGroup->GetError())
+ throw uno::RuntimeException();
+
+ const sal_uInt16 nCount = pGlosGroup->GetCount();
+ uno::Sequence< OUString > aEntryNames(nCount);
+ OUString *pArr = aEntryNames.getArray();
+
+ for ( sal_uInt16 i = 0; i < nCount; i++ )
+ pArr[i] = pGlosGroup->GetShortName(i);
+ return aEntryNames;
+}
+
+sal_Bool SwXAutoTextGroup::hasByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ bool bRet = false;
+ std::unique_ptr<SwTextBlocks> pGlosGroup(m_pGlossaries ? m_pGlossaries->GetGroupDoc(m_sGroupName) : nullptr);
+ if (!pGlosGroup || pGlosGroup->GetError())
+ throw uno::RuntimeException();
+
+ const sal_uInt16 nCount = pGlosGroup->GetCount();
+ for( sal_uInt16 i = 0; i < nCount; ++i )
+ {
+ OUString sCompare(pGlosGroup->GetShortName(i));
+ if(sCompare.equalsIgnoreAsciiCase(rName))
+ {
+ bRet = true;
+ break;
+ }
+ }
+ return bRet;
+}
+
+uno::Reference< beans::XPropertySetInfo > SwXAutoTextGroup::getPropertySetInfo()
+{
+ static uno::Reference< beans::XPropertySetInfo > xRet = m_pPropSet->getPropertySetInfo();
+ return xRet;
+}
+
+void SwXAutoTextGroup::setPropertyValue(
+ const OUString& rPropertyName, const uno::Any& aValue)
+{
+ SolarMutexGuard aGuard;
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+
+ if(!pEntry)
+ throw beans::UnknownPropertyException(rPropertyName);
+
+ std::unique_ptr<SwTextBlocks> pGlosGroup(m_pGlossaries ? m_pGlossaries->GetGroupDoc(m_sGroupName) : nullptr);
+ if(!pGlosGroup || pGlosGroup->GetError())
+ throw uno::RuntimeException();
+ switch(pEntry->nWID)
+ {
+ case WID_GROUP_TITLE:
+ {
+ OUString sNewTitle;
+ aValue >>= sNewTitle;
+ if(sNewTitle.isEmpty())
+ throw lang::IllegalArgumentException();
+ bool bChanged = sNewTitle != pGlosGroup->GetName();
+ pGlosGroup->SetName(sNewTitle);
+ if(bChanged && HasGlossaryList())
+ GetGlossaryList()->ClearGroups();
+ }
+ break;
+ }
+}
+
+uno::Any SwXAutoTextGroup::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName);
+
+ if(!pEntry)
+ throw beans::UnknownPropertyException(rPropertyName);
+ std::unique_ptr<SwTextBlocks> pGlosGroup(m_pGlossaries ? m_pGlossaries->GetGroupDoc(m_sGroupName) : nullptr);
+ if(!pGlosGroup || pGlosGroup->GetError())
+ throw uno::RuntimeException();
+
+ uno::Any aAny;
+ switch(pEntry->nWID)
+ {
+ case WID_GROUP_PATH:
+ aAny <<= pGlosGroup->GetFileName();
+ break;
+ case WID_GROUP_TITLE:
+ aAny <<= pGlosGroup->GetName();
+ break;
+ }
+ return aAny;
+}
+
+void SwXAutoTextGroup::addPropertyChangeListener(
+ const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
+{
+}
+
+void SwXAutoTextGroup::removePropertyChangeListener(
+ const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
+{
+}
+
+void SwXAutoTextGroup::addVetoableChangeListener(
+ const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
+{
+}
+
+void SwXAutoTextGroup::removeVetoableChangeListener(
+ const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
+{
+}
+
+void SwXAutoTextGroup::Invalidate()
+{
+ m_pGlossaries = nullptr;
+ m_sName.clear();
+ m_sGroupName.clear();
+}
+
+OUString SwXAutoTextGroup::getImplementationName()
+{
+ return "SwXAutoTextGroup";
+}
+
+sal_Bool SwXAutoTextGroup::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SwXAutoTextGroup::getSupportedServiceNames()
+{
+ uno::Sequence<OUString> aRet { "com.sun.star.text.AutoTextGroup" };
+ return aRet;
+}
+
+const uno::Sequence< sal_Int8 > & SwXAutoTextEntry::getUnoTunnelId()
+{
+ static const comphelper::UnoIdInit theSwXAutoTextEntryUnoTunnelId;
+ return theSwXAutoTextEntryUnoTunnelId.getSeq();
+}
+
+sal_Int64 SAL_CALL SwXAutoTextEntry::getSomething( const uno::Sequence< sal_Int8 >& rId )
+{
+ return comphelper::getSomethingImpl(rId, this);
+}
+
+SwXAutoTextEntry::SwXAutoTextEntry(SwGlossaries* pGlss, const OUString& rGroupName,
+ const OUString& rEntryName) :
+ m_pGlossaries(pGlss),
+ m_sGroupName(rGroupName),
+ m_sEntryName(rEntryName)
+{
+}
+
+SwXAutoTextEntry::~SwXAutoTextEntry()
+{
+ SolarMutexGuard aGuard;
+
+ // ensure that any pending modifications are written
+ implFlushDocument( true );
+}
+
+void SwXAutoTextEntry::implFlushDocument( bool _bCloseDoc )
+{
+ if ( !m_xDocSh.is() )
+ return;
+
+ if ( m_xDocSh->GetDoc()->getIDocumentState().IsModified () )
+ m_xDocSh->Save();
+
+ if ( _bCloseDoc )
+ {
+ // stop listening at the document
+ EndListening( *m_xDocSh );
+
+ m_xDocSh->DoClose();
+ m_xDocSh.clear();
+ }
+}
+
+void SwXAutoTextEntry::Notify( SfxBroadcaster& _rBC, const SfxHint& _rHint )
+{
+ if ( &_rBC != m_xDocSh.get() )
+ return;
+
+// it's our document
+ if (const SfxEventHint* pEventHint = dynamic_cast<const SfxEventHint*>(&_rHint))
+ {
+ if (SfxEventHintId::PrepareCloseDoc == pEventHint->GetEventId())
+ {
+ implFlushDocument();
+ mxBodyText.clear();
+ EndListening( *m_xDocSh );
+ m_xDocSh.clear();
+ }
+ }
+ else
+ {
+ if ( SfxHintId::Deinitializing == _rHint.GetId() )
+ {
+ // our document is dying (possibly because we're shutting down, and the document was notified
+ // earlier than we are?)
+ // stop listening at the docu
+ EndListening( *m_xDocSh );
+ // and release our reference
+ m_xDocSh.clear();
+ }
+ }
+}
+
+void SwXAutoTextEntry::GetBodyText ()
+{
+ SolarMutexGuard aGuard;
+
+ m_xDocSh = m_pGlossaries->EditGroupDoc ( m_sGroupName, m_sEntryName, false );
+ OSL_ENSURE( m_xDocSh.is(), "SwXAutoTextEntry::GetBodyText: unexpected: no doc returned by EditGroupDoc!" );
+
+ // start listening at the document
+ StartListening( *m_xDocSh );
+
+ mxBodyText = new SwXBodyText ( m_xDocSh->GetDoc() );
+}
+
+void SwXAutoTextEntry::disposing(std::unique_lock<std::mutex>&)
+{
+ SolarMutexGuard g;
+ implFlushDocument(true);
+}
+
+uno::Reference< text::XTextCursor > SwXAutoTextEntry::createTextCursor()
+{
+ SolarMutexGuard aGuard;
+ EnsureBodyText();
+ return mxBodyText->createTextCursor();
+}
+
+uno::Reference< text::XTextCursor > SwXAutoTextEntry::createTextCursorByRange(
+ const uno::Reference< text::XTextRange > & aTextPosition)
+{
+ SolarMutexGuard aGuard;
+ EnsureBodyText();
+ return mxBodyText->createTextCursorByRange ( aTextPosition );
+}
+
+void SwXAutoTextEntry::insertString(const uno::Reference< text::XTextRange > & xRange, const OUString& aString, sal_Bool bAbsorb)
+{
+ SolarMutexGuard aGuard;
+ EnsureBodyText();
+ mxBodyText->insertString ( xRange, aString, bAbsorb );
+}
+
+void SwXAutoTextEntry::insertControlCharacter(const uno::Reference< text::XTextRange > & xRange,
+ sal_Int16 nControlCharacter, sal_Bool bAbsorb)
+{
+ SolarMutexGuard aGuard;
+ EnsureBodyText();
+ mxBodyText->insertControlCharacter ( xRange, nControlCharacter, bAbsorb );
+}
+
+void SwXAutoTextEntry::insertTextContent(
+ const uno::Reference< text::XTextRange > & xRange,
+ const uno::Reference< text::XTextContent > & xContent, sal_Bool bAbsorb)
+{
+ SolarMutexGuard aGuard;
+ EnsureBodyText();
+ mxBodyText->insertTextContent ( xRange, xContent, bAbsorb );
+}
+
+void SwXAutoTextEntry::removeTextContent(
+ const uno::Reference< text::XTextContent > & xContent)
+{
+ SolarMutexGuard aGuard;
+ EnsureBodyText();
+ mxBodyText->removeTextContent ( xContent );
+}
+
+uno::Reference< text::XText > SwXAutoTextEntry::getText()
+{
+ SolarMutexGuard aGuard;
+ uno::Reference< text::XText > xRet = static_cast<text::XText*>(this);
+ return xRet;
+}
+
+uno::Reference< text::XTextRange > SwXAutoTextEntry::getStart()
+{
+ SolarMutexGuard aGuard;
+ EnsureBodyText();
+ return mxBodyText->getStart();
+}
+
+uno::Reference< text::XTextRange > SwXAutoTextEntry::getEnd()
+{
+ SolarMutexGuard aGuard;
+ EnsureBodyText();
+ return mxBodyText->getEnd();
+}
+
+OUString SwXAutoTextEntry::getString()
+{
+ SolarMutexGuard aGuard;
+ EnsureBodyText();
+ return mxBodyText->getString();
+}
+
+void SwXAutoTextEntry::setString(const OUString& aString)
+{
+ SolarMutexGuard aGuard;
+ EnsureBodyText();
+ mxBodyText->setString( aString );
+}
+
+void SwXAutoTextEntry::applyTo(const uno::Reference< text::XTextRange > & xTextRange)
+{
+ SolarMutexGuard aGuard;
+
+ // ensure that any pending modifications are written
+ // reason is that we're holding the _copy_ of the auto text, while the real auto text
+ // is stored somewhere. And below, we're not working with our copy, but only tell the target
+ // TextRange to work with the stored version.
+ // #96380# - 2003-03-03 - fs@openoffice.org
+ implFlushDocument();
+ // TODO: think about if we should pass "true" here
+ // The difference would be that when the next modification is made to this instance here, then
+ // we would be forced to open the document again, instead of working on our current copy.
+ // This means that we would reflect any changes which were done to the AutoText by foreign instances
+ // in the meantime
+
+ // The reference to the tunnel is needed during the whole call, likely because it could be a
+ // different object, not xTextRange itself, and the reference guards it from preliminary death
+ uno::Reference<lang::XUnoTunnel> xTunnel( xTextRange, uno::UNO_QUERY);
+ SwXTextRange* pRange = comphelper::getFromUnoTunnel<SwXTextRange>(xTunnel);
+ OTextCursorHelper* pCursor = comphelper::getFromUnoTunnel<OTextCursorHelper>(xTunnel);
+ SwXText *pText = comphelper::getFromUnoTunnel<SwXText>(xTunnel);
+
+ SwDoc* pDoc = nullptr;
+ if (pRange)
+ pDoc = &pRange->GetDoc();
+ else if ( pCursor )
+ pDoc = pCursor->GetDoc();
+ else if ( pText && pText->GetDoc() )
+ {
+ xTunnel.set(pText->getStart(), uno::UNO_QUERY);
+ pCursor = comphelper::getFromUnoTunnel<OTextCursorHelper>(xTunnel);
+ if (pCursor)
+ pDoc = pText->GetDoc();
+ }
+
+ if(!pDoc)
+ throw uno::RuntimeException();
+
+ SwPaM InsertPaM(pDoc->GetNodes());
+ if (pRange)
+ {
+ if (!pRange->GetPositions(InsertPaM))
+ {
+ throw uno::RuntimeException();
+ }
+ }
+ else
+ {
+ InsertPaM = *pCursor->GetPaM();
+ }
+
+ std::unique_ptr<SwTextBlocks> pBlock(m_pGlossaries->GetGroupDoc(m_sGroupName));
+ const bool bResult = pBlock && !pBlock->GetError()
+ && pDoc->InsertGlossary( *pBlock, m_sEntryName, InsertPaM);
+
+ if(!bResult)
+ throw uno::RuntimeException();
+}
+
+OUString SwXAutoTextEntry::getImplementationName()
+{
+ return "SwXAutoTextEntry";
+}
+
+sal_Bool SwXAutoTextEntry::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SwXAutoTextEntry::getSupportedServiceNames()
+{
+ uno::Sequence<OUString> aRet { "com.sun.star.text.AutoTextEntry" };
+ return aRet;
+}
+
+uno::Reference< container::XNameReplace > SwXAutoTextEntry::getEvents()
+{
+ return new SwAutoTextEventDescriptor( *this );
+}
+
+const struct SvEventDescription aAutotextEvents[] =
+{
+ { SvMacroItemId::SwStartInsGlossary, "OnInsertStart" },
+ { SvMacroItemId::SwEndInsGlossary, "OnInsertDone" },
+ { SvMacroItemId::NONE, nullptr }
+};
+
+SwAutoTextEventDescriptor::SwAutoTextEventDescriptor(
+ SwXAutoTextEntry& rAutoText ) :
+ SvBaseEventDescriptor(aAutotextEvents),
+ m_rAutoTextEntry(rAutoText)
+{
+}
+
+SwAutoTextEventDescriptor::~SwAutoTextEventDescriptor()
+{
+}
+
+OUString SwAutoTextEventDescriptor::getImplementationName()
+{
+ return "SwAutoTextEventDescriptor";
+}
+
+void SwAutoTextEventDescriptor::replaceByName(
+ const SvMacroItemId nEvent,
+ const SvxMacro& rMacro)
+{
+ OSL_ENSURE( nullptr != m_rAutoTextEntry.GetGlossaries(),
+ "Strangely enough, the AutoText vanished!" );
+ OSL_ENSURE( (nEvent == SvMacroItemId::SwEndInsGlossary) ||
+ (nEvent == SvMacroItemId::SwStartInsGlossary) ,
+ "Unknown event ID" );
+
+ SwGlossaries *const pGlossaries =
+ const_cast<SwGlossaries*>(m_rAutoTextEntry.GetGlossaries());
+ std::unique_ptr<SwTextBlocks> pBlocks(
+ pGlossaries->GetGroupDoc( m_rAutoTextEntry.GetGroupName() ));
+ OSL_ENSURE( pBlocks,
+ "can't get autotext group; SwAutoTextEntry has illegal name?");
+
+ if( !pBlocks || pBlocks->GetError())
+ return;
+
+ sal_uInt16 nIndex = pBlocks->GetIndex( m_rAutoTextEntry.GetEntryName() );
+ if( nIndex != USHRT_MAX )
+ {
+ SvxMacroTableDtor aMacroTable;
+ if( pBlocks->GetMacroTable( nIndex, aMacroTable ) )
+ {
+ aMacroTable.Insert( nEvent, rMacro );
+ pBlocks->SetMacroTable( nIndex, aMacroTable );
+ }
+ }
+ // else: ignore
+}
+
+void SwAutoTextEventDescriptor::getByName(
+ SvxMacro& rMacro,
+ const SvMacroItemId nEvent )
+{
+ OSL_ENSURE( nullptr != m_rAutoTextEntry.GetGlossaries(), "no AutoText" );
+ OSL_ENSURE( (nEvent == SvMacroItemId::SwEndInsGlossary) ||
+ (nEvent == SvMacroItemId::SwStartInsGlossary) ,
+ "Unknown event ID" );
+
+ SwGlossaries *const pGlossaries =
+ const_cast<SwGlossaries*>(m_rAutoTextEntry.GetGlossaries());
+ std::unique_ptr<SwTextBlocks> pBlocks(
+ pGlossaries->GetGroupDoc( m_rAutoTextEntry.GetGroupName() ));
+ OSL_ENSURE( pBlocks,
+ "can't get autotext group; SwAutoTextEntry has illegal name?");
+
+ // return empty macro, unless macro is found
+ OUString sEmptyStr;
+ SvxMacro aEmptyMacro(sEmptyStr, sEmptyStr);
+ rMacro = aEmptyMacro;
+
+ if ( !pBlocks || pBlocks->GetError())
+ return;
+
+ sal_uInt16 nIndex = pBlocks->GetIndex( m_rAutoTextEntry.GetEntryName() );
+ if( nIndex != USHRT_MAX )
+ {
+ SvxMacroTableDtor aMacroTable;
+ if( pBlocks->GetMacroTable( nIndex, aMacroTable ) )
+ {
+ SvxMacro *pMacro = aMacroTable.Get( nEvent );
+ if( pMacro )
+ rMacro = *pMacro;
+ }
+ }
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+SwXAutoTextContainer_get_implementation(css::uno::XComponentContext*,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ //the module may not be loaded
+ SolarMutexGuard aGuard;
+ SwGlobals::ensure();
+ return cppu::acquire(new SwXAutoTextContainer());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/uno/unodefaults.cxx b/sw/source/uibase/uno/unodefaults.cxx
new file mode 100644
index 000000000..378ddc0b9
--- /dev/null
+++ b/sw/source/uibase/uno/unodefaults.cxx
@@ -0,0 +1,46 @@
+/* -*- 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 "unodefaults.hxx"
+#include <svx/unoprov.hxx>
+#include <drawdoc.hxx>
+#include <doc.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+
+SwSvxUnoDrawPool::SwSvxUnoDrawPool(SwDoc& rDoc)
+ : SvxUnoDrawPool(rDoc.getIDocumentDrawModelAccess().GetDrawModel(),
+ SVXUNO_SERVICEID_COM_SUN_STAR_DRAWING_DEFAULTS_WRITER)
+ , m_rDoc(rDoc)
+{
+}
+
+SwSvxUnoDrawPool::~SwSvxUnoDrawPool() noexcept {}
+
+SfxItemPool* SwSvxUnoDrawPool::getModelPool(bool /*bReadOnly*/) noexcept
+{
+ // DVO, OD 01.10.2003 #i18732# - return item pool of writer document;
+ // it contains draw model item pool as secondary pool.
+ //SdrModel* pModel = m_rDoc.MakeDrawModel();
+ //return &pModel->GetItemPool();
+ // #i52858# - method name changed
+ m_rDoc.getIDocumentDrawModelAccess().GetOrCreateDrawModel();
+ return &(m_rDoc.GetAttrPool());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/uno/unodefaults.hxx b/sw/source/uibase/uno/unodefaults.hxx
new file mode 100644
index 000000000..5c14c1726
--- /dev/null
+++ b/sw/source/uibase/uno/unodefaults.hxx
@@ -0,0 +1,36 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <svx/unopool.hxx>
+
+class SwDoc;
+
+class SwSvxUnoDrawPool : public SvxUnoDrawPool
+{
+ SwDoc& m_rDoc;
+
+public:
+ SwSvxUnoDrawPool(SwDoc& rDoc);
+ virtual ~SwSvxUnoDrawPool() noexcept override;
+
+ virtual SfxItemPool* getModelPool(bool bReadOnly) noexcept override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/uno/unodispatch.cxx b/sw/source/uibase/uno/unodispatch.cxx
new file mode 100644
index 000000000..0c7f46580
--- /dev/null
+++ b/sw/source/uibase/uno/unodispatch.cxx
@@ -0,0 +1,387 @@
+/* -*- 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 <config_features.h>
+#include <config_fuzzers.h>
+
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svx/dataaccessdescriptor.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <osl/diagnose.h>
+#include <unodispatch.hxx>
+#include <view.hxx>
+#include <cmdid.h>
+#include <wrtsh.hxx>
+#include <dbmgr.hxx>
+
+using namespace ::com::sun::star;
+
+const char cURLFormLetter[] = ".uno:DataSourceBrowser/FormLetter";
+const char cURLInsertContent[] = ".uno:DataSourceBrowser/InsertContent";//data into fields
+const char cURLInsertColumns[] = ".uno:DataSourceBrowser/InsertColumns";//data into text
+const char cURLDocumentDataSource[] = ".uno:DataSourceBrowser/DocumentDataSource";//current data source of the document
+const char cInternalDBChangeNotification[] = ".uno::Writer/DataSourceChanged";
+
+SwXDispatchProviderInterceptor::SwXDispatchProviderInterceptor(SwView& rVw) :
+ m_pView(&rVw)
+{
+ uno::Reference< frame::XFrame> xUnoFrame = m_pView->GetViewFrame()->GetFrame().GetFrameInterface();
+ m_xIntercepted.set(xUnoFrame, uno::UNO_QUERY);
+ if(m_xIntercepted.is())
+ {
+ osl_atomic_increment(&m_refCount);
+ m_xIntercepted->registerDispatchProviderInterceptor(static_cast<frame::XDispatchProviderInterceptor*>(this));
+ // this should make us the top-level dispatch-provider for the component, via a call to our
+ // setDispatchProvider we should have got a fallback for requests we (i.e. our master) cannot fulfill
+ uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
+ if (xInterceptedComponent.is())
+ xInterceptedComponent->addEventListener(static_cast<lang::XEventListener*>(this));
+ osl_atomic_decrement(&m_refCount);
+ }
+}
+
+SwXDispatchProviderInterceptor::~SwXDispatchProviderInterceptor()
+{
+}
+
+uno::Reference< frame::XDispatch > SwXDispatchProviderInterceptor::queryDispatch(
+ const util::URL& aURL, const OUString& aTargetFrameName, sal_Int32 nSearchFlags )
+{
+ DispatchMutexLock_Impl aLock;
+ uno::Reference< frame::XDispatch> xResult;
+ // create some dispatch ...
+ if(m_pView && aURL.Complete.startsWith(".uno:DataSourceBrowser/"))
+ {
+ if(aURL.Complete == cURLFormLetter ||
+ aURL.Complete == cURLInsertContent ||
+ aURL.Complete == cURLInsertColumns ||
+ aURL.Complete == cURLDocumentDataSource)
+ {
+ if(!m_xDispatch.is())
+ m_xDispatch = new SwXDispatch(*m_pView);
+ xResult = m_xDispatch;
+ }
+ }
+
+ // ask our slave provider
+ if (!xResult.is() && m_xSlaveDispatcher.is())
+ xResult = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags);
+
+ return xResult;
+}
+
+uno::Sequence<OUString> SAL_CALL SwXDispatchProviderInterceptor::getInterceptedURLs()
+{
+ uno::Sequence<OUString> aRet =
+ {
+ OUString(".uno:DataSourceBrowser/*")
+ };
+
+ return aRet;
+}
+
+uno::Sequence< uno::Reference< frame::XDispatch > > SwXDispatchProviderInterceptor::queryDispatches(
+ const uno::Sequence< frame::DispatchDescriptor >& aDescripts )
+{
+ DispatchMutexLock_Impl aLock;
+ uno::Sequence< uno::Reference< frame::XDispatch> > aReturn(aDescripts.getLength());
+ std::transform(aDescripts.begin(), aDescripts.end(), aReturn.getArray(),
+ [this](const frame::DispatchDescriptor& rDescr) -> uno::Reference<frame::XDispatch> {
+ return queryDispatch(rDescr.FeatureURL, rDescr.FrameName, rDescr.SearchFlags); });
+ return aReturn;
+}
+
+uno::Reference< frame::XDispatchProvider > SwXDispatchProviderInterceptor::getSlaveDispatchProvider( )
+{
+ DispatchMutexLock_Impl aLock;
+ return m_xSlaveDispatcher;
+}
+
+void SwXDispatchProviderInterceptor::setSlaveDispatchProvider(
+ const uno::Reference< frame::XDispatchProvider >& xNewDispatchProvider )
+{
+ DispatchMutexLock_Impl aLock;
+ m_xSlaveDispatcher = xNewDispatchProvider;
+}
+
+uno::Reference< frame::XDispatchProvider > SwXDispatchProviderInterceptor::getMasterDispatchProvider( )
+{
+ DispatchMutexLock_Impl aLock;
+ return m_xMasterDispatcher;
+}
+
+void SwXDispatchProviderInterceptor::setMasterDispatchProvider(
+ const uno::Reference< frame::XDispatchProvider >& xNewSupplier )
+{
+ DispatchMutexLock_Impl aLock;
+ m_xMasterDispatcher = xNewSupplier;
+}
+
+void SwXDispatchProviderInterceptor::disposing( const lang::EventObject& )
+{
+ DispatchMutexLock_Impl aLock;
+ if (m_xIntercepted.is())
+ {
+ m_xIntercepted->releaseDispatchProviderInterceptor(static_cast<frame::XDispatchProviderInterceptor*>(this));
+ uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
+ if (xInterceptedComponent.is())
+ xInterceptedComponent->removeEventListener(static_cast<lang::XEventListener*>(this));
+ m_xDispatch = nullptr;
+ }
+ m_xIntercepted = nullptr;
+}
+
+const uno::Sequence< sal_Int8 > & SwXDispatchProviderInterceptor::getUnoTunnelId()
+{
+ static const comphelper::UnoIdInit theSwXDispatchProviderInterceptorUnoTunnelId;
+ return theSwXDispatchProviderInterceptorUnoTunnelId.getSeq();
+}
+
+sal_Int64 SwXDispatchProviderInterceptor::getSomething(
+ const uno::Sequence< sal_Int8 >& aIdentifier )
+{
+ return comphelper::getSomethingImpl(aIdentifier, this);
+}
+
+void SwXDispatchProviderInterceptor::Invalidate()
+{
+ DispatchMutexLock_Impl aLock;
+ if (m_xIntercepted.is())
+ {
+ m_xIntercepted->releaseDispatchProviderInterceptor(static_cast<frame::XDispatchProviderInterceptor*>(this));
+ uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
+ if (xInterceptedComponent.is())
+ xInterceptedComponent->removeEventListener(static_cast<lang::XEventListener*>(this));
+ m_xDispatch = nullptr;
+ }
+ m_xIntercepted = nullptr;
+ m_pView = nullptr;
+}
+
+SwXDispatch::SwXDispatch(SwView& rVw) :
+ m_pView(&rVw),
+ m_bOldEnable(false),
+ m_bListenerAdded(false)
+{
+}
+
+SwXDispatch::~SwXDispatch()
+{
+ if(m_bListenerAdded && m_pView)
+ {
+ uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject();
+ uno::Reference<view::XSelectionChangeListener> xThis = this;
+ xSupplier->removeSelectionChangeListener(xThis);
+ }
+}
+
+void SwXDispatch::dispatch(const util::URL& aURL,
+ const uno::Sequence< beans::PropertyValue >& aArgs)
+{
+ if(!m_pView)
+ throw uno::RuntimeException();
+#if !HAVE_FEATURE_DBCONNECTIVITY || ENABLE_FUZZERS
+ (void) aArgs;
+ if (false)
+ {
+ }
+#else
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ SwDBManager* pDBManager = rSh.GetDBManager();
+ if(aURL.Complete == cURLInsertContent)
+ {
+ svx::ODataAccessDescriptor aDescriptor(aArgs);
+ SwMergeDescriptor aMergeDesc( DBMGR_MERGE, rSh, aDescriptor );
+ pDBManager->Merge(aMergeDesc);
+ }
+ else if(aURL.Complete == cURLInsertColumns)
+ {
+ SwDBManager::InsertText(rSh, aArgs);
+ }
+ else if(aURL.Complete == cURLFormLetter)
+ {
+ SfxUnoAnyItem aDBProperties(FN_PARAM_DATABASE_PROPERTIES, uno::Any(aArgs));
+ m_pView->GetViewFrame()->GetDispatcher()->ExecuteList(
+ FN_MAILMERGE_WIZARD,
+ SfxCallMode::ASYNCHRON,
+ { &aDBProperties });
+ }
+#endif
+ else if(aURL.Complete == cURLDocumentDataSource)
+ {
+ OSL_FAIL("SwXDispatch::dispatch: this URL is not to be dispatched!");
+ }
+ else if(aURL.Complete == cInternalDBChangeNotification)
+ {
+ frame::FeatureStateEvent aEvent;
+ aEvent.Source = *static_cast<cppu::OWeakObject*>(this);
+
+ const SwDBData& rData = m_pView->GetWrtShell().GetDBData();
+ svx::ODataAccessDescriptor aDescriptor;
+ aDescriptor.setDataSource(rData.sDataSource);
+ aDescriptor[svx::DataAccessDescriptorProperty::Command] <<= rData.sCommand;
+ aDescriptor[svx::DataAccessDescriptorProperty::CommandType] <<= rData.nCommandType;
+
+ aEvent.State <<= aDescriptor.createPropertyValueSequence();
+ aEvent.IsEnabled = !rData.sDataSource.isEmpty();
+
+ // calls to statusChanged may call addStatusListener or removeStatusListener
+ // so copy m_aStatusListenerVector on stack
+ auto copyStatusListenerVector = m_aStatusListenerVector;
+ for (auto & status : copyStatusListenerVector)
+ {
+ if(status.aURL.Complete == cURLDocumentDataSource)
+ {
+ aEvent.FeatureURL = status.aURL;
+ status.xListener->statusChanged( aEvent );
+ }
+ }
+ }
+ else
+ throw uno::RuntimeException();
+
+}
+
+void SwXDispatch::addStatusListener(
+ const uno::Reference< frame::XStatusListener >& xControl, const util::URL& aURL )
+{
+ if(!m_pView)
+ throw uno::RuntimeException();
+ ShellMode eMode = m_pView->GetShellMode();
+ bool bEnable = ShellMode::Text == eMode ||
+ ShellMode::ListText == eMode ||
+ ShellMode::TableText == eMode ||
+ ShellMode::TableListText == eMode;
+
+ m_bOldEnable = bEnable;
+ frame::FeatureStateEvent aEvent;
+ aEvent.IsEnabled = bEnable;
+ aEvent.Source = *static_cast<cppu::OWeakObject*>(this);
+ aEvent.FeatureURL = aURL;
+
+ // one of the URLs requires a special state...
+ if (aURL.Complete == cURLDocumentDataSource)
+ {
+ const SwDBData& rData = m_pView->GetWrtShell().GetDBData();
+
+ svx::ODataAccessDescriptor aDescriptor;
+ aDescriptor.setDataSource(rData.sDataSource);
+ aDescriptor[svx::DataAccessDescriptorProperty::Command] <<= rData.sCommand;
+ aDescriptor[svx::DataAccessDescriptorProperty::CommandType] <<= rData.nCommandType;
+
+ aEvent.State <<= aDescriptor.createPropertyValueSequence();
+ aEvent.IsEnabled = !rData.sDataSource.isEmpty();
+ }
+
+ xControl->statusChanged( aEvent );
+
+ StatusStruct_Impl aStatus;
+ aStatus.xListener = xControl;
+ aStatus.aURL = aURL;
+ m_aStatusListenerVector.emplace_back(aStatus);
+
+ if(!m_bListenerAdded)
+ {
+ uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject();
+ uno::Reference<view::XSelectionChangeListener> xThis = this;
+ xSupplier->addSelectionChangeListener(xThis);
+ m_bListenerAdded = true;
+ }
+}
+
+void SwXDispatch::removeStatusListener(
+ const uno::Reference< frame::XStatusListener >& xControl, const util::URL& )
+{
+ m_aStatusListenerVector.erase(
+ std::remove_if(m_aStatusListenerVector.begin(), m_aStatusListenerVector.end(),
+ [&](const StatusStruct_Impl& status) { return status.xListener.get() == xControl.get(); }),
+ m_aStatusListenerVector.end());
+ if(m_aStatusListenerVector.empty() && m_pView)
+ {
+ uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject();
+ uno::Reference<view::XSelectionChangeListener> xThis = this;
+ xSupplier->removeSelectionChangeListener(xThis);
+ m_bListenerAdded = false;
+ }
+}
+
+void SwXDispatch::selectionChanged( const lang::EventObject& )
+{
+ ShellMode eMode = m_pView->GetShellMode();
+ bool bEnable = ShellMode::Text == eMode ||
+ ShellMode::ListText == eMode ||
+ ShellMode::TableText == eMode ||
+ ShellMode::TableListText == eMode;
+ if(bEnable == m_bOldEnable)
+ return;
+
+ m_bOldEnable = bEnable;
+ frame::FeatureStateEvent aEvent;
+ aEvent.IsEnabled = bEnable;
+ aEvent.Source = *static_cast<cppu::OWeakObject*>(this);
+
+ // calls to statusChanged may call addStatusListener or removeStatusListener
+ // so copy m_aStatusListenerVector on stack
+ auto copyStatusListenerVector = m_aStatusListenerVector;
+ for (auto & status : copyStatusListenerVector)
+ {
+ aEvent.FeatureURL = status.aURL;
+ if (status.aURL.Complete != cURLDocumentDataSource)
+ // the document's data source does not depend on the selection, so it's state does not change here
+ status.xListener->statusChanged( aEvent );
+ }
+}
+
+void SwXDispatch::disposing( const lang::EventObject& rSource )
+{
+ uno::Reference<view::XSelectionSupplier> xSupplier(rSource.Source, uno::UNO_QUERY);
+ uno::Reference<view::XSelectionChangeListener> xThis = this;
+ xSupplier->removeSelectionChangeListener(xThis);
+ m_bListenerAdded = false;
+
+ lang::EventObject aObject;
+ aObject.Source = static_cast<cppu::OWeakObject*>(this);
+ // calls to statusChanged may call addStatusListener or removeStatusListener
+ // so copy m_aStatusListenerVector on stack
+ auto copyStatusListenerVector = m_aStatusListenerVector;
+ for (auto & status : copyStatusListenerVector)
+ {
+ status.xListener->disposing(aObject);
+ }
+ m_pView = nullptr;
+}
+
+const char* SwXDispatch::GetDBChangeURL()
+{
+ return cInternalDBChangeNotification;
+}
+
+SwXDispatchProviderInterceptor::DispatchMutexLock_Impl::DispatchMutexLock_Impl()
+{
+}
+
+SwXDispatchProviderInterceptor::DispatchMutexLock_Impl::~DispatchMutexLock_Impl()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/uno/unodoc.cxx b/sw/source/uibase/uno/unodoc.cxx
new file mode 100644
index 000000000..b525d2e36
--- /dev/null
+++ b/sw/source/uibase/uno/unodoc.cxx
@@ -0,0 +1,93 @@
+/* -*- 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 <sal/config.h>
+#include <config_features.h>
+#include <config_fuzzers.h>
+
+#include <sfx2/sfxmodelfactory.hxx>
+#include <swdll.hxx>
+#include <docsh.hxx>
+#include <globdoc.hxx>
+#include <wdocsh.hxx>
+#include <vcl/svapp.hxx>
+#include <unomailmerge.hxx>
+
+using namespace ::com::sun::star;
+
+// com.sun.star.comp.Writer.TextDocument
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+Writer_SwTextDocument_get_implementation(
+ css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const& args)
+{
+ SolarMutexGuard aGuard;
+ SwGlobals::ensure();
+ css::uno::Reference<css::uno::XInterface> xInterface = sfx2::createSfxModelInstance(args,
+ [](SfxModelFlags _nCreationFlags)
+ {
+ SfxObjectShell* pShell = new SwDocShell( _nCreationFlags );
+ return pShell->GetModel();
+ });
+ xInterface->acquire();
+ return xInterface.get();
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+com_sun_star_comp_Writer_WebDocument_get_implementation(css::uno::XComponentContext*,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ SolarMutexGuard aGuard;
+ SwGlobals::ensure();
+ SfxObjectShell* pShell = new SwWebDocShell;
+ uno::Reference< uno::XInterface > model( pShell->GetModel() );
+ model->acquire();
+ return model.get();
+}
+
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+com_sun_star_comp_Writer_GlobalDocument_get_implementation(css::uno::XComponentContext*,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ SolarMutexGuard aGuard;
+ SwGlobals::ensure();
+ SfxObjectShell* pShell = new SwGlobalDocShell( SfxObjectCreateMode::STANDARD );
+ uno::Reference< uno::XInterface > model( pShell->GetModel() );
+ model->acquire();
+ return model.get();
+}
+
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+SwXMailMerge_get_implementation(css::uno::XComponentContext*,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ SolarMutexGuard aGuard;
+
+ //the module may not be loaded
+ SwGlobals::ensure();
+ return cppu::acquire(new SwXMailMerge());
+#else
+ return nullptr;
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/uno/unomailmerge.cxx b/sw/source/uibase/uno/unomailmerge.cxx
new file mode 100644
index 000000000..89aa97861
--- /dev/null
+++ b/sw/source/uibase/uno/unomailmerge.cxx
@@ -0,0 +1,1168 @@
+/* -*- 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 <comphelper/servicehelper.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/mutex.hxx>
+#include <svl/itemprop.hxx>
+#include <svx/dataaccessdescriptor.hxx>
+#include <unotools/tempfile.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/docfilt.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/diagnose_ex.h>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/string.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <vcl/timer.hxx>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/text/MailMergeType.hpp>
+#include <com/sun/star/text/MailMergeEvent.hpp>
+#include <com/sun/star/text/XMailMergeListener.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/util/CloseVetoException.hpp>
+#include <com/sun/star/sdbcx/XRowLocate.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/mail/XSmtpService.hpp>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/event.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <printdata.hxx>
+#include <swevent.hxx>
+#include <unomailmerge.hxx>
+#include <unoprnms.hxx>
+#include <unomap.hxx>
+#include <swunohelper.hxx>
+#include <docsh.hxx>
+#include <IDocumentDeviceAccess.hxx>
+#include <view.hxx>
+#include <dbmgr.hxx>
+#include <unotxdoc.hxx>
+#include <wrtsh.hxx>
+#include <mmconfigitem.hxx>
+#include <mailmergehelper.hxx>
+
+#include <iodetect.hxx>
+
+#include <memory>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::text;
+using namespace SWUnoHelper;
+
+typedef ::utl::SharedUNOComponent< XInterface > SharedComponent;
+
+static osl::Mutex & GetMailMergeMutex()
+{
+ static osl::Mutex aMutex;
+ return aMutex;
+}
+
+namespace {
+
+enum CloseResult
+{
+ eSuccess, // successfully closed
+ eVetoed, // vetoed, ownership transferred to the vetoing instance
+ eFailed // failed for some unknown reason
+};
+
+}
+
+static CloseResult CloseModelAndDocSh(
+ Reference< frame::XModel > const &rxModel,
+ SfxObjectShellRef &rxDocSh )
+{
+ CloseResult eResult = eSuccess;
+
+ rxDocSh = nullptr;
+
+ //! models/documents should never be disposed (they may still be
+ //! used for printing which is called asynchronously for example)
+ //! instead call close
+ Reference< util::XCloseable > xClose( rxModel, UNO_QUERY );
+ if (xClose.is())
+ {
+ try
+ {
+ //! 'sal_True' -> transfer ownership to vetoing object if vetoed!
+ //! I.e. now that object is responsible for closing the model and doc shell.
+ xClose->close( true );
+ }
+ catch (const util::CloseVetoException&)
+ {
+ //! here we have the problem that the temporary file that is
+ //! currently being printed will never be deleted. :-(
+ eResult = eVetoed;
+ }
+ catch (const uno::RuntimeException&)
+ {
+ eResult = eFailed;
+ }
+ }
+ return eResult;
+}
+
+/// @throws RuntimeException
+static bool LoadFromURL_impl(
+ Reference< frame::XModel > &rxModel,
+ SfxObjectShellRef &rxDocSh,
+ const OUString &rURL,
+ bool bClose )
+{
+ // try to open the document readonly and hidden
+ Reference< frame::XModel > xTmpModel;
+ Sequence < PropertyValue > aArgs{ comphelper::makePropertyValue("Hidden", true) };
+ try
+ {
+ Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
+ xTmpModel.set( xDesktop->loadComponentFromURL( rURL, "_blank", 0, aArgs ), UNO_QUERY );
+ }
+ catch (const Exception&)
+ {
+ return false;
+ }
+
+ // try to get the DocShell
+ SwDocShell *pTmpDocShell = nullptr;
+ if (auto pTextDoc = comphelper::getFromUnoTunnel<SwXTextDocument>(xTmpModel); pTextDoc)
+ pTmpDocShell = pTextDoc->GetDocShell();
+
+ bool bRes = false;
+ if (xTmpModel.is() && pTmpDocShell) // everything available?
+ {
+ if (bClose)
+ CloseModelAndDocSh( rxModel, rxDocSh );
+ // set new stuff
+ rxModel = xTmpModel;
+ rxDocSh = pTmpDocShell;
+ bRes = true;
+ }
+ else
+ {
+ // SfxObjectShellRef is ok here, since the document will be explicitly closed
+ SfxObjectShellRef xTmpDocSh = pTmpDocShell;
+ CloseModelAndDocSh( xTmpModel, xTmpDocSh );
+ }
+
+ return bRes;
+}
+
+namespace
+{
+ class DelayedFileDeletion : public ::cppu::WeakImplHelper<util::XCloseListener>
+ {
+ protected:
+ ::osl::Mutex m_aMutex;
+ Reference< util::XCloseable > m_xDocument;
+ Timer m_aDeleteTimer;
+ OUString m_sTemporaryFile;
+ sal_Int32 m_nPendingDeleteAttempts;
+
+ DelayedFileDeletion(DelayedFileDeletion const&) = delete;
+ DelayedFileDeletion& operator=(DelayedFileDeletion const&) = delete;
+
+ public:
+ DelayedFileDeletion( const Reference< XModel >& _rxModel,
+ const OUString& _rTemporaryFile );
+
+ protected:
+ virtual ~DelayedFileDeletion( ) override;
+
+ // XCloseListener
+ virtual void SAL_CALL queryClosing( const EventObject& _rSource, sal_Bool _bGetsOwnership ) override;
+ virtual void SAL_CALL notifyClosing( const EventObject& _rSource ) override;
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const EventObject& Source ) override;
+
+ private:
+ void implTakeOwnership( );
+ DECL_LINK( OnTryDeleteFile, Timer*, void );
+ };
+
+ DelayedFileDeletion::DelayedFileDeletion( const Reference< XModel >& _rxModel, const OUString& _rTemporaryFile )
+ :
+ m_xDocument( _rxModel, UNO_QUERY )
+ ,m_aDeleteTimer("sw DelayedFileDeletion m_aDeleteTimer")
+ ,m_sTemporaryFile( _rTemporaryFile )
+ ,m_nPendingDeleteAttempts( 0 )
+ {
+ osl_atomic_increment( &m_refCount );
+ try
+ {
+ if ( m_xDocument.is() )
+ {
+ m_xDocument->addCloseListener( this );
+ // successfully added -> keep ourself alive
+ acquire();
+ }
+ else {
+ OSL_FAIL("DelayedFileDeletion::DelayedFileDeletion: model is no component!" );
+ }
+ }
+ catch (const Exception&)
+ {
+ OSL_FAIL("DelayedFileDeletion::DelayedFileDeletion: could not register as event listener at the model!" );
+ }
+ osl_atomic_decrement( &m_refCount );
+ }
+
+ IMPL_LINK_NOARG(DelayedFileDeletion, OnTryDeleteFile, Timer *, void)
+ {
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ bool bSuccess = false;
+ try
+ {
+ bool bDeliverOwnership = ( 0 == m_nPendingDeleteAttempts );
+ // if this is our last attempt, then anybody which vetoes this has to take the consequences
+ // (means take the ownership)
+ m_xDocument->close( bDeliverOwnership );
+ bSuccess = true;
+ }
+ catch (const util::CloseVetoException&)
+ {
+ // somebody vetoed -> next try
+ if ( m_nPendingDeleteAttempts )
+ {
+ // next attempt
+ --m_nPendingDeleteAttempts;
+ m_aDeleteTimer.Start();
+ }
+ else
+ bSuccess = true; // can't do anything here ...
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "sw", "DelayedFileDeletion::OnTryDeleteFile: caught a strange exception!" );
+ bSuccess = true;
+ // can't do anything here ...
+ }
+
+ if ( bSuccess )
+ {
+ SWUnoHelper::UCB_DeleteFile( m_sTemporaryFile );
+ aGuard.clear();
+ release(); // this should be our last reference, we should be dead after this
+ }
+ }
+
+ void DelayedFileDeletion::implTakeOwnership( )
+ {
+ // revoke ourself as listener
+ try
+ {
+ m_xDocument->removeCloseListener( this );
+ }
+ catch (const Exception&)
+ {
+ OSL_FAIL("DelayedFileDeletion::implTakeOwnership: could not revoke the listener!" );
+ }
+
+ m_aDeleteTimer.SetTimeout( 3000 ); // 3 seconds
+ m_aDeleteTimer.SetInvokeHandler( LINK( this, DelayedFileDeletion, OnTryDeleteFile ) );
+ m_nPendingDeleteAttempts = 3; // try 3 times at most
+ m_aDeleteTimer.Start( );
+ }
+
+ void SAL_CALL DelayedFileDeletion::queryClosing( const EventObject& , sal_Bool _bGetsOwnership )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( _bGetsOwnership )
+ implTakeOwnership( );
+
+ // always veto: We want to take the ownership ourself, as this is the only chance to delete
+ // the temporary file which the model is based on
+ throw util::CloseVetoException( );
+ }
+
+ void SAL_CALL DelayedFileDeletion::notifyClosing( const EventObject& )
+ {
+ OSL_FAIL("DelayedFileDeletion::notifyClosing: how this?" );
+ // this should not happen:
+ // Either, a foreign instance closes the document, then we should veto this, and take the ownership
+ // Or, we ourself close the document, then we should not be a listener anymore
+ }
+
+ void SAL_CALL DelayedFileDeletion::disposing( const EventObject& )
+ {
+ OSL_FAIL("DelayedFileDeletion::disposing: how this?" );
+ // this should not happen:
+ // Either, a foreign instance closes the document, then we should veto this, and take the ownership
+ // Or, we ourself close the document, then we should not be a listener anymore
+ }
+
+ DelayedFileDeletion::~DelayedFileDeletion( )
+ {
+ }
+}
+
+static bool DeleteTmpFile_Impl(
+ Reference< frame::XModel > &rxModel,
+ SfxObjectShellRef &rxDocSh,
+ const OUString &rTmpFileURL )
+{
+ bool bRes = false;
+ if (!rTmpFileURL.isEmpty())
+ {
+ bool bDelete = true;
+ if ( eVetoed == CloseModelAndDocSh( rxModel, rxDocSh ) )
+ {
+ // somebody vetoed the closing, and took the ownership of the document
+ // -> ensure that the temporary file is deleted later on
+ new DelayedFileDeletion( rxModel, rTmpFileURL );
+ // note: as soon as #106931# is fixed, the whole DelayedFileDeletion is to be superseded by
+ // a better solution
+ bDelete = false;
+ }
+
+ rxModel = nullptr;
+ rxDocSh = nullptr; // destroy doc shell
+
+ if ( bDelete )
+ {
+ if ( !SWUnoHelper::UCB_DeleteFile( rTmpFileURL ) )
+ {
+ new DelayedFileDeletion( rxModel, rTmpFileURL );
+ // same not as above: as soon as #106931#, ...
+ }
+ }
+ else
+ bRes = true; // file will be deleted delayed
+ }
+ return bRes;
+}
+
+SwXMailMerge::SwXMailMerge() :
+ m_aEvtListeners ( GetMailMergeMutex() ),
+ m_aMergeListeners ( GetMailMergeMutex() ),
+ m_aPropListeners ( GetMailMergeMutex() ),
+ m_pPropSet( aSwMapProvider.GetPropertySet( PROPERTY_MAP_MAILMERGE ) ),
+ m_nDataCommandType(sdb::CommandType::TABLE),
+ m_nOutputType(MailMergeType::PRINTER),
+ m_bEscapeProcessing(true), //!! allow to process properties like "Filter", "Order", ...
+ m_bSinglePrintJobs(false),
+ m_bFileNameFromColumn(false),
+ m_bSendAsHTML(false),
+ m_bSendAsAttachment(false),
+ m_bSaveAsSingleFile(false),
+ m_bDisposing(false),
+ m_pMgr(nullptr)
+{
+ // create empty document
+ // like in: SwModule::InsertEnv (appenv.cxx)
+ m_xDocSh = new SwDocShell( SfxObjectCreateMode::STANDARD );
+ m_xDocSh->DoInitNew();
+ SfxViewFrame *pFrame = SfxViewFrame::LoadHiddenDocument( *m_xDocSh, SFX_INTERFACE_NONE );
+ SwView *pView = static_cast<SwView*>( pFrame->GetViewShell() );
+ pView->AttrChangedNotify(nullptr); //So that SelectShell is called.
+ m_xModel = m_xDocSh->GetModel();
+}
+
+SwXMailMerge::~SwXMailMerge()
+{
+ if (!m_aTmpFileName.isEmpty())
+ DeleteTmpFile_Impl( m_xModel, m_xDocSh, m_aTmpFileName );
+ else // there was no temporary file in use
+ {
+ //! we still need to close the model and doc shell manually
+ //! because there is no automatism that will do that later.
+ //! #120086#
+ if ( eVetoed == CloseModelAndDocSh( m_xModel, m_xDocSh ) )
+ OSL_FAIL("ownership transferred to vetoing object!" );
+
+ m_xModel = nullptr;
+ m_xDocSh = nullptr; // destroy doc shell
+ }
+}
+
+// Guarantee object consistence in case of an exception
+class MailMergeExecuteFinalizer
+{
+public:
+ explicit MailMergeExecuteFinalizer(SwXMailMerge *mailmerge)
+ : m_pMailMerge(mailmerge)
+ {
+ assert(m_pMailMerge); //mailmerge object missing
+ }
+ ~MailMergeExecuteFinalizer()
+ {
+ osl::MutexGuard aMgrGuard( GetMailMergeMutex() );
+ m_pMailMerge->m_pMgr = nullptr;
+ }
+
+private:
+ MailMergeExecuteFinalizer(MailMergeExecuteFinalizer const&) = delete;
+ MailMergeExecuteFinalizer& operator=(MailMergeExecuteFinalizer const&) = delete;
+
+ SwXMailMerge *m_pMailMerge;
+};
+
+uno::Any SAL_CALL SwXMailMerge::execute(
+ const uno::Sequence< beans::NamedValue >& rArguments )
+{
+ SolarMutexGuard aGuard;
+ MailMergeExecuteFinalizer aFinalizer(this);
+
+ // get property values to be used
+ // (use values from the service as default and override them with
+ // the values that are provided as arguments)
+
+ uno::Sequence< uno::Any > aCurSelection = m_aSelection;
+ uno::Reference< sdbc::XResultSet > xCurResultSet = m_xResultSet;
+ uno::Reference< sdbc::XConnection > xCurConnection = m_xConnection;
+ uno::Reference< frame::XModel > xCurModel = m_xModel;
+ OUString aCurDataSourceName = m_aDataSourceName;
+ OUString aCurDataCommand = m_aDataCommand;
+ OUString aCurFilter = m_aFilter;
+ OUString aCurDocumentURL = m_aDocumentURL;
+ OUString aCurOutputURL = m_aOutputURL;
+ OUString aCurFileNamePrefix = m_aFileNamePrefix;
+ sal_Int32 nCurDataCommandType = m_nDataCommandType;
+ sal_Int16 nCurOutputType = m_nOutputType;
+ bool bCurEscapeProcessing = m_bEscapeProcessing;
+ bool bCurSinglePrintJobs = m_bSinglePrintJobs;
+ bool bCurFileNameFromColumn = m_bFileNameFromColumn;
+
+ SfxObjectShellRef xCurDocSh = m_xDocSh; // the document
+
+ for (const beans::NamedValue& rArgument : rArguments)
+ {
+ const OUString &rName = rArgument.Name;
+ const Any &rValue = rArgument.Value;
+
+ bool bOK = true;
+ if (rName == UNO_NAME_SELECTION)
+ bOK = rValue >>= aCurSelection;
+ else if (rName == UNO_NAME_RESULT_SET)
+ bOK = rValue >>= xCurResultSet;
+ else if (rName == UNO_NAME_CONNECTION)
+ bOK = rValue >>= xCurConnection;
+ else if (rName == UNO_NAME_MODEL)
+ throw PropertyVetoException("Property is read-only: " + rName, static_cast < cppu::OWeakObject * > ( this ) );
+ else if (rName == UNO_NAME_DATA_SOURCE_NAME)
+ bOK = rValue >>= aCurDataSourceName;
+ else if (rName == UNO_NAME_DAD_COMMAND)
+ bOK = rValue >>= aCurDataCommand;
+ else if (rName == UNO_NAME_FILTER)
+ bOK = rValue >>= aCurFilter;
+ else if (rName == UNO_NAME_DOCUMENT_URL)
+ {
+ bOK = rValue >>= aCurDocumentURL;
+ if (!aCurDocumentURL.isEmpty()
+ && !LoadFromURL_impl( xCurModel, xCurDocSh, aCurDocumentURL, false ))
+ throw RuntimeException("Failed to create document from URL: " + aCurDocumentURL, static_cast < cppu::OWeakObject * > ( this ) );
+ }
+ else if (rName == UNO_NAME_OUTPUT_URL)
+ {
+ bOK = rValue >>= aCurOutputURL;
+ if (!aCurOutputURL.isEmpty())
+ {
+ if (!UCB_IsDirectory(aCurOutputURL))
+ throw IllegalArgumentException("URL does not point to a directory: " + aCurOutputURL, static_cast < cppu::OWeakObject * > ( this ), 0 );
+ if (UCB_IsReadOnlyFileName(aCurOutputURL))
+ throw IllegalArgumentException("URL is read-only: " + aCurOutputURL, static_cast < cppu::OWeakObject * > ( this ), 0 );
+ }
+ }
+ else if (rName == UNO_NAME_FILE_NAME_PREFIX)
+ bOK = rValue >>= aCurFileNamePrefix;
+ else if (rName == UNO_NAME_DAD_COMMAND_TYPE)
+ bOK = rValue >>= nCurDataCommandType;
+ else if (rName == UNO_NAME_OUTPUT_TYPE)
+ bOK = rValue >>= nCurOutputType;
+ else if (rName == UNO_NAME_ESCAPE_PROCESSING)
+ bOK = rValue >>= bCurEscapeProcessing;
+ else if (rName == UNO_NAME_SINGLE_PRINT_JOBS)
+ bOK = rValue >>= bCurSinglePrintJobs;
+ else if (rName == UNO_NAME_FILE_NAME_FROM_COLUMN)
+ bOK = rValue >>= bCurFileNameFromColumn;
+ else if (rName == UNO_NAME_SUBJECT)
+ bOK = rValue >>= m_sSubject;
+ else if (rName == UNO_NAME_ADDRESS_FROM_COLUMN)
+ bOK = rValue >>= m_sAddressFromColumn;
+ else if (rName == UNO_NAME_SEND_AS_HTML)
+ bOK = rValue >>= m_bSendAsHTML;
+ else if (rName == UNO_NAME_MAIL_BODY)
+ bOK = rValue >>= m_sMailBody;
+ else if (rName == UNO_NAME_ATTACHMENT_NAME)
+ bOK = rValue >>= m_sAttachmentName;
+ else if (rName == UNO_NAME_ATTACHMENT_FILTER)
+ bOK = rValue >>= m_sAttachmentFilter;
+ else if (rName == UNO_NAME_COPIES_TO)
+ bOK = rValue >>= m_aCopiesTo;
+ else if (rName == UNO_NAME_BLIND_COPIES_TO)
+ bOK = rValue >>= m_aBlindCopiesTo;
+ else if (rName == UNO_NAME_SEND_AS_ATTACHMENT)
+ bOK = rValue >>= m_bSendAsAttachment;
+ else if (rName == UNO_NAME_PRINT_OPTIONS)
+ bOK = rValue >>= m_aPrintSettings;
+ else if (rName == UNO_NAME_SAVE_AS_SINGLE_FILE)
+ bOK = rValue >>= m_bSaveAsSingleFile;
+ else if (rName == UNO_NAME_SAVE_FILTER)
+ bOK = rValue >>= m_sSaveFilter;
+ else if (rName == UNO_NAME_SAVE_FILTER_OPTIONS)
+ bOK = rValue >>= m_sSaveFilterOptions;
+ else if (rName == UNO_NAME_SAVE_FILTER_DATA)
+ bOK = rValue >>= m_aSaveFilterData;
+ else if (rName == UNO_NAME_IN_SERVER_PASSWORD)
+ bOK = rValue >>= m_sInServerPassword;
+ else if (rName == UNO_NAME_OUT_SERVER_PASSWORD)
+ bOK = rValue >>= m_sOutServerPassword;
+ else
+ throw UnknownPropertyException( "Property is unknown: " + rName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ if (!bOK)
+ throw IllegalArgumentException("Property type mismatch or property not set: " + rName, static_cast < cppu::OWeakObject * > ( this ), 0 );
+ }
+
+ // need to translate the selection: the API here requires a sequence of bookmarks, but the Merge
+ // method we will call below requires a sequence of indices.
+ if ( aCurSelection.hasElements() )
+ {
+ Sequence< Any > aTranslated( aCurSelection.getLength() );
+
+ bool bValid = false;
+ Reference< sdbcx::XRowLocate > xRowLocate( xCurResultSet, UNO_QUERY );
+ if ( xRowLocate.is() )
+ {
+ Any* pTranslated = aTranslated.getArray();
+
+ try
+ {
+ bool bEverythingsFine = true;
+ for ( const Any& rBookmark : std::as_const(aCurSelection) )
+ {
+ bEverythingsFine = xRowLocate->moveToBookmark( rBookmark );
+ if ( !bEverythingsFine )
+ break;
+ *pTranslated <<= xCurResultSet->getRow();
+ ++pTranslated;
+ }
+ if ( bEverythingsFine )
+ bValid = true;
+ }
+ catch (const Exception&)
+ {
+ bValid = false;
+ }
+ }
+
+ if ( !bValid )
+ {
+ throw IllegalArgumentException(
+ "The current 'Selection' does not describe a valid array of bookmarks, relative to the current 'ResultSet'.",
+ static_cast < cppu::OWeakObject * > ( this ),
+ 0
+ );
+ }
+
+ aCurSelection = aTranslated;
+ }
+
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( xCurDocSh.get(), false);
+ SwView *pView = pFrame ? dynamic_cast<SwView*>( pFrame->GetViewShell() ) : nullptr;
+ if (!pView)
+ throw RuntimeException();
+ SwWrtShell &rSh = *pView->GetWrtShellPtr();
+
+ // avoid assertion in 'Update' from Sfx by supplying a shell
+ // and thus avoiding the SelectShell call in Writers GetState function
+ // while still in Update of Sfx.
+ // (GetSelection in Update is not allowed)
+ if (!aCurDocumentURL.isEmpty())
+ pView->AttrChangedNotify(nullptr);//So that SelectShell is called.
+
+ SharedComponent aRowSetDisposeHelper;
+ if (!xCurResultSet.is())
+ {
+ if (aCurDataSourceName.isEmpty() || aCurDataCommand.isEmpty() )
+ {
+ OSL_FAIL("PropertyValues missing or unset");
+ throw IllegalArgumentException("Either the ResultSet or DataSourceName and DataCommand must be set.", static_cast < cppu::OWeakObject * > ( this ), 0 );
+ }
+
+ // build ResultSet from DataSourceName, DataCommand and DataCommandType
+
+ Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
+ if (xMgr.is())
+ {
+ Reference< XInterface > xInstance = xMgr->createInstance( "com.sun.star.sdb.RowSet" );
+ aRowSetDisposeHelper.reset( xInstance, SharedComponent::TakeOwnership );
+ Reference< XPropertySet > xRowSetPropSet( xInstance, UNO_QUERY );
+ OSL_ENSURE( xRowSetPropSet.is(), "failed to get XPropertySet interface from RowSet" );
+ if (xRowSetPropSet.is())
+ {
+ if (xCurConnection.is())
+ xRowSetPropSet->setPropertyValue( "ActiveConnection", Any( xCurConnection ) );
+ xRowSetPropSet->setPropertyValue( "DataSourceName", Any( aCurDataSourceName ) );
+ xRowSetPropSet->setPropertyValue( "Command", Any( aCurDataCommand ) );
+ xRowSetPropSet->setPropertyValue( "CommandType", Any( nCurDataCommandType ) );
+ xRowSetPropSet->setPropertyValue( "EscapeProcessing", Any( bCurEscapeProcessing ) );
+ xRowSetPropSet->setPropertyValue( "ApplyFilter", Any( true ) );
+ xRowSetPropSet->setPropertyValue( "Filter", Any( aCurFilter ) );
+
+ Reference< sdbc::XRowSet > xRowSet( xInstance, UNO_QUERY );
+ if (xRowSet.is())
+ xRowSet->execute(); // build ResultSet from properties
+ if( !xCurConnection.is() )
+ xCurConnection.set( xRowSetPropSet->getPropertyValue( "ActiveConnection" ), UNO_QUERY );
+ xCurResultSet = xRowSet;
+ OSL_ENSURE( xCurResultSet.is(), "failed to build ResultSet" );
+ }
+ }
+ }
+
+ svx::ODataAccessDescriptor aDescriptor;
+ aDescriptor.setDataSource(aCurDataSourceName);
+ aDescriptor[ svx::DataAccessDescriptorProperty::Connection ] <<= xCurConnection;
+ aDescriptor[ svx::DataAccessDescriptorProperty::Command ] <<= aCurDataCommand;
+ aDescriptor[ svx::DataAccessDescriptorProperty::CommandType ] <<= nCurDataCommandType;
+ aDescriptor[ svx::DataAccessDescriptorProperty::EscapeProcessing ] <<= bCurEscapeProcessing;
+ aDescriptor[ svx::DataAccessDescriptorProperty::Cursor ] <<= xCurResultSet;
+ // aDescriptor[ svx::DataAccessDescriptorProperty::ColumnName ] not used
+ // aDescriptor[ svx::DataAccessDescriptorProperty::ColumnObject ] not used
+ aDescriptor[ svx::DataAccessDescriptorProperty::Selection ] <<= aCurSelection;
+
+ DBManagerOptions nMergeType;
+ switch (nCurOutputType)
+ {
+ case MailMergeType::PRINTER : nMergeType = DBMGR_MERGE_PRINTER; break;
+ case MailMergeType::FILE : nMergeType = DBMGR_MERGE_FILE; break;
+ case MailMergeType::MAIL : nMergeType = DBMGR_MERGE_EMAIL; break;
+ case MailMergeType::SHELL : nMergeType = DBMGR_MERGE_SHELL; break;
+ default:
+ throw IllegalArgumentException("Invalid value of property: OutputType", static_cast < cppu::OWeakObject * > ( this ), 0 );
+ }
+
+ SwDBManager* pMgr = rSh.GetDBManager();
+ //force layout creation
+ rSh.CalcLayout();
+ OSL_ENSURE( pMgr, "database manager missing" );
+ m_pMgr = pMgr;
+
+ SwMergeDescriptor aMergeDesc( nMergeType, rSh, aDescriptor );
+
+ std::unique_ptr< SwMailMergeConfigItem > pMMConfigItem;
+ uno::Reference< mail::XMailService > xInService;
+ switch (nCurOutputType)
+ {
+ case MailMergeType::PRINTER:
+ {
+ IDocumentDeviceAccess& rIDDA = rSh.getIDocumentDeviceAccess();
+ SwPrintData aPrtData( rIDDA.getPrintData() );
+ aPrtData.SetPrintSingleJobs( bCurSinglePrintJobs );
+ rIDDA.setPrintData( aPrtData );
+ // #i25686# printing should not be done asynchronously to prevent dangling offices
+ // when mail merge is called as command line macro
+ aMergeDesc.aPrintOptions = m_aPrintSettings;
+ aMergeDesc.bCreateSingleFile = true;
+ }
+ break;
+ case MailMergeType::SHELL:
+ aMergeDesc.bCreateSingleFile = true;
+ pMMConfigItem.reset(new SwMailMergeConfigItem);
+ aMergeDesc.pMailMergeConfigItem = pMMConfigItem.get();
+ break;
+ case MailMergeType::FILE:
+ {
+ INetURLObject aURLObj;
+ aURLObj.SetSmartProtocol( INetProtocol::File );
+
+ if (!aCurDocumentURL.isEmpty())
+ {
+ // if OutputURL or FileNamePrefix are missing get
+ // them from DocumentURL
+ aURLObj.SetSmartURL( aCurDocumentURL );
+ if (aCurFileNamePrefix.isEmpty())
+ aCurFileNamePrefix = aURLObj.GetBase(); // filename without extension
+ if (aCurOutputURL.isEmpty())
+ {
+ aURLObj.removeSegment();
+ aCurOutputURL = aURLObj.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
+ }
+ }
+ else // default empty document without URL
+ {
+ if (aCurOutputURL.isEmpty())
+ throw RuntimeException("OutputURL is not set and can not be obtained.", static_cast < cppu::OWeakObject * > ( this ) );
+ }
+
+ aURLObj.SetSmartURL( aCurOutputURL );
+ OUString aPath = aURLObj.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
+
+ static const OUStringLiteral aDelim( u"/" );
+ if (!aPath.isEmpty() && !aPath.endsWith(aDelim))
+ aPath += aDelim;
+ if (bCurFileNameFromColumn)
+ aMergeDesc.sDBcolumn = aCurFileNamePrefix;
+ else
+ {
+ aPath += aCurFileNamePrefix;
+ }
+
+ aMergeDesc.sPrefix = aPath;
+ aMergeDesc.sSaveToFilter = m_sSaveFilter;
+ aMergeDesc.sSaveToFilterOptions = m_sSaveFilterOptions;
+ aMergeDesc.aSaveToFilterData = m_aSaveFilterData;
+ aMergeDesc.bCreateSingleFile = m_bSaveAsSingleFile;
+ }
+ break;
+ case MailMergeType::MAIL:
+ {
+ aMergeDesc.sDBcolumn = m_sAddressFromColumn;
+ if(m_sAddressFromColumn.isEmpty())
+ throw RuntimeException("Mail address column not set.", static_cast < cppu::OWeakObject * > ( this ) );
+ aMergeDesc.sSaveToFilter = m_sAttachmentFilter;
+ aMergeDesc.sSubject = m_sSubject;
+ aMergeDesc.sMailBody = m_sMailBody;
+ aMergeDesc.sAttachmentName = m_sAttachmentName;
+ aMergeDesc.aCopiesTo = m_aCopiesTo;
+ aMergeDesc.aBlindCopiesTo = m_aBlindCopiesTo;
+ aMergeDesc.bSendAsHTML = m_bSendAsHTML;
+ aMergeDesc.bSendAsAttachment = m_bSendAsAttachment;
+
+ aMergeDesc.bCreateSingleFile = false;
+ pMMConfigItem.reset(new SwMailMergeConfigItem);
+ aMergeDesc.pMailMergeConfigItem = pMMConfigItem.get();
+ aMergeDesc.xSmtpServer = SwMailMergeHelper::ConnectToSmtpServer(
+ *pMMConfigItem,
+ xInService,
+ m_sInServerPassword, m_sOutServerPassword );
+ if( !aMergeDesc.xSmtpServer.is() || !aMergeDesc.xSmtpServer->isConnected())
+ throw RuntimeException("Failed to connect to mail server.", static_cast < cppu::OWeakObject * > ( this ) );
+ }
+ break;
+ }
+
+ // save document with temporary filename
+ std::shared_ptr<const SfxFilter> pSfxFlt = SwIoSystem::GetFilterOfFormat(
+ FILTER_XML,
+ SwDocShell::Factory().GetFilterContainer() );
+ OUString aExtension(comphelper::string::stripStart(pSfxFlt->GetDefaultExtension(), '*'));
+ utl::TempFile aTempFile( u"SwMM", true, &aExtension );
+ m_aTmpFileName = aTempFile.GetURL();
+
+ Reference< XStorable > xStorable( xCurModel, UNO_QUERY );
+ bool bStoredAsTemporary = false;
+ if ( xStorable.is() )
+ {
+ try
+ {
+ xStorable->storeAsURL( m_aTmpFileName, Sequence< PropertyValue >() );
+ bStoredAsTemporary = true;
+ }
+ catch (const Exception&)
+ {
+ }
+ }
+ if ( !bStoredAsTemporary )
+ throw RuntimeException("Failed to save temporary file.", static_cast < cppu::OWeakObject * > ( this ) );
+
+ pMgr->SetMergeSilent( true ); // suppress dialogs, message boxes, etc.
+ const SwXMailMerge *pOldSrc = pMgr->GetMailMergeEvtSrc();
+ OSL_ENSURE( !pOldSrc || pOldSrc == this, "Ooops... different event source already set." );
+ pMgr->SetMailMergeEvtSrc( this ); // launch events for listeners
+
+ SfxGetpApp()->NotifyEvent(SfxEventHint(SfxEventHintId::SwMailMerge, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE), xCurDocSh.get()));
+ bool bSucc = pMgr->Merge( aMergeDesc );
+ SfxGetpApp()->NotifyEvent(SfxEventHint(SfxEventHintId::SwMailMergeEnd, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE_END), xCurDocSh.get()));
+
+ pMgr->SetMailMergeEvtSrc( pOldSrc );
+
+ if ( xCurModel.get() != m_xModel.get() )
+ { // in case it was a temporary model -> close it, and delete the file
+ DeleteTmpFile_Impl( xCurModel, xCurDocSh, m_aTmpFileName );
+ m_aTmpFileName.clear();
+ }
+ // (in case it wasn't a temporary model, it will be closed in the dtor, at the latest)
+
+ if (!bSucc)
+ throw Exception("Mail merge failed. Sorry, no further information available.", static_cast < cppu::OWeakObject * > ( this ) );
+
+ //de-initialize services
+ if(xInService.is() && xInService->isConnected())
+ xInService->disconnect();
+ if(aMergeDesc.xSmtpServer.is() && aMergeDesc.xSmtpServer->isConnected())
+ aMergeDesc.xSmtpServer->disconnect();
+
+ if (DBMGR_MERGE_SHELL == nMergeType)
+ {
+ return Any( aMergeDesc.pMailMergeConfigItem->GetTargetView()->GetDocShell()->GetBaseModel() );
+ }
+ else
+ return Any( true );
+}
+
+void SAL_CALL SwXMailMerge::cancel()
+{
+ // Cancel may be called from a second thread, so this protects from m_pMgr
+ /// cleanup in the execute function.
+ osl::MutexGuard aMgrGuard( GetMailMergeMutex() );
+ if (m_pMgr)
+ m_pMgr->MergeCancel();
+}
+
+void SwXMailMerge::LaunchMailMergeEvent( const MailMergeEvent &rEvt ) const
+{
+ comphelper::OInterfaceIteratorHelper2 aIt( const_cast<SwXMailMerge *>(this)->m_aMergeListeners );
+ while (aIt.hasMoreElements())
+ {
+ static_cast< XMailMergeListener* >( aIt.next() )->notifyMailMergeEvent( rEvt );
+ }
+}
+
+void SwXMailMerge::launchEvent( const PropertyChangeEvent &rEvt ) const
+{
+ comphelper::OInterfaceContainerHelper3<XPropertyChangeListener> *pContainer =
+ m_aPropListeners.getContainer( rEvt.PropertyHandle );
+ if (pContainer)
+ {
+ pContainer->notifyEach( &XPropertyChangeListener::propertyChange, rEvt );
+ }
+}
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL SwXMailMerge::getPropertySetInfo( )
+{
+ SolarMutexGuard aGuard;
+ static Reference< XPropertySetInfo > aRef = m_pPropSet->getPropertySetInfo();
+ return aRef;
+}
+
+void SAL_CALL SwXMailMerge::setPropertyValue(
+ const OUString& rPropertyName, const uno::Any& rValue )
+{
+ SolarMutexGuard aGuard;
+
+ const SfxItemPropertyMapEntry* pCur = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if (!pCur)
+ throw UnknownPropertyException(rPropertyName);
+ else if (pCur->nFlags & PropertyAttribute::READONLY)
+ throw PropertyVetoException();
+ else
+ {
+ void *pData = nullptr;
+ switch (pCur->nWID)
+ {
+ case WID_SELECTION : pData = &m_aSelection; break;
+ case WID_RESULT_SET : pData = &m_xResultSet; break;
+ case WID_CONNECTION : pData = &m_xConnection; break;
+ case WID_MODEL : pData = &m_xModel; break;
+ case WID_DATA_SOURCE_NAME : pData = &m_aDataSourceName; break;
+ case WID_DATA_COMMAND : pData = &m_aDataCommand; break;
+ case WID_FILTER : pData = &m_aFilter; break;
+ case WID_DOCUMENT_URL : pData = &m_aDocumentURL; break;
+ case WID_OUTPUT_URL : pData = &m_aOutputURL; break;
+ case WID_DATA_COMMAND_TYPE : pData = &m_nDataCommandType; break;
+ case WID_OUTPUT_TYPE : pData = &m_nOutputType; break;
+ case WID_ESCAPE_PROCESSING : pData = &m_bEscapeProcessing; break;
+ case WID_SINGLE_PRINT_JOBS : pData = &m_bSinglePrintJobs; break;
+ case WID_FILE_NAME_FROM_COLUMN : pData = &m_bFileNameFromColumn; break;
+ case WID_FILE_NAME_PREFIX : pData = &m_aFileNamePrefix; break;
+ case WID_MAIL_SUBJECT: pData = &m_sSubject; break;
+ case WID_ADDRESS_FROM_COLUMN: pData = &m_sAddressFromColumn; break;
+ case WID_SEND_AS_HTML: pData = &m_bSendAsHTML; break;
+ case WID_SEND_AS_ATTACHMENT: pData = &m_bSendAsAttachment; break;
+ case WID_MAIL_BODY: pData = &m_sMailBody; break;
+ case WID_ATTACHMENT_NAME: pData = &m_sAttachmentName; break;
+ case WID_ATTACHMENT_FILTER: pData = &m_sAttachmentFilter;break;
+ case WID_PRINT_OPTIONS: pData = &m_aPrintSettings; break;
+ case WID_SAVE_AS_SINGLE_FILE: pData = &m_bSaveAsSingleFile; break;
+ case WID_SAVE_FILTER: pData = &m_sSaveFilter; break;
+ case WID_SAVE_FILTER_OPTIONS: pData = &m_sSaveFilterOptions; break;
+ case WID_SAVE_FILTER_DATA: pData = &m_aSaveFilterData; break;
+ case WID_COPIES_TO: pData = &m_aCopiesTo; break;
+ case WID_BLIND_COPIES_TO: pData = &m_aBlindCopiesTo;break;
+ case WID_IN_SERVER_PASSWORD: pData = &m_sInServerPassword; break;
+ case WID_OUT_SERVER_PASSWORD: pData = &m_sOutServerPassword; break;
+ default :
+ OSL_FAIL("unknown WID");
+ }
+ Any aOld( pData, pCur->aType );
+
+ bool bChanged = false;
+ bool bOK = true;
+ if (aOld != rValue)
+ {
+ if (pData == &m_aSelection)
+ bOK = rValue >>= m_aSelection;
+ else if (pData == &m_xResultSet)
+ bOK = rValue >>= m_xResultSet;
+ else if (pData == &m_xConnection)
+ bOK = rValue >>= m_xConnection;
+ else if (pData == &m_xModel)
+ bOK = rValue >>= m_xModel;
+ else if (pData == &m_aDataSourceName)
+ bOK = rValue >>= m_aDataSourceName;
+ else if (pData == &m_aDataCommand)
+ bOK = rValue >>= m_aDataCommand;
+ else if (pData == &m_aFilter)
+ bOK = rValue >>= m_aFilter;
+ else if (pData == &m_aDocumentURL)
+ {
+ OUString aText;
+ bOK = rValue >>= aText;
+ if (!aText.isEmpty()
+ && !LoadFromURL_impl( m_xModel, m_xDocSh, aText, true ))
+ throw RuntimeException("Failed to create document from URL: " + aText, static_cast < cppu::OWeakObject * > ( this ) );
+ m_aDocumentURL = aText;
+ }
+ else if (pData == &m_aOutputURL)
+ {
+ OUString aText;
+ bOK = rValue >>= aText;
+ if (!aText.isEmpty())
+ {
+ if (!UCB_IsDirectory(aText))
+ throw IllegalArgumentException("URL does not point to a directory: " + aText, static_cast < cppu::OWeakObject * > ( this ), 0 );
+ if (UCB_IsReadOnlyFileName(aText))
+ throw IllegalArgumentException("URL is read-only: " + aText, static_cast < cppu::OWeakObject * > ( this ), 0 );
+ }
+ m_aOutputURL = aText;
+ }
+ else if (pData == &m_nDataCommandType)
+ bOK = rValue >>= m_nDataCommandType;
+ else if (pData == &m_nOutputType)
+ bOK = rValue >>= m_nOutputType;
+ else if (pData == &m_bEscapeProcessing)
+ bOK = rValue >>= m_bEscapeProcessing;
+ else if (pData == &m_bSinglePrintJobs)
+ bOK = rValue >>= m_bSinglePrintJobs;
+ else if (pData == &m_bFileNameFromColumn)
+ bOK = rValue >>= m_bFileNameFromColumn;
+ else if (pData == &m_aFileNamePrefix)
+ bOK = rValue >>= m_aFileNamePrefix;
+ else if (pData == &m_sSubject)
+ bOK = rValue >>= m_sSubject;
+ else if (pData == &m_sAddressFromColumn)
+ bOK = rValue >>= m_sAddressFromColumn;
+ else if (pData == &m_bSendAsHTML)
+ bOK = rValue >>= m_bSendAsHTML;
+ else if (pData == &m_bSendAsAttachment)
+ bOK = rValue >>= m_bSendAsAttachment;
+ else if (pData == &m_sMailBody)
+ bOK = rValue >>= m_sMailBody;
+ else if (pData == &m_sAttachmentName)
+ bOK = rValue >>= m_sAttachmentName;
+ else if (pData == &m_sAttachmentFilter)
+ bOK = rValue >>= m_sAttachmentFilter;
+ else if (pData == &m_aPrintSettings)
+ bOK = rValue >>= m_aPrintSettings;
+ else if (pData == &m_bSaveAsSingleFile)
+ bOK = rValue >>= m_bSaveAsSingleFile;
+ else if (pData == &m_sSaveFilter)
+ bOK = rValue >>= m_sSaveFilter;
+ else if (pData == &m_sSaveFilterOptions)
+ bOK = rValue >>= m_sSaveFilterOptions;
+ else if (pData == &m_aSaveFilterData)
+ bOK = rValue >>= m_aSaveFilterData;
+ else if (pData == &m_aCopiesTo)
+ bOK = rValue >>= m_aCopiesTo;
+ else if (pData == &m_aBlindCopiesTo)
+ bOK = rValue >>= m_aBlindCopiesTo;
+ else if(pData == &m_sInServerPassword)
+ bOK = rValue >>= m_sInServerPassword;
+ else if(pData == &m_sOutServerPassword)
+ bOK = rValue >>= m_sOutServerPassword;
+ else {
+ OSL_FAIL("invalid pointer" );
+ }
+ OSL_ENSURE( bOK, "set value failed" );
+ bChanged = true;
+ }
+ if (!bOK)
+ throw IllegalArgumentException("Property type mismatch or property not set: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ), 0 );
+
+ if (bChanged)
+ {
+ PropertyChangeEvent aChgEvt( static_cast<XPropertySet *>(this), rPropertyName,
+ false, pCur->nWID, aOld, rValue );
+ launchEvent( aChgEvt );
+ }
+ }
+}
+
+uno::Any SAL_CALL SwXMailMerge::getPropertyValue(
+ const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+
+ Any aRet;
+
+ const SfxItemPropertyMapEntry* pCur = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if (!pCur)
+ throw UnknownPropertyException(rPropertyName);
+
+ switch (pCur->nWID)
+ {
+ case WID_SELECTION : aRet <<= m_aSelection; break;
+ case WID_RESULT_SET : aRet <<= m_xResultSet; break;
+ case WID_CONNECTION : aRet <<= m_xConnection; break;
+ case WID_MODEL : aRet <<= m_xModel; break;
+ case WID_DATA_SOURCE_NAME : aRet <<= m_aDataSourceName; break;
+ case WID_DATA_COMMAND : aRet <<= m_aDataCommand; break;
+ case WID_FILTER : aRet <<= m_aFilter; break;
+ case WID_DOCUMENT_URL : aRet <<= m_aDocumentURL; break;
+ case WID_OUTPUT_URL : aRet <<= m_aOutputURL; break;
+ case WID_DATA_COMMAND_TYPE : aRet <<= m_nDataCommandType; break;
+ case WID_OUTPUT_TYPE : aRet <<= m_nOutputType; break;
+ case WID_ESCAPE_PROCESSING : aRet <<= m_bEscapeProcessing; break;
+ case WID_SINGLE_PRINT_JOBS : aRet <<= m_bSinglePrintJobs; break;
+ case WID_FILE_NAME_FROM_COLUMN : aRet <<= m_bFileNameFromColumn; break;
+ case WID_FILE_NAME_PREFIX : aRet <<= m_aFileNamePrefix; break;
+ case WID_MAIL_SUBJECT: aRet <<= m_sSubject; break;
+ case WID_ADDRESS_FROM_COLUMN: aRet <<= m_sAddressFromColumn; break;
+ case WID_SEND_AS_HTML: aRet <<= m_bSendAsHTML; break;
+ case WID_SEND_AS_ATTACHMENT: aRet <<= m_bSendAsAttachment; break;
+ case WID_MAIL_BODY: aRet <<= m_sMailBody; break;
+ case WID_ATTACHMENT_NAME: aRet <<= m_sAttachmentName; break;
+ case WID_ATTACHMENT_FILTER: aRet <<= m_sAttachmentFilter;break;
+ case WID_PRINT_OPTIONS: aRet <<= m_aPrintSettings; break;
+ case WID_SAVE_AS_SINGLE_FILE: aRet <<= m_bSaveAsSingleFile; break;
+ case WID_SAVE_FILTER: aRet <<= m_sSaveFilter; break;
+ case WID_SAVE_FILTER_OPTIONS: aRet <<= m_sSaveFilterOptions; break;
+ case WID_SAVE_FILTER_DATA: aRet <<= m_aSaveFilterData; break;
+ case WID_COPIES_TO: aRet <<= m_aCopiesTo; break;
+ case WID_BLIND_COPIES_TO: aRet <<= m_aBlindCopiesTo;break;
+ case WID_IN_SERVER_PASSWORD: aRet <<= m_sInServerPassword; break;
+ case WID_OUT_SERVER_PASSWORD: aRet <<= m_sOutServerPassword; break;
+ default :
+ OSL_FAIL("unknown WID");
+ }
+
+ return aRet;
+}
+
+void SAL_CALL SwXMailMerge::addPropertyChangeListener(
+ const OUString& rPropertyName,
+ const uno::Reference< beans::XPropertyChangeListener >& rListener )
+{
+ SolarMutexGuard aGuard;
+ if (!m_bDisposing && rListener.is())
+ {
+ const SfxItemPropertyMapEntry* pCur = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if (!pCur)
+ throw UnknownPropertyException(rPropertyName);
+ m_aPropListeners.addInterface( pCur->nWID, rListener );
+ }
+}
+
+void SAL_CALL SwXMailMerge::removePropertyChangeListener(
+ const OUString& rPropertyName,
+ const uno::Reference< beans::XPropertyChangeListener >& rListener )
+{
+ SolarMutexGuard aGuard;
+ if (!m_bDisposing && rListener.is())
+ {
+ const SfxItemPropertyMapEntry* pCur = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if (!pCur)
+ throw UnknownPropertyException(rPropertyName);
+ m_aPropListeners.removeInterface( pCur->nWID, rListener );
+ }
+}
+
+void SAL_CALL SwXMailMerge::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*rListener*/ )
+{
+ // no vetoable property, thus no support for vetoable change listeners
+ OSL_FAIL("not implemented");
+}
+
+void SAL_CALL SwXMailMerge::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*rListener*/ )
+{
+ // no vetoable property, thus no support for vetoable change listeners
+ OSL_FAIL("not implemented");
+}
+
+void SAL_CALL SwXMailMerge::dispose()
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_bDisposing)
+ {
+ m_bDisposing = true;
+
+ EventObject aEvtObj( static_cast<XPropertySet *>(this) );
+ m_aEvtListeners.disposeAndClear( aEvtObj );
+ m_aMergeListeners.disposeAndClear( aEvtObj );
+ m_aPropListeners.disposeAndClear( aEvtObj );
+ }
+}
+
+void SAL_CALL SwXMailMerge::addEventListener(
+ const Reference< XEventListener >& rxListener )
+{
+ SolarMutexGuard aGuard;
+ if (!m_bDisposing && rxListener.is())
+ m_aEvtListeners.addInterface( rxListener );
+}
+
+void SAL_CALL SwXMailMerge::removeEventListener(
+ const Reference< XEventListener >& rxListener )
+{
+ SolarMutexGuard aGuard;
+ if (!m_bDisposing && rxListener.is())
+ m_aEvtListeners.removeInterface( rxListener );
+}
+
+void SAL_CALL SwXMailMerge::addMailMergeEventListener(
+ const uno::Reference< XMailMergeListener >& rxListener )
+{
+ SolarMutexGuard aGuard;
+ if (!m_bDisposing && rxListener.is())
+ m_aMergeListeners.addInterface( rxListener );
+}
+
+void SAL_CALL SwXMailMerge::removeMailMergeEventListener(
+ const uno::Reference< XMailMergeListener >& rxListener )
+{
+ SolarMutexGuard aGuard;
+ if (!m_bDisposing && rxListener.is())
+ m_aMergeListeners.removeInterface( rxListener );
+}
+
+OUString SAL_CALL SwXMailMerge::getImplementationName()
+{
+ return "SwXMailMerge";
+}
+
+sal_Bool SAL_CALL SwXMailMerge::supportsService( const OUString& rServiceName )
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL SwXMailMerge::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.MailMerge", "com.sun.star.sdb.DataAccessDescriptor" };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/uno/unomod.cxx b/sw/source/uibase/uno/unomod.cxx
new file mode 100644
index 000000000..1506d197b
--- /dev/null
+++ b/sw/source/uibase/uno/unomod.cxx
@@ -0,0 +1,976 @@
+/* -*- 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 <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/view/DocumentZoomType.hpp>
+#include <comphelper/ChainablePropertySetInfo.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <o3tl/any.hxx>
+#include <osl/diagnose.h>
+#include <svl/itemprop.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/UnitConversion.hxx>
+#include <vcl/svapp.hxx>
+
+#include <unomod.hxx>
+#include <usrpref.hxx>
+#include <prtopt.hxx>
+#include <swmodule.hxx>
+#include <view.hxx>
+#include <docsh.hxx>
+#include <wrtsh.hxx>
+#include <viewopt.hxx>
+#include <doc.hxx>
+#include <IDocumentDeviceAccess.hxx>
+#include <edtwin.hxx>
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::comphelper;
+
+namespace {
+
+enum SwViewSettingsPropertyHandles
+{
+ HANDLE_VIEWSET_ANNOTATIONS,
+ HANDLE_VIEWSET_BREAKS,
+ HANDLE_VIEWSET_DRAWINGS,
+ HANDLE_VIEWSET_FIELD_COMMANDS,
+ HANDLE_VIEWSET_FOOTNOTE_BACKGROUND,
+ HANDLE_VIEWSET_GRAPHICS,
+ HANDLE_VIEWSET_HIDDEN_CHARACTERS,
+ HANDLE_VIEWSET_HIDDEN_PARAGRAPHS,
+ HANDLE_VIEWSET_HIDDEN_TEXT,
+ HANDLE_VIEWSET_HRULER,
+ HANDLE_VIEWSET_HSCROLL,
+ HANDLE_VIEWSET_INDEX_MARK_BACKGROUND,
+ HANDLE_VIEWSET_NONPRINTING_CHARACTERS,
+ HANDLE_VIEWSET_ONLINE_LAYOUT,
+ HANDLE_VIEWSET_PARA_BREAKS,
+ HANDLE_VIEWSET_PROTECTED_SPACES,
+ HANDLE_VIEWSET_SOFT_HYPHENS,
+ HANDLE_VIEWSET_SPACES,
+ HANDLE_VIEWSET_TABLE_BOUNDARIES,
+ HANDLE_VIEWSET_TABLES,
+ HANDLE_VIEWSET_TABSTOPS,
+ HANDLE_VIEWSET_TEXT_BOUNDARIES,
+ HANDLE_VIEWSET_TEXT_FIELD_BACKGROUND,
+ HANDLE_VIEWSET_VRULER,
+ HANDLE_VIEWSET_VSCROLL,
+ HANDLE_VIEWSET_SMOOTH_SCROLLING,
+ HANDLE_VIEWSET_ZOOM_TYPE,
+ HANDLE_VIEWSET_ZOOM,
+ HANDLE_VIEWSET_SHOW_CONTENT_TIPS,
+ HANDLE_VIEWSET_HELP_URL,
+ HANDLE_VIEWSET_VRULER_RIGHT,
+ HANDLE_VIEWSET_SHOW_RULER,
+ HANDLE_VIEWSET_IS_RASTER_VISIBLE,
+ HANDLE_VIEWSET_IS_SNAP_TO_RASTER,
+ HANDLE_VIEWSET_RASTER_RESOLUTION_X,
+ HANDLE_VIEWSET_RASTER_RESOLUTION_Y,
+ HANDLE_VIEWSET_RASTER_SUBDIVISION_X,
+ HANDLE_VIEWSET_RASTER_SUBDIVISION_Y,
+ HANDLE_VIEWSET_HORI_RULER_METRIC,
+ HANDLE_VIEWSET_VERT_RULER_METRIC,
+ HANDLE_VIEWSET_SCROLLBAR_TIPS,
+ HANDLE_VIEWSET_INLINECHANGES_TIPS,
+ HANDLE_VIEWSET_HIDE_WHITESPACE,
+ HANDLE_VIEWSET_USE_HEADERFOOTERMENU,
+ HANDLE_VIEWSET_BOOKMARKS,
+ HANDLE_VIEWSET_SHOW_OUTLINECONTENTVISIBILITYBUTTON,
+ HANDLE_VIEWSET_TREAT_SUB_OUTLINE_LEVELS_AS_CONTENT,
+ HANDLE_VIEWSET_CHANGES_IN_MARGIN
+};
+
+enum SwPrintSettingsPropertyHandles
+{
+ HANDLE_PRINTSET_ANNOTATION_MODE,
+ HANDLE_PRINTSET_BLACK_FONTS,
+ HANDLE_PRINTSET_CONTROLS,
+ HANDLE_PRINTSET_DRAWINGS,
+ HANDLE_PRINTSET_GRAPHICS,
+ HANDLE_PRINTSET_LEFT_PAGES,
+ HANDLE_PRINTSET_PAGE_BACKGROUND,
+ HANDLE_PRINTSET_PROSPECT,
+ HANDLE_PRINTSET_REVERSED,
+ HANDLE_PRINTSET_RIGHT_PAGES,
+ HANDLE_PRINTSET_FAX_NAME,
+ HANDLE_PRINTSET_PAPER_FROM_SETUP,
+ HANDLE_PRINTSET_TABLES,
+ HANDLE_PRINTSET_SINGLE_JOBS,
+ HANDLE_PRINTSET_EMPTY_PAGES,
+ HANDLE_PRINTSET_PROSPECT_RTL,
+ HANDLE_PRINTSET_PLACEHOLDER,
+ HANDLE_PRINTSET_HIDDEN_TEXT
+};
+
+}
+
+static rtl::Reference<ChainablePropertySetInfo> lcl_createViewSettingsInfo()
+{
+ static PropertyInfo const aViewSettingsMap_Impl[] =
+ {
+ { OUString( "HelpURL" ), HANDLE_VIEWSET_HELP_URL , cppu::UnoType<OUString>::get(), PROPERTY_NONE},
+ { OUString( "HorizontalRulerMetric"),HANDLE_VIEWSET_HORI_RULER_METRIC , cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE},
+ { OUString( "IsRasterVisible"), HANDLE_VIEWSET_IS_RASTER_VISIBLE, cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "IsSnapToRaster"), HANDLE_VIEWSET_IS_SNAP_TO_RASTER, cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "IsVertRulerRightAligned"),HANDLE_VIEWSET_VRULER_RIGHT , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowContentTips" ), HANDLE_VIEWSET_SHOW_CONTENT_TIPS , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowInlineTooltips" ), HANDLE_VIEWSET_INLINECHANGES_TIPS , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "UseHeaderFooterMenu" ), HANDLE_VIEWSET_USE_HEADERFOOTERMENU , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowOutlineContentVisibilityButton" ), HANDLE_VIEWSET_SHOW_OUTLINECONTENTVISIBILITYBUTTON , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "TreatSubOutlineLevelsAsContent" ), HANDLE_VIEWSET_TREAT_SUB_OUTLINE_LEVELS_AS_CONTENT , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowChangesInMargin" ), HANDLE_VIEWSET_CHANGES_IN_MARGIN, cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "RasterResolutionX"), HANDLE_VIEWSET_RASTER_RESOLUTION_X, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE},
+ { OUString( "RasterResolutionY"), HANDLE_VIEWSET_RASTER_RESOLUTION_Y, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE},
+ { OUString( "RasterSubdivisionX"), HANDLE_VIEWSET_RASTER_SUBDIVISION_X, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE},
+ { OUString( "RasterSubdivisionY"), HANDLE_VIEWSET_RASTER_SUBDIVISION_Y, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE},
+ { OUString( "ShowAnnotations" ), HANDLE_VIEWSET_ANNOTATIONS , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowBookmarks" ), HANDLE_VIEWSET_BOOKMARKS, cppu::UnoType<bool>::get(), PROPERTY_NONE },
+ { OUString( "ShowBreaks"), HANDLE_VIEWSET_BREAKS , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowDrawings"), HANDLE_VIEWSET_DRAWINGS , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowFieldCommands"), HANDLE_VIEWSET_FIELD_COMMANDS , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowFootnoteBackground"),HANDLE_VIEWSET_FOOTNOTE_BACKGROUND , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowGraphics"), HANDLE_VIEWSET_GRAPHICS , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowHiddenCharacters"), HANDLE_VIEWSET_HIDDEN_CHARACTERS , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "HideWhitespace"), HANDLE_VIEWSET_HIDE_WHITESPACE , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowHiddenParagraphs"), HANDLE_VIEWSET_HIDDEN_PARAGRAPHS , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowHiddenText"), HANDLE_VIEWSET_HIDDEN_TEXT , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowHoriRuler"), HANDLE_VIEWSET_HRULER , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowHoriScrollBar"), HANDLE_VIEWSET_HSCROLL , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowIndexMarkBackground"),HANDLE_VIEWSET_INDEX_MARK_BACKGROUND, cppu::UnoType<bool>::get(),PROPERTY_NONE},
+ { OUString( "ShowNonprintingCharacters"),HANDLE_VIEWSET_NONPRINTING_CHARACTERS, cppu::UnoType<bool>::get(),PROPERTY_NONE},
+ { OUString( "ShowOnlineLayout"), HANDLE_VIEWSET_ONLINE_LAYOUT , cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID},
+ { OUString( "ShowParaBreaks"), HANDLE_VIEWSET_PARA_BREAKS , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowProtectedSpaces"), HANDLE_VIEWSET_PROTECTED_SPACES , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowRulers"), HANDLE_VIEWSET_SHOW_RULER , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowScrollBarTips"), HANDLE_VIEWSET_SCROLLBAR_TIPS , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowSoftHyphens"), HANDLE_VIEWSET_SOFT_HYPHENS , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowSpaces"), HANDLE_VIEWSET_SPACES , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowTableBoundaries"), HANDLE_VIEWSET_TABLE_BOUNDARIES , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowTables"), HANDLE_VIEWSET_TABLES , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowTabstops"), HANDLE_VIEWSET_TABSTOPS , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowTextBoundaries"), HANDLE_VIEWSET_TEXT_BOUNDARIES , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowTextFieldBackground"),HANDLE_VIEWSET_TEXT_FIELD_BACKGROUND, cppu::UnoType<bool>::get(),PROPERTY_NONE},
+ { OUString( "ShowVertRuler"), HANDLE_VIEWSET_VRULER , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "ShowVertScrollBar"), HANDLE_VIEWSET_VSCROLL , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "SmoothScrolling"), HANDLE_VIEWSET_SMOOTH_SCROLLING , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "VerticalRulerMetric"), HANDLE_VIEWSET_VERT_RULER_METRIC , cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE},
+ { OUString( "ZoomType"), HANDLE_VIEWSET_ZOOM_TYPE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE},
+ { OUString( "ZoomValue"), HANDLE_VIEWSET_ZOOM , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE},
+ { OUString(), 0, css::uno::Type(), 0 }
+ };
+ return new ChainablePropertySetInfo ( aViewSettingsMap_Impl );
+}
+
+static rtl::Reference<ChainablePropertySetInfo> lcl_createPrintSettingsInfo()
+{
+ static PropertyInfo const aPrintSettingsMap_Impl[] =
+ {
+ { OUString( "PrintAnnotationMode" ), HANDLE_PRINTSET_ANNOTATION_MODE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE},
+ { OUString( "PrintBlackFonts" ), HANDLE_PRINTSET_BLACK_FONTS , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "PrintControls" ), HANDLE_PRINTSET_CONTROLS , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "PrintDrawings" ), HANDLE_PRINTSET_DRAWINGS , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "PrintGraphics" ), HANDLE_PRINTSET_GRAPHICS , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "PrintHiddenText"), HANDLE_PRINTSET_HIDDEN_TEXT , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "PrintLeftPages" ), HANDLE_PRINTSET_LEFT_PAGES , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "PrintPageBackground" ), HANDLE_PRINTSET_PAGE_BACKGROUND , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "PrintProspect" ), HANDLE_PRINTSET_PROSPECT , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "PrintProspectRTL" ), HANDLE_PRINTSET_PROSPECT_RTL , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "PrintReversed" ), HANDLE_PRINTSET_REVERSED , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "PrintRightPages" ), HANDLE_PRINTSET_RIGHT_PAGES , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "PrintFaxName" ), HANDLE_PRINTSET_FAX_NAME , cppu::UnoType<OUString>::get(), PROPERTY_NONE},
+ { OUString( "PrintPaperFromSetup" ), HANDLE_PRINTSET_PAPER_FROM_SETUP , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "PrintTables" ), HANDLE_PRINTSET_TABLES , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "PrintTextPlaceholder"), HANDLE_PRINTSET_PLACEHOLDER , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "PrintSingleJobs" ), HANDLE_PRINTSET_SINGLE_JOBS , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString( "PrintEmptyPages" ), HANDLE_PRINTSET_EMPTY_PAGES , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+ { OUString(), 0, css::uno::Type(), 0}
+ };
+ return new ChainablePropertySetInfo ( aPrintSettingsMap_Impl );
+}
+
+SwXModule::SwXModule()
+{
+}
+
+SwXModule::~SwXModule()
+{
+}
+
+Reference< XPropertySet > SwXModule::getViewSettings()
+{
+ SolarMutexGuard aGuard;
+ if(!mxViewSettings.is())
+ {
+ OSL_FAIL("Web or Text?");
+ mxViewSettings = new SwXViewSettings( nullptr );
+ }
+ return mxViewSettings;
+}
+
+Reference< XPropertySet > SwXModule::getPrintSettings()
+{
+ SolarMutexGuard aGuard;
+ if(!mxPrintSettings.is())
+ {
+ OSL_FAIL("Web or Text?");
+ mxPrintSettings = new SwXPrintSettings( SwXPrintSettingsType::Module );
+ }
+ return mxPrintSettings;
+}
+
+OUString SwXModule::getImplementationName()
+{
+ return "SwXModule";
+}
+
+sal_Bool SwXModule::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXModule::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.GlobalSettings" };
+}
+
+SwXPrintSettings::SwXPrintSettings(SwXPrintSettingsType eType, SwDoc* pDoc)
+: ChainablePropertySet ( lcl_createPrintSettingsInfo().get(), &Application::GetSolarMutex() )
+, meType(eType)
+, mpPrtOpt ( nullptr )
+, mpDoc ( pDoc )
+{
+}
+
+SwXPrintSettings::~SwXPrintSettings()
+ noexcept
+{
+}
+
+void SwXPrintSettings::_preSetValues ()
+{
+ switch (meType)
+ {
+ case SwXPrintSettingsType::Module:
+ mpPrtOpt = SW_MOD()->GetPrtOptions( false );
+ break;
+ case SwXPrintSettingsType::Document:
+ {
+ if (!mpDoc)
+ throw IllegalArgumentException ();
+ mpPrtOpt = const_cast< SwPrintData * >(&mpDoc->getIDocumentDeviceAccess().getPrintData());
+ }
+ break;
+ }
+}
+
+namespace
+{
+ bool tryBoolAccess(const uno::Any &rValue)
+ {
+ const auto xPrSet = o3tl::tryAccess<bool>(rValue);
+ if (!xPrSet)
+ throw lang::IllegalArgumentException();
+ return *xPrSet;
+ }
+}
+
+void SwXPrintSettings::_setSingleValue( const comphelper::PropertyInfo & rInfo, const uno::Any &rValue )
+{
+ switch( rInfo.mnHandle )
+ {
+ case HANDLE_PRINTSET_LEFT_PAGES:
+ {
+ mpPrtOpt->SetPrintLeftPage(tryBoolAccess(rValue));
+ }
+ break;
+ case HANDLE_PRINTSET_RIGHT_PAGES:
+ {
+ mpPrtOpt->SetPrintRightPage(tryBoolAccess(rValue));
+ }
+ break;
+ case HANDLE_PRINTSET_REVERSED:
+ {
+ mpPrtOpt->SetPrintReverse(tryBoolAccess(rValue));
+ }
+ break;
+ case HANDLE_PRINTSET_PROSPECT:
+ {
+ mpPrtOpt->SetPrintProspect(tryBoolAccess(rValue));
+ }
+ break;
+ case HANDLE_PRINTSET_GRAPHICS:
+ {
+ mpPrtOpt->SetPrintGraphic(tryBoolAccess(rValue));
+ }
+ break;
+ case HANDLE_PRINTSET_TABLES:
+ {
+ mpPrtOpt->SetPrintTable(tryBoolAccess(rValue));
+ }
+ break;
+ case HANDLE_PRINTSET_DRAWINGS:
+ {
+ mpPrtOpt->SetPrintDraw(tryBoolAccess(rValue));
+ }
+ break;
+ case HANDLE_PRINTSET_CONTROLS:
+ {
+ mpPrtOpt->SetPrintControl(tryBoolAccess(rValue));
+ }
+ break;
+ case HANDLE_PRINTSET_PAGE_BACKGROUND:
+ {
+ mpPrtOpt->SetPrintPageBackground(tryBoolAccess(rValue));
+ }
+ break;
+ case HANDLE_PRINTSET_BLACK_FONTS:
+ {
+ mpPrtOpt->SetPrintBlackFont(tryBoolAccess(rValue));
+ }
+ break;
+ case HANDLE_PRINTSET_SINGLE_JOBS:
+ {
+ mpPrtOpt->SetPrintSingleJobs(tryBoolAccess(rValue));
+ }
+ break;
+ case HANDLE_PRINTSET_PAPER_FROM_SETUP:
+ {
+ mpPrtOpt->SetPaperFromSetup(tryBoolAccess(rValue));
+ }
+ break;
+ case HANDLE_PRINTSET_ANNOTATION_MODE:
+ {
+ sal_Int16 nTmp = 0;
+ rValue >>= nTmp;
+ SwPostItMode nVal = static_cast<SwPostItMode>(nTmp);
+ if(nVal > SwPostItMode::EndPage)
+ throw lang::IllegalArgumentException();
+
+ mpPrtOpt->SetPrintPostIts(nVal);
+ }
+ break;
+ case HANDLE_PRINTSET_EMPTY_PAGES:
+ {
+ mpPrtOpt->SetPrintEmptyPages(tryBoolAccess(rValue));
+ }
+ break;
+ case HANDLE_PRINTSET_FAX_NAME:
+ {
+ OUString sString;
+ if ( !(rValue >>= sString))
+ throw lang::IllegalArgumentException();
+
+ mpPrtOpt->SetFaxName(sString);
+ }
+ break;
+ case HANDLE_PRINTSET_PROSPECT_RTL:
+ {
+ mpPrtOpt->SetPrintProspect_RTL(tryBoolAccess(rValue));
+ }
+ break;
+ case HANDLE_PRINTSET_PLACEHOLDER:
+ {
+ mpPrtOpt->SetPrintTextPlaceholder(tryBoolAccess(rValue));
+ }
+ break;
+ case HANDLE_PRINTSET_HIDDEN_TEXT:
+ {
+ mpPrtOpt->SetPrintHiddenText(tryBoolAccess(rValue));
+ }
+ break;
+ default:
+ throw UnknownPropertyException(OUString::number(rInfo.mnHandle));
+ }
+}
+
+void SwXPrintSettings::_postSetValues()
+{
+ mpPrtOpt = nullptr;
+}
+
+void SwXPrintSettings::_preGetValues()
+{
+ switch (meType)
+ {
+ case SwXPrintSettingsType::Module:
+ mpPrtOpt = SW_MOD()->GetPrtOptions( false );
+ break;
+ case SwXPrintSettingsType::Document:
+ {
+ if (!mpDoc)
+ throw IllegalArgumentException ();
+ mpPrtOpt = const_cast< SwPrintData * >(&mpDoc->getIDocumentDeviceAccess().getPrintData());
+ }
+ break;
+ }
+}
+
+void SwXPrintSettings::_getSingleValue( const comphelper::PropertyInfo & rInfo, uno::Any & rValue )
+{
+ switch( rInfo.mnHandle )
+ {
+ case HANDLE_PRINTSET_LEFT_PAGES:
+ rValue <<= mpPrtOpt->IsPrintLeftPage();
+ break;
+ case HANDLE_PRINTSET_RIGHT_PAGES:
+ rValue <<= mpPrtOpt->IsPrintRightPage();
+ break;
+ case HANDLE_PRINTSET_REVERSED:
+ rValue <<= mpPrtOpt->IsPrintReverse();
+ break;
+ case HANDLE_PRINTSET_PROSPECT:
+ rValue <<= mpPrtOpt->IsPrintProspect();
+ break;
+ case HANDLE_PRINTSET_GRAPHICS:
+ rValue <<= mpPrtOpt->IsPrintGraphic();
+ break;
+ case HANDLE_PRINTSET_TABLES:
+ rValue <<= mpPrtOpt->IsPrintTable();
+ break;
+ case HANDLE_PRINTSET_DRAWINGS:
+ rValue <<= mpPrtOpt->IsPrintDraw();
+ break;
+ case HANDLE_PRINTSET_CONTROLS:
+ rValue <<= mpPrtOpt->IsPrintControl();
+ break;
+ case HANDLE_PRINTSET_PAGE_BACKGROUND:
+ rValue <<= mpPrtOpt->IsPrintPageBackground();
+ break;
+ case HANDLE_PRINTSET_BLACK_FONTS:
+ rValue <<= mpPrtOpt->IsPrintBlackFont();
+ break;
+ case HANDLE_PRINTSET_SINGLE_JOBS:
+ rValue <<= mpPrtOpt->IsPrintSingleJobs();
+ break;
+ case HANDLE_PRINTSET_EMPTY_PAGES:
+ rValue <<= mpPrtOpt->IsPrintEmptyPages();
+ break;
+ case HANDLE_PRINTSET_PAPER_FROM_SETUP:
+ rValue <<= mpPrtOpt->IsPaperFromSetup();
+ break;
+ case HANDLE_PRINTSET_ANNOTATION_MODE:
+ {
+ rValue <<= static_cast < sal_Int16 > ( mpPrtOpt->GetPrintPostIts() );
+ }
+ break;
+ case HANDLE_PRINTSET_FAX_NAME :
+ {
+ rValue <<= mpPrtOpt->GetFaxName();
+ }
+ break;
+ case HANDLE_PRINTSET_PROSPECT_RTL:
+ {
+ rValue <<= mpPrtOpt->IsPrintProspectRTL();
+ }
+ break;
+ case HANDLE_PRINTSET_PLACEHOLDER:
+ {
+ rValue <<= mpPrtOpt->IsPrintTextPlaceholder();
+ }
+ break;
+ case HANDLE_PRINTSET_HIDDEN_TEXT:
+ {
+ rValue <<= mpPrtOpt->IsPrintHiddenText();
+ }
+ break;
+ default:
+ throw UnknownPropertyException(OUString::number(rInfo.mnHandle));
+ }
+}
+
+void SwXPrintSettings::_postGetValues ()
+{
+ mpPrtOpt = nullptr;
+}
+
+OUString SwXPrintSettings::getImplementationName()
+{
+ return "SwXPrintSettings";
+}
+
+sal_Bool SwXPrintSettings::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXPrintSettings::getSupportedServiceNames()
+{
+ Sequence<OUString> aRet { "com.sun.star.text.PrintSettings" };
+ return aRet;
+}
+
+SwXViewSettings::SwXViewSettings(SwView* pVw)
+ : ChainablePropertySet( lcl_createViewSettingsInfo().get(), &Application::GetSolarMutex() )
+ , m_pView(pVw)
+ , mpConstViewOption(nullptr)
+ , m_bObjectValid(true)
+ , mbApplyZoom(false)
+ , m_eHRulerUnit(FieldUnit::CM)
+ , mbApplyHRulerMetric(false)
+ , m_eVRulerUnit(FieldUnit::CM)
+ , mbApplyVRulerMetric(false)
+{
+ // This property only exists if we have a view (ie, not at the module )
+ if ( !m_pView )
+ mxInfo->remove ( "HelpURL" );
+
+}
+
+SwXViewSettings::~SwXViewSettings()
+ noexcept
+{
+
+}
+
+void SwXViewSettings::_preSetValues ()
+{
+ const SwViewOption* pVOpt = nullptr;
+ if(m_pView)
+ {
+ if(!IsValid())
+ return;
+ pVOpt = m_pView->GetWrtShell().GetViewOptions();
+ }
+ else
+ pVOpt = SW_MOD()->GetViewOption(false);
+
+ mpViewOption.reset( new SwViewOption (*pVOpt) );
+ mbApplyZoom = false;
+ if(m_pView)
+ mpViewOption->SetStarOneSetting(true);
+}
+
+void SwXViewSettings::_setSingleValue( const comphelper::PropertyInfo & rInfo, const uno::Any &rValue )
+{
+ // the API flag should not be set to the application's view settings
+ switch( rInfo.mnHandle )
+ {
+ case HANDLE_VIEWSET_SHOW_RULER : mpViewOption->SetViewAnyRuler(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_HRULER : mpViewOption->SetViewHRuler(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_VRULER : mpViewOption->SetViewVRuler(*o3tl::doAccess<bool>(rValue));break;
+ case HANDLE_VIEWSET_VRULER_RIGHT : mpViewOption->SetVRulerRight(*o3tl::doAccess<bool>(rValue));break;
+ case HANDLE_VIEWSET_HSCROLL : mpViewOption->SetViewHScrollBar(*o3tl::doAccess<bool>(rValue));break;
+ case HANDLE_VIEWSET_VSCROLL : mpViewOption->SetViewVScrollBar(*o3tl::doAccess<bool>(rValue));break;
+ case HANDLE_VIEWSET_GRAPHICS : mpViewOption->SetGraphic(*o3tl::doAccess<bool>(rValue));break;
+ case HANDLE_VIEWSET_TABLES : mpViewOption->SetTable(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_DRAWINGS : mpViewOption->SetDraw(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_FIELD_COMMANDS : mpViewOption->SetFieldName(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_ANNOTATIONS : mpViewOption->SetPostIts(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_INDEX_MARK_BACKGROUND : SwViewOption::SetAppearanceFlag(ViewOptFlags::FieldShadings, *o3tl::doAccess<bool>(rValue), true); break;
+ case HANDLE_VIEWSET_NONPRINTING_CHARACTERS: mpViewOption->SetViewMetaChars( *o3tl::doAccess<bool>(rValue) ); break;
+ case HANDLE_VIEWSET_FOOTNOTE_BACKGROUND : SwViewOption::SetAppearanceFlag(ViewOptFlags::FieldShadings, *o3tl::doAccess<bool>(rValue), true); break;
+ case HANDLE_VIEWSET_TEXT_FIELD_BACKGROUND : SwViewOption::SetAppearanceFlag(ViewOptFlags::FieldShadings, *o3tl::doAccess<bool>(rValue), true); break;
+ case HANDLE_VIEWSET_PARA_BREAKS : mpViewOption->SetParagraph(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_SOFT_HYPHENS : mpViewOption->SetSoftHyph(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_SPACES : mpViewOption->SetBlank(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_PROTECTED_SPACES : mpViewOption->SetHardBlank(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_TABSTOPS : mpViewOption->SetTab(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_BREAKS : mpViewOption->SetLineBreak(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_BOOKMARKS : mpViewOption->SetShowBookmarks(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_HIDDEN_TEXT : mpViewOption->SetShowHiddenField(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_HIDDEN_CHARACTERS : mpViewOption->SetShowHiddenChar(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_HIDDEN_PARAGRAPHS : mpViewOption->SetShowHiddenPara(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_TABLE_BOUNDARIES : SwViewOption::SetAppearanceFlag(ViewOptFlags::TableBoundaries, *o3tl::doAccess<bool>(rValue), true); break;
+ case HANDLE_VIEWSET_TEXT_BOUNDARIES : SwViewOption::SetDocBoundaries(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_SMOOTH_SCROLLING : mpViewOption->SetSmoothScroll(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_SHOW_CONTENT_TIPS : mpViewOption->SetShowContentTips(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_IS_RASTER_VISIBLE : mpViewOption->SetGridVisible(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_IS_SNAP_TO_RASTER : mpViewOption->SetSnap(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_SCROLLBAR_TIPS : mpViewOption->SetShowScrollBarTips(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_INLINECHANGES_TIPS : mpViewOption->SetShowInlineTooltips(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_USE_HEADERFOOTERMENU : mpViewOption->SetUseHeaderFooterMenu(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_SHOW_OUTLINECONTENTVISIBILITYBUTTON : mpViewOption->SetShowOutlineContentVisibilityButton(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_TREAT_SUB_OUTLINE_LEVELS_AS_CONTENT : mpViewOption->SetTreatSubOutlineLevelsAsContent(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_CHANGES_IN_MARGIN : mpViewOption->SetShowChangesInMargin(*o3tl::doAccess<bool>(rValue)); break;
+ case HANDLE_VIEWSET_RASTER_RESOLUTION_X :
+ {
+ sal_Int32 nTmp = 0;
+ if(!(rValue >>= nTmp) || nTmp < 10)
+ throw IllegalArgumentException();
+ Size aSize( mpViewOption->GetSnapSize() );
+ aSize.setWidth( o3tl::toTwips(nTmp, o3tl::Length::mm100) );
+ mpViewOption->SetSnapSize( aSize );
+ }
+ break;
+ case HANDLE_VIEWSET_RASTER_RESOLUTION_Y :
+ {
+ sal_Int32 nTmp = 0;
+ if(!(rValue >>= nTmp) || nTmp < 10)
+ throw IllegalArgumentException();
+ Size aSize( mpViewOption->GetSnapSize() );
+ aSize.setHeight( o3tl::toTwips(nTmp, o3tl::Length::mm100) );
+ mpViewOption->SetSnapSize( aSize );
+ }
+ break;
+ case HANDLE_VIEWSET_RASTER_SUBDIVISION_X :
+ {
+ sal_Int32 nTmp = 0;
+ if(!(rValue >>= nTmp) || (0 > nTmp || nTmp >= 100))
+ throw IllegalArgumentException();
+ mpViewOption->SetDivisionX( static_cast<short>(nTmp) );
+ }
+ break;
+ case HANDLE_VIEWSET_RASTER_SUBDIVISION_Y :
+ {
+ sal_Int32 nTmp = 0;
+ if(!(rValue >>= nTmp) || (0 > nTmp || nTmp >= 100))
+ throw IllegalArgumentException();
+ mpViewOption->SetDivisionY( static_cast<short>(nTmp) );
+ }
+ break;
+ case HANDLE_VIEWSET_ZOOM :
+ {
+ sal_Int16 nZoom = 0;
+ if(!(rValue >>= nZoom) || nZoom > MAXZOOM || nZoom < MINZOOM)
+ throw lang::IllegalArgumentException();
+ mpViewOption->SetZoom(o3tl::narrowing<sal_uInt16>(nZoom));
+ mbApplyZoom = true;
+ }
+ break;
+ case HANDLE_VIEWSET_ZOOM_TYPE:
+ {
+ sal_Int16 nZoom = 0;
+ if(!(rValue >>= nZoom))
+ throw IllegalArgumentException();
+ SvxZoomType eZoom;
+ switch (nZoom)
+ {
+ case view::DocumentZoomType::OPTIMAL:
+ eZoom = SvxZoomType::OPTIMAL;
+ break;
+ case view::DocumentZoomType::PAGE_WIDTH:
+ eZoom = SvxZoomType::PAGEWIDTH;
+ break;
+ case view::DocumentZoomType::ENTIRE_PAGE:
+ eZoom = SvxZoomType::WHOLEPAGE;
+ break;
+ case view::DocumentZoomType::BY_VALUE:
+ eZoom = SvxZoomType::PERCENT;
+ break;
+ case view::DocumentZoomType::PAGE_WIDTH_EXACT:
+ eZoom = SvxZoomType::PAGEWIDTH_NOBORDER;
+ break;
+ default:
+ throw IllegalArgumentException(
+ "SwXViewSettings: invalid zoom type", nullptr, 0);
+ }
+ mpViewOption->SetZoomType( eZoom );
+ mbApplyZoom = true;
+ }
+ break;
+ case HANDLE_VIEWSET_ONLINE_LAYOUT :
+ {
+ if ( m_pView )
+ {
+ bool bVal = *o3tl::doAccess<bool>(rValue);
+ SwViewOption aOpt(*m_pView->GetWrtShell().GetViewOptions());
+ if (!bVal != !aOpt.getBrowseMode())
+ {
+ aOpt.setBrowseMode( bVal );
+ m_pView->GetWrtShell().ApplyViewOptions( aOpt );
+
+ // must be set in mpViewOption as this will overwrite settings in _post!
+ if(mpViewOption)
+ mpViewOption->setBrowseMode(bVal);
+
+ m_pView->GetDocShell()->ToggleLayoutMode(m_pView);
+ }
+ }
+ }
+ break;
+ case HANDLE_VIEWSET_HIDE_WHITESPACE:
+ {
+ if ( m_pView )
+ {
+ bool bVal = *o3tl::doAccess<bool>(rValue);
+ SwViewOption aOpt(*m_pView->GetWrtShell().GetViewOptions());
+ if (!bVal != !aOpt.IsHideWhitespaceMode())
+ {
+ aOpt.SetHideWhitespaceMode( bVal );
+ m_pView->GetWrtShell().ApplyViewOptions( aOpt );
+
+ // must be set in mpViewOption as this will overwrite settings in _post!
+ if(mpViewOption)
+ mpViewOption->SetHideWhitespaceMode(bVal);
+ }
+ }
+ }
+ break;
+ case HANDLE_VIEWSET_HELP_URL:
+ {
+ if ( !m_pView )
+ throw UnknownPropertyException();
+
+ OUString sHelpURL;
+ if ( ! ( rValue >>= sHelpURL ) )
+ throw IllegalArgumentException();
+
+ INetURLObject aHID( sHelpURL );
+ if ( aHID.GetProtocol() != INetProtocol::Hid )
+ throw IllegalArgumentException ();
+
+ m_pView->GetEditWin().SetHelpId( OUStringToOString( aHID.GetURLPath(), RTL_TEXTENCODING_UTF8 ) );
+ }
+ break;
+ case HANDLE_VIEWSET_HORI_RULER_METRIC:
+ case HANDLE_VIEWSET_VERT_RULER_METRIC:
+ {
+ sal_uInt16 nUnit;
+ if( rValue >>= nUnit )
+ switch (static_cast<FieldUnit>(nUnit))
+ {
+ case FieldUnit::MM:
+ case FieldUnit::CM:
+ case FieldUnit::POINT:
+ case FieldUnit::PICA:
+ case FieldUnit::INCH:
+ if( rInfo.mnHandle == HANDLE_VIEWSET_HORI_RULER_METRIC )
+ {
+ m_eHRulerUnit = static_cast<FieldUnit>(nUnit);
+ mbApplyHRulerMetric = true;
+ }
+ else
+ {
+ m_eVRulerUnit = static_cast<FieldUnit>(nUnit);
+ mbApplyVRulerMetric = true;
+ }
+ break;
+ default:
+ throw IllegalArgumentException();
+ }
+ }
+ break;
+ default:
+ throw UnknownPropertyException(OUString::number(rInfo.mnHandle));
+ }
+}
+
+void SwXViewSettings::_postSetValues()
+{
+ if( m_pView )
+ {
+ if(mbApplyZoom )
+ m_pView->SetZoom( mpViewOption->GetZoomType(),
+ mpViewOption->GetZoom(), true );
+ if(mbApplyHRulerMetric)
+ m_pView->ChangeTabMetric(m_eHRulerUnit);
+ if(mbApplyVRulerMetric)
+ m_pView->ChangeVRulerMetric(m_eVRulerUnit);
+
+ }
+ else
+ {
+ if(mbApplyHRulerMetric)
+ SW_MOD()->ApplyRulerMetric( m_eHRulerUnit, true, false );
+ if(mbApplyVRulerMetric)
+ SW_MOD()->ApplyRulerMetric( m_eVRulerUnit, false, false );
+ }
+
+ SW_MOD()->ApplyUsrPref( *mpViewOption, m_pView, m_pView ? SvViewOpt::DestViewOnly
+ : SvViewOpt::DestText );
+
+ mpViewOption.reset();
+}
+
+void SwXViewSettings::_preGetValues ()
+{
+ if(m_pView)
+ {
+ if(!IsValid())
+ return;
+ mpConstViewOption = m_pView->GetWrtShell().GetViewOptions();
+ }
+ else
+ mpConstViewOption = SW_MOD()->GetViewOption(false);
+}
+
+void SwXViewSettings::_getSingleValue( const comphelper::PropertyInfo & rInfo, uno::Any & rValue )
+{
+ bool bBool = true;
+ bool bBoolVal = false;
+ switch( rInfo.mnHandle )
+ {
+ case HANDLE_VIEWSET_SHOW_RULER: bBoolVal = mpConstViewOption->IsViewAnyRuler(); break;
+ case HANDLE_VIEWSET_HRULER : bBoolVal = mpConstViewOption->IsViewHRuler(true); break;
+ case HANDLE_VIEWSET_VRULER : bBoolVal = mpConstViewOption->IsViewVRuler(true);break;
+ case HANDLE_VIEWSET_VRULER_RIGHT : bBoolVal = mpConstViewOption->IsVRulerRight();break;
+ case HANDLE_VIEWSET_HSCROLL: bBoolVal = mpConstViewOption->IsViewHScrollBar();break;
+ case HANDLE_VIEWSET_VSCROLL: bBoolVal = mpConstViewOption->IsViewVScrollBar();break;
+ case HANDLE_VIEWSET_GRAPHICS : bBoolVal = mpConstViewOption->IsGraphic();break;
+ case HANDLE_VIEWSET_TABLES : bBoolVal = mpConstViewOption->IsTable(); break;
+ case HANDLE_VIEWSET_DRAWINGS : bBoolVal = mpConstViewOption->IsDraw(); break;
+ case HANDLE_VIEWSET_FIELD_COMMANDS : bBoolVal = mpConstViewOption->IsFieldName(); break;
+ case HANDLE_VIEWSET_ANNOTATIONS : bBoolVal = mpConstViewOption->IsPostIts(); break;
+ case HANDLE_VIEWSET_INDEX_MARK_BACKGROUND : bBoolVal = SwViewOption::IsFieldShadings(); break;
+ case HANDLE_VIEWSET_NONPRINTING_CHARACTERS: bBoolVal = mpConstViewOption->IsViewMetaChars(); break;
+ case HANDLE_VIEWSET_FOOTNOTE_BACKGROUND : bBoolVal = SwViewOption::IsFieldShadings(); break;
+ case HANDLE_VIEWSET_TEXT_FIELD_BACKGROUND : bBoolVal = SwViewOption::IsFieldShadings(); break;
+ case HANDLE_VIEWSET_PARA_BREAKS : bBoolVal = mpConstViewOption->IsParagraph(true); break;
+ case HANDLE_VIEWSET_SOFT_HYPHENS : bBoolVal = mpConstViewOption->IsSoftHyph(); break;
+ case HANDLE_VIEWSET_SPACES : bBoolVal = mpConstViewOption->IsBlank(true); break;
+ case HANDLE_VIEWSET_PROTECTED_SPACES : bBoolVal = mpConstViewOption->IsHardBlank(); break;
+ case HANDLE_VIEWSET_TABSTOPS : bBoolVal = mpConstViewOption->IsTab(true); break;
+ case HANDLE_VIEWSET_BREAKS : bBoolVal = mpConstViewOption->IsLineBreak(true); break;
+ case HANDLE_VIEWSET_BOOKMARKS : bBoolVal = mpConstViewOption->IsShowBookmarks(true); break;
+ case HANDLE_VIEWSET_HIDDEN_TEXT : bBoolVal = mpConstViewOption->IsShowHiddenField(); break;
+ case HANDLE_VIEWSET_HIDDEN_CHARACTERS : bBoolVal = mpConstViewOption->IsShowHiddenChar(true); break;
+ case HANDLE_VIEWSET_HIDE_WHITESPACE : bBoolVal = mpConstViewOption->IsHideWhitespaceMode(); break;
+ case HANDLE_VIEWSET_HIDDEN_PARAGRAPHS : bBoolVal = mpConstViewOption->IsShowHiddenPara(); break;
+ case HANDLE_VIEWSET_TABLE_BOUNDARIES : bBoolVal = SwViewOption::IsTableBoundaries(); break;
+ case HANDLE_VIEWSET_TEXT_BOUNDARIES : bBoolVal = SwViewOption::IsDocBoundaries(); break;
+ case HANDLE_VIEWSET_SMOOTH_SCROLLING : bBoolVal = mpConstViewOption->IsSmoothScroll(); break;
+ case HANDLE_VIEWSET_SHOW_CONTENT_TIPS : bBoolVal = mpConstViewOption->IsShowContentTips(); break;
+ case HANDLE_VIEWSET_INLINECHANGES_TIPS : bBoolVal = mpConstViewOption->IsShowInlineTooltips(); break;
+ case HANDLE_VIEWSET_CHANGES_IN_MARGIN : bBoolVal = mpConstViewOption->IsShowChangesInMargin(); break;
+ case HANDLE_VIEWSET_IS_RASTER_VISIBLE : bBoolVal = mpConstViewOption->IsGridVisible(); break;
+ case HANDLE_VIEWSET_IS_SNAP_TO_RASTER : bBoolVal = mpConstViewOption->IsSnap(); break;
+ case HANDLE_VIEWSET_SCROLLBAR_TIPS : bBoolVal = mpConstViewOption->IsShowScrollBarTips(); break;
+ case HANDLE_VIEWSET_RASTER_RESOLUTION_X :
+ bBool = false;
+ rValue <<= static_cast<sal_Int32>(convertTwipToMm100(mpConstViewOption->GetSnapSize().Width()));
+ break;
+ case HANDLE_VIEWSET_RASTER_RESOLUTION_Y :
+ bBool = false;
+ rValue <<= static_cast<sal_Int32>(convertTwipToMm100(mpConstViewOption->GetSnapSize().Height()));
+ break;
+ case HANDLE_VIEWSET_RASTER_SUBDIVISION_X :
+ bBool = false;
+ rValue <<= static_cast<sal_Int32>(mpConstViewOption->GetDivisionX());
+ break;
+ case HANDLE_VIEWSET_RASTER_SUBDIVISION_Y :
+ bBool = false;
+ rValue <<= static_cast<sal_Int32>(mpConstViewOption->GetDivisionY());
+ break;
+ case HANDLE_VIEWSET_ZOOM :
+ bBool = false;
+ rValue <<= static_cast<sal_Int16>(mpConstViewOption->GetZoom());
+ break;
+ case HANDLE_VIEWSET_ZOOM_TYPE:
+ {
+ bBool = false;
+ sal_Int16 nRet(0);
+ switch (mpConstViewOption->GetZoomType())
+ {
+ case SvxZoomType::OPTIMAL:
+ nRet = view::DocumentZoomType::OPTIMAL;
+ break;
+ case SvxZoomType::PAGEWIDTH:
+ nRet = view::DocumentZoomType::PAGE_WIDTH;
+ break;
+ case SvxZoomType::WHOLEPAGE:
+ nRet = view::DocumentZoomType::ENTIRE_PAGE;
+ break;
+ case SvxZoomType::PERCENT:
+ nRet = view::DocumentZoomType::BY_VALUE;
+ break;
+ case SvxZoomType::PAGEWIDTH_NOBORDER:
+ nRet = view::DocumentZoomType::PAGE_WIDTH_EXACT;
+ break;
+ default:
+ OSL_FAIL("SwXViewSettings: invalid zoom type");
+ break;
+ }
+ rValue <<= nRet;
+ }
+ break;
+ case HANDLE_VIEWSET_ONLINE_LAYOUT:
+ if(m_pView)
+ bBoolVal = m_pView->GetWrtShell().GetViewOptions()->getBrowseMode();
+ break;
+ case HANDLE_VIEWSET_HELP_URL :
+ {
+ if ( !m_pView )
+ throw UnknownPropertyException();
+
+ bBool = false;
+ SwEditWin &rEditWin = m_pView->GetEditWin();
+ OUString sHelpURL = INET_HID_SCHEME + OUString::fromUtf8( rEditWin.GetHelpId() );
+ rValue <<= sHelpURL;
+ }
+ break;
+ case HANDLE_VIEWSET_HORI_RULER_METRIC:
+ {
+ if ( m_pView )
+ {
+ FieldUnit eUnit;
+ m_pView->GetHRulerMetric( eUnit );
+ rValue <<= static_cast<sal_Int32>(eUnit);
+ }
+ else
+ {
+ const SwMasterUsrPref* pUsrPref = SW_MOD()->GetUsrPref( false );
+ rValue <<= static_cast<sal_Int32>(pUsrPref->GetHScrollMetric());
+ }
+ bBool = false;
+ }
+ break;
+ case HANDLE_VIEWSET_VERT_RULER_METRIC:
+ {
+ if ( m_pView )
+ {
+ FieldUnit eUnit;
+ m_pView->GetVRulerMetric( eUnit );
+ rValue <<= static_cast<sal_Int32>(eUnit);
+ }
+ else
+ {
+ const SwMasterUsrPref* pUsrPref = SW_MOD()->GetUsrPref( false );
+ rValue <<= static_cast<sal_Int32>(pUsrPref->GetVScrollMetric());
+ }
+ bBool = false;
+ }
+ break;
+ default: OSL_FAIL("there is no such ID!");
+ }
+ if( bBool )
+ rValue <<= bBoolVal;
+}
+
+void SwXViewSettings::_postGetValues ()
+{
+ mpConstViewOption = nullptr;
+}
+
+OUString SwXViewSettings::getImplementationName()
+{
+ return "SwXViewSettings";
+}
+
+sal_Bool SwXViewSettings::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXViewSettings::getSupportedServiceNames()
+{
+ Sequence<OUString> aRet { "com.sun.star.text.ViewSettings" };
+ return aRet;
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+SwXModule_get_implementation(css::uno::XComponentContext*,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(new SwXModule());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/uno/unomodule.cxx b/sw/source/uibase/uno/unomodule.cxx
new file mode 100644
index 000000000..da821aece
--- /dev/null
+++ b/sw/source/uibase/uno/unomodule.cxx
@@ -0,0 +1,150 @@
+/* -*- 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 <com/sun/star/frame/DispatchResultState.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+
+#include <swmodule.hxx>
+#include <swdll.hxx>
+#include "unomodule.hxx"
+#include <cppuhelper/supportsservice.hxx>
+#include <comphelper/processfactory.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <sfx2/frame.hxx>
+#include <vcl/svapp.hxx>
+
+using namespace css;
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Writer_WriterModule_get_implementation(uno::XComponentContext* /*pCtx*/,
+ uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ SolarMutexGuard aGuard;
+ return cppu::acquire(new SwUnoModule);
+}
+
+ // XNotifyingDispatch
+void SAL_CALL SwUnoModule::dispatchWithNotification( const util::URL& aURL, const uno::Sequence< beans::PropertyValue >& aArgs, const uno::Reference< frame::XDispatchResultListener >& xListener )
+{
+ // there is no guarantee, that we are holded alive during this method!
+ // May the outside dispatch container will be updated by a CONTEXT_CHANGED
+ // asynchronous ...
+ uno::Reference< uno::XInterface > xThis(static_cast< frame::XNotifyingDispatch* >(this));
+
+ SolarMutexGuard aGuard;
+ SwGlobals::ensure();
+ const SfxSlot* pSlot = SW_MOD()->GetInterface()->GetSlot( aURL.Complete );
+
+ sal_Int16 aState = frame::DispatchResultState::DONTKNOW;
+ if ( !pSlot )
+ aState = frame::DispatchResultState::FAILURE;
+ else
+ {
+ SfxRequest aReq( pSlot, aArgs, SfxCallMode::SYNCHRON, SW_MOD()->GetPool() );
+ SfxAllItemSet aInternalSet( SfxGetpApp()->GetPool() );
+
+ css::uno::Reference<css::frame::XDesktop2> xDesktop = css::frame::Desktop::create(::comphelper::getProcessComponentContext());
+ css::uno::Reference<css::frame::XFrame> xCurrentFrame = xDesktop->getCurrentFrame();
+ if (xCurrentFrame.is()) // an empty set is no problem ... but an empty frame reference can be a problem !
+ aInternalSet.Put(SfxUnoFrameItem(SID_FILLFRAME, xCurrentFrame));
+
+ aReq.SetInternalArgs_Impl(aInternalSet);
+ const SfxPoolItem* pResult = SW_MOD()->ExecuteSlot( aReq );
+ if ( pResult )
+ aState = frame::DispatchResultState::SUCCESS;
+ else
+ aState = frame::DispatchResultState::FAILURE;
+ }
+
+ if ( xListener.is() )
+ {
+ xListener->dispatchFinished(
+ frame::DispatchResultEvent(
+ xThis, aState, uno::Any()));
+ }
+}
+
+ // XDispatch
+void SAL_CALL SwUnoModule::dispatch( const util::URL& aURL, const uno::Sequence< beans::PropertyValue >& aArgs )
+{
+ dispatchWithNotification(aURL, aArgs, uno::Reference< frame::XDispatchResultListener >());
+}
+
+void SAL_CALL SwUnoModule::addStatusListener(
+ const uno::Reference< frame::XStatusListener > & /*xControl*/,
+ const util::URL& /*aURL*/)
+{
+}
+
+void SAL_CALL SwUnoModule::removeStatusListener(
+ const uno::Reference< frame::XStatusListener > & /*xControl*/,
+ const util::URL& /*aURL*/)
+{
+}
+
+uno::Sequence< uno::Reference< frame::XDispatch > > SAL_CALL SwUnoModule::queryDispatches(
+ const uno::Sequence< frame::DispatchDescriptor >& seqDescripts )
+{
+ sal_Int32 nCount = seqDescripts.getLength();
+ uno::Sequence< uno::Reference< frame::XDispatch > > lDispatcher( nCount );
+
+ std::transform(seqDescripts.begin(), seqDescripts.end(), lDispatcher.getArray(),
+ [this](const frame::DispatchDescriptor& rDescr) -> uno::Reference< frame::XDispatch > {
+ return queryDispatch( rDescr.FeatureURL, rDescr.FrameName, rDescr.SearchFlags ); });
+
+ return lDispatcher;
+}
+
+// XDispatchProvider
+uno::Reference< frame::XDispatch > SAL_CALL SwUnoModule::queryDispatch(
+ const util::URL& aURL, const OUString& /*sTargetFrameName*/,
+ sal_Int32 /*eSearchFlags*/ )
+{
+ uno::Reference< frame::XDispatch > xReturn;
+
+ SolarMutexGuard aGuard;
+ SwGlobals::ensure();
+ const SfxSlot* pSlot = SW_MOD()->GetInterface()->GetSlot( aURL.Complete );
+ if ( pSlot )
+ xReturn = this;
+
+ return xReturn;
+}
+
+// XServiceInfo
+OUString SAL_CALL SwUnoModule::getImplementationName( )
+{
+ return "com.sun.star.comp.Writer.WriterModule";
+}
+
+sal_Bool SAL_CALL SwUnoModule::supportsService( const OUString& sServiceName )
+{
+ return cppu::supportsService(this, sServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL SwUnoModule::getSupportedServiceNames( )
+{
+ uno::Sequence<OUString> aSeq { "com.sun.star.text.ModuleDispatcher" };
+ return aSeq;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/uno/unomodule.hxx b/sw/source/uibase/uno/unomodule.hxx
new file mode 100644
index 000000000..fa85f11d7
--- /dev/null
+++ b/sw/source/uibase/uno/unomodule.hxx
@@ -0,0 +1,74 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <rtl/ustring.hxx>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XNotifyingDispatch.hpp>
+#include <com/sun/star/frame/DispatchDescriptor.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <cppuhelper/implbase.hxx>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+namespace com
+{
+ namespace sun
+ {
+ namespace star
+ {
+ namespace lang
+ {
+ class XMultiServiceFactory;
+ }
+ namespace beans
+ {
+ struct PropertyValue;
+ }
+ }
+ }
+}
+
+class SwUnoModule : public ::cppu::WeakImplHelper< css::frame::XDispatchProvider, css::frame::XNotifyingDispatch, css::lang::XServiceInfo >
+{
+public:
+ SwUnoModule() {}
+
+ // XNotifyingDispatch
+ virtual void SAL_CALL dispatchWithNotification( const css::util::URL& aURL, const css::uno::Sequence< css::beans::PropertyValue >& aArgs, const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ) override;
+
+ // XDispatch
+ virtual void SAL_CALL dispatch( const css::util::URL& aURL, const css::uno::Sequence< css::beans::PropertyValue >& aArgs ) override;
+ virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener > & xControl, const css::util::URL& aURL) override;
+ virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener > & xControl, const css::util::URL& aURL) override;
+
+ // XDispatchProvider
+ virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& seqDescriptor ) override ;
+ virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch( const css::util::URL & aURL ,
+ const OUString & sTargetFrameName,
+ sal_Int32 eSearchFlags ) override ;
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName( ) override;
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
new file mode 100644
index 000000000..b3f6e2e74
--- /dev/null
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -0,0 +1,4707 @@
+/* -*- 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 <sal/config.h>
+#include <officecfg/Office/Common.hxx>
+#include <comphelper/string.hxx>
+#include <AnnotationWin.hxx>
+#include <o3tl/any.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/sysdata.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/print.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/lokhelper.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/printer.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <toolkit/awt/vclxdevice.hxx>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <sfx2/lokcomponenthelpers.hxx>
+#include <sfx2/ipclient.hxx>
+#include <editeng/svxacorr.hxx>
+#include <editeng/acorrcfg.hxx>
+#include <cmdid.h>
+#include <swtypes.hxx>
+#include <wdocsh.hxx>
+#include <wrtsh.hxx>
+#include <pview.hxx>
+#include <viewsh.hxx>
+#include <pvprtdat.hxx>
+#include <printdata.hxx>
+#include <pagefrm.hxx>
+#include <rootfrm.hxx>
+#include <svl/stritem.hxx>
+#include <unotxdoc.hxx>
+#include <svl/numformat.hxx>
+#include <svl/numuno.hxx>
+#include <fldbas.hxx>
+#include <unomap.hxx>
+#include <unotextbodyhf.hxx>
+#include <unotextrange.hxx>
+#include <unotextcursor.hxx>
+#include <unosett.hxx>
+#include <unocoll.hxx>
+#include <unoredlines.hxx>
+#include <unosrch.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/objsh.hxx>
+#include <unoprnms.hxx>
+#include <unostyle.hxx>
+#include <unodraw.hxx>
+#include <svl/eitem.hxx>
+#include <unotools/datetime.hxx>
+#include <unocrsr.hxx>
+#include <unofieldcoll.hxx>
+#include <unoidxcoll.hxx>
+#include <unocrsrhelper.hxx>
+#include <globdoc.hxx>
+#include <viewopt.hxx>
+#include <unochart.hxx>
+#include <charatr.hxx>
+#include <svx/xmleohlp.hxx>
+#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/lang/NoSupportException.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/XFastPropertySet.hpp>
+#include <com/sun/star/document/RedlineDisplayType.hpp>
+#include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/script/XInvocation.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <sfx2/linkmgr.hxx>
+#include <svx/unofill.hxx>
+#include <swmodule.hxx>
+#include <docstat.hxx>
+#include <modcfg.hxx>
+#include <ndtxt.hxx>
+#include <strings.hrc>
+#include <bitmaps.hlst>
+#include "unodefaults.hxx"
+#include "SwXDocumentSettings.hxx"
+#include <doc.hxx>
+#include <IDocumentSettingAccess.hxx>
+#include <IDocumentDeviceAccess.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+#include <IDocumentChartDataProviderAccess.hxx>
+#include <IDocumentLinksAdministration.hxx>
+#include <IDocumentRedlineAccess.hxx>
+#include <IDocumentFieldsAccess.hxx>
+#include <IDocumentStatistics.hxx>
+#include <IDocumentStylePoolAccess.hxx>
+#include <IDocumentState.hxx>
+#include <drawdoc.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <osl/file.hxx>
+#include <comphelper/lok.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <sfx2/dispatch.hxx>
+#include <swruler.hxx>
+#include <docufld.hxx>
+
+#include <EnhancedPDFExportHelper.hxx>
+#include <numrule.hxx>
+
+#include <editeng/langitem.hxx>
+#include <docary.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nutil/searchopt.hxx>
+
+#include <charfmt.hxx>
+#include <fmtcol.hxx>
+#include <istyleaccess.hxx>
+
+#include <swatrset.hxx>
+#include <view.hxx>
+#include <viscrs.hxx>
+#include <srcview.hxx>
+#include <edtwin.hxx>
+#include <swdtflvr.hxx>
+#include <PostItMgr.hxx>
+
+#include <svtools/langtab.hxx>
+#include <map>
+#include <set>
+#include <vector>
+
+#include <editeng/eeitem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <svx/svdoutl.hxx>
+#include <svx/svdview.hxx>
+#include <comphelper/interfacecontainer4.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <memory>
+#include <redline.hxx>
+#include <DocumentRedlineManager.hxx>
+#include <xmloff/odffields.hxx>
+#include <tools/json_writer.hxx>
+#include <tools/UnitConversion.hxx>
+
+#include <svx/svdpage.hxx>
+
+#include <IDocumentOutlineNodes.hxx>
+#include <SearchResultLocator.hxx>
+#include <textcontentcontrol.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::i18n;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::document;
+using ::osl::FileBase;
+
+static std::unique_ptr<SwPrintUIOptions> lcl_GetPrintUIOptions(
+ SwDocShell * pDocShell,
+ const SfxViewShell * pView )
+{
+ if (!pDocShell)
+ return nullptr;
+
+ const bool bWebDoc = nullptr != dynamic_cast< const SwWebDocShell * >(pDocShell);
+ const bool bSwSrcView = nullptr != dynamic_cast< const SwSrcView * >(pView);
+ const SwView * pSwView = dynamic_cast< const SwView * >(pView);
+ const bool bHasSelection = pSwView && pSwView->HasSelection( false ); // check for any selection, not just text selection
+ const bool bHasPostIts = sw_GetPostIts(pDocShell->GetDoc()->getIDocumentFieldsAccess(), nullptr);
+
+ // get default values to use in dialog from documents SwPrintData
+ const SwPrintData &rPrintData = pDocShell->GetDoc()->getIDocumentDeviceAccess().getPrintData();
+
+ // Get current page number
+ sal_uInt16 nCurrentPage = 1;
+ const SwWrtShell* pSh = pDocShell->GetWrtShell();
+ const SwRootFrame *pFrame = nullptr;
+ if (pSh)
+ {
+ SwPaM* pShellCursor = pSh->GetCursor();
+ nCurrentPage = pShellCursor->GetPageNum();
+ pFrame = pSh->GetLayout();
+ }
+ else if (!bSwSrcView)
+ {
+ const SwPagePreview* pPreview = dynamic_cast< const SwPagePreview* >(pView);
+ OSL_ENSURE(pPreview, "Unexpected type of the view shell");
+ if (pPreview)
+ {
+ nCurrentPage = pPreview->GetSelectedPage();
+ pFrame = pPreview->GetViewShell()->GetLayout();
+ }
+ }
+
+ // If blanks are skipped, account for them in initial page range value
+ if (pFrame && !rPrintData.IsPrintEmptyPages())
+ {
+ sal_uInt16 nMax = nCurrentPage;
+ const SwPageFrame *pPage = dynamic_cast<const SwPageFrame*>(pFrame->Lower());
+ while (pPage && nMax-- > 0)
+ {
+ if (pPage->getFrameArea().Height() == 0)
+ nCurrentPage--;
+ pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
+ }
+ }
+ return std::make_unique<SwPrintUIOptions>( nCurrentPage, bWebDoc, bSwSrcView, bHasSelection, bHasPostIts, rPrintData );
+}
+
+static SwTextFormatColl *lcl_GetParaStyle(const OUString& rCollName, SwDoc& rDoc)
+{
+ SwTextFormatColl* pColl = rDoc.FindTextFormatCollByName( rCollName );
+ if( !pColl )
+ {
+ const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(
+ rCollName, SwGetPoolIdFromName::TxtColl );
+ if( USHRT_MAX != nId )
+ pColl = rDoc.getIDocumentStylePoolAccess().GetTextCollFromPool( nId );
+ }
+ return pColl;
+}
+
+static void lcl_DisposeView( SfxViewFrame* pToClose, SwDocShell const * pDocShell )
+{
+ // check if the view frame still exists
+ SfxViewFrame* pFound = SfxViewFrame::GetFirst( pDocShell, false );
+ while(pFound)
+ {
+ if( pFound == pToClose)
+ {
+ pToClose->DoClose();
+ break;
+ }
+ pFound = SfxViewFrame::GetNext( *pFound, pDocShell, false );
+ }
+}
+
+class SwXTextDocument::Impl
+{
+public:
+ std::mutex m_Mutex; // just for OInterfaceContainerHelper4
+ ::comphelper::OInterfaceContainerHelper4<css::util::XRefreshListener> m_RefreshListeners;
+};
+
+const Sequence< sal_Int8 > & SwXTextDocument::getUnoTunnelId()
+{
+ static const comphelper::UnoIdInit theSwXTextDocumentUnoTunnelId;
+ return theSwXTextDocumentUnoTunnelId.getSeq();
+}
+
+sal_Int64 SAL_CALL SwXTextDocument::getSomething( const Sequence< sal_Int8 >& rId )
+{
+ if( comphelper::isUnoTunnelId<SwXTextDocument>(rId) )
+ {
+ return comphelper::getSomething_cast(this);
+ }
+ if( comphelper::isUnoTunnelId<SfxObjectShell>(rId) )
+ {
+ return comphelper::getSomething_cast(m_pDocShell);
+ }
+
+ sal_Int64 nRet = SfxBaseModel::getSomething( rId );
+ if (nRet)
+ return nRet;
+
+ GetNumberFormatter();
+ if (!m_xNumFormatAgg.is()) // may happen if not valid or no SwDoc
+ return 0;
+ Any aNumTunnel = m_xNumFormatAgg->queryAggregation(cppu::UnoType<XUnoTunnel>::get());
+ Reference<XUnoTunnel> xNumTunnel;
+ aNumTunnel >>= xNumTunnel;
+ return (xNumTunnel.is()) ? xNumTunnel->getSomething(rId) : 0;
+}
+
+Any SAL_CALL SwXTextDocument::queryInterface( const uno::Type& rType )
+{
+ Any aRet = SwXTextDocumentBaseClass::queryInterface(rType);
+ if ( !aRet.hasValue() )
+ aRet = SfxBaseModel::queryInterface(rType);
+ if ( !aRet.hasValue() &&
+ rType == cppu::UnoType<lang::XMultiServiceFactory>::get())
+ {
+ Reference<lang::XMultiServiceFactory> xTmp = this;
+ aRet <<= xTmp;
+ }
+ if ( !aRet.hasValue() &&
+ rType == cppu::UnoType<tiledrendering::XTiledRenderable>::get())
+ {
+ Reference<tiledrendering::XTiledRenderable> xTmp = this;
+ aRet <<= xTmp;
+ }
+
+ if ( !aRet.hasValue()
+ && rType != cppu::UnoType<css::document::XDocumentEventBroadcaster>::get()
+ && rType != cppu::UnoType<css::frame::XController>::get()
+ && rType != cppu::UnoType<css::frame::XFrame>::get()
+ && rType != cppu::UnoType<css::script::XInvocation>::get()
+ && rType != cppu::UnoType<css::beans::XFastPropertySet>::get()
+ && rType != cppu::UnoType<css::awt::XWindow>::get())
+ {
+ GetNumberFormatter();
+ if(m_xNumFormatAgg.is())
+ aRet = m_xNumFormatAgg->queryAggregation(rType);
+ }
+ return aRet;
+}
+
+void SAL_CALL SwXTextDocument::acquire()noexcept
+{
+ SfxBaseModel::acquire();
+}
+
+void SAL_CALL SwXTextDocument::release()noexcept
+{
+ SfxBaseModel::release();
+}
+
+Sequence< uno::Type > SAL_CALL SwXTextDocument::getTypes()
+{
+ Sequence< uno::Type > aNumTypes;
+ GetNumberFormatter();
+ if(m_xNumFormatAgg.is())
+ {
+ const uno::Type& rProvType = cppu::UnoType<XTypeProvider>::get();
+ Any aNumProv = m_xNumFormatAgg->queryAggregation(rProvType);
+ Reference<XTypeProvider> xNumProv;
+ if(aNumProv >>= xNumProv)
+ {
+ aNumTypes = xNumProv->getTypes();
+ }
+ }
+ return comphelper::concatSequences(
+ SfxBaseModel::getTypes(),
+ SwXTextDocumentBaseClass::getTypes(),
+ aNumTypes,
+ Sequence {
+ cppu::UnoType<lang::XMultiServiceFactory>::get(),
+ cppu::UnoType<tiledrendering::XTiledRenderable>::get()});
+}
+
+SwXTextDocument::SwXTextDocument(SwDocShell* pShell)
+ : SwXTextDocumentBaseClass(pShell)
+ , m_pImpl(new Impl)
+ ,
+ m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_DOCUMENT)),
+ m_pDocShell(pShell),
+ m_bObjectValid(pShell != nullptr),
+ m_pHiddenViewFrame(nullptr),
+ // #i117783#
+ m_bApplyPagePrintSettingsFromXPagePrintable( false )
+{
+}
+
+SdrModel& SwXTextDocument::getSdrModelFromUnoModel() const
+{
+ OSL_ENSURE(m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetOrCreateDrawModel(), "No SdrModel in SwDoc, should not happen");
+ return *m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
+}
+
+SwXTextDocument::~SwXTextDocument()
+{
+ InitNewDoc();
+ if(m_xNumFormatAgg.is())
+ {
+ Reference< XInterface > x0;
+ m_xNumFormatAgg->setDelegator(x0);
+ m_xNumFormatAgg = nullptr;
+ }
+ m_pPrintUIOptions.reset();
+ if (m_pRenderData && m_pRenderData->IsViewOptionAdjust())
+ { // rhbz#827695: this can happen if the last page is not printed
+ // the SwViewShell has been deleted already by SwView::~SwView
+ // FIXME: replace this awful implementation of XRenderable with
+ // something less insane that has its own view
+ m_pRenderData->ViewOptionAdjustCrashPreventionKludge();
+ }
+ m_pRenderData.reset();
+}
+
+SwXDocumentPropertyHelper * SwXTextDocument::GetPropertyHelper ()
+{
+ if(!mxPropertyHelper.is())
+ {
+ mxPropertyHelper = new SwXDocumentPropertyHelper(*m_pDocShell->GetDoc());
+ }
+ return mxPropertyHelper.get();
+}
+
+void SwXTextDocument::GetNumberFormatter()
+{
+ if(!IsValid())
+ return;
+
+ if(!m_xNumFormatAgg.is())
+ {
+ if ( m_pDocShell->GetDoc() )
+ {
+ rtl::Reference<SvNumberFormatsSupplierObj> pNumFormat = new SvNumberFormatsSupplierObj(
+ m_pDocShell->GetDoc()->GetNumberFormatter());
+ m_xNumFormatAgg = pNumFormat;
+ }
+ if(m_xNumFormatAgg.is())
+ m_xNumFormatAgg->setDelegator(static_cast<cppu::OWeakObject*>(static_cast<SwXTextDocumentBaseClass*>(this)));
+ }
+ else
+ {
+ const uno::Type& rTunnelType = cppu::UnoType<XUnoTunnel>::get();
+ Any aNumTunnel = m_xNumFormatAgg->queryAggregation(rTunnelType);
+ Reference< XUnoTunnel > xNumTunnel;
+ aNumTunnel >>= xNumTunnel;
+ SvNumberFormatsSupplierObj* pNumFormat
+ = comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>(xNumTunnel);
+ OSL_ENSURE(pNumFormat, "No number formatter available");
+ if (pNumFormat && !pNumFormat->GetNumberFormatter())
+ pNumFormat->SetNumberFormatter(m_pDocShell->GetDoc()->GetNumberFormatter());
+ }
+}
+
+Reference< XText > SwXTextDocument::getText()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!m_xBodyText.is())
+ {
+ m_xBodyText = new SwXBodyText(m_pDocShell->GetDoc());
+ }
+ return m_xBodyText;
+}
+
+void SwXTextDocument::reformat()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+}
+
+void SwXTextDocument::lockControllers()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+
+ maActionArr.emplace_front(new UnoActionContext(m_pDocShell->GetDoc()));
+}
+
+void SwXTextDocument::unlockControllers()
+{
+ SolarMutexGuard aGuard;
+ if(maActionArr.empty())
+ throw RuntimeException("Nothing to unlock");
+
+ maActionArr.pop_front();
+}
+
+sal_Bool SwXTextDocument::hasControllersLocked()
+{
+ SolarMutexGuard aGuard;
+ return !maActionArr.empty();
+}
+
+Reference< frame::XController > SwXTextDocument::getCurrentController()
+{
+ return SfxBaseModel::getCurrentController();
+}
+
+void SwXTextDocument::setCurrentController(const Reference< frame::XController > & xController)
+{
+ SfxBaseModel::setCurrentController(xController);
+}
+
+Reference< XInterface > SwXTextDocument::getCurrentSelection()
+{
+ SolarMutexGuard aGuard;
+ Reference< XInterface > xRef;
+ if(IsValid())
+ {
+ SwView* pView = static_cast<SwView*>(SfxViewShell::GetFirst(true, checkSfxViewShell<SwView>));
+ while(pView && pView->GetObjectShell() != m_pDocShell)
+ {
+ pView = static_cast<SwView*>(SfxViewShell::GetNext(*pView, true, checkSfxViewShell<SwView>));
+ }
+ if(pView)
+ {
+ Any aRef = pView->GetUNOObject()->getSelection();
+ aRef >>= xRef;
+ }
+ }
+ return xRef;
+}
+
+sal_Bool SwXTextDocument::attachResource(const OUString& aURL, const Sequence< beans::PropertyValue >& aArgs)
+{
+ return SfxBaseModel::attachResource(aURL, aArgs);
+}
+
+OUString SwXTextDocument::getURL()
+{
+ return SfxBaseModel::getURL();
+}
+
+Sequence< beans::PropertyValue > SwXTextDocument::getArgs()
+{
+ return SfxBaseModel::getArgs();
+}
+
+void SwXTextDocument::connectController(const Reference< frame::XController > & xController)
+{
+ SfxBaseModel::connectController(xController);
+}
+
+void SwXTextDocument::disconnectController(const Reference< frame::XController > & xController)
+{
+ SfxBaseModel::disconnectController(xController);
+}
+
+void SwXTextDocument::dispose()
+{
+ // Delete UnoActionContexts before deleting the SwDoc, as the first has unowned pointers to the
+ // second.
+ maActionArr.clear();
+
+ SfxBaseModel::dispose();
+}
+
+void SwXTextDocument::close( sal_Bool bDeliverOwnership )
+{
+ if(m_pDocShell)
+ {
+ uno::Sequence< uno::Any > aArgs;
+ m_pDocShell->CallAutomationDocumentEventSinks( "Close", aArgs );
+ }
+ SolarMutexGuard aGuard;
+ if(IsValid() && m_pHiddenViewFrame)
+ lcl_DisposeView( m_pHiddenViewFrame, m_pDocShell);
+ SfxBaseModel::close(bDeliverOwnership);
+}
+
+void SwXTextDocument::addEventListener(const Reference< lang::XEventListener > & aListener)
+{
+ SfxBaseModel::addEventListener(aListener);
+}
+
+void SwXTextDocument::removeEventListener(const Reference< lang::XEventListener > & aListener)
+{
+ SfxBaseModel::removeEventListener(aListener);
+}
+
+Reference< XPropertySet > SwXTextDocument::getLineNumberingProperties()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+
+ if(!mxXLineNumberingProperties.is())
+ {
+ mxXLineNumberingProperties = new SwXLineNumberingProperties(m_pDocShell->GetDoc());
+ }
+ return mxXLineNumberingProperties;
+}
+
+Reference< XIndexReplace > SwXTextDocument::getChapterNumberingRules()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!mxXChapterNumbering.is())
+ {
+ mxXChapterNumbering = new SwXChapterNumbering(*m_pDocShell);
+ }
+ return mxXChapterNumbering;
+}
+
+Reference< XIndexAccess > SwXTextDocument::getNumberingRules()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!mxXNumberingRules.is() )
+ {
+ mxXNumberingRules = new SwXNumberingRulesCollection( m_pDocShell->GetDoc() );
+ }
+ return mxXNumberingRules;
+}
+
+Reference< XIndexAccess > SwXTextDocument::getFootnotes()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!mxXFootnotes.is())
+ {
+ mxXFootnotes = new SwXFootnotes(false, m_pDocShell->GetDoc());
+ }
+ return mxXFootnotes;
+}
+
+Reference< XPropertySet > SAL_CALL
+ SwXTextDocument::getFootnoteSettings()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!mxXFootnoteSettings.is())
+ {
+ mxXFootnoteSettings = new SwXFootnoteProperties(m_pDocShell->GetDoc());
+ }
+ return mxXFootnoteSettings;
+}
+
+Reference< XIndexAccess > SwXTextDocument::getEndnotes()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!mxXEndnotes.is())
+ {
+ mxXEndnotes = new SwXFootnotes(true, m_pDocShell->GetDoc());
+ }
+ return mxXEndnotes;
+}
+
+Reference< XPropertySet > SwXTextDocument::getEndnoteSettings()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!mxXEndnoteSettings.is())
+ {
+ mxXEndnoteSettings = new SwXEndnoteProperties(m_pDocShell->GetDoc());
+ }
+ return mxXEndnoteSettings;
+}
+
+Reference< util::XReplaceDescriptor > SwXTextDocument::createReplaceDescriptor()
+{
+ return new SwXTextSearch;
+}
+
+SwUnoCursor* SwXTextDocument::CreateCursorForSearch(Reference< XTextCursor > & xCursor)
+{
+ getText();
+ XText *const pText = m_xBodyText.get();
+ SwXBodyText* pBText = static_cast<SwXBodyText*>(pText);
+ rtl::Reference<SwXTextCursor> pXTextCursor = pBText->CreateTextCursor(true);
+ xCursor.set( static_cast<text::XWordCursor*>(pXTextCursor.get()) );
+
+ auto& rUnoCursor(pXTextCursor->GetCursor());
+ rUnoCursor.SetRemainInSection(false);
+ return &rUnoCursor;
+}
+
+sal_Int32 SwXTextDocument::replaceAll(const Reference< util::XSearchDescriptor > & xDesc)
+{
+ SolarMutexGuard aGuard;
+ Reference< XUnoTunnel > xDescTunnel(xDesc, UNO_QUERY_THROW);
+ SwXTextSearch* pSearch;
+ if (!IsValid() || !(pSearch = comphelper::getFromUnoTunnel<SwXTextSearch>(xDescTunnel)))
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+
+ Reference< XTextCursor > xCursor;
+ auto pUnoCursor(CreateCursorForSearch(xCursor));
+ int eRanges(FindRanges::InBody|FindRanges::InSelAll);
+
+ i18nutil::SearchOptions2 aSearchOpt;
+ pSearch->FillSearchOptions( aSearchOpt );
+
+ SwDocPositions eStart = pSearch->m_bBack ? SwDocPositions::End : SwDocPositions::Start;
+ SwDocPositions eEnd = pSearch->m_bBack ? SwDocPositions::Start : SwDocPositions::End;
+
+ // Search should take place anywhere
+ pUnoCursor->SetRemainInSection(false);
+ sal_uInt32 nResult;
+ UnoActionContext aContext(m_pDocShell->GetDoc());
+ //try attribute search first
+ if(pSearch->HasSearchAttributes()||pSearch->HasReplaceAttributes())
+ {
+ SfxItemSetFixed<RES_CHRATR_BEGIN, RES_CHRATR_END-1,
+ RES_PARATR_BEGIN, RES_PARATR_END-1,
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1> aSearch(m_pDocShell->GetDoc()->GetAttrPool());
+ SfxItemSetFixed<RES_CHRATR_BEGIN, RES_CHRATR_END-1,
+ RES_PARATR_BEGIN, RES_PARATR_END-1,
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1> aReplace(m_pDocShell->GetDoc()->GetAttrPool());
+ pSearch->FillSearchItemSet(aSearch);
+ pSearch->FillReplaceItemSet(aReplace);
+ bool bCancel;
+ nResult = static_cast<sal_Int32>(pUnoCursor->FindAttrs(aSearch, !pSearch->m_bStyles,
+ eStart, eEnd, bCancel,
+ static_cast<FindRanges>(eRanges),
+ !pSearch->m_sSearchText.isEmpty() ? &aSearchOpt : nullptr,
+ &aReplace ));
+ }
+ else if(pSearch->m_bStyles)
+ {
+ SwTextFormatColl *pSearchColl = lcl_GetParaStyle(pSearch->m_sSearchText, pUnoCursor->GetDoc());
+ SwTextFormatColl *pReplaceColl = lcl_GetParaStyle(pSearch->m_sReplaceText, pUnoCursor->GetDoc());
+
+ bool bCancel;
+ nResult = pUnoCursor->FindFormat(*pSearchColl,
+ eStart, eEnd, bCancel,
+ static_cast<FindRanges>(eRanges), pReplaceColl );
+
+ }
+ else
+ {
+ //todo/mba: assuming that notes should be omitted
+ bool bCancel;
+ nResult = pUnoCursor->Find_Text(aSearchOpt, false/*bSearchInNotes*/,
+ eStart, eEnd, bCancel,
+ static_cast<FindRanges>(eRanges),
+ true );
+ }
+ return static_cast<sal_Int32>(nResult);
+
+}
+
+Reference< util::XSearchDescriptor > SwXTextDocument::createSearchDescriptor()
+{
+ return new SwXTextSearch;
+}
+
+// Used for findAll/First/Next
+
+SwUnoCursor* SwXTextDocument::FindAny(const Reference< util::XSearchDescriptor > & xDesc,
+ Reference< XTextCursor > & xCursor,
+ bool bAll,
+ sal_Int32& nResult,
+ Reference< XInterface > const & xLastResult)
+{
+ const auto pSearch = comphelper::getFromUnoTunnel<SwXTextSearch>(xDesc);
+ if(!IsValid() || !pSearch)
+ return nullptr;
+
+ auto pUnoCursor(CreateCursorForSearch(xCursor));
+
+ bool bParentInExtra = false;
+ if(xLastResult.is())
+ {
+ Reference<XUnoTunnel> xCursorTunnel( xLastResult, UNO_QUERY);
+ OTextCursorHelper* pPosCursor = comphelper::getFromUnoTunnel<OTextCursorHelper>(xCursorTunnel);
+ SwPaM* pCursor = pPosCursor ? pPosCursor->GetPaM() : nullptr;
+ if(pCursor)
+ {
+ *pUnoCursor->GetPoint() = *pCursor->End();
+ pUnoCursor->DeleteMark();
+ }
+ else
+ {
+ SwXTextRange* pRange = comphelper::getFromUnoTunnel<SwXTextRange>(xCursorTunnel);
+ if(!pRange)
+ return nullptr;
+ pRange->GetPositions(*pUnoCursor);
+ if(pUnoCursor->HasMark())
+ {
+ if(*pUnoCursor->GetPoint() < *pUnoCursor->GetMark())
+ pUnoCursor->Exchange();
+ pUnoCursor->DeleteMark();
+ }
+ }
+ const SwNode& rRangeNode = pUnoCursor->GetNode();
+ bParentInExtra = rRangeNode.FindFlyStartNode() ||
+ rRangeNode.FindFootnoteStartNode() ||
+ rRangeNode.FindHeaderStartNode() ||
+ rRangeNode.FindFooterStartNode() ;
+ }
+
+ i18nutil::SearchOptions2 aSearchOpt;
+ pSearch->FillSearchOptions( aSearchOpt );
+
+/**
+ * The following combinations are allowed:
+ * - Search in the body: -> FindRanges::InBody
+ * - Search all in the body: -> FindRanges::InBodyOnly | FindRanges::InSelAll
+ * - Search in selections: one / all -> FindRanges::InSel [ | FindRanges::InSelAll ]
+ * - Search outside the body: one / all -> FindRanges::InOther [ | FindRanges::InSelAll ]
+ * - Search everywhere all: -> FindRanges::InSelAll
+ */
+ FindRanges eRanges(FindRanges::InBody);
+ if(bParentInExtra)
+ eRanges = FindRanges::InOther;
+ if(bAll) //always - everywhere?
+ eRanges = FindRanges::InSelAll;
+ SwDocPositions eStart = !bAll ? SwDocPositions::Curr : pSearch->m_bBack ? SwDocPositions::End : SwDocPositions::Start;
+ SwDocPositions eEnd = pSearch->m_bBack ? SwDocPositions::Start : SwDocPositions::End;
+
+ nResult = 0;
+ for (int nSearchProc = 0; nSearchProc < 2; ++nSearchProc)
+ {
+ //try attribute search first
+ if(pSearch->HasSearchAttributes())
+ {
+ SfxItemSetFixed<
+ RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
+ RES_TXTATR_INETFMT, RES_TXTATR_CHARFMT,
+ RES_PARATR_BEGIN, RES_PARATR_END - 1,
+ RES_FRMATR_BEGIN, RES_FRMATR_END - 1>
+ aSearch( m_pDocShell->GetDoc()->GetAttrPool() );
+ pSearch->FillSearchItemSet(aSearch);
+ bool bCancel;
+ nResult = static_cast<sal_Int32>(pUnoCursor->FindAttrs(aSearch, !pSearch->m_bStyles,
+ eStart, eEnd, bCancel,
+ eRanges,
+ !pSearch->m_sSearchText.isEmpty() ? &aSearchOpt : nullptr ));
+ }
+ else if(pSearch->m_bStyles)
+ {
+ SwTextFormatColl *pSearchColl = lcl_GetParaStyle(pSearch->m_sSearchText, pUnoCursor->GetDoc());
+ //pSearch->sReplaceText
+ SwTextFormatColl *pReplaceColl = nullptr;
+ bool bCancel;
+ nResult = static_cast<sal_Int32>(pUnoCursor->FindFormat(*pSearchColl,
+ eStart, eEnd, bCancel,
+ eRanges, pReplaceColl ));
+ }
+ else
+ {
+ //todo/mba: assuming that notes should be omitted
+ bool bCancel;
+ nResult = static_cast<sal_Int32>(pUnoCursor->Find_Text(aSearchOpt, false/*bSearchInNotes*/,
+ eStart, eEnd, bCancel,
+ eRanges ));
+ }
+ if(nResult || (eRanges&(FindRanges::InSelAll|FindRanges::InOther)))
+ break;
+ //second step - find in other
+ eRanges = FindRanges::InOther;
+ }
+ return pUnoCursor;
+}
+
+Reference< XIndexAccess >
+ SwXTextDocument::findAll(const Reference< util::XSearchDescriptor > & xDesc)
+{
+ SolarMutexGuard aGuard;
+ Reference< XInterface > xTmp;
+ sal_Int32 nResult = 0;
+ Reference< XTextCursor > xCursor;
+ auto pResultCursor(FindAny(xDesc, xCursor, true, nResult, xTmp));
+ if(!pResultCursor)
+ throw RuntimeException("No result cursor");
+ Reference< XIndexAccess > xRet = SwXTextRanges::Create( nResult ? &(*pResultCursor) : nullptr );
+ return xRet;
+}
+
+Reference< XInterface > SwXTextDocument::findFirst(const Reference< util::XSearchDescriptor > & xDesc)
+{
+ SolarMutexGuard aGuard;
+ Reference< XInterface > xTmp;
+ sal_Int32 nResult = 0;
+ Reference< XTextCursor > xCursor;
+ auto pResultCursor(FindAny(xDesc, xCursor, false, nResult, xTmp));
+ if(!pResultCursor)
+ throw RuntimeException("No result cursor");
+ Reference< XInterface > xRet;
+ if(nResult)
+ {
+ const uno::Reference< text::XText > xParent =
+ ::sw::CreateParentXText(*m_pDocShell->GetDoc(),
+ *pResultCursor->GetPoint());
+ xRet = *new SwXTextCursor(xParent, *pResultCursor);
+ }
+ return xRet;
+}
+
+Reference< XInterface > SwXTextDocument::findNext(const Reference< XInterface > & xStartAt,
+ const Reference< util::XSearchDescriptor > & xDesc)
+{
+ SolarMutexGuard aGuard;
+ sal_Int32 nResult = 0;
+ Reference< XTextCursor > xCursor;
+ if(!xStartAt.is())
+ throw RuntimeException("xStartAt missing");
+ auto pResultCursor(FindAny(xDesc, xCursor, false, nResult, xStartAt));
+ if(!pResultCursor)
+ throw RuntimeException("No result cursor");
+ Reference< XInterface > xRet;
+ if(nResult)
+ {
+ const uno::Reference< text::XText > xParent =
+ ::sw::CreateParentXText(*m_pDocShell->GetDoc(),
+ *pResultCursor->GetPoint());
+
+ xRet = *new SwXTextCursor(xParent, *pResultCursor);
+ }
+ return xRet;
+}
+
+Sequence< beans::PropertyValue > SwXTextDocument::getPagePrintSettings()
+{
+ SolarMutexGuard aGuard;
+ Sequence< beans::PropertyValue > aSeq(9);
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+
+ beans::PropertyValue* pArray = aSeq.getArray();
+ SwPagePreviewPrtData aData;
+ const SwPagePreviewPrtData* pData = m_pDocShell->GetDoc()->GetPreviewPrtData();
+ if(pData)
+ aData = *pData;
+ Any aVal;
+ aVal <<= static_cast<sal_Int16>(aData.GetRow());
+ pArray[0] = beans::PropertyValue("PageRows", -1, aVal, PropertyState_DIRECT_VALUE);
+ aVal <<= static_cast<sal_Int16>(aData.GetCol());
+ pArray[1] = beans::PropertyValue("PageColumns", -1, aVal, PropertyState_DIRECT_VALUE);
+ aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetLeftSpace()));
+ pArray[2] = beans::PropertyValue("LeftMargin", -1, aVal, PropertyState_DIRECT_VALUE);
+ aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetRightSpace()));
+ pArray[3] = beans::PropertyValue("RightMargin", -1, aVal, PropertyState_DIRECT_VALUE);
+ aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetTopSpace()));
+ pArray[4] = beans::PropertyValue("TopMargin", -1, aVal, PropertyState_DIRECT_VALUE);
+ aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetBottomSpace()));
+ pArray[5] = beans::PropertyValue("BottomMargin", -1, aVal, PropertyState_DIRECT_VALUE);
+ aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetHorzSpace()));
+ pArray[6] = beans::PropertyValue("HoriMargin", -1, aVal, PropertyState_DIRECT_VALUE);
+ aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetVertSpace()));
+ pArray[7] = beans::PropertyValue("VertMargin", -1, aVal, PropertyState_DIRECT_VALUE);
+ aVal <<= aData.GetLandscape();
+ pArray[8] = beans::PropertyValue("IsLandscape", -1, aVal, PropertyState_DIRECT_VALUE);
+
+ return aSeq;
+}
+
+static sal_uInt32 lcl_Any_To_ULONG(const Any& rValue, bool& bException)
+{
+ bException = false;
+ TypeClass eType = rValue.getValueType().getTypeClass();
+
+ sal_uInt32 nRet = 0;
+ if( eType == TypeClass_UNSIGNED_LONG )
+ rValue >>= nRet;
+ else
+ {
+ sal_Int32 nVal=0;
+ bException = !(rValue >>= nVal);
+ if( !bException )
+ nRet = static_cast<sal_uInt32>(nVal);
+ }
+
+ return nRet;
+}
+
+static OUString lcl_CreateOutlineString(const size_t nIndex, const SwDoc* pDoc)
+{
+ OUStringBuffer sEntry;
+ const SwOutlineNodes& rOutlineNodes = pDoc->GetNodes().GetOutLineNds();
+ const SwNumRule* pOutlRule = pDoc->GetOutlineNumRule();
+ const SwTextNode * pTextNd = rOutlineNodes[ nIndex ]->GetTextNode();
+ SwNumberTree::tNumberVector aNumVector = pTextNd->GetNumberVector();
+ if( pOutlRule && pTextNd->GetNumRule())
+ for( int nLevel = 0;
+ nLevel <= pTextNd->GetActualListLevel();
+ nLevel++ )
+ {
+ tools::Long nVal = aNumVector[nLevel];
+ nVal ++;
+ nVal -= pOutlRule->Get(nLevel).GetStart();
+ sEntry.append( nVal );
+ sEntry.append(".");
+ }
+ OUString sOutlineText = pDoc->getIDocumentOutlineNodes().getOutlineText(
+ nIndex, pDoc->GetDocShell()->GetWrtShell()->GetLayout(), false);
+ sEntry.append(sOutlineText);
+ return sEntry.makeStringAndClear();
+}
+
+void SwXTextDocument::setPagePrintSettings(const Sequence< beans::PropertyValue >& aSettings)
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+
+ SwPagePreviewPrtData aData;
+ //if only a few properties are coming, then use the current settings
+ const SwPagePreviewPrtData* pData = m_pDocShell->GetDoc()->GetPreviewPrtData();
+ if(pData)
+ aData = *pData;
+ for(const beans::PropertyValue& rProperty : aSettings)
+ {
+ OUString sName = rProperty.Name;
+ const Any& rVal = rProperty.Value;
+ bool bException;
+ sal_uInt32 nVal = lcl_Any_To_ULONG(rVal, bException);
+ if( sName == "PageRows" )
+ {
+ if(!nVal || nVal > 0xff)
+ throw RuntimeException("Invalid value");
+ aData.SetRow(static_cast<sal_uInt8>(nVal));
+ }
+ else if(sName == "PageColumns")
+ {
+ if(!nVal || nVal > 0xff)
+ throw RuntimeException("Invalid value");
+ aData.SetCol(static_cast<sal_uInt8>(nVal));
+ }
+ else if(sName == "LeftMargin")
+ {
+ aData.SetLeftSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
+ }
+ else if(sName == "RightMargin")
+ {
+ aData.SetRightSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
+ }
+ else if(sName == "TopMargin")
+ {
+ aData.SetTopSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
+ }
+ else if(sName == "BottomMargin")
+ {
+ aData.SetBottomSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
+ }
+ else if(sName == "HoriMargin")
+ {
+ aData.SetHorzSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
+ }
+ else if(sName == "VertMargin")
+ {
+ aData.SetVertSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
+ }
+ else if(sName == "IsLandscape")
+ {
+ auto b = o3tl::tryAccess<bool>(rVal);
+ bException = !b;
+ if (b)
+ {
+ aData.SetLandscape(*b);
+ }
+ }
+ else
+ bException = true;
+ if(bException)
+ throw RuntimeException();
+ }
+ m_pDocShell->GetDoc()->SetPreviewPrtData(&aData);
+
+}
+
+void SwXTextDocument::printPages(const Sequence< beans::PropertyValue >& xOptions)
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+
+ SfxViewFrame* pFrame = SfxViewFrame::LoadHiddenDocument( *m_pDocShell, SfxInterfaceId(7) );
+ SfxRequest aReq(FN_PRINT_PAGEPREVIEW, SfxCallMode::SYNCHRON,
+ m_pDocShell->GetDoc()->GetAttrPool());
+ aReq.AppendItem(SfxBoolItem(FN_PRINT_PAGEPREVIEW, true));
+
+ for ( const beans::PropertyValue &rProp : xOptions )
+ {
+ // get Property-Value from options
+ Any aValue( rProp.Value );
+
+ // FileName-Property?
+ if ( rProp.Name == UNO_NAME_FILE_NAME )
+ {
+ OUString sFileURL;
+ if ( rProp.Value >>= sFileURL )
+ {
+ // Convert the File URL into a system dependent path, as the SalPrinter expects
+ OUString sSystemPath;
+ FileBase::getSystemPathFromFileURL ( sFileURL, sSystemPath );
+ aReq.AppendItem(SfxStringItem( SID_FILE_NAME, sSystemPath ) );
+ }
+ else if ( rProp.Value.getValueType() != cppu::UnoType<void>::get() )
+ throw IllegalArgumentException();
+ }
+
+ // CopyCount-Property
+ else if ( rProp.Name == UNO_NAME_COPY_COUNT )
+ {
+ sal_Int32 nCopies = 0;
+ aValue >>= nCopies;
+ aReq.AppendItem(SfxInt16Item( SID_PRINT_COPIES, static_cast<sal_Int16>(nCopies) ) );
+ }
+
+ // Collate-Property
+ else if ( rProp.Name == UNO_NAME_COLLATE )
+ {
+ auto b = o3tl::tryAccess<bool>(rProp.Value);
+ if ( !b )
+ throw IllegalArgumentException();
+ aReq.AppendItem(SfxBoolItem( SID_PRINT_COLLATE, *b ) );
+
+ }
+
+ // Sort-Property
+ else if ( rProp.Name == UNO_NAME_SORT )
+ {
+ auto b = o3tl::tryAccess<bool>(rProp.Value);
+ if ( !b )
+ throw IllegalArgumentException();
+
+ aReq.AppendItem(SfxBoolItem( SID_PRINT_SORT, *b ) );
+ }
+
+ // Pages-Property
+ else if ( rProp.Name == UNO_NAME_PAGES )
+ {
+ OUString sTmp;
+ if ( !(rProp.Value >>= sTmp) )
+ throw IllegalArgumentException();
+
+ aReq.AppendItem( SfxStringItem( SID_PRINT_PAGES, sTmp ) );
+
+ }
+ }
+
+ // #i117783#
+ m_bApplyPagePrintSettingsFromXPagePrintable = true;
+ pFrame->GetViewShell()->ExecuteSlot(aReq);
+ // Frame close
+ pFrame->DoClose();
+
+}
+
+Reference< XNameAccess > SwXTextDocument::getReferenceMarks()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!mxXReferenceMarks.is())
+ {
+ mxXReferenceMarks = new SwXReferenceMarks(m_pDocShell->GetDoc());
+ }
+ return mxXReferenceMarks;
+}
+
+Reference< XEnumerationAccess > SwXTextDocument::getTextFields()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!mxXTextFieldTypes.is())
+ {
+ mxXTextFieldTypes = new SwXTextFieldTypes(m_pDocShell->GetDoc());
+ }
+ return mxXTextFieldTypes;
+}
+
+Reference< XNameAccess > SwXTextDocument::getTextFieldMasters()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!mxXTextFieldMasters.is())
+ {
+ mxXTextFieldMasters = new SwXTextFieldMasters(m_pDocShell->GetDoc());
+ }
+ return mxXTextFieldMasters;
+}
+
+Reference< XNameAccess > SwXTextDocument::getEmbeddedObjects()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!mxXEmbeddedObjects.is())
+ {
+ mxXEmbeddedObjects = new SwXTextEmbeddedObjects(m_pDocShell->GetDoc());
+ }
+ return mxXEmbeddedObjects;
+}
+
+Reference< XNameAccess > SwXTextDocument::getBookmarks()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!mxXBookmarks.is())
+ {
+ mxXBookmarks = new SwXBookmarks(m_pDocShell->GetDoc());
+ }
+ return mxXBookmarks;
+}
+
+Reference< XNameAccess > SwXTextDocument::getTextSections()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!mxXTextSections.is())
+ {
+ mxXTextSections = new SwXTextSections(m_pDocShell->GetDoc());
+ }
+ return mxXTextSections;
+}
+
+Reference< XNameAccess > SwXTextDocument::getTextTables()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!mxXTextTables.is())
+ {
+ mxXTextTables = new SwXTextTables(m_pDocShell->GetDoc());
+ }
+ return mxXTextTables;
+}
+
+Reference< XNameAccess > SwXTextDocument::getGraphicObjects()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!mxXGraphicObjects.is())
+ {
+ mxXGraphicObjects = new SwXTextGraphicObjects(m_pDocShell->GetDoc());
+ }
+ return mxXGraphicObjects;
+}
+
+Reference< XNameAccess > SwXTextDocument::getTextFrames()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!mxXTextFrames.is())
+ {
+ mxXTextFrames = new SwXTextFrames(m_pDocShell->GetDoc());
+ }
+ return mxXTextFrames;
+}
+
+Reference< XNameAccess > SwXTextDocument::getStyleFamilies()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!mxXStyleFamilies.is())
+ {
+ mxXStyleFamilies = new SwXStyleFamilies(*m_pDocShell);
+ }
+ return mxXStyleFamilies;
+}
+
+uno::Reference< style::XAutoStyles > SwXTextDocument::getAutoStyles( )
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!mxXAutoStyles.is())
+ {
+ mxXAutoStyles = new SwXAutoStyles(*m_pDocShell);
+ }
+ return mxXAutoStyles;
+
+}
+
+Reference< drawing::XDrawPage > SwXTextDocument::getDrawPage()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ if(!m_xDrawPage.is())
+ {
+ m_xDrawPage = new SwXDrawPage(m_pDocShell->GetDoc());
+ // Create a Reference to trigger the complete initialization of the
+ // object. Otherwise in some corner cases it would get initialized
+ // at ::InitNewDoc -> which would get called during
+ // close() or dispose() -> n#681746
+ uno::Reference<lang::XComponent> xTriggerInit( static_cast<cppu::OWeakObject*>(m_xDrawPage.get()), uno::UNO_QUERY );
+ }
+ return m_xDrawPage;
+}
+
+namespace {
+
+class SwDrawPagesObj : public cppu::WeakImplHelper<
+ css::drawing::XDrawPages,
+ css::lang::XServiceInfo>
+{
+private:
+ css::uno::Reference< css::drawing::XDrawPageSupplier > m_xDoc;
+public:
+ SwDrawPagesObj(const css::uno::Reference< css::drawing::XDrawPageSupplier >& rxDoc) : m_xDoc(rxDoc) {}
+
+ // XDrawPages
+ virtual css::uno::Reference< css::drawing::XDrawPage > SAL_CALL
+ insertNewByIndex(sal_Int32 /*nIndex*/) override { throw css::lang::NoSupportException(); }
+
+ virtual void SAL_CALL remove(const css::uno::Reference< css::drawing::XDrawPage >& /*xPage*/) override
+ {
+ throw css::lang::NoSupportException();
+ }
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount() override { return 1; }
+
+ virtual css::uno::Any SAL_CALL getByIndex(sal_Int32 Index) override
+ {
+ if (Index != 0)
+ throw css::lang::IndexOutOfBoundsException("Writer documents have only one DrawPage!");
+ return css::uno::Any(m_xDoc->getDrawPage());
+ }
+
+ // XElementAccess
+ virtual css::uno::Type SAL_CALL getElementType() override
+ {
+ return cppu::UnoType<drawing::XDrawPage>::get();
+ }
+
+ virtual sal_Bool SAL_CALL hasElements() override { return true; }
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override
+ {
+ return "SwDrawPagesObj";
+ }
+
+ virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override
+ {
+ return cppu::supportsService(this, ServiceName);
+ }
+
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
+ {
+ return { "com.sun.star.drawing.DrawPages" };
+ }
+};
+
+}
+
+// XDrawPagesSupplier
+
+uno::Reference<drawing::XDrawPages> SAL_CALL SwXTextDocument::getDrawPages()
+{
+ SolarMutexGuard aGuard;
+ return new SwDrawPagesObj(this);
+}
+
+void SwXTextDocument::Invalidate()
+{
+ m_bObjectValid = false;
+ if(m_xNumFormatAgg.is())
+ {
+ const uno::Type& rTunnelType = cppu::UnoType<XUnoTunnel>::get();
+ Any aNumTunnel = m_xNumFormatAgg->queryAggregation(rTunnelType);
+ Reference< XUnoTunnel > xNumTunnel;
+ aNumTunnel >>= xNumTunnel;
+ SvNumberFormatsSupplierObj* pNumFormat
+ = comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>(xNumTunnel);
+ OSL_ENSURE(pNumFormat, "No number formatter available");
+ if (pNumFormat)
+ pNumFormat->SetNumberFormatter(nullptr);
+ OSL_ENSURE(pNumFormat, "No number formatter available");
+ }
+ InitNewDoc();
+ m_pDocShell = nullptr;
+ lang::EventObject const ev(static_cast<SwXTextDocumentBaseClass &>(*this));
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_RefreshListeners.disposeAndClear(aGuard, ev);
+}
+
+void SwXTextDocument::Reactivate(SwDocShell* pNewDocShell)
+{
+ if(m_pDocShell && m_pDocShell != pNewDocShell)
+ Invalidate();
+ m_pDocShell = pNewDocShell;
+ m_bObjectValid = true;
+}
+
+void SwXTextDocument::InitNewDoc()
+{
+ // first invalidate all collections, then delete references and Set to zero
+ if(mxXTextTables.is())
+ {
+ XNameAccess* pTables = mxXTextTables.get();
+ static_cast<SwXTextTables*>(pTables)->Invalidate();
+ mxXTextTables.clear();
+ }
+
+ if(mxXTextFrames.is())
+ {
+ XNameAccess* pFrames = mxXTextFrames.get();
+ static_cast<SwXTextFrames*>(pFrames)->Invalidate();
+ mxXTextFrames.clear();
+ }
+
+ if(mxXGraphicObjects.is())
+ {
+ XNameAccess* pFrames = mxXGraphicObjects.get();
+ static_cast<SwXTextGraphicObjects*>(pFrames)->Invalidate();
+ mxXGraphicObjects.clear();
+ }
+
+ if(mxXEmbeddedObjects.is())
+ {
+ XNameAccess* pOLE = mxXEmbeddedObjects.get();
+ static_cast<SwXTextEmbeddedObjects*>(pOLE)->Invalidate();
+ mxXEmbeddedObjects.clear();
+ }
+
+ m_xBodyText = nullptr;
+
+ if(m_xNumFormatAgg.is())
+ {
+ const uno::Type& rTunnelType = cppu::UnoType<XUnoTunnel>::get();
+ Any aNumTunnel = m_xNumFormatAgg->queryAggregation(rTunnelType);
+ Reference< XUnoTunnel > xNumTunnel;
+ aNumTunnel >>= xNumTunnel;
+ SvNumberFormatsSupplierObj* pNumFormat
+ = comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>(xNumTunnel);
+ OSL_ENSURE(pNumFormat, "No number formatter available");
+ if (pNumFormat)
+ pNumFormat->SetNumberFormatter(nullptr);
+ }
+
+ if(mxXTextFieldTypes.is())
+ {
+ XEnumerationAccess* pT = mxXTextFieldTypes.get();
+ static_cast<SwXTextFieldTypes*>(pT)->Invalidate();
+ mxXTextFieldTypes.clear();
+ }
+
+ if(mxXTextFieldMasters.is())
+ {
+ XNameAccess* pT = mxXTextFieldMasters.get();
+ static_cast<SwXTextFieldMasters*>(pT)->Invalidate();
+ mxXTextFieldMasters.clear();
+ }
+
+ if(mxXTextSections.is())
+ {
+ XNameAccess* pSect = mxXTextSections.get();
+ static_cast<SwXTextSections*>(pSect)->Invalidate();
+ mxXTextSections.clear();
+ }
+
+ if(m_xDrawPage.is())
+ {
+ // #i91798#, #i91895#
+ // dispose XDrawPage here. We are the owner and know that it is no longer in a valid condition.
+ Reference<XComponent>(static_cast<cppu::OWeakObject*>(m_xDrawPage.get()), UNO_QUERY_THROW)->dispose();
+ m_xDrawPage->InvalidateSwDoc();
+ m_xDrawPage.clear();
+ }
+
+ if ( mxXNumberingRules.is() )
+ {
+ XIndexAccess* pNum = mxXNumberingRules.get();
+ static_cast<SwXNumberingRulesCollection*>(pNum)->Invalidate();
+ mxXNumberingRules.clear();
+ }
+
+ if(mxXFootnotes.is())
+ {
+ XIndexAccess* pFootnote = mxXFootnotes.get();
+ static_cast<SwXFootnotes*>(pFootnote)->Invalidate();
+ mxXFootnotes.clear();
+ }
+
+ if(mxXEndnotes.is())
+ {
+ XIndexAccess* pFootnote = mxXEndnotes.get();
+ static_cast<SwXFootnotes*>(pFootnote)->Invalidate();
+ mxXEndnotes.clear();
+ }
+
+ if(mxXDocumentIndexes.is())
+ {
+ XIndexAccess* pIdxs = mxXDocumentIndexes.get();
+ static_cast<SwXDocumentIndexes*>(pIdxs)->Invalidate();
+ mxXDocumentIndexes.clear();
+ }
+
+ if(mxXStyleFamilies.is())
+ {
+ XNameAccess* pStyles = mxXStyleFamilies.get();
+ static_cast<SwXStyleFamilies*>(pStyles)->Invalidate();
+ mxXStyleFamilies.clear();
+ }
+ if(mxXAutoStyles.is())
+ {
+ XNameAccess* pStyles = mxXAutoStyles.get();
+ static_cast<SwXAutoStyles*>(pStyles)->Invalidate();
+ mxXAutoStyles.clear();
+ }
+
+ if(mxXBookmarks.is())
+ {
+ XNameAccess* pBm = mxXBookmarks.get();
+ static_cast<SwXBookmarks*>(pBm)->Invalidate();
+ mxXBookmarks.clear();
+ }
+
+ if(mxXChapterNumbering.is())
+ {
+ XIndexReplace* pCh = mxXChapterNumbering.get();
+ static_cast<SwXChapterNumbering*>(pCh)->Invalidate();
+ mxXChapterNumbering.clear();
+ }
+
+ if(mxXFootnoteSettings.is())
+ {
+ XPropertySet* pFntSet = mxXFootnoteSettings.get();
+ static_cast<SwXFootnoteProperties*>(pFntSet)->Invalidate();
+ mxXFootnoteSettings.clear();
+ }
+
+ if(mxXEndnoteSettings.is())
+ {
+ XPropertySet* pEndSet = mxXEndnoteSettings.get();
+ static_cast<SwXEndnoteProperties*>(pEndSet)->Invalidate();
+ mxXEndnoteSettings.clear();
+ }
+
+ if(mxXLineNumberingProperties.is())
+ {
+ XPropertySet* pLine = mxXLineNumberingProperties.get();
+ static_cast<SwXLineNumberingProperties*>(pLine)->Invalidate();
+ mxXLineNumberingProperties.clear();
+ }
+ if(mxXReferenceMarks.is())
+ {
+ XNameAccess* pMarks = mxXReferenceMarks.get();
+ static_cast<SwXReferenceMarks*>(pMarks)->Invalidate();
+ mxXReferenceMarks.clear();
+ }
+ if(mxLinkTargetSupplier.is())
+ {
+ XNameAccess* pAccess = mxLinkTargetSupplier.get();
+ static_cast<SwXLinkTargetSupplier*>(pAccess)->Invalidate();
+ mxLinkTargetSupplier.clear();
+ }
+ if(mxXRedlines.is())
+ {
+ XEnumerationAccess* pMarks = mxXRedlines.get();
+ static_cast<SwXRedlines*>(pMarks)->Invalidate();
+ mxXRedlines.clear();
+ }
+ if(mxPropertyHelper.is())
+ {
+ mxPropertyHelper->Invalidate();
+ mxPropertyHelper.clear();
+ }
+}
+
+css::uno::Reference<css::uno::XInterface> SwXTextDocument::create(
+ OUString const & rServiceName,
+ css::uno::Sequence<css::uno::Any> const * arguments)
+{
+ SolarMutexGuard aGuard;
+ if (!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+
+ const SwServiceType nType = SwXServiceProvider::GetProviderType(rServiceName);
+ if (nType != SwServiceType::Invalid)
+ {
+ return SwXServiceProvider::MakeInstance(nType, *m_pDocShell->GetDoc());
+ }
+ if (rServiceName == "com.sun.star.drawing.DashTable")
+ {
+ return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Dash);
+ }
+ if (rServiceName == "com.sun.star.drawing.GradientTable")
+ {
+ return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Gradient);
+ }
+ if (rServiceName == "com.sun.star.drawing.HatchTable")
+ {
+ return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Hatch);
+ }
+ if (rServiceName == "com.sun.star.drawing.BitmapTable")
+ {
+ return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Bitmap);
+ }
+ if (rServiceName == "com.sun.star.drawing.TransparencyGradientTable")
+ {
+ return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::TransGradient);
+ }
+ if (rServiceName == "com.sun.star.drawing.MarkerTable")
+ {
+ return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Marker);
+ }
+ if (rServiceName == "com.sun.star.drawing.Defaults")
+ {
+ return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Defaults);
+ }
+ if (rServiceName == "com.sun.star.document.Settings")
+ {
+ return Reference<XInterface>(*new SwXDocumentSettings(this));
+ }
+ if (rServiceName == "com.sun.star.document.ImportEmbeddedObjectResolver")
+ {
+ return static_cast<cppu::OWeakObject *>(
+ new SvXMLEmbeddedObjectHelper(
+ *m_pDocShell, SvXMLEmbeddedObjectHelperMode::Read));
+ }
+ if (rServiceName == "com.sun.star.text.DocumentSettings")
+ {
+ return Reference<XInterface>(*new SwXDocumentSettings(this));
+ }
+ if (rServiceName == "com.sun.star.chart2.data.DataProvider")
+ {
+ return Reference<XInterface>(
+ static_cast<chart2::data::XDataProvider *>(
+ m_pDocShell->getIDocumentChartDataProviderAccess().
+ GetChartDataProvider()));
+ }
+ if (!rServiceName.startsWith("com.sun.star.")
+ || rServiceName.endsWith(".OLE2Shape"))
+ {
+ // We do not want to insert OLE2 Shapes (e.g.,
+ // "com.sun.star.drawing.OLE2Shape", ...) like this (by creating them
+ // with the documents factory and adding the shapes to the draw page);
+ // for inserting OLE objects the proper way is to use
+ // "com.sun.star.text.TextEmbeddedObject":
+ throw ServiceNotRegisteredException();
+ }
+ // The XML import is allowed to create instances of
+ // "com.sun.star.drawing.OLE2Shape"; thus, a temporary service name is
+ // introduced to make this possible:
+ OUString aTmpServiceName(rServiceName);
+ if (rServiceName == "com.sun.star.drawing.temporaryForXMLImportOLE2Shape")
+ {
+ aTmpServiceName = "com.sun.star.drawing.OLE2Shape";
+ }
+ Reference<XInterface> xTmp(
+ arguments == nullptr
+ ? SvxFmMSFactory::createInstance(aTmpServiceName)
+ : SvxFmMSFactory::createInstanceWithArguments(
+ aTmpServiceName, *arguments));
+ if (rServiceName == "com.sun.star.drawing.GroupShape"
+ || rServiceName == "com.sun.star.drawing.Shape3DSceneObject")
+ {
+ return *new SwXGroupShape(xTmp, m_pDocShell->GetDoc());
+ }
+ if (rServiceName.startsWith("com.sun.star.drawing."))
+ {
+ return *new SwXShape(xTmp, m_pDocShell->GetDoc());
+ }
+ return xTmp;
+}
+
+Reference< XInterface > SwXTextDocument::createInstance(const OUString& rServiceName)
+{
+ return create(rServiceName, nullptr);
+}
+
+Reference< XInterface > SwXTextDocument::createInstanceWithArguments(
+ const OUString& ServiceSpecifier,
+ const Sequence< Any >& Arguments)
+{
+ return create(ServiceSpecifier, &Arguments);
+}
+
+Sequence< OUString > SwXTextDocument::getAvailableServiceNames()
+{
+ static Sequence< OUString > aServices;
+ if ( !aServices.hasElements() )
+ {
+ Sequence< OUString > aRet = SvxFmMSFactory::getAvailableServiceNames();
+ auto i = comphelper::findValue(aRet, "com.sun.star.drawing.OLE2Shape");
+ if (i != -1)
+ {
+ auto nLength = aRet.getLength();
+ aRet.getArray()[i] = aRet[nLength - 1];
+ aRet.realloc( nLength - 1 );
+ }
+ Sequence< OUString > aOwn = SwXServiceProvider::GetAllServiceNames();
+ aServices = comphelper::concatSequences(aRet, aOwn);
+ }
+
+ return aServices;
+}
+
+OUString SwXTextDocument::getImplementationName()
+{
+ return "SwXTextDocument";
+ /* // Matching the .component information:
+ return dynamic_cast<SwGlobalDocShell*>( pDocShell ) != nullptr
+ ? OUString("com.sun.star.comp.Writer.GlobalDocument")
+ : dynamic_cast<SwWebDocShell*>( pDocShell ) != nullptr
+ ? OUString("com.sun.star.comp.Writer.WebDocument")
+ : OUString("com.sun.star.comp.Writer.TextDocument");
+ */
+}
+
+sal_Bool SwXTextDocument::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXTextDocument::getSupportedServiceNames()
+{
+ bool bWebDoc = (dynamic_cast<SwWebDocShell*>( m_pDocShell) != nullptr );
+ bool bGlobalDoc = (dynamic_cast<SwGlobalDocShell*>( m_pDocShell) != nullptr );
+ bool bTextDoc = (!bWebDoc && !bGlobalDoc);
+
+ Sequence< OUString > aRet (3);
+ OUString* pArray = aRet.getArray();
+
+ pArray[0] = "com.sun.star.document.OfficeDocument";
+ pArray[1] = "com.sun.star.text.GenericTextDocument";
+
+ if (bTextDoc)
+ pArray[2] = "com.sun.star.text.TextDocument";
+ else if (bWebDoc)
+ pArray[2] = "com.sun.star.text.WebDocument";
+ else if (bGlobalDoc)
+ pArray[2] = "com.sun.star.text.GlobalDocument";
+
+ return aRet;
+}
+
+Reference< XIndexAccess > SwXTextDocument::getDocumentIndexes()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+
+ if(!mxXDocumentIndexes.is())
+ {
+ mxXDocumentIndexes = new SwXDocumentIndexes(m_pDocShell->GetDoc());
+ }
+ return mxXDocumentIndexes;
+}
+
+Reference< XPropertySetInfo > SwXTextDocument::getPropertySetInfo()
+{
+ static Reference< XPropertySetInfo > xRet = m_pPropSet->getPropertySetInfo();
+ return xRet;
+}
+
+void SwXTextDocument::setPropertyValue(const OUString& rPropertyName, const Any& aValue)
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName);
+
+ if(!pEntry)
+ throw UnknownPropertyException(rPropertyName);
+ if(pEntry->nFlags & PropertyAttribute::READONLY)
+ throw PropertyVetoException();
+ switch(pEntry->nWID)
+ {
+ case WID_DOC_CHAR_COUNT :
+ case WID_DOC_PARA_COUNT :
+ case WID_DOC_WORD_COUNT :
+ throw RuntimeException(
+ "bad WID",
+ static_cast< cppu::OWeakObject * >(
+ static_cast< SwXTextDocumentBaseClass * >(this)));
+ case WID_DOC_WORD_SEPARATOR :
+ {
+ OUString sDelim;
+ aValue >>= sDelim;
+ SW_MOD()->GetModuleConfig()->SetWordDelimiter(sDelim);
+ }
+ break;
+ case WID_DOC_CHANGES_RECORD:
+ case WID_DOC_CHANGES_SHOW:
+ {
+ bool bSet = *o3tl::doAccess<bool>(aValue);
+ RedlineFlags eMode = m_pDocShell->GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags();
+ if(WID_DOC_CHANGES_SHOW == pEntry->nWID)
+ {
+ eMode |= RedlineFlags(RedlineFlags::ShowInsert | RedlineFlags::ShowDelete);
+ if( !bSet )
+ m_pDocShell->GetDoc()->GetDocumentRedlineManager().SetHideRedlines(true);
+ }
+ else if(WID_DOC_CHANGES_RECORD == pEntry->nWID)
+ {
+ eMode = bSet ? eMode|RedlineFlags::On : eMode&~RedlineFlags::On;
+ }
+ m_pDocShell->GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags( eMode );
+ }
+ break;
+ case WID_DOC_CHANGES_PASSWORD:
+ {
+ Sequence <sal_Int8> aNew;
+ if(aValue >>= aNew)
+ {
+ SwDoc* pDoc = m_pDocShell->GetDoc();
+ pDoc->getIDocumentRedlineAccess().SetRedlinePassword(aNew);
+ if(aNew.hasElements())
+ {
+ RedlineFlags eMode = pDoc->getIDocumentRedlineAccess().GetRedlineFlags();
+ eMode |= RedlineFlags::On;
+ pDoc->getIDocumentRedlineAccess().SetRedlineFlags( eMode );
+ }
+ }
+ }
+ break;
+ case WID_DOC_AUTO_MARK_URL :
+ {
+ OUString sURL;
+ aValue >>= sURL;
+ m_pDocShell->GetDoc()->SetTOIAutoMarkURL(sURL);
+ }
+ break;
+ case WID_DOC_HIDE_TIPS :
+ SW_MOD()->GetModuleConfig()->SetHideFieldTips(*o3tl::doAccess<bool>(aValue));
+ break;
+ case WID_DOC_REDLINE_DISPLAY:
+ {
+ RedlineFlags eRedMode = m_pDocShell->GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags();
+ eRedMode = eRedMode & (~RedlineFlags::ShowMask);
+ sal_Int16 nSet = 0;
+ aValue >>= nSet;
+ switch(nSet)
+ {
+ case RedlineDisplayType::NONE: break;
+ case RedlineDisplayType::INSERTED: eRedMode |= RedlineFlags::ShowInsert; break;
+ case RedlineDisplayType::REMOVED: eRedMode |= RedlineFlags::ShowDelete; break;
+ case RedlineDisplayType::
+ INSERTED_AND_REMOVED: eRedMode |= RedlineFlags::ShowInsert|RedlineFlags::ShowDelete;
+ break;
+ default: throw IllegalArgumentException();
+ }
+ m_pDocShell->GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags(eRedMode);
+ }
+ break;
+ case WID_DOC_TWO_DIGIT_YEAR:
+ {
+ sal_Int16 nYear = 0;
+ aValue >>= nYear;
+ SfxRequest aRequest ( SID_ATTR_YEAR2000, SfxCallMode::SLOT, m_pDocShell->GetDoc()->GetAttrPool());
+ aRequest.AppendItem(SfxUInt16Item( SID_ATTR_YEAR2000, static_cast < sal_uInt16 > ( nYear ) ) );
+ m_pDocShell->Execute ( aRequest );
+ }
+ break;
+ case WID_DOC_AUTOMATIC_CONTROL_FOCUS:
+ {
+ SwDrawModel * pDrawDoc = m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
+ bool bAuto = *o3tl::doAccess<bool>(aValue);
+
+ if ( nullptr != pDrawDoc )
+ pDrawDoc->SetAutoControlFocus( bAuto );
+ else if (bAuto)
+ {
+ // if setting to true, and we don't have an
+ // SdrModel, then we are changing the default and
+ // must thus create an SdrModel, if we don't have an
+ // SdrModel and we are leaving the default at false,
+ // we don't need to make an SdrModel and can do nothing
+ // #i52858# - method name changed
+ pDrawDoc = m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetOrCreateDrawModel();
+ pDrawDoc->SetAutoControlFocus ( bAuto );
+ }
+ }
+ break;
+ case WID_DOC_APPLY_FORM_DESIGN_MODE:
+ {
+ SwDrawModel * pDrawDoc = m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
+ bool bMode = *o3tl::doAccess<bool>(aValue);
+
+ if ( nullptr != pDrawDoc )
+ pDrawDoc->SetOpenInDesignMode( bMode );
+ else if (!bMode)
+ {
+ // if setting to false, and we don't have an
+ // SdrModel, then we are changing the default and
+ // must thus create an SdrModel, if we don't have an
+ // SdrModel and we are leaving the default at true,
+ // we don't need to make an SdrModel and can do
+ // nothing
+ // #i52858# - method name changed
+ pDrawDoc = m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetOrCreateDrawModel();
+ pDrawDoc->SetOpenInDesignMode ( bMode );
+ }
+ }
+ break;
+ // #i42634# New property to set the bInReading
+ // flag at the document, used during binary import
+ case WID_DOC_LOCK_UPDATES :
+ {
+ SwDoc* pDoc = m_pDocShell->GetDoc();
+ bool bBool (false);
+ if( aValue >>= bBool )
+ {
+ pDoc->SetInReading( bBool );
+ }
+ }
+ break;
+ case WID_DOC_WRITERFILTER:
+ {
+ SwDoc* pDoc = m_pDocShell->GetDoc();
+ bool bBool = {};
+ if (aValue >>= bBool)
+ { // HACK: writerfilter has to use API to set this :(
+ bool bOld = pDoc->IsInWriterfilterImport();
+ pDoc->SetInWriterfilterImport(bBool);
+ if (bOld && !bBool)
+ {
+ pDoc->getIDocumentFieldsAccess().SetFieldsDirty(false, nullptr, SwNodeOffset(0));
+ }
+ }
+ }
+ break;
+ case WID_DOC_BUILDID:
+ aValue >>= maBuildId;
+ break;
+
+ case WID_DOC_DEFAULT_PAGE_MODE:
+ {
+ bool bDefaultPageMode( false );
+ aValue >>= bDefaultPageMode;
+ m_pDocShell->GetDoc()->SetDefaultPageMode( bDefaultPageMode );
+ }
+ break;
+ case WID_DOC_INTEROP_GRAB_BAG:
+ setGrabBagItem(aValue);
+ break;
+
+ default:
+ {
+ const SfxPoolItem& rItem = m_pDocShell->GetDoc()->GetDefault(pEntry->nWID);
+ std::unique_ptr<SfxPoolItem> pNewItem(rItem.Clone());
+ pNewItem->PutValue(aValue, pEntry->nMemberId);
+ m_pDocShell->GetDoc()->SetDefault(*pNewItem);
+ }
+ }
+}
+
+Any SwXTextDocument::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName);
+
+ if(!pEntry)
+ throw UnknownPropertyException(rPropertyName);
+ Any aAny;
+ switch(pEntry->nWID)
+ {
+ case WID_DOC_ISTEMPLATEID :
+ aAny <<= m_pDocShell->IsTemplate();
+ break;
+ case WID_DOC_CHAR_COUNT :
+ case WID_DOC_PARA_COUNT :
+ case WID_DOC_WORD_COUNT :
+ {
+ const SwDocStat& rStat(m_pDocShell->GetDoc()->getIDocumentStatistics().GetUpdatedDocStat( false, true ));
+ sal_Int32 nValue;
+ switch(pEntry->nWID)
+ {
+ case WID_DOC_CHAR_COUNT :nValue = rStat.nChar;break;
+ case WID_DOC_PARA_COUNT :nValue = rStat.nPara;break;
+ case WID_DOC_WORD_COUNT :nValue = rStat.nWord;break;
+ }
+ aAny <<= nValue;
+ }
+ break;
+ case WID_DOC_WORD_SEPARATOR :
+ {
+ aAny <<= SW_MOD()->GetDocStatWordDelim();
+ }
+ break;
+ case WID_DOC_CHANGES_RECORD:
+ case WID_DOC_CHANGES_SHOW:
+ {
+ const RedlineFlags eMode = m_pDocShell->GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags();
+ bool bSet = false;
+ if(WID_DOC_CHANGES_SHOW == pEntry->nWID)
+ {
+ bSet = IDocumentRedlineAccess::IsShowChanges(eMode);
+ }
+ else if(WID_DOC_CHANGES_RECORD == pEntry->nWID)
+ {
+ bSet = bool(eMode & RedlineFlags::On);
+ }
+ aAny <<= bSet;
+ }
+ break;
+ case WID_DOC_CHANGES_PASSWORD:
+ {
+ SwDoc* pDoc = m_pDocShell->GetDoc();
+ aAny <<= pDoc->getIDocumentRedlineAccess().GetRedlinePassword();
+ }
+ break;
+ case WID_DOC_AUTO_MARK_URL :
+ aAny <<= m_pDocShell->GetDoc()->GetTOIAutoMarkURL();
+ break;
+ case WID_DOC_HIDE_TIPS :
+ aAny <<= SW_MOD()->GetModuleConfig()->IsHideFieldTips();
+ break;
+ case WID_DOC_REDLINE_DISPLAY:
+ {
+ RedlineFlags eRedMode = m_pDocShell->GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags();
+ eRedMode = eRedMode & RedlineFlags::ShowMask;
+ sal_Int16 nRet = RedlineDisplayType::NONE;
+ if(RedlineFlags::ShowInsert == eRedMode)
+ nRet = RedlineDisplayType::INSERTED;
+ else if(RedlineFlags::ShowDelete == eRedMode)
+ nRet = RedlineDisplayType::REMOVED;
+ else if(RedlineFlags::ShowMask == eRedMode)
+ nRet = RedlineDisplayType::INSERTED_AND_REMOVED;
+ aAny <<= nRet;
+ }
+ break;
+ case WID_DOC_FORBIDDEN_CHARS:
+ {
+ GetPropertyHelper();
+ Reference<XForbiddenCharacters> xRet = mxPropertyHelper;
+ aAny <<= xRet;
+ }
+ break;
+ case WID_DOC_TWO_DIGIT_YEAR:
+ {
+ aAny <<= static_cast < sal_Int16 > (m_pDocShell->GetDoc()->GetNumberFormatter ()->GetYear2000());
+ }
+ break;
+ case WID_DOC_AUTOMATIC_CONTROL_FOCUS:
+ {
+ SwDrawModel * pDrawDoc = m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
+ bool bAuto;
+ if ( nullptr != pDrawDoc )
+ bAuto = pDrawDoc->GetAutoControlFocus();
+ else
+ bAuto = false;
+ aAny <<= bAuto;
+ }
+ break;
+ case WID_DOC_APPLY_FORM_DESIGN_MODE:
+ {
+ SwDrawModel * pDrawDoc = m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
+ bool bMode;
+ if ( nullptr != pDrawDoc )
+ bMode = pDrawDoc->GetOpenInDesignMode();
+ else
+ bMode = true;
+ aAny <<= bMode;
+ }
+ break;
+ case WID_DOC_BASIC_LIBRARIES:
+ aAny <<= m_pDocShell->GetBasicContainer();
+ break;
+ case WID_DOC_DIALOG_LIBRARIES:
+ aAny <<= m_pDocShell->GetDialogContainer();
+ break;
+ case WID_DOC_VBA_DOCOBJ:
+ {
+ /* #i111553# This property provides the name of the constant that
+ will be used to store this model in the global Basic manager.
+ That constant will be equivalent to 'ThisComponent' but for
+ each application, so e.g. a 'ThisExcelDoc' and a 'ThisWordDoc'
+ constant can co-exist, as required by VBA. */
+ aAny <<= OUString( "ThisWordDoc" );
+ }
+ break;
+ case WID_DOC_RUNTIME_UID:
+ aAny <<= getRuntimeUID();
+ break;
+ case WID_DOC_LOCK_UPDATES :
+ aAny <<= m_pDocShell->GetDoc()->IsInReading();
+ break;
+ case WID_DOC_BUILDID:
+ aAny <<= maBuildId;
+ break;
+ case WID_DOC_HAS_VALID_SIGNATURES:
+ aAny <<= hasValidSignatures();
+ break;
+ case WID_DOC_INTEROP_GRAB_BAG:
+ getGrabBagItem(aAny);
+ break;
+
+ default:
+ {
+ const SfxPoolItem& rItem = m_pDocShell->GetDoc()->GetDefault(pEntry->nWID);
+ rItem.QueryValue(aAny, pEntry->nMemberId);
+ }
+ }
+ return aAny;
+}
+
+void SwXTextDocument::addPropertyChangeListener(const OUString& /*PropertyName*/,
+ const Reference< XPropertyChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXTextDocument::removePropertyChangeListener(const OUString& /*PropertyName*/,
+ const Reference< XPropertyChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXTextDocument::addVetoableChangeListener(const OUString& /*PropertyName*/,
+ const Reference< XVetoableChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXTextDocument::removeVetoableChangeListener(const OUString& /*PropertyName*/,
+ const Reference< XVetoableChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+Reference< XNameAccess > SwXTextDocument::getLinks()
+{
+ if(!mxLinkTargetSupplier.is())
+ {
+ mxLinkTargetSupplier = new SwXLinkTargetSupplier(*this);
+ }
+ return mxLinkTargetSupplier;
+}
+
+Reference< XEnumerationAccess > SwXTextDocument::getRedlines( )
+{
+ if(!mxXRedlines.is())
+ {
+ mxXRedlines = new SwXRedlines(m_pDocShell->GetDoc());
+ }
+ return mxXRedlines;
+}
+
+void SwXTextDocument::NotifyRefreshListeners()
+{
+ // why does SwBaseShell not just call refresh? maybe because it's rSh is
+ // (sometimes) a different shell than GetWrtShell()?
+ lang::EventObject const ev(static_cast<SwXTextDocumentBaseClass &>(*this));
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_RefreshListeners.notifyEach(aGuard,
+ & util::XRefreshListener::refreshed, ev);
+}
+
+void SwXTextDocument::refresh()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+
+ SwViewShell *pViewShell = m_pDocShell->GetWrtShell();
+ NotifyRefreshListeners();
+ if(pViewShell)
+ pViewShell->Reformat();
+}
+
+void SAL_CALL SwXTextDocument::addRefreshListener(
+ const Reference<util::XRefreshListener> & xListener)
+{
+ if (xListener)
+ {
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_RefreshListeners.addInterface(aGuard, xListener);
+ }
+}
+
+void SAL_CALL SwXTextDocument::removeRefreshListener(
+ const Reference<util::XRefreshListener> & xListener)
+{
+ if (xListener)
+ {
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_RefreshListeners.removeInterface(aGuard, xListener);
+ }
+}
+
+void SwXTextDocument::updateLinks( )
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+
+ SwDoc* pDoc = m_pDocShell->GetDoc();
+ sfx2::LinkManager& rLnkMan = pDoc->getIDocumentLinksAdministration().GetLinkManager();
+ if( !rLnkMan.GetLinks().empty() )
+ {
+ UnoActionContext aAction(pDoc);
+ rLnkMan.UpdateAllLinks( false, true, nullptr );
+ }
+}
+
+//XPropertyState
+PropertyState SAL_CALL SwXTextDocument::getPropertyState( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName);
+ if(!pEntry)
+ throw UnknownPropertyException(rPropertyName);
+ return PropertyState_DIRECT_VALUE;
+}
+
+Sequence< PropertyState > SAL_CALL SwXTextDocument::getPropertyStates( const Sequence< OUString >& rPropertyNames )
+{
+ const sal_Int32 nCount = rPropertyNames.getLength();
+ Sequence < PropertyState > aRet ( nCount );
+
+ std::transform(rPropertyNames.begin(), rPropertyNames.end(), aRet.getArray(),
+ [this](const OUString& rName) -> PropertyState { return getPropertyState(rName); });
+
+ return aRet;
+}
+
+void SAL_CALL SwXTextDocument::setPropertyToDefault( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName);
+ if(!pEntry)
+ throw UnknownPropertyException(rPropertyName);
+ switch(pEntry->nWID)
+ {
+ case 0:default:break;
+ }
+}
+
+Any SAL_CALL SwXTextDocument::getPropertyDefault( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName);
+ if(!pEntry)
+ throw UnknownPropertyException(rPropertyName);
+ Any aAny;
+ switch(pEntry->nWID)
+ {
+ case 0:default:break;
+ }
+ return aAny;
+}
+
+static VclPtr< OutputDevice > lcl_GetOutputDevice( const SwPrintUIOptions &rPrintUIOptions )
+{
+ VclPtr< OutputDevice > pOut;
+
+ uno::Any aAny( rPrintUIOptions.getValue( "RenderDevice" ));
+ uno::Reference< awt::XDevice > xRenderDevice;
+ aAny >>= xRenderDevice;
+ if (xRenderDevice.is())
+ {
+ VCLXDevice* pDevice = comphelper::getFromUnoTunnel<VCLXDevice>( xRenderDevice );
+ pOut = pDevice ? pDevice->GetOutputDevice() : VclPtr< OutputDevice >();
+ }
+
+ return pOut;
+}
+
+static bool lcl_SeqHasProperty(
+ const uno::Sequence< beans::PropertyValue >& rOptions,
+ const char *pPropName )
+{
+ return std::any_of(rOptions.begin(), rOptions.end(),
+ [&pPropName](const beans::PropertyValue& rProp) {
+ return rProp.Name.equalsAscii( pPropName ); });
+}
+
+static bool lcl_GetBoolProperty(
+ const uno::Sequence< beans::PropertyValue >& rOptions,
+ const char *pPropName )
+{
+ bool bRes = false;
+ auto pOption = std::find_if(rOptions.begin(), rOptions.end(),
+ [&pPropName](const beans::PropertyValue& rProp) {
+ return rProp.Name.equalsAscii( pPropName ); });
+ if (pOption != rOptions.end())
+ pOption->Value >>= bRes;
+ return bRes;
+}
+
+SfxViewShell * SwXTextDocument::GetRenderView(
+ bool &rbIsSwSrcView,
+ const uno::Sequence< beans::PropertyValue >& rOptions,
+ bool bIsPDFExport )
+{
+ // get view shell to use
+ SfxViewShell *pView = nullptr;
+ if (bIsPDFExport)
+ pView = GuessViewShell( rbIsSwSrcView );
+ else
+ {
+ uno::Any aTmp;
+ auto pOption = std::find_if(rOptions.begin(), rOptions.end(),
+ [](const beans::PropertyValue& rProp) { return rProp.Name == "View"; });
+ if (pOption != rOptions.end())
+ aTmp = pOption->Value;
+
+ uno::Reference< frame::XController > xController;
+ if (aTmp >>= xController)
+ {
+ OSL_ENSURE( xController.is(), "controller is empty!" );
+ pView = GuessViewShell( rbIsSwSrcView, xController );
+ }
+ }
+ return pView;
+}
+
+/*
+ * GetRenderDoc:
+ * returns the document to be rendered, usually this will be the 'regular'
+ * document but in case of PDF export of (multi-)selection it will
+ * be a temporary document that gets created if not already done.
+ * The rpView variable will be set (if not already done) to the used
+ * SfxViewShell.
+*/
+SwDoc * SwXTextDocument::GetRenderDoc(
+ SfxViewShell *&rpView,
+ const uno::Any& rSelection,
+ bool bIsPDFExport )
+{
+ SwDoc *pDoc = nullptr;
+
+ uno::Reference< frame::XModel > xModel;
+ rSelection >>= xModel;
+ if (xModel == m_pDocShell->GetModel())
+ pDoc = m_pDocShell->GetDoc();
+ else
+ {
+ OSL_ENSURE( !xModel.is(), "unexpected model found" );
+
+ if (rSelection.hasValue()) // is anything selected ?
+ {
+ // this part should only be called when a temporary document needs to be created,
+ // for example for PDF export or printing of (multi-)selection only.
+
+ if (!rpView)
+ {
+ bool bIsSwSrcView = false;
+ // aside from maybe PDF export the view should always have been provided!
+ OSL_ENSURE( bIsPDFExport, "view is missing, guessing one..." );
+
+ rpView = GuessViewShell( bIsSwSrcView );
+ }
+ OSL_ENSURE( rpView, "SwViewShell missing" );
+ // the view shell should be SwView for documents PDF export.
+ // for the page preview no selection should be possible
+ // (the export dialog does not allow for this option)
+ if (auto pSwView = dynamic_cast<SwView *>( rpView ))
+ {
+ if (!m_pRenderData)
+ {
+ OSL_FAIL("GetRenderDoc: no renderdata");
+ return nullptr;
+ }
+ SfxObjectShellLock xDocSh(m_pRenderData->GetTempDocShell());
+ if (!xDocSh.Is())
+ {
+ xDocSh = pSwView->CreateTmpSelectionDoc();
+ m_pRenderData->SetTempDocShell(xDocSh);
+ }
+ if (xDocSh.Is())
+ {
+ pDoc = static_cast<SwDocShell*>(&xDocSh)->GetDoc();
+ rpView = pDoc->GetDocShell()->GetView();
+ }
+ }
+ else
+ {
+ OSL_FAIL("unexpected SwViewShell" );
+ }
+ }
+ }
+ return pDoc;
+}
+
+static void lcl_SavePrintUIOptionsToDocumentPrintData(
+ SwDoc &rDoc,
+ const SwPrintUIOptions &rPrintUIOptions,
+ bool bIsPDFEXport )
+{
+ SwPrintData aDocPrintData( rDoc.getIDocumentDeviceAccess().getPrintData() );
+
+ aDocPrintData.SetPrintGraphic( rPrintUIOptions.IsPrintGraphics() );
+ aDocPrintData.SetPrintTable( true ); // for now it was decided that tables should always be printed
+ aDocPrintData.SetPrintDraw( rPrintUIOptions.IsPrintDrawings() );
+ aDocPrintData.SetPrintControl( rPrintUIOptions.IsPrintFormControls() );
+ aDocPrintData.SetPrintLeftPage( rPrintUIOptions.IsPrintLeftPages() );
+ aDocPrintData.SetPrintRightPage( rPrintUIOptions.IsPrintRightPages() );
+ aDocPrintData.SetPrintReverse( false ); /*handled by print dialog now*/
+ aDocPrintData.SetPaperFromSetup( rPrintUIOptions.IsPaperFromSetup() );
+ aDocPrintData.SetPrintEmptyPages( rPrintUIOptions.IsPrintEmptyPages( bIsPDFEXport ) );
+ aDocPrintData.SetPrintPostIts( rPrintUIOptions.GetPrintPostItsType() );
+ aDocPrintData.SetPrintProspect( rPrintUIOptions.IsPrintProspect() );
+ aDocPrintData.SetPrintProspect_RTL( rPrintUIOptions.IsPrintProspectRTL() );
+ aDocPrintData.SetPrintPageBackground( rPrintUIOptions.IsPrintPageBackground() );
+ aDocPrintData.SetPrintBlackFont( rPrintUIOptions.IsPrintWithBlackTextColor() );
+ // aDocPrintData.SetPrintSingleJobs( b ); handled by File/Print dialog itself
+ // arDocPrintData.SetFaxName( s ); n/a in File/Print dialog
+ aDocPrintData.SetPrintHiddenText( rPrintUIOptions.IsPrintHiddenText() );
+ aDocPrintData.SetPrintTextPlaceholder( rPrintUIOptions.IsPrintTextPlaceholders() );
+
+ rDoc.getIDocumentDeviceAccess().setPrintData( aDocPrintData );
+}
+
+sal_Int32 SAL_CALL SwXTextDocument::getRendererCount(
+ const uno::Any& rSelection,
+ const uno::Sequence< beans::PropertyValue >& rxOptions )
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ {
+ throw DisposedException( OUString(),
+ static_cast< XTextDocument* >(this) );
+ }
+
+ const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" );
+ bool bIsSwSrcView = false;
+ SfxViewShell *pView = GetRenderView( bIsSwSrcView, rxOptions, bIsPDFExport );
+
+ if (!bIsSwSrcView && !m_pRenderData)
+ m_pRenderData.reset(new SwRenderData);
+ if (!m_pPrintUIOptions)
+ m_pPrintUIOptions = lcl_GetPrintUIOptions( m_pDocShell, pView );
+ bool bFormat = m_pPrintUIOptions->processPropertiesAndCheckFormat( rxOptions );
+
+ SwDoc *pDoc = GetRenderDoc( pView, rSelection, bIsPDFExport );
+ OSL_ENSURE( pDoc && pView, "doc or view shell missing!" );
+ if (!pDoc || !pView)
+ return 0;
+
+ // save current UI options from the print dialog for the next call to that dialog
+ lcl_SavePrintUIOptionsToDocumentPrintData( *pDoc, *m_pPrintUIOptions, bIsPDFExport );
+
+ sal_Int32 nRet = 0;
+ if (bIsSwSrcView)
+ {
+ SwSrcView& rSwSrcView = dynamic_cast<SwSrcView&>(*pView);
+ VclPtr< OutputDevice> pOutDev = lcl_GetOutputDevice( *m_pPrintUIOptions );
+ nRet = rSwSrcView.PrintSource( pOutDev, 1 /* dummy */, true /* get page count only */ );
+ }
+ else
+ {
+ SwDocShell *pRenderDocShell = pDoc->GetDocShell();
+
+ // TODO/mba: we really need a generic way to get the SwViewShell!
+ SwViewShell* pViewShell = nullptr;
+ SwView* pSwView = dynamic_cast<SwView*>( pView );
+ if ( pSwView )
+ {
+ pViewShell = pSwView->GetWrtShellPtr();
+ }
+ else
+ {
+ if ( bIsPDFExport && bFormat )
+ {
+ //create a hidden view to be able to export as PDF also in print preview
+ //pView and pSwView are not changed intentionally!
+ m_pHiddenViewFrame = SfxViewFrame::LoadHiddenDocument( *pRenderDocShell, SFX_INTERFACE_SFXDOCSH );
+ pViewShell = static_cast<SwView*>(m_pHiddenViewFrame->GetViewShell())->GetWrtShellPtr();
+ }
+ else
+ pViewShell = static_cast<SwPagePreview*>(pView)->GetViewShell();
+ }
+
+ if (!pViewShell || !pViewShell->GetLayout())
+ return 0;
+
+ if (bFormat)
+ {
+ // #i38289
+ if( pViewShell->GetViewOptions()->getBrowseMode() ||
+ pViewShell->GetViewOptions()->IsWhitespaceHidden() )
+ {
+ SwViewOption aOpt( *pViewShell->GetViewOptions() );
+ aOpt.setBrowseMode( false );
+ aOpt.SetHideWhitespaceMode( false );
+ pViewShell->ApplyViewOptions( aOpt );
+ if (pSwView)
+ {
+ pSwView->RecheckBrowseMode();
+ }
+ }
+
+ // reformatting the document for printing will show the changes in the view
+ // which is likely to produce many unwanted and not nice to view actions.
+ // We don't want that! Thus we disable updating of the view.
+ pViewShell->StartAction();
+
+ if (pSwView)
+ {
+ if (m_pRenderData && m_pRenderData->NeedNewViewOptionAdjust( *pViewShell ) )
+ m_pRenderData->ViewOptionAdjustStop();
+ if (m_pRenderData && !m_pRenderData->IsViewOptionAdjust())
+ {
+ m_pRenderData->ViewOptionAdjustStart(
+ *pViewShell, *pViewShell->GetViewOptions() );
+ }
+ }
+
+ m_pRenderData->MakeSwPrtOptions( pRenderDocShell,
+ m_pPrintUIOptions.get(), bIsPDFExport );
+
+ if (pSwView)
+ {
+ // PDF export should not make use of the SwPrtOptions
+ const SwPrintData *pPrtOptions = bIsPDFExport
+ ? nullptr : m_pRenderData->GetSwPrtOptions();
+ bool setShowPlaceHoldersInPDF = false;
+ if(bIsPDFExport)
+ setShowPlaceHoldersInPDF = lcl_GetBoolProperty( rxOptions, "ExportPlaceholders" );
+ m_pRenderData->ViewOptionAdjust( pPrtOptions, setShowPlaceHoldersInPDF );
+ }
+
+ // since printing now also use the API for PDF export this option
+ // should be set for printing as well ...
+ pViewShell->SetPDFExportOption( true );
+
+ // there is some redundancy between those two function calls, but right now
+ // there is no time to sort this out.
+ //TODO: check what exactly needs to be done and make just one function for that
+ pViewShell->CalcLayout();
+
+ // #122919# Force field update before PDF export, but after layout init (tdf#121962)
+ bool bStateChanged = false;
+ // check configuration: shall update of printing information in DocInfo set the document to "modified"?
+ if (pRenderDocShell->IsEnableSetModified() && !officecfg::Office::Common::Print::PrintingModifiesDocument::get())
+ {
+ pRenderDocShell->EnableSetModified( false );
+ bStateChanged = true;
+ }
+ pViewShell->SwViewShell::UpdateFields(true);
+ if( bStateChanged )
+ pRenderDocShell->EnableSetModified();
+
+ pViewShell->CalcPagesForPrint( pViewShell->GetPageCount() );
+
+ pViewShell->SetPDFExportOption( false );
+
+ // enable view again
+ pViewShell->EndAction();
+ }
+
+ const sal_Int32 nPageCount = pViewShell->GetPageCount();
+
+ // get number of pages to be rendered
+
+ const bool bPrintProspect = m_pPrintUIOptions->getBoolValue( "PrintProspect" );
+ if (bPrintProspect)
+ {
+ SwDoc::CalculatePagePairsForProspectPrinting( *pViewShell->GetLayout(), *m_pRenderData, *m_pPrintUIOptions, nPageCount );
+ nRet = m_pRenderData->GetPagePairsForProspectPrinting().size();
+ }
+ else
+ {
+ const SwPostItMode nPostItMode = static_cast<SwPostItMode>( m_pPrintUIOptions->getIntValue( "PrintAnnotationMode", 0 ) );
+ if (nPostItMode != SwPostItMode::NONE)
+ {
+ VclPtr< OutputDevice > pOutDev = lcl_GetOutputDevice( *m_pPrintUIOptions );
+ m_pRenderData->CreatePostItData(*pDoc, pViewShell->GetViewOptions(), pOutDev);
+ }
+
+ // get set of valid document pages (according to the current settings)
+ // and their start frames
+ SwDoc::CalculatePagesForPrinting( *pViewShell->GetLayout(), *m_pRenderData, *m_pPrintUIOptions, bIsPDFExport, nPageCount );
+
+ if (nPostItMode != SwPostItMode::NONE)
+ {
+ SwDoc::UpdatePagesForPrintingWithPostItData( *m_pRenderData,
+ *m_pPrintUIOptions, nPageCount );
+ }
+
+ nRet = m_pRenderData->GetPagesToPrint().size();
+ }
+ }
+ OSL_ENSURE( nRet >= 0, "negative number of pages???" );
+ // tdf#144989 the layout is complete now - prevent DoIdleJobs() from
+ // messing it up, particulary SwDocUpdateField::MakeFieldList_() unhiding
+ // sections
+ pDoc->getIDocumentTimerAccess().BlockIdling();
+
+ return nRet;
+}
+
+uno::Sequence< beans::PropertyValue > SAL_CALL SwXTextDocument::getRenderer(
+ sal_Int32 nRenderer,
+ const uno::Any& rSelection,
+ const uno::Sequence< beans::PropertyValue >& rxOptions )
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ {
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+ }
+
+ const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" );
+ bool bIsSwSrcView = false;
+ SfxViewShell *pView = GetRenderView( bIsSwSrcView, rxOptions, bIsPDFExport );
+
+ // m_pRenderData should NOT be created here!
+ // That should only be done in getRendererCount. If this function is called before
+ // getRendererCount was called then the caller will probably just retrieve the extra UI options
+ // and is not interested in getting valid information about the other data that would
+ // otherwise be provided here!
+// if( ! m_pRenderData )
+// m_pRenderData = new SwRenderData;
+ if (!m_pPrintUIOptions)
+ m_pPrintUIOptions = lcl_GetPrintUIOptions( m_pDocShell, pView );
+ m_pPrintUIOptions->processProperties( rxOptions );
+ const bool bPrintProspect = m_pPrintUIOptions->getBoolValue( "PrintProspect" );
+ const bool bIsSkipEmptyPages = !m_pPrintUIOptions->IsPrintEmptyPages( bIsPDFExport );
+ const bool bPrintPaperFromSetup = m_pPrintUIOptions->getBoolValue( "PrintPaperFromSetup" );
+
+ SwDoc *pDoc = GetRenderDoc( pView, rSelection, bIsPDFExport );
+ OSL_ENSURE( pDoc && pView, "doc or view shell missing!" );
+ if (!pDoc || !pView)
+ return uno::Sequence< beans::PropertyValue >();
+
+ // due to #110067# (document page count changes sometimes during
+ // PDF export/printing) we can not check for the upper bound properly.
+ // Thus instead of throwing the exception we silently return.
+ if (0 > nRenderer)
+ throw IllegalArgumentException();
+
+ // TODO/mba: we really need a generic way to get the SwViewShell!
+ SwViewShell* pVwSh = nullptr;
+ SwView* pSwView = dynamic_cast<SwView*>( pView );
+ if ( pSwView )
+ pVwSh = pSwView->GetWrtShellPtr();
+ else
+ pVwSh = static_cast<SwPagePreview*>(pView)->GetViewShell();
+
+ sal_Int32 nMaxRenderer = 0;
+ if (!bIsSwSrcView && m_pRenderData)
+ {
+ OSL_ENSURE( m_pRenderData, "m_pRenderData missing!!" );
+ nMaxRenderer = bPrintProspect?
+ m_pRenderData->GetPagePairsForProspectPrinting().size() - 1 :
+ m_pRenderData->GetPagesToPrint().size() - 1;
+ }
+ // since SwSrcView::PrintSource is a poor implementation to get the number of pages to print
+ // we obmit checking of the upper bound in this case.
+ if (!bIsSwSrcView && m_pRenderData && nRenderer > nMaxRenderer)
+ return uno::Sequence< beans::PropertyValue >();
+
+ uno::Sequence< beans::PropertyValue > aRenderer;
+ if (m_pRenderData)
+ {
+ // #i114210#
+ // determine the correct page number from the renderer index
+ // #i114875
+ // consider brochure print
+ const sal_Int32 nPage = bPrintProspect
+ ? nRenderer + 1
+ : m_pRenderData->GetPagesToPrint()[ nRenderer ];
+
+ // get paper tray to use ...
+ sal_Int32 nPrinterPaperTray = -1;
+ if (! bPrintPaperFromSetup)
+ {
+ // ... from individual page style (see the page tab in Format/Page dialog)
+ const std::map< sal_Int32, sal_Int32 > &rPaperTrays = m_pRenderData->GetPrinterPaperTrays();
+ std::map< sal_Int32, sal_Int32 >::const_iterator aIt( rPaperTrays.find( nPage ) );
+ if (aIt != rPaperTrays.end())
+ nPrinterPaperTray = aIt->second;
+ }
+
+ awt::Size aPageSize;
+ awt::Point aPagePos;
+ awt::Size aPreferredPageSize;
+ Size aTmpSize;
+ if (bIsSwSrcView || bPrintProspect)
+ {
+ // for printing of HTML source code and prospect printing we should use
+ // the printers paper size since
+ // a) HTML source view has no page size
+ // b) prospect printing has a different page size from the documents page
+ // since two document pages will get rendered on one printer page
+
+ // since PageIncludesNonprintableArea will be set to true we can return the
+ // printers paper size here.
+ // Sometimes 'getRenderer' is only called to get "ExtraPrintUIOptions", in this
+ // case we won't get an OutputDevice here, but then the caller also has no need
+ // for the correct PageSize right now...
+ VclPtr< Printer > pPrinter = dynamic_cast< Printer * >(lcl_GetOutputDevice( *m_pPrintUIOptions ).get());
+ if (pPrinter)
+ {
+ // HTML source view and prospect adapt to the printer's paper size
+ aTmpSize = pPrinter->GetPaperSize();
+ aTmpSize = OutputDevice::LogicToLogic( aTmpSize,
+ pPrinter->GetMapMode(), MapMode( MapUnit::Map100thMM ));
+ aPageSize = awt::Size( aTmpSize.Width(), aTmpSize.Height() );
+ #if 0
+ // #i115048# it seems users didn't like getting double the formatted page size
+ // revert to "old" behavior scaling to the current paper size of the printer
+ if (bPrintProspect)
+ {
+ // we just state what output size we would need
+ // which may cause vcl to set that page size on the printer
+ // (if available and not overridden by the user)
+ aTmpSize = pVwSh->GetPageSize( nPage, bIsSkipEmptyPages );
+ aPreferredPageSize = awt::Size ( convertTwipToMm100( 2 * aTmpSize.Width() ),
+ convertTwipToMm100( aTmpSize.Height() ));
+ }
+ #else
+ if( bPrintProspect )
+ {
+ // just switch to an appropriate portrait/landscape format
+ // FIXME: brochure printing with landscape pages puts the
+ // pages next to each other, so landscape is currently always
+ // the better choice
+ if( aPageSize.Width < aPageSize.Height )
+ {
+ aPreferredPageSize.Width = aPageSize.Height;
+ aPreferredPageSize.Height = aPageSize.Width;
+ }
+ }
+ #endif
+ }
+ }
+ else
+ {
+ aTmpSize = pVwSh->GetPageSize( nPage, bIsSkipEmptyPages );
+ aPageSize = awt::Size ( convertTwipToMm100( aTmpSize.Width() ),
+ convertTwipToMm100( aTmpSize.Height() ));
+ Point aPoint = pVwSh->GetPagePos(nPage);
+ aPagePos = awt::Point(convertTwipToMm100(aPoint.X()), convertTwipToMm100(aPoint.Y()));
+ }
+
+ sal_Int32 nLen = 3;
+ aRenderer = { comphelper::makePropertyValue("PageSize", aPageSize),
+ comphelper::makePropertyValue("PageIncludesNonprintableArea", true),
+ comphelper::makePropertyValue("PagePos", aPagePos) };
+ if (aPreferredPageSize.Width && aPreferredPageSize.Height)
+ {
+ ++nLen;
+ aRenderer.realloc( nLen );
+ auto pRenderer = aRenderer.getArray();
+ pRenderer[ nLen - 1 ].Name = "PreferredPageSize";
+ pRenderer[ nLen - 1 ].Value <<= aPreferredPageSize;
+ }
+ if (nPrinterPaperTray >= 0)
+ {
+ ++nLen;
+ aRenderer.realloc( nLen );
+ auto pRenderer = aRenderer.getArray();
+ pRenderer[ nLen - 1 ].Name = "PrinterPaperTray";
+ pRenderer[ nLen - 1 ].Value <<= nPrinterPaperTray;
+ }
+ }
+
+ // #i117783#
+ if ( m_bApplyPagePrintSettingsFromXPagePrintable )
+ {
+ const SwPagePreviewPrtData* pPagePrintSettings =
+ m_pDocShell->GetDoc()->GetPreviewPrtData();
+ if ( pPagePrintSettings &&
+ ( pPagePrintSettings->GetRow() > 1 ||
+ pPagePrintSettings->GetCol() > 1 ) )
+ {
+ // extend render data by page print settings attributes
+ sal_Int32 nLen = aRenderer.getLength();
+ const sal_Int32 nRenderDataIdxStart = nLen;
+ nLen += 9;
+ aRenderer.realloc( nLen );
+ auto pRenderer = aRenderer.getArray();
+ // put page print settings attribute into render data
+ const sal_Int32 nRow = pPagePrintSettings->GetRow();
+ pRenderer[ nRenderDataIdxStart + 0 ].Name = "NUpRows";
+ pRenderer[ nRenderDataIdxStart + 0 ].Value <<= std::max<sal_Int32>( nRow, 1);
+ const sal_Int32 nCol = pPagePrintSettings->GetCol();
+ pRenderer[ nRenderDataIdxStart + 1 ].Name = "NUpColumns";
+ pRenderer[ nRenderDataIdxStart + 1 ].Value <<= std::max<sal_Int32>( nCol, 1);
+ pRenderer[ nRenderDataIdxStart + 2 ].Name = "NUpPageMarginLeft";
+ pRenderer[ nRenderDataIdxStart + 2 ].Value <<= pPagePrintSettings->GetLeftSpace();
+ pRenderer[ nRenderDataIdxStart + 3 ].Name = "NUpPageMarginRight";
+ pRenderer[ nRenderDataIdxStart + 3 ].Value <<= pPagePrintSettings->GetRightSpace();
+ pRenderer[ nRenderDataIdxStart + 4 ].Name = "NUpPageMarginTop";
+ pRenderer[ nRenderDataIdxStart + 4 ].Value <<= pPagePrintSettings->GetTopSpace();
+ pRenderer[ nRenderDataIdxStart + 5 ].Name = "NUpPageMarginBottom";
+ pRenderer[ nRenderDataIdxStart + 5 ].Value <<= pPagePrintSettings->GetBottomSpace();
+ pRenderer[ nRenderDataIdxStart + 6 ].Name = "NUpHorizontalSpacing";
+ pRenderer[ nRenderDataIdxStart + 6 ].Value <<= pPagePrintSettings->GetHorzSpace();
+ pRenderer[ nRenderDataIdxStart + 7 ].Name = "NUpVerticalSpacing";
+ pRenderer[ nRenderDataIdxStart + 7 ].Value <<= pPagePrintSettings->GetVertSpace();
+ {
+ Printer* pPrinter = m_pDocShell->GetDoc()->getIDocumentDeviceAccess().getPrinter( false );
+ if ( pPrinter )
+ {
+ awt::Size aNewPageSize;
+ const Size aPageSize = pPrinter->PixelToLogic( pPrinter->GetPaperSizePixel(), MapMode( MapUnit::Map100thMM ) );
+ aNewPageSize = awt::Size( aPageSize.Width(), aPageSize.Height() );
+ if ( ( pPagePrintSettings->GetLandscape() &&
+ aPageSize.Width() < aPageSize.Height() ) ||
+ ( !pPagePrintSettings->GetLandscape() &&
+ aPageSize.Width() > aPageSize.Height() ) )
+ {
+ aNewPageSize = awt::Size( aPageSize.Height(), aPageSize.Width() );
+ }
+ pRenderer[ nRenderDataIdxStart + 8 ].Name = "NUpPaperSize";
+ pRenderer[ nRenderDataIdxStart + 8 ].Value <<= aNewPageSize;
+ }
+ }
+ }
+
+ m_bApplyPagePrintSettingsFromXPagePrintable = false;
+ }
+
+ m_pPrintUIOptions->appendPrintUIOptions( aRenderer );
+
+ return aRenderer;
+}
+
+SfxViewShell * SwXTextDocument::GuessViewShell(
+ /* out */ bool &rbIsSwSrcView,
+ const uno::Reference< css::frame::XController >& rController )
+{
+ // #130810# SfxViewShell::Current() / SfxViewShell::GetObjectShell()
+ // must not be used (see comment from MBA)
+
+ SfxViewShell *pView = nullptr;
+ SwView *pSwView = nullptr;
+ SwPagePreview *pSwPagePreview = nullptr;
+ SwSrcView *pSwSrcView = nullptr;
+ SfxViewFrame *pFrame = SfxViewFrame::GetFirst( m_pDocShell, false );
+
+ // look for the view shell with the same controller in use,
+ // otherwise look for a suitable view, preferably a SwView,
+ // if that one is not found use a SwPagePreview if found.
+ while (pFrame)
+ {
+ pView = pFrame->GetViewShell();
+ pSwView = dynamic_cast< SwView * >(pView);
+ pSwSrcView = dynamic_cast< SwSrcView * >(pView);
+ if (!pSwPagePreview)
+ pSwPagePreview = dynamic_cast< SwPagePreview * >(pView);
+ if (rController.is())
+ {
+ if (pView && pView->GetController() == rController)
+ break;
+ }
+ else if (pSwView || pSwSrcView)
+ break;
+ pFrame = SfxViewFrame::GetNext( *pFrame, m_pDocShell, false );
+ }
+
+ OSL_ENSURE( pSwView || pSwPagePreview || pSwSrcView, "failed to get view shell" );
+ if (pView)
+ rbIsSwSrcView = pSwSrcView != nullptr;
+ return pView;
+}
+
+void SAL_CALL SwXTextDocument::render(
+ sal_Int32 nRenderer,
+ const uno::Any& rSelection,
+ const uno::Sequence< beans::PropertyValue >& rxOptions )
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ {
+ throw DisposedException( OUString(),
+ static_cast< XTextDocument* >(this) );
+ }
+
+ // due to #110067# (document page count changes sometimes during
+ // PDF export/printing) we can not check for the upper bound properly.
+ // Thus instead of throwing the exception we silently return.
+ if (0 > nRenderer)
+ throw IllegalArgumentException();
+
+ // tdf#135244: prevent jumping to cursor at any temporary modification
+ auto aLock = m_pDocShell->LockAllViews();
+
+ const bool bHasPDFExtOutDevData = lcl_SeqHasProperty( rxOptions, "HasPDFExtOutDevData" );
+ const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" ) || bHasPDFExtOutDevData;
+ bool bIsSwSrcView = false;
+ SfxViewShell *pView = GetRenderView( bIsSwSrcView, rxOptions, bIsPDFExport );
+
+ OSL_ENSURE( m_pRenderData, "data should have been created already in getRendererCount..." );
+ OSL_ENSURE( m_pPrintUIOptions, "data should have been created already in getRendererCount..." );
+ if (!bIsSwSrcView && !m_pRenderData)
+ m_pRenderData.reset(new SwRenderData);
+ if (!m_pPrintUIOptions)
+ m_pPrintUIOptions = lcl_GetPrintUIOptions( m_pDocShell, pView );
+ m_pPrintUIOptions->processProperties( rxOptions );
+ const bool bPrintProspect = m_pPrintUIOptions->getBoolValue( "PrintProspect" );
+ const bool bLastPage = m_pPrintUIOptions->getBoolValue( "IsLastPage" );
+
+ SwDoc *pDoc = GetRenderDoc( pView, rSelection, bIsPDFExport );
+ OSL_ENSURE( pDoc && pView, "doc or view shell missing!" );
+ if (pDoc && pView)
+ {
+ sal_Int32 nMaxRenderer = 0;
+ if (!bIsSwSrcView)
+ {
+ OSL_ENSURE( m_pRenderData, "m_pRenderData missing!!" );
+ nMaxRenderer = bPrintProspect?
+ m_pRenderData->GetPagePairsForProspectPrinting().size() - 1 :
+ m_pRenderData->GetPagesToPrint().size() - 1;
+ }
+ // since SwSrcView::PrintSource is a poor implementation to get the number of pages to print
+ // we obmit checking of the upper bound in this case.
+ if (bIsSwSrcView || nRenderer <= nMaxRenderer)
+ {
+ if (bIsSwSrcView)
+ {
+ SwSrcView& rSwSrcView = dynamic_cast<SwSrcView&>(*pView);
+ VclPtr< OutputDevice > pOutDev = lcl_GetOutputDevice( *m_pPrintUIOptions );
+ rSwSrcView.PrintSource(pOutDev, nRenderer + 1, false);
+ }
+ else
+ {
+ // the view shell should be SwView for documents PDF export
+ // or SwPagePreview for PDF export of the page preview
+ SwViewShell* pVwSh = nullptr;
+ // TODO/mba: we really need a generic way to get the SwViewShell!
+ const SwView* pSwView = dynamic_cast<const SwView*>(pView);
+ if (pSwView)
+ pVwSh = pSwView->GetWrtShellPtr();
+ else
+ pVwSh = static_cast<SwPagePreview*>(pView)->GetViewShell();
+
+ // get output device to use
+ VclPtr< OutputDevice > pOut = lcl_GetOutputDevice( *m_pPrintUIOptions );
+
+ if(pVwSh && pOut && m_pRenderData->HasSwPrtOptions())
+ {
+ const OUString aPageRange = m_pPrintUIOptions->getStringValue( "PageRange" );
+ const bool bFirstPage = m_pPrintUIOptions->getBoolValue( "IsFirstPage" );
+ bool bIsSkipEmptyPages = !m_pPrintUIOptions->IsPrintEmptyPages( bIsPDFExport );
+
+ OSL_ENSURE((pSwView && m_pRenderData->IsViewOptionAdjust())
+ || (!pSwView && !m_pRenderData->IsViewOptionAdjust()),
+ "SwView / SwViewOptionAdjust_Impl availability mismatch" );
+
+ // since printing now also use the API for PDF export this option
+ // should be set for printing as well ...
+ pVwSh->SetPDFExportOption( true );
+
+ // #i12836# enhanced pdf export
+
+ // First, we have to export hyperlinks, notes, and outline to pdf.
+ // During this process, additional information required for tagging
+ // the pdf file are collected, which are evaluated during painting.
+
+ SwWrtShell* pWrtShell = pSwView ? pSwView->GetWrtShellPtr() : nullptr;
+
+ SwPrintData const& rSwPrtOptions =
+ *m_pRenderData->GetSwPrtOptions();
+
+ if (bIsPDFExport && (bFirstPage || bHasPDFExtOutDevData) && pWrtShell)
+ {
+ SwEnhancedPDFExportHelper aHelper( *pWrtShell, *pOut, aPageRange, bIsSkipEmptyPages, false, rSwPrtOptions );
+ }
+
+ if (bPrintProspect)
+ pVwSh->PrintProspect( pOut, rSwPrtOptions, nRenderer );
+ else // normal printing and PDF export
+ pVwSh->PrintOrPDFExport( pOut, rSwPrtOptions, nRenderer, bIsPDFExport );
+
+ // #i35176#
+
+ // After printing the last page, we take care for the links coming
+ // from the EditEngine. The links are generated during the painting
+ // process, but the destinations are still missing.
+
+ if (bIsPDFExport && bLastPage && pWrtShell)
+ {
+ SwEnhancedPDFExportHelper aHelper( *pWrtShell, *pOut, aPageRange, bIsSkipEmptyPages, true, rSwPrtOptions );
+ }
+
+ pVwSh->SetPDFExportOption( false );
+
+ // last page to be rendered? (not necessarily the last page of the document)
+ // -> do clean-up of data
+ if (bLastPage)
+ {
+ // #i96167# haggai: delete ViewOptionsAdjust here because it makes use
+ // of the shell, which might get destroyed in lcl_DisposeView!
+ if (m_pRenderData->IsViewOptionAdjust())
+ m_pRenderData->ViewOptionAdjustStop();
+
+ if (m_pRenderData->HasPostItData())
+ m_pRenderData->DeletePostItData();
+ if (m_pHiddenViewFrame)
+ {
+ lcl_DisposeView( m_pHiddenViewFrame, m_pDocShell );
+ m_pHiddenViewFrame = nullptr;
+
+ // prevent crash described in #i108805
+ SwDocShell *pRenderDocShell = pDoc->GetDocShell();
+ SfxItemSet *pSet = pRenderDocShell->GetMedium()->GetItemSet();
+ pSet->Put( SfxBoolItem( SID_HIDDEN, false ) );
+
+ }
+ }
+ }
+ }
+ }
+ }
+ if( bLastPage )
+ {
+ // tdf#144989 enable DoIdleJobs() again after last page
+ pDoc->getIDocumentTimerAccess().UnblockIdling();
+ m_pRenderData.reset();
+ m_pPrintUIOptions.reset();
+ }
+}
+
+// xforms::XFormsSupplier
+Reference<XNameContainer> SAL_CALL SwXTextDocument::getXForms()
+{
+ SolarMutexGuard aGuard;
+ if ( !m_pDocShell )
+ throw DisposedException( OUString(), static_cast< XTextDocument* >( this ) );
+ SwDoc* pDoc = m_pDocShell->GetDoc();
+ return pDoc->getXForms();
+}
+
+uno::Reference< text::XFlatParagraphIterator > SAL_CALL SwXTextDocument::getFlatParagraphIterator(::sal_Int32 nTextMarkupType, sal_Bool bAutomatic)
+{
+ SolarMutexGuard aGuard;
+ if (!IsValid())
+ {
+ throw DisposedException("SwXTextDocument not valid",
+ static_cast<XTextDocument*>(this));
+ }
+
+ return SwUnoCursorHelper::CreateFlatParagraphIterator(
+ *m_pDocShell->GetDoc(), nTextMarkupType, bAutomatic);
+}
+
+uno::Reference< util::XCloneable > SwXTextDocument::createClone( )
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw DisposedException("", static_cast< XTextDocument* >(this));
+
+ // create a new document - hidden - copy the storage and return it
+ // SfxObjectShellRef is used here, since the model should control object lifetime after creation
+ // and thus SfxObjectShellLock is not allowed here
+ // the model holds reference to the shell, so the shell will not destructed at the end of method
+ SfxObjectShellRef pShell = m_pDocShell->GetDoc()->CreateCopy(false, false);
+ uno::Reference< frame::XModel > xNewModel = pShell->GetModel();
+ uno::Reference< embed::XStorage > xNewStorage = ::comphelper::OStorageHelper::GetTemporaryStorage( );
+ uno::Sequence< beans::PropertyValue > aTempMediaDescriptor;
+ storeToStorage( xNewStorage, aTempMediaDescriptor );
+ uno::Reference< document::XStorageBasedDocument > xStorageDoc( xNewModel, uno::UNO_QUERY );
+ xStorageDoc->loadFromStorage( xNewStorage, aTempMediaDescriptor );
+ return uno::Reference< util::XCloneable >( xNewModel, UNO_QUERY );
+}
+
+void SwXTextDocument::addPasteEventListener(const uno::Reference<text::XPasteListener>& xListener)
+{
+ SolarMutexGuard aGuard;
+
+ if (IsValid() && xListener.is())
+ m_pDocShell->GetWrtShell()->GetPasteListeners().addInterface(xListener);
+}
+
+void SwXTextDocument::removePasteEventListener(
+ const uno::Reference<text::XPasteListener>& xListener)
+{
+ SolarMutexGuard aGuard;
+
+ if (IsValid() && xListener.is())
+ m_pDocShell->GetWrtShell()->GetPasteListeners().removeInterface(xListener);
+}
+
+void SwXTextDocument::paintTile( VirtualDevice &rDevice,
+ int nOutputWidth, int nOutputHeight,
+ int nTilePosX, int nTilePosY,
+ tools::Long nTileWidth, tools::Long nTileHeight )
+{
+ SwViewShell* pViewShell = m_pDocShell->GetWrtShell();
+ pViewShell->PaintTile(rDevice, nOutputWidth, nOutputHeight,
+ nTilePosX, nTilePosY, nTileWidth, nTileHeight);
+
+ LokChartHelper::PaintAllChartsOnTile(rDevice, nOutputWidth, nOutputHeight,
+ nTilePosX, nTilePosY, nTileWidth, nTileHeight);
+}
+
+Size SwXTextDocument::getDocumentSize()
+{
+ SwViewShell* pViewShell = m_pDocShell->GetWrtShell();
+ Size aDocSize = pViewShell->GetDocSize();
+
+ return Size(aDocSize.Width() + 2 * DOCUMENTBORDER,
+ aDocSize.Height() + 2 * DOCUMENTBORDER);
+}
+
+void SwXTextDocument::setPart(int nPart, bool /*bAllowChangeFocus*/)
+{
+ SolarMutexGuard aGuard;
+
+ SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
+ if (!pWrtShell)
+ return;
+
+ pWrtShell->GotoPage(nPart + 1, true);
+}
+
+int SwXTextDocument::getParts()
+{
+ SolarMutexGuard aGuard;
+
+ SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
+ if (!pWrtShell)
+ return 0;
+
+ return pWrtShell->GetPageCnt();
+}
+
+OUString SwXTextDocument::getPartPageRectangles()
+{
+ SolarMutexGuard aGuard;
+
+ SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
+ if (!pWrtShell)
+ return OUString();
+
+ return pWrtShell->getPageRectangles();
+}
+
+void SwXTextDocument::setClipboard(const uno::Reference<datatransfer::clipboard::XClipboard>& xClipboard)
+{
+ SolarMutexGuard aGuard;
+
+ SwView* pView = m_pDocShell->GetView();
+ if (pView)
+ pView->GetEditWin().SetClipboard(xClipboard);
+}
+
+bool SwXTextDocument::isMimeTypeSupported()
+{
+ SolarMutexGuard aGuard;
+
+ SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
+ if (!pWrtShell)
+ return false;
+
+ TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromSystemClipboard(&pWrtShell->GetView().GetEditWin()));
+ if (SdrView* pSdrView = pWrtShell->GetDrawView())
+ {
+ if (pSdrView->GetTextEditObject())
+ // Editing shape text
+ return EditEngine::HasValidData(aDataHelper.GetTransferable());
+ }
+
+ return aDataHelper.GetXTransferable().is() && SwTransferable::IsPaste(*pWrtShell, aDataHelper);
+}
+
+void SwXTextDocument::setClientVisibleArea(const tools::Rectangle& rRectangle)
+{
+ if (SwView* pView = m_pDocShell->GetView())
+ {
+ // set the PgUp/PgDown offset
+ pView->ForcePageUpDownOffset(2 * rRectangle.GetHeight() / 3);
+ }
+
+ if (SwViewShell* pViewShell = m_pDocShell->GetWrtShell())
+ {
+ pViewShell->setLOKVisibleArea(rRectangle);
+ }
+}
+
+void SwXTextDocument::setClientZoom(int nTilePixelWidth_, int /*nTilePixelHeight_*/,
+ int nTileTwipWidth_, int /*nTileTwipHeight_*/)
+{
+ // Here we set the zoom value as it has been set by the user in the client.
+ // This value is used in postMouseEvent and setGraphicSelection methods
+ // for in place chart editing. We assume that x and y scale is roughly
+ // the same.
+ SfxInPlaceClient* pIPClient = m_pDocShell->GetView()->GetIPClient();
+ if (!pIPClient)
+ return;
+
+ SwViewShell* pWrtViewShell = m_pDocShell->GetWrtShell();
+ double fScale = 100.0 * nTilePixelWidth_ / nTileTwipWidth_
+ * o3tl::convert(1.0, o3tl::Length::px, o3tl::Length::twip);
+ SwViewOption aOption(*(pWrtViewShell->GetViewOptions()));
+ if (aOption.GetZoom() != fScale)
+ {
+ aOption.SetZoom(fScale);
+ pWrtViewShell->ApplyViewOptions(aOption);
+
+ // Changing the zoom value doesn't always trigger the updating of
+ // the client ole object area, so we call it directly.
+ pIPClient->VisAreaChanged();
+ }
+}
+
+PointerStyle SwXTextDocument::getPointer()
+{
+ SolarMutexGuard aGuard;
+
+ SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
+ if (!pWrtShell)
+ return PointerStyle::Arrow;
+
+ return pWrtShell->GetView().GetEditWin().GetPointer();
+}
+
+void SwXTextDocument::getTrackedChanges(tools::JsonWriter& rJson)
+{
+ auto redlinesNode = rJson.startArray("redlines");
+
+ // Disable since usability is very low beyond some small number of changes.
+ static bool bDisableRedlineComments = getenv("DISABLE_REDLINE") != nullptr;
+ if (bDisableRedlineComments)
+ return;
+
+ const SwRedlineTable& rRedlineTable
+ = m_pDocShell->GetDoc()->getIDocumentRedlineAccess().GetRedlineTable();
+ for (SwRedlineTable::size_type i = 0; i < rRedlineTable.size(); ++i)
+ {
+ auto redlineNode = rJson.startStruct();
+ rJson.put("index", rRedlineTable[i]->GetId());
+ rJson.put("author", rRedlineTable[i]->GetAuthorString(1));
+ rJson.put("type", SwRedlineTypeToOUString(
+ rRedlineTable[i]->GetRedlineData().GetType()));
+ rJson.put("comment",
+ rRedlineTable[i]->GetRedlineData().GetComment());
+ rJson.put("description", rRedlineTable[i]->GetDescr());
+ OUString sDateTime = utl::toISO8601(
+ rRedlineTable[i]->GetRedlineData().GetTimeStamp().GetUNODateTime());
+ rJson.put("dateTime", sDateTime);
+
+ SwContentNode* pContentNd = rRedlineTable[i]->GetContentNode();
+ SwView* pView = dynamic_cast<SwView*>(SfxViewShell::Current());
+ if (pView && pContentNd)
+ {
+ SwShellCursor aCursor(pView->GetWrtShell(), *(rRedlineTable[i]->Start()));
+ aCursor.SetMark();
+ aCursor.GetMark()->nNode = *pContentNd;
+ aCursor.GetMark()->nContent.Assign(pContentNd,
+ rRedlineTable[i]->End()->nContent.GetIndex());
+
+ aCursor.FillRects();
+
+ SwRects* pRects(&aCursor);
+ std::vector<OString> aRects;
+ for (const SwRect& rNextRect : *pRects)
+ aRects.push_back(rNextRect.SVRect().toString());
+
+ const OString sRects = comphelper::string::join("; ", aRects);
+ rJson.put("textRange", sRects);
+ }
+ }
+}
+
+void SwXTextDocument::getTrackedChangeAuthors(tools::JsonWriter& rJsonWriter)
+{
+ SW_MOD()->GetRedlineAuthorInfo(rJsonWriter);
+}
+
+void SwXTextDocument::getRulerState(tools::JsonWriter& rJsonWriter)
+{
+ SwView* pView = m_pDocShell->GetView();
+ dynamic_cast<SwCommentRuler&>(pView->GetHRuler()).CreateJsonNotification(rJsonWriter);
+}
+
+void SwXTextDocument::getPostIts(tools::JsonWriter& rJsonWriter)
+{
+ SolarMutexGuard aGuard;
+ auto commentsNode = rJsonWriter.startArray("comments");
+ for (auto const& sidebarItem : *m_pDocShell->GetView()->GetPostItMgr())
+ {
+ sw::annotation::SwAnnotationWin* pWin = sidebarItem->mpPostIt.get();
+
+ if (!pWin)
+ {
+ continue;
+ }
+
+ const SwPostItField* pField = pWin->GetPostItField();
+ const SwRect& aRect = pWin->GetAnchorRect();
+ tools::Rectangle aSVRect(aRect.Pos().getX(),
+ aRect.Pos().getY(),
+ aRect.Pos().getX() + aRect.SSize().Width(),
+ aRect.Pos().getY() + aRect.SSize().Height());
+
+ if (!sidebarItem->maLayoutInfo.mPositionFromCommentAnchor)
+ {
+ // Comments on frames: anchor position is the corner position, not the whole frame.
+ aSVRect.SetSize(Size(0, 0));
+ }
+
+ std::vector<OString> aRects;
+ for (const basegfx::B2DRange& aRange : pWin->GetAnnotationTextRanges())
+ {
+ const SwRect rect(aRange.getMinX(), aRange.getMinY(), aRange.getWidth(), aRange.getHeight());
+ aRects.push_back(rect.SVRect().toString());
+ }
+ const OString sRects = comphelper::string::join("; ", aRects);
+
+ auto commentNode = rJsonWriter.startStruct();
+ rJsonWriter.put("id", pField->GetPostItId());
+ rJsonWriter.put("parent", pWin->CalcParent());
+ rJsonWriter.put("author", pField->GetPar1());
+ rJsonWriter.put("text", pField->GetPar2());
+ rJsonWriter.put("resolved", pField->GetResolved() ? "true" : "false");
+ rJsonWriter.put("dateTime", utl::toISO8601(pField->GetDateTime().GetUNODateTime()));
+ rJsonWriter.put("anchorPos", aSVRect.toString());
+ rJsonWriter.put("textRange", sRects);
+ }
+}
+
+void SwXTextDocument::executeFromFieldEvent(const StringMap& aArguments)
+{
+ auto aIter = aArguments.find("type");
+ if (aIter == aArguments.end() || aIter->second != "drop-down")
+ return;
+
+ aIter = aArguments.find("cmd");
+ if (aIter == aArguments.end() || aIter->second != "selected")
+ return;
+
+ aIter = aArguments.find("data");
+ if (aIter == aArguments.end())
+ return;
+
+ sal_Int32 nSelection = aIter->second.toInt32();
+ SwPosition aPos(*m_pDocShell->GetWrtShell()->GetCursor()->GetPoint());
+ sw::mark::IFieldmark* pFieldBM = m_pDocShell->GetWrtShell()->getIDocumentMarkAccess()->getFieldmarkFor(aPos);
+ if ( !pFieldBM )
+ {
+ --aPos.nContent;
+ pFieldBM = m_pDocShell->GetWrtShell()->getIDocumentMarkAccess()->getFieldmarkFor(aPos);
+ }
+ if (pFieldBM && pFieldBM->GetFieldname() == ODF_FORMDROPDOWN)
+ {
+ if (nSelection >= 0)
+ {
+ (*pFieldBM->GetParameters())[ODF_FORMDROPDOWN_RESULT] <<= nSelection;
+ pFieldBM->Invalidate();
+ m_pDocShell->GetWrtShell()->SetModified();
+ m_pDocShell->GetView()->GetEditWin().LogicInvalidate(nullptr);
+ }
+ }
+}
+
+std::vector<basegfx::B2DRange>
+SwXTextDocument::getSearchResultRectangles(const char* pPayload)
+{
+ SwDoc* pDoc = m_pDocShell->GetDoc();
+ if (!pDoc)
+ return std::vector<basegfx::B2DRange>();
+
+ sw::search::SearchResultLocator aLocator(pDoc);
+ sw::search::LocationResult aResult = aLocator.findForPayload(pPayload);
+ if (aResult.mbFound)
+ {
+ return aResult.maRectangles;
+ }
+ return std::vector<basegfx::B2DRange>();
+}
+
+namespace
+{
+inline constexpr OUStringLiteral SELECTED_DATE_FORMAT = u"YYYY-MM-DD";
+}
+
+void SwXTextDocument::executeContentControlEvent(const StringMap& rArguments)
+{
+ auto it = rArguments.find("type");
+ if (it == rArguments.end())
+ {
+ return;
+ }
+
+ if (it->second == "drop-down")
+ {
+ SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
+ const SwPosition* pStart = pWrtShell->GetCursor()->Start();
+ SwTextNode* pTextNode = pStart->nNode.GetNode().GetTextNode();
+ if (!pTextNode)
+ {
+ return;
+ }
+
+ SwTextAttr* pAttr = pTextNode->GetTextAttrAt(pStart->nContent.GetIndex(),
+ RES_TXTATR_CONTENTCONTROL, SwTextNode::PARENT);
+ if (!pAttr)
+ {
+ return;
+ }
+
+ auto pTextContentControl = static_txtattr_cast<SwTextContentControl*>(pAttr);
+ const SwFormatContentControl& rFormatContentControl = pTextContentControl->GetContentControl();
+ std::shared_ptr<SwContentControl> pContentControl = rFormatContentControl.GetContentControl();
+ if (!pContentControl->HasListItems())
+ {
+ return;
+ }
+
+ it = rArguments.find("selected");
+ if (it == rArguments.end())
+ {
+ return;
+ }
+
+ sal_Int32 nSelection = it->second.toInt32();
+ pContentControl->SetSelectedListItem(nSelection);
+ pWrtShell->GotoContentControl(rFormatContentControl);
+ }
+ else if (it->second == "picture")
+ {
+ it = rArguments.find("changed");
+ if (it == rArguments.end())
+ {
+ return;
+ }
+
+ SwView* pView = m_pDocShell->GetView();
+ if (!pView)
+ {
+ return;
+ }
+
+ // The current placeholder is selected, so this will replace, not insert.
+ SfxStringItem aItem(SID_INSERT_GRAPHIC, it->second);
+ pView->GetViewFrame()->GetDispatcher()->ExecuteList(SID_INSERT_GRAPHIC,
+ SfxCallMode::SYNCHRON, { &aItem });
+ }
+ else if (it->second == "date")
+ {
+ SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
+ const SwPosition* pStart = pWrtShell->GetCursor()->Start();
+ SwTextNode* pTextNode = pStart->nNode.GetNode().GetTextNode();
+ if (!pTextNode)
+ {
+ return;
+ }
+
+ SwTextAttr* pAttr = pTextNode->GetTextAttrAt(pStart->nContent.GetIndex(),
+ RES_TXTATR_CONTENTCONTROL, SwTextNode::PARENT);
+ if (!pAttr)
+ {
+ return;
+ }
+
+ auto pTextContentControl = static_txtattr_cast<SwTextContentControl*>(pAttr);
+ const SwFormatContentControl& rFormatContentControl
+ = pTextContentControl->GetContentControl();
+ std::shared_ptr<SwContentControl> pContentControl
+ = rFormatContentControl.GetContentControl();
+ if (!pContentControl->GetDate())
+ {
+ return;
+ }
+
+ it = rArguments.find("selected");
+ if (it == rArguments.end())
+ {
+ return;
+ }
+
+ OUString aSelectedDate = it->second.replaceAll("T00:00:00Z", "");
+ SwDoc& rDoc = pTextNode->GetDoc();
+ SvNumberFormatter* pNumberFormatter = rDoc.GetNumberFormatter();
+ sal_uInt32 nFormat
+ = pNumberFormatter->GetEntryKey(SELECTED_DATE_FORMAT, LANGUAGE_ENGLISH_US);
+ if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ sal_Int32 nCheckPos = 0;
+ SvNumFormatType nType;
+ OUString sFormat = SELECTED_DATE_FORMAT;
+ pNumberFormatter->PutEntry(sFormat, nCheckPos, nType, nFormat, LANGUAGE_ENGLISH_US);
+ }
+
+ if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ return;
+ }
+
+ double dCurrentDate = 0;
+ pNumberFormatter->IsNumberFormat(aSelectedDate, nFormat, dCurrentDate);
+ pContentControl->SetSelectedDate(dCurrentDate);
+ pWrtShell->GotoContentControl(rFormatContentControl);
+ }
+}
+
+int SwXTextDocument::getPart()
+{
+ SolarMutexGuard aGuard;
+
+ SwView* pView = m_pDocShell->GetView();
+ if (!pView)
+ return 0;
+
+ return pView->getPart();
+}
+
+OUString SwXTextDocument::getPartName(int nPart)
+{
+ return SwResId(STR_PAGE) + OUString::number(nPart + 1);
+}
+
+OUString SwXTextDocument::getPartHash(int nPart)
+{
+ OUString sPart(SwResId(STR_PAGE) + OUString::number(nPart + 1));
+
+ return OUString::number(sPart.hashCode());
+}
+
+VclPtr<vcl::Window> SwXTextDocument::getDocWindow()
+{
+ SolarMutexGuard aGuard;
+ SwView* pView = m_pDocShell->GetView();
+
+ if (VclPtr<vcl::Window> pWindow = LokChartHelper(pView).GetWindow())
+ return pWindow;
+ if (VclPtr<vcl::Window> pWindow = LokStarMathHelper(pView).GetWidgetWindow())
+ return pWindow;
+
+ if (pView)
+ return &(pView->GetEditWin());
+
+ return {};
+}
+
+void SwXTextDocument::initializeForTiledRendering(const css::uno::Sequence<css::beans::PropertyValue>& rArguments)
+{
+ SolarMutexGuard aGuard;
+
+ SwViewShell* pViewShell = m_pDocShell->GetWrtShell();
+
+ SwView* pView = m_pDocShell->GetView();
+ if (!pView)
+ return;
+
+ pView->SetViewLayout(1/*nColumns*/, false/*bBookMode*/, true);
+
+ // Tiled rendering defaults.
+ SwViewOption aViewOption(*pViewShell->GetViewOptions());
+ aViewOption.SetHardBlank(false);
+
+ // Disable field shadings: the result would depend on the cursor position.
+ SwViewOption::SetAppearanceFlag(ViewOptFlags::FieldShadings, false);
+
+ for (const beans::PropertyValue& rValue : rArguments)
+ {
+ if (rValue.Name == ".uno:HideWhitespace" && rValue.Value.has<bool>())
+ aViewOption.SetHideWhitespaceMode(rValue.Value.get<bool>());
+ else if (rValue.Name == ".uno:ShowBorderShadow" && rValue.Value.has<bool>())
+ SwViewOption::SetAppearanceFlag(ViewOptFlags::Shadow , rValue.Value.get<bool>());
+ else if (rValue.Name == ".uno:Author" && rValue.Value.has<OUString>())
+ {
+ // Store the author name in the view.
+ pView->SetRedlineAuthor(rValue.Value.get<OUString>());
+ // Let the actual author name pick up the value from the current
+ // view, which would normally happen only during the next view
+ // switch.
+ m_pDocShell->SetView(pView);
+ }
+ else if (rValue.Name == ".uno:SpellOnline" && rValue.Value.has<bool>())
+ aViewOption.SetOnlineSpell(rValue.Value.get<bool>());
+ }
+
+ // Set the initial zoom value to 1; usually it is set in setClientZoom and
+ // SwViewShell::PaintTile; zoom value is used for chart in place
+ // editing, see postMouseEvent and setGraphicSelection methods.
+ aViewOption.SetZoom(1 * 100);
+
+ aViewOption.SetPostIts(comphelper::LibreOfficeKit::isTiledAnnotations());
+ pViewShell->ApplyViewOptions(aViewOption);
+
+ // position the pages again after setting view options. Eg: if postit
+ // rendering is false, then there would be no sidebar, so width of the
+ // document needs to be adjusted
+ pViewShell->GetLayout()->CheckViewLayout( pViewShell->GetViewOptions(), nullptr );
+
+ // Disable map mode, so that it's possible to send mouse event coordinates
+ // directly in twips.
+ SwEditWin& rEditWin = m_pDocShell->GetView()->GetEditWin();
+ rEditWin.EnableMapMode(false);
+
+ // when the "This document may contain formatting or content that cannot
+ // be saved..." dialog appears, it is auto-cancelled with tiled rendering,
+ // causing 'Save' being disabled; so let's always save to the original
+ // format
+ auto xChanges = comphelper::ConfigurationChanges::create();
+ officecfg::Office::Common::Save::Document::WarnAlienFormat::set(false, xChanges);
+ xChanges->commit();
+
+ // disable word auto-completion suggestions, the tooltips are not visible,
+ // and the editeng-like auto-completion is annoying
+ SvxAutoCorrCfg::Get().GetAutoCorrect()->GetSwFlags().bAutoCompleteWords = false;
+
+ // don't change the whitespace at the beginning of paragraphs, this is
+ // annoying when taking minutes without further formatting
+ SwEditShell::GetAutoFormatFlags()->bAFormatByInpDelSpacesAtSttEnd = false;
+}
+
+void SwXTextDocument::postKeyEvent(int nType, int nCharCode, int nKeyCode)
+{
+ SolarMutexGuard aGuard;
+ SfxLokHelper::postKeyEventAsync(getDocWindow(), nType, nCharCode, nKeyCode);
+}
+
+void SwXTextDocument::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
+{
+ SolarMutexGuard aGuard;
+
+ SwViewShell* pWrtViewShell = m_pDocShell->GetWrtShell();
+ if (!pWrtViewShell)
+ {
+ return;
+ }
+
+ SwViewOption aOption(*(pWrtViewShell->GetViewOptions()));
+ double fScale = aOption.GetZoom() / o3tl::convert(100.0, o3tl::Length::px, o3tl::Length::twip);
+
+ // check if the user hit a chart/math object which is being edited by this view
+ if (LokChartHelper(m_pDocShell->GetView()).postMouseEvent(nType, nX, nY,
+ nCount, nButtons, nModifier,
+ fScale, fScale))
+ return;
+ if (LokStarMathHelper(m_pDocShell->GetView()).postMouseEvent(nType, nX, nY,
+ nCount, nButtons, nModifier,
+ fScale, fScale))
+ return;
+
+ // check if the user hit a chart which is being edited by someone else
+ // and, if so, skip current mouse event
+ if (nType != LOK_MOUSEEVENT_MOUSEMOVE)
+ {
+ if (LokChartHelper::HitAny(Point(nX, nY)))
+ return;
+ }
+
+ SwEditWin& rEditWin = m_pDocShell->GetView()->GetEditWin();
+ LokMouseEventData aMouseEventData(nType, Point(nX, nY), nCount,
+ MouseEventModifiers::SIMPLECLICK,
+ nButtons, nModifier);
+ SfxLokHelper::postMouseEventAsync(&rEditWin, aMouseEventData);
+}
+
+void SwXTextDocument::setTextSelection(int nType, int nX, int nY)
+{
+ SolarMutexGuard aGuard;
+
+ SfxViewShell* pViewShell = m_pDocShell->GetView();
+ LokChartHelper aChartHelper(pViewShell);
+ if (aChartHelper.setTextSelection(nType, nX, nY))
+ return;
+
+ SwEditWin& rEditWin = m_pDocShell->GetView()->GetEditWin();
+ switch (nType)
+ {
+ case LOK_SETTEXTSELECTION_START:
+ rEditWin.SetCursorTwipPosition(Point(nX, nY), /*bPoint=*/false, /*bClearMark=*/false);
+ break;
+ case LOK_SETTEXTSELECTION_END:
+ rEditWin.SetCursorTwipPosition(Point(nX, nY), /*bPoint=*/true, /*bClearMark=*/false);
+ break;
+ case LOK_SETTEXTSELECTION_RESET:
+ rEditWin.SetCursorTwipPosition(Point(nX, nY), /*bPoint=*/true, /*bClearMark=*/true);
+ break;
+ default:
+ assert(false);
+ break;
+ }
+}
+
+uno::Reference<datatransfer::XTransferable> SwXTextDocument::getSelection()
+{
+ SolarMutexGuard aGuard;
+
+ uno::Reference<datatransfer::XTransferable> xTransferable;
+
+ SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
+ if (SdrView* pSdrView = pWrtShell ? pWrtShell->GetDrawView() : nullptr)
+ {
+ if (pSdrView->GetTextEditObject())
+ {
+ // Editing shape text
+ EditView& rEditView = pSdrView->GetTextEditOutlinerView()->GetEditView();
+ xTransferable = rEditView.GetEditEngine()->CreateTransferable(rEditView.GetSelection());
+ }
+ }
+
+ if (SwPostItMgr* pPostItMgr = m_pDocShell->GetView()->GetPostItMgr())
+ {
+ if (sw::annotation::SwAnnotationWin* pWin = pPostItMgr->GetActiveSidebarWin())
+ {
+ // Editing postit text.
+ EditView& rEditView = pWin->GetOutlinerView()->GetEditView();
+ xTransferable = rEditView.GetEditEngine()->CreateTransferable(rEditView.GetSelection());
+ }
+ }
+
+ if (!xTransferable.is() && pWrtShell)
+ xTransferable = new SwTransferable(*pWrtShell);
+
+ return xTransferable;
+}
+
+void SwXTextDocument::setGraphicSelection(int nType, int nX, int nY)
+{
+ SolarMutexGuard aGuard;
+
+ SwViewShell* pWrtViewShell = m_pDocShell->GetWrtShell();
+ SwViewOption aOption(*(pWrtViewShell->GetViewOptions()));
+ double fScale = aOption.GetZoom() / o3tl::convert(100.0, o3tl::Length::px, o3tl::Length::twip);
+
+ SfxViewShell* pViewShell = m_pDocShell->GetView();
+ LokChartHelper aChartHelper(pViewShell);
+ if (aChartHelper.setGraphicSelection(nType, nX, nY, fScale, fScale))
+ return;
+
+ SwEditWin& rEditWin = m_pDocShell->GetView()->GetEditWin();
+ switch (nType)
+ {
+ case LOK_SETGRAPHICSELECTION_START:
+ rEditWin.SetGraphicTwipPosition(/*bStart=*/true, Point(nX, nY));
+ break;
+ case LOK_SETGRAPHICSELECTION_END:
+ rEditWin.SetGraphicTwipPosition(/*bStart=*/false, Point(nX, nY));
+ break;
+ default:
+ assert(false);
+ break;
+ }
+}
+
+void SwXTextDocument::resetSelection()
+{
+ SolarMutexGuard aGuard;
+
+ SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
+ pWrtShell->ResetSelect(nullptr, false);
+}
+
+void SAL_CALL SwXTextDocument::paintTile( const ::css::uno::Any& Parent, ::sal_Int32 nOutputWidth, ::sal_Int32 nOutputHeight, ::sal_Int32 nTilePosX, ::sal_Int32 nTilePosY, ::sal_Int32 nTileWidth, ::sal_Int32 nTileHeight )
+{
+ SystemGraphicsData aData;
+ aData.nSize = sizeof(SystemGraphicsData);
+ #if defined(_WIN32)
+ sal_Int64 nWindowHandle;
+ Parent >>= nWindowHandle;
+ aData.hWnd = reinterpret_cast<HWND>(nWindowHandle);
+ ScopedVclPtrInstance<VirtualDevice> xDevice(aData, Size(1, 1), DeviceFormat::DEFAULT);
+ paintTile(*xDevice, nOutputWidth, nOutputHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
+ #else
+ // TODO: support other platforms
+ (void)Parent;
+ (void)nOutputWidth;
+ (void)nOutputHeight;
+ (void)nTilePosX;
+ (void)nTilePosY;
+ (void)nTileWidth;
+ (void)nTileHeight;
+ #endif
+}
+
+/**
+ * retrieve languages already used in current document
+ */
+uno::Sequence< lang::Locale > SAL_CALL SwXTextDocument::getDocumentLanguages(
+ ::sal_Int16 nScriptTypes,
+ ::sal_Int16 nMaxCount )
+{
+ SolarMutexGuard aGuard;
+
+ // possible canonical values for nScriptTypes
+ // any bit wise combination is allowed
+ const sal_Int16 nLatin = 0x001;
+ const sal_Int16 nAsian = 0x002;
+ const sal_Int16 nComplex = 0x004;
+
+ // script types for which to get the languages
+ const bool bLatin = 0 != (nScriptTypes & nLatin);
+ const bool bAsian = 0 != (nScriptTypes & nAsian);
+ const bool bComplex = 0 != (nScriptTypes & nComplex);
+
+ if (nScriptTypes < nLatin || nScriptTypes > (nLatin | nAsian | nComplex))
+ throw IllegalArgumentException("nScriptTypes ranges from 1 to 7!", Reference< XInterface >(), 1);
+ if (!m_pDocShell)
+ throw DisposedException();
+ SwDoc* pDoc = m_pDocShell->GetDoc();
+
+ // avoid duplicate values
+ std::set< LanguageType > aAllLangs;
+
+ //USER STYLES
+
+ const SwCharFormats *pFormats = pDoc->GetCharFormats();
+ for(size_t i = 0; i < pFormats->size(); ++i)
+ {
+ const SwAttrSet &rAttrSet = (*pFormats)[i]->GetAttrSet();
+ LanguageType nLang = LANGUAGE_DONTKNOW;
+ if (bLatin)
+ {
+ nLang = rAttrSet.GetLanguage( false ).GetLanguage();
+ if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
+ aAllLangs.insert( nLang );
+ }
+ if (bAsian)
+ {
+ nLang = rAttrSet.GetCJKLanguage( false ).GetLanguage();
+ if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
+ aAllLangs.insert( nLang );
+ }
+ if (bComplex)
+ {
+ nLang = rAttrSet.GetCTLLanguage( false ).GetLanguage();
+ if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
+ aAllLangs.insert( nLang );
+ }
+ }
+
+ const SwTextFormatColls *pColls = pDoc->GetTextFormatColls();
+ for (size_t i = 0; i < pColls->size(); ++i)
+ {
+ const SwAttrSet &rAttrSet = (*pColls)[i]->GetAttrSet();
+ LanguageType nLang = LANGUAGE_DONTKNOW;
+ if (bLatin)
+ {
+ nLang = rAttrSet.GetLanguage( false ).GetLanguage();
+ if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
+ aAllLangs.insert( nLang );
+ }
+ if (bAsian)
+ {
+ nLang = rAttrSet.GetCJKLanguage( false ).GetLanguage();
+ if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
+ aAllLangs.insert( nLang );
+ }
+ if (bComplex)
+ {
+ nLang = rAttrSet.GetCTLLanguage( false ).GetLanguage();
+ if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
+ aAllLangs.insert( nLang );
+ }
+ }
+
+ //AUTO STYLES
+ const IStyleAccess::SwAutoStyleFamily aFam[2] =
+ {
+ IStyleAccess::AUTO_STYLE_CHAR,
+ IStyleAccess::AUTO_STYLE_PARA
+ };
+ for (IStyleAccess::SwAutoStyleFamily i : aFam)
+ {
+ std::vector< std::shared_ptr<SfxItemSet> > rStyles;
+ pDoc->GetIStyleAccess().getAllStyles(rStyles, i);
+ while (!rStyles.empty())
+ {
+ std::shared_ptr<SfxItemSet> pStyle = rStyles.back();
+ rStyles.pop_back();
+ const SfxItemSet *pSet = pStyle.get();
+
+ LanguageType nLang = LANGUAGE_DONTKNOW;
+ if (bLatin)
+ {
+ assert(pSet);
+ nLang = dynamic_cast< const SvxLanguageItem & >(pSet->Get( RES_CHRATR_LANGUAGE, false )).GetLanguage();
+ if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
+ aAllLangs.insert( nLang );
+ }
+ if (bAsian)
+ {
+ assert(pSet);
+ nLang = dynamic_cast< const SvxLanguageItem & >(pSet->Get( RES_CHRATR_CJK_LANGUAGE, false )).GetLanguage();
+ if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
+ aAllLangs.insert( nLang );
+ }
+ if (bComplex)
+ {
+ assert(pSet);
+ nLang = dynamic_cast< const SvxLanguageItem & >(pSet->Get( RES_CHRATR_CTL_LANGUAGE, false )).GetLanguage();
+ if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
+ aAllLangs.insert( nLang );
+ }
+ }
+ }
+
+ //TODO/mba: it's a strange concept that a view is needed to retrieve core data
+ SwWrtShell *pWrtSh = m_pDocShell->GetWrtShell();
+ SdrView *pSdrView = pWrtSh->GetDrawView();
+
+ if( pSdrView )
+ {
+ SdrOutliner* pOutliner = pSdrView->GetTextEditOutliner();
+ if(pOutliner)
+ {
+ EditEngine& rEditEng = const_cast<EditEngine&>(pOutliner->GetEditEngine());
+ sal_Int32 nParCount = pOutliner->GetParagraphCount();
+ for (sal_Int32 nPar=0; nPar<nParCount; nPar++)
+ {
+ //every paragraph
+ std::vector<sal_Int32> aPortions;
+ rEditEng.GetPortions( nPar, aPortions );
+
+ for ( size_t nPos = aPortions.size(); nPos; )
+ {
+ //every position
+ --nPos;
+ sal_Int32 nEnd = aPortions[ nPos ];
+ sal_Int32 nStart = nPos ? aPortions[ nPos - 1 ] : 0;
+ ESelection aSelection( nPar, nStart, nPar, nEnd );
+ SfxItemSet aAttr = rEditEng.GetAttribs( aSelection );
+
+ LanguageType nLang = LANGUAGE_DONTKNOW;
+ if (bLatin)
+ {
+ nLang = dynamic_cast< const SvxLanguageItem & >(aAttr.Get( EE_CHAR_LANGUAGE, false )).GetLanguage();
+ if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
+ aAllLangs.insert( nLang );
+ }
+ if (bAsian)
+ {
+ nLang = dynamic_cast< const SvxLanguageItem & >(aAttr.Get( EE_CHAR_LANGUAGE_CJK, false )).GetLanguage();
+ if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
+ aAllLangs.insert( nLang );
+ }
+ if (bComplex)
+ {
+ nLang = dynamic_cast< const SvxLanguageItem & >(aAttr.Get( EE_CHAR_LANGUAGE_CTL, false )).GetLanguage();
+ if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
+ aAllLangs.insert( nLang );
+ }
+ }
+ }
+ }
+ }
+ // less than nMaxCount languages
+ if (nMaxCount > static_cast< sal_Int16 >( aAllLangs.size() ))
+ nMaxCount = static_cast< sal_Int16 >( aAllLangs.size() );
+
+ // build return value
+ uno::Sequence< lang::Locale > aLanguages( nMaxCount );
+ lang::Locale* pLanguage = aLanguages.getArray();
+ if (nMaxCount > 0)
+ {
+ sal_Int32 nCount = 0;
+ for (const auto& rLang : aAllLangs)
+ {
+ if (nCount >= nMaxCount)
+ break;
+ if (LANGUAGE_NONE != rLang)
+ {
+ pLanguage[nCount] = LanguageTag::convertToLocale( rLang );
+ pLanguage[nCount].Language = SvtLanguageTable::GetLanguageString( rLang );
+ nCount += 1;
+ }
+ }
+ }
+
+ return aLanguages;
+}
+
+SwXLinkTargetSupplier::SwXLinkTargetSupplier(SwXTextDocument& rxDoc) :
+ m_pxDoc(&rxDoc)
+{
+ m_sTables = SwResId(STR_CONTENT_TYPE_TABLE);
+ m_sFrames = SwResId(STR_CONTENT_TYPE_FRAME);
+ m_sGraphics = SwResId(STR_CONTENT_TYPE_GRAPHIC);
+ m_sOLEs = SwResId(STR_CONTENT_TYPE_OLE);
+ m_sSections = SwResId(STR_CONTENT_TYPE_REGION);
+ m_sOutlines = SwResId(STR_CONTENT_TYPE_OUTLINE);
+ m_sBookmarks = SwResId(STR_CONTENT_TYPE_BOOKMARK);
+ m_sDrawingObjects = SwResId(STR_CONTENT_TYPE_DRAWOBJECT);
+}
+
+SwXLinkTargetSupplier::~SwXLinkTargetSupplier()
+{
+}
+
+Any SwXLinkTargetSupplier::getByName(const OUString& rName)
+{
+ Any aRet;
+ if(!m_pxDoc)
+ throw RuntimeException("No document available");
+ OUString sSuffix("|");
+ if(rName == m_sTables)
+ {
+ sSuffix += "table";
+
+ Reference< XNameAccess > xTables = new SwXLinkNameAccessWrapper(
+ m_pxDoc->getTextTables(), rName, sSuffix );
+ aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
+ }
+ else if(rName == m_sFrames)
+ {
+ sSuffix += "frame";
+ Reference< XNameAccess > xTables = new SwXLinkNameAccessWrapper(
+ m_pxDoc->getTextFrames(), rName, sSuffix );
+ aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
+ }
+ else if(rName == m_sSections)
+ {
+ sSuffix += "region";
+ Reference< XNameAccess > xTables = new SwXLinkNameAccessWrapper(
+ m_pxDoc->getTextSections(), rName, sSuffix );
+ aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
+ }
+ else if(rName == m_sGraphics)
+ {
+ sSuffix += "graphic";
+ Reference< XNameAccess > xTables = new SwXLinkNameAccessWrapper(
+ m_pxDoc->getGraphicObjects(), rName, sSuffix );
+ aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
+ }
+ else if(rName == m_sOLEs)
+ {
+ sSuffix += "ole";
+ Reference< XNameAccess > xTables = new SwXLinkNameAccessWrapper(
+ m_pxDoc->getEmbeddedObjects(), rName, sSuffix );
+ aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
+ }
+ else if(rName == m_sOutlines)
+ {
+ sSuffix += "outline";
+ Reference< XNameAccess > xTables = new SwXLinkNameAccessWrapper(
+ *m_pxDoc, rName, sSuffix );
+ aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
+ }
+ else if(rName == m_sBookmarks)
+ {
+ sSuffix.clear();
+ Reference< XNameAccess > xBkms = new SwXLinkNameAccessWrapper(
+ m_pxDoc->getBookmarks(), rName, sSuffix );
+ aRet <<= Reference< XPropertySet >(xBkms, UNO_QUERY);
+ }
+ else if(rName == m_sDrawingObjects)
+ {
+ sSuffix += "drawingobject";
+ Reference<XNameAccess> xDrawingObjects = new SwXLinkNameAccessWrapper(
+ *m_pxDoc, rName, sSuffix);
+ aRet <<= Reference<XPropertySet>(xDrawingObjects, UNO_QUERY);
+ }
+ else
+ throw NoSuchElementException();
+ return aRet;
+}
+
+Sequence< OUString > SwXLinkTargetSupplier::getElementNames()
+{
+ return { m_sTables,
+ m_sFrames,
+ m_sGraphics,
+ m_sOLEs,
+ m_sSections,
+ m_sOutlines,
+ m_sBookmarks,
+ m_sDrawingObjects };
+}
+
+sal_Bool SwXLinkTargetSupplier::hasByName(const OUString& rName)
+{
+ if( rName == m_sTables ||
+ rName == m_sFrames ||
+ rName == m_sGraphics||
+ rName == m_sOLEs ||
+ rName == m_sSections ||
+ rName == m_sOutlines ||
+ rName == m_sBookmarks ||
+ rName == m_sDrawingObjects )
+ return true;
+ return false;
+}
+
+uno::Type SwXLinkTargetSupplier::getElementType()
+{
+ return cppu::UnoType<XPropertySet>::get();
+
+}
+
+sal_Bool SwXLinkTargetSupplier::hasElements()
+{
+ return nullptr != m_pxDoc;
+}
+
+OUString SwXLinkTargetSupplier::getImplementationName()
+{
+ return "SwXLinkTargetSupplier";
+}
+
+sal_Bool SwXLinkTargetSupplier::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXLinkTargetSupplier::getSupportedServiceNames()
+{
+ Sequence< OUString > aRet { "com.sun.star.document.LinkTargets" };
+ return aRet;
+}
+
+SwXLinkNameAccessWrapper::SwXLinkNameAccessWrapper(
+ Reference< XNameAccess > const & xAccess, const OUString& rLinkDisplayName, const OUString& sSuffix ) :
+ m_xRealAccess(xAccess),
+ m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_LINK_TARGET)),
+ m_sLinkSuffix(sSuffix),
+ m_sLinkDisplayName(rLinkDisplayName),
+ m_pxDoc(nullptr)
+{
+}
+
+SwXLinkNameAccessWrapper::SwXLinkNameAccessWrapper(SwXTextDocument& rxDoc,
+ const OUString& rLinkDisplayName, const OUString& sSuffix) :
+ m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_LINK_TARGET)),
+ m_sLinkSuffix(sSuffix),
+ m_sLinkDisplayName(rLinkDisplayName),
+ m_pxDoc(&rxDoc)
+{
+}
+
+SwXLinkNameAccessWrapper::~SwXLinkNameAccessWrapper()
+{
+}
+
+Any SwXLinkNameAccessWrapper::getByName(const OUString& rName)
+{
+ Any aRet;
+ bool bFound = false;
+ //cut link extension and call the real NameAccess
+ OUString sParam = rName;
+ OUString sSuffix(m_sLinkSuffix);
+ if(sParam.getLength() > sSuffix.getLength() )
+ {
+ std::u16string_view sCmp = sParam.subView(sParam.getLength() - sSuffix.getLength(),
+ sSuffix.getLength());
+ if(sCmp == sSuffix)
+ {
+ if(m_pxDoc)
+ {
+ sParam = sParam.copy(0, sParam.getLength() - sSuffix.getLength());
+ if(!m_pxDoc->GetDocShell())
+ throw RuntimeException("No document shell available");
+ SwDoc* pDoc = m_pxDoc->GetDocShell()->GetDoc();
+
+ if (sSuffix == "|outline")
+ {
+ const size_t nOutlineCount = pDoc->GetNodes().GetOutLineNds().size();
+
+ for (size_t i = 0; i < nOutlineCount && !bFound; ++i)
+ {
+ if(sParam == lcl_CreateOutlineString(i, pDoc))
+ {
+ OUString sOutlineText =
+ pDoc->getIDocumentOutlineNodes().getOutlineText(
+ i, pDoc->GetDocShell()->GetWrtShell()->GetLayout());
+ sal_Int32 nOutlineLevel = pDoc->getIDocumentOutlineNodes().getOutlineLevel(i);
+ Reference<XPropertySet> xOutline =
+ new SwXOutlineTarget(sParam, sOutlineText, nOutlineLevel);
+ aRet <<= xOutline;
+ bFound = true;
+ }
+ }
+ }
+ else if (sSuffix == "|drawingobject")
+ {
+ SwDrawModel* pModel = pDoc->getIDocumentDrawModelAccess().GetDrawModel();
+ if (pModel)
+ {
+ SdrPage* pPage = pModel->GetPage(0);
+ for (size_t i = 0; i < pPage->GetObjCount() && !bFound; ++i)
+ {
+ SdrObject* pObj = pPage->GetObj(i);
+ if (sParam == pObj->GetName())
+ {
+ Reference<XPropertySet> xDrawingObject = new SwXDrawingObjectTarget(sParam);
+ aRet <<= xDrawingObject;
+ bFound = true;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ aRet = m_xRealAccess->getByName(sParam.copy(0, sParam.getLength() - sSuffix.getLength()));
+ Reference< XInterface > xInt;
+ if(!(aRet >>= xInt))
+ throw RuntimeException("Could not retrieve property");
+ Reference< XPropertySet > xProp(xInt, UNO_QUERY);
+ aRet <<= xProp;
+ bFound = true;
+ }
+ }
+ }
+ if(!bFound)
+ throw NoSuchElementException();
+ return aRet;
+}
+
+Sequence< OUString > SwXLinkNameAccessWrapper::getElementNames()
+{
+ Sequence< OUString > aRet;
+ if(m_pxDoc)
+ {
+ if(!m_pxDoc->GetDocShell())
+ throw RuntimeException("No document shell available");
+ SwDoc* pDoc = m_pxDoc->GetDocShell()->GetDoc();
+ if (m_sLinkSuffix == "|outline")
+ {
+ const SwOutlineNodes& rOutlineNodes = pDoc->GetNodes().GetOutLineNds();
+ const size_t nOutlineCount = rOutlineNodes.size();
+ aRet.realloc(nOutlineCount);
+ OUString* pResArr = aRet.getArray();
+ for (size_t i = 0; i < nOutlineCount; ++i)
+ {
+ OUString sEntry = lcl_CreateOutlineString(i, pDoc) + "|outline";
+ pResArr[i] = sEntry;
+ }
+ }
+ else if (m_sLinkSuffix == "|drawingobject")
+ {
+ SwDrawModel* pModel = pDoc->getIDocumentDrawModelAccess().GetDrawModel();
+ if(pModel)
+ {
+ SdrPage* pPage = pModel->GetPage(0);
+ const size_t nObjCount = pPage->GetObjCount();
+ aRet.realloc(nObjCount);
+ OUString* pResArr = aRet.getArray();
+ auto j = 0;
+ for (size_t i = 0; i < nObjCount; ++i)
+ {
+ SdrObject* pObj = pPage->GetObj(i);
+ if (!pObj->GetName().isEmpty())
+ pResArr[j++] = pObj->GetName() + "|drawingobject";
+ }
+ }
+ }
+ }
+ else
+ {
+ const Sequence< OUString > aOrg = m_xRealAccess->getElementNames();
+ aRet.realloc(aOrg.getLength());
+ std::transform(aOrg.begin(), aOrg.end(), aRet.getArray(),
+ [this](const OUString& rOrg) -> OUString { return rOrg + m_sLinkSuffix; });
+ }
+ return aRet;
+}
+
+sal_Bool SwXLinkNameAccessWrapper::hasByName(const OUString& rName)
+{
+ bool bRet = false;
+ OUString sParam(rName);
+ if(sParam.getLength() > m_sLinkSuffix.getLength() )
+ {
+ std::u16string_view sCmp = sParam.subView(sParam.getLength() - m_sLinkSuffix.getLength(),
+ m_sLinkSuffix.getLength());
+ if(sCmp == m_sLinkSuffix)
+ {
+ sParam = sParam.copy(0, sParam.getLength() - m_sLinkSuffix.getLength());
+ if(m_pxDoc)
+ {
+ if(!m_pxDoc->GetDocShell())
+ throw RuntimeException("No document shell available");
+ SwDoc* pDoc = m_pxDoc->GetDocShell()->GetDoc();
+ if (m_sLinkSuffix == "|outline")
+ {
+ const size_t nOutlineCount = pDoc->GetNodes().GetOutLineNds().size();
+
+ for (size_t i = 0; i < nOutlineCount && !bRet; ++i)
+ {
+ if(sParam == lcl_CreateOutlineString(i, pDoc))
+ {
+ bRet = true;
+ }
+ }
+ }
+ else if (m_sLinkSuffix == "|drawingobject")
+ {
+ SwDrawModel* pModel = pDoc->getIDocumentDrawModelAccess().GetDrawModel();
+ if (pModel)
+ {
+ SdrPage* pPage = pModel->GetPage(0);
+ const size_t nObjCount = pPage->GetObjCount();
+ for (size_t i = 0; i < nObjCount && !bRet; ++i)
+ {
+ if (sParam == pPage->GetObj(i)->GetName())
+ bRet = true;
+ }
+ }
+ }
+ }
+ else
+ {
+ bRet = m_xRealAccess->hasByName(sParam);
+ }
+ }
+ }
+ return bRet;
+}
+
+uno::Type SwXLinkNameAccessWrapper::getElementType()
+{
+ return cppu::UnoType<XPropertySet>::get();
+}
+
+sal_Bool SwXLinkNameAccessWrapper::hasElements()
+{
+ bool bRet = false;
+ if(m_pxDoc)
+ {
+ OSL_FAIL("not implemented");
+ }
+ else
+ {
+ bRet = m_xRealAccess->hasElements();
+ }
+ return bRet;
+}
+
+Reference< XPropertySetInfo > SwXLinkNameAccessWrapper::getPropertySetInfo()
+{
+ static Reference< XPropertySetInfo > xRet = m_pPropSet->getPropertySetInfo();
+ return xRet;
+}
+
+void SwXLinkNameAccessWrapper::setPropertyValue(
+ const OUString& rPropName, const Any& )
+{
+ throw UnknownPropertyException(rPropName);
+}
+
+static Any lcl_GetDisplayBitmap(std::u16string_view sLinkSuffix)
+{
+ Any aRet;
+ if(!sLinkSuffix.empty())
+ sLinkSuffix = sLinkSuffix.substr(1);
+ OUString sImgId;
+
+ if(sLinkSuffix == u"outline")
+ sImgId = RID_BMP_NAVI_OUTLINE;
+ else if(sLinkSuffix == u"table")
+ sImgId = RID_BMP_NAVI_TABLE;
+ else if(sLinkSuffix == u"frame")
+ sImgId = RID_BMP_NAVI_FRAME;
+ else if(sLinkSuffix == u"graphic")
+ sImgId = RID_BMP_NAVI_GRAPHIC;
+ else if(sLinkSuffix == u"ole")
+ sImgId = RID_BMP_NAVI_OLE;
+ else if(sLinkSuffix.empty())
+ sImgId = RID_BMP_NAVI_BOOKMARK;
+ else if(sLinkSuffix == u"region")
+ sImgId = RID_BMP_NAVI_REGION;
+ else if(sLinkSuffix == u"drawingobject")
+ sImgId = RID_BMP_NAVI_DRAWOBJECT;
+
+ if (!sImgId.isEmpty())
+ {
+ aRet <<= VCLUnoHelper::CreateBitmap(BitmapEx(sImgId));
+ }
+ return aRet;
+}
+
+Any SwXLinkNameAccessWrapper::getPropertyValue(const OUString& rPropertyName)
+{
+ Any aRet;
+ if( rPropertyName == UNO_LINK_DISPLAY_NAME )
+ {
+ aRet <<= m_sLinkDisplayName;
+ }
+ else if( rPropertyName == UNO_LINK_DISPLAY_BITMAP )
+ {
+ aRet = lcl_GetDisplayBitmap(m_sLinkSuffix);
+ }
+ else
+ throw UnknownPropertyException(rPropertyName);
+ return aRet;
+}
+
+void SwXLinkNameAccessWrapper::addPropertyChangeListener(
+ const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
+{}
+
+void SwXLinkNameAccessWrapper::removePropertyChangeListener(
+ const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
+{}
+
+void SwXLinkNameAccessWrapper::addVetoableChangeListener(
+ const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
+{}
+
+void SwXLinkNameAccessWrapper::removeVetoableChangeListener(
+ const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
+{}
+
+Reference< XNameAccess > SwXLinkNameAccessWrapper::getLinks()
+{
+ return this;
+}
+
+OUString SwXLinkNameAccessWrapper::getImplementationName()
+{
+ return "SwXLinkNameAccessWrapper";
+}
+
+sal_Bool SwXLinkNameAccessWrapper::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXLinkNameAccessWrapper::getSupportedServiceNames()
+{
+ Sequence< OUString > aRet { "com.sun.star.document.LinkTargets" };
+ return aRet;
+}
+
+SwXOutlineTarget::SwXOutlineTarget(const OUString& rOutlineText, const OUString& rActualText,
+ const sal_Int32 nOutlineLevel) :
+ m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_LINK_TARGET)),
+ m_sOutlineText(rOutlineText),
+ m_sActualText(rActualText),
+ m_nOutlineLevel(nOutlineLevel)
+{
+}
+
+SwXOutlineTarget::~SwXOutlineTarget()
+{
+}
+
+Reference< XPropertySetInfo > SwXOutlineTarget::getPropertySetInfo()
+{
+ static Reference< XPropertySetInfo > xRet = m_pPropSet->getPropertySetInfo();
+ return xRet;
+}
+
+void SwXOutlineTarget::setPropertyValue(
+ const OUString& rPropertyName, const Any& /*aValue*/)
+{
+ throw UnknownPropertyException(rPropertyName);
+}
+
+Any SwXOutlineTarget::getPropertyValue(const OUString& rPropertyName)
+{
+ if (rPropertyName != UNO_LINK_DISPLAY_NAME && rPropertyName != "ActualOutlineName" &&
+ rPropertyName != "OutlineLevel")
+ throw UnknownPropertyException(rPropertyName);
+
+ if (rPropertyName == "ActualOutlineName")
+ return Any(m_sActualText);
+
+ if (rPropertyName == "OutlineLevel")
+ return Any(m_nOutlineLevel);
+
+ return Any(m_sOutlineText);
+}
+
+void SwXOutlineTarget::addPropertyChangeListener(
+ const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
+{
+}
+
+void SwXOutlineTarget::removePropertyChangeListener(
+ const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
+{
+}
+
+void SwXOutlineTarget::addVetoableChangeListener(
+ const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
+{
+}
+
+void SwXOutlineTarget::removeVetoableChangeListener(
+ const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
+{
+}
+
+OUString SwXOutlineTarget::getImplementationName()
+{
+ return "SwXOutlineTarget";
+}
+
+sal_Bool SwXOutlineTarget::supportsService(const OUString& ServiceName)
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+Sequence< OUString > SwXOutlineTarget::getSupportedServiceNames()
+{
+ Sequence<OUString> aRet { "com.sun.star.document.LinkTarget" };
+
+ return aRet;
+}
+
+SwXDrawingObjectTarget::SwXDrawingObjectTarget(const OUString& rDrawingObjectText) :
+ m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_LINK_TARGET)),
+ m_sDrawingObjectText(rDrawingObjectText)
+{
+}
+
+SwXDrawingObjectTarget::~SwXDrawingObjectTarget()
+{
+}
+
+Reference< XPropertySetInfo > SwXDrawingObjectTarget::getPropertySetInfo()
+{
+ static Reference< XPropertySetInfo > xRet = m_pPropSet->getPropertySetInfo();
+ return xRet;
+}
+
+void SwXDrawingObjectTarget::setPropertyValue(
+ const OUString& rPropertyName, const Any& /*aValue*/)
+{
+ throw UnknownPropertyException(rPropertyName);
+}
+
+Any SwXDrawingObjectTarget::getPropertyValue(const OUString& rPropertyName)
+{
+ if(rPropertyName != UNO_LINK_DISPLAY_NAME)
+ throw UnknownPropertyException(rPropertyName);
+
+ return Any(m_sDrawingObjectText);
+}
+
+void SwXDrawingObjectTarget::addPropertyChangeListener(
+ const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
+{
+}
+
+void SwXDrawingObjectTarget::removePropertyChangeListener(
+ const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
+{
+}
+
+void SwXDrawingObjectTarget::addVetoableChangeListener(
+ const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
+{
+}
+
+void SwXDrawingObjectTarget::removeVetoableChangeListener(
+ const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
+{
+}
+
+OUString SwXDrawingObjectTarget::getImplementationName()
+{
+ return "SwXDrawingObjectTarget";
+}
+
+sal_Bool SwXDrawingObjectTarget::supportsService(const OUString& ServiceName)
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+Sequence< OUString > SwXDrawingObjectTarget::getSupportedServiceNames()
+{
+ Sequence<OUString> aRet { "com.sun.star.document.LinkTarget" };
+
+ return aRet;
+}
+
+SwXDocumentPropertyHelper::SwXDocumentPropertyHelper(SwDoc& rDoc) :
+SvxUnoForbiddenCharsTable ( rDoc.getIDocumentSettingAccess().getForbiddenCharacterTable() )
+,m_pDoc(&rDoc)
+{
+}
+
+SwXDocumentPropertyHelper::~SwXDocumentPropertyHelper()
+{
+}
+
+Reference<XInterface> SwXDocumentPropertyHelper::GetDrawTable(SwCreateDrawTable nWhich)
+{
+ Reference<XInterface> xRet;
+ if(m_pDoc)
+ {
+ switch(nWhich)
+ {
+ // #i52858#
+ // assure that Draw model is created, if it doesn't exist.
+ case SwCreateDrawTable::Dash :
+ if(!m_xDashTable.is())
+ m_xDashTable = SvxUnoDashTable_createInstance( m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
+ xRet = m_xDashTable;
+ break;
+ case SwCreateDrawTable::Gradient :
+ if(!m_xGradientTable.is())
+ m_xGradientTable = SvxUnoGradientTable_createInstance( m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
+ xRet = m_xGradientTable;
+ break;
+ case SwCreateDrawTable::Hatch :
+ if(!m_xHatchTable.is())
+ m_xHatchTable = SvxUnoHatchTable_createInstance( m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
+ xRet = m_xHatchTable;
+ break;
+ case SwCreateDrawTable::Bitmap :
+ if(!m_xBitmapTable.is())
+ m_xBitmapTable = SvxUnoBitmapTable_createInstance( m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
+ xRet = m_xBitmapTable;
+ break;
+ case SwCreateDrawTable::TransGradient:
+ if(!m_xTransGradientTable.is())
+ m_xTransGradientTable = SvxUnoTransGradientTable_createInstance( m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
+ xRet = m_xTransGradientTable;
+ break;
+ case SwCreateDrawTable::Marker :
+ if(!m_xMarkerTable.is())
+ m_xMarkerTable = SvxUnoMarkerTable_createInstance( m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
+ xRet = m_xMarkerTable;
+ break;
+ case SwCreateDrawTable::Defaults:
+ if(!m_xDrawDefaults.is())
+ m_xDrawDefaults = static_cast<cppu::OWeakObject*>(new SwSvxUnoDrawPool(*m_pDoc));
+ xRet = m_xDrawDefaults;
+ break;
+#if OSL_DEBUG_LEVEL > 0
+ default: OSL_FAIL("which table?");
+#endif
+ }
+ }
+ return xRet;
+}
+
+void SwXDocumentPropertyHelper::Invalidate()
+{
+ m_xDashTable = nullptr;
+ m_xGradientTable = nullptr;
+ m_xHatchTable = nullptr;
+ m_xBitmapTable = nullptr;
+ m_xTransGradientTable = nullptr;
+ m_xMarkerTable = nullptr;
+ m_xDrawDefaults = nullptr;
+ m_pDoc = nullptr;
+ SvxUnoForbiddenCharsTable::mxForbiddenChars.reset();
+}
+
+void SwXDocumentPropertyHelper::onChange()
+{
+ if(m_pDoc)
+ m_pDoc->getIDocumentState().SetModified();
+}
+
+SwViewOptionAdjust_Impl::SwViewOptionAdjust_Impl(
+ SwViewShell& rSh, const SwViewOption &rViewOptions)
+ : m_pShell(&rSh)
+ , m_aOldViewOptions( rViewOptions )
+{
+}
+
+SwViewOptionAdjust_Impl::~SwViewOptionAdjust_Impl()
+{
+ if (m_pShell)
+ {
+ m_pShell->ApplyViewOptions( m_aOldViewOptions );
+ }
+}
+
+void
+SwViewOptionAdjust_Impl::AdjustViewOptions(SwPrintData const*const pPrtOptions, bool setShowPlaceHoldersInPDF)
+{
+ // to avoid unnecessary reformatting the view options related to the content
+ // below should only change if necessary, that is if respective content is present
+ const bool bContainsHiddenChars = m_pShell->GetDoc()->ContainsHiddenChars();
+ const SwFieldType* pFieldType = m_pShell->GetDoc()->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::HiddenText );
+ const bool bContainsHiddenFields = pFieldType && pFieldType->HasWriterListeners();
+ pFieldType = m_pShell->GetDoc()->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::HiddenPara );
+ const bool bContainsHiddenParagraphs = pFieldType && pFieldType->HasWriterListeners();
+ pFieldType = m_pShell->GetDoc()->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::JumpEdit );
+ const bool bContainsPlaceHolders = pFieldType && pFieldType->HasWriterListeners();
+ const bool bContainsFields = m_pShell->IsAnyFieldInDoc();
+
+ SwViewOption aRenderViewOptions( m_aOldViewOptions );
+
+ // disable anything in the view that should not be printed (or exported to PDF) by default
+ // (see also dialog "Tools/Options - StarOffice Writer - Formatting Aids"
+ // in section "Display of ...")
+ aRenderViewOptions.SetParagraph( false ); // paragraph end
+ aRenderViewOptions.SetSoftHyph( false ); // aka custom hyphens
+ aRenderViewOptions.SetBlank( false ); // spaces
+ aRenderViewOptions.SetHardBlank( false ); // non-breaking spaces
+ aRenderViewOptions.SetTab( false ); // tabs
+ aRenderViewOptions.SetShowBookmarks( false ); // bookmarks
+ aRenderViewOptions.SetLineBreak( false ); // breaks (type 1)
+ aRenderViewOptions.SetPageBreak( false ); // breaks (type 2)
+ aRenderViewOptions.SetColumnBreak( false ); // breaks (type 3)
+ bool bVal = pPrtOptions && pPrtOptions->m_bPrintHiddenText;
+ if (bContainsHiddenChars)
+ aRenderViewOptions.SetShowHiddenChar( bVal ); // hidden text
+ if (bContainsHiddenFields)
+ aRenderViewOptions.SetShowHiddenField( bVal );
+ if (bContainsHiddenParagraphs)
+ aRenderViewOptions.SetShowHiddenPara( bVal );
+
+ if (bContainsPlaceHolders)
+ {
+ // should always be printed in PDF export!
+ bVal = !pPrtOptions ? setShowPlaceHoldersInPDF : pPrtOptions->m_bPrintTextPlaceholder;
+ aRenderViewOptions.SetShowPlaceHolderFields( bVal );
+ }
+
+ if (bContainsFields)
+ aRenderViewOptions.SetFieldName( false );
+
+ // we need to set this flag in order to get to see the visible effect of
+ // some of the above settings (needed for correct rendering)
+ aRenderViewOptions.SetViewMetaChars( true );
+
+ if (m_aOldViewOptions != aRenderViewOptions) // check if reformatting is necessary
+ {
+ aRenderViewOptions.SetPrinting( pPrtOptions != nullptr );
+ m_pShell->ApplyViewOptions( aRenderViewOptions );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/uno/unotxvw.cxx b/sw/source/uibase/uno/unotxvw.cxx
new file mode 100644
index 000000000..7a4751b9d
--- /dev/null
+++ b/sw/source/uibase/uno/unotxvw.cxx
@@ -0,0 +1,1784 @@
+/* -*- 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 <viscrs.hxx>
+#include <o3tl/any.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <cmdid.h>
+#include <docsh.hxx>
+#include <rubylist.hxx>
+#include <doc.hxx>
+#include <IDocumentDeviceAccess.hxx>
+#include <unotxvw.hxx>
+#include <unodispatch.hxx>
+#include <unomap.hxx>
+#include <unoprnms.hxx>
+#include <view.hxx>
+#include <viewopt.hxx>
+#include <unomod.hxx>
+#include <unoframe.hxx>
+#include <unocrsr.hxx>
+#include <wrtsh.hxx>
+#include <unotbl.hxx>
+#include <svx/fmshell.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdouno.hxx>
+#include <editeng/pbinitem.hxx>
+#include <pagedesc.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/request.hxx>
+#include <frmatr.hxx>
+#include <IMark.hxx>
+#include <unodraw.hxx>
+#include <svx/svdpagv.hxx>
+#include <ndtxt.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/drawing/ShapeCollection.hpp>
+#include <editeng/outliner.hxx>
+#include <editeng/editview.hxx>
+#include <unoparagraph.hxx>
+#include <unocrsrhelper.hxx>
+#include <unotextrange.hxx>
+#include <sfx2/docfile.hxx>
+#include <swdtflvr.hxx>
+#include <rootfrm.hxx>
+#include <edtwin.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/profilezone.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <tools/UnitConversion.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::view;
+using namespace ::com::sun::star::frame;
+
+using ::com::sun::star::util::URL;
+
+SwXTextView::SwXTextView(SwView* pSwView) :
+ SfxBaseController(pSwView),
+ m_SelChangedListeners(m_aMutex),
+ m_pView(pSwView),
+ m_pPropSet( aSwMapProvider.GetPropertySet( PROPERTY_MAP_TEXT_VIEW ) )
+{
+
+}
+
+SwXTextView::~SwXTextView()
+{
+ Invalidate();
+}
+
+void SwXTextView::Invalidate()
+{
+ if(mxViewSettings.is())
+ {
+ comphelper::ChainablePropertySet *pSettings = static_cast < comphelper::ChainablePropertySet * > ( mxViewSettings.get() );
+ static_cast < SwXViewSettings* > ( pSettings )->Invalidate();
+ mxViewSettings.clear();
+ }
+ if(mxTextViewCursor.is())
+ {
+ text::XTextViewCursor* pCursor = mxTextViewCursor.get();
+ static_cast<SwXTextViewCursor*>(pCursor)->Invalidate();
+ mxTextViewCursor.clear();
+ }
+
+ osl_atomic_increment(&m_refCount); //prevent second d'tor call
+
+ {
+ uno::Reference<uno::XInterface> const xInt(static_cast<
+ cppu::OWeakObject*>(static_cast<SfxBaseController*>(this)));
+ lang::EventObject aEvent(xInt);
+ m_SelChangedListeners.disposeAndClear(aEvent);
+ }
+
+ osl_atomic_decrement(&m_refCount);
+ m_pView = nullptr;
+}
+
+Sequence< uno::Type > SAL_CALL SwXTextView::getTypes( )
+{
+ return cppu::OTypeCollection(
+ cppu::UnoType<XSelectionSupplier>::get(),
+ cppu::UnoType<XServiceInfo>::get(),
+ cppu::UnoType<XFormLayerAccess>::get(),
+ cppu::UnoType<XTextViewCursorSupplier>::get(),
+ cppu::UnoType<XTextViewTextRangeSupplier>::get(),
+ cppu::UnoType<XViewSettingsSupplier>::get(),
+ cppu::UnoType<XRubySelection>::get(),
+ cppu::UnoType<XPropertySet>::get(),
+ cppu::UnoType<datatransfer::XTransferableSupplier>::get(),
+ cppu::UnoType<datatransfer::XTransferableTextSupplier>::get(),
+ SfxBaseController::getTypes()
+ ).getTypes();
+}
+
+Sequence< sal_Int8 > SAL_CALL SwXTextView::getImplementationId( )
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+void SAL_CALL SwXTextView::acquire( )noexcept
+{
+ SfxBaseController::acquire();
+}
+
+void SAL_CALL SwXTextView::release( )noexcept
+{
+ SfxBaseController::release();
+}
+
+uno::Any SAL_CALL SwXTextView::queryInterface( const uno::Type& aType )
+{
+ uno::Any aRet;
+ if(aType == cppu::UnoType<view::XSelectionSupplier>::get())
+ {
+ uno::Reference<view::XSelectionSupplier> xRet = this;
+ aRet <<= xRet;
+ }
+ else if(aType == cppu::UnoType<lang::XServiceInfo>::get())
+ {
+ uno::Reference<lang::XServiceInfo> xRet = this;
+ aRet <<= xRet;
+ }
+ else if(aType == cppu::UnoType<view::XControlAccess>::get())
+ {
+ uno::Reference<view::XControlAccess> xRet = this;
+ aRet <<= xRet;
+ }
+ else if(aType == cppu::UnoType<view::XFormLayerAccess>::get())
+ {
+ uno::Reference<view::XFormLayerAccess> xRet = this;
+ aRet <<= xRet;
+ }
+ else if(aType == cppu::UnoType<text::XTextViewCursorSupplier>::get())
+ {
+ uno::Reference<text::XTextViewCursorSupplier> xRet = this;
+ aRet <<= xRet;
+ }
+ else if (aType == cppu::UnoType<text::XTextViewTextRangeSupplier>::get())
+ {
+ uno::Reference<text::XTextViewTextRangeSupplier> xRet = this;
+ aRet <<= xRet;
+ }
+ else if(aType == cppu::UnoType<view::XViewSettingsSupplier>::get())
+ {
+ uno::Reference<view::XViewSettingsSupplier> xRet = this;
+ aRet <<= xRet;
+ }
+ else if(aType == cppu::UnoType<XRubySelection>::get())
+ {
+ uno::Reference<XRubySelection> xRet = this;
+ aRet <<= xRet;
+ }
+ else if(aType == cppu::UnoType<XPropertySet>::get())
+ {
+ uno::Reference<XPropertySet> xRet = this;
+ aRet <<= xRet;
+ }
+ else if(aType == cppu::UnoType<datatransfer::XTransferableSupplier>::get())
+ {
+ uno::Reference<datatransfer::XTransferableSupplier> xRet = this;
+ aRet <<= xRet;
+ }
+ else if(aType == cppu::UnoType<datatransfer::XTransferableTextSupplier>::get())
+ {
+ uno::Reference<datatransfer::XTransferableTextSupplier> xRet = this;
+ aRet <<= xRet;
+ }
+ else
+ aRet = SfxBaseController::queryInterface(aType);
+ return aRet;
+}
+
+sal_Bool SwXTextView::select(const uno::Any& aInterface)
+{
+ SolarMutexGuard aGuard;
+
+ uno::Reference< uno::XInterface > xInterface;
+ if (!GetView() || !(aInterface >>= xInterface))
+ {
+ return false;
+ }
+
+ SwWrtShell& rSh = GetView()->GetWrtShell();
+ SwDoc* pDoc = GetView()->GetDocShell()->GetDoc();
+ std::vector<SdrObject *> sdrObjects;
+ uno::Reference<awt::XControlModel> const xCtrlModel(xInterface,
+ UNO_QUERY);
+ if (xCtrlModel.is())
+ {
+ uno::Reference<awt::XControl> xControl;
+ SdrObject *const pSdrObject = GetControl(xCtrlModel, xControl);
+ if (pSdrObject) // hmm... needs view to verify it's in right doc...
+ {
+ sdrObjects.push_back(pSdrObject);
+ }
+ }
+ else
+ {
+ SwPaM * pPaM(nullptr);
+ std::pair<OUString, FlyCntType> frame;
+ OUString tableName;
+ SwUnoTableCursor const* pTableCursor(nullptr);
+ ::sw::mark::IMark const* pMark(nullptr);
+ SwUnoCursorHelper::GetSelectableFromAny(xInterface, *pDoc,
+ pPaM, frame, tableName, pTableCursor, pMark, sdrObjects);
+ if (pPaM)
+ {
+ rSh.EnterStdMode();
+ rSh.SetSelection(*pPaM);
+ // the pPaM has been copied - delete it
+ while (pPaM->GetNext() != pPaM)
+ delete pPaM->GetNext();
+ delete pPaM;
+ return true;
+ }
+ else if (!frame.first.isEmpty())
+ {
+ bool const bSuccess(rSh.GotoFly(frame.first, frame.second));
+ if (bSuccess)
+ {
+ rSh.HideCursor();
+ rSh.EnterSelFrameMode();
+ }
+ return true;
+ }
+ else if (!tableName.isEmpty())
+ {
+ rSh.EnterStdMode();
+ rSh.GotoTable(tableName);
+ return true;
+ }
+ else if (pTableCursor)
+ {
+ UnoActionRemoveContext const aContext(*pTableCursor);
+ rSh.EnterStdMode();
+ rSh.SetSelection(*pTableCursor);
+ return true;
+ }
+ else if (pMark)
+ {
+ rSh.EnterStdMode();
+ rSh.GotoMark(pMark);
+ return true;
+ }
+ // sdrObjects handled below
+ }
+ bool bRet(false);
+ if (!sdrObjects.empty())
+ {
+
+ SdrView *const pDrawView = rSh.GetDrawView();
+ SdrPageView *const pPV = pDrawView->GetSdrPageView();
+
+ pDrawView->SdrEndTextEdit();
+ pDrawView->UnmarkAll();
+
+ for (SdrObject* pSdrObject : sdrObjects)
+ {
+ // GetSelectableFromAny did not check pSdrObject is in right doc!
+ if (pPV && pSdrObject->getSdrPageFromSdrObject() == pPV->GetPage())
+ {
+ pDrawView->MarkObj(pSdrObject, pPV);
+ bRet = true;
+ }
+ }
+
+ // tdf#112696 if we selected every individual element of a group, then
+ // select that group instead
+ const SdrMarkList &rMrkList = pDrawView->GetMarkedObjectList();
+ size_t nMarkCount = rMrkList.GetMarkCount();
+ if (nMarkCount > 1)
+ {
+ SdrObject* pObject = rMrkList.GetMark(0)->GetMarkedSdrObj();
+ SdrObject* pGroupParent = pObject->getParentSdrObjectFromSdrObject();
+ for (size_t i = 1; i < nMarkCount; ++i)
+ {
+ pObject = rMrkList.GetMark(i)->GetMarkedSdrObj();
+ SdrObject* pParent = pObject->getParentSdrObjectFromSdrObject();
+ if (pParent != pGroupParent)
+ {
+ pGroupParent = nullptr;
+ break;
+ }
+ }
+
+ if (pGroupParent && pGroupParent->IsGroupObject() &&
+ pGroupParent->getChildrenOfSdrObject()->GetObjCount() == nMarkCount)
+ {
+ pDrawView->UnmarkAll();
+ pDrawView->MarkObj(pGroupParent, pPV);
+ }
+ }
+ }
+ return bRet;
+}
+
+uno::Any SwXTextView::getSelection()
+{
+ SolarMutexGuard aGuard;
+ uno::Reference< uno::XInterface > aRef;
+ if(GetView())
+ {
+ //force immediat shell update
+ m_pView->StopShellTimer();
+ //Generating an interface from the current selection.
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ ShellMode eSelMode = m_pView->GetShellMode();
+ switch(eSelMode)
+ {
+ case ShellMode::TableText :
+ {
+ if(rSh.GetTableCursor())
+ {
+ OSL_ENSURE(rSh.GetTableFormat(), "not a table format?");
+ uno::Reference< text::XTextTableCursor > xCursor = new SwXTextTableCursor(*rSh.GetTableFormat(),
+ rSh.GetTableCursor());
+ aRef.set(xCursor, uno::UNO_QUERY);
+ break;
+ }
+ [[fallthrough]];
+ // without a table selection the text will be delivered
+ }
+ case ShellMode::ListText :
+ case ShellMode::TableListText:
+ case ShellMode::Text :
+ {
+ uno::Reference< container::XIndexAccess > xPos = SwXTextRanges::Create(rSh.GetCursor());
+ aRef.set(xPos, uno::UNO_QUERY);
+ }
+ break;
+ case ShellMode::Frame :
+ {
+ SwFrameFormat *const pFormat = rSh.GetFlyFrameFormat();
+ if (pFormat)
+ {
+ aRef = SwXTextFrame::CreateXTextFrame(
+ *pFormat->GetDoc(), pFormat);
+ }
+ }
+ break;
+ case ShellMode::Graphic :
+ {
+ SwFrameFormat *const pFormat = rSh.GetFlyFrameFormat();
+ if (pFormat)
+ {
+ aRef = SwXTextGraphicObject::CreateXTextGraphicObject(
+ *pFormat->GetDoc(), pFormat);
+ }
+ }
+ break;
+ case ShellMode::Object :
+ {
+ SwFrameFormat *const pFormat = rSh.GetFlyFrameFormat();
+ if (pFormat)
+ {
+ aRef = SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
+ *pFormat->GetDoc(), pFormat);
+ }
+ }
+ break;
+ case ShellMode::Draw :
+ case ShellMode::DrawForm :
+ case ShellMode::DrawText :
+ case ShellMode::Bezier :
+ {
+ uno::Reference< drawing::XShapes > xShCol = drawing::ShapeCollection::create(
+ comphelper::getProcessComponentContext());
+
+ const SdrMarkList& rMarkList = rSh.GetDrawView()->GetMarkedObjectList();
+ for(size_t i = 0; i < rMarkList.GetMarkCount(); ++i)
+ {
+ SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
+ uno::Reference<drawing::XShape> xShape = SwFmDrawPage::GetShape( pObj );
+ xShCol->add(xShape);
+ }
+ aRef.set(xShCol, uno::UNO_QUERY);
+ }
+ break;
+ default:;//prevent warning
+ }
+ }
+ uno::Any aRet(&aRef, cppu::UnoType<uno::XInterface>::get());
+ return aRet;
+}
+
+void SwXTextView::addSelectionChangeListener(
+ const uno::Reference< view::XSelectionChangeListener > & rxListener)
+{
+ SolarMutexGuard aGuard;
+ m_SelChangedListeners.addInterface(rxListener);
+}
+
+void SwXTextView::removeSelectionChangeListener(
+ const uno::Reference< view::XSelectionChangeListener > & rxListener)
+{
+ SolarMutexGuard aGuard;
+ m_SelChangedListeners.removeInterface(rxListener);
+}
+
+SdrObject* SwXTextView::GetControl(
+ const uno::Reference< awt::XControlModel > & xModel,
+ uno::Reference< awt::XControl >& xToFill )
+{
+ SwView* pView2 = GetView();
+ FmFormShell* pFormShell = pView2 ? pView2->GetFormShell() : nullptr;
+ SdrView* pDrawView = pView2 ? pView2->GetDrawView() : nullptr;
+ vcl::Window* pWindow = pView2 ? pView2->GetWrtShell().GetWin() : nullptr;
+
+ OSL_ENSURE( pFormShell && pDrawView && pWindow, "SwXTextView::GetControl: how could I?" );
+
+ SdrObject* pControl = nullptr;
+ if ( pFormShell && pDrawView && pWindow )
+ pControl = pFormShell->GetFormControl( xModel, *pDrawView, *pWindow->GetOutDev(), xToFill );
+ return pControl;
+}
+
+uno::Reference< awt::XControl > SwXTextView::getControl(const uno::Reference< awt::XControlModel > & xModel)
+{
+ SolarMutexGuard aGuard;
+ uno::Reference< awt::XControl > xRet;
+ GetControl(xModel, xRet);
+ return xRet;
+}
+
+uno::Reference< form::runtime::XFormController > SAL_CALL SwXTextView::getFormController( const uno::Reference< form::XForm >& Form )
+{
+ SolarMutexGuard aGuard;
+
+ SwView* pView2 = GetView();
+ FmFormShell* pFormShell = pView2 ? pView2->GetFormShell() : nullptr;
+ SdrView* pDrawView = pView2 ? pView2->GetDrawView() : nullptr;
+ vcl::Window* pWindow = pView2 ? pView2->GetWrtShell().GetWin() : nullptr;
+ OSL_ENSURE( pFormShell && pDrawView && pWindow, "SwXTextView::getFormController: how could I?" );
+
+ uno::Reference< form::runtime::XFormController > xController;
+ if ( pFormShell && pDrawView && pWindow )
+ xController = FmFormShell::GetFormController( Form, *pDrawView, *pWindow->GetOutDev() );
+ return xController;
+}
+
+sal_Bool SAL_CALL SwXTextView::isFormDesignMode( )
+{
+ SolarMutexGuard aGuard;
+ SwView* pView2 = GetView();
+ FmFormShell* pFormShell = pView2 ? pView2->GetFormShell() : nullptr;
+ return !pFormShell || pFormShell->IsDesignMode();
+}
+
+void SAL_CALL SwXTextView::setFormDesignMode( sal_Bool DesignMode )
+{
+ SolarMutexGuard aGuard;
+ SwView* pView2 = GetView();
+ FmFormShell* pFormShell = pView2 ? pView2->GetFormShell() : nullptr;
+ if ( pFormShell )
+ pFormShell->SetDesignMode( DesignMode );
+}
+
+uno::Reference< text::XTextViewCursor > SwXTextView::getViewCursor()
+{
+ SolarMutexGuard aGuard;
+ comphelper::ProfileZone aZone("getViewCursor");
+ if(!GetView())
+ throw uno::RuntimeException();
+
+ if(!mxTextViewCursor.is())
+ {
+ mxTextViewCursor = new SwXTextViewCursor(GetView());
+ }
+ return mxTextViewCursor;
+}
+
+uno::Reference<text::XTextRange>
+SwXTextView::createTextRangeByPixelPosition(const awt::Point& rPixelPosition)
+{
+ SolarMutexGuard aGuard;
+
+ Point aPixelPoint(rPixelPosition.X, rPixelPosition.Y);
+ if (!m_pView)
+ throw RuntimeException();
+
+ Point aLogicPoint = m_pView->GetEditWin().PixelToLogic(aPixelPoint);
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ SwPosition aPosition(*rSh.GetCurrentShellCursor().GetPoint());
+ rSh.GetLayout()->GetModelPositionForViewPoint(&aPosition, aLogicPoint);
+ uno::Reference<text::XTextRange> xRet
+ = SwXTextRange::CreateXTextRange(*rSh.GetDoc(), aPosition, /*pMark=*/nullptr);
+
+ return xRet;
+}
+
+uno::Reference< beans::XPropertySet > SwXTextView::getViewSettings()
+{
+ SolarMutexGuard aGuard;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ if(!mxViewSettings.is())
+ {
+ mxViewSettings = new SwXViewSettings( m_pView );
+ }
+
+ return mxViewSettings;
+}
+
+Sequence< Sequence< PropertyValue > > SwXTextView::getRubyList( sal_Bool /*bAutomatic*/ )
+{
+ SolarMutexGuard aGuard;
+
+ if(!GetView())
+ throw RuntimeException();
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ ShellMode eSelMode = m_pView->GetShellMode();
+ if (eSelMode != ShellMode::ListText &&
+ eSelMode != ShellMode::TableListText &&
+ eSelMode != ShellMode::TableText &&
+ eSelMode != ShellMode::Text )
+ return Sequence< Sequence< PropertyValue > > ();
+
+ SwRubyList aList;
+
+ const sal_uInt16 nCount = SwDoc::FillRubyList( *rSh.GetCursor(), aList );
+ Sequence< Sequence< PropertyValue > > aRet(nCount);
+ Sequence< PropertyValue >* pRet = aRet.getArray();
+ OUString aString;
+ for(sal_uInt16 n = 0; n < nCount; n++)
+ {
+ const SwRubyListEntry* pEntry = aList[n].get();
+
+ const OUString& rEntryText = pEntry->GetText();
+ const SwFormatRuby& rAttr = pEntry->GetRubyAttr();
+
+ pRet[n].realloc(6);
+ PropertyValue* pValues = pRet[n].getArray();
+ pValues[0].Name = UNO_NAME_RUBY_BASE_TEXT;
+ pValues[0].Value <<= rEntryText;
+ pValues[1].Name = UNO_NAME_RUBY_TEXT;
+ pValues[1].Value <<= rAttr.GetText();
+ pValues[2].Name = UNO_NAME_RUBY_CHAR_STYLE_NAME;
+ SwStyleNameMapper::FillProgName(rAttr.GetCharFormatName(), aString, SwGetPoolIdFromName::ChrFmt );
+ pValues[2].Value <<= aString;
+ pValues[3].Name = UNO_NAME_RUBY_ADJUST;
+ pValues[3].Value <<= static_cast<sal_Int16>(rAttr.GetAdjustment());
+ pValues[4].Name = UNO_NAME_RUBY_IS_ABOVE;
+ pValues[4].Value <<= !rAttr.GetPosition();
+ pValues[5].Name = UNO_NAME_RUBY_POSITION;
+ pValues[5].Value <<= rAttr.GetPosition();
+ }
+ return aRet;
+}
+
+void SAL_CALL SwXTextView::setRubyList(
+ const Sequence< Sequence< PropertyValue > >& rRubyList, sal_Bool /*bAutomatic*/ )
+{
+ SolarMutexGuard aGuard;
+
+ if(!GetView() || !rRubyList.hasElements())
+ throw RuntimeException();
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ ShellMode eSelMode = m_pView->GetShellMode();
+ if (eSelMode != ShellMode::ListText &&
+ eSelMode != ShellMode::TableListText &&
+ eSelMode != ShellMode::TableText &&
+ eSelMode != ShellMode::Text )
+ throw RuntimeException();
+
+ SwRubyList aList;
+
+ for(const Sequence<PropertyValue>& rPropList : rRubyList)
+ {
+ std::unique_ptr<SwRubyListEntry> pEntry(new SwRubyListEntry);
+ OUString sTmp;
+ for(const PropertyValue& rProperty : rPropList)
+ {
+ if(rProperty.Name == UNO_NAME_RUBY_BASE_TEXT)
+ {
+ rProperty.Value >>= sTmp;
+ pEntry->SetText(sTmp);
+ }
+ else if(rProperty.Name == UNO_NAME_RUBY_TEXT)
+ {
+ rProperty.Value >>= sTmp;
+ pEntry->GetRubyAttr().SetText(sTmp);
+ }
+ else if(rProperty.Name == UNO_NAME_RUBY_CHAR_STYLE_NAME)
+ {
+ if(rProperty.Value >>= sTmp)
+ {
+ OUString sName;
+ SwStyleNameMapper::FillUIName(sTmp, sName, SwGetPoolIdFromName::ChrFmt );
+ const sal_uInt16 nPoolId = sName.isEmpty() ? 0
+ : SwStyleNameMapper::GetPoolIdFromUIName(sName,
+ SwGetPoolIdFromName::ChrFmt );
+
+ pEntry->GetRubyAttr().SetCharFormatName( sName );
+ pEntry->GetRubyAttr().SetCharFormatId( nPoolId );
+ }
+ }
+ else if(rProperty.Name == UNO_NAME_RUBY_ADJUST)
+ {
+ sal_Int16 nTmp = 0;
+ if(rProperty.Value >>= nTmp)
+ pEntry->GetRubyAttr().SetAdjustment(static_cast<css::text::RubyAdjust>(nTmp));
+ }
+ else if(rProperty.Name == UNO_NAME_RUBY_IS_ABOVE)
+ {
+ bool bValue = !rProperty.Value.hasValue() ||
+ *o3tl::doAccess<bool>(rProperty.Value);
+ pEntry->GetRubyAttr().SetPosition(bValue ? 0 : 1);
+ }
+ else if(rProperty.Name == UNO_NAME_RUBY_POSITION)
+ {
+ sal_Int16 nTmp = 0;
+ if(rProperty.Value >>= nTmp)
+ pEntry->GetRubyAttr().SetPosition( nTmp );
+ }
+ }
+ aList.push_back(std::move(pEntry));
+ }
+ SwDoc* pDoc = m_pView->GetDocShell()->GetDoc();
+ pDoc->SetRubyList( *rSh.GetCursor(), aList );
+}
+
+SfxObjectShellLock SwXTextView::BuildTmpSelectionDoc()
+{
+ SwWrtShell& rOldSh = m_pView->GetWrtShell();
+ SfxPrinter *pPrt = rOldSh.getIDocumentDeviceAccess().getPrinter( false );
+ SwDocShell* pDocSh;
+ SfxObjectShellLock xDocSh( pDocSh = new SwDocShell(SfxObjectCreateMode::STANDARD) );
+ xDocSh->DoInitNew();
+ SwDoc *const pTempDoc( pDocSh->GetDoc() );
+ // #i103634#, #i112425#: do not expand numbering and fields on PDF export
+ pTempDoc->SetClipBoard(true);
+ rOldSh.FillPrtDoc(*pTempDoc, pPrt);
+ SfxViewFrame* pDocFrame = SfxViewFrame::LoadHiddenDocument( *xDocSh, SFX_INTERFACE_NONE );
+ SwView* pDocView = static_cast<SwView*>( pDocFrame->GetViewShell() );
+ pDocView->AttrChangedNotify(nullptr);//So that SelectShell is called.
+ SwWrtShell* pSh = pDocView->GetWrtShellPtr();
+
+ IDocumentDeviceAccess& rIDDA = pSh->getIDocumentDeviceAccess();
+ SfxPrinter* pTempPrinter = rIDDA.getPrinter( true );
+
+ const SwPageDesc& rCurPageDesc = rOldSh.GetPageDesc(rOldSh.GetCurPageDesc());
+
+ IDocumentDeviceAccess& rIDDA_old = rOldSh.getIDocumentDeviceAccess();
+
+ if( rIDDA_old.getPrinter( false ) )
+ {
+ rIDDA.setJobsetup( *rIDDA_old.getJobsetup() );
+ //#69563# if it isn't the same printer then the pointer has been invalidated!
+ pTempPrinter = rIDDA.getPrinter( true );
+ }
+
+ pTempPrinter->SetPaperBin(rCurPageDesc.GetMaster().GetPaperBin().GetValue());
+
+ return xDocSh;
+}
+
+void SwXTextView::NotifySelChanged()
+{
+ OSL_ENSURE( m_pView, "view is missing" );
+
+ uno::Reference<uno::XInterface> const xInt(
+ static_cast<cppu::OWeakObject*>(static_cast<SfxBaseController*>(this)));
+
+ lang::EventObject const aEvent(xInt);
+ m_SelChangedListeners.notifyEach(
+ &view::XSelectionChangeListener::selectionChanged, aEvent);
+}
+
+void SwXTextView::NotifyDBChanged()
+{
+ URL aURL;
+ aURL.Complete = OUString::createFromAscii(SwXDispatch::GetDBChangeURL());
+
+ m_SelChangedListeners.forEach(
+ [&aURL] (const uno::Reference<XSelectionChangeListener>& xListener)
+ {
+ uno::Reference<XDispatch> xDispatch(xListener, UNO_QUERY);
+ if (xDispatch)
+ xDispatch->dispatch(aURL, {});
+ });
+}
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL SwXTextView::getPropertySetInfo( )
+{
+ SolarMutexGuard aGuard;
+ static uno::Reference< XPropertySetInfo > aRef = m_pPropSet->getPropertySetInfo();
+ return aRef;
+}
+
+void SAL_CALL SwXTextView::setPropertyValue(
+ const OUString& rPropertyName, const uno::Any& rValue )
+{
+ SolarMutexGuard aGuard;
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if (!pEntry)
+ throw UnknownPropertyException(rPropertyName);
+ else if (pEntry->nFlags & PropertyAttribute::READONLY)
+ throw PropertyVetoException();
+ else
+ {
+ switch (pEntry->nWID)
+ {
+ case WID_IS_HIDE_SPELL_MARKS :
+ // deprecated #i91949
+ break;
+ case WID_IS_CONSTANT_SPELLCHECK :
+ {
+ bool bVal = false;
+ const SwViewOption *pOpt = m_pView->GetWrtShell().GetViewOptions();
+ if (!pOpt || !(rValue >>= bVal))
+ throw RuntimeException();
+ SwViewOption aNewOpt( *pOpt );
+ if (pEntry->nWID == WID_IS_CONSTANT_SPELLCHECK)
+ aNewOpt.SetOnlineSpell(bVal);
+ m_pView->GetWrtShell().ApplyViewOptions( aNewOpt );
+ }
+ break;
+ default :
+ OSL_FAIL("unknown WID");
+ }
+ }
+}
+
+uno::Any SAL_CALL SwXTextView::getPropertyValue(
+ const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+
+ Any aRet;
+
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if (!pEntry)
+ throw UnknownPropertyException(rPropertyName);
+
+ sal_Int16 nWID = pEntry->nWID;
+ switch (nWID)
+ {
+ case WID_PAGE_COUNT :
+ case WID_LINE_COUNT :
+ {
+ // format document completely in order to get meaningful
+ // values for page count and line count
+ m_pView->GetWrtShell().CalcLayout();
+
+ sal_Int32 nCount = -1;
+ if (nWID == WID_PAGE_COUNT)
+ nCount = m_pView->GetWrtShell().GetPageCount();
+ else // WID_LINE_COUNT
+ nCount = m_pView->GetWrtShell().GetLineCount();
+ aRet <<= nCount;
+ }
+ break;
+ case WID_IS_HIDE_SPELL_MARKS :
+ // deprecated #i91949
+ break;
+ case WID_IS_CONSTANT_SPELLCHECK :
+ {
+ const SwViewOption *pOpt = m_pView->GetWrtShell().GetViewOptions();
+ if (!pOpt)
+ throw RuntimeException();
+ aRet <<= bool(pOpt->GetCoreOptions() & ViewOptFlags1::OnlineSpell);
+ }
+ break;
+ default :
+ OSL_FAIL("unknown WID");
+ }
+
+ return aRet;
+}
+
+void SAL_CALL SwXTextView::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*rxListener*/ )
+{
+ OSL_FAIL("not implemented");
+}
+
+void SAL_CALL SwXTextView::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*rxListener*/ )
+{
+ OSL_FAIL("not implemented");
+}
+
+void SAL_CALL SwXTextView::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*rxListener*/ )
+{
+ OSL_FAIL("not implemented");
+}
+
+void SAL_CALL SwXTextView::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*rxListener*/ )
+{
+ OSL_FAIL("not implemented");
+}
+
+OUString SwXTextView::getImplementationName()
+{
+ return "SwXTextView";
+}
+
+sal_Bool SwXTextView::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXTextView::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.TextDocumentView", "com.sun.star.view.OfficeDocumentView" };
+}
+
+SwXTextViewCursor::SwXTextViewCursor(SwView* pVw) :
+ m_pView(pVw),
+ m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR))
+{
+}
+
+SwXTextViewCursor::~SwXTextViewCursor()
+{
+}
+
+// used to determine if there is a text selection or not.
+// If there is no text selection the functions that need a working
+// cursor will be disabled (throw RuntimeException). This will be the case
+// for the following interfaces:
+// - XViewCursor
+// - XTextCursor
+// - XTextRange
+// - XLineCursor
+bool SwXTextViewCursor::IsTextSelection( bool bAllowTables ) const
+{
+
+ bool bRes = false;
+ OSL_ENSURE(m_pView, "m_pView is NULL ???");
+ if(m_pView)
+ {
+ //! m_pView->GetShellMode() will only work after the shell
+ //! has already changed and thus can not be used here!
+ SelectionType eSelType = m_pView->GetWrtShell().GetSelectionType();
+ bRes = ( (SelectionType::Text & eSelType) ||
+ (SelectionType::NumberList & eSelType) ) &&
+ (!(SelectionType::TableCell & eSelType) || bAllowTables);
+ }
+ return bRes;
+}
+
+sal_Bool SwXTextViewCursor::isVisible()
+{
+ OSL_FAIL("not implemented");
+ return true;
+}
+
+void SwXTextViewCursor::setVisible(sal_Bool /*bVisible*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+awt::Point SwXTextViewCursor::getPosition()
+{
+ SolarMutexGuard aGuard;
+ awt::Point aRet;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ const SwWrtShell& rSh = m_pView->GetWrtShell();
+ const SwRect& aCharRect(rSh.GetCharRect());
+
+ const SwFrameFormat& rMaster = rSh.GetPageDesc( rSh.GetCurPageDesc() ).GetMaster();
+
+ const SvxULSpaceItem& rUL = rMaster.GetULSpace();
+ const tools::Long nY = aCharRect.Top() - (rUL.GetUpper() + DOCUMENTBORDER);
+ aRet.Y = convertTwipToMm100(nY);
+
+ const SvxLRSpaceItem& rLR = rMaster.GetLRSpace();
+ const tools::Long nX = aCharRect.Left() - (rLR.GetLeft() + DOCUMENTBORDER);
+ aRet.X = convertTwipToMm100(nX);
+
+ return aRet;
+}
+
+void SwXTextViewCursor::collapseToStart()
+{
+ SolarMutexGuard aGuard;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ if (!IsTextSelection())
+ throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
+
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ if(rSh.HasSelection())
+ {
+ SwPaM* pShellCursor = rSh.GetCursor();
+ if(*pShellCursor->GetPoint() > *pShellCursor->GetMark())
+ pShellCursor->Exchange();
+ pShellCursor->DeleteMark();
+ rSh.EnterStdMode();
+ rSh.SetSelection(*pShellCursor);
+ }
+
+}
+
+void SwXTextViewCursor::collapseToEnd()
+{
+ SolarMutexGuard aGuard;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ if (!IsTextSelection())
+ throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
+
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ if(rSh.HasSelection())
+ {
+ SwPaM* pShellCursor = rSh.GetCursor();
+ if(*pShellCursor->GetPoint() < *pShellCursor->GetMark())
+ pShellCursor->Exchange();
+ pShellCursor->DeleteMark();
+ rSh.EnterStdMode();
+ rSh.SetSelection(*pShellCursor);
+ }
+
+}
+
+sal_Bool SwXTextViewCursor::isCollapsed()
+{
+ SolarMutexGuard aGuard;
+ bool bRet = false;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ if (!IsTextSelection())
+ throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
+
+ const SwWrtShell& rSh = m_pView->GetWrtShell();
+ bRet = !rSh.HasSelection();
+
+ return bRet;
+
+}
+
+sal_Bool SwXTextViewCursor::goLeft(sal_Int16 nCount, sal_Bool bExpand)
+{
+ SolarMutexGuard aGuard;
+ bool bRet = false;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ if (!IsTextSelection())
+ throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
+
+ bRet = m_pView->GetWrtShell().Left( CRSR_SKIP_CHARS, bExpand, nCount, true );
+
+ return bRet;
+}
+
+sal_Bool SwXTextViewCursor::goRight(sal_Int16 nCount, sal_Bool bExpand)
+{
+ SolarMutexGuard aGuard;
+ bool bRet = false;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ if (!IsTextSelection())
+ throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
+
+ bRet = m_pView->GetWrtShell().Right( CRSR_SKIP_CHARS, bExpand, nCount, true );
+
+ return bRet;
+
+}
+
+void SwXTextViewCursor::gotoRange(
+ const uno::Reference< text::XTextRange > & xRange,
+ sal_Bool bExpand)
+{
+ SolarMutexGuard aGuard;
+ if(!(m_pView && xRange.is()))
+ throw uno::RuntimeException();
+
+ if (!IsTextSelection())
+ throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
+
+ SwUnoInternalPaM rDestPam(*m_pView->GetDocShell()->GetDoc());
+ if (!::sw::XTextRangeToSwPaM(rDestPam, xRange))
+ {
+ throw uno::RuntimeException();
+ }
+
+ ShellMode eSelMode = m_pView->GetShellMode();
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ // call EnterStdMode in non-text selections only
+ if(!bExpand ||
+ (eSelMode != ShellMode::TableText &&
+ eSelMode != ShellMode::ListText &&
+ eSelMode != ShellMode::TableListText &&
+ eSelMode != ShellMode::Text ))
+ rSh.EnterStdMode();
+ SwPaM* pShellCursor = rSh.GetCursor();
+ SwPaM aOwnPaM(*pShellCursor->GetPoint());
+ if(pShellCursor->HasMark())
+ {
+ aOwnPaM.SetMark();
+ *aOwnPaM.GetMark() = *pShellCursor->GetMark();
+ }
+
+ uno::Reference<lang::XUnoTunnel> xRangeTunnel( xRange, uno::UNO_QUERY);
+ SwXTextRange* pRange = comphelper::getFromUnoTunnel<SwXTextRange>(xRangeTunnel);
+ SwXParagraph* pPara = comphelper::getFromUnoTunnel<SwXParagraph>(xRangeTunnel);
+ OTextCursorHelper* pCursor = comphelper::getFromUnoTunnel<OTextCursorHelper>(xRangeTunnel);
+
+ const FrameTypeFlags nFrameType = rSh.GetFrameType(nullptr,true);
+
+ SwStartNodeType eSearchNodeType = SwNormalStartNode;
+ if(nFrameType & FrameTypeFlags::FLY_ANY)
+ eSearchNodeType = SwFlyStartNode;
+ else if(nFrameType &FrameTypeFlags::HEADER)
+ eSearchNodeType = SwHeaderStartNode;
+ else if(nFrameType & FrameTypeFlags::FOOTER)
+ eSearchNodeType = SwFooterStartNode;
+ else if(nFrameType & FrameTypeFlags::TABLE)
+ eSearchNodeType = SwTableBoxStartNode;
+ else if(nFrameType & FrameTypeFlags::FOOTNOTE)
+ eSearchNodeType = SwFootnoteStartNode;
+
+ const SwStartNode* pOwnStartNode = aOwnPaM.GetNode().
+ FindSttNodeByType(eSearchNodeType);
+
+ const SwNode* pSrcNode = nullptr;
+ if(pCursor && pCursor->GetPaM())
+ {
+ pSrcNode = &pCursor->GetPaM()->GetNode();
+ }
+ else if (pRange)
+ {
+ SwPaM aPam(pRange->GetDoc().GetNodes());
+ if (pRange->GetPositions(aPam))
+ {
+ pSrcNode = &aPam.GetNode();
+ }
+ }
+ else if (pPara && pPara->GetTextNode())
+ {
+ pSrcNode = pPara->GetTextNode();
+ }
+ const SwStartNode* pTmp = pSrcNode ? pSrcNode->FindSttNodeByType(eSearchNodeType) : nullptr;
+
+ //Skip SectionNodes
+ while(pTmp && pTmp->IsSectionNode())
+ {
+ pTmp = pTmp->StartOfSectionNode();
+ }
+ while(pOwnStartNode && pOwnStartNode->IsSectionNode())
+ {
+ pOwnStartNode = pOwnStartNode->StartOfSectionNode();
+ }
+ //Without Expand it is allowed to jump out with the ViewCursor everywhere,
+ //with Expand only in the same environment
+ if(bExpand &&
+ (pOwnStartNode != pTmp ||
+ (eSelMode != ShellMode::TableText &&
+ eSelMode != ShellMode::ListText &&
+ eSelMode != ShellMode::TableListText &&
+ eSelMode != ShellMode::Text)))
+ throw uno::RuntimeException();
+
+ //Now, the selection must be expanded.
+ if(bExpand)
+ {
+ // The cursor should include everything that has been included
+ // by him and the transferred Range.
+ SwPosition aOwnLeft(*aOwnPaM.Start());
+ SwPosition aOwnRight(*aOwnPaM.End());
+ SwPosition* pParamLeft = rDestPam.Start();
+ SwPosition* pParamRight = rDestPam.End();
+ // Now four SwPositions are there, two of them are needed, but which?
+ if(aOwnRight > *pParamRight)
+ *aOwnPaM.GetPoint() = aOwnRight;
+ else
+ *aOwnPaM.GetPoint() = *pParamRight;
+ aOwnPaM.SetMark();
+ if(aOwnLeft < *pParamLeft)
+ *aOwnPaM.GetMark() = aOwnLeft;
+ else
+ *aOwnPaM.GetMark() = *pParamLeft;
+ }
+ else
+ {
+ //The cursor shall match the passed range.
+ *aOwnPaM.GetPoint() = *rDestPam.GetPoint();
+ if(rDestPam.HasMark())
+ {
+ aOwnPaM.SetMark();
+ *aOwnPaM.GetMark() = *rDestPam.GetMark();
+ }
+ else
+ aOwnPaM.DeleteMark();
+ }
+ rSh.SetSelection(aOwnPaM);
+
+
+}
+
+void SwXTextViewCursor::gotoStart(sal_Bool bExpand)
+{
+ SolarMutexGuard aGuard;
+ comphelper::ProfileZone aZone("SwXTextViewCursor::gotoStart");
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ if (!IsTextSelection())
+ throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
+
+ m_pView->GetWrtShell().StartOfSection( bExpand );
+
+}
+
+void SwXTextViewCursor::gotoEnd(sal_Bool bExpand)
+{
+ SolarMutexGuard aGuard;
+ comphelper::ProfileZone aZone("SwXTextViewCursor::gotoEnd");
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ if (!IsTextSelection())
+ throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
+
+ m_pView->GetWrtShell().EndOfSection( bExpand );
+
+}
+
+sal_Bool SwXTextViewCursor::jumpToFirstPage()
+{
+ SolarMutexGuard aGuard;
+ bool bRet = false;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ if (rSh.IsSelFrameMode())
+ {
+ rSh.UnSelectFrame();
+ rSh.LeaveSelFrameMode();
+ }
+ rSh.EnterStdMode();
+ bRet = rSh.SttEndDoc(true);
+
+ return bRet;
+}
+
+sal_Bool SwXTextViewCursor::jumpToLastPage()
+{
+ SolarMutexGuard aGuard;
+ bool bRet = false;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ if (rSh.IsSelFrameMode())
+ {
+ rSh.UnSelectFrame();
+ rSh.LeaveSelFrameMode();
+ }
+ rSh.EnterStdMode();
+ bRet = rSh.SttEndDoc(false);
+ rSh.SttPg();
+
+ return bRet;
+}
+
+sal_Bool SwXTextViewCursor::jumpToPage(sal_Int16 nPage)
+{
+ SolarMutexGuard aGuard;
+ bool bRet = false;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ bRet = m_pView->GetWrtShell().GotoPage(nPage, true);
+
+ return bRet;
+}
+
+sal_Bool SwXTextViewCursor::jumpToNextPage()
+{
+ SolarMutexGuard aGuard;
+ bool bRet = false;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ bRet = m_pView->GetWrtShell().SttNxtPg();
+
+ return bRet;
+}
+
+sal_Bool SwXTextViewCursor::jumpToPreviousPage()
+{
+ SolarMutexGuard aGuard;
+ bool bRet = false;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ bRet = m_pView->GetWrtShell().EndPrvPg();
+
+ return bRet;
+}
+
+sal_Bool SwXTextViewCursor::jumpToEndOfPage()
+{
+ SolarMutexGuard aGuard;
+ bool bRet = false;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ bRet = m_pView->GetWrtShell().EndPg();
+
+ return bRet;
+}
+
+sal_Bool SwXTextViewCursor::jumpToStartOfPage()
+{
+ SolarMutexGuard aGuard;
+ bool bRet = false;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ bRet = m_pView->GetWrtShell().SttPg();
+
+ return bRet;
+}
+
+sal_Int16 SwXTextViewCursor::getPage()
+{
+ SolarMutexGuard aGuard;
+ sal_Int16 nRet = 0;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ SwPaM* pShellCursor = rSh.GetCursor();
+ nRet = static_cast<sal_Int16>(pShellCursor->GetPageNum());
+
+ return nRet;
+}
+
+sal_Bool SwXTextViewCursor::screenDown()
+{
+ SolarMutexGuard aGuard;
+ bool bRet = false;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ SfxRequest aReq(FN_PAGEDOWN, SfxCallMode::SLOT, m_pView->GetPool());
+ m_pView->Execute(aReq);
+ const SfxPoolItem* pRet = aReq.GetReturnValue();
+ bRet = pRet && static_cast<const SfxBoolItem*>(pRet)->GetValue();
+
+ return bRet;
+}
+
+sal_Bool SwXTextViewCursor::screenUp()
+{
+ SolarMutexGuard aGuard;
+ bool bRet = false;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ SfxRequest aReq(FN_PAGEUP, SfxCallMode::SLOT, m_pView->GetPool());
+ m_pView->Execute(aReq);
+ const SfxPoolItem* pRet = aReq.GetReturnValue();
+ bRet = pRet && static_cast<const SfxBoolItem*>(pRet)->GetValue();
+
+ return bRet;
+}
+
+uno::Reference< text::XText > SwXTextViewCursor::getText()
+{
+ SolarMutexGuard aGuard;
+ uno::Reference< text::XText > xRet;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ if (!IsTextSelection( false ))
+ throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
+
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ SwPaM* pShellCursor = rSh.GetCursor();
+ SwDoc* pDoc = m_pView->GetDocShell()->GetDoc();
+ xRet = ::sw::CreateParentXText(*pDoc, *pShellCursor->Start());
+
+ return xRet;
+}
+
+uno::Reference< text::XTextRange > SwXTextViewCursor::getStart()
+{
+ SolarMutexGuard aGuard;
+ uno::Reference< text::XTextRange > xRet;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ if (!IsTextSelection())
+ throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
+
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ SwPaM* pShellCursor = rSh.GetCursor();
+ SwDoc* pDoc = m_pView->GetDocShell()->GetDoc();
+ xRet = SwXTextRange::CreateXTextRange(*pDoc, *pShellCursor->Start(), nullptr);
+
+ return xRet;
+}
+
+uno::Reference< text::XTextRange > SwXTextViewCursor::getEnd()
+{
+ SolarMutexGuard aGuard;
+ uno::Reference< text::XTextRange > xRet;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ if (!IsTextSelection())
+ throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
+
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ SwPaM* pShellCursor = rSh.GetCursor();
+ SwDoc* pDoc = m_pView->GetDocShell()->GetDoc();
+ xRet = SwXTextRange::CreateXTextRange(*pDoc, *pShellCursor->End(), nullptr);
+
+ return xRet;
+}
+
+OUString SwXTextViewCursor::getString()
+{
+ SolarMutexGuard aGuard;
+ OUString uRet;
+ if(m_pView)
+ {
+ if (!IsTextSelection( false ))
+ {
+ SAL_WARN("sw.uno", "no text selection in getString() " << static_cast<cppu::OWeakObject*>(this));
+ return uRet;
+ }
+
+ ShellMode eSelMode = m_pView->GetShellMode();
+ switch(eSelMode)
+ {
+ //! since setString for SEL_TABLE_TEXT (with possible
+ //! multi selection of cells) would not work properly we
+ //! will ignore this case for both
+ //! functions (setString AND getString) because of symmetrie.
+
+ case ShellMode::ListText :
+ case ShellMode::TableListText:
+ case ShellMode::Text :
+ {
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ SwPaM* pShellCursor = rSh.GetCursor();
+ SwUnoCursorHelper::GetTextFromPam(*pShellCursor, uRet,
+ rSh.GetLayout());
+ break;
+ }
+ default:;//prevent warning
+ }
+ }
+ return uRet;
+}
+
+void SwXTextViewCursor::setString(const OUString& aString)
+{
+ SolarMutexGuard aGuard;
+ if(!m_pView)
+ return;
+
+ if (!IsTextSelection( false ))
+ throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
+
+ ShellMode eSelMode = m_pView->GetShellMode();
+ switch(eSelMode)
+ {
+ //! since setString for SEL_TABLE_TEXT (with possible
+ //! multi selection of cells) would not work properly we
+ //! will ignore this case for both
+ //! functions (setString AND getString) because of symmetrie.
+
+ case ShellMode::ListText :
+ case ShellMode::TableListText :
+ case ShellMode::Text :
+ {
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ SwCursor* pShellCursor = rSh.GetCursor();
+ SwUnoCursorHelper::SetString(*pShellCursor, aString);
+ break;
+ }
+ default:;//prevent warning
+ }
+}
+
+uno::Reference< XPropertySetInfo > SwXTextViewCursor::getPropertySetInfo( )
+{
+ static uno::Reference< XPropertySetInfo > xRef = m_pPropSet->getPropertySetInfo();
+ return xRef;
+}
+
+void SwXTextViewCursor::setPropertyValue( const OUString& rPropertyName, const Any& aValue )
+{
+ SolarMutexGuard aGuard;
+ if(!m_pView)
+ throw RuntimeException();
+
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ SwPaM* pShellCursor = rSh.GetCursor();
+ SwNode& rNode = pShellCursor->GetNode();
+ if (!rNode.IsTextNode())
+ throw RuntimeException();
+
+ SwUnoCursorHelper::SetPropertyValue(
+ *pShellCursor, *m_pPropSet, rPropertyName, aValue );
+
+
+}
+
+Any SwXTextViewCursor::getPropertyValue( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ Any aRet;
+ if(!m_pView)
+ throw RuntimeException();
+
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ SwPaM* pShellCursor = rSh.GetCursor();
+ aRet = SwUnoCursorHelper::GetPropertyValue(
+ *pShellCursor, *m_pPropSet, rPropertyName);
+
+ return aRet;
+}
+
+void SwXTextViewCursor::addPropertyChangeListener(
+ const OUString& /*aPropertyName*/, const uno::Reference< XPropertyChangeListener >& /*xListener*/ )
+{
+}
+
+void SwXTextViewCursor::removePropertyChangeListener(
+ const OUString& /*aPropertyName*/, const uno::Reference< XPropertyChangeListener >& /*aListener*/ )
+{
+}
+
+void SwXTextViewCursor::addVetoableChangeListener(
+ const OUString& /*PropertyName*/, const uno::Reference< XVetoableChangeListener >& /*aListener*/ )
+{
+}
+
+void SwXTextViewCursor::removeVetoableChangeListener(
+ const OUString& /*PropertyName*/, const uno::Reference< XVetoableChangeListener >& /*aListener*/ )
+{
+}
+
+PropertyState SwXTextViewCursor::getPropertyState( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ PropertyState eState;
+ if(!m_pView)
+ throw RuntimeException();
+
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ SwPaM* pShellCursor = rSh.GetCursor();
+ eState = SwUnoCursorHelper::GetPropertyState(
+ *pShellCursor, *m_pPropSet, rPropertyName);
+
+ return eState;
+}
+
+Sequence< PropertyState > SwXTextViewCursor::getPropertyStates(
+ const Sequence< OUString >& rPropertyNames )
+{
+ SolarMutexGuard aGuard;
+ Sequence< PropertyState > aRet;
+ if(m_pView)
+ {
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ SwPaM* pShellCursor = rSh.GetCursor();
+ aRet = SwUnoCursorHelper::GetPropertyStates(
+ *pShellCursor, *m_pPropSet, rPropertyNames);
+ }
+ return aRet;
+}
+
+void SwXTextViewCursor::setPropertyToDefault( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ if(m_pView)
+ {
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ SwPaM* pShellCursor = rSh.GetCursor();
+ SwUnoCursorHelper::SetPropertyToDefault(
+ *pShellCursor, *m_pPropSet, rPropertyName);
+ }
+}
+
+Any SwXTextViewCursor::getPropertyDefault( const OUString& rPropertyName )
+{
+ Any aRet;
+ SolarMutexGuard aGuard;
+ if(m_pView)
+ {
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ SwPaM* pShellCursor = rSh.GetCursor();
+ aRet = SwUnoCursorHelper::GetPropertyDefault(
+ *pShellCursor, *m_pPropSet, rPropertyName);
+ }
+ return aRet;
+}
+
+sal_Bool SwXTextViewCursor::goDown(sal_Int16 nCount, sal_Bool bExpand)
+{
+ SolarMutexGuard aGuard;
+ comphelper::ProfileZone aZone("SwXTextViewCursor::goDown");
+ bool bRet = false;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ if (!IsTextSelection())
+ throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
+
+ bRet = m_pView->GetWrtShell().Down( bExpand, nCount, true );
+
+ return bRet;
+}
+
+sal_Bool SwXTextViewCursor::goUp(sal_Int16 nCount, sal_Bool bExpand)
+{
+ SolarMutexGuard aGuard;
+ comphelper::ProfileZone aZone("SwXTextViewCursor::goUp");
+ bool bRet = false;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ if (!IsTextSelection())
+ throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
+
+ bRet = m_pView->GetWrtShell().Up( bExpand, nCount, true );
+
+ return bRet;
+}
+
+sal_Bool SwXTextViewCursor::isAtStartOfLine()
+{
+ SolarMutexGuard aGuard;
+ bool bRet = false;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ if (!IsTextSelection( false ))
+ throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
+
+ bRet = m_pView->GetWrtShell().IsAtLeftMargin();
+
+ return bRet;
+}
+
+sal_Bool SwXTextViewCursor::isAtEndOfLine()
+{
+ SolarMutexGuard aGuard;
+ bool bRet = false;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ if (!IsTextSelection( false ))
+ throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
+
+ bRet = m_pView->GetWrtShell().IsAtRightMargin();
+
+ return bRet;
+}
+
+void SwXTextViewCursor::gotoEndOfLine(sal_Bool bExpand)
+{
+ SolarMutexGuard aGuard;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ if (!IsTextSelection( false ))
+ throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
+
+ m_pView->GetWrtShell().RightMargin(bExpand, true);
+
+}
+
+void SwXTextViewCursor::gotoStartOfLine(sal_Bool bExpand)
+{
+ SolarMutexGuard aGuard;
+ if(!m_pView)
+ throw uno::RuntimeException();
+
+ if (!IsTextSelection( false ))
+ throw uno::RuntimeException("no text selection", static_cast < cppu::OWeakObject * > ( this ) );
+
+ m_pView->GetWrtShell().LeftMargin(bExpand, true);
+
+}
+
+OUString SwXTextViewCursor::getImplementationName()
+{
+ return "SwXTextViewCursor";
+}
+
+sal_Bool SwXTextViewCursor::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXTextViewCursor::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.TextViewCursor",
+ "com.sun.star.style.CharacterProperties",
+ "com.sun.star.style.CharacterPropertiesAsian",
+ "com.sun.star.style.CharacterPropertiesComplex",
+ "com.sun.star.style.ParagraphProperties",
+ "com.sun.star.style.ParagraphPropertiesAsian",
+ "com.sun.star.style.ParagraphPropertiesComplex" };
+}
+
+const uno::Sequence< sal_Int8 > & SwXTextViewCursor::getUnoTunnelId()
+{
+ static const comphelper::UnoIdInit theSwXTextViewCursorUnoTunnelId;
+ return theSwXTextViewCursorUnoTunnelId.getSeq();
+}
+
+//XUnoTunnel
+sal_Int64 SAL_CALL SwXTextViewCursor::getSomething(
+ const uno::Sequence< sal_Int8 >& rId )
+{
+ return comphelper::getSomethingImpl(rId, this,
+ comphelper::FallbackToGetSomethingOf<OTextCursorHelper>{});
+}
+
+IMPLEMENT_FORWARD_XINTERFACE2(SwXTextViewCursor,SwXTextViewCursor_Base,OTextCursorHelper)
+const SwDoc* SwXTextViewCursor::GetDoc() const
+{
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ return rSh.GetCursor() ? &rSh.GetCursor()->GetDoc() : nullptr;
+}
+
+SwDoc* SwXTextViewCursor::GetDoc()
+{
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ return rSh.GetCursor() ? &rSh.GetCursor()->GetDoc() : nullptr;
+}
+
+const SwPaM* SwXTextViewCursor::GetPaM() const
+{
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ return rSh.GetCursor();
+}
+
+SwPaM* SwXTextViewCursor::GetPaM()
+{
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ return rSh.GetCursor();
+}
+
+uno::Reference<datatransfer::XTransferable> SAL_CALL
+SwXTextView::getTransferableForTextRange(uno::Reference<text::XTextRange> const& xTextRange)
+{
+ SolarMutexGuard aGuard;
+
+ // the point is we can copy PaM that wouldn't be legal as shell cursor
+ SwUnoInternalPaM aPam(*m_pView->GetDocShell()->GetDoc());
+ if (!::sw::XTextRangeToSwPaM(aPam, xTextRange, ::sw::TextRangeMode::AllowNonTextNode))
+ {
+ throw uno::RuntimeException("invalid text range");
+ }
+
+ //force immediate shell update
+ GetView()->StopShellTimer();
+ SwWrtShell& rSh = GetView()->GetWrtShell();
+ rtl::Reference<SwTransferable> pTransfer = new SwTransferable(rSh);
+ const bool bLockedView = rSh.IsViewLocked();
+ rSh.LockView( true );
+ pTransfer->PrepareForCopyTextRange(aPam);
+ rSh.LockView( bLockedView );
+ return pTransfer;
+}
+
+uno::Reference< datatransfer::XTransferable > SAL_CALL SwXTextView::getTransferable()
+{
+ SolarMutexGuard aGuard;
+
+ //force immediat shell update
+ GetView()->StopShellTimer();
+ SwWrtShell& rSh = GetView()->GetWrtShell();
+ if ( GetView()->GetShellMode() == ShellMode::DrawText )
+ {
+ SdrView *pSdrView = rSh.GetDrawView();
+ OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView();
+ return pOLV->GetEditView().GetTransferable();
+ }
+ else
+ {
+ rtl::Reference<SwTransferable> pTransfer = new SwTransferable( rSh );
+ const bool bLockedView = rSh.IsViewLocked();
+ rSh.LockView( true ); //lock visible section
+ pTransfer->PrepareForCopy();
+ rSh.LockView( bLockedView );
+ return pTransfer;
+ }
+}
+
+void SAL_CALL SwXTextView::insertTransferable( const uno::Reference< datatransfer::XTransferable >& xTrans )
+{
+ SolarMutexGuard aGuard;
+
+ //force immediat shell update
+ GetView()->StopShellTimer();
+ SwWrtShell& rSh = GetView()->GetWrtShell();
+ if ( GetView()->GetShellMode() == ShellMode::DrawText )
+ {
+ SdrView *pSdrView = rSh.GetDrawView();
+ OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView();
+ pOLV->GetEditView().InsertText( xTrans, GetView()->GetDocShell()->GetMedium()->GetBaseURL(), false );
+ }
+ else
+ {
+ TransferableDataHelper aDataHelper( xTrans );
+ if ( SwTransferable::IsPaste( rSh, aDataHelper ) )
+ {
+ SwTransferable::Paste( rSh, aDataHelper );
+ if( rSh.IsFrameSelected() || rSh.IsObjSelected() )
+ rSh.EnterSelFrameMode();
+ GetView()->AttrChangedNotify(nullptr);
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */