Home | History | Annotate | Download | only in shell_dialogs
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ui/shell_dialogs/select_file_dialog.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/logging.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "build/build_config.h"
     11 #include "ui/base/l10n/l10n_util.h"
     12 #include "ui/shell_dialogs/select_file_dialog_factory.h"
     13 #include "ui/shell_dialogs/select_file_policy.h"
     14 #include "ui/shell_dialogs/selected_file_info.h"
     15 #include "ui/shell_dialogs/shell_dialogs_delegate.h"
     16 
     17 #if defined(OS_WIN)
     18 #include "ui/shell_dialogs/select_file_dialog_win.h"
     19 #elif defined(OS_MACOSX)
     20 #include "ui/shell_dialogs/select_file_dialog_mac.h"
     21 #elif defined(TOOLKIT_GTK)
     22 #include "ui/shell_dialogs/gtk/select_file_dialog_impl.h"
     23 #elif defined(OS_ANDROID)
     24 #include "ui/shell_dialogs/select_file_dialog_android.h"
     25 #elif defined(USE_AURA) && !defined(USE_ASH) && defined(OS_LINUX)
     26 #include "ui/shell_dialogs/linux_shell_dialog.h"
     27 #endif
     28 
     29 namespace {
     30 
     31 // Optional dialog factory. Leaked.
     32 ui::SelectFileDialogFactory* dialog_factory_ = NULL;
     33 
     34 // The global shell dialogs delegate.
     35 ui::ShellDialogsDelegate* g_shell_dialogs_delegate_ = NULL;
     36 
     37 }  // namespace
     38 
     39 namespace ui {
     40 
     41 SelectFileDialog::FileTypeInfo::FileTypeInfo()
     42     : include_all_files(false),
     43       support_drive(false) {}
     44 
     45 SelectFileDialog::FileTypeInfo::~FileTypeInfo() {}
     46 
     47 void SelectFileDialog::Listener::FileSelectedWithExtraInfo(
     48     const ui::SelectedFileInfo& file,
     49     int index,
     50     void* params) {
     51   // Most of the dialogs need actual local path, so default to it.
     52   FileSelected(file.local_path, index, params);
     53 }
     54 
     55 void SelectFileDialog::Listener::MultiFilesSelectedWithExtraInfo(
     56     const std::vector<ui::SelectedFileInfo>& files,
     57     void* params) {
     58   std::vector<base::FilePath> file_paths;
     59   for (size_t i = 0; i < files.size(); ++i)
     60     file_paths.push_back(files[i].local_path);
     61 
     62   MultiFilesSelected(file_paths, params);
     63 }
     64 
     65 // static
     66 void SelectFileDialog::SetFactory(ui::SelectFileDialogFactory* factory) {
     67   delete dialog_factory_;
     68   dialog_factory_ = factory;
     69 }
     70 
     71 // static
     72 scoped_refptr<SelectFileDialog> SelectFileDialog::Create(
     73     Listener* listener,
     74     ui::SelectFilePolicy* policy) {
     75   if (dialog_factory_) {
     76     SelectFileDialog* dialog = dialog_factory_->Create(listener, policy);
     77     if (dialog)
     78       return dialog;
     79   }
     80 
     81 #if defined(USE_AURA) && !defined(USE_ASH) && defined(OS_LINUX)
     82   const ui::LinuxShellDialog* shell_dialogs = ui::LinuxShellDialog::instance();
     83   if (shell_dialogs)
     84     return shell_dialogs->CreateSelectFileDialog(listener, policy);
     85 #endif
     86 
     87 #if defined(OS_WIN)
     88   // TODO(ananta)
     89   // Fix this for Chrome ASH on Windows.
     90   return CreateWinSelectFileDialog(listener, policy);
     91 #elif defined(OS_MACOSX) && !defined(USE_AURA)
     92   return CreateMacSelectFileDialog(listener, policy);
     93 #elif defined(TOOLKIT_GTK)
     94   return CreateLinuxSelectFileDialog(listener, policy);
     95 #elif defined(OS_ANDROID)
     96   return CreateAndroidSelectFileDialog(listener, policy);
     97 #endif
     98 
     99   return NULL;
    100 }
    101 
    102 void SelectFileDialog::SelectFile(
    103     Type type,
    104     const base::string16& title,
    105     const base::FilePath& default_path,
    106     const FileTypeInfo* file_types,
    107     int file_type_index,
    108     const base::FilePath::StringType& default_extension,
    109     gfx::NativeWindow owning_window,
    110     void* params) {
    111   DCHECK(listener_);
    112 
    113   if (select_file_policy_.get() &&
    114       !select_file_policy_->CanOpenSelectFileDialog()) {
    115     select_file_policy_->SelectFileDenied();
    116 
    117     // Inform the listener that no file was selected.
    118     // Post a task rather than calling FileSelectionCanceled directly to ensure
    119     // that the listener is called asynchronously.
    120     base::MessageLoop::current()->PostTask(
    121         FROM_HERE,
    122         base::Bind(&SelectFileDialog::CancelFileSelection, this, params));
    123     return;
    124   }
    125 
    126   // Call the platform specific implementation of the file selection dialog.
    127   SelectFileImpl(type, title, default_path, file_types, file_type_index,
    128                  default_extension, owning_window, params);
    129 }
    130 
    131 bool SelectFileDialog::HasMultipleFileTypeChoices() {
    132   return HasMultipleFileTypeChoicesImpl();
    133 }
    134 
    135 // static
    136 void SelectFileDialog::SetShellDialogsDelegate(ShellDialogsDelegate* delegate) {
    137   g_shell_dialogs_delegate_ = delegate;
    138 }
    139 
    140 SelectFileDialog::SelectFileDialog(Listener* listener,
    141                                    ui::SelectFilePolicy* policy)
    142     : listener_(listener),
    143       select_file_policy_(policy) {
    144   DCHECK(listener_);
    145 }
    146 
    147 SelectFileDialog::~SelectFileDialog() {}
    148 
    149 void SelectFileDialog::CancelFileSelection(void* params) {
    150   if (listener_)
    151     listener_->FileSelectionCanceled(params);
    152 }
    153 
    154 ShellDialogsDelegate* SelectFileDialog::GetShellDialogsDelegate() {
    155   return g_shell_dialogs_delegate_;
    156 }
    157 
    158 }  // namespace ui
    159