summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-12 23:36:30 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-12 23:36:30 +0000
commit0f44d3e778979b6f1acae43a39e4b4bf9d557c8b (patch)
tree8f37c45a6e7de25156fbaa7516373920d96a8500 /chrome
parentbd1d148d3f4888f715c2c9995d78b9294c35084b (diff)
downloadchromium_src-0f44d3e778979b6f1acae43a39e4b4bf9d557c8b.zip
chromium_src-0f44d3e778979b6f1acae43a39e4b4bf9d557c8b.tar.gz
chromium_src-0f44d3e778979b6f1acae43a39e4b4bf9d557c8b.tar.bz2
Gtk dialogs, first cut.
Only the Save As file selection dialog is implemented for now. Review URL: http://codereview.chromium.org/42152 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@11594 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/browser.h4
-rw-r--r--chrome/browser/browser.scons1
-rw-r--r--chrome/browser/download/download_manager.cc19
-rw-r--r--chrome/browser/download/download_manager.h4
-rw-r--r--chrome/browser/gtk/dialogs_gtk.cc182
-rw-r--r--chrome/browser/shell_dialogs.h6
-rw-r--r--chrome/browser/tab_contents/web_contents.h2
-rw-r--r--chrome/common/temp_scaffolding_stubs.h2
8 files changed, 209 insertions, 11 deletions
diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h
index 3c3bb7e..025a8e5 100644
--- a/chrome/browser/browser.h
+++ b/chrome/browser/browser.h
@@ -10,7 +10,7 @@
#include <set>
#include <vector>
-#if defined(OS_MACOSX) || defined(OS_LINUX)
+#if defined(OS_MACOSX)
// Remove when we've finished porting the supporting classes.
#include "chrome/common/temp_scaffolding_stubs.h"
#endif
@@ -29,7 +29,7 @@
#include "base/task.h"
#include "skia/include/SkBitmap.h"
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_LINUX)
#include "chrome/browser/shell_dialogs.h"
#endif
diff --git a/chrome/browser/browser.scons b/chrome/browser/browser.scons
index a572a0b..70da7dc 100644
--- a/chrome/browser/browser.scons
+++ b/chrome/browser/browser.scons
@@ -747,6 +747,7 @@ if env.Bit('linux'):
'gtk/browser_window_factory_gtk.cc',
'gtk/browser_window_gtk.cc',
'gtk/custom_button.cc',
+ 'gtk/dialogs_gtk.cc',
'gtk/download_item_gtk.cc',
'gtk/download_shelf_gtk.cc',
'gtk/find_bar_gtk.cc',
diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc
index 719efa0..98b0e32 100644
--- a/chrome/browser/download/download_manager.cc
+++ b/chrome/browser/download/download_manager.cc
@@ -45,6 +45,10 @@
#include "chrome/common/win_util.h"
#endif
+#if defined(OS_LINUX)
+#include <gtk/gtk.h>
+#endif
+
// Periodically update our observers.
class DownloadItemUpdateTask : public Task {
public:
@@ -618,7 +622,7 @@ void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info) {
}
void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) {
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_LINUX)
DCHECK(MessageLoop::current() == ui_loop_);
DCHECK(info);
@@ -629,20 +633,27 @@ void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) {
WebContents* contents = tab_util::GetWebContentsByID(
info->render_process_id, info->render_view_id);
+#if defined(OS_WIN)
std::wstring filter =
win_util::GetFileFilterFromPath(info->suggested_path.value());
- HWND owning_hwnd =
+ gfx::NativeWindow owning_window =
contents ? GetAncestor(contents->GetNativeView(), GA_ROOT) : NULL;
+#elif defined(OS_LINUX)
+ std::wstring filter;
+ gfx::NativeWindow owning_window = contents ?
+ GTK_WINDOW(gtk_widget_get_toplevel(contents->GetNativeView())) :
+ NULL;
+#endif
select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE,
std::wstring(),
info->suggested_path.ToWStringHack(),
filter, std::wstring(),
- owning_hwnd, info);
+ owning_window, info);
} else {
// No prompting for download, just continue with the suggested name.
ContinueStartDownload(info, info->suggested_path);
}
-#elif defined(OS_POSIX)
+#elif defined(OS_MACOSX)
// TODO(port): port this file -- need dialogs.
NOTIMPLEMENTED();
#endif
diff --git a/chrome/browser/download/download_manager.h b/chrome/browser/download/download_manager.h
index de1f3ab..4a3125b 100644
--- a/chrome/browser/download/download_manager.h
+++ b/chrome/browser/download/download_manager.h
@@ -53,10 +53,10 @@
#include "chrome/browser/history/history.h"
#include "chrome/common/pref_member.h"
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_LINUX)
// TODO(port): port this header.
#include "chrome/browser/shell_dialogs.h"
-#elif defined(OS_POSIX)
+#elif defined(OS_MACOSX)
#include "chrome/common/temp_scaffolding_stubs.h"
#endif
diff --git a/chrome/browser/gtk/dialogs_gtk.cc b/chrome/browser/gtk/dialogs_gtk.cc
new file mode 100644
index 0000000..c2d2f3f
--- /dev/null
+++ b/chrome/browser/gtk/dialogs_gtk.cc
@@ -0,0 +1,182 @@
+// Copyright (c) 2009 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.
+
+#include <gtk/gtk.h>
+#include <map>
+#include <set>
+
+#include "base/file_path.h"
+#include "base/logging.h"
+#include "base/string_util.h"
+#include "chrome/browser/shell_dialogs.h"
+
+// Implementation of SelectFileDialog that shows a Gtk common dialog for
+// choosing a file or folder.
+// This acts as a modal dialog. Ideally we want to only act modally for the
+// parent window and allow other toplevel chrome windows to still function while
+// the dialog is showing, but we need the GtkWindowGroup or something similar to
+// get that, and that API is only available in more recent versions of GTK.
+// TODO(port): fix modality: crbug.com/8727
+class SelectFileDialogImpl : public SelectFileDialog {
+ public:
+ explicit SelectFileDialogImpl(Listener* listener);
+ virtual ~SelectFileDialogImpl();
+
+ // BaseShellDialog implementation.
+ virtual bool IsRunning(gfx::NativeWindow parent_window) const;
+ virtual void ListenerDestroyed();
+
+ // SelectFileDialog implementation.
+ // |params| is user data we pass back via the Listener interface.
+ virtual void SelectFile(Type type, const std::wstring& title,
+ const std::wstring& default_path,
+ const std::wstring& filter,
+ const std::wstring& default_extension,
+ gfx::NativeWindow parent_window,
+ void* params);
+
+ private:
+ // Notifies the listener that a single file was chosen.
+ void FileSelected(GtkWidget* dialog, const FilePath& path);
+
+ // Notifies the listener that no file was chosen (the action was canceled).
+ // Dialog is passed so we can find that |params| pointer that was passed to
+ // us when we were told to show the dialog.
+ void FileNotSelected(GtkWidget* dialog);
+
+ // Removes and returns the |params| associated with |dialog| from
+ // |params_map_|.
+ void* PopParamsForDialog(GtkWidget* dialog);
+
+ // Removes and returns the parent associated with |dialog| from |parents_|.
+ void RemoveParentForDialog(GtkWidget* dialog);
+
+ // Callback for when the user cancels or closes the dialog.
+ static void OnSelectFileDialogResponse(GtkWidget* dialog, gint response_id,
+ SelectFileDialogImpl* dialog_impl);
+
+ // The listener to be notified of selection completion.
+ Listener* listener_;
+
+ // Our parent window.
+ gfx::NativeWindow parent_window_;
+
+ // A map from dialog windows to the |params| user data associated with them.
+ std::map<GtkWidget*, void*> params_map_;
+
+ // The set of all parent windows for which we are currently running dialogs.
+ std::set<GtkWindow*> parents_;
+
+ DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImpl);
+};
+
+// static
+SelectFileDialog* SelectFileDialog::Create(Listener* listener) {
+ return new SelectFileDialogImpl(listener);
+}
+
+SelectFileDialogImpl::SelectFileDialogImpl(Listener* listener)
+ : listener_(listener) {
+}
+
+SelectFileDialogImpl::~SelectFileDialogImpl() {
+}
+
+bool SelectFileDialogImpl::IsRunning(gfx::NativeWindow parent_window) const {
+ return parents_.find(parent_window) != parents_.end();
+}
+
+void SelectFileDialogImpl::ListenerDestroyed() {
+ listener_ = NULL;
+}
+
+// We ignore |filter| and |default_extension|.
+void SelectFileDialogImpl::SelectFile(
+ Type type,
+ const std::wstring& title,
+ const std::wstring& default_path,
+ const std::wstring& filter,
+ const std::wstring& default_extension,
+ gfx::NativeWindow parent_window,
+ void* params) {
+ // TODO(estade): on windows, parent_window may be null. But I'm not sure when
+ // that's used and how to deal with it here. For now, don't allow it.
+ DCHECK(parent_window);
+ parents_.insert(parent_window);
+
+ if (type != SELECT_SAVEAS_FILE) {
+ NOTIMPLEMENTED();
+ return;
+ }
+
+ // TODO(port): get rid of these conversions when the parameter types are
+ // ported.
+ std::string title_string = WideToUTF8(title);
+ FilePath default_file_path = FilePath::FromWStringHack(default_path);
+
+ GtkWidget* dialog =
+ gtk_file_chooser_dialog_new(title_string.c_str(), parent_window,
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ NULL);
+ params_map_[dialog] = params;
+ gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
+ default_file_path.DirName().value().c_str());
+ gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog),
+ default_file_path.BaseName().value().c_str());
+ gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE);
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+ g_signal_connect(G_OBJECT(dialog), "response",
+ G_CALLBACK(OnSelectFileDialogResponse), this);
+ gtk_widget_show_all(dialog);
+}
+
+void SelectFileDialogImpl::FileSelected(GtkWidget* dialog,
+ const FilePath& path) {
+ void* params = PopParamsForDialog(dialog);
+ if (listener_)
+ listener_->FileSelected(path.ToWStringHack(), params);
+ RemoveParentForDialog(dialog);
+ gtk_widget_destroy(dialog);
+}
+
+void SelectFileDialogImpl::FileNotSelected(GtkWidget* dialog) {
+ void* params = PopParamsForDialog(dialog);
+ if (listener_)
+ listener_->FileSelectionCanceled(params);
+ RemoveParentForDialog(dialog);
+ gtk_widget_destroy(dialog);
+}
+
+void* SelectFileDialogImpl::PopParamsForDialog(GtkWidget* dialog) {
+ std::map<GtkWidget*, void*>::iterator iter = params_map_.find(dialog);
+ DCHECK(iter != params_map_.end());
+ void* params = iter->second;
+ params_map_.erase(iter);
+ return params;
+}
+
+void SelectFileDialogImpl::RemoveParentForDialog(GtkWidget* dialog) {
+ GtkWindow* parent = gtk_window_get_transient_for(GTK_WINDOW(dialog));
+ DCHECK(parent);
+ std::set<GtkWindow*>::iterator iter = parents_.find(parent);
+ DCHECK(iter != parents_.end());
+ parents_.erase(iter);
+}
+
+// static
+void SelectFileDialogImpl::OnSelectFileDialogResponse(
+ GtkWidget* dialog, gint response_id,
+ SelectFileDialogImpl* dialog_impl) {
+ if (response_id == GTK_RESPONSE_CANCEL ||
+ response_id == GTK_RESPONSE_DELETE_EVENT) {
+ dialog_impl->FileNotSelected(dialog);
+ return;
+ }
+
+ DCHECK(response_id == GTK_RESPONSE_ACCEPT);
+ gchar* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+ dialog_impl->FileSelected(dialog, FilePath(filename));
+}
diff --git a/chrome/browser/shell_dialogs.h b/chrome/browser/shell_dialogs.h
index bbc3bc7..d368a99 100644
--- a/chrome/browser/shell_dialogs.h
+++ b/chrome/browser/shell_dialogs.h
@@ -21,7 +21,7 @@ class BaseShellDialog {
public:
// Returns true if the a shell dialog box is currently being shown modally
// to the specified owner.
- virtual bool IsRunning(gfx::NativeView owning_window) const = 0;
+ virtual bool IsRunning(gfx::NativeWindow owning_window) const = 0;
// Notifies the dialog box that the listener has been destroyed and it should
// no longer be sent notifications.
@@ -137,12 +137,12 @@ class SelectFontDialog
// at a time (for obvious reasons).
// TODO(beng): support specifying the default font selected in the list when
// the dialog appears.
- virtual void SelectFont(gfx::NativeView owning_window,
+ virtual void SelectFont(gfx::NativeWindow owning_window,
void* params) = 0;
// Same as above - also support specifying the default font selected in the
// list when the dialog appears.
- virtual void SelectFont(gfx::NativeView owning_window,
+ virtual void SelectFont(gfx::NativeWindow owning_window,
void* params,
const std::wstring& font_name,
int font_size) = 0;
diff --git a/chrome/browser/tab_contents/web_contents.h b/chrome/browser/tab_contents/web_contents.h
index 37c4ef7..5a07b5f 100644
--- a/chrome/browser/tab_contents/web_contents.h
+++ b/chrome/browser/tab_contents/web_contents.h
@@ -29,6 +29,8 @@
#include "chrome/common/temp_scaffolding_stubs.h"
#elif defined(OS_WIN)
#include "chrome/browser/printing/print_view_manager.h"
+#endif
+#if defined(OS_LINUX) || defined(OS_WIN)
#include "chrome/browser/shell_dialogs.h"
#endif
diff --git a/chrome/common/temp_scaffolding_stubs.h b/chrome/common/temp_scaffolding_stubs.h
index 71c534d..bd8ee62 100644
--- a/chrome/common/temp_scaffolding_stubs.h
+++ b/chrome/common/temp_scaffolding_stubs.h
@@ -419,6 +419,7 @@ class FaviconStatus {
GURL url_;
};
+#if defined(OS_MACOSX)
class SelectFileDialog : public base::RefCountedThreadSafe<SelectFileDialog> {
public:
enum Type {
@@ -439,6 +440,7 @@ class SelectFileDialog : public base::RefCountedThreadSafe<SelectFileDialog> {
return new SelectFileDialog;
}
};
+#endif
class DockInfo {
public: