• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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_FILE_SELECT_HELPER_H_
6 #define CHROME_BROWSER_FILE_SELECT_HELPER_H_
7 #pragma once
8 
9 #include <map>
10 #include <vector>
11 
12 #include "base/compiler_specific.h"
13 #include "chrome/browser/ui/shell_dialogs.h"
14 #include "content/browser/tab_contents/tab_contents_observer.h"
15 #include "content/common/notification_observer.h"
16 #include "content/common/notification_registrar.h"
17 #include "net/base/directory_lister.h"
18 
19 class Profile;
20 class RenderViewHost;
21 struct ViewHostMsg_RunFileChooser_Params;
22 
23 
24 // This class handles file-selection requests coming from WebUI elements
25 // (via the ExtensionHost class). It implements both the initialisation
26 // and listener functions for file-selection dialogs.
27 class FileSelectHelper
28     : public SelectFileDialog::Listener,
29       public NotificationObserver {
30  public:
31   explicit FileSelectHelper(Profile* profile);
32   ~FileSelectHelper();
33 
34   // Show the file chooser dialog.
35   void RunFileChooser(RenderViewHost* render_view_host,
36                       TabContents* tab_contents,
37                       const ViewHostMsg_RunFileChooser_Params& params);
38 
39   // Enumerates all the files in directory.
40   void EnumerateDirectory(int request_id,
41                           RenderViewHost* render_view_host,
42                           const FilePath& path);
43 
44  private:
45   // Utility class which can listen for directory lister events and relay
46   // them to the main object with the correct tracking id.
47   class DirectoryListerDispatchDelegate
48       : public net::DirectoryLister::DirectoryListerDelegate {
49    public:
DirectoryListerDispatchDelegate(FileSelectHelper * parent,int id)50     DirectoryListerDispatchDelegate(FileSelectHelper* parent, int id)
51         : parent_(parent),
52           id_(id) {}
~DirectoryListerDispatchDelegate()53     ~DirectoryListerDispatchDelegate() {}
OnListFile(const net::DirectoryLister::DirectoryListerData & data)54     virtual void OnListFile(
55         const net::DirectoryLister::DirectoryListerData& data) {
56       parent_->OnListFile(id_, data);
57     }
OnListDone(int error)58     virtual void OnListDone(int error) {
59       parent_->OnListDone(id_, error);
60     }
61    private:
62     // This FileSelectHelper owns this object.
63     FileSelectHelper* parent_;
64     int id_;
65 
66     DISALLOW_COPY_AND_ASSIGN(DirectoryListerDispatchDelegate);
67   };
68 
69   // SelectFileDialog::Listener overrides.
70   virtual void FileSelected(
71       const FilePath& path, int index, void* params) OVERRIDE;
72   virtual void MultiFilesSelected(const std::vector<FilePath>& files,
73                                   void* params) OVERRIDE;
74   virtual void FileSelectionCanceled(void* params) OVERRIDE;
75 
76   // NotificationObserver overrides.
77   virtual void Observe(NotificationType type,
78                        const NotificationSource& source,
79                        const NotificationDetails& details) OVERRIDE;
80 
81   // Kicks off a new directory enumeration.
82   void StartNewEnumeration(const FilePath& path,
83                            int request_id,
84                            RenderViewHost* render_view_host);
85 
86   // Callbacks from directory enumeration.
87   virtual void OnListFile(
88       int id,
89       const net::DirectoryLister::DirectoryListerData& data);
90   virtual void OnListDone(int id, int error);
91 
92   // Helper method to get allowed extensions for select file dialog from
93   // the specified accept types as defined in the spec:
94   //   http://whatwg.org/html/number-state.html#attr-input-accept
95   SelectFileDialog::FileTypeInfo* GetFileTypesFromAcceptType(
96       const string16& accept_types);
97 
98   // Profile used to set/retrieve the last used directory.
99   Profile* profile_;
100 
101   // The RenderViewHost for the page showing a file dialog (may only be one
102   // such dialog).
103   RenderViewHost* render_view_host_;
104 
105   // Dialog box used for choosing files to upload from file form fields.
106   scoped_refptr<SelectFileDialog> select_file_dialog_;
107 
108   // The type of file dialog last shown.
109   SelectFileDialog::Type dialog_type_;
110 
111   // Maintain a list of active directory enumerations.  These could come from
112   // the file select dialog or from drag-and-drop of directories, so there could
113   // be more than one going on at a time.
114   struct ActiveDirectoryEnumeration;
115   std::map<int, ActiveDirectoryEnumeration*> directory_enumerations_;
116 
117   // Registrar for notifications regarding our RenderViewHost.
118   NotificationRegistrar notification_registrar_;
119 
120   DISALLOW_COPY_AND_ASSIGN(FileSelectHelper);
121 };
122 
123 class FileSelectObserver : public TabContentsObserver {
124  public:
125   explicit FileSelectObserver(TabContents* tab_contents);
126   ~FileSelectObserver();
127 
128  private:
129   // TabContentsObserver overrides.
130   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
131 
132   // Called when a file selection is to be done.
133   void OnRunFileChooser(const ViewHostMsg_RunFileChooser_Params& params);
134 
135   // Called when a direction enumeration is to be done.
136   void OnEnumerateDirectory(int request_id, const FilePath& path);
137 
138   // FileSelectHelper, lazily created.
139   scoped_ptr<FileSelectHelper> file_select_helper_;
140 
141   DISALLOW_COPY_AND_ASSIGN(FileSelectObserver);
142 };
143 
144 #endif  // CHROME_BROWSER_FILE_SELECT_HELPER_H_
145