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