/* -*- 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/util/SearchAlgorithms2.hpp>
#include <o3tl/any.hxx>
#include <vcl/graphicfilter.hxx>
#include <com/sun/star/sdb/DatabaseContext.hpp>
#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
#include <com/sun/star/ui/dialogs/ListboxControlActions.hpp>
#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
#include <com/sun/star/linguistic2/XProofreadingIterator.hpp>
#include <com/sun/star/linguistic2/XDictionary.hpp>
#include <comphelper/propertyvalue.hxx>
#include <officecfg/Office/Common.hxx>
#include <SwCapObjType.hxx>
#include <SwStyleNameMapper.hxx>
#include <docary.hxx>
#include <hintids.hxx>
#include <SwRewriter.hxx>
#include <numrule.hxx>
#include <swundo.hxx>
#include <svl/PasswordHelper.hxx>
#include <svl/urihelper.hxx>
#include <sfx2/passwd.hxx>
#include <sfx2/sfxdlg.hxx>
#include <sfx2/filedlghelper.hxx>
#include <editeng/langitem.hxx>
#include <svx/linkwarn.hxx>
#include <svx/statusitem.hxx>
#include <svx/viewlayoutitem.hxx>
#include <svx/zoomslideritem.hxx>
#include <sfx2/lokhelper.hxx>
#include <sfx2/htmlmode.hxx>
#include <vcl/svapp.hxx>
#include <sfx2/app.hxx>
#include <sfx2/request.hxx>
#include <sfx2/bindings.hxx>
#include <editeng/lrspitem.hxx>
#include <unotools/localedatawrapper.hxx>
#include <unotools/syslocale.hxx>
#include <editeng/unolingu.hxx>
#include <vcl/weld.hxx>
#include <editeng/tstpitem.hxx>
#include <sfx2/event.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/fcontnr.hxx>
#include <editeng/sizeitem.hxx>
#include <sfx2/dispatch.hxx>
#include <svl/whiter.hxx>
#include <svl/ptitem.hxx>
#include <sfx2/viewfrm.hxx>
#include <vcl/errinf.hxx>
#include <tools/hostfilter.hxx>
#include <tools/urlobj.hxx>
#include <svx/svdview.hxx>
#include <swtypes.hxx>
#include <swwait.hxx>
#include <redlndlg.hxx>
#include <view.hxx>
#include <uivwimp.hxx>
#include <docsh.hxx>
#include <doc.hxx>
#include <printdata.hxx>
#include <IDocumentDeviceAccess.hxx>
#include <IDocumentRedlineAccess.hxx>
#include <DocumentRedlineManager.hxx>
#include <IDocumentUndoRedo.hxx>
#include <IDocumentSettingAccess.hxx>
#include <IDocumentDrawModelAccess.hxx>
#include <IDocumentStatistics.hxx>
#include <IDocumentOutlineNodes.hxx>
#include <wrtsh.hxx>
#include <viewopt.hxx>
#include <basesh.hxx>
#include <swmodule.hxx>
#include <uitool.hxx>
#include <shellio.hxx>
#include <fmtinfmt.hxx>
#include <mdiexp.hxx>
#include <drawbase.hxx>
#include <frmatr.hxx>
#include <frmmgr.hxx>
#include <pagedesc.hxx>
#include <section.hxx>
#include <tox.hxx>
#include <edtwin.hxx>
#include <wview.hxx>
#include <cmdid.h>
#include <sfx2/strings.hrc>
#include <sfx2/sfxresid.hxx>
#include <strings.hrc>
#include <swerror.h>
#include <globals.hrc>
#include <fmtclds.hxx>
#include <sfx2/templatedlg.hxx>
#include <dbconfig.hxx>
#include <dbmgr.hxx>
#include <reffld.hxx>
#include <comphelper/lok.hxx>
#include <comphelper/string.hxx>
#include <comphelper/docpasswordhelper.hxx>
#include <svtools/strings.hrc>
#include <svtools/svtresid.hxx>
#include <PostItMgr.hxx>
#include <comphelper/processfactory.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <svx/svxdlg.hxx>
#include <swabstdlg.hxx>
#include <fmthdft.hxx>
#include <unotextrange.hxx>
#include <docstat.hxx>
#include <wordcountdialog.hxx>
#include <OnlineAccessibilityCheck.hxx>
#include <sfx2/sidebar/Sidebar.hxx>
#include <vcl/GraphicNativeTransform.hxx>
#include <vcl/GraphicNativeMetadata.hxx>
#include <vcl/settings.hxx>
#include <i18nutil/searchopt.hxx>
#include <osl/diagnose.h>
#include <paratr.hxx>
#include <rootfrm.hxx>
#include <frameformats.hxx>
#include <viewimp.hxx>
#include <pagefrm.hxx>
#include <memory>
#include <string_view>
#include <svl/slstitm.hxx>
#include <basegfx/utils/zoomtools.hxx>
#include <ndtxt.hxx>
#include <svx/srchdlg.hxx>
#include <o3tl/string_view.hxx>
#include <svx/dialog/gotodlg.hxx>
const char sStatusDelim[] = " : ";
using namespace sfx2;
using namespace ::com::sun::star;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::scanner;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::ui::dialogs;
namespace {
class SwNumberInputDlg : public SfxDialogController
{
private:
std::unique_ptr<weld::Label> m_xLabel1;
std::unique_ptr<weld::SpinButton> m_xSpinButton;
std::unique_ptr<weld::Label> m_xLabel2;
std::unique_ptr<weld::Button> m_xOKButton;
DECL_LINK(InputModifiedHdl, weld::Entry&, void);
public:
SwNumberInputDlg(weld::Window* pParent, const OUString& rTitle,
const OUString& rLabel1, const sal_Int64 nValue, const sal_Int64 min, const sal_Int64 max,
OUString rLabel2 = OUString())
: SfxDialogController(pParent, u"modules/swriter/ui/numberinput.ui"_ustr, u"NumberInputDialog"_ustr)
, m_xLabel1(m_xBuilder->weld_label(u"label1"_ustr))
, m_xSpinButton(m_xBuilder->weld_spin_button(u"spinbutton"_ustr))
, m_xLabel2(m_xBuilder->weld_label(u"label2"_ustr))
, m_xOKButton(m_xBuilder->weld_button(u"ok"_ustr))
{
m_xDialog->set_title(rTitle);
m_xLabel1->set_label(rLabel1);
m_xSpinButton->set_value(nValue);
m_xSpinButton->set_range(min, max);
m_xSpinButton->set_position(-1);
m_xSpinButton->select_region(0, -1);
m_xSpinButton->connect_changed(LINK(this, SwNumberInputDlg, InputModifiedHdl));
if (!rLabel2.isEmpty())
{
m_xLabel2->set_label(rLabel2);
m_xLabel2->show();
}
}
auto GetNumber()
{
return m_xSpinButton->get_text().toInt32();
}
};
IMPL_LINK_NOARG(SwNumberInputDlg, InputModifiedHdl, weld::Entry&, void)
{
m_xOKButton->set_sensitive(!m_xSpinButton->get_text().isEmpty());
if (!m_xOKButton->get_sensitive())
return;
auto nValue = m_xSpinButton->get_text().toInt32();
if (nValue <= m_xSpinButton->get_min())
m_xSpinButton->set_value(m_xSpinButton->get_min());
else if (nValue > m_xSpinButton->get_max())
m_xSpinButton->set_value(m_xSpinButton->get_max());
else
m_xSpinButton->set_value(nValue);
m_xSpinButton->set_position(-1);
}
}
static void lcl_SetAllTextToDefaultLanguage( SwWrtShell &rWrtSh, TypedWhichId<SvxLanguageItem> nWhichId )
{
if (!(nWhichId == RES_CHRATR_LANGUAGE ||
nWhichId == RES_CHRATR_CJK_LANGUAGE ||
nWhichId == RES_CHRATR_CTL_LANGUAGE))
return;
rWrtSh.StartAction();
rWrtSh.LockView( true );
rWrtSh.Push();
// prepare to apply new language to all text in document
rWrtSh.SelAll();
rWrtSh.ExtendedSelectAll();
// set language attribute to default for all text
rWrtSh.ResetAttr({ nWhichId });
rWrtSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
rWrtSh.LockView( false );
rWrtSh.EndAction();
}
/**
* Create string for showing the page number in the statusbar
*
* @param nPhyNum The physical page number
* @param nVirtNum The logical page number (user-assigned)
* @param rPgStr User-defined page name (will be shown if different from logical page number)
*
* @return OUString Formatted string: Page 1 of 10 (Page 1 of 8 to print OR Page nVirtNumv/rPgStr)
**/
OUString SwView::GetPageStr(sal_uInt16 nPhyNum, sal_uInt16 nVirtNum, const OUString& rPgStr)
{
// Show user-defined page number in brackets if any.
OUString extra;
if (!rPgStr.isEmpty() && std::u16string_view(OUString::number(nPhyNum)) != rPgStr)
extra = rPgStr;
else if (nPhyNum != nVirtNum)
extra = OUString::number(nVirtNum);
sal_uInt16 nPageCount = GetWrtShell().GetPageCnt();
sal_uInt16 nPrintedPhyNum = nPhyNum;
sal_uInt16 nPrintedPageCount = nPageCount;
if (!GetWrtShell().getIDocumentDeviceAccess().getPrintData().IsPrintEmptyPages())
SwDoc::CalculateNonBlankPages(*m_pWrtShell->GetLayout(), nPrintedPageCount, nPrintedPhyNum);
// Show printed page numbers only, when they are different
OUString aStr( nPageCount != nPrintedPageCount
? SwResId(STR_PAGE_COUNT_PRINTED)
: (extra.isEmpty() ? SwResId(STR_PAGE_COUNT) : SwResId(STR_PAGE_COUNT_CUSTOM)));
aStr = aStr.replaceFirst("%1", OUString::number(nPhyNum));
if (nPageCount != nPrintedPageCount)
{
aStr = aStr.replaceFirst("%2", OUString::number(nPageCount));
aStr = aStr.replaceFirst("%3", OUString::number(nPrintedPhyNum));
aStr = aStr.replaceFirst("%4", OUString::number(nPrintedPageCount));
}
else {
if (extra.isEmpty())
aStr = aStr.replaceFirst("%2", OUString::number(nPageCount));
else
{
aStr = aStr.replaceFirst("%2", extra);
aStr = aStr.replaceFirst("%3", OUString::number(nPageCount));
}
}
return aStr;
}
ErrCode SwView::InsertGraphic( const OUString &rPath, const OUString &rFilter,
bool bLink, GraphicFilter *pFilter )
{
SwWait aWait( *GetDocShell(), true );
Graphic aGraphic;
ErrCode aResult = ERRCODE_NONE;
if( !pFilter )
{
pFilter = &GraphicFilter::GetGraphicFilter();
}
if (comphelper::LibreOfficeKit::isActive())
{
INetURLObject aURL(rPath);
if (INetProtocol::File != aURL.GetProtocol() && HostFilter::isForbidden(aURL.GetHost()))
SfxLokHelper::sendNetworkAccessError("insert");
}
aResult = GraphicFilter::LoadGraphic( rPath, rFilter, aGraphic, pFilter );
if( ERRCODE_NONE == aResult )
{
GraphicNativeMetadata aMetadata;
if ( aMetadata.read(aGraphic) )
{
const Degree10 aRotation = aMetadata.getRotation();
if (aRotation)
{
GraphicNativeTransform aTransform( aGraphic );
aTransform.rotate( aRotation );
}
}
SwFlyFrameAttrMgr aFrameManager( true, GetWrtShellPtr(), Frmmgr_Type::GRF, nullptr );
SwWrtShell& rShell = GetWrtShell();
// #i123922# determine if we really want to insert or replace the graphic at a selected object
const bool bReplaceMode(rShell.HasSelection() && SelectionType::Frame == rShell.GetSelectionType());
if(bReplaceMode)
{
// #i123922# Do same as in D&D, ReRead graphic and all is done
rShell.ReRead(
bLink ? rPath : OUString(),
bLink ? rFilter : OUString(),
&aGraphic);
}
else
{
rShell.StartAction();
if( bLink )
{
SwDocShell* pDocSh = GetDocShell();
INetURLObject aTemp(
pDocSh->HasName() ?
pDocSh->GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE ) :
OUString());
OUString sURL = URIHelper::SmartRel2Abs(
aTemp, rPath, URIHelper::GetMaybeFileHdl() );
aGraphic.setOriginURL(sURL);
rShell.InsertGraphic( sURL, rFilter, aGraphic, &aFrameManager );
}
else
{
rShell.InsertGraphic( OUString(), OUString(), aGraphic, &aFrameManager );
}
// it is too late after "EndAction" because the Shell can already be destroyed.
rShell.EndAction();
}
}
return aResult;
}
bool SwView::InsertGraphicDlg( SfxRequest& rReq )
{
bool bReturn = false;
SwDocShell* pDocShell = GetDocShell();
SwDoc* pDoc = pDocShell->GetDoc();
OUString sGraphicFormat = SwResId(STR_POOLFRM_GRAPHIC);
const SfxStringItem* pName = rReq.GetArg<SfxStringItem>(SID_INSERT_GRAPHIC);
bool bShowError = !pName;
// No file pickers in a non-desktop (mobile app) build.
#if HAVE_FEATURE_DESKTOP
// when in HTML mode insert only as a link
const sal_uInt16 nHtmlMode = ::GetHtmlMode(pDocShell);
if (!pName && !Application::IsHeadlessModeEnabled())
{
std::unique_ptr<FileDialogHelper> pFileDlg(new FileDialogHelper(
ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE,
FileDialogFlags::Graphic, GetFrameWeld()));
pFileDlg->SetTitle(SwResId(STR_INSERT_GRAPHIC ));
pFileDlg->SetContext( FileDialogHelper::WriterInsertImage );
uno::Reference < XFilePicker3 > xFP = pFileDlg->GetFilePicker();
uno::Reference < XFilePickerControlAccess > xCtrlAcc(xFP, UNO_QUERY);
if(nHtmlMode & HTMLMODE_ON)
{
xCtrlAcc->setValue( ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, Any(true));
xCtrlAcc->enableControl( ExtendedFilePickerElementIds::CHECKBOX_LINK, false);
}
std::vector<OUString> aFormats;
const size_t nArrLen = pDoc->GetFrameFormats()->size();
for( size_t i = 0; i < nArrLen; ++i )
{
const SwFrameFormat* pFormat = (*pDoc->GetFrameFormats())[ i ];
if(pFormat->IsDefault() || pFormat->IsAuto())
continue;
aFormats.push_back(pFormat->GetName());
}
// pool formats
const std::vector<OUString>& rFramePoolArr(
SwStyleNameMapper::GetFrameFormatUINameArray());
for(const auto & i : rFramePoolArr)
{
aFormats.push_back(i);
}
std::sort(aFormats.begin(), aFormats.end());
aFormats.erase(std::unique(aFormats.begin(), aFormats.end()), aFormats.end());
Sequence<OUString> aListBoxEntries(aFormats.size());
OUString* pEntries = aListBoxEntries.getArray();
sal_Int16 nSelect = 0;
for( size_t i = 0; i < aFormats.size(); ++i )
{
pEntries[i] = aFormats[i];
if(pEntries[i] == sGraphicFormat)
nSelect = i;
}
try
{
Any aTemplates(&aListBoxEntries, cppu::UnoType<decltype(aListBoxEntries)>::get());
xCtrlAcc->setValue( ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE,
ListboxControlActions::ADD_ITEMS , aTemplates );
Any aSelectPos(&nSelect, cppu::UnoType<decltype(nSelect)>::get());
xCtrlAcc->setValue( ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE,
ListboxControlActions::SET_SELECT_ITEM, aSelectPos );
}
catch (const Exception&)
{
OSL_FAIL("control access failed");
}
// execute file dialog, without capturing mouse (tdf#156033)
vcl::Window* pWin = GetWindow();
const bool bMouseCaptured = pWin && pWin->IsMouseCaptured();
if (bMouseCaptured)
pWin->ReleaseMouse();
bool bHaveName = ERRCODE_NONE == pFileDlg->Execute();
if (bMouseCaptured)
pWin->CaptureMouse();
if (bHaveName)
{
rReq.AppendItem(SfxStringItem(SID_INSERT_GRAPHIC, pFileDlg->GetPath()));
rReq.AppendItem(SfxStringItem(FN_PARAM_FILTER, pFileDlg->GetCurrentFilter()));
pName = rReq.GetArg<SfxStringItem>(SID_INSERT_GRAPHIC);
bool bAsLink = false;
if(nHtmlMode & HTMLMODE_ON)
bAsLink = true;
else
{
try
{
Any aVal = xCtrlAcc->getValue( ExtendedFilePickerElementIds::CHECKBOX_LINK, 0);
OSL_ENSURE(aVal.hasValue(), "Value CBX_INSERT_AS_LINK not found");
bAsLink = !aVal.hasValue() || *o3tl::doAccess<bool>(aVal);
Any aTemplateValue = xCtrlAcc->getValue(
ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE,
ListboxControlActions::GET_SELECTED_ITEM );
OUString sTmpl;
aTemplateValue >>= sTmpl;
rReq.AppendItem( SfxStringItem( FN_PARAM_2, sTmpl) );
}
catch (const Exception&)
{
OSL_FAIL("control access failed");
}
}
rReq.AppendItem( SfxBoolItem( FN_PARAM_1, bAsLink ) );
}
}
#endif
if (pName)
{
OUString aFileName = pName->GetValue();
OUString aFilterName;
if (const SfxStringItem* pFilter = rReq.GetArg<SfxStringItem>(FN_PARAM_FILTER))
aFilterName = pFilter->GetValue();
bool bAsLink = false;
if (const SfxBoolItem* pAsLink = rReq.GetArg<SfxBoolItem>(FN_PARAM_1))
bAsLink = pAsLink->GetValue();
if (const SfxStringItem* pStyle = rReq.GetArg<SfxStringItem>(FN_PARAM_2);
pStyle && !pStyle->GetValue().isEmpty())
sGraphicFormat = pStyle->GetValue();
#if HAVE_FEATURE_DESKTOP
if( nHtmlMode & HTMLMODE_ON )
bAsLink = true;
else
{
// really store as link only?
if (bAsLink && bShowError
&& officecfg::Office::Common::Misc::ShowLinkWarningDialog::get())
{
SvxLinkWarningDialog aWarnDlg(GetFrameWeld(), aFileName);
if (aWarnDlg.run() != RET_OK)
bAsLink=false; // don't store as link
}
}
#endif
SwWrtShell& rSh = GetWrtShell();
rSh.LockPaint(LockPaintReason::InsertGraphic);
rSh.StartAction();
SwRewriter aRewriter;
aRewriter.AddRule(UndoArg1, SwResId(STR_GRAPHIC_DEFNAME));
// #i123922# determine if we really want to insert or replace the graphic at a selected object
const bool bReplaceMode(rSh.HasSelection() && SelectionType::Frame == rSh.GetSelectionType());
rSh.StartUndo(SwUndoId::INSERT, &aRewriter);
ErrCode nError = InsertGraphic( aFileName, aFilterName, bAsLink, &GraphicFilter::GetGraphicFilter() );
// format not equal to current filter (with autodetection)
if( nError == ERRCODE_GRFILTER_FORMATERROR )
nError = InsertGraphic( aFileName, OUString(), bAsLink, &GraphicFilter::GetGraphicFilter() );
// #i123922# no new FrameFormat for replace mode, only when new object was created,
// else this would reset the current setting for the frame holding the graphic
if ( !bReplaceMode && rSh.IsFrameSelected() )
{
SwFrameFormat* pFormat = pDoc->FindFrameFormatByName( sGraphicFormat );
if(!pFormat)
pFormat = pDoc->MakeFrameFormat(sGraphicFormat,
pDocShell->GetDoc()->GetDfltFrameFormat(),
false);
rSh.SetFrameFormat( pFormat );
}
TranslateId pResId;
if( nError == ERRCODE_GRFILTER_OPENERROR )
pResId = STR_GRFILTER_OPENERROR;
else if( nError == ERRCODE_GRFILTER_IOERROR )
pResId = STR_GRFILTER_IOERROR;
else if( nError ==ERRCODE_GRFILTER_FORMATERROR )
pResId = STR_GRFILTER_FORMATERROR;
else if( nError ==ERRCODE_GRFILTER_VERSIONERROR )
pResId = STR_GRFILTER_VERSIONERROR;
else if( nError ==ERRCODE_GRFILTER_FILTERERROR )
pResId = STR_GRFILTER_FILTERERROR;
else if( nError ==ERRCODE_GRFILTER_TOOBIG )
pResId = STR_GRFILTER_TOOBIG;
rSh.EndAction();
rSh.UnlockPaint();
if (pResId)
{
if( bShowError )
{
std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetFrameWeld(),
VclMessageType::Info, VclButtonsType::Ok,
SwResId(pResId)));
xInfoBox->run();
}
rReq.Ignore();
}
else
{
// set the specific graphic attributes to the graphic
bReturn = true;
AutoCaption( GRAPHIC_CAP );
rReq.Done();
}
rSh.EndUndo(); // due to possible change of Shell
}
return bReturn;
}
void SwView::Execute(SfxRequest &rReq)
{
const sal_uInt16 nSlot = rReq.GetSlot();
const SfxItemSet* pArgs = rReq.GetArgs();
const SfxPoolItem* pItem;
bool bIgnore = false;
switch( nSlot )
{
case SID_CREATE_SW_DRAWVIEW:
m_pWrtShell->getIDocumentDrawModelAccess().GetOrCreateDrawModel();
break;
case FN_LINE_NUMBERING_DLG:
{
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateVclSwViewDialog(*this));
VclAbstractDialog::AsyncContext aContext;
aContext.maEndDialogFn = [](sal_Int32){};
pDlg->StartExecuteAsync(aContext);
break;
}
case FN_EDIT_LINK_DLG:
EditLinkDlg();
break;
case SID_REFRESH_VIEW:
GetEditWin().Invalidate();
m_pWrtShell->Reformat();
break;
case FN_PAGEUP:
case FN_PAGEUP_SEL:
case FN_PAGEDOWN:
case FN_PAGEDOWN_SEL:
{
tools::Rectangle aVis( GetVisArea() );
SwEditWin& rTmpWin = GetEditWin();
if ( FN_PAGEUP == nSlot || FN_PAGEUP_SEL == nSlot )
PageUpCursor(FN_PAGEUP_SEL == nSlot);
else
PageDownCursor(FN_PAGEDOWN_SEL == nSlot);
rReq.SetReturnValue(SfxBoolItem(nSlot,
aVis != GetVisArea()));
//#i42732# - notify the edit window that from now on we do not use the input language
rTmpWin.SetUseInputLanguage( false );
}
break;
case SID_ZOOM_IN:
case SID_ZOOM_OUT:
{
sal_uInt16 nFact = m_pWrtShell->GetViewOptions()->GetZoom();
if (SID_ZOOM_IN == nSlot)
nFact = basegfx::zoomtools::zoomIn(nFact);
else
nFact = basegfx::zoomtools::zoomOut(nFact);
SetZoom(SvxZoomType::PERCENT, nFact);
}
break;
case FN_TO_PREV_PAGE:
case FN_TO_NEXT_PAGE:
{
sal_uInt16 nPage = 0;
if (m_pWrtShell->IsCursorVisible())
nPage = m_pWrtShell->GetCursor()->GetPageNum();
else
{
SwFrame* pPageFrame = m_pWrtShell->Imp()->GetFirstVisPage(m_pWrtShell->GetOut());
if (pPageFrame)
nPage = pPageFrame->GetPhyPageNum();
}
if (nPage != 0)
{
sal_uInt16 nOldPage(nPage);
if (FN_TO_PREV_PAGE == nSlot && nPage > 1)
nPage--;
else if (FN_TO_NEXT_PAGE == nSlot && nPage < m_pWrtShell->GetPageCount())
nPage++;
if (nPage != nOldPage)
{
m_pWrtShell->LockPaint(LockPaintReason::GotoPage);
if (IsDrawMode())
LeaveDrawCreate();
m_pWrtShell->EnterStdMode();
m_pWrtShell->GotoPage(nPage, true);
// set visible area (borrowed from SwView::PhyPageUp/Down)
const Point aPt(m_aVisArea.Left(), m_pWrtShell->GetPagePos(nPage).Y());
Point aAlPt(AlignToPixel(aPt));
if(aPt.Y() != aAlPt.Y())
aAlPt.AdjustY(3 * GetEditWin().PixelToLogic(Size(0, 1)).Height());
SetVisArea(aAlPt);
m_pWrtShell->UnlockPaint();
}
}
}
break;
case FN_SELECTION_CYCLE:
{
if (m_pWrtShell->IsSelFrameMode())
break;
if (!m_pWrtShell->IsStdMode())
m_pWrtShell->EnterStdMode();
SwShellCursor *pCursor = m_pWrtShell->SwCursorShell::GetCursor_();
Point CurrMarkPt = pCursor->GetMkPos();
Point CurrPointPt = pCursor->GetPtPos();
sal_uInt16 nStep = m_aSelectCycle.nStep;
if (nStep && (CurrMarkPt != m_aSelectCycle.m_MarkPt || CurrPointPt != m_aSelectCycle.m_PointPt))
nStep = 0;
switch(nStep)
{
case 0:
m_aSelectCycle.m_pInitialCursor = CurrPointPt;
m_pWrtShell->SwCursorShell::ClearMark();
m_pWrtShell->SelWrd(&CurrPointPt);
break;
case 1:
m_pWrtShell->SelSentence(&CurrPointPt);
break;
case 2:
m_pWrtShell->SelPara(&CurrPointPt);
break;
case 3:
m_pWrtShell->SwCursorShell::ClearMark();
m_pWrtShell->SwCursorShell::SetCursor(m_aSelectCycle.m_pInitialCursor);
break;
}
nStep++;
nStep %= 4;
pCursor = m_pWrtShell->SwCursorShell::GetCursor_();
m_aSelectCycle.m_MarkPt = pCursor->GetMkPos();
m_aSelectCycle.m_PointPt = pCursor->GetPtPos();
m_aSelectCycle.nStep = nStep;
}
break;
case FN_REDLINE_ON:
{
if( pArgs &&
SfxItemState::SET == pArgs->GetItemState(nSlot, false, &pItem ))
{
IDocumentRedlineAccess& rIDRA = m_pWrtShell->getIDocumentRedlineAccess();
Sequence <sal_Int8> aPasswd = rIDRA.GetRedlinePassword();
if( aPasswd.hasElements() )
{
OSL_ENSURE( !static_cast<const SfxBoolItem*>(pItem)->GetValue(), "SwView::Execute(): password set and redlining off doesn't match!" );
// xmlsec05: new password dialog
SfxPasswordDialog aPasswdDlg(GetFrameWeld());
aPasswdDlg.SetMinLen(1);
//#i69751# the result of Execute() can be ignored
(void)aPasswdDlg.run();
OUString sNewPasswd(aPasswdDlg.GetPassword());
// password verification
bool bPasswordOk = false;
if (aPasswd.getLength() == 1 && aPasswd[0] == 1)
{
// dummy RedlinePassword from OOXML import: get real password info
// from the grab-bag to verify the password
const css::uno::Sequence< css::beans::PropertyValue > aDocumentProtection =
static_cast<SfxObjectShell*>(GetDocShell())->
GetDocumentProtectionFromGrabBag();
bPasswordOk =
// password is ok, if there is no DocumentProtection in the GrabBag,
// i.e. the dummy RedlinePassword imported from an OpenDocument file
!aDocumentProtection.hasElements() ||
// verify password with the password info imported from OOXML
::comphelper::DocPasswordHelper::IsModifyPasswordCorrect(sNewPasswd,
::comphelper::DocPasswordHelper::ConvertPasswordInfo ( aDocumentProtection ) );
}
else
{
// the simplified RedlinePassword
Sequence <sal_Int8> aNewPasswd = rIDRA.GetRedlinePassword();
SvPasswordHelper::GetHashPassword( aNewPasswd, sNewPasswd );
bPasswordOk = SvPasswordHelper::CompareHashPassword(aPasswd, sNewPasswd);
}
if (bPasswordOk)
rIDRA.SetRedlinePassword(Sequence <sal_Int8> ());
else
{ // xmlsec05: message box for wrong password
std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(nullptr,
VclMessageType::Info, VclButtonsType::Ok,
SfxResId(RID_SVXSTR_INCORRECT_PASSWORD)));
xInfoBox->run();
break;
}
}
SwDocShell* pDocShell = GetDocShell();
pDocShell->SetChangeRecording( static_cast<const SfxBoolItem*>(pItem)->GetValue(), /*bLockAllViews=*/true );
// Notify all view shells of this document, as the track changes mode is document-global.
for (SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst(pDocShell); pViewFrame; pViewFrame = SfxViewFrame::GetNext(*pViewFrame, pDocShell))
{
pViewFrame->GetBindings().Invalidate(FN_REDLINE_ON);
pViewFrame->GetBindings().Update(FN_REDLINE_ON);
}
}
}
break;
case FN_REDLINE_PROTECT :
{
IDocumentRedlineAccess& rIDRA = m_pWrtShell->getIDocumentRedlineAccess();
Sequence <sal_Int8> aPasswd = rIDRA.GetRedlinePassword();
if( pArgs && SfxItemState::SET == pArgs->GetItemState(nSlot, false, &pItem )
&& static_cast<const SfxBoolItem*>(pItem)->GetValue() == aPasswd.hasElements() )
break;
// xmlsec05: new password dialog
// message box for wrong password
SfxPasswordDialog aPasswdDlg(GetFrameWeld());
aPasswdDlg.SetMinLen(1);
if (!aPasswd.hasElements())
aPasswdDlg.ShowExtras(SfxShowExtras::CONFIRM);
if (aPasswdDlg.run())
{
RedlineFlags nOn = RedlineFlags::On;
OUString sNewPasswd(aPasswdDlg.GetPassword());
Sequence <sal_Int8> aNewPasswd =
rIDRA.GetRedlinePassword();
SvPasswordHelper::GetHashPassword( aNewPasswd, sNewPasswd );
if(!aPasswd.hasElements())
{
rIDRA.SetRedlinePassword(aNewPasswd);
}
else if(SvPasswordHelper::CompareHashPassword(aPasswd, sNewPasswd))
{
rIDRA.SetRedlinePassword(Sequence <sal_Int8> ());
nOn = RedlineFlags::NONE;
}
const RedlineFlags nMode = rIDRA.GetRedlineFlags();
m_pWrtShell->SetRedlineFlagsAndCheckInsMode( (nMode & ~RedlineFlags::On) | nOn);
rReq.AppendItem( SfxBoolItem( FN_REDLINE_PROTECT, !(nMode&RedlineFlags::On) ) );
}
else
bIgnore = true;
}
break;
case FN_REDLINE_SHOW:
if( pArgs &&
SfxItemState::SET == pArgs->GetItemState(nSlot, false, &pItem))
{
// tdf#125754 avoid recursive layout
// because all views share the layout, have to use AllAction
const bool bShow = static_cast<const SfxBoolItem*>(pItem)->GetValue();
m_pWrtShell->StartAllAction();
// always show redline insertions in Hide Changes mode
if ( m_pWrtShell->GetViewOptions()->IsShowChangesInMargin() &&
m_pWrtShell->GetViewOptions()->IsShowChangesInMargin2() )
{
GetDocShell()->GetDoc()->GetDocumentRedlineManager().HideAll(/*bDeletion=*/!bShow);
}
m_pWrtShell->GetLayout()->SetHideRedlines( !bShow );
m_pWrtShell->EndAllAction();
if (m_pWrtShell->IsRedlineOn())
m_pWrtShell->SetInsMode();
}
break;
case FN_MAILMERGE_SENDMAIL_CHILDWINDOW:
case FN_REDLINE_ACCEPT:
GetViewFrame().ToggleChildWindow(nSlot);
break;
case FN_REDLINE_ACCEPT_DIRECT:
case FN_REDLINE_REJECT_DIRECT:
case FN_REDLINE_ACCEPT_TONEXT:
case FN_REDLINE_REJECT_TONEXT:
{
SwDoc *pDoc = m_pWrtShell->GetDoc();
SwPaM *pCursor = m_pWrtShell->GetCursor();
const SwRedlineTable& rRedlineTable = pDoc->getIDocumentRedlineAccess().GetRedlineTable();
SwRedlineTable::size_type nRedline = SwRedlineTable::npos;
if (pArgs && pArgs->GetItemState(nSlot, false, &pItem) == SfxItemState::SET)
{
const sal_Int64 nChangeId = static_cast<const SfxUInt32Item*>(pItem)->GetValue();
for (SwRedlineTable::size_type i = 0; i < rRedlineTable.size(); ++i)
{
if (nChangeId == rRedlineTable[i]->GetId())
nRedline = i;
}
}
if( pCursor->HasMark() && nRedline == SwRedlineTable::npos)
{
bool bAccept = FN_REDLINE_ACCEPT_DIRECT == nSlot || FN_REDLINE_ACCEPT_TONEXT == nSlot;
SwUndoId eUndoId = bAccept ? SwUndoId::ACCEPT_REDLINE : SwUndoId::REJECT_REDLINE;
SwWrtShell& rSh = GetWrtShell();
SwRewriter aRewriter;
bool bTableSelection = rSh.IsTableMode();
if ( bTableSelection )
{
aRewriter.AddRule(UndoArg1, SwResId( STR_REDLINE_TABLECHG ));
rSh.StartUndo( eUndoId, &aRewriter);
}
if ( bAccept )
m_pWrtShell->AcceptRedlinesInSelection();
else
m_pWrtShell->RejectRedlinesInSelection();
if ( bTableSelection )
rSh.EndUndo( eUndoId, &aRewriter);
}
else
{
// We check for a redline at the start of the selection/cursor, not the point.
// This ensures we work properly with FN_REDLINE_NEXT_CHANGE, which leaves the
// point at the *end* of the redline and the mark at the start (so GetRedline
// would return NULL if called on the point)
const SwRangeRedline* pRedline = nullptr;
if (nRedline != SwRedlineTable::npos)
{
// A redline was explicitly requested by specifying an
// index, don't guess based on the cursor position.
if (nRedline < rRedlineTable.size())
pRedline = rRedlineTable[nRedline];
}
else
pRedline = pDoc->getIDocumentRedlineAccess().GetRedline(*pCursor->Start(), &nRedline);
// accept or reject table row deletion or insertion
bool bTableChange = false;
if ( !pRedline && m_pWrtShell->IsCursorInTable() )
{
nRedline = 0;
auto pTabBox = pCursor->Start()->GetNode().GetTableBox();
auto pTabLine = pTabBox->GetUpper();
const SwTableNode* pTableNd = pCursor->Start()->GetNode().FindTableNode();
if ( RedlineType::None != pTabLine->GetRedlineType() )
{
nRedline = pTabLine->UpdateTextChangesOnly(nRedline);
if ( nRedline != SwRedlineTable::npos )
{
bTableChange = true;
SwWrtShell& rSh = GetWrtShell();
SwRewriter aRewriter;
aRewriter.AddRule(UndoArg1, SwResId(
rRedlineTable[nRedline]->GetType() == RedlineType::Delete
? STR_REDLINE_TABLE_ROW_DELETE
: STR_REDLINE_TABLE_ROW_INSERT ));
SwUndoId eUndoId =
(FN_REDLINE_ACCEPT_DIRECT == nSlot || FN_REDLINE_ACCEPT_TONEXT == nSlot)
? SwUndoId::ACCEPT_REDLINE
: SwUndoId::REJECT_REDLINE;
rSh.StartUndo( eUndoId, &aRewriter);
while ( nRedline != SwRedlineTable::npos && nRedline < rRedlineTable.size() )
{
pRedline = rRedlineTable[nRedline];
// until next redline is not in the same row
SwTableBox* pTableBox = pRedline->Start()->GetNode().GetTableBox();
if ( !pTableBox || pTableBox->GetUpper() != pTabLine )
break;
if (FN_REDLINE_ACCEPT_DIRECT == nSlot || FN_REDLINE_ACCEPT_TONEXT == nSlot)
m_pWrtShell->AcceptRedline(nRedline);
else
m_pWrtShell->RejectRedline(nRedline);
}
rSh.EndUndo( eUndoId, &aRewriter);
}
}
else if ( RedlineType::None != pTabBox->GetRedlineType() )
{
nRedline = pTabBox->GetRedline();
if ( nRedline != SwRedlineTable::npos )
{
bTableChange = true;
SwWrtShell& rSh = GetWrtShell();
SwRewriter aRewriter;
aRewriter.AddRule(UndoArg1, SwResId(
rRedlineTable[nRedline]->GetType() == RedlineType::Delete
? STR_REDLINE_TABLE_COLUMN_DELETE
: STR_REDLINE_TABLE_COLUMN_INSERT ));
SwUndoId eUndoId =
(FN_REDLINE_ACCEPT_DIRECT == nSlot || FN_REDLINE_ACCEPT_TONEXT == nSlot)
? SwUndoId::ACCEPT_REDLINE
: SwUndoId::REJECT_REDLINE;
// change only the cells with the same data
SwRedlineData aData(rRedlineTable[nRedline]->GetRedlineData(0));
// start from the first redline of the table to handle all the
// cells of the changed column(s)
while ( nRedline )
{
pRedline = rRedlineTable[nRedline-1];
SwTableBox* pTableBox = pRedline->Start()->GetNode().GetTableBox();
SwTableNode* pTableNode = pRedline->Start()->GetNode().FindTableNode();
// previous redline is not in the same table
if ( !pTableBox || pTableNode != pTableNd )
break;
--nRedline;
}
rSh.StartUndo( eUndoId, &aRewriter);
while ( nRedline != SwRedlineTable::npos && nRedline < rRedlineTable.size() )
{
pRedline = rRedlineTable[nRedline];
// until next redline is not in the same table
SwTableBox* pTableBox = pRedline->Start()->GetNode().GetTableBox();
SwTableNode* pTableNode = pRedline->Start()->GetNode().FindTableNode();
if ( !pTableBox || pTableNode != pTableNd )
break;
// skip cells which are not from the same author, same type change
// or timestamp, i.e. keep only the cells of the same tracked
// column insertion or deletion
if ( !pRedline->GetRedlineData(0).CanCombine(aData) ||
// not a tracked cell change
RedlineType::None == pTableBox->GetRedlineType() )
{
++nRedline;
continue;
}
if (FN_REDLINE_ACCEPT_DIRECT == nSlot || FN_REDLINE_ACCEPT_TONEXT == nSlot)
m_pWrtShell->AcceptRedline(nRedline);
else
m_pWrtShell->RejectRedline(nRedline);
}
rSh.EndUndo( eUndoId, &aRewriter);
}
}
}
else
{
assert(pRedline != nullptr);
}
if (pRedline && !bTableChange)
{
if (FN_REDLINE_ACCEPT_DIRECT == nSlot || FN_REDLINE_ACCEPT_TONEXT == nSlot)
m_pWrtShell->AcceptRedline(nRedline);
else
m_pWrtShell->RejectRedline(nRedline);
}
}
if (FN_REDLINE_ACCEPT_TONEXT == nSlot || FN_REDLINE_REJECT_TONEXT == nSlot)
{
// Go to next change after accepting or rejecting one (tdf#101977)
GetViewFrame().GetDispatcher()->Execute(FN_REDLINE_NEXT_CHANGE, SfxCallMode::ASYNCHRON);
}
}
break;
case FN_REDLINE_NEXT_CHANGE:
{
// If a parameter is provided, try going to the nth change, not to
// the next one.
SwDoc* pDoc = m_pWrtShell->GetDoc();
const SwRedlineTable& rRedlineTable = pDoc->getIDocumentRedlineAccess().GetRedlineTable();
SwRedlineTable::size_type nRedline = SwRedlineTable::npos;
if (pArgs && pArgs->GetItemState(nSlot, false, &pItem) == SfxItemState::SET)
{
const sal_uInt32 nChangeId = static_cast<const SfxUInt32Item*>(pItem)->GetValue();
for (SwRedlineTable::size_type i = 0; i < rRedlineTable.size(); ++i)
{
if (nChangeId == rRedlineTable[i]->GetId())
nRedline = i;
}
}
const SwRangeRedline *pNext = nullptr;
if (nRedline < rRedlineTable.size())
pNext = m_pWrtShell->GotoRedline(nRedline, true);
else
pNext = m_pWrtShell->SelNextRedline();
if (pNext)
{
if (comphelper::LibreOfficeKit::isActive())
{
sal_uInt32 nRedlineId = pNext->GetId();
OString aPayload(".uno:CurrentTrackedChangeId=" + OString::number(nRedlineId));
libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED, aPayload);
}
m_pWrtShell->SetInSelect();
}
}
break;
case FN_REDLINE_PREV_CHANGE:
{
const SwRangeRedline *pPrev = m_pWrtShell->SelPrevRedline();
if (pPrev)
{
if (comphelper::LibreOfficeKit::isActive())
{
sal_uInt32 nRedlineId = pPrev->GetId();
OString aPayload(".uno:CurrentTrackedChangeId=" + OString::number(nRedlineId));
libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED, aPayload);
}
m_pWrtShell->SetInSelect();
}
}
break;
case SID_DOCUMENT_COMPARE:
case SID_DOCUMENT_MERGE:
{
OUString sFileName, sFilterName;
sal_Int16 nVersion = 0;
bool bHasFileName = false;
m_pViewImpl->SetParam( 0 );
bool bNoAcceptDialog = false;
if( pArgs )
{
if( const SfxStringItem* pFileItem = pArgs->GetItemIfSet( SID_FILE_NAME, false ))
sFileName = pFileItem->GetValue();
bHasFileName = !sFileName.isEmpty();
if( const SfxStringItem* pFilterNameItem = pArgs->GetItemIfSet( SID_FILTER_NAME, false ))
sFilterName = pFilterNameItem->GetValue();
if( const SfxInt16Item* pVersionItem = pArgs->GetItemIfSet( SID_VERSION, false ))
{
nVersion = pVersionItem->GetValue();
m_pViewImpl->SetParam( nVersion );
}
if( const SfxBoolItem* pDialogItem = pArgs->GetItemIfSet( SID_NO_ACCEPT_DIALOG, false ))
{
bNoAcceptDialog = pDialogItem->GetValue();
}
}
m_pViewImpl->InitRequest( rReq );
tools::Long nFound = InsertDoc( nSlot, sFileName, sFilterName, nVersion );
if ( bHasFileName )
{
rReq.SetReturnValue( SfxInt32Item( nSlot, nFound ));
if (nFound > 0 && !bNoAcceptDialog) // show Redline browser
{
SfxViewFrame& rVFrame = GetViewFrame();
rVFrame.ShowChildWindow(FN_REDLINE_ACCEPT);
// re-initialize the Redline dialog
const sal_uInt16 nId = SwRedlineAcceptChild::GetChildWindowId();
SwRedlineAcceptChild *pRed = static_cast<SwRedlineAcceptChild*>(
rVFrame.GetChildWindow(nId));
if (pRed)
pRed->ReInitDlg(GetDocShell());
}
}
else
bIgnore = true;
}
break;
case FN_SYNC_LABELS:
GetViewFrame().ShowChildWindow(nSlot);
break;
case FN_ESCAPE:
{
if ( m_pWrtShell->HasDrawViewDrag() )
{
m_pWrtShell->BreakDrag();
m_pWrtShell->EnterSelFrameMode();
}
else if ( m_pWrtShell->IsDrawCreate() )
{
GetDrawFuncPtr()->BreakCreate();
AttrChangedNotify(nullptr); // shell change if needed
}
else if ( m_pWrtShell->HasSelection() || IsDrawMode() )
{
SdrView *pSdrView = m_pWrtShell->HasDrawView() ? m_pWrtShell->GetDrawView() : nullptr;
if(pSdrView && pSdrView->GetMarkedObjectList().GetMarkCount() != 0 &&
pSdrView->GetHdlList().GetFocusHdl())
{
const_cast<SdrHdlList&>(pSdrView->GetHdlList()).ResetFocusHdl();
}
else
{
if(pSdrView)
{
LeaveDrawCreate();
Point aPt(LONG_MIN, LONG_MIN);
//go out of the frame
m_pWrtShell->SelectObj(aPt, SW_LEAVE_FRAME);
SfxBindings& rBind = GetViewFrame().GetBindings();
rBind.Invalidate( SID_ATTR_SIZE );
}
m_pWrtShell->EnterStdMode();
AttrChangedNotify(nullptr); // shell change if necessary
}
}
else if ( GetEditWin().GetApplyTemplate() )
{
GetEditWin().SetApplyTemplate(SwApplyTemplate());
}
else if( static_cast<SfxObjectShell*>(GetDocShell())->IsInPlaceActive() )
{
Escape();
}
else if ( GetEditWin().IsChainMode() )
{
GetEditWin().SetChainMode( false );
}
else if( m_pWrtShell->GetFlyFrameFormat() )
{
const SwFrameFormat* pFormat = m_pWrtShell->GetFlyFrameFormat();
if(m_pWrtShell->GotoFly( pFormat->GetName(), FLYCNTTYPE_FRM ))
{
m_pWrtShell->HideCursor();
m_pWrtShell->EnterSelFrameMode();
}
}
else
{
SfxBoolItem aItem( SID_WIN_FULLSCREEN, false );
GetViewFrame().GetDispatcher()->ExecuteList(SID_WIN_FULLSCREEN,
SfxCallMode::RECORD, { &aItem });
bIgnore = true;
}
}
break;
case SID_ATTR_BORDER_INNER:
case SID_ATTR_BORDER_OUTER:
case SID_ATTR_BORDER_SHADOW:
if(pArgs)
m_pWrtShell->SetAttrSet(*pArgs);
break;
case SID_ATTR_PAGE:
case SID_ATTR_PAGE_SIZE:
case SID_ATTR_PAGE_MAXSIZE:
case SID_ATTR_PAGE_PAPERBIN:
case SID_ATTR_PAGE_EXT1:
case FN_PARAM_FTN_INFO:
{
if(pArgs)
{
const size_t nCurIdx = m_pWrtShell->GetCurPageDesc();
SwPageDesc aPageDesc( m_pWrtShell->GetPageDesc( nCurIdx ) );
::ItemSetToPageDesc( *pArgs, aPageDesc );
// change the descriptor of the core
m_pWrtShell->ChgPageDesc( nCurIdx, aPageDesc );
}
}
break;
case SID_GO_TO_PAGE:
{
sal_uInt16 nPhyPage, nVirPage;
GetWrtShell().GetPageNum(nPhyPage, nVirPage);
svx::GotoPageDlg aDlg(GetViewFrame().GetFrameWeld(), SwResId(STR_GOTO_PAGE_DLG_TITLE),
SwResId(ST_PGE) + ":", nPhyPage, GetWrtShell().GetPageCnt());
if (aDlg.run() == RET_OK)
GetWrtShell().GotoPage(aDlg.GetPageSelection(), true);
}
break;
case FN_EDIT_CURRENT_TOX:
{
GetViewFrame().GetDispatcher()->Execute(
FN_INSERT_MULTI_TOX, SfxCallMode::ASYNCHRON);
}
break;
case FN_UPDATE_CUR_TOX:
{
const SwTOXBase* pBase = m_pWrtShell->GetCurTOX();
if(pBase)
{
// tdf#106374: don't jump view on the update
const bool bWasLocked = m_pWrtShell->IsViewLocked();
m_pWrtShell->LockView(true);
m_pWrtShell->StartAction();
if(TOX_INDEX == pBase->GetType())
m_pWrtShell->ApplyAutoMark();
m_pWrtShell->UpdateTableOf( *pBase );
m_pWrtShell->EndAction();
if (!bWasLocked)
m_pWrtShell->LockView(false);
}
}
break;
case FN_UPDATE_TOX:
{
m_pWrtShell->StartAction();
m_pWrtShell->EnterStdMode();
bool bOldCursorInReadOnly = m_pWrtShell->IsReadOnlyAvailable();
m_pWrtShell->SetReadOnlyAvailable( true );
for( int i = 0; i < 2; ++i )
{
if( m_pWrtShell->GetTOXCount() == 1 )
++i;
while( m_pWrtShell->GotoPrevTOXBase() )
; // jump to the first "table of ..."
// if we are not in one, jump to next
const SwTOXBase* pBase = m_pWrtShell->GetCurTOX();
if( !pBase )
{
if (m_pWrtShell->GotoNextTOXBase())
pBase = m_pWrtShell->GetCurTOX();
}
bool bAutoMarkApplied = false;
while( pBase )
{
if(TOX_INDEX == pBase->GetType() && !bAutoMarkApplied)
{
m_pWrtShell->ApplyAutoMark();
bAutoMarkApplied = true;
}
// pBase is needed only for the interface. Should be changed in future! (JP 1996)
m_pWrtShell->UpdateTableOf( *pBase );
if( m_pWrtShell->GotoNextTOXBase() )
pBase = m_pWrtShell->GetCurTOX();
else
pBase = nullptr;
}
}
m_pWrtShell->SetReadOnlyAvailable( bOldCursorInReadOnly );
m_pWrtShell->EndAction();
}
break;
case SID_ATTR_BRUSH:
{
if(pArgs && SfxItemState::SET == pArgs->GetItemState(RES_BACKGROUND, false, &pItem))
{
const size_t nCurIdx = m_pWrtShell->GetCurPageDesc();
SwPageDesc aDesc( m_pWrtShell->GetPageDesc( nCurIdx ));
SwFrameFormat& rMaster = aDesc.GetMaster();
rMaster.SetFormatAttr(*pItem);
m_pWrtShell->ChgPageDesc( nCurIdx, aDesc);
}
}
break;
case SID_CLEARHISTORY:
{
m_pWrtShell->DelAllUndoObj();
}
break;
case SID_UNDO:
{
m_pShell->ExecuteSlot(rReq);
}
break;
#if defined(_WIN32) || defined UNX
case SID_TWAIN_SELECT:
case SID_TWAIN_TRANSFER:
GetViewImpl()->ExecuteScan( rReq );
break;
#endif
case SID_ATTR_DEFTABSTOP:
{
const SfxUInt16Item* pTabStopItem = nullptr;
if(pArgs && (pTabStopItem = pArgs->GetItemIfSet(SID_ATTR_DEFTABSTOP, false)))
{
SvxTabStopItem aDefTabs( 0, 0, SvxTabAdjust::Default, RES_PARATR_TABSTOP );
const sal_uInt16 nTab = pTabStopItem->GetValue();
MakeDefTabs( nTab, aDefTabs );
m_pWrtShell->SetDefault( aDefTabs );
}
}
break;
case SID_ATTR_LANGUAGE :
{
const SvxLanguageItem* pLangItem;
if(pArgs && (pLangItem = pArgs->GetItemIfSet(SID_ATTR_LANGUAGE, false)))
{
SvxLanguageItem aLang(pLangItem->GetLanguage(), RES_CHRATR_LANGUAGE);
m_pWrtShell->SetDefault( aLang );
lcl_SetAllTextToDefaultLanguage( *m_pWrtShell, RES_CHRATR_LANGUAGE );
}
}
break;
case SID_ATTR_CHAR_CTL_LANGUAGE:
if(pArgs && SfxItemState::SET == pArgs->GetItemState(RES_CHRATR_CTL_LANGUAGE, false, &pItem))
{
m_pWrtShell->SetDefault( *pItem );
lcl_SetAllTextToDefaultLanguage( *m_pWrtShell, RES_CHRATR_CTL_LANGUAGE );
}
break;
case SID_ATTR_CHAR_CJK_LANGUAGE:
if(pArgs && SfxItemState::SET == pArgs->GetItemState(RES_CHRATR_CJK_LANGUAGE, false, &pItem))
{
m_pWrtShell->SetDefault( *pItem );
lcl_SetAllTextToDefaultLanguage( *m_pWrtShell, RES_CHRATR_CJK_LANGUAGE );
}
break;
case FN_OUTLINE_LEVELS_SHOWN:
{
SwWrtShell& rSh = GetWrtShell();
int nOutlineLevel = -1;
auto nOutlinePos = rSh.GetOutlinePos();
if (nOutlinePos != SwOutlineNodes::npos)
nOutlineLevel = rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nOutlinePos);
SwNumberInputDlg aDlg(GetViewFrame().GetFrameWeld(),
SwResId(STR_OUTLINE_LEVELS_SHOWN_TITLE),
SwResId(STR_OUTLINE_LEVELS_SHOWN_SPIN_LABEL),
nOutlineLevel + 1, 1, 10,
SwResId(STR_OUTLINE_LEVELS_SHOWN_HELP_LABEL));
if (aDlg.run() == RET_OK)
rSh.MakeOutlineLevelsVisible(aDlg.GetNumber());
}
break;
case FN_TOGGLE_OUTLINE_CONTENT_VISIBILITY:
{
size_t nPos(m_pWrtShell->GetOutlinePos());
if (nPos != SwOutlineNodes::npos)
GetEditWin().ToggleOutlineContentVisibility(nPos, false);
}
break;
case FN_NAV_ELEMENT:
{
pArgs->GetItemState(GetPool().GetWhichIDFromSlotID(FN_NAV_ELEMENT), false, &pItem);
if(pItem)
{
SvxSearchDialogWrapper::SetSearchLabel(SearchLabel::Empty);
sal_uInt32 nMoveType(static_cast<const SfxUInt32Item*>(pItem)->GetValue());
SwView::SetMoveType(nMoveType);
}
}
break;
case FN_SCROLL_PREV:
case FN_SCROLL_NEXT:
{
bool *pbNext = new bool(true);
if (nSlot == FN_SCROLL_PREV)
*pbNext = false;
MoveNavigationHdl(pbNext);
}
break;
case SID_JUMPTOMARK:
if( pArgs && SfxItemState::SET == pArgs->GetItemState(SID_JUMPTOMARK, false, &pItem))
JumpToSwMark( static_cast<const SfxStringItem*>(pItem)->GetValue() );
break;
case SID_GALLERY :
// First make sure that the sidebar is visible
GetViewFrame().ShowChildWindow(SID_SIDEBAR);
::sfx2::sidebar::Sidebar::ShowPanel(
u"GalleryPanel",
GetViewFrame().GetFrame().GetFrameInterface());
break;
case SID_AVMEDIA_PLAYER :
GetViewFrame().ChildWindowExecute(rReq);
break;
case SID_VIEW_DATA_SOURCE_BROWSER:
{
SfxViewFrame& rVFrame = GetViewFrame();
rVFrame.ChildWindowExecute(rReq);
if(rVFrame.HasChildWindow(SID_BROWSER))
{
const SwDBData& rData = GetWrtShell().GetDBData();
SwModule::ShowDBObj(*this, rData);
}
}
break;
case FN_INSERT_FIELD_DATA_ONLY:
{
bool bShow = false;
if( pArgs &&
SfxItemState::SET == pArgs->GetItemState(nSlot, false, &pItem ))
bShow = static_cast<const SfxBoolItem*>(pItem)->GetValue();
if((bShow && m_bInMailMerge) != GetViewFrame().HasChildWindow(nSlot))
GetViewFrame().ToggleChildWindow(nSlot);
//if fields have been successfully inserted call the "real"
//mail merge dialog
#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
SwWrtShell &rSh = GetWrtShell();
if(m_bInMailMerge && rSh.IsAnyDatabaseFieldInDoc())
{
SwDBManager* pDBManager = rSh.GetDBManager();
if (pDBManager)
{
SwDBData aData = rSh.GetDBData();
rSh.EnterStdMode(); // force change in text shell; necessary for mixing DB fields
AttrChangedNotify(nullptr);
Sequence<PropertyValue> aProperties
{
comphelper::makePropertyValue(u"DataSourceName"_ustr, aData.sDataSource),
comphelper::makePropertyValue(u"Command"_ustr, aData.sCommand),
comphelper::makePropertyValue(u"CommandType"_ustr, aData.nCommandType)
};
pDBManager->ExecuteFormLetter(rSh, aProperties);
}
}
#endif
m_bInMailMerge &= bShow;
GetViewFrame().GetBindings().Invalidate(FN_INSERT_FIELD);
}
break;
case FN_QRY_MERGE:
{
bool bUseCurrentDocument = true;
bool bQuery = !pArgs || SfxItemState::SET != pArgs->GetItemState(nSlot);
if(bQuery)
{
SfxViewFrame& rTmpFrame = GetViewFrame();
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
ScopedVclPtr<AbstractMailMergeCreateFromDlg> pDlg(pFact->CreateMailMergeCreateFromDlg(rTmpFrame.GetFrameWeld()));
if (RET_OK == pDlg->Execute())
bUseCurrentDocument = pDlg->IsThisDocument();
else
break;
}
GenerateFormLetter(bUseCurrentDocument);
}
break;
case SID_RECHECK_DOCUMENT:
{
SwDocShell* pDocShell = GetDocShell();
SwDoc* pDoc = pDocShell->GetDoc();
uno::Reference< linguistic2::XProofreadingIterator > xGCIterator( pDoc->GetGCIterator() );
if( xGCIterator.is() )
{
xGCIterator->resetIgnoreRules();
}
// reset ignore lists
pDoc->SpellItAgainSam( true, false, false );
// clear ignore dictionary
uno::Reference< linguistic2::XDictionary > xDictionary = LinguMgr::GetIgnoreAllList();
if( xDictionary.is() )
xDictionary->clear();
// put cursor to the start of the document
m_pWrtShell->StartOfSection();
[[fallthrough]]; // call spell/grammar dialog
}
case FN_SPELL_GRAMMAR_DIALOG:
{
SfxViewFrame& rViewFrame = GetViewFrame();
if (rReq.GetArgs() != nullptr)
rViewFrame.SetChildWindow (FN_SPELL_GRAMMAR_DIALOG,
static_cast<const SfxBoolItem&>( (rReq.GetArgs()->
Get(FN_SPELL_GRAMMAR_DIALOG))).GetValue());
else
rViewFrame.ToggleChildWindow(FN_SPELL_GRAMMAR_DIALOG);
rViewFrame.GetBindings().Invalidate(FN_SPELL_GRAMMAR_DIALOG);
rReq.Ignore ();
}
break;
case SID_ALIGN_ANY_LEFT :
case SID_ALIGN_ANY_HCENTER :
case SID_ALIGN_ANY_RIGHT :
case SID_ALIGN_ANY_JUSTIFIED:
case SID_ALIGN_ANY_TOP :
case SID_ALIGN_ANY_VCENTER :
case SID_ALIGN_ANY_BOTTOM :
case SID_ALIGN_ANY_HDEFAULT :
case SID_ALIGN_ANY_VDEFAULT :
{
sal_uInt16 nAlias = 0;
if( m_nSelectionType & (SelectionType::DrawObjectEditMode|SelectionType::Text) )
{
switch( nSlot )
{
case SID_ALIGN_ANY_LEFT : nAlias = SID_ATTR_PARA_ADJUST_LEFT; break;
case SID_ALIGN_ANY_HCENTER : nAlias = SID_ATTR_PARA_ADJUST_CENTER; break;
case SID_ALIGN_ANY_RIGHT : nAlias = SID_ATTR_PARA_ADJUST_RIGHT; break;
case SID_ALIGN_ANY_JUSTIFIED: nAlias = SID_ATTR_PARA_ADJUST_BLOCK; break;
case SID_ALIGN_ANY_TOP : nAlias = SID_TABLE_VERT_NONE; break;
case SID_ALIGN_ANY_VCENTER : nAlias = SID_TABLE_VERT_CENTER; break;
case SID_ALIGN_ANY_BOTTOM : nAlias = SID_TABLE_VERT_BOTTOM; break;
}
}
else
{
switch( nSlot )
{
case SID_ALIGN_ANY_LEFT : nAlias = SID_OBJECT_ALIGN_LEFT ; break;
case SID_ALIGN_ANY_HCENTER : nAlias = SID_OBJECT_ALIGN_CENTER ; break;
case SID_ALIGN_ANY_RIGHT : nAlias = SID_OBJECT_ALIGN_RIGHT ; break;
case SID_ALIGN_ANY_TOP : nAlias = SID_OBJECT_ALIGN_UP ; break;
case SID_ALIGN_ANY_VCENTER : nAlias = SID_OBJECT_ALIGN_MIDDLE ; break;
case SID_ALIGN_ANY_BOTTOM : nAlias = SID_OBJECT_ALIGN_DOWN ; break;
}
}
//these slots are either re-mapped to text or object alignment
if (nAlias)
GetViewFrame().GetDispatcher()->Execute(
nAlias, SfxCallMode::ASYNCHRON);
}
break;
case SID_RESTORE_EDITING_VIEW:
{
//#i33307# restore editing position
Point aCursorPos;
bool bSelectObj;
if(m_pViewImpl->GetRestorePosition(aCursorPos, bSelectObj))
{
m_pWrtShell->SwCursorShell::SetCursor( aCursorPos, !bSelectObj );
if( bSelectObj )
{
m_pWrtShell->SelectObj( aCursorPos );
m_pWrtShell->EnterSelFrameMode( &aCursorPos );
}
}
}
break;
case SID_INSERT_GRAPHIC:
{
rReq.SetReturnValue(SfxBoolItem(nSlot, InsertGraphicDlg( rReq )));
}
break;
case SID_MOVE_SHAPE_HANDLE:
{
if (pArgs && pArgs->Count() >= 3)
{
SdrView *pSdrView = m_pWrtShell->HasDrawView() ? m_pWrtShell->GetDrawView() : nullptr;
if (pSdrView == nullptr)
break;
const SfxUInt32Item* handleNumItem = rReq.GetArg<SfxUInt32Item>(FN_PARAM_1);
const SfxUInt32Item* newPosXTwips = rReq.GetArg<SfxUInt32Item>(FN_PARAM_2);
const SfxUInt32Item* newPosYTwips = rReq.GetArg<SfxUInt32Item>(FN_PARAM_3);
const SfxInt32Item* OrdNum = rReq.GetArg<SfxInt32Item>(FN_PARAM_4);
const sal_uLong handleNum = handleNumItem->GetValue();
const sal_uLong newPosX = newPosXTwips->GetValue();
const sal_uLong newPosY = newPosYTwips->GetValue();
const Point mPoint(newPosX, newPosY);
const SdrHdl* handle = pSdrView->GetHdlList().GetHdl(handleNum);
if (!handle)
{
break;
}
if (handle->GetKind() == SdrHdlKind::Anchor || handle->GetKind() == SdrHdlKind::Anchor_TR)
m_pWrtShell->FindAnchorPos(mPoint, /*bMoveIt=*/true);
else
pSdrView->MoveShapeHandle(handleNum, mPoint, OrdNum ? OrdNum->GetValue() : -1);
}
break;
}
default:
OSL_ENSURE(false, "wrong dispatcher");
return;
}
if(!bIgnore)
rReq.Done();
}
bool SwView::IsConditionalFastCall( const SfxRequest &rReq )
{
sal_uInt16 nId = rReq.GetSlot();
bool bRet = false;
if (nId == FN_REDLINE_ACCEPT_DIRECT || nId == FN_REDLINE_REJECT_DIRECT)
{
if (comphelper::LibreOfficeKit::isActive())
bRet = true;
}
return bRet || SfxShell::IsConditionalFastCall(rReq);
}
/// invalidate page numbering field
void SwView::UpdatePageNums()
{
SfxBindings &rBnd = GetViewFrame().GetBindings();
rBnd.Invalidate(FN_STAT_PAGE);
}
void SwView::UpdateDocStats()
{
SfxBindings &rBnd = GetViewFrame().GetBindings();
rBnd.Invalidate( FN_STAT_WORDCOUNT );
rBnd.Update( FN_STAT_WORDCOUNT );
}
/// get status of the status line
void SwView::StateStatusLine(SfxItemSet &rSet)
{
SwWrtShell& rShell = GetWrtShell();
SfxWhichIter aIter( rSet );
sal_uInt16 nWhich = aIter.FirstWhich();
OSL_ENSURE( nWhich, "empty set");
//get section change event
const SwSection* CurrSect = rShell.GetCurrSection();
if( CurrSect )
{
const OUString& sCurrentSectionName = CurrSect->GetSectionName();
if(sCurrentSectionName != m_sOldSectionName)
{
SwCursorShell::FireSectionChangeEvent(2, 1);
}
m_sOldSectionName = sCurrentSectionName;
}
else if (!m_sOldSectionName.isEmpty())
{
SwCursorShell::FireSectionChangeEvent(2, 1);
m_sOldSectionName= OUString();
}
//get column change event
if(rShell.bColumnChange())
{
SwCursorShell::FireColumnChangeEvent(2, 1);
}
while( nWhich )
{
switch( nWhich )
{
case FN_STAT_PAGE:
{
OUString aTooltip;
OUString aPageStr;
SwVisiblePageNumbers aVisiblePageNumbers;
m_pWrtShell->GetFirstLastVisPageNumbers(aVisiblePageNumbers, m_pWrtShell->GetView());
// convert to strings and define references
OUString sFirstPhy = OUString::number(aVisiblePageNumbers.nFirstPhy);
OUString sLastPhy = OUString::number(aVisiblePageNumbers.nLastPhy);
OUString sFirstVirt = OUString::number(aVisiblePageNumbers.nFirstVirt);
OUString sLastVirt = OUString::number(aVisiblePageNumbers.nLastVirt);
OUString& sFirstCustomPhy = aVisiblePageNumbers.sFirstCustomPhy;
OUString& sLastCustomPhy = aVisiblePageNumbers.sLastCustomPhy;
OUString& sFirstCustomVirt = aVisiblePageNumbers.sFirstCustomVirt;
OUString& sLastCustomVirt = aVisiblePageNumbers.sLastCustomVirt;
OUString sPageCount = OUString::number(m_pWrtShell->GetPageCount());
if (aVisiblePageNumbers.nFirstPhy == aVisiblePageNumbers.nFirstVirt)
{
aTooltip = SwResId(STR_BOOKCTRL_HINT);
if (aVisiblePageNumbers.nFirstPhy != aVisiblePageNumbers.nLastPhy)
{
if (sFirstPhy == sFirstCustomPhy && sLastPhy == sLastCustomPhy)
{
aPageStr = SwResId(STR_PAGES_COUNT);
aPageStr = aPageStr.replaceFirst("%1", sFirstPhy);
aPageStr = aPageStr.replaceFirst("%2", sLastPhy);
aPageStr = aPageStr.replaceFirst("%3", sPageCount);
}
else
{
aPageStr = SwResId(STR_PAGES_COUNT_CUSTOM);
aPageStr = aPageStr.replaceFirst("%1", sFirstPhy);
aPageStr = aPageStr.replaceFirst("%2", sLastPhy);
aPageStr = aPageStr.replaceFirst("%3", sFirstCustomPhy);
aPageStr = aPageStr.replaceFirst("%4", sLastCustomPhy);
aPageStr = aPageStr.replaceFirst("%5", sPageCount);
}
}
else
{
if (sFirstPhy == sFirstCustomPhy && sLastPhy == sLastCustomPhy)
{
aPageStr = SwResId(STR_PAGE_COUNT);
aPageStr = aPageStr.replaceFirst("%1", sFirstPhy);
aPageStr = aPageStr.replaceFirst("%2", sPageCount);
}
else
{
aPageStr = SwResId(STR_PAGE_COUNT_CUSTOM);
aPageStr = aPageStr.replaceFirst("%1", sFirstPhy);
aPageStr = aPageStr.replaceFirst("%2", sFirstCustomPhy);
aPageStr = aPageStr.replaceFirst("%3", sPageCount);
}
}
}
else
{
aTooltip = SwResId(STR_BOOKCTRL_HINT_EXTENDED);
if (aVisiblePageNumbers.nFirstPhy != aVisiblePageNumbers.nLastPhy)
{
if (sFirstPhy == sFirstCustomPhy && sLastPhy == sLastCustomPhy)
{
aPageStr = SwResId(STR_PAGES_COUNT_EXTENDED);
aPageStr = aPageStr.replaceFirst("%1", sFirstPhy);
aPageStr = aPageStr.replaceFirst("%2", sLastPhy);
aPageStr = aPageStr.replaceFirst("%3", sPageCount);
aPageStr = aPageStr.replaceFirst("%4", sFirstVirt);
aPageStr = aPageStr.replaceFirst("%5", sLastVirt);
}
else
{
aPageStr = SwResId(STR_PAGES_COUNT_CUSTOM_EXTENDED);
aPageStr = aPageStr.replaceFirst("%1", sFirstPhy);
aPageStr = aPageStr.replaceFirst("%2", sLastPhy);
aPageStr = aPageStr.replaceFirst("%3", sFirstCustomPhy);
aPageStr = aPageStr.replaceFirst("%4", sLastCustomPhy);
aPageStr = aPageStr.replaceFirst("%5", sPageCount);
aPageStr = aPageStr.replaceFirst("%6", sFirstVirt);
aPageStr = aPageStr.replaceFirst("%7", sLastVirt);
aPageStr = aPageStr.replaceFirst("%8", sFirstCustomVirt);
aPageStr = aPageStr.replaceFirst("%9", sLastCustomVirt);
}
}
else
{
if (sFirstPhy == sFirstCustomPhy && sLastPhy == sLastCustomPhy)
{
aPageStr = SwResId(STR_PAGE_COUNT_EXTENDED);
aPageStr = aPageStr.replaceFirst("%1", sFirstPhy);
aPageStr = aPageStr.replaceFirst("%2", sPageCount);
aPageStr = aPageStr.replaceFirst("%3", sFirstVirt);
}
else
{
aPageStr = SwResId(STR_PAGE_COUNT_CUSTOM_EXTENDED);
aPageStr = aPageStr.replaceFirst("%1", sFirstPhy);
aPageStr = aPageStr.replaceFirst("%2", sFirstCustomPhy);
aPageStr = aPageStr.replaceFirst("%3", sPageCount);
aPageStr = aPageStr.replaceFirst("%4", sFirstVirt);
aPageStr = aPageStr.replaceFirst("%5", sFirstCustomVirt);
}
}
}
// replace range indicator with two pages conjunction if applicable
if ((aVisiblePageNumbers.nLastPhy - aVisiblePageNumbers.nFirstPhy) == 1)
aPageStr = aPageStr.replaceAll("-", SwResId(STR_PAGES_TWO_CONJUNCTION));
// status bar bookmark control string and tooltip
std::vector<OUString> aStringList
{
aPageStr,
aTooltip
};
rSet.Put(SfxStringListItem(FN_STAT_PAGE, &aStringList));
//if existing page number is not equal to old page number, send out this event.
if (m_nOldPageNum != aVisiblePageNumbers.nFirstPhy)
{
if (m_nOldPageNum != 0)
SwCursorShell::FirePageChangeEvent(m_nOldPageNum, aVisiblePageNumbers.nFirstPhy);
m_nOldPageNum = aVisiblePageNumbers.nFirstPhy;
}
const sal_uInt16 nCnt = GetWrtShell().GetPageCnt();
if (m_nPageCnt != nCnt) // notify Basic
{
m_nPageCnt = nCnt;
SfxGetpApp()->NotifyEvent(SfxEventHint(SfxEventHintId::SwEventPageCount, SwDocShell::GetEventName(STR_SW_EVENT_PAGE_COUNT), GetViewFrame().GetObjectShell()), false);
}
}
break;
case FN_STAT_WORDCOUNT:
{
SwDocStat selectionStats;
SwDocStat documentStats;
rShell.CountWords(selectionStats);
documentStats = rShell.GetDoc()->getIDocumentStatistics().GetUpdatedDocStat( true /* complete-async */, false /* don't update fields */ );
sal_uLong nWord = selectionStats.nChar ? selectionStats.nWord : documentStats.nWord;
sal_uLong nChar = selectionStats.nChar ? selectionStats.nChar : documentStats.nChar;
TranslateId pResId = selectionStats.nChar ? STR_WORDCOUNT : STR_WORDCOUNT_NO_SELECTION;
TranslateNId pWordResId = selectionStats.nChar ? STR_WORDCOUNT_WORDARG : STR_WORDCOUNT_WORDARG_NO_SELECTION;
TranslateNId pCharResId = selectionStats.nChar ? STR_WORDCOUNT_CHARARG : STR_WORDCOUNT_CHARARG_NO_SELECTION;
const LocaleDataWrapper& rLocaleData = Application::GetSettings().GetUILocaleDataWrapper();
OUString aWordArg = SwResId(pWordResId, nWord).replaceAll("$1", rLocaleData.getNum(nWord, 0));
OUString aCharArg = SwResId(pCharResId, nChar).replaceAll("$1", rLocaleData.getNum(nChar, 0));
OUString aWordCount(SwResId(pResId));
aWordCount = aWordCount.replaceAll("$1", aWordArg);
aWordCount = aWordCount.replaceAll("$2", aCharArg);
rSet.Put( SfxStringItem( FN_STAT_WORDCOUNT, aWordCount ) );
SwPostItMgr* pPostItMgr = rShell.GetPostItMgr();
if (pPostItMgr)
selectionStats.nComments = pPostItMgr->end() - pPostItMgr->begin();
SwWordCountWrapper *pWrdCnt = static_cast<SwWordCountWrapper*>(GetViewFrame().GetChildWindow(SwWordCountWrapper::GetChildWindowId()));
if (pWrdCnt)
pWrdCnt->SetCounts(selectionStats, documentStats);
}
break;
case FN_STAT_ACCESSIBILITY_CHECK:
{
std::unique_ptr<sw::OnlineAccessibilityCheck> const& rOnlineAccessibilityCheck = rShell.GetDoc()->getOnlineAccessibilityCheck();
if (rOnlineAccessibilityCheck)
{
sal_Int32 nIssues = rOnlineAccessibilityCheck->getNumberOfAccessibilityIssues()
+ rOnlineAccessibilityCheck->getNumberOfDocumentLevelAccessibilityIssues();
rSet.Put(SfxInt32Item(FN_STAT_ACCESSIBILITY_CHECK, nIssues));
}
}
break;
case FN_STAT_TEMPLATE:
{
rSet.Put(SfxStringItem( FN_STAT_TEMPLATE,
rShell.GetCurPageStyle()));
}
break;
case SID_ATTR_ZOOM:
{
if ( ( GetDocShell()->GetCreateMode() != SfxObjectCreateMode::EMBEDDED ) || !GetDocShell()->IsInPlaceActive() )
{
const SwViewOption* pVOpt = rShell.GetViewOptions();
SvxZoomType eZoom = pVOpt->GetZoomType();
SvxZoomItem aZoom(eZoom,
pVOpt->GetZoom());
if( pVOpt->getBrowseMode() )
{
aZoom.SetValueSet(
SvxZoomEnableFlags::N50|
SvxZoomEnableFlags::N75|
SvxZoomEnableFlags::N100|
SvxZoomEnableFlags::N150|
SvxZoomEnableFlags::N200);
}
rSet.Put( aZoom );
}
else
rSet.DisableItem( SID_ATTR_ZOOM );
}
break;
case SID_ATTR_VIEWLAYOUT:
{
if ( ( GetDocShell()->GetCreateMode() != SfxObjectCreateMode::EMBEDDED ) || !GetDocShell()->IsInPlaceActive() )
{
const SwViewOption* pVOpt = rShell.GetViewOptions();
const sal_uInt16 nColumns = pVOpt->GetViewLayoutColumns();
const bool bBookMode = pVOpt->IsViewLayoutBookMode();
SvxViewLayoutItem aViewLayout(nColumns, bBookMode);
rSet.Put( aViewLayout );
}
else
rSet.DisableItem( SID_ATTR_VIEWLAYOUT );
}
break;
case SID_ATTR_ZOOMSLIDER:
{
if ( ( GetDocShell()->GetCreateMode() != SfxObjectCreateMode::EMBEDDED ) || !GetDocShell()->IsInPlaceActive() )
{
const SwViewOption* pVOpt = rShell.GetViewOptions();
const sal_uInt16 nCurrentZoom = pVOpt->GetZoom();
SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM, MAXZOOM );
aZoomSliderItem.AddSnappingPoint( 100 );
if ( !m_pWrtShell->getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE) )
{
const sal_uInt16 nColumns = pVOpt->GetViewLayoutColumns();
const bool bAutomaticViewLayout = 0 == nColumns;
const SwPostItMgr* pMgr = GetPostItMgr();
// snapping points:
// automatic mode: 1 Page, 2 Pages, 100%
// n Columns mode: n Pages, 100%
// n Columns book mode: nPages without gaps, 100%
const SwRect aPageRect( m_pWrtShell->GetAnyCurRect( CurRectType::PageCalc ) );
const SwRect aRootRect( m_pWrtShell->GetAnyCurRect( CurRectType::PagesArea ) ); // width of columns
Size aPageSize( aPageRect.SSize() );
aPageSize.AdjustWidth(pMgr->HasNotes() && pMgr->ShowNotes() ?
pMgr->GetSidebarWidth() + pMgr->GetSidebarBorderWidth() :
0 );
Size aRootSize( aRootRect.SSize() );
const MapMode aTmpMap( MapUnit::MapTwip );
const Size aEditSize = GetEditWin().GetOutputSizePixel();
const Size aWindowSize( GetEditWin().PixelToLogic( aEditSize, aTmpMap ) );
const tools::Long nOf = pVOpt->GetDocumentBorder() * 2;
tools::Long nTmpWidth = bAutomaticViewLayout ? aPageSize.Width() : aRootSize.Width();
nTmpWidth += nOf;
aPageSize.AdjustHeight(nOf );
tools::Long nFac = aWindowSize.Width() * 100 / nTmpWidth;
tools::Long nVisPercent = aWindowSize.Height() * 100 / aPageSize.Height();
nFac = std::min( nFac, nVisPercent );
if (nFac >= MINZOOM)
{
aZoomSliderItem.AddSnappingPoint( nFac );
}
if ( bAutomaticViewLayout )
{
nTmpWidth += aPageSize.Width() + pVOpt->GetGapBetweenPages();
nFac = aWindowSize.Width() * 100 / nTmpWidth;
nFac = std::min( nFac, nVisPercent );
if (nFac >= MINZOOM)
{
aZoomSliderItem.AddSnappingPoint( nFac );
}
}
}
rSet.Put( aZoomSliderItem );
}
else
rSet.DisableItem( SID_ATTR_ZOOMSLIDER );
}
break;
case SID_ATTR_POSITION:
case SID_ATTR_SIZE:
{
if( !rShell.IsFrameSelected() && !rShell.IsObjSelected() )
SwBaseShell::SetFrameMode_( FLY_DRAG_END );
else
{
FlyMode eFrameMode = SwBaseShell::GetFrameMode();
if ( eFrameMode == FLY_DRAG_START || eFrameMode == FLY_DRAG )
{
if ( nWhich == SID_ATTR_POSITION )
rSet.Put( SfxPointItem( SID_ATTR_POSITION,
rShell.GetAnchorObjDiff()));
else
rSet.Put( SvxSizeItem( SID_ATTR_SIZE,
rShell.GetObjSize()));
}
}
}
break;
case SID_TABLE_CELL:
if( rShell.IsFrameSelected() || rShell.IsObjSelected() )
{
// #i39171# Don't put a SvxSizeItem into a slot which is defined as SfxStringItem.
// SvxPosSizeStatusBarControl no longer resets to empty display if only one slot
// has no item, so SID_TABLE_CELL can remain empty (the SvxSizeItem is supplied
// in SID_ATTR_SIZE).
}
else
{
StatusCategory eCategory(StatusCategory::NONE);
OUString sStr;
if( rShell.IsCursorInTable() )
{
// table name + cell coordinate
sStr = rShell.GetTableFormat()->GetName() + ":" + rShell.GetBoxNms();
eCategory = StatusCategory::TableCell;
}
else
{
const SwSection* pCurrSect = rShell.GetCurrSection();
if( pCurrSect )
{
switch( pCurrSect->GetType() )
{
case SectionType::ToxHeader:
case SectionType::ToxContent:
{
const SwTOXBase* pTOX = m_pWrtShell->GetCurTOX();
if( pTOX )
{
sStr = pTOX->GetTOXName();
eCategory = StatusCategory::TableOfContents;
}
else
{
OSL_ENSURE( false,
"Unknown kind of section" );
sStr = pCurrSect->GetSectionName();
eCategory = StatusCategory::Section;
}
}
break;
default:
sStr = pCurrSect->GetSectionName();
eCategory = StatusCategory::Section;
break;
}
}
}
const SwNumRule* pNumRule = rShell.GetNumRuleAtCurrCursorPos();
const bool bOutlineNum = pNumRule && pNumRule->IsOutlineRule();
if (pNumRule && !bOutlineNum ) // cursor in numbering
{
sal_uInt8 nNumLevel = rShell.GetNumLevel();
if ( nNumLevel < MAXLEVEL )
{
if(!pNumRule->IsAutoRule())
{
SfxItemSetFixed<RES_PARATR_NUMRULE, RES_PARATR_NUMRULE> aSet(GetPool());
rShell.GetCurAttr(aSet);
if(SfxItemState::DEFAULT <=
aSet.GetItemState(RES_PARATR_NUMRULE))
{
const OUString& rNumStyle =
aSet.Get(RES_PARATR_NUMRULE).GetValue();
if(!rNumStyle.isEmpty())
{
if(!sStr.isEmpty())
sStr += sStatusDelim;
if (eCategory == StatusCategory::NONE)
eCategory = StatusCategory::ListStyle;
sStr += rNumStyle;
}
}
}
if (!sStr.isEmpty())
sStr += sStatusDelim;
sStr += SwResId(STR_NUM_LEVEL) + OUString::number( nNumLevel + 1 );
if (eCategory == StatusCategory::NONE)
eCategory = StatusCategory::Numbering;
}
}
const int nOutlineLevel = rShell.GetCurrentParaOutlineLevel();
if( nOutlineLevel != 0 )
{
if (!sStr.isEmpty())
sStr += " , ";
if( bOutlineNum )
{
sStr += SwResId(STR_OUTLINE_NUMBERING) +
sStatusDelim + SwResId(STR_NUM_LEVEL);
}
else
sStr += SwResId(STR_NUM_OUTLINE);
sStr += OUString::number( nOutlineLevel);
if (eCategory == StatusCategory::NONE)
eCategory = StatusCategory::Numbering;
}
if( rShell.HasReadonlySel() )
{
if (!sStr.isEmpty())
sStr = sStatusDelim + sStr;
sStr = SwResId(SW_STR_READONLY) + sStr;
}
if (!sStr.isEmpty())
rSet.Put( SvxStatusItem( SID_TABLE_CELL, sStr, eCategory ));
}
break;
case FN_STAT_SELMODE:
{
if(rShell.IsStdMode())
rSet.Put(SfxUInt16Item(FN_STAT_SELMODE, 0));
else if(rShell.IsAddMode())
rSet.Put(SfxUInt16Item(FN_STAT_SELMODE, 2));
else if(rShell.IsBlockMode())
rSet.Put(SfxUInt16Item(FN_STAT_SELMODE, 3));
else
rSet.Put(SfxUInt16Item(FN_STAT_SELMODE, 1));
break;
}
case SID_ATTR_INSERT:
if( rShell.IsRedlineOn() )
rSet.DisableItem( nWhich );
else
{
rSet.Put(SfxBoolItem(SID_ATTR_INSERT,rShell.IsInsMode()));
}
break;
}
nWhich = aIter.NextWhich();
}
}
/** execute method for the status line
*
* @param rReq ???
*/
void SwView::ExecuteStatusLine(SfxRequest &rReq)
{
SwWrtShell &rSh = GetWrtShell();
const SfxItemSet* pArgs = rReq.GetArgs();
const SfxPoolItem* pItem=nullptr;
bool bUp = false;
sal_uInt16 nWhich = rReq.GetSlot();
switch( nWhich )
{
case FN_STAT_PAGE:
{
GetViewFrame().GetDispatcher()->Execute( SID_GO_TO_PAGE,
SfxCallMode::SYNCHRON|SfxCallMode::RECORD );
}
break;
case FN_STAT_WORDCOUNT:
{
GetViewFrame().GetDispatcher()->Execute(FN_WORDCOUNT_DIALOG,
SfxCallMode::SYNCHRON|SfxCallMode::RECORD );
}
break;
case FN_STAT_ACCESSIBILITY_CHECK:
{
const SfxStringItem sDeckName(SID_SIDEBAR_DECK, u"A11yCheckDeck"_ustr);
GetViewFrame().GetDispatcher()->ExecuteList(SID_SIDEBAR_DECK, SfxCallMode::RECORD,
{ &sDeckName });
}
break;
case FN_STAT_BOOKMARK:
if ( pArgs )
{
if (SfxItemState::SET == pArgs->GetItemState( nWhich, true, &pItem))
{
const IDocumentMarkAccess* pMarkAccess = rSh.getIDocumentMarkAccess();
const sal_Int32 nIdx = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
if(nIdx < pMarkAccess->getBookmarksCount())
{
const auto ppBookmark = rSh.getIDocumentMarkAccess()->getBookmarksBegin() + nIdx;
rSh.EnterStdMode();
rSh.GotoMark( *ppBookmark );
}
else
OSL_FAIL("SwView::ExecuteStatusLine(..)"
" - Ignoring out of range bookmark index");
}
}
break;
case FN_STAT_TEMPLATE:
{
weld::Window* pDialogParent = GetViewFrame().GetFrameWeld();
css::uno::Any aAny(pDialogParent->GetXWindow());
SfxUnoAnyItem aDialogParent(SID_DIALOG_PARENT, aAny);
const SfxPoolItem* pInternalItems[ 2 ];
pInternalItems[ 0 ] = &aDialogParent;
pInternalItems[ 1 ] = nullptr;
GetViewFrame().GetDispatcher()->Execute(FN_FORMAT_PAGE_DLG,
SfxCallMode::SYNCHRON|SfxCallMode::RECORD,
nullptr, 0, pInternalItems);
}
break;
case SID_ATTR_ZOOM:
{
if ( ( GetDocShell()->GetCreateMode() != SfxObjectCreateMode::EMBEDDED ) || !GetDocShell()->IsInPlaceActive() )
{
const SfxItemSet *pSet = nullptr;
ScopedVclPtr<AbstractSvxZoomDialog> pDlg;
if ( pArgs )
pSet = pArgs;
else
{
const SwViewOption& rViewOptions = *rSh.GetViewOptions();
SfxItemSetFixed<SID_ATTR_ZOOM, SID_ATTR_ZOOM, SID_ATTR_VIEWLAYOUT, SID_ATTR_VIEWLAYOUT> aCoreSet(m_pShell->GetPool());
SvxZoomItem aZoom( rViewOptions.GetZoomType(), rViewOptions.GetZoom() );
const bool bBrowseMode = rSh.GetViewOptions()->getBrowseMode();
if( bBrowseMode )
{
aZoom.SetValueSet(
SvxZoomEnableFlags::N50|
SvxZoomEnableFlags::N75|
SvxZoomEnableFlags::N100|
SvxZoomEnableFlags::N150|
SvxZoomEnableFlags::N200);
}
aCoreSet.Put( aZoom );
if ( !bBrowseMode )
{
const SvxViewLayoutItem aViewLayout( rViewOptions.GetViewLayoutColumns(), rViewOptions.IsViewLayoutBookMode() );
aCoreSet.Put( aViewLayout );
}
SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
pDlg.disposeAndReset(pFact->CreateSvxZoomDialog(GetViewFrame().GetFrameWeld(), aCoreSet));
pDlg->SetLimits( MINZOOM, MAXZOOM );
if( pDlg->Execute() != RET_CANCEL )
pSet = pDlg->GetOutputItemSet();
}
const SvxViewLayoutItem* pViewLayoutItem = nullptr;
if ( pSet && (pViewLayoutItem = pSet->GetItemIfSet(SID_ATTR_VIEWLAYOUT)))
{
const sal_uInt16 nColumns = pViewLayoutItem->GetValue();
const bool bBookMode = pViewLayoutItem->IsBookMode();
SetViewLayout( nColumns, bBookMode );
}
const SvxZoomItem* pZoomItem = nullptr;
if ( pSet && (pZoomItem = pSet->GetItemIfSet(SID_ATTR_ZOOM)))
{
SvxZoomType eType = pZoomItem->GetType();
SetZoom( eType, pZoomItem->GetValue() );
}
bUp = true;
if ( pZoomItem )
rReq.AppendItem( *pZoomItem );
rReq.Done();
}
}
break;
case SID_ATTR_VIEWLAYOUT:
{
if ( pArgs && !rSh.getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE) &&
( ( GetDocShell()->GetCreateMode() != SfxObjectCreateMode::EMBEDDED ) || !GetDocShell()->IsInPlaceActive() ) )
{
if ( const SvxViewLayoutItem* pLayoutItem = pArgs->GetItemIfSet(SID_ATTR_VIEWLAYOUT ))
{
const sal_uInt16 nColumns = pLayoutItem->GetValue();
const bool bBookMode = (0 != nColumns && 0 == (nColumns % 2)) && pLayoutItem->IsBookMode();
SetViewLayout( nColumns, bBookMode );
}
bUp = true;
rReq.Done();
InvalidateRulerPos();
}
}
break;
case SID_ATTR_ZOOMSLIDER:
{
if ( pArgs && ( ( GetDocShell()->GetCreateMode() != SfxObjectCreateMode::EMBEDDED ) || !GetDocShell()->IsInPlaceActive() ) )
{
if ( const SvxZoomSliderItem* pZoomItem = pArgs->GetItemIfSet(SID_ATTR_ZOOMSLIDER) )
{
const sal_uInt16 nCurrentZoom = pZoomItem->GetValue();
SetZoom( SvxZoomType::PERCENT, nCurrentZoom );
}
bUp = true;
rReq.Done();
}
}
break;
case SID_ATTR_SIZE:
{
sal_uInt16 nId = 0;
if( rSh.IsCursorInTable() )
nId = FN_FORMAT_TABLE_DLG;
else if( rSh.GetCurTOX() )
nId = FN_INSERT_MULTI_TOX;
else if( rSh.GetCurrSection() )
nId = FN_EDIT_REGION;
else
{
const SwNumRule* pNumRule = rSh.GetNumRuleAtCurrCursorPos();
if( pNumRule ) // cursor in numbering
{
if( pNumRule->IsAutoRule() )
nId = FN_NUMBER_BULLETS;
else
{
// start dialog of the painter
nId = 0;
}
}
else if( rSh.IsFrameSelected() )
nId = FN_FORMAT_FRAME_DLG;
else if( rSh.IsObjSelected() )
nId = SID_ATTR_TRANSFORM;
}
if( nId )
GetViewFrame().GetDispatcher()->Execute(nId,
SfxCallMode::SYNCHRON | SfxCallMode::RECORD );
}
break;
case FN_STAT_SELMODE:
{
if ( pArgs )
{
if (SfxItemState::SET == pArgs->GetItemState( nWhich, true, &pItem))
{
switch ( static_cast<const SfxUInt16Item *>(pItem)->GetValue() )
{
case 0: rSh.EnterStdMode(); break;
case 1: rSh.EnterExtMode(); break;
case 2: rSh.EnterAddMode(); break;
case 3: rSh.EnterBlockMode(); break;
}
}
}
bUp = true;
break;
}
case FN_SET_ADD_MODE:
rSh.ToggleAddMode();
nWhich = FN_STAT_SELMODE;
bUp = true;
break;
case FN_SET_BLOCK_MODE:
rSh.ToggleBlockMode();
nWhich = FN_STAT_SELMODE;
bUp = true;
break;
case FN_SET_EXT_MODE:
rSh.ToggleExtMode();
nWhich = FN_STAT_SELMODE;
bUp = true;
break;
case SID_ATTR_INSERT:
SwPostItMgr* pMgr = GetPostItMgr();
if ( pMgr && pMgr->HasActiveSidebarWin() )
{
pMgr->ToggleInsModeOnActiveSidebarWin();
}
else
rSh.ToggleInsMode();
bUp = true;
break;
}
if ( bUp )
{
SfxBindings &rBnd = GetViewFrame().GetBindings();
rBnd.Invalidate(nWhich);
rBnd.Update(nWhich);
}
}
void SwView::InsFrameMode(sal_uInt16 nCols)
{
if ( m_pWrtShell->HasWholeTabSelection() )
{
SwFlyFrameAttrMgr aMgr( true, m_pWrtShell.get(), Frmmgr_Type::TEXT, nullptr );
const SwFrameFormat &rPageFormat =
m_pWrtShell->GetPageDesc(m_pWrtShell->GetCurPageDesc()).GetMaster();
SwTwips lWidth = rPageFormat.GetFrameSize().GetWidth();
const SvxLRSpaceItem &rLR = rPageFormat.GetLRSpace();
lWidth -= rLR.GetLeft() + rLR.GetRight();
aMgr.SetSize(Size(lWidth, aMgr.GetSize().Height()));
if(nCols > 1)
{
SwFormatCol aCol;
aCol.Init( nCols, aCol.GetGutterWidth(), aCol.GetWishWidth() );
aMgr.SetCol( aCol );
}
aMgr.InsertFlyFrame();
}
else
GetEditWin().InsFrame(nCols);
}
/// show "edit link" dialog
void SwView::EditLinkDlg()
{
if (officecfg::Office::Common::Security::Scripting::DisableActiveContent::get())
{
std::unique_ptr<weld::MessageDialog> xError(
Application::CreateMessageDialog(nullptr, VclMessageType::Warning, VclButtonsType::Ok,
SvtResId(STR_WARNING_EXTERNAL_LINK_EDIT_DISABLED)));
xError->run();
return;
}
bool bWeb = dynamic_cast<SwWebView*>( this ) != nullptr;
SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
VclPtr<SfxAbstractLinksDialog> pDlg(pFact->CreateLinksDialog(GetViewFrame().GetFrameWeld(), &GetWrtShell().GetLinkManager(), bWeb));
pDlg->StartExecuteAsync(
[pDlg] (sal_Int32 /*nResult*/)->void
{
pDlg->disposeOnce();
}
);
}
namespace sw {
auto PrepareJumpToTOXMark(SwDoc const& rDoc, std::u16string_view aName)
-> std::optional<std::pair<SwTOXMark, sal_Int32>>
{
size_t const first(aName.find(toxMarkSeparator));
if (first == std::u16string_view::npos)
{
SAL_WARN("sw.ui", "JumpToTOXMark: missing separator");
return std::optional<std::pair<SwTOXMark, sal_Int32>>();
}
sal_Int32 const counter(o3tl::toInt32(aName.substr(0, first)));
if (counter <= 0)
{
SAL_WARN("sw.ui", "JumpToTOXMark: invalid counter");
return std::optional<std::pair<SwTOXMark, sal_Int32>>();
}
size_t const second(aName.find(toxMarkSeparator, first + 1));
if (second == std::u16string_view::npos)
{
SAL_WARN("sw.ui", "JumpToTOXMark: missing separator");
return std::optional<std::pair<SwTOXMark, sal_Int32>>();
}
std::u16string_view const entry(aName.substr(first + 1, second - (first + 1)));
if (aName.size() < second + 2)
{
SAL_WARN("sw.ui", "JumpToTOXMark: invalid tox");
return std::optional<std::pair<SwTOXMark, sal_Int32>>();
}
sal_uInt16 const indexType(aName[second + 1]);
std::u16string_view const indexName(aName.substr(second + 2));
SwTOXType const* pType(nullptr);
switch (indexType)
{
case 'A':
pType = rDoc.GetTOXType(TOX_INDEX, 0);
assert(pType);
break;
case 'C':
pType = rDoc.GetTOXType(TOX_CONTENT, 0);
assert(pType);
break;
case 'U':
for (auto i = rDoc.GetTOXTypeCount(TOX_USER); 0 < i; )
{
--i;
auto const pTmp(rDoc.GetTOXType(TOX_USER, i));
if (pTmp->GetTypeName() == indexName)
{
pType = pTmp;
break;
}
}
break;
}
if (!pType)
{
SAL_WARN("sw.ui", "JumpToTOXMark: tox doesn't exist");
return std::optional<std::pair<SwTOXMark, sal_Int32>>();
}
// type and alt text are the search keys
SwTOXMark tmp(pType);
tmp.SetAlternativeText(OUString(entry));
return std::optional<std::pair<SwTOXMark, sal_Int32>>(std::pair<SwTOXMark, sal_Int32>(tmp, counter));
}
} // namespace sw
static auto JumpToTOXMark(SwWrtShell & rSh, std::u16string_view aName) -> bool
{
std::optional<std::pair<SwTOXMark, sal_Int32>> const tmp(
sw::PrepareJumpToTOXMark(*rSh.GetDoc(), aName));
if (!tmp)
{
return false;
}
SwTOXMark const* pMark(&tmp->first);
// hack: check first if one exists
// need simple ptr control, else UnitTest CppunitTest_sw_uiwriter3 fails
if (!areSfxPoolItemPtrsEqual(&tmp->first, &rSh.GetDoc()->GotoTOXMark(tmp->first, TOX_SAME_NXT, rSh.IsReadOnlyAvailable())))
{
for (sal_Int32 i = 0; i < tmp->second; ++i)
{
pMark = &rSh.GotoTOXMark(*pMark, TOX_SAME_NXT);
}
return true;
}
else
{
SAL_WARN("sw.ui", "JumpToTOXMark: tox mark doesn't exist");
return false;
}
}
bool SwView::JumpToSwMark( std::u16string_view rMark )
{
bool bRet = false;
if( !rMark.empty() )
{
// place bookmark at top-center
bool bSaveCC = m_bCenterCursor;
bool bSaveCT = m_bTopCursor;
SetCursorAtTop( true );
// For scrolling the FrameSet, the corresponding shell needs to have the focus.
bool bHasShFocus = m_pWrtShell->HasShellFocus();
if( !bHasShFocus )
m_pWrtShell->ShellGetFocus();
const SwFormatINetFormat* pINet;
OUString sCmp;
OUString sMark( INetURLObject::decode( rMark,
INetURLObject::DecodeMechanism::WithCharset ));
sal_Int32 nLastPos, nPos = sMark.indexOf( cMarkSeparator );
if( -1 != nPos )
while( -1 != ( nLastPos = sMark.indexOf( cMarkSeparator, nPos + 1 )) )
nPos = nLastPos;
IDocumentMarkAccess::const_iterator ppMark;
IDocumentMarkAccess* const pMarkAccess = m_pWrtShell->getIDocumentMarkAccess();
if( -1 != nPos )
sCmp = sMark.copy(nPos + 1).replaceAll(" ", "");
if( !sCmp.isEmpty() )
{
OUString sName( sMark.copy( 0, nPos ) );
sCmp = sCmp.toAsciiLowerCase();
FlyCntType eFlyType = FLYCNTTYPE_ALL;
if (sCmp == "drawingobject")
bRet = m_pWrtShell->GotoDrawingObject(sName);
else if( sCmp == "region" )
{
m_pWrtShell->EnterStdMode();
bRet = m_pWrtShell->GotoRegion( sName );
}
else if( sCmp == "outline" )
{
m_pWrtShell->EnterStdMode();
bRet = m_pWrtShell->GotoOutline( sName );
}
else if( sCmp == "frame" )
eFlyType = FLYCNTTYPE_FRM;
else if( sCmp == "graphic" )
eFlyType = FLYCNTTYPE_GRF;
else if( sCmp == "ole" )
eFlyType = FLYCNTTYPE_OLE;
else if( sCmp == "table" )
{
m_pWrtShell->EnterStdMode();
bRet = m_pWrtShell->GotoTable( sName );
}
else if( sCmp == "sequence" )
{
m_pWrtShell->EnterStdMode();
sal_Int32 nNoPos = sName.indexOf( cSequenceMarkSeparator );
if ( nNoPos != -1 )
{
sal_uInt16 nSeqNo = o3tl::toInt32(sName.subView( nNoPos + 1 ));
sName = sName.copy( 0, nNoPos );
bRet = m_pWrtShell->GotoRefMark(sName, REF_SEQUENCEFLD, nSeqNo);
}
}
else if (sCmp == "toxmark")
{
bRet = JumpToTOXMark(*m_pWrtShell, sName);
}
else if( sCmp == "text" )
{
// normal text search
m_pWrtShell->EnterStdMode();
i18nutil::SearchOptions2 aSearchOpt(
0,
sName, OUString(),
SvtSysLocale().GetLanguageTag().getLocale(),
0,0,0,
TransliterationFlags::IGNORE_CASE,
SearchAlgorithms2::ABSOLUTE,
'\\' );
//todo/mba: assuming that notes shouldn't be searched
if( m_pWrtShell->SearchPattern( aSearchOpt, false/*bSearchInNotes*/, SwDocPositions::Start, SwDocPositions::End ))
{
m_pWrtShell->EnterStdMode(); // remove the selection
bRet = true;
}
}
else if( pMarkAccess->getAllMarksEnd() != (ppMark = pMarkAccess->findMark(sMark)) )
{
bRet = m_pWrtShell->GotoMark( *ppMark, false );
}
else if( nullptr != ( pINet = m_pWrtShell->FindINetAttr( sMark ) )) {
m_pWrtShell->addCurrentPosition();
bRet = m_pWrtShell->GotoINetAttr( *pINet->GetTextINetFormat() );
}
// for all types of Flys
if( FLYCNTTYPE_ALL != eFlyType && m_pWrtShell->GotoFly( sName, eFlyType ))
{
bRet = true;
if( FLYCNTTYPE_FRM == eFlyType )
{
// TextFrames: set Cursor in the frame
m_pWrtShell->UnSelectFrame();
m_pWrtShell->LeaveSelFrameMode();
}
else
{
m_pWrtShell->HideCursor();
m_pWrtShell->EnterSelFrameMode();
}
}
}
else if( pMarkAccess->getAllMarksEnd() != (ppMark = pMarkAccess->findMark(sMark)))
{
bRet = m_pWrtShell->GotoMark( *ppMark, false );
}
else if( nullptr != ( pINet = m_pWrtShell->FindINetAttr( sMark ) ))
bRet = m_pWrtShell->GotoINetAttr( *pINet->GetTextINetFormat() );
// make selection visible later
if ( m_aVisArea.IsEmpty() )
m_bMakeSelectionVisible = true;
// reset ViewStatus
SetCursorAtTop( bSaveCT, bSaveCC );
if(!m_pWrtShell->IsFrameSelected() && !m_pWrtShell->IsObjSelected())
m_pWrtShell->ShowCursor();
if( !bHasShFocus )
m_pWrtShell->ShellLoseFocus();
}
return bRet;
}
// #i67305# Undo after insert from file:
// Undo "Insert form file" crashes with documents imported from binary filter (.sdw) => disabled
// Undo "Insert form file" crashes with (.odt) documents crashes if these documents contains
// page styles with active header/footer => disabled for those documents
static size_t lcl_PageDescWithHeader( const SwDoc& rDoc )
{
size_t nRet = 0;
size_t nCnt = rDoc.GetPageDescCnt();
for( size_t i = 0; i < nCnt; ++i )
{
const SwPageDesc& rPageDesc = rDoc.GetPageDesc( i );
const SwFrameFormat& rMaster = rPageDesc.GetMaster();
const SwFormatHeader* pHeaderItem = rMaster.GetAttrSet().GetItemIfSet( RES_HEADER, false );
const SwFormatFooter* pFooterItem = rMaster.GetAttrSet().GetItemIfSet( RES_FOOTER, false );
if( (pHeaderItem && pHeaderItem->IsActive()) ||
(pFooterItem && pFooterItem->IsActive()) )
++nRet;
}
return nRet; // number of page styles with active header/footer
}
void SwView::ExecuteInsertDoc( SfxRequest& rRequest, const SfxPoolItem* pItem )
{
m_pViewImpl->InitRequest( rRequest );
m_pViewImpl->SetParam( pItem ? 1 : 0 );
const sal_uInt16 nSlot = rRequest.GetSlot();
if ( !pItem )
{
InsertDoc( nSlot, u""_ustr, u""_ustr );
}
else
{
OUString sFile, sFilter;
sFile = static_cast<const SfxStringItem *>( pItem )->GetValue();
if ( SfxItemState::SET == rRequest.GetArgs()->GetItemState( FN_PARAM_1, true, &pItem ) )
sFilter = static_cast<const SfxStringItem *>(pItem )->GetValue();
bool bHasFileName = !sFile.isEmpty();
tools::Long nFound = InsertDoc( nSlot, sFile, sFilter );
if ( bHasFileName )
{
rRequest.SetReturnValue( SfxBoolItem( nSlot, nFound != -1 ) );
rRequest.Done();
}
}
}
tools::Long SwView::InsertDoc( sal_uInt16 nSlotId, const OUString& rFileName, const OUString& rFilterName, sal_Int16 nVersion )
{
std::unique_ptr<SfxMedium> pMed;
SwDocShell* pDocSh = GetDocShell();
if( !rFileName.isEmpty() )
{
SfxObjectFactory& rFact = pDocSh->GetFactory();
std::shared_ptr<const SfxFilter> pFilter = rFact.GetFilterContainer()->GetFilter4FilterName( rFilterName );
if ( !pFilter )
{
pMed.reset(new SfxMedium(rFileName, StreamMode::READ, nullptr, nullptr ));
SfxFilterMatcher aMatcher( rFact.GetFilterContainer()->GetName() );
pMed->UseInteractionHandler( true );
ErrCode nErr = aMatcher.GuessFilter(*pMed, pFilter, SfxFilterFlags::NONE);
if ( nErr )
pMed.reset();
else
pMed->SetFilter( pFilter );
}
else
pMed.reset(new SfxMedium(rFileName, StreamMode::READ, std::move(pFilter), nullptr));
}
else
{
m_pViewImpl->StartDocumentInserter(
// tdf#118578 allow inserting any Writer document except GlobalDoc
SwDocShell::Factory().GetFactoryName(),
LINK( this, SwView, DialogClosedHdl ),
nSlotId
);
return -1;
}
if( !pMed )
return -1;
return InsertMedium( nSlotId, std::move(pMed), nVersion );
}
tools::Long SwView::InsertMedium( sal_uInt16 nSlotId, std::unique_ptr<SfxMedium> pMedium, sal_Int16 nVersion )
{
bool bInsert = false, bCompare = false;
tools::Long nFound = 0;
SwDocShell* pDocSh = GetDocShell();
switch( nSlotId )
{
case SID_DOCUMENT_MERGE: break;
case SID_DOCUMENT_COMPARE: bCompare = true; break;
case SID_INSERTDOC: bInsert = true; break;
default:
OSL_ENSURE( false, "unknown SlotId!" );
bInsert = true;
break;
}
if( bInsert )
{
uno::Reference< frame::XDispatchRecorder > xRecorder =
GetViewFrame().GetBindings().GetRecorder();
if ( xRecorder.is() )
{
SfxRequest aRequest(GetViewFrame(), SID_INSERTDOC);
aRequest.AppendItem(SfxStringItem(SID_INSERTDOC, pMedium->GetOrigURL()));
if(pMedium->GetFilter())
aRequest.AppendItem(SfxStringItem(FN_PARAM_1, pMedium->GetFilter()->GetName()));
aRequest.Done();
}
SfxObjectShellRef aRef( pDocSh );
ErrCode nError = SfxObjectShell::HandleFilter( pMedium.get(), pDocSh );
// #i16722# aborted?
if(nError != ERRCODE_NONE)
{
return -1;
}
pMedium->Download(); // start download if needed
if( aRef.is() && 1 < aRef->GetRefCount() ) // still a valid ref?
{
SwReaderPtr pRdr;
Reader *pRead = pDocSh->StartConvertFrom(*pMedium, pRdr, m_pWrtShell.get());
if( pRead ||
(pMedium->GetFilter()->GetFilterFlags() & SfxFilterFlags::STARONEFILTER) )
{
size_t nUndoCheck = 0;
SwDoc *pDoc = pDocSh->GetDoc();
if( pRead && pDocSh->GetDoc() )
nUndoCheck = lcl_PageDescWithHeader( *pDoc );
ErrCodeMsg nErrno;
{ //Scope for SwWait-Object, to be able to execute slots
//outside this scope.
SwWait aWait( *GetDocShell(), true );
m_pWrtShell->StartAllAction();
if ( m_pWrtShell->HasSelection() )
m_pWrtShell->DelRight(); // delete selections
if( pRead )
{
nErrno = pRdr->Read( *pRead ); // and insert document
pRdr.reset();
}
else
{
::sw::UndoGuard const ug(pDoc->GetIDocumentUndoRedo());
rtl::Reference<SwXTextRange> const xInsertPosition(
SwXTextRange::CreateXTextRange(*pDoc,
*m_pWrtShell->GetCursor()->GetPoint(), nullptr));
nErrno = pDocSh->ImportFrom(*pMedium, xInsertPosition)
? ERRCODE_NONE : ERR_SWG_READ_ERROR;
}
}
// update all "table of ..." sections if needed
if( m_pWrtShell->IsUpdateTOX() )
{
SfxRequest aReq( FN_UPDATE_TOX, SfxCallMode::SLOT, GetPool() );
Execute( aReq );
m_pWrtShell->SetUpdateTOX( false ); // reset
}
if( pDoc )
{ // Disable Undo for .sdw or
// if the number of page styles with header/footer has changed
if( !pRead || nUndoCheck != lcl_PageDescWithHeader( *pDoc ) )
{
pDoc->GetIDocumentUndoRedo().DelAllUndoObj();
}
}
m_pWrtShell->EndAllAction();
if( nErrno )
{
ErrorHandler::HandleError( nErrno );
nFound = nErrno.IsError() ? -1 : 0;
}
else
nFound = 0;
}
}
}
else
{
SfxObjectShellRef xDocSh;
SfxObjectShellLock xLockRef;
const int nRet = SwFindDocShell( xDocSh, xLockRef, pMedium->GetName(), OUString(),
OUString(), nVersion, pDocSh );
if( nRet )
{
SwWait aWait( *GetDocShell(), true );
m_pWrtShell->StartAllAction();
m_pWrtShell->EnterStdMode(); // delete selections
if( bCompare )
nFound = m_pWrtShell->CompareDoc( *static_cast<SwDocShell*>( xDocSh.get() )->GetDoc() );
else
nFound = m_pWrtShell->MergeDoc( *static_cast<SwDocShell*>( xDocSh.get() )->GetDoc() );
m_pWrtShell->EndAllAction();
if (!bCompare && !nFound)
{
std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetEditWin().GetFrameWeld(),
VclMessageType::Info, VclButtonsType::Ok,
SwResId(STR_NO_MERGE_ENTRY)));
xInfoBox->run();
}
if( nRet==2 && xDocSh.is() )
xDocSh->DoClose();
}
}
return nFound;
}
void SwView::EnableMailMerge()
{
m_bInMailMerge = true;
SfxBindings& rBind = GetViewFrame().GetBindings();
rBind.Invalidate(FN_INSERT_FIELD_DATA_ONLY);
rBind.Update(FN_INSERT_FIELD_DATA_ONLY);
}
#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
namespace
{
bool lcl_NeedAdditionalDataSource( const uno::Reference< XDatabaseContext >& _rDatasourceContext )
{
Sequence < OUString > aNames = _rDatasourceContext->getElementNames();
return ( !aNames.hasElements()
|| ( ( 1 == aNames.getLength() )
&& aNames.getConstArray()[0] == SW_MOD()->GetDBConfig()->GetBibliographySource().sDataSource
)
);
}
}
#endif
void SwView::GenerateFormLetter(bool bUseCurrentDocument)
{
#if !HAVE_FEATURE_DBCONNECTIVITY || ENABLE_FUZZERS
(void) bUseCurrentDocument;
#else
if(bUseCurrentDocument)
{
if(!GetWrtShell().IsAnyDatabaseFieldInDoc())
{
//check availability of data sources (except biblio source)
const uno::Reference<XComponentContext>& xContext( ::comphelper::getProcessComponentContext() );
uno::Reference<XDatabaseContext> xDBContext = DatabaseContext::create(xContext);
bool bCallAddressPilot = false;
if ( lcl_NeedAdditionalDataSource( xDBContext ) )
{
// no data sources are available - create a new one
std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), u"modules/swriter/ui/datasourcesunavailabledialog.ui"_ustr));
std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog(u"DataSourcesUnavailableDialog"_ustr));
// no cancel allowed
if (RET_OK != xQuery->run())
return;
bCallAddressPilot = true;
}
else
{
//take an existing data source or create a new one?
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
ScopedVclPtr<AbstractMailMergeFieldConnectionsDlg> pConnectionsDlg(pFact->CreateMailMergeFieldConnectionsDlg(GetFrameWeld()));
if(RET_OK == pConnectionsDlg->Execute())
bCallAddressPilot = !pConnectionsDlg->IsUseExistingConnections();
else
return;
}
if(bCallAddressPilot)
{
GetViewFrame().GetDispatcher()->Execute(
SID_ADDRESS_DATA_SOURCE, SfxCallMode::SYNCHRON);
if ( lcl_NeedAdditionalDataSource( xDBContext ) )
// no additional data source has been created
// -> assume that the user has cancelled the pilot
return;
}
//call insert fields with database field page available, only
SfxViewFrame& rVFrame = GetViewFrame();
//at first hide the default field dialog if currently visible
rVFrame.SetChildWindow(FN_INSERT_FIELD, false);
//enable the status of the db field dialog - it is disabled in the status method
//to prevent creation of the dialog without mail merge active
EnableMailMerge();
//then show the "Data base only" field dialog
SfxBoolItem aOn(FN_INSERT_FIELD_DATA_ONLY, true);
rVFrame.GetDispatcher()->ExecuteList(FN_INSERT_FIELD_DATA_ONLY,
SfxCallMode::SYNCHRON, { &aOn });
return;
}
else
{
OUString sSource;
if(!GetWrtShell().IsFieldDataSourceAvailable(sSource))
{
std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), u"modules/swriter/ui/warndatasourcedialog.ui"_ustr));
std::unique_ptr<weld::MessageDialog> xWarning(xBuilder->weld_message_dialog(u"WarnDataSourceDialog"_ustr));
OUString sTmp(xWarning->get_primary_text());
xWarning->set_primary_text(sTmp.replaceFirst("%1", sSource));
if (RET_OK == xWarning->run())
{
SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
VclPtr<VclAbstractDialog> pDlg(pFact->CreateVclDialog( nullptr, SID_OPTIONS_DATABASES ));
pDlg->StartExecuteAsync(
[pDlg] (sal_Int32 /*nResult*/)->void
{
pDlg->disposeOnce();
}
);
}
return ;
}
}
SwDBManager* pDBManager = GetWrtShell().GetDBManager();
SwDBData aData;
SwWrtShell &rSh = GetWrtShell();
std::vector<OUString> aDBNameList;
std::vector<OUString> aAllDBNames;
rSh.GetAllUsedDB( aDBNameList, &aAllDBNames );
if(!aDBNameList.empty())
{
const OUString& sDBName(aDBNameList[0]);
sal_Int32 nIdx {0};
aData.sDataSource = sDBName.getToken(0, DB_DELIM, nIdx);
aData.sCommand = sDBName.getToken(0, DB_DELIM, nIdx);
aData.nCommandType = o3tl::toInt32(o3tl::getToken(sDBName, 0, DB_DELIM, nIdx));
}
rSh.EnterStdMode(); // force change in text shell; necessary for mixing DB fields
AttrChangedNotify(nullptr);
if (pDBManager)
{
Sequence<PropertyValue> aProperties
{
comphelper::makePropertyValue(u"DataSourceName"_ustr, aData.sDataSource),
comphelper::makePropertyValue(u"Command"_ustr, aData.sCommand),
comphelper::makePropertyValue(u"CommandType"_ustr, aData.nCommandType),
};
pDBManager->ExecuteFormLetter(GetWrtShell(), aProperties);
}
}
else
{
// call documents and template dialog
SfxApplication* pSfxApp = SfxGetpApp();
weld::Window* pTopWin = pSfxApp->GetTopWindow();
SfxTemplateManagerDlg aDocTemplDlg(GetFrameWeld());
int nRet = aDocTemplDlg.run();
bool bNewWin = false;
if ( nRet == RET_OK )
{
if ( pTopWin != pSfxApp->GetTopWindow() )
{
// the dialogue opens a document -> a new TopWindow appears
pTopWin = pSfxApp->GetTopWindow();
bNewWin = true;
}
}
if (bNewWin)
{
// after the destruction of the dialogue its parent comes to top,
// but we want that the new document is on top
pTopWin->present();
}
}
#endif
}
IMPL_LINK( SwView, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg, void )
{
if ( ERRCODE_NONE != _pFileDlg->GetError() )
return;
std::unique_ptr<SfxMedium> pMed = m_pViewImpl->CreateMedium();
if ( !pMed )
{
std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetEditWin().GetFrameWeld(),
VclMessageType::Info, VclButtonsType::Ok,
SwResId(RID_SVXSTR_TXTFILTER_FILTERERROR)));
xInfoBox->run();
return;
}
const sal_uInt16 nSlot = m_pViewImpl->GetRequest()->GetSlot();
tools::Long nFound = InsertMedium( nSlot, std::move(pMed), m_pViewImpl->GetParam() );
if ( SID_INSERTDOC == nSlot )
{
if ( m_pViewImpl->GetParam() == 0 )
{
m_pViewImpl->GetRequest()->SetReturnValue( SfxBoolItem( nSlot, nFound != -1 ) );
m_pViewImpl->GetRequest()->Ignore();
}
else
{
m_pViewImpl->GetRequest()->SetReturnValue( SfxBoolItem( nSlot, nFound != -1 ) );
m_pViewImpl->GetRequest()->Done();
}
}
else if ( SID_DOCUMENT_COMPARE == nSlot || SID_DOCUMENT_MERGE == nSlot )
{
m_pViewImpl->GetRequest()->SetReturnValue( SfxInt32Item( nSlot, nFound ) );
if ( nFound > 0 ) // show Redline browser
{
SfxViewFrame& rVFrame = GetViewFrame();
rVFrame.ShowChildWindow(FN_REDLINE_ACCEPT);
// re-initialize Redline dialog
sal_uInt16 nId = SwRedlineAcceptChild::GetChildWindowId();
SwRedlineAcceptChild* pRed = static_cast<SwRedlineAcceptChild*>(rVFrame.GetChildWindow( nId ));
if ( pRed )
pRed->ReInitDlg( GetDocShell() );
}
}
}
void SwView::ExecuteScan( SfxRequest& rReq )
{
if (m_pViewImpl)
m_pViewImpl->ExecuteScan(rReq) ;
}
const OUString& SwView::GetOldGrfCat()
{
return GetCachedString(OldGrfCat);
}
void SwView::SetOldGrfCat(const OUString& sStr)
{
SetCachedString(OldGrfCat, sStr);
}
const OUString& SwView::GetOldTabCat()
{
return GetCachedString(OldTabCat);
}
void SwView::SetOldTabCat(const OUString& sStr)
{
SetCachedString(OldTabCat, sStr);
}
const OUString& SwView::GetOldFrameCat()
{
return GetCachedString(OldFrameCat);
}
void SwView::SetOldFrameCat(const OUString& sStr)
{
SetCachedString(OldFrameCat, sStr);
}
const OUString& SwView::GetOldDrwCat()
{
return GetCachedString(OldDrwCat);
}
void SwView::SetOldDrwCat(const OUString& sStr)
{
SwView::SetCachedString(OldDrwCat, sStr);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V530 The return value of function 'Execute' is required to be utilized.
↑ V530 The return value of function 'ExecuteList' is required to be utilized.
↑ V530 The return value of function 'Execute' is required to be utilized.
↑ V530 The return value of function 'ExecuteSlot' is required to be utilized.
↑ V530 The return value of function 'Execute' is required to be utilized.
↑ V530 The return value of function 'FindAnchorPos' is required to be utilized.
↑ V530 The return value of function 'Execute' is required to be utilized.
↑ V530 The return value of function 'Execute' is required to be utilized.
↑ V530 The return value of function 'ExecuteList' is required to be utilized.
↑ V530 The return value of function 'Execute' is required to be utilized.
↑ V530 The return value of function 'Execute' is required to be utilized.
↑ V530 The return value of function 'Execute' is required to be utilized.
↑ V530 The return value of function 'ExecuteList' is required to be utilized.
↑ V595 The 'pDoc' pointer was utilized before it was verified against nullptr. Check lines: 2865, 2881.
↑ V560 A part of conditional expression is always true: nRedline != SwRedlineTable::npos.