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