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#ifndef CHROME_BROWSER_UI_VIEWS_SELECT_FILE_DIALOG_EXTENSION_H_
6#define CHROME_BROWSER_UI_VIEWS_SELECT_FILE_DIALOG_EXTENSION_H_
7
8#include <vector>
9
10#include "base/compiler_specific.h"
11#include "base/memory/ref_counted.h"
12#include "chrome/browser/ui/views/extensions/extension_dialog_observer.h"
13#include "ui/gfx/native_widget_types.h"  // gfx::NativeWindow
14#include "ui/shell_dialogs/select_file_dialog.h"
15
16class ExtensionDialog;
17class Profile;
18
19namespace content {
20class RenderViewHost;
21class WebContents;
22}
23
24namespace ui {
25struct SelectedFileInfo;
26class SelectFilePolicy;
27}
28
29// Shows a dialog box for selecting a file or a folder, using the
30// file manager extension implementation.
31class SelectFileDialogExtension
32    : public ui::SelectFileDialog,
33      public ExtensionDialogObserver {
34 public:
35  // Opaque ID type for identifying the tab spawned each dialog, unique for
36  // every WebContents.
37  typedef const void* RoutingID;
38  static RoutingID GetRoutingIDFromWebContents(
39      const content::WebContents* web_contents);
40
41  static SelectFileDialogExtension* Create(
42      ui::SelectFileDialog::Listener* listener,
43      ui::SelectFilePolicy* policy);
44
45  // BaseShellDialog implementation.
46  virtual bool IsRunning(gfx::NativeWindow owner_window) const OVERRIDE;
47  virtual void ListenerDestroyed() OVERRIDE;
48
49  // ExtensionDialog::Observer implementation.
50  virtual void ExtensionDialogClosing(ExtensionDialog* dialog) OVERRIDE;
51  virtual void ExtensionTerminated(ExtensionDialog* dialog) OVERRIDE;
52
53  // Routes callback to appropriate SelectFileDialog::Listener based on the
54  // owning |web_contents|.
55  static void OnFileSelected(RoutingID routing_id,
56                             const ui::SelectedFileInfo& file,
57                             int index);
58  static void OnMultiFilesSelected(
59      RoutingID routing_id,
60      const std::vector<ui::SelectedFileInfo>& files);
61  static void OnFileSelectionCanceled(RoutingID routing_id);
62
63  // For testing, so we can inject JavaScript into the contained view.
64  content::RenderViewHost* GetRenderViewHost();
65
66 protected:
67  // SelectFileDialog implementation.
68  virtual void SelectFileImpl(
69      Type type,
70      const base::string16& title,
71      const base::FilePath& default_path,
72      const FileTypeInfo* file_types,
73      int file_type_index,
74      const base::FilePath::StringType& default_extension,
75      gfx::NativeWindow owning_window,
76      void* params) OVERRIDE;
77
78 private:
79  friend class SelectFileDialogExtensionBrowserTest;
80  friend class SelectFileDialogExtensionTest;
81
82  // Object is ref-counted, use Create().
83  explicit SelectFileDialogExtension(SelectFileDialog::Listener* listener,
84                                     ui::SelectFilePolicy* policy);
85  virtual ~SelectFileDialogExtension();
86
87  // Invokes the appropriate file selection callback on our listener.
88  void NotifyListener();
89
90  // Adds this to the list of pending dialogs, used for testing.
91  void AddPending(RoutingID routing_id);
92
93  // Check if the list of pending dialogs contains dialog for |routing_id|.
94  static bool PendingExists(RoutingID routing_id);
95
96  // Returns true if the dialog has multiple file type choices.
97  virtual bool HasMultipleFileTypeChoicesImpl() OVERRIDE;
98
99  bool has_multiple_file_type_choices_;
100
101  // Host for the extension that implements this dialog.
102  scoped_refptr<ExtensionDialog> extension_dialog_;
103
104  // ID of the tab that spawned this dialog, used to route callbacks.
105  RoutingID routing_id_;
106
107  // Pointer to the profile the dialog is running in.
108  Profile* profile_;
109
110  // The window that created the dialog.
111  gfx::NativeWindow owner_window_;
112
113  // We defer the callback into SelectFileDialog::Listener until the window
114  // closes, to match the semantics of file selection on Windows and Mac.
115  // These are the data passed to the listener.
116  enum SelectionType {
117    CANCEL = 0,
118    SINGLE_FILE,
119    MULTIPLE_FILES
120  };
121  SelectionType selection_type_;
122  std::vector<ui::SelectedFileInfo> selection_files_;
123  int selection_index_;
124  void* params_;
125
126  DISALLOW_COPY_AND_ASSIGN(SelectFileDialogExtension);
127};
128
129#endif  // CHROME_BROWSER_UI_VIEWS_SELECT_FILE_DIALOG_EXTENSION_H_
130