1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <comphelper/string.hxx>
21 #include <svl/urlbmk.hxx>
22 #include <svl/stritem.hxx>
23 #include <vcl/graphicfilter.hxx>
24 #include <sot/formats.hxx>
25 #include <sot/filelist.hxx>
26 #include <sfx2/event.hxx>
27 #include <sfx2/dispatch.hxx>
28 #include <sfx2/viewfrm.hxx>
29 #include <tools/urlobj.hxx>
30 #include <osl/diagnose.h>
31 #include <swtypes.hxx>
32 #include <swmodule.hxx>
34 #include <navicfg.hxx>
39 #include <sfx2/app.hxx>
43 #include <strings.hrc>
44 #include <bitmaps.hlst>
48 #include <o3tl/enumrange.hxx>
50 #include <workctrl.hxx>
52 #include <comphelper/lok.hxx>
54 using namespace ::com::sun::star::uno
;
55 using namespace ::com::sun::star::frame
;
57 // Filter the control characters out of the Outline-Entry
58 OUString
SwNavigationPI::CleanEntry(const OUString
& rEntry
)
63 OUStringBuffer
aEntry(rEntry
);
64 for (sal_Int32 i
= 0; i
< rEntry
.getLength(); ++i
)
65 if(aEntry
[i
] == 10 || aEntry
[i
] == 9)
68 return aEntry
.makeStringAndClear();
71 // Execution of the drag operation with and without the children.
73 void SwNavigationPI::MoveOutline(SwOutlineNodes::size_type nSource
, SwOutlineNodes::size_type nTarget
)
75 SwView
*pView
= GetCreateView();
76 SwWrtShell
&rSh
= pView
->GetWrtShell();
77 if(nTarget
< nSource
|| nTarget
== SwOutlineNodes::npos
)
79 if ( !rSh
.IsOutlineMovable( nSource
))
82 SwOutlineNodes::difference_type nMove
= nTarget
-nSource
; //( nDir<0 ) ? 1 : 0 ;
83 rSh
.GotoOutline(nSource
);
84 rSh
.MakeOutlineSel(nSource
, nSource
, true);
85 // While moving, the selected children does not counting.
86 const SwOutlineNodes::size_type nLastOutlinePos
= rSh
.GetOutlinePos(MAXLEVEL
);
87 if(nMove
> 1 && nLastOutlinePos
< nTarget
)
89 if(!rSh
.IsCursorPtAtEnd())
91 nMove
-= nLastOutlinePos
- nSource
;
93 if( nMove
< 1 || nLastOutlinePos
< nTarget
)
94 rSh
.MoveOutlinePara( nMove
);
96 rSh
.GotoOutline( nSource
+ nMove
);
100 // After goto cancel the status frame selection
101 static void lcl_UnSelectFrame(SwWrtShell
*pSh
)
103 if (pSh
->IsFrameSelected())
105 pSh
->UnSelectFrame();
106 pSh
->LeaveSelFrameMode();
110 // Select the document view
111 IMPL_LINK(SwNavigationPI
, DocListBoxSelectHdl
, weld::ComboBox
&, rBox
, void)
113 int nEntryIdx
= rBox
.get_active();
115 pView
= SwModule::GetFirstView();
116 while (nEntryIdx
-- && pView
)
118 pView
= SwModule::GetNextView(pView
);
123 m_xContentTree
->ShowHiddenShell():
124 m_xContentTree
->ShowActualView();
129 m_xContentTree
->SetConstantShell(pView
->GetWrtShellPtr());
133 void SwNavigationPI::UpdateNavigateBy()
135 SfxUInt32Item
aParam(FN_NAV_ELEMENT
, m_pNavigateByComboBox
->get_active_id().toUInt32());
136 const SfxPoolItem
* aArgs
[2];
139 SfxDispatcher
* pDispatcher
= GetCreateView()->GetFrame()->GetDispatcher();
140 pDispatcher
->Execute(FN_NAV_ELEMENT
, SfxCallMode::SYNCHRON
, aArgs
);
143 IMPL_LINK(SwNavigationPI
, NavigateByComboBoxSelectHdl
, weld::ComboBox
&, rComboBox
, void)
145 m_xContentTree
->SelectContentType(rComboBox
.get_active_text());
149 // Filling of the list box for outline view or documents
150 // The PI will be set to full size
151 void SwNavigationPI::FillBox()
153 if(m_pContentWrtShell
)
155 m_xContentTree
->SetHiddenShell( m_pContentWrtShell
);
156 m_xContentTree
->Display( false );
160 SwView
*pView
= GetCreateView();
163 m_xContentTree
->SetActiveShell(nullptr);
165 else if( pView
!= m_pActContView
)
167 SwWrtShell
* pWrtShell
= pView
->GetWrtShellPtr();
168 m_xContentTree
->SetActiveShell(pWrtShell
);
171 m_xContentTree
->Display( true );
172 m_pActContView
= pView
;
174 m_xContentTree
->UpdateTracking();
178 void SwNavigationPI::UsePage()
180 SwView
*pView
= GetCreateView();
181 SwWrtShell
*pSh
= pView
? &pView
->GetWrtShell() : nullptr;
182 m_xEdit
->set_value(1);
185 const sal_uInt16 nPageCnt
= pSh
->GetPageCnt();
186 sal_uInt16 nPhyPage
, nVirPage
;
187 pSh
->GetPageNum(nPhyPage
, nVirPage
);
189 m_xEdit
->set_max(nPageCnt
);
190 m_xEdit
->set_width_chars(3);
191 m_xEdit
->set_value(nPhyPage
);
195 // Select handler of the toolboxes
196 IMPL_LINK(SwNavigationPI
, ToolBoxSelectHdl
, const OUString
&, rCommand
, void)
198 SwView
*pView
= GetCreateView();
201 SwWrtShell
&rSh
= pView
->GetWrtShell();
202 // Get MouseModifier for Outline-Move
205 bool bFocusToDoc
= false;
206 if (rCommand
== ".uno:ScrollToPrevious" || rCommand
== ".uno:ScrollToNext")
208 bool *pbNext
= new bool(true);
209 if (rCommand
== ".uno:ScrollToPrevious")
211 pView
->MoveNavigationHdl(pbNext
);
213 else if (rCommand
== "root")
215 m_xContentTree
->ToggleToRoot();
217 else if (rCommand
== "listbox")
219 if (ParentIsFloatingWindow(m_xNavigatorDlg
))
232 // Functions that will trigger a direct action.
233 else if (rCommand
== "footer")
236 const FrameTypeFlags eType
= rSh
.GetFrameType(nullptr,false);
237 if (eType
& FrameTypeFlags::FOOTER
)
240 nFuncId
= FN_END_OF_PAGE
;
242 else if (rSh
.GotoFooterText())
243 nFuncId
= FN_TO_FOOTER
;
246 else if (rCommand
== "header")
249 const FrameTypeFlags eType
= rSh
.GetFrameType(nullptr,false);
250 if (eType
& FrameTypeFlags::HEADER
)
253 nFuncId
= FN_START_OF_PAGE
;
255 else if (rSh
.GotoHeaderText())
256 nFuncId
= FN_TO_HEADER
;
259 else if (rCommand
== "anchor")
262 const FrameTypeFlags eFrameType
= rSh
.GetFrameType(nullptr,false);
263 // Jump from the footnote to the anchor.
264 if (eFrameType
& FrameTypeFlags::FOOTNOTE
)
266 if (rSh
.GotoFootnoteAnchor())
267 nFuncId
= FN_FOOTNOTE_TO_ANCHOR
;
269 // Otherwise, jump to the first footnote text;
270 // go to the next footnote if this is not possible;
271 // if this is also not possible got to the footnote before.
274 if (rSh
.GotoFootnoteText())
275 nFuncId
= FN_FOOTNOTE_TO_ANCHOR
;
276 else if (rSh
.GotoNextFootnoteAnchor())
277 nFuncId
= FN_NEXT_FOOTNOTE
;
278 else if (rSh
.GotoPrevFootnoteAnchor())
279 nFuncId
= FN_PREV_FOOTNOTE
;
283 else if (rCommand
== "reminder")
285 rSh
.GetView().GetViewFrame().GetDispatcher()->Execute(FN_SET_REMINDER
, SfxCallMode::ASYNCHRON
);
287 else if (rCommand
== "chapterdown" ||
288 rCommand
== "movedown" ||
289 rCommand
== "chapterup" ||
290 rCommand
== "moveup" ||
291 rCommand
== "promote" ||
292 rCommand
== "demote" ||
296 m_xGlobalTree
->ExecCommand(rCommand
);
299 // Standard: sublevels are taken
300 // do not take sublevels with Ctrl
301 bool bOutlineWithChildren
= (KEY_MOD1
!= m_xContent6ToolBox
->get_modifier_state());
302 m_xContentTree
->ExecCommand(rCommand
, bOutlineWithChildren
);
305 else if (rCommand
== "contenttoggle" || rCommand
== "globaltoggle")
308 bool bGlobalMode
= IsGlobalMode();
309 m_pConfig
->SetGlobalActive(bGlobalMode
);
310 m_xGlobalToolBox
->set_item_active("globaltoggle", bGlobalMode
);
311 m_xContent1ToolBox
->set_item_active("contenttoggle", bGlobalMode
);
313 else if (rCommand
== "save")
315 bool bSave
= rSh
.IsGlblDocSaveLinks();
316 rSh
.SetGlblDocSaveLinks( !bSave
);
317 m_xGlobalToolBox
->set_item_active(rCommand
, !bSave
);
319 else if (rCommand
== "dragmode")
320 m_xContent6ToolBox
->set_menu_item_active("dragmode", !m_xContent6ToolBox
->get_menu_item_active("dragmode"));
321 else if (rCommand
== "headings")
322 m_xContent5ToolBox
->set_menu_item_active("headings", !m_xContent5ToolBox
->get_menu_item_active("headings"));
323 else if (rCommand
== "update")
324 m_xGlobalToolBox
->set_menu_item_active("update", !m_xGlobalToolBox
->get_menu_item_active("update"));
325 else if (rCommand
== "insert")
326 m_xGlobalToolBox
->set_menu_item_active("insert", !m_xGlobalToolBox
->get_menu_item_active("insert"));
329 lcl_UnSelectFrame(&rSh
);
331 pView
->GetEditWin().GrabFocus();
334 // Click handler of the toolboxes
335 IMPL_LINK(SwNavigationPI
, ToolBoxClickHdl
, const OUString
&, rCommand
, void)
337 if (!m_xGlobalToolBox
->get_menu_item_active(rCommand
))
340 if (rCommand
== "update")
341 m_xGlobalTree
->TbxMenuHdl(rCommand
, *m_xUpdateMenu
);
342 else if (rCommand
== "insert")
343 m_xGlobalTree
->TbxMenuHdl(rCommand
, *m_xInsertMenu
);
346 IMPL_LINK(SwNavigationPI
, ToolBox6DropdownClickHdl
, const OUString
&, rCommand
, void)
348 if (!m_xContent6ToolBox
->get_menu_item_active(rCommand
))
351 if (rCommand
!= "dragmode")
354 switch (m_nRegionMode
)
356 case RegionMode::NONE
:
357 m_xDragModeMenu
->set_active("hyperlink", true);
359 case RegionMode::LINK
:
360 m_xDragModeMenu
->set_active("link", true);
362 case RegionMode::EMBEDDED
:
363 m_xDragModeMenu
->set_active("copy", true);
368 IMPL_LINK(SwNavigationPI
, DropModeMenuSelectHdl
, const OUString
&, rIdent
, void)
370 if (rIdent
== "hyperlink")
371 SetRegionDropMode(RegionMode::NONE
);
372 else if (rIdent
== "link")
373 SetRegionDropMode(RegionMode::LINK
);
374 else if (rIdent
== "copy")
375 SetRegionDropMode(RegionMode::EMBEDDED
);
378 IMPL_LINK(SwNavigationPI
, GlobalMenuSelectHdl
, const OUString
&, rIdent
, void)
380 m_xGlobalTree
->ExecuteContextMenuAction(rIdent
);
383 IMPL_LINK(SwNavigationPI
, ToolBox5DropdownClickHdl
, const OUString
&, rCommand
, void)
385 if (!m_xContent5ToolBox
->get_menu_item_active(rCommand
))
388 if (rCommand
== "headings")
389 m_xHeadingsMenu
->set_active(OUString::number(m_xContentTree
->GetOutlineLevel()), true);
392 // Action-Handler Edit:
393 // Switches to the page if the structure view is not turned on.
394 bool SwNavigationPI::EditAction()
396 SwView
*pView
= GetCreateView();
400 if (m_aPageChgIdle
.IsActive())
401 m_aPageChgIdle
.Stop();
403 // if the user has clicked into the document, forget about changing the page
404 if (pView
->GetEditWin().HasFocus())
407 SwWrtShell
&rSh
= m_pCreateView
->GetWrtShell();
408 sal_uInt16 nNewPage
= m_xEdit
->get_value();
410 rSh
.GotoPage(nNewPage
, true);
411 m_pCreateView
->GetViewFrame().GetBindings().Invalidate(FN_STAT_PAGE
);
416 void SwNavigationPI::ZoomOut()
420 SfxNavigator
* pNav
= m_xNavigatorDlg
.get();
423 m_bIsZoomedIn
= false;
427 m_xGlobalBox
->show();
428 m_xGlobalTree
->ShowTree();
432 m_xContentBox
->show();
433 m_xContentTree
->ShowTree();
434 m_xDocListBox
->show();
437 pNav
->InvalidateChildSizeCache();
438 Size
aOptimalSize(pNav
->GetOptimalSize());
439 Size
aNewSize(pNav
->GetOutputSizePixel());
440 aNewSize
.setHeight( m_aExpandedSize
.Height() );
441 pNav
->SetMinOutputSizePixel(aOptimalSize
);
442 pNav
->SetOutputSizePixel(aNewSize
);
444 m_xContentTree
->Select(); // Enable toolbox
445 m_pConfig
->SetSmall(false);
446 m_xContent6ToolBox
->set_item_active("listbox", true);
449 void SwNavigationPI::ZoomIn()
453 SfxNavigator
* pNav
= m_xNavigatorDlg
.get();
457 m_aExpandedSize
= m_xNavigatorDlg
->GetSizePixel();
459 m_xContentBox
->hide();
460 m_xContentTree
->HideTree();
461 m_xGlobalBox
->hide();
462 m_xGlobalTree
->HideTree();
463 m_xDocListBox
->hide();
464 m_bIsZoomedIn
= true;
466 pNav
->InvalidateChildSizeCache();
467 Size
aOptimalSize(pNav
->GetOptimalSize());
468 Size
aNewSize(pNav
->GetOutputSizePixel());
469 aNewSize
.setHeight( aOptimalSize
.Height() );
470 pNav
->SetMinOutputSizePixel(aOptimalSize
);
471 pNav
->SetOutputSizePixel(aNewSize
);
473 m_xContentTree
->Select(); // Enable toolbox
475 m_pConfig
->SetSmall(true);
476 m_xContent6ToolBox
->set_item_active("listbox", false);
490 std::unique_ptr
<PanelLayout
> SwNavigationPI::Create(weld::Widget
* pParent
,
491 const css::uno::Reference
<css::frame::XFrame
>& rxFrame
,
492 SfxBindings
* pBindings
)
494 if( pParent
== nullptr )
495 throw css::lang::IllegalArgumentException("no parent window given to SwNavigationPI::Create", nullptr, 0);
497 throw css::lang::IllegalArgumentException("no XFrame given to SwNavigationPI::Create", nullptr, 0);
498 if( pBindings
== nullptr )
499 throw css::lang::IllegalArgumentException("no SfxBindings given to SwNavigationPI::Create", nullptr, 0);
500 return std::make_unique
<SwNavigationPI
>(pParent
, rxFrame
, pBindings
, nullptr);
503 SwNavigationPI::SwNavigationPI(weld::Widget
* pParent
,
504 const css::uno::Reference
<css::frame::XFrame
>& rxFrame
,
505 SfxBindings
* _pBindings
, SfxNavigator
* pNavigatorDlg
)
506 : PanelLayout(pParent
, "NavigatorPanel", "modules/swriter/ui/navigatorpanel.ui")
507 , m_aDocFullName(SID_DOCFULLNAME
, *_pBindings
, *this)
508 , m_aPageStats(FN_STAT_PAGE
, *_pBindings
, *this)
509 , m_xContent1ToolBox(m_xBuilder
->weld_toolbar("content1"))
510 , m_xContent2ToolBox(m_xBuilder
->weld_toolbar("content2"))
511 , m_xContent3ToolBox(m_xBuilder
->weld_toolbar("content3"))
512 , m_xContent4ToolBox(m_xBuilder
->weld_toolbar("content4"))
513 , m_xContent5ToolBox(m_xBuilder
->weld_toolbar("content5"))
514 , m_xContent6ToolBox(m_xBuilder
->weld_toolbar("content6"))
515 , m_xContent2Dispatch(new ToolbarUnoDispatcher(*m_xContent2ToolBox
, *m_xBuilder
, rxFrame
))
516 , m_xContent3Dispatch(new ToolbarUnoDispatcher(*m_xContent3ToolBox
, *m_xBuilder
, rxFrame
))
517 , m_xHeadingsMenu(m_xBuilder
->weld_menu("headingsmenu"))
518 , m_xDragModeMenu(m_xBuilder
->weld_menu("dragmodemenu"))
519 , m_xUpdateMenu(m_xBuilder
->weld_menu("updatemenu"))
520 , m_xInsertMenu(m_xBuilder
->weld_menu("insertmenu"))
521 , m_xGlobalToolBox(m_xBuilder
->weld_toolbar("global"))
522 , m_xEdit(m_xBuilder
->weld_spin_button("spinbutton"))
523 , m_xContentBox(m_xBuilder
->weld_widget("contentbox"))
524 , m_xContentTree(new SwContentTree(m_xBuilder
->weld_tree_view("contenttree"), this))
525 , m_xGlobalBox(m_xBuilder
->weld_widget("globalbox"))
526 , m_xGlobalTree(new SwGlobalTree(m_xBuilder
->weld_tree_view("globaltree"), this))
527 , m_xDocListBox(m_xBuilder
->weld_combo_box("documents"))
528 , m_aPageChgIdle("SwNavigationPI m_aPageChgIdle")
529 , m_xNavigatorDlg(pNavigatorDlg
)
530 , m_pContentView(nullptr)
531 , m_pContentWrtShell(nullptr)
532 , m_pActContView(nullptr)
533 , m_pCreateView(nullptr)
534 , m_pConfig(SW_MOD()->GetNavigationConfig())
535 , m_rBindings(*_pBindings
)
536 , m_nRegionMode(RegionMode::NONE
)
537 , m_bIsZoomedIn(false)
538 , m_bGlobalMode(false)
540 m_xContainer
->connect_container_focus_changed(LINK(this, SwNavigationPI
, SetFocusChildHdl
));
542 Reference
<XToolbarController
> xController
=
543 m_xContent2Dispatch
->GetControllerForCommand(".uno:NavElement");
544 NavElementToolBoxControl
* pToolBoxControl
=
545 dynamic_cast<NavElementToolBoxControl
*>(xController
.get());
546 assert(pToolBoxControl
);
547 m_pNavigateByComboBox
= pToolBoxControl
->GetComboBox();
549 // Restore content tree settings before calling UpdateInitShow. UpdateInitShow calls Fillbox,
550 // which calls Display and UpdateTracking. Incorrect outline levels could be displayed and
551 // unexpected content tracking could occur if these content tree settings are not done before.
552 m_xContentTree
->SetOutlineLevel(static_cast<sal_uInt8
>(m_pConfig
->GetOutlineLevel()));
553 m_xContentTree
->SetOutlineTracking(static_cast<sal_uInt8
>(m_pConfig
->GetOutlineTracking()));
554 for (ContentTypeId eCntTypeId
: o3tl::enumrange
<ContentTypeId
>())
556 if (eCntTypeId
!= ContentTypeId::OUTLINE
)
557 m_xContentTree
->SetContentTypeTracking(
558 eCntTypeId
, m_pConfig
->IsContentTypeTrack(eCntTypeId
));
561 if (const ContentTypeId nRootType
= m_pConfig
->GetRootType();
562 nRootType
!= ContentTypeId::UNKNOWN
)
564 m_xContentTree
->SetRootType(nRootType
);
565 m_xContent5ToolBox
->set_item_active("root", true);
566 if (nRootType
== ContentTypeId::OUTLINE
|| nRootType
== ContentTypeId::DRAWOBJECT
)
567 m_xContentTree
->set_selection_mode(SelectionMode::Multiple
);
569 m_xContentTree
->set_selection_mode(SelectionMode::Single
);
572 m_xContentTree
->set_selection_mode(SelectionMode::Single
);
578 m_xContent1ToolBox
->set_help_id(HID_NAVIGATOR_TOOLBOX
);
579 m_xContent2ToolBox
->set_help_id(HID_NAVIGATOR_TOOLBOX
);
580 m_xContent3ToolBox
->set_help_id(HID_NAVIGATOR_TOOLBOX
);
581 m_xContent4ToolBox
->set_help_id(HID_NAVIGATOR_TOOLBOX
);
582 m_xContent5ToolBox
->set_help_id(HID_NAVIGATOR_TOOLBOX
);
583 m_xContent6ToolBox
->set_help_id(HID_NAVIGATOR_TOOLBOX
);
584 m_xGlobalToolBox
->set_help_id(HID_NAVIGATOR_GLOBAL_TOOLBOX
);
585 m_xDocListBox
->set_help_id(HID_NAVIGATOR_LISTBOX
);
586 m_xDocListBox
->set_size_request(42, -1); // set a nominal width so it takes width of surroundings
588 // Insert the numeric field in the toolbox.
589 m_xEdit
->set_accessible_name(m_xEdit
->get_tooltip_text());
590 m_xEdit
->set_width_chars(3);
591 m_xEdit
->connect_activate(LINK(this, SwNavigationPI
, EditActionHdl
));
592 m_xEdit
->connect_value_changed(LINK(this, SwNavigationPI
, PageEditModifyHdl
));
593 m_xEdit
->set_help_id("modules/swriter/ui/navigatorpanel/numericfield");
597 m_xContent1ToolBox
->set_item_visible("contenttoggle", false);
600 const TranslateId REGIONNAME_ARY
[] =
607 const TranslateId REGIONMODE_ARY
[] =
614 static_assert(SAL_N_ELEMENTS(REGIONNAME_ARY
) == SAL_N_ELEMENTS(REGIONMODE_ARY
), "### unexpected size!");
615 static_assert(SAL_N_ELEMENTS(REGIONNAME_ARY
) == static_cast<sal_uInt16
>(RegionMode::EMBEDDED
) + 1, "### unexpected size!");
617 for (sal_uInt16 i
= 0; i
<= static_cast<sal_uInt16
>(RegionMode::EMBEDDED
); ++i
)
619 m_aStatusArr
[i
] = SwResId(REGIONMODE_ARY
[i
]);
622 m_aStatusArr
[3] = SwResId(STR_ACTIVE_VIEW
);
624 bool bFloatingNavigator
= ParentIsFloatingWindow(m_xNavigatorDlg
);
626 SetRegionDropMode(m_pConfig
->GetRegionMode());
628 m_xContentTree
->ShowTree();
629 m_xContent6ToolBox
->set_item_active("listbox", true);
630 m_xContent6ToolBox
->set_item_sensitive("listbox", bFloatingNavigator
);
632 // TreeListBox for global document
633 m_xGlobalTree
->set_selection_mode(SelectionMode::Multiple
);
636 Link
<const OUString
&, void> aLk
= LINK(this, SwNavigationPI
, ToolBoxSelectHdl
);
637 m_xContent1ToolBox
->connect_clicked(aLk
);
638 m_xContent3ToolBox
->connect_clicked(aLk
);
639 m_xContent5ToolBox
->connect_clicked(aLk
);
640 m_xContent6ToolBox
->connect_clicked(aLk
);
641 m_xGlobalToolBox
->connect_clicked(aLk
);
642 m_xDocListBox
->connect_changed(LINK(this, SwNavigationPI
, DocListBoxSelectHdl
));
643 m_xContent5ToolBox
->set_item_menu("headings", m_xHeadingsMenu
.get());
644 m_xHeadingsMenu
->connect_activate(LINK(this, SwNavigationPI
, HeadingsMenuSelectHdl
));
645 m_xContent5ToolBox
->connect_menu_toggled(LINK(this, SwNavigationPI
, ToolBox5DropdownClickHdl
));
646 m_xContent6ToolBox
->set_item_menu("dragmode", m_xDragModeMenu
.get());
647 m_xDragModeMenu
->connect_activate(LINK(this, SwNavigationPI
, DropModeMenuSelectHdl
));
648 m_xContent6ToolBox
->connect_menu_toggled(LINK(this, SwNavigationPI
, ToolBox6DropdownClickHdl
));
649 m_xGlobalToolBox
->set_item_menu("update", m_xUpdateMenu
.get());
650 m_xUpdateMenu
->connect_activate(LINK(this, SwNavigationPI
, GlobalMenuSelectHdl
));
651 m_xGlobalToolBox
->set_item_menu("insert", m_xInsertMenu
.get());
652 m_xInsertMenu
->connect_activate(LINK(this, SwNavigationPI
, GlobalMenuSelectHdl
));
653 m_xGlobalToolBox
->connect_menu_toggled(LINK(this, SwNavigationPI
, ToolBoxClickHdl
));
654 m_xGlobalToolBox
->set_item_active("globaltoggle", true);
655 m_pNavigateByComboBox
->connect_changed(LINK(this, SwNavigationPI
, NavigateByComboBoxSelectHdl
));
657 // set toolbar of both modes to widest of each
658 m_xGlobalToolBox
->set_size_request(m_xContent1ToolBox
->get_preferred_size().Width() +
659 m_xContent2ToolBox
->get_preferred_size().Width() +
660 m_xContent3ToolBox
->get_preferred_size().Width() +
661 m_xContent4ToolBox
->get_preferred_size().Width(), -1);
663 StartListening(*SfxGetpApp());
667 SwView
*pActView
= GetCreateView();
668 if (pActView
&& pActView
->GetWrtShellPtr())
669 m_xGlobalToolBox
->set_item_active("save",
670 pActView
->GetWrtShellPtr()->IsGlblDocSaveLinks());
671 if (m_pConfig
->IsGlobalActive())
673 if (bFloatingNavigator
)
674 m_xGlobalTree
->grab_focus();
676 else if (bFloatingNavigator
)
677 m_xContentTree
->grab_focus();
679 m_aPageChgIdle
.SetInvokeHandler(LINK(this, SwNavigationPI
, ChangePageHdl
));
680 m_aPageChgIdle
.SetPriority(TaskPriority::LOWEST
);
682 m_xContentTree
->set_accessible_name(SwResId(STR_ACCESS_TL_CONTENT
));
683 m_xGlobalTree
->set_accessible_name(SwResId(STR_ACCESS_TL_GLOBAL
));
684 m_xDocListBox
->set_accessible_name(m_aStatusArr
[3]);
686 m_aExpandedSize
= m_xContainer
->get_preferred_size();
688 if(comphelper::LibreOfficeKit::isActive())
690 m_xBuilder
->weld_container("gridcontent16")->hide();
691 m_xDocListBox
->hide();
692 m_xGlobalBox
->hide();
693 m_xGlobalToolBox
->hide();
694 m_xGlobalTree
->HideTree();
698 weld::Window
* SwNavigationPI::GetFrameWeld() const
701 return m_xNavigatorDlg
->GetFrameWeld();
702 return PanelLayout::GetFrameWeld();
705 SwNavigationPI::~SwNavigationPI()
707 if (IsGlobalDoc() && !IsGlobalMode())
709 SwView
*pView
= GetCreateView();
710 SwWrtShell
&rSh
= pView
->GetWrtShell();
711 if (!rSh
.IsAllProtect())
712 pView
->GetDocShell()->SetReadOnlyUI(false);
715 EndListening(*SfxGetpApp());
719 if (m_oObjectShell
->Is())
720 (*m_oObjectShell
)->DoClose();
721 m_oObjectShell
.reset();
724 m_xDocListBox
.reset();
725 m_xGlobalTree
.reset();
726 m_xGlobalBox
.reset();
727 m_xContentTree
.reset();
728 m_xContentBox
.reset();
729 m_xGlobalToolBox
.reset();
731 m_xHeadingsMenu
.reset();
732 m_xDragModeMenu
.reset();
733 m_xUpdateMenu
.reset();
734 m_xInsertMenu
.reset();
735 m_xContent2Dispatch
.reset();
736 m_xContent3Dispatch
.reset();
737 m_xContent1ToolBox
.reset();
738 m_xContent2ToolBox
.reset();
739 m_xContent3ToolBox
.reset();
740 m_xContent4ToolBox
.reset();
741 m_xContent5ToolBox
.reset();
742 m_xContent6ToolBox
.reset();
744 m_aPageChgIdle
.Stop();
746 m_aDocFullName
.dispose();
747 m_aPageStats
.dispose();
750 void SwNavigationPI::NotifyItemUpdate(sal_uInt16 nSID
, SfxItemState
/*eState*/,
751 const SfxPoolItem
* /*pState*/)
753 if (nSID
== SID_DOCFULLNAME
)
755 SwView
*pActView
= GetCreateView();
758 SwWrtShell
* pWrtShell
= pActView
->GetWrtShellPtr();
759 m_xContentTree
->SetActiveShell(pWrtShell
);
760 bool bGlobal
= IsGlobalDoc();
761 m_xContent1ToolBox
->set_item_visible("contenttoggle", bGlobal
);
762 if ((!bGlobal
&& IsGlobalMode()) || (!IsGlobalMode() && m_pConfig
->IsGlobalActive()))
768 m_xGlobalToolBox
->set_item_active("save", pWrtShell
->IsGlblDocSaveLinks());
773 m_xContentTree
->SetActiveShell(nullptr);
777 else if (nSID
== FN_STAT_PAGE
)
779 if(!comphelper::LibreOfficeKit::isActive())
781 SwView
*pActView
= GetCreateView();
784 SwWrtShell
&rSh
= pActView
->GetWrtShell();
785 m_xEdit
->set_max(rSh
.GetPageCnt());
786 m_xEdit
->set_width_chars(3);
792 void SwNavigationPI::UpdateInitShow()
794 // if the parent isn't a float, then the navigator is displayed in
795 // the sidebar or is otherwise docked. While the navigator could change
796 // its size, the sidebar can not, and the navigator would just waste
797 // space. Therefore disable this button.
798 bool bParentIsFloatingWindow(ParentIsFloatingWindow(m_xNavigatorDlg
));
799 m_xContent6ToolBox
->set_item_sensitive("listbox", bParentIsFloatingWindow
);
800 // show content if docked
801 if (!bParentIsFloatingWindow
&& IsZoomedIn())
807 IMPL_LINK_NOARG(SwNavigationPI
, SetFocusChildHdl
, weld::Container
&, void)
809 // update documents listbox
813 // Notification on modified DocInfo
814 void SwNavigationPI::Notify( SfxBroadcaster
& rBrdc
, const SfxHint
& rHint
)
816 if(&rBrdc
== m_pCreateView
)
818 if (rHint
.GetId() == SfxHintId::Dying
)
820 EndListening(*m_pCreateView
);
821 m_pCreateView
= nullptr;
822 m_xContentTree
->SetActiveShell(nullptr);
827 if (const SfxEventHint
* pHint
= dynamic_cast<const SfxEventHint
*>(&rHint
))
829 SfxEventHintId eEventId
= pHint
->GetEventId();
830 if (eEventId
== SfxEventHintId::OpenDoc
)
832 SwView
*pActView
= GetCreateView();
835 SwWrtShell
* pWrtShell
= pActView
->GetWrtShellPtr();
836 m_xContentTree
->SetActiveShell(pWrtShell
);
837 if (m_xGlobalTree
->get_visible())
839 bool bUpdateAll
= m_xGlobalTree
->Update(false);
840 // If no update is needed, then update the font colors
841 // at the entries of broken links.
842 m_xGlobalTree
->Display(!bUpdateAll
);
850 IMPL_LINK( SwNavigationPI
, HeadingsMenuSelectHdl
, const OUString
&, rMenuId
, void )
852 if (!rMenuId
.isEmpty())
853 m_xContentTree
->SetOutlineLevel(rMenuId
.toUInt32());
856 void SwNavigationPI::UpdateListBox()
858 if (!m_xDocListBox
) // disposed
861 m_xDocListBox
->freeze();
862 m_xDocListBox
->clear();
863 SwView
*pActView
= GetCreateView();
864 bool bDisable
= pActView
== nullptr;
865 SwView
*pView
= SwModule::GetFirstView();
866 sal_Int32 nCount
= 0;
868 sal_Int32 nConstPos
= 0;
869 const SwView
* pConstView
= m_xContentTree
->IsConstantView() &&
870 m_xContentTree
->GetActiveWrtShell() ?
871 &m_xContentTree
->GetActiveWrtShell()->GetView():
875 SfxObjectShell
* pDoc
= pView
->GetDocShell();
876 // #i53333# don't show help pages here
877 if ( !pDoc
->IsHelpDocument() )
879 OUString sEntry
= pDoc
->GetTitle() + " (";
880 if (pView
== pActView
)
883 sEntry
+= m_aStatusArr
[IDX_STR_ACTIVE
];
886 sEntry
+= m_aStatusArr
[IDX_STR_INACTIVE
];
888 m_xDocListBox
->append_text(sEntry
);
890 if (pConstView
&& pView
== pConstView
)
895 pView
= SwModule::GetNextView(pView
);
897 m_xDocListBox
->append_text(m_aStatusArr
[3]); // "Active Window"
900 if(m_xContentTree
->GetHiddenWrtShell())
902 OUString sEntry
= m_xContentTree
->GetHiddenWrtShell()->GetView().
903 GetDocShell()->GetTitle() +
905 m_aStatusArr
[IDX_STR_HIDDEN
] +
907 m_xDocListBox
->append_text(sEntry
);
911 m_xDocListBox
->thaw();
913 if(m_xContentTree
->IsActiveView())
915 //Either the name of the current Document or "Active Document".
916 m_xDocListBox
->set_active(pActView
? nAct
: --nCount
);
918 else if(m_xContentTree
->IsHiddenView())
920 m_xDocListBox
->set_active(nCount
);
923 m_xDocListBox
->set_active(nConstPos
);
925 m_xDocListBox
->set_sensitive(!bDisable
);
928 IMPL_LINK(SwNavigationPI
, DoneLink
, SfxPoolItem
const *, pItem
, void)
930 const SfxViewFrameItem
* pFrameItem
= dynamic_cast<SfxViewFrameItem
const *>( pItem
);
934 SfxViewFrame
* pFrame
= pFrameItem
->GetFrame();
937 m_xContentTree
->clear();
938 m_pContentView
= dynamic_cast<SwView
*>( pFrame
->GetViewShell() );
939 OSL_ENSURE(m_pContentView
, "no SwView");
941 m_pContentWrtShell
= m_pContentView
->GetWrtShellPtr();
943 m_pContentWrtShell
= nullptr;
944 m_oObjectShell
.emplace( pFrame
->GetObjectShell() );
949 OUString
SwNavigationPI::CreateDropFileName( const TransferableDataHelper
& rData
)
952 SotClipboardFormatId nFormat
;
953 if( rData
.HasFormat( nFormat
= SotClipboardFormatId::FILE_LIST
))
956 rData
.GetFileList( nFormat
, aFileList
);
957 sFileName
= aFileList
.GetFile( 0 );
959 else if( rData
.HasFormat( nFormat
= SotClipboardFormatId::STRING
) ||
960 rData
.HasFormat( nFormat
= SotClipboardFormatId::SIMPLE_FILE
) ||
961 rData
.HasFormat( nFormat
= SotClipboardFormatId::FILENAME
))
963 (void)rData
.GetString(nFormat
, sFileName
);
965 else if( rData
.HasFormat( nFormat
= SotClipboardFormatId::SOLK
) ||
966 rData
.HasFormat( nFormat
= SotClipboardFormatId::NETSCAPE_BOOKMARK
)||
967 rData
.HasFormat( nFormat
= SotClipboardFormatId::FILECONTENT
) ||
968 rData
.HasFormat( nFormat
= SotClipboardFormatId::FILEGRPDESCRIPTOR
) ||
969 rData
.HasFormat( nFormat
= SotClipboardFormatId::UNIFORMRESOURCELOCATOR
))
971 INetBookmark aBkmk
{ OUString(), OUString() };
972 if (rData
.GetINetBookmark(nFormat
, aBkmk
))
973 sFileName
= aBkmk
.GetURL();
975 if( !sFileName
.isEmpty() )
977 sFileName
= INetURLObject( sFileName
).GetMainURL( INetURLObject::DecodeMechanism::NONE
);
982 sal_Int8
SwNavigationPI::AcceptDrop()
984 return ( !m_xContentTree
->IsInDrag() &&
985 ( m_xContentTree
->IsDropFormatSupported( SotClipboardFormatId::SIMPLE_FILE
) ||
986 m_xContentTree
->IsDropFormatSupported( SotClipboardFormatId::STRING
) ||
987 m_xContentTree
->IsDropFormatSupported( SotClipboardFormatId::SOLK
) ||
988 m_xContentTree
->IsDropFormatSupported( SotClipboardFormatId::NETSCAPE_BOOKMARK
)||
989 m_xContentTree
->IsDropFormatSupported( SotClipboardFormatId::FILECONTENT
) ||
990 m_xContentTree
->IsDropFormatSupported( SotClipboardFormatId::FILEGRPDESCRIPTOR
) ||
991 m_xContentTree
->IsDropFormatSupported( SotClipboardFormatId::UNIFORMRESOURCELOCATOR
) ||
992 m_xContentTree
->IsDropFormatSupported( SotClipboardFormatId::FILENAME
)))
997 sal_Int8
SwNavigationPI::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
999 TransferableDataHelper
aData( rEvt
.maDropEvent
.Transferable
);
1000 sal_Int8 nRet
= DND_ACTION_NONE
;
1001 if (m_xContentTree
->IsInDrag())
1004 OUString sFileName
= SwNavigationPI::CreateDropFileName(aData
);
1005 if (sFileName
.isEmpty())
1008 INetURLObject
aTemp(sFileName
);
1009 GraphicDescriptor
aDesc(aTemp
);
1010 if (aDesc
.Detect()) // accept no graphics
1013 if (-1 != sFileName
.indexOf('#'))
1016 if (m_sContentFileName
.isEmpty() || m_sContentFileName
!= sFileName
)
1018 nRet
= rEvt
.mnAction
;
1019 sFileName
= comphelper::string::stripEnd(sFileName
, 0);
1020 m_sContentFileName
= sFileName
;
1023 m_xContentTree
->SetHiddenShell( nullptr );
1024 (*m_oObjectShell
)->DoClose();
1025 m_oObjectShell
.reset();
1027 SfxStringItem
aFileItem(SID_FILE_NAME
, sFileName
);
1028 SfxStringItem
aOptionsItem( SID_OPTIONS
, "HRC" );
1029 SfxLinkItem
aLink( SID_DONELINK
,
1030 LINK( this, SwNavigationPI
, DoneLink
) );
1031 if (SwView
* pView
= GetActiveView())
1032 pView
->GetViewFrame().GetDispatcher()->ExecuteList(
1033 SID_OPENDOC
, SfxCallMode::ASYNCHRON
,
1034 { &aFileItem
, &aOptionsItem
, &aLink
});
1039 void SwNavigationPI::SetRegionDropMode(RegionMode nNewMode
)
1041 m_nRegionMode
= nNewMode
;
1042 m_pConfig
->SetRegionMode( m_nRegionMode
);
1047 case RegionMode::NONE
:
1048 sImageId
= RID_BMP_DROP_REGION
;
1050 case RegionMode::LINK
:
1051 sImageId
= RID_BMP_DROP_LINK
;
1053 case RegionMode::EMBEDDED
:
1054 sImageId
= RID_BMP_DROP_COPY
;
1057 m_xContent6ToolBox
->set_item_icon_name("dragmode", sImageId
);
1060 void SwNavigationPI::ToggleTree()
1062 if (comphelper::LibreOfficeKit::isActive())
1064 m_xGlobalTree
->HideTree();
1068 bool bGlobalDoc
= IsGlobalDoc();
1069 if (!IsGlobalMode() && bGlobalDoc
)
1073 m_xGlobalBox
->show();
1074 m_xGlobalTree
->ShowTree();
1075 m_xGlobalToolBox
->show();
1076 m_xContentBox
->hide();
1077 m_xContentTree
->HideTree();
1078 m_xContent1ToolBox
->hide();
1079 m_xContent2ToolBox
->hide();
1080 m_xContent3ToolBox
->hide();
1081 m_xContent4ToolBox
->hide();
1082 m_xContent5ToolBox
->hide();
1083 m_xContent6ToolBox
->hide();
1084 m_xDocListBox
->hide();
1085 SetGlobalMode(true);
1089 m_xGlobalBox
->hide();
1090 m_xGlobalTree
->HideTree();
1091 m_xGlobalToolBox
->hide();
1094 m_xContentBox
->show();
1095 m_xContentTree
->ShowTree();
1096 m_xContent1ToolBox
->show();
1097 m_xContent2ToolBox
->show();
1098 m_xContent3ToolBox
->show();
1099 m_xContent4ToolBox
->show();
1100 m_xContent5ToolBox
->show();
1101 m_xContent6ToolBox
->show();
1102 m_xDocListBox
->show();
1104 SetGlobalMode(false);
1108 bool SwNavigationPI::IsGlobalDoc() const
1111 SwView
*pView
= GetCreateView();
1114 SwWrtShell
&rSh
= pView
->GetWrtShell();
1115 bRet
= rSh
.IsGlobalDoc();
1120 IMPL_LINK_NOARG(SwNavigationPI
, ChangePageHdl
, Timer
*, void)
1122 if (!m_xDocListBox
) // disposed
1124 // tdf#134959 if the SpinButton changed value this Timer was launched, now
1125 // change to the desired page, but we leave focus where it currently is,
1126 // i.e. typically remaining in the spinbutton, or whatever other widget the
1127 // user moved to in the meantime
1131 void SwNavigationPI::SelectNavigateByContentType(const OUString
& rContentTypeName
)
1133 if (auto nPos
= m_pNavigateByComboBox
->find_text(rContentTypeName
); nPos
!= -1)
1135 m_pNavigateByComboBox
->set_active(nPos
);
1140 IMPL_LINK_NOARG(SwNavigationPI
, EditActionHdl
, weld::Entry
&, bool)
1142 // tdf#134959 if the user presses enter to activate the Entry
1143 // go to the page, and on success we move focus to the document
1145 m_pCreateView
->GetEditWin().GrabFocus();
1149 IMPL_LINK_NOARG(SwNavigationPI
, PageEditModifyHdl
, weld::SpinButton
&, void)
1151 if (m_aPageChgIdle
.IsActive())
1152 m_aPageChgIdle
.Stop();
1153 m_aPageChgIdle
.Start();
1156 SwView
* SwNavigationPI::GetCreateView() const
1160 SwView
* pView
= SwModule::GetFirstView();
1163 if(&pView
->GetViewFrame().GetBindings() == &m_rBindings
)
1165 const_cast<SwNavigationPI
*>(this)->m_pCreateView
= pView
;
1166 const_cast<SwNavigationPI
*>(this)->StartListening(*m_pCreateView
);
1169 pView
= SwModule::GetNextView(pView
);
1172 return m_pCreateView
;
1175 class SwNavigatorWin
: public SfxNavigator
1178 std::unique_ptr
<SwNavigationPI
> m_xNavi
;
1180 SwNavigatorWin(SfxBindings
* _pBindings
, SfxChildWindow
* _pMgr
,
1181 vcl::Window
* pParent
, SfxChildWinInfo
* pInfo
);
1182 virtual void StateChanged(StateChangedType nStateChange
) override
;
1183 virtual void dispose() override
1186 SfxNavigator::dispose();
1188 virtual ~SwNavigatorWin() override
1194 SwNavigatorWin::SwNavigatorWin(SfxBindings
* _pBindings
, SfxChildWindow
* _pMgr
,
1195 vcl::Window
* pParent
, SfxChildWinInfo
* pInfo
)
1196 : SfxNavigator(_pBindings
, _pMgr
, pParent
, pInfo
)
1197 , m_xNavi(std::make_unique
<SwNavigationPI
>(m_xContainer
.get(), _pBindings
->GetActiveFrame(), _pBindings
, this))
1199 _pBindings
->Invalidate(SID_NAVIGATOR
);
1201 SwNavigationConfig
* pNaviConfig
= SW_MOD()->GetNavigationConfig();
1203 SetMinOutputSizePixel(GetOptimalSize());
1204 if (pNaviConfig
->IsSmall())
1208 void SwNavigatorWin::StateChanged(StateChangedType nStateChange
)
1210 SfxNavigator::StateChanged(nStateChange
);
1211 if (nStateChange
== StateChangedType::InitShow
)
1212 m_xNavi
->UpdateInitShow();
1215 SFX_IMPL_DOCKINGWINDOW(SwNavigatorWrapper
, SID_NAVIGATOR
);
1217 SwNavigatorWrapper::SwNavigatorWrapper(vcl::Window
*_pParent
, sal_uInt16 nId
,
1218 SfxBindings
* pBindings
, SfxChildWinInfo
* pInfo
)
1219 : SfxNavigatorWrapper(_pParent
, nId
)
1221 SetWindow(VclPtr
<SwNavigatorWin
>::Create(pBindings
, this, _pParent
, pInfo
));
1225 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */