diff options
Diffstat (limited to 'filter/source/xsltdialog/xmlfiltersettingsdialog.cxx')
-rw-r--r-- | filter/source/xsltdialog/xmlfiltersettingsdialog.cxx | 1800 |
1 files changed, 1800 insertions, 0 deletions
diff --git a/filter/source/xsltdialog/xmlfiltersettingsdialog.cxx b/filter/source/xsltdialog/xmlfiltersettingsdialog.cxx new file mode 100644 index 000000000000..33a0aff4e5b4 --- /dev/null +++ b/filter/source/xsltdialog/xmlfiltersettingsdialog.cxx @@ -0,0 +1,1800 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_filter.hxx" +#include <com/sun/star/frame/XConfigManager.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/util/XFlushable.hpp> + +#include <com/sun/star/beans/PropertyValue.hpp> + +#include "com/sun/star/ui/dialogs/TemplateDescription.hpp" +#include <tools/urlobj.hxx> +#include <svtools/headbar.hxx> +#include <unotools/streamwrap.hxx> +#include <osl/file.hxx> +#include <vcl/msgbox.hxx> +#include <sfx2/filedlghelper.hxx> + +#include <rtl/uri.hxx> + +#include <algorithm> + +#include "xmlfilterdialogstrings.hrc" +#include "xmlfiltersettingsdialog.hxx" +#include "xmlfiltersettingsdialog.hrc" +#include "xmlfiltertabdialog.hxx" +#include "xmlfiltertestdialog.hxx" +#include "xmlfilterjar.hxx" +#include "xmlfilterhelpids.hrc" + +using namespace rtl; +using namespace osl; +using namespace com::sun::star::lang; +using namespace com::sun::star::uno; +using namespace com::sun::star::io; +using namespace com::sun::star::frame; +using namespace com::sun::star::container; +using namespace com::sun::star::beans; +using namespace com::sun::star::util; + +ResMgr* XMLFilterSettingsDialog::mpResMgr = NULL; + +XMLFilterSettingsDialog::XMLFilterSettingsDialog( Window* pParent, ResMgr& rResMgr, const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxMSF ) : + WorkWindow( pParent, ResId( DLG_XML_FILTER_SETTINGS_DIALOG, rResMgr ) ), + mxMSF( rxMSF ), + maCtrlFilterList( this, ResId( CTRL_XML_FILTER_LIST, rResMgr ) ), + maPBNew( this, ResId( PB_XML_FILTER_NEW, rResMgr ) ), + maPBEdit( this, ResId( PB_XML_FILTER_EDIT, rResMgr ) ), + maPBTest( this, ResId( PB_XML_FILTER_TEST, rResMgr ) ), + maPBDelete( this, ResId( PB_XML_FILTER_DELETE, rResMgr ) ), + maPBSave( this, ResId( PB_XML_FILTER_SAVE, rResMgr ) ), + maPBOpen( this, ResId( PB_XML_FILTER_OPEN, rResMgr ) ), + maPBHelp( this, ResId( BTN_XML_FILTER_HELP, rResMgr ) ), + maPBClose( this, ResId( PB_XML_FILTER_CLOSE, rResMgr ) ), + mbIsClosable(true), + sTemplatePath( RTL_CONSTASCII_USTRINGPARAM( "$(user)/template/") ), + sDocTypePrefix( RTL_CONSTASCII_USTRINGPARAM( "doctype:") ) +{ + FreeResource(); + + mpResMgr = &rResMgr; + + mpFilterListBox = new XMLFilterListBox( &maCtrlFilterList ); + mpFilterListBox->SetSelectHdl( LINK( this, XMLFilterSettingsDialog, SelectionChangedHdl_Impl ) ); + mpFilterListBox->SetDeselectHdl( LINK( this, XMLFilterSettingsDialog, SelectionChangedHdl_Impl ) ); + mpFilterListBox->SetDoubleClickHdl( LINK( this, XMLFilterSettingsDialog, DoubleClickHdl_Impl ) ); + mpFilterListBox->SetHelpId( HID_XML_FILTER_LIST ); + + maPBNew.SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) ); + maPBEdit.SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) ); + maPBTest.SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) ); + maPBDelete.SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) ); + maPBSave.SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) ); + maPBOpen.SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) ); + maPBClose.SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) ); + + try + { + mxFilterContainer = Reference< XNameContainer >::query( rxMSF->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.FilterFactory" )) ) ); + mxTypeDetection = Reference< XNameContainer >::query( rxMSF->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.TypeDetection" )) )); + mxExtendedTypeDetection = Reference< XNameContainer >::query( rxMSF->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.ExtendedTypeDetectionFactory" )) ) ); + + Reference< XConfigManager > xCfgMgr( mxMSF->createInstance(OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.config.SpecialConfigManager" )) ), UNO_QUERY ); + if( xCfgMgr.is() ) + { + sTemplatePath = xCfgMgr->substituteVariables( sTemplatePath ); + } + } + catch(Exception&) + { + DBG_ERROR( "XMLFilterSettingsDialog::XMLFilterSettingsDialog exception catched!" ); + } +} + +// ----------------------------------------------------------------------- + +XMLFilterSettingsDialog::~XMLFilterSettingsDialog() +{ + delete mpFilterListBox; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK(XMLFilterSettingsDialog, ClickHdl_Impl, PushButton *, pButton ) +{ + mbIsClosable = false; + + if( &maPBNew == pButton ) + { + onNew(); + } + else if( &maPBEdit == pButton ) + { + onEdit(); + } + else if( &maPBTest == pButton ) + { + onTest(); + } + else if( &maPBDelete == pButton ) + { + onDelete(); + } + else if( &maPBSave == pButton ) + { + onSave(); + } + else if( &maPBOpen == pButton ) + { + onOpen(); + } + else if( &maPBClose == pButton ) + { + onClose(); + } + + mbIsClosable = true; + return 0; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK(XMLFilterSettingsDialog, SelectionChangedHdl_Impl, void *, EMPTYARG ) +{ + updateStates(); + return 0; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK(XMLFilterSettingsDialog, DoubleClickHdl_Impl, void *, EMPTYARG ) +{ + onEdit(); + return 0; +} + +bool XMLFilterSettingsDialog::isClosable() +{ + return mbIsClosable; +} + +// ----------------------------------------------------------------------- + +void XMLFilterSettingsDialog::ShowWindow() +{ + maCtrlFilterList.GrabFocus(); + disposeFilterList(); + mpFilterListBox->Clear(); + initFilterList(); + updateStates(); + mpFilterListBox->Reset(); + + WorkWindow::Show( TRUE ); +} + +// ----------------------------------------------------------------------- + +void XMLFilterSettingsDialog::updateStates() +{ + SvLBoxEntry* pSelectedEntry = mpFilterListBox->FirstSelected(); + + bool bHasSelection = pSelectedEntry != NULL; + + bool bMultiSelection = bHasSelection && (mpFilterListBox->NextSelected( pSelectedEntry ) != NULL ); + bool bIsReadonly = false; + bool bIsDefault = false; + if(pSelectedEntry) + { + filter_info_impl* pInfo = (filter_info_impl*)pSelectedEntry->GetUserData(); + bIsReadonly = 0 != pInfo->mbReadonly; + + sal_Int32 nFact = SvtModuleOptions::E_WRITER; + while(nFact <= SvtModuleOptions::E_BASIC) + { + ::rtl::OUString sDefault = maModuleOpt.GetFactoryDefaultFilter((SvtModuleOptions::EFactory)nFact); + if( sDefault == pInfo->maFilterName ) + { + bIsDefault = true; + break; + } + ++nFact; + } + } + maPBEdit.Enable( bHasSelection && !bMultiSelection && !bIsReadonly); + maPBTest.Enable( bHasSelection && !bMultiSelection ); + maPBDelete.Enable( bHasSelection && !bMultiSelection && !bIsReadonly && !bIsDefault); + maPBSave.Enable( bHasSelection ); +} + +// ----------------------------------------------------------------------- + +/** is called when the user clicks on the "New" button */ +void XMLFilterSettingsDialog::onNew() +{ + filter_info_impl aTempInfo; + + // create a unique filter name + aTempInfo.maFilterName = createUniqueFilterName( String( RESID( STR_DEFAULT_FILTER_NAME ) ) ); + + // init default extension + String aDefaultExtension( RESID( STR_DEFAULT_EXTENSION ) ); + aTempInfo.maExtension = aDefaultExtension; + + // set default ui name + aTempInfo.maInterfaceName = createUniqueInterfaceName( String( RESID( STR_DEFAULT_UI_NAME ) ) ); + + // set default application + aTempInfo.maDocumentService = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextDocument" )); + + // execute XML Filter Dialog + XMLFilterTabDialog aDlg( this, *mpResMgr, mxMSF, &aTempInfo ); + if ( aDlg.Execute() == RET_OK ) + { + // insert the new filter + insertOrEdit( aDlg.getNewFilterInfo() ); + } +} + +// ----------------------------------------------------------------------- + +/** is called when the user clicks on the "Edit" Button */ +void XMLFilterSettingsDialog::onEdit() +{ + // get selected filter entry + SvLBoxEntry* pEntry = mpFilterListBox->FirstSelected(); + if( pEntry ) + { + // get its filter info + filter_info_impl* pOldInfo = (filter_info_impl*)pEntry->GetUserData(); + + // execute XML Filter Dialog + XMLFilterTabDialog aDlg( this, *mpResMgr, mxMSF, pOldInfo ); + if ( aDlg.Execute() == RET_OK ) + { + filter_info_impl* pNewInfo = aDlg.getNewFilterInfo(); + + if( !(*pOldInfo == *pNewInfo) ) + { + // change filter + insertOrEdit( pNewInfo, pOldInfo ); + } + } + } +} + +// ----------------------------------------------------------------------- + +/** helper to create a sequence of strings from an extensions strings + "ext1;ext2;ext3" will become { "ext1", "ext2", "ext3" } */ +static Sequence< OUString > createExtensionsSequence( const rtl::OUString& rExtensions ) +{ + // first count how many extensions we have inside the string + int nExtensions = 0; + + int nLength = rExtensions.getLength(); + if( nLength ) + { + // a non empty string has at least one extension + nExtensions++; + + // now count the delimeters ';' + const sal_Unicode * pString = rExtensions.getStr(); + int i; + for( i = 0; i < nLength; i++, pString++ ) + { + if( *pString == sal_Unicode( ';' ) ) + nExtensions++; + } + } + + Sequence< OUString > aExtensions( nExtensions ); + + // extract the extensions from the source string and fill the sequence + + int nLastIndex = 0; + int nCurrentIndex = 0; + int i; + + for( i = 0; i < nExtensions; i++ ) + { + nLastIndex = rExtensions.indexOf( sal_Unicode( ';' ), nLastIndex ); + + if( nLastIndex == -1 ) + { + aExtensions[i] = rExtensions.copy( nCurrentIndex ); + break; + } + else + { + aExtensions[i] = rExtensions.copy( nCurrentIndex, nLastIndex - nCurrentIndex ); + nCurrentIndex = nLastIndex + 1; + nLastIndex = nCurrentIndex; + } + } + + return aExtensions; +} + +// ----------------------------------------------------------------------- + +/** checks if the given name is unique inside the filter factory. If not, + numbers are added until the returned name is unique */ +OUString XMLFilterSettingsDialog::createUniqueFilterName( const OUString& rFilterName ) +{ + OUString aFilterName( rFilterName ); + OUString aSpace( sal_Unicode( ' ' ) ); + + sal_Int32 nId = 2; + + while( mxFilterContainer->hasByName( aFilterName ) ) + { + aFilterName = rFilterName; + aFilterName += aSpace; + aFilterName += OUString::valueOf( nId++ ); + } + + return aFilterName; +} + +// ----------------------------------------------------------------------- + +/** checks if the given name is unique inside the type detection. If not, + numbers are added until the returned name is unique */ +OUString XMLFilterSettingsDialog::createUniqueTypeName( const OUString& rTypeName ) +{ + OUString aTypeName( rTypeName ); + OUString aSpace( sal_Unicode( ' ' ) ); + + sal_Int32 nId = 2; + + while( mxFilterContainer->hasByName( aTypeName ) ) + { + aTypeName = rTypeName; + aTypeName += aSpace; + aTypeName += OUString::valueOf( nId++ ); + } + + return aTypeName; +} + +/** checks if the given name is a unique ui name inside the filter factory. If not, + numbers are added until the returned name is unique */ +OUString XMLFilterSettingsDialog::createUniqueInterfaceName( const OUString& rInterfaceName ) +{ + sal_Int32 nDefaultNumber = 0; + + try + { + Sequence< OUString > aFilterNames( mxFilterContainer->getElementNames() ); + OUString* pFilterName = aFilterNames.getArray(); + + const sal_Int32 nCount = aFilterNames.getLength(); + sal_Int32 nFilter; + + Sequence< PropertyValue > aValues; + for( nFilter = 0; (nFilter < nCount); nFilter++, pFilterName++ ) + { + Any aAny( mxFilterContainer->getByName( *pFilterName ) ); + if( !(aAny >>= aValues) ) + continue; + + const sal_Int32 nValueCount( aValues.getLength() ); + PropertyValue* pValues = aValues.getArray(); + sal_Int32 nValue; + + for( nValue = 0; nValue < nValueCount; nValue++, pValues++ ) + { + if( pValues->Name.equalsAscii( "UIName" ) ) + { + OUString aInterfaceName; + pValues->Value >>= aInterfaceName; + + + // see if this filter matches our default filter name + if( aInterfaceName.match( rInterfaceName ) ) + { + // if yes, make sure we generate a unique name with a higher number + // this is dump but fast + sal_Int32 nNumber = aInterfaceName.copy( rInterfaceName.getLength() ).toInt32(); + if( nNumber >= nDefaultNumber ) + nDefaultNumber = nNumber + 1; + } + } + } + } + } + catch( Exception& ) + { + DBG_ERROR( "XMLFilterSettingsDialog::createUniqueInterfaceName exception catched!" ); + } + + OUString aInterfaceName( rInterfaceName ); + if( nDefaultNumber ) + { + aInterfaceName += OUString( sal_Unicode( ' ' ) ); + aInterfaceName += String::CreateFromInt32( nDefaultNumber ); + } + + return aInterfaceName; +} + +// ----------------------------------------------------------------------- + +/** inserts a new filter into the ui and configuration if pOldInfo is NULL. + If pOldInfo is not null, the old filter will be replaced with the new settings */ +bool XMLFilterSettingsDialog::insertOrEdit( filter_info_impl* pNewInfo, const filter_info_impl* pOldInfo ) +{ + bool bOk = true; + + if( pOldInfo ) + { + // see if we need to update the type name + if( pOldInfo->maFilterName != pNewInfo->maFilterName ) + { + if( pOldInfo->maType == pOldInfo->maFilterName ) + { + pNewInfo->maType = OUString(); + } + } + + // see if we need to clean up old stuff first + try + { + // if filter name changed, we need to remove the old filter first + if( pOldInfo->maFilterName != pNewInfo->maFilterName ) + mxFilterContainer->removeByName( pOldInfo->maFilterName ); + + // if type name changed, we need to remove the old type first + if( pOldInfo->maType != pNewInfo->maType ) + mxTypeDetection->removeByName( pOldInfo->maType ); + } + catch( Exception& ) + { + DBG_ERROR( "XMLFilterSettingsDialog::insertOrEdit exception catched!" ); + bOk = false; + } + } + + filter_info_impl* pFilterEntry( NULL ); + + if( bOk ) + { + // create or copy filter info + if( pOldInfo ) + { + // change existing filter entry in filter list box + pFilterEntry = const_cast<filter_info_impl*>(pOldInfo); + *pFilterEntry = *pNewInfo; + } + else + { + // add new entry to filter list box + pFilterEntry = new filter_info_impl( *pNewInfo ); + } + } + + // check if we need to copy the template + if( pFilterEntry->maImportTemplate.getLength() ) + { + if( !pFilterEntry->maImportTemplate.matchIgnoreAsciiCase( sTemplatePath ) ) + { + INetURLObject aSourceURL( pFilterEntry->maImportTemplate ); + if( aSourceURL.GetName().getLength() != 0 ) + { + OUString aDestURL( sTemplatePath ); + aDestURL += pFilterEntry->maFilterName; + aDestURL += OUString( sal_Unicode('/') ); + if( createDirectory( aDestURL ) ) + { + aDestURL += aSourceURL.GetName(); + + SvFileStream aInputStream(pFilterEntry->maImportTemplate, STREAM_READ ); + Reference< XInputStream > xIS( new utl::OInputStreamWrapper( aInputStream ) ); + SvFileStream aOutputStream(aDestURL, STREAM_WRITE ); + Reference< XOutputStream > xOS( new utl::OOutputStreamWrapper( aOutputStream ) ); + + if( copyStreams( xIS, xOS ) ) + pFilterEntry->maImportTemplate = aDestURL; + } + } + } + } + + if( bOk ) + { + if( pFilterEntry->maType.getLength() == 0 ) + { + pFilterEntry->maType = createUniqueTypeName( pNewInfo->maFilterName ); + } + + // update import/export flags + if( pFilterEntry->maImportXSLT.getLength() ) + { + pFilterEntry->maFlags |= 1; + } + else + { + pFilterEntry->maFlags &= ~1; + } + + if( pFilterEntry->maExportXSLT.getLength() ) + { + pFilterEntry->maFlags |= 2; + } + else + { + pFilterEntry->maFlags &= ~2; + } + pFilterEntry->maFlags |= 0x80040; + + // 2. create user data for filter entry + Sequence< OUString > aUserData( pFilterEntry->getFilterUserData()); + + // 3. create property values for filter entry + Sequence< PropertyValue > aFilterData( 8 ); + + aFilterData[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ); + aFilterData[0].Value <<= pFilterEntry->maType; + + aFilterData[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ) ); + aFilterData[1].Value <<= pFilterEntry->maInterfaceName; + + aFilterData[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentService" ) ); + aFilterData[2].Value <<= pFilterEntry->maDocumentService; + + aFilterData[3].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterService" ) ); + aFilterData[3].Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Writer.XmlFilterAdaptor" ) ); + + aFilterData[4].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Flags" ) ); + aFilterData[4].Value <<= pFilterEntry->maFlags; + + aFilterData[5].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "UserData" ) ); + aFilterData[5].Value <<= aUserData; + + aFilterData[6].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "FileFormatVersion" ) ); + aFilterData[6].Value <<= pFilterEntry->maFileFormatVersion; + + aFilterData[7].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "TemplateName" ) ); + aFilterData[7].Value <<= pFilterEntry->maImportTemplate; + + // 4. insert new or replace existing filter + try + { + Any aAny( makeAny( aFilterData ) ); + if( mxFilterContainer->hasByName( pFilterEntry->maFilterName ) ) + { + mxFilterContainer->replaceByName( pFilterEntry->maFilterName, aAny ); + } + else + { + mxFilterContainer->insertByName( pFilterEntry->maFilterName, aAny ); + } + } + catch( Exception& ) + { + DBG_ERROR( "XMLFilterSettingsDialog::insertOrEdit exception catched!" ); + bOk = false; + } + } + + // 5. prepare type information + if( bOk ) + { + Sequence< PropertyValue > aValues(4); + + aValues[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ) ); + aValues[0].Value <<= pFilterEntry->maInterfaceName; +/* + aValues[i ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ); + aValues[i++].Value <<= pFilterEntry->maDocType; +*/ + aValues[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "ClipboardFormat" ) ); + OUString aDocType; + if( !pFilterEntry->maDocType.match( sDocTypePrefix ) ) + { + aDocType = sDocTypePrefix; + aDocType += pFilterEntry->maDocType; + } + else + { + aDocType = pFilterEntry->maDocType; + } + if (aDocType == sDocTypePrefix) + aValues[1].Value <<= OUString(); + else + aValues[1].Value <<= aDocType; + + aValues[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentIconID" ) ); + aValues[2].Value <<= pFilterEntry->mnDocumentIconID; + + aValues[3].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Extensions" ) ); + aValues[3].Value <<= createExtensionsSequence( pFilterEntry->maExtension ); + + // the detect service will only be registered, if a doctype/search token was specified + if (aDocType.getLength() > sDocTypePrefix.getLength()) + { + aValues.realloc(5); + aValues[4].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "DetectService" ) ); + aValues[4].Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.filters.XMLFilterDetect" ) ); + } + + // 6. insert new or replace existing type information + if( mxTypeDetection.is() ) + { + try + { + Any aAny( makeAny( aValues ) ); + if( mxTypeDetection->hasByName( pFilterEntry->maType ) ) + { + mxTypeDetection->replaceByName( pFilterEntry->maType, aAny ); + } + else + { + mxTypeDetection->insertByName( pFilterEntry->maType, aAny ); + } + } + catch( Exception& ) + { + DBG_ERROR( "XMLFilterSettingsDialog::insertOrEdit exception catched!" ); + bOk = false; + } + } + + if( bOk ) + { + try + { + Reference< XFlushable > xFlushable = Reference< XFlushable >::query( mxTypeDetection ); + if( xFlushable.is() ) + xFlushable->flush(); + } + catch( Exception& ) + { + DBG_ERROR( "XMLFilterSettingsDialog::insertOrEdit exception catched!" ); + bOk = false; + } + } + + if( !bOk ) + { + // we failed to add the type, so lets remove the filter + try + { + mxFilterContainer->removeByName( pFilterEntry->maFilterName ); + } + catch( Exception& ) + { + DBG_ERROR( "XMLFilterSettingsDialog::insertOrEdit exception catched!" ); + bOk = false; + } + } + else + { + if( bOk ) + { + try + { + Reference< XFlushable > xFlushable( mxFilterContainer, UNO_QUERY ); + if( xFlushable.is() ) + xFlushable->flush(); + } + catch( Exception& ) + { + DBG_ERROR( "XMLFilterSettingsDialog::insertOrEdit exception catched!" ); + bOk = false; + } + + if( !bOk ) + { + // we failed to add the filter, so lets remove the type + try + { + mxTypeDetection->removeByName( pFilterEntry->maType ); + } + catch( Exception& ) + { + DBG_ERROR( "XMLFilterSettingsDialog::insertOrEdit exception catched!" ); + } + } + + } + } + } + + if( bOk ) + { + if( mxExtendedTypeDetection.is() ) + { + OUString sFilterDetectService( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.filters.XMLFilterDetect") ); + if( mxExtendedTypeDetection->hasByName( sFilterDetectService ) ) + { + Sequence< PropertyValue > aSequence; + if( mxExtendedTypeDetection->getByName( sFilterDetectService ) >>= aSequence ) + { + sal_Int32 nCount = aSequence.getLength(); + sal_Int32 nIndex; + for( nIndex = 0; nIndex < nCount; nIndex++ ) + { + OUString aName( aSequence[nIndex].Name ); + if( aSequence[nIndex].Name.equalsAscii( "Types" ) ) + { + Sequence< OUString > aTypes; + if( aSequence[nIndex].Value >>= aTypes ) + { + sal_Int32 nStrCount = aTypes.getLength(); + sal_Int32 nStr; + for( nStr = 0; nStr < nStrCount; nStr++ ) + { + OUString aType( aTypes[nStr] ); + if( aTypes[nStr] == pFilterEntry->maType ) + break; + } + + if( nStr == nStrCount ) + { + aTypes.realloc( nStrCount + 1 ); + aTypes[nStrCount] = pFilterEntry->maType; + + aSequence[nIndex].Value <<= aTypes; + + mxExtendedTypeDetection->replaceByName( sFilterDetectService, makeAny( aSequence ) ); + + Reference< XFlushable > xFlushable( mxExtendedTypeDetection, UNO_QUERY ); + if( xFlushable.is() ) + xFlushable->flush(); + } + } + + break; + } + } + } + } + } + } + + // update ui + if( bOk ) + { + if( pOldInfo ) + { + mpFilterListBox->changeEntry( pFilterEntry ); + } + else + { + mpFilterListBox->addFilterEntry( pFilterEntry ); + maFilterVector.push_back( pFilterEntry ); + } + } + + return bOk; +} + +// ----------------------------------------------------------------------- + +/** is called when the user clicks the "Test" button */ +void XMLFilterSettingsDialog::onTest() +{ + // get the first selected filter + SvLBoxEntry* pEntry = mpFilterListBox->FirstSelected(); + if( pEntry ) + { + filter_info_impl* pInfo = (filter_info_impl*)pEntry->GetUserData(); + + XMLFilterTestDialog aDlg( this, *mpResMgr, mxMSF ); + aDlg.test( *pInfo ); + } +} + +// ----------------------------------------------------------------------- + +void XMLFilterSettingsDialog::onDelete() +{ + SvLBoxEntry* pEntry = mpFilterListBox->FirstSelected(); + if( pEntry ) + { + filter_info_impl* pInfo = (filter_info_impl*)pEntry->GetUserData(); + + String aPlaceHolder( RTL_CONSTASCII_USTRINGPARAM("%s") ); + String aMessage(RESID(STR_WARN_DELETE)); + aMessage.SearchAndReplace( aPlaceHolder, pInfo->maFilterName ); + + WarningBox aWarnBox(this, (WinBits)(WB_YES_NO | WB_DEF_YES), aMessage ); + if( aWarnBox.Execute() == RET_YES ) + { + try + { + if( mxFilterContainer->hasByName( pInfo->maFilterName ) ) + { + mxFilterContainer->removeByName( pInfo->maFilterName ); + + bool bTypeStillUsed = false; + + // now loop over all filter and see if someone else uses the same type + Sequence< OUString > aFilterNames( mxFilterContainer->getElementNames() ); + OUString* pFilterName = aFilterNames.getArray(); + + const sal_Int32 nCount = aFilterNames.getLength(); + sal_Int32 nFilter; + Sequence< PropertyValue > aValues; + + for( nFilter = 0; (nFilter < nCount) && !bTypeStillUsed; nFilter++, pFilterName++ ) + { + Any aAny( mxFilterContainer->getByName( *pFilterName ) ); + if( !(aAny >>= aValues) ) + continue; + + const sal_Int32 nValueCount( aValues.getLength() ); + PropertyValue* pValues = aValues.getArray(); + sal_Int32 nValue; + + for( nValue = 0; (nValue < nValueCount) && !bTypeStillUsed; nValue++, pValues++ ) + { + if( pValues->Name.equalsAscii( "Type" ) ) + { + OUString aType; + pValues->Value >>= aType; + if( aType == pInfo->maType ) + bTypeStillUsed = true; + + break; + } + } + } + + // if the type is not used anymore, remove it also + if( !bTypeStillUsed ) + { + if( mxTypeDetection->hasByName( pInfo->maType ) ) + { + mxTypeDetection->removeByName( pInfo->maType ); + } + } + + Reference< XFlushable > xFlushable( mxFilterContainer, UNO_QUERY ); + if( xFlushable.is() ) + xFlushable->flush(); + + xFlushable = Reference< XFlushable >::query( mxTypeDetection ); + if( xFlushable.is() ) + xFlushable->flush(); + + // now remove entry from ui + mpFilterListBox->RemoveSelection(); + + // and delete the filter entry + maFilterVector.erase(std::find( maFilterVector.begin(), maFilterVector.end(), pInfo )); + + delete pInfo; + } + } + catch( Exception& ) + { + DBG_ERROR( "XMLFilterSettingsDialog::onDelete exception catched!" ); + } + } + } + + updateStates(); +} + +// ----------------------------------------------------------------------- + +void XMLFilterSettingsDialog::onSave() +{ + XMLFilterVector aFilters; + + int nFilters = 0; + + SvLBoxEntry* pEntry = mpFilterListBox->FirstSelected(); + while( pEntry ) + { + filter_info_impl* pInfo = (filter_info_impl*)pEntry->GetUserData(); + aFilters.push_back( pInfo ); + pEntry = mpFilterListBox->NextSelected( pEntry ); + nFilters++; + } + + // Open Fileopen-Dialog + ::sfx2::FileDialogHelper aDlg( + com::sun::star::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION, + 0 ); + + String aExtensions( RTL_CONSTASCII_USTRINGPARAM("*.jar") ); + String aFilterName( RESID( STR_FILTER_PACKAGE ) ); + aFilterName += String( RTL_CONSTASCII_USTRINGPARAM(" (") ); + aFilterName += aExtensions; + aFilterName += sal_Unicode(')'); + + aDlg.AddFilter( aFilterName, aExtensions ); + + if ( aDlg.Execute() == ERRCODE_NONE ) + { + XMLFilterJarHelper aJarHelper( mxMSF ); + aJarHelper.savePackage( aDlg.GetPath(), aFilters ); + + INetURLObject aURL( aDlg.GetPath() ); + + String sPlaceholder( RTL_CONSTASCII_USTRINGPARAM( "%s" ) ); + + String aMsg; + if( nFilters > 0 ) + { + aMsg = String( RESID( STR_FILTERS_HAVE_BEEN_SAVED ) ); + aMsg.SearchAndReplace( sPlaceholder, String::CreateFromInt32(nFilters) ); + aMsg.SearchAndReplace( sPlaceholder, aURL.GetName() ); + } + else + { + aMsg = String( RESID( STR_FILTER_HAS_BEEN_SAVED ) ); + aMsg.SearchAndReplace( sPlaceholder, (*aFilters.begin())->maFilterName ); + aMsg.SearchAndReplace( sPlaceholder, aURL.GetName() ); + } + + InfoBox aBox(this, aMsg ); + aBox.Execute(); + } +} + +// ----------------------------------------------------------------------- + +void XMLFilterSettingsDialog::onOpen() +{ + XMLFilterVector aFilters; + + // Open Fileopen-Dialog + ::sfx2::FileDialogHelper aDlg( + com::sun::star::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, 0 ); + + String aExtensions( RTL_CONSTASCII_USTRINGPARAM("*.jar") ); + String aFilterName( RESID( STR_FILTER_PACKAGE ) ); + aFilterName += String( RTL_CONSTASCII_USTRINGPARAM(" (") ); + aFilterName += aExtensions; + aFilterName += sal_Unicode(')'); + + aDlg.AddFilter( aFilterName, aExtensions ); + + if ( aDlg.Execute() == ERRCODE_NONE ) + { + OUString aURL( aDlg.GetPath() ); + + XMLFilterJarHelper aJarHelper( mxMSF ); + aJarHelper.openPackage( aURL, aFilters ); + + int nFilters = 0; + XMLFilterVector::iterator aIter( aFilters.begin() ); + while( aIter != aFilters.end() ) + { + filter_info_impl* pInfo = (*aIter++); + + if( insertOrEdit( pInfo ) ) + { + aFilterName = pInfo->maFilterName; + nFilters++; + } + + delete pInfo; + } + + disposeFilterList(); + initFilterList(); + + String sPlaceholder( RTL_CONSTASCII_USTRINGPARAM( "%s" ) ); + String aMsg; + if( nFilters == 0 ) + { + INetURLObject aURLObj( aURL ); + aMsg = String( RESID( STR_NO_FILTERS_FOUND ) ); + aMsg.SearchAndReplace( sPlaceholder, aURLObj.GetName() ); + } + else if( nFilters == 1 ) + { + aMsg = String( RESID( STR_FILTER_INSTALLED ) ); + aMsg.SearchAndReplace( sPlaceholder, aFilterName ); + + } + else + { + aMsg = String( RESID( STR_FILTERS_INSTALLED ) ); + aMsg.SearchAndReplace( sPlaceholder, String::CreateFromInt32(nFilters) ); + } + + InfoBox aBox(this, aMsg ); + aBox.Execute(); + } +} + +// ----------------------------------------------------------------------- + +void XMLFilterSettingsDialog::onClose() +{ + Close(); +} + +long XMLFilterSettingsDialog::Notify( NotifyEvent& rNEvt ) +{ + // Zuerst Basisklasse rufen wegen TabSteuerung + long nRet = WorkWindow::Notify( rNEvt ); + if ( !nRet ) + { + if ( rNEvt.GetType() == EVENT_KEYINPUT ) + { + const KeyEvent* pKEvt = rNEvt.GetKeyEvent(); + KeyCode aKeyCode = pKEvt->GetKeyCode(); + USHORT nKeyCode = aKeyCode.GetCode(); + + if( nKeyCode == KEY_ESCAPE ) + { + Close(); + return TRUE; + } + } + } + + return nRet; +} + +// ----------------------------------------------------------------------- + +void XMLFilterSettingsDialog::disposeFilterList() +{ + std::vector< filter_info_impl* >::iterator aIter( maFilterVector.begin() ); + while( aIter != maFilterVector.end() ) + { + delete (*aIter++); + } + maFilterVector.clear(); + + mpFilterListBox->Clear(); +} + +// ----------------------------------------------------------------------- + +void XMLFilterSettingsDialog::initFilterList() +{ + if( mxFilterContainer.is() ) + { + Sequence< OUString > aFilterNames( mxFilterContainer->getElementNames() ); + OUString* pFilterName = aFilterNames.getArray(); + + const sal_Int32 nCount = aFilterNames.getLength(); + sal_Int32 nFilter; + + Sequence< PropertyValue > aValues; + + filter_info_impl* pTempFilter = new filter_info_impl; + Sequence< OUString > aUserData; + + for( nFilter = 0; nFilter < nCount; nFilter++, pFilterName++ ) + { + aUserData.realloc(0); + + try + { + Any aAny( mxFilterContainer->getByName( *pFilterName ) ); + if( !(aAny >>= aValues) ) + continue; + + OUString aFilterService; + pTempFilter->maFilterName = *pFilterName; + + const sal_Int32 nValueCount( aValues.getLength() ); + PropertyValue* pValues = aValues.getArray(); + sal_Int32 nValue; + + for( nValue = 0; nValue < nValueCount; nValue++, pValues++ ) + { + if( pValues->Name.equalsAscii( "Type" ) ) + { + pValues->Value >>= pTempFilter->maType; + } + else if( pValues->Name.equalsAscii( "UIName" ) ) + { + pValues->Value >>= pTempFilter->maInterfaceName; + } + else if( pValues->Name.equalsAscii( "DocumentService" ) ) + { + pValues->Value >>= pTempFilter->maDocumentService; + } + else if( pValues->Name.equalsAscii( "FilterService" ) ) + { + pValues->Value >>= aFilterService; + } + else if( pValues->Name.equalsAscii( "Flags" ) ) + { + pValues->Value >>= pTempFilter->maFlags; + } + else if( pValues->Name.equalsAscii( "UserData" ) ) + { + pValues->Value >>= aUserData; + } + else if( pValues->Name.equalsAscii( "FileFormatVersion" ) ) + { + pValues->Value >>= pTempFilter->maFileFormatVersion; + } + else if( pValues->Name.equalsAscii( "TemplateName" ) ) + { + pValues->Value >>= pTempFilter->maImportTemplate; + } + else if(pValues->Name.equalsAscii( "Finalized" )) + { + pValues->Value >>= pTempFilter->mbReadonly; + } + } + + // if this is not a XmlFilterAdaptor entry, skip it + if( !aFilterService.equalsAscii( "com.sun.star.comp.Writer.XmlFilterAdaptor" ) ) + continue; + + + // if we don't have the needed user data, skip it + if( aUserData.getLength() < 6 ) + continue; + + // if this is not an XSLTFilter entry, skip it + if( !aUserData[0].equalsAscii( "com.sun.star.documentconversion.XSLTFilter" ) ) + continue; + + // get filter information from userdata + pTempFilter->maImportService = aUserData[2]; + pTempFilter->maExportService = aUserData[3]; + pTempFilter->maImportXSLT = aUserData[4]; + pTempFilter->maExportXSLT = aUserData[5]; + if( aUserData.getLength() >= 7 ) + pTempFilter->maDTD = aUserData[6]; + if( aUserData.getLength() >= 8 ) + pTempFilter->maComment = aUserData[7]; + + // get type information + if( mxTypeDetection.is() ) + { + try + { + aAny = mxTypeDetection->getByName( pTempFilter->maType ); + Sequence< PropertyValue > aValues2; + + if( aAny >>= aValues2 ) + { + const sal_Int32 nValueCount2( aValues2.getLength() ); + PropertyValue* pValues2 = aValues2.getArray(); + sal_Int32 nValue2; + + for( nValue2 = 0; nValue2 < nValueCount2; nValue2++, pValues2++ ) + { +/* + if( pValues2->Name.equalsAscii( "MediaType" ) ) + { + pValues2->Value >>= pTempFilter->maDocType; + } else +*/ + if( pValues2->Name.equalsAscii( "ClipboardFormat" ) ) + { + OUString aDocType; + pValues2->Value >>= aDocType; + + if( aDocType.match( sDocTypePrefix ) ) + aDocType = aDocType.copy( sDocTypePrefix.getLength() ); + + pTempFilter->maDocType = aDocType; + } + else if( pValues2->Name.equalsAscii( "Extensions" ) ) + { + Sequence< OUString > aExtensions; + if( pValues2->Value >>= aExtensions ) + { + pTempFilter->maExtension = OUString(); + + sal_Int32 nCount3( aExtensions.getLength() ); + OUString* pExtensions = aExtensions.getArray(); + sal_Int32 n; + for( n = 0; n < nCount3; n++ ) + { + if( n > 0 ) + pTempFilter->maExtension += OUString( sal_Unicode(';') ); + pTempFilter->maExtension += (*pExtensions++); + } + } + } + else if( pValues2->Name.equalsAscii( "DocumentIconID" ) ) + { + pValues2->Value >>= pTempFilter->mnDocumentIconID; + } + else if(pValues2->Name.equalsAscii( "Finalized" )) + { + // both the filter and the type may be finalized + sal_Bool bTemp = sal_False; + pValues2->Value >>= bTemp; + pTempFilter->mbReadonly |= bTemp; + } + } + } + } + catch( ::com::sun::star::container::NoSuchElementException& ) + { + DBG_ERROR( "Type not found, user error?" ); // TODO: error? + } + } + + // add entry to internal container and to ui filter list box + maFilterVector.push_back( pTempFilter ); + mpFilterListBox->addFilterEntry( pTempFilter ); + + + pTempFilter = new filter_info_impl; + } + catch( Exception& ) + { + DBG_ERROR( "XMLFilterSettingsDialog::initFilterList exception catched!" ); + } + + } + + delete pTempFilter; + } + + SvLBoxEntry* pEntry = mpFilterListBox->GetEntry( 0 ); + if( pEntry ) + mpFilterListBox->Select( pEntry ); +} + +// ----------------------------------------------------------------------- + +// ----------------------------------------------------------------------- + +application_info_impl::application_info_impl( const sal_Char * pDocumentService, ResId& rUINameRes, const sal_Char * mpXMLImporter, const sal_Char * mpXMLExporter ) +: maDocumentService( pDocumentService, strlen( pDocumentService ), RTL_TEXTENCODING_ASCII_US ), + maDocumentUIName( String( rUINameRes ) ), + maXMLImporter( mpXMLImporter, strlen( mpXMLImporter ), RTL_TEXTENCODING_ASCII_US ), + maXMLExporter( mpXMLExporter, strlen( mpXMLExporter ), RTL_TEXTENCODING_ASCII_US ) +{ +} + +// ----------------------------------------------------------------------- + +std::vector< application_info_impl* >& getApplicationInfos() +{ + static std::vector< application_info_impl* > aInfos; + + if( aInfos.empty() ) + { + ResId aResId1( STR_APPL_NAME_WRITER, *getXSLTDialogResMgr() ); + aInfos.push_back( new application_info_impl( + "com.sun.star.text.TextDocument", + aResId1, + "com.sun.star.comp.Writer.XMLImporter", + "com.sun.star.comp.Writer.XMLExporter" ) ); + + ResId aResId2( STR_APPL_NAME_CALC, *getXSLTDialogResMgr() ); + aInfos.push_back( new application_info_impl( + "com.sun.star.sheet.SpreadsheetDocument", + aResId2, + "com.sun.star.comp.Calc.XMLImporter", + "com.sun.star.comp.Calc.XMLExporter" ) ); + + ResId aResId3( STR_APPL_NAME_IMPRESS, *getXSLTDialogResMgr() ); + aInfos.push_back( new application_info_impl( + "com.sun.star.presentation.PresentationDocument", + aResId3, + "com.sun.star.comp.Impress.XMLImporter", + "com.sun.star.comp.Impress.XMLExporter" ) ); + + ResId aResId4( STR_APPL_NAME_DRAW, *getXSLTDialogResMgr() ); + aInfos.push_back( new application_info_impl( + "com.sun.star.drawing.DrawingDocument", + aResId4, + "com.sun.star.comp.Draw.XMLImporter", + "com.sun.star.comp.Draw.XMLExporter" ) ); + + // --- oasis file formats... + ResId aResId5( STR_APPL_NAME_OASIS_WRITER, *getXSLTDialogResMgr() ); + aInfos.push_back( new application_info_impl( + "com.sun.star.text.TextDocument", + aResId5, + "com.sun.star.comp.Writer.XMLOasisImporter", + "com.sun.star.comp.Writer.XMLOasisExporter" ) ); + + ResId aResId6( STR_APPL_NAME_OASIS_CALC, *getXSLTDialogResMgr() ); + aInfos.push_back( new application_info_impl( + "com.sun.star.sheet.SpreadsheetDocument", + aResId6, + "com.sun.star.comp.Calc.XMLOasisImporter", + "com.sun.star.comp.Calc.XMLOasisExporter" ) ); + + ResId aResId7( STR_APPL_NAME_OASIS_IMPRESS, *getXSLTDialogResMgr() ); + aInfos.push_back( new application_info_impl( + "com.sun.star.presentation.PresentationDocument", + aResId7, + "com.sun.star.comp.Impress.XMLOasisImporter", + "com.sun.star.comp.Impress.XMLOasisExporter" ) ); + + ResId aResId8( STR_APPL_NAME_OASIS_DRAW, *getXSLTDialogResMgr() ); + aInfos.push_back( new application_info_impl( + "com.sun.star.drawing.DrawingDocument", + aResId8, + "com.sun.star.comp.Draw.XMLOasisImporter", + "com.sun.star.comp.Draw.XMLOasisExporter" ) ); +} + + return aInfos; +} + +// ----------------------------------------------------------------------- + +const application_info_impl* getApplicationInfo( const OUString& rServiceName ) +{ + std::vector< application_info_impl* >& rInfos = getApplicationInfos(); + std::vector< application_info_impl* >::iterator aIter( rInfos.begin() ); + while( aIter != rInfos.end() ) + { + // if( rServiceName == (*aIter)->maDocumentService ) + if( rServiceName == (*aIter)->maXMLExporter || + rServiceName == (*aIter)->maXMLImporter) + { + return (*aIter); + } + aIter++; + } + return NULL; +} + +// ----------------------------------------------------------------------- + +OUString getApplicationUIName( const OUString& rServiceName ) +{ + const application_info_impl* pInfo = getApplicationInfo( rServiceName ); + if( pInfo ) + { + return pInfo->maDocumentUIName; + } + else + { + OUString aRet = String( RESID( STR_UNKNOWN_APPLICATION ) ); + if( rServiceName.getLength() ) + { + aRet += OUString( RTL_CONSTASCII_USTRINGPARAM( " (" )); + aRet += rServiceName; + aRet += OUString( RTL_CONSTASCII_USTRINGPARAM( ")" )); + } + return aRet; + } +} + +// ----------------------------------------------------------------------- + +ResMgr* getXSLTDialogResMgr() +{ + return XMLFilterSettingsDialog::mpResMgr; +} + +// ----------------------------------------------------------------------- + +// ----------------------------------------------------------------------- + +long SvxPathControl_Impl::Notify( NotifyEvent& rNEvt ) +{ + long nRet = Control::Notify( rNEvt ); + + if ( m_pFocusCtrl && rNEvt.GetWindow() != m_pFocusCtrl && rNEvt.GetType() == EVENT_GETFOCUS ) + m_pFocusCtrl->GrabFocus(); + return nRet; +} + +#define ITEMID_NAME 1 +#define ITEMID_TYPE 2 + +XMLFilterListBox::XMLFilterListBox( SvxPathControl_Impl * pParent ) +: SvTabListBox( pParent, WB_SORT | WB_HSCROLL | WB_CLIPCHILDREN | WB_TABSTOP ), + mbFirstPaint( true ) +{ + Size aBoxSize( pParent->GetOutputSizePixel() ); + + mpHeaderBar = new HeaderBar( pParent, /*WB_BUTTONSTYLE | */ WB_BOTTOMBORDER ); + mpHeaderBar->SetPosSizePixel( Point( 0, 0 ), Size( aBoxSize.Width(), 16 ) ); + mpHeaderBar->SetEndDragHdl( LINK( this, XMLFilterListBox, HeaderEndDrag_Impl ) ); + + String aStr1( RESID( STR_COLUMN_HEADER_NAME ) ); + String aStr2( RESID( STR_COLUMN_HEADER_TYPE ) ); + + long nTabSize = aBoxSize.Width() / 2; + + mpHeaderBar->InsertItem( ITEMID_NAME, aStr1, nTabSize, + HIB_LEFT | HIB_VCENTER ); + mpHeaderBar->InsertItem( ITEMID_TYPE, aStr2, nTabSize, + HIB_LEFT | HIB_VCENTER ); + + static long nTabs[] = {3, 0, nTabSize, 2*nTabSize }; + Size aHeadSize( mpHeaderBar->GetSizePixel() ); + + WinBits nBits = WB_SORT | WB_HSCROLL | WB_CLIPCHILDREN | WB_TABSTOP; + pParent->SetFocusControl( this ); + SetWindowBits( nBits ); +// SetDoubleClickHdl( aLink ); +// SetSelectHdl( LINK( this, SvxPathTabPage, PathSelect_Impl ) ); + SetSelectionMode( MULTIPLE_SELECTION ); + SetPosSizePixel( Point( 0, aHeadSize.Height() ), Size( aBoxSize.Width(), aBoxSize.Height() - aHeadSize.Height() ) ); + SetTabs( &nTabs[0], MAP_PIXEL ); + SetScrolledHdl( LINK( this, XMLFilterListBox, TabBoxScrollHdl_Impl ) ); + SetHighlightRange(); +// SetHelpId( HID_OPTPATH_CTL_PATH ); +// mpHeaderBar->SetHelpId( HID_OPTPATH_HEADERBAR ); + Show(); + mpHeaderBar->Show(); +} + +// ----------------------------------------------------------------------- + +XMLFilterListBox::~XMLFilterListBox() +{ + delete mpHeaderBar; +} + +// ----------------------------------------------------------------------- + +void XMLFilterListBox::Reset() +{ + Size aBoxSize( Window::GetParent()->GetOutputSizePixel() ); + long nTabSize = aBoxSize.Width() / 2; + static long nTabs[] = {3, 0, nTabSize, 2*nTabSize }; + SetTabs( &nTabs[0], MAP_PIXEL ); + mpHeaderBar->SetItemSize( ITEMID_NAME, nTabSize ); + mpHeaderBar->SetItemSize( ITEMID_TYPE, nTabSize ); +} + +// ----------------------------------------------------------------------- + +void XMLFilterListBox::Paint( const Rectangle& rRect ) +{ + if( mbFirstPaint ) + { + mbFirstPaint = false; + RepaintScrollBars(); + } + + SvTabListBox::Paint( rRect ); +} + +IMPL_LINK( XMLFilterListBox, TabBoxScrollHdl_Impl, SvTabListBox*, /* pList */ ) +{ + mpHeaderBar->SetOffset( -GetXOffset() ); + return 0; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( XMLFilterListBox, HeaderSelect_Impl, HeaderBar*, pBar ) +{ + if ( pBar && pBar->GetCurItemId() != ITEMID_NAME ) + return 0; + + HeaderBarItemBits nBits = mpHeaderBar->GetItemBits(ITEMID_TYPE); + BOOL bUp = ( ( nBits & HIB_UPARROW ) == HIB_UPARROW ); + SvSortMode eMode = SortAscending; + + if ( bUp ) + { + nBits &= ~HIB_UPARROW; + nBits |= HIB_DOWNARROW; + eMode = SortDescending; + } + else + { + nBits &= ~HIB_DOWNARROW; + nBits |= HIB_UPARROW; + } + mpHeaderBar->SetItemBits( ITEMID_NAME, nBits ); + SvTreeList* pMod = GetModel(); + pMod->SetSortMode( eMode ); + pMod->Resort(); + return 1; +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( XMLFilterListBox, HeaderEndDrag_Impl, HeaderBar*, pBar ) +{ + if ( pBar && !pBar->GetCurItemId() ) + return 0; + + if ( !mpHeaderBar->IsItemMode() ) + { + Size aSz; + USHORT nTabs = mpHeaderBar->GetItemCount(); + long nTmpSz = 0; + long nWidth = mpHeaderBar->GetItemSize(ITEMID_NAME); + long nBarWidth = mpHeaderBar->GetSizePixel().Width(); + + if(nWidth < 30) + mpHeaderBar->SetItemSize( ITEMID_TYPE, 30); + else if ( ( nBarWidth - nWidth ) < 30 ) + mpHeaderBar->SetItemSize( ITEMID_TYPE, nBarWidth - 30 ); + + for ( USHORT i = 1; i <= nTabs; ++i ) + { + long nW = mpHeaderBar->GetItemSize(i); + aSz.Width() = nW + nTmpSz; + nTmpSz += nW; + SetTab( i, PixelToLogic( aSz, MapMode(MAP_APPFONT) ).Width(), MAP_APPFONT ); + } + } + return 1; +} + +// ----------------------------------------------------------------------- + +/** adds a new filter info entry to the ui filter list */ +void XMLFilterListBox::addFilterEntry( const filter_info_impl* pInfo ) +{ + const XubString aEntryStr( getEntryString( pInfo ) ); + InsertEntryToColumn( aEntryStr, LIST_APPEND, 0xffff, (void*)pInfo ); +} + +// ----------------------------------------------------------------------- + +void XMLFilterListBox::changeEntry( const filter_info_impl* pInfo ) +{ + const ULONG nCount = GetEntryCount(); + ULONG nPos; + for( nPos = 0; nPos < nCount; nPos++ ) + { + SvLBoxEntry* pEntry = GetEntry( nPos ); + if( (filter_info_impl*)pEntry->GetUserData() == pInfo ) + { + XubString aEntryText( getEntryString( pInfo ) ); + SetEntryText( aEntryText, pEntry ); + break; + } + } +} + +// ----------------------------------------------------------------------- + +String XMLFilterListBox::getEntryString( const filter_info_impl* pInfo ) const +{ + String aEntryStr( pInfo->maFilterName ); + aEntryStr += '\t'; + // aEntryStr += String( getApplicationUIName( pInfo->maDocumentService ) ); + if ( pInfo->maExportService.getLength() > 0 ) + aEntryStr += String( getApplicationUIName( pInfo->maExportService ) ); + else + aEntryStr += String( getApplicationUIName( pInfo->maImportService ) ); + aEntryStr += ' '; + aEntryStr += '-'; + aEntryStr += ' '; + + if( pInfo->maFlags & 1 ) + { + if( pInfo->maFlags & 2 ) + { + aEntryStr += String( RESID( STR_IMPORT_EXPORT ) ); + } + else + { + aEntryStr += String( RESID( STR_IMPORT_ONLY ) ); + } + } + else if( pInfo->maFlags & 2 ) + { + aEntryStr += String( RESID( STR_EXPORT_ONLY ) ); + } + else + { + aEntryStr += String( RESID( STR_UNDEFINED_FILTER ) ); + } + + return aEntryStr; +} + +// ----------------------------------------------------------------------- + +// ----------------------------------------------------------------------- + +filter_info_impl::filter_info_impl() +: maFlags(0x00080040), + maFileFormatVersion(0), + mnDocumentIconID(0), + mbReadonly(sal_False) +{ +} + +// ----------------------------------------------------------------------- + +filter_info_impl::filter_info_impl( const filter_info_impl& rInfo ) : + maFilterName( rInfo.maFilterName ), + maType( rInfo.maType ), + maDocumentService( rInfo.maDocumentService ), + maFilterService( rInfo.maFilterService ), + maInterfaceName( rInfo.maInterfaceName ), + maComment( rInfo.maComment ), + maExtension( rInfo.maExtension ), + maDTD( rInfo.maDTD ), + maExportXSLT( rInfo.maExportXSLT ), + maImportXSLT( rInfo.maImportXSLT ), + maImportTemplate( rInfo.maImportTemplate ), + maDocType( rInfo.maDocType ), + maImportService( rInfo.maImportService ), + maExportService( rInfo.maExportService ), + maFlags( rInfo.maFlags ), + maFileFormatVersion( rInfo.maFileFormatVersion ), + mnDocumentIconID( rInfo.mnDocumentIconID ), + mbReadonly( rInfo.mbReadonly ) +{ +} + +// ----------------------------------------------------------------------- + +int filter_info_impl::operator==( const filter_info_impl& r ) const +{ + if( maFilterName != r.maFilterName || + maType != r.maType || + maDocumentService != r.maDocumentService || + maFilterService != r.maFilterService || + maInterfaceName != r.maInterfaceName || + maComment != r.maComment || + maExtension != r.maExtension || + maDocType != r.maDocType || + maDTD != r.maDTD || + maExportXSLT != r.maExportXSLT || + maImportXSLT != r.maImportXSLT || + maExportService != r.maExportService || + maImportService != r.maImportService || + maImportTemplate != r.maImportTemplate || + maFlags != r.maFlags || + maFileFormatVersion != r.maFileFormatVersion ) + return false; + + return true; +} + +// ----------------------------------------------------------------------- + +Sequence< OUString > filter_info_impl::getFilterUserData() const +{ + Sequence< OUString > aUserData(8); + + aUserData[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.documentconversion.XSLTFilter" ) ); + /* + const application_info_impl* pInfo = getApplicationInfo( maDocumentService ); + if( pInfo ) + { + aUserData[2] = pInfo->maXMLImporter; + aUserData[3] = pInfo->maXMLExporter; + } + */ + aUserData[2] = maImportService; + aUserData[3] = maExportService; + aUserData[4] = maImportXSLT; + aUserData[5] = maExportXSLT; + aUserData[6] = maDTD; + aUserData[7] = maComment; + + return aUserData; +} + + +// ----------------------------------------------------------------------- + +OUString string_encode( const OUString & rText ) +{ + + static sal_Bool const aCharClass[] + = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* UricNoSlash */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, /* !"#$%&'()*+,-./*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, /*0123456789:;<=>?*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*@ABCDEFGHIJKLMNO*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /*PQRSTUVWXYZ[\]^_*/ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*`abcdefghijklmno*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0 /*pqrstuvwxyz{|}~ */ + }; + + + return Uri::encode( rText, aCharClass, rtl_UriEncodeCheckEscapes, RTL_TEXTENCODING_UTF8 ); +} + +// ----------------------------------------------------------------------- + +OUString string_decode( const OUString & rText ) +{ + return Uri::decode( rText, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 ); +} + +// ----------------------------------------------------------------------- + +bool isFileURL( const ::rtl::OUString & rURL ) +{ + return rURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM("file:") ) == 0; +} + +// ----------------------------------------------------------------------- + +bool copyStreams( Reference< XInputStream > xIS, Reference< XOutputStream > xOS ) +{ + try + { + sal_Int32 nBufferSize = 512; + Sequence< sal_Int8 > aDataBuffer(nBufferSize); + + sal_Int32 nRead; + do + { + nRead = xIS->readBytes( aDataBuffer, nBufferSize ); + + if( nRead ) + { + if( nRead < nBufferSize ) + { + nBufferSize = nRead; + aDataBuffer.realloc(nRead); + } + + xOS->writeBytes( aDataBuffer ); + } + } + while( nRead ); + + xOS->flush(); + + return true; + } + catch(Exception&) + { + DBG_ERROR( "copyStreams() exception catched!" ); + } + + return false; +} + +// ----------------------------------------------------------------------- + +bool createDirectory( OUString& rURL ) +{ + sal_Int32 nLastIndex = sizeof( "file:///" ) - 2; + while( nLastIndex != -1 ) + { + nLastIndex = rURL.indexOf( sal_Unicode('/'), nLastIndex + 1); + if( nLastIndex != -1 ) + { + OUString aDirURL( rURL.copy( 0, nLastIndex ) ); + Directory aDir( aDirURL ); + Directory::RC rc = aDir.open(); + if( rc == Directory::E_NOENT ) + rc = osl::Directory::create( aDirURL ); + + if( rc != Directory::E_None ) + { + return false; + } + } + } + + return true; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |