include/oox/vml/vmlformatting.hxx | 1 include/sfx2/sfxsids.hrc | 10 include/sfx2/watermarkitem.hxx | 47 + officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu | 8 oox/source/export/vmlexport.cxx | 4 oox/source/vml/vmlformatting.cxx | 22 oox/source/vml/vmlshapecontext.cxx | 12 sfx2/Library_sfx.mk | 1 sfx2/sdi/sfx.sdi | 20 sfx2/sdi/sfxitems.sdi | 1 sfx2/source/doc/watermarkitem.cxx | 92 ++ sw/Library_sw.mk | 1 sw/UIConfig_swriter.mk | 1 sw/inc/editsh.hxx | 4 sw/qa/extras/ooxmlexport/data/watermark-font.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport2.cxx | 13 sw/qa/extras/ooxmlexport/ooxmlexport7.cxx | 4 sw/qa/extras/uiwriter/data/watermark.docx |binary sw/qa/extras/uiwriter/uiwriter.cxx | 22 sw/sdi/_basesh.sdi | 6 sw/source/core/edit/edfcol.cxx | 374 ++++++---- sw/source/uibase/app/docsh2.cxx | 34 sw/source/uibase/app/docst.cxx | 8 sw/source/uibase/dialog/watermarkdialog.cxx | 104 ++ sw/source/uibase/inc/watermarkdialog.hxx | 42 + sw/source/uibase/shells/basesh.cxx | 5 sw/source/uibase/shells/slotadd.cxx | 1 sw/uiconfig/swriter/menubar/menubar.xml | 1 sw/uiconfig/swriter/ui/watermarkdialog.ui | 215 +++++ 29 files changed, 921 insertions(+), 132 deletions(-)
New commits: commit 8d322275b0a4d482296b891a550e538e33986324 Author: Szymon KÅos <szymon.k...@collabora.com> Date: Thu May 25 18:54:37 2017 +0200 Watermark: VML font-family import for textpath Handle style attribute to get font-family: <v:textpath style="font-family:"DejaVu Sans Light";font-size:1pt" .../> Change-Id: I5fe530aecccc57e103b413ef494502f666f1005a Reviewed-on: https://gerrit.libreoffice.org/38039 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> diff --git a/include/oox/vml/vmlformatting.hxx b/include/oox/vml/vmlformatting.hxx index d7c3e92f0b9c..efb0e6606887 100644 --- a/include/oox/vml/vmlformatting.hxx +++ b/include/oox/vml/vmlformatting.hxx @@ -241,6 +241,7 @@ struct OOX_DLLPUBLIC ShadowModel struct OOX_DLLPUBLIC TextpathModel { OptValue<OUString> moString; ///< Specifies the string of the textpath. + OptValue<OUString> moStyle; ///< Specifies the style of the textpath. TextpathModel(); diff --git a/oox/source/vml/vmlformatting.cxx b/oox/source/vml/vmlformatting.cxx index 36cc43dea07d..f37c15d181d6 100644 --- a/oox/source/vml/vmlformatting.cxx +++ b/oox/source/vml/vmlformatting.cxx @@ -882,6 +882,28 @@ void TextpathModel::pushToPropMap(ShapePropertyMap& rPropMap, const uno::Referen } rPropMap.setAnyProperty(PROP_CustomShapeGeometry, uno::makeAny(aGeomPropSeq)); } + if (moStyle.has()) + { + OUString aStyle = moStyle.get(OUString()); + + sal_Int32 nIndex = 0; + while( nIndex >= 0 ) + { + OUString aName, aValue; + if (ConversionHelper::separatePair(aName, aValue, aStyle.getToken(0, ';', nIndex), ':')) + { + if (aName == "font-family") + { + // remove " (first, and last character) + if (aValue.getLength() > 2) + aValue = aValue.copy(1, aValue.getLength() - 2); + + uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY); + xPropertySet->setPropertyValue("CharFontName", uno::makeAny(aValue)); + } + } + } + } } } // namespace vml diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx index ed369ae1c7d9..02cf06e51429 100644 --- a/oox/source/vml/vmlshapecontext.cxx +++ b/oox/source/vml/vmlshapecontext.cxx @@ -383,6 +383,7 @@ ContextHandlerRef ShapeTypeContext::onCreateContext( sal_Int32 nElement, const A break; case VML_TOKEN( textpath ): mrTypeModel.maTextpathModel.moString.assignIfUsed(rAttribs.getString(XML_string)); + mrTypeModel.maTextpathModel.moStyle.assignIfUsed(rAttribs.getString(XML_style)); break; } return nullptr; diff --git a/sw/qa/extras/ooxmlexport/data/watermark-font.docx b/sw/qa/extras/ooxmlexport/data/watermark-font.docx new file mode 100644 index 000000000000..82d7ec8a83fc Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/watermark-font.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx index 80b5bba9ad9f..636dd76643e6 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx @@ -727,6 +727,19 @@ DECLARE_OOXMLEXPORT_TEST(testWatermark, "watermark.docx") CPPUNIT_ASSERT_EQUAL(drawing::LineStyle_NONE, getProperty<drawing::LineStyle>(xShape, "LineStyle")); } +DECLARE_OOXMLEXPORT_TEST(testWatermarkFont, "watermark-font.docx") +{ + uno::Reference<text::XTextRange> xShape(getShape(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("TestFont"), xShape->getString()); + + uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY); + OUString aFont; + + // Check font family + CPPUNIT_ASSERT(xPropertySet->getPropertyValue("CharFontName") >>= aFont); + CPPUNIT_ASSERT_EQUAL(OUString("DejaVu Serif"), aFont); +} + DECLARE_OOXMLEXPORT_TEST(testFdo43093, "fdo43093.docx") { // The problem was that the alignment are not exchange when the paragraph are RTL. diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index e8c81d6e575b..b3c0ff237025 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -835,8 +835,7 @@ void SwUiWriterTest::testWatermarkDOCX() const SfxWatermarkItem* pWatermark = static_cast<const SfxWatermarkItem*>(pItem); CPPUNIT_ASSERT_EQUAL(OUString("CustomWatermark"), pWatermark->GetText()); - //TODO: VML import textpath style - //CPPUNIT_ASSERT_EQUAL(OUString("DejaVu Sans Light"), pWatermark->GetFont()); + CPPUNIT_ASSERT_EQUAL(OUString("DejaVu Sans Light"), pWatermark->GetFont()); CPPUNIT_ASSERT_EQUAL((sal_Int16)45, pWatermark->GetAngle()); CPPUNIT_ASSERT_EQUAL((sal_uInt32)0x548dd4, pWatermark->GetColor()); CPPUNIT_ASSERT_EQUAL((sal_Int16)50, pWatermark->GetTransparency()); commit 5bc597c49207be961454cc333425f6d2a9230347 Author: Szymon KÅos <szymon.k...@collabora.com> Date: Wed May 24 00:15:15 2017 +0200 Watermark: docx interoperability Before patch: Document created in MS Word: <v:shapetype id="_x0000_t136" o:spt="136" ...> <v:shape type="#_x0000_t136" ...> Imported to LO and exported: <v:shapetype id="shapetype_136" o:spt="136" ...> <v:shape type="shapetype_136" ...> Then again imported to MS Word and exported: <v:shapetype id="shapetype_136" o:spid="_x0000_m1026" o:spt="100" ...> <v:shape type="#shapetype_136" ...> In this moment LO after import had shape in the navigator but it wasn't visible. Patch: * vmshapecontext.cxx is changed to read ShapeType from id instead of o:spt when o:spid is present. * vmlexport.cxx added o:spid for Word to identify inserted watermark * edfxol.cxx changed name of shape to "PowerPlusWaterMarkObject" for Word * tests Change-Id: I25322628838a98c45cbeed64144d04977b2ea9ba Reviewed-on: https://gerrit.libreoffice.org/37969 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> diff --git a/oox/source/export/vmlexport.cxx b/oox/source/export/vmlexport.cxx index 28de3dce50c2..8ba7d9fb492f 100644 --- a/oox/source/export/vmlexport.cxx +++ b/oox/source/export/vmlexport.cxx @@ -197,8 +197,10 @@ void VMLExport::AddShape( sal_uInt32 nShapeType, sal_uInt32 nShapeFlags, sal_uIn } else { - // A watermark object - store the optional shape ID also ('o:spid') + // A watermark object - store the optional shape ID m_pShapeAttrList->add( XML_id, OUStringToOString(m_pSdrObject->GetName(), RTL_TEXTENCODING_UTF8) ); + // also ('o:spid') + m_pShapeAttrList->addNS( XML_o, XML_spid, ShapeIdString( nShapeId ) ); } } diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx index dc654223aca6..ed369ae1c7d9 100644 --- a/oox/source/vml/vmlshapecontext.cxx +++ b/oox/source/vml/vmlshapecontext.cxx @@ -275,11 +275,18 @@ ShapeTypeContext::ShapeTypeContext( ContextHandler2Helper& rParent, ShapeType& r mrTypeModel.maShapeId = rAttribs.getXString( bHasOspid ? O_TOKEN( spid ) : XML_id, OUString() ); mrTypeModel.maLegacyId = rAttribs.getString( XML_id, OUString() ); OSL_ENSURE( !mrTypeModel.maShapeId.isEmpty(), "ShapeTypeContext::ShapeTypeContext - missing shape identifier" ); + // builtin shape type identifier + mrTypeModel.moShapeType = rAttribs.getInteger( O_TOKEN( spt ) ); // if the o:spid attribute exists, the id attribute contains the user-defined shape name if( bHasOspid ) + { mrTypeModel.maShapeName = rAttribs.getXString( XML_id, OUString() ); - // builtin shape type identifier - mrTypeModel.moShapeType = rAttribs.getInteger( O_TOKEN( spt ) ); + // get ShapeType and ShapeId from name for compatibility + mrTypeModel.maShapeId = mrTypeModel.maShapeName; + static const OUString sShapeTypePrefix = "shapetype_"; + if( mrTypeModel.maShapeName.startsWith( sShapeTypePrefix ) ) + mrTypeModel.moShapeType = mrTypeModel.maShapeName.copy(sShapeTypePrefix.getLength()).toInt32(); + } // coordinate system position/size, CSS style mrTypeModel.moCoordPos = lclDecodeInt32Pair( rAttribs, XML_coordorigin ); diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx index b538e9f990da..e7f24005cd92 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx @@ -106,6 +106,10 @@ DECLARE_OOXMLEXPORT_TEST(testTextWatermark, "textWatermark.docx") return; assertXPath(pXmlHeader1, "/w:hdr[1]/w:p[1]/w:r[1]/w:pict[1]/v:shape[1]","id","PowerPlusWaterMarkObject93701316"); + + //The second problem was that Word uses also "o:spid" + const OUString& sSpid = getXPath(pXmlHeader1, "/w:hdr[1]/w:p[1]/w:r[1]/w:pict[1]/v:shape[1]","spid"); + CPPUNIT_ASSERT(!sSpid.isEmpty()); } DECLARE_OOXMLEXPORT_TEST(testPictureWatermark, "pictureWatermark.docx") diff --git a/sw/qa/extras/uiwriter/data/watermark.docx b/sw/qa/extras/uiwriter/data/watermark.docx new file mode 100644 index 000000000000..0b26d4442e98 Binary files /dev/null and b/sw/qa/extras/uiwriter/data/watermark.docx differ diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index 4594b5ba4936..e8c81d6e575b 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -100,6 +100,7 @@ #include <comphelper/configurationhelper.hxx> #include <editeng/unolingu.hxx> #include <config_features.h> +#include <sfx2/watermarkitem.hxx> static const char* DATA_DIRECTORY = "/sw/qa/extras/uiwriter/data/"; @@ -121,6 +122,7 @@ public: void testDOCXAutoTextMultiple(); void testDOTMAutoText(); void testDOCXAutoTextGallery(); + void testWatermarkDOCX(); void testTdf67238(); void testFdo75110(); void testFdo75898(); @@ -243,6 +245,7 @@ public: CPPUNIT_TEST(testDOCXAutoTextMultiple); CPPUNIT_TEST(testDOTMAutoText); CPPUNIT_TEST(testDOCXAutoTextGallery); + CPPUNIT_TEST(testWatermarkDOCX); CPPUNIT_TEST(testTdf67238); CPPUNIT_TEST(testFdo75110); CPPUNIT_TEST(testFdo75898); @@ -819,6 +822,26 @@ void SwUiWriterTest::testDOCXAutoTextGallery() CPPUNIT_ASSERT_EQUAL(OUString("Multiple"), pGlossary->GetLongName(0)); } +void SwUiWriterTest::testWatermarkDOCX() +{ + SwDoc* const pDoc = createDoc("watermark.docx"); + SwDocShell* pDocShell = pDoc->GetDocShell(); + const SfxPoolItem* pItem; + SfxItemState eState = pDocShell->GetViewShell()->GetViewFrame()->GetDispatcher()->QueryState(SID_WATERMARK, pItem); + + CPPUNIT_ASSERT(eState >= SfxItemState::DEFAULT); + CPPUNIT_ASSERT(pItem); + CPPUNIT_ASSERT_EQUAL((unsigned short)SID_WATERMARK, pItem->Which()); + + const SfxWatermarkItem* pWatermark = static_cast<const SfxWatermarkItem*>(pItem); + CPPUNIT_ASSERT_EQUAL(OUString("CustomWatermark"), pWatermark->GetText()); + //TODO: VML import textpath style + //CPPUNIT_ASSERT_EQUAL(OUString("DejaVu Sans Light"), pWatermark->GetFont()); + CPPUNIT_ASSERT_EQUAL((sal_Int16)45, pWatermark->GetAngle()); + CPPUNIT_ASSERT_EQUAL((sal_uInt32)0x548dd4, pWatermark->GetColor()); + CPPUNIT_ASSERT_EQUAL((sal_Int16)50, pWatermark->GetTransparency()); +} + void SwUiWriterTest::testFdo74981() { // create a document with an input field diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx index dc5f4b9d8853..bd139d75799c 100644 --- a/sw/source/core/edit/edfcol.cxx +++ b/sw/source/core/edit/edfcol.cxx @@ -60,6 +60,8 @@ #include <pagefrm.hxx> #include <sfx2/watermarkitem.hxx> +#define WATERMARK_NAME "PowerPlusWaterMarkObject" + namespace { @@ -114,8 +116,8 @@ bool lcl_hasField(const uno::Reference<text::XText>& xText, const OUString& rSer return false; } -/// Search for a frame named rShapeName of type rServiceName in xText. -uno::Reference<drawing::XShape> lcl_getWatermark(const uno::Reference<text::XText>& xText, const OUString& rServiceName, const OUString& rShapeName) +/// Search for a frame with WATERMARK_NAME in name of type rServiceName in xText. Returns found name in rShapeName. +uno::Reference<drawing::XShape> lcl_getWatermark(const uno::Reference<text::XText>& xText, const OUString& rServiceName, OUString& rShapeName) { uno::Reference<container::XEnumerationAccess> xParagraphEnumerationAccess(xText, uno::UNO_QUERY); uno::Reference<container::XEnumeration> xParagraphs = xParagraphEnumerationAccess->createEnumeration(); @@ -144,9 +146,12 @@ uno::Reference<drawing::XShape> lcl_getWatermark(const uno::Reference<text::XTex continue; uno::Reference<container::XNamed> xNamed(xWatermark, uno::UNO_QUERY); - if (xNamed->getName() != rShapeName) + + if (!xNamed->getName().match(WATERMARK_NAME)) continue; + rShapeName = xNamed->getName(); + uno::Reference<drawing::XShape> xShape(xWatermark, uno::UNO_QUERY); return xShape; } @@ -283,7 +288,7 @@ SfxWatermarkItem SwEditShell::GetWatermark() xPageStyle->getPropertyValue(UNO_NAME_HEADER_TEXT) >>= xHeaderText; OUString aShapeServiceName = "com.sun.star.drawing.CustomShape"; - static const OUString sWatermark = SfxClassificationHelper::PROP_PREFIX_INTELLECTUALPROPERTY() + SfxClassificationHelper::PROP_DOCWATERMARK(); + OUString sWatermark = ""; uno::Reference<drawing::XShape> xWatermark = lcl_getWatermark(xHeaderText, aShapeServiceName, sWatermark); if (xWatermark.is()) @@ -349,7 +354,7 @@ void SwEditShell::SetWatermark(const SfxWatermarkItem& rWatermark) xPageStyle->getPropertyValue(UNO_NAME_HEADER_TEXT) >>= xHeaderText; OUString aShapeServiceName = "com.sun.star.drawing.CustomShape"; - static const OUString sWatermark = SfxClassificationHelper::PROP_PREFIX_INTELLECTUALPROPERTY() + SfxClassificationHelper::PROP_DOCWATERMARK(); + OUString sWatermark = WATERMARK_NAME; uno::Reference<drawing::XShape> xWatermark = lcl_getWatermark(xHeaderText, aShapeServiceName, sWatermark); bool bDeleteWatermark = rWatermark.GetText().isEmpty(); @@ -490,7 +495,7 @@ void SwEditShell::SetWatermark(const SfxWatermarkItem& rWatermark) xPropertySet->setPropertyValue("CustomShapeGeometry", uno::makeAny(comphelper::containerToSequence(aGeomPropVec))); uno::Reference<container::XNamed> xNamed(xShape, uno::UNO_QUERY); - xNamed->setName(SfxClassificationHelper::PROP_PREFIX_INTELLECTUALPROPERTY() + SfxClassificationHelper::PROP_DOCWATERMARK()); + xNamed->setName(sWatermark); xLockable->removeActionLock(); } } commit 8421372dd3c25c7852de388e3c8cc4a8b65dc2de Author: Szymon KÅos <szymon.k...@collabora.com> Date: Thu May 25 15:12:46 2017 +0200 Watermark: updated Put and QueryValue Change-Id: Ica65be783130b1981093204edd03dc793a16343b Reviewed-on: https://gerrit.libreoffice.org/38027 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Maxim Monastirsky <momonas...@gmail.com> diff --git a/sfx2/source/doc/watermarkitem.cxx b/sfx2/source/doc/watermarkitem.cxx index ebb794fcd73e..f54745694557 100644 --- a/sfx2/source/doc/watermarkitem.cxx +++ b/sfx2/source/doc/watermarkitem.cxx @@ -9,6 +9,7 @@ #include <sfx2/watermarkitem.hxx> #include <sfx2/sfxsids.hrc> +#include <comphelper/propertysequence.hxx> SfxWatermarkItem::SfxWatermarkItem() : SfxPoolItem( SID_WATERMARK ) @@ -52,26 +53,36 @@ SfxPoolItem* SfxWatermarkItem::Clone( SfxItemPool *) const bool SfxWatermarkItem::QueryValue( css::uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) const { - rVal <<= m_aText; - rVal <<= m_aFont; - rVal <<= m_nAngle; - rVal <<= m_nTransparency; - rVal <<= m_nColor; + rVal <<= comphelper::InitPropertySequence( { + { "Text", css::uno::makeAny( m_aText ) }, + { "Font", css::uno::makeAny( m_aFont ) }, + { "Angle", css::uno::makeAny( m_nAngle ) }, + { "Transparency", css::uno::makeAny( m_nTransparency ) }, + { "Color", css::uno::makeAny( m_nColor ) }, + } ); return true; } bool SfxWatermarkItem::PutValue( const css::uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) { - OUString aText; + css::uno::Sequence<css::beans::PropertyValue> aSequence; - if ( rVal >>= aText ) + if ( rVal >>= aSequence ) { - m_aText = aText; - rVal >>= m_aFont; - rVal >>= m_nAngle; - rVal >>= m_nTransparency; - rVal >>= m_nColor; + for(const auto& aEntry : aSequence) + { + if(aEntry.Name == "Text") + aEntry.Value >>= m_aText; + if(aEntry.Name == "Font") + aEntry.Value >>= m_aFont; + if(aEntry.Name == "Angle") + aEntry.Value >>= m_nAngle; + if(aEntry.Name == "Transparency") + aEntry.Value >>= m_nTransparency; + if(aEntry.Name == "Color") + aEntry.Value >>= m_nColor; + } return true; } commit 10c4276c2c8d7a9b6a5243a0d1d7a00ed5b882a0 Author: Szymon KÅos <szymon.k...@collabora.com> Date: Wed May 24 12:59:26 2017 +0200 tdf#108040 Don't turn on header to check if Watermark exist Change-Id: Ieaf42384248deb283f71743f68c059b384abaa1a diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx index df0dcfabb059..dc5f4b9d8853 100644 --- a/sw/source/core/edit/edfcol.cxx +++ b/sw/source/core/edit/edfcol.cxx @@ -277,7 +277,7 @@ SfxWatermarkItem SwEditShell::GetWatermark() bool bHeaderIsOn = false; xPageStyle->getPropertyValue(UNO_NAME_HEADER_IS_ON) >>= bHeaderIsOn; if (!bHeaderIsOn) - xPageStyle->setPropertyValue(UNO_NAME_HEADER_IS_ON, uno::makeAny(true)); + return SfxWatermarkItem(); uno::Reference<text::XText> xHeaderText; xPageStyle->getPropertyValue(UNO_NAME_HEADER_TEXT) >>= xHeaderText; commit e54eb23ac824d3f08cd21f2518c153d255200f9d Author: Szymon KÅos <szymon.k...@collabora.com> Date: Tue May 23 13:40:24 2017 +0200 Watermark: read angle value Change-Id: Ib6b98c58b1251c27476cbbbd03a2f7ed97e68c45 Reviewed-on: https://gerrit.libreoffice.org/37947 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Szymon KÅos <szymon.k...@collabora.com> diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx index 4f1967dc9648..df0dcfabb059 100644 --- a/sw/source/core/edit/edfcol.cxx +++ b/sw/source/core/edit/edfcol.cxx @@ -294,6 +294,7 @@ SfxWatermarkItem SwEditShell::GetWatermark() sal_uInt32 nColor; sal_Int16 nTransparency; OUString aFont; + drawing::HomogenMatrix3 aMatrix; aItem.SetText(xTextRange->getString()); @@ -301,7 +302,14 @@ SfxWatermarkItem SwEditShell::GetWatermark() aItem.SetFont(aFont); if (xPropertySet->getPropertyValue(UNO_NAME_FILLCOLOR) >>= nColor) aItem.SetColor(nColor); - // TODO: aItem.SetAngle(nAngle); + if (xPropertySet->getPropertyValue("Transformation") >>= aMatrix) + { + double y = aMatrix.Line2.Column1; + double x = aMatrix.Line1.Column1; + double nRad = atan2(y, x) * -1; + double nDeg = nRad * 180.0 / F_PI; + aItem.SetAngle(nDeg); + } if (xPropertySet->getPropertyValue(UNO_NAME_FILL_TRANSPARENCE) >>= nTransparency) aItem.SetTransparency(nTransparency); @@ -347,21 +355,28 @@ void SwEditShell::SetWatermark(const SfxWatermarkItem& rWatermark) bool bDeleteWatermark = rWatermark.GetText().isEmpty(); if (xWatermark.is()) { + drawing::HomogenMatrix3 aMatrix; sal_uInt32 nColor = 0xc0c0c0; sal_Int16 nTransparency = 50; + sal_Int16 nAngle = 45; OUString aFont = ""; uno::Reference<beans::XPropertySet> xPropertySet(xWatermark, uno::UNO_QUERY); xPropertySet->getPropertyValue(UNO_NAME_CHAR_FONT_NAME) >>= aFont; xPropertySet->getPropertyValue(UNO_NAME_FILLCOLOR) >>= nColor; - // TODO: Angle xPropertySet->getPropertyValue(UNO_NAME_FILL_TRANSPARENCE) >>= nTransparency; + xPropertySet->getPropertyValue("Transformation") >>= aMatrix; + double y = aMatrix.Line2.Column1; + double x = aMatrix.Line1.Column1; + double nRad = atan2(y, x) * -1; + nAngle = nRad * 180.0 / F_PI; // If the header already contains a watermark, see if it its text is up to date. uno::Reference<text::XTextRange> xTextRange(xWatermark, uno::UNO_QUERY); if (xTextRange->getString() != rWatermark.GetText() || aFont != rWatermark.GetFont() || nColor != rWatermark.GetColor() + || nAngle != rWatermark.GetAngle() || nTransparency != rWatermark.GetTransparency() || bDeleteWatermark) { commit c14fcaa5e8d4d3693e18ea8c60ddf8dde5674da3 Author: Szymon KÅos <szymon.k...@collabora.com> Date: Tue May 23 11:35:30 2017 +0200 Watermark: move to the insert menu Change-Id: I6058236434de00cddec1340613e83c10acc4df2a diff --git a/sw/uiconfig/swriter/menubar/menubar.xml b/sw/uiconfig/swriter/menubar/menubar.xml index b91238f96df0..a9474f441cb7 100644 --- a/sw/uiconfig/swriter/menubar/menubar.xml +++ b/sw/uiconfig/swriter/menubar/menubar.xml @@ -268,6 +268,7 @@ </menu:menupopup> </menu:menu> <menu:menuitem menu:id=".uno:FontworkGalleryFloater"/> + <menu:menuitem menu:id=".uno:Watermark"/> <menu:menuseparator/> <menu:menuitem menu:id=".uno:DrawText"/> <menu:menuitem menu:id=".uno:InsertAnnotation"/> diff --git a/sw/uiconfig/swriter/toolbar/classificationbar.xml b/sw/uiconfig/swriter/toolbar/classificationbar.xml index 01981333a46e..3ee34071e040 100644 --- a/sw/uiconfig/swriter/toolbar/classificationbar.xml +++ b/sw/uiconfig/swriter/toolbar/classificationbar.xml @@ -9,5 +9,4 @@ --> <toolbar:toolbar xmlns:toolbar="http://openoffice.org/2001/toolbar" xmlns:xlink="http://www.w3.org/1999/xlink" toolbar:id="toolbar"> <toolbar:toolbaritem xlink:href=".uno:ClassificationApply"/> - <toolbar:toolbaritem xlink:href=".uno:Watermark"/> </toolbar:toolbar> commit eb4f3c80ed695a7f0452b3c5c313750c51c962a5 Author: Szymon KÅos <szymon.k...@collabora.com> Date: Tue May 23 11:29:43 2017 +0200 Watermark: remove enable checkbox Change-Id: Ic18b85070bf6c5c3e9678859a87cb9f44411533b diff --git a/sw/source/uibase/dialog/watermarkdialog.cxx b/sw/source/uibase/dialog/watermarkdialog.cxx index 1246eabce4cc..6b993d22caf1 100644 --- a/sw/source/uibase/dialog/watermarkdialog.cxx +++ b/sw/source/uibase/dialog/watermarkdialog.cxx @@ -23,8 +23,6 @@ SwWatermarkDialog::SwWatermarkDialog( vcl::Window* pParent, SfxBindings& rBindin : ModelessDialog( pParent, "WatermarkDialog", "modules/swriter/ui/watermarkdialog.ui" ) , m_rBindings( rBindings ) { - get( m_pTextGrid, "TextGrid" ); - get( m_pEnableWatermarkCB, "EnableWatermarkCB" ); get( m_pTextInput, "TextInput" ); get( m_pOKButton, "ok" ); get( m_pFont, "FontBox" ); @@ -47,8 +45,6 @@ void SwWatermarkDialog::dispose() m_pAngle.clear(); m_pTransparency.clear(); m_pColor.clear(); - m_pTextGrid.clear(); - m_pEnableWatermarkCB.clear(); m_pTextInput.clear(); m_pOKButton.clear(); @@ -70,7 +66,6 @@ void SwWatermarkDialog::InitFields() m_pFont->Fill( pFontList ); - m_pEnableWatermarkCB->SetClickHdl( LINK( this, SwWatermarkDialog, CheckBoxHdl ) ); m_pOKButton->SetClickHdl( LINK( this, SwWatermarkDialog, OKButtonHdl ) ); // Get watermark properties @@ -81,7 +76,6 @@ void SwWatermarkDialog::InitFields() { const SfxWatermarkItem* pWatermark = static_cast<const SfxWatermarkItem*>( pItem ); OUString sText = pWatermark->GetText(); - m_pEnableWatermarkCB->Check( !sText.isEmpty() ); m_pTextInput->SetText( sText ); m_pFont->SelectEntryPos( m_pFont->GetEntryPos( pWatermark->GetFont() ) ); m_pAngle->SetValue( pWatermark->GetAngle() ); @@ -90,24 +84,9 @@ void SwWatermarkDialog::InitFields() } } -void SwWatermarkDialog::Update() -{ - if( m_pEnableWatermarkCB->IsChecked() ) - m_pTextGrid->Enable(); - else - m_pTextGrid->Disable(); -} - -IMPL_LINK_NOARG( SwWatermarkDialog, CheckBoxHdl, Button*, void ) -{ - Update(); -} - IMPL_LINK_NOARG( SwWatermarkDialog, OKButtonHdl, Button*, void ) { - OUString sText = ""; - if( m_pEnableWatermarkCB->IsChecked() ) - sText = m_pTextInput->GetText(); + OUString sText = m_pTextInput->GetText(); css::uno::Sequence<css::beans::PropertyValue> aPropertyValues( comphelper::InitPropertySequence( { diff --git a/sw/source/uibase/inc/watermarkdialog.hxx b/sw/source/uibase/inc/watermarkdialog.hxx index 7f59fe0a2bb7..b443fbce797d 100644 --- a/sw/source/uibase/inc/watermarkdialog.hxx +++ b/sw/source/uibase/inc/watermarkdialog.hxx @@ -23,16 +23,12 @@ public: virtual void dispose() override; void InitFields(); - void Update(); private: - DECL_LINK( CheckBoxHdl, Button*, void ); DECL_LINK( OKButtonHdl, Button*, void ); SfxBindings& m_rBindings; - VclPtr<VclGrid> m_pTextGrid; - VclPtr<CheckBox> m_pEnableWatermarkCB; VclPtr<Edit> m_pTextInput; VclPtr<PushButton> m_pOKButton; VclPtr<FontNameBox> m_pFont; diff --git a/sw/uiconfig/swriter/ui/watermarkdialog.ui b/sw/uiconfig/swriter/ui/watermarkdialog.ui index 316cd0c5d8bc..2edb38bf7f3a 100644 --- a/sw/uiconfig/swriter/ui/watermarkdialog.ui +++ b/sw/uiconfig/swriter/ui/watermarkdialog.ui @@ -62,7 +62,7 @@ <property name="expand">False</property> <property name="fill">True</property> <property name="pack_type">end</property> - <property name="position">0</property> + <property name="position">1</property> </packing> </child> <child> @@ -72,21 +72,6 @@ <property name="orientation">vertical</property> <property name="spacing">6</property> <child> - <object class="GtkCheckButton" id="EnableWatermarkCB"> - <property name="label" translatable="yes">Insert watermark</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="xalign">0</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> <object class="GtkGrid" id="TextGrid"> <property name="visible">True</property> <property name="can_focus">False</property> @@ -210,14 +195,14 @@ <packing> <property name="expand">True</property> <property name="fill">True</property> - <property name="position">1</property> + <property name="position">0</property> </packing> </child> </object> <packing> <property name="expand">True</property> <property name="fill">True</property> - <property name="position">1</property> + <property name="position">0</property> </packing> </child> </object> commit 489597d339af14a6403ee079bea35908112720ec Author: Szymon KÅos <szymon.k...@collabora.com> Date: Fri May 19 00:18:15 2017 +0200 Watermark: extended configuration * it is possible to set font family, color, angle and transparency Change-Id: Idea2fb9ee748394bb3d706fa790e109238584cdb Reviewed-on: https://gerrit.libreoffice.org/37793 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Szymon KÅos <szymon.k...@collabora.com> diff --git a/include/sfx2/sfxsids.hrc b/include/sfx2/sfxsids.hrc index dbd8ab6ef39d..cfc59403d198 100644 --- a/include/sfx2/sfxsids.hrc +++ b/include/sfx2/sfxsids.hrc @@ -344,7 +344,10 @@ #define SID_INSERT_FLOATINGFRAME (SID_SFX_START + 563) #define SID_CLASSIFICATION_APPLY (SID_SFX_START + 672) #define SID_WATERMARK (SID_SFX_START + 676) -// FREE (SID_SFX_START + 677) +#define SID_WATERMARK_FONT (SID_SFX_START + 677) +#define SID_WATERMARK_TRANSPARENCY (SID_SFX_START + 805) +#define SID_WATERMARK_COLOR (SID_SFX_START + 806) +#define SID_WATERMARK_ANGLE (SID_SFX_START + 807) #define SID_HYPERLINK_DIALOG (SID_SFX_START + 678) @@ -411,9 +414,6 @@ #define SID_PASTE_ONLY_TEXT (SID_SFX_START + 802) #define SID_PASTE_ONLY_FORMULA (SID_SFX_START + 803) #define SID_PASTE_ONLY_VALUE (SID_SFX_START + 804) - // FREE: SID_SFX_START + 805 - // FREE: SID_SFX_START + 806 - // FREE: SID_SFX_START + 807 // FREE: SID_SFX_START + 808 // FREE: SID_SFX_START + 809 // FREE: SID_SFX_START + 810 diff --git a/include/sfx2/watermarkitem.hxx b/include/sfx2/watermarkitem.hxx index 760aab3b0285..9fd7a91415a4 100644 --- a/include/sfx2/watermarkitem.hxx +++ b/include/sfx2/watermarkitem.hxx @@ -17,17 +17,29 @@ class SFX2_DLLPUBLIC SfxWatermarkItem: public SfxPoolItem public: static SfxPoolItem* CreateDefault(); SfxWatermarkItem(); - SfxWatermarkItem( sal_uInt16 nWhich, const OUString &rText ); SfxWatermarkItem( const SfxWatermarkItem& ); virtual SfxPoolItem* Clone( SfxItemPool *pPool = nullptr ) const override; virtual bool operator==( const SfxPoolItem& ) const override; virtual bool QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId = 0 ) const override; virtual bool PutValue( const css::uno::Any& rVal, sal_uInt8 nMemberId ) override; - const OUString& GetText() const { return m_aText; } + const OUString GetText() const { return m_aText; } + void SetText(const OUString& aText) { m_aText = aText; } + const OUString GetFont() const { return m_aFont; } + void SetFont(const OUString& aFont) { m_aFont = aFont; } + sal_Int16 GetAngle() const { return m_nAngle; } + void SetAngle(const sal_Int16 nAngle) { m_nAngle = nAngle; } + sal_Int16 GetTransparency() const { return m_nTransparency; } + void SetTransparency(const sal_Int16 nTransparency) { m_nTransparency = nTransparency; } + sal_uInt32 GetColor() const { return m_nColor; } + void SetColor(const sal_uInt32 nColor) { m_nColor = nColor; } private: OUString m_aText; + OUString m_aFont; + sal_Int16 m_nAngle; + sal_Int16 m_nTransparency; + sal_uInt32 m_nColor; }; #endif diff --git a/sfx2/sdi/sfx.sdi b/sfx2/sdi/sfx.sdi index 88735bbf9088..95d16d1588ee 100644 --- a/sfx2/sdi/sfx.sdi +++ b/sfx2/sdi/sfx.sdi @@ -4458,7 +4458,10 @@ SfxVoidItem ClassificationApply SID_CLASSIFICATION_APPLY ] SfxWatermarkItem Watermark SID_WATERMARK -(SfxStringItem Text SID_WATERMARK) +(SfxStringItem Text SID_WATERMARK, SfxStringItem Font SID_WATERMARK_FONT, + SfxInt16Item Angle SID_WATERMARK_ANGLE, SfxInt16Item Transparency SID_WATERMARK_TRANSPARENCY, + SfxUInt32Item Color SID_WATERMARK_COLOR +) [ AutoUpdate = FALSE, FastCall = FALSE, diff --git a/sfx2/source/doc/watermarkitem.cxx b/sfx2/source/doc/watermarkitem.cxx index 00c31f25d823..ebb794fcd73e 100644 --- a/sfx2/source/doc/watermarkitem.cxx +++ b/sfx2/source/doc/watermarkitem.cxx @@ -13,6 +13,10 @@ SfxWatermarkItem::SfxWatermarkItem() : SfxPoolItem( SID_WATERMARK ) , m_aText( "" ) +, m_aFont( "Liberation Sans" ) +, m_nAngle( 45 ) +, m_nTransparency( 50 ) +, m_nColor( 0xc0c0c0 ) { } @@ -21,22 +25,24 @@ SfxPoolItem* SfxWatermarkItem::CreateDefault() return new SfxWatermarkItem(); } -SfxWatermarkItem::SfxWatermarkItem( sal_uInt16 nWhichId, const OUString& rText ) -: SfxPoolItem( nWhichId ) -, m_aText( rText ) -{ -} - SfxWatermarkItem::SfxWatermarkItem( const SfxWatermarkItem& rCopy ) : SfxPoolItem( rCopy ) , m_aText( rCopy.m_aText ) +, m_aFont( rCopy.m_aFont ) +, m_nAngle( rCopy.m_nAngle ) +, m_nTransparency( rCopy.m_nTransparency ) +, m_nColor( rCopy.m_nColor ) { } bool SfxWatermarkItem::operator==( const SfxPoolItem& rCmp ) const { return ( SfxPoolItem::operator==( rCmp ) && - m_aText == static_cast<const SfxWatermarkItem&>(rCmp).m_aText ); + m_aText == static_cast<const SfxWatermarkItem&>(rCmp).m_aText && + m_aFont == static_cast<const SfxWatermarkItem&>(rCmp).m_aFont && + m_nAngle == static_cast<const SfxWatermarkItem&>(rCmp).m_nAngle && + m_nTransparency == static_cast<const SfxWatermarkItem&>(rCmp).m_nTransparency && + m_nColor == static_cast<const SfxWatermarkItem&>(rCmp).m_nColor ); } SfxPoolItem* SfxWatermarkItem::Clone( SfxItemPool *) const @@ -47,6 +53,10 @@ SfxPoolItem* SfxWatermarkItem::Clone( SfxItemPool *) const bool SfxWatermarkItem::QueryValue( css::uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) const { rVal <<= m_aText; + rVal <<= m_aFont; + rVal <<= m_nAngle; + rVal <<= m_nTransparency; + rVal <<= m_nColor; return true; } @@ -58,6 +68,10 @@ bool SfxWatermarkItem::PutValue( const css::uno::Any& rVal, sal_uInt8 /*nMemberI if ( rVal >>= aText ) { m_aText = aText; + rVal >>= m_aFont; + rVal >>= m_nAngle; + rVal >>= m_nTransparency; + rVal >>= m_nColor; return true; } diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx index db7a5346a586..e031303b6aae 100644 --- a/sw/inc/editsh.hxx +++ b/sw/inc/editsh.hxx @@ -367,7 +367,7 @@ public: void SetClassification(const OUString& rName, SfxClassificationPolicyType eType); SfxWatermarkItem GetWatermark(); - void SetWatermark(const OUString& rText); + void SetWatermark(const SfxWatermarkItem& rText); void Insert2(SwField&, const bool bForceExpandHints); diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx index 029eb57be727..4f1967dc9648 100644 --- a/sw/source/core/edit/edfcol.cxx +++ b/sw/source/core/edit/edfcol.cxx @@ -229,7 +229,9 @@ void SwEditShell::SetClassification(const OUString& rName, SfxClassificationPoli } } - SetWatermark(aWatermark); + SfxWatermarkItem aWatermarkItem; + aWatermarkItem.SetText(aWatermark); + SetWatermark(aWatermarkItem); } if (bFooterIsNeeded) @@ -260,7 +262,7 @@ SfxWatermarkItem SwEditShell::GetWatermark() { SwDocShell* pDocShell = GetDoc()->GetDocShell(); if (!pDocShell) - return SfxWatermarkItem(SID_WATERMARK, ""); + return SfxWatermarkItem(); uno::Reference<frame::XModel> xModel = pDocShell->GetBaseModel(); uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(xModel, uno::UNO_QUERY); @@ -286,14 +288,30 @@ SfxWatermarkItem SwEditShell::GetWatermark() if (xWatermark.is()) { + SfxWatermarkItem aItem; uno::Reference<text::XTextRange> xTextRange(xWatermark, uno::UNO_QUERY); - return SfxWatermarkItem(SID_WATERMARK, xTextRange->getString()); + uno::Reference<beans::XPropertySet> xPropertySet(xWatermark, uno::UNO_QUERY); + sal_uInt32 nColor; + sal_Int16 nTransparency; + OUString aFont; + + aItem.SetText(xTextRange->getString()); + + if (xPropertySet->getPropertyValue(UNO_NAME_CHAR_FONT_NAME) >>= aFont) + aItem.SetFont(aFont); + if (xPropertySet->getPropertyValue(UNO_NAME_FILLCOLOR) >>= nColor) + aItem.SetColor(nColor); + // TODO: aItem.SetAngle(nAngle); + if (xPropertySet->getPropertyValue(UNO_NAME_FILL_TRANSPARENCE) >>= nTransparency) + aItem.SetTransparency(nTransparency); + + return aItem; } } - return SfxWatermarkItem(SID_WATERMARK, ""); + return SfxWatermarkItem(); } -void SwEditShell::SetWatermark(const OUString& rWatermark) +void SwEditShell::SetWatermark(const SfxWatermarkItem& rWatermark) { SwDocShell* pDocShell = GetDoc()->GetDocShell(); if (!pDocShell) @@ -326,12 +344,26 @@ void SwEditShell::SetWatermark(const OUString& rWatermark) static const OUString sWatermark = SfxClassificationHelper::PROP_PREFIX_INTELLECTUALPROPERTY() + SfxClassificationHelper::PROP_DOCWATERMARK(); uno::Reference<drawing::XShape> xWatermark = lcl_getWatermark(xHeaderText, aShapeServiceName, sWatermark); - bool bDeleteWatermark = rWatermark.isEmpty(); + bool bDeleteWatermark = rWatermark.GetText().isEmpty(); if (xWatermark.is()) { + sal_uInt32 nColor = 0xc0c0c0; + sal_Int16 nTransparency = 50; + OUString aFont = ""; + + uno::Reference<beans::XPropertySet> xPropertySet(xWatermark, uno::UNO_QUERY); + xPropertySet->getPropertyValue(UNO_NAME_CHAR_FONT_NAME) >>= aFont; + xPropertySet->getPropertyValue(UNO_NAME_FILLCOLOR) >>= nColor; + // TODO: Angle + xPropertySet->getPropertyValue(UNO_NAME_FILL_TRANSPARENCE) >>= nTransparency; + // If the header already contains a watermark, see if it its text is up to date. uno::Reference<text::XTextRange> xTextRange(xWatermark, uno::UNO_QUERY); - if (xTextRange->getString() != rWatermark || bDeleteWatermark) + if (xTextRange->getString() != rWatermark.GetText() + || aFont != rWatermark.GetFont() + || nColor != rWatermark.GetColor() + || nTransparency != rWatermark.GetTransparency() + || bDeleteWatermark) { // No: delete it and we'll insert a replacement. uno::Reference<lang::XComponent> xComponent(xWatermark, uno::UNO_QUERY); @@ -342,12 +374,18 @@ void SwEditShell::SetWatermark(const OUString& rWatermark) if (!xWatermark.is() && !bDeleteWatermark) { + OUString sFont = rWatermark.GetFont(); + sal_Int16 nAngle = rWatermark.GetAngle(); + sal_Int16 nTransparency = rWatermark.GetTransparency(); + sal_uInt32 nColor = rWatermark.GetColor(); + // Calc the ratio. double fRatio = 0; OutputDevice* pOut = Application::GetDefaultDevice(); vcl::Font aFont(pOut->GetFont()); + aFont.SetFamilyName(sFont); fRatio = aFont.GetFontSize().Height(); - fRatio /= pOut->GetTextWidth(rWatermark); + fRatio /= pOut->GetTextWidth(rWatermark.GetText()); // Calc the size. sal_Int32 nWidth = 0; @@ -378,7 +416,7 @@ void SwEditShell::SetWatermark(const OUString& rWatermark) basegfx::B2DHomMatrix aTransformation; aTransformation.identity(); aTransformation.scale(nWidth, nHeight); - aTransformation.rotate(F_PI180 * -45); + aTransformation.rotate(F_PI180 * -1 * nAngle); drawing::HomogenMatrix3 aMatrix; aMatrix.Line1.Column1 = aTransformation.get(0, 0); aMatrix.Line1.Column2 = aTransformation.get(0, 1); @@ -397,9 +435,9 @@ void SwEditShell::SetWatermark(const OUString& rWatermark) // The remaining properties have to be set after the shape is inserted: do that in one batch to avoid flickering. uno::Reference<document::XActionLockable> xLockable(xShape, uno::UNO_QUERY); xLockable->addActionLock(); - xPropertySet->setPropertyValue(UNO_NAME_FILLCOLOR, uno::makeAny(static_cast<sal_Int32>(0xc0c0c0))); + xPropertySet->setPropertyValue(UNO_NAME_FILLCOLOR, uno::makeAny(static_cast<sal_Int32>(nColor))); xPropertySet->setPropertyValue(UNO_NAME_FILLSTYLE, uno::makeAny(drawing::FillStyle_SOLID)); - xPropertySet->setPropertyValue(UNO_NAME_FILL_TRANSPARENCE, uno::makeAny(static_cast<sal_Int16>(50))); + xPropertySet->setPropertyValue(UNO_NAME_FILL_TRANSPARENCE, uno::makeAny(nTransparency)); xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION, uno::makeAny(static_cast<sal_Int16>(text::RelOrientation::PAGE_PRINT_AREA))); xPropertySet->setPropertyValue(UNO_NAME_LINESTYLE, uno::makeAny(drawing::LineStyle_NONE)); xPropertySet->setPropertyValue(UNO_NAME_OPAQUE, uno::makeAny(false)); @@ -407,15 +445,15 @@ void SwEditShell::SetWatermark(const OUString& rWatermark) xPropertySet->setPropertyValue(UNO_NAME_TEXT_AUTOGROWWIDTH, uno::makeAny(false)); xPropertySet->setPropertyValue(UNO_NAME_TEXT_MINFRAMEHEIGHT, uno::makeAny(nHeight)); xPropertySet->setPropertyValue(UNO_NAME_TEXT_MINFRAMEWIDTH, uno::makeAny(nWidth)); - xPropertySet->setPropertyValue(UNO_NAME_TEXT_WRAP, uno::makeAny(text::WrapTextMode_THROUGH)); + xPropertySet->setPropertyValue(UNO_NAME_TEXT_WRAP, uno::makeAny(text::WrapTextMode_THROUGHT)); xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT_RELATION, uno::makeAny(static_cast<sal_Int16>(text::RelOrientation::PAGE_PRINT_AREA))); - xPropertySet->setPropertyValue(UNO_NAME_CHAR_FONT_NAME, uno::makeAny(OUString("Liberation Sans"))); + xPropertySet->setPropertyValue(UNO_NAME_CHAR_FONT_NAME, uno::makeAny(sFont)); xPropertySet->setPropertyValue("Transformation", uno::makeAny(aMatrix)); xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT, uno::makeAny(static_cast<sal_Int16>(text::HoriOrientation::CENTER))); xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT, uno::makeAny(static_cast<sal_Int16>(text::VertOrientation::CENTER))); uno::Reference<text::XTextRange> xTextRange(xShape, uno::UNO_QUERY); - xTextRange->setString(rWatermark); + xTextRange->setString(rWatermark.GetText()); uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(xShape, uno::UNO_QUERY); xDefaulter->createCustomShapeDefaults("fontwork-plain-text"); diff --git a/sw/source/uibase/app/docsh2.cxx b/sw/source/uibase/app/docsh2.cxx index 7268c502230e..55db8a619643 100644 --- a/sw/source/uibase/app/docsh2.cxx +++ b/sw/source/uibase/app/docsh2.cxx @@ -57,6 +57,7 @@ #include <svx/fmshell.hxx> #include <sfx2/linkmgr.hxx> #include <sfx2/classificationhelper.hxx> +#include <sfx2/watermarkitem.hxx> #include <svtools/htmlcfg.hxx> #include <svx/ofaitem.hxx> @@ -1167,8 +1168,19 @@ void SwDocShell::Execute(SfxRequest& rReq) { if (pArgs && pArgs->GetItemState( SID_WATERMARK, false, &pItem ) == SfxItemState::SET) { - OUString aText = static_cast<const SfxStringItem*>( pItem )->GetValue(); - pSh->SetWatermark( aText ); + SfxWatermarkItem aItem; + aItem.SetText( static_cast<const SfxStringItem*>( pItem )->GetValue() ); + + if ( pArgs->GetItemState( SID_WATERMARK_FONT, false, &pItem ) == SfxItemState::SET ) + aItem.SetFont( static_cast<const SfxStringItem*>( pItem )->GetValue() ); + if ( pArgs->GetItemState( SID_WATERMARK_ANGLE, false, &pItem ) == SfxItemState::SET ) + aItem.SetAngle( static_cast<const SfxInt16Item*>( pItem )->GetValue() ); + if ( pArgs->GetItemState( SID_WATERMARK_TRANSPARENCY, false, &pItem ) == SfxItemState::SET ) + aItem.SetTransparency( static_cast<const SfxInt16Item*>( pItem )->GetValue() ); + if ( pArgs->GetItemState( SID_WATERMARK_COLOR, false, &pItem ) == SfxItemState::SET ) + aItem.SetColor( static_cast<const SfxUInt32Item*>( pItem )->GetValue() ); + + pSh->SetWatermark( aItem ); } else { diff --git a/sw/source/uibase/app/docst.cxx b/sw/source/uibase/app/docst.cxx index cffd2eca88ca..6eff974face6 100644 --- a/sw/source/uibase/app/docst.cxx +++ b/sw/source/uibase/app/docst.cxx @@ -276,10 +276,9 @@ void SwDocShell::StateStyleSheet(SfxItemSet& rSet, SwWrtShell* pSh) break; case SID_WATERMARK: { + SfxWatermarkItem aItem = pSh->GetWatermark(); if( pSh ) - rSet.Put(pSh->GetWatermark()); - - rSet.InvalidateItem(nWhich); + rSet.Put(aItem); } break; default: diff --git a/sw/source/uibase/dialog/watermarkdialog.cxx b/sw/source/uibase/dialog/watermarkdialog.cxx index bcc6077e9d03..1246eabce4cc 100644 --- a/sw/source/uibase/dialog/watermarkdialog.cxx +++ b/sw/source/uibase/dialog/watermarkdialog.cxx @@ -10,11 +10,14 @@ #include <watermarkdialog.hxx> #include <comphelper/propertysequence.hxx> #include <comphelper/dispatchcommand.hxx> +#include <editeng/editids.hrc> +#include <editeng/flstitem.hxx> #include <sfx2/sfxsids.hrc> #include <sfx2/bindings.hxx> #include <sfx2/dispatch.hxx> #include <svl/eitem.hxx> #include <sfx2/watermarkitem.hxx> +#include <svtools/ctrltool.hxx> SwWatermarkDialog::SwWatermarkDialog( vcl::Window* pParent, SfxBindings& rBindings ) : ModelessDialog( pParent, "WatermarkDialog", "modules/swriter/ui/watermarkdialog.ui" ) @@ -24,9 +27,10 @@ SwWatermarkDialog::SwWatermarkDialog( vcl::Window* pParent, SfxBindings& rBindin get( m_pEnableWatermarkCB, "EnableWatermarkCB" ); get( m_pTextInput, "TextInput" ); get( m_pOKButton, "ok" ); - - m_pEnableWatermarkCB->SetClickHdl( LINK( this, SwWatermarkDialog, CheckBoxHdl ) ); - m_pOKButton->SetClickHdl( LINK( this, SwWatermarkDialog, OKButtonHdl ) ); + get( m_pFont, "FontBox" ); + get( m_pAngle, "Angle" ); + get( m_pTransparency, "Transparency" ); + get( m_pColor, "Color" ); InitFields(); Update(); @@ -39,6 +43,10 @@ SwWatermarkDialog::~SwWatermarkDialog() void SwWatermarkDialog::dispose() { + m_pFont.clear(); + m_pAngle.clear(); + m_pTransparency.clear(); + m_pColor.clear(); m_pTextGrid.clear(); m_pEnableWatermarkCB.clear(); m_pTextInput.clear(); @@ -49,14 +57,36 @@ void SwWatermarkDialog::dispose() void SwWatermarkDialog::InitFields() { + // Update font list + SfxObjectShell* pDocSh = SfxObjectShell::Current(); + const SfxPoolItem* pFontItem; + const FontList* pFontList = nullptr; + + if ( pDocSh && ( ( pFontItem = pDocSh->GetItem( SID_ATTR_CHAR_FONTLIST ) ) != nullptr ) ) + pFontList = static_cast<const SvxFontListItem*>( pFontItem )->GetFontList(); + + if(!pFontList) + pFontList = new FontList(Application::GetDefaultDevice(), nullptr); + + m_pFont->Fill( pFontList ); + + m_pEnableWatermarkCB->SetClickHdl( LINK( this, SwWatermarkDialog, CheckBoxHdl ) ); + m_pOKButton->SetClickHdl( LINK( this, SwWatermarkDialog, OKButtonHdl ) ); + + // Get watermark properties const SfxPoolItem* pItem; SfxItemState eState = m_rBindings.GetDispatcher()->QueryState( SID_WATERMARK, pItem ); - if( eState >= SfxItemState::DEFAULT && pItem ) + if( eState >= SfxItemState::DEFAULT && pItem && pItem->Which() == SID_WATERMARK) { - OUString sText = static_cast<const SfxWatermarkItem*>( pItem )->GetText(); + const SfxWatermarkItem* pWatermark = static_cast<const SfxWatermarkItem*>( pItem ); + OUString sText = pWatermark->GetText(); m_pEnableWatermarkCB->Check( !sText.isEmpty() ); m_pTextInput->SetText( sText ); + m_pFont->SelectEntryPos( m_pFont->GetEntryPos( pWatermark->GetFont() ) ); + m_pAngle->SetValue( pWatermark->GetAngle() ); + m_pColor->SelectEntry( pWatermark->GetColor() ); + m_pTransparency->SetValue( pWatermark->GetTransparency() ); } } @@ -81,7 +111,11 @@ IMPL_LINK_NOARG( SwWatermarkDialog, OKButtonHdl, Button*, void ) css::uno::Sequence<css::beans::PropertyValue> aPropertyValues( comphelper::InitPropertySequence( { - { "Text", css::uno::makeAny( sText ) } + { "Text", css::uno::makeAny( sText ) }, + { "Font", css::uno::makeAny( m_pFont->GetSelectEntry() ) }, + { "Angle", css::uno::makeAny( static_cast<sal_Int16>( m_pAngle->GetValue() ) ) }, + { "Transparency", css::uno::makeAny( static_cast<sal_Int16>( m_pTransparency->GetValue() ) ) }, + { "Color", css::uno::makeAny( static_cast<sal_uInt32>( m_pColor->GetSelectEntryColor().GetRGBColor() ) ) } } ) ); comphelper::dispatchCommand( ".uno:Watermark", aPropertyValues ); diff --git a/sw/source/uibase/inc/watermarkdialog.hxx b/sw/source/uibase/inc/watermarkdialog.hxx index e1a60b96637d..7f59fe0a2bb7 100644 --- a/sw/source/uibase/inc/watermarkdialog.hxx +++ b/sw/source/uibase/inc/watermarkdialog.hxx @@ -10,7 +10,10 @@ #define INCLUDED_SW_SOURCE_UIBASE_INC_WATERMARKDIALOG_HXX #include <sfx2/bindings.hxx> +#include <vcl/field.hxx> #include <vcl/layout.hxx> +#include <svtools/ctrlbox.hxx> +#include <svx/colorbox.hxx> class SwWatermarkDialog : public ModelessDialog { @@ -32,6 +35,10 @@ private: VclPtr<CheckBox> m_pEnableWatermarkCB; VclPtr<Edit> m_pTextInput; VclPtr<PushButton> m_pOKButton; + VclPtr<FontNameBox> m_pFont; + VclPtr<NumericField> m_pAngle; + VclPtr<NumericField> m_pTransparency; + VclPtr<SvxColorListBox> m_pColor; }; #endif diff --git a/sw/uiconfig/swriter/ui/watermarkdialog.ui b/sw/uiconfig/swriter/ui/watermarkdialog.ui index f4d9b6377440..316cd0c5d8bc 100644 --- a/sw/uiconfig/swriter/ui/watermarkdialog.ui +++ b/sw/uiconfig/swriter/ui/watermarkdialog.ui @@ -2,6 +2,17 @@ <!-- Generated with glade 3.20.0 --> <interface> <requires lib="gtk+" version="3.0"/> + <requires lib="LibreOffice" version="1.0"/> + <object class="GtkAdjustment" id="angle_adj"> + <property name="upper">359</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> + <object class="GtkAdjustment" id="transparenct_adj"> + <property name="upper">100</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> <object class="GtkDialog" id="WatermarkDialog"> <property name="can_focus">False</property> <property name="border_width">6</property> @@ -86,6 +97,7 @@ <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes">Text</property> + <property name="xalign">0</property> </object> <packing> <property name="left_attach">0</property> @@ -103,6 +115,97 @@ <property name="top_attach">0</property> </packing> </child> + <child> + <object class="svtlo-FontNameBox" id="FontBox"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="FontLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Font</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="AngleLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Angle</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="TransparencyLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Transparency</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">3</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="ColorLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Color</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">4</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="Angle"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="adjustment">angle_adj</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">2</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="Transparency"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="adjustment">transparenct_adj</property> + <property name="value">50</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">3</property> + </packing> + </child> + <child> + <object class="svxcorelo-SvxColorListBox" id="Color"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">4</property> + </packing> + </child> </object> <packing> <property name="expand">True</property> @@ -124,10 +227,4 @@ <action-widget response="0">cancel</action-widget> </action-widgets> </object> - <object class="GtkTextBuffer" id="textbuffer1"> - <property name="text" translatable="yes">You did not specify a new name for the attachment.</property> - </object> - <object class="GtkTextBuffer" id="textbuffer2"> - <property name="text" translatable="yes">If you would like to provide one, please type it now.</property> - </object> </interface> commit abf39e521178e3438dc507167e18a24d160b3fd5 Author: Szymon KÅos <szymon.k...@collabora.com> Date: Sun May 14 15:09:02 2017 +0200 Watermark: Insert watermark command * added new command .uno:Watermark * if no arguments are provided the dialog is opened where user can enter the text * with provided Text argument the watermark is created * created SfxWatermarkItem to transfer watermark properties * dialog loads current setings * SetClassification use SetWatermark Change-Id: Ifc1319f5aa7c11bb141f8e4b5b9a5088613021c2 Reviewed-on: https://gerrit.libreoffice.org/37599 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Szymon KÅos <szymon.k...@collabora.com> diff --git a/include/sfx2/sfxsids.hrc b/include/sfx2/sfxsids.hrc index aaa19884c0bc..dbd8ab6ef39d 100644 --- a/include/sfx2/sfxsids.hrc +++ b/include/sfx2/sfxsids.hrc @@ -343,7 +343,7 @@ #define SID_INSERT_OBJECT (SID_SFX_START + 561) #define SID_INSERT_FLOATINGFRAME (SID_SFX_START + 563) #define SID_CLASSIFICATION_APPLY (SID_SFX_START + 672) -// FREE (SID_SFX_START + 676) +#define SID_WATERMARK (SID_SFX_START + 676) // FREE (SID_SFX_START + 677) #define SID_HYPERLINK_DIALOG (SID_SFX_START + 678) diff --git a/include/sfx2/watermarkitem.hxx b/include/sfx2/watermarkitem.hxx new file mode 100644 index 000000000000..760aab3b0285 --- /dev/null +++ b/include/sfx2/watermarkitem.hxx @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#ifndef INCLUDED_SFX2_WATERMARKITEM_HXX +#define INCLUDED_SFX2_WATERMARKITEM_HXX + +#include <sfx2/dllapi.h> +#include <svl/poolitem.hxx> + +class SFX2_DLLPUBLIC SfxWatermarkItem: public SfxPoolItem +{ +public: + static SfxPoolItem* CreateDefault(); + SfxWatermarkItem(); + SfxWatermarkItem( sal_uInt16 nWhich, const OUString &rText ); + SfxWatermarkItem( const SfxWatermarkItem& ); + virtual SfxPoolItem* Clone( SfxItemPool *pPool = nullptr ) const override; + virtual bool operator==( const SfxPoolItem& ) const override; + virtual bool QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId = 0 ) const override; + virtual bool PutValue( const css::uno::Any& rVal, sal_uInt8 nMemberId ) override; + + const OUString& GetText() const { return m_aText; } + +private: + OUString m_aText; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu index 177ab9b26e8d..327a7dcd2ad8 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu @@ -2883,6 +2883,14 @@ <value>1</value> </prop> </node> + <node oor:name=".uno:Watermark" oor:op="replace"> + <prop oor:name="Label" oor:type="xs:string"> + <value xml:lang="en-US">Watermark</value> + </prop> + <prop oor:name="Properties" oor:type="xs:int"> + <value>1</value> + </prop> + </node> </node> </node> </oor:component-data> diff --git a/sfx2/Library_sfx.mk b/sfx2/Library_sfx.mk index 647078f5f500..17fd09f772dc 100644 --- a/sfx2/Library_sfx.mk +++ b/sfx2/Library_sfx.mk @@ -236,6 +236,7 @@ $(eval $(call gb_Library_add_exception_objects,sfx,\ sfx2/source/doc/syspath \ sfx2/source/doc/zoomitem \ sfx2/source/doc/templatedlg \ + sfx2/source/doc/watermarkitem \ sfx2/source/doc/saveastemplatedlg \ sfx2/source/explorer/nochaos \ sfx2/source/inet/inettbc \ diff --git a/sfx2/sdi/sfx.sdi b/sfx2/sdi/sfx.sdi index 0347532228af..88735bbf9088 100644 --- a/sfx2/sdi/sfx.sdi +++ b/sfx2/sdi/sfx.sdi @@ -4457,6 +4457,23 @@ SfxVoidItem ClassificationApply SID_CLASSIFICATION_APPLY GroupId = GID_DOCUMENT; ] +SfxWatermarkItem Watermark SID_WATERMARK +(SfxStringItem Text SID_WATERMARK) +[ + AutoUpdate = FALSE, + FastCall = FALSE, + ReadOnlyDoc = FALSE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + AccelConfig = TRUE, + MenuConfig = TRUE, + ToolBoxConfig = TRUE, + GroupId = GID_DOCUMENT; +] + SfxUInt16Item SwitchViewShell SID_VIEWSHELL [ diff --git a/sfx2/sdi/sfxitems.sdi b/sfx2/sdi/sfxitems.sdi index ab1b3fd067e0..3a45c573ab1e 100644 --- a/sfx2/sdi/sfxitems.sdi +++ b/sfx2/sdi/sfxitems.sdi @@ -34,6 +34,7 @@ item String SfxObjectShellItem //! Dummy item String SfxUsrAnyItem //! Dummy item String SfxUnoFrameItem //! Dummy + item String SfxWatermarkItem //! Dummy struct Point { diff --git a/sfx2/source/doc/watermarkitem.cxx b/sfx2/source/doc/watermarkitem.cxx new file mode 100644 index 000000000000..00c31f25d823 --- /dev/null +++ b/sfx2/source/doc/watermarkitem.cxx @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <sfx2/watermarkitem.hxx> +#include <sfx2/sfxsids.hrc> + +SfxWatermarkItem::SfxWatermarkItem() +: SfxPoolItem( SID_WATERMARK ) +, m_aText( "" ) +{ +} + +SfxPoolItem* SfxWatermarkItem::CreateDefault() +{ + return new SfxWatermarkItem(); +} + +SfxWatermarkItem::SfxWatermarkItem( sal_uInt16 nWhichId, const OUString& rText ) +: SfxPoolItem( nWhichId ) +, m_aText( rText ) +{ +} + +SfxWatermarkItem::SfxWatermarkItem( const SfxWatermarkItem& rCopy ) +: SfxPoolItem( rCopy ) +, m_aText( rCopy.m_aText ) +{ +} + +bool SfxWatermarkItem::operator==( const SfxPoolItem& rCmp ) const +{ + return ( SfxPoolItem::operator==( rCmp ) && + m_aText == static_cast<const SfxWatermarkItem&>(rCmp).m_aText ); +} + +SfxPoolItem* SfxWatermarkItem::Clone( SfxItemPool *) const +{ + return new SfxWatermarkItem(*this); +} + +bool SfxWatermarkItem::QueryValue( css::uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) const +{ + rVal <<= m_aText; + + return true; +} + +bool SfxWatermarkItem::PutValue( const css::uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) +{ + OUString aText; + + if ( rVal >>= aText ) + { + m_aText = aText; + return true; + } + + return false; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk index 811c8c629ef6..2bffd7344fd7 100644 --- a/sw/Library_sw.mk +++ b/sw/Library_sw.mk @@ -588,6 +588,7 @@ $(eval $(call gb_Library_add_exception_objects,sw,\ sw/source/uibase/dialog/regionsw \ sw/source/uibase/dialog/swabstdlg \ sw/source/uibase/dialog/swwrtshitem \ + sw/source/uibase/dialog/watermarkdialog \ sw/source/uibase/dochdl/gloshdl \ sw/source/uibase/dochdl/swdtflvr \ sw/source/uibase/docvw/AnchorOverlayObject \ diff --git a/sw/UIConfig_swriter.mk b/sw/UIConfig_swriter.mk index 2ff017fe3b6a..e480f63f27e5 100644 --- a/sw/UIConfig_swriter.mk +++ b/sw/UIConfig_swriter.mk @@ -266,6 +266,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/swriter,\ sw/uiconfig/swriter/ui/viewoptionspage \ sw/uiconfig/swriter/ui/warndatasourcedialog \ sw/uiconfig/swriter/ui/warnemaildialog \ + sw/uiconfig/swriter/ui/watermarkdialog \ sw/uiconfig/swriter/ui/wordcount \ sw/uiconfig/swriter/ui/wrapdialog \ sw/uiconfig/swriter/ui/wrappage \ diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx index c65d4e5df500..db7a5346a586 100644 --- a/sw/inc/editsh.hxx +++ b/sw/inc/editsh.hxx @@ -54,6 +54,7 @@ class CommandExtTextInputData; class SvNumberFormatter; class SfxPoolItem; class SfxItemSet; +class SfxWatermarkItem; class SvxAutoCorrect; class SwField; @@ -365,6 +366,9 @@ public: void SetClassification(const OUString& rName, SfxClassificationPolicyType eType); + SfxWatermarkItem GetWatermark(); + void SetWatermark(const OUString& rText); + void Insert2(SwField&, const bool bForceExpandHints); void UpdateFields( SwField & ); ///< One single field. diff --git a/sw/sdi/_basesh.sdi b/sw/sdi/_basesh.sdi index 1d3d1ae0f15f..b68ee48d55c3 100644 --- a/sw/sdi/_basesh.sdi +++ b/sw/sdi/_basesh.sdi @@ -372,6 +372,12 @@ interface BaseTextSelection StateMethod = StateStyle ; ] + SID_WATERMARK + [ + ExecMethod = Execute ; + StateMethod = StateStyle ; + ] + //OS: Selection.Escape gibt es zusaetzlich zu Window.Escape FN_ESCAPE // status(final|play|rec) diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx index 5277af00a11b..029eb57be727 100644 --- a/sw/source/core/edit/edfcol.cxx +++ b/sw/source/core/edit/edfcol.cxx @@ -58,6 +58,7 @@ #include <unoprnms.hxx> #include <rootfrm.hxx> #include <pagefrm.hxx> +#include <sfx2/watermarkitem.hxx> namespace { @@ -228,127 +229,7 @@ void SwEditShell::SetClassification(const OUString& rName, SfxClassificationPoli } } - if (bWatermarkIsNeeded || bHadWatermark) - { - OUString aShapeServiceName = "com.sun.star.drawing.CustomShape"; - static const OUString sWatermark = SfxClassificationHelper::PROP_PREFIX_INTELLECTUALPROPERTY() + SfxClassificationHelper::PROP_DOCWATERMARK(); - uno::Reference<drawing::XShape> xWatermark = lcl_getWatermark(xHeaderText, aShapeServiceName, sWatermark); - - bool bDeleteWatermark = bHadWatermark && !bWatermarkIsNeeded; - if (xWatermark.is()) - { - // If the header already contains a watermark, see if it its text is up to date. - uno::Reference<text::XTextRange> xTextRange(xWatermark, uno::UNO_QUERY); - if (xTextRange->getString() != aWatermark || bDeleteWatermark) - { - // No: delete it and we'll insert a replacement. - uno::Reference<lang::XComponent> xComponent(xWatermark, uno::UNO_QUERY); - xComponent->dispose(); - xWatermark.clear(); - } - } - - if (!xWatermark.is() && bWatermarkIsNeeded) - { - // Calc the ratio. - double fRatio = 0; - OutputDevice* pOut = Application::GetDefaultDevice(); - vcl::Font aFont(pOut->GetFont()); - fRatio = aFont.GetFontSize().Height(); - fRatio /= pOut->GetTextWidth(aWatermark); - - // Calc the size. - sal_Int32 nWidth = 0; - awt::Size aSize; - xPageStyle->getPropertyValue(UNO_NAME_SIZE) >>= aSize; - if (aSize.Width < aSize.Height) - { - // Portrait. - sal_Int32 nLeftMargin = 0; - xPageStyle->getPropertyValue(UNO_NAME_LEFT_MARGIN) >>= nLeftMargin; - sal_Int32 nRightMargin = 0; - xPageStyle->getPropertyValue(UNO_NAME_RIGHT_MARGIN) >>= nRightMargin; - nWidth = aSize.Width - nLeftMargin - nRightMargin; - } - else - { - // Landscape. - sal_Int32 nTopMargin = 0; - xPageStyle->getPropertyValue(UNO_NAME_TOP_MARGIN) >>= nTopMargin; - sal_Int32 nBottomMargin = 0; - xPageStyle->getPropertyValue(UNO_NAME_BOTTOM_MARGIN) >>= nBottomMargin; - nWidth = aSize.Height - nTopMargin - nBottomMargin; - } - sal_Int32 nHeight = nWidth * fRatio; - - // Create and insert the shape. - uno::Reference<drawing::XShape> xShape(xMultiServiceFactory->createInstance(aShapeServiceName), uno::UNO_QUERY); - basegfx::B2DHomMatrix aTransformation; - aTransformation.identity(); - aTransformation.scale(nWidth, nHeight); - aTransformation.rotate(F_PI180 * -45); - drawing::HomogenMatrix3 aMatrix; - aMatrix.Line1.Column1 = aTransformation.get(0, 0); - aMatrix.Line1.Column2 = aTransformation.get(0, 1); - aMatrix.Line1.Column3 = aTransformation.get(0, 2); - aMatrix.Line2.Column1 = aTransformation.get(1, 0); - aMatrix.Line2.Column2 = aTransformation.get(1, 1); - aMatrix.Line2.Column3 = aTransformation.get(1, 2); - aMatrix.Line3.Column1 = aTransformation.get(2, 0); - aMatrix.Line3.Column2 = aTransformation.get(2, 1); - aMatrix.Line3.Column3 = aTransformation.get(2, 2); - uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY); - xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, uno::makeAny(text::TextContentAnchorType_AT_CHARACTER)); - uno::Reference<text::XTextContent> xTextContent(xShape, uno::UNO_QUERY); - xHeaderText->insertTextContent(xHeaderText->getEnd(), xTextContent, false); - - // The remaining properties have to be set after the shape is inserted: do that in one batch to avoid flickering. - uno::Reference<document::XActionLockable> xLockable(xShape, uno::UNO_QUERY); - xLockable->addActionLock(); - xPropertySet->setPropertyValue(UNO_NAME_FILLCOLOR, uno::makeAny(static_cast<sal_Int32>(0xc0c0c0))); - xPropertySet->setPropertyValue(UNO_NAME_FILLSTYLE, uno::makeAny(drawing::FillStyle_SOLID)); - xPropertySet->setPropertyValue(UNO_NAME_FILL_TRANSPARENCE, uno::makeAny(static_cast<sal_Int16>(50))); - xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION, uno::makeAny(static_cast<sal_Int16>(text::RelOrientation::PAGE_PRINT_AREA))); - xPropertySet->setPropertyValue(UNO_NAME_LINESTYLE, uno::makeAny(drawing::LineStyle_NONE)); - xPropertySet->setPropertyValue(UNO_NAME_OPAQUE, uno::makeAny(false)); - xPropertySet->setPropertyValue(UNO_NAME_TEXT_AUTOGROWHEIGHT, uno::makeAny(false)); - xPropertySet->setPropertyValue(UNO_NAME_TEXT_AUTOGROWWIDTH, uno::makeAny(false)); - xPropertySet->setPropertyValue(UNO_NAME_TEXT_MINFRAMEHEIGHT, uno::makeAny(nHeight)); - xPropertySet->setPropertyValue(UNO_NAME_TEXT_MINFRAMEWIDTH, uno::makeAny(nWidth)); - xPropertySet->setPropertyValue(UNO_NAME_TEXT_WRAP, uno::makeAny(text::WrapTextMode_THROUGHT)); - xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT_RELATION, uno::makeAny(static_cast<sal_Int16>(text::RelOrientation::PAGE_PRINT_AREA))); - xPropertySet->setPropertyValue(UNO_NAME_CHAR_FONT_NAME, uno::makeAny(OUString("Liberation Sans"))); - xPropertySet->setPropertyValue("Transformation", uno::makeAny(aMatrix)); - xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT, uno::makeAny(static_cast<sal_Int16>(text::HoriOrientation::CENTER))); - xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT, uno::makeAny(static_cast<sal_Int16>(text::VertOrientation::CENTER))); - - uno::Reference<text::XTextRange> xTextRange(xShape, uno::UNO_QUERY); - xTextRange->setString(aWatermark); - - uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(xShape, uno::UNO_QUERY); - xDefaulter->createCustomShapeDefaults("fontwork-plain-text"); - - auto aGeomPropSeq = xPropertySet->getPropertyValue("CustomShapeGeometry").get< uno::Sequence<beans::PropertyValue> >(); - auto aGeomPropVec = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(aGeomPropSeq); - uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence( - { - {"TextPath", uno::makeAny(true)}, - })); - auto it = std::find_if(aGeomPropVec.begin(), aGeomPropVec.end(), [](const beans::PropertyValue& rValue) - { - return rValue.Name == "TextPath"; - }); - if (it == aGeomPropVec.end()) - aGeomPropVec.push_back(comphelper::makePropertyValue("TextPath", aPropertyValues)); - else - it->Value <<= aPropertyValues; - xPropertySet->setPropertyValue("CustomShapeGeometry", uno::makeAny(comphelper::containerToSequence(aGeomPropVec))); - - uno::Reference<container::XNamed> xNamed(xShape, uno::UNO_QUERY); - xNamed->setName(SfxClassificationHelper::PROP_PREFIX_INTELLECTUALPROPERTY() + SfxClassificationHelper::PROP_DOCWATERMARK()); - xLockable->removeActionLock(); - } - } + SetWatermark(aWatermark); } if (bFooterIsNeeded) @@ -375,6 +256,193 @@ void SwEditShell::SetClassification(const OUString& rName, SfxClassificationPoli } } +SfxWatermarkItem SwEditShell::GetWatermark() +{ + SwDocShell* pDocShell = GetDoc()->GetDocShell(); + if (!pDocShell) + return SfxWatermarkItem(SID_WATERMARK, ""); + + uno::Reference<frame::XModel> xModel = pDocShell->GetBaseModel(); + uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(xModel, uno::UNO_QUERY); + uno::Reference<container::XNameAccess> xStyleFamilies(xStyleFamiliesSupplier->getStyleFamilies(), uno::UNO_QUERY); + uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"), uno::UNO_QUERY); + std::set<OUString> aUsedPageStyles = lcl_getUsedPageStyles(this); + for (const OUString& rPageStyleName : aUsedPageStyles) + { + uno::Reference<beans::XPropertySet> xPageStyle(xStyleFamily->getByName(rPageStyleName), uno::UNO_QUERY); + uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(xModel, uno::UNO_QUERY); + + bool bHeaderIsOn = false; + xPageStyle->getPropertyValue(UNO_NAME_HEADER_IS_ON) >>= bHeaderIsOn; + if (!bHeaderIsOn) + xPageStyle->setPropertyValue(UNO_NAME_HEADER_IS_ON, uno::makeAny(true)); + + uno::Reference<text::XText> xHeaderText; + xPageStyle->getPropertyValue(UNO_NAME_HEADER_TEXT) >>= xHeaderText; + + OUString aShapeServiceName = "com.sun.star.drawing.CustomShape"; + static const OUString sWatermark = SfxClassificationHelper::PROP_PREFIX_INTELLECTUALPROPERTY() + SfxClassificationHelper::PROP_DOCWATERMARK(); + uno::Reference<drawing::XShape> xWatermark = lcl_getWatermark(xHeaderText, aShapeServiceName, sWatermark); + + if (xWatermark.is()) + { + uno::Reference<text::XTextRange> xTextRange(xWatermark, uno::UNO_QUERY); + return SfxWatermarkItem(SID_WATERMARK, xTextRange->getString()); + } + } + return SfxWatermarkItem(SID_WATERMARK, ""); +} + +void SwEditShell::SetWatermark(const OUString& rWatermark) +{ + SwDocShell* pDocShell = GetDoc()->GetDocShell(); + if (!pDocShell) + return; + + SfxClassificationHelper aHelper(pDocShell->getDocProperties()); + + uno::Reference<frame::XModel> xModel = pDocShell->GetBaseModel(); + uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(xModel, uno::UNO_QUERY); + uno::Reference<container::XNameAccess> xStyleFamilies(xStyleFamiliesSupplier->getStyleFamilies(), uno::UNO_QUERY); + uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"), uno::UNO_QUERY); + + std::set<OUString> aUsedPageStyles = lcl_getUsedPageStyles(this); + for (const OUString& rPageStyleName : aUsedPageStyles) + { + uno::Reference<beans::XPropertySet> xPageStyle(xStyleFamily->getByName(rPageStyleName), uno::UNO_QUERY); + uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(xModel, uno::UNO_QUERY); + + // If the header is off, turn it on. + bool bHeaderIsOn = false; + xPageStyle->getPropertyValue(UNO_NAME_HEADER_IS_ON) >>= bHeaderIsOn; + if (!bHeaderIsOn) + xPageStyle->setPropertyValue(UNO_NAME_HEADER_IS_ON, uno::makeAny(true)); + + // If the header already contains a document header field, no need to do anything. + uno::Reference<text::XText> xHeaderText; + xPageStyle->getPropertyValue(UNO_NAME_HEADER_TEXT) >>= xHeaderText; + + OUString aShapeServiceName = "com.sun.star.drawing.CustomShape"; + static const OUString sWatermark = SfxClassificationHelper::PROP_PREFIX_INTELLECTUALPROPERTY() + SfxClassificationHelper::PROP_DOCWATERMARK(); + uno::Reference<drawing::XShape> xWatermark = lcl_getWatermark(xHeaderText, aShapeServiceName, sWatermark); + + bool bDeleteWatermark = rWatermark.isEmpty(); + if (xWatermark.is()) + { + // If the header already contains a watermark, see if it its text is up to date. + uno::Reference<text::XTextRange> xTextRange(xWatermark, uno::UNO_QUERY); + if (xTextRange->getString() != rWatermark || bDeleteWatermark) + { + // No: delete it and we'll insert a replacement. + uno::Reference<lang::XComponent> xComponent(xWatermark, uno::UNO_QUERY); + xComponent->dispose(); + xWatermark.clear(); + } + } + + if (!xWatermark.is() && !bDeleteWatermark) + { + // Calc the ratio. + double fRatio = 0; + OutputDevice* pOut = Application::GetDefaultDevice(); + vcl::Font aFont(pOut->GetFont()); + fRatio = aFont.GetFontSize().Height(); + fRatio /= pOut->GetTextWidth(rWatermark); + + // Calc the size. + sal_Int32 nWidth = 0; + awt::Size aSize; + xPageStyle->getPropertyValue(UNO_NAME_SIZE) >>= aSize; + if (aSize.Width < aSize.Height) + { + // Portrait. + sal_Int32 nLeftMargin = 0; + xPageStyle->getPropertyValue(UNO_NAME_LEFT_MARGIN) >>= nLeftMargin; + sal_Int32 nRightMargin = 0; + xPageStyle->getPropertyValue(UNO_NAME_RIGHT_MARGIN) >>= nRightMargin; + nWidth = aSize.Width - nLeftMargin - nRightMargin; + } + else + { + // Landscape. + sal_Int32 nTopMargin = 0; + xPageStyle->getPropertyValue(UNO_NAME_TOP_MARGIN) >>= nTopMargin; + sal_Int32 nBottomMargin = 0; + xPageStyle->getPropertyValue(UNO_NAME_BOTTOM_MARGIN) >>= nBottomMargin; + nWidth = aSize.Height - nTopMargin - nBottomMargin; + } + sal_Int32 nHeight = nWidth * fRatio; + + // Create and insert the shape. + uno::Reference<drawing::XShape> xShape(xMultiServiceFactory->createInstance(aShapeServiceName), uno::UNO_QUERY); + basegfx::B2DHomMatrix aTransformation; + aTransformation.identity(); + aTransformation.scale(nWidth, nHeight); + aTransformation.rotate(F_PI180 * -45); + drawing::HomogenMatrix3 aMatrix; + aMatrix.Line1.Column1 = aTransformation.get(0, 0); + aMatrix.Line1.Column2 = aTransformation.get(0, 1); + aMatrix.Line1.Column3 = aTransformation.get(0, 2); + aMatrix.Line2.Column1 = aTransformation.get(1, 0); + aMatrix.Line2.Column2 = aTransformation.get(1, 1); + aMatrix.Line2.Column3 = aTransformation.get(1, 2); + aMatrix.Line3.Column1 = aTransformation.get(2, 0); + aMatrix.Line3.Column2 = aTransformation.get(2, 1); + aMatrix.Line3.Column3 = aTransformation.get(2, 2); + uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY); + xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, uno::makeAny(text::TextContentAnchorType_AT_CHARACTER)); + uno::Reference<text::XTextContent> xTextContent(xShape, uno::UNO_QUERY); + xHeaderText->insertTextContent(xHeaderText->getEnd(), xTextContent, false); + + // The remaining properties have to be set after the shape is inserted: do that in one batch to avoid flickering. + uno::Reference<document::XActionLockable> xLockable(xShape, uno::UNO_QUERY); + xLockable->addActionLock(); + xPropertySet->setPropertyValue(UNO_NAME_FILLCOLOR, uno::makeAny(static_cast<sal_Int32>(0xc0c0c0))); + xPropertySet->setPropertyValue(UNO_NAME_FILLSTYLE, uno::makeAny(drawing::FillStyle_SOLID)); + xPropertySet->setPropertyValue(UNO_NAME_FILL_TRANSPARENCE, uno::makeAny(static_cast<sal_Int16>(50))); + xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION, uno::makeAny(static_cast<sal_Int16>(text::RelOrientation::PAGE_PRINT_AREA))); + xPropertySet->setPropertyValue(UNO_NAME_LINESTYLE, uno::makeAny(drawing::LineStyle_NONE)); + xPropertySet->setPropertyValue(UNO_NAME_OPAQUE, uno::makeAny(false)); + xPropertySet->setPropertyValue(UNO_NAME_TEXT_AUTOGROWHEIGHT, uno::makeAny(false)); + xPropertySet->setPropertyValue(UNO_NAME_TEXT_AUTOGROWWIDTH, uno::makeAny(false)); + xPropertySet->setPropertyValue(UNO_NAME_TEXT_MINFRAMEHEIGHT, uno::makeAny(nHeight)); + xPropertySet->setPropertyValue(UNO_NAME_TEXT_MINFRAMEWIDTH, uno::makeAny(nWidth)); + xPropertySet->setPropertyValue(UNO_NAME_TEXT_WRAP, uno::makeAny(text::WrapTextMode_THROUGH)); + xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT_RELATION, uno::makeAny(static_cast<sal_Int16>(text::RelOrientation::PAGE_PRINT_AREA))); + xPropertySet->setPropertyValue(UNO_NAME_CHAR_FONT_NAME, uno::makeAny(OUString("Liberation Sans"))); + xPropertySet->setPropertyValue("Transformation", uno::makeAny(aMatrix)); + xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT, uno::makeAny(static_cast<sal_Int16>(text::HoriOrientation::CENTER))); + xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT, uno::makeAny(static_cast<sal_Int16>(text::VertOrientation::CENTER))); + + uno::Reference<text::XTextRange> xTextRange(xShape, uno::UNO_QUERY); + xTextRange->setString(rWatermark); + + uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(xShape, uno::UNO_QUERY); + xDefaulter->createCustomShapeDefaults("fontwork-plain-text"); + + auto aGeomPropSeq = xPropertySet->getPropertyValue("CustomShapeGeometry").get< uno::Sequence<beans::PropertyValue> >(); + auto aGeomPropVec = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(aGeomPropSeq); + uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence( + { + {"TextPath", uno::makeAny(true)}, + })); + auto it = std::find_if(aGeomPropVec.begin(), aGeomPropVec.end(), [](const beans::PropertyValue& rValue) + { + return rValue.Name == "TextPath"; + }); + if (it == aGeomPropVec.end()) + aGeomPropVec.push_back(comphelper::makePropertyValue("TextPath", aPropertyValues)); + else + it->Value <<= aPropertyValues; + xPropertySet->setPropertyValue("CustomShapeGeometry", uno::makeAny(comphelper::containerToSequence(aGeomPropVec))); + + uno::Reference<container::XNamed> xNamed(xShape, uno::UNO_QUERY); + xNamed->setName(SfxClassificationHelper::PROP_PREFIX_INTELLECTUALPROPERTY() + SfxClassificationHelper::PROP_DOCWATERMARK()); + xLockable->removeActionLock(); + } + } +} + // #i62675# void SwEditShell::SetTextFormatColl(SwTextFormatColl *pFormat, const bool bResetListAttrs) diff --git a/sw/source/uibase/app/docsh2.cxx b/sw/source/uibase/app/docsh2.cxx index 4198d18ec46b..7268c502230e 100644 --- a/sw/source/uibase/app/docsh2.cxx +++ b/sw/source/uibase/app/docsh2.cxx @@ -124,6 +124,7 @@ #include "dialog.hrc" #include "swabstdlg.hxx" +#include "watermarkdialog.hxx" #include <ndtxt.hxx> @@ -1159,6 +1160,27 @@ void SwDocShell::Execute(SfxRequest& rReq) SAL_WARN("sw.ui", "missing parameter for SID_CLASSIFICATION_APPLY"); } break; + case SID_WATERMARK: + { + SwWrtShell* pSh = GetWrtShell(); + if ( pSh ) + { + if (pArgs && pArgs->GetItemState( SID_WATERMARK, false, &pItem ) == SfxItemState::SET) + { + OUString aText = static_cast<const SfxStringItem*>( pItem )->GetValue(); + pSh->SetWatermark( aText ); + } + else + { + SfxViewShell* pViewShell = GetView()? GetView(): SfxViewShell::Current(); + SfxBindings& rBindings( pViewShell->GetViewFrame()->GetBindings() ); + ScopedVclPtr<SwWatermarkDialog> pDlg( VclPtr<SwWatermarkDialog>::Create( nullptr, rBindings ) ); + pDlg->Execute(); + pDlg.disposeAndClear(); + } + } + } + break; case SID_NOTEBOOKBAR: { const SfxStringItem* pFile = rReq.GetArg<SfxStringItem>( SID_NOTEBOOKBAR ); diff --git a/sw/source/uibase/app/docst.cxx b/sw/source/uibase/app/docst.cxx index ee02b382a861..cffd2eca88ca 100644 --- a/sw/source/uibase/app/docst.cxx +++ b/sw/source/uibase/app/docst.cxx @@ -85,6 +85,7 @@ #include <list.hxx> #include <paratr.hxx> #include <tblafmt.hxx> +#include <sfx2/watermarkitem.hxx> extern bool g_bNoInterrupt; // in swmodule.cxx @@ -273,6 +274,14 @@ void SwDocShell::StateStyleSheet(SfxItemSet& rSet, SwWrtShell* pSh) // Just trigger ClassificationCategoriesController::statusChanged(). rSet.InvalidateItem(nWhich); break; + case SID_WATERMARK: + { + if( pSh ) + rSet.Put(pSh->GetWatermark()); + + rSet.InvalidateItem(nWhich); + } + break; default: OSL_FAIL("Invalid SlotId"); } diff --git a/sw/source/uibase/dialog/watermarkdialog.cxx b/sw/source/uibase/dialog/watermarkdialog.cxx new file mode 100644 index 000000000000..bcc6077e9d03 --- /dev/null +++ b/sw/source/uibase/dialog/watermarkdialog.cxx @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <watermarkdialog.hxx> +#include <comphelper/propertysequence.hxx> +#include <comphelper/dispatchcommand.hxx> +#include <sfx2/sfxsids.hrc> +#include <sfx2/bindings.hxx> +#include <sfx2/dispatch.hxx> +#include <svl/eitem.hxx> +#include <sfx2/watermarkitem.hxx> + +SwWatermarkDialog::SwWatermarkDialog( vcl::Window* pParent, SfxBindings& rBindings ) +: ModelessDialog( pParent, "WatermarkDialog", "modules/swriter/ui/watermarkdialog.ui" ) +, m_rBindings( rBindings ) +{ + get( m_pTextGrid, "TextGrid" ); + get( m_pEnableWatermarkCB, "EnableWatermarkCB" ); + get( m_pTextInput, "TextInput" ); + get( m_pOKButton, "ok" ); + + m_pEnableWatermarkCB->SetClickHdl( LINK( this, SwWatermarkDialog, CheckBoxHdl ) ); + m_pOKButton->SetClickHdl( LINK( this, SwWatermarkDialog, OKButtonHdl ) ); + + InitFields(); + Update(); +} + +SwWatermarkDialog::~SwWatermarkDialog() +{ + disposeOnce(); +} + +void SwWatermarkDialog::dispose() +{ + m_pTextGrid.clear(); + m_pEnableWatermarkCB.clear(); + m_pTextInput.clear(); + m_pOKButton.clear(); + + ModelessDialog::dispose(); +} + +void SwWatermarkDialog::InitFields() +{ + const SfxPoolItem* pItem; + SfxItemState eState = m_rBindings.GetDispatcher()->QueryState( SID_WATERMARK, pItem ); + + if( eState >= SfxItemState::DEFAULT && pItem ) + { + OUString sText = static_cast<const SfxWatermarkItem*>( pItem )->GetText(); + m_pEnableWatermarkCB->Check( !sText.isEmpty() ); + m_pTextInput->SetText( sText ); + } +} + +void SwWatermarkDialog::Update() +{ + if( m_pEnableWatermarkCB->IsChecked() ) + m_pTextGrid->Enable(); + else + m_pTextGrid->Disable(); +} + +IMPL_LINK_NOARG( SwWatermarkDialog, CheckBoxHdl, Button*, void ) +{ + Update(); +} + +IMPL_LINK_NOARG( SwWatermarkDialog, OKButtonHdl, Button*, void ) +{ + OUString sText = ""; + if( m_pEnableWatermarkCB->IsChecked() ) + sText = m_pTextInput->GetText(); + + css::uno::Sequence<css::beans::PropertyValue> aPropertyValues( comphelper::InitPropertySequence( + { + { "Text", css::uno::makeAny( sText ) } + } ) ); + comphelper::dispatchCommand( ".uno:Watermark", aPropertyValues ); + + Close(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sw/source/uibase/inc/watermarkdialog.hxx b/sw/source/uibase/inc/watermarkdialog.hxx new file mode 100644 index 000000000000..e1a60b96637d --- /dev/null +++ b/sw/source/uibase/inc/watermarkdialog.hxx @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#ifndef INCLUDED_SW_SOURCE_UIBASE_INC_WATERMARKDIALOG_HXX +#define INCLUDED_SW_SOURCE_UIBASE_INC_WATERMARKDIALOG_HXX + +#include <sfx2/bindings.hxx> +#include <vcl/layout.hxx> + +class SwWatermarkDialog : public ModelessDialog +{ +public: + SwWatermarkDialog( vcl::Window* pParent, SfxBindings& rBindings ); + virtual ~SwWatermarkDialog() override; + virtual void dispose() override; + + void InitFields(); + void Update(); + +private: + DECL_LINK( CheckBoxHdl, Button*, void ); + DECL_LINK( OKButtonHdl, Button*, void ); + + SfxBindings& m_rBindings; + + VclPtr<VclGrid> m_pTextGrid; + VclPtr<CheckBox> m_pEnableWatermarkCB; + VclPtr<Edit> m_pTextInput; + VclPtr<PushButton> m_pOKButton; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx index 3127b1f25beb..9da444b3d081 100644 --- a/sw/source/uibase/shells/basesh.cxx +++ b/sw/source/uibase/shells/basesh.cxx @@ -959,6 +959,11 @@ void SwBaseShell::Execute(SfxRequest &rReq) GetView().GetDocShell()->Execute(rReq); } break; + case SID_WATERMARK: + { + GetView().GetDocShell()->Execute(rReq); + } + break; case FN_ESCAPE: GetView().ExecuteSlot(rReq); break; diff --git a/sw/source/uibase/shells/slotadd.cxx b/sw/source/uibase/shells/slotadd.cxx index c0658a329e51..39b4df4b6896 100644 --- a/sw/source/uibase/shells/slotadd.cxx +++ b/sw/source/uibase/shells/slotadd.cxx @@ -40,6 +40,7 @@ #include <svx/pageitem.hxx> #include <svl/srchitem.hxx> #include <sfx2/tplpitem.hxx> +#include <sfx2/watermarkitem.hxx> #include <editeng/wrlmitem.hxx> #include <editeng/protitem.hxx> #include <editeng/opaqitem.hxx> diff --git a/sw/uiconfig/swriter/toolbar/classificationbar.xml b/sw/uiconfig/swriter/toolbar/classificationbar.xml index 3ee34071e040..01981333a46e 100644 --- a/sw/uiconfig/swriter/toolbar/classificationbar.xml +++ b/sw/uiconfig/swriter/toolbar/classificationbar.xml @@ -9,4 +9,5 @@ --> <toolbar:toolbar xmlns:toolbar="http://openoffice.org/2001/toolbar" xmlns:xlink="http://www.w3.org/1999/xlink" toolbar:id="toolbar"> <toolbar:toolbaritem xlink:href=".uno:ClassificationApply"/> + <toolbar:toolbaritem xlink:href=".uno:Watermark"/> </toolbar:toolbar> diff --git a/sw/uiconfig/swriter/ui/watermarkdialog.ui b/sw/uiconfig/swriter/ui/watermarkdialog.ui new file mode 100644 index 000000000000..f4d9b6377440 --- /dev/null +++ b/sw/uiconfig/swriter/ui/watermarkdialog.ui @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.20.0 --> +<interface> + <requires lib="gtk+" version="3.0"/> + <object class="GtkDialog" id="WatermarkDialog"> + <property name="can_focus">False</property> + <property name="border_width">6</property> + <property name="title" translatable="yes">Watermark</property> + <property name="type_hint">dialog</property> + <child internal-child="vbox"> + <object class="GtkBox" id="dialog-vbox1"> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">24</property> + <child internal-child="action_area"> + <object class="GtkButtonBox" id="dialog-action_area1"> + <property name="can_focus">False</property> + <property name="layout_style">end</property> + <child> + <object class="GtkButton" id="ok"> + <property name="label">gtk-ok</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="can_default">True</property> + <property name="has_default">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="cancel"> + <property name="label">gtk-cancel</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack_type">end</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox" id="Box"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <child> + <object class="GtkCheckButton" id="EnableWatermarkCB"> + <property name="label" translatable="yes">Insert watermark</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="xalign">0</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkGrid" id="TextGrid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="row_spacing">6</property> + <property name="column_spacing">6</property> + <child> + <object class="GtkLabel" id="TextLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Text</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="TextInput"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + </packing> ... etc. - the rest is truncated
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits