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) 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_PREVIEW_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 string16 shortcut_text(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->AddLocalizedString("pageRangeInstruction", 242 IDS_PRINT_PREVIEW_PAGE_RANGE_INSTRUCTION); 243 source->AddLocalizedString("copiesInstruction", 244 IDS_PRINT_PREVIEW_COPIES_INSTRUCTION); 245 source->AddLocalizedString("incrementTitle", 246 IDS_PRINT_PREVIEW_INCREMENT_TITLE); 247 source->AddLocalizedString("decrementTitle", 248 IDS_PRINT_PREVIEW_DECREMENT_TITLE); 249 source->AddLocalizedString("printPagesLabel", 250 IDS_PRINT_PREVIEW_PRINT_PAGES_LABEL); 251 source->AddLocalizedString("optionsLabel", IDS_PRINT_PREVIEW_OPTIONS_LABEL); 252 source->AddLocalizedString("optionHeaderFooter", 253 IDS_PRINT_PREVIEW_OPTION_HEADER_FOOTER); 254 source->AddLocalizedString("optionFitToPage", 255 IDS_PRINT_PREVIEW_OPTION_FIT_TO_PAGE); 256 source->AddLocalizedString( 257 "optionBackgroundColorsAndImages", 258 IDS_PRINT_PREVIEW_OPTION_BACKGROUND_COLORS_AND_IMAGES); 259 source->AddLocalizedString("optionSelectionOnly", 260 IDS_PRINT_PREVIEW_OPTION_SELECTION_ONLY); 261 source->AddLocalizedString("marginsLabel", IDS_PRINT_PREVIEW_MARGINS_LABEL); 262 source->AddLocalizedString("defaultMargins", 263 IDS_PRINT_PREVIEW_DEFAULT_MARGINS); 264 source->AddLocalizedString("noMargins", IDS_PRINT_PREVIEW_NO_MARGINS); 265 source->AddLocalizedString("customMargins", IDS_PRINT_PREVIEW_CUSTOM_MARGINS); 266 source->AddLocalizedString("minimumMargins", 267 IDS_PRINT_PREVIEW_MINIMUM_MARGINS); 268 source->AddLocalizedString("top", IDS_PRINT_PREVIEW_TOP_MARGIN_LABEL); 269 source->AddLocalizedString("bottom", IDS_PRINT_PREVIEW_BOTTOM_MARGIN_LABEL); 270 source->AddLocalizedString("left", IDS_PRINT_PREVIEW_LEFT_MARGIN_LABEL); 271 source->AddLocalizedString("right", IDS_PRINT_PREVIEW_RIGHT_MARGIN_LABEL); 272 source->AddLocalizedString("destinationSearchTitle", 273 IDS_PRINT_PREVIEW_DESTINATION_SEARCH_TITLE); 274 source->AddLocalizedString("userInfo", IDS_PRINT_PREVIEW_USER_INFO); 275 source->AddLocalizedString("cloudPrintPromotion", 276 IDS_PRINT_PREVIEW_CLOUD_PRINT_PROMOTION); 277 source->AddLocalizedString("searchBoxPlaceholder", 278 IDS_PRINT_PREVIEW_SEARCH_BOX_PLACEHOLDER); 279 source->AddLocalizedString("noDestinationsMessage", 280 IDS_PRINT_PREVIEW_NO_DESTINATIONS_MESSAGE); 281 source->AddLocalizedString("showAllButtonText", 282 IDS_PRINT_PREVIEW_SHOW_ALL_BUTTON_TEXT); 283 source->AddLocalizedString("destinationCount", 284 IDS_PRINT_PREVIEW_DESTINATION_COUNT); 285 source->AddLocalizedString("recentDestinationsTitle", 286 IDS_PRINT_PREVIEW_RECENT_DESTINATIONS_TITLE); 287 source->AddLocalizedString("localDestinationsTitle", 288 IDS_PRINT_PREVIEW_LOCAL_DESTINATIONS_TITLE); 289 source->AddLocalizedString("cloudDestinationsTitle", 290 IDS_PRINT_PREVIEW_CLOUD_DESTINATIONS_TITLE); 291 source->AddLocalizedString("manage", IDS_PRINT_PREVIEW_MANAGE); 292 source->AddLocalizedString("setupCloudPrinters", 293 IDS_PRINT_PREVIEW_SETUP_CLOUD_PRINTERS); 294 source->AddLocalizedString("changeDestination", 295 IDS_PRINT_PREVIEW_CHANGE_DESTINATION); 296 source->AddLocalizedString("offlineForYear", 297 IDS_PRINT_PREVIEW_OFFLINE_FOR_YEAR); 298 source->AddLocalizedString("offlineForMonth", 299 IDS_PRINT_PREVIEW_OFFLINE_FOR_MONTH); 300 source->AddLocalizedString("offlineForWeek", 301 IDS_PRINT_PREVIEW_OFFLINE_FOR_WEEK); 302 source->AddLocalizedString("offline", IDS_PRINT_PREVIEW_OFFLINE); 303 source->AddLocalizedString("fedexTos", IDS_PRINT_PREVIEW_FEDEX_TOS); 304 source->AddLocalizedString("tosCheckboxLabel", 305 IDS_PRINT_PREVIEW_TOS_CHECKBOX_LABEL); 306 source->AddLocalizedString("noDestsPromoTitle", 307 IDS_PRINT_PREVIEW_NO_DESTS_PROMO_TITLE); 308 source->AddLocalizedString("noDestsPromoBody", 309 IDS_PRINT_PREVIEW_NO_DESTS_PROMO_BODY); 310 source->AddLocalizedString("noDestsPromoGcpDesc", 311 IDS_PRINT_PREVIEW_NO_DESTS_GCP_DESC); 312 source->AddLocalizedString( 313 "noDestsPromoAddPrinterButtonLabel", 314 IDS_PRINT_PREVIEW_NO_DESTS_PROMO_ADD_PRINTER_BUTTON_LABEL); 315 source->AddLocalizedString( 316 "noDestsPromoNotNowButtonLabel", 317 IDS_PRINT_PREVIEW_NO_DESTS_PROMO_NOT_NOW_BUTTON_LABEL); 318 319 source->SetJsonPath("strings.js"); 320 source->AddResourcePath("print_preview.js", IDR_PRINT_PREVIEW_JS); 321 source->AddResourcePath("images/printer.png", 322 IDR_PRINT_PREVIEW_IMAGES_PRINTER); 323 source->AddResourcePath("images/printer_shared.png", 324 IDR_PRINT_PREVIEW_IMAGES_PRINTER_SHARED); 325 source->AddResourcePath("images/third_party.png", 326 IDR_PRINT_PREVIEW_IMAGES_THIRD_PARTY); 327 source->AddResourcePath("images/third_party_fedex.png", 328 IDR_PRINT_PREVIEW_IMAGES_THIRD_PARTY_FEDEX); 329 source->AddResourcePath("images/google_doc.png", 330 IDR_PRINT_PREVIEW_IMAGES_GOOGLE_DOC); 331 source->AddResourcePath("images/pdf.png", IDR_PRINT_PREVIEW_IMAGES_PDF); 332 source->AddResourcePath("images/mobile.png", IDR_PRINT_PREVIEW_IMAGES_MOBILE); 333 source->AddResourcePath("images/mobile_shared.png", 334 IDR_PRINT_PREVIEW_IMAGES_MOBILE_SHARED); 335 source->SetDefaultResource(IDR_PRINT_PREVIEW_HTML); 336 source->SetRequestFilter(base::Bind(&HandleRequestCallback)); 337 source->OverrideContentSecurityPolicyObjectSrc("object-src 'self';"); 338 return source; 339 } 340 341 } // namespace 342 343 PrintPreviewUI::PrintPreviewUI(content::WebUI* web_ui) 344 : ConstrainedWebDialogUI(web_ui), 345 initial_preview_start_time_(base::TimeTicks::Now()), 346 id_(g_print_preview_ui_id_map.Get().Add(this)), 347 handler_(NULL), 348 source_is_modifiable_(true), 349 source_has_selection_(false), 350 dialog_closed_(false) { 351 // Set up the chrome://print/ data source. 352 Profile* profile = Profile::FromWebUI(web_ui); 353 content::WebUIDataSource::Add(profile, CreatePrintPreviewUISource()); 354 355 // Set up the chrome://theme/ source. 356 content::URLDataSource::Add(profile, new ThemeSource(profile)); 357 358 // WebUI owns |handler_|. 359 handler_ = new PrintPreviewHandler(); 360 web_ui->AddMessageHandler(handler_); 361 362 g_print_preview_request_id_map.Get().Set(id_, -1); 363 } 364 365 PrintPreviewUI::~PrintPreviewUI() { 366 print_preview_data_service()->RemoveEntry(id_); 367 g_print_preview_request_id_map.Get().Erase(id_); 368 g_print_preview_ui_id_map.Get().Remove(id_); 369 } 370 371 void PrintPreviewUI::GetPrintPreviewDataForIndex( 372 int index, 373 scoped_refptr<base::RefCountedBytes>* data) { 374 print_preview_data_service()->GetDataEntry(id_, index, data); 375 } 376 377 void PrintPreviewUI::SetPrintPreviewDataForIndex( 378 int index, 379 const base::RefCountedBytes* data) { 380 print_preview_data_service()->SetDataEntry(id_, index, data); 381 } 382 383 void PrintPreviewUI::ClearAllPreviewData() { 384 print_preview_data_service()->RemoveEntry(id_); 385 } 386 387 int PrintPreviewUI::GetAvailableDraftPageCount() { 388 return print_preview_data_service()->GetAvailableDraftPageCount(id_); 389 } 390 391 void PrintPreviewUI::SetInitiatorTitle( 392 const string16& job_title) { 393 initiator_title_ = job_title; 394 } 395 396 // static 397 void PrintPreviewUI::SetInitialParams( 398 content::WebContents* print_preview_dialog, 399 const PrintHostMsg_RequestPrintPreview_Params& params) { 400 if (!print_preview_dialog || !print_preview_dialog->GetWebUI()) 401 return; 402 PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>( 403 print_preview_dialog->GetWebUI()->GetController()); 404 print_preview_ui->source_is_modifiable_ = params.is_modifiable; 405 print_preview_ui->source_has_selection_ = params.has_selection; 406 print_preview_ui->print_selection_only_ = params.selection_only; 407 } 408 409 // static 410 void PrintPreviewUI::GetCurrentPrintPreviewStatus(int32 preview_ui_id, 411 int request_id, 412 bool* cancel) { 413 int current_id = -1; 414 if (!g_print_preview_request_id_map.Get().Get(preview_ui_id, ¤t_id)) { 415 *cancel = true; 416 return; 417 } 418 *cancel = (request_id != current_id); 419 } 420 421 int32 PrintPreviewUI::GetIDForPrintPreviewUI() const { 422 return id_; 423 } 424 425 void PrintPreviewUI::OnPrintPreviewDialogClosed() { 426 WebContents* preview_dialog = web_ui()->GetWebContents(); 427 printing::BackgroundPrintingManager* background_printing_manager = 428 g_browser_process->background_printing_manager(); 429 if (background_printing_manager->HasPrintPreviewDialog(preview_dialog)) 430 return; 431 OnClosePrintPreviewDialog(); 432 } 433 434 void PrintPreviewUI::OnInitiatorClosed() { 435 WebContents* preview_dialog = web_ui()->GetWebContents(); 436 printing::BackgroundPrintingManager* background_printing_manager = 437 g_browser_process->background_printing_manager(); 438 if (background_printing_manager->HasPrintPreviewDialog(preview_dialog)) 439 web_ui()->CallJavascriptFunction("cancelPendingPrintRequest"); 440 else 441 OnClosePrintPreviewDialog(); 442 } 443 444 void PrintPreviewUI::OnPrintPreviewRequest(int request_id) { 445 g_print_preview_request_id_map.Get().Set(id_, request_id); 446 } 447 448 void PrintPreviewUI::OnShowSystemDialog() { 449 web_ui()->CallJavascriptFunction("onSystemDialogLinkClicked"); 450 } 451 452 void PrintPreviewUI::OnDidGetPreviewPageCount( 453 const PrintHostMsg_DidGetPreviewPageCount_Params& params) { 454 DCHECK_GT(params.page_count, 0); 455 base::FundamentalValue count(params.page_count); 456 base::FundamentalValue request_id(params.preview_request_id); 457 web_ui()->CallJavascriptFunction("onDidGetPreviewPageCount", 458 count, 459 request_id); 460 } 461 462 void PrintPreviewUI::OnDidGetDefaultPageLayout( 463 const PageSizeMargins& page_layout, const gfx::Rect& printable_area, 464 bool has_custom_page_size_style) { 465 if (page_layout.margin_top < 0 || page_layout.margin_left < 0 || 466 page_layout.margin_bottom < 0 || page_layout.margin_right < 0 || 467 page_layout.content_width < 0 || page_layout.content_height < 0 || 468 printable_area.width() <= 0 || printable_area.height() <= 0) { 469 NOTREACHED(); 470 return; 471 } 472 473 base::DictionaryValue layout; 474 layout.SetDouble(printing::kSettingMarginTop, page_layout.margin_top); 475 layout.SetDouble(printing::kSettingMarginLeft, page_layout.margin_left); 476 layout.SetDouble(printing::kSettingMarginBottom, page_layout.margin_bottom); 477 layout.SetDouble(printing::kSettingMarginRight, page_layout.margin_right); 478 layout.SetDouble(printing::kSettingContentWidth, page_layout.content_width); 479 layout.SetDouble(printing::kSettingContentHeight, page_layout.content_height); 480 layout.SetInteger(printing::kSettingPrintableAreaX, printable_area.x()); 481 layout.SetInteger(printing::kSettingPrintableAreaY, printable_area.y()); 482 layout.SetInteger(printing::kSettingPrintableAreaWidth, 483 printable_area.width()); 484 layout.SetInteger(printing::kSettingPrintableAreaHeight, 485 printable_area.height()); 486 487 base::FundamentalValue has_page_size_style(has_custom_page_size_style); 488 web_ui()->CallJavascriptFunction("onDidGetDefaultPageLayout", layout, 489 has_page_size_style); 490 } 491 492 void PrintPreviewUI::OnDidPreviewPage(int page_number, 493 int preview_request_id) { 494 DCHECK_GE(page_number, 0); 495 base::FundamentalValue number(page_number); 496 base::FundamentalValue ui_identifier(id_); 497 base::FundamentalValue request_id(preview_request_id); 498 web_ui()->CallJavascriptFunction( 499 "onDidPreviewPage", number, ui_identifier, request_id); 500 } 501 502 void PrintPreviewUI::OnReusePreviewData(int preview_request_id) { 503 base::FundamentalValue ui_identifier(id_); 504 base::FundamentalValue ui_preview_request_id(preview_request_id); 505 web_ui()->CallJavascriptFunction("reloadPreviewPages", ui_identifier, 506 ui_preview_request_id); 507 } 508 509 void PrintPreviewUI::OnPreviewDataIsAvailable(int expected_pages_count, 510 int preview_request_id) { 511 VLOG(1) << "Print preview request finished with " 512 << expected_pages_count << " pages"; 513 514 if (!initial_preview_start_time_.is_null()) { 515 UMA_HISTOGRAM_TIMES("PrintPreview.InitialDisplayTime", 516 base::TimeTicks::Now() - initial_preview_start_time_); 517 UMA_HISTOGRAM_COUNTS("PrintPreview.PageCount.Initial", 518 expected_pages_count); 519 initial_preview_start_time_ = base::TimeTicks(); 520 } 521 base::FundamentalValue ui_identifier(id_); 522 base::FundamentalValue ui_preview_request_id(preview_request_id); 523 web_ui()->CallJavascriptFunction("updatePrintPreview", ui_identifier, 524 ui_preview_request_id); 525 } 526 527 void PrintPreviewUI::OnPrintPreviewDialogDestroyed() { 528 handler_->OnPrintPreviewDialogDestroyed(); 529 } 530 531 void PrintPreviewUI::OnFileSelectionCancelled() { 532 web_ui()->CallJavascriptFunction("fileSelectionCancelled"); 533 } 534 535 void PrintPreviewUI::OnCancelPendingPreviewRequest() { 536 g_print_preview_request_id_map.Get().Set(id_, -1); 537 } 538 539 void PrintPreviewUI::OnPrintPreviewFailed() { 540 handler_->OnPrintPreviewFailed(); 541 web_ui()->CallJavascriptFunction("printPreviewFailed"); 542 } 543 544 void PrintPreviewUI::OnInvalidPrinterSettings() { 545 web_ui()->CallJavascriptFunction("invalidPrinterSettings"); 546 } 547 548 PrintPreviewDataService* PrintPreviewUI::print_preview_data_service() { 549 return PrintPreviewDataService::GetInstance(); 550 } 551 552 void PrintPreviewUI::OnHidePreviewDialog() { 553 WebContents* preview_dialog = web_ui()->GetWebContents(); 554 printing::BackgroundPrintingManager* background_printing_manager = 555 g_browser_process->background_printing_manager(); 556 if (background_printing_manager->HasPrintPreviewDialog(preview_dialog)) 557 return; 558 559 ConstrainedWebDialogDelegate* delegate = GetConstrainedDelegate(); 560 if (!delegate) 561 return; 562 delegate->ReleaseWebContentsOnDialogClose(); 563 background_printing_manager->OwnPrintPreviewDialog(preview_dialog); 564 OnClosePrintPreviewDialog(); 565 } 566 567 void PrintPreviewUI::OnClosePrintPreviewDialog() { 568 if (dialog_closed_) 569 return; 570 dialog_closed_ = true; 571 ConstrainedWebDialogDelegate* delegate = GetConstrainedDelegate(); 572 if (!delegate) 573 return; 574 delegate->GetWebDialogDelegate()->OnDialogClosed(std::string()); 575 delegate->OnDialogCloseFromWebUI(); 576 } 577 578 void PrintPreviewUI::OnReloadPrintersList() { 579 web_ui()->CallJavascriptFunction("reloadPrintersList"); 580 } 581 582 void PrintPreviewUI::OnPrintPreviewScalingDisabled() { 583 web_ui()->CallJavascriptFunction("printScalingDisabledForSourcePDF"); 584 } 585