1868 lines
72 KiB
C++
1868 lines
72 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 <com/sun/star/table/BorderLineStyle.hpp>
|
|
#include <officecfg/Office/Calc.hxx>
|
|
|
|
#include <comphelper/lok.hxx>
|
|
#include <editeng/boxitem.hxx>
|
|
#include <editeng/langitem.hxx>
|
|
#include <o3tl/temporary.hxx>
|
|
#include <sfx2/bindings.hxx>
|
|
#include <sfx2/request.hxx>
|
|
#include <sfx2/sfxdlg.hxx>
|
|
#include <sfx2/sidebar/Sidebar.hxx>
|
|
#include <sfx2/viewfrm.hxx>
|
|
#include <sfx2/dispatch.hxx>
|
|
#include <sfx2/newstyle.hxx>
|
|
#include <sfx2/tplpitem.hxx>
|
|
#include <svl/ilstitem.hxx>
|
|
#include <svl/numformat.hxx>
|
|
#include <svl/zformat.hxx>
|
|
#include <svl/int64item.hxx>
|
|
#include <svl/ptitem.hxx>
|
|
#include <svl/srchitem.hxx>
|
|
#include <svl/srchdefs.hxx>
|
|
#include <svl/stritem.hxx>
|
|
#include <svl/whiter.hxx>
|
|
#include <svx/numinf.hxx>
|
|
#include <svx/xbtmpit.hxx>
|
|
#include <svx/xlndsit.hxx>
|
|
#include <svx/xlnstit.hxx>
|
|
#include <svx/xlnedit.hxx>
|
|
#include <svx/xflgrit.hxx>
|
|
#include <svx/xflftrit.hxx>
|
|
#include <svx/xflhtit.hxx>
|
|
#include <svx/zoomslideritem.hxx>
|
|
|
|
#include <global.hxx>
|
|
#include <appoptio.hxx>
|
|
#include <attrib.hxx>
|
|
#include <cellform.hxx>
|
|
#include <cellvalue.hxx>
|
|
#include <compiler.hxx>
|
|
#include <docsh.hxx>
|
|
#include <document.hxx>
|
|
#include <formulacell.hxx>
|
|
#include <globstr.hrc>
|
|
#include <inputhdl.hxx>
|
|
#include <inputwin.hxx>
|
|
#include <markdata.hxx>
|
|
#include <patattr.hxx>
|
|
#include <sc.hrc>
|
|
#include <scabstdlg.hxx>
|
|
#include <scitems.hxx>
|
|
#include <scmod.hxx>
|
|
#include <scresid.hxx>
|
|
#include <stlpool.hxx>
|
|
#include <tabvwsh.hxx>
|
|
#include <tokenarray.hxx>
|
|
#include <viewdata.hxx>
|
|
#include <printfun.hxx>
|
|
#include <undostyl.hxx>
|
|
#include <futext.hxx>
|
|
|
|
#include <memory>
|
|
|
|
using namespace com::sun::star;
|
|
|
|
bool ScTabViewShell::GetFunction( OUString& rFuncStr, FormulaError nErrCode )
|
|
{
|
|
sal_uInt32 nFuncs = ScModule::get()->GetAppOptions().GetStatusFunc();
|
|
ScViewData& rViewData = GetViewData();
|
|
ScMarkData& rMark = rViewData.GetMarkData();
|
|
bool bIgnoreError = (rMark.IsMarked() || rMark.IsMultiMarked());
|
|
bool bFirst = true;
|
|
for ( sal_uInt16 nFunc = 0; nFunc < 32; nFunc++ )
|
|
{
|
|
if ( !(nFuncs & (1U << nFunc)) )
|
|
continue;
|
|
ScSubTotalFunc eFunc = static_cast<ScSubTotalFunc>(nFunc);
|
|
|
|
if (bIgnoreError && (eFunc == SUBTOTAL_FUNC_CNT || eFunc == SUBTOTAL_FUNC_CNT2))
|
|
nErrCode = FormulaError::NONE;
|
|
|
|
if (nErrCode != FormulaError::NONE)
|
|
{
|
|
rFuncStr = ScGlobal::GetLongErrorString(nErrCode);
|
|
return true;
|
|
}
|
|
|
|
TranslateId pGlobStrId;
|
|
switch (eFunc)
|
|
{
|
|
case SUBTOTAL_FUNC_AVE: pGlobStrId = STR_FUN_TEXT_AVG; break;
|
|
case SUBTOTAL_FUNC_CNT: pGlobStrId = STR_FUN_TEXT_COUNT; break;
|
|
case SUBTOTAL_FUNC_CNT2: pGlobStrId = STR_FUN_TEXT_COUNT2; break;
|
|
case SUBTOTAL_FUNC_MAX: pGlobStrId = STR_FUN_TEXT_MAX; break;
|
|
case SUBTOTAL_FUNC_MIN: pGlobStrId = STR_FUN_TEXT_MIN; break;
|
|
case SUBTOTAL_FUNC_SUM: pGlobStrId = STR_FUN_TEXT_SUM; break;
|
|
case SUBTOTAL_FUNC_SELECTION_COUNT: pGlobStrId = STR_FUN_TEXT_SELECTION_COUNT; break;
|
|
|
|
default:
|
|
{
|
|
// added to avoid warnings
|
|
}
|
|
}
|
|
if (pGlobStrId)
|
|
{
|
|
ScDocument& rDoc = rViewData.GetDocument();
|
|
SCCOL nPosX = rViewData.GetCurX();
|
|
SCROW nPosY = rViewData.GetCurY();
|
|
SCTAB nTab = rViewData.GetTabNo();
|
|
|
|
OUString aStr = ScResId(pGlobStrId) + ": ";
|
|
|
|
ScAddress aCursor( nPosX, nPosY, nTab );
|
|
double nVal;
|
|
if ( rDoc.GetSelectionFunction( eFunc, aCursor, rMark, nVal ) )
|
|
{
|
|
if ( nVal == 0.0 )
|
|
aStr += "0";
|
|
else
|
|
{
|
|
// Number in the standard format, the other on the cursor position
|
|
ScInterpreterContext& rContext = rDoc.GetNonThreadedContext();
|
|
sal_uInt32 nNumFmt = 0;
|
|
if ( eFunc != SUBTOTAL_FUNC_CNT && eFunc != SUBTOTAL_FUNC_CNT2 && eFunc != SUBTOTAL_FUNC_SELECTION_COUNT)
|
|
{
|
|
// number format from attributes or formula
|
|
nNumFmt = rDoc.GetNumberFormat( nPosX, nPosY, nTab );
|
|
// If the number format is time (without date) and the
|
|
// result is not within 24 hours, use a duration
|
|
// format. Summing date+time doesn't make much sense
|
|
// otherwise but we also don't want to display duration
|
|
// for a single date+time value.
|
|
if (nVal < 0.0 || nVal >= 1.0)
|
|
{
|
|
const SvNumberformat* pFormat = rContext.NFGetFormatEntry(nNumFmt);
|
|
if (pFormat && (pFormat->GetType() == SvNumFormatType::TIME))
|
|
nNumFmt = rContext.NFGetTimeFormat( nVal, pFormat->GetLanguage(), true);
|
|
}
|
|
}
|
|
|
|
OUString aValStr;
|
|
const Color* pDummy;
|
|
rContext.NFGetOutputString( nVal, nNumFmt, aValStr, &pDummy );
|
|
aStr += aValStr;
|
|
}
|
|
}
|
|
if ( bFirst )
|
|
{
|
|
rFuncStr += aStr;
|
|
bFirst = false;
|
|
}
|
|
else
|
|
rFuncStr += "; " + aStr;
|
|
}
|
|
}
|
|
|
|
return !rFuncStr.isEmpty();
|
|
}
|
|
|
|
// Functions that are disabled, depending on the selection
|
|
// Default:
|
|
// SID_DELETE,
|
|
// SID_DELETE_CONTENTS,
|
|
// FID_DELETE_CELL
|
|
// FID_VALIDATION
|
|
|
|
void ScTabViewShell::GetState( SfxItemSet& rSet )
|
|
{
|
|
ScViewData& rViewData = GetViewData();
|
|
ScDocument& rDoc = rViewData.GetDocument();
|
|
ScDocShell* pDocShell = rViewData.GetDocShell();
|
|
ScMarkData& rMark = rViewData.GetMarkData();
|
|
SCCOL nPosX = rViewData.GetCurX();
|
|
SCROW nPosY = rViewData.GetCurY();
|
|
SCTAB nTab = rViewData.GetTabNo();
|
|
|
|
SfxViewFrame& rThisFrame = GetViewFrame();
|
|
bool bOle = GetViewFrame().GetFrame().IsInPlace();
|
|
|
|
SCTAB nTabSelCount = rMark.GetSelectCount();
|
|
|
|
SfxWhichIter aIter(rSet);
|
|
sal_uInt16 nWhich = aIter.FirstWhich();
|
|
|
|
while ( nWhich )
|
|
{
|
|
switch ( nWhich )
|
|
{
|
|
case FID_CHG_COMMENT:
|
|
{
|
|
ScDocShell* pDocSh = GetViewData().GetDocShell();
|
|
ScAddress aPos( nPosX, nPosY, nTab );
|
|
if ( pDocSh->IsReadOnly() || !pDocSh->GetChangeAction(aPos) || pDocSh->IsDocShared() )
|
|
rSet.DisableItem( nWhich );
|
|
}
|
|
break;
|
|
|
|
case SID_OPENDLG_EDIT_PRINTAREA:
|
|
case SID_ADD_PRINTAREA:
|
|
case SID_DEFINE_PRINTAREA:
|
|
{
|
|
if ( pDocShell && pDocShell->IsDocShared() )
|
|
{
|
|
rSet.DisableItem( nWhich );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SID_DELETE_PRINTAREA:
|
|
if ( pDocShell && pDocShell->IsDocShared() )
|
|
{
|
|
rSet.DisableItem( nWhich );
|
|
}
|
|
else if (rDoc.IsPrintEntireSheet(nTab))
|
|
rSet.DisableItem(nWhich);
|
|
break;
|
|
|
|
case SID_STATUS_PAGESTYLE:
|
|
case SID_HFEDIT:
|
|
GetViewData().GetDocShell()->GetStatePageStyle( rSet, nTab );
|
|
break;
|
|
|
|
case SID_SEARCH_ITEM:
|
|
{
|
|
SvxSearchItem aItem(ScGlobal::GetSearchItem()); // make a copy.
|
|
// Search on current selection if a range is marked.
|
|
aItem.SetSelection(rMark.IsMarked());
|
|
rSet.Put(aItem);
|
|
break;
|
|
}
|
|
|
|
case SID_SEARCH_OPTIONS:
|
|
{
|
|
// Anything goes
|
|
SearchOptionFlags nOptions = SearchOptionFlags::ALL;
|
|
|
|
// No replacement if ReadOnly
|
|
if (GetViewData().GetDocShell()->IsReadOnly())
|
|
nOptions &= ~SearchOptionFlags( SearchOptionFlags::REPLACE | SearchOptionFlags::REPLACE_ALL );
|
|
rSet.Put( SfxUInt16Item( nWhich, static_cast<sal_uInt16>(nOptions) ) );
|
|
}
|
|
break;
|
|
|
|
case SID_CURRENTCELL:
|
|
{
|
|
ScAddress aScAddress( GetViewData().GetCurX(), GetViewData().GetCurY(), 0 );
|
|
OUString aAddr(aScAddress.Format(ScRefFlags::ADDR_ABS, nullptr, rDoc.GetAddressConvention()));
|
|
SfxStringItem aPosItem( SID_CURRENTCELL, aAddr );
|
|
|
|
rSet.Put( aPosItem );
|
|
}
|
|
break;
|
|
|
|
case SID_CURRENTTAB:
|
|
// Table for Basic is 1-based
|
|
rSet.Put( SfxUInt16Item( nWhich, static_cast<sal_uInt16>(GetViewData().GetTabNo()) + 1 ) );
|
|
break;
|
|
|
|
case SID_CURRENTDOC:
|
|
rSet.Put( SfxStringItem( nWhich, GetViewData().GetDocShell()->GetTitle() ) );
|
|
break;
|
|
|
|
case FID_TOGGLEINPUTLINE:
|
|
{
|
|
sal_uInt16 nId = ScInputWindowWrapper::GetChildWindowId();
|
|
|
|
if ( rThisFrame.KnowsChildWindow( nId ) )
|
|
{
|
|
SfxChildWindow* pWnd = rThisFrame.GetChildWindow( nId );
|
|
rSet.Put( SfxBoolItem( nWhich, pWnd != nullptr ) );
|
|
}
|
|
else
|
|
rSet.DisableItem( nWhich );
|
|
}
|
|
break;
|
|
|
|
case FID_DEL_MANUALBREAKS:
|
|
if (!rDoc.HasManualBreaks(nTab))
|
|
rSet.DisableItem( nWhich );
|
|
break;
|
|
|
|
case FID_RESET_PRINTZOOM:
|
|
{
|
|
// disable if already set to default
|
|
|
|
OUString aStyleName = rDoc.GetPageStyle( nTab );
|
|
ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool();
|
|
SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName,
|
|
SfxStyleFamily::Page );
|
|
OSL_ENSURE( pStyleSheet, "PageStyle not found" );
|
|
if ( pStyleSheet )
|
|
{
|
|
SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
|
|
sal_uInt16 nScale = rStyleSet.Get(ATTR_PAGE_SCALE).GetValue();
|
|
sal_uInt16 nPages = rStyleSet.Get(ATTR_PAGE_SCALETOPAGES).GetValue();
|
|
if ( nScale == 100 && nPages == 0 )
|
|
rSet.DisableItem( nWhich );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SID_ZOOM_IN:
|
|
{
|
|
const Fraction& rZoomY = GetViewData().GetZoomY();
|
|
tools::Long nZoom = tools::Long(rZoomY * 100);
|
|
if (nZoom >= MAXZOOM)
|
|
rSet.DisableItem(nWhich);
|
|
}
|
|
break;
|
|
case SID_ZOOM_OUT:
|
|
{
|
|
const Fraction& rZoomY = GetViewData().GetZoomY();
|
|
tools::Long nZoom = tools::Long(rZoomY * 100);
|
|
if (nZoom <= MINZOOM)
|
|
rSet.DisableItem(nWhich);
|
|
}
|
|
break;
|
|
|
|
case FID_SCALE:
|
|
case SID_ATTR_ZOOM:
|
|
if ( bOle )
|
|
rSet.DisableItem( nWhich );
|
|
else
|
|
{
|
|
const Fraction& rOldY = GetViewData().GetZoomY();
|
|
sal_uInt16 nZoom = static_cast<sal_uInt16>(tools::Long( rOldY * 100 ));
|
|
rSet.Put( SvxZoomItem( SvxZoomType::PERCENT, nZoom, TypedWhichId<SvxZoomItem>(nWhich) ) );
|
|
}
|
|
break;
|
|
|
|
case SID_ATTR_ZOOMSLIDER:
|
|
{
|
|
if ( bOle )
|
|
rSet.DisableItem( nWhich );
|
|
else
|
|
{
|
|
const Fraction& rOldY = GetViewData().GetZoomY();
|
|
sal_uInt16 nCurrentZoom = static_cast<sal_uInt16>(tools::Long( rOldY * 100 ));
|
|
|
|
if( nCurrentZoom )
|
|
{
|
|
SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM, MAXZOOM, SID_ATTR_ZOOMSLIDER );
|
|
aZoomSliderItem.AddSnappingPoint( 100 );
|
|
rSet.Put( aZoomSliderItem );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case FID_FUNCTION_BOX:
|
|
{
|
|
const bool bBoxOpen = ::sfx2::sidebar::Sidebar::IsPanelVisible(u"ScFunctionsPanel",
|
|
rThisFrame.GetFrame().GetFrameInterface());
|
|
rSet.Put(SfxBoolItem(nWhich, bBoxOpen));
|
|
break;
|
|
}
|
|
|
|
case FID_TOGGLESYNTAX:
|
|
rSet.Put(SfxBoolItem(nWhich, GetViewData().IsSyntaxMode()));
|
|
break;
|
|
|
|
case FID_TOGGLECOLROWHIGHLIGHTING:
|
|
rSet.Put(SfxBoolItem(
|
|
nWhich,
|
|
officecfg::Office::Calc::Content::Display::ColumnRowHighlighting::get()));
|
|
break;
|
|
|
|
case FID_TOGGLEHEADERS:
|
|
rSet.Put(SfxBoolItem(nWhich, GetViewData().IsHeaderMode()));
|
|
break;
|
|
|
|
case FID_TOGGLEFORMULA:
|
|
{
|
|
const ScViewOptions& rOpts = rViewData.GetOptions();
|
|
bool bFormulaMode = rOpts.GetOption( VOPT_FORMULAS );
|
|
rSet.Put(SfxBoolItem(nWhich, bFormulaMode ));
|
|
}
|
|
break;
|
|
|
|
case FID_NORMALVIEWMODE:
|
|
case FID_PAGEBREAKMODE:
|
|
// always handle both slots - they exclude each other
|
|
if ( bOle )
|
|
{
|
|
rSet.DisableItem( FID_NORMALVIEWMODE );
|
|
rSet.DisableItem( FID_PAGEBREAKMODE );
|
|
}
|
|
else
|
|
{
|
|
rSet.Put(SfxBoolItem(FID_NORMALVIEWMODE, !GetViewData().IsPagebreakMode()));
|
|
rSet.Put(SfxBoolItem(FID_PAGEBREAKMODE, GetViewData().IsPagebreakMode()));
|
|
}
|
|
break;
|
|
|
|
case FID_PROTECT_DOC:
|
|
{
|
|
if ( pDocShell && pDocShell->IsDocShared() )
|
|
{
|
|
rSet.DisableItem( nWhich );
|
|
}
|
|
else
|
|
{
|
|
rSet.Put( SfxBoolItem( nWhich, rDoc.IsDocProtected() ) );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case FID_PROTECT_TABLE:
|
|
{
|
|
if ( pDocShell && pDocShell->IsDocShared() )
|
|
{
|
|
rSet.DisableItem( nWhich );
|
|
}
|
|
else
|
|
{
|
|
rSet.Put( SfxBoolItem( nWhich, rDoc.IsTabProtected( nTab ) ) );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SID_AUTO_OUTLINE:
|
|
{
|
|
if (rDoc.GetChangeTrack()!=nullptr || GetViewData().IsMultiMarked())
|
|
{
|
|
rSet.DisableItem( nWhich );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SID_OUTLINE_DELETEALL:
|
|
{
|
|
SCTAB nOlTab = GetViewData().GetTabNo();
|
|
ScOutlineTable* pOlTable = rDoc.GetOutlineTable( nOlTab );
|
|
if (pOlTable == nullptr)
|
|
rSet.DisableItem( nWhich );
|
|
}
|
|
break;
|
|
|
|
case SID_WINDOW_SPLIT:
|
|
rSet.Put(SfxBoolItem(nWhich,
|
|
rViewData.GetHSplitMode() == SC_SPLIT_NORMAL ||
|
|
rViewData.GetVSplitMode() == SC_SPLIT_NORMAL ));
|
|
break;
|
|
|
|
case SID_WINDOW_FIX:
|
|
if(!comphelper::LibreOfficeKit::isActive())
|
|
{
|
|
rSet.Put(SfxBoolItem(nWhich,
|
|
rViewData.GetHSplitMode() == SC_SPLIT_FIX ||
|
|
rViewData.GetVSplitMode() == SC_SPLIT_FIX ));
|
|
}
|
|
else
|
|
{
|
|
rSet.Put(SfxBoolItem(nWhich,
|
|
rViewData.GetLOKSheetFreezeIndex(true) > 0 ||
|
|
rViewData.GetLOKSheetFreezeIndex(false) > 0 ));
|
|
}
|
|
break;
|
|
|
|
case SID_WINDOW_FIX_COL:
|
|
case SID_WINDOW_FIX_ROW:
|
|
{
|
|
Point aPos;
|
|
bool bIsCol = (nWhich == SID_WINDOW_FIX_COL);
|
|
aPos.setX(rViewData.GetLOKSheetFreezeIndex(bIsCol));
|
|
aPos.setY(rViewData.GetTabNo());
|
|
rSet.Put(SfxPointItem(nWhich, aPos));
|
|
}
|
|
break;
|
|
|
|
case FID_CHG_SHOW:
|
|
{
|
|
if ( rDoc.GetChangeTrack() == nullptr || ( pDocShell && pDocShell->IsDocShared() ) )
|
|
rSet.DisableItem( nWhich );
|
|
}
|
|
break;
|
|
case FID_CHG_ACCEPT:
|
|
{
|
|
if(
|
|
( !rDoc.GetChangeTrack() && !rThisFrame.HasChildWindow(FID_CHG_ACCEPT) )
|
|
||
|
|
( pDocShell && pDocShell->IsDocShared() )
|
|
)
|
|
{
|
|
rSet.DisableItem( nWhich);
|
|
}
|
|
else
|
|
{
|
|
rSet.Put(SfxBoolItem(FID_CHG_ACCEPT,
|
|
rThisFrame.HasChildWindow(FID_CHG_ACCEPT)));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SID_FORMATPAGE:
|
|
// in protected tables
|
|
if ( pDocShell && ( pDocShell->IsReadOnly() || pDocShell->IsDocShared() ) )
|
|
rSet.DisableItem( nWhich );
|
|
break;
|
|
|
|
case SID_PRINTPREVIEW:
|
|
// Toggle slot needs a State
|
|
rSet.Put( SfxBoolItem( nWhich, false ) );
|
|
break;
|
|
|
|
case SID_READONLY_MODE:
|
|
rSet.Put( SfxBoolItem( nWhich, GetViewData().GetDocShell()->IsReadOnly() ) );
|
|
break;
|
|
|
|
case FID_TAB_DESELECTALL:
|
|
if ( nTabSelCount == 1 )
|
|
rSet.DisableItem( nWhich ); // enabled only if several sheets are selected
|
|
break;
|
|
|
|
case FID_TOGGLEHIDDENCOLROW:
|
|
const svtools::ColorConfig& rColorCfg = ScModule::get()->GetColorConfig();
|
|
rSet.Put( SfxBoolItem( nWhich, rColorCfg.GetColorValue(svtools::CALCHIDDENROWCOL).bIsVisible) );
|
|
break;
|
|
|
|
} // switch ( nWitch )
|
|
nWhich = aIter.NextWhich();
|
|
} // while ( nWitch )
|
|
}
|
|
|
|
void ScTabViewShell::ExecuteCellFormatDlg(SfxRequest& rReq, const OUString &rName)
|
|
{
|
|
ScDocument& rDoc = GetViewData().GetDocument();
|
|
|
|
std::shared_ptr<SvxBoxItem> aLineOuter(std::make_shared<SvxBoxItem>(ATTR_BORDER));
|
|
std::shared_ptr<SvxBoxInfoItem> aLineInner(std::make_shared<SvxBoxInfoItem>(ATTR_BORDER_INNER));
|
|
|
|
const ScPatternAttr* pOldAttrs = GetSelectionPattern();
|
|
|
|
auto xOldSet = std::make_shared<SfxItemSet>(pOldAttrs->GetItemSet());
|
|
|
|
xOldSet->MergeRange(XATTR_FILLSTYLE, XATTR_FILLCOLOR);
|
|
|
|
xOldSet->MergeRange(SID_ATTR_BORDER_STYLES, SID_ATTR_BORDER_DEFAULT_WIDTH);
|
|
|
|
// We only allow these border line types.
|
|
std::vector<sal_Int32> aBorderStyles{
|
|
table::BorderLineStyle::SOLID,
|
|
table::BorderLineStyle::DOTTED,
|
|
table::BorderLineStyle::DASHED,
|
|
table::BorderLineStyle::FINE_DASHED,
|
|
table::BorderLineStyle::DASH_DOT,
|
|
table::BorderLineStyle::DASH_DOT_DOT,
|
|
table::BorderLineStyle::DOUBLE_THIN };
|
|
|
|
xOldSet->Put(SfxIntegerListItem(SID_ATTR_BORDER_STYLES, std::move(aBorderStyles)));
|
|
|
|
// Set the default border width to 0.75 points.
|
|
SfxInt64Item aBorderWidthItem(SID_ATTR_BORDER_DEFAULT_WIDTH, 75);
|
|
xOldSet->Put(aBorderWidthItem);
|
|
|
|
// Get border items and put them in the set:
|
|
GetSelectionFrame( aLineOuter, aLineInner );
|
|
|
|
//Fix border incorrect for RTL fdo#62399
|
|
if( rDoc.IsLayoutRTL( GetViewData().GetTabNo() ) )
|
|
{
|
|
std::unique_ptr<SvxBoxItem> aNewFrame(aLineOuter->Clone());
|
|
std::unique_ptr<SvxBoxInfoItem> aTempInfo(aLineInner->Clone());
|
|
|
|
if ( aLineInner->IsValid(SvxBoxInfoItemValidFlags::LEFT) )
|
|
aNewFrame->SetLine( aLineOuter->GetLeft(), SvxBoxItemLine::RIGHT );
|
|
if ( aLineInner->IsValid(SvxBoxInfoItemValidFlags::RIGHT) )
|
|
aNewFrame->SetLine( aLineOuter->GetRight(), SvxBoxItemLine::LEFT );
|
|
|
|
aLineInner->SetValid( SvxBoxInfoItemValidFlags::LEFT, aTempInfo->IsValid(SvxBoxInfoItemValidFlags::RIGHT));
|
|
aLineInner->SetValid( SvxBoxInfoItemValidFlags::RIGHT, aTempInfo->IsValid(SvxBoxInfoItemValidFlags::LEFT));
|
|
|
|
xOldSet->Put( std::move(aNewFrame) );
|
|
}
|
|
else
|
|
{
|
|
xOldSet->Put( *aLineOuter );
|
|
}
|
|
|
|
xOldSet->Put( *aLineInner );
|
|
|
|
// Generate NumberFormat Value from Value and Language and box it.
|
|
if (pOldAttrs->HasNumberFormat()) // tdf#42989: don't set it for multi-format selection
|
|
xOldSet->Put(
|
|
SfxUInt32Item(ATTR_VALUE_FORMAT, pOldAttrs->GetNumberFormat(rDoc.GetFormatTable())));
|
|
|
|
std::unique_ptr<SvxNumberInfoItem> pNumberInfoItem = MakeNumberInfoItem(rDoc, GetViewData());
|
|
xOldSet->MergeRange( SID_ATTR_NUMBERFORMAT_INFO, SID_ATTR_NUMBERFORMAT_INFO );
|
|
xOldSet->Put( std::move(pNumberInfoItem) );
|
|
|
|
bInFormatDialog = true;
|
|
ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
|
|
|
|
VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateScAttrDlg(GetFrameWeld(), xOldSet.get()));
|
|
|
|
if (!rName.isEmpty())
|
|
pDlg->SetCurPageId(rName);
|
|
|
|
auto xRequest = std::make_shared<SfxRequest>(rReq);
|
|
rReq.Ignore(); // the 'old' request is not relevant any more
|
|
|
|
pDlg->StartExecuteAsync([pDlg, xOldSet=std::move(xOldSet), xRequest=std::move(xRequest), this](sal_Int32 nResult){
|
|
bInFormatDialog = false;
|
|
|
|
if ( nResult == RET_OK )
|
|
{
|
|
const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
|
|
if(const SvxNumberInfoItem* pItem = pOutSet->GetItemIfSet(SID_ATTR_NUMBERFORMAT_INFO))
|
|
{
|
|
UpdateNumberFormatter(*pItem);
|
|
}
|
|
|
|
ApplyAttributes(*pOutSet, *xOldSet);
|
|
|
|
xRequest->Done(*pOutSet);
|
|
}
|
|
|
|
pDlg->disposeOnce();
|
|
});
|
|
}
|
|
|
|
const OUString* ScTabViewShell::GetEditString() const
|
|
{
|
|
if (mpInputHandler)
|
|
return &mpInputHandler->GetEditString();
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
bool ScTabViewShell::IsRefInputMode() const
|
|
{
|
|
if (ScModule* pScMod = ScModule::get())
|
|
{
|
|
if( pScMod->IsRefDialogOpen() )
|
|
return pScMod->IsFormulaMode();
|
|
if( pScMod->IsFormulaMode() )
|
|
{
|
|
ScInputHandler* pHdl = pScMod->GetInputHdl();
|
|
if ( pHdl )
|
|
{
|
|
const ScViewData& rViewData = GetViewData();
|
|
ScDocument& rDoc = rViewData.GetDocument();
|
|
const ScAddress aPos( rViewData.GetCurPos() );
|
|
const sal_uInt32 nIndex = rDoc.GetAttr(aPos, ATTR_VALUE_FORMAT )->GetValue();
|
|
const SvNumFormatType nType = rDoc.GetFormatTable()->GetType(nIndex);
|
|
if (nType == SvNumFormatType::TEXT)
|
|
{
|
|
return false;
|
|
}
|
|
OUString aString = pHdl->GetEditString();
|
|
if ( !pHdl->GetSelIsRef() && aString.getLength() > 1 &&
|
|
( aString[0] == '+' || aString[0] == '-' ) )
|
|
{
|
|
ScCompiler aComp( rDoc, aPos, rDoc.GetGrammar() );
|
|
aComp.SetCloseBrackets( false );
|
|
std::unique_ptr<ScTokenArray> pArr(aComp.CompileString(aString));
|
|
if ( pArr && pArr->MayReferenceFollow() )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void ScTabViewShell::ExecuteInputDirect()
|
|
{
|
|
if ( !IsRefInputMode() )
|
|
{
|
|
if (ScModule* pScMod = ScModule::get())
|
|
{
|
|
pScMod->InputEnterHandler();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ScTabViewShell::UpdateInputHandler( bool bForce /* = sal_False */, bool bStopEditing /* = sal_True */ )
|
|
{
|
|
ScInputHandler* pHdl = mpInputHandler ? mpInputHandler.get() : ScModule::get()->GetInputHdl();
|
|
|
|
if ( pHdl )
|
|
{
|
|
OUString aString;
|
|
const EditTextObject* pObject = nullptr;
|
|
ScViewData& rViewData = GetViewData();
|
|
ScDocument& rDoc = rViewData.GetDocument();
|
|
SCCOL nPosX = rViewData.GetCurX();
|
|
SCROW nPosY = rViewData.GetCurY();
|
|
SCTAB nTab = rViewData.GetTabNo();
|
|
SCTAB nStartTab = 0;
|
|
SCTAB nEndTab = 0;
|
|
SCCOL nStartCol = 0;
|
|
SCROW nStartRow = 0;
|
|
SCCOL nEndCol = 0;
|
|
SCROW nEndRow = 0;
|
|
ScAddress aPos = rViewData.GetCurPos();
|
|
|
|
rViewData.GetSimpleArea( nStartCol, nStartRow, nStartTab,
|
|
nEndCol, nEndRow, nEndTab );
|
|
|
|
PutInOrder( nStartCol, nEndCol );
|
|
PutInOrder( nStartRow, nEndRow );
|
|
PutInOrder( nStartTab, nEndTab );
|
|
|
|
bool bHideFormula = false;
|
|
bool bHideAll = false;
|
|
|
|
if (rDoc.IsTabProtected(nTab))
|
|
{
|
|
const ScProtectionAttr* pProt = rDoc.GetAttr( nPosX,nPosY,nTab,
|
|
ATTR_PROTECTION);
|
|
bHideFormula = pProt->GetHideFormula();
|
|
bHideAll = pProt->GetHideCell();
|
|
}
|
|
|
|
if (!bHideAll)
|
|
{
|
|
ScRefCellValue rCell(rDoc, aPos);
|
|
if (rCell.getType() == CELLTYPE_FORMULA)
|
|
{
|
|
if (!bHideFormula)
|
|
aString = rCell.getFormula()->GetFormula();
|
|
}
|
|
else if (rCell.getType() == CELLTYPE_EDIT)
|
|
{
|
|
pObject = rCell.getEditText();
|
|
}
|
|
else
|
|
{
|
|
ScInterpreterContext& rContext = rDoc.GetNonThreadedContext();
|
|
sal_uInt32 nNumFmt = rDoc.GetNumberFormat( ScRange(aPos) );
|
|
|
|
aString = ScCellFormat::GetInputString( rCell, nNumFmt, &rContext, rDoc );
|
|
if (rCell.getType() == CELLTYPE_STRING)
|
|
{
|
|
// Put a ' in front if necessary, so that the string is not
|
|
// unintentionally interpreted as a number, and to show the
|
|
// user that it is a string (#35060#).
|
|
// If cell is not formatted as Text, a leading apostrophe
|
|
// needs another prepended, also '=' or '+' or '-'
|
|
// otherwise starting a formula.
|
|
// NOTE: this corresponds with
|
|
// sc/source/core/data/column3.cxx ScColumn::ParseString()
|
|
// removing one apostrophe.
|
|
// For number format Text IsNumberFormat() would never
|
|
// result in numeric anyway.
|
|
if (!rContext.NFIsTextFormat(nNumFmt) && (aString.startsWith("'")
|
|
|| aString.startsWith("=") || aString.startsWith("+") || aString.startsWith("-")
|
|
|| rContext.NFIsNumberFormat(aString, nNumFmt, o3tl::temporary(double()))))
|
|
aString = "'" + aString;
|
|
}
|
|
}
|
|
}
|
|
|
|
ScInputHdlState aState( ScAddress( nPosX, nPosY, nTab ),
|
|
ScAddress( nStartCol, nStartRow, nTab ),
|
|
ScAddress( nEndCol, nEndRow, nTab ),
|
|
aString,
|
|
pObject );
|
|
|
|
// if using the view's local input handler, this view can always be set
|
|
// as current view inside NotifyChange.
|
|
ScTabViewShell* pSourceSh = mpInputHandler ? this : nullptr;
|
|
|
|
pHdl->NotifyChange( &aState, bForce, pSourceSh, bStopEditing );
|
|
}
|
|
|
|
SfxBindings& rBindings = GetViewFrame().GetBindings();
|
|
rBindings.Invalidate( SID_STATUS_SUM ); // always together with the input row
|
|
rBindings.Invalidate( SID_ATTR_SIZE );
|
|
rBindings.Invalidate( SID_TABLE_CELL );
|
|
}
|
|
|
|
void ScTabViewShell::UpdateInputHandlerCellAdjust( SvxCellHorJustify eJust )
|
|
{
|
|
if( ScInputHandler* pHdl = mpInputHandler ? mpInputHandler.get() : ScModule::get()->GetInputHdl() )
|
|
pHdl->UpdateCellAdjust( eJust );
|
|
}
|
|
|
|
void ScTabViewShell::ExecuteSave( SfxRequest& rReq )
|
|
{
|
|
// only SID_SAVEDOC / SID_SAVEASDOC
|
|
bool bCommitChanges = true;
|
|
const SfxItemSet* pReqArgs = rReq.GetArgs();
|
|
const SfxPoolItem* pItem;
|
|
|
|
if (pReqArgs && pReqArgs->HasItem(FN_PARAM_1, &pItem))
|
|
bCommitChanges = !static_cast<const SfxBoolItem*>(pItem)->GetValue();
|
|
|
|
// Finish entering unless 'DontTerminateEdit' is specified, even if a formula is being processed
|
|
if (bCommitChanges)
|
|
{
|
|
bool bLOKActive = comphelper::LibreOfficeKit::isActive();
|
|
|
|
// Disable error dialog box when about to save in lok mode as
|
|
// this ultimately invokes SvpSalInstance::DoYield() when we want
|
|
// to save immediately without committing any erroneous input in possibly
|
|
// a cell with validation rules. After save is complete the user
|
|
// can continue editing.
|
|
ScModule::get()->InputEnterHandler(ScEnterMode::NORMAL, bLOKActive /* bBeforeSavingInLOK */);
|
|
|
|
if (bLOKActive)
|
|
{
|
|
// Normally this isn't needed, but in Calc when editing a cell formula
|
|
// and manually saving (without changing cells or hitting enter), while
|
|
// InputEnterHandler will mark the doc as modified (when it is), because
|
|
// we will save the doc immediately afterwards, the modified state event
|
|
// is clobbered. To avoid that, we need to update SID_DOC_MODIFIED so that
|
|
// a possible state of "true" after "InputEnterHandler" will be sent
|
|
// as a notification. It is important that the notification goes through
|
|
// normal process (cache) rather than directly notifying the views.
|
|
// Otherwise, because there is a previous state of "false" in cache, the
|
|
// "false" state after saving will be ignored.
|
|
// This will work only if .uno:ModifiedStatus message will be removed from
|
|
// the mechanism that keeps in the message queue only last message of
|
|
// a particular status even if the values are different.
|
|
if (SfxBindings* pBindings = GetViewData().GetDocShell()->GetViewBindings())
|
|
pBindings->Update(SID_DOC_MODIFIED);
|
|
}
|
|
}
|
|
|
|
if ( GetViewData().GetDocShell()->IsDocShared() )
|
|
{
|
|
GetViewData().GetDocShell()->SetDocumentModified();
|
|
}
|
|
|
|
// otherwise as normal
|
|
GetViewData().GetDocShell()->ExecuteSlot( rReq );
|
|
}
|
|
|
|
void ScTabViewShell::GetSaveState( SfxItemSet& rSet )
|
|
{
|
|
SfxShell* pDocSh = GetViewData().GetDocShell();
|
|
|
|
SfxWhichIter aIter(rSet);
|
|
sal_uInt16 nWhich = aIter.FirstWhich();
|
|
while( nWhich )
|
|
{
|
|
if ( nWhich != SID_SAVEDOC || !GetViewData().GetDocShell()->IsDocShared() )
|
|
{
|
|
// get state from DocShell
|
|
pDocSh->GetSlotState( nWhich, nullptr, &rSet );
|
|
}
|
|
nWhich = aIter.NextWhich();
|
|
}
|
|
}
|
|
|
|
void ScTabViewShell::ExecDrawOpt( const SfxRequest& rReq )
|
|
{
|
|
ScViewOptions aViewOptions = GetViewData().GetOptions();
|
|
ScGridOptions aGridOptions = aViewOptions.GetGridOptions();
|
|
|
|
SfxBindings& rBindings = GetViewFrame().GetBindings();
|
|
const SfxItemSet* pArgs = rReq.GetArgs();
|
|
const SfxPoolItem* pItem;
|
|
sal_uInt16 nSlotId = rReq.GetSlot();
|
|
switch (nSlotId)
|
|
{
|
|
case SID_GRID_VISIBLE:
|
|
if ( pArgs && pArgs->GetItemState(nSlotId,true,&pItem) == SfxItemState::SET )
|
|
{
|
|
aGridOptions.SetGridVisible( static_cast<const SfxBoolItem*>(pItem)->GetValue() );
|
|
aViewOptions.SetGridOptions(aGridOptions);
|
|
rBindings.Invalidate(SID_GRID_VISIBLE);
|
|
}
|
|
break;
|
|
|
|
case SID_GRID_USE:
|
|
if ( pArgs && pArgs->GetItemState(nSlotId,true,&pItem) == SfxItemState::SET )
|
|
{
|
|
aGridOptions.SetUseGridSnap( static_cast<const SfxBoolItem*>(pItem)->GetValue() );
|
|
aViewOptions.SetGridOptions(aGridOptions);
|
|
rBindings.Invalidate(SID_GRID_USE);
|
|
}
|
|
break;
|
|
|
|
case SID_HELPLINES_MOVE:
|
|
if ( pArgs && pArgs->GetItemState(nSlotId,true,&pItem) == SfxItemState::SET )
|
|
{
|
|
aViewOptions.SetOption( VOPT_HELPLINES, static_cast<const SfxBoolItem*>(pItem)->GetValue() );
|
|
rBindings.Invalidate(SID_HELPLINES_MOVE);
|
|
}
|
|
break;
|
|
}
|
|
|
|
GetViewData().SetOptions(aViewOptions);
|
|
}
|
|
|
|
void ScTabViewShell::GetDrawOptState( SfxItemSet& rSet )
|
|
{
|
|
SfxBoolItem aBool;
|
|
|
|
const ScViewOptions& rViewOptions = GetViewData().GetOptions();
|
|
const ScGridOptions& rGridOptions = rViewOptions.GetGridOptions();
|
|
|
|
aBool.SetValue(rGridOptions.GetGridVisible());
|
|
aBool.SetWhich( SID_GRID_VISIBLE );
|
|
rSet.Put( aBool );
|
|
|
|
aBool.SetValue(rGridOptions.GetUseGridSnap());
|
|
aBool.SetWhich( SID_GRID_USE );
|
|
rSet.Put( aBool );
|
|
|
|
aBool.SetValue(rViewOptions.GetOption( VOPT_HELPLINES ));
|
|
aBool.SetWhich( SID_HELPLINES_MOVE );
|
|
rSet.Put( aBool );
|
|
}
|
|
|
|
void ScTabViewShell::ExecStyle( SfxRequest& rReq )
|
|
{
|
|
const SfxItemSet* pArgs = rReq.GetArgs();
|
|
const sal_uInt16 nSlotId = rReq.GetSlot();
|
|
if ( !pArgs && nSlotId != SID_STYLE_NEW_BY_EXAMPLE && nSlotId != SID_STYLE_UPDATE_BY_EXAMPLE )
|
|
{
|
|
// in case of vertical toolbar
|
|
GetDispatcher()->Execute( SID_STYLE_DESIGNER, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD );
|
|
return;
|
|
}
|
|
|
|
SfxBindings& rBindings = GetViewData().GetBindings();
|
|
const SCTAB nCurTab = GetViewData().GetTabNo();
|
|
ScDocShell* pDocSh = GetViewData().GetDocShell();
|
|
ScDocument& rDoc = pDocSh->GetDocument();
|
|
ScMarkData& rMark = GetViewData().GetMarkData();
|
|
ScModule* pScMod = ScModule::get();
|
|
SdrObject* pEditObject = GetDrawView()->GetTextEditObject();
|
|
OutlinerView* pOLV = GetDrawView()->GetTextEditOutlinerView();
|
|
ESelection aSelection = pOLV ? pOLV->GetSelection() : ESelection();
|
|
OUString aRefName;
|
|
bool bUndo = rDoc.IsUndoEnabled();
|
|
|
|
SfxStyleSheetBasePool* pStylePool = rDoc.GetStyleSheetPool();
|
|
SfxStyleSheetBase* pStyleSheet = nullptr;
|
|
|
|
bool bStyleToMarked = false;
|
|
bool bListAction = false;
|
|
bool bAddUndo = false; // add ScUndoModifyStyle (style modified)
|
|
auto xOldData = std::make_shared<ScStyleSaveData>(); // for undo/redo
|
|
auto xNewData = std::make_shared<ScStyleSaveData>();
|
|
|
|
SfxStyleFamily eFamily = SfxStyleFamily::Para;
|
|
const SfxUInt16Item* pFamItem;
|
|
const SfxStringItem* pFamilyNameItem;
|
|
if ( pArgs && (pFamItem = pArgs->GetItemIfSet( SID_STYLE_FAMILY )) )
|
|
eFamily = static_cast<SfxStyleFamily>(pFamItem->GetValue());
|
|
else if ( pArgs && (pFamilyNameItem = pArgs->GetItemIfSet( SID_STYLE_FAMILYNAME )) )
|
|
{
|
|
const OUString& sFamily = pFamilyNameItem->GetValue();
|
|
if (sFamily == "CellStyles")
|
|
eFamily = SfxStyleFamily::Para;
|
|
else if (sFamily == "PageStyles")
|
|
eFamily = SfxStyleFamily::Page;
|
|
else if (sFamily == "GraphicStyles")
|
|
eFamily = SfxStyleFamily::Frame;
|
|
}
|
|
|
|
OUString aStyleName;
|
|
sal_uInt16 nRetMask = 0xffff;
|
|
|
|
switch ( nSlotId )
|
|
{
|
|
case SID_STYLE_NEW:
|
|
{
|
|
const SfxPoolItem* pNameItem;
|
|
if (pArgs && SfxItemState::SET == pArgs->GetItemState( nSlotId, true, &pNameItem ))
|
|
aStyleName = static_cast<const SfxStringItem*>(pNameItem)->GetValue();
|
|
|
|
const SfxStringItem* pRefItem=nullptr;
|
|
if (pArgs && (pRefItem = pArgs->GetItemIfSet( SID_STYLE_REFERENCE )))
|
|
{
|
|
aRefName = pRefItem->GetValue();
|
|
}
|
|
|
|
pStyleSheet = &(pStylePool->Make( aStyleName, eFamily,
|
|
SfxStyleSearchBits::UserDefined ) );
|
|
|
|
if (pStyleSheet->HasParentSupport())
|
|
pStyleSheet->SetParent(aRefName);
|
|
}
|
|
break;
|
|
|
|
case SID_STYLE_APPLY:
|
|
{
|
|
const SfxStringItem* pNameItem = rReq.GetArg<SfxStringItem>(SID_APPLY_STYLE);
|
|
const SfxStringItem* pFamilyItem = rReq.GetArg<SfxStringItem>(SID_STYLE_FAMILYNAME);
|
|
if ( pFamilyItem && pNameItem )
|
|
{
|
|
try
|
|
{
|
|
css::uno::Reference< css::container::XNameAccess > xStyles;
|
|
css::uno::Reference< css::container::XNameAccess > xCont = pDocSh->GetModel()->getStyleFamilies();
|
|
xCont->getByName(pFamilyItem->GetValue()) >>= xStyles;
|
|
css::uno::Reference< css::beans::XPropertySet > xInfo;
|
|
xStyles->getByName( pNameItem->GetValue() ) >>= xInfo;
|
|
OUString aUIName;
|
|
xInfo->getPropertyValue(u"DisplayName"_ustr) >>= aUIName;
|
|
if ( !aUIName.isEmpty() )
|
|
rReq.AppendItem( SfxStringItem( SID_STYLE_APPLY, aUIName ) );
|
|
}
|
|
catch( css::uno::Exception& )
|
|
{
|
|
}
|
|
}
|
|
[[fallthrough]];
|
|
}
|
|
case SID_STYLE_EDIT:
|
|
case SID_STYLE_DELETE:
|
|
case SID_STYLE_HIDE:
|
|
case SID_STYLE_SHOW:
|
|
case SID_STYLE_NEW_BY_EXAMPLE:
|
|
{
|
|
const SfxPoolItem* pNameItem;
|
|
if (pArgs && SfxItemState::SET == pArgs->GetItemState(nSlotId, true, &pNameItem))
|
|
aStyleName = static_cast<const SfxStringItem*>(pNameItem)->GetValue();
|
|
else if ( nSlotId == SID_STYLE_NEW_BY_EXAMPLE )
|
|
{
|
|
weld::Window* pDialogParent = rReq.GetFrameWeld();
|
|
if (!pDialogParent)
|
|
pDialogParent = GetFrameWeld();
|
|
SfxNewStyleDlg aDlg(pDialogParent, *pStylePool, eFamily);
|
|
if (aDlg.run() != RET_OK)
|
|
return;
|
|
aStyleName = aDlg.GetName();
|
|
}
|
|
|
|
pStyleSheet = pStylePool->Find( aStyleName, eFamily );
|
|
|
|
xOldData->InitFromStyle( pStyleSheet );
|
|
}
|
|
break;
|
|
|
|
case SID_STYLE_WATERCAN:
|
|
{
|
|
bool bWaterCan = pScMod->GetIsWaterCan();
|
|
|
|
if( !bWaterCan )
|
|
{
|
|
const SfxPoolItem* pItem;
|
|
|
|
if (pArgs && SfxItemState::SET == pArgs->GetItemState(nSlotId, true, &pItem))
|
|
{
|
|
const SfxStringItem* pStrItem = dynamic_cast< const SfxStringItem *>( pItem );
|
|
if ( pStrItem )
|
|
{
|
|
aStyleName = pStrItem->GetValue();
|
|
pStyleSheet = pStylePool->Find( aStyleName, eFamily );
|
|
|
|
if ( pStyleSheet )
|
|
{
|
|
static_cast<ScStyleSheetPool*>(pStylePool)->
|
|
SetActualStyleSheet( pStyleSheet );
|
|
rReq.Done();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( !bWaterCan && pStyleSheet )
|
|
{
|
|
pScMod->SetWaterCan( true );
|
|
SetActivePointer( PointerStyle::Fill );
|
|
rReq.Done();
|
|
}
|
|
else
|
|
{
|
|
pScMod->SetWaterCan( false );
|
|
SetActivePointer( PointerStyle::Arrow );
|
|
rReq.Done();
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// set new style for paintbrush format mode
|
|
if ( nSlotId == SID_STYLE_APPLY && pScMod->GetIsWaterCan() && pStyleSheet )
|
|
static_cast<ScStyleSheetPool*>(pStylePool)->SetActualStyleSheet( pStyleSheet );
|
|
|
|
switch ( eFamily )
|
|
{
|
|
case SfxStyleFamily::Para:
|
|
{
|
|
switch ( nSlotId )
|
|
{
|
|
case SID_STYLE_DELETE:
|
|
{
|
|
if ( pStyleSheet )
|
|
{
|
|
RemoveStyleSheetInUse( pStyleSheet );
|
|
pStylePool->Remove( pStyleSheet );
|
|
InvalidateAttribs();
|
|
nRetMask = sal_uInt16(true);
|
|
bAddUndo = true;
|
|
rReq.Done();
|
|
}
|
|
else
|
|
nRetMask = sal_uInt16(false);
|
|
}
|
|
break;
|
|
|
|
case SID_STYLE_HIDE:
|
|
case SID_STYLE_SHOW:
|
|
{
|
|
if ( pStyleSheet )
|
|
{
|
|
pStyleSheet->SetHidden( nSlotId == SID_STYLE_HIDE );
|
|
InvalidateAttribs();
|
|
rReq.Done();
|
|
}
|
|
else
|
|
nRetMask = sal_uInt16(false);
|
|
}
|
|
break;
|
|
|
|
case SID_STYLE_APPLY:
|
|
{
|
|
if ( pStyleSheet && !pScMod->GetIsWaterCan() )
|
|
{
|
|
// apply style sheet to document
|
|
SetStyleSheetToMarked( static_cast<SfxStyleSheet*>(pStyleSheet) );
|
|
InvalidateAttribs();
|
|
rReq.Done();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SID_STYLE_NEW_BY_EXAMPLE:
|
|
case SID_STYLE_UPDATE_BY_EXAMPLE:
|
|
{
|
|
// create/replace style sheet by attributes
|
|
// at cursor position:
|
|
|
|
const ScPatternAttr* pAttrItem = nullptr;
|
|
|
|
// The query if marked, was always wrong here,
|
|
// so now no more, and just from the cursor.
|
|
// If attributes are to be removed from the selection, still need to be
|
|
// cautious not to adopt items from templates
|
|
// (GetSelectionPattern also collects items from originals) (# 44748 #)
|
|
SCCOL nCol = GetViewData().GetCurX();
|
|
SCROW nRow = GetViewData().GetCurY();
|
|
pAttrItem = rDoc.GetPattern( nCol, nRow, nCurTab );
|
|
|
|
SfxItemSet aAttrSet = pAttrItem->GetItemSet();
|
|
aAttrSet.ClearItem( ATTR_MERGE );
|
|
aAttrSet.ClearItem( ATTR_MERGE_FLAG );
|
|
|
|
// Do not adopt conditional formatting and validity,
|
|
// because they can not be edited in the template
|
|
aAttrSet.ClearItem( ATTR_VALIDDATA );
|
|
aAttrSet.ClearItem( ATTR_CONDITIONAL );
|
|
|
|
if ( SID_STYLE_NEW_BY_EXAMPLE == nSlotId )
|
|
{
|
|
if ( bUndo )
|
|
{
|
|
OUString aUndo = ScResId( STR_UNDO_EDITCELLSTYLE );
|
|
pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo, 0, GetViewShellId() );
|
|
bListAction = true;
|
|
}
|
|
|
|
bool bConvertBack = false;
|
|
SfxStyleSheet* pSheetInUse = const_cast<SfxStyleSheet*>(GetStyleSheetFromMarked());
|
|
|
|
// when a new style is present and is used in the selection,
|
|
// then the parent can not be adopted:
|
|
if ( pStyleSheet && pSheetInUse && pStyleSheet == pSheetInUse )
|
|
pSheetInUse = nullptr;
|
|
|
|
// if already present, first remove ...
|
|
if ( pStyleSheet )
|
|
{
|
|
// style pointer to names before erase,
|
|
// otherwise cells will get invalid pointer
|
|
//!!! As it happens, a method that does it for a particular style
|
|
rDoc.getCellAttributeHelper().AllStylesToNames();
|
|
bConvertBack = true;
|
|
pStylePool->Remove(pStyleSheet);
|
|
}
|
|
|
|
// ...and create new
|
|
pStyleSheet = &pStylePool->Make( aStyleName, eFamily,
|
|
SfxStyleSearchBits::UserDefined );
|
|
|
|
// when a style is present, then this will become
|
|
// the parent of the new style:
|
|
if ( pSheetInUse && pStyleSheet->HasParentSupport() )
|
|
pStyleSheet->SetParent( pSheetInUse->GetName() );
|
|
|
|
if ( bConvertBack )
|
|
// Name to style pointer
|
|
rDoc.getCellAttributeHelper().UpdateAllStyleSheets(rDoc);
|
|
else
|
|
rDoc.getCellAttributeHelper().CellStyleCreated(rDoc, aStyleName);
|
|
|
|
// Adopt attribute and use style
|
|
pStyleSheet->GetItemSet().Put( aAttrSet );
|
|
UpdateStyleSheetInUse( pStyleSheet );
|
|
|
|
// call SetStyleSheetToMarked after adding the ScUndoModifyStyle
|
|
// (pStyleSheet pointer is used!)
|
|
bStyleToMarked = true;
|
|
}
|
|
else // ( nSlotId == SID_STYLE_UPDATE_BY_EXAMPLE )
|
|
{
|
|
pStyleSheet = const_cast<SfxStyleSheet*>(GetStyleSheetFromMarked());
|
|
|
|
if ( pStyleSheet )
|
|
{
|
|
xOldData->InitFromStyle( pStyleSheet );
|
|
|
|
if ( bUndo )
|
|
{
|
|
OUString aUndo = ScResId( STR_UNDO_EDITCELLSTYLE );
|
|
pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo, 0, GetViewShellId() );
|
|
bListAction = true;
|
|
}
|
|
|
|
pStyleSheet->GetItemSet().Put( aAttrSet );
|
|
UpdateStyleSheetInUse( pStyleSheet );
|
|
|
|
// call SetStyleSheetToMarked after adding the ScUndoModifyStyle
|
|
// (pStyleSheet pointer is used!)
|
|
bStyleToMarked = true;
|
|
}
|
|
}
|
|
|
|
xNewData->InitFromStyle( pStyleSheet );
|
|
bAddUndo = true;
|
|
rReq.Done();
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
} // case SfxStyleFamily::Para:
|
|
break;
|
|
|
|
case SfxStyleFamily::Page:
|
|
{
|
|
switch ( nSlotId )
|
|
{
|
|
case SID_STYLE_DELETE:
|
|
{
|
|
nRetMask = sal_uInt16( nullptr != pStyleSheet );
|
|
if ( pStyleSheet )
|
|
{
|
|
if ( rDoc.RemovePageStyleInUse( pStyleSheet->GetName() ) )
|
|
{
|
|
ScPrintFunc( pDocSh, GetPrinter(true), nCurTab ).UpdatePages();
|
|
rBindings.Invalidate( SID_STATUS_PAGESTYLE );
|
|
rBindings.Invalidate( FID_RESET_PRINTZOOM );
|
|
}
|
|
pStylePool->Remove( pStyleSheet );
|
|
rBindings.Invalidate( SID_STYLE_FAMILY4 );
|
|
pDocSh->SetDocumentModified();
|
|
bAddUndo = true;
|
|
rReq.Done();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SID_STYLE_HIDE:
|
|
case SID_STYLE_SHOW:
|
|
{
|
|
nRetMask = sal_uInt16( nullptr != pStyleSheet );
|
|
if ( pStyleSheet )
|
|
{
|
|
pStyleSheet->SetHidden( nSlotId == SID_STYLE_HIDE );
|
|
rBindings.Invalidate( SID_STYLE_FAMILY4 );
|
|
pDocSh->SetDocumentModified();
|
|
rReq.Done();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SID_STYLE_APPLY:
|
|
{
|
|
nRetMask = sal_uInt16( nullptr != pStyleSheet );
|
|
if ( pStyleSheet && !pScMod->GetIsWaterCan() )
|
|
{
|
|
std::unique_ptr<ScUndoApplyPageStyle> pUndoAction;
|
|
SCTAB nTabCount = rDoc.GetTableCount();
|
|
for (const auto& rTab : rMark)
|
|
{
|
|
if (rTab >= nTabCount)
|
|
break;
|
|
OUString aOldName = rDoc.GetPageStyle( rTab );
|
|
if ( aOldName != aStyleName )
|
|
{
|
|
rDoc.SetPageStyle( rTab, aStyleName );
|
|
ScPrintFunc( pDocSh, GetPrinter(true), rTab ).UpdatePages();
|
|
if( !pUndoAction )
|
|
pUndoAction.reset(new ScUndoApplyPageStyle( pDocSh, aStyleName ));
|
|
pUndoAction->AddSheetAction( rTab, aOldName );
|
|
}
|
|
}
|
|
if( pUndoAction )
|
|
{
|
|
pDocSh->GetUndoManager()->AddUndoAction( std::move(pUndoAction) );
|
|
pDocSh->SetDocumentModified();
|
|
rBindings.Invalidate( SID_STYLE_FAMILY4 );
|
|
rBindings.Invalidate( SID_STATUS_PAGESTYLE );
|
|
rBindings.Invalidate( FID_RESET_PRINTZOOM );
|
|
}
|
|
rReq.Done();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SID_STYLE_NEW_BY_EXAMPLE:
|
|
{
|
|
const OUString aStrCurStyle = rDoc.GetPageStyle( nCurTab );
|
|
|
|
if ( aStrCurStyle != aStyleName )
|
|
{
|
|
SfxStyleSheetBase* pCurStyle = pStylePool->Find( aStrCurStyle, eFamily );
|
|
SfxItemSet aAttrSet = pCurStyle->GetItemSet();
|
|
SCTAB nInTab;
|
|
bool bUsed = rDoc.IsPageStyleInUse( aStyleName, &nInTab );
|
|
|
|
// if already present, first remove...
|
|
if ( pStyleSheet )
|
|
pStylePool->Remove( pStyleSheet );
|
|
|
|
// ...and create new
|
|
pStyleSheet = &pStylePool->Make( aStyleName, eFamily,
|
|
SfxStyleSearchBits::UserDefined );
|
|
|
|
// Adopt attribute
|
|
pStyleSheet->GetItemSet().Put( aAttrSet );
|
|
pDocSh->SetDocumentModified();
|
|
|
|
// If being used -> Update
|
|
if ( bUsed )
|
|
ScPrintFunc( pDocSh, GetPrinter(true), nInTab ).UpdatePages();
|
|
|
|
xNewData->InitFromStyle( pStyleSheet );
|
|
bAddUndo = true;
|
|
rReq.Done();
|
|
nRetMask = sal_uInt16(true);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
} // switch ( nSlotId )
|
|
} // case SfxStyleFamily::Page:
|
|
break;
|
|
|
|
case SfxStyleFamily::Frame:
|
|
{
|
|
switch ( nSlotId )
|
|
{
|
|
case SID_STYLE_DELETE:
|
|
{
|
|
if ( pStyleSheet )
|
|
{
|
|
pStylePool->Remove( pStyleSheet );
|
|
InvalidateAttribs();
|
|
pDocSh->SetDocumentModified();
|
|
nRetMask = sal_uInt16(true);
|
|
bAddUndo = true;
|
|
rReq.Done();
|
|
}
|
|
else
|
|
nRetMask = sal_uInt16(false);
|
|
}
|
|
break;
|
|
|
|
case SID_STYLE_HIDE:
|
|
case SID_STYLE_SHOW:
|
|
{
|
|
if ( pStyleSheet )
|
|
{
|
|
pStyleSheet->SetHidden( nSlotId == SID_STYLE_HIDE );
|
|
InvalidateAttribs();
|
|
rReq.Done();
|
|
}
|
|
else
|
|
nRetMask = sal_uInt16(false);
|
|
}
|
|
break;
|
|
|
|
case SID_STYLE_APPLY:
|
|
{
|
|
if ( pStyleSheet && !pScMod->GetIsWaterCan() )
|
|
{
|
|
GetScDrawView()->ScEndTextEdit();
|
|
GetScDrawView()->SetStyleSheet(static_cast<SfxStyleSheet*>(pStyleSheet), false);
|
|
|
|
GetScDrawView()->InvalidateAttribs();
|
|
InvalidateAttribs();
|
|
rReq.Done();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SID_STYLE_NEW_BY_EXAMPLE:
|
|
case SID_STYLE_UPDATE_BY_EXAMPLE:
|
|
{
|
|
if (nSlotId == SID_STYLE_NEW_BY_EXAMPLE)
|
|
{
|
|
pStyleSheet = &pStylePool->Make( aStyleName, eFamily, SfxStyleSearchBits::UserDefined );
|
|
|
|
// when a style is present, then this will become
|
|
// the parent of the new style:
|
|
if (SfxStyleSheet* pOldStyle = GetDrawView()->GetStyleSheet())
|
|
pStyleSheet->SetParent(pOldStyle->GetName());
|
|
}
|
|
else
|
|
{
|
|
pStyleSheet = GetDrawView()->GetStyleSheet();
|
|
xOldData->InitFromStyle( pStyleSheet );
|
|
}
|
|
|
|
if ( bUndo )
|
|
{
|
|
OUString aUndo = ScResId( STR_UNDO_EDITGRAPHICSTYLE );
|
|
pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo, 0, GetViewShellId() );
|
|
bListAction = true;
|
|
}
|
|
|
|
SfxItemSet aCoreSet(GetDrawView()->GetModel().GetItemPool());
|
|
GetDrawView()->GetAttributes(aCoreSet, true);
|
|
|
|
SfxItemSet* pStyleSet = &pStyleSheet->GetItemSet();
|
|
pStyleSet->Put(aCoreSet);
|
|
static_cast<SfxStyleSheet*>(pStyleSheet)->Broadcast(SfxHint(SfxHintId::DataChanged));
|
|
|
|
xNewData->InitFromStyle( pStyleSheet );
|
|
bAddUndo = true;
|
|
|
|
// call SetStyleSheet after adding the ScUndoModifyStyle
|
|
// (pStyleSheet pointer is used!)
|
|
bStyleToMarked = true;
|
|
rReq.Done();
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
} // switch ( eFamily )
|
|
|
|
// create new or process through Dialog:
|
|
if ( nSlotId == SID_STYLE_NEW || nSlotId == SID_STYLE_EDIT )
|
|
{
|
|
if (pStyleSheet)
|
|
{
|
|
ExecuteStyleEdit(rReq, pStyleSheet, nRetMask, nSlotId, bAddUndo, bUndo,
|
|
xOldData, xNewData, eFamily, bStyleToMarked, bListAction, pEditObject, aSelection);
|
|
return; // skip calling ExecuteStyleEditPost because we invoked an async dialog
|
|
}
|
|
}
|
|
|
|
ExecuteStyleEditPost(rReq, pStyleSheet, nSlotId, nRetMask, bAddUndo, bUndo,
|
|
eFamily, *xOldData, *xNewData, bStyleToMarked, bListAction, pEditObject, aSelection);
|
|
}
|
|
|
|
void ScTabViewShell::ExecuteStyleEdit(SfxRequest& rReq, SfxStyleSheetBase* pStyleSheet, sal_uInt16 nRetMask,
|
|
sal_uInt16 nSlotId, bool bAddUndo, bool bUndo,
|
|
const std::shared_ptr<ScStyleSaveData>& rOldData,
|
|
const std::shared_ptr<ScStyleSaveData>& rNewData, SfxStyleFamily eFamily,
|
|
bool bStyleToMarked, bool bListAction,
|
|
SdrObject* pEditObject, ESelection aSelection)
|
|
{
|
|
ScDocShell* pDocSh = GetViewData().GetDocShell();
|
|
ScDocument& rDoc = pDocSh->GetDocument();
|
|
SfxStyleFamily eFam = pStyleSheet->GetFamily();
|
|
VclPtr<SfxAbstractTabDialog> pDlg;
|
|
bool bPage = false;
|
|
|
|
// Store old Items from the style
|
|
std::shared_ptr<SfxItemSet> xOldSet = std::make_shared<SfxItemSet>(pStyleSheet->GetItemSet());
|
|
OUString aOldName = pStyleSheet->GetName();
|
|
|
|
switch ( eFam )
|
|
{
|
|
case SfxStyleFamily::Page:
|
|
bPage = true;
|
|
break;
|
|
|
|
case SfxStyleFamily::Para:
|
|
{
|
|
SfxItemSet& rSet = pStyleSheet->GetItemSet();
|
|
|
|
if ( const SfxUInt32Item* pItem = rSet.GetItemIfSet( ATTR_VALUE_FORMAT,
|
|
false ) )
|
|
{
|
|
// Produce and format NumberFormat Value from Value and Language
|
|
sal_uLong nFormat = pItem->GetValue();
|
|
LanguageType eLang =
|
|
rSet.Get(ATTR_LANGUAGE_FORMAT ).GetLanguage();
|
|
sal_uLong nLangFormat = rDoc.GetFormatTable()->
|
|
GetFormatForLanguageIfBuiltIn( nFormat, eLang );
|
|
if ( nLangFormat != nFormat )
|
|
{
|
|
SfxUInt32Item aNewItem( ATTR_VALUE_FORMAT, nLangFormat );
|
|
rSet.Put( aNewItem );
|
|
xOldSet->Put( aNewItem );
|
|
// Also in aOldSet for comparison after the dialog,
|
|
// Otherwise might miss a language change
|
|
}
|
|
}
|
|
|
|
std::unique_ptr<SvxNumberInfoItem> pNumberInfoItem(
|
|
ScTabViewShell::MakeNumberInfoItem(rDoc, GetViewData()));
|
|
|
|
pDocSh->PutItem( *pNumberInfoItem );
|
|
bPage = false;
|
|
|
|
// Definitely a SvxBoxInfoItem with Table = sal_False in set:
|
|
// (If there is no item, the dialogue will also delete the
|
|
// BORDER_OUTER SvxBoxItem from the Template Set)
|
|
if ( rSet.GetItemState( ATTR_BORDER_INNER, false ) != SfxItemState::SET )
|
|
{
|
|
SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
|
|
aBoxInfoItem.SetTable(false); // no inner lines
|
|
aBoxInfoItem.SetDist(true);
|
|
aBoxInfoItem.SetMinDist(false);
|
|
rSet.Put( aBoxInfoItem );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SfxStyleFamily::Frame:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
SetInFormatDialog(true);
|
|
|
|
SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
|
|
rStyleSet.MergeRange( XATTR_FILL_FIRST, XATTR_FILL_LAST );
|
|
|
|
ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
|
|
|
|
weld::Window* pDialogParent = rReq.GetFrameWeld();
|
|
if (!pDialogParent)
|
|
pDialogParent = GetFrameWeld();
|
|
|
|
if (eFam == SfxStyleFamily::Frame)
|
|
pDlg = pFact->CreateScDrawStyleDlg(pDialogParent, *pStyleSheet, GetDrawView());
|
|
else
|
|
pDlg = pFact->CreateScStyleDlg(pDialogParent, *pStyleSheet, bPage);
|
|
|
|
auto xRequest = std::make_shared<SfxRequest>(rReq);
|
|
rReq.Ignore(); // the 'old' request is not relevant any more
|
|
pDlg->StartExecuteAsync(
|
|
[this, pDlg, xRequest=std::move(xRequest), pStyleSheet,
|
|
nRetMask, xOldSet=std::move(xOldSet), nSlotId, bAddUndo, bUndo,
|
|
xOldData = rOldData, xNewData = rNewData, aOldName, eFamily, bStyleToMarked,
|
|
bListAction, pEditObject, aSelection]
|
|
(sal_Int32 nResult) mutable -> void
|
|
{
|
|
SetInFormatDialog(false);
|
|
ExecuteStyleEditDialog(pDlg, pStyleSheet, nResult, nRetMask, xOldSet, nSlotId,
|
|
bAddUndo, *xNewData, aOldName);
|
|
pDlg->disposeOnce();
|
|
ExecuteStyleEditPost(*xRequest, pStyleSheet, nSlotId, nRetMask, bAddUndo, bUndo, eFamily,
|
|
*xOldData, *xNewData, bStyleToMarked, bListAction, pEditObject, aSelection);
|
|
}
|
|
);
|
|
}
|
|
|
|
void ScTabViewShell::ExecuteStyleEditDialog(VclPtr<SfxAbstractTabDialog> pDlg,
|
|
SfxStyleSheetBase* pStyleSheet, sal_uInt16 nResult,
|
|
sal_uInt16& rnRetMask, std::shared_ptr<SfxItemSet> xOldSet, const sal_uInt16 nSlotId,
|
|
bool& rbAddUndo, ScStyleSaveData& rNewData, std::u16string_view aOldName)
|
|
{
|
|
ScDocShell* pDocSh = GetViewData().GetDocShell();
|
|
ScDocument& rDoc = pDocSh->GetDocument();
|
|
SfxBindings& rBindings = GetViewData().GetBindings();
|
|
SfxStyleSheetBasePool* pStylePool = rDoc.GetStyleSheetPool();
|
|
SfxStyleFamily eFam = pStyleSheet->GetFamily();
|
|
if ( nResult == RET_OK )
|
|
{
|
|
const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
|
|
|
|
if ( pOutSet )
|
|
{
|
|
rnRetMask = sal_uInt16(pStyleSheet->GetMask());
|
|
|
|
// Attribute comparisons (earlier in ModifyStyleSheet) now here
|
|
// with the old values (the style is already changed)
|
|
if ( SfxStyleFamily::Para == eFam )
|
|
{
|
|
SfxItemSet& rNewSet = pStyleSheet->GetItemSet();
|
|
bool bNumFormatChanged;
|
|
if ( ScGlobal::CheckWidthInvalidate(
|
|
bNumFormatChanged, rNewSet, *xOldSet ) )
|
|
rDoc.InvalidateTextWidth( nullptr, nullptr, bNumFormatChanged );
|
|
|
|
SCTAB nTabCount = rDoc.GetTableCount();
|
|
for (SCTAB nTab=0; nTab<nTabCount; nTab++)
|
|
rDoc.SetStreamValid(nTab, false);
|
|
|
|
sal_uLong nOldFormat = xOldSet->Get( ATTR_VALUE_FORMAT ).GetValue();
|
|
sal_uLong nNewFormat = rNewSet.Get( ATTR_VALUE_FORMAT ).GetValue();
|
|
if ( nNewFormat != nOldFormat )
|
|
{
|
|
ScInterpreterContext& rContext = rDoc.GetNonThreadedContext();
|
|
const SvNumberformat* pOld = rContext.NFGetFormatEntry( nOldFormat );
|
|
const SvNumberformat* pNew = rContext.NFGetFormatEntry( nNewFormat );
|
|
if ( pOld && pNew && pOld->GetLanguage() != pNew->GetLanguage() )
|
|
rNewSet.Put( SvxLanguageItem(
|
|
pNew->GetLanguage(), ATTR_LANGUAGE_FORMAT ) );
|
|
}
|
|
|
|
rDoc.getCellAttributeHelper().CellStyleCreated(rDoc, pStyleSheet->GetName());
|
|
}
|
|
else if ( SfxStyleFamily::Page == eFam )
|
|
{
|
|
//! Here also queries for Page Styles
|
|
|
|
OUString aNewName = pStyleSheet->GetName();
|
|
if ( aNewName != aOldName &&
|
|
rDoc.RenamePageStyleInUse( aOldName, aNewName ) )
|
|
{
|
|
rBindings.Invalidate( SID_STATUS_PAGESTYLE );
|
|
rBindings.Invalidate( FID_RESET_PRINTZOOM );
|
|
}
|
|
|
|
rDoc.ModifyStyleSheet( *pStyleSheet, *pOutSet );
|
|
rBindings.Invalidate( FID_RESET_PRINTZOOM );
|
|
}
|
|
else
|
|
{
|
|
SfxItemSet& rAttr = pStyleSheet->GetItemSet();
|
|
sdr::properties::CleanupFillProperties(rAttr);
|
|
|
|
// check for unique names of named items for xml
|
|
auto checkForUniqueItem = [&] (auto nWhichId)
|
|
{
|
|
if (auto pOldItem = rAttr.GetItemIfSet(nWhichId, false))
|
|
{
|
|
if (auto pNewItem = pOldItem->checkForUniqueItem(GetDrawView()->GetModel()))
|
|
rAttr.Put(std::move(pNewItem));
|
|
}
|
|
};
|
|
|
|
checkForUniqueItem(XATTR_FILLBITMAP);
|
|
checkForUniqueItem(XATTR_LINEDASH);
|
|
checkForUniqueItem(XATTR_LINESTART);
|
|
checkForUniqueItem(XATTR_LINEEND);
|
|
checkForUniqueItem(XATTR_FILLGRADIENT);
|
|
checkForUniqueItem(XATTR_FILLFLOATTRANSPARENCE);
|
|
checkForUniqueItem(XATTR_FILLHATCH);
|
|
|
|
static_cast<SfxStyleSheet*>(pStyleSheet)->Broadcast(SfxHint(SfxHintId::DataChanged));
|
|
GetScDrawView()->InvalidateAttribs();
|
|
}
|
|
|
|
pDocSh->SetDocumentModified();
|
|
|
|
if ( SfxStyleFamily::Para == eFam )
|
|
{
|
|
ScTabViewShell::UpdateNumberFormatter(
|
|
*( pDocSh->GetItem(SID_ATTR_NUMBERFORMAT_INFO) ));
|
|
|
|
UpdateStyleSheetInUse( pStyleSheet );
|
|
InvalidateAttribs();
|
|
}
|
|
|
|
rNewData.InitFromStyle( pStyleSheet );
|
|
rbAddUndo = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( nSlotId == SID_STYLE_NEW )
|
|
pStylePool->Remove( pStyleSheet );
|
|
else
|
|
{
|
|
// If in the meantime something was painted with the
|
|
// temporary changed item set
|
|
pDocSh->PostPaintGridAll();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ScTabViewShell::ExecuteStyleEditPost(SfxRequest& rReq, SfxStyleSheetBase* pStyleSheet,
|
|
sal_uInt16 nSlotId, sal_uInt16 nRetMask, bool bAddUndo, bool bUndo,
|
|
const SfxStyleFamily eFamily,
|
|
ScStyleSaveData& rOldData, ScStyleSaveData& rNewData,
|
|
bool bStyleToMarked, bool bListAction,
|
|
SdrObject* pEditObject, ESelection aSelection)
|
|
{
|
|
ScDocShell* pDocSh = GetViewData().GetDocShell();
|
|
|
|
rReq.SetReturnValue( SfxUInt16Item( nSlotId, nRetMask ) );
|
|
|
|
if ( bAddUndo && bUndo)
|
|
pDocSh->GetUndoManager()->AddUndoAction(
|
|
std::make_unique<ScUndoModifyStyle>( pDocSh, eFamily, rOldData, rNewData ) );
|
|
|
|
if ( bStyleToMarked )
|
|
{
|
|
// call SetStyleSheetToMarked after adding the ScUndoModifyStyle,
|
|
// so redo will find the modified style
|
|
if (eFamily == SfxStyleFamily::Para)
|
|
{
|
|
SetStyleSheetToMarked( static_cast<SfxStyleSheet*>(pStyleSheet) );
|
|
}
|
|
else if (eFamily == SfxStyleFamily::Frame)
|
|
{
|
|
GetScDrawView()->ScEndTextEdit();
|
|
GetScDrawView()->SetStyleSheet( static_cast<SfxStyleSheet*>(pStyleSheet), false );
|
|
}
|
|
InvalidateAttribs();
|
|
}
|
|
|
|
if ( bListAction )
|
|
pDocSh->GetUndoManager()->LeaveListAction();
|
|
|
|
// The above call to ScEndTextEdit left us in an inconsistent state:
|
|
// Text editing isn't active, but the text edit shell still is. And we
|
|
// couldn't just deactivate it fully, because in case of editing a
|
|
// comment, that will make the comment disappear. So let's try to
|
|
// reactivate text editing instead:
|
|
auto pFuText = dynamic_cast<FuText*>(GetDrawFuncPtr());
|
|
if (pFuText && pEditObject != GetDrawView()->GetTextEditObject())
|
|
{
|
|
pFuText->SetInEditMode(pEditObject);
|
|
if (GetDrawView()->GetTextEditOutlinerView())
|
|
GetDrawView()->GetTextEditOutlinerView()->SetSelection(aSelection);
|
|
}
|
|
}
|
|
|
|
void ScTabViewShell::GetStyleState( SfxItemSet& rSet )
|
|
{
|
|
ScDocument& rDoc = GetViewData().GetDocument();
|
|
SfxStyleSheetBasePool* pStylePool = rDoc.GetStyleSheetPool();
|
|
|
|
bool bProtected = false;
|
|
SCTAB nTabCount = rDoc.GetTableCount();
|
|
for (SCTAB i=0; i<nTabCount && !bProtected; i++)
|
|
if (rDoc.IsTabProtected(i)) // look after protected table
|
|
bProtected = true;
|
|
|
|
SfxWhichIter aIter(rSet);
|
|
sal_uInt16 nWhich = aIter.FirstWhich();
|
|
sal_uInt16 nSlotId = 0;
|
|
|
|
while ( nWhich )
|
|
{
|
|
nSlotId = SfxItemPool::IsWhich( nWhich )
|
|
? GetPool().GetSlotId( nWhich )
|
|
: nWhich;
|
|
|
|
switch ( nSlotId )
|
|
{
|
|
case SID_STYLE_APPLY:
|
|
if ( !pStylePool )
|
|
rSet.DisableItem( nSlotId );
|
|
break;
|
|
|
|
case SID_STYLE_FAMILY2: // cell style sheets
|
|
{
|
|
SfxStyleSheet* pStyleSheet = const_cast<SfxStyleSheet*>(GetStyleSheetFromMarked());
|
|
|
|
if ( pStyleSheet )
|
|
rSet.Put( SfxTemplateItem( nSlotId, pStyleSheet->GetName() ) );
|
|
else
|
|
rSet.Put( SfxTemplateItem( nSlotId, OUString() ) );
|
|
}
|
|
break;
|
|
|
|
case SID_STYLE_FAMILY3: // drawing style sheets
|
|
{
|
|
SfxStyleSheet* pStyleSheet = GetDrawView()->GetStyleSheet();
|
|
|
|
if ( pStyleSheet )
|
|
rSet.Put( SfxTemplateItem( nSlotId, pStyleSheet->GetName() ) );
|
|
else
|
|
rSet.Put( SfxTemplateItem( nSlotId, OUString() ) );
|
|
}
|
|
break;
|
|
|
|
case SID_STYLE_FAMILY4: // page style sheets
|
|
{
|
|
SCTAB nCurTab = GetViewData().GetTabNo();
|
|
OUString aPageStyle = rDoc.GetPageStyle( nCurTab );
|
|
SfxStyleSheet* pStyleSheet = pStylePool ? static_cast<SfxStyleSheet*>(pStylePool->
|
|
Find( aPageStyle, SfxStyleFamily::Page )) : nullptr;
|
|
|
|
if ( pStyleSheet )
|
|
rSet.Put( SfxTemplateItem( nSlotId, aPageStyle ) );
|
|
else
|
|
rSet.Put( SfxTemplateItem( nSlotId, OUString() ) );
|
|
}
|
|
break;
|
|
|
|
case SID_STYLE_WATERCAN:
|
|
{
|
|
rSet.Put(SfxBoolItem(nSlotId, ScModule::get()->GetIsWaterCan()));
|
|
}
|
|
break;
|
|
|
|
case SID_STYLE_UPDATE_BY_EXAMPLE:
|
|
{
|
|
std::unique_ptr<SfxUInt16Item> pFamilyItem;
|
|
GetViewFrame().GetBindings().QueryState(SID_STYLE_FAMILY, pFamilyItem);
|
|
|
|
bool bPage = pFamilyItem && SfxStyleFamily::Page == static_cast<SfxStyleFamily>(pFamilyItem->GetValue());
|
|
|
|
if ( bProtected || bPage )
|
|
rSet.DisableItem( nSlotId );
|
|
}
|
|
break;
|
|
|
|
case SID_STYLE_EDIT:
|
|
case SID_STYLE_DELETE:
|
|
case SID_STYLE_HIDE:
|
|
case SID_STYLE_SHOW:
|
|
{
|
|
std::unique_ptr<SfxUInt16Item> pFamilyItem;
|
|
GetViewFrame().GetBindings().QueryState(SID_STYLE_FAMILY, pFamilyItem);
|
|
bool bPage = pFamilyItem && SfxStyleFamily::Page == static_cast<SfxStyleFamily>(pFamilyItem->GetValue());
|
|
|
|
if ( bProtected && !bPage )
|
|
rSet.DisableItem( nSlotId );
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
nWhich = aIter.NextWhich();
|
|
}
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|