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 #ifndef CHROME_BROWSER_PRINTING_PRINT_PREVIEW_DIALOG_CONTROLLER_H_ 6 #define CHROME_BROWSER_PRINTING_PRINT_PREVIEW_DIALOG_CONTROLLER_H_ 7 8 #include <map> 9 10 #include "base/basictypes.h" 11 #include "base/callback.h" 12 #include "base/memory/ref_counted.h" 13 #include "components/sessions/session_id.h" 14 #include "content/public/browser/notification_observer.h" 15 #include "content/public/browser/notification_registrar.h" 16 17 class GURL; 18 19 namespace content { 20 struct LoadCommittedDetails; 21 class RenderProcessHost; 22 class WebContents; 23 } 24 25 namespace printing { 26 27 // For print preview, the WebContents that initiates the printing operation is 28 // the initiator, and the constrained dialog that shows the print preview is the 29 // print preview dialog. 30 // This class manages print preview dialog creation and destruction, and keeps 31 // track of the 1:1 relationship between initiator tabs and print preview 32 // dialogs. 33 class PrintPreviewDialogController 34 : public base::RefCounted<PrintPreviewDialogController>, 35 public content::NotificationObserver { 36 public: 37 PrintPreviewDialogController(); 38 39 static PrintPreviewDialogController* GetInstance(); 40 41 // Initiate print preview for |initiator|. 42 // Call this instead of GetOrCreatePreviewDialog(). 43 static void PrintPreview(content::WebContents* initiator); 44 45 // Get/Create the print preview dialog for |initiator|. 46 // Exposed for unit tests. 47 content::WebContents* GetOrCreatePreviewDialog( 48 content::WebContents* initiator); 49 50 // Returns the preview dialog for |contents|. 51 // Returns |contents| if |contents| is a preview dialog. 52 // Returns NULL if no preview dialog exists for |contents|. 53 content::WebContents* GetPrintPreviewForContents( 54 content::WebContents* contents) const; 55 56 // Returns the initiator for |preview_dialog|. 57 // Returns NULL if no initiator exists for |preview_dialog|. 58 content::WebContents* GetInitiator(content::WebContents* preview_dialog); 59 60 // Run |callback| on the dialog of each active print preview operation. 61 void ForEachPreviewDialog( 62 base::Callback<void(content::WebContents*)> callback); 63 64 // content::NotificationObserver implementation. 65 virtual void Observe(int type, 66 const content::NotificationSource& source, 67 const content::NotificationDetails& details) OVERRIDE; 68 69 // Returns true if |contents| is a print preview dialog. 70 static bool IsPrintPreviewDialog(content::WebContents* contents); 71 72 // Returns true if |url| is a print preview url. 73 static bool IsPrintPreviewURL(const GURL& url); 74 75 // Erase the initiator info associated with |preview_dialog|. 76 void EraseInitiatorInfo(content::WebContents* preview_dialog); 77 is_creating_print_preview_dialog()78 bool is_creating_print_preview_dialog() const { 79 return is_creating_print_preview_dialog_; 80 } 81 82 private: 83 friend class base::RefCounted<PrintPreviewDialogController>; 84 85 // 1:1 relationship between a print preview dialog and its initiator tab. 86 // Key: Print preview dialog. 87 // Value: Initiator. 88 typedef std::map<content::WebContents*, content::WebContents*> 89 PrintPreviewDialogMap; 90 91 virtual ~PrintPreviewDialogController(); 92 93 // Handler for the RENDERER_PROCESS_CLOSED notification. This is observed when 94 // the initiator renderer crashed. 95 void OnRendererProcessClosed(content::RenderProcessHost* rph); 96 97 // Handler for the WEB_CONTENTS_DESTROYED notification. This is observed when 98 // either WebContents is closed. 99 void OnWebContentsDestroyed(content::WebContents* contents); 100 101 // Handler for the NAV_ENTRY_COMMITTED notification. This is observed when the 102 // renderer is navigated to a different page. 103 void OnNavEntryCommitted(content::WebContents* contents, 104 content::LoadCommittedDetails* details); 105 106 // Creates a new print preview dialog. 107 content::WebContents* CreatePrintPreviewDialog( 108 content::WebContents* initiator); 109 110 // Helper function to store the title of the initiator associated with 111 // |preview_dialog| in |preview_dialog|'s PrintPreviewUI. 112 void SaveInitiatorTitle(content::WebContents* preview_dialog); 113 114 // Adds/Removes observers for notifications from |contents|. 115 void AddObservers(content::WebContents* contents); 116 void RemoveObservers(content::WebContents* contents); 117 118 // Removes WebContents when they close/crash/navigate. 119 void RemoveInitiator(content::WebContents* initiator); 120 void RemovePreviewDialog(content::WebContents* preview_dialog); 121 122 // Mapping between print preview dialog and the corresponding initiator. 123 PrintPreviewDialogMap preview_dialog_map_; 124 125 // A registrar for listening to notifications. 126 content::NotificationRegistrar registrar_; 127 128 // True if the controller is waiting for a new preview dialog via 129 // content::NAVIGATION_TYPE_NEW_PAGE. 130 bool waiting_for_new_preview_page_; 131 132 // Whether the PrintPreviewDialogController is in the middle of creating a 133 // print preview dialog. 134 bool is_creating_print_preview_dialog_; 135 136 DISALLOW_COPY_AND_ASSIGN(PrintPreviewDialogController); 137 }; 138 139 } // namespace printing 140 141 #endif // CHROME_BROWSER_PRINTING_PRINT_PREVIEW_DIALOG_CONTROLLER_H_ 142