1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "com/sun/star/beans/XPropertyAccess.hpp" 29 #include "com/sun/star/container/XContainerQuery.hpp" 30 #include "com/sun/star/container/XNameContainer.hpp" 31 #include "com/sun/star/document/AmbigousFilterRequest.hpp" 32 #include "com/sun/star/document/FilterOptionsRequest.hpp" 33 #include "com/sun/star/document/NoSuchFilterRequest.hpp" 34 #include "com/sun/star/document/XImporter.hpp" 35 #include "com/sun/star/document/XInteractionFilterOptions.hpp" 36 #include "com/sun/star/document/XInteractionFilterSelect.hpp" 37 #include "com/sun/star/lang/XMultiServiceFactory.hpp" 38 #include "com/sun/star/task/XInteractionAbort.hpp" 39 #include "com/sun/star/task/XInteractionRequest.hpp" 40 #include "com/sun/star/ui/dialogs/XExecutableDialog.hpp" 41 42 #include "vos/mutex.hxx" 43 #include "comphelper/sequenceashashmap.hxx" 44 #include "vcl/svapp.hxx" 45 46 #include "getcontinuations.hxx" 47 #include "fltdlg.hxx" 48 49 #include "iahndl.hxx" 50 51 using namespace com::sun::star; 52 53 namespace { 54 55 void 56 executeFilterDialog( 57 Window * pParent , 58 rtl::OUString const & rURL , 59 uui::FilterNameList const & rFilters, 60 rtl::OUString & rFilter ) 61 SAL_THROW((uno::RuntimeException)) 62 { 63 try 64 { 65 vos::OGuard aGuard(Application::GetSolarMutex()); 66 67 std::auto_ptr< ResMgr > xManager( 68 ResMgr::CreateResMgr(CREATEVERSIONRESMGR_NAME(uui))); 69 70 std::auto_ptr< uui::FilterDialog > xDialog( 71 new uui::FilterDialog(pParent, xManager.get())); 72 73 xDialog->SetURL(rURL); 74 xDialog->ChangeFilters(&rFilters); 75 76 uui::FilterNameListPtr pSelected = rFilters.end(); 77 if( xDialog->AskForFilter( pSelected ) ) 78 { 79 rFilter = pSelected->sInternal; 80 } 81 } 82 catch (std::bad_alloc const &) 83 { 84 throw uno::RuntimeException( 85 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("out of memory")), 86 uno::Reference< uno::XInterface >()); 87 } 88 } 89 90 void 91 handleNoSuchFilterRequest_( 92 Window * pParent, 93 uno::Reference< lang::XMultiServiceFactory > const & xServiceFactory, 94 document::NoSuchFilterRequest const & rRequest, 95 uno::Sequence< uno::Reference< task::XInteractionContinuation > > const & 96 rContinuations ) 97 SAL_THROW((uno::RuntimeException)) 98 { 99 uno::Reference< task::XInteractionAbort > xAbort; 100 uno::Reference< document::XInteractionFilterSelect > xFilterTransport; 101 getContinuations(rContinuations, &xAbort, &xFilterTransport); 102 103 // check neccessary ressources - if they don't exist - abort or 104 // break this operation 105 if (!xAbort.is()) 106 return; 107 108 if (!xFilterTransport.is()) 109 { 110 xAbort->select(); 111 return; 112 } 113 114 uno::Reference< container::XContainerQuery > xFilterContainer; 115 try 116 { 117 xFilterContainer.set( xServiceFactory->createInstance( 118 ::rtl::OUString::createFromAscii( 119 "com.sun.star.document.FilterFactory") ), 120 uno::UNO_QUERY ); 121 } 122 catch ( uno::Exception const & ) 123 { 124 } 125 126 if (!xFilterContainer.is()) 127 { 128 xAbort->select(); 129 return; 130 } 131 132 uui::FilterNameList lNames; 133 134 // Note: We look for all filters here which match the following criteria: 135 // - they are import filters as minimum (of course they can 136 // support export too) 137 // - we don't show any filter which are flaged as "don't show it 138 // at the UI" or "they are not installed" 139 // - we ignore filters, which have not set any valid 140 // DocumentService (e.g. our pure graphic filters) 141 // - we show it sorted by her UIName's 142 // - We don't use the order flag or prefer default filters. 143 // (Because this list shows all filters and the user should 144 // find his filter vry easy by his UIName ...) 145 // - We use "_query_all" here ... but we filter graphic filters 146 // out by using DocumentService property later! 147 uno::Reference< container::XEnumeration > xFilters 148 = xFilterContainer->createSubSetEnumerationByQuery( 149 ::rtl::OUString::createFromAscii( 150 "_query_all:sort_prop=uiname:iflags=1:eflags=143360")); 151 while (xFilters->hasMoreElements()) 152 { 153 try 154 { 155 ::comphelper::SequenceAsHashMap lProps(xFilters->nextElement()); 156 uui::FilterNamePair aPair; 157 158 aPair.sInternal = lProps.getUnpackedValueOrDefault( 159 rtl::OUString::createFromAscii("Name"), ::rtl::OUString()); 160 aPair.sUI = lProps.getUnpackedValueOrDefault( 161 rtl::OUString::createFromAscii("UIName"), ::rtl::OUString()); 162 if ( (!aPair.sInternal.Len()) || (!aPair.sUI.Len() ) ) 163 { 164 continue; 165 } 166 lNames.push_back( aPair ); 167 } 168 catch(const uno::RuntimeException&) 169 { 170 throw; 171 } 172 catch(const uno::Exception&) 173 { 174 continue; 175 } 176 } 177 178 // no list available for showing 179 // -> abort operation 180 if (lNames.size()<1) 181 { 182 xAbort->select(); 183 return; 184 } 185 186 // let the user select the right filter 187 rtl::OUString sSelectedFilter; 188 executeFilterDialog( pParent, 189 rRequest.URL, 190 lNames, 191 sSelectedFilter ); 192 193 // If he doesn't select anyone 194 // -> abort operation 195 if (sSelectedFilter.getLength()<1) 196 { 197 xAbort->select(); 198 return; 199 } 200 201 // otherwhise set it for return 202 xFilterTransport->setFilter( sSelectedFilter ); 203 xFilterTransport->select(); 204 } 205 206 void 207 handleAmbigousFilterRequest_( 208 Window * pParent, 209 uno::Reference< lang::XMultiServiceFactory > const & xServiceFactory, 210 document::AmbigousFilterRequest const & rRequest, 211 uno::Sequence< 212 uno::Reference< 213 task::XInteractionContinuation > > const & rContinuations) 214 SAL_THROW((uno::RuntimeException)) 215 { 216 uno::Reference< task::XInteractionAbort > xAbort; 217 uno::Reference< document::XInteractionFilterSelect > xFilterTransport; 218 getContinuations(rContinuations, &xAbort, &xFilterTransport); 219 220 uui::FilterNameList lNames; 221 222 uno::Reference< container::XNameContainer > xFilterContainer; 223 try 224 { 225 xFilterContainer.set( xServiceFactory->createInstance( 226 ::rtl::OUString::createFromAscii( 227 "com.sun.star.document.FilterFactory") ), 228 uno::UNO_QUERY ); 229 } 230 catch ( uno::Exception & ) 231 { 232 } 233 234 if( xFilterContainer.is() ) 235 { 236 uno::Any aPackedSet ; 237 uno::Sequence< beans::PropertyValue > lProps ; 238 sal_Int32 nStep ; 239 uui::FilterNamePair aPair ; 240 241 try 242 { 243 aPackedSet = xFilterContainer->getByName( rRequest.SelectedFilter ); 244 } 245 catch(const container::NoSuchElementException&) 246 { 247 aPackedSet.clear(); 248 } 249 aPackedSet >>= lProps; 250 for( nStep=0; nStep<lProps.getLength(); ++nStep ) 251 { 252 if( lProps[nStep].Name.compareToAscii("UIName") == 0 ) 253 { 254 ::rtl::OUString sTemp; 255 lProps[nStep].Value >>= sTemp; 256 aPair.sUI = sTemp; 257 aPair.sInternal = rRequest.SelectedFilter; 258 lNames.push_back( aPair ); 259 break; 260 } 261 } 262 263 try 264 { 265 aPackedSet = xFilterContainer->getByName( rRequest.DetectedFilter ); 266 } 267 catch(const container::NoSuchElementException&) 268 { 269 aPackedSet.clear(); 270 } 271 aPackedSet >>= lProps; 272 for( nStep=0; nStep<lProps.getLength(); ++nStep ) 273 { 274 if( lProps[nStep].Name.compareToAscii("UIName") == 0 ) 275 { 276 ::rtl::OUString sTemp; 277 lProps[nStep].Value >>= sTemp; 278 aPair.sUI = sTemp; 279 aPair.sInternal = rRequest.DetectedFilter; 280 lNames.push_back( aPair ); 281 break; 282 } 283 } 284 } 285 286 if( xAbort.is() && xFilterTransport.is() ) 287 { 288 if( lNames.size() < 1 ) 289 { 290 xAbort->select(); 291 } 292 else 293 { 294 rtl::OUString sFilter; 295 executeFilterDialog( pParent, 296 rRequest.URL, 297 lNames, 298 sFilter ); 299 300 if( sFilter.getLength() > 0 ) 301 { 302 xFilterTransport->setFilter( sFilter ); 303 xFilterTransport->select(); 304 } 305 else 306 xAbort->select(); 307 } 308 } 309 } 310 311 void 312 handleFilterOptionsRequest_( 313 uno::Reference< lang::XMultiServiceFactory > const & xServiceFactory, 314 document::FilterOptionsRequest const & rRequest, 315 uno::Sequence< uno::Reference< task::XInteractionContinuation > > const & 316 rContinuations) 317 SAL_THROW((uno::RuntimeException)) 318 { 319 uno::Reference< task::XInteractionAbort > xAbort; 320 uno::Reference< document::XInteractionFilterOptions > xFilterOptions; 321 getContinuations(rContinuations, &xAbort, &xFilterOptions); 322 323 uno::Reference< container::XNameAccess > xFilterCFG; 324 try 325 { 326 xFilterCFG.set( xServiceFactory->createInstance( 327 ::rtl::OUString::createFromAscii( 328 "com.sun.star.document.FilterFactory" ) ), 329 uno::UNO_QUERY ); 330 } 331 catch ( uno::Exception const & ) 332 { 333 } 334 335 if( xFilterCFG.is() && rRequest.rProperties.getLength() ) 336 { 337 try 338 { 339 ::rtl::OUString aFilterName; 340 sal_Int32 nPropCount = rRequest.rProperties.getLength(); 341 for( sal_Int32 ind = 0; ind < nPropCount; ++ind ) 342 { 343 rtl::OUString tmp = rRequest.rProperties[ind].Name; 344 if( rRequest.rProperties[ind].Name.equals( 345 ::rtl::OUString::createFromAscii("FilterName")) ) 346 { 347 rRequest.rProperties[ind].Value >>= aFilterName; 348 break; 349 } 350 } 351 352 uno::Sequence < beans::PropertyValue > aProps; 353 if ( xFilterCFG->getByName( aFilterName ) >>= aProps ) 354 { 355 sal_Int32 nPropertyCount = aProps.getLength(); 356 for( sal_Int32 nProperty=0; 357 nProperty < nPropertyCount; 358 ++nProperty ) 359 if( aProps[nProperty].Name.equals( 360 ::rtl::OUString::createFromAscii("UIComponent")) ) 361 { 362 ::rtl::OUString aServiceName; 363 aProps[nProperty].Value >>= aServiceName; 364 if( aServiceName.getLength() ) 365 { 366 uno::Reference< 367 ui::dialogs::XExecutableDialog > xFilterDialog( 368 xServiceFactory->createInstance( 369 aServiceName ), 370 uno::UNO_QUERY ); 371 uno::Reference< beans::XPropertyAccess > 372 xFilterProperties( xFilterDialog, 373 uno::UNO_QUERY ); 374 375 if( xFilterDialog.is() && xFilterProperties.is() ) 376 { 377 uno::Reference< 378 document::XImporter > xImporter( 379 xFilterDialog, uno::UNO_QUERY ); 380 if( xImporter.is() ) 381 xImporter->setTargetDocument( 382 uno::Reference< lang::XComponent >( 383 rRequest.rModel, uno::UNO_QUERY ) ); 384 385 xFilterProperties->setPropertyValues( 386 rRequest.rProperties ); 387 388 if( xFilterDialog->execute() ) 389 { 390 xFilterOptions->setFilterOptions( 391 xFilterProperties->getPropertyValues() ); 392 xFilterOptions->select(); 393 return; 394 } 395 } 396 } 397 break; 398 } 399 } 400 } 401 catch( container::NoSuchElementException& ) 402 { 403 // the filter name is unknown 404 } 405 catch( uno::Exception& ) 406 { 407 } 408 } 409 410 xAbort->select(); 411 } 412 413 } // namespace 414 415 bool 416 UUIInteractionHelper::handleNoSuchFilterRequest( 417 uno::Reference< task::XInteractionRequest > const & rRequest) 418 SAL_THROW((uno::RuntimeException)) 419 { 420 uno::Any aAnyRequest(rRequest->getRequest()); 421 422 document::NoSuchFilterRequest aNoSuchFilterRequest; 423 if (aAnyRequest >>= aNoSuchFilterRequest) 424 { 425 handleNoSuchFilterRequest_(getParentProperty(), 426 m_xServiceFactory, 427 aNoSuchFilterRequest, 428 rRequest->getContinuations()); 429 return true; 430 } 431 return false; 432 } 433 434 bool 435 UUIInteractionHelper::handleAmbigousFilterRequest( 436 uno::Reference< task::XInteractionRequest > const & rRequest) 437 SAL_THROW((uno::RuntimeException)) 438 { 439 uno::Any aAnyRequest(rRequest->getRequest()); 440 441 document::AmbigousFilterRequest aAmbigousFilterRequest; 442 if (aAnyRequest >>= aAmbigousFilterRequest) 443 { 444 handleAmbigousFilterRequest_(getParentProperty(), 445 m_xServiceFactory, 446 aAmbigousFilterRequest, 447 rRequest->getContinuations()); 448 return true; 449 } 450 return false; 451 } 452 453 bool 454 UUIInteractionHelper::handleFilterOptionsRequest( 455 uno::Reference< task::XInteractionRequest > const & rRequest) 456 SAL_THROW((uno::RuntimeException)) 457 { 458 uno::Any aAnyRequest(rRequest->getRequest()); 459 460 document::FilterOptionsRequest aFilterOptionsRequest; 461 if (aAnyRequest >>= aFilterOptionsRequest) 462 { 463 handleFilterOptionsRequest_(m_xServiceFactory, 464 aFilterOptionsRequest, 465 rRequest->getContinuations()); 466 return true; 467 } 468 return false; 469 } 470 471 472