1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <svtools/htmlkywd.hxx>
21 
22 #include <rtl/tencinfo.h>
23 #include <sal/log.hxx>
24 
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>
30 
31 #include <sfx2/frmdescr.hxx>
32 #include <sfx2/frmhtmlw.hxx>
33 #include <strings.hxx>
34 
35 #include <comphelper/processfactory.hxx>
36 #include <comphelper/string.hxx>
37 
38 #include <com/sun/star/script/Converter.hpp>
39 #include <com/sun/star/document/XDocumentProperties.hpp>
40 #include <com/sun/star/beans/XPropertySet.hpp>
41 
42 #include <rtl/bootstrap.hxx>
43 #include <rtl/strbuf.hxx>
44 #include <sax/tools/converter.hxx>
45 
46 using namespace ::com::sun::star;
47 
48 char const sHTML_SC_yes[] =  "YES";
49 char const sHTML_SC_no[] =       "NO";
50 
OutMeta(SvStream & rStrm,const char * pIndent,const OUString & rName,const OUString & rContent,bool bHTTPEquiv,rtl_TextEncoding eDestEnc,OUString * pNonConvertableChars)51 void SfxFrameHTMLWriter::OutMeta( SvStream& rStrm,
52                                   const char *pIndent,
53                                   const OUString& rName,
54                                   const OUString& rContent,
55                                   bool bHTTPEquiv,
56                                   rtl_TextEncoding eDestEnc,
57                                   OUString *pNonConvertableChars  )
58 {
59     rStrm.WriteCharPtr( SAL_NEWLINE_STRING );
60     if( pIndent )
61         rStrm.WriteCharPtr( pIndent );
62 
63     OStringBuffer sOut;
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() );
67 
68     HTMLOutFuncs::Out_String( rStrm, rName, eDestEnc, pNonConvertableChars );
69 
70     sOut.append("\" " OOO_STRING_SVTOOLS_HTML_O_content "=\"");
71     rStrm.WriteOString( sOut.makeStringAndClear() );
72 
73     HTMLOutFuncs::Out_String( rStrm, rContent, eDestEnc, pNonConvertableChars ).WriteCharPtr( "\"/>" );
74 }
75 
Out_DocInfo(SvStream & rStrm,const OUString & rBaseURL,const uno::Reference<document::XDocumentProperties> & i_xDocProps,const char * pIndent,rtl_TextEncoding eDestEnc,OUString * pNonConvertableChars)76 void SfxFrameHTMLWriter::Out_DocInfo( SvStream& rStrm, const OUString& rBaseURL,
77         const uno::Reference<document::XDocumentProperties> & i_xDocProps,
78         const char *pIndent,
79         rtl_TextEncoding eDestEnc,
80         OUString *pNonConvertableChars    )
81 {
82     const char *pCharSet =
83                 rtl_getBestMimeCharsetFromTextEncoding( eDestEnc );
84 
85     if( pCharSet )
86     {
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 );
90     }
91 
92     // Title (regardless if empty)
93     rStrm.WriteCharPtr( SAL_NEWLINE_STRING );
94     if( pIndent )
95         rStrm.WriteCharPtr( pIndent );
96     HTMLOutFuncs::Out_AsciiTag( rStrm, OOO_STRING_SVTOOLS_HTML_title );
97     if( i_xDocProps.is() )
98     {
99         const OUString& rTitle = i_xDocProps->getTitle();
100         if( !rTitle.isEmpty() )
101             HTMLOutFuncs::Out_String( rStrm, rTitle, eDestEnc, pNonConvertableChars );
102     }
103     HTMLOutFuncs::Out_AsciiTag( rStrm, OOO_STRING_SVTOOLS_HTML_title, false );
104 
105     // Target-Frame
106     if( i_xDocProps.is() )
107     {
108         const OUString& rTarget = i_xDocProps->getDefaultTarget();
109         if( !rTarget.isEmpty() )
110         {
111             rStrm.WriteCharPtr( SAL_NEWLINE_STRING );
112             if( pIndent )
113                 rStrm.WriteCharPtr( pIndent );
114 
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( "\">" );
119         }
120     }
121 
122     // Who we are
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 );
128 
129     if( !i_xDocProps.is() )
130         return;
131 
132     // Reload
133     if( (i_xDocProps->getAutoloadSecs() != 0) ||
134         !i_xDocProps->getAutoloadURL().isEmpty() )
135     {
136         OUString sContent = OUString::number(
137                             i_xDocProps->getAutoloadSecs() );
138 
139         const OUString &rReloadURL = i_xDocProps->getAutoloadURL();
140         if( !rReloadURL.isEmpty() )
141         {
142             sContent += ";URL=" + URIHelper::simpleNormalizedMakeRelative(
143                           rBaseURL, rReloadURL);
144         }
145 
146         OutMeta( rStrm, pIndent, OOO_STRING_SVTOOLS_HTML_META_refresh, sContent, true,
147                  eDestEnc, pNonConvertableChars );
148     }
149 
150     // Author
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 );
155 
156     // created
157     ::util::DateTime uDT = i_xDocProps->getCreationDate();
158     OUStringBuffer aBuffer;
159     ::sax::Converter::convertTimeOrDateTime(aBuffer, uDT);
160 
161     OutMeta( rStrm, pIndent, OOO_STRING_SVTOOLS_HTML_META_created, aBuffer.makeStringAndClear(), false,
162              eDestEnc, pNonConvertableChars );
163 
164     // changedby
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 );
169 
170     // changed
171     uDT = i_xDocProps->getModificationDate();
172     ::sax::Converter::convertTimeOrDateTime(aBuffer, uDT);
173 
174     OutMeta( rStrm, pIndent, OOO_STRING_SVTOOLS_HTML_META_changed, aBuffer.makeStringAndClear(), false,
175              eDestEnc, pNonConvertableChars );
176 
177     // Subject
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 );
182 
183     // Description
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);
188 
189     // Keywords
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);
195 
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)
205     {
206         try
207         {
208             OUString name = rProp.Name;
209             uno::Any aStr = xConverter->convertToSimpleType(
210                     xUserDefinedProps->getPropertyValue(name),
211                     uno::TypeClass_STRING);
212             OUString str;
213             aStr >>= str;
214             OUString valstr(comphelper::string::stripEnd(str, ' '));
215             OutMeta( rStrm, pIndent, name, valstr, false,
216                      eDestEnc, pNonConvertableChars );
217         }
218         catch (const uno::Exception&)
219         {
220             // may happen with concurrent modification...
221             SAL_INFO("sfx", "SfxFrameHTMLWriter::Out_DocInfo: exception");
222         }
223     }
224 }
225 
Out_FrameDescriptor(SvStream & rOut,const OUString & rBaseURL,const uno::Reference<beans::XPropertySet> & xSet,rtl_TextEncoding eDestEnc,OUString * pNonConvertableChars)226 void SfxFrameHTMLWriter::Out_FrameDescriptor(
227     SvStream& rOut, const OUString& rBaseURL, const uno::Reference < beans::XPropertySet >& xSet,
228     rtl_TextEncoding eDestEnc, OUString *pNonConvertableChars )
229 {
230     try
231     {
232         OStringBuffer sOut;
233         OUString aStr;
234         uno::Any aAny = xSet->getPropertyValue("FrameURL");
235         if ( (aAny >>= aStr) && !aStr.isEmpty() )
236         {
237             OUString aURL = INetURLObject( aStr ).GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
238             if( !aURL.isEmpty() )
239             {
240                 aURL = URIHelper::simpleNormalizedMakeRelative(
241                     rBaseURL, aURL );
242                 sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_src "=\"");
243                 rOut.WriteOString( sOut.makeStringAndClear() );
244                 HTMLOutFuncs::Out_String( rOut, aURL, eDestEnc, pNonConvertableChars );
245                 sOut.append('\"');
246             }
247         }
248 
249         aAny = xSet->getPropertyValue("FrameName");
250         if ( (aAny >>= aStr) && !aStr.isEmpty() )
251         {
252             sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_name "=\"");
253             rOut.WriteOString( sOut.makeStringAndClear() );
254             HTMLOutFuncs::Out_String( rOut, aStr, eDestEnc, pNonConvertableChars );
255             sOut.append('\"');
256         }
257 
258         sal_Int32 nVal = SIZE_NOT_SET;
259         aAny = xSet->getPropertyValue("FrameMarginWidth");
260         if ( (aAny >>= nVal) && nVal != SIZE_NOT_SET )
261         {
262             sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_marginwidth)
263                 .append('=').append(nVal);
264         }
265         aAny = xSet->getPropertyValue("FrameMarginHeight");
266         if ( (aAny >>= nVal) && nVal != SIZE_NOT_SET )
267         {
268             sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_marginheight)
269                 .append('=').append(nVal);
270         }
271 
272         bool bVal = true;
273         aAny = xSet->getPropertyValue("FrameIsAutoScroll");
274         if ( (aAny >>= bVal) && !bVal )
275         {
276             aAny = xSet->getPropertyValue("FrameIsScrollingMode");
277             if ( aAny >>= bVal )
278             {
279                 const char *pStr = bVal ? sHTML_SC_yes : sHTML_SC_no;
280                 sOut.append(OString::Concat(" " OOO_STRING_SVTOOLS_HTML_O_scrolling) +
281                         pStr);
282             }
283         }
284 
285         // frame border (MS+Netscape-Extension)
286         aAny = xSet->getPropertyValue("FrameIsAutoBorder");
287         if ( (aAny >>= bVal) && !bVal )
288         {
289             aAny = xSet->getPropertyValue("FrameIsBorder");
290             if ( aAny >>= bVal )
291             {
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);
295             }
296         }
297         rOut.WriteOString( sOut.makeStringAndClear() );
298     }
299     catch (const uno::Exception&)
300     {
301     }
302 }
303 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
304