summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/select_file_dialog.h
blob: 60824230614d45af7cdc4bd2a5b319586b1c9cdf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
// 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_SELECT_FILE_DIALOG_H_
#define CHROME_BROWSER_UI_SELECT_FILE_DIALOG_H_
#pragma once

#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/callback_forward.h"
#include "base/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
#include "ui/base/dialogs/base_shell_dialog.h"
#include "ui/gfx/native_widget_types.h"

namespace ui {
class SelectFilePolicy;
}

namespace content {
class WebContents;
}

namespace ui {
struct SelectedFileInfo;
}

// This function is declared extern such that it is accessible for unit tests
// in /chrome/browser/ui/views/select_file_dialog_win_unittest.cc
extern std::wstring AppendExtensionIfNeeded(const std::wstring& filename,
                                            const std::wstring& filter_selected,
                                            const std::wstring& suggested_ext);

// Shows a dialog box for selecting a file or a folder.
class SelectFileDialog
    : public base::RefCountedThreadSafe<SelectFileDialog>,
      public ui::BaseShellDialog {
 public:
  enum Type {
    SELECT_NONE,
    SELECT_FOLDER,
    SELECT_SAVEAS_FILE,
    SELECT_OPEN_FILE,
    SELECT_OPEN_MULTI_FILE
  };

  // An interface implemented by a Listener object wishing to know about the
  // the result of the Select File/Folder action. These callbacks must be
  // re-entrant.
  class Listener {
   public:
    // Notifies the Listener that a file/folder selection has been made. The
    // file/folder path is in |path|. |params| is contextual passed to
    // SelectFile. |index| specifies the index of the filter passed to the
    // the initial call to SelectFile.
    virtual void FileSelected(const FilePath& path,
                              int index, void* params) = 0;

    // Similar to FileSelected() but takes SelectedFileInfo instead of
    // FilePath. Used for passing extra information (ex. display name).
    //
    // If not overridden, calls FileSelected() with path from |file|.
    virtual void FileSelectedWithExtraInfo(
        const ui::SelectedFileInfo& file,
        int index,
        void* params);

    // Notifies the Listener that many files have been selected. The
    // files are in |files|. |params| is contextual passed to SelectFile.
    virtual void MultiFilesSelected(
      const std::vector<FilePath>& files, void* params) {}

    // Similar to MultiFilesSelected() but takes SelectedFileInfo instead of
    // FilePath. Used for passing extra information (ex. display name).
    //
    // If not overridden, calls MultiFilesSelected() with paths from |files|.
    virtual void MultiFilesSelectedWithExtraInfo(
      const std::vector<ui::SelectedFileInfo>& files,
      void* params);

    // Notifies the Listener that the file/folder selection was aborted (via
    // the  user canceling or closing the selection dialog box, for example).
    // |params| is contextual passed to SelectFile.
    virtual void FileSelectionCanceled(void* params) {}

   protected:
    virtual ~Listener() {}
  };

  // Creates a dialog box helper. This object is ref-counted, but the returned
  // object will have no reference (refcount is 0). |policy| is an optional
  // class that can prevent showing a dialog.
  static SelectFileDialog* Create(Listener* listener,
                                  ui::SelectFilePolicy* policy);

  // Holds information about allowed extensions on a file save dialog.
  // |extensions| is a list of allowed extensions. For example, it might be
  //   { { "htm", "html" }, { "txt" } }. Only pass more than one extension
  //   in the inner vector if the extensions are equivalent. Do NOT include
  //   leading periods.
  // |extension_description_overrides| overrides the system descriptions of the
  //   specified extensions. Entries correspond to |extensions|; if left blank
  //   the system descriptions will be used.
  // |include_all_files| specifies whether there will be a filter added for all
  //   files (i.e. *.*).
  struct FileTypeInfo {
    FileTypeInfo();
    ~FileTypeInfo();

    std::vector<std::vector<FilePath::StringType> > extensions;
    std::vector<string16> extension_description_overrides;
    bool include_all_files;
  };

  // Selects a File.
  // Before doing anything this function checks if FileBrowsing is forbidden
  // by Policy. If so, it tries to show an InfoBar and behaves as though no File
  // was selected (the user clicked `Cancel` immediately).
  // Otherwise it will start displaying the dialog box. This will also
  // block the calling window until the dialog box is complete. The listener
  // associated with this object will be notified when the selection is
  // complete.
  // |type| is the type of file dialog to be shown, see Type enumeration above.
  // |title| is the title to be displayed in the dialog. If this string is
  //   empty, the default title is used.
  // |default_path| is the default path and suggested file name to be shown in
  //   the dialog. This only works for SELECT_SAVEAS_FILE and SELECT_OPEN_FILE.
  //   Can be an empty string to indicate the platform default.
  // |file_types| holds the information about the file types allowed. Pass NULL
  //   to get no special behavior
  // |file_type_index| is the 1-based index into the file type list in
  //   |file_types|. Specify 0 if you don't need to specify extension behavior.
  // |default_extension| is the default extension to add to the file if the
  //   user doesn't type one. This should NOT include the '.'. On Windows, if
  //   you specify this you must also specify |file_types|.
  // |owning_window| is the window the dialog is modal to, or NULL for a
  //   modeless dialog.
  // |params| is data from the calling context which will be passed through to
  //   the listener. Can be NULL.
  // NOTE: only one instance of any shell dialog can be shown per owning_window
  //       at a time (for obvious reasons).
  void SelectFile(Type type,
                  const string16& title,
                  const FilePath& default_path,
                  const FileTypeInfo* file_types,
                  int file_type_index,
                  const FilePath::StringType& default_extension,
                  gfx::NativeWindow owning_window,
                  void* params);
  bool HasMultipleFileTypeChoices();

 protected:
  friend class base::RefCountedThreadSafe<SelectFileDialog>;
  explicit SelectFileDialog(Listener* listener,
                            ui::SelectFilePolicy* policy);
  virtual ~SelectFileDialog();

  // Displays the actual file-selection dialog.
  // This is overridden in the platform-specific descendants of FileSelectDialog
  // and gets called from SelectFile after testing the
  // AllowFileSelectionDialogs-Policy.
  virtual void SelectFileImpl(Type type,
                              const string16& title,
                              const FilePath& default_path,
                              const FileTypeInfo* file_types,
                              int file_type_index,
                              const FilePath::StringType& default_extension,
                              gfx::NativeWindow owning_window,
                              void* params) = 0;

  // The listener to be notified of selection completion.
  Listener* listener_;

 private:
  // Tests if the file selection dialog can be displayed by
  // testing if the AllowFileSelectionDialogs-Policy is
  // either unset or set to true.
  bool CanOpenSelectFileDialog();

  // Informs the |listener_| that the file selection dialog was canceled. Moved
  // to a function for being able to post it to the message loop.
  void CancelFileSelection(void* params);

  // Returns true if the dialog has multiple file type choices.
  virtual bool HasMultipleFileTypeChoicesImpl() = 0;

  scoped_ptr<ui::SelectFilePolicy> select_file_policy_;

  DISALLOW_COPY_AND_ASSIGN(SelectFileDialog);
};

#endif  // CHROME_BROWSER_UI_SELECT_FILE_DIALOG_H_