diff options
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/cmdid.h | 2 | ||||
-rw-r--r-- | sw/inc/doc.hxx | 2 | ||||
-rw-r--r-- | sw/inc/strings.hrc | 4 | ||||
-rw-r--r-- | sw/inc/view.hxx | 4 | ||||
-rw-r--r-- | sw/sdi/_viewsh.sdi | 6 | ||||
-rw-r--r-- | sw/sdi/swriter.sdi | 17 | ||||
-rw-r--r-- | sw/source/core/doc/doc.cxx | 55 | ||||
-rw-r--r-- | sw/source/core/inc/txtfrm.hxx | 6 | ||||
-rw-r--r-- | sw/source/core/layout/paintfrm.cxx | 89 | ||||
-rw-r--r-- | sw/source/core/text/frmpaint.cxx | 4 | ||||
-rw-r--r-- | sw/source/core/text/inftxt.cxx | 177 | ||||
-rw-r--r-- | sw/source/core/text/inftxt.hxx | 2 | ||||
-rw-r--r-- | sw/source/core/text/porexp.cxx | 3 | ||||
-rw-r--r-- | sw/source/core/text/portxt.cxx | 2 | ||||
-rw-r--r-- | sw/source/uibase/docvw/edtwin2.cxx | 203 | ||||
-rw-r--r-- | sw/source/uibase/uiview/view0.cxx | 11 |
16 files changed, 585 insertions, 2 deletions
diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h index 82616e3c2340..5459c63b8ff1 100644 --- a/sw/inc/cmdid.h +++ b/sw/inc/cmdid.h @@ -170,6 +170,8 @@ class SwUINumRuleItem; #define FN_VIEW_FIELDNAME (FN_VIEW + 26) /* View field names */ #define FN_VIEW_TABLEGRID (FN_VIEW + 27) /* View tablegrid */ +#define FN_HIGHLIGHT_CHAR_DF (FN_VIEW + 28) + #define FN_SET_PAGE (FN_VIEW + 29) /* Set page template to paragraph */ #define FN_PRINT_LAYOUT (FN_VIEW + 37) /* print layout */ diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx index 1b008bf2bac2..7a1b2e0ee969 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -1690,6 +1690,8 @@ public: void SetLanguage(const LanguageType eLang, const sal_uInt16 nId); + static bool HasParagraphDirectFormatting(const SwPosition& rPos); + private: // Copies master header to left / first one, if necessary - used by ChgPageDesc(). void CopyMasterHeader(const SwPageDesc &rChged, const SwFormatHeader &rHead, SwPageDesc &pDesc, bool bLeft, bool bFirst); diff --git a/sw/inc/strings.hrc b/sw/inc/strings.hrc index a9e5a78828e0..a29a9c9e6e52 100644 --- a/sw/inc/strings.hrc +++ b/sw/inc/strings.hrc @@ -1468,6 +1468,10 @@ #define STR_INFORODLG_FOLDED_PRIMARY NC_("STR_INFORODLG_FOLDED_PRIMARY", "You are trying to delete folded (hidden) content.") #define STR_INFORODLG_FOLDED_SECONDARY NC_("STR_INFORODLG_FOLDED_SECONDARY", "To delete this content, first unfold it so you can see what you intend to delete.") +#define STR_PARAGRAPH_DIRECT_FORMATTING NC_("STR_PARAGRAPH_DIRECT_FORMATTING", "Paragraph Direct Formatting") +#define STR_CHARACTER_DIRECT_FORMATTING NC_("STR_CHARACTER_DIRECT_FORMATTING", "Character Direct Formatting") +#define STR_CHARACTER_DIRECT_FORMATTING_TAG NC_("STR_CHARACTER_DIRECT_FORMATTING_TAG", "df") + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/inc/view.hxx b/sw/inc/view.hxx index ff0099ace634..60fe6fdc7303 100644 --- a/sw/inc/view.hxx +++ b/sw/inc/view.hxx @@ -270,6 +270,8 @@ class SW_DLLPUBLIC SwView: public SfxViewShell int m_nMaxOutlineLevelShown = 10; + bool m_bIsHighlightCharDF = false; + static constexpr sal_uInt16 MAX_ZOOM_PERCENT = 600; static constexpr sal_uInt16 MIN_ZOOM_PERCENT = 20; @@ -706,6 +708,8 @@ public: virtual tools::Rectangle getLOKVisibleArea() const override; virtual void flushPendingLOKInvalidateTiles() override; virtual std::optional<OString> getLOKPayload(int nType, int nViewId) const override; + + bool IsHighlightCharDF() { return m_bIsHighlightCharDF; } }; inline tools::Long SwView::GetXScroll() const diff --git a/sw/sdi/_viewsh.sdi b/sw/sdi/_viewsh.sdi index 020383d31abc..a3b2e5e3cdcc 100644 --- a/sw/sdi/_viewsh.sdi +++ b/sw/sdi/_viewsh.sdi @@ -912,6 +912,12 @@ interface BaseTextEditView StateMethod = StateViewOptions ; ] + FN_HIGHLIGHT_CHAR_DF + [ + ExecMethod = ExecViewOptions ; + StateMethod = StateViewOptions ; + ] + FN_VIEW_META_CHARS // status() [ ExecMethod = ExecViewOptions ; diff --git a/sw/sdi/swriter.sdi b/sw/sdi/swriter.sdi index 69e41da52ccc..15d098cc996c 100644 --- a/sw/sdi/swriter.sdi +++ b/sw/sdi/swriter.sdi @@ -4070,6 +4070,23 @@ SfxBoolItem Marks FN_VIEW_MARKS GroupId = SfxGroupId::View; ] +SfxBoolItem HighlightCharDF FN_HIGHLIGHT_CHAR_DF + +[ + AutoUpdate = TRUE, + FastCall = FALSE, + ReadOnlyDoc = TRUE, + Toggle = TRUE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + AccelConfig = TRUE, + MenuConfig = TRUE, + ToolBoxConfig = TRUE, + GroupId = SfxGroupId::View; +] + SfxVoidItem MergeCells FN_TABLE_MERGE_CELLS () [ diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx index 07f54882fbdd..5c686f1f8c3a 100644 --- a/sw/source/core/doc/doc.cxx +++ b/sw/source/core/doc/doc.cxx @@ -105,6 +105,12 @@ */ #include <docsh.hxx> +#include <com/sun/star/text/XTextRange.hpp> +#include <editeng/unoprnms.hxx> +#include <unotextrange.hxx> +#include <unoprnms.hxx> +#include <unomap.hxx> + using namespace ::com::sun::star; sal_Int32 SwDoc::acquire() @@ -1859,4 +1865,53 @@ void SwDoc::SetLanguage(const LanguageType eLang, const sal_uInt16 nId) mpAttrPool->SetPoolDefaultItem(SvxLanguageItem(eLang, nId)); } +bool SwDoc::HasParagraphDirectFormatting(const SwPosition& rPos) +{ + uno::Reference<text::XTextRange> xRange(SwXTextRange::CreateXTextRange(rPos.GetDoc(), rPos, + &rPos)); + uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xRange, uno::UNO_QUERY_THROW); + uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration(); + uno::Reference<text::XTextRange> xThisParagraphRange(xParaEnum->nextElement(), uno::UNO_QUERY); + if (xThisParagraphRange.is()) + { + 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_PARA_AUTO_STYLE)); + SfxItemPropertyMap const& rMap(rPropSet.getPropertyMap()); + + uno::Reference<beans::XPropertySet> xPropertySet(xThisParagraphRange, + uno::UNO_QUERY_THROW); + uno::Reference<beans::XPropertyState> xPropertyState(xThisParagraphRange, + uno::UNO_QUERY_THROW); + const uno::Sequence<beans::Property> aProperties + = xPropertySet->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 (xPropertyState->getPropertyState(rPropName) == beans::PropertyState_DIRECT_VALUE) + return true; + } + } + return false; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx index 942867882626..2376153b40d3 100644 --- a/sw/source/core/inc/txtfrm.hxx +++ b/sw/source/core/inc/txtfrm.hxx @@ -27,6 +27,8 @@ #include <set> #include <utility> +#include <view.hxx> + namespace com::sun::star::linguistic2 { class XHyphenatedWord; } namespace sw::mark { class IMark; } @@ -330,6 +332,8 @@ class SW_DLLPUBLIC SwTextFrame final : public SwContentFrame void UpdateOutlineContentVisibilityButton(SwWrtShell* pWrtSh) const; void PaintOutlineContentVisibilityButton() const; + void PaintParagraphStylesHighlighting() const; + virtual void SwClientNotify(SwModify const& rModify, SfxHint const& rHint) override; /// Like GetDrawObjs(), but limit to fly frames which are allowed to split. @@ -791,6 +795,8 @@ public: /// a follow, i.e. not the last in a master -> follow 1 -> ... -> last follow chain? bool HasNonLastSplitFlyDrawObj() const; + static SwView* GetView(); + virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const override; }; diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx index 66612ba3b840..a68f58eaf5d7 100644 --- a/sw/source/core/layout/paintfrm.cxx +++ b/sw/source/core/layout/paintfrm.cxx @@ -120,6 +120,10 @@ #include <vcl/GraphicLoader.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> +#include <svl/style.hxx> +#include <ndtxt.hxx> +#include <vcl/hatch.hxx> + using namespace ::editeng; using namespace ::com::sun::star; @@ -4332,6 +4336,90 @@ void SwFlyFrame::PaintDecorators() const } } +SwView* SwTextFrame::GetView() +{ + SwWrtShell* pWrtSh = dynamic_cast<SwWrtShell*>(gProp.pSGlobalShell); + + if (!pWrtSh) + return nullptr; + + return &pWrtSh->GetView(); +} + +void SwTextFrame::PaintParagraphStylesHighlighting() const +{ + // Maybe avoid the dynamic_cast and just use GetActiveWrtShell() + // NO! Multiple windows will not dispay the highlighting correctly if GetActiveWrtShell is used. + SwWrtShell* pWrtSh = dynamic_cast<SwWrtShell*>(gProp.pSGlobalShell); + + if (!pWrtSh) + return; + + vcl::RenderContext* pRenderContext = pWrtSh->GetOut(); + if (!pRenderContext) + return; + + StylesHighlighterColorMap& rParaStylesColorMap + = pWrtSh->GetView().GetStylesHighlighterParaColorMap(); + + if (rParaStylesColorMap.empty()) + return; + + // draw styles highlighter + OUString sStyleName = GetTextNodeFirst()->GetTextColl()->GetName(); + if (rParaStylesColorMap.find(sStyleName) != rParaStylesColorMap.end()) + { + SwRect aFrameAreaRect(getFrameArea()); + + if (IsRightToLeft()) + { + aFrameAreaRect.AddRight(75); + aFrameAreaRect.Left(aFrameAreaRect.Right() + 300); + } + else + { + aFrameAreaRect.AddLeft(-375); + aFrameAreaRect.Right(aFrameAreaRect.Left() + 300); + } + + const tools::Rectangle& rRect = aFrameAreaRect.SVRect(); + + vcl::Font aFont(OutputDevice::GetDefaultFont(DefaultFontType::UI_SANS, GetAppLanguage(), + GetDefaultFontFlags::OnlyOne, pRenderContext)); + aFont.SetFontSize(Size(0, 140 * pRenderContext->GetDPIScaleFactor())); + aFont.SetUnderline(FontLineStyle::LINESTYLE_NONE); + aFont.SetTransparent(false); + aFont.SetWeight(WEIGHT_NORMAL); + aFont.SetFamily(FontFamily::FAMILY_MODERN); + aFont.SetColor(COL_BLACK); + + pRenderContext->Push(vcl::PushFlags::ALL); + + pRenderContext->SetFillColor(rParaStylesColorMap[sStyleName].first); + pRenderContext->SetLineColor(rParaStylesColorMap[sStyleName].first); + + pRenderContext->DrawRect(rRect); + + // draw hatch pattern if paragraph has direct formatting + if (SwDoc::HasParagraphDirectFormatting(SwPosition(*GetTextNodeForParaProps()))) + { + Color aHatchColor(rParaStylesColorMap[sStyleName].first); + // make hatch line color 41% darker than the fill color + aHatchColor.ApplyTintOrShade(-4100); + Hatch aHatch(HatchStyle::Single, aHatchColor, 50, 450_deg10); + pRenderContext->DrawHatch(tools::PolyPolygon(rRect), aHatch); + } + + pRenderContext->SetFont(aFont); + pRenderContext->SetLayoutMode(vcl::text::ComplexTextLayoutFlags::Default); + pRenderContext->SetTextFillColor(rParaStylesColorMap[sStyleName].first); + pRenderContext->DrawText(rRect, OUString::number(rParaStylesColorMap[sStyleName].second), + DrawTextFlags::Center | DrawTextFlags::VCenter); + + pRenderContext->Pop(); + } +} + void SwTextFrame::PaintOutlineContentVisibilityButton() const { SwWrtShell* pWrtSh = dynamic_cast<SwWrtShell*>(gProp.pSGlobalShell); @@ -4339,7 +4427,6 @@ void SwTextFrame::PaintOutlineContentVisibilityButton() const UpdateOutlineContentVisibilityButton(pWrtSh); } - void SwTabFrame::PaintSwFrame(vcl::RenderContext& rRenderContext, SwRect const& rRect, SwPrintData const*const) const { const SwViewOption* pViewOption = gProp.pSGlobalShell->GetViewOptions(); diff --git a/sw/source/core/text/frmpaint.cxx b/sw/source/core/text/frmpaint.cxx index 74ff8c968e07..b187db7ac0b1 100644 --- a/sw/source/core/text/frmpaint.cxx +++ b/sw/source/core/text/frmpaint.cxx @@ -501,6 +501,8 @@ SwRect SwTextFrame::GetPaintSwRect() bool SwTextFrame::PaintEmpty( const SwRect &rRect, bool bCheck ) const { + PaintParagraphStylesHighlighting(); + SwViewShell *pSh = getRootFrame()->GetCurrShell(); if( pSh && ( pSh->GetViewOptions()->IsParagraph() || bInitFont ) ) { @@ -793,6 +795,8 @@ void SwTextFrame::PaintSwFrame(vcl::RenderContext& rRenderContext, SwRect const& rRepaint.Clear(); } + PaintParagraphStylesHighlighting(); + const_cast<SwRect&>(rRect) = aOldRect; OSL_ENSURE( ! IsSwapped(), "A frame is swapped after Paint" ); diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx index a0032082dd95..895d2aba2dd7 100644 --- a/sw/source/core/text/inftxt.cxx +++ b/sw/source/core/text/inftxt.cxx @@ -67,6 +67,16 @@ #include <i18nlangtag/mslangid.hxx> #include <formatlinebreak.hxx> +#include <view.hxx> +#include <wrtsh.hxx> +#include <com/sun/star/text/XTextRange.hpp> +#include <unotextrange.hxx> +#include <SwStyleNameMapper.hxx> +#include <unoprnms.hxx> +#include <editeng/unoprnms.hxx> +#include <unomap.hxx> +#include <com/sun/star/awt/FontSlant.hpp> + using namespace ::com::sun::star; using namespace ::com::sun::star::linguistic2; using namespace ::com::sun::star::uno; @@ -1305,6 +1315,173 @@ void SwTextPaintInfo::DrawBorder( const SwLinePortion &rPor ) const } } +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; +} +} + +void SwTextPaintInfo::DrawCSDFHighlighting(const SwLinePortion &rPor) const +{ + // Don't use GetActiveView() as it does not work as expected when there are multiple open + // documents. + SwView* pView = SwTextFrame::GetView(); + if (!pView) + return; + + StylesHighlighterColorMap& rCharStylesColorMap = pView->GetStylesHighlighterCharColorMap(); + + if (rCharStylesColorMap.empty() && !pView->IsHighlightCharDF()) + return; + + SwRect aRect; + CalcRect(rPor, &aRect, nullptr, true); + if(!aRect.HasArea()) + return; + + SwTextFrame* pFrame = const_cast<SwTextFrame*>(GetTextFrame()); + if (!pFrame) + return; + + SwPosition aPosition(pFrame->MapViewToModelPos(GetIdx())); + SwPosition aMarkPosition(pFrame->MapViewToModelPos(GetIdx() + GetLen())); + + uno::Reference<text::XTextRange> xRange( + SwXTextRange::CreateXTextRange(pFrame->GetDoc(), aPosition, &aMarkPosition)); + uno::Reference<beans::XPropertySet> xPropertiesSet(xRange, uno::UNO_QUERY_THROW); + + OUString sCurrentCharStyle; + xPropertiesSet->getPropertyValue("CharStyleName") >>= sCurrentCharStyle; + + std::optional<OUString> sCSNumberOrDF; // CS number or "df" or not used + std::optional<Color> aFillColor; + + // check for CS formatting, if not CS formatted check for direct character formatting + if (!sCurrentCharStyle.isEmpty()) + { + if (!rCharStylesColorMap.empty()) + { + OUString sCharStyleDisplayName; + sCharStyleDisplayName = SwStyleNameMapper::GetUIName(sCurrentCharStyle, + SwGetPoolIdFromName::ChrFmt); + if (!sCharStyleDisplayName.isEmpty() + && rCharStylesColorMap.find(sCharStyleDisplayName) + != rCharStylesColorMap.end()) + { + aFillColor = rCharStylesColorMap[sCharStyleDisplayName].first; + sCSNumberOrDF = OUString::number(rCharStylesColorMap[sCharStyleDisplayName].second); + } + } + } + // not character style formatted + else if (pView->IsHighlightCharDF()) + { + 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()); + + + uno::Reference<beans::XPropertyState> xPropertiesState(xRange, uno::UNO_QUERY_THROW); + const uno::Sequence<beans::Property> aProperties + = xPropertiesSet->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 (xPropertiesState->getPropertyState(rPropName) == beans::PropertyState_DIRECT_VALUE) + { + const uno::Any aAny = xPropertiesSet->getPropertyValue(rPropName); + if (HasValidPropertyValue(aAny)) + { + sCSNumberOrDF = SwResId(STR_CHARACTER_DIRECT_FORMATTING_TAG); + aFillColor = COL_LIGHTGRAY; + break; + } + } + } + } + if (sCSNumberOrDF) + { + OutputDevice* pTmpOut = const_cast<OutputDevice*>(GetOut()); + pTmpOut->Push(vcl::PushFlags::LINECOLOR | vcl::PushFlags::FILLCOLOR + | vcl::PushFlags::TEXTLAYOUTMODE | vcl::PushFlags::FONT); + + // draw a filled rectangle at the formatted CS or DF text + pTmpOut->SetFillColor(aFillColor.value()); + pTmpOut->SetLineColor(aFillColor.value()); + tools::Rectangle aSVRect(aRect.SVRect()); + pTmpOut->DrawRect(aSVRect); + + // calculate size and position for the CS number or "df" text and rectangle + tools::Long nWidth = pTmpOut->GetTextWidth(sCSNumberOrDF.value()); + tools::Long nHeight = pTmpOut->GetTextHeight(); + aSVRect.SetSize(Size(nWidth, nHeight)); + aSVRect.Move(-(nWidth / 1.5), -(nHeight / 1.5)); + + vcl::Font aFont(pTmpOut->GetFont()); + aFont.SetOrientation(Degree10(0)); + pTmpOut->SetFont(aFont); + + pTmpOut->SetLayoutMode(vcl::text::ComplexTextLayoutFlags::TextOriginLeft); + //pTmpOut->SetLayoutMode(vcl::text::ComplexTextLayoutFlags::BiDiStrong); + + pTmpOut->SetTextFillColor(aFillColor.value()); + pTmpOut->DrawText(aSVRect, sCSNumberOrDF.value(), DrawTextFlags::NONE); + + pTmpOut->Pop(); + } +} + void SwTextPaintInfo::DrawViewOpt( const SwLinePortion &rPor, PortionType nWhich, const Color *pColor ) const { diff --git a/sw/source/core/text/inftxt.hxx b/sw/source/core/text/inftxt.hxx index 8011b29b442a..62cca26ac08f 100644 --- a/sw/source/core/text/inftxt.hxx +++ b/sw/source/core/text/inftxt.hxx @@ -416,6 +416,8 @@ public: void DrawCheckBox(const SwFieldFormCheckboxPortion &rPor, bool bChecked) const; + void DrawCSDFHighlighting(const SwLinePortion &rPor) const; + /** * Calculate the rectangular area where the portion takes place. * @param[in] rPor portion for which the method specify the painting area diff --git a/sw/source/core/text/porexp.cxx b/sw/source/core/text/porexp.cxx index 9251d9f84171..de435df5ae54 100644 --- a/sw/source/core/text/porexp.cxx +++ b/sw/source/core/text/porexp.cxx @@ -74,12 +74,15 @@ bool SwExpandPortion::Format( SwTextFormatInfo &rInf ) void SwExpandPortion::Paint( const SwTextPaintInfo &rInf ) const { + rInf.DrawCSDFHighlighting(*this); // here it detects as CS and not DF + SwTextSlot aDiffText( &rInf, this, true, true ); const SwFont aOldFont = *rInf.GetFont(); if( GetJoinBorderWithPrev() ) const_cast<SwTextPaintInfo&>(rInf).GetFont()->SetLeftBorder(nullptr); if( GetJoinBorderWithNext() ) const_cast<SwTextPaintInfo&>(rInf).GetFont()->SetRightBorder(nullptr); +// rInf.DrawCSDFHighlighting(*this); // here it detects as DF and only the '/' is detected as CS rInf.DrawBackBrush( *this ); rInf.DrawBorder( *this ); diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx index 778a319d2470..ebd281c607cf 100644 --- a/sw/source/core/text/portxt.cxx +++ b/sw/source/core/text/portxt.cxx @@ -549,6 +549,8 @@ void SwTextPortion::Paint( const SwTextPaintInfo &rInf ) const rInf.DrawBackBrush( *this ); rInf.DrawBorder( *this ); + rInf.DrawCSDFHighlighting(*this); + // do we have to repaint a post it portion? if( rInf.OnWin() && mpNextPortion && !mpNextPortion->Width() ) mpNextPortion->PrePaint( rInf, this ); diff --git a/sw/source/uibase/docvw/edtwin2.cxx b/sw/source/uibase/docvw/edtwin2.cxx index 94febf8b1f72..a98d38cf1e79 100644 --- a/sw/source/uibase/docvw/edtwin2.cxx +++ b/sw/source/uibase/docvw/edtwin2.cxx @@ -54,6 +54,205 @@ #include <comphelper/lok.hxx> #include <authfld.hxx> +#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> + +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; + + uno::Reference<text::XTextRange> xRange( + SwXTextRange::CreateXTextRange(*(rView.GetDocShell()->GetDoc()), + aPos, &aPos)); + uno::Reference<beans::XPropertySet> xPropertySet(xRange, uno::UNO_QUERY_THROW); + + 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; + xPropertySet->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()); + + uno::Reference<beans::XPropertyState> xPropertiesState(xRange, uno::UNO_QUERY_THROW); + const uno::Sequence<beans::Property> aProperties + = xPropertySet->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 (xPropertiesState->getPropertyState(rPropName) + == beans::PropertyState_DIRECT_VALUE) + { + const uno::Any aAny = xPropertySet->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; + xPropertySet->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 ) { TranslateId pResId; @@ -108,6 +307,10 @@ OUString SwEditWin::ClipLongToolTip(const OUString& rText) 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; diff --git a/sw/source/uibase/uiview/view0.cxx b/sw/source/uibase/uiview/view0.cxx index ba555570044e..0a620a0a05e5 100644 --- a/sw/source/uibase/uiview/view0.cxx +++ b/sw/source/uibase/uiview/view0.cxx @@ -225,7 +225,7 @@ void SwView::StateViewOptions(SfxItemSet &rSet) while(nWhich) { bool bReadonly = GetDocShell()->IsReadOnly(); - if ( bReadonly && nWhich != FN_VIEW_GRAPHIC ) + if (bReadonly && nWhich != FN_VIEW_GRAPHIC && nWhich != FN_HIGHLIGHT_CHAR_DF) { rSet.DisableItem(nWhich); nWhich = 0; @@ -359,6 +359,9 @@ void SwView::StateViewOptions(SfxItemSet &rSet) case FN_SHOW_CHANGES_IN_MARGIN: aBool.SetValue( pOpt->IsShowChangesInMargin() ); break; + case FN_HIGHLIGHT_CHAR_DF: + aBool.SetValue(m_bIsHighlightCharDF); + break; } if( nWhich ) @@ -549,6 +552,12 @@ void SwView::ExecViewOptions(SfxRequest &rReq) lcl_SetViewMarks( *pOpt, bFlag ); break; + case FN_HIGHLIGHT_CHAR_DF: + if (STATE_TOGGLE == eState) + bFlag = !m_bIsHighlightCharDF; + m_bIsHighlightCharDF = bFlag; + break; + case FN_VIEW_META_CHARS: if( STATE_TOGGLE == eState ) bFlag = !pOpt->IsViewMetaChars(); |