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_starmath.hxx" 26 27 #include "smdetect.hxx" 28 29 //#include <framework/interaction.hxx> 30 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 31 #include <com/sun/star/beans/PropertyValue.hpp> 32 #include <com/sun/star/frame/XFrame.hpp> 33 #include <com/sun/star/frame/XModel.hpp> 34 #include <com/sun/star/awt/XWindow.hpp> 35 #include <com/sun/star/lang/XUnoTunnel.hpp> 36 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX 37 #include <comphelper/processfactory.hxx> 38 #endif 39 #include <com/sun/star/beans/PropertyValue.hpp> 40 #include <com/sun/star/io/XInputStream.hpp> 41 #include <com/sun/star/task/XInteractionHandler.hpp> 42 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> 43 #include <com/sun/star/ucb/CommandAbortedException.hpp> 44 #include <com/sun/star/ucb/InteractiveAppException.hpp> 45 #include <com/sun/star/ucb/XContent.hpp> 46 #include <com/sun/star/packages/zip/ZipIOException.hpp> 47 #include <framework/interaction.hxx> 48 49 #ifndef _TOOLKIT_UNOHLP_HXX 50 #include <toolkit/helper/vclunohelper.hxx> 51 #endif 52 #include <ucbhelper/simpleinteractionrequest.hxx> 53 54 #include <rtl/ustring.h> 55 #include <rtl/logfile.hxx> 56 #include <svl/itemset.hxx> 57 #include <vcl/window.hxx> 58 #include <svl/eitem.hxx> 59 #include <svl/stritem.hxx> 60 #include <tools/urlobj.hxx> 61 #include <vos/mutex.hxx> 62 #include <svtools/sfxecode.hxx> 63 #include <svtools/ehdl.hxx> 64 #include <sot/storinfo.hxx> 65 #include <vcl/svapp.hxx> 66 #include <sfx2/app.hxx> 67 #include <sfx2/sfxsids.hrc> 68 #include <sfx2/request.hxx> 69 #include <sfx2/docfile.hxx> 70 #include <sfx2/docfilt.hxx> 71 #include <sfx2/fcontnr.hxx> 72 #include <sfx2/brokenpackageint.hxx> 73 74 #include "document.hxx" 75 #include "eqnolefilehdr.hxx" 76 77 using namespace ::com::sun::star; 78 using namespace ::com::sun::star::uno; 79 using namespace ::com::sun::star::io; 80 using namespace ::com::sun::star::frame; 81 using namespace ::com::sun::star::task; 82 using namespace ::com::sun::star::beans; 83 using namespace ::com::sun::star::lang; 84 using namespace ::com::sun::star::ucb; 85 using namespace ::rtl; 86 87 SmFilterDetect::SmFilterDetect( const REFERENCE < ::com::sun::star::lang::XMultiServiceFactory >& /*xFactory*/ ) 88 { 89 } 90 91 SmFilterDetect::~SmFilterDetect() 92 { 93 } 94 95 ::rtl::OUString SAL_CALL SmFilterDetect::detect( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lDescriptor ) throw( ::com::sun::star::uno::RuntimeException ) 96 { 97 REFERENCE< XInputStream > xStream; 98 REFERENCE< XContent > xContent; 99 REFERENCE< XInteractionHandler > xInteraction; 100 String aURL; 101 ::rtl::OUString sTemp; 102 String aTypeName; // a name describing the type (from MediaDescriptor, usually from flat detection) 103 String aPreselectedFilterName; // a name describing the filter to use (from MediaDescriptor, usually from UI action) 104 105 ::rtl::OUString aDocumentTitle; // interesting only if set in this method 106 107 // opening as template is done when a parameter tells to do so and a template filter can be detected 108 // (otherwise no valid filter would be found) or if the detected filter is a template filter and 109 // there is no parameter that forbids to open as template 110 sal_Bool bOpenAsTemplate = sal_False; 111 sal_Bool bWasReadOnly = sal_False, bReadOnly = sal_False; 112 113 sal_Bool bRepairPackage = sal_False; 114 sal_Bool bRepairAllowed = sal_False; 115 116 // now some parameters that can already be in the array, but may be overwritten or new inserted here 117 // remember their indices in the case new values must be added to the array 118 sal_Int32 nPropertyCount = lDescriptor.getLength(); 119 sal_Int32 nIndexOfFilterName = -1; 120 sal_Int32 nIndexOfInputStream = -1; 121 sal_Int32 nIndexOfContent = -1; 122 sal_Int32 nIndexOfReadOnlyFlag = -1; 123 sal_Int32 nIndexOfTemplateFlag = -1; 124 sal_Int32 nIndexOfDocumentTitle = -1; 125 126 for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty ) 127 { 128 // extract properties 129 if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("URL")) ) 130 { 131 lDescriptor[nProperty].Value >>= sTemp; 132 aURL = sTemp; 133 } 134 else if( !aURL.Len() && lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("FileName")) ) 135 { 136 lDescriptor[nProperty].Value >>= sTemp; 137 aURL = sTemp; 138 } 139 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("TypeName")) ) 140 { 141 lDescriptor[nProperty].Value >>= sTemp; 142 aTypeName = sTemp; 143 } 144 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("FilterName")) ) 145 { 146 lDescriptor[nProperty].Value >>= sTemp; 147 aPreselectedFilterName = sTemp; 148 149 // if the preselected filter name is not correct, it must be erased after detection 150 // remember index of property to get access to it later 151 nIndexOfFilterName = nProperty; 152 } 153 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("InputStream")) ) 154 nIndexOfInputStream = nProperty; 155 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("ReadOnly")) ) 156 nIndexOfReadOnlyFlag = nProperty; 157 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("UCBContent")) ) 158 nIndexOfContent = nProperty; 159 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("AsTemplate")) ) 160 { 161 lDescriptor[nProperty].Value >>= bOpenAsTemplate; 162 nIndexOfTemplateFlag = nProperty; 163 } 164 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("InteractionHandler")) ) 165 lDescriptor[nProperty].Value >>= xInteraction; 166 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("RepairPackage")) ) 167 lDescriptor[nProperty].Value >>= bRepairPackage; 168 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentTitle")) ) 169 nIndexOfDocumentTitle = nProperty; 170 } 171 172 // can't check the type for external filters, so set the "dont" flag accordingly 173 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 174 //SfxFilterFlags nMust = SFX_FILTER_IMPORT, nDont = SFX_FILTER_NOTINSTALLED; 175 176 SfxApplication* pApp = SFX_APP(); 177 SfxAllItemSet *pSet = new SfxAllItemSet( pApp->GetPool() ); 178 TransformParameters( SID_OPENDOC, lDescriptor, *pSet ); 179 SFX_ITEMSET_ARG( pSet, pItem, SfxBoolItem, SID_DOC_READONLY, sal_False ); 180 181 bWasReadOnly = pItem && pItem->GetValue(); 182 183 String aFilterName; 184 String aPrefix = String::CreateFromAscii( "private:factory/" ); 185 if( aURL.Match( aPrefix ) == aPrefix.Len() ) 186 { 187 const SfxFilter* pFilter = 0; 188 String aPattern( aPrefix ); 189 aPattern += String::CreateFromAscii("smath"); 190 if ( aURL.Match( aPattern ) >= aPattern.Len() ) 191 { 192 pFilter = SfxFilter::GetDefaultFilterFromFactory( aURL ); 193 aTypeName = pFilter->GetTypeName(); 194 aFilterName = pFilter->GetName(); 195 } 196 } 197 else 198 { 199 // ctor of SfxMedium uses owner transition of ItemSet 200 SfxMedium aMedium( aURL, bWasReadOnly ? STREAM_STD_READ : STREAM_STD_READWRITE, sal_False, NULL, pSet ); 201 aMedium.UseInteractionHandler( sal_True ); 202 203 sal_Bool bIsStorage = aMedium.IsStorage(); 204 if ( aMedium.GetErrorCode() == ERRCODE_NONE ) 205 { 206 // remember input stream and content and put them into the descriptor later 207 // should be done here since later the medium can switch to a version 208 xStream = aMedium.GetInputStream(); 209 xContent = aMedium.GetContent(); 210 bReadOnly = aMedium.IsReadOnly(); 211 212 if ( bIsStorage ) 213 { 214 //TODO/LATER: factor this out! 215 uno::Reference < embed::XStorage > xStorage = aMedium.GetStorage( sal_False ); 216 if ( aMedium.GetLastStorageCreationState() != ERRCODE_NONE ) 217 { 218 // error during storage creation means _here_ that the medium 219 // is broken, but we can not handle it in medium since unpossibility 220 // to create a storage does not _always_ means that the medium is broken 221 aMedium.SetError( aMedium.GetLastStorageCreationState(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 222 if ( xInteraction.is() ) 223 { 224 OUString empty; 225 try 226 { 227 InteractiveAppException xException( empty, 228 REFERENCE< XInterface >(), 229 InteractionClassification_ERROR, 230 aMedium.GetError() ); 231 232 REFERENCE< XInteractionRequest > xRequest( 233 new ucbhelper::SimpleInteractionRequest( makeAny( xException ), 234 ucbhelper::CONTINUATION_APPROVE ) ); 235 xInteraction->handle( xRequest ); 236 } 237 catch ( Exception & ) {}; 238 } 239 } 240 else 241 { 242 aFilterName.Erase(); 243 244 try 245 { 246 const SfxFilter* pFilter = aPreselectedFilterName.Len() ? 247 SfxFilterMatcher().GetFilter4FilterName( aPreselectedFilterName ) : aTypeName.Len() ? 248 SfxFilterMatcher(String::CreateFromAscii("smath")).GetFilter4EA( aTypeName ) : 0; 249 String aTmpFilterName; 250 if ( pFilter ) 251 aTmpFilterName = pFilter->GetName(); 252 aTypeName = SfxFilter::GetTypeFromStorage( xStorage, pFilter ? pFilter->IsAllowedAsTemplate() : sal_False, &aTmpFilterName ); 253 } 254 catch( lang::WrappedTargetException& aWrap ) 255 { 256 packages::zip::ZipIOException aZipException; 257 258 // repairing is done only if this type is requested from outside 259 if ( ( aWrap.TargetException >>= aZipException ) && aTypeName.Len() ) 260 { 261 if ( xInteraction.is() ) 262 { 263 // the package is broken one 264 aDocumentTitle = aMedium.GetURLObject().getName( 265 INetURLObject::LAST_SEGMENT, 266 true, 267 INetURLObject::DECODE_WITH_CHARSET ); 268 269 if ( !bRepairPackage ) 270 { 271 // ask the user whether he wants to try to repair 272 RequestPackageReparation aRequest( aDocumentTitle ); 273 xInteraction->handle( aRequest.GetRequest() ); 274 bRepairAllowed = aRequest.isApproved(); 275 } 276 277 if ( !bRepairAllowed ) 278 { 279 // repair either not allowed or not successful 280 NotifyBrokenPackage aNotifyRequest( aDocumentTitle ); 281 xInteraction->handle( aNotifyRequest.GetRequest() ); 282 } 283 } 284 285 if ( !bRepairAllowed ) 286 aTypeName.Erase(); 287 } 288 } 289 catch( uno::RuntimeException& ) 290 { 291 throw; 292 } 293 catch( uno::Exception& ) 294 { 295 aTypeName.Erase(); 296 } 297 298 if ( aTypeName.Len() ) 299 { 300 const SfxFilter* pFilter = 301 SfxFilterMatcher( String::CreateFromAscii("smath") ).GetFilter4EA( aTypeName ); 302 if ( pFilter ) 303 aFilterName = pFilter->GetName(); 304 } 305 } 306 } 307 else 308 { 309 // DesignScience Equation Editor MathType 3.0 ? 310 SvStream *pStrm = aMedium.GetInStream(); 311 aTypeName.Erase(); 312 if (pStrm && !pStrm->GetError()) 313 { 314 SotStorageRef aStorage = new SotStorage ( pStrm, sal_False ); 315 if ( !aStorage->GetError() ) 316 { 317 if ( aStorage->IsStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Equation Native" ) ) ) ) 318 { 319 sal_uInt8 nVersion; 320 if (GetMathTypeVersion( aStorage, nVersion ) && nVersion <=3) 321 aTypeName.AssignAscii( "math_MathType_3x" ); 322 } 323 } 324 else 325 { 326 // MathML? The SAX parser expects the 'math' root element incl. 327 // the namespace URL. Neither '<?xml' prolog nor <!doctype is needed. 328 // If the math element has a prefix (e.g. <bla:math), the 329 // prefix has to be defined in the namespace attribut 330 // (e.g. xmlns:bla="http://www.w3.org/1998/Math/MathML") 331 // #124636 is fixed too. 332 pStrm->Seek( STREAM_SEEK_TO_BEGIN ); 333 const size_t nBufSize=2048; 334 sal_uInt16 aBuffer[nBufSize]; // will be casted to an Unicode-Array below 335 sal_uInt8* pByte = reinterpret_cast<sal_uInt8*>(aBuffer); 336 const sal_uLong nBytesRead(pStrm->Read( pByte, nBufSize * 2 ) ); 337 const sal_uLong nUnicodeCharsRead (nBytesRead / 2 ); 338 339 // For backwards searching an OUString is used. The conversion needs an 340 // encoding information. Default encoding is UTF-8, UTF-16 is possible 341 // (e.g. from MS "Math Input Control"), others are unlikely. 342 // Looking for Byte Order Mark 343 rtl_TextEncoding aEncoding = RTL_TEXTENCODING_UTF8; 344 bool bIsUnicode = false; 345 if (nBytesRead >= 2 && (aBuffer[0]==0xfffe || aBuffer[0]==0xfeff) ) 346 { 347 aEncoding = RTL_TEXTENCODING_UNICODE; 348 bIsUnicode = true; 349 if ( aBuffer[0] == 0xfffe) 350 { //swap bytes to make Big Endian 351 for (size_t i=0; i < nUnicodeCharsRead; ++i) 352 { 353 aBuffer[i] = (aBuffer[i]>>8) | (aBuffer[i]<<8) ; 354 } 355 } 356 } 357 358 bool isMathFile(false); 359 if ( nBytesRead > 56) // minimal <math xmlns="http://www.w3.org/1998/Math/MathML"></math> 360 { 361 const sal_Char* pChar = reinterpret_cast<sal_Char*>(aBuffer); 362 sal_Unicode* pUnicode = (sal_Unicode*) aBuffer; 363 364 const OUString sFragment( (bIsUnicode) 365 ? OUString( pUnicode , nUnicodeCharsRead ) 366 : OUString( pChar, nBytesRead, aEncoding) ); 367 const sal_Int32 nFragmentLength(sFragment.getLength()); 368 369 // look for MathML URL http://www.w3.org/1998/Math/MathML 370 // #i53509 A MathML URL can be value of a namespace attribute, but can be as well 371 // inside a doctype e.g. [<!ENTITY mathml 'http://www.w3.org/1998/Math/MathML'>] 372 // or inside a schema reference e.g. s:schemaLocation="http://www.w3.org/1998/Math/MathML" 373 // Use a loop to get the correct one. 374 const OUString sURL( OUString::createFromAscii("http://www.w3.org/1998/Math/MathML")); 375 const sal_Int32 nURLLength = sURL.getLength(); 376 const OUString sEQ( OUString::createFromAscii("=") ); 377 const OUString sXMLNS( OUString::createFromAscii("xmlns") ); 378 sal_Int32 nPosURL = -1; // for index of first character of URL 379 sal_Int32 nPosURLSearchStart = 0; 380 sal_Int32 nPosEQ = -1; // for index of equal sign 381 sal_Int32 nPosXMLNS = -1; // for index of first character of string "xmlns" 382 do 383 { 384 nPosURL = sFragment.indexOf(sURL,nPosURLSearchStart); 385 if( nPosURL < 0 ) 386 { 387 break; // no MathML URL, cannot be parsed 388 } 389 // need 'xmlns:prefix =' or 'xmlns =', look backwards, first for equal sign 390 nPosEQ = sFragment.lastIndexOf(sEQ,nPosURL); 391 if (nPosEQ >= 0 && nPosEQ >= nPosURLSearchStart) 392 { 393 nPosXMLNS = sFragment.lastIndexOf(sXMLNS,nPosEQ); 394 if( nPosXMLNS >= nPosURLSearchStart ) 395 { // an xmlns attribute is found, but it might belong to a schema 396 // get prefix if present 397 const OUString sPrefix = (sFragment.copy(nPosXMLNS+5,nPosEQ-(nPosXMLNS+5))).trim(); 398 // such prefix definition must start with colon (will be removed below) 399 bool bHasPrefix( (sPrefix.isEmpty()) ? false : sPrefix.toChar() == sal_Unicode(':') ); 400 // the math element starts either with '<prefix:math' or '<math' 401 const OUString sMathStart( (bHasPrefix) 402 ? OUString::createFromAscii("<") + sPrefix.copy(1,sPrefix.getLength()-1) + OUString::createFromAscii(":math") 403 : OUString::createFromAscii("<math") ); 404 sal_Int32 nPosMath (sFragment.lastIndexOf(sMathStart,nPosXMLNS)); 405 if( nPosMath >= 0) 406 { // xmlns attribute belongs to math element 407 isMathFile = true; 408 break; 409 } 410 } 411 } 412 // MathML URL was wrong one, look for next 413 nPosURLSearchStart = nPosURL + nURLLength; 414 } 415 while ( nPosURLSearchStart + nURLLength <= nFragmentLength); 416 417 if(isMathFile) 418 { 419 static const sal_Char sFltrNm_2[] = MATHML_XML; 420 static const sal_Char sTypeNm_2[] = "math_MathML_XML_Math"; 421 422 aFilterName.AssignAscii( sFltrNm_2 ); 423 aTypeName.AssignAscii( sTypeNm_2 ); 424 } 425 } 426 } 427 428 if ( aTypeName.Len() ) 429 { 430 const SfxFilter* pFilt = SfxFilterMatcher( String::CreateFromAscii("smath") ).GetFilter4EA( aTypeName ); 431 if ( pFilt ) 432 aFilterName = pFilt->GetName(); 433 } 434 } 435 } 436 } 437 } 438 439 if ( nIndexOfInputStream == -1 && xStream.is() ) 440 { 441 // if input stream wasn't part of the descriptor, now it should be, otherwise the content would be opend twice 442 lDescriptor.realloc( nPropertyCount + 1 ); 443 lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("InputStream"); 444 lDescriptor[nPropertyCount].Value <<= xStream; 445 nPropertyCount++; 446 } 447 448 if ( nIndexOfContent == -1 && xContent.is() ) 449 { 450 // if input stream wasn't part of the descriptor, now it should be, otherwise the content would be opend twice 451 lDescriptor.realloc( nPropertyCount + 1 ); 452 lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("UCBContent"); 453 lDescriptor[nPropertyCount].Value <<= xContent; 454 nPropertyCount++; 455 } 456 457 if ( bReadOnly != bWasReadOnly ) 458 { 459 if ( nIndexOfReadOnlyFlag == -1 ) 460 { 461 lDescriptor.realloc( nPropertyCount + 1 ); 462 lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("ReadOnly"); 463 lDescriptor[nPropertyCount].Value <<= bReadOnly; 464 nPropertyCount++; 465 } 466 else 467 lDescriptor[nIndexOfReadOnlyFlag].Value <<= bReadOnly; 468 } 469 470 if ( !bRepairPackage && bRepairAllowed ) 471 { 472 lDescriptor.realloc( nPropertyCount + 1 ); 473 lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("RepairPackage"); 474 lDescriptor[nPropertyCount].Value <<= bRepairAllowed; 475 nPropertyCount++; 476 477 bOpenAsTemplate = sal_True; 478 479 // TODO/LATER: set progress bar that should be used 480 } 481 482 if ( bOpenAsTemplate ) 483 { 484 if ( nIndexOfTemplateFlag == -1 ) 485 { 486 lDescriptor.realloc( nPropertyCount + 1 ); 487 lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("AsTemplate"); 488 lDescriptor[nPropertyCount].Value <<= bOpenAsTemplate; 489 nPropertyCount++; 490 } 491 else 492 lDescriptor[nIndexOfTemplateFlag].Value <<= bOpenAsTemplate; 493 } 494 495 if ( aDocumentTitle.getLength() ) 496 { 497 // the title was set here 498 if ( nIndexOfDocumentTitle == -1 ) 499 { 500 lDescriptor.realloc( nPropertyCount + 1 ); 501 lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("DocumentTitle"); 502 lDescriptor[nPropertyCount].Value <<= aDocumentTitle; 503 nPropertyCount++; 504 } 505 else 506 lDescriptor[nIndexOfDocumentTitle].Value <<= aDocumentTitle; 507 } 508 509 if ( !aFilterName.Len() ) 510 aTypeName.Erase(); 511 512 return aTypeName; 513 } 514 515 SFX_IMPL_SINGLEFACTORY( SmFilterDetect ) 516 517 /* XServiceInfo */ 518 UNOOUSTRING SAL_CALL SmFilterDetect::getImplementationName() throw( UNORUNTIMEEXCEPTION ) 519 { 520 return impl_getStaticImplementationName(); 521 } 522 \ 523 /* XServiceInfo */ 524 sal_Bool SAL_CALL SmFilterDetect::supportsService( const UNOOUSTRING& sServiceName ) throw( UNORUNTIMEEXCEPTION ) 525 { 526 UNOSEQUENCE< UNOOUSTRING > seqServiceNames = getSupportedServiceNames(); 527 const UNOOUSTRING* pArray = seqServiceNames.getConstArray(); 528 for ( sal_Int32 nCounter=0; nCounter<seqServiceNames.getLength(); nCounter++ ) 529 { 530 if ( pArray[nCounter] == sServiceName ) 531 { 532 return sal_True ; 533 } 534 } 535 return sal_False ; 536 } 537 538 /* XServiceInfo */ 539 UNOSEQUENCE< UNOOUSTRING > SAL_CALL SmFilterDetect::getSupportedServiceNames() throw( UNORUNTIMEEXCEPTION ) 540 { 541 return impl_getStaticSupportedServiceNames(); 542 } 543 544 /* Helper for XServiceInfo */ 545 UNOSEQUENCE< UNOOUSTRING > SmFilterDetect::impl_getStaticSupportedServiceNames() 546 { 547 UNOMUTEXGUARD aGuard( UNOMUTEX::getGlobalMutex() ); 548 UNOSEQUENCE< UNOOUSTRING > seqServiceNames( 1 ); 549 seqServiceNames.getArray() [0] = UNOOUSTRING::createFromAscii( "com.sun.star.frame.ExtendedTypeDetection" ); 550 return seqServiceNames ; 551 } 552 553 /* Helper for XServiceInfo */ 554 UNOOUSTRING SmFilterDetect::impl_getStaticImplementationName() 555 { 556 return UNOOUSTRING::createFromAscii( "com.sun.star.comp.math.FormatDetector" ); 557 } 558 559 /* Helper for registry */ 560 UNOREFERENCE< UNOXINTERFACE > SAL_CALL SmFilterDetect::impl_createInstance( const UNOREFERENCE< UNOXMULTISERVICEFACTORY >& xServiceManager ) throw( UNOEXCEPTION ) 561 { 562 return UNOREFERENCE< UNOXINTERFACE >( *new SmFilterDetect( xServiceManager ) ); 563 } 564 565