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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svtools/htmlkywd.hxx>
22 #include <rtl/tencinfo.h>
23 #include <sal/log.hxx>
25 #include <svl/urihelper.hxx>
26 #include <tools/stream.hxx>
27 #include <tools/debug.hxx>
28 #include <unotools/resmgr.hxx>
29 #include <svtools/htmlout.hxx>
31 #include <sfx2/frmdescr.hxx>
32 #include <sfx2/frmhtmlw.hxx>
33 #include <strings.hxx>
35 #include <comphelper/processfactory.hxx>
36 #include <comphelper/string.hxx>
38 #include <com/sun/star/script/Converter.hpp>
39 #include <com/sun/star/document/XDocumentProperties.hpp>
40 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <rtl/bootstrap.hxx>
43 #include <rtl/strbuf.hxx>
44 #include <sax/tools/converter.hxx>
46 using namespace ::com::sun::star
;
48 char const sHTML_SC_yes
[] = "YES";
49 char const sHTML_SC_no
[] = "NO";
51 void SfxFrameHTMLWriter::OutMeta( SvStream
& rStrm
,
53 const OUString
& rName
,
54 const OUString
& rContent
,
56 rtl_TextEncoding eDestEnc
,
57 OUString
*pNonConvertableChars
)
59 rStrm
.WriteCharPtr( SAL_NEWLINE_STRING
);
61 rStrm
.WriteCharPtr( pIndent
);
64 sOut
.append("<" OOO_STRING_SVTOOLS_HTML_meta
" ")
65 .append(bHTTPEquiv
? OOO_STRING_SVTOOLS_HTML_O_httpequiv
: OOO_STRING_SVTOOLS_HTML_O_name
).append("=\"");
66 rStrm
.WriteOString( sOut
.makeStringAndClear() );
68 HTMLOutFuncs::Out_String( rStrm
, rName
, eDestEnc
, pNonConvertableChars
);
70 sOut
.append("\" " OOO_STRING_SVTOOLS_HTML_O_content
"=\"");
71 rStrm
.WriteOString( sOut
.makeStringAndClear() );
73 HTMLOutFuncs::Out_String( rStrm
, rContent
, eDestEnc
, pNonConvertableChars
).WriteCharPtr( "\"/>" );
76 void SfxFrameHTMLWriter::Out_DocInfo( SvStream
& rStrm
, const OUString
& rBaseURL
,
77 const uno::Reference
<document::XDocumentProperties
> & i_xDocProps
,
79 rtl_TextEncoding eDestEnc
,
80 OUString
*pNonConvertableChars
)
82 const char *pCharSet
=
83 rtl_getBestMimeCharsetFromTextEncoding( eDestEnc
);
87 OUString aContentType
= "text/html; charset=" + OUString(pCharSet
, strlen(pCharSet
), RTL_TEXTENCODING_UTF8
);
88 OutMeta( rStrm
, pIndent
, OOO_STRING_SVTOOLS_HTML_META_content_type
, aContentType
, true,
89 eDestEnc
, pNonConvertableChars
);
92 // Title (regardless if empty)
93 rStrm
.WriteCharPtr( SAL_NEWLINE_STRING
);
95 rStrm
.WriteCharPtr( pIndent
);
96 HTMLOutFuncs::Out_AsciiTag( rStrm
, OOO_STRING_SVTOOLS_HTML_title
);
97 if( i_xDocProps
.is() )
99 const OUString
& rTitle
= i_xDocProps
->getTitle();
100 if( !rTitle
.isEmpty() )
101 HTMLOutFuncs::Out_String( rStrm
, rTitle
, eDestEnc
, pNonConvertableChars
);
103 HTMLOutFuncs::Out_AsciiTag( rStrm
, OOO_STRING_SVTOOLS_HTML_title
, false );
106 if( i_xDocProps
.is() )
108 const OUString
& rTarget
= i_xDocProps
->getDefaultTarget();
109 if( !rTarget
.isEmpty() )
111 rStrm
.WriteCharPtr( SAL_NEWLINE_STRING
);
113 rStrm
.WriteCharPtr( pIndent
);
115 rStrm
.WriteOString( "<" OOO_STRING_SVTOOLS_HTML_base
" "
116 OOO_STRING_SVTOOLS_HTML_O_target
"=\"" );
117 HTMLOutFuncs::Out_String( rStrm
, rTarget
, eDestEnc
, pNonConvertableChars
)
118 .WriteCharPtr( "\">" );
123 OUString
sGenerator(Translate::ExpandVariables(STR_HTML_GENERATOR
));
124 OUString
os( "$_OS" );
125 ::rtl::Bootstrap::expandMacros(os
);
126 sGenerator
= sGenerator
.replaceFirst( "%1", os
);
127 OutMeta( rStrm
, pIndent
, OOO_STRING_SVTOOLS_HTML_META_generator
, sGenerator
, false, eDestEnc
, pNonConvertableChars
);
129 if( !i_xDocProps
.is() )
133 if( (i_xDocProps
->getAutoloadSecs() != 0) ||
134 !i_xDocProps
->getAutoloadURL().isEmpty() )
136 OUString sContent
= OUString::number(
137 i_xDocProps
->getAutoloadSecs() );
139 const OUString
&rReloadURL
= i_xDocProps
->getAutoloadURL();
140 if( !rReloadURL
.isEmpty() )
142 sContent
+= ";URL=" + URIHelper::simpleNormalizedMakeRelative(
143 rBaseURL
, rReloadURL
);
146 OutMeta( rStrm
, pIndent
, OOO_STRING_SVTOOLS_HTML_META_refresh
, sContent
, true,
147 eDestEnc
, pNonConvertableChars
);
151 const OUString
& rAuthor
= i_xDocProps
->getAuthor();
152 if( !rAuthor
.isEmpty() )
153 OutMeta( rStrm
, pIndent
, OOO_STRING_SVTOOLS_HTML_META_author
, rAuthor
, false,
154 eDestEnc
, pNonConvertableChars
);
157 ::util::DateTime uDT
= i_xDocProps
->getCreationDate();
158 OUStringBuffer aBuffer
;
159 ::sax::Converter::convertTimeOrDateTime(aBuffer
, uDT
);
161 OutMeta( rStrm
, pIndent
, OOO_STRING_SVTOOLS_HTML_META_created
, aBuffer
.makeStringAndClear(), false,
162 eDestEnc
, pNonConvertableChars
);
165 const OUString
& rChangedBy
= i_xDocProps
->getModifiedBy();
166 if( !rChangedBy
.isEmpty() )
167 OutMeta( rStrm
, pIndent
, OOO_STRING_SVTOOLS_HTML_META_changedby
, rChangedBy
, false,
168 eDestEnc
, pNonConvertableChars
);
171 uDT
= i_xDocProps
->getModificationDate();
172 ::sax::Converter::convertTimeOrDateTime(aBuffer
, uDT
);
174 OutMeta( rStrm
, pIndent
, OOO_STRING_SVTOOLS_HTML_META_changed
, aBuffer
.makeStringAndClear(), false,
175 eDestEnc
, pNonConvertableChars
);
178 const OUString
& rTheme
= i_xDocProps
->getSubject();
179 if( !rTheme
.isEmpty() )
180 OutMeta( rStrm
, pIndent
, OOO_STRING_SVTOOLS_HTML_META_classification
, rTheme
, false,
181 eDestEnc
, pNonConvertableChars
);
184 const OUString
& rComment
= i_xDocProps
->getDescription();
185 if( !rComment
.isEmpty() )
186 OutMeta( rStrm
, pIndent
, OOO_STRING_SVTOOLS_HTML_META_description
, rComment
, false,
187 eDestEnc
, pNonConvertableChars
);
190 OUString Keywords
= ::comphelper::string::convertCommaSeparated(
191 i_xDocProps
->getKeywords());
192 if( !Keywords
.isEmpty() )
193 OutMeta( rStrm
, pIndent
, OOO_STRING_SVTOOLS_HTML_META_keywords
, Keywords
, false,
194 eDestEnc
, pNonConvertableChars
);
196 uno::Reference
< script::XTypeConverter
> xConverter( script::Converter::create(
197 ::comphelper::getProcessComponentContext() ) );
198 uno::Reference
<beans::XPropertySet
> xUserDefinedProps(
199 i_xDocProps
->getUserDefinedProperties(), uno::UNO_QUERY_THROW
);
200 uno::Reference
<beans::XPropertySetInfo
> xPropInfo
=
201 xUserDefinedProps
->getPropertySetInfo();
202 DBG_ASSERT(xPropInfo
.is(), "UserDefinedProperties Info is null");
203 const uno::Sequence
<beans::Property
> props
= xPropInfo
->getProperties();
204 for (const auto& rProp
: props
)
208 OUString name
= rProp
.Name
;
209 uno::Any aStr
= xConverter
->convertToSimpleType(
210 xUserDefinedProps
->getPropertyValue(name
),
211 uno::TypeClass_STRING
);
214 OUString
valstr(comphelper::string::stripEnd(str
, ' '));
215 OutMeta( rStrm
, pIndent
, name
, valstr
, false,
216 eDestEnc
, pNonConvertableChars
);
218 catch (const uno::Exception
&)
220 // may happen with concurrent modification...
221 SAL_INFO("sfx", "SfxFrameHTMLWriter::Out_DocInfo: exception");
226 void SfxFrameHTMLWriter::Out_FrameDescriptor(
227 SvStream
& rOut
, const OUString
& rBaseURL
, const uno::Reference
< beans::XPropertySet
>& xSet
,
228 rtl_TextEncoding eDestEnc
, OUString
*pNonConvertableChars
)
234 uno::Any aAny
= xSet
->getPropertyValue("FrameURL");
235 if ( (aAny
>>= aStr
) && !aStr
.isEmpty() )
237 OUString aURL
= INetURLObject( aStr
).GetMainURL( INetURLObject::DecodeMechanism::ToIUri
);
238 if( !aURL
.isEmpty() )
240 aURL
= URIHelper::simpleNormalizedMakeRelative(
242 sOut
.append(" " OOO_STRING_SVTOOLS_HTML_O_src
"=\"");
243 rOut
.WriteOString( sOut
.makeStringAndClear() );
244 HTMLOutFuncs::Out_String( rOut
, aURL
, eDestEnc
, pNonConvertableChars
);
249 aAny
= xSet
->getPropertyValue("FrameName");
250 if ( (aAny
>>= aStr
) && !aStr
.isEmpty() )
252 sOut
.append(" " OOO_STRING_SVTOOLS_HTML_O_name
"=\"");
253 rOut
.WriteOString( sOut
.makeStringAndClear() );
254 HTMLOutFuncs::Out_String( rOut
, aStr
, eDestEnc
, pNonConvertableChars
);
258 sal_Int32 nVal
= SIZE_NOT_SET
;
259 aAny
= xSet
->getPropertyValue("FrameMarginWidth");
260 if ( (aAny
>>= nVal
) && nVal
!= SIZE_NOT_SET
)
262 sOut
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_marginwidth
)
263 .append('=').append(nVal
);
265 aAny
= xSet
->getPropertyValue("FrameMarginHeight");
266 if ( (aAny
>>= nVal
) && nVal
!= SIZE_NOT_SET
)
268 sOut
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_marginheight
)
269 .append('=').append(nVal
);
273 aAny
= xSet
->getPropertyValue("FrameIsAutoScroll");
274 if ( (aAny
>>= bVal
) && !bVal
)
276 aAny
= xSet
->getPropertyValue("FrameIsScrollingMode");
279 const char *pStr
= bVal
? sHTML_SC_yes
: sHTML_SC_no
;
280 sOut
.append(OString::Concat(" " OOO_STRING_SVTOOLS_HTML_O_scrolling
) +
285 // frame border (MS+Netscape-Extension)
286 aAny
= xSet
->getPropertyValue("FrameIsAutoBorder");
287 if ( (aAny
>>= bVal
) && !bVal
)
289 aAny
= xSet
->getPropertyValue("FrameIsBorder");
292 const char* pStr
= bVal
? sHTML_SC_yes
: sHTML_SC_no
;
293 sOut
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_frameborder
)
294 .append('=').append(pStr
);
297 rOut
.WriteOString( sOut
.makeStringAndClear() );
299 catch (const uno::Exception
&)
303 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */