Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / uibase / uiview / view2.cxx
blob585f38b7cae1122812dec27207deaeef29134a0b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_features.h>
21 #include <config_fuzzers.h>
23 #include <com/sun/star/util/SearchAlgorithms2.hpp>
24 #include <o3tl/any.hxx>
25 #include <vcl/graphicfilter.hxx>
26 #include <com/sun/star/sdb/DatabaseContext.hpp>
27 #include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
28 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
29 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
30 #include <com/sun/star/ui/dialogs/ListboxControlActions.hpp>
31 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
32 #include <com/sun/star/linguistic2/XProofreadingIterator.hpp>
33 #include <com/sun/star/linguistic2/XDictionary.hpp>
34 #include <comphelper/propertyvalue.hxx>
35 #include <officecfg/Office/Common.hxx>
36 #include <SwCapObjType.hxx>
37 #include <SwStyleNameMapper.hxx>
38 #include <docary.hxx>
39 #include <hintids.hxx>
40 #include <SwRewriter.hxx>
41 #include <numrule.hxx>
42 #include <swundo.hxx>
43 #include <svl/PasswordHelper.hxx>
44 #include <svl/urihelper.hxx>
45 #include <sfx2/passwd.hxx>
46 #include <sfx2/sfxdlg.hxx>
47 #include <sfx2/filedlghelper.hxx>
48 #include <editeng/langitem.hxx>
49 #include <svx/linkwarn.hxx>
50 #include <svx/statusitem.hxx>
51 #include <svx/viewlayoutitem.hxx>
52 #include <svx/zoomslideritem.hxx>
53 #include <sfx2/htmlmode.hxx>
54 #include <vcl/svapp.hxx>
55 #include <sfx2/app.hxx>
56 #include <sfx2/request.hxx>
57 #include <sfx2/bindings.hxx>
58 #include <editeng/lrspitem.hxx>
59 #include <unotools/localedatawrapper.hxx>
60 #include <unotools/syslocale.hxx>
61 #include <editeng/unolingu.hxx>
62 #include <vcl/weld.hxx>
63 #include <editeng/tstpitem.hxx>
64 #include <sfx2/event.hxx>
65 #include <sfx2/docfile.hxx>
66 #include <sfx2/docfilt.hxx>
67 #include <sfx2/fcontnr.hxx>
68 #include <editeng/sizeitem.hxx>
69 #include <sfx2/dispatch.hxx>
70 #include <svl/whiter.hxx>
71 #include <svl/ptitem.hxx>
72 #include <sfx2/viewfrm.hxx>
73 #include <vcl/errinf.hxx>
74 #include <tools/urlobj.hxx>
75 #include <svx/svdview.hxx>
76 #include <swtypes.hxx>
77 #include <swwait.hxx>
78 #include <redlndlg.hxx>
79 #include <gotodlg.hxx>
80 #include <view.hxx>
81 #include <uivwimp.hxx>
82 #include <docsh.hxx>
83 #include <doc.hxx>
84 #include <printdata.hxx>
85 #include <IDocumentDeviceAccess.hxx>
86 #include <IDocumentRedlineAccess.hxx>
87 #include <DocumentRedlineManager.hxx>
88 #include <IDocumentUndoRedo.hxx>
89 #include <IDocumentSettingAccess.hxx>
90 #include <IDocumentDrawModelAccess.hxx>
91 #include <IDocumentStatistics.hxx>
92 #include <IDocumentOutlineNodes.hxx>
93 #include <wrtsh.hxx>
94 #include <viewopt.hxx>
95 #include <basesh.hxx>
96 #include <swmodule.hxx>
97 #include <uitool.hxx>
98 #include <shellio.hxx>
99 #include <fmtinfmt.hxx>
100 #include <mdiexp.hxx>
101 #include <drawbase.hxx>
102 #include <frmatr.hxx>
103 #include <frmmgr.hxx>
104 #include <pagedesc.hxx>
105 #include <section.hxx>
106 #include <tox.hxx>
107 #include <edtwin.hxx>
108 #include <wview.hxx>
109 #include <cmdid.h>
110 #include <sfx2/strings.hrc>
111 #include <sfx2/sfxresid.hxx>
112 #include <strings.hrc>
113 #include <swerror.h>
114 #include <globals.hrc>
115 #include <fmtclds.hxx>
116 #include <sfx2/templatedlg.hxx>
117 #include <dbconfig.hxx>
118 #include <dbmgr.hxx>
119 #include <reffld.hxx>
120 #include <comphelper/lok.hxx>
121 #include <comphelper/string.hxx>
122 #include <comphelper/docpasswordhelper.hxx>
124 #include <PostItMgr.hxx>
126 #include <comphelper/processfactory.hxx>
127 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
129 #include <svx/svxdlg.hxx>
130 #include <swabstdlg.hxx>
131 #include <fmthdft.hxx>
132 #include <unotextrange.hxx>
133 #include <docstat.hxx>
134 #include <wordcountdialog.hxx>
135 #include <OnlineAccessibilityCheck.hxx>
136 #include <sfx2/sidebar/Sidebar.hxx>
138 #include <vcl/GraphicNativeTransform.hxx>
139 #include <vcl/GraphicNativeMetadata.hxx>
140 #include <vcl/settings.hxx>
141 #include <i18nutil/searchopt.hxx>
142 #include <osl/diagnose.h>
143 #include <paratr.hxx>
144 #include <rootfrm.hxx>
145 #include <frameformats.hxx>
147 #include <viewimp.hxx>
148 #include <pagefrm.hxx>
150 #include <memory>
151 #include <string_view>
152 #include <svl/slstitm.hxx>
154 #include <basegfx/utils/zoomtools.hxx>
156 #include <ndtxt.hxx>
158 #include <svx/srchdlg.hxx>
159 #include <o3tl/string_view.hxx>
161 const char sStatusDelim[] = " : ";
163 using namespace sfx2;
164 using namespace ::com::sun::star;
165 using namespace ::com::sun::star::i18n;
166 using namespace ::com::sun::star::util;
167 using namespace ::com::sun::star::uno;
168 using namespace ::com::sun::star::lang;
169 using namespace ::com::sun::star::scanner;
170 using namespace ::com::sun::star::beans;
171 using namespace ::com::sun::star::container;
172 using namespace ::com::sun::star::sdb;
173 using namespace ::com::sun::star::ui::dialogs;
175 namespace {
177 class SwNumberInputDlg : public SfxDialogController
179 private:
180 std::unique_ptr<weld::Label> m_xLabel1;
181 std::unique_ptr<weld::SpinButton> m_xSpinButton;
182 std::unique_ptr<weld::Label> m_xLabel2;
183 std::unique_ptr<weld::Button> m_xOKButton;
185 DECL_LINK(InputModifiedHdl, weld::Entry&, void);
186 public:
187 SwNumberInputDlg(weld::Window* pParent, const OUString& rTitle,
188 const OUString& rLabel1, const sal_Int64 nValue, const sal_Int64 min, const sal_Int64 max,
189 OUString rLabel2 = OUString())
190 : SfxDialogController(pParent, "modules/swriter/ui/numberinput.ui", "NumberInputDialog")
191 , m_xLabel1(m_xBuilder->weld_label("label1"))
192 , m_xSpinButton(m_xBuilder->weld_spin_button("spinbutton"))
193 , m_xLabel2(m_xBuilder->weld_label("label2"))
194 , m_xOKButton(m_xBuilder->weld_button("ok"))
196 m_xDialog->set_title(rTitle);
197 m_xLabel1->set_label(rLabel1);
198 m_xSpinButton->set_value(nValue);
199 m_xSpinButton->set_range(min, max);
200 m_xSpinButton->set_position(-1);
201 m_xSpinButton->select_region(0, -1);
202 m_xSpinButton->connect_changed(LINK(this, SwNumberInputDlg, InputModifiedHdl));
203 if (!rLabel2.isEmpty())
205 m_xLabel2->set_label(rLabel2);
206 m_xLabel2->show();
210 auto GetNumber()
212 return m_xSpinButton->get_text().toInt32();
216 IMPL_LINK_NOARG(SwNumberInputDlg, InputModifiedHdl, weld::Entry&, void)
218 m_xOKButton->set_sensitive(!m_xSpinButton->get_text().isEmpty());
219 if (!m_xOKButton->get_sensitive())
220 return;
222 auto nValue = m_xSpinButton->get_text().toInt32();
223 if (nValue <= m_xSpinButton->get_min())
224 m_xSpinButton->set_value(m_xSpinButton->get_min());
225 else if (nValue > m_xSpinButton->get_max())
226 m_xSpinButton->set_value(m_xSpinButton->get_max());
227 else
228 m_xSpinButton->set_value(nValue);
230 m_xSpinButton->set_position(-1);
235 static void lcl_SetAllTextToDefaultLanguage( SwWrtShell &rWrtSh, sal_uInt16 nWhichId )
237 if (!(nWhichId == RES_CHRATR_LANGUAGE ||
238 nWhichId == RES_CHRATR_CJK_LANGUAGE ||
239 nWhichId == RES_CHRATR_CTL_LANGUAGE))
240 return;
242 rWrtSh.StartAction();
243 rWrtSh.LockView( true );
244 rWrtSh.Push();
246 // prepare to apply new language to all text in document
247 rWrtSh.SelAll();
248 rWrtSh.ExtendedSelectAll();
250 // set language attribute to default for all text
251 rWrtSh.ResetAttr({ nWhichId });
253 rWrtSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
254 rWrtSh.LockView( false );
255 rWrtSh.EndAction();
260 * Create string for showing the page number in the statusbar
262 * @param nPhyNum The physical page number
263 * @param nVirtNum The logical page number (user-assigned)
264 * @param rPgStr User-defined page name (will be shown if different from logical page number)
266 * @return OUString Formatted string: Page 1 of 10 (Page 1 of 8 to print OR Page nVirtNumv/rPgStr)
268 OUString SwView::GetPageStr(sal_uInt16 nPhyNum, sal_uInt16 nVirtNum, const OUString& rPgStr)
270 // Show user-defined page number in brackets if any.
271 OUString extra;
272 if (!rPgStr.isEmpty() && std::u16string_view(OUString::number(nPhyNum)) != rPgStr)
273 extra = rPgStr;
274 else if (nPhyNum != nVirtNum)
275 extra = OUString::number(nVirtNum);
277 sal_uInt16 nPageCount = GetWrtShell().GetPageCnt();
278 sal_uInt16 nPrintedPhyNum = nPhyNum;
279 sal_uInt16 nPrintedPageCount = nPageCount;
280 if (!GetWrtShell().getIDocumentDeviceAccess().getPrintData().IsPrintEmptyPages())
281 SwDoc::CalculateNonBlankPages(*m_pWrtShell->GetLayout(), nPrintedPageCount, nPrintedPhyNum);
282 // Show printed page numbers only, when they are different
283 OUString aStr( nPageCount != nPrintedPageCount
284 ? SwResId(STR_PAGE_COUNT_PRINTED)
285 : (extra.isEmpty() ? SwResId(STR_PAGE_COUNT) : SwResId(STR_PAGE_COUNT_CUSTOM)));
286 aStr = aStr.replaceFirst("%1", OUString::number(nPhyNum));
287 aStr = aStr.replaceFirst("%2", OUString::number(nPageCount));
288 if (nPageCount != nPrintedPageCount)
290 aStr = aStr.replaceFirst("%3", OUString::number(nPrintedPhyNum));
291 aStr = aStr.replaceFirst("%4", OUString::number(nPrintedPageCount));
293 else
294 aStr = aStr.replaceFirst("%3", extra);
296 return aStr;
299 ErrCode SwView::InsertGraphic( const OUString &rPath, const OUString &rFilter,
300 bool bLink, GraphicFilter *pFilter )
302 SwWait aWait( *GetDocShell(), true );
304 Graphic aGraphic;
305 ErrCode aResult = ERRCODE_NONE;
306 if( !pFilter )
308 pFilter = &GraphicFilter::GetGraphicFilter();
310 aResult = GraphicFilter::LoadGraphic( rPath, rFilter, aGraphic, pFilter );
312 if( ERRCODE_NONE == aResult )
314 GraphicNativeMetadata aMetadata;
315 if ( aMetadata.read(aGraphic) )
317 const Degree10 aRotation = aMetadata.getRotation();
318 if (aRotation)
320 GraphicNativeTransform aTransform( aGraphic );
321 aTransform.rotate( aRotation );
325 SwFlyFrameAttrMgr aFrameManager( true, GetWrtShellPtr(), Frmmgr_Type::GRF, nullptr );
326 SwWrtShell& rShell = GetWrtShell();
328 // #i123922# determine if we really want to insert or replace the graphic at a selected object
329 const bool bReplaceMode(rShell.HasSelection() && SelectionType::Frame == rShell.GetSelectionType());
331 if(bReplaceMode)
333 // #i123922# Do same as in D&D, ReRead graphic and all is done
334 rShell.ReRead(
335 bLink ? rPath : OUString(),
336 bLink ? rFilter : OUString(),
337 &aGraphic);
339 else
341 rShell.StartAction();
342 if( bLink )
344 SwDocShell* pDocSh = GetDocShell();
345 INetURLObject aTemp(
346 pDocSh->HasName() ?
347 pDocSh->GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE ) :
348 OUString());
350 OUString sURL = URIHelper::SmartRel2Abs(
351 aTemp, rPath, URIHelper::GetMaybeFileHdl() );
352 aGraphic.setOriginURL(sURL);
353 rShell.InsertGraphic( sURL, rFilter, aGraphic, &aFrameManager );
355 else
357 rShell.InsertGraphic( OUString(), OUString(), aGraphic, &aFrameManager );
360 // it is too late after "EndAction" because the Shell can already be destroyed.
361 rShell.EndAction();
364 return aResult;
367 bool SwView::InsertGraphicDlg( SfxRequest& rReq )
369 bool bReturn = false;
370 SwDocShell* pDocShell = GetDocShell();
371 SwDoc* pDoc = pDocShell->GetDoc();
373 OUString sGraphicFormat = SwResId(STR_POOLFRM_GRAPHIC);
375 // No file pickers in a non-desktop (mobile app) build.
377 #if HAVE_FEATURE_DESKTOP
378 // when in HTML mode insert only as a link
379 const sal_uInt16 nHtmlMode = ::GetHtmlMode(pDocShell);
380 std::unique_ptr<FileDialogHelper> pFileDlg(new FileDialogHelper(
381 ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE,
382 FileDialogFlags::Graphic, GetFrameWeld()));
383 pFileDlg->SetTitle(SwResId(STR_INSERT_GRAPHIC ));
384 pFileDlg->SetContext( FileDialogHelper::WriterInsertImage );
386 uno::Reference < XFilePicker3 > xFP = pFileDlg->GetFilePicker();
387 uno::Reference < XFilePickerControlAccess > xCtrlAcc(xFP, UNO_QUERY);
388 if(nHtmlMode & HTMLMODE_ON)
390 xCtrlAcc->setValue( ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, Any(true));
391 xCtrlAcc->enableControl( ExtendedFilePickerElementIds::CHECKBOX_LINK, false);
394 std::vector<OUString> aFormats;
395 const size_t nArrLen = pDoc->GetFrameFormats()->size();
396 for( size_t i = 0; i < nArrLen; ++i )
398 const SwFrameFormat* pFormat = (*pDoc->GetFrameFormats())[ i ];
399 if(pFormat->IsDefault() || pFormat->IsAuto())
400 continue;
401 aFormats.push_back(pFormat->GetName());
404 // pool formats
406 const std::vector<OUString>& rFramePoolArr(
407 SwStyleNameMapper::GetFrameFormatUINameArray());
408 for(const auto & i : rFramePoolArr)
410 aFormats.push_back(i);
413 std::sort(aFormats.begin(), aFormats.end());
414 aFormats.erase(std::unique(aFormats.begin(), aFormats.end()), aFormats.end());
416 Sequence<OUString> aListBoxEntries(aFormats.size());
417 OUString* pEntries = aListBoxEntries.getArray();
418 sal_Int16 nSelect = 0;
419 for( size_t i = 0; i < aFormats.size(); ++i )
421 pEntries[i] = aFormats[i];
422 if(pEntries[i] == sGraphicFormat)
423 nSelect = i;
427 Any aTemplates(&aListBoxEntries, cppu::UnoType<decltype(aListBoxEntries)>::get());
429 xCtrlAcc->setValue( ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE,
430 ListboxControlActions::ADD_ITEMS , aTemplates );
432 Any aSelectPos(&nSelect, cppu::UnoType<decltype(nSelect)>::get());
433 xCtrlAcc->setValue( ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE,
434 ListboxControlActions::SET_SELECT_ITEM, aSelectPos );
436 catch (const Exception&)
438 OSL_FAIL("control access failed");
440 #endif
442 const SfxStringItem* pName = rReq.GetArg<SfxStringItem>(SID_INSERT_GRAPHIC);
443 bool bShowError = !pName;
445 bool bHaveName = pName != nullptr;
446 #if HAVE_FEATURE_DESKTOP
447 if (!bHaveName && !Application::IsHeadlessModeEnabled())
449 // execute file dialog, without capturing mouse (tdf#156033)
450 vcl::Window* pWin = GetWindow();
451 const bool bMouseCaptured = pWin && pWin->IsMouseCaptured();
452 if (bMouseCaptured)
453 pWin->ReleaseMouse();
454 bHaveName = ERRCODE_NONE == pFileDlg->Execute();
455 if (bMouseCaptured)
456 pWin->CaptureMouse();
458 #endif
459 if (bHaveName)
462 OUString aFileName, aFilterName;
463 if ( pName )
465 aFileName = pName->GetValue();
466 const SfxStringItem* pFilter = rReq.GetArg<SfxStringItem>(FN_PARAM_FILTER);
467 if ( pFilter )
468 aFilterName = pFilter->GetValue();
470 #if HAVE_FEATURE_DESKTOP
471 else
473 aFileName = pFileDlg->GetPath();
474 aFilterName = pFileDlg->GetCurrentFilter();
475 rReq.AppendItem( SfxStringItem( SID_INSERT_GRAPHIC, aFileName ) );
476 rReq.AppendItem( SfxStringItem( FN_PARAM_FILTER, aFilterName ) );
478 bool bAsLink = false;
479 if(nHtmlMode & HTMLMODE_ON)
480 bAsLink = true;
481 else
485 Any aVal = xCtrlAcc->getValue( ExtendedFilePickerElementIds::CHECKBOX_LINK, 0);
486 OSL_ENSURE(aVal.hasValue(), "Value CBX_INSERT_AS_LINK not found");
487 bAsLink = !aVal.hasValue() || *o3tl::doAccess<bool>(aVal);
488 Any aTemplateValue = xCtrlAcc->getValue(
489 ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE,
490 ListboxControlActions::GET_SELECTED_ITEM );
491 OUString sTmpl;
492 aTemplateValue >>= sTmpl;
493 rReq.AppendItem( SfxStringItem( FN_PARAM_2, sTmpl) );
495 catch (const Exception&)
497 OSL_FAIL("control access failed");
500 rReq.AppendItem( SfxBoolItem( FN_PARAM_1, bAsLink ) );
502 const SfxBoolItem* pAsLink = rReq.GetArg<SfxBoolItem>(FN_PARAM_1);
503 const SfxStringItem* pStyle = rReq.GetArg<SfxStringItem>(FN_PARAM_2);
504 #endif
506 bool bAsLink = false;
508 #if HAVE_FEATURE_DESKTOP
509 if( nHtmlMode & HTMLMODE_ON )
510 bAsLink = true;
511 else
513 if ( rReq.GetArgs() )
515 if ( pAsLink )
516 bAsLink = pAsLink->GetValue();
517 if ( pStyle && !pStyle->GetValue().isEmpty() )
518 sGraphicFormat = pStyle->GetValue();
520 else
522 Any aVal = xCtrlAcc->getValue( ExtendedFilePickerElementIds::CHECKBOX_LINK, 0);
523 OSL_ENSURE(aVal.hasValue(), "Value CBX_INSERT_AS_LINK not found");
524 bAsLink = !aVal.hasValue() || *o3tl::doAccess<bool>(aVal);
525 Any aTemplateValue = xCtrlAcc->getValue(
526 ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE,
527 ListboxControlActions::GET_SELECTED_ITEM );
528 OUString sTmpl;
529 aTemplateValue >>= sTmpl;
530 if( !sTmpl.isEmpty() )
531 sGraphicFormat = sTmpl;
532 rReq.AppendItem( SfxStringItem( FN_PARAM_2, sGraphicFormat ) );
533 rReq.AppendItem( SfxBoolItem( FN_PARAM_1, bAsLink ) );
536 // really store as link only?
537 if( bAsLink && officecfg::Office::Common::Misc::ShowLinkWarningDialog::get() )
539 SvxLinkWarningDialog aWarnDlg(GetFrameWeld(), pFileDlg->GetPath());
540 if (aWarnDlg.run() != RET_OK)
541 bAsLink=false; // don't store as link
544 #endif
546 SwWrtShell& rSh = GetWrtShell();
547 rSh.LockPaint(LockPaintReason::InsertGraphic);
548 rSh.StartAction();
550 SwRewriter aRewriter;
551 aRewriter.AddRule(UndoArg1, SwResId(STR_GRAPHIC_DEFNAME));
553 // #i123922# determine if we really want to insert or replace the graphic at a selected object
554 const bool bReplaceMode(rSh.HasSelection() && SelectionType::Frame == rSh.GetSelectionType());
556 rSh.StartUndo(SwUndoId::INSERT, &aRewriter);
558 ErrCode nError = InsertGraphic( aFileName, aFilterName, bAsLink, &GraphicFilter::GetGraphicFilter() );
560 // format not equal to current filter (with autodetection)
561 if( nError == ERRCODE_GRFILTER_FORMATERROR )
562 nError = InsertGraphic( aFileName, OUString(), bAsLink, &GraphicFilter::GetGraphicFilter() );
564 // #i123922# no new FrameFormat for replace mode, only when new object was created,
565 // else this would reset the current setting for the frame holding the graphic
566 if ( !bReplaceMode && rSh.IsFrameSelected() )
568 SwFrameFormat* pFormat = pDoc->FindFrameFormatByName( sGraphicFormat );
569 if(!pFormat)
570 pFormat = pDoc->MakeFrameFormat(sGraphicFormat,
571 pDocShell->GetDoc()->GetDfltFrameFormat(),
572 true, false);
573 rSh.SetFrameFormat( pFormat );
576 TranslateId pResId;
577 if( nError == ERRCODE_GRFILTER_OPENERROR )
578 pResId = STR_GRFILTER_OPENERROR;
579 else if( nError == ERRCODE_GRFILTER_IOERROR )
580 pResId = STR_GRFILTER_IOERROR;
581 else if( nError ==ERRCODE_GRFILTER_FORMATERROR )
582 pResId = STR_GRFILTER_FORMATERROR;
583 else if( nError ==ERRCODE_GRFILTER_VERSIONERROR )
584 pResId = STR_GRFILTER_VERSIONERROR;
585 else if( nError ==ERRCODE_GRFILTER_FILTERERROR )
586 pResId = STR_GRFILTER_FILTERERROR;
587 else if( nError ==ERRCODE_GRFILTER_TOOBIG )
588 pResId = STR_GRFILTER_TOOBIG;
590 rSh.EndAction();
591 rSh.UnlockPaint();
592 if (pResId)
594 if( bShowError )
596 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetFrameWeld(),
597 VclMessageType::Info, VclButtonsType::Ok,
598 SwResId(pResId)));
599 xInfoBox->run();
601 rReq.Ignore();
603 else
605 // set the specific graphic attributes to the graphic
606 bReturn = true;
607 AutoCaption( GRAPHIC_CAP );
608 rReq.Done();
611 rSh.EndUndo(); // due to possible change of Shell
614 return bReturn;
617 void SwView::Execute(SfxRequest &rReq)
619 const sal_uInt16 nSlot = rReq.GetSlot();
620 const SfxItemSet* pArgs = rReq.GetArgs();
621 const SfxPoolItem* pItem;
622 bool bIgnore = false;
623 switch( nSlot )
625 case SID_CREATE_SW_DRAWVIEW:
626 m_pWrtShell->getIDocumentDrawModelAccess().GetOrCreateDrawModel();
627 break;
629 case FN_LINE_NUMBERING_DLG:
631 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
632 ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateVclSwViewDialog(*this));
633 VclAbstractDialog::AsyncContext aContext;
634 aContext.maEndDialogFn = [](sal_Int32){};
635 pDlg->StartExecuteAsync(aContext);
636 break;
638 case FN_EDIT_LINK_DLG:
639 EditLinkDlg();
640 break;
641 case SID_REFRESH_VIEW:
642 GetEditWin().Invalidate();
643 m_pWrtShell->Reformat();
644 break;
645 case FN_PAGEUP:
646 case FN_PAGEUP_SEL:
647 case FN_PAGEDOWN:
648 case FN_PAGEDOWN_SEL:
650 tools::Rectangle aVis( GetVisArea() );
651 SwEditWin& rTmpWin = GetEditWin();
652 if ( FN_PAGEUP == nSlot || FN_PAGEUP_SEL == nSlot )
653 PageUpCursor(FN_PAGEUP_SEL == nSlot);
654 else
655 PageDownCursor(FN_PAGEDOWN_SEL == nSlot);
657 rReq.SetReturnValue(SfxBoolItem(nSlot,
658 aVis != GetVisArea()));
659 //#i42732# - notify the edit window that from now on we do not use the input language
660 rTmpWin.SetUseInputLanguage( false );
662 break;
663 case SID_ZOOM_IN:
664 case SID_ZOOM_OUT:
666 sal_uInt16 nFact = m_pWrtShell->GetViewOptions()->GetZoom();
667 if (SID_ZOOM_IN == nSlot)
668 nFact = basegfx::zoomtools::zoomIn(nFact);
669 else
670 nFact = basegfx::zoomtools::zoomOut(nFact);
671 SetZoom(SvxZoomType::PERCENT, nFact);
673 break;
674 case FN_TO_PREV_PAGE:
675 case FN_TO_NEXT_PAGE:
677 sal_uInt16 nPage = 0;
678 if (m_pWrtShell->IsCursorVisible())
679 nPage = m_pWrtShell->GetCursor()->GetPageNum();
680 else
682 SwFrame* pPageFrame = m_pWrtShell->Imp()->GetFirstVisPage(m_pWrtShell->GetOut());
683 if (pPageFrame)
684 nPage = pPageFrame->GetPhyPageNum();
686 if (nPage != 0)
688 sal_uInt16 nOldPage(nPage);
689 if (FN_TO_PREV_PAGE == nSlot && nPage > 1)
690 nPage--;
691 else if (FN_TO_NEXT_PAGE == nSlot && nPage < m_pWrtShell->GetPageCount())
692 nPage++;
693 if (nPage != nOldPage)
695 m_pWrtShell->LockPaint(LockPaintReason::GotoPage);
696 if (IsDrawMode())
697 LeaveDrawCreate();
698 m_pWrtShell->EnterStdMode();
699 m_pWrtShell->GotoPage(nPage, true);
700 // set visible area (borrowed from SwView::PhyPageUp/Down)
701 const Point aPt(m_aVisArea.Left(), m_pWrtShell->GetPagePos(nPage).Y());
702 Point aAlPt(AlignToPixel(aPt));
703 if(aPt.Y() != aAlPt.Y())
704 aAlPt.AdjustY(3 * GetEditWin().PixelToLogic(Size(0, 1)).Height());
705 SetVisArea(aAlPt);
706 m_pWrtShell->UnlockPaint();
710 break;
711 case FN_SELECTION_CYCLE:
713 if (m_pWrtShell->IsSelFrameMode())
714 break;
715 if (!m_pWrtShell->IsStdMode())
716 m_pWrtShell->EnterStdMode();
717 SwShellCursor *pCursor = m_pWrtShell->SwCursorShell::GetCursor_();
718 Point CurrMarkPt = pCursor->GetMkPos();
719 Point CurrPointPt = pCursor->GetPtPos();
720 sal_uInt16 nStep = m_aSelectCycle.nStep;
721 if (nStep && (CurrMarkPt != m_aSelectCycle.m_MarkPt || CurrPointPt != m_aSelectCycle.m_PointPt))
722 nStep = 0;
723 switch(nStep)
725 case 0:
726 m_aSelectCycle.m_pInitialCursor = CurrPointPt;
727 m_pWrtShell->SwCursorShell::ClearMark();
728 m_pWrtShell->SelWrd(&CurrPointPt);
729 break;
730 case 1:
731 m_pWrtShell->SelSentence(&CurrPointPt);
732 break;
733 case 2:
734 m_pWrtShell->SelPara(&CurrPointPt);
735 break;
736 case 3:
737 m_pWrtShell->SwCursorShell::ClearMark();
738 m_pWrtShell->SwCursorShell::SetCursor(m_aSelectCycle.m_pInitialCursor);
739 break;
741 nStep++;
742 nStep %= 4;
743 pCursor = m_pWrtShell->SwCursorShell::GetCursor_();
744 m_aSelectCycle.m_MarkPt = pCursor->GetMkPos();
745 m_aSelectCycle.m_PointPt = pCursor->GetPtPos();
746 m_aSelectCycle.nStep = nStep;
748 break;
749 case FN_REDLINE_ON:
751 if( pArgs &&
752 SfxItemState::SET == pArgs->GetItemState(nSlot, false, &pItem ))
754 IDocumentRedlineAccess& rIDRA = m_pWrtShell->getIDocumentRedlineAccess();
755 Sequence <sal_Int8> aPasswd = rIDRA.GetRedlinePassword();
756 if( aPasswd.hasElements() )
758 OSL_ENSURE( !static_cast<const SfxBoolItem*>(pItem)->GetValue(), "SwView::Execute(): password set and redlining off doesn't match!" );
760 // xmlsec05: new password dialog
761 SfxPasswordDialog aPasswdDlg(GetFrameWeld());
762 aPasswdDlg.SetMinLen(1);
763 //#i69751# the result of Execute() can be ignored
764 (void)aPasswdDlg.run();
765 OUString sNewPasswd(aPasswdDlg.GetPassword());
767 // password verification
768 bool bPasswordOk = false;
769 if (aPasswd.getLength() == 1 && aPasswd[0] == 1)
771 // dummy RedlinePassword from OOXML import: get real password info
772 // from the grab-bag to verify the password
773 const css::uno::Sequence< css::beans::PropertyValue > aDocumentProtection =
774 static_cast<SfxObjectShell*>(GetDocShell())->
775 GetDocumentProtectionFromGrabBag();
777 bPasswordOk =
778 // password is ok, if there is no DocumentProtection in the GrabBag,
779 // i.e. the dummy RedlinePassword imported from an OpenDocument file
780 !aDocumentProtection.hasElements() ||
781 // verify password with the password info imported from OOXML
782 ::comphelper::DocPasswordHelper::IsModifyPasswordCorrect(sNewPasswd,
783 ::comphelper::DocPasswordHelper::ConvertPasswordInfo ( aDocumentProtection ) );
785 else
787 // the simplified RedlinePassword
788 Sequence <sal_Int8> aNewPasswd = rIDRA.GetRedlinePassword();
789 SvPasswordHelper::GetHashPassword( aNewPasswd, sNewPasswd );
790 bPasswordOk = SvPasswordHelper::CompareHashPassword(aPasswd, sNewPasswd);
793 if (bPasswordOk)
794 rIDRA.SetRedlinePassword(Sequence <sal_Int8> ());
795 else
796 { // xmlsec05: message box for wrong password
797 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(nullptr,
798 VclMessageType::Info, VclButtonsType::Ok,
799 SfxResId(RID_SVXSTR_INCORRECT_PASSWORD)));
800 xInfoBox->run();
801 break;
805 SwDocShell* pDocShell = GetDocShell();
806 pDocShell->SetChangeRecording( static_cast<const SfxBoolItem*>(pItem)->GetValue(), /*bLockAllViews=*/true );
808 // Notify all view shells of this document, as the track changes mode is document-global.
809 for (SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst(pDocShell); pViewFrame; pViewFrame = SfxViewFrame::GetNext(*pViewFrame, pDocShell))
811 pViewFrame->GetBindings().Invalidate(FN_REDLINE_ON);
812 pViewFrame->GetBindings().Update(FN_REDLINE_ON);
816 break;
817 case FN_REDLINE_PROTECT :
819 IDocumentRedlineAccess& rIDRA = m_pWrtShell->getIDocumentRedlineAccess();
820 Sequence <sal_Int8> aPasswd = rIDRA.GetRedlinePassword();
821 if( pArgs && SfxItemState::SET == pArgs->GetItemState(nSlot, false, &pItem )
822 && static_cast<const SfxBoolItem*>(pItem)->GetValue() == aPasswd.hasElements() )
823 break;
825 // xmlsec05: new password dialog
826 // message box for wrong password
827 SfxPasswordDialog aPasswdDlg(GetFrameWeld());
828 aPasswdDlg.SetMinLen(1);
829 if (!aPasswd.hasElements())
830 aPasswdDlg.ShowExtras(SfxShowExtras::CONFIRM);
831 if (aPasswdDlg.run())
833 RedlineFlags nOn = RedlineFlags::On;
834 OUString sNewPasswd(aPasswdDlg.GetPassword());
835 Sequence <sal_Int8> aNewPasswd =
836 rIDRA.GetRedlinePassword();
837 SvPasswordHelper::GetHashPassword( aNewPasswd, sNewPasswd );
838 if(!aPasswd.hasElements())
840 rIDRA.SetRedlinePassword(aNewPasswd);
842 else if(SvPasswordHelper::CompareHashPassword(aPasswd, sNewPasswd))
844 rIDRA.SetRedlinePassword(Sequence <sal_Int8> ());
845 nOn = RedlineFlags::NONE;
847 const RedlineFlags nMode = rIDRA.GetRedlineFlags();
848 m_pWrtShell->SetRedlineFlagsAndCheckInsMode( (nMode & ~RedlineFlags::On) | nOn);
849 rReq.AppendItem( SfxBoolItem( FN_REDLINE_PROTECT, !(nMode&RedlineFlags::On) ) );
851 else
852 bIgnore = true;
854 break;
855 case FN_REDLINE_SHOW:
857 if( pArgs &&
858 SfxItemState::SET == pArgs->GetItemState(nSlot, false, &pItem))
860 // tdf#125754 avoid recursive layout
861 // because all views share the layout, have to use AllAction
862 const bool bShow = static_cast<const SfxBoolItem*>(pItem)->GetValue();
863 m_pWrtShell->StartAllAction();
864 // always show redline insertions in Hide Changes mode
865 if ( m_pWrtShell->GetViewOptions()->IsShowChangesInMargin() &&
866 m_pWrtShell->GetViewOptions()->IsShowChangesInMargin2() )
868 GetDocShell()->GetDoc()->GetDocumentRedlineManager().HideAll(/*bDeletion=*/!bShow);
870 m_pWrtShell->GetLayout()->SetHideRedlines( !bShow );
871 m_pWrtShell->EndAllAction();
872 if (m_pWrtShell->IsRedlineOn())
873 m_pWrtShell->SetInsMode();
875 break;
876 case FN_MAILMERGE_SENDMAIL_CHILDWINDOW:
877 case FN_REDLINE_ACCEPT:
878 GetViewFrame().ToggleChildWindow(nSlot);
879 break;
880 case FN_REDLINE_ACCEPT_DIRECT:
881 case FN_REDLINE_REJECT_DIRECT:
882 case FN_REDLINE_ACCEPT_TONEXT:
883 case FN_REDLINE_REJECT_TONEXT:
885 SwDoc *pDoc = m_pWrtShell->GetDoc();
886 SwPaM *pCursor = m_pWrtShell->GetCursor();
887 const SwRedlineTable& rRedlineTable = pDoc->getIDocumentRedlineAccess().GetRedlineTable();
888 SwRedlineTable::size_type nRedline = SwRedlineTable::npos;
889 if (pArgs && pArgs->GetItemState(nSlot, false, &pItem) == SfxItemState::SET)
891 const sal_Int64 nChangeId = static_cast<const SfxUInt32Item*>(pItem)->GetValue();
892 for (SwRedlineTable::size_type i = 0; i < rRedlineTable.size(); ++i)
894 if (nChangeId == rRedlineTable[i]->GetId())
895 nRedline = i;
899 if( pCursor->HasMark() && nRedline == SwRedlineTable::npos)
901 bool bAccept = FN_REDLINE_ACCEPT_DIRECT == nSlot || FN_REDLINE_ACCEPT_TONEXT == nSlot;
902 SwUndoId eUndoId = bAccept ? SwUndoId::ACCEPT_REDLINE : SwUndoId::REJECT_REDLINE;
903 SwWrtShell& rSh = GetWrtShell();
904 SwRewriter aRewriter;
905 bool bTableSelection = rSh.IsTableMode();
906 if ( bTableSelection )
908 aRewriter.AddRule(UndoArg1, SwResId( STR_REDLINE_TABLECHG ));
909 rSh.StartUndo( eUndoId, &aRewriter);
911 if ( bAccept )
912 m_pWrtShell->AcceptRedlinesInSelection();
913 else
914 m_pWrtShell->RejectRedlinesInSelection();
915 if ( bTableSelection )
916 rSh.EndUndo( eUndoId, &aRewriter);
918 else
920 // We check for a redline at the start of the selection/cursor, not the point.
921 // This ensures we work properly with FN_REDLINE_NEXT_CHANGE, which leaves the
922 // point at the *end* of the redline and the mark at the start (so GetRedline
923 // would return NULL if called on the point)
924 const SwRangeRedline* pRedline = nullptr;
925 if (nRedline != SwRedlineTable::npos)
927 // A redline was explicitly requested by specifying an
928 // index, don't guess based on the cursor position.
930 if (nRedline < rRedlineTable.size())
931 pRedline = rRedlineTable[nRedline];
933 else
934 pRedline = pDoc->getIDocumentRedlineAccess().GetRedline(*pCursor->Start(), &nRedline);
936 // accept or reject table row deletion or insertion
937 bool bTableChange = false;
938 if ( !pRedline && m_pWrtShell->IsCursorInTable() )
940 nRedline = 0;
941 auto pTabBox = pCursor->Start()->GetNode().GetTableBox();
942 auto pTabLine = pTabBox->GetUpper();
943 const SwTableNode* pTableNd = pCursor->Start()->GetNode().FindTableNode();
945 if ( RedlineType::None != pTabLine->GetRedlineType() )
947 nRedline = pTabLine->UpdateTextChangesOnly(nRedline);
949 if ( nRedline != SwRedlineTable::npos )
951 bTableChange = true;
953 SwWrtShell& rSh = GetWrtShell();
954 SwRewriter aRewriter;
956 aRewriter.AddRule(UndoArg1, SwResId(
957 rRedlineTable[nRedline]->GetType() == RedlineType::Delete
958 ? STR_REDLINE_TABLE_ROW_DELETE
959 : STR_REDLINE_TABLE_ROW_INSERT ));
961 SwUndoId eUndoId =
962 (FN_REDLINE_ACCEPT_DIRECT == nSlot || FN_REDLINE_ACCEPT_TONEXT == nSlot)
963 ? SwUndoId::ACCEPT_REDLINE
964 : SwUndoId::REJECT_REDLINE;
966 rSh.StartUndo( eUndoId, &aRewriter);
967 while ( nRedline != SwRedlineTable::npos && nRedline < rRedlineTable.size() )
969 pRedline = rRedlineTable[nRedline];
971 // until next redline is not in the same row
972 SwTableBox* pTableBox = pRedline->Start()->GetNode().GetTableBox();
973 if ( !pTableBox || pTableBox->GetUpper() != pTabLine )
974 break;
976 if (FN_REDLINE_ACCEPT_DIRECT == nSlot || FN_REDLINE_ACCEPT_TONEXT == nSlot)
977 m_pWrtShell->AcceptRedline(nRedline);
978 else
979 m_pWrtShell->RejectRedline(nRedline);
981 rSh.EndUndo( eUndoId, &aRewriter);
984 else if ( RedlineType::None != pTabBox->GetRedlineType() )
986 nRedline = pTabBox->GetRedline();
988 if ( nRedline != SwRedlineTable::npos )
990 bTableChange = true;
992 SwWrtShell& rSh = GetWrtShell();
993 SwRewriter aRewriter;
995 aRewriter.AddRule(UndoArg1, SwResId(
996 rRedlineTable[nRedline]->GetType() == RedlineType::Delete
997 ? STR_REDLINE_TABLE_COLUMN_DELETE
998 : STR_REDLINE_TABLE_COLUMN_INSERT ));
1000 SwUndoId eUndoId =
1001 (FN_REDLINE_ACCEPT_DIRECT == nSlot || FN_REDLINE_ACCEPT_TONEXT == nSlot)
1002 ? SwUndoId::ACCEPT_REDLINE
1003 : SwUndoId::REJECT_REDLINE;
1005 // change only the cells with the same data
1006 SwRedlineData aData(rRedlineTable[nRedline]->GetRedlineData(0));
1008 // start from the first redline of the table to handle all the
1009 // cells of the changed column(s)
1010 while ( nRedline )
1012 pRedline = rRedlineTable[nRedline-1];
1013 SwTableBox* pTableBox = pRedline->Start()->GetNode().GetTableBox();
1014 SwTableNode* pTableNode = pRedline->Start()->GetNode().FindTableNode();
1016 // previous redline is not in the same table
1017 if ( !pTableBox || pTableNode != pTableNd )
1018 break;
1020 --nRedline;
1023 rSh.StartUndo( eUndoId, &aRewriter);
1024 while ( nRedline != SwRedlineTable::npos && nRedline < rRedlineTable.size() )
1026 pRedline = rRedlineTable[nRedline];
1028 // until next redline is not in the same table
1029 SwTableBox* pTableBox = pRedline->Start()->GetNode().GetTableBox();
1030 SwTableNode* pTableNode = pRedline->Start()->GetNode().FindTableNode();
1031 if ( !pTableBox || pTableNode != pTableNd )
1032 break;
1034 // skip cells which are not from the same author, same type change
1035 // or timestamp, i.e. keep only the cells of the same tracked
1036 // column insertion or deletion
1037 if ( !pRedline->GetRedlineData(0).CanCombine(aData) ||
1038 // not a tracked cell change
1039 RedlineType::None == pTableBox->GetRedlineType() )
1041 ++nRedline;
1042 continue;
1045 if (FN_REDLINE_ACCEPT_DIRECT == nSlot || FN_REDLINE_ACCEPT_TONEXT == nSlot)
1046 m_pWrtShell->AcceptRedline(nRedline);
1047 else
1048 m_pWrtShell->RejectRedline(nRedline);
1050 rSh.EndUndo( eUndoId, &aRewriter);
1054 else
1056 assert(pRedline != nullptr);
1059 if (pRedline && !bTableChange)
1061 if (FN_REDLINE_ACCEPT_DIRECT == nSlot || FN_REDLINE_ACCEPT_TONEXT == nSlot)
1062 m_pWrtShell->AcceptRedline(nRedline);
1063 else
1064 m_pWrtShell->RejectRedline(nRedline);
1067 if (FN_REDLINE_ACCEPT_TONEXT == nSlot || FN_REDLINE_REJECT_TONEXT == nSlot)
1069 // Go to next change after accepting or rejecting one (tdf#101977)
1070 GetViewFrame().GetDispatcher()->Execute(FN_REDLINE_NEXT_CHANGE, SfxCallMode::ASYNCHRON);
1073 break;
1075 case FN_REDLINE_NEXT_CHANGE:
1077 // If a parameter is provided, try going to the nth change, not to
1078 // the next one.
1079 SwDoc* pDoc = m_pWrtShell->GetDoc();
1080 const SwRedlineTable& rRedlineTable = pDoc->getIDocumentRedlineAccess().GetRedlineTable();
1081 SwRedlineTable::size_type nRedline = SwRedlineTable::npos;
1082 if (pArgs && pArgs->GetItemState(nSlot, false, &pItem) == SfxItemState::SET)
1084 const sal_uInt32 nChangeId = static_cast<const SfxUInt32Item*>(pItem)->GetValue();
1085 for (SwRedlineTable::size_type i = 0; i < rRedlineTable.size(); ++i)
1087 if (nChangeId == rRedlineTable[i]->GetId())
1088 nRedline = i;
1092 const SwRangeRedline *pNext = nullptr;
1093 if (nRedline < rRedlineTable.size())
1094 pNext = m_pWrtShell->GotoRedline(nRedline, true);
1095 else
1096 pNext = m_pWrtShell->SelNextRedline();
1098 if (pNext)
1100 if (comphelper::LibreOfficeKit::isActive())
1102 sal_uInt32 nRedlineId = pNext->GetId();
1103 OString aPayload(".uno:CurrentTrackedChangeId=" + OString::number(nRedlineId));
1104 libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED, aPayload);
1107 m_pWrtShell->SetInSelect();
1111 break;
1113 case FN_REDLINE_PREV_CHANGE:
1115 const SwRangeRedline *pPrev = m_pWrtShell->SelPrevRedline();
1117 if (pPrev)
1119 if (comphelper::LibreOfficeKit::isActive())
1121 sal_uInt32 nRedlineId = pPrev->GetId();
1122 OString aPayload(".uno:CurrentTrackedChangeId=" + OString::number(nRedlineId));
1123 libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED, aPayload);
1126 m_pWrtShell->SetInSelect();
1129 break;
1131 case SID_DOCUMENT_COMPARE:
1132 case SID_DOCUMENT_MERGE:
1134 OUString sFileName, sFilterName;
1135 sal_Int16 nVersion = 0;
1136 bool bHasFileName = false;
1137 m_pViewImpl->SetParam( 0 );
1138 bool bNoAcceptDialog = false;
1140 if( pArgs )
1142 if( const SfxStringItem* pFileItem = pArgs->GetItemIfSet( SID_FILE_NAME, false ))
1143 sFileName = pFileItem->GetValue();
1144 bHasFileName = !sFileName.isEmpty();
1146 if( const SfxStringItem* pFilterNameItem = pArgs->GetItemIfSet( SID_FILTER_NAME, false ))
1147 sFilterName = pFilterNameItem->GetValue();
1149 if( const SfxInt16Item* pVersionItem = pArgs->GetItemIfSet( SID_VERSION, false ))
1151 nVersion = pVersionItem->GetValue();
1152 m_pViewImpl->SetParam( nVersion );
1154 if( const SfxBoolItem* pDialogItem = pArgs->GetItemIfSet( SID_NO_ACCEPT_DIALOG, false ))
1156 bNoAcceptDialog = pDialogItem->GetValue();
1160 m_pViewImpl->InitRequest( rReq );
1161 tools::Long nFound = InsertDoc( nSlot, sFileName, sFilterName, nVersion );
1163 if ( bHasFileName )
1165 rReq.SetReturnValue( SfxInt32Item( nSlot, nFound ));
1167 if (nFound > 0 && !bNoAcceptDialog) // show Redline browser
1169 SfxViewFrame& rVFrame = GetViewFrame();
1170 rVFrame.ShowChildWindow(FN_REDLINE_ACCEPT);
1172 // re-initialize the Redline dialog
1173 const sal_uInt16 nId = SwRedlineAcceptChild::GetChildWindowId();
1174 SwRedlineAcceptChild *pRed = static_cast<SwRedlineAcceptChild*>(
1175 rVFrame.GetChildWindow(nId));
1176 if (pRed)
1177 pRed->ReInitDlg(GetDocShell());
1180 else
1181 bIgnore = true;
1183 break;
1184 case FN_SYNC_LABELS:
1185 GetViewFrame().ShowChildWindow(nSlot);
1186 break;
1187 case FN_ESCAPE:
1189 if ( m_pWrtShell->HasDrawViewDrag() )
1191 m_pWrtShell->BreakDrag();
1192 m_pWrtShell->EnterSelFrameMode();
1194 else if ( m_pWrtShell->IsDrawCreate() )
1196 GetDrawFuncPtr()->BreakCreate();
1197 AttrChangedNotify(nullptr); // shell change if needed
1199 else if ( m_pWrtShell->HasSelection() || IsDrawMode() )
1201 SdrView *pSdrView = m_pWrtShell->HasDrawView() ? m_pWrtShell->GetDrawView() : nullptr;
1202 if(pSdrView && pSdrView->AreObjectsMarked() &&
1203 pSdrView->GetHdlList().GetFocusHdl())
1205 const_cast<SdrHdlList&>(pSdrView->GetHdlList()).ResetFocusHdl();
1207 else
1209 if(pSdrView)
1211 LeaveDrawCreate();
1212 Point aPt(LONG_MIN, LONG_MIN);
1213 //go out of the frame
1214 m_pWrtShell->SelectObj(aPt, SW_LEAVE_FRAME);
1215 SfxBindings& rBind = GetViewFrame().GetBindings();
1216 rBind.Invalidate( SID_ATTR_SIZE );
1218 m_pWrtShell->EnterStdMode();
1219 AttrChangedNotify(nullptr); // shell change if necessary
1222 else if ( GetEditWin().GetApplyTemplate() )
1224 GetEditWin().SetApplyTemplate(SwApplyTemplate());
1226 else if( static_cast<SfxObjectShell*>(GetDocShell())->IsInPlaceActive() )
1228 Escape();
1230 else if ( GetEditWin().IsChainMode() )
1232 GetEditWin().SetChainMode( false );
1234 else if( m_pWrtShell->GetFlyFrameFormat() )
1236 const SwFrameFormat* pFormat = m_pWrtShell->GetFlyFrameFormat();
1237 if(m_pWrtShell->GotoFly( pFormat->GetName(), FLYCNTTYPE_FRM ))
1239 m_pWrtShell->HideCursor();
1240 m_pWrtShell->EnterSelFrameMode();
1243 else
1245 SfxBoolItem aItem( SID_WIN_FULLSCREEN, false );
1246 GetViewFrame().GetDispatcher()->ExecuteList(SID_WIN_FULLSCREEN,
1247 SfxCallMode::RECORD, { &aItem });
1248 bIgnore = true;
1251 break;
1252 case SID_ATTR_BORDER_INNER:
1253 case SID_ATTR_BORDER_OUTER:
1254 case SID_ATTR_BORDER_SHADOW:
1255 if(pArgs)
1256 m_pWrtShell->SetAttrSet(*pArgs);
1257 break;
1259 case SID_ATTR_PAGE:
1260 case SID_ATTR_PAGE_SIZE:
1261 case SID_ATTR_PAGE_MAXSIZE:
1262 case SID_ATTR_PAGE_PAPERBIN:
1263 case SID_ATTR_PAGE_EXT1:
1264 case FN_PARAM_FTN_INFO:
1266 if(pArgs)
1268 const size_t nCurIdx = m_pWrtShell->GetCurPageDesc();
1269 SwPageDesc aPageDesc( m_pWrtShell->GetPageDesc( nCurIdx ) );
1270 ::ItemSetToPageDesc( *pArgs, aPageDesc );
1271 // change the descriptor of the core
1272 m_pWrtShell->ChgPageDesc( nCurIdx, aPageDesc );
1275 break;
1276 case FN_GOTO_PAGE:
1278 SwGotoPageDlg aDlg(GetViewFrame().GetFrameWeld(), GetViewFrame().GetBindings());
1279 if (aDlg.run() == RET_OK)
1280 GetWrtShell().GotoPage(aDlg.GetPageSelection(), true);
1282 break;
1283 case FN_EDIT_CURRENT_TOX:
1285 GetViewFrame().GetDispatcher()->Execute(
1286 FN_INSERT_MULTI_TOX, SfxCallMode::ASYNCHRON);
1288 break;
1289 case FN_UPDATE_CUR_TOX:
1291 const SwTOXBase* pBase = m_pWrtShell->GetCurTOX();
1292 if(pBase)
1294 // tdf#106374: don't jump view on the update
1295 const bool bWasLocked = m_pWrtShell->IsViewLocked();
1296 m_pWrtShell->LockView(true);
1297 m_pWrtShell->StartAction();
1298 if(TOX_INDEX == pBase->GetType())
1299 m_pWrtShell->ApplyAutoMark();
1300 m_pWrtShell->UpdateTableOf( *pBase );
1301 m_pWrtShell->EndAction();
1302 if (!bWasLocked)
1303 m_pWrtShell->LockView(false);
1306 break;
1307 case FN_UPDATE_TOX:
1309 m_pWrtShell->StartAction();
1310 m_pWrtShell->EnterStdMode();
1311 bool bOldCursorInReadOnly = m_pWrtShell->IsReadOnlyAvailable();
1312 m_pWrtShell->SetReadOnlyAvailable( true );
1314 for( int i = 0; i < 2; ++i )
1316 if( m_pWrtShell->GetTOXCount() == 1 )
1317 ++i;
1319 while( m_pWrtShell->GotoPrevTOXBase() )
1320 ; // jump to the first "table of ..."
1322 // if we are not in one, jump to next
1323 const SwTOXBase* pBase = m_pWrtShell->GetCurTOX();
1324 if( !pBase )
1326 if (m_pWrtShell->GotoNextTOXBase())
1327 pBase = m_pWrtShell->GetCurTOX();
1330 bool bAutoMarkApplied = false;
1331 while( pBase )
1333 if(TOX_INDEX == pBase->GetType() && !bAutoMarkApplied)
1335 m_pWrtShell->ApplyAutoMark();
1336 bAutoMarkApplied = true;
1338 // pBase is needed only for the interface. Should be changed in future! (JP 1996)
1339 m_pWrtShell->UpdateTableOf( *pBase );
1341 if( m_pWrtShell->GotoNextTOXBase() )
1342 pBase = m_pWrtShell->GetCurTOX();
1343 else
1344 pBase = nullptr;
1347 m_pWrtShell->SetReadOnlyAvailable( bOldCursorInReadOnly );
1348 m_pWrtShell->EndAction();
1350 break;
1351 case SID_ATTR_BRUSH:
1353 if(pArgs && SfxItemState::SET == pArgs->GetItemState(RES_BACKGROUND, false, &pItem))
1355 const size_t nCurIdx = m_pWrtShell->GetCurPageDesc();
1356 SwPageDesc aDesc( m_pWrtShell->GetPageDesc( nCurIdx ));
1357 SwFrameFormat& rMaster = aDesc.GetMaster();
1358 rMaster.SetFormatAttr(*pItem);
1359 m_pWrtShell->ChgPageDesc( nCurIdx, aDesc);
1362 break;
1363 case SID_CLEARHISTORY:
1365 m_pWrtShell->DelAllUndoObj();
1367 break;
1368 case SID_UNDO:
1370 m_pShell->ExecuteSlot(rReq);
1372 break;
1373 #if defined(_WIN32) || defined UNX
1374 case SID_TWAIN_SELECT:
1375 case SID_TWAIN_TRANSFER:
1376 GetViewImpl()->ExecuteScan( rReq );
1377 break;
1378 #endif
1380 case SID_ATTR_DEFTABSTOP:
1382 const SfxUInt16Item* pTabStopItem = nullptr;
1383 if(pArgs && (pTabStopItem = pArgs->GetItemIfSet(SID_ATTR_DEFTABSTOP, false)))
1385 SvxTabStopItem aDefTabs( 0, 0, SvxTabAdjust::Default, RES_PARATR_TABSTOP );
1386 const sal_uInt16 nTab = pTabStopItem->GetValue();
1387 MakeDefTabs( nTab, aDefTabs );
1388 m_pWrtShell->SetDefault( aDefTabs );
1391 break;
1392 case SID_ATTR_LANGUAGE :
1394 const SvxLanguageItem* pLangItem;
1395 if(pArgs && (pLangItem = pArgs->GetItemIfSet(SID_ATTR_LANGUAGE, false)))
1397 SvxLanguageItem aLang(pLangItem->GetLanguage(), RES_CHRATR_LANGUAGE);
1398 m_pWrtShell->SetDefault( aLang );
1399 lcl_SetAllTextToDefaultLanguage( *m_pWrtShell, RES_CHRATR_LANGUAGE );
1402 break;
1403 case SID_ATTR_CHAR_CTL_LANGUAGE:
1404 if(pArgs && SfxItemState::SET == pArgs->GetItemState(RES_CHRATR_CTL_LANGUAGE, false, &pItem))
1406 m_pWrtShell->SetDefault( *pItem );
1407 lcl_SetAllTextToDefaultLanguage( *m_pWrtShell, RES_CHRATR_CTL_LANGUAGE );
1409 break;
1410 case SID_ATTR_CHAR_CJK_LANGUAGE:
1411 if(pArgs && SfxItemState::SET == pArgs->GetItemState(RES_CHRATR_CJK_LANGUAGE, false, &pItem))
1413 m_pWrtShell->SetDefault( *pItem );
1414 lcl_SetAllTextToDefaultLanguage( *m_pWrtShell, RES_CHRATR_CJK_LANGUAGE );
1416 break;
1417 case FN_OUTLINE_LEVELS_SHOWN:
1419 SwWrtShell& rSh = GetWrtShell();
1420 int nOutlineLevel = -1;
1421 auto nOutlinePos = rSh.GetOutlinePos();
1422 if (nOutlinePos != SwOutlineNodes::npos)
1423 nOutlineLevel = rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nOutlinePos);
1424 SwNumberInputDlg aDlg(GetViewFrame().GetFrameWeld(),
1425 SwResId(STR_OUTLINE_LEVELS_SHOWN_TITLE),
1426 SwResId(STR_OUTLINE_LEVELS_SHOWN_SPIN_LABEL),
1427 nOutlineLevel + 1, 1, 10,
1428 SwResId(STR_OUTLINE_LEVELS_SHOWN_HELP_LABEL));
1429 if (aDlg.run() == RET_OK)
1430 rSh.MakeOutlineLevelsVisible(aDlg.GetNumber());
1432 break;
1433 case FN_TOGGLE_OUTLINE_CONTENT_VISIBILITY:
1435 size_t nPos(m_pWrtShell->GetOutlinePos());
1436 if (nPos != SwOutlineNodes::npos)
1437 GetEditWin().ToggleOutlineContentVisibility(nPos, false);
1439 break;
1440 case FN_NAV_ELEMENT:
1442 pArgs->GetItemState(GetPool().GetWhich(FN_NAV_ELEMENT), false, &pItem);
1443 if(pItem)
1445 SvxSearchDialogWrapper::SetSearchLabel(SearchLabel::Empty);
1446 sal_uInt32 nMoveType(static_cast<const SfxUInt32Item*>(pItem)->GetValue());
1447 SwView::SetMoveType(nMoveType);
1450 break;
1451 case FN_SCROLL_PREV:
1452 case FN_SCROLL_NEXT:
1454 bool *pbNext = new bool(true);
1455 if (nSlot == FN_SCROLL_PREV)
1456 *pbNext = false;
1457 MoveNavigationHdl(pbNext);
1459 break;
1460 case SID_JUMPTOMARK:
1461 if( pArgs && SfxItemState::SET == pArgs->GetItemState(SID_JUMPTOMARK, false, &pItem))
1462 JumpToSwMark( static_cast<const SfxStringItem*>(pItem)->GetValue() );
1463 break;
1464 case SID_GALLERY :
1465 // First make sure that the sidebar is visible
1466 GetViewFrame().ShowChildWindow(SID_SIDEBAR);
1468 ::sfx2::sidebar::Sidebar::ShowPanel(
1469 u"GalleryPanel",
1470 GetViewFrame().GetFrame().GetFrameInterface());
1471 break;
1472 case SID_AVMEDIA_PLAYER :
1473 GetViewFrame().ChildWindowExecute(rReq);
1474 break;
1475 case SID_VIEW_DATA_SOURCE_BROWSER:
1477 SfxViewFrame& rVFrame = GetViewFrame();
1478 rVFrame.ChildWindowExecute(rReq);
1479 if(rVFrame.HasChildWindow(SID_BROWSER))
1481 const SwDBData& rData = GetWrtShell().GetDBData();
1482 SwModule::ShowDBObj(*this, rData);
1485 break;
1486 case FN_INSERT_FIELD_DATA_ONLY:
1488 bool bShow = false;
1489 if( pArgs &&
1490 SfxItemState::SET == pArgs->GetItemState(nSlot, false, &pItem ))
1491 bShow = static_cast<const SfxBoolItem*>(pItem)->GetValue();
1492 if((bShow && m_bInMailMerge) != GetViewFrame().HasChildWindow(nSlot))
1493 GetViewFrame().ToggleChildWindow(nSlot);
1494 //if fields have been successfully inserted call the "real"
1495 //mail merge dialog
1496 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
1497 SwWrtShell &rSh = GetWrtShell();
1498 if(m_bInMailMerge && rSh.IsAnyDatabaseFieldInDoc())
1500 SwDBManager* pDBManager = rSh.GetDBManager();
1501 if (pDBManager)
1503 SwDBData aData = rSh.GetDBData();
1504 rSh.EnterStdMode(); // force change in text shell; necessary for mixing DB fields
1505 AttrChangedNotify(nullptr);
1507 Sequence<PropertyValue> aProperties
1509 comphelper::makePropertyValue("DataSourceName", aData.sDataSource),
1510 comphelper::makePropertyValue("Command", aData.sCommand),
1511 comphelper::makePropertyValue("CommandType", aData.nCommandType)
1513 pDBManager->ExecuteFormLetter(rSh, aProperties);
1516 #endif
1517 m_bInMailMerge &= bShow;
1518 GetViewFrame().GetBindings().Invalidate(FN_INSERT_FIELD);
1520 break;
1521 case FN_QRY_MERGE:
1523 bool bUseCurrentDocument = true;
1524 bool bQuery = !pArgs || SfxItemState::SET != pArgs->GetItemState(nSlot);
1525 if(bQuery)
1527 SfxViewFrame& rTmpFrame = GetViewFrame();
1528 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
1529 ScopedVclPtr<AbstractMailMergeCreateFromDlg> pDlg(pFact->CreateMailMergeCreateFromDlg(rTmpFrame.GetFrameWeld()));
1530 if (RET_OK == pDlg->Execute())
1531 bUseCurrentDocument = pDlg->IsThisDocument();
1532 else
1533 break;
1535 GenerateFormLetter(bUseCurrentDocument);
1537 break;
1538 case SID_RECHECK_DOCUMENT:
1540 SwDocShell* pDocShell = GetDocShell();
1541 SwDoc* pDoc = pDocShell->GetDoc();
1542 uno::Reference< linguistic2::XProofreadingIterator > xGCIterator( pDoc->GetGCIterator() );
1543 if( xGCIterator.is() )
1545 xGCIterator->resetIgnoreRules();
1547 // reset ignore lists
1548 pDoc->SpellItAgainSam( true, false, false );
1549 // clear ignore dictionary
1550 uno::Reference< linguistic2::XDictionary > xDictionary = LinguMgr::GetIgnoreAllList();
1551 if( xDictionary.is() )
1552 xDictionary->clear();
1553 // put cursor to the start of the document
1554 m_pWrtShell->StartOfSection();
1555 [[fallthrough]]; // call spell/grammar dialog
1557 case FN_SPELL_GRAMMAR_DIALOG:
1559 SfxViewFrame& rViewFrame = GetViewFrame();
1560 if (rReq.GetArgs() != nullptr)
1561 rViewFrame.SetChildWindow (FN_SPELL_GRAMMAR_DIALOG,
1562 static_cast<const SfxBoolItem&>( (rReq.GetArgs()->
1563 Get(FN_SPELL_GRAMMAR_DIALOG))).GetValue());
1564 else
1565 rViewFrame.ToggleChildWindow(FN_SPELL_GRAMMAR_DIALOG);
1567 rViewFrame.GetBindings().Invalidate(FN_SPELL_GRAMMAR_DIALOG);
1568 rReq.Ignore ();
1570 break;
1571 case SID_ALIGN_ANY_LEFT :
1572 case SID_ALIGN_ANY_HCENTER :
1573 case SID_ALIGN_ANY_RIGHT :
1574 case SID_ALIGN_ANY_JUSTIFIED:
1575 case SID_ALIGN_ANY_TOP :
1576 case SID_ALIGN_ANY_VCENTER :
1577 case SID_ALIGN_ANY_BOTTOM :
1578 case SID_ALIGN_ANY_HDEFAULT :
1579 case SID_ALIGN_ANY_VDEFAULT :
1581 sal_uInt16 nAlias = 0;
1582 if( m_nSelectionType & (SelectionType::DrawObjectEditMode|SelectionType::Text) )
1584 switch( nSlot )
1586 case SID_ALIGN_ANY_LEFT : nAlias = SID_ATTR_PARA_ADJUST_LEFT; break;
1587 case SID_ALIGN_ANY_HCENTER : nAlias = SID_ATTR_PARA_ADJUST_CENTER; break;
1588 case SID_ALIGN_ANY_RIGHT : nAlias = SID_ATTR_PARA_ADJUST_RIGHT; break;
1589 case SID_ALIGN_ANY_JUSTIFIED: nAlias = SID_ATTR_PARA_ADJUST_BLOCK; break;
1590 case SID_ALIGN_ANY_TOP : nAlias = SID_TABLE_VERT_NONE; break;
1591 case SID_ALIGN_ANY_VCENTER : nAlias = SID_TABLE_VERT_CENTER; break;
1592 case SID_ALIGN_ANY_BOTTOM : nAlias = SID_TABLE_VERT_BOTTOM; break;
1595 else
1597 switch( nSlot )
1599 case SID_ALIGN_ANY_LEFT : nAlias = SID_OBJECT_ALIGN_LEFT ; break;
1600 case SID_ALIGN_ANY_HCENTER : nAlias = SID_OBJECT_ALIGN_CENTER ; break;
1601 case SID_ALIGN_ANY_RIGHT : nAlias = SID_OBJECT_ALIGN_RIGHT ; break;
1602 case SID_ALIGN_ANY_TOP : nAlias = SID_OBJECT_ALIGN_UP ; break;
1603 case SID_ALIGN_ANY_VCENTER : nAlias = SID_OBJECT_ALIGN_MIDDLE ; break;
1604 case SID_ALIGN_ANY_BOTTOM : nAlias = SID_OBJECT_ALIGN_DOWN ; break;
1607 //these slots are either re-mapped to text or object alignment
1608 if (nAlias)
1609 GetViewFrame().GetDispatcher()->Execute(
1610 nAlias, SfxCallMode::ASYNCHRON);
1612 break;
1613 case SID_RESTORE_EDITING_VIEW:
1615 //#i33307# restore editing position
1616 Point aCursorPos;
1617 bool bSelectObj;
1618 if(m_pViewImpl->GetRestorePosition(aCursorPos, bSelectObj))
1620 m_pWrtShell->SwCursorShell::SetCursor( aCursorPos, !bSelectObj );
1621 if( bSelectObj )
1623 m_pWrtShell->SelectObj( aCursorPos );
1624 m_pWrtShell->EnterSelFrameMode( &aCursorPos );
1628 break;
1629 case SID_INSERT_GRAPHIC:
1631 rReq.SetReturnValue(SfxBoolItem(nSlot, InsertGraphicDlg( rReq )));
1633 break;
1634 case SID_MOVE_SHAPE_HANDLE:
1636 if (pArgs && pArgs->Count() >= 3)
1638 SdrView *pSdrView = m_pWrtShell->HasDrawView() ? m_pWrtShell->GetDrawView() : nullptr;
1639 if (pSdrView == nullptr)
1640 break;
1641 const SfxUInt32Item* handleNumItem = rReq.GetArg<SfxUInt32Item>(FN_PARAM_1);
1642 const SfxUInt32Item* newPosXTwips = rReq.GetArg<SfxUInt32Item>(FN_PARAM_2);
1643 const SfxUInt32Item* newPosYTwips = rReq.GetArg<SfxUInt32Item>(FN_PARAM_3);
1644 const SfxInt32Item* OrdNum = rReq.GetArg<SfxInt32Item>(FN_PARAM_4);
1646 const sal_uLong handleNum = handleNumItem->GetValue();
1647 const sal_uLong newPosX = newPosXTwips->GetValue();
1648 const sal_uLong newPosY = newPosYTwips->GetValue();
1649 const Point mPoint(newPosX, newPosY);
1650 const SdrHdl* handle = pSdrView->GetHdlList().GetHdl(handleNum);
1651 if (!handle)
1653 break;
1656 if (handle->GetKind() == SdrHdlKind::Anchor || handle->GetKind() == SdrHdlKind::Anchor_TR)
1657 m_pWrtShell->FindAnchorPos(mPoint, /*bMoveIt=*/true);
1658 else
1659 pSdrView->MoveShapeHandle(handleNum, mPoint, OrdNum ? OrdNum->GetValue() : -1);
1661 break;
1664 default:
1665 OSL_ENSURE(false, "wrong dispatcher");
1666 return;
1668 if(!bIgnore)
1669 rReq.Done();
1672 bool SwView::IsConditionalFastCall( const SfxRequest &rReq )
1674 sal_uInt16 nId = rReq.GetSlot();
1675 bool bRet = false;
1677 if (nId == FN_REDLINE_ACCEPT_DIRECT || nId == FN_REDLINE_REJECT_DIRECT)
1679 if (comphelper::LibreOfficeKit::isActive())
1680 bRet = true;
1682 return bRet || SfxShell::IsConditionalFastCall(rReq);
1686 /// invalidate page numbering field
1687 void SwView::UpdatePageNums()
1689 SfxBindings &rBnd = GetViewFrame().GetBindings();
1690 rBnd.Invalidate(FN_STAT_PAGE);
1693 void SwView::UpdateDocStats()
1695 SfxBindings &rBnd = GetViewFrame().GetBindings();
1696 rBnd.Invalidate( FN_STAT_WORDCOUNT );
1697 rBnd.Update( FN_STAT_WORDCOUNT );
1700 /// get status of the status line
1701 void SwView::StateStatusLine(SfxItemSet &rSet)
1703 SwWrtShell& rShell = GetWrtShell();
1705 SfxWhichIter aIter( rSet );
1706 sal_uInt16 nWhich = aIter.FirstWhich();
1707 OSL_ENSURE( nWhich, "empty set");
1709 //get section change event
1710 const SwSection* CurrSect = rShell.GetCurrSection();
1711 if( CurrSect )
1713 const OUString& sCurrentSectionName = CurrSect->GetSectionName();
1714 if(sCurrentSectionName != m_sOldSectionName)
1716 SwCursorShell::FireSectionChangeEvent(2, 1);
1718 m_sOldSectionName = sCurrentSectionName;
1720 else if (!m_sOldSectionName.isEmpty())
1722 SwCursorShell::FireSectionChangeEvent(2, 1);
1723 m_sOldSectionName= OUString();
1725 //get column change event
1726 if(rShell.bColumnChange())
1728 SwCursorShell::FireColumnChangeEvent(2, 1);
1731 while( nWhich )
1733 switch( nWhich )
1735 case FN_STAT_PAGE:
1737 OUString aTooltip;
1738 OUString aPageStr;
1740 SwVisiblePageNumbers aVisiblePageNumbers;
1741 m_pWrtShell->GetFirstLastVisPageNumbers(aVisiblePageNumbers);
1743 // convert to strings and define references
1744 OUString sFirstPhy = OUString::number(aVisiblePageNumbers.nFirstPhy);
1745 OUString sLastPhy = OUString::number(aVisiblePageNumbers.nLastPhy);
1746 OUString sFirstVirt = OUString::number(aVisiblePageNumbers.nFirstVirt);
1747 OUString sLastVirt = OUString::number(aVisiblePageNumbers.nLastVirt);
1748 OUString& sFirstCustomPhy = aVisiblePageNumbers.sFirstCustomPhy;
1749 OUString& sLastCustomPhy = aVisiblePageNumbers.sLastCustomPhy;
1750 OUString& sFirstCustomVirt = aVisiblePageNumbers.sFirstCustomVirt;
1751 OUString& sLastCustomVirt = aVisiblePageNumbers.sLastCustomVirt;
1752 OUString sPageCount = OUString::number(m_pWrtShell->GetPageCount());
1754 if (aVisiblePageNumbers.nFirstPhy == aVisiblePageNumbers.nFirstVirt)
1756 aTooltip = SwResId(STR_BOOKCTRL_HINT);
1757 if (aVisiblePageNumbers.nFirstPhy != aVisiblePageNumbers.nLastPhy)
1759 if (sFirstPhy == sFirstCustomPhy && sLastPhy == sLastCustomPhy)
1761 aPageStr = SwResId(STR_PAGES_COUNT);
1762 aPageStr = aPageStr.replaceFirst("%1", sFirstPhy);
1763 aPageStr = aPageStr.replaceFirst("%2", sLastPhy);
1764 aPageStr = aPageStr.replaceFirst("%3", sPageCount);
1766 else
1768 aPageStr = SwResId(STR_PAGES_COUNT_CUSTOM);
1769 aPageStr = aPageStr.replaceFirst("%1", sFirstPhy);
1770 aPageStr = aPageStr.replaceFirst("%2", sLastPhy);
1771 aPageStr = aPageStr.replaceFirst("%3", sFirstCustomPhy);
1772 aPageStr = aPageStr.replaceFirst("%4", sLastCustomPhy);
1773 aPageStr = aPageStr.replaceFirst("%5", sPageCount);
1776 else
1778 if (sFirstPhy == sFirstCustomPhy && sLastPhy == sLastCustomPhy)
1780 aPageStr = SwResId(STR_PAGE_COUNT);
1781 aPageStr = aPageStr.replaceFirst("%1", sFirstPhy);
1782 aPageStr = aPageStr.replaceFirst("%2", sPageCount);
1784 else
1786 aPageStr = SwResId(STR_PAGE_COUNT_CUSTOM);
1787 aPageStr = aPageStr.replaceFirst("%1", sFirstPhy);
1788 aPageStr = aPageStr.replaceFirst("%2", sFirstCustomPhy);
1789 aPageStr = aPageStr.replaceFirst("%3", sPageCount);
1793 else
1795 aTooltip = SwResId(STR_BOOKCTRL_HINT_EXTENDED);
1796 if (aVisiblePageNumbers.nFirstPhy != aVisiblePageNumbers.nLastPhy)
1798 if (sFirstPhy == sFirstCustomPhy && sLastPhy == sLastCustomPhy)
1800 aPageStr = SwResId(STR_PAGES_COUNT_EXTENDED);
1801 aPageStr = aPageStr.replaceFirst("%1", sFirstPhy);
1802 aPageStr = aPageStr.replaceFirst("%2", sLastPhy);
1803 aPageStr = aPageStr.replaceFirst("%3", sPageCount);
1804 aPageStr = aPageStr.replaceFirst("%4", sFirstVirt);
1805 aPageStr = aPageStr.replaceFirst("%5", sLastVirt);
1807 else
1809 aPageStr = SwResId(STR_PAGES_COUNT_CUSTOM_EXTENDED);
1810 aPageStr = aPageStr.replaceFirst("%1", sFirstPhy);
1811 aPageStr = aPageStr.replaceFirst("%2", sLastPhy);
1812 aPageStr = aPageStr.replaceFirst("%3", sFirstCustomPhy);
1813 aPageStr = aPageStr.replaceFirst("%4", sLastCustomPhy);
1814 aPageStr = aPageStr.replaceFirst("%5", sPageCount);
1815 aPageStr = aPageStr.replaceFirst("%6", sFirstVirt);
1816 aPageStr = aPageStr.replaceFirst("%7", sLastVirt);
1817 aPageStr = aPageStr.replaceFirst("%8", sFirstCustomVirt);
1818 aPageStr = aPageStr.replaceFirst("%9", sLastCustomVirt);
1821 else
1823 if (sFirstPhy == sFirstCustomPhy && sLastPhy == sLastCustomPhy)
1825 aPageStr = SwResId(STR_PAGE_COUNT_EXTENDED);
1826 aPageStr = aPageStr.replaceFirst("%1", sFirstPhy);
1827 aPageStr = aPageStr.replaceFirst("%2", sPageCount);
1828 aPageStr = aPageStr.replaceFirst("%3", sFirstVirt);
1830 else
1832 aPageStr = SwResId(STR_PAGE_COUNT_CUSTOM_EXTENDED);
1833 aPageStr = aPageStr.replaceFirst("%1", sFirstPhy);
1834 aPageStr = aPageStr.replaceFirst("%2", sFirstCustomPhy);
1835 aPageStr = aPageStr.replaceFirst("%3", sPageCount);
1836 aPageStr = aPageStr.replaceFirst("%4", sFirstVirt);
1837 aPageStr = aPageStr.replaceFirst("%5", sFirstCustomVirt);
1842 // replace range indicator with two pages conjunction if applicable
1843 if ((aVisiblePageNumbers.nLastPhy - aVisiblePageNumbers.nFirstPhy) == 1)
1844 aPageStr = aPageStr.replaceAll("-", SwResId(STR_PAGES_TWO_CONJUNCTION));
1846 // status bar bookmark control string and tooltip
1847 std::vector<OUString> aStringList
1849 aPageStr,
1850 aTooltip
1852 rSet.Put(SfxStringListItem(FN_STAT_PAGE, &aStringList));
1854 //if existing page number is not equal to old page number, send out this event.
1855 if (m_nOldPageNum != aVisiblePageNumbers.nFirstPhy)
1857 if (m_nOldPageNum != 0)
1858 SwCursorShell::FirePageChangeEvent(m_nOldPageNum, aVisiblePageNumbers.nFirstPhy);
1859 m_nOldPageNum = aVisiblePageNumbers.nFirstPhy;
1861 const sal_uInt16 nCnt = GetWrtShell().GetPageCnt();
1862 if (m_nPageCnt != nCnt) // notify Basic
1864 m_nPageCnt = nCnt;
1865 SfxGetpApp()->NotifyEvent(SfxEventHint(SfxEventHintId::SwEventPageCount, SwDocShell::GetEventName(STR_SW_EVENT_PAGE_COUNT), GetViewFrame().GetObjectShell()), false);
1868 break;
1870 case FN_STAT_WORDCOUNT:
1872 SwDocStat selectionStats;
1873 SwDocStat documentStats;
1874 rShell.CountWords(selectionStats);
1875 documentStats = rShell.GetDoc()->getIDocumentStatistics().GetUpdatedDocStat( true /* complete-async */, false /* don't update fields */ );
1877 sal_uLong nWord = selectionStats.nWord ? selectionStats.nWord : documentStats.nWord;
1878 sal_uLong nChar = selectionStats.nChar ? selectionStats.nChar : documentStats.nChar;
1879 TranslateId pResId = selectionStats.nWord ? STR_WORDCOUNT : STR_WORDCOUNT_NO_SELECTION;
1880 TranslateNId pWordResId = selectionStats.nWord ? STR_WORDCOUNT_WORDARG : STR_WORDCOUNT_WORDARG_NO_SELECTION;
1881 TranslateNId pCharResId = selectionStats.nWord ? STR_WORDCOUNT_CHARARG : STR_WORDCOUNT_CHARARG_NO_SELECTION;
1883 const LocaleDataWrapper& rLocaleData = Application::GetSettings().GetUILocaleDataWrapper();
1884 OUString aWordArg = SwResId(pWordResId, nWord).replaceAll("$1", rLocaleData.getNum(nWord, 0));
1885 OUString aCharArg = SwResId(pCharResId, nChar).replaceAll("$1", rLocaleData.getNum(nChar, 0));
1886 OUString aWordCount(SwResId(pResId));
1887 aWordCount = aWordCount.replaceAll("$1", aWordArg);
1888 aWordCount = aWordCount.replaceAll("$2", aCharArg);
1890 rSet.Put( SfxStringItem( FN_STAT_WORDCOUNT, aWordCount ) );
1892 SwWordCountWrapper *pWrdCnt = static_cast<SwWordCountWrapper*>(GetViewFrame().GetChildWindow(SwWordCountWrapper::GetChildWindowId()));
1893 if (pWrdCnt)
1894 pWrdCnt->SetCounts(selectionStats, documentStats);
1896 break;
1897 case FN_STAT_ACCESSIBILITY_CHECK:
1899 std::unique_ptr<sw::OnlineAccessibilityCheck> const& rOnlineAccessibilityCheck = rShell.GetDoc()->getOnlineAccessibilityCheck();
1900 if (rOnlineAccessibilityCheck)
1902 sal_Int32 nIssues = rOnlineAccessibilityCheck->getNumberOfAccessibilityIssues()
1903 + rOnlineAccessibilityCheck->getNumberOfDocumentLevelAccessibilityIssues();
1904 rSet.Put(SfxInt32Item(FN_STAT_ACCESSIBILITY_CHECK, nIssues));
1907 break;
1909 case FN_STAT_TEMPLATE:
1911 rSet.Put(SfxStringItem( FN_STAT_TEMPLATE,
1912 rShell.GetCurPageStyle()));
1915 break;
1916 case SID_ATTR_ZOOM:
1918 if ( ( GetDocShell()->GetCreateMode() != SfxObjectCreateMode::EMBEDDED ) || !GetDocShell()->IsInPlaceActive() )
1920 const SwViewOption* pVOpt = rShell.GetViewOptions();
1921 SvxZoomType eZoom = pVOpt->GetZoomType();
1922 SvxZoomItem aZoom(eZoom,
1923 pVOpt->GetZoom());
1924 if( pVOpt->getBrowseMode() )
1926 aZoom.SetValueSet(
1927 SvxZoomEnableFlags::N50|
1928 SvxZoomEnableFlags::N75|
1929 SvxZoomEnableFlags::N100|
1930 SvxZoomEnableFlags::N150|
1931 SvxZoomEnableFlags::N200);
1933 rSet.Put( aZoom );
1935 else
1936 rSet.DisableItem( SID_ATTR_ZOOM );
1938 break;
1939 case SID_ATTR_VIEWLAYOUT:
1941 if ( ( GetDocShell()->GetCreateMode() != SfxObjectCreateMode::EMBEDDED ) || !GetDocShell()->IsInPlaceActive() )
1943 const SwViewOption* pVOpt = rShell.GetViewOptions();
1944 const sal_uInt16 nColumns = pVOpt->GetViewLayoutColumns();
1945 const bool bBookMode = pVOpt->IsViewLayoutBookMode();
1946 SvxViewLayoutItem aViewLayout(nColumns, bBookMode);
1947 rSet.Put( aViewLayout );
1949 else
1950 rSet.DisableItem( SID_ATTR_VIEWLAYOUT );
1952 break;
1953 case SID_ATTR_ZOOMSLIDER:
1955 if ( ( GetDocShell()->GetCreateMode() != SfxObjectCreateMode::EMBEDDED ) || !GetDocShell()->IsInPlaceActive() )
1957 const SwViewOption* pVOpt = rShell.GetViewOptions();
1958 const sal_uInt16 nCurrentZoom = pVOpt->GetZoom();
1959 SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM, MAXZOOM );
1960 aZoomSliderItem.AddSnappingPoint( 100 );
1962 if ( !m_pWrtShell->getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE) )
1964 const sal_uInt16 nColumns = pVOpt->GetViewLayoutColumns();
1965 const bool bAutomaticViewLayout = 0 == nColumns;
1966 const SwPostItMgr* pMgr = GetPostItMgr();
1968 // snapping points:
1969 // automatic mode: 1 Page, 2 Pages, 100%
1970 // n Columns mode: n Pages, 100%
1971 // n Columns book mode: nPages without gaps, 100%
1972 const SwRect aPageRect( m_pWrtShell->GetAnyCurRect( CurRectType::PageCalc ) );
1973 const SwRect aRootRect( m_pWrtShell->GetAnyCurRect( CurRectType::PagesArea ) ); // width of columns
1974 Size aPageSize( aPageRect.SSize() );
1975 aPageSize.AdjustWidth(pMgr->HasNotes() && pMgr->ShowNotes() ?
1976 pMgr->GetSidebarWidth() + pMgr->GetSidebarBorderWidth() :
1977 0 );
1979 Size aRootSize( aRootRect.SSize() );
1981 const MapMode aTmpMap( MapUnit::MapTwip );
1982 const Size& rEditSize = GetEditWin().GetOutputSizePixel();
1983 const Size aWindowSize( GetEditWin().PixelToLogic( rEditSize, aTmpMap ) );
1985 const tools::Long nOf = pVOpt->GetDocumentBorder() * 2;
1986 tools::Long nTmpWidth = bAutomaticViewLayout ? aPageSize.Width() : aRootSize.Width();
1987 nTmpWidth += nOf;
1988 aPageSize.AdjustHeight(nOf );
1989 tools::Long nFac = aWindowSize.Width() * 100 / nTmpWidth;
1991 tools::Long nVisPercent = aWindowSize.Height() * 100 / aPageSize.Height();
1992 nFac = std::min( nFac, nVisPercent );
1994 if (nFac >= MINZOOM)
1996 aZoomSliderItem.AddSnappingPoint( nFac );
1999 if ( bAutomaticViewLayout )
2001 nTmpWidth += aPageSize.Width() + pVOpt->GetGapBetweenPages();
2002 nFac = aWindowSize.Width() * 100 / nTmpWidth;
2003 nFac = std::min( nFac, nVisPercent );
2004 if (nFac >= MINZOOM)
2006 aZoomSliderItem.AddSnappingPoint( nFac );
2011 rSet.Put( aZoomSliderItem );
2013 else
2014 rSet.DisableItem( SID_ATTR_ZOOMSLIDER );
2016 break;
2017 case SID_ATTR_POSITION:
2018 case SID_ATTR_SIZE:
2020 if( !rShell.IsFrameSelected() && !rShell.IsObjSelected() )
2021 SwBaseShell::SetFrameMode_( FLY_DRAG_END );
2022 else
2024 FlyMode eFrameMode = SwBaseShell::GetFrameMode();
2025 if ( eFrameMode == FLY_DRAG_START || eFrameMode == FLY_DRAG )
2027 if ( nWhich == SID_ATTR_POSITION )
2028 rSet.Put( SfxPointItem( SID_ATTR_POSITION,
2029 rShell.GetAnchorObjDiff()));
2030 else
2031 rSet.Put( SvxSizeItem( SID_ATTR_SIZE,
2032 rShell.GetObjSize()));
2036 break;
2037 case SID_TABLE_CELL:
2039 if( rShell.IsFrameSelected() || rShell.IsObjSelected() )
2041 // #i39171# Don't put a SvxSizeItem into a slot which is defined as SfxStringItem.
2042 // SvxPosSizeStatusBarControl no longer resets to empty display if only one slot
2043 // has no item, so SID_TABLE_CELL can remain empty (the SvxSizeItem is supplied
2044 // in SID_ATTR_SIZE).
2046 else
2048 StatusCategory eCategory(StatusCategory::NONE);
2049 OUString sStr;
2050 if( rShell.IsCursorInTable() )
2052 // table name + cell coordinate
2053 sStr = rShell.GetTableFormat()->GetName() + ":" + rShell.GetBoxNms();
2054 eCategory = StatusCategory::TableCell;
2056 else
2058 const SwSection* pCurrSect = rShell.GetCurrSection();
2059 if( pCurrSect )
2061 switch( pCurrSect->GetType() )
2063 case SectionType::ToxHeader:
2064 case SectionType::ToxContent:
2066 const SwTOXBase* pTOX = m_pWrtShell->GetCurTOX();
2067 if( pTOX )
2069 sStr = pTOX->GetTOXName();
2070 eCategory = StatusCategory::TableOfContents;
2072 else
2074 OSL_ENSURE( false,
2075 "Unknown kind of section" );
2076 sStr = pCurrSect->GetSectionName();
2077 eCategory = StatusCategory::Section;
2080 break;
2081 default:
2082 sStr = pCurrSect->GetSectionName();
2083 eCategory = StatusCategory::Section;
2084 break;
2089 const SwNumRule* pNumRule = rShell.GetNumRuleAtCurrCursorPos();
2090 const bool bOutlineNum = pNumRule && pNumRule->IsOutlineRule();
2092 if (pNumRule && !bOutlineNum ) // cursor in numbering
2094 sal_uInt8 nNumLevel = rShell.GetNumLevel();
2095 if ( nNumLevel < MAXLEVEL )
2097 if(!pNumRule->IsAutoRule())
2099 SfxItemSetFixed<RES_PARATR_NUMRULE, RES_PARATR_NUMRULE> aSet(GetPool());
2100 rShell.GetCurAttr(aSet);
2101 if(SfxItemState::DEFAULT <=
2102 aSet.GetItemState(RES_PARATR_NUMRULE))
2104 const OUString& rNumStyle =
2105 aSet.Get(RES_PARATR_NUMRULE).GetValue();
2106 if(!rNumStyle.isEmpty())
2108 if(!sStr.isEmpty())
2109 sStr += sStatusDelim;
2110 if (eCategory == StatusCategory::NONE)
2111 eCategory = StatusCategory::ListStyle;
2112 sStr += rNumStyle;
2116 if (!sStr.isEmpty())
2117 sStr += sStatusDelim;
2118 sStr += SwResId(STR_NUM_LEVEL) + OUString::number( nNumLevel + 1 );
2119 if (eCategory == StatusCategory::NONE)
2120 eCategory = StatusCategory::Numbering;
2123 const int nOutlineLevel = rShell.GetCurrentParaOutlineLevel();
2124 if( nOutlineLevel != 0 )
2126 if (!sStr.isEmpty())
2127 sStr += " , ";
2128 if( bOutlineNum )
2130 sStr += SwResId(STR_OUTLINE_NUMBERING) +
2131 sStatusDelim + SwResId(STR_NUM_LEVEL);
2133 else
2134 sStr += SwResId(STR_NUM_OUTLINE);
2135 sStr += OUString::number( nOutlineLevel);
2136 if (eCategory == StatusCategory::NONE)
2137 eCategory = StatusCategory::Numbering;
2140 if( rShell.HasReadonlySel() )
2142 if (!sStr.isEmpty())
2143 sStr = sStatusDelim + sStr;
2144 sStr = SwResId(SW_STR_READONLY) + sStr;
2146 if (!sStr.isEmpty())
2147 rSet.Put( SvxStatusItem( SID_TABLE_CELL, sStr, eCategory ));
2149 break;
2150 case FN_STAT_SELMODE:
2152 if(rShell.IsStdMode())
2153 rSet.Put(SfxUInt16Item(FN_STAT_SELMODE, 0));
2154 else if(rShell.IsAddMode())
2155 rSet.Put(SfxUInt16Item(FN_STAT_SELMODE, 2));
2156 else if(rShell.IsBlockMode())
2157 rSet.Put(SfxUInt16Item(FN_STAT_SELMODE, 3));
2158 else
2159 rSet.Put(SfxUInt16Item(FN_STAT_SELMODE, 1));
2160 break;
2162 case SID_ATTR_INSERT:
2163 if( rShell.IsRedlineOn() )
2164 rSet.DisableItem( nWhich );
2165 else
2167 rSet.Put(SfxBoolItem(SID_ATTR_INSERT,rShell.IsInsMode()));
2169 break;
2171 nWhich = aIter.NextWhich();
2175 /** execute method for the status line
2177 * @param rReq ???
2179 void SwView::ExecuteStatusLine(SfxRequest &rReq)
2181 SwWrtShell &rSh = GetWrtShell();
2182 const SfxItemSet* pArgs = rReq.GetArgs();
2183 const SfxPoolItem* pItem=nullptr;
2184 bool bUp = false;
2185 sal_uInt16 nWhich = rReq.GetSlot();
2186 switch( nWhich )
2188 case FN_STAT_PAGE:
2190 GetViewFrame().GetDispatcher()->Execute( FN_GOTO_PAGE,
2191 SfxCallMode::SYNCHRON|SfxCallMode::RECORD );
2193 break;
2195 case FN_STAT_WORDCOUNT:
2197 GetViewFrame().GetDispatcher()->Execute(FN_WORDCOUNT_DIALOG,
2198 SfxCallMode::SYNCHRON|SfxCallMode::RECORD );
2200 break;
2202 case FN_STAT_ACCESSIBILITY_CHECK:
2204 const SfxStringItem sDeckName(SID_SIDEBAR_DECK, "A11yCheckDeck");
2205 GetViewFrame().GetDispatcher()->ExecuteList(SID_SIDEBAR_DECK, SfxCallMode::RECORD,
2206 { &sDeckName });
2208 break;
2210 case FN_STAT_BOOKMARK:
2211 if ( pArgs )
2213 if (SfxItemState::SET == pArgs->GetItemState( nWhich, true, &pItem))
2215 const IDocumentMarkAccess* pMarkAccess = rSh.getIDocumentMarkAccess();
2216 const sal_Int32 nIdx = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
2217 if(nIdx < pMarkAccess->getBookmarksCount())
2219 const IDocumentMarkAccess::const_iterator_t ppBookmark = rSh.getIDocumentMarkAccess()->getBookmarksBegin() + nIdx;
2220 rSh.EnterStdMode();
2221 rSh.GotoMark( *ppBookmark );
2223 else
2224 OSL_FAIL("SwView::ExecuteStatusLine(..)"
2225 " - Ignoring out of range bookmark index");
2228 break;
2230 case FN_STAT_TEMPLATE:
2232 weld::Window* pDialogParent = GetViewFrame().GetFrameWeld();
2233 css::uno::Any aAny(pDialogParent->GetXWindow());
2234 SfxUnoAnyItem aDialogParent(SID_DIALOG_PARENT, aAny);
2235 const SfxPoolItem* pInternalItems[ 2 ];
2236 pInternalItems[ 0 ] = &aDialogParent;
2237 pInternalItems[ 1 ] = nullptr;
2238 GetViewFrame().GetDispatcher()->Execute(FN_FORMAT_PAGE_DLG,
2239 SfxCallMode::SYNCHRON|SfxCallMode::RECORD,
2240 nullptr, 0, pInternalItems);
2242 break;
2243 case SID_ATTR_ZOOM:
2245 if ( ( GetDocShell()->GetCreateMode() != SfxObjectCreateMode::EMBEDDED ) || !GetDocShell()->IsInPlaceActive() )
2247 const SfxItemSet *pSet = nullptr;
2248 ScopedVclPtr<AbstractSvxZoomDialog> pDlg;
2249 if ( pArgs )
2250 pSet = pArgs;
2251 else
2253 const SwViewOption& rViewOptions = *rSh.GetViewOptions();
2254 SfxItemSetFixed<SID_ATTR_ZOOM, SID_ATTR_ZOOM, SID_ATTR_VIEWLAYOUT, SID_ATTR_VIEWLAYOUT> aCoreSet(m_pShell->GetPool());
2255 SvxZoomItem aZoom( rViewOptions.GetZoomType(), rViewOptions.GetZoom() );
2257 const bool bBrowseMode = rSh.GetViewOptions()->getBrowseMode();
2258 if( bBrowseMode )
2260 aZoom.SetValueSet(
2261 SvxZoomEnableFlags::N50|
2262 SvxZoomEnableFlags::N75|
2263 SvxZoomEnableFlags::N100|
2264 SvxZoomEnableFlags::N150|
2265 SvxZoomEnableFlags::N200);
2267 aCoreSet.Put( aZoom );
2269 if ( !bBrowseMode )
2271 const SvxViewLayoutItem aViewLayout( rViewOptions.GetViewLayoutColumns(), rViewOptions.IsViewLayoutBookMode() );
2272 aCoreSet.Put( aViewLayout );
2275 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
2276 pDlg.disposeAndReset(pFact->CreateSvxZoomDialog(GetViewFrame().GetFrameWeld(), aCoreSet));
2277 pDlg->SetLimits( MINZOOM, MAXZOOM );
2278 if( pDlg->Execute() != RET_CANCEL )
2279 pSet = pDlg->GetOutputItemSet();
2282 const SvxViewLayoutItem* pViewLayoutItem = nullptr;
2283 if ( pSet && (pViewLayoutItem = pSet->GetItemIfSet(SID_ATTR_VIEWLAYOUT)))
2285 const sal_uInt16 nColumns = pViewLayoutItem->GetValue();
2286 const bool bBookMode = pViewLayoutItem->IsBookMode();
2287 SetViewLayout( nColumns, bBookMode );
2290 const SvxZoomItem* pZoomItem = nullptr;
2291 if ( pSet && (pZoomItem = pSet->GetItemIfSet(SID_ATTR_ZOOM)))
2293 SvxZoomType eType = pZoomItem->GetType();
2294 SetZoom( eType, pZoomItem->GetValue() );
2296 bUp = true;
2297 if ( pZoomItem )
2298 rReq.AppendItem( *pZoomItem );
2299 rReq.Done();
2302 break;
2304 case SID_ATTR_VIEWLAYOUT:
2306 if ( pArgs && !rSh.getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE) &&
2307 ( ( GetDocShell()->GetCreateMode() != SfxObjectCreateMode::EMBEDDED ) || !GetDocShell()->IsInPlaceActive() ) )
2309 if ( const SvxViewLayoutItem* pLayoutItem = pArgs->GetItemIfSet(SID_ATTR_VIEWLAYOUT ))
2311 const sal_uInt16 nColumns = pLayoutItem->GetValue();
2312 const bool bBookMode = (0 != nColumns && 0 == (nColumns % 2)) && pLayoutItem->IsBookMode();
2314 SetViewLayout( nColumns, bBookMode );
2317 bUp = true;
2318 rReq.Done();
2320 InvalidateRulerPos();
2323 break;
2325 case SID_ATTR_ZOOMSLIDER:
2327 if ( pArgs && ( ( GetDocShell()->GetCreateMode() != SfxObjectCreateMode::EMBEDDED ) || !GetDocShell()->IsInPlaceActive() ) )
2329 if ( const SvxZoomSliderItem* pZoomItem = pArgs->GetItemIfSet(SID_ATTR_ZOOMSLIDER) )
2331 const sal_uInt16 nCurrentZoom = pZoomItem->GetValue();
2332 SetZoom( SvxZoomType::PERCENT, nCurrentZoom );
2335 bUp = true;
2336 rReq.Done();
2339 break;
2341 case SID_ATTR_SIZE:
2343 sal_uInt16 nId = 0;
2344 if( rSh.IsCursorInTable() )
2345 nId = FN_FORMAT_TABLE_DLG;
2346 else if( rSh.GetCurTOX() )
2347 nId = FN_INSERT_MULTI_TOX;
2348 else if( rSh.GetCurrSection() )
2349 nId = FN_EDIT_REGION;
2350 else
2352 const SwNumRule* pNumRule = rSh.GetNumRuleAtCurrCursorPos();
2353 if( pNumRule ) // cursor in numbering
2355 if( pNumRule->IsAutoRule() )
2356 nId = FN_NUMBER_BULLETS;
2357 else
2359 // start dialog of the painter
2360 nId = 0;
2363 else if( rSh.IsFrameSelected() )
2364 nId = FN_FORMAT_FRAME_DLG;
2365 else if( rSh.IsObjSelected() )
2366 nId = SID_ATTR_TRANSFORM;
2368 if( nId )
2369 GetViewFrame().GetDispatcher()->Execute(nId,
2370 SfxCallMode::SYNCHRON | SfxCallMode::RECORD );
2372 break;
2374 case FN_STAT_SELMODE:
2376 if ( pArgs )
2378 if (SfxItemState::SET == pArgs->GetItemState( nWhich, true, &pItem))
2380 switch ( static_cast<const SfxUInt16Item *>(pItem)->GetValue() )
2382 case 0: rSh.EnterStdMode(); break;
2383 case 1: rSh.EnterExtMode(); break;
2384 case 2: rSh.EnterAddMode(); break;
2385 case 3: rSh.EnterBlockMode(); break;
2389 bUp = true;
2390 break;
2392 case FN_SET_ADD_MODE:
2393 rSh.ToggleAddMode();
2394 nWhich = FN_STAT_SELMODE;
2395 bUp = true;
2396 break;
2397 case FN_SET_BLOCK_MODE:
2398 rSh.ToggleBlockMode();
2399 nWhich = FN_STAT_SELMODE;
2400 bUp = true;
2401 break;
2402 case FN_SET_EXT_MODE:
2403 rSh.ToggleExtMode();
2404 nWhich = FN_STAT_SELMODE;
2405 bUp = true;
2406 break;
2407 case SID_ATTR_INSERT:
2408 SwPostItMgr* pMgr = GetPostItMgr();
2409 if ( pMgr && pMgr->HasActiveSidebarWin() )
2411 pMgr->ToggleInsModeOnActiveSidebarWin();
2413 else
2414 rSh.ToggleInsMode();
2415 bUp = true;
2416 break;
2419 if ( bUp )
2421 SfxBindings &rBnd = GetViewFrame().GetBindings();
2422 rBnd.Invalidate(nWhich);
2423 rBnd.Update(nWhich);
2427 void SwView::InsFrameMode(sal_uInt16 nCols)
2429 if ( m_pWrtShell->HasWholeTabSelection() )
2431 SwFlyFrameAttrMgr aMgr( true, m_pWrtShell.get(), Frmmgr_Type::TEXT, nullptr );
2433 const SwFrameFormat &rPageFormat =
2434 m_pWrtShell->GetPageDesc(m_pWrtShell->GetCurPageDesc()).GetMaster();
2435 SwTwips lWidth = rPageFormat.GetFrameSize().GetWidth();
2436 const SvxLRSpaceItem &rLR = rPageFormat.GetLRSpace();
2437 lWidth -= rLR.GetLeft() + rLR.GetRight();
2438 aMgr.SetSize(Size(lWidth, aMgr.GetSize().Height()));
2439 if(nCols > 1)
2441 SwFormatCol aCol;
2442 aCol.Init( nCols, aCol.GetGutterWidth(), aCol.GetWishWidth() );
2443 aMgr.SetCol( aCol );
2445 aMgr.InsertFlyFrame();
2447 else
2448 GetEditWin().InsFrame(nCols);
2451 /// show "edit link" dialog
2452 void SwView::EditLinkDlg()
2454 bool bWeb = dynamic_cast<SwWebView*>( this ) != nullptr;
2455 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
2456 ScopedVclPtr<SfxAbstractLinksDialog> pDlg(pFact->CreateLinksDialog(GetViewFrame().GetFrameWeld(), &GetWrtShell().GetLinkManager(), bWeb));
2457 pDlg->Execute();
2460 namespace sw {
2462 auto PrepareJumpToTOXMark(SwDoc const& rDoc, std::u16string_view aName)
2463 -> std::optional<std::pair<SwTOXMark, sal_Int32>>
2465 size_t const first(aName.find(toxMarkSeparator));
2466 if (first == std::u16string_view::npos)
2468 SAL_WARN("sw.ui", "JumpToTOXMark: missing separator");
2469 return std::optional<std::pair<SwTOXMark, sal_Int32>>();
2471 sal_Int32 const counter(o3tl::toInt32(aName.substr(0, first)));
2472 if (counter <= 0)
2474 SAL_WARN("sw.ui", "JumpToTOXMark: invalid counter");
2475 return std::optional<std::pair<SwTOXMark, sal_Int32>>();
2477 size_t const second(aName.find(toxMarkSeparator, first + 1));
2478 if (second == std::u16string_view::npos)
2480 SAL_WARN("sw.ui", "JumpToTOXMark: missing separator");
2481 return std::optional<std::pair<SwTOXMark, sal_Int32>>();
2483 std::u16string_view const entry(aName.substr(first + 1, second - (first + 1)));
2484 if (aName.size() < second + 2)
2486 SAL_WARN("sw.ui", "JumpToTOXMark: invalid tox");
2487 return std::optional<std::pair<SwTOXMark, sal_Int32>>();
2489 sal_uInt16 const indexType(aName[second + 1]);
2490 std::u16string_view const indexName(aName.substr(second + 2));
2491 SwTOXType const* pType(nullptr);
2492 switch (indexType)
2494 case 'A':
2495 pType = rDoc.GetTOXType(TOX_INDEX, 0);
2496 assert(pType);
2497 break;
2498 case 'C':
2499 pType = rDoc.GetTOXType(TOX_CONTENT, 0);
2500 assert(pType);
2501 break;
2502 case 'U':
2503 for (auto i = rDoc.GetTOXTypeCount(TOX_USER); 0 < i; )
2505 --i;
2506 auto const pTmp(rDoc.GetTOXType(TOX_USER, i));
2507 if (pTmp->GetTypeName() == indexName)
2509 pType = pTmp;
2510 break;
2513 break;
2515 if (!pType)
2517 SAL_WARN("sw.ui", "JumpToTOXMark: tox doesn't exist");
2518 return std::optional<std::pair<SwTOXMark, sal_Int32>>();
2520 // type and alt text are the search keys
2521 SwTOXMark tmp(pType);
2522 tmp.SetAlternativeText(OUString(entry));
2523 return std::optional<std::pair<SwTOXMark, sal_Int32>>(std::pair<SwTOXMark, sal_Int32>(tmp, counter));
2526 } // namespace sw
2528 static auto JumpToTOXMark(SwWrtShell & rSh, std::u16string_view aName) -> bool
2530 std::optional<std::pair<SwTOXMark, sal_Int32>> const tmp(
2531 sw::PrepareJumpToTOXMark(*rSh.GetDoc(), aName));
2532 if (!tmp)
2534 return false;
2536 SwTOXMark const* pMark(&tmp->first);
2537 // hack: check first if one exists
2538 if (&tmp->first != &rSh.GetDoc()->GotoTOXMark(tmp->first, TOX_SAME_NXT, rSh.IsReadOnlyAvailable()))
2540 for (sal_Int32 i = 0; i < tmp->second; ++i)
2542 pMark = &rSh.GotoTOXMark(*pMark, TOX_SAME_NXT);
2544 return true;
2546 else
2548 SAL_WARN("sw.ui", "JumpToTOXMark: tox mark doesn't exist");
2549 return false;
2553 bool SwView::JumpToSwMark( std::u16string_view rMark )
2555 bool bRet = false;
2556 if( !rMark.empty() )
2558 // place bookmark at top-center
2559 bool bSaveCC = m_bCenterCursor;
2560 bool bSaveCT = m_bTopCursor;
2561 SetCursorAtTop( true );
2563 // For scrolling the FrameSet, the corresponding shell needs to have the focus.
2564 bool bHasShFocus = m_pWrtShell->HasShellFocus();
2565 if( !bHasShFocus )
2566 m_pWrtShell->ShellGetFocus();
2568 const SwFormatINetFormat* pINet;
2569 OUString sCmp;
2570 OUString sMark( INetURLObject::decode( rMark,
2571 INetURLObject::DecodeMechanism::WithCharset ));
2573 sal_Int32 nLastPos, nPos = sMark.indexOf( cMarkSeparator );
2574 if( -1 != nPos )
2575 while( -1 != ( nLastPos = sMark.indexOf( cMarkSeparator, nPos + 1 )) )
2576 nPos = nLastPos;
2578 IDocumentMarkAccess::const_iterator_t ppMark;
2579 IDocumentMarkAccess* const pMarkAccess = m_pWrtShell->getIDocumentMarkAccess();
2580 if( -1 != nPos )
2581 sCmp = sMark.copy(nPos + 1).replaceAll(" ", "");
2583 if( !sCmp.isEmpty() )
2585 OUString sName( sMark.copy( 0, nPos ) );
2586 sCmp = sCmp.toAsciiLowerCase();
2587 FlyCntType eFlyType = FLYCNTTYPE_ALL;
2589 if (sCmp == "drawingobject")
2590 bRet = m_pWrtShell->GotoDrawingObject(sName);
2591 else if( sCmp == "region" )
2593 m_pWrtShell->EnterStdMode();
2594 bRet = m_pWrtShell->GotoRegion( sName );
2596 else if( sCmp == "outline" )
2598 m_pWrtShell->EnterStdMode();
2599 bRet = m_pWrtShell->GotoOutline( sName );
2601 else if( sCmp == "frame" )
2602 eFlyType = FLYCNTTYPE_FRM;
2603 else if( sCmp == "graphic" )
2604 eFlyType = FLYCNTTYPE_GRF;
2605 else if( sCmp == "ole" )
2606 eFlyType = FLYCNTTYPE_OLE;
2607 else if( sCmp == "table" )
2609 m_pWrtShell->EnterStdMode();
2610 bRet = m_pWrtShell->GotoTable( sName );
2612 else if( sCmp == "sequence" )
2614 m_pWrtShell->EnterStdMode();
2615 sal_Int32 nNoPos = sName.indexOf( cSequenceMarkSeparator );
2616 if ( nNoPos != -1 )
2618 sal_uInt16 nSeqNo = o3tl::toInt32(sName.subView( nNoPos + 1 ));
2619 sName = sName.copy( 0, nNoPos );
2620 bRet = m_pWrtShell->GotoRefMark(sName, REF_SEQUENCEFLD, nSeqNo);
2623 else if (sCmp == "toxmark")
2625 bRet = JumpToTOXMark(*m_pWrtShell, sName);
2627 else if( sCmp == "text" )
2629 // normal text search
2630 m_pWrtShell->EnterStdMode();
2632 i18nutil::SearchOptions2 aSearchOpt(
2633 SearchAlgorithms_ABSOLUTE, 0,
2634 sName, OUString(),
2635 SvtSysLocale().GetLanguageTag().getLocale(),
2636 0,0,0,
2637 TransliterationFlags::IGNORE_CASE,
2638 SearchAlgorithms2::ABSOLUTE,
2639 '\\' );
2641 //todo/mba: assuming that notes shouldn't be searched
2642 if( m_pWrtShell->SearchPattern( aSearchOpt, false/*bSearchInNotes*/, SwDocPositions::Start, SwDocPositions::End ))
2644 m_pWrtShell->EnterStdMode(); // remove the selection
2645 bRet = true;
2648 else if( pMarkAccess->getAllMarksEnd() != (ppMark = pMarkAccess->findMark(sMark)) )
2650 bRet = m_pWrtShell->GotoMark( *ppMark, false );
2652 else if( nullptr != ( pINet = m_pWrtShell->FindINetAttr( sMark ) )) {
2653 m_pWrtShell->addCurrentPosition();
2654 bRet = m_pWrtShell->GotoINetAttr( *pINet->GetTextINetFormat() );
2657 // for all types of Flys
2658 if( FLYCNTTYPE_ALL != eFlyType && m_pWrtShell->GotoFly( sName, eFlyType ))
2660 bRet = true;
2661 if( FLYCNTTYPE_FRM == eFlyType )
2663 // TextFrames: set Cursor in the frame
2664 m_pWrtShell->UnSelectFrame();
2665 m_pWrtShell->LeaveSelFrameMode();
2667 else
2669 m_pWrtShell->HideCursor();
2670 m_pWrtShell->EnterSelFrameMode();
2674 else if( pMarkAccess->getAllMarksEnd() != (ppMark = pMarkAccess->findMark(sMark)))
2676 bRet = m_pWrtShell->GotoMark( *ppMark, false );
2678 else if( nullptr != ( pINet = m_pWrtShell->FindINetAttr( sMark ) ))
2679 bRet = m_pWrtShell->GotoINetAttr( *pINet->GetTextINetFormat() );
2681 // make selection visible later
2682 if ( m_aVisArea.IsEmpty() )
2683 m_bMakeSelectionVisible = true;
2685 // reset ViewStatus
2686 SetCursorAtTop( bSaveCT, bSaveCC );
2688 if(!m_pWrtShell->IsFrameSelected() && !m_pWrtShell->IsObjSelected())
2689 m_pWrtShell->ShowCursor();
2691 if( !bHasShFocus )
2692 m_pWrtShell->ShellLoseFocus();
2694 return bRet;
2697 // #i67305# Undo after insert from file:
2698 // Undo "Insert form file" crashes with documents imported from binary filter (.sdw) => disabled
2699 // Undo "Insert form file" crashes with (.odt) documents crashes if these documents contains
2700 // page styles with active header/footer => disabled for those documents
2701 static size_t lcl_PageDescWithHeader( const SwDoc& rDoc )
2703 size_t nRet = 0;
2704 size_t nCnt = rDoc.GetPageDescCnt();
2705 for( size_t i = 0; i < nCnt; ++i )
2707 const SwPageDesc& rPageDesc = rDoc.GetPageDesc( i );
2708 const SwFrameFormat& rMaster = rPageDesc.GetMaster();
2709 const SwFormatHeader* pHeaderItem = rMaster.GetAttrSet().GetItemIfSet( RES_HEADER, false );
2710 const SwFormatFooter* pFooterItem = rMaster.GetAttrSet().GetItemIfSet( RES_FOOTER, false );
2711 if( (pHeaderItem && pHeaderItem->IsActive()) ||
2712 (pFooterItem && pFooterItem->IsActive()) )
2713 ++nRet;
2715 return nRet; // number of page styles with active header/footer
2718 void SwView::ExecuteInsertDoc( SfxRequest& rRequest, const SfxPoolItem* pItem )
2720 m_pViewImpl->InitRequest( rRequest );
2721 m_pViewImpl->SetParam( pItem ? 1 : 0 );
2722 const sal_uInt16 nSlot = rRequest.GetSlot();
2724 if ( !pItem )
2726 InsertDoc( nSlot, "", "" );
2728 else
2730 OUString sFile, sFilter;
2731 sFile = static_cast<const SfxStringItem *>( pItem )->GetValue();
2732 if ( SfxItemState::SET == rRequest.GetArgs()->GetItemState( FN_PARAM_1, true, &pItem ) )
2733 sFilter = static_cast<const SfxStringItem *>(pItem )->GetValue();
2735 bool bHasFileName = !sFile.isEmpty();
2736 tools::Long nFound = InsertDoc( nSlot, sFile, sFilter );
2738 if ( bHasFileName )
2740 rRequest.SetReturnValue( SfxBoolItem( nSlot, nFound != -1 ) );
2741 rRequest.Done();
2746 tools::Long SwView::InsertDoc( sal_uInt16 nSlotId, const OUString& rFileName, const OUString& rFilterName, sal_Int16 nVersion )
2748 std::unique_ptr<SfxMedium> pMed;
2749 SwDocShell* pDocSh = GetDocShell();
2751 if( !rFileName.isEmpty() )
2753 SfxObjectFactory& rFact = pDocSh->GetFactory();
2754 std::shared_ptr<const SfxFilter> pFilter = rFact.GetFilterContainer()->GetFilter4FilterName( rFilterName );
2755 if ( !pFilter )
2757 pMed.reset(new SfxMedium(rFileName, StreamMode::READ, nullptr, nullptr ));
2758 SfxFilterMatcher aMatcher( rFact.GetFilterContainer()->GetName() );
2759 pMed->UseInteractionHandler( true );
2760 ErrCode nErr = aMatcher.GuessFilter(*pMed, pFilter, SfxFilterFlags::NONE);
2761 if ( nErr )
2762 pMed.reset();
2763 else
2764 pMed->SetFilter( pFilter );
2766 else
2767 pMed.reset(new SfxMedium(rFileName, StreamMode::READ, pFilter, nullptr));
2769 else
2771 m_pViewImpl->StartDocumentInserter(
2772 // tdf#118578 allow inserting any Writer document except GlobalDoc
2773 SwDocShell::Factory().GetFactoryName(),
2774 LINK( this, SwView, DialogClosedHdl ),
2775 nSlotId
2777 return -1;
2780 if( !pMed )
2781 return -1;
2783 return InsertMedium( nSlotId, std::move(pMed), nVersion );
2786 tools::Long SwView::InsertMedium( sal_uInt16 nSlotId, std::unique_ptr<SfxMedium> pMedium, sal_Int16 nVersion )
2788 bool bInsert = false, bCompare = false;
2789 tools::Long nFound = 0;
2790 SwDocShell* pDocSh = GetDocShell();
2792 switch( nSlotId )
2794 case SID_DOCUMENT_MERGE: break;
2795 case SID_DOCUMENT_COMPARE: bCompare = true; break;
2796 case SID_INSERTDOC: bInsert = true; break;
2798 default:
2799 OSL_ENSURE( false, "unknown SlotId!" );
2800 bInsert = true;
2801 break;
2804 if( bInsert )
2806 uno::Reference< frame::XDispatchRecorder > xRecorder =
2807 GetViewFrame().GetBindings().GetRecorder();
2808 if ( xRecorder.is() )
2810 SfxRequest aRequest(GetViewFrame(), SID_INSERTDOC);
2811 aRequest.AppendItem(SfxStringItem(SID_INSERTDOC, pMedium->GetOrigURL()));
2812 if(pMedium->GetFilter())
2813 aRequest.AppendItem(SfxStringItem(FN_PARAM_1, pMedium->GetFilter()->GetName()));
2814 aRequest.Done();
2817 SfxObjectShellRef aRef( pDocSh );
2819 ErrCode nError = SfxObjectShell::HandleFilter( pMedium.get(), pDocSh );
2820 // #i16722# aborted?
2821 if(nError != ERRCODE_NONE)
2823 return -1;
2826 pMedium->Download(); // start download if needed
2827 if( aRef.is() && 1 < aRef->GetRefCount() ) // still a valid ref?
2829 SwReaderPtr pRdr;
2830 Reader *pRead = pDocSh->StartConvertFrom(*pMedium, pRdr, m_pWrtShell.get());
2831 if( pRead ||
2832 (pMedium->GetFilter()->GetFilterFlags() & SfxFilterFlags::STARONEFILTER) )
2834 size_t nUndoCheck = 0;
2835 SwDoc *pDoc = pDocSh->GetDoc();
2836 if( pRead && pDocSh->GetDoc() )
2837 nUndoCheck = lcl_PageDescWithHeader( *pDoc );
2838 ErrCode nErrno;
2839 { //Scope for SwWait-Object, to be able to execute slots
2840 //outside this scope.
2841 SwWait aWait( *GetDocShell(), true );
2842 m_pWrtShell->StartAllAction();
2843 if ( m_pWrtShell->HasSelection() )
2844 m_pWrtShell->DelRight(); // delete selections
2845 if( pRead )
2847 nErrno = pRdr->Read( *pRead ); // and insert document
2848 pRdr.reset();
2850 else
2852 ::sw::UndoGuard const ug(pDoc->GetIDocumentUndoRedo());
2853 rtl::Reference<SwXTextRange> const xInsertPosition(
2854 SwXTextRange::CreateXTextRange(*pDoc,
2855 *m_pWrtShell->GetCursor()->GetPoint(), nullptr));
2856 nErrno = pDocSh->ImportFrom(*pMedium, xInsertPosition)
2857 ? ERRCODE_NONE : ERR_SWG_READ_ERROR;
2862 // update all "table of ..." sections if needed
2863 if( m_pWrtShell->IsUpdateTOX() )
2865 SfxRequest aReq( FN_UPDATE_TOX, SfxCallMode::SLOT, GetPool() );
2866 Execute( aReq );
2867 m_pWrtShell->SetUpdateTOX( false ); // reset
2870 if( pDoc )
2871 { // Disable Undo for .sdw or
2872 // if the number of page styles with header/footer has changed
2873 if( !pRead || nUndoCheck != lcl_PageDescWithHeader( *pDoc ) )
2875 pDoc->GetIDocumentUndoRedo().DelAllUndoObj();
2879 m_pWrtShell->EndAllAction();
2880 if( nErrno )
2882 ErrorHandler::HandleError( nErrno );
2883 nFound = nErrno.IsError() ? -1 : 0;
2885 else
2886 nFound = 0;
2890 else
2892 SfxObjectShellRef xDocSh;
2893 SfxObjectShellLock xLockRef;
2895 const int nRet = SwFindDocShell( xDocSh, xLockRef, pMedium->GetName(), OUString(),
2896 OUString(), nVersion, pDocSh );
2897 if( nRet )
2899 SwWait aWait( *GetDocShell(), true );
2900 m_pWrtShell->StartAllAction();
2902 m_pWrtShell->EnterStdMode(); // delete selections
2904 if( bCompare )
2905 nFound = m_pWrtShell->CompareDoc( *static_cast<SwDocShell*>( xDocSh.get() )->GetDoc() );
2906 else
2907 nFound = m_pWrtShell->MergeDoc( *static_cast<SwDocShell*>( xDocSh.get() )->GetDoc() );
2909 m_pWrtShell->EndAllAction();
2911 if (!bCompare && !nFound)
2913 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetEditWin().GetFrameWeld(),
2914 VclMessageType::Info, VclButtonsType::Ok,
2915 SwResId(STR_NO_MERGE_ENTRY)));
2916 xInfoBox->run();
2918 if( nRet==2 && xDocSh.is() )
2919 xDocSh->DoClose();
2923 return nFound;
2926 void SwView::EnableMailMerge()
2928 m_bInMailMerge = true;
2929 SfxBindings& rBind = GetViewFrame().GetBindings();
2930 rBind.Invalidate(FN_INSERT_FIELD_DATA_ONLY);
2931 rBind.Update(FN_INSERT_FIELD_DATA_ONLY);
2934 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
2936 namespace
2938 bool lcl_NeedAdditionalDataSource( const uno::Reference< XDatabaseContext >& _rDatasourceContext )
2940 Sequence < OUString > aNames = _rDatasourceContext->getElementNames();
2942 return ( !aNames.hasElements()
2943 || ( ( 1 == aNames.getLength() )
2944 && aNames.getConstArray()[0] == SW_MOD()->GetDBConfig()->GetBibliographySource().sDataSource
2950 #endif
2952 void SwView::GenerateFormLetter(bool bUseCurrentDocument)
2954 #if !HAVE_FEATURE_DBCONNECTIVITY || ENABLE_FUZZERS
2955 (void) bUseCurrentDocument;
2956 #else
2957 if(bUseCurrentDocument)
2959 if(!GetWrtShell().IsAnyDatabaseFieldInDoc())
2961 //check availability of data sources (except biblio source)
2962 uno::Reference<XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
2963 uno::Reference<XDatabaseContext> xDBContext = DatabaseContext::create(xContext);
2964 bool bCallAddressPilot = false;
2965 if ( lcl_NeedAdditionalDataSource( xDBContext ) )
2967 // no data sources are available - create a new one
2968 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "modules/swriter/ui/datasourcesunavailabledialog.ui"));
2969 std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("DataSourcesUnavailableDialog"));
2970 // no cancel allowed
2971 if (RET_OK != xQuery->run())
2972 return;
2973 bCallAddressPilot = true;
2975 else
2977 //take an existing data source or create a new one?
2978 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
2979 ScopedVclPtr<AbstractMailMergeFieldConnectionsDlg> pConnectionsDlg(pFact->CreateMailMergeFieldConnectionsDlg(GetFrameWeld()));
2980 if(RET_OK == pConnectionsDlg->Execute())
2981 bCallAddressPilot = !pConnectionsDlg->IsUseExistingConnections();
2982 else
2983 return;
2986 if(bCallAddressPilot)
2988 GetViewFrame().GetDispatcher()->Execute(
2989 SID_ADDRESS_DATA_SOURCE, SfxCallMode::SYNCHRON);
2990 if ( lcl_NeedAdditionalDataSource( xDBContext ) )
2991 // no additional data source has been created
2992 // -> assume that the user has cancelled the pilot
2993 return;
2996 //call insert fields with database field page available, only
2997 SfxViewFrame& rVFrame = GetViewFrame();
2998 //at first hide the default field dialog if currently visible
2999 rVFrame.SetChildWindow(FN_INSERT_FIELD, false);
3000 //enable the status of the db field dialog - it is disabled in the status method
3001 //to prevent creation of the dialog without mail merge active
3002 EnableMailMerge();
3003 //then show the "Data base only" field dialog
3004 SfxBoolItem aOn(FN_INSERT_FIELD_DATA_ONLY, true);
3005 rVFrame.GetDispatcher()->ExecuteList(FN_INSERT_FIELD_DATA_ONLY,
3006 SfxCallMode::SYNCHRON, { &aOn });
3007 return;
3009 else
3011 OUString sSource;
3012 if(!GetWrtShell().IsFieldDataSourceAvailable(sSource))
3014 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "modules/swriter/ui/warndatasourcedialog.ui"));
3015 std::unique_ptr<weld::MessageDialog> xWarning(xBuilder->weld_message_dialog("WarnDataSourceDialog"));
3016 OUString sTmp(xWarning->get_primary_text());
3017 xWarning->set_primary_text(sTmp.replaceFirst("%1", sSource));
3018 if (RET_OK == xWarning->run())
3020 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
3021 ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateVclDialog( nullptr, SID_OPTIONS_DATABASES ));
3022 pDlg->Execute();
3024 return ;
3027 SwDBManager* pDBManager = GetWrtShell().GetDBManager();
3029 SwDBData aData;
3030 SwWrtShell &rSh = GetWrtShell();
3032 std::vector<OUString> aDBNameList;
3033 std::vector<OUString> aAllDBNames;
3034 rSh.GetAllUsedDB( aDBNameList, &aAllDBNames );
3035 if(!aDBNameList.empty())
3037 OUString sDBName(aDBNameList[0]);
3038 sal_Int32 nIdx {0};
3039 aData.sDataSource = sDBName.getToken(0, DB_DELIM, nIdx);
3040 aData.sCommand = sDBName.getToken(0, DB_DELIM, nIdx);
3041 aData.nCommandType = o3tl::toInt32(o3tl::getToken(sDBName, 0, DB_DELIM, nIdx));
3043 rSh.EnterStdMode(); // force change in text shell; necessary for mixing DB fields
3044 AttrChangedNotify(nullptr);
3046 if (pDBManager)
3048 Sequence<PropertyValue> aProperties
3050 comphelper::makePropertyValue("DataSourceName", aData.sDataSource),
3051 comphelper::makePropertyValue("Command", aData.sCommand),
3052 comphelper::makePropertyValue("CommandType", aData.nCommandType),
3054 pDBManager->ExecuteFormLetter(GetWrtShell(), aProperties);
3057 else
3059 // call documents and template dialog
3060 SfxApplication* pSfxApp = SfxGetpApp();
3061 weld::Window* pTopWin = pSfxApp->GetTopWindow();
3063 SfxTemplateManagerDlg aDocTemplDlg(GetFrameWeld());
3064 int nRet = aDocTemplDlg.run();
3065 bool bNewWin = false;
3066 if ( nRet == RET_OK )
3068 if ( pTopWin != pSfxApp->GetTopWindow() )
3070 // the dialogue opens a document -> a new TopWindow appears
3071 pTopWin = pSfxApp->GetTopWindow();
3072 bNewWin = true;
3076 if (bNewWin)
3078 // after the destruction of the dialogue its parent comes to top,
3079 // but we want that the new document is on top
3080 pTopWin->present();
3083 #endif
3086 IMPL_LINK( SwView, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg, void )
3088 if ( ERRCODE_NONE != _pFileDlg->GetError() )
3089 return;
3091 std::unique_ptr<SfxMedium> pMed = m_pViewImpl->CreateMedium();
3092 if ( !pMed )
3094 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetEditWin().GetFrameWeld(),
3095 VclMessageType::Info, VclButtonsType::Ok,
3096 SwResId(RID_SVXSTR_TXTFILTER_FILTERERROR)));
3097 xInfoBox->run();
3098 return;
3101 const sal_uInt16 nSlot = m_pViewImpl->GetRequest()->GetSlot();
3102 tools::Long nFound = InsertMedium( nSlot, std::move(pMed), m_pViewImpl->GetParam() );
3104 if ( SID_INSERTDOC == nSlot )
3106 if ( m_pViewImpl->GetParam() == 0 )
3108 m_pViewImpl->GetRequest()->SetReturnValue( SfxBoolItem( nSlot, nFound != -1 ) );
3109 m_pViewImpl->GetRequest()->Ignore();
3111 else
3113 m_pViewImpl->GetRequest()->SetReturnValue( SfxBoolItem( nSlot, nFound != -1 ) );
3114 m_pViewImpl->GetRequest()->Done();
3117 else if ( SID_DOCUMENT_COMPARE == nSlot || SID_DOCUMENT_MERGE == nSlot )
3119 m_pViewImpl->GetRequest()->SetReturnValue( SfxInt32Item( nSlot, nFound ) );
3121 if ( nFound > 0 ) // show Redline browser
3123 SfxViewFrame& rVFrame = GetViewFrame();
3124 rVFrame.ShowChildWindow(FN_REDLINE_ACCEPT);
3126 // re-initialize Redline dialog
3127 sal_uInt16 nId = SwRedlineAcceptChild::GetChildWindowId();
3128 SwRedlineAcceptChild* pRed = static_cast<SwRedlineAcceptChild*>(rVFrame.GetChildWindow( nId ));
3129 if ( pRed )
3130 pRed->ReInitDlg( GetDocShell() );
3135 void SwView::ExecuteScan( SfxRequest& rReq )
3137 if (m_pViewImpl)
3138 m_pViewImpl->ExecuteScan(rReq) ;
3141 const OUString& SwView::GetOldGrfCat()
3143 return GetCachedString(OldGrfCat);
3146 void SwView::SetOldGrfCat(const OUString& sStr)
3148 SetCachedString(OldGrfCat, sStr);
3151 const OUString& SwView::GetOldTabCat()
3153 return GetCachedString(OldTabCat);
3156 void SwView::SetOldTabCat(const OUString& sStr)
3158 SetCachedString(OldTabCat, sStr);
3161 const OUString& SwView::GetOldFrameCat()
3163 return GetCachedString(OldFrameCat);
3166 void SwView::SetOldFrameCat(const OUString& sStr)
3168 SetCachedString(OldFrameCat, sStr);
3171 const OUString& SwView::GetOldDrwCat()
3173 return GetCachedString(OldDrwCat);
3176 void SwView::SetOldDrwCat(const OUString& sStr)
3178 SwView::SetCachedString(OldDrwCat, sStr);
3182 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */