if (!nRet || !SdrUndoManager::GetUndoActionCount()) return nRet;
const SfxUndoAction* pAction = SdrUndoManager::GetUndoAction(); if (!pAction) return nRet;
if (!m_bRepair)
{ // If another view created the last undo action, prevent undoing it from this view.
ViewShellId nViewShellId = m_pView->GetViewShellId(); if (pAction->GetViewShellId() != nViewShellId)
nRet = 0;
}
if (!nRet || !SdrUndoManager::GetRedoActionCount()) return nRet;
const SfxUndoAction* pAction = SdrUndoManager::GetRedoAction(); if (!pAction) return nRet;
if (!m_bRepair)
{ // If another view created the first redo action, prevent redoing it from this view.
ViewShellId nViewShellId = m_pView->GetViewShellId(); if (pAction->GetViewShellId() != nViewShellId)
nRet = 0;
}
if (nCount) // otherwise: empty list action not inserted!
{
assert(pLastUndo);
assert(SwUndoId::START != eUndoId); auto pListAction = dynamic_cast<SfxListUndoAction*>(SdrUndoManager::GetUndoAction());
assert(pListAction); if (SwUndoId::END != eUndoId)
{
OSL_ENSURE(static_cast<SwUndoId>(pListAction->GetId()) == eUndoId, "EndUndo(): given ID different from StartUndo()"); // comment set by caller of EndUndo
OUString comment = GetUndoComment(eUndoId); if (pRewriter)
{
comment = pRewriter->Apply(comment);
}
pListAction->SetComment(comment);
} elseif (SwUndoId::START != static_cast<SwUndoId>(pListAction->GetId()))
{ // comment set by caller of StartUndo: nothing to do here
} elseif (pLastUndo)
{ // comment was not set at StartUndo or EndUndo: // take comment of last contained action // (note that this works recursively, i.e. the last contained // action may be a list action created by StartUndo/EndUndo)
OUString const comment(pLastUndo->GetComment());
pListAction->SetComment(comment);
} else
{
OSL_ENSURE(false, "EndUndo(): no comment?");
}
} else
{
eUndoId = SwUndoId::EMPTY;
}
return eUndoId;
}
/** *ChecksifthetopmostundoactionownedbypViewisindependentfromthetopmostactionundo *action.
*/ bool UndoManager::IsViewUndoActionIndependent(const SwView* pView, sal_uInt16& rOffset) const
{ if (GetUndoActionCount() <= 1)
{ // Single or less undo, owned by another view. returnfalse;
}
if (!pView)
{ returnfalse;
}
// Last undo action that doesn't belong to the view. const SfxUndoAction* pTopAction = GetUndoAction();
ViewShellId nViewId = pView->GetViewShellId();
// Earlier undo action that belongs to the view, but is not the top one. const SfxUndoAction* pViewAction = nullptr;
size_t nOffset = 0; for (size_t i = 0; i < GetUndoActionCount(); ++i)
{ const SfxUndoAction* pAction = GetUndoAction(i); if (pAction->GetViewShellId() == nViewId)
{
pViewAction = pAction;
nOffset = i; break;
}
}
if (!pViewAction)
{ // Found no earlier undo action that belongs to the view. returnfalse;
}
auto pTopSwAction = dynamic_cast<const SwUndo*>(pTopAction); if (!pTopSwAction || pTopSwAction->GetId() != SwUndoId::TYPING)
{ returnfalse;
}
auto pViewSwAction = dynamic_cast<const SwUndo*>(pViewAction); if (!pViewSwAction || pViewSwAction->GetId() != SwUndoId::TYPING)
{ returnfalse;
}
for (size_t i = 0; i < GetRedoActionCount(); ++i)
{ auto pRedoAction = dynamic_cast<const SwUndo*>(GetRedoAction(i)); if (!pRedoAction || pRedoAction->GetId() != SwUndoId::TYPING)
{ returnfalse;
}
constauto& rRedoInsert = *static_cast<const SwUndoInsert*>(pRedoAction); if (!rViewInsert.IsIndependent(rRedoInsert) && rRedoInsert.GetViewShellId() != nViewId)
{ // Dependent redo action and owned by another view. returnfalse;
}
}
if (!rViewInsert.IsIndependent(rTopInsert))
{ returnfalse;
}
rOffset = nOffset; returntrue;
}
bool
UndoManager::GetLastUndoInfo(
OUString *const o_pStr, SwUndoId *const o_pId, const SwView* pView) const
{ // this is actually expected to work on the current level, // but that was really not obvious from the previous implementation... if (!SdrUndoManager::GetUndoActionCount())
{ returnfalse;
}
if (comphelper::LibreOfficeKit::isActive() && !m_bRepair)
{ // If another view created the undo action, prevent undoing it from this view.
ViewShellId nViewShellId = pView ? pView->GetViewShellId() : m_pDocShell->GetView()->GetViewShellId(); // Unless we know that the other view's undo action is independent from us. if (pAction->GetViewShellId() != nViewShellId
&& !IsViewUndoActionIndependent(pView, o3tl::temporary(sal_uInt16())))
{ if (o_pId)
{
*o_pId = SwUndoId::CONFLICT;
} returnfalse;
}
}
SwUndoComments_t UndoManager::GetUndoComments() const
{
OSL_ENSURE(!SdrUndoManager::IsInListAction(), "GetUndoComments() called while in list action?");
SwUndoComments_t ret; const size_t nUndoCount(SdrUndoManager::GetUndoActionCount(TopLevel)); for (size_t n = 0; n < nUndoCount; ++n)
{
OUString const comment(
SdrUndoManager::GetUndoActionComment(n, TopLevel));
ret.push_back(comment);
}
if (comphelper::LibreOfficeKit::isActive() && !m_bRepair)
{ // If another view created the undo action, prevent redoing it from this view.
ViewShellId nViewShellId = pView ? pView->GetViewShellId() : m_pDocShell->GetView()->GetViewShellId(); if (pAction->GetViewShellId() != nViewShellId)
{ if (o_pId)
{
*o_pId = SwUndoId::CONFLICT;
} returnfalse;
}
}
SwUndoComments_t UndoManager::GetRedoComments() const
{
OSL_ENSURE(!SdrUndoManager::IsInListAction(), "GetRedoComments() called while in list action?");
SwUndoComments_t ret; const size_t nRedoCount(SdrUndoManager::GetRedoActionCount(TopLevel)); for (size_t n = 0; n < nRedoCount; ++n)
{
OUString const comment(
SdrUndoManager::GetRedoActionComment(n, TopLevel));
ret.push_back(comment);
}
// if the undo nodes array is too large, delete some actions while (UNDO_ACTION_LIMIT < sal_Int32(GetUndoNodes().Count()))
{ if (!RemoveOldestUndoAction()) break;
}
}
namespace {
class CursorGuard
{ public:
CursorGuard(SwEditShell & rShell, boolconst bSave)
: m_rShell(rShell)
, m_bSaveCursor(bSave)
{ if (m_bSaveCursor)
{
m_rShell.Push(); // prevent modification of current cursor
}
}
~CursorGuard() COVERITY_NOEXCEPT_FALSE
{ if (m_bSaveCursor)
{
m_rShell.Pop(SwCursorShell::PopMode::DeleteCurrent);
}
} private:
SwEditShell & m_rShell; boolconst m_bSaveCursor;
};
// in case the model has controllers locked, the Undo should not // change the view cursors! boolconst bSaveCursors(pEditShell->CursorsLocked());
CursorGuard aCursorGuard(*pEditShell, bSaveCursors); if (!bSaveCursors)
{ // (in case Undo was called via API) clear the cursors:
pEditShell->KillPams();
pEditShell->SetMark();
pEditShell->ClearMark();
}
// N.B. these may throw! if (UndoOrRedoType::Undo == undoOrRedo)
{
bRet = SdrUndoManager::UndoWithContext(context);
} else
{
bRet = SdrUndoManager::RedoWithContext(context);
}
if (bRet)
{ // if we are at the "last save" position, the document is not modified if (SdrUndoManager::HasTopUndoActionMark(m_UndoSaveMark))
{
m_rState.ResetModified();
} else
{
m_rState.SetModified();
}
}
void UndoManager::EmptyActionsChanged()
{ if (m_pDocShell)
{
m_pDocShell->Broadcast(SfxHint(SfxHintId::DocumentRepair));
}
}
/** N.B.: this does _not_ call SdrUndoManager::Repeat because it is not possibletowrapalistactionaroundit: callingEnterListActionherewillcauseSdrUndoManager::Repeat torepeatthelistaction!
*/ bool UndoManager::Repeat(::sw::RepeatContext & rContext,
sal_uInt16 const nRepeatCount)
{ if (SdrUndoManager::IsInListAction())
{
OSL_ENSURE(false, "repeat in open list action???"); returnfalse;
} if (!SdrUndoManager::GetUndoActionCount(TopLevel))
{ returnfalse;
}
SfxUndoAction *const pRepeatAction(GetUndoAction());
assert(pRepeatAction); if (!pRepeatAction->CanRepeat(rContext))
{ returnfalse;
}
OUString const comment(pRepeatAction->GetComment());
OUString const rcomment(pRepeatAction->GetRepeatComment(rContext));
SwUndoId nId; if (autoconst* const pSwAction = dynamic_cast<SwUndo*>(pRepeatAction))
nId = pSwAction->GetId(); elseif (autoconst* const pListAction = dynamic_cast<SfxListUndoAction*>(pRepeatAction))
nId = static_cast<SwUndoId>(pListAction->GetId()); else returnfalse; if (DoesUndo())
{
ViewShellId nViewShellId(-1); if (m_pDocShell)
{ if (const SwView* pView = m_pDocShell->GetView())
nViewShellId = pView->GetViewShellId();
}
EnterListAction(comment, rcomment, static_cast<sal_uInt16>(nId), nViewShellId);
}
SwPaM* pTmp = rContext.m_pCurrentPaM; for(SwPaM& rPaM : rContext.GetRepeatPaM().GetRingContainer())
{ // iterate over ring
rContext.m_pCurrentPaM = &rPaM; if (DoesUndo() && & rPaM != pTmp)
{
m_isAddWithIgnoreRepeat = true;
} for (sal_uInt16 nRptCnt = nRepeatCount; nRptCnt > 0; --nRptCnt)
{
pRepeatAction->Repeat(rContext);
} if (DoesUndo() && & rPaM != pTmp)
{
m_isAddWithIgnoreRepeat = false;
}
rContext.m_bDeleteRepeated = false; // reset for next PaM
}
rContext.m_pCurrentPaM = pTmp;
if (DoesUndo())
{
LeaveListAction();
} returntrue;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.