diff options
Diffstat (limited to '')
-rw-r--r-- | sc/source/ui/view/cellsh3.cxx | 1058 |
1 files changed, 1058 insertions, 0 deletions
diff --git a/sc/source/ui/view/cellsh3.cxx b/sc/source/ui/view/cellsh3.cxx new file mode 100644 index 000000000..9158748a9 --- /dev/null +++ b/sc/source/ui/view/cellsh3.cxx @@ -0,0 +1,1058 @@ +/* -*- 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 <formula/formulahelper.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/request.hxx> +#include <svl/stritem.hxx> +#include <vcl/svapp.hxx> +#include <vcl/weld.hxx> +#include <globstr.hrc> +#include <scresid.hxx> +#include <scmod.hxx> +#include <appoptio.hxx> +#include <tabvwsh.hxx> +#include <document.hxx> +#include <sc.hrc> +#include <reffact.hxx> +#include <uiitems.hxx> +#include <autoform.hxx> +#include <cellsh.hxx> +#include <inputhdl.hxx> +#include <editable.hxx> +#include <funcdesc.hxx> +#include <markdata.hxx> +#include <scabstdlg.hxx> +#include <columnspanset.hxx> +#include <comphelper/lok.hxx> +#include <LibreOfficeKit/LibreOfficeKitEnums.h> +#include <sfx2/lokhelper.hxx> + +#include <memory> + +#define IS_EDITMODE() GetViewData()->HasEditView( GetViewData()->GetActivePart() ) + +using sc::HMMToTwips; +using sc::TwipsToEvenHMM; + +namespace +{ +/// Rid ourselves of unwanted " quoted json characters. +OString escapeJSON(const OUString &aStr) +{ + OUString aEscaped = aStr; + aEscaped = aEscaped.replaceAll("\n", " "); + aEscaped = aEscaped.replaceAll("\"", "'"); + return OUStringToOString(aEscaped, RTL_TEXTENCODING_UTF8); +} + +void lcl_lokGetWholeFunctionList() +{ + const SfxViewShell* pViewShell = SfxViewShell::Current(); + if (comphelper::LibreOfficeKit::isActive() + && pViewShell && pViewShell->isLOKMobilePhone()) + { + const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList(); + sal_uInt32 nListCount = pFuncList->GetCount(); + std::set<OUString> aFuncNameOrderedSet; + for(sal_uInt32 i = 0; i < nListCount; ++i) + { + const ScFuncDesc* pDesc = pFuncList->GetFunction( i ); + if ( pDesc->mxFuncName ) + { + aFuncNameOrderedSet.insert(*pDesc->mxFuncName); + } + } + ScFunctionMgr* pFuncManager = ScGlobal::GetStarCalcFunctionMgr(); + if (pFuncManager && aFuncNameOrderedSet.size()) + { + OStringBuffer aPayload; + aPayload.append("{ \"wholeList\": true, "); + aPayload.append("\"categories\": [ "); + + formula::FormulaHelper aHelper(pFuncManager); + sal_uInt32 nCategoryCount = pFuncManager->getCount(); + for (sal_uInt32 i = 0; i < nCategoryCount; ++i) + { + OUString sCategoryName = ScFunctionMgr::GetCategoryName(i); + aPayload.append("{"); + aPayload.append("\"name\": \""); + aPayload.append(escapeJSON(sCategoryName)); + aPayload.append("\"}, "); + } + sal_Int32 nLen = aPayload.getLength(); + aPayload[nLen - 2] = ' '; + aPayload[nLen - 1] = ']'; + aPayload.append(", "); + + OUString aDescFuncNameStr; + aPayload.append("\"functions\": [ "); + sal_uInt32 nCurIndex = 0; + for (const OUString& aFuncNameStr : aFuncNameOrderedSet) + { + aDescFuncNameStr = aFuncNameStr + "()"; + sal_Int32 nNextFStart = 0; + const formula::IFunctionDescription* ppFDesc; + ::std::vector< OUString > aArgs; + OUString eqPlusFuncName = "=" + aDescFuncNameStr; + if ( aHelper.GetNextFunc( eqPlusFuncName, false, nNextFStart, nullptr, &ppFDesc, &aArgs ) ) + { + if ( ppFDesc && !ppFDesc->getFunctionName().isEmpty() ) + { + if (ppFDesc->getCategory()) + { + aPayload.append("{"); + aPayload.append("\"index\": "); + aPayload.append(OString::number(nCurIndex)); + aPayload.append(", "); + aPayload.append("\"category\": "); + aPayload.append(OString::number(ppFDesc->getCategory()->getNumber())); + aPayload.append(", "); + aPayload.append("\"signature\": \""); + aPayload.append(escapeJSON(ppFDesc->getSignature())); + aPayload.append("\", "); + aPayload.append("\"description\": \""); + aPayload.append(escapeJSON(ppFDesc->getDescription())); + aPayload.append("\"}, "); + } + } + } + ++nCurIndex; + } + nLen = aPayload.getLength(); + aPayload[nLen - 2] = ' '; + aPayload[nLen - 1] = ']'; + aPayload.append(" }"); + + OString s = aPayload.makeStringAndClear(); + pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_CALC_FUNCTION_LIST, s.getStr()); + } + } +} + +} // end namespace + +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 + [[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 ) + { + if (comphelper::LibreOfficeKit::isActive()) + { + // Let the client know about our entry, so if they save + // (say because the user closes the document or window,) + // this change gets persisted (assuming DontTerminateEdit + // is set to false in the .uno:Save command). + SfxLokHelper::notifyAllViews(LOK_CALLBACK_STATE_CHANGED, ".uno:ModifiedStatus=true"); + } + + 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 if (pHdl) + { + 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 )); + + const ScAddress& aCursorPos = pStatusItem->GetPos(); + const 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: + { + const SfxViewShell* pViewShell = SfxViewShell::Current(); + if (comphelper::LibreOfficeKit::isActive() + && pViewShell && pViewShell->isLOKMobilePhone()) + { + // not set the dialog id in the mobile case or we would + // not be able to get cell address pasted in the edit view + // by just tapping on them + lcl_lokGetWholeFunctionList(); + } + else + { + sal_uInt16 nId = SID_OPENDLG_FUNCTION; + SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame(); + SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId ); + bool bVis = comphelper::LibreOfficeKit::isActive() || pWnd == nullptr; + pScMod->SetRefDialog( nId, bVis ); + } + 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) + { + std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(pTabViewShell->GetFrameWeld(), + 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() ) + { + std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pTabViewShell->GetFrameWeld(), + 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->GetFrameWeld(), 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: + { + weld::Window* pDlgParent = pTabViewShell->GetFrameWeld(); + 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, + 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: */ |