summaryrefslogtreecommitdiffstats
path: root/chrome/browser/printing
diff options
context:
space:
mode:
authorsverrir@google.com <sverrir@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-19 15:58:01 +0000
committersverrir@google.com <sverrir@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-19 15:58:01 +0000
commit8227045e458705c27ca116a02fd7b9b9a75237ae (patch)
tree2e694fc454663eedc62b27e99aeef67d476a09ab /chrome/browser/printing
parentb0fd9c1c6b3ccf0b436d38d181ab26100b3135a6 (diff)
downloadchromium_src-8227045e458705c27ca116a02fd7b9b9a75237ae.zip
chromium_src-8227045e458705c27ca116a02fd7b9b9a75237ae.tar.gz
chromium_src-8227045e458705c27ca116a02fd7b9b9a75237ae.tar.bz2
Add Print Selection support to Chrome. This change is fairly involved since this means that the printing is done async instead of the fully synchronous mode the normal full page printing is.
This means we create an in memory copy of the selected text for printing. This is the next step to move to fully async printing with print frame support. This change also removes the print on demand functionality that was no longer used. BUG=http://crbug.com/1682 TEST=The print dialog on Windows now contains an option to print selection only. Test that with various pages and various selections. Review URL: http://codereview.chromium.org/125082 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18815 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/printing')
-rw-r--r--chrome/browser/printing/page_range.cc8
-rw-r--r--chrome/browser/printing/page_range.h3
-rw-r--r--chrome/browser/printing/page_range_unittest.cc2
-rw-r--r--chrome/browser/printing/print_job_worker.cc19
-rw-r--r--chrome/browser/printing/print_job_worker.h4
-rw-r--r--chrome/browser/printing/print_view_manager.cc15
-rw-r--r--chrome/browser/printing/print_view_manager.h6
-rw-r--r--chrome/browser/printing/printed_document.cc63
-rw-r--r--chrome/browser/printing/printed_document.h11
-rw-r--r--chrome/browser/printing/win_printing_context.cc18
10 files changed, 50 insertions, 99 deletions
diff --git a/chrome/browser/printing/page_range.cc b/chrome/browser/printing/page_range.cc
index bb9d05a..9669a9e 100644
--- a/chrome/browser/printing/page_range.cc
+++ b/chrome/browser/printing/page_range.cc
@@ -8,6 +8,7 @@
namespace printing {
+/* static */
std::vector<int> PageRange::GetPages(const PageRanges& ranges) {
std::set<int> pages;
for (unsigned i = 0; i < ranges.size(); ++i) {
@@ -20,4 +21,11 @@ std::vector<int> PageRange::GetPages(const PageRanges& ranges) {
return SetToVector(pages);
}
+/* static */
+int PageRange::GetTotalPages(const PageRanges& ranges) {
+ // Since ranges can overlap we need to merge them before counting
+ std::vector<int> pages = PageRange::GetPages(ranges);
+ return pages.size();
+}
+
} // namespace printing
diff --git a/chrome/browser/printing/page_range.h b/chrome/browser/printing/page_range.h
index a2d042c..1f3e024 100644
--- a/chrome/browser/printing/page_range.h
+++ b/chrome/browser/printing/page_range.h
@@ -24,6 +24,9 @@ struct PageRange {
// Retrieves the sorted list of unique pages in the page ranges.
static std::vector<int> GetPages(const PageRanges& ranges);
+
+ // Gets the total number of pages.
+ static int GetTotalPages(const PageRanges& ranges);
};
} // namespace printing
diff --git a/chrome/browser/printing/page_range_unittest.cc b/chrome/browser/printing/page_range_unittest.cc
index b059d5b..a5ac563 100644
--- a/chrome/browser/printing/page_range_unittest.cc
+++ b/chrome/browser/printing/page_range_unittest.cc
@@ -27,10 +27,12 @@ TEST(PageRangeTest, RangeMerge) {
EXPECT_EQ(10, pages[5]);
EXPECT_EQ(11, pages[6]);
EXPECT_EQ(12, pages[7]);
+ EXPECT_EQ(8, printing::PageRange::GetTotalPages(ranges));
}
TEST(PageRangeTest, Empty) {
printing::PageRanges ranges;
std::vector<int> pages(printing::PageRange::GetPages(ranges));
EXPECT_EQ(0U, pages.size());
+ EXPECT_EQ(0, printing::PageRange::GetTotalPages(ranges));
}
diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc
index 19c2add..af32da0 100644
--- a/chrome/browser/printing/print_job_worker.cc
+++ b/chrome/browser/printing/print_job_worker.cc
@@ -50,7 +50,7 @@ class PrintJobWorker::NotificationTask : public Task {
PrintJobWorker::PrintJobWorker(PrintJobWorkerOwner* owner)
: Thread("Printing_Worker"),
owner_(owner) {
- // The object is created in the UI thread.
+ // The object is created in the IO thread.
DCHECK_EQ(owner_->message_loop(), MessageLoop::current());
}
@@ -167,7 +167,7 @@ void PrintJobWorker::OnNewPage() {
// Is the page available?
scoped_refptr<PrintedPage> page;
if (!document_->GetPage(page_number_.ToInt(), &page)) {
- // The page is implictly requested.
+ // The page is implicitly requested.
break;
}
// The page is there, print it.
@@ -192,21 +192,6 @@ void PrintJobWorker::DismissDialog() {
printing_context_.DismissDialog();
}
-void PrintJobWorker::RequestMissingPages() {
- DCHECK_EQ(message_loop(), MessageLoop::current());
- // It may arrive out of order. Don't mind about it.
- if (page_number_ != PageNumber::npos()) {
- // We are printing.
- document_->RequestMissingPages();
- }
- NotificationTask* task = new NotificationTask();
- task->Init(owner_,
- JobEventDetails::ALL_PAGES_REQUESTED,
- document_.get(),
- NULL);
- owner_->message_loop()->PostTask(FROM_HERE, task);
-}
-
void PrintJobWorker::OnDocumentDone() {
DCHECK_EQ(message_loop(), MessageLoop::current());
DCHECK_EQ(page_number_, PageNumber::npos());
diff --git a/chrome/browser/printing/print_job_worker.h b/chrome/browser/printing/print_job_worker.h
index cc1bde1..b01881a 100644
--- a/chrome/browser/printing/print_job_worker.h
+++ b/chrome/browser/printing/print_job_worker.h
@@ -55,10 +55,6 @@ class PrintJobWorker : public base::Thread {
// Cancels the Print... dialog box if shown, noop otherwise.
void DismissDialog();
- // Requests the missing pages in rendered_document_. Sends back a
- // ALL_PAGES_REQUESTED notification once done.
- void RequestMissingPages();
-
protected:
// Retrieves the context for testing only.
PrintingContext& printing_context() { return printing_context_; }
diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc
index 5976bf3..d775ff5 100644
--- a/chrome/browser/printing/print_view_manager.cc
+++ b/chrome/browser/printing/print_view_manager.cc
@@ -25,6 +25,7 @@ namespace printing {
PrintViewManager::PrintViewManager(TabContents& owner)
: owner_(owner),
waiting_to_print_(false),
+ printing_succeeded_(false),
inside_inner_message_loop_(false) {
}
@@ -46,7 +47,7 @@ bool PrintViewManager::OnRenderViewGone(RenderViewHost* render_view_host) {
scoped_refptr<PrintedDocument> document(print_job_->document());
if (document) {
- // If IsComplete() returns false, the document isn't completely renderered.
+ // If IsComplete() returns false, the document isn't completely rendered.
// Since our renderer is gone, there's nothing to do, cancel it. Otherwise,
// the print job may finish without problem.
TerminatePrintJob(!document->IsComplete());
@@ -148,7 +149,6 @@ void PrintViewManager::OnNotifyPrintJobEvent(
const JobEventDetails& event_details) {
switch (event_details.type()) {
case JobEventDetails::FAILED: {
- // TODO(maruel): bug 1123882 Show some kind of notification.
TerminatePrintJob(true);
break;
}
@@ -176,6 +176,7 @@ void PrintViewManager::OnNotifyPrintJobEvent(
// Printing is done, we don't need it anymore.
// print_job_->is_job_pending() may still be true, depending on the order
// of object registration.
+ printing_succeeded_ = true;
ReleasePrintJob();
break;
}
@@ -202,6 +203,7 @@ bool PrintViewManager::RenderAllMissingPagesNow() {
// Is the document already complete?
if (print_job_->document() && print_job_->document()->IsComplete()) {
waiting_to_print_ = false;
+ printing_succeeded_ = true;
return true;
}
@@ -266,6 +268,7 @@ bool PrintViewManager::CreateNewPrintJob(PrintJobWorkerOwner* job) {
print_job_->Initialize(job, this);
registrar_.Add(this, NotificationType::PRINT_JOB_EVENT,
Source<PrintJob>(print_job_.get()));
+ printing_succeeded_ = false;
return true;
}
@@ -287,6 +290,12 @@ void PrintViewManager::DisconnectFromCurrentPrintJob() {
}
}
+void PrintViewManager::PrintingDone(bool success) {
+ if (print_job_.get()) {
+ owner_.PrintingDone(print_job_->cookie(), success);
+ }
+}
+
void PrintViewManager::TerminatePrintJob(bool cancel) {
if (!print_job_.get())
return;
@@ -314,6 +323,8 @@ void PrintViewManager::ReleasePrintJob() {
if (!print_job_.get())
return;
+ PrintingDone(printing_succeeded_);
+
registrar_.Remove(this, NotificationType::PRINT_JOB_EVENT,
Source<PrintJob>(print_job_.get()));
print_job_->DisconnectSource();
diff --git a/chrome/browser/printing/print_view_manager.h b/chrome/browser/printing/print_view_manager.h
index 2562885..cd95f06 100644
--- a/chrome/browser/printing/print_view_manager.h
+++ b/chrome/browser/printing/print_view_manager.h
@@ -77,6 +77,9 @@ class PrintViewManager : public NotificationObserver,
// disconnect from it.
void DisconnectFromCurrentPrintJob();
+ // Notify that the printing is done.
+ void PrintingDone(bool success);
+
// Terminates the print job. Noop if no print job has been created. If
// |cancel| is true, cancel it instead of waiting for the job to finish. Will
// call ReleasePrintJob().
@@ -113,6 +116,9 @@ class PrintViewManager : public NotificationObserver,
// called.
bool waiting_to_print_;
+ // Indication of success of the print job.
+ bool printing_succeeded_;
+
// Running an inner message loop inside RenderAllMissingPagesNow(). This means
// we are _blocking_ until all the necessary pages have been rendered or the
// print settings are being loaded.
diff --git a/chrome/browser/printing/printed_document.cc b/chrome/browser/printing/printed_document.cc
index f330070..c5ea1d9 100644
--- a/chrome/browser/printing/printed_document.cc
+++ b/chrome/browser/printing/printed_document.cc
@@ -67,25 +67,14 @@ void PrintedDocument::SetPage(int page_number, gfx::Emf* emf, double shrink) {
bool PrintedDocument::GetPage(int page_number,
scoped_refptr<PrintedPage>* page) {
- bool request = false;
- {
- AutoLock lock(lock_);
- PrintedPages::const_iterator itr = mutable_.pages_.find(page_number);
- if (itr != mutable_.pages_.end()) {
- if (itr->second.get()) {
- *page = itr->second;
- return true;
- }
- request = false;
- } else {
- request = true;
- // Force the creation to not repeatedly request the same page.
- mutable_.pages_[page_number];
+ AutoLock lock(lock_);
+ PrintedPages::const_iterator itr = mutable_.pages_.find(page_number);
+ if (itr != mutable_.pages_.end()) {
+ if (itr->second.get()) {
+ *page = itr->second;
+ return true;
}
}
- if (request) {
- PrintPage_ThreadJump(page_number);
- }
return false;
}
@@ -180,32 +169,6 @@ bool PrintedDocument::IsComplete() const {
return true;
}
-bool PrintedDocument::RequestMissingPages() {
- typedef std::set<int> PageNumbers;
- PageNumbers missing_pages;
- {
- AutoLock lock(lock_);
- PageNumber page(immutable_.settings_, mutable_.page_count_);
- if (page == PageNumber::npos())
- return false;
- for (; page != PageNumber::npos(); ++page) {
- PrintedPage* printed_page = mutable_.pages_[page.ToInt()].get();
- if (!printed_page || !printed_page->emf())
- missing_pages.insert(page.ToInt());
- }
- }
- if (!missing_pages.size())
- return true;
- PageNumbers::const_iterator end = missing_pages.end();
- for (PageNumbers::const_iterator itr = missing_pages.begin();
- itr != end;
- ++itr) {
- int page_number = *itr;
- PrintPage_ThreadJump(page_number);
- }
- return true;
-}
-
void PrintedDocument::DisconnectSource() {
AutoLock lock(lock_);
mutable_.source_ = NULL;
@@ -334,20 +297,6 @@ void PrintedDocument::PrintHeaderFooter(HDC context,
DCHECK_NE(res, 0);
}
-void PrintedDocument::PrintPage_ThreadJump(int page_number) {
- if (MessageLoop::current() != immutable_.source_message_loop_) {
- immutable_.source_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(
- this, &PrintedDocument::PrintPage_ThreadJump, page_number));
- } else {
- PrintedPagesSource* source = NULL;
- {
- AutoLock lock(lock_);
- source = mutable_.source_;
- }
- NOTREACHED();
- }
-}
-
PrintedDocument::Mutable::Mutable(PrintedPagesSource* source)
: source_(source),
expected_page_count_(0),
diff --git a/chrome/browser/printing/printed_document.h b/chrome/browser/printing/printed_document.h
index 6080e0d..c78f57a 100644
--- a/chrome/browser/printing/printed_document.h
+++ b/chrome/browser/printing/printed_document.h
@@ -63,13 +63,6 @@ class PrintedDocument : public base::RefCountedThreadSafe<PrintedDocument> {
// Note: locks while parsing the whole tree.
bool IsComplete() const;
- // Requests all the missing pages. Returns true if at least one page has been
- // requested. Returns false if there was not enough information to request the
- // missing pages, i.e. document_page_count_ is not initialized or no page has
- // been requested.
- // Note: locks while parsing the whole tree.
- bool RequestMissingPages();
-
// Disconnects the PrintedPage source (PrintedPagesSource). It is done when
// the source is being destroyed.
void DisconnectSource();
@@ -173,10 +166,6 @@ class PrintedDocument : public base::RefCountedThreadSafe<PrintedDocument> {
PageOverlays::VerticalPosition y,
const gfx::Font& font) const;
- // Calls the render source to render a page. Makes sure to execute the call in
- // the right thread context.
- void PrintPage_ThreadJump(int page_number);
-
// All writable data member access must be guarded by this lock. Needs to be
// mutable since it can be acquired from const member functions.
mutable Lock lock_;
diff --git a/chrome/browser/printing/win_printing_context.cc b/chrome/browser/printing/win_printing_context.cc
index 6866800..1d0ad0e 100644
--- a/chrome/browser/printing/win_printing_context.cc
+++ b/chrome/browser/printing/win_printing_context.cc
@@ -403,15 +403,17 @@ bool PrintingContext::InitializeSettings(const DEVMODE& dev_mode,
DCHECK(!in_print_job_);
DCHECK(hdc_);
- // Convert the PRINTPAGERANGE array to a PrintSettings::PageRanges vector.
PageRanges ranges_vector;
- ranges_vector.reserve(number_ranges);
- for (int i = 0; i < number_ranges; ++i) {
- PageRange range;
- // Transfert from 1-based to 0-based.
- range.from = ranges[i].nFromPage - 1;
- range.to = ranges[i].nToPage - 1;
- ranges_vector.push_back(range);
+ if (!selection_only) {
+ // Convert the PRINTPAGERANGE array to a PrintSettings::PageRanges vector.
+ ranges_vector.reserve(number_ranges);
+ for (int i = 0; i < number_ranges; ++i) {
+ PageRange range;
+ // Transfer from 1-based to 0-based.
+ range.from = ranges[i].nFromPage - 1;
+ range.to = ranges[i].nToPage - 1;
+ ranges_vector.push_back(range);
+ }
}
settings_.Init(hdc_,
dev_mode,