1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <com/sun/star/awt/Size.hpp>
11 #include <com/sun/star/awt/XControlModel.hpp>
12 #include <com/sun/star/drawing/XControlShape.hpp>
13 #include <com/sun/star/text/VertOrientation.hpp>
15 #include <editeng/unoprnms.hxx>
16 #include <vcl/outdev.hxx>
17 #include <vcl/svapp.hxx>
18 #include <unotools/datetime.hxx>
20 #include <DomainMapper_Impl.hxx>
21 #include <StyleSheetTable.hxx>
22 #include <SdtHelper.hxx>
24 namespace writerfilter
29 using namespace ::com::sun::star
;
31 /// w:sdt's w:dropDownList doesn't have width, so guess the size based on the longest string.
32 awt::Size
lcl_getOptimalWidth(StyleSheetTablePtr pStyleSheet
, OUString
& rDefault
, std::vector
<OUString
>& rItems
)
34 OUString aLongest
= rDefault
;
35 sal_Int32 nHeight
= 0;
36 for (size_t i
= 0; i
< rItems
.size(); ++i
)
37 if (rItems
[i
].getLength() > aLongest
.getLength())
40 MapMode
aMap(MAP_100TH_MM
);
41 OutputDevice
* pOut
= Application::GetDefaultDevice();
42 pOut
->Push(PUSH_FONT
| PUSH_MAPMODE
);
44 PropertyMapPtr pDefaultCharProps
= pStyleSheet
->GetDefaultCharProps();
45 Font
aFont(pOut
->GetFont());
46 PropertyMap::iterator aFontName
= pDefaultCharProps
->find(PROP_CHAR_FONT_NAME
);
47 if (aFontName
!= pDefaultCharProps
->end())
48 aFont
.SetName(aFontName
->second
.getValue().get
<OUString
>());
49 PropertyMap::iterator aHeight
= pDefaultCharProps
->find(PROP_CHAR_HEIGHT
);
50 if (aHeight
!= pDefaultCharProps
->end())
52 nHeight
= aHeight
->second
.getValue().get
<double>() * 35; // points -> mm100
53 aFont
.SetSize(Size(0, nHeight
));
56 pOut
->SetMapMode(aMap
);
57 sal_Int32 nWidth
= pOut
->GetTextWidth(aLongest
);
61 // Border: see PDFWriterImpl::drawFieldBorder(), border size is font height / 4,
62 // so additional width / height needed is height / 2.
63 sal_Int32 nBorder
= nHeight
/ 2;
65 // Width: space for the text + the square having the dropdown arrow.
66 return awt::Size(nWidth
+ nBorder
+ nHeight
, nHeight
+ nBorder
);
69 SdtHelper::SdtHelper(DomainMapper_Impl
& rDM_Impl
)
70 : m_rDM_Impl(rDM_Impl
)
71 , m_bHasElements(false)
75 SdtHelper::~SdtHelper()
79 void SdtHelper::createDropDownControl()
81 OUString aDefaultText
= m_aSdtTexts
.makeStringAndClear();
82 uno::Reference
<awt::XControlModel
> xControlModel(m_rDM_Impl
.GetTextFactory()->createInstance("com.sun.star.form.component.ComboBox"), uno::UNO_QUERY
);
83 uno::Reference
<beans::XPropertySet
> xPropertySet(xControlModel
, uno::UNO_QUERY
);
84 xPropertySet
->setPropertyValue("DefaultText", uno::makeAny(aDefaultText
));
85 xPropertySet
->setPropertyValue("Dropdown", uno::makeAny(sal_True
));
86 uno::Sequence
<OUString
> aItems(m_aDropDownItems
.size());
87 for (size_t i
= 0; i
< m_aDropDownItems
.size(); ++i
)
88 aItems
[i
] = m_aDropDownItems
[i
];
89 xPropertySet
->setPropertyValue("StringItemList", uno::makeAny(aItems
));
91 createControlShape(lcl_getOptimalWidth(m_rDM_Impl
.GetStyleSheetTable(), aDefaultText
, m_aDropDownItems
), xControlModel
);
92 m_aDropDownItems
.clear();
95 void SdtHelper::createDateControl(OUString
& rContentText
)
97 uno::Reference
<awt::XControlModel
> xControlModel(m_rDM_Impl
.GetTextFactory()->createInstance("com.sun.star.form.component.DateField"), uno::UNO_QUERY
);
98 uno::Reference
<beans::XPropertySet
> xPropertySet(xControlModel
, uno::UNO_QUERY
);
100 xPropertySet
->setPropertyValue("Dropdown", uno::makeAny(sal_True
));
102 // See com/sun/star/awt/UnoControlDateFieldModel.idl, DateFormat; sadly there are no constants
103 sal_Int16 nDateFormat
= 0;
104 OUString sDateFormat
= m_sDateFormat
.makeStringAndClear();
105 if (sDateFormat
== "M/d/yyyy" || sDateFormat
== "M.d.yyyy")
106 // Approximate with MM.dd.yyy
109 // Set default format, so at least the date picker is created.
110 SAL_WARN("writerfilter", "unhandled w:dateFormat value");
111 xPropertySet
->setPropertyValue("DateFormat", uno::makeAny(nDateFormat
));
114 util::DateTime aDateTime
;
115 if (utl::ISO8601parseDateTime(m_sDate
.makeStringAndClear(), aDateTime
))
117 utl::extractDate(aDateTime
, aDate
);
118 xPropertySet
->setPropertyValue("Date", uno::makeAny(aDate
));
119 xPropertySet
->setPropertyValue("HelpText", uno::makeAny(OUString("Click here to enter a date")));
122 xPropertySet
->setPropertyValue("HelpText", uno::makeAny(rContentText
));
124 // append date format to grab bag
125 uno::Sequence
<beans::PropertyValue
> aGrabBag(4);
126 aGrabBag
[0].Name
= "OriginalDate";
127 aGrabBag
[0].Value
= uno::makeAny(aDate
);
128 aGrabBag
[1].Name
= "OriginalContent";
129 aGrabBag
[1].Value
= uno::makeAny(rContentText
);
130 aGrabBag
[2].Name
= "DateFormat";
131 aGrabBag
[2].Value
= uno::makeAny(sDateFormat
);
132 aGrabBag
[3].Name
= "Locale";
133 aGrabBag
[3].Value
= uno::makeAny(m_sLocale
.makeStringAndClear());
135 std::vector
<OUString
> aItems
;
136 createControlShape(lcl_getOptimalWidth(m_rDM_Impl
.GetStyleSheetTable(), rContentText
, aItems
), xControlModel
, aGrabBag
);
139 void SdtHelper::createControlShape(awt::Size aSize
, uno::Reference
<awt::XControlModel
> xControlModel
)
141 createControlShape(aSize
, xControlModel
, uno::Sequence
<beans::PropertyValue
>());
144 void SdtHelper::createControlShape(awt::Size aSize
, uno::Reference
<awt::XControlModel
> xControlModel
, const uno::Sequence
<beans::PropertyValue
>& rGrabBag
)
146 uno::Reference
<drawing::XControlShape
> xControlShape(m_rDM_Impl
.GetTextFactory()->createInstance("com.sun.star.drawing.ControlShape"), uno::UNO_QUERY
);
147 xControlShape
->setSize(aSize
);
148 xControlShape
->setControl(xControlModel
);
150 uno::Reference
<beans::XPropertySet
> xPropertySet(xControlShape
, uno::UNO_QUERY
);
151 xPropertySet
->setPropertyValue("VertOrient", uno::makeAny(text::VertOrientation::CENTER
));
153 if (rGrabBag
.hasElements())
154 xPropertySet
->setPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG
, uno::makeAny(rGrabBag
));
156 uno::Reference
<text::XTextContent
> xTextContent(xControlShape
, uno::UNO_QUERY
);
157 m_rDM_Impl
.appendTextContent(xTextContent
, uno::Sequence
< beans::PropertyValue
>());
158 m_bHasElements
= true;
161 std::vector
<OUString
>& SdtHelper::getDropDownItems()
163 return m_aDropDownItems
;
166 OUStringBuffer
& SdtHelper::getSdtTexts()
171 OUStringBuffer
& SdtHelper::getDate()
176 OUStringBuffer
& SdtHelper::getDateFormat()
178 return m_sDateFormat
;
181 OUStringBuffer
& SdtHelper::getLocale()
186 bool SdtHelper::hasElements()
188 return m_bHasElements
;
191 void SdtHelper::appendToInteropGrabBag(com::sun::star::beans::PropertyValue rValue
)
193 sal_Int32 nLength
= m_aGrabBag
.getLength();
194 m_aGrabBag
.realloc(nLength
+ 1);
195 m_aGrabBag
[nLength
] = rValue
;
198 com::sun::star::uno::Sequence
<com::sun::star::beans::PropertyValue
> SdtHelper::getInteropGrabBagAndClear()
200 com::sun::star::uno::Sequence
<com::sun::star::beans::PropertyValue
> aRet
= m_aGrabBag
;
201 m_aGrabBag
.realloc(0);
205 bool SdtHelper::isInteropGrabBagEmpty()
207 return m_aGrabBag
.getLength() == 0;
210 sal_Int32
SdtHelper::getInteropGrabBagSize()
212 return m_aGrabBag
.getLength();
215 bool SdtHelper::containedInInteropGrabBag(const OUString
& rValueName
)
217 for (sal_Int32 i
=0; i
< m_aGrabBag
.getLength(); ++i
)
218 if (m_aGrabBag
[i
].Name
== rValueName
)
224 } // namespace dmapper
225 } // namespace writerfilter
227 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */