00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "precompiled_starmath.hxx"
00038
00039 #include "smdetect.hxx"
00040
00041 #include <framework/interaction.hxx>
00042
00043 #ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
00044 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
00045 #endif
00046 #ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
00047 #include <com/sun/star/beans/PropertyValue.hpp>
00048 #endif
00049 #ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
00050 #include <com/sun/star/frame/XFrame.hpp>
00051 #endif
00052 #ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
00053 #include <com/sun/star/frame/XModel.hpp>
00054 #endif
00055 #ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
00056 #include <com/sun/star/awt/XWindow.hpp>
00057 #endif
00058 #ifndef _COM_SUN_STAR_LANG_XUNOTUNNEL_HPP_
00059 #include <com/sun/star/lang/XUnoTunnel.hpp>
00060 #endif
00061 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX
00062 #include <comphelper/processfactory.hxx>
00063 #endif
00064 #ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
00065 #include <com/sun/star/beans/PropertyValue.hpp>
00066 #endif
00067 #ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
00068 #include <com/sun/star/io/XInputStream.hpp>
00069 #endif
00070 #ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_
00071 #include <com/sun/star/task/XInteractionHandler.hpp>
00072 #endif
00073 #ifndef _COM_SUN_STAR_LANG_WRAPPEDTARGETRUNTIMEEXCEPTION_HPP_
00074 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
00075 #endif
00076 #ifndef _COM_SUN_STAR_UCB_COMMANDABORTEDEXCEPTION_HPP_
00077 #include <com/sun/star/ucb/CommandAbortedException.hpp>
00078 #endif
00079 #ifndef _COM_SUN_STAR_UCB_INTERACTIVEAPPEXCEPTION_HPP_
00080 #include <com/sun/star/ucb/InteractiveAppException.hpp>
00081 #endif
00082 #ifndef _COM_SUN_STAR_UCB_XCONTENT_HPP_
00083 #include <com/sun/star/ucb/XContent.hpp>
00084 #endif
00085 #ifndef _COM_SUN_STAR_PACKAGES_ZIP_ZIPIOEXCEPTION_HPP_
00086 #include <com/sun/star/packages/zip/ZipIOException.hpp>
00087 #endif
00088
00089 #ifndef __FRAMEWORK_DISPATCH_INTERACTION_HXX_
00090 #include <framework/interaction.hxx>
00091 #endif
00092
00093 #ifndef _TOOLKIT_UNOHLP_HXX
00094 #include <toolkit/helper/vclunohelper.hxx>
00095 #endif
00096
00097 #ifndef _UCBHELPER_SIMPLEINTERACTIONREQUEST_HXX
00098 #include <ucbhelper/simpleinteractionrequest.hxx>
00099 #endif
00100
00101 #include <rtl/ustring.h>
00102 #include <rtl/logfile.hxx>
00103 #include <svtools/itemset.hxx>
00104 #include <vcl/window.hxx>
00105 #include <svtools/eitem.hxx>
00106 #include <svtools/stritem.hxx>
00107 #include <tools/urlobj.hxx>
00108 #include <vos/mutex.hxx>
00109 #include <svtools/sfxecode.hxx>
00110 #include <svtools/ehdl.hxx>
00111 #include <sot/storinfo.hxx>
00112 #include <vcl/svapp.hxx>
00113 #include <sfx2/app.hxx>
00114 #include <sfx2/sfxsids.hrc>
00115 #include <sfx2/request.hxx>
00116 #include <sfx2/docfile.hxx>
00117 #include <sfx2/docfilt.hxx>
00118 #include <sfx2/fcontnr.hxx>
00119 #include <sfx2/brokenpackageint.hxx>
00120
00121 #include "document.hxx"
00122 #ifndef __EQNOLEFILEHDR_HXX__
00123 #include "eqnolefilehdr.hxx"
00124 #endif
00125
00126
00127 using namespace ::com::sun::star;
00128 using namespace ::com::sun::star::uno;
00129 using namespace ::com::sun::star::io;
00130 using namespace ::com::sun::star::frame;
00131 using namespace ::com::sun::star::task;
00132 using namespace ::com::sun::star::beans;
00133 using namespace ::com::sun::star::lang;
00134 using namespace ::com::sun::star::ucb;
00135 using namespace ::rtl;
00136
00137 SmFilterDetect::SmFilterDetect( const REFERENCE < ::com::sun::star::lang::XMultiServiceFactory >& )
00138 {
00139 }
00140
00141 SmFilterDetect::~SmFilterDetect()
00142 {
00143 }
00144
00145 ::rtl::OUString SAL_CALL SmFilterDetect::detect( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lDescriptor ) throw( ::com::sun::star::uno::RuntimeException )
00146 {
00147 REFERENCE< XInputStream > xStream;
00148 REFERENCE< XContent > xContent;
00149 REFERENCE< XInteractionHandler > xInteraction;
00150 String aURL;
00151 ::rtl::OUString sTemp;
00152 String aTypeName;
00153 String aPreselectedFilterName;
00154
00155 ::rtl::OUString aDocumentTitle;
00156
00157
00158
00159
00160 sal_Bool bOpenAsTemplate = sal_False;
00161 sal_Bool bWasReadOnly = sal_False, bReadOnly = sal_False;
00162
00163 sal_Bool bRepairPackage = sal_False;
00164 sal_Bool bRepairAllowed = sal_False;
00165
00166
00167
00168 sal_Int32 nPropertyCount = lDescriptor.getLength();
00169 sal_Int32 nIndexOfFilterName = -1;
00170 sal_Int32 nIndexOfInputStream = -1;
00171 sal_Int32 nIndexOfContent = -1;
00172 sal_Int32 nIndexOfReadOnlyFlag = -1;
00173 sal_Int32 nIndexOfTemplateFlag = -1;
00174 sal_Int32 nIndexOfDocumentTitle = -1;
00175
00176 for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty )
00177 {
00178
00179 if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("URL")) )
00180 {
00181 lDescriptor[nProperty].Value >>= sTemp;
00182 aURL = sTemp;
00183 }
00184 else if( !aURL.Len() && lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("FileName")) )
00185 {
00186 lDescriptor[nProperty].Value >>= sTemp;
00187 aURL = sTemp;
00188 }
00189 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("TypeName")) )
00190 {
00191 lDescriptor[nProperty].Value >>= sTemp;
00192 aTypeName = sTemp;
00193 }
00194 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("FilterName")) )
00195 {
00196 lDescriptor[nProperty].Value >>= sTemp;
00197 aPreselectedFilterName = sTemp;
00198
00199
00200
00201 nIndexOfFilterName = nProperty;
00202 }
00203 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("InputStream")) )
00204 nIndexOfInputStream = nProperty;
00205 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("ReadOnly")) )
00206 nIndexOfReadOnlyFlag = nProperty;
00207 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("UCBContent")) )
00208 nIndexOfContent = nProperty;
00209 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("AsTemplate")) )
00210 {
00211 lDescriptor[nProperty].Value >>= bOpenAsTemplate;
00212 nIndexOfTemplateFlag = nProperty;
00213 }
00214 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("InteractionHandler")) )
00215 lDescriptor[nProperty].Value >>= xInteraction;
00216 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("RapairPackage")) )
00217 lDescriptor[nProperty].Value >>= bRepairPackage;
00218 else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentTitle")) )
00219 nIndexOfDocumentTitle = nProperty;
00220 }
00221
00222
00223 ::vos::OGuard aGuard( Application::GetSolarMutex() );
00224
00225
00226 SfxApplication* pApp = SFX_APP();
00227 SfxAllItemSet *pSet = new SfxAllItemSet( pApp->GetPool() );
00228 TransformParameters( SID_OPENDOC, lDescriptor, *pSet );
00229 SFX_ITEMSET_ARG( pSet, pItem, SfxBoolItem, SID_DOC_READONLY, FALSE );
00230
00231 bWasReadOnly = pItem && pItem->GetValue();
00232
00233 String aFilterName;
00234 String aPrefix = String::CreateFromAscii( "private:factory/" );
00235 if( aURL.Match( aPrefix ) == aPrefix.Len() )
00236 {
00237 const SfxFilter* pFilter = 0;
00238 String aPattern( aPrefix );
00239 aPattern += String::CreateFromAscii("smath");
00240 if ( aURL.Match( aPattern ) >= aPattern.Len() )
00241 {
00242 pFilter = SfxFilter::GetDefaultFilterFromFactory( aURL );
00243 aTypeName = pFilter->GetTypeName();
00244 aFilterName = pFilter->GetName();
00245 }
00246 }
00247 else
00248 {
00249
00250 SfxMedium aMedium( aURL, bWasReadOnly ? STREAM_STD_READ : STREAM_STD_READWRITE, FALSE, NULL, pSet );
00251 aMedium.UseInteractionHandler( TRUE );
00252
00253 BOOL bIsStorage = aMedium.IsStorage();
00254 if ( aMedium.GetErrorCode() == ERRCODE_NONE )
00255 {
00256
00257
00258 xStream = aMedium.GetInputStream();
00259 xContent = aMedium.GetContent();
00260 bReadOnly = aMedium.IsReadOnly();
00261
00262 if ( bIsStorage )
00263 {
00264
00265 uno::Reference < embed::XStorage > xStorage = aMedium.GetStorage();
00266 if ( aMedium.GetLastStorageCreationState() != ERRCODE_NONE )
00267 {
00268
00269
00270
00271 aMedium.SetError( aMedium.GetLastStorageCreationState() );
00272 if ( xInteraction.is() )
00273 {
00274 OUString empty;
00275 try
00276 {
00277 InteractiveAppException xException( empty,
00278 REFERENCE< XInterface >(),
00279 InteractionClassification_ERROR,
00280 aMedium.GetError() );
00281
00282 REFERENCE< XInteractionRequest > xRequest(
00283 new ucbhelper::SimpleInteractionRequest( makeAny( xException ),
00284 ucbhelper::CONTINUATION_APPROVE ) );
00285 xInteraction->handle( xRequest );
00286 }
00287 catch ( Exception & ) {};
00288 }
00289 }
00290 else
00291 {
00292 aFilterName.Erase();
00293
00294 try
00295 {
00296 const SfxFilter* pFilter = aPreselectedFilterName.Len() ?
00297 SfxFilterMatcher().GetFilter4FilterName( aPreselectedFilterName ) : aTypeName.Len() ?
00298 SfxFilterMatcher(String::CreateFromAscii("smath")).GetFilter4EA( aTypeName ) : 0;
00299 String aTmpFilterName;
00300 if ( pFilter )
00301 aTmpFilterName = pFilter->GetName();
00302 aTypeName = SfxFilter::GetTypeFromStorage( xStorage, pFilter ? pFilter->IsAllowedAsTemplate() : FALSE, &aTmpFilterName );
00303 }
00304 catch( lang::WrappedTargetException& aWrap )
00305 {
00306 packages::zip::ZipIOException aZipException;
00307
00308
00309 if ( ( aWrap.TargetException >>= aZipException ) && aTypeName.Len() )
00310 {
00311 if ( xInteraction.is() )
00312 {
00313
00314 aDocumentTitle = aMedium.GetURLObject().getName(
00315 INetURLObject::LAST_SEGMENT,
00316 true,
00317 INetURLObject::DECODE_WITH_CHARSET );
00318
00319 if ( !bRepairPackage )
00320 {
00321
00322 RequestPackageReparation* pRequest = new RequestPackageReparation( aDocumentTitle );
00323 uno::Reference< task::XInteractionRequest > xRequest ( pRequest );
00324
00325 xInteraction->handle( xRequest );
00326
00327 bRepairAllowed = pRequest->isApproved();
00328 }
00329
00330 if ( !bRepairAllowed )
00331 {
00332
00333 NotifyBrokenPackage* pNotifyRequest = new NotifyBrokenPackage( aDocumentTitle );
00334 uno::Reference< task::XInteractionRequest > xRequest ( pNotifyRequest );
00335 xInteraction->handle( xRequest );
00336 }
00337 }
00338
00339 if ( !bRepairAllowed )
00340 aTypeName.Erase();
00341 }
00342 }
00343 catch( uno::RuntimeException& )
00344 {
00345 throw;
00346 }
00347 catch( uno::Exception& )
00348 {
00349 aTypeName.Erase();
00350 }
00351
00352 if ( aTypeName.Len() )
00353 {
00354 const SfxFilter* pFilter =
00355 SfxFilterMatcher( String::CreateFromAscii("smath") ).GetFilter4EA( aTypeName );
00356 if ( pFilter )
00357 aFilterName = pFilter->GetName();
00358 }
00359 }
00360 }
00361 else
00362 {
00363
00364
00365
00366 SvStream *pStrm = aMedium.GetInStream();
00367 aTypeName.Erase();
00368 if (pStrm && !pStrm->GetError())
00369 {
00370 SotStorageRef aStorage = new SotStorage ( pStrm, FALSE );
00371 if ( !aStorage->GetError() )
00372 {
00373 if ( aStorage->IsStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Equation Native" ) ) ) )
00374 {
00375 sal_uInt8 nVersion;
00376 if (GetMathTypeVersion( aStorage, nVersion ) && nVersion <=3)
00377 aTypeName.AssignAscii( "math_MathType_3x" );
00378 }
00379 }
00380 else
00381 {
00382 const USHORT nSize = 5;
00383 sal_Char aBuffer[nSize+1];
00384 aBuffer[nSize] = 0;
00385 pStrm->Seek( STREAM_SEEK_TO_BEGIN );
00386 ULONG nBytesRead = pStrm->Read( aBuffer, nSize );
00387 if (nBytesRead == nSize)
00388 {
00389 if (0 == strncmp( "<?xml",aBuffer,nSize))
00390 {
00391 static const sal_Char sFltrNm_2[] = MATHML_XML;
00392 static const sal_Char sTypeNm_2[] = "math_MathML_XML_Math";
00393 aFilterName.AssignAscii( sFltrNm_2 );
00394 aTypeName.AssignAscii( sTypeNm_2 );
00395 }
00396 }
00397 }
00398
00399 if ( aTypeName.Len() )
00400 {
00401 const SfxFilter* pFilt = SfxFilterMatcher( String::CreateFromAscii("smath") ).GetFilter4EA( aTypeName );
00402 if ( pFilt )
00403 aFilterName = pFilt->GetName();
00404 }
00405 }
00406 }
00407 }
00408 }
00409
00410 if ( nIndexOfInputStream == -1 && xStream.is() )
00411 {
00412
00413 lDescriptor.realloc( nPropertyCount + 1 );
00414 lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("InputStream");
00415 lDescriptor[nPropertyCount].Value <<= xStream;
00416 nPropertyCount++;
00417 }
00418
00419 if ( nIndexOfContent == -1 && xContent.is() )
00420 {
00421
00422 lDescriptor.realloc( nPropertyCount + 1 );
00423 lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("UCBContent");
00424 lDescriptor[nPropertyCount].Value <<= xContent;
00425 nPropertyCount++;
00426 }
00427
00428 if ( bReadOnly != bWasReadOnly )
00429 {
00430 if ( nIndexOfReadOnlyFlag == -1 )
00431 {
00432 lDescriptor.realloc( nPropertyCount + 1 );
00433 lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("ReadOnly");
00434 lDescriptor[nPropertyCount].Value <<= bReadOnly;
00435 nPropertyCount++;
00436 }
00437 else
00438 lDescriptor[nIndexOfReadOnlyFlag].Value <<= bReadOnly;
00439 }
00440
00441 if ( !bRepairPackage && bRepairAllowed )
00442 {
00443 lDescriptor.realloc( nPropertyCount + 1 );
00444 lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("RepairPackage");
00445 lDescriptor[nPropertyCount].Value <<= bRepairAllowed;
00446 nPropertyCount++;
00447
00448 bOpenAsTemplate = sal_True;
00449
00450
00451 }
00452
00453 if ( bOpenAsTemplate )
00454 {
00455 if ( nIndexOfTemplateFlag == -1 )
00456 {
00457 lDescriptor.realloc( nPropertyCount + 1 );
00458 lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("AsTemplate");
00459 lDescriptor[nPropertyCount].Value <<= bOpenAsTemplate;
00460 nPropertyCount++;
00461 }
00462 else
00463 lDescriptor[nIndexOfTemplateFlag].Value <<= bOpenAsTemplate;
00464 }
00465
00466 if ( aDocumentTitle.getLength() )
00467 {
00468
00469 if ( nIndexOfDocumentTitle == -1 )
00470 {
00471 lDescriptor.realloc( nPropertyCount + 1 );
00472 lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("DocumentTitle");
00473 lDescriptor[nPropertyCount].Value <<= aDocumentTitle;
00474 nPropertyCount++;
00475 }
00476 else
00477 lDescriptor[nIndexOfDocumentTitle].Value <<= aDocumentTitle;
00478 }
00479
00480 if ( !aFilterName.Len() )
00481 aTypeName.Erase();
00482
00483 return aTypeName;
00484 }
00485
00486 SFX_IMPL_SINGLEFACTORY( SmFilterDetect )
00487
00488
00489 UNOOUSTRING SAL_CALL SmFilterDetect::getImplementationName() throw( UNORUNTIMEEXCEPTION )
00490 {
00491 return impl_getStaticImplementationName();
00492 }
00493 \
00494
00495 sal_Bool SAL_CALL SmFilterDetect::supportsService( const UNOOUSTRING& sServiceName ) throw( UNORUNTIMEEXCEPTION )
00496 {
00497 UNOSEQUENCE< UNOOUSTRING > seqServiceNames = getSupportedServiceNames();
00498 const UNOOUSTRING* pArray = seqServiceNames.getConstArray();
00499 for ( sal_Int32 nCounter=0; nCounter<seqServiceNames.getLength(); nCounter++ )
00500 {
00501 if ( pArray[nCounter] == sServiceName )
00502 {
00503 return sal_True ;
00504 }
00505 }
00506 return sal_False ;
00507 }
00508
00509
00510 UNOSEQUENCE< UNOOUSTRING > SAL_CALL SmFilterDetect::getSupportedServiceNames() throw( UNORUNTIMEEXCEPTION )
00511 {
00512 return impl_getStaticSupportedServiceNames();
00513 }
00514
00515
00516 UNOSEQUENCE< UNOOUSTRING > SmFilterDetect::impl_getStaticSupportedServiceNames()
00517 {
00518 UNOMUTEXGUARD aGuard( UNOMUTEX::getGlobalMutex() );
00519 UNOSEQUENCE< UNOOUSTRING > seqServiceNames( 1 );
00520 seqServiceNames.getArray() [0] = UNOOUSTRING::createFromAscii( "com.sun.star.frame.ExtendedTypeDetection" );
00521 return seqServiceNames ;
00522 }
00523
00524
00525 UNOOUSTRING SmFilterDetect::impl_getStaticImplementationName()
00526 {
00527 return UNOOUSTRING::createFromAscii( "com.sun.star.comp.math.FormatDetector" );
00528 }
00529
00530
00531 UNOREFERENCE< UNOXINTERFACE > SAL_CALL SmFilterDetect::impl_createInstance( const UNOREFERENCE< UNOXMULTISERVICEFACTORY >& xServiceManager ) throw( UNOEXCEPTION )
00532 {
00533 return UNOREFERENCE< UNOXINTERFACE >( *new SmFilterDetect( xServiceManager ) );
00534 }
00535