diff options
-rw-r--r-- | chrome/app/chrome_command_ids.h | 1 | ||||
-rw-r--r-- | chrome/browser/printing/print_job_manager.cc | 6 | ||||
-rw-r--r-- | chrome/browser/printing/print_job_manager.h | 9 | ||||
-rw-r--r-- | chrome/browser/printing/print_job_worker.cc | 23 | ||||
-rw-r--r-- | chrome/browser/printing/print_job_worker.h | 10 | ||||
-rw-r--r-- | chrome/browser/printing/print_view_manager.cc | 10 | ||||
-rw-r--r-- | chrome/browser/printing/print_view_manager.h | 5 | ||||
-rw-r--r-- | chrome/browser/printing/printer_query.cc | 7 | ||||
-rw-r--r-- | chrome/browser/printing/printer_query.h | 8 | ||||
-rw-r--r-- | chrome/browser/printing/printing_message_filter.cc | 10 | ||||
-rw-r--r-- | chrome/browser/ui/browser_command_controller.cc | 19 | ||||
-rw-r--r-- | chrome/browser/ui/browser_commands.cc | 4 | ||||
-rw-r--r-- | chrome/browser/ui/browser_commands.h | 1 | ||||
-rw-r--r-- | printing/print_destination_interface.h | 33 | ||||
-rw-r--r-- | printing/print_destination_none.cc | 13 | ||||
-rw-r--r-- | printing/print_destination_win.cc | 52 | ||||
-rw-r--r-- | printing/printing.gyp | 6 |
17 files changed, 208 insertions, 9 deletions
diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h index da1a0fb..d7aec0e 100644 --- a/chrome/app/chrome_command_ids.h +++ b/chrome/app/chrome_command_ids.h @@ -77,6 +77,7 @@ #define IDC_EMAIL_PAGE_LOCATION 35006 #define IDC_ADVANCED_PRINT 35007 #define IDC_CHROME_TO_MOBILE_PAGE 35008 +#define IDC_PRINT_TO_DESTINATION 35009 // When adding a new encoding to this list, be sure to append it to the // EncodingMenuController::kValidEncodingIds array in diff --git a/chrome/browser/printing/print_job_manager.cc b/chrome/browser/printing/print_job_manager.cc index e83238c..e3abfd1 100644 --- a/chrome/browser/printing/print_job_manager.cc +++ b/chrome/browser/printing/print_job_manager.cc @@ -59,6 +59,11 @@ void PrintJobManager::StopJobs(bool wait_for_finish) { current_jobs_.clear(); } +void PrintJobManager::SetPrintDestination( + PrintDestinationInterface* destination) { + destination_ = destination; +} + void PrintJobManager::QueuePrinterQuery(PrinterQuery* job) { base::AutoLock lock(lock_); DCHECK(job); @@ -125,6 +130,7 @@ void PrintJobManager::OnPrintJobEvent( DCHECK(current_jobs_.end() == std::find(current_jobs_.begin(), current_jobs_.end(), print_job)); + destination_ = NULL; break; } case JobEventDetails::FAILED: { diff --git a/chrome/browser/printing/print_job_manager.h b/chrome/browser/printing/print_job_manager.h index 4fc34d4..3ea70a63 100644 --- a/chrome/browser/printing/print_job_manager.h +++ b/chrome/browser/printing/print_job_manager.h @@ -13,6 +13,7 @@ #include "chrome/browser/prefs/pref_member.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" +#include "printing/print_destination_interface.h" class PrefService; @@ -38,6 +39,9 @@ class PrintJobManager : public content::NotificationObserver { // a chance to complete before stopping them. void StopJobs(bool wait_for_finish); + // Sets the print destination to be set on the next print job. + void SetPrintDestination(PrintDestinationInterface* destination); + // Queues a semi-initialized worker thread. Can be called from any thread. // Current use case is queuing from the I/O thread. // TODO(maruel): Have them vanish after a timeout (~5 minutes?) @@ -58,6 +62,9 @@ class PrintJobManager : public content::NotificationObserver { // prefs::kPrintingEnabled via g_browser_process->local_state() directly. bool printing_enabled() const; + // May return NULL when no destination was set. + PrintDestinationInterface* destination() const { return destination_.get(); } + private: typedef std::vector<scoped_refptr<PrintJob> > PrintJobs; typedef std::vector<scoped_refptr<PrinterQuery> > PrinterQueries; @@ -83,6 +90,8 @@ class PrintJobManager : public content::NotificationObserver { PrinterQueries queued_queries_; + scoped_refptr<PrintDestinationInterface> destination_; + // Current print jobs that are active. PrintJobs current_jobs_; diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc index 1162cc5..54082cf 100644 --- a/chrome/browser/printing/print_job_worker.cc +++ b/chrome/browser/printing/print_job_worker.cc @@ -69,6 +69,11 @@ void PrintJobWorker::SetNewOwner(PrintJobWorkerOwner* new_owner) { owner_ = new_owner; } +void PrintJobWorker::SetPrintDestination( + PrintDestinationInterface* destination) { + destination_ = destination; +} + void PrintJobWorker::GetSettings(bool ask_user_for_settings, gfx::NativeView parent_view, int document_page_count, @@ -85,7 +90,9 @@ void PrintJobWorker::GetSettings(bool ask_user_for_settings, // MessageLoop::current()->SetNestableTasksAllowed(true); printing_context_->set_margin_type(margin_type); - if (ask_user_for_settings) { + // When we delegate to a destination, we don't ask the user for settings. + // TODO(mad): Ask the destination for settings. + if (ask_user_for_settings && destination_.get() == NULL) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&HoldRefCallback, make_scoped_refptr(owner_), @@ -241,6 +248,8 @@ void PrintJobWorker::OnNewPage() { } // We have enough information to initialize page_number_. page_number_.Init(document_->settings(), page_count); + if (destination_.get() != NULL) + destination_->SetPageCount(page_count); } DCHECK_NE(page_number_, PageNumber::npos()); @@ -308,6 +317,18 @@ void PrintJobWorker::SpoolPage(PrintedPage* page) { return; } + if (destination_.get() != NULL) { + std::vector<uint8> metabytes(page->metafile()->GetDataSize()); + bool success = page->metafile()->GetData( + reinterpret_cast<void*>(&metabytes[0]), metabytes.size()); + DCHECK(success) << "Failed to get metafile data."; + destination_->SetPageContent( + page->page_number(), + reinterpret_cast<void*>(&metabytes[0]), + metabytes.size()); + return; + } + // Actual printing. #if defined(OS_WIN) || defined(OS_MACOSX) document_->RenderPrintedPage(*page, printing_context_->context()); diff --git a/chrome/browser/printing/print_job_worker.h b/chrome/browser/printing/print_job_worker.h index fee682d..41b9171 100644 --- a/chrome/browser/printing/print_job_worker.h +++ b/chrome/browser/printing/print_job_worker.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -11,6 +11,7 @@ #include "base/memory/weak_ptr.h" #include "base/threading/thread.h" #include "printing/page_number.h" +#include "printing/print_destination_interface.h" #include "printing/printing_context.h" #include "printing/print_job_constants.h" #include "ui/gfx/native_widget_types.h" @@ -39,6 +40,10 @@ class PrintJobWorker : public base::Thread { void SetNewOwner(PrintJobWorkerOwner* new_owner); + // Set a destination for print. + // This supercedes the document's rendering destination. + void SetPrintDestination(PrintDestinationInterface* destination); + // Initializes the print settings. If |ask_user_for_settings| is true, a // Print... dialog box will be shown to ask the user his preference. void GetSettings(bool ask_user_for_settings, @@ -118,6 +123,9 @@ class PrintJobWorker : public base::Thread { // The printed document. Only has read-only access. scoped_refptr<PrintedDocument> document_; + // The print destination, may be NULL. + scoped_refptr<PrintDestinationInterface> destination_; + // The print job owning this worker thread. It is guaranteed to outlive this // object. PrintJobWorkerOwner* owner_; diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc index 477336e..6f8a334 100644 --- a/chrome/browser/printing/print_view_manager.cc +++ b/chrome/browser/printing/print_view_manager.cc @@ -31,6 +31,7 @@ #include "grit/generated_resources.h" #include "printing/metafile.h" #include "printing/metafile_impl.h" +#include "printing/print_destination_interface.h" #include "printing/printed_document.h" #include "ui/base/l10n/l10n_util.h" @@ -101,6 +102,13 @@ bool PrintViewManager::AdvancedPrintNow() { } } +bool PrintViewManager::PrintToDestination() { + // TODO(mad): Use a passed in destination interface instead. + g_browser_process->print_job_manager()->SetPrintDestination( + printing::CreatePrintDestination()); + return PrintNowInternal(new PrintMsg_PrintPages(routing_id())); +} + bool PrintViewManager::PrintPreviewNow() { if (print_preview_state_ != NOT_PREVIEWING) { NOTREACHED(); @@ -613,6 +621,8 @@ void PrintViewManager::ReleasePrinterQuery() { int cookie = cookie_; cookie_ = 0; + g_browser_process->print_job_manager()->SetPrintDestination(NULL); + printing::PrintJobManager* print_job_manager = g_browser_process->print_job_manager(); diff --git a/chrome/browser/printing/print_view_manager.h b/chrome/browser/printing/print_view_manager.h index da74578..02ef195 100644 --- a/chrome/browser/printing/print_view_manager.h +++ b/chrome/browser/printing/print_view_manager.h @@ -51,6 +51,11 @@ class PrintViewManager : public content::NotificationObserver, // preview tab. bool AdvancedPrintNow(); + // Same as PrintNow(), but for the case where we want to send the result to + // another destination. + // TODO(mad) Add an argument so we can pass the destination interface. + bool PrintToDestination(); + // Initiate print preview of the current document by first notifying the // renderer. Since this happens asynchronous, the print preview tab creation // will not be completed on the return of this function. Returns false if diff --git a/chrome/browser/printing/printer_query.cc b/chrome/browser/printing/printer_query.cc index 0536b24..7c07fe2 100644 --- a/chrome/browser/printing/printer_query.cc +++ b/chrome/browser/printing/printer_query.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -100,6 +100,11 @@ void PrinterQuery::SetSettings(const DictionaryValue& new_settings, new_settings.DeepCopy())); } +void PrinterQuery::SetWorkerDestination( + PrintDestinationInterface* destination) { + worker_->SetPrintDestination(destination); +} + void PrinterQuery::StartWorker(const base::Closure& callback) { DCHECK(callback_.is_null()); DCHECK(worker_.get()); diff --git a/chrome/browser/printing/printer_query.h b/chrome/browser/printing/printer_query.h index dcb2f6a..a2b9bb9 100644 --- a/chrome/browser/printing/printer_query.h +++ b/chrome/browser/printing/printer_query.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -21,7 +21,8 @@ class DictionaryValue; namespace printing { -class PrintJobWorker; + class PrintDestinationInterface; + class PrintJobWorker; // Query the printer for settings. class PrinterQuery : public PrintJobWorkerOwner { @@ -57,6 +58,9 @@ class PrinterQuery : public PrintJobWorkerOwner { void SetSettings(const base::DictionaryValue& new_settings, const base::Closure& callback); + // Set a destination for the worker. + void SetWorkerDestination(PrintDestinationInterface* destination); + // Stops the worker thread since the client is done with this object. void StopWorker(); diff --git a/chrome/browser/printing/printing_message_filter.cc b/chrome/browser/printing/printing_message_filter.cc index 812a7a0..2ba8a02 100644 --- a/chrome/browser/printing/printing_message_filter.cc +++ b/chrome/browser/printing/printing_message_filter.cc @@ -232,8 +232,10 @@ void PrintingMessageFilter::OnGetDefaultPrintSettings(IPC::Message* reply_msg) { return; } print_job_manager_->PopPrinterQuery(0, &printer_query); - if (!printer_query.get()) + if (!printer_query.get()) { printer_query = new printing::PrinterQuery; + printer_query->SetWorkerDestination(print_job_manager_->destination()); + } // Loads default settings. This is asynchronous, only the IPC message sender // will hang until the settings are retrieved. @@ -282,6 +284,7 @@ void PrintingMessageFilter::OnScriptedPrint( print_job_manager_->PopPrinterQuery(params.cookie, &printer_query); if (!printer_query.get()) { printer_query = new printing::PrinterQuery; + printer_query->SetWorkerDestination(print_job_manager_->destination()); } GetPrintSettingsForRenderViewParams settings_params; settings_params.ask_user_for_settings = printing::PrinterQuery::ASK_USER; @@ -331,9 +334,10 @@ void PrintingMessageFilter::OnUpdatePrintSettings( } print_job_manager_->PopPrinterQuery(document_cookie, &printer_query); - if (!printer_query.get()) + if (!printer_query.get()) { printer_query = new printing::PrinterQuery; - + printer_query->SetWorkerDestination(print_job_manager_->destination()); + } printer_query->SetSettings( job_settings, base::Bind(&PrintingMessageFilter::OnUpdatePrintSettingsReply, this, diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index fd43df0..158e74d 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc @@ -371,6 +371,9 @@ void BrowserCommandController::ExecuteCommandWithDisposition( case IDC_ADVANCED_PRINT: AdvancedPrint(browser_); break; + case IDC_PRINT_TO_DESTINATION: + PrintToDestination(browser_); + break; case IDC_CHROME_TO_MOBILE_PAGE: ShowChromeToMobileBubble(browser_); break; @@ -1013,9 +1016,23 @@ void BrowserCommandController::UpdateCommandsForMultipleProfiles() { } void BrowserCommandController::UpdatePrintingState() { - command_updater_.UpdateCommandEnabled(IDC_PRINT, CanPrint(browser_)); + bool print_enabled = CanPrint(browser_); + command_updater_.UpdateCommandEnabled(IDC_PRINT, print_enabled); command_updater_.UpdateCommandEnabled(IDC_ADVANCED_PRINT, CanAdvancedPrint(browser_)); + command_updater_.UpdateCommandEnabled(IDC_PRINT_TO_DESTINATION, + print_enabled); +#if defined(OS_WIN) + HMODULE metro_module = base::win::GetMetroModule(); + if (metro_module != NULL) { + typedef void (*MetroEnablePrinting)(BOOL); + MetroEnablePrinting metro_enable_printing = + reinterpret_cast<MetroEnablePrinting>( + ::GetProcAddress(metro_module, "MetroEnablePrinting")); + if (metro_enable_printing) + metro_enable_printing(print_enabled); + } +#endif } void BrowserCommandController::UpdateSaveAsState() { diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index 248b866..1b74ce1 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc @@ -633,6 +633,10 @@ bool CanAdvancedPrint(const Browser* browser) { return PrintPreviewShowing(browser) || CanPrint(browser); } +void PrintToDestination(Browser* browser) { + browser->GetActiveTabContents()->print_view_manager()->PrintToDestination(); +} + void EmailPageLocation(Browser* browser) { content::RecordAction(UserMetricsAction("EmailPageLocation")); WebContents* wc = browser->GetActiveWebContents(); diff --git a/chrome/browser/ui/browser_commands.h b/chrome/browser/ui/browser_commands.h index bdb7d36..20eba2d 100644 --- a/chrome/browser/ui/browser_commands.h +++ b/chrome/browser/ui/browser_commands.h @@ -104,6 +104,7 @@ void Print(Browser* browser); bool CanPrint(const Browser* browser); void AdvancedPrint(Browser* browser); bool CanAdvancedPrint(const Browser* browser); +void PrintToDestination(Browser* browser); void EmailPageLocation(Browser* browser); bool CanEmailPageLocation(const Browser* browser); void Cut(Browser* browser); diff --git a/printing/print_destination_interface.h b/printing/print_destination_interface.h new file mode 100644 index 0000000..13e8c95 --- /dev/null +++ b/printing/print_destination_interface.h @@ -0,0 +1,33 @@ +// Copyright (c) 2012 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 PRINTING_PRINT_DESTINATION_INTERFACE_H_ +#define PRINTING_PRINT_DESTINATION_INTERFACE_H_ +#pragma once + +#include "base/memory/ref_counted.h" +#include "printing/printing_export.h" + +namespace printing { + +class PrintDestinationInterface + : public base::RefCountedThreadSafe<PrintDestinationInterface> { + public: + // Sets the number of pages to print as soon as it is known. + virtual void SetPageCount(int page_count) = 0; + + // Sets the metafile bits for a given page as soon as it is ready. + virtual void SetPageContent(int page_number, + void* content, + size_t content_size) = 0; + protected: + friend class base::RefCountedThreadSafe<PrintDestinationInterface>; + virtual ~PrintDestinationInterface() {} +}; + +PRINTING_EXPORT PrintDestinationInterface* CreatePrintDestination(); + +} // namespace printing + +#endif // PRINTING_PRINT_DESTINATION_INTERFACE_H_ diff --git a/printing/print_destination_none.cc b/printing/print_destination_none.cc new file mode 100644 index 0000000..66b838e --- /dev/null +++ b/printing/print_destination_none.cc @@ -0,0 +1,13 @@ +// Copyright (c) 2012 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 "printing/print_destination_interface.h" + +namespace printing { + +PrintDestinationInterface* CreatePrintDestination() { + return NULL; +} + +} // namespace printing diff --git a/printing/print_destination_win.cc b/printing/print_destination_win.cc new file mode 100644 index 0000000..dc99469 --- /dev/null +++ b/printing/print_destination_win.cc @@ -0,0 +1,52 @@ +// Copyright (c) 2012 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 "printing/print_destination_interface.h" + +#include "base/win/metro.h" + +namespace printing { + +class PrintDestinationWin : public PrintDestinationInterface { + public: + PrintDestinationWin() + : metro_set_print_page_count_(NULL), + metro_set_print_page_content_(NULL) { + HMODULE metro_module = base::win::GetMetroModule(); + if (metro_module != NULL) { + metro_set_print_page_count_ = + reinterpret_cast<MetroSetPrintPageCount>( + ::GetProcAddress(metro_module, "MetroSetPrintPageCount")); + metro_set_print_page_content_ = + reinterpret_cast<MetroSetPrintPageContent>( + ::GetProcAddress(metro_module, "MetroSetPrintPageContent")); + } + } + virtual void SetPageCount(int page_count) { + if (metro_set_print_page_count_) + metro_set_print_page_count_(page_count); + } + + virtual void SetPageContent(int page_number, + void* content, + size_t content_size) { + if (metro_set_print_page_content_) + metro_set_print_page_content_(page_number - 1, content, content_size); + } + private: + typedef void (*MetroSetPrintPageCount)(INT); + typedef void (*MetroSetPrintPageContent)(INT, VOID*, UINT32); + MetroSetPrintPageCount metro_set_print_page_count_; + MetroSetPrintPageContent metro_set_print_page_content_; +}; + +PrintDestinationInterface* CreatePrintDestination() { + // We currently only support the Metro print destination. + if (base::win::IsMetroProcess()) + return new PrintDestinationWin; + else + return NULL; +} + +} // namespace printing diff --git a/printing/printing.gyp b/printing/printing.gyp index 19fa1b2..6af7b88 100644 --- a/printing/printing.gyp +++ b/printing/printing.gyp @@ -55,6 +55,9 @@ 'pdf_metafile_cg_mac.h', 'pdf_metafile_skia.h', 'pdf_metafile_skia.cc', + 'print_destination_interface.h', + 'print_destination_none.cc', + 'print_destination_win.cc', 'printed_document_gtk.cc', 'printed_document.cc', 'printed_document.h', @@ -146,6 +149,9 @@ 'backend/win_helper.h', 'backend/print_backend_win.cc', ], + 'sources!': [ + 'print_destination_none.cc', + ], }], ['chromeos==1 or use_aura==1',{ 'sources': [ |