/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <comphelper/string.hxx>
#include <svl/urlbmk.hxx>
#include <svl/stritem.hxx>
#include <vcl/graphicfilter.hxx>
#include <sot/formats.hxx>
#include <sot/filelist.hxx>
#include <sfx2/event.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewfrm.hxx>
#include <tools/urlobj.hxx>
#include <osl/diagnose.h>
#include <swtypes.hxx>
#include <swmodule.hxx>
#include <view.hxx>
#include <navicfg.hxx>
#include <wrtsh.hxx>
#include <docsh.hxx>
#include <navipi.hxx>
#include <edtwin.hxx>
#include <sfx2/app.hxx>
#include <cmdid.h>
#include <helpids.h>
#include <strings.hrc>
#include <bitmaps.hlst>
#include <memory>
#include <o3tl/enumrange.hxx>
#include <workctrl.hxx>
#include <comphelper/lok.hxx>
#include <swcont.hxx>
#include <content.hxx>
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::frame;
// Filter the control characters out of the Outline-Entry
OUString SwNavigationPI::CleanEntry(const OUString& rEntry)
{
if (rEntry.isEmpty())
return rEntry;
OUStringBuffer aEntry(rEntry);
for (sal_Int32 i = 0; i < rEntry.getLength(); ++i)
if(aEntry[i] == 10 || aEntry[i] == 9)
aEntry[i] = 0x20;
return aEntry.makeStringAndClear();
}
// Execution of the drag operation with and without the children.
void SwNavigationPI::MoveOutline(SwOutlineNodes::size_type nSource, SwOutlineNodes::size_type nTarget)
{
SwView *pView = GetCreateView();
if (!pView)
return;
SwWrtShell &rSh = pView->GetWrtShell();
if (nTarget == SwOutlineNodes::npos)
nTarget = 0;
else if (nTarget < nSource)
nTarget++;
if ( !rSh.IsOutlineMovable( nSource ))
return;
SwOutlineNodes::difference_type nMove = nTarget-nSource; //( nDir<0 ) ? 1 : 0 ;
rSh.GotoOutline(nSource);
rSh.MakeOutlineSel(nSource, nSource, true);
// While moving, the selected children does not counting.
const SwOutlineNodes::size_type nLastOutlinePos = rSh.GetOutlinePos(MAXLEVEL);
if(nMove > 1 && nLastOutlinePos < nTarget)
{
if(!rSh.IsCursorPtAtEnd())
rSh.SwapPam();
nMove -= nLastOutlinePos - nSource;
}
if( nMove < 1 || nLastOutlinePos < nTarget )
rSh.MoveOutlinePara( nMove );
rSh.ClearMark();
rSh.GotoOutline( nSource + nMove);
}
// After goto cancel the status frame selection
static void lcl_UnSelectFrame(SwWrtShell *pSh)
{
if (pSh->IsFrameSelected())
{
pSh->UnSelectFrame();
pSh->LeaveSelFrameMode();
}
}
// Select the document view
IMPL_LINK(SwNavigationPI, DocListBoxSelectHdl, weld::ComboBox&, rBox, void)
{
int nEntryIdx = rBox.get_active();
SwView *pView ;
pView = SwModule::GetFirstView();
while (nEntryIdx-- && pView)
{
pView = SwModule::GetNextView(pView);
}
if(!pView)
{
nEntryIdx == 0 ?
m_xContentTree->ShowHiddenShell():
m_xContentTree->ShowActualView();
}
else
{
m_xContentTree->SetConstantShell(pView->GetWrtShellPtr());
}
}
void SwNavigationPI::UpdateNavigateBy()
{
if (!m_pNavigateByComboBox)
return;
SfxUInt32Item aParam(FN_NAV_ELEMENT, m_pNavigateByComboBox->get_active_id().toUInt32());
const SfxPoolItem* aArgs[2];
aArgs[0] = &aParam;
aArgs[1] = nullptr;
SfxDispatcher* pDispatcher = GetCreateView()->GetFrame()->GetDispatcher();
pDispatcher->Execute(FN_NAV_ELEMENT, SfxCallMode::SYNCHRON, aArgs);
}
IMPL_LINK(SwNavigationPI, NavigateByComboBoxSelectHdl, weld::ComboBox&, rComboBox, void)
{
m_xContentTree->SelectContentType(rComboBox.get_active_text());
UpdateNavigateBy();
}
void SwNavigationPI::SetContent3And4ToolBoxVisibility()
{
if (IsGlobalMode())
return;
bool bIsMoveTypePage = SwView::GetMoveType() == NID_PGE;
m_xContent3ToolBox->set_visible(!bIsMoveTypePage);
m_xContent4ToolBox->set_visible(bIsMoveTypePage);
}
// Filling of the list box for outline view or documents
// The PI will be set to full size
void SwNavigationPI::FillBox()
{
if(m_pContentWrtShell)
{
m_xContentTree->SetHiddenShell( m_pContentWrtShell );
m_xContentTree->Display( false );
}
else
{
SwView *pView = GetCreateView();
if(!pView)
{
m_xContentTree->SetActiveShell(nullptr);
}
else if( pView != m_pActContView)
{
SwWrtShell* pWrtShell = pView->GetWrtShellPtr();
m_xContentTree->SetActiveShell(pWrtShell);
}
else
m_xContentTree->Display( true );
m_pActContView = pView;
if (m_pActContView)
m_xContentTree->UpdateTracking();
}
}
// Select handler of the toolboxes
IMPL_LINK(SwNavigationPI, ToolBoxSelectHdl, const OUString&, rCommand, void)
{
SwView *pView = GetCreateView();
if (!pView)
return;
SwWrtShell &rSh = pView->GetWrtShell();
// Get MouseModifier for Outline-Move
int nFuncId = 0;
bool bFocusToDoc = false;
if (rCommand == "root")
{
m_xContentTree->ToggleToRoot();
}
else if (rCommand == "listbox")
{
if (ParentIsFloatingWindow(m_xNavigatorDlg))
{
if (IsZoomedIn())
{
ZoomOut();
}
else
{
ZoomIn();
}
}
return;
}
// Functions that will trigger a direct action.
else if (rCommand == "footer")
{
rSh.MoveCursor();
const FrameTypeFlags eType = rSh.GetFrameType(nullptr,false);
if (eType & FrameTypeFlags::FOOTER)
{
if (rSh.EndPg())
nFuncId = FN_END_OF_PAGE;
}
else if (rSh.GotoFooterText())
nFuncId = FN_TO_FOOTER;
bFocusToDoc = true;
}
else if (rCommand == "header")
{
rSh.MoveCursor();
const FrameTypeFlags eType = rSh.GetFrameType(nullptr,false);
if (eType & FrameTypeFlags::HEADER)
{
if (rSh.SttPg())
nFuncId = FN_START_OF_PAGE;
}
else if (rSh.GotoHeaderText())
nFuncId = FN_TO_HEADER;
bFocusToDoc = true;
}
else if (rCommand == "anchor")
{
rSh.MoveCursor();
const FrameTypeFlags eFrameType = rSh.GetFrameType(nullptr,false);
// Jump from the footnote to the anchor.
if (eFrameType & FrameTypeFlags::FOOTNOTE)
{
if (rSh.GotoFootnoteAnchor())
nFuncId = FN_FOOTNOTE_TO_ANCHOR;
}
// Otherwise, jump to the first footnote text;
// go to the next footnote if this is not possible;
// if this is also not possible got to the footnote before.
else
{
if (rSh.GotoFootnoteText())
nFuncId = FN_FOOTNOTE_TO_ANCHOR;
else if (rSh.GotoNextFootnoteAnchor())
nFuncId = FN_NEXT_FOOTNOTE;
else if (rSh.GotoPrevFootnoteAnchor())
nFuncId = FN_PREV_FOOTNOTE;
}
bFocusToDoc = true;
}
else if (rCommand == "reminder")
{
rSh.GetView().GetViewFrame().GetDispatcher()->Execute(FN_SET_REMINDER, SfxCallMode::ASYNCHRON);
}
else if (rCommand == "movedown" ||
rCommand == "moveup" ||
rCommand == "edit")
{
if (IsGlobalMode())
m_xGlobalTree->ExecCommand(rCommand);
}
else if (rCommand == "contenttoggle" || rCommand == "globaltoggle")
{
ToggleTree();
bool bGlobalMode = IsGlobalMode();
m_pConfig->SetGlobalActive(bGlobalMode);
m_xGlobalToolBox->set_item_active(u"globaltoggle"_ustr, bGlobalMode);
}
else if (rCommand == "save")
{
bool bSave = rSh.IsGlblDocSaveLinks();
rSh.SetGlblDocSaveLinks( !bSave );
m_xGlobalToolBox->set_item_active(rCommand, !bSave);
}
else if (rCommand == "headings")
m_xContent5ToolBox->set_menu_item_active(u"headings"_ustr, !m_xContent5ToolBox->get_menu_item_active(u"headings"_ustr));
else if (rCommand == "update")
m_xGlobalToolBox->set_menu_item_active(u"update"_ustr, !m_xGlobalToolBox->get_menu_item_active(u"update"_ustr));
else if (rCommand == "insert")
m_xGlobalToolBox->set_menu_item_active(u"insert"_ustr, !m_xGlobalToolBox->get_menu_item_active(u"insert"_ustr));
if (nFuncId)
lcl_UnSelectFrame(&rSh);
if (bFocusToDoc)
pView->GetEditWin().GrabFocus();
}
// Click handler of the toolboxes
IMPL_LINK(SwNavigationPI, ToolBoxClickHdl, const OUString&, rCommand, void)
{
if (!m_xGlobalToolBox->get_menu_item_active(rCommand))
return;
if (rCommand == "update")
m_xGlobalTree->TbxMenuHdl(rCommand, *m_xUpdateMenu);
else if (rCommand == "insert")
m_xGlobalTree->TbxMenuHdl(rCommand, *m_xInsertMenu);
}
IMPL_LINK(SwNavigationPI, GlobalMenuSelectHdl, const OUString&, rIdent, void)
{
m_xGlobalTree->ExecuteContextMenuAction(rIdent);
}
IMPL_LINK(SwNavigationPI, ToolBox5DropdownClickHdl, const OUString&, rCommand, void)
{
if (!m_xContent5ToolBox->get_menu_item_active(rCommand))
return;
if (rCommand == "headings")
m_xHeadingsMenu->set_active(OUString::number(m_xContentTree->GetOutlineLevel()), true);
}
void SwNavigationPI::ZoomOut()
{
if (!IsZoomedIn())
return;
SfxNavigator* pNav = m_xNavigatorDlg.get();
if (!pNav)
return;
m_bIsZoomedIn = false;
FillBox();
if (IsGlobalMode())
{
m_xGlobalBox->show();
m_xGlobalTree->ShowTree();
}
else
{
m_xContentBox->show();
m_xContentTree->ShowTree();
m_xDocListBox->show();
}
pNav->InvalidateChildSizeCache();
Size aOptimalSize(pNav->GetOptimalSize());
Size aNewSize(pNav->GetOutputSizePixel());
aNewSize.setHeight( m_aExpandedSize.Height() );
pNav->SetMinOutputSizePixel(aOptimalSize);
pNav->SetOutputSizePixel(aNewSize);
m_xContentTree->UpdateContentFunctionsToolbar(); // Enable toolbox
m_pConfig->SetSmall(false);
m_xContent6ToolBox->set_item_active(u"listbox"_ustr, true);
}
void SwNavigationPI::ZoomIn()
{
if (IsZoomedIn())
return;
SfxNavigator* pNav = m_xNavigatorDlg.get();
if (!pNav)
return;
m_aExpandedSize = m_xNavigatorDlg->GetSizePixel();
m_xContentBox->hide();
m_xContentTree->HideTree();
m_xGlobalBox->hide();
m_xGlobalTree->HideTree();
m_xDocListBox->hide();
m_bIsZoomedIn = true;
pNav->InvalidateChildSizeCache();
Size aOptimalSize(pNav->GetOptimalSize());
Size aNewSize(pNav->GetOutputSizePixel());
aNewSize.setHeight( aOptimalSize.Height() );
pNav->SetMinOutputSizePixel(aOptimalSize);
pNav->SetOutputSizePixel(aNewSize);
m_xContentTree->UpdateContentFunctionsToolbar(); // Enable toolbox
m_pConfig->SetSmall(true);
m_xContent6ToolBox->set_item_active(u"listbox"_ustr, false);
}
std::unique_ptr<PanelLayout> SwNavigationPI::Create(weld::Widget* pParent,
const css::uno::Reference<css::frame::XFrame>& rxFrame,
SfxBindings* pBindings)
{
if( pParent == nullptr )
throw css::lang::IllegalArgumentException(u"no parent window given to SwNavigationPI::Create"_ustr, nullptr, 0);
if( !rxFrame.is() )
throw css::lang::IllegalArgumentException(u"no XFrame given to SwNavigationPI::Create"_ustr, nullptr, 0);
if( pBindings == nullptr )
throw css::lang::IllegalArgumentException(u"no SfxBindings given to SwNavigationPI::Create"_ustr, nullptr, 0);
return std::make_unique<SwNavigationPI>(pParent, rxFrame, pBindings, nullptr);
}
SwNavigationPI::SwNavigationPI(weld::Widget* pParent,
const css::uno::Reference<css::frame::XFrame>& rxFrame,
SfxBindings* _pBindings, SfxNavigator* pNavigatorDlg)
: PanelLayout(pParent, u"NavigatorPanel"_ustr, u"modules/swriter/ui/navigatorpanel.ui"_ustr)
, m_aDocFullName(SID_DOCFULLNAME, *_pBindings, *this)
, m_aPageStats(FN_STAT_PAGE, *_pBindings, *this)
, m_aNavElement(FN_NAV_ELEMENT, *_pBindings, *this)
, m_xFrame(rxFrame)
, m_xContent1ToolBox(m_xBuilder->weld_toolbar(u"content1"_ustr))
, m_xContent2ToolBox(m_xBuilder->weld_toolbar(u"content2"_ustr))
, m_xContent3ToolBox(m_xBuilder->weld_toolbar(u"content3"_ustr))
, m_xContent4ToolBox(m_xBuilder->weld_toolbar(u"content4"_ustr))
, m_xContent5ToolBox(m_xBuilder->weld_toolbar(u"content5"_ustr))
, m_xContent6ToolBox(m_xBuilder->weld_toolbar(u"content6"_ustr))
, m_xContent2Dispatch(new ToolbarUnoDispatcher(*m_xContent2ToolBox, *m_xBuilder, rxFrame))
, m_xContent3Dispatch(new ToolbarUnoDispatcher(*m_xContent3ToolBox, *m_xBuilder, rxFrame))
, m_xHeadingsMenu(m_xBuilder->weld_menu(u"headingsmenu"_ustr))
, m_xUpdateMenu(m_xBuilder->weld_menu(u"updatemenu"_ustr))
, m_xInsertMenu(m_xBuilder->weld_menu(u"insertmenu"_ustr))
, m_xGlobalToolBox(m_xBuilder->weld_toolbar(u"global"_ustr))
, m_xGotoPageSpinButton(m_xBuilder->weld_spin_button(u"gotopage"_ustr))
, m_xContentBox(m_xBuilder->weld_widget(u"contentbox"_ustr))
, m_xContentTree(new SwContentTree(m_xBuilder->weld_tree_view(u"contenttree"_ustr), this))
, m_xGlobalBox(m_xBuilder->weld_widget(u"globalbox"_ustr))
, m_xGlobalTree(new SwGlobalTree(m_xBuilder->weld_tree_view(u"globaltree"_ustr), this))
, m_xDocListBox(m_xBuilder->weld_combo_box(u"documents"_ustr))
, m_xNavigatorDlg(pNavigatorDlg)
, m_pContentView(nullptr)
, m_pContentWrtShell(nullptr)
, m_pActContView(nullptr)
, m_pCreateView(nullptr)
, m_pConfig(SW_MOD()->GetNavigationConfig())
, m_rBindings(*_pBindings)
, m_bIsZoomedIn(false)
, m_bGlobalMode(false)
{
InitContentFunctionsToolbar();
m_xContainer->connect_container_focus_changed(LINK(this, SwNavigationPI, SetFocusChildHdl));
Reference<XToolbarController> xController =
m_xContent2Dispatch->GetControllerForCommand(u".uno:NavElement"_ustr);
NavElementToolBoxControl* pToolBoxControl =
dynamic_cast<NavElementToolBoxControl*>(xController.get());
// In case of LOK, the xController may not a NavElementToolBoxControl
if (comphelper::LibreOfficeKit::isActive() && !pToolBoxControl)
{
m_pNavigateByComboBox = nullptr;
}
else
{
assert(pToolBoxControl);
m_pNavigateByComboBox = pToolBoxControl->GetComboBox();
SetContent3And4ToolBoxVisibility();
}
// Restore content tree settings before calling UpdateInitShow. UpdateInitShow calls Fillbox,
// which calls Display and UpdateTracking. Incorrect outline levels could be displayed and
// unexpected content tracking could occur if these content tree settings are not done before.
m_xContentTree->SetOutlineLevel(static_cast<sal_uInt8>(m_pConfig->GetOutlineLevel()));
m_xContentTree->SetOutlineTracking(static_cast<sal_uInt8>(m_pConfig->GetOutlineTracking()));
for (ContentTypeId eCntTypeId : o3tl::enumrange<ContentTypeId>())
{
if (eCntTypeId != ContentTypeId::OUTLINE)
m_xContentTree->SetContentTypeTracking(
eCntTypeId, m_pConfig->IsContentTypeTrack(eCntTypeId));
}
if (const ContentTypeId nRootType = m_pConfig->GetRootType();
nRootType != ContentTypeId::UNKNOWN)
{
m_xContentTree->SetRootType(nRootType);
m_xContent5ToolBox->set_item_active(u"root"_ustr, true);
if (nRootType == ContentTypeId::OUTLINE || nRootType == ContentTypeId::DRAWOBJECT)
m_xContentTree->set_selection_mode(SelectionMode::Multiple);
else
m_xContentTree->set_selection_mode(SelectionMode::Single);
}
else
m_xContentTree->set_selection_mode(SelectionMode::Single);
UpdateInitShow();
GetCreateView();
m_xContent1ToolBox->set_help_id(HID_NAVIGATOR_TOOLBOX);
m_xContent2ToolBox->set_help_id(HID_NAVIGATOR_TOOLBOX);
m_xContent3ToolBox->set_help_id(HID_NAVIGATOR_TOOLBOX);
m_xContent4ToolBox->set_help_id(HID_NAVIGATOR_TOOLBOX);
m_xContent5ToolBox->set_help_id(HID_NAVIGATOR_TOOLBOX);
m_xContent6ToolBox->set_help_id(HID_NAVIGATOR_TOOLBOX);
m_xGlobalToolBox->set_help_id(HID_NAVIGATOR_GLOBAL_TOOLBOX);
m_xDocListBox->set_help_id(HID_NAVIGATOR_LISTBOX);
m_xDocListBox->set_size_request(42, -1); // set a nominal width so it takes width of surroundings
bool bFloatingNavigator = ParentIsFloatingWindow(m_xNavigatorDlg);
m_xContentTree->ShowTree();
m_xContent6ToolBox->set_item_active(u"listbox"_ustr, true);
m_xContent6ToolBox->set_item_sensitive(u"listbox"_ustr, bFloatingNavigator);
// TreeListBox for global document
m_xGlobalTree->set_selection_mode(SelectionMode::Multiple);
// Handler
Link<const OUString&, void> aLk = LINK(this, SwNavigationPI, ToolBoxSelectHdl);
m_xContent1ToolBox->connect_clicked(aLk);
m_xContent5ToolBox->connect_clicked(aLk);
m_xContent6ToolBox->connect_clicked(aLk);
m_xGlobalToolBox->connect_clicked(aLk);
m_xDocListBox->connect_changed(LINK(this, SwNavigationPI, DocListBoxSelectHdl));
m_xContent5ToolBox->set_item_menu(u"headings"_ustr, m_xHeadingsMenu.get());
m_xHeadingsMenu->connect_activate(LINK(this, SwNavigationPI, HeadingsMenuSelectHdl));
m_xContent5ToolBox->connect_menu_toggled(LINK(this, SwNavigationPI, ToolBox5DropdownClickHdl));
m_xGlobalToolBox->set_item_menu(u"update"_ustr, m_xUpdateMenu.get());
m_xUpdateMenu->connect_activate(LINK(this, SwNavigationPI, GlobalMenuSelectHdl));
m_xGlobalToolBox->set_item_menu(u"insert"_ustr, m_xInsertMenu.get());
m_xInsertMenu->connect_activate(LINK(this, SwNavigationPI, GlobalMenuSelectHdl));
m_xGlobalToolBox->connect_menu_toggled(LINK(this, SwNavigationPI, ToolBoxClickHdl));
m_xGlobalToolBox->set_item_active(u"globaltoggle"_ustr, true);
if (m_pNavigateByComboBox)
m_pNavigateByComboBox->connect_changed(
LINK(this, SwNavigationPI, NavigateByComboBoxSelectHdl));
m_xGotoPageSpinButton->connect_value_changed(
LINK(this, SwNavigationPI, GotoPageSpinButtonValueChangedHdl));
StartListening(*SfxGetpApp());
if(IsGlobalDoc())
{
SwView *pActView = GetCreateView();
if (pActView && pActView->GetWrtShellPtr())
m_xGlobalToolBox->set_item_active(u"save"_ustr,
pActView->GetWrtShellPtr()->IsGlblDocSaveLinks());
if (m_pConfig->IsGlobalActive())
ToggleTree();
else
m_xContent1ToolBox->set_visible(true);
if (bFloatingNavigator)
m_xGlobalTree->grab_focus();
}
else if (bFloatingNavigator)
m_xContentTree->grab_focus();
m_xContentTree->set_accessible_name(SwResId(STR_ACCESS_TL_CONTENT));
m_xGlobalTree->set_accessible_name(SwResId(STR_ACCESS_TL_GLOBAL));
m_xDocListBox->set_accessible_name(SwResId(STR_ACTIVE_VIEW));
m_aExpandedSize = m_xContainer->get_preferred_size();
if(comphelper::LibreOfficeKit::isActive())
{
m_xBuilder->weld_container(u"gridcontent16"_ustr)->hide();
m_xDocListBox->hide();
m_xGlobalBox->hide();
m_xGlobalToolBox->hide();
m_xGlobalTree->HideTree();
//Open Headings by default
SwView *pView = GetCreateView();
if (pView && pView->m_nNaviExpandedStatus < 0)
{
pView->m_nNaviExpandedStatus = 1;
m_xContentTree->ExpandAllHeadings();
}
}
}
void SwNavigationPI::InitContentFunctionsToolbar()
{
m_xHeadingsContentFunctionsToolbar
= m_xBuilder->weld_toolbar("HeadingsContentFunctionButtonsToolbar");
m_xDeleteFunctionToolbar = m_xBuilder->weld_toolbar("DeleteFunctionButtonToolbar");
const OUString sContentTypes[]
= { "Headings", "Tables", "Frames", "Images", "OLEobjects",
"Bookmarks", "Sections", "Hyperlinks", "References", "Indexes",
"Comments", "Drawingobjects", "Fields", "Footnotes", "Endnotes" };
for (ContentTypeId eContentTypeId : o3tl::enumrange<ContentTypeId>())
{
if (eContentTypeId == ContentTypeId::OUTLINE)
continue;
m_aContentTypeUnoToolbarMap[eContentTypeId] = m_xBuilder->weld_toolbar(
sContentTypes[static_cast<int>(eContentTypeId)] + "ContentTypeUnoToolbar");
m_aContentTypeToolbarUnoDispatcherMap[eContentTypeId]
= std::make_unique<ToolbarUnoDispatcher>(*m_aContentTypeUnoToolbarMap[eContentTypeId],
*m_xBuilder, m_xFrame);
m_aContentUnoToolbarMap[eContentTypeId] = m_xBuilder->weld_toolbar(
sContentTypes[static_cast<int>(eContentTypeId)] + "ContentUnoToolbar");
m_aContentToolbarUnoDispatcherMap[eContentTypeId] = std::make_unique<ToolbarUnoDispatcher>(
*m_aContentUnoToolbarMap[eContentTypeId], *m_xBuilder, m_xFrame);
}
Link<const OUString&, void> aLink
= LINK(this,SwNavigationPI, ContentFunctionsToolbarSelectHdl);
m_xHeadingsContentFunctionsToolbar->connect_clicked(aLink);
m_xDeleteFunctionToolbar->connect_clicked(aLink);
}
namespace
{
bool lcl_ToolbarHasItemWithIdent(weld::Toolbar& rToolbar, std::u16string_view rIdent)
{
for (auto i = 0; i < rToolbar.get_n_items(); i++)
{
if (rToolbar.get_item_ident(i) == rIdent)
return true;
}
return false;
}
}
void SwNavigationPI::UpdateContentFunctionsToolbar()
{
m_xHeadingsContentFunctionsToolbar->hide();
for (ContentTypeId eContentTypeId : o3tl::enumrange<ContentTypeId>())
{
if (eContentTypeId == ContentTypeId::OUTLINE)
continue;
m_aContentTypeUnoToolbarMap[eContentTypeId]->hide();
m_aContentUnoToolbarMap[eContentTypeId]->hide();
}
m_xDeleteFunctionToolbar->hide();
weld::TreeView& rTreeView = m_xContentTree->get_widget();
if (IsZoomedIn() || !rTreeView.is_visible())
return;
std::unique_ptr<weld::TreeIter> xEntry(rTreeView.make_iterator());
if (!rTreeView.get_selected(xEntry.get()))
return;
bool bUseDeleteFunctionsToolbar = true;
ContentTypeId eContentTypeId = ContentTypeId::UNKNOWN;
const bool bContentType
= weld::fromId<const SwTypeNumber*>(rTreeView.get_id(*xEntry))->GetTypeId() == 1;
if (bContentType)
{
const SwContentType* pContentType = weld::fromId<SwContentType*>(rTreeView.get_id(*xEntry));
eContentTypeId = pContentType->GetType();
if (eContentTypeId == ContentTypeId::OUTLINE)
return;
weld::Toolbar& rContentTypeToolbar = *m_aContentTypeUnoToolbarMap[eContentTypeId];
if (rContentTypeToolbar.get_n_items())
{
if (eContentTypeId == ContentTypeId::POSTIT)
{
// prefer .uno:DeleteAllNotes over delete functions toolbar
bUseDeleteFunctionsToolbar
= !lcl_ToolbarHasItemWithIdent(rContentTypeToolbar, u".uno:DeleteAllNotes");
}
rContentTypeToolbar.show();
}
}
else
{
const SwContentType* pContentType
= weld::fromId<SwContent*>(rTreeView.get_id(*xEntry))->GetParent();
eContentTypeId = pContentType->GetType();
if (eContentTypeId == ContentTypeId::OUTLINE)
{
// todo: make buttons sensitive to movability (think position and protection)
m_xHeadingsContentFunctionsToolbar->show();
}
else if (m_xContentTree->IsSelectedEntryCurrentDocCursorPosition(*xEntry))
{
weld::Toolbar& rContentTypeToolbar = *m_aContentUnoToolbarMap[eContentTypeId];
if (rContentTypeToolbar.get_n_items())
{
if (eContentTypeId == ContentTypeId::TABLE)
{
// prefer .uno:DeleteTable over delete functions toolbar
bUseDeleteFunctionsToolbar
= !lcl_ToolbarHasItemWithIdent(rContentTypeToolbar, u".uno:DeleteTable");
}
else if (eContentTypeId == ContentTypeId::INDEX)
{
// prefer .uno:RemoveTableOf over delete functions toolbar
bUseDeleteFunctionsToolbar
= !lcl_ToolbarHasItemWithIdent(rContentTypeToolbar, u".uno:RemoveTableOf");
}
rContentTypeToolbar.show();
}
}
}
if (bUseDeleteFunctionsToolbar && m_xContentTree->IsDeletable(*xEntry))
{
OUString sToolTip;
switch (eContentTypeId)
{
case ContentTypeId::OUTLINE:
sToolTip = SwResId(STR_DELETE_OUTLINE);
break;
case ContentTypeId::TABLE:
sToolTip = SwResId(bContentType ? STR_DELETE_ALL_TABLES : STR_DELETE_TABLE);
break;
case ContentTypeId::FRAME:
sToolTip = SwResId(bContentType ? STR_DELETE_ALL_FRAMES : STR_DELETE_FRAME);
break;
case ContentTypeId::GRAPHIC:
sToolTip = SwResId(bContentType ? STR_DELETE_ALL_GRAPHIC : STR_DELETE_GRAPHIC);
break;
case ContentTypeId::OLE:
sToolTip = SwResId(bContentType ? STR_DELETE_ALL_OLE_OBJECTS : STR_DELETE_OLE_OBJECT);
break;
case ContentTypeId::BOOKMARK:
sToolTip = SwResId(bContentType ? STR_DELETE_ALL_BOOKMARKS : STR_DELETE_BOOKMARK);
break;
case ContentTypeId::REGION:
sToolTip = SwResId(bContentType ? STR_DELETE_ALL_REGIONS : STR_DELETE_REGION);
break;
case ContentTypeId::URLFIELD:
sToolTip = SwResId(bContentType ? STR_DELETE_ALL_URLFIELDS : STR_DELETE_URLFIELD);
break;
case ContentTypeId::REFERENCE:
sToolTip = SwResId(bContentType ? STR_DELETE_ALL_REFERENCES : STR_DELETE_REFERENCE);
break;
case ContentTypeId::INDEX:
sToolTip = SwResId(bContentType ? STR_DELETE_ALL_INDEXES : STR_DELETE_INDEX);
break;
case ContentTypeId::POSTIT:
sToolTip = SwResId(bContentType ? STR_DELETE_ALL_POSTITS : STR_DELETE_POSTIT);
break;
case ContentTypeId::DRAWOBJECT:
sToolTip = SwResId(bContentType ? STR_DELETE_ALL_DRAWOBJECTS : STR_DELETE_DRAWOBJECT);
break;
case ContentTypeId::TEXTFIELD:
sToolTip = SwResId(bContentType ? STR_DELETE_ALL_TEXTFIELDS : STR_DELETE_TEXTFIELD);
break;
case ContentTypeId::FOOTNOTE:
sToolTip = SwResId(bContentType ? STR_DELETE_ALL_FOOTNOTES : STR_DELETE_FOOTNOTE);
break;
case ContentTypeId::ENDNOTE:
sToolTip = SwResId(bContentType ? STR_DELETE_ALL_ENDNOTES : STR_DELETE_ENDNOTE);
break;
default:
break;
}
if (!sToolTip.isEmpty())
{
m_xDeleteFunctionToolbar->set_item_tooltip_text("delete", sToolTip);
m_xDeleteFunctionToolbar->show();
}
}
}
IMPL_LINK(SwNavigationPI, ContentFunctionsToolbarSelectHdl, const OUString&, rCommand, void)
{
weld::TreeView& rTreeView = m_xContentTree->get_widget();
std::unique_ptr<weld::TreeIter> xEntry(rTreeView.make_iterator());
if (!rTreeView.get_selected(xEntry.get()))
return;
const bool bContentEntry
= weld::fromId<const SwTypeNumber*>(rTreeView.get_id(*xEntry))->GetTypeId() == 0;
if (bContentEntry)
{
SwContent* pContent = weld::fromId<SwContent*>(rTreeView.get_id(*xEntry));
if (pContent)
m_xContentTree->GotoContent(pContent);
}
if (rCommand == "chapterdown" || rCommand == "chapterup" || rCommand == "promote"
|| rCommand == "demote")
{
// Get MouseModifier for Outline-Move
// Standard: sublevels are taken
// do not take sublevels with Ctrl
bool bOutlineWithChildren = (KEY_MOD1 != m_xContent6ToolBox->get_modifier_state());
m_xContentTree->ExecCommand(rCommand, bOutlineWithChildren);
}
else if (rCommand == "delete")
{
if (!bContentEntry)
{
m_xContentTree->DeleteAllContentOfEntryContentType(*xEntry);
}
else
{
m_xContentTree->EditEntry(*xEntry, EditEntryMode::DELETE);
}
}
}
weld::Window* SwNavigationPI::GetFrameWeld() const
{
if (m_xNavigatorDlg)
return m_xNavigatorDlg->GetFrameWeld();
return PanelLayout::GetFrameWeld();
}
IMPL_LINK_NOARG(SwNavigationPI, GotoPageSpinButtonValueChangedHdl, weld::SpinButton&, void)
{
auto nPage = m_xGotoPageSpinButton->get_value();
SwView *pView = GetCreateView();
SwWrtShell &rSh = pView->GetWrtShell();
auto nPageCount = rSh.GetPageCount();
if (nPage > nPageCount)
{
nPage = nPageCount;
m_xGotoPageSpinButton->set_text(OUString::number(nPage));
}
rSh.LockView(true);
rSh.GotoPage(nPage, false);
// adjust the visible area so that the top of the page is at the top of the view
const Point aPt(pView->GetVisArea().Left(), rSh.GetPagePos(nPage).Y());
pView->SetVisArea(aPt);
rSh.LockView(false);
}
SwNavigationPI::~SwNavigationPI()
{
if (IsGlobalDoc() && !IsGlobalMode())
{
SwView *pView = GetCreateView();
SwWrtShell &rSh = pView->GetWrtShell();
if (!rSh.IsAllProtect())
pView->GetDocShell()->SetReadOnlyUI(false);
}
EndListening(*SfxGetpApp());
if (m_oObjectShell)
{
if (m_oObjectShell->Is())
(*m_oObjectShell)->DoClose();
m_oObjectShell.reset();
}
m_xDocListBox.reset();
m_xGlobalTree.reset();
m_xGlobalBox.reset();
m_xContentTree.reset();
m_xContentBox.reset();
m_xGlobalToolBox.reset();
m_xGotoPageSpinButton.reset();
m_xHeadingsMenu.reset();
m_xUpdateMenu.reset();
m_xInsertMenu.reset();
m_xContent2Dispatch.reset();
m_xContent3Dispatch.reset();
m_xContent1ToolBox.reset();
m_xContent2ToolBox.reset();
m_xContent3ToolBox.reset();
m_xContent4ToolBox.reset();
m_xContent5ToolBox.reset();
m_xContent6ToolBox.reset();
m_aDocFullName.dispose();
m_aPageStats.dispose();
m_aNavElement.dispose();
}
void SwNavigationPI::NotifyItemUpdate(sal_uInt16 nSID, SfxItemState /*eState*/,
const SfxPoolItem* /*pState*/)
{
switch (nSID)
{
case SID_DOCFULLNAME:
{
SwView *pActView = GetCreateView();
if(pActView)
{
SwWrtShell* pWrtShell = pActView->GetWrtShellPtr();
m_xContentTree->SetActiveShell(pWrtShell);
if (IsGlobalDoc())
{
m_xGlobalToolBox->set_item_active(u"save"_ustr, pWrtShell->IsGlblDocSaveLinks());
}
}
else
{
m_xContentTree->SetActiveShell(nullptr);
}
UpdateListBox();
}
break;
case FN_NAV_ELEMENT:
SetContent3And4ToolBoxVisibility();
[[fallthrough]];
case FN_STAT_PAGE:
{
if (SwView::GetMoveType() == NID_PGE)
{
SwView *pView = GetCreateView();
if (pView)
{
SwWrtShell& rSh = pView->GetWrtShell();
// GetPageNum - return current page number:
// true: in which cursor is located.
// false: which is visible at the upper margin.
sal_uInt16 nPhyNum, nVirtNum;
rSh.GetPageNum(nPhyNum, nVirtNum, false);
m_xGotoPageSpinButton->set_text(OUString::number(nPhyNum));
}
}
}
}
}
void SwNavigationPI::UpdateInitShow()
{
// if the parent isn't a float, then the navigator is displayed in
// the sidebar or is otherwise docked. While the navigator could change
// its size, the sidebar can not, and the navigator would just waste
// space. Therefore disable this button.
bool bParentIsFloatingWindow(ParentIsFloatingWindow(m_xNavigatorDlg));
m_xContent6ToolBox->set_item_sensitive(u"listbox"_ustr, bParentIsFloatingWindow);
// show content if docked
if (!bParentIsFloatingWindow && IsZoomedIn())
ZoomOut();
if (!IsZoomedIn())
FillBox();
}
IMPL_LINK_NOARG(SwNavigationPI, SetFocusChildHdl, weld::Container&, void)
{
// update documents listbox
UpdateListBox();
}
// Notification on modified DocInfo
void SwNavigationPI::Notify( SfxBroadcaster& rBrdc, const SfxHint& rHint )
{
if(&rBrdc == m_pCreateView)
{
if (rHint.GetId() == SfxHintId::Dying)
{
EndListening(*m_pCreateView);
m_pCreateView = nullptr;
m_xContentTree->SetActiveShell(nullptr);
}
}
else
{
if (rHint.GetId() == SfxHintId::ThisIsAnSfxEventHint)
{
SfxEventHintId eEventId = static_cast<const SfxEventHint&>(rHint).GetEventId();
if (eEventId == SfxEventHintId::OpenDoc)
{
SwView *pActView = GetCreateView();
if(pActView)
{
SwWrtShell* pWrtShell = pActView->GetWrtShellPtr();
m_xContentTree->SetActiveShell(pWrtShell);
if (m_xGlobalTree->get_visible())
{
bool bUpdateAll = m_xGlobalTree->Update(false);
// If no update is needed, then update the font colors
// at the entries of broken links.
m_xGlobalTree->Display(!bUpdateAll);
}
}
}
}
}
}
IMPL_LINK( SwNavigationPI, HeadingsMenuSelectHdl, const OUString&, rMenuId, void )
{
if (!rMenuId.isEmpty())
m_xContentTree->SetOutlineLevel(rMenuId.toUInt32());
}
void SwNavigationPI::UpdateListBox()
{
if (!m_xDocListBox) // disposed
return;
m_xDocListBox->freeze();
m_xDocListBox->clear();
SwView *pActView = GetCreateView();
bool bDisable = pActView == nullptr;
SwView *pView = SwModule::GetFirstView();
sal_Int32 nCount = 0;
sal_Int32 nAct = 0;
sal_Int32 nConstPos = 0;
const SwView* pConstView = m_xContentTree->IsConstantView() &&
m_xContentTree->GetActiveWrtShell() ?
&m_xContentTree->GetActiveWrtShell()->GetView():
nullptr;
while (pView)
{
SfxObjectShell* pDoc = pView->GetDocShell();
// #i53333# don't show help pages here
if ( !pDoc->IsHelpDocument() )
{
OUString sEntry = pDoc->GetTitle() + " (";
if (pView == pActView)
{
nAct = nCount;
sEntry += SwResId(STR_ACTIVE);
}
else
sEntry += SwResId(STR_INACTIVE);
sEntry += ")";
m_xDocListBox->append_text(sEntry);
if (pConstView && pView == pConstView)
nConstPos = nCount;
nCount++;
}
pView = SwModule::GetNextView(pView);
}
m_xDocListBox->append_text(SwResId(STR_ACTIVE_VIEW)); // "Active Window"
nCount++;
if (SwWrtShell* pHiddenWrtShell = m_xContentTree->GetHiddenWrtShell())
{
OUString sEntry = pHiddenWrtShell->GetView().GetDocShell()->GetTitle() +
" (" + SwResId(STR_HIDDEN) + ")";
m_xDocListBox->append_text(sEntry);
bDisable = false;
}
m_xDocListBox->thaw();
if(m_xContentTree->IsActiveView())
{
//Either the name of the current Document or "Active Document".
m_xDocListBox->set_active(pActView ? nAct : --nCount);
}
else if(m_xContentTree->IsHiddenView())
{
m_xDocListBox->set_active(nCount);
}
else
m_xDocListBox->set_active(nConstPos);
m_xDocListBox->set_sensitive(!bDisable);
}
IMPL_LINK(SwNavigationPI, DoneLink, SfxPoolItem const *, pItem, void)
{
const SfxViewFrameItem* pFrameItem = dynamic_cast<SfxViewFrameItem const *>( pItem );
if( !pFrameItem )
return;
SfxViewFrame* pFrame = pFrameItem->GetFrame();
if(pFrame)
{
m_xContentTree->clear();
m_pContentView = dynamic_cast<SwView*>( pFrame->GetViewShell() );
OSL_ENSURE(m_pContentView, "no SwView");
if(m_pContentView)
m_pContentWrtShell = m_pContentView->GetWrtShellPtr();
else
m_pContentWrtShell = nullptr;
m_oObjectShell.emplace( pFrame->GetObjectShell() );
FillBox();
}
}
OUString SwNavigationPI::CreateDropFileName( const TransferableDataHelper& rData )
{
OUString sFileName;
SotClipboardFormatId nFormat;
if( rData.HasFormat( nFormat = SotClipboardFormatId::FILE_LIST ))
{
FileList aFileList;
rData.GetFileList( nFormat, aFileList );
sFileName = aFileList.GetFile( 0 );
}
else if( rData.HasFormat( nFormat = SotClipboardFormatId::STRING ) ||
rData.HasFormat( nFormat = SotClipboardFormatId::SIMPLE_FILE ) ||
rData.HasFormat( nFormat = SotClipboardFormatId::FILENAME ))
{
(void)rData.GetString(nFormat, sFileName);
}
else if( rData.HasFormat( nFormat = SotClipboardFormatId::SOLK ) ||
rData.HasFormat( nFormat = SotClipboardFormatId::NETSCAPE_BOOKMARK )||
rData.HasFormat( nFormat = SotClipboardFormatId::FILECONTENT ) ||
rData.HasFormat( nFormat = SotClipboardFormatId::FILEGRPDESCRIPTOR ) ||
rData.HasFormat( nFormat = SotClipboardFormatId::UNIFORMRESOURCELOCATOR ))
{
INetBookmark aBkmk { OUString(), OUString() };
if (rData.GetINetBookmark(nFormat, aBkmk))
sFileName = aBkmk.GetURL();
}
if( !sFileName.isEmpty() )
{
sFileName = INetURLObject( sFileName ).GetMainURL( INetURLObject::DecodeMechanism::NONE );
}
return sFileName;
}
sal_Int8 SwNavigationPI::AcceptDrop()
{
return ( !m_xContentTree->IsInDrag() &&
( m_xContentTree->IsDropFormatSupported( SotClipboardFormatId::SIMPLE_FILE ) ||
m_xContentTree->IsDropFormatSupported( SotClipboardFormatId::STRING ) ||
m_xContentTree->IsDropFormatSupported( SotClipboardFormatId::SOLK ) ||
m_xContentTree->IsDropFormatSupported( SotClipboardFormatId::NETSCAPE_BOOKMARK )||
m_xContentTree->IsDropFormatSupported( SotClipboardFormatId::FILECONTENT ) ||
m_xContentTree->IsDropFormatSupported( SotClipboardFormatId::FILEGRPDESCRIPTOR ) ||
m_xContentTree->IsDropFormatSupported( SotClipboardFormatId::UNIFORMRESOURCELOCATOR ) ||
m_xContentTree->IsDropFormatSupported( SotClipboardFormatId::FILENAME )))
? DND_ACTION_COPY
: DND_ACTION_NONE;
}
sal_Int8 SwNavigationPI::ExecuteDrop( const ExecuteDropEvent& rEvt )
{
TransferableDataHelper aData( rEvt.maDropEvent.Transferable );
sal_Int8 nRet = DND_ACTION_NONE;
if (m_xContentTree->IsInDrag())
return nRet;
OUString sFileName = SwNavigationPI::CreateDropFileName(aData);
if (sFileName.isEmpty())
return nRet;
INetURLObject aTemp(sFileName);
GraphicDescriptor aDesc(aTemp);
if (aDesc.Detect()) // accept no graphics
return nRet;
if (-1 != sFileName.indexOf('#'))
return nRet;
if (m_sContentFileName.isEmpty() || m_sContentFileName != sFileName)
{
nRet = rEvt.mnAction;
sFileName = comphelper::string::stripEnd(sFileName, 0);
m_sContentFileName = sFileName;
if(m_oObjectShell)
{
m_xContentTree->SetHiddenShell( nullptr );
(*m_oObjectShell)->DoClose();
m_oObjectShell.reset();
}
SfxStringItem aFileItem(SID_FILE_NAME, sFileName );
SfxStringItem aOptionsItem( SID_OPTIONS, u"HRC"_ustr );
SfxLinkItem aLink( SID_DONELINK,
LINK( this, SwNavigationPI, DoneLink ) );
if (SwView* pView = GetActiveView())
pView->GetViewFrame().GetDispatcher()->ExecuteList(
SID_OPENDOC, SfxCallMode::ASYNCHRON,
{ &aFileItem, &aOptionsItem, &aLink });
}
return nRet;
}
// toggle between showing the global tree or the content tree
void SwNavigationPI::ToggleTree()
{
if (comphelper::LibreOfficeKit::isActive())
{
m_xGlobalTree->HideTree();
return;
}
bool bGlobalDoc = IsGlobalDoc();
if (!IsGlobalMode() && bGlobalDoc)
{
// toggle to global mode
if (IsZoomedIn())
ZoomOut();
m_xGlobalBox->show();
m_xGlobalTree->ShowTree();
m_xGlobalToolBox->show();
m_xContentBox->hide();
m_xContentTree->HideTree();
m_xContent1ToolBox->hide();
m_xContent2ToolBox->hide();
m_xContent3ToolBox->hide();
m_xContent4ToolBox->hide();
m_xContent5ToolBox->hide();
m_xContent6ToolBox->hide();
m_xDocListBox->hide();
SetGlobalMode(true);
}
else
{
m_xGlobalBox->hide();
m_xGlobalTree->HideTree();
m_xGlobalToolBox->hide();
SetGlobalMode(false);
if (!IsZoomedIn())
{
m_xContentBox->show();
m_xContentTree->ShowTree();
m_xContent1ToolBox->show();
m_xContent2ToolBox->show();
SetContent3And4ToolBoxVisibility();
m_xContent5ToolBox->show();
m_xContent6ToolBox->show();
m_xDocListBox->show();
}
}
}
bool SwNavigationPI::IsGlobalDoc() const
{
bool bRet = false;
SwView *pView = GetCreateView();
if (pView)
{
SwWrtShell &rSh = pView->GetWrtShell();
bRet = rSh.IsGlobalDoc();
}
return bRet;
}
void SwNavigationPI::SelectNavigateByContentType(const OUString& rContentTypeName)
{
if (!m_pNavigateByComboBox)
return;
if (auto nPos = m_pNavigateByComboBox->find_text(rContentTypeName); nPos != -1)
{
m_pNavigateByComboBox->set_active(nPos);
UpdateNavigateBy();
}
}
SwView* SwNavigationPI::GetCreateView() const
{
if (!m_pCreateView)
{
SwView* pView = SwModule::GetFirstView();
while (pView)
{
if(&pView->GetViewFrame().GetBindings() == &m_rBindings)
{
const_cast<SwNavigationPI*>(this)->m_pCreateView = pView;
const_cast<SwNavigationPI*>(this)->StartListening(*m_pCreateView);
break;
}
pView = SwModule::GetNextView(pView);
}
}
return m_pCreateView;
}
class SwNavigatorWin : public SfxNavigator
{
private:
std::unique_ptr<SwNavigationPI> m_xNavi;
public:
SwNavigatorWin(SfxBindings* _pBindings, SfxChildWindow* _pMgr,
vcl::Window* pParent, SfxChildWinInfo* pInfo);
virtual void StateChanged(StateChangedType nStateChange) override;
virtual void dispose() override
{
m_xNavi.reset();
SfxNavigator::dispose();
}
virtual ~SwNavigatorWin() override
{
disposeOnce();
}
};
SwNavigatorWin::SwNavigatorWin(SfxBindings* _pBindings, SfxChildWindow* _pMgr,
vcl::Window* pParent, SfxChildWinInfo* pInfo)
: SfxNavigator(_pBindings, _pMgr, pParent, pInfo)
, m_xNavi(std::make_unique<SwNavigationPI>(m_xContainer.get(), _pBindings->GetActiveFrame(), _pBindings, this))
{
_pBindings->Invalidate(SID_NAVIGATOR);
SwNavigationConfig* pNaviConfig = SW_MOD()->GetNavigationConfig();
SetMinOutputSizePixel(GetOptimalSize());
if (pNaviConfig->IsSmall())
m_xNavi->ZoomIn();
}
void SwNavigatorWin::StateChanged(StateChangedType nStateChange)
{
SfxNavigator::StateChanged(nStateChange);
if (nStateChange == StateChangedType::InitShow)
m_xNavi->UpdateInitShow();
}
SFX_IMPL_DOCKINGWINDOW(SwNavigatorWrapper, SID_NAVIGATOR);
SwNavigatorWrapper::SwNavigatorWrapper(vcl::Window *_pParent, sal_uInt16 nId,
SfxBindings* pBindings, SfxChildWinInfo* pInfo)
: SfxNavigatorWrapper(_pParent, nId)
{
SetWindow(VclPtr<SwNavigatorWin>::Create(pBindings, this, _pParent, pInfo));
Initialize();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V522 Dereferencing of the null pointer 'm_pCreateView' might take place.
↑ V1053 Calling the 'GetOptimalSize' virtual function in the constructor may lead to unexpected result at runtime.
↑ V522 There might be dereferencing of a potential null pointer 'pToolBoxControl'.