1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sfx2.hxx" 26 27 #ifndef _INETDEF_HXX 28 #include <svl/inetdef.hxx> 29 #endif 30 #include "svtools/htmlkywd.hxx" 31 32 //!(dv) #include <chaos2/cntapi.hxx> 33 #include <rtl/tencinfo.h> 34 35 #include <unotools/configmgr.hxx> 36 #include "svl/urihelper.hxx" 37 #include <tools/datetime.hxx> 38 39 #include <sfx2/frmhtmlw.hxx> 40 #include <sfx2/evntconf.hxx> 41 #include <sfx2/frame.hxx> 42 #include <sfx2/app.hxx> 43 #include <sfx2/viewfrm.hxx> 44 #include <sfx2/docfile.hxx> 45 #include "sfx2/sfxresid.hxx" 46 #include <sfx2/objsh.hxx> 47 #include <sfx2/sfx.hrc> 48 #include "bastyp.hrc" 49 50 #include <comphelper/string.hxx> 51 #include <comphelper/processfactory.hxx> 52 53 #include <com/sun/star/script/XTypeConverter.hpp> 54 #include <com/sun/star/document/XDocumentProperties.hpp> 55 56 57 // ----------------------------------------------------------------------- 58 59 using namespace ::com::sun::star; 60 61 static sal_Char __READONLY_DATA sHTML_SC_yes[] = "YES"; 62 static sal_Char __READONLY_DATA sHTML_SC_no[] = "NO"; 63 static sal_Char __READONLY_DATA sHTML_SC_auto[] = "AUTO"; 64 static sal_Char __READONLY_DATA sHTML_MIME_text_html[] = "text/html; charset="; 65 66 /* not used anymore? 67 static HTMLOutEvent __FAR_DATA aFrameSetEventTable[] = 68 { 69 { sHTML_O_SDonload, sHTML_O_onload, SFX_EVENT_OPENDOC }, 70 { sHTML_O_SDonunload, sHTML_O_onunload, SFX_EVENT_PREPARECLOSEDOC }, 71 { sHTML_O_SDonfocus, sHTML_O_onfocus, SFX_EVENT_ACTIVATEDOC }, 72 { sHTML_O_SDonblur, sHTML_O_onblur, SFX_EVENT_DEACTIVATEDOC }, 73 { 0, 0, 0 } 74 }; 75 */ 76 77 #if defined(UNX) 78 const sal_Char SfxFrameHTMLWriter::sNewLine[] = "\012"; 79 #else 80 const sal_Char __FAR_DATA SfxFrameHTMLWriter::sNewLine[] = "\015\012"; 81 #endif 82 83 void SfxFrameHTMLWriter::OutMeta( SvStream& rStrm, 84 const sal_Char *pIndent, 85 const String& rName, 86 const String& rContent, sal_Bool bHTTPEquiv, 87 rtl_TextEncoding eDestEnc, 88 String *pNonConvertableChars ) 89 { 90 rStrm << sNewLine; 91 if( pIndent ) 92 rStrm << pIndent; 93 94 ByteString sOut( '<' ); 95 (((sOut += OOO_STRING_SVTOOLS_HTML_meta) += ' ') 96 += (bHTTPEquiv ? OOO_STRING_SVTOOLS_HTML_O_httpequiv : OOO_STRING_SVTOOLS_HTML_O_name)) += "=\""; 97 rStrm << sOut.GetBuffer(); 98 99 HTMLOutFuncs::Out_String( rStrm, rName, eDestEnc, pNonConvertableChars ); 100 101 ((sOut = "\" ") += OOO_STRING_SVTOOLS_HTML_O_content) += "=\""; 102 rStrm << sOut.GetBuffer(); 103 104 HTMLOutFuncs::Out_String( rStrm, rContent, eDestEnc, pNonConvertableChars ) << "\">"; 105 } 106 107 void SfxFrameHTMLWriter::Out_DocInfo( SvStream& rStrm, const String& rBaseURL, 108 const uno::Reference<document::XDocumentProperties> & i_xDocProps, 109 const sal_Char *pIndent, 110 rtl_TextEncoding eDestEnc, 111 String *pNonConvertableChars ) 112 { 113 const sal_Char *pCharSet = 114 rtl_getBestMimeCharsetFromTextEncoding( eDestEnc ); 115 116 if( pCharSet ) 117 { 118 String aContentType = String::CreateFromAscii( sHTML_MIME_text_html ); 119 aContentType.AppendAscii( pCharSet ); 120 OutMeta( rStrm, pIndent, OOO_STRING_SVTOOLS_HTML_META_content_type, aContentType, sal_True, 121 eDestEnc, pNonConvertableChars ); 122 } 123 124 // Titel (auch wenn er leer ist) 125 rStrm << sNewLine; 126 if( pIndent ) 127 rStrm << pIndent; 128 HTMLOutFuncs::Out_AsciiTag( rStrm, OOO_STRING_SVTOOLS_HTML_title ); 129 if( i_xDocProps.is() ) 130 { 131 const String& rTitle = i_xDocProps->getTitle(); 132 if( rTitle.Len() ) 133 HTMLOutFuncs::Out_String( rStrm, rTitle, eDestEnc, pNonConvertableChars ); 134 } 135 HTMLOutFuncs::Out_AsciiTag( rStrm, OOO_STRING_SVTOOLS_HTML_title, sal_False ); 136 137 // Target-Frame 138 if( i_xDocProps.is() ) 139 { 140 const String& rTarget = i_xDocProps->getDefaultTarget(); 141 if( rTarget.Len() ) 142 { 143 rStrm << sNewLine; 144 if( pIndent ) 145 rStrm << pIndent; 146 147 ByteString sOut( '<' ); 148 (((sOut += OOO_STRING_SVTOOLS_HTML_base) += ' ') += OOO_STRING_SVTOOLS_HTML_O_target) += "=\""; 149 rStrm << sOut.GetBuffer(); 150 HTMLOutFuncs::Out_String( rStrm, rTarget, eDestEnc, pNonConvertableChars ) 151 << "\">"; 152 } 153 } 154 155 // Who we are 156 String sGenerator( SfxResId( STR_HTML_GENERATOR ) ); 157 sGenerator.SearchAndReplaceAscii( "%1", String( DEFINE_CONST_UNICODE( TOOLS_INETDEF_OS ) ) ); 158 OutMeta( rStrm, pIndent, OOO_STRING_SVTOOLS_HTML_META_generator, sGenerator, sal_False, eDestEnc, pNonConvertableChars ); 159 160 if( i_xDocProps.is() ) 161 { 162 // Reload 163 if( (i_xDocProps->getAutoloadSecs() != 0) || 164 !i_xDocProps->getAutoloadURL().equalsAscii("") ) 165 { 166 String sContent = String::CreateFromInt32( 167 i_xDocProps->getAutoloadSecs() ); 168 169 const String &rReloadURL = i_xDocProps->getAutoloadURL(); 170 if( rReloadURL.Len() ) 171 { 172 sContent.AppendAscii( ";URL=" ); 173 sContent += String( 174 URIHelper::simpleNormalizedMakeRelative( 175 rBaseURL, rReloadURL)); 176 } 177 178 OutMeta( rStrm, pIndent, OOO_STRING_SVTOOLS_HTML_META_refresh, sContent, sal_True, 179 eDestEnc, pNonConvertableChars ); 180 } 181 182 // Author 183 const String& rAuthor = i_xDocProps->getAuthor(); 184 if( rAuthor.Len() ) 185 OutMeta( rStrm, pIndent, OOO_STRING_SVTOOLS_HTML_META_author, rAuthor, sal_False, 186 eDestEnc, pNonConvertableChars ); 187 188 // created 189 ::util::DateTime uDT = i_xDocProps->getCreationDate(); 190 Date aD(uDT.Day, uDT.Month, uDT.Year); 191 Time aT(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.HundredthSeconds); 192 String sOut = String::CreateFromInt32(aD.GetDate()); 193 sOut += ';'; 194 sOut += String::CreateFromInt32(aT.GetTime()); 195 OutMeta( rStrm, pIndent, OOO_STRING_SVTOOLS_HTML_META_created, sOut, sal_False, 196 eDestEnc, pNonConvertableChars ); 197 198 // changedby 199 const String& rChangedBy = i_xDocProps->getModifiedBy(); 200 if( rChangedBy.Len() ) 201 OutMeta( rStrm, pIndent, OOO_STRING_SVTOOLS_HTML_META_changedby, rChangedBy, sal_False, 202 eDestEnc, pNonConvertableChars ); 203 204 // changed 205 uDT = i_xDocProps->getModificationDate(); 206 Date aD2(uDT.Day, uDT.Month, uDT.Year); 207 Time aT2(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.HundredthSeconds); 208 sOut = String::CreateFromInt32(aD2.GetDate()); 209 sOut += ';'; 210 sOut += String::CreateFromInt32(aT2.GetTime()); 211 OutMeta( rStrm, pIndent, OOO_STRING_SVTOOLS_HTML_META_changed, sOut, sal_False, 212 eDestEnc, pNonConvertableChars ); 213 214 // Subject 215 const String& rTheme = i_xDocProps->getSubject(); 216 if( rTheme.Len() ) 217 OutMeta( rStrm, pIndent, OOO_STRING_SVTOOLS_HTML_META_classification, rTheme, sal_False, 218 eDestEnc, pNonConvertableChars ); 219 220 // Description 221 const String& rComment = i_xDocProps->getDescription(); 222 if( rComment.Len() ) 223 OutMeta( rStrm, pIndent, OOO_STRING_SVTOOLS_HTML_META_description, rComment, sal_False, 224 eDestEnc, pNonConvertableChars); 225 226 // Keywords 227 String Keywords = ::comphelper::string::convertCommaSeparated( 228 i_xDocProps->getKeywords()); 229 if( Keywords.Len() ) 230 OutMeta( rStrm, pIndent, OOO_STRING_SVTOOLS_HTML_META_keywords, Keywords, sal_False, 231 eDestEnc, pNonConvertableChars); 232 233 uno::Reference < script::XTypeConverter > xConverter( 234 ::comphelper::getProcessServiceFactory()->createInstance( 235 ::rtl::OUString::createFromAscii("com.sun.star.script.Converter")), 236 uno::UNO_QUERY_THROW ); 237 uno::Reference<beans::XPropertySet> xUserDefinedProps( 238 i_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); 239 DBG_ASSERT(xUserDefinedProps.is(), "UserDefinedProperties is null"); 240 uno::Reference<beans::XPropertySetInfo> xPropInfo = 241 xUserDefinedProps->getPropertySetInfo(); 242 DBG_ASSERT(xPropInfo.is(), "UserDefinedProperties Info is null"); 243 uno::Sequence<beans::Property> props = xPropInfo->getProperties(); 244 for (sal_Int32 i = 0; i < props.getLength(); ++i) { 245 try { 246 ::rtl::OUString name = props[i].Name; 247 ::rtl::OUString str; 248 uno::Any aStr = xConverter->convertToSimpleType( 249 xUserDefinedProps->getPropertyValue(name), 250 uno::TypeClass_STRING); 251 aStr >>= str; 252 String valstr(str); 253 valstr.EraseTrailingChars(); 254 OutMeta( rStrm, pIndent, name, valstr, sal_False, 255 eDestEnc, pNonConvertableChars ); 256 } catch (uno::Exception &) { 257 // may happen with concurrent modification... 258 DBG_WARNING("SfxFrameHTMLWriter::Out_DocInfo: exception"); 259 } 260 } 261 } 262 } 263 /* 264 void SfxFrameHTMLWriter::OutHeader( rtl_TextEncoding eDestEnc ) 265 { 266 // <HTML> 267 // <HEAD> 268 // <TITLE>Titel</TITLE> 269 // </HEAD> 270 HTMLOutFuncs::Out_AsciiTag( Strm(), sHTML_html ) << sNewLine; 271 HTMLOutFuncs::Out_AsciiTag( Strm(), sHTML_head ); 272 273 Out_DocInfo( Strm(), &pDoc->GetDocInfo(), "\t", eDestEnc ); 274 Strm() << sNewLine; 275 HTMLOutFuncs::Out_AsciiTag( Strm(), sHTML_head, sal_False ) << sNewLine; 276 277 //! OutScript(); // Hier fehlen noch die Scripten im Header 278 } 279 */ 280 281 void SfxFrameHTMLWriter::Out_FrameDescriptor( 282 SvStream& rOut, const String& rBaseURL, const uno::Reference < beans::XPropertySet >& xSet, 283 rtl_TextEncoding eDestEnc, String *pNonConvertableChars ) 284 { 285 try 286 { 287 ByteString sOut; 288 ::rtl::OUString aStr; 289 uno::Any aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("FrameURL") ); 290 if ( (aAny >>= aStr) && aStr.getLength() ) 291 { 292 String aURL = INetURLObject( aStr ).GetMainURL( INetURLObject::DECODE_TO_IURI ); 293 if( aURL.Len() ) 294 { 295 aURL = URIHelper::simpleNormalizedMakeRelative( 296 rBaseURL, aURL ); 297 ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_src) += "=\""; 298 rOut << sOut.GetBuffer(); 299 HTMLOutFuncs::Out_String( rOut, aURL, eDestEnc, pNonConvertableChars ); 300 sOut = '\"'; 301 } 302 } 303 304 aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("FrameName") ); 305 if ( (aAny >>= aStr) && aStr.getLength() ) 306 { 307 ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_name) += "=\""; 308 rOut << sOut.GetBuffer(); 309 HTMLOutFuncs::Out_String( rOut, aStr, eDestEnc, pNonConvertableChars ); 310 sOut = '\"'; 311 } 312 313 sal_Int32 nVal = SIZE_NOT_SET; 314 aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("FrameMarginWidth") ); 315 if ( (aAny >>= nVal) && nVal != SIZE_NOT_SET ) 316 (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_marginwidth) += '=') += ByteString::CreateFromInt32( nVal ); 317 aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("FrameMarginHeight") ); 318 if ( (aAny >>= nVal) && nVal != SIZE_NOT_SET ) 319 (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_marginheight) += '=') += ByteString::CreateFromInt32( nVal ); 320 321 sal_Bool bVal = sal_True; 322 aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("FrameIsAutoScroll") ); 323 if ( (aAny >>= bVal) && !bVal ) 324 { 325 aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("FrameIsScrollingMode") ); 326 if ( aAny >>= bVal ) 327 { 328 const sal_Char *pStr = bVal ? sHTML_SC_yes : sHTML_SC_no; 329 (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_scrolling) += '=') += pStr; 330 } 331 } 332 333 // frame border (MS+Netscape-Erweiterung) 334 aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("FrameIsAutoBorder") ); 335 if ( (aAny >>= bVal) && !bVal ) 336 { 337 aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("FrameIsBorder") ); 338 if ( aAny >>= bVal ) 339 { 340 const char* pStr = bVal ? sHTML_SC_yes : sHTML_SC_no; 341 (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_frameborder) += '=') += pStr; 342 } 343 } 344 345 // TODO/LATER: currently not supported attributes 346 // resize 347 //if( !pFrame->IsResizable() ) 348 // (sOut += ' ') += sHTML_O_noresize; 349 // 350 //if ( pFrame->GetWallpaper() ) 351 //{ 352 // ((sOut += ' ') += sHTML_O_bordercolor) += '='; 353 // rOut << sOut.GetBuffer(); 354 // HTMLOutFuncs::Out_Color( rOut, pFrame->GetWallpaper()->GetColor(), eDestEnc ); 355 //} 356 //else 357 rOut << sOut.GetBuffer(); 358 } 359 catch ( uno::Exception& ) 360 { 361 } 362 } 363 364 String SfxFrameHTMLWriter::CreateURL( SfxFrame* pFrame ) 365 { 366 String aRet; 367 SfxObjectShell* pShell = pFrame->GetCurrentDocument(); 368 if( !aRet.Len() && pShell ) 369 { 370 aRet = pShell->GetMedium()->GetName(); 371 //!(dv) CntAnchor::ToPresentationURL( aRet ); 372 } 373 374 return aRet; 375 } 376 377 378