1309 lines
45 KiB
C++
1309 lines
45 KiB
C++
/* -*- 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(SwModule::get()->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();
|
|
if (rSh.GetViewOptions()->IsMultipageView())
|
|
// maybe set the spin button text to the page that has the cursor?
|
|
break;
|
|
SwVisiblePageNumbers aVisiblePageNumbers;
|
|
rSh.GetFirstLastVisPageNumbers(aVisiblePageNumbers, *pView);
|
|
m_xGotoPageSpinButton->set_text(OUString::number(aVisiblePageNumbers.nFirstPhy));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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 = SwModule::get()->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: */
|