Index: chrome/browser/printing/print_preview_tab_controller.cc |
=================================================================== |
--- chrome/browser/printing/print_preview_tab_controller.cc (revision 105275) |
+++ chrome/browser/printing/print_preview_tab_controller.cc (working copy) |
@@ -4,6 +4,9 @@ |
#include "chrome/browser/printing/print_preview_tab_controller.h" |
+#include <algorithm> |
+#include <memory> |
+#include <string> |
#include <vector> |
#include "base/command_line.h" |
@@ -18,6 +21,8 @@ |
#include "chrome/browser/ui/browser_list.h" |
#include "chrome/browser/ui/browser_navigator.h" |
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
+#include "chrome/browser/ui/webui/constrained_html_ui.h" |
+#include "chrome/browser/ui/webui/html_dialog_ui.h" |
#include "chrome/browser/ui/webui/print_preview_ui.h" |
#include "chrome/common/chrome_content_client.h" |
#include "chrome/common/chrome_switches.h" |
@@ -41,10 +46,87 @@ |
ASCIIToUTF16(chrome::ChromeContentClient::kPDFPluginName)); |
} |
-void ResetPreviewTabOverrideTitle(TabContentsWrapper* preview_tab) { |
- preview_tab->print_view_manager()->ResetTitleOverride(); |
+class PrintPreviewTabDelegate : public HtmlDialogUIDelegate { |
kmadhusu
2011/10/13 18:52:18
Maybe this class should get moved out of pptc?
Lei Zhang
2011/10/13 21:12:12
No, I don't think this delegate makes sense for an
|
+ public: |
+ explicit PrintPreviewTabDelegate(TabContentsWrapper* initiator_tab); |
+ virtual ~PrintPreviewTabDelegate(); |
+ |
+ virtual bool IsDialogModal() const OVERRIDE; |
+ virtual string16 GetDialogTitle() const OVERRIDE; |
+ virtual GURL GetDialogContentURL() const OVERRIDE; |
+ virtual void GetWebUIMessageHandlers( |
+ std::vector<WebUIMessageHandler*, |
+ std::allocator<WebUIMessageHandler*> >*) const OVERRIDE; |
+ virtual void GetDialogSize(gfx::Size*) const OVERRIDE; |
+ virtual std::string GetDialogArgs() const OVERRIDE; |
+ virtual void OnDialogClosed(const std::string&) OVERRIDE; |
+ virtual void OnCloseContents(TabContents*, bool*) OVERRIDE; |
+ virtual bool ShouldShowDialogTitle() const OVERRIDE; |
+ |
+ private: |
+ gfx::Size size_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(PrintPreviewTabDelegate); |
+}; |
+ |
+PrintPreviewTabDelegate::PrintPreviewTabDelegate( |
+ TabContentsWrapper* initiator_tab) { |
+ const gfx::Size min_size(800, 480); |
+ const int kBorder = 50; |
+ gfx::Rect rect; |
+ initiator_tab->tab_contents()->GetContainerBounds(&rect); |
+ size_.set_width(std::max(rect.width(), min_size.width()) - kBorder); |
+ size_.set_height(std::max(rect.height(), min_size.height()) - kBorder); |
} |
+PrintPreviewTabDelegate::~PrintPreviewTabDelegate() { |
+} |
+ |
+bool PrintPreviewTabDelegate::IsDialogModal() const { |
+ // Not used, returning dummy value. |
+ NOTREACHED(); |
+ return true; |
+} |
+ |
+string16 PrintPreviewTabDelegate::GetDialogTitle() const { |
+ // Only used on Windows? UI folks prefer no title. |
+ return string16(); |
+} |
+ |
+GURL PrintPreviewTabDelegate::GetDialogContentURL() const { |
+ return GURL(chrome::kChromeUIPrintURL); |
+} |
+ |
+void PrintPreviewTabDelegate::GetWebUIMessageHandlers( |
+ std::vector<WebUIMessageHandler*, |
+ std::allocator<WebUIMessageHandler*> >* handlers) const { |
+ // PrintPreviewUI adds its own message handlers. |
+} |
+ |
+void PrintPreviewTabDelegate::GetDialogSize(gfx::Size* size) const { |
+ *size = size_; |
+} |
+ |
+std::string PrintPreviewTabDelegate::GetDialogArgs() const { |
+ return std::string(); |
+} |
+ |
+void PrintPreviewTabDelegate::OnDialogClosed(const std::string& /* unused */) { |
+ delete this; |
+} |
+ |
+void PrintPreviewTabDelegate::OnCloseContents(TabContents* /* unused */, |
+ bool* /* unused */) { |
+ // Not used, returning dummy value. |
+ NOTREACHED(); |
+} |
+ |
+bool PrintPreviewTabDelegate::ShouldShowDialogTitle() const { |
+ // Not used, returning dummy value. |
+ NOTREACHED(); |
+ return false; |
+} |
+ |
} // namespace |
namespace printing { |
@@ -82,8 +164,9 @@ |
if (!preview_tab) |
return CreatePrintPreviewTab(initiator_tab); |
- // Show current preview tab. |
- static_cast<RenderViewHostDelegate*>(preview_tab->tab_contents())->Activate(); |
+ // Show the initiator tab holding the existing preview tab. |
+ static_cast<RenderViewHostDelegate*>( |
+ initiator_tab->tab_contents())->Activate(); |
kmadhusu
2011/10/13 18:52:18
Is this required? We are already in initiator tab.
Lei Zhang
2011/10/13 21:12:12
One possible reason is tab A is loading, and the u
|
return preview_tab; |
} |
@@ -140,109 +223,82 @@ |
void PrintPreviewTabController::OnRendererProcessClosed( |
RenderProcessHost* rph) { |
+ // Store tabs in a vector and deal with them after iterating through |
+ // |preview_tab_map_| becase RemoveFooTab() can change |preview_tab_map_|. |
kmadhusu
2011/10/13 18:52:18
typo "because"
Lei Zhang
2011/10/13 21:12:12
Done.
|
+ std::vector<TabContentsWrapper*> vec; |
for (PrintPreviewTabMap::iterator iter = preview_tab_map_.begin(); |
kmadhusu
2011/10/13 18:52:18
Rather than reusing the "vec" I would like to use
Lei Zhang
2011/10/13 21:12:12
Done.
|
iter != preview_tab_map_.end(); ++iter) { |
+ TabContentsWrapper* preview_tab = iter->first; |
+ if (preview_tab->render_view_host()->process() == rph) { |
+ vec.push_back(preview_tab); |
+ } |
+ } |
+ for (size_t i = 0; i < vec.size(); ++i) { |
kmadhusu
2011/10/13 18:52:18
size_t vector_len = vec.size();
for (size_t i = 0;
Lei Zhang
2011/10/13 21:12:12
I'll leave the optimization up to the compiler. We
|
+ RemovePreviewTab(vec[i]); |
+ PrintPreviewUI* print_preview_ui = |
+ static_cast<PrintPreviewUI*>(vec[i]->web_ui()); |
+ if (print_preview_ui) |
+ print_preview_ui->OnPrintPreviewTabCrashed(); |
+ } |
+ |
+ vec.clear(); |
+ for (PrintPreviewTabMap::iterator iter = preview_tab_map_.begin(); |
+ iter != preview_tab_map_.end(); ++iter) { |
TabContentsWrapper* initiator_tab = iter->second; |
- if (initiator_tab && |
- initiator_tab->render_view_host()->process() == rph) { |
- TabContentsWrapper* preview_tab = iter->first; |
- PrintPreviewUI* print_preview_ui = |
- static_cast<PrintPreviewUI*>(preview_tab->web_ui()); |
- print_preview_ui->OnInitiatorTabCrashed(); |
+ if (initiator_tab && initiator_tab->render_view_host()->process() == rph) { |
+ vec.push_back(initiator_tab); |
} |
} |
+ for (size_t i = 0; i < vec.size(); ++i) |
+ RemoveInitiatorTab(vec[i]); |
} |
void PrintPreviewTabController::OnTabContentsDestroyed( |
TabContentsWrapper* tab) { |
TabContentsWrapper* preview_tab = GetPrintPreviewForTab(tab); |
- if (!preview_tab) |
+ if (!preview_tab) { |
+ NOTREACHED(); |
return; |
- |
- if (tab == preview_tab) { |
- // Remove the initiator tab's observers before erasing the mapping. |
- TabContentsWrapper* initiator_tab = GetInitiatorTab(tab); |
- if (initiator_tab) |
- RemoveObservers(initiator_tab); |
- |
- // Print preview tab contents are destroyed. Notify |PrintPreviewUI| to |
- // abort the initiator tab preview request. |
- if (IsPrintPreviewTab(tab) && tab->web_ui()) { |
- PrintPreviewUI* print_preview_ui = |
- static_cast<PrintPreviewUI*>(tab->web_ui()); |
- print_preview_ui->OnTabDestroyed(); |
- } |
- |
- // Erase the map entry. |
- preview_tab_map_.erase(tab); |
- } else { |
- // Initiator tab is closed. Disable the controls in preview tab. |
- if (preview_tab->web_ui()) { |
- PrintPreviewUI* print_preview_ui = |
- static_cast<PrintPreviewUI*>(preview_tab->web_ui()); |
- print_preview_ui->OnInitiatorTabClosed(); |
- } |
- |
- // |tab| is an initiator tab, update the map entry and remove observers. |
- preview_tab_map_[preview_tab] = NULL; |
} |
- ResetPreviewTabOverrideTitle(preview_tab); |
- RemoveObservers(tab); |
+ if (tab == preview_tab) |
+ RemovePreviewTab(tab); |
+ else |
+ RemoveInitiatorTab(tab); |
} |
void PrintPreviewTabController::OnNavEntryCommitted( |
TabContentsWrapper* tab, content::LoadCommittedDetails* details) { |
TabContentsWrapper* preview_tab = GetPrintPreviewForTab(tab); |
+ if (!preview_tab) { |
+ NOTREACHED(); |
+ return; |
+ } |
bool source_tab_is_preview_tab = (tab == preview_tab); |
- if (details) { |
- content::PageTransition transition_type = details->entry->transition_type(); |
- NavigationType::Type nav_type = details->type; |
- // Don't update/erase the map entry if the page has not changed. |
- if (transition_type == content::PAGE_TRANSITION_RELOAD || |
- nav_type == NavigationType::SAME_PAGE) { |
- if (source_tab_is_preview_tab) |
+ if (source_tab_is_preview_tab) { |
+ // Preview tab navigated. |
+ if (details) { |
+ content::PageTransition transition_type = |
+ details->entry->transition_type(); |
+ NavigationType::Type nav_type = details->type; |
+ |
+ // New |preview_tab| is created. Don't update/erase map entry. |
+ if (waiting_for_new_preview_page_ && |
+ transition_type == content::PAGE_TRANSITION_START_PAGE && |
+ nav_type == NavigationType::NEW_PAGE && |
+ source_tab_is_preview_tab) { |
kmadhusu
2011/10/13 18:52:18
"source_tab_is_preview_tab" check is not required
Lei Zhang
2011/10/13 21:12:12
Done.
|
+ waiting_for_new_preview_page_ = false; |
SetInitiatorTabURLAndTitle(preview_tab); |
- return; |
+ return; |
+ } |
} |
- |
- // New |preview_tab| is created. Don't update/erase map entry. |
- if (waiting_for_new_preview_page_ && |
- transition_type == content::PAGE_TRANSITION_LINK && |
- nav_type == NavigationType::NEW_PAGE && |
- source_tab_is_preview_tab) { |
- waiting_for_new_preview_page_ = false; |
- SetInitiatorTabURLAndTitle(preview_tab); |
- return; |
- } |
- |
- // User navigated to a preview tab using forward/back button. |
- if (source_tab_is_preview_tab && |
- transition_type == content::PAGE_TRANSITION_FORWARD_BACK && |
- nav_type == NavigationType::EXISTING_PAGE) { |
- return; |
- } |
+ NOTREACHED(); |
+ return; |
} |
- RemoveObservers(tab); |
- ResetPreviewTabOverrideTitle(preview_tab); |
- if (source_tab_is_preview_tab) { |
- // Remove the initiator tab's observers before erasing the mapping. |
- TabContentsWrapper* initiator_tab = GetInitiatorTab(tab); |
- if (initiator_tab) |
- RemoveObservers(initiator_tab); |
- preview_tab_map_.erase(tab); |
- } else { |
- preview_tab_map_[preview_tab] = NULL; |
- |
- // Initiator tab is closed. Disable the controls in preview tab. |
- if (preview_tab->web_ui()) { |
- PrintPreviewUI* print_preview_ui = |
- static_cast<PrintPreviewUI*>(preview_tab->web_ui()); |
- print_preview_ui->OnInitiatorTabClosed(); |
- } |
- } |
+ // Initiator tab navigated. |
+ RemoveInitiatorTab(tab); |
} |
// static |
@@ -264,7 +320,6 @@ |
RemoveObservers(it->second); |
preview_tab_map_[preview_tab] = NULL; |
- ResetPreviewTabOverrideTitle(preview_tab); |
} |
TabContentsWrapper* PrintPreviewTabController::GetInitiatorTab( |
@@ -293,25 +348,13 @@ |
} |
} |
- // Add a new tab next to initiator tab. |
- browser::NavigateParams params(current_browser, |
- GURL(chrome::kChromeUIPrintURL), |
- content::PAGE_TRANSITION_LINK); |
- params.disposition = NEW_FOREGROUND_TAB; |
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kChromeFrame)) |
- params.disposition = NEW_POPUP; |
- |
- // For normal tabs, set the position as immediately to the right, |
- // otherwise let the tab strip decide. |
- if (current_browser->is_type_tabbed()) { |
- params.tabstrip_index = current_browser->tabstrip_model()-> |
- GetIndexOfTabContents(initiator_tab) + 1; |
- } |
- |
- browser::Navigate(¶ms); |
- TabContentsWrapper* preview_tab = params.target_contents; |
+ HtmlDialogUIDelegate* delegate = new PrintPreviewTabDelegate(initiator_tab); |
+ ConstrainedHtmlUIDelegate* html_delegate = |
+ ConstrainedHtmlUI::CreateConstrainedHtmlDialog(current_browser->profile(), |
+ delegate, |
+ initiator_tab); |
+ TabContentsWrapper* preview_tab = html_delegate->tab(); |
EnableInternalPDFPluginForTab(preview_tab); |
- static_cast<RenderViewHostDelegate*>(preview_tab->tab_contents())->Activate(); |
// Add an entry to the map. |
preview_tab_map_[preview_tab] = initiator_tab; |
@@ -371,4 +414,43 @@ |
} |
} |
+void PrintPreviewTabController::RemoveInitiatorTab( |
+ TabContentsWrapper* initiator_tab) { |
+ TabContentsWrapper* preview_tab = GetPrintPreviewForTab(initiator_tab); |
+ // Update the map entry first, so when the print preview tab gets destroyed |
+ // and reaches RemovePreviewTab(), it does not attempt to also remove the |
+ // initiator tab's observers. |
+ preview_tab_map_[preview_tab] = NULL; |
+ RemoveObservers(initiator_tab); |
+ |
+ initiator_tab->print_view_manager()->PrintPreviewDone(); |
+ |
+ // Initiator tab is closed. Close the print preview tab too. |
+ PrintPreviewUI* print_preview_ui = |
+ static_cast<PrintPreviewUI*>(preview_tab->web_ui()); |
+ if (print_preview_ui) |
+ print_preview_ui->OnInitiatorTabClosed(); |
+} |
+ |
+void PrintPreviewTabController::RemovePreviewTab( |
+ TabContentsWrapper* preview_tab) { |
+ // Remove the initiator tab's observers before erasing the mapping. |
+ TabContentsWrapper* initiator_tab = GetInitiatorTab(preview_tab); |
+ if (initiator_tab) { |
+ initiator_tab->print_view_manager()->PrintPreviewDone(); |
+ RemoveObservers(initiator_tab); |
+ } |
+ |
+ // Print preview TabContents is destroyed. Notify |PrintPreviewUI| to abort |
+ // the initiator tab preview request. |
+ if (IsPrintPreviewTab(preview_tab) && preview_tab->web_ui()) { |
kmadhusu
2011/10/13 18:52:18
We already know that this is a print preview tab.
Lei Zhang
2011/10/13 21:12:12
This was originally added for the case where the p
|
+ PrintPreviewUI* print_preview_ui = |
+ static_cast<PrintPreviewUI*>(preview_tab->web_ui()); |
+ print_preview_ui->OnTabDestroyed(); |
+ } |
+ |
+ preview_tab_map_.erase(preview_tab); |
+ RemoveObservers(preview_tab); |
+} |
+ |
} // namespace printing |