build fix
[LibreOffice.git] / filter / source / xsltdialog / xmlfiltersettingsdialog.cxx
blob1c0bc8f37866a91139bb1a625f6299f774fbeadb
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/frame/XConfigManager.hpp>
21 #include <com/sun/star/container/XNameAccess.hpp>
22 #include <com/sun/star/util/XFlushable.hpp>
24 #include <com/sun/star/beans/PropertyValue.hpp>
26 #include "com/sun/star/ui/dialogs/TemplateDescription.hpp"
27 #include <tools/resmgr.hxx>
28 #include <tools/urlobj.hxx>
29 #include <svtools/headbar.hxx>
30 #include <unotools/streamwrap.hxx>
31 #include <unotools/pathoptions.hxx>
32 #include <osl/file.hxx>
33 #include <o3tl/enumrange.hxx>
34 #include <vcl/msgbox.hxx>
35 #include <vcl/svapp.hxx>
36 #include <vcl/builderfactory.hxx>
37 #include <sfx2/filedlghelper.hxx>
38 #include "svtools/treelistentry.hxx"
40 #include <rtl/uri.hxx>
42 #include <algorithm>
43 #include <memory>
45 #include "xmlfilterdialogstrings.hrc"
46 #include "xmlfiltersettingsdialog.hxx"
47 #include "xmlfiltertabdialog.hxx"
48 #include "xmlfiltertestdialog.hxx"
49 #include "xmlfilterjar.hxx"
51 using namespace osl;
52 using namespace com::sun::star::lang;
53 using namespace com::sun::star::uno;
54 using namespace com::sun::star::io;
55 using namespace com::sun::star::frame;
56 using namespace com::sun::star::container;
57 using namespace com::sun::star::beans;
58 using namespace com::sun::star::util;
60 using ::rtl::Uri;
62 namespace {
64 std::unique_ptr<ResMgr> getXSLTDialogResMgr() {
65 return std::unique_ptr<ResMgr>(
66 ResMgr::CreateResMgr(
67 "xsltdlg", Application::GetSettings().GetUILanguageTag()));
72 #define RESID(x) ResId(x, *getXSLTDialogResMgr().get())
73 #define RESIDSTR(x) RESID(x).toString()
75 XMLFilterSettingsDialog::XMLFilterSettingsDialog(vcl::Window* pParent,
76 const css::uno::Reference<css::uno::XComponentContext>& rxContext,
77 Dialog::InitFlag eFlag)
78 : ModelessDialog(pParent, "XMLFilterSettingsDialog", "filter/ui/xmlfiltersettings.ui", eFlag)
79 , mxContext( rxContext )
80 , m_bIsClosable(true)
81 , m_sTemplatePath("$(user)/template/")
82 , m_sDocTypePrefix("doctype:")
84 get(m_pCtrlFilterList, "filterlist");
85 get(m_pPBNew, "new");
86 get(m_pPBEdit, "edit");
87 get(m_pPBTest, "test");
88 get(m_pPBDelete, "delete");
89 get(m_pPBSave, "save");
90 get(m_pPBOpen, "open");
91 get(m_pPBClose, "close");
93 m_pFilterListBox = m_pCtrlFilterList->getListBox();
94 m_pFilterListBox->SetSelectHdl( LINK( this, XMLFilterSettingsDialog, SelectionChangedHdl_Impl ) );
95 m_pFilterListBox->SetDeselectHdl( LINK( this, XMLFilterSettingsDialog, SelectionChangedHdl_Impl ) );
96 m_pFilterListBox->SetDoubleClickHdl( LINK( this, XMLFilterSettingsDialog, DoubleClickHdl_Impl ) );
97 m_pFilterListBox->SetAccessibleName(RESIDSTR(STR_XML_FILTER_LISTBOX));
98 m_pFilterListBox->SetHelpId(m_pCtrlFilterList->GetHelpId());
100 m_pPBNew->SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) );
101 m_pPBEdit->SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) );
102 m_pPBTest->SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) );
103 m_pPBDelete->SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) );
104 m_pPBSave->SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) );
105 m_pPBOpen->SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) );
106 m_pPBClose->SetClickHdl(LINK( this, XMLFilterSettingsDialog, ClickHdl_Impl ) );
110 mxFilterContainer.set( rxContext->getServiceManager()->createInstanceWithContext( "com.sun.star.document.FilterFactory", rxContext ), UNO_QUERY );
111 mxTypeDetection.set( rxContext->getServiceManager()->createInstanceWithContext( "com.sun.star.document.TypeDetection", rxContext ), UNO_QUERY );
112 mxExtendedTypeDetection.set( rxContext->getServiceManager()->createInstanceWithContext( "com.sun.star.document.ExtendedTypeDetectionFactory", rxContext ), UNO_QUERY );
114 SvtPathOptions aOptions;
115 m_sTemplatePath = aOptions.SubstituteVariable( m_sTemplatePath );
117 catch(const Exception&)
119 OSL_FAIL( "XMLFilterSettingsDialog::XMLFilterSettingsDialog exception catched!" );
123 XMLFilterSettingsDialog::~XMLFilterSettingsDialog()
125 disposeOnce();
128 void XMLFilterSettingsDialog::dispose()
130 m_pFilterListBox.clear();
131 m_pCtrlFilterList.clear();
132 m_pPBNew.clear();
133 m_pPBEdit.clear();
134 m_pPBTest.clear();
135 m_pPBDelete.clear();
136 m_pPBSave.clear();
137 m_pPBOpen.clear();
138 m_pPBClose.clear();
139 ModelessDialog::dispose();
142 IMPL_LINK(XMLFilterSettingsDialog, ClickHdl_Impl, Button *, pButton, void )
144 m_bIsClosable = false;
146 if (m_pPBNew == pButton)
148 onNew();
150 else if (m_pPBEdit == pButton)
152 onEdit();
154 else if (m_pPBTest == pButton)
156 onTest();
158 else if (m_pPBDelete == pButton)
160 onDelete();
162 else if (m_pPBSave == pButton)
164 onSave();
166 else if (m_pPBOpen == pButton)
168 onOpen();
170 else if (m_pPBClose == pButton)
172 Close();
175 m_bIsClosable = true;
178 IMPL_LINK_NOARG(XMLFilterSettingsDialog, SelectionChangedHdl_Impl, SvTreeListBox*, void)
180 updateStates();
183 IMPL_LINK_NOARG(XMLFilterSettingsDialog, DoubleClickHdl_Impl, SvTreeListBox*, bool)
185 onEdit();
186 return false;
189 short XMLFilterSettingsDialog::Execute()
191 m_pCtrlFilterList->GrabFocus();
192 disposeFilterList();
193 m_pFilterListBox->Clear();
194 initFilterList();
195 updateStates();
197 return ModelessDialog::Execute();
200 void XMLFilterSettingsDialog::updateStates()
202 SvTreeListEntry* pSelectedEntry = m_pFilterListBox->FirstSelected();
204 bool bHasSelection = pSelectedEntry != nullptr;
206 bool bMultiSelection = bHasSelection && (m_pFilterListBox->NextSelected( pSelectedEntry ) != nullptr );
207 bool bIsReadonly = false;
208 bool bIsDefault = false;
209 if(pSelectedEntry)
211 filter_info_impl* pInfo = static_cast<filter_info_impl*>(pSelectedEntry->GetUserData());
212 bIsReadonly = pInfo->mbReadonly;
214 for( auto nFact : o3tl::enumrange<SvtModuleOptions::EFactory>())
216 OUString sDefault = maModuleOpt.GetFactoryDefaultFilter(nFact);
217 if( sDefault == pInfo->maFilterName )
219 bIsDefault = true;
220 break;
224 m_pPBEdit->Enable( bHasSelection && !bMultiSelection && !bIsReadonly);
225 m_pPBTest->Enable( bHasSelection && !bMultiSelection );
226 m_pPBDelete->Enable( bHasSelection && !bMultiSelection && !bIsReadonly && !bIsDefault);
227 m_pPBSave->Enable( bHasSelection );
230 /** is called when the user clicks on the "New" button */
231 void XMLFilterSettingsDialog::onNew()
233 filter_info_impl aTempInfo;
235 // create a unique filter name
236 aTempInfo.maFilterName = createUniqueFilterName(RESIDSTR(STR_DEFAULT_FILTER_NAME));
238 // init default extension
239 OUString aDefaultExtension(RESIDSTR(STR_DEFAULT_EXTENSION));
240 aTempInfo.maExtension = aDefaultExtension;
242 // set default ui name
243 aTempInfo.maInterfaceName = createUniqueInterfaceName(RESIDSTR(STR_DEFAULT_UI_NAME));
245 // set default application
246 aTempInfo.maDocumentService = "com.sun.star.text.TextDocument";
248 // execute XML Filter Dialog
249 ScopedVclPtrInstance< XMLFilterTabDialog > aDlg( this, *getXSLTDialogResMgr().get(), mxContext, &aTempInfo );
250 if ( aDlg->Execute() == RET_OK )
252 // insert the new filter
253 insertOrEdit( aDlg->getNewFilterInfo() );
257 /** is called when the user clicks on the "Edit" Button */
258 void XMLFilterSettingsDialog::onEdit()
260 // get selected filter entry
261 SvTreeListEntry* pEntry = m_pFilterListBox->FirstSelected();
262 if( pEntry )
264 // get its filter info
265 filter_info_impl* pOldInfo = static_cast<filter_info_impl*>(pEntry->GetUserData());
267 // execute XML Filter Dialog
268 ScopedVclPtrInstance< XMLFilterTabDialog > aDlg( this, *getXSLTDialogResMgr().get(), mxContext, pOldInfo );
269 if ( aDlg->Execute() == RET_OK )
271 filter_info_impl* pNewInfo = aDlg->getNewFilterInfo();
273 if( !(*pOldInfo == *pNewInfo) )
275 // change filter
276 insertOrEdit( pNewInfo, pOldInfo );
282 /** helper to create a sequence of strings from an extensions strings
283 "ext1;ext2;ext3" will become { "ext1", "ext2", "ext3" } */
284 static Sequence< OUString > createExtensionsSequence( const OUString& rExtensions )
286 // first count how many extensions we have inside the string
287 int nExtensions = 0;
289 int nLength = rExtensions.getLength();
290 if( nLength )
292 // a non empty string has at least one extension
293 nExtensions++;
295 // now count the delimiters ';'
296 const sal_Unicode * pString = rExtensions.getStr();
297 int i;
298 for( i = 0; i < nLength; i++, pString++ )
300 if( *pString == ';' )
301 nExtensions++;
305 Sequence< OUString > aExtensions( nExtensions );
307 // extract the extensions from the source string and fill the sequence
309 int nLastIndex = 0;
310 int nCurrentIndex = 0;
311 int i;
313 for( i = 0; i < nExtensions; i++ )
315 nLastIndex = rExtensions.indexOf( ';', nLastIndex );
317 if( nLastIndex == -1 )
319 aExtensions[i] = rExtensions.copy( nCurrentIndex );
320 break;
322 else
324 aExtensions[i] = rExtensions.copy( nCurrentIndex, nLastIndex - nCurrentIndex );
325 nCurrentIndex = nLastIndex + 1;
326 nLastIndex = nCurrentIndex;
330 return aExtensions;
333 /** checks if the given name is unique inside the filter factory. If not,
334 numbers are added until the returned name is unique */
335 OUString XMLFilterSettingsDialog::createUniqueFilterName( const OUString& rFilterName )
337 OUString aFilterName( rFilterName );
338 OUString aSpace(" ");
340 sal_Int32 nId = 2;
342 while( mxFilterContainer->hasByName( aFilterName ) )
344 aFilterName = rFilterName;
345 aFilterName += aSpace;
346 aFilterName += OUString::number( nId++ );
349 return aFilterName;
352 /** checks if the given name is unique inside the type detection. If not,
353 numbers are added until the returned name is unique */
354 OUString XMLFilterSettingsDialog::createUniqueTypeName( const OUString& rTypeName )
356 OUString aTypeName( rTypeName );
357 OUString aSpace(" ");
359 sal_Int32 nId = 2;
361 while( mxFilterContainer->hasByName( aTypeName ) )
363 aTypeName = rTypeName;
364 aTypeName += aSpace;
365 aTypeName += OUString::number( nId++ );
368 return aTypeName;
371 /** checks if the given name is a unique ui name inside the filter factory. If not,
372 numbers are added until the returned name is unique */
373 OUString XMLFilterSettingsDialog::createUniqueInterfaceName( const OUString& rInterfaceName )
375 sal_Int32 nDefaultNumber = 0;
379 Sequence< OUString > aFilterNames( mxFilterContainer->getElementNames() );
380 OUString* pFilterName = aFilterNames.getArray();
382 const sal_Int32 nCount = aFilterNames.getLength();
383 sal_Int32 nFilter;
385 Sequence< PropertyValue > aValues;
386 for( nFilter = 0; (nFilter < nCount); nFilter++, pFilterName++ )
388 Any aAny( mxFilterContainer->getByName( *pFilterName ) );
389 if( !(aAny >>= aValues) )
390 continue;
392 const sal_Int32 nValueCount( aValues.getLength() );
393 PropertyValue* pValues = aValues.getArray();
394 sal_Int32 nValue;
396 for( nValue = 0; nValue < nValueCount; nValue++, pValues++ )
398 if ( pValues->Name == "UIName" )
400 OUString aInterfaceName;
401 pValues->Value >>= aInterfaceName;
404 // see if this filter matches our default filter name
405 if( aInterfaceName.match( rInterfaceName ) )
407 // if yes, make sure we generate a unique name with a higher number
408 // this is dump but fast
409 sal_Int32 nNumber = aInterfaceName.copy( rInterfaceName.getLength() ).toInt32();
410 if( nNumber >= nDefaultNumber )
411 nDefaultNumber = nNumber + 1;
417 catch( const Exception& )
419 OSL_FAIL( "XMLFilterSettingsDialog::createUniqueInterfaceName exception catched!" );
422 OUString aInterfaceName( rInterfaceName );
423 if( nDefaultNumber )
425 aInterfaceName += " " + OUString::number( nDefaultNumber );
428 return aInterfaceName;
431 /** inserts a new filter into the ui and configuration if pOldInfo is NULL.
432 If pOldInfo is not null, the old filter will be replaced with the new settings */
433 bool XMLFilterSettingsDialog::insertOrEdit( filter_info_impl* pNewInfo, const filter_info_impl* pOldInfo )
435 bool bOk = true;
437 if( pOldInfo )
439 // see if we need to update the type name
440 if( pOldInfo->maFilterName != pNewInfo->maFilterName )
442 if( pOldInfo->maType == pOldInfo->maFilterName )
444 (pNewInfo->maType).clear();
448 // see if we need to clean up old stuff first
451 // if filter name changed, we need to remove the old filter first
452 if( pOldInfo->maFilterName != pNewInfo->maFilterName )
453 mxFilterContainer->removeByName( pOldInfo->maFilterName );
455 // if type name changed, we need to remove the old type first
456 if( pOldInfo->maType != pNewInfo->maType )
457 mxTypeDetection->removeByName( pOldInfo->maType );
459 catch( const Exception& )
461 OSL_FAIL( "XMLFilterSettingsDialog::insertOrEdit exception catched!" );
462 bOk = false;
466 filter_info_impl* pFilterEntry( nullptr );
468 if( bOk )
470 // create or copy filter info
471 if( pOldInfo )
473 // change existing filter entry in filter list box
474 pFilterEntry = const_cast<filter_info_impl*>(pOldInfo);
475 *pFilterEntry = *pNewInfo;
477 else
479 // add new entry to filter list box
480 pFilterEntry = new filter_info_impl( *pNewInfo );
484 // check if we need to copy the template
485 if( bOk && !pFilterEntry->maImportTemplate.isEmpty() )
487 if( !pFilterEntry->maImportTemplate.matchIgnoreAsciiCase( m_sTemplatePath ) )
489 INetURLObject aSourceURL( pFilterEntry->maImportTemplate );
490 if( !aSourceURL.GetName().isEmpty() )
492 OUString aDestURL( m_sTemplatePath );
493 aDestURL += pFilterEntry->maFilterName + "/";
494 if( createDirectory( aDestURL ) )
496 aDestURL += aSourceURL.GetName();
498 SvFileStream aInputStream(pFilterEntry->maImportTemplate, StreamMode::READ );
499 Reference< XInputStream > xIS( new utl::OInputStreamWrapper( aInputStream ) );
500 SvFileStream aOutputStream(aDestURL, StreamMode::WRITE );
501 Reference< XOutputStream > xOS( new utl::OOutputStreamWrapper( aOutputStream ) );
503 if( copyStreams( xIS, xOS ) )
504 pFilterEntry->maImportTemplate = aDestURL;
510 if( bOk )
512 if( pFilterEntry->maType.isEmpty() )
514 pFilterEntry->maType = createUniqueTypeName( pNewInfo->maFilterName );
517 // update import/export flags
518 if( !pFilterEntry->maImportXSLT.isEmpty() )
520 pFilterEntry->maFlags |= 1;
522 else
524 pFilterEntry->maFlags &= ~1;
527 if( !pFilterEntry->maExportXSLT.isEmpty() )
529 pFilterEntry->maFlags |= 2;
531 else
533 pFilterEntry->maFlags &= ~2;
535 pFilterEntry->maFlags |= 0x80040;
537 // 2. create user data for filter entry
538 Sequence< OUString > aUserData( pFilterEntry->getFilterUserData());
540 // 3. create property values for filter entry
541 Sequence< PropertyValue > aFilterData( 8 );
543 aFilterData[0].Name = "Type";
544 aFilterData[0].Value <<= pFilterEntry->maType;
546 aFilterData[1].Name = "UIName";
547 aFilterData[1].Value <<= pFilterEntry->maInterfaceName;
549 aFilterData[2].Name = "DocumentService";
550 aFilterData[2].Value <<= pFilterEntry->maDocumentService;
552 aFilterData[3].Name = "FilterService";
553 aFilterData[3].Value <<= OUString( "com.sun.star.comp.Writer.XmlFilterAdaptor" );
555 aFilterData[4].Name = "Flags";
556 aFilterData[4].Value <<= pFilterEntry->maFlags;
558 aFilterData[5].Name = "UserData";
559 aFilterData[5].Value <<= aUserData;
561 aFilterData[6].Name = "FileFormatVersion";
562 aFilterData[6].Value <<= pFilterEntry->maFileFormatVersion;
564 aFilterData[7].Name = "TemplateName";
565 aFilterData[7].Value <<= pFilterEntry->maImportTemplate;
567 // 4. insert new or replace existing filter
570 Any aAny( makeAny( aFilterData ) );
571 if( mxFilterContainer->hasByName( pFilterEntry->maFilterName ) )
573 mxFilterContainer->replaceByName( pFilterEntry->maFilterName, aAny );
575 else
577 mxFilterContainer->insertByName( pFilterEntry->maFilterName, aAny );
580 catch( const Exception& )
582 OSL_FAIL( "XMLFilterSettingsDialog::insertOrEdit exception catched!" );
583 bOk = false;
587 // 5. prepare type information
588 if( bOk )
590 Sequence< PropertyValue > aValues(4);
592 aValues[0].Name = "UIName";
593 aValues[0].Value <<= pFilterEntry->maInterfaceName;
594 aValues[1].Name = "ClipboardFormat";
595 OUString aDocType;
596 if( !pFilterEntry->maDocType.match( m_sDocTypePrefix ) )
598 aDocType = m_sDocTypePrefix;
599 aDocType += pFilterEntry->maDocType;
601 else
603 aDocType = pFilterEntry->maDocType;
605 if (aDocType == m_sDocTypePrefix)
606 aValues[1].Value <<= OUString();
607 else
608 aValues[1].Value <<= aDocType;
610 aValues[2].Name = "DocumentIconID";
611 aValues[2].Value <<= pFilterEntry->mnDocumentIconID;
613 aValues[3].Name = "Extensions";
614 aValues[3].Value <<= createExtensionsSequence( pFilterEntry->maExtension );
616 // the detect service will only be registered, if a doctype/search token was specified
617 if (aDocType.getLength() > m_sDocTypePrefix.getLength())
619 aValues.realloc(5);
620 aValues[4].Name = "DetectService";
621 aValues[4].Value <<= OUString( "com.sun.star.comp.filters.XMLFilterDetect" );
624 // 6. insert new or replace existing type information
625 if( mxTypeDetection.is() )
629 Any aAny( makeAny( aValues ) );
630 if( mxTypeDetection->hasByName( pFilterEntry->maType ) )
632 mxTypeDetection->replaceByName( pFilterEntry->maType, aAny );
634 else
636 mxTypeDetection->insertByName( pFilterEntry->maType, aAny );
639 catch( const Exception& )
641 OSL_FAIL( "XMLFilterSettingsDialog::insertOrEdit exception catched!" );
642 bOk = false;
646 if( bOk )
650 Reference< XFlushable > xFlushable( mxTypeDetection, UNO_QUERY );
651 if( xFlushable.is() )
652 xFlushable->flush();
654 catch( const Exception& )
656 OSL_FAIL( "XMLFilterSettingsDialog::insertOrEdit exception catched!" );
657 bOk = false;
661 if( !bOk )
663 // we failed to add the type, so lets remove the filter
666 mxFilterContainer->removeByName( pFilterEntry->maFilterName );
668 catch( const Exception& )
670 OSL_FAIL( "XMLFilterSettingsDialog::insertOrEdit exception catched!" );
671 bOk = false;
674 else
676 if( bOk )
680 Reference< XFlushable > xFlushable( mxFilterContainer, UNO_QUERY );
681 if( xFlushable.is() )
682 xFlushable->flush();
684 catch( const Exception& )
686 OSL_FAIL( "XMLFilterSettingsDialog::insertOrEdit exception catched!" );
687 bOk = false;
690 if( !bOk )
692 // we failed to add the filter, so lets remove the type
695 mxTypeDetection->removeByName( pFilterEntry->maType );
697 catch( const Exception& )
699 OSL_FAIL( "XMLFilterSettingsDialog::insertOrEdit exception catched!" );
707 if( bOk )
709 if( mxExtendedTypeDetection.is() )
711 OUString sFilterDetectService( "com.sun.star.comp.filters.XMLFilterDetect" );
712 if( mxExtendedTypeDetection->hasByName( sFilterDetectService ) )
714 Sequence< PropertyValue > aSequence;
715 if( mxExtendedTypeDetection->getByName( sFilterDetectService ) >>= aSequence )
717 sal_Int32 nCount = aSequence.getLength();
718 sal_Int32 nIndex;
719 for( nIndex = 0; nIndex < nCount; nIndex++ )
721 if ( aSequence[nIndex].Name == "Types" )
723 Sequence< OUString > aTypes;
724 if( aSequence[nIndex].Value >>= aTypes )
726 sal_Int32 nStrCount = aTypes.getLength();
727 sal_Int32 nStr;
728 for( nStr = 0; nStr < nStrCount; nStr++ )
730 if( aTypes[nStr] == pFilterEntry->maType )
731 break;
734 if( nStr == nStrCount )
736 aTypes.realloc( nStrCount + 1 );
737 aTypes[nStrCount] = pFilterEntry->maType;
739 aSequence[nIndex].Value <<= aTypes;
741 mxExtendedTypeDetection->replaceByName( sFilterDetectService, makeAny( aSequence ) );
743 Reference< XFlushable > xFlushable( mxExtendedTypeDetection, UNO_QUERY );
744 if( xFlushable.is() )
745 xFlushable->flush();
749 break;
757 // update ui
758 if( bOk )
760 if( pOldInfo )
762 m_pFilterListBox->changeEntry( pFilterEntry );
764 else
766 m_pFilterListBox->addFilterEntry( pFilterEntry );
767 maFilterVector.push_back( pFilterEntry );
771 return bOk;
774 /** is called when the user clicks the "Test" button */
775 void XMLFilterSettingsDialog::onTest()
777 // get the first selected filter
778 SvTreeListEntry* pEntry = m_pFilterListBox->FirstSelected();
779 if( pEntry )
781 filter_info_impl* pInfo = static_cast<filter_info_impl*>(pEntry->GetUserData());
783 ScopedVclPtrInstance< XMLFilterTestDialog > aDlg(this, mxContext);
784 aDlg->test( *pInfo );
788 void XMLFilterSettingsDialog::onDelete()
790 SvTreeListEntry* pEntry = m_pFilterListBox->FirstSelected();
791 if( pEntry )
793 filter_info_impl* pInfo = static_cast<filter_info_impl*>(pEntry->GetUserData());
795 OUString aPlaceHolder( "%s" );
796 OUString aMessage(RESIDSTR(STR_WARN_DELETE));
797 aMessage = aMessage.replaceFirst( aPlaceHolder, pInfo->maFilterName );
799 ScopedVclPtrInstance< WarningBox > aWarnBox(this, (WinBits)(WB_YES_NO | WB_DEF_YES), aMessage );
800 if( aWarnBox->Execute() == RET_YES )
804 if( mxFilterContainer->hasByName( pInfo->maFilterName ) )
806 mxFilterContainer->removeByName( pInfo->maFilterName );
808 bool bTypeStillUsed = false;
810 // now loop over all filter and see if someone else uses the same type
811 Sequence< OUString > aFilterNames( mxFilterContainer->getElementNames() );
812 OUString* pFilterName = aFilterNames.getArray();
814 const sal_Int32 nCount = aFilterNames.getLength();
815 sal_Int32 nFilter;
816 Sequence< PropertyValue > aValues;
818 for( nFilter = 0; (nFilter < nCount) && !bTypeStillUsed; nFilter++, pFilterName++ )
820 Any aAny( mxFilterContainer->getByName( *pFilterName ) );
821 if( !(aAny >>= aValues) )
822 continue;
824 const sal_Int32 nValueCount( aValues.getLength() );
825 PropertyValue* pValues = aValues.getArray();
826 sal_Int32 nValue;
828 for( nValue = 0; (nValue < nValueCount) && !bTypeStillUsed; nValue++, pValues++ )
830 if ( pValues->Name == "Type" )
832 OUString aType;
833 pValues->Value >>= aType;
834 if( aType == pInfo->maType )
835 bTypeStillUsed = true;
837 break;
842 // if the type is not used anymore, remove it also
843 if( !bTypeStillUsed )
845 if( mxTypeDetection->hasByName( pInfo->maType ) )
847 mxTypeDetection->removeByName( pInfo->maType );
851 Reference< XFlushable > xFlushable( mxFilterContainer, UNO_QUERY );
852 if( xFlushable.is() )
853 xFlushable->flush();
855 xFlushable.set( mxTypeDetection, UNO_QUERY );
856 if( xFlushable.is() )
857 xFlushable->flush();
859 // now remove entry from ui
860 m_pFilterListBox->RemoveSelection();
862 // and delete the filter entry
863 maFilterVector.erase(std::find( maFilterVector.begin(), maFilterVector.end(), pInfo ));
865 delete pInfo;
868 catch( const Exception& )
870 OSL_FAIL( "XMLFilterSettingsDialog::onDelete exception catched!" );
875 updateStates();
878 void XMLFilterSettingsDialog::onSave()
880 XMLFilterVector aFilters;
882 int nFilters = 0;
884 SvTreeListEntry* pEntry = m_pFilterListBox->FirstSelected();
885 while( pEntry )
887 filter_info_impl* pInfo = static_cast<filter_info_impl*>(pEntry->GetUserData());
888 aFilters.push_back( pInfo );
889 pEntry = m_pFilterListBox->NextSelected( pEntry );
890 nFilters++;
893 // Open Fileopen-Dialog
894 ::sfx2::FileDialogHelper aDlg(
895 css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION );
897 OUString aExtensions( "*.jar" );
898 OUString aFilterName(RESIDSTR(STR_FILTER_PACKAGE));
899 aFilterName += " (" + aExtensions + ")";
901 aDlg.AddFilter( aFilterName, aExtensions );
903 if ( aDlg.Execute() == ERRCODE_NONE )
905 XMLFilterJarHelper aJarHelper( mxContext );
906 aJarHelper.savePackage( aDlg.GetPath(), aFilters );
908 INetURLObject aURL( aDlg.GetPath() );
910 OUString sPlaceholder( "%s" );
912 OUString aMsg;
913 if( nFilters > 0 )
915 aMsg = RESIDSTR(STR_FILTERS_HAVE_BEEN_SAVED);
916 aMsg = aMsg.replaceFirst( sPlaceholder, OUString::number( nFilters ) );
917 aMsg = aMsg.replaceFirst( sPlaceholder, aURL.GetName() );
919 else
921 aMsg = RESIDSTR(STR_FILTER_HAS_BEEN_SAVED);
922 aMsg = aMsg.replaceFirst( sPlaceholder, (*aFilters.begin())->maFilterName );
923 aMsg = aMsg.replaceFirst( sPlaceholder, aURL.GetName() );
926 ScopedVclPtrInstance< InfoBox > aBox(this, aMsg );
927 aBox->Execute();
931 void XMLFilterSettingsDialog::onOpen()
933 XMLFilterVector aFilters;
935 // Open Fileopen-Dialog
936 ::sfx2::FileDialogHelper aDlg(
937 css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE );
939 OUString aExtensions( "*.jar" );
940 OUString aFilterName(RESIDSTR(STR_FILTER_PACKAGE));
941 aFilterName += " (" + aExtensions + ")";
943 aDlg.AddFilter( aFilterName, aExtensions );
945 if ( aDlg.Execute() == ERRCODE_NONE )
947 OUString aURL( aDlg.GetPath() );
949 XMLFilterJarHelper aJarHelper( mxContext );
950 aJarHelper.openPackage( aURL, aFilters );
952 int nFilters = 0;
953 XMLFilterVector::iterator aIter( aFilters.begin() );
954 while( aIter != aFilters.end() )
956 filter_info_impl* pInfo = (*aIter++);
958 if( insertOrEdit( pInfo ) )
960 aFilterName = pInfo->maFilterName;
961 nFilters++;
964 delete pInfo;
967 disposeFilterList();
968 initFilterList();
970 OUString sPlaceholder( "%s" );
971 OUString aMsg;
972 if( nFilters == 0 )
974 INetURLObject aURLObj( aURL );
975 aMsg = RESIDSTR(STR_NO_FILTERS_FOUND);
976 aMsg = aMsg.replaceFirst( sPlaceholder, aURLObj.GetName() );
978 else if( nFilters == 1 )
980 aMsg = RESIDSTR(STR_FILTER_INSTALLED);
981 aMsg = aMsg.replaceFirst( sPlaceholder, aFilterName );
984 else
986 aMsg = RESIDSTR(STR_FILTERS_INSTALLED);
987 aMsg = aMsg.replaceFirst( sPlaceholder, OUString::number( nFilters ) );
990 ScopedVclPtrInstance< InfoBox > aBox(this, aMsg );
991 aBox->Execute();
995 bool XMLFilterSettingsDialog::EventNotify( NotifyEvent& rNEvt )
997 // Because of tab control first call the base class.
998 bool bRet = ModelessDialog::EventNotify(rNEvt);
999 if ( !bRet )
1001 if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
1003 const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
1004 vcl::KeyCode aKeyCode = pKEvt->GetKeyCode();
1005 sal_uInt16 nKeyCode = aKeyCode.GetCode();
1006 bool bMod1 = pKEvt->GetKeyCode().IsMod1();
1008 if( nKeyCode == KEY_ESCAPE || (bMod1 && (nKeyCode == KEY_W)))
1010 Close();
1011 return true;
1016 return bRet;
1019 void XMLFilterSettingsDialog::disposeFilterList()
1021 std::vector< filter_info_impl* >::iterator aIter( maFilterVector.begin() );
1022 while( aIter != maFilterVector.end() )
1024 delete (*aIter++);
1026 maFilterVector.clear();
1028 m_pFilterListBox->Clear();
1031 void XMLFilterSettingsDialog::initFilterList()
1033 if( mxFilterContainer.is() )
1035 Sequence< OUString > aFilterNames( mxFilterContainer->getElementNames() );
1036 OUString* pFilterName = aFilterNames.getArray();
1038 const sal_Int32 nCount = aFilterNames.getLength();
1039 sal_Int32 nFilter;
1041 Sequence< PropertyValue > aValues;
1043 std::unique_ptr<filter_info_impl> pTempFilter( new filter_info_impl );
1044 Sequence< OUString > aUserData;
1046 for( nFilter = 0; nFilter < nCount; nFilter++, pFilterName++ )
1048 aUserData.realloc(0);
1052 Any aAny( mxFilterContainer->getByName( *pFilterName ) );
1053 if( !(aAny >>= aValues) )
1054 continue;
1056 OUString aFilterService;
1057 pTempFilter->maFilterName = *pFilterName;
1059 const sal_Int32 nValueCount( aValues.getLength() );
1060 PropertyValue* pValues = aValues.getArray();
1061 sal_Int32 nValue;
1063 for( nValue = 0; nValue < nValueCount; nValue++, pValues++ )
1065 if ( pValues->Name == "Type" )
1067 pValues->Value >>= pTempFilter->maType;
1069 else if ( pValues->Name == "UIName" )
1071 pValues->Value >>= pTempFilter->maInterfaceName;
1073 else if ( pValues->Name == "DocumentService" )
1075 pValues->Value >>= pTempFilter->maDocumentService;
1077 else if ( pValues->Name == "FilterService" )
1079 pValues->Value >>= aFilterService;
1081 else if ( pValues->Name == "Flags" )
1083 pValues->Value >>= pTempFilter->maFlags;
1085 else if ( pValues->Name == "UserData" )
1087 pValues->Value >>= aUserData;
1089 else if ( pValues->Name == "FileFormatVersion" )
1091 pValues->Value >>= pTempFilter->maFileFormatVersion;
1093 else if ( pValues->Name == "TemplateName" )
1095 pValues->Value >>= pTempFilter->maImportTemplate;
1097 else if ( pValues->Name == "Finalized" )
1099 pValues->Value >>= pTempFilter->mbReadonly;
1103 // if this is not a XmlFilterAdaptor entry, skip it
1104 if( aFilterService != "com.sun.star.comp.Writer.XmlFilterAdaptor" )
1105 continue;
1108 // if we don't have the needed user data, skip it
1109 if( aUserData.getLength() < 6 )
1110 continue;
1112 // if this is not an XSLTFilter entry, skip it
1113 if( aUserData[0] != "com.sun.star.documentconversion.XSLTFilter" )
1114 continue;
1116 // get filter information from userdata
1117 pTempFilter->mbNeedsXSLT2 = aUserData[1].toBoolean();
1118 pTempFilter->maImportService = aUserData[2];
1119 pTempFilter->maExportService = aUserData[3];
1120 pTempFilter->maImportXSLT = aUserData[4];
1121 pTempFilter->maExportXSLT = aUserData[5];
1122 if( aUserData.getLength() >= 8 )
1123 pTempFilter->maComment = aUserData[7];
1125 // get type information
1126 if( mxTypeDetection.is() )
1130 aAny = mxTypeDetection->getByName( pTempFilter->maType );
1131 Sequence< PropertyValue > aValues2;
1133 if( aAny >>= aValues2 )
1135 const sal_Int32 nValueCount2( aValues2.getLength() );
1136 PropertyValue* pValues2 = aValues2.getArray();
1137 sal_Int32 nValue2;
1139 for( nValue2 = 0; nValue2 < nValueCount2; nValue2++, pValues2++ )
1141 if ( pValues2->Name == "ClipboardFormat" )
1143 OUString aDocType;
1144 pValues2->Value >>= aDocType;
1146 if( aDocType.match( m_sDocTypePrefix ) )
1147 aDocType = aDocType.copy( m_sDocTypePrefix.getLength() );
1149 pTempFilter->maDocType = aDocType;
1151 else if ( pValues2->Name == "Extensions" )
1153 Sequence< OUString > aExtensions;
1154 if( pValues2->Value >>= aExtensions )
1156 (pTempFilter->maExtension).clear();
1158 sal_Int32 nCount3( aExtensions.getLength() );
1159 OUString* pExtensions = aExtensions.getArray();
1160 sal_Int32 n;
1161 for( n = 0; n < nCount3; n++ )
1163 if( n > 0 )
1164 pTempFilter->maExtension += ";";
1165 pTempFilter->maExtension += (*pExtensions++);
1169 else if ( pValues2->Name == "DocumentIconID" )
1171 pValues2->Value >>= pTempFilter->mnDocumentIconID;
1173 else if ( pValues2->Name == "Finalized" )
1175 // both the filter and the type may be finalized
1176 bool bTemp = false;
1177 pValues2->Value >>= bTemp;
1178 pTempFilter->mbReadonly |= bTemp;
1183 catch( const css::container::NoSuchElementException& )
1185 OSL_FAIL( "Type not found, user error?" ); // TODO: error?
1189 // add entry to internal container and to ui filter list box
1190 maFilterVector.push_back( pTempFilter.get() );
1191 m_pFilterListBox->addFilterEntry( pTempFilter.release() );
1194 pTempFilter.reset( new filter_info_impl );
1196 catch( const Exception& )
1198 OSL_FAIL( "XMLFilterSettingsDialog::initFilterList exception catched!" );
1204 SvTreeListEntry* pEntry = m_pFilterListBox->GetEntry( 0 );
1205 if( pEntry )
1206 m_pFilterListBox->Select( pEntry );
1209 application_info_impl::application_info_impl( const sal_Char * pDocumentService, ResId& rUINameRes, const sal_Char * mpXMLImporter, const sal_Char * mpXMLExporter )
1210 : maDocumentService( pDocumentService, strlen( pDocumentService ), RTL_TEXTENCODING_ASCII_US ),
1211 maDocumentUIName( OUString( rUINameRes ) ),
1212 maXMLImporter( mpXMLImporter, strlen( mpXMLImporter ), RTL_TEXTENCODING_ASCII_US ),
1213 maXMLExporter( mpXMLExporter, strlen( mpXMLExporter ), RTL_TEXTENCODING_ASCII_US )
1217 std::vector< application_info_impl* >& getApplicationInfos()
1219 static std::vector< application_info_impl* > aInfos;
1221 if( aInfos.empty() )
1223 auto resmgr = getXSLTDialogResMgr();
1224 ResId aResId1( STR_APPL_NAME_WRITER, *resmgr.get() );
1225 aInfos.push_back( new application_info_impl(
1226 "com.sun.star.text.TextDocument",
1227 aResId1,
1228 "com.sun.star.comp.Writer.XMLImporter",
1229 "com.sun.star.comp.Writer.XMLExporter" ) );
1231 ResId aResId2( STR_APPL_NAME_CALC, *resmgr.get() );
1232 aInfos.push_back( new application_info_impl(
1233 "com.sun.star.sheet.SpreadsheetDocument",
1234 aResId2,
1235 "com.sun.star.comp.Calc.XMLImporter",
1236 "com.sun.star.comp.Calc.XMLExporter" ) );
1238 ResId aResId3( STR_APPL_NAME_IMPRESS, *resmgr.get() );
1239 aInfos.push_back( new application_info_impl(
1240 "com.sun.star.presentation.PresentationDocument",
1241 aResId3,
1242 "com.sun.star.comp.Impress.XMLImporter",
1243 "com.sun.star.comp.Impress.XMLExporter" ) );
1245 ResId aResId4( STR_APPL_NAME_DRAW, *resmgr.get() );
1246 aInfos.push_back( new application_info_impl(
1247 "com.sun.star.drawing.DrawingDocument",
1248 aResId4,
1249 "com.sun.star.comp.Draw.XMLImporter",
1250 "com.sun.star.comp.Draw.XMLExporter" ) );
1252 // --- oasis file formats...
1253 ResId aResId5( STR_APPL_NAME_OASIS_WRITER, *resmgr.get() );
1254 aInfos.push_back( new application_info_impl(
1255 "com.sun.star.text.TextDocument",
1256 aResId5,
1257 "com.sun.star.comp.Writer.XMLOasisImporter",
1258 "com.sun.star.comp.Writer.XMLOasisExporter" ) );
1260 ResId aResId6( STR_APPL_NAME_OASIS_CALC, *resmgr.get() );
1261 aInfos.push_back( new application_info_impl(
1262 "com.sun.star.sheet.SpreadsheetDocument",
1263 aResId6,
1264 "com.sun.star.comp.Calc.XMLOasisImporter",
1265 "com.sun.star.comp.Calc.XMLOasisExporter" ) );
1267 ResId aResId7( STR_APPL_NAME_OASIS_IMPRESS, *resmgr.get() );
1268 aInfos.push_back( new application_info_impl(
1269 "com.sun.star.presentation.PresentationDocument",
1270 aResId7,
1271 "com.sun.star.comp.Impress.XMLOasisImporter",
1272 "com.sun.star.comp.Impress.XMLOasisExporter" ) );
1274 ResId aResId8( STR_APPL_NAME_OASIS_DRAW, *resmgr.get() );
1275 aInfos.push_back( new application_info_impl(
1276 "com.sun.star.drawing.DrawingDocument",
1277 aResId8,
1278 "com.sun.star.comp.Draw.XMLOasisImporter",
1279 "com.sun.star.comp.Draw.XMLOasisExporter" ) );
1282 return aInfos;
1285 const application_info_impl* getApplicationInfo( const OUString& rServiceName )
1287 std::vector< application_info_impl* >& rInfos = getApplicationInfos();
1288 for (std::vector< application_info_impl* >::const_iterator aIter( rInfos.begin() ), aEnd( rInfos.end() );
1289 aIter != aEnd ; ++aIter)
1291 if( rServiceName == (*aIter)->maXMLExporter ||
1292 rServiceName == (*aIter)->maXMLImporter)
1294 return (*aIter);
1297 return nullptr;
1300 OUString getApplicationUIName( const OUString& rServiceName )
1302 const application_info_impl* pInfo = getApplicationInfo( rServiceName );
1303 if( pInfo )
1305 return pInfo->maDocumentUIName;
1307 else
1309 OUString aRet = RESIDSTR(STR_UNKNOWN_APPLICATION);
1310 if( !rServiceName.isEmpty() )
1312 aRet += " (" + rServiceName + ")";
1314 return aRet;
1318 SvxPathControl::SvxPathControl(vcl::Window* pParent)
1319 : Window(pParent, WB_HIDE | WB_CLIPCHILDREN | WB_TABSTOP | WB_DIALOGCONTROL | WB_BORDER)
1320 , bHasBeenShown(false)
1322 m_pVBox = VclPtr<VclVBox>::Create(this);
1324 m_pHeaderBar = VclPtr<HeaderBar>::Create(m_pVBox, WB_BOTTOMBORDER);
1325 m_pHeaderBar->set_height_request(GetTextHeight() + 6);
1327 m_pFocusCtrl = VclPtr<XMLFilterListBox>::Create(m_pVBox, this);
1328 m_pFocusCtrl->set_fill(true);
1329 m_pFocusCtrl->set_expand(true);
1331 m_pVBox->set_hexpand(true);
1332 m_pVBox->set_vexpand(true);
1333 m_pVBox->set_expand(true);
1334 m_pVBox->set_fill(true);
1335 m_pVBox->Show();
1338 #define ITEMID_NAME 1
1339 #define ITEMID_TYPE 2
1341 void SvxPathControl::Resize()
1343 Window::Resize();
1345 if (!m_pVBox)
1346 return;
1348 m_pVBox->SetSizePixel(GetSizePixel());
1350 if (!bHasBeenShown)
1351 bHasBeenShown = IsReallyShown();
1353 if (!bHasBeenShown)
1355 std::vector<long> aWidths;
1356 m_pFocusCtrl->getPreferredDimensions(aWidths);
1357 if (aWidths.empty())
1359 bHasBeenShown = false;
1360 return;
1362 long nFirstColumnWidth = aWidths[1];
1363 m_pHeaderBar->SetItemSize(ITEMID_NAME, nFirstColumnWidth);
1364 m_pHeaderBar->SetItemSize(ITEMID_TYPE, 0xFFFF);
1365 long nTabs[] = {2, 0, nFirstColumnWidth};
1366 m_pFocusCtrl->SetTabs(&nTabs[0], MapUnit::MapPixel);
1370 Size SvxPathControl::GetOptimalSize() const
1372 Size aDefSize(LogicToPixel(Size(150, 0), MapMode(MapUnit::MapAppFont)));
1373 Size aOptSize(m_pVBox->GetOptimalSize());
1374 long nRowHeight(GetTextHeight());
1375 aOptSize.Height() = nRowHeight * 10;
1376 aOptSize.Width() = std::max(aDefSize.Width(), aOptSize.Width());
1377 return aOptSize;
1380 SvxPathControl::~SvxPathControl()
1382 disposeOnce();
1385 void SvxPathControl::dispose()
1387 m_pFocusCtrl.disposeAndClear();
1388 m_pHeaderBar.disposeAndClear();
1389 m_pVBox.disposeAndClear();
1390 vcl::Window::dispose();
1393 VCL_BUILDER_FACTORY(SvxPathControl)
1395 bool SvxPathControl::EventNotify(NotifyEvent& rNEvt)
1397 bool bRet = Window::EventNotify(rNEvt);
1399 if ( m_pFocusCtrl && rNEvt.GetWindow() != m_pFocusCtrl && rNEvt.GetType() == MouseNotifyEvent::GETFOCUS )
1400 m_pFocusCtrl->GrabFocus();
1402 return bRet;
1405 XMLFilterListBox::XMLFilterListBox(Window* pParent, SvxPathControl* pPathControl)
1406 : SvTabListBox(pParent, WB_SORT | WB_HSCROLL | WB_CLIPCHILDREN | WB_TABSTOP)
1407 , m_pHeaderBar(pPathControl->getHeaderBar())
1409 Size aBoxSize( pParent->GetOutputSizePixel() );
1411 m_pHeaderBar->SetEndDragHdl( LINK( this, XMLFilterListBox, HeaderEndDrag_Impl ) );
1413 OUString aStr1(RESIDSTR(STR_COLUMN_HEADER_NAME));
1414 OUString aStr2(RESIDSTR(STR_COLUMN_HEADER_TYPE));
1416 long nTabSize = aBoxSize.Width() / 2;
1418 m_pHeaderBar->InsertItem( ITEMID_NAME, aStr1, nTabSize,
1419 HeaderBarItemBits::LEFT | HeaderBarItemBits::VCENTER );
1420 m_pHeaderBar->InsertItem( ITEMID_TYPE, aStr2, nTabSize,
1421 HeaderBarItemBits::LEFT | HeaderBarItemBits::VCENTER );
1423 static long nTabs[] = {2, 0, nTabSize };
1425 SetSelectionMode( SelectionMode::Multiple );
1426 SetTabs( &nTabs[0], MapUnit::MapPixel );
1427 SetScrolledHdl( LINK( this, XMLFilterListBox, TabBoxScrollHdl_Impl ) );
1428 SetHighlightRange();
1429 Show();
1430 m_pHeaderBar->Show();
1433 XMLFilterListBox::~XMLFilterListBox()
1435 disposeOnce();
1438 void XMLFilterListBox::dispose()
1440 m_pHeaderBar.clear();
1441 SvTabListBox::dispose();
1444 IMPL_LINK_NOARG( XMLFilterListBox, TabBoxScrollHdl_Impl, SvTreeListBox*, void )
1446 m_pHeaderBar->SetOffset( -GetXOffset() );
1449 IMPL_LINK( XMLFilterListBox, HeaderEndDrag_Impl, HeaderBar*, pBar, void )
1451 if ( pBar && !pBar->GetCurItemId() )
1452 return;
1454 if ( !m_pHeaderBar->IsItemMode() )
1456 Size aSz;
1457 sal_uInt16 nTabs = m_pHeaderBar->GetItemCount();
1458 long nTmpSz = 0;
1459 long nWidth = m_pHeaderBar->GetItemSize(ITEMID_NAME);
1460 long nBarWidth = m_pHeaderBar->GetSizePixel().Width();
1462 if(nWidth < 30)
1463 m_pHeaderBar->SetItemSize( ITEMID_TYPE, 30);
1464 else if ( ( nBarWidth - nWidth ) < 30 )
1465 m_pHeaderBar->SetItemSize( ITEMID_TYPE, nBarWidth - 30 );
1467 for ( sal_uInt16 i = 1; i <= nTabs; ++i )
1469 long nW = m_pHeaderBar->GetItemSize(i);
1470 aSz.Width() = nW + nTmpSz;
1471 nTmpSz += nW;
1472 SetTab( i, PixelToLogic( aSz, MapMode(MapUnit::MapAppFont) ).Width() );
1477 /** adds a new filter info entry to the ui filter list */
1478 void XMLFilterListBox::addFilterEntry( const filter_info_impl* pInfo )
1480 const OUString aEntryStr( getEntryString( pInfo ) );
1481 InsertEntryToColumn( aEntryStr, TREELIST_APPEND, 0xffff, const_cast<filter_info_impl *>(pInfo) );
1484 void XMLFilterListBox::changeEntry( const filter_info_impl* pInfo )
1486 const sal_uLong nCount = GetEntryCount();
1487 sal_uLong nPos;
1488 for( nPos = 0; nPos < nCount; nPos++ )
1490 SvTreeListEntry* pEntry = GetEntry( nPos );
1491 if( static_cast<filter_info_impl*>(pEntry->GetUserData()) == pInfo )
1493 OUString aEntryText( getEntryString( pInfo ) );
1494 SetEntryText( aEntryText, pEntry );
1495 break;
1500 OUString XMLFilterListBox::getEntryString( const filter_info_impl* pInfo )
1502 OUString aEntryStr( pInfo->maFilterName + "\t");
1503 if ( !pInfo->maExportService.isEmpty() )
1504 aEntryStr += getApplicationUIName( pInfo->maExportService );
1505 else
1506 aEntryStr += getApplicationUIName( pInfo->maImportService );
1507 aEntryStr += " - ";
1509 if( pInfo->maFlags & 1 )
1511 if( pInfo->maFlags & 2 )
1513 aEntryStr += RESIDSTR(STR_IMPORT_EXPORT);
1515 else
1517 aEntryStr += RESIDSTR(STR_IMPORT_ONLY);
1520 else if( pInfo->maFlags & 2 )
1522 aEntryStr += RESIDSTR(STR_EXPORT_ONLY);
1524 else
1526 aEntryStr += RESIDSTR(STR_UNDEFINED_FILTER);
1529 return aEntryStr;
1532 filter_info_impl::filter_info_impl()
1533 : maFlags(0x00080040)
1534 , maFileFormatVersion(0)
1535 , mnDocumentIconID(0)
1536 , mbReadonly(false)
1537 , mbNeedsXSLT2(false)
1541 filter_info_impl::filter_info_impl( const filter_info_impl& rInfo ) :
1542 maFilterName( rInfo.maFilterName ),
1543 maType( rInfo.maType ),
1544 maDocumentService( rInfo.maDocumentService ),
1545 maFilterService( rInfo.maFilterService ),
1546 maInterfaceName( rInfo.maInterfaceName ),
1547 maComment( rInfo.maComment ),
1548 maExtension( rInfo.maExtension ),
1549 maExportXSLT( rInfo.maExportXSLT ),
1550 maImportXSLT( rInfo.maImportXSLT ),
1551 maImportTemplate( rInfo.maImportTemplate ),
1552 maDocType( rInfo.maDocType ),
1553 maImportService( rInfo.maImportService ),
1554 maExportService( rInfo.maExportService ),
1555 maFlags( rInfo.maFlags ),
1556 maFileFormatVersion( rInfo.maFileFormatVersion ),
1557 mnDocumentIconID( rInfo.mnDocumentIconID ),
1558 mbReadonly( rInfo.mbReadonly ),
1559 mbNeedsXSLT2( rInfo.mbNeedsXSLT2 )
1563 bool filter_info_impl::operator==( const filter_info_impl& r ) const
1565 return maFilterName == r.maFilterName &&
1566 maType == r.maType &&
1567 maDocumentService == r.maDocumentService &&
1568 maFilterService == r.maFilterService &&
1569 maInterfaceName == r.maInterfaceName &&
1570 maComment == r.maComment &&
1571 maExtension == r.maExtension &&
1572 maDocType == r.maDocType &&
1573 maExportXSLT == r.maExportXSLT &&
1574 maImportXSLT == r.maImportXSLT &&
1575 maExportService == r.maExportService &&
1576 maImportService == r.maImportService &&
1577 maImportTemplate == r.maImportTemplate &&
1578 maFlags == r.maFlags &&
1579 maFileFormatVersion == r.maFileFormatVersion &&
1580 mbNeedsXSLT2 == r.mbNeedsXSLT2;
1584 Sequence< OUString > filter_info_impl::getFilterUserData() const
1586 Sequence< OUString > aUserData(8);
1588 aUserData[0] = "com.sun.star.documentconversion.XSLTFilter";
1589 aUserData[1] = OUString::boolean( mbNeedsXSLT2 );
1590 aUserData[2] = maImportService;
1591 aUserData[3] = maExportService;
1592 aUserData[4] = maImportXSLT;
1593 aUserData[5] = maExportXSLT;
1594 aUserData[7] = maComment;
1596 return aUserData;
1599 OUString string_encode( const OUString & rText )
1601 static sal_Bool const uricNoSlash[] = {
1602 false, false, false, false, false, false, false, false,
1603 false, false, false, false, false, false, false, false,
1604 false, false, false, false, false, false, false, false,
1605 false, false, false, false, false, false, false, false,
1606 false, true, false, false, true, false, true, true, // !"#$%&'
1607 true, true, true, true, false, true, true, false, // ()*+,-./
1608 true, true, true, true, true, true, true, true, // 01234567
1609 true, true, true, false, false, true, false, true, // 89:;<=>?
1610 true, true, true, true, true, true, true, true, // @ABCDEFG
1611 true, true, true, true, true, true, true, true, // HIJKLMNO
1612 true, true, true, true, true, true, true, true, // PQRSTUVW
1613 true, true, true, false, false, false, false, true, // XYZ[\]^_
1614 false, true, true, true, true, true, true, true, // `abcdefg
1615 true, true, true, true, true, true, true, true, // hijklmno
1616 true, true, true, true, true, true, true, true, // pqrstuvw
1617 true, true, true, false, false, false, true, false}; // xyz{|}~
1620 return Uri::encode( rText, uricNoSlash, rtl_UriEncodeCheckEscapes, RTL_TEXTENCODING_UTF8 );
1623 OUString string_decode( const OUString & rText )
1625 return Uri::decode( rText, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
1628 bool copyStreams( const Reference< XInputStream >& xIS, const Reference< XOutputStream >& xOS )
1632 sal_Int32 nBufferSize = 512;
1633 Sequence< sal_Int8 > aDataBuffer(nBufferSize);
1635 sal_Int32 nRead;
1638 nRead = xIS->readBytes( aDataBuffer, nBufferSize );
1640 if( nRead )
1642 if( nRead < nBufferSize )
1644 nBufferSize = nRead;
1645 aDataBuffer.realloc(nRead);
1648 xOS->writeBytes( aDataBuffer );
1651 while( nRead );
1653 xOS->flush();
1655 return true;
1657 catch(const Exception&)
1659 OSL_FAIL( "copyStreams() exception catched!" );
1662 return false;
1665 bool createDirectory( OUString& rURL )
1667 sal_Int32 nLastIndex = sizeof( "file:///" ) - 2;
1668 while( nLastIndex != -1 )
1670 nLastIndex = rURL.indexOf( '/', nLastIndex + 1);
1671 if( nLastIndex != -1 )
1673 OUString aDirURL( rURL.copy( 0, nLastIndex ) );
1674 Directory aDir( aDirURL );
1675 Directory::RC rc = aDir.open();
1676 if( rc == Directory::E_NOENT )
1677 rc = osl::Directory::create( aDirURL );
1679 if( rc != Directory::E_None )
1681 return false;
1686 return true;
1689 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */