1 // Copyright 2015 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 UI_GTK_SELECT_FILE_DIALOG_IMPL_GTK_H_
6 #define UI_GTK_SELECT_FILE_DIALOG_IMPL_GTK_H_
7 
8 #include "base/macros.h"
9 #include "ui/base/glib/glib_signal.h"
10 #include "ui/gtk/gtk_util.h"
11 #include "ui/gtk/select_file_dialog_impl.h"
12 
13 namespace gtk {
14 
15 // Implementation of SelectFileDialog that shows a Gtk common dialog for
16 // choosing a file or folder. This acts as a modal dialog.
17 class SelectFileDialogImplGTK : public SelectFileDialogImpl,
18                                 public aura::WindowObserver {
19  public:
20   SelectFileDialogImplGTK(Listener* listener,
21                           std::unique_ptr<ui::SelectFilePolicy> policy);
22 
23  protected:
24   ~SelectFileDialogImplGTK() override;
25 
26   // BaseShellDialog implementation:
27   bool IsRunning(gfx::NativeWindow parent_window) const override;
28 
29   // SelectFileDialog implementation.
30   // |params| is user data we pass back via the Listener interface.
31   void SelectFileImpl(Type type,
32                       const base::string16& title,
33                       const base::FilePath& default_path,
34                       const FileTypeInfo* file_types,
35                       int file_type_index,
36                       const base::FilePath::StringType& default_extension,
37                       gfx::NativeWindow owning_window,
38                       void* params) override;
39 
40  private:
41   friend class FilePicker;
42   bool HasMultipleFileTypeChoicesImpl() override;
43 
44   // Overridden from aura::WindowObserver:
45   void OnWindowDestroying(aura::Window* window) override;
46 
47   // Add the filters from |file_types_| to |chooser|.
48   void AddFilters(GtkFileChooser* chooser);
49 
50   // Notifies the listener that a single file was chosen.
51   void FileSelected(GtkWidget* dialog, const base::FilePath& path);
52 
53   // Notifies the listener that multiple files were chosen.
54   void MultiFilesSelected(GtkWidget* dialog,
55                           const std::vector<base::FilePath>& files);
56 
57   // Notifies the listener that no file was chosen (the action was canceled).
58   // Dialog is passed so we can find that |params| pointer that was passed to
59   // us when we were told to show the dialog.
60   void FileNotSelected(GtkWidget* dialog);
61 
62   GtkWidget* CreateSelectFolderDialog(Type type,
63                                       const std::string& title,
64                                       const base::FilePath& default_path,
65                                       gfx::NativeWindow parent);
66 
67   GtkWidget* CreateFileOpenDialog(const std::string& title,
68                                   const base::FilePath& default_path,
69                                   gfx::NativeWindow parent);
70 
71   GtkWidget* CreateMultiFileOpenDialog(const std::string& title,
72                                        const base::FilePath& default_path,
73                                        gfx::NativeWindow parent);
74 
75   GtkWidget* CreateSaveAsDialog(const std::string& title,
76                                 const base::FilePath& default_path,
77                                 gfx::NativeWindow parent);
78 
79   // Removes and returns the |params| associated with |dialog| from
80   // |params_map_|.
81   void* PopParamsForDialog(GtkWidget* dialog);
82 
83   // Check whether response_id corresponds to the user cancelling/closing the
84   // dialog. Used as a helper for the below callbacks.
85   bool IsCancelResponse(gint response_id);
86 
87   // Common function for OnSelectSingleFileDialogResponse and
88   // OnSelectSingleFolderDialogResponse.
89   void SelectSingleFileHelper(GtkWidget* dialog,
90                               gint response_id,
91                               bool allow_folder);
92 
93   // Common function for CreateFileOpenDialog and CreateMultiFileOpenDialog.
94   GtkWidget* CreateFileOpenHelper(const std::string& title,
95                                   const base::FilePath& default_path,
96                                   gfx::NativeWindow parent);
97 
98   // Callback for when the user responds to a Save As or Open File dialog.
99   CHROMEG_CALLBACK_1(SelectFileDialogImplGTK,
100                      void,
101                      OnSelectSingleFileDialogResponse,
102                      GtkWidget*,
103                      int);
104 
105   // Callback for when the user responds to a Select Folder dialog.
106   CHROMEG_CALLBACK_1(SelectFileDialogImplGTK,
107                      void,
108                      OnSelectSingleFolderDialogResponse,
109                      GtkWidget*,
110                      int);
111 
112   // Callback for when the user responds to a Open Multiple Files dialog.
113   CHROMEG_CALLBACK_1(SelectFileDialogImplGTK,
114                      void,
115                      OnSelectMultiFileDialogResponse,
116                      GtkWidget*,
117                      int);
118 
119   // Callback for when the file chooser gets destroyed.
120   CHROMEG_CALLBACK_0(SelectFileDialogImplGTK,
121                      void,
122                      OnFileChooserDestroy,
123                      GtkWidget*);
124 
125   // Callback for when we update the preview for the selection.
126   CHROMEG_CALLBACK_0(SelectFileDialogImplGTK,
127                      void,
128                      OnUpdatePreview,
129                      GtkWidget*);
130 
131   // A map from dialog windows to the |params| user data associated with them.
132   std::map<GtkWidget*, void*> params_map_;
133 
134   // The GtkImage widget for showing previews of selected images.
135   GtkWidget* preview_;
136 
137   // All our dialogs.
138   std::set<GtkWidget*> dialogs_;
139 
140   // The set of all parent windows for which we are currently running dialogs.
141   std::set<aura::Window*> parents_;
142 
143   DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImplGTK);
144 };
145 
146 }  // namespace gtk
147 
148 #endif  // UI_GTK_SELECT_FILE_DIALOG_IMPL_GTK_H_
149