summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sfx2/sfxsids.hrc2
-rw-r--r--include/sfx2/watermarkitem.hxx35
-rw-r--r--officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu8
-rw-r--r--sfx2/Library_sfx.mk1
-rw-r--r--sfx2/sdi/sfx.sdi17
-rw-r--r--sfx2/sdi/sfxitems.sdi1
-rw-r--r--sfx2/source/doc/watermarkitem.cxx67
-rw-r--r--sw/Library_sw.mk1
-rw-r--r--sw/UIConfig_swriter.mk1
-rw-r--r--sw/inc/editsh.hxx4
-rw-r--r--sw/sdi/_basesh.sdi6
-rw-r--r--sw/source/core/edit/edfcol.cxx310
-rw-r--r--sw/source/uibase/app/docsh2.cxx22
-rw-r--r--sw/source/uibase/app/docst.cxx9
-rw-r--r--sw/source/uibase/dialog/watermarkdialog.cxx91
-rw-r--r--sw/source/uibase/inc/watermarkdialog.hxx39
-rw-r--r--sw/source/uibase/shells/basesh.cxx5
-rw-r--r--sw/source/uibase/shells/slotadd.cxx1
-rw-r--r--sw/uiconfig/swriter/toolbar/classificationbar.xml1
-rw-r--r--sw/uiconfig/swriter/ui/watermarkdialog.ui133
20 files changed, 632 insertions, 122 deletions
diff --git a/include/sfx2/sfxsids.hrc b/include/sfx2/sfxsids.hrc
index f061b163428a..c17b2e850c20 100644
--- a/include/sfx2/sfxsids.hrc
+++ b/include/sfx2/sfxsids.hrc
@@ -329,7 +329,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 a73fe0a505a2..177b7c59480d 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu
@@ -2916,6 +2916,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 5b0ca8cccd85..16f52bab5b57 100644
--- a/sfx2/Library_sfx.mk
+++ b/sfx2/Library_sfx.mk
@@ -233,6 +233,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 4622d3f838c9..6fce89a16635 100644
--- a/sfx2/sdi/sfx.sdi
+++ b/sfx2/sdi/sfx.sdi
@@ -4267,6 +4267,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 3c6c671efeb2..53e430ede61b 100644
--- a/sw/Library_sw.mk
+++ b/sw/Library_sw.mk
@@ -592,6 +592,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 3be87d04f098..a57f5657c0f4 100644
--- a/sw/UIConfig_swriter.mk
+++ b/sw/UIConfig_swriter.mk
@@ -277,6 +277,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 7ffcf379365a..63842e296c84 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;
@@ -366,6 +367,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 0df1825ba2c6..52b3a031d3a5 100644
--- a/sw/sdi/_basesh.sdi
+++ b/sw/sdi/_basesh.sdi
@@ -377,6 +377,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 7de9077240fb..024278e9971f 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_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(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 41dd001ed534..5348175ffc58 100644
--- a/sw/source/uibase/app/docsh2.cxx
+++ b/sw/source/uibase/app/docsh2.cxx
@@ -123,6 +123,7 @@
#include "dialog.hrc"
#include "swabstdlg.hxx"
+#include "watermarkdialog.hxx"
#include <ndtxt.hxx>
@@ -1155,6 +1156,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 1316084f082c..16fed3f39afd 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>
using namespace ::com::sun::star;
@@ -273,6 +274,14 @@ void SwDocShell::StateStyleSheet(SfxItemSet& rSet, SwWrtShell* pSh)
break;
case SID_STYLE_EDIT:
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 a5aeb348f25c..027ec78151a8 100644
--- a/sw/source/uibase/shells/basesh.cxx
+++ b/sw/source/uibase/shells/basesh.cxx
@@ -957,6 +957,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 4ea84aa6969e..bd0e90e963d4 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>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="0">ok</action-widget>
+ <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>