summaryrefslogtreecommitdiff
path: root/sfx2/source/doc/SfxDocumentMetaData.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sfx2/source/doc/SfxDocumentMetaData.cxx')
-rw-r--r--sfx2/source/doc/SfxDocumentMetaData.cxx198
1 files changed, 124 insertions, 74 deletions
diff --git a/sfx2/source/doc/SfxDocumentMetaData.cxx b/sfx2/source/doc/SfxDocumentMetaData.cxx
index 1423e712242e..476d6f5186a5 100644
--- a/sfx2/source/doc/SfxDocumentMetaData.cxx
+++ b/sfx2/source/doc/SfxDocumentMetaData.cxx
@@ -66,6 +66,7 @@
#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
#include "com/sun/star/util/Date.hpp"
#include "com/sun/star/util/Time.hpp"
+#include "com/sun/star/util/Duration.hpp"
#include "SfxDocumentMetaData.hxx"
#include "rtl/ustrbuf.hxx"
@@ -79,6 +80,7 @@
#include "comphelper/storagehelper.hxx"
#include "comphelper/mediadescriptor.hxx"
#include "comphelper/sequenceasvector.hxx"
+#include "comphelper/stlunosequence.hxx"
#include "sot/storage.hxx"
#include "sfx2/docfile.hxx"
#include "sax/tools/converter.hxx"
@@ -322,7 +324,7 @@ private:
/// standard meta data (multiple occurrences)
std::map< ::rtl::OUString,
std::vector<css::uno::Reference<css::xml::dom::XNode> > > m_metaList;
- /// user-defined meta data (meta:user-defined)
+ /// user-defined meta data (meta:user-defined) @ATTENTION may be null!
css::uno::Reference<css::beans::XPropertyContainer> m_xUserDefined;
// now for some meta-data attributes; these are not updated directly in the
// DOM because updates (detecting "empty" elements) would be quite messy
@@ -468,6 +470,11 @@ const char* s_nsODFMeta = "urn:oasis:names:tc:opendocument:xmlns:meta:1.0";
const char* s_metaXml = "meta.xml";
+bool isValidDate(const css::util::Date & i_rDate)
+{
+ return i_rDate.Month > 0;
+}
+
bool isValidDateTime(const css::util::DateTime & i_rDateTime)
{
return i_rDateTime.Month > 0;
@@ -499,16 +506,25 @@ getQualifier(const char* i_name) {
return ::rtl::OUString::createFromAscii(ns);
}
+bool SAL_CALL
+textToDateOrDateTime(css::util::Date & io_rd, css::util::DateTime & io_rdt,
+ bool & o_rIsDateTime, ::rtl::OUString i_text) throw ()
+{
+ if (::sax::Converter::convertDateOrDateTime(
+ io_rd, io_rdt, o_rIsDateTime, i_text)) {
+ return true;
+ } else {
+ DBG_WARNING1("SfxDocumentMetaData: invalid date: %s",
+ OUStringToOString(i_text, RTL_TEXTENCODING_UTF8).getStr());
+ return false;
+ }
+}
+
// convert string to date/time
bool SAL_CALL
textToDateTime(css::util::DateTime & io_rdt, ::rtl::OUString i_text) throw ()
{
if (::sax::Converter::convertDateTime(io_rdt, i_text)) {
- // NB: there may be rounding errors; handle these here
- if (io_rdt.HundredthSeconds > 0) {
- io_rdt.Seconds++;
- io_rdt.HundredthSeconds = 0;
- }
return true;
} else {
DBG_WARNING1("SfxDocumentMetaData: invalid date: %s",
@@ -527,6 +543,20 @@ textToDateTimeDefault(::rtl::OUString i_text) throw ()
return dt;
}
+// convert date to string
+::rtl::OUString SAL_CALL
+dateToText(css::util::Date const& i_rd) throw ()
+{
+ if (isValidDate(i_rd)) {
+ ::rtl::OUStringBuffer buf;
+ ::sax::Converter::convertDate(buf, i_rd);
+ return buf.makeStringAndClear();
+ } else {
+ return ::rtl::OUString();
+ }
+}
+
+
// convert date/time to string
::rtl::OUString SAL_CALL
dateTimeToText(css::util::DateTime const& i_rdt) throw ()
@@ -541,60 +571,48 @@ dateTimeToText(css::util::DateTime const& i_rdt) throw ()
}
// convert string to duration
-bool SAL_CALL
-textToDuration(css::util::Time& io_rut, ::rtl::OUString i_text) throw ()
+bool
+textToDuration(css::util::Duration& io_rDur, ::rtl::OUString const& i_rText)
+throw ()
{
- css::util::DateTime dt;
- if (::sax::Converter::convertTime(dt, i_text)) {
- // NB: there may be rounding errors; handle these here
- if (dt.HundredthSeconds > 0) {
- dt.Seconds++;
- dt.HundredthSeconds = 0;
- }
- io_rut.Hours = dt.Hours;
- io_rut.Minutes = dt.Minutes;
- io_rut.Seconds = dt.Seconds;
- io_rut.HundredthSeconds = dt.HundredthSeconds;
+ if (::sax::Converter::convertDuration(io_rDur, i_rText)) {
return true;
} else {
DBG_WARNING1("SfxDocumentMetaData: invalid duration: %s",
- OUStringToOString(i_text, RTL_TEXTENCODING_UTF8).getStr());
+ OUStringToOString(i_rText, RTL_TEXTENCODING_UTF8).getStr());
return false;
}
}
-sal_Int32 SAL_CALL textToDuration(::rtl::OUString i_text) throw ()
+sal_Int32 textToDuration(::rtl::OUString const& i_rText) throw ()
{
- css::util::Time t;
- if (textToDuration(t, i_text)) {
- return t.Hours * 3600 + t.Minutes * 60 + t.Seconds;
+ css::util::Duration d;
+ if (textToDuration(d, i_rText)) {
+ return (d.Days * (24*3600))
+ + (d.Hours * 3600) + (d.Minutes * 60) + d.Seconds;
} else {
return 0; // default
}
}
// convert duration to string
-::rtl::OUString SAL_CALL durationToText(css::util::Time const& i_rut) throw ()
+::rtl::OUString durationToText(css::util::Duration const& i_rDur) throw ()
{
- css::util::DateTime dt;
- dt.Hours = i_rut.Hours;
- dt.Minutes = i_rut.Minutes;
- dt.Seconds = i_rut.Seconds;
- dt.HundredthSeconds = i_rut.HundredthSeconds;
::rtl::OUStringBuffer buf;
- ::sax::Converter::convertTime(buf, dt);
+ ::sax::Converter::convertDuration(buf, i_rDur);
return buf.makeStringAndClear();
}
// convert duration to string
::rtl::OUString SAL_CALL durationToText(sal_Int32 i_value) throw ()
{
- css::util::Time ut;
- ut.Hours = static_cast<sal_Int16>(i_value / 3600);
- ut.Minutes = static_cast<sal_Int16>((i_value % 3600) / 60);
- ut.Seconds = static_cast<sal_Int16>(i_value % 60);
- ut.HundredthSeconds = 0;
- return durationToText(ut);
+ css::util::Duration ud;
+ ud.Days = static_cast<sal_Int16>(i_value / (24 * 3600));
+ ud.Hours = static_cast<sal_Int16>((i_value % (24 * 3600)) / 3600);
+ ud.Minutes = static_cast<sal_Int16>((i_value % 3600) / 60);
+ ud.Seconds = static_cast<sal_Int16>(i_value % 60);
+ ud.HundredthSeconds = 0;
+ return durationToText(ud);
}
// extract base URL (necessary for converting relative links)
@@ -921,17 +939,26 @@ propsToStrings(css::uno::Reference<css::beans::XPropertySet> const & i_xPropSet)
} else if (type == ::cppu::UnoType<css::util::Date>::get()) {
css::util::Date d;
any >>= d;
- css::util::DateTime dt;
- dt.Year = d.Year;
- dt.Month = d.Month;
- dt.Day = d.Day;
- values.push_back(dateTimeToText(dt));
+ values.push_back(dateToText(d));
as.push_back(std::make_pair(vt,
::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("date"))));
} else if (type == ::cppu::UnoType<css::util::Time>::get()) {
+ // #i97029#: replaced by Duration
+ // Time is supported for backward compatibility with OOo 3.x, x<=2
css::util::Time ut;
any >>= ut;
- values.push_back(durationToText(ut));
+ css::util::Duration ud;
+ ud.Hours = ut.Hours;
+ ud.Minutes = ut.Minutes;
+ ud.Seconds = ut.Seconds;
+ ud.HundredthSeconds = ut.HundredthSeconds;
+ values.push_back(durationToText(ud));
+ as.push_back(std::make_pair(vt,
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("time"))));
+ } else if (type == ::cppu::UnoType<css::util::Duration>::get()) {
+ css::util::Duration ud;
+ any >>= ud;
+ values.push_back(durationToText(ud));
as.push_back(std::make_pair(vt,
::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("time"))));
} else if (::cppu::UnoType<double>::get().isAssignableFrom(type)) {
@@ -998,9 +1025,12 @@ SfxDocumentMetaData::updateElement(const char *i_name,
void SAL_CALL SfxDocumentMetaData::updateUserDefinedAndAttributes()
{
createUserDefined();
- css::uno::Reference<css::beans::XPropertySet> xPSet(m_xUserDefined,css::uno::UNO_QUERY_THROW);
- std::pair<css::uno::Sequence< ::rtl::OUString>, AttrVector> udStringsAttrs = propsToStrings(xPSet);
- (void) setMetaList("meta:user-defined", udStringsAttrs.first,&udStringsAttrs.second);
+ const css::uno::Reference<css::beans::XPropertySet> xPSet(m_xUserDefined,
+ css::uno::UNO_QUERY_THROW);
+ const std::pair<css::uno::Sequence< ::rtl::OUString>, AttrVector>
+ udStringsAttrs( propsToStrings(xPSet) );
+ (void) setMetaList("meta:user-defined", udStringsAttrs.first,
+ &udStringsAttrs.second);
// update elements with attributes
std::vector<std::pair<const char *, ::rtl::OUString> > attributes;
@@ -1217,15 +1247,13 @@ void SAL_CALL SfxDocumentMetaData::init(
std::vector<css::uno::Reference<css::xml::dom::XNode> > & vec =
m_metaList[::rtl::OUString::createFromAscii("meta:user-defined")];
- // user-defined meta data: create PropertyBag which only accepts property
- // values of allowed types
+ m_xUserDefined.clear(); // #i105826#: reset (may be re-initialization)
if ( !vec.empty() )
{
createUserDefined();
}
// user-defined meta data: initialize PropertySet from DOM nodes
-
for (std::vector<css::uno::Reference<css::xml::dom::XNode> >::iterator
it = vec.begin(); it != vec.end(); ++it) {
css::uno::Reference<css::xml::dom::XElement> xElem(*it,
@@ -1248,18 +1276,24 @@ void SAL_CALL SfxDocumentMetaData::init(
continue;
}
} else if (type.equalsAscii("date")) {
+ bool isDateTime;
+ css::util::Date d;
css::util::DateTime dt;
- if (textToDateTime(dt, text)) {
- any <<= dt;
+ if (textToDateOrDateTime(d, dt, isDateTime, text)) {
+ if (isDateTime) {
+ any <<= dt;
+ } else {
+ any <<= d;
+ }
} else {
DBG_WARNING1("SfxDocumentMetaData: invalid date: %s",
OUStringToOString(text, RTL_TEXTENCODING_UTF8).getStr());
continue;
}
} else if (type.equalsAscii("time")) {
- css::util::Time ut;
- if (textToDuration(ut, text)) {
- any <<= ut;
+ css::util::Duration ud;
+ if (textToDuration(ud, text)) {
+ any <<= ud;
} else {
DBG_WARNING1("SfxDocumentMetaData: invalid time: %s",
OUStringToOString(text, RTL_TEXTENCODING_UTF8).getStr());
@@ -1301,10 +1335,14 @@ void SAL_CALL SfxDocumentMetaData::init(
////////////////////////////////////////////////////////////////////////////
SfxDocumentMetaData::SfxDocumentMetaData(
- css::uno::Reference< css::uno::XComponentContext > const & context) :
- BaseMutex(), SfxDocumentMetaData_Base(m_aMutex),
- m_xContext(context), m_NotifyListeners(m_aMutex),
- m_isInitialized(false), m_isModified(false)
+ css::uno::Reference< css::uno::XComponentContext > const & context)
+ : BaseMutex()
+ , SfxDocumentMetaData_Base(m_aMutex)
+ , m_xContext(context)
+ , m_NotifyListeners(m_aMutex)
+ , m_isInitialized(false)
+ , m_isModified(false)
+ , m_AutoloadSecs(0)
{
DBG_ASSERT(context.is(), "SfxDocumentMetaData: context is null");
DBG_ASSERT(context->getServiceManager().is(),
@@ -2168,7 +2206,7 @@ void SAL_CALL SfxDocumentMetaData::setModified( ::sal_Bool bModified )
::osl::MutexGuard g(m_aMutex);
checkInit();
m_isModified = bModified;
- if ( !bModified )
+ if ( !bModified && m_xUserDefined.is() )
{
xMB.set(m_xUserDefined, css::uno::UNO_QUERY);
DBG_ASSERT(xMB.is(),
@@ -2241,46 +2279,58 @@ void SAL_CALL SfxDocumentMetaData::serialize(
void SfxDocumentMetaData::createUserDefined()
{
+ // user-defined meta data: create PropertyBag which only accepts property
+ // values of allowed types
if ( !m_xUserDefined.is() )
{
- css::uno::Sequence<css::uno::Type> types(10);
+ css::uno::Sequence<css::uno::Type> types(11);
types[0] = ::cppu::UnoType<bool>::get();
types[1] = ::cppu::UnoType< ::rtl::OUString>::get();
types[2] = ::cppu::UnoType<css::util::DateTime>::get();
types[3] = ::cppu::UnoType<css::util::Date>::get();
- types[4] = ::cppu::UnoType<css::util::Time>::get();
+ types[4] = ::cppu::UnoType<css::util::Duration>::get();
types[5] = ::cppu::UnoType<float>::get();
types[6] = ::cppu::UnoType<double>::get();
types[7] = ::cppu::UnoType<sal_Int16>::get();
types[8] = ::cppu::UnoType<sal_Int32>::get();
types[9] = ::cppu::UnoType<sal_Int64>::get();
+ // Time is supported for backward compatibility with OOo 3.x, x<=2
+ types[10] = ::cppu::UnoType<css::util::Time>::get();
css::uno::Sequence<css::uno::Any> args(2);
args[0] <<= css::beans::NamedValue(
::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AllowedTypes")),
css::uno::makeAny(types));
- // #i94175#: ODF 1.1 allows empty user-defined property names!
- args[1] <<= css::beans::NamedValue(
- ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AllowEmptyPropertyName")),
+ // #i94175#: ODF allows empty user-defined property names!
+ args[1] <<= css::beans::NamedValue( ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("AllowEmptyPropertyName")),
css::uno::makeAny(sal_True));
- css::uno::Reference<css::lang::XMultiComponentFactory> xMsf (m_xContext->getServiceManager());
+ const css::uno::Reference<css::lang::XMultiComponentFactory> xMsf(
+ m_xContext->getServiceManager());
m_xUserDefined.set(
- xMsf->createInstanceWithContext(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.beans.PropertyBag")), m_xContext),
+ xMsf->createInstanceWithContext(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.beans.PropertyBag")), m_xContext),
css::uno::UNO_QUERY_THROW);
- css::uno::Reference<css::lang::XInitialization> xInit(m_xUserDefined,
- css::uno::UNO_QUERY);
+ const css::uno::Reference<css::lang::XInitialization> xInit(
+ m_xUserDefined, css::uno::UNO_QUERY);
if (xInit.is()) {
xInit->initialize(args);
}
- css::uno::Reference<css::util::XModifyBroadcaster> xMB(m_xUserDefined,css::uno::UNO_QUERY);
+ const css::uno::Reference<css::util::XModifyBroadcaster> xMB(
+ m_xUserDefined, css::uno::UNO_QUERY);
if (xMB.is())
{
- css::uno::Sequence< css::uno::Reference< css::uno::XInterface > > aListener = m_NotifyListeners.getElements();
- const css::uno::Reference< css::uno::XInterface >* pIter = aListener.getConstArray();
- const css::uno::Reference< css::uno::XInterface >* pEnd = pIter + aListener.getLength();
- for(;pIter != pEnd;++pIter )
- xMB->addModifyListener(css::uno::Reference< css::util::XModifyListener >(*pIter,css::uno::UNO_QUERY));
+ const css::uno::Sequence<css::uno::Reference<css::uno::XInterface> >
+ listeners(m_NotifyListeners.getElements());
+ for (css::uno::Reference< css::uno::XInterface > const * iter =
+ ::comphelper::stl_begin(listeners);
+ iter != ::comphelper::stl_end(listeners); ++iter) {
+ xMB->addModifyListener(
+ css::uno::Reference< css::util::XModifyListener >(*iter,
+ css::uno::UNO_QUERY));
+ }
}
}
}