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_filter.hxx"
26 #include <com/sun/star/frame/XConfigManager.hpp>
27 #include <com/sun/star/container/XNameAccess.hpp>
28 #include <com/sun/star/util/XFlushable.hpp>
29 
30 #ifndef _COM_SUN_STAR_BEANS_NAMEDVALUE_HPP_
31 #include <com/sun/star/beans/PropertyValue.hpp>
32 #endif
33 
34 #include "com/sun/star/ui/dialogs/TemplateDescription.hpp"
35 #include <tools/urlobj.hxx>
36 #include <svtools/headbar.hxx>
37 #include <unotools/streamwrap.hxx>
38 #include <osl/file.hxx>
39 #include <vcl/msgbox.hxx>
40 #include <sfx2/filedlghelper.hxx>
41 
42 #include <rtl/uri.hxx>
43 
44 #include <algorithm>
45 
46 #include "xmlfilterdialogstrings.hrc"
47 #include "xmlfiltersettingsdialog.hxx"
48 #include "xmlfiltersettingsdialog.hrc"
49 #include "xmlfiltertabdialog.hxx"
50 #include "xmlfiltertestdialog.hxx"
51 #include "xmlfilterjar.hxx"
52 #include "xmlfilterhelpids.hrc"
53 
54 using namespace rtl;
55 using namespace osl;
56 using namespace com::sun::star::lang;
57 using namespace com::sun::star::uno;
58 using namespace com::sun::star::io;
59 using namespace com::sun::star::frame;
60 using namespace com::sun::star::container;
61 using namespace com::sun::star::beans;
62 using namespace com::sun::star::util;
63 
64 ResMgr* XMLFilterSettingsDialog::mpResMgr = NULL;
65 
XMLFilterSettingsDialog(Window * pParent,ResMgr & rResMgr,const com::sun::star::uno::Reference<com::sun::star::lang::XMultiServiceFactory> & rxMSF)66 XMLFilterSettingsDialog::XMLFilterSettingsDialog( Window* pParent, ResMgr& rResMgr, const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxMSF ) :
67 	WorkWindow( pParent, ResId( DLG_XML_FILTER_SETTINGS_DIALOG, rResMgr ) ),
68 	mxMSF( rxMSF ),
69 	maCtrlFilterList( this, ResId( CTRL_XML_FILTER_LIST, rResMgr ) ),
70 	maPBNew( this, ResId( PB_XML_FILTER_NEW, rResMgr ) ),
71 	maPBEdit( this, ResId( PB_XML_FILTER_EDIT, rResMgr ) ),
72 	maPBTest( this, ResId( PB_XML_FILTER_TEST, rResMgr ) ),
73 	maPBDelete( this, ResId( PB_XML_FILTER_DELETE, rResMgr ) ),
74 	maPBSave( this, ResId( PB_XML_FILTER_SAVE, rResMgr ) ),
75 	maPBOpen( this, ResId( PB_XML_FILTER_OPEN, rResMgr ) ),
76 	maPBHelp( this, ResId( BTN_XML_FILTER_HELP, rResMgr ) ),
77 	maPBClose( this, ResId( PB_XML_FILTER_CLOSE, rResMgr ) ),
78 	mbIsClosable(true),
79 	sTemplatePath( RTL_CONSTASCII_USTRINGPARAM( "$(user)/template/") ),
80 	sDocTypePrefix( RTL_CONSTASCII_USTRINGPARAM( "doctype:") )
81 {
82 	FreeResource();
83 
84 	mpResMgr = &rResMgr;
85 
86 	mpFilterListBox = new XMLFilterListBox( &maCtrlFilterList );
87 	mpFilterListBox->SetSelectHdl( LINK( this, XMLFilterSettingsDialog, SelectionChangedHdl_Impl ) );
88 	mpFilterListBox->SetDeselectHdl( LINK( this, XMLFilterSettingsDialog, SelectionChangedHdl_Impl ) );
89 	mpFilterListBox->SetDoubleClickHdl( LINK( this, XMLFilterSettingsDialog, DoubleClickHdl_Impl ) );
90 	mpFilterListBox->SetAccessibleName(String( RESID( STR_XML_FILTER_LISTBOX )));
91 	maCtrlFilterList.SetAccessibleName(String( RESID( STR_XML_FILTER_LISTBOX )));
92 	mpFilterListBox->SetHelpId( HID_XML_FILTER_LIST );
93 
94 	maPBNew.SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) );
95 	maPBEdit.SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) );
96 	maPBTest.SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) );
97 	maPBDelete.SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) );
98 	maPBSave.SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) );
99 	maPBOpen.SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) );
100 	maPBClose.SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) );
101 
102 	try
103 	{
104 		mxFilterContainer = Reference< XNameContainer >::query( rxMSF->createInstance( OUString::createFromAscii("com.sun.star.document.FilterFactory" ) ) );
105 		mxTypeDetection = Reference< XNameContainer >::query( rxMSF->createInstance( OUString::createFromAscii("com.sun.star.document.TypeDetection" ) ));
106 		mxExtendedTypeDetection = Reference< XNameContainer >::query( rxMSF->createInstance( OUString::createFromAscii("com.sun.star.document.ExtendedTypeDetectionFactory" ) ) );
107 
108 		Reference< XConfigManager > xCfgMgr( mxMSF->createInstance(OUString::createFromAscii("com.sun.star.config.SpecialConfigManager") ), UNO_QUERY );
109 		if( xCfgMgr.is() )
110 		{
111 			sTemplatePath = xCfgMgr->substituteVariables( sTemplatePath );
112 		}
113 	}
114 	catch(Exception&)
115 	{
116 		DBG_ERROR( "XMLFilterSettingsDialog::XMLFilterSettingsDialog exception catched!" );
117 	}
118 }
119 
120 // -----------------------------------------------------------------------
121 
~XMLFilterSettingsDialog()122 XMLFilterSettingsDialog::~XMLFilterSettingsDialog()
123 {
124 	delete mpFilterListBox;
125 }
126 
127 // -----------------------------------------------------------------------
128 
IMPL_LINK(XMLFilterSettingsDialog,ClickHdl_Impl,PushButton *,pButton)129 IMPL_LINK(XMLFilterSettingsDialog, ClickHdl_Impl, PushButton *, pButton )
130 {
131 	mbIsClosable = false;
132 
133 	if( &maPBNew == pButton )
134 	{
135 		onNew();
136 	}
137 	else if( &maPBEdit == pButton )
138 	{
139 		onEdit();
140 	}
141 	else if( &maPBTest == pButton )
142 	{
143 		onTest();
144 	}
145 	else if( &maPBDelete == pButton )
146 	{
147 		onDelete();
148 	}
149 	else if( &maPBSave == pButton )
150 	{
151 		onSave();
152 	}
153 	else if( &maPBOpen == pButton )
154 	{
155 		onOpen();
156 	}
157 	else if( &maPBClose == pButton )
158 	{
159 		onClose();
160 	}
161 
162 	mbIsClosable = true;
163 	return 0;
164 }
165 
166 // -----------------------------------------------------------------------
167 
IMPL_LINK(XMLFilterSettingsDialog,SelectionChangedHdl_Impl,void *,EMPTYARG)168 IMPL_LINK(XMLFilterSettingsDialog, SelectionChangedHdl_Impl, void *, EMPTYARG )
169 {
170 	updateStates();
171 	return 0;
172 }
173 
174 // -----------------------------------------------------------------------
175 
IMPL_LINK(XMLFilterSettingsDialog,DoubleClickHdl_Impl,void *,EMPTYARG)176 IMPL_LINK(XMLFilterSettingsDialog, DoubleClickHdl_Impl, void *, EMPTYARG )
177 {
178 	onEdit();
179 	return 0;
180 }
181 
isClosable()182 bool XMLFilterSettingsDialog::isClosable()
183 {
184 	return mbIsClosable;
185 }
186 
187 // -----------------------------------------------------------------------
188 
ShowWindow()189 void XMLFilterSettingsDialog::ShowWindow()
190 {
191 	maCtrlFilterList.GrabFocus();
192 	disposeFilterList();
193 	mpFilterListBox->Clear();
194 	initFilterList();
195 	updateStates();
196 	mpFilterListBox->Reset();
197 
198 	WorkWindow::Show( sal_True );
199 }
200 
201 // -----------------------------------------------------------------------
202 
updateStates()203 void XMLFilterSettingsDialog::updateStates()
204 {
205 	SvLBoxEntry* pSelectedEntry = mpFilterListBox->FirstSelected();
206 
207 	bool bHasSelection = pSelectedEntry != NULL;
208 
209 	bool bMultiSelection = bHasSelection && (mpFilterListBox->NextSelected( pSelectedEntry ) != NULL );
210     bool bIsReadonly = false;
211     bool bIsDefault = false;
212     if(pSelectedEntry)
213     {
214         filter_info_impl* pInfo = (filter_info_impl*)pSelectedEntry->GetUserData();
215         bIsReadonly = 0 != pInfo->mbReadonly;
216 
217         sal_Int32 nFact = SvtModuleOptions::E_WRITER;
218         while(nFact <= SvtModuleOptions::E_BASIC)
219         {
220             ::rtl::OUString sDefault = maModuleOpt.GetFactoryDefaultFilter((SvtModuleOptions::EFactory)nFact);
221             if( sDefault == pInfo->maFilterName )
222             {
223                 bIsDefault = true;
224                 break;
225             }
226             ++nFact;
227         }
228     }
229     maPBEdit.Enable( bHasSelection && !bMultiSelection && !bIsReadonly);
230 	maPBTest.Enable( bHasSelection && !bMultiSelection );
231     maPBDelete.Enable( bHasSelection && !bMultiSelection && !bIsReadonly && !bIsDefault);
232 	maPBSave.Enable( bHasSelection );
233 }
234 
235 // -----------------------------------------------------------------------
236 
237 /** is called when the user clicks on the "New" button */
onNew()238 void XMLFilterSettingsDialog::onNew()
239 {
240 	filter_info_impl aTempInfo;
241 
242 	// create a unique filter name
243 	aTempInfo.maFilterName = createUniqueFilterName( String( RESID( STR_DEFAULT_FILTER_NAME ) ) );
244 
245 	// init default extension
246 	String aDefaultExtension( RESID( STR_DEFAULT_EXTENSION ) );
247 	aTempInfo.maExtension = aDefaultExtension;
248 
249 	// set default ui name
250 	aTempInfo.maInterfaceName = createUniqueInterfaceName( String( RESID( STR_DEFAULT_UI_NAME ) ) );
251 
252 	// set default application
253 	aTempInfo.maDocumentService = OUString::createFromAscii("com.sun.star.text.TextDocument");
254 
255 	// execute XML Filter Dialog
256 	XMLFilterTabDialog aDlg( this, *mpResMgr, mxMSF, &aTempInfo );
257 	if ( aDlg.Execute() == RET_OK )
258 	{
259 		// insert the new filter
260 		insertOrEdit( aDlg.getNewFilterInfo() );
261 	}
262 }
263 
264 // -----------------------------------------------------------------------
265 
266 /** is called when the user clicks on the "Edit" Button */
onEdit()267 void XMLFilterSettingsDialog::onEdit()
268 {
269 	// get selected filter entry
270 	SvLBoxEntry* pEntry = mpFilterListBox->FirstSelected();
271 	if( pEntry )
272 	{
273 		// get its filter info
274 		filter_info_impl* pOldInfo = (filter_info_impl*)pEntry->GetUserData();
275 
276 		// execute XML Filter Dialog
277 		XMLFilterTabDialog aDlg( this, *mpResMgr, mxMSF, pOldInfo );
278 		if ( aDlg.Execute() == RET_OK )
279 		{
280 			filter_info_impl* pNewInfo = aDlg.getNewFilterInfo();
281 
282 			if( !(*pOldInfo == *pNewInfo) )
283 			{
284 				// change filter
285 				insertOrEdit( pNewInfo, pOldInfo );
286 			}
287 		}
288 	}
289 }
290 
291 // -----------------------------------------------------------------------
292 
293 /** helper to create a sequence of strings from an extensions strings
294 	"ext1;ext2;ext3" will become { "ext1", "ext2", "ext3" } */
createExtensionsSequence(const rtl::OUString & rExtensions)295 static Sequence< OUString > createExtensionsSequence( const rtl::OUString& rExtensions )
296 {
297 	// first count how many extensions we have inside the string
298 	int nExtensions = 0;
299 
300 	int nLength = rExtensions.getLength();
301 	if( nLength )
302 	{
303 		// a non empty string has at least one extension
304 		nExtensions++;
305 
306 		// now count the delimeters ';'
307 		const sal_Unicode * pString = rExtensions.getStr();
308 		int i;
309 		for( i = 0; i < nLength; i++, pString++ )
310 		{
311 			if( *pString == sal_Unicode( ';' ) )
312 				nExtensions++;
313 		}
314 	}
315 
316 	Sequence< OUString > aExtensions( nExtensions );
317 
318 	// extract the extensions from the source string and fill the sequence
319 
320 	int nLastIndex = 0;
321 	int nCurrentIndex = 0;
322 	int i;
323 
324 	for( i = 0; i < nExtensions; i++ )
325 	{
326 		nLastIndex = rExtensions.indexOf( sal_Unicode( ';' ), nLastIndex );
327 
328 		if( nLastIndex == -1 )
329 		{
330 			aExtensions[i] = rExtensions.copy( nCurrentIndex );
331 			break;
332 		}
333 		else
334 		{
335 			aExtensions[i] = rExtensions.copy( nCurrentIndex, nLastIndex - nCurrentIndex );
336 			nCurrentIndex = nLastIndex + 1;
337 			nLastIndex = nCurrentIndex;
338 		}
339 	}
340 
341 	return aExtensions;
342 }
343 
344 // -----------------------------------------------------------------------
345 
346 /** checks if the given name is unique inside the filter factory. If not,
347 	numbers are added until the returned name is unique */
createUniqueFilterName(const OUString & rFilterName)348 OUString XMLFilterSettingsDialog::createUniqueFilterName( const OUString& rFilterName )
349 {
350 	OUString aFilterName( rFilterName );
351 	OUString aSpace( sal_Unicode( ' ' ) );
352 
353 	sal_Int32 nId = 2;
354 
355 	while( mxFilterContainer->hasByName( aFilterName ) )
356 	{
357 		aFilterName = rFilterName;
358 		aFilterName += aSpace;
359 		aFilterName += OUString::valueOf( nId++ );
360 	}
361 
362 	return aFilterName;
363 }
364 
365 // -----------------------------------------------------------------------
366 
367 /** checks if the given name is unique inside the type detection. If not,
368 	numbers are added until the returned name is unique */
createUniqueTypeName(const OUString & rTypeName)369 OUString XMLFilterSettingsDialog::createUniqueTypeName( const OUString& rTypeName )
370 {
371 	OUString aTypeName( rTypeName );
372 	OUString aSpace( sal_Unicode( ' ' ) );
373 
374 	sal_Int32 nId = 2;
375 
376 	while( mxFilterContainer->hasByName( aTypeName ) )
377 	{
378 		aTypeName = rTypeName;
379 		aTypeName += aSpace;
380 		aTypeName += OUString::valueOf( nId++ );
381 	}
382 
383 	return aTypeName;
384 }
385 
386 /** checks if the given name is a unique ui name inside the filter factory. If not,
387 	numbers are added until the returned name is unique */
createUniqueInterfaceName(const OUString & rInterfaceName)388 OUString XMLFilterSettingsDialog::createUniqueInterfaceName( const OUString& rInterfaceName )
389 {
390 	sal_Int32 nDefaultNumber = 0;
391 
392 	try
393 	{
394 		Sequence< OUString > aFilterNames( mxFilterContainer->getElementNames() );
395 		OUString* pFilterName = aFilterNames.getArray();
396 
397 		const sal_Int32 nCount = aFilterNames.getLength();
398 		sal_Int32 nFilter;
399 
400 		Sequence< PropertyValue > aValues;
401 		for( nFilter = 0; (nFilter < nCount); nFilter++, pFilterName++ )
402 		{
403 			Any aAny( mxFilterContainer->getByName( *pFilterName ) );
404 			if( !(aAny >>= aValues) )
405 				continue;
406 
407 			const sal_Int32 nValueCount( aValues.getLength() );
408 			PropertyValue* pValues = aValues.getArray();
409 			sal_Int32 nValue;
410 
411 			for( nValue = 0; nValue < nValueCount; nValue++, pValues++ )
412 			{
413 				if( pValues->Name.equalsAscii( "UIName" ) )
414 				{
415 					OUString aInterfaceName;
416 					pValues->Value >>= aInterfaceName;
417 
418 
419 					// see if this filter matches our default filter name
420 					if( aInterfaceName.match( rInterfaceName ) )
421 					{
422 						// if yes, make sure we generate a unique name with a higher number
423 						// this is dump but fast
424 						sal_Int32 nNumber = aInterfaceName.copy( rInterfaceName.getLength() ).toInt32();
425 						if( nNumber >= nDefaultNumber )
426 							nDefaultNumber = nNumber + 1;
427 					}
428 				}
429 			}
430 		}
431 	}
432 	catch( Exception& )
433 	{
434 		DBG_ERROR( "XMLFilterSettingsDialog::createUniqueInterfaceName exception catched!" );
435 	}
436 
437 	OUString aInterfaceName( rInterfaceName );
438 	if( nDefaultNumber )
439 	{
440 		aInterfaceName += OUString( sal_Unicode( ' ' ) );
441 		aInterfaceName += String::CreateFromInt32( nDefaultNumber );
442 	}
443 
444 	return aInterfaceName;
445 }
446 
447 // -----------------------------------------------------------------------
448 
449 /** inserts a new filter into the ui and configuration if pOldInfo is NULL.
450 	If pOldInfo is not null, the old filter will be replaced with the new settings */
insertOrEdit(filter_info_impl * pNewInfo,const filter_info_impl * pOldInfo)451 bool XMLFilterSettingsDialog::insertOrEdit( filter_info_impl* pNewInfo, const filter_info_impl* pOldInfo )
452 {
453 	bool bOk = true;
454 
455 	if( pOldInfo )
456 	{
457 		// see if we need to update the type name
458 		if( pOldInfo->maFilterName != pNewInfo->maFilterName )
459 		{
460 			if( pOldInfo->maType == pOldInfo->maFilterName )
461 			{
462 				pNewInfo->maType = OUString();
463 			}
464 		}
465 
466 		// see if we need to clean up old stuff first
467 		try
468 		{
469 			// if filter name changed, we need to remove the old filter first
470 			if( pOldInfo->maFilterName != pNewInfo->maFilterName )
471 				mxFilterContainer->removeByName( pOldInfo->maFilterName );
472 
473 			// if type name changed, we need to remove the old type first
474 			if( pOldInfo->maType != pNewInfo->maType )
475 				mxTypeDetection->removeByName( pOldInfo->maType );
476 		}
477 		catch( Exception& )
478 		{
479 			DBG_ERROR( "XMLFilterSettingsDialog::insertOrEdit exception catched!" );
480 			bOk = false;
481 		}
482 	}
483 
484 	filter_info_impl* pFilterEntry( NULL );
485 
486 	if( bOk )
487 	{
488 		// create or copy filter info
489 		if( pOldInfo )
490 		{
491 			// change existing filter entry in filter list box
492 			pFilterEntry = const_cast<filter_info_impl*>(pOldInfo);
493 			*pFilterEntry = *pNewInfo;
494 		}
495 		else
496 		{
497 			// add new entry to filter list box
498 			pFilterEntry = new filter_info_impl( *pNewInfo );
499 		}
500 	}
501 
502 	// check if we need to copy the template
503 	if( pFilterEntry->maImportTemplate.getLength() )
504 	{
505 		if( !pFilterEntry->maImportTemplate.matchIgnoreAsciiCase( sTemplatePath ) )
506 		{
507 			INetURLObject aSourceURL( pFilterEntry->maImportTemplate );
508 			if( aSourceURL.GetName().getLength() != 0 )
509 			{
510 				OUString aDestURL( sTemplatePath );
511 				aDestURL += pFilterEntry->maFilterName;
512 				aDestURL += OUString( sal_Unicode('/') );
513 				if( createDirectory( aDestURL ) )
514 				{
515 					aDestURL += aSourceURL.GetName();
516 
517 					SvFileStream aInputStream(pFilterEntry->maImportTemplate, STREAM_READ );
518 					Reference< XInputStream > xIS( new utl::OInputStreamWrapper( aInputStream ) );
519 					SvFileStream aOutputStream(aDestURL, STREAM_WRITE );
520 					Reference< XOutputStream > xOS(  new utl::OOutputStreamWrapper( aOutputStream ) );
521 
522 					if( copyStreams( xIS, xOS ) )
523 						pFilterEntry->maImportTemplate = aDestURL;
524 				}
525 			}
526 		}
527 	}
528 
529 	if( bOk )
530 	{
531 		if( pFilterEntry->maType.getLength() == 0 )
532 		{
533 			pFilterEntry->maType = createUniqueTypeName( pNewInfo->maFilterName );
534 		}
535 
536 		// update import/export flags
537 		if( pFilterEntry->maImportXSLT.getLength() )
538 		{
539 			pFilterEntry->maFlags |= 1;
540 		}
541 		else
542 		{
543 			pFilterEntry->maFlags &= ~1;
544 		}
545 
546 		if( pFilterEntry->maExportXSLT.getLength() )
547 		{
548 			pFilterEntry->maFlags |= 2;
549 		}
550 		else
551 		{
552 			pFilterEntry->maFlags &= ~2;
553 		}
554 		pFilterEntry->maFlags |= 0x80040;
555 
556 		// 2. create user data for filter entry
557 		Sequence< OUString > aUserData( pFilterEntry->getFilterUserData());
558 
559 		// 3. create property values for filter entry
560 		Sequence< PropertyValue > aFilterData( 8 );
561 
562 		aFilterData[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ) );
563 		aFilterData[0].Value <<= pFilterEntry->maType;
564 
565 		aFilterData[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ) );
566 		aFilterData[1].Value <<= pFilterEntry->maInterfaceName;
567 
568 		aFilterData[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentService" ) );
569 		aFilterData[2].Value <<= pFilterEntry->maDocumentService;
570 
571 		aFilterData[3].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterService" ) );
572 		aFilterData[3].Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Writer.XmlFilterAdaptor" ) );
573 
574 		aFilterData[4].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Flags" ) );
575 		aFilterData[4].Value <<= pFilterEntry->maFlags;
576 
577 		aFilterData[5].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "UserData" ) );
578 		aFilterData[5].Value <<= aUserData;
579 
580 		aFilterData[6].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "FileFormatVersion" ) );
581 		aFilterData[6].Value <<= pFilterEntry->maFileFormatVersion;
582 
583 		aFilterData[7].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "TemplateName" ) );
584 		aFilterData[7].Value <<= pFilterEntry->maImportTemplate;
585 
586 		// 4. insert new or replace existing filter
587 		try
588 		{
589 			Any aAny( makeAny( aFilterData ) );
590 			if( mxFilterContainer->hasByName( pFilterEntry->maFilterName ) )
591 			{
592 				mxFilterContainer->replaceByName( pFilterEntry->maFilterName, aAny );
593 			}
594 			else
595 			{
596 				mxFilterContainer->insertByName( pFilterEntry->maFilterName, aAny );
597 			}
598 		}
599 		catch( Exception& )
600 		{
601 			DBG_ERROR( "XMLFilterSettingsDialog::insertOrEdit exception catched!" );
602 			bOk = false;
603 		}
604 	}
605 
606 	// 5. prepare type information
607 	if( bOk )
608 	{
609 		Sequence< PropertyValue > aValues(4);
610 
611 		aValues[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ) );
612 		aValues[0].Value <<= pFilterEntry->maInterfaceName;
613 /*
614 		aValues[i  ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
615 		aValues[i++].Value <<= pFilterEntry->maDocType;
616 */
617 		aValues[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "ClipboardFormat" ) );
618 		OUString aDocType;
619     	if( !pFilterEntry->maDocType.match( sDocTypePrefix ) )
620 		{
621 			aDocType = sDocTypePrefix;
622 			aDocType += pFilterEntry->maDocType;
623 		}
624 		else
625 		{
626 			aDocType = pFilterEntry->maDocType;
627 		}
628         if (aDocType == sDocTypePrefix)
629             aValues[1].Value <<= OUString();
630         else
631 		    aValues[1].Value <<= aDocType;
632 
633 		aValues[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentIconID" ) );
634 		aValues[2].Value <<= pFilterEntry->mnDocumentIconID;
635 
636 		aValues[3].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Extensions" ) );
637 		aValues[3].Value <<= createExtensionsSequence( pFilterEntry->maExtension );
638 
639         // the detect service will only be registered, if a doctype/search token was specified
640         if (aDocType.getLength() > sDocTypePrefix.getLength())
641         {
642             aValues.realloc(5);
643 		    aValues[4].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "DetectService" ) );
644 		    aValues[4].Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.filters.XMLFilterDetect" ) );
645         }
646 
647 		// 6. insert new or replace existing type information
648 		if( mxTypeDetection.is() )
649 		{
650 			try
651 			{
652 				Any aAny( makeAny( aValues ) );
653 				if( mxTypeDetection->hasByName( pFilterEntry->maType ) )
654 				{
655 					mxTypeDetection->replaceByName( pFilterEntry->maType, aAny );
656 				}
657 				else
658 				{
659 					mxTypeDetection->insertByName( pFilterEntry->maType, aAny );
660 				}
661 			}
662 			catch( Exception& )
663 			{
664 				DBG_ERROR( "XMLFilterSettingsDialog::insertOrEdit exception catched!" );
665 				bOk = false;
666 			}
667 		}
668 
669 		if( bOk )
670 		{
671 			try
672 			{
673 				Reference< XFlushable > xFlushable = Reference< XFlushable >::query( mxTypeDetection );
674 				if( xFlushable.is() )
675 					xFlushable->flush();
676 			}
677 			catch( Exception& )
678 			{
679 				DBG_ERROR( "XMLFilterSettingsDialog::insertOrEdit exception catched!" );
680 				bOk = false;
681 			}
682 		}
683 
684 		if( !bOk )
685 		{
686 			// we failed to add the type, so lets remove the filter
687 			try
688 			{
689 				mxFilterContainer->removeByName( pFilterEntry->maFilterName );
690 			}
691 			catch( Exception& )
692 			{
693 				DBG_ERROR( "XMLFilterSettingsDialog::insertOrEdit exception catched!" );
694 				bOk = false;
695 			}
696 		}
697 		else
698 		{
699 			if( bOk )
700 			{
701 				try
702 				{
703 					Reference< XFlushable > xFlushable( mxFilterContainer, UNO_QUERY );
704 					if( xFlushable.is() )
705 						xFlushable->flush();
706 				}
707 				catch( Exception& )
708 				{
709 					DBG_ERROR( "XMLFilterSettingsDialog::insertOrEdit exception catched!" );
710 					bOk = false;
711 				}
712 
713 				if( !bOk )
714 				{
715 					// we failed to add the filter, so lets remove the type
716 					try
717 					{
718 						mxTypeDetection->removeByName( pFilterEntry->maType );
719 					}
720 					catch( Exception& )
721 					{
722 						DBG_ERROR( "XMLFilterSettingsDialog::insertOrEdit exception catched!" );
723 					}
724 				}
725 
726 			}
727 		}
728 	}
729 
730 	if( bOk )
731 	{
732 		if( mxExtendedTypeDetection.is() )
733 		{
734 			OUString sFilterDetectService( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.filters.XMLFilterDetect") );
735 			if( mxExtendedTypeDetection->hasByName( sFilterDetectService ) )
736 			{
737 				Sequence< PropertyValue > aSequence;
738 				if( mxExtendedTypeDetection->getByName( sFilterDetectService ) >>= aSequence )
739 				{
740 					sal_Int32 nCount = aSequence.getLength();
741 					sal_Int32 nIndex;
742 					for( nIndex = 0; nIndex < nCount; nIndex++ )
743 					{
744 						OUString aName( aSequence[nIndex].Name );
745 						if( aSequence[nIndex].Name.equalsAscii( "Types" ) )
746 						{
747 							Sequence< OUString > aTypes;
748 							if( aSequence[nIndex].Value >>= aTypes )
749 							{
750 								sal_Int32 nStrCount = aTypes.getLength();
751 								sal_Int32 nStr;
752 								for( nStr = 0; nStr < nStrCount; nStr++ )
753 								{
754 									OUString aType( aTypes[nStr] );
755 									if( aTypes[nStr] == pFilterEntry->maType )
756 										break;
757 								}
758 
759 								if( nStr == nStrCount )
760 								{
761 									aTypes.realloc( nStrCount + 1 );
762 									aTypes[nStrCount] = pFilterEntry->maType;
763 
764 									aSequence[nIndex].Value <<= aTypes;
765 
766 									mxExtendedTypeDetection->replaceByName( sFilterDetectService, makeAny( aSequence ) );
767 
768 									Reference< XFlushable > xFlushable( mxExtendedTypeDetection, UNO_QUERY );
769 									if( xFlushable.is() )
770 										xFlushable->flush();
771 								}
772 							}
773 
774 							break;
775 						}
776 					}
777 				}
778 			}
779 		}
780 	}
781 
782 	// update ui
783 	if( bOk )
784 	{
785 		if( pOldInfo )
786 		{
787 			mpFilterListBox->changeEntry( pFilterEntry );
788 		}
789 		else
790 		{
791 			mpFilterListBox->addFilterEntry( pFilterEntry );
792 			maFilterVector.push_back( pFilterEntry );
793 		}
794 	}
795 
796 	return bOk;
797 }
798 
799 // -----------------------------------------------------------------------
800 
801 /** is called when the user clicks the "Test" button */
onTest()802 void XMLFilterSettingsDialog::onTest()
803 {
804 	// get the first selected filter
805 	SvLBoxEntry* pEntry = mpFilterListBox->FirstSelected();
806 	if( pEntry )
807 	{
808 		filter_info_impl* pInfo = (filter_info_impl*)pEntry->GetUserData();
809 
810 		XMLFilterTestDialog aDlg( this, *mpResMgr, mxMSF );
811 		aDlg.test( *pInfo );
812 	}
813 }
814 
815 // -----------------------------------------------------------------------
816 
onDelete()817 void XMLFilterSettingsDialog::onDelete()
818 {
819 	SvLBoxEntry* pEntry = mpFilterListBox->FirstSelected();
820 	if( pEntry )
821 	{
822 		filter_info_impl* pInfo = (filter_info_impl*)pEntry->GetUserData();
823 
824 		String aPlaceHolder( RTL_CONSTASCII_USTRINGPARAM("%s") );
825 		String aMessage(RESID(STR_WARN_DELETE));
826 		aMessage.SearchAndReplace( aPlaceHolder, pInfo->maFilterName );
827 
828 		WarningBox aWarnBox(this, (WinBits)(WB_YES_NO | WB_DEF_YES),	aMessage );
829 		if( aWarnBox.Execute() == RET_YES )
830 		{
831 			try
832 			{
833 				if( mxFilterContainer->hasByName( pInfo->maFilterName ) )
834 				{
835 					mxFilterContainer->removeByName( pInfo->maFilterName );
836 
837 					bool bTypeStillUsed = false;
838 
839 					// now loop over all filter and see if someone else uses the same type
840 					Sequence< OUString > aFilterNames( mxFilterContainer->getElementNames() );
841 					OUString* pFilterName = aFilterNames.getArray();
842 
843 					const sal_Int32 nCount = aFilterNames.getLength();
844 					sal_Int32 nFilter;
845 					Sequence< PropertyValue > aValues;
846 
847 					for( nFilter = 0; (nFilter < nCount) && !bTypeStillUsed; nFilter++, pFilterName++ )
848 					{
849 						Any aAny( mxFilterContainer->getByName( *pFilterName ) );
850 						if( !(aAny >>= aValues) )
851 							continue;
852 
853 						const sal_Int32 nValueCount( aValues.getLength() );
854 						PropertyValue* pValues = aValues.getArray();
855 						sal_Int32 nValue;
856 
857 						for( nValue = 0; (nValue < nValueCount) && !bTypeStillUsed; nValue++, pValues++ )
858 						{
859 							if( pValues->Name.equalsAscii( "Type" ) )
860 							{
861 								OUString aType;
862 								pValues->Value >>= aType;
863 								if( aType == pInfo->maType )
864 									bTypeStillUsed = true;
865 
866 								break;
867 							}
868 						}
869 					}
870 
871 					// if the type is not used anymore, remove it also
872 					if( !bTypeStillUsed )
873 					{
874 						if( mxTypeDetection->hasByName( pInfo->maType ) )
875 						{
876 							mxTypeDetection->removeByName( pInfo->maType );
877 						}
878 					}
879 
880 					Reference< XFlushable > xFlushable( mxFilterContainer, UNO_QUERY );
881 					if( xFlushable.is() )
882 						xFlushable->flush();
883 
884 					xFlushable = Reference< XFlushable >::query( mxTypeDetection );
885 					if( xFlushable.is() )
886 						xFlushable->flush();
887 
888 					// now remove entry from ui
889 					mpFilterListBox->RemoveSelection();
890 
891 					// and delete the filter entry
892 					maFilterVector.erase(std::find( maFilterVector.begin(), maFilterVector.end(), pInfo ));
893 
894 					delete pInfo;
895 				}
896 			}
897 			catch( Exception& )
898 			{
899 				DBG_ERROR( "XMLFilterSettingsDialog::onDelete exception catched!" );
900 			}
901 		}
902 	}
903 
904 	updateStates();
905 }
906 
907 // -----------------------------------------------------------------------
908 
onSave()909 void XMLFilterSettingsDialog::onSave()
910 {
911 	XMLFilterVector aFilters;
912 
913 	int nFilters = 0;
914 
915 	SvLBoxEntry* pEntry = mpFilterListBox->FirstSelected();
916 	while( pEntry )
917 	{
918 		filter_info_impl* pInfo = (filter_info_impl*)pEntry->GetUserData();
919 		aFilters.push_back( pInfo );
920 		pEntry = mpFilterListBox->NextSelected( pEntry );
921 		nFilters++;
922 	}
923 
924 	// Open Fileopen-Dialog
925    	::sfx2::FileDialogHelper aDlg(
926         com::sun::star::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION,
927         0 );
928 
929 	String aExtensions( RTL_CONSTASCII_USTRINGPARAM("*.jar") );
930 	String aFilterName( RESID( STR_FILTER_PACKAGE ) );
931 	aFilterName += String( RTL_CONSTASCII_USTRINGPARAM(" (") );
932 	aFilterName += aExtensions;
933 	aFilterName += sal_Unicode(')');
934 
935 	aDlg.AddFilter( aFilterName, aExtensions );
936 
937 	if ( aDlg.Execute() == ERRCODE_NONE )
938 	{
939 		XMLFilterJarHelper aJarHelper( mxMSF );
940 		aJarHelper.savePackage( aDlg.GetPath(), aFilters );
941 
942 		INetURLObject aURL( aDlg.GetPath() );
943 
944 		String sPlaceholder( RTL_CONSTASCII_USTRINGPARAM( "%s" ) );
945 
946 		String aMsg;
947 		if( nFilters > 0 )
948 		{
949 			aMsg = String( RESID( STR_FILTERS_HAVE_BEEN_SAVED ) );
950 			aMsg.SearchAndReplace( sPlaceholder, String::CreateFromInt32(nFilters) );
951 			aMsg.SearchAndReplace( sPlaceholder, aURL.GetName() );
952 		}
953 		else
954 		{
955 			aMsg = String( RESID( STR_FILTER_HAS_BEEN_SAVED ) );
956 			aMsg.SearchAndReplace( sPlaceholder, (*aFilters.begin())->maFilterName );
957 			aMsg.SearchAndReplace( sPlaceholder, aURL.GetName() );
958 		}
959 
960 		InfoBox aBox(this, aMsg );
961 		aBox.Execute();
962 	}
963 }
964 
965 // -----------------------------------------------------------------------
966 
onOpen()967 void XMLFilterSettingsDialog::onOpen()
968 {
969 	XMLFilterVector aFilters;
970 
971 	// Open Fileopen-Dialog
972    	::sfx2::FileDialogHelper aDlg(
973         com::sun::star::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, 0 );
974 
975 	String aExtensions( RTL_CONSTASCII_USTRINGPARAM("*.jar") );
976 	String aFilterName( RESID( STR_FILTER_PACKAGE ) );
977 	aFilterName += String( RTL_CONSTASCII_USTRINGPARAM(" (") );
978 	aFilterName += aExtensions;
979 	aFilterName += sal_Unicode(')');
980 
981 	aDlg.AddFilter( aFilterName, aExtensions );
982 
983 	if ( aDlg.Execute() == ERRCODE_NONE )
984 	{
985 		OUString aURL( aDlg.GetPath() );
986 
987 		XMLFilterJarHelper aJarHelper( mxMSF );
988 		aJarHelper.openPackage( aURL, aFilters );
989 
990 		int nFilters = 0;
991 		XMLFilterVector::iterator aIter( aFilters.begin() );
992 		while( aIter != aFilters.end() )
993 		{
994 			filter_info_impl* pInfo = (*aIter++);
995 
996 			if( insertOrEdit( pInfo ) )
997 			{
998 				aFilterName = pInfo->maFilterName;
999 				nFilters++;
1000 			}
1001 
1002 			delete pInfo;
1003 		}
1004 
1005 		disposeFilterList();
1006 		initFilterList();
1007 
1008 		String sPlaceholder( RTL_CONSTASCII_USTRINGPARAM( "%s" ) );
1009 		String aMsg;
1010 		if( nFilters == 0 )
1011 		{
1012 			INetURLObject aURLObj( aURL );
1013 			aMsg = String( RESID( STR_NO_FILTERS_FOUND ) );
1014 			aMsg.SearchAndReplace( sPlaceholder, aURLObj.GetName() );
1015 		}
1016 		else if( nFilters == 1 )
1017 		{
1018 			aMsg = String( RESID( STR_FILTER_INSTALLED ) );
1019 			aMsg.SearchAndReplace( sPlaceholder, aFilterName );
1020 
1021 		}
1022 		else
1023 		{
1024 			aMsg = String( RESID( STR_FILTERS_INSTALLED ) );
1025 			aMsg.SearchAndReplace( sPlaceholder, String::CreateFromInt32(nFilters) );
1026 		}
1027 
1028 		InfoBox aBox(this, aMsg );
1029 		aBox.Execute();
1030 	}
1031 }
1032 
1033 // -----------------------------------------------------------------------
1034 
onClose()1035 void XMLFilterSettingsDialog::onClose()
1036 {
1037 	Close();
1038 }
1039 
Notify(NotifyEvent & rNEvt)1040 long XMLFilterSettingsDialog::Notify( NotifyEvent& rNEvt )
1041 {
1042     // Zuerst Basisklasse rufen wegen TabSteuerung
1043     long nRet = WorkWindow::Notify( rNEvt );
1044     if ( !nRet )
1045     {
1046         if ( rNEvt.GetType() == EVENT_KEYINPUT )
1047         {
1048             const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
1049             KeyCode         aKeyCode = pKEvt->GetKeyCode();
1050             sal_uInt16          nKeyCode = aKeyCode.GetCode();
1051 
1052             if( nKeyCode == KEY_ESCAPE )
1053             {
1054                 Close();
1055                 return sal_True;
1056             }
1057         }
1058 	}
1059 
1060 	return nRet;
1061 }
1062 
1063 // -----------------------------------------------------------------------
1064 
disposeFilterList()1065 void XMLFilterSettingsDialog::disposeFilterList()
1066 {
1067 	std::vector< filter_info_impl* >::iterator aIter( maFilterVector.begin() );
1068 	while( aIter != maFilterVector.end() )
1069 	{
1070 		delete (*aIter++);
1071 	}
1072 	maFilterVector.clear();
1073 
1074 	mpFilterListBox->Clear();
1075 }
1076 
1077 // -----------------------------------------------------------------------
1078 
initFilterList()1079 void XMLFilterSettingsDialog::initFilterList()
1080 {
1081 	if( mxFilterContainer.is() )
1082 	{
1083 		Sequence< OUString > aFilterNames( mxFilterContainer->getElementNames() );
1084 		OUString* pFilterName = aFilterNames.getArray();
1085 
1086 		const sal_Int32 nCount = aFilterNames.getLength();
1087 		sal_Int32 nFilter;
1088 
1089 		Sequence< PropertyValue > aValues;
1090 
1091 		filter_info_impl* pTempFilter = new filter_info_impl;
1092 		Sequence< OUString > aUserData;
1093 
1094 		for( nFilter = 0; nFilter < nCount; nFilter++, pFilterName++ )
1095 		{
1096 			aUserData.realloc(0);
1097 
1098 			try
1099 			{
1100 				Any aAny( mxFilterContainer->getByName( *pFilterName ) );
1101 				if( !(aAny >>= aValues) )
1102 					continue;
1103 
1104 				OUString aFilterService;
1105 				pTempFilter->maFilterName = *pFilterName;
1106 
1107 				const sal_Int32 nValueCount( aValues.getLength() );
1108 				PropertyValue* pValues = aValues.getArray();
1109 				sal_Int32 nValue;
1110 
1111 				for( nValue = 0; nValue < nValueCount; nValue++, pValues++ )
1112 				{
1113 					if( pValues->Name.equalsAscii( "Type" ) )
1114 					{
1115 						pValues->Value >>= pTempFilter->maType;
1116 					}
1117 					else if( pValues->Name.equalsAscii( "UIName" ) )
1118 					{
1119 						pValues->Value >>= pTempFilter->maInterfaceName;
1120 					}
1121 					else if( pValues->Name.equalsAscii( "DocumentService" ) )
1122 					{
1123 						pValues->Value >>= pTempFilter->maDocumentService;
1124 					}
1125 					else if( pValues->Name.equalsAscii( "FilterService" ) )
1126 					{
1127 						pValues->Value >>= aFilterService;
1128 					}
1129 					else if( pValues->Name.equalsAscii( "Flags" ) )
1130 					{
1131 						pValues->Value >>= pTempFilter->maFlags;
1132 					}
1133 					else if( pValues->Name.equalsAscii( "UserData" ) )
1134 					{
1135 						pValues->Value >>= aUserData;
1136 					}
1137 					else if( pValues->Name.equalsAscii( "FileFormatVersion" ) )
1138 					{
1139 						pValues->Value >>= pTempFilter->maFileFormatVersion;
1140 					}
1141 					else if( pValues->Name.equalsAscii( "TemplateName" ) )
1142 					{
1143 						pValues->Value >>= pTempFilter->maImportTemplate;
1144 					}
1145                     else if(pValues->Name.equalsAscii( "Finalized" ))
1146                     {
1147                         pValues->Value >>= pTempFilter->mbReadonly;
1148                     }
1149                 }
1150 
1151 				// if this is not a XmlFilterAdaptor entry, skip it
1152 				if( !aFilterService.equalsAscii( "com.sun.star.comp.Writer.XmlFilterAdaptor" ) )
1153 					continue;
1154 
1155 
1156 				// if we don't have the needed user data, skip it
1157 				if( aUserData.getLength() < 6 )
1158 					continue;
1159 
1160 				// if this is not an XSLTFilter entry, skip it
1161 				if( !aUserData[0].equalsAscii( "com.sun.star.documentconversion.XSLTFilter" ) )
1162 					continue;
1163 
1164 				// get filter information from userdata
1165 				pTempFilter->maImportService = aUserData[2];
1166 				pTempFilter->maExportService = aUserData[3];
1167 				pTempFilter->maImportXSLT = aUserData[4];
1168 				pTempFilter->maExportXSLT = aUserData[5];
1169 				if( aUserData.getLength() >= 7 )
1170 					pTempFilter->maDTD = aUserData[6];
1171 				if( aUserData.getLength() >= 8 )
1172 					pTempFilter->maComment = aUserData[7];
1173 
1174 				// get type information
1175 				if( mxTypeDetection.is() )
1176 				{
1177 					try
1178 					{
1179 						aAny = mxTypeDetection->getByName( pTempFilter->maType );
1180 						Sequence< PropertyValue > aValues2;
1181 
1182 						if( aAny >>= aValues2 )
1183 						{
1184 							const sal_Int32 nValueCount2( aValues2.getLength() );
1185 							PropertyValue* pValues2 = aValues2.getArray();
1186 							sal_Int32 nValue2;
1187 
1188 							for( nValue2 = 0; nValue2 < nValueCount2; nValue2++, pValues2++ )
1189 							{
1190 /*
1191 								if( pValues2->Name.equalsAscii( "MediaType" ) )
1192 								{
1193 									pValues2->Value >>= pTempFilter->maDocType;
1194 								} else
1195 */
1196 								if( pValues2->Name.equalsAscii( "ClipboardFormat" ) )
1197 								{
1198 									OUString aDocType;
1199 									pValues2->Value >>= aDocType;
1200 
1201 									if( aDocType.match( sDocTypePrefix ) )
1202 										aDocType = aDocType.copy( sDocTypePrefix.getLength() );
1203 
1204 									pTempFilter->maDocType = aDocType;
1205 								}
1206 								else if( pValues2->Name.equalsAscii( "Extensions" ) )
1207 								{
1208 									Sequence< OUString > aExtensions;
1209 									if( pValues2->Value >>= aExtensions )
1210 									{
1211 										pTempFilter->maExtension = OUString();
1212 
1213 										sal_Int32 nCount3( aExtensions.getLength() );
1214 										OUString* pExtensions = aExtensions.getArray();
1215 										sal_Int32 n;
1216 										for( n = 0; n < nCount3; n++ )
1217 										{
1218 											if( n > 0 )
1219 												pTempFilter->maExtension += OUString( sal_Unicode(';') );
1220 											pTempFilter->maExtension += (*pExtensions++);
1221 										}
1222 									}
1223 								}
1224 								else if( pValues2->Name.equalsAscii( "DocumentIconID" ) )
1225 								{
1226 									pValues2->Value >>= pTempFilter->mnDocumentIconID;
1227 								}
1228                                 else if(pValues2->Name.equalsAscii( "Finalized" ))
1229                                 {
1230                                     // both the filter and the type may be finalized
1231                                     sal_Bool bTemp = sal_False;
1232                                     pValues2->Value >>= bTemp;
1233                                     pTempFilter->mbReadonly |= bTemp;
1234                                 }
1235 							}
1236 						}
1237 					}
1238 					catch( ::com::sun::star::container::NoSuchElementException& )
1239 					{
1240 						DBG_ERROR( "Type not found, user error?" ); // TODO: error?
1241 					}
1242 				}
1243 
1244 				// add entry to internal container and to ui filter list box
1245 				maFilterVector.push_back( pTempFilter );
1246 				mpFilterListBox->addFilterEntry( pTempFilter );
1247 
1248 
1249 				pTempFilter = new filter_info_impl;
1250 			}
1251 			catch( Exception& )
1252 			{
1253 				DBG_ERROR( "XMLFilterSettingsDialog::initFilterList exception catched!" );
1254 			}
1255 
1256 		}
1257 
1258 		delete pTempFilter;
1259 	}
1260 
1261 	SvLBoxEntry* pEntry = mpFilterListBox->GetEntry( 0 );
1262 	if( pEntry )
1263 		mpFilterListBox->Select( pEntry );
1264 }
1265 
1266 // -----------------------------------------------------------------------
1267 
1268 // -----------------------------------------------------------------------
1269 
application_info_impl(const sal_Char * pDocumentService,ResId & rUINameRes,const sal_Char * mpXMLImporter,const sal_Char * mpXMLExporter)1270 application_info_impl::application_info_impl( const sal_Char * pDocumentService, ResId& rUINameRes, const sal_Char * mpXMLImporter, const sal_Char * mpXMLExporter )
1271 :	maDocumentService( pDocumentService, strlen( pDocumentService ), RTL_TEXTENCODING_ASCII_US ),
1272 	maDocumentUIName( String( rUINameRes ) ),
1273 	maXMLImporter( mpXMLImporter, strlen( mpXMLImporter ), RTL_TEXTENCODING_ASCII_US ),
1274 	maXMLExporter( mpXMLExporter, strlen( mpXMLExporter ), RTL_TEXTENCODING_ASCII_US )
1275 {
1276 }
1277 
1278 // -----------------------------------------------------------------------
1279 
getApplicationInfos()1280 std::vector< application_info_impl* >& getApplicationInfos()
1281 {
1282 	static std::vector< application_info_impl* > aInfos;
1283 
1284 	if( aInfos.empty() )
1285 	{
1286         ResId aResId1( STR_APPL_NAME_WRITER, *getXSLTDialogResMgr() );
1287 		aInfos.push_back( new application_info_impl(
1288 			"com.sun.star.text.TextDocument",
1289 			aResId1,
1290 			"com.sun.star.comp.Writer.XMLImporter",
1291 			"com.sun.star.comp.Writer.XMLExporter" ) );
1292 
1293 		ResId aResId2( STR_APPL_NAME_CALC, *getXSLTDialogResMgr() );
1294 		aInfos.push_back( new application_info_impl(
1295 			"com.sun.star.sheet.SpreadsheetDocument",
1296 			aResId2,
1297 			"com.sun.star.comp.Calc.XMLImporter",
1298 			"com.sun.star.comp.Calc.XMLExporter" ) );
1299 
1300 		ResId aResId3( STR_APPL_NAME_IMPRESS, *getXSLTDialogResMgr() );
1301 		aInfos.push_back( new application_info_impl(
1302 			"com.sun.star.presentation.PresentationDocument",
1303 			aResId3,
1304 			"com.sun.star.comp.Impress.XMLImporter",
1305 			"com.sun.star.comp.Impress.XMLExporter" ) );
1306 
1307 		ResId aResId4( STR_APPL_NAME_DRAW, *getXSLTDialogResMgr() );
1308 		aInfos.push_back( new application_info_impl(
1309 			"com.sun.star.drawing.DrawingDocument",
1310 			aResId4,
1311 			"com.sun.star.comp.Draw.XMLImporter",
1312 			"com.sun.star.comp.Draw.XMLExporter" ) );
1313 
1314         // --- oasis file formats...
1315 	    ResId aResId5( STR_APPL_NAME_OASIS_WRITER, *getXSLTDialogResMgr() );
1316 		aInfos.push_back( new application_info_impl(
1317 			"com.sun.star.text.TextDocument",
1318 			aResId5,
1319 			"com.sun.star.comp.Writer.XMLOasisImporter",
1320 			"com.sun.star.comp.Writer.XMLOasisExporter" ) );
1321 
1322 		ResId aResId6( STR_APPL_NAME_OASIS_CALC, *getXSLTDialogResMgr() );
1323 		aInfos.push_back( new application_info_impl(
1324 			"com.sun.star.sheet.SpreadsheetDocument",
1325 			aResId6,
1326 			"com.sun.star.comp.Calc.XMLOasisImporter",
1327 			"com.sun.star.comp.Calc.XMLOasisExporter" ) );
1328 
1329 		ResId aResId7( STR_APPL_NAME_OASIS_IMPRESS, *getXSLTDialogResMgr() );
1330 		aInfos.push_back( new application_info_impl(
1331 			"com.sun.star.presentation.PresentationDocument",
1332 			aResId7,
1333 			"com.sun.star.comp.Impress.XMLOasisImporter",
1334 			"com.sun.star.comp.Impress.XMLOasisExporter" ) );
1335 
1336 		ResId aResId8( STR_APPL_NAME_OASIS_DRAW, *getXSLTDialogResMgr() );
1337 		aInfos.push_back( new application_info_impl(
1338 			"com.sun.star.drawing.DrawingDocument",
1339 			aResId8,
1340 			"com.sun.star.comp.Draw.XMLOasisImporter",
1341 			"com.sun.star.comp.Draw.XMLOasisExporter" ) );
1342 }
1343 
1344 	return aInfos;
1345 }
1346 
1347 // -----------------------------------------------------------------------
1348 
getApplicationInfo(const OUString & rServiceName)1349 const application_info_impl* getApplicationInfo( const OUString& rServiceName )
1350 {
1351 	std::vector< application_info_impl* >& rInfos = getApplicationInfos();
1352 	std::vector< application_info_impl* >::iterator aIter( rInfos.begin() );
1353 	while( aIter != rInfos.end() )
1354 	{
1355 		// if( rServiceName == (*aIter)->maDocumentService )
1356         if( rServiceName == (*aIter)->maXMLExporter ||
1357             rServiceName == (*aIter)->maXMLImporter)
1358 		{
1359 			return (*aIter);
1360 		}
1361 		aIter++;
1362 	}
1363 	return NULL;
1364 }
1365 
1366 // -----------------------------------------------------------------------
1367 
getApplicationUIName(const OUString & rServiceName)1368 OUString getApplicationUIName( const OUString& rServiceName )
1369 {
1370 	const application_info_impl* pInfo = getApplicationInfo( rServiceName );
1371 	if( pInfo )
1372 	{
1373 		return pInfo->maDocumentUIName;
1374 	}
1375 	else
1376 	{
1377 		OUString aRet = String( RESID( STR_UNKNOWN_APPLICATION ) );
1378 		if( rServiceName.getLength() )
1379 		{
1380 			aRet += OUString::createFromAscii(" (");
1381 			aRet += rServiceName;
1382 			aRet += OUString::createFromAscii(")");
1383 		}
1384 		return aRet;
1385 	}
1386 }
1387 
1388 // -----------------------------------------------------------------------
1389 
getXSLTDialogResMgr()1390 ResMgr* getXSLTDialogResMgr()
1391 {
1392 	return XMLFilterSettingsDialog::mpResMgr;
1393 }
1394 
1395 // -----------------------------------------------------------------------
1396 
1397 // -----------------------------------------------------------------------
1398 
Notify(NotifyEvent & rNEvt)1399 long SvxPathControl_Impl::Notify( NotifyEvent& rNEvt )
1400 {
1401 	long nRet = Control::Notify( rNEvt );
1402 
1403 	if ( m_pFocusCtrl && rNEvt.GetWindow() != m_pFocusCtrl && rNEvt.GetType() == EVENT_GETFOCUS )
1404 		m_pFocusCtrl->GrabFocus();
1405 	return nRet;
1406 }
1407 
1408 #define ITEMID_NAME		1
1409 #define ITEMID_TYPE		2
1410 
XMLFilterListBox(SvxPathControl_Impl * pParent)1411 XMLFilterListBox::XMLFilterListBox( SvxPathControl_Impl * pParent )
1412 :	SvTabListBox( pParent, WB_SORT | WB_HSCROLL | WB_CLIPCHILDREN | WB_TABSTOP ),
1413 	mbFirstPaint( true )
1414 {
1415 	Size aBoxSize( pParent->GetOutputSizePixel() );
1416 
1417 	mpHeaderBar = new HeaderBar( pParent, /*WB_BUTTONSTYLE | */ WB_BOTTOMBORDER );
1418 	mpHeaderBar->SetPosSizePixel( Point( 0, 0 ), Size( aBoxSize.Width(), 16 ) );
1419 	mpHeaderBar->SetEndDragHdl( LINK( this, XMLFilterListBox, HeaderEndDrag_Impl ) );
1420 
1421 	String aStr1( RESID( STR_COLUMN_HEADER_NAME ) );
1422 	String aStr2( RESID( STR_COLUMN_HEADER_TYPE ) );
1423 
1424 	long nTabSize = aBoxSize.Width() / 2;
1425 
1426 	mpHeaderBar->InsertItem( ITEMID_NAME, aStr1, nTabSize,
1427 							HIB_LEFT | HIB_VCENTER );
1428 	mpHeaderBar->InsertItem( ITEMID_TYPE, aStr2, nTabSize,
1429 							HIB_LEFT | HIB_VCENTER );
1430 
1431 	static long nTabs[] = {3, 0, nTabSize, 2*nTabSize };
1432 	Size aHeadSize( mpHeaderBar->GetSizePixel() );
1433 
1434 	pParent->SetFocusControl( this );
1435 //	SetDoubleClickHdl( aLink );
1436 //	SetSelectHdl( LINK( this, SvxPathTabPage, PathSelect_Impl ) );
1437 	SetSelectionMode( MULTIPLE_SELECTION );
1438 	SetPosSizePixel( Point( 0, aHeadSize.Height() ), Size( aBoxSize.Width(), aBoxSize.Height() - aHeadSize.Height() ) );
1439 	SetTabs( &nTabs[0], MAP_PIXEL );
1440 	SetScrolledHdl( LINK( this, XMLFilterListBox, TabBoxScrollHdl_Impl ) );
1441 	SetHighlightRange();
1442 //	SetHelpId( HID_OPTPATH_CTL_PATH );
1443 //	mpHeaderBar->SetHelpId( HID_OPTPATH_HEADERBAR );
1444 	Show();
1445 	mpHeaderBar->Show();
1446 }
1447 
1448 // -----------------------------------------------------------------------
1449 
~XMLFilterListBox()1450 XMLFilterListBox::~XMLFilterListBox()
1451 {
1452 	delete mpHeaderBar;
1453 }
1454 
1455 // -----------------------------------------------------------------------
1456 
Reset()1457 void XMLFilterListBox::Reset()
1458 {
1459 	Size aBoxSize( Window::GetParent()->GetOutputSizePixel() );
1460 	long nTabSize = aBoxSize.Width() / 2;
1461 	static long nTabs[] = {3, 0, nTabSize, 2*nTabSize };
1462 	SetTabs( &nTabs[0], MAP_PIXEL );
1463 	mpHeaderBar->SetItemSize( ITEMID_NAME, nTabSize );
1464 	mpHeaderBar->SetItemSize( ITEMID_TYPE, nTabSize );
1465 }
1466 
1467 // -----------------------------------------------------------------------
1468 
Paint(const Rectangle & rRect)1469 void XMLFilterListBox::Paint( const Rectangle& rRect )
1470 {
1471 	if( mbFirstPaint )
1472 	{
1473 		mbFirstPaint = false;
1474 		RepaintScrollBars();
1475 	}
1476 
1477 	SvTabListBox::Paint( rRect );
1478 }
1479 
1480 IMPL_LINK( XMLFilterListBox, TabBoxScrollHdl_Impl, SvTabListBox*, /* pList */ )
1481 {
1482 	mpHeaderBar->SetOffset( -GetXOffset() );
1483 	return 0;
1484 }
1485 
1486 // -----------------------------------------------------------------------
1487 
IMPL_LINK(XMLFilterListBox,HeaderSelect_Impl,HeaderBar *,pBar)1488 IMPL_LINK( XMLFilterListBox, HeaderSelect_Impl, HeaderBar*, pBar )
1489 {
1490 	if ( pBar && pBar->GetCurItemId() != ITEMID_NAME )
1491 		return 0;
1492 
1493 	HeaderBarItemBits nBits	= mpHeaderBar->GetItemBits(ITEMID_TYPE);
1494 	sal_Bool bUp = ( ( nBits & HIB_UPARROW ) == HIB_UPARROW );
1495 	SvSortMode eMode = SortAscending;
1496 
1497 	if ( bUp )
1498 	{
1499 		nBits &= ~HIB_UPARROW;
1500 		nBits |= HIB_DOWNARROW;
1501 		eMode = SortDescending;
1502 	}
1503 	else
1504 	{
1505 		nBits &= ~HIB_DOWNARROW;
1506 		nBits |= HIB_UPARROW;
1507 	}
1508 	mpHeaderBar->SetItemBits( ITEMID_NAME, nBits );
1509 	SvTreeList* pMod = GetModel();
1510 	pMod->SetSortMode( eMode );
1511 	pMod->Resort();
1512 	return 1;
1513 }
1514 
1515 // -----------------------------------------------------------------------
1516 
IMPL_LINK(XMLFilterListBox,HeaderEndDrag_Impl,HeaderBar *,pBar)1517 IMPL_LINK( XMLFilterListBox, HeaderEndDrag_Impl, HeaderBar*, pBar )
1518 {
1519 	if ( pBar && !pBar->GetCurItemId() )
1520 		return 0;
1521 
1522 	if ( !mpHeaderBar->IsItemMode() )
1523 	{
1524 		Size aSz;
1525 		sal_uInt16 nTabs = mpHeaderBar->GetItemCount();
1526 		long nTmpSz = 0;
1527 		long nWidth = mpHeaderBar->GetItemSize(ITEMID_NAME);
1528 		long nBarWidth = mpHeaderBar->GetSizePixel().Width();
1529 
1530         if(nWidth < 30)
1531             mpHeaderBar->SetItemSize( ITEMID_TYPE, 30);
1532         else if ( ( nBarWidth - nWidth ) < 30 )
1533             mpHeaderBar->SetItemSize( ITEMID_TYPE, nBarWidth - 30 );
1534 
1535 		for ( sal_uInt16 i = 1; i <= nTabs; ++i )
1536 		{
1537 			long nW = mpHeaderBar->GetItemSize(i);
1538 			aSz.Width() =  nW + nTmpSz;
1539 			nTmpSz += nW;
1540 			SetTab( i, PixelToLogic( aSz, MapMode(MAP_APPFONT) ).Width(), MAP_APPFONT );
1541 		}
1542 	}
1543 	return 1;
1544 }
1545 
1546 // -----------------------------------------------------------------------
1547 
1548 /** adds a new filter info entry to the ui filter list */
addFilterEntry(const filter_info_impl * pInfo)1549 void XMLFilterListBox::addFilterEntry( const filter_info_impl* pInfo )
1550 {
1551 	const XubString aEntryStr( getEntryString( pInfo ) );
1552 	InsertEntryToColumn( aEntryStr, LIST_APPEND, 0xffff, (void*)pInfo );
1553 }
1554 
1555 // -----------------------------------------------------------------------
1556 
changeEntry(const filter_info_impl * pInfo)1557 void XMLFilterListBox::changeEntry( const filter_info_impl* pInfo )
1558 {
1559 	const sal_uLong nCount = GetEntryCount();
1560 	sal_uLong nPos;
1561 	for( nPos = 0; nPos < nCount; nPos++ )
1562 	{
1563 		SvLBoxEntry* pEntry = GetEntry( nPos );
1564 		if( (filter_info_impl*)pEntry->GetUserData() == pInfo )
1565 		{
1566 			XubString aEntryText( getEntryString( pInfo ) );
1567 			SetEntryText( aEntryText, pEntry );
1568 			break;
1569 		}
1570 	}
1571 }
1572 
1573 // -----------------------------------------------------------------------
1574 
getEntryString(const filter_info_impl * pInfo) const1575 String XMLFilterListBox::getEntryString( const filter_info_impl* pInfo ) const
1576 {
1577 	String aEntryStr( pInfo->maFilterName );
1578 	aEntryStr += '\t';
1579 	// aEntryStr += String( getApplicationUIName( pInfo->maDocumentService ) );
1580     if ( pInfo->maExportService.getLength() > 0 )
1581         aEntryStr += String( getApplicationUIName( pInfo->maExportService ) );
1582     else
1583         aEntryStr += String( getApplicationUIName( pInfo->maImportService ) );
1584 	aEntryStr += ' ';
1585 	aEntryStr += '-';
1586 	aEntryStr += ' ';
1587 
1588 	if( pInfo->maFlags & 1 )
1589 	{
1590 		if( pInfo->maFlags & 2 )
1591 		{
1592 			aEntryStr += String( RESID( STR_IMPORT_EXPORT ) );
1593 		}
1594 		else
1595 		{
1596 			aEntryStr += String( RESID( STR_IMPORT_ONLY ) );
1597 		}
1598 	}
1599 	else if( pInfo->maFlags & 2 )
1600 	{
1601 		aEntryStr += String( RESID( STR_EXPORT_ONLY ) );
1602 	}
1603 	else
1604 	{
1605 		aEntryStr += String( RESID( STR_UNDEFINED_FILTER ) );
1606 	}
1607 
1608 	return aEntryStr;
1609 }
1610 
1611 // -----------------------------------------------------------------------
1612 
1613 // -----------------------------------------------------------------------
1614 
filter_info_impl()1615 filter_info_impl::filter_info_impl()
1616 :	maFlags(0x00080040),
1617 	maFileFormatVersion(0),
1618     mnDocumentIconID(0),
1619     mbReadonly(sal_False)
1620 {
1621 }
1622 
1623 // -----------------------------------------------------------------------
1624 
filter_info_impl(const filter_info_impl & rInfo)1625 filter_info_impl::filter_info_impl( const filter_info_impl& rInfo ) :
1626 	maFilterName( rInfo.maFilterName ),
1627 	maType( rInfo.maType ),
1628 	maDocumentService( rInfo.maDocumentService ),
1629 	maFilterService( rInfo.maFilterService ),
1630 	maInterfaceName( rInfo.maInterfaceName ),
1631 	maComment( rInfo.maComment ),
1632 	maExtension( rInfo.maExtension ),
1633 	maDTD( rInfo.maDTD ),
1634 	maExportXSLT( rInfo.maExportXSLT ),
1635 	maImportXSLT( rInfo.maImportXSLT ),
1636 	maImportTemplate( rInfo.maImportTemplate ),
1637 	maDocType( rInfo.maDocType ),
1638 	maImportService( rInfo.maImportService ),
1639 	maExportService( rInfo.maExportService ),
1640 	maFlags( rInfo.maFlags ),
1641 	maFileFormatVersion( rInfo.maFileFormatVersion ),
1642     mnDocumentIconID( rInfo.mnDocumentIconID ),
1643     mbReadonly( rInfo.mbReadonly )
1644 {
1645 }
1646 
1647 // -----------------------------------------------------------------------
1648 
operator ==(const filter_info_impl & r) const1649 int filter_info_impl::operator==( const filter_info_impl& r ) const
1650 {
1651 	if( maFilterName != r.maFilterName ||
1652 		maType != r.maType ||
1653 		maDocumentService != r.maDocumentService ||
1654 		maFilterService != r.maFilterService ||
1655 		maInterfaceName != r.maInterfaceName ||
1656 		maComment != r.maComment ||
1657 		maExtension != r.maExtension ||
1658 		maDocType != r.maDocType ||
1659 		maDTD != r.maDTD ||
1660 		maExportXSLT != r.maExportXSLT ||
1661 		maImportXSLT != r.maImportXSLT ||
1662         maExportService != r.maExportService ||
1663 		maImportService != r.maImportService ||
1664 		maImportTemplate != r.maImportTemplate ||
1665 		maFlags != r.maFlags ||
1666 		maFileFormatVersion != r.maFileFormatVersion )
1667 		return false;
1668 
1669 	return true;
1670 }
1671 
1672 // -----------------------------------------------------------------------
1673 
getFilterUserData() const1674 Sequence< OUString > filter_info_impl::getFilterUserData() const
1675 {
1676 	Sequence< OUString > aUserData(8);
1677 
1678 	aUserData[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.documentconversion.XSLTFilter" ) );
1679     /*
1680 	const application_info_impl* pInfo = getApplicationInfo( maDocumentService );
1681 	if( pInfo )
1682 	{
1683 		aUserData[2] = pInfo->maXMLImporter;
1684 		aUserData[3] = pInfo->maXMLExporter;
1685 	}
1686     */
1687 	aUserData[2] = maImportService;
1688 	aUserData[3] = maExportService;
1689     aUserData[4] = maImportXSLT;
1690 	aUserData[5] = maExportXSLT;
1691 	aUserData[6] = maDTD;
1692 	aUserData[7] = maComment;
1693 
1694 	return aUserData;
1695 }
1696 
1697 
1698 // -----------------------------------------------------------------------
1699 
string_encode(const OUString & rText)1700 OUString string_encode( const OUString & rText )
1701 {
1702 
1703 	static sal_Bool const aCharClass[]
1704     =  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* UricNoSlash */
1705          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1706          0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, /* !"#$%&'()*+,-./*/
1707          1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, /*0123456789:;<=>?*/
1708          1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*@ABCDEFGHIJKLMNO*/
1709          1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /*PQRSTUVWXYZ[\]^_*/
1710          0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*`abcdefghijklmno*/
1711          1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0  /*pqrstuvwxyz{|}~ */
1712        };
1713 
1714 
1715 	return Uri::encode( rText, aCharClass, rtl_UriEncodeCheckEscapes, RTL_TEXTENCODING_UTF8 );
1716 }
1717 
1718 // -----------------------------------------------------------------------
1719 
string_decode(const OUString & rText)1720 OUString string_decode( const OUString & rText )
1721 {
1722 	return Uri::decode( rText, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
1723 }
1724 
1725 // -----------------------------------------------------------------------
1726 
isFileURL(const::rtl::OUString & rURL)1727 bool isFileURL( const ::rtl::OUString & rURL )
1728 {
1729 	return rURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM("file:") ) == 0;
1730 }
1731 
1732 // -----------------------------------------------------------------------
1733 
copyStreams(Reference<XInputStream> xIS,Reference<XOutputStream> xOS)1734 bool copyStreams( Reference< XInputStream > xIS, Reference< XOutputStream > xOS )
1735 {
1736 	try
1737 	{
1738 		sal_Int32 nBufferSize = 512;
1739 		Sequence< sal_Int8 > aDataBuffer(nBufferSize);
1740 
1741 		sal_Int32 nRead;
1742 		do
1743 		{
1744 			nRead = xIS->readBytes( aDataBuffer, nBufferSize );
1745 
1746 			if( nRead )
1747 			{
1748 				if( nRead < nBufferSize )
1749 				{
1750 					nBufferSize = nRead;
1751 					aDataBuffer.realloc(nRead);
1752 				}
1753 
1754 				xOS->writeBytes( aDataBuffer );
1755 			}
1756 		}
1757 		while( nRead );
1758 
1759 		xOS->flush();
1760 
1761 		return true;
1762 	}
1763 	catch(Exception&)
1764 	{
1765 		DBG_ERROR( "copyStreams() exception catched!" );
1766 	}
1767 
1768 	return false;
1769 }
1770 
1771 // -----------------------------------------------------------------------
1772 
createDirectory(OUString & rURL)1773 bool createDirectory( OUString& rURL )
1774 {
1775 	sal_Int32 nLastIndex = sizeof( "file:///" ) - 2;
1776 	while( nLastIndex != -1 )
1777 	{
1778 		nLastIndex = rURL.indexOf( sal_Unicode('/'), nLastIndex + 1);
1779 		if( nLastIndex != -1 )
1780 		{
1781 			OUString aDirURL( rURL.copy( 0, nLastIndex ) );
1782 			Directory aDir( aDirURL );
1783 			Directory::RC rc = aDir.open();
1784 			if( rc == Directory::E_NOENT )
1785 				rc = osl::Directory::create( aDirURL );
1786 
1787 			if( rc != Directory::E_None )
1788 			{
1789 				return false;
1790 			}
1791 		}
1792 	}
1793 
1794 	return true;
1795 }
1796