tdf#133957 sw: SelectAll should select fly in empty section
Ctrl+A should select everything in the section; if the section is empty, there's no text to select, and then the shell will cancel the selection because SwCursorShell::HasSelection() returns false - so check if there are flys anchored there, which fixes the Copy. To fix Delete, a few more checks for empty selection need to be changed. Change-Id: If54160bdca976ad5f153b89cf8492f4da1e774b7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96324 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@cib.de>
This commit is contained in:
parent
786d0b9abf
commit
2d89b9929e
6 changed files with 49 additions and 24 deletions
|
@ -152,6 +152,9 @@ bool IsDestroyFrameAnchoredAtChar(SwPosition const & rAnchorPos,
|
|||
bool IsSelectFrameAnchoredAtPara(SwPosition const & rAnchorPos,
|
||||
SwPosition const & rStart, SwPosition const & rEnd,
|
||||
DelContentType const nDelContentType = DelContentType::AllMask);
|
||||
/// check at-char and at-para flys in rDoc
|
||||
bool IsFlySelectedByCursor(SwDoc const & rDoc,
|
||||
SwPosition const & rStart, SwPosition const & rEnd);
|
||||
|
||||
// This class has to be inherited into an Undo-object if it saves content
|
||||
// for Redo/Undo...
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
#include <vcl/uitest/eventdescription.hxx>
|
||||
#include <tabcol.hxx>
|
||||
#include <wrtsh.hxx>
|
||||
#include <undobj.hxx>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
using namespace com::sun::star;
|
||||
|
@ -2501,7 +2502,10 @@ void SwCursorShell::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
|
|||
bool SwCursorShell::HasSelection() const
|
||||
{
|
||||
const SwPaM* pCursor = getShellCursor( true );
|
||||
return IsTableMode() || ( pCursor->HasMark() && *pCursor->GetPoint() != *pCursor->GetMark() );
|
||||
return IsTableMode()
|
||||
|| (pCursor->HasMark() &&
|
||||
(*pCursor->GetPoint() != *pCursor->GetMark()
|
||||
|| IsFlySelectedByCursor(*GetDoc(), *pCursor->Start(), *pCursor->End())));
|
||||
}
|
||||
|
||||
void SwCursorShell::CallChgLnk()
|
||||
|
|
|
@ -4062,8 +4062,11 @@ bool DocumentContentOperationsManager::DeleteRangeImplImpl(SwPaM & rPam)
|
|||
{
|
||||
SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
|
||||
|
||||
if( !rPam.HasMark() || *pStt >= *pEnd )
|
||||
if (!rPam.HasMark()
|
||||
|| (*pStt == *pEnd && !IsFlySelectedByCursor(m_rDoc, *pStt, *pEnd)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( m_rDoc.GetAutoCorrExceptWord() )
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <editsh.hxx>
|
||||
#include <pam.hxx>
|
||||
#include <swundo.hxx>
|
||||
#include <undobj.hxx>
|
||||
#include <SwRewriter.hxx>
|
||||
#include <osl/diagnose.h>
|
||||
|
||||
|
@ -34,8 +35,12 @@ void SwEditShell::DeleteSel( SwPaM& rPam, bool* pUndo )
|
|||
{
|
||||
bool bSelectAll = StartsWithTable() && ExtendedSelectedAll();
|
||||
// only for selections
|
||||
if( !rPam.HasMark() || *rPam.GetPoint() == *rPam.GetMark())
|
||||
if (!rPam.HasMark()
|
||||
|| (*rPam.GetPoint() == *rPam.GetMark()
|
||||
&& !IsFlySelectedByCursor(*GetDoc(), *rPam.Start(), *rPam.End())))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Is the selection in a table? Then delete only the content of the selected boxes.
|
||||
// Here, there are two cases:
|
||||
|
|
|
@ -561,28 +561,9 @@ bool SwUndoDelete::CanGrouping( SwDoc* pDoc, const SwPaM& rDelPam )
|
|||
// tdf#132725 - if at-char/at-para flys would be deleted, don't group!
|
||||
// DelContentIndex() would be called at the wrong time here, the indexes
|
||||
// in the stored SwHistoryTextFlyCnt would be wrong when Undo is invoked
|
||||
for (SwFrameFormat const*const pFly : *pDoc->GetSpzFrameFormats())
|
||||
if (IsFlySelectedByCursor(*pDoc, *pStt, *pEnd))
|
||||
{
|
||||
SwFormatAnchor const& rAnchor(pFly->GetAnchor());
|
||||
switch (rAnchor.GetAnchorId())
|
||||
{
|
||||
case RndStdIds::FLY_AT_CHAR:
|
||||
case RndStdIds::FLY_AT_PARA:
|
||||
{
|
||||
SwPosition const*const pAnchorPos(rAnchor.GetContentAnchor());
|
||||
// can this really be null?
|
||||
if (pAnchorPos != nullptr
|
||||
&& ((rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR)
|
||||
? IsDestroyFrameAnchoredAtChar(*pAnchorPos, *pStt, *pEnd)
|
||||
: IsSelectFrameAnchoredAtPara(*pAnchorPos, *pStt, *pEnd)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: // other types not relevant
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -1645,4 +1645,33 @@ bool IsSelectFrameAnchoredAtPara(SwPosition const & rAnchorPos,
|
|||
|| (IsAtEndOfSection(rAnchorPos) && IsAtStartOfSection2(rStart)))));
|
||||
}
|
||||
|
||||
bool IsFlySelectedByCursor(SwDoc const & rDoc,
|
||||
SwPosition const & rStart, SwPosition const & rEnd)
|
||||
{
|
||||
for (SwFrameFormat const*const pFly : *rDoc.GetSpzFrameFormats())
|
||||
{
|
||||
SwFormatAnchor const& rAnchor(pFly->GetAnchor());
|
||||
switch (rAnchor.GetAnchorId())
|
||||
{
|
||||
case RndStdIds::FLY_AT_CHAR:
|
||||
case RndStdIds::FLY_AT_PARA:
|
||||
{
|
||||
SwPosition const*const pAnchorPos(rAnchor.GetContentAnchor());
|
||||
// can this really be null?
|
||||
if (pAnchorPos != nullptr
|
||||
&& ((rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR)
|
||||
? IsDestroyFrameAnchoredAtChar(*pAnchorPos, rStart, rEnd)
|
||||
: IsSelectFrameAnchoredAtPara(*pAnchorPos, rStart, rEnd)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: // other types not relevant
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
|
Loading…
Reference in a new issue