| Index: chrome/browser/printing/print_preview_tab_controller.cc
|
| ===================================================================
|
| --- chrome/browser/printing/print_preview_tab_controller.cc (revision 110066)
|
| +++ chrome/browser/printing/print_preview_tab_controller.cc (working copy)
|
| @@ -4,8 +4,12 @@
|
|
|
| #include "chrome/browser/printing/print_preview_tab_controller.h"
|
|
|
| +#include <algorithm>
|
| +#include <memory>
|
| +#include <string>
|
| #include <vector>
|
|
|
| +#include "base/auto_reset.h"
|
| #include "base/command_line.h"
|
| #include "base/utf_string_conversions.h"
|
| #include "chrome/browser/browser_process.h"
|
| @@ -18,6 +22,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,16 +47,94 @@
|
| ASCIIToUTF16(chrome::ChromeContentClient::kPDFPluginName));
|
| }
|
|
|
| -void ResetPreviewTabOverrideTitle(TabContentsWrapper* preview_tab) {
|
| - preview_tab->print_view_manager()->ResetTitleOverride();
|
| +class PrintPreviewTabDelegate : public HtmlDialogUIDelegate {
|
| + 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*>* handlers) const OVERRIDE;
|
| + virtual void GetDialogSize(gfx::Size* size) const OVERRIDE;
|
| + virtual std::string GetDialogArgs() const OVERRIDE;
|
| + virtual void OnDialogClosed(const std::string& json_retval) OVERRIDE;
|
| + virtual void OnCloseContents(TabContents* source,
|
| + bool* out_close_dialog) OVERRIDE;
|
| + virtual bool ShouldShowDialogTitle() const OVERRIDE;
|
| +
|
| + private:
|
| + gfx::Size size_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(PrintPreviewTabDelegate);
|
| +};
|
| +
|
| +PrintPreviewTabDelegate::PrintPreviewTabDelegate(
|
| + TabContentsWrapper* initiator_tab) {
|
| + const gfx::Size kMinDialogSize(800, 480);
|
| + const int kBorder = 50;
|
| + gfx::Rect rect;
|
| + initiator_tab->tab_contents()->GetContainerBounds(&rect);
|
| + size_.set_width(std::max(rect.width(), kMinDialogSize.width()) - kBorder);
|
| + size_.set_height(std::max(rect.height(), kMinDialogSize.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*>* /* 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& /* json_retval */) {
|
| + delete this;
|
| +}
|
| +
|
| +void PrintPreviewTabDelegate::OnCloseContents(TabContents* /* source */,
|
| + bool* /* out_close_dialog */) {
|
| + // Not used, returning dummy value.
|
| + NOTREACHED();
|
| +}
|
| +
|
| +bool PrintPreviewTabDelegate::ShouldShowDialogTitle() const {
|
| + // Not used, returning dummy value.
|
| + NOTREACHED();
|
| + return false;
|
| +}
|
| +
|
| } // namespace
|
|
|
| namespace printing {
|
|
|
| PrintPreviewTabController::PrintPreviewTabController()
|
| - : waiting_for_new_preview_page_(false) {
|
| + : waiting_for_new_preview_page_(false),
|
| + is_creating_print_preview_tab_(false) {
|
| }
|
|
|
| PrintPreviewTabController::~PrintPreviewTabController() {}
|
| @@ -82,8 +166,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();
|
| return preview_tab;
|
| }
|
|
|
| @@ -141,109 +226,90 @@
|
|
|
| void PrintPreviewTabController::OnRendererProcessClosed(
|
| RenderProcessHost* rph) {
|
| + // Store tabs in a vector and deal with them after iterating through
|
| + // |preview_tab_map_| because RemoveFooTab() can change |preview_tab_map_|.
|
| + std::vector<TabContentsWrapper*> closed_initiator_tabs;
|
| + std::vector<TabContentsWrapper*> closed_preview_tabs;
|
| for (PrintPreviewTabMap::iterator iter = preview_tab_map_.begin();
|
| iter != preview_tab_map_.end(); ++iter) {
|
| + TabContentsWrapper* preview_tab = iter->first;
|
| 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 (preview_tab->render_view_host()->process() == rph) {
|
| + closed_preview_tabs.push_back(preview_tab);
|
| + } else if (initiator_tab &&
|
| + initiator_tab->render_view_host()->process() == rph) {
|
| + closed_initiator_tabs.push_back(initiator_tab);
|
| }
|
| }
|
| +
|
| + for (size_t i = 0; i < closed_preview_tabs.size(); ++i) {
|
| + RemovePreviewTab(closed_preview_tabs[i]);
|
| + PrintPreviewUI* print_preview_ui =
|
| + static_cast<PrintPreviewUI*>(closed_preview_tabs[i]->web_ui());
|
| + if (print_preview_ui)
|
| + print_preview_ui->OnPrintPreviewTabClosed();
|
| + }
|
| +
|
| + for (size_t i = 0; i < closed_initiator_tabs.size(); ++i)
|
| + RemoveInitiatorTab(closed_initiator_tabs[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();
|
| - content::NavigationType 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 == content::NAVIGATION_TYPE_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();
|
| + content::NavigationType 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 == content::NAVIGATION_TYPE_NEW_PAGE) {
|
| + waiting_for_new_preview_page_ = false;
|
| SetInitiatorTabURLAndTitle(preview_tab);
|
| - 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 == content::NAVIGATION_TYPE_NEW_PAGE &&
|
| - source_tab_is_preview_tab) {
|
| - waiting_for_new_preview_page_ = false;
|
| - SetInitiatorTabURLAndTitle(preview_tab);
|
| - return;
|
| - }
|
| + // Disabling the delegate will prevent all future navigation.
|
| + tab->tab_contents()->set_delegate(NULL);
|
| + 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 == content::NAVIGATION_TYPE_EXISTING_PAGE) {
|
| - return;
|
| + // Cloud print sign-in causes a reload.
|
| + if (!waiting_for_new_preview_page_ &&
|
| + transition_type == content::PAGE_TRANSITION_RELOAD &&
|
| + nav_type == content::NAVIGATION_TYPE_EXISTING_PAGE &&
|
| + IsPrintPreviewURL(details->previous_url)) {
|
| + 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
|
| @@ -265,9 +331,12 @@
|
|
|
| RemoveObservers(it->second);
|
| preview_tab_map_[preview_tab] = NULL;
|
| - ResetPreviewTabOverrideTitle(preview_tab);
|
| }
|
|
|
| +bool PrintPreviewTabController::is_creating_print_preview_tab() const {
|
| + return is_creating_print_preview_tab_;
|
| +}
|
| +
|
| TabContentsWrapper* PrintPreviewTabController::GetInitiatorTab(
|
| TabContentsWrapper* preview_tab) {
|
| PrintPreviewTabMap::iterator it = preview_tab_map_.find(preview_tab);
|
| @@ -278,6 +347,7 @@
|
|
|
| TabContentsWrapper* PrintPreviewTabController::CreatePrintPreviewTab(
|
| TabContentsWrapper* initiator_tab) {
|
| + AutoReset<bool> auto_reset(&is_creating_print_preview_tab_, true);
|
| Browser* current_browser = BrowserList::FindBrowserWithID(
|
| initiator_tab->restore_tab_helper()->window_id().id());
|
| if (!current_browser) {
|
| @@ -294,25 +364,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;
|
| @@ -374,4 +432,39 @@
|
| }
|
| }
|
|
|
| +void PrintPreviewTabController::RemoveInitiatorTab(
|
| + TabContentsWrapper* initiator_tab) {
|
| + TabContentsWrapper* preview_tab = GetPrintPreviewForTab(initiator_tab);
|
| + DCHECK(preview_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 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)
|
| + RemoveObservers(initiator_tab);
|
| +
|
| + // Print preview TabContents is destroyed. Notify |PrintPreviewUI| to abort
|
| + // the initiator tab preview request.
|
| + PrintPreviewUI* print_preview_ui =
|
| + static_cast<PrintPreviewUI*>(preview_tab->web_ui());
|
| + if (print_preview_ui)
|
| + print_preview_ui->OnTabDestroyed();
|
| +
|
| + preview_tab_map_.erase(preview_tab);
|
| + RemoveObservers(preview_tab);
|
| +}
|
| +
|
| } // namespace printing
|
|
|