/* -*- 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 <undoblk.hxx>
#include <document.hxx>
#include <docsh.hxx>
#include <tabvwsh.hxx>
#include <olinetab.hxx>
#include <globstr.hrc>
#include <scresid.hxx>
#include <global.hxx>
#include <target.hxx>
#include <columnspanset.hxx>
#include <undoolk.hxx>
#include <svx/svdundo.hxx>
/** Change column widths or row heights */
ScUndoWidthOrHeight::ScUndoWidthOrHeight( ScDocShell& rNewDocShell,
const ScMarkData& rMark,
SCCOLROW nNewStart, SCTAB nNewStartTab, SCCOLROW nNewEnd, SCTAB nNewEndTab,
ScDocumentUniquePtr pNewUndoDoc, std::vector<sc::ColRowSpan>&& rRanges,
std::unique_ptr<ScOutlineTable> pNewUndoTab,
ScSizeMode eNewMode, sal_uInt16 nNewSizeTwips,
bool bNewWidth ) :
ScSimpleUndo( rNewDocShell ),
aMarkData( rMark ),
nStart( nNewStart ),
nEnd( nNewEnd ),
nStartTab( nNewStartTab ),
nEndTab( nNewEndTab ),
pUndoDoc( std::move(pNewUndoDoc) ),
pUndoTab( std::move(pNewUndoTab) ),
maRanges( std::move(rRanges) ),
nNewSize( nNewSizeTwips ),
bWidth( bNewWidth ),
eMode( eNewMode )
{
pDrawUndo = GetSdrUndoAction( &rDocShell.GetDocument() );
}
ScUndoWidthOrHeight::~ScUndoWidthOrHeight()
{
pUndoDoc.reset();
pUndoTab.reset();
pDrawUndo.reset();
}
OUString ScUndoWidthOrHeight::GetComment()
const
{
// [ "optimal " ] "Column width" | "row height"
return ( bWidth ?
( ( eMode == SC_SIZE_OPTIMAL )?
ScResId( STR_UNDO_OPTCOLWIDTH ) :
ScResId( STR_UNDO_COLWIDTH )
) :
( ( eMode == SC_SIZE_OPTIMAL )?
ScResId( STR_UNDO_OPTROWHEIGHT ) :
ScResId( STR_UNDO_ROWHEIGHT )
) );
}
void ScUndoWidthOrHeight::Undo()
{
BeginUndo();
ScDocument& rDoc = rDocShell.GetDocument();
SCCOLROW nPaintStart = nStart > 0 ? nStart-1 :
static_cast<SCCOLROW>(0);
if (eMode==SC_SIZE_OPTIMAL)
{
if ( SetViewMarkData( aMarkData ) )
nPaintStart = 0;
// paint all, because of changed selection
}
//! outlines from all tables?
if (pUndoTab)
// Outlines are included when saving ?
rDoc.SetOutlineTable( nStartTab, pUndoTab.get() );
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
SCTAB nTabCount = rDoc.GetTableCount();
for (
const auto& rTab : aMarkData)
{
if (rTab >= nTabCount)
break;
if (pViewShell)
pViewShell->OnLOKSetWidthOrHeight(nStart, bWidth);
if (bWidth)
// Width
{
pUndoDoc->CopyToDocument(
static_cast<SCCOL>(nStart), 0, rTab,
static_cast<SCCOL>(nEnd), rDoc.MaxRow(), rTab, InsertDeleteFlags::NONE,
false, rDoc);
rDoc.UpdatePageBreaks( rTab );
rDocShell.PostPaint(
static_cast<SCCOL>(nPaintStart), 0, rTab,
rDoc.MaxCol(), rDoc.MaxRow(), rTab, PaintPartFlags::Grid | PaintPartFlags::Top );
}
else // Height
{
pUndoDoc->CopyToDocument(0, nStart, rTab, rDoc.MaxCol(), nEnd, rTab, InsertDeleteFlags:
:NONE, false, rDoc);
rDoc.UpdatePageBreaks( rTab );
rDocShell.PostPaint( 0, nPaintStart, rTab, rDoc.MaxCol(), rDoc.MaxRow(), rTab, PaintPartFlags::Grid | PaintPartFlags::Left );
}
}
DoSdrUndoAction( pDrawUndo.get(), &rDoc );
if (pViewShell)
{
SCTAB nCurrentTab = pViewShell->GetViewData().GetTabNo();
bool bAffectsVisibility = (eMode != SC_SIZE_ORIGINAL && eMode != SC_SIZE_VISOPT);
ScTabViewShell::notifyAllViewsSheetGeomInvalidation(
pViewShell, bWidth /* bColumns */, !bWidth /* bRows */,
true /* bSizes*/, bAffectsVisibility /* bHidden */, bAffectsVisibility /* bFiltered */,
false /* bGroups */, nCurrentTab);
pViewShell->UpdateScrollBars(bWidth ? COLUMN_HEADER : ROW_HEADER);
if ( nCurrentTab < nStartTab || nCurrentTab > nEndTab )
pViewShell->SetTabNo( nStartTab );
}
EndUndo();
}
void ScUndoWidthOrHeight::Redo()
{
BeginRedo();
ScDocument& rDoc = rDocShell.GetDocument();
bool bPaintAll = false;
if (eMode==SC_SIZE_OPTIMAL)
{
if ( SetViewMarkData( aMarkData ) )
bPaintAll = true; // paint all, because of changed selection
}
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
if (pViewShell)
{
SCTAB nTab = pViewShell->GetViewData().GetTabNo();
if ( nTab < nStartTab || nTab > nEndTab )
pViewShell->SetTabNo( nStartTab );
// SetWidthOrHeight changes current sheet!
pViewShell->SetWidthOrHeight(
bWidth, maRanges, eMode, nNewSize, false, &aMarkData);
}
// paint grid if selection was changed directly at the MarkData
if (bPaintAll)
rDocShell.PostPaint( 0, 0, nStartTab, rDoc.MaxCol(), rDoc.MaxRow(), nEndTab, PaintPartFlags::Grid );
EndRedo();
}
void ScUndoWidthOrHeight::Repeat(SfxRepeatTarget& rTarget)
{
if (auto pViewTarget = dynamic_cast<ScTabViewTarget*>( &rTarget))
pViewTarget->GetViewShell().SetMarkedWidthOrHeight( bWidth, eMode, nNewSize );
}
bool ScUndoWidthOrHeight::CanRepeat(SfxRepeatTarget& rTarget) const
{
return dynamic_cast<const ScTabViewTarget*>( &rTarget) != nullptr;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */