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