Chromium Code Reviews| 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 |