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