sw/inc/swcrsr.hxx | 8 ++++---- sw/source/core/access/accportions.cxx | 13 ++++++------- sw/source/core/access/accportions.hxx | 2 +- sw/source/core/crsr/crsrsh.cxx | 3 ++- sw/source/core/crsr/swcrsr.cxx | 16 ++++++++++++++-- sw/source/core/text/itrcrsr.cxx | 17 ++++++++++++++--- sw/source/core/text/itrform2.cxx | 23 ++++++++++++++++++++++- sw/source/core/text/porfld.cxx | 15 +++++++++------ sw/source/core/text/porfld.hxx | 6 +++++- sw/source/core/view/viewsh.cxx | 15 +++++++++++++++ sw/source/uibase/docvw/edtwin.cxx | 2 +- sw/source/uibase/fldui/fldmgr.cxx | 6 ++++-- sw/source/uibase/shells/textfld.cxx | 4 ++-- 13 files changed, 99 insertions(+), 31 deletions(-)
New commits: commit 926a1a16a061b666a0b125cd2d15461716655e78 Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Tue Sep 22 12:17:06 2020 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Fri Sep 25 10:40:49 2020 +0200 tdf#101830 sw: show field name for inline input fields too Currently if the View->Field Names is toggled, SwViewShell::ImplApplyViewOptions() will call Reformat() and throw away all existing portions. So we can just create a different kind of portion altogether depending on the value of the setting, and avoid complex multi-inheritance portion or copying lots of code around. This requires correcting a few assumptions that a SwFieldPortion has a length of 0 or 1; for the input field, its length is the length of the entire input field including CH_TXT_ATR_INPUTFIELDSTART/END (unless it's a follow/rest portion, those are length 0 as always). For the cursor travelling, LeftRight() works similar to f6a60ce214117946eef222701023dca612bf0a2b, while UpDown() and mouse click positioning need tweaks in SwTextCursor::GetModelPositionForViewPoint() to take the field length into account. Due to the previous point, mouse click related functions in edtwin.cxx require checking the position at the start now. When enabling Field Names, move any shell cursors out of input fields. Change-Id: I1304f419bd6fa20f0c55fd1b13165c4866d64000 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103155 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@cib.de> diff --git a/sw/inc/swcrsr.hxx b/sw/inc/swcrsr.hxx index a6e634ac3b55..4ed649e85681 100644 --- a/sw/inc/swcrsr.hxx +++ b/sw/inc/swcrsr.hxx @@ -162,15 +162,15 @@ public: virtual bool LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode, bool bAllowVisual, bool bSkipHidden, bool bInsertCursor, - SwRootFrame const* pLayout); + SwRootFrame const* pLayout, bool isFieldNames); bool UpDown(bool bUp, sal_uInt16 nCnt, Point const * pPt, long nUpDownX, SwRootFrame & rLayout); bool LeftRightMargin(SwRootFrame const& rLayout, bool bLeftMargin, bool bAPI); bool IsAtLeftRightMargin(SwRootFrame const& rLayout, bool bLeftMargin, bool bAPI) const; bool SttEndDoc( bool bSttDoc ); bool GoPrevNextCell( bool bNext, sal_uInt16 nCnt ); - bool Left( sal_uInt16 nCnt ) { return LeftRight( true, nCnt, CRSR_SKIP_CHARS, false/*bAllowVisual*/, false/*bSkipHidden*/, false, nullptr ); } - bool Right( sal_uInt16 nCnt ) { return LeftRight( false, nCnt, CRSR_SKIP_CHARS, false/*bAllowVisual*/, false/*bSkipHidden*/, false, nullptr ); } + bool Left( sal_uInt16 nCnt ) { return LeftRight(true, nCnt, CRSR_SKIP_CHARS, false/*bAllowVisual*/, false/*bSkipHidden*/, false, nullptr, false); } + bool Right( sal_uInt16 nCnt ) { return LeftRight(false, nCnt, CRSR_SKIP_CHARS, false/*bAllowVisual*/, false/*bSkipHidden*/, false, nullptr, false); } bool GoNextCell( sal_uInt16 nCnt = 1 ) { return GoPrevNextCell( true, nCnt ); } bool GoPrevCell( sal_uInt16 nCnt = 1 ) { return GoPrevNextCell( false, nCnt ); } virtual bool GotoTable( const OUString& rName ); @@ -271,7 +271,7 @@ public: virtual bool LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode, bool bAllowVisual, bool bSkipHidden, bool bInsertCursor, - SwRootFrame const*) override; + SwRootFrame const*, bool) override; virtual bool GotoTable( const OUString& rName ) override; void InsertBox( const SwTableBox& rTableBox ); diff --git a/sw/source/core/access/accportions.cxx b/sw/source/core/access/accportions.cxx index b929bc54b5ac..c472490f8b59 100644 --- a/sw/source/core/access/accportions.cxx +++ b/sw/source/core/access/accportions.cxx @@ -353,7 +353,7 @@ TextFrameIndex SwAccessiblePortionData::GetCoreViewPosition(sal_Int32 const nPos // return the portion start if( ! IsSpecialPortion( nPortionNo ) ) { - // 'wide' portions have to be of the same width + // text portions have to be of the same width OSL_ENSURE( sal_Int32(m_ViewPositions[nPortionNo+1] - nStartPos) == ( m_aAccessiblePositions[nPortionNo+1] - m_aAccessiblePositions[nPortionNo] ), @@ -518,9 +518,9 @@ sal_Int32 SwAccessiblePortionData::GetAccessiblePosition(TextFrameIndex const nP // else return that position TextFrameIndex nStartPos = m_ViewPositions[nPortionNo]; TextFrameIndex nEndPos = m_ViewPositions[nPortionNo+1]; - if ((nEndPos - nStartPos) > TextFrameIndex(1)) + if (!IsSpecialPortion(nPortionNo)) { - // 'wide' portions have to be of the same width + // text portions have to be of the same width OSL_ENSURE( sal_Int32(nEndPos - nStartPos) == ( m_aAccessiblePositions[nPortionNo+1] - m_aAccessiblePositions[nPortionNo] ), @@ -574,10 +574,9 @@ TextFrameIndex SwAccessiblePortionData::FillSpecialPos( "portion with core-representation expected" ); // if we have anything except plain text, compute nExtend + nRefPos - if ((nCoreEndPos - nCorePos == TextFrameIndex(1)) && - (m_pTextFrame->GetText()[sal_Int32(nCorePos)] != m_sAccessibleString[nPos])) + if (IsSpecialPortion(nCorePortionNo)) { - // case 1: a one-character, non-text portion + // case 1: a non-text portion // reference position is the first accessibility for our // core portion nRefPos = m_aAccessiblePositions[ nCorePortionNo ]; @@ -731,7 +730,7 @@ bool SwAccessiblePortionData::IsInGrayPortion( sal_Int32 nPos ) PORATTR_GRAY ); } -sal_Int32 SwAccessiblePortionData::GetFieldIndex(sal_Int32 nPos) +sal_Int32 SwAccessiblePortionData::GetFieldIndex(sal_Int32 nPos) const { sal_Int32 nIndex = -1; if( m_aFieldPosition.size() >= 2 ) diff --git a/sw/source/core/access/accportions.hxx b/sw/source/core/access/accportions.hxx index 246ed862299f..5598699a63d0 100644 --- a/sw/source/core/access/accportions.hxx +++ b/sw/source/core/access/accportions.hxx @@ -100,7 +100,7 @@ public: bool FillBoundaryIFDateField( css::i18n::Boundary& rBound, const sal_Int32 nPos ); bool IsIndexInFootnode(sal_Int32 nIndex); bool IsInGrayPortion( sal_Int32 nPos ); - sal_Int32 GetFieldIndex(sal_Int32 nPos); + sal_Int32 GetFieldIndex(sal_Int32 nPos) const; bool IsZeroCorePositionData(); diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx index 26ed4473924e..4398607ce0f7 100644 --- a/sw/source/core/crsr/crsrsh.cxx +++ b/sw/source/core/crsr/crsrsh.cxx @@ -368,7 +368,8 @@ bool SwCursorShell::LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode, const bool bResetOfInFrontOfLabel = SetInFrontOfLabel( false ); bRet = pShellCursor->LeftRight( bLeft, nCnt, nMode, bVisualAllowed, bSkipHidden, !IsOverwriteCursor(), - GetLayout()); + GetLayout(), + GetViewOptions()->IsFieldName()); if ( !bRet && bLeft && bResetOfInFrontOfLabel ) { // undo reset of <bInFrontOfLabel> flag diff --git a/sw/source/core/crsr/swcrsr.cxx b/sw/source/core/crsr/swcrsr.cxx index 97e46bd827e9..dbb60e5ea6bc 100644 --- a/sw/source/core/crsr/swcrsr.cxx +++ b/sw/source/core/crsr/swcrsr.cxx @@ -1677,7 +1677,7 @@ bool SwCursor::ExpandToSentenceBorders(SwRootFrame const*const pLayout) bool SwTableCursor::LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 /*nMode*/, bool /*bVisualAllowed*/, bool /*bSkipHidden*/, bool /*bInsertCursor*/, - SwRootFrame const*) + SwRootFrame const*, bool /*isFieldNames*/) { return bLeft ? GoPrevCell( nCnt ) : GoNextCell( nCnt ); @@ -1743,7 +1743,7 @@ SwCursor::DoSetBidiLevelLeftRight( bool SwCursor::LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode, bool bVisualAllowed,bool bSkipHidden, bool bInsertCursor, - SwRootFrame const*const pLayout) + SwRootFrame const*const pLayout, bool isFieldNames) { // calculate cursor bidi level SwNode& rNode = GetPoint()->nNode.GetNode(); @@ -1813,6 +1813,18 @@ bool SwCursor::LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode, } } + if (isFieldNames) + { + SwTextNode const*const pNode(GetPoint()->nNode.GetNode().GetTextNode()); + assert(pNode); + SwTextAttr const*const pInputField(pNode->GetTextAttrAt( + GetPoint()->nContent.GetIndex(), RES_TXTATR_INPUTFIELD, SwTextNode::PARENT)); + if (pInputField) + { + continue; // skip over input fields + } + } + // If we were located inside a covered cell but our position has been // corrected, we check if the last move has moved the cursor to a // different table cell. In this case we set the cursor to the stored diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx index 6e9325fa4509..9ca00be6df8d 100644 --- a/sw/source/core/text/itrcrsr.cxx +++ b/sw/source/core/text/itrcrsr.cxx @@ -1495,7 +1495,7 @@ TextFrameIndex SwTextCursor::GetModelPositionForViewPoint( SwPosition *pPos, con } return nCurrStart; } - if (TextFrameIndex(1) == nLength) + if (TextFrameIndex(1) == nLength || pPor->InFieldGrp()) { if ( nWidth ) { @@ -1519,7 +1519,16 @@ TextFrameIndex SwTextCursor::GetModelPositionForViewPoint( SwPosition *pPos, con if( nWidth - nHeight/2 <= nX && ( ! pPor->InFieldGrp() || !static_cast<SwFieldPortion*>(pPor)->HasFollow() ) ) - ++nCurrStart; + { + if (pPor->InFieldGrp()) + { + nCurrStart += static_cast<SwFieldPortion*>(pPor)->GetFieldLen(); + } + else + { + ++nCurrStart; + } + } } else if ( ( !pPor->IsFlyPortion() || ( pPor->GetNextPortion() && !pPor->GetNextPortion()->IsMarginPortion() && @@ -1549,7 +1558,9 @@ TextFrameIndex SwTextCursor::GetModelPositionForViewPoint( SwPosition *pPos, con if ( pPor->InFieldGrp() ) { if( bRightOver && !static_cast<SwFieldPortion*>(pPor)->HasFollow() ) - ++nCurrStart; + { + nCurrStart += static_cast<SwFieldPortion*>(pPor)->GetFieldLen(); + } return nCurrStart; } } diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx index a78d4f730e7f..d6de4e28849e 100644 --- a/sw/source/core/text/itrform2.cxx +++ b/sw/source/core/text/itrform2.cxx @@ -890,7 +890,28 @@ SwTextPortion *SwTextFormatter::WhichTextPor( SwTextFormatInfo &rInf ) const } else if ( GetFnt()->IsInputField() ) { - pPor = new SwTextInputFieldPortion(); + if (rInf.GetOpt().IsFieldName()) + { + OUString aFieldName = SwFieldType::GetTypeStr(SwFieldTypesEnum::Input); + // assume this is only the *first* portion and follows will be created elsewhere => input field must start at Idx + assert(rInf.GetText()[sal_Int32(rInf.GetIdx())] == CH_TXT_ATR_INPUTFIELDSTART); + TextFrameIndex nFieldLen(-1); + for (TextFrameIndex i = rInf.GetIdx() + TextFrameIndex(1); ; ++i) + { + assert(rInf.GetText()[sal_Int32(i)] != CH_TXT_ATR_INPUTFIELDSTART); // can't nest + if (rInf.GetText()[sal_Int32(i)] == CH_TXT_ATR_INPUTFIELDEND) + { + nFieldLen = i + TextFrameIndex(1) - rInf.GetIdx(); + break; + } + } + assert(2 <= sal_Int32(nFieldLen)); + pPor = new SwFieldPortion(aFieldName, nullptr, false, nFieldLen); + } + else + { + pPor = new SwTextInputFieldPortion(); + } } else { diff --git a/sw/source/core/text/porfld.cxx b/sw/source/core/text/porfld.cxx index 6b9e1647b591..b278484fc955 100644 --- a/sw/source/core/text/porfld.cxx +++ b/sw/source/core/text/porfld.cxx @@ -72,8 +72,9 @@ void SwFieldPortion::TakeNextOffset( const SwFieldPortion* pField ) m_bFollow = true; } -SwFieldPortion::SwFieldPortion( const OUString &rExpand, std::unique_ptr<SwFont> pFont, bool bPlaceHold ) - : m_aExpand(rExpand), m_pFont(std::move(pFont)), m_nNextOffset(0), m_nNextScriptChg(COMPLETE_STRING), m_nViewWidth(0) +SwFieldPortion::SwFieldPortion(const OUString &rExpand, std::unique_ptr<SwFont> pFont, bool bPlaceHold, TextFrameIndex const nFieldLen) + : m_aExpand(rExpand), m_pFont(std::move(pFont)), m_nNextOffset(0) + , m_nNextScriptChg(COMPLETE_STRING), m_nFieldLen(nFieldLen), m_nViewWidth(0) , m_bFollow( false ), m_bLeft( false), m_bHide( false) , m_bCenter (false), m_bHasFollow( false ) , m_bAnimated( false), m_bNoPaint( false) @@ -89,6 +90,7 @@ SwFieldPortion::SwFieldPortion( const SwFieldPortion& rField ) , m_aExpand( rField.GetExp() ) , m_nNextOffset( rField.GetNextOffset() ) , m_nNextScriptChg( rField.m_nNextScriptChg ) + , m_nFieldLen(rField.m_nFieldLen) , m_nViewWidth( rField.m_nViewWidth ) , m_bFollow( rField.IsFollow() ) , m_bLeft( rField.IsLeft() ) @@ -175,7 +177,8 @@ SwFieldSlot::SwFieldSlot( const SwTextFormatInfo* pNew, const SwFieldPortion *pP } else if (nIdx < TextFrameIndex(pOldText->getLength())) { - aText = (*pOldText).replaceAt(sal_Int32(nIdx), 1, aText); + sal_Int32 const nFieldLen(pPor->GetFieldLen()); + aText = (*pOldText).replaceAt(sal_Int32(nIdx), nFieldLen, aText); } pInf->SetText( aText ); } @@ -229,7 +232,7 @@ void SwFieldPortion::CheckScript( const SwTextSizeInfo &rInf ) // #i98418# const sal_uInt8 nFieldDir = (IsNumberPortion() || IsFootnoteNumPortion()) ? rSI.GetDefaultDir() - : rSI.DirType(IsFollow() ? rInf.GetIdx() - TextFrameIndex(1) : rInf.GetIdx()); + : rSI.DirType(IsFollow() ? rInf.GetIdx() - m_nFieldLen : rInf.GetIdx()); { UErrorCode nError = U_ZERO_ERROR; @@ -326,7 +329,7 @@ bool SwFieldPortion::Format( SwTextFormatInfo &rInf ) // and passed along in nRest. Or else the old length would be // retained and be used for nRest! SetLen(TextFrameIndex(0)); - TextFrameIndex const nFollow(IsFollow() ? 0 : 1); + TextFrameIndex const nFollow(IsFollow() ? TextFrameIndex(0) : m_nFieldLen); // As odd is may seem: the query for GetLen() must return false due // to the ExpandPortions _after_ aDiffText (see SoftHyphs), caused @@ -429,7 +432,7 @@ void SwFieldPortion::Paint( const SwTextPaintInfo &rInf ) const { SwFontSave aSave( rInf, m_pFont.get() ); - OSL_ENSURE(GetLen() <= TextFrameIndex(1), "SwFieldPortion::Paint: rest-portion pollution?"); +// OSL_ENSURE(GetLen() <= TextFrameIndex(1), "SwFieldPortion::Paint: rest-portion pollution?"); if( Width() && ( !m_bPlaceHolder || rInf.GetOpt().IsShowPlaceHolderFields() ) ) { // A very liberal use of the background diff --git a/sw/source/core/text/porfld.hxx b/sw/source/core/text/porfld.hxx index cac7cbc25071..c2ba88285a23 100644 --- a/sw/source/core/text/porfld.hxx +++ b/sw/source/core/text/porfld.hxx @@ -35,6 +35,8 @@ protected: std::unique_ptr<SwFont> m_pFont; // For multi-line fields TextFrameIndex m_nNextOffset; // Offset of the follow in the original string TextFrameIndex m_nNextScriptChg; + TextFrameIndex m_nFieldLen; //< Length of field text, 1 for normal fields, any number for input fields + // TODO ^ do we need this as member or is base class len enough? sal_uInt16 m_nViewWidth; // Screen width for empty fields bool m_bFollow : 1; // 2nd or later part of a field bool m_bLeft : 1; // Used by SwNumberPortion @@ -53,7 +55,7 @@ protected: public: SwFieldPortion( const SwFieldPortion& rField ); - SwFieldPortion( const OUString &rExpand, std::unique_ptr<SwFont> pFnt = nullptr, bool bPlaceHolder = false ); + SwFieldPortion(const OUString &rExpand, std::unique_ptr<SwFont> pFnt = nullptr, bool bPlaceHolder = false, TextFrameIndex nLen = TextFrameIndex(1)); virtual ~SwFieldPortion() override; sal_uInt16 m_nAttrFieldType; @@ -91,6 +93,8 @@ public: TextFrameIndex GetNextOffset() const { return m_nNextOffset; } void SetNextOffset(TextFrameIndex nNew) { m_nNextOffset = nNew; } + TextFrameIndex GetFieldLen() const { return m_nFieldLen; } + // Field cloner for SplitGlue virtual SwFieldPortion *Clone( const OUString &rExpand ) const; diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx index 52a82345ef65..654c3a373590 100644 --- a/sw/source/core/view/viewsh.cxx +++ b/sw/source/core/view/viewsh.cxx @@ -2188,6 +2188,7 @@ void SwViewShell::ImplApplyViewOptions( const SwViewOption &rOpt ) // ( - SwEndPortion must _no_ longer be generated. ) // - Of course, the screen is something completely different than the printer ... bReformat = bReformat || mpOpt->IsFieldName() != rOpt.IsFieldName(); + bool const isEnableFieldNames(mpOpt->IsFieldName() != rOpt.IsFieldName() && rOpt.IsFieldName()); // The map mode is changed, minima/maxima will be attended by UI if( mpOpt->GetZoom() != rOpt.GetZoom() && !IsPreview() ) @@ -2275,6 +2276,20 @@ void SwViewShell::ImplApplyViewOptions( const SwViewOption &rOpt ) EndAction(); } + if (isEnableFieldNames) + { + for(SwViewShell& rSh : GetRingContainer()) + { + if (SwCursorShell *const pSh = dynamic_cast<SwCursorShell *>(&rSh)) + { + if (pSh->CursorInsideInputField()) + { // move cursor out of input field + pSh->Left(1, CRSR_SKIP_CHARS); + } + } + } + } + if( !bOnlineSpellChgd ) return; diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx index aa7c64ed2b7c..69d7d6b60b38 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -3373,7 +3373,7 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt) bool bFootnote = false; if( !bIsDocReadOnly && - ( nullptr != ( pField = rSh.GetCurField() ) || + (nullptr != (pField = rSh.GetCurField(true)) || ( bFootnote = rSh.GetCurFootnote() ) ) ) { RstMBDownFlags(); diff --git a/sw/source/uibase/fldui/fldmgr.cxx b/sw/source/uibase/fldui/fldmgr.cxx index d966dac4d490..96fe6e375627 100644 --- a/sw/source/uibase/fldui/fldmgr.cxx +++ b/sw/source/uibase/fldui/fldmgr.cxx @@ -65,6 +65,7 @@ #include <flddropdown.hxx> #include <strings.hrc> #include <tox.hxx> +#include <viewopt.hxx> #include <unotools/useroptions.hxx> using namespace com::sun::star::uno; @@ -1491,8 +1492,9 @@ bool SwFieldMgr::InsertField( pCurShell->Push(); // start dialog, not before the field is inserted tdf#99529 - pCurShell->Left(CRSR_SKIP_CHARS, - false, (INP_VAR == (nSubType & 0xff)) ? 1 : 2, false ); + pCurShell->Left(CRSR_SKIP_CHARS, false, + (INP_VAR == (nSubType & 0xff) || pCurShell->GetViewOptions()->IsFieldName()) ? 1 : 2, + false); pCurShell->StartInputFieldDlg(pField.get(), false, true, rData.m_pParent); pCurShell->Pop(SwCursorShell::PopMode::DeleteCurrent); diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx index c3169a40ede0..3068fdadb57c 100644 --- a/sw/source/uibase/shells/textfld.cxx +++ b/sw/source/uibase/shells/textfld.cxx @@ -115,7 +115,7 @@ void SwTextShell::ExecField(SfxRequest &rReq) { case FN_EDIT_FIELD: { - SwField* pField = rSh.GetCurField(); + SwField* pField = rSh.GetCurField(true); if( pField ) { switch ( pField->GetTypeId() ) @@ -810,7 +810,7 @@ void SwTextShell::StateField( SfxItemSet &rSet ) { if( !bGetField ) { - pField = rSh.GetCurField(); + pField = rSh.GetCurField(true); bGetField = true; } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits