/* -*- 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 <scitems.hxx>
#include <editeng/editview.hxx>
#include <editeng/editeng.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/request.hxx>
#include <svl/stritem.hxx>
#include <vcl/weld.hxx>
#include <sfx2/app.hxx>
#include <globstr.hrc>
#include <scresid.hxx>
#include <scmod.hxx>
#include <appoptio.hxx>
#include <tabvwsh.hxx>
#include <document.hxx>
#include <sc.hrc>
#include <docsh.hxx>
#include <reffact.hxx>
#include <uiitems.hxx>
#include <autoform.hxx>
#include <autofmt.hxx>
#include <cellsh.hxx>
#include <inputhdl.hxx>
#include <editable.hxx>
#include <markdata.hxx>
#include <scabstdlg.hxx>
#include <columnspanset.hxx>
#include <memory>
#define IS_EDITMODE() GetViewData()->HasEditView( GetViewData()->GetActivePart() )
using sc::HMMToTwips;
using sc::TwipsToEvenHMM;
void ScCellShell::Execute( SfxRequest& rReq )
{
ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
SfxBindings& rBindings = pTabViewShell->GetViewFrame()->GetBindings();
ScModule* pScMod = SC_MOD();
const SfxItemSet* pReqArgs = rReq.GetArgs();
sal_uInt16 nSlot = rReq.GetSlot();
if (nSlot != SID_CURRENTCELL) // this comes with MouseButtonUp
pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
if ( IS_EDITMODE() )
{
switch ( nSlot )
{
// when opening a reference-dialog the subshell may not be switched
// (on closing the dialog StopEditShell is called)
case SID_OPENDLG_FUNCTION:
// inplace leads to trouble with EditShell ...
//! cannot always be switched ????
if (!pTabViewShell->GetViewFrame()->GetFrame().IsInPlace())
pTabViewShell->SetDontSwitch(true); // do not switch off EditShell
SAL_FALLTHROUGH;
case FID_CELL_FORMAT:
case SID_ENABLE_HYPHENATION:
case SID_DATA_SELECT:
case SID_OPENDLG_CONSOLIDATE:
case SID_OPENDLG_SOLVE:
case SID_OPENDLG_OPTSOLVER:
pScMod->InputEnterHandler();
pTabViewShell->UpdateInputHandler();
pTabViewShell->SetDontSwitch(false);
break;
default:
break;
}
}
switch ( nSlot )
{
case SID_STATUS_SELMODE:
if ( pReqArgs )
{
/* 0: STD Click cancels selection
* 1: ER Click extends selection
* 2: ERG Click defines further selection
*/
sal_uInt16 nMode = static_cast<const SfxUInt16Item&>(pReqArgs->Get( nSlot )).GetValue();
switch ( nMode )
{
case 1: nMode = KEY_SHIFT; break;
case 2: nMode = KEY_MOD1; break; // control-key
case 0:
default:
nMode = 0;
}
pTabViewShell->LockModifiers( nMode );
}
else
{
// no arguments (also executed by double click on the status bar controller):
// advance to next selection mode
sal_uInt16 nModifiers = pTabViewShell->GetLockedModifiers();
switch ( nModifiers )
{
case KEY_SHIFT: nModifiers = KEY_MOD1; break; // EXT -> ADD
case KEY_MOD1: nModifiers = 0; break; // ADD -> STD
default: nModifiers = KEY_SHIFT; break; // STD -> EXT
}
pTabViewShell->LockModifiers( nModifiers );
}
rBindings.Invalidate( SID_STATUS_SELMODE );
rReq.Done();
break;
// SID_STATUS_SELMODE_NORM is not used ???
case SID_STATUS_SELMODE_NORM:
pTabViewShell->LockModifiers( 0 );
rBindings.Invalidate( SID_STATUS_SELMODE );
break;
// SID_STATUS_SELMODE_ERG / SID_STATUS_SELMODE_ERW as toggles:
case SID_STATUS_SELMODE_ERG:
if ( pTabViewShell->GetLockedModifiers() & KEY_MOD1 )
pTabViewShell->LockModifiers( 0 );
else
pTabViewShell->LockModifiers( KEY_MOD1 );
rBindings.Invalidate( SID_STATUS_SELMODE );
break;
case SID_STATUS_SELMODE_ERW:
if ( pTabViewShell->GetLockedModifiers() & KEY_SHIFT )
pTabViewShell->LockModifiers( 0 );
else
pTabViewShell->LockModifiers( KEY_SHIFT );
rBindings.Invalidate( SID_STATUS_SELMODE );
break;
case SID_ENTER_STRING:
{
if ( pReqArgs )
{
OUString aStr( static_cast<const SfxStringItem&>(pReqArgs->
Get( SID_ENTER_STRING )).GetValue() );
const SfxPoolItem* pDontCommitItem;
bool bCommit = true;
if (pReqArgs->HasItem(FN_PARAM_1, &pDontCommitItem))
bCommit = !(static_cast<const SfxBoolItem*>(pDontCommitItem)->GetValue());
ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pTabViewShell );
if (bCommit)
{
pTabViewShell->EnterData( GetViewData()->GetCurX(),
GetViewData()->GetCurY(),
GetViewData()->GetTabNo(),
aStr );
}
else
{
SC_MOD()->SetInputMode(SC_INPUT_TABLE);
EditView* pTableView = pHdl->GetActiveView();
pHdl->DataChanging();
if (pTableView)
pTableView->GetEditEngine()->SetText(aStr);
pHdl->DataChanged();
SC_MOD()->SetInputMode(SC_INPUT_NONE);
}
if ( !pHdl || !pHdl->IsInEnterHandler() )
{
// UpdateInputHandler is needed after the cell content
// has changed, but if called from EnterHandler, UpdateInputHandler
// will be called later when moving the cursor.
pTabViewShell->UpdateInputHandler();
}
rReq.Done();
// no GrabFocus here, as otherwise on a Mac the tab jumps before the
// sideview, when the input was not finished
// (GrabFocus is called in KillEditView)
}
}
break;
case SID_INSERT_MATRIX:
{
if ( pReqArgs )
{
OUString aStr = static_cast<const SfxStringItem&>(pReqArgs->
Get( SID_INSERT_MATRIX )).GetValue();
ScDocument* pDoc = GetViewData()->GetDocument();
pTabViewShell->EnterMatrix( aStr, pDoc->GetGrammar() );
rReq.Done();
}
}
break;
case FID_INPUTLINE_ENTER:
case FID_INPUTLINE_BLOCK:
case FID_INPUTLINE_MATRIX:
{
if( pReqArgs == nullptr ) //XXX temporary HACK to avoid GPF
break;
const ScInputStatusItem* pStatusItem
= static_cast<const ScInputStatusItem*>(&pReqArgs->
Get( FID_INPUTLINE_STATUS ));
ScAddress aCursorPos = pStatusItem->GetPos();
OUString aString = pStatusItem->GetString();
const EditTextObject* pData = pStatusItem->GetEditData();
if (pData)
{
if (nSlot == FID_INPUTLINE_BLOCK)
{
pTabViewShell->EnterBlock( aString, pData );
}
else if ( !aString.isEmpty() && ( aString[0] == '=' || aString[0] == '+' || aString[0] == '-' ) )
{
pTabViewShell->EnterData( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), aString, pData );
}
else
{
pTabViewShell->EnterData(aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), *pData);
}
}
else
{
if (nSlot == FID_INPUTLINE_ENTER)
{
if (
aCursorPos.Col() == GetViewData()->GetCurX() &&
aCursorPos.Row() == GetViewData()->GetCurY() &&
aCursorPos.Tab() == GetViewData()->GetTabNo()
)
{
SfxStringItem aItem( SID_ENTER_STRING, aString );
const SfxPoolItem* aArgs[2];
aArgs[0] = &aItem;
aArgs[1] = nullptr;
rBindings.Execute( SID_ENTER_STRING, aArgs );
}
else
{
pTabViewShell->EnterData( aCursorPos.Col(),
aCursorPos.Row(),
aCursorPos.Tab(),
aString );
rReq.Done();
}
}
else if (nSlot == FID_INPUTLINE_BLOCK)
{
pTabViewShell->EnterBlock( aString, nullptr );
rReq.Done();
}
else
{
ScDocument* pDoc = GetViewData()->GetDocument();
pTabViewShell->EnterMatrix( aString, pDoc->GetGrammar() );
rReq.Done();
}
}
pTabViewShell->SetAutoSpellData(
aCursorPos.Col(), aCursorPos.Row(), pStatusItem->GetMisspellRanges());
// no GrabFocus here, as otherwise on a Mac the tab jumps before the
// sideview, when the input was not finished
// (GrabFocus is called in KillEditView)
}
break;
case SID_OPENDLG_FUNCTION:
{
sal_uInt16 nId = SID_OPENDLG_FUNCTION;
SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
pScMod->SetRefDialog( nId, pWnd == nullptr );
rReq.Ignore();
}
break;
case SID_OPENDLG_CONSOLIDATE:
{
sal_uInt16 nId = ScConsolidateDlgWrapper::GetChildWindowId();
SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
pScMod->SetRefDialog( nId, pWnd == nullptr );
}
break;
case FID_CELL_FORMAT:
{
if ( pReqArgs != nullptr )
{
// set cell attribute without dialog:
std::unique_ptr<SfxItemSet> pEmptySet(
new SfxItemSet( *pReqArgs->GetPool(),
svl::Items<ATTR_PATTERN_START,
ATTR_PATTERN_END>{} ));
std::unique_ptr<SfxItemSet> pNewSet(
new SfxItemSet( *pReqArgs->GetPool(),
svl::Items<ATTR_PATTERN_START,
ATTR_PATTERN_END>{} ));
const SfxPoolItem* pAttr = nullptr;
sal_uInt16 nWhich = 0;
for ( nWhich=ATTR_PATTERN_START; nWhich<=ATTR_PATTERN_END; nWhich++ )
if ( pReqArgs->GetItemState( nWhich, true, &pAttr ) == SfxItemState::SET )
pNewSet->Put( *pAttr );
pTabViewShell->ApplyAttributes( pNewSet.get(), pEmptySet.get() );
pNewSet.reset();
pEmptySet.reset();
rReq.Done();
}
else
{
pTabViewShell->ExecuteCellFormatDlg( rReq, "" );
}
}
break;
case SID_ENABLE_HYPHENATION:
pTabViewShell->ExecuteCellFormatDlg(rReq, "alignment");
break;
case SID_PROPERTY_PANEL_CELLTEXT_DLG:
pTabViewShell->ExecuteCellFormatDlg( rReq, "font" );
break;
case SID_CELL_FORMAT_BORDER:
pTabViewShell->ExecuteCellFormatDlg( rReq, "borders" );
break;
case SID_CHAR_DLG_EFFECT:
pTabViewShell->ExecuteCellFormatDlg( rReq, "fonteffects" );
break;
case SID_OPENDLG_SOLVE:
{
sal_uInt16 nId = ScSolverDlgWrapper::GetChildWindowId();
SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
pScMod->SetRefDialog( nId, pWnd == nullptr );
}
break;
case SID_OPENDLG_OPTSOLVER:
{
sal_uInt16 nId = ScOptSolverDlgWrapper::GetChildWindowId();
SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
pScMod->SetRefDialog( nId, pWnd == nullptr );
}
break;
case SID_OPENDLG_TABOP:
{
sal_uInt16 nId = ScTabOpDlgWrapper::GetChildWindowId();
SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
pScMod->SetRefDialog( nId, pWnd == nullptr );
}
break;
case SID_SCENARIOS:
{
ScDocument* pDoc = GetViewData()->GetDocument();
ScMarkData& rMark = GetViewData()->GetMarkData();
SCTAB nTab = GetViewData()->GetTabNo();
if ( pDoc->IsScenario(nTab) )
{
rMark.MarkToMulti();
if ( rMark.IsMultiMarked() )
{
bool bExtend = rReq.IsAPI();
if (!bExtend)
{
vcl::Window* pWin = pTabViewShell->GetDialogParent();
std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(pWin ? pWin->GetFrameWeld() : nullptr,
VclMessageType::Question, VclButtonsType::YesNo,
ScResId(STR_UPDATE_SCENARIO)));
xQueryBox->set_default_response(RET_YES);
bExtend = xQueryBox->run() == RET_YES;
}
if (bExtend)
{
pTabViewShell->ExtendScenario();
rReq.Done();
}
}
else if( ! rReq.IsAPI() )
{
vcl::Window* pWin = pTabViewShell->GetDialogParent();
std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pWin ? pWin->GetFrameWeld() : nullptr,
VclMessageType::Warning, VclButtonsType::Ok,
ScResId(STR_NOAREASELECTED)));
xErrorBox->run();
}
}
else
{
rMark.MarkToMulti();
if ( rMark.IsMultiMarked() )
{
SCTAB i=1;
OUString aBaseName;
OUString aName;
OUString aComment;
Color aColor;
ScScenarioFlags nFlags;
OUString aTmp;
pDoc->GetName(nTab, aTmp);
aBaseName = aTmp + "_" + ScResId(STR_SCENARIO) + "_";
// first test, if the prefix is recognised as valid,
// else avoid only doubles
bool bPrefix = ScDocument::ValidTabName( aBaseName );
OSL_ENSURE(bPrefix, "invalid sheet name");
while ( pDoc->IsScenario(nTab+i) )
i++;
bool bValid;
SCTAB nDummy;
do
{
aName = aBaseName + OUString::number( i );
if (bPrefix)
bValid = pDoc->ValidNewTabName( aName );
else
bValid = !pDoc->GetTable( aName, nDummy );
++i;
}
while ( !bValid && i <= MAXTAB + 2 );
if ( pReqArgs != nullptr )
{
OUString aArgName;
OUString aArgComment;
const SfxPoolItem* pItem;
if ( pReqArgs->GetItemState( SID_SCENARIOS, true, &pItem ) == SfxItemState::SET )
aArgName = static_cast<const SfxStringItem*>(pItem)->GetValue();
if ( pReqArgs->GetItemState( SID_NEW_TABLENAME, true, &pItem ) == SfxItemState::SET )
aArgComment = static_cast<const SfxStringItem*>(pItem)->GetValue();
aColor = COL_LIGHTGRAY; // Default
nFlags = ScScenarioFlags::NONE; // not TwoWay
pTabViewShell->MakeScenario( aArgName, aArgComment, aColor, nFlags );
if( ! rReq.IsAPI() )
rReq.Done();
}
else
{
bool bSheetProtected = pDoc->IsTabProtected(nTab);
ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
ScopedVclPtr<AbstractScNewScenarioDlg> pNewDlg(pFact->CreateScNewScenarioDlg(pTabViewShell->GetDialogParent(), aName, false, bSheetProtected));
if ( pNewDlg->Execute() == RET_OK )
{
pNewDlg->GetScenarioData( aName, aComment, aColor, nFlags );
pTabViewShell->MakeScenario( aName, aComment, aColor, nFlags );
rReq.AppendItem( SfxStringItem( SID_SCENARIOS, aName ) );
rReq.AppendItem( SfxStringItem( SID_NEW_TABLENAME, aComment ) );
rReq.Done();
}
}
}
else if( ! rReq.IsAPI() )
{
pTabViewShell->ErrorMessage(STR_ERR_NEWSCENARIO);
}
}
}
break;
case SID_SELECTALL:
{
pTabViewShell->SelectAll();
rReq.Done();
}
break;
case FID_ROW_HEIGHT:
{
const SfxPoolItem* pRow;
const SfxPoolItem* pHeight;
sal_uInt16 nHeight;
if ( pReqArgs && pReqArgs->HasItem( FID_ROW_HEIGHT, &pHeight ) &&
pReqArgs->HasItem( FN_PARAM_1, &pRow ) )
{
std::vector<sc::ColRowSpan> aRanges;
SCCOLROW nRow = static_cast<const SfxInt32Item*>(pRow)->GetValue() - 1;
nHeight = static_cast<const SfxUInt16Item*>(pHeight)->GetValue();
ScMarkData& rMark = GetViewData()->GetMarkData();
if ( rMark.IsRowMarked( static_cast<SCROW>(nRow) ) )
{
aRanges = rMark.GetMarkedRowSpans();
}
else
{
aRanges.emplace_back(nRow, nRow);
}
pTabViewShell->SetWidthOrHeight(false, aRanges, SC_SIZE_DIRECT, HMMToTwips(nHeight));
}
else if ( pReqArgs && pReqArgs->HasItem( FID_ROW_HEIGHT, &pHeight ) )
{
nHeight = static_cast<const SfxUInt16Item*>(pHeight)->GetValue();
// #101390#; the value of the macro is in HMM so use HMMToTwips to convert
pTabViewShell->SetMarkedWidthOrHeight( false, SC_SIZE_DIRECT,
sal::static_int_cast<sal_uInt16>( HMMToTwips(nHeight) ) );
if( ! rReq.IsAPI() )
rReq.Done();
}
else
{
ScViewData* pData = GetViewData();
FieldUnit eMetric = SC_MOD()->GetAppOptions().GetAppMetric();
sal_uInt16 nCurHeight = pData->GetDocument()->
GetRowHeight( pData->GetCurY(),
pData->GetTabNo() );
ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
ScopedVclPtr<AbstractScMetricInputDlg> pDlg(pFact->CreateScMetricInputDlg(
pTabViewShell->GetFrameWeld(), "RowHeightDialog",
nCurHeight, ScGlobal::nStdRowHeight,
eMetric, 2, MAX_ROW_HEIGHT));
if ( pDlg->Execute() == RET_OK )
{
long nVal = pDlg->GetInputValue();
pTabViewShell->SetMarkedWidthOrHeight( false, SC_SIZE_DIRECT, static_cast<sal_uInt16>(nVal) );
// #101390#; the value of the macro should be in HMM so use TwipsToEvenHMM to convert
rReq.AppendItem( SfxUInt16Item( FID_ROW_HEIGHT, static_cast<sal_uInt16>(TwipsToEvenHMM(nVal)) ) );
rReq.Done();
}
}
}
break;
case FID_ROW_OPT_HEIGHT:
{
if ( pReqArgs )
{
const SfxUInt16Item& rUInt16Item = static_cast<const SfxUInt16Item&>(pReqArgs->Get( FID_ROW_OPT_HEIGHT ));
// #101390#; the value of the macro is in HMM so use HMMToTwips to convert
pTabViewShell->SetMarkedWidthOrHeight( false, SC_SIZE_OPTIMAL,
sal::static_int_cast<sal_uInt16>( HMMToTwips(rUInt16Item.GetValue()) ) );
ScGlobal::nLastRowHeightExtra = rUInt16Item.GetValue();
if( ! rReq.IsAPI() )
rReq.Done();
}
else
{
FieldUnit eMetric = SC_MOD()->GetAppOptions().GetAppMetric();
ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
ScopedVclPtr<AbstractScMetricInputDlg> pDlg(pFact->CreateScMetricInputDlg(
pTabViewShell->GetFrameWeld(), "OptimalRowHeightDialog",
ScGlobal::nLastRowHeightExtra, 0, eMetric, 1, MAX_EXTRA_HEIGHT));
if ( pDlg->Execute() == RET_OK )
{
long nVal = pDlg->GetInputValue();
pTabViewShell->SetMarkedWidthOrHeight( false, SC_SIZE_OPTIMAL, static_cast<sal_uInt16>(nVal) );
ScGlobal::nLastRowHeightExtra = nVal;
// #101390#; the value of the macro should be in HMM so use TwipsToEvenHMM to convert
rReq.AppendItem( SfxUInt16Item( FID_ROW_OPT_HEIGHT, static_cast<sal_uInt16>(TwipsToEvenHMM(nVal)) ) );
rReq.Done();
}
}
}
break;
case FID_COL_WIDTH:
{
const SfxPoolItem* pColumn;
const SfxPoolItem* pWidth;
sal_uInt16 nWidth;
if ( pReqArgs && pReqArgs->HasItem( FID_COL_WIDTH, &pWidth ) &&
pReqArgs->HasItem( FN_PARAM_1, &pColumn ) )
{
std::vector<sc::ColRowSpan> aRanges;
SCCOLROW nColumn = static_cast<const SfxUInt16Item*>(pColumn)->GetValue() - 1;
nWidth = static_cast<const SfxUInt16Item*>(pWidth)->GetValue();
ScMarkData& rMark = GetViewData()->GetMarkData();
if ( rMark.IsColumnMarked( static_cast<SCCOL>(nColumn) ) )
{
aRanges = rMark.GetMarkedColSpans();
}
else
{
aRanges.emplace_back(nColumn, nColumn);
}
pTabViewShell->SetWidthOrHeight(true, aRanges, SC_SIZE_DIRECT, HMMToTwips(nWidth));
}
else if ( pReqArgs && pReqArgs->HasItem( FID_COL_WIDTH, &pWidth ) )
{
nWidth = static_cast<const SfxUInt16Item*>(pWidth)->GetValue();
// #101390#; the value of the macro is in HMM so use HMMToTwips to convert
pTabViewShell->SetMarkedWidthOrHeight( true, SC_SIZE_DIRECT,
sal::static_int_cast<sal_uInt16>( HMMToTwips(nWidth) ) );
if( ! rReq.IsAPI() )
rReq.Done();
}
else
{
FieldUnit eMetric = SC_MOD()->GetAppOptions().GetAppMetric();
ScViewData* pData = GetViewData();
sal_uInt16 nCurHeight = pData->GetDocument()->
GetColWidth( pData->GetCurX(),
pData->GetTabNo() );
ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
ScopedVclPtr<AbstractScMetricInputDlg> pDlg(pFact->CreateScMetricInputDlg(
pTabViewShell->GetFrameWeld(), "ColWidthDialog", nCurHeight,
STD_COL_WIDTH, eMetric, 2, MAX_COL_WIDTH));
if ( pDlg->Execute() == RET_OK )
{
long nVal = pDlg->GetInputValue();
pTabViewShell->SetMarkedWidthOrHeight( true, SC_SIZE_DIRECT, static_cast<sal_uInt16>(nVal) );
// #101390#; the value of the macro should be in HMM so use TwipsToEvenHMM to convert
rReq.AppendItem( SfxUInt16Item( FID_COL_WIDTH, static_cast<sal_uInt16>(TwipsToEvenHMM(nVal))) );
rReq.Done();
}
}
}
break;
case FID_COL_OPT_WIDTH:
{
if ( pReqArgs )
{
const SfxUInt16Item& rUInt16Item = static_cast<const SfxUInt16Item&>(pReqArgs->Get( FID_COL_OPT_WIDTH ));
// #101390#; the value of the macro is in HMM so use HMMToTwips to convert
pTabViewShell->SetMarkedWidthOrHeight( true, SC_SIZE_OPTIMAL,
sal::static_int_cast<sal_uInt16>( HMMToTwips(rUInt16Item.GetValue()) ) );
ScGlobal::nLastColWidthExtra = rUInt16Item.GetValue();
if( ! rReq.IsAPI() )
rReq.Done();
}
else
{
FieldUnit eMetric = SC_MOD()->GetAppOptions().GetAppMetric();
ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
ScopedVclPtr<AbstractScMetricInputDlg> pDlg(pFact->CreateScMetricInputDlg(
pTabViewShell->GetFrameWeld(), "OptimalColWidthDialog",
ScGlobal::nLastColWidthExtra, STD_EXTRA_WIDTH, eMetric, 1, MAX_EXTRA_WIDTH));
if ( pDlg->Execute() == RET_OK )
{
long nVal = pDlg->GetInputValue();
pTabViewShell->SetMarkedWidthOrHeight( true, SC_SIZE_OPTIMAL, static_cast<sal_uInt16>(nVal) );
ScGlobal::nLastColWidthExtra = nVal;
// #101390#; the value of the macro should be in HMM so use TwipsToEvenHMM to convert
rReq.AppendItem( SfxUInt16Item( FID_COL_OPT_WIDTH, static_cast<sal_uInt16>(TwipsToEvenHMM(nVal)) ) );
rReq.Done();
}
}
}
break;
case FID_COL_OPT_DIRECT:
pTabViewShell->SetMarkedWidthOrHeight( true, SC_SIZE_OPTIMAL, STD_EXTRA_WIDTH );
rReq.Done();
break;
case FID_ROW_HIDE:
pTabViewShell->SetMarkedWidthOrHeight( false, SC_SIZE_DIRECT, 0 );
rReq.Done();
break;
case FID_ROW_SHOW:
pTabViewShell->SetMarkedWidthOrHeight( false, SC_SIZE_SHOW, 0 );
rReq.Done();
break;
case FID_COL_HIDE:
pTabViewShell->SetMarkedWidthOrHeight( true, SC_SIZE_DIRECT, 0 );
rReq.Done();
break;
case FID_COL_SHOW:
pTabViewShell->SetMarkedWidthOrHeight( true, SC_SIZE_SHOW, 0 );
rReq.Done();
break;
case SID_CELL_FORMAT_RESET:
{
pTabViewShell->DeleteContents( InsertDeleteFlags::HARDATTR | InsertDeleteFlags::EDITATTR );
rReq.Done();
}
break;
case FID_MERGE_ON:
case FID_MERGE_OFF:
case FID_MERGE_TOGGLE:
{
if ( !GetViewData()->GetDocument()->GetChangeTrack() )
{
// test whether to merge or to split
bool bMerge = false;
bool bCenter = false;
switch( nSlot )
{
case FID_MERGE_ON:
bMerge = true;
break;
case FID_MERGE_OFF:
bMerge = false;
break;
case FID_MERGE_TOGGLE:
{
bCenter = true;
std::unique_ptr<SfxPoolItem> pItem;
if( rBindings.QueryState( nSlot, pItem ) >= SfxItemState::DEFAULT )
bMerge = !static_cast< SfxBoolItem* >( pItem.get() )->GetValue();
}
break;
}
if( bMerge )
{
// merge - check if to move contents of covered cells
bool bMoveContents = false;
bool bApi = rReq.IsAPI();
const SfxPoolItem* pItem;
if ( pReqArgs &&
pReqArgs->GetItemState(nSlot, true, &pItem) == SfxItemState::SET )
{
OSL_ENSURE(dynamic_cast<const SfxBoolItem*>( pItem), "wrong item");
bMoveContents = static_cast<const SfxBoolItem*>(pItem)->GetValue();
}
if (pTabViewShell->MergeCells( bApi, bMoveContents, bCenter ))
{
if (!bApi && bMoveContents) // "yes" clicked in dialog
rReq.AppendItem( SfxBoolItem( nSlot, bMoveContents ) );
rBindings.Invalidate( nSlot );
rReq.Done();
}
}
else
{
// split cells
if (pTabViewShell->RemoveMerge())
{
rBindings.Invalidate( nSlot );
rReq.Done();
}
}
break;
}
}
break;
case SID_AUTOFORMAT:
{
vcl::Window* pDlgParent = pTabViewShell->GetDialogParent();
SCCOL nStartCol;
SCROW nStartRow;
SCTAB nStartTab;
SCCOL nEndCol;
SCROW nEndRow;
SCTAB nEndTab;
const ScMarkData& rMark = GetViewData()->GetMarkData();
if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
pTabViewShell->MarkDataArea();
GetViewData()->GetSimpleArea( nStartCol,nStartRow,nStartTab,
nEndCol,nEndRow,nEndTab );
if ( ( std::abs(nEndCol-nStartCol) > 1 )
&& ( std::abs(nEndRow-nStartRow) > 1 ) )
{
if ( pReqArgs )
{
const SfxStringItem& rNameItem = pReqArgs->Get( SID_AUTOFORMAT );
ScAutoFormat* pFormat = ScGlobal::GetOrCreateAutoFormat();
ScAutoFormat::const_iterator it = pFormat->find(rNameItem.GetValue());
ScAutoFormat::const_iterator itBeg = pFormat->begin();
size_t nIndex = std::distance(itBeg, it);
pTabViewShell->AutoFormat( nIndex );
if( ! rReq.IsAPI() )
rReq.Done();
}
else
{
ScGlobal::ClearAutoFormat();
std::unique_ptr<ScAutoFormatData> pNewEntry(pTabViewShell->CreateAutoFormatData());
ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
ScopedVclPtr<AbstractScAutoFormatDlg> pDlg(pFact->CreateScAutoFormatDlg(pDlgParent, ScGlobal::GetOrCreateAutoFormat(), pNewEntry.get(), GetViewData()));
if ( pDlg->Execute() == RET_OK )
{
ScEditableTester aTester( pTabViewShell );
if ( !aTester.IsEditable() )
{
pTabViewShell->ErrorMessage(aTester.GetMessageId());
}
else
{
pTabViewShell->AutoFormat( pDlg->GetIndex() );
rReq.AppendItem( SfxStringItem( SID_AUTOFORMAT, pDlg->GetCurrFormatName() ) );
rReq.Done();
}
}
}
}
else
{
std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pDlgParent ? pDlgParent->GetFrameWeld() : nullptr,
VclMessageType::Warning, VclButtonsType::Ok,
ScResId(STR_INVALID_AFAREA)));
xErrorBox->run();
}
}
break;
case SID_CANCEL:
{
if (GetViewData()->HasEditView(GetViewData()->GetActivePart()))
pScMod->InputCancelHandler();
else if (pTabViewShell->HasPaintBrush())
pTabViewShell->ResetBrushDocument(); // abort format paint brush
else if (pTabViewShell->HasHintWindow())
pTabViewShell->RemoveHintWindow();
else if( ScViewUtil::IsFullScreen( *pTabViewShell ) )
ScViewUtil::SetFullScreen( *pTabViewShell, false );
else
{
// TODO/LATER: when is this code executed?
pTabViewShell->Escape();
}
}
break;
case SID_DATA_SELECT:
pTabViewShell->StartDataSelect();
break;
case SID_DETECTIVE_FILLMODE:
{
bool bOldMode = pTabViewShell->IsAuditShell();
pTabViewShell->SetAuditShell( !bOldMode );
pTabViewShell->Invalidate( nSlot );
}
break;
case FID_INPUTLINE_STATUS:
OSL_FAIL("Execute from InputLine status");
break;
case SID_STATUS_DOCPOS:
// Launch navigator.
GetViewData()->GetDispatcher().Execute(
SID_NAVIGATOR, SfxCallMode::SYNCHRON|SfxCallMode::RECORD );
break;
case SID_MARKAREA:
// called from Basic at the hidden view to select a range in the visible view
OSL_FAIL("old slot SID_MARKAREA");
break;
default:
OSL_FAIL("ScCellShell::Execute: unknown slot");
break;
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V595 The 'pHdl' pointer was utilized before it was verified against nullptr. Check lines: 192, 197.