Home | History | Annotate | Download | only in browser
      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:
     50     DirectoryListerDispatchDelegate(FileSelectHelper* parent, int id)
     51         : parent_(parent),
     52           id_(id) {}
     53     ~DirectoryListerDispatchDelegate() {}
     54     virtual void OnListFile(
     55         const net::DirectoryLister::DirectoryListerData& data) {
     56       parent_->OnListFile(id_, data);
     57     }
     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