1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h" 6 7 #include <map> 8 9 #include "base/id_map.h" 10 #include "base/lazy_instance.h" 11 #include "base/memory/ref_counted_memory.h" 12 #include "base/metrics/histogram.h" 13 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_split.h" 15 #include "base/strings/string_util.h" 16 #include "base/strings/utf_string_conversions.h" 17 #include "base/synchronization/lock.h" 18 #include "base/values.h" 19 #include "chrome/browser/browser_process.h" 20 #include "chrome/browser/printing/background_printing_manager.h" 21 #include "chrome/browser/printing/print_preview_data_service.h" 22 #include "chrome/browser/profiles/profile.h" 23 #include "chrome/browser/ui/webui/print_preview/print_preview_handler.h" 24 #include "chrome/browser/ui/webui/theme_source.h" 25 #include "chrome/common/print_messages.h" 26 #include "chrome/common/url_constants.h" 27 #include "content/public/browser/url_data_source.h" 28 #include "content/public/browser/web_contents.h" 29 #include "content/public/browser/web_ui_data_source.h" 30 #include "grit/browser_resources.h" 31 #include "grit/chromium_strings.h" 32 #include "grit/generated_resources.h" 33 #include "grit/google_chrome_strings.h" 34 #include "printing/page_size_margins.h" 35 #include "printing/print_job_constants.h" 36 #include "ui/base/l10n/l10n_util.h" 37 #include "ui/gfx/rect.h" 38 #include "ui/web_dialogs/web_dialog_delegate.h" 39 #include "ui/web_dialogs/web_dialog_ui.h" 40 41 using content::WebContents; 42 using printing::PageSizeMargins; 43 44 namespace { 45 46 #if defined(OS_MACOSX) 47 // U+0028 U+21E7 U+2318 U+0050 U+0029 in UTF8 48 const char kAdvancedPrintShortcut[] = "\x28\xE2\x8c\xA5\xE2\x8C\x98\x50\x29"; 49 #elif defined(OS_WIN) || defined(OS_CHROMEOS) 50 const char kAdvancedPrintShortcut[] = "(Ctrl+Shift+P)"; 51 #else 52 const char kAdvancedPrintShortcut[] = "(Shift+Ctrl+P)"; 53 #endif 54 55 // Thread-safe wrapper around a std::map to keep track of mappings from 56 // PrintPreviewUI IDs to most recent print preview request IDs. 57 class PrintPreviewRequestIdMapWithLock { 58 public: 59 PrintPreviewRequestIdMapWithLock() {} 60 ~PrintPreviewRequestIdMapWithLock() {} 61 62 // Gets the value for |preview_id|. 63 // Returns true and sets |out_value| on success. 64 bool Get(int32 preview_id, int* out_value) { 65 base::AutoLock lock(lock_); 66 PrintPreviewRequestIdMap::const_iterator it = map_.find(preview_id); 67 if (it == map_.end()) 68 return false; 69 *out_value = it->second; 70 return true; 71 } 72 73 // Sets the |value| for |preview_id|. 74 void Set(int32 preview_id, int value) { 75 base::AutoLock lock(lock_); 76 map_[preview_id] = value; 77 } 78 79 // Erases the entry for |preview_id|. 80 void Erase(int32 preview_id) { 81 base::AutoLock lock(lock_); 82 map_.erase(preview_id); 83 } 84 85 private: 86 // Mapping from PrintPreviewUI ID to print preview request ID. 87 typedef std::map<int, int> PrintPreviewRequestIdMap; 88 89 PrintPreviewRequestIdMap map_; 90 base::Lock lock_; 91 92 DISALLOW_COPY_AND_ASSIGN(PrintPreviewRequestIdMapWithLock); 93 }; 94 95 // Written to on the UI thread, read from any thread. 96 base::LazyInstance<PrintPreviewRequestIdMapWithLock> 97 g_print_preview_request_id_map = LAZY_INSTANCE_INITIALIZER; 98 99 // PrintPreviewUI IDMap used to avoid exposing raw pointer addresses to WebUI. 100 // Only accessed on the UI thread. 101 base::LazyInstance<IDMap<PrintPreviewUI> > 102 g_print_preview_ui_id_map = LAZY_INSTANCE_INITIALIZER; 103 104 // PrintPreviewUI serves data for chrome://print requests. 105 // 106 // The format for requesting PDF data is as follows: 107 // chrome://print/<PrintPreviewUIID>/<PageIndex>/print.pdf 108 // 109 // Parameters (< > required): 110 // <PrintPreviewUIID> = PrintPreview UI ID 111 // <PageIndex> = Page index is zero-based or 112 // |printing::COMPLETE_PREVIEW_DOCUMENT_INDEX| to represent 113 // a print ready PDF. 114 // 115 // Example: 116 // chrome://print/123/10/print.pdf 117 // 118 // Requests to chrome://print with paths not ending in /print.pdf are used 119 // to return the markup or other resources for the print preview page itself. 120 bool HandleRequestCallback( 121 const std::string& path, 122 const content::WebUIDataSource::GotDataCallback& callback) { 123 // ChromeWebUIDataSource handles most requests except for the print preview 124 // data. 125 if (!EndsWith(path, "/print.pdf", true)) 126 return false; 127 128 // Print Preview data. 129 scoped_refptr<base::RefCountedBytes> data; 130 std::vector<std::string> url_substr; 131 base::SplitString(path, '/', &url_substr); 132 int preview_ui_id = -1; 133 int page_index = 0; 134 if (url_substr.size() == 3 && 135 base::StringToInt(url_substr[0], &preview_ui_id), 136 base::StringToInt(url_substr[1], &page_index) && 137 preview_ui_id >= 0) { 138 PrintPreviewDataService::GetInstance()->GetDataEntry( 139 preview_ui_id, page_index, &data); 140 } 141 if (data.get()) { 142 callback.Run(data.get()); 143 return true; 144 } 145 // Invalid request. 146 scoped_refptr<base::RefCountedBytes> empty_bytes(new base::RefCountedBytes); 147 callback.Run(empty_bytes.get()); 148 return true; 149 } 150 151 content::WebUIDataSource* CreatePrintPreviewUISource() { 152 content::WebUIDataSource* source = 153 content::WebUIDataSource::Create(chrome::kChromeUIPrintHost); 154 #if defined(OS_CHROMEOS) 155 source->AddLocalizedString("title", 156 IDS_PRINT_PREVIEW_GOOGLE_CLOUD_PRINT_TITLE); 157 #else 158 source->AddLocalizedString("title", IDS_PRINT_PREVIEW_TITLE); 159 #endif 160 source->AddLocalizedString("loading", IDS_PRINT_PREVIEW_LOADING); 161 source->AddLocalizedString("noPlugin", IDS_PRINT_PREVIEW_NO_PLUGIN); 162 source->AddLocalizedString("launchNativeDialog", 163 IDS_PRINT_PREVIEW_NATIVE_DIALOG); 164 source->AddLocalizedString("previewFailed", IDS_PRINT_PREVIEW_FAILED); 165 source->AddLocalizedString("invalidPrinterSettings", 166 IDS_PRINT_INVALID_PRINTER_SETTINGS); 167 source->AddLocalizedString("printButton", IDS_PRINT_PREVIEW_PRINT_BUTTON); 168 source->AddLocalizedString("saveButton", IDS_PRINT_PREVIEW_SAVE_BUTTON); 169 source->AddLocalizedString("cancelButton", IDS_PRINT_PREVIEW_CANCEL_BUTTON); 170 source->AddLocalizedString("printing", IDS_PRINT_PREVIEW_PRINTING); 171 source->AddLocalizedString("printingToPDFInProgress", 172 IDS_PRINT_PREVIEW_PRINTING_TO_PDF_IN_PROGRESS); 173 #if defined(OS_MACOSX) 174 source->AddLocalizedString("openingPDFInPreview", 175 IDS_PRINT_PREVIEW_OPENING_PDF_IN_PREVIEW); 176 #endif 177 source->AddLocalizedString("destinationLabel", 178 IDS_PRINT_PREVIEW_DESTINATION_LABEL); 179 source->AddLocalizedString("copiesLabel", IDS_PRINT_PREVIEW_COPIES_LABEL); 180 source->AddLocalizedString("examplePageRangeText", 181 IDS_PRINT_PREVIEW_EXAMPLE_PAGE_RANGE_TEXT); 182 source->AddLocalizedString("layoutLabel", IDS_PRINT_PREVIEW_LAYOUT_LABEL); 183 source->AddLocalizedString("optionAllPages", 184 IDS_PRINT_PREVIEW_OPTION_ALL_PAGES); 185 source->AddLocalizedString("optionBw", IDS_PRINT_PREVIEW_OPTION_BW); 186 source->AddLocalizedString("optionCollate", IDS_PRINT_PREVIEW_OPTION_COLLATE); 187 source->AddLocalizedString("optionColor", IDS_PRINT_PREVIEW_OPTION_COLOR); 188 source->AddLocalizedString("optionLandscape", 189 IDS_PRINT_PREVIEW_OPTION_LANDSCAPE); 190 source->AddLocalizedString("optionPortrait", 191 IDS_PRINT_PREVIEW_OPTION_PORTRAIT); 192 source->AddLocalizedString("optionTwoSided", 193 IDS_PRINT_PREVIEW_OPTION_TWO_SIDED); 194 source->AddLocalizedString("pagesLabel", IDS_PRINT_PREVIEW_PAGES_LABEL); 195 source->AddLocalizedString("pageRangeTextBox", 196 IDS_PRINT_PREVIEW_PAGE_RANGE_TEXT); 197 source->AddLocalizedString("pageRangeRadio", 198 IDS_PRINT_PREVIEW_PAGE_RANGE_RADIO); 199 source->AddLocalizedString("printToPDF", IDS_PRINT_PREVIEW_PRINT_TO_PDF); 200 source->AddLocalizedString("printPreviewSummaryFormatShort", 201 IDS_PRINT_PREVIEW_SUMMARY_FORMAT_SHORT); 202 source->AddLocalizedString("printPreviewSummaryFormatLong", 203 IDS_PRINT_PREVIEW_SUMMARY_FORMAT_LONG); 204 source->AddLocalizedString("printPreviewSheetsLabelSingular", 205 IDS_PRINT_PREVIEW_SHEETS_LABEL_SINGULAR); 206 source->AddLocalizedString("printPreviewSheetsLabelPlural", 207 IDS_PRINT_PREVIEW_SHEETS_LABEL_PLURAL); 208 source->AddLocalizedString("printPreviewPageLabelSingular", 209 IDS_PRINT_PREVIEW_PAGE_LABEL_SINGULAR); 210 source->AddLocalizedString("printPreviewPageLabelPlural", 211 IDS_PRINT_PREVIEW_PAGE_LABEL_PLURAL); 212 const base::string16 shortcut_text(base::UTF8ToUTF16(kAdvancedPrintShortcut)); 213 #if defined(OS_CHROMEOS) 214 source->AddString( 215 "systemDialogOption", 216 l10n_util::GetStringFUTF16( 217 IDS_PRINT_PREVIEW_CLOUD_DIALOG_OPTION, 218 l10n_util::GetStringUTF16(IDS_GOOGLE_CLOUD_PRINT), 219 shortcut_text)); 220 #else 221 source->AddString( 222 "systemDialogOption", 223 l10n_util::GetStringFUTF16( 224 IDS_PRINT_PREVIEW_SYSTEM_DIALOG_OPTION, 225 shortcut_text)); 226 #endif 227 source->AddString( 228 "cloudPrintDialogOption", 229 l10n_util::GetStringFUTF16( 230 IDS_PRINT_PREVIEW_CLOUD_DIALOG_OPTION_NO_SHORTCUT, 231 l10n_util::GetStringUTF16(IDS_GOOGLE_CLOUD_PRINT))); 232 #if defined(OS_MACOSX) 233 source->AddLocalizedString("openPdfInPreviewOption", 234 IDS_PRINT_PREVIEW_OPEN_PDF_IN_PREVIEW_APP); 235 #endif 236 source->AddString( 237 "printWithCloudPrintWait", 238 l10n_util::GetStringFUTF16( 239 IDS_PRINT_PREVIEW_PRINT_WITH_CLOUD_PRINT_WAIT, 240 l10n_util::GetStringUTF16(IDS_GOOGLE_CLOUD_PRINT))); 241 source->AddString( 242 "noDestsPromoLearnMoreUrl", 243 chrome::kCloudPrintNoDestinationsLearnMoreURL); 244 source->AddLocalizedString("pageRangeInstruction", 245 IDS_PRINT_PREVIEW_PAGE_RANGE_INSTRUCTION); 246 source->AddLocalizedString("copiesInstruction", 247 IDS_PRINT_PREVIEW_COPIES_INSTRUCTION); 248 source->AddLocalizedString("incrementTitle", 249 IDS_PRINT_PREVIEW_INCREMENT_TITLE); 250 source->AddLocalizedString("decrementTitle", 251 IDS_PRINT_PREVIEW_DECREMENT_TITLE); 252 source->AddLocalizedString("printPagesLabel", 253 IDS_PRINT_PREVIEW_PRINT_PAGES_LABEL); 254 source->AddLocalizedString("optionsLabel", IDS_PRINT_PREVIEW_OPTIONS_LABEL); 255 source->AddLocalizedString("optionHeaderFooter", 256 IDS_PRINT_PREVIEW_OPTION_HEADER_FOOTER); 257 source->AddLocalizedString("optionFitToPage", 258 IDS_PRINT_PREVIEW_OPTION_FIT_TO_PAGE); 259 source->AddLocalizedString( 260 "optionBackgroundColorsAndImages", 261 IDS_PRINT_PREVIEW_OPTION_BACKGROUND_COLORS_AND_IMAGES); 262 source->AddLocalizedString("optionSelectionOnly", 263 IDS_PRINT_PREVIEW_OPTION_SELECTION_ONLY); 264 source->AddLocalizedString("marginsLabel", IDS_PRINT_PREVIEW_MARGINS_LABEL); 265 source->AddLocalizedString("defaultMargins", 266 IDS_PRINT_PREVIEW_DEFAULT_MARGINS); 267 source->AddLocalizedString("noMargins", IDS_PRINT_PREVIEW_NO_MARGINS); 268 source->AddLocalizedString("customMargins", IDS_PRINT_PREVIEW_CUSTOM_MARGINS); 269 source->AddLocalizedString("minimumMargins", 270 IDS_PRINT_PREVIEW_MINIMUM_MARGINS); 271 source->AddLocalizedString("top", IDS_PRINT_PREVIEW_TOP_MARGIN_LABEL); 272 source->AddLocalizedString("bottom", IDS_PRINT_PREVIEW_BOTTOM_MARGIN_LABEL); 273 source->AddLocalizedString("left", IDS_PRINT_PREVIEW_LEFT_MARGIN_LABEL); 274 source->AddLocalizedString("right", IDS_PRINT_PREVIEW_RIGHT_MARGIN_LABEL); 275 source->AddLocalizedString("mediaSizeLabel", 276 IDS_PRINT_PREVIEW_MEDIA_SIZE_LABEL); 277 source->AddLocalizedString("destinationSearchTitle", 278 IDS_PRINT_PREVIEW_DESTINATION_SEARCH_TITLE); 279 source->AddLocalizedString("userInfo", IDS_PRINT_PREVIEW_USER_INFO); 280 source->AddLocalizedString("accountSelectTitle", 281 IDS_PRINT_PREVIEW_ACCOUNT_SELECT_TITLE); 282 source->AddLocalizedString("addAccountTitle", 283 IDS_PRINT_PREVIEW_ADD_ACCOUNT_TITLE); 284 source->AddLocalizedString("cloudPrintPromotion", 285 IDS_PRINT_PREVIEW_CLOUD_PRINT_PROMOTION); 286 source->AddLocalizedString("searchBoxPlaceholder", 287 IDS_PRINT_PREVIEW_SEARCH_BOX_PLACEHOLDER); 288 source->AddLocalizedString("noDestinationsMessage", 289 IDS_PRINT_PREVIEW_NO_DESTINATIONS_MESSAGE); 290 source->AddLocalizedString("showAllButtonText", 291 IDS_PRINT_PREVIEW_SHOW_ALL_BUTTON_TEXT); 292 source->AddLocalizedString("destinationCount", 293 IDS_PRINT_PREVIEW_DESTINATION_COUNT); 294 source->AddLocalizedString("recentDestinationsTitle", 295 IDS_PRINT_PREVIEW_RECENT_DESTINATIONS_TITLE); 296 source->AddLocalizedString("localDestinationsTitle", 297 IDS_PRINT_PREVIEW_LOCAL_DESTINATIONS_TITLE); 298 source->AddLocalizedString("cloudDestinationsTitle", 299 IDS_PRINT_PREVIEW_CLOUD_DESTINATIONS_TITLE); 300 source->AddLocalizedString("manage", IDS_PRINT_PREVIEW_MANAGE); 301 source->AddLocalizedString("setupCloudPrinters", 302 IDS_PRINT_PREVIEW_SETUP_CLOUD_PRINTERS); 303 source->AddLocalizedString("changeDestination", 304 IDS_PRINT_PREVIEW_CHANGE_DESTINATION); 305 source->AddLocalizedString("offlineForYear", 306 IDS_PRINT_PREVIEW_OFFLINE_FOR_YEAR); 307 source->AddLocalizedString("offlineForMonth", 308 IDS_PRINT_PREVIEW_OFFLINE_FOR_MONTH); 309 source->AddLocalizedString("offlineForWeek", 310 IDS_PRINT_PREVIEW_OFFLINE_FOR_WEEK); 311 source->AddLocalizedString("offline", IDS_PRINT_PREVIEW_OFFLINE); 312 source->AddLocalizedString("fedexTos", IDS_PRINT_PREVIEW_FEDEX_TOS); 313 source->AddLocalizedString("tosCheckboxLabel", 314 IDS_PRINT_PREVIEW_TOS_CHECKBOX_LABEL); 315 source->AddLocalizedString("noDestsPromoTitle", 316 IDS_PRINT_PREVIEW_NO_DESTS_PROMO_TITLE); 317 source->AddLocalizedString("noDestsPromoBody", 318 IDS_PRINT_PREVIEW_NO_DESTS_PROMO_BODY); 319 source->AddLocalizedString("noDestsPromoGcpDesc", 320 IDS_PRINT_PREVIEW_NO_DESTS_GCP_DESC); 321 source->AddLocalizedString("learnMore", 322 IDS_LEARN_MORE); 323 source->AddLocalizedString( 324 "noDestsPromoAddPrinterButtonLabel", 325 IDS_PRINT_PREVIEW_NO_DESTS_PROMO_ADD_PRINTER_BUTTON_LABEL); 326 source->AddLocalizedString( 327 "noDestsPromoNotNowButtonLabel", 328 IDS_PRINT_PREVIEW_NO_DESTS_PROMO_NOT_NOW_BUTTON_LABEL); 329 source->AddLocalizedString("couldNotPrint", 330 IDS_PRINT_PREVIEW_COULD_NOT_PRINT); 331 source->AddLocalizedString("registerPromoButtonText", 332 IDS_PRINT_PREVIEW_REGISTER_PROMO_BUTTON_TEXT); 333 334 source->SetJsonPath("strings.js"); 335 source->AddResourcePath("print_preview.js", IDR_PRINT_PREVIEW_JS); 336 source->AddResourcePath("images/printer.png", 337 IDR_PRINT_PREVIEW_IMAGES_PRINTER); 338 source->AddResourcePath("images/printer_shared.png", 339 IDR_PRINT_PREVIEW_IMAGES_PRINTER_SHARED); 340 source->AddResourcePath("images/third_party.png", 341 IDR_PRINT_PREVIEW_IMAGES_THIRD_PARTY); 342 source->AddResourcePath("images/third_party_fedex.png", 343 IDR_PRINT_PREVIEW_IMAGES_THIRD_PARTY_FEDEX); 344 source->AddResourcePath("images/google_doc.png", 345 IDR_PRINT_PREVIEW_IMAGES_GOOGLE_DOC); 346 source->AddResourcePath("images/pdf.png", IDR_PRINT_PREVIEW_IMAGES_PDF); 347 source->AddResourcePath("images/mobile.png", IDR_PRINT_PREVIEW_IMAGES_MOBILE); 348 source->AddResourcePath("images/mobile_shared.png", 349 IDR_PRINT_PREVIEW_IMAGES_MOBILE_SHARED); 350 source->SetDefaultResource(IDR_PRINT_PREVIEW_HTML); 351 source->SetRequestFilter(base::Bind(&HandleRequestCallback)); 352 source->OverrideContentSecurityPolicyObjectSrc("object-src 'self';"); 353 return source; 354 } 355 356 PrintPreviewUI::TestingDelegate* g_testing_delegate = NULL; 357 358 } // namespace 359 360 PrintPreviewUI::PrintPreviewUI(content::WebUI* web_ui) 361 : ConstrainedWebDialogUI(web_ui), 362 initial_preview_start_time_(base::TimeTicks::Now()), 363 id_(g_print_preview_ui_id_map.Get().Add(this)), 364 handler_(NULL), 365 source_is_modifiable_(true), 366 source_has_selection_(false), 367 dialog_closed_(false) { 368 // Set up the chrome://print/ data source. 369 Profile* profile = Profile::FromWebUI(web_ui); 370 content::WebUIDataSource::Add(profile, CreatePrintPreviewUISource()); 371 372 // Set up the chrome://theme/ source. 373 content::URLDataSource::Add(profile, new ThemeSource(profile)); 374 375 // WebUI owns |handler_|. 376 handler_ = new PrintPreviewHandler(); 377 web_ui->AddMessageHandler(handler_); 378 379 g_print_preview_request_id_map.Get().Set(id_, -1); 380 } 381 382 PrintPreviewUI::~PrintPreviewUI() { 383 print_preview_data_service()->RemoveEntry(id_); 384 g_print_preview_request_id_map.Get().Erase(id_); 385 g_print_preview_ui_id_map.Get().Remove(id_); 386 } 387 388 void PrintPreviewUI::GetPrintPreviewDataForIndex( 389 int index, 390 scoped_refptr<base::RefCountedBytes>* data) { 391 print_preview_data_service()->GetDataEntry(id_, index, data); 392 } 393 394 void PrintPreviewUI::SetPrintPreviewDataForIndex( 395 int index, 396 const base::RefCountedBytes* data) { 397 print_preview_data_service()->SetDataEntry(id_, index, data); 398 } 399 400 void PrintPreviewUI::ClearAllPreviewData() { 401 print_preview_data_service()->RemoveEntry(id_); 402 } 403 404 int PrintPreviewUI::GetAvailableDraftPageCount() { 405 return print_preview_data_service()->GetAvailableDraftPageCount(id_); 406 } 407 408 void PrintPreviewUI::SetInitiatorTitle( 409 const base::string16& job_title) { 410 initiator_title_ = job_title; 411 } 412 413 // static 414 void PrintPreviewUI::SetInitialParams( 415 content::WebContents* print_preview_dialog, 416 const PrintHostMsg_RequestPrintPreview_Params& params) { 417 if (!print_preview_dialog || !print_preview_dialog->GetWebUI()) 418 return; 419 PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>( 420 print_preview_dialog->GetWebUI()->GetController()); 421 print_preview_ui->source_is_modifiable_ = params.is_modifiable; 422 print_preview_ui->source_has_selection_ = params.has_selection; 423 print_preview_ui->print_selection_only_ = params.selection_only; 424 } 425 426 // static 427 void PrintPreviewUI::GetCurrentPrintPreviewStatus(int32 preview_ui_id, 428 int request_id, 429 bool* cancel) { 430 int current_id = -1; 431 if (!g_print_preview_request_id_map.Get().Get(preview_ui_id, ¤t_id)) { 432 *cancel = true; 433 return; 434 } 435 *cancel = (request_id != current_id); 436 } 437 438 int32 PrintPreviewUI::GetIDForPrintPreviewUI() const { 439 return id_; 440 } 441 442 void PrintPreviewUI::OnPrintPreviewDialogClosed() { 443 WebContents* preview_dialog = web_ui()->GetWebContents(); 444 printing::BackgroundPrintingManager* background_printing_manager = 445 g_browser_process->background_printing_manager(); 446 if (background_printing_manager->HasPrintPreviewDialog(preview_dialog)) 447 return; 448 OnClosePrintPreviewDialog(); 449 } 450 451 void PrintPreviewUI::OnInitiatorClosed() { 452 WebContents* preview_dialog = web_ui()->GetWebContents(); 453 printing::BackgroundPrintingManager* background_printing_manager = 454 g_browser_process->background_printing_manager(); 455 if (background_printing_manager->HasPrintPreviewDialog(preview_dialog)) 456 web_ui()->CallJavascriptFunction("cancelPendingPrintRequest"); 457 else 458 OnClosePrintPreviewDialog(); 459 } 460 461 void PrintPreviewUI::OnPrintPreviewRequest(int request_id) { 462 if (!initial_preview_start_time_.is_null()) { 463 UMA_HISTOGRAM_TIMES("PrintPreview.InitializationTime", 464 base::TimeTicks::Now() - initial_preview_start_time_); 465 } 466 g_print_preview_request_id_map.Get().Set(id_, request_id); 467 } 468 469 void PrintPreviewUI::OnShowSystemDialog() { 470 web_ui()->CallJavascriptFunction("onSystemDialogLinkClicked"); 471 } 472 473 void PrintPreviewUI::OnDidGetPreviewPageCount( 474 const PrintHostMsg_DidGetPreviewPageCount_Params& params) { 475 DCHECK_GT(params.page_count, 0); 476 if (g_testing_delegate) 477 g_testing_delegate->DidGetPreviewPageCount(params.page_count); 478 base::FundamentalValue count(params.page_count); 479 base::FundamentalValue request_id(params.preview_request_id); 480 web_ui()->CallJavascriptFunction("onDidGetPreviewPageCount", 481 count, 482 request_id); 483 } 484 485 void PrintPreviewUI::OnDidGetDefaultPageLayout( 486 const PageSizeMargins& page_layout, const gfx::Rect& printable_area, 487 bool has_custom_page_size_style) { 488 if (page_layout.margin_top < 0 || page_layout.margin_left < 0 || 489 page_layout.margin_bottom < 0 || page_layout.margin_right < 0 || 490 page_layout.content_width < 0 || page_layout.content_height < 0 || 491 printable_area.width() <= 0 || printable_area.height() <= 0) { 492 NOTREACHED(); 493 return; 494 } 495 496 base::DictionaryValue layout; 497 layout.SetDouble(printing::kSettingMarginTop, page_layout.margin_top); 498 layout.SetDouble(printing::kSettingMarginLeft, page_layout.margin_left); 499 layout.SetDouble(printing::kSettingMarginBottom, page_layout.margin_bottom); 500 layout.SetDouble(printing::kSettingMarginRight, page_layout.margin_right); 501 layout.SetDouble(printing::kSettingContentWidth, page_layout.content_width); 502 layout.SetDouble(printing::kSettingContentHeight, page_layout.content_height); 503 layout.SetInteger(printing::kSettingPrintableAreaX, printable_area.x()); 504 layout.SetInteger(printing::kSettingPrintableAreaY, printable_area.y()); 505 layout.SetInteger(printing::kSettingPrintableAreaWidth, 506 printable_area.width()); 507 layout.SetInteger(printing::kSettingPrintableAreaHeight, 508 printable_area.height()); 509 510 base::FundamentalValue has_page_size_style(has_custom_page_size_style); 511 web_ui()->CallJavascriptFunction("onDidGetDefaultPageLayout", layout, 512 has_page_size_style); 513 } 514 515 void PrintPreviewUI::OnDidPreviewPage(int page_number, 516 int preview_request_id) { 517 DCHECK_GE(page_number, 0); 518 base::FundamentalValue number(page_number); 519 base::FundamentalValue ui_identifier(id_); 520 base::FundamentalValue request_id(preview_request_id); 521 if (g_testing_delegate) 522 g_testing_delegate->DidRenderPreviewPage(web_ui()->GetWebContents()); 523 web_ui()->CallJavascriptFunction( 524 "onDidPreviewPage", number, ui_identifier, request_id); 525 if (g_testing_delegate && g_testing_delegate->IsAutoCancelEnabled()) 526 web_ui()->CallJavascriptFunction("autoCancelForTesting"); 527 } 528 529 void PrintPreviewUI::OnPreviewDataIsAvailable(int expected_pages_count, 530 int preview_request_id) { 531 VLOG(1) << "Print preview request finished with " 532 << expected_pages_count << " pages"; 533 534 if (!initial_preview_start_time_.is_null()) { 535 UMA_HISTOGRAM_TIMES("PrintPreview.InitialDisplayTime", 536 base::TimeTicks::Now() - initial_preview_start_time_); 537 UMA_HISTOGRAM_COUNTS("PrintPreview.PageCount.Initial", 538 expected_pages_count); 539 UMA_HISTOGRAM_COUNTS( 540 "PrintPreview.RegeneratePreviewRequest.BeforeFirstData", 541 handler_->regenerate_preview_request_count()); 542 initial_preview_start_time_ = base::TimeTicks(); 543 } 544 base::FundamentalValue ui_identifier(id_); 545 base::FundamentalValue ui_preview_request_id(preview_request_id); 546 web_ui()->CallJavascriptFunction("updatePrintPreview", ui_identifier, 547 ui_preview_request_id); 548 } 549 550 void PrintPreviewUI::OnPrintPreviewDialogDestroyed() { 551 handler_->OnPrintPreviewDialogDestroyed(); 552 } 553 554 void PrintPreviewUI::OnFileSelectionCancelled() { 555 web_ui()->CallJavascriptFunction("fileSelectionCancelled"); 556 } 557 558 void PrintPreviewUI::OnCancelPendingPreviewRequest() { 559 g_print_preview_request_id_map.Get().Set(id_, -1); 560 } 561 562 void PrintPreviewUI::OnPrintPreviewFailed() { 563 handler_->OnPrintPreviewFailed(); 564 web_ui()->CallJavascriptFunction("printPreviewFailed"); 565 } 566 567 void PrintPreviewUI::OnInvalidPrinterSettings() { 568 web_ui()->CallJavascriptFunction("invalidPrinterSettings"); 569 } 570 571 PrintPreviewDataService* PrintPreviewUI::print_preview_data_service() { 572 return PrintPreviewDataService::GetInstance(); 573 } 574 575 void PrintPreviewUI::OnHidePreviewDialog() { 576 WebContents* preview_dialog = web_ui()->GetWebContents(); 577 printing::BackgroundPrintingManager* background_printing_manager = 578 g_browser_process->background_printing_manager(); 579 if (background_printing_manager->HasPrintPreviewDialog(preview_dialog)) 580 return; 581 582 ConstrainedWebDialogDelegate* delegate = GetConstrainedDelegate(); 583 if (!delegate) 584 return; 585 delegate->ReleaseWebContentsOnDialogClose(); 586 background_printing_manager->OwnPrintPreviewDialog(preview_dialog); 587 OnClosePrintPreviewDialog(); 588 } 589 590 void PrintPreviewUI::OnClosePrintPreviewDialog() { 591 if (dialog_closed_) 592 return; 593 dialog_closed_ = true; 594 ConstrainedWebDialogDelegate* delegate = GetConstrainedDelegate(); 595 if (!delegate) 596 return; 597 delegate->GetWebDialogDelegate()->OnDialogClosed(std::string()); 598 delegate->OnDialogCloseFromWebUI(); 599 } 600 601 void PrintPreviewUI::OnReloadPrintersList() { 602 web_ui()->CallJavascriptFunction("reloadPrintersList"); 603 } 604 605 void PrintPreviewUI::OnPrintPreviewScalingDisabled() { 606 web_ui()->CallJavascriptFunction("printScalingDisabledForSourcePDF"); 607 } 608 609 // static 610 void PrintPreviewUI::SetDelegateForTesting(TestingDelegate* delegate) { 611 g_testing_delegate = delegate; 612 } 613