[go: nahoru, domu]

On Chrome OS, use the application locale to determine the default paper size rather than rely on GTK.

BUG=None.
TEST=Web pages printed from Chrome OS should use locale-specific default paper size (specifically, for US, it should use 8.5 x 11).

Review URL: http://codereview.chromium.org/5636001

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@68233 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc
index 111b81b..4a9eedc 100644
--- a/chrome/browser/printing/print_job_worker.cc
+++ b/chrome/browser/printing/print_job_worker.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/printing/print_job_worker.h"
 
 #include "base/message_loop.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_thread.h"
 #include "chrome/browser/printing/print_job.h"
 #include "chrome/common/notification_service.h"
@@ -53,7 +54,8 @@
   // The object is created in the IO thread.
   DCHECK_EQ(owner_->message_loop(), MessageLoop::current());
 
-  printing_context_.reset(PrintingContext::Create());
+  printing_context_.reset(PrintingContext::Create(
+      g_browser_process->GetApplicationLocale()));
 }
 
 PrintJobWorker::~PrintJobWorker() {
diff --git a/printing/emf_win_unittest.cc b/printing/emf_win_unittest.cc
index b0f721c..92384254 100644
--- a/printing/emf_win_unittest.cc
+++ b/printing/emf_win_unittest.cc
@@ -78,7 +78,7 @@
 
   // Initialize it.
   scoped_ptr<printing::PrintingContext> context(
-      printing::PrintingContext::Create());
+      printing::PrintingContext::Create(std::string()));
   EXPECT_EQ(context->InitWithSettings(settings), printing::PrintingContext::OK);
 
   FilePath emf_file;
diff --git a/printing/printing_context.cc b/printing/printing_context.cc
index cd888ea..bc9ba21 100644
--- a/printing/printing_context.cc
+++ b/printing/printing_context.cc
@@ -6,10 +6,11 @@
 
 namespace printing {
 
-PrintingContext::PrintingContext()
+PrintingContext::PrintingContext(const std::string& app_locale)
     : dialog_box_dismissed_(false),
       in_print_job_(false),
-      abort_printing_(false) {
+      abort_printing_(false),
+      app_locale_(app_locale) {
 }
 
 PrintingContext::~PrintingContext() {
diff --git a/printing/printing_context.h b/printing/printing_context.h
index 4edd84e..8cb4f25 100644
--- a/printing/printing_context.h
+++ b/printing/printing_context.h
@@ -84,7 +84,7 @@
   // Creates an instance of this object. Implementers of this interface should
   // implement this method to create an object of their implementation. The
   // caller owns the returned object.
-  static PrintingContext* Create();
+  static PrintingContext* Create(const std::string& app_locale);
 
   void set_use_overlays(bool use_overlays) {
     settings_.use_overlays = use_overlays;
@@ -95,7 +95,7 @@
   }
 
  protected:
-  PrintingContext();
+  explicit PrintingContext(const std::string& app_locale);
 
   // Reinitializes the settings for object reuse.
   void ResetSettings();
@@ -115,6 +115,9 @@
   // Did the user cancel the print job.
   volatile bool abort_printing_;
 
+  // The application locale.
+  std::string app_locale_;
+
   DISALLOW_COPY_AND_ASSIGN(PrintingContext);
 };
 
diff --git a/printing/printing_context_cairo.cc b/printing/printing_context_cairo.cc
index c2097f2..5f9f884 100644
--- a/printing/printing_context_cairo.cc
+++ b/printing/printing_context_cairo.cc
@@ -6,18 +6,22 @@
 
 #include <gtk/gtk.h>
 #include <gtk/gtkprintunixdialog.h>
+#include <unicode/ulocdata.h>
 
 #include "base/logging.h"
+#include "printing/native_metafile.h"
 #include "printing/print_settings_initializer_gtk.h"
+#include "printing/units.h"
 
 namespace printing {
 
 // static
-PrintingContext* PrintingContext::Create() {
-  return static_cast<PrintingContext*>(new PrintingContextCairo);
+  PrintingContext* PrintingContext::Create(const std::string& app_locale) {
+  return static_cast<PrintingContext*>(new PrintingContextCairo(app_locale));
 }
 
-PrintingContextCairo::PrintingContextCairo() : PrintingContext() {
+  PrintingContextCairo::PrintingContextCairo(const std::string& app_locale)
+      : PrintingContext(app_locale) {
 }
 
 PrintingContextCairo::~PrintingContextCairo() {
@@ -37,7 +41,47 @@
   DCHECK(!in_print_job_);
 
   ResetSettings();
+#if defined(OS_CHROMEOS)
+  // For Chrome OS use default values based on the app locale rather than rely
+  // on GTK. Note that relying on the app locale does not work well if it is
+  // different from the system locale, e.g. a user using Chinese ChromeOS in the
+  // US. Eventually we need to get the defaults from the printer.
+  // TODO(sanjeevr): We need a better feedback loop between the cloud print
+  // dialog and this code.
+  int dpi = 300;
+  gfx::Size physical_size_device_units;
+  gfx::Rect printable_area_device_units;
+  int32_t width = 0;
+  int32_t height = 0;
+  UErrorCode error = U_ZERO_ERROR;
+  ulocdata_getPaperSize(app_locale_.c_str(), &height, &width, &error);
+  if (error != U_ZERO_ERROR) {
+    // If the call failed, assume a paper size of 8.5 x 11 inches.
+    LOG(WARNING) << "ulocdata_getPaperSize failed, using 8.5 x 11, error: "
+                 << error;
+    width = static_cast<int>(8.5 * dpi);
+    height = static_cast<int>(11 * dpi);
+  } else {
+    // ulocdata_getPaperSize returns the width and height in mm.
+    // Convert this to pixels based on the dpi.
+    width = static_cast<int>(ConvertUnitDouble(width, 25.4, 1.0) * dpi);
+    height = static_cast<int>(ConvertUnitDouble(height, 25.4, 1.0) * dpi);
+  }
 
+  physical_size_device_units.SetSize(width, height);
+  printable_area_device_units.SetRect(
+      static_cast<int>(NativeMetafile::kLeftMarginInInch * dpi),
+      static_cast<int>(NativeMetafile::kTopMarginInInch * dpi),
+      width - (NativeMetafile::kLeftMarginInInch +
+          NativeMetafile::kRightMarginInInch) * dpi,
+      height - (NativeMetafile::kTopMarginInInch +
+          NativeMetafile::kBottomMarginInInch) * dpi);
+
+  settings_.set_dpi(dpi);
+  settings_.SetPrinterPrintableArea(physical_size_device_units,
+                                    printable_area_device_units,
+                                    dpi);
+#else  // defined(OS_CHROMEOS)
   GtkWidget* dialog = gtk_print_unix_dialog_new(NULL, NULL);
   GtkPrintSettings* settings =
       gtk_print_unix_dialog_get_settings(GTK_PRINT_UNIX_DIALOG(dialog));
@@ -51,6 +95,7 @@
   g_object_unref(settings);
   // |page_setup| is owned by dialog, so it does not need to be unref'ed.
   gtk_widget_destroy(dialog);
+#endif  // defined(OS_CHROMEOS)
 
   return OK;
 }
diff --git a/printing/printing_context_cairo.h b/printing/printing_context_cairo.h
index d4c98ca..c5a8fa8 100644
--- a/printing/printing_context_cairo.h
+++ b/printing/printing_context_cairo.h
@@ -5,13 +5,15 @@
 #ifndef PRINTING_PRINTING_CONTEXT_CAIRO_H_
 #define PRINTING_PRINTING_CONTEXT_CAIRO_H_
 
+#include <string>
+
 #include "printing/printing_context.h"
 
 namespace printing {
 
 class PrintingContextCairo : public PrintingContext {
  public:
-  PrintingContextCairo();
+  explicit PrintingContextCairo(const std::string& app_locale);
   ~PrintingContextCairo();
 
   // PrintingContext implementation.
diff --git a/printing/printing_context_mac.h b/printing/printing_context_mac.h
index f94fae2..49ba983 100644
--- a/printing/printing_context_mac.h
+++ b/printing/printing_context_mac.h
@@ -5,6 +5,8 @@
 #ifndef PRINTING_PRINTING_CONTEXT_MAC_H_
 #define PRINTING_PRINTING_CONTEXT_MAC_H_
 
+#include <string>
+
 #include "printing/printing_context.h"
 
 #ifdef __OBJC__
@@ -17,7 +19,7 @@
 
 class PrintingContextMac : public PrintingContext {
  public:
-  PrintingContextMac();
+  explicit PrintingContextMac(const std::string& app_locale);
   ~PrintingContextMac();
 
   // PrintingContext implementation.
diff --git a/printing/printing_context_mac.mm b/printing/printing_context_mac.mm
index 63c67bd..466c59b 100644
--- a/printing/printing_context_mac.mm
+++ b/printing/printing_context_mac.mm
@@ -15,12 +15,12 @@
 namespace printing {
 
 // static
-PrintingContext* PrintingContext::Create() {
-  return static_cast<PrintingContext*>(new PrintingContextMac);
+PrintingContext* PrintingContext::Create(const std::string& app_locale) {
+  return static_cast<PrintingContext*>(new PrintingContextMac(app_locale));
 }
 
-PrintingContextMac::PrintingContextMac()
-    : PrintingContext(),
+PrintingContextMac::PrintingContextMac(const std::string& app_locale)
+    : PrintingContext(app_locale),
       print_info_(NULL),
       context_(NULL) {
 }
diff --git a/printing/printing_context_win.cc b/printing/printing_context_win.cc
index 9cd65f98..9afa511 100644
--- a/printing/printing_context_win.cc
+++ b/printing/printing_context_win.cc
@@ -122,12 +122,12 @@
 };
 
 // static
-PrintingContext* PrintingContext::Create() {
-  return static_cast<PrintingContext*>(new PrintingContextWin);
+PrintingContext* PrintingContext::Create(const std::string& app_locale) {
+  return static_cast<PrintingContext*>(new PrintingContextWin(app_locale));
 }
 
-PrintingContextWin::PrintingContextWin()
-    : PrintingContext(),
+PrintingContextWin::PrintingContextWin(const std::string& app_locale)
+    : PrintingContext(app_locale),
       context_(NULL),
       dialog_box_(NULL),
       print_dialog_func_(&PrintDlgEx) {
diff --git a/printing/printing_context_win.h b/printing/printing_context_win.h
index 90fc738..7d3818f 100644
--- a/printing/printing_context_win.h
+++ b/printing/printing_context_win.h
@@ -19,7 +19,7 @@
 
 class PrintingContextWin : public PrintingContext {
  public:
-  PrintingContextWin();
+  explicit PrintingContextWin(const std::string& app_locale);
   ~PrintingContextWin();
 
   // PrintingContext implementation.
diff --git a/printing/printing_context_win_unittest.cc b/printing/printing_context_win_unittest.cc
index c43bb03b..874c62d 100644
--- a/printing/printing_context_win_unittest.cc
+++ b/printing/printing_context_win_unittest.cc
@@ -112,7 +112,7 @@
   settings.set_device_name(GetDefaultPrinter());
   // Initialize it.
   scoped_ptr<printing::PrintingContext> context(
-      printing::PrintingContext::Create());
+      printing::PrintingContext::Create(std::string()));
   EXPECT_EQ(printing::PrintingContext::OK, context->InitWithSettings(settings));
 
   // The print may lie to use and may not support world transformation.
@@ -127,7 +127,8 @@
   if (IsTestCaseDisabled())
     return;
 
-  printing::PrintingContextWin context;
+  std::string dummy_locale;
+  printing::PrintingContextWin context(dummy_locale);
   context.SetPrintDialog(&PrintDlgExMock);
   context.AskUserForSettings(
       NULL,