diff options
author | kmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-13 00:40:39 +0000 |
---|---|---|
committer | kmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-13 00:40:39 +0000 |
commit | 63313aed25758c7a634414f88b6d0549d572c155 (patch) | |
tree | 64da60df5fb0373fc5b7bf8ac85fcfc3625f1165 | |
parent | 611b6f634dbdbc87a40810cc60f5713f4d5eb434 (diff) | |
download | chromium_src-63313aed25758c7a634414f88b6d0549d572c155.zip chromium_src-63313aed25758c7a634414f88b6d0549d572c155.tar.gz chromium_src-63313aed25758c7a634414f88b6d0549d572c155.tar.bz2 |
Reland 105087: PrintPreview: Fix printer color settings issues based on printer ppd/schema info.
Show/Hide the color options based on printer ppd/schema information. Some printers does not provide sufficient information in the printer schema/ppd regarding the color settings and they use custom advance settings to print in black & white/greyscale. In those cases, users need to print using native dialog in order to set these advance color settings.
BUG=93811, 93490, 87344, 96658, 98768
TEST= Please refer to bug description.
Review URL: http://codereview.chromium.org/8138020
Review URL: http://codereview.chromium.org/8226024
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@105217 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/printing/print_dialog_gtk.cc | 24 | ||||
-rw-r--r-- | chrome/browser/printing/print_system_task_proxy.cc | 543 | ||||
-rw-r--r-- | chrome/browser/printing/print_system_task_proxy.h | 73 | ||||
-rw-r--r-- | chrome/browser/printing/print_system_task_proxy_unittest.cc (renamed from chrome/browser/ui/webui/print_preview_handler_unittest.cc) | 7 | ||||
-rw-r--r-- | chrome/browser/resources/print_preview/color_settings.js | 26 | ||||
-rw-r--r-- | chrome/browser/resources/print_preview/print_preview.js | 5 | ||||
-rw-r--r-- | chrome/browser/ui/webui/print_preview_handler.cc | 355 | ||||
-rw-r--r-- | chrome/browser/ui/webui/print_preview_handler.h | 18 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 2 | ||||
-rw-r--r-- | printing/print_job_constants.cc | 18 | ||||
-rw-r--r-- | printing/print_job_constants.h | 40 | ||||
-rw-r--r-- | printing/print_settings.cc | 96 | ||||
-rw-r--r-- | printing/print_settings.h | 11 | ||||
-rw-r--r-- | printing/printing_context_mac.mm | 20 |
15 files changed, 832 insertions, 408 deletions
diff --git a/chrome/browser/printing/print_dialog_gtk.cc b/chrome/browser/printing/print_dialog_gtk.cc index 557fbb4..e952484 100644 --- a/chrome/browser/printing/print_dialog_gtk.cc +++ b/chrome/browser/printing/print_dialog_gtk.cc @@ -28,12 +28,6 @@ using printing::PrintSettings; namespace { -// CUPS ColorModel attribute and values. -const char kCMYK[] = "CMYK"; -const char kCUPSColorModel[] = "cups-ColorModel"; -const char kColor[] = "Color"; -const char kGrayscale[] = "Grayscale"; - // CUPS Duplex attribute and values. const char kCUPSDuplex[] = "cups-Duplex"; const char kDuplexNone[] = "None"; @@ -193,19 +187,11 @@ bool PrintDialogGtk::UpdateSettings(const DictionaryValue& settings, gtk_print_settings_set_n_copies(gtk_settings_, copies); gtk_print_settings_set_collate(gtk_settings_, collate); - const char* color_mode; - switch (color) { - case printing::COLOR: - color_mode = kColor; - break; - case printing::CMYK: - color_mode = kCMYK; - break; - default: - color_mode = kGrayscale; - break; - } - gtk_print_settings_set(gtk_settings_, kCUPSColorModel, color_mode); + std::string color_value; + std::string color_setting_name; + printing::GetColorModelForMode(color, &color_setting_name, &color_value); + gtk_print_settings_set(gtk_settings_, color_setting_name.c_str(), + color_value.c_str()); if (duplex_mode != printing::UNKNOWN_DUPLEX_MODE) { const char* cups_duplex_mode = NULL; diff --git a/chrome/browser/printing/print_system_task_proxy.cc b/chrome/browser/printing/print_system_task_proxy.cc new file mode 100644 index 0000000..c1811f5 --- /dev/null +++ b/chrome/browser/printing/print_system_task_proxy.cc @@ -0,0 +1,543 @@ +// Copyright (c) 2011 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 "chrome/browser/printing/print_system_task_proxy.h" + +#include <ctype.h> + +#include <string> +#include <vector> + +#include "base/bind.h" +#include "base/metrics/histogram.h" +#include "base/string_split.h" +#include "base/string_util.h" +#include "base/values.h" +#include "printing/backend/print_backend.h" +#include "printing/print_job_constants.h" +#include "printing/print_settings.h" + +#if defined(USE_CUPS) +#include <cups/cups.h> +#include <cups/ppd.h> + +#include "base/file_util.h" +#endif + +#if defined(USE_CUPS) && !defined(OS_MACOSX) +namespace printing_internal { + +void parse_lpoptions(const FilePath& filepath, const std::string& printer_name, + int* num_options, cups_option_t** options) { + std::string content; + if (!file_util::ReadFileToString(filepath, &content)) + return; + + const char kDest[] = "dest"; + const char kDefault[] = "default"; + size_t kDestLen = sizeof(kDest) - 1; + size_t kDefaultLen = sizeof(kDefault) - 1; + std::vector <std::string> lines; + base::SplitString(content, '\n', &lines); + + for (size_t i = 0; i < lines.size(); ++i) { + std::string line = lines[i]; + if (line.empty()) + continue; + + if (base::strncasecmp (line.c_str(), kDefault, kDefaultLen) == 0 && + isspace(line[kDefaultLen])) { + line = line.substr(kDefaultLen); + } else if (base::strncasecmp (line.c_str(), kDest, kDestLen) == 0 && + isspace(line[kDestLen])) { + line = line.substr(kDestLen); + } else { + continue; + } + + TrimWhitespaceASCII(line, TRIM_ALL, &line); + if (line.empty()) + continue; + + size_t space_found = line.find(' '); + if (space_found == std::string::npos) + continue; + + std::string name = line.substr(0, space_found); + if (name.empty()) + continue; + + if (base::strncasecmp(printer_name.c_str(), name.c_str(), + name.length()) != 0) { + continue; // This is not the required printer. + } + + line = line.substr(space_found + 1); + TrimWhitespaceASCII(line, TRIM_ALL, &line); // Remove extra spaces. + if (line.empty()) + continue; + // Parse the selected printer custom options. + *num_options = cupsParseOptions(line.c_str(), 0, options); + } +} + +void mark_lpoptions(const std::string& printer_name, ppd_file_t** ppd) { + cups_option_t* options = NULL; + int num_options = 0; + ppdMarkDefaults(*ppd); + + const char kSystemLpOptionPath[] = "/etc/cups/lpoptions"; + const char kUserLpOptionPath[] = ".cups/lpoptions"; + + std::vector<FilePath> file_locations; + file_locations.push_back(FilePath(kSystemLpOptionPath)); + file_locations.push_back(FilePath( + file_util::GetHomeDir().Append(kUserLpOptionPath))); + + for (std::vector<FilePath>::const_iterator it = file_locations.begin(); + it != file_locations.end(); ++it) { + num_options = 0; + options = NULL; + parse_lpoptions(*it, printer_name, &num_options, &options); + if (num_options > 0 && options) { + cupsMarkOptions(*ppd, num_options, options); + cupsFreeOptions(num_options, options); + } + } +} + +} // printing_internal namespace +#endif + +namespace { + +const char kDisableColorOption[] = "disableColorOption"; +const char kSetColorAsDefault[] = "setColorAsDefault"; +const char kSetDuplexAsDefault[] = "setDuplexAsDefault"; +const char kPrinterColorModelForBlack[] = "printerColorModelForBlack"; +const char kPrinterColorModelForColor[] = "printerColorModelForColor"; +const char kPrinterDefaultDuplexValue[] = "printerDefaultDuplexValue"; + +#if defined(OS_WIN) +const char kPskColor[] = "psk:Color"; +const char kPskGray[] = "psk:Grayscale"; +const char kPskMonochrome[] = "psk:Monochrome"; +const char kPskDuplexFeature[] = "psk:JobDuplexAllDocumentsContiguously"; +const char kPskTwoSided[] = "psk:TwoSided"; +#elif defined(USE_CUPS) +const char kColorDevice[] = "ColorDevice"; +const char kColorModel[] = "ColorModel"; +const char kColorMode[] = "ColorMode"; +const char kProcessColorModel[] = "ProcessColorModel"; +const char kPrintoutMode[] = "PrintoutMode"; +const char kDraftGray[] = "Draft.Gray"; +const char kHighGray[] = "High.Gray"; + +const char kDuplex[] = "Duplex"; +const char kDuplexNone[] = "None"; + +bool getBasicColorModelSettings( + ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color, + bool* color_is_default) { + ppd_option_t* color_model = ppdFindOption(ppd, kColorModel); + if (!color_model) + return false; + + if (ppdFindChoice(color_model, printing::kBlack)) + *color_model_for_black = printing::BLACK; + else if (ppdFindChoice(color_model, printing::kGray)) + *color_model_for_black = printing::GRAY; + + if (ppdFindChoice(color_model, printing::kColor)) + *color_model_for_color = printing::COLOR; + else if (ppdFindChoice(color_model, printing::kCMYK)) + *color_model_for_color = printing::CMYK; + else if (ppdFindChoice(color_model, printing::kRGB)) + *color_model_for_color = printing::RGB; + else if (ppdFindChoice(color_model, printing::kRGBA)) + *color_model_for_color = printing::RGBA; + else if (ppdFindChoice(color_model, printing::kRGB16)) + *color_model_for_color = printing::RGB16; + else if (ppdFindChoice(color_model, printing::kCMY)) + *color_model_for_color = printing::CMY; + else if (ppdFindChoice(color_model, printing::kKCMY)) + *color_model_for_color = printing::KCMY; + else if (ppdFindChoice(color_model, printing::kCMY_K)) + *color_model_for_color = printing::CMY_K; + + ppd_choice_t* marked_choice = ppdFindMarkedChoice(ppd, kColorModel); + if (!marked_choice) + marked_choice = ppdFindChoice(color_model, color_model->defchoice); + + if (marked_choice) { + *color_is_default = + (base::strcasecmp(marked_choice->choice, printing::kBlack) != 0) && + (base::strcasecmp(marked_choice->choice, printing::kGray) != 0); + } + return true; +} + +bool getPrintOutModeColorSettings( + ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color, + bool* color_is_default) { + ppd_option_t* printout_mode = ppdFindOption(ppd, kPrintoutMode); + if (!printout_mode) + return false; + + *color_model_for_color = printing::PRINTOUTMODE_NORMAL; + *color_model_for_black = printing::PRINTOUTMODE_NORMAL; + + // Check to see if NORMAL_GRAY value is supported by PrintoutMode. + // If NORMAL_GRAY is not supported, NORMAL value is used to + // represent grayscale. If NORMAL_GRAY is supported, NORMAL is used to + // represent color. + if (ppdFindChoice(printout_mode, printing::kNormalGray)) + *color_model_for_black = printing::PRINTOUTMODE_NORMAL_GRAY; + + // Get the default marked choice to identify the default color setting + // value. + ppd_choice_t* printout_mode_choice = ppdFindMarkedChoice(ppd, kPrintoutMode); + if (!printout_mode_choice) { + printout_mode_choice = ppdFindChoice(printout_mode, + printout_mode->defchoice); + } + if (printout_mode_choice) { + if ((base::strcasecmp(printout_mode_choice->choice, + printing::kNormalGray) == 0) || + (base::strcasecmp(printout_mode_choice->choice, kHighGray) == 0) || + (base::strcasecmp(printout_mode_choice->choice, kDraftGray) == 0)) { + *color_model_for_black = printing::PRINTOUTMODE_NORMAL_GRAY; + *color_is_default = false; + } + } + return true; +} + +bool getColorModeSettings( + ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color, + bool* color_is_default) { + // Samsung printers use "ColorMode" attribute in their ppds. + ppd_option_t* color_mode_option = ppdFindOption(ppd, kColorMode); + if (!color_mode_option) + return false; + + if (ppdFindChoice(color_mode_option, printing::kColor)) + *color_model_for_color = printing::COLORMODE_COLOR; + + if (ppdFindChoice(color_mode_option, printing::kMonochrome)) + *color_model_for_black = printing::COLORMODE_MONOCHROME; + + ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kColorMode); + if (!mode_choice) { + mode_choice = ppdFindChoice(color_mode_option, + color_mode_option->defchoice); + } + + if (mode_choice) { + *color_is_default = + (base::strcasecmp(mode_choice->choice, printing::kColor) == 0); + } + return true; +} + +bool getHPColorSettings( + ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color, + bool* color_is_default) { + // HP printers use "Color/Color Model" attribute in their ppds. + ppd_option_t* color_mode_option = ppdFindOption(ppd, printing::kColor); + if (!color_mode_option) + return false; + + if (ppdFindChoice(color_mode_option, printing::kColor)) + *color_model_for_color = printing::HP_COLOR_COLOR; + if (ppdFindChoice(color_mode_option, printing::kBlack)) + *color_model_for_black = printing::HP_COLOR_BLACK; + + ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kColorMode); + if (!mode_choice) { + mode_choice = ppdFindChoice(color_mode_option, + color_mode_option->defchoice); + } + if (mode_choice) { + *color_is_default = + (base::strcasecmp(mode_choice->choice, printing::kColor) == 0); + } + return true; +} + +bool getProcessColorModelSettings( + ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color, + bool* color_is_default) { + // Canon printers use "ProcessColorModel" attribute in their ppds. + ppd_option_t* color_mode_option = ppdFindOption(ppd, kProcessColorModel); + if (!color_mode_option) + return false; + + if (ppdFindChoice(color_mode_option, printing::kRGB)) + *color_model_for_color = printing::PROCESSCOLORMODEL_RGB; + else if (ppdFindChoice(color_mode_option, printing::kCMYK)) + *color_model_for_color = printing::PROCESSCOLORMODEL_CMYK; + + if (ppdFindChoice(color_mode_option, printing::kGreyscale)) + *color_model_for_black = printing::PROCESSCOLORMODEL_GREYSCALE; + + ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kProcessColorModel); + if (!mode_choice) { + mode_choice = ppdFindChoice(color_mode_option, + color_mode_option->defchoice); + } + + if (mode_choice) { + *color_is_default = + (base::strcasecmp(mode_choice->choice, printing::kGreyscale) != 0); + } + return true; +} +#endif + +} // namespace + +PrintSystemTaskProxy::PrintSystemTaskProxy( + const base::WeakPtr<PrintPreviewHandler>& handler, + printing::PrintBackend* print_backend, + bool has_logged_printers_count) + : handler_(handler), + print_backend_(print_backend), + has_logged_printers_count_(has_logged_printers_count) { +} + +PrintSystemTaskProxy::~PrintSystemTaskProxy() { +} + +void PrintSystemTaskProxy::GetDefaultPrinter() { + VLOG(1) << "Get default printer start"; + StringValue* default_printer = NULL; + if (PrintPreviewHandler::last_used_printer_name_ == NULL) { + default_printer = new StringValue( + print_backend_->GetDefaultPrinterName()); + } else { + default_printer = new StringValue( + *PrintPreviewHandler::last_used_printer_name_); + } + std::string default_printer_string; + default_printer->GetAsString(&default_printer_string); + VLOG(1) << "Get default printer finished, found: " + << default_printer_string; + + StringValue* cloud_print_data = NULL; + if (PrintPreviewHandler::last_used_printer_cloud_print_data_ != NULL) { + cloud_print_data = new StringValue( + *PrintPreviewHandler::last_used_printer_cloud_print_data_); + } else { + cloud_print_data = new StringValue(""); + } + + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&PrintSystemTaskProxy::SendDefaultPrinter, this, + default_printer, cloud_print_data)); +} + +void PrintSystemTaskProxy::SendDefaultPrinter( + const StringValue* default_printer, const StringValue* cloud_print_data) { + if (handler_) + handler_->SendDefaultPrinter(*default_printer, *cloud_print_data); + delete default_printer; +} + +void PrintSystemTaskProxy::EnumeratePrinters() { + VLOG(1) << "Enumerate printers start"; + ListValue* printers = new ListValue; + printing::PrinterList printer_list; + print_backend_->EnumeratePrinters(&printer_list); + + if (!has_logged_printers_count_) { + // Record the total number of printers. + UMA_HISTOGRAM_COUNTS("PrintPreview.NumberOfPrinters", + printer_list.size()); + } + int i = 0; + for (printing::PrinterList::iterator iter = printer_list.begin(); + iter != printer_list.end(); ++iter, ++i) { + DictionaryValue* printer_info = new DictionaryValue; + std::string printerName; +#if defined(OS_MACOSX) + // On Mac, |iter->printer_description| specifies the printer name and + // |iter->printer_name| specifies the device name / printer queue name. + printerName = iter->printer_description; +#else + printerName = iter->printer_name; +#endif + printer_info->SetString(printing::kSettingPrinterName, printerName); + printer_info->SetString(printing::kSettingDeviceName, iter->printer_name); + printers->Append(printer_info); + } + VLOG(1) << "Enumerate printers finished, found " << i << " printers"; + + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&PrintSystemTaskProxy::SetupPrinterList, this, printers)); +} + +void PrintSystemTaskProxy::SetupPrinterList(ListValue* printers) { + if (handler_) + handler_->SetupPrinterList(*printers); + delete printers; +} + +void PrintSystemTaskProxy::GetPrinterCapabilities( + const std::string& printer_name) { + VLOG(1) << "Get printer capabilities start for " << printer_name; + printing::PrinterCapsAndDefaults printer_info; + + bool set_color_as_default = false; + bool disable_color_options = true; + bool set_duplex_as_default = false; + int printer_color_space_for_color = printing::UNKNOWN_COLOR_MODEL; + int printer_color_space_for_black = printing::UNKNOWN_COLOR_MODEL; + int default_duplex_setting_value = printing::UNKNOWN_DUPLEX_MODE; + if (!print_backend_->GetPrinterCapsAndDefaults(printer_name, + &printer_info)) { + return; + } + +#if defined(USE_CUPS) + FilePath ppd_file_path; + if (!file_util::CreateTemporaryFile(&ppd_file_path)) + return; + + int data_size = printer_info.printer_capabilities.length(); + if (data_size != file_util::WriteFile( + ppd_file_path, + printer_info.printer_capabilities.data(), + data_size)) { + file_util::Delete(ppd_file_path, false); + return; + } + + ppd_file_t* ppd = ppdOpenFile(ppd_file_path.value().c_str()); + if (ppd) { +#if !defined(OS_MACOSX) + printing_internal::mark_lpoptions(printer_name, &ppd); +#endif + ppd_choice_t* duplex_choice = ppdFindMarkedChoice(ppd, kDuplex); + if (duplex_choice) { + ppd_option_t* option = ppdFindOption(ppd, kDuplex); + if (option) + duplex_choice = ppdFindChoice(option, option->defchoice); + } + + if (duplex_choice) { + if (base::strcasecmp(duplex_choice->choice, kDuplexNone) != 0) { + set_duplex_as_default = true; + default_duplex_setting_value = printing::LONG_EDGE; + } else { + default_duplex_setting_value = printing::SIMPLEX; + } + } + + bool is_color_device = false; + ppd_attr_t* attr = ppdFindAttr(ppd, kColorDevice, NULL); + if (attr && attr->value) + is_color_device = ppd->color_device; + disable_color_options = !is_color_device; + set_color_as_default = is_color_device; + + if (!((is_color_device && getBasicColorModelSettings( + ppd, &printer_color_space_for_black, + &printer_color_space_for_color, &set_color_as_default)) || + getPrintOutModeColorSettings( + ppd, &printer_color_space_for_black, + &printer_color_space_for_color, &set_color_as_default) || + getColorModeSettings( + ppd, &printer_color_space_for_black, + &printer_color_space_for_color, &set_color_as_default) || + getHPColorSettings( + ppd, &printer_color_space_for_black, + &printer_color_space_for_color, &set_color_as_default) || + getProcessColorModelSettings( + ppd, &printer_color_space_for_black, + &printer_color_space_for_color, &set_color_as_default))) { + VLOG(1) << "Unknown printer color model"; + } + ppdClose(ppd); + } + file_util::Delete(ppd_file_path, false); +#elif defined(OS_WIN) + // According to XPS 1.0 spec, only color printers have psk:Color. + // Therefore we don't need to parse the whole XML file, we just need to + // search the string. The spec can be found at: + // http://msdn.microsoft.com/en-us/windows/hardware/gg463431. + if (printer_info.printer_capabilities.find(kPskColor) != std::string::npos) + printer_color_space_for_color = printing::COLOR; + + if ((printer_info.printer_capabilities.find(kPskGray) != + std::string::npos) || + (printer_info.printer_capabilities.find(kPskMonochrome) != + std::string::npos)) { + printer_color_space_for_black = printing::GRAY; + } + set_color_as_default = + (printer_info.printer_defaults.find(kPskColor) != std::string::npos); + + set_duplex_as_default = + (printer_info.printer_defaults.find(kPskDuplexFeature) != + std::string::npos) && + (printer_info.printer_defaults.find(kPskTwoSided) != + std::string::npos); + + if (printer_info.printer_defaults.find(kPskDuplexFeature) != + std::string::npos) { + if (printer_info.printer_defaults.find(kPskTwoSided) != + std::string::npos) { + default_duplex_setting_value = printing::LONG_EDGE; + } else { + default_duplex_setting_value = printing::SIMPLEX; + } + } +#else + NOTIMPLEMENTED(); +#endif + disable_color_options = !printer_color_space_for_color || + !printer_color_space_for_black || + (printer_color_space_for_color == + printer_color_space_for_black); + + DictionaryValue settings_info; + settings_info.SetBoolean(kDisableColorOption, disable_color_options); + if (printer_color_space_for_color == printing::UNKNOWN_COLOR_MODEL) + printer_color_space_for_color = printing::COLOR; + + if (printer_color_space_for_black == printing::UNKNOWN_COLOR_MODEL) + printer_color_space_for_black = printing::GRAY; + + if (disable_color_options || + PrintPreviewHandler::last_used_color_model_ == + printing::UNKNOWN_COLOR_MODEL) { + settings_info.SetBoolean(kSetColorAsDefault, set_color_as_default); + } else { + settings_info.SetBoolean(kSetColorAsDefault, + printing::isColorModelSelected( + PrintPreviewHandler::last_used_color_model_)); + } + + settings_info.SetBoolean(kSetDuplexAsDefault, set_duplex_as_default); + settings_info.SetInteger(kPrinterColorModelForColor, + printer_color_space_for_color); + settings_info.SetInteger(kPrinterColorModelForBlack, + printer_color_space_for_black); + settings_info.SetInteger(kPrinterDefaultDuplexValue, + default_duplex_setting_value); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&PrintSystemTaskProxy::SendPrinterCapabilities, this, + settings_info.DeepCopy())); +} + +void PrintSystemTaskProxy::SendPrinterCapabilities( + DictionaryValue* settings_info) { + if (handler_) + handler_->SendPrinterCapabilities(*settings_info); + delete settings_info; +} diff --git a/chrome/browser/printing/print_system_task_proxy.h b/chrome/browser/printing/print_system_task_proxy.h new file mode 100644 index 0000000..8d5b00c --- /dev/null +++ b/chrome/browser/printing/print_system_task_proxy.h @@ -0,0 +1,73 @@ +// Copyright (c) 2011 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 CHROME_BROWSER_PRINTING_PRINT_SYSTEM_TASK_PROXY_H_ +#define CHROME_BROWSER_PRINTING_PRINT_SYSTEM_TASK_PROXY_H_ +#pragma once + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "build/build_config.h" +#include "chrome/browser/ui/webui/print_preview_handler.h" +#include "content/browser/browser_thread.h" + +namespace base { +class DictionaryValue; +class FundamentalValue; +class StringValue; +} + +namespace printing { +class PrintBackend; +} + +#if defined(UNIT_TEST) && defined(USE_CUPS) && !defined(OS_MACOSX) +typedef struct cups_option_s cups_option_t; + +namespace printing_internal { +// Helper function to parse the lpoptions custom settings. |num_options| and +// |options| will be updated if the custom settings for |printer_name| are +// found, otherwise nothing is done. +// NOTE: This function is declared here so it can be exposed for unit testing. +void parse_lpoptions(const FilePath& filepath, const std::string& printer_name, + int* num_options, cups_option_t** options); +} // namespace printing_internal + +#endif + +class PrintSystemTaskProxy + : public base::RefCountedThreadSafe<PrintSystemTaskProxy, + BrowserThread::DeleteOnUIThread> { + public: + PrintSystemTaskProxy(const base::WeakPtr<PrintPreviewHandler>& handler, + printing::PrintBackend* print_backend, + bool has_logged_printers_count); + + void GetDefaultPrinter(); + + void EnumeratePrinters(); + + void GetPrinterCapabilities(const std::string& printer_name); + + private: + friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; + friend class DeleteTask<PrintSystemTaskProxy>; + + void SendDefaultPrinter(const base::StringValue* default_printer, + const base::StringValue* cloud_print_data); + void SetupPrinterList(base::ListValue* printers); + void SendPrinterCapabilities(base::DictionaryValue* settings_info); + + ~PrintSystemTaskProxy(); + + base::WeakPtr<PrintPreviewHandler> handler_; + + scoped_refptr<printing::PrintBackend> print_backend_; + + bool has_logged_printers_count_; + + DISALLOW_COPY_AND_ASSIGN(PrintSystemTaskProxy); +}; + +#endif // CHROME_BROWSER_PRINTING_PRINT_SYSTEM_TASK_PROXY_H_ diff --git a/chrome/browser/ui/webui/print_preview_handler_unittest.cc b/chrome/browser/printing/print_system_task_proxy_unittest.cc index c4fc995..836baa3 100644 --- a/chrome/browser/ui/webui/print_preview_handler_unittest.cc +++ b/chrome/browser/printing/print_system_task_proxy_unittest.cc @@ -11,7 +11,8 @@ #include "base/file_path.h" #include "base/file_util.h" #include "base/scoped_temp_dir.h" -#include "chrome/browser/ui/webui/print_preview_handler.h" +#include "chrome/browser/printing/print_system_task_proxy.h" +#include "printing/backend/print_backend.h" #include "testing/gtest/include/gtest/gtest.h" namespace { @@ -45,7 +46,7 @@ void verifyOptionValue(ppd_file_t* ppd, using printing_internal::parse_lpoptions; // Test to verify that lpoption custom settings are marked on the ppd file. -TEST(PrintPreviewHandlerTest, MarkLpoptionsInPPD) { +TEST(PrintSystemTaskProxyTest, MarkLpoptionsInPPD) { const std::string kColorModel = "ColorModel"; const std::string kBlack = "Black"; const std::string kGray = "Gray"; @@ -152,7 +153,7 @@ TEST(PrintPreviewHandlerTest, MarkLpoptionsInPPD) { } // Test the lpoption parsing code. -TEST(PrintPreviewHandlerTest, ParseLpoptionData) { +TEST(PrintSystemTaskProxyTest, ParseLpoptionData) { // Specifies the user lpoption data. std::string user_lpoptions; diff --git a/chrome/browser/resources/print_preview/color_settings.js b/chrome/browser/resources/print_preview/color_settings.js index dc02ab0..9289c9f 100644 --- a/chrome/browser/resources/print_preview/color_settings.js +++ b/chrome/browser/resources/print_preview/color_settings.js @@ -14,12 +14,13 @@ cr.define('print_preview', function() { this.colorOption_ = $('color-option'); this.colorRadioButton_ = $('color'); this.bwRadioButton_ = $('bw'); - this.GRAY = 1; - this.COLOR = 2; - this.CMYK = 3; // cmyk - Cyan, magenta, yellow, black - this.printerColorModelForColor_ = this.COLOR; + + this.printerColorModelForColor_ = ColorSettings.COLOR; + this.printerColorModelForBlack_ = ColorSettings.GRAY; } + ColorSettings.GRAY = 1; + ColorSettings.COLOR = 2; cr.addSingletonGetter(ColorSettings); ColorSettings.prototype = { @@ -40,13 +41,12 @@ cr.define('print_preview', function() { }, /** - * Returns the color mode for print preview. - * @return {Number} Returns the printer color space + * @return {number} The color mode for print preview. */ get colorMode() { - if (this.bwRadioButton_.checked) - return this.GRAY; - return this.printerColorModelForColor_; + return this.bwRadioButton_.checked ? + this.printerColorModelForBlack_: + this.printerColorModelForColor_; }, /** @@ -79,13 +79,19 @@ cr.define('print_preview', function() { var setColorAsDefault = e.printerCapabilities.setColorAsDefault; this.printerColorModelForColor_ = e.printerCapabilities.printerColorModelForColor; + if (e.printerCapabilities.printerColorModelForBlack) { + this.printerColorModelForBlack_ = + e.printerCapabilities.printerColorModelForBlack; + } else { + this.printerColorModelForBlack_ = ColorSettings.GRAY; + } this.colorRadioButton_.checked = setColorAsDefault; this.bwRadioButton_.checked = !setColorAsDefault; setColor(this.colorRadioButton_.checked); }, /** - * Listener executing when a PDFLoaded event occurs. + * Executes when a PDFLoaded event occurs. * @private */ onPDFLoaded_: function() { diff --git a/chrome/browser/resources/print_preview/print_preview.js b/chrome/browser/resources/print_preview/print_preview.js index 725ba39..047db6e 100644 --- a/chrome/browser/resources/print_preview/print_preview.js +++ b/chrome/browser/resources/print_preview/print_preview.js @@ -249,7 +249,7 @@ function updateControlsWithSelectedPrinterCapabilities() { 'disableColorOption': true, 'setColorAsDefault': true, 'setDuplexAsDefault': false, - 'printerColorModelForColor': colorSettings.COLOR, + 'printerColorModelForColor': print_preview.ColorSettings.COLOR, 'printerDefaultDuplexValue': copiesSettings.UNKNOWN_DUPLEX_MODE, 'disableCopiesOption': true}); } else { @@ -974,7 +974,8 @@ function createPDFPlugin(srcDataIndex) { pdfViewer.goToPage('0'); pdfViewer.resetPrintPreviewUrl(srcURL); pdfViewer.reload(); - pdfViewer.grayscale(colorSettings.colorMode == colorSettings.GRAY); + pdfViewer.grayscale( + colorSettings.colorMode == print_preview.ColorSettings.GRAY); return; } diff --git a/chrome/browser/ui/webui/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview_handler.cc index c2e6f57..4982473 100644 --- a/chrome/browser/ui/webui/print_preview_handler.cc +++ b/chrome/browser/ui/webui/print_preview_handler.cc @@ -17,8 +17,6 @@ #include "base/memory/ref_counted.h" #include "base/metrics/histogram.h" #include "base/path_service.h" -#include "base/string_split.h" -#include "base/string_util.h" #include "base/threading/thread.h" #include "base/threading/thread_restrictions.h" #include "base/utf_string_conversions.h" @@ -30,6 +28,7 @@ #include "chrome/browser/printing/print_dialog_cloud.h" #include "chrome/browser/printing/print_job_manager.h" #include "chrome/browser/printing/print_preview_tab_controller.h" +#include "chrome/browser/printing/print_system_task_proxy.h" #include "chrome/browser/printing/print_view_manager.h" #include "chrome/browser/printing/printer_manager_dialog.h" #include "chrome/browser/sessions/restore_tab_helper.h" @@ -47,125 +46,15 @@ #include "printing/metafile.h" #include "printing/metafile_impl.h" #include "printing/page_range.h" -#include "printing/print_job_constants.h" - -#if defined(USE_CUPS) -#include <cups/cups.h> -#include <cups/ppd.h> - -#include "base/file_util.h" -#endif +#include "printing/print_settings.h" #if !defined(OS_CHROMEOS) #include "base/command_line.h" #include "chrome/common/chrome_switches.h" #endif -#if defined(USE_CUPS) && !defined(OS_MACOSX) -namespace printing_internal { - -void parse_lpoptions(const FilePath& filepath, const std::string& printer_name, - int* num_options, cups_option_t** options) { - std::string content; - if (!file_util::ReadFileToString(filepath, &content)) - return; - - const char kDest[] = "dest"; - const char kDefault[] = "default"; - size_t kDestLen = sizeof(kDest) - 1; - size_t kDefaultLen = sizeof(kDefault) - 1; - std::vector <std::string> lines; - base::SplitString(content, '\n', &lines); - - for (size_t i = 0; i < lines.size(); ++i) { - std::string line = lines[i]; - if (line.empty()) - continue; - - if (base::strncasecmp (line.c_str(), kDefault, kDefaultLen) == 0 && - isspace(line[kDefaultLen])) { - line = line.substr(kDefaultLen); - } else if (base::strncasecmp (line.c_str(), kDest, kDestLen) == 0 && - isspace(line[kDestLen])) { - line = line.substr(kDestLen); - } else { - continue; - } - - TrimWhitespaceASCII(line, TRIM_ALL, &line); - if (line.empty()) - continue; - - size_t space_found = line.find(' '); - if (space_found == std::string::npos) - continue; - - std::string name = line.substr(0, space_found); - if (name.empty()) - continue; - - if (base::strncasecmp(printer_name.c_str(), name.c_str(), - name.length()) != 0) { - continue; // This is not the required printer. - } - - line = line.substr(space_found + 1); - TrimWhitespaceASCII(line, TRIM_ALL, &line); // Remove extra spaces. - if (line.empty()) - continue; - // Parse the selected printer custom options. - *num_options = cupsParseOptions(line.c_str(), 0, options); - } -} - -void mark_lpoptions(const std::string& printer_name, ppd_file_t** ppd) { - cups_option_t* options = NULL; - int num_options = 0; - ppdMarkDefaults(*ppd); - - const char kSystemLpOptionPath[] = "/etc/cups/lpoptions"; - const char kUserLpOptionPath[] = ".cups/lpoptions"; - - std::vector<FilePath> file_locations; - file_locations.push_back(FilePath(kSystemLpOptionPath)); - file_locations.push_back(file_util::GetHomeDir().Append(kUserLpOptionPath)); - - for (std::vector<FilePath>::const_iterator it = file_locations.begin(); - it != file_locations.end(); ++it) { - num_options = 0; - options = NULL; - parse_lpoptions(*it, printer_name, &num_options, &options); - if (num_options > 0 && options) { - cupsMarkOptions(*ppd, num_options, options); - cupsFreeOptions(num_options, options); - } - } -} - -} // printing_internal namespace -#endif - namespace { -const char kDisableColorOption[] = "disableColorOption"; -const char kSetColorAsDefault[] = "setColorAsDefault"; -const char kSetDuplexAsDefault[] = "setDuplexAsDefault"; -const char kPrinterColorModelForColor[] = "printerColorModelForColor"; -const char kPrinterDefaultDuplexValue[] = "printerDefaultDuplexValue"; - -#if defined(USE_CUPS) -const char kColorDevice[] = "ColorDevice"; -const char kColorModel[] = "ColorModel"; -const char kColorModelForColor[] = "Color"; -const char kCMYK[] = "CMYK"; -const char kDuplex[] = "Duplex"; -const char kDuplexNone[] = "None"; -#elif defined(OS_WIN) -const char kPskColor[] = "psk:Color"; -const char kPskDuplexFeature[] = "psk:JobDuplexAllDocumentsContiguously"; -const char kPskTwoSided[] = "psk:TwoSided"; -#endif - enum UserActionBuckets { PRINT_TO_PRINTER, PRINT_TO_PDF, @@ -263,8 +152,8 @@ void ReportPrintSettingsStats(const DictionaryValue& settings) { int color_mode; if (settings.GetInteger(printing::kSettingColor, &color_mode)) { - ReportPrintSettingHistogram(color_mode == printing::GRAY ? BLACK_AND_WHITE : - COLOR); + ReportPrintSettingHistogram( + printing::isColorModelSelected(color_mode) ? COLOR : BLACK_AND_WHITE); } } @@ -274,229 +163,6 @@ printing::BackgroundPrintingManager* GetBackgroundPrintingManager() { } // namespace -class PrintSystemTaskProxy - : public base::RefCountedThreadSafe<PrintSystemTaskProxy, - BrowserThread::DeleteOnUIThread> { - public: - PrintSystemTaskProxy(const base::WeakPtr<PrintPreviewHandler>& handler, - printing::PrintBackend* print_backend, - bool has_logged_printers_count) - : handler_(handler), - print_backend_(print_backend), - has_logged_printers_count_(has_logged_printers_count) { - } - - void GetDefaultPrinter() { - VLOG(1) << "Get default printer start"; - StringValue* default_printer = NULL; - if (PrintPreviewHandler::last_used_printer_name_ == NULL) { - default_printer = new StringValue( - print_backend_->GetDefaultPrinterName()); - } else { - default_printer = new StringValue( - *PrintPreviewHandler::last_used_printer_name_); - } - std::string default_printer_string; - default_printer->GetAsString(&default_printer_string); - VLOG(1) << "Get default printer finished, found: " - << default_printer_string; - - StringValue* cloud_print_data = NULL; - if (PrintPreviewHandler::last_used_printer_cloud_print_data_ != NULL) { - cloud_print_data = new StringValue( - *PrintPreviewHandler::last_used_printer_cloud_print_data_); - } else { - cloud_print_data = new StringValue(""); - } - - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&PrintSystemTaskProxy::SendDefaultPrinter, this, - default_printer, cloud_print_data)); - } - - void SendDefaultPrinter(const StringValue* default_printer, - const StringValue* cloud_print_data) { - if (handler_) - handler_->SendDefaultPrinter(*default_printer, *cloud_print_data); - delete default_printer; - } - - void EnumeratePrinters() { - VLOG(1) << "Enumerate printers start"; - ListValue* printers = new ListValue; - - printing::PrinterList printer_list; - print_backend_->EnumeratePrinters(&printer_list); - - if (!has_logged_printers_count_) { - // Record the total number of printers. - UMA_HISTOGRAM_COUNTS("PrintPreview.NumberOfPrinters", - printer_list.size()); - } - - int i = 0; - for (printing::PrinterList::iterator iter = printer_list.begin(); - iter != printer_list.end(); ++iter, ++i) { - DictionaryValue* printer_info = new DictionaryValue; - std::string printerName; - #if defined(OS_MACOSX) - // On Mac, |iter->printer_description| specifies the printer name and - // |iter->printer_name| specifies the device name / printer queue name. - printerName = iter->printer_description; - #else - printerName = iter->printer_name; - #endif - printer_info->SetString(printing::kSettingPrinterName, printerName); - printer_info->SetString(printing::kSettingDeviceName, iter->printer_name); - printers->Append(printer_info); - } - VLOG(1) << "Enumerate printers finished, found " << i << " printers"; - - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&PrintSystemTaskProxy::SetupPrinterList, this, printers)); - } - - void SetupPrinterList(ListValue* printers) { - if (handler_) { - handler_->SetupPrinterList(*printers); - } - delete printers; - } - - void GetPrinterCapabilities(const std::string& printer_name) { - VLOG(1) << "Get printer capabilities start for " << printer_name; - printing::PrinterCapsAndDefaults printer_info; - bool supports_color = true; - bool set_duplex_as_default = false; - int printer_color_space = printing::GRAY; - int default_duplex_setting_value = printing::UNKNOWN_DUPLEX_MODE; - if (!print_backend_->GetPrinterCapsAndDefaults(printer_name, - &printer_info)) { - return; - } - -#if defined(USE_CUPS) - FilePath ppd_file_path; - if (!file_util::CreateTemporaryFile(&ppd_file_path)) - return; - - int data_size = printer_info.printer_capabilities.length(); - if (data_size != file_util::WriteFile( - ppd_file_path, - printer_info.printer_capabilities.data(), - data_size)) { - file_util::Delete(ppd_file_path, false); - return; - } - - ppd_file_t* ppd = ppdOpenFile(ppd_file_path.value().c_str()); - if (ppd) { -#if !defined(OS_MACOSX) - printing_internal::mark_lpoptions(printer_name, &ppd); -#endif - ppd_attr_t* attr = ppdFindAttr(ppd, kColorDevice, NULL); - if (attr && attr->value) - supports_color = ppd->color_device; - - ppd_choice_t* duplex_choice = ppdFindMarkedChoice(ppd, kDuplex); - if (duplex_choice) { - ppd_option_t* option = ppdFindOption(ppd, kDuplex); - if (option) - duplex_choice = ppdFindChoice(option, option->defchoice); - } - - if (duplex_choice) { - if (base::strcasecmp(duplex_choice->choice, kDuplexNone) != 0) { - set_duplex_as_default = true; - default_duplex_setting_value = printing::LONG_EDGE; - } else { - default_duplex_setting_value = printing::SIMPLEX; - } - } - - if (supports_color) { - // Identify the color space (COLOR/CMYK) for this printer. - ppd_option_t* color_model = ppdFindOption(ppd, kColorModel); - if (color_model) { - if (ppdFindChoice(color_model, kColorModelForColor)) - printer_color_space = printing::COLOR; - else if (ppdFindChoice(color_model, kCMYK)) - printer_color_space = printing::CMYK; - } - } - ppdClose(ppd); - } - file_util::Delete(ppd_file_path, false); -#elif defined(OS_WIN) - // According to XPS 1.0 spec, only color printers have psk:Color. - // Therefore we don't need to parse the whole XML file, we just need to - // search the string. The spec can be found at: - // http://msdn.microsoft.com/en-us/windows/hardware/gg463431. - supports_color = (printer_info.printer_capabilities.find(kPskColor) != - std::string::npos); - if (supports_color) - printer_color_space = printing::COLOR; - - set_duplex_as_default = - (printer_info.printer_defaults.find(kPskDuplexFeature) != - std::string::npos) && - (printer_info.printer_defaults.find(kPskTwoSided) != - std::string::npos); - - if (printer_info.printer_defaults.find(kPskDuplexFeature) != - std::string::npos) { - if (printer_info.printer_defaults.find(kPskTwoSided) != - std::string::npos) { - default_duplex_setting_value = printing::LONG_EDGE; - } else { - default_duplex_setting_value = printing::SIMPLEX; - } - } -#else - NOTIMPLEMENTED(); -#endif - - DictionaryValue settings_info; - settings_info.SetBoolean(kDisableColorOption, !supports_color); - if (!supports_color) { - settings_info.SetBoolean(kSetColorAsDefault, false); - } else { - settings_info.SetBoolean(kSetColorAsDefault, - PrintPreviewHandler::last_used_color_setting_); - } - settings_info.SetBoolean(kSetDuplexAsDefault, set_duplex_as_default); - settings_info.SetInteger(kPrinterColorModelForColor, printer_color_space); - settings_info.SetInteger(kPrinterDefaultDuplexValue, - default_duplex_setting_value); - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&PrintSystemTaskProxy::SendPrinterCapabilities, this, - settings_info.DeepCopy())); - } - - void SendPrinterCapabilities(DictionaryValue* settings_info) { - if (handler_) - handler_->SendPrinterCapabilities(*settings_info); - delete settings_info; - } - - private: - friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; - friend class DeleteTask<PrintSystemTaskProxy>; - - ~PrintSystemTaskProxy() {} - - base::WeakPtr<PrintPreviewHandler> handler_; - - scoped_refptr<printing::PrintBackend> print_backend_; - - bool has_logged_printers_count_; - - DISALLOW_COPY_AND_ASSIGN(PrintSystemTaskProxy); -}; - // A Task implementation that stores a PDF file on disk. class PrintToPdfTask : public Task { public: @@ -529,7 +195,8 @@ class PrintToPdfTask : public Task { FilePath* PrintPreviewHandler::last_saved_path_ = NULL; std::string* PrintPreviewHandler::last_used_printer_cloud_print_data_ = NULL; std::string* PrintPreviewHandler::last_used_printer_name_ = NULL; -bool PrintPreviewHandler::last_used_color_setting_ = false; +printing::ColorModels PrintPreviewHandler::last_used_color_model_ = + printing::UNKNOWN_COLOR_MODEL; PrintPreviewHandler::PrintPreviewHandler() : print_backend_(printing::PrintBackend::CreateInstance(NULL)), @@ -710,11 +377,11 @@ void PrintPreviewHandler::HandlePrint(const ListValue* args) { if (!settings.get()) return; - // Storing last used color setting. - int color_mode; - if (!settings->GetInteger(printing::kSettingColor, &color_mode)) - color_mode = printing::GRAY; - last_used_color_setting_ = (color_mode != printing::GRAY); + // Storing last used color model. + int color_model; + if (!settings->GetInteger(printing::kSettingColor, &color_model)) + color_model = printing::GRAY; + last_used_color_model_ = static_cast<printing::ColorModels>(color_model); bool print_to_pdf = false; settings->GetBoolean(printing::kSettingPrintToPDF, &print_to_pdf); diff --git a/chrome/browser/ui/webui/print_preview_handler.h b/chrome/browser/ui/webui/print_preview_handler.h index feddf0f..f7491dd 100644 --- a/chrome/browser/ui/webui/print_preview_handler.h +++ b/chrome/browser/ui/webui/print_preview_handler.h @@ -15,6 +15,7 @@ #include "chrome/browser/printing/print_view_manager_observer.h" #include "chrome/browser/ui/shell_dialogs.h" #include "content/browser/webui/web_ui.h" +#include "printing/print_job_constants.h" class FilePath; class PrintSystemTaskProxy; @@ -30,21 +31,6 @@ namespace printing { class PrintBackend; } -#if defined(UNIT_TEST) && defined(USE_CUPS) && !defined(OS_MACOSX) -typedef struct cups_option_s cups_option_t; - -namespace printing_internal { - -// Helper function to parse the lpoptions custom settings. |num_options| and -// |options| will be updated if the custom settings for |printer_name| are -// found, otherwise nothing is done. -// NOTE: This function is declared here so it can be exposed for unit testing. -void parse_lpoptions(const FilePath& filepath, const std::string& printer_name, - int* num_options, cups_option_t** options); - -} // namespace printing_internal -#endif - // The handler for Javascript messages related to the print preview dialog. class PrintPreviewHandler : public WebUIMessageHandler, public base::SupportsWeakPtr<PrintPreviewHandler>, @@ -198,7 +184,7 @@ class PrintPreviewHandler : public WebUIMessageHandler, static FilePath* last_saved_path_; static std::string* last_used_printer_cloud_print_data_; static std::string* last_used_printer_name_; - static bool last_used_color_setting_; + static printing::ColorModels last_used_color_model_; // A count of how many requests received to regenerate preview data. // Initialized to 0 then incremented and emitted to a histogram. diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 2b41f88..097166d 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1897,6 +1897,8 @@ 'browser/printing/print_preview_message_handler.h', 'browser/printing/print_preview_tab_controller.cc', 'browser/printing/print_preview_tab_controller.h', + 'browser/printing/print_system_task_proxy.cc', + 'browser/printing/print_system_task_proxy.h', 'browser/printing/print_view_manager.cc', 'browser/printing/print_view_manager.h', 'browser/printing/print_view_manager_observer.h', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 3d862f8..9e2d81f 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -2191,7 +2191,7 @@ 'USE_CUPS', ], 'sources': [ - 'browser/ui/webui/print_preview_handler_unittest.cc', + 'browser/printing/print_system_task_proxy_unittest.cc', ], }], ], diff --git a/printing/print_job_constants.cc b/printing/print_job_constants.cc index 3efb488..5420e74 100644 --- a/printing/print_job_constants.cc +++ b/printing/print_job_constants.cc @@ -121,4 +121,22 @@ const char kSettingPrintToPDF[] = "printToPDF"; const int FIRST_PAGE_INDEX = 0; const int COMPLETE_PREVIEW_DOCUMENT_INDEX = -1; +#if defined (USE_CUPS) +const char kBlack[] = "Black"; +const char kCMYK[] = "CMYK"; +const char kKCMY[] = "KCMY"; +const char kCMY_K[] = "CMY+K"; +const char kCMY[] = "CMY"; +const char kColor[] = "Color"; +const char kGray[] = "Gray"; +const char kGrayscale[] = "Grayscale"; +const char kGreyscale[] = "Greyscale"; +const char kMonochrome[] = "Monochrome"; +const char kNormal[] = "Normal"; +const char kNormalGray[] = "Normal.Gray"; +const char kRGB[] = "RGB"; +const char kRGBA[] = "RGBA"; +const char kRGB16[] = "RGB16"; +#endif + } // namespace printing diff --git a/printing/print_job_constants.h b/printing/print_job_constants.h index cbdad74..8b3c638 100644 --- a/printing/print_job_constants.h +++ b/printing/print_job_constants.h @@ -48,6 +48,25 @@ PRINTING_EXPORT extern const char kSettingPrintToPDF[]; PRINTING_EXPORT extern const int FIRST_PAGE_INDEX; PRINTING_EXPORT extern const int COMPLETE_PREVIEW_DOCUMENT_INDEX; +#if defined (USE_CUPS) +// Printer color models +PRINTING_EXPORT extern const char kBlack[]; +PRINTING_EXPORT extern const char kCMYK[]; +PRINTING_EXPORT extern const char kKCMY[]; +PRINTING_EXPORT extern const char kCMY_K[]; +PRINTING_EXPORT extern const char kCMY[]; +PRINTING_EXPORT extern const char kColor[]; +PRINTING_EXPORT extern const char kGray[]; +PRINTING_EXPORT extern const char kGrayscale[]; +PRINTING_EXPORT extern const char kGreyscale[]; +PRINTING_EXPORT extern const char kMonochrome[]; +PRINTING_EXPORT extern const char kNormal[]; +PRINTING_EXPORT extern const char kNormalGray[]; +PRINTING_EXPORT extern const char kRGB[]; +PRINTING_EXPORT extern const char kRGBA[]; +PRINTING_EXPORT extern const char kRGB16[]; +#endif + // Print job duplex mode values. enum DuplexMode { UNKNOWN_DUPLEX_MODE = -1, @@ -70,10 +89,27 @@ enum VerticalHeaderFooterPosition { }; // Print job color mode values. -enum ColorMode { - GRAY = 1, +enum ColorModels { + UNKNOWN_COLOR_MODEL, + GRAY, COLOR, CMYK, + CMY, + KCMY, + CMY_K, // CMY_K represents CMY+K. + BLACK, + RGB, + RGB16, + RGBA, + COLORMODE_COLOR, // Used in samsung printer ppds. + COLORMODE_MONOCHROME, // Used in samsung printer ppds. + HP_COLOR_COLOR, // Used in HP color printer ppds. + HP_COLOR_BLACK, // Used in HP color printer ppds. + PRINTOUTMODE_NORMAL, // Used in foomatic ppds. + PRINTOUTMODE_NORMAL_GRAY, // Used in foomatic ppds. + PROCESSCOLORMODEL_CMYK, // Used in canon printer ppds. + PROCESSCOLORMODEL_GREYSCALE, // Used in canon printer ppds. + PROCESSCOLORMODEL_RGB, // Used in canon printer ppds }; } // namespace printing diff --git a/printing/print_settings.cc b/printing/print_settings.cc index d08d02f5..06aac453d 100644 --- a/printing/print_settings.cc +++ b/printing/print_settings.cc @@ -10,6 +10,102 @@ namespace printing { +#if defined (USE_CUPS) +void GetColorModelForMode( + int color_mode, std::string* color_setting_name, std::string* color_value) { +#if defined(OS_MACOSX) + const char kCUPSColorMode[] = "ColorMode"; + const char kCUPSColorModel[] = "ColorModel"; + const char kCUPSPrintoutMode[] = "PrintoutMode"; + const char kCUPSProcessColorModel[] = "ProcessColorModel"; +#else + const char kCUPSColorMode[] = "cups-ColorMode"; + const char kCUPSColorModel[] = "cups-ColorModel"; + const char kCUPSPrintoutMode[] = "cups-PrintoutMode"; + const char kCUPSProcessColorModel[] = "cups-ProcessColorModel"; +#endif + + color_setting_name->assign(kCUPSColorModel); + switch (color_mode) { + case printing::COLOR: + color_value->assign(printing::kColor); + break; + case printing::CMYK: + color_value->assign(printing::kCMYK); + break; + case printing::PRINTOUTMODE_NORMAL: + color_value->assign(printing::kNormal); + color_setting_name->assign(kCUPSPrintoutMode); + break; + case printing::PRINTOUTMODE_NORMAL_GRAY: + color_value->assign(printing::kNormalGray); + color_setting_name->assign(kCUPSPrintoutMode); + break; + case printing::RGB16: + color_value->assign(printing::kRGB16); + break; + case printing::RGBA: + color_value->assign(printing::kRGBA); + break; + case printing::RGB: + color_value->assign(printing::kRGB); + break; + case printing::CMY: + color_value->assign(printing::kCMY); + break; + case printing::CMY_K: + color_value->assign(printing::kCMY_K); + break; + case printing::BLACK: + color_value->assign(printing::kBlack); + break; + case printing::GRAY: + color_value->assign(printing::kGray); + break; + case printing::COLORMODE_COLOR: + color_setting_name->assign(kCUPSColorMode); + color_value->assign(printing::kColor); + break; + case printing::COLORMODE_MONOCHROME: + color_setting_name->assign(kCUPSColorMode); + color_value->assign(printing::kMonochrome); + break; + case printing::HP_COLOR_COLOR: + color_setting_name->assign(kColor); + color_value->assign(printing::kColor); + break; + case printing::HP_COLOR_BLACK: + color_setting_name->assign(kColor); + color_value->assign(printing::kBlack); + break; + case printing::PROCESSCOLORMODEL_CMYK: + color_setting_name->assign(kCUPSProcessColorModel); + color_value->assign(printing::kCMYK); + break; + case printing::PROCESSCOLORMODEL_GREYSCALE: + color_setting_name->assign(kCUPSProcessColorModel); + color_value->assign(printing::kGreyscale); + break; + case printing::PROCESSCOLORMODEL_RGB: + color_setting_name->assign(kCUPSProcessColorModel); + color_value->assign(printing::kRGB); + break; + default: + color_value->assign(printing::kGrayscale); + break; + } +} +#endif + +bool isColorModelSelected(int model) { + return (model != printing::GRAY && + model != printing::BLACK && + model != printing::PRINTOUTMODE_NORMAL_GRAY && + model != printing::COLORMODE_MONOCHROME && + model != printing::PROCESSCOLORMODEL_GREYSCALE && + model != printing::HP_COLOR_BLACK); +} + // Global SequenceNumber used for generating unique cookie values. static base::AtomicSequenceNumber cookie_seq(base::LINKER_INITIALIZED); diff --git a/printing/print_settings.h b/printing/print_settings.h index 4e40231..d73fd66 100644 --- a/printing/print_settings.h +++ b/printing/print_settings.h @@ -11,10 +11,21 @@ #include "base/string16.h" #include "printing/page_range.h" #include "printing/page_setup.h" +#include "printing/printing_export.h" #include "ui/gfx/rect.h" namespace printing { +// Returns true if color model is selected. +PRINTING_EXPORT bool isColorModelSelected(int model); + +#if defined (USE_CUPS) + // Get the color model setting name and value for the |color_mode|. + PRINTING_EXPORT void GetColorModelForMode(int color_mode, + std::string* color_setting_name, + std::string* color_value); +#endif + // OS-independent print settings. class PRINTING_EXPORT PrintSettings { public: diff --git a/printing/printing_context_mac.mm b/printing/printing_context_mac.mm index 15348a0..bfb9817 100644 --- a/printing/printing_context_mac.mm +++ b/printing/printing_context_mac.mm @@ -15,10 +15,6 @@ #include "base/values.h" #include "printing/print_settings_initializer_mac.h" -static const CFStringRef kColorModel = CFSTR("ColorModel"); -static const CFStringRef kGrayColor = CFSTR("Gray"); -static const CFStringRef kCMYK = CFSTR("CMYK"); - namespace printing { // static @@ -253,15 +249,17 @@ bool PrintingContextMac::SetDuplexModeInPrintSettings(DuplexMode mode) { bool PrintingContextMac::SetOutputColor(int color_mode) { PMPrintSettings pmPrintSettings = static_cast<PMPrintSettings>([print_info_.get() PMPrintSettings]); - CFStringRef output_color = NULL; - if (color_mode == printing::GRAY) - output_color = kGrayColor; - else if (color_mode == printing::CMYK) - output_color = kCMYK; + std::string color_setting_name; + std::string color_value; + printing::GetColorModelForMode(color_mode, &color_setting_name, &color_value); + base::mac::ScopedCFTypeRef<CFStringRef> color_setting( + base::SysUTF8ToCFStringRef(color_setting_name)); + base::mac::ScopedCFTypeRef<CFStringRef> output_color( + base::SysUTF8ToCFStringRef(color_value)); return PMPrintSettingsSetValue(pmPrintSettings, - kColorModel, - output_color, + color_setting.get(), + output_color.get(), false) == noErr; } |