| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import <Cocoa/Cocoa.h> | 5 #import <Cocoa/Cocoa.h> |
| 6 | 6 |
| 7 #include "app/l10n_util.h" | 7 #include "app/resource_bundle.h" |
| 8 #include "app/l10n_util_mac.h" |
| 8 #include "base/mac_util.h" | 9 #include "base/mac_util.h" |
| 9 #include "base/process_util.h" | 10 #include "base/process_util.h" |
| 10 #include "base/sys_string_conversions.h" | 11 #include "base/sys_string_conversions.h" |
| 11 #include "grit/generated_resources.h" | |
| 12 #include "chrome/browser/browser_list.h" | 12 #include "chrome/browser/browser_list.h" |
| 13 #include "chrome/browser/hung_renderer_dialog.h" | 13 #include "chrome/browser/hung_renderer_dialog.h" |
| 14 #import "chrome/browser/cocoa/hung_renderer_controller.h" | 14 #import "chrome/browser/cocoa/hung_renderer_controller.h" |
| 15 #include "chrome/browser/tab_contents/tab_contents.h" | 15 #include "chrome/browser/tab_contents/tab_contents.h" |
| 16 #include "chrome/common/logging_chrome.h" | 16 #include "chrome/common/logging_chrome.h" |
| 17 #include "chrome/common/result_codes.h" | 17 #include "chrome/common/result_codes.h" |
| 18 #include "grit/chromium_strings.h" | 18 #include "grit/chromium_strings.h" |
| 19 #include "grit/generated_resources.h" |
| 20 #include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" |
| 19 | 21 |
| 20 namespace { | 22 namespace { |
| 21 // We only support showing one of these at a time per app. The | 23 // We only support showing one of these at a time per app. The |
| 22 // controller owns itself and is released when its window is closed. | 24 // controller owns itself and is released when its window is closed. |
| 23 HungRendererController* g_instance = NULL; | 25 HungRendererController* g_instance = NULL; |
| 24 } // end namespace | 26 } // end namespace |
| 25 | 27 |
| 26 @implementation HungRendererController | 28 @implementation HungRendererController |
| 27 | 29 |
| 28 - (id)initWithWindowNibName:(NSString*)nibName { | 30 - (id)initWithWindowNibName:(NSString*)nibName { |
| 29 NSString* nibpath = [mac_util::MainAppBundle() pathForResource:nibName | 31 NSString* nibpath = [mac_util::MainAppBundle() pathForResource:nibName |
| 30 ofType:@"nib"]; | 32 ofType:@"nib"]; |
| 31 self = [super initWithWindowNibPath:nibpath owner:self]; | 33 self = [super initWithWindowNibPath:nibpath owner:self]; |
| 32 if (self) { | 34 if (self) { |
| 33 [tableView_ setDataSource:self]; | 35 [tableView_ setDataSource:self]; |
| 34 } | 36 } |
| 35 return self; | 37 return self; |
| 36 } | 38 } |
| 37 | 39 |
| 38 - (void)dealloc { | 40 - (void)dealloc { |
| 39 DCHECK(!g_instance); | 41 DCHECK(!g_instance); |
| 40 [super dealloc]; | 42 [super dealloc]; |
| 41 } | 43 } |
| 42 | 44 |
| 43 - (void)awakeFromNib { | 45 - (void)awakeFromNib { |
| 44 // This is easier than creating a localizer, since we only have one | 46 // Load in the image |
| 45 // string to modify. | 47 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 46 std::wstring productString = l10n_util::GetString(IDS_PRODUCT_NAME); | 48 NSImage* backgroundImage = rb.GetNSImageNamed(IDR_FROZEN_TAB_ICON); |
| 47 [[self window] setTitle:base::SysWideToNSString(productString)]; | 49 DCHECK(backgroundImage); |
| 50 [imageView_ setImage:backgroundImage]; |
| 51 |
| 52 // Make the message fit. |
| 53 CGFloat messageShift = |
| 54 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:messageView_]; |
| 55 |
| 56 // Move the graphic up to be top even with the message. |
| 57 NSRect graphicFrame = [imageView_ frame]; |
| 58 graphicFrame.origin.y += messageShift; |
| 59 [imageView_ setFrame:graphicFrame]; |
| 60 |
| 61 // Make the window taller to fit everything. |
| 62 NSWindow* window = [self window]; |
| 63 [[window contentView] setAutoresizesSubviews:NO]; |
| 64 NSRect windowFrame = [window frame]; |
| 65 windowFrame.size.height += messageShift; |
| 66 [window setFrame:windowFrame display:NO]; |
| 67 [[window contentView] setAutoresizesSubviews:YES]; |
| 48 } | 68 } |
| 49 | 69 |
| 50 - (IBAction)kill:(id)sender { | 70 - (IBAction)kill:(id)sender { |
| 51 if (hungContents_) | 71 if (hungContents_) |
| 52 base::KillProcess(hungContents_->process()->process().handle(), | 72 base::KillProcess(hungContents_->process()->process().handle(), |
| 53 ResultCodes::HUNG, false); | 73 ResultCodes::HUNG, false); |
| 54 // Cannot call performClose:, because the close button is disabled. | 74 // Cannot call performClose:, because the close button is disabled. |
| 55 [self close]; | 75 [self close]; |
| 56 } | 76 } |
| 57 | 77 |
| 58 - (IBAction)wait:(id)sender { | 78 - (IBAction)wait:(id)sender { |
| 59 if (hungContents_ && hungContents_->render_view_host()) | 79 if (hungContents_ && hungContents_->render_view_host()) |
| 60 hungContents_->render_view_host()->RestartHangMonitorTimeout(); | 80 hungContents_->render_view_host()->RestartHangMonitorTimeout(); |
| 61 // Cannot call performClose:, because the close button is disabled. | 81 // Cannot call performClose:, because the close button is disabled. |
| 62 [self close]; | 82 [self close]; |
| 63 } | 83 } |
| 64 | 84 |
| 65 - (int)numberOfRowsInTableView:(NSTableView *)aTableView { | 85 - (int)numberOfRowsInTableView:(NSTableView *)aTableView { |
| 66 return hungRenderers_.size(); | 86 return hungRenderers_.size(); |
| 67 } | 87 } |
| 68 | 88 |
| 69 - (id)tableView:(NSTableView*)aTableView | 89 - (id)tableView:(NSTableView*)aTableView |
| 70 objectValueForTableColumn:(NSTableColumn*)column | 90 objectValueForTableColumn:(NSTableColumn*)column |
| 71 row:(int)rowIndex { | 91 row:(int)rowIndex { |
| 72 // TODO(rohitrao): Add favicons. | 92 // TODO(rohitrao): Add favicons. |
| 73 TabContents* contents = hungRenderers_[rowIndex]; | 93 TabContents* contents = hungRenderers_[rowIndex]; |
| 74 string16 title = contents->GetTitle(); | 94 string16 title = contents->GetTitle(); |
| 75 if (title.empty()) | 95 if (!title.empty()) |
| 76 title = l10n_util::GetStringUTF16(IDS_TAB_UNTITLED_TITLE); | 96 return base::SysUTF16ToNSString(title); |
| 77 return base::SysUTF16ToNSString(title); | 97 return l10n_util::GetNSStringWithFixup(IDS_TAB_UNTITLED_TITLE); |
| 78 } | 98 } |
| 79 | 99 |
| 80 - (void)windowWillClose:(NSNotification*)notification { | 100 - (void)windowWillClose:(NSNotification*)notification { |
| 81 // We have to reset g_instance before autoreleasing the window, | 101 // We have to reset g_instance before autoreleasing the window, |
| 82 // because we want to avoid reusing the same dialog if someone calls | 102 // because we want to avoid reusing the same dialog if someone calls |
| 83 // HungRendererDialog::ShowForTabContents() between the autorelease | 103 // HungRendererDialog::ShowForTabContents() between the autorelease |
| 84 // call and the actual dealloc. | 104 // call and the actual dealloc. |
| 85 g_instance = nil; | 105 g_instance = nil; |
| 86 | 106 |
| 87 [self autorelease]; | 107 [self autorelease]; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 initWithWindowNibName:@"HungRendererDialog"]; | 150 initWithWindowNibName:@"HungRendererDialog"]; |
| 131 [g_instance showForTabContents:contents]; | 151 [g_instance showForTabContents:contents]; |
| 132 } | 152 } |
| 133 } | 153 } |
| 134 | 154 |
| 135 // static | 155 // static |
| 136 void HungRendererDialog::HideForTabContents(TabContents* contents) { | 156 void HungRendererDialog::HideForTabContents(TabContents* contents) { |
| 137 if (!logging::DialogsAreSuppressed() && g_instance) | 157 if (!logging::DialogsAreSuppressed() && g_instance) |
| 138 [g_instance endForTabContents:contents]; | 158 [g_instance endForTabContents:contents]; |
| 139 } | 159 } |
| OLD | NEW |