summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-12 22:10:20 +0000
committersky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-12 22:10:20 +0000
commit39a248b002d0f41ad816754bb2833eea0aff9c61 (patch)
tree2b3c12b82e8ba1779f3b5cf0b6e1783bb357c8bb
parentfe60fbbb329988a1b4eab5fcc78faaad719cda1b (diff)
downloadchromium_src-39a248b002d0f41ad816754bb2833eea0aff9c61.zip
chromium_src-39a248b002d0f41ad816754bb2833eea0aff9c61.tar.gz
chromium_src-39a248b002d0f41ad816754bb2833eea0aff9c61.tar.bz2
Adds the ability for save dialogs to take a default extension.
BUG=4287 TEST=see bug Review URL: http://codereview.chromium.org/10621 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5304 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/task.h14
-rw-r--r--base/tuple.h65
-rw-r--r--chrome/browser/browser.cc5
-rw-r--r--chrome/browser/download/download_manager.cc1
-rw-r--r--chrome/browser/shell_dialogs.h14
-rw-r--r--chrome/browser/views/bookmark_manager_view.cc20
-rw-r--r--chrome/browser/views/options/content_page_view.cc4
-rw-r--r--chrome/browser/views/shell_dialogs.cc12
-rw-r--r--chrome/browser/views/user_data_dir_dialog.cc4
-rw-r--r--chrome/browser/web_contents.cc5
-rw-r--r--chrome/common/win_util.cc16
-rw-r--r--chrome/common/win_util.h11
12 files changed, 135 insertions, 36 deletions
diff --git a/base/task.h b/base/task.h
index c1b25cf..a00555a 100644
--- a/base/task.h
+++ b/base/task.h
@@ -387,6 +387,20 @@ inline CancelableTask* NewRunnableMethod(T* object, Method method,
f));
}
+template <class T, class Method, class A, class B, class C, class D, class E,
+ class F, class G>
+inline CancelableTask* NewRunnableMethod(T* object, Method method,
+ const A& a, const B& b,
+ const C& c, const D& d, const E& e,
+ const F& f, const G& g) {
+ return new RunnableMethod<T,
+ Method,
+ Tuple7<A, B, C, D, E, F, G> >(object,
+ method,
+ MakeTuple(a, b, c, d,
+ e, f, g));
+}
+
// RunnableFunction and NewRunnableFunction implementation ---------------------
template <class Function, class Params>
diff --git a/base/tuple.h b/base/tuple.h
index a515830..8fd965f 100644
--- a/base/tuple.h
+++ b/base/tuple.h
@@ -233,6 +233,51 @@ public:
F f;
};
+template <class A, class B, class C, class D, class E, class F, class G>
+struct Tuple7 {
+public:
+ typedef A TypeA;
+ typedef B TypeB;
+ typedef C TypeC;
+ typedef D TypeD;
+ typedef E TypeE;
+ typedef F TypeF;
+ typedef G TypeG;
+ typedef Tuple7<typename TupleTraits<A>::ValueType,
+ typename TupleTraits<B>::ValueType,
+ typename TupleTraits<C>::ValueType,
+ typename TupleTraits<D>::ValueType,
+ typename TupleTraits<E>::ValueType,
+ typename TupleTraits<F>::ValueType,
+ typename TupleTraits<G>::ValueType> ValueTuple;
+ typedef Tuple7<typename TupleTraits<A>::RefType,
+ typename TupleTraits<B>::RefType,
+ typename TupleTraits<C>::RefType,
+ typename TupleTraits<D>::RefType,
+ typename TupleTraits<E>::RefType,
+ typename TupleTraits<F>::RefType,
+ typename TupleTraits<G>::RefType> RefTuple;
+
+ Tuple7() {}
+ Tuple7(typename TupleTraits<A>::ParamType a,
+ typename TupleTraits<B>::ParamType b,
+ typename TupleTraits<C>::ParamType c,
+ typename TupleTraits<D>::ParamType d,
+ typename TupleTraits<E>::ParamType e,
+ typename TupleTraits<F>::ParamType f,
+ typename TupleTraits<G>::ParamType g)
+ : a(a), b(b), c(c), d(d), e(e), f(f), g(g) {
+ }
+
+ A a;
+ B b;
+ C c;
+ D d;
+ E e;
+ F f;
+ G g;
+};
+
// Tuple creators -------------------------------------------------------------
//
// Helper functions for constructing tuples while inferring the template
@@ -275,6 +320,13 @@ inline Tuple6<A, B, C, D, E, F> MakeTuple(const A& a, const B& b, const C& c,
return Tuple6<A, B, C, D, E, F>(a, b, c, d, e, f);
}
+template <class A, class B, class C, class D, class E, class F, class G>
+inline Tuple7<A, B, C, D, E, F, G> MakeTuple(const A& a, const B& b, const C& c,
+ const D& d, const E& e, const F& f,
+ const G& g) {
+ return Tuple7<A, B, C, D, E, F, G>(a, b, c, d, e, f, g);
+}
+
// The following set of helpers make what Boost refers to as "Tiers" - a tuple
// of references.
@@ -309,6 +361,12 @@ inline Tuple6<A&, B&, C&, D&, E&, F&> MakeRefTuple(A& a, B& b, C& c, D& d, E& e,
return Tuple6<A&, B&, C&, D&, E&, F&>(a, b, c, d, e, f);
}
+template <class A, class B, class C, class D, class E, class F, class G>
+inline Tuple7<A&, B&, C&, D&, E&, F&, G&> MakeRefTuple(A& a, B& b, C& c, D& d,
+ E& e, F& f, G& g) {
+ return Tuple7<A&, B&, C&, D&, E&, F&, G&>(a, b, c, d, e, f, g);
+}
+
// Dispatchers ----------------------------------------------------------------
//
// Helper functions that call the given method on an object, with the unpacked
@@ -365,6 +423,13 @@ inline void DispatchToMethod(ObjT* obj, Method method,
(obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f);
}
+template<class ObjT, class Method, class A, class B, class C, class D, class E,
+ class F, class G>
+inline void DispatchToMethod(ObjT* obj, Method method,
+ const Tuple7<A, B, C, D, E, F, G>& arg) {
+ (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f, arg.g);
+}
+
// Static Dispatchers with no out params.
template <class Function>
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index 86174b4..b8715a3 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -1068,7 +1068,9 @@ void Browser::OpenFile() {
if (!select_file_dialog_.get())
select_file_dialog_ = SelectFileDialog::Create(this);
select_file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE,
- L"", L"", GetTopLevelHWND(), NULL);
+ std::wstring(), std::wstring(),
+ std::wstring(), std::wstring(),
+ GetTopLevelHWND(), NULL);
}
void Browser::OpenTaskManager() {
@@ -2477,4 +2479,3 @@ void Browser::RegisterAppPrefs(const std::wstring& app_name) {
prefs->RegisterDictionaryPref(window_pref.c_str());
}
-
diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc
index e10173d..ec6aa37 100644
--- a/chrome/browser/download/download_manager.cc
+++ b/chrome/browser/download/download_manager.cc
@@ -608,6 +608,7 @@ void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) {
contents ? GetAncestor(contents->GetContainerHWND(), GA_ROOT) : NULL;
select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE,
std::wstring(), info->suggested_path,
+ std::wstring(), std::wstring(),
owning_hwnd, info);
} else {
// No prompting for download, just continue with the suggested name.
diff --git a/chrome/browser/shell_dialogs.h b/chrome/browser/shell_dialogs.h
index 74cf66c..183081dc 100644
--- a/chrome/browser/shell_dialogs.h
+++ b/chrome/browser/shell_dialogs.h
@@ -77,26 +77,20 @@ class SelectFileDialog
// and filters and terminated with two nulls.
// |owning_hwnd| is the window the dialog is modal to, or NULL for a modeless
// dialog.
+ // |default_extension| is the default extension to add to the file if the
+ // user doesn't type one. This should NOT include the '.'. If you specify
+ // this you must also specify a filter.
// |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_hwnd
// at a time (for obvious reasons).
- // TODO: convert all callers to this and rip out the old.
virtual void SelectFile(Type type,
const std::wstring& title,
const std::wstring& default_path,
const std::wstring& filter,
+ const std::wstring& default_extension,
HWND owning_hwnd,
void* params) = 0;
-
- void SelectFile(Type type,
- const std::wstring& title,
- const std::wstring& default_path,
- HWND owning_hwnd,
- void* params) {
- SelectFile(type, title, default_path, std::wstring(),
- owning_hwnd, params);
- }
};
// Shows a dialog box for selecting a font.
diff --git a/chrome/browser/views/bookmark_manager_view.cc b/chrome/browser/views/bookmark_manager_view.cc
index e5bd6ae..9172b28 100644
--- a/chrome/browser/views/bookmark_manager_view.cc
+++ b/chrome/browser/views/bookmark_manager_view.cc
@@ -26,6 +26,7 @@
#include "chrome/common/gfx/color_utils.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
+#include "chrome/common/win_util.h"
#include "chrome/views/container_win.h"
#include "chrome/views/grid_layout.h"
#include "chrome/views/menu_button.h"
@@ -683,18 +684,20 @@ void BookmarkManagerView::ShowToolsMenu(HWND host, int x, int y) {
views::MenuItemView::TOPLEFT, true);
}
+// The filter used when opening a file.
+// TODO(sky): need a textual description here once we can add new
+// strings.
+static const wchar_t KFilterString[] = L"*.html\0*.html\0";
+
void BookmarkManagerView::ShowImportBookmarksFileChooser() {
if (select_file_dialog_.get())
select_file_dialog_->ListenerDestroyed();
- // TODO(sky): need a textual description here once we can add new
- // strings.
- const wchar_t filter_c_str[] = L"*.html\0*.html\0\0\0";
- std::wstring filter_string(filter_c_str, arraysize(filter_c_str));
+ std::wstring filter_string(KFilterString, arraysize(KFilterString));
select_file_dialog_ = SelectFileDialog::Create(this);
select_file_dialog_->SelectFile(
- SelectFileDialog::SELECT_OPEN_FILE, std::wstring(), std::wstring(),
- filter_string, GetContainer()->GetHWND(),
+ SelectFileDialog::SELECT_OPEN_FILE, std::wstring(), L"bookmarks.html",
+ filter_string, std::wstring(), GetContainer()->GetHWND(),
reinterpret_cast<void*>(IDS_BOOKMARK_MANAGER_IMPORT_MENU));
}
@@ -704,7 +707,8 @@ void BookmarkManagerView::ShowExportBookmarksFileChooser() {
select_file_dialog_ = SelectFileDialog::Create(this);
select_file_dialog_->SelectFile(
- SelectFileDialog::SELECT_SAVEAS_FILE, std::wstring(), std::wstring(),
- std::wstring(), GetContainer()->GetHWND(),
+ SelectFileDialog::SELECT_SAVEAS_FILE, std::wstring(), L"bookmarks.html",
+ win_util::GetFileFilterFromPath(L"bookmarks.html"), L"html",
+ GetContainer()->GetHWND(),
reinterpret_cast<void*>(IDS_BOOKMARK_MANAGER_EXPORT_MENU));
}
diff --git a/chrome/browser/views/options/content_page_view.cc b/chrome/browser/views/options/content_page_view.cc
index edd83b4..665b14b 100644
--- a/chrome/browser/views/options/content_page_view.cc
+++ b/chrome/browser/views/options/content_page_view.cc
@@ -196,7 +196,9 @@ void ContentPageView::ButtonPressed(views::NativeButton* sender) {
const std::wstring dialog_title =
l10n_util::GetString(IDS_OPTIONS_DOWNLOADLOCATION_BROWSE_TITLE);
select_file_dialog_->SelectFile(SelectFileDialog::SELECT_FOLDER,
- dialog_title, L"", GetRootWindow(), NULL);
+ dialog_title, std::wstring(),
+ std::wstring(), std::wstring(),
+ GetRootWindow(), NULL);
} else if (sender == download_ask_for_save_location_checkbox_) {
bool enabled = download_ask_for_save_location_checkbox_->IsSelected();
if (enabled) {
diff --git a/chrome/browser/views/shell_dialogs.cc b/chrome/browser/views/shell_dialogs.cc
index feadbed..31cbaa5b 100644
--- a/chrome/browser/views/shell_dialogs.cc
+++ b/chrome/browser/views/shell_dialogs.cc
@@ -194,6 +194,7 @@ class SelectFileDialogImpl : public SelectFileDialog,
virtual void SelectFile(Type type, const std::wstring& title,
const std::wstring& default_path,
const std::wstring& filter,
+ const std::wstring& default_extension,
HWND owning_hwnd,
void* params);
virtual bool IsRunning(HWND owning_hwnd) const;
@@ -206,6 +207,7 @@ class SelectFileDialogImpl : public SelectFileDialog,
const std::wstring& title,
const std::wstring& default_path,
const std::wstring& filter,
+ const std::wstring& default_extension,
RunState run_state,
void* params);
@@ -250,12 +252,14 @@ void SelectFileDialogImpl::SelectFile(Type type,
const std::wstring& title,
const std::wstring& default_path,
const std::wstring& filter,
+ const std::wstring& default_extension,
HWND owner,
void* params) {
RunState run_state = BeginRun(owner);
run_state.dialog_thread->message_loop()->PostTask(FROM_HERE,
NewRunnableMethod(this, &SelectFileDialogImpl::ExecuteSelectFile, type,
- title, default_path, filter, run_state, params));
+ title, default_path, filter, default_extension,
+ run_state, params));
}
bool SelectFileDialogImpl::IsRunning(HWND owning_hwnd) const {
@@ -273,6 +277,7 @@ void SelectFileDialogImpl::ExecuteSelectFile(
const std::wstring& title,
const std::wstring& default_path,
const std::wstring& filter,
+ const std::wstring& default_extension,
RunState run_state,
void* params) {
std::wstring path = default_path;
@@ -280,7 +285,10 @@ void SelectFileDialogImpl::ExecuteSelectFile(
if (type == SELECT_FOLDER) {
success = RunSelectFolderDialog(title, run_state.owner, &path);
} else if (type == SELECT_SAVEAS_FILE) {
- success = win_util::SaveFileAs(run_state.owner, default_path, &path);
+ const wchar_t* filter_string = filter.empty() ? NULL : filter.c_str();
+ unsigned index = 0;
+ success = win_util::SaveFileAsWithFilter(run_state.owner, default_path,
+ filter_string, default_extension, &index, &path);
DisableOwner(run_state.owner);
} else if (type == SELECT_OPEN_FILE) {
success = RunOpenFileDialog(title, filter, run_state.owner, &path);
diff --git a/chrome/browser/views/user_data_dir_dialog.cc b/chrome/browser/views/user_data_dir_dialog.cc
index 8189331..85e512d 100644
--- a/chrome/browser/views/user_data_dir_dialog.cc
+++ b/chrome/browser/views/user_data_dir_dialog.cc
@@ -72,8 +72,8 @@ bool UserDataDirDialog::Accept() {
HWND owning_hwnd =
GetAncestor(message_box_view_->GetContainer()->GetHWND(), GA_ROOT);
select_file_dialog_->SelectFile(SelectFileDialog::SELECT_FOLDER,
- dialog_title, std::wstring(), owning_hwnd,
- NULL);
+ dialog_title, std::wstring(), std::wstring(),
+ std::wstring(), owning_hwnd, NULL);
return false;
}
diff --git a/chrome/browser/web_contents.cc b/chrome/browser/web_contents.cc
index 0ed5904..2f2fd39 100644
--- a/chrome/browser/web_contents.cc
+++ b/chrome/browser/web_contents.cc
@@ -1067,8 +1067,9 @@ void WebContents::RunFileChooser(const std::wstring& default_file) {
HWND toplevel_hwnd = GetAncestor(GetContainerHWND(), GA_ROOT);
if (!select_file_dialog_.get())
select_file_dialog_ = SelectFileDialog::Create(this);
- select_file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE, L"",
- default_file, toplevel_hwnd, NULL);
+ select_file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE,
+ std::wstring(), default_file, std::wstring(),
+ std::wstring(), toplevel_hwnd, NULL);
}
void WebContents::RunJavaScriptMessage(
diff --git a/chrome/common/win_util.cc b/chrome/common/win_util.cc
index fc0e055..243d629 100644
--- a/chrome/common/win_util.cc
+++ b/chrome/common/win_util.cc
@@ -341,11 +341,9 @@ static void FormatSaveAsFilterForExtension(const std::wstring& file_ext,
(*buffer)[offset] = L'\0'; // Double NULL required.
}
-bool SaveFileAs(HWND owner,
- const std::wstring& suggested_name,
- std::wstring* final_name) {
+std::wstring GetFileFilterFromPath(const std::wstring& file_name) {
std::wstring reg_description;
- std::wstring file_ext = file_util::GetFileExtensionFromPath(suggested_name);
+ std::wstring file_ext = file_util::GetFileExtensionFromPath(file_name);
if (!file_ext.empty()) {
file_ext = L"." + file_ext;
GetRegistryDescriptionFromExtension(file_ext, &reg_description);
@@ -353,11 +351,17 @@ bool SaveFileAs(HWND owner,
std::vector<wchar_t> filter;
FormatSaveAsFilterForExtension(file_ext, reg_description, true, &filter);
+ return std::wstring(&filter[0], filter.size());
+}
+bool SaveFileAs(HWND owner,
+ const std::wstring& suggested_name,
+ std::wstring* final_name) {
+ std::wstring filter = GetFileFilterFromPath(suggested_name);
unsigned index = 1;
return SaveFileAsWithFilter(owner,
suggested_name,
- &filter[0],
+ filter.c_str(),
L"",
&index,
final_name);
@@ -390,7 +394,7 @@ bool SaveFileAsWithFilter(HWND owner,
save_as.hwndOwner = owner;
save_as.hInstance = NULL;
- save_as.lpstrFilter = &filter[0];
+ save_as.lpstrFilter = filter;
save_as.lpstrCustomFilter = NULL;
save_as.nMaxCustFilter = 0;
diff --git a/chrome/common/win_util.h b/chrome/common/win_util.h
index 6688892..5b0fc58 100644
--- a/chrome/common/win_util.h
+++ b/chrome/common/win_util.h
@@ -125,6 +125,8 @@ bool OpenItemViaShellNoZoneCheck(const std::wstring& full_path,
// Returns 'true' on successful open, 'false' otherwise.
bool OpenItemWithExternalApp(const std::wstring& full_path);
+std::wstring GetFileFilterFromPath(const std::wstring& file_name);
+
// Prompt the user for location to save a file. 'suggested_name' is a full path
// that gives the dialog box a hint as to how to initialize itself.
// For example, a 'suggested_name' of:
@@ -149,9 +151,12 @@ bool SaveFileAs(HWND owner,
// The parameter |index| indicates the initial index of filter description
// and filter pattern for the dialog box. If |index| is zero or greater than
// the number of total filter types, the system uses the first filter in the
-// |filter| buffer. The parameter |final_name| returns the file name which
-// contains the drive designator, path, file name, and extension of the user
-// selected file name.
+// |filter| buffer. |index| is used to specify the initial selected extension,
+// and when done contains the extension the user chose. The parameter
+// |final_name| returns the file name which contains the drive designator,
+// path, file name, and extension of the user selected file name. |def_ext| is
+// the default extension to give to the file if the user did not enter an
+// extension.
bool SaveFileAsWithFilter(HWND owner,
const std::wstring& suggested_name,
const wchar_t* filter,