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