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 <sal/config.h> 21 22 #include "VistaFilePicker.hxx" 23 24 #include "WinImplHelper.hxx" 25 #include "shared.hxx" 26 27 #include <com/sun/star/awt/XWindow.hpp> 28 #include <com/sun/star/lang/DisposedException.hpp> 29 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp> 30 #include <com/sun/star/ui/dialogs/XFilePickerNotifier.hpp> 31 #include <com/sun/star/ui/dialogs/XFilePickerListener.hpp> 32 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> 33 34 #include <cppuhelper/interfacecontainer.h> 35 #include <cppuhelper/supportsservice.hxx> 36 #include <comphelper/processfactory.hxx> 37 #include <osl/file.hxx> 38 #include <officecfg/Office/Common.hxx> 39 40 #include <shlobj.h> 41 42 namespace fpicker{ 43 namespace win32{ 44 namespace vista{ 45 46 VistaFilePicker::VistaFilePicker(bool bFolderPicker) 47 : TVistaFilePickerBase (m_aMutex ) 48 , m_bInitialized (false ) 49 , m_bFolderPicker (bFolderPicker ) 50 { 51 } 52 53 VistaFilePicker::~VistaFilePicker() 54 { 55 } 56 57 void SAL_CALL VistaFilePicker::addFilePickerListener(const css::uno::Reference< css::ui::dialogs::XFilePickerListener >& xListener) 58 { 59 Request rRequest; 60 rRequest.setRequest (VistaFilePickerImpl::E_ADD_PICKER_LISTENER); 61 rRequest.setArgument(PROP_PICKER_LISTENER, xListener); 62 63 m_rDialog.doRequest(rRequest); 64 } 65 66 void SAL_CALL VistaFilePicker::removeFilePickerListener(const css::uno::Reference< css::ui::dialogs::XFilePickerListener >& xListener ) 67 { 68 Request rRequest; 69 rRequest.setRequest (VistaFilePickerImpl::E_REMOVE_PICKER_LISTENER); 70 rRequest.setArgument(PROP_PICKER_LISTENER, xListener); 71 72 m_rDialog.doRequest(rRequest); 73 } 74 75 void VistaFilePicker::disposing(const css::lang::EventObject& /*aEvent*/) 76 { 77 } 78 79 void SAL_CALL VistaFilePicker::setMultiSelectionMode(sal_Bool bMode) 80 { 81 ensureInit(); 82 83 Request rRequest; 84 rRequest.setRequest (VistaFilePickerImpl::E_SET_MULTISELECTION_MODE); 85 rRequest.setArgument(PROP_MULTISELECTION_MODE, bMode); 86 87 m_rDialog.doRequest(rRequest); 88 } 89 90 void SAL_CALL VistaFilePicker::setTitle(const OUString& sTitle) 91 { 92 ensureInit(); 93 94 Request rRequest; 95 rRequest.setRequest (VistaFilePickerImpl::E_SET_TITLE); 96 rRequest.setArgument(PROP_TITLE, sTitle); 97 98 m_rDialog.doRequest(rRequest); 99 } 100 101 void SAL_CALL VistaFilePicker::appendFilter(const OUString& sTitle , 102 const OUString& sFilter) 103 { 104 Request rRequest; 105 rRequest.setRequest (VistaFilePickerImpl::E_APPEND_FILTER); 106 rRequest.setArgument(PROP_FILTER_TITLE, sTitle ); 107 rRequest.setArgument(PROP_FILTER_VALUE, sFilter); 108 109 m_rDialog.doRequest(rRequest); 110 } 111 112 void SAL_CALL VistaFilePicker::setCurrentFilter(const OUString& sTitle) 113 { 114 Request rRequest; 115 rRequest.setRequest (VistaFilePickerImpl::E_SET_CURRENT_FILTER); 116 rRequest.setArgument(PROP_FILTER_TITLE, sTitle); 117 118 m_rDialog.doRequest(rRequest); 119 } 120 121 OUString SAL_CALL VistaFilePicker::getCurrentFilter() 122 { 123 Request rRequest; 124 rRequest.setRequest (VistaFilePickerImpl::E_GET_CURRENT_FILTER); 125 126 m_rDialog.doRequest(rRequest); 127 128 const OUString sTitle = rRequest.getArgumentOrDefault(PROP_FILTER_TITLE, OUString()); 129 return sTitle; 130 } 131 132 void SAL_CALL VistaFilePicker::appendFilterGroup(const OUString& /*sGroupTitle*/, 133 const css::uno::Sequence< css::beans::StringPair >& rFilters ) 134 { 135 Request rRequest; 136 rRequest.setRequest (VistaFilePickerImpl::E_APPEND_FILTERGROUP); 137 rRequest.setArgument(PROP_FILTER_GROUP, rFilters); 138 139 m_rDialog.doRequest(rRequest); 140 } 141 142 void SAL_CALL VistaFilePicker::setDefaultName(const OUString& sName ) 143 { 144 ensureInit(); 145 146 Request rRequest; 147 rRequest.setRequest (VistaFilePickerImpl::E_SET_DEFAULT_NAME); 148 rRequest.setArgument(PROP_FILENAME, sName); 149 150 m_rDialog.doRequest(rRequest); 151 } 152 153 void SAL_CALL VistaFilePicker::setDisplayDirectory(const OUString& sDirectory) 154 { 155 ensureInit(); 156 157 Request rRequest; 158 rRequest.setRequest (VistaFilePickerImpl::E_SET_DIRECTORY); 159 rRequest.setArgument(PROP_DIRECTORY, sDirectory); 160 161 m_rDialog.doRequest(rRequest); 162 } 163 164 OUString SAL_CALL VistaFilePicker::getDisplayDirectory() 165 { 166 ensureInit(); 167 168 Request rRequest; 169 rRequest.setRequest (VistaFilePickerImpl::E_GET_DIRECTORY); 170 m_rDialog.doRequest(rRequest); 171 const OUString sDirectory = rRequest.getArgumentOrDefault(PROP_DIRECTORY, OUString()); 172 173 return sDirectory; 174 } 175 176 // @deprecated can't be supported any longer ... see IDL description for further details 177 css::uno::Sequence< OUString > SAL_CALL VistaFilePicker::getFiles() 178 { 179 css::uno::Sequence< OUString > lFiles = getSelectedFiles(); 180 // multiselection doesn't really work 181 // so just retrieve the first url 182 if (lFiles.getLength() > 1) 183 lFiles.realloc(1); 184 m_lLastFiles = lFiles; 185 return lFiles; 186 } 187 188 css::uno::Sequence< OUString > SAL_CALL VistaFilePicker::getSelectedFiles() 189 { 190 Request rRequest; 191 rRequest.setRequest (VistaFilePickerImpl::E_GET_SELECTED_FILES); 192 193 m_rDialog.doRequest(rRequest); 194 195 const css::uno::Sequence< OUString > lFiles = rRequest.getArgumentOrDefault(PROP_SELECTED_FILES, css::uno::Sequence< OUString >()); 196 m_lLastFiles = lFiles; 197 return lFiles; 198 } 199 200 void VistaFilePicker::ensureInit() 201 { 202 if ( !m_bInitialized ) 203 { 204 if (m_bFolderPicker) 205 { 206 Request rRequest; 207 rRequest.setRequest (VistaFilePickerImpl::E_CREATE_FOLDER_PICKER); 208 m_rDialog.doRequest(rRequest); 209 m_bInitialized = true; 210 } 211 else 212 { 213 initialize( { css::uno::Any(css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE) }); 214 } 215 } 216 } 217 218 ::sal_Int16 SAL_CALL VistaFilePicker::execute() 219 { 220 ensureInit(); 221 222 Request rRequest; 223 rRequest.setRequest (VistaFilePickerImpl::E_SHOW_DIALOG_MODAL); 224 225 // show a modal window 226 m_rDialog.doRequest(rRequest); 227 228 const bool bOK = rRequest.getArgumentOrDefault(PROP_DIALOG_SHOW_RESULT, false ); 229 m_lLastFiles = rRequest.getArgumentOrDefault(PROP_SELECTED_FILES , css::uno::Sequence< OUString >()); 230 231 ::sal_Int16 nResult = css::ui::dialogs::ExecutableDialogResults::CANCEL; 232 if (bOK) 233 nResult = css::ui::dialogs::ExecutableDialogResults::OK; 234 return nResult; 235 } 236 237 // XFilePicker 238 239 void SAL_CALL VistaFilePicker::setValue( ::sal_Int16 nControlId , 240 ::sal_Int16 nControlAction, 241 const css::uno::Any& aValue ) 242 { 243 Request rRequest; 244 rRequest.setRequest (VistaFilePickerImpl::E_SET_CONTROL_VALUE); 245 rRequest.setArgument(PROP_CONTROL_ID , nControlId ); 246 rRequest.setArgument(PROP_CONTROL_ACTION, nControlAction); 247 rRequest.setArgument(PROP_CONTROL_VALUE , aValue ); 248 249 m_rDialog.doRequest(rRequest); 250 } 251 252 css::uno::Any SAL_CALL VistaFilePicker::getValue(::sal_Int16 nControlId , 253 ::sal_Int16 nControlAction) 254 { 255 Request rRequest; 256 rRequest.setRequest (VistaFilePickerImpl::E_GET_CONTROL_VALUE); 257 rRequest.setArgument(PROP_CONTROL_ID , nControlId ); 258 rRequest.setArgument(PROP_CONTROL_ACTION, nControlAction); 259 260 m_rDialog.doRequest(rRequest); 261 return rRequest.getValue(PROP_CONTROL_VALUE); 262 } 263 264 void SAL_CALL VistaFilePicker::enableControl(::sal_Int16 nControlId, 265 sal_Bool bEnable ) 266 { 267 Request rRequest; 268 rRequest.setRequest (VistaFilePickerImpl::E_ENABLE_CONTROL); 269 rRequest.setArgument(PROP_CONTROL_ID , nControlId); 270 rRequest.setArgument(PROP_CONTROL_ENABLE, bEnable ); 271 272 m_rDialog.doRequest(rRequest); 273 } 274 275 void SAL_CALL VistaFilePicker::setLabel( ::sal_Int16 nControlId, 276 const OUString& sLabel ) 277 { 278 Request rRequest; 279 rRequest.setRequest (VistaFilePickerImpl::E_SET_CONTROL_LABEL); 280 rRequest.setArgument(PROP_CONTROL_ID , nControlId); 281 rRequest.setArgument(PROP_CONTROL_LABEL, sLabel ); 282 283 m_rDialog.doRequest(rRequest); 284 } 285 286 OUString SAL_CALL VistaFilePicker::getLabel(::sal_Int16 nControlId) 287 { 288 Request rRequest; 289 rRequest.setRequest (VistaFilePickerImpl::E_GET_CONTROL_LABEL); 290 rRequest.setArgument(PROP_CONTROL_ID, nControlId); 291 292 m_rDialog.doRequest(rRequest); 293 const OUString sLabel = rRequest.getArgumentOrDefault(PROP_CONTROL_LABEL, OUString()); 294 return sLabel; 295 } 296 297 css::uno::Sequence< ::sal_Int16 > SAL_CALL VistaFilePicker::getSupportedImageFormats() 298 { 299 return css::uno::Sequence< sal_Int16 >(); 300 } 301 302 sal_Int32 SAL_CALL VistaFilePicker::getTargetColorDepth() 303 { 304 return 0; 305 } 306 307 sal_Int32 SAL_CALL VistaFilePicker::getAvailableWidth() 308 { 309 return 0; 310 } 311 312 sal_Int32 SAL_CALL VistaFilePicker::getAvailableHeight() 313 { 314 return 0; 315 } 316 317 void SAL_CALL VistaFilePicker::setImage( sal_Int16 /*nImageFormat*/, 318 const css::uno::Any& /*aImage */) 319 { 320 } 321 322 sal_Bool SAL_CALL VistaFilePicker::setShowState(sal_Bool /*bShowState*/) 323 { 324 return false; 325 } 326 327 sal_Bool SAL_CALL VistaFilePicker::getShowState() 328 { 329 return false; 330 } 331 332 void SAL_CALL VistaFilePicker::initialize(const css::uno::Sequence< css::uno::Any >& lArguments) 333 { 334 if (lArguments.getLength() < 1) 335 throw css::lang::IllegalArgumentException( 336 "XInitialization::initialize() called without arguments.", 337 static_cast< css::ui::dialogs::XFilePicker2* >( this ), 338 1); 339 340 sal_Int32 nTemplate = -1; 341 lArguments[0] >>= nTemplate; 342 343 bool bFileOpenDialog = true; 344 ::sal_Int32 nFeatures = 0; 345 346 switch(nTemplate) 347 { 348 case css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE : 349 { 350 bFileOpenDialog = true; 351 } 352 break; 353 354 case css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE : 355 { 356 bFileOpenDialog = false; 357 } 358 break; 359 360 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD : 361 { 362 bFileOpenDialog = false; 363 nFeatures |= FEATURE_AUTOEXTENSION; 364 nFeatures |= FEATURE_PASSWORD; 365 nFeatures |= FEATURE_GPGPASSWORD; 366 } 367 break; 368 369 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS : 370 { 371 bFileOpenDialog = false; 372 nFeatures |= FEATURE_AUTOEXTENSION; 373 nFeatures |= FEATURE_PASSWORD; 374 nFeatures |= FEATURE_FILTEROPTIONS; 375 nFeatures |= FEATURE_GPGPASSWORD; 376 } 377 break; 378 379 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION : 380 { 381 bFileOpenDialog = false; 382 nFeatures |= FEATURE_AUTOEXTENSION; 383 nFeatures |= FEATURE_SELECTION; 384 } 385 break; 386 387 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE : 388 { 389 bFileOpenDialog = false; 390 nFeatures |= FEATURE_AUTOEXTENSION; 391 nFeatures |= FEATURE_TEMPLATE; 392 } 393 break; 394 395 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE : 396 { 397 bFileOpenDialog = true; 398 nFeatures |= FEATURE_LINK; 399 nFeatures |= FEATURE_PREVIEW; 400 nFeatures |= FEATURE_IMAGETEMPLATE; 401 } 402 break; 403 404 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_ANCHOR : 405 { 406 bFileOpenDialog = true; 407 nFeatures |= FEATURE_LINK; 408 nFeatures |= FEATURE_PREVIEW; 409 nFeatures |= FEATURE_IMAGEANCHOR; 410 } 411 break; 412 413 case css::ui::dialogs::TemplateDescription::FILEOPEN_PLAY : 414 { 415 bFileOpenDialog = true; 416 nFeatures |= FEATURE_PLAY; 417 } 418 break; 419 420 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PLAY : 421 { 422 bFileOpenDialog = true; 423 nFeatures |= FEATURE_LINK; 424 nFeatures |= FEATURE_PLAY; 425 } 426 break; 427 428 case css::ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION : 429 { 430 bFileOpenDialog = true; 431 nFeatures |= FEATURE_READONLY; 432 nFeatures |= FEATURE_VERSION; 433 } 434 break; 435 436 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW : 437 { 438 bFileOpenDialog = true; 439 nFeatures |= FEATURE_LINK; 440 nFeatures |= FEATURE_PREVIEW; 441 } 442 break; 443 444 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION : 445 { 446 bFileOpenDialog = false; 447 nFeatures |= FEATURE_AUTOEXTENSION; 448 } 449 break; 450 451 case css::ui::dialogs::TemplateDescription::FILEOPEN_PREVIEW : 452 { 453 bFileOpenDialog = true; 454 nFeatures |= FEATURE_PREVIEW; 455 } 456 break; 457 } 458 css::uno::Reference<css::awt::XWindow> xParentWindow; 459 if(lArguments.getLength() > 1) 460 { 461 lArguments[1] >>= xParentWindow; 462 } 463 Request rRequest; 464 if (bFileOpenDialog) 465 rRequest.setRequest (VistaFilePickerImpl::E_CREATE_OPEN_DIALOG); 466 else 467 rRequest.setRequest (VistaFilePickerImpl::E_CREATE_SAVE_DIALOG); 468 rRequest.setArgument(PROP_FEATURES, nFeatures); 469 rRequest.setArgument(PROP_TEMPLATE_DESCR, nTemplate); 470 if(xParentWindow.is()) 471 rRequest.setArgument(PROP_PARENT_WINDOW, xParentWindow); 472 m_rDialog.doRequest(rRequest); 473 474 m_bInitialized = true; 475 } 476 477 void SAL_CALL VistaFilePicker::cancel() 478 { 479 } 480 481 OUString SAL_CALL VistaFilePicker::getDirectory() 482 { 483 ensureInit(); 484 css::uno::Sequence< OUString > aFileSeq = getSelectedFiles(); 485 assert(aFileSeq.getLength() <= 1); 486 return aFileSeq.getLength() ? aFileSeq[0] : OUString(); 487 } 488 489 void SAL_CALL VistaFilePicker::setDescription( const OUString& aDescription ) 490 { 491 setTitle(aDescription); 492 } 493 494 // XServiceInfo 495 496 OUString SAL_CALL VistaFilePicker::getImplementationName() 497 { 498 if (m_bFolderPicker) 499 return "com.sun.star.ui.dialogs.Win32FolderPicker"; 500 else 501 return "com.sun.star.ui.dialogs.Win32FilePicker"; 502 } 503 504 sal_Bool SAL_CALL VistaFilePicker::supportsService(const OUString& sServiceName) 505 { 506 return cppu::supportsService(this, sServiceName); 507 } 508 509 css::uno::Sequence< OUString > SAL_CALL VistaFilePicker::getSupportedServiceNames() 510 { 511 return { 512 "com.sun.star.ui.dialogs.FilePicker", 513 "com.sun.star.ui.dialogs.SystemFilePicker", 514 "com.sun.star.ui.dialogs.SystemFolderPicker" }; 515 } 516 517 } // namespace vista 518 } // namespace win32 519 } // namespace fpicker 520 521 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* 522 fpicker_win32_FilePicker_get_implementation( 523 css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const&) 524 { 525 return cppu::acquire(new ::fpicker::win32::vista::VistaFilePicker(false)); 526 } 527 528 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* 529 fpicker_win32_FolderPicker_get_implementation( 530 css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const&) 531 { 532 return cppu::acquire(new ::fpicker::win32::vista::VistaFilePicker(true)); 533 } 534 535 536 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 537
