/* -*- 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace com::sun::star; // maximum values for UI static SCCOL SCNAV_MAXCOL(const ScSheetLimits& rLimits) { return rLimits.GetMaxColCount(); } static sal_Int32 SCNAV_COLDIGITS(const ScSheetLimits& rLimits) { return static_cast( floor( log10( static_cast(SCNAV_MAXCOL(rLimits)))) ) + 1; // 1...256...18278 } static sal_Int32 SCNAV_COLLETTERS(const ScSheetLimits& rLimits) { return ::ScColToAlpha(SCNAV_MAXCOL(rLimits)).getLength(); // A...IV...ZZZ } static SCROW SCNAV_MAXROW(const ScSheetLimits& rSheetLimits) { return rSheetLimits.GetMaxRowCount(); } void ScNavigatorDlg::ReleaseFocus() { SfxViewShell* pCurSh = SfxViewShell::Current(); if ( pCurSh ) { vcl::Window* pShellWnd = pCurSh->GetWindow(); if ( pShellWnd ) pShellWnd->GrabFocus(); } } namespace { SCCOL NumToAlpha(const ScSheetLimits& rSheetLimits, SCCOL nColNo, OUString& rStr) { if ( nColNo > SCNAV_MAXCOL(rSheetLimits) ) nColNo = SCNAV_MAXCOL(rSheetLimits); else if ( nColNo < 1 ) nColNo = 1; ::ScColToAlpha( rStr, nColNo - 1); return nColNo; } SCCOL AlphaToNum(const ScDocument& rDoc, OUString& rStr) { SCCOL nColumn = 0; if ( CharClass::isAsciiAlpha( rStr) ) { rStr = rStr.toAsciiUpperCase(); if (::AlphaToCol( rDoc, nColumn, rStr)) ++nColumn; if ( (rStr.getLength() > SCNAV_COLLETTERS(rDoc.GetSheetLimits())) || (nColumn > SCNAV_MAXCOL(rDoc.GetSheetLimits())) ) { nColumn = SCNAV_MAXCOL(rDoc.GetSheetLimits()); NumToAlpha( rDoc.GetSheetLimits(), nColumn, rStr ); } } else rStr.clear(); return nColumn; } SCCOL NumStrToAlpha(const ScSheetLimits& rSheetLimits, OUString& rStr) { SCCOL nColumn = 0; if ( CharClass::isAsciiNumeric(rStr) ) nColumn = NumToAlpha( rSheetLimits, static_cast(rStr.toInt32()), rStr ); else rStr.clear(); return nColumn; } } IMPL_LINK(ScNavigatorDlg, ParseRowInputHdl, int*, result, bool) { SCCOL nCol(0); OUString aStrCol = m_xEdCol->get_text(); if (!aStrCol.isEmpty()) { if (ScViewData* pData = GetViewData()) { ScDocument& rDoc = pData->GetDocument(); if ( CharClass::isAsciiNumeric(aStrCol) ) nCol = NumStrToAlpha( rDoc.GetSheetLimits(), aStrCol ); else nCol = AlphaToNum( rDoc, aStrCol ); } } *result = nCol; return true; } IMPL_LINK_NOARG(ScNavigatorDlg, ExecuteColHdl, weld::Entry&, bool) { ReleaseFocus(); SCROW nRow = m_xEdRow->get_value(); SCCOL nCol = m_xEdCol->get_value(); if ( (nCol > 0) && (nRow > 0) ) SetCurrentCell(nCol - 1, nRow - 1); return true; } IMPL_LINK_NOARG(ScNavigatorDlg, FormatRowOutputHdl, weld::SpinButton&, void) { OUString aStr; ::ScColToAlpha(aStr, m_xEdCol->get_value() - 1); m_xEdCol->set_text(aStr); } IMPL_LINK_NOARG(ScNavigatorDlg, ExecuteRowHdl, weld::Entry&, bool) { ReleaseFocus(); SCCOL nCol = m_xEdCol->get_value(); SCROW nRow = m_xEdRow->get_value(); if ( (nCol > 0) && (nRow > 0) ) SetCurrentCell(nCol - 1, nRow - 1); return true; } IMPL_LINK(ScNavigatorDlg, DocumentSelectHdl, weld::ComboBox&, rListBox, void) { ScNavigatorDlg::ReleaseFocus(); OUString aDocName = rListBox.get_active_text(); m_xLbEntries->SelectDoc(aDocName); } IMPL_LINK(ScNavigatorDlg, ToolBoxSelectHdl, const OUString&, rSelId, void) { // Switch the mode? if (rSelId == "contents" || rSelId == "scenarios") { NavListMode eOldMode = eListMode; NavListMode eNewMode; if (rSelId == "scenarios") { if (eOldMode == NAV_LMODE_SCENARIOS) eNewMode = NAV_LMODE_AREAS; else eNewMode = NAV_LMODE_SCENARIOS; } else // on/off { if (eOldMode == NAV_LMODE_NONE) eNewMode = NAV_LMODE_AREAS; else eNewMode = NAV_LMODE_NONE; } SetListMode(eNewMode); UpdateButtons(); } else if (rSelId == "dragmode") m_xTbxCmd2->set_menu_item_active(u"dragmode"_ustr, !m_xTbxCmd2->get_menu_item_active(u"dragmode"_ustr)); else { if (rSelId == "datarange") MarkDataArea(); else if (rSelId == "start") StartOfDataArea(); else if (rSelId == "end") EndOfDataArea(); else if (rSelId == "toggle") { m_xLbEntries->ToggleRoot(); UpdateButtons(); } } } IMPL_LINK(ScNavigatorDlg, ToolBoxDropdownClickHdl, const OUString&, rCommand, void) { if (!m_xTbxCmd2->get_menu_item_active(rCommand)) return; // the popup menu of the drop mode has to be called in the // click (button down) and not in the select (button up) if (rCommand != "dragmode") return; switch (GetDropMode()) { case 0: m_xDragModeMenu->set_active(u"hyperlink"_ustr, true); break; case 1: m_xDragModeMenu->set_active(u"link"_ustr, true); break; case 2: m_xDragModeMenu->set_active(u"copy"_ustr, true); break; } } IMPL_LINK(ScNavigatorDlg, MenuSelectHdl, const OUString&, rIdent, void) { if (rIdent == u"hyperlink") SetDropMode(0); else if (rIdent == u"link") SetDropMode(1); else if (rIdent == u"copy") SetDropMode(2); } void ScNavigatorDlg::UpdateButtons() { NavListMode eMode = eListMode; m_xTbxCmd2->set_item_active(u"scenarios"_ustr, eMode == NAV_LMODE_SCENARIOS); m_xTbxCmd1->set_item_active(u"contents"_ustr, eMode != NAV_LMODE_NONE); // the toggle button: if (eMode == NAV_LMODE_SCENARIOS || eMode == NAV_LMODE_NONE) { m_xTbxCmd2->set_item_sensitive(u"toggle"_ustr, false); m_xTbxCmd2->set_item_active(u"toggle"_ustr, false); } else { m_xTbxCmd2->set_item_sensitive(u"toggle"_ustr, true); bool bRootSet = m_xLbEntries->GetRootType() != ScContentId::ROOT; m_xTbxCmd2->set_item_active(u"toggle"_ustr, bRootSet); } OUString sImageId; switch (nDropMode) { case SC_DROPMODE_URL: sImageId = RID_BMP_DROP_URL; break; case SC_DROPMODE_LINK: sImageId = RID_BMP_DROP_LINK; break; case SC_DROPMODE_COPY: sImageId = RID_BMP_DROP_COPY; break; } m_xTbxCmd2->set_item_icon_name(u"dragmode"_ustr, sImageId); } ScNavigatorSettings::ScNavigatorSettings() : mnRootSelected(ScContentId::ROOT) , mnChildSelected(SC_CONTENT_NOCHILD) { maExpandedVec.fill(false); } class ScNavigatorWin : public SfxNavigator { private: std::unique_ptr m_xNavigator; public: ScNavigatorWin(SfxBindings* _pBindings, SfxChildWindow* pMgr, vcl::Window* pParent, SfxChildWinInfo* pInfo); virtual void StateChanged(StateChangedType nStateChange) override; virtual void dispose() override { m_xNavigator.reset(); SfxNavigator::dispose(); } virtual ~ScNavigatorWin() override { disposeOnce(); } }; ScNavigatorWin::ScNavigatorWin(SfxBindings* _pBindings, SfxChildWindow* _pMgr, vcl::Window* _pParent, SfxChildWinInfo* pInfo) : SfxNavigator(_pBindings, _pMgr, _pParent, pInfo) { m_xNavigator = std::make_unique(_pBindings, m_xContainer.get(), this); SetMinOutputSizePixel(GetOptimalSize()); } ScNavigatorDlg::ScNavigatorDlg(SfxBindings* pB, weld::Widget* pParent, SfxNavigator* pNavigatorDlg) : PanelLayout(pParent, u"NavigatorPanel"_ustr, u"modules/scalc/ui/navigatorpanel.ui"_ustr) , rBindings(*pB) , m_xEdCol(m_xBuilder->weld_spin_button(u"column"_ustr)) , m_xEdRow(m_xBuilder->weld_spin_button(u"row"_ustr)) , m_xTbxCmd1(m_xBuilder->weld_toolbar(u"toolbox1"_ustr)) , m_xTbxCmd2(m_xBuilder->weld_toolbar(u"toolbox2"_ustr)) , m_xLbEntries(new ScContentTree(m_xBuilder->weld_tree_view(u"contentbox"_ustr), this)) , m_xScenarioBox(m_xBuilder->weld_widget(u"scenariobox"_ustr)) , m_xWndScenarios(new ScScenarioWindow(*m_xBuilder, ScResId(SCSTR_QHLP_SCEN_LISTBOX), ScResId(SCSTR_QHLP_SCEN_COMMENT))) , m_xLbDocuments(m_xBuilder->weld_combo_box(u"documents"_ustr)) , m_xDragModeMenu(m_xBuilder->weld_menu(u"dragmodemenu"_ustr)) , m_xNavigatorDlg(pNavigatorDlg) , aContentIdle("ScNavigatorDlg aContentIdle") , aStrActiveWin(ScResId(SCSTR_ACTIVEWIN)) , pViewData(nullptr ) , eListMode(NAV_LMODE_NONE) , nDropMode(SC_DROPMODE_URL) , nCurCol(0) , nCurRow(0) , nCurTab(0) { UpdateInitShow(); UpdateSheetLimits(); m_xEdRow->set_width_chars(5); //max rows is 1,000,000, which is too long for typical use m_xEdRow->connect_activate(LINK(this, ScNavigatorDlg, ExecuteRowHdl)); m_xEdCol->connect_activate(LINK(this, ScNavigatorDlg, ExecuteColHdl)); m_xEdCol->connect_output(LINK(this, ScNavigatorDlg, FormatRowOutputHdl)); m_xEdCol->connect_input(LINK(this, ScNavigatorDlg, ParseRowInputHdl)); m_xTbxCmd1->connect_clicked(LINK(this, ScNavigatorDlg, ToolBoxSelectHdl)); m_xTbxCmd2->connect_clicked(LINK(this, ScNavigatorDlg, ToolBoxSelectHdl)); m_xTbxCmd2->set_item_menu(u"dragmode"_ustr, m_xDragModeMenu.get()); m_xDragModeMenu->connect_activate(LINK(this, ScNavigatorDlg, MenuSelectHdl)); m_xTbxCmd2->connect_menu_toggled(LINK(this, ScNavigatorDlg, ToolBoxDropdownClickHdl)); ScNavipiCfg& rCfg = ScModule::get()->GetNavipiCfg(); nDropMode = rCfg.GetDragMode(); m_xLbDocuments->set_size_request(42, -1); // set a nominal width so it takes width of surroundings m_xLbDocuments->connect_changed(LINK(this, ScNavigatorDlg, DocumentSelectHdl)); aStrActive = " (" + ScResId(SCSTR_ACTIVE) + ")"; // " (active)" aStrNotActive = " (" + ScResId(SCSTR_NOTACTIVE) + ")"; // " (not active)" rBindings.ENTERREGISTRATIONS(); mvBoundItems[0].reset(new ScNavigatorControllerItem(SID_CURRENTCELL,*this,rBindings)); mvBoundItems[1].reset(new ScNavigatorControllerItem(SID_CURRENTTAB,*this,rBindings)); mvBoundItems[2].reset(new ScNavigatorControllerItem(SID_CURRENTDOC,*this,rBindings)); mvBoundItems[3].reset(new ScNavigatorControllerItem(SID_SELECT_SCENARIO,*this,rBindings)); rBindings.LEAVEREGISTRATIONS(); StartListening( *(SfxGetpApp()) ); StartListening( rBindings ); // was a category chosen as root? ScContentId nLastRoot = rCfg.GetRootType(); if ( nLastRoot != ScContentId::ROOT ) m_xLbEntries->SetRootType( nLastRoot ); GetDocNames(nullptr); UpdateButtons(); UpdateColumn(); UpdateRow(); UpdateTable(nullptr); m_xLbEntries->hide(); m_xScenarioBox->hide(); aContentIdle.SetInvokeHandler( LINK( this, ScNavigatorDlg, TimeHdl ) ); aContentIdle.SetPriority( TaskPriority::LOWEST ); m_xLbEntries->SetNavigatorDlgFlag(true); // if scenario was active, switch on NavListMode eNavMode = static_cast(rCfg.GetListMode()); if (eNavMode == NAV_LMODE_SCENARIOS) m_xTbxCmd2->set_item_active(u"scenarios"_ustr, true); else eNavMode = NAV_LMODE_AREAS; SetListMode(eNavMode); if(comphelper::LibreOfficeKit::isActive()) { m_xBuilder->weld_container(u"gridbuttons"_ustr)->hide(); m_xLbDocuments->hide(); } } weld::Window* ScNavigatorDlg::GetFrameWeld() const { if (m_xNavigatorDlg) return m_xNavigatorDlg->GetFrameWeld(); return PanelLayout::GetFrameWeld(); } void ScNavigatorDlg::UpdateSheetLimits() { if (ScViewData* pData = GetViewData()) { ScDocument& rDoc = pData->GetDocument(); m_xEdRow->set_range(1, SCNAV_MAXROW(rDoc.GetSheetLimits())); m_xEdCol->set_range(1, SCNAV_MAXCOL(rDoc.GetSheetLimits())); m_xEdCol->set_width_chars(SCNAV_COLDIGITS(rDoc.GetSheetLimits())); // 1...256...18278 or A...IV...ZZZ } } void ScNavigatorDlg::UpdateInitShow() { // When the navigator is displayed in the sidebar, or is otherwise // docked, it has the whole deck to fill. Therefore hide the button that // hides all controls below the top two rows of buttons. m_xTbxCmd1->set_item_visible(u"contents"_ustr, ParentIsFloatingWindow(m_xNavigatorDlg)); } void ScNavigatorWin::StateChanged(StateChangedType nStateChange) { SfxNavigator::StateChanged(nStateChange); if (nStateChange == StateChangedType::InitShow) m_xNavigator->UpdateInitShow(); } ScNavigatorDlg::~ScNavigatorDlg() { aContentIdle.Stop(); for (auto & p : mvBoundItems) p.reset(); moMarkArea.reset(); EndListening( *(SfxGetpApp()) ); EndListening( rBindings ); m_xEdCol.reset(); m_xEdRow.reset(); m_xTbxCmd1.reset(); m_xTbxCmd2.reset(); m_xDragModeMenu.reset(); m_xLbEntries.reset(); m_xWndScenarios.reset(); m_xScenarioBox.reset(); m_xLbDocuments.reset(); } void ScNavigatorDlg::Notify( SfxBroadcaster&, const SfxHint& rHint ) { if (rHint.GetId() == SfxHintId::ThisIsAnSfxEventHint) { // This is for when the document might change and the navigator // wants to update for the new document, which isn't a scenario // that happens in online. if (comphelper::LibreOfficeKit::isActive()) return; const SfxEventHint& rEventHint = static_cast(rHint); if (rEventHint.GetEventId() == SfxEventHintId::ActivateDoc) { UpdateSheetLimits(); bool bRefreshed = m_xLbEntries->ActiveDocChanged(); // UpdateAll just possibly calls Refresh (and always // ContentUpdated) so if ActiveDocChanged already called Refresh // skip re-calling it if (bRefreshed) ContentUpdated(); else UpdateAll(); } } else { const SfxHintId nHintId = rHint.GetId(); if (nHintId == SfxHintId::ScDocNameChanged) { m_xLbEntries->ActiveDocChanged(); } else if (NAV_LMODE_NONE == eListMode) { // Table not any more } else { switch ( nHintId ) { case SfxHintId::ScTablesChanged: m_xLbEntries->Refresh( ScContentId::TABLE ); break; case SfxHintId::ScDbAreasChanged: m_xLbEntries->Refresh( ScContentId::DBAREA ); break; case SfxHintId::ScAreasChanged: m_xLbEntries->Refresh( ScContentId::RANGENAME ); break; case SfxHintId::ScDrawChanged: m_xLbEntries->Refresh( ScContentId::GRAPHIC ); m_xLbEntries->Refresh( ScContentId::OLEOBJECT ); m_xLbEntries->Refresh( ScContentId::DRAWING ); aContentIdle.Start(); // Do not search notes immediately break; case SfxHintId::ScAreaLinksChanged: m_xLbEntries->Refresh( ScContentId::AREALINK ); break; // SfxHintId::DocChanged not only at document change case SfxHintId::ScNavigatorUpdateAll: UpdateAll(); break; case SfxHintId::ScDataChanged: case SfxHintId::ScAnyDataChanged: aContentIdle.Start(); // Do not search notes immediately break; case SfxHintId::ScSelectionChanged: UpdateSelection(); break; default: break; } } } } IMPL_LINK( ScNavigatorDlg, TimeHdl, Timer*, pIdle, void ) { if ( pIdle != &aContentIdle ) return; m_xLbEntries->Refresh( ScContentId::NOTE ); } void ScNavigatorDlg::SetDropMode(sal_uInt16 nNew) { nDropMode = nNew; UpdateButtons(); ScNavipiCfg& rCfg = ScModule::get()->GetNavipiCfg(); rCfg.SetDragMode(nDropMode); } void ScNavigatorDlg::SetCurrentCell( SCCOL nColNo, SCROW nRowNo ) { if ((nColNo+1 == nCurCol) && (nRowNo+1 == nCurRow)) return; // SID_CURRENTCELL == Item #0 clear cache, so it's possible // setting the current cell even in combined areas mvBoundItems[0]->ClearCache(); ScAddress aScAddress( nColNo, nRowNo, 0 ); OUString aAddr(aScAddress.Format(ScRefFlags::ADDR_ABS)); bool bUnmark = false; if ( GetViewData() ) bUnmark = !pViewData->GetMarkData().IsCellMarked( nColNo, nRowNo ); SfxStringItem aPosItem( SID_CURRENTCELL, aAddr ); SfxBoolItem aUnmarkItem( FN_PARAM_1, bUnmark ); // cancel selection rBindings.GetDispatcher()->ExecuteList(SID_CURRENTCELL, SfxCallMode::SYNCHRON | SfxCallMode::RECORD, { &aPosItem, &aUnmarkItem }); } void ScNavigatorDlg::SetCurrentCellStr( const OUString& rName ) { mvBoundItems[0]->ClearCache(); SfxStringItem aNameItem( SID_CURRENTCELL, rName ); rBindings.GetDispatcher()->ExecuteList(SID_CURRENTCELL, SfxCallMode::SYNCHRON | SfxCallMode::RECORD, { &aNameItem }); } void ScNavigatorDlg::SetCurrentTable( SCTAB nTabNo ) { if ( nTabNo != nCurTab ) { // Table for basic is base-1 SfxUInt16Item aTabItem( SID_CURRENTTAB, static_cast(nTabNo) + 1 ); rBindings.GetDispatcher()->ExecuteList(SID_CURRENTTAB, SfxCallMode::SYNCHRON | SfxCallMode::RECORD, { &aTabItem }); } } void ScNavigatorDlg::SetCurrentTableStr( std::u16string_view rName ) { if (!GetViewData()) return; ScDocument& rDoc = pViewData->GetDocument(); SCTAB nCount = rDoc.GetTableCount(); OUString aTabName; SCTAB nLastSheet = 0; for (SCTAB i = 0; iExecuteList( SID_CURRENTOBJECT, SfxCallMode::SYNCHRON | SfxCallMode::RECORD, { &aNameItem }); } void ScNavigatorDlg::SetCurrentDoc( const OUString& rDocName ) // activate { SfxStringItem aDocItem( SID_CURRENTDOC, rDocName ); rBindings.GetDispatcher()->ExecuteList( SID_CURRENTDOC, SfxCallMode::SYNCHRON | SfxCallMode::RECORD, { &aDocItem }); } void ScNavigatorDlg::UpdateSelection() { ScTabViewShell* pViewSh = GetTabViewShell(); if( !pViewSh ) return; uno::Reference< drawing::XShapes > xShapes = pViewSh->getSelectedXShapes(); if( !xShapes ) return; uno::Reference< container::XIndexAccess > xIndexAccess( xShapes, uno::UNO_QUERY_THROW ); if( xIndexAccess->getCount() > 1 ) return; uno::Reference< drawing::XShape > xShape; if( xIndexAccess->getByIndex(0) >>= xShape ) { uno::Reference< container::XNamed > xNamed( xShape, uno::UNO_QUERY_THROW ); OUString sName = xNamed->getName(); if (!sName.isEmpty()) { m_xLbEntries->SelectEntryByName( ScContentId::DRAWING, sName ); } } } ScTabViewShell* ScNavigatorDlg::GetTabViewShell() { return dynamic_cast( SfxViewShell::Current() ); } ScNavigatorSettings* ScNavigatorDlg::GetNavigatorSettings() { // Don't store the settings pointer here, because the settings belong to // the view, and the view may be closed while the navigator is open (reload). // If the pointer is cached here again later for performance reasons, it has to // be forgotten when the view is closed. ScTabViewShell* pViewSh = GetTabViewShell(); return pViewSh ? pViewSh->GetNavigatorSettings() : nullptr; } ScViewData* ScNavigatorDlg::GetViewData() { ScTabViewShell* pViewSh = GetTabViewShell(); pViewData = pViewSh ? &pViewSh->GetViewData() : nullptr; return pViewData; } void ScNavigatorDlg::UpdateColumn( const SCCOL* pCol ) { if ( pCol ) nCurCol = *pCol; else if ( GetViewData() ) nCurCol = pViewData->GetCurX() + 1; m_xEdCol->set_value(nCurCol); } void ScNavigatorDlg::UpdateRow( const SCROW* pRow ) { if ( pRow ) nCurRow = *pRow; else if ( GetViewData() ) nCurRow = pViewData->GetCurY() + 1; m_xEdRow->set_value(nCurRow); } void ScNavigatorDlg::UpdateTable( const SCTAB* pTab ) { if ( pTab ) nCurTab = *pTab; else if ( GetViewData() ) nCurTab = pViewData->GetTabNo(); } void ScNavigatorDlg::UpdateAll() { switch (eListMode) { case NAV_LMODE_AREAS: m_xLbEntries->Refresh(); break; case NAV_LMODE_NONE: //! ??? break; default: break; } ContentUpdated(); // not again } void ScNavigatorDlg::ContentUpdated() { aContentIdle.Stop(); } void ScNavigatorDlg::SetListMode(NavListMode eMode) { if (eMode != eListMode) { bool bForceParentResize = ParentIsFloatingWindow(m_xNavigatorDlg) && (eMode == NAV_LMODE_NONE || eListMode == NAV_LMODE_NONE); SfxNavigator* pNav = bForceParentResize ? m_xNavigatorDlg.get() : nullptr; if (pNav && eMode == NAV_LMODE_NONE) //save last normal size on minimizing aExpandedSize = pNav->GetSizePixel(); eListMode = eMode; switch (eMode) { case NAV_LMODE_NONE: ShowList(false); break; case NAV_LMODE_AREAS: m_xLbEntries->Refresh(); ShowList(true); break; case NAV_LMODE_SCENARIOS: ShowScenarios(); break; } UpdateButtons(); if (eMode != NAV_LMODE_NONE) { ScNavipiCfg& rCfg = ScModule::get()->GetNavipiCfg(); rCfg.SetListMode( static_cast(eMode) ); } if (pNav) { pNav->InvalidateChildSizeCache(); Size aOptimalSize(pNav->GetOptimalSize()); Size aNewSize(pNav->GetOutputSizePixel()); aNewSize.setHeight( eMode == NAV_LMODE_NONE ? aOptimalSize.Height() : aExpandedSize.Height() ); pNav->SetMinOutputSizePixel(aOptimalSize); pNav->SetOutputSizePixel(aNewSize); } } if (moMarkArea) UnmarkDataArea(); } void ScNavigatorDlg::ShowList(bool bShow) { if (bShow) { m_xLbEntries->show(); m_xLbDocuments->show(); } else { m_xLbEntries->hide(); m_xLbDocuments->hide(); } m_xScenarioBox->hide(); } void ScNavigatorDlg::ShowScenarios() { rBindings.Invalidate( SID_SELECT_SCENARIO ); rBindings.Update( SID_SELECT_SCENARIO ); m_xScenarioBox->show(); m_xLbDocuments->show(); m_xLbEntries->hide(); } // documents for Dropdown-Listbox void ScNavigatorDlg::GetDocNames( const OUString* pManualSel ) { m_xLbDocuments->clear(); m_xLbDocuments->freeze(); ScDocShell* pCurrentSh = dynamic_cast( SfxObjectShell::Current() ); OUString aSelEntry; SfxObjectShell* pSh = SfxObjectShell::GetFirst(); while ( pSh ) { if ( dynamic_cast( pSh) != nullptr ) { OUString aName = pSh->GetTitle(); OUString aEntry = aName; if (pSh == pCurrentSh) aEntry += aStrActive; else aEntry += aStrNotActive; m_xLbDocuments->append_text(aEntry); if ( pManualSel ? ( aName == *pManualSel ) : ( pSh == pCurrentSh ) ) aSelEntry = aEntry; // complete entry for selection } pSh = SfxObjectShell::GetNext( *pSh ); } m_xLbDocuments->append_text(aStrActiveWin); m_xLbDocuments->thaw(); m_xLbDocuments->set_active_text(aSelEntry); } void ScNavigatorDlg::MarkDataArea() { ScTabViewShell* pViewSh = GetTabViewShell(); if ( !pViewSh ) return; if ( !moMarkArea ) moMarkArea.emplace(); pViewSh->MarkDataArea(); const ScRange& aMarkRange = pViewSh->GetViewData().GetMarkData().GetMarkArea(); moMarkArea->nColStart = aMarkRange.aStart.Col(); moMarkArea->nRowStart = aMarkRange.aStart.Row(); moMarkArea->nColEnd = aMarkRange.aEnd.Col(); moMarkArea->nRowEnd = aMarkRange.aEnd.Row(); moMarkArea->nTab = aMarkRange.aStart.Tab(); } void ScNavigatorDlg::UnmarkDataArea() { ScTabViewShell* pViewSh = GetTabViewShell(); if ( pViewSh ) { pViewSh->Unmark(); moMarkArea.reset(); } } void ScNavigatorDlg::StartOfDataArea() { // pMarkArea evaluate ??? if ( GetViewData() ) { ScMarkData& rMark = pViewData->GetMarkData(); const ScRange& aMarkRange = rMark.GetMarkArea(); SCCOL nCol = aMarkRange.aStart.Col(); SCROW nRow = aMarkRange.aStart.Row(); if ( (nCol+1 != m_xEdCol->get_value()) || (nRow+1 != m_xEdRow->get_value()) ) SetCurrentCell( nCol, nRow ); } } void ScNavigatorDlg::EndOfDataArea() { // pMarkArea evaluate ??? if ( GetViewData() ) { ScMarkData& rMark = pViewData->GetMarkData(); const ScRange& aMarkRange = rMark.GetMarkArea(); SCCOL nCol = aMarkRange.aEnd.Col(); SCROW nRow = aMarkRange.aEnd.Row(); if ( (nCol+1 != m_xEdCol->get_value()) || (nRow+1 != m_xEdRow->get_value()) ) SetCurrentCell( nCol, nRow ); } } SFX_IMPL_DOCKINGWINDOW(ScNavigatorWrapper, SID_NAVIGATOR); ScNavigatorWrapper::ScNavigatorWrapper(vcl::Window *_pParent, sal_uInt16 nId, SfxBindings* pBindings, SfxChildWinInfo* pInfo) : SfxNavigatorWrapper(_pParent, nId) { SetWindow(VclPtr::Create(pBindings, this, _pParent, pInfo)); Initialize(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */