summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--printing/DEPS1
-rw-r--r--printing/printing.gyp1
-rw-r--r--printing/printing_context_win.cc58
-rw-r--r--printing/printing_context_win.h15
-rw-r--r--ui/shell_dialogs.gypi2
-rw-r--r--ui/shell_dialogs/base_shell_dialog_win.cc4
-rw-r--r--ui/shell_dialogs/print_settings_dialog_win.cc58
-rw-r--r--ui/shell_dialogs/print_settings_dialog_win.h83
8 files changed, 198 insertions, 24 deletions
diff --git a/printing/DEPS b/printing/DEPS
index 00c20e2..64123b8 100644
--- a/printing/DEPS
+++ b/printing/DEPS
@@ -7,5 +7,6 @@ include_rules = [
"+ui/base/resource",
"+ui/base/text",
"+ui/gfx",
+ "+ui/shell_dialogs",
"+win8/util",
]
diff --git a/printing/printing.gyp b/printing/printing.gyp
index 455786e..c7ff11e 100644
--- a/printing/printing.gyp
+++ b/printing/printing.gyp
@@ -18,6 +18,7 @@
'../third_party/icu/icu.gyp:icui18n',
'../third_party/icu/icu.gyp:icuuc',
'../ui/gfx/gfx.gyp:gfx',
+ '../ui/ui.gyp:shell_dialogs',
'../ui/ui.gyp:ui',
'../url/url.gyp:url_lib',
],
diff --git a/printing/printing_context_win.cc b/printing/printing_context_win.cc
index 642ada6..29b2604 100644
--- a/printing/printing_context_win.cc
+++ b/printing/printing_context_win.cc
@@ -189,11 +189,11 @@ PrintingContextWin::~PrintingContextWin() {
ReleaseContext();
}
-// TODO(vitalybuka): Implement as ui::BaseShellDialog crbug.com/180997.
void PrintingContextWin::AskUserForSettings(
gfx::NativeView view, int max_pages, bool has_selection,
const PrintSettingsCallback& callback) {
DCHECK(!in_print_job_);
+ // TODO(scottmg): Possibly this has to move into the threaded runner too?
if (win8::IsSingleWindowMetroMode()) {
// The system dialog can not be opened while running in Metro.
// But we can programatically launch the Metro print device charm though.
@@ -226,40 +226,40 @@ void PrintingContextWin::AskUserForSettings(
// - Cancel, the settings are not changed, the previous setting, if it was
// initialized before, are kept. CANCEL is returned.
// On failure, the settings are reset and FAILED is returned.
- PRINTDLGEX dialog_options = { sizeof(PRINTDLGEX) };
- dialog_options.hwndOwner = window;
+ PRINTDLGEX* dialog_options =
+ reinterpret_cast<PRINTDLGEX*>(malloc(sizeof(PRINTDLGEX)));
+ ZeroMemory(dialog_options, sizeof(PRINTDLGEX));
+ dialog_options->lStructSize = sizeof(PRINTDLGEX);
+ dialog_options->hwndOwner = window;
// Disable options we don't support currently.
// TODO(maruel): Reuse the previously loaded settings!
- dialog_options.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE |
- PD_NOCURRENTPAGE | PD_HIDEPRINTTOFILE;
+ dialog_options->Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE |
+ PD_NOCURRENTPAGE | PD_HIDEPRINTTOFILE;
if (!has_selection)
- dialog_options.Flags |= PD_NOSELECTION;
+ dialog_options->Flags |= PD_NOSELECTION;
- PRINTPAGERANGE ranges[32];
- dialog_options.nStartPage = START_PAGE_GENERAL;
+ const size_t max_page_ranges = 32;
+ PRINTPAGERANGE* ranges = new PRINTPAGERANGE[max_page_ranges];
+ dialog_options->lpPageRanges = ranges;
+ dialog_options->nStartPage = START_PAGE_GENERAL;
if (max_pages) {
// Default initialize to print all the pages.
memset(ranges, 0, sizeof(ranges));
ranges[0].nFromPage = 1;
ranges[0].nToPage = max_pages;
- dialog_options.nPageRanges = 1;
- dialog_options.nMaxPageRanges = arraysize(ranges);
- dialog_options.nMinPage = 1;
- dialog_options.nMaxPage = max_pages;
- dialog_options.lpPageRanges = ranges;
+ dialog_options->nPageRanges = 1;
+ dialog_options->nMaxPageRanges = max_page_ranges;
+ dialog_options->nMinPage = 1;
+ dialog_options->nMaxPage = max_pages;
} else {
// No need to bother, we don't know how many pages are available.
- dialog_options.Flags |= PD_NOPAGENUMS;
+ dialog_options->Flags |= PD_NOPAGENUMS;
}
- HRESULT hr = (*print_dialog_func_)(&dialog_options);
- if (hr != S_OK) {
- ResetSettings();
- callback.Run(FAILED);
- }
-
- // TODO(maruel): Support PD_PRINTTOFILE.
- callback.Run(ParseDialogResultEx(dialog_options));
+ callback_ = callback;
+ print_settings_dialog_ = new ui::PrintSettingsDialogWin(this);
+ print_settings_dialog_->GetPrintSettings(
+ print_dialog_func_, window, dialog_options);
}
PrintingContext::Result PrintingContextWin::UseDefaultSettings() {
@@ -565,6 +565,20 @@ gfx::NativeDrawingContext PrintingContextWin::context() const {
return context_;
}
+void PrintingContextWin::PrintSettingsConfirmed(PRINTDLGEX* dialog_options) {
+ // TODO(maruel): Support PD_PRINTTOFILE.
+ callback_.Run(ParseDialogResultEx(*dialog_options));
+ delete [] dialog_options->lpPageRanges;
+ free(dialog_options);
+}
+
+void PrintingContextWin::PrintSettingsCancelled(PRINTDLGEX* dialog_options) {
+ ResetSettings();
+ callback_.Run(FAILED);
+ delete [] dialog_options->lpPageRanges;
+ free(dialog_options);
+}
+
// static
BOOL PrintingContextWin::AbortProc(HDC hdc, int nCode) {
if (nCode) {
diff --git a/printing/printing_context_win.h b/printing/printing_context_win.h
index c54b531..06226b2 100644
--- a/printing/printing_context_win.h
+++ b/printing/printing_context_win.h
@@ -14,10 +14,13 @@
#include "build/build_config.h"
#include "printing/printing_context.h"
#include "ui/gfx/native_widget_types.h"
+#include "ui/shell_dialogs/print_settings_dialog_win.h"
namespace printing {
-class PRINTING_EXPORT PrintingContextWin : public PrintingContext {
+class PRINTING_EXPORT PrintingContextWin
+ : public PrintingContext,
+ public ui::PrintSettingsDialogWin::Observer {
public:
explicit PrintingContextWin(const std::string& app_locale);
~PrintingContextWin();
@@ -41,6 +44,10 @@ class PRINTING_EXPORT PrintingContextWin : public PrintingContext {
virtual void ReleaseContext() OVERRIDE;
virtual gfx::NativeDrawingContext context() const OVERRIDE;
+ // PrintSettingsDialogWin::Observer implementation:
+ virtual void PrintSettingsConfirmed(PRINTDLGEX* dialog_options) OVERRIDE;
+ virtual void PrintSettingsCancelled(PRINTDLGEX* dialog_options) OVERRIDE;
+
#if defined(UNIT_TEST) || defined(PRINTING_IMPLEMENTATION)
// Sets a fake PrintDlgEx function pointer in tests.
void SetPrintDialog(HRESULT (__stdcall *print_dialog_func)(LPPRINTDLGEX)) {
@@ -88,6 +95,12 @@ class PRINTING_EXPORT PrintingContextWin : public PrintingContext {
// SetPrintDialog() in tests.
HRESULT (__stdcall *print_dialog_func_)(LPPRINTDLGEX);
+ // Where to notify when the dialog is closed.
+ PrintSettingsCallback callback_;
+
+ // Wrapper around native print dialog that runs it on a background thread.
+ scoped_refptr<ui::PrintSettingsDialogWin> print_settings_dialog_;
+
DISALLOW_COPY_AND_ASSIGN(PrintingContextWin);
};
diff --git a/ui/shell_dialogs.gypi b/ui/shell_dialogs.gypi
index 2675d73..29f676f 100644
--- a/ui/shell_dialogs.gypi
+++ b/ui/shell_dialogs.gypi
@@ -30,6 +30,8 @@
'shell_dialogs/gtk/select_file_dialog_impl_kde.cc',
'shell_dialogs/linux_shell_dialog.cc',
'shell_dialogs/linux_shell_dialog.h',
+ 'shell_dialogs/print_settings_dialog_win.cc',
+ 'shell_dialogs/print_settings_dialog_win.h',
'shell_dialogs/select_file_dialog.cc',
'shell_dialogs/select_file_dialog.h',
'shell_dialogs/select_file_dialog_android.cc',
diff --git a/ui/shell_dialogs/base_shell_dialog_win.cc b/ui/shell_dialogs/base_shell_dialog_win.cc
index 9ccd1bb..e121fbf 100644
--- a/ui/shell_dialogs/base_shell_dialog_win.cc
+++ b/ui/shell_dialogs/base_shell_dialog_win.cc
@@ -30,7 +30,9 @@ BaseShellDialogImpl::RunState BaseShellDialogImpl::BeginRun(HWND owner) {
DCHECK(!IsRunningDialogForOwner(owner));
// The owner must be a top level window, otherwise we could end up with two
// entries in our map for the same top level window.
- DCHECK(!owner || owner == GetAncestor(owner, GA_ROOT));
+ // TODO(scottmg): This should be re-enabled when Chrome Frame is removed.
+ // http://crbug.com/310264
+ // DCHECK(!owner || owner == GetAncestor(owner, GA_ROOT));
RunState run_state;
run_state.dialog_thread = CreateDialogThread();
run_state.owner = owner;
diff --git a/ui/shell_dialogs/print_settings_dialog_win.cc b/ui/shell_dialogs/print_settings_dialog_win.cc
new file mode 100644
index 0000000..f3f89b3
--- /dev/null
+++ b/ui/shell_dialogs/print_settings_dialog_win.cc
@@ -0,0 +1,58 @@
+// Copyright 2013 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 "ui/shell_dialogs/print_settings_dialog_win.h"
+
+#include "base/bind.h"
+#include "base/threading/thread.h"
+
+#if defined(USE_AURA)
+#include "ui/aura/root_window.h"
+#endif
+
+namespace ui {
+
+PrintSettingsDialogWin::PrintSettingsDialogWin(
+ PrintSettingsDialogWin::Observer* observer)
+ : observer_(observer) {
+}
+
+PrintSettingsDialogWin::~PrintSettingsDialogWin() {
+}
+
+void PrintSettingsDialogWin::GetPrintSettings(PrintDialogFunc print_dialog_func,
+ HWND owning_window,
+ PRINTDLGEX* dialog_options) {
+ DCHECK(observer_);
+
+ ExecutePrintSettingsParams execute_params(BeginRun(owning_window),
+ owning_window,
+ print_dialog_func,
+ dialog_options);
+ execute_params.run_state.dialog_thread->message_loop()->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &PrintSettingsDialogWin::ExecutePrintSettings, this, execute_params));
+}
+
+void PrintSettingsDialogWin::ExecutePrintSettings(
+ const ExecutePrintSettingsParams& params) {
+ HRESULT hr = (*params.print_dialog_func)(params.dialog_options);
+ params.ui_proxy->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &PrintSettingsDialogWin::PrintSettingsCompleted, this, hr, params));
+}
+
+void PrintSettingsDialogWin::PrintSettingsCompleted(
+ HRESULT hresult,
+ const ExecutePrintSettingsParams& params) {
+ EndRun(params.run_state);
+ if (hresult != S_OK)
+ observer_->PrintSettingsCancelled(params.dialog_options);
+ else
+ observer_->PrintSettingsConfirmed(params.dialog_options);
+}
+
+} // namespace ui
diff --git a/ui/shell_dialogs/print_settings_dialog_win.h b/ui/shell_dialogs/print_settings_dialog_win.h
new file mode 100644
index 0000000..6a1efed
--- /dev/null
+++ b/ui/shell_dialogs/print_settings_dialog_win.h
@@ -0,0 +1,83 @@
+// Copyright 2013 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 UI_SHELL_DIALOGS_PRINT_SETTINGS_DIALOG_WIN_H_
+#define UI_SHELL_DIALOGS_PRINT_SETTINGS_DIALOG_WIN_H_
+
+#include <ocidl.h>
+#include <commdlg.h>
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "ui/shell_dialogs/base_shell_dialog_win.h"
+#include "ui/shell_dialogs/shell_dialogs_export.h"
+
+namespace ui {
+
+// A thin wrapper around the native window print dialog that uses
+// BaseShellDialog to have the dialog run on a background thread.
+class SHELL_DIALOGS_EXPORT PrintSettingsDialogWin
+ : public base::RefCountedThreadSafe<PrintSettingsDialogWin>,
+ public BaseShellDialogImpl {
+ public:
+ class SHELL_DIALOGS_EXPORT Observer {
+ public:
+ virtual void PrintSettingsConfirmed(PRINTDLGEX* dialog_options) = 0;
+ virtual void PrintSettingsCancelled(PRINTDLGEX* dialog_options) = 0;
+ };
+ typedef HRESULT(__stdcall* PrintDialogFunc)(PRINTDLGEX*);
+
+ explicit PrintSettingsDialogWin(Observer* observer);
+ virtual ~PrintSettingsDialogWin();
+
+ // Called to open the system print dialog on a background thread.
+ // |print_dialog_func| should generally be ::PrintDlgEx, however alternate
+ // functions are used for testing. |owning_window| is the parent HWND, and
+ // |dialog_options| is passed to |print_dialog_func|.
+ void GetPrintSettings(
+ PrintDialogFunc print_dialog_func,
+ HWND owning_window,
+ PRINTDLGEX* dialog_options);
+
+ private:
+ // A struct for holding all the state necessary for displaying the print
+ // settings dialog.
+ struct ExecutePrintSettingsParams {
+ ExecutePrintSettingsParams(RunState run_state,
+ HWND owner,
+ PrintDialogFunc print_dialog_func,
+ PRINTDLGEX* dialog_options)
+ : run_state(run_state),
+ owner(owner),
+ print_dialog_func(print_dialog_func),
+ dialog_options(dialog_options),
+ ui_proxy(base::MessageLoopForUI::current()->message_loop_proxy()) {}
+
+ RunState run_state;
+ HWND owner;
+ PrintDialogFunc print_dialog_func;
+ PRINTDLGEX* dialog_options;
+ scoped_refptr<base::MessageLoopProxy> ui_proxy;
+ };
+
+ // Runs the print dialog. Should be run on the the BaseShellDialogImpl thread.
+ // Posts back to PrintSettingsCompleted on the UI thread on completion.
+ void ExecutePrintSettings(const ExecutePrintSettingsParams& params);
+
+ // Handler for the result of the print settings dialog. Should be run on the
+ // UI thread, and notifies the observer of the result of the dialog.
+ void PrintSettingsCompleted(HRESULT hresult,
+ const ExecutePrintSettingsParams& params);
+
+ // Observer that's notified when the dialog is confirmed or cancelled.
+ Observer* observer_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrintSettingsDialogWin);
+};
+
+} // namespace ui
+
+#endif // UI_SHELL_DIALOGS_PRINT_SETTINGS_DIALOG_WIN_H_