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