diff options
Diffstat (limited to 'sw/source/uibase/docvw/edtwin2.cxx')
-rw-r--r-- | sw/source/uibase/docvw/edtwin2.cxx | 417 |
1 files changed, 324 insertions, 93 deletions
diff --git a/sw/source/uibase/docvw/edtwin2.cxx b/sw/source/uibase/docvw/edtwin2.cxx index a72554202f2e..07bf72ff4b99 100644 --- a/sw/source/uibase/docvw/edtwin2.cxx +++ b/sw/source/uibase/docvw/edtwin2.cxx @@ -21,6 +21,7 @@ #include <osl/diagnose.h> #include <osl/thread.h> #include <vcl/help.hxx> +#include <tools/json_writer.hxx> #include <tools/urlobj.hxx> #include <fmtrfmrk.hxx> #include <svl/urihelper.hxx> @@ -51,17 +52,231 @@ #include <IDocumentRedlineAccess.hxx> #include <txtfrm.hxx> #include <ndtxt.hxx> -#include <FrameControlsManager.hxx> #include <comphelper/lok.hxx> #include <authfld.hxx> -static OUString lcl_GetRedlineHelp( const SwRangeRedline& rRedl, bool bBalloon ) +#include <com/sun/star/text/XTextRange.hpp> +#include <unotextrange.hxx> +#include <SwStyleNameMapper.hxx> +#include <unoprnms.hxx> +#include <editeng/unoprnms.hxx> +#include <rootfrm.hxx> +#include <unomap.hxx> +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <LibreOfficeKit/LibreOfficeKitEnums.h> + +namespace { + +bool HasValidPropertyValue(const uno::Any& rAny) +{ + if (bool bValue; rAny >>= bValue) + { + return true; + } + else if (OUString aValue; (rAny >>= aValue) && !(aValue.isEmpty())) + { + return true; + } + else if (awt::FontSlant eValue; rAny >>= eValue) + { + return true; + } + else if (tools::Long nValueLong; rAny >>= nValueLong) + { + return true; + } + else if (double fValue; rAny >>= fValue) + { + return true; + } + else if (short nValueShort; rAny >>= nValueShort) + { + return true; + } + else + return false; +} + +bool PSCSDFPropsQuickHelp(const HelpEvent &rEvt, SwWrtShell& rSh) +{ + OUString sText; + SwView& rView = rSh.GetView(); + + if (rView.IsHighlightCharDF() || rView.GetStylesHighlighterParaColorMap().size() + || rView.GetStylesHighlighterCharColorMap().size()) + { + SwPosition aPos(rSh.GetDoc()->GetNodes()); + Point aPt(rSh.GetWin()->PixelToLogic( + rSh.GetWin()->ScreenToOutputPixel(rEvt.GetMousePosPixel()))); + + rSh.GetLayout()->GetModelPositionForViewPoint(&aPos, aPt); + + if (!aPos.GetContentNode()->IsTextNode()) + return false; + + rtl::Reference<SwXTextRange> xRange( + SwXTextRange::CreateXTextRange(*(rView.GetDocShell()->GetDoc()), + aPos, &aPos)); + if (!xRange) + throw uno::RuntimeException(); + + SwContentFrame* pContentFrame = aPos.GetContentNode()->GetTextNode()->getLayoutFrame( + rSh.GetLayout()); + + SwRect aFrameAreaRect; + + bool bContainsPt = false; + do + { + aFrameAreaRect = pContentFrame->getFrameArea(); + if (aFrameAreaRect.Contains(aPt)) + { + bContainsPt = true; + break; + } + } while((pContentFrame = pContentFrame->GetFollow())); + + if (bContainsPt) + { + if (rView.GetStylesHighlighterCharColorMap().size()) + { + // check if in CS formatting highlighted area + OUString sCharStyle; + xRange->getPropertyValue("CharStyleName") >>= sCharStyle; + if (!sCharStyle.isEmpty()) + sText = SwStyleNameMapper::GetUIName(sCharStyle, SwGetPoolIdFromName::ChrFmt); + } + + if (sText.isEmpty() && rView.IsHighlightCharDF()) + { + // check if in direct formatting highlighted area + const std::vector<OUString> aHiddenProperties{ UNO_NAME_RSID, + UNO_NAME_PARA_IS_NUMBERING_RESTART, + UNO_NAME_PARA_STYLE_NAME, + UNO_NAME_PARA_CONDITIONAL_STYLE_NAME, + UNO_NAME_PAGE_STYLE_NAME, + UNO_NAME_NUMBERING_START_VALUE, + UNO_NAME_NUMBERING_IS_NUMBER, + UNO_NAME_PARA_CONTINUEING_PREVIOUS_SUB_TREE, + UNO_NAME_CHAR_STYLE_NAME, + UNO_NAME_NUMBERING_LEVEL, + UNO_NAME_SORTED_TEXT_ID, + UNO_NAME_PARRSID, + UNO_NAME_CHAR_COLOR_THEME, + UNO_NAME_CHAR_COLOR_TINT_OR_SHADE }; + + SfxItemPropertySet const& rPropSet( + *aSwMapProvider.GetPropertySet(PROPERTY_MAP_CHAR_AUTO_STYLE)); + SfxItemPropertyMap const& rMap(rPropSet.getPropertyMap()); + + const uno::Sequence<beans::Property> aProperties + = xRange->getPropertySetInfo()->getProperties(); + + for (const beans::Property& rProperty : aProperties) + { + const OUString& rPropName = rProperty.Name; + + if (!rMap.hasPropertyByName(rPropName)) + continue; + + if (std::find(aHiddenProperties.begin(), aHiddenProperties.end(), rPropName) + != aHiddenProperties.end()) + continue; + + if (xRange->getPropertyState(rPropName) + == beans::PropertyState_DIRECT_VALUE) + { + const uno::Any aAny = xRange->getPropertyValue(rPropName); + if (HasValidPropertyValue(aAny)) + { + sText = SwResId(STR_CHARACTER_DIRECT_FORMATTING); + break; + } + } + } + } + } + else if (rView.GetStylesHighlighterParaColorMap().size()) + { + // check if in paragraph style formatting highlighted area + pContentFrame = aPos.GetContentNode()->GetTextNode()->getLayoutFrame( + rSh.GetLayout()); + do + { + aFrameAreaRect = pContentFrame->getFrameArea(); + if (pContentFrame->IsRightToLeft()) + { + aFrameAreaRect.AddRight(375); + aFrameAreaRect.Left(aFrameAreaRect.Right() - 300); + } + else + { + aFrameAreaRect.AddLeft(-375); + aFrameAreaRect.Right(aFrameAreaRect.Left() + 300); + } + if (aFrameAreaRect.Contains(aPt)) + { + OUString sParaStyle; + xRange->getPropertyValue("ParaStyleName") >>= sParaStyle; + sText = SwStyleNameMapper::GetUIName(sParaStyle, SwGetPoolIdFromName::TxtColl); + // check for paragraph direct formatting + if (SwDoc::HasParagraphDirectFormatting(aPos)) + sText = sText + " + " + SwResId(STR_PARAGRAPH_DIRECT_FORMATTING); + break; + } + } while((pContentFrame = pContentFrame->GetFollow())); + } + } + + if (!sText.isEmpty()) + { + tools::Rectangle aRect(rSh.GetWin()->PixelToLogic( + rSh.GetWin()->ScreenToOutputPixel(rEvt.GetMousePosPixel())), + Size(1, 1)); + Point aPt(rSh.GetWin()->OutputToScreenPixel(rSh.GetWin()->LogicToPixel(aRect.TopLeft()))); + aRect.SetLeft(aPt.X()); + aRect.SetTop(aPt.Y()); + aPt = rSh.GetWin()->OutputToScreenPixel(rSh.GetWin()->LogicToPixel(aRect.BottomRight())); + aRect.SetRight(aPt.X()); + aRect.SetBottom(aPt.Y()); + + // tdf#136336 ensure tooltip area surrounds the current mouse position with at least a pixel margin + aRect.Union(tools::Rectangle(rEvt.GetMousePosPixel(), Size(1, 1))); + aRect.AdjustLeft(-1); + aRect.AdjustRight(1); + aRect.AdjustTop(-1); + aRect.AdjustBottom(1); + + QuickHelpFlags nStyle = QuickHelpFlags::NONE; //TipStyleBalloon; + Help::ShowQuickHelp(rSh.GetWin(), aRect, sText, nStyle); + } + + return !sText.isEmpty(); +} +} + +static OUString lcl_GetRedlineHelp( const SwRangeRedline& rRedl, bool bBalloon, + bool bTableChange, bool bTableColChange ) { - const char* pResId = nullptr; + TranslateId pResId; switch( rRedl.GetType() ) { - case RedlineType::Insert: pResId = STR_REDLINE_INSERT; break; - case RedlineType::Delete: pResId = STR_REDLINE_DELETE; break; + case RedlineType::Insert: pResId = bTableChange + ? !bTableColChange + ? STR_REDLINE_TABLE_ROW_INSERT + : STR_REDLINE_TABLE_COLUMN_INSERT + : rRedl.IsMoved() + ? STR_REDLINE_INSERT_MOVED + : STR_REDLINE_INSERT; + break; + case RedlineType::Delete: pResId = bTableChange + ? !bTableColChange + ? STR_REDLINE_TABLE_ROW_DELETE + : STR_REDLINE_TABLE_COLUMN_DELETE + : rRedl.IsMoved() + ? STR_REDLINE_DELETE_MOVED + : STR_REDLINE_DELETE; + break; case RedlineType::Format: pResId = STR_REDLINE_FORMAT; break; case RedlineType::Table: pResId = STR_REDLINE_TABLE; break; case RedlineType::FmtColl: pResId = STR_REDLINE_FMTCOLL; break; @@ -73,17 +288,15 @@ static OUString lcl_GetRedlineHelp( const SwRangeRedline& rRedl, bool bBalloon ) default: break; } - OUStringBuffer sBuf; - if (pResId) - { - sBuf.append(SwResId(pResId)); - sBuf.append(": "); - sBuf.append(rRedl.GetAuthorString()); - sBuf.append(" - "); - sBuf.append(GetAppLangDateTimeString(rRedl.GetTimeStamp())); - if( bBalloon && !rRedl.GetComment().isEmpty() ) - sBuf.append('\n').append(rRedl.GetComment()); - } + if (!pResId) + return OUString(); + OUStringBuffer sBuf(SwResId(pResId) + + ": " + + rRedl.GetAuthorString() + + " - " + + GetAppLangDateTimeString(rRedl.GetTimeStamp())); + if( bBalloon && !rRedl.GetComment().isEmpty() ) + sBuf.append("\n" + rRedl.GetComment()); return sBuf.makeStringAndClear(); } @@ -94,13 +307,28 @@ OUString SwEditWin::ClipLongToolTip(const OUString& rText) tools::Long nMaxWidth = GetDesktopRectPixel().GetWidth() * 2 / 3; nMaxWidth = PixelToLogic(Size(nMaxWidth, 0)).Width(); if (nTextWidth > nMaxWidth) - sDisplayText = GetEllipsisString(sDisplayText, nMaxWidth, DrawTextFlags::CenterEllipsis); + sDisplayText = GetOutDev()->GetEllipsisString(sDisplayText, nMaxWidth, DrawTextFlags::CenterEllipsis); return sDisplayText; } +static OString getTooltipPayload(const OUString& tooltip, const SwRect& rect) +{ + tools::JsonWriter writer; + { + writer.put("type", "generaltooltip"); + writer.put("text", tooltip); + writer.put("rectangle", rect.SVRect().toString()); + } + return writer.finishAndGetAsOString(); +} + void SwEditWin::RequestHelp(const HelpEvent &rEvt) { SwWrtShell &rSh = m_rView.GetWrtShell(); + + if (PSCSDFPropsQuickHelp(rEvt, rSh)) + return; + bool bQuickBalloon = bool(rEvt.GetMode() & ( HelpEventMode::QUICK | HelpEventMode::BALLOON )); if(bQuickBalloon && !rSh.GetViewOptions()->IsShowContentTips()) return; @@ -133,7 +361,9 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt) IsAttrAtPos::TableBoxValue | ( bBalloon ? IsAttrAtPos::CurrAttrs : IsAttrAtPos::NONE) | #endif - IsAttrAtPos::TableBoxFml ); + IsAttrAtPos::TableBoxFml | + IsAttrAtPos::TableRedline | + IsAttrAtPos::TableColRedline ); if( rSh.GetContentAtPos( aPos, aContentAtPos, false, &aFieldRect ) ) { @@ -146,9 +376,11 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt) #ifdef DBG_UTIL case IsAttrAtPos::TableBoxValue: { - sText = OStringToOUString(OString::number( - static_cast<const SwTableBoxValue*>(aContentAtPos.aFnd.pAttr)->GetValue()), - osl_getThreadTextEncoding()); + if(aContentAtPos.aFnd.pAttr) + { + sText = OUString::number( + static_cast<const SwTableBoxValue*>(aContentAtPos.aFnd.pAttr)->GetValue()); + } break; } case IsAttrAtPos::CurrAttrs: @@ -166,15 +398,15 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt) sal_Int32 nFound = sText.indexOf(cMarkSeparator); if( nFound != -1 && (++nFound) < sText.getLength() ) { - OUString sSuffix( sText.copy(nFound) ); - if( sSuffix == "table" || - sSuffix == "frame" || - sSuffix == "region" || - sSuffix == "outline" || - sSuffix == "text" || - sSuffix == "graphic" || - sSuffix == "ole" || - sSuffix == "drawingobject" ) + std::u16string_view sSuffix( sText.subView(nFound) ); + if( sSuffix == u"table" || + sSuffix == u"frame" || + sSuffix == u"region" || + sSuffix == u"outline" || + sSuffix == u"text" || + sSuffix == u"graphic" || + sSuffix == u"ole" || + sSuffix == u"drawingobject" ) sText = sText.copy( 0, nFound - 1); } // #i104300# @@ -188,7 +420,7 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt) IDocumentMarkAccess::GetType(**ppBkmk) == IDocumentMarkAccess::MarkType::CROSSREF_HEADING_BOOKMARK ) { - SwTextNode* pTextNode = (*ppBkmk)->GetMarkStart().nNode.GetNode().GetTextNode(); + SwTextNode* pTextNode = (*ppBkmk)->GetMarkStart().GetNode().GetTextNode(); if ( pTextNode ) { sText = sw::GetExpandTextMerged(rSh.GetLayout(), *pTextNode, true, false, ExpandMode(0)); @@ -240,12 +472,19 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt) } break; + case IsAttrAtPos::TableRedline: + case IsAttrAtPos::TableColRedline: case IsAttrAtPos::Redline: { const bool bShowTrackChanges = IDocumentRedlineAccess::IsShowChanges( m_rView.GetDocShell()->GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags() ); const bool bShowInlineTooltips = rSh.GetViewOptions()->IsShowInlineTooltips(); if ( bShowTrackChanges && bShowInlineTooltips ) - sText = lcl_GetRedlineHelp(*aContentAtPos.aFnd.pRedl, bBalloon); + { + sText = lcl_GetRedlineHelp(*aContentAtPos.aFnd.pRedl, bBalloon, + IsAttrAtPos::TableRedline == aContentAtPos.eContentAtPos || + IsAttrAtPos::TableColRedline == aContentAtPos.eContentAtPos, + IsAttrAtPos::TableColRedline == aContentAtPos.eContentAtPos); + } break; } @@ -266,8 +505,8 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt) case IsAttrAtPos::RefMark: if(aContentAtPos.aFnd.pAttr) { - sText = SwResId(STR_CONTENT_TYPE_SINGLE_REFERENCE) + ": "; - sText += static_cast<const SwFormatRefMark*>(aContentAtPos.aFnd.pAttr)->GetRefName(); + sText = SwResId(STR_CONTENT_TYPE_SINGLE_REFERENCE) + ": " + + static_cast<const SwFormatRefMark*>(aContentAtPos.aFnd.pAttr)->GetRefName(); } break; @@ -307,6 +546,18 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt) break; case SwFieldIds::User: + { + OUString aTitle = pField->GetTitle(); + if (!aTitle.isEmpty()) + { + sText = aTitle; + } + else + { + sText = pField->GetPar1(); + } + break; + } case SwFieldIds::HiddenText: sText = pField->GetPar1(); break; @@ -329,7 +580,7 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt) if ( pRefField->IsRefToHeadingCrossRefBookmark() || pRefField->IsRefToNumItemCrossRefBookmark() ) { - sText = pRefField->GetExpandedTextOfReferencedTextNode(*rSh.GetLayout()); + sText = pRefField->GetExpandedTextOfReferencedTextNode(*rSh.GetLayout(), nullptr, nullptr); if ( sText.getLength() > 80 ) { sText = OUString::Concat(sText.subView(0, 80)) + "..."; @@ -344,17 +595,17 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt) } case SwFieldIds::TableOfAuthorities: { - const auto pAuthorityField - = static_cast<const SwAuthorityField*>(pField); - sText = pAuthorityField->GetAuthority(aContentAtPos.pFndTextAttr, - rSh.GetLayout()); - if (pAuthorityField->HasURL()) + const auto pAuthorityField = static_cast<const SwAuthorityField*>(pField); + sText = pAuthorityField->GetAuthority(rSh.GetLayout()); + + if (auto t = pAuthorityField->GetTargetType(); + t == SwAuthorityField::TargetType::UseDisplayURL + || t == SwAuthorityField::TargetType::UseTargetURL) { - const OUString& rURL - = pAuthorityField->GetAuthEntry()->GetAuthorField( - AUTH_FIELD_URL); + const OUString& rURL = pAuthorityField->GetAbsoluteURL(); sText += "\n" + SfxHelp::GetURLHelpText(rURL); } + break; } @@ -370,35 +621,43 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt) { aContentAtPos.eContentAtPos = IsAttrAtPos::Redline; if( rSh.GetContentAtPos( aPos, aContentAtPos, false, &aFieldRect ) ) - sText = lcl_GetRedlineHelp(*aContentAtPos.aFnd.pRedl, bBalloon); + sText = lcl_GetRedlineHelp(*aContentAtPos.aFnd.pRedl, bBalloon, /*bTableChange=*/false, /*bTableColChange=*/false); } } } } if (!sText.isEmpty()) { - tools::Rectangle aRect( aFieldRect.SVRect() ); - Point aPt( OutputToScreenPixel( LogicToPixel( aRect.TopLeft() ))); - aRect.SetLeft( aPt.X() ); - aRect.SetTop( aPt.Y() ); - aPt = OutputToScreenPixel( LogicToPixel( aRect.BottomRight() )); - aRect.SetRight( aPt.X() ); - aRect.SetBottom( aPt.Y() ); - - // tdf#136336 ensure tooltip area surrounds the current mouse position with at least a pixel margin - aRect.Union(tools::Rectangle(rEvt.GetMousePosPixel(), Size(1, 1))); - aRect.AdjustLeft(-1); - aRect.AdjustRight(1); - aRect.AdjustTop(-1); - aRect.AdjustBottom(1); - - if( bBalloon ) - Help::ShowBalloon( this, rEvt.GetMousePosPixel(), aRect, sText ); + if (comphelper::LibreOfficeKit::isActive()) + { + m_rView.libreOfficeKitViewCallback( + LOK_CALLBACK_TOOLTIP, getTooltipPayload(sText, aFieldRect)); + } else { - // the show the help - OUString sDisplayText(ClipLongToolTip(sText)); - Help::ShowQuickHelp(this, aRect, sDisplayText, nStyle); + tools::Rectangle aRect(aFieldRect.SVRect()); + Point aPt(OutputToScreenPixel(LogicToPixel(aRect.TopLeft()))); + aRect.SetLeft(aPt.X()); + aRect.SetTop(aPt.Y()); + aPt = OutputToScreenPixel(LogicToPixel(aRect.BottomRight())); + aRect.SetRight(aPt.X()); + aRect.SetBottom(aPt.Y()); + + // tdf#136336 ensure tooltip area surrounds the current mouse position with at least a pixel margin + aRect.Union(tools::Rectangle(rEvt.GetMousePosPixel(), Size(1, 1))); + aRect.AdjustLeft(-1); + aRect.AdjustRight(1); + aRect.AdjustTop(-1); + aRect.AdjustBottom(1); + + if (bBalloon) + Help::ShowBalloon(this, rEvt.GetMousePosPixel(), aRect, sText); + else + { + // the show the help + OUString sDisplayText(ClipLongToolTip(sText)); + Help::ShowQuickHelp(this, aRect, sDisplayText, nStyle); + } } } @@ -413,12 +672,8 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt) void SwEditWin::PrePaint(vcl::RenderContext& /*rRenderContext*/) { - SwWrtShell* pWrtShell = GetView().GetWrtShellPtr(); - - if(pWrtShell) - { + if (SwWrtShell* pWrtShell = GetView().GetWrtShellPtr()) pWrtShell->PrePaint(); - } } void SwEditWin::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) @@ -426,24 +681,6 @@ void SwEditWin::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle SwWrtShell* pWrtShell = GetView().GetWrtShellPtr(); if(!pWrtShell) return; - bool bPaintShadowCursor = false; - if( m_pShadCursor ) - { - tools::Rectangle aRect( m_pShadCursor->GetRect()); - // fully resides inside? - if( rRect.IsInside( aRect ) ) - { - // then cancel - m_pShadCursor.reset(); - } - else if( rRect.IsOver( aRect )) - { - // resides somewhat above, then everything is clipped outside - // and we have to make the "inner part" at the end of the - // Paint visible again. Otherwise Paint errors occur! - bPaintShadowCursor = true; - } - } if ( GetView().GetVisArea().GetWidth() <= 0 || GetView().GetVisArea().GetHeight() <= 0 ) @@ -464,12 +701,6 @@ void SwEditWin::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle } pWrtShell->setOutputToWindow(false); } - - if( bPaintShadowCursor ) - m_pShadCursor->Paint(); - - if (pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton()) - GetFrameControlsManager().SetOutlineContentVisibilityButtons(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |