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