diff options
author | mirandac@chromium.org <mirandac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-03 16:15:32 +0000 |
---|---|---|
committer | mirandac@chromium.org <mirandac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-03 16:15:32 +0000 |
commit | 3896b185aa328b422ebfd002e382e0186ec3fbd7 (patch) | |
tree | d2a6db357bf72adeaff75b4953ad560e96215913 /chrome/browser/cocoa | |
parent | 71aa3446235a444e69185f972b5cec8216f64374 (diff) | |
download | chromium_src-3896b185aa328b422ebfd002e382e0186ec3fbd7.zip chromium_src-3896b185aa328b422ebfd002e382e0186ec3fbd7.tar.gz chromium_src-3896b185aa328b422ebfd002e382e0186ec3fbd7.tar.bz2 |
Add "Report Bug" dialog to Mac OSX.
BUG= http://crbug.com/19282
TEST= Use report bug dialog on Mac OSX.
Review URL: http://codereview.chromium.org/340039
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30815 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa')
-rw-r--r-- | chrome/browser/cocoa/browser_window_cocoa.mm | 10 | ||||
-rw-r--r-- | chrome/browser/cocoa/bug_report_window_controller.h | 88 | ||||
-rw-r--r-- | chrome/browser/cocoa/bug_report_window_controller.mm | 157 | ||||
-rw-r--r-- | chrome/browser/cocoa/bug_report_window_controller_unittest.mm | 71 |
4 files changed, 325 insertions, 1 deletions
diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm index 398948e..9eee4c7 100644 --- a/chrome/browser/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/cocoa/browser_window_cocoa.mm @@ -9,6 +9,7 @@ #include "chrome/browser/bookmarks/bookmark_utils.h" #include "chrome/browser/cocoa/browser_window_cocoa.h" #import "chrome/browser/cocoa/browser_window_controller.h" +#import "chrome/browser/cocoa/bug_report_window_controller.h" #import "chrome/browser/cocoa/clear_browsing_data_controller.h" #import "chrome/browser/cocoa/download_shelf_controller.h" #import "chrome/browser/cocoa/html_dialog_window_controller.h" @@ -246,7 +247,14 @@ DownloadShelf* BrowserWindowCocoa::GetDownloadShelf() { } void BrowserWindowCocoa::ShowReportBugDialog() { - NOTIMPLEMENTED(); + TabContents* current_tab = browser_->GetSelectedTabContents(); + if (current_tab && current_tab->controller().GetActiveEntry()) { + BugReportWindowController* controller = + [[BugReportWindowController alloc] + initWithTabContents:current_tab + profile:browser_->profile()]; + [controller runModalDialog]; + } } void BrowserWindowCocoa::ShowClearBrowsingDataDialog() { diff --git a/chrome/browser/cocoa/bug_report_window_controller.h b/chrome/browser/cocoa/bug_report_window_controller.h new file mode 100644 index 0000000..93eea0a --- /dev/null +++ b/chrome/browser/cocoa/bug_report_window_controller.h @@ -0,0 +1,88 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_COCOA_BUG_REPORT_WINDOW_CONTROLLER_H_ +#define CHROME_BROWSER_COCOA_BUG_REPORT_WINDOW_CONTROLLER_H_ + +#import <Cocoa/Cocoa.h> + +#include <vector> + +#include "base/scoped_ptr.h" + +class Profile; +class TabContents; + +// A window controller for managing the "Report Bug" feature. Modally +// presents a dialog that allows the user to either file a bug report on +// a broken page, or go directly to Google's "Report Phishing" page and +// file a report there. +@interface BugReportWindowController : NSWindowController { + @private + TabContents* currentTab_; // Weak, owned by browser. + Profile* profile_; // Weak, owned by browser. + + // Holds screenshot of current tab. + std::vector<unsigned char> pngData_; + + // Values bound to data in the dialog box. These values cannot be boxed in + // scoped_nsobjects because we use them for bindings. + NSString* bugDescription_; // Strong. + NSUInteger bugType_; + NSString* pageTitle_; // Strong. + NSString* pageURL_; // Strong. + + // We keep a pointer to this button so we can change its title. + NSButton* sendReportButton_; // Weak. + + BOOL sendScreenshot_; + + // Disable screenshot if no browser window is open. + BOOL disableScreenshot_; + + // Menu for the bug type popup button. We create it here instead of in + // IB so that we can nicely check whether the phishing page is selected, + // and so that we can create a menu without "page" options when no browser + // window is open. + NSArray* bugTypeList_; // Strong. +} + +// Initialize with the contents of the tab to be reported as buggy / wrong. +// If dialog is called without an open window, currentTab may be null; in +// that case, a dialog is opened with options for reporting a bugs not +// related to a specific page. Profile is passed to BugReportUtil, who +// will not send a report if the value is null. +- (id)initWithTabContents:(TabContents*)currentTab profile:(Profile*)profile; + +// Run the dialog with an application-modal event loop. If the user accepts, +// send the report of the bug or broken web site. +- (void)runModalDialog; + +// IBActions for the dialog buttons. +- (IBAction)sendReport:(id)sender; +- (IBAction)cancel:(id)sender; + +// YES if the user has selected the phishing report option. +- (BOOL)isPhishingReport; + +// The "send report" button may need to change its title to reflect that it's +// bouncing to the phish report page instead of sending a report directly +// from the dialog box (or vice versa). Observe the menu of bug types +// and change the button title along with the selected bug. +- (void)menu:(NSMenu *)menu willHighlightItem:(NSMenuItem *)item; + +// Properties for bindings. +@property (copy, nonatomic) NSString* bugDescription; +@property NSUInteger bugType; +@property (copy, nonatomic) NSString* pageTitle; +@property (copy, nonatomic) NSString* pageURL; +@property (assign, nonatomic) IBOutlet NSButton* sendReportButton; +@property BOOL sendScreenshot; +@property BOOL disableScreenshot; +@property (readonly, nonatomic) NSArray* bugTypeList; + +@end + +#endif // CHROME_BROWSER_COCOA_BUG_REPORT_WINDOW_CONTROLLER_H_ + diff --git a/chrome/browser/cocoa/bug_report_window_controller.mm b/chrome/browser/cocoa/bug_report_window_controller.mm new file mode 100644 index 0000000..6fd7e5d --- /dev/null +++ b/chrome/browser/cocoa/bug_report_window_controller.mm @@ -0,0 +1,157 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "chrome/browser/cocoa/bug_report_window_controller.h" + +#include "app/l10n_util_mac.h" +#include "base/mac_util.h" +#include "base/sys_string_conversions.h" +#include "chrome/browser/bug_report_util.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/tab_contents/tab_contents_view.h" +#include "grit/chromium_strings.h" +#include "grit/generated_resources.h" +#include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" + +@implementation BugReportWindowController + +@synthesize bugDescription = bugDescription_; +@synthesize bugType = bugType_; +@synthesize pageURL = pageURL_; +@synthesize pageTitle = pageTitle_; +@synthesize sendReportButton = sendReportButton_; +@synthesize sendScreenshot = sendScreenshot_; +@synthesize disableScreenshot = disableScreenshot_; +@synthesize bugTypeList = bugTypeList_; + +- (id)initWithTabContents:(TabContents*)currentTab + profile:(Profile*)profile { + NSString* nibpath = [mac_util::MainAppBundle() pathForResource:@"ReportBug" + ofType:@"nib"]; + if ((self = [super initWithWindowNibPath:nibpath owner:self])) { + currentTab_ = currentTab; + profile_ = profile; + [self setBugDescription:@""]; + + if (currentTab_ != NULL) { + // Get data from current tab, if one exists. This dialog could be called + // from the main menu with no tab contents, so currentTab_ is not + // guaranteed to be non-NULL. + // TODO(mirandac): This dialog should be a tab-modal sheet if a browser + // window exists. + [self setSendScreenshot:YES]; + [self setDisableScreenshot:NO]; + bugTypeList_ = [[NSArray alloc] initWithObjects: + l10n_util::GetNSStringWithFixup(IDS_BUGREPORT_PAGE_WONT_LOAD), + l10n_util::GetNSStringWithFixup(IDS_BUGREPORT_PAGE_LOOKS_ODD), + l10n_util::GetNSStringWithFixup(IDS_BUGREPORT_PHISHING_PAGE), + l10n_util::GetNSStringWithFixup(IDS_BUGREPORT_CANT_SIGN_IN), + l10n_util::GetNSStringWithFixup(IDS_BUGREPORT_CHROME_MISBEHAVES), + l10n_util::GetNSStringWithFixup(IDS_BUGREPORT_SOMETHING_MISSING), + l10n_util::GetNSStringWithFixup(IDS_BUGREPORT_BROWSER_CRASH), + l10n_util::GetNSStringWithFixup(IDS_BUGREPORT_OTHER_PROBLEM), + nil]; + [self setPageURL:base::SysUTF8ToNSString( + currentTab_->controller().GetActiveEntry()->url().spec())]; + [self setPageTitle:base::SysUTF16ToNSString(currentTab_->GetTitle())]; + mac_util::GrabWindowSnapshot( + currentTab_->view()->GetTopLevelNativeWindow(), &pngData_); + } else { + // If no current tab exists, create a menu without the "broken page" + // options, with page URL and title empty, and screenshot disabled. + [self setSendScreenshot:NO]; + [self setDisableScreenshot:YES]; + bugTypeList_ = [[NSArray alloc] initWithObjects: + l10n_util::GetNSStringWithFixup(IDS_BUGREPORT_CHROME_MISBEHAVES), + l10n_util::GetNSStringWithFixup(IDS_BUGREPORT_SOMETHING_MISSING), + l10n_util::GetNSStringWithFixup(IDS_BUGREPORT_BROWSER_CRASH), + l10n_util::GetNSStringWithFixup(IDS_BUGREPORT_OTHER_PROBLEM), + nil]; + // Because "Report Bug" is being called with no browser open in this + // case, make URL and title empty. + [self setPageURL:@""]; + [self setPageTitle:@""]; + } + } + return self; +} + +- (void)dealloc { + [pageURL_ release]; + [pageTitle_ release]; + [bugDescription_ release]; + [bugTypeList_ release]; + [super dealloc]; +} + +// Delegate callback so that closing the window deletes the controller. +- (void)windowWillClose:(NSNotification*)notification { + [self autorelease]; +} + +- (void)closeDialog { + [NSApp stopModal]; + [[self window] close]; +} + +- (void)runModalDialog { + [NSApp runModalForWindow:[self window]]; +} + +- (IBAction)sendReport:(id)sender { + if ([self isPhishingReport]) { + BugReportUtil::ReportPhishing(currentTab_, + base::SysNSStringToUTF8(pageURL_)); + } else { + BugReportUtil::SendReport( + profile_, + base::SysNSStringToUTF8(pageTitle_), + bugType_, + base::SysNSStringToUTF8(pageURL_), + base::SysNSStringToUTF8(bugDescription_), + sendScreenshot_ && !pngData_.empty() ? + reinterpret_cast<const char *>(&(pngData_[0])) : NULL, + pngData_.size()); + } + [self closeDialog]; +} + +- (IBAction)cancel:(id)sender { + [self closeDialog]; +} + +- (BOOL)isPhishingReport { + return bugType_ == [bugTypeList_ indexOfObject: + l10n_util::GetNSStringWithFixup(IDS_BUGREPORT_PHISHING_PAGE)]; +} + +- (void)menu:(NSMenu *)menu willHighlightItem:(NSMenuItem *)item { + NSString* buttonTitle = [[item title] isEqualToString: + l10n_util::GetNSStringWithFixup(IDS_BUGREPORT_PHISHING_PAGE)] ? + l10n_util::GetNSStringWithFixup(IDS_BUGREPORT_SEND_PHISHING_REPORT) : + l10n_util::GetNSStringWithFixup(IDS_BUGREPORT_SEND_REPORT); + if (![buttonTitle isEqualToString:[sendReportButton_ title]]) { + [sendReportButton_ setTitle:buttonTitle]; + CGFloat deltaWidth = + [GTMUILocalizerAndLayoutTweaker sizeToFitView:sendReportButton_].width; + NSRect newButtonFrame = [sendReportButton_ frame]; + newButtonFrame.origin.x -= deltaWidth; + [sendReportButton_ setFrame:newButtonFrame]; + } +} + +// BugReportWindowController needs to change the title of the Send Report +// button when the user chooses the phishing bug type, so we need to bind +// the function that changes the button title to the bug type key. ++ (NSSet*)keyPathsForValuesAffectingValueForKey:(NSString*)key { + NSSet* paths = [super keyPathsForValuesAffectingValueForKey:key]; + if ([key isEqualToString:@"isPhishingReport"]) { + paths = [paths setByAddingObject:@"bugType"]; + } + return paths; +} + +@end + + diff --git a/chrome/browser/cocoa/bug_report_window_controller_unittest.mm b/chrome/browser/cocoa/bug_report_window_controller_unittest.mm new file mode 100644 index 0000000..6b15c4a --- /dev/null +++ b/chrome/browser/cocoa/bug_report_window_controller_unittest.mm @@ -0,0 +1,71 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import <Cocoa/Cocoa.h> + +#include "base/ref_counted.h" +#import "chrome/browser/cocoa/bug_report_window_controller.h" +#include "chrome/browser/renderer_host/site_instance.h" +#include "chrome/browser/renderer_host/test/test_render_view_host.h" +#include "chrome/browser/tab_contents/test_tab_contents.h" +#include "chrome/browser/profile.h" + +namespace { + +class BugReportWindowControllerUnittest : public RenderViewHostTestHarness { +}; + +TEST_F(BugReportWindowControllerUnittest, ReportBugWithNewTabPageOpen) { + // Create a "chrome://newtab" test tab. SiteInstance will be deleted when + // tabContents is deleted. + SiteInstance* instance = + SiteInstance::CreateSiteInstance(profile_.get()); + TestTabContents* tabContents = new TestTabContents(profile_.get(), + instance); + tabContents->controller().LoadURL(GURL("chrome://newtab"), + GURL(), PageTransition::START_PAGE); + + BugReportWindowController* controller = [[BugReportWindowController alloc] + initWithTabContents:tabContents + profile:profile_.get()]; + + // The phishing report bug is stored at index 2 in the Report Bug dialog. + [controller setBugType:2]; + EXPECT_TRUE([controller isPhishingReport]); + [controller setBugType:1]; + EXPECT_FALSE([controller isPhishingReport]); + + // Make sure that the tab was correctly recorded. + EXPECT_TRUE([[controller pageURL] isEqualToString:@"chrome://newtab/"]); + EXPECT_TRUE([[controller pageTitle] isEqualToString:@"New Tab"]); + + // When we call "report bug" with non-empty tab contents, all menu options + // should be available, and we should send screenshot by default. + EXPECT_EQ([[controller bugTypeList] count], 8U); + EXPECT_TRUE([controller sendScreenshot]); + + delete tabContents; + [controller release]; +} + +TEST_F(BugReportWindowControllerUnittest, ReportBugWithNoWindowOpen) { + BugReportWindowController* controller = [[BugReportWindowController alloc] + initWithTabContents:NULL + profile:profile_.get()]; + + // Make sure that no page title or URL are recorded. + EXPECT_TRUE([[controller pageURL] isEqualToString:@""]); + EXPECT_TRUE([[controller pageTitle] isEqualToString:@""]); + + // When we call "report bug" with empty tab contents, only menu options + // that don't refer to a specific page should be available, and the send + // screenshot option should be turned off. + EXPECT_EQ([[controller bugTypeList] count], 4U); + EXPECT_FALSE([controller sendScreenshot]); + + [controller release]; +} + +} // namespace + |