// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_UI_VIEWS_SELECT_FILE_DIALOG_EXTENSION_H_ #define CHROME_BROWSER_UI_VIEWS_SELECT_FILE_DIALOG_EXTENSION_H_ #include #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "chrome/browser/ui/views/extensions/extension_dialog_observer.h" #include "ui/gfx/native_widget_types.h" // gfx::NativeWindow #include "ui/shell_dialogs/select_file_dialog.h" class ExtensionDialog; class Profile; namespace content { class RenderViewHost; class WebContents; } namespace ui { struct SelectedFileInfo; class SelectFilePolicy; } // Shows a dialog box for selecting a file or a folder, using the // file manager extension implementation. class SelectFileDialogExtension : public ui::SelectFileDialog, public ExtensionDialogObserver { public: // Opaque ID type for identifying the tab spawned each dialog, unique for // every WebContents. typedef const void* RoutingID; static RoutingID GetRoutingIDFromWebContents( const content::WebContents* web_contents); static SelectFileDialogExtension* Create( ui::SelectFileDialog::Listener* listener, ui::SelectFilePolicy* policy); // BaseShellDialog implementation. bool IsRunning(gfx::NativeWindow owner_window) const override; void ListenerDestroyed() override; // ExtensionDialog::Observer implementation. void ExtensionDialogClosing(ExtensionDialog* dialog) override; void ExtensionTerminated(ExtensionDialog* dialog) override; // Routes callback to appropriate SelectFileDialog::Listener based on the // owning |web_contents|. static void OnFileSelected(RoutingID routing_id, const ui::SelectedFileInfo& file, int index); static void OnMultiFilesSelected( RoutingID routing_id, const std::vector& files); static void OnFileSelectionCanceled(RoutingID routing_id); // For testing, so we can inject JavaScript into the contained view. content::RenderViewHost* GetRenderViewHost(); protected: // SelectFileDialog implementation. void SelectFileImpl(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) override; private: friend class SelectFileDialogExtensionBrowserTest; friend class SelectFileDialogExtensionTest; // Object is ref-counted, use Create(). explicit SelectFileDialogExtension(SelectFileDialog::Listener* listener, ui::SelectFilePolicy* policy); ~SelectFileDialogExtension() override; // Invokes the appropriate file selection callback on our listener. void NotifyListener(); // Adds this to the list of pending dialogs, used for testing. void AddPending(RoutingID routing_id); // Check if the list of pending dialogs contains dialog for |routing_id|. static bool PendingExists(RoutingID routing_id); // Returns true if the dialog has multiple file type choices. bool HasMultipleFileTypeChoicesImpl() override; bool has_multiple_file_type_choices_; // Host for the extension that implements this dialog. scoped_refptr extension_dialog_; // ID of the tab that spawned this dialog, used to route callbacks. RoutingID routing_id_; // Pointer to the profile the dialog is running in. Profile* profile_; // The window that created the dialog. gfx::NativeWindow owner_window_; // We defer the callback into SelectFileDialog::Listener until the window // closes, to match the semantics of file selection on Windows and Mac. // These are the data passed to the listener. enum SelectionType { CANCEL = 0, SINGLE_FILE, MULTIPLE_FILES }; SelectionType selection_type_; std::vector selection_files_; int selection_index_; void* params_; DISALLOW_COPY_AND_ASSIGN(SelectFileDialogExtension); }; #endif // CHROME_BROWSER_UI_VIEWS_SELECT_FILE_DIALOG_EXTENSION_H_