Files
libreoffice/sc/source/ui/navipi/navipi.cxx
Caolán McNamara b37ac48935 Resolves: tdf#105450 calc navigator gets 0 height on toggle off/on when docked
Change-Id: Icd346cdf0a208ccaeddd77e6803f4f906361324c
2017-01-24 15:12:32 +00:00

1043 lines
28 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 <rangelst.hxx>
#include <sfx2/app.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/event.hxx>
#include <sfx2/navigat.hxx>
#include <svl/stritem.hxx>
#include <svl/urlbmk.hxx>
#include <vcl/builderfactory.hxx>
#include <vcl/settings.hxx>
#include <unotools/charclass.hxx>
#include <stdlib.h>
#include "viewdata.hxx"
#include "tabvwsh.hxx"
#include "docsh.hxx"
#include "document.hxx"
#include "dbdata.hxx"
#include "rangenam.hxx"
#include "rangeutl.hxx"
#include "popmenu.hxx"
#include "sc.hrc"
#include "scresid.hxx"
#include "scmod.hxx"
#include "navicfg.hxx"
#include "navcitem.hxx"
#include "navipi.hxx"
#include "navsett.hxx"
#include "markdata.hxx"
#include <algorithm>
// maximum values for UI
#define SCNAV_MAXCOL (MAXCOLCOUNT)
// macro is sufficient since only used in ctor
#define SCNAV_COLDIGITS (static_cast<sal_Int32>( floor( log10( static_cast<double>(SCNAV_MAXCOL)))) + 1) // 1...256...18278
// precomputed constant because it is used in every change of spin button field
static const sal_Int32 SCNAV_COLLETTERS = ::ScColToAlpha(SCNAV_MAXCOL).getLength(); // A...IV...ZZZ
#define SCNAV_MAXROW (MAXROWCOUNT)
void ScNavigatorDlg::ReleaseFocus()
{
SfxViewShell* pCurSh = SfxViewShell::Current();
if ( pCurSh )
{
vcl::Window* pShellWnd = pCurSh->GetWindow();
if ( pShellWnd )
pShellWnd->GrabFocus();
}
}
ColumnEdit::ColumnEdit(Window* pParent, WinBits nWinBits)
: SpinField(pParent, nWinBits)
, nCol(0)
{
SetMaxTextLen(SCNAV_COLDIGITS); // 1...256...18278 or A...IV...ZZZ
}
ColumnEdit::~ColumnEdit()
{
disposeOnce();
}
VCL_BUILDER_FACTORY_ARGS(ColumnEdit, WB_BORDER | WB_SPIN | WB_REPEAT | WB_RIGHT)
bool ColumnEdit::EventNotify( NotifyEvent& rNEvt )
{
bool bHandled = SpinField::EventNotify(rNEvt);
MouseNotifyEvent nType = rNEvt.GetType();
if ( nType == MouseNotifyEvent::KEYINPUT )
{
const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
vcl::KeyCode aCode = pKEvt->GetKeyCode();
if ( !aCode.IsMod1() && !aCode.IsMod2() )
{
//! Input Validation (only alphanumerics, max 2-3 digits)
//! was before VCL not forwarded keyinput
//! rethink this!!!
if ( aCode.GetCode() == KEY_RETURN )
{
ScNavigatorDlg::ReleaseFocus();
ExecuteCol();
bHandled = true;
}
}
}
else if ( nType == MouseNotifyEvent::LOSEFOCUS ) // LoseFocus not called at VCL
EvalText(); // nCol set
return bHandled;
}
void ColumnEdit::LoseFocus()
{
EvalText();
}
void ColumnEdit::dispose()
{
xDlg.clear();
SpinField::dispose();
}
void ColumnEdit::Up()
{
nCol++;
if ( nCol <= SCNAV_MAXCOL )
SetCol( nCol );
else
nCol--;
}
void ColumnEdit::Down()
{
if ( nCol>1 )
SetCol( nCol-1 );
}
void ColumnEdit::First()
{
nCol = 1;
SetText(OUString('A'));
}
void ColumnEdit::Last()
{
OUString aStr;
nCol = NumToAlpha( SCNAV_MAXCOL, aStr );
SetText( aStr );
}
void ColumnEdit::EvalText()
{
OUString aStrCol = GetText();
if (!aStrCol.isEmpty())
{
// nKeyGroup is no longer set at VCL, in cause of lack of keyinput
if ( CharClass::isAsciiNumeric(aStrCol) )
nCol = NumStrToAlpha( aStrCol );
else
nCol = AlphaToNum( aStrCol );
}
else
nCol = 0;
SetText( aStrCol );
}
void ColumnEdit::ExecuteCol()
{
SCROW nRow = xDlg->aEdRow->GetRow();
EvalText(); // setzt nCol
if ( (nCol > 0) && (nRow > 0) )
xDlg->SetCurrentCell(nCol - 1, nRow - 1);
}
void ColumnEdit::SetCol( SCCOL nColNo )
{
OUString aStr;
if ( nColNo == 0 )
{
nCol = 0;
SetText( aStr );
}
else
{
nColNo = NumToAlpha( nColNo, aStr );
nCol = nColNo;
SetText( aStr );
}
}
SCCOL ColumnEdit::AlphaToNum( OUString& rStr )
{
SCCOL nColumn = 0;
if ( CharClass::isAsciiAlpha( rStr) )
{
rStr = rStr.toAsciiUpperCase();
if (::AlphaToCol( nColumn, rStr))
++nColumn;
if ( (rStr.getLength() > SCNAV_COLLETTERS) || (nColumn > SCNAV_MAXCOL) )
{
nColumn = SCNAV_MAXCOL;
NumToAlpha( nColumn, rStr );
}
}
else
rStr.clear();
return nColumn;
}
SCCOL ColumnEdit::NumStrToAlpha( OUString& rStr )
{
SCCOL nColumn = 0;
if ( CharClass::isAsciiNumeric(rStr) )
nColumn = NumToAlpha( (SCCOL)rStr.toInt32(), rStr );
else
rStr.clear();
return nColumn;
}
SCCOL ColumnEdit::NumToAlpha( SCCOL nColNo, OUString& rStr )
{
if ( nColNo > SCNAV_MAXCOL )
nColNo = SCNAV_MAXCOL;
else if ( nColNo < 1 )
nColNo = 1;
::ScColToAlpha( rStr, nColNo - 1);
return nColNo;
}
RowEdit::RowEdit(Window* pParent, WinBits nWinBits)
: NumericField(pParent, nWinBits)
{
SetMax(SCNAV_MAXROW);
SetLast(SCNAV_MAXROW);
}
RowEdit::~RowEdit()
{
disposeOnce();
}
VCL_BUILDER_FACTORY_ARGS(RowEdit, WB_BORDER | WB_SPIN | WB_REPEAT | WB_RIGHT)
bool RowEdit::EventNotify( NotifyEvent& rNEvt )
{
bool bHandled = NumericField::EventNotify(rNEvt);
if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
{
const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
vcl::KeyCode aCode = pKEvt->GetKeyCode();
if ( aCode.GetCode() == KEY_RETURN && !aCode.IsMod1() && !aCode.IsMod2() )
{
ScNavigatorDlg::ReleaseFocus();
ExecuteRow();
bHandled = true;
}
}
return bHandled;
}
void RowEdit::LoseFocus()
{
}
void RowEdit::dispose()
{
xDlg.clear();
NumericField::dispose();
}
Size RowEdit::GetOptimalSize() const
{
//max rows is 1,000,000, which is too long for typical use
return CalcMinimumSizeForText("1,000");
}
void RowEdit::ExecuteRow()
{
SCCOL nCol = xDlg->aEdCol->GetCol();
SCROW nRow = (SCROW)GetValue();
if ( (nCol > 0) && (nRow > 0) )
xDlg->SetCurrentCell(nCol - 1, nRow - 1);
}
IMPL_LINK(ScNavigatorDlg, DocumentSelectHdl, ListBox&, rListBox, void)
{
ScNavigatorDlg::ReleaseFocus();
OUString aDocName = rListBox.GetSelectEntry();
aLbEntries->SelectDoc(aDocName);
}
IMPL_LINK(ScNavigatorDlg, ToolBoxSelectHdl, ToolBox*, pToolBox, void)
{
sal_uInt16 nSelId = pToolBox->GetCurItemId();
// Modus umschalten ?
if (nSelId == nZoomId || nSelId == nScenarioId)
{
NavListMode eOldMode = eListMode;
NavListMode eNewMode;
if (nSelId == nScenarioId)
{
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 (nSelId == nDataId)
MarkDataArea();
else if (nSelId == nUpId)
StartOfDataArea();
else if (nSelId == nDownId)
EndOfDataArea();
else if (nSelId == nChangeRootId)
{
aLbEntries->ToggleRoot();
UpdateButtons();
}
}
}
IMPL_LINK(ScNavigatorDlg, ToolBoxDropdownClickHdl, ToolBox *, pToolBox, void)
{
// the popup menue of the drop modus has to be called in the
// click (button down) and not in the select (button up)
if (pToolBox->GetCurItemId() == nDragModeId)
{
ScopedVclPtrInstance<ScPopupMenu> aPop(ScResId(RID_POPUP_DROPMODE));
aPop->CheckItem(RID_DROPMODE_URL + GetDropMode());
aPop->Execute(pToolBox, pToolBox->GetItemRect(nDragModeId), PopupMenuFlags::ExecuteDown);
sal_uInt16 nId = aPop->GetSelected();
pToolBox->EndSelection(); // before SetDropMode (SetDropMode calls SetItemImage)
if (nId >= RID_DROPMODE_URL && nId <= RID_DROPMODE_COPY)
SetDropMode(nId - RID_DROPMODE_URL);
}
}
void ScNavigatorDlg::UpdateButtons()
{
NavListMode eMode = eListMode;
aTbxCmd->CheckItem(nScenarioId, eMode == NAV_LMODE_SCENARIOS);
aTbxCmd->CheckItem(nZoomId, eMode != NAV_LMODE_NONE);
// Umschalten-Button:
if (eMode == NAV_LMODE_SCENARIOS || eMode == NAV_LMODE_NONE)
{
aTbxCmd->EnableItem(nChangeRootId, false);
aTbxCmd->CheckItem(nChangeRootId, false);
}
else
{
aTbxCmd->EnableItem(nChangeRootId);
bool bRootSet = aLbEntries->GetRootType() != ScContentId::ROOT;
aTbxCmd->CheckItem(nChangeRootId, bRootSet);
}
sal_uInt16 nImageId = 0;
switch (nDropMode)
{
case SC_DROPMODE_URL:
nImageId = RID_BMP_DROP_URL;
break;
case SC_DROPMODE_LINK:
nImageId = RID_BMP_DROP_LINK;
break;
case SC_DROPMODE_COPY:
nImageId = RID_BMP_DROP_COPY;
break;
}
aTbxCmd->SetItemImage(nDragModeId, Image(BitmapEx(ScResId(nImageId))));
}
ScNavigatorSettings::ScNavigatorSettings()
: mnRootSelected(ScContentId::ROOT)
, mnChildSelected(SC_CONTENT_NOCHILD)
{
}
SFX_IMPL_CHILDWINDOWCONTEXT( ScNavigatorDialogWrapper, SID_NAVIGATOR )
ScNavigatorDialogWrapper::ScNavigatorDialogWrapper(vcl::Window* pParent,
sal_uInt16 nId,
SfxBindings* pBind,
SfxChildWinInfo* /* pInfo */)
: SfxChildWindowContext(nId)
{
pNavigator = VclPtr<ScNavigatorDlg>::Create(pBind, pParent);
if (SfxNavigator* pNav = dynamic_cast<SfxNavigator*>(pParent))
pNav->SetMinOutputSizePixel(pNavigator->GetOptimalSize());
SetWindow(pNavigator);
}
#define CTRL_ITEMS 4
#define REGISTER_SLOT(i,id) \
ppBoundItems[i]=new ScNavigatorControllerItem(id,*this,rBindings);
ScNavigatorDlg::ScNavigatorDlg(SfxBindings* pB, vcl::Window* pParent)
: PanelLayout(pParent, "NavigatorPanel", "modules/scalc/ui/navigatorpanel.ui", nullptr)
, rBindings(*pB)
, aStrDragMode(ScResId(SCSTR_DRAGMODE))
, aStrDisplay(ScResId(SCSTR_DISPLAY))
, aStrActiveWin(ScResId(SCSTR_ACTIVEWIN))
, pMarkArea(nullptr)
, pViewData(nullptr )
, eListMode(NAV_LMODE_NONE)
, nDropMode(SC_DROPMODE_URL)
, nCurCol(0)
, nCurRow(0)
, nCurTab(0)
{
get(aLbDocuments, "documents");
get(aEdCol, "column");
aEdCol->SetNavigatorDlg(this);
get(aEdRow, "row");
aEdRow->SetNavigatorDlg(this);
get(aTbxCmd, "toolbox");
aTbxCmd->SetSelectHdl(LINK(this, ScNavigatorDlg, ToolBoxSelectHdl));
aTbxCmd->SetDropdownClickHdl(LINK(this, ScNavigatorDlg, ToolBoxDropdownClickHdl));
nZoomId = aTbxCmd->GetItemId("contents");
nChangeRootId = aTbxCmd->GetItemId("toggle");
nDragModeId = aTbxCmd->GetItemId("dragmode");
aTbxCmd->SetItemBits(nDragModeId, aTbxCmd->GetItemBits(nDragModeId) | ToolBoxItemBits::DROPDOWNONLY);
nScenarioId = aTbxCmd->GetItemId("scenarios");
nDownId = aTbxCmd->GetItemId("end");
nUpId = aTbxCmd->GetItemId("start");
nAreaId = aTbxCmd->GetItemId("datarange");
get(aContentBox, "contentbox");
aLbEntries = VclPtr<ScContentTree>::Create(aContentBox, this);
aLbEntries->set_hexpand(true);
aLbEntries->set_vexpand(true);
aLbEntries->Show();
get(aScenarioBox, "scenariobox");
aWndScenarios = VclPtr<ScScenarioWindow>::Create(aScenarioBox,
ScResId(SCSTR_QHLP_SCEN_LISTBOX), ScResId(SCSTR_QHLP_SCEN_COMMENT));
aWndScenarios->set_hexpand(true);
aWndScenarios->set_vexpand(true);
aWndScenarios->Show();
ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
nDropMode = rCfg.GetDragMode();
aTbxCmd->InsertBreak(3);
aTbxCmd->SetLineCount(2);
aLbDocuments->SetDropDownLineCount(9);
aLbDocuments->SetSelectHdl(LINK(this, ScNavigatorDlg, DocumentSelectHdl));
aStrActive = " (" + OUString(ScResId(SCSTR_ACTIVE)) + ")"; // " (active)"
aStrNotActive = " (" + OUString(ScResId(SCSTR_NOTACTIVE)) + ")"; // " (not active)"
aStrHidden = " (" + OUString(ScResId(SCSTR_HIDDEN)) + ")"; // " (hidden)"
aTitleBase = GetText();
ppBoundItems = new ScNavigatorControllerItem* [CTRL_ITEMS];
rBindings.ENTERREGISTRATIONS();
REGISTER_SLOT( 0, SID_CURRENTCELL );
REGISTER_SLOT( 1, SID_CURRENTTAB );
REGISTER_SLOT( 2, SID_CURRENTDOC );
REGISTER_SLOT( 3, SID_SELECT_SCENARIO );
rBindings.LEAVEREGISTRATIONS();
StartListening( *(SfxGetpApp()) );
StartListening( rBindings );
aLbEntries->InitWindowBits(true);
aLbEntries->SetSpaceBetweenEntries(0);
aLbEntries->SetSelectionMode( SelectionMode::Single );
aLbEntries->SetDragDropMode( DragDropMode::CTRL_MOVE |
DragDropMode::CTRL_COPY |
DragDropMode::ENABLE_TOP );
// was a category chosen as root?
ScContentId nLastRoot = rCfg.GetRootType();
if ( nLastRoot != ScContentId::ROOT )
aLbEntries->SetRootType( nLastRoot );
aLbEntries->Refresh();
GetDocNames(nullptr);
UpdateButtons();
UpdateColumn();
UpdateRow();
UpdateTable(nullptr);
aContentBox->Hide();
aScenarioBox->Hide();
aContentIdle.SetInvokeHandler( LINK( this, ScNavigatorDlg, TimeHdl ) );
aContentIdle.SetPriority( TaskPriority::LOWEST );
if (!SfxChildWindowContext::GetFloatingWindow(GetParent()))
{
// 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.
aTbxCmd->RemoveItem(aTbxCmd->GetItemPos(nZoomId));
}
aLbEntries->SetNavigatorDlgFlag(true);
// if scenario was active, switch on
NavListMode eNavMode = (NavListMode) rCfg.GetListMode();
if (eNavMode == NAV_LMODE_SCENARIOS)
aTbxCmd->CheckItem(nScenarioId);
else
eNavMode = NAV_LMODE_AREAS;
SetListMode(eNavMode);
aExpandedSize = GetOptimalSize();
}
ScNavigatorDlg::~ScNavigatorDlg()
{
disposeOnce();
}
void ScNavigatorDlg::dispose()
{
aContentIdle.Stop();
for (sal_uInt16 i = 0; i < CTRL_ITEMS; ++i)
delete ppBoundItems[i];
delete [] ppBoundItems;
delete pMarkArea;
EndListening( *(SfxGetpApp()) );
EndListening( rBindings );
aEdCol.clear();
aEdRow.clear();
aTbxCmd.clear();
aLbEntries.disposeAndClear();
aContentBox.clear();
aWndScenarios.disposeAndClear();
aScenarioBox.clear();
aLbDocuments.clear();
PanelLayout::dispose();
}
void ScNavigatorDlg::Notify( SfxBroadcaster&, const SfxHint& rHint )
{
if (const SfxEventHint* pHint = dynamic_cast<const SfxEventHint*>(&rHint))
{
if (pHint->GetEventId() == SfxEventHintId::ActivateDoc)
{
aLbEntries->ActiveDocChanged();
UpdateAll();
}
}
else
{
const SfxHintId nHintId = rHint.GetId();
if (nHintId == SfxHintId::ScDocNameChanged)
{
aLbEntries->ActiveDocChanged();
}
else if (NAV_LMODE_NONE == eListMode)
{
// Table not any more
}
else
{
switch ( nHintId )
{
case SfxHintId::ScTablesChanged:
aLbEntries->Refresh( ScContentId::TABLE );
break;
case SfxHintId::ScDbAreasChanged:
aLbEntries->Refresh( ScContentId::DBAREA );
break;
case SfxHintId::ScAreasChanged:
aLbEntries->Refresh( ScContentId::RANGENAME );
break;
case SfxHintId::ScDrawChanged:
aLbEntries->Refresh( ScContentId::GRAPHIC );
aLbEntries->Refresh( ScContentId::OLEOBJECT );
aLbEntries->Refresh( ScContentId::DRAWING );
break;
case SfxHintId::ScAreaLinksChanged:
aLbEntries->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::ScKillEditView:
aLbEntries->ObjectFresh( ScContentId::OLEOBJECT );
aLbEntries->ObjectFresh( ScContentId::DRAWING );
aLbEntries->ObjectFresh( ScContentId::GRAPHIC );
break;
default:
break;
}
}
}
}
IMPL_LINK( ScNavigatorDlg, TimeHdl, Timer*, pIdle, void )
{
if ( pIdle != &aContentIdle )
return;
aLbEntries->Refresh( ScContentId::NOTE );
}
void ScNavigatorDlg::SetDropMode(sal_uInt16 nNew)
{
nDropMode = nNew;
UpdateButtons();
ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
rCfg.SetDragMode(nDropMode);
}
void ScNavigatorDlg::SetCurrentCell( SCCOL nColNo, SCROW nRowNo )
{
if ( (nColNo+1 != nCurCol) || (nRowNo+1 != nCurRow) )
{
// SID_CURRENTCELL == Item #0 clear cache, so it's possible
// setting the current cell even in combined areas
ppBoundItems[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 selektion
rBindings.GetDispatcher()->ExecuteList(SID_CURRENTCELL,
SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
{ &aPosItem, &aUnmarkItem });
}
}
void ScNavigatorDlg::SetCurrentCellStr( const OUString& rName )
{
ppBoundItems[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<sal_uInt16>(nTabNo) + 1 );
rBindings.GetDispatcher()->ExecuteList(SID_CURRENTTAB,
SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
{ &aTabItem });
}
}
void ScNavigatorDlg::SetCurrentTableStr( const OUString& rName )
{
if (!GetViewData()) return;
ScDocument* pDoc = pViewData->GetDocument();
SCTAB nCount = pDoc->GetTableCount();
OUString aTabName;
SCTAB nLastSheet = 0;
for (SCTAB i = 0; i<nCount; i++)
{
pDoc->GetName(i, aTabName);
if (aTabName.equals(rName))
{
// Check if this is a Scenario sheet and if so select the sheet
// where it belongs to, which is the previous non-Scenario sheet.
if (pDoc->IsScenario(i))
{
SetCurrentTable(nLastSheet);
return;
}
else
{
SetCurrentTable(i);
return;
}
}
else
{
if (!pDoc->IsScenario(i))
nLastSheet = i;
}
}
}
void ScNavigatorDlg::SetCurrentObject( const OUString& rName )
{
SfxStringItem aNameItem( SID_CURRENTOBJECT, rName );
rBindings.GetDispatcher()->ExecuteList( 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 });
}
ScTabViewShell* ScNavigatorDlg::GetTabViewShell()
{
return dynamic_cast<ScTabViewShell*>( 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;
}
bool ScNavigatorDlg::GetViewData()
{
ScTabViewShell* pViewSh = GetTabViewShell();
pViewData = pViewSh ? &pViewSh->GetViewData() : nullptr;
return ( pViewData != nullptr );
}
void ScNavigatorDlg::UpdateColumn( const SCCOL* pCol )
{
if ( pCol )
nCurCol = *pCol;
else if ( GetViewData() )
nCurCol = pViewData->GetCurX() + 1;
aEdCol->SetCol( nCurCol );
CheckDataArea();
}
void ScNavigatorDlg::UpdateRow( const SCROW* pRow )
{
if ( pRow )
nCurRow = *pRow;
else if ( GetViewData() )
nCurRow = pViewData->GetCurY() + 1;
aEdRow->SetRow( nCurRow );
CheckDataArea();
}
void ScNavigatorDlg::UpdateTable( const SCTAB* pTab )
{
if ( pTab )
nCurTab = *pTab;
else if ( GetViewData() )
nCurTab = pViewData->GetTabNo();
CheckDataArea();
}
void ScNavigatorDlg::UpdateAll()
{
switch (eListMode)
{
case NAV_LMODE_AREAS:
aLbEntries->Refresh();
break;
case NAV_LMODE_NONE:
//! ???
break;
default:
break;
}
aContentIdle.Stop(); // not again
}
void ScNavigatorDlg::SetListMode(NavListMode eMode)
{
if (eMode != eListMode)
{
bool bForceParentResize = SfxChildWindowContext::GetFloatingWindow(GetParent()) &&
(eMode == NAV_LMODE_NONE || eListMode == NAV_LMODE_NONE);
SfxNavigator* pNav = bForceParentResize ? dynamic_cast<SfxNavigator*>(GetParent()) : nullptr;
if (pNav && eMode == NAV_LMODE_NONE) //save last normal size on minimizing
aExpandedSize = GetSizePixel();
eListMode = eMode;
switch (eMode)
{
case NAV_LMODE_NONE:
ShowList(false);
break;
case NAV_LMODE_AREAS:
aLbEntries->Refresh();
ShowList(true);
break;
case NAV_LMODE_SCENARIOS:
ShowScenarios();
break;
}
UpdateButtons();
if (eMode != NAV_LMODE_NONE)
{
ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
rCfg.SetListMode( (sal_uInt16) eMode );
}
if (pNav)
{
Size aOptimalSize(GetOptimalSize());
Size aNewSize(pNav->GetOutputSizePixel());
aNewSize.Height() = eMode == NAV_LMODE_NONE ? aOptimalSize.Height() : aExpandedSize.Height();
pNav->SetMinOutputSizePixel(aOptimalSize);
pNav->SetOutputSizePixel(aNewSize);
}
}
if (pMarkArea)
UnmarkDataArea();
}
void ScNavigatorDlg::ShowList(bool bShow)
{
if (bShow)
{
aContentBox->Show();
aLbDocuments->Show();
}
else
{
aContentBox->Hide();
aLbDocuments->Hide();
}
aScenarioBox->Hide();
}
void ScNavigatorDlg::ShowScenarios()
{
rBindings.Invalidate( SID_SELECT_SCENARIO );
rBindings.Update( SID_SELECT_SCENARIO );
aScenarioBox->Show();
aLbDocuments->Show();
aContentBox->Hide();
}
// documents for Dropdown-Listbox
void ScNavigatorDlg::GetDocNames( const OUString* pManualSel )
{
aLbDocuments->Clear();
aLbDocuments->SetUpdateMode( false );
ScDocShell* pCurrentSh = dynamic_cast<ScDocShell*>( SfxObjectShell::Current() );
OUString aSelEntry;
SfxObjectShell* pSh = SfxObjectShell::GetFirst();
while ( pSh )
{
if ( dynamic_cast<const ScDocShell*>( pSh) != nullptr )
{
OUString aName = pSh->GetTitle();
OUString aEntry = aName;
if (pSh == pCurrentSh)
aEntry += aStrActive;
else
aEntry += aStrNotActive;
aLbDocuments->InsertEntry( aEntry );
if ( pManualSel ? ( aName == *pManualSel )
: ( pSh == pCurrentSh ) )
aSelEntry = aEntry; // complete entry for selection
}
pSh = SfxObjectShell::GetNext( *pSh );
}
aLbDocuments->InsertEntry( aStrActiveWin );
OUString aHidden = aLbEntries->GetHiddenTitle();
if (!aHidden.isEmpty())
{
OUString aEntry = aHidden;
aEntry += aStrHidden;
aLbDocuments->InsertEntry( aEntry );
if ( pManualSel && aHidden == *pManualSel )
aSelEntry = aEntry;
}
aLbDocuments->SetUpdateMode( true );
aLbDocuments->SelectEntry( aSelEntry );
}
void ScNavigatorDlg::MarkDataArea()
{
ScTabViewShell* pViewSh = GetTabViewShell();
if ( pViewSh )
{
if ( !pMarkArea )
pMarkArea = new ScArea;
pViewSh->MarkDataArea();
ScRange aMarkRange;
pViewSh->GetViewData().GetMarkData().GetMarkArea(aMarkRange);
pMarkArea->nColStart = aMarkRange.aStart.Col();
pMarkArea->nRowStart = aMarkRange.aStart.Row();
pMarkArea->nColEnd = aMarkRange.aEnd.Col();
pMarkArea->nRowEnd = aMarkRange.aEnd.Row();
pMarkArea->nTab = aMarkRange.aStart.Tab();
}
}
void ScNavigatorDlg::UnmarkDataArea()
{
ScTabViewShell* pViewSh = GetTabViewShell();
if ( pViewSh )
{
pViewSh->Unmark();
DELETEZ( pMarkArea );
}
}
void ScNavigatorDlg::CheckDataArea()
{
if (aTbxCmd->IsItemChecked(nDataId) && pMarkArea)
{
if ( nCurTab != pMarkArea->nTab
|| nCurCol < pMarkArea->nColStart+1
|| nCurCol > pMarkArea->nColEnd+1
|| nCurRow < pMarkArea->nRowStart+1
|| nCurRow > pMarkArea->nRowEnd+1 )
{
aTbxCmd->SetItemState(nDataId, TriState(TRISTATE_TRUE));
aTbxCmd->TriggerItem(nDataId);
}
}
}
void ScNavigatorDlg::StartOfDataArea()
{
// pMarkArea evaluate ???
if ( GetViewData() )
{
ScMarkData& rMark = pViewData->GetMarkData();
ScRange aMarkRange;
rMark.GetMarkArea( aMarkRange );
SCCOL nCol = aMarkRange.aStart.Col();
SCROW nRow = aMarkRange.aStart.Row();
if ( (nCol+1 != aEdCol->GetCol()) || (nRow+1 != aEdRow->GetRow()) )
SetCurrentCell( nCol, nRow );
}
}
void ScNavigatorDlg::EndOfDataArea()
{
// pMarkArea evaluate ???
if ( GetViewData() )
{
ScMarkData& rMark = pViewData->GetMarkData();
ScRange aMarkRange;
rMark.GetMarkArea( aMarkRange );
SCCOL nCol = aMarkRange.aEnd.Col();
SCROW nRow = aMarkRange.aEnd.Row();
if ( (nCol+1 != aEdCol->GetCol()) || (nRow+1 != aEdRow->GetRow()) )
SetCurrentCell( nCol, nRow );
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */