xref: /AOO41X/main/filter/source/xsltdialog/xmlfiltersettingsdialog.cxx (revision 9e0fc027f109ec4ffcb6033aeec742a099701108)
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