diff options
Diffstat (limited to 'sd/source/ui/dlg/navigatr.cxx')
-rw-r--r-- | sd/source/ui/dlg/navigatr.cxx | 890 |
1 files changed, 890 insertions, 0 deletions
diff --git a/sd/source/ui/dlg/navigatr.cxx b/sd/source/ui/dlg/navigatr.cxx new file mode 100644 index 0000000000..f1a4a66c1e --- /dev/null +++ b/sd/source/ui/dlg/navigatr.cxx @@ -0,0 +1,890 @@ +/* -*- 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 <memory> +#include <sal/config.h> + +#include <osl/file.hxx> +#include <tools/urlobj.hxx> +#include <sfx2/fcontnr.hxx> +#include <svl/stritem.hxx> +#include <sfx2/docfile.hxx> +#include <svl/intitem.hxx> +#include <sfx2/dispatch.hxx> + +#include <sfx2/viewfrm.hxx> + +#include <pres.hxx> +#include <navigatr.hxx> +#include <pgjump.hxx> +#include <app.hrc> + +#include <bitmaps.hlst> +#include <drawdoc.hxx> +#include <DrawDocShell.hxx> +#include <ViewShell.hxx> +#include <ViewShellBase.hxx> +#include <slideshow.hxx> +#include <FrameView.hxx> +#include <Window.hxx> + +#include <DrawViewShell.hxx> +#include <utility> + +#include <vcl/commandevent.hxx> +#include <comphelper/lok.hxx> + +/** + * SdNavigatorWin - FloatingWindow + */ +SdNavigatorWin::SdNavigatorWin(weld::Widget* pParent, SfxBindings* pInBindings, SfxNavigator* pNavigatorDlg) + : PanelLayout(pParent, "NavigatorPanel", "modules/simpress/ui/navigatorpanel.ui") + , mxToolbox(m_xBuilder->weld_toolbar("toolbox")) + , mxTlbObjects(new SdPageObjsTLV(m_xBuilder->weld_tree_view("tree"))) + , mxLbDocs(m_xBuilder->weld_combo_box("documents")) + , mxDragModeMenu(m_xBuilder->weld_menu("dragmodemenu")) + , mxShapeMenu(m_xBuilder->weld_menu("shapemenu")) + , mxNavigatorDlg(pNavigatorDlg) + , mbDocImported ( false ) + // On changes of the DragType: adjust SelectionMode of TLB! + , meDragType ( NAVIGATOR_DRAGTYPE_EMBEDDED ) + , mpBindings ( pInBindings ) +{ + mxTlbObjects->SetViewFrame( mpBindings->GetDispatcher()->GetFrame() ); + + mxTlbObjects->connect_row_activated(LINK(this, SdNavigatorWin, ClickObjectHdl)); + mxTlbObjects->set_selection_mode(SelectionMode::Multiple); + mxTlbObjects->connect_mouse_release(LINK(this, SdNavigatorWin, MouseReleaseHdl)); + mxTlbObjects->connect_popup_menu(LINK(this, SdNavigatorWin, CommandHdl)); + + mxToolbox->connect_clicked(LINK(this, SdNavigatorWin, SelectToolboxHdl)); + mxToolbox->connect_menu_toggled(LINK(this, SdNavigatorWin, DropdownClickToolBoxHdl)); + + mxToolbox->set_item_menu("dragmode", mxDragModeMenu.get()); + mxDragModeMenu->connect_activate(LINK(this, SdNavigatorWin, MenuSelectHdl)); + + // Shape filter drop down menu. + mxToolbox->set_item_menu("shapes", mxShapeMenu.get()); + mxShapeMenu->connect_activate(LINK(this, SdNavigatorWin, ShapeFilterCallback)); + + mxTlbObjects->SetSdNavigator(this); + + // DragTypeListBox + mxLbDocs->set_size_request(42, -1); // set a nominal width so it takes width of surroundings + mxLbDocs->connect_changed(LINK(this, SdNavigatorWin, SelectDocumentHdl)); + + SetDragImage(); + + mxToolbox->connect_key_press(LINK(this, SdNavigatorWin, KeyInputHdl)); + mxTlbObjects->connect_key_press(LINK(this, SdNavigatorWin, KeyInputHdl)); + mxLbDocs->connect_key_press(LINK(this, SdNavigatorWin, KeyInputHdl)); + if(comphelper::LibreOfficeKit::isActive()) + { + mxToolbox->hide(); + mxLbDocs->hide(); + } +} + +void SdNavigatorWin::FirstFocus() +{ + // set focus to listbox, otherwise it is in the toolbox which is only useful + // for keyboard navigation + mxTlbObjects->grab_focus(); +} + +weld::Window* SdNavigatorWin::GetFrameWeld() const +{ + if (mxNavigatorDlg) + return mxNavigatorDlg->GetFrameWeld(); + return PanelLayout::GetFrameWeld(); +} + +void SdNavigatorWin::SetUpdateRequestFunctor(const UpdateRequestFunctor& rUpdateRequest) +{ + mpNavigatorCtrlItem.reset( new SdNavigatorControllerItem(SID_NAVIGATOR_STATE, this, mpBindings, rUpdateRequest) ); + mpPageNameCtrlItem.reset( new SdPageNameControllerItem(SID_NAVIGATOR_PAGENAME, this, mpBindings) ); + + // InitTlb; is initiated over Slot + if (rUpdateRequest) + rUpdateRequest(); +} + +SdNavigatorWin::~SdNavigatorWin() +{ + mpNavigatorCtrlItem.reset(); + mpPageNameCtrlItem.reset(); + mxDragModeMenu.reset(); + mxShapeMenu.reset(); + mxToolbox.reset(); + mxTlbObjects.reset(); + mxLbDocs.reset(); +} + +static void lcl_select_marked_object(const sd::ViewShell* pViewShell, SdPageObjsTLV* pTlbObjects) +{ + if (const SdrView* pView = pViewShell->GetDrawView()) + { + auto vMarkedObjects = pView->GetMarkedObjects(); + if (vMarkedObjects.size()) + { + pTlbObjects->unselect_all(); + for (auto rMarkedObject: vMarkedObjects) + pTlbObjects->SelectEntry(rMarkedObject); + } + else + pTlbObjects->SelectEntry(pViewShell->GetName()); + } +} + +//when object is marked , fresh the corresponding entry tree . +void SdNavigatorWin::FreshTree( const SdDrawDocument* pDoc ) +{ + SdDrawDocument* pNonConstDoc = const_cast<SdDrawDocument*>(pDoc); // const as const can... + sd::DrawDocShell* pDocShell = pNonConstDoc->GetDocSh(); + const OUString& aDocShName( pDocShell->GetName() ); + OUString aDocName = pDocShell->GetMedium()->GetName(); + if (!mxTlbObjects->IsEqualToDoc(pDoc)) + { + mxTlbObjects->Fill( pDoc, false, aDocName ); // Only normal pages + RefreshDocumentLB(); + mxLbDocs->set_active_text(aDocShName); + } + if (const sd::ViewShell* pViewShell = pDocShell->GetViewShell()) + lcl_select_marked_object(pViewShell, mxTlbObjects.get()); +} + +void SdNavigatorWin::InitTreeLB( const SdDrawDocument* pDoc ) +{ + SdDrawDocument* pNonConstDoc = const_cast<SdDrawDocument*>(pDoc); // const as const can... + ::sd::DrawDocShell* pDocShell = pNonConstDoc->GetDocSh(); + OUString aDocShName( pDocShell->GetName() ); + ::sd::ViewShell* pViewShell = pDocShell->GetViewShell(); + + // Restore the 'ShowAllShapes' flag from the last time (in this session) + // that the navigator was shown. + if (pViewShell != nullptr) + { + ::sd::FrameView* pFrameView = pViewShell->GetFrameView(); + if (pFrameView != nullptr) + mxTlbObjects->SetShowAllShapes(pFrameView->IsNavigatorShowingAllShapes(), false); + } + + // Disable the shape filter drop down menu when there is a running slide + // show. + if (pViewShell!=nullptr && sd::SlideShow::IsRunning( pViewShell->GetViewShellBase() )) + mxToolbox->set_item_sensitive("shapes", false); + else + mxToolbox->set_item_sensitive("shapes", true); + + if( !mxTlbObjects->IsEqualToDoc( pDoc ) ) + { + OUString aDocName = pDocShell->GetMedium()->GetName(); + mxTlbObjects->clear(); + mxTlbObjects->Fill( pDoc, false, aDocName ); // only normal pages + + RefreshDocumentLB(); + mxLbDocs->set_active_text(aDocShName); + } + else + { + mxLbDocs->set_active(-1); + mxLbDocs->set_active_text(aDocShName); + +// commented in order to fix 30246 +// if( mxLbDocs->get_active() == -1 ) + { + RefreshDocumentLB(); + mxLbDocs->set_active_text(aDocShName); + } + } + + if (pViewShell) + lcl_select_marked_object(pViewShell, mxTlbObjects.get()); + + SfxViewFrame* pViewFrame = ( ( pViewShell && pViewShell->GetViewFrame() ) ? pViewShell->GetViewFrame() : SfxViewFrame::Current() ); + if( pViewFrame ) + pViewFrame->GetBindings().Invalidate(SID_NAVIGATOR_PAGENAME, true, true); +} + +/** + * DragType is set on dependence if a Drag is even possible. For example, + * under certain circumstances, it is not allowed to drag graphics (#31038#). + */ +NavigatorDragType SdNavigatorWin::GetNavigatorDragType() +{ + NavigatorDragType eDT = meDragType; + NavDocInfo* pInfo = GetDocInfo(); + + if( ( eDT == NAVIGATOR_DRAGTYPE_LINK ) && ( ( pInfo && !pInfo->HasName() ) || !mxTlbObjects->IsLinkableSelected() ) ) + eDT = NAVIGATOR_DRAGTYPE_NONE; + + return eDT; +} + +SdPageObjsTLV& SdNavigatorWin::GetObjects() +{ + return *mxTlbObjects; +} + +IMPL_STATIC_LINK_NOARG(SdNavigatorWin, MouseReleaseHdl, const MouseEvent&, bool) +{ + return true; +} + +IMPL_LINK(SdNavigatorWin, CommandHdl, const CommandEvent&, rCEvt, bool) +{ + if (rCEvt.GetCommand() != CommandEventId::ContextMenu) + return false; + weld::TreeView& rTreeView = GetObjects().get_treeview(); + std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(&rTreeView, + "modules/sdraw/ui/navigatorcontextmenu.ui")); + std::unique_ptr<weld::Menu> xPop = xBuilder->weld_menu("navmenu"); + OUString sCommand = xPop->popup_at_rect(&rTreeView, + tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1))); + if (!sCommand.isEmpty()) + ExecuteContextMenuAction(sCommand); + return true; +} + +void SdNavigatorWin::ExecuteContextMenuAction(std::u16string_view rSelectedPopupEntry) +{ + if (rSelectedPopupEntry == u"rename" && mpBindings) + { + weld::TreeView& rTreeView = GetObjects().get_treeview(); + std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator()); + if (rTreeView.get_selected(xIter.get())) + { + if (rTreeView.get_iter_depth(*xIter) > 0) + mpBindings->Execute(SID_NAME_GROUP); + else + mpBindings->Execute(SID_RENAMEPAGE); + } + } +} + +IMPL_LINK(SdNavigatorWin, SelectToolboxHdl, const OUString&, rCommand, void) +{ + PageJump ePage = PAGE_NONE; + + if (rCommand == "first") + ePage = PAGE_FIRST; + else if (rCommand == "previous") + ePage = PAGE_PREVIOUS; + else if (rCommand == "next") + ePage = PAGE_NEXT; + else if (rCommand == "last") + ePage = PAGE_LAST; + else if (rCommand == "dragmode") + mxToolbox->set_menu_item_active("dragmode", !mxToolbox->get_menu_item_active("dragmode")); + else if (rCommand == "shapes") + mxToolbox->set_menu_item_active("shapes", !mxToolbox->get_menu_item_active("shapes")); + + if (ePage != PAGE_NONE) + { + SfxUInt16Item aItem( SID_NAVIGATOR_PAGE, static_cast<sal_uInt16>(ePage) ); + mpBindings->GetDispatcher()->ExecuteList(SID_NAVIGATOR_PAGE, + SfxCallMode::SLOT | SfxCallMode::RECORD, { &aItem }); + } +} + +IMPL_LINK(SdNavigatorWin, DropdownClickToolBoxHdl, const OUString&, rCommand, void) +{ + if (!mxToolbox->get_menu_item_active(rCommand)) + return; + + if (rCommand == "dragmode") + { + NavDocInfo* pInfo = GetDocInfo(); + if( ( pInfo && !pInfo->HasName() ) || !mxTlbObjects->IsLinkableSelected() ) + { + mxDragModeMenu->set_sensitive(OUString::number(NAVIGATOR_DRAGTYPE_LINK), false); + mxDragModeMenu->set_sensitive(OUString::number(NAVIGATOR_DRAGTYPE_URL), false); + meDragType = NAVIGATOR_DRAGTYPE_EMBEDDED; + } + + mxDragModeMenu->set_active(OUString::number(meDragType), true); + } + else if (rCommand == "shapes") + { + bool bAll = mxTlbObjects->GetShowAllShapes(); + mxShapeMenu->set_active("named", !bAll); + mxShapeMenu->set_active("all", bAll); + bool bOrderFrontToBack = mxTlbObjects->GetOrderFrontToBack(); + mxShapeMenu->set_active("fronttoback", bOrderFrontToBack); + mxShapeMenu->set_active("backtofront", !bOrderFrontToBack); + } +} + +IMPL_LINK_NOARG(SdNavigatorWin, ClickObjectHdl, weld::TreeView&, bool) +{ + if( !mbDocImported || mxLbDocs->get_active() != 0 ) + { + NavDocInfo* pInfo = GetDocInfo(); + + // if it is the active window, we jump to the page + if( pInfo && pInfo->IsActive() ) + { + OUString aStr(mxTlbObjects->get_cursor_text()); + + if( !aStr.isEmpty() ) + { + sd::DrawDocShell* pDocShell = pInfo->mpDocShell; + if (!pDocShell) + return false; + sd::ViewShell* pViewShell = pDocShell->GetViewShell(); + if (!pViewShell) + return false; + SdrView* pDrawView = pViewShell->GetDrawView(); + if (!pDrawView) + return false; + + // Save the selected tree entries re-mark the objects in the view after navigation. + auto vSelectedEntryIds = mxTlbObjects->GetSelectedEntryIds(); + + // Page entries in the tree have id value 1. Object entries have id value of + // the address of the pointer to the object. + const auto& rCursorEntryId = mxTlbObjects->get_cursor_id(); + auto nCursorEntryId = rCursorEntryId.toInt64(); + SdrObject* pCursorEntryObject = weld::fromId<SdrObject*>(rCursorEntryId); + + bool bIsCursorEntrySelected(std::find(vSelectedEntryIds.begin(), + vSelectedEntryIds.end(), + rCursorEntryId) != vSelectedEntryIds.end()); + + if (bIsCursorEntrySelected) + { + // Set a temporary name, if need be, so the object can be navigated to. + bool bCursorEntryObjectHasEmptyName = false; + if (nCursorEntryId != 1 && pCursorEntryObject + && pCursorEntryObject->GetName().isEmpty()) + { + bCursorEntryObjectHasEmptyName = true; + bool bUndo = pCursorEntryObject->getSdrModelFromSdrObject().IsUndoEnabled(); + pCursorEntryObject->getSdrModelFromSdrObject().EnableUndo(false); + pCursorEntryObject->SetName(aStr, false); + pCursorEntryObject->getSdrModelFromSdrObject().EnableUndo(bUndo); + } + + // All objects are unmarked when navigating to an object. + SfxStringItem aItem(SID_NAVIGATOR_OBJECT, aStr); + mpBindings->GetDispatcher()->ExecuteList(SID_NAVIGATOR_OBJECT, + SfxCallMode::SLOT | SfxCallMode::RECORD, { &aItem }); + + if (bCursorEntryObjectHasEmptyName) + { + bool bUndo = pCursorEntryObject->getSdrModelFromSdrObject().IsUndoEnabled(); + pCursorEntryObject->getSdrModelFromSdrObject().EnableUndo(false); + pCursorEntryObject->SetName(OUString(), false); + pCursorEntryObject->getSdrModelFromSdrObject().EnableUndo(bUndo); + } + + // re-mark the objects + if (bIsCursorEntrySelected) + { + // Mark the objects in the view that are selected in the Navigator tree. + for (auto& rEntryId: vSelectedEntryIds) + { + if (rEntryId != "1") + { + SdrObject* pEntryObject = weld::fromId<SdrObject*>(rEntryId); + if (pEntryObject) + pDrawView->MarkObj(pEntryObject, pDrawView->GetSdrPageView()); + } + } + } + } + else if (nCursorEntryId != 1 && pCursorEntryObject) + { + // unmark + pDrawView->MarkObj(pCursorEntryObject, pDrawView->GetSdrPageView(), true); + } + + // moved here from SetGetFocusHdl. Reset the + // focus only if something has been selected in the + // document. + SfxViewShell* pCurSh = SfxViewShell::Current(); + + if ( pCurSh ) + { + vcl::Window* pShellWnd = pCurSh->GetWindow(); + if ( pShellWnd ) + pShellWnd->GrabFocus(); + } + + // We navigated to an object, but the current shell may be + // still the slide sorter. Explicitly try to grab the draw + // shell focus, so follow-up operations work with the object + // and not with the whole slide. + vcl::Window* pWindow = pViewShell->GetActiveWindow(); + if (pWindow) + pWindow->GrabFocus(); + + if (!mxTlbObjects->IsNavigationGrabsFocus()) + { + // This is the case when keyboard navigation inside the + // navigator should continue to work. + if (mxNavigatorDlg) + mxNavigatorDlg->GrabFocus(); + mxTlbObjects->grab_focus(); + } + } + } + } + return false; +} + +IMPL_LINK_NOARG(SdNavigatorWin, SelectDocumentHdl, weld::ComboBox&, void) +{ + OUString aStrLb = mxLbDocs->get_active_text(); + tools::Long nPos = mxLbDocs->get_active(); + bool bFound = false; + ::sd::DrawDocShell* pDocShell = nullptr; + NavDocInfo* pInfo = GetDocInfo(); + + // is it a dragged object? + if( mbDocImported && nPos == 0 ) + { + // construct document in TLB + InsertFile( aStrLb ); + } + else if (pInfo) + { + pDocShell = pInfo->mpDocShell; + + bFound = true; + } + + if( bFound ) + { + SdDrawDocument* pDoc = pDocShell->GetDoc(); + if( !mxTlbObjects->IsEqualToDoc( pDoc ) ) + { + SdDrawDocument* pNonConstDoc = pDoc; // const as const can... + ::sd::DrawDocShell* pNCDocShell = pNonConstDoc->GetDocSh(); + OUString aDocName = pNCDocShell->GetMedium()->GetName(); + mxTlbObjects->clear(); + mxTlbObjects->Fill( pDoc, false, aDocName ); // only normal pages + } + } + + // check if link or url is possible + if( ( pInfo && !pInfo->HasName() ) || !mxTlbObjects->IsLinkableSelected() || ( meDragType != NAVIGATOR_DRAGTYPE_EMBEDDED ) ) + { + meDragType = NAVIGATOR_DRAGTYPE_EMBEDDED; + SetDragImage(); + } +} + +/** + * Set DrageType and set image accordingly to it. + */ +IMPL_LINK(SdNavigatorWin, MenuSelectHdl, const OUString&, rIdent, void) +{ + sal_uInt32 nMenuId = rIdent.toUInt32(); + + NavigatorDragType eDT = static_cast<NavigatorDragType>(nMenuId); + if( meDragType == eDT ) + return; + + meDragType = eDT; + SetDragImage(); + + if( meDragType == NAVIGATOR_DRAGTYPE_URL ) + { + // patch, prevents endless loop + if (mxTlbObjects->count_selected_rows() > 1) + mxTlbObjects->unselect_all(); + + mxTlbObjects->set_selection_mode(SelectionMode::Single); + } + else + mxTlbObjects->set_selection_mode(SelectionMode::Multiple); +} + +IMPL_LINK( SdNavigatorWin, ShapeFilterCallback, const OUString&, rIdent, void ) +{ + bool bShowAllShapes(mxTlbObjects->GetShowAllShapes()); + bool bOrderFrontToBack(mxTlbObjects->GetOrderFrontToBack()); + if (rIdent == "named") + bShowAllShapes = false; + else if (rIdent == "all") + bShowAllShapes = true; + else if (rIdent == "fronttoback") + bOrderFrontToBack = true; + else if (rIdent == "backtofront") + bOrderFrontToBack = false; + else + OSL_FAIL("SdNavigatorWin::ShapeFilterCallback called for unknown menu entry"); + + mxTlbObjects->SetOrderFrontToBack(bOrderFrontToBack); + mxTlbObjects->SetShowAllShapes(bShowAllShapes, true); + + // Remember the selection in the FrameView. + NavDocInfo* pInfo = GetDocInfo(); + if (pInfo == nullptr) + return; + + ::sd::DrawDocShell* pDocShell = pInfo->mpDocShell; + if (pDocShell != nullptr) + { + ::sd::ViewShell* pViewShell = pDocShell->GetViewShell(); + if (pViewShell != nullptr) + { + ::sd::FrameView* pFrameView = pViewShell->GetFrameView(); + if (pFrameView != nullptr) + { + pFrameView->SetIsNavigatorShowingAllShapes(bShowAllShapes); + } + lcl_select_marked_object(pViewShell, mxTlbObjects.get()); + } + } +} + +bool SdNavigatorWin::InsertFile(const OUString& rFileName) +{ + INetURLObject aURL( rFileName ); + + if( aURL.GetProtocol() == INetProtocol::NotValid ) + { + OUString aURLStr; + osl::FileBase::getFileURLFromSystemPath( rFileName, aURLStr ); + aURL = INetURLObject( aURLStr ); + } + + // get adjusted FileName + OUString aFileName( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) ); + + if (aFileName.isEmpty()) + { + // show actual document again + maDropFileName = aFileName; + } + else + { + // show dragged-in document + std::shared_ptr<const SfxFilter> pFilter; + ErrCode nErr = ERRCODE_NONE; + + if (aFileName != maDropFileName) + { + SfxMedium aMed(aFileName, (StreamMode::READ | StreamMode::SHARE_DENYNONE)); + SfxFilterMatcher aMatch( "simpress" ); + aMed.UseInteractionHandler( true ); + nErr = aMatch.GuessFilter(aMed, pFilter); + } + + if ((pFilter && !nErr) || aFileName == maDropFileName) + { + // The medium may be opened with READ/WRITE. Therefore, we first + // check if it contains a Storage. + std::unique_ptr<SfxMedium> xMedium(new SfxMedium(aFileName, + StreamMode::READ | StreamMode::NOCREATE)); + + if (xMedium->IsStorage()) + { + // Now depending on mode: + // mxTlbObjects->set_selection_mode(SelectionMode::Multiple); + // handover of ownership of xMedium; + SdDrawDocument* pDropDoc = mxTlbObjects->GetBookmarkDoc(xMedium.release()); + + if (pDropDoc) + { + mxTlbObjects->clear(); + maDropFileName = aFileName; + + if( !mxTlbObjects->IsEqualToDoc( pDropDoc ) ) + { + // only normal pages + mxTlbObjects->Fill(pDropDoc, false, maDropFileName); + RefreshDocumentLB( &maDropFileName ); + } + } + } + else + { + return false; + } + } + else + { + return false; + } + } + + return true; +} + +void SdNavigatorWin::RefreshDocumentLB( const OUString* pDocName ) +{ + sal_Int32 nPos = 0; + + if( pDocName ) + { + if( mbDocImported ) + mxLbDocs->remove(0); + + mxLbDocs->insert_text(0, *pDocName); + mbDocImported = true; + } + else + { + nPos = mxLbDocs->get_active(); + if (nPos == -1) + nPos = 0; + + OUString aStr; + if( mbDocImported ) + aStr = mxLbDocs->get_text(0); + + mxLbDocs->clear(); + + // delete list of DocInfos + maDocList.clear(); + + if( mbDocImported ) + mxLbDocs->insert_text(0, aStr); + + ::sd::DrawDocShell* pCurrentDocShell = + dynamic_cast< ::sd::DrawDocShell *>( SfxObjectShell::Current() ); + SfxObjectShell* pSfxDocShell = SfxObjectShell::GetFirst([](const SfxObjectShell*){return true;}, false); + while( pSfxDocShell ) + { + ::sd::DrawDocShell* pDocShell = dynamic_cast< ::sd::DrawDocShell *>( pSfxDocShell ); + if( pDocShell && !pDocShell->IsInDestruction() && ( pDocShell->GetCreateMode() != SfxObjectCreateMode::EMBEDDED ) ) + { + NavDocInfo aInfo ; + aInfo.mpDocShell = pDocShell; + + SfxMedium *pMedium = pDocShell->GetMedium(); + aStr = pMedium ? pMedium->GetName() : OUString(); + if( !aStr.isEmpty() ) + aInfo.SetName( true ); + else + aInfo.SetName( false ); + // at the moment, we use the name of the shell again (i.e. + // without path) since Koose thinks it is an error if the path + // is shown in url notation! + aStr = pDocShell->GetName(); + + mxLbDocs->append_text(aStr); + + if( pDocShell == pCurrentDocShell ) + aInfo.SetActive( true ); + else + aInfo.SetActive( false ); + + maDocList.push_back( aInfo ); + } + pSfxDocShell = SfxObjectShell::GetNext( *pSfxDocShell, [](const SfxObjectShell*){return true;}, false ); + } + } + mxLbDocs->set_active(nPos); +} + +OUString SdNavigatorWin::GetDragTypeSdBmpId(NavigatorDragType eDT) +{ + switch( eDT ) + { + case NAVIGATOR_DRAGTYPE_NONE: + return OUString(); + case NAVIGATOR_DRAGTYPE_URL: + return BMP_HYPERLINK; + case NAVIGATOR_DRAGTYPE_EMBEDDED: + return BMP_EMBEDDED; + case NAVIGATOR_DRAGTYPE_LINK: + return BMP_LINK; + default: OSL_FAIL( "No resource for DragType available!" ); + } + return OUString(); +} + +NavDocInfo* SdNavigatorWin::GetDocInfo() +{ + sal_uInt32 nPos = mxLbDocs->get_active(); + + if( mbDocImported ) + { + if( nPos == 0 ) + { + return nullptr; + } + nPos--; + } + + return nPos < maDocList.size() ? &(maDocList[ nPos ]) : nullptr; +} + +/** + * catch ESCAPE in order to end show + */ +IMPL_LINK(SdNavigatorWin, KeyInputHdl, const KeyEvent&, rKEvt, bool) +{ + bool bConsumed = false; + + if (KEY_ESCAPE == rKEvt.GetKeyCode().GetCode()) + { + // during drag'n'drop we just stop the drag but do not close the navigator + if (!SdPageObjsTLV::IsInDrag() && !GetObjects().IsEditingActive()) + { + ::sd::ViewShellBase* pBase = ::sd::ViewShellBase::GetViewShellBase( mpBindings->GetDispatcher()->GetFrame()); + if (pBase) + sd::SlideShow::Stop(*pBase); + bConsumed = true; + } + } + + return bConsumed; +} + +void SdNavigatorWin::SetDragImage() +{ + mxToolbox->set_item_icon_name("dragmode", GetDragTypeSdBmpId(meDragType)); +} + +/** + * ControllerItem for Navigator + */ +SdNavigatorControllerItem::SdNavigatorControllerItem( + sal_uInt16 _nId, + SdNavigatorWin* pNavWin, + SfxBindings* _pBindings, + SdNavigatorWin::UpdateRequestFunctor aUpdateRequest) + : SfxControllerItem( _nId, *_pBindings ), + pNavigatorWin( pNavWin ), + maUpdateRequest(std::move(aUpdateRequest)) +{ +} + +void SdNavigatorControllerItem::StateChangedAtToolBoxControl( sal_uInt16 nSId, + SfxItemState eState, const SfxPoolItem* pItem ) +{ + if( eState < SfxItemState::DEFAULT || nSId != SID_NAVIGATOR_STATE ) + return; + + // only if doc in LB is the active + NavDocInfo* pInfo = pNavigatorWin->GetDocInfo(); + if( !(pInfo && pInfo->IsActive()) ) + return; + + if (::sd::DrawDocShell* pDrawDocShell = pInfo->GetDrawDocShell()) + { + const auto pDrawViewShell = + static_cast<::sd::DrawViewShell *>(pDrawDocShell->GetViewShell()); + if (pDrawViewShell) + { + pNavigatorWin->FreshTree(pDrawDocShell->GetDoc()); + bool bEditModePage(pDrawViewShell->GetEditMode() == EditMode::Page); + pNavigatorWin->mxToolbox->set_sensitive(bEditModePage); + pNavigatorWin->mxLbDocs->set_sensitive(bEditModePage); + pNavigatorWin->mxTlbObjects->set_sensitive(bEditModePage); + } + } + + const SfxUInt32Item& rStateItem = dynamic_cast<const SfxUInt32Item&>(*pItem); + NavState nState = static_cast<NavState>(rStateItem.GetValue()); + + // First + if (nState & NavState::BtnFirstEnabled && + !pNavigatorWin->mxToolbox->get_item_sensitive("first")) + pNavigatorWin->mxToolbox->set_item_sensitive("first", true); + if (nState & NavState::BtnFirstDisabled && + pNavigatorWin->mxToolbox->get_item_sensitive("first")) + pNavigatorWin->mxToolbox->set_item_sensitive("first", false); + + // Prev + if (nState & NavState::BtnPrevEnabled && + !pNavigatorWin->mxToolbox->get_item_sensitive("previous")) + pNavigatorWin->mxToolbox->set_item_sensitive("previous", true); + if (nState & NavState::BtnPrevDisabled && + pNavigatorWin->mxToolbox->get_item_sensitive("previous")) + pNavigatorWin->mxToolbox->set_item_sensitive("previous", false); + + // Last + if (nState & NavState::BtnLastEnabled && + !pNavigatorWin->mxToolbox->get_item_sensitive("last")) + pNavigatorWin->mxToolbox->set_item_sensitive("last", true); + if (nState & NavState::BtnLastDisabled && + pNavigatorWin->mxToolbox->get_item_sensitive("last")) + pNavigatorWin->mxToolbox->set_item_sensitive("last", false); + + // Next + if (nState & NavState::BtnNextEnabled && + !pNavigatorWin->mxToolbox->get_item_sensitive("next")) + pNavigatorWin->mxToolbox->set_item_sensitive("next", true); + if (nState & NavState::BtnNextDisabled && + pNavigatorWin->mxToolbox->get_item_sensitive("next")) + pNavigatorWin->mxToolbox->set_item_sensitive("next", false); + + if (nState & NavState::TableUpdate) + { + // InitTlb; is initiated by Slot + if (maUpdateRequest && !pNavigatorWin->GetObjects().get_treeview().has_focus()) + maUpdateRequest(); + } +} + +/** + * ControllerItem for Navigator to show page in TreeLB + */ +SdPageNameControllerItem::SdPageNameControllerItem( + sal_uInt16 _nId, + SdNavigatorWin* pNavWin, + SfxBindings* _pBindings) + : SfxControllerItem( _nId, *_pBindings ), + pNavigatorWin( pNavWin ) +{ +} + +void SdPageNameControllerItem::StateChangedAtToolBoxControl( sal_uInt16 nSId, + SfxItemState eState, const SfxPoolItem* pItem ) +{ + if( eState < SfxItemState::DEFAULT || nSId != SID_NAVIGATOR_PAGENAME ) + return; + + // only if doc in LB is the active + NavDocInfo* pInfo = pNavigatorWin->GetDocInfo(); + if( !(pInfo && pInfo->IsActive()) ) + return; + + // Without a test for marked objects the page name entry is not selected when there are no + // marked objects. The HasSelectedChildren test is required when in 'Named Shapes' mode in + // order to select the page name when none of the marked objects have a name. + bool bDrawViewHasMarkedObjects = false; + if (pInfo->GetDrawDocShell() && pInfo->GetDrawDocShell()->GetViewShell()) + { + const SdrView* pDrawView = pInfo->GetDrawDocShell()->GetViewShell()->GetDrawView(); + if (pDrawView && pDrawView->GetMarkedObjectCount()) + bDrawViewHasMarkedObjects = true; + } + + const SfxStringItem& rStateItem = dynamic_cast<const SfxStringItem&>(*pItem); + const OUString& aPageName = rStateItem.GetValue(); + + if (!bDrawViewHasMarkedObjects || !pNavigatorWin->mxTlbObjects->HasSelectedChildren(aPageName)) + { + if (pNavigatorWin->mxTlbObjects->get_selection_mode() == SelectionMode::Multiple) + { + // because otherwise it is always additional select + pNavigatorWin->mxTlbObjects->unselect_all(); + } + pNavigatorWin->mxTlbObjects->SelectEntry( aPageName ); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |