summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/printing/print_dialog_gtk.cc166
-rw-r--r--chrome/browser/printing/print_dialog_gtk.h7
-rw-r--r--printing/print_dialog_gtk_interface.h13
-rw-r--r--printing/print_settings_initializer_gtk.cc13
-rw-r--r--printing/printing_context_cairo.cc38
5 files changed, 200 insertions, 37 deletions
diff --git a/chrome/browser/printing/print_dialog_gtk.cc b/chrome/browser/printing/print_dialog_gtk.cc
index 4f549db..72a7c4c 100644
--- a/chrome/browser/printing/print_dialog_gtk.cc
+++ b/chrome/browser/printing/print_dialog_gtk.cc
@@ -10,6 +10,9 @@
#include <sys/stat.h>
#include <sys/types.h>
+#include <string>
+#include <vector>
+
#include "base/file_util.h"
#include "base/file_util_proxy.h"
#include "base/logging.h"
@@ -18,8 +21,64 @@
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "printing/metafile.h"
+#include "printing/print_job_constants.h"
#include "printing/print_settings_initializer_gtk.h"
+using printing::PageRanges;
+using printing::PrintSettings;
+
+namespace {
+
+// Helper class to track GTK printers.
+class GtkPrinterList {
+ public:
+ GtkPrinterList() : default_printer_(NULL) {
+ gtk_enumerate_printers((GtkPrinterFunc)SetPrinter, this, NULL, TRUE);
+ }
+
+ ~GtkPrinterList() {
+ for (std::vector<GtkPrinter*>::iterator it = printers_.begin();
+ it < printers_.end(); ++it) {
+ g_object_unref(*it);
+ }
+ }
+
+ GtkPrinter* default_printer() {
+ return default_printer_;
+ }
+
+ GtkPrinter* GetPrinterWithName(const char* name) {
+ if (!name || !*name)
+ return NULL;
+
+ for (std::vector<GtkPrinter*>::iterator it = printers_.begin();
+ it < printers_.end(); ++it) {
+ if (strcmp(name, gtk_printer_get_name(*it)) == 0) {
+ return *it;
+ }
+ }
+
+ return NULL;
+ }
+
+ private:
+ // Callback function used by gtk_enumerate_printers() to get all printer.
+ static bool SetPrinter(GtkPrinter* printer, GtkPrinterList* printer_list) {
+ if (gtk_printer_is_default(printer))
+ printer_list->default_printer_ = printer;
+
+ g_object_ref(printer);
+ printer_list->printers_.push_back(printer);
+
+ return false;
+ }
+
+ std::vector<GtkPrinter*> printers_;
+ GtkPrinter* default_printer_;
+};
+
+} // namespace
+
// static
printing::PrintDialogGtkInterface* PrintDialogGtk::CreatePrintDialog(
PrintingContextCairo* context) {
@@ -34,17 +93,15 @@ PrintDialogGtk::PrintDialogGtk(PrintingContextCairo* context)
gtk_settings_(NULL),
page_setup_(NULL),
printer_(NULL) {
- GtkWindow* parent = BrowserList::GetLastActive()->window()->GetNativeHandle();
-
- // TODO(estade): We need a window title here.
- dialog_ = gtk_print_unix_dialog_new(NULL, parent);
}
PrintDialogGtk::~PrintDialogGtk() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- gtk_widget_destroy(dialog_);
- dialog_ = NULL;
+ if (dialog_) {
+ gtk_widget_destroy(dialog_);
+ dialog_ = NULL;
+ }
if (gtk_settings_) {
g_object_unref(gtk_settings_);
gtk_settings_ = NULL;
@@ -59,12 +116,81 @@ PrintDialogGtk::~PrintDialogGtk() {
}
}
+void PrintDialogGtk::UseDefaultSettings() {
+ DCHECK(!save_document_event_.get());
+ DCHECK(!page_setup_);
+
+ // |gtk_settings_| is a new object.
+ gtk_settings_ = gtk_print_settings_new();
+
+ scoped_ptr<GtkPrinterList> printer_list(new GtkPrinterList);
+ printer_ = printer_list->default_printer();
+ if (printer_) {
+ g_object_ref(printer_);
+ gtk_print_settings_set_printer(gtk_settings_,
+ gtk_printer_get_name(printer_));
+#if GTK_CHECK_VERSION(2, 14, 0)
+ page_setup_ = gtk_printer_get_default_page_size(printer_);
+#endif
+ }
+
+ if (!page_setup_)
+ page_setup_ = gtk_page_setup_new();
+
+ // No page range to initialize for default settings.
+ PageRanges ranges_vector;
+ InitPrintSettings(ranges_vector);
+}
+
+bool PrintDialogGtk::UpdateSettings(const DictionaryValue& settings,
+ const printing::PageRanges& ranges) {
+ std::string printer_name;
+ settings.GetString(printing::kSettingPrinterName, &printer_name);
+
+ scoped_ptr<GtkPrinterList> printer_list(new GtkPrinterList);
+ printer_ = printer_list->GetPrinterWithName(printer_name.c_str());
+ if (!printer_)
+ return false;
+ g_object_ref(printer_);
+ gtk_print_settings_set_printer(gtk_settings_,
+ gtk_printer_get_name(printer_));
+
+ bool landscape;
+ if (!settings.GetBoolean(printing::kSettingLandscape, &landscape))
+ return false;
+
+ gtk_print_settings_set_orientation(
+ gtk_settings_,
+ landscape ? GTK_PAGE_ORIENTATION_LANDSCAPE :
+ GTK_PAGE_ORIENTATION_PORTRAIT);
+
+ int copies;
+ if (!settings.GetInteger(printing::kSettingCopies, &copies))
+ return false;
+ gtk_print_settings_set_n_copies(gtk_settings_, copies);
+
+ bool collate;
+ if (!settings.GetBoolean(printing::kSettingCollate, &collate))
+ return false;
+ gtk_print_settings_set_collate(gtk_settings_, collate);
+
+ // TODO(thestig) Color: gtk_print_settings_set_color() does not work.
+ // TODO(thestig) Duplex: gtk_print_settings_set_duplex() does not work.
+
+ InitPrintSettings(ranges);
+ return true;
+}
+
void PrintDialogGtk::ShowDialog(
PrintingContextCairo::PrintSettingsCallback* callback) {
DCHECK(!save_document_event_.get());
callback_ = callback;
+ GtkWindow* parent = BrowserList::GetLastActive()->window()->GetNativeHandle();
+ // TODO(estade): We need a window title here.
+ dialog_ = gtk_print_unix_dialog_new(NULL, parent);
+
// Set modal so user cannot focus the same tab and press print again.
gtk_window_set_modal(GTK_WINDOW(dialog_), TRUE);
@@ -120,17 +246,25 @@ void PrintDialogGtk::OnResponse(GtkWidget* dialog, int response_id) {
switch (response_id) {
case GTK_RESPONSE_OK: {
+ if (gtk_settings_)
+ g_object_unref(gtk_settings_);
gtk_settings_ = gtk_print_unix_dialog_get_settings(
GTK_PRINT_UNIX_DIALOG(dialog_));
+
+ if (printer_)
+ g_object_unref(printer_);
printer_ = gtk_print_unix_dialog_get_selected_printer(
GTK_PRINT_UNIX_DIALOG(dialog_));
g_object_ref(printer_);
+
+ if (page_setup_)
+ g_object_unref(page_setup_);
page_setup_ = gtk_print_unix_dialog_get_page_setup(
GTK_PRINT_UNIX_DIALOG(dialog_));
g_object_ref(page_setup_);
// Handle page ranges.
- printing::PageRanges ranges_vector;
+ PageRanges ranges_vector;
gint num_ranges;
GtkPageRange* gtk_range =
gtk_print_settings_get_page_ranges(gtk_settings_, &num_ranges);
@@ -144,7 +278,7 @@ void PrintDialogGtk::OnResponse(GtkWidget* dialog, int response_id) {
g_free(gtk_range);
}
- printing::PrintSettings settings;
+ PrintSettings settings;
printing::PrintSettingsInitializerGtk::InitPrintSettings(
gtk_settings_, page_setup_, ranges_vector, false, &settings);
context_->InitWithSettings(settings);
@@ -199,6 +333,15 @@ void PrintDialogGtk::SaveDocumentToDisk(const printing::Metafile* metafile,
void PrintDialogGtk::SendDocumentToPrinter(const string16& document_name) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ // If |printer_| is NULL then somehow the GTK printer list changed out under
+ // us. In which case, just bail out.
+ if (!printer_) {
+ // Matches AddRef() in PrintDocument();
+ Release();
+ return;
+ }
+
GtkPrintJob* print_job = gtk_print_job_new(
UTF16ToUTF8(document_name).c_str(),
printer_,
@@ -228,3 +371,10 @@ void PrintDialogGtk::OnJobCompleted(GtkPrintJob* print_job, GError* error) {
// Printing finished. Matches AddRef() in PrintDocument();
Release();
}
+
+void PrintDialogGtk::InitPrintSettings(const PageRanges& page_ranges) {
+ PrintSettings settings;
+ printing::PrintSettingsInitializerGtk::InitPrintSettings(
+ gtk_settings_, page_setup_, page_ranges, false, &settings);
+ context_->InitWithSettings(settings);
+}
diff --git a/chrome/browser/printing/print_dialog_gtk.h b/chrome/browser/printing/print_dialog_gtk.h
index c6d999f..7ec804f 100644
--- a/chrome/browser/printing/print_dialog_gtk.h
+++ b/chrome/browser/printing/print_dialog_gtk.h
@@ -38,6 +38,9 @@ class PrintDialogGtk
PrintingContextCairo* context);
// printing::PrintDialogGtkInterface implementation.
+ virtual void UseDefaultSettings();
+ virtual bool UpdateSettings(const DictionaryValue& settings,
+ const printing::PageRanges& ranges);
virtual void ShowDialog(
PrintingContextCairo::PrintSettingsCallback* callback);
virtual void PrintDocument(const printing::Metafile* metafile,
@@ -68,6 +71,10 @@ class PrintDialogGtk
GError* error);
void OnJobCompleted(GtkPrintJob* print_job, GError* error);
+ // Helper function for initializing |context_|'s PrintSettings with a given
+ // set of |page_ranges|.
+ void InitPrintSettings(const printing::PageRanges& page_ranges);
+
// Printing dialog callback.
PrintingContextCairo::PrintSettingsCallback* callback_;
PrintingContextCairo* context_;
diff --git a/printing/print_dialog_gtk_interface.h b/printing/print_dialog_gtk_interface.h
index dab0c9c..c47f978 100644
--- a/printing/print_dialog_gtk_interface.h
+++ b/printing/print_dialog_gtk_interface.h
@@ -17,7 +17,18 @@ class Metafile;
// correct without exposing those requirements to printing/.
class PrintDialogGtkInterface {
public:
- // Shows the dialog and handles the response with |callback|.
+ // Tell the dialog to use the default print setting.
+ virtual void UseDefaultSettings() = 0;
+
+ // Update the dialog to use |settings| and |ranges|, where |settings| is a
+ // dictionary of settings with possible keys from
+ // printing/print_job_constants.h. Only used when printing without the system
+ // print dialog. E.g. for Print Preview. Returns false on error.
+ virtual bool UpdateSettings(const DictionaryValue& settings,
+ const PageRanges& ranges) = 0;
+
+ // Shows the dialog and handles the response with |callback|. Only used when
+ // printing with the native print dialog.
virtual void ShowDialog(
PrintingContextCairo::PrintSettingsCallback* callback) = 0;
diff --git a/printing/print_settings_initializer_gtk.cc b/printing/print_settings_initializer_gtk.cc
index a42561ba..9b8915c 100644
--- a/printing/print_settings_initializer_gtk.cc
+++ b/printing/print_settings_initializer_gtk.cc
@@ -33,9 +33,6 @@ void PrintSettingsInitializerGtk::InitPrintSettings(
print_settings->ranges = new_ranges;
print_settings->selection_only = print_selection_only;
- GtkPageOrientation orientation = gtk_print_settings_get_orientation(settings);
- print_settings->set_landscape(orientation == GTK_PAGE_ORIENTATION_LANDSCAPE);
-
gfx::Size physical_size_device_units;
gfx::Rect printable_area_device_units;
int dpi = gtk_print_settings_get_resolution(settings);
@@ -68,6 +65,16 @@ void PrintSettingsInitializerGtk::InitPrintSettings(
print_settings->SetPrinterPrintableArea(physical_size_device_units,
printable_area_device_units,
dpi);
+
+ // Note: With the normal GTK print dialog, when the user selects the landscape
+ // orientation, all that does is change the paper size. Which seems to be
+ // enough to render the right output and send it to the printer.
+ // The orientation value stays as portrait and does not actually affect
+ // printing.
+ // Thus this is only useful in print preview mode, where we manually set the
+ // orientation and change the paper size ourselves.
+ GtkPageOrientation orientation = gtk_print_settings_get_orientation(settings);
+ print_settings->SetOrientation(orientation == GTK_PAGE_ORIENTATION_LANDSCAPE);
}
const double PrintSettingsInitializerGtk::kTopMarginInInch = 0.25;
diff --git a/printing/printing_context_cairo.cc b/printing/printing_context_cairo.cc
index 6b24063..81d8696 100644
--- a/printing/printing_context_cairo.cc
+++ b/printing/printing_context_cairo.cc
@@ -8,11 +8,11 @@
#include "base/values.h"
#include "printing/metafile.h"
#include "printing/print_job_constants.h"
-#include "printing/print_settings_initializer_gtk.h"
#include "printing/units.h"
#if defined(OS_CHROMEOS)
#include <unicode/ulocdata.h>
+#include "printing/print_settings_initializer_gtk.h"
#else
#include <gtk/gtk.h>
#include <gtk/gtkprintunixdialog.h>
@@ -78,8 +78,6 @@ void PrintingContextCairo::AskUserForSettings(
#if defined(OS_CHROMEOS)
callback->Run(OK);
#else
- print_dialog_ = create_dialog_func_(this);
- print_dialog_->AddRefToDialog();
print_dialog_->ShowDialog(callback);
#endif // defined(OS_CHROMEOS)
}
@@ -128,20 +126,12 @@ PrintingContext::Result PrintingContextCairo::UseDefaultSettings() {
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));
- GtkPageSetup* page_setup =
- gtk_print_unix_dialog_get_page_setup(GTK_PRINT_UNIX_DIALOG(dialog));
-
- PageRanges ranges_vector; // Nothing to initialize for default settings.
- PrintSettingsInitializerGtk::InitPrintSettings(
- settings, page_setup, ranges_vector, false, &settings_);
-
- g_object_unref(settings);
- // |page_setup| is owned by dialog, so it does not need to be unref'ed.
- gtk_widget_destroy(dialog);
+#else
+ if (!print_dialog_) {
+ print_dialog_ = create_dialog_func_(this);
+ print_dialog_->AddRefToDialog();
+ }
+ print_dialog_->UseDefaultSettings();
#endif // defined(OS_CHROMEOS)
return OK;
@@ -149,19 +139,17 @@ PrintingContext::Result PrintingContextCairo::UseDefaultSettings() {
PrintingContext::Result PrintingContextCairo::UpdatePrintSettings(
const DictionaryValue& job_settings, const PageRanges& ranges) {
+#if defined(OS_CHROMEOS)
+ NOTIMPLEMENTED();
+ return OK;
+#else
DCHECK(!in_print_job_);
- bool landscape;
- if (!job_settings.GetBoolean(kSettingLandscape, &landscape))
+ if (!print_dialog_->UpdateSettings(job_settings, ranges))
return OnError();
- settings_.SetOrientation(landscape);
- settings_.ranges = ranges;
-
- // TODO(kmadhusu): Update other print settings such as number of copies,
- // collate, duplex printing, etc.,
-
return OK;
+#endif
}
PrintingContext::Result PrintingContextCairo::InitWithSettings(