xref: /aoo4110/main/sw/source/ui/uno/swdetect.cxx (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_sw.hxx"
26*b1cdbd2cSJim Jagielski #include "swdetect.hxx"
27*b1cdbd2cSJim Jagielski 
28*b1cdbd2cSJim Jagielski #include <framework/interaction.hxx>
29*b1cdbd2cSJim Jagielski #include <com/sun/star/frame/XFrame.hpp>
30*b1cdbd2cSJim Jagielski #include <com/sun/star/frame/XModel.hpp>
31*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/XUnoTunnel.hpp>
32*b1cdbd2cSJim Jagielski #ifndef _UNOTOOLS_PROCESSFACTORY_HXX
33*b1cdbd2cSJim Jagielski #include <comphelper/processfactory.hxx>
34*b1cdbd2cSJim Jagielski #endif
35*b1cdbd2cSJim Jagielski #include <com/sun/star/container/XNameAccess.hpp>
36*b1cdbd2cSJim Jagielski #include <com/sun/star/io/XInputStream.hpp>
37*b1cdbd2cSJim Jagielski #include <com/sun/star/task/XInteractionHandler.hpp>
38*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
39*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/CommandAbortedException.hpp>
40*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/InteractiveAppException.hpp>
41*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/XContent.hpp>
42*b1cdbd2cSJim Jagielski #include <com/sun/star/packages/zip/ZipIOException.hpp>
43*b1cdbd2cSJim Jagielski #ifndef _TOOLKIT_UNOHLP_HXX
44*b1cdbd2cSJim Jagielski #include <toolkit/helper/vclunohelper.hxx>
45*b1cdbd2cSJim Jagielski #endif
46*b1cdbd2cSJim Jagielski #include <ucbhelper/simpleinteractionrequest.hxx>
47*b1cdbd2cSJim Jagielski #include <rtl/ustring.h>
48*b1cdbd2cSJim Jagielski #include <rtl/logfile.hxx>
49*b1cdbd2cSJim Jagielski #include <svl/itemset.hxx>
50*b1cdbd2cSJim Jagielski #include <vcl/window.hxx>
51*b1cdbd2cSJim Jagielski #include <svl/eitem.hxx>
52*b1cdbd2cSJim Jagielski #include <svl/stritem.hxx>
53*b1cdbd2cSJim Jagielski #include <tools/urlobj.hxx>
54*b1cdbd2cSJim Jagielski #include <vos/mutex.hxx>
55*b1cdbd2cSJim Jagielski #include <svtools/sfxecode.hxx>
56*b1cdbd2cSJim Jagielski #include <svtools/ehdl.hxx>
57*b1cdbd2cSJim Jagielski #include <sot/storinfo.hxx>
58*b1cdbd2cSJim Jagielski #include <vcl/svapp.hxx>
59*b1cdbd2cSJim Jagielski #include <sfx2/app.hxx>
60*b1cdbd2cSJim Jagielski #include <sfx2/sfxsids.hrc>
61*b1cdbd2cSJim Jagielski #include <sfx2/request.hxx>
62*b1cdbd2cSJim Jagielski #include <sfx2/docfile.hxx>
63*b1cdbd2cSJim Jagielski #include <sfx2/docfilt.hxx>
64*b1cdbd2cSJim Jagielski #include <sfx2/fcontnr.hxx>
65*b1cdbd2cSJim Jagielski #include <sfx2/brokenpackageint.hxx>
66*b1cdbd2cSJim Jagielski #include <svtools/FilterConfigItem.hxx>
67*b1cdbd2cSJim Jagielski #include <unotools/moduleoptions.hxx>
68*b1cdbd2cSJim Jagielski #include <com/sun/star/util/XArchiver.hpp>
69*b1cdbd2cSJim Jagielski #include <comphelper/ihwrapnofilter.hxx>
70*b1cdbd2cSJim Jagielski 
71*b1cdbd2cSJim Jagielski #include <swdll.hxx>
72*b1cdbd2cSJim Jagielski 
73*b1cdbd2cSJim Jagielski using namespace ::com::sun::star;
74*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::uno;
75*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::io;
76*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::frame;
77*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::task;
78*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::beans;
79*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::lang;
80*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::ucb;
81*b1cdbd2cSJim Jagielski using ::rtl::OUString;
82*b1cdbd2cSJim Jagielski 
SwFilterDetect(const REFERENCE<lang::XMultiServiceFactory> &)83*b1cdbd2cSJim Jagielski SwFilterDetect::SwFilterDetect( const REFERENCE < lang::XMultiServiceFactory >& /*xFactory*/ )
84*b1cdbd2cSJim Jagielski {
85*b1cdbd2cSJim Jagielski }
86*b1cdbd2cSJim Jagielski 
~SwFilterDetect()87*b1cdbd2cSJim Jagielski SwFilterDetect::~SwFilterDetect()
88*b1cdbd2cSJim Jagielski {
89*b1cdbd2cSJim Jagielski }
90*b1cdbd2cSJim Jagielski 
detect(uno::Sequence<beans::PropertyValue> & lDescriptor)91*b1cdbd2cSJim Jagielski ::rtl::OUString SAL_CALL SwFilterDetect::detect( uno::Sequence< beans::PropertyValue >& lDescriptor ) throw( uno::RuntimeException )
92*b1cdbd2cSJim Jagielski {
93*b1cdbd2cSJim Jagielski     REFERENCE< XInputStream > xStream;
94*b1cdbd2cSJim Jagielski     REFERENCE< XContent > xContent;
95*b1cdbd2cSJim Jagielski     REFERENCE< XInteractionHandler > xInteraction;
96*b1cdbd2cSJim Jagielski     String aURL;
97*b1cdbd2cSJim Jagielski 	::rtl::OUString sTemp;
98*b1cdbd2cSJim Jagielski     String aTypeName;            // a name describing the type (from MediaDescriptor, usually from flat detection)
99*b1cdbd2cSJim Jagielski     String aPreselectedFilterName;      // a name describing the filter to use (from MediaDescriptor, usually from UI action)
100*b1cdbd2cSJim Jagielski 
101*b1cdbd2cSJim Jagielski 	::rtl::OUString aDocumentTitle; // interesting only if set in this method
102*b1cdbd2cSJim Jagielski 
103*b1cdbd2cSJim Jagielski 	// opening as template is done when a parameter tells to do so and a template filter can be detected
104*b1cdbd2cSJim Jagielski     // (otherwise no valid filter would be found) or if the detected filter is a template filter and
105*b1cdbd2cSJim Jagielski 	// there is no parameter that forbids to open as template
106*b1cdbd2cSJim Jagielski 	sal_Bool bOpenAsTemplate = sal_False;
107*b1cdbd2cSJim Jagielski     sal_Bool bWasReadOnly = sal_False, bReadOnly = sal_False;
108*b1cdbd2cSJim Jagielski 
109*b1cdbd2cSJim Jagielski 	sal_Bool bRepairPackage = sal_False;
110*b1cdbd2cSJim Jagielski 	sal_Bool bRepairAllowed = sal_False;
111*b1cdbd2cSJim Jagielski 
112*b1cdbd2cSJim Jagielski 	// now some parameters that can already be in the array, but may be overwritten or new inserted here
113*b1cdbd2cSJim Jagielski 	// remember their indices in the case new values must be added to the array
114*b1cdbd2cSJim Jagielski 	sal_Int32 nPropertyCount = lDescriptor.getLength();
115*b1cdbd2cSJim Jagielski     sal_Int32 nIndexOfFilterName = -1;
116*b1cdbd2cSJim Jagielski     sal_Int32 nIndexOfInputStream = -1;
117*b1cdbd2cSJim Jagielski     sal_Int32 nIndexOfContent = -1;
118*b1cdbd2cSJim Jagielski     sal_Int32 nIndexOfReadOnlyFlag = -1;
119*b1cdbd2cSJim Jagielski     sal_Int32 nIndexOfTemplateFlag = -1;
120*b1cdbd2cSJim Jagielski     sal_Int32 nIndexOfDocumentTitle = -1;
121*b1cdbd2cSJim Jagielski     sal_Int32 nIndexOfInteractionHandler = -1;
122*b1cdbd2cSJim Jagielski 
123*b1cdbd2cSJim Jagielski     for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty )
124*b1cdbd2cSJim Jagielski 	{
125*b1cdbd2cSJim Jagielski         // extract properties
126*b1cdbd2cSJim Jagielski         if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("URL")) )
127*b1cdbd2cSJim Jagielski 		{
128*b1cdbd2cSJim Jagielski 			lDescriptor[nProperty].Value >>= sTemp;
129*b1cdbd2cSJim Jagielski 			aURL = sTemp;
130*b1cdbd2cSJim Jagielski 		}
131*b1cdbd2cSJim Jagielski         else if( !aURL.Len() && lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("FileName")) )
132*b1cdbd2cSJim Jagielski 		{
133*b1cdbd2cSJim Jagielski 			lDescriptor[nProperty].Value >>= sTemp;
134*b1cdbd2cSJim Jagielski 			aURL = sTemp;
135*b1cdbd2cSJim Jagielski 		}
136*b1cdbd2cSJim Jagielski         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("TypeName")) )
137*b1cdbd2cSJim Jagielski 		{
138*b1cdbd2cSJim Jagielski 			lDescriptor[nProperty].Value >>= sTemp;
139*b1cdbd2cSJim Jagielski             aTypeName = sTemp;
140*b1cdbd2cSJim Jagielski 		}
141*b1cdbd2cSJim Jagielski         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("FilterName")) )
142*b1cdbd2cSJim Jagielski 		{
143*b1cdbd2cSJim Jagielski 			lDescriptor[nProperty].Value >>= sTemp;
144*b1cdbd2cSJim Jagielski             aPreselectedFilterName = sTemp;
145*b1cdbd2cSJim Jagielski 
146*b1cdbd2cSJim Jagielski             // if the preselected filter name is not correct, it must be erased after detection
147*b1cdbd2cSJim Jagielski             // remember index of property to get access to it later
148*b1cdbd2cSJim Jagielski             nIndexOfFilterName = nProperty;
149*b1cdbd2cSJim Jagielski 		}
150*b1cdbd2cSJim Jagielski         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("InputStream")) )
151*b1cdbd2cSJim Jagielski             nIndexOfInputStream = nProperty;
152*b1cdbd2cSJim Jagielski         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("ReadOnly")) )
153*b1cdbd2cSJim Jagielski             nIndexOfReadOnlyFlag = nProperty;
154*b1cdbd2cSJim Jagielski         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("UCBContent")) )
155*b1cdbd2cSJim Jagielski             nIndexOfContent = nProperty;
156*b1cdbd2cSJim Jagielski         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("AsTemplate")) )
157*b1cdbd2cSJim Jagielski 		{
158*b1cdbd2cSJim Jagielski 			lDescriptor[nProperty].Value >>= bOpenAsTemplate;
159*b1cdbd2cSJim Jagielski             nIndexOfTemplateFlag = nProperty;
160*b1cdbd2cSJim Jagielski 		}
161*b1cdbd2cSJim Jagielski         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("InteractionHandler")) )
162*b1cdbd2cSJim Jagielski         {
163*b1cdbd2cSJim Jagielski             lDescriptor[nProperty].Value >>= xInteraction;
164*b1cdbd2cSJim Jagielski             nIndexOfInteractionHandler = nProperty;
165*b1cdbd2cSJim Jagielski         }
166*b1cdbd2cSJim Jagielski         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("RepairPackage")) )
167*b1cdbd2cSJim Jagielski             lDescriptor[nProperty].Value >>= bRepairPackage;
168*b1cdbd2cSJim Jagielski         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentTitle")) )
169*b1cdbd2cSJim Jagielski             nIndexOfDocumentTitle = nProperty;
170*b1cdbd2cSJim Jagielski 	}
171*b1cdbd2cSJim Jagielski 
172*b1cdbd2cSJim Jagielski     // can't check the type for external filters, so set the "dont" flag accordingly
173*b1cdbd2cSJim Jagielski     ::vos::OGuard aGuard( Application::GetSolarMutex() );
174*b1cdbd2cSJim Jagielski     //SfxFilterFlags nMust = SFX_FILTER_IMPORT, nDont = SFX_FILTER_NOTINSTALLED;
175*b1cdbd2cSJim Jagielski 
176*b1cdbd2cSJim Jagielski     SfxApplication* pApp = SFX_APP();
177*b1cdbd2cSJim Jagielski     SfxAllItemSet *pSet = new SfxAllItemSet( pApp->GetPool() );
178*b1cdbd2cSJim Jagielski     TransformParameters( SID_OPENDOC, lDescriptor, *pSet );
179*b1cdbd2cSJim Jagielski     SFX_ITEMSET_ARG( pSet, pItem, SfxBoolItem, SID_DOC_READONLY, sal_False );
180*b1cdbd2cSJim Jagielski 
181*b1cdbd2cSJim Jagielski     bWasReadOnly = pItem && pItem->GetValue();
182*b1cdbd2cSJim Jagielski 
183*b1cdbd2cSJim Jagielski 	const SfxFilter* pFilter = 0;
184*b1cdbd2cSJim Jagielski 	String aPrefix = String::CreateFromAscii( "private:factory/" );
185*b1cdbd2cSJim Jagielski 	if( aURL.Match( aPrefix ) == aPrefix.Len() )
186*b1cdbd2cSJim Jagielski 	{
187*b1cdbd2cSJim Jagielski 		if( SvtModuleOptions().IsWriter() )
188*b1cdbd2cSJim Jagielski 		{
189*b1cdbd2cSJim Jagielski 			String aPattern( aPrefix );
190*b1cdbd2cSJim Jagielski 			aPattern += String::CreateFromAscii("swriter");
191*b1cdbd2cSJim Jagielski 			if ( aURL.Match( aPattern ) >= aPattern.Len() )
192*b1cdbd2cSJim Jagielski 				//pFilter = SfxFilter::GetDefaultFilterFromFactory( aURL );
193*b1cdbd2cSJim Jagielski 				return aTypeName;
194*b1cdbd2cSJim Jagielski 		}
195*b1cdbd2cSJim Jagielski 	}
196*b1cdbd2cSJim Jagielski 	else
197*b1cdbd2cSJim Jagielski 	{
198*b1cdbd2cSJim Jagielski 	    // ctor of SfxMedium uses owner transition of ItemSet
199*b1cdbd2cSJim Jagielski 	    SfxMedium aMedium( aURL, bWasReadOnly ? STREAM_STD_READ : STREAM_STD_READWRITE, sal_False, NULL, pSet );
200*b1cdbd2cSJim Jagielski 	    aMedium.UseInteractionHandler( sal_True );
201*b1cdbd2cSJim Jagielski 	    if ( aMedium.GetErrorCode() == ERRCODE_NONE )
202*b1cdbd2cSJim Jagielski 	    {
203*b1cdbd2cSJim Jagielski 	        // remember input stream and content and put them into the descriptor later
204*b1cdbd2cSJim Jagielski 			// should be done here since later the medium can switch to a version
205*b1cdbd2cSJim Jagielski 	        xStream = aMedium.GetInputStream();
206*b1cdbd2cSJim Jagielski 			xContent = aMedium.GetContent();
207*b1cdbd2cSJim Jagielski             bReadOnly = aMedium.IsReadOnly();
208*b1cdbd2cSJim Jagielski 
209*b1cdbd2cSJim Jagielski         	sal_Bool bIsStorage = aMedium.IsStorage();
210*b1cdbd2cSJim Jagielski             if ( bIsStorage )
211*b1cdbd2cSJim Jagielski 			{
212*b1cdbd2cSJim Jagielski                 uno::Reference< embed::XStorage > xStorage = aMedium.GetStorage( sal_False );
213*b1cdbd2cSJim Jagielski 				if ( aMedium.GetLastStorageCreationState() != ERRCODE_NONE )
214*b1cdbd2cSJim Jagielski 				{
215*b1cdbd2cSJim Jagielski 					// error during storage creation means _here_ that the medium
216*b1cdbd2cSJim Jagielski                     // is broken, but we can not handle it in medium since impossibility
217*b1cdbd2cSJim Jagielski 					// to create a storage does not _always_ means that the medium is broken
218*b1cdbd2cSJim Jagielski 					aMedium.SetError( aMedium.GetLastStorageCreationState(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
219*b1cdbd2cSJim Jagielski 					if ( xInteraction.is() )
220*b1cdbd2cSJim Jagielski 					{
221*b1cdbd2cSJim Jagielski 						OUString empty;
222*b1cdbd2cSJim Jagielski 						try
223*b1cdbd2cSJim Jagielski 						{
224*b1cdbd2cSJim Jagielski 							InteractiveAppException xException( empty,
225*b1cdbd2cSJim Jagielski 															REFERENCE< XInterface >(),
226*b1cdbd2cSJim Jagielski 															InteractionClassification_ERROR,
227*b1cdbd2cSJim Jagielski 															aMedium.GetError() );
228*b1cdbd2cSJim Jagielski 
229*b1cdbd2cSJim Jagielski 							REFERENCE< XInteractionRequest > xRequest(
230*b1cdbd2cSJim Jagielski 								new ucbhelper::SimpleInteractionRequest( makeAny( xException ),
231*b1cdbd2cSJim Jagielski 																 	 ucbhelper::CONTINUATION_APPROVE ) );
232*b1cdbd2cSJim Jagielski 							xInteraction->handle( xRequest );
233*b1cdbd2cSJim Jagielski 						}
234*b1cdbd2cSJim Jagielski 						catch ( Exception & ) {};
235*b1cdbd2cSJim Jagielski 					}
236*b1cdbd2cSJim Jagielski 				}
237*b1cdbd2cSJim Jagielski 				else
238*b1cdbd2cSJim Jagielski 				{
239*b1cdbd2cSJim Jagielski 					DBG_ASSERT( xStorage.is(), "At this point storage must exist!" );
240*b1cdbd2cSJim Jagielski 
241*b1cdbd2cSJim Jagielski 					try
242*b1cdbd2cSJim Jagielski 					{
243*b1cdbd2cSJim Jagielski                         const SfxFilter* pPreFilter = aPreselectedFilterName.Len() ?
244*b1cdbd2cSJim Jagielski                                 SfxFilterMatcher().GetFilter4FilterName( aPreselectedFilterName ) : aTypeName.Len() ?
245*b1cdbd2cSJim Jagielski                                 SfxFilterMatcher(String::CreateFromAscii("swriter")).GetFilter4EA( aTypeName ) : 0;
246*b1cdbd2cSJim Jagielski                         if (!pPreFilter)
247*b1cdbd2cSJim Jagielski                             pPreFilter = SfxFilterMatcher(String::CreateFromAscii("sweb")).GetFilter4EA( aTypeName );
248*b1cdbd2cSJim Jagielski                         String aFilterName;
249*b1cdbd2cSJim Jagielski                         if ( pPreFilter )
250*b1cdbd2cSJim Jagielski                         {
251*b1cdbd2cSJim Jagielski                             aFilterName = pPreFilter->GetName();
252*b1cdbd2cSJim Jagielski                             aTypeName = pPreFilter->GetTypeName();
253*b1cdbd2cSJim Jagielski                         }
254*b1cdbd2cSJim Jagielski 
255*b1cdbd2cSJim Jagielski                         aTypeName = SfxFilter::GetTypeFromStorage( xStorage, pPreFilter ? pPreFilter->IsOwnTemplateFormat() : sal_False, &aFilterName );
256*b1cdbd2cSJim Jagielski 					}
257*b1cdbd2cSJim Jagielski 					catch( lang::WrappedTargetException& aWrap )
258*b1cdbd2cSJim Jagielski 					{
259*b1cdbd2cSJim Jagielski 						packages::zip::ZipIOException aZipException;
260*b1cdbd2cSJim Jagielski 
261*b1cdbd2cSJim Jagielski 						// repairing is done only if this type is requested from outside
262*b1cdbd2cSJim Jagielski                         // we don't do any type detection on broken packages (f.e. because it might be impossible), so any requested
263*b1cdbd2cSJim Jagielski                         // type will be accepted if the user allows to repair the file
264*b1cdbd2cSJim Jagielski                         if ( ( aWrap.TargetException >>= aZipException ) && ( aTypeName.Len() || aPreselectedFilterName.Len() ) )
265*b1cdbd2cSJim Jagielski 						{
266*b1cdbd2cSJim Jagielski 							if ( xInteraction.is() )
267*b1cdbd2cSJim Jagielski 							{
268*b1cdbd2cSJim Jagielski                                 // the package is a broken one
269*b1cdbd2cSJim Jagielski        							aDocumentTitle = aMedium.GetURLObject().getName(
270*b1cdbd2cSJim Jagielski 															INetURLObject::LAST_SEGMENT,
271*b1cdbd2cSJim Jagielski 															true,
272*b1cdbd2cSJim Jagielski 															INetURLObject::DECODE_WITH_CHARSET );
273*b1cdbd2cSJim Jagielski 
274*b1cdbd2cSJim Jagielski 								if ( !bRepairPackage )
275*b1cdbd2cSJim Jagielski 								{
276*b1cdbd2cSJim Jagielski                                     // ask the user whether he wants to try to repair
277*b1cdbd2cSJim Jagielski                                     RequestPackageReparation aRequest( aDocumentTitle );
278*b1cdbd2cSJim Jagielski                                     xInteraction->handle( aRequest.GetRequest() );
279*b1cdbd2cSJim Jagielski                                     bRepairAllowed = aRequest.isApproved();
280*b1cdbd2cSJim Jagielski 								}
281*b1cdbd2cSJim Jagielski 
282*b1cdbd2cSJim Jagielski 								if ( !bRepairAllowed )
283*b1cdbd2cSJim Jagielski 								{
284*b1cdbd2cSJim Jagielski 									// repair either not allowed or not successful
285*b1cdbd2cSJim Jagielski 									// repair either not allowed or not successful
286*b1cdbd2cSJim Jagielski                                     NotifyBrokenPackage aNotifyRequest( aDocumentTitle );
287*b1cdbd2cSJim Jagielski                                     xInteraction->handle( aNotifyRequest.GetRequest() );
288*b1cdbd2cSJim Jagielski 
289*b1cdbd2cSJim Jagielski                                     rtl::Reference< ::comphelper::OIHWrapNoFilterDialog > xHandler = new ::comphelper::OIHWrapNoFilterDialog( xInteraction );
290*b1cdbd2cSJim Jagielski                                     if ( nIndexOfInteractionHandler != -1 )
291*b1cdbd2cSJim Jagielski                                         lDescriptor[nIndexOfInteractionHandler].Value <<= uno::Reference< XInteractionHandler >( static_cast< task::XInteractionHandler* >( xHandler.get() ) );
292*b1cdbd2cSJim Jagielski 
293*b1cdbd2cSJim Jagielski 									aMedium.SetError( ERRCODE_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
294*b1cdbd2cSJim Jagielski 								}
295*b1cdbd2cSJim Jagielski 							}
296*b1cdbd2cSJim Jagielski 							else
297*b1cdbd2cSJim Jagielski                                 // no interaction, error handling as usual
298*b1cdbd2cSJim Jagielski 								aMedium.SetError( ERRCODE_IO_BROKENPACKAGE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
299*b1cdbd2cSJim Jagielski 
300*b1cdbd2cSJim Jagielski 							if ( !bRepairAllowed )
301*b1cdbd2cSJim Jagielski 							{
302*b1cdbd2cSJim Jagielski 								aTypeName.Erase();
303*b1cdbd2cSJim Jagielski 								aPreselectedFilterName.Erase();
304*b1cdbd2cSJim Jagielski 							}
305*b1cdbd2cSJim Jagielski 						}
306*b1cdbd2cSJim Jagielski 					}
307*b1cdbd2cSJim Jagielski 					catch( uno::RuntimeException& )
308*b1cdbd2cSJim Jagielski 					{
309*b1cdbd2cSJim Jagielski 						throw;
310*b1cdbd2cSJim Jagielski 					}
311*b1cdbd2cSJim Jagielski 					catch( uno::Exception& )
312*b1cdbd2cSJim Jagielski 					{
313*b1cdbd2cSJim Jagielski 						aTypeName.Erase();
314*b1cdbd2cSJim Jagielski 						aPreselectedFilterName.Erase();
315*b1cdbd2cSJim Jagielski 					}
316*b1cdbd2cSJim Jagielski 				}
317*b1cdbd2cSJim Jagielski 			}
318*b1cdbd2cSJim Jagielski             else
319*b1cdbd2cSJim Jagielski             {
320*b1cdbd2cSJim Jagielski                 aMedium.GetInStream();
321*b1cdbd2cSJim Jagielski                 if ( aMedium.GetErrorCode() == ERRCODE_NONE )
322*b1cdbd2cSJim Jagielski                 {
323*b1cdbd2cSJim Jagielski                     if ( aPreselectedFilterName.Len() )
324*b1cdbd2cSJim Jagielski                         pFilter = SfxFilter::GetFilterByName( aPreselectedFilterName );
325*b1cdbd2cSJim Jagielski                     else
326*b1cdbd2cSJim Jagielski                         pFilter = SfxFilterMatcher().GetFilter4EA( aTypeName );
327*b1cdbd2cSJim Jagielski 
328*b1cdbd2cSJim Jagielski                     sal_Bool bTestWriter = !pFilter || pFilter->GetServiceName().EqualsAscii("com.sun.star.text.TextDocument") ||
329*b1cdbd2cSJim Jagielski                         pFilter->GetServiceName().EqualsAscii("com.sun.star.text.WebDocument");
330*b1cdbd2cSJim Jagielski                     sal_Bool bTestGlobal = !pFilter || pFilter->GetServiceName().EqualsAscii("com.sun.star.text.GlobalDocument");
331*b1cdbd2cSJim Jagielski 
332*b1cdbd2cSJim Jagielski                     const SfxFilter* pOrigFilter = NULL;
333*b1cdbd2cSJim Jagielski                     if ( !bTestWriter && !bTestGlobal && pFilter )
334*b1cdbd2cSJim Jagielski                     {
335*b1cdbd2cSJim Jagielski                         // cross filter; now this should be a type detection only, not a filter detection
336*b1cdbd2cSJim Jagielski                         // we can simulate it by preserving the preselected filter if the type matches
337*b1cdbd2cSJim Jagielski                         // example: HTML filter for Calc
338*b1cdbd2cSJim Jagielski                         pOrigFilter = pFilter;
339*b1cdbd2cSJim Jagielski                         pFilter = SfxFilterMatcher().GetFilter4EA( pFilter->GetTypeName() );
340*b1cdbd2cSJim Jagielski                         bTestWriter = sal_True;
341*b1cdbd2cSJim Jagielski                     }
342*b1cdbd2cSJim Jagielski 
343*b1cdbd2cSJim Jagielski                     sal_uLong nErr = ERRCODE_NONE;
344*b1cdbd2cSJim Jagielski                     if ( pFilter || bTestWriter )
345*b1cdbd2cSJim Jagielski                         nErr = DetectFilter( aMedium, &pFilter );
346*b1cdbd2cSJim Jagielski                     if ( nErr != ERRCODE_NONE )
347*b1cdbd2cSJim Jagielski                         pFilter = NULL;
348*b1cdbd2cSJim Jagielski                     else if ( pOrigFilter && pFilter && pFilter->GetTypeName() == pOrigFilter->GetTypeName() )
349*b1cdbd2cSJim Jagielski                         // cross filter, see above
350*b1cdbd2cSJim Jagielski                         pFilter = pOrigFilter;
351*b1cdbd2cSJim Jagielski                 }
352*b1cdbd2cSJim Jagielski 
353*b1cdbd2cSJim Jagielski                 if ( pFilter )
354*b1cdbd2cSJim Jagielski                     aTypeName = pFilter->GetTypeName();
355*b1cdbd2cSJim Jagielski                 else
356*b1cdbd2cSJim Jagielski                     aTypeName.Erase();
357*b1cdbd2cSJim Jagielski             }
358*b1cdbd2cSJim Jagielski 		}
359*b1cdbd2cSJim Jagielski 	}
360*b1cdbd2cSJim Jagielski 
361*b1cdbd2cSJim Jagielski     if ( nIndexOfInputStream == -1 && xStream.is() )
362*b1cdbd2cSJim Jagielski     {
363*b1cdbd2cSJim Jagielski         // if input stream wasn't part of the descriptor, now it should be, otherwise the content would be opend twice
364*b1cdbd2cSJim Jagielski         lDescriptor.realloc( nPropertyCount + 1 );
365*b1cdbd2cSJim Jagielski         lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("InputStream");
366*b1cdbd2cSJim Jagielski         lDescriptor[nPropertyCount].Value <<= xStream;
367*b1cdbd2cSJim Jagielski         nPropertyCount++;
368*b1cdbd2cSJim Jagielski     }
369*b1cdbd2cSJim Jagielski 
370*b1cdbd2cSJim Jagielski     if ( nIndexOfContent == -1 && xContent.is() )
371*b1cdbd2cSJim Jagielski     {
372*b1cdbd2cSJim Jagielski         // if input stream wasn't part of the descriptor, now it should be, otherwise the content would be opend twice
373*b1cdbd2cSJim Jagielski         lDescriptor.realloc( nPropertyCount + 1 );
374*b1cdbd2cSJim Jagielski         lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("UCBContent");
375*b1cdbd2cSJim Jagielski         lDescriptor[nPropertyCount].Value <<= xContent;
376*b1cdbd2cSJim Jagielski         nPropertyCount++;
377*b1cdbd2cSJim Jagielski     }
378*b1cdbd2cSJim Jagielski 
379*b1cdbd2cSJim Jagielski     if ( bReadOnly != bWasReadOnly )
380*b1cdbd2cSJim Jagielski     {
381*b1cdbd2cSJim Jagielski         if ( nIndexOfReadOnlyFlag == -1 )
382*b1cdbd2cSJim Jagielski         {
383*b1cdbd2cSJim Jagielski             lDescriptor.realloc( nPropertyCount + 1 );
384*b1cdbd2cSJim Jagielski             lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("ReadOnly");
385*b1cdbd2cSJim Jagielski             lDescriptor[nPropertyCount].Value <<= bReadOnly;
386*b1cdbd2cSJim Jagielski             nPropertyCount++;
387*b1cdbd2cSJim Jagielski         }
388*b1cdbd2cSJim Jagielski         else
389*b1cdbd2cSJim Jagielski             lDescriptor[nIndexOfReadOnlyFlag].Value <<= bReadOnly;
390*b1cdbd2cSJim Jagielski     }
391*b1cdbd2cSJim Jagielski 
392*b1cdbd2cSJim Jagielski 	if ( !bRepairPackage && bRepairAllowed )
393*b1cdbd2cSJim Jagielski 	{
394*b1cdbd2cSJim Jagielski         lDescriptor.realloc( nPropertyCount + 1 );
395*b1cdbd2cSJim Jagielski         lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("RepairPackage");
396*b1cdbd2cSJim Jagielski         lDescriptor[nPropertyCount].Value <<= bRepairAllowed;
397*b1cdbd2cSJim Jagielski         nPropertyCount++;
398*b1cdbd2cSJim Jagielski 		bOpenAsTemplate = sal_True;
399*b1cdbd2cSJim Jagielski 		// TODO/LATER: set progress bar that should be used
400*b1cdbd2cSJim Jagielski 	}
401*b1cdbd2cSJim Jagielski 
402*b1cdbd2cSJim Jagielski 	if ( bOpenAsTemplate )
403*b1cdbd2cSJim Jagielski 	{
404*b1cdbd2cSJim Jagielski 		if ( nIndexOfTemplateFlag == -1 )
405*b1cdbd2cSJim Jagielski 		{
406*b1cdbd2cSJim Jagielski         	lDescriptor.realloc( nPropertyCount + 1 );
407*b1cdbd2cSJim Jagielski         	lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("AsTemplate");
408*b1cdbd2cSJim Jagielski         	lDescriptor[nPropertyCount].Value <<= bOpenAsTemplate;
409*b1cdbd2cSJim Jagielski         	nPropertyCount++;
410*b1cdbd2cSJim Jagielski 		}
411*b1cdbd2cSJim Jagielski 		else
412*b1cdbd2cSJim Jagielski         	lDescriptor[nIndexOfTemplateFlag].Value <<= bOpenAsTemplate;
413*b1cdbd2cSJim Jagielski 	}
414*b1cdbd2cSJim Jagielski 
415*b1cdbd2cSJim Jagielski 	if ( aDocumentTitle.getLength() )
416*b1cdbd2cSJim Jagielski 	{
417*b1cdbd2cSJim Jagielski 		// the title was set here
418*b1cdbd2cSJim Jagielski 		if ( nIndexOfDocumentTitle == -1 )
419*b1cdbd2cSJim Jagielski 		{
420*b1cdbd2cSJim Jagielski         	lDescriptor.realloc( nPropertyCount + 1 );
421*b1cdbd2cSJim Jagielski         	lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("DocumentTitle");
422*b1cdbd2cSJim Jagielski         	lDescriptor[nPropertyCount].Value <<= aDocumentTitle;
423*b1cdbd2cSJim Jagielski         	nPropertyCount++;
424*b1cdbd2cSJim Jagielski 		}
425*b1cdbd2cSJim Jagielski 		else
426*b1cdbd2cSJim Jagielski         	lDescriptor[nIndexOfDocumentTitle].Value <<= aDocumentTitle;
427*b1cdbd2cSJim Jagielski 	}
428*b1cdbd2cSJim Jagielski 
429*b1cdbd2cSJim Jagielski 
430*b1cdbd2cSJim Jagielski     return aTypeName;
431*b1cdbd2cSJim Jagielski }
432*b1cdbd2cSJim Jagielski 
SFX_IMPL_SINGLEFACTORY(SwFilterDetect)433*b1cdbd2cSJim Jagielski SFX_IMPL_SINGLEFACTORY( SwFilterDetect )
434*b1cdbd2cSJim Jagielski 
435*b1cdbd2cSJim Jagielski /* XServiceInfo */
436*b1cdbd2cSJim Jagielski UNOOUSTRING SAL_CALL SwFilterDetect::getImplementationName() throw( UNORUNTIMEEXCEPTION )
437*b1cdbd2cSJim Jagielski {
438*b1cdbd2cSJim Jagielski     return impl_getStaticImplementationName();
439*b1cdbd2cSJim Jagielski }
440*b1cdbd2cSJim Jagielski                                                                                                                                 \
441*b1cdbd2cSJim Jagielski /* XServiceInfo */
supportsService(const UNOOUSTRING & sServiceName)442*b1cdbd2cSJim Jagielski sal_Bool SAL_CALL SwFilterDetect::supportsService( const UNOOUSTRING& sServiceName ) throw( UNORUNTIMEEXCEPTION )
443*b1cdbd2cSJim Jagielski {
444*b1cdbd2cSJim Jagielski     UNOSEQUENCE< UNOOUSTRING >  seqServiceNames =   getSupportedServiceNames();
445*b1cdbd2cSJim Jagielski     const UNOOUSTRING*          pArray          =   seqServiceNames.getConstArray();
446*b1cdbd2cSJim Jagielski     for ( sal_Int32 nCounter=0; nCounter<seqServiceNames.getLength(); nCounter++ )
447*b1cdbd2cSJim Jagielski     {
448*b1cdbd2cSJim Jagielski         if ( pArray[nCounter] == sServiceName )
449*b1cdbd2cSJim Jagielski         {
450*b1cdbd2cSJim Jagielski             return sal_True ;
451*b1cdbd2cSJim Jagielski         }
452*b1cdbd2cSJim Jagielski     }
453*b1cdbd2cSJim Jagielski     return sal_False ;
454*b1cdbd2cSJim Jagielski }
455*b1cdbd2cSJim Jagielski 
456*b1cdbd2cSJim Jagielski /* XServiceInfo */
getSupportedServiceNames()457*b1cdbd2cSJim Jagielski UNOSEQUENCE< UNOOUSTRING > SAL_CALL SwFilterDetect::getSupportedServiceNames() throw( UNORUNTIMEEXCEPTION )
458*b1cdbd2cSJim Jagielski {
459*b1cdbd2cSJim Jagielski     return impl_getStaticSupportedServiceNames();
460*b1cdbd2cSJim Jagielski }
461*b1cdbd2cSJim Jagielski 
462*b1cdbd2cSJim Jagielski /* Helper for XServiceInfo */
impl_getStaticSupportedServiceNames()463*b1cdbd2cSJim Jagielski UNOSEQUENCE< UNOOUSTRING > SwFilterDetect::impl_getStaticSupportedServiceNames()
464*b1cdbd2cSJim Jagielski {
465*b1cdbd2cSJim Jagielski     UNOMUTEXGUARD aGuard( UNOMUTEX::getGlobalMutex() );
466*b1cdbd2cSJim Jagielski     UNOSEQUENCE< UNOOUSTRING > seqServiceNames( 3 );
467*b1cdbd2cSJim Jagielski     seqServiceNames.getArray() [0] = UNOOUSTRING::createFromAscii( "com.sun.star.frame.ExtendedTypeDetection"  );
468*b1cdbd2cSJim Jagielski     seqServiceNames.getArray() [1] = UNOOUSTRING::createFromAscii( "com.sun.star.text.FormatDetector"  );
469*b1cdbd2cSJim Jagielski     seqServiceNames.getArray() [2] = UNOOUSTRING::createFromAscii( "com.sun.star.text.W4WFormatDetector"  );
470*b1cdbd2cSJim Jagielski     return seqServiceNames ;
471*b1cdbd2cSJim Jagielski }
472*b1cdbd2cSJim Jagielski 
473*b1cdbd2cSJim Jagielski /* Helper for XServiceInfo */
impl_getStaticImplementationName()474*b1cdbd2cSJim Jagielski UNOOUSTRING SwFilterDetect::impl_getStaticImplementationName()
475*b1cdbd2cSJim Jagielski {
476*b1cdbd2cSJim Jagielski     return UNOOUSTRING::createFromAscii( "com.sun.star.comp.writer.FormatDetector" );
477*b1cdbd2cSJim Jagielski }
478*b1cdbd2cSJim Jagielski 
479*b1cdbd2cSJim Jagielski /* Helper for registry */
impl_createInstance(const UNOREFERENCE<UNOXMULTISERVICEFACTORY> & xServiceManager)480*b1cdbd2cSJim Jagielski UNOREFERENCE< UNOXINTERFACE > SAL_CALL SwFilterDetect::impl_createInstance( const UNOREFERENCE< UNOXMULTISERVICEFACTORY >& xServiceManager ) throw( UNOEXCEPTION )
481*b1cdbd2cSJim Jagielski {
482*b1cdbd2cSJim Jagielski     return UNOREFERENCE< UNOXINTERFACE >( *new SwFilterDetect( xServiceManager ) );
483*b1cdbd2cSJim Jagielski }
484*b1cdbd2cSJim Jagielski 
485