diff options
author | Kristian Monsen <kristianm@google.com> | 2011-06-28 21:49:31 +0100 |
---|---|---|
committer | Kristian Monsen <kristianm@google.com> | 2011-07-08 17:55:00 +0100 |
commit | ddb351dbec246cf1fab5ec20d2d5520909041de1 (patch) | |
tree | 158e3fb57bdcac07c7f1e767fde3c70687c9fbb1 /chrome/browser/ui/cocoa | |
parent | 6b92e04f5f151c896e3088e86f70db7081009308 (diff) | |
download | external_chromium-ddb351dbec246cf1fab5ec20d2d5520909041de1.zip external_chromium-ddb351dbec246cf1fab5ec20d2d5520909041de1.tar.gz external_chromium-ddb351dbec246cf1fab5ec20d2d5520909041de1.tar.bz2 |
Merge Chromium at r12.0.742.93: Initial merge by git
Change-Id: Ic5ee2fec31358bbee305f7e915442377bfa6cda6
Diffstat (limited to 'chrome/browser/ui/cocoa')
375 files changed, 4854 insertions, 12251 deletions
diff --git a/chrome/browser/ui/cocoa/about_ipc_controller.h b/chrome/browser/ui/cocoa/about_ipc_controller.h index f0d4075..52ea212 100644 --- a/chrome/browser/ui/cocoa/about_ipc_controller.h +++ b/chrome/browser/ui/cocoa/about_ipc_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,7 +8,7 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_ptr.h" +#include "base/memory/scoped_ptr.h" #include "ipc/ipc_logging.h" #include "ipc/ipc_message_utils.h" #include "third_party/GTM/Foundation/GTMRegex.h" diff --git a/chrome/browser/ui/cocoa/about_ipc_controller_unittest.mm b/chrome/browser/ui/cocoa/about_ipc_controller_unittest.mm index afde86e..3e1ce94 100644 --- a/chrome/browser/ui/cocoa/about_ipc_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/about_ipc_controller_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/about_ipc_controller.h" #include "chrome/browser/ui/cocoa/browser_test_helper.h" #include "chrome/browser/ui/cocoa/cocoa_test_helper.h" diff --git a/chrome/browser/ui/cocoa/about_window_controller.mm b/chrome/browser/ui/cocoa/about_window_controller.mm index 788e26c..a6d10d8 100644 --- a/chrome/browser/ui/cocoa/about_window_controller.mm +++ b/chrome/browser/ui/cocoa/about_window_controller.mm @@ -9,18 +9,18 @@ #include "base/string_number_conversions.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_window.h" #import "chrome/browser/cocoa/keystone_glue.h" #include "chrome/browser/google/google_util.h" #include "chrome/browser/platform_util.h" +#include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/browser_window.h" #import "chrome/browser/ui/cocoa/background_tile_view.h" #include "chrome/browser/ui/cocoa/restart_browser.h" #include "chrome/common/url_constants.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" -#include "grit/theme_resources.h" #include "grit/locale_settings.h" +#include "grit/theme_resources.h" #include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_mac.h" diff --git a/chrome/browser/ui/cocoa/about_window_controller_unittest.mm b/chrome/browser/ui/cocoa/about_window_controller_unittest.mm index 4b57809..ac46d8e 100644 --- a/chrome/browser/ui/cocoa/about_window_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/about_window_controller_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #import "chrome/browser/cocoa/keystone_glue.h" #import "chrome/browser/ui/cocoa/about_window_controller.h" #include "chrome/browser/ui/cocoa/browser_test_helper.h" diff --git a/chrome/browser/ui/cocoa/accelerators_cocoa.h b/chrome/browser/ui/cocoa/accelerators_cocoa.h index 24e9353..867dda5 100644 --- a/chrome/browser/ui/cocoa/accelerators_cocoa.h +++ b/chrome/browser/ui/cocoa/accelerators_cocoa.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -19,7 +19,7 @@ template <typename T> struct DefaultSingletonTraits; // It is recommended that this class be used as a singleton so that the key map // isn't created multiple places. // -// #import "base/singleton.h" +// #import "base/memory/singleton.h" // ... // AcceleratorsCocoa* keymap = AcceleratorsCocoa::GetInstance(); // return keymap->GetAcceleratorForCommand(IDC_COPY); diff --git a/chrome/browser/ui/cocoa/accelerators_cocoa.mm b/chrome/browser/ui/cocoa/accelerators_cocoa.mm index 1b8f3d7..3ec2ed5 100644 --- a/chrome/browser/ui/cocoa/accelerators_cocoa.mm +++ b/chrome/browser/ui/cocoa/accelerators_cocoa.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -6,7 +6,7 @@ #import <Cocoa/Cocoa.h> -#include "base/singleton.h" +#include "base/memory/singleton.h" #include "chrome/app/chrome_command_ids.h" namespace { diff --git a/chrome/browser/ui/cocoa/accelerators_cocoa_unittest.mm b/chrome/browser/ui/cocoa/accelerators_cocoa_unittest.mm index 2a39ffe..c6e2346 100644 --- a/chrome/browser/ui/cocoa/accelerators_cocoa_unittest.mm +++ b/chrome/browser/ui/cocoa/accelerators_cocoa_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/singleton.h" +#include "base/memory/singleton.h" #include "chrome/app/chrome_command_ids.h" #import "chrome/browser/ui/cocoa/accelerators_cocoa.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/animatable_image.h b/chrome/browser/ui/cocoa/animatable_image.h index a6f8ab9..54eac84 100644 --- a/chrome/browser/ui/cocoa/animatable_image.h +++ b/chrome/browser/ui/cocoa/animatable_image.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,7 +9,7 @@ #import <Cocoa/Cocoa.h> #import <QuartzCore/QuartzCore.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" // This class helps animate an NSImage's frame and opacity. It works by creating // a blank NSWindow in the size specified and giving it a layer on which the diff --git a/chrome/browser/ui/cocoa/animatable_view.h b/chrome/browser/ui/cocoa/animatable_view.h index 2bd121a..aa417d2 100644 --- a/chrome/browser/ui/cocoa/animatable_view.h +++ b/chrome/browser/ui/cocoa/animatable_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,7 +9,7 @@ #import <Cocoa/Cocoa.h> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/background_gradient_view.h" #import "chrome/browser/ui/cocoa/view_resizer.h" diff --git a/chrome/browser/ui/cocoa/animatable_view_unittest.mm b/chrome/browser/ui/cocoa/animatable_view_unittest.mm index b9073a8..e59eae9 100644 --- a/chrome/browser/ui/cocoa/animatable_view_unittest.mm +++ b/chrome/browser/ui/cocoa/animatable_view_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/animatable_view.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/view_resizer_pong.h" diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.h b/chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.h index 293d738..e55f933 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.h +++ b/chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.h @@ -8,7 +8,7 @@ #import <objc/objc-runtime.h> #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/app_controller_mac.h" #import "chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.h" #include "chrome/browser/ui/cocoa/browser_test_helper.h" diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm b/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm index 40d84b2..9a01d2f 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/applescript/bookmark_folder_applescript.h" -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #import "base/string16.h" #include "base/sys_string_conversions.h" #include "chrome/browser/bookmarks/bookmark_model.h" @@ -17,9 +17,9 @@ - (NSArray*)bookmarkFolders { NSMutableArray* bookmarkFolders = [NSMutableArray - arrayWithCapacity:bookmarkNode_->GetChildCount()]; + arrayWithCapacity:bookmarkNode_->child_count()]; - for (int i = 0; i < bookmarkNode_->GetChildCount(); ++i) { + for (int i = 0; i < bookmarkNode_->child_count(); ++i) { const BookmarkNode* node = bookmarkNode_->GetChild(i); if (!node->is_folder()) @@ -44,9 +44,9 @@ if (!model) return; - const BookmarkNode* node = model->AddGroup(bookmarkNode_, - bookmarkNode_->GetChildCount(), - string16()); + const BookmarkNode* node = model->AddFolder(bookmarkNode_, + bookmarkNode_->child_count(), + string16()); if (!node) { AppleScript::SetError(AppleScript::errCreateBookmarkFolder); return; @@ -66,9 +66,9 @@ if (!model) return; - const BookmarkNode* node = model->AddGroup(bookmarkNode_, - position, - string16()); + const BookmarkNode* node = model->AddFolder(bookmarkNode_, + position, + string16()); if (!node) { AppleScript::SetError(AppleScript::errCreateBookmarkFolder); return; @@ -89,9 +89,9 @@ - (NSArray*)bookmarkItems { NSMutableArray* bookmarkItems = [NSMutableArray - arrayWithCapacity:bookmarkNode_->GetChildCount()]; + arrayWithCapacity:bookmarkNode_->child_count()]; - for (int i = 0; i < bookmarkNode_->GetChildCount(); ++i) { + for (int i = 0; i < bookmarkNode_->child_count(); ++i) { const BookmarkNode* node = bookmarkNode_->GetChild(i); if (!node->is_url()) @@ -124,7 +124,7 @@ } const BookmarkNode* node = model->AddURL(bookmarkNode_, - bookmarkNode_->GetChildCount(), + bookmarkNode_->child_count(), string16(), url); if (!node) { diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript_unittest.mm b/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript_unittest.mm index fbdbf09..b62ef8b 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript_unittest.mm +++ b/chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/sys_string_conversions.h" #import "chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.h" #import "chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.h" diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript_unittest.mm b/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript_unittest.mm index 2cd5a94..51f079c 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript_unittest.mm +++ b/chrome/browser/ui/cocoa/applescript/bookmark_item_applescript_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/sys_string_conversions.h" #import "chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.h" #import "chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.h" diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.mm b/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.mm index 3dabbbe..24b5857 100644 --- a/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/bookmark_node_applescript.mm @@ -1,12 +1,12 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/applescript/bookmark_node_applescript.h" #include "base/logging.h" +#import "base/memory/scoped_nsobject.h" #include "base/sys_string_conversions.h" -#import "base/scoped_nsobject.h" #import "chrome/browser/app_controller_mac.h" #include "chrome/browser/bookmarks/bookmark_model.h" #import "chrome/browser/chrome_browser_application_mac.h" @@ -103,8 +103,8 @@ } - (NSNumber*)index { - const BookmarkNode* parent = bookmarkNode_->GetParent(); - int index = parent->IndexOfChild(bookmarkNode_); + const BookmarkNode* parent = bookmarkNode_->parent(); + int index = parent->GetIndexOf(bookmarkNode_); // NOTE: AppleScript is 1-Based. return [NSNumber numberWithInt:index+1]; } diff --git a/chrome/browser/ui/cocoa/applescript/browsercrapplication+applescript.mm b/chrome/browser/ui/cocoa/applescript/browsercrapplication+applescript.mm index c8659b7..9cd3517 100644 --- a/chrome/browser/ui/cocoa/applescript/browsercrapplication+applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/browsercrapplication+applescript.mm @@ -1,15 +1,15 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/applescript/browsercrapplication+applescript.h" #include "base/logging.h" -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #import "chrome/browser/app_controller_mac.h" #include "chrome/browser/bookmarks/bookmark_model.h" -#include "chrome/browser/browser_list.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser_list.h" #import "chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.h" #import "chrome/browser/ui/cocoa/applescript/constants_applescript.h" #import "chrome/browser/ui/cocoa/applescript/error_applescript.h" diff --git a/chrome/browser/ui/cocoa/applescript/tab_applescript.h b/chrome/browser/ui/cocoa/applescript/tab_applescript.h index 30064fa..424d5cf 100644 --- a/chrome/browser/ui/cocoa/applescript/tab_applescript.h +++ b/chrome/browser/ui/cocoa/applescript/tab_applescript.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,12 +9,12 @@ #import "chrome/browser/ui/cocoa/applescript/element_applescript.h" -class TabContents; +class TabContentsWrapper; // Represents a tab scriptable item in applescript. @interface TabAppleScript : ElementAppleScript { @private - TabContents* tabContents_; // weak. + TabContentsWrapper* tabContents_; // weak. // Contains the temporary URL when a user creates a new folder/item with // url specified like // |make new tab with properties {url:"http://google.com"}|. @@ -27,10 +27,10 @@ class TabContents; - (id)init; // Does not create a new tab but uses an existing one. -- (id)initWithTabContent:(TabContents*)aTabContent; +- (id)initWithTabContent:(TabContentsWrapper*)aTabContent; // Assigns a tab, sets its unique ID and also copies temporary values. -- (void)setTabContent:(TabContents*)aTabContent; +- (void)setTabContent:(TabContentsWrapper*)aTabContent; // Return the URL currently visible to the user in the location bar. - (NSString*)URL; diff --git a/chrome/browser/ui/cocoa/applescript/tab_applescript.mm b/chrome/browser/ui/cocoa/applescript/tab_applescript.mm index ab9b827..401eb6b 100644 --- a/chrome/browser/ui/cocoa/applescript/tab_applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/tab_applescript.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -6,17 +6,18 @@ #include "base/file_path.h" #include "base/logging.h" -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" #include "chrome/browser/download/save_package.h" #include "chrome/browser/sessions/session_id.h" #include "chrome/browser/ui/cocoa/applescript/error_applescript.h" +#include "chrome/browser/ui/download/download_tab_helper.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/common/url_constants.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/browser/tab_contents/navigation_controller.h" #include "content/browser/tab_contents/navigation_entry.h" -#include "content/browser/tab_contents/tab_contents.h" #include "googleurl/src/gurl.h" @interface TabAppleScript() @@ -46,7 +47,7 @@ [super dealloc]; } -- (id)initWithTabContent:(TabContents*)aTabContent { +- (id)initWithTabContent:(TabContentsWrapper*)aTabContent { if (!aTabContent) { [self release]; return nil; @@ -65,7 +66,7 @@ return self; } -- (void)setTabContent:(TabContents*)aTabContent { +- (void)setTabContent:(TabContentsWrapper*)aTabContent { DCHECK(aTabContent); // It is safe to be weak, if a tab goes away (eg user closing a tab) // the applescript runtime calls tabs in AppleScriptWindow and this @@ -112,10 +113,10 @@ return; const GURL& previousURL = entry->virtual_url(); - tabContents_->OpenURL(url, - previousURL, - CURRENT_TAB, - PageTransition::TYPED); + tabContents_->tab_contents()->OpenURL(url, + previousURL, + CURRENT_TAB, + PageTransition::TYPED); } - (NSString*)title { @@ -132,7 +133,7 @@ } - (NSNumber*)loading { - BOOL loadingValue = tabContents_->is_loading() ? YES : NO; + BOOL loadingValue = tabContents_->tab_contents()->is_loading() ? YES : NO; return [NSNumber numberWithBool:loadingValue]; } @@ -227,7 +228,7 @@ } - (void)handlesPrintScriptCommand:(NSScriptCommand*)command { - bool initiateStatus = tabContents_->PrintNow(); + bool initiateStatus = tabContents_->print_view_manager()->PrintNow(); if (initiateStatus == false) { AppleScript::SetError(AppleScript::errInitiatePrinting); } @@ -240,7 +241,7 @@ // Scripter has not specifed the location at which to save, so we prompt for // it. if (!fileURL) { - tabContents_->OnSavePage(); + tabContents_->download_tab_helper()->OnSavePage(); return; } @@ -266,15 +267,21 @@ } } - tabContents_->SavePage(mainFile, directoryPath, savePackageType); + tabContents_->download_tab_helper()->SavePage(mainFile, + directoryPath, + savePackageType); } - (void)handlesViewSourceScriptCommand:(NSScriptCommand*)command { NavigationEntry* entry = tabContents_->controller().GetLastCommittedEntry(); if (entry) { - tabContents_->OpenURL(GURL(chrome::kViewSourceScheme + std::string(":") + - entry->url().spec()), GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK); + tabContents_->tab_contents()->OpenURL( + GURL(chrome::kViewSourceScheme + std::string(":") + + entry->url().spec()), + GURL(), + NEW_FOREGROUND_TAB, + PageTransition::LINK); } } diff --git a/chrome/browser/ui/cocoa/applescript/window_applescript.mm b/chrome/browser/ui/cocoa/applescript/window_applescript.mm index d9213de..491cc8d 100644 --- a/chrome/browser/ui/cocoa/applescript/window_applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/window_applescript.mm @@ -1,12 +1,12 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/applescript/window_applescript.h" #include "base/logging.h" -#import "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#import "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "base/time.h" #import "chrome/browser/app_controller_mac.h" #import "chrome/browser/chrome_browser_application_mac.h" @@ -105,7 +105,7 @@ - (NSNumber*)activeTabIndex { // Note: applescript is 1-based, that is lists begin with index 1. - int activeTabIndex = browser_->selected_index() + 1; + int activeTabIndex = browser_->active_index() + 1; if (!activeTabIndex) { return nil; } @@ -116,7 +116,7 @@ // Note: applescript is 1-based, that is lists begin with index 1. int atIndex = [anActiveTabIndex intValue] - 1; if (atIndex >= 0 && atIndex < browser_->tab_count()) - browser_->SelectTabContentsAt(atIndex, true); + browser_->ActivateTabAt(atIndex, true); else AppleScript::SetError(AppleScript::errInvalidTabIndex); } @@ -136,8 +136,10 @@ } - (TabAppleScript*)activeTab { - TabAppleScript* currentTab = [[[TabAppleScript alloc] - initWithTabContent:browser_->GetSelectedTabContents()] autorelease]; + TabAppleScript* currentTab = + [[[TabAppleScript alloc] + initWithTabContent:browser_->GetSelectedTabContentsWrapper()] + autorelease]; [currentTab setContainer:self property:AppleScript::kTabsProperty]; return currentTab; @@ -155,7 +157,7 @@ scoped_nsobject<TabAppleScript> tab( [[TabAppleScript alloc] - initWithTabContent:(browser_->GetTabContentsAt(i))]); + initWithTabContent:(browser_->GetTabContentsWrapperAt(i))]); [tab setContainer:self property:AppleScript::kTabsProperty]; [tabs addObject:tab]; @@ -175,7 +177,7 @@ browser_->AddSelectedTabWithURL(GURL(chrome::kChromeUINewTabURL), PageTransition::TYPED); contents->tab_contents()->set_new_tab_start_time(newTabStartTime); - [aTab setTabContent:contents->tab_contents()]; + [aTab setTabContent:contents]; } - (void)insertInTabs:(TabAppleScript*)aTab atIndex:(int)index { @@ -195,7 +197,7 @@ params.target_contents->tab_contents()->set_new_tab_start_time( newTabStartTime); - [aTab setTabContent:params.target_contents->tab_contents()]; + [aTab setTabContent:params.target_contents]; } - (void)removeFromTabsAtIndex:(int)index { diff --git a/chrome/browser/ui/cocoa/applescript/window_applescript_test.mm b/chrome/browser/ui/cocoa/applescript/window_applescript_test.mm index 96eb930..b1bee22 100644 --- a/chrome/browser/ui/cocoa/applescript/window_applescript_test.mm +++ b/chrome/browser/ui/cocoa/applescript/window_applescript_test.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #include "base/sys_string_conversions.h" #import "chrome/browser/app_controller_mac.h" #import "chrome/browser/chrome_browser_application_mac.h" diff --git a/chrome/browser/ui/cocoa/background_gradient_view.mm b/chrome/browser/ui/cocoa/background_gradient_view.mm index 7b031a2..4f808c8 100644 --- a/chrome/browser/ui/cocoa/background_gradient_view.mm +++ b/chrome/browser/ui/cocoa/background_gradient_view.mm @@ -1,10 +1,11 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. #include "chrome/browser/ui/cocoa/background_gradient_view.h" -#import "chrome/browser/themes/browser_theme_provider.h" +#import "chrome/browser/themes/theme_service.h" +#import "chrome/browser/ui/cocoa/nsview_additions.h" #import "chrome/browser/ui/cocoa/themed_window.h" #include "grit/theme_resources.h" @@ -43,8 +44,8 @@ } else { CGFloat winHeight = NSHeight([[self window] frame]); NSGradient* gradient = themeProvider->GetNSGradient( - isKey ? BrowserThemeProvider::GRADIENT_TOOLBAR : - BrowserThemeProvider::GRADIENT_TOOLBAR_INACTIVE); + isKey ? ThemeService::GRADIENT_TOOLBAR : + ThemeService::GRADIENT_TOOLBAR_INACTIVE); NSPoint startPoint = [self convertPoint:NSMakePoint(0, winHeight - kToolbarTopOffset) fromView:nil]; @@ -62,7 +63,8 @@ // Draw bottom stroke [[self strokeColor] set]; NSRect borderRect, contentRect; - NSDivideRect([self bounds], &borderRect, &contentRect, 1, NSMinYEdge); + NSDivideRect([self bounds], &borderRect, &contentRect, + [self cr_lineWidth], NSMinYEdge); NSRectFillUsingOperation(borderRect, NSCompositeSourceOver); } } @@ -74,8 +76,8 @@ if (!themeProvider) return [NSColor blackColor]; return themeProvider->GetNSColor( - isKey ? BrowserThemeProvider::COLOR_TOOLBAR_STROKE : - BrowserThemeProvider::COLOR_TOOLBAR_STROKE_INACTIVE, true); + isKey ? ThemeService::COLOR_TOOLBAR_STROKE : + ThemeService::COLOR_TOOLBAR_STROKE_INACTIVE, true); } @end diff --git a/chrome/browser/ui/cocoa/background_gradient_view_unittest.mm b/chrome/browser/ui/cocoa/background_gradient_view_unittest.mm index 693c21a..73040d2 100644 --- a/chrome/browser/ui/cocoa/background_gradient_view_unittest.mm +++ b/chrome/browser/ui/cocoa/background_gradient_view_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/background_gradient_view.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/background_tile_view_unittest.mm b/chrome/browser/ui/cocoa/background_tile_view_unittest.mm index 4af5751..8b14e63 100644 --- a/chrome/browser/ui/cocoa/background_tile_view_unittest.mm +++ b/chrome/browser/ui/cocoa/background_tile_view_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/background_tile_view.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/base_bubble_controller.h b/chrome/browser/ui/cocoa/base_bubble_controller.h index 216406b..27d750e 100644 --- a/chrome/browser/ui/cocoa/base_bubble_controller.h +++ b/chrome/browser/ui/cocoa/base_bubble_controller.h @@ -1,11 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_ptr.h" namespace BaseBubbleControllerInternal { class Bridge; diff --git a/chrome/browser/ui/cocoa/base_bubble_controller.mm b/chrome/browser/ui/cocoa/base_bubble_controller.mm index 618faf9..7b1f247 100644 --- a/chrome/browser/ui/cocoa/base_bubble_controller.mm +++ b/chrome/browser/ui/cocoa/base_bubble_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -6,13 +6,13 @@ #include "base/logging.h" #include "base/mac/mac_util.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/string_util.h" #import "chrome/browser/ui/cocoa/info_bubble_view.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/notification_type.h" +#include "content/common/notification_observer.h" +#include "content/common/notification_registrar.h" +#include "content/common/notification_service.h" +#include "content/common/notification_type.h" #include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" diff --git a/chrome/browser/ui/cocoa/base_view.h b/chrome/browser/ui/cocoa/base_view.h index bb2aeed..5dbc87b 100644 --- a/chrome/browser/ui/cocoa/base_view.h +++ b/chrome/browser/ui/cocoa/base_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,7 +8,7 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "ui/gfx/rect.h" // A view that provides common functionality that many views will need: diff --git a/chrome/browser/ui/cocoa/base_view_unittest.mm b/chrome/browser/ui/cocoa/base_view_unittest.mm index bd356b4..1cc99d2 100644 --- a/chrome/browser/ui/cocoa/base_view_unittest.mm +++ b/chrome/browser/ui/cocoa/base_view_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/base_view.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/bookmarks/OWNERS b/chrome/browser/ui/cocoa/bookmarks/OWNERS index df805b9..ec05942 100644 --- a/chrome/browser/ui/cocoa/bookmarks/OWNERS +++ b/chrome/browser/ui/cocoa/bookmarks/OWNERS @@ -1,2 +1,3 @@ jrg@chromium.org mrossetti@chromium.org +maf@chromium.org diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller.mm index 67095d2..47dab5d 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -61,13 +61,15 @@ [NSCharacterSet newlineCharacterSet]]; std::wstring newTitle = base::SysNSStringToWide(name); const BookmarkNode* newParentNode = [self selectedNode]; - int newIndex = newParentNode->GetChildCount(); + if (!newParentNode) + return [NSNumber numberWithBool:NO]; + int newIndex = newParentNode->child_count(); // Create the new folder which will contain all of the tab URLs. NSString* newFolderName = [self displayName]; string16 newFolderString = base::SysNSStringToUTF16(newFolderName); BookmarkModel* model = [self bookmarkModel]; - const BookmarkNode* newFolder = model->AddGroup(newParentNode, newIndex, - newFolderString); + const BookmarkNode* newFolder = model->AddFolder(newParentNode, newIndex, + newFolderString); // Get a list of all open tabs, create nodes for them, and add // to the new folder node. [self UpdateActiveTabPairs]; diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller_unittest.mm index 9f8a7d8..d71c6ec 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" #include "chrome/browser/bookmarks/bookmark_model.h" @@ -38,22 +38,22 @@ class BookmarkAllTabsControllerTest : public CocoaTest { BrowserTestHelper helper_; const BookmarkNode* parent_node_; BookmarkAllTabsControllerOverride* controller_; - const BookmarkNode* group_a_; + const BookmarkNode* folder_a_; BookmarkAllTabsControllerTest() { BookmarkModel& model(*(helper_.profile()->GetBookmarkModel())); const BookmarkNode* root = model.GetBookmarkBarNode(); - group_a_ = model.AddGroup(root, 0, ASCIIToUTF16("a")); - model.AddURL(group_a_, 0, ASCIIToUTF16("a-0"), GURL("http://a-0.com")); - model.AddURL(group_a_, 1, ASCIIToUTF16("a-1"), GURL("http://a-1.com")); - model.AddURL(group_a_, 2, ASCIIToUTF16("a-2"), GURL("http://a-2.com")); + folder_a_ = model.AddFolder(root, 0, ASCIIToUTF16("a")); + model.AddURL(folder_a_, 0, ASCIIToUTF16("a-0"), GURL("http://a-0.com")); + model.AddURL(folder_a_, 1, ASCIIToUTF16("a-1"), GURL("http://a-1.com")); + model.AddURL(folder_a_, 2, ASCIIToUTF16("a-2"), GURL("http://a-2.com")); } virtual BookmarkAllTabsControllerOverride* CreateController() { return [[BookmarkAllTabsControllerOverride alloc] initWithParentWindow:test_window() profile:helper_.profile() - parent:group_a_ + parent:folder_a_ configuration:BookmarkEditor::SHOW_TREE]; } @@ -72,11 +72,11 @@ class BookmarkAllTabsControllerTest : public CocoaTest { TEST_F(BookmarkAllTabsControllerTest, BookmarkAllTabs) { // OK button should always be enabled. EXPECT_TRUE([controller_ okButtonEnabled]); - [controller_ selectTestNodeInBrowser:group_a_]; + [controller_ selectTestNodeInBrowser:folder_a_]; [controller_ setDisplayName:@"ALL MY TABS"]; [controller_ ok:nil]; - EXPECT_EQ(4, group_a_->GetChildCount()); - const BookmarkNode* folderChild = group_a_->GetChild(3); + EXPECT_EQ(4, folder_a_->child_count()); + const BookmarkNode* folderChild = folder_a_->GetChild(3); EXPECT_EQ(folderChild->GetTitle(), ASCIIToUTF16("ALL MY TABS")); - EXPECT_EQ(3, folderChild->GetChildCount()); + EXPECT_EQ(3, folderChild->child_count()); } diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.h index 811c450..849d85c 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.h @@ -41,7 +41,7 @@ class BookmarkBarBridge : public BookmarkModelObserver { const BookmarkNode* node); virtual void BookmarkNodeChanged(BookmarkModel* model, const BookmarkNode* node); - virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, + virtual void BookmarkNodeFaviconLoaded(BookmarkModel* model, const BookmarkNode* node); virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, const BookmarkNode* node); diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.mm index 54f5e81..a00e7cb 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.mm @@ -62,9 +62,9 @@ void BookmarkBarBridge::BookmarkNodeChanged(BookmarkModel* model, [controller_ nodeChanged:model node:node]; } -void BookmarkBarBridge::BookmarkNodeFavIconLoaded(BookmarkModel* model, +void BookmarkBarBridge::BookmarkNodeFaviconLoaded(BookmarkModel* model, const BookmarkNode* node) { - [controller_ nodeFavIconLoaded:model node:node]; + [controller_ nodeFaviconLoaded:model node:node]; } void BookmarkBarBridge::BookmarkNodeChildrenReordered( diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge_unittest.mm index 067d327..646af0e 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge_unittest.mm @@ -67,7 +67,7 @@ typedef std::pair<GURL,WindowOpenDisposition> OpenInfo; [callbacks_ addObject:[NSNumber numberWithInt:4]]; } -- (void)nodeFavIconLoaded:(BookmarkModel*)model +- (void)nodeFaviconLoaded:(BookmarkModel*)model node:(const BookmarkNode*)node { [callbacks_ addObject:[NSNumber numberWithInt:5]]; } @@ -121,7 +121,7 @@ TEST_F(BookmarkBarBridgeTest, TestRedirect) { bridge->BookmarkNodeMoved(NULL, NULL, 0, NULL, 0); bridge->BookmarkNodeAdded(NULL, NULL, 0); bridge->BookmarkNodeChanged(NULL, NULL); - bridge->BookmarkNodeFavIconLoaded(NULL, NULL); + bridge->BookmarkNodeFaviconLoaded(NULL, NULL); bridge->BookmarkNodeChildrenReordered(NULL, NULL); bridge->BookmarkNodeRemoved(NULL, NULL, 0, NULL); diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h index 2598c70..b874014 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h @@ -9,15 +9,15 @@ #import <Cocoa/Cocoa.h> #include <map> -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_constants.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_state.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h" #include "chrome/browser/ui/cocoa/tabs/tab_strip_model_observer_bridge.h" -#import "chrome/common/chrome_application_mac.h" +#import "content/common/chrome_application_mac.h" #include "webkit/glue/window_open_disposition.h" @class BookmarkBarController; @@ -31,10 +31,6 @@ class BookmarkModel; class BookmarkNode; class Browser; class GURL; -class PrefService; -class TabContents; -@class ToolbarController; -@protocol ViewResizer; namespace bookmarks { @@ -260,6 +256,13 @@ willAnimateFromState:(bookmarks::VisualState)oldState // Set to YES to prevent any node animations. Useful for unit testing so that // incomplete animations do not cause valgrind complaints. BOOL ignoreAnimations_; + + // YES if there is a possible drop about to happen in the bar. + BOOL hasInsertionPos_; + + // The x point on the bar where the left edge of the new item will end + // up if it is dropped. + CGFloat insertionPos_; } @property(readonly, nonatomic) bookmarks::VisualState visualState; @@ -305,8 +308,8 @@ willAnimateFromState:(bookmarks::VisualState)oldState // Import bookmarks from another browser. - (IBAction)importBookmarks:(id)sender; -// Provide a favIcon for a bookmark node. May return nil. -- (NSImage*)favIconForNode:(const BookmarkNode*)node; +// Provide a favicon for a bookmark node. May return nil. +- (NSImage*)faviconForNode:(const BookmarkNode*)node; // Used for situations where the bookmark bar folder menus should no longer // be actively popping up. Called when the window loses focus, a click has @@ -321,6 +324,9 @@ willAnimateFromState:(bookmarks::VisualState)oldState // Checks if operations such as edit or delete are allowed. - (BOOL)canEditBookmark:(const BookmarkNode*)node; +// Checks if bookmark editing is enabled at all. +- (BOOL)canEditBookmarks; + // Actions for manipulating bookmarks. // Open a normal bookmark or folder from a button, ... - (IBAction)openBookmark:(id)sender; @@ -360,7 +366,7 @@ willAnimateFromState:(bookmarks::VisualState)oldState newParent:(const BookmarkNode*)newParent newIndex:(int)newIndex; - (void)nodeRemoved:(BookmarkModel*)model parent:(const BookmarkNode*)oldParent index:(int)index; -- (void)nodeFavIconLoaded:(BookmarkModel*)model +- (void)nodeFaviconLoaded:(BookmarkModel*)model node:(const BookmarkNode*)node; - (void)nodeChildrenReordered:(BookmarkModel*)model node:(const BookmarkNode*)node; diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm index 4e7eda5..c8156d0 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm @@ -4,6 +4,7 @@ #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h" +#include "app/mac/nsimage_cache.h" #include "base/mac/mac_util.h" #include "base/metrics/histogram.h" #include "base/sys_string_conversions.h" @@ -14,7 +15,8 @@ #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" -#import "chrome/browser/themes/browser_theme_provider.h" +#import "chrome/browser/themes/theme_service.h" +#import "chrome/browser/themes/theme_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #import "chrome/browser/ui/cocoa/background_gradient_view.h" @@ -33,7 +35,6 @@ #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/event_utils.h" #import "chrome/browser/ui/cocoa/fullscreen_controller.h" -#import "chrome/browser/ui/cocoa/importer/import_dialog_cocoa.h" #import "chrome/browser/ui/cocoa/menu_button.h" #import "chrome/browser/ui/cocoa/themed_window.h" #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" @@ -209,8 +210,9 @@ void RecordAppLaunch(Profile* profile, GURL url) { - (void)addButtonsToView; - (void)centerNoItemsLabel; - (void)setNodeForBarMenu; - - (void)watchForExitEvent:(BOOL)watch; +- (void)resetAllButtonPositionsWithAnimation:(BOOL)animate; +- (BOOL)animationEnabled; @end @@ -241,7 +243,7 @@ void RecordAppLaunch(Profile* profile, GURL url) { ResourceBundle& rb = ResourceBundle::GetSharedInstance(); folderImage_.reset( [rb.GetNativeImageNamed(IDR_BOOKMARK_BAR_FOLDER) retain]); - defaultImage_.reset([rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON) retain]); + defaultImage_.reset([app::mac::GetCachedImageWithName(@"nav.pdf") retain]); // Register for theme changes, bookmark button pulsing, ... NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter]; @@ -262,6 +264,12 @@ void RecordAppLaunch(Profile* profile, GURL url) { return self; } +// Can be overridden in a test subclass if a simplistic test is being confused +// by asynchronous animation or is running needlessly slow. +- (BOOL)animationEnabled { + return YES; +} + - (void)pulseBookmarkNotification:(NSNotification*)notification { NSDictionary* dict = [notification userInfo]; const BookmarkNode* node = NULL; @@ -288,7 +296,7 @@ void RecordAppLaunch(Profile* profile, GURL url) { [otherBookmarksButton_ setIsContinuousPulsing:doPulse]; return; } - if (node->GetParent() == bookmarkModel_->GetBookmarkBarNode()) { + if (node->parent() == bookmarkModel_->GetBookmarkBarNode()) { [offTheSideButton_ setIsContinuousPulsing:doPulse]; return; } @@ -397,8 +405,8 @@ void RecordAppLaunch(Profile* profile, GURL url) { name:NSWindowWillCloseNotification object:[[self view] window]]; [defaultCenter addObserver:self - selector:@selector(parentWindowDidResignKey:) - name:NSWindowDidResignKeyNotification + selector:@selector(parentWindowDidResignMain:) + name:NSWindowDidResignMainNotification object:[[self view] window]]; } @@ -425,7 +433,7 @@ void RecordAppLaunch(Profile* profile, GURL url) { } // NSNotificationCenter callback. -- (void)parentWindowDidResignKey:(NSNotification*)notification { +- (void)parentWindowDidResignMain:(NSNotification*)notification { [self closeFolderAndStopTrackingMenus]; } @@ -503,16 +511,16 @@ void RecordAppLaunch(Profile* profile, GURL url) { return [self isInState:bookmarks::kShowingState] ? 0 : 1; } -- (NSImage*)favIconForNode:(const BookmarkNode*)node { +- (NSImage*)faviconForNode:(const BookmarkNode*)node { if (!node) return defaultImage_; if (node->is_folder()) return folderImage_; - const SkBitmap& favIcon = bookmarkModel_->GetFavIcon(node); - if (!favIcon.isNull()) - return gfx::SkBitmapToNSImage(favIcon); + const SkBitmap& favicon = bookmarkModel_->GetFavicon(node); + if (!favicon.isNull()) + return gfx::SkBitmapToNSImage(favicon); return defaultImage_; } @@ -522,6 +530,11 @@ void RecordAppLaunch(Profile* profile, GURL url) { [self closeAllBookmarkFolders]; } +- (BOOL)canEditBookmarks { + PrefService* prefs = browser_->profile()->GetPrefs(); + return prefs->GetBoolean(prefs::kEditBookmarksEnabled); +} + - (BOOL)canEditBookmark:(const BookmarkNode*)node { // Don't allow edit/delete of the bar node, or of "Other Bookmarks" if ((node == nil) || @@ -533,14 +546,88 @@ void RecordAppLaunch(Profile* profile, GURL url) { #pragma mark Actions -- (IBAction)openBookmark:(id)sender { +// Helper methods called on the main thread by runMenuFlashThread. + +- (void)setButtonFlashStateOn:(id)sender { + [sender highlight:YES]; +} + +- (void)setButtonFlashStateOff:(id)sender { + [sender highlight:NO]; +} + +-(void)cleanupAfterMenuFlashThread:(id)sender { [self closeFolderAndStopTrackingMenus]; + + // Items retained by doMenuFlashOnSeparateThread below. + [sender release]; + [self release]; +} + +// End runMenuFlashThread helper methods. + +// This call is invoked only by doMenuFlashOnSeparateThread below. +// It makes the selected BookmarkButton (which is masquerading as a menu item) +// flash a few times to give confirmation feedback, then it closes the menu. +// It spends all its time sleeping or scheduling UI work on the main thread. +- (void)runMenuFlashThread:(id)sender { + + // Check this is not running on the main thread, as it sleeps. + DCHECK(![NSThread isMainThread]); + + // Duration of flash phases and number of flashes designed to evoke a + // slightly retro "more mac-like than the Mac" feel. + // Current Cocoa UI has a barely perceptible flash,probably because Apple + // doesn't fire the action til after the animation and so there's a hurry. + // As this code is fully asynchronous, it can take its time. + const float kBBOnFlashTime = 0.08; + const float kBBOffFlashTime = 0.08; + const int kBookmarkButtonMenuFlashes = 3; + + for (int count = 0 ; count < kBookmarkButtonMenuFlashes ; count++) { + [self performSelectorOnMainThread:@selector(setButtonFlashStateOn:) + withObject:sender + waitUntilDone:NO]; + [NSThread sleepForTimeInterval:kBBOnFlashTime]; + [self performSelectorOnMainThread:@selector(setButtonFlashStateOff:) + withObject:sender + waitUntilDone:NO]; + [NSThread sleepForTimeInterval:kBBOffFlashTime]; + } + [self performSelectorOnMainThread:@selector(cleanupAfterMenuFlashThread:) + withObject:sender + waitUntilDone:NO]; +} + +// Non-blocking call which starts the process to make the selected menu item +// flash a few times to give confirmation feedback, after which it closes the +// menu. The item is of course actually a BookmarkButton masquerading as a menu +// item). +- (void)doMenuFlashOnSeparateThread:(id)sender { + + // Ensure that self and sender don't go away before the animation completes. + // These retains are balanced in cleanupAfterMenuFlashThread above. + [self retain]; + [sender retain]; + [NSThread detachNewThreadSelector:@selector(runMenuFlashThread:) + toTarget:self + withObject:sender]; +} + +- (IBAction)openBookmark:(id)sender { + BOOL isMenuItem = [[sender cell] isFolderButtonCell]; + BOOL animate = isMenuItem && [self animationEnabled]; + if (animate) + [self doMenuFlashOnSeparateThread:sender]; DCHECK([sender respondsToSelector:@selector(bookmarkNode)]); const BookmarkNode* node = [sender bookmarkNode]; WindowOpenDisposition disposition = event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]); RecordAppLaunch(browser_->profile(), node->GetURL()); [self openURL:node->GetURL() disposition:disposition]; + + if (!animate) + [self closeFolderAndStopTrackingMenus]; } // Common function to open a bookmark folder of any type. @@ -612,7 +699,7 @@ void RecordAppLaunch(Profile* profile, GURL url) { // UI. BookmarkEditor::Show([[self view] window], browser_->profile(), - node->GetParent(), + node->parent(), BookmarkEditor::EditDetails(node), BookmarkEditor::SHOW_TREE); } @@ -643,9 +730,9 @@ void RecordAppLaunch(Profile* profile, GURL url) { if (node) { int index = -1; if (node != bookmarkModel_->GetBookmarkBarNode() && !node->is_folder()) { - const BookmarkNode* parent = node->GetParent(); - index = parent->IndexOfChild(node) + 1; - if (index > parent->GetChildCount()) + const BookmarkNode* parent = node->parent(); + index = parent->GetIndexOf(node) + 1; + if (index > parent->child_count()) index = -1; node = parent; } @@ -656,8 +743,8 @@ void RecordAppLaunch(Profile* profile, GURL url) { - (IBAction)deleteBookmark:(id)sender { const BookmarkNode* node = [self nodeFromMenuItem:sender]; if (node) { - bookmarkModel_->Remove(node->GetParent(), - node->GetParent()->IndexOfChild(node)); + bookmarkModel_->Remove(node->parent(), + node->parent()->GetIndexOf(node)); } } @@ -717,10 +804,10 @@ void RecordAppLaunch(Profile* profile, GURL url) { type == BookmarkNode::OTHER_NODE || type == BookmarkNode::FOLDER) { parent = senderNode; - newIndex = parent->GetChildCount(); + newIndex = parent->child_count(); } else { - parent = senderNode->GetParent(); - newIndex = parent->IndexOfChild(senderNode) + 1; + parent = senderNode->parent(); + newIndex = parent->GetIndexOf(senderNode) + 1; } BookmarkNameFolderController* controller = [[BookmarkNameFolderController alloc] @@ -732,8 +819,7 @@ void RecordAppLaunch(Profile* profile, GURL url) { } - (IBAction)importBookmarks:(id)sender { - [ImportDialogController showImportSettingsDialogForProfile: - browser_->profile()]; + browser_->OpenImportSettingsDialog(); } #pragma mark Private Methods @@ -741,7 +827,7 @@ void RecordAppLaunch(Profile* profile, GURL url) { // Called after the current theme has changed. - (void)themeDidChangeNotification:(NSNotification*)aNotification { ui::ThemeProvider* themeProvider = - static_cast<ui::ThemeProvider*>([[aNotification object] pointerValue]); + static_cast<ThemeService*>([[aNotification object] pointerValue]); [self updateTheme:themeProvider]; } @@ -781,7 +867,7 @@ void RecordAppLaunch(Profile* profile, GURL url) { [[offTheSideButton_ cell] setStartingChildIndex:displayedButtonCount_]; [[offTheSideButton_ cell] setBookmarkNode:bookmarkModel_->GetBookmarkBarNode()]; - int bookmarkChildren = bookmarkModel_->GetBookmarkBarNode()->GetChildCount(); + int bookmarkChildren = bookmarkModel_->GetBookmarkBarNode()->child_count(); if (bookmarkChildren > displayedButtonCount_) { [offTheSideButton_ setHidden:NO]; } else { @@ -795,6 +881,35 @@ void RecordAppLaunch(Profile* profile, GURL url) { } } +// Main menubar observation code, so we can know to close our fake menus if the +// user clicks on the actual menubar, as multiple unconnected menus sharing +// the screen looks weird. +// Needed because the hookForEvent method doesn't see the click on the menubar. + +// Gets called when the menubar is clicked. +- (void)begunTracking:(NSNotification *)notification { + [self closeFolderAndStopTrackingMenus]; +} + +// Install the callback. +- (void)startObservingMenubar { + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + [nc addObserver:self + selector:@selector(begunTracking:) + name:NSMenuDidBeginTrackingNotification + object:[NSApp mainMenu]]; +} + +// Remove the callback. +- (void)stopObservingMenubar { + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + [nc removeObserver:self + name:NSMenuDidBeginTrackingNotification + object:[NSApp mainMenu]]; +} + +// End of menubar observation code. + // Begin (or end) watching for a click outside this window. Unlike // normal NSWindows, bookmark folder "fake menu" windows do not become // key or main. Thus, traditional notification (e.g. WillResignKey) @@ -806,11 +921,15 @@ void RecordAppLaunch(Profile* profile, GURL url) { sharedApplication]); DCHECK([app isKindOfClass:[CrApplication class]]); if (watch) { - if (!watchingForExitEvent_) + if (!watchingForExitEvent_) { [app addEventHook:self]; + [self startObservingMenubar]; + } } else { - if (watchingForExitEvent_) + if (watchingForExitEvent_) { [app removeEventHook:self]; + [self stopObservingMenubar]; + } } watchingForExitEvent_ = watch; } @@ -926,7 +1045,7 @@ void RecordAppLaunch(Profile* profile, GURL url) { if (menu == [[self view] menu]) { thingsToDo = [buttons_ count] ? YES : NO; } else { - if (node && node->is_folder() && node->GetChildCount()) { + if (node && node->is_folder() && node->child_count()) { thingsToDo = YES; } } @@ -940,18 +1059,27 @@ void RecordAppLaunch(Profile* profile, GURL url) { return NO; } + bool can_edit = [self canEditBookmarks]; if ((action == @selector(editBookmark:)) || (action == @selector(deleteBookmark:)) || (action == @selector(cutBookmark:)) || (action == @selector(copyBookmark:))) { - if (![self canEditBookmark:node]) { + if (![self canEditBookmark:node]) + return NO; + if (action != @selector(copyBookmark:) && !can_edit) return NO; - } } if (action == @selector(pasteBookmark:) && - !bookmark_utils::CanPasteFromClipboard(node)) + (!bookmark_utils::CanPasteFromClipboard(node) || !can_edit)) { + return NO; + } + + if ((!can_edit) && + ((action == @selector(addPage:)) || + (action == @selector(addFolder:)))) { return NO; + } // If this is an incognito window, don't allow "open in incognito". if ((action == @selector(openBookmarkInIncognitoWindow:)) || @@ -1006,11 +1134,11 @@ void RecordAppLaunch(Profile* profile, GURL url) { action:nil keyEquivalent:@""] autorelease]; [menu addItem:item]; - [item setImage:[self favIconForNode:child]]; + [item setImage:[self faviconForNode:child]]; if (child->is_folder()) { NSMenu* submenu = [[[NSMenu alloc] initWithTitle:title] autorelease]; [menu setSubmenu:submenu forItem:item]; - if (child->GetChildCount()) { + if (child->child_count()) { [self addFolderNode:child toMenu:submenu]; // potentially recursive } else { [self tagEmptyMenu:submenu]; @@ -1042,7 +1170,7 @@ void RecordAppLaunch(Profile* profile, GURL url) { // Add the children of the given bookmark node (and their children...) // to menu, one menu item per node. - (void)addFolderNode:(const BookmarkNode*)node toMenu:(NSMenu*)menu { - for (int i = 0; i < node->GetChildCount(); i++) { + for (int i = 0; i < node->child_count(); i++) { const BookmarkNode* child = node->GetChild(i); [self addNode:child toMenu:menu]; } @@ -1085,7 +1213,7 @@ void RecordAppLaunch(Profile* profile, GURL url) { // appropriate) the "no items" container (text which says "bookmarks // go here"). - (void)showOrHideNoItemContainerForNode:(const BookmarkNode*)node { - BOOL hideNoItemWarning = node->GetChildCount() > 0; + BOOL hideNoItemWarning = node->child_count() > 0; [[buttonView_ noItemContainer] setHidden:hideNoItemWarning]; } @@ -1097,7 +1225,7 @@ void RecordAppLaunch(Profile* profile, GURL url) { CGFloat maxViewX = NSMaxX([[self view] bounds]); int xOffset = 0; - for (int i = 0; i < node->GetChildCount(); i++) { + for (int i = 0; i < node->child_count(); i++) { const BookmarkNode* child = node->GetChild(i); BookmarkButton* button = [self buttonForNode:child xOffset:&xOffset]; if (NSMinX([button frame]) >= maxViewX) @@ -1132,7 +1260,7 @@ void RecordAppLaunch(Profile* profile, GURL url) { ui::ThemeProvider* themeProvider = [[[self view] window] themeProvider]; if (themeProvider) { NSColor* color = - themeProvider->GetNSColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT, + themeProvider->GetNSColor(ThemeService::COLOR_BOOKMARK_TEXT, true); [cell setTextColor:color]; } @@ -1395,7 +1523,7 @@ void RecordAppLaunch(Profile* profile, GURL url) { - (void)redistributeButtonsOnBarAsNeeded { const BookmarkNode* node = bookmarkModel_->GetBookmarkBarNode(); - NSInteger barCount = node->GetChildCount(); + NSInteger barCount = node->child_count(); // Determine the current maximum extent of the visible buttons. CGFloat maxViewX = NSMaxX([[self view] bounds]); @@ -1510,7 +1638,7 @@ void RecordAppLaunch(Profile* profile, GURL url) { // Return an autoreleased NSCell suitable for a bookmark button. // TODO(jrg): move much of the cell config into the BookmarkButtonCell class. - (BookmarkButtonCell*)cellForBookmarkNode:(const BookmarkNode*)node { - NSImage* image = node ? [self favIconForNode:node] : nil; + NSImage* image = node ? [self faviconForNode:node] : nil; NSMenu* menu = node && node->is_folder() ? buttonFolderContextMenu_ : buttonContextMenu_; BookmarkButtonCell* cell = [BookmarkButtonCell buttonCellForNode:node @@ -1558,12 +1686,12 @@ void RecordAppLaunch(Profile* profile, GURL url) { CGFloat delta = desiredSize - frame.size.width; if (delta) { frame.size.width = desiredSize; - [[button animator] setFrame:frame]; + [button setFrame:frame]; for (NSButton* button in buttons_.get()) { NSRect buttonFrame = [button frame]; if (buttonFrame.origin.x > frame.origin.x) { buttonFrame.origin.x += delta; - [[button animator] setFrame:buttonFrame]; + [button setFrame:buttonFrame]; } } } @@ -1616,7 +1744,7 @@ void RecordAppLaunch(Profile* profile, GURL url) { if (!themeProvider) return; NSColor* color = - themeProvider->GetNSColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT, + themeProvider->GetNSColor(ThemeService::COLOR_BOOKMARK_TEXT, true); for (BookmarkButton* button in buttons_.get()) { BookmarkButtonCell* cell = [button cell]; @@ -1655,10 +1783,23 @@ void RecordAppLaunch(Profile* profile, GURL url) { return YES; } break; - case NSKeyDown: + case NSKeyDown: { + bool result = NO; + // Event hooks often see the same keydown event twice due to the way key + // events get dispatched and redispatched, so ignore if this keydown + // event has the EXACT same timestamp as the previous keydown. + static NSTimeInterval lastKeyDownEventTime; + NSTimeInterval thisTime = [event timestamp]; + if (lastKeyDownEventTime != thisTime) { + lastKeyDownEventTime = thisTime; + if (folderController_) { + result = [folderController_ handleInputText:[event characters]]; + } + } + return result; + } case NSKeyUp: - // Any key press ends things. - return YES; + return NO; case NSLeftMouseDragged: // We can get here with the following sequence: // - open a bookmark folder @@ -1758,7 +1899,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { const BookmarkNode* afterNode = [buttonToTheRightOfDraggedButton bookmarkNode]; DCHECK(afterNode); - int index = afterNode->GetParent()->IndexOfChild(afterNode); + int index = afterNode->parent()->GetIndexOf(afterNode); // Make sure we don't get confused by buttons which aren't visible. return std::min(index, displayedButtonCount_); } @@ -1783,7 +1924,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { if ([button isFolder]) { destParent = [button bookmarkNode]; // Drop it at the end. - destIndex = [button bookmarkNode]->GetChildCount(); + destIndex = [button bookmarkNode]->child_count(); } else { // Else we're dropping somewhere on the bar, so find the right spot. destParent = bookmarkModel_->GetBookmarkBarNode(); @@ -1808,6 +1949,75 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { - (void)draggingEnded:(id<NSDraggingInfo>)info { [self closeFolderAndStopTrackingMenus]; + [[BookmarkButton draggedButton] setHidden:NO]; + [self resetAllButtonPositionsWithAnimation:YES]; +} + +// Set insertionPos_ and hasInsertionPos_, and make insertion space for a +// hypothetical drop with the new button having a left edge of |where|. +// Gets called only by our view. +- (void)setDropInsertionPos:(CGFloat)where { + BOOL animate = [self animationEnabled]; + if (!hasInsertionPos_ || where != insertionPos_) { + insertionPos_ = where; + hasInsertionPos_ = YES; + CGFloat left = bookmarks::kBookmarkHorizontalPadding; + CGFloat paddingWidth = bookmarks::kDefaultBookmarkWidth; + BookmarkButton* draggedButton = [BookmarkButton draggedButton]; + if (draggedButton) { + paddingWidth = std::min(bookmarks::kDefaultBookmarkWidth, + NSWidth([draggedButton frame])); + } + // Put all the buttons where they belong, with all buttons to the right + // of the insertion point shuffling right to make space for it. + for (NSButton* button in buttons_.get()) { + // Hidden buttons get no space. + if ([button isHidden]) + continue; + NSRect buttonFrame = [button frame]; + buttonFrame.origin.x = left; + // Update "left" for next time around. + left += buttonFrame.size.width; + if (left > insertionPos_) + buttonFrame.origin.x += paddingWidth; + left += bookmarks::kBookmarkHorizontalPadding; + if (animate) + [[button animator] setFrame:buttonFrame]; + else + [button setFrame:buttonFrame]; + } + } +} + +// Put all visible bookmark bar buttons in their normal locations, either with +// or without animation according to the |animate| flag. +// This is generally useful, so is called from various places internally. +- (void)resetAllButtonPositionsWithAnimation:(BOOL)animate { + CGFloat left = bookmarks::kBookmarkHorizontalPadding; + animate &= [self animationEnabled]; + + for (NSButton* button in buttons_.get()) { + // Hidden buttons get no space. + if ([button isHidden]) + continue; + NSRect buttonFrame = [button frame]; + buttonFrame.origin.x = left; + left += buttonFrame.size.width + bookmarks::kBookmarkHorizontalPadding; + if (animate) + [[button animator] setFrame:buttonFrame]; + else + [button setFrame:buttonFrame]; + } +} + +// Clear insertion flag, remove insertion space and put all visible bookmark +// bar buttons in their normal locations. +// Gets called only by our view. +- (void)clearDropInsertionPos { + if (hasInsertionPos_) { + hasInsertionPos_ = NO; + [self resetAllButtonPositionsWithAnimation:YES]; + } } #pragma mark Bridge Notification Handlers @@ -1837,6 +2047,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { [self addButtonsToView]; [self configureOffTheSideButtonContentsAndVisibility]; [self setNodeForBarMenu]; + [self reconfigureBookmarkBar]; } - (void)beingDeleted:(BookmarkModel*)model { @@ -1913,19 +2124,22 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { // this looks bad I may need to change widthForBookmarkButtonCell to // add space for an image even if not there on the assumption that // favicons will eventually load. -- (void)nodeFavIconLoaded:(BookmarkModel*)model +- (void)nodeFaviconLoaded:(BookmarkModel*)model node:(const BookmarkNode*)node { for (BookmarkButton* button in buttons_.get()) { const BookmarkNode* cellnode = [button bookmarkNode]; if (cellnode == node) { [[button cell] setBookmarkCellText:[button title] - image:[self favIconForNode:node]]; + image:[self faviconForNode:node]]; // Adding an image means we might need more room for the // bookmark. Test for it by growing the button (if needed) // and shifting everything else over. [self checkForBookmarkButtonGrowth:button]; } } + + if (folderController_) + [folderController_ faviconLoadedForNode:node]; } // TODO(jrg): for now this is brute force. @@ -2003,7 +2217,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { } - (ui::ThemeProvider*)themeProvider { - return browser_->profile()->GetThemeProvider(); + return ThemeServiceFactory::GetForProfile(browser_->profile()); } #pragma mark BookmarkButtonDelegate Protocol @@ -2055,22 +2269,26 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { } - (BOOL)canDragBookmarkButtonToTrash:(BookmarkButton*)button { - return [self canEditBookmark:[button bookmarkNode]]; + return [self canEditBookmarks] && + [self canEditBookmark:[button bookmarkNode]]; } - (void)didDragBookmarkToTrash:(BookmarkButton*)button { - // TODO(mrossetti): Refactor BookmarkBarFolder common code. - // http://crbug.com/35966 - const BookmarkNode* node = [button bookmarkNode]; - if (node) { - const BookmarkNode* parent = node->GetParent(); - bookmarkModel_->Remove(parent, - parent->IndexOfChild(node)); + if ([self canDragBookmarkButtonToTrash:button]) { + const BookmarkNode* node = [button bookmarkNode]; + if (node) { + const BookmarkNode* parent = node->parent(); + bookmarkModel_->Remove(parent, + parent->GetIndexOf(node)); + } } } -- (void)bookmarkDragDidEnd:(BookmarkButton*)button { +- (void)bookmarkDragDidEnd:(BookmarkButton*)button + operation:(NSDragOperation)operation { [self closeFolderAndStopTrackingMenus]; + [button setHidden:NO]; + [self resetAllButtonPositionsWithAnimation:YES]; } @@ -2093,6 +2311,10 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { return bookmarkModel_; } +- (BOOL)draggingAllowed:(id<NSDraggingInfo>)info { + return [self canEditBookmarks]; +} + // TODO(jrg): much of this logic is duped with // [BookmarkBarFolderController draggingEntered:] except when noted. // http://crbug.com/35966 @@ -2136,7 +2358,8 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { [[hoverButton_ target] performSelector:@selector(openBookmarkFolderFromButton:) withObject:hoverButton_ - afterDelay:bookmarks::kDragHoverOpenDelay]; + afterDelay:bookmarks::kDragHoverOpenDelay + inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; } if (!button) { if (hoverButton_) { @@ -2212,13 +2435,16 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { int numButtons = displayedButtonCount_; // If it's a drop strictly between existing buttons ... - if (destIndex >= 0 && destIndex < numButtons) { + + if (destIndex == 0) { + x = 0.5 * bookmarks::kBookmarkHorizontalPadding; + } else if (destIndex > 0 && destIndex < numButtons) { // ... put the indicator right between the buttons. BookmarkButton* button = - [buttons_ objectAtIndex:static_cast<NSUInteger>(destIndex)]; + [buttons_ objectAtIndex:static_cast<NSUInteger>(destIndex-1)]; DCHECK(button); NSRect buttonFrame = [button frame]; - x = buttonFrame.origin.x - 0.5 * bookmarks::kBookmarkHorizontalPadding; + x = NSMaxX(buttonFrame) + 0.5 * bookmarks::kBookmarkHorizontalPadding; // If it's a drop at the end (past the last button, if there are any) ... } else if (destIndex == numButtons) { @@ -2321,19 +2547,10 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { bookmarks::kBookmarkHorizontalPadding; } BookmarkButton* newButton = [self buttonForNode:node xOffset:&newOffset]; - CGFloat xOffset = - NSWidth([newButton frame]) + bookmarks::kBookmarkHorizontalPadding; - NSUInteger buttonCount = [buttons_ count]; - for (NSUInteger i = buttonIndex; i < buttonCount; ++i) { - BookmarkButton* button = [buttons_ objectAtIndex:i]; - NSPoint buttonOrigin = [button frame].origin; - buttonOrigin.x += xOffset; - [[button animator] setFrameOrigin:buttonOrigin]; - } ++displayedButtonCount_; [buttons_ insertObject:newButton atIndex:buttonIndex]; [buttonView_ addSubview:newButton]; - + [self resetAllButtonPositionsWithAnimation:NO]; // See if any buttons need to be pushed off to or brought in from the side. [self reconfigureBookmarkBar]; } else { @@ -2356,7 +2573,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { if ([button isFolder]) { destParent = [button bookmarkNode]; // Drop it at the end. - destIndex = [button bookmarkNode]->GetChildCount(); + destIndex = [button bookmarkNode]->child_count(); } else { // Else we're dropping somewhere on the bar, so find the right spot. destParent = bookmarkModel_->GetBookmarkBarNode(); @@ -2387,7 +2604,6 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { return nodesWereAdded; } -// TODO(mrossetti): jrg wants this broken up into smaller functions. - (void)moveButtonFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex { if (fromIndex != toIndex) { NSInteger buttonCount = (NSInteger)[buttons_ count]; @@ -2397,38 +2613,10 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { // both button indexes are in the visible space. if (fromIndex < buttonCount && toIndex < buttonCount) { BookmarkButton* movedButton = [buttons_ objectAtIndex:fromIndex]; - NSRect movedFrame = [movedButton frame]; - NSPoint toOrigin = movedFrame.origin; - CGFloat xOffset = - NSWidth(movedFrame) + bookmarks::kBookmarkHorizontalPadding; - // Hide the button to reduce flickering while drawing the window. - [movedButton setHidden:YES]; [buttons_ removeObjectAtIndex:fromIndex]; - if (fromIndex < toIndex) { - // Move the button from left to right within the bar. - BookmarkButton* targetButton = [buttons_ objectAtIndex:toIndex - 1]; - NSRect toFrame = [targetButton frame]; - toOrigin.x = toFrame.origin.x - NSWidth(movedFrame) + NSWidth(toFrame); - for (NSInteger i = fromIndex; i < toIndex; ++i) { - BookmarkButton* button = [buttons_ objectAtIndex:i]; - NSRect frame = [button frame]; - frame.origin.x -= xOffset; - [[button animator] setFrameOrigin:frame.origin]; - } - } else { - // Move the button from right to left within the bar. - BookmarkButton* targetButton = [buttons_ objectAtIndex:toIndex]; - toOrigin = [targetButton frame].origin; - for (NSInteger i = fromIndex - 1; i >= toIndex; --i) { - BookmarkButton* button = [buttons_ objectAtIndex:i]; - NSRect buttonFrame = [button frame]; - buttonFrame.origin.x += xOffset; - [[button animator] setFrameOrigin:buttonFrame.origin]; - } - } [buttons_ insertObject:movedButton atIndex:toIndex]; - [movedButton setFrameOrigin:toOrigin]; [movedButton setHidden:NO]; + [self resetAllButtonPositionsWithAnimation:NO]; } else if (fromIndex < buttonCount) { // A button is being removed from the bar and added to off-the-side. // By now the node has already been inserted into the model so the @@ -2465,25 +2653,14 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { [self closeAllBookmarkFolders]; } NSPoint poofPoint = [oldButton screenLocationForRemoveAnimation]; - NSRect oldFrame = [oldButton frame]; [oldButton setDelegate:nil]; [oldButton removeFromSuperview]; if (animate && !ignoreAnimations_ && [self isVisible]) NSShowAnimationEffect(NSAnimationEffectDisappearingItemDefault, poofPoint, NSZeroSize, nil, nil, nil); - CGFloat xOffset = NSWidth(oldFrame) + bookmarks::kBookmarkHorizontalPadding; [buttons_ removeObjectAtIndex:buttonIndex]; - NSUInteger buttonCount = [buttons_ count]; - for (NSUInteger i = buttonIndex; i < buttonCount; ++i) { - BookmarkButton* button = [buttons_ objectAtIndex:i]; - NSRect buttonFrame = [button frame]; - buttonFrame.origin.x -= xOffset; - [[button animator] setFrame:buttonFrame]; - // If this button is showing its menu then we need to move the menu, too. - if (button == [folderController_ parentButton]) - [folderController_ offsetFolderMenuWindow:NSMakeSize(xOffset, 0.0)]; - } --displayedButtonCount_; + [self resetAllButtonPositionsWithAnimation:YES]; [self reconfigureBookmarkBar]; } else if (folderController_ && [folderController_ parentButton] == offTheSideButton_) { diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm index a2655d6..f0b4bce 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -6,7 +6,7 @@ #include "base/basictypes.h" #include "base/command_line.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/string16.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" @@ -32,8 +32,18 @@ #import "third_party/ocmock/OCMock/OCMock.h" #include "ui/base/theme_provider.h" +// Unit tests don't need time-consuming asynchronous animations. +@interface BookmarkBarControllerTestable : BookmarkBarController { +} +@end +@implementation BookmarkBarControllerTestable +- (BOOL)animationEnabled { + return NO; +} +@end + // Just like a BookmarkBarController but openURL: is stubbed out. -@interface BookmarkBarControllerNoOpen : BookmarkBarController { +@interface BookmarkBarControllerNoOpen : BookmarkBarControllerTestable { @public std::vector<GURL> urls_; std::vector<WindowOpenDisposition> dispositions_; @@ -136,7 +146,7 @@ // Just like a BookmarkBarController but intercedes when providing // pasteboard drag data. -@interface BookmarkBarControllerDragData : BookmarkBarController { +@interface BookmarkBarControllerDragData : BookmarkBarControllerTestable { const BookmarkNode* dragDataNode_; // Weak } - (void)setDragDataNode:(const BookmarkNode*)node; @@ -261,7 +271,7 @@ class BookmarkBarControllerTestBase : public CocoaTest { BookmarkBarControllerTestBase() { FilePath extension_dir; helper_.profile()->CreateExtensionService(CommandLine::ForCurrentProcess(), - extension_dir); + extension_dir, false); resizeDelegate_.reset([[ViewResizerPong alloc] init]); NSRect parent_frame = NSMakeRect(0, 0, 800, 50); parent_view_.reset([[NSView alloc] initWithFrame:parent_frame]); @@ -323,7 +333,7 @@ class BookmarkBarControllerTest : public BookmarkBarControllerTestBase { NSMenuItem* ItemForBookmarkBarMenu(GURL& gurl) { BookmarkModel* model = helper_.profile()->GetBookmarkModel(); const BookmarkNode* parent = model->GetBookmarkBarNode(); - const BookmarkNode* node = model->AddURL(parent, parent->GetChildCount(), + const BookmarkNode* node = model->AddURL(parent, parent->child_count(), ASCIIToUTF16("A title"), gurl); [menu_ setRepresentedObject:[NSNumber numberWithLongLong:node->id()]]; return menu_item_; @@ -519,16 +529,16 @@ TEST_F(BookmarkBarControllerTest, NoItemContainerGoesAway) { DCHECK(noItemContainer); EXPECT_FALSE([noItemContainer isHidden]); - const BookmarkNode* node = model->AddURL(bar, bar->GetChildCount(), + const BookmarkNode* node = model->AddURL(bar, bar->child_count(), ASCIIToUTF16("title"), GURL("http://www.google.com")); EXPECT_TRUE([noItemContainer isHidden]); - model->Remove(bar, bar->IndexOfChild(node)); + model->Remove(bar, bar->GetIndexOf(node)); EXPECT_FALSE([noItemContainer isHidden]); // Now try it using a bookmark from the Other Bookmarks. const BookmarkNode* otherBookmarks = model->other_node(); - node = model->AddURL(otherBookmarks, otherBookmarks->GetChildCount(), + node = model->AddURL(otherBookmarks, otherBookmarks->child_count(), ASCIIToUTF16("TheOther"), GURL("http://www.other.com")); EXPECT_FALSE([noItemContainer isHidden]); @@ -556,7 +566,7 @@ TEST_F(BookmarkBarControllerTest, OffTheSideButtonHidden) { const BookmarkNode* parent = model->GetBookmarkBarNode(); for (int i = 0; i < 20; i++) { - model->AddURL(parent, parent->GetChildCount(), + model->AddURL(parent, parent->child_count(), ASCIIToUTF16("super duper wide title"), GURL("http://superfriends.hall-of-justice.edu")); } @@ -572,12 +582,12 @@ TEST_F(BookmarkBarControllerTest, OffTheSideButtonHidden) { BookmarkBarFolderController* bbfc = [bar_ folderController]; EXPECT_TRUE(bbfc); [bbfc setIgnoreAnimations:YES]; - while (parent->GetChildCount()) { + while (parent->child_count()) { // We've completed the job so we're done. if ([bar_ offTheSideButtonIsHidden]) break; // Delete the last button. - model->Remove(parent, parent->GetChildCount()-1); + model->Remove(parent, parent->child_count()-1); // If last one make sure the menu is closed and the button is hidden. // Else make sure menu stays open. if ([bar_ offTheSideButtonIsHidden]) { @@ -601,7 +611,7 @@ TEST_F(BookmarkBarControllerTest, DeleteFromOffTheSideWhileItIsOpen) { for (int i = 0; i < 100; i++) { std::ostringstream title; title << "super duper wide title " << i; - model->AddURL(parent, parent->GetChildCount(), ASCIIToUTF16(title.str()), + model->AddURL(parent, parent->child_count(), ASCIIToUTF16(title.str()), GURL("http://superfriends.hall-of-justice.edu")); } EXPECT_FALSE([bar_ offTheSideButtonIsHidden]); @@ -616,9 +626,9 @@ TEST_F(BookmarkBarControllerTest, DeleteFromOffTheSideWhileItIsOpen) { // Start deleting items; try and delete randomish ones in case it // makes a difference. int indices[] = { 2, 4, 5, 1, 7, 9, 2, 0, 10, 9 }; - while (parent->GetChildCount()) { + while (parent->child_count()) { for (unsigned int i = 0; i < arraysize(indices); i++) { - if (indices[i] < parent->GetChildCount()) { + if (indices[i] < parent->child_count()) { // First we mouse-enter the button to make things harder. NSArray* buttons = [bbfc buttons]; for (BookmarkButton* button in buttons) { @@ -709,17 +719,17 @@ TEST_F(BookmarkBarControllerTest, MenuForFolderNode) { // Test with an actual folder as well const BookmarkNode* parent = model->GetBookmarkBarNode(); - const BookmarkNode* folder = model->AddGroup(parent, - parent->GetChildCount(), - ASCIIToUTF16("group")); - model->AddURL(folder, folder->GetChildCount(), + const BookmarkNode* folder = model->AddFolder(parent, + parent->child_count(), + ASCIIToUTF16("folder")); + model->AddURL(folder, folder->child_count(), ASCIIToUTF16("f1"), GURL("http://framma-lamma.com")); - model->AddURL(folder, folder->GetChildCount(), + model->AddURL(folder, folder->child_count(), ASCIIToUTF16("f2"), GURL("http://framma-lamma-ding-dong.com")); menu = [bar_ menuForFolderNode:model->GetBookmarkBarNode()]; EXPECT_EQ([menu numberOfItems], 3); - item = [menu itemWithTitle:@"group"]; + item = [menu itemWithTitle:@"folder"]; EXPECT_TRUE(item); EXPECT_TRUE([item hasSubmenu]); NSMenu *submenu = [item submenu]; @@ -823,7 +833,7 @@ TEST_F(BookmarkBarControllerTest, TestButtonLimits) { EXPECT_EQ(0U, [[bar_ buttons] count]); // Add one; make sure we see it. const BookmarkNode* parent = model->GetBookmarkBarNode(); - model->AddURL(parent, parent->GetChildCount(), + model->AddURL(parent, parent->child_count(), ASCIIToUTF16("title"), GURL("http://www.google.com")); EXPECT_EQ(1U, [[bar_ buttons] count]); @@ -832,7 +842,7 @@ TEST_F(BookmarkBarControllerTest, TestButtonLimits) { model->Remove(parent, 0); EXPECT_EQ(0U, [[bar_ buttons] count]); for (int i=0; i<30; i++) { - model->AddURL(parent, parent->GetChildCount(), + model->AddURL(parent, parent->child_count(), ASCIIToUTF16("title"), GURL("http://www.google.com")); } int count = [[bar_ buttons] count]; @@ -913,21 +923,21 @@ TEST_F(BookmarkBarControllerTest, DeleteBookmark) { "http://www.foo-bar-baz.com/" }; const BookmarkNode* parent = model->GetBookmarkBarNode(); for (unsigned int i = 0; i < arraysize(urls); i++) { - model->AddURL(parent, parent->GetChildCount(), + model->AddURL(parent, parent->child_count(), ASCIIToUTF16("title"), GURL(urls[i])); } - EXPECT_EQ(3, parent->GetChildCount()); + EXPECT_EQ(3, parent->child_count()); const BookmarkNode* middle_node = parent->GetChild(1); NSMenuItem* item = ItemForBookmarkBarMenu(middle_node); [bar_ deleteBookmark:item]; - EXPECT_EQ(2, parent->GetChildCount()); + EXPECT_EQ(2, parent->child_count()); EXPECT_EQ(parent->GetChild(0)->GetURL(), GURL(urls[0])); // node 2 moved into spot 1 EXPECT_EQ(parent->GetChild(1)->GetURL(), GURL(urls[2])); } -// TODO(jrg): write a test to confirm that nodeFavIconLoaded calls +// TODO(jrg): write a test to confirm that nodeFaviconLoaded calls // checkForBookmarkButtonGrowth:. TEST_F(BookmarkBarControllerTest, Cell) { @@ -935,7 +945,7 @@ TEST_F(BookmarkBarControllerTest, Cell) { [bar_ loaded:model]; const BookmarkNode* parent = model->GetBookmarkBarNode(); - model->AddURL(parent, parent->GetChildCount(), + model->AddURL(parent, parent->child_count(), ASCIIToUTF16("supertitle"), GURL("http://superfriends.hall-of-justice.edu")); const BookmarkNode* node = parent->GetChild(0); @@ -985,7 +995,7 @@ TEST_F(BookmarkBarControllerTest, HidesHelpMessageWithBookmark) { BookmarkModel* model = helper_.profile()->GetBookmarkModel(); const BookmarkNode* parent = model->GetBookmarkBarNode(); - model->AddURL(parent, parent->GetChildCount(), + model->AddURL(parent, parent->child_count(), ASCIIToUTF16("title"), GURL("http://one.com")); [bar_ loaded:model]; @@ -996,7 +1006,7 @@ TEST_F(BookmarkBarControllerTest, BookmarkButtonSizing) { BookmarkModel* model = helper_.profile()->GetBookmarkModel(); const BookmarkNode* parent = model->GetBookmarkBarNode(); - model->AddURL(parent, parent->GetChildCount(), + model->AddURL(parent, parent->child_count(), ASCIIToUTF16("title"), GURL("http://one.com")); [bar_ loaded:model]; @@ -1037,8 +1047,8 @@ TEST_F(BookmarkBarControllerTest, DropBookmarks) { BookmarkModel* model = helper_.profile()->GetBookmarkModel(); const BookmarkNode* parent = model->GetBookmarkBarNode(); [bar_ addURLs:nsurls withTitles:nstitles at:NSZeroPoint]; - EXPECT_EQ(4, parent->GetChildCount()); - for (int i = 0; i < parent->GetChildCount(); ++i) { + EXPECT_EQ(4, parent->child_count()); + for (int i = 0; i < parent->child_count(); ++i) { GURL gurl = parent->GetChild(i)->GetURL(); if (gurl.scheme() == "http" || gurl.scheme() == "javascript") { @@ -1086,9 +1096,9 @@ TEST_F(BookmarkBarControllerTest, TestButtonOrBar) { TEST_F(BookmarkBarControllerTest, TestMenuNodeAndDisable) { BookmarkModel* model = helper_.profile()->GetBookmarkModel(); const BookmarkNode* parent = model->GetBookmarkBarNode(); - const BookmarkNode* folder = model->AddGroup(parent, - parent->GetChildCount(), - ASCIIToUTF16("group")); + const BookmarkNode* folder = model->AddFolder(parent, + parent->child_count(), + ASCIIToUTF16("folder")); NSButton* button = [[bar_ buttons] objectAtIndex:0]; EXPECT_TRUE(button); @@ -1104,7 +1114,7 @@ TEST_F(BookmarkBarControllerTest, TestMenuNodeAndDisable) { EXPECT_FALSE([bar_ validateUserInterfaceItem:item]); // Now add a child and make sure the item would be enabled. - model->AddURL(folder, folder->GetChildCount(), + model->AddURL(folder, folder->child_count(), ASCIIToUTF16("super duper wide title"), GURL("http://superfriends.hall-of-justice.edu")); EXPECT_TRUE([bar_ validateUserInterfaceItem:item]); @@ -1162,14 +1172,14 @@ TEST_F(BookmarkBarControllerTest, TestDragButton) { EXPECT_EQ(arraysize(titles), [[bar_ buttons] count]); // A drop on a folder button. - const BookmarkNode* folder = model->AddGroup(model->GetBookmarkBarNode(), - 0, - ASCIIToUTF16("awesome group")); + const BookmarkNode* folder = model->AddFolder(model->GetBookmarkBarNode(), + 0, + ASCIIToUTF16("awesome folder")); DCHECK(folder); model->AddURL(folder, 0, ASCIIToUTF16("already"), GURL("http://www.google.com")); EXPECT_EQ(arraysize(titles) + 1, [[bar_ buttons] count]); - EXPECT_EQ(1, folder->GetChildCount()); + EXPECT_EQ(1, folder->child_count()); x = NSMidX([[[bar_ buttons] objectAtIndex:0] frame]); x += [[bar_ view] frame].origin.x; string16 title = [[[bar_ buttons] objectAtIndex:2] bookmarkNode]->GetTitle(); @@ -1179,7 +1189,7 @@ TEST_F(BookmarkBarControllerTest, TestDragButton) { // Gone from the bar EXPECT_EQ(arraysize(titles), [[bar_ buttons] count]); // In the folder - EXPECT_EQ(2, folder->GetChildCount()); + EXPECT_EQ(2, folder->child_count()); // At the end EXPECT_EQ(title, folder->GetChild(1)->GetTitle()); } @@ -1278,13 +1288,13 @@ TEST_F(BookmarkBarControllerTest, TestFolders) { // Create some folder buttons. const BookmarkNode* parent = model->GetBookmarkBarNode(); - const BookmarkNode* folder = model->AddGroup(parent, - parent->GetChildCount(), - ASCIIToUTF16("group")); - model->AddURL(folder, folder->GetChildCount(), + const BookmarkNode* folder = model->AddFolder(parent, + parent->child_count(), + ASCIIToUTF16("folder")); + model->AddURL(folder, folder->child_count(), ASCIIToUTF16("f1"), GURL("http://framma-lamma.com")); - folder = model->AddGroup(parent, parent->GetChildCount(), - ASCIIToUTF16("empty")); + folder = model->AddFolder(parent, parent->child_count(), + ASCIIToUTF16("empty")); EXPECT_EQ([[bar_ buttons] count], 2U); @@ -1329,7 +1339,7 @@ TEST_F(BookmarkBarControllerTest, TestFolderButtons) { // Add a real bookmark so we can click on it. const BookmarkNode* folder = root->GetChild(3); - model.AddURL(folder, folder->GetChildCount(), ASCIIToUTF16("CLICK ME"), + model.AddURL(folder, folder->child_count(), ASCIIToUTF16("CLICK ME"), GURL("http://www.google.com/")); // Click on a folder button. @@ -1371,14 +1381,6 @@ TEST_F(BookmarkBarControllerTest, TestFolderButtons) { BookmarkBarFolderController* newBBFC = [bar_ folderController]; EXPECT_TRUE(newBBFC); EXPECT_NE(oldBBFC, newBBFC); - - // A click on a real bookmark should close and stop tracking the folder menus. - BookmarkButton* bookmarkButton = [newBBFC buttonWithTitleEqualTo:@"CLICK ME"]; - EXPECT_TRUE(bookmarkButton); - [newBBFC openBookmark:bookmarkButton]; - EXPECT_FALSE([bar_ folderController]); - [bar_ mouseEnteredButton:button event:event]; - EXPECT_FALSE([bar_ folderController]); } // Make sure the "off the side" folder looks like a bookmark folder @@ -1392,14 +1394,14 @@ TEST_F(BookmarkBarControllerTest, OffTheSideFolder) { BookmarkModel* model = helper_.profile()->GetBookmarkModel(); const BookmarkNode* parent = model->GetBookmarkBarNode(); for (int x = 0; x < 30; x++) { - model->AddURL(parent, parent->GetChildCount(), + model->AddURL(parent, parent->child_count(), ASCIIToUTF16("medium-size-title"), GURL("http://framma-lamma.com")); } // Add a couple more so we can delete one and make sure its button goes away. - model->AddURL(parent, parent->GetChildCount(), + model->AddURL(parent, parent->child_count(), ASCIIToUTF16("DELETE_ME"), GURL("http://ashton-tate.com")); - model->AddURL(parent, parent->GetChildCount(), + model->AddURL(parent, parent->child_count(), ASCIIToUTF16("medium-size-title"), GURL("http://framma-lamma.com")); @@ -1429,7 +1431,7 @@ TEST_F(BookmarkBarControllerTest, OffTheSideFolder) { // Delete a bookmark in the off-the-side and verify it's gone. BookmarkButton* button = [bbfc buttonWithTitleEqualTo:@"DELETE_ME"]; EXPECT_TRUE(button); - model->Remove(parent, parent->GetChildCount() - 2); + model->Remove(parent, parent->child_count() - 2); button = [bbfc buttonWithTitleEqualTo:@"DELETE_ME"]; EXPECT_FALSE(button); } @@ -1461,7 +1463,7 @@ TEST_F(BookmarkBarControllerTest, EventToExitCheck) { charactersIgnoringModifiers:@"x" isARepeat:NO keyCode:87]; - EXPECT_TRUE([bar_ isEventAnExitEvent:event]); + EXPECT_FALSE([bar_ isEventAnExitEvent:event]); [[[bar_ view] window] removeChildWindow:folderWindow]; } @@ -1470,8 +1472,8 @@ TEST_F(BookmarkBarControllerTest, DropDestination) { // Make some buttons. BookmarkModel* model = helper_.profile()->GetBookmarkModel(); const BookmarkNode* parent = model->GetBookmarkBarNode(); - model->AddGroup(parent, parent->GetChildCount(), ASCIIToUTF16("group 1")); - model->AddGroup(parent, parent->GetChildCount(), ASCIIToUTF16("group 2")); + model->AddFolder(parent, parent->child_count(), ASCIIToUTF16("folder 1")); + model->AddFolder(parent, parent->child_count(), ASCIIToUTF16("folder 2")); EXPECT_EQ([[bar_ buttons] count], 2U); // Confirm "off to left" and "off to right" match nothing. @@ -1511,7 +1513,7 @@ TEST_F(BookmarkBarControllerTest, NodeDeletedWhileMenuIsOpen) { const BookmarkNode* parent = model->GetBookmarkBarNode(); const BookmarkNode* initialNode = model->AddURL( - parent, parent->GetChildCount(), + parent, parent->child_count(), ASCIIToUTF16("initial"), GURL("http://www.google.com")); @@ -1526,7 +1528,7 @@ TEST_F(BookmarkBarControllerTest, NodeDeletedWhileMenuIsOpen) { // Now delete the node and make sure things are happy (no crash, // NULL node caught). - model->Remove(parent, parent->IndexOfChild(initialNode)); + model->Remove(parent, parent->GetIndexOf(initialNode)); EXPECT_EQ(nil, [bar_ nodeFromMenuItem:item]); // Should not crash by referencing a deleted node. [bar_ openBookmarkInNewWindow:item]; @@ -1549,10 +1551,10 @@ TEST_F(BookmarkBarControllerTest, NodeDeletedWhileContextMenuIsOpen) { [bar_ loaded:model]; const BookmarkNode* parent = model->GetBookmarkBarNode(); - const BookmarkNode* folder = model->AddGroup(parent, - parent->GetChildCount(), - ASCIIToUTF16("group")); - const BookmarkNode* framma = model->AddURL(folder, folder->GetChildCount(), + const BookmarkNode* folder = model->AddFolder(parent, + parent->child_count(), + ASCIIToUTF16("folder")); + const BookmarkNode* framma = model->AddURL(folder, folder->child_count(), ASCIIToUTF16("f1"), GURL("http://framma-lamma.com")); @@ -1563,7 +1565,7 @@ TEST_F(BookmarkBarControllerTest, NodeDeletedWhileContextMenuIsOpen) { [bar_ setButtonContextMenu:fakeMenu]; // Force a delete which should cancelTracking on the menu. - model->Remove(framma->GetParent(), framma->GetParent()->IndexOfChild(framma)); + model->Remove(framma->parent(), framma->parent()->GetIndexOf(framma)); // Restore, then confirm cancelTracking was called. [bar_ setButtonContextMenu:origMenu]; @@ -1573,14 +1575,14 @@ TEST_F(BookmarkBarControllerTest, NodeDeletedWhileContextMenuIsOpen) { TEST_F(BookmarkBarControllerTest, CloseFolderOnAnimate) { BookmarkModel* model = helper_.profile()->GetBookmarkModel(); const BookmarkNode* parent = model->GetBookmarkBarNode(); - const BookmarkNode* folder = model->AddGroup(parent, - parent->GetChildCount(), - ASCIIToUTF16("group")); - model->AddGroup(parent, parent->GetChildCount(), - ASCIIToUTF16("sibbling group")); - model->AddURL(folder, folder->GetChildCount(), ASCIIToUTF16("title a"), + const BookmarkNode* folder = model->AddFolder(parent, + parent->child_count(), + ASCIIToUTF16("folder")); + model->AddFolder(parent, parent->child_count(), + ASCIIToUTF16("sibbling folder")); + model->AddURL(folder, folder->child_count(), ASCIIToUTF16("title a"), GURL("http://www.google.com/a")); - model->AddURL(folder, folder->GetChildCount(), + model->AddURL(folder, folder->child_count(), ASCIIToUTF16("title super duper long long whoa momma title you betcha"), GURL("http://www.google.com/b")); BookmarkButton* button = [[bar_ buttons] objectAtIndex:0]; @@ -1697,15 +1699,15 @@ public: BookmarkModel* model = helper_.profile()->GetBookmarkModel(); parent_ = model->GetBookmarkBarNode(); // { one, { two-one, two-two }, three } - model->AddURL(parent_, parent_->GetChildCount(), ASCIIToUTF16("title"), + model->AddURL(parent_, parent_->child_count(), ASCIIToUTF16("title"), GURL("http://one.com")); - folder_ = model->AddGroup(parent_, parent_->GetChildCount(), - ASCIIToUTF16("group")); - model->AddURL(folder_, folder_->GetChildCount(), + folder_ = model->AddFolder(parent_, parent_->child_count(), + ASCIIToUTF16("folder")); + model->AddURL(folder_, folder_->child_count(), ASCIIToUTF16("title"), GURL("http://two-one.com")); - model->AddURL(folder_, folder_->GetChildCount(), + model->AddURL(folder_, folder_->child_count(), ASCIIToUTF16("title"), GURL("http://two-two.com")); - model->AddURL(parent_, parent_->GetChildCount(), + model->AddURL(parent_, parent_->child_count(), ASCIIToUTF16("title"), GURL("https://three.com")); } const BookmarkNode* parent_; // Weak @@ -1875,7 +1877,7 @@ TEST_F(BookmarkBarControllerDragDropTest, DragMoveBarBookmarkToOffTheSide) { // Remember how many buttons are showing and are available. int oldDisplayedButtons = [bar_ displayedButtonCount]; - int oldChildCount = root->GetChildCount(); + int oldChildCount = root->child_count(); // Pop up the off-the-side menu. BookmarkButton* otsButton = (BookmarkButton*)[bar_ offTheSideButton]; @@ -1899,7 +1901,7 @@ TEST_F(BookmarkBarControllerDragDropTest, DragMoveBarBookmarkToOffTheSide) { // There should still be the same number of buttons in the bar // and off-the-side should have one more. int newDisplayedButtons = [bar_ displayedButtonCount]; - int newChildCount = root->GetChildCount(); + int newChildCount = root->child_count(); int newOTSCount = (int)[[otsController buttons] count]; EXPECT_EQ(oldDisplayedButtons, newDisplayedButtons); EXPECT_EQ(oldChildCount + 1, newChildCount); @@ -1933,8 +1935,8 @@ TEST_F(BookmarkBarControllerDragDropTest, DragOffTheSideToOther) { // Remember how many buttons are showing and are available. int oldDisplayedButtons = [bar_ displayedButtonCount]; - int oldRootCount = root->GetChildCount(); - int oldOtherCount = other->GetChildCount(); + int oldRootCount = root->child_count(); + int oldOtherCount = other->child_count(); // Pop up the off-the-side menu. BookmarkButton* otsButton = (BookmarkButton*)[bar_ offTheSideButton]; @@ -1956,9 +1958,9 @@ TEST_F(BookmarkBarControllerDragDropTest, DragOffTheSideToOther) { // There should one less button in the bar, one less in off-the-side, // and one more in other bookmarks. - int newRootCount = root->GetChildCount(); + int newRootCount = root->child_count(); int newOTSCount = (int)[[otsController buttons] count]; - int newOtherCount = other->GetChildCount(); + int newOtherCount = other->child_count(); EXPECT_EQ(oldRootCount - 1, newRootCount); EXPECT_EQ(oldOTSCount - 1, newOTSCount); EXPECT_EQ(oldOtherCount + 1, newOtherCount); @@ -1982,7 +1984,7 @@ TEST_F(BookmarkBarControllerDragDropTest, DragBookmarkData) { EXPECT_EQ(other_string, actual); // Remember the little ones. - int oldChildCount = root->GetChildCount(); + int oldChildCount = root->child_count(); BookmarkButton* targetButton = [bar_ buttonWithTitleEqualTo:@"3b"]; ASSERT_TRUE(targetButton); @@ -1995,7 +1997,7 @@ TEST_F(BookmarkBarControllerDragDropTest, DragBookmarkData) { [bar_ dragBookmarkData:(id<NSDraggingInfo>)dragInfo.get()]; // There should one more button in the bar. - int newChildCount = root->GetChildCount(); + int newChildCount = root->child_count(); EXPECT_EQ(oldChildCount + 1, newChildCount); // Verify the model. const std::string expected("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] " @@ -2014,7 +2016,7 @@ TEST_F(BookmarkBarControllerDragDropTest, DragBookmarkData) { [dragInfo setDropLocation:targetPoint]; [bar_ dragBookmarkData:(id<NSDraggingInfo>)dragInfo.get()]; - newChildCount = root->GetChildCount(); + newChildCount = root->child_count(); EXPECT_EQ(oldChildCount, newChildCount); // Verify the model. const std::string expected1("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] " @@ -2036,7 +2038,7 @@ TEST_F(BookmarkBarControllerDragDropTest, AddURLs) { EXPECT_EQ(model_string, actual); // Remember the children. - int oldChildCount = root->GetChildCount(); + int oldChildCount = root->child_count(); BookmarkButton* targetButton = [bar_ buttonWithTitleEqualTo:@"3b"]; ASSERT_TRUE(targetButton); @@ -2047,7 +2049,7 @@ TEST_F(BookmarkBarControllerDragDropTest, AddURLs) { [bar_ addURLs:urls withTitles:titles at:[targetButton center]]; // There should two more nodes in the bar. - int newChildCount = root->GetChildCount(); + int newChildCount = root->child_count(); EXPECT_EQ(oldChildCount + 2, newChildCount); // Verify the model. const std::string expected("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] " @@ -2108,7 +2110,7 @@ TEST_F(BookmarkBarControllerDragDropTest, PulseButton) { BookmarkModel* model = helper_.profile()->GetBookmarkModel(); const BookmarkNode* root = model->GetBookmarkBarNode(); GURL gurl("http://www.google.com"); - const BookmarkNode* node = model->AddURL(root, root->GetChildCount(), + const BookmarkNode* node = model->AddURL(root, root->child_count(), ASCIIToUTF16("title"), gurl); BookmarkButton* button = [[bar_ buttons] objectAtIndex:0]; @@ -2150,7 +2152,7 @@ TEST_F(BookmarkBarControllerDragDropTest, DragBookmarkDataToTrash) { std::string actual = model_test_utils::ModelStringFromNode(root); EXPECT_EQ(model_string, actual); - int oldChildCount = root->GetChildCount(); + int oldChildCount = root->child_count(); // Drag a button to the trash. BookmarkButton* buttonToDelete = [bar_ buttonWithTitleEqualTo:@"3b"]; @@ -2159,7 +2161,7 @@ TEST_F(BookmarkBarControllerDragDropTest, DragBookmarkDataToTrash) { [bar_ didDragBookmarkToTrash:buttonToDelete]; // There should be one less button in the bar. - int newChildCount = root->GetChildCount(); + int newChildCount = root->child_count(); EXPECT_EQ(oldChildCount - 1, newChildCount); // Verify the model. const std::string expected("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] " diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.h index f599e0a..f768e27 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -20,7 +20,7 @@ class BookmarkNode; } // Create a button cell which draws without a theme and with a frame -// color provided by the BrowserThemeProvider defaults. +// color provided by the ThemeService defaults. + (id)buttonCellForNode:(const BookmarkNode*)node contextMenu:(NSMenu*)contextMenu cellText:(NSString*)cellText diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.mm index c03500d..4c05c72 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -19,4 +19,11 @@ return buttonCell; } +- (BOOL)isFolderButtonCell { + return YES; +} + +- (void)setMouseInside:(BOOL)flag animate:(BOOL)animated { +} + @end diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell_unittest.mm index 3c20cf7..dff15be 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h index 54b918c..fae30ab 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h @@ -8,7 +8,7 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h" #import "chrome/browser/ui/cocoa/tracking_area.h" @@ -23,7 +23,8 @@ // which look sort of like menus. @interface BookmarkBarFolderController : NSWindowController<BookmarkButtonDelegate, - BookmarkButtonControllerProtocol> { + BookmarkButtonControllerProtocol, + NSUserInterfaceValidations> { @private // The button whose click opened us. scoped_nsobject<BookmarkButton> parentButton_; @@ -140,6 +141,9 @@ // Set to YES to prevent any node animations. Useful for unit testing so that // incomplete animations do not cause valgrind complaints. BOOL ignoreAnimations_; + + int selectedIndex_; + NSString* typedPrefix_; } // Designated initializer. @@ -150,6 +154,20 @@ // Return the parent button that owns the bookmark folder we represent. - (BookmarkButton*)parentButton; +// Text typed by user, for type-select and arrow key support. +// Returns YES if the menu should be closed now. +- (BOOL)handleInputText:(NSString*)newText; + +// If you wanted to clear the type-select buffer. Currently only used +// internally. +- (void)clearInputText; + +// Gets notified when a fav icon asynchronously loads, so we can now use the +// real icon instead of a generic placeholder. +- (void)faviconLoadedForNode:(const BookmarkNode*)node; + +- (void)setSelectedButtonByIndex:(int)index; + // Offset our folder menu window. This is usually needed in response to a // parent folder menu window or the bookmark bar changing position due to // the dragging of a bookmark node from the parent into this folder menu. @@ -169,6 +187,9 @@ // Passed up by a child view to tell us of a desire to scroll. - (void)scrollWheel:(NSEvent *)theEvent; +- (void)mouseDragged:(NSEvent*)theEvent; + + // Forwarded to the associated BookmarkBarController. - (IBAction)addFolder:(id)sender; - (IBAction)addPage:(id)sender; diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm index 9286220..54809f6 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm @@ -8,7 +8,6 @@ #include "base/sys_string_conversions.h" #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/bookmarks/bookmark_utils.h" -#import "chrome/browser/themes/browser_theme_provider.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_constants.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.h" @@ -18,6 +17,7 @@ #import "chrome/browser/ui/cocoa/bookmarks/bookmark_folder_target.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/event_utils.h" +#include "ui/base/theme_provider.h" using bookmarks::kBookmarkBarMenuCornerRadius; @@ -103,6 +103,12 @@ struct LayoutMetrics { } // namespace + +// Required to set the right tracking bounds for our fake menus. +@interface NSView(Private) +- (void)_updateTrackingAreas; +@end + @interface BookmarkBarFolderController(Private) - (void)configureWindow; - (void)addOrUpdateScrollTracking; @@ -204,12 +210,6 @@ struct LayoutMetrics { // otherwise only border the button when the mouse is inside the button. - (void)forceButtonBorderToStayOnAlways:(BOOL)forceOn; -// On 10.6 event dispatch for an NSButtonCell's -// showsBorderOnlyWhileMouseInside seems broken if scrolling the -// view that contains the button. It appears that a mouseExited: -// gets lost, so the button stays highlit forever. We accomodate -// here. -- (void)toggleButtonBorderingWhileMouseInside; @end @implementation BookmarkButton (BookmarkBarFolderMenuHighlighting) @@ -219,12 +219,6 @@ struct LayoutMetrics { [self setNeedsDisplay]; } -- (void)toggleButtonBorderingWhileMouseInside { - BOOL toggle = [self showsBorderOnlyWhileMouseInside]; - [self setShowsBorderOnlyWhileMouseInside:!toggle]; - [self setShowsBorderOnlyWhileMouseInside:toggle]; -} - @end @implementation BookmarkBarFolderController @@ -239,6 +233,7 @@ struct LayoutMetrics { ofType:@"nib"]; if ((self = [super initWithWindowNibPath:nibPath owner:self])) { parentButton_.reset([button retain]); + selectedIndex_ = -1; // We want the button to remain bordered as part of the menu path. [button forceButtonBorderToStayOnAlways:YES]; @@ -259,6 +254,8 @@ struct LayoutMetrics { } - (void)dealloc { + [self clearInputText]; + // The button is no longer part of the menu path. [parentButton_ forceButtonBorderToStayOnAlways:NO]; [parentButton_ setNeedsDisplay]; @@ -295,6 +292,10 @@ struct LayoutMetrics { [super showWindow:sender]; } +- (int)buttonCount { + return [[self buttons] count]; +} + - (BookmarkButton*)parentButton { return parentButton_.get(); } @@ -321,7 +322,7 @@ struct LayoutMetrics { #pragma mark Private Methods - (BookmarkButtonCell*)cellForBookmarkNode:(const BookmarkNode*)child { - NSImage* image = child ? [barController_ favIconForNode:child] : nil; + NSImage* image = child ? [barController_ faviconForNode:child] : nil; NSMenu* menu = child ? child->is_folder() ? folderMenu_ : buttonMenu_ : nil; BookmarkBarFolderButtonCell* cell = [BookmarkBarFolderButtonCell buttonCellForNode:child @@ -430,7 +431,7 @@ struct LayoutMetrics { // If off the screen, switch direction. if ((x + windowWidth + bookmarks::kBookmarkHorizontalScreenPadding) > - NSMaxX([[[self window] screen] frame])) { + NSMaxX([[[self window] screen] visibleFrame])) { [self setSubFolderGrowthToRight:NO]; } else { return x; @@ -443,7 +444,7 @@ struct LayoutMetrics { bookmarks::kBookmarkMenuOverlap - windowWidth; // If off the screen, switch direction. - if (x < NSMinX([[[self window] screen] frame])) { + if (x < NSMinX([[[self window] screen] visibleFrame])) { [self setSubFolderGrowthToRight:YES]; } else { return x; @@ -451,7 +452,7 @@ struct LayoutMetrics { } } // Unhappy; do the best we can. - return NSMaxX([[[self window] screen] frame]) - windowWidth; + return NSMaxX([[[self window] screen] visibleFrame]) - windowWidth; } @@ -481,7 +482,7 @@ struct LayoutMetrics { // Make sure the window is on-screen; if not, push left. It is // intentional that top level folders "push left" slightly // different than subfolders. - NSRect screenFrame = [[[parentButton_ window] screen] frame]; + NSRect screenFrame = [[[parentButton_ window] screen] visibleFrame]; CGFloat spillOff = (newWindowTopLeft.x + windowWidth) - NSMaxX(screenFrame); if (spillOff > 0.0) { newWindowTopLeft.x = std::max(newWindowTopLeft.x - spillOff, @@ -579,7 +580,7 @@ struct LayoutMetrics { effectiveFolderY -= metrics.windowSize.height; metrics.canScrollUp = effectiveFolderY < metrics.minimumY; CGFloat maximumY = - NSMaxY([screen frame]) - bookmarks::kScrollWindowVerticalMargin; + NSMaxY([screen visibleFrame]) - bookmarks::kScrollWindowVerticalMargin; metrics.canScrollDown = metrics.folderTop > maximumY; // Accommodate changes in the bottom of the menu. @@ -654,7 +655,8 @@ struct LayoutMetrics { } else { if (metrics.canScrollDown) { // Couldn't -> Can - metrics.deltaWindowHeight += (NSMaxY([[[self window] screen] frame]) - + metrics.deltaWindowHeight += (NSMaxY([[[self window] screen] + visibleFrame]) - NSMaxY(metrics.windowFrame)); metrics.deltaVisibleHeight -= bookmarks::kScrollWindowVerticalMargin; metrics.deltaScrollerHeight -= verticalScrollArrowHeight_; @@ -691,6 +693,16 @@ struct LayoutMetrics { if (!metrics.preScroll) [[scrollView_ documentView] scrollPoint:metrics.scrollPoint]; + // TODO(maf) find a non-SPI way to do this. + // Hack. This is the only way I've found to get the tracking area cache + // to update properly during a mouse tracking loop. + // Without this, the item tracking-areas are wrong when using a scrollable + // menu with the mouse held down. + NSView *contentView = [[self window] contentView] ; + if ([contentView respondsToSelector:@selector(_updateTrackingAreas)]) + [contentView _updateTrackingAreas]; + + if (metrics.canScrollUp != metrics.couldScrollUp || metrics.canScrollDown != metrics.couldScrollDown || metrics.scrollDelta != 0.0) { @@ -730,9 +742,9 @@ struct LayoutMetrics { const BookmarkNode* node = [parentButton_ bookmarkNode]; DCHECK(node); int startingIndex = [[parentButton_ cell] startingChildIndex]; - DCHECK_LE(startingIndex, node->GetChildCount()); + DCHECK_LE(startingIndex, node->child_count()); // Must have at least 1 button (for "empty") - int buttons = std::max(node->GetChildCount() - startingIndex, 1); + int buttons = std::max(node->child_count() - startingIndex, 1); // Prelim height of the window. We'll trim later as needed. int height = [self menuHeightForButtonCount:buttons]; @@ -751,7 +763,7 @@ struct LayoutMetrics { // TODO(jrg): combine with addNodesToButtonList: code from // bookmark_bar_controller.mm (but use y offset) // http://crbug.com/35966 - if (!node->GetChildCount()) { + if (!node->child_count()) { // If no children we are the empty button. BookmarkButton* button = [self makeButtonForNode:nil frame:buttonsOuterFrame]; @@ -759,7 +771,7 @@ struct LayoutMetrics { [folderView_ addSubview:button]; } else { for (int i = startingIndex; - i < node->GetChildCount(); + i < node->child_count(); i++) { const BookmarkNode* child = node->GetChild(i); BookmarkButton* button = [self makeButtonForNode:child @@ -796,8 +808,8 @@ struct LayoutMetrics { [folderView_ setFrame:folderFrame]; NSSize newSize = NSMakeSize(windowWidth, 0.0); [self adjustWindowLeft:newWindowTopLeft.x size:newSize scrollingBy:0.0]; - [window display]; [self configureWindowLevel]; + [window display]; } // TODO(mrossetti): See if the following can be moved into view's viewWillDraw:. @@ -841,17 +853,74 @@ struct LayoutMetrics { } } +- (int)indexOfButton:(BookmarkButton*)button { + if (button == nil) + return -1; + int index = [buttons_ indexOfObject:button]; + return (index == NSNotFound) ? -1 : index; +} + +- (BookmarkButton*)buttonAtIndex:(int)which { + if (which < 0 || which >= [self buttonCount]) + return nil; + return [buttons_ objectAtIndex:which]; +} + +// Private, called by performOneScroll only. +// If the button at index contains the mouse it will select it and return YES. +// Otherwise returns NO. +- (BOOL)selectButtonIfHoveredAtIndex:(int)index { + BookmarkButton *btn = [self buttonAtIndex:index]; + if ([[btn cell] isMouseReallyInside]) { + buttonThatMouseIsIn_ = btn; + [self setSelectedButtonByIndex:index]; + return YES; + } + return NO; +} + // Perform a single scroll of the specified amount. - (void)performOneScroll:(CGFloat)delta { + if (delta == 0.0) + return; CGFloat finalDelta = [self determineFinalScrollDelta:delta]; - if (finalDelta > 0.0 || finalDelta < 0.0) { - if (buttonThatMouseIsIn_) - [buttonThatMouseIsIn_ toggleButtonBorderingWhileMouseInside]; - NSRect windowFrame = [[self window] frame]; - NSSize newSize = NSMakeSize(NSWidth(windowFrame), 0.0); - [self adjustWindowLeft:windowFrame.origin.x - size:newSize - scrollingBy:finalDelta]; + if (finalDelta == 0.0) + return; + int index = [self indexOfButton:buttonThatMouseIsIn_]; + // Check for a current mouse-initiated selection. + BOOL maintainHoverSelection = + (buttonThatMouseIsIn_ && + [[buttonThatMouseIsIn_ cell] isMouseReallyInside] && + selectedIndex_ != -1 && + index == selectedIndex_); + NSRect windowFrame = [[self window] frame]; + NSSize newSize = NSMakeSize(NSWidth(windowFrame), 0.0); + [self adjustWindowLeft:windowFrame.origin.x + size:newSize + scrollingBy:finalDelta]; + // We have now scrolled. + if (!maintainHoverSelection) + return; + // Is mouse still in the same hovered button? + if ([[buttonThatMouseIsIn_ cell] isMouseReallyInside]) + return; + // The finalDelta scroll direction will tell us us whether to search up or + // down the buttons array for the newly hovered button. + if (finalDelta < 0.0) { // Scrolled up, so search backwards for new hover. + index--; + while (index >= 0) { + if ([self selectButtonIfHoveredAtIndex:index]) + return; + index--; + } + } else { // Scrolled down, so search forward for new hovered button. + index++; + int btnMax = [self buttonCount]; + while (index < btnMax) { + if ([self selectButtonIfHoveredAtIndex:index]) + return; + index++; + } } } @@ -878,7 +947,7 @@ struct LayoutMetrics { delta = MIN(delta, maxUpDelta); } else { // Scrolling down. - NSRect screenFrame = [screen frame]; + NSRect screenFrame = [screen visibleFrame]; CGFloat topOfScreen = NSMaxY(screenFrame); NSRect folderFrame = [folderView_ frame]; CGFloat folderHeight = NSHeight(folderFrame); @@ -901,43 +970,44 @@ struct LayoutMetrics { } -// Add a timer to fire at a regular interveral which scrolls the +// Add a timer to fire at a regular interval which scrolls the // window vertically |delta|. - (void)addScrollTimerWithDelta:(CGFloat)delta { if (scrollTimer_ && verticalScrollDelta_ == delta) return; [self endScroll]; verticalScrollDelta_ = delta; - scrollTimer_ = - [NSTimer scheduledTimerWithTimeInterval:kBookmarkBarFolderScrollInterval - target:self - selector:@selector(performScroll:) - userInfo:nil - repeats:YES]; + scrollTimer_ = [NSTimer timerWithTimeInterval:kBookmarkBarFolderScrollInterval + target:self + selector:@selector(performScroll:) + userInfo:nil + repeats:YES]; + + [[NSRunLoop mainRunLoop] addTimer:scrollTimer_ forMode:NSRunLoopCommonModes]; } + // Called as a result of our tracking area. Warning: on the main // screen (of a single-screened machine), the minimum mouse y value is // 1, not 0. Also, we do not get events when the mouse is above the // menubar (to be fixed by setting the proper window level; see // initializer). -- (void)mouseMoved:(NSEvent*)theEvent { - NSWindow* window = [theEvent window]; - DCHECK(window == [self window]); - +// Note [theEvent window] may not be our window, as we also get these messages +// forwarded from BookmarkButton's mouse tracking loop. +- (void)mouseMovedOrDragged:(NSEvent*)theEvent { NSPoint eventScreenLocation = - [window convertBaseToScreen:[theEvent locationInWindow]]; + [[theEvent window] convertBaseToScreen:[theEvent locationInWindow]]; // Base hot spot calculations on the positions of the scroll arrow views. NSRect testRect = [scrollDownArrowView_ frame]; NSPoint testPoint = [visibleView_ convertPoint:testRect.origin toView:nil]; - testPoint = [window convertBaseToScreen:testPoint]; + testPoint = [[self window] convertBaseToScreen:testPoint]; CGFloat closeToTopOfScreen = testPoint.y; testRect = [scrollUpArrowView_ frame]; testPoint = [visibleView_ convertPoint:testRect.origin toView:nil]; - testPoint = [window convertBaseToScreen:testPoint]; + testPoint = [[self window] convertBaseToScreen:testPoint]; CGFloat closeToBottomOfScreen = testPoint.y + testRect.size.height; if (eventScreenLocation.y <= closeToBottomOfScreen && ![scrollUpArrowView_ isHidden]) { @@ -950,6 +1020,14 @@ struct LayoutMetrics { } } +- (void)mouseMoved:(NSEvent*)theEvent { + [self mouseMovedOrDragged:theEvent]; +} + +- (void)mouseDragged:(NSEvent*)theEvent { + [self mouseMovedOrDragged:theEvent]; +} + - (void)mouseExited:(NSEvent*)theEvent { [self endScroll]; } @@ -964,7 +1042,9 @@ struct LayoutMetrics { initWithRect:[view bounds] options:(NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | - NSTrackingActiveAlways) + NSTrackingActiveAlways | + NSTrackingEnabledDuringMouseDrag + ) proxiedOwner:self userInfo:nil]); [view addTrackingArea:scrollTrackingArea_.get()]; @@ -974,6 +1054,7 @@ struct LayoutMetrics { - (void)removeScrollTracking { if (scrollTrackingArea_.get()) { [[[self window] contentView] removeTrackingArea:scrollTrackingArea_.get()]; + [scrollTrackingArea_.get() clearOwner]; } scrollTrackingArea_.reset(); } @@ -1010,6 +1091,10 @@ struct LayoutMetrics { #pragma mark Actions Forwarded to Parent BookmarkBarController +- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item { + return [barController_ validateUserInterfaceItem:item]; +} + - (IBAction)openBookmark:(id)sender { [barController_ openBookmark:sender]; } @@ -1156,7 +1241,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { bookmarkNode]; DCHECK(beforeNode); // Be careful if the number of buttons != number of nodes. - return ((beforeNode->GetParent()->IndexOfChild(beforeNode) + 1) - + return ((beforeNode->parent()->GetIndexOf(beforeNode) + 1) - [[parentButton_ cell] startingChildIndex]); } @@ -1177,7 +1262,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { if ([button isFolder]) { destParent = [button bookmarkNode]; // Drop it at the end. - destIndex = [button bookmarkNode]->GetChildCount(); + destIndex = [button bookmarkNode]->child_count(); } else { // Else we're dropping somewhere in the folder, so find the right spot. destParent = [parentButton_ bookmarkNode]; @@ -1201,6 +1286,14 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { return wasCopiedOrMoved; } +// TODO(maf): Implement live drag & drop animation using this hook. +- (void)setDropInsertionPos:(CGFloat)where { +} + +// TODO(maf): Implement live drag & drop animation using this hook. +- (void)clearDropInsertionPos { +} + #pragma mark NSWindowDelegate Functions - (void)windowWillClose:(NSNotification*)notification { @@ -1231,7 +1324,10 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { // Called from BookmarkButton. // Unlike bookmark_bar_controller's version, we DO default to being enabled. - (void)mouseEnteredButton:(id)sender event:(NSEvent*)event { + [[NSCursor arrowCursor] set]; + buttonThatMouseIsIn_ = sender; + [self setSelectedButtonByIndex:[self indexOfButton:sender]]; // Cancel a previous hover if needed. [NSObject cancelPreviousPerformRequestsWithTarget:self]; @@ -1251,6 +1347,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { - (void)mouseExitedButton:(id)sender event:(NSEvent*)event { if (buttonThatMouseIsIn_ == sender) buttonThatMouseIsIn_ = nil; + [self setSelectedButtonByIndex:-1]; // Stop any timer about opening a new hover-open folder. @@ -1269,22 +1366,18 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { } - (BOOL)canDragBookmarkButtonToTrash:(BookmarkButton*)button { - return [barController_ canEditBookmark:[button bookmarkNode]]; + return [barController_ canEditBookmarks] && + [barController_ canEditBookmark:[button bookmarkNode]]; } - (void)didDragBookmarkToTrash:(BookmarkButton*)button { - // TODO(mrossetti): Refactor BookmarkBarFolder common code. - // http://crbug.com/35966 - const BookmarkNode* node = [button bookmarkNode]; - if (node) { - const BookmarkNode* parent = node->GetParent(); - [self bookmarkModel]->Remove(parent, - parent->IndexOfChild(node)); - } + [barController_ didDragBookmarkToTrash:button]; } -- (void)bookmarkDragDidEnd:(BookmarkButton*)button { - [barController_ bookmarkDragDidEnd:button]; +- (void)bookmarkDragDidEnd:(BookmarkButton*)button + operation:(NSDragOperation)operation { + [barController_ bookmarkDragDidEnd:button + operation:operation]; } @@ -1299,6 +1392,9 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { // Close our bookmark folder (a sub-controller) if we have one. - (void)closeBookmarkFolder:(id)sender { if (folderController_) { + // Make this menu key, so key status doesn't go back to the browser + // window when the submenu closes. + [[self window] makeKeyWindow]; [self setSubFolderGrowthToRight:YES]; [[folderController_ window] close]; folderController_ = nil; @@ -1309,6 +1405,10 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { return [barController_ bookmarkModel]; } +- (BOOL)draggingAllowed:(id<NSDraggingInfo>)info { + return [barController_ draggingAllowed:info]; +} + // TODO(jrg): Refactor BookmarkBarFolder common code. http://crbug.com/35966 // Most of the work (e.g. drop indicator) is taken care of in the // folder_view. Here we handle hover open issues for subfolders. @@ -1335,6 +1435,10 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { return [hoverState_ draggingEnteredButton:button]; } +- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)info { + return NSDragOperationMove; +} + // Unlike bookmark_bar_controller, we need to keep track of dragging state. // We also need to make sure we cancel the delayed hover close. - (void)draggingExited:(id<NSDraggingInfo>)info { @@ -1395,6 +1499,182 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { return ![self buttonForDroppingOnAtPoint:point]; } +// Button selection change code to support type to select and arrow key events. +#pragma mark Keyboard Support + +// Scroll the menu to show the selected button, if it's not already visible. +- (void)showSelectedButton { + int bMaxIndex = [self buttonCount] - 1; // Max array index in button array. + + // Is there a valid selected button? + if (bMaxIndex < 0 || selectedIndex_ < 0 || selectedIndex_ > bMaxIndex) + return; + + // Is the menu scrollable anyway? + if (![self canScrollUp] && ![self canScrollDown]) + return; + + // Now check to see if we need to scroll, which way, and how far. + CGFloat delta = 0.0; + NSPoint scrollPoint = [scrollView_ documentVisibleRect].origin; + CGFloat itemBottom = (bMaxIndex - selectedIndex_) * + bookmarks::kBookmarkFolderButtonHeight; + CGFloat itemTop = itemBottom + bookmarks::kBookmarkFolderButtonHeight; + CGFloat viewHeight = NSHeight([scrollView_ frame]); + + if (scrollPoint.y > itemBottom) { // Need to scroll down. + delta = scrollPoint.y - itemBottom; + } else if ((scrollPoint.y + viewHeight) < itemTop) { // Need to scroll up. + delta = -(itemTop - (scrollPoint.y + viewHeight)); + } else { // No need to scroll. + return; + } + + [self performOneScroll:delta]; +} + +// All changes to selectedness of buttons (aka fake menu items) ends up +// calling this method to actually flip the state of items. +// Needs to handle -1 as the invalid index (when nothing is selected) and +// greater than range values too. +- (void)setStateOfButtonByIndex:(int)index + state:(bool)state { + if (index >= 0 && index < [self buttonCount]) + [[buttons_ objectAtIndex:index] highlight:state]; +} + +// Selects the required button and deselects the previously selected one. +// An index of -1 means no selection. +- (void)setSelectedButtonByIndex:(int)index { + if (index == selectedIndex_) + return; + + [self setStateOfButtonByIndex:selectedIndex_ state:NO]; + [self setStateOfButtonByIndex:index state:YES]; + selectedIndex_ = index; + + [self showSelectedButton]; +} + +- (void)clearInputText { + [typedPrefix_ release]; + typedPrefix_ = nil; +} + +// Find the earliest item in the folder which has the target prefix. +// Returns nil if there is no prefix or there are no matches. +// These are in no particular order, and not particularly numerous, so linear +// search should be OK. +// -1 means no match. +- (int)earliestBookmarkIndexWithPrefix:(NSString*)prefix { + if ([prefix length] == 0) // Also handles nil. + return -1; + int maxButtons = [buttons_ count]; + NSString *lowercasePrefix = [prefix lowercaseString]; + for (int i = 0 ; i < maxButtons ; ++i) { + BookmarkButton* button = [buttons_ objectAtIndex:i]; + if ([[[button title] lowercaseString] hasPrefix:lowercasePrefix]) + return i; + } + return -1; +} + +- (void)setSelectedButtonByPrefix:(NSString*)prefix { + [self setSelectedButtonByIndex:[self earliestBookmarkIndexWithPrefix:prefix]]; +} + +- (void)selectPrevious { + int newIndex; + if (selectedIndex_ == 0) + return; + if (selectedIndex_ < 0) + newIndex = [self buttonCount] -1; + else + newIndex = std::max(selectedIndex_ - 1, 0); + [self setSelectedButtonByIndex:newIndex]; +} + +- (void) selectNext { + if (selectedIndex_ + 1 < [self buttonCount]) + [self setSelectedButtonByIndex:selectedIndex_ + 1]; +} + +- (BOOL)handleInputText:(NSString*)newText { + const unichar kUnicodeEscape = 0x001B; + const unichar kUnicodeSpace = 0x0020; + + // Event goes to the deepest nested open submenu. + if (folderController_) + return [folderController_ handleInputText:newText]; + + // Look for arrow keys or other function keys. + if ([newText length] == 1) { + // Get the 16-bit unicode char. + unichar theChar = [newText characterAtIndex:0]; + switch (theChar) { + + // Keys that trigger opening of the selection. + case kUnicodeSpace: // Space. + case NSNewlineCharacter: + case NSCarriageReturnCharacter: + case NSEnterCharacter: + if (selectedIndex_ >= 0 && selectedIndex_ < [self buttonCount]) { + [self openBookmark:[buttons_ objectAtIndex:selectedIndex_]]; + return NO; // NO because the selection-handling code will close later. + } else { + return YES; // Triggering with no selection closes the menu. + } + // Keys that cancel and close the menu. + case kUnicodeEscape: + case NSDeleteCharacter: + case NSBackspaceCharacter: + [self clearInputText]; + return YES; + // Keys that change selection directionally. + case NSUpArrowFunctionKey: + [self clearInputText]; + [self selectPrevious]; + return NO; + case NSDownArrowFunctionKey: + [self clearInputText]; + [self selectNext]; + return NO; + // Keys that open and close submenus. + case NSRightArrowFunctionKey: { + BookmarkButton* btn = [self buttonAtIndex:selectedIndex_]; + if (btn && [btn isFolder]) { + [self openBookmarkFolderFromButtonAndCloseOldOne:btn]; + [folderController_ selectNext]; + } + [self clearInputText]; + return NO; + } + case NSLeftArrowFunctionKey: + [self clearInputText]; + [parentController_ closeBookmarkFolder:self]; + return NO; + + // Check for other keys that should close the menu. + default: { + if (theChar > NSUpArrowFunctionKey && + theChar <= NSModeSwitchFunctionKey) { + [self clearInputText]; + return YES; + } + break; + } + } + } + + // It is a char or string worth adding to the type-select buffer. + NSString *newString = (!typedPrefix_) ? + newText : [typedPrefix_ stringByAppendingString:newText]; + [typedPrefix_ release]; + typedPrefix_ = [newString retain]; + [self setSelectedButtonByPrefix:typedPrefix_]; + return NO; +} + // Return the y position for a drop indicator. // // TODO(jrg): again we have code dup, sort of, with @@ -1449,6 +1729,20 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { return folderController_; } +- (void)faviconLoadedForNode:(const BookmarkNode*)node { + for (BookmarkButton* button in buttons_.get()) { + if ([button bookmarkNode] == node) { + [button setImage:[barController_ faviconForNode:node]]; + [button setNeedsDisplay:YES]; + return; + } + } + + // Node was not in this menu, try submenu. + if (folderController_) + [folderController_ faviconLoadedForNode:node]; +} + // Add a new folder controller as triggered by the given folder button. - (void)addNewFolderControllerWithParentButton:(BookmarkButton*)parentButton { if (folderController_) @@ -1477,8 +1771,8 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { // When adding a button to an empty folder we must remove the 'empty' // placeholder button. This can be detected by checking for a parent // child count of 1. - const BookmarkNode* parentNode = node->GetParent(); - if (parentNode->GetChildCount() == 1) { + const BookmarkNode* parentNode = node->parent(); + if (parentNode->child_count() == 1) { BookmarkButton* emptyButton = [buttons_ lastObject]; newButtonFrame = [emptyButton frame]; [emptyButton setDelegate:nil]; @@ -1525,7 +1819,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { if ([button isFolder]) { destParent = [button bookmarkNode]; // Drop it at the end. - destIndex = [button bookmarkNode]->GetChildCount(); + destIndex = [button bookmarkNode]->child_count(); } else { // Else we're dropping somewhere in the folder, so find the right spot. destParent = [parentButton_ bookmarkNode]; @@ -1559,6 +1853,8 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { if (toIndex == -1) toIndex = [buttons_ count]; BookmarkButton* movedButton = [buttons_ objectAtIndex:fromIndex]; + if (movedButton == buttonThatMouseIsIn_) + buttonThatMouseIsIn_ = nil; [buttons_ removeObjectAtIndex:fromIndex]; NSRect movedFrame = [movedButton frame]; NSPoint toOrigin = movedFrame.origin; diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm index d357087..5b35e3b 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm @@ -5,7 +5,7 @@ #import <Cocoa/Cocoa.h> #include "base/basictypes.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/utf_string_conversions.h" #include "chrome/browser/bookmarks/bookmark_model.h" #import "chrome/browser/ui/cocoa/animation_utils.h" @@ -125,31 +125,31 @@ class BookmarkBarFolderControllerTest : public CocoaTest { public: BrowserTestHelper helper_; scoped_nsobject<BookmarkBarControllerChildFolderRedirect> bar_; - const BookmarkNode* folderA_; // owned by model - const BookmarkNode* longTitleNode_; // owned by model + const BookmarkNode* folderA_; // Owned by model. + const BookmarkNode* longTitleNode_; // Owned by model. BookmarkBarFolderControllerTest() { BookmarkModel* model = helper_.profile()->GetBookmarkModel(); const BookmarkNode* parent = model->GetBookmarkBarNode(); - const BookmarkNode* folderA = model->AddGroup(parent, - parent->GetChildCount(), - ASCIIToUTF16("group")); + const BookmarkNode* folderA = model->AddFolder(parent, + parent->child_count(), + ASCIIToUTF16("folder")); folderA_ = folderA; - model->AddGroup(parent, parent->GetChildCount(), - ASCIIToUTF16("sibbling group")); - const BookmarkNode* folderB = model->AddGroup(folderA, - folderA->GetChildCount(), - ASCIIToUTF16("subgroup 1")); - model->AddGroup(folderA, - folderA->GetChildCount(), - ASCIIToUTF16("subgroup 2")); - model->AddURL(folderA, folderA->GetChildCount(), ASCIIToUTF16("title a"), + model->AddFolder(parent, parent->child_count(), + ASCIIToUTF16("sibbling folder")); + const BookmarkNode* folderB = model->AddFolder(folderA, + folderA->child_count(), + ASCIIToUTF16("subfolder 1")); + model->AddFolder(folderA, + folderA->child_count(), + ASCIIToUTF16("subfolder 2")); + model->AddURL(folderA, folderA->child_count(), ASCIIToUTF16("title a"), GURL("http://www.google.com/a")); longTitleNode_ = model->AddURL( - folderA, folderA->GetChildCount(), + folderA, folderA->child_count(), ASCIIToUTF16("title super duper long long whoa momma title you betcha"), GURL("http://www.google.com/b")); - model->AddURL(folderB, folderB->GetChildCount(), ASCIIToUTF16("t"), + model->AddURL(folderB, folderB->child_count(), ASCIIToUTF16("t"), GURL("http://www.google.com/c")); bar_.reset( @@ -174,8 +174,8 @@ class BookmarkBarFolderControllerTest : public CocoaTest { // Remove the bookmark with the long title. void RemoveLongTitleNode() { BookmarkModel* model = helper_.profile()->GetBookmarkModel(); - model->Remove(longTitleNode_->GetParent(), - longTitleNode_->GetParent()->IndexOfChild(longTitleNode_)); + model->Remove(longTitleNode_->parent(), + longTitleNode_->parent()->GetIndexOf(longTitleNode_)); } // Add LOTS of nodes to our model if needed (e.g. scrolling). @@ -183,7 +183,7 @@ class BookmarkBarFolderControllerTest : public CocoaTest { int AddLotsOfNodes() { BookmarkModel* model = helper_.profile()->GetBookmarkModel(); for (int i = 0; i < kLotsOfNodesCount; i++) { - model->AddURL(folderA_, folderA_->GetChildCount(), + model->AddURL(folderA_, folderA_->child_count(), ASCIIToUTF16("repeated title"), GURL("http://www.google.com/repeated/url")); } @@ -296,8 +296,8 @@ TEST_F(BookmarkBarFolderControllerTest, PositionRightLeftRight) { const int count = 100; int i; // Make some super duper deeply nested folders. - for (i=0; i<count; i++) { - folder = model->AddGroup(folder, 0, ASCIIToUTF16("nested folder")); + for (i = 0; i < count; i++) { + folder = model->AddFolder(folder, 0, ASCIIToUTF16("nested folder")); } // Setup initial state for opening all folders. @@ -448,9 +448,10 @@ TEST_F(BookmarkBarFolderControllerTest, ChildFolderWidth) { } // Simple scrolling tests. -TEST_F(BookmarkBarFolderControllerTest, SimpleScroll) { +// Currently flaky due to a changed definition of the correct menu boundaries. +TEST_F(BookmarkBarFolderControllerTest, DISABLED_SimpleScroll) { scoped_nsobject<BookmarkBarFolderController> bbfc; - NSRect screenFrame = [[NSScreen mainScreen] frame]; + NSRect screenFrame = [[NSScreen mainScreen] visibleFrame]; CGFloat screenHeight = NSHeight(screenFrame); int nodecount = AddLotsOfNodes(); bbfc.reset(SimpleBookmarkBarFolderController()); @@ -474,7 +475,7 @@ TEST_F(BookmarkBarFolderControllerTest, SimpleScroll) { NSScrollView* scrollView = [bbfc scrollView]; // Find the next-to-last button showing at the bottom of the window and - // us its center for hit testing. + // use its center for hit testing. BookmarkButton* targetButton = nil; NSPoint scrollPoint = [scrollView documentVisibleRect].origin; for (BookmarkButton* button in [bbfc buttons]) { @@ -506,7 +507,7 @@ TEST_F(BookmarkBarFolderControllerTest, SimpleScroll) { bool bothAtOnce = false; while ([bbfc canScrollUp]) { [bbfc performOneScroll:60]; - EXPECT_TRUE(NSContainsRect(screenFrame, [window frame])); + EXPECT_TRUE(NSContainsRect([[NSScreen mainScreen] frame], [window frame])); // Make sure, sometime during our scroll, we have the ability to // scroll in either direction. if ([bbfc canScrollUp] && @@ -519,6 +520,8 @@ TEST_F(BookmarkBarFolderControllerTest, SimpleScroll) { EXPECT_FALSE([bbfc canScrollUp]); EXPECT_TRUE([bbfc canScrollDown]); + NSRect wholeScreenRect = [[NSScreen mainScreen] frame]; + // Now scroll down and make sure the window size does not change. // Also confirm we never scroll the window off the screen the other // way. @@ -527,14 +530,11 @@ TEST_F(BookmarkBarFolderControllerTest, SimpleScroll) { // Once we can no longer scroll down the window height changes. if (![bbfc canScrollDown]) break; - EXPECT_EQ(screenHeight, NSHeight([window frame])); - EXPECT_TRUE(NSContainsRect(screenFrame, [window frame])); + EXPECT_TRUE(NSContainsRect(wholeScreenRect, [window frame])); } - // The final height should be offset from the top of the screen and still - // within the screen. - CGFloat height = screenHeight - bookmarks::kScrollWindowVerticalMargin; - EXPECT_CGFLOAT_EQ(height, NSHeight([window frame])); - EXPECT_TRUE(NSContainsRect(screenFrame, [window frame])); + + EXPECT_GT(NSHeight(wholeScreenRect), NSHeight([window frame])); + EXPECT_TRUE(NSContainsRect(wholeScreenRect, [window frame])); } // Folder menu sizing and placement while deleting bookmarks @@ -1168,9 +1168,9 @@ TEST_F(BookmarkBarFolderControllerMenuTest, MenuSizingAndScrollArrows) { EXPECT_EQ(model_string, actualModelString); const BookmarkNode* parent = model.GetBookmarkBarNode(); - const BookmarkNode* folder = model.AddGroup(parent, - parent->GetChildCount(), - ASCIIToUTF16("BIG")); + const BookmarkNode* folder = model.AddFolder(parent, + parent->child_count(), + ASCIIToUTF16("BIG")); // Pop open the new folder window and verify it has one (empty) item. BookmarkButton* button = [bar_ buttonWithTitleEqualTo:@"BIG"]; @@ -1189,7 +1189,7 @@ TEST_F(BookmarkBarFolderControllerMenuTest, MenuSizingAndScrollArrows) { EXPECT_FALSE([folderController canScrollDown]); // Now add a real bookmark and reopen. - model.AddURL(folder, folder->GetChildCount(), ASCIIToUTF16("a"), + model.AddURL(folder, folder->child_count(), ASCIIToUTF16("a"), GURL("http://a.com/")); folderController = [bar_ folderController]; EXPECT_TRUE(folderController); @@ -1215,7 +1215,7 @@ TEST_F(BookmarkBarFolderControllerMenuTest, MenuSizingAndScrollArrows) { EXPECT_LT(scrollerWidth, NSWidth([folderView frame])); // Add a wider bookmark and make sure the button widths match. - int reallyWideButtonNumber = folder->GetChildCount(); + int reallyWideButtonNumber = folder->child_count(); model.AddURL(folder, reallyWideButtonNumber, ASCIIToUTF16("A really, really, really, really, really, " "really long name"), @@ -1230,7 +1230,7 @@ TEST_F(BookmarkBarFolderControllerMenuTest, MenuSizingAndScrollArrows) { // for a scroll up arrow. NSUInteger tripWire = 0; // Prevent a runaway. while (![folderController canScrollUp] && ++tripWire < 1000) { - model.AddURL(folder, folder->GetChildCount(), ASCIIToUTF16("B"), + model.AddURL(folder, folder->child_count(), ASCIIToUTF16("B"), GURL("http://b.com/")); } EXPECT_TRUE([folderController canScrollUp]); @@ -1255,11 +1255,11 @@ TEST_F(BookmarkBarFolderControllerMenuTest, MenuSizingAndScrollArrows) { TEST_F(BookmarkBarFolderControllerMenuTest, HoverThenDeleteBookmark) { BookmarkModel& model(*helper_.profile()->GetBookmarkModel()); const BookmarkNode* root = model.GetBookmarkBarNode(); - const BookmarkNode* folder = model.AddGroup(root, - root->GetChildCount(), - ASCIIToUTF16("BIG")); + const BookmarkNode* folder = model.AddFolder(root, + root->child_count(), + ASCIIToUTF16("BIG")); for (int i = 0; i < kLotsOfNodesCount; i++) - model.AddURL(folder, folder->GetChildCount(), ASCIIToUTF16("kid"), + model.AddURL(folder, folder->child_count(), ASCIIToUTF16("kid"), GURL("http://kid.com/smile")); // Pop open the new folder window and hover one of its kids. @@ -1391,7 +1391,7 @@ TEST_F(BookmarkBarFolderControllerMenuTest, DragBookmarkDataToTrash) { EXPECT_EQ(model_string, actual); const BookmarkNode* folderNode = root->GetChild(1); - int oldFolderChildCount = folderNode->GetChildCount(); + int oldFolderChildCount = folderNode->child_count(); // Pop open a folder. BookmarkButton* button = [bar_ buttonWithTitleEqualTo:@"2f"]; @@ -1409,7 +1409,7 @@ TEST_F(BookmarkBarFolderControllerMenuTest, DragBookmarkDataToTrash) { [folderController didDragBookmarkToTrash:buttonToDelete]; // There should be one less button in the folder. - int newFolderChildCount = folderNode->GetChildCount(); + int newFolderChildCount = folderNode->child_count(); EXPECT_EQ(oldFolderChildCount - 1, newFolderChildCount); // Verify the model. const std::string expected("1b 2f:[ 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] " diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_hover_state.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_hover_state.h index 373e0e6..20ea39e 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_hover_state.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_hover_state.h @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h" // Hover state machine. Encapsulates the hover state for diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_hover_state.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_hover_state.mm index b762bb3..abd3f88 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_hover_state.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_hover_state.mm @@ -85,7 +85,8 @@ [self setHoverState:kHoverStateClosing]; [self performSelector:@selector(closeBookmarkFolderOnHoverButton:) withObject:hoverButton_ - afterDelay:bookmarks::kDragHoverCloseDelay]; + afterDelay:bookmarks::kDragHoverCloseDelay + inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; } // Cancel pending hover close. Transition to kHoverStateOpen state. @@ -104,7 +105,8 @@ [self setHoverState:kHoverStateOpening]; [self performSelector:@selector(openBookmarkFolderOnHoverButton:) withObject:hoverButton_ - afterDelay:bookmarks::kDragHoverOpenDelay]; + afterDelay:bookmarks::kDragHoverOpenDelay + inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; } // Cancel pending hover open. Transition to kHoverStateClosed state. diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view.mm index 5a451a8..d37a6fb 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view.mm @@ -78,6 +78,8 @@ // http://crbug.com/35966 - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info { inDrag_ = YES; + if (![[self controller] draggingAllowed:info]) + return NSDragOperationNone; if ([[info draggingPasteboard] dataForType:kBookmarkButtonDragType] || [self dragClipboardContainsBookmarks] || [[info draggingPasteboard] containsURLData]) { diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm index 07aca2b..df2e98f 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h" @@ -139,6 +139,10 @@ namespace { return dropIndicatorShown_; } +- (BOOL)draggingAllowed:(id<NSDraggingInfo>)info { + return YES; +} + - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info { draggingEnteredCalled_ = YES; return NSDragOperationNone; diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_window.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_window.h index 7fe6608..4a245f0 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_window.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_window.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,7 +8,7 @@ #import <Cocoa/Cocoa.h> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" // Window for a bookmark folder "menu". This menu pops up when you diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_window.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_window.mm index c64de1e..413cce4 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_window.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_window.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/bookmarks/bookmark_bar_folder_window.h" #import "base/logging.h" -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_constants.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h" #import "chrome/browser/ui/cocoa/image_utils.h" @@ -30,6 +30,18 @@ using bookmarks::kBookmarkBarMenuCornerRadius; return self; } +- (BOOL)canBecomeKeyWindow { + return YES; +} + +- (BOOL)canBecomeMainWindow { + return NO; +} + +// Override of keyDown as the NSWindow default implementation beeps. +- (void)keyDown:(NSEvent *)theEvent { +} + @end diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_window_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_window_unittest.mm index 7dd6c06..d1d1005 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_window_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_window_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_ptr.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_window.h" #include "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.mm index 94c364d..1060e59 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.h" #include "chrome/browser/ntp_background_util.h" -#include "chrome/browser/themes/browser_theme_provider.h" +#include "chrome/browser/themes/theme_service.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_constants.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" @@ -26,6 +26,12 @@ const CGFloat kBorderRadius = 3.0; return [controller_ isInState:bookmarks::kDetachedState]; } +- (void)resetCursorRects { + NSCursor *arrow = [NSCursor arrowCursor]; + [self addCursorRect:[self visibleRect] cursor:arrow]; + [arrow setOnMouseEntered:YES]; +} + - (void)drawRect:(NSRect)rect { if ([controller_ isInState:bookmarks::kDetachedState] || [controller_ isAnimatingToState:bookmarks::kDetachedState] || @@ -89,7 +95,7 @@ const CGFloat kBorderRadius = 3.0; // Draw the rounded rectangle. NSColor* toolbarColor = - themeProvider->GetNSColor(BrowserThemeProvider::COLOR_TOOLBAR, true); + themeProvider->GetNSColor(ThemeService::COLOR_TOOLBAR, true); CGFloat alpha = morph * [toolbarColor alphaComponent]; [[toolbarColor colorWithAlphaComponent:alpha] set]; // Set with opacity. [border fill]; @@ -107,7 +113,7 @@ const CGFloat kBorderRadius = 3.0; // Draw the border of the rounded rectangle. NSColor* borderColor = themeProvider->GetNSColor( - BrowserThemeProvider::COLOR_TOOLBAR_BUTTON_STROKE, true); + ThemeService::COLOR_TOOLBAR_BUTTON_STROKE, true); alpha = morph * [borderColor alphaComponent]; [[borderColor colorWithAlphaComponent:alpha] set]; // Set with opacity. [border stroke]; diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view_unittest.mm index ef8bfc8..e946af2 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view_unittest.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" -#include "chrome/browser/themes/browser_theme_provider.h" +#include "base/memory/scoped_nsobject.h" +#include "chrome/browser/themes/theme_service.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" @@ -133,7 +133,7 @@ TEST_F(BookmarkBarToolbarViewTest, DisplayAsDetachedBarWithNoImage) { // Tests where we don't have a background image, only a color. MockThemeProvider provider; - EXPECT_CALL(provider, GetColor(BrowserThemeProvider::COLOR_NTP_BACKGROUND)) + EXPECT_CALL(provider, GetColor(ThemeService::COLOR_NTP_BACKGROUND)) .WillRepeatedly(Return(SK_ColorWHITE)); EXPECT_CALL(provider, HasCustomImage(IDR_THEME_NTP_BACKGROUND)) .WillRepeatedly(Return(false)); @@ -144,12 +144,12 @@ TEST_F(BookmarkBarToolbarViewTest, DisplayAsDetachedBarWithNoImage) { // Actions used in DisplayAsDetachedBarWithBgImage. ACTION(SetBackgroundTiling) { - *arg1 = BrowserThemeProvider::NO_REPEAT; + *arg1 = ThemeService::NO_REPEAT; return true; } ACTION(SetAlignLeft) { - *arg1 = BrowserThemeProvider::ALIGN_LEFT; + *arg1 = ThemeService::ALIGN_LEFT; return true; } @@ -161,17 +161,17 @@ TEST_F(BookmarkBarToolbarViewTest, DisplayAsDetachedBarWithBgImage) { MockThemeProvider provider; // Advertise having an image. - EXPECT_CALL(provider, GetColor(BrowserThemeProvider::COLOR_NTP_BACKGROUND)) + EXPECT_CALL(provider, GetColor(ThemeService::COLOR_NTP_BACKGROUND)) .WillRepeatedly(Return(SK_ColorRED)); EXPECT_CALL(provider, HasCustomImage(IDR_THEME_NTP_BACKGROUND)) .WillRepeatedly(Return(true)); // Return the correct tiling/alignment information. EXPECT_CALL(provider, - GetDisplayProperty(BrowserThemeProvider::NTP_BACKGROUND_TILING, _)) + GetDisplayProperty(ThemeService::NTP_BACKGROUND_TILING, _)) .WillRepeatedly(SetBackgroundTiling()); EXPECT_CALL(provider, - GetDisplayProperty(BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT, _)) + GetDisplayProperty(ThemeService::NTP_BACKGROUND_ALIGNMENT, _)) .WillRepeatedly(SetAlignLeft()); // Create a dummy bitmap full of not-red to blit with. diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view.mm index b3bb105..80935e2 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -11,7 +11,7 @@ #import "chrome/browser/ui/cocoa/bookmarks/bookmark_folder_target.h" #import "chrome/browser/ui/cocoa/themed_window.h" #import "chrome/browser/ui/cocoa/view_id_util.h" -#import "chrome/browser/themes/browser_theme_provider.h" +#import "chrome/browser/themes/theme_service.h" #import "third_party/mozilla/NSPasteboard+Utils.h" @interface BookmarkBarView (Private) @@ -25,6 +25,7 @@ @synthesize dropIndicatorPosition = dropIndicatorPosition_; @synthesize noItemContainer = noItemContainer_; + - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; // This probably isn't strictly necessary, but can't hurt. @@ -71,7 +72,7 @@ // Called after the current theme has changed. - (void)themeDidChangeNotification:(NSNotification*)aNotification { ui::ThemeProvider* themeProvider = - static_cast<ui::ThemeProvider*>([[aNotification object] pointerValue]); + static_cast<ThemeService*>([[aNotification object] pointerValue]); [self updateTheme:themeProvider]; } @@ -82,7 +83,7 @@ return; NSColor* color = - themeProvider->GetNSColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT, + themeProvider->GetNSColor(ThemeService::COLOR_BOOKMARK_TEXT, true); [noItemTextfield_ setTextColor:color]; } @@ -105,27 +106,18 @@ return controller_; } +// Internal method, needs to be called whenever a change has been made to +// dropIndicatorShown_ or dropIndicatorPosition_ so it can get the controller +// to reflect the change by moving buttons around. +-(void)dropIndicatorChanged { + if (dropIndicatorShown_) + [controller_ setDropInsertionPos:dropIndicatorPosition_]; + else + [controller_ clearDropInsertionPos]; +} + -(void)drawRect:(NSRect)dirtyRect { [super drawRect:dirtyRect]; - - // Draw the bookmark-button-dragging drop indicator if necessary. - if (dropIndicatorShown_) { - const CGFloat kBarWidth = 1; - const CGFloat kBarHalfWidth = kBarWidth / 2.0; - const CGFloat kBarVertPad = 4; - const CGFloat kBarOpacity = 0.85; - - // Prevent the indicator from being clipped on the left. - CGFloat xLeft = MAX(dropIndicatorPosition_ - kBarHalfWidth, 0); - - NSRect uglyBlackBar = - NSMakeRect(xLeft, kBarVertPad, - kBarWidth, NSHeight([self bounds]) - 2 * kBarVertPad); - NSColor* uglyBlackBarColor = [[self window] themeProvider]-> - GetNSColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT, true); - [[uglyBlackBarColor colorWithAlphaComponent:kBarOpacity] setFill]; - [[NSBezierPath bezierPathWithRect:uglyBlackBar] fill]; - } } // Shim function to assist in unit testing. @@ -136,6 +128,8 @@ // NSDraggingDestination methods - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info { + if (![controller_ draggingAllowed:info]) + return NSDragOperationNone; if ([[info draggingPasteboard] dataForType:kBookmarkButtonDragType] || [self dragClipboardContainsBookmarks] || [[info draggingPasteboard] containsURLData]) { @@ -146,7 +140,7 @@ if (!showIt) { if (dropIndicatorShown_) { dropIndicatorShown_ = NO; - [self setNeedsDisplay:YES]; + [self dropIndicatorChanged]; } } else { CGFloat x = @@ -156,7 +150,7 @@ if (!dropIndicatorShown_ || dropIndicatorPosition_ != x) { dropIndicatorShown_ = YES; dropIndicatorPosition_ = x; - [self setNeedsDisplay:YES]; + [self dropIndicatorChanged]; } } @@ -171,26 +165,25 @@ // drop indicator if one was shown. if (dropIndicatorShown_) { dropIndicatorShown_ = NO; - [self setNeedsDisplay:YES]; + [self dropIndicatorChanged]; } } - (void)draggingEnded:(id<NSDraggingInfo>)info { - // For now, we just call |-draggingExited:|. - [self draggingExited:info]; + [[BookmarkButton draggedButton] setHidden:NO]; + if (dropIndicatorShown_) { + dropIndicatorShown_ = NO; + [self dropIndicatorChanged]; + } + [controller_ draggingEnded:info]; } - (BOOL)wantsPeriodicDraggingUpdates { - // TODO(port): This should probably return |YES| and the controller should - // slide the existing bookmark buttons interactively to the side to make - // room for the about-to-be-dropped bookmark. return YES; } - (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)info { // For now it's the same as draggingEntered:. - // TODO(jrg): once we return YES for wantsPeriodicDraggingUpdates, - // this should ping the controller_ to perform animations. return [self draggingEntered:info]; } diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_unittest.mm index c847a61..0cf602d 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h" @@ -117,6 +117,10 @@ namespace { return NO; } +- (BOOL)canEditBookmarks { + return YES; +} + // Confirm the pongs. - (BOOL)dragButtonToPong { @@ -139,11 +143,21 @@ namespace { return dropIndicatorShown_; } +- (BOOL)draggingAllowed:(id<NSDraggingInfo>)info { + return YES; +} + - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info { draggingEnteredCalled_ = YES; return NSDragOperationNone; } +- (void)setDropInsertionPos:(CGFloat)where { +} + +- (void)clearDropInsertionPos { +} + @end namespace { diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h index e1d7bb4..1f94cd5 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h @@ -1,11 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_ptr.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h" class BookmarkBubbleNotificationBridge; diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm index d0a6dd8..d7f3d6c 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -12,9 +12,9 @@ #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/info_bubble_view.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "chrome/common/notification_service.h" +#include "content/common/notification_observer.h" +#include "content/common/notification_registrar.h" +#include "content/common/notification_service.h" #include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -116,7 +116,7 @@ void BookmarkBubbleNotificationBridge::Observe( // until we find something visible to pulse. - (void)startPulsingBookmarkButton:(const BookmarkNode*)node { while (node) { - if ((node->GetParent() == model_->GetBookmarkBarNode()) || + if ((node->parent() == model_->GetBookmarkBarNode()) || (node == model_->other_node())) { pulsingBookmarkNode_ = node; NSValue *value = [NSValue valueWithPointer:node]; @@ -132,7 +132,7 @@ void BookmarkBubbleNotificationBridge::Observe( userInfo:dict]; return; } - node = node->GetParent(); + node = node->parent(); } } @@ -332,7 +332,7 @@ void BookmarkBubbleNotificationBridge::Observe( model_->profile()); } // Then the parent folder. - const BookmarkNode* oldParent = node_->GetParent(); + const BookmarkNode* oldParent = node_->parent(); NSMenuItem* selectedItem = [folderPopUpButton_ selectedItem]; id representedObject = [selectedItem representedObject]; if ([representedObject isEqual:[[self class] chooseAnotherFolderObject]]) { @@ -343,7 +343,7 @@ void BookmarkBubbleNotificationBridge::Observe( static_cast<const BookmarkNode*>([representedObject pointerValue]); DCHECK(newParent); if (oldParent != newParent) { - int index = newParent->GetChildCount(); + int index = newParent->child_count(); model_->Move(node_, newParent, index); UserMetrics::RecordAction(UserMetricsAction("BookmarkBubble_ChangeParent"), model_->profile()); @@ -365,7 +365,7 @@ void BookmarkBubbleNotificationBridge::Observe( ChooseAnotherFolder* obj = [[self class] chooseAnotherFolderObject]; [item setRepresentedObject:obj]; // Finally, select the current parent. - NSValue* parentValue = [NSValue valueWithPointer:node_->GetParent()]; + NSValue* parentValue = [NSValue valueWithPointer:node_->parent()]; NSInteger idx = [menu indexOfItemWithRepresentedObject:parentValue]; [folderPopUpButton_ selectItemAtIndex:idx]; } @@ -395,7 +395,7 @@ void BookmarkBubbleNotificationBridge::Observe( [item setIndentationLevel:indentation]; ++indentation; } - for (int i = 0; i < parent->GetChildCount(); i++) { + for (int i = 0; i < parent->child_count(); i++) { const BookmarkNode* child = parent->GetChild(i); if (child->is_folder()) [self addFolderNodes:child diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller_unittest.mm index ef3a47a..48b0916 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller_unittest.mm @@ -1,18 +1,18 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/basictypes.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/utf_string_conversions.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h" #include "chrome/browser/ui/cocoa/browser_test_helper.h" #include "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/info_bubble_window.h" -#include "chrome/common/notification_service.h" +#include "content/common/notification_service.h" #include "testing/gtest/include/gtest/gtest.h" #import "testing/gtest_mac.h" #include "testing/platform_test.h" @@ -139,16 +139,16 @@ TEST_F(BookmarkBubbleControllerTest, TestFillInFolder) { EXPECT_TRUE(model); const BookmarkNode* bookmarkBarNode = model->GetBookmarkBarNode(); EXPECT_TRUE(bookmarkBarNode); - const BookmarkNode* node1 = model->AddGroup(bookmarkBarNode, 0, - ASCIIToUTF16("one")); + const BookmarkNode* node1 = model->AddFolder(bookmarkBarNode, 0, + ASCIIToUTF16("one")); EXPECT_TRUE(node1); - const BookmarkNode* node2 = model->AddGroup(bookmarkBarNode, 1, - ASCIIToUTF16("two")); + const BookmarkNode* node2 = model->AddFolder(bookmarkBarNode, 1, + ASCIIToUTF16("two")); EXPECT_TRUE(node2); - const BookmarkNode* node3 = model->AddGroup(bookmarkBarNode, 2, - ASCIIToUTF16("three")); + const BookmarkNode* node3 = model->AddFolder(bookmarkBarNode, 2, + ASCIIToUTF16("three")); EXPECT_TRUE(node3); - const BookmarkNode* node4 = model->AddGroup(node2, 0, ASCIIToUTF16("sub")); + const BookmarkNode* node4 = model->AddFolder(node2, 0, ASCIIToUTF16("sub")); EXPECT_TRUE(node4); const BookmarkNode* node5 = model->AddURL(node1, 0, ASCIIToUTF16("title1"), GURL("http://www.google.com")); @@ -156,8 +156,8 @@ TEST_F(BookmarkBubbleControllerTest, TestFillInFolder) { const BookmarkNode* node6 = model->AddURL(node3, 0, ASCIIToUTF16("title2"), GURL("http://www.google.com")); EXPECT_TRUE(node6); - const BookmarkNode* node7 = model->AddURL(node4, 0, ASCIIToUTF16("title3"), - GURL("http://www.google.com/reader")); + const BookmarkNode* node7 = model->AddURL( + node4, 0, ASCIIToUTF16("title3"), GURL("http://www.google.com/reader")); EXPECT_TRUE(node7); BookmarkBubbleController* controller = ControllerForNode(node4); @@ -180,14 +180,14 @@ TEST_F(BookmarkBubbleControllerTest, TestFolderWithBlankName) { EXPECT_TRUE(model); const BookmarkNode* bookmarkBarNode = model->GetBookmarkBarNode(); EXPECT_TRUE(bookmarkBarNode); - const BookmarkNode* node1 = model->AddGroup(bookmarkBarNode, 0, - ASCIIToUTF16("one")); + const BookmarkNode* node1 = model->AddFolder(bookmarkBarNode, 0, + ASCIIToUTF16("one")); EXPECT_TRUE(node1); - const BookmarkNode* node2 = model->AddGroup(bookmarkBarNode, 1, - ASCIIToUTF16("")); + const BookmarkNode* node2 = model->AddFolder(bookmarkBarNode, 1, + ASCIIToUTF16("")); EXPECT_TRUE(node2); - const BookmarkNode* node3 = model->AddGroup(bookmarkBarNode, 2, - ASCIIToUTF16("three")); + const BookmarkNode* node3 = model->AddFolder(bookmarkBarNode, 2, + ASCIIToUTF16("three")); EXPECT_TRUE(node3); const BookmarkNode* node2_1 = model->AddURL(node2, 0, ASCIIToUTF16("title1"), GURL("http://www.google.com")); @@ -261,11 +261,11 @@ TEST_F(BookmarkBubbleControllerTest, TestUserEdit) { 0, ASCIIToUTF16("short-title"), GURL("http://www.google.com")); - const BookmarkNode* grandma = model->AddGroup(bookmarkBarNode, 0, - ASCIIToUTF16("grandma")); + const BookmarkNode* grandma = model->AddFolder(bookmarkBarNode, 0, + ASCIIToUTF16("grandma")); EXPECT_TRUE(grandma); - const BookmarkNode* grandpa = model->AddGroup(bookmarkBarNode, 0, - ASCIIToUTF16("grandpa")); + const BookmarkNode* grandpa = model->AddFolder(bookmarkBarNode, 0, + ASCIIToUTF16("grandpa")); EXPECT_TRUE(grandpa); BookmarkBubbleController* controller = ControllerForNode(node); @@ -277,7 +277,7 @@ TEST_F(BookmarkBubbleControllerTest, TestUserEdit) { // Make sure bookmark has changed EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("oops")); - EXPECT_EQ(node->GetParent()->GetTitle(), ASCIIToUTF16("grandma")); + EXPECT_EQ(node->parent()->GetTitle(), ASCIIToUTF16("grandma")); } // Confirm happiness with parent nodes that have the same name. @@ -292,13 +292,13 @@ TEST_F(BookmarkBubbleControllerTest, TestNewParentSameName) { ASCIIToUTF16("short-title"), GURL("http://www.google.com")); EXPECT_TRUE(node); - const BookmarkNode* group = model->AddGroup(bookmarkBarNode, 0, - ASCIIToUTF16("NAME")); - EXPECT_TRUE(group); - group = model->AddGroup(bookmarkBarNode, 0, ASCIIToUTF16("NAME")); - EXPECT_TRUE(group); - group = model->AddGroup(bookmarkBarNode, 0, ASCIIToUTF16("NAME")); - EXPECT_TRUE(group); + const BookmarkNode* folder = model->AddFolder(bookmarkBarNode, 0, + ASCIIToUTF16("NAME")); + EXPECT_TRUE(folder); + folder = model->AddFolder(bookmarkBarNode, 0, ASCIIToUTF16("NAME")); + EXPECT_TRUE(folder); + folder = model->AddFolder(bookmarkBarNode, 0, ASCIIToUTF16("NAME")); + EXPECT_TRUE(folder); BookmarkBubbleController* controller = ControllerForNode(node); EXPECT_TRUE(controller); @@ -308,7 +308,7 @@ TEST_F(BookmarkBubbleControllerTest, TestNewParentSameName) { // Make sure bookmark has changed, and that the parent is what we // expect. This proves nobody did searching based on name. - EXPECT_EQ(node->GetParent(), bookmarkBarNode->GetChild(i)); + EXPECT_EQ(node->parent(), bookmarkBarNode->GetChild(i)); } } @@ -317,11 +317,11 @@ TEST_F(BookmarkBubbleControllerTest, TestDuplicateNodeNames) { BookmarkModel* model = GetBookmarkModel(); const BookmarkNode* bookmarkBarNode = model->GetBookmarkBarNode(); EXPECT_TRUE(bookmarkBarNode); - const BookmarkNode* node1 = model->AddGroup(bookmarkBarNode, 0, - ASCIIToUTF16("NAME")); + const BookmarkNode* node1 = model->AddFolder(bookmarkBarNode, 0, + ASCIIToUTF16("NAME")); EXPECT_TRUE(node1); - const BookmarkNode* node2 = model->AddGroup(bookmarkBarNode, 0, - ASCIIToUTF16("NAME")); + const BookmarkNode* node2 = model->AddFolder(bookmarkBarNode, 0, + ASCIIToUTF16("NAME")); EXPECT_TRUE(node2); BookmarkBubbleController* controller = ControllerForNode(bookmarkBarNode); EXPECT_TRUE(controller); @@ -417,17 +417,17 @@ TEST_F(BookmarkBubbleControllerTest, TestMenuIndentation) { EXPECT_TRUE(model); const BookmarkNode* bookmarkBarNode = model->GetBookmarkBarNode(); EXPECT_TRUE(bookmarkBarNode); - const BookmarkNode* node1 = model->AddGroup(bookmarkBarNode, 0, - ASCIIToUTF16("one")); + const BookmarkNode* node1 = model->AddFolder(bookmarkBarNode, 0, + ASCIIToUTF16("one")); EXPECT_TRUE(node1); - const BookmarkNode* node2 = model->AddGroup(bookmarkBarNode, 1, - ASCIIToUTF16("two")); + const BookmarkNode* node2 = model->AddFolder(bookmarkBarNode, 1, + ASCIIToUTF16("two")); EXPECT_TRUE(node2); - const BookmarkNode* node2_1 = model->AddGroup(node2, 0, - ASCIIToUTF16("two dot one")); + const BookmarkNode* node2_1 = model->AddFolder(node2, 0, + ASCIIToUTF16("two dot one")); EXPECT_TRUE(node2_1); - const BookmarkNode* node3 = model->AddGroup(bookmarkBarNode, 2, - ASCIIToUTF16("three")); + const BookmarkNode* node3 = model->AddFolder(bookmarkBarNode, 2, + ASCIIToUTF16("three")); EXPECT_TRUE(node3); BookmarkBubbleController* controller = ControllerForNode(node1); diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_button.h index c04b3eb..4683267 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -53,7 +53,8 @@ class ThemeProvider; // This is called after the drag has finished, for any reason. // We particularly need this so we can hide bookmark folder menus and stop // doing that hover thing. -- (void)bookmarkDragDidEnd:(BookmarkButton*)button; +- (void)bookmarkDragDidEnd:(BookmarkButton*)button + operation:(NSDragOperation)operation; @end @@ -78,6 +79,7 @@ class ThemeProvider; - (BookmarkModel*)bookmarkModel; // Perform drag enter/exit operations, such as hover-open and hover-close. +- (BOOL)draggingAllowed:(id<NSDraggingInfo>)info; - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info; - (void)draggingExited:(id<NSDraggingInfo>)info; @@ -122,6 +124,12 @@ class ThemeProvider; // http://crbug.com/35968 - (CGFloat)indicatorPosForDragToPoint:(NSPoint)point; +// Used to tell the controller that room should be made for a drop. +- (void)setDropInsertionPos:(CGFloat)where; + +// Used to tell the controller to stop making room for a drop. +- (void)clearDropInsertionPos; + // Return the theme provider associated with this browser window. - (ui::ThemeProvider*)themeProvider; @@ -147,7 +155,7 @@ class ThemeProvider; // cut/paste/delete and drag/drop. Such changes may involve coordinating // the bookmark button contents of two controllers (such as when a bookmark is // dragged from one folder to another). The bookmark bar controller -// coordinates in response to notifications propogated by the bookmark model +// coordinates in response to notifications propagated by the bookmark model // through BookmarkBarBridge calls. The following three functions are // implemented by the controllers and are dispatched by the bookmark bar // controller in response to notifications coming in from the BookmarkBarBridge. @@ -212,6 +220,10 @@ class ThemeProvider; // Return YES if this is a folder button (the node has subnodes). - (BOOL)isFolder; +- (void)mouseDragged:(NSEvent*)theEvent; + +- (BOOL)acceptsTrackInFrom:(id)sender; + // At this time we represent an empty folder (e.g. the string // '(empty)') as a disabled button with no associated node. // diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_button.mm index 191f371..197e92f 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button.mm @@ -1,14 +1,15 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/bookmarks/bookmark_button.h" #include "base/logging.h" -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/metrics/user_metrics.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h" +#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_window.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/view_id_util.h" @@ -63,6 +64,12 @@ BookmarkButton* gDraggedButton = nil; // Weak if ([[self cell] respondsToSelector:@selector(safelyStopPulsing)]) [[self cell] safelyStopPulsing]; view_id_util::UnsetID(self); + + if (area_) { + [self removeTrackingArea:area_]; + [area_ release]; + } + [super dealloc]; } @@ -159,6 +166,11 @@ BookmarkButton* gDraggedButton = nil; // Weak return; } + if ([self isFolder]) { + // Close the folder's drop-down menu if it's visible. + [[self target] closeBookmarkFolder:self]; + } + // At the moment, moving bookmarks causes their buttons (like me!) // to be destroyed and rebuilt. Make sure we don't go away while on // the stack. @@ -180,7 +192,7 @@ BookmarkButton* gDraggedButton = nil; // Weak delay:NO]; } const BookmarkNode* node = [self bookmarkNode]; - const BookmarkNode* parent = node ? node->GetParent() : NULL; + const BookmarkNode* parent = node ? node->parent() : NULL; if (parent && parent->type() == BookmarkNode::FOLDER) { UserMetrics::RecordAction(UserMetricsAction("BookmarkBarFolder_DragStart")); } else { @@ -190,13 +202,13 @@ BookmarkButton* gDraggedButton = nil; // Weak dragMouseOffset_ = [self convertPointFromBase:[event locationInWindow]]; dragPending_ = YES; gDraggedButton = self; - [[self animator] setHidden:YES]; CGFloat yAt = [self bounds].size.height; NSSize dragOffset = NSMakeSize(0.0, 0.0); - [self dragImage:[self dragImage] at:NSMakePoint(0, yAt) offset:dragOffset + NSImage* image = [self dragImage]; + [self setHidden:YES]; + [self dragImage:image at:NSMakePoint(0, yAt) offset:dragOffset event:event pasteboard:pboard source:self slideBack:YES]; - [self setHidden:NO]; // And we're done. @@ -235,7 +247,8 @@ BookmarkButton* gDraggedButton = nil; // Weak gDraggedButton = nil; // Inform delegate of drag source that we're finished dragging, // so it can close auto-opened bookmark folders etc. - [delegate_ bookmarkDragDidEnd:self]; + [delegate_ bookmarkDragDidEnd:self + operation:operation]; // Tell delegate if it should delete us. if (operation & NSDragOperationDelete) { dragEndScreenLocation_ = aPoint; @@ -243,6 +256,75 @@ BookmarkButton* gDraggedButton = nil; // Weak } } +- (void)performMouseDownAction:(NSEvent*)theEvent { + int eventMask = NSLeftMouseUpMask | NSMouseEnteredMask | NSMouseExitedMask | + NSLeftMouseDraggedMask; + + BOOL keepGoing = YES; + [[self target] performSelector:[self action] withObject:self]; + self.actionHasFired = YES; + + DraggableButton* insideBtn = nil; + + while (keepGoing) { + theEvent = [[self window] nextEventMatchingMask:eventMask]; + if (!theEvent) + continue; + + NSPoint mouseLoc = [self convertPoint:[theEvent locationInWindow] + fromView:nil]; + BOOL isInside = [self mouse:mouseLoc inRect:[self bounds]]; + + switch ([theEvent type]) { + case NSMouseEntered: + case NSMouseExited: { + NSView* trackedView = (NSView*)[[theEvent trackingArea] owner]; + if (trackedView && [trackedView isKindOfClass:[self class]]) { + BookmarkButton* btn = static_cast<BookmarkButton*>(trackedView); + if (![btn acceptsTrackInFrom:self]) + break; + if ([theEvent type] == NSMouseEntered) { + [[NSCursor arrowCursor] set]; + [[btn cell] mouseEntered:theEvent]; + insideBtn = btn; + } else { + [[btn cell] mouseExited:theEvent]; + if (insideBtn == btn) + insideBtn = nil; + } + } + break; + } + case NSLeftMouseDragged: { + if (insideBtn) + [insideBtn mouseDragged:theEvent]; + break; + } + case NSLeftMouseUp: { + self.durationMouseWasDown = [theEvent timestamp] - self.whenMouseDown; + if (!isInside && insideBtn && insideBtn != self) { + // Has tracked onto another BookmarkButton menu item, and released, + // so fire its action. + [[insideBtn target] performSelector:[insideBtn action] + withObject:insideBtn]; + + } else { + [self secondaryMouseUpAction:isInside]; + [[self cell] mouseExited:theEvent]; + [[insideBtn cell] mouseExited:theEvent]; + } + keepGoing = NO; + break; + } + default: + /* Ignore any other kind of event. */ + break; + } + } +} + + + // mouseEntered: and mouseExited: are called from our // BookmarkButtonCell. We redirect this information to our delegate. // The controller can then perform menu-like actions (e.g. "hover over @@ -256,6 +338,16 @@ BookmarkButton* gDraggedButton = nil; // Weak [delegate_ mouseExitedButton:self event:event]; } +- (void)mouseMoved:(NSEvent*)theEvent { + if ([delegate_ respondsToSelector:@selector(mouseMoved:)]) + [id(delegate_) mouseMoved:theEvent]; +} + +- (void)mouseDragged:(NSEvent*)theEvent { + if ([delegate_ respondsToSelector:@selector(mouseDragged:)]) + [id(delegate_) mouseDragged:theEvent]; +} + + (BookmarkButton*)draggedButton { return gDraggedButton; } @@ -269,7 +361,8 @@ BookmarkButton* gDraggedButton = nil; // Weak } else { // Mouse tracked out of button during menu track. Hide menus. if (!wasInside) - [delegate_ bookmarkDragDidEnd:self]; + [delegate_ bookmarkDragDidEnd:self + operation:NSDragOperationNone]; } } @@ -277,13 +370,17 @@ BookmarkButton* gDraggedButton = nil; // Weak @implementation BookmarkButton(Private) -- (void)installCustomTrackingArea { - if (area_) - return; - NSTrackingAreaOptions options = NSTrackingActiveInActiveApp | - NSTrackingMouseEnteredAndExited | NSTrackingEnabledDuringMouseDrag | - NSTrackingInVisibleRect; +- (void)installCustomTrackingArea { + const NSTrackingAreaOptions options = + NSTrackingActiveAlways | + NSTrackingMouseEnteredAndExited | + NSTrackingEnabledDuringMouseDrag; + + if (area_) { + [self removeTrackingArea:area_]; + [area_ release]; + } area_ = [[NSTrackingArea alloc] initWithRect:[self bounds] options:options @@ -310,7 +407,7 @@ BookmarkButton* gDraggedButton = nil; // Weak // Make an autoreleased |NSImage|, which will be returned, and draw into it. // By default, the |NSImage| will be completely transparent. NSImage* dragImage = - [[[NSImage alloc] initWithSize:[bitmap size]] autorelease]; + [[[NSImage alloc] initWithSize:[bitmap size]] autorelease]; [dragImage lockFocus]; // Draw the image with the appropriate opacity, clipping it tightly. diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h index dbcff34..cce3302 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -60,6 +60,8 @@ class BookmarkNode; // Set the color of text in this cell. - (void)setTextColor:(NSColor*)color; +- (BOOL)isFolderButtonCell; + @end #endif // CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_BUTTON_CELL_H_ diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm index 129117d..0f21ed5 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm @@ -72,6 +72,10 @@ [self configureBookmarkButtonCell]; } +- (BOOL)isFolderButtonCell { + return NO; +} + // Perform all normal init routines specific to the BookmarkButtonCell. - (void)configureBookmarkButtonCell { [self setButtonType:NSMomentaryPushInButton]; @@ -145,7 +149,7 @@ const BookmarkNode* node = static_cast<const BookmarkNode*>([[self representedObject] pointerValue]); - if (node->GetParent() && node->GetParent()->type() == BookmarkNode::FOLDER) { + if (node->parent() && node->parent()->type() == BookmarkNode::FOLDER) { UserMetrics::RecordAction(UserMetricsAction("BookmarkBarFolder_CtxMenu")); } else { UserMetrics::RecordAction(UserMetricsAction("BookmarkBar_CtxMenu")); diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell_unittest.mm index 6460ebf..322036e 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell_unittest.mm @@ -1,18 +1,17 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "app/mac/nsimage_cache.h" +#include "base/memory/scoped_nsobject.h" #include "base/utf_string_conversions.h" #include "chrome/browser/bookmarks/bookmark_model.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_menu.h" #include "chrome/browser/ui/cocoa/browser_test_helper.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" -#include "grit/app_resources.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" -#include "ui/base/resource/resource_bundle.h" #include "ui/gfx/image.h" // Simple class to remember how many mouseEntered: and mouseExited: @@ -66,9 +65,8 @@ TEST_F(BookmarkButtonCellTest, IconOnlySqueeze) { [view setCell:cell.get()]; [[test_window() contentView] addSubview:view]; - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - scoped_nsobject<NSImage> image([rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON) - retain]); + scoped_nsobject<NSImage> image( + [app::mac::GetCachedImageWithName(@"nav.pdf") retain]); EXPECT_TRUE(image.get()); NSRect r = NSMakeRect(0, 0, 100, 100); @@ -160,7 +158,7 @@ TEST_F(BookmarkButtonCellTest, Awake) { TEST_F(BookmarkButtonCellTest, FolderArrow) { BookmarkModel* model = helper_.profile()->GetBookmarkModel(); const BookmarkNode* bar = model->GetBookmarkBarNode(); - const BookmarkNode* node = model->AddURL(bar, bar->GetChildCount(), + const BookmarkNode* node = model->AddURL(bar, bar->child_count(), ASCIIToUTF16("title"), GURL("http://www.google.com")); scoped_nsobject<BookmarkButtonCell> cell( diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_unittest.mm index d45132f..2f45d9e 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/utf_string_conversions.h" #include "chrome/browser/bookmarks/bookmark_model.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h" @@ -53,9 +53,9 @@ didDragToTrashCount_++; } -- (void)bookmarkDragDidEnd:(BookmarkButton*)button { +- (void)bookmarkDragDidEnd:(BookmarkButton*)button + operation:(NSDragOperation)operation { } - @end namespace { diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.h index b39953b..fa487d9 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,8 +9,8 @@ #import <Cocoa/Cocoa.h> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_ptr.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/bookmarks/bookmark_editor.h" class BookmarkEditorBaseControllerBridge; diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.mm index 329a027..7b10686 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -126,7 +126,7 @@ class BookmarkEditorBaseControllerBridge : public BookmarkModelObserver { [controller_ modelChangedPreserveSelection:YES]; } - virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, + virtual void BookmarkNodeFaviconLoaded(BookmarkModel* model, const BookmarkNode* node) { // I care nothing for these 'favicons': I only show folders. } @@ -364,7 +364,7 @@ class BookmarkEditorBaseControllerBridge : public BookmarkModelObserver { while (node != rootNode) { DCHECK(node); nodeStack.push(node); - node = node->GetParent(); + node = node->parent(); } NSUInteger stackSize = nodeStack.size(); @@ -392,7 +392,7 @@ class BookmarkEditorBaseControllerBridge : public BookmarkModelObserver { - (NSMutableArray*)addChildFoldersFromNode:(const BookmarkNode*)node { NSMutableArray* childFolders = nil; - int childCount = node->GetChildCount(); + int childCount = node->child_count(); for (int i = 0; i < childCount; ++i) { const BookmarkNode* childNode = node->GetChild(i); if (childNode->type() != BookmarkNode::URL) { @@ -463,8 +463,8 @@ class BookmarkEditorBaseControllerBridge : public BookmarkModelObserver { if ([subFolderInfo newFolder]) { BookmarkModel* model = [self bookmarkModel]; const BookmarkNode* newFolder = - model->AddGroup(parentNode, i, - base::SysNSStringToUTF16([subFolderInfo folderName])); + model->AddFolder(parentNode, i, + base::SysNSStringToUTF16([subFolderInfo folderName])); // Update our dictionary with the actual folder node just created. [subFolderInfo setFolderNode:newFolder]; [subFolderInfo setNewFolder:NO]; diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller_unittest.mm index 1df1697..bf64055 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" #include "chrome/browser/bookmarks/bookmark_model.h" @@ -21,11 +21,11 @@ class BookmarkEditorBaseControllerTest : public CocoaTest { public: BrowserTestHelper browser_helper_; BookmarkEditorBaseController* controller_; // weak - const BookmarkNode* group_a_; - const BookmarkNode* group_b_; - const BookmarkNode* group_b_0_; - const BookmarkNode* group_b_3_; - const BookmarkNode* group_c_; + const BookmarkNode* folder_a_; + const BookmarkNode* folder_b_; + const BookmarkNode* folder_b_0_; + const BookmarkNode* folder_b_3_; + const BookmarkNode* folder_c_; BookmarkEditorBaseControllerTest() { // Set up a small bookmark hierarchy, which will look as follows: @@ -40,26 +40,26 @@ class BookmarkEditorBaseControllerTest : public CocoaTest { // b-4 BookmarkModel& model(*(browser_helper_.profile()->GetBookmarkModel())); const BookmarkNode* root = model.GetBookmarkBarNode(); - group_a_ = model.AddGroup(root, 0, ASCIIToUTF16("a")); - model.AddURL(group_a_, 0, ASCIIToUTF16("a-0"), GURL("http://a-0.com")); - model.AddURL(group_a_, 1, ASCIIToUTF16("a-1"), GURL("http://a-1.com")); - model.AddURL(group_a_, 2, ASCIIToUTF16("a-2"), GURL("http://a-2.com")); - - group_b_ = model.AddGroup(root, 1, ASCIIToUTF16("b")); - group_b_0_ = model.AddGroup(group_b_, 0, ASCIIToUTF16("b-0")); - model.AddURL(group_b_0_, 0, ASCIIToUTF16("bb-0"), GURL("http://bb-0.com")); - model.AddURL(group_b_, 1, ASCIIToUTF16("b-1"), GURL("http://b-1.com")); - model.AddURL(group_b_, 2, ASCIIToUTF16("b-2"), GURL("http://b-2.com")); - group_b_3_ = model.AddGroup(group_b_, 3, ASCIIToUTF16("b-3")); - model.AddURL(group_b_3_, 0, ASCIIToUTF16("b-30"), GURL("http://b-30.com")); - model.AddURL(group_b_3_, 1, ASCIIToUTF16("b-31"), GURL("http://b-31.com")); - model.AddURL(group_b_, 4, ASCIIToUTF16("b-4"), GURL("http://b-4.com")); - - group_c_ = model.AddGroup(root, 2, ASCIIToUTF16("c")); - model.AddURL(group_c_, 0, ASCIIToUTF16("c-0"), GURL("http://c-0.com")); - model.AddURL(group_c_, 1, ASCIIToUTF16("c-1"), GURL("http://c-1.com")); - model.AddURL(group_c_, 2, ASCIIToUTF16("c-2"), GURL("http://c-2.com")); - model.AddURL(group_c_, 3, ASCIIToUTF16("c-3"), GURL("http://c-3.com")); + folder_a_ = model.AddFolder(root, 0, ASCIIToUTF16("a")); + model.AddURL(folder_a_, 0, ASCIIToUTF16("a-0"), GURL("http://a-0.com")); + model.AddURL(folder_a_, 1, ASCIIToUTF16("a-1"), GURL("http://a-1.com")); + model.AddURL(folder_a_, 2, ASCIIToUTF16("a-2"), GURL("http://a-2.com")); + + folder_b_ = model.AddFolder(root, 1, ASCIIToUTF16("b")); + folder_b_0_ = model.AddFolder(folder_b_, 0, ASCIIToUTF16("b-0")); + model.AddURL(folder_b_0_, 0, ASCIIToUTF16("bb-0"), GURL("http://bb-0.com")); + model.AddURL(folder_b_, 1, ASCIIToUTF16("b-1"), GURL("http://b-1.com")); + model.AddURL(folder_b_, 2, ASCIIToUTF16("b-2"), GURL("http://b-2.com")); + folder_b_3_ = model.AddFolder(folder_b_, 3, ASCIIToUTF16("b-3")); + model.AddURL(folder_b_3_, 0, ASCIIToUTF16("b-30"), GURL("http://b-30.com")); + model.AddURL(folder_b_3_, 1, ASCIIToUTF16("b-31"), GURL("http://b-31.com")); + model.AddURL(folder_b_, 4, ASCIIToUTF16("b-4"), GURL("http://b-4.com")); + + folder_c_ = model.AddFolder(root, 2, ASCIIToUTF16("c")); + model.AddURL(folder_c_, 0, ASCIIToUTF16("c-0"), GURL("http://c-0.com")); + model.AddURL(folder_c_, 1, ASCIIToUTF16("c-1"), GURL("http://c-1.com")); + model.AddURL(folder_c_, 2, ASCIIToUTF16("c-2"), GURL("http://c-2.com")); + model.AddURL(folder_c_, 3, ASCIIToUTF16("c-3"), GURL("http://c-3.com")); model.AddURL(root, 3, ASCIIToUTF16("d"), GURL("http://d-0.com")); } @@ -69,7 +69,7 @@ class BookmarkEditorBaseControllerTest : public CocoaTest { initWithParentWindow:test_window() nibName:@"BookmarkAllTabs" profile:browser_helper_.profile() - parent:group_b_0_ + parent:folder_b_0_ configuration:BookmarkEditor::SHOW_TREE]; } @@ -89,63 +89,63 @@ class BookmarkEditorBaseControllerTest : public CocoaTest { TEST_F(BookmarkEditorBaseControllerTest, VerifyBookmarkTestModel) { BookmarkModel& model(*(browser_helper_.profile()->GetBookmarkModel())); const BookmarkNode& root(*model.GetBookmarkBarNode()); - EXPECT_EQ(4, root.GetChildCount()); + EXPECT_EQ(4, root.child_count()); // a const BookmarkNode* child = root.GetChild(0); - EXPECT_EQ(3, child->GetChildCount()); + EXPECT_EQ(3, child->child_count()); const BookmarkNode* subchild = child->GetChild(0); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); subchild = child->GetChild(1); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); subchild = child->GetChild(2); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); // b child = root.GetChild(1); - EXPECT_EQ(5, child->GetChildCount()); + EXPECT_EQ(5, child->child_count()); subchild = child->GetChild(0); - EXPECT_EQ(1, subchild->GetChildCount()); + EXPECT_EQ(1, subchild->child_count()); const BookmarkNode* subsubchild = subchild->GetChild(0); - EXPECT_EQ(0, subsubchild->GetChildCount()); + EXPECT_EQ(0, subsubchild->child_count()); subchild = child->GetChild(1); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); subchild = child->GetChild(2); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); subchild = child->GetChild(3); - EXPECT_EQ(2, subchild->GetChildCount()); + EXPECT_EQ(2, subchild->child_count()); subsubchild = subchild->GetChild(0); - EXPECT_EQ(0, subsubchild->GetChildCount()); + EXPECT_EQ(0, subsubchild->child_count()); subsubchild = subchild->GetChild(1); - EXPECT_EQ(0, subsubchild->GetChildCount()); + EXPECT_EQ(0, subsubchild->child_count()); subchild = child->GetChild(4); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); // c child = root.GetChild(2); - EXPECT_EQ(4, child->GetChildCount()); + EXPECT_EQ(4, child->child_count()); subchild = child->GetChild(0); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); subchild = child->GetChild(1); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); subchild = child->GetChild(2); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); subchild = child->GetChild(3); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); // d child = root.GetChild(3); - EXPECT_EQ(0, child->GetChildCount()); + EXPECT_EQ(0, child->child_count()); [controller_ cancel:nil]; } TEST_F(BookmarkEditorBaseControllerTest, NodeSelection) { EXPECT_TRUE([controller_ folderTreeArray]); - [controller_ selectTestNodeInBrowser:group_b_3_]; + [controller_ selectTestNodeInBrowser:folder_b_3_]; const BookmarkNode* node = [controller_ selectedNode]; - EXPECT_EQ(node, group_b_3_); + EXPECT_EQ(node, folder_b_3_); [controller_ cancel:nil]; } TEST_F(BookmarkEditorBaseControllerTest, CreateFolder) { - EXPECT_EQ(2, group_b_3_->GetChildCount()); - [controller_ selectTestNodeInBrowser:group_b_3_]; + EXPECT_EQ(2, folder_b_3_->child_count()); + [controller_ selectTestNodeInBrowser:folder_b_3_]; NSString* expectedName = l10n_util::GetNSStringWithFixup(IDS_BOOMARK_EDITOR_NEW_FOLDER_NAME); [controller_ setDisplayName:expectedName]; @@ -160,7 +160,7 @@ TEST_F(BookmarkEditorBaseControllerTest, CreateFolder) { EXPECT_NSEQ(expectedName, newFolderName); [controller_ createNewFolders]; // Verify that the tab folder was added to the new folder. - EXPECT_EQ(3, group_b_3_->GetChildCount()); + EXPECT_EQ(3, folder_b_3_->child_count()); [controller_ cancel:nil]; } @@ -180,12 +180,12 @@ TEST_F(BookmarkEditorBaseControllerTest, CreateTwoFolders) { TEST_F(BookmarkEditorBaseControllerTest, SelectedFolderDeleted) { BookmarkModel& model(*(browser_helper_.profile()->GetBookmarkModel())); - [controller_ selectTestNodeInBrowser:group_b_3_]; - EXPECT_EQ(group_b_3_, [controller_ selectedNode]); + [controller_ selectTestNodeInBrowser:folder_b_3_]; + EXPECT_EQ(folder_b_3_, [controller_ selectedNode]); // Delete the selected node, and verify it's no longer selected: - model.Remove(group_b_, 3); - EXPECT_NE(group_b_3_, [controller_ selectedNode]); + model.Remove(folder_b_, 3); + EXPECT_NE(folder_b_3_, [controller_ selectedNode]); [controller_ cancel:nil]; } @@ -193,12 +193,12 @@ TEST_F(BookmarkEditorBaseControllerTest, SelectedFolderDeleted) { TEST_F(BookmarkEditorBaseControllerTest, SelectedFoldersParentDeleted) { BookmarkModel& model(*(browser_helper_.profile()->GetBookmarkModel())); const BookmarkNode* root = model.GetBookmarkBarNode(); - [controller_ selectTestNodeInBrowser:group_b_3_]; - EXPECT_EQ(group_b_3_, [controller_ selectedNode]); + [controller_ selectTestNodeInBrowser:folder_b_3_]; + EXPECT_EQ(folder_b_3_, [controller_ selectedNode]); // Delete the selected node's parent, and verify it's no longer selected: model.Remove(root, 1); - EXPECT_NE(group_b_3_, [controller_ selectedNode]); + EXPECT_NE(folder_b_3_, [controller_ selectedNode]); [controller_ cancel:nil]; } @@ -207,11 +207,11 @@ TEST_F(BookmarkEditorBaseControllerTest, FolderAdded) { BookmarkModel& model(*(browser_helper_.profile()->GetBookmarkModel())); const BookmarkNode* root = model.GetBookmarkBarNode(); - // Add a group node to the model, and verify it can be selected in the tree: - const BookmarkNode* group_added = model.AddGroup(root, 0, - ASCIIToUTF16("added")); - [controller_ selectTestNodeInBrowser:group_added]; - EXPECT_EQ(group_added, [controller_ selectedNode]); + // Add a folder node to the model, and verify it can be selected in the tree: + const BookmarkNode* folder_added = model.AddFolder( + root, 0, ASCIIToUTF16("added")); + [controller_ selectTestNodeInBrowser:folder_added]; + EXPECT_EQ(folder_added, [controller_ selectedNode]); [controller_ cancel:nil]; } diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.mm index 557150f..c320e9c 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -126,10 +126,10 @@ model->SetTitle(node_, newTitle); const BookmarkNode* oldParentNode = [self parentNode]; if (newParentNode != oldParentNode) - model->Move(node_, newParentNode, newParentNode->GetChildCount()); + model->Move(node_, newParentNode, newParentNode->child_count()); } else { // Otherwise, add a new bookmark at the end of the newly selected folder. - model->AddURL(newParentNode, newParentNode->GetChildCount(), newTitle, + model->AddURL(newParentNode, newParentNode->child_count(), newTitle, newURL); } return [NSNumber numberWithBool:YES]; diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller_unittest.mm index be2007b..a930b72 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller_unittest.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -50,7 +50,7 @@ class BookmarkEditorControllerTest : public CocoaTest { TEST_F(BookmarkEditorControllerTest, NoEdit) { [controller_ cancel:nil]; - ASSERT_EQ(default_parent_->GetChildCount(), 1); + ASSERT_EQ(default_parent_->child_count(), 1); const BookmarkNode* child = default_parent_->GetChild(0); EXPECT_EQ(child->GetTitle(), default_title_); EXPECT_EQ(child->GetURL(), GURL(default_name_)); @@ -59,7 +59,7 @@ TEST_F(BookmarkEditorControllerTest, NoEdit) { TEST_F(BookmarkEditorControllerTest, EditTitle) { [controller_ setDisplayName:@"whamma jamma bamma"]; [controller_ ok:nil]; - ASSERT_EQ(default_parent_->GetChildCount(), 1); + ASSERT_EQ(default_parent_->child_count(), 1); const BookmarkNode* child = default_parent_->GetChild(0); EXPECT_EQ(child->GetTitle(), ASCIIToUTF16("whamma jamma bamma")); EXPECT_EQ(child->GetURL(), GURL(default_name_)); @@ -70,7 +70,7 @@ TEST_F(BookmarkEditorControllerTest, EditURL) { [controller_ setDisplayURL:@"http://yellow-sneakers.com/"]; EXPECT_TRUE([controller_ okButtonEnabled]); [controller_ ok:nil]; - ASSERT_EQ(default_parent_->GetChildCount(), 1); + ASSERT_EQ(default_parent_->child_count(), 1); const BookmarkNode* child = default_parent_->GetChild(0); EXPECT_EQ(child->GetTitle(), default_title_); EXPECT_EQ(child->GetURL(), GURL("http://yellow-sneakers.com/")); @@ -79,7 +79,7 @@ TEST_F(BookmarkEditorControllerTest, EditURL) { TEST_F(BookmarkEditorControllerTest, EditAndFixPrefix) { [controller_ setDisplayURL:@"x"]; [controller_ ok:nil]; - ASSERT_EQ(default_parent_->GetChildCount(), 1); + ASSERT_EQ(default_parent_->child_count(), 1); const BookmarkNode* child = default_parent_->GetChild(0); EXPECT_TRUE(child->GetURL().is_valid()); } @@ -207,10 +207,10 @@ class BookmarkEditorControllerTreeTest : public CocoaTest { public: BrowserTestHelper browser_helper_; BookmarkEditorController* controller_; - const BookmarkNode* group_a_; - const BookmarkNode* group_b_; - const BookmarkNode* group_bb_; - const BookmarkNode* group_c_; + const BookmarkNode* folder_a_; + const BookmarkNode* folder_b_; + const BookmarkNode* folder_bb_; + const BookmarkNode* folder_c_; const BookmarkNode* bookmark_bb_3_; GURL bb3_url_1_; GURL bb3_url_2_; @@ -228,34 +228,34 @@ class BookmarkEditorControllerTreeTest : public CocoaTest { // b-2 BookmarkModel& model(*(browser_helper_.profile()->GetBookmarkModel())); const BookmarkNode* root = model.GetBookmarkBarNode(); - group_a_ = model.AddGroup(root, 0, ASCIIToUTF16("a")); - model.AddURL(group_a_, 0, ASCIIToUTF16("a-0"), GURL("http://a-0.com")); - model.AddURL(group_a_, 1, ASCIIToUTF16("a-1"), GURL("http://a-1.com")); - model.AddURL(group_a_, 2, ASCIIToUTF16("a-2"), GURL("http://a-2.com")); - - group_b_ = model.AddGroup(root, 1, ASCIIToUTF16("b")); - model.AddURL(group_b_, 0, ASCIIToUTF16("b-0"), GURL("http://b-0.com")); - group_bb_ = model.AddGroup(group_b_, 1, ASCIIToUTF16("bb")); - model.AddURL(group_bb_, 0, ASCIIToUTF16("bb-0"), GURL("http://bb-0.com")); - model.AddURL(group_bb_, 1, ASCIIToUTF16("bb-1"), GURL("http://bb-1.com")); - model.AddURL(group_bb_, 2, ASCIIToUTF16("bb-2"), GURL("http://bb-2.com")); + folder_a_ = model.AddFolder(root, 0, ASCIIToUTF16("a")); + model.AddURL(folder_a_, 0, ASCIIToUTF16("a-0"), GURL("http://a-0.com")); + model.AddURL(folder_a_, 1, ASCIIToUTF16("a-1"), GURL("http://a-1.com")); + model.AddURL(folder_a_, 2, ASCIIToUTF16("a-2"), GURL("http://a-2.com")); + + folder_b_ = model.AddFolder(root, 1, ASCIIToUTF16("b")); + model.AddURL(folder_b_, 0, ASCIIToUTF16("b-0"), GURL("http://b-0.com")); + folder_bb_ = model.AddFolder(folder_b_, 1, ASCIIToUTF16("bb")); + model.AddURL(folder_bb_, 0, ASCIIToUTF16("bb-0"), GURL("http://bb-0.com")); + model.AddURL(folder_bb_, 1, ASCIIToUTF16("bb-1"), GURL("http://bb-1.com")); + model.AddURL(folder_bb_, 2, ASCIIToUTF16("bb-2"), GURL("http://bb-2.com")); // To find it later, this bookmark name must always have a URL // of http://bb-3.com or https://bb-3.com bb3_url_1_ = GURL("http://bb-3.com"); bb3_url_2_ = GURL("https://bb-3.com"); - bookmark_bb_3_ = model.AddURL(group_bb_, 3, ASCIIToUTF16("bb-3"), + bookmark_bb_3_ = model.AddURL(folder_bb_, 3, ASCIIToUTF16("bb-3"), bb3_url_1_); - model.AddURL(group_bb_, 4, ASCIIToUTF16("bb-4"), GURL("http://bb-4.com")); - model.AddURL(group_b_, 2, ASCIIToUTF16("b-1"), GURL("http://b-2.com")); - model.AddURL(group_b_, 3, ASCIIToUTF16("b-2"), GURL("http://b-3.com")); + model.AddURL(folder_bb_, 4, ASCIIToUTF16("bb-4"), GURL("http://bb-4.com")); + model.AddURL(folder_b_, 2, ASCIIToUTF16("b-1"), GURL("http://b-2.com")); + model.AddURL(folder_b_, 3, ASCIIToUTF16("b-2"), GURL("http://b-3.com")); - group_c_ = model.AddGroup(root, 2, ASCIIToUTF16("c")); - model.AddURL(group_c_, 0, ASCIIToUTF16("c-0"), GURL("http://c-0.com")); - model.AddURL(group_c_, 1, ASCIIToUTF16("c-1"), GURL("http://c-1.com")); - model.AddURL(group_c_, 2, ASCIIToUTF16("c-2"), GURL("http://c-2.com")); - model.AddURL(group_c_, 3, ASCIIToUTF16("c-3"), GURL("http://c-3.com")); + folder_c_ = model.AddFolder(root, 2, ASCIIToUTF16("c")); + model.AddURL(folder_c_, 0, ASCIIToUTF16("c-0"), GURL("http://c-0.com")); + model.AddURL(folder_c_, 1, ASCIIToUTF16("c-1"), GURL("http://c-1.com")); + model.AddURL(folder_c_, 2, ASCIIToUTF16("c-2"), GURL("http://c-2.com")); + model.AddURL(folder_c_, 3, ASCIIToUTF16("c-3"), GURL("http://c-3.com")); model.AddURL(root, 3, ASCIIToUTF16("d"), GURL("http://d-0.com")); } @@ -264,7 +264,7 @@ class BookmarkEditorControllerTreeTest : public CocoaTest { return [[BookmarkEditorController alloc] initWithParentWindow:test_window() profile:browser_helper_.profile() - parent:group_bb_ + parent:folder_bb_ node:bookmark_bb_3_ configuration:BookmarkEditor::SHOW_TREE]; } @@ -300,102 +300,102 @@ TEST_F(BookmarkEditorControllerTreeTest, VerifyBookmarkTestModel) { BookmarkModel& model(*(browser_helper_.profile()->GetBookmarkModel())); model.root_node(); const BookmarkNode& root(*model.GetBookmarkBarNode()); - EXPECT_EQ(4, root.GetChildCount()); + EXPECT_EQ(4, root.child_count()); const BookmarkNode* child = root.GetChild(0); - EXPECT_EQ(3, child->GetChildCount()); + EXPECT_EQ(3, child->child_count()); const BookmarkNode* subchild = child->GetChild(0); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); subchild = child->GetChild(1); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); subchild = child->GetChild(2); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); child = root.GetChild(1); - EXPECT_EQ(4, child->GetChildCount()); + EXPECT_EQ(4, child->child_count()); subchild = child->GetChild(0); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); subchild = child->GetChild(1); - EXPECT_EQ(5, subchild->GetChildCount()); + EXPECT_EQ(5, subchild->child_count()); const BookmarkNode* subsubchild = subchild->GetChild(0); - EXPECT_EQ(0, subsubchild->GetChildCount()); + EXPECT_EQ(0, subsubchild->child_count()); subsubchild = subchild->GetChild(1); - EXPECT_EQ(0, subsubchild->GetChildCount()); + EXPECT_EQ(0, subsubchild->child_count()); subsubchild = subchild->GetChild(2); - EXPECT_EQ(0, subsubchild->GetChildCount()); + EXPECT_EQ(0, subsubchild->child_count()); subsubchild = subchild->GetChild(3); - EXPECT_EQ(0, subsubchild->GetChildCount()); + EXPECT_EQ(0, subsubchild->child_count()); subsubchild = subchild->GetChild(4); - EXPECT_EQ(0, subsubchild->GetChildCount()); + EXPECT_EQ(0, subsubchild->child_count()); subchild = child->GetChild(2); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); subchild = child->GetChild(3); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); child = root.GetChild(2); - EXPECT_EQ(4, child->GetChildCount()); + EXPECT_EQ(4, child->child_count()); subchild = child->GetChild(0); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); subchild = child->GetChild(1); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); subchild = child->GetChild(2); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); subchild = child->GetChild(3); - EXPECT_EQ(0, subchild->GetChildCount()); + EXPECT_EQ(0, subchild->child_count()); child = root.GetChild(3); - EXPECT_EQ(0, child->GetChildCount()); + EXPECT_EQ(0, child->child_count()); [controller_ cancel:nil]; } TEST_F(BookmarkEditorControllerTreeTest, RenameBookmarkInPlace) { - const BookmarkNode* oldParent = bookmark_bb_3_->GetParent(); + const BookmarkNode* oldParent = bookmark_bb_3_->parent(); [controller_ setDisplayName:@"NEW NAME"]; [controller_ ok:nil]; UpdateBB3(); - const BookmarkNode* newParent = bookmark_bb_3_->GetParent(); + const BookmarkNode* newParent = bookmark_bb_3_->parent(); ASSERT_EQ(newParent, oldParent); - int childIndex = newParent->IndexOfChild(bookmark_bb_3_); + int childIndex = newParent->GetIndexOf(bookmark_bb_3_); ASSERT_EQ(3, childIndex); } TEST_F(BookmarkEditorControllerTreeTest, ChangeBookmarkURLInPlace) { - const BookmarkNode* oldParent = bookmark_bb_3_->GetParent(); + const BookmarkNode* oldParent = bookmark_bb_3_->parent(); [controller_ setDisplayURL:@"https://bb-3.com"]; [controller_ ok:nil]; UpdateBB3(); - const BookmarkNode* newParent = bookmark_bb_3_->GetParent(); + const BookmarkNode* newParent = bookmark_bb_3_->parent(); ASSERT_EQ(newParent, oldParent); - int childIndex = newParent->IndexOfChild(bookmark_bb_3_); + int childIndex = newParent->GetIndexOf(bookmark_bb_3_); ASSERT_EQ(3, childIndex); } -TEST_F(BookmarkEditorControllerTreeTest, ChangeBookmarkGroup) { - [controller_ selectTestNodeInBrowser:group_c_]; +TEST_F(BookmarkEditorControllerTreeTest, ChangeBookmarkFolder) { + [controller_ selectTestNodeInBrowser:folder_c_]; [controller_ ok:nil]; UpdateBB3(); - const BookmarkNode* parent = bookmark_bb_3_->GetParent(); - ASSERT_EQ(parent, group_c_); - int childIndex = parent->IndexOfChild(bookmark_bb_3_); + const BookmarkNode* parent = bookmark_bb_3_->parent(); + ASSERT_EQ(parent, folder_c_); + int childIndex = parent->GetIndexOf(bookmark_bb_3_); ASSERT_EQ(4, childIndex); } -TEST_F(BookmarkEditorControllerTreeTest, ChangeNameAndBookmarkGroup) { +TEST_F(BookmarkEditorControllerTreeTest, ChangeNameAndBookmarkFolder) { [controller_ setDisplayName:@"NEW NAME"]; - [controller_ selectTestNodeInBrowser:group_c_]; + [controller_ selectTestNodeInBrowser:folder_c_]; [controller_ ok:nil]; UpdateBB3(); - const BookmarkNode* parent = bookmark_bb_3_->GetParent(); - ASSERT_EQ(parent, group_c_); - int childIndex = parent->IndexOfChild(bookmark_bb_3_); + const BookmarkNode* parent = bookmark_bb_3_->parent(); + ASSERT_EQ(parent, folder_c_); + int childIndex = parent->GetIndexOf(bookmark_bb_3_); ASSERT_EQ(4, childIndex); EXPECT_EQ(bookmark_bb_3_->GetTitle(), ASCIIToUTF16("NEW NAME")); } -TEST_F(BookmarkEditorControllerTreeTest, AddFolderWithGroupSelected) { +TEST_F(BookmarkEditorControllerTreeTest, AddFolderWithFolderSelected) { // Folders are NOT added unless the OK button is pressed. [controller_ newFolder:nil]; [controller_ cancel:nil]; - EXPECT_EQ(5, group_bb_->GetChildCount()); + EXPECT_EQ(5, folder_bb_->child_count()); } class BookmarkEditorControllerTreeNoNodeTest : @@ -405,7 +405,7 @@ class BookmarkEditorControllerTreeNoNodeTest : return [[BookmarkEditorController alloc] initWithParentWindow:test_window() profile:browser_helper_.profile() - parent:group_bb_ + parent:folder_bb_ node:nil configuration:BookmarkEditor::SHOW_TREE]; } @@ -416,8 +416,8 @@ TEST_F(BookmarkEditorControllerTreeNoNodeTest, NewBookmarkNoNode) { [controller_ setDisplayName:@"NEW BOOKMARK"]; [controller_ setDisplayURL:@"http://NEWURL.com"]; [controller_ ok:nil]; - const BookmarkNode* new_node = group_bb_->GetChild(5); - ASSERT_EQ(0, new_node->GetChildCount()); + const BookmarkNode* new_node = folder_bb_->GetChild(5); + ASSERT_EQ(0, new_node->child_count()); EXPECT_EQ(new_node->GetTitle(), ASCIIToUTF16("NEW BOOKMARK")); EXPECT_EQ(new_node->GetURL(), GURL("http://NEWURL.com")); } diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h index 37a4a2c..5b80b48 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -23,7 +23,7 @@ #include <map> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/browser/bookmarks/bookmark_model_observer.h" class BookmarkNode; @@ -55,7 +55,7 @@ class BookmarkMenuBridge : public BookmarkModelObserver { const BookmarkNode* node); virtual void BookmarkNodeChanged(BookmarkModel* model, const BookmarkNode* node); - virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, + virtual void BookmarkNodeFaviconLoaded(BookmarkModel* model, const BookmarkNode* node); virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, const BookmarkNode* node); diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm index 339e94c..a5bfc5d 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -63,7 +63,7 @@ void BookmarkMenuBridge::UpdateMenu(NSMenu* bookmark_menu) { // Add bookmark bar items, if any. const BookmarkNode* barNode = model->GetBookmarkBarNode(); CHECK(barNode); - if (barNode->GetChildCount()) { + if (barNode->child_count()) { [bookmark_menu addItem:[NSMenuItem separatorItem]]; AddNodeToMenu(barNode, bookmark_menu); } @@ -115,7 +115,7 @@ void BookmarkMenuBridge::BookmarkNodeChanged(BookmarkModel* model, ConfigureMenuItem(node, item, true); } -void BookmarkMenuBridge::BookmarkNodeFavIconLoaded(BookmarkModel* model, +void BookmarkMenuBridge::BookmarkNodeFaviconLoaded(BookmarkModel* model, const BookmarkNode* node) { NSMenuItem* item = MenuItemForNode(node); if (item) @@ -187,7 +187,7 @@ void BookmarkMenuBridge::AddNodeAsSubmenu(NSMenu* menu, // TODO(jrg): limit the number of bookmarks in the menubar? void BookmarkMenuBridge::AddNodeToMenu(const BookmarkNode* node, NSMenu* menu) { - int child_count = node->GetChildCount(); + int child_count = node->child_count(); if (!child_count) { NSString* empty_string = l10n_util::GetNSString(IDS_MENU_EMPTY_SUBMENU); NSMenuItem* item = [[[NSMenuItem alloc] initWithTitle:empty_string @@ -275,7 +275,7 @@ void BookmarkMenuBridge::ConfigureMenuItem(const BookmarkNode* node, NSImage* favicon = nil; BookmarkModel* model = GetBookmarkModel(); if (model) { - const SkBitmap& bitmap = model->GetFavIcon(node); + const SkBitmap& bitmap = model->GetFavicon(node); if (!bitmap.isNull()) favicon = gfx::SkBitmapToNSImage(bitmap); } diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm index c4ea6a6..caad0f6 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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 <AppKit/AppKit.h> -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #include "base/string16.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" @@ -181,7 +181,7 @@ TEST_F(BookmarkMenuBridgeTest, TestAddNodeToMenu) { model->AddURL(root, 0, ASCIIToUTF16(short_url), GURL(short_url)); bridge_->UpdateMenu(menu); int prev_count = [menu numberOfItems] - 1; // "extras" added at this point - node = model->AddGroup(root, 1, empty); + node = model->AddFolder(root, 1, empty); model->AddURL(root, 2, ASCIIToUTF16(long_url), GURL(long_url)); // And the submenu fo the middle one @@ -310,7 +310,7 @@ TEST_F(BookmarkMenuBridgeTest, TestGetMenuItemForNode) { BookmarkModel* model = bridge_->GetBookmarkModel(); const BookmarkNode* bookmark_bar = model->GetBookmarkBarNode(); - const BookmarkNode* root = model->AddGroup(bookmark_bar, 0, empty); + const BookmarkNode* root = model->AddFolder(bookmark_bar, 0, empty); EXPECT_TRUE(model && root); model->AddURL(root, 0, ASCIIToUTF16("Test Item"), GURL("http://test")); @@ -323,9 +323,9 @@ TEST_F(BookmarkMenuBridgeTest, TestGetMenuItemForNode) { EXPECT_TRUE(MenuItemForNode(bridge_.get(), root->GetChild(1))); const BookmarkNode* removed_node = root->GetChild(0); - EXPECT_EQ(2, root->GetChildCount()); + EXPECT_EQ(2, root->child_count()); model->Remove(root, 0); - EXPECT_EQ(1, root->GetChildCount()); + EXPECT_EQ(1, root->child_count()); bridge_->UpdateMenu(menu); EXPECT_FALSE(MenuItemForNode(bridge_.get(), removed_node)); EXPECT_TRUE(MenuItemForNode(bridge_.get(), root->GetChild(0))); @@ -355,7 +355,7 @@ TEST_F(BookmarkMenuBridgeTest, TestAddNodeToOther) { EXPECT_NSEQ(@"http://foo/", [[[other submenu] itemAtIndex:0] title]); } -TEST_F(BookmarkMenuBridgeTest, TestFavIconLoading) { +TEST_F(BookmarkMenuBridgeTest, TestFaviconLoading) { NSMenu* menu = bridge_->menu_; BookmarkModel* model = bridge_->GetBookmarkModel(); @@ -369,7 +369,7 @@ TEST_F(BookmarkMenuBridgeTest, TestFavIconLoading) { NSMenuItem* item = [menu itemWithTitle:@"Test Item"]; EXPECT_TRUE([item image]); [item setImage:nil]; - bridge_->BookmarkNodeFavIconLoaded(model, node); + bridge_->BookmarkNodeFaviconLoaded(model, node); EXPECT_TRUE([item image]); } diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_unittest.mm index ef251b0..cf444db 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_menu.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h index 9061132..7868a69 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -23,7 +23,7 @@ #import <Cocoa/Cocoa.h> #include "base/basictypes.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/bookmarks/bookmark_model_observer.h" @@ -66,7 +66,7 @@ class BookmarkModelObserverForCocoa : public BookmarkModelObserver { const BookmarkNode* parent, int index) { } - virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, + virtual void BookmarkNodeFaviconLoaded(BookmarkModel* model, const BookmarkNode* node) { } virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa_unittest.mm index 5ff8687..418ad2c 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa_unittest.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_ptr.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "base/utf_string_conversions.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h" #import "chrome/browser/ui/cocoa/browser_test_helper.h" @@ -61,7 +61,7 @@ TEST_F(BookmarkModelObserverForCocoaTest, TestCallback) { model->Move(node, model->other_node(), 0); EXPECT_EQ(3, pingCount.get()->pings); - model->Remove(node->GetParent(), 0); + model->Remove(node->parent(), 0); EXPECT_EQ(4, pingCount.get()->pings); } diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.h index 40f1cb1..1b95d4b 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,8 +8,8 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/bookmarks/bookmark_model.h" class BookmarkModelObserverForCocoa; diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.mm index fa369a2..e988c56 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -30,7 +30,7 @@ parent_ = parent; newIndex_ = newIndex; if (parent) { - DCHECK_LE(newIndex, parent->GetChildCount()); + DCHECK_LE(newIndex, parent->child_count()); } if (node_) { initialName_.reset([base::SysUTF16ToNSString(node_->GetTitle()) retain]); @@ -93,9 +93,9 @@ if (node_) { model->SetTitle(node_, base::SysNSStringToUTF16(name)); } else { - model->AddGroup(parent_, - newIndex_, - base::SysNSStringToUTF16(name)); + model->AddFolder(parent_, + newIndex_, + base::SysNSStringToUTF16(name)); } [NSApp endSheet:[self window]]; } diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller_unittest.mm index 69fb939..99ace46 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/utf_string_conversions.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.h" #include "chrome/browser/ui/cocoa/browser_test_helper.h" @@ -23,7 +23,7 @@ class BookmarkNameFolderControllerTest : public CocoaTest { TEST_F(BookmarkNameFolderControllerTest, AddNew) { BookmarkModel* model = helper_.profile()->GetBookmarkModel(); const BookmarkNode* parent = model->GetBookmarkBarNode(); - EXPECT_EQ(0, parent->GetChildCount()); + EXPECT_EQ(0, parent->child_count()); scoped_nsobject<BookmarkNameFolderController> controller([[BookmarkNameFolderController alloc] @@ -35,16 +35,16 @@ TEST_F(BookmarkNameFolderControllerTest, AddNew) { // Do nothing. [controller cancel:nil]; - EXPECT_EQ(0, parent->GetChildCount()); + EXPECT_EQ(0, parent->child_count()); // Change name then cancel. [controller setFolderName:@"Bozo"]; [controller cancel:nil]; - EXPECT_EQ(0, parent->GetChildCount()); + EXPECT_EQ(0, parent->child_count()); // Add a new folder. [controller ok:nil]; - EXPECT_EQ(1, parent->GetChildCount()); + EXPECT_EQ(1, parent->child_count()); EXPECT_TRUE(parent->GetChild(0)->is_folder()); EXPECT_EQ(ASCIIToUTF16("Bozo"), parent->GetChild(0)->GetTitle()); } @@ -59,7 +59,7 @@ TEST_F(BookmarkNameFolderControllerTest, AddNewWithSibling) { GURL("http://www.google.com")); model->AddURL(parent, 1, ASCIIToUTF16("title 3"), GURL("http://www.google.com")); - EXPECT_EQ(2, parent->GetChildCount()); + EXPECT_EQ(2, parent->child_count()); scoped_nsobject<BookmarkNameFolderController> controller([[BookmarkNameFolderController alloc] @@ -74,7 +74,7 @@ TEST_F(BookmarkNameFolderControllerTest, AddNewWithSibling) { [controller ok:nil]; // Confirm we now have 3, and that the new one is in the middle. - EXPECT_EQ(3, parent->GetChildCount()); + EXPECT_EQ(3, parent->child_count()); EXPECT_TRUE(parent->GetChild(1)->is_folder()); EXPECT_EQ(ASCIIToUTF16("middle"), parent->GetChild(1)->GetTitle()); } @@ -83,7 +83,7 @@ TEST_F(BookmarkNameFolderControllerTest, AddNewWithSibling) { TEST_F(BookmarkNameFolderControllerTest, AddNewDefaultName) { BookmarkModel* model = helper_.profile()->GetBookmarkModel(); const BookmarkNode* parent = model->GetBookmarkBarNode(); - EXPECT_EQ(0, parent->GetChildCount()); + EXPECT_EQ(0, parent->child_count()); scoped_nsobject<BookmarkNameFolderController> controller([[BookmarkNameFolderController alloc] @@ -96,7 +96,7 @@ TEST_F(BookmarkNameFolderControllerTest, AddNewDefaultName) { // Click OK without changing the name [controller ok:nil]; - EXPECT_EQ(1, parent->GetChildCount()); + EXPECT_EQ(1, parent->child_count()); EXPECT_TRUE(parent->GetChild(0)->is_folder()); } @@ -104,7 +104,7 @@ TEST_F(BookmarkNameFolderControllerTest, AddNewDefaultName) { TEST_F(BookmarkNameFolderControllerTest, AddNewBlankName) { BookmarkModel* model = helper_.profile()->GetBookmarkModel(); const BookmarkNode* parent = model->GetBookmarkBarNode(); - EXPECT_EQ(0, parent->GetChildCount()); + EXPECT_EQ(0, parent->child_count()); scoped_nsobject<BookmarkNameFolderController> controller([[BookmarkNameFolderController alloc] @@ -117,16 +117,16 @@ TEST_F(BookmarkNameFolderControllerTest, AddNewBlankName) { // Change the name to blank, click OK. [controller setFolderName:@""]; [controller ok:nil]; - EXPECT_EQ(1, parent->GetChildCount()); + EXPECT_EQ(1, parent->child_count()); EXPECT_TRUE(parent->GetChild(0)->is_folder()); } TEST_F(BookmarkNameFolderControllerTest, Rename) { BookmarkModel* model = helper_.profile()->GetBookmarkModel(); const BookmarkNode* parent = model->GetBookmarkBarNode(); - const BookmarkNode* folder = model->AddGroup(parent, - parent->GetChildCount(), - ASCIIToUTF16("group")); + const BookmarkNode* folder = model->AddFolder(parent, + parent->child_count(), + ASCIIToUTF16("folder")); // Rename the folder by creating a controller that originates from // the node. @@ -137,10 +137,10 @@ TEST_F(BookmarkNameFolderControllerTest, Rename) { node:folder]); [controller window]; // force nib load - EXPECT_NSEQ(@"group", [controller folderName]); + EXPECT_NSEQ(@"folder", [controller folderName]); [controller setFolderName:@"Zobo"]; [controller ok:nil]; - EXPECT_EQ(1, parent->GetChildCount()); + EXPECT_EQ(1, parent->child_count()); EXPECT_TRUE(parent->GetChild(0)->is_folder()); EXPECT_EQ(ASCIIToUTF16("Zobo"), parent->GetChild(0)->GetTitle()); } @@ -148,7 +148,7 @@ TEST_F(BookmarkNameFolderControllerTest, Rename) { TEST_F(BookmarkNameFolderControllerTest, EditAndConfirmOKButton) { BookmarkModel* model = helper_.profile()->GetBookmarkModel(); const BookmarkNode* parent = model->GetBookmarkBarNode(); - EXPECT_EQ(0, parent->GetChildCount()); + EXPECT_EQ(0, parent->child_count()); scoped_nsobject<BookmarkNameFolderController> controller([[BookmarkNameFolderController alloc] diff --git a/chrome/browser/ui/cocoa/browser_frame_view.h b/chrome/browser/ui/cocoa/browser_frame_view.h index 42faa9b..1d5a095 100644 --- a/chrome/browser/ui/cocoa/browser_frame_view.h +++ b/chrome/browser/ui/cocoa/browser_frame_view.h @@ -1,13 +1,11 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> // BrowserFrameView is a class whose methods we swizzle into NSGrayFrame -// (an AppKit framework class) so that we can support custom frame drawing, and -// have the ability to move our window widgets (close, zoom, miniaturize) where -// we want them. +// (an AppKit framework class) so that we can support custom frame drawing. // This class is never to be instantiated on its own. // We explored a variety of ways to support custom frame drawing and custom // window widgets. @@ -20,8 +18,6 @@ // c) We had to be able to support "transparent" themes, so that you could see // through to the underlying windows in places without the system theme // getting in the way. -// d) We had to support having the custom window controls moved down by a couple -// of pixels and rollovers, accessibility, etc. all had to work. // // Since we want "A" we couldn't just do a transparent borderless window. At // least I couldn't find the right combination of HITheme calls to make it draw @@ -30,9 +26,6 @@ // "C" precluded us from inserting a view between the system frame and the // the content frame in Z order. To get the transparency we actually need to // replace the drawing of the system frame. -// "D" required us to override _mouseInGroup to get our custom widget rollovers -// drawing correctly. The widgets call _mouseInGroup on their superview to -// decide whether they should draw in highlight mode or not. // "B" precluded us from just setting a background color on the window. // // Originally we tried overriding the private API +frameViewForStyleMask: to @@ -43,8 +36,7 @@ // class is NOT an instance of NSGrayView (as opposed to a subclass of // NSGrayView) then the system drawing will not work correctly. // -// Given all of the above, we found swizzling drawRect, and adding an -// implementation of _mouseInGroup and updateTrackingAreas, in _load to be the +// Given all of the above, we found swizzling drawRect in _load to be the // easiest and safest method of achieving our goals. We do the best we can to // check that everything is safe, and attempt to fallback gracefully if it is // not. diff --git a/chrome/browser/ui/cocoa/browser_frame_view.mm b/chrome/browser/ui/cocoa/browser_frame_view.mm index 4b6980b..fd661fe 100644 --- a/chrome/browser/ui/cocoa/browser_frame_view.mm +++ b/chrome/browser/ui/cocoa/browser_frame_view.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,7 +9,7 @@ #include "base/logging.h" #include "base/mac/scoped_nsautorelease_pool.h" -#import "chrome/browser/themes/browser_theme_provider.h" +#import "chrome/browser/themes/theme_service.h" #import "chrome/browser/ui/cocoa/framed_browser_window.h" #import "chrome/browser/ui/cocoa/themed_window.h" #include "grit/theme_resources.h" @@ -22,8 +22,6 @@ static BOOL gCanGetCornerRadius = NO; @interface NSView (Swizzles) - (void)drawRectOriginal:(NSRect)rect; -- (BOOL)_mouseInGroup:(NSButton*)widget; -- (void)updateTrackingAreas; - (NSUInteger)_shadowFlagsOriginal; @end @@ -71,27 +69,6 @@ static BOOL gCanGetCornerRadius = NO; } } - // Add _mouseInGroup. - m0 = class_getInstanceMethod([self class], @selector(_mouseInGroup:)); - DCHECK(m0); - if (m0) { - BOOL didAdd = class_addMethod(grayFrameClass, - @selector(_mouseInGroup:), - method_getImplementation(m0), - method_getTypeEncoding(m0)); - DCHECK(didAdd); - } - // Add updateTrackingArea. - m0 = class_getInstanceMethod([self class], @selector(updateTrackingAreas)); - DCHECK(m0); - if (m0) { - BOOL didAdd = class_addMethod(grayFrameClass, - @selector(updateTrackingAreas), - method_getImplementation(m0), - method_getTypeEncoding(m0)); - DCHECK(didAdd); - } - gCanDrawTitle = [grayFrameClass instancesRespondToSelector:@selector(_titlebarTitleRect)] && @@ -248,8 +225,8 @@ static BOOL gCanGetCornerRadius = NO; NSGradient* gradient = nil; if (!themeImageColor && incognito) gradient = themeProvider->GetNSGradient( - active ? BrowserThemeProvider::GRADIENT_FRAME_INCOGNITO : - BrowserThemeProvider::GRADIENT_FRAME_INCOGNITO_INACTIVE); + active ? ThemeService::GRADIENT_FRAME_INCOGNITO : + ThemeService::GRADIENT_FRAME_INCOGNITO_INACTIVE); BOOL themed = NO; if (themeImageColor) { @@ -336,10 +313,10 @@ static BOOL gCanGetCornerRadius = NO; NSColor* titleColor = nil; if (popup && active) { titleColor = themeProvider->GetNSColor( - BrowserThemeProvider::COLOR_TAB_TEXT, false); + ThemeService::COLOR_TAB_TEXT, false); } else if (popup && !active) { titleColor = themeProvider->GetNSColor( - BrowserThemeProvider::COLOR_BACKGROUND_TAB_TEXT, false); + ThemeService::COLOR_BACKGROUND_TAB_TEXT, false); } if (titleColor) @@ -351,29 +328,6 @@ static BOOL gCanGetCornerRadius = NO; return [NSColor windowFrameTextColor]; } -// Check to see if the mouse is currently in one of our window widgets. -- (BOOL)_mouseInGroup:(NSButton*)widget { - BOOL mouseInGroup = NO; - if ([[self window] isKindOfClass:[FramedBrowserWindow class]]) { - FramedBrowserWindow* window = - static_cast<FramedBrowserWindow*>([self window]); - mouseInGroup = [window mouseInGroup:widget]; - } else if ([super respondsToSelector:@selector(_mouseInGroup:)]) { - mouseInGroup = [super _mouseInGroup:widget]; - } - return mouseInGroup; -} - -// Let our window handle updating the window widget tracking area. -- (void)updateTrackingAreas { - [super updateTrackingAreas]; - if ([[self window] isKindOfClass:[FramedBrowserWindow class]]) { - FramedBrowserWindow* window = - static_cast<FramedBrowserWindow*>([self window]); - [window updateTrackingAreas]; - } -} - // When the compositor is active, the whole content area is transparent (with // an OpenGL surface behind it), so Cocoa draws the shadow only around the // toolbar area. diff --git a/chrome/browser/ui/cocoa/browser_frame_view_unittest.mm b/chrome/browser/ui/cocoa/browser_frame_view_unittest.mm index ca2de67..9de6734 100644 --- a/chrome/browser/ui/cocoa/browser_frame_view_unittest.mm +++ b/chrome/browser/ui/cocoa/browser_frame_view_unittest.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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 <objc/runtime.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/browser_frame_view.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" @@ -26,23 +26,15 @@ class BrowserFrameViewTest : public PlatformTest { // Test to make sure our class modifications were successful. TEST_F(BrowserFrameViewTest, SuccessfulClassModifications) { unsigned int count; - BOOL foundMouseInGroup = NO; BOOL foundDrawRectOriginal = NO; - BOOL foundUpdateTrackingAreas = NO; Method* methods = class_copyMethodList([view_ class], &count); for (unsigned int i = 0; i < count; ++i) { SEL selector = method_getName(methods[i]); - if (selector == @selector(_mouseInGroup:)) { - foundMouseInGroup = YES; - } else if (selector == @selector(drawRectOriginal:)) { + if (selector == @selector(drawRectOriginal:)) { foundDrawRectOriginal = YES; - } else if (selector == @selector(updateTrackingAreas)) { - foundUpdateTrackingAreas = YES; } } - EXPECT_TRUE(foundMouseInGroup); EXPECT_TRUE(foundDrawRectOriginal); - EXPECT_TRUE(foundUpdateTrackingAreas); free(methods); } diff --git a/chrome/browser/ui/cocoa/browser_test_helper.cc b/chrome/browser/ui/cocoa/browser_test_helper.cc index 3e046e3..d1a22ca 100644 --- a/chrome/browser/ui/cocoa/browser_test_helper.cc +++ b/chrome/browser/ui/cocoa/browser_test_helper.cc @@ -27,12 +27,15 @@ BrowserTestHelper::~BrowserTestHelper() { // Delete the testing profile on the UI thread. But first release the // browser, since it may trigger accesses to the profile upon destruction. browser_.reset(); + message_loop_.DeleteSoon(FROM_HERE, profile_.release()); + + // Make sure any pending tasks run before we destroy other threads. + message_loop_.RunAllPending(); // Drop any new tasks for the IO and FILE threads. io_thread_.reset(); file_thread_.reset(); - message_loop_.DeleteSoon(FROM_HERE, profile_.release()); message_loop_.RunAllPending(); } @@ -41,7 +44,7 @@ TestingProfile* BrowserTestHelper::profile() const { } BrowserWindow* BrowserTestHelper::CreateBrowserWindow() { - browser_->CreateBrowserWindow(); + browser_->InitBrowserWindow(); return browser_->window(); } diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.h b/chrome/browser/ui/cocoa/browser_window_cocoa.h index dfcb6a8..11d09fd 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.h +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.h @@ -6,11 +6,11 @@ #define CHROME_BROWSER_UI_COCOA_BROWSER_WINDOW_COCOA_H_ #pragma once -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/task.h" -#include "chrome/browser/browser_window.h" #include "chrome/browser/bookmarks/bookmark_model.h" -#include "chrome/common/notification_registrar.h" +#include "chrome/browser/ui/browser_window.h" +#include "content/common/notification_registrar.h" class Browser; @class BrowserWindowController; @@ -33,6 +33,7 @@ class BrowserWindowCocoa : public BrowserWindow, // Overridden from BrowserWindow virtual void Show(); + virtual void ShowInactive(); virtual void SetBounds(const gfx::Rect& bounds); virtual void Close(); virtual void Activate(); @@ -42,7 +43,7 @@ class BrowserWindowCocoa : public BrowserWindow, virtual gfx::NativeWindow GetNativeHandle(); virtual BrowserWindowTesting* GetBrowserWindowTesting(); virtual StatusBubble* GetStatusBubble(); - virtual void SelectedTabToolbarSizeChanged(bool is_animating); + virtual void ToolbarSizeChanged(bool is_animating); virtual void UpdateTitleBar(); virtual void ShelfVisibilityChanged(); virtual void UpdateDevTools(); @@ -78,15 +79,8 @@ class BrowserWindowCocoa : public BrowserWindow, virtual void ShowBookmarkBubble(const GURL& url, bool already_bookmarked); virtual bool IsDownloadShelfVisible() const; virtual DownloadShelf* GetDownloadShelf(); - virtual void ShowClearBrowsingDataDialog(); - virtual void ShowImportDialog(); - virtual void ShowSearchEnginesDialog(); - virtual void ShowPasswordManager(); virtual void ShowRepostFormWarningDialog(TabContents* tab_contents); - virtual void ShowContentSettingsWindow(ContentSettingsType content_type, - Profile* profile); virtual void ShowCollectedCookiesDialog(TabContents* tab_contents); - virtual void ShowProfileErrorDialog(int message_id); virtual void ShowThemeInstallBubble(); virtual void ConfirmBrowserCloseWithPendingDownloads(); virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate, @@ -102,7 +96,8 @@ class BrowserWindowCocoa : public BrowserWindow, virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut); virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event); - virtual void ShowCreateWebAppShortcutsDialog(TabContents* tab_contents); + virtual void ShowCreateWebAppShortcutsDialog( + TabContentsWrapper* tab_contents); virtual void ShowCreateChromeAppShortcutsDialog(Profile* profile, const Extension* app); virtual void Cut(); @@ -111,7 +106,7 @@ class BrowserWindowCocoa : public BrowserWindow, virtual void ToggleTabStripMode(); virtual void OpenTabpose(); virtual void PrepareForInstant(); - virtual void ShowInstant(TabContents* preview_contents); + virtual void ShowInstant(TabContentsWrapper* preview); virtual void HideInstant(bool instant_is_active); virtual gfx::Rect GetInstantBounds(); diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm index dae1719..eb02ac8 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm @@ -22,16 +22,11 @@ #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/bug_report_window_controller.h" #import "chrome/browser/ui/cocoa/chrome_event_processing_window.h" -#import "chrome/browser/ui/cocoa/clear_browsing_data_controller.h" #import "chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.h" #import "chrome/browser/ui/cocoa/download/download_shelf_controller.h" #import "chrome/browser/ui/cocoa/html_dialog_window_controller.h" -#import "chrome/browser/ui/cocoa/importer/import_dialog_cocoa.h" #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" #import "chrome/browser/ui/cocoa/nsmenuitem_additions.h" -#import "chrome/browser/ui/cocoa/options/content_settings_dialog_controller.h" -#import "chrome/browser/ui/cocoa/options/edit_search_engine_cocoa_controller.h" -#import "chrome/browser/ui/cocoa/options/keyword_editor_cocoa_controller.h" #include "chrome/browser/ui/cocoa/repost_form_warning_mac.h" #include "chrome/browser/ui/cocoa/restart_browser.h" #include "chrome/browser/ui/cocoa/status_bubble_mac.h" @@ -39,10 +34,10 @@ #import "chrome/browser/ui/cocoa/theme_install_bubble_view.h" #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" -#include "chrome/common/native_web_keyboard_event.h" -#include "chrome/common/notification_service.h" #include "chrome/common/pref_names.h" #include "content/browser/tab_contents/tab_contents.h" +#include "content/common/native_web_keyboard_event.h" +#include "content/common/notification_service.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -76,6 +71,10 @@ void BrowserWindowCocoa::Show() { [window() makeKeyAndOrderFront:controller_]; } +void BrowserWindowCocoa::ShowInactive() { + [window() orderFront:controller_]; +} + void BrowserWindowCocoa::SetBounds(const gfx::Rect& bounds) { SetFullscreen(false); NSRect cocoa_bounds = NSMakeRect(bounds.x(), 0, bounds.width(), @@ -140,7 +139,7 @@ StatusBubble* BrowserWindowCocoa::GetStatusBubble() { return [controller_ statusBubble]; } -void BrowserWindowCocoa::SelectedTabToolbarSizeChanged(bool is_animating) { +void BrowserWindowCocoa::ToolbarSizeChanged(bool is_animating) { // According to beng, this is an ugly method that comes from the days when the // download shelf was a ChromeView attached to the TabContents, and as its // size changed via animation it notified through TCD/etc to the browser view @@ -224,16 +223,7 @@ bool BrowserWindowCocoa::IsFullscreenBubbleVisible() const { void BrowserWindowCocoa::ConfirmAddSearchProvider( const TemplateURL* template_url, Profile* profile) { - // The controller will release itself when the window closes. - EditSearchEngineCocoaController* editor = - [[EditSearchEngineCocoaController alloc] initWithProfile:profile - delegate:NULL - templateURL:template_url]; - [NSApp beginSheet:[editor window] - modalForWindow:window() - modalDelegate:controller_ - didEndSelector:@selector(sheetDidEnd:returnCode:context:) - contextInfo:NULL]; + NOTIMPLEMENTED(); } LocationBar* BrowserWindowCocoa::GetLocationBar() const { @@ -275,7 +265,10 @@ void BrowserWindowCocoa::FocusChromeOSStatus() { } bool BrowserWindowCocoa::IsBookmarkBarVisible() const { - return browser_->profile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); + return (browser_->profile()->GetPrefs()->GetBoolean( + prefs::kShowBookmarkBar) && + browser_->profile()->GetPrefs()->GetBoolean( + prefs::kEnableBookmarkBar)); } bool BrowserWindowCocoa::IsBookmarkBarAnimating() const { @@ -336,50 +329,16 @@ DownloadShelf* BrowserWindowCocoa::GetDownloadShelf() { return [shelfController bridge]; } -void BrowserWindowCocoa::ShowClearBrowsingDataDialog() { - [ClearBrowsingDataController - showClearBrowsingDialogForProfile:browser_->profile()]; -} - -void BrowserWindowCocoa::ShowImportDialog() { - [ImportDialogController - showImportSettingsDialogForProfile:browser_->profile()]; -} - -void BrowserWindowCocoa::ShowSearchEnginesDialog() { - [KeywordEditorCocoaController showKeywordEditor:browser_->profile()]; -} - -void BrowserWindowCocoa::ShowPasswordManager() { - NOTIMPLEMENTED(); -} - void BrowserWindowCocoa::ShowRepostFormWarningDialog( TabContents* tab_contents) { RepostFormWarningMac::Create(GetNativeHandle(), tab_contents); } -void BrowserWindowCocoa::ShowContentSettingsWindow( - ContentSettingsType settings_type, - Profile* profile) { - [ContentSettingsDialogController showContentSettingsForType:settings_type - profile:profile]; -} - void BrowserWindowCocoa::ShowCollectedCookiesDialog(TabContents* tab_contents) { // Deletes itself on close. new CollectedCookiesMac(GetNativeHandle(), tab_contents); } -void BrowserWindowCocoa::ShowProfileErrorDialog(int message_id) { - scoped_nsobject<NSAlert> alert([[NSAlert alloc] init]); - [alert addButtonWithTitle:l10n_util::GetNSStringWithFixup(IDS_OK)]; - [alert setMessageText:l10n_util::GetNSStringWithFixup(IDS_PRODUCT_NAME)]; - [alert setInformativeText:l10n_util::GetNSStringWithFixup(message_id)]; - [alert setAlertStyle:NSWarningAlertStyle]; - [alert runModal]; -} - void BrowserWindowCocoa::ShowThemeInstallBubble() { ThemeInstallBubbleView::Show(window()); } @@ -555,7 +514,7 @@ bool BrowserWindowCocoa::HandleKeyboardEventInternal(NSEvent* event) { } void BrowserWindowCocoa::ShowCreateWebAppShortcutsDialog( - TabContents* tab_contents) { + TabContentsWrapper* tab_contents) { NOTIMPLEMENTED(); } @@ -588,8 +547,8 @@ void BrowserWindowCocoa::PrepareForInstant() { // TODO: implement fade as done on windows. } -void BrowserWindowCocoa::ShowInstant(TabContents* preview_contents) { - [controller_ showInstant:preview_contents]; +void BrowserWindowCocoa::ShowInstant(TabContentsWrapper* preview) { + [controller_ showInstant:preview->tab_contents()]; } void BrowserWindowCocoa::HideInstant(bool instant_is_active) { diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa_unittest.mm b/chrome/browser/ui/cocoa/browser_window_cocoa_unittest.mm index c76d3ee..a68af29 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa_unittest.mm +++ b/chrome/browser/ui/cocoa/browser_window_cocoa_unittest.mm @@ -1,16 +1,16 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "base/string_util.h" #include "chrome/browser/bookmarks/bookmark_utils.h" #include "chrome/browser/ui/cocoa/browser_test_helper.h" #include "chrome/browser/ui/cocoa/browser_window_cocoa.h" #include "chrome/browser/ui/cocoa/browser_window_controller.h" #include "chrome/browser/ui/cocoa/cocoa_test_helper.h" -#include "chrome/common/notification_type.h" +#include "content/common/notification_type.h" #include "testing/gtest/include/gtest/gtest.h" // A BrowserWindowCocoa that goes PONG when diff --git a/chrome/browser/ui/cocoa/browser_window_controller.h b/chrome/browser/ui/cocoa/browser_window_controller.h index 597ed90..cc72002 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.h +++ b/chrome/browser/ui/cocoa/browser_window_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -13,8 +13,8 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/sync/sync_ui_util.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h" @@ -267,6 +267,7 @@ class TabContents; // Shows or hides the Instant preview contents. - (void)showInstant:(TabContents*)previewContents; - (void)hideInstant; +- (void)commitInstant; // Returns the frame, in Cocoa (unflipped) screen coordinates, of the area where // Instant results are. If Instant is not showing, returns the frame of where @@ -320,6 +321,9 @@ class TabContents; // Methods having to do with fullscreen mode. @interface BrowserWindowController(Fullscreen) +// Enters fullscreen mode. +- (IBAction)enterFullscreen:(id)sender; + // Enters (or exits) fullscreen mode. - (void)setFullscreen:(BOOL)fullscreen; diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm index ce8f3fe..d0bfe00 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller.mm @@ -9,17 +9,19 @@ #include "app/mac/scoped_nsdisable_screen_updates.h" #include "app/mac/nsimage_cache.h" #include "base/mac/mac_util.h" -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #include "base/sys_string_conversions.h" #include "chrome/app/chrome_command_ids.h" // IDC_* #include "chrome/browser/bookmarks/bookmark_editor.h" #include "chrome/browser/google/google_util.h" +#include "chrome/browser/instant/instant_controller.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/sync/sync_ui_util_mac.h" #include "chrome/browser/tab_contents/tab_contents_view_mac.h" #include "chrome/browser/tabs/tab_strip_model.h" -#include "chrome/browser/themes/browser_theme_provider.h" +#include "chrome/browser/themes/theme_service.h" +#include "chrome/browser/themes/theme_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #import "chrome/browser/ui/cocoa/background_gradient_view.h" @@ -62,6 +64,7 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_mac.h" + // ORGANIZATION: This is a big file. It is (in principle) organized as follows // (in order): // 1. Interfaces. Very short, one-time-use classes may include an implementation @@ -137,7 +140,7 @@ // and if it's set we continue to constrain the resize. -@interface NSWindow(NSPrivateApis) +@interface NSWindow (NSPrivateApis) // Note: These functions are private, use -[NSObject respondsToSelector:] // before calling them. @@ -147,6 +150,26 @@ @end +// Provide the forward-declarations of new 10.7 SDK symbols so they can be +// called when building with the 10.5 SDK. +#if !defined(MAC_OS_X_VERSION_10_7) || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 + +@interface NSWindow (LionSDKDeclarations) +- (void)toggleFullScreen:(id)sender; +- (void)setRestorable:(BOOL)flag; +@end + +enum { + NSWindowCollectionBehaviorFullScreenPrimary = 1 << 7, + NSWindowCollectionBehaviorFullScreenAuxiliary = 1 << 8 +}; + +enum { + NSWindowFullScreenButton = 7 +}; + +#endif // MAC_OS_X_VERSION_10_7 // IncognitoImageView subclasses NSView to allow mouse events to pass through it // so you can drag the window by dragging on the spy guy. @@ -238,6 +261,13 @@ if ([window respondsToSelector:@selector(setBottomCornerRounded:)]) [window setBottomCornerRounded:NO]; + // Lion will attempt to automagically save and restore the UI. This + // functionality appears to be leaky (or at least interacts badly with our + // architecture) and thus BrowserWindowController never gets released. This + // prevents the browser from being able to quit <http://crbug.com/79113>. + if ([window respondsToSelector:@selector(setRestorable:)]) + [window setRestorable:NO]; + // Get the most appropriate size for the window, then enforce the // minimum width and height. The window shim will handle flipping // the coordinates for us so we can use it to save some code. @@ -387,6 +417,21 @@ if ([self hasToolbar]) // Do not create the buttons in popups. [toolbarController_ createBrowserActionButtons]; + // For versions of Mac OS that provide an "enter fullscreen" button, make + // one appear (in a rather hacky manner). http://crbug.com/74065 : When + // switching the fullscreen implementation to the new API, revisit how much + // of this hacky code is necessary. + if ([window respondsToSelector:@selector(toggleFullScreen:)]) { + NSWindowCollectionBehavior behavior = [window collectionBehavior]; + behavior |= NSWindowCollectionBehaviorFullScreenPrimary; + [window setCollectionBehavior:behavior]; + + NSButton* fullscreenButton = + [window standardWindowButton:NSWindowFullScreenButton]; + [fullscreenButton setAction:@selector(enterFullscreen:)]; + [fullscreenButton setTarget:self]; + } + // We are done initializing now. initializing_ = NO; } @@ -687,6 +732,9 @@ - (void)activate { [[self window] makeKeyAndOrderFront:self]; + ProcessSerialNumber psn; + GetCurrentProcess(&psn); + SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly); } // Determine whether we should let a window zoom/unzoom to the given |newFrame|. @@ -1352,6 +1400,10 @@ NSMinY([[bookmarkBarController_ view] frame]); CGFloat maxWidth = NSWidth([contentView frame]); [findBarCocoaController_ positionFindBarViewAtMaxY:maxY maxWidth:maxWidth]; + + // This allows the FindBarCocoaController to call |layoutSubviews| and get + // its position adjusted. + [findBarCocoaController_ setBrowserWindowController:self]; } - (NSWindow*)createFullscreenWindow { @@ -1484,7 +1536,7 @@ } - (ui::ThemeProvider*)themeProvider { - return browser_->profile()->GetThemeProvider(); + return ThemeServiceFactory::GetForProfile(browser_->profile()); } - (ThemedWindowStyle)themedWindowStyle { @@ -1570,7 +1622,7 @@ [[[BookmarkEditorController alloc] initWithParentWindow:[self window] profile:browser_->profile() - parent:node->GetParent() + parent:node->parent() node:node configuration:BookmarkEditor::SHOW_TREE] runAsModalSheet]; @@ -1627,7 +1679,7 @@ - (void)magnifyWithEvent:(NSEvent*)event { // The deltaZ difference necessary to trigger a zoom action. Derived from // experimentation to find a value that feels reasonable. - const float kZoomStepValue = 150; + const float kZoomStepValue = 300; // Find the (absolute) thresholds on either side of the current zoom factor, // then convert those to actual numbers to trigger a zoom in or out. @@ -1676,6 +1728,14 @@ if (RenderWidgetHostView* rwhv = contents->GetRenderWidgetHostView()) rwhv->WindowFrameChanged(); } + + // The FindBar needs to know its own position to properly detect overlaps + // with find results. The position changes whenever the window is resized, + // and |layoutSubviews| computes the FindBar's position. + // TODO: calling |layoutSubviews| here is a waste, find a better way to + // do this. + if ([findBarCocoaController_ isFindBarVisible]) + [self layoutSubviews]; } // Handle the openLearnMoreAboutCrashLink: action from SadTabController when @@ -1809,6 +1869,11 @@ willAnimateFromState:(bookmarks::VisualState)oldState [self updateBookmarkBarVisibilityWithAnimation:NO]; } +- (void)commitInstant { + InstantController::CommitIfCurrent(browser_->instant()); +} + + - (NSRect)instantFrame { // The view's bounds are in its own coordinate system. Convert that to the // window base coordinate system, then translate it into the screen's @@ -1821,6 +1886,12 @@ willAnimateFromState:(bookmarks::VisualState)oldState NSPoint originInScreenCoords = [[view window] convertBaseToScreen:frame.origin]; frame.origin = originInScreenCoords; + + // Account for the bookmark bar height if it is currently in the detached + // state on the new tab page. + if ([bookmarkBarController_ isInState:(bookmarks::kDetachedState)]) + frame.size.height += [[bookmarkBarController_ view] bounds].size.height; + return frame; } @@ -1835,6 +1906,10 @@ willAnimateFromState:(bookmarks::VisualState)oldState @implementation BrowserWindowController(Fullscreen) +- (IBAction)enterFullscreen:(id)sender { + browser_->ExecuteCommand(IDC_FULLSCREEN); +} + - (void)setFullscreen:(BOOL)fullscreen { // The logic in this function is a bit complicated and very carefully // arranged. See the below comments for more details. @@ -1940,6 +2015,16 @@ willAnimateFromState:(bookmarks::VisualState)oldState [destWindow setWindowController:self]; [self adjustUIForFullscreen:fullscreen]; + // Adjust the infobar container. In fullscreen, it needs to be below all + // top chrome elements so it only sits atop the web contents. When in normal + // mode, it needs to draw over the bookmark bar and part of the toolbar. + [[infoBarContainerController_ view] removeFromSuperview]; + NSView* infoBarDest = [[destWindow contentView] superview]; + [infoBarDest addSubview:[infoBarContainerController_ view] + positioned:fullscreen ? NSWindowBelow : NSWindowAbove + relativeTo:fullscreen ? floatingBarBackingView_ + : [bookmarkBarController_ view]]; + // When entering fullscreen mode, the controller forces a layout for us. When // exiting, we need to call layoutSubviews manually. if (fullscreen) { diff --git a/chrome/browser/ui/cocoa/browser_window_controller_private.mm b/chrome/browser/ui/cocoa/browser_window_controller_private.mm index cb81b18..2eac331 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller_private.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller_private.mm @@ -4,11 +4,12 @@ #import "chrome/browser/ui/cocoa/browser_window_controller_private.h" -#import "base/scoped_nsobject.h" +#include "base/command_line.h" +#import "base/memory/scoped_nsobject.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/prefs/scoped_user_pref_update.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/ui/browser_list.h" #import "chrome/browser/ui/cocoa/fast_resize_view.h" #import "chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h" @@ -21,6 +22,7 @@ #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" +#include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "content/browser/renderer_host/render_widget_host_view.h" #include "content/browser/tab_contents/tab_contents.h" @@ -40,6 +42,20 @@ const CGFloat kLocBarBottomInset = 1; } // end namespace +// 10.7 adds public APIs for full-screen support. Provide the declaration so it +// can be called below when building with the 10.5 SDK. +#if !defined(MAC_OS_X_VERSION_10_7) || \ +MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 + +@interface NSWindow (LionSDKDeclarations) +- (void)toggleFullScreen:(id)sender; +@end + +enum { + NSWindowFullScreenButton = 7 +}; + +#endif // MAC_OS_X_VERSION_10_7 @implementation BrowserWindowController(Private) @@ -101,8 +117,8 @@ const CGFloat kLocBarBottomInset = 1; if (browser_->ShouldSaveWindowPlacement()) browser_->SaveWindowPlacement(bounds, /*maximized=*/ false); - DictionaryValue* windowPreferences = prefs->GetMutableDictionary( - browser_->GetWindowPlacementKey().c_str()); + DictionaryPrefUpdate update(prefs, browser_->GetWindowPlacementKey().c_str()); + DictionaryValue* windowPreferences = update.Get(); windowPreferences->SetInteger("left", bounds.x()); windowPreferences->SetInteger("top", bounds.y()); windowPreferences->SetInteger("right", bounds.right()); @@ -283,9 +299,19 @@ willPositionSheet:(NSWindow*)sheet // Now lay out incognito badge together with the tab strip. if (incognitoBadge_.get()) { + // Avoid the full-screen button. + CGFloat extraPadding = 0; + if ([[self window] respondsToSelector:@selector(toggleFullScreen:)]) { + NSButton* fullscreenButton = + [[self window] standardWindowButton:NSWindowFullScreenButton]; + if (fullscreenButton) + extraPadding += [fullscreenButton frame].size.width; + } + // Actually place the badge *above* |maxY|, by +2 to miss the divider. NSPoint origin = NSMakePoint(width - NSWidth([incognitoBadge_ frame]) - - kIncognitoBadgeOffset, maxY + 2); + kIncognitoBadgeOffset - extraPadding, + maxY + 2); [incognitoBadge_ setFrameOrigin:origin]; [incognitoBadge_ setHidden:NO]; // Make sure it's shown. } @@ -449,6 +475,10 @@ willPositionSheet:(NSWindow*)sheet } - (BOOL)shouldShowDetachedBookmarkBar { + // NTP4 never detaches the bookmark bar. + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNewTabPage4)) + return NO; + DCHECK(browser_.get()); TabContents* contents = browser_->GetSelectedTabContents(); return (contents && diff --git a/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm b/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm index 8ca0617..5666f2c 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/browser_window.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/sync/sync_ui_util.h" +#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/cocoa/browser_test_helper.h" #include "chrome/browser/ui/cocoa/browser_window_controller.h" #include "chrome/browser/ui/cocoa/cocoa_test_helper.h" @@ -622,6 +622,14 @@ class BrowserWindowFullScreenControllerTest : public CocoaTest { - (BOOL)supportsFullscreen; @end +// Check if the window is front most or if one of its child windows (such +// as a status bubble) is front most. +static bool IsFrontWindow(NSWindow *window) { + NSWindow* frontmostWindow = [[NSApp orderedWindows] objectAtIndex:0]; + return [frontmostWindow isEqual:window] || + [[frontmostWindow parentWindow] isEqual:window]; +} + TEST_F(BrowserWindowFullScreenControllerTest, TestFullscreen) { EXPECT_FALSE([controller_ isFullscreen]); [controller_ setFullscreen:YES]; @@ -638,13 +646,11 @@ TEST_F(BrowserWindowFullScreenControllerTest, TestActivate) { EXPECT_FALSE([controller_ isFullscreen]); [controller_ activate]; - NSWindow* frontmostWindow = [[NSApp orderedWindows] objectAtIndex:0]; - EXPECT_EQ(frontmostWindow, [controller_ window]); + EXPECT_TRUE(IsFrontWindow([controller_ window])); [controller_ setFullscreen:YES]; [controller_ activate]; - frontmostWindow = [[NSApp orderedWindows] objectAtIndex:0]; - EXPECT_EQ(frontmostWindow, [controller_ createFullscreenWindow]); + EXPECT_TRUE(IsFrontWindow([controller_ createFullscreenWindow])); // We have to cleanup after ourselves by unfullscreening. [controller_ setFullscreen:NO]; diff --git a/chrome/browser/ui/cocoa/bubble_view.h b/chrome/browser/ui/cocoa/bubble_view.h index 755c8a4..448c813 100644 --- a/chrome/browser/ui/cocoa/bubble_view.h +++ b/chrome/browser/ui/cocoa/bubble_view.h @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" // A view class that looks like a "bubble" with rounded corners and displays // text inside. Can be themed. To put flush against the sides of a window, the diff --git a/chrome/browser/ui/cocoa/bubble_view.mm b/chrome/browser/ui/cocoa/bubble_view.mm index 0b92f39..9892ecd 100644 --- a/chrome/browser/ui/cocoa/bubble_view.mm +++ b/chrome/browser/ui/cocoa/bubble_view.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/bubble_view.h" -#include "chrome/browser/themes/browser_theme_provider.h" +#include "chrome/browser/themes/theme_service.h" #import "chrome/browser/ui/cocoa/themed_window.h" #import "third_party/GTM/AppKit/GTMNSBezierPath+RoundRect.h" #import "third_party/GTM/AppKit/GTMNSColor+Luminance.h" @@ -90,7 +90,7 @@ const float kWindowEdge = 0.7f; bottomRightCornerRadius:bottomRightRadius]; if (themeProvider) - [themeProvider->GetNSColor(BrowserThemeProvider::COLOR_TOOLBAR, true) set]; + [themeProvider->GetNSColor(ThemeService::COLOR_TOOLBAR, true) set]; [border fill]; [[NSColor colorWithDeviceWhite:kWindowEdge alpha:1.0f] set]; @@ -99,7 +99,7 @@ const float kWindowEdge = 0.7f; // Text NSColor* textColor = [NSColor blackColor]; if (themeProvider) - textColor = themeProvider->GetNSColor(BrowserThemeProvider::COLOR_TAB_TEXT, + textColor = themeProvider->GetNSColor(ThemeService::COLOR_TAB_TEXT, true); NSFont* textFont = [self font]; scoped_nsobject<NSShadow> textShadow([[NSShadow alloc] init]); diff --git a/chrome/browser/ui/cocoa/bubble_view_unittest.mm b/chrome/browser/ui/cocoa/bubble_view_unittest.mm index 5d788ea..4b8850e 100644 --- a/chrome/browser/ui/cocoa/bubble_view_unittest.mm +++ b/chrome/browser/ui/cocoa/bubble_view_unittest.mm @@ -1,9 +1,9 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/bubble_view.h" #include "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "testing/gtest_mac.h" diff --git a/chrome/browser/ui/cocoa/bug_report_window_controller.h b/chrome/browser/ui/cocoa/bug_report_window_controller.h index c0c9384..272c5bf 100644 --- a/chrome/browser/ui/cocoa/bug_report_window_controller.h +++ b/chrome/browser/ui/cocoa/bug_report_window_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -10,7 +10,7 @@ #include <vector> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" class Profile; class TabContents; diff --git a/chrome/browser/ui/cocoa/bug_report_window_controller_unittest.mm b/chrome/browser/ui/cocoa/bug_report_window_controller_unittest.mm index b0cbed5..614e760 100644 --- a/chrome/browser/ui/cocoa/bug_report_window_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/bug_report_window_controller_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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" +#include "base/memory/ref_counted.h" #include "chrome/browser/profiles/profile.h" #import "chrome/browser/ui/cocoa/bug_report_window_controller.h" #include "chrome/test/testing_profile.h" diff --git a/chrome/browser/ui/cocoa/chrome_browser_window.mm b/chrome/browser/ui/cocoa/chrome_browser_window.mm index cceeb14..e21507b 100644 --- a/chrome/browser/ui/cocoa/chrome_browser_window.mm +++ b/chrome/browser/ui/cocoa/chrome_browser_window.mm @@ -1,12 +1,12 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/chrome_browser_window.h" #include "base/logging.h" -#include "chrome/browser/themes/browser_theme_provider.h" #import "chrome/browser/ui/cocoa/themed_window.h" +#include "ui/base/theme_provider.h" @implementation ChromeBrowserWindow diff --git a/chrome/browser/ui/cocoa/chrome_event_processing_window.h b/chrome/browser/ui/cocoa/chrome_event_processing_window.h index 3524d6f..be60afd 100644 --- a/chrome/browser/ui/cocoa/chrome_event_processing_window.h +++ b/chrome/browser/ui/cocoa/chrome_event_processing_window.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,7 +8,7 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" // Override NSWindow to access unhandled keyboard events (for command // processing); subclassing NSWindow is the only method to do diff --git a/chrome/browser/ui/cocoa/chrome_event_processing_window_unittest.mm b/chrome/browser/ui/cocoa/chrome_event_processing_window_unittest.mm index f2fd657..ea6005e 100644 --- a/chrome/browser/ui/cocoa/chrome_event_processing_window_unittest.mm +++ b/chrome/browser/ui/cocoa/chrome_event_processing_window_unittest.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. #include <Carbon/Carbon.h> #include "base/debug/debugger.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/app/chrome_command_ids.h" #import "chrome/browser/ui/cocoa/chrome_event_processing_window.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" diff --git a/chrome/browser/ui/cocoa/clear_browsing_data_controller.h b/chrome/browser/ui/cocoa/clear_browsing_data_controller.h deleted file mode 100644 index ac52b38..0000000 --- a/chrome/browser/ui/cocoa/clear_browsing_data_controller.h +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2011 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_UI_COCOA_CLEAR_BROWSING_DATA_CONTROLLER_ -#define CHROME_BROWSER_UI_COCOA_CLEAR_BROWSING_DATA_CONTROLLER_ -#pragma once - -#import <Cocoa/Cocoa.h> - -#include "base/scoped_ptr.h" - -class BrowsingDataRemover; -class ClearBrowsingObserver; -class Profile; -@class ThrobberView; - -// Name of notification that is called when data is cleared. -extern NSString* const kClearBrowsingDataControllerDidDelete; -// A key in the above notification's userInfo. Contains a NSNumber with the -// logically-ored constants defined in BrowsingDataRemover for the removal. -extern NSString* const kClearBrowsingDataControllerRemoveMask; - -// A window controller for managing the "Clear Browsing Data" feature. Modally -// presents a dialog offering the user a set of choices of what browsing data -// to delete and does so if the user chooses. - -@interface ClearBrowsingDataController : NSWindowController { - @private - Profile* profile_; // Weak, owned by browser. - // If non-null means there is a removal in progress. Member used mainly for - // automated tests. The remove deletes itself when it's done, so this is a - // weak reference. - BrowsingDataRemover* remover_; - scoped_ptr<ClearBrowsingObserver> observer_; - BOOL isClearing_; // YES while clearing data is ongoing. - - // Values for checkboxes, kept in sync with bindings. These values get - // persisted into prefs if the user accepts the dialog. - BOOL clearBrowsingHistory_; - BOOL clearDownloadHistory_; - BOOL emptyCache_; - BOOL deleteCookies_; - BOOL clearSavedPasswords_; - BOOL clearFormData_; - NSInteger timePeriod_; -} - -// Properties for bindings -@property(nonatomic) BOOL clearBrowsingHistory; -@property(nonatomic) BOOL clearDownloadHistory; -@property(nonatomic) BOOL emptyCache; -@property(nonatomic) BOOL deleteCookies; -@property(nonatomic) BOOL clearSavedPasswords; -@property(nonatomic) BOOL clearFormData; -@property(nonatomic) NSInteger timePeriod; -@property(nonatomic) BOOL isClearing; - -// Show the clear browsing data window. Do not use |-initWithProfile:|, -// go through this instead so we don't end up with multiple instances. -// This function does not block, so it can be used from WebUI calls. -+ (void)showClearBrowsingDialogForProfile:(Profile*)profile; -+ (ClearBrowsingDataController*)controllerForProfile:(Profile*)profile; - -// Run the dialog with an application-modal event loop. If the user accepts, -// performs the deletion of the selected browsing data. The values of the -// checkboxes will be persisted into prefs for next time. -- (void)runModalDialog; - -// IBActions for the dialog buttons -- (IBAction)clearData:(id)sender; -- (IBAction)cancel:(id)sender; -- (IBAction)openFlashPlayerSettings:(id)sender; - -@end - - -@interface ClearBrowsingDataController (ExposedForUnitTests) -@property(readonly) int removeMask; - -// Create the controller with the given profile (which must not be NULL). -- (id)initWithProfile:(Profile*)profile; -- (void)persistToPrefs; -- (void)closeDialog; -- (void)dataRemoverDidFinish; -@end - -#endif // CHROME_BROWSER_UI_COCOA_CLEAR_BROWSING_DATA_CONTROLLER_ diff --git a/chrome/browser/ui/cocoa/clear_browsing_data_controller.mm b/chrome/browser/ui/cocoa/clear_browsing_data_controller.mm deleted file mode 100644 index ae57e26..0000000 --- a/chrome/browser/ui/cocoa/clear_browsing_data_controller.mm +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright (c) 2011 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/ui/cocoa/clear_browsing_data_controller.h" - -#include "base/lazy_instance.h" -#include "base/mac/mac_util.h" -#include "base/scoped_nsobject.h" -#include "chrome/browser/browsing_data_remover.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/common/pref_names.h" -#include "grit/locale_settings.h" -#import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" -#include "ui/base/l10n/l10n_util.h" - -NSString* const kClearBrowsingDataControllerDidDelete = - @"kClearBrowsingDataControllerDidDelete"; -NSString* const kClearBrowsingDataControllerRemoveMask = - @"kClearBrowsingDataControllerRemoveMask"; - -@interface ClearBrowsingDataController(Private) -- (void)initFromPrefs; -- (void)persistToPrefs; -- (void)dataRemoverDidFinish; -@end - -class ClearBrowsingObserver : public BrowsingDataRemover::Observer { - public: - ClearBrowsingObserver(ClearBrowsingDataController* controller) - : controller_(controller) { } - void OnBrowsingDataRemoverDone() { [controller_ dataRemoverDidFinish]; } - private: - ClearBrowsingDataController* controller_; -}; - -namespace { - -typedef std::map<Profile*, ClearBrowsingDataController*> ProfileControllerMap; - -static base::LazyInstance<ProfileControllerMap> g_profile_controller_map( - base::LINKER_INITIALIZED); - -} // namespace - -@implementation ClearBrowsingDataController - -@synthesize clearBrowsingHistory = clearBrowsingHistory_; -@synthesize clearDownloadHistory = clearDownloadHistory_; -@synthesize emptyCache = emptyCache_; -@synthesize deleteCookies = deleteCookies_; -@synthesize clearSavedPasswords = clearSavedPasswords_; -@synthesize clearFormData = clearFormData_; -@synthesize timePeriod = timePeriod_; -@synthesize isClearing = isClearing_; - -+ (void)showClearBrowsingDialogForProfile:(Profile*)profile { - ClearBrowsingDataController* controller = - [ClearBrowsingDataController controllerForProfile:profile]; - if (![controller isWindowLoaded]) { - // This function needs to return instead of blocking, to match the windows - // api call. It caused problems when launching the dialog from the - // WebUI history page. See bug and code review for more details. - // http://crbug.com/37976 - [controller performSelector:@selector(runModalDialog) - withObject:nil - afterDelay:0]; - } -} - -+ (ClearBrowsingDataController *)controllerForProfile:(Profile*)profile { - // Get the original profile in case we get here from an incognito window - // |GetOriginalProfile()| will return the same profile if it is the original - // profile. - profile = profile->GetOriginalProfile(); - - ProfileControllerMap* map = g_profile_controller_map.Pointer(); - DCHECK(map != NULL); - ProfileControllerMap::iterator it = map->find(profile); - if (it == map->end()) { - // Since we don't currently support multiple profiles, this class - // has not been tested against this case. - if (!map->empty()) - return nil; - - ClearBrowsingDataController* controller = - [[self alloc] initWithProfile:profile]; - it = map->insert(std::make_pair(profile, controller)).first; - } - return it->second; -} - -- (id)initWithProfile:(Profile*)profile { - DCHECK(profile); - // Use initWithWindowNibPath:: instead of initWithWindowNibName: so we - // can override it in a unit test. - NSString *nibpath = [base::mac::MainAppBundle() - pathForResource:@"ClearBrowsingData" - ofType:@"nib"]; - if ((self = [super initWithWindowNibPath:nibpath owner:self])) { - profile_ = profile; - observer_.reset(new ClearBrowsingObserver(self)); - [self initFromPrefs]; - } - return self; -} - -- (void)dealloc { - if (remover_) { - // We were destroyed while clearing history was in progress. This can only - // occur during automated tests (normally the user can't close the dialog - // while clearing is in progress as the dialog is modal and not closeable). - remover_->RemoveObserver(observer_.get()); - } - - [super dealloc]; -} - -// Run application modal. -- (void)runModalDialog { - // Check again to make sure there is only one window. Since we use - // |performSelector:afterDelay:| it is possible for this to somehow be - // triggered twice. - DCHECK([NSThread isMainThread]); - if (![self isWindowLoaded]) { - // The Window size in the nib is a min size, loop over the views collecting - // the max they grew by, that is how much the window needs to be widened by. - CGFloat maxWidthGrowth = 0.0; - NSWindow* window = [self window]; - NSView* contentView = [window contentView]; - Class widthBasedTweakerClass = [GTMWidthBasedTweaker class]; - for (id subView in [contentView subviews]) { - if ([subView isKindOfClass:widthBasedTweakerClass]) { - GTMWidthBasedTweaker* tweaker = subView; - CGFloat delta = [tweaker changedWidth]; - maxWidthGrowth = std::max(maxWidthGrowth, delta); - } - } - if (maxWidthGrowth > 0.0) { - NSRect rect = [contentView convertRect:[window frame] fromView:nil]; - rect.size.width += maxWidthGrowth; - rect = [contentView convertRect:rect toView:nil]; - [window setFrame:rect display:NO]; - // For some reason the content view is resizing, but some times not - // adjusting its origin, so correct it manually. - [contentView setFrameOrigin:NSZeroPoint]; - } - // Now start the modal loop. - [NSApp runModalForWindow:window]; - } -} - -- (int)removeMask { - int removeMask = 0L; - if (clearBrowsingHistory_) - removeMask |= BrowsingDataRemover::REMOVE_HISTORY; - if (clearDownloadHistory_) - removeMask |= BrowsingDataRemover::REMOVE_DOWNLOADS; - if (emptyCache_) - removeMask |= BrowsingDataRemover::REMOVE_CACHE; - if (deleteCookies_) - removeMask |= BrowsingDataRemover::REMOVE_COOKIES; - if (clearSavedPasswords_) - removeMask |= BrowsingDataRemover::REMOVE_PASSWORDS; - if (clearFormData_) - removeMask |= BrowsingDataRemover::REMOVE_FORM_DATA; - return removeMask; -} - -// Called when the user clicks the "clear" button. Do the work and persist -// the prefs for next time. We don't stop the modal session until we get -// the callback from the BrowsingDataRemover so the window stays on the screen. -// While we're working, dim the buttons so the user can't click them. -- (IBAction)clearData:(id)sender { - // Set that we're working so that the buttons disable. - [self setIsClearing:YES]; - - [self persistToPrefs]; - - // BrowsingDataRemover deletes itself when done. - remover_ = new BrowsingDataRemover(profile_, - static_cast<BrowsingDataRemover::TimePeriod>(timePeriod_), - base::Time()); - remover_->AddObserver(observer_.get()); - remover_->Remove([self removeMask]); -} - -// Called when the user clicks the cancel button. All we need to do is stop -// the modal session. -- (IBAction)cancel:(id)sender { - [self closeDialog]; -} - -// Called when the user clicks the "Flash Player storage settings" button. -- (IBAction)openFlashPlayerSettings:(id)sender { - // The "Clear Data" dialog is app-modal on OS X. Hence, close it before - // opening a tab with flash settings. - [self closeDialog]; - - Browser* browser = Browser::Create(profile_); - browser->OpenURL(GURL(l10n_util::GetStringUTF8(IDS_FLASH_STORAGE_URL)), - GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK); - browser->window()->Show(); -} - -- (void)closeDialog { - ProfileControllerMap* map = g_profile_controller_map.Pointer(); - ProfileControllerMap::iterator it = map->find(profile_); - if (it != map->end()) { - map->erase(it); - } - [self autorelease]; - [[self window] orderOut:self]; - [NSApp stopModal]; -} - -// Initialize the bools from prefs using the setters to be KVO-compliant. -- (void)initFromPrefs { - PrefService* prefs = profile_->GetPrefs(); - [self setClearBrowsingHistory: - prefs->GetBoolean(prefs::kDeleteBrowsingHistory)]; - [self setClearDownloadHistory: - prefs->GetBoolean(prefs::kDeleteDownloadHistory)]; - [self setEmptyCache:prefs->GetBoolean(prefs::kDeleteCache)]; - [self setDeleteCookies:prefs->GetBoolean(prefs::kDeleteCookies)]; - [self setClearSavedPasswords:prefs->GetBoolean(prefs::kDeletePasswords)]; - [self setClearFormData:prefs->GetBoolean(prefs::kDeleteFormData)]; - [self setTimePeriod:prefs->GetInteger(prefs::kDeleteTimePeriod)]; -} - -// Save the checkbox values to the preferences. -- (void)persistToPrefs { - PrefService* prefs = profile_->GetPrefs(); - prefs->SetBoolean(prefs::kDeleteBrowsingHistory, - [self clearBrowsingHistory]); - prefs->SetBoolean(prefs::kDeleteDownloadHistory, - [self clearDownloadHistory]); - prefs->SetBoolean(prefs::kDeleteCache, [self emptyCache]); - prefs->SetBoolean(prefs::kDeleteCookies, [self deleteCookies]); - prefs->SetBoolean(prefs::kDeletePasswords, [self clearSavedPasswords]); - prefs->SetBoolean(prefs::kDeleteFormData, [self clearFormData]); - prefs->SetInteger(prefs::kDeleteTimePeriod, [self timePeriod]); -} - -// Called when the data remover object is done with its work. Close the window. -// The remover will delete itself. End the modal session at this point. -- (void)dataRemoverDidFinish { - NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; - int removeMask = [self removeMask]; - NSDictionary* userInfo = - [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:removeMask] - forKey:kClearBrowsingDataControllerRemoveMask]; - [center postNotificationName:kClearBrowsingDataControllerDidDelete - object:self - userInfo:userInfo]; - - [self closeDialog]; - [[self window] orderOut:self]; - [self setIsClearing:NO]; - remover_ = NULL; -} - -@end diff --git a/chrome/browser/ui/cocoa/clear_browsing_data_controller_unittest.mm b/chrome/browser/ui/cocoa/clear_browsing_data_controller_unittest.mm deleted file mode 100644 index d5f238a..0000000 --- a/chrome/browser/ui/cocoa/clear_browsing_data_controller_unittest.mm +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright (c) 2010 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/scoped_nsobject.h" -#include "chrome/browser/browsing_data_remover.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/cocoa/browser_test_helper.h" -#import "chrome/browser/ui/cocoa/clear_browsing_data_controller.h" -#import "chrome/browser/ui/cocoa/cocoa_test_helper.h" -#include "chrome/common/pref_names.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" -#import "third_party/ocmock/OCMock/OCMock.h" - -namespace { - -class ClearBrowsingDataControllerTest : public CocoaTest { - public: - virtual void SetUp() { - CocoaTest::SetUp(); - // Set up some interesting prefs: - PrefService* prefs = helper_.profile()->GetPrefs(); - prefs->SetBoolean(prefs::kDeleteBrowsingHistory, true); - prefs->SetBoolean(prefs::kDeleteDownloadHistory, false); - prefs->SetBoolean(prefs::kDeleteCache, true); - prefs->SetBoolean(prefs::kDeleteCookies, false); - prefs->SetBoolean(prefs::kDeletePasswords, true); - prefs->SetBoolean(prefs::kDeleteFormData, false); - prefs->SetInteger(prefs::kDeleteTimePeriod, - BrowsingDataRemover::FOUR_WEEKS); - controller_ = - [ClearBrowsingDataController controllerForProfile:helper_.profile()]; - } - - virtual void TearDown() { - [controller_ closeDialog]; - CocoaTest::TearDown(); - } - - BrowserTestHelper helper_; - ClearBrowsingDataController* controller_; -}; - -TEST_F(ClearBrowsingDataControllerTest, InitialState) { - // Check properties match the prefs set above: - EXPECT_TRUE([controller_ clearBrowsingHistory]); - EXPECT_FALSE([controller_ clearDownloadHistory]); - EXPECT_TRUE([controller_ emptyCache]); - EXPECT_FALSE([controller_ deleteCookies]); - EXPECT_TRUE([controller_ clearSavedPasswords]); - EXPECT_FALSE([controller_ clearFormData]); - EXPECT_EQ(BrowsingDataRemover::FOUR_WEEKS, - [controller_ timePeriod]); -} - -TEST_F(ClearBrowsingDataControllerTest, InitialRemoveMask) { - // Check that the remove-mask matches the initial properties: - EXPECT_EQ(BrowsingDataRemover::REMOVE_HISTORY | - BrowsingDataRemover::REMOVE_CACHE | - BrowsingDataRemover::REMOVE_PASSWORDS, - [controller_ removeMask]); -} - -TEST_F(ClearBrowsingDataControllerTest, ModifiedRemoveMask) { - // Invert all properties and check that the remove-mask is still correct: - [controller_ setClearBrowsingHistory:false]; - [controller_ setClearDownloadHistory:true]; - [controller_ setEmptyCache:false]; - [controller_ setDeleteCookies:true]; - [controller_ setClearSavedPasswords:false]; - [controller_ setClearFormData:true]; - - EXPECT_EQ(BrowsingDataRemover::REMOVE_DOWNLOADS | - BrowsingDataRemover::REMOVE_COOKIES | - BrowsingDataRemover::REMOVE_FORM_DATA, - [controller_ removeMask]); -} - -TEST_F(ClearBrowsingDataControllerTest, EmptyRemoveMask) { - // Clear all properties and check that the remove-mask is zero: - [controller_ setClearBrowsingHistory:false]; - [controller_ setClearDownloadHistory:false]; - [controller_ setEmptyCache:false]; - [controller_ setDeleteCookies:false]; - [controller_ setClearSavedPasswords:false]; - [controller_ setClearFormData:false]; - - EXPECT_EQ(0, - [controller_ removeMask]); -} - -TEST_F(ClearBrowsingDataControllerTest, PersistToPrefs) { - // Change some settings and store to prefs: - [controller_ setClearBrowsingHistory:false]; - [controller_ setClearDownloadHistory:true]; - [controller_ persistToPrefs]; - - // Test that the modified settings were stored to prefs: - PrefService* prefs = helper_.profile()->GetPrefs(); - EXPECT_FALSE(prefs->GetBoolean(prefs::kDeleteBrowsingHistory)); - EXPECT_TRUE(prefs->GetBoolean(prefs::kDeleteDownloadHistory)); - - // Make sure the rest of the prefs didn't change: - EXPECT_TRUE(prefs->GetBoolean(prefs::kDeleteCache)); - EXPECT_FALSE(prefs->GetBoolean(prefs::kDeleteCookies)); - EXPECT_TRUE(prefs->GetBoolean(prefs::kDeletePasswords)); - EXPECT_FALSE(prefs->GetBoolean(prefs::kDeleteFormData)); - EXPECT_EQ(BrowsingDataRemover::FOUR_WEEKS, - prefs->GetInteger(prefs::kDeleteTimePeriod)); -} - -TEST_F(ClearBrowsingDataControllerTest, SameControllerForProfile) { - ClearBrowsingDataController* controller = - [ClearBrowsingDataController controllerForProfile:helper_.profile()]; - EXPECT_EQ(controller_, controller); -} - -TEST_F(ClearBrowsingDataControllerTest, DataRemoverDidFinish) { - id observer = [OCMockObject observerMock]; - // Don't use |controller_| as the object because it will free itself twice - // because both |-dataRemoverDidFinish| and TearDown() call |-closeDialog|. - ClearBrowsingDataController* controller = - [[ClearBrowsingDataController alloc] initWithProfile:helper_.profile()]; - - NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; - [center addMockObserver:observer - name:kClearBrowsingDataControllerDidDelete - object:controller]; - - int mask = [controller removeMask]; - NSDictionary* expectedInfo = - [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:mask] - forKey:kClearBrowsingDataControllerRemoveMask]; - [[observer expect] - notificationWithName:kClearBrowsingDataControllerDidDelete - object:controller - userInfo:expectedInfo]; - - // This calls |-closeDialog| and cleans the controller up. - [controller dataRemoverDidFinish]; - - [observer verify]; -} - -} // namespace diff --git a/chrome/browser/ui/cocoa/clickhold_button_cell.h b/chrome/browser/ui/cocoa/clickhold_button_cell.h index 89218cf..d38ccb8 100644 --- a/chrome/browser/ui/cocoa/clickhold_button_cell.h +++ b/chrome/browser/ui/cocoa/clickhold_button_cell.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,7 +8,7 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/gradient_button_cell.h" // A button cell that implements "click hold" behavior after a specified delay diff --git a/chrome/browser/ui/cocoa/clickhold_button_cell_unittest.mm b/chrome/browser/ui/cocoa/clickhold_button_cell_unittest.mm index 7ccc773..f76f805 100644 --- a/chrome/browser/ui/cocoa/clickhold_button_cell_unittest.mm +++ b/chrome/browser/ui/cocoa/clickhold_button_cell_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/clickhold_button_cell.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/cocoa_test_helper.h b/chrome/browser/ui/cocoa/cocoa_test_helper.h index d7eb150..6891489 100644 --- a/chrome/browser/ui/cocoa/cocoa_test_helper.h +++ b/chrome/browser/ui/cocoa/cocoa_test_helper.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -10,9 +10,9 @@ #include "base/path_service.h" #import "base/mac/scoped_nsautorelease_pool.h" -#import "base/scoped_nsobject.h" -#import "chrome/common/chrome_application_mac.h" +#import "base/memory/scoped_nsobject.h" #include "chrome/common/chrome_constants.h" +#import "content/common/chrome_application_mac.h" #include "testing/platform_test.h" // Background windows normally will not display things such as focus @@ -109,13 +109,13 @@ class CocoaTest : public PlatformTest { // from a window. All tests that work with NSView subclasses and/or // NSViewController subclasses should use it. #define TEST_VIEW(test_fixture, test_view) \ - TEST_F(test_fixture, AddRemove##test_fixture) { \ + TEST_F(test_fixture, test_fixture##_TestViewMacroAddRemove) { \ scoped_nsobject<NSView> view([test_view retain]); \ EXPECT_EQ([test_window() contentView], [view superview]); \ [view removeFromSuperview]; \ EXPECT_FALSE([view superview]); \ } \ - TEST_F(test_fixture, Display##test_fixture) { \ + TEST_F(test_fixture, test_fixture##_TestViewMacroDisplay) { \ [test_view display]; \ } diff --git a/chrome/browser/ui/cocoa/command_observer_bridge_unittest.mm b/chrome/browser/ui/cocoa/command_observer_bridge_unittest.mm index 371bb2c..90c5b8a 100644 --- a/chrome/browser/ui/cocoa/command_observer_bridge_unittest.mm +++ b/chrome/browser/ui/cocoa/command_observer_bridge_unittest.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_ptr.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #import "chrome/browser/ui/cocoa/command_observer_bridge.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" diff --git a/chrome/browser/ui/cocoa/confirm_quit_panel_controller.h b/chrome/browser/ui/cocoa/confirm_quit_panel_controller.h index be56941..8a1816d 100644 --- a/chrome/browser/ui/cocoa/confirm_quit_panel_controller.h +++ b/chrome/browser/ui/cocoa/confirm_quit_panel_controller.h @@ -12,6 +12,26 @@ @class ConfirmQuitFrameView; +namespace confirm_quit { + +enum ConfirmQuitMetric { + // The user quit without having the feature enabled. + kNoConfirm = 0, + // The user held Cmd+Q for the entire duration. + kHoldDuration, + // The user hit Cmd+Q twice for the accelerated path. + kDoubleTap, + // The user tapped Cmd+Q once and then held it. + kTapHold, + + kSampleCount +}; + +// Records the histogram value for the above metric. +void RecordHistogram(ConfirmQuitMetric sample); + +} // namespace confirm_quit + // The ConfirmQuitPanelController manages the black HUD window that tells users // to "Hold Cmd+Q to Quit". @interface ConfirmQuitPanelController : NSWindowController<NSWindowDelegate> { @@ -42,10 +62,13 @@ // Returns the Accelerator for the Quit menu item. + (ui::AcceleratorCocoa)quitAccelerator; +// Returns a string representation fit for display of |+quitAccelerator|. ++ (NSString*)keyCommandString; + @end @interface ConfirmQuitPanelController (UnitTesting) -- (NSString*)keyCombinationForAccelerator:(const ui::AcceleratorCocoa&)item; ++ (NSString*)keyCombinationForAccelerator:(const ui::AcceleratorCocoa&)item; @end #endif // CHROME_BROWSER_UI_COCOA_CONFIRM_QUIT_PANEL_CONTROLLER_H_ diff --git a/chrome/browser/ui/cocoa/confirm_quit_panel_controller.mm b/chrome/browser/ui/cocoa/confirm_quit_panel_controller.mm index c4cb727..4b44d4d 100644 --- a/chrome/browser/ui/cocoa/confirm_quit_panel_controller.mm +++ b/chrome/browser/ui/cocoa/confirm_quit_panel_controller.mm @@ -6,7 +6,8 @@ #import <QuartzCore/QuartzCore.h> #include "base/logging.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" +#include "base/metrics/histogram.h" #include "base/sys_string_conversions.h" #import "chrome/browser/ui/cocoa/confirm_quit_panel_controller.h" #include "grit/generated_resources.h" @@ -24,6 +25,20 @@ const NSTimeInterval kTimeDeltaFuzzFactor = 1.0; // Duration of the window fade out animation. const NSTimeInterval kWindowFadeAnimationDuration = 0.2; +// For metrics recording only: How long the user must hold the keys to +// differentitate kDoubleTap from kTapHold. +const NSTimeInterval kDoubleTapTimeDelta = 0.32; + +// Functions /////////////////////////////////////////////////////////////////// + +namespace confirm_quit { + +void RecordHistogram(ConfirmQuitMetric sample) { + HISTOGRAM_ENUMERATION("ConfirmToQuit", sample, kSampleCount); +} + +} // namespace confirm_quit + // Custom Content View ///////////////////////////////////////////////////////// // The content view of the window that draws a custom frame. @@ -71,8 +86,9 @@ const NSTimeInterval kWindowFadeAnimationDuration = 0.2; scoped_nsobject<NSMutableAttributedString> attrString( [[NSMutableAttributedString alloc] initWithString:text]); scoped_nsobject<NSShadow> textShadow([[NSShadow alloc] init]); - [textShadow setShadowColor:[NSColor colorWithCalibratedWhite:0 alpha:0.6]]; - [textShadow setShadowOffset:NSMakeSize(0, -1)]; + [textShadow.get() setShadowColor:[NSColor colorWithCalibratedWhite:0 + alpha:0.6]]; + [textShadow.get() setShadowOffset:NSMakeSize(0, -1)]; [textShadow setShadowBlurRadius:1.0]; [attrString addAttribute:NSShadowAttributeName value:textShadow @@ -96,11 +112,49 @@ const NSTimeInterval kWindowFadeAnimationDuration = 0.2; @end +// Animation /////////////////////////////////////////////////////////////////// + +// This animation will run through all the windows of the passed-in +// NSApplication and will fade their alpha value to 0.0. When the animation is +// complete, this will release itself. +@interface FadeAllWindowsAnimation : NSAnimation<NSAnimationDelegate> { + @private + NSApplication* application_; +} +- (id)initWithApplication:(NSApplication*)app + animationDuration:(NSTimeInterval)duration; +@end + + +@implementation FadeAllWindowsAnimation + +- (id)initWithApplication:(NSApplication*)app + animationDuration:(NSTimeInterval)duration { + if ((self = [super initWithDuration:duration + animationCurve:NSAnimationLinear])) { + application_ = app; + [self setDelegate:self]; + } + return self; +} + +- (void)setCurrentProgress:(NSAnimationProgress)progress { + for (NSWindow* window in [application_ windows]) { + [window setAlphaValue:1.0 - progress]; + } +} + +- (void)animationDidStop:(NSAnimation*)anim { + DCHECK_EQ(self, anim); + [self autorelease]; +} + +@end + // Private Interface /////////////////////////////////////////////////////////// @interface ConfirmQuitPanelController (Private) - (void)animateFadeOut; -- (NSString*)keyCommandString; - (NSEvent*)pumpEventQueueForKeyUp:(NSApplication*)app untilDate:(NSDate*)date; - (void)hideAllWindowsForApplication:(NSApplication*)app withDuration:(NSTimeInterval)duration; @@ -117,7 +171,7 @@ ConfirmQuitPanelController* g_confirmQuitPanelController = nil; g_confirmQuitPanelController = [[ConfirmQuitPanelController alloc] init]; } - return g_confirmQuitPanelController; + return [[g_confirmQuitPanelController retain] autorelease]; } - (id)init { @@ -142,7 +196,7 @@ ConfirmQuitPanelController* g_confirmQuitPanelController = nil; // Set the proper string. NSString* message = l10n_util::GetNSStringF(IDS_CONFIRM_TO_QUIT_DESCRIPTION, - base::SysNSStringToUTF16([self keyCommandString])); + base::SysNSStringToUTF16([[self class] keyCommandString])); [contentView_ setMessageText:message]; } return self; @@ -151,12 +205,14 @@ ConfirmQuitPanelController* g_confirmQuitPanelController = nil; + (BOOL)eventTriggersFeature:(NSEvent*)event { if ([event type] != NSKeyDown) return NO; - ui::AcceleratorCocoa eventAccelerator([event characters], + ui::AcceleratorCocoa eventAccelerator([event charactersIgnoringModifiers], [event modifierFlags] & NSDeviceIndependentModifierFlagsMask); return [self quitAccelerator] == eventAccelerator; } - (NSApplicationTerminateReply)runModalLoopForApplication:(NSApplication*)app { + scoped_nsobject<ConfirmQuitPanelController> keepAlive([self retain]); + // If this is the second of two such attempts to quit within a certain time // interval, then just quit. // Time of last quit attempt, if any. @@ -176,6 +232,12 @@ ConfirmQuitPanelController* g_confirmQuitPanelController = nil; NSEvent* nextEvent = [self pumpEventQueueForKeyUp:app untilDate:[NSDate distantFuture]]; [app discardEventsMatchingMask:NSAnyEventMask beforeEvent:nextEvent]; + + // Based on how long the user held the keys, record the metric. + if ([[NSDate date] timeIntervalSinceDate:timeNow] < kDoubleTapTimeDelta) + confirm_quit::RecordHistogram(confirm_quit::kDoubleTap); + else + confirm_quit::RecordHistogram(confirm_quit::kTapHold); return NSTerminateNow; } else { [lastQuitAttempt release]; // Harmless if already nil. @@ -191,9 +253,12 @@ ConfirmQuitPanelController* g_confirmQuitPanelController = nil; BOOL willQuit = NO; NSEvent* nextEvent = nil; do { - // Dequeue events until a key up is received. - // TODO(rsesek): Explore using |untilDate| with |targetDate|. - nextEvent = [self pumpEventQueueForKeyUp:app untilDate:nil]; + // Dequeue events until a key up is received. To avoid busy waiting, figure + // out the amount of time that the thread can sleep before taking further + // action. + NSDate* waitDate = [NSDate dateWithTimeIntervalSinceNow: + kTimeToConfirmQuit - kTimeDeltaFuzzFactor]; + nextEvent = [self pumpEventQueueForKeyUp:app untilDate:waitDate]; // Wait for the time expiry to happen. Once past the hold threshold, // commit to quitting and hide all the open windows. @@ -219,6 +284,7 @@ ConfirmQuitPanelController* g_confirmQuitPanelController = nil; if (willQuit) { // The user held down the combination long enough that quitting should // happen. + confirm_quit::RecordHistogram(confirm_quit::kHoldDuration); return NSTerminateNow; } else { // Slowly fade the confirm window out in case the user doesn't @@ -242,7 +308,7 @@ ConfirmQuitPanelController* g_confirmQuitPanelController = nil; - (void)showWindow:(id)sender { // If a panel that is fading out is going to be reused here, make sure it // does not get released when the animation finishes. - scoped_nsobject<ConfirmQuitPanelController> stayAlive([self retain]); + scoped_nsobject<ConfirmQuitPanelController> keepAlive([self retain]); [[self window] setAnimations:[NSDictionary dictionary]]; [[self window] center]; [[self window] setAlphaValue:1.0]; @@ -293,9 +359,9 @@ ConfirmQuitPanelController* g_confirmQuitPanelController = nil; // This looks at the Main Menu and determines what the user has set as the // key combination for quit. It then gets the modifiers and builds a string // to display them. -- (NSString*)keyCommandString { ++ (NSString*)keyCommandString { ui::AcceleratorCocoa accelerator = [[self class] quitAccelerator]; - return [self keyCombinationForAccelerator:accelerator]; + return [[self class] keyCombinationForAccelerator:accelerator]; } // Runs a nested loop that pumps the event queue until the next KeyUp event. @@ -309,23 +375,14 @@ ConfirmQuitPanelController* g_confirmQuitPanelController = nil; // Iterates through the list of open windows and hides them all. - (void)hideAllWindowsForApplication:(NSApplication*)app withDuration:(NSTimeInterval)duration { - [NSAnimationContext beginGrouping]; - [[NSAnimationContext currentContext] setDuration:duration]; - for (NSWindow* window in [app windows]) { - // Windows that are set to animate and have a delegate do no expect to be - // animated by other things and could result in an invalid state. If a - // window is set up like so, just force the alpha value to 0. Otherwise, - // animate all pretty and stuff. - if (duration > 0 && ![[window animationForKey:@"alphaValue"] delegate]) { - [[window animator] setAlphaValue:0.0]; - } else { - [window setAlphaValue:0.0]; - } - } - [NSAnimationContext endGrouping]; + FadeAllWindowsAnimation* animation = + [[FadeAllWindowsAnimation alloc] initWithApplication:app + animationDuration:duration]; + // Releases itself when the animation stops. + [animation startAnimation]; } -- (NSString*)keyCombinationForAccelerator:(const ui::AcceleratorCocoa&)item { ++ (NSString*)keyCombinationForAccelerator:(const ui::AcceleratorCocoa&)item { NSMutableString* string = [NSMutableString string]; NSUInteger modifiers = item.modifiers(); diff --git a/chrome/browser/ui/cocoa/confirm_quit_panel_controller_unittest.mm b/chrome/browser/ui/cocoa/confirm_quit_panel_controller_unittest.mm index 899b444..36aed30 100644 --- a/chrome/browser/ui/cocoa/confirm_quit_panel_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/confirm_quit_panel_controller_unittest.mm @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "chrome/browser/ui/cocoa/confirm_quit_panel_controller.h" #include "testing/gtest_mac.h" @@ -40,8 +40,7 @@ TEST_F(ConfirmQuitPanelControllerTest, ShowAndDismiss) { } TEST_F(ConfirmQuitPanelControllerTest, KeyCombinationForAccelerator) { - scoped_nsobject<ConfirmQuitPanelController> controller( - [[ConfirmQuitPanelController alloc] init]); + Class controller = [ConfirmQuitPanelController class]; ui::AcceleratorCocoa item = ui::AcceleratorCocoa(@"q", NSCommandKeyMask); EXPECT_NSEQ(TestString(@"{Cmd}Q"), diff --git a/chrome/browser/ui/cocoa/constrained_html_delegate_mac.mm b/chrome/browser/ui/cocoa/constrained_html_delegate_mac.mm index 620e7fb..d3cabc5 100644 --- a/chrome/browser/ui/cocoa/constrained_html_delegate_mac.mm +++ b/chrome/browser/ui/cocoa/constrained_html_delegate_mac.mm @@ -4,13 +4,15 @@ #include "chrome/browser/ui/webui/constrained_html_ui.h" -#include "base/scoped_nsobject.h" +#import <Cocoa/Cocoa.h> + +#include "base/memory/scoped_nsobject.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/cocoa/constrained_window_mac.h" #include "chrome/browser/ui/webui/html_dialog_ui.h" #include "chrome/browser/ui/webui/html_dialog_tab_contents_delegate.h" #include "content/browser/tab_contents/tab_contents.h" -#import <Cocoa/Cocoa.h> +#include "ui/gfx/size.h" class ConstrainedHtmlDelegateMac : public ConstrainedWindowMacDelegateCustomSheet, @@ -38,7 +40,6 @@ class ConstrainedHtmlDelegateMac : // HtmlDialogTabContentsDelegate --------------------------------------------- void MoveContents(TabContents* source, const gfx::Rect& pos) {} - void ToolbarSizeChanged(TabContents* source, bool is_animating) {} void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {} void set_window(ConstrainedWindow* window) { @@ -121,7 +122,7 @@ void ConstrainedHtmlDelegateMac::OnDialogClose() { } // static -void ConstrainedHtmlUI::CreateConstrainedHtmlDialog( +ConstrainedWindow* ConstrainedHtmlUI::CreateConstrainedHtmlDialog( Profile* profile, HtmlDialogUIDelegate* delegate, TabContents* overshadowed) { @@ -132,6 +133,7 @@ void ConstrainedHtmlUI::CreateConstrainedHtmlDialog( ConstrainedWindow* constrained_window = overshadowed->CreateConstrainedDialog(constrained_delegate); constrained_delegate->set_window(constrained_window); + return constrained_window; } @implementation ConstrainedHtmlDialogSheetCocoa diff --git a/chrome/browser/ui/cocoa/constrained_window_mac.h b/chrome/browser/ui/cocoa/constrained_window_mac.h index 629262b..2de151a 100644 --- a/chrome/browser/ui/cocoa/constrained_window_mac.h +++ b/chrome/browser/ui/cocoa/constrained_window_mac.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -12,7 +12,7 @@ #include "base/basictypes.h" #include "base/logging.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" @class BrowserWindowController; @class GTMWindowSheetController; diff --git a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.h b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.h index 1ac8ed3..eda63ae 100644 --- a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.h +++ b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.h @@ -1,18 +1,19 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/cookies_tree_model.h" #include "chrome/browser/ui/cocoa/constrained_window_mac.h" #import "chrome/browser/ui/cocoa/content_settings/cookie_tree_node.h" -#include "chrome/common/notification_registrar.h" +#include "content/common/notification_registrar.h" @class CollectedCookiesWindowController; +@class CookieDetailsViewController; @class VerticalGradientView; class TabContents; @@ -54,6 +55,7 @@ class CollectedCookiesMac : public ConstrainedWindowMacDelegateCustomSheet, // very thin bridge (see cookies_window_controller.h). @interface CollectedCookiesWindowController : NSWindowController <NSOutlineViewDelegate, + NSTabViewDelegate, NSWindowDelegate> { @private // Platform-independent model. @@ -77,15 +79,20 @@ class CollectedCookiesMac : public ConstrainedWindowMacDelegateCustomSheet, IBOutlet VerticalGradientView* infoBar_; IBOutlet NSImageView* infoBarIcon_; IBOutlet NSTextField* infoBarText_; - IBOutlet NSSplitView* splitView_; - IBOutlet NSScrollView* lowerScrollView_; + IBOutlet NSTabView* tabView_; + IBOutlet NSScrollView* blockedScrollView_; IBOutlet NSTextField* blockedCookiesText_; + IBOutlet NSView* cookieDetailsViewPlaceholder_; scoped_nsobject<NSViewAnimation> animation_; + scoped_nsobject<CookieDetailsViewController> detailsViewController_; + TabContents* tabContents_; // weak BOOL infoBarVisible_; + + BOOL contentSettingsChanged_; } @property(readonly, nonatomic) NSTreeController* allowedTreeController; @property(readonly, nonatomic) NSTreeController* blockedTreeController; @@ -103,19 +110,13 @@ class CollectedCookiesMac : public ConstrainedWindowMacDelegateCustomSheet, - (IBAction)allowForSessionFromOrigin:(id)sender; - (IBAction)blockOrigin:(id)sender; -// NSSplitView delegate methods: -- (CGFloat) splitView:(NSSplitView *)sender - constrainMinCoordinate:(CGFloat)proposedMin - ofSubviewAt:(NSInteger)offset; -- (BOOL)splitView:(NSSplitView *)sender canCollapseSubview:(NSView *)subview; - -// Returns the cocoaAllowedTreeModel_ and cocoaBlockedTreeModel_. +// Returns the |cocoaAllowedTreeModel_| and |cocoaBlockedTreeModel_|. - (CocoaCookieTreeNode*)cocoaAllowedTreeModel; - (CocoaCookieTreeNode*)cocoaBlockedTreeModel; - (void)setCocoaAllowedTreeModel:(CocoaCookieTreeNode*)model; - (void)setCocoaBlockedTreeModel:(CocoaCookieTreeNode*)model; -// Returns the allowedTreeModel_ and blockedTreeModel_. +// Returns the |allowedTreeModel_| and |blockedTreeModel_|. - (CookiesTreeModel*)allowedTreeModel; - (CookiesTreeModel*)blockedTreeModel; diff --git a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm index 87c7c72..0c7c664 100644 --- a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm +++ b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,17 +9,19 @@ #import "base/mac/mac_util.h" #include "base/sys_string_conversions.h" #include "chrome/browser/profiles/profile.h" +#import "chrome/browser/ui/cocoa/content_settings/cookie_details_view_controller.h" #import "chrome/browser/ui/cocoa/vertical_gradient_view.h" -#include "chrome/common/notification_details.h" -#include "chrome/common/notification_source.h" +#include "chrome/browser/ui/collected_cookies_infobar_delegate.h" #include "content/browser/tab_contents/tab_contents.h" +#include "content/common/notification_details.h" +#include "content/common/notification_source.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "skia/ext/skia_utils_mac.h" -#include "third_party/apple/ImageAndTextCell.h" -#include "third_party/skia/include/core/SkBitmap.h" #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" +#include "third_party/apple/ImageAndTextCell.h" +#include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/l10n/l10n_util_mac.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/image.h" @@ -32,8 +34,11 @@ const double kBannerGradientColorBottom[3] = {250.0 / 255.0, 230.0 / 255.0, 145.0 / 255.0}; const double kBannerStrokeColor = 135.0 / 255.0; -// Minimal height for the collected cookies dialog. -const CGFloat kMinCollectedCookiesViewHeight = 116; +enum TabViewItemIndices { + kAllowedCookiesTabIndex = 0, + kBlockedCookiesTabIndex +}; + } // namespace #pragma mark Bridge between the constrained window delegate and the sheet @@ -134,13 +139,12 @@ void CollectedCookiesMac::OnSheetDidEnd(NSWindow* sheet) { - (id)initWithTabContents:(TabContents*)tabContents { DCHECK(tabContents); - infoBarVisible_ = NO; - tabContents_ = tabContents; NSString* nibpath = [base::mac::MainAppBundle() pathForResource:@"CollectedCookies" ofType:@"nib"]; if ((self = [super initWithWindowNibPath:nibpath owner:self])) { + tabContents_ = tabContents; [self loadTreeModelFromTabContents]; animation_.reset([[NSViewAnimation alloc] init]); @@ -184,25 +188,34 @@ void CollectedCookiesMac::OnSheetDidEnd(NSWindow* sheet) { CGFloat textDeltaY = [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:blockedCookiesText_]; - // Shrink the upper custom view. - NSView* upperContentView = [[splitView_ subviews] objectAtIndex:0]; - NSRect frame = [upperContentView frame]; - [splitView_ setPosition:(frame.size.height - textDeltaY/2.0) - ofDividerAtIndex:0]; - - // Shrink the lower outline view. - frame = [lowerScrollView_ frame]; + // Shrink the blocked cookies outline view. + NSRect frame = [blockedScrollView_ frame]; frame.size.height -= textDeltaY; - [lowerScrollView_ setFrame:frame]; + [blockedScrollView_ setFrame:frame]; // Move the label down so it actually fits. frame = [blockedCookiesText_ frame]; frame.origin.y -= textDeltaY; [blockedCookiesText_ setFrame:frame]; } + + detailsViewController_.reset([[CookieDetailsViewController alloc] init]); + + NSView* detailView = [detailsViewController_.get() view]; + NSRect viewFrameRect = [cookieDetailsViewPlaceholder_ frame]; + [[detailsViewController_.get() view] setFrame:viewFrameRect]; + [[cookieDetailsViewPlaceholder_ superview] + replaceSubview:cookieDetailsViewPlaceholder_ + with:detailView]; + + [self tabView:tabView_ didSelectTabViewItem:[tabView_ selectedTabViewItem]]; } - (void)windowWillClose:(NSNotification*)notif { + if (contentSettingsChanged_) { + tabContents_->AddInfoBar( + new CollectedCookiesInfoBarDelegate(tabContents_)); + } [allowedOutlineView_ setDelegate:nil]; [blockedOutlineView_ setDelegate:nil]; [animation_ stopAnimation]; @@ -238,6 +251,7 @@ void CollectedCookiesMac::OnSheetDidEnd(NSWindow* sheet) { [self showInfoBarForMultipleDomainsAndSetting:setting]; else [self showInfoBarForDomain:lastDomain setting:setting]; + contentSettingsChanged_ = YES; } - (IBAction)allowOrigin:(id)sender { @@ -255,20 +269,6 @@ void CollectedCookiesMac::OnSheetDidEnd(NSWindow* sheet) { forTreeController:allowedTreeController_]; } -- (CGFloat) splitView:(NSSplitView *)sender - constrainMinCoordinate:(CGFloat)proposedMin - ofSubviewAt:(NSInteger)offset { - return proposedMin + kMinCollectedCookiesViewHeight; -} -- (CGFloat) splitView:(NSSplitView *)sender - constrainMaxCoordinate:(CGFloat)proposedMax - ofSubviewAt:(NSInteger)offset { - return proposedMax - kMinCollectedCookiesViewHeight; -} -- (BOOL)splitView:(NSSplitView *)sender canCollapseSubview:(NSView *)subview { - return YES; -} - - (CocoaCookieTreeNode*)cocoaAllowedTreeModel { return cocoaAllowedTreeModel_.get(); } @@ -450,16 +450,13 @@ void CollectedCookiesMac::OnSheetDidEnd(NSWindow* sheet) { NSWindow* sheet = [self window]; NSRect sheetFrame = [sheet frame]; NSRect infoBarFrame = [infoBar_ frame]; - NSRect splitViewFrame = [splitView_ frame]; + NSRect tabViewFrame = [tabView_ frame]; // Calculate the end position of the info bar and set it to its start // position. infoBarFrame.origin.y = NSHeight(sheetFrame); infoBarFrame.size.width = NSWidth(sheetFrame); - NSRect infoBarStartFrame = infoBarFrame; - infoBarStartFrame.origin.y += NSHeight(infoBarFrame); - infoBarStartFrame.size.height = 0.0; - [infoBar_ setFrame:infoBarStartFrame]; + [infoBar_ setFrame:infoBarFrame]; [[[self window] contentView] addSubview:infoBar_]; // Calculate the new position of the sheet. @@ -472,14 +469,12 @@ void CollectedCookiesMac::OnSheetDidEnd(NSWindow* sheet) { infoBar_, NSViewAnimationTargetKey, [NSValue valueWithRect:infoBarFrame], NSViewAnimationEndFrameKey, - [NSValue valueWithRect:infoBarStartFrame], - NSViewAnimationStartFrameKey, nil]]; - // Make sure the split view ends up in the right position. + // Make sure the tab view ends up in the right position. [animations addObject: [NSDictionary dictionaryWithObjectsAndKeys: - splitView_, NSViewAnimationTargetKey, - [NSValue valueWithRect:splitViewFrame], + tabView_, NSViewAnimationTargetKey, + [NSValue valueWithRect:tabViewFrame], NSViewAnimationEndFrameKey, nil]]; @@ -498,4 +493,21 @@ void CollectedCookiesMac::OnSheetDidEnd(NSWindow* sheet) { [animation_ startAnimation]; } +- (void) tabView:(NSTabView*)tabView + didSelectTabViewItem:(NSTabViewItem*)tabViewItem { + NSTreeController* treeController = nil; + switch ([tabView indexOfTabViewItem:tabViewItem]) { + case kAllowedCookiesTabIndex: + treeController = allowedTreeController_; + break; + case kBlockedCookiesTabIndex: + treeController = blockedTreeController_; + break; + default: + NOTREACHED(); + return; + } + [detailsViewController_ configureBindingsForTreeController:treeController]; +} + @end diff --git a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac_unittest.mm b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac_unittest.mm index fb7a330..de960ae 100644 --- a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac_unittest.mm +++ b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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" +#include "base/memory/ref_counted.h" #include "chrome/browser/profiles/profile.h" #import "chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.h" #include "content/browser/renderer_host/test_render_view_host.h" diff --git a/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.h b/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.h index 362f3ea..6f59b99 100644 --- a/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.h +++ b/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -7,8 +7,8 @@ #import <Cocoa/Cocoa.h> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #import "chrome/browser/ui/cocoa/base_bubble_controller.h" class ContentSettingBubbleModel; diff --git a/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.mm b/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.mm index cbecce9..9624dd1 100644 --- a/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.mm +++ b/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.mm @@ -15,7 +15,6 @@ #import "chrome/browser/ui/cocoa/hyperlink_button_cell.h" #import "chrome/browser/ui/cocoa/info_bubble_view.h" #import "chrome/browser/ui/cocoa/l10n_util.h" -#import "chrome/browser/ui/cocoa/options/content_settings_dialog_controller.h" #include "grit/generated_resources.h" #include "skia/ext/skia_utils_mac.h" #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" diff --git a/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa_unittest.mm b/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa_unittest.mm index 9f38322..1888be3 100644 --- a/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa_unittest.mm +++ b/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa_unittest.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -7,7 +7,7 @@ #import <Cocoa/Cocoa.h> #include "base/debug/debugger.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/browser/content_setting_bubble_model.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "chrome/common/content_settings_types.h" diff --git a/chrome/browser/ui/cocoa/content_settings/cookie_details.h b/chrome/browser/ui/cocoa/content_settings/cookie_details.h index 050e379..a162336 100644 --- a/chrome/browser/ui/cocoa/content_settings/cookie_details.h +++ b/chrome/browser/ui/cocoa/content_settings/cookie_details.h @@ -1,13 +1,13 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/memory/scoped_nsobject.h" #include "chrome/browser/browsing_data_database_helper.h" #include "chrome/browser/browsing_data_indexed_db_helper.h" #include "chrome/browser/browsing_data_local_storage_helper.h" -#include "base/scoped_nsobject.h" #include "net/base/cookie_monster.h" #include "webkit/appcache/appcache_service.h" diff --git a/chrome/browser/ui/cocoa/content_settings/cookie_tree_node.h b/chrome/browser/ui/cocoa/content_settings/cookie_tree_node.h index 175a1b5..818e0ed 100644 --- a/chrome/browser/ui/cocoa/content_settings/cookie_tree_node.h +++ b/chrome/browser/ui/cocoa/content_settings/cookie_tree_node.h @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/browser/cookies_tree_model.h" #include "chrome/browser/ui/cocoa/content_settings/cookie_details.h" diff --git a/chrome/browser/ui/cocoa/content_settings/cookie_tree_node.mm b/chrome/browser/ui/cocoa/content_settings/cookie_tree_node.mm index e6a08bd..92aad45 100644 --- a/chrome/browser/ui/cocoa/content_settings/cookie_tree_node.mm +++ b/chrome/browser/ui/cocoa/content_settings/cookie_tree_node.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -39,7 +39,7 @@ - (NSMutableArray*)mutableChildren { if (!children_.get()) { - const int childCount = treeNode_->GetChildCount(); + const int childCount = treeNode_->child_count(); children_.reset([[NSMutableArray alloc] initWithCapacity:childCount]); for (int i = 0; i < childCount; ++i) { CookieTreeNode* child = treeNode_->GetChild(i); diff --git a/chrome/browser/ui/cocoa/content_settings/simple_content_exceptions_window_controller.h b/chrome/browser/ui/cocoa/content_settings/simple_content_exceptions_window_controller.h deleted file mode 100644 index 61fd48c..0000000 --- a/chrome/browser/ui/cocoa/content_settings/simple_content_exceptions_window_controller.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2010 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> - -#import "base/mac/cocoa_protocols.h" -#include "base/scoped_ptr.h" -#include "chrome/browser/remove_rows_table_model.h" -#import "chrome/browser/ui/cocoa/table_model_array_controller.h" - -class RemoveRowsObserverBridge; - -// Controller for the geolocation exception dialog. -@interface SimpleContentExceptionsWindowController : NSWindowController - <NSWindowDelegate> { - @private - IBOutlet NSTableView* tableView_; - IBOutlet NSButton* removeButton_; - IBOutlet NSButton* removeAllButton_; - IBOutlet NSButton* doneButton_; - IBOutlet TableModelArrayController* arrayController_; - - scoped_ptr<RemoveRowsTableModel> model_; -} - -// Shows or makes frontmost the exceptions window. -// Changes made by the user in the window are persisted in |model|. -// Takes ownership of |model|. -+ (id)controllerWithTableModel:(RemoveRowsTableModel*)model; - -// Sets the minimum width of the sheet and resizes it if necessary. -- (void)setMinWidth:(CGFloat)minWidth; - -- (void)attachSheetTo:(NSWindow*)window; -- (IBAction)closeSheet:(id)sender; - -@end diff --git a/chrome/browser/ui/cocoa/content_settings/simple_content_exceptions_window_controller.mm b/chrome/browser/ui/cocoa/content_settings/simple_content_exceptions_window_controller.mm deleted file mode 100644 index b78b269..0000000 --- a/chrome/browser/ui/cocoa/content_settings/simple_content_exceptions_window_controller.mm +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2010 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/ui/cocoa/content_settings/simple_content_exceptions_window_controller.h" - -#include "base/logging.h" -#import "base/mac/mac_util.h" -#import "base/scoped_nsobject.h" -#include "base/sys_string_conversions.h" -#include "grit/generated_resources.h" -#include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" -#include "ui/base/l10n/l10n_util_mac.h" -#include "ui/base/models/table_model_observer.h" - -@interface SimpleContentExceptionsWindowController (Private) -- (id)initWithTableModel:(RemoveRowsTableModel*)model; -@end - -namespace { - -const CGFloat kButtonBarHeight = 35.0; - -SimpleContentExceptionsWindowController* g_exceptionWindow = nil; - -} // namespace - -@implementation SimpleContentExceptionsWindowController - -+ (id)controllerWithTableModel:(RemoveRowsTableModel*)model { - if (!g_exceptionWindow) { - g_exceptionWindow = [[SimpleContentExceptionsWindowController alloc] - initWithTableModel:model]; - } - return g_exceptionWindow; -} - -- (id)initWithTableModel:(RemoveRowsTableModel*)model { - NSString* nibpath = [base::mac::MainAppBundle() - pathForResource:@"SimpleContentExceptionsWindow" - ofType:@"nib"]; - if ((self = [super initWithWindowNibPath:nibpath owner:self])) { - model_.reset(model); - - // TODO(thakis): autoremember window rect. - // TODO(thakis): sorting support. - } - return self; -} - -- (void)awakeFromNib { - DCHECK([self window]); - DCHECK_EQ(self, [[self window] delegate]); - DCHECK(tableView_); - DCHECK(arrayController_); - - CGFloat minWidth = [[removeButton_ superview] bounds].size.width + - [[doneButton_ superview] bounds].size.width; - [[self window] setMinSize:NSMakeSize(minWidth, - [[self window] minSize].height)]; - NSDictionary* columns = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInt:IDS_EXCEPTIONS_HOSTNAME_HEADER], @"hostname", - [NSNumber numberWithInt:IDS_EXCEPTIONS_ACTION_HEADER], @"action", - nil]; - [arrayController_ bindToTableModel:model_.get() - withColumns:columns - groupTitleColumn:@"hostname"]; -} - -- (void)setMinWidth:(CGFloat)minWidth { - NSWindow* window = [self window]; - [window setMinSize:NSMakeSize(minWidth, [window minSize].height)]; - if ([window frame].size.width < minWidth) { - NSRect frame = [window frame]; - frame.size.width = minWidth; - [window setFrame:frame display:NO]; - } -} - -- (void)windowWillClose:(NSNotification*)notification { - g_exceptionWindow = nil; - [self autorelease]; -} - -// Let esc close the window. -- (void)cancel:(id)sender { - [self closeSheet:self]; -} - -- (void)keyDown:(NSEvent*)event { - NSString* chars = [event charactersIgnoringModifiers]; - if ([chars length] == 1) { - switch ([chars characterAtIndex:0]) { - case NSDeleteCharacter: - case NSDeleteFunctionKey: - // Delete deletes. - if ([[tableView_ selectedRowIndexes] count] > 0) - [arrayController_ remove:event]; - return; - } - } - [super keyDown:event]; -} - -- (void)attachSheetTo:(NSWindow*)window { - [NSApp beginSheet:[self window] - modalForWindow:window - modalDelegate:self - didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) - contextInfo:nil]; -} - -- (void)sheetDidEnd:(NSWindow*)sheet - returnCode:(NSInteger)returnCode - contextInfo:(void*)context { - [sheet close]; - [sheet orderOut:self]; -} - -- (IBAction)closeSheet:(id)sender { - [NSApp endSheet:[self window]]; -} - - -@end diff --git a/chrome/browser/ui/cocoa/content_settings/simple_content_exceptions_window_controller_unittest.mm b/chrome/browser/ui/cocoa/content_settings/simple_content_exceptions_window_controller_unittest.mm deleted file mode 100644 index ec5b2f5..0000000 --- a/chrome/browser/ui/cocoa/content_settings/simple_content_exceptions_window_controller_unittest.mm +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2010 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/ui/cocoa/content_settings/simple_content_exceptions_window_controller.h" - -#import <Cocoa/Cocoa.h> - -#import "base/scoped_nsobject.h" -#include "base/ref_counted.h" -#include "chrome/browser/content_settings/host_content_settings_map.h" -#include "chrome/browser/geolocation/geolocation_exceptions_table_model.h" -#include "chrome/browser/plugin_exceptions_table_model.h" -#include "chrome/browser/ui/cocoa/browser_test_helper.h" -#include "chrome/browser/ui/cocoa/cocoa_test_helper.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -@interface SimpleContentExceptionsWindowController (Testing) - -@property(readonly, nonatomic) TableModelArrayController* arrayController; - -@end - -@implementation SimpleContentExceptionsWindowController (Testing) - -- (TableModelArrayController*)arrayController { - return arrayController_; -} - -@end - - -namespace { - -class SimpleContentExceptionsWindowControllerTest : public CocoaTest { - public: - virtual void SetUp() { - CocoaTest::SetUp(); - TestingProfile* profile = browser_helper_.profile(); - geolocation_settings_ = new GeolocationContentSettingsMap(profile); - content_settings_ = new HostContentSettingsMap(profile); - } - - SimpleContentExceptionsWindowController* GetController() { - GeolocationExceptionsTableModel* model = // Freed by window controller. - new GeolocationExceptionsTableModel(geolocation_settings_.get()); - id controller = [SimpleContentExceptionsWindowController - controllerWithTableModel:model]; - [controller showWindow:nil]; - return controller; - } - - void ClickRemoveAll(SimpleContentExceptionsWindowController* controller) { - [controller.arrayController removeAll:nil]; - } - - protected: - BrowserTestHelper browser_helper_; - scoped_refptr<GeolocationContentSettingsMap> geolocation_settings_; - scoped_refptr<HostContentSettingsMap> content_settings_; -}; - -TEST_F(SimpleContentExceptionsWindowControllerTest, Construction) { - GeolocationExceptionsTableModel* model = // Freed by window controller. - new GeolocationExceptionsTableModel(geolocation_settings_.get()); - SimpleContentExceptionsWindowController* controller = - [SimpleContentExceptionsWindowController controllerWithTableModel:model]; - [controller showWindow:nil]; - [controller close]; // Should autorelease. -} - -TEST_F(SimpleContentExceptionsWindowControllerTest, ShowPluginExceptions) { - PluginExceptionsTableModel* model = // Freed by window controller. - new PluginExceptionsTableModel(content_settings_.get(), NULL); - SimpleContentExceptionsWindowController* controller = - [SimpleContentExceptionsWindowController controllerWithTableModel:model]; - [controller showWindow:nil]; - [controller close]; // Should autorelease. -} - -TEST_F(SimpleContentExceptionsWindowControllerTest, AddExistingEditAdd) { - geolocation_settings_->SetContentSetting( - GURL("http://myhost"), GURL(), CONTENT_SETTING_BLOCK); - - SimpleContentExceptionsWindowController* controller = GetController(); - ClickRemoveAll(controller); - - [controller close]; - - EXPECT_EQ(0u, geolocation_settings_->GetAllOriginsSettings().size()); -} - -} // namespace diff --git a/chrome/browser/ui/cocoa/dev_tools_controller.h b/chrome/browser/ui/cocoa/dev_tools_controller.h index e8fa567..7de513e 100644 --- a/chrome/browser/ui/cocoa/dev_tools_controller.h +++ b/chrome/browser/ui/cocoa/dev_tools_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,7 +8,7 @@ #import <Foundation/Foundation.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h" @class NSSplitView; diff --git a/chrome/browser/ui/cocoa/dev_tools_controller.mm b/chrome/browser/ui/cocoa/dev_tools_controller.mm index 81ebd26..c7a2c11 100644 --- a/chrome/browser/ui/cocoa/dev_tools_controller.mm +++ b/chrome/browser/ui/cocoa/dev_tools_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -12,6 +12,7 @@ #include "chrome/browser/debugger/devtools_window.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #import "chrome/browser/ui/cocoa/view_id_util.h" #include "chrome/common/pref_names.h" #include "content/browser/tab_contents/tab_contents.h" @@ -68,8 +69,10 @@ const int kMinWebHeight = 50; - (void)updateDevToolsForTabContents:(TabContents*)contents withProfile:(Profile*)profile { // Get current devtools content. - TabContents* devToolsContents = contents ? + TabContentsWrapper* devToolsTab = contents ? DevToolsWindow::GetDevToolsContents(contents) : NULL; + TabContents* devToolsContents = devToolsTab ? + devToolsTab->tab_contents() : NULL; [self showDevToolsContents:devToolsContents withProfile:profile]; } diff --git a/chrome/browser/ui/cocoa/dock_icon.mm b/chrome/browser/ui/cocoa/dock_icon.mm index 980519a..562326e 100644 --- a/chrome/browser/ui/cocoa/dock_icon.mm +++ b/chrome/browser/ui/cocoa/dock_icon.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/dock_icon.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" // The fraction of the size of the dock icon that the badge is. static const float kBadgeFraction = 0.4f; diff --git a/chrome/browser/ui/cocoa/download/download_item_button.mm b/chrome/browser/ui/cocoa/download/download_item_button.mm index da9f6b4..ef1eb69 100644 --- a/chrome/browser/ui/cocoa/download/download_item_button.mm +++ b/chrome/browser/ui/cocoa/download/download_item_button.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -47,4 +47,8 @@ [[self cell] setHighlighted:NO]; } +- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent*)event { + return YES; +} + @end diff --git a/chrome/browser/ui/cocoa/download/download_item_button_unittest.mm b/chrome/browser/ui/cocoa/download/download_item_button_unittest.mm index bb0279d..acf0242 100644 --- a/chrome/browser/ui/cocoa/download/download_item_button_unittest.mm +++ b/chrome/browser/ui/cocoa/download/download_item_button_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/download/download_item_button.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/download/download_item_cell.h b/chrome/browser/ui/cocoa/download/download_item_cell.h index 32415e0..91bceb5 100644 --- a/chrome/browser/ui/cocoa/download/download_item_cell.h +++ b/chrome/browser/ui/cocoa/download/download_item_cell.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -7,7 +7,7 @@ #pragma once #import "base/mac/cocoa_protocols.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_ptr.h" #import "chrome/browser/ui/cocoa/gradient_button_cell.h" #include "base/file_path.h" diff --git a/chrome/browser/ui/cocoa/download/download_item_cell.mm b/chrome/browser/ui/cocoa/download/download_item_cell.mm index 37e300a..cb18b48 100644 --- a/chrome/browser/ui/cocoa/download/download_item_cell.mm +++ b/chrome/browser/ui/cocoa/download/download_item_cell.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,7 +9,7 @@ #include "chrome/browser/download/download_item_model.h" #include "chrome/browser/download/download_manager.h" #include "chrome/browser/download/download_util.h" -#import "chrome/browser/themes/browser_theme_provider.h" +#import "chrome/browser/themes/theme_service.h" #import "chrome/browser/ui/cocoa/download/download_item_cell.h" #import "chrome/browser/ui/cocoa/image_utils.h" #import "chrome/browser/ui/cocoa/themed_window.h" @@ -22,58 +22,61 @@ namespace { -// Distance from top border to icon +// Distance from top border to icon. const CGFloat kImagePaddingTop = 7; -// Distance from left border to icon +// Distance from left border to icon. const CGFloat kImagePaddingLeft = 9; -// Width of icon +// Width of icon. const CGFloat kImageWidth = 16; -// Height of icon +// Height of icon. const CGFloat kImageHeight = 16; -// x coordinate of download name string, in view coords +// x coordinate of download name string, in view coords. const CGFloat kTextPosLeft = kImagePaddingLeft + kImageWidth + download_util::kSmallProgressIconOffset; -// Distance from end of download name string to dropdown area +// Distance from end of download name string to dropdown area. const CGFloat kTextPaddingRight = 3; // y coordinate of download name string, in view coords, when status message -// is visible +// is visible. const CGFloat kPrimaryTextPosTop = 3; // y coordinate of download name string, in view coords, when status message -// is not visible +// is not visible. const CGFloat kPrimaryTextOnlyPosTop = 10; -// y coordinate of status message, in view coords +// y coordinate of status message, in view coords. const CGFloat kSecondaryTextPosTop = 18; -// Grey value of status text +// Grey value of status text. const CGFloat kSecondaryTextColor = 0.5; // Width of dropdown area on the right (includes 1px for the border on each // side). const CGFloat kDropdownAreaWidth = 14; -// Width of dropdown arrow +// Width of dropdown arrow. const CGFloat kDropdownArrowWidth = 5; -// Height of dropdown arrow +// Height of dropdown arrow. const CGFloat kDropdownArrowHeight = 3; // Vertical displacement of dropdown area, relative to the "centered" position. const CGFloat kDropdownAreaY = -2; -// Duration of the two-lines-to-one-line animation, in seconds +// Duration of the two-lines-to-one-line animation, in seconds. NSTimeInterval kHideStatusDuration = 0.3; -// Duration of the 'download complete' animation, in seconds +// Duration of the 'download complete' animation, in seconds. const int kCompleteAnimationDuration = 2.5; +// Duration of the 'download interrupted' animation, in seconds. +const int kInterruptedAnimationDuration = 2.5; + } // This is a helper class to animate the fading out of the status text. @@ -142,7 +145,7 @@ NSColor* BackgroundTheme::GetNSColor(int id, bool allow_default) const { } NSColor* BackgroundTheme::GetNSColorTint(int id, bool allow_default) const { - if (id == BrowserThemeProvider::TINT_BUTTONS) + if (id == ThemeService::TINT_BUTTONS) return borderColor_.get(); return provider_->GetNSColorTint(id, allow_default); @@ -150,11 +153,11 @@ NSColor* BackgroundTheme::GetNSColorTint(int id, bool allow_default) const { NSGradient* BackgroundTheme::GetNSGradient(int id) const { switch (id) { - case BrowserThemeProvider::GRADIENT_TOOLBAR_BUTTON: - case BrowserThemeProvider::GRADIENT_TOOLBAR_BUTTON_INACTIVE: + case ThemeService::GRADIENT_TOOLBAR_BUTTON: + case ThemeService::GRADIENT_TOOLBAR_BUTTON_INACTIVE: return buttonGradient_.get(); - case BrowserThemeProvider::GRADIENT_TOOLBAR_BUTTON_PRESSED: - case BrowserThemeProvider::GRADIENT_TOOLBAR_BUTTON_PRESSED_INACTIVE: + case ThemeService::GRADIENT_TOOLBAR_BUTTON_PRESSED: + case ThemeService::GRADIENT_TOOLBAR_BUTTON_PRESSED_INACTIVE: return buttonPressedGradient_.get(); default: return provider_->GetNSGradient(id); @@ -267,6 +270,21 @@ NSGradient* BackgroundTheme::GetNSGradient(int id) const { case DownloadItem::CANCELLED: percentDone_ = -1; break; + case DownloadItem::INTERRUPTED: + // Small downloads may start in an interrupted state due to asynchronous + // notifications. In this case, we'll get a second complete notification + // via the observers, so we ignore it and avoid creating a second complete + // animation. + if (completionAnimation_.get()) + break; + completionAnimation_.reset([[DownloadItemCellAnimation alloc] + initWithDownloadItemCell:self + duration:kInterruptedAnimationDuration + animationCurve:NSAnimationLinear]); + [completionAnimation_.get() setDelegate:self]; + [completionAnimation_.get() startAnimation]; + percentDone_ = -2; + break; case DownloadItem::IN_PROGRESS: percentDone_ = downloadModel->download()->is_paused() ? -1 : downloadModel->download()->PercentComplete(); @@ -435,7 +453,7 @@ NSGradient* BackgroundTheme::GetNSGradient(int id) const { ui::ThemeProvider* themeProvider = [[[self controlView] window] themeProvider]; NSColor* themeTextColor = - themeProvider->GetNSColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT, + themeProvider->GetNSColor(ThemeService::COLOR_BOOKMARK_TEXT, true); return [self pressedWithDefaultThemeOnPart:part] ? [NSColor alternateSelectedControlTextColor] : themeTextColor; @@ -491,8 +509,8 @@ NSGradient* BackgroundTheme::GetNSGradient(int id) const { if (!isDefaultTheme) { themeProvider = [self backgroundThemeWrappingProvider:themeProvider]; bgGradient = themeProvider->GetNSGradient( - active ? BrowserThemeProvider::GRADIENT_TOOLBAR_BUTTON : - BrowserThemeProvider::GRADIENT_TOOLBAR_BUTTON_INACTIVE); + active ? ThemeService::GRADIENT_TOOLBAR_BUTTON : + ThemeService::GRADIENT_TOOLBAR_BUTTON_INACTIVE); } NSRect buttonDrawRect, dropdownDrawRect; @@ -580,10 +598,17 @@ NSGradient* BackgroundTheme::GetNSGradient(int id) const { canvas.set_composite_alpha(true); if (completionAnimation_.get()) { if ([completionAnimation_ isAnimating]) { - download_util::PaintDownloadComplete(&canvas, - x, y, - [completionAnimation_ currentValue], - download_util::SMALL); + if (percentDone_ == -1) { + download_util::PaintDownloadComplete(&canvas, + x, y, + [completionAnimation_ currentValue], + download_util::SMALL); + } else { + download_util::PaintDownloadInterrupted(&canvas, + x, y, + [completionAnimation_ currentValue], + download_util::SMALL); + } } } else if (percentDone_ >= 0) { download_util::PaintDownloadProgress(&canvas, diff --git a/chrome/browser/ui/cocoa/download/download_item_controller.h b/chrome/browser/ui/cocoa/download/download_item_controller.h index c41ff43..6d8fb44 100644 --- a/chrome/browser/ui/cocoa/download/download_item_controller.h +++ b/chrome/browser/ui/cocoa/download/download_item_controller.h @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_ptr.h" +#include "base/memory/scoped_ptr.h" #include "base/time.h" class BaseDownloadItemModel; diff --git a/chrome/browser/ui/cocoa/download/download_item_controller.mm b/chrome/browser/ui/cocoa/download/download_item_controller.mm index 60eb845..6d92901 100644 --- a/chrome/browser/ui/cocoa/download/download_item_controller.mm +++ b/chrome/browser/ui/cocoa/download/download_item_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -14,7 +14,7 @@ #include "chrome/browser/download/download_item_model.h" #include "chrome/browser/download/download_shelf.h" #include "chrome/browser/download/download_util.h" -#import "chrome/browser/themes/browser_theme_provider.h" +#import "chrome/browser/themes/theme_service.h" #import "chrome/browser/ui/cocoa/download/download_item_button.h" #import "chrome/browser/ui/cocoa/download/download_item_cell.h" #include "chrome/browser/ui/cocoa/download/download_item_mac.h" @@ -231,7 +231,7 @@ class DownloadShelfContextMenuMac : public DownloadShelfContextMenu { } // Set correct popup menu. Also, set draggable download on completion. - if (downloadModel->download()->state() == DownloadItem::COMPLETE) { + if (downloadModel->download()->IsComplete()) { [progressView_ setMenu:completeDownloadMenu_]; [progressView_ setDownload:downloadModel->download()->full_path()]; } else { @@ -324,7 +324,7 @@ class DownloadShelfContextMenuMac : public DownloadShelfContextMenu { // Called after the current theme has changed. - (void)themeDidChangeNotification:(NSNotification*)aNotification { ui::ThemeProvider* themeProvider = - static_cast<ui::ThemeProvider*>([[aNotification object] pointerValue]); + static_cast<ThemeService*>([[aNotification object] pointerValue]); [self updateTheme:themeProvider]; } @@ -332,7 +332,7 @@ class DownloadShelfContextMenuMac : public DownloadShelfContextMenu { // this is shown for the first time. - (void)updateTheme:(ui::ThemeProvider*)themeProvider { NSColor* color = - themeProvider->GetNSColor(BrowserThemeProvider::COLOR_TAB_TEXT, true); + themeProvider->GetNSColor(ThemeService::COLOR_TAB_TEXT, true); [dangerousDownloadLabel_ setTextColor:color]; } @@ -348,10 +348,10 @@ class DownloadShelfContextMenuMac : public DownloadShelfContextMenu { - (IBAction)discardDownload:(id)sender { UMA_HISTOGRAM_LONG_TIMES("clickjacking.discard_download", base::Time::Now() - creationTime_); - if (bridge_->download_model()->download()->state() == - DownloadItem::IN_PROGRESS) - bridge_->download_model()->download()->Cancel(true); - bridge_->download_model()->download()->Remove(true); + DownloadItem* download = bridge_->download_model()->download(); + if (download->IsPartialDownload()) + download->Cancel(true); + download->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); // WARNING: we are deleted at this point. Don't access 'this'. } diff --git a/chrome/browser/ui/cocoa/download/download_item_mac.h b/chrome/browser/ui/cocoa/download/download_item_mac.h index 8eafb17..24d9c4a 100644 --- a/chrome/browser/ui/cocoa/download/download_item_mac.h +++ b/chrome/browser/ui/cocoa/download/download_item_mac.h @@ -8,8 +8,8 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/download/download_item.h" #include "chrome/browser/download/download_manager.h" #include "chrome/browser/icon_manager.h" @@ -38,7 +38,6 @@ class DownloadItemMac : DownloadItem::Observer { // DownloadItem::Observer implementation virtual void OnDownloadUpdated(DownloadItem* download); virtual void OnDownloadOpened(DownloadItem* download); - virtual void OnDownloadFileCompleted(DownloadItem* download) { } BaseDownloadItemModel* download_model() { return download_model_.get(); } diff --git a/chrome/browser/ui/cocoa/download/download_item_mac.mm b/chrome/browser/ui/cocoa/download/download_item_mac.mm index 7c02af2..0297ab4 100644 --- a/chrome/browser/ui/cocoa/download/download_item_mac.mm +++ b/chrome/browser/ui/cocoa/download/download_item_mac.mm @@ -56,6 +56,7 @@ void DownloadItemMac::OnDownloadUpdated(DownloadItem* download) { download_util::NotifySystemOfDownloadComplete(download->full_path()); // fall through case DownloadItem::IN_PROGRESS: + case DownloadItem::INTERRUPTED: case DownloadItem::CANCELLED: [item_controller_ setStateFromDownload:download_model_.get()]; break; diff --git a/chrome/browser/ui/cocoa/download/download_shelf_controller.h b/chrome/browser/ui/cocoa/download/download_shelf_controller.h index e75911f..cacedd8 100644 --- a/chrome/browser/ui/cocoa/download/download_shelf_controller.h +++ b/chrome/browser/ui/cocoa/download/download_shelf_controller.h @@ -1,12 +1,12 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #import "chrome/browser/ui/cocoa/view_resizer.h" @class AnimatableView; @@ -17,6 +17,7 @@ class Browser; class DownloadShelf; @class DownloadShelfView; @class HyperlinkButtonCell; +@class HoverButton; // A controller class that manages the download shelf for one window. It is // responsible for the behavior of the shelf itself (showing/hiding, handling @@ -41,8 +42,12 @@ class DownloadShelf; IBOutlet NSImageView* image_; + IBOutlet HoverButton* hoverCloseButton_; + BOOL barIsVisible_; + BOOL isFullscreen_; + scoped_ptr<DownloadShelf> bridge_; // Height of the shelf when it's fully visible. diff --git a/chrome/browser/ui/cocoa/download/download_shelf_controller.mm b/chrome/browser/ui/cocoa/download/download_shelf_controller.mm index 26d00fc..a40c36c 100644 --- a/chrome/browser/ui/cocoa/download/download_shelf_controller.mm +++ b/chrome/browser/ui/cocoa/download/download_shelf_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,7 +9,8 @@ #include "chrome/browser/download/download_item.h" #include "chrome/browser/download/download_manager.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/themes/browser_theme_provider.h" +#include "chrome/browser/themes/theme_service.h" +#include "chrome/browser/themes/theme_service_factory.h" #include "chrome/browser/ui/browser.h" #import "chrome/browser/ui/cocoa/animatable_view.h" #include "chrome/browser/ui/cocoa/browser_window_cocoa.h" @@ -17,6 +18,8 @@ #include "chrome/browser/ui/cocoa/download/download_item_controller.h" #include "chrome/browser/ui/cocoa/download/download_shelf_mac.h" #import "chrome/browser/ui/cocoa/download/download_shelf_view.h" +#import "chrome/browser/ui/cocoa/fullscreen_controller.h" +#import "chrome/browser/ui/cocoa/hover_button.h" #import "chrome/browser/ui/cocoa/hyperlink_button_cell.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" @@ -62,6 +65,9 @@ const NSTimeInterval kDownloadShelfCloseDuration = 0.12; // autoclosed, in seconds. const NSTimeInterval kAutoCloseDelaySeconds = 5; +// The size of the x button by default. +const NSSize kHoverCloseButtonDefaultSize = { 16, 16 }; + } // namespace @interface DownloadShelfController(Private) @@ -76,6 +82,10 @@ const NSTimeInterval kAutoCloseDelaySeconds = 5; - (void)installTrackingArea; - (void)cancelAutoCloseAndRemoveTrackingArea; + +- (void)willEnterFullscreen; +- (void)willLeaveFullscreen; +- (void)updateCloseButton; @end @@ -88,6 +98,10 @@ const NSTimeInterval kAutoCloseDelaySeconds = 5; resizeDelegate_ = resizeDelegate; maxShelfHeight_ = NSHeight([[self view] bounds]); currentShelfHeight_ = maxShelfHeight_; + if (browser && browser->window()) + isFullscreen_ = browser->window()->IsFullscreen(); + else + isFullscreen_ = NO; // Reset the download shelf's frame height to zero. It will be properly // positioned and sized the first time we try to set its height. (Just @@ -106,6 +120,8 @@ const NSTimeInterval kAutoCloseDelaySeconds = 5; } - (void)awakeFromNib { + DCHECK(hoverCloseButton_); + NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter]; [defaultCenter addObserver:self selector:@selector(themeDidChangeNotification:) @@ -123,6 +139,17 @@ const NSTimeInterval kAutoCloseDelaySeconds = 5; NSImage* favicon = rb.GetNativeImageNamed(IDR_DOWNLOADS_FAVICON); DCHECK(favicon); [image_ setImage:favicon]; + + // These notifications are declared in fullscreen_controller, and are posted + // without objects. + [defaultCenter addObserver:self + selector:@selector(willEnterFullscreen) + name:kWillEnterFullscreenNotification + object:nil]; + [defaultCenter addObserver:self + selector:@selector(willLeaveFullscreen) + name:kWillLeaveFullscreenNotification + object:nil]; } - (void)dealloc { @@ -163,10 +190,10 @@ const NSTimeInterval kAutoCloseDelaySeconds = 5; if (bridge_.get() && bridge_->browser() && bridge_->browser()->profile()) { ui::ThemeProvider* provider = - bridge_->browser()->profile()->GetThemeProvider(); + ThemeServiceFactory::GetForProfile(bridge_->browser()->profile()); color = - provider->GetNSColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT, false); + provider->GetNSColor(ThemeService::COLOR_BOOKMARK_TEXT, false); } if (!color) @@ -239,6 +266,7 @@ const NSTimeInterval kAutoCloseDelaySeconds = 5; [view animateToNewHeight:0 duration:kDownloadShelfCloseDuration]; barIsVisible_ = enable; + [self updateCloseButton]; } - (DownloadShelf*)bridge { @@ -355,9 +383,9 @@ const NSTimeInterval kAutoCloseDelaySeconds = 5; DownloadItemController* itemController = [downloadItemControllers_ objectAtIndex:i]; DownloadItem* download = [itemController download]; - bool isTransferDone = - download->state() == DownloadItem::COMPLETE || - download->state() == DownloadItem::CANCELLED; + bool isTransferDone = download->IsComplete() || + download->IsCancelled() || + download->IsInterrupted(); if (isTransferDone && download->safety_state() != DownloadItem::DANGEROUS) { [self remove:itemController]; @@ -425,4 +453,40 @@ const NSTimeInterval kAutoCloseDelaySeconds = 5; } } +- (void)willEnterFullscreen { + isFullscreen_ = YES; + [self updateCloseButton]; +} + +- (void)willLeaveFullscreen { + isFullscreen_ = NO; + [self updateCloseButton]; +} + +- (void)updateCloseButton { + if (!barIsVisible_) + return; + + NSRect selfBounds = [[self view] bounds]; + NSRect hoverFrame = [hoverCloseButton_ frame]; + NSRect bounds; + + if (isFullscreen_) { + bounds = NSMakeRect(NSMinX(hoverFrame), 0, + selfBounds.size.width - NSMinX(hoverFrame), + selfBounds.size.height); + } else { + bounds.origin.x = NSMinX(hoverFrame); + bounds.origin.y = NSMidY(hoverFrame) - + kHoverCloseButtonDefaultSize.height / 2.0; + bounds.size = kHoverCloseButtonDefaultSize; + } + + // Set the tracking off to create a new tracking area for the control. + // When changing the bounds/frame on a HoverButton, the tracking isn't updated + // correctly, it needs to be turned off and back on. + [hoverCloseButton_ setTrackingEnabled:NO]; + [hoverCloseButton_ setFrame:bounds]; + [hoverCloseButton_ setTrackingEnabled:YES]; +} @end diff --git a/chrome/browser/ui/cocoa/download/download_shelf_view.mm b/chrome/browser/ui/cocoa/download/download_shelf_view.mm index 55b88d5..3ab757c 100644 --- a/chrome/browser/ui/cocoa/download/download_shelf_view.mm +++ b/chrome/browser/ui/cocoa/download/download_shelf_view.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/download/download_shelf_view.h" -#include "base/scoped_nsobject.h" -#include "chrome/browser/themes/browser_theme_provider.h" +#include "base/memory/scoped_nsobject.h" +#include "chrome/browser/themes/theme_service.h" #import "chrome/browser/ui/cocoa/themed_window.h" #import "chrome/browser/ui/cocoa/view_id_util.h" #include "grit/theme_resources.h" @@ -16,8 +16,8 @@ BOOL isKey = [[self window] isKeyWindow]; ui::ThemeProvider* themeProvider = [[self window] themeProvider]; return themeProvider ? themeProvider->GetNSColor( - isKey ? BrowserThemeProvider::COLOR_TOOLBAR_STROKE : - BrowserThemeProvider::COLOR_TOOLBAR_STROKE_INACTIVE, true) : + isKey ? ThemeService::COLOR_TOOLBAR_STROKE : + ThemeService::COLOR_TOOLBAR_STROKE_INACTIVE, true) : [NSColor blackColor]; } @@ -38,8 +38,8 @@ NSRectFill([self bounds]); } else { NSGradient* gradient = themeProvider->GetNSGradient( - isKey ? BrowserThemeProvider::GRADIENT_TOOLBAR : - BrowserThemeProvider::GRADIENT_TOOLBAR_INACTIVE); + isKey ? ThemeService::GRADIENT_TOOLBAR : + ThemeService::GRADIENT_TOOLBAR_INACTIVE); NSPoint startPoint = [self convertPoint:NSMakePoint(0, 0) fromView:nil]; NSPoint endPoint = [self convertPoint:NSMakePoint(0, [self frame].size.height) diff --git a/chrome/browser/ui/cocoa/download/download_shelf_view_unittest.mm b/chrome/browser/ui/cocoa/download/download_shelf_view_unittest.mm index 926593f..b7263fc 100644 --- a/chrome/browser/ui/cocoa/download/download_shelf_view_unittest.mm +++ b/chrome/browser/ui/cocoa/download/download_shelf_view_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/download/download_shelf_view.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/download/download_started_animation_mac.mm b/chrome/browser/ui/cocoa/download/download_started_animation_mac.mm index b316d18..1abc3c0 100644 --- a/chrome/browser/ui/cocoa/download/download_started_animation_mac.mm +++ b/chrome/browser/ui/cocoa/download/download_started_animation_mac.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. // @@ -12,11 +12,11 @@ #import <QuartzCore/QuartzCore.h> #include "chrome/browser/tab_contents/tab_contents_view_mac.h" -#include "chrome/common/notification_registrar.h" #import "chrome/browser/ui/cocoa/animatable_image.h" -#include "chrome/common/notification_details.h" -#include "chrome/common/notification_source.h" #include "content/browser/tab_contents/tab_contents.h" +#include "content/common/notification_details.h" +#include "content/common/notification_registrar.h" +#include "content/common/notification_source.h" #include "grit/theme_resources.h" #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" #include "third_party/skia/include/utils/mac/SkCGUtils.h" diff --git a/chrome/browser/ui/cocoa/download/download_util_mac_unittest.mm b/chrome/browser/ui/cocoa/download/download_util_mac_unittest.mm index bd99e02..2230207 100644 --- a/chrome/browser/ui/cocoa/download/download_util_mac_unittest.mm +++ b/chrome/browser/ui/cocoa/download/download_util_mac_unittest.mm @@ -51,7 +51,7 @@ TEST_F(DownloadUtilMacTest, AddFileToPasteboardTest) { NSArray* files = [pasteboard() propertyListForType:NSFilenamesPboardType]; ASSERT_TRUE(files != nil); NSString* expectedPath = [files objectAtIndex:0]; - NSString* realPath = base::SysWideToNSString(testPath.ToWStringHack()); + NSString* realPath = base::SysUTF8ToNSString(testPath.value()); EXPECT_NSEQ(expectedPath, realPath); } diff --git a/chrome/browser/ui/cocoa/draggable_button.h b/chrome/browser/ui/cocoa/draggable_button.h index ab74c2b..4e0d596 100644 --- a/chrome/browser/ui/cocoa/draggable_button.h +++ b/chrome/browser/ui/cocoa/draggable_button.h @@ -17,6 +17,13 @@ NSTimeInterval whenMouseDown_; } +@property NSTimeInterval durationMouseWasDown; + +@property NSTimeInterval whenMouseDown; + +// Whether the action has already fired for this click. +@property(nonatomic) BOOL actionHasFired; + // Enable or disable dragability for special buttons like "Other Bookmarks". @property(nonatomic) BOOL draggable; @@ -31,11 +38,6 @@ // -drag* methods of NSView when overriding this method. - (void)beginDrag:(NSEvent*)dragEvent; -// Called internally. Default impl only returns YES if sender==self. -// Override if your subclass wants to accept being tracked into while a -// click is being tracked on another DraggableButton. Needed to support -// buttons being used as fake menu items or menu titles, as BookmarkButton does. -- (BOOL)acceptsTrackInFrom:(id)sender; // Override if you want to do any extra work on mouseUp, after a mouseDown // action has already fired. @@ -65,8 +67,6 @@ yHysteresis:(float)yHysteresis; -@property(nonatomic) NSTimeInterval durationMouseWasDown; - @end // @interface DraggableButton @interface DraggableButton (Private) diff --git a/chrome/browser/ui/cocoa/draggable_button.mm b/chrome/browser/ui/cocoa/draggable_button.mm index 654ae25..25f3fe7 100644 --- a/chrome/browser/ui/cocoa/draggable_button.mm +++ b/chrome/browser/ui/cocoa/draggable_button.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/draggable_button.h" #include "base/logging.h" -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" namespace { @@ -22,6 +22,9 @@ const CGFloat kDragExpirationTimeout = 1.0; @synthesize draggable = draggable_; @synthesize actsOnMouseDown = actsOnMouseDown_; @synthesize durationMouseWasDown = durationMouseWasDown_; +@synthesize actionHasFired = actionHasFired_; +@synthesize whenMouseDown = whenMouseDown_; + - (id)initWithFrame:(NSRect)frame { if ((self = [super initWithFrame:frame])) { @@ -153,62 +156,33 @@ const CGFloat kDragExpirationTimeout = 1.0; // action has already fired. } -- (BOOL)acceptsTrackInFrom:(id)sender { - return (sender == self); -} - - (void)performMouseDownAction:(NSEvent*)theEvent { - int eventMask = NSLeftMouseUpMask | NSMouseEnteredMask | NSMouseExitedMask; + int eventMask = NSLeftMouseUpMask; [[self target] performSelector:[self action] withObject:self]; actionHasFired_ = YES; - DraggableButton* insideBtn = nil; - while (1) { theEvent = [[self window] nextEventMatchingMask:eventMask]; + if (!theEvent) + continue; NSPoint mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; BOOL isInside = [self mouse:mouseLoc inRect:[self bounds]]; + [self highlight:isInside]; switch ([theEvent type]) { - case NSMouseEntered: - case NSMouseExited: { - NSView* trackedView = (NSView*)[[theEvent trackingArea] owner]; - if (trackedView && [trackedView isKindOfClass:[self class]]) { - DraggableButton *btn = static_cast<DraggableButton*>(trackedView); - if (![btn acceptsTrackInFrom:self]) - break; - if ([theEvent type] == NSMouseEntered) { - [[NSCursor arrowCursor] set]; - [[btn cell] mouseEntered:theEvent]; - insideBtn = btn; - } else { - [[btn cell] mouseExited:theEvent]; - if (insideBtn == btn) - insideBtn = nil; - } - } - break; - } - case NSLeftMouseUp: { - if (!isInside && insideBtn && insideBtn != self) { - // Has tracked onto another DraggableButton menu item, and released, - // so click it. - [insideBtn performClick:self]; - } + case NSLeftMouseUp: durationMouseWasDown_ = [theEvent timestamp] - whenMouseDown_; [self secondaryMouseUpAction:isInside]; - [[self cell] mouseExited:theEvent]; - [[insideBtn cell] mouseExited:theEvent]; - return; break; - } default: /* Ignore any other kind of event. */ break; } } + + [self highlight:NO]; } // Mimic "begin a click" operation visually. Do NOT follow through diff --git a/chrome/browser/ui/cocoa/draggable_button_unittest.mm b/chrome/browser/ui/cocoa/draggable_button_unittest.mm index 2700a49..110d306 100644 --- a/chrome/browser/ui/cocoa/draggable_button_unittest.mm +++ b/chrome/browser/ui/cocoa/draggable_button_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/draggable_button.h" #import "chrome/browser/ui/cocoa/test_event_utils.h" diff --git a/chrome/browser/ui/cocoa/extensions/browser_action_button.h b/chrome/browser/ui/cocoa/extensions/browser_action_button.h index a09ce7f..e8bad88 100644 --- a/chrome/browser/ui/cocoa/extensions/browser_action_button.h +++ b/chrome/browser/ui/cocoa/extensions/browser_action_button.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,8 +8,8 @@ #import <Cocoa/Cocoa.h> -#import "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#import "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #import "chrome/browser/ui/cocoa/gradient_button_cell.h" class Extension; diff --git a/chrome/browser/ui/cocoa/extensions/browser_action_button.mm b/chrome/browser/ui/cocoa/extensions/browser_action_button.mm index f4480c2..aaaefb9 100644 --- a/chrome/browser/ui/cocoa/extensions/browser_action_button.mm +++ b/chrome/browser/ui/cocoa/extensions/browser_action_button.mm @@ -15,10 +15,10 @@ #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_action.h" #include "chrome/common/extensions/extension_resource.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "chrome/common/notification_source.h" -#include "chrome/common/notification_type.h" +#include "content/common/notification_observer.h" +#include "content/common/notification_registrar.h" +#include "content/common/notification_source.h" +#include "content/common/notification_type.h" #include "skia/ext/skia_utils_mac.h" #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" #include "ui/gfx/canvas_skia_paint.h" @@ -37,7 +37,6 @@ static const CGFloat kBrowserActionBadgeOriginYOffset = 5; namespace { const CGFloat kAnimationDuration = 0.2; -const CGFloat kShadowOffset = 2.0; } // anonymous namespace // A helper class to bridge the asynchronous Skia bitmap loading mechanism to @@ -65,7 +64,8 @@ class ExtensionImageTrackerBridge : public NotificationObserver, ~ExtensionImageTrackerBridge() {} // ImageLoadingTracker::Observer implementation. - void OnImageLoaded(SkBitmap* image, ExtensionResource resource, int index) { + void OnImageLoaded(SkBitmap* image, const ExtensionResource& resource, + int index) { if (image) [owner_ setDefaultIcon:gfx::SkBitmapToNSImage(*image)]; [owner_ updateState]; @@ -94,12 +94,11 @@ class ExtensionImageTrackerBridge : public NotificationObserver, DISALLOW_COPY_AND_ASSIGN(ExtensionImageTrackerBridge); }; -@interface BrowserActionCell(Internals) -- (void)setIconShadow; +@interface BrowserActionCell (Internals) - (void)drawBadgeWithinFrame:(NSRect)frame; @end -@interface BrowserActionButton(Private) +@interface BrowserActionButton (Private) - (void)endDrag; @end @@ -275,7 +274,6 @@ class ExtensionImageTrackerBridge : public NotificationObserver, [[NSColor clearColor] set]; NSRectFill(bounds); - [[self cell] setIconShadow]; NSImage* actionImage = [self image]; const NSSize imageSize = [actionImage size]; @@ -289,8 +287,7 @@ class ExtensionImageTrackerBridge : public NotificationObserver, fraction:1.0 neverFlipped:YES]; - bounds.origin.y += kShadowOffset - kBrowserActionBadgeOriginYOffset; - bounds.origin.x -= kShadowOffset; + bounds.origin.y += kBrowserActionBadgeOriginYOffset; [[self cell] drawBadgeWithinFrame:bounds]; [image unlockFocus]; @@ -304,16 +301,6 @@ class ExtensionImageTrackerBridge : public NotificationObserver, @synthesize tabId = tabId_; @synthesize extensionAction = extensionAction_; -- (void)setIconShadow { - // Create the shadow below and to the right of the drawn image. - scoped_nsobject<NSShadow> imgShadow([[NSShadow alloc] init]); - [imgShadow.get() setShadowOffset:NSMakeSize(kShadowOffset, -kShadowOffset)]; - [imgShadow setShadowBlurRadius:2.0]; - [imgShadow.get() setShadowColor:[[NSColor blackColor] - colorWithAlphaComponent:0.3]]; - [imgShadow set]; -} - - (void)drawBadgeWithinFrame:(NSRect)frame { gfx::CanvasSkiaPaint canvas(frame, false); canvas.set_composite_alpha(true); @@ -323,7 +310,6 @@ class ExtensionImageTrackerBridge : public NotificationObserver, - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { [NSGraphicsContext saveGraphicsState]; - [self setIconShadow]; [super drawInteriorWithFrame:cellFrame inView:controlView]; cellFrame.origin.y += kBrowserActionBadgeOriginYOffset; [self drawBadgeWithinFrame:cellFrame]; diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm b/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm index 3d10e22..c6b1fa6 100644 --- a/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm +++ b/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -7,7 +7,7 @@ #include <algorithm> #include "base/basictypes.h" -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/view_id_util.h" NSString* const kBrowserActionGrippyDragStartedNotification = diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_container_view_unittest.mm b/chrome/browser/ui/cocoa/extensions/browser_actions_container_view_unittest.mm index 002aa05..14b5c1b 100644 --- a/chrome/browser/ui/cocoa/extensions/browser_actions_container_view_unittest.mm +++ b/chrome/browser/ui/cocoa/extensions/browser_actions_container_view_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/extensions/browser_actions_container_view.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.h b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.h index 1f19863..02a26d9 100644 --- a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.h +++ b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,8 +8,8 @@ #import <Cocoa/Cocoa.h> -#import "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#import "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" class Browser; @class BrowserActionButton; diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm index 7fc94c1..e8d899e 100644 --- a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm +++ b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -11,8 +11,8 @@ #include "base/sys_string_conversions.h" #include "chrome/browser/extensions/extension_browser_event_router.h" #include "chrome/browser/extensions/extension_host.h" -#include "chrome/browser/extensions/extension_toolbar_model.h" #include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/extension_toolbar_model.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" @@ -22,12 +22,12 @@ #import "chrome/browser/ui/cocoa/extensions/extension_popup_controller.h" #import "chrome/browser/ui/cocoa/menu_button.h" #include "chrome/common/extensions/extension_action.h" -#include "chrome/common/notification_details.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "chrome/common/notification_source.h" #include "chrome/common/pref_names.h" #include "content/browser/tab_contents/tab_contents.h" +#include "content/common/notification_details.h" +#include "content/common/notification_observer.h" +#include "content/common/notification_registrar.h" +#include "content/common/notification_source.h" #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" NSString* const kBrowserActionVisibilityChangedNotification = @@ -749,8 +749,9 @@ class ExtensionServiceObserverBridge : public NotificationObserver, - (BOOL)shouldDisplayBrowserAction:(const Extension*)extension { // Only display incognito-enabled extensions while in incognito mode. - return (!profile_->IsOffTheRecord() || - profile_->GetExtensionService()->IsIncognitoEnabled(extension)); + return + (!profile_->IsOffTheRecord() || + profile_->GetExtensionService()->IsIncognitoEnabled(extension->id())); } - (void)showChevronIfNecessaryInFrame:(NSRect)frame animate:(BOOL)animate { diff --git a/chrome/browser/ui/cocoa/extensions/chevron_menu_button_unittest.mm b/chrome/browser/ui/cocoa/extensions/chevron_menu_button_unittest.mm index 71c8929..4336c49 100644 --- a/chrome/browser/ui/cocoa/extensions/chevron_menu_button_unittest.mm +++ b/chrome/browser/ui/cocoa/extensions/chevron_menu_button_unittest.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/extensions/chevron_menu_button.h" #import "chrome/browser/ui/cocoa/extensions/chevron_menu_button_cell.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" namespace { diff --git a/chrome/browser/ui/cocoa/extensions/extension_action_context_menu.h b/chrome/browser/ui/cocoa/extensions/extension_action_context_menu.h index 9af03e1..ae4b5a2 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_action_context_menu.h +++ b/chrome/browser/ui/cocoa/extensions/extension_action_context_menu.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,8 +8,8 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_ptr.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" class AsyncUninstaller; class DevmodeObserver; diff --git a/chrome/browser/ui/cocoa/extensions/extension_action_context_menu.mm b/chrome/browser/ui/cocoa/extensions/extension_action_context_menu.mm index 3248619..989c472 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_action_context_menu.mm +++ b/chrome/browser/ui/cocoa/extensions/extension_action_context_menu.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -6,13 +6,13 @@ #include "base/sys_string_conversions.h" #include "base/task.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/extensions/extension_install_ui.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_tabs_module.h" +#include "chrome/browser/extensions/extension_uninstall_dialog.h" #include "chrome/browser/prefs/pref_change_registrar.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/cocoa/browser_window_cocoa.h" #include "chrome/browser/ui/cocoa/browser_window_controller.h" #include "chrome/browser/ui/cocoa/extensions/browser_actions_controller.h" @@ -23,36 +23,35 @@ #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_action.h" #include "chrome/common/extensions/extension_constants.h" -#include "chrome/common/notification_details.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_source.h" -#include "chrome/common/notification_type.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" +#include "content/common/notification_details.h" +#include "content/common/notification_observer.h" +#include "content/common/notification_source.h" +#include "content/common/notification_type.h" #include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util_mac.h" // A class that loads the extension icon on the I/O thread before showing the // confirmation dialog to uninstall the given extension. // Also acts as the extension's UI delegate in order to display the dialog. -class AsyncUninstaller : public ExtensionInstallUI::Delegate { +class AsyncUninstaller : public ExtensionUninstallDialog::Delegate { public: AsyncUninstaller(const Extension* extension, Profile* profile) : extension_(extension), profile_(profile) { - install_ui_.reset(new ExtensionInstallUI(profile)); - install_ui_->ConfirmUninstall(this, extension_); + extension_uninstall_dialog_.reset(new ExtensionUninstallDialog(profile)); + extension_uninstall_dialog_->ConfirmUninstall(this, extension_); } ~AsyncUninstaller() {} - // Overridden by ExtensionInstallUI::Delegate. - virtual void InstallUIProceed() { + // ExtensionUninstallDialog::Delegate: + virtual void ExtensionDialogAccepted() { profile_->GetExtensionService()-> - UninstallExtension(extension_->id(), false); + UninstallExtension(extension_->id(), false, NULL); } - - virtual void InstallUIAbort() {} + virtual void ExtensionDialogCanceled() {} private: // The extension that we're loading the icon for. Weak. @@ -61,7 +60,7 @@ class AsyncUninstaller : public ExtensionInstallUI::Delegate { // The current profile. Weak. Profile* profile_; - scoped_ptr<ExtensionInstallUI> install_ui_; + scoped_ptr<ExtensionUninstallDialog> extension_uninstall_dialog_; DISALLOW_COPY_AND_ASSIGN(AsyncUninstaller); }; diff --git a/chrome/browser/ui/cocoa/extensions/extension_infobar_controller.h b/chrome/browser/ui/cocoa/extensions/extension_infobar_controller.h index d160782..f1d0987 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_infobar_controller.h +++ b/chrome/browser/ui/cocoa/extensions/extension_infobar_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -10,8 +10,8 @@ #import <Cocoa/Cocoa.h> -#import "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#import "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" @class ExtensionActionContextMenu; class ExtensionInfoBarDelegate; diff --git a/chrome/browser/ui/cocoa/extensions/extension_infobar_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_infobar_controller.mm index 2a64d7d..982b1d7 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_infobar_controller.mm +++ b/chrome/browser/ui/cocoa/extensions/extension_infobar_controller.mm @@ -8,6 +8,7 @@ #include "chrome/browser/extensions/extension_host.h" #include "chrome/browser/extensions/extension_infobar_delegate.h" +#include "chrome/browser/extensions/image_loading_tracker.h" #import "chrome/browser/ui/cocoa/animatable_view.h" #import "chrome/browser/ui/cocoa/extensions/extension_action_context_menu.h" #import "chrome/browser/ui/cocoa/menu_button.h" @@ -82,7 +83,7 @@ class InfobarBridge : public ExtensionInfoBarDelegate::DelegateObserver, // TODO(andybons): The infobar view implementations share a lot of the same // code. Come up with a strategy to share amongst them. virtual void OnImageLoaded( - SkBitmap* image, ExtensionResource resource, int index) { + SkBitmap* image, const ExtensionResource& resource, int index) { if (!delegate_) return; // The delegate can go away while the image asynchronously loads. diff --git a/chrome/browser/ui/cocoa/extensions/extension_install_prompt_controller.h b/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.h index b110217..8c7818d 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_install_prompt_controller.h +++ b/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.h @@ -1,16 +1,16 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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_UI_COCOA_EXTENSION_INSTALL_PROMPT_H_ -#define CHROME_BROWSER_UI_COCOA_EXTENSION_INSTALL_PROMPT_H_ +#ifndef CHROME_BROWSER_UI_COCOA_EXTENSIONS_EXTENSION_INSTALL_DIALOG_CONTROLER_H_ +#define CHROME_BROWSER_UI_COCOA_EXTENSIONS_EXTENSION_INSTALL_DIALOG_CONTROLER_H_ #pragma once #include <vector> #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/string16.h" #include "chrome/browser/extensions/extension_install_ui.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -20,7 +20,7 @@ class Profile; // A controller for dialog to let the user install an extension. Created by // CrxInstaller. -@interface ExtensionInstallPromptController : NSWindowController { +@interface ExtensionInstallDialogController : NSWindowController { @private IBOutlet NSImageView* iconView_; IBOutlet NSTextField* titleField_; @@ -62,4 +62,4 @@ class Profile; @end -#endif /* CHROME_BROWSER_UI_COCOA_EXTENSION_INSTALL_PROMPT_H_ */ +#endif // CHROME_BROWSER_UI_COCOA_EXTENSIONS_EXTENSION_INSTALL_DIALOG_CONTROLLER_H_ diff --git a/chrome/browser/ui/cocoa/extensions/extension_install_prompt_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm index 84ca937..9368106 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_install_prompt_controller.mm +++ b/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm @@ -1,13 +1,14 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/extensions/extension_install_prompt_controller.h" +#import "chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.h" #include "base/mac/mac_util.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" +#include "chrome/browser/extensions/extension_install_dialog.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" @@ -46,7 +47,7 @@ void OffsetControlVertically(NSControl* control, CGFloat amount) { } -@implementation ExtensionInstallPromptController +@implementation ExtensionInstallDialogController @synthesize iconView = iconView_; @synthesize titleField = titleField_; @@ -136,7 +137,7 @@ void OffsetControlVertically(NSControl* control, CGFloat amount) { [iconView_ setImage:image]; // Make sure we're the window's delegate as set in the nib. - DCHECK_EQ(self, static_cast<ExtensionInstallPromptController*>( + DCHECK_EQ(self, static_cast<ExtensionInstallDialogController*>( [[self window] delegate])); // If there are any warnings, then we have to do some special layout. @@ -189,12 +190,11 @@ void OffsetControlVertically(NSControl* control, CGFloat amount) { [self autorelease]; } -@end // ExtensionInstallPromptController +@end // ExtensionInstallDialogController - -void ExtensionInstallUI::ShowExtensionInstallUIPrompt2Impl( +void ShowExtensionInstallDialog( Profile* profile, - Delegate* delegate, + ExtensionInstallUI::Delegate* delegate, const Extension* extension, SkBitmap* icon, const std::vector<string16>& warnings, @@ -213,8 +213,8 @@ void ExtensionInstallUI::ShowExtensionInstallUIPrompt2Impl( gfx::NativeWindow native_window = window->GetNativeHandle(); - ExtensionInstallPromptController* controller = - [[ExtensionInstallPromptController alloc] + ExtensionInstallDialogController* controller = + [[ExtensionInstallDialogController alloc] initWithParentWindow:native_window profile:profile extension:extension diff --git a/chrome/browser/ui/cocoa/extensions/extension_install_prompt_controller_unittest.mm b/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller_unittest.mm index f11aeb4..b68686f 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_install_prompt_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller_unittest.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -11,12 +11,12 @@ #include "base/utf_string_conversions.h" #include "base/values.h" #import "chrome/browser/extensions/extension_install_ui.h" -#import "chrome/browser/ui/cocoa/extensions/extension_install_prompt_controller.h" #include "chrome/browser/ui/cocoa/browser_test_helper.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" +#import "chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/extensions/extension.h" -#include "chrome/common/json_value_serializer.h" +#include "content/common/json_value_serializer.h" #include "testing/gtest/include/gtest/gtest.h" #import "testing/gtest_mac.h" #include "testing/platform_test.h" @@ -25,9 +25,9 @@ // Base class for our tests. -class ExtensionInstallPromptControllerTest : public CocoaTest { +class ExtensionInstallDialogControllerTest : public CocoaTest { public: - ExtensionInstallPromptControllerTest() { + ExtensionInstallDialogControllerTest() { PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_); test_data_dir_ = test_data_dir_.AppendASCII("extensions") .AppendASCII("install_prompt"); @@ -60,8 +60,8 @@ public: return; } - extension_ = Extension::Create( - path.DirName(), Extension::INVALID, *value, false, true, &error); + extension_ = Extension::Create(path.DirName(), Extension::INVALID, *value, + Extension::STRICT_ERROR_CHECKS, &error); if (!extension_.get()) { LOG(ERROR) << error; return; @@ -102,15 +102,15 @@ class MockExtensionInstallUIDelegate : public ExtensionInstallUI::Delegate { // Test that we can load the two kinds of prompts correctly, that the outlets // are hooked up, and that the dialog calls cancel when cancel is pressed. -TEST_F(ExtensionInstallPromptControllerTest, BasicsNormalCancel) { +TEST_F(ExtensionInstallDialogControllerTest, BasicsNormalCancel) { scoped_ptr<MockExtensionInstallUIDelegate> delegate( new MockExtensionInstallUIDelegate); std::vector<string16> warnings; warnings.push_back(UTF8ToUTF16("warning 1")); - scoped_nsobject<ExtensionInstallPromptController> - controller([[ExtensionInstallPromptController alloc] + scoped_nsobject<ExtensionInstallDialogController> + controller([[ExtensionInstallDialogController alloc] initWithParentWindow:test_window() profile:helper_.profile() extension:extension_.get() @@ -159,15 +159,15 @@ TEST_F(ExtensionInstallPromptControllerTest, BasicsNormalCancel) { } -TEST_F(ExtensionInstallPromptControllerTest, BasicsNormalOK) { +TEST_F(ExtensionInstallDialogControllerTest, BasicsNormalOK) { scoped_ptr<MockExtensionInstallUIDelegate> delegate( new MockExtensionInstallUIDelegate); std::vector<string16> warnings; warnings.push_back(UTF8ToUTF16("warning 1")); - scoped_nsobject<ExtensionInstallPromptController> - controller([[ExtensionInstallPromptController alloc] + scoped_nsobject<ExtensionInstallDialogController> + controller([[ExtensionInstallDialogController alloc] initWithParentWindow:test_window() profile:helper_.profile() extension:extension_.get() @@ -185,7 +185,7 @@ TEST_F(ExtensionInstallPromptControllerTest, BasicsNormalOK) { // Test that controls get repositioned when there are two warnings vs one // warning. -TEST_F(ExtensionInstallPromptControllerTest, MultipleWarnings) { +TEST_F(ExtensionInstallDialogControllerTest, MultipleWarnings) { scoped_ptr<MockExtensionInstallUIDelegate> delegate1( new MockExtensionInstallUIDelegate); scoped_ptr<MockExtensionInstallUIDelegate> delegate2( @@ -198,8 +198,8 @@ TEST_F(ExtensionInstallPromptControllerTest, MultipleWarnings) { two_warnings.push_back(UTF8ToUTF16("warning 1")); two_warnings.push_back(UTF8ToUTF16("warning 2")); - scoped_nsobject<ExtensionInstallPromptController> - controller1([[ExtensionInstallPromptController alloc] + scoped_nsobject<ExtensionInstallDialogController> + controller1([[ExtensionInstallDialogController alloc] initWithParentWindow:test_window() profile:helper_.profile() extension:extension_.get() @@ -210,8 +210,8 @@ TEST_F(ExtensionInstallPromptControllerTest, MultipleWarnings) { [controller1 window]; // force nib load - scoped_nsobject<ExtensionInstallPromptController> - controller2([[ExtensionInstallPromptController alloc] + scoped_nsobject<ExtensionInstallDialogController> + controller2([[ExtensionInstallDialogController alloc] initWithParentWindow:test_window() profile:helper_.profile() extension:extension_.get() @@ -246,15 +246,15 @@ TEST_F(ExtensionInstallPromptControllerTest, MultipleWarnings) { // Test that we can load the skinny prompt correctly, and that the outlets are // are hooked up. -TEST_F(ExtensionInstallPromptControllerTest, BasicsSkinny) { +TEST_F(ExtensionInstallDialogControllerTest, BasicsSkinny) { scoped_ptr<MockExtensionInstallUIDelegate> delegate( new MockExtensionInstallUIDelegate); // No warnings should trigger skinny prompt. std::vector<string16> warnings; - scoped_nsobject<ExtensionInstallPromptController> - controller([[ExtensionInstallPromptController alloc] + scoped_nsobject<ExtensionInstallDialogController> + controller([[ExtensionInstallDialogController alloc] initWithParentWindow:test_window() profile:helper_.profile() extension:extension_.get() diff --git a/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_bridge.mm b/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_bridge.mm index c6a8143..32b8688 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_bridge.mm +++ b/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_bridge.mm @@ -9,7 +9,10 @@ #include "chrome/browser/tab_contents/simple_alert_infobar_delegate.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/browser_window.h" #import "chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_action.h" #include "grit/generated_resources.h" @@ -46,7 +49,7 @@ namespace browser { void ShowExtensionInstalledBubble( const Extension* extension, Browser* browser, - SkBitmap icon, + const SkBitmap& icon, Profile* profile) { if ((extension->browser_action()) || !extension->omnibox_keyword().empty() || (extension->page_action() && diff --git a/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.h b/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.h index ad95fba..c9386cf 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.h +++ b/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,7 +9,7 @@ #import <Cocoa/Cocoa.h> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_ptr.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" #include "third_party/skia/include/core/SkBitmap.h" diff --git a/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.mm index ec558f2..0101680 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.mm +++ b/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,6 +8,8 @@ #include "base/mac/mac_util.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/cocoa/browser_window_cocoa.h" #include "chrome/browser/ui/cocoa/browser_window_controller.h" #include "chrome/browser/ui/cocoa/extensions/browser_actions_controller.h" @@ -15,13 +17,11 @@ #include "chrome/browser/ui/cocoa/info_bubble_view.h" #include "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" #include "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_window.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_action.h" -#include "chrome/common/notification_details.h" -#include "chrome/common/notification_registrar.h" -#include "chrome/common/notification_source.h" +#include "content/common/notification_details.h" +#include "content/common/notification_registrar.h" +#include "content/common/notification_source.h" #include "grit/generated_resources.h" #import "skia/ext/skia_utils_mac.h" #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" diff --git a/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller_unittest.mm index 5115d7d..a6ccdcb 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller_unittest.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -7,10 +7,10 @@ #include "base/basictypes.h" #include "base/file_path.h" #include "base/file_util.h" +#include "base/memory/scoped_ptr.h" #include "base/path_service.h" -#include "base/scoped_ptr.h" #include "base/values.h" -#import "chrome/browser/browser_window.h" +#import "chrome/browser/ui/browser_window.h" #import "chrome/browser/ui/cocoa/browser_test_helper.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.h" @@ -100,8 +100,8 @@ class ExtensionInstalledBubbleControllerTest : public CocoaTest { } std::string error; - return Extension::Create( - path, Extension::INVALID, extension_input_value, false, true, &error); + return Extension::Create(path, Extension::INVALID, extension_input_value, + Extension::STRICT_ERROR_CHECKS, &error); } // Allows us to create the window and browser for testing. diff --git a/chrome/browser/ui/cocoa/extensions/extension_popup_controller.h b/chrome/browser/ui/cocoa/extensions/extension_popup_controller.h index d3fb422..edd144f 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_popup_controller.h +++ b/chrome/browser/ui/cocoa/extensions/extension_popup_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,8 +9,8 @@ #import <Cocoa/Cocoa.h> #import "base/mac/cocoa_protocols.h" -#import "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#import "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/ui/cocoa/info_bubble_view.h" #include "googleurl/src/gurl.h" diff --git a/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm index 0a188ae..2e8c66e 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm +++ b/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -14,9 +14,9 @@ #import "chrome/browser/ui/cocoa/browser_window_cocoa.h" #import "chrome/browser/ui/cocoa/extensions/extension_view_mac.h" #import "chrome/browser/ui/cocoa/info_bubble_window.h" -#include "chrome/common/notification_details.h" -#include "chrome/common/notification_registrar.h" -#include "chrome/common/notification_source.h" +#include "content/common/notification_details.h" +#include "content/common/notification_registrar.h" +#include "content/common/notification_source.h" namespace { // The duration for any animations that might be invoked by this controller. diff --git a/chrome/browser/ui/cocoa/extensions/extension_popup_controller_unittest.mm b/chrome/browser/ui/cocoa/extensions/extension_popup_controller_unittest.mm index a0b5614..58e35a5 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_popup_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/extensions/extension_popup_controller_unittest.mm @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/memory/scoped_nsobject.h" #include "base/message_loop.h" -#include "base/scoped_nsobject.h" #include "chrome/browser/extensions/extension_pref_value_map.h" #include "chrome/browser/extensions/extension_prefs.h" #include "chrome/browser/extensions/extension_process_manager.h" @@ -36,7 +36,8 @@ class ExtensionTestingProfile : public TestingProfile { CommandLine::ForCurrentProcess(), GetExtensionsInstallDir(), extension_prefs_.get(), - false); + false, + true); service_->set_extensions_enabled(true); service_->set_show_extensions_prompts(false); service_->ClearProvidersForTesting(); diff --git a/chrome/browser/ui/cocoa/extensions/extension_install_prompt.mm b/chrome/browser/ui/cocoa/extensions/extension_uninstall_dialog_cocoa.mm index 97530b1..825fc9d 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_install_prompt.mm +++ b/chrome/browser/ui/cocoa/extensions/extension_uninstall_dialog_cocoa.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,7 +8,8 @@ #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/extensions/extension_install_ui.h" +#include "chrome/browser/extensions/extension_uninstall_dialog.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/common/extensions/extension.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" @@ -16,18 +17,16 @@ #include "ui/base/l10n/l10n_util_mac.h" #include "ui/base/resource/resource_bundle.h" -class Profile; - -void ExtensionInstallUI::ShowExtensionInstallUIPromptImpl( +// static +void ExtensionUninstallDialog::Show( Profile* profile, - Delegate* delegate, + ExtensionUninstallDialog::Delegate* delegate, const Extension* extension, - SkBitmap* icon, - ExtensionInstallUI::PromptType type) { + SkBitmap* icon) { NSAlert* alert = [[[NSAlert alloc] init] autorelease]; NSButton* continueButton = [alert addButtonWithTitle:l10n_util::GetNSString( - ExtensionInstallUI::kButtonIds[type])]; + IDS_EXTENSION_PROMPT_UNINSTALL_BUTTON)]; // Clear the key equivalent (currently 'Return') because cancel is the default // button. [continueButton setKeyEquivalent:@""]; @@ -37,14 +36,13 @@ void ExtensionInstallUI::ShowExtensionInstallUIPromptImpl( [cancelButton setKeyEquivalent:@"\r"]; [alert setMessageText:l10n_util::GetNSStringF( - ExtensionInstallUI::kHeadingIds[type], + IDS_EXTENSION_UNINSTALL_PROMPT_HEADING, UTF8ToUTF16(extension->name()))]; [alert setAlertStyle:NSWarningAlertStyle]; [alert setIcon:gfx::SkBitmapToNSImage(*icon)]; - if ([alert runModal] == NSAlertFirstButtonReturn) { - delegate->InstallUIProceed(); - } else { - delegate->InstallUIAbort(); - } + if ([alert runModal] == NSAlertFirstButtonReturn) + delegate->ExtensionDialogAccepted(); + else + delegate->ExtensionDialogCanceled(); } diff --git a/chrome/browser/ui/cocoa/fast_resize_view_unittest.mm b/chrome/browser/ui/cocoa/fast_resize_view_unittest.mm index d64be3f..02ac295 100644 --- a/chrome/browser/ui/cocoa/fast_resize_view_unittest.mm +++ b/chrome/browser/ui/cocoa/fast_resize_view_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/fast_resize_view.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h b/chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h index 5a1be97..fe0a39d 100644 --- a/chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h +++ b/chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h @@ -9,7 +9,6 @@ #include "base/logging.h" #include "chrome/browser/ui/find_bar/find_bar.h" -class BrowserWindowCocoa; class FindBarController; // This class is included by find_bar_host_browsertest.cc, so it has to be diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_bridge.mm b/chrome/browser/ui/cocoa/find_bar/find_bar_bridge.mm index 4ead584..2d44325 100644 --- a/chrome/browser/ui/cocoa/find_bar/find_bar_bridge.mm +++ b/chrome/browser/ui/cocoa/find_bar/find_bar_bridge.mm @@ -2,6 +2,7 @@ // 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 "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h" #include "base/sys_string_conversions.h" @@ -26,7 +27,6 @@ void FindBarBridge::SetFindBarController( } FindBarController* FindBarBridge::GetFindBarController() const { - DCHECK(find_bar_controller_); return find_bar_controller_; } @@ -72,8 +72,7 @@ bool FindBarBridge::IsFindBarVisible() { void FindBarBridge::MoveWindowIfNecessary(const gfx::Rect& selection_rect, bool no_redraw) { - // http://crbug.com/11084 - // http://crbug.com/22036 + // See FindBarCocoaController moveFindBarToAvoidRect. } void FindBarBridge::StopAnimation() { @@ -86,12 +85,14 @@ void FindBarBridge::RestoreSavedFocus() { bool FindBarBridge::GetFindBarWindowInfo(gfx::Point* position, bool* fully_visible) { - // TODO(rohitrao): Return the proper position. http://crbug.com/22036 - if (position) - *position = gfx::Point(0, 0); - NSWindow* window = [[cocoa_controller_ view] window]; bool window_visible = [window isVisible] ? true : false; + if (position) { + if (window_visible) + *position = [cocoa_controller_ findBarWindowPosition]; + else + *position = gfx::Point(0, 0); + } if (fully_visible) { *fully_visible = window_visible && [cocoa_controller_ isFindBarVisible] && diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h b/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h index 548b1ba..e231c7f 100644 --- a/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h +++ b/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h @@ -1,15 +1,14 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> -#import "chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h" - -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/string16.h" +#include "ui/gfx/point.h" -class BrowserWindowCocoa; +@class BrowserWindowController; class FindBarBridge; @class FindBarTextField; class FindNotificationDetails; @@ -31,23 +30,35 @@ class FindNotificationDetails; // Needed to call methods on FindBarController. FindBarBridge* findBarBridge_; // weak + // Needed to request a layout of the FindBar view. + BrowserWindowController* browserWindowController_; // weak + scoped_nsobject<FocusTracker> focusTracker_; - // The currently-running animation. This is defined to be non-nil if an + // The show/hide animation. This is defined to be non-nil if the // animation is running, and is always nil otherwise. The // FindBarCocoaController should not be deallocated while an animation is // running (stopAnimation is currently called before the last tab in a // window is removed). - scoped_nsobject<NSViewAnimation> currentAnimation_; + scoped_nsobject<NSViewAnimation> showHideAnimation_; + + // The horizontal-moving animation, to avoid occluding find results. This + // is nil when the animation is not running, and is also stopped by + // stopAnimation. + scoped_nsobject<NSViewAnimation> moveAnimation_; // If YES, do nothing as a result of find pasteboard update notifications. BOOL suppressPboardUpdateActions_; + + // Vertical point of attachment of the FindBar. + CGFloat maxY_; }; // Initializes a new FindBarCocoaController. - (id)init; - (void)setFindBarBridge:(FindBarBridge*)findBar; +- (void)setBrowserWindowController:(BrowserWindowController*)controller; - (IBAction)close:(id)sender; @@ -75,4 +86,8 @@ class FindNotificationDetails; - (BOOL)isFindBarVisible; - (BOOL)isFindBarAnimating; +// Returns the FindBar's position in the superview's coordinates, but with +// the Y coordinate growing down. +- (gfx::Point)findBarWindowPosition; + @end diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm b/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm index 4488ee4..bd6e618 100644 --- a/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm +++ b/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -6,35 +6,51 @@ #include "base/mac/mac_util.h" #include "base/sys_string_conversions.h" -#include "chrome/browser/ui/cocoa/browser_window_cocoa.h" +#include "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h" #import "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h" #import "chrome/browser/ui/cocoa/find_bar/find_bar_text_field.h" #import "chrome/browser/ui/cocoa/find_bar/find_bar_text_field_cell.h" #import "chrome/browser/ui/cocoa/find_pasteboard.h" #import "chrome/browser/ui/cocoa/focus_tracker.h" +#import "chrome/browser/ui/cocoa/nsview_additions.h" #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" #include "chrome/browser/ui/find_bar/find_bar_controller.h" #include "chrome/browser/ui/find_bar/find_tab_helper.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/browser/tab_contents/tab_contents.h" +#include "content/browser/tab_contents/tab_contents_view.h" #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" -namespace { const float kFindBarOpenDuration = 0.2; const float kFindBarCloseDuration = 0.15; -} +const float kFindBarMoveDuration = 0.15; +const float kRightEdgeOffset = 25; -@interface FindBarCocoaController (PrivateMethods) +@interface FindBarCocoaController (PrivateMethods) <NSAnimationDelegate> // Returns the appropriate frame for a hidden find bar. - (NSRect)hiddenFindBarFrame; +// Animates the given |view| to the given |endFrame| within |duration| seconds. +// Returns a new NSViewAnimation. +- (NSViewAnimation*)createAnimationForView:(NSView*)view + toFrame:(NSRect)endFrame + duration:(float)duration; + // Sets the frame of |findBarView_|. |duration| is ignored if |animate| is NO. - (void)setFindBarFrame:(NSRect)endFrame animate:(BOOL)animate duration:(float)duration; +// Returns the horizontal position the FindBar should use in order to avoid +// overlapping with the current find result, if there's one. +- (float)findBarHorizontalPosition; + +// Adjusts the horizontal position if necessary to avoid overlapping with the +// current find result. +- (void)moveFindBarIfNecessary:(BOOL)animate; + // Optionally stops the current search, puts |text| into the find bar, and // enables the buttons, but doesn't start a new search for |text|. - (void)prepopulateText:(NSString*)text stopSearch:(BOOL)stopSearch; @@ -57,7 +73,8 @@ const float kFindBarCloseDuration = 0.15; - (void)dealloc { // All animations should be explicitly stopped by the TabContents before a tab // is closed. - DCHECK(!currentAnimation_.get()); + DCHECK(!showHideAnimation_.get()); + DCHECK(!moveAnimation_.get()); [[NSNotificationCenter defaultCenter] removeObserver:self]; [super dealloc]; } @@ -67,6 +84,11 @@ const float kFindBarCloseDuration = 0.15; findBarBridge_ = findBarBridge; } +- (void)setBrowserWindowController:(BrowserWindowController*)controller { + DCHECK(!browserWindowController_); // should only be called once. + browserWindowController_ = controller; +} + - (void)awakeFromNib { [findBarView_ setFrame:[self hiddenFindBarFrame]]; @@ -110,19 +132,30 @@ const float kFindBarCloseDuration = 0.15; } - (void)positionFindBarViewAtMaxY:(CGFloat)maxY maxWidth:(CGFloat)maxWidth { - static const CGFloat kRightEdgeOffset = 25; NSView* containerView = [self view]; CGFloat containerHeight = NSHeight([containerView frame]); CGFloat containerWidth = NSWidth([containerView frame]); // Adjust where we'll actually place the find bar. - CGFloat maxX = maxWidth - kRightEdgeOffset; - DLOG_IF(WARNING, maxX < 0) << "Window too narrow for find bar"; - maxY += 1; - - NSRect newFrame = NSMakeRect(maxX - containerWidth, maxY - containerHeight, + maxY += [containerView cr_lineWidth]; + maxY_ = maxY; + CGFloat x = [self findBarHorizontalPosition]; + NSRect newFrame = NSMakeRect(x, maxY - containerHeight, containerWidth, containerHeight); - [containerView setFrame:newFrame]; + + if (moveAnimation_.get() != nil) { + NSRect frame = [containerView frame]; + [moveAnimation_ stopAnimation]; + // Restore to the X position before the animation was stopped. The Y + // position is immediately adjusted. + frame.origin.y = newFrame.origin.y; + [containerView setFrame:frame]; + moveAnimation_.reset([self createAnimationForView:containerView + toFrame:newFrame + duration:kFindBarMoveDuration]); + } else { + [containerView setFrame:newFrame]; + } } // NSControl delegate method. @@ -217,6 +250,16 @@ const float kFindBarCloseDuration = 0.15; focusTracker_.reset( [[FocusTracker alloc] initWithWindow:[findBarView_ window]]); + // The browser window might have changed while the FindBar was hidden. + // Update its position now. + [browserWindowController_ layoutSubviews]; + + // Move to the correct horizontal position first, to prevent the FindBar + // from jumping around when switching tabs. + // Prevent jumping while the FindBar is animating (hiding, then showing) too. + if (![self isFindBarVisible]) + [self moveFindBarIfNecessary:NO]; + // Animate the view into place. NSRect frame = [findBarView_ frame]; frame.origin = NSMakePoint(0, 0); @@ -229,9 +272,13 @@ const float kFindBarCloseDuration = 0.15; } - (void)stopAnimation { - if (currentAnimation_.get()) { - [currentAnimation_ stopAnimation]; - currentAnimation_.reset(nil); + if (showHideAnimation_.get()) { + [showHideAnimation_ stopAnimation]; + showHideAnimation_.reset(nil); + } + if (moveAnimation_.get()) { + [moveAnimation_ stopAnimation]; + moveAnimation_.reset(nil); } } @@ -303,6 +350,10 @@ const float kFindBarCloseDuration = 0.15; // restore focus to the tab contents. if (result.number_of_matches() > 0) focusTracker_.reset(nil); + + // Adjust the FindBar position, even when there are no matches (so that it + // goes back to the default position, if required). + [self moveFindBarIfNecessary:[self isFindBarVisible]]; } - (BOOL)isFindBarVisible { @@ -311,21 +362,35 @@ const float kFindBarCloseDuration = 0.15; } - (BOOL)isFindBarAnimating { - return (currentAnimation_.get() != nil); + return (showHideAnimation_.get() != nil) || (moveAnimation_.get() != nil); } // NSAnimation delegate methods. - (void)animationDidEnd:(NSAnimation*)animation { - // Autorelease the animation (cannot use release because the animation object + // Autorelease the animations (cannot use release because the animation object // is still on the stack. - DCHECK(animation == currentAnimation_.get()); - [currentAnimation_.release() autorelease]; + if (animation == showHideAnimation_.get()) { + [showHideAnimation_.release() autorelease]; + } else if (animation == moveAnimation_.get()) { + [moveAnimation_.release() autorelease]; + } else { + NOTREACHED(); + } // If the find bar is not visible, make it actually hidden, so it'll no longer // respond to key events. [findBarView_ setHidden:![self isFindBarVisible]]; } +- (gfx::Point)findBarWindowPosition { + gfx::Rect view_rect(NSRectToCGRect([[self view] frame])); + // Convert Cocoa coordinates (Y growing up) to Y growing down. + // Offset from |maxY_|, which represents the content view's top, instead + // of from the superview, which represents the whole browser window. + view_rect.set_y(maxY_ - view_rect.bottom()); + return view_rect.origin(); +} + @end @implementation FindBarCocoaController (PrivateMethods) @@ -337,6 +402,23 @@ const float kFindBarCloseDuration = 0.15; return frame; } +- (NSViewAnimation*)createAnimationForView:(NSView*)view + toFrame:(NSRect)endFrame + duration:(float)duration { + NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys: + view, NSViewAnimationTargetKey, + [NSValue valueWithRect:endFrame], NSViewAnimationEndFrameKey, nil]; + + NSViewAnimation* animation = + [[NSViewAnimation alloc] + initWithViewAnimations:[NSArray arrayWithObjects:dict, nil]]; + [animation gtm_setDuration:duration + eventMask:NSLeftMouseUpMask]; + [animation setDelegate:self]; + [animation startAnimation]; + return animation; +} + - (void)setFindBarFrame:(NSRect)endFrame animate:(BOOL)animate duration:(float)duration { @@ -344,12 +426,12 @@ const float kFindBarCloseDuration = 0.15; NSRect startFrame = [findBarView_ frame]; // Stop any existing animations. - [currentAnimation_ stopAnimation]; + [showHideAnimation_ stopAnimation]; if (!animate) { [findBarView_ setFrame:endFrame]; [findBarView_ setHidden:![self isFindBarVisible]]; - currentAnimation_.reset(nil); + showHideAnimation_.reset(nil); return; } @@ -359,17 +441,73 @@ const float kFindBarCloseDuration = 0.15; // Reset the frame to what was saved above. [findBarView_ setFrame:startFrame]; - NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys: - findBarView_, NSViewAnimationTargetKey, - [NSValue valueWithRect:endFrame], NSViewAnimationEndFrameKey, nil]; - currentAnimation_.reset( - [[NSViewAnimation alloc] - initWithViewAnimations:[NSArray arrayWithObjects:dict, nil]]); - [currentAnimation_ gtm_setDuration:duration - eventMask:NSLeftMouseUpMask]; - [currentAnimation_ setDelegate:self]; - [currentAnimation_ startAnimation]; + showHideAnimation_.reset([self createAnimationForView:findBarView_ + toFrame:endFrame + duration:duration]); +} + +- (float)findBarHorizontalPosition { + // Get the rect of the FindBar. + NSView* view = [self view]; + NSRect frame = [view frame]; + gfx::Rect view_rect(NSRectToCGRect(frame)); + + if (!findBarBridge_ || !findBarBridge_->GetFindBarController()) + return frame.origin.x; + TabContentsWrapper* contents = + findBarBridge_->GetFindBarController()->tab_contents(); + if (!contents) + return frame.origin.x; + + // Get the size of the container. + gfx::Rect container_rect(contents->view()->GetContainerSize()); + + // Position the FindBar on the top right corner. + view_rect.set_x( + container_rect.width() - view_rect.width() - kRightEdgeOffset); + // Convert from Cocoa coordinates (Y growing up) to Y growing down. + // Notice that the view frame's Y offset is relative to the whole window, + // while GetLocationForFindbarView() expects it relative to the + // content's boundaries. |maxY_| has the correct placement in Cocoa coords, + // so we just have to invert the Y coordinate. + view_rect.set_y(maxY_ - view_rect.bottom()); + + // Get the rect of the current find result, if there is one. + const FindNotificationDetails& find_result = + contents->find_tab_helper()->find_result(); + if (find_result.number_of_matches() == 0) + return view_rect.x(); + gfx::Rect selection_rect(find_result.selection_rect()); + + // Adjust |view_rect| to avoid the |selection_rect| within |container_rect|. + gfx::Rect new_pos = FindBarController::GetLocationForFindbarView( + view_rect, container_rect, selection_rect); + + return new_pos.x(); +} + +- (void)moveFindBarIfNecessary:(BOOL)animate { + // Don't animate during tests. + if (FindBarBridge::disable_animations_during_testing_) + animate = NO; + + NSView* view = [self view]; + NSRect frame = [view frame]; + float x = [self findBarHorizontalPosition]; + + if (animate) { + [moveAnimation_ stopAnimation]; + // Restore to the position before the animation was stopped. + [view setFrame:frame]; + frame.origin.x = x; + moveAnimation_.reset([self createAnimationForView:view + toFrame:frame + duration:kFindBarMoveDuration]); + } else { + frame.origin.x = x; + [view setFrame:frame]; + } } - (void)prepopulateText:(NSString*)text stopSearch:(BOOL)stopSearch{ diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller_unittest.mm b/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller_unittest.mm index b3a6389..f18edf5 100644 --- a/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller_unittest.mm @@ -1,14 +1,14 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. #include "base/string_util.h" #include "base/sys_string_conversions.h" -#include "chrome/browser/browser_window.h" +#include "chrome/browser/ui/browser_window.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h" -#import "chrome/browser/ui/cocoa/find_pasteboard.h" #import "chrome/browser/ui/cocoa/find_bar/find_bar_text_field.h" +#import "chrome/browser/ui/cocoa/find_pasteboard.h" #include "chrome/browser/ui/find_bar/find_notification_details.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" @@ -52,6 +52,11 @@ class FindBarCocoaControllerTest : public CocoaTest { [[test_window() contentView] addSubview:[controller_ view]]; } + virtual void TearDown() { + CocoaTest::TearDown(); + [controller_ stopAnimation]; + } + protected: scoped_nsobject<FindBarCocoaController> controller_; }; diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_text_field_cell.h b/chrome/browser/ui/cocoa/find_bar/find_bar_text_field_cell.h index ee6785f..3ef6c65 100644 --- a/chrome/browser/ui/cocoa/find_bar/find_bar_text_field_cell.h +++ b/chrome/browser/ui/cocoa/find_bar/find_bar_text_field_cell.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -6,7 +6,7 @@ #import "chrome/browser/ui/cocoa/styled_text_field_cell.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" // FindBarTextFieldCell extends StyledTextFieldCell to provide support for a // results label rooted at the right edge of the cell. diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_text_field_cell_unittest.mm b/chrome/browser/ui/cocoa/find_bar/find_bar_text_field_cell_unittest.mm index c65431c..a13e29a 100644 --- a/chrome/browser/ui/cocoa/find_bar/find_bar_text_field_cell_unittest.mm +++ b/chrome/browser/ui/cocoa/find_bar/find_bar_text_field_cell_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/find_bar/find_bar_text_field_cell.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_text_field_unittest.mm b/chrome/browser/ui/cocoa/find_bar/find_bar_text_field_unittest.mm index 836a82b..f9af990 100644 --- a/chrome/browser/ui/cocoa/find_bar/find_bar_text_field_unittest.mm +++ b/chrome/browser/ui/cocoa/find_bar/find_bar_text_field_unittest.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/find_bar/find_bar_text_field.h" #import "chrome/browser/ui/cocoa/find_bar/find_bar_text_field_cell.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_view.h b/chrome/browser/ui/cocoa/find_bar/find_bar_view.h index a3cc96b..919c67c 100644 --- a/chrome/browser/ui/cocoa/find_bar/find_bar_view.h +++ b/chrome/browser/ui/cocoa/find_bar/find_bar_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -14,6 +14,11 @@ @interface FindBarView : BackgroundGradientView { } + +// Specifies that mouse events over this view should be ignored by the +// render host. +- (BOOL)nonWebContentView; + @end #endif // CHROME_BROWSER_UI_COCOA_FIND_BAR_FIND_BAR_VIEW_H_ diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_view.mm b/chrome/browser/ui/cocoa/find_bar/find_bar_view.mm index 7883a1f..520902b 100644 --- a/chrome/browser/ui/cocoa/find_bar/find_bar_view.mm +++ b/chrome/browser/ui/cocoa/find_bar/find_bar_view.mm @@ -1,9 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/find_bar/find_bar_view.h" +#import "chrome/browser/ui/cocoa/nsview_additions.h" #import "chrome/browser/ui/cocoa/themed_window.h" #import "chrome/browser/ui/cocoa/url_drop_target.h" #import "chrome/browser/ui/cocoa/view_id_util.h" @@ -20,9 +21,12 @@ CGFloat kCurveSize = 8; } - (void)drawRect:(NSRect)rect { + const CGFloat lineWidth = [self cr_lineWidth]; + const CGFloat halfLineWidth = lineWidth / 2.0; + // TODO(rohitrao): Make this prettier. - rect = NSInsetRect([self bounds], 0.5, 0.5); - rect = NSOffsetRect(rect, 0, 1.0); + rect = NSInsetRect([self bounds], halfLineWidth, halfLineWidth); + rect = NSOffsetRect(rect, 0, lineWidth); NSPoint topLeft = NSMakePoint(NSMinX(rect), NSMaxY(rect)); NSPoint topRight = NSMakePoint(NSMaxX(rect), NSMaxY(rect)); @@ -69,6 +73,7 @@ CGFloat kCurveSize = 8; [context restoreGraphicsState]; [[self strokeColor] set]; + [path setLineWidth:lineWidth]; [path stroke]; } @@ -128,4 +133,10 @@ CGFloat kCurveSize = 8; return VIEW_ID_FIND_IN_PAGE; } +// Specifies that mouse events over this view should be ignored by the +// render host. +- (BOOL)nonWebContentView { + return YES; +} + @end diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_view_unittest.mm b/chrome/browser/ui/cocoa/find_bar/find_bar_view_unittest.mm index ce80bec..fa597e2 100644 --- a/chrome/browser/ui/cocoa/find_bar/find_bar_view_unittest.mm +++ b/chrome/browser/ui/cocoa/find_bar/find_bar_view_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/find_bar/find_bar_view.h" #include "chrome/browser/ui/cocoa/test_event_utils.h" diff --git a/chrome/browser/ui/cocoa/find_pasteboard.h b/chrome/browser/ui/cocoa/find_pasteboard.h index f7153f6..175c8e5 100644 --- a/chrome/browser/ui/cocoa/find_pasteboard.h +++ b/chrome/browser/ui/cocoa/find_pasteboard.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -12,7 +12,7 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" extern NSString* kFindPasteboardChangedNotification; diff --git a/chrome/browser/ui/cocoa/find_pasteboard_unittest.mm b/chrome/browser/ui/cocoa/find_pasteboard_unittest.mm index 739eff3..e83635a 100644 --- a/chrome/browser/ui/cocoa/find_pasteboard_unittest.mm +++ b/chrome/browser/ui/cocoa/find_pasteboard_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/find_pasteboard.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/first_run_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/first_run_bubble_controller_unittest.mm index d9f37c9..c0a72ad 100644 --- a/chrome/browser/ui/cocoa/first_run_bubble_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/first_run_bubble_controller_unittest.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -7,7 +7,7 @@ #import <Cocoa/Cocoa.h> #include "base/debug/debugger.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/browser/ui/cocoa/browser_test_helper.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/first_run_dialog.h b/chrome/browser/ui/cocoa/first_run_dialog.h index 3e575a3..92d529d 100644 --- a/chrome/browser/ui/cocoa/first_run_dialog.h +++ b/chrome/browser/ui/cocoa/first_run_dialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -17,6 +17,7 @@ BOOL makeDefaultBrowser_; IBOutlet NSArray* objectsToSize_; + IBOutlet NSButton* setAsDefaultCheckbox_; IBOutlet NSButton* statsCheckbox_; BOOL beenSized_; } diff --git a/chrome/browser/ui/cocoa/first_run_dialog.mm b/chrome/browser/ui/cocoa/first_run_dialog.mm index 2771dea..2bab790 100644 --- a/chrome/browser/ui/cocoa/first_run_dialog.mm +++ b/chrome/browser/ui/cocoa/first_run_dialog.mm @@ -1,20 +1,36 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/first_run_dialog.h" #include "base/mac/mac_util.h" +#include "base/memory/ref_counted.h" +#import "base/memory/scoped_nsobject.h" #include "base/message_loop.h" -#include "base/ref_counted.h" #include "base/sys_string_conversions.h" +#include "chrome/browser/first_run/first_run.h" +#include "chrome/browser/first_run/first_run_dialog.h" #include "chrome/browser/google/google_util.h" +#include "chrome/browser/platform_util.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/search_engines/template_url_model.h" +#import "chrome/browser/ui/cocoa/search_engine_dialog_controller.h" #include "chrome/common/url_constants.h" #include "googleurl/src/gurl.h" #include "grit/locale_settings.h" #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" #include "ui/base/l10n/l10n_util_mac.h" +#if defined(GOOGLE_CHROME_BUILD) +#import "chrome/app/breakpad_mac.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/shell_integration.h" +#include "chrome/common/pref_names.h" +#include "chrome/installer/util/google_update_settings.h" +#endif + @interface FirstRunDialogController (PrivateMethods) // Show the dialog. - (void)show; @@ -53,7 +69,88 @@ void FirstRunShowBridge::ShowDialog() { MessageLoop::current()->QuitNow(); } -}; +// Show the search engine selection dialog. +void ShowSearchEngineSelectionDialog(Profile* profile, + bool randomize_search_engine_experiment) { + scoped_nsobject<SearchEngineDialogController> dialog( + [[SearchEngineDialogController alloc] init]); + [dialog.get() setProfile:profile]; + [dialog.get() setRandomize:randomize_search_engine_experiment]; + + [dialog.get() showWindow:nil]; +} + +// Show the first run UI. +void ShowFirstRun(Profile* profile) { +#if defined(GOOGLE_CHROME_BUILD) + // The purpose of the dialog is to ask the user to enable stats and crash + // reporting. This setting may be controlled through configuration management + // in enterprise scenarios. If that is the case, skip the dialog entirely, as + // it's not worth bothering the user for only the default browser question + // (which is likely to be forced in enterprise deployments anyway). + const PrefService::Preference* metrics_reporting_pref = + g_browser_process->local_state()->FindPreference( + prefs::kMetricsReportingEnabled); + if (!metrics_reporting_pref || !metrics_reporting_pref->IsManaged()) { + scoped_nsobject<FirstRunDialogController> dialog( + [[FirstRunDialogController alloc] init]); + + [dialog.get() showWindow:nil]; + + // If the dialog asked the user to opt-in for stats and crash reporting, + // record the decision and enable the crash reporter if appropriate. + bool stats_enabled = [dialog.get() statsEnabled]; + GoogleUpdateSettings::SetCollectStatsConsent(stats_enabled); + + // Breakpad is normally enabled very early in the startup process. However, + // on the first run it may not have been enabled due to the missing opt-in + // from the user. If the user agreed now, enable breakpad if necessary. + if (!IsCrashReporterEnabled() && stats_enabled) { + InitCrashReporter(); + InitCrashProcessInfo(); + } + + // If selected set as default browser. + BOOL make_default_browser = [dialog.get() makeDefaultBrowser]; + if (make_default_browser) { + bool success = ShellIntegration::SetAsDefaultBrowser(); + DCHECK(success); + } + } +#else // GOOGLE_CHROME_BUILD + // We don't show the dialog in Chromium. +#endif // GOOGLE_CHROME_BUILD + + FirstRun::CreateSentinel(); + + // Set preference to show first run bubble and welcome page. + // Don't display the minimal bubble if there is no default search provider. + TemplateURLModel* search_engines_model = profile->GetTemplateURLModel(); + if (search_engines_model && + search_engines_model->GetDefaultSearchProvider()) { + FirstRun::SetShowFirstRunBubblePref(true); + } + FirstRun::SetShowWelcomePagePref(); +} + +} // namespace + +namespace first_run { + +void ShowFirstRunDialog(Profile* profile, + bool randomize_search_engine_experiment) { + // If the default search is not managed via policy, ask the user to + // choose a default. + TemplateURLModel* model = profile->GetTemplateURLModel(); + if (!FirstRun::SearchEngineSelectorDisallowed() || + (model && !model->is_default_search_managed())) { + ShowSearchEngineSelectionDialog(profile, + randomize_search_engine_experiment); + } + ShowFirstRun(profile); +} + +} // namespace first_run @implementation FirstRunDialogController @@ -92,6 +189,11 @@ void FirstRunShowBridge::ShowDialog() { - (void)show { NSWindow* win = [self window]; + if (!platform_util::CanSetAsDefaultBrowser()) { + [setAsDefaultCheckbox_ setHidden:YES]; + makeDefaultBrowser_ = NO; + } + // Only support the sizing the window once. DCHECK(!beenSized_) << "ShowWindow was called twice?"; if (!beenSized_) { diff --git a/chrome/browser/ui/cocoa/focus_tracker.h b/chrome/browser/ui/cocoa/focus_tracker.h index f828979..e7f9e65 100644 --- a/chrome/browser/ui/cocoa/focus_tracker.h +++ b/chrome/browser/ui/cocoa/focus_tracker.h @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" // A class that handles saving and restoring focus. An instance of // this class snapshots the currently focused view when it is diff --git a/chrome/browser/ui/cocoa/focus_tracker_unittest.mm b/chrome/browser/ui/cocoa/focus_tracker_unittest.mm index 9868cbd..b4aed78 100644 --- a/chrome/browser/ui/cocoa/focus_tracker_unittest.mm +++ b/chrome/browser/ui/cocoa/focus_tracker_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/focus_tracker.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/framed_browser_window.h b/chrome/browser/ui/cocoa/framed_browser_window.h index 719799d..fb3827e 100644 --- a/chrome/browser/ui/cocoa/framed_browser_window.h +++ b/chrome/browser/ui/cocoa/framed_browser_window.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,7 +8,7 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/browser/ui/cocoa/chrome_browser_window.h" // Offsets from the top/left of the window frame to the top of the window @@ -31,23 +31,15 @@ const NSInteger kFramedWindowButtonsInterButtonSpacing = 7; @interface FramedBrowserWindow : ChromeBrowserWindow { @private BOOL shouldHideTitle_; + BOOL hasTabStrip_; NSButton* closeButton_; NSButton* miniaturizeButton_; NSButton* zoomButton_; - BOOL entered_; - scoped_nsobject<NSTrackingArea> widgetTrackingArea_; } // Tells the window to suppress title drawing. - (void)setShouldHideTitle:(BOOL)flag; -// Return true if the mouse is currently in our tracking area for our window -// widgets. -- (BOOL)mouseInGroup:(NSButton*)widget; - -// Update the tracking areas for our window widgets as appropriate. -- (void)updateTrackingAreas; - @end @interface NSWindow (UndocumentedAPI) diff --git a/chrome/browser/ui/cocoa/framed_browser_window.mm b/chrome/browser/ui/cocoa/framed_browser_window.mm index 30064cb..539c9ff 100644 --- a/chrome/browser/ui/cocoa/framed_browser_window.mm +++ b/chrome/browser/ui/cocoa/framed_browser_window.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -11,25 +11,32 @@ #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" #import "chrome/browser/ui/cocoa/themed_window.h" #import "chrome/browser/renderer_host/render_widget_host_view_mac.h" -#include "chrome/browser/themes/browser_theme_provider.h" +#include "chrome/browser/themes/theme_service.h" + +// Implementer's note: Moving the window controls is tricky. When altering the +// code, ensure that: +// - accessibility hit testing works +// - the accessibility hierarchy is correct +// - close/min in the background don't bring the window forward +// - rollover effects work correctly namespace { - // Size of the gradient. Empirically determined so that the gradient looks - // like what the heuristic does when there are just a few tabs. - const CGFloat kWindowGradientHeight = 24.0; + +// Size of the gradient. Empirically determined so that the gradient looks +// like what the heuristic does when there are just a few tabs. +const CGFloat kWindowGradientHeight = 24.0; + } -// Our browser window does some interesting things to get the behaviors that -// we want. We replace the standard window controls (zoom, close, miniaturize) -// with our own versions, so that we can position them slightly differently than -// the default window has them. To do this, we hide the ones that Apple provides -// us with, and create our own. This requires us to handle tracking for the -// buttons (so that they highlight and activate correctly) as well as implement -// the private method _mouseInGroup in our frame view class which is required -// to get the rollover highlight drawing to draw correctly. -@interface FramedBrowserWindow(PrivateMethods) -// Return the view that does the "frame" drawing. +@interface FramedBrowserWindow (Private) + +- (void)adjustCloseButton:(NSNotification*)notification; +- (void)adjustMiniaturizeButton:(NSNotification*)notification; +- (void)adjustZoomButton:(NSNotification*)notification; +- (void)adjustButton:(NSButton*)button + ofKind:(NSWindowButton)kind; - (NSView*)frameView; + @end @implementation FramedBrowserWindow @@ -51,17 +58,38 @@ namespace { [self setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge]; [self setContentBorderThickness:kWindowGradientHeight forEdge:NSMaxYEdge]; } + + closeButton_ = [self standardWindowButton:NSWindowCloseButton]; + [closeButton_ setPostsFrameChangedNotifications:YES]; + miniaturizeButton_ = [self standardWindowButton:NSWindowMiniaturizeButton]; + [miniaturizeButton_ setPostsFrameChangedNotifications:YES]; + zoomButton_ = [self standardWindowButton:NSWindowZoomButton]; + [zoomButton_ setPostsFrameChangedNotifications:YES]; + + NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; + [center addObserver:self + selector:@selector(adjustCloseButton:) + name:NSViewFrameDidChangeNotification + object:closeButton_]; + [center addObserver:self + selector:@selector(adjustMiniaturizeButton:) + name:NSViewFrameDidChangeNotification + object:miniaturizeButton_]; + [center addObserver:self + selector:@selector(adjustZoomButton:) + name:NSViewFrameDidChangeNotification + object:zoomButton_]; + [center addObserver:self + selector:@selector(themeDidChangeNotification:) + name:kBrowserThemeDidChangeNotification + object:nil]; } + return self; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [[NSDistributedNotificationCenter defaultCenter] removeObserver:self]; - if (widgetTrackingArea_) { - [[self frameView] removeTrackingArea:widgetTrackingArea_]; - widgetTrackingArea_.reset(); - } [super dealloc]; } @@ -69,104 +97,75 @@ namespace { if (controller == [self windowController]) { return; } - // Clean up our old stuff. - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [[NSDistributedNotificationCenter defaultCenter] removeObserver:self]; - [closeButton_ removeFromSuperview]; - closeButton_ = nil; - [miniaturizeButton_ removeFromSuperview]; - miniaturizeButton_ = nil; - [zoomButton_ removeFromSuperview]; - zoomButton_ = nil; [super setWindowController:controller]; BrowserWindowController* browserController = static_cast<BrowserWindowController*>(controller); if ([browserController isKindOfClass:[BrowserWindowController class]]) { - NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter]; - [defaultCenter addObserver:self - selector:@selector(themeDidChangeNotification:) - name:kBrowserThemeDidChangeNotification - object:nil]; - - // Hook ourselves up to get notified if the user changes the system - // theme on us. - NSDistributedNotificationCenter* distCenter = - [NSDistributedNotificationCenter defaultCenter]; - [distCenter addObserver:self - selector:@selector(systemThemeDidChangeNotification:) - name:@"AppleAquaColorVariantChanged" - object:nil]; - // Set up our buttons how we like them. - NSView* frameView = [self frameView]; - NSRect frameViewBounds = [frameView bounds]; - - // Find all the "original" buttons, and hide them. We can't use the original - // buttons because the OS likes to move them around when we resize windows - // and will put them back in what it considers to be their "preferred" - // locations. - NSButton* oldButton = [self standardWindowButton:NSWindowCloseButton]; - [oldButton setHidden:YES]; - oldButton = [self standardWindowButton:NSWindowMiniaturizeButton]; - [oldButton setHidden:YES]; - oldButton = [self standardWindowButton:NSWindowZoomButton]; - [oldButton setHidden:YES]; - - // Create and position our new buttons. - NSUInteger aStyle = [self styleMask]; - closeButton_ = [NSWindow standardWindowButton:NSWindowCloseButton - forStyleMask:aStyle]; - NSRect closeButtonFrame = [closeButton_ frame]; - BOOL hasTabStrip = [browserController hasTabStrip]; - CGFloat xOffset = hasTabStrip ? - kFramedWindowButtonsWithTabStripOffsetFromLeft : - kFramedWindowButtonsWithoutTabStripOffsetFromLeft; - CGFloat yOffset = hasTabStrip ? - kFramedWindowButtonsWithTabStripOffsetFromTop : - kFramedWindowButtonsWithoutTabStripOffsetFromTop; - closeButtonFrame.origin = - NSMakePoint(xOffset, (NSHeight(frameViewBounds) - - NSHeight(closeButtonFrame) - yOffset)); - - [closeButton_ setFrame:closeButtonFrame]; - [closeButton_ setTarget:self]; - [closeButton_ setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin]; - [frameView addSubview:closeButton_]; - - miniaturizeButton_ = - [NSWindow standardWindowButton:NSWindowMiniaturizeButton - forStyleMask:aStyle]; - NSRect miniaturizeButtonFrame = [miniaturizeButton_ frame]; - miniaturizeButtonFrame.origin = - NSMakePoint((NSMaxX(closeButtonFrame) + - kFramedWindowButtonsInterButtonSpacing), - NSMinY(closeButtonFrame)); - [miniaturizeButton_ setFrame:miniaturizeButtonFrame]; - [miniaturizeButton_ setTarget:self]; - [miniaturizeButton_ setAutoresizingMask:(NSViewMaxXMargin | - NSViewMinYMargin)]; - [frameView addSubview:miniaturizeButton_]; - - zoomButton_ = [NSWindow standardWindowButton:NSWindowZoomButton - forStyleMask:aStyle]; - NSRect zoomButtonFrame = [zoomButton_ frame]; - zoomButtonFrame.origin = - NSMakePoint((NSMaxX(miniaturizeButtonFrame) + - kFramedWindowButtonsInterButtonSpacing), - NSMinY(miniaturizeButtonFrame)); - [zoomButton_ setFrame:zoomButtonFrame]; - [zoomButton_ setTarget:self]; - [zoomButton_ setAutoresizingMask:(NSViewMaxXMargin | - NSViewMinYMargin)]; - - [frameView addSubview:zoomButton_]; + hasTabStrip_ = [browserController hasTabStrip]; + } else { + hasTabStrip_ = NO; + } + + // Force re-layout of the window buttons by wiggling the size of the frame + // view. + NSView* frameView = [[self contentView] superview]; + BOOL frameViewDidAutoresizeSubviews = [frameView autoresizesSubviews]; + [frameView setAutoresizesSubviews:NO]; + NSRect oldFrame = [frameView frame]; + [frameView setFrame:NSZeroRect]; + [frameView setFrame:oldFrame]; + [frameView setAutoresizesSubviews:frameViewDidAutoresizeSubviews]; +} + +- (void)adjustCloseButton:(NSNotification*)notification { + [self adjustButton:[notification object] + ofKind:NSWindowCloseButton]; +} + +- (void)adjustMiniaturizeButton:(NSNotification*)notification { + [self adjustButton:[notification object] + ofKind:NSWindowMiniaturizeButton]; +} + +- (void)adjustZoomButton:(NSNotification*)notification { + [self adjustButton:[notification object] + ofKind:NSWindowZoomButton]; +} + +- (void)adjustButton:(NSButton*)button + ofKind:(NSWindowButton)kind { + NSRect buttonFrame = [button frame]; + NSRect frameViewBounds = [[self frameView] bounds]; + + CGFloat xOffset = hasTabStrip_ + ? kFramedWindowButtonsWithTabStripOffsetFromLeft + : kFramedWindowButtonsWithoutTabStripOffsetFromLeft; + CGFloat yOffset = hasTabStrip_ + ? kFramedWindowButtonsWithTabStripOffsetFromTop + : kFramedWindowButtonsWithoutTabStripOffsetFromTop; + buttonFrame.origin = + NSMakePoint(xOffset, (NSHeight(frameViewBounds) - + NSHeight(buttonFrame) - yOffset)); + + switch (kind) { + case NSWindowZoomButton: + buttonFrame.origin.x += NSWidth([miniaturizeButton_ frame]); + buttonFrame.origin.x += kFramedWindowButtonsInterButtonSpacing; + // fallthrough + case NSWindowMiniaturizeButton: + buttonFrame.origin.x += NSWidth([closeButton_ frame]); + buttonFrame.origin.x += kFramedWindowButtonsInterButtonSpacing; + // fallthrough + default: + break; } - // Update our tracking areas. We want to update them even if we haven't - // added buttons above as we need to remove the old tracking area. If the - // buttons aren't to be shown, updateTrackingAreas won't add new ones. - [self updateTrackingAreas]; + BOOL didPost = [button postsBoundsChangedNotifications]; + [button setPostsFrameChangedNotifications:NO]; + [button setFrame:buttonFrame]; + [button setPostsFrameChangedNotifications:didPost]; } - (NSView*)frameView { @@ -191,65 +190,7 @@ namespace { return value; } -// Map our custom buttons into the accessibility hierarchy correctly. -- (id)accessibilityAttributeValue:(NSString*)attribute { - id value = nil; - struct { - NSString* attribute_; - id value_; - } attributeMap[] = { - { NSAccessibilityCloseButtonAttribute, [closeButton_ cell]}, - { NSAccessibilityZoomButtonAttribute, [zoomButton_ cell]}, - { NSAccessibilityMinimizeButtonAttribute, [miniaturizeButton_ cell]}, - }; - - for (size_t i = 0; i < sizeof(attributeMap) / sizeof(attributeMap[0]); ++i) { - if ([attributeMap[i].attribute_ isEqualToString:attribute]) { - value = attributeMap[i].value_; - break; - } - } - if (!value) { - value = [super accessibilityAttributeValue:attribute]; - } - return value; -} - -- (void)updateTrackingAreas { - NSView* frameView = [self frameView]; - if (widgetTrackingArea_) { - [frameView removeTrackingArea:widgetTrackingArea_]; - } - if (closeButton_) { - NSRect trackingRect = [closeButton_ frame]; - trackingRect.size.width = NSMaxX([zoomButton_ frame]) - - NSMinX(trackingRect); - widgetTrackingArea_.reset( - [[NSTrackingArea alloc] initWithRect:trackingRect - options:(NSTrackingMouseEnteredAndExited | - NSTrackingActiveAlways) - owner:self - userInfo:nil]); - [frameView addTrackingArea:widgetTrackingArea_]; - - // Check to see if the cursor is still in trackingRect. - NSPoint point = [self mouseLocationOutsideOfEventStream]; - point = [[self contentView] convertPoint:point fromView:nil]; - BOOL newEntered = NSPointInRect (point, trackingRect); - if (newEntered != entered_) { - // Buttons have moved, so update button state. - entered_ = newEntered; - [closeButton_ setNeedsDisplay]; - [zoomButton_ setNeedsDisplay]; - [miniaturizeButton_ setNeedsDisplay]; - } - } -} - - (void)windowMainStatusChanged { - [closeButton_ setNeedsDisplay]; - [zoomButton_ setNeedsDisplay]; - [miniaturizeButton_ setNeedsDisplay]; NSView* frameView = [self frameView]; NSView* contentView = [self contentView]; NSRect updateRect = [frameView frame]; @@ -275,19 +216,14 @@ namespace { [[self frameView] setNeedsDisplay:YES]; } -- (void)systemThemeDidChangeNotification:(NSNotification*)aNotification { - [closeButton_ setNeedsDisplay]; - [zoomButton_ setNeedsDisplay]; - [miniaturizeButton_ setNeedsDisplay]; -} - - (void)sendEvent:(NSEvent*)event { - // For cocoa windows, clicking on the close and the miniaturize (but not the - // zoom buttons) while a window is in the background does NOT bring that - // window to the front. We don't get that behavior for free, so we handle - // it here. Zoom buttons do bring the window to the front. Note that - // Finder windows (in Leopard) behave differently in this regard in that - // zoom buttons don't bring the window to the foreground. + // For Cocoa windows, clicking on the close and the miniaturize buttons (but + // not the zoom button) while a window is in the background does NOT bring + // that window to the front. We don't get that behavior for free (probably + // because the tab strip view covers those buttons), so we handle it here. + // Zoom buttons do bring the window to the front. Note that Finder windows (in + // Leopard) behave differently in this regard in that zoom buttons don't bring + // the window to the foreground. BOOL eventHandled = NO; if (![self isMainWindow]) { if ([event type] == NSLeftMouseDown) { @@ -308,31 +244,11 @@ namespace { } } -// Update our buttons so that they highlight correctly. -- (void)mouseEntered:(NSEvent*)event { - entered_ = YES; - [closeButton_ setNeedsDisplay]; - [zoomButton_ setNeedsDisplay]; - [miniaturizeButton_ setNeedsDisplay]; -} - -// Update our buttons so that they highlight correctly. -- (void)mouseExited:(NSEvent*)event { - entered_ = NO; - [closeButton_ setNeedsDisplay]; - [zoomButton_ setNeedsDisplay]; - [miniaturizeButton_ setNeedsDisplay]; -} - -- (BOOL)mouseInGroup:(NSButton*)widget { - return entered_; -} - - (void)setShouldHideTitle:(BOOL)flag { shouldHideTitle_ = flag; } --(BOOL)_isTitleHidden { +- (BOOL)_isTitleHidden { return shouldHideTitle_; } diff --git a/chrome/browser/ui/cocoa/framed_browser_window_unittest.mm b/chrome/browser/ui/cocoa/framed_browser_window_unittest.mm index b9d96c0..8de5ebf 100644 --- a/chrome/browser/ui/cocoa/framed_browser_window_unittest.mm +++ b/chrome/browser/ui/cocoa/framed_browser_window_unittest.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/debug/debugger.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/app/chrome_command_ids.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/browser_frame_view.h" @@ -25,9 +25,9 @@ class FramedBrowserWindowTest : public CocoaTest { NSMiniaturizableWindowMask | NSResizableWindowMask; window_ = [[FramedBrowserWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600) - styleMask:mask - backing:NSBackingStoreBuffered - defer:NO]; + styleMask:mask + backing:NSBackingStoreBuffered + defer:NO]; if (base::debug::BeingDebugged()) { [window_ orderFront:nil]; } else { @@ -101,12 +101,11 @@ TEST_F(FramedBrowserWindowTest, DoesHideTitle) { // Test to make sure that our window widgets are in the right place. TEST_F(FramedBrowserWindowTest, WindowWidgetLocation) { // First without tabstrip. - NSCell* closeBoxCell = [window_ accessibilityAttributeValue: - NSAccessibilityCloseButtonAttribute]; - NSView* closeBoxControl = [closeBoxCell controlView]; + NSView* closeBoxControl = [window_ standardWindowButton:NSWindowCloseButton]; EXPECT_TRUE(closeBoxControl); NSRect closeBoxFrame = [closeBoxControl frame]; NSRect windowBounds = [window_ frame]; + windowBounds = [[window_ contentView] convertRect:windowBounds fromView:nil]; windowBounds.origin = NSZeroPoint; EXPECT_EQ(NSMaxY(closeBoxFrame), NSMaxY(windowBounds) - @@ -114,9 +113,8 @@ TEST_F(FramedBrowserWindowTest, WindowWidgetLocation) { EXPECT_EQ(NSMinX(closeBoxFrame), kFramedWindowButtonsWithoutTabStripOffsetFromLeft); - NSCell* miniaturizeCell = [window_ accessibilityAttributeValue: - NSAccessibilityMinimizeButtonAttribute]; - NSView* miniaturizeControl = [miniaturizeCell controlView]; + NSView* miniaturizeControl = + [window_ standardWindowButton:NSWindowMiniaturizeButton]; EXPECT_TRUE(miniaturizeControl); NSRect miniaturizeFrame = [miniaturizeControl frame]; EXPECT_EQ(NSMaxY(miniaturizeFrame), @@ -136,12 +134,11 @@ TEST_F(FramedBrowserWindowTest, WindowWidgetLocation) { [[[controller expect] andReturnValue:OCMOCK_VALUE(yes)] isNormalWindow]; [window_ setWindowController:controller]; - closeBoxCell = [window_ accessibilityAttributeValue: - NSAccessibilityCloseButtonAttribute]; - closeBoxControl = [closeBoxCell controlView]; + closeBoxControl = [window_ standardWindowButton:NSWindowCloseButton]; EXPECT_TRUE(closeBoxControl); closeBoxFrame = [closeBoxControl frame]; windowBounds = [window_ frame]; + windowBounds = [[window_ contentView] convertRect:windowBounds fromView:nil]; windowBounds.origin = NSZeroPoint; EXPECT_EQ(NSMaxY(closeBoxFrame), NSMaxY(windowBounds) - @@ -149,9 +146,7 @@ TEST_F(FramedBrowserWindowTest, WindowWidgetLocation) { EXPECT_EQ(NSMinX(closeBoxFrame), kFramedWindowButtonsWithTabStripOffsetFromLeft); - miniaturizeCell = [window_ accessibilityAttributeValue: - NSAccessibilityMinimizeButtonAttribute]; - miniaturizeControl = [miniaturizeCell controlView]; + miniaturizeControl = [window_ standardWindowButton:NSWindowMiniaturizeButton]; EXPECT_TRUE(miniaturizeControl); miniaturizeFrame = [miniaturizeControl frame]; EXPECT_EQ(NSMaxY(miniaturizeFrame), @@ -162,25 +157,3 @@ TEST_F(FramedBrowserWindowTest, WindowWidgetLocation) { [window_ setWindowController:nil]; } -// Test that we actually have a tracking area in place. -TEST_F(FramedBrowserWindowTest, WindowWidgetTrackingArea) { - NSCell* closeBoxCell = - [window_ accessibilityAttributeValue:NSAccessibilityCloseButtonAttribute]; - NSView* closeBoxControl = [closeBoxCell controlView]; - NSView* frameView = [[window_ contentView] superview]; - NSArray* trackingAreas = [frameView trackingAreas]; - NSPoint point = [closeBoxControl frame].origin; - point.x += 1; - point.y += 1; - BOOL foundArea = NO; - for (NSTrackingArea* area in trackingAreas) { - NSRect rect = [area rect]; - foundArea = NSPointInRect(point, rect); - if (foundArea) { - EXPECT_NSEQ(frameView, [area owner]); - break; - } - } - EXPECT_TRUE(foundArea); -} - diff --git a/chrome/browser/ui/cocoa/fullscreen_window.mm b/chrome/browser/ui/cocoa/fullscreen_window.mm index ee4b881..586dbfa 100644 --- a/chrome/browser/ui/cocoa/fullscreen_window.mm +++ b/chrome/browser/ui/cocoa/fullscreen_window.mm @@ -1,10 +1,9 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/fullscreen_window.h" -#include "chrome/browser/themes/browser_theme_provider.h" #import "chrome/browser/ui/cocoa/themed_window.h" @implementation FullscreenWindow diff --git a/chrome/browser/ui/cocoa/fullscreen_window_unittest.mm b/chrome/browser/ui/cocoa/fullscreen_window_unittest.mm index 7e54581..0ccf365 100644 --- a/chrome/browser/ui/cocoa/fullscreen_window_unittest.mm +++ b/chrome/browser/ui/cocoa/fullscreen_window_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_ptr.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "chrome/browser/ui/cocoa/fullscreen_window.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/gradient_button_cell.h b/chrome/browser/ui/cocoa/gradient_button_cell.h index 48929b5..9da4b4e 100644 --- a/chrome/browser/ui/cocoa/gradient_button_cell.h +++ b/chrome/browser/ui/cocoa/gradient_button_cell.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,7 +8,7 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" namespace ui { class ThemeProvider; @@ -104,6 +104,9 @@ typedef enum { // Needed by an owning control's dealloc routine. - (void)safelyStopPulsing; +// Actually fetches current mouse position and does a hit test. +- (BOOL)isMouseReallyInside; + @property(assign, nonatomic) CGFloat hoverAlpha; // An image that will be drawn after the normal content of the button cell, diff --git a/chrome/browser/ui/cocoa/gradient_button_cell.mm b/chrome/browser/ui/cocoa/gradient_button_cell.mm index 86f4bfe..9893dca 100644 --- a/chrome/browser/ui/cocoa/gradient_button_cell.mm +++ b/chrome/browser/ui/cocoa/gradient_button_cell.mm @@ -1,13 +1,14 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. #include "chrome/browser/ui/cocoa/gradient_button_cell.h" #include "base/logging.h" -#import "base/scoped_nsobject.h" -#import "chrome/browser/themes/browser_theme_provider.h" +#import "base/memory/scoped_nsobject.h" +#import "chrome/browser/themes/theme_service.h" #import "chrome/browser/ui/cocoa/image_utils.h" +#import "chrome/browser/ui/cocoa/nsview_additions.h" #import "chrome/browser/ui/cocoa/themed_window.h" #include "grit/theme_resources.h" #import "third_party/GTM/AppKit/GTMNSColor+Luminance.h" @@ -392,8 +393,8 @@ static const NSTimeInterval kAnimationContinuousCycleDuration = 0.4; } else { clickedGradient = themeProvider ? themeProvider->GetNSGradient( active ? - BrowserThemeProvider::GRADIENT_TOOLBAR_BUTTON_PRESSED : - BrowserThemeProvider::GRADIENT_TOOLBAR_BUTTON_PRESSED_INACTIVE) : + ThemeService::GRADIENT_TOOLBAR_BUTTON_PRESSED : + ThemeService::GRADIENT_TOOLBAR_BUTTON_PRESSED_INACTIVE) : nil; } [clickedGradient drawInBezierPath:innerPath angle:90.0]; @@ -438,8 +439,8 @@ static const NSTimeInterval kAnimationContinuousCycleDuration = 0.4; alpha:0.3 * outerStrokeAlphaMult_]; } else { strokeColor = themeProvider ? themeProvider->GetNSColor( - active ? BrowserThemeProvider::COLOR_TOOLBAR_BUTTON_STROKE : - BrowserThemeProvider::COLOR_TOOLBAR_BUTTON_STROKE_INACTIVE, + active ? ThemeService::COLOR_TOOLBAR_BUTTON_STROKE : + ThemeService::COLOR_TOOLBAR_BUTTON_STROKE_INACTIVE, true) : [NSColor colorWithCalibratedWhite:0.0 alpha:0.3 * outerStrokeAlphaMult_]; } @@ -456,10 +457,13 @@ static const NSTimeInterval kAnimationContinuousCycleDuration = 0.4; innerFrame:(NSRect*)returnInnerFrame innerPath:(NSBezierPath**)returnInnerPath clipPath:(NSBezierPath**)returnClipPath { + const CGFloat lineWidth = [controlView cr_lineWidth]; + const CGFloat halfLineWidth = lineWidth / 2.0; + // Constants from Cole. Will kConstant them once the feedback loop // is complete. - NSRect drawFrame = NSInsetRect(cellFrame, 1.5, 1.5); - NSRect innerFrame = NSInsetRect(cellFrame, 2, 1); + NSRect drawFrame = NSInsetRect(cellFrame, 1.5 * lineWidth, 1.5 * lineWidth); + NSRect innerFrame = NSInsetRect(cellFrame, 2 * lineWidth, lineWidth); const CGFloat radius = 3.5; ButtonType type = [[(NSControl*)controlView cell] tag]; @@ -490,13 +494,16 @@ static const NSTimeInterval kAnimationContinuousCycleDuration = 0.4; *returnInnerPath = [NSBezierPath bezierPathWithRoundedRect:drawFrame xRadius:radius yRadius:radius]; + [*returnInnerPath setLineWidth:lineWidth]; } if (returnClipPath) { DCHECK(*returnClipPath == nil); - NSRect clipPathRect = NSInsetRect(drawFrame, -0.5, -0.5); - *returnClipPath = [NSBezierPath bezierPathWithRoundedRect:clipPathRect - xRadius:radius + 0.5 - yRadius:radius + 0.5]; + NSRect clipPathRect = + NSInsetRect(drawFrame, -halfLineWidth, -halfLineWidth); + *returnClipPath = [NSBezierPath + bezierPathWithRoundedRect:clipPathRect + xRadius:radius + halfLineWidth + yRadius:radius + halfLineWidth]; } } @@ -548,11 +555,12 @@ static const NSTimeInterval kAnimationContinuousCycleDuration = 0.4; // If this is the left side of a segmented button, draw a slight shadow. ButtonType type = [[(NSControl*)controlView cell] tag]; if (type == kLeftButtonWithShadowType) { + const CGFloat lineWidth = [controlView cr_lineWidth]; NSRect borderRect, contentRect; - NSDivideRect(cellFrame, &borderRect, &contentRect, 1.0, NSMaxXEdge); + NSDivideRect(cellFrame, &borderRect, &contentRect, lineWidth, NSMaxXEdge); NSColor* stroke = themeProvider ? themeProvider->GetNSColor( - active ? BrowserThemeProvider::COLOR_TOOLBAR_BUTTON_STROKE : - BrowserThemeProvider::COLOR_TOOLBAR_BUTTON_STROKE_INACTIVE, + active ? ThemeService::COLOR_TOOLBAR_BUTTON_STROKE : + ThemeService::COLOR_TOOLBAR_BUTTON_STROKE_INACTIVE, true) : [NSColor blackColor]; [[stroke colorWithAlphaComponent:0.2] set]; @@ -563,6 +571,8 @@ static const NSTimeInterval kAnimationContinuousCycleDuration = 0.4; } - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { + const CGFloat lineWidth = [controlView cr_lineWidth]; + if (shouldTheme_) { BOOL isTemplate = [[self image] isTemplate]; @@ -571,19 +581,19 @@ static const NSTimeInterval kAnimationContinuousCycleDuration = 0.4; CGContextRef context = (CGContextRef)([[NSGraphicsContext currentContext] graphicsPort]); - BrowserThemeProvider* themeProvider = static_cast<BrowserThemeProvider*>( + ThemeService* themeProvider = static_cast<ThemeService*>( [[controlView window] themeProvider]); NSColor* color = themeProvider ? - themeProvider->GetNSColorTint(BrowserThemeProvider::TINT_BUTTONS, + themeProvider->GetNSColorTint(ThemeService::TINT_BUTTONS, true) : [NSColor blackColor]; if (isTemplate && themeProvider && themeProvider->UsingDefaultTheme()) { scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]); [shadow.get() setShadowColor:themeProvider->GetNSColor( - BrowserThemeProvider::COLOR_TOOLBAR_BEZEL, true)]; - [shadow.get() setShadowOffset:NSMakeSize(0.0, -1.0)]; - [shadow setShadowBlurRadius:1.0]; + ThemeService::COLOR_TOOLBAR_BEZEL, true)]; + [shadow.get() setShadowOffset:NSMakeSize(0.0, -lineWidth)]; + [shadow setShadowBlurRadius:lineWidth]; [shadow set]; } @@ -606,7 +616,7 @@ static const NSTimeInterval kAnimationContinuousCycleDuration = 0.4; } else { // NSCell draws these off-center for some reason, probably because of the // positioning of the control in the xib. - [super drawInteriorWithFrame:NSOffsetRect(cellFrame, 0, 1) + [super drawInteriorWithFrame:NSOffsetRect(cellFrame, 0, lineWidth) inView:controlView]; } @@ -715,7 +725,7 @@ static const NSTimeInterval kAnimationContinuousCycleDuration = 0.4; [self updateTrackingAreas]; } -- (void)updateTrackingAreas { +- (BOOL)isMouseReallyInside { BOOL mouseInView = NO; NSView* controlView = [self controlView]; NSWindow* window = [controlView window]; @@ -725,6 +735,12 @@ static const NSTimeInterval kAnimationContinuousCycleDuration = 0.4; mousePoint = [controlView convertPointFromBase:mousePoint]; mouseInView = [controlView mouse:mousePoint inRect:bounds]; } + return mouseInView; +} + +- (void)updateTrackingAreas { + NSView* controlView = [self controlView]; + BOOL mouseInView = [self isMouseReallyInside]; if (trackingArea_.get()) [controlView removeTrackingArea:trackingArea_]; @@ -735,12 +751,12 @@ static const NSTimeInterval kAnimationContinuousCycleDuration = 0.4; options |= NSTrackingAssumeInside; trackingArea_.reset([[NSTrackingArea alloc] - initWithRect:bounds + initWithRect:[controlView bounds] options:options owner:self userInfo:nil]); if (isMouseInside_ != mouseInView) { - isMouseInside_ = mouseInView; + [self setMouseInside:mouseInView animate:NO]; [controlView setNeedsDisplay:YES]; } } diff --git a/chrome/browser/ui/cocoa/gradient_button_cell_unittest.mm b/chrome/browser/ui/cocoa/gradient_button_cell_unittest.mm index a9d09da..9860341 100644 --- a/chrome/browser/ui/cocoa/gradient_button_cell_unittest.mm +++ b/chrome/browser/ui/cocoa/gradient_button_cell_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/gradient_button_cell.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/history_menu_bridge.h b/chrome/browser/ui/cocoa/history_menu_bridge.h index 2e90b1d..09cd694 100644 --- a/chrome/browser/ui/cocoa/history_menu_bridge.h +++ b/chrome/browser/ui/cocoa/history_menu_bridge.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,15 +9,15 @@ #import <Cocoa/Cocoa.h> #include <map> -#include "base/ref_counted.h" -#include "base/scoped_nsobject.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/favicon_service.h" #include "chrome/browser/history/history.h" #include "chrome/browser/sessions/session_id.h" #include "chrome/browser/sessions/tab_restore_service.h" #include "chrome/browser/sessions/tab_restore_service_observer.h" -#include "chrome/common/notification_observer.h" #include "content/browser/cancelable_request.h" +#include "content/common/notification_observer.h" class NavigationEntry; class NotificationRegistrar; @@ -187,10 +187,7 @@ class HistoryMenuBridge : public NotificationObserver, // sets the image on the menu. Called on the same same thread that // GetFaviconForHistoryItem() was called on (UI thread). void GotFaviconData(FaviconService::Handle handle, - bool know_favicon, - scoped_refptr<RefCountedMemory> data, - bool expired, - GURL url); + history::FaviconData favicon); // Cancels a favicon load request for a given HistoryItem, if one is in // progress. diff --git a/chrome/browser/ui/cocoa/history_menu_bridge.mm b/chrome/browser/ui/cocoa/history_menu_bridge.mm index 14fa62c..ef5be5f 100644 --- a/chrome/browser/ui/cocoa/history_menu_bridge.mm +++ b/chrome/browser/ui/cocoa/history_menu_bridge.mm @@ -1,9 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. #include "chrome/browser/ui/cocoa/history_menu_bridge.h" +#include "app/mac/nsimage_cache.h" #include "base/callback.h" #include "base/stl_util-inl.h" #include "base/string_number_conversions.h" @@ -15,9 +16,9 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sessions/session_types.h" #import "chrome/browser/ui/cocoa/history_menu_cocoa_controller.h" -#include "chrome/common/notification_registrar.h" -#include "chrome/common/notification_service.h" #include "chrome/common/url_constants.h" +#include "content/common/notification_registrar.h" +#include "content/common/notification_service.h" #include "grit/app_resources.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" @@ -91,7 +92,7 @@ HistoryMenuBridge::HistoryMenuBridge(Profile* profile) } ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - default_favicon_.reset([rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON) retain]); + default_favicon_.reset([app::mac::GetCachedImageWithName(@"nav.pdf") retain]); // Set the static icons in the menu. NSMenuItem* item = [HistoryMenu() itemWithTag:IDC_SHOW_HISTORY]; @@ -380,8 +381,8 @@ void HistoryMenuBridge::OnVisitedHistoryResults( HistoryItem* item = new HistoryItem(); item->title = history_item->GetTitle(); item->url = history_item->GetURL(); - if (history_item->HasFavIcon()) { - const SkBitmap* icon = history_item->GetFavIcon(); + if (history_item->HasFavicon()) { + const SkBitmap* icon = history_item->GetFavicon(); item->icon.reset([gfx::SkBitmapToNSImage(*icon) retain]); } else { GetFaviconForHistoryItem(item); @@ -422,7 +423,7 @@ void HistoryMenuBridge::GetFaviconForHistoryItem(HistoryItem* item) { FaviconService* service = profile_->GetFaviconService(Profile::EXPLICIT_ACCESS); FaviconService::Handle handle = service->GetFaviconForURL(item->url, - &favicon_consumer_, + history::FAVICON, &favicon_consumer_, NewCallback(this, &HistoryMenuBridge::GotFaviconData)); favicon_consumer_.SetClientData(service, handle, item); item->icon_handle = handle; @@ -430,10 +431,7 @@ void HistoryMenuBridge::GetFaviconForHistoryItem(HistoryItem* item) { } void HistoryMenuBridge::GotFaviconData(FaviconService::Handle handle, - bool know_favicon, - scoped_refptr<RefCountedMemory> data, - bool expired, - GURL url) { + history::FaviconData favicon) { // Since we're going to do Cocoa-y things, make sure this is the main thread. DCHECK([NSThread isMainThread]); @@ -447,8 +445,9 @@ void HistoryMenuBridge::GotFaviconData(FaviconService::Handle handle, // Convert the raw data to Skia and then to a NSImage. // TODO(rsesek): Is there an easier way to do this? SkBitmap icon; - if (know_favicon && data.get() && data->size() && - gfx::PNGCodec::Decode(data->front(), data->size(), &icon)) { + if (favicon.is_valid() && + gfx::PNGCodec::Decode(favicon.image_data->front(), + favicon.image_data->size(), &icon)) { NSImage* image = gfx::SkBitmapToNSImage(icon); if (image) { // The conversion was successful. diff --git a/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm b/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm index 7491ed2..8c669b8 100644 --- a/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm +++ b/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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 <vector> -#include "base/ref_counted_memory.h" +#include "base/memory/ref_counted_memory.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" @@ -103,11 +103,8 @@ class HistoryMenuBridgeTest : public CocoaTest { } void GotFaviconData(FaviconService::Handle handle, - bool know_favicon, - scoped_refptr<RefCountedBytes> data, - bool expired, - GURL url) { - bridge_->GotFaviconData(handle, know_favicon, data, expired, url); + history::FaviconData favicon) { + bridge_->GotFaviconData(handle, favicon); } CancelableRequestConsumerTSimple<HistoryMenuBridge::HistoryItem*>& @@ -366,7 +363,7 @@ TEST_F(HistoryMenuBridgeTest, GotFaviconData) { // make icons look pretty. std::vector<unsigned char> raw; gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &raw); - scoped_refptr<RefCountedBytes> bytes(new RefCountedBytes(raw)); + scoped_refptr<RefCountedBytes> bytes(); // Set up the HistoryItem. HistoryMenuBridge::HistoryItem item; @@ -374,7 +371,13 @@ TEST_F(HistoryMenuBridgeTest, GotFaviconData) { GetFaviconForHistoryItem(&item); // Pretend to be called back. - GotFaviconData(item.icon_handle, true, bytes, false, GURL()); + history::FaviconData favicon; + favicon.known_icon = true; + favicon.image_data = new RefCountedBytes(raw); + favicon.expired = false; + favicon.icon_url = GURL(); + favicon.icon_type = history::FAVICON; + GotFaviconData(item.icon_handle, favicon); // Make sure the callback works. EXPECT_FALSE(item.icon_requested); diff --git a/chrome/browser/ui/cocoa/history_menu_cocoa_controller.mm b/chrome/browser/ui/cocoa/history_menu_cocoa_controller.mm index f3662a4..b9f6602 100644 --- a/chrome/browser/ui/cocoa/history_menu_cocoa_controller.mm +++ b/chrome/browser/ui/cocoa/history_menu_cocoa_controller.mm @@ -1,16 +1,17 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/history_menu_cocoa_controller.h" -#include "base/scoped_vector.h" +#include "base/memory/scoped_vector.h" #include "chrome/app/chrome_command_ids.h" // IDC_HISTORY_MENU #import "chrome/browser/app_controller_mac.h" #include "chrome/browser/history/history.h" #include "chrome/browser/history/history_types.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_tab_restore_service_delegate.h" #include "chrome/browser/ui/cocoa/event_utils.h" #include "webkit/glue/window_open_disposition.h" @@ -39,7 +40,8 @@ // just load the URL. TabRestoreService* service = bridge_->profile()->GetTabRestoreService(); if (node->session_id && service) { - service->RestoreEntryById(browser, node->session_id, false); + service->RestoreEntryById(browser->tab_restore_service_delegate(), + node->session_id, false); } else { DCHECK(node->url.is_valid()); browser->OpenURL(node->url, GURL(), disposition, diff --git a/chrome/browser/ui/cocoa/history_menu_cocoa_controller_unittest.mm b/chrome/browser/ui/cocoa/history_menu_cocoa_controller_unittest.mm index 7edc34b..6442576 100644 --- a/chrome/browser/ui/cocoa/history_menu_cocoa_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/history_menu_cocoa_controller_unittest.mm @@ -1,9 +1,9 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" #include "chrome/app/chrome_command_ids.h" diff --git a/chrome/browser/ui/cocoa/hover_button.h b/chrome/browser/ui/cocoa/hover_button.h index e411434..022c120 100644 --- a/chrome/browser/ui/cocoa/hover_button.h +++ b/chrome/browser/ui/cocoa/hover_button.h @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" // A button that changes when you hover over it and click it. @interface HoverButton : NSButton { diff --git a/chrome/browser/ui/cocoa/hover_close_button.h b/chrome/browser/ui/cocoa/hover_close_button.h index 372582c..eb25b4f 100644 --- a/chrome/browser/ui/cocoa/hover_close_button.h +++ b/chrome/browser/ui/cocoa/hover_close_button.h @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/browser/ui/cocoa/hover_button.h" // The standard close button for our Mac UI which is the "x" that changes to a @@ -17,6 +17,13 @@ // Bezier path for drawing the hover state circle behind the 'x'. scoped_nsobject<NSBezierPath> circlePath_; + + // Translation of the 'x' button to the middle vertically. + scoped_nsobject<NSAffineTransform> transform_; + + // The size of the control when the last drawRect: was called, to recenter + // the paths above if it changed. + NSSize oldSize_; } // Sets up the button's tracking areas and accessibility info when instantiated diff --git a/chrome/browser/ui/cocoa/hover_close_button.mm b/chrome/browser/ui/cocoa/hover_close_button.mm index c9d5a2d..32a5c80 100644 --- a/chrome/browser/ui/cocoa/hover_close_button.mm +++ b/chrome/browser/ui/cocoa/hover_close_button.mm @@ -1,21 +1,16 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/hover_close_button.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "grit/generated_resources.h" #import "third_party/molokocacao/NSBezierPath+MCAdditions.h" #include "ui/base/l10n/l10n_util.h" namespace { -// Convenience function to return the middle point of the given |rect|. -static NSPoint MidRect(NSRect rect) { - return NSMakePoint(NSMidX(rect), NSMidY(rect)); -} - -const CGFloat kCircleRadiusPercentage = 0.415; +const CGFloat kCircleRadius = 0.415 * 16; const CGFloat kCircleHoverWhite = 0.565; const CGFloat kCircleClickWhite = 0.396; const CGFloat kXShadowAlpha = 0.75; @@ -23,6 +18,7 @@ const CGFloat kXShadowCircleAlpha = 0.1; } // namespace @interface HoverCloseButton(Private) +- (void)updatePaths; - (void)setUpDrawingPaths; @end @@ -44,6 +40,10 @@ const CGFloat kXShadowCircleAlpha = 0.1; if (!circlePath_.get() || !xPath_.get()) [self setUpDrawingPaths]; + // Only call updatePaths if the size changed. + if (!NSEqualSizes(oldSize_, [self bounds].size)) + [self updatePaths]; + // If the user is hovering over the button, a light/dark gray circle is drawn // behind the 'x'. if (hoverState_ != kHoverStateNone) { @@ -82,12 +82,14 @@ const CGFloat kXShadowCircleAlpha = 0.1; } - (void)setUpDrawingPaths { - NSPoint viewCenter = MidRect([self bounds]); + // Keep the paths centered around the origin in this function. It is then + // translated in -updatePaths. + NSPoint xCenter = NSZeroPoint; circlePath_.reset([[NSBezierPath bezierPath] retain]); - [circlePath_ moveToPoint:viewCenter]; - CGFloat radius = kCircleRadiusPercentage * NSWidth([self bounds]); - [circlePath_ appendBezierPathWithArcWithCenter:viewCenter + [circlePath_ moveToPoint:xCenter]; + CGFloat radius = kCircleRadius; + [circlePath_ appendBezierPathWithArcWithCenter:xCenter radius:radius startAngle:0.0 endAngle:365.0]; @@ -98,14 +100,36 @@ const CGFloat kXShadowCircleAlpha = 0.1; [xPath_ appendBezierPathWithRect:NSMakeRect(3.5, 7.0, 9.0, 2.0)]; [xPath_ appendBezierPathWithRect:NSMakeRect(7.0, 3.5, 2.0, 9.0)]; - NSPoint pathCenter = MidRect([xPath_ bounds]); + NSRect pathBounds = [xPath_ bounds]; + NSPoint pathCenter = NSMakePoint(NSMidX(pathBounds), NSMidY(pathBounds)); NSAffineTransform* transform = [NSAffineTransform transform]; - [transform translateXBy:viewCenter.x yBy:viewCenter.y]; + [transform translateXBy:xCenter.x yBy:xCenter.y]; [transform rotateByDegrees:45.0]; [transform translateXBy:-pathCenter.x yBy:-pathCenter.y]; [xPath_ transformUsingAffineTransform:transform]; } +- (void)updatePaths { + oldSize_ = [self bounds].size; + + // Revert the current transform for the two points. + if (transform_.get()) { + [transform_.get() invert]; + [circlePath_.get() transformUsingAffineTransform:transform_.get()]; + [xPath_.get() transformUsingAffineTransform:transform_.get()]; + } + + // Create the new transform. [self bounds] is prefered in case aRect wasn't + // literally taken as bounds (e.g. cropped). + NSPoint xCenter = NSMakePoint(8, oldSize_.height / 2.0f); + + // Retain here, as scoped_* don't retain. + transform_.reset([[NSAffineTransform transform] retain]); + [transform_.get() translateXBy:xCenter.x yBy:xCenter.y]; + [circlePath_.get() transformUsingAffineTransform:transform_.get()]; + [xPath_.get() transformUsingAffineTransform:transform_.get()]; +} + @end diff --git a/chrome/browser/ui/cocoa/hover_image_button.h b/chrome/browser/ui/cocoa/hover_image_button.h index 76a702d..ec63d44 100644 --- a/chrome/browser/ui/cocoa/hover_image_button.h +++ b/chrome/browser/ui/cocoa/hover_image_button.h @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/browser/ui/cocoa/hover_button.h" // A button that changes images when you hover over it and click it. diff --git a/chrome/browser/ui/cocoa/hover_image_button.mm b/chrome/browser/ui/cocoa/hover_image_button.mm index a6ae41e..95352d3 100644 --- a/chrome/browser/ui/cocoa/hover_image_button.mm +++ b/chrome/browser/ui/cocoa/hover_image_button.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/hover_image_button.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" diff --git a/chrome/browser/ui/cocoa/hover_image_button_unittest.mm b/chrome/browser/ui/cocoa/hover_image_button_unittest.mm index b34bf98..e25dc77 100644 --- a/chrome/browser/ui/cocoa/hover_image_button_unittest.mm +++ b/chrome/browser/ui/cocoa/hover_image_button_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/hover_image_button.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/ui/cocoa/html_dialog_window_controller.h b/chrome/browser/ui/cocoa/html_dialog_window_controller.h index e5660da..b4d0f3e 100644 --- a/chrome/browser/ui/cocoa/html_dialog_window_controller.h +++ b/chrome/browser/ui/cocoa/html_dialog_window_controller.h @@ -9,7 +9,7 @@ #import <Cocoa/Cocoa.h> #include "base/basictypes.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/ui/webui/html_dialog_ui.h" class HtmlDialogWindowDelegateBridge; diff --git a/chrome/browser/ui/cocoa/html_dialog_window_controller.mm b/chrome/browser/ui/cocoa/html_dialog_window_controller.mm index b5b291b..67c9537 100644 --- a/chrome/browser/ui/cocoa/html_dialog_window_controller.mm +++ b/chrome/browser/ui/cocoa/html_dialog_window_controller.mm @@ -5,7 +5,7 @@ #import "chrome/browser/ui/cocoa/html_dialog_window_controller.h" #include "base/logging.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/sys_string_conversions.h" #include "chrome/browser/profiles/profile.h" #import "chrome/browser/ui/browser_dialogs.h" @@ -13,8 +13,8 @@ #import "chrome/browser/ui/cocoa/chrome_event_processing_window.h" #include "chrome/browser/ui/webui/html_dialog_tab_contents_delegate.h" #include "chrome/browser/ui/webui/html_dialog_ui.h" -#include "chrome/common/native_web_keyboard_event.h" #include "content/browser/tab_contents/tab_contents.h" +#include "content/common/native_web_keyboard_event.h" #include "ui/base/keycodes/keyboard_codes.h" #include "ui/gfx/size.h" @@ -48,7 +48,6 @@ public: // HtmlDialogTabContentsDelegate declarations. virtual void MoveContents(TabContents* source, const gfx::Rect& pos); - virtual void ToolbarSizeChanged(TabContents* source, bool is_animating); virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event); private: @@ -171,11 +170,6 @@ void HtmlDialogWindowDelegateBridge::MoveContents(TabContents* source, // TODO(akalin): Actually set the window bounds. } -void HtmlDialogWindowDelegateBridge::ToolbarSizeChanged( - TabContents* source, bool is_animating) { - // TODO(akalin): Figure out what to do here. -} - // A simplified version of BrowserWindowCocoa::HandleKeyboardEvent(). // We don't handle global keyboard shortcuts here, but that's fine since // they're all browser-specific. (This may change in the future.) diff --git a/chrome/browser/ui/cocoa/hung_renderer_controller.h b/chrome/browser/ui/cocoa/hung_renderer_controller.h index 584feb8..957e5fb 100644 --- a/chrome/browser/ui/cocoa/hung_renderer_controller.h +++ b/chrome/browser/ui/cocoa/hung_renderer_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -21,7 +21,7 @@ #import <Cocoa/Cocoa.h> #import "base/mac/cocoa_protocols.h" -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" @class MultiKeyEquivalentButton; class TabContents; diff --git a/chrome/browser/ui/cocoa/hung_renderer_controller.mm b/chrome/browser/ui/cocoa/hung_renderer_controller.mm index 031d1d5..0d4b341 100644 --- a/chrome/browser/ui/cocoa/hung_renderer_controller.mm +++ b/chrome/browser/ui/cocoa/hung_renderer_controller.mm @@ -6,20 +6,23 @@ #import <Cocoa/Cocoa.h> +#include "app/mac/nsimage_cache.h" #include "base/mac/mac_util.h" #include "base/process_util.h" #include "base/sys_string_conversions.h" -#include "chrome/browser/browser_list.h" +#include "chrome/browser/favicon_helper.h" #include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/browser/ui/browser_list.h" #import "chrome/browser/ui/cocoa/multi_key_equivalent_button.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/common/logging_chrome.h" -#include "chrome/common/result_codes.h" #include "content/browser/renderer_host/render_process_host.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/browser/tab_contents/tab_contents.h" -#include "grit/chromium_strings.h" +#import "chrome/browser/ui/cocoa/tab_contents/favicon_util.h" +#include "content/common/result_codes.h" #include "grit/app_resources.h" +#include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "skia/ext/skia_utils_mac.h" @@ -138,21 +141,13 @@ HungRendererController* g_instance = NULL; scoped_nsobject<NSMutableArray> titles([[NSMutableArray alloc] init]); scoped_nsobject<NSMutableArray> favicons([[NSMutableArray alloc] init]); for (TabContentsIterator it; !it.done(); ++it) { - if (it->GetRenderProcessHost() == hungContents_->GetRenderProcessHost()) { - string16 title = (*it)->GetTitle(); + if (it->tab_contents()->GetRenderProcessHost() == + hungContents_->GetRenderProcessHost()) { + string16 title = (*it)->tab_contents()->GetTitle(); if (title.empty()) title = TabContentsWrapper::GetDefaultTitle(); [titles addObject:base::SysUTF16ToNSString(title)]; - - // TabContents can return a null SkBitmap if it has no favicon. If this - // happens, use the default favicon. - const SkBitmap& bitmap = it->GetFavIcon(); - if (!bitmap.isNull()) { - [favicons addObject:gfx::SkBitmapToNSImage(bitmap)]; - } else { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - [favicons addObject:rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON)]; - } + [favicons addObject:mac::FaviconForTabContents(it->tab_contents())]; } } hungTitles_.reset([titles copy]); diff --git a/chrome/browser/ui/cocoa/hung_renderer_controller_unittest.mm b/chrome/browser/ui/cocoa/hung_renderer_controller_unittest.mm index e03becf..7a9e6b3 100644 --- a/chrome/browser/ui/cocoa/hung_renderer_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/hung_renderer_controller_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #include "chrome/browser/ui/cocoa/browser_test_helper.h" #include "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/hung_renderer_controller.h" diff --git a/chrome/browser/ui/cocoa/hyperlink_button_cell.h b/chrome/browser/ui/cocoa/hyperlink_button_cell.h index fd9ec0c..96bc73a 100644 --- a/chrome/browser/ui/cocoa/hyperlink_button_cell.h +++ b/chrome/browser/ui/cocoa/hyperlink_button_cell.h @@ -1,9 +1,9 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" // A HyperlinkButtonCell is used to create an NSButton that looks and acts // like a hyperlink. The default styling is to look like blue, underlined text diff --git a/chrome/browser/ui/cocoa/hyperlink_button_cell_unittest.mm b/chrome/browser/ui/cocoa/hyperlink_button_cell_unittest.mm index 0adae14..4c1624e 100644 --- a/chrome/browser/ui/cocoa/hyperlink_button_cell_unittest.mm +++ b/chrome/browser/ui/cocoa/hyperlink_button_cell_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/hyperlink_button_cell.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/importer/import_dialog_cocoa.h b/chrome/browser/ui/cocoa/importer/import_dialog_cocoa.h deleted file mode 100644 index 74564f0..0000000 --- a/chrome/browser/ui/cocoa/importer/import_dialog_cocoa.h +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2011 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_UI_COCOA_IMPORTER_IMPORT_DIALOG_COCOA_H_ -#define CHROME_BROWSER_UI_COCOA_IMPORTER_IMPORT_DIALOG_COCOA_H_ -#pragma once - -#import <Cocoa/Cocoa.h> - -#include "base/scoped_nsobject.h" -#include "chrome/browser/importer/importer.h" - -class Profile; -class ImporterListObserverBridge; - -// Controller for the Import Bookmarks and Settings dialog. This controller -// automatically autoreleases itself when its associated dialog is dismissed. -@interface ImportDialogController : NSWindowController { - @private - NSWindow* parentWindow_; // weak - Profile* profile_; // weak - scoped_refptr<ImporterList> importerList_; - scoped_ptr<ImporterListObserverBridge> importerListObserver_; - scoped_nsobject<NSArray> sourceBrowsersList_; - NSUInteger sourceBrowserIndex_; - // The following are all bound via the properties below. - BOOL importHistory_; - BOOL importFavorites_; - BOOL importPasswords_; - BOOL importSearchEngines_; - BOOL historyAvailable_; - BOOL favoritesAvailable_; - BOOL passwordsAvailable_; - BOOL searchEnginesAvailable_; - IBOutlet NSPopUpButton* sourceProfilePopUpButton_; -} - -// Show the import settings window. Window is displayed as an app modal dialog. -// If the dialog is already being displayed, this method whill return with -// no error. -+ (void)showImportSettingsDialogForProfile:(Profile*)profile; - -// Called when the "Import" button is pressed. -- (IBAction)ok:(id)sender; - -// Cancel button calls this. -- (IBAction)cancel:(id)sender; - -// An array of ImportSettingsProfiles, provide the list of browser profiles -// available for importing. Bound to the Browser List array controller. -- (NSArray*)sourceBrowsersList; - -// Called when source profiles have been loaded. -- (void)sourceProfilesLoaded; - -// Properties for bindings. -@property(assign, nonatomic) NSUInteger sourceBrowserIndex; -@property(assign, readonly, nonatomic) BOOL importSomething; -// Bindings for the value of the import checkboxes. -@property(assign, nonatomic) BOOL importHistory; -@property(assign, nonatomic) BOOL importFavorites; -@property(assign, nonatomic) BOOL importPasswords; -@property(assign, nonatomic) BOOL importSearchEngines; -// Bindings for enabling/disabling the checkboxes. -@property(assign, readonly, nonatomic) BOOL historyAvailable; -@property(assign, readonly, nonatomic) BOOL favoritesAvailable; -@property(assign, readonly, nonatomic) BOOL passwordsAvailable; -@property(assign, readonly, nonatomic) BOOL searchEnginesAvailable; - -@end - -@interface ImportDialogController (TestingAPI) - -// Initialize by providing an array of source profile dictionaries. Exposed for -// unit testing but also called by -[initWithProfile:]. -- (id)initWithSourceProfiles:(NSArray*)profiles; - -// Return selected services to import as mapped by the ImportItem enum. -- (uint16)servicesToImport; - -@end - -// Utility class used as array elements for sourceBrowsersList, above. -@interface ImportSettingsProfile : NSObject { - @private - NSString* browserName_; - uint16 services_; // Services as defined by enum ImportItem. -} - -// Convenience creator. |services| is a bitfield of enum ImportItems. -+ (id)importSettingsProfileWithBrowserName:(NSString*)browserName - services:(uint16)services; - -// Designated initializer. |services| is a bitfield of enum ImportItems. -- (id)initWithBrowserName:(NSString*)browserName - services:(uint16)services; // Bitfield of enum ImportItems. - -@property(copy, nonatomic) NSString* browserName; -@property(assign, nonatomic) uint16 services; // Bitfield of enum ImportItems. - -@end - -#endif // CHROME_BROWSER_UI_COCOA_IMPORTER_IMPORT_DIALOG_COCOA_H_ diff --git a/chrome/browser/ui/cocoa/importer/import_dialog_cocoa.mm b/chrome/browser/ui/cocoa/importer/import_dialog_cocoa.mm deleted file mode 100644 index 0642b94..0000000 --- a/chrome/browser/ui/cocoa/importer/import_dialog_cocoa.mm +++ /dev/null @@ -1,305 +0,0 @@ -// Copyright (c) 2011 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/ui/cocoa/importer/import_dialog_cocoa.h" - -#include "base/compiler_specific.h" -#include "base/mac/mac_util.h" -#include "base/sys_string_conversions.h" -#include "chrome/browser/importer/importer_data_types.h" -#include "chrome/browser/importer/importer_list.h" -#include "chrome/browser/importer/importer_progress_dialog.h" -#include "chrome/browser/profiles/profile.h" -#include "grit/generated_resources.h" -#include "ui/base/l10n/l10n_util_mac.h" - -// Bridge to receive observer messages from an ImporterList and relay -// them to the ImportDialogController. -class ImporterListObserverBridge : public ImporterList::Observer { - public: - explicit ImporterListObserverBridge( - ImportDialogController *controller); - - private: - // ImporterList::Observer: - virtual void SourceProfilesLoaded() OVERRIDE; - - ImportDialogController* window_controller_; // weak, owns us. -}; - -ImporterListObserverBridge::ImporterListObserverBridge( - ImportDialogController *controller) - : window_controller_(controller) { -} - -void ImporterListObserverBridge::SourceProfilesLoaded() { - [window_controller_ sourceProfilesLoaded]; -} - -namespace { - -bool importSettingsDialogVisible = false; - -} // namespace - -@interface ImportDialogController () - -@property(assign, readwrite, nonatomic) BOOL historyAvailable; -@property(assign, readwrite, nonatomic) BOOL favoritesAvailable; -@property(assign, readwrite, nonatomic) BOOL passwordsAvailable; -@property(assign, readwrite, nonatomic) BOOL searchEnginesAvailable; - -@end - -@implementation ImportSettingsProfile - -@synthesize browserName = browserName_; -@synthesize services = services_; - -+ (id)importSettingsProfileWithBrowserName:(NSString*)browserName - services:(uint16)services { - id settingsProfile = [[[ImportSettingsProfile alloc] - initWithBrowserName:browserName - services:services] autorelease]; - return settingsProfile; -} - -- (id)initWithBrowserName:(NSString*)browserName - services:(uint16)services { - DCHECK(browserName); - if ((self = [super init])) { - if (browserName) { - browserName_ = [browserName retain]; - services_ = services; - } else { - [self release]; - self = nil; - } - } - return self; -} - -- (id)init { - NOTREACHED(); // Should never be called. - return [self initWithBrowserName:NULL services:0]; -} - -- (void)dealloc { - [browserName_ release]; - [super dealloc]; -} - -@end - -@interface ImportDialogController (Private) - -// Initialize the dialog controller with either the default profile or -// the profile for the current browser. -- (id)initWithProfile:(Profile*)profile; - -// Present the app modal dialog. -- (void)runModalDialog; - -// Close the modal dialog. -- (void)closeDialog; - -@end - -@implementation ImportDialogController - -@synthesize sourceBrowserIndex = sourceBrowserIndex_; -@synthesize importHistory = importHistory_; -@synthesize importFavorites = importFavorites_; -@synthesize importPasswords = importPasswords_; -@synthesize importSearchEngines = importSearchEngines_; -@synthesize historyAvailable = historyAvailable_; -@synthesize favoritesAvailable = favoritesAvailable_; -@synthesize passwordsAvailable = passwordsAvailable_; -@synthesize searchEnginesAvailable = searchEnginesAvailable_; - -// Set bindings dependencies for importSomething property. -+ (NSSet*)keyPathsForValuesAffectingImportSomething { - return [NSSet setWithObjects:@"importHistory", @"importFavorites", - @"importPasswords", @"importSearchEngines", nil]; -} - -+ (void)showImportSettingsDialogForProfile:(Profile*)profile { - // Don't display if already visible. - if (importSettingsDialogVisible) - return; - ImportDialogController* controller = - [[ImportDialogController alloc] initWithProfile:profile]; - [controller runModalDialog]; -} - -- (id)initWithProfile:(Profile*)profile { - // Collect profile information (profile name and the services which can - // be imported from each) into an array of ImportSettingsProfile which - // are bound to the Browser List array controller and the popup name - // presentation. The services element is used to indirectly control - // checkbox enabling. - importerList_ = new ImporterList; - ImporterList& importerList(*(importerList_.get())); - importerListObserver_.reset(new ImporterListObserverBridge(self)); - importerList.DetectSourceProfiles(importerListObserver_.get()); - - if ((self = [self initWithSourceProfiles:nil])) { - profile_ = profile; - } - return self; -} - -- (id)initWithSourceProfiles:(NSArray*)profiles { - NSString* nibpath = - [base::mac::MainAppBundle() pathForResource:@"ImportSettingsDialog" - ofType:@"nib"]; - if ((self = [super initWithWindowNibPath:nibpath owner:self]) && profiles) - sourceBrowsersList_.reset([profiles retain]); - - return self; -} - -- (id)init { - return [self initWithProfile:nil]; -} - -- (void)dealloc { - if (importerList_) - importerList_->SetObserver(NULL); - [super dealloc]; -} - -- (void)awakeFromNib { - // Force an update of the checkbox enabled states. - [self setSourceBrowserIndex:0]; -} - -// Run application modal. -- (void)runModalDialog { - importSettingsDialogVisible = true; - [NSApp runModalForWindow:[self window]]; -} - -- (IBAction)ok:(id)sender { - [self closeDialog]; - const importer::ProfileInfo& sourceProfile = - importerList_.get()->GetSourceProfileInfoAt([self sourceBrowserIndex]); - uint16 items = sourceProfile.services_supported; - uint16 servicesToImport = items & [self servicesToImport]; - if (servicesToImport) { - if (profile_) { - ImporterHost* importerHost = new ExternalProcessImporterHost; - // Note that a side effect of the following call is to cause the - // importerHost to be disposed once the import has completed. - importer::ShowImportProgressDialog( - nil, servicesToImport, importerHost, nil, sourceProfile, profile_, - false); - } - } else { - LOG(WARNING) << "There were no settings to import from '" - << sourceProfile.description << "'."; - } -} - -- (IBAction)cancel:(id)sender { - [self closeDialog]; -} - -- (void)closeDialog { - importSettingsDialogVisible = false; - [[self window] orderOut:self]; - [NSApp stopModal]; - [self autorelease]; -} - -- (void)sourceProfilesLoaded { - NSMutableArray* browserProfiles; - ImporterList& importerList(*(importerList_.get())); - int profilesCount = importerList.GetAvailableProfileCount(); - if (profilesCount) { - browserProfiles = - [[NSMutableArray alloc] initWithCapacity:profilesCount]; - for (int i = 0; i < profilesCount; ++i) { - const importer::ProfileInfo& sourceProfile = - importerList.GetSourceProfileInfoAt(i); - NSString* browserName = - base::SysWideToNSString(sourceProfile.description); - uint16 browserServices = sourceProfile.services_supported; - ImportSettingsProfile* settingsProfile = - [ImportSettingsProfile - importSettingsProfileWithBrowserName:browserName - services:browserServices]; - [browserProfiles addObject:settingsProfile]; - } - } else { - browserProfiles = - [[NSMutableArray alloc] initWithCapacity:1]; - NSString* dummyName = l10n_util::GetNSString(IDS_IMPORT_NO_PROFILE_FOUND); - ImportSettingsProfile* dummySourceProfile = - [ImportSettingsProfile importSettingsProfileWithBrowserName:dummyName - services:0]; - [browserProfiles addObject:dummySourceProfile]; - } - - [self willChangeValueForKey:@"sourceBrowsersList"]; - sourceBrowsersList_.reset(browserProfiles); - [self didChangeValueForKey:@"sourceBrowsersList"]; - - // Force an update of the checkbox enabled states. - [self setSourceBrowserIndex:0]; - - // Resize and show the popup button. - [sourceProfilePopUpButton_ sizeToFit]; - [sourceProfilePopUpButton_ setHidden:NO]; -} - -#pragma mark Accessors - -- (NSArray*)sourceBrowsersList { - return sourceBrowsersList_.get(); -} - -// Accessor which cascades selected-browser changes into a re-evaluation of the -// available services and the associated checkbox enable and checked states. -- (void)setSourceBrowserIndex:(NSUInteger)browserIndex { - uint16 items = 0; - if ([sourceBrowsersList_.get() count]) { - [self willChangeValueForKey:@"sourceBrowserIndex"]; - sourceBrowserIndex_ = browserIndex; - [self didChangeValueForKey:@"sourceBrowserIndex"]; - - ImportSettingsProfile* profile = - [sourceBrowsersList_.get() objectAtIndex:browserIndex]; - items = [profile services]; - } - [self setHistoryAvailable:(items & importer::HISTORY) ? YES : NO]; - [self setImportHistory:[self historyAvailable]]; - [self setFavoritesAvailable:(items & importer::FAVORITES) ? YES : NO]; - [self setImportFavorites:[self favoritesAvailable]]; - [self setPasswordsAvailable:(items & importer::PASSWORDS) ? YES : NO]; - [self setImportPasswords:[self passwordsAvailable]]; - [self setSearchEnginesAvailable:(items & importer::SEARCH_ENGINES) ? - YES : NO]; - [self setImportSearchEngines:[self searchEnginesAvailable]]; -} - -- (uint16)servicesToImport { - uint16 servicesToImport = 0; - if ([self importHistory]) servicesToImport |= importer::HISTORY; - if ([self importFavorites]) servicesToImport |= importer::FAVORITES; - if ([self importPasswords]) servicesToImport |= importer::PASSWORDS; - if ([self importSearchEngines]) servicesToImport |= - importer::SEARCH_ENGINES; - return servicesToImport; -} - -// KVO accessor which returns YES if at least one of the services -// provided by the selected profile has been marked for importing -// and bound to the OK button's enable property. -- (BOOL)importSomething { - return [self importHistory] || [self importFavorites] || - [self importPasswords] || [self importSearchEngines]; -} - -@end diff --git a/chrome/browser/ui/cocoa/importer/import_dialog_cocoa_unittest.mm b/chrome/browser/ui/cocoa/importer/import_dialog_cocoa_unittest.mm deleted file mode 100644 index 2a76dfb..0000000 --- a/chrome/browser/ui/cocoa/importer/import_dialog_cocoa_unittest.mm +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2011 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/scoped_nsobject.h" -#include "chrome/browser/importer/importer.h" -#import "chrome/browser/ui/cocoa/browser_test_helper.h" -#import "chrome/browser/ui/cocoa/cocoa_test_helper.h" -#import "chrome/browser/ui/cocoa/importer/import_dialog_cocoa.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -class ImportSettingsDialogTest : public CocoaTest { - public: - ImportDialogController* controller_; - - virtual void SetUp() { - CocoaTest::SetUp(); - uint16 safariServices = importer::HISTORY | importer::FAVORITES | - importer::COOKIES | importer::PASSWORDS | - importer::SEARCH_ENGINES; - ImportSettingsProfile* mockSafari = - [ImportSettingsProfile - importSettingsProfileWithBrowserName:@"MockSafari" - services:safariServices]; - uint16 firefoxServices = importer::HISTORY | importer::FAVORITES | - importer::COOKIES | importer::PASSWORDS; - ImportSettingsProfile* mockFirefox = - [ImportSettingsProfile - importSettingsProfileWithBrowserName:@"MockFirefox" - services:firefoxServices]; - uint16 caminoServices = importer::HISTORY | importer::COOKIES | - importer::SEARCH_ENGINES; - ImportSettingsProfile* mockCamino = - [ImportSettingsProfile - importSettingsProfileWithBrowserName:@"MockCamino" - services:caminoServices]; - NSArray* browsers = [NSArray arrayWithObjects: - mockSafari, mockFirefox, mockCamino, nil]; - controller_ = [[ImportDialogController alloc] - initWithSourceProfiles:browsers]; - } - - virtual void TearDown() { - controller_ = NULL; - CocoaTest::TearDown(); - } -}; - -TEST_F(ImportSettingsDialogTest, CancelDialog) { - [controller_ cancel:nil]; -} - -TEST_F(ImportSettingsDialogTest, ChooseVariousBrowsers) { - // Initial choice should already be MockSafari with all items enabled. - [controller_ setSourceBrowserIndex:0]; - EXPECT_TRUE([controller_ importHistory]); - EXPECT_TRUE([controller_ historyAvailable]); - EXPECT_TRUE([controller_ importFavorites]); - EXPECT_TRUE([controller_ favoritesAvailable]); - EXPECT_TRUE([controller_ importPasswords]); - EXPECT_TRUE([controller_ passwordsAvailable]); - EXPECT_TRUE([controller_ importSearchEngines]); - EXPECT_TRUE([controller_ searchEnginesAvailable]); - EXPECT_EQ(importer::HISTORY | importer::FAVORITES | importer::PASSWORDS | - importer::SEARCH_ENGINES, - [controller_ servicesToImport]); - - // Next choice we test is MockCamino. - [controller_ setSourceBrowserIndex:2]; - EXPECT_TRUE([controller_ importHistory]); - EXPECT_TRUE([controller_ historyAvailable]); - EXPECT_FALSE([controller_ importFavorites]); - EXPECT_FALSE([controller_ favoritesAvailable]); - EXPECT_FALSE([controller_ importPasswords]); - EXPECT_FALSE([controller_ passwordsAvailable]); - EXPECT_TRUE([controller_ importSearchEngines]); - EXPECT_TRUE([controller_ searchEnginesAvailable]); - EXPECT_EQ(importer::HISTORY | importer::SEARCH_ENGINES, - [controller_ servicesToImport]); - - // Next choice we test is MockFirefox. - [controller_ setSourceBrowserIndex:1]; - EXPECT_TRUE([controller_ importHistory]); - EXPECT_TRUE([controller_ historyAvailable]); - EXPECT_TRUE([controller_ importFavorites]); - EXPECT_TRUE([controller_ favoritesAvailable]); - EXPECT_TRUE([controller_ importPasswords]); - EXPECT_TRUE([controller_ passwordsAvailable]); - EXPECT_FALSE([controller_ importSearchEngines]); - EXPECT_FALSE([controller_ searchEnginesAvailable]); - EXPECT_EQ(importer::HISTORY | importer::FAVORITES | importer::PASSWORDS, - [controller_ servicesToImport]); - - [controller_ cancel:nil]; -} - -TEST_F(ImportSettingsDialogTest, SetVariousSettings) { - // Leave the choice MockSafari, but toggle the settings. - [controller_ setImportHistory:NO]; - [controller_ setImportFavorites:NO]; - [controller_ setImportPasswords:NO]; - [controller_ setImportSearchEngines:NO]; - EXPECT_EQ(importer::NONE, [controller_ servicesToImport]); - EXPECT_FALSE([controller_ importSomething]); - - [controller_ setImportHistory:YES]; - EXPECT_EQ(importer::HISTORY, [controller_ servicesToImport]); - EXPECT_TRUE([controller_ importSomething]); - - [controller_ setImportHistory:NO]; - [controller_ setImportFavorites:YES]; - EXPECT_EQ(importer::FAVORITES, [controller_ servicesToImport]); - EXPECT_TRUE([controller_ importSomething]); - [controller_ setImportFavorites:NO]; - - [controller_ setImportPasswords:YES]; - EXPECT_EQ(importer::PASSWORDS, [controller_ servicesToImport]); - EXPECT_TRUE([controller_ importSomething]); - - [controller_ setImportPasswords:NO]; - [controller_ setImportSearchEngines:YES]; - EXPECT_EQ(importer::SEARCH_ENGINES, [controller_ servicesToImport]); - EXPECT_TRUE([controller_ importSomething]); - - [controller_ cancel:nil]; -} diff --git a/chrome/browser/ui/cocoa/importer/import_lock_dialog_cocoa.mm b/chrome/browser/ui/cocoa/importer/import_lock_dialog_cocoa.mm index ab53984..f04261d 100644 --- a/chrome/browser/ui/cocoa/importer/import_lock_dialog_cocoa.mm +++ b/chrome/browser/ui/cocoa/importer/import_lock_dialog_cocoa.mm @@ -4,15 +4,16 @@ #import <Cocoa/Cocoa.h> +#include "base/memory/scoped_nsobject.h" #include "base/message_loop.h" -#include "base/scoped_nsobject.h" -#include "chrome/browser/importer/importer.h" -#include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/browser/importer/importer_host.h" +#include "chrome/browser/importer/importer_lock_dialog.h" +#include "chrome/browser/metrics/user_metrics.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util_mac.h" -namespace browser { +namespace importer { void ShowImportLockDialog(gfx::NativeWindow parent, ImporterHost* importer_host) { @@ -28,11 +29,12 @@ void ShowImportLockDialog(gfx::NativeWindow parent, if ([lock_alert runModal] == NSAlertFirstButtonReturn) { MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( - importer_host, &ImporterHost::OnLockViewEnd, true)); + importer_host, &ImporterHost::OnImportLockDialogEnd, true)); } else { MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( - importer_host, &ImporterHost::OnLockViewEnd, false)); + importer_host, &ImporterHost::OnImportLockDialogEnd, false)); } + UserMetrics::RecordAction(UserMetricsAction("ImportLockDialogCocoa_Shown")); } -} // namespace browser +} // namespace importer diff --git a/chrome/browser/ui/cocoa/importer/import_progress_dialog_cocoa.h b/chrome/browser/ui/cocoa/importer/import_progress_dialog_cocoa.h index 48d2880..ad6ebbf 100644 --- a/chrome/browser/ui/cocoa/importer/import_progress_dialog_cocoa.h +++ b/chrome/browser/ui/cocoa/importer/import_progress_dialog_cocoa.h @@ -8,11 +8,15 @@ #import <Cocoa/Cocoa.h> -#include "chrome/browser/importer/importer.h" +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/importer/importer_data_types.h" +#include "chrome/browser/importer/importer_progress_observer.h" -class ImporterObserverBridge; +class ImporterHost; class ImporterObserver; +class ImporterObserverBridge; // Class that acts as a controller for the dialog that shows progress for an // import operation. @@ -20,7 +24,7 @@ class ImporterObserver; @interface ImportProgressDialogController : NSWindowController { scoped_ptr<ImporterObserverBridge> import_host_observer_bridge_; ImporterHost* importer_host_; // (weak) - ImporterObserver* observer_; // (weak) + ImporterObserver* observer_; // (weak) // Strings bound to static labels in the UI dialog. NSString* explanatory_text_; @@ -67,25 +71,18 @@ class ImporterObserver; @end // C++ -> objc bridge for import status notifications. -class ImporterObserverBridge : public ImporterHost::Observer { +class ImporterObserverBridge : public importer::ImporterProgressObserver { public: ImporterObserverBridge(ImportProgressDialogController* owner); virtual ~ImporterObserverBridge(); - // Invoked when data for the specified item is about to be collected. - virtual void ImportItemStarted(importer::ImportItem item); - - // Invoked when data for the specified item has been collected from the - // source profile and is now ready for further processing. - virtual void ImportItemEnded(importer::ImportItem item); - - // Invoked when the import begins. - virtual void ImportStarted(); - - // Invoked when the source profile has been imported. - virtual void ImportEnded(); - private: + // importer::ImporterProgressObserver: + virtual void ImportStarted() OVERRIDE; + virtual void ImportItemStarted(importer::ImportItem item) OVERRIDE; + virtual void ImportItemEnded(importer::ImportItem item) OVERRIDE; + virtual void ImportEnded() OVERRIDE; + ImportProgressDialogController* owner_; DISALLOW_COPY_AND_ASSIGN(ImporterObserverBridge); diff --git a/chrome/browser/ui/cocoa/importer/import_progress_dialog_cocoa.mm b/chrome/browser/ui/cocoa/importer/import_progress_dialog_cocoa.mm index 9befa8c..9d50236 100644 --- a/chrome/browser/ui/cocoa/importer/import_progress_dialog_cocoa.mm +++ b/chrome/browser/ui/cocoa/importer/import_progress_dialog_cocoa.mm @@ -7,9 +7,10 @@ #include "base/logging.h" #include "base/mac/mac_util.h" #include "base/message_loop.h" -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #import "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" +#include "chrome/browser/importer/importer_host.h" #include "chrome/browser/importer/importer_observer.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" @@ -54,7 +55,7 @@ NSString* keyForImportItem(importer::ImportItem item) { @synthesize historyImportEnabled = history_import_enabled_; - (id)initWithImporterHost:(ImporterHost*)host - browserName:(string16)browserName + importerName:(string16)importerName observer:(ImporterObserver*)observer itemsEnabled:(int16)items { NSString* nib_path = @@ -71,7 +72,7 @@ NSString* keyForImportItem(importer::ImportItem item) { NSString* explanatory_text = l10n_util::GetNSStringF( IDS_IMPORT_PROGRESS_EXPLANATORY_TEXT_MAC, productName, - browserName); + importerName); [self setExplanatoryText:explanatory_text]; progress_text_ = @@ -160,6 +161,10 @@ ImporterObserverBridge::ImporterObserverBridge( ImporterObserverBridge::~ImporterObserverBridge() {} +void ImporterObserverBridge::ImportStarted() { + // Not needed for out of process import. +} + void ImporterObserverBridge::ImportItemStarted(importer::ImportItem item) { [owner_ ImportItemStarted:item]; } @@ -168,10 +173,6 @@ void ImporterObserverBridge::ImportItemEnded(importer::ImportItem item) { [owner_ ImportItemEnded:item]; } -void ImporterObserverBridge::ImportStarted() { - // Not needed for out of process import. -} - void ImporterObserverBridge::ImportEnded() { [owner_ ImportEnded]; } @@ -182,20 +183,16 @@ void ShowImportProgressDialog(gfx::NativeWindow parent_window, uint16 items, ImporterHost* importer_host, ImporterObserver* importer_observer, - const ProfileInfo& source_profile, + const SourceProfile& source_profile, Profile* target_profile, bool first_run) { DCHECK(items != 0); - // Retrieve name of browser we're importing from and do a little dance to - // convert wstring -> string16. - string16 import_browser_name = WideToUTF16Hack(source_profile.description); - - // progress_dialog_ is responsible for deleting itself. - ImportProgressDialogController* progress_dialog_ = + // |progress_dialog| is responsible for deleting itself. + ImportProgressDialogController* progress_dialog = [[ImportProgressDialogController alloc] initWithImporterHost:importer_host - browserName:import_browser_name + importerName:source_profile.importer_name observer:importer_observer itemsEnabled:items]; // Call is async. @@ -205,9 +202,9 @@ void ShowImportProgressDialog(gfx::NativeWindow parent_window, // Display the window while spinning a message loop. // For details on why we need a modal message loop see http://crbug.com/19169 - NSWindow* progress_window = [progress_dialog_ window]; + NSWindow* progress_window = [progress_dialog window]; NSModalSession session = [NSApp beginModalSessionForWindow:progress_window]; - [progress_dialog_ showWindow:nil]; + [progress_dialog showWindow:nil]; while (true) { if ([NSApp runModalSession:session] != NSRunContinuesResponse) break; diff --git a/chrome/browser/ui/cocoa/info_bubble_view.mm b/chrome/browser/ui/cocoa/info_bubble_view.mm index 209857a..bc12045 100644 --- a/chrome/browser/ui/cocoa/info_bubble_view.mm +++ b/chrome/browser/ui/cocoa/info_bubble_view.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/info_bubble_view.h" #include "base/logging.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" @implementation InfoBubbleView diff --git a/chrome/browser/ui/cocoa/info_bubble_view_unittest.mm b/chrome/browser/ui/cocoa/info_bubble_view_unittest.mm index c3c438d..ff60da5 100644 --- a/chrome/browser/ui/cocoa/info_bubble_view_unittest.mm +++ b/chrome/browser/ui/cocoa/info_bubble_view_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/info_bubble_view.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" diff --git a/chrome/browser/ui/cocoa/info_bubble_window.h b/chrome/browser/ui/cocoa/info_bubble_window.h index ee91794..cf992d7 100644 --- a/chrome/browser/ui/cocoa/info_bubble_window.h +++ b/chrome/browser/ui/cocoa/info_bubble_window.h @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_ptr.h" +#include "base/memory/scoped_ptr.h" #import "chrome/browser/ui/cocoa/chrome_event_processing_window.h" class AppNotificationBridge; diff --git a/chrome/browser/ui/cocoa/info_bubble_window.mm b/chrome/browser/ui/cocoa/info_bubble_window.mm index 183cf8a..dd28438 100644 --- a/chrome/browser/ui/cocoa/info_bubble_window.mm +++ b/chrome/browser/ui/cocoa/info_bubble_window.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -6,11 +6,11 @@ #include "base/basictypes.h" #include "base/logging.h" -#include "base/scoped_nsobject.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/notification_type.h" +#include "base/memory/scoped_nsobject.h" +#include "content/common/notification_observer.h" +#include "content/common/notification_registrar.h" +#include "content/common/notification_service.h" +#include "content/common/notification_type.h" #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" namespace { diff --git a/chrome/browser/ui/cocoa/info_bubble_window_unittest.mm b/chrome/browser/ui/cocoa/info_bubble_window_unittest.mm index aed5c0a..b174af2 100644 --- a/chrome/browser/ui/cocoa/info_bubble_window_unittest.mm +++ b/chrome/browser/ui/cocoa/info_bubble_window_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_ptr.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "chrome/browser/ui/cocoa/info_bubble_window.h" diff --git a/chrome/browser/ui/cocoa/infobars/infobar_container_controller.h b/chrome/browser/ui/cocoa/infobars/infobar_container_controller.h index 34e4d74..322516e 100644 --- a/chrome/browser/ui/cocoa/infobars/infobar_container_controller.h +++ b/chrome/browser/ui/cocoa/infobars/infobar_container_controller.h @@ -8,10 +8,10 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #import "chrome/browser/ui/cocoa/view_resizer.h" -#include "chrome/common/notification_registrar.h" +#include "content/common/notification_registrar.h" @class InfoBarController; class InfoBarDelegate; @@ -31,7 +31,7 @@ class TabStripModel; namespace infobars { // How tall the tip is on a normal infobar. -const CGFloat kAntiSpoofHeight = 9.0; +const CGFloat kBaseHeight = 36.0; }; // namespace infobars @@ -100,7 +100,8 @@ const CGFloat kAntiSpoofHeight = 9.0; - (NSUInteger)infobarCount; // Returns the amount of additional height the container view needs to draw the -// anti-spoofing bulge. This will return 0 if |-infobarCount| is 0. +// anti-spoofing tip. This will return 0 if |-infobarCount| is 0. This is the +// total amount of overlap for all infobars. - (CGFloat)antiSpoofHeight; @end diff --git a/chrome/browser/ui/cocoa/infobars/infobar_container_controller.mm b/chrome/browser/ui/cocoa/infobars/infobar_container_controller.mm index 8a374ca..9b9d8b9 100644 --- a/chrome/browser/ui/cocoa/infobars/infobar_container_controller.mm +++ b/chrome/browser/ui/cocoa/infobars/infobar_container_controller.mm @@ -10,9 +10,9 @@ #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" #import "chrome/browser/ui/cocoa/infobars/infobar_controller.h" #import "chrome/browser/ui/cocoa/view_id_util.h" -#include "chrome/common/notification_details.h" -#include "chrome/common/notification_source.h" #include "content/browser/tab_contents/tab_contents.h" +#include "content/common/notification_details.h" +#include "content/common/notification_source.h" #include "skia/ext/skia_utils_mac.h" // C++ class that receives INFOBAR_ADDED and INFOBAR_REMOVED @@ -153,7 +153,7 @@ class InfoBarNotificationObserver : public NotificationObserver { } - (CGFloat)antiSpoofHeight { - return [self infobarCount] ? infobars::kAntiSpoofHeight : 0; + return 0; } - (void)resizeView:(NSView*)view newHeight:(CGFloat)height { @@ -173,9 +173,9 @@ class InfoBarNotificationObserver : public NotificationObserver { @implementation InfoBarContainerController (PrivateMethods) - (CGFloat)desiredHeight { - CGFloat height = [self antiSpoofHeight]; + CGFloat height = 0; for (InfoBarController* controller in infobarControllers_.get()) - height += NSHeight([[controller view] frame]) - infobars::kAntiSpoofHeight; + height += NSHeight([[controller view] frame]); return height; } @@ -235,10 +235,11 @@ class InfoBarNotificationObserver : public NotificationObserver { NSView* view = [controller view]; NSRect frame = [view frame]; frame.origin.x = NSMinX(containerBounds); - frame.size.width = NSWidth(containerBounds); frame.origin.y = minY; - minY += frame.size.height - infobars::kAntiSpoofHeight; + frame.size.width = NSWidth(containerBounds); [view setFrame:frame]; + + minY += NSHeight(frame); } [resizeDelegate_ resizeView:[self view] newHeight:[self desiredHeight]]; diff --git a/chrome/browser/ui/cocoa/infobars/infobar_container_controller_unittest.mm b/chrome/browser/ui/cocoa/infobars/infobar_container_controller_unittest.mm index bdeeb73..c05a9ae 100644 --- a/chrome/browser/ui/cocoa/infobars/infobar_container_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/infobars/infobar_container_controller_unittest.mm @@ -4,7 +4,7 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" #include "chrome/browser/ui/cocoa/infobars/mock_confirm_infobar_delegate.h" diff --git a/chrome/browser/ui/cocoa/infobars/infobar_controller.h b/chrome/browser/ui/cocoa/infobars/infobar_controller.h index 6214a42..847ca20 100644 --- a/chrome/browser/ui/cocoa/infobars/infobar_controller.h +++ b/chrome/browser/ui/cocoa/infobars/infobar_controller.h @@ -1,11 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" @class AnimatableView; @class HoverCloseButton; diff --git a/chrome/browser/ui/cocoa/infobars/infobar_controller.mm b/chrome/browser/ui/cocoa/infobars/infobar_controller.mm index 0c9967a..dd9725c 100644 --- a/chrome/browser/ui/cocoa/infobars/infobar_controller.mm +++ b/chrome/browser/ui/cocoa/infobars/infobar_controller.mm @@ -152,6 +152,9 @@ const float kAnimateCloseDuration = 0.12; // Called when someone clicks on the close button. - (void)dismiss:(id)sender { + if (delegate_) + delegate_->InfoBarDismissed(); + [self removeInfoBar]; } @@ -168,9 +171,6 @@ const float kAnimateCloseDuration = 0.12; - (void)animateOpen { // Force the frame size to be 0 and then start an animation. NSRect frame = [[self view] frame]; - // Slide the origin down so it doesn't animate on top of the toolbar, but - // rather just in the content area. - frame.origin.y -= infobars::kAntiSpoofHeight; CGFloat finalHeight = frame.size.height; frame.size.height = 0; [[self view] setFrame:frame]; @@ -189,11 +189,6 @@ const float kAnimateCloseDuration = 0.12; // Notify the container of our intentions. [containerController_ willRemoveController:self]; - // Take out the anti-spoof height so that the animation does not jump. - NSRect frame = [[self view] frame]; - frame.size.height -= infobars::kAntiSpoofHeight; - [[self view] setFrame:frame]; - // Start animating closed. We will receive a notification when the animation // is done, at which point we can remove our view from the hierarchy and // notify the delegate that the infobar was closed. diff --git a/chrome/browser/ui/cocoa/infobars/infobar_controller_unittest.mm b/chrome/browser/ui/cocoa/infobars/infobar_controller_unittest.mm index b41f972..011e38b 100644 --- a/chrome/browser/ui/cocoa/infobars/infobar_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/infobars/infobar_controller_unittest.mm @@ -4,7 +4,7 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" #include "chrome/browser/tab_contents/confirm_infobar_delegate.h" diff --git a/chrome/browser/ui/cocoa/infobars/infobar_gradient_view.mm b/chrome/browser/ui/cocoa/infobars/infobar_gradient_view.mm index 70e1bb3..8acd360 100644 --- a/chrome/browser/ui/cocoa/infobars/infobar_gradient_view.mm +++ b/chrome/browser/ui/cocoa/infobars/infobar_gradient_view.mm @@ -4,8 +4,8 @@ #include "chrome/browser/ui/cocoa/infobars/infobar_gradient_view.h" -#include "base/scoped_nsobject.h" -#import "chrome/browser/themes/browser_theme_provider.h" +#include "base/memory/scoped_nsobject.h" +#import "chrome/browser/themes/theme_service.h" #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" #import "chrome/browser/ui/cocoa/themed_window.h" @@ -17,10 +17,6 @@ const double kBackgroundColorBottom[3] = {250.0 / 255.0, 230.0 / 255.0, 145.0 / 255.0}; } -@interface InfoBarGradientView (Private) -- (void)strokePath:(NSBezierPath*)path; -@end - @implementation InfoBarGradientView - (id)initWithFrame:(NSRect)frameRect { @@ -50,54 +46,26 @@ const double kBackgroundColorBottom[3] = BOOL active = [[self window] isMainWindow]; return themeProvider->GetNSColor( - active ? BrowserThemeProvider::COLOR_TOOLBAR_STROKE : - BrowserThemeProvider::COLOR_TOOLBAR_STROKE_INACTIVE, + active ? ThemeService::COLOR_TOOLBAR_STROKE : + ThemeService::COLOR_TOOLBAR_STROKE_INACTIVE, true); } - (void)drawRect:(NSRect)rect { NSRect bounds = [self bounds]; - bounds.size.height -= infobars::kAntiSpoofHeight; - - const CGFloat tipHeight = infobars::kAntiSpoofHeight; - const CGFloat curveDistance = 13.0; - const CGFloat iconWidth = 29.0; - const CGFloat tipPadding = 4.0; - const CGFloat pathJoinShift = 2.5; - - // Draw the tab bulge that acts as the anti-spoofing countermeasure. - NSBezierPath* bulgePath = [NSBezierPath bezierPath]; - NSPoint startPoint = NSMakePoint(0, NSMaxY([self frame]) - tipHeight); - [bulgePath moveToPoint:startPoint]; - [bulgePath relativeCurveToPoint:NSMakePoint(curveDistance, tipHeight) - controlPoint1:NSMakePoint(curveDistance/2, 0) - controlPoint2:NSMakePoint(curveDistance/2, tipHeight)]; - - // The height is too small and the control points too close for the stroke - // across this straight line to have enough definition. Save off the points - // for later to create a separate line to stroke. - NSPoint topStrokeStart = [bulgePath currentPoint]; - [bulgePath relativeLineToPoint:NSMakePoint(tipPadding + iconWidth, 0)]; - NSPoint topStrokeEnd = [bulgePath currentPoint]; - - [bulgePath relativeCurveToPoint:NSMakePoint(curveDistance, -tipHeight) - controlPoint1:NSMakePoint(curveDistance/2, 0) - controlPoint2:NSMakePoint(curveDistance/2, -tipHeight)]; + bounds.size.height = infobars::kBaseHeight; // Around the bounds of the infobar, continue drawing the path into which the // gradient will be drawn. - scoped_nsobject<NSBezierPath> infoBarPath([bulgePath copy]); - [infoBarPath lineToPoint:NSMakePoint(NSMaxX(bounds), startPoint.y)]; + NSBezierPath* infoBarPath = [NSBezierPath bezierPath]; + [infoBarPath moveToPoint:NSMakePoint(NSMinX(bounds), NSMaxY(bounds))]; + [infoBarPath lineToPoint:NSMakePoint(NSMaxX(bounds), NSMaxY(bounds))]; + scoped_nsobject<NSBezierPath> topPath([infoBarPath copy]); + [infoBarPath lineToPoint:NSMakePoint(NSMaxX(bounds), NSMinY(bounds))]; [infoBarPath lineToPoint:NSMakePoint(NSMinX(bounds), NSMinY(bounds))]; - [infoBarPath lineToPoint:NSMakePoint(NSMinX(bounds), startPoint.y)]; - [infoBarPath lineToPoint:startPoint]; [infoBarPath closePath]; - // Stroke the bulge. - [bulgePath setLineCapStyle:NSSquareLineCapStyle]; - [self strokePath:bulgePath]; - // Draw the gradient. [[self gradient] drawInBezierPath:infoBarPath angle:270]; @@ -110,13 +78,12 @@ const double kBackgroundColorBottom[3] = NSRectFillUsingOperation(borderRect, NSCompositeSourceOver); } - // Stroke the horizontal line to ensure it has enough definition. - topStrokeStart.x -= pathJoinShift; - topStrokeEnd.x += pathJoinShift; - NSBezierPath* topStroke = [NSBezierPath bezierPath]; - [topStroke moveToPoint:topStrokeStart]; - [topStroke lineToPoint:topStrokeEnd]; - [self strokePath:topStroke]; + // Add an inner stroke. + [[NSColor colorWithDeviceWhite:1.0 alpha:1.0] setStroke]; + NSAffineTransform* transform = [NSAffineTransform transform]; + [transform translateXBy:0.0 yBy:-1.0]; + [topPath transformUsingAffineTransform:transform]; + [topPath stroke]; } - (BOOL)mouseDownCanMoveWindow { @@ -136,20 +103,4 @@ const double kBackgroundColorBottom[3] = return [super accessibilityAttributeValue:attribute]; } -// Private ///////////////////////////////////////////////////////////////////// - -// Stroking paths with just |-strokeColor| will blend with the color underneath -// it and will make it appear lighter than it should. Stroke with black first to -// have the stroke color come out right. -- (void)strokePath:(NSBezierPath*)path { - [[NSGraphicsContext currentContext] saveGraphicsState]; - - [[NSColor blackColor] set]; - [path stroke]; - [[self strokeColor] set]; - [path stroke]; - - [[NSGraphicsContext currentContext] restoreGraphicsState]; -} - @end diff --git a/chrome/browser/ui/cocoa/infobars/infobar_gradient_view_unittest.mm b/chrome/browser/ui/cocoa/infobars/infobar_gradient_view_unittest.mm index f7a6756..da5b02b 100644 --- a/chrome/browser/ui/cocoa/infobars/infobar_gradient_view_unittest.mm +++ b/chrome/browser/ui/cocoa/infobars/infobar_gradient_view_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/infobars/infobar_gradient_view.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" diff --git a/chrome/browser/ui/cocoa/instant_confirm_window_controller.h b/chrome/browser/ui/cocoa/instant_confirm_window_controller.h deleted file mode 100644 index a0f0c2f..0000000 --- a/chrome/browser/ui/cocoa/instant_confirm_window_controller.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2010 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_UI_COCOA_INSTANT_CONFIRM_WINDOW_CONTROLLER_H_ -#define CHROME_BROWSER_UI_COCOA_INSTANT_CONFIRM_WINDOW_CONTROLLER_H_ -#pragma once - -#import <Cocoa/Cocoa.h> - -#import "base/mac/cocoa_protocols.h" - -class Profile; - -// This controller manages a dialog that informs the user about Instant search. -// The recommended API is to not use this class directly, but instead to use -// the functions in //chrome/browser/instant/instant_confirm_dialog.h: -// void ShowInstantConfirmDialog[IfNecessary](gfx::NativeWindow* parent, ...) -// Which will attach the window to |parent| as a sheet. -@interface InstantConfirmWindowController : NSWindowController<NSWindowDelegate> -{ - @private - // The long description about Instant that needs to be sized-to-fit. - IBOutlet NSTextField* description_; - - Profile* profile_; // weak -} - -// Designated initializer. The controller will release itself on window close. -- (id)initWithProfile:(Profile*)profile; - -// Action for the "Learn more" link. -- (IBAction)learnMore:(id)sender; - -// The user has opted in to Instant. This enables the Instant preference. -- (IBAction)ok:(id)sender; - -// Closes the sheet without altering the preference value. -- (IBAction)cancel:(id)sender; - -@end - -#endif // CHROME_BROWSER_UI_COCOA_INSTANT_CONFIRM_WINDOW_CONTROLLER_H_ diff --git a/chrome/browser/ui/cocoa/instant_confirm_window_controller.mm b/chrome/browser/ui/cocoa/instant_confirm_window_controller.mm deleted file mode 100644 index c98d3f0..0000000 --- a/chrome/browser/ui/cocoa/instant_confirm_window_controller.mm +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) 2010 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/ui/cocoa/instant_confirm_window_controller.h" - -#include "base/logging.h" -#include "base/mac/mac_util.h" -#include "chrome/browser/instant/instant_confirm_dialog.h" -#include "chrome/browser/instant/instant_controller.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/options/show_options_url.h" -#include "googleurl/src/gurl.h" -#import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" -#include "ui/gfx/native_widget_types.h" - -namespace browser { - -void ShowInstantConfirmDialog(gfx::NativeWindow parent, Profile* profile) { - InstantConfirmWindowController* controller = - [[InstantConfirmWindowController alloc] initWithProfile:profile]; - [NSApp beginSheet:[controller window] - modalForWindow:parent - modalDelegate:nil - didEndSelector:NULL - contextInfo:NULL]; -} - -} // namespace browser - -@implementation InstantConfirmWindowController - -- (id)initWithProfile:(Profile*)profile { - NSString* nibPath = [base::mac::MainAppBundle() - pathForResource:@"InstantConfirm" - ofType:@"nib"]; - if ((self = [super initWithWindowNibPath:nibPath owner:self])) { - profile_ = profile; - } - return self; -} - -- (void)awakeFromNib { - DCHECK([self window]); - DCHECK_EQ(self, [[self window] delegate]); - - CGFloat delta = [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField: - description_]; - NSRect descriptionFrame = [description_ frame]; - descriptionFrame.origin.y -= delta; - [description_ setFrame:descriptionFrame]; - - NSRect frame = [[self window] frame]; - frame.size.height += delta; - [[self window] setFrame:frame display:YES]; -} - -- (void)windowWillClose:(NSNotification*)notif { - [self autorelease]; -} - -- (IBAction)learnMore:(id)sender { - browser::ShowOptionsURL(profile_, browser::InstantLearnMoreURL()); -} - -- (IBAction)ok:(id)sender { - InstantController::Enable(profile_); - [self cancel:sender]; -} - -- (IBAction)cancel:(id)sender { - [NSApp endSheet:[self window]]; - [[self window] close]; -} - -@end diff --git a/chrome/browser/ui/cocoa/instant_confirm_window_controller_unittest.mm b/chrome/browser/ui/cocoa/instant_confirm_window_controller_unittest.mm deleted file mode 100644 index 71d8c9e..0000000 --- a/chrome/browser/ui/cocoa/instant_confirm_window_controller_unittest.mm +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2010 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/ui/cocoa/instant_confirm_window_controller.h" - -#include "chrome/browser/instant/instant_confirm_dialog.h" -#import "chrome/browser/ui/cocoa/browser_test_helper.h" -#import "chrome/browser/ui/cocoa/cocoa_test_helper.h" - -namespace { - -class InstantConfirmWindowControllerTest : public CocoaTest { - public: - InstantConfirmWindowControllerTest() : controller_(nil) {} - - BrowserTestHelper helper_; - InstantConfirmWindowController* controller_; // Weak. Owns self. -}; - -TEST_F(InstantConfirmWindowControllerTest, Init) { - controller_ = - [[InstantConfirmWindowController alloc] initWithProfile: - helper_.profile()]; - EXPECT_TRUE([controller_ window]); - [controller_ release]; -} - -TEST_F(InstantConfirmWindowControllerTest, Show) { - browser::ShowInstantConfirmDialog(test_window(), helper_.profile()); - controller_ = [[test_window() attachedSheet] windowController]; - EXPECT_TRUE(controller_); - [controller_ cancel:nil]; -} - -} // namespace diff --git a/chrome/browser/ui/cocoa/js_modal_dialog_cocoa.h b/chrome/browser/ui/cocoa/js_modal_dialog_cocoa.h index 9179b04..073e60f 100644 --- a/chrome/browser/ui/cocoa/js_modal_dialog_cocoa.h +++ b/chrome/browser/ui/cocoa/js_modal_dialog_cocoa.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,8 +9,8 @@ #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h" #include "base/logging.h" -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #if __OBJC__ @class NSAlert; diff --git a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.h b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.h index f4001b1..aef1c8b 100644 --- a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.h +++ b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,7 +9,7 @@ #import <Cocoa/Cocoa.h> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/styled_text_field.h" #import "chrome/browser/ui/cocoa/url_drop_target.h" diff --git a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_cell_unittest.mm b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_cell_unittest.mm index 1bc2eee..72acb71 100644 --- a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_cell_unittest.mm +++ b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_cell_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/utf_string_conversions.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.h" diff --git a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.h b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.h index 905bc84..b483381 100644 --- a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.h +++ b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.h @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/url_drop_target.h" @class AutocompleteTextField; diff --git a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm index 9ed6ebd..415e6c6 100644 --- a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm +++ b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm @@ -1,20 +1,47 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/location_bar/autocomplete_text_field_editor.h" #include "base/string_util.h" -#include "grit/generated_resources.h" #include "base/sys_string_conversions.h" #include "chrome/app/chrome_command_ids.h" // IDC_* -#include "chrome/browser/browser_list.h" +#include "chrome/browser/ui/browser_list.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.h" #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_cell.h" #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" +#include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util_mac.h" +namespace { + +// When too much data is put into a single-line text field, things get +// janky due to the cost of computing the blink rect. Sometimes users +// accidentally paste large amounts, so place a limit on what will be +// accepted. +// +// 10k characters was arbitrarily chosen by seeing how much a text +// field could handle in a single line before it started getting too +// janky to recover from (jankiness was detectable around 5k). +// www.google.com returns an error for searches around 2k characters, +// so this is conservative. +const NSUInteger kMaxPasteLength = 10000; + +// Returns |YES| if too much text would be pasted. +BOOL ThePasteboardIsTooDamnBig() { + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + NSString* type = + [pb availableTypeFromArray:[NSArray arrayWithObject:NSStringPboardType]]; + if (!type) + return NO; + + return [[pb stringForType:type] length] > kMaxPasteLength; +} + +} // namespace + @implementation AutocompleteTextFieldEditor - (id)initWithFrame:(NSRect)frameRect { @@ -90,6 +117,11 @@ } - (void)paste:(id)sender { + if (ThePasteboardIsTooDamnBig()) { + NSBeep(); + return; + } + AutocompleteTextFieldObserver* observer = [self observer]; DCHECK(observer); if (observer) { @@ -98,6 +130,11 @@ } - (void)pasteAndGo:sender { + if (ThePasteboardIsTooDamnBig()) { + NSBeep(); + return; + } + AutocompleteTextFieldObserver* observer = [self observer]; DCHECK(observer); if (observer) { diff --git a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor_unittest.mm b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor_unittest.mm index 8e2d347..889d948 100644 --- a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor_unittest.mm +++ b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor_unittest.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/location_bar/autocomplete_text_field_editor.h" -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "base/string_util.h" #include "chrome/app/chrome_command_ids.h" // IDC_* #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" diff --git a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_unittest.mm b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_unittest.mm index 1aa65ec..62905bd 100644 --- a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_unittest.mm +++ b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_unittest.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.h" #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_cell.h" #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.h" diff --git a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_unittest_helper.h b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_unittest_helper.h index e4686b9..1d260be 100644 --- a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_unittest_helper.h +++ b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_unittest_helper.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,7 +9,7 @@ #import <Cocoa/Cocoa.h> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.h" #include "testing/gmock/include/gmock/gmock.h" diff --git a/chrome/browser/ui/cocoa/location_bar/bubble_decoration.h b/chrome/browser/ui/cocoa/location_bar/bubble_decoration.h index 55e09be..508cbd4 100644 --- a/chrome/browser/ui/cocoa/location_bar/bubble_decoration.h +++ b/chrome/browser/ui/cocoa/location_bar/bubble_decoration.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,7 +9,7 @@ #import <Cocoa/Cocoa.h> #include "base/gtest_prod_util.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/browser/ui/cocoa/location_bar/location_bar_decoration.h" // Draws an outlined rounded rect, with an optional image to the left diff --git a/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.h b/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.h index 0e12f39..8c3346b 100644 --- a/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.h +++ b/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -6,7 +6,7 @@ #define CHROME_BROWSER_UI_COCOA_LOCATION_BAR_CONTENT_SETTING_DECORATION_H_ #pragma once -#include "base/scoped_ptr.h" +#include "base/memory/scoped_ptr.h" #import "chrome/browser/ui/cocoa/location_bar/image_decoration.h" #include "chrome/common/content_settings_types.h" diff --git a/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.mm b/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.mm index b036bec..efdcff7 100644 --- a/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.mm +++ b/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,11 +9,11 @@ #include "base/command_line.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/content_setting_image_model.h" #include "chrome/browser/content_setting_bubble_model.h" +#include "chrome/browser/content_setting_image_model.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser_list.h" #import "chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.h" #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" #include "chrome/common/chrome_switches.h" diff --git a/chrome/browser/ui/cocoa/location_bar/image_decoration.h b/chrome/browser/ui/cocoa/location_bar/image_decoration.h index c0bcfbf..889144b 100644 --- a/chrome/browser/ui/cocoa/location_bar/image_decoration.h +++ b/chrome/browser/ui/cocoa/location_bar/image_decoration.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -6,7 +6,7 @@ #define CHROME_BROWSER_UI_COCOA_LOCATION_BAR_IMAGE_DECORATION_H_ #pragma once -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #include "chrome/browser/ui/cocoa/location_bar/location_bar_decoration.h" // |LocationBarDecoration| which sizes and draws itself according to diff --git a/chrome/browser/ui/cocoa/location_bar/instant_opt_in_controller_unittest.mm b/chrome/browser/ui/cocoa/location_bar/instant_opt_in_controller_unittest.mm index 81ef513..dd1ea26 100644 --- a/chrome/browser/ui/cocoa/location_bar/instant_opt_in_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/location_bar/instant_opt_in_controller_unittest.mm @@ -1,9 +1,9 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/location_bar/instant_opt_in_controller.h" #include "testing/gmock/include/gmock/gmock.h" diff --git a/chrome/browser/ui/cocoa/location_bar/keyword_hint_decoration.h b/chrome/browser/ui/cocoa/location_bar/keyword_hint_decoration.h index da8c42b..0e4e587 100644 --- a/chrome/browser/ui/cocoa/location_bar/keyword_hint_decoration.h +++ b/chrome/browser/ui/cocoa/location_bar/keyword_hint_decoration.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -10,7 +10,7 @@ #import "chrome/browser/ui/cocoa/location_bar/location_bar_decoration.h" -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #include "base/string16.h" // Draws the keyword hint, "Press [tab] to search <site>". diff --git a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h index 4c1bd3c..388facb 100644 --- a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h +++ b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -10,13 +10,14 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" -#include "base/scoped_vector.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" #include "chrome/browser/autocomplete/autocomplete_edit.h" #include "chrome/browser/autocomplete/autocomplete_edit_view_mac.h" #include "chrome/browser/extensions/image_loading_tracker.h" #include "chrome/browser/first_run/first_run.h" +#include "chrome/browser/prefs/pref_member.h" #include "chrome/browser/ui/omnibox/location_bar.h" #include "chrome/browser/ui/toolbar/toolbar_model.h" #include "chrome/common/content_settings_types.h" @@ -54,7 +55,8 @@ class LocationBarViewMac : public AutocompleteEditController, // Overridden from LocationBar: virtual void ShowFirstRunBubble(FirstRun::BubbleType bubble_type); - virtual void SetSuggestedText(const string16& text); + virtual void SetSuggestedText(const string16& text, + InstantCompleteBehavior behavior); virtual std::wstring GetInputString() const; virtual WindowOpenDisposition GetWindowOpenDisposition() const; virtual PageTransition::Type GetPageTransition() const; @@ -134,10 +136,10 @@ class LocationBarViewMac : public AutocompleteEditController, virtual void OnInputInProgress(bool in_progress); virtual void OnKillFocus(); virtual void OnSetFocus(); - virtual SkBitmap GetFavIcon() const; + virtual SkBitmap GetFavicon() const; virtual string16 GetTitle() const; virtual InstantController* GetInstant(); - virtual TabContentsWrapper* GetTabContentsWrapper(); + virtual TabContentsWrapper* GetTabContentsWrapper() const; NSImage* GetKeywordImage(const string16& keyword); @@ -169,6 +171,9 @@ class LocationBarViewMac : public AutocompleteEditController, void ShowFirstRunBubbleInternal(FirstRun::BubbleType bubble_type); + // Checks if the bookmark star should be enabled or not. + bool IsStarEnabled(); + scoped_ptr<AutocompleteEditViewMac> edit_view_; CommandUpdater* command_updater_; // Weak, owned by Browser. @@ -220,6 +225,9 @@ class LocationBarViewMac : public AutocompleteEditController, // Used to schedule a task for the first run info bubble. ScopedRunnableMethodFactory<LocationBarViewMac> first_run_bubble_; + // Used to change the visibility of the star decoration. + BooleanPrefMember edit_bookmarks_enabled_; + DISALLOW_COPY_AND_ASSIGN(LocationBarViewMac); }; diff --git a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm index 2b82cfc..980ea27 100644 --- a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm +++ b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm @@ -13,10 +13,9 @@ #import "chrome/browser/app_controller_mac.h" #import "chrome/browser/autocomplete/autocomplete_edit_view_mac.h" #import "chrome/browser/autocomplete/autocomplete_popup_model.h" -#include "chrome/browser/browser_list.h" #include "chrome/browser/command_updater.h" -#include "chrome/browser/content_setting_image_model.h" #include "chrome/browser/content_setting_bubble_model.h" +#include "chrome/browser/content_setting_image_model.h" #include "chrome/browser/defaults.h" #include "chrome/browser/extensions/extension_browser_event_router.h" #include "chrome/browser/extensions/extension_service.h" @@ -25,6 +24,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search_engines/template_url.h" #include "chrome/browser/search_engines/template_url_model.h" +#include "chrome/browser/ui/browser_list.h" #import "chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.h" #include "chrome/browser/ui/cocoa/event_utils.h" #import "chrome/browser/ui/cocoa/extensions/extension_action_context_menu.h" @@ -43,12 +43,13 @@ #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_action.h" #include "chrome/common/extensions/extension_resource.h" -#include "chrome/common/notification_service.h" +#include "chrome/common/pref_names.h" #include "content/browser/tab_contents/navigation_entry.h" #include "content/browser/tab_contents/tab_contents.h" -#include "net/base/net_util.h" +#include "content/common/notification_service.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" +#include "net/base/net_util.h" #include "skia/ext/skia_utils_mac.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -101,6 +102,9 @@ LocationBarViewMac::LocationBarViewMac( registrar_.Add(this, NotificationType::EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED, NotificationService::AllSources()); + + edit_bookmarks_enabled_.Init(prefs::kEditBookmarksEnabled, + profile_->GetPrefs(), this); } LocationBarViewMac::~LocationBarViewMac() { @@ -137,8 +141,9 @@ std::wstring LocationBarViewMac::GetInputString() const { return location_input_; } -void LocationBarViewMac::SetSuggestedText(const string16& text) { - edit_view_->model()->SetSuggestedText(text); +void LocationBarViewMac::SetSuggestedText(const string16& text, + InstantCompleteBehavior behavior) { + edit_view_->model()->SetSuggestedText(text, behavior); } WindowOpenDisposition LocationBarViewMac::GetWindowOpenDisposition() const { @@ -201,8 +206,7 @@ void LocationBarViewMac::SaveStateToContents(TabContents* contents) { void LocationBarViewMac::Update(const TabContents* contents, bool should_restore_state) { - bool star_enabled = browser_defaults::bookmarks_enabled && - [field_ isEditable] && !toolbar_model_->input_in_progress(); + bool star_enabled = IsStarEnabled(); command_updater_->UpdateCommandEnabled(IDC_BOOKMARK_PAGE, star_enabled); star_decoration_->SetVisible(star_enabled); RefreshPageActionDecorations(); @@ -273,7 +277,7 @@ void LocationBarViewMac::OnKillFocus() { // Do nothing. } -SkBitmap LocationBarViewMac::GetFavIcon() const { +SkBitmap LocationBarViewMac::GetFavicon() const { NOTIMPLEMENTED(); return SkBitmap(); } @@ -287,7 +291,7 @@ InstantController* LocationBarViewMac::GetInstant() { return browser_->instant(); } -TabContentsWrapper* LocationBarViewMac::GetTabContentsWrapper() { +TabContentsWrapper* LocationBarViewMac::GetTabContentsWrapper() const { return browser_->GetSelectedTabContentsWrapper(); } @@ -416,8 +420,7 @@ void LocationBarViewMac::TestPageActionPressed(size_t index) { void LocationBarViewMac::SetEditable(bool editable) { [field_ setEditable:editable ? YES : NO]; - star_decoration_->SetVisible(browser_defaults::bookmarks_enabled && - editable && !toolbar_model_->input_in_progress()); + star_decoration_->SetVisible(IsStarEnabled()); UpdatePageActions(); Layout(); } @@ -486,6 +489,12 @@ void LocationBarViewMac::Observe(NotificationType type, [field_ setNeedsDisplay:YES]; break; } + + case NotificationType::PREF_CHANGED: + star_decoration_->SetVisible(IsStarEnabled()); + OnChanged(); + break; + default: NOTREACHED() << "Unexpected notification"; break; @@ -629,3 +638,10 @@ void LocationBarViewMac::Layout() { [field_ setNeedsDisplay:YES]; } + +bool LocationBarViewMac::IsStarEnabled() { + return [field_ isEditable] && + browser_defaults::bookmarks_enabled && + !toolbar_model_->input_in_progress() && + edit_bookmarks_enabled_.GetValue(); +} diff --git a/chrome/browser/ui/cocoa/location_bar/omnibox_popup_view_unittest.mm b/chrome/browser/ui/cocoa/location_bar/omnibox_popup_view_unittest.mm index ac4be55..648e040 100644 --- a/chrome/browser/ui/cocoa/location_bar/omnibox_popup_view_unittest.mm +++ b/chrome/browser/ui/cocoa/location_bar/omnibox_popup_view_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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 "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/location_bar/omnibox_popup_view.h" diff --git a/chrome/browser/ui/cocoa/location_bar/page_action_decoration.h b/chrome/browser/ui/cocoa/location_bar/page_action_decoration.h index 13d2cd1..bc91bb7 100644 --- a/chrome/browser/ui/cocoa/location_bar/page_action_decoration.h +++ b/chrome/browser/ui/cocoa/location_bar/page_action_decoration.h @@ -35,7 +35,7 @@ class PageActionDecoration : public ImageDecoration, // Overridden from |ImageLoadingTracker::Observer|. virtual void OnImageLoaded( - SkBitmap* image, ExtensionResource resource, int index); + SkBitmap* image, const ExtensionResource& resource, int index); // Called to notify the Page Action that it should determine whether // to be visible or hidden. |contents| is the TabContents that is diff --git a/chrome/browser/ui/cocoa/location_bar/page_action_decoration.mm b/chrome/browser/ui/cocoa/location_bar/page_action_decoration.mm index d966146..3c11dec 100644 --- a/chrome/browser/ui/cocoa/location_bar/page_action_decoration.mm +++ b/chrome/browser/ui/cocoa/location_bar/page_action_decoration.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -15,8 +15,8 @@ #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" #include "chrome/common/extensions/extension_action.h" #include "chrome/common/extensions/extension_resource.h" -#include "chrome/common/notification_service.h" #include "content/browser/tab_contents/tab_contents.h" +#include "content/common/notification_service.h" #include "skia/ext/skia_utils_mac.h" namespace { @@ -111,7 +111,7 @@ bool PageActionDecoration::OnMousePressed(NSRect frame) { } void PageActionDecoration::OnImageLoaded( - SkBitmap* image, ExtensionResource resource, int index) { + SkBitmap* image, const ExtensionResource& resource, int index) { // We loaded icons()->size() icons, plus one extra if the Page Action had // a default icon. int total_icons = static_cast<int>(page_action_->icon_paths()->size()); diff --git a/chrome/browser/ui/cocoa/menu_button.h b/chrome/browser/ui/cocoa/menu_button.h index 0b463db..9b51648 100644 --- a/chrome/browser/ui/cocoa/menu_button.h +++ b/chrome/browser/ui/cocoa/menu_button.h @@ -8,7 +8,8 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" +#import "chrome/browser/ui/cocoa/toolbar/toolbar_button.h" // This a button which displays a user-provided menu "attached" below it upon // being clicked or dragged (or clicked and held). It expects a @@ -22,7 +23,7 @@ // held. This is used for the toolbar back/forward buttons, which have a // primary action and the menu as a secondary click-hold action. The default // value is NO so that custom actions can be hooked up in Interface Builder. -@interface MenuButton : NSButton { +@interface MenuButton : ToolbarButton { @private scoped_nsobject<NSMenu> attachedMenu_; BOOL attachedMenuEnabled_; diff --git a/chrome/browser/ui/cocoa/menu_button.mm b/chrome/browser/ui/cocoa/menu_button.mm index c66b8d2..07111ab 100644 --- a/chrome/browser/ui/cocoa/menu_button.mm +++ b/chrome/browser/ui/cocoa/menu_button.mm @@ -5,7 +5,7 @@ #import "chrome/browser/ui/cocoa/menu_button.h" #include "base/logging.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/clickhold_button_cell.h" @interface MenuButton (Private) diff --git a/chrome/browser/ui/cocoa/menu_button_unittest.mm b/chrome/browser/ui/cocoa/menu_button_unittest.mm index 8adceb4..e2d0de8 100644 --- a/chrome/browser/ui/cocoa/menu_button_unittest.mm +++ b/chrome/browser/ui/cocoa/menu_button_unittest.mm @@ -3,7 +3,7 @@ // found in the LICENSE file. #include "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/clickhold_button_cell.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/menu_button.h" diff --git a/chrome/browser/ui/cocoa/menu_controller.h b/chrome/browser/ui/cocoa/menu_controller.h index e842ac1..5aa0913 100644 --- a/chrome/browser/ui/cocoa/menu_controller.h +++ b/chrome/browser/ui/cocoa/menu_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,7 +9,7 @@ #import <Cocoa/Cocoa.h> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" namespace ui { class MenuModel; diff --git a/chrome/browser/ui/cocoa/new_tab_button.h b/chrome/browser/ui/cocoa/new_tab_button.h index 9578cbf..623225b 100644 --- a/chrome/browser/ui/cocoa/new_tab_button.h +++ b/chrome/browser/ui/cocoa/new_tab_button.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,7 +8,7 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" // Overrides hit-test behavior to only accept clicks inside the image of the // button, not just inside the bounding box. This could be abstracted to general diff --git a/chrome/browser/ui/cocoa/notifications/balloon_controller.h b/chrome/browser/ui/cocoa/notifications/balloon_controller.h index e346f42..f8a69ce 100644 --- a/chrome/browser/ui/cocoa/notifications/balloon_controller.h +++ b/chrome/browser/ui/cocoa/notifications/balloon_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,8 +9,8 @@ #import <Cocoa/Cocoa.h> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" class Balloon; @class BalloonContentViewCocoa; diff --git a/chrome/browser/ui/cocoa/notifications/balloon_controller.mm b/chrome/browser/ui/cocoa/notifications/balloon_controller.mm index 692cc19..dec0b90 100644 --- a/chrome/browser/ui/cocoa/notifications/balloon_controller.mm +++ b/chrome/browser/ui/cocoa/notifications/balloon_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -7,10 +7,11 @@ #include "app/mac/nsimage_cache.h" #import "base/mac/cocoa_protocols.h" #include "base/mac/mac_util.h" -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #include "base/utf_string_conversions.h" #include "chrome/browser/notifications/balloon.h" #include "chrome/browser/notifications/desktop_notification_service.h" +#include "chrome/browser/notifications/desktop_notification_service_factory.h" #include "chrome/browser/notifications/notification.h" #include "chrome/browser/notifications/notification_options_menu_model.h" #include "chrome/browser/profiles/profile.h" @@ -144,7 +145,7 @@ const int kRightMargin = 2; - (IBAction)permissionRevoked:(id)sender { DesktopNotificationService* service = - balloon_->profile()->GetDesktopNotificationService(); + DesktopNotificationServiceFactory::GetForProfile(balloon_->profile()); service->DenyPermission(balloon_->notification().origin_url()); } diff --git a/chrome/browser/ui/cocoa/notifications/balloon_controller_unittest.mm b/chrome/browser/ui/cocoa/notifications/balloon_controller_unittest.mm index 33c24ce..35d8f7d 100644 --- a/chrome/browser/ui/cocoa/notifications/balloon_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/notifications/balloon_controller_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/utf_string_conversions.h" #include "chrome/browser/notifications/balloon.h" #include "chrome/browser/notifications/balloon_collection.h" diff --git a/chrome/browser/ui/cocoa/notifications/balloon_view.mm b/chrome/browser/ui/cocoa/notifications/balloon_view.mm index aa78be6..fb5e87a 100644 --- a/chrome/browser/ui/cocoa/notifications/balloon_view.mm +++ b/chrome/browser/ui/cocoa/notifications/balloon_view.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -7,7 +7,7 @@ #import <Cocoa/Cocoa.h> #include "base/basictypes.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/notifications/balloon_controller.h" #import "third_party/GTM/AppKit/GTMNSBezierPath+RoundRect.h" diff --git a/chrome/browser/ui/cocoa/nsmenuitem_additions_unittest.mm b/chrome/browser/ui/cocoa/nsmenuitem_additions_unittest.mm index ecbf07d..f9d7412 100644 --- a/chrome/browser/ui/cocoa/nsmenuitem_additions_unittest.mm +++ b/chrome/browser/ui/cocoa/nsmenuitem_additions_unittest.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,7 +8,7 @@ #include <ostream> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/sys_string_conversions.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/nsview_additions.h b/chrome/browser/ui/cocoa/nsview_additions.h new file mode 100644 index 0000000..60095c2 --- /dev/null +++ b/chrome/browser/ui/cocoa/nsview_additions.h @@ -0,0 +1,18 @@ +// Copyright (c) 2011 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_UI_COCOA_NSVIEW_ADDITIONS_H_ +#define CHROME_BROWSER_UI_COCOA_NSVIEW_ADDITIONS_H_ +#pragma once + +#import <Cocoa/Cocoa.h> + +@interface NSView (ChromeAdditions) + +// Returns the line width that will generate a 1 pixel wide line. +- (CGFloat)cr_lineWidth; + +@end + +#endif // CHROME_BROWSER_UI_COCOA_NSVIEW_ADDITIONS_H_ diff --git a/chrome/browser/ui/cocoa/nsview_additions.mm b/chrome/browser/ui/cocoa/nsview_additions.mm new file mode 100644 index 0000000..636837c --- /dev/null +++ b/chrome/browser/ui/cocoa/nsview_additions.mm @@ -0,0 +1,13 @@ +// Copyright (c) 2011 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/ui/cocoa/nsview_additions.h" + +@implementation NSView (ChromeAdditions) + +- (CGFloat)cr_lineWidth { + return 1.0 / [self convertSizeToBase:NSMakeSize(1, 1)].width; +} + +@end diff --git a/chrome/browser/ui/cocoa/objc_method_swizzle.mm b/chrome/browser/ui/cocoa/objc_method_swizzle.mm index 34f88a5..39f3d9b 100644 --- a/chrome/browser/ui/cocoa/objc_method_swizzle.mm +++ b/chrome/browser/ui/cocoa/objc_method_swizzle.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/objc_method_swizzle.h" #import "base/logging.h" -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #import "chrome/app/breakpad_mac.h" namespace ObjcEvilDoers { diff --git a/chrome/browser/ui/cocoa/objc_method_swizzle_unittest.mm b/chrome/browser/ui/cocoa/objc_method_swizzle_unittest.mm index 1641741..f56043c 100644 --- a/chrome/browser/ui/cocoa/objc_method_swizzle_unittest.mm +++ b/chrome/browser/ui/cocoa/objc_method_swizzle_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/objc_method_swizzle.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "testing/gtest/include/gtest/gtest.h" @interface ObjcMethodSwizzleTest : NSObject diff --git a/chrome/browser/ui/cocoa/options/OWNERS b/chrome/browser/ui/cocoa/options/OWNERS deleted file mode 100644 index 7d8d85f..0000000 --- a/chrome/browser/ui/cocoa/options/OWNERS +++ /dev/null @@ -1,3 +0,0 @@ -pinkerton@chromium.org -rsesek@chromium.org -thomasvl@chromium.org diff --git a/chrome/browser/ui/cocoa/options/content_exceptions_window_controller.h b/chrome/browser/ui/cocoa/options/content_exceptions_window_controller.h deleted file mode 100644 index e5ce74f..0000000 --- a/chrome/browser/ui/cocoa/options/content_exceptions_window_controller.h +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2010 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> - -#import "base/mac/cocoa_protocols.h" -#include "base/scoped_ptr.h" -#include "chrome/browser/content_settings/host_content_settings_map.h" -#include "chrome/common/content_settings_types.h" - -class ContentExceptionsTableModel; -class ContentSettingComboModel; -class UpdatingContentSettingsObserver; - -// Controller for the content exception dialogs. -@interface ContentExceptionsWindowController : NSWindowController - <NSWindowDelegate, - NSTableViewDataSource, - NSTableViewDelegate> { - @private - IBOutlet NSTableView* tableView_; - IBOutlet NSButton* addButton_; - IBOutlet NSButton* removeButton_; - IBOutlet NSButton* removeAllButton_; - IBOutlet NSButton* doneButton_; - - ContentSettingsType settingsType_; - HostContentSettingsMap* settingsMap_; // weak - HostContentSettingsMap* otrSettingsMap_; // weak - scoped_ptr<ContentExceptionsTableModel> model_; - scoped_ptr<ContentSettingComboModel> popup_model_; - - // Is set if adding and editing exceptions for the current OTR session should - // be allowed. - BOOL otrAllowed_; - - // Listens for changes to the content settings and reloads the data when they - // change. See comment in -modelDidChange in the mm file for details. - scoped_ptr<UpdatingContentSettingsObserver> tableObserver_; - - // If this is set to NO, notifications by |tableObserver_| are ignored. This - // is used to suppress updates at bad times. - BOOL updatesEnabled_; - - // This is non-NULL only while a new element is being added and its pattern - // is being edited. - scoped_ptr<HostContentSettingsMap::PatternSettingPair> newException_; -} - -// Returns the content exceptions window controller for |settingsType|. -// Changes made by the user in the window are persisted in |settingsMap|. -+ (id)controllerForType:(ContentSettingsType)settingsType - settingsMap:(HostContentSettingsMap*)settingsMap - otrSettingsMap:(HostContentSettingsMap*)otrSettingsMap; - -// Shows the exceptions dialog as a modal sheet attached to |window|. -- (void)attachSheetTo:(NSWindow*)window; - -// Sets the minimum width of the sheet and resizes it if necessary. -- (void)setMinWidth:(CGFloat)minWidth; - -- (IBAction)addException:(id)sender; -- (IBAction)removeException:(id)sender; -- (IBAction)removeAllExceptions:(id)sender; -// Closes the sheet and ends the modal loop. -- (IBAction)closeSheet:(id)sender; - -@end - -@interface ContentExceptionsWindowController(VisibleForTesting) -- (void)cancel:(id)sender; -- (BOOL)editingNewException; -@end diff --git a/chrome/browser/ui/cocoa/options/content_exceptions_window_controller.mm b/chrome/browser/ui/cocoa/options/content_exceptions_window_controller.mm deleted file mode 100644 index a5141de..0000000 --- a/chrome/browser/ui/cocoa/options/content_exceptions_window_controller.mm +++ /dev/null @@ -1,488 +0,0 @@ -// Copyright (c) 2010 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/ui/cocoa/options/content_exceptions_window_controller.h" - -#include "base/command_line.h" -#import "base/mac/mac_util.h" -#import "base/scoped_nsobject.h" -#include "base/sys_string_conversions.h" -#include "chrome/browser/content_exceptions_table_model.h" -#include "chrome/browser/content_setting_combo_model.h" -#include "chrome/common/notification_registrar.h" -#include "chrome/common/notification_service.h" -#include "grit/generated_resources.h" -#include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/l10n/l10n_util_mac.h" -#include "ui/base/models/table_model_observer.h" - -@interface ContentExceptionsWindowController (Private) -- (id)initWithType:(ContentSettingsType)settingsType - settingsMap:(HostContentSettingsMap*)settingsMap - otrSettingsMap:(HostContentSettingsMap*)otrSettingsMap; -- (void)updateRow:(NSInteger)row - withEntry:(const HostContentSettingsMap::PatternSettingPair&)entry - forOtr:(BOOL)isOtr; -- (void)adjustEditingButtons; -- (void)modelDidChange; -- (NSString*)titleForIndex:(size_t)index; -@end - -//////////////////////////////////////////////////////////////////////////////// -// PatternFormatter - -// A simple formatter that accepts text that vaguely looks like a pattern. -@interface PatternFormatter : NSFormatter -@end - -@implementation PatternFormatter -- (NSString*)stringForObjectValue:(id)object { - if (![object isKindOfClass:[NSString class]]) - return nil; - return object; -} - -- (BOOL)getObjectValue:(id*)object - forString:(NSString*)string - errorDescription:(NSString**)error { - if ([string length]) { - if (ContentSettingsPattern( - base::SysNSStringToUTF8(string)).IsValid()) { - *object = string; - return YES; - } - } - if (error) - *error = @"Invalid pattern"; - return NO; -} - -- (NSAttributedString*)attributedStringForObjectValue:(id)object - withDefaultAttributes:(NSDictionary*)attribs { - return nil; -} -@end - -//////////////////////////////////////////////////////////////////////////////// -// UpdatingContentSettingsObserver - -// UpdatingContentSettingsObserver is a notification observer that tells a -// window controller to update its data on every notification. -class UpdatingContentSettingsObserver : public NotificationObserver { - public: - UpdatingContentSettingsObserver(ContentExceptionsWindowController* controller) - : controller_(controller) { - // One would think one could register a TableModelObserver to be notified of - // changes to ContentExceptionsTableModel. One would be wrong: The table - // model only sends out changes that are made through the model, not for - // changes made directly to its backing HostContentSettings object (that - // happens e.g. if the user uses the cookie confirmation dialog). Hence, - // observe the CONTENT_SETTINGS_CHANGED notification directly. - registrar_.Add(this, NotificationType::CONTENT_SETTINGS_CHANGED, - NotificationService::AllSources()); - } - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - private: - NotificationRegistrar registrar_; - ContentExceptionsWindowController* controller_; -}; - -void UpdatingContentSettingsObserver::Observe( - NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - [controller_ modelDidChange]; -} - -//////////////////////////////////////////////////////////////////////////////// -// Static functions - -namespace { - -NSString* GetWindowTitle(ContentSettingsType settingsType) { - switch (settingsType) { - case CONTENT_SETTINGS_TYPE_COOKIES: - return l10n_util::GetNSStringWithFixup(IDS_COOKIE_EXCEPTION_TITLE); - case CONTENT_SETTINGS_TYPE_IMAGES: - return l10n_util::GetNSStringWithFixup(IDS_IMAGES_EXCEPTION_TITLE); - case CONTENT_SETTINGS_TYPE_JAVASCRIPT: - return l10n_util::GetNSStringWithFixup(IDS_JS_EXCEPTION_TITLE); - case CONTENT_SETTINGS_TYPE_PLUGINS: - return l10n_util::GetNSStringWithFixup(IDS_PLUGINS_EXCEPTION_TITLE); - case CONTENT_SETTINGS_TYPE_POPUPS: - return l10n_util::GetNSStringWithFixup(IDS_POPUP_EXCEPTION_TITLE); - default: - NOTREACHED(); - } - return @""; -} - -const CGFloat kButtonBarHeight = 35.0; - -} // namespace - -//////////////////////////////////////////////////////////////////////////////// -// ContentExceptionsWindowController implementation - -static ContentExceptionsWindowController* - g_exceptionWindows[CONTENT_SETTINGS_NUM_TYPES] = { nil }; - -@implementation ContentExceptionsWindowController - -+ (id)controllerForType:(ContentSettingsType)settingsType - settingsMap:(HostContentSettingsMap*)settingsMap - otrSettingsMap:(HostContentSettingsMap*)otrSettingsMap { - if (!g_exceptionWindows[settingsType]) { - g_exceptionWindows[settingsType] = - [[ContentExceptionsWindowController alloc] - initWithType:settingsType - settingsMap:settingsMap - otrSettingsMap:otrSettingsMap]; - } - return g_exceptionWindows[settingsType]; -} - -- (id)initWithType:(ContentSettingsType)settingsType - settingsMap:(HostContentSettingsMap*)settingsMap - otrSettingsMap:(HostContentSettingsMap*)otrSettingsMap { - NSString* nibpath = - [base::mac::MainAppBundle() pathForResource:@"ContentExceptionsWindow" - ofType:@"nib"]; - if ((self = [super initWithWindowNibPath:nibpath owner:self])) { - settingsType_ = settingsType; - settingsMap_ = settingsMap; - otrSettingsMap_ = otrSettingsMap; - model_.reset(new ContentExceptionsTableModel( - settingsMap_, otrSettingsMap_, settingsType_)); - popup_model_.reset(new ContentSettingComboModel(settingsType_)); - otrAllowed_ = otrSettingsMap != NULL; - tableObserver_.reset(new UpdatingContentSettingsObserver(self)); - updatesEnabled_ = YES; - - // TODO(thakis): autoremember window rect. - // TODO(thakis): sorting support. - } - return self; -} - -- (void)awakeFromNib { - DCHECK([self window]); - DCHECK_EQ(self, [[self window] delegate]); - DCHECK(tableView_); - DCHECK_EQ(self, [tableView_ dataSource]); - DCHECK_EQ(self, [tableView_ delegate]); - - [[self window] setTitle:GetWindowTitle(settingsType_)]; - - CGFloat minWidth = [[addButton_ superview] bounds].size.width + - [[doneButton_ superview] bounds].size.width; - [self setMinWidth:minWidth]; - - [self adjustEditingButtons]; - - // Initialize menu for the data cell in the "action" column. - scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@"exceptionMenu"]); - for (int i = 0; i < popup_model_->GetItemCount(); ++i) { - NSString* title = - l10n_util::FixUpWindowsStyleLabel(popup_model_->GetItemAt(i)); - scoped_nsobject<NSMenuItem> allowItem( - [[NSMenuItem alloc] initWithTitle:title action:NULL keyEquivalent:@""]); - [allowItem.get() setTag:popup_model_->SettingForIndex(i)]; - [menu.get() addItem:allowItem.get()]; - } - NSCell* menuCell = - [[tableView_ tableColumnWithIdentifier:@"action"] dataCell]; - [menuCell setMenu:menu.get()]; - - NSCell* patternCell = - [[tableView_ tableColumnWithIdentifier:@"pattern"] dataCell]; - [patternCell setFormatter:[[[PatternFormatter alloc] init] autorelease]]; - - if (!otrAllowed_) { - [tableView_ - removeTableColumn:[tableView_ tableColumnWithIdentifier:@"otr"]]; - } -} - -- (void)setMinWidth:(CGFloat)minWidth { - NSWindow* window = [self window]; - [window setMinSize:NSMakeSize(minWidth, [window minSize].height)]; - if ([window frame].size.width < minWidth) { - NSRect frame = [window frame]; - frame.size.width = minWidth; - [window setFrame:frame display:NO]; - } -} - -- (void)windowWillClose:(NSNotification*)notification { - // Without this, some of the unit tests fail on 10.6: - [tableView_ setDataSource:nil]; - - g_exceptionWindows[settingsType_] = nil; - [self autorelease]; -} - -- (BOOL)editingNewException { - return newException_.get() != NULL; -} - -// Let esc cancel editing if the user is currently editing a pattern. Else, let -// esc close the window. -- (void)cancel:(id)sender { - if ([tableView_ currentEditor] != nil) { - [tableView_ abortEditing]; - [[self window] makeFirstResponder:tableView_]; // Re-gain focus. - - if ([tableView_ selectedRow] == model_->RowCount()) { - // Cancel addition of new row. - [self removeException:self]; - } - } else { - [self closeSheet:self]; - } -} - -- (void)keyDown:(NSEvent*)event { - NSString* chars = [event charactersIgnoringModifiers]; - if ([chars length] == 1) { - switch ([chars characterAtIndex:0]) { - case NSDeleteCharacter: - case NSDeleteFunctionKey: - // Delete deletes. - if ([[tableView_ selectedRowIndexes] count] > 0) - [self removeException:self]; - return; - case NSCarriageReturnCharacter: - case NSEnterCharacter: - // Return enters rename mode. - if ([[tableView_ selectedRowIndexes] count] == 1) { - [tableView_ editColumn:0 - row:[[tableView_ selectedRowIndexes] lastIndex] - withEvent:nil - select:YES]; - } - return; - } - } - [super keyDown:event]; -} - -- (void)attachSheetTo:(NSWindow*)window { - [NSApp beginSheet:[self window] - modalForWindow:window - modalDelegate:self - didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) - contextInfo:nil]; -} - -- (void)sheetDidEnd:(NSWindow*)sheet - returnCode:(NSInteger)returnCode - contextInfo:(void*)context { - [sheet close]; - [sheet orderOut:self]; -} - -- (IBAction)addException:(id)sender { - if (newException_.get()) { - // The invariant is that |newException_| is non-NULL exactly if the pattern - // of a new exception is currently being edited - so there's nothing to do - // in that case. - return; - } - newException_.reset(new HostContentSettingsMap::PatternSettingPair); - newException_->first = ContentSettingsPattern( - l10n_util::GetStringUTF8(IDS_EXCEPTIONS_SAMPLE_PATTERN)); - newException_->second = CONTENT_SETTING_BLOCK; - [tableView_ reloadData]; - - [self adjustEditingButtons]; - int index = model_->RowCount(); - NSIndexSet* selectedSet = [NSIndexSet indexSetWithIndex:index]; - [tableView_ selectRowIndexes:selectedSet byExtendingSelection:NO]; - [tableView_ editColumn:0 row:index withEvent:nil select:YES]; -} - -- (IBAction)removeException:(id)sender { - updatesEnabled_ = NO; - NSIndexSet* selection = [tableView_ selectedRowIndexes]; - [tableView_ deselectAll:self]; // Else we'll get a -setObjectValue: later. - DCHECK_GT([selection count], 0U); - NSUInteger index = [selection lastIndex]; - while (index != NSNotFound) { - if (index == static_cast<NSUInteger>(model_->RowCount())) - newException_.reset(); - else - model_->RemoveException(index); - index = [selection indexLessThanIndex:index]; - } - updatesEnabled_ = YES; - [self modelDidChange]; -} - -- (IBAction)removeAllExceptions:(id)sender { - updatesEnabled_ = NO; - [tableView_ deselectAll:self]; // Else we'll get a -setObjectValue: later. - newException_.reset(); - model_->RemoveAll(); - updatesEnabled_ = YES; - [self modelDidChange]; -} - -- (IBAction)closeSheet:(id)sender { - [NSApp endSheet:[self window]]; -} - -// Table View Data Source ----------------------------------------------------- - -- (NSInteger)numberOfRowsInTableView:(NSTableView*)table { - return model_->RowCount() + (newException_.get() ? 1 : 0); -} - -- (id)tableView:(NSTableView*)tv - objectValueForTableColumn:(NSTableColumn*)tableColumn - row:(NSInteger)row { - const HostContentSettingsMap::PatternSettingPair* entry; - int isOtr; - if (newException_.get() && row >= model_->RowCount()) { - entry = newException_.get(); - isOtr = 0; - } else { - entry = &model_->entry_at(row); - isOtr = model_->entry_is_off_the_record(row) ? 1 : 0; - } - - NSObject* result = nil; - NSString* identifier = [tableColumn identifier]; - if ([identifier isEqualToString:@"pattern"]) { - result = base::SysUTF8ToNSString(entry->first.AsString()); - } else if ([identifier isEqualToString:@"action"]) { - result = - [NSNumber numberWithInt:popup_model_->IndexForSetting(entry->second)]; - } else if ([identifier isEqualToString:@"otr"]) { - result = [NSNumber numberWithInt:isOtr]; - } else { - NOTREACHED(); - } - return result; -} - -// Updates exception at |row| to contain the data in |entry|. -- (void)updateRow:(NSInteger)row - withEntry:(const HostContentSettingsMap::PatternSettingPair&)entry - forOtr:(BOOL)isOtr { - // TODO(thakis): This apparently moves an edited row to the back of the list. - // It's what windows and linux do, but it's kinda sucky. Fix. - // http://crbug.com/36904 - updatesEnabled_ = NO; - if (row < model_->RowCount()) - model_->RemoveException(row); - model_->AddException(entry.first, entry.second, isOtr); - updatesEnabled_ = YES; - [self modelDidChange]; - - // For now, at least re-select the edited element. - int newIndex = model_->IndexOfExceptionByPattern(entry.first, isOtr); - DCHECK(newIndex != -1); - [tableView_ selectRowIndexes:[NSIndexSet indexSetWithIndex:newIndex] - byExtendingSelection:NO]; -} - -- (void) tableView:(NSTableView*)tv - setObjectValue:(id)object - forTableColumn:(NSTableColumn*)tableColumn - row:(NSInteger)row { - // -remove: and -removeAll: both call |tableView_|'s -deselectAll:, which - // calls this method if a cell is currently being edited. Do not commit edits - // of rows that are about to be deleted. - if (!updatesEnabled_) { - // If this method gets called, the pattern filed of the new exception can no - // longer be being edited. Reset |newException_| to keep the invariant true. - newException_.reset(); - return; - } - - // Get model object. - bool isNewRow = newException_.get() && row >= model_->RowCount(); - HostContentSettingsMap::PatternSettingPair originalEntry = - isNewRow ? *newException_ : model_->entry_at(row); - HostContentSettingsMap::PatternSettingPair entry = originalEntry; - bool isOtr = - isNewRow ? 0 : model_->entry_is_off_the_record(row); - bool wasOtr = isOtr; - - // Modify it. - NSString* identifier = [tableColumn identifier]; - if ([identifier isEqualToString:@"pattern"]) { - entry.first = ContentSettingsPattern(base::SysNSStringToUTF8(object)); - } - if ([identifier isEqualToString:@"action"]) { - int index = [object intValue]; - entry.second = popup_model_->SettingForIndex(index); - } - if ([identifier isEqualToString:@"otr"]) { - isOtr = [object intValue] != 0; - } - - // Commit modification, if any. - if (isNewRow) { - newException_.reset(); - if (![identifier isEqualToString:@"pattern"]) { - [tableView_ reloadData]; - [self adjustEditingButtons]; - return; // Commit new rows only when the pattern has been set. - } - int newIndex = model_->IndexOfExceptionByPattern(entry.first, false); - if (newIndex != -1) { - // The new pattern was already in the table. Focus existing row instead of - // overwriting it with a new one. - [tableView_ selectRowIndexes:[NSIndexSet indexSetWithIndex:newIndex] - byExtendingSelection:NO]; - [tableView_ reloadData]; - [self adjustEditingButtons]; - return; - } - } - if (entry != originalEntry || wasOtr != isOtr || isNewRow) - [self updateRow:row withEntry:entry forOtr:isOtr]; -} - - -// Table View Delegate -------------------------------------------------------- - -// When the selection in the table view changes, we need to adjust buttons. -- (void)tableViewSelectionDidChange:(NSNotification*)notification { - [self adjustEditingButtons]; -} - -// Private -------------------------------------------------------------------- - -// This method appropriately sets the enabled states on the table's editing -// buttons. -- (void)adjustEditingButtons { - NSIndexSet* selection = [tableView_ selectedRowIndexes]; - [removeButton_ setEnabled:([selection count] > 0)]; - [removeAllButton_ setEnabled:([tableView_ numberOfRows] > 0)]; -} - -- (void)modelDidChange { - // Some calls on |model_|, e.g. RemoveException(), change something on the - // backing content settings map object (which sends a notification) and then - // change more stuff in |model_|. If |model_| is deleted when the notification - // is sent, this second access causes a segmentation violation. Hence, disable - // resetting |model_| while updates can be in progress. - if (!updatesEnabled_) - return; - - // The model caches its data, meaning we need to recreate it on every change. - model_.reset(new ContentExceptionsTableModel( - settingsMap_, otrSettingsMap_, settingsType_)); - - [tableView_ reloadData]; - [self adjustEditingButtons]; -} - -@end diff --git a/chrome/browser/ui/cocoa/options/content_exceptions_window_controller_unittest.mm b/chrome/browser/ui/cocoa/options/content_exceptions_window_controller_unittest.mm deleted file mode 100644 index 3118101..0000000 --- a/chrome/browser/ui/cocoa/options/content_exceptions_window_controller_unittest.mm +++ /dev/null @@ -1,252 +0,0 @@ -// Copyright (c) 2010 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/ui/cocoa/options/content_exceptions_window_controller.h" - -#import <Cocoa/Cocoa.h> - -#import "base/scoped_nsobject.h" -#include "base/ref_counted.h" -#include "chrome/browser/ui/cocoa/browser_test_helper.h" -#include "chrome/browser/ui/cocoa/cocoa_test_helper.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -namespace { - -void ProcessEvents() { - for (;;) { - base::mac::ScopedNSAutoreleasePool pool; - NSEvent* next_event = [NSApp nextEventMatchingMask:NSAnyEventMask - untilDate:nil - inMode:NSDefaultRunLoopMode - dequeue:YES]; - if (!next_event) - break; - [NSApp sendEvent:next_event]; - } -} - -void SendKeyEvents(NSString* characters) { - for (NSUInteger i = 0; i < [characters length]; ++i) { - unichar character = [characters characterAtIndex:i]; - NSString* charString = [NSString stringWithCharacters:&character length:1]; - NSEvent* event = [NSEvent keyEventWithType:NSKeyDown - location:NSZeroPoint - modifierFlags:0 - timestamp:0.0 - windowNumber:0 - context:nil - characters:charString - charactersIgnoringModifiers:charString - isARepeat:NO - keyCode:0]; - [NSApp sendEvent:event]; - } -} - -class ContentExceptionsWindowControllerTest : public CocoaTest { - public: - virtual void SetUp() { - CocoaTest::SetUp(); - TestingProfile* profile = browser_helper_.profile(); - settingsMap_ = new HostContentSettingsMap(profile); - } - - ContentExceptionsWindowController* GetController(ContentSettingsType type) { - id controller = [ContentExceptionsWindowController - controllerForType:type - settingsMap:settingsMap_.get() - otrSettingsMap:NULL]; - [controller showWindow:nil]; - return controller; - } - - void ClickAdd(ContentExceptionsWindowController* controller) { - [controller addException:nil]; - ProcessEvents(); - } - - void ClickRemove(ContentExceptionsWindowController* controller) { - [controller removeException:nil]; - ProcessEvents(); - } - - void ClickRemoveAll(ContentExceptionsWindowController* controller) { - [controller removeAllExceptions:nil]; - ProcessEvents(); - } - - void EnterText(NSString* str) { - SendKeyEvents(str); - ProcessEvents(); - } - - void HitEscape(ContentExceptionsWindowController* controller) { - [controller cancel:nil]; - ProcessEvents(); - } - - protected: - BrowserTestHelper browser_helper_; - scoped_refptr<HostContentSettingsMap> settingsMap_; -}; - -TEST_F(ContentExceptionsWindowControllerTest, Construction) { - ContentExceptionsWindowController* controller = - [ContentExceptionsWindowController - controllerForType:CONTENT_SETTINGS_TYPE_PLUGINS - settingsMap:settingsMap_.get() - otrSettingsMap:NULL]; - [controller showWindow:nil]; - [controller close]; // Should autorelease. -} - -// Regression test for http://crbug.com/37137 -TEST_F(ContentExceptionsWindowControllerTest, AddRemove) { - ContentExceptionsWindowController* controller = - GetController(CONTENT_SETTINGS_TYPE_PLUGINS); - - HostContentSettingsMap::SettingsForOneType settings; - - ClickAdd(controller); - settingsMap_->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PLUGINS, - "", - &settings); - EXPECT_EQ(0u, settings.size()); - - ClickRemove(controller); - - EXPECT_FALSE([controller editingNewException]); - [controller close]; - - settingsMap_->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PLUGINS, - "", - &settings); - EXPECT_EQ(0u, settings.size()); -} - -// Regression test for http://crbug.com/37137 -TEST_F(ContentExceptionsWindowControllerTest, AddRemoveAll) { - ContentExceptionsWindowController* controller = - GetController(CONTENT_SETTINGS_TYPE_PLUGINS); - - ClickAdd(controller); - ClickRemoveAll(controller); - - EXPECT_FALSE([controller editingNewException]); - [controller close]; - - HostContentSettingsMap::SettingsForOneType settings; - settingsMap_->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PLUGINS, - "", - &settings); - EXPECT_EQ(0u, settings.size()); -} - -TEST_F(ContentExceptionsWindowControllerTest, Add) { - ContentExceptionsWindowController* controller = - GetController(CONTENT_SETTINGS_TYPE_PLUGINS); - - ClickAdd(controller); - EnterText(@"addedhost\n"); - - EXPECT_FALSE([controller editingNewException]); - [controller close]; - - HostContentSettingsMap::SettingsForOneType settings; - settingsMap_->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PLUGINS, - "", - &settings); - EXPECT_EQ(1u, settings.size()); - EXPECT_EQ(ContentSettingsPattern("addedhost"), settings[0].first); -} - -TEST_F(ContentExceptionsWindowControllerTest, AddEscDoesNotAdd) { - ContentExceptionsWindowController* controller = - GetController(CONTENT_SETTINGS_TYPE_PLUGINS); - - ClickAdd(controller); - EnterText(@"addedhost"); // but do not press enter - HitEscape(controller); - - HostContentSettingsMap::SettingsForOneType settings; - settingsMap_->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PLUGINS, - "", - &settings); - EXPECT_EQ(0u, settings.size()); - EXPECT_FALSE([controller editingNewException]); - - [controller close]; -} - -// Regression test for http://crbug.com/37208 -TEST_F(ContentExceptionsWindowControllerTest, AddEditAddAdd) { - ContentExceptionsWindowController* controller = - GetController(CONTENT_SETTINGS_TYPE_PLUGINS); - - ClickAdd(controller); - EnterText(@"testtesttest"); // but do not press enter - ClickAdd(controller); - ClickAdd(controller); - - EXPECT_TRUE([controller editingNewException]); - [controller close]; - - HostContentSettingsMap::SettingsForOneType settings; - settingsMap_->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PLUGINS, - "", - &settings); - EXPECT_EQ(0u, settings.size()); -} - -TEST_F(ContentExceptionsWindowControllerTest, AddExistingEditAdd) { - settingsMap_->SetContentSetting(ContentSettingsPattern("myhost"), - CONTENT_SETTINGS_TYPE_PLUGINS, - "", - CONTENT_SETTING_BLOCK); - - ContentExceptionsWindowController* controller = - GetController(CONTENT_SETTINGS_TYPE_PLUGINS); - - ClickAdd(controller); - EnterText(@"myhost"); // but do not press enter - ClickAdd(controller); - - EXPECT_TRUE([controller editingNewException]); - [controller close]; - - - HostContentSettingsMap::SettingsForOneType settings; - settingsMap_->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PLUGINS, - "", - &settings); - EXPECT_EQ(1u, settings.size()); -} - -TEST_F(ContentExceptionsWindowControllerTest, AddExistingDoesNotOverwrite) { - settingsMap_->SetContentSetting(ContentSettingsPattern("myhost"), - CONTENT_SETTINGS_TYPE_COOKIES, - "", - CONTENT_SETTING_SESSION_ONLY); - - ContentExceptionsWindowController* controller = - GetController(CONTENT_SETTINGS_TYPE_COOKIES); - - ClickAdd(controller); - EnterText(@"myhost\n"); - - EXPECT_FALSE([controller editingNewException]); - [controller close]; - - HostContentSettingsMap::SettingsForOneType settings; - settingsMap_->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_COOKIES, - "", - &settings); - EXPECT_EQ(1u, settings.size()); - EXPECT_EQ(CONTENT_SETTING_SESSION_ONLY, settings[0].second); -} - - -} // namespace diff --git a/chrome/browser/ui/cocoa/options/content_settings_dialog_controller.h b/chrome/browser/ui/cocoa/options/content_settings_dialog_controller.h deleted file mode 100644 index a785bd8..0000000 --- a/chrome/browser/ui/cocoa/options/content_settings_dialog_controller.h +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) 2010 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> - -#import "base/mac/cocoa_protocols.h" -#include "base/scoped_ptr.h" -#include "chrome/common/content_settings_types.h" -#include "chrome/browser/prefs/pref_change_registrar.h" -#include "chrome/browser/prefs/pref_member.h" - -// Index of the "enabled" and "disabled" radio group settings in all tabs except -// the ones below. -const NSInteger kContentSettingsEnabledIndex = 0; -const NSInteger kContentSettingsDisabledIndex = 1; - -// Indices of the various cookie settings in the cookie radio group. -const NSInteger kCookieEnabledIndex = 0; -const NSInteger kCookieDisabledIndex = 1; - -// Indices of the various plugin settings in the plugins radio group. -const NSInteger kPluginsAllowIndex = 0; -const NSInteger kPluginsAskIndex = 1; -const NSInteger kPluginsBlockIndex = 2; - -// Indices of the various geolocation settings in the geolocation radio group. -const NSInteger kGeolocationEnabledIndex = 0; -const NSInteger kGeolocationAskIndex = 1; -const NSInteger kGeolocationDisabledIndex = 2; - -// Indices of the various notifications settings in the geolocation radio group. -const NSInteger kNotificationsEnabledIndex = 0; -const NSInteger kNotificationsAskIndex = 1; -const NSInteger kNotificationsDisabledIndex = 2; - -namespace ContentSettingsDialogControllerInternal { -class PrefObserverBridge; -} - -class Profile; -@class TabViewPickerTable; - -// This controller manages a dialog that lets the user manage the content -// settings for several content setting types. -@interface ContentSettingsDialogController - : NSWindowController<NSWindowDelegate, NSTabViewDelegate> { - @private - IBOutlet NSTabView* tabView_; - IBOutlet TabViewPickerTable* tabViewPicker_; - IBOutlet NSMatrix* pluginDefaultSettingMatrix_; - Profile* profile_; // weak - IntegerPrefMember lastSelectedTab_; - BooleanPrefMember clearSiteDataOnExit_; - PrefChangeRegistrar registrar_; - scoped_ptr<ContentSettingsDialogControllerInternal::PrefObserverBridge> - observer_; // Watches for pref changes. -} - -// Show the content settings dialog associated with the given profile (or the -// original profile if this is an incognito profile). If no content settings -// dialog exists for this profile, create one and show it. Any resulting -// editor releases itself when closed. -+(id)showContentSettingsForType:(ContentSettingsType)settingsType - profile:(Profile*)profile; - -// Closes an exceptions sheet, if one is attached. -- (void)closeExceptionsSheet; - -- (IBAction)showCookies:(id)sender; -- (IBAction)openFlashPlayerSettings:(id)sender; -- (IBAction)openPluginsPage:(id)sender; - -- (IBAction)showCookieExceptions:(id)sender; -- (IBAction)showImagesExceptions:(id)sender; -- (IBAction)showJavaScriptExceptions:(id)sender; -- (IBAction)showPluginsExceptions:(id)sender; -- (IBAction)showPopupsExceptions:(id)sender; -- (IBAction)showGeolocationExceptions:(id)sender; -- (IBAction)showNotificationsExceptions:(id)sender; - -@end - -@interface ContentSettingsDialogController (TestingAPI) -// Properties that the radio groups and checkboxes are bound to. -@property(nonatomic) NSInteger cookieSettingIndex; -@property(nonatomic) BOOL blockThirdPartyCookies; -@property(nonatomic) BOOL clearSiteDataOnExit; -@property(nonatomic) NSInteger imagesEnabledIndex; -@property(nonatomic) NSInteger javaScriptEnabledIndex; -@property(nonatomic) NSInteger popupsEnabledIndex; -@property(nonatomic) NSInteger pluginsEnabledIndex; -@property(nonatomic) NSInteger geolocationSettingIndex; -@property(nonatomic) NSInteger notificationsSettingIndex; - -@property(nonatomic, readonly) BOOL blockThirdPartyCookiesManaged; -@property(nonatomic, readonly) BOOL clearSiteDataOnExitManaged; -@property(nonatomic, readonly) BOOL cookieSettingsManaged; -@property(nonatomic, readonly) BOOL imagesSettingsManaged; -@property(nonatomic, readonly) BOOL javaScriptSettingsManaged; -@property(nonatomic, readonly) BOOL pluginsSettingsManaged; -@property(nonatomic, readonly) BOOL popupsSettingsManaged; -@end diff --git a/chrome/browser/ui/cocoa/options/content_settings_dialog_controller.mm b/chrome/browser/ui/cocoa/options/content_settings_dialog_controller.mm deleted file mode 100644 index 7c8fe9e..0000000 --- a/chrome/browser/ui/cocoa/options/content_settings_dialog_controller.mm +++ /dev/null @@ -1,652 +0,0 @@ -// Copyright (c) 2010 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/ui/cocoa/options/content_settings_dialog_controller.h" - -#import <Cocoa/Cocoa.h> - -#include "base/command_line.h" -#include "base/mac/mac_util.h" -#import "chrome/browser/content_settings/content_settings_details.h" -#import "chrome/browser/content_settings/host_content_settings_map.h" -#import "chrome/browser/geolocation/geolocation_content_settings_map.h" -#import "chrome/browser/geolocation/geolocation_exceptions_table_model.h" -#import "chrome/browser/notifications/desktop_notification_service.h" -#import "chrome/browser/notifications/notification_exceptions_table_model.h" -#include "chrome/browser/plugin_exceptions_table_model.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_window.h" -#import "chrome/browser/ui/cocoa/l10n_util.h" -#import "chrome/browser/ui/cocoa/content_settings/simple_content_exceptions_window_controller.h" -#import "chrome/browser/ui/cocoa/options/content_exceptions_window_controller.h" -#import "chrome/browser/ui/cocoa/options/cookies_window_controller.h" -#import "chrome/browser/ui/cocoa/tab_view_picker_table.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/url_constants.h" -#include "grit/locale_settings.h" -#include "grit/generated_resources.h" -#include "ui/base/l10n/l10n_util.h" - -namespace { - -// Stores the currently visible content settings dialog, if any. -ContentSettingsDialogController* g_instance = nil; - -} // namespace - - -@interface ContentSettingsDialogController(Private) -- (id)initWithProfile:(Profile*)profile; -- (void)selectTab:(ContentSettingsType)settingsType; -- (void)showExceptionsForType:(ContentSettingsType)settingsType; - -// Callback when preferences are changed. |prefName| is the name of the -// pref that has changed. -- (void)prefChanged:(const std::string&)prefName; - -// Callback when content settings are changed. -- (void)contentSettingsChanged:(ContentSettingsDetails*)details; - -@end - -namespace ContentSettingsDialogControllerInternal { - -// A C++ class registered for changes in preferences. -class PrefObserverBridge : public NotificationObserver { - public: - PrefObserverBridge(ContentSettingsDialogController* controller) - : controller_(controller), disabled_(false) {} - - virtual ~PrefObserverBridge() {} - - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - if (disabled_) - return; - - // This is currently used by most notifications. - if (type == NotificationType::PREF_CHANGED) { - std::string* detail = Details<std::string>(details).ptr(); - if (detail) - [controller_ prefChanged:*detail]; - } - - // This is sent when the "is managed" state changes. - // TODO(markusheintz): Move all content settings to this notification. - if (type == NotificationType::CONTENT_SETTINGS_CHANGED) { - ContentSettingsDetails* settings_details = - Details<ContentSettingsDetails>(details).ptr(); - [controller_ contentSettingsChanged:settings_details]; - } - } - - void SetDisabled(bool disabled) { - disabled_ = disabled; - } - - private: - ContentSettingsDialogController* controller_; // weak, owns us - bool disabled_; // true if notifications should be ignored. -}; - -// A C++ utility class to disable notifications for PrefsObserverBridge. -// The intended usage is to create this on the stack. -class PrefObserverDisabler { - public: - PrefObserverDisabler(PrefObserverBridge *bridge) : bridge_(bridge) { - bridge_->SetDisabled(true); - } - - ~PrefObserverDisabler() { - bridge_->SetDisabled(false); - } - - private: - PrefObserverBridge *bridge_; -}; - -} // ContentSettingsDialogControllerInternal - -@implementation ContentSettingsDialogController - -+ (id)showContentSettingsForType:(ContentSettingsType)settingsType - profile:(Profile*)profile { - profile = profile->GetOriginalProfile(); - if (!g_instance) - g_instance = [[self alloc] initWithProfile:profile]; - - // The code doesn't expect multiple profiles. Check that support for that - // hasn't been added. - DCHECK(g_instance->profile_ == profile); - - // Select desired tab. - if (settingsType == CONTENT_SETTINGS_TYPE_DEFAULT) { - // Remember the last visited page from local state. - int value = g_instance->lastSelectedTab_.GetValue(); - if (value >= 0 && value < CONTENT_SETTINGS_NUM_TYPES) - settingsType = static_cast<ContentSettingsType>(value); - if (settingsType == CONTENT_SETTINGS_TYPE_DEFAULT) - settingsType = CONTENT_SETTINGS_TYPE_COOKIES; - } - // TODO(thakis): Autosave window pos. - - [g_instance selectTab:settingsType]; - [g_instance showWindow:nil]; - [g_instance closeExceptionsSheet]; - return g_instance; -} - -- (id)initWithProfile:(Profile*)profile { - DCHECK(profile); - NSString* nibpath = - [base::mac::MainAppBundle() pathForResource:@"ContentSettings" - ofType:@"nib"]; - if ((self = [super initWithWindowNibPath:nibpath owner:self])) { - profile_ = profile; - - observer_.reset( - new ContentSettingsDialogControllerInternal::PrefObserverBridge(self)); - clearSiteDataOnExit_.Init(prefs::kClearSiteDataOnExit, - profile_->GetPrefs(), observer_.get()); - - // Manually observe notifications for preferences that are grouped in - // the HostContentSettingsMap or GeolocationContentSettingsMap. - PrefService* prefs = profile_->GetPrefs(); - registrar_.Init(prefs); - registrar_.Add(prefs::kBlockThirdPartyCookies, observer_.get()); - registrar_.Add(prefs::kBlockNonsandboxedPlugins, observer_.get()); - registrar_.Add(prefs::kDefaultContentSettings, observer_.get()); - registrar_.Add(prefs::kGeolocationDefaultContentSetting, observer_.get()); - - // We don't need to observe changes in this value. - lastSelectedTab_.Init(prefs::kContentSettingsWindowLastTabIndex, - profile_->GetPrefs(), NULL); - } - return self; -} - -- (void)closeExceptionsSheet { - NSWindow* attachedSheet = [[self window] attachedSheet]; - if (attachedSheet) { - [NSApp endSheet:attachedSheet]; - } -} - -- (void)awakeFromNib { - DCHECK([self window]); - DCHECK(tabView_); - DCHECK(tabViewPicker_); - DCHECK_EQ(self, [[self window] delegate]); - - // Adapt views to potentially long localized strings. - CGFloat windowDelta = 0; - for (NSTabViewItem* tab in [tabView_ tabViewItems]) { - NSArray* subviews = [[tab view] subviews]; - windowDelta = MAX(windowDelta, - cocoa_l10n_util::VerticallyReflowGroup(subviews)); - - for (NSView* view in subviews) { - // Since the tab pane is in a horizontal resizer in IB, it's convenient - // to give all the subviews flexible width so that their sizes are - // autoupdated in IB. However, in chrome, the subviews shouldn't have - // flexible widths as this looks weird. - [view setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin]; - } - } - - NSString* label = - l10n_util::GetNSStringWithFixup(IDS_CONTENT_SETTINGS_FEATURES_LABEL); - label = [label stringByReplacingOccurrencesOfString:@":" withString:@""]; - [tabViewPicker_ setHeading:label]; - - if (!CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableClickToPlay)) { - // The |pluginsEnabledIndex| property is bound to the selected *tag*, - // so we don't have to worry about index shifts when removing a row - // from the matrix. - [pluginDefaultSettingMatrix_ removeRow:kPluginsAskIndex]; - NSArray* siblingViews = [[pluginDefaultSettingMatrix_ superview] subviews]; - for (NSView* view in siblingViews) { - NSRect frame = [view frame]; - if (frame.origin.y < [pluginDefaultSettingMatrix_ frame].origin.y) { - frame.origin.y += - ([pluginDefaultSettingMatrix_ cellSize].height + - [pluginDefaultSettingMatrix_ intercellSpacing].height); - [view setFrame:frame]; - } - } - } - - NSRect frame = [[self window] frame]; - frame.origin.y -= windowDelta; - frame.size.height += windowDelta; - [[self window] setFrame:frame display:NO]; -} - -// NSWindowDelegate method. -- (void)windowWillClose:(NSNotification*)notification { - [self autorelease]; - g_instance = nil; -} - -- (void)selectTab:(ContentSettingsType)settingsType { - [self window]; // Make sure the nib file is loaded. - DCHECK(tabView_); - [tabView_ selectTabViewItemAtIndex:settingsType]; -} - -// NSTabViewDelegate method. -- (void) tabView:(NSTabView*)tabView - didSelectTabViewItem:(NSTabViewItem*)tabViewItem { - DCHECK_EQ(tabView_, tabView); - NSInteger index = [tabView indexOfTabViewItem:tabViewItem]; - DCHECK_GT(index, CONTENT_SETTINGS_TYPE_DEFAULT); - DCHECK_LT(index, CONTENT_SETTINGS_NUM_TYPES); - if (index > CONTENT_SETTINGS_TYPE_DEFAULT && - index < CONTENT_SETTINGS_NUM_TYPES) - lastSelectedTab_.SetValue(index); -} - -// Let esc close the window. -- (void)cancel:(id)sender { - [self close]; -} - -- (void)setCookieSettingIndex:(NSInteger)value { - ContentSetting setting = CONTENT_SETTING_DEFAULT; - switch (value) { - case kCookieEnabledIndex: setting = CONTENT_SETTING_ALLOW; break; - case kCookieDisabledIndex: setting = CONTENT_SETTING_BLOCK; break; - default: - NOTREACHED(); - } - ContentSettingsDialogControllerInternal::PrefObserverDisabler - disabler(observer_.get()); - profile_->GetHostContentSettingsMap()->SetDefaultContentSetting( - CONTENT_SETTINGS_TYPE_COOKIES, - setting); -} - -- (NSInteger)cookieSettingIndex { - switch (profile_->GetHostContentSettingsMap()->GetDefaultContentSetting( - CONTENT_SETTINGS_TYPE_COOKIES)) { - case CONTENT_SETTING_ALLOW: return kCookieEnabledIndex; - case CONTENT_SETTING_BLOCK: return kCookieDisabledIndex; - default: - NOTREACHED(); - return kCookieEnabledIndex; - } -} - -- (BOOL)cookieSettingsManaged { - return profile_->GetHostContentSettingsMap()->IsDefaultContentSettingManaged( - CONTENT_SETTINGS_TYPE_COOKIES); -} - -- (BOOL)blockThirdPartyCookies { - HostContentSettingsMap* settingsMap = profile_->GetHostContentSettingsMap(); - return settingsMap->BlockThirdPartyCookies(); -} - -- (void)setBlockThirdPartyCookies:(BOOL)value { - HostContentSettingsMap* settingsMap = profile_->GetHostContentSettingsMap(); - ContentSettingsDialogControllerInternal::PrefObserverDisabler - disabler(observer_.get()); - settingsMap->SetBlockThirdPartyCookies(value); -} - -- (BOOL)blockThirdPartyCookiesManaged { - HostContentSettingsMap* settingsMap = profile_->GetHostContentSettingsMap(); - return settingsMap->IsBlockThirdPartyCookiesManaged(); -} - -- (BOOL)clearSiteDataOnExitManaged { - return clearSiteDataOnExit_.IsManaged(); -} - -- (BOOL)clearSiteDataOnExit { - return clearSiteDataOnExit_.GetValue(); -} - -- (void)setClearSiteDataOnExit:(BOOL)value { - ContentSettingsDialogControllerInternal::PrefObserverDisabler - disabler(observer_.get()); - clearSiteDataOnExit_.SetValue(value); -} - -// Shows the cookies controller. -- (IBAction)showCookies:(id)sender { - // The cookie controller will autorelease itself when it's closed. - BrowsingDataDatabaseHelper* databaseHelper = - new BrowsingDataDatabaseHelper(profile_); - BrowsingDataLocalStorageHelper* storageHelper = - new BrowsingDataLocalStorageHelper(profile_); - BrowsingDataAppCacheHelper* appcacheHelper = - new BrowsingDataAppCacheHelper(profile_); - BrowsingDataIndexedDBHelper* indexedDBHelper = - BrowsingDataIndexedDBHelper::Create(profile_); - CookiesWindowController* controller = - [[CookiesWindowController alloc] initWithProfile:profile_ - databaseHelper:databaseHelper - storageHelper:storageHelper - appcacheHelper:appcacheHelper - indexedDBHelper:indexedDBHelper]; - [controller attachSheetTo:[self window]]; -} - -// Called when the user clicks the "Flash Player storage settings" button. -- (IBAction)openFlashPlayerSettings:(id)sender { - Browser* browser = Browser::Create(profile_); - browser->OpenURL(GURL(l10n_util::GetStringUTF8(IDS_FLASH_STORAGE_URL)), - GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK); - browser->window()->Show(); -} - -// Called when the user clicks the "Disable individual plug-ins..." button. -- (IBAction)openPluginsPage:(id)sender { - Browser* browser = Browser::Create(profile_); - browser->OpenURL(GURL(chrome::kChromeUIPluginsURL), - GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK); - browser->window()->Show(); -} - -- (IBAction)showCookieExceptions:(id)sender { - [self showExceptionsForType:CONTENT_SETTINGS_TYPE_COOKIES]; -} - -- (IBAction)showImagesExceptions:(id)sender { - [self showExceptionsForType:CONTENT_SETTINGS_TYPE_IMAGES]; -} - -- (IBAction)showJavaScriptExceptions:(id)sender { - [self showExceptionsForType:CONTENT_SETTINGS_TYPE_JAVASCRIPT]; -} - -- (IBAction)showPluginsExceptions:(id)sender { - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableResourceContentSettings)) { - HostContentSettingsMap* settingsMap = profile_->GetHostContentSettingsMap(); - HostContentSettingsMap* offTheRecordSettingsMap = - profile_->HasOffTheRecordProfile() ? - profile_->GetOffTheRecordProfile()->GetHostContentSettingsMap() : - NULL; - PluginExceptionsTableModel* model = - new PluginExceptionsTableModel(settingsMap, offTheRecordSettingsMap); - model->LoadSettings(); - [[SimpleContentExceptionsWindowController controllerWithTableModel:model] - attachSheetTo:[self window]]; - } else { - [self showExceptionsForType:CONTENT_SETTINGS_TYPE_PLUGINS]; - } -} - -- (IBAction)showPopupsExceptions:(id)sender { - [self showExceptionsForType:CONTENT_SETTINGS_TYPE_POPUPS]; -} - -- (IBAction)showGeolocationExceptions:(id)sender { - GeolocationContentSettingsMap* settingsMap = - profile_->GetGeolocationContentSettingsMap(); - GeolocationExceptionsTableModel* model = // Freed by window controller. - new GeolocationExceptionsTableModel(settingsMap); - [[SimpleContentExceptionsWindowController controllerWithTableModel:model] - attachSheetTo:[self window]]; -} - -- (IBAction)showNotificationsExceptions:(id)sender { - DesktopNotificationService* service = - profile_->GetDesktopNotificationService(); - NotificationExceptionsTableModel* model = // Freed by window controller. - new NotificationExceptionsTableModel(service); - [[SimpleContentExceptionsWindowController controllerWithTableModel:model] - attachSheetTo:[self window]]; -} - -- (void)showExceptionsForType:(ContentSettingsType)settingsType { - HostContentSettingsMap* settingsMap = profile_->GetHostContentSettingsMap(); - HostContentSettingsMap* offTheRecordSettingsMap = - profile_->HasOffTheRecordProfile() ? - profile_->GetOffTheRecordProfile()->GetHostContentSettingsMap() : - NULL; - [[ContentExceptionsWindowController controllerForType:settingsType - settingsMap:settingsMap - otrSettingsMap:offTheRecordSettingsMap] - attachSheetTo:[self window]]; -} - -- (void)setImagesEnabledIndex:(NSInteger)value { - ContentSetting setting = value == kContentSettingsEnabledIndex ? - CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; - ContentSettingsDialogControllerInternal::PrefObserverDisabler - disabler(observer_.get()); - profile_->GetHostContentSettingsMap()->SetDefaultContentSetting( - CONTENT_SETTINGS_TYPE_IMAGES, setting); -} - -- (NSInteger)imagesEnabledIndex { - HostContentSettingsMap* settingsMap = profile_->GetHostContentSettingsMap(); - bool enabled = - settingsMap->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_IMAGES) == - CONTENT_SETTING_ALLOW; - return enabled ? kContentSettingsEnabledIndex : kContentSettingsDisabledIndex; -} - -- (BOOL)imagesSettingsManaged { - return profile_->GetHostContentSettingsMap()->IsDefaultContentSettingManaged( - CONTENT_SETTINGS_TYPE_IMAGES); -} - -- (void)setJavaScriptEnabledIndex:(NSInteger)value { - ContentSetting setting = value == kContentSettingsEnabledIndex ? - CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; - ContentSettingsDialogControllerInternal::PrefObserverDisabler - disabler(observer_.get()); - profile_->GetHostContentSettingsMap()->SetDefaultContentSetting( - CONTENT_SETTINGS_TYPE_JAVASCRIPT, setting); -} - -- (NSInteger)javaScriptEnabledIndex { - HostContentSettingsMap* settingsMap = profile_->GetHostContentSettingsMap(); - bool enabled = - settingsMap->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT) == - CONTENT_SETTING_ALLOW; - return enabled ? kContentSettingsEnabledIndex : kContentSettingsDisabledIndex; -} - -- (BOOL)javaScriptSettingsManaged { - return profile_->GetHostContentSettingsMap()->IsDefaultContentSettingManaged( - CONTENT_SETTINGS_TYPE_JAVASCRIPT); -} - -- (void)setPluginsEnabledIndex:(NSInteger)value { - ContentSetting setting = CONTENT_SETTING_DEFAULT; - switch (value) { - case kPluginsAllowIndex: - setting = CONTENT_SETTING_ALLOW; - break; - case kPluginsAskIndex: - setting = CONTENT_SETTING_ASK; - break; - case kPluginsBlockIndex: - setting = CONTENT_SETTING_BLOCK; - break; - default: - NOTREACHED(); - } - ContentSettingsDialogControllerInternal::PrefObserverDisabler - disabler(observer_.get()); - profile_->GetHostContentSettingsMap()->SetDefaultContentSetting( - CONTENT_SETTINGS_TYPE_PLUGINS, setting); -} - -- (NSInteger)pluginsEnabledIndex { - HostContentSettingsMap* map = profile_->GetHostContentSettingsMap(); - ContentSetting setting = - map->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS); - switch (setting) { - case CONTENT_SETTING_ALLOW: - return kPluginsAllowIndex; - case CONTENT_SETTING_ASK: - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableClickToPlay)) - return kPluginsAskIndex; - // Fall through to the next case. - case CONTENT_SETTING_BLOCK: - return kPluginsBlockIndex; - default: - NOTREACHED(); - return kPluginsAllowIndex; - } -} - -- (BOOL)pluginsSettingsManaged { - return profile_->GetHostContentSettingsMap()->IsDefaultContentSettingManaged( - CONTENT_SETTINGS_TYPE_PLUGINS); -} - -- (void)setPopupsEnabledIndex:(NSInteger)value { - ContentSetting setting = value == kContentSettingsEnabledIndex ? - CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; - ContentSettingsDialogControllerInternal::PrefObserverDisabler - disabler(observer_.get()); - profile_->GetHostContentSettingsMap()->SetDefaultContentSetting( - CONTENT_SETTINGS_TYPE_POPUPS, setting); -} - -- (NSInteger)popupsEnabledIndex { - HostContentSettingsMap* settingsMap = profile_->GetHostContentSettingsMap(); - bool enabled = - settingsMap->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_POPUPS) == - CONTENT_SETTING_ALLOW; - return enabled ? kContentSettingsEnabledIndex : kContentSettingsDisabledIndex; -} - -- (BOOL)popupsSettingsManaged { - return profile_->GetHostContentSettingsMap()->IsDefaultContentSettingManaged( - CONTENT_SETTINGS_TYPE_POPUPS); -} - -- (void)setGeolocationSettingIndex:(NSInteger)value { - ContentSetting setting = CONTENT_SETTING_DEFAULT; - switch (value) { - case kGeolocationEnabledIndex: setting = CONTENT_SETTING_ALLOW; break; - case kGeolocationAskIndex: setting = CONTENT_SETTING_ASK; break; - case kGeolocationDisabledIndex: setting = CONTENT_SETTING_BLOCK; break; - default: - NOTREACHED(); - } - ContentSettingsDialogControllerInternal::PrefObserverDisabler - disabler(observer_.get()); - profile_->GetGeolocationContentSettingsMap()->SetDefaultContentSetting( - setting); -} - -- (NSInteger)geolocationSettingIndex { - ContentSetting setting = - profile_->GetGeolocationContentSettingsMap()->GetDefaultContentSetting(); - switch (setting) { - case CONTENT_SETTING_ALLOW: return kGeolocationEnabledIndex; - case CONTENT_SETTING_ASK: return kGeolocationAskIndex; - case CONTENT_SETTING_BLOCK: return kGeolocationDisabledIndex; - default: - NOTREACHED(); - return kGeolocationAskIndex; - } -} - -- (void)setNotificationsSettingIndex:(NSInteger)value { - ContentSetting setting = CONTENT_SETTING_DEFAULT; - switch (value) { - case kNotificationsEnabledIndex: setting = CONTENT_SETTING_ALLOW; break; - case kNotificationsAskIndex: setting = CONTENT_SETTING_ASK; break; - case kNotificationsDisabledIndex: setting = CONTENT_SETTING_BLOCK; break; - default: - NOTREACHED(); - } - ContentSettingsDialogControllerInternal::PrefObserverDisabler - disabler(observer_.get()); - profile_->GetDesktopNotificationService()->SetDefaultContentSetting( - setting); -} - -- (NSInteger)notificationsSettingIndex { - ContentSetting setting = - profile_->GetDesktopNotificationService()->GetDefaultContentSetting(); - switch (setting) { - case CONTENT_SETTING_ALLOW: return kNotificationsEnabledIndex; - case CONTENT_SETTING_ASK: return kNotificationsAskIndex; - case CONTENT_SETTING_BLOCK: return kNotificationsDisabledIndex; - default: - NOTREACHED(); - return kGeolocationAskIndex; - } -} - -// Callback when preferences are changed. |prefName| is the name of the -// pref that has changed and should not be NULL. -- (void)prefChanged:(const std::string&)prefName { - if (prefName == prefs::kClearSiteDataOnExit) { - [self willChangeValueForKey:@"clearSiteDataOnExit"]; - [self didChangeValueForKey:@"clearSiteDataOnExit"]; - [self willChangeValueForKey:@"clearSiteDataOnExitManaged"]; - [self didChangeValueForKey:@"clearSiteDataOnExitManaged"]; - } - if (prefName == prefs::kBlockThirdPartyCookies) { - [self willChangeValueForKey:@"blockThirdPartyCookies"]; - [self didChangeValueForKey:@"blockThirdPartyCookies"]; - [self willChangeValueForKey:@"blockThirdPartyCookiesManaged"]; - [self didChangeValueForKey:@"blockThirdPartyCookiesManaged"]; - } - if (prefName == prefs::kBlockNonsandboxedPlugins) { - [self willChangeValueForKey:@"pluginsEnabledIndex"]; - [self didChangeValueForKey:@"pluginsEnabledIndex"]; - } - if (prefName == prefs::kDefaultContentSettings) { - // We don't know exactly which setting has changed, so we'll tickle all - // of the properties that apply to kDefaultContentSettings. This will - // keep the UI up-to-date. - [self willChangeValueForKey:@"cookieSettingIndex"]; - [self didChangeValueForKey:@"cookieSettingIndex"]; - [self willChangeValueForKey:@"imagesEnabledIndex"]; - [self didChangeValueForKey:@"imagesEnabledIndex"]; - [self willChangeValueForKey:@"javaScriptEnabledIndex"]; - [self didChangeValueForKey:@"javaScriptEnabledIndex"]; - [self willChangeValueForKey:@"pluginsEnabledIndex"]; - [self didChangeValueForKey:@"pluginsEnabledIndex"]; - [self willChangeValueForKey:@"popupsEnabledIndex"]; - [self didChangeValueForKey:@"popupsEnabledIndex"]; - - // Updates the "Enable" state of the radio groups and the exception buttons. - [self willChangeValueForKey:@"cookieSettingsManaged"]; - [self didChangeValueForKey:@"cookieSettingsManaged"]; - [self willChangeValueForKey:@"imagesSettingsManaged"]; - [self didChangeValueForKey:@"imagesSettingsManaged"]; - [self willChangeValueForKey:@"javaScriptSettingsManaged"]; - [self didChangeValueForKey:@"javaScriptSettingsManaged"]; - [self willChangeValueForKey:@"pluginsSettingsManaged"]; - [self didChangeValueForKey:@"pluginsSettingsManaged"]; - [self willChangeValueForKey:@"popupsSettingsManaged"]; - [self didChangeValueForKey:@"popupsSettingsManaged"]; - } - if (prefName == prefs::kGeolocationDefaultContentSetting) { - [self willChangeValueForKey:@"geolocationSettingIndex"]; - [self didChangeValueForKey:@"geolocationSettingIndex"]; - } - if (prefName == prefs::kDesktopNotificationDefaultContentSetting) { - [self willChangeValueForKey:@"notificationsSettingIndex"]; - [self didChangeValueForKey:@"notificationsSettingIndex"]; - } -} - -- (void)contentSettingsChanged:(ContentSettingsDetails*)details { - [self prefChanged:prefs::kBlockNonsandboxedPlugins]; - [self prefChanged:prefs::kDefaultContentSettings]; -} - -@end diff --git a/chrome/browser/ui/cocoa/options/content_settings_dialog_controller_unittest.mm b/chrome/browser/ui/cocoa/options/content_settings_dialog_controller_unittest.mm deleted file mode 100644 index fc29386..0000000 --- a/chrome/browser/ui/cocoa/options/content_settings_dialog_controller_unittest.mm +++ /dev/null @@ -1,289 +0,0 @@ -// Copyright (c) 2010 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/ui/cocoa/options/content_settings_dialog_controller.h" - -#include "base/auto_reset.h" -#include "base/command_line.h" -#import "base/scoped_nsobject.h" -#include "base/ref_counted.h" -#include "chrome/browser/content_settings/host_content_settings_map.h" -#include "chrome/browser/geolocation/geolocation_content_settings_map.h" -#include "chrome/browser/notifications/desktop_notification_service.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/ui/cocoa/browser_test_helper.h" -#include "chrome/browser/ui/cocoa/cocoa_test_helper.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/chrome_switches.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -namespace { - -class ContentSettingsDialogControllerTest : public CocoaTest { - public: - virtual void SetUp() { - CocoaTest::SetUp(); - TestingProfile* profile = browser_helper_.profile(); - settingsMap_ = new HostContentSettingsMap(profile); - geoSettingsMap_ = new GeolocationContentSettingsMap(profile); - notificationsService_.reset(new DesktopNotificationService(profile, NULL)); - controller_ = [ContentSettingsDialogController - showContentSettingsForType:CONTENT_SETTINGS_TYPE_DEFAULT - profile:browser_helper_.profile()]; - } - - virtual void TearDown() { - [controller_ close]; - CocoaTest::TearDown(); - } - - protected: - ContentSettingsDialogController* controller_; - BrowserTestHelper browser_helper_; - scoped_refptr<HostContentSettingsMap> settingsMap_; - scoped_refptr<GeolocationContentSettingsMap> geoSettingsMap_; - scoped_ptr<DesktopNotificationService> notificationsService_; -}; - -// Test that +showContentSettingsDialogForProfile brings up the existing editor -// and doesn't leak or crash. -TEST_F(ContentSettingsDialogControllerTest, CreateDialog) { - EXPECT_TRUE(controller_); -} - -TEST_F(ContentSettingsDialogControllerTest, CookieSetting) { - // Change setting, check dialog property. - settingsMap_->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES, - CONTENT_SETTING_ALLOW); - EXPECT_EQ([controller_ cookieSettingIndex], kCookieEnabledIndex); - - settingsMap_->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES, - CONTENT_SETTING_BLOCK); - EXPECT_EQ([controller_ cookieSettingIndex], kCookieDisabledIndex); - - // Change dialog property, check setting. - NSInteger setting; - [controller_ setCookieSettingIndex:kCookieEnabledIndex]; - setting = - settingsMap_->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES); - EXPECT_EQ(setting, CONTENT_SETTING_ALLOW); - - [controller_ setCookieSettingIndex:kCookieDisabledIndex]; - setting = - settingsMap_->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES); - EXPECT_EQ(setting, CONTENT_SETTING_BLOCK); -} - -TEST_F(ContentSettingsDialogControllerTest, BlockThirdPartyCookiesSetting) { - // Change setting, check dialog property. - settingsMap_->SetBlockThirdPartyCookies(YES); - EXPECT_TRUE([controller_ blockThirdPartyCookies]); - - settingsMap_->SetBlockThirdPartyCookies(NO); - EXPECT_FALSE([controller_ blockThirdPartyCookies]); - - // Change dialog property, check setting. - [controller_ setBlockThirdPartyCookies:YES]; - EXPECT_TRUE(settingsMap_->BlockThirdPartyCookies()); - - [controller_ setBlockThirdPartyCookies:NO]; - EXPECT_FALSE(settingsMap_->BlockThirdPartyCookies()); -} - -TEST_F(ContentSettingsDialogControllerTest, ClearSiteDataOnExitSetting) { - TestingProfile* profile = browser_helper_.profile(); - - // Change setting, check dialog property. - profile->GetPrefs()->SetBoolean(prefs::kClearSiteDataOnExit, true); - EXPECT_TRUE([controller_ clearSiteDataOnExit]); - - profile->GetPrefs()->SetBoolean(prefs::kClearSiteDataOnExit, false); - EXPECT_FALSE([controller_ clearSiteDataOnExit]); - - // Change dialog property, check setting. - [controller_ setClearSiteDataOnExit:YES]; - EXPECT_TRUE(profile->GetPrefs()->GetBoolean(prefs::kClearSiteDataOnExit)); - - [controller_ setClearSiteDataOnExit:NO]; - EXPECT_FALSE(profile->GetPrefs()->GetBoolean(prefs::kClearSiteDataOnExit)); -} - -TEST_F(ContentSettingsDialogControllerTest, ImagesSetting) { - // Change setting, check dialog property. - settingsMap_->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_IMAGES, - CONTENT_SETTING_ALLOW); - EXPECT_EQ([controller_ imagesEnabledIndex], kContentSettingsEnabledIndex); - - settingsMap_->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_IMAGES, - CONTENT_SETTING_BLOCK); - EXPECT_EQ([controller_ imagesEnabledIndex], kContentSettingsDisabledIndex); - - // Change dialog property, check setting. - NSInteger setting; - [controller_ setImagesEnabledIndex:kContentSettingsEnabledIndex]; - setting = - settingsMap_->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_IMAGES); - EXPECT_EQ(setting, CONTENT_SETTING_ALLOW); - - [controller_ setImagesEnabledIndex:kContentSettingsDisabledIndex]; - setting = - settingsMap_->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_IMAGES); - EXPECT_EQ(setting, CONTENT_SETTING_BLOCK); -} - -TEST_F(ContentSettingsDialogControllerTest, JavaScriptSetting) { - // Change setting, check dialog property. - settingsMap_->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT, - CONTENT_SETTING_ALLOW); - EXPECT_EQ([controller_ javaScriptEnabledIndex], kContentSettingsEnabledIndex); - - settingsMap_->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT, - CONTENT_SETTING_BLOCK); - EXPECT_EQ([controller_ javaScriptEnabledIndex], - kContentSettingsDisabledIndex); - - // Change dialog property, check setting. - NSInteger setting; - [controller_ setJavaScriptEnabledIndex:kContentSettingsEnabledIndex]; - setting = - settingsMap_->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT); - EXPECT_EQ(setting, CONTENT_SETTING_ALLOW); - - [controller_ setJavaScriptEnabledIndex:kContentSettingsDisabledIndex]; - setting = - settingsMap_->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT); - EXPECT_EQ(setting, CONTENT_SETTING_BLOCK); -} - -TEST_F(ContentSettingsDialogControllerTest, PluginsSetting) { - // Change setting, check dialog property. - settingsMap_->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS, - CONTENT_SETTING_ALLOW); - EXPECT_EQ(kPluginsAllowIndex, [controller_ pluginsEnabledIndex]); - - settingsMap_->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS, - CONTENT_SETTING_BLOCK); - EXPECT_EQ(kPluginsBlockIndex, [controller_ pluginsEnabledIndex]); - - { - // Click-to-play needs to be enabled to set the content setting to ASK. - CommandLine* cmd = CommandLine::ForCurrentProcess(); - AutoReset<CommandLine> auto_reset(cmd, *cmd); - cmd->AppendSwitch(switches::kEnableClickToPlay); - - settingsMap_->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS, - CONTENT_SETTING_ASK); - EXPECT_EQ(kPluginsAskIndex, [controller_ pluginsEnabledIndex]); - } - - // Change dialog property, check setting. - NSInteger setting; - [controller_ setPluginsEnabledIndex:kPluginsAllowIndex]; - setting = - settingsMap_->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS); - EXPECT_EQ(CONTENT_SETTING_ALLOW, setting); - - [controller_ setPluginsEnabledIndex:kPluginsBlockIndex]; - setting = - settingsMap_->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS); - EXPECT_EQ(CONTENT_SETTING_BLOCK, setting); - - { - CommandLine* cmd = CommandLine::ForCurrentProcess(); - AutoReset<CommandLine> auto_reset(cmd, *cmd); - cmd->AppendSwitch(switches::kEnableClickToPlay); - - [controller_ setPluginsEnabledIndex:kPluginsAskIndex]; - setting = - settingsMap_->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS); - EXPECT_EQ(CONTENT_SETTING_ASK, setting); - } -} - -TEST_F(ContentSettingsDialogControllerTest, PopupsSetting) { - // Change setting, check dialog property. - settingsMap_->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_POPUPS, - CONTENT_SETTING_ALLOW); - EXPECT_EQ([controller_ popupsEnabledIndex], kContentSettingsEnabledIndex); - - settingsMap_->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_POPUPS, - CONTENT_SETTING_BLOCK); - EXPECT_EQ([controller_ popupsEnabledIndex], kContentSettingsDisabledIndex); - - // Change dialog property, check setting. - NSInteger setting; - [controller_ setPopupsEnabledIndex:kContentSettingsEnabledIndex]; - setting = - settingsMap_->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_POPUPS); - EXPECT_EQ(setting, CONTENT_SETTING_ALLOW); - - [controller_ setPopupsEnabledIndex:kContentSettingsDisabledIndex]; - setting = - settingsMap_->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_POPUPS); - EXPECT_EQ(setting, CONTENT_SETTING_BLOCK); -} - -TEST_F(ContentSettingsDialogControllerTest, GeolocationSetting) { - // Change setting, check dialog property. - geoSettingsMap_->SetDefaultContentSetting(CONTENT_SETTING_ALLOW); - EXPECT_EQ([controller_ geolocationSettingIndex], kGeolocationEnabledIndex); - - geoSettingsMap_->SetDefaultContentSetting(CONTENT_SETTING_ASK); - EXPECT_EQ([controller_ geolocationSettingIndex], kGeolocationAskIndex); - - geoSettingsMap_->SetDefaultContentSetting(CONTENT_SETTING_BLOCK); - EXPECT_EQ([controller_ geolocationSettingIndex], kGeolocationDisabledIndex); - - // Change dialog property, check setting. - NSInteger setting; - [controller_ setGeolocationSettingIndex:kGeolocationEnabledIndex]; - setting = - geoSettingsMap_->GetDefaultContentSetting(); - EXPECT_EQ(setting, CONTENT_SETTING_ALLOW); - - [controller_ setGeolocationSettingIndex:kGeolocationAskIndex]; - setting = - geoSettingsMap_->GetDefaultContentSetting(); - EXPECT_EQ(setting, CONTENT_SETTING_ASK); - - [controller_ setGeolocationSettingIndex:kGeolocationDisabledIndex]; - setting = - geoSettingsMap_->GetDefaultContentSetting(); - EXPECT_EQ(setting, CONTENT_SETTING_BLOCK); -} - -TEST_F(ContentSettingsDialogControllerTest, NotificationsSetting) { - // Change setting, check dialog property. - notificationsService_->SetDefaultContentSetting(CONTENT_SETTING_ALLOW); - EXPECT_EQ([controller_ notificationsSettingIndex], - kNotificationsEnabledIndex); - - notificationsService_->SetDefaultContentSetting(CONTENT_SETTING_ASK); - EXPECT_EQ([controller_ notificationsSettingIndex], kNotificationsAskIndex); - - notificationsService_->SetDefaultContentSetting(CONTENT_SETTING_BLOCK); - EXPECT_EQ([controller_ notificationsSettingIndex], - kNotificationsDisabledIndex); - - // Change dialog property, check setting. - NSInteger setting; - [controller_ setNotificationsSettingIndex:kNotificationsEnabledIndex]; - setting = - notificationsService_->GetDefaultContentSetting(); - EXPECT_EQ(setting, CONTENT_SETTING_ALLOW); - - [controller_ setNotificationsSettingIndex:kNotificationsAskIndex]; - setting = - notificationsService_->GetDefaultContentSetting(); - EXPECT_EQ(setting, CONTENT_SETTING_ASK); - - [controller_ setNotificationsSettingIndex:kNotificationsDisabledIndex]; - setting = - notificationsService_->GetDefaultContentSetting(); - EXPECT_EQ(setting, CONTENT_SETTING_BLOCK); -} - -} // namespace - diff --git a/chrome/browser/ui/cocoa/options/cookies_window_controller.h b/chrome/browser/ui/cocoa/options/cookies_window_controller.h deleted file mode 100644 index 62d2507..0000000 --- a/chrome/browser/ui/cocoa/options/cookies_window_controller.h +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright (c) 2010 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> - -#import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" -#include "chrome/browser/cookies_tree_model.h" -#import "chrome/browser/ui/cocoa/content_settings/cookie_tree_node.h" -#include "net/base/cookie_monster.h" - -@class CookiesWindowController; -@class CookieDetailsViewController; -class Profile; - -namespace { -class CookiesWindowControllerTest; -} - -namespace ui { -class TreeModel; -class TreeModelNode; -} - -// Thin bridge to the window controller that performs model update actions -// directly on the treeController_. -class CookiesTreeModelObserverBridge : public CookiesTreeModel::Observer { - public: - explicit CookiesTreeModelObserverBridge(CookiesWindowController* controller); - - // Begin TreeModelObserver implementation. - virtual void TreeNodesAdded(ui::TreeModel* model, - ui::TreeModelNode* parent, - int start, - int count); - virtual void TreeNodesRemoved(ui::TreeModel* model, - ui::TreeModelNode* parent, - int start, - int count); - virtual void TreeNodeChanged(ui::TreeModel* model, ui::TreeModelNode* node); - // End TreeModelObserver implementation. - - virtual void TreeModelBeginBatch(CookiesTreeModel* model); - virtual void TreeModelEndBatch(CookiesTreeModel* model); - - // Invalidates the Cocoa model. This is used to tear down the Cocoa model - // when we're about to entirely rebuild it. - void InvalidateCocoaModel(); - - private: - friend class ::CookiesWindowControllerTest; - - // Creates a CocoaCookieTreeNode from a platform-independent one. - // Return value is autoreleased. This creates child nodes recusively. - CocoaCookieTreeNode* CocoaNodeFromTreeNode(ui::TreeModelNode* node); - - // Finds the Cocoa model node based on a platform-independent one. This is - // done by comparing the treeNode pointers. |start| is the node to start - // searching at. If |start| is nil, the root is used. - CocoaCookieTreeNode* FindCocoaNode(ui::TreeModelNode* node, - CocoaCookieTreeNode* start); - - // Returns whether or not the Cocoa tree model is built. - bool HasCocoaModel(); - - CookiesWindowController* window_controller_; // weak, owns us. - - // If this is true, then the Model has informed us that it is batching - // updates. Rather than updating the Cocoa side of the model, we ignore those - // small changes and rebuild once at the end. - bool batch_update_; -}; - -// Controller for the cookies manager. This class stores an internal copy of -// the CookiesTreeModel but with Cocoa-converted values (NSStrings and NSImages -// instead of std::strings and SkBitmaps). Doing this allows us to use bindings -// for the interface. Changes are pushed to this internal model via a very thin -// bridge (see above). -@interface CookiesWindowController : NSWindowController - <NSOutlineViewDelegate, - NSWindowDelegate> { - @private - // Platform-independent model and C++/Obj-C bridge components. - scoped_ptr<CookiesTreeModel> treeModel_; - scoped_ptr<CookiesTreeModelObserverBridge> modelObserver_; - - // Cached array of icons. - scoped_nsobject<NSMutableArray> icons_; - - // Our Cocoa copy of the model. - scoped_nsobject<CocoaCookieTreeNode> cocoaTreeModel_; - - // A flag indicating whether or not the "Remove" button should be enabled. - BOOL removeButtonEnabled_; - - IBOutlet NSTreeController* treeController_; - IBOutlet NSOutlineView* outlineView_; - IBOutlet NSSearchField* searchField_; - IBOutlet NSView* cookieDetailsViewPlaceholder_; - IBOutlet NSButton* removeButton_; - - scoped_nsobject<CookieDetailsViewController> detailsViewController_; - Profile* profile_; // weak - BrowsingDataDatabaseHelper* databaseHelper_; // weak - BrowsingDataLocalStorageHelper* storageHelper_; // weak - BrowsingDataAppCacheHelper* appcacheHelper_; // weak - BrowsingDataIndexedDBHelper* indexedDBHelper_; // weak -} -@property(assign, nonatomic) BOOL removeButtonEnabled; -@property(readonly, nonatomic) NSTreeController* treeController; - -// Designated initializer. Profile cannot be NULL. -- (id)initWithProfile:(Profile*)profile - databaseHelper:(BrowsingDataDatabaseHelper*)databaseHelper - storageHelper:(BrowsingDataLocalStorageHelper*)storageHelper - appcacheHelper:(BrowsingDataAppCacheHelper*)appcacheHelper - indexedDBHelper:(BrowsingDataIndexedDBHelper*)indexedDBHelper; - -// Shows the cookies window as a modal sheet attached to |window|. -- (void)attachSheetTo:(NSWindow*)window; - -// Updates the filter from the search field. -- (IBAction)updateFilter:(id)sender; - -// Delete cookie actions. -- (IBAction)deleteCookie:(id)sender; -- (IBAction)deleteAllCookies:(id)sender; - -// Closes the sheet and ends the modal loop. This will also cleanup the memory. -- (IBAction)closeSheet:(id)sender; - -// Returns the cocoaTreeModel_. -- (CocoaCookieTreeNode*)cocoaTreeModel; -- (void)setCocoaTreeModel:(CocoaCookieTreeNode*)model; - -// Returns the treeModel_. -- (CookiesTreeModel*)treeModel; - -@end - -@interface CookiesWindowController (UnitTesting) -- (void)deleteNodeAtIndexPath:(NSIndexPath*)path; -- (void)clearBrowsingDataNotification:(NSNotification*)notif; -- (CookiesTreeModelObserverBridge*)modelObserver; -- (NSArray*)icons; -- (void)loadTreeModelFromProfile; -@end diff --git a/chrome/browser/ui/cocoa/options/cookies_window_controller.mm b/chrome/browser/ui/cocoa/options/cookies_window_controller.mm deleted file mode 100644 index 9cadaa9..0000000 --- a/chrome/browser/ui/cocoa/options/cookies_window_controller.mm +++ /dev/null @@ -1,449 +0,0 @@ -// Copyright (c) 2010 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/ui/cocoa/options/cookies_window_controller.h" - -#include <queue> -#include <vector> - -#import "base/mac/mac_util.h" -#include "base/sys_string_conversions.h" -#include "chrome/browser/browsing_data_remover.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/cocoa/clear_browsing_data_controller.h" -#include "chrome/browser/ui/cocoa/content_settings/cookie_details_view_controller.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "skia/ext/skia_utils_mac.h" -#include "third_party/apple/ImageAndTextCell.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "ui/base/l10n/l10n_util_mac.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/image.h" - -// Key path used for notifying KVO. -static NSString* const kCocoaTreeModel = @"cocoaTreeModel"; - -CookiesTreeModelObserverBridge::CookiesTreeModelObserverBridge( - CookiesWindowController* controller) - : window_controller_(controller), - batch_update_(false) { -} - -// Notification that nodes were added to the specified parent. -void CookiesTreeModelObserverBridge::TreeNodesAdded(ui::TreeModel* model, - ui::TreeModelNode* parent, - int start, - int count) { - // We're in for a major rebuild. Ignore this request. - if (batch_update_ || !HasCocoaModel()) - return; - - CocoaCookieTreeNode* cocoa_parent = FindCocoaNode(parent, nil); - NSMutableArray* cocoa_children = [cocoa_parent mutableChildren]; - - [window_controller_ willChangeValueForKey:kCocoaTreeModel]; - CookieTreeNode* cookie_parent = static_cast<CookieTreeNode*>(parent); - for (int i = 0; i < count; ++i) { - CookieTreeNode* cookie_child = cookie_parent->GetChild(start + i); - CocoaCookieTreeNode* new_child = CocoaNodeFromTreeNode(cookie_child); - [cocoa_children addObject:new_child]; - } - [window_controller_ didChangeValueForKey:kCocoaTreeModel]; -} - -// Notification that nodes were removed from the specified parent. -void CookiesTreeModelObserverBridge::TreeNodesRemoved(ui::TreeModel* model, - ui::TreeModelNode* parent, - int start, - int count) { - // We're in for a major rebuild. Ignore this request. - if (batch_update_ || !HasCocoaModel()) - return; - - CocoaCookieTreeNode* cocoa_parent = FindCocoaNode(parent, nil); - [window_controller_ willChangeValueForKey:kCocoaTreeModel]; - NSMutableArray* cocoa_children = [cocoa_parent mutableChildren]; - for (int i = start + count - 1; i >= start; --i) { - [cocoa_children removeObjectAtIndex:i]; - } - [window_controller_ didChangeValueForKey:kCocoaTreeModel]; -} - -// Notification that the contents of a node has changed. -void CookiesTreeModelObserverBridge::TreeNodeChanged(ui::TreeModel* model, - ui::TreeModelNode* node) { - // If we don't have a Cocoa model, only let the root node change. - if (batch_update_ || (!HasCocoaModel() && model->GetRoot() != node)) - return; - - if (HasCocoaModel()) { - // We still have a Cocoa model, so just rebuild the node. - [window_controller_ willChangeValueForKey:kCocoaTreeModel]; - CocoaCookieTreeNode* changed_node = FindCocoaNode(node, nil); - [changed_node rebuild]; - [window_controller_ didChangeValueForKey:kCocoaTreeModel]; - } else { - // Full rebuild. - [window_controller_ setCocoaTreeModel:CocoaNodeFromTreeNode(node)]; - } -} - -void CookiesTreeModelObserverBridge::TreeModelBeginBatch( - CookiesTreeModel* model) { - batch_update_ = true; -} - -void CookiesTreeModelObserverBridge::TreeModelEndBatch( - CookiesTreeModel* model) { - DCHECK(batch_update_); - CocoaCookieTreeNode* root = CocoaNodeFromTreeNode(model->GetRoot()); - [window_controller_ setCocoaTreeModel:root]; - batch_update_ = false; -} - -void CookiesTreeModelObserverBridge::InvalidateCocoaModel() { - [[[window_controller_ cocoaTreeModel] mutableChildren] removeAllObjects]; -} - -CocoaCookieTreeNode* CookiesTreeModelObserverBridge::CocoaNodeFromTreeNode( - ui::TreeModelNode* node) { - CookieTreeNode* cookie_node = static_cast<CookieTreeNode*>(node); - return [[[CocoaCookieTreeNode alloc] initWithNode:cookie_node] autorelease]; -} - -// Does breadth-first search on the tree to find |node|. This method is most -// commonly used to find origin/folder nodes, which are at the first level off -// the root (hence breadth-first search). -CocoaCookieTreeNode* CookiesTreeModelObserverBridge::FindCocoaNode( - ui::TreeModelNode* target, CocoaCookieTreeNode* start) { - if (!start) { - start = [window_controller_ cocoaTreeModel]; - } - if ([start treeNode] == target) { - return start; - } - - // Enqueue the root node of the search (sub-)tree. - std::queue<CocoaCookieTreeNode*> horizon; - horizon.push(start); - - // Loop until we've looked at every node or we found the target. - while (!horizon.empty()) { - // Dequeue the item at the front. - CocoaCookieTreeNode* node = horizon.front(); - horizon.pop(); - - // If this is the droid we're looking for, report it. - if ([node treeNode] == target) - return node; - - // "Move along, move along." by adding all child nodes to the queue. - if (![node isLeaf]) { - NSArray* children = [node children]; - for (CocoaCookieTreeNode* child in children) { - horizon.push(child); - } - } - } - - return nil; // We couldn't find the node. -} - -// Returns whether or not the Cocoa tree model is built. -bool CookiesTreeModelObserverBridge::HasCocoaModel() { - return ([[[window_controller_ cocoaTreeModel] children] count] > 0U); -} - -#pragma mark Window Controller - -@implementation CookiesWindowController - -@synthesize removeButtonEnabled = removeButtonEnabled_; -@synthesize treeController = treeController_; - -- (id)initWithProfile:(Profile*)profile - databaseHelper:(BrowsingDataDatabaseHelper*)databaseHelper - storageHelper:(BrowsingDataLocalStorageHelper*)storageHelper - appcacheHelper:(BrowsingDataAppCacheHelper*)appcacheHelper - indexedDBHelper:(BrowsingDataIndexedDBHelper*)indexedDBHelper { - DCHECK(profile); - NSString* nibpath = [base::mac::MainAppBundle() pathForResource:@"Cookies" - ofType:@"nib"]; - if ((self = [super initWithWindowNibPath:nibpath owner:self])) { - profile_ = profile; - databaseHelper_ = databaseHelper; - storageHelper_ = storageHelper; - appcacheHelper_ = appcacheHelper; - indexedDBHelper_ = indexedDBHelper; - - [self loadTreeModelFromProfile]; - - // Register for Clear Browsing Data controller so we update appropriately. - ClearBrowsingDataController* clearingController = - [ClearBrowsingDataController controllerForProfile:profile_]; - if (clearingController) { - NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; - [center addObserver:self - selector:@selector(clearBrowsingDataNotification:) - name:kClearBrowsingDataControllerDidDelete - object:clearingController]; - } - } - return self; -} - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [super dealloc]; -} - -- (void)awakeFromNib { - DCHECK([self window]); - DCHECK_EQ(self, [[self window] delegate]); - - detailsViewController_.reset([[CookieDetailsViewController alloc] init]); - - NSView* detailView = [detailsViewController_.get() view]; - NSRect viewFrameRect = [cookieDetailsViewPlaceholder_ frame]; - [[detailsViewController_.get() view] setFrame:viewFrameRect]; - [[cookieDetailsViewPlaceholder_ superview] - replaceSubview:cookieDetailsViewPlaceholder_ - with:detailView]; - - [detailsViewController_ configureBindingsForTreeController:treeController_]; -} - -- (void)windowWillClose:(NSNotification*)notif { - [searchField_ setTarget:nil]; - [outlineView_ setDelegate:nil]; - [self autorelease]; -} - -- (void)attachSheetTo:(NSWindow*)window { - [NSApp beginSheet:[self window] - modalForWindow:window - modalDelegate:self - didEndSelector:@selector(sheetEndSheet:returnCode:contextInfo:) - contextInfo:nil]; -} - -- (void)sheetEndSheet:(NSWindow*)sheet - returnCode:(NSInteger)returnCode - contextInfo:(void*)context { - [sheet close]; - [sheet orderOut:self]; -} - -- (IBAction)updateFilter:(id)sender { - DCHECK([sender isKindOfClass:[NSSearchField class]]); - NSString* string = [sender stringValue]; - // Invalidate the model here because all the nodes are going to be removed - // in UpdateSearchResults(). This could lead to there temporarily being - // invalid pointers in the Cocoa model. - modelObserver_->InvalidateCocoaModel(); - treeModel_->UpdateSearchResults(base::SysNSStringToWide(string)); -} - -- (IBAction)deleteCookie:(id)sender { - DCHECK_EQ(1U, [[treeController_ selectedObjects] count]); - [self deleteNodeAtIndexPath:[treeController_ selectionIndexPath]]; -} - -// This will delete the Cocoa model node as well as the backing model object at -// the specified index path in the Cocoa model. If the node that was deleted -// was the sole child of the parent node, this will be called recursively to -// delete empty parents. -- (void)deleteNodeAtIndexPath:(NSIndexPath*)path { - NSTreeNode* treeNode = - [[treeController_ arrangedObjects] descendantNodeAtIndexPath:path]; - if (!treeNode) - return; - - CocoaCookieTreeNode* node = [treeNode representedObject]; - CookieTreeNode* cookie = static_cast<CookieTreeNode*>([node treeNode]); - treeModel_->DeleteCookieNode(cookie); - // If there is a next cookie, this will select it because items will slide - // up. If there is no next cookie, this is a no-op. - [treeController_ setSelectionIndexPath:path]; - // If the above setting of the selection was in fact a no-op, find the next - // node to select. - if (![[treeController_ selectedObjects] count]) { - NSUInteger lastIndex = [path indexAtPosition:[path length] - 1]; - if (lastIndex != 0) { - // If there any nodes remaining, select the node that is in the list - // before this one. - path = [path indexPathByRemovingLastIndex]; - path = [path indexPathByAddingIndex:lastIndex - 1]; - [treeController_ setSelectionIndexPath:path]; - } - } -} - -- (IBAction)deleteAllCookies:(id)sender { - // Preemptively delete all cookies in the Cocoa model. - modelObserver_->InvalidateCocoaModel(); - treeModel_->DeleteAllStoredObjects(); -} - -- (IBAction)closeSheet:(id)sender { - [NSApp endSheet:[self window]]; -} - -- (void)clearBrowsingDataNotification:(NSNotification*)notif { - NSNumber* removeMask = - [[notif userInfo] objectForKey:kClearBrowsingDataControllerRemoveMask]; - if ([removeMask intValue] & BrowsingDataRemover::REMOVE_COOKIES) { - [self loadTreeModelFromProfile]; - } -} - -// Override keyDown on the controller (which is the first responder) to allow -// both backspace and delete to be captured by the Remove button. -- (void)keyDown:(NSEvent*)theEvent { - NSString* keys = [theEvent characters]; - if ([keys length]) { - unichar key = [keys characterAtIndex:0]; - // The button has a key equivalent of backspace, so examine this event for - // forward delete. - if ((key == NSDeleteCharacter || key == NSDeleteFunctionKey) && - [self removeButtonEnabled]) { - [removeButton_ performClick:self]; - return; - } - } - [super keyDown:theEvent]; -} - -#pragma mark Getters and Setters - -- (CocoaCookieTreeNode*)cocoaTreeModel { - return cocoaTreeModel_.get(); -} -- (void)setCocoaTreeModel:(CocoaCookieTreeNode*)model { - cocoaTreeModel_.reset([model retain]); -} - -- (CookiesTreeModel*)treeModel { - return treeModel_.get(); -} - -#pragma mark Outline View Delegate - -- (void)outlineView:(NSOutlineView*)outlineView - willDisplayCell:(id)cell - forTableColumn:(NSTableColumn*)tableColumn - item:(id)item { - CocoaCookieTreeNode* node = [item representedObject]; - int index = treeModel_->GetIconIndex([node treeNode]); - NSImage* icon = nil; - if (index >= 0) - icon = [icons_ objectAtIndex:index]; - else - icon = [icons_ lastObject]; - [(ImageAndTextCell*)cell setImage:icon]; -} - -- (void)outlineViewItemDidExpand:(NSNotification*)notif { - NSTreeNode* item = [[notif userInfo] objectForKey:@"NSObject"]; - CocoaCookieTreeNode* node = [item representedObject]; - NSArray* children = [node children]; - if ([children count] == 1U) { - // The node that will expand has one child. Do the user a favor and expand - // that node (saving her a click) if it is non-leaf. - CocoaCookieTreeNode* child = [children lastObject]; - if (![child isLeaf]) { - NSOutlineView* outlineView = [notif object]; - // Tell the OutlineView to expand the NSTreeNode, not the model object. - children = [item childNodes]; - DCHECK_EQ([children count], 1U); - [outlineView expandItem:[children lastObject]]; - // Select the first node in that child set. - NSTreeNode* folderChild = [children lastObject]; - if ([[folderChild childNodes] count] > 0) { - NSTreeNode* firstCookieChild = - [[folderChild childNodes] objectAtIndex:0]; - [treeController_ setSelectionIndexPath:[firstCookieChild indexPath]]; - } - } - } -} - -- (void)outlineViewSelectionDidChange:(NSNotification*)notif { - // Multi-selection should be disabled in the UI, but for sanity, double-check - // that they can't do it here. - NSArray* selectedObjects = [treeController_ selectedObjects]; - NSUInteger count = [selectedObjects count]; - if (count != 1U) { - DCHECK_LT(count, 1U) << "User was able to select more than 1 cookie node!"; - [self setRemoveButtonEnabled:NO]; - return; - } - - // Go through the selection's indexPath and make sure that the node that is - // being referenced actually exists in the Cocoa model. - NSIndexPath* selection = [treeController_ selectionIndexPath]; - NSUInteger length = [selection length]; - CocoaCookieTreeNode* node = [self cocoaTreeModel]; - for (NSUInteger i = 0; i < length; ++i) { - NSUInteger childIndex = [selection indexAtPosition:i]; - if (childIndex >= [[node children] count]) { - [self setRemoveButtonEnabled:NO]; - return; - } - node = [[node children] objectAtIndex:childIndex]; - } - - // If there is a valid selection, make sure that the remove - // button is enabled. - [self setRemoveButtonEnabled:YES]; -} - -#pragma mark Unit Testing - -- (CookiesTreeModelObserverBridge*)modelObserver { - return modelObserver_.get(); -} - -- (NSArray*)icons { - return icons_.get(); -} - -// Re-initializes the |treeModel_|, creates a new observer for it, and re- -// builds the |cocoaTreeModel_|. We use this to initialize the controller and -// to rebuild after the user clears browsing data. Because the models get -// clobbered, we rebuild the icon cache for safety (though they do not change). -- (void)loadTreeModelFromProfile { - treeModel_.reset(new CookiesTreeModel( - profile_->GetRequestContext()->GetCookieStore()->GetCookieMonster(), - databaseHelper_, - storageHelper_, - NULL, - appcacheHelper_, - indexedDBHelper_)); - modelObserver_.reset(new CookiesTreeModelObserverBridge(self)); - treeModel_->AddCookiesTreeObserver(modelObserver_.get()); - - // Convert the model's icons from Skia to Cocoa. - std::vector<SkBitmap> skiaIcons; - treeModel_->GetIcons(&skiaIcons); - icons_.reset([[NSMutableArray alloc] init]); - for (std::vector<SkBitmap>::iterator it = skiaIcons.begin(); - it != skiaIcons.end(); ++it) { - [icons_ addObject:gfx::SkBitmapToNSImage(*it)]; - } - - // Default icon will be the last item in the array. - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - // TODO(rsesek): Rename this resource now that it's in multiple places. - [icons_ addObject:rb.GetNativeImageNamed(IDR_BOOKMARK_BAR_FOLDER)]; - - // Create the Cocoa model. - CookieTreeNode* root = static_cast<CookieTreeNode*>(treeModel_->GetRoot()); - scoped_nsobject<CocoaCookieTreeNode> model( - [[CocoaCookieTreeNode alloc] initWithNode:root]); - [self setCocoaTreeModel:model.get()]; // Takes ownership. -} - -@end diff --git a/chrome/browser/ui/cocoa/options/cookies_window_controller_unittest.mm b/chrome/browser/ui/cocoa/options/cookies_window_controller_unittest.mm deleted file mode 100644 index 119f67b..0000000 --- a/chrome/browser/ui/cocoa/options/cookies_window_controller_unittest.mm +++ /dev/null @@ -1,710 +0,0 @@ -// Copyright (c) 2010 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> - -#import "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/browsing_data_remover.h" -#include "chrome/browser/cookies_tree_model.h" -#include "chrome/browser/mock_browsing_data_appcache_helper.h" -#include "chrome/browser/mock_browsing_data_database_helper.h" -#include "chrome/browser/mock_browsing_data_indexed_db_helper.h" -#include "chrome/browser/mock_browsing_data_local_storage_helper.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/cocoa/browser_test_helper.h" -#include "chrome/browser/ui/cocoa/clear_browsing_data_controller.h" -#include "chrome/browser/ui/cocoa/cocoa_test_helper.h" -#import "chrome/browser/ui/cocoa/options/cookies_window_controller.h" -#include "chrome/common/net/url_request_context_getter.h" -#include "chrome/test/testing_profile.h" -#include "googleurl/src/gurl.h" -#include "grit/generated_resources.h" -#include "net/url_request/url_request_context.h" -#include "testing/gtest/include/gtest/gtest.h" -#import "testing/gtest_mac.h" -#include "testing/platform_test.h" -#import "third_party/ocmock/OCMock/OCMock.h" -#include "ui/base/l10n/l10n_util_mac.h" -#include "ui/base/models/tree_model.h" - -// Used to test FindCocoaNode. This only sets the title and node, without -// initializing any other members. -@interface FakeCocoaCookieTreeNode : CocoaCookieTreeNode { - ui::TreeModelNode* testNode_; -} -- (id)initWithTreeNode:(ui::TreeModelNode*)node; -@end -@implementation FakeCocoaCookieTreeNode -- (id)initWithTreeNode:(ui::TreeModelNode*)node { - if ((self = [super init])) { - testNode_ = node; - children_.reset([[NSMutableArray alloc] init]); - } - return self; -} -- (ui::TreeModelNode*)treeNode { - return testNode_; -} -@end - -namespace { - -class CookiesWindowControllerTest : public CocoaTest { - public: - - virtual void SetUp() { - CocoaTest::SetUp(); - TestingProfile* profile = browser_helper_.profile(); - profile->CreateRequestContext(); - database_helper_ = new MockBrowsingDataDatabaseHelper(profile); - local_storage_helper_ = new MockBrowsingDataLocalStorageHelper(profile); - appcache_helper_ = new MockBrowsingDataAppCacheHelper(profile); - indexed_db_helper_ = new MockBrowsingDataIndexedDBHelper(profile); - controller_.reset( - [[CookiesWindowController alloc] initWithProfile:profile - databaseHelper:database_helper_ - storageHelper:local_storage_helper_ - appcacheHelper:appcache_helper_ - indexedDBHelper:indexed_db_helper_] - ); - } - - virtual void TearDown() { - CocoaTest::TearDown(); - } - - CocoaCookieTreeNode* CocoaNodeFromTreeNode(ui::TreeModelNode* node) { - return [controller_ modelObserver]->CocoaNodeFromTreeNode(node); - } - - CocoaCookieTreeNode* FindCocoaNode(ui::TreeModelNode* node, - CocoaCookieTreeNode* start) { - return [controller_ modelObserver]->FindCocoaNode(node, start); - } - - protected: - BrowserTestHelper browser_helper_; - scoped_nsobject<CookiesWindowController> controller_; - MockBrowsingDataDatabaseHelper* database_helper_; - MockBrowsingDataLocalStorageHelper* local_storage_helper_; - MockBrowsingDataAppCacheHelper* appcache_helper_; - MockBrowsingDataIndexedDBHelper* indexed_db_helper_; -}; - -TEST_F(CookiesWindowControllerTest, Construction) { - std::vector<SkBitmap> skia_icons; - [controller_ treeModel]->GetIcons(&skia_icons); - - EXPECT_EQ([[controller_ icons] count], skia_icons.size() + 1U); -} - -TEST_F(CookiesWindowControllerTest, FindCocoaNodeRoot) { - scoped_ptr< ui::TreeNodeWithValue<int> > search( - new ui::TreeNodeWithValue<int>(42)); - scoped_nsobject<FakeCocoaCookieTreeNode> node( - [[FakeCocoaCookieTreeNode alloc] initWithTreeNode:search.get()]); - EXPECT_EQ(node.get(), FindCocoaNode(search.get(), node.get())); -} - -TEST_F(CookiesWindowControllerTest, FindCocoaNodeImmediateChild) { - scoped_ptr< ui::TreeNodeWithValue<int> > parent( - new ui::TreeNodeWithValue<int>(100)); - scoped_ptr< ui::TreeNodeWithValue<int> > child1( - new ui::TreeNodeWithValue<int>(10)); - scoped_ptr< ui::TreeNodeWithValue<int> > child2( - new ui::TreeNodeWithValue<int>(20)); - scoped_nsobject<FakeCocoaCookieTreeNode> cocoaParent( - [[FakeCocoaCookieTreeNode alloc] initWithTreeNode:parent.get()]); - scoped_nsobject<FakeCocoaCookieTreeNode> cocoaChild1( - [[FakeCocoaCookieTreeNode alloc] initWithTreeNode:child1.get()]); - scoped_nsobject<FakeCocoaCookieTreeNode> cocoaChild2( - [[FakeCocoaCookieTreeNode alloc] initWithTreeNode:child2.get()]); - [[cocoaParent mutableChildren] addObject:cocoaChild1.get()]; - [[cocoaParent mutableChildren] addObject:cocoaChild2.get()]; - - EXPECT_EQ(cocoaChild2.get(), FindCocoaNode(child2.get(), cocoaParent.get())); -} - -TEST_F(CookiesWindowControllerTest, FindCocoaNodeRecursive) { - scoped_ptr< ui::TreeNodeWithValue<int> > parent( - new ui::TreeNodeWithValue<int>(100)); - scoped_ptr< ui::TreeNodeWithValue<int> > child1( - new ui::TreeNodeWithValue<int>(10)); - scoped_ptr< ui::TreeNodeWithValue<int> > child2( - new ui::TreeNodeWithValue<int>(20)); - scoped_nsobject<FakeCocoaCookieTreeNode> cocoaParent( - [[FakeCocoaCookieTreeNode alloc] initWithTreeNode:parent.get()]); - scoped_nsobject<FakeCocoaCookieTreeNode> cocoaChild1( - [[FakeCocoaCookieTreeNode alloc] initWithTreeNode:child1.get()]); - scoped_nsobject<FakeCocoaCookieTreeNode> cocoaChild2( - [[FakeCocoaCookieTreeNode alloc] initWithTreeNode:child2.get()]); - [[cocoaParent mutableChildren] addObject:cocoaChild1.get()]; - [[cocoaChild1 mutableChildren] addObject:cocoaChild2.get()]; - - EXPECT_EQ(cocoaChild2.get(), FindCocoaNode(child2.get(), cocoaParent.get())); -} - -TEST_F(CookiesWindowControllerTest, CocoaNodeFromTreeNodeCookie) { - net::CookieMonster* cm = browser_helper_.profile()->GetCookieMonster(); - cm->SetCookie(GURL("http://foo.com"), "A=B"); - CookiesTreeModel model(cm, database_helper_, local_storage_helper_, nil, nil, - nil); - - // Root --> foo.com --> Cookies --> A. Create node for 'A'. - ui::TreeModelNode* node = - model.GetRoot()->GetChild(0)->GetChild(0)->GetChild(0); - CocoaCookieTreeNode* cookie = CocoaNodeFromTreeNode(node); - - CocoaCookieDetails* details = [cookie details]; - EXPECT_NSEQ(@"B", [details content]); - EXPECT_NSEQ(l10n_util::GetNSString(IDS_COOKIES_COOKIE_EXPIRES_SESSION), - [details expires]); - EXPECT_NSEQ(l10n_util::GetNSString(IDS_COOKIES_COOKIE_SENDFOR_ANY), - [details sendFor]); - EXPECT_NSEQ(@"A", [cookie title]); - EXPECT_NSEQ(@"A", [details name]); - EXPECT_NSEQ(@"/", [details path]); - EXPECT_EQ(0U, [[cookie children] count]); - EXPECT_TRUE([details created]); - EXPECT_TRUE([cookie isLeaf]); - EXPECT_EQ(node, [cookie treeNode]); -} - -TEST_F(CookiesWindowControllerTest, CocoaNodeFromTreeNodeRecursive) { - net::CookieMonster* cm = browser_helper_.profile()->GetCookieMonster(); - cm->SetCookie(GURL("http://foo.com"), "A=B"); - CookiesTreeModel model(cm, database_helper_, local_storage_helper_, nil, nil, - nil); - - // Root --> foo.com --> Cookies --> A. Create node for 'foo.com'. - CookieTreeNode* node = model.GetRoot()->GetChild(0); - CocoaCookieTreeNode* domain = CocoaNodeFromTreeNode(node); - CocoaCookieTreeNode* cookies = [[domain children] objectAtIndex:0]; - CocoaCookieTreeNode* cookie = [[cookies children] objectAtIndex:0]; - - // Test domain-level node. - EXPECT_NSEQ(@"foo.com", [domain title]); - - EXPECT_FALSE([domain isLeaf]); - EXPECT_EQ(1U, [[domain children] count]); - EXPECT_EQ(node, [domain treeNode]); - - // Test "Cookies" folder node. - EXPECT_NSEQ(l10n_util::GetNSString(IDS_COOKIES_COOKIES), [cookies title]); - EXPECT_FALSE([cookies isLeaf]); - EXPECT_EQ(1U, [[cookies children] count]); - EXPECT_EQ(node->GetChild(0), [cookies treeNode]); - - // Test cookie node. This is the same as CocoaNodeFromTreeNodeCookie. - CocoaCookieDetails* details = [cookie details]; - EXPECT_NSEQ(@"B", [details content]); - EXPECT_NSEQ(l10n_util::GetNSString(IDS_COOKIES_COOKIE_EXPIRES_SESSION), - [details expires]); - EXPECT_NSEQ(l10n_util::GetNSString(IDS_COOKIES_COOKIE_SENDFOR_ANY), - [details sendFor]); - EXPECT_NSEQ(@"A", [cookie title]); - EXPECT_NSEQ(@"A", [details name]); - EXPECT_NSEQ(@"/", [details path]); - EXPECT_NSEQ(@"foo.com", [details domain]); - EXPECT_EQ(0U, [[cookie children] count]); - EXPECT_TRUE([details created]); - EXPECT_TRUE([cookie isLeaf]); - EXPECT_EQ(node->GetChild(0)->GetChild(0), [cookie treeNode]); -} - -TEST_F(CookiesWindowControllerTest, TreeNodesAdded) { - const GURL url = GURL("http://foo.com"); - TestingProfile* profile = browser_helper_.profile(); - net::CookieMonster* cm = profile->GetCookieMonster(); - cm->SetCookie(url, "A=B"); - - controller_.reset( - [[CookiesWindowController alloc] initWithProfile:profile - databaseHelper:database_helper_ - storageHelper:local_storage_helper_ - appcacheHelper:appcache_helper_ - indexedDBHelper:indexed_db_helper_]); - - // Root --> foo.com --> Cookies. - NSMutableArray* cocoa_children = - [[[[[[controller_ cocoaTreeModel] children] objectAtIndex:0] - children] objectAtIndex:0] mutableChildren]; - EXPECT_EQ(1U, [cocoa_children count]); - - // Create some cookies. - cm->SetCookie(url, "C=D"); - cm->SetCookie(url, "E=F"); - - net::CookieList list = cm->GetAllCookies(); - CookiesTreeModel* model = [controller_ treeModel]; - // Root --> foo.com --> Cookies. - CookieTreeNode* parent = model->GetRoot()->GetChild(0)->GetChild(0); - - ASSERT_EQ(3U, list.size()); - - // Add the cookie nodes. - CookieTreeCookieNode* cnode = new CookieTreeCookieNode(&list[1]); - parent->Add(1, cnode); // |parent| takes ownership. - cnode = new CookieTreeCookieNode(&list[2]); - parent->Add(2, cnode); - - // Manually notify the observer. - [controller_ modelObserver]->TreeNodesAdded(model, parent, 1, 2); - - // Check that we have created 2 more Cocoa nodes. - EXPECT_EQ(3U, [cocoa_children count]); -} - -TEST_F(CookiesWindowControllerTest, TreeNodesRemoved) { - const GURL url = GURL("http://foo.com"); - TestingProfile* profile = browser_helper_.profile(); - net::CookieMonster* cm = profile->GetCookieMonster(); - cm->SetCookie(url, "A=B"); - cm->SetCookie(url, "C=D"); - cm->SetCookie(url, "E=F"); - - controller_.reset( - [[CookiesWindowController alloc] initWithProfile:profile - databaseHelper:database_helper_ - storageHelper:local_storage_helper_ - appcacheHelper:appcache_helper_ - indexedDBHelper:indexed_db_helper_]); - - // Root --> foo.com --> Cookies. - NSMutableArray* cocoa_children = - [[[[[[controller_ cocoaTreeModel] children] objectAtIndex:0] - children] objectAtIndex:0] mutableChildren]; - EXPECT_EQ(3U, [cocoa_children count]); - - CookiesTreeModel* model = [controller_ treeModel]; - // Root --> foo.com --> Cookies. - CookieTreeNode* parent = model->GetRoot()->GetChild(0)->GetChild(0); - - // Pretend to remove the nodes. - [controller_ modelObserver]->TreeNodesRemoved(model, parent, 1, 2); - - EXPECT_EQ(1U, [cocoa_children count]); - - NSString* title = [[[cocoa_children objectAtIndex:0] details] name]; - EXPECT_NSEQ(@"A", title); -} - -TEST_F(CookiesWindowControllerTest, TreeNodeChanged) { - const GURL url = GURL("http://foo.com"); - TestingProfile* profile = browser_helper_.profile(); - net::CookieMonster* cm = profile->GetCookieMonster(); - cm->SetCookie(url, "A=B"); - - controller_.reset( - [[CookiesWindowController alloc] initWithProfile:profile - databaseHelper:database_helper_ - storageHelper:local_storage_helper_ - appcacheHelper:appcache_helper_ - indexedDBHelper:indexed_db_helper_]); - - CookiesTreeModel* model = [controller_ treeModel]; - // Root --> foo.com --> Cookies. - CookieTreeNode* node = model->GetRoot()->GetChild(0)->GetChild(0); - - // Root --> foo.com --> Cookies. - CocoaCookieTreeNode* cocoa_node = - [[[[[controller_ cocoaTreeModel] children] objectAtIndex:0] - children] objectAtIndex:0]; - - EXPECT_NSEQ(l10n_util::GetNSString(IDS_COOKIES_COOKIES), - [cocoa_node title]); - - // Fake update the cookie folder's title. This would never happen in reality, - // but it tests the code path that ultimately calls CocoaNodeFromTreeNode, - // which is tested elsewhere. - node->SetTitle(ASCIIToUTF16("Silly Change")); - [controller_ modelObserver]->TreeNodeChanged(model, node); - - EXPECT_NSEQ(@"Silly Change", [cocoa_node title]); -} - -TEST_F(CookiesWindowControllerTest, DeleteCookie) { - const GURL url = GURL("http://foo.com"); - TestingProfile* profile = browser_helper_.profile(); - net::CookieMonster* cm = profile->GetCookieMonster(); - cm->SetCookie(url, "A=B"); - cm->SetCookie(url, "C=D"); - cm->SetCookie(GURL("http://google.com"), "E=F"); - - // This will clean itself up when we call |-closeSheet:|. If we reset the - // scoper, we'd get a double-free. - CookiesWindowController* controller = - [[CookiesWindowController alloc] initWithProfile:profile - databaseHelper:database_helper_ - storageHelper:local_storage_helper_ - appcacheHelper:appcache_helper_ - indexedDBHelper:indexed_db_helper_]; - [controller attachSheetTo:test_window()]; - NSTreeController* treeController = [controller treeController]; - - // Select cookie A. - NSUInteger pathA[3] = {0, 0, 0}; - NSIndexPath* indexPath = [NSIndexPath indexPathWithIndexes:pathA length:3]; - [treeController setSelectionIndexPath:indexPath]; - - // Press the "Delete" button. - [controller deleteCookie:nil]; - - // Root --> foo.com --> Cookies. - NSArray* cookies = [[[[[[controller cocoaTreeModel] children] - objectAtIndex:0] children] objectAtIndex:0] children]; - EXPECT_EQ(1U, [cookies count]); - EXPECT_NSEQ(@"C", [[cookies lastObject] title]); - EXPECT_NSEQ(indexPath, [treeController selectionIndexPath]); - - // Select cookie E. - NSUInteger pathE[3] = {1, 0, 0}; - indexPath = [NSIndexPath indexPathWithIndexes:pathE length:3]; - [treeController setSelectionIndexPath:indexPath]; - - // Perform delete. - [controller deleteCookie:nil]; - - // Make sure that both the domain level node and the Cookies folder node got - // deleted because there was only one leaf node. - EXPECT_EQ(1U, [[[controller cocoaTreeModel] children] count]); - - // Select cookie C. - NSUInteger pathC[3] = {0, 0, 0}; - indexPath = [NSIndexPath indexPathWithIndexes:pathC length:3]; - [treeController setSelectionIndexPath:indexPath]; - - // Perform delete. - [controller deleteCookie:nil]; - - // Make sure the world didn't explode and that there's nothing in the tree. - EXPECT_EQ(0U, [[[controller cocoaTreeModel] children] count]); - - [controller closeSheet:nil]; -} - -TEST_F(CookiesWindowControllerTest, DidExpandItem) { - const GURL url = GURL("http://foo.com"); - TestingProfile* profile = browser_helper_.profile(); - net::CookieMonster* cm = profile->GetCookieMonster(); - cm->SetCookie(url, "A=B"); - cm->SetCookie(url, "C=D"); - - controller_.reset( - [[CookiesWindowController alloc] initWithProfile:profile - databaseHelper:database_helper_ - storageHelper:local_storage_helper_ - appcacheHelper:appcache_helper_ - indexedDBHelper:indexed_db_helper_]); - - // Root --> foo.com. - CocoaCookieTreeNode* foo = - [[[controller_ cocoaTreeModel] children] objectAtIndex:0]; - - // Create the objects we are going to be testing with. - id outlineView = [OCMockObject mockForClass:[NSOutlineView class]]; - id treeNode = [OCMockObject mockForClass:[NSTreeNode class]]; - NSTreeNode* childTreeNode = - [NSTreeNode treeNodeWithRepresentedObject:[[foo children] lastObject]]; - NSArray* fakeChildren = [NSArray arrayWithObject:childTreeNode]; - - // Set up the mock object. - [[[treeNode stub] andReturn:foo] representedObject]; - [[[treeNode stub] andReturn:fakeChildren] childNodes]; - - // Create a fake "ItemDidExpand" notification. - NSDictionary* userInfo = [NSDictionary dictionaryWithObject:treeNode - forKey:@"NSObject"]; - NSNotification* notif = - [NSNotification notificationWithName:@"ItemDidExpandNotification" - object:outlineView - userInfo:userInfo]; - - // Make sure we work correctly. - [[outlineView expect] expandItem:childTreeNode]; - [controller_ outlineViewItemDidExpand:notif]; - [outlineView verify]; -} - -TEST_F(CookiesWindowControllerTest, ClearBrowsingData) { - const GURL url = GURL("http://foo.com"); - TestingProfile* profile = browser_helper_.profile(); - net::CookieMonster* cm = profile->GetCookieMonster(); - cm->SetCookie(url, "A=B"); - cm->SetCookie(url, "C=D"); - cm->SetCookie(url, "E=F"); - - id mock = [OCMockObject partialMockForObject:controller_.get()]; - [[mock expect] loadTreeModelFromProfile]; - - NSNumber* mask = - [NSNumber numberWithInt:BrowsingDataRemover::REMOVE_COOKIES]; - NSDictionary* userInfo = - [NSDictionary dictionaryWithObject:mask - forKey:kClearBrowsingDataControllerRemoveMask]; - NSNotification* notif = - [NSNotification notificationWithName:kClearBrowsingDataControllerDidDelete - object:nil - userInfo:userInfo]; - [controller_ clearBrowsingDataNotification:notif]; - - [mock verify]; -} - -// This test has been flaky under Valgrind and turns the bot red since r38504. -// Under Mac Tests 10.5, it occasionally reports: -// malloc: *** error for object 0x31e0468: Non-aligned pointer being freed -// *** set a breakpoint in malloc_error_break to debug -// Attempts to reproduce locally were not successful. This code is likely -// changing in the future, so it's marked flaky for now. http://crbug.com/35327 -TEST_F(CookiesWindowControllerTest, FLAKY_RemoveButtonEnabled) { - const GURL url = GURL("http://foo.com"); - TestingProfile* profile = browser_helper_.profile(); - net::CookieMonster* cm = profile->GetCookieMonster(); - cm->SetCookie(url, "A=B"); - cm->SetCookie(url, "C=D"); - - // This will clean itself up when we call |-closeSheet:|. If we reset the - // scoper, we'd get a double-free. - database_helper_ = new MockBrowsingDataDatabaseHelper(profile); - local_storage_helper_ = new MockBrowsingDataLocalStorageHelper(profile); - local_storage_helper_->AddLocalStorageSamples(); - CookiesWindowController* controller = - [[CookiesWindowController alloc] initWithProfile:profile - databaseHelper:database_helper_ - storageHelper:local_storage_helper_ - appcacheHelper:appcache_helper_ - indexedDBHelper:indexed_db_helper_]; - local_storage_helper_->Notify(); - [controller attachSheetTo:test_window()]; - - // Nothing should be selected right now. - EXPECT_FALSE([controller removeButtonEnabled]); - - { - // Pretend to select cookie A. - NSUInteger path[3] = {0, 0, 0}; - NSIndexPath* indexPath = [NSIndexPath indexPathWithIndexes:path length:3]; - [[controller treeController] setSelectionIndexPath:indexPath]; - [controller outlineViewSelectionDidChange:nil]; - EXPECT_TRUE([controller removeButtonEnabled]); - } - - { - // Pretend to select cookie C. - NSUInteger path[3] = {0, 0, 1}; - NSIndexPath* indexPath = [NSIndexPath indexPathWithIndexes:path length:3]; - [[controller treeController] setSelectionIndexPath:indexPath]; - [controller outlineViewSelectionDidChange:nil]; - EXPECT_TRUE([controller removeButtonEnabled]); - } - - { - // Select a local storage node. - NSUInteger path[3] = {2, 0, 0}; - NSIndexPath* indexPath = [NSIndexPath indexPathWithIndexes:path length:3]; - [[controller treeController] setSelectionIndexPath:indexPath]; - [controller outlineViewSelectionDidChange:nil]; - EXPECT_TRUE([controller removeButtonEnabled]); - } - - { - // Pretend to select something that isn't there! - NSUInteger path[3] = {0, 0, 2}; - NSIndexPath* indexPath = [NSIndexPath indexPathWithIndexes:path length:3]; - [[controller treeController] setSelectionIndexPath:indexPath]; - [controller outlineViewSelectionDidChange:nil]; - EXPECT_FALSE([controller removeButtonEnabled]); - } - - { - // Try selecting something that doesn't exist again. - NSUInteger path[3] = {7, 1, 4}; - NSIndexPath* indexPath = [NSIndexPath indexPathWithIndexes:path length:3]; - [[controller treeController] setSelectionIndexPath:indexPath]; - [controller outlineViewSelectionDidChange:nil]; - EXPECT_FALSE([controller removeButtonEnabled]); - } - - [controller closeSheet:nil]; -} - -TEST_F(CookiesWindowControllerTest, UpdateFilter) { - const GURL url = GURL("http://foo.com"); - TestingProfile* profile = browser_helper_.profile(); - net::CookieMonster* cm = profile->GetCookieMonster(); - cm->SetCookie(GURL("http://a.com"), "A=B"); - cm->SetCookie(GURL("http://aa.com"), "C=D"); - cm->SetCookie(GURL("http://b.com"), "E=F"); - cm->SetCookie(GURL("http://d.com"), "G=H"); - cm->SetCookie(GURL("http://dd.com"), "I=J"); - - controller_.reset( - [[CookiesWindowController alloc] initWithProfile:profile - databaseHelper:database_helper_ - storageHelper:local_storage_helper_ - appcacheHelper:appcache_helper_ - indexedDBHelper:indexed_db_helper_]); - - // Make sure we registered all five cookies. - EXPECT_EQ(5U, [[[controller_ cocoaTreeModel] children] count]); - - NSSearchField* field = - [[NSSearchField alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)]; - - // Make sure we still have five cookies. - [field setStringValue:@""]; - [controller_ updateFilter:field]; - EXPECT_EQ(5U, [[[controller_ cocoaTreeModel] children] count]); - - // Search for "a". - [field setStringValue:@"a"]; - [controller_ updateFilter:field]; - EXPECT_EQ(2U, [[[controller_ cocoaTreeModel] children] count]); - - // Search for "b". - [field setStringValue:@"b"]; - [controller_ updateFilter:field]; - EXPECT_EQ(1U, [[[controller_ cocoaTreeModel] children] count]); - - // Search for "d". - [field setStringValue:@"d"]; - [controller_ updateFilter:field]; - EXPECT_EQ(2U, [[[controller_ cocoaTreeModel] children] count]); - - // Search for "e". - [field setStringValue:@"e"]; - [controller_ updateFilter:field]; - EXPECT_EQ(0U, [[[controller_ cocoaTreeModel] children] count]); - - // Search for "aa". - [field setStringValue:@"aa"]; - [controller_ updateFilter:field]; - EXPECT_EQ(1U, [[[controller_ cocoaTreeModel] children] count]); -} - -TEST_F(CookiesWindowControllerTest, CreateDatabaseStorageNodes) { - TestingProfile* profile = browser_helper_.profile(); - database_helper_ = new MockBrowsingDataDatabaseHelper(profile); - local_storage_helper_ = new MockBrowsingDataLocalStorageHelper(profile); - database_helper_->AddDatabaseSamples(); - controller_.reset( - [[CookiesWindowController alloc] initWithProfile:profile - databaseHelper:database_helper_ - storageHelper:local_storage_helper_ - appcacheHelper:appcache_helper_ - indexedDBHelper:indexed_db_helper_]); - database_helper_->Notify(); - - ASSERT_EQ(2U, [[[controller_ cocoaTreeModel] children] count]); - - // Root --> gdbhost1. - CocoaCookieTreeNode* node = - [[[controller_ cocoaTreeModel] children] objectAtIndex:0]; - EXPECT_NSEQ(@"gdbhost1", [node title]); - EXPECT_EQ(kCocoaCookieDetailsTypeFolder, [node nodeType]); - EXPECT_EQ(1U, [[node children] count]); - - // host1 --> Web Databases. - node = [[node children] lastObject]; - EXPECT_NSEQ(l10n_util::GetNSString(IDS_COOKIES_WEB_DATABASES), [node title]); - EXPECT_EQ(kCocoaCookieDetailsTypeFolder, [node nodeType]); - EXPECT_EQ(1U, [[node children] count]); - - // Database Storage --> db1. - node = [[node children] lastObject]; - EXPECT_NSEQ(@"db1", [node title]); - EXPECT_EQ(kCocoaCookieDetailsTypeTreeDatabase, [node nodeType]); - CocoaCookieDetails* details = [node details]; - EXPECT_NSEQ(@"description 1", [details databaseDescription]); - EXPECT_TRUE([details lastModified]); - EXPECT_TRUE([details fileSize]); - - // Root --> gdbhost2. - node = - [[[controller_ cocoaTreeModel] children] objectAtIndex:1]; - EXPECT_NSEQ(@"gdbhost2", [node title]); - EXPECT_EQ(kCocoaCookieDetailsTypeFolder, [node nodeType]); - EXPECT_EQ(1U, [[node children] count]); - - // host1 --> Web Databases. - node = [[node children] lastObject]; - EXPECT_NSEQ(l10n_util::GetNSString(IDS_COOKIES_WEB_DATABASES), [node title]); - EXPECT_EQ(kCocoaCookieDetailsTypeFolder, [node nodeType]); - EXPECT_EQ(1U, [[node children] count]); - - // Database Storage --> db2. - node = [[node children] lastObject]; - EXPECT_NSEQ(@"db2", [node title]); - EXPECT_EQ(kCocoaCookieDetailsTypeTreeDatabase, [node nodeType]); - details = [node details]; - EXPECT_NSEQ(@"description 2", [details databaseDescription]); - EXPECT_TRUE([details lastModified]); - EXPECT_TRUE([details fileSize]); -} - -TEST_F(CookiesWindowControllerTest, CreateLocalStorageNodes) { - TestingProfile* profile = browser_helper_.profile(); - net::CookieMonster* cm = profile->GetCookieMonster(); - cm->SetCookie(GURL("http://google.com"), "A=B"); - cm->SetCookie(GURL("http://dev.chromium.org"), "C=D"); - database_helper_ = new MockBrowsingDataDatabaseHelper(profile); - local_storage_helper_ = new MockBrowsingDataLocalStorageHelper(profile); - local_storage_helper_->AddLocalStorageSamples(); - controller_.reset( - [[CookiesWindowController alloc] initWithProfile:profile - databaseHelper:database_helper_ - storageHelper:local_storage_helper_ - appcacheHelper:appcache_helper_ - indexedDBHelper:indexed_db_helper_]); - local_storage_helper_->Notify(); - - ASSERT_EQ(4U, [[[controller_ cocoaTreeModel] children] count]); - - // Root --> host1. - CocoaCookieTreeNode* node = - [[[controller_ cocoaTreeModel] children] objectAtIndex:2]; - EXPECT_NSEQ(@"host1", [node title]); - EXPECT_EQ(kCocoaCookieDetailsTypeFolder, [node nodeType]); - EXPECT_EQ(1U, [[node children] count]); - - // host1 --> Local Storage. - node = [[node children] lastObject]; - EXPECT_NSEQ(l10n_util::GetNSString(IDS_COOKIES_LOCAL_STORAGE), [node title]); - EXPECT_EQ(kCocoaCookieDetailsTypeFolder, [node nodeType]); - EXPECT_EQ(1U, [[node children] count]); - - // Local Storage --> http://host1:1/. - node = [[node children] lastObject]; - EXPECT_NSEQ(@"http://host1:1/", [node title]); - EXPECT_EQ(kCocoaCookieDetailsTypeTreeLocalStorage, [node nodeType]); - EXPECT_NSEQ(@"http://host1:1/", [[node details] domain]); - EXPECT_TRUE([[node details] lastModified]); - EXPECT_TRUE([[node details] fileSize]); - - // Root --> host2. - node = - [[[controller_ cocoaTreeModel] children] objectAtIndex:3]; - EXPECT_NSEQ(@"host2", [node title]); - EXPECT_EQ(kCocoaCookieDetailsTypeFolder, [node nodeType]); - EXPECT_EQ(1U, [[node children] count]); - - // host2 --> Local Storage. - node = [[node children] lastObject]; - EXPECT_NSEQ(l10n_util::GetNSString(IDS_COOKIES_LOCAL_STORAGE), [node title]); - EXPECT_EQ(kCocoaCookieDetailsTypeFolder, [node nodeType]); - EXPECT_EQ(1U, [[node children] count]); - - // Local Storage --> http://host2:2/. - node = [[node children] lastObject]; - EXPECT_NSEQ(@"http://host2:2/", [node title]); - EXPECT_EQ(kCocoaCookieDetailsTypeTreeLocalStorage, [node nodeType]); - EXPECT_NSEQ(@"http://host2:2/", [[node details] domain]); - EXPECT_TRUE([[node details] lastModified]); - EXPECT_TRUE([[node details] fileSize]); -} - -} // namespace diff --git a/chrome/browser/ui/cocoa/options/custom_home_pages_model.h b/chrome/browser/ui/cocoa/options/custom_home_pages_model.h deleted file mode 100644 index 1b4385a..0000000 --- a/chrome/browser/ui/cocoa/options/custom_home_pages_model.h +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) 2010 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_UI_COCOA_OPTIONS_CUSTOM_HOME_PAGES_MODEL_H_ -#define CHROME_BROWSER_UI_COCOA_OPTIONS_CUSTOM_HOME_PAGES_MODEL_H_ -#pragma once - -#import <Cocoa/Cocoa.h> - -#include <vector> -#include "base/scoped_nsobject.h" -#include "chrome/browser/history/history.h" -#include "googleurl/src/gurl.h" - -class Profile; - -// The model for the "custom home pages" table in preferences. Contains a list -// of CustomHomePageEntry objects. This is intended to be used with Cocoa -// bindings. -// -// The supported binding is |customHomePages|, a to-many relationship which -// can be observed with an array controller. - -@interface CustomHomePagesModel : NSObject { - @private - scoped_nsobject<NSMutableArray> entries_; - Profile* profile_; // weak, used for loading favicons -} - -// Initialize with |profile|, which must not be NULL. The profile is used for -// loading favicons for urls. -- (id)initWithProfile:(Profile*)profile; - -// Get/set the urls the model currently contains as a group. Only one change -// notification will be sent. -- (std::vector<GURL>)URLs; -- (void)setURLs:(const std::vector<GURL>&)urls; - -// Reloads the URLs from their stored state. This will notify using KVO -// |customHomePages|. -- (void)reloadURLs; - -// Validates the set of URLs stored in the model. The user may have input bad -// data. This function removes invalid entries from the model, which will result -// in anyone observing being updated. -- (void)validateURLs; - -// For binding |customHomePages| to a mutable array controller. -- (NSUInteger)countOfCustomHomePages; -- (id)objectInCustomHomePagesAtIndex:(NSUInteger)index; -- (void)insertObject:(id)object inCustomHomePagesAtIndex:(NSUInteger)index; -- (void)removeObjectFromCustomHomePagesAtIndex:(NSUInteger)index; -@end - -//////////////////////////////////////////////////////////////////////////////// - -// An entry representing a single item in the custom home page model. Stores -// a url and a favicon. -@interface CustomHomePageEntry : NSObject { - @private - scoped_nsobject<NSString> url_; - scoped_nsobject<NSImage> icon_; - - // If non-zero, indicates we're loading the favicon for the page. - HistoryService::Handle icon_handle_; -} - -@property(nonatomic, copy) NSString* URL; -@property(nonatomic, retain) NSImage* image; - -@end - -//////////////////////////////////////////////////////////////////////////////// - -@interface CustomHomePagesModel (InternalOrTestingAPI) - -// Clears the URL string at the specified index. This constitutes bad data. The -// validator should scrub the entry from the list the next time it is run. -- (void)setURLStringEmptyAt:(NSUInteger)index; - -@end - -// A notification that fires when the URL of one of the entries changes. -// Prevents interested parties from having to observe all model objects in order -// to persist changes to a single entry. Changes to the number of items in the -// model can be observed by watching |customHomePages| via KVO so an additional -// notification is not sent. -extern NSString* const kHomepageEntryChangedNotification; - -#endif // CHROME_BROWSER_UI_COCOA_OPTIONS_CUSTOM_HOME_PAGES_MODEL_H_ diff --git a/chrome/browser/ui/cocoa/options/custom_home_pages_model.mm b/chrome/browser/ui/cocoa/options/custom_home_pages_model.mm deleted file mode 100644 index 6ee80b6..0000000 --- a/chrome/browser/ui/cocoa/options/custom_home_pages_model.mm +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (c) 2010 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/ui/cocoa/options/custom_home_pages_model.h" - -#include "base/sys_string_conversions.h" -#include "chrome/browser/net/url_fixer_upper.h" -#include "chrome/browser/prefs/session_startup_pref.h" - -NSString* const kHomepageEntryChangedNotification = - @"kHomepageEntryChangedNotification"; - -@interface CustomHomePagesModel (Private) -- (void)setURLsInternal:(const std::vector<GURL>&)urls; -@end - -@implementation CustomHomePagesModel - -- (id)initWithProfile:(Profile*)profile { - if ((self = [super init])) { - profile_ = profile; - entries_.reset([[NSMutableArray alloc] init]); - } - return self; -} - -- (NSUInteger)countOfCustomHomePages { - return [entries_ count]; -} - -- (id)objectInCustomHomePagesAtIndex:(NSUInteger)index { - return [entries_ objectAtIndex:index]; -} - -- (void)insertObject:(id)object inCustomHomePagesAtIndex:(NSUInteger)index { - [entries_ insertObject:object atIndex:index]; -} - -- (void)removeObjectFromCustomHomePagesAtIndex:(NSUInteger)index { - [entries_ removeObjectAtIndex:index]; - // Force a save. - [self validateURLs]; -} - -// Get/set the urls the model currently contains as a group. These will weed -// out any URLs that are empty and not add them to the model. As a result, -// the next time they're persisted to the prefs backend, they'll disappear. -- (std::vector<GURL>)URLs { - std::vector<GURL> urls; - for (CustomHomePageEntry* entry in entries_.get()) { - const char* urlString = [[entry URL] UTF8String]; - if (urlString && std::strlen(urlString)) { - urls.push_back(GURL(std::string(urlString))); - } - } - return urls; -} - -- (void)setURLs:(const std::vector<GURL>&)urls { - [self willChangeValueForKey:@"customHomePages"]; - [self setURLsInternal:urls]; - SessionStartupPref pref(SessionStartupPref::GetStartupPref(profile_)); - pref.urls = urls; - SessionStartupPref::SetStartupPref(profile_, pref); - [self didChangeValueForKey:@"customHomePages"]; -} - -// Converts the C++ URLs to Cocoa objects without notifying KVO. -- (void)setURLsInternal:(const std::vector<GURL>&)urls { - [entries_ removeAllObjects]; - for (size_t i = 0; i < urls.size(); ++i) { - scoped_nsobject<CustomHomePageEntry> entry( - [[CustomHomePageEntry alloc] init]); - const char* urlString = urls[i].spec().c_str(); - if (urlString && std::strlen(urlString)) { - [entry setURL:[NSString stringWithCString:urlString - encoding:NSUTF8StringEncoding]]; - [entries_ addObject:entry]; - } - } -} - -- (void)reloadURLs { - [self willChangeValueForKey:@"customHomePages"]; - SessionStartupPref pref(SessionStartupPref::GetStartupPref(profile_)); - [self setURLsInternal:pref.urls]; - [self didChangeValueForKey:@"customHomePages"]; -} - -- (void)validateURLs { - [self setURLs:[self URLs]]; -} - -- (void)setURLStringEmptyAt:(NSUInteger)index { - // This replaces the data at |index| with an empty (invalid) URL string. - CustomHomePageEntry* entry = [entries_ objectAtIndex:index]; - [entry setURL:[NSString stringWithString:@""]]; -} - -@end - -//--------------------------------------------------------------------------- - -@implementation CustomHomePageEntry - -- (void)setURL:(NSString*)url { - // |url| can be nil if the user cleared the text from the edit field. - if (!url) - url = [NSString stringWithString:@""]; - - // Make sure the url is valid before setting it by fixing it up. - std::string fixedUrl(URLFixerUpper::FixupURL( - base::SysNSStringToUTF8(url), std::string()).possibly_invalid_spec()); - url_.reset([base::SysUTF8ToNSString(fixedUrl) retain]); - - // Broadcast that an individual item has changed. - [[NSNotificationCenter defaultCenter] - postNotificationName:kHomepageEntryChangedNotification object:nil]; - - // TODO(pinkerton): fetch favicon, convert to NSImage http://crbug.com/34642 -} - -- (NSString*)URL { - return url_.get(); -} - -- (void)setImage:(NSImage*)image { - icon_.reset(image); -} - -- (NSImage*)image { - return icon_.get(); -} - -- (NSString*)description { - return url_.get(); -} - -@end diff --git a/chrome/browser/ui/cocoa/options/custom_home_pages_model_unittest.mm b/chrome/browser/ui/cocoa/options/custom_home_pages_model_unittest.mm deleted file mode 100644 index a79615b..0000000 --- a/chrome/browser/ui/cocoa/options/custom_home_pages_model_unittest.mm +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright (c) 2010 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. - -#include "base/scoped_nsobject.h" -#include "chrome/browser/prefs/session_startup_pref.h" -#include "chrome/browser/ui/cocoa/browser_test_helper.h" -#import "chrome/browser/ui/cocoa/options/custom_home_pages_model.h" -#include "testing/gtest/include/gtest/gtest.h" -#import "testing/gtest_mac.h" -#include "testing/platform_test.h" - -// A helper for KVO and NSNotifications. Makes a note that it's been called -// back. -@interface CustomHomePageHelper : NSObject { - @public - BOOL sawNotification_; -} -@end - -@implementation CustomHomePageHelper -- (void)observeValueForKeyPath:(NSString*)keyPath - ofObject:(id)object - change:(NSDictionary*)change - context:(void*)context { - sawNotification_ = YES; -} - -- (void)entryChanged:(NSNotification*)notify { - sawNotification_ = YES; -} -@end - -@interface NSObject () -- (void)setURL:(NSString*)url; -@end - -namespace { - -// Helper that creates an autoreleased entry. -CustomHomePageEntry* MakeEntry(NSString* url) { - CustomHomePageEntry* entry = [[[CustomHomePageEntry alloc] init] autorelease]; - [entry setURL:url]; - return entry; -} - -// Helper that casts from |id| to the Entry type and returns the URL string. -NSString* EntryURL(id entry) { - return [static_cast<CustomHomePageEntry*>(entry) URL]; -} - -class CustomHomePagesModelTest : public PlatformTest { - public: - CustomHomePagesModelTest() { - model_.reset([[CustomHomePagesModel alloc] - initWithProfile:helper_.profile()]); - } - ~CustomHomePagesModelTest() { } - - BrowserTestHelper helper_; - scoped_nsobject<CustomHomePagesModel> model_; -}; - -TEST_F(CustomHomePagesModelTest, Init) { - scoped_nsobject<CustomHomePagesModel> model( - [[CustomHomePagesModel alloc] initWithProfile:helper_.profile()]); -} - -TEST_F(CustomHomePagesModelTest, GetSetURLs) { - // Basic test. - std::vector<GURL> urls; - urls.push_back(GURL("http://www.google.com")); - [model_ setURLs:urls]; - std::vector<GURL> received_urls = [model_.get() URLs]; - EXPECT_EQ(received_urls.size(), 1U); - EXPECT_TRUE(urls[0] == received_urls[0]); - - // Set an empty list, make sure we get back an empty list. - std::vector<GURL> empty; - [model_ setURLs:empty]; - received_urls = [model_.get() URLs]; - EXPECT_EQ(received_urls.size(), 0U); - - // Give it a list with not well-formed URLs and make sure we get back. - // only the good ones. - std::vector<GURL> poorly_formed; - poorly_formed.push_back(GURL("http://www.google.com")); // good - poorly_formed.push_back(GURL("www.google.com")); // bad - poorly_formed.push_back(GURL("www.yahoo.")); // bad - poorly_formed.push_back(GURL("http://www.yahoo.com")); // good - [model_ setURLs:poorly_formed]; - received_urls = [model_.get() URLs]; - EXPECT_EQ(received_urls.size(), 2U); -} - -// Test that we get a KVO notification when called setURLs. -TEST_F(CustomHomePagesModelTest, KVOObserveWhenListChanges) { - scoped_nsobject<CustomHomePageHelper> kvo_helper( - [[CustomHomePageHelper alloc] init]); - [model_ addObserver:kvo_helper - forKeyPath:@"customHomePages" - options:0L - context:NULL]; - EXPECT_FALSE(kvo_helper.get()->sawNotification_); - - std::vector<GURL> urls; - urls.push_back(GURL("http://www.google.com")); - [model_ setURLs:urls]; // Should send kvo change notification. - EXPECT_TRUE(kvo_helper.get()->sawNotification_); - - [model_ removeObserver:kvo_helper forKeyPath:@"customHomePages"]; -} - -// Test the KVO "to-many" bindings for |customHomePages| and the KVO -// notifiation when items are added to and removed from the list. -TEST_F(CustomHomePagesModelTest, KVO) { - EXPECT_EQ([model_ countOfCustomHomePages], 0U); - - scoped_nsobject<CustomHomePageHelper> kvo_helper( - [[CustomHomePageHelper alloc] init]); - [model_ addObserver:kvo_helper - forKeyPath:@"customHomePages" - options:0L - context:NULL]; - EXPECT_FALSE(kvo_helper.get()->sawNotification_); - - // Cheat and insert NSString objects into the array. As long as we don't - // call -URLs, we'll be ok. - [model_ insertObject:MakeEntry(@"www.google.com") inCustomHomePagesAtIndex:0]; - EXPECT_TRUE(kvo_helper.get()->sawNotification_); - [model_ insertObject:MakeEntry(@"www.yahoo.com") inCustomHomePagesAtIndex:1]; - [model_ insertObject:MakeEntry(@"dev.chromium.org") - inCustomHomePagesAtIndex:2]; - EXPECT_EQ([model_ countOfCustomHomePages], 3U); - - EXPECT_NSEQ(@"http://www.yahoo.com/", - EntryURL([model_ objectInCustomHomePagesAtIndex:1])); - - kvo_helper.get()->sawNotification_ = NO; - [model_ removeObjectFromCustomHomePagesAtIndex:1]; - EXPECT_TRUE(kvo_helper.get()->sawNotification_); - EXPECT_EQ([model_ countOfCustomHomePages], 2U); - EXPECT_NSEQ(@"http://dev.chromium.org/", - EntryURL([model_ objectInCustomHomePagesAtIndex:1])); - EXPECT_NSEQ(@"http://www.google.com/", - EntryURL([model_ objectInCustomHomePagesAtIndex:0])); - - [model_ removeObserver:kvo_helper forKeyPath:@"customHomePages"]; -} - -// Test that when individual items are changed that they broadcast a message. -TEST_F(CustomHomePagesModelTest, ModelChangedNotification) { - scoped_nsobject<CustomHomePageHelper> kvo_helper( - [[CustomHomePageHelper alloc] init]); - [[NSNotificationCenter defaultCenter] - addObserver:kvo_helper - selector:@selector(entryChanged:) - name:kHomepageEntryChangedNotification - object:nil]; - - std::vector<GURL> urls; - urls.push_back(GURL("http://www.google.com")); - [model_ setURLs:urls]; - NSObject* entry = [model_ objectInCustomHomePagesAtIndex:0]; - [entry setURL:@"http://www.foo.bar"]; - EXPECT_TRUE(kvo_helper.get()->sawNotification_); - [[NSNotificationCenter defaultCenter] removeObserver:kvo_helper]; -} - -TEST_F(CustomHomePagesModelTest, ReloadURLs) { - scoped_nsobject<CustomHomePageHelper> kvo_helper( - [[CustomHomePageHelper alloc] init]); - [model_ addObserver:kvo_helper - forKeyPath:@"customHomePages" - options:0L - context:NULL]; - EXPECT_FALSE(kvo_helper.get()->sawNotification_); - EXPECT_EQ([model_ countOfCustomHomePages], 0U); - - std::vector<GURL> urls; - urls.push_back(GURL("http://www.google.com")); - SessionStartupPref pref; - pref.urls = urls; - SessionStartupPref::SetStartupPref(helper_.profile(), pref); - - [model_ reloadURLs]; - - EXPECT_TRUE(kvo_helper.get()->sawNotification_); - EXPECT_EQ([model_ countOfCustomHomePages], 1U); - EXPECT_NSEQ(@"http://www.google.com/", - EntryURL([model_ objectInCustomHomePagesAtIndex:0])); - - [model_ removeObserver:kvo_helper.get() forKeyPath:@"customHomePages"]; -} - -} // namespace diff --git a/chrome/browser/ui/cocoa/options/edit_search_engine_cocoa_controller.h b/chrome/browser/ui/cocoa/options/edit_search_engine_cocoa_controller.h deleted file mode 100644 index c4ebb00..0000000 --- a/chrome/browser/ui/cocoa/options/edit_search_engine_cocoa_controller.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2011 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> - -class TemplateURL; - -#import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" -#include "chrome/browser/ui/search_engines/edit_search_engine_controller.h" - -// This controller presents a dialog that allows a user to add or edit a search -// engine. If constructed with a nil |templateURL| then it is an add operation, -// otherwise it will modify the passed URL. A |delegate| is necessary to -// perform the actual database modifications, and should probably be an -// instance of KeywordEditorModelObserver. - -@interface EditSearchEngineCocoaController : - NSWindowController<NSWindowDelegate> { - IBOutlet NSTextField* nameField_; - IBOutlet NSTextField* keywordField_; - IBOutlet NSTextField* urlField_; - IBOutlet NSImageView* nameImage_; - IBOutlet NSImageView* keywordImage_; - IBOutlet NSImageView* urlImage_; - IBOutlet NSButton* doneButton_; - IBOutlet NSTextField* urlDescriptionField_; - IBOutlet NSView* labelContainer_; - IBOutlet NSBox* fieldAndImageContainer_; - - // Refs to the good and bad images used in the interface validation. - scoped_nsobject<NSImage> goodImage_; - scoped_nsobject<NSImage> badImage_; - - Profile* profile_; // weak - const TemplateURL* templateURL_; // weak - scoped_ptr<EditSearchEngineController> controller_; -} - -- (id)initWithProfile:(Profile*)profile - delegate:(EditSearchEngineControllerDelegate*)delegate - templateURL:(const TemplateURL*)url; - -- (IBAction)cancel:(id)sender; -- (IBAction)save:(id)sender; - -@end - -@interface EditSearchEngineCocoaController (ExposedForTesting) -- (BOOL)validateFields; -@end diff --git a/chrome/browser/ui/cocoa/options/edit_search_engine_cocoa_controller.mm b/chrome/browser/ui/cocoa/options/edit_search_engine_cocoa_controller.mm deleted file mode 100644 index a4890a1..0000000 --- a/chrome/browser/ui/cocoa/options/edit_search_engine_cocoa_controller.mm +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright (c) 2010 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/ui/cocoa/options/edit_search_engine_cocoa_controller.h" - -#include "base/logging.h" -#import "base/mac/mac_util.h" -#include "base/string16.h" -#include "base/sys_string_conversions.h" -#include "chrome/browser/search_engines/template_url.h" -#include "grit/app_resources.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" -#include "ui/base/l10n/l10n_util_mac.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/image.h" - -namespace { - -void ShiftOriginY(NSView* view, CGFloat amount) { - NSPoint origin = [view frame].origin; - origin.y += amount; - [view setFrameOrigin:origin]; -} - -} // namespace - -@implementation EditSearchEngineCocoaController - -- (id)initWithProfile:(Profile*)profile - delegate:(EditSearchEngineControllerDelegate*)delegate - templateURL:(const TemplateURL*)url { - DCHECK(profile); - NSString* nibpath = [base::mac::MainAppBundle() - pathForResource:@"EditSearchEngine" - ofType:@"nib"]; - if ((self = [super initWithWindowNibPath:nibpath owner:self])) { - profile_ = profile; - templateURL_ = url; - controller_.reset( - new EditSearchEngineController(templateURL_, delegate, profile_)); - } - return self; -} - -- (void)awakeFromNib { - DCHECK([self window]); - DCHECK_EQ(self, [[self window] delegate]); - - // Make sure the url description field fits the text in it. - CGFloat descriptionShift = [GTMUILocalizerAndLayoutTweaker - sizeToFitFixedWidthTextField:urlDescriptionField_]; - - // Move the label container above the url description. - ShiftOriginY(labelContainer_, descriptionShift); - // There was no way via view containment to use a helper view to move all - // the textfields and images at once, most move them all on their own so - // they stay above the url description. - ShiftOriginY(nameField_, descriptionShift); - ShiftOriginY(keywordField_, descriptionShift); - ShiftOriginY(urlField_, descriptionShift); - ShiftOriginY(nameImage_, descriptionShift); - ShiftOriginY(keywordImage_, descriptionShift); - ShiftOriginY(urlImage_, descriptionShift); - - // Resize the containing box for the name/keyword/url fields/images since it - // also contains the url description (which just grew). - [[fieldAndImageContainer_ contentView] setAutoresizesSubviews:NO]; - NSRect rect = [fieldAndImageContainer_ frame]; - rect.size.height += descriptionShift; - [fieldAndImageContainer_ setFrame:rect]; - [[fieldAndImageContainer_ contentView] setAutoresizesSubviews:YES]; - - // Resize the window. - NSWindow* window = [self window]; - NSSize windowDelta = NSMakeSize(0, descriptionShift); - [GTMUILocalizerAndLayoutTweaker - resizeWindowWithoutAutoResizingSubViews:window - delta:windowDelta]; - - ResourceBundle& bundle = ResourceBundle::GetSharedInstance(); - goodImage_.reset([bundle.GetNativeImageNamed(IDR_INPUT_GOOD) retain]); - badImage_.reset([bundle.GetNativeImageNamed(IDR_INPUT_ALERT) retain]); - if (templateURL_) { - // Defaults to |..._NEW_WINDOW_TITLE|. - [window setTitle:l10n_util::GetNSString( - IDS_SEARCH_ENGINES_EDITOR_EDIT_WINDOW_TITLE)]; - [nameField_ setStringValue: - base::SysUTF16ToNSString(templateURL_->short_name())]; - [keywordField_ setStringValue: - base::SysUTF16ToNSString(templateURL_->keyword())]; - [urlField_ setStringValue: - base::SysUTF16ToNSString(templateURL_->url()->DisplayURL())]; - [urlField_ setEnabled:(templateURL_->prepopulate_id() == 0)]; - } - // When creating a new keyword, this will mark the fields as "invalid" and - // will not let the user save. If this is an edit, then this will set all - // the images to the "valid" state. - [self validateFields]; -} - -// When the window closes, clean ourselves up. -- (void)windowWillClose:(NSNotification*)notif { - [self autorelease]; -} - -// Performs the logic of closing the window. If we are a sheet, then it ends the -// modal session; otherwise, it closes the window. -- (void)doClose { - if ([[self window] isSheet]) { - [NSApp endSheet:[self window]]; - } else { - [[self window] close]; - } -} - -- (IBAction)cancel:(id)sender { - [self doClose]; -} - -- (IBAction)save:(id)sender { - DCHECK([self validateFields]); - string16 title = base::SysNSStringToUTF16([nameField_ stringValue]); - string16 keyword = base::SysNSStringToUTF16([keywordField_ stringValue]); - std::string url = base::SysNSStringToUTF8([urlField_ stringValue]); - controller_->AcceptAddOrEdit(title, keyword, url); - [self doClose]; -} - -// Delegate method for the text fields. - -- (void)controlTextDidChange:(NSNotification*)notif { - [self validateFields]; -} - -- (void)controlTextDidEndEditing:(NSNotification*)notif { - [self validateFields]; -} - -// Private -------------------------------------------------------------------- - -// Sets the appropriate image and tooltip based on a boolean |valid|. -- (void)setIsValid:(BOOL)valid - toolTip:(int)messageID - forImageView:(NSImageView*)imageView - textField:(NSTextField*)textField { - NSImage* image = (valid) ? goodImage_ : badImage_; - [imageView setImage:image]; - - NSString* toolTip = nil; - if (!valid) - toolTip = l10n_util::GetNSString(messageID); - [textField setToolTip:toolTip]; - [imageView setToolTip:toolTip]; -} - -// This sets the image state for all the controls and enables or disables the -// done button. Returns YES if all the fields are valid. -- (BOOL)validateFields { - string16 title = base::SysNSStringToUTF16([nameField_ stringValue]); - BOOL titleValid = controller_->IsTitleValid(title); - [self setIsValid:titleValid - toolTip:IDS_SEARCH_ENGINES_INVALID_TITLE_TT - forImageView:nameImage_ - textField:nameField_]; - - string16 keyword = base::SysNSStringToUTF16([keywordField_ stringValue]); - BOOL keywordValid = controller_->IsKeywordValid(keyword); - [self setIsValid:keywordValid - toolTip:IDS_SEARCH_ENGINES_INVALID_KEYWORD_TT - forImageView:keywordImage_ - textField:keywordField_]; - - std::string url = base::SysNSStringToUTF8([urlField_ stringValue]); - BOOL urlValid = controller_->IsURLValid(url); - [self setIsValid:urlValid - toolTip:IDS_SEARCH_ENGINES_INVALID_URL_TT - forImageView:urlImage_ - textField:urlField_]; - - BOOL isValid = (titleValid && keywordValid && urlValid); - [doneButton_ setEnabled:isValid]; - return isValid; -} - -@end diff --git a/chrome/browser/ui/cocoa/options/edit_search_engine_cocoa_controller_unittest.mm b/chrome/browser/ui/cocoa/options/edit_search_engine_cocoa_controller_unittest.mm deleted file mode 100644 index 90e0a49..0000000 --- a/chrome/browser/ui/cocoa/options/edit_search_engine_cocoa_controller_unittest.mm +++ /dev/null @@ -1,233 +0,0 @@ -// Copyright (c) 2011 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. - -#include "base/scoped_nsobject.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/search_engines/template_url.h" -#include "chrome/browser/ui/cocoa/browser_test_helper.h" -#include "chrome/browser/ui/cocoa/cocoa_test_helper.h" -#import "chrome/browser/ui/cocoa/options/edit_search_engine_cocoa_controller.h" -#include "chrome/test/testing_profile.h" -#include "grit/generated_resources.h" -#include "testing/gtest/include/gtest/gtest.h" -#import "testing/gtest_mac.h" -#include "testing/platform_test.h" -#include "ui/base/l10n/l10n_util_mac.h" - -@interface FakeEditSearchEngineController : EditSearchEngineCocoaController { -} -@property (nonatomic, readonly) NSTextField* nameField; -@property (nonatomic, readonly) NSTextField* keywordField; -@property (nonatomic, readonly) NSTextField* urlField; -@property (nonatomic, readonly) NSImageView* nameImage; -@property (nonatomic, readonly) NSImageView* keywordImage; -@property (nonatomic, readonly) NSImageView* urlImage; -@property (nonatomic, readonly) NSButton* doneButton; -@property (nonatomic, readonly) NSImage* goodImage; -@property (nonatomic, readonly) NSImage* badImage; -@end - -@implementation FakeEditSearchEngineController -@synthesize nameField = nameField_; -@synthesize keywordField = keywordField_; -@synthesize urlField = urlField_; -@synthesize nameImage = nameImage_; -@synthesize keywordImage = keywordImage_; -@synthesize urlImage = urlImage_; -@synthesize doneButton = doneButton_; -- (NSImage*)goodImage { - return goodImage_.get(); -} -- (NSImage*)badImage { - return badImage_.get(); -} -@end - -namespace { - -class EditSearchEngineControllerTest : public CocoaTest { - public: - virtual void SetUp() { - CocoaTest::SetUp(); - TestingProfile* profile = - static_cast<TestingProfile*>(browser_helper_.profile()); - profile->CreateTemplateURLModel(); - controller_ = [[FakeEditSearchEngineController alloc] - initWithProfile:profile - delegate:nil - templateURL:nil]; - } - - virtual void TearDown() { - // Force the window to load so we hit |-awakeFromNib| to register as the - // window's delegate so that the controller can clean itself up in - // |-windowWillClose:|. - ASSERT_TRUE([controller_ window]); - - [controller_ close]; - CocoaTest::TearDown(); - } - - BrowserTestHelper browser_helper_; - FakeEditSearchEngineController* controller_; -}; - -TEST_F(EditSearchEngineControllerTest, ValidImageOriginals) { - EXPECT_FALSE([controller_ goodImage]); - EXPECT_FALSE([controller_ badImage]); - - EXPECT_TRUE([controller_ window]); // Force the window to load. - - EXPECT_TRUE([[controller_ goodImage] isKindOfClass:[NSImage class]]); - EXPECT_TRUE([[controller_ badImage] isKindOfClass:[NSImage class]]); - - // Test window title is set correctly. - NSString* title = l10n_util::GetNSString( - IDS_SEARCH_ENGINES_EDITOR_NEW_WINDOW_TITLE); - EXPECT_NSEQ(title, [[controller_ window] title]); -} - -TEST_F(EditSearchEngineControllerTest, SetImageViews) { - EXPECT_TRUE([controller_ window]); // Force the window to load. - EXPECT_EQ([controller_ badImage], [[controller_ nameImage] image]); - // An empty keyword is not OK. - EXPECT_EQ([controller_ badImage], [[controller_ keywordImage] image]); - EXPECT_EQ([controller_ badImage], [[controller_ urlImage] image]); -} - -// This test ensures that on creating a new keyword, we are in an "invalid" -// state that cannot save. -TEST_F(EditSearchEngineControllerTest, InvalidState) { - EXPECT_TRUE([controller_ window]); // Force window to load. - NSString* toolTip = nil; - EXPECT_FALSE([controller_ validateFields]); - - EXPECT_NSEQ(@"", [[controller_ nameField] stringValue]); - EXPECT_EQ([controller_ badImage], [[controller_ nameImage] image]); - toolTip = l10n_util::GetNSString(IDS_SEARCH_ENGINES_INVALID_TITLE_TT); - EXPECT_NSEQ(toolTip, [[controller_ nameField] toolTip]); - EXPECT_NSEQ(toolTip, [[controller_ nameImage] toolTip]); - - // Keywords can not be empty strings. - EXPECT_NSEQ(@"", [[controller_ keywordField] stringValue]); - EXPECT_EQ([controller_ badImage], [[controller_ keywordImage] image]); - EXPECT_TRUE([[controller_ keywordField] toolTip]); - EXPECT_TRUE([[controller_ keywordImage] toolTip]); - - EXPECT_NSEQ(@"", [[controller_ urlField] stringValue]); - EXPECT_EQ([controller_ badImage], [[controller_ urlImage] image]); - toolTip = l10n_util::GetNSString(IDS_SEARCH_ENGINES_INVALID_URL_TT); - EXPECT_NSEQ(toolTip, [[controller_ urlField] toolTip]); - EXPECT_NSEQ(toolTip, [[controller_ urlImage] toolTip]); -} - -// Tests that the single name field validates. -TEST_F(EditSearchEngineControllerTest, ValidateName) { - EXPECT_TRUE([controller_ window]); // Force window to load. - - EXPECT_EQ([controller_ badImage], [[controller_ nameImage] image]); - EXPECT_FALSE([controller_ validateFields]); - NSString* toolTip = - l10n_util::GetNSString(IDS_SEARCH_ENGINES_INVALID_TITLE_TT); - EXPECT_NSEQ(toolTip, [[controller_ nameField] toolTip]); - EXPECT_NSEQ(toolTip, [[controller_ nameImage] toolTip]); - [[controller_ nameField] setStringValue:@"Test Name"]; - EXPECT_FALSE([controller_ validateFields]); - EXPECT_EQ([controller_ goodImage], [[controller_ nameImage] image]); - EXPECT_FALSE([[controller_ nameField] toolTip]); - EXPECT_FALSE([[controller_ nameImage] toolTip]); - EXPECT_FALSE([[controller_ doneButton] isEnabled]); -} - -// The keyword field is not valid if it is empty. -TEST_F(EditSearchEngineControllerTest, ValidateKeyword) { - EXPECT_TRUE([controller_ window]); // Force window load. - - EXPECT_EQ([controller_ badImage], [[controller_ keywordImage] image]); - EXPECT_FALSE([controller_ validateFields]); - EXPECT_TRUE([[controller_ keywordField] toolTip]); - EXPECT_TRUE([[controller_ keywordImage] toolTip]); - [[controller_ keywordField] setStringValue:@"foobar"]; - EXPECT_FALSE([controller_ validateFields]); - EXPECT_EQ([controller_ goodImage], [[controller_ keywordImage] image]); - EXPECT_FALSE([[controller_ keywordField] toolTip]); - EXPECT_FALSE([[controller_ keywordImage] toolTip]); - EXPECT_FALSE([[controller_ doneButton] isEnabled]); -} - -// Tests that the URL field validates. -TEST_F(EditSearchEngineControllerTest, ValidateURL) { - EXPECT_TRUE([controller_ window]); // Force window to load. - - EXPECT_EQ([controller_ badImage], [[controller_ urlImage] image]); - EXPECT_FALSE([controller_ validateFields]); - NSString* toolTip = - l10n_util::GetNSString(IDS_SEARCH_ENGINES_INVALID_URL_TT); - EXPECT_NSEQ(toolTip, [[controller_ urlField] toolTip]); - EXPECT_NSEQ(toolTip, [[controller_ urlImage] toolTip]); - [[controller_ urlField] setStringValue:@"http://foo-bar.com"]; - EXPECT_FALSE([controller_ validateFields]); - EXPECT_EQ([controller_ goodImage], [[controller_ urlImage] image]); - EXPECT_FALSE([[controller_ urlField] toolTip]); - EXPECT_FALSE([[controller_ urlImage] toolTip]); - EXPECT_FALSE([[controller_ doneButton] isEnabled]); -} - -// Tests that if the user enters all valid data that the UI reflects that -// and that they can save. -TEST_F(EditSearchEngineControllerTest, ValidateFields) { - EXPECT_TRUE([controller_ window]); // Force window to load. - - // State before entering data. - EXPECT_EQ([controller_ badImage], [[controller_ nameImage] image]); - EXPECT_EQ([controller_ badImage], [[controller_ keywordImage] image]); - EXPECT_EQ([controller_ badImage], [[controller_ urlImage] image]); - EXPECT_FALSE([[controller_ doneButton] isEnabled]); - EXPECT_FALSE([controller_ validateFields]); - - [[controller_ nameField] setStringValue:@"Test Name"]; - EXPECT_FALSE([controller_ validateFields]); - EXPECT_EQ([controller_ goodImage], [[controller_ nameImage] image]); - EXPECT_FALSE([[controller_ doneButton] isEnabled]); - - [[controller_ keywordField] setStringValue:@"foobar"]; - EXPECT_FALSE([controller_ validateFields]); - EXPECT_EQ([controller_ goodImage], [[controller_ keywordImage] image]); - EXPECT_FALSE([[controller_ doneButton] isEnabled]); - - // Once the URL is entered, we should have all 3 valid fields. - [[controller_ urlField] setStringValue:@"http://foo-bar.com"]; - EXPECT_TRUE([controller_ validateFields]); - EXPECT_EQ([controller_ goodImage], [[controller_ urlImage] image]); - EXPECT_TRUE([[controller_ doneButton] isEnabled]); -} - -// Tests editing an existing TemplateURL. -TEST_F(EditSearchEngineControllerTest, EditTemplateURL) { - TemplateURL url; - url.set_short_name(ASCIIToUTF16("Foobar")); - url.set_keyword(ASCIIToUTF16("keyword")); - std::string urlString = TemplateURLRef::DisplayURLToURLRef( - ASCIIToUTF16("http://foo-bar.com")); - url.SetURL(urlString, 0, 1); - TestingProfile* profile = browser_helper_.profile(); - FakeEditSearchEngineController *controller = - [[FakeEditSearchEngineController alloc] initWithProfile:profile - delegate:nil - templateURL:&url]; - EXPECT_TRUE([controller window]); - NSString* title = l10n_util::GetNSString( - IDS_SEARCH_ENGINES_EDITOR_EDIT_WINDOW_TITLE); - EXPECT_NSEQ(title, [[controller window] title]); - NSString* nameString = [[controller nameField] stringValue]; - EXPECT_NSEQ(@"Foobar", nameString); - NSString* keywordString = [[controller keywordField] stringValue]; - EXPECT_NSEQ(@"keyword", keywordString); - NSString* urlValueString = [[controller urlField] stringValue]; - EXPECT_NSEQ(@"http://foo-bar.com", urlValueString); - EXPECT_TRUE([controller validateFields]); - [controller close]; -} - -} // namespace diff --git a/chrome/browser/ui/cocoa/options/font_language_settings_controller.h b/chrome/browser/ui/cocoa/options/font_language_settings_controller.h deleted file mode 100644 index 3123cd2..0000000 --- a/chrome/browser/ui/cocoa/options/font_language_settings_controller.h +++ /dev/null @@ -1,94 +0,0 @@ -// 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> - -#import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" -#include "chrome/browser/prefs/pref_member.h" - -class Profile; - -// Used to keep track of which type of font the user is currently selecting. -enum FontSettingType { - FontSettingSerif, - FontSettingSansSerif, - FontSettingFixed -}; - -// Keys for the dictionaries in the |encodings_| array. -extern NSString* const kCharacterInfoEncoding; // NSString value. -extern NSString* const kCharacterInfoName; // NSString value. -extern NSString* const kCharacterInfoID; // NSNumber value. - -// A window controller that allows the user to change the default WebKit fonts -// and language encodings for web pages. This window controller is meant to be -// used as a modal sheet on another window. -@interface FontLanguageSettingsController : NSWindowController - <NSWindowDelegate> { - @private - // The font that we are currently changing. - NSFont* currentFont_; // weak - FontSettingType currentType_; - - IBOutlet NSButton* serifButton_; - IBOutlet NSTextField* serifField_; - scoped_nsobject<NSFont> serifFont_; - IBOutlet NSTextField* serifLabel_; - BOOL changedSerif_; - - IBOutlet NSButton* sansSerifButton_; - IBOutlet NSTextField* sansSerifField_; - scoped_nsobject<NSFont> sansSerifFont_; - IBOutlet NSTextField* sansSerifLabel_; - BOOL changedSansSerif_; - - IBOutlet NSButton* fixedWidthButton_; - IBOutlet NSTextField* fixedWidthField_; - scoped_nsobject<NSFont> fixedWidthFont_; - IBOutlet NSTextField* fixedWidthLabel_; - BOOL changedFixedWidth_; - - // The actual preference members. - StringPrefMember serifName_; - StringPrefMember sansSerifName_; - StringPrefMember fixedWidthName_; - IntegerPrefMember serifSize_; - IntegerPrefMember sansSerifSize_; - IntegerPrefMember fixedWidthSize_; - - // Array of dictionaries that contain the canonical encoding name, human- - // readable name, and the ID. See the constants defined at the top of this - // file for the keys. - scoped_nsobject<NSMutableArray> encodings_; - - IBOutlet NSPopUpButton* encodingsMenu_; - NSInteger defaultEncodingIndex_; - StringPrefMember defaultEncoding_; - BOOL changedEncoding_; - - Profile* profile_; // weak -} - -// Profile cannot be NULL. Caller is responsible for showing the window as a -// modal sheet. -- (id)initWithProfile:(Profile*)profile; - -// Action for all the font changing buttons. This starts the font picker. -- (IBAction)selectFont:(id)sender; - -// Sent by the FontManager after the user has selected a font. -- (void)changeFont:(id)fontManager; - -// Performs the closing of the window. This is used by both the cancel button -// and |-save:| after it persists the settings. -- (IBAction)closeSheet:(id)sender; - -// Persists the new values into the preferences and closes the sheet. -- (IBAction)save:(id)sender; - -// Returns the |encodings_| array. This is used by bindings for KVO/KVC. -- (NSArray*)encodings; - -@end diff --git a/chrome/browser/ui/cocoa/options/font_language_settings_controller.mm b/chrome/browser/ui/cocoa/options/font_language_settings_controller.mm deleted file mode 100644 index 7ee6c29..0000000 --- a/chrome/browser/ui/cocoa/options/font_language_settings_controller.mm +++ /dev/null @@ -1,280 +0,0 @@ -// Copyright (c) 2010 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/ui/cocoa/options/font_language_settings_controller.h" - -#import <Cocoa/Cocoa.h> -#import "base/mac/mac_util.h" -#include "base/sys_string_conversions.h" -#include "chrome/browser/character_encoding.h" -#include "chrome/browser/fonts_languages_window.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/common/pref_names.h" - -NSString* const kCharacterInfoEncoding = @"encoding"; -NSString* const kCharacterInfoName = @"name"; -NSString* const kCharacterInfoID = @"id"; - -void ShowFontsLanguagesWindow(gfx::NativeWindow window, - FontsLanguagesPage page, - Profile* profile) { - NOTIMPLEMENTED(); -} - -@interface FontLanguageSettingsController (Private) -- (void)updateDisplayField:(NSTextField*)field - withFont:(NSFont*)font - withLabel:(NSTextField*)label; -@end - -@implementation FontLanguageSettingsController - -- (id)initWithProfile:(Profile*)profile { - DCHECK(profile); - NSString* nibpath = [base::mac::MainAppBundle() - pathForResource:@"FontLanguageSettings" - ofType:@"nib"]; - if ((self = [super initWithWindowNibPath:nibpath owner:self])) { - profile_ = profile; - - // Convert the name/size preference values to NSFont objects. - serifName_.Init(prefs::kWebKitSerifFontFamily, profile->GetPrefs(), NULL); - serifSize_.Init(prefs::kWebKitDefaultFontSize, profile->GetPrefs(), NULL); - NSString* serif = base::SysUTF8ToNSString(serifName_.GetValue()); - serifFont_.reset( - [[NSFont fontWithName:serif size:serifSize_.GetValue()] retain]); - - sansSerifName_.Init(prefs::kWebKitSansSerifFontFamily, profile->GetPrefs(), - NULL); - sansSerifSize_.Init(prefs::kWebKitDefaultFontSize, profile->GetPrefs(), - NULL); - NSString* sansSerif = base::SysUTF8ToNSString(sansSerifName_.GetValue()); - sansSerifFont_.reset( - [[NSFont fontWithName:sansSerif - size:sansSerifSize_.GetValue()] retain]); - - fixedWidthName_.Init(prefs::kWebKitFixedFontFamily, profile->GetPrefs(), - NULL); - fixedWidthSize_.Init(prefs::kWebKitDefaultFixedFontSize, - profile->GetPrefs(), NULL); - NSString* fixedWidth = base::SysUTF8ToNSString(fixedWidthName_.GetValue()); - fixedWidthFont_.reset( - [[NSFont fontWithName:fixedWidth - size:fixedWidthSize_.GetValue()] retain]); - - // Generate a list of encodings. - NSInteger count = CharacterEncoding::GetSupportCanonicalEncodingCount(); - NSMutableArray* encodings = [NSMutableArray arrayWithCapacity:count]; - for (NSInteger i = 0; i < count; ++i) { - int commandId = CharacterEncoding::GetEncodingCommandIdByIndex(i); - string16 name = CharacterEncoding::\ - GetCanonicalEncodingDisplayNameByCommandId(commandId); - std::string encoding = - CharacterEncoding::GetCanonicalEncodingNameByCommandId(commandId); - NSDictionary* strings = [NSDictionary dictionaryWithObjectsAndKeys: - base::SysUTF16ToNSString(name), kCharacterInfoName, - base::SysUTF8ToNSString(encoding), kCharacterInfoEncoding, - [NSNumber numberWithInt:commandId], kCharacterInfoID, - nil - ]; - [encodings addObject:strings]; - } - - // Sort the encodings. - scoped_nsobject<NSSortDescriptor> sorter( - [[NSSortDescriptor alloc] initWithKey:kCharacterInfoName - ascending:YES]); - NSArray* sorterArray = [NSArray arrayWithObject:sorter.get()]; - encodings_.reset( - [[encodings sortedArrayUsingDescriptors:sorterArray] retain]); - - // Find and set the default encoding. - defaultEncoding_.Init(prefs::kDefaultCharset, profile->GetPrefs(), NULL); - NSString* defaultEncoding = - base::SysUTF8ToNSString(defaultEncoding_.GetValue()); - NSUInteger index = 0; - for (NSDictionary* entry in encodings_.get()) { - NSString* encoding = [entry objectForKey:kCharacterInfoEncoding]; - if ([encoding isEqualToString:defaultEncoding]) { - defaultEncodingIndex_ = index; - break; - } - ++index; - } - - // Register as a KVO observer so we can receive updates when the encoding - // changes. - [self addObserver:self - forKeyPath:@"defaultEncodingIndex_" - options:NSKeyValueObservingOptionNew - context:NULL]; - } - return self; -} - -- (void)dealloc { - [self removeObserver:self forKeyPath:@"defaultEncodingIndex_"]; - [super dealloc]; -} - -- (void)awakeFromNib { - DCHECK([self window]); - [[self window] setDelegate:self]; - - // Set up the font display. - [self updateDisplayField:serifField_ - withFont:serifFont_.get() - withLabel:serifLabel_]; - [self updateDisplayField:sansSerifField_ - withFont:sansSerifFont_.get() - withLabel:sansSerifLabel_]; - [self updateDisplayField:fixedWidthField_ - withFont:fixedWidthFont_.get() - withLabel:fixedWidthLabel_]; -} - -- (void)windowWillClose:(NSNotification*)notif { - [self autorelease]; -} - -- (IBAction)selectFont:(id)sender { - if (sender == serifButton_) { - currentFont_ = serifFont_.get(); - currentType_ = FontSettingSerif; - } else if (sender == sansSerifButton_) { - currentFont_ = sansSerifFont_.get(); - currentType_ = FontSettingSansSerif; - } else if (sender == fixedWidthButton_) { - currentFont_ = fixedWidthFont_.get(); - currentType_ = FontSettingFixed; - } else { - NOTREACHED(); - } - - // Validate whatever editing is currently happening. - if ([[self window] makeFirstResponder:nil]) { - NSFontManager* manager = [NSFontManager sharedFontManager]; - [manager setTarget:self]; - [manager setSelectedFont:currentFont_ isMultiple:NO]; - [manager orderFrontFontPanel:self]; - } -} - -// Called by the font manager when the user has selected a new font. We should -// then persist those changes into the preference system. -- (void)changeFont:(id)fontManager { - switch (currentType_) { - case FontSettingSerif: - serifFont_.reset([[fontManager convertFont:serifFont_] retain]); - [self updateDisplayField:serifField_ - withFont:serifFont_.get() - withLabel:serifLabel_]; - changedSerif_ = YES; - break; - case FontSettingSansSerif: - sansSerifFont_.reset([[fontManager convertFont:sansSerifFont_] retain]); - [self updateDisplayField:sansSerifField_ - withFont:sansSerifFont_.get() - withLabel:sansSerifLabel_]; - changedSansSerif_ = YES; - break; - case FontSettingFixed: - fixedWidthFont_.reset( - [[fontManager convertFont:fixedWidthFont_] retain]); - [self updateDisplayField:fixedWidthField_ - withFont:fixedWidthFont_.get() - withLabel:fixedWidthLabel_]; - changedFixedWidth_ = YES; - break; - default: - NOTREACHED(); - } -} - -- (IBAction)closeSheet:(id)sender { - NSFontPanel* panel = [[NSFontManager sharedFontManager] fontPanel:NO]; - [panel close]; - [NSApp endSheet:[self window]]; -} - -- (IBAction)save:(id)sender { - if (changedSerif_) { - serifName_.SetValue(base::SysNSStringToUTF8([serifFont_ fontName])); - serifSize_.SetValue([serifFont_ pointSize]); - } - if (changedSansSerif_) { - sansSerifName_.SetValue( - base::SysNSStringToUTF8([sansSerifFont_ fontName])); - sansSerifSize_.SetValue([sansSerifFont_ pointSize]); - } - if (changedFixedWidth_) { - fixedWidthName_.SetValue( - base::SysNSStringToUTF8([fixedWidthFont_ fontName])); - fixedWidthSize_.SetValue([fixedWidthFont_ pointSize]); - } - if (changedEncoding_) { - NSDictionary* object = [encodings_ objectAtIndex:defaultEncodingIndex_]; - NSString* newEncoding = [object objectForKey:kCharacterInfoEncoding]; - std::string encoding = base::SysNSStringToUTF8(newEncoding); - defaultEncoding_.SetValue(encoding); - } - [self closeSheet:sender]; -} - -- (NSArray*)encodings { - return encodings_.get(); -} - -// KVO notification. -- (void)observeValueForKeyPath:(NSString*)keyPath - ofObject:(id)object - change:(NSDictionary*)change - context:(void*)context { - // If this is the default encoding, then set the flag to persist the value. - if ([keyPath isEqual:@"defaultEncodingIndex_"]) { - changedEncoding_ = YES; - return; - } - - [super observeValueForKeyPath:keyPath - ofObject:object - change:change - context:context]; -} - -#pragma mark Private - -// Set the baseline for the font field to be aligned with the baseline -// of its corresponding label. -- (NSPoint)getFontFieldOrigin:(NSTextField*)field - forLabel:(NSTextField*)label { - [field sizeToFit]; - NSRect labelFrame = [label frame]; - NSPoint newOrigin = - [[label superview] convertPoint:labelFrame.origin - toView:[field superview]]; - newOrigin.x = 0; // Left-align font field. - newOrigin.y += [[field font] descender] - [[label font] descender]; - return newOrigin; -} - -// This will set the font on |field| to be |font|, and will set the string -// value to something human-readable. -- (void)updateDisplayField:(NSTextField*)field - withFont:(NSFont*)font - withLabel:(NSTextField*)label { - if (!font) { - // Something has gone really wrong. Don't make things worse by showing the - // user "(null)". - return; - } - [field setFont:font]; - NSString* value = - [NSString stringWithFormat:@"%@, %g", [font fontName], [font pointSize]]; - [field setStringValue:value]; - [field setFrameOrigin:[self getFontFieldOrigin:field forLabel:label]]; -} - -@end diff --git a/chrome/browser/ui/cocoa/options/font_language_settings_controller_unittest.mm b/chrome/browser/ui/cocoa/options/font_language_settings_controller_unittest.mm deleted file mode 100644 index 1cac9a0..0000000 --- a/chrome/browser/ui/cocoa/options/font_language_settings_controller_unittest.mm +++ /dev/null @@ -1,91 +0,0 @@ -// 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. - -#include "base/scoped_nsobject.h" -#include "chrome/browser/character_encoding.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/cocoa/browser_test_helper.h" -#import "chrome/browser/ui/cocoa/cocoa_test_helper.h" -#import "chrome/browser/ui/cocoa/options/font_language_settings_controller.h" -#include "testing/gtest/include/gtest/gtest.h" -#import "testing/gtest_mac.h" -#include "testing/platform_test.h" - -// The FontLanguageSettingsControllerForTest overrides the getFontFieldOrigin -// method to provide a dummy point, so we don't have to actually display the -// window to test the controller. -@interface FontLanguageSettingsControllerForTest : - FontLanguageSettingsController { -} - -- (NSPoint)getFontFieldOrigin:(NSTextField*)field - forLabel:(NSTextField*)label; - -@end - -@implementation FontLanguageSettingsControllerForTest - -- (NSPoint)getFontFieldOrigin:(NSTextField*)field - forLabel:(NSTextField*)label { - return NSMakePoint(10, 10); -} - -@end - -@interface FontLanguageSettingsController (Testing) -- (void)updateDisplayField:(NSTextField*)field - withFont:(NSFont*)font - withLabel:(NSTextField*)label; -@end - -class FontLanguageSettingsControllerTest : public CocoaTest { - public: - FontLanguageSettingsControllerTest() { - Profile* profile = helper_.profile(); - font_controller_.reset([[FontLanguageSettingsControllerForTest alloc] - initWithProfile:profile]); - } - ~FontLanguageSettingsControllerTest() {} - - BrowserTestHelper helper_; - scoped_nsobject<FontLanguageSettingsController> font_controller_; -}; - -TEST_F(FontLanguageSettingsControllerTest, Init) { - ASSERT_EQ(CharacterEncoding::GetSupportCanonicalEncodingCount(), - static_cast<int>([[font_controller_ encodings] count])); -} - -TEST_F(FontLanguageSettingsControllerTest, UpdateDisplayField) { - NSFont* font = [NSFont fontWithName:@"Times-Roman" size:12.0]; - scoped_nsobject<NSTextField> field( - [[NSTextField alloc] initWithFrame:NSMakeRect(100, 100, 100, 100)]); - scoped_nsobject<NSTextField> label( - [[NSTextField alloc] initWithFrame:NSMakeRect(100, 100, 100, 100)]); - [font_controller_ updateDisplayField:field.get() - withFont:font - withLabel:label]; - - ASSERT_NSEQ([font fontName], [[field font] fontName]); - ASSERT_NSEQ(@"Times-Roman, 12", [field stringValue]); -} - -TEST_F(FontLanguageSettingsControllerTest, UpdateDisplayFieldNilFont) { - scoped_nsobject<NSTextField> field( - [[NSTextField alloc] initWithFrame:NSMakeRect(100, 100, 100, 100)]); - scoped_nsobject<NSTextField> label( - [[NSTextField alloc] initWithFrame:NSMakeRect(100, 100, 100, 100)]); - [field setStringValue:@"foo"]; - [font_controller_ updateDisplayField:field.get() - withFont:nil - withLabel:label]; - - ASSERT_NSEQ(@"foo", [field stringValue]); -} - -TEST_F(FontLanguageSettingsControllerTest, UpdateDisplayFieldNilField) { - // Don't crash. - NSFont* font = [NSFont fontWithName:@"Times-Roman" size:12.0]; - [font_controller_ updateDisplayField:nil withFont:font withLabel:nil]; -} diff --git a/chrome/browser/ui/cocoa/options/keyword_editor_cocoa_controller.h b/chrome/browser/ui/cocoa/options/keyword_editor_cocoa_controller.h deleted file mode 100644 index f9a949b..0000000 --- a/chrome/browser/ui/cocoa/options/keyword_editor_cocoa_controller.h +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2011 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> - -#import "base/mac/cocoa_protocols.h" -#include "base/scoped_ptr.h" -#include "base/string16.h" -#include "chrome/browser/search_engines/template_url_model_observer.h" -#include "chrome/browser/ui/cocoa/table_row_nsimage_cache.h" -#include "chrome/browser/ui/search_engines/edit_search_engine_controller.h" -#include "chrome/browser/ui/search_engines/keyword_editor_controller.h" -#include "ui/base/models/table_model_observer.h" - -class EditSearchEngineControllerDelegate; -@class KeywordEditorCocoaController; -class Profile; -@class WindowSizeAutosaver; - -// Very thin bridge that simply pushes notifications from C++ to ObjC. -class KeywordEditorModelObserver : public TemplateURLModelObserver, - public EditSearchEngineControllerDelegate, - public ui::TableModelObserver, - public TableRowNSImageCache::Table { - public: - explicit KeywordEditorModelObserver(KeywordEditorCocoaController* controller); - virtual ~KeywordEditorModelObserver(); - - // Notification that the template url model has changed in some way. - virtual void OnTemplateURLModelChanged(); - - // Invoked from the EditSearchEngineController when the user accepts the - // edits. NOTE: |template_url| is the value supplied to - // EditSearchEngineController's constructor, and may be NULL. A NULL value - // indicates a new TemplateURL should be created rather than modifying an - // existing TemplateURL. - virtual void OnEditedKeyword(const TemplateURL* template_url, - const string16& title, - const string16& keyword, - const std::string& url); - - // ui::TableModelObserver overrides. Invalidate icon cache. - virtual void OnModelChanged(); - virtual void OnItemsChanged(int start, int length); - virtual void OnItemsAdded(int start, int length); - virtual void OnItemsRemoved(int start, int length); - - // TableRowNSImageCache::Table - virtual int RowCount() const; - virtual SkBitmap GetIcon(int row) const; - - // Lazily converts the image at the given row and caches it in |icon_cache_|. - NSImage* GetImageForRow(int row); - - private: - KeywordEditorCocoaController* controller_; - - TableRowNSImageCache icon_cache_; - - DISALLOW_COPY_AND_ASSIGN(KeywordEditorModelObserver); -}; - -// This controller manages a window with a table view of search engines. It -// acts as |tableView_|'s data source and delegate, feeding it data from the -// KeywordEditorController's |table_model()|. - -@interface KeywordEditorCocoaController : NSWindowController - <NSWindowDelegate, - NSTableViewDataSource, - NSTableViewDelegate> { - IBOutlet NSTableView* tableView_; - IBOutlet NSButton* addButton_; - IBOutlet NSButton* removeButton_; - IBOutlet NSButton* makeDefaultButton_; - - scoped_nsobject<NSTextFieldCell> groupCell_; - - Profile* profile_; // weak - scoped_ptr<KeywordEditorController> controller_; - scoped_ptr<KeywordEditorModelObserver> observer_; - - scoped_nsobject<WindowSizeAutosaver> sizeSaver_; -} -@property(nonatomic, readonly) KeywordEditorController* controller; - -// Show the keyword editor associated with the given profile (or the -// original profile if this is an incognito profile). If no keyword -// editor exists for this profile, create one and show it. Any -// resulting editor releases itself when closed. -+ (void)showKeywordEditor:(Profile*)profile; - -- (KeywordEditorController*)controller; - -// Message forwarded by KeywordEditorModelObserver. -- (void)modelChanged; - -- (IBAction)addKeyword:(id)sender; -- (IBAction)deleteKeyword:(id)sender; -- (IBAction)makeDefault:(id)sender; - -@end - -@interface KeywordEditorCocoaController (TestingAPI) - -// Instances of this class are managed, use +showKeywordEditor:. -- (id)initWithProfile:(Profile*)profile; - -// Returns a reference to the shared instance for the given profile, -// or nil if there is none. -+ (KeywordEditorCocoaController*)sharedInstanceForProfile:(Profile*)profile; - -// Converts a row index in our table view (which has group header rows) into -// one in the |controller_|'s model, which does not have them. -- (int)indexInModelForRow:(NSUInteger)row; - -@end diff --git a/chrome/browser/ui/cocoa/options/keyword_editor_cocoa_controller.mm b/chrome/browser/ui/cocoa/options/keyword_editor_cocoa_controller.mm deleted file mode 100644 index 3c29a29..0000000 --- a/chrome/browser/ui/cocoa/options/keyword_editor_cocoa_controller.mm +++ /dev/null @@ -1,425 +0,0 @@ -// 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> - -#import "chrome/browser/ui/cocoa/options/keyword_editor_cocoa_controller.h" - -#import "base/mac/mac_util.h" -#include "base/lazy_instance.h" -#include "base/sys_string_conversions.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/search_engines/template_url_model.h" -#import "chrome/browser/ui/cocoa/options/edit_search_engine_cocoa_controller.h" -#import "chrome/browser/ui/cocoa/window_size_autosaver.h" -#include "chrome/browser/ui/search_engines/template_url_table_model.h" -#include "chrome/common/pref_names.h" -#include "grit/generated_resources.h" -#include "skia/ext/skia_utils_mac.h" -#include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" -#include "third_party/skia/include/core/SkBitmap.h" - -namespace { - -const CGFloat kButtonBarHeight = 35.0; - -} // namespace - -@interface KeywordEditorCocoaController (Private) -- (void)adjustEditingButtons; -- (void)editKeyword:(id)sender; -- (int)indexInModelForRow:(NSUInteger)row; -@end - -// KeywordEditorModelObserver ------------------------------------------------- - -KeywordEditorModelObserver::KeywordEditorModelObserver( - KeywordEditorCocoaController* controller) - : controller_(controller), - icon_cache_(this) { -} - -KeywordEditorModelObserver::~KeywordEditorModelObserver() { -} - -// Notification that the template url model has changed in some way. -void KeywordEditorModelObserver::OnTemplateURLModelChanged() { - [controller_ modelChanged]; -} - -void KeywordEditorModelObserver::OnEditedKeyword( - const TemplateURL* template_url, - const string16& title, - const string16& keyword, - const std::string& url) { - KeywordEditorController* controller = [controller_ controller]; - if (template_url) { - controller->ModifyTemplateURL(template_url, title, keyword, url); - } else { - controller->AddTemplateURL(title, keyword, url); - } -} - -void KeywordEditorModelObserver::OnModelChanged() { - icon_cache_.OnModelChanged(); - [controller_ modelChanged]; -} - -void KeywordEditorModelObserver::OnItemsChanged(int start, int length) { - icon_cache_.OnItemsChanged(start, length); - [controller_ modelChanged]; -} - -void KeywordEditorModelObserver::OnItemsAdded(int start, int length) { - icon_cache_.OnItemsAdded(start, length); - [controller_ modelChanged]; -} - -void KeywordEditorModelObserver::OnItemsRemoved(int start, int length) { - icon_cache_.OnItemsRemoved(start, length); - [controller_ modelChanged]; -} - -int KeywordEditorModelObserver::RowCount() const { - return [controller_ controller]->table_model()->RowCount(); -} - -SkBitmap KeywordEditorModelObserver::GetIcon(int row) const { - return [controller_ controller]->table_model()->GetIcon(row); -} - -NSImage* KeywordEditorModelObserver::GetImageForRow(int row) { - return icon_cache_.GetImageForRow(row); -} - -// KeywordEditorCocoaController ----------------------------------------------- - -namespace { - -typedef std::map<Profile*,KeywordEditorCocoaController*> ProfileControllerMap; - -static base::LazyInstance<ProfileControllerMap> g_profile_controller_map( - base::LINKER_INITIALIZED); - -} // namespace - -@implementation KeywordEditorCocoaController - -+ (KeywordEditorCocoaController*)sharedInstanceForProfile:(Profile*)profile { - ProfileControllerMap* map = g_profile_controller_map.Pointer(); - DCHECK(map != NULL); - ProfileControllerMap::iterator it = map->find(profile); - if (it != map->end()) { - return it->second; - } - return nil; -} - -// TODO(shess): The Windows code watches a single global window which -// is not distinguished by profile. This code could distinguish by -// profile by checking the controller's class and profile. -+ (void)showKeywordEditor:(Profile*)profile { - // http://crbug.com/23359 describes a case where this panel is - // opened from an incognito window, which can leave the panel - // holding onto a stale profile. Since the same panel is used - // either way, arrange to use the original profile instead. - profile = profile->GetOriginalProfile(); - - ProfileControllerMap* map = g_profile_controller_map.Pointer(); - DCHECK(map != NULL); - ProfileControllerMap::iterator it = map->find(profile); - if (it == map->end()) { - // Since we don't currently support multiple profiles, this class - // has not been tested against them, so document that assumption. - DCHECK_EQ(map->size(), 0U); - - KeywordEditorCocoaController* controller = - [[self alloc] initWithProfile:profile]; - it = map->insert(std::make_pair(profile, controller)).first; - } - - [it->second showWindow:nil]; -} - -- (id)initWithProfile:(Profile*)profile { - DCHECK(profile); - NSString* nibpath = [base::mac::MainAppBundle() - pathForResource:@"KeywordEditor" - ofType:@"nib"]; - if ((self = [super initWithWindowNibPath:nibpath owner:self])) { - profile_ = profile; - controller_.reset(new KeywordEditorController(profile_)); - observer_.reset(new KeywordEditorModelObserver(self)); - controller_->table_model()->SetObserver(observer_.get()); - controller_->url_model()->AddObserver(observer_.get()); - groupCell_.reset([[NSTextFieldCell alloc] init]); - - if (g_browser_process && g_browser_process->local_state()) { - sizeSaver_.reset([[WindowSizeAutosaver alloc] - initWithWindow:[self window] - prefService:g_browser_process->local_state() - path:prefs::kKeywordEditorWindowPlacement]); - } - } - return self; -} - -- (void)dealloc { - controller_->table_model()->SetObserver(NULL); - controller_->url_model()->RemoveObserver(observer_.get()); - [tableView_ setDataSource:nil]; - observer_.reset(); - [super dealloc]; -} - -- (void)awakeFromNib { - // Make sure the button fits its label, but keep it the same height as the - // other two buttons. - [GTMUILocalizerAndLayoutTweaker sizeToFitView:makeDefaultButton_]; - NSSize size = [makeDefaultButton_ frame].size; - size.height = NSHeight([addButton_ frame]); - [makeDefaultButton_ setFrameSize:size]; - - [[self window] setAutorecalculatesContentBorderThickness:NO - forEdge:NSMinYEdge]; - [[self window] setContentBorderThickness:kButtonBarHeight - forEdge:NSMinYEdge]; - - [self adjustEditingButtons]; - [tableView_ setDoubleAction:@selector(editKeyword:)]; - [tableView_ setTarget:self]; -} - -// When the window closes, clean ourselves up. -- (void)windowWillClose:(NSNotification*)notif { - [self autorelease]; - - ProfileControllerMap* map = g_profile_controller_map.Pointer(); - ProfileControllerMap::iterator it = map->find(profile_); - // It should not be possible for this to be missing. - // TODO(shess): Except that the unit test reaches in directly. - // Consider circling around and refactoring that. - //DCHECK(it != map->end()); - if (it != map->end()) { - map->erase(it); - } -} - -- (void)modelChanged { - [tableView_ reloadData]; - [self adjustEditingButtons]; -} - -- (KeywordEditorController*)controller { - return controller_.get(); -} - -- (void)sheetDidEnd:(NSWindow*)sheet - returnCode:(NSInteger)code - context:(void*)context { - [sheet orderOut:self]; -} - -- (IBAction)addKeyword:(id)sender { - // The controller will release itself when the window closes. - EditSearchEngineCocoaController* editor = - [[EditSearchEngineCocoaController alloc] initWithProfile:profile_ - delegate:observer_.get() - templateURL:NULL]; - [NSApp beginSheet:[editor window] - modalForWindow:[self window] - modalDelegate:self - didEndSelector:@selector(sheetDidEnd:returnCode:context:) - contextInfo:NULL]; -} - -- (void)editKeyword:(id)sender { - const NSInteger clickedRow = [tableView_ clickedRow]; - if (clickedRow < 0 || [self tableView:tableView_ isGroupRow:clickedRow]) - return; - const TemplateURL* url = controller_->GetTemplateURL( - [self indexInModelForRow:clickedRow]); - // The controller will release itself when the window closes. - EditSearchEngineCocoaController* editor = - [[EditSearchEngineCocoaController alloc] initWithProfile:profile_ - delegate:observer_.get() - templateURL:url]; - [NSApp beginSheet:[editor window] - modalForWindow:[self window] - modalDelegate:self - didEndSelector:@selector(sheetDidEnd:returnCode:context:) - contextInfo:NULL]; -} - -- (IBAction)deleteKeyword:(id)sender { - NSIndexSet* selection = [tableView_ selectedRowIndexes]; - DCHECK_GT([selection count], 0U); - NSUInteger index = [selection lastIndex]; - while (index != NSNotFound) { - controller_->RemoveTemplateURL([self indexInModelForRow:index]); - index = [selection indexLessThanIndex:index]; - } -} - -- (IBAction)makeDefault:(id)sender { - NSIndexSet* selection = [tableView_ selectedRowIndexes]; - DCHECK_EQ([selection count], 1U); - int row = [self indexInModelForRow:[selection firstIndex]]; - controller_->MakeDefaultTemplateURL(row); -} - -// Called when the user hits the escape key. Closes the window. -- (void)cancel:(id)sender { - [[self window] performClose:self]; -} - -// Table View Data Source ----------------------------------------------------- - -- (NSInteger)numberOfRowsInTableView:(NSTableView*)table { - int rowCount = controller_->table_model()->RowCount(); - int numGroups = controller_->table_model()->GetGroups().size(); - if ([self tableView:table isGroupRow:rowCount + numGroups - 1]) { - // Don't show a group header with no rows underneath it. - --numGroups; - } - return rowCount + numGroups; -} - -- (id)tableView:(NSTableView*)tv - objectValueForTableColumn:(NSTableColumn*)tableColumn - row:(NSInteger)row { - if ([self tableView:tv isGroupRow:row]) { - DCHECK(!tableColumn); - ui::TableModel::Groups groups = controller_->table_model()->GetGroups(); - if (row == 0) { - return base::SysUTF16ToNSString(groups[0].title); - } else { - return base::SysUTF16ToNSString(groups[1].title); - } - } - - NSString* identifier = [tableColumn identifier]; - if ([identifier isEqualToString:@"name"]) { - // The name column is an NSButtonCell so we can have text and image in the - // same cell. As such, the "object value" for a button cell is either on - // or off, so we always return off so we don't act like a button. - return [NSNumber numberWithInt:NSOffState]; - } - if ([identifier isEqualToString:@"keyword"]) { - // The keyword object value is a normal string. - int index = [self indexInModelForRow:row]; - int columnID = IDS_SEARCH_ENGINES_EDITOR_KEYWORD_COLUMN; - string16 text = controller_->table_model()->GetText(index, columnID); - return base::SysUTF16ToNSString(text); - } - - // And we shouldn't have any other columns... - NOTREACHED(); - return nil; -} - -// Table View Delegate -------------------------------------------------------- - -// When the selection in the table view changes, we need to adjust buttons. -- (void)tableViewSelectionDidChange:(NSNotification*)aNotification { - [self adjustEditingButtons]; -} - -// Disallow selection of the group header rows. -- (BOOL)tableView:(NSTableView*)table shouldSelectRow:(NSInteger)row { - return ![self tableView:table isGroupRow:row]; -} - -- (BOOL)tableView:(NSTableView*)table isGroupRow:(NSInteger)row { - int otherGroupRow = - controller_->table_model()->last_search_engine_index() + 1; - return (row == 0 || row == otherGroupRow); -} - -- (NSCell*)tableView:(NSTableView*)tableView - dataCellForTableColumn:(NSTableColumn*)tableColumn - row:(NSInteger)row { - static const CGFloat kCellFontSize = 12.0; - - // Check to see if we are a grouped row. - if ([self tableView:tableView isGroupRow:row]) { - DCHECK(!tableColumn); // This would violate the group row contract. - return groupCell_.get(); - } - - NSCell* cell = [tableColumn dataCellForRow:row]; - int offsetRow = [self indexInModelForRow:row]; - - // Set the favicon and title for the search engine in the name column. - if ([[tableColumn identifier] isEqualToString:@"name"]) { - DCHECK([cell isKindOfClass:[NSButtonCell class]]); - NSButtonCell* buttonCell = static_cast<NSButtonCell*>(cell); - string16 title = controller_->table_model()->GetText(offsetRow, - IDS_SEARCH_ENGINES_EDITOR_DESCRIPTION_COLUMN); - [buttonCell setTitle:base::SysUTF16ToNSString(title)]; - [buttonCell setImage:observer_->GetImageForRow(offsetRow)]; - [buttonCell setRefusesFirstResponder:YES]; // Don't push in like a button. - [buttonCell setHighlightsBy:NSNoCellMask]; - } - - // The default search engine should be in bold font. - const TemplateURL* defaultEngine = - controller_->url_model()->GetDefaultSearchProvider(); - int rowIndex = controller_->table_model()->IndexOfTemplateURL(defaultEngine); - if (rowIndex == offsetRow) { - [cell setFont:[NSFont boldSystemFontOfSize:kCellFontSize]]; - } else { - [cell setFont:[NSFont systemFontOfSize:kCellFontSize]]; - } - return cell; -} - -// Private -------------------------------------------------------------------- - -// This function appropriately sets the enabled states on the table's editing -// buttons. -- (void)adjustEditingButtons { - NSIndexSet* selection = [tableView_ selectedRowIndexes]; - BOOL canRemove = ([selection count] > 0); - NSUInteger index = [selection firstIndex]; - - // Delete button. - while (canRemove && index != NSNotFound) { - int modelIndex = [self indexInModelForRow:index]; - const TemplateURL& url = - controller_->table_model()->GetTemplateURL(modelIndex); - if (!controller_->CanRemove(&url)) - canRemove = NO; - index = [selection indexGreaterThanIndex:index]; - } - [removeButton_ setEnabled:canRemove]; - - // Make default button. - if ([selection count] != 1) { - [makeDefaultButton_ setEnabled:NO]; - } else { - int row = [self indexInModelForRow:[selection firstIndex]]; - const TemplateURL& url = - controller_->table_model()->GetTemplateURL(row); - [makeDefaultButton_ setEnabled:controller_->CanMakeDefault(&url)]; - } -} - -// This converts a row index in our table view to an index in the model by -// computing the group offsets. -- (int)indexInModelForRow:(NSUInteger)row { - DCHECK_GT(row, 0U); - unsigned otherGroupId = - controller_->table_model()->last_search_engine_index() + 1; - DCHECK_NE(row, otherGroupId); - if (row >= otherGroupId) { - return row - 2; // Other group. - } else { - return row - 1; // Default group. - } -} - -@end diff --git a/chrome/browser/ui/cocoa/options/keyword_editor_cocoa_controller_unittest.mm b/chrome/browser/ui/cocoa/options/keyword_editor_cocoa_controller_unittest.mm deleted file mode 100644 index 8810992..0000000 --- a/chrome/browser/ui/cocoa/options/keyword_editor_cocoa_controller_unittest.mm +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright (c) 2011 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. - -#include "base/mac/scoped_nsautorelease_pool.h" -#include "base/scoped_nsobject.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/search_engines/template_url.h" -#include "chrome/browser/search_engines/template_url_model.h" -#include "chrome/browser/ui/cocoa/browser_test_helper.h" -#include "chrome/browser/ui/cocoa/cocoa_test_helper.h" -#import "chrome/browser/ui/cocoa/options/keyword_editor_cocoa_controller.h" -#include "chrome/test/testing_profile.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -@interface FakeKeywordEditorController : KeywordEditorCocoaController { - @public - BOOL modelChanged_; -} -- (void)modelChanged; -- (BOOL)hasModelChanged; -- (KeywordEditorModelObserver*)observer; -@end - -@implementation FakeKeywordEditorController - -- (void)modelChanged { - modelChanged_ = YES; -} - -- (BOOL)hasModelChanged { - return modelChanged_; -} - -- (KeywordEditorModelObserver*)observer { - return observer_.get(); -} - -- (NSTableView*)tableView { - return tableView_; -} - -@end - -// TODO(rsesek): Figure out a good way to test this class (crbug.com/21640). - -namespace { - -class KeywordEditorCocoaControllerTest : public CocoaTest { - public: - virtual void SetUp() { - CocoaTest::SetUp(); - TestingProfile* profile = - static_cast<TestingProfile*>(browser_helper_.profile()); - profile->CreateTemplateURLModel(); - - controller_ = - [[FakeKeywordEditorController alloc] initWithProfile:profile]; - } - - virtual void TearDown() { - // Force the window to load so we hit |-awakeFromNib| to register as the - // window's delegate so that the controller can clean itself up in - // |-windowWillClose:|. - ASSERT_TRUE([controller_ window]); - - [controller_ close]; - CocoaTest::TearDown(); - } - - // Helper to count the keyword editors. - NSUInteger CountKeywordEditors() { - base::mac::ScopedNSAutoreleasePool pool; - NSUInteger count = 0; - for (NSWindow* window in [NSApp windows]) { - id controller = [window windowController]; - if ([controller isKindOfClass:[KeywordEditorCocoaController class]]) { - ++count; - } - } - return count; - } - - BrowserTestHelper browser_helper_; - FakeKeywordEditorController* controller_; -}; - -TEST_F(KeywordEditorCocoaControllerTest, TestModelChanged) { - EXPECT_FALSE([controller_ hasModelChanged]); - KeywordEditorModelObserver* observer = [controller_ observer]; - observer->OnTemplateURLModelChanged(); - EXPECT_TRUE([controller_ hasModelChanged]); -} - -// Test that +showKeywordEditor brings up the existing editor and -// creates one if needed. -TEST_F(KeywordEditorCocoaControllerTest, ShowKeywordEditor) { - // No outstanding editors. - Profile* profile(browser_helper_.profile()); - KeywordEditorCocoaController* sharedInstance = - [KeywordEditorCocoaController sharedInstanceForProfile:profile]; - EXPECT_TRUE(nil == sharedInstance); - EXPECT_EQ(CountKeywordEditors(), 0U); - - const NSUInteger initial_window_count([[NSApp windows] count]); - - // The window unwinds using -autorelease, so we need to introduce an - // autorelease pool to really test whether it went away or not. - { - base::mac::ScopedNSAutoreleasePool pool; - - // +showKeywordEditor: creates a new controller. - [KeywordEditorCocoaController showKeywordEditor:profile]; - sharedInstance = - [KeywordEditorCocoaController sharedInstanceForProfile:profile]; - EXPECT_TRUE(sharedInstance); - EXPECT_EQ(CountKeywordEditors(), 1U); - - // Another call doesn't create another controller. - [KeywordEditorCocoaController showKeywordEditor:profile]; - EXPECT_TRUE(sharedInstance == - [KeywordEditorCocoaController sharedInstanceForProfile:profile]); - EXPECT_EQ(CountKeywordEditors(), 1U); - - [sharedInstance close]; - } - - // No outstanding editors. - sharedInstance = - [KeywordEditorCocoaController sharedInstanceForProfile:profile]; - EXPECT_TRUE(nil == sharedInstance); - EXPECT_EQ(CountKeywordEditors(), 0U); - - // Windows we created should be gone. - EXPECT_EQ([[NSApp windows] count], initial_window_count); - - // Get a new editor, should be different from the previous one. - [KeywordEditorCocoaController showKeywordEditor:profile]; - KeywordEditorCocoaController* newSharedInstance = - [KeywordEditorCocoaController sharedInstanceForProfile:profile]; - EXPECT_TRUE(sharedInstance != newSharedInstance); - EXPECT_EQ(CountKeywordEditors(), 1U); - [newSharedInstance close]; -} - -TEST_F(KeywordEditorCocoaControllerTest, IndexInModelForRowMixed) { - [controller_ window]; // Force |-awakeFromNib|. - TemplateURLModel* template_model = [controller_ controller]->url_model(); - - // Add a default engine. - TemplateURL* t_url = new TemplateURL(); - t_url->SetURL("http://test1/{searchTerms}", 0, 0); - t_url->set_keyword(ASCIIToUTF16("test1")); - t_url->set_short_name(ASCIIToUTF16("Test1")); - t_url->set_show_in_default_list(true); - template_model->Add(t_url); - - // Add a non-default engine. - t_url = new TemplateURL(); - t_url->SetURL("http://test2/{searchTerms}", 0, 0); - t_url->set_keyword(ASCIIToUTF16("test2")); - t_url->set_short_name(ASCIIToUTF16("Test2")); - t_url->set_show_in_default_list(false); - template_model->Add(t_url); - - // Two headers with a single row underneath each. - NSTableView* table = [controller_ tableView]; - [table reloadData]; - ASSERT_EQ(4, [[controller_ tableView] numberOfRows]); - - // Index 0 is the group header, index 1 should be the first engine. - ASSERT_EQ(0, [controller_ indexInModelForRow:1]); - - // Index 2 should be the group header, so index 3 should be the non-default - // engine. - ASSERT_EQ(1, [controller_ indexInModelForRow:3]); - - ASSERT_TRUE([controller_ tableView:table isGroupRow:0]); - ASSERT_FALSE([controller_ tableView:table isGroupRow:1]); - ASSERT_TRUE([controller_ tableView:table isGroupRow:2]); - ASSERT_FALSE([controller_ tableView:table isGroupRow:3]); - - ASSERT_FALSE([controller_ tableView:table shouldSelectRow:0]); - ASSERT_TRUE([controller_ tableView:table shouldSelectRow:1]); - ASSERT_FALSE([controller_ tableView:table shouldSelectRow:2]); - ASSERT_TRUE([controller_ tableView:table shouldSelectRow:3]); -} - -TEST_F(KeywordEditorCocoaControllerTest, IndexInModelForDefault) { - [controller_ window]; // Force |-awakeFromNib|. - TemplateURLModel* template_model = [controller_ controller]->url_model(); - - // Add 2 default engines. - TemplateURL* t_url = new TemplateURL(); - t_url->SetURL("http://test1/{searchTerms}", 0, 0); - t_url->set_keyword(ASCIIToUTF16("test1")); - t_url->set_short_name(ASCIIToUTF16("Test1")); - t_url->set_show_in_default_list(true); - template_model->Add(t_url); - - t_url = new TemplateURL(); - t_url->SetURL("http://test2/{searchTerms}", 0, 0); - t_url->set_keyword(ASCIIToUTF16("test2")); - t_url->set_short_name(ASCIIToUTF16("Test2")); - t_url->set_show_in_default_list(true); - template_model->Add(t_url); - - // One header and two rows. - NSTableView* table = [controller_ tableView]; - [table reloadData]; - ASSERT_EQ(3, [[controller_ tableView] numberOfRows]); - - // Index 0 is the group header, index 1 should be the first engine. - ASSERT_EQ(0, [controller_ indexInModelForRow:1]); - ASSERT_EQ(1, [controller_ indexInModelForRow:2]); - - ASSERT_TRUE([controller_ tableView:table isGroupRow:0]); - ASSERT_FALSE([controller_ tableView:table isGroupRow:1]); - ASSERT_FALSE([controller_ tableView:table isGroupRow:2]); - - ASSERT_FALSE([controller_ tableView:table shouldSelectRow:0]); - ASSERT_TRUE([controller_ tableView:table shouldSelectRow:1]); - ASSERT_TRUE([controller_ tableView:table shouldSelectRow:2]); -} - -} // namespace diff --git a/chrome/browser/ui/cocoa/options/preferences_window_controller.h b/chrome/browser/ui/cocoa/options/preferences_window_controller.h deleted file mode 100644 index a962cea..0000000 --- a/chrome/browser/ui/cocoa/options/preferences_window_controller.h +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright (c) 2010 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/scoped_ptr.h" -#include "base/scoped_nsobject.h" -#include "chrome/browser/prefs/pref_member.h" -#include "chrome/browser/prefs/pref_set_observer.h" -#include "chrome/browser/prefs/pref_change_registrar.h" -#include "chrome/browser/ui/options/options_window.h" - -namespace PreferencesWindowControllerInternal { -class PrefObserverBridge; -class ManagedPrefsBannerState; -} - -@class CustomHomePagesModel; -@class FontLanguageSettingsController; -class PrefService; -class Profile; -class ProfileSyncService; -@class SearchEngineListModel; -@class VerticalGradientView; -@class WindowSizeAutosaver; - -// A window controller that handles the preferences window. The bulk of the -// work is handled via Cocoa Bindings and getter/setter methods that wrap -// cross-platform PrefMember objects. When prefs change in the back-end -// (that is, outside of this UI), our observer receives a notification and can -// tickle the KVO to update the UI so we are always in sync. The bindings are -// specified in the nib file. Preferences are persisted into the back-end -// as they are changed in the UI, and are thus immediately available even while -// the window is still open. When the window closes, a notification is sent -// via the system NotificationCenter. This can be used as a signal to -// release this controller, as it's likely the client wants to enforce there -// only being one (we don't do that internally as it makes it very difficult -// to unit test). -@interface PreferencesWindowController : NSWindowController { - @private - Profile* profile_; // weak ref - OptionsPage initialPage_; - PrefService* prefs_; // weak ref - Obtained from profile_ for convenience. - // weak ref - Also obtained from profile_ for convenience. May be NULL. - ProfileSyncService* syncService_; - scoped_ptr<PreferencesWindowControllerInternal::PrefObserverBridge> - observer_; // Watches for pref changes. - PrefChangeRegistrar registrar_; // Manages pref change observer registration. - scoped_nsobject<WindowSizeAutosaver> sizeSaver_; - NSView* currentPrefsView_; // weak ref - current prefs page view. - scoped_ptr<PreferencesWindowControllerInternal::ManagedPrefsBannerState> - bannerState_; - BOOL managedPrefsBannerVisible_; - - IBOutlet NSToolbar* toolbar_; - IBOutlet VerticalGradientView* managedPrefsBannerView_; - IBOutlet NSImageView* managedPrefsBannerWarningImage_; - - // The views we'll rotate through - IBOutlet NSView* basicsView_; - IBOutlet NSView* personalStuffView_; - IBOutlet NSView* underTheHoodView_; - // The last page the user was on when they opened the Options window. - IntegerPrefMember lastSelectedPage_; - - // The groups of the Basics view for layout fixup. - IBOutlet NSArray* basicsGroupStartup_; - IBOutlet NSArray* basicsGroupHomePage_; - IBOutlet NSArray* basicsGroupToolbar_; - IBOutlet NSArray* basicsGroupSearchEngine_; - IBOutlet NSArray* basicsGroupDefaultBrowser_; - - // The groups of the Personal Stuff view for layout fixup. - IBOutlet NSArray* personalStuffGroupSync_; - IBOutlet NSArray* personalStuffGroupPasswords_; - IBOutlet NSArray* personalStuffGroupAutofill_; - IBOutlet NSArray* personalStuffGroupBrowserData_; - IBOutlet NSArray* personalStuffGroupThemes_; - - // Having two animations around is bad (they fight), so just use one. - scoped_nsobject<NSViewAnimation> animation_; - - IBOutlet NSArrayController* customPagesArrayController_; - - // Basics panel - IntegerPrefMember restoreOnStartup_; - scoped_nsobject<CustomHomePagesModel> customPagesSource_; - BooleanPrefMember newTabPageIsHomePage_; - StringPrefMember homepage_; - BooleanPrefMember showHomeButton_; - BooleanPrefMember instantEnabled_; - IBOutlet NSButton* instantCheckbox_; - scoped_nsobject<SearchEngineListModel> searchEngineModel_; - BooleanPrefMember default_browser_policy_; - // Used when creating a new home page url to make the new cell editable. - BOOL pendingSelectForEdit_; - BOOL restoreButtonsEnabled_; - BOOL restoreURLsEnabled_; - BOOL showHomeButtonEnabled_; - BOOL defaultSearchEngineEnabled_; - - // User Data panel - BooleanPrefMember askSavePasswords_; - BooleanPrefMember autoFillEnabled_; - IBOutlet NSButton* autoFillSettingsButton_; - IBOutlet NSButton* syncButton_; - IBOutlet NSButton* syncCustomizeButton_; - IBOutlet NSTextField* syncStatus_; - IBOutlet NSButton* syncLink_; - IBOutlet NSButton* privacyDashboardLink_; - scoped_nsobject<NSColor> syncStatusNoErrorBackgroundColor_; - scoped_nsobject<NSColor> syncLinkNoErrorBackgroundColor_; - scoped_nsobject<NSColor> syncErrorBackgroundColor_; - BOOL passwordManagerChoiceEnabled_; - BOOL passwordManagerButtonEnabled_; - BOOL autoFillSettingsButtonEnabled_; - - // Under the hood panel - IBOutlet NSView* underTheHoodContentView_; - IBOutlet NSScrollView* underTheHoodScroller_; - IBOutlet NSButton* contentSettingsButton_; - IBOutlet NSButton* clearDataButton_; - BooleanPrefMember alternateErrorPages_; - BooleanPrefMember useSuggest_; - BooleanPrefMember dnsPrefetch_; - BooleanPrefMember safeBrowsing_; - BooleanPrefMember metricsReporting_; - IBOutlet NSPathControl* downloadLocationControl_; - IBOutlet NSButton* downloadLocationButton_; - StringPrefMember defaultDownloadLocation_; - BooleanPrefMember askForSaveLocation_; - IBOutlet NSButton* resetFileHandlersButton_; - StringPrefMember autoOpenFiles_; - BooleanPrefMember translateEnabled_; - BooleanPrefMember tabsToLinks_; - FontLanguageSettingsController* fontLanguageSettings_; - StringPrefMember currentTheme_; - IBOutlet NSButton* enableLoggingCheckbox_; - scoped_ptr<PrefSetObserver> proxyPrefs_; - BOOL showAlternateErrorPagesEnabled_; - BOOL useSuggestEnabled_; - BOOL dnsPrefetchEnabled_; - BOOL safeBrowsingEnabled_; - BOOL metricsReportingEnabled_; - BOOL downloadLocationEnabled_; - BOOL proxiesConfigureButtonEnabled_; -} - -// Usable from cocoa bindings to hook up the custom home pages table. -@property(nonatomic, readonly) CustomHomePagesModel* customPagesSource; - -// Properties for the enabled state of various UI elements. Keep these ordered -// by occurrence on the dialog. -@property(nonatomic) BOOL restoreButtonsEnabled; -@property(nonatomic) BOOL restoreURLsEnabled; -@property(nonatomic) BOOL showHomeButtonEnabled; -@property(nonatomic) BOOL defaultSearchEngineEnabled; -@property(nonatomic) BOOL passwordManagerChoiceEnabled; -@property(nonatomic) BOOL passwordManagerButtonEnabled; -@property(nonatomic) BOOL autoFillSettingsButtonEnabled; -@property(nonatomic) BOOL showAlternateErrorPagesEnabled; -@property(nonatomic) BOOL useSuggestEnabled; -@property(nonatomic) BOOL dnsPrefetchEnabled; -@property(nonatomic) BOOL safeBrowsingEnabled; -@property(nonatomic) BOOL metricsReportingEnabled; -@property(nonatomic) BOOL downloadLocationEnabled; -@property(nonatomic) BOOL proxiesConfigureButtonEnabled; - -// Designated initializer. |profile| should not be NULL. -- (id)initWithProfile:(Profile*)profile initialPage:(OptionsPage)initialPage; - -// Show the preferences window. -- (void)showPreferences:(id)sender; - -// Switch to the given preference page. -- (void)switchToPage:(OptionsPage)page animate:(BOOL)animate; - -// Enables or disables the restoreOnStartup elements -- (void) setEnabledStateOfRestoreOnStartup; - -// IBAction methods for responding to user actions. - -// Basics panel -- (IBAction)addHomepage:(id)sender; -- (IBAction)removeSelectedHomepages:(id)sender; -- (IBAction)useCurrentPagesAsHomepage:(id)sender; -- (IBAction)manageSearchEngines:(id)sender; -- (IBAction)toggleInstant:(id)sender; -- (IBAction)learnMoreAboutInstant:(id)sender; -- (IBAction)makeDefaultBrowser:(id)sender; - -// User Data panel -- (IBAction)doSyncAction:(id)sender; -- (IBAction)doSyncCustomize:(id)sender; -- (IBAction)doSyncReauthentication:(id)sender; -- (IBAction)showPrivacyDashboard:(id)sender; -- (IBAction)showSavedPasswords:(id)sender; -- (IBAction)showAutoFillSettings:(id)sender; -- (IBAction)importData:(id)sender; -- (IBAction)resetThemeToDefault:(id)sender; -- (IBAction)themesGallery:(id)sender; - -// Under the hood -- (IBAction)showContentSettings:(id)sender; -- (IBAction)clearData:(id)sender; -- (IBAction)privacyLearnMore:(id)sender; -- (IBAction)browseDownloadLocation:(id)sender; -- (IBAction)resetAutoOpenFiles:(id)sender; -- (IBAction)changeFontAndLanguageSettings:(id)sender; -- (IBAction)openProxyPreferences:(id)sender; -- (IBAction)showCertificates:(id)sender; -- (IBAction)resetToDefaults:(id)sender; - -// When a toolbar button is clicked -- (IBAction)toolbarButtonSelected:(id)sender; - -@end - -@interface PreferencesWindowController(Testing) - -- (IntegerPrefMember*)lastSelectedPage; -- (NSToolbar*)toolbar; -- (NSView*)basicsView; -- (NSView*)personalStuffView; -- (NSView*)underTheHoodView; - -// Converts the given OptionsPage value (which may be OPTIONS_PAGE_DEFAULT) -// into a concrete OptionsPage value. -- (OptionsPage)normalizePage:(OptionsPage)page; - -// Returns the toolbar item corresponding to the given page. Should be -// called only after awakeFromNib is. -- (NSToolbarItem*)getToolbarItemForPage:(OptionsPage)page; - -// Returns the (normalized) page corresponding to the given toolbar item. -// Should be called only after awakeFromNib is. -- (OptionsPage)getPageForToolbarItem:(NSToolbarItem*)toolbarItem; - -// Returns the view corresponding to the given page. Should be called -// only after awakeFromNib is. -- (NSView*)getPrefsViewForPage:(OptionsPage)page; - -@end diff --git a/chrome/browser/ui/cocoa/options/preferences_window_controller.mm b/chrome/browser/ui/cocoa/options/preferences_window_controller.mm deleted file mode 100644 index 14baa89..0000000 --- a/chrome/browser/ui/cocoa/options/preferences_window_controller.mm +++ /dev/null @@ -1,2177 +0,0 @@ -// Copyright (c) 2011 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/ui/cocoa/options/preferences_window_controller.h" - -#include <algorithm> - -#include "base/logging.h" -#include "base/mac/mac_util.h" -#include "base/mac/scoped_aedesc.h" -#include "base/string16.h" -#include "base/string_util.h" -#include "base/sys_string_conversions.h" -#include "chrome/browser/autofill/autofill_dialog.h" -#include "chrome/browser/autofill/autofill_type.h" -#include "chrome/browser/autofill/personal_data_manager.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/download/download_manager.h" -#include "chrome/browser/download/download_prefs.h" -#include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/google/google_util.h" -#include "chrome/browser/instant/instant_confirm_dialog.h" -#include "chrome/browser/instant/instant_controller.h" -#include "chrome/browser/metrics/metrics_service.h" -#include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/net/url_fixer_upper.h" -#include "chrome/browser/policy/managed_prefs_banner_base.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/prefs/session_startup_pref.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/safe_browsing/safe_browsing_service.h" -#include "chrome/browser/shell_integration.h" -#include "chrome/browser/sync/profile_sync_service.h" -#include "chrome/browser/sync/sync_ui_util.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_list.h" -#import "chrome/browser/ui/cocoa/clear_browsing_data_controller.h" -#import "chrome/browser/ui/cocoa/importer/import_dialog_cocoa.h" -#import "chrome/browser/ui/cocoa/l10n_util.h" -#import "chrome/browser/ui/cocoa/options/content_settings_dialog_controller.h" -#import "chrome/browser/ui/cocoa/options/custom_home_pages_model.h" -#import "chrome/browser/ui/cocoa/options/font_language_settings_controller.h" -#import "chrome/browser/ui/cocoa/options/keyword_editor_cocoa_controller.h" -#import "chrome/browser/ui/cocoa/options/search_engine_list_model.h" -#import "chrome/browser/ui/cocoa/vertical_gradient_view.h" -#import "chrome/browser/ui/cocoa/window_size_autosaver.h" -#include "chrome/browser/ui/options/options_util.h" -#include "chrome/browser/ui/options/options_window.h" -#include "chrome/browser/ui/options/show_options_url.h" -#include "chrome/common/notification_details.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_type.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/url_constants.h" -#include "chrome/installer/util/google_update_settings.h" -#include "content/browser/renderer_host/resource_dispatcher_host.h" -#include "content/browser/tab_contents/tab_contents.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "grit/theme_resources.h" -#import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" -#import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/l10n/l10n_util_mac.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/image.h" - -namespace { - -// Colors for the managed preferences warning banner. -static const double kBannerGradientColorTop[3] = - {255.0 / 255.0, 242.0 / 255.0, 183.0 / 255.0}; -static const double kBannerGradientColorBottom[3] = - {250.0 / 255.0, 230.0 / 255.0, 145.0 / 255.0}; -static const double kBannerStrokeColor = 135.0 / 255.0; - -// Tag id for retrieval via viewWithTag in NSView (from IB). -static const uint32 kBasicsStartupPageTableTag = 1000; - -bool IsNewTabUIURLString(const GURL& url) { - return url == GURL(chrome::kChromeUINewTabURL); -} - -// Helper that sizes two buttons to fit in a row keeping their spacing, returns -// the total horizontal size change. -CGFloat SizeToFitButtonPair(NSButton* leftButton, NSButton* rightButton) { - CGFloat widthShift = 0.0; - - NSSize delta = [GTMUILocalizerAndLayoutTweaker sizeToFitView:leftButton]; - DCHECK_EQ(delta.height, 0.0) << "Height changes unsupported"; - widthShift += delta.width; - - if (widthShift != 0.0) { - NSPoint origin = [rightButton frame].origin; - origin.x += widthShift; - [rightButton setFrameOrigin:origin]; - } - delta = [GTMUILocalizerAndLayoutTweaker sizeToFitView:rightButton]; - DCHECK_EQ(delta.height, 0.0) << "Height changes unsupported"; - widthShift += delta.width; - - return widthShift; -} - -// The different behaviors for the "pref group" auto sizing. -enum AutoSizeGroupBehavior { - kAutoSizeGroupBehaviorVerticalToFit, - kAutoSizeGroupBehaviorVerticalFirstToFit, - kAutoSizeGroupBehaviorHorizontalToFit, - kAutoSizeGroupBehaviorHorizontalFirstGrows, - kAutoSizeGroupBehaviorFirstTwoAsRowVerticalToFit -}; - -// Helper to tweak the layout of the "pref groups" and also ripple any height -// changes from one group to the next groups' origins. -// |views| is an ordered list of views with first being the label for the -// group and the rest being top down or left to right ordering of the views. -// The label is assumed to already be the same height as all the views it is -// next too. -CGFloat AutoSizeGroup(NSArray* views, AutoSizeGroupBehavior behavior, - CGFloat verticalShift) { - DCHECK_GE([views count], 2U) << "Should be at least a label and a control"; - NSTextField* label = [views objectAtIndex:0]; - DCHECK([label isKindOfClass:[NSTextField class]]) - << "First view should be the label for the group"; - - // Auto size the label to see if we need more vertical space for its localized - // string. - CGFloat labelHeightChange = - [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:label]; - - CGFloat localVerticalShift = 0.0; - switch (behavior) { - case kAutoSizeGroupBehaviorVerticalToFit: { - // Walk bottom up doing the sizing and moves. - for (NSUInteger index = [views count] - 1; index > 0; --index) { - NSView* view = [views objectAtIndex:index]; - NSSize delta = cocoa_l10n_util::WrapOrSizeToFit(view); - DCHECK_GE(delta.height, 0.0) << "Should NOT shrink in height"; - if (localVerticalShift) { - NSPoint origin = [view frame].origin; - origin.y += localVerticalShift; - [view setFrameOrigin:origin]; - } - localVerticalShift += delta.height; - } - break; - } - case kAutoSizeGroupBehaviorVerticalFirstToFit: { - // Just size the top one. - NSView* view = [views objectAtIndex:1]; - NSSize delta = cocoa_l10n_util::WrapOrSizeToFit(view); - DCHECK_GE(delta.height, 0.0) << "Should NOT shrink in height"; - localVerticalShift += delta.height; - break; - } - case kAutoSizeGroupBehaviorHorizontalToFit: { - // Walk left to right doing the sizing and moves. - // NOTE: Don't worry about vertical, assume it always fits. - CGFloat horizontalShift = 0.0; - NSUInteger count = [views count]; - for (NSUInteger index = 1; index < count; ++index) { - NSView* view = [views objectAtIndex:index]; - NSSize delta = cocoa_l10n_util::WrapOrSizeToFit(view); - DCHECK_GE(delta.height, 0.0) << "Should NOT shrink in height"; - if (horizontalShift) { - NSPoint origin = [view frame].origin; - origin.x += horizontalShift; - [view setFrameOrigin:origin]; - } - horizontalShift += delta.width; - } - break; - } - case kAutoSizeGroupBehaviorHorizontalFirstGrows: { - // Walk right to left doing the sizing and moves, then apply the space - // collected into the first. - // NOTE: Don't worry about vertical, assume it always all fits. - CGFloat horizontalShift = 0.0; - for (NSUInteger index = [views count] - 1; index > 1; --index) { - NSView* view = [views objectAtIndex:index]; - NSSize delta = cocoa_l10n_util::WrapOrSizeToFit(view); - DCHECK_GE(delta.height, 0.0) << "Should NOT shrink in height"; - horizontalShift -= delta.width; - NSPoint origin = [view frame].origin; - origin.x += horizontalShift; - [view setFrameOrigin:origin]; - } - if (horizontalShift) { - NSView* view = [views objectAtIndex:1]; - NSSize delta = NSMakeSize(horizontalShift, 0.0); - [GTMUILocalizerAndLayoutTweaker - resizeViewWithoutAutoResizingSubViews:view - delta:delta]; - } - break; - } - case kAutoSizeGroupBehaviorFirstTwoAsRowVerticalToFit: { - // Start out like kAutoSizeGroupBehaviorVerticalToFit but don't do - // the first two. Then handle the two as a row, but apply any - // vertical shift. - // All but the first two (in the row); walk bottom up. - for (NSUInteger index = [views count] - 1; index > 2; --index) { - NSView* view = [views objectAtIndex:index]; - NSSize delta = cocoa_l10n_util::WrapOrSizeToFit(view); - DCHECK_GE(delta.height, 0.0) << "Should NOT shrink in height"; - if (localVerticalShift) { - NSPoint origin = [view frame].origin; - origin.y += localVerticalShift; - [view setFrameOrigin:origin]; - } - localVerticalShift += delta.height; - } - // Deal with the two for the horizontal row. Size the second one. - CGFloat horizontalShift = 0.0; - NSView* view = [views objectAtIndex:2]; - NSSize delta = cocoa_l10n_util::WrapOrSizeToFit(view); - DCHECK_GE(delta.height, 0.0) << "Should NOT shrink in height"; - horizontalShift -= delta.width; - NSPoint origin = [view frame].origin; - origin.x += horizontalShift; - if (localVerticalShift) { - origin.y += localVerticalShift; - } - [view setFrameOrigin:origin]; - // Now expand the first item in the row to consume the space opened up. - view = [views objectAtIndex:1]; - if (horizontalShift) { - NSSize delta = NSMakeSize(horizontalShift, 0.0); - [GTMUILocalizerAndLayoutTweaker - resizeViewWithoutAutoResizingSubViews:view - delta:delta]; - } - // And move it up by any amount needed from the previous items. - if (localVerticalShift) { - NSPoint origin = [view frame].origin; - origin.y += localVerticalShift; - [view setFrameOrigin:origin]; - } - break; - } - default: - NOTREACHED(); - break; - } - - // If the label grew more then the views, the other views get an extra shift. - // Otherwise, move the label to its top is aligned with the other views. - CGFloat nonLabelShift = 0.0; - if (labelHeightChange > localVerticalShift) { - // Since the lable is taller, centering the other views looks best, just - // shift the views by 1/2 of the size difference. - nonLabelShift = (labelHeightChange - localVerticalShift) / 2.0; - } else { - NSPoint origin = [label frame].origin; - origin.y += localVerticalShift - labelHeightChange; - [label setFrameOrigin:origin]; - } - - // Apply the input shift requested along with any the shift from label being - // taller then the rest of the group. - for (NSView* view in views) { - NSPoint origin = [view frame].origin; - origin.y += verticalShift; - if (view != label) { - origin.y += nonLabelShift; - } - [view setFrameOrigin:origin]; - } - - // Return how much the group grew. - return localVerticalShift + nonLabelShift; -} - -// Helper to remove a view and move everything above it down to take over the -// space. -void RemoveViewFromView(NSView* view, NSView* toRemove) { - // Sort bottom up so we can spin over what is above it. - NSArray* views = - [[view subviews] sortedArrayUsingFunction:cocoa_l10n_util::CompareFrameY - context:NULL]; - - // Find where |toRemove| was. - NSUInteger index = [views indexOfObject:toRemove]; - DCHECK_NE(index, NSNotFound); - NSUInteger count = [views count]; - CGFloat shrinkHeight = 0; - if (index < (count - 1)) { - // If we're not the topmost control, the amount to shift is the bottom of - // |toRemove| to the bottom of the view above it. - CGFloat shiftDown = - NSMinY([[views objectAtIndex:index + 1] frame]) - - NSMinY([toRemove frame]); - - // Now cycle over the views above it moving them down. - for (++index; index < count; ++index) { - NSView* view = [views objectAtIndex:index]; - NSPoint origin = [view frame].origin; - origin.y -= shiftDown; - [view setFrameOrigin:origin]; - } - - shrinkHeight = shiftDown; - } else if (index > 0) { - // If we're the topmost control, there's nothing to shift but we want to - // shrink until the top edge of the second-topmost control, unless it is - // actually higher than the topmost control (since we're sorting by the - // bottom edge). - shrinkHeight = std::max(0.f, - NSMaxY([toRemove frame]) - - NSMaxY([[views objectAtIndex:index - 1] frame])); - } - // If we only have one control, don't do any resizing (for now). - - // Remove |toRemove|. - [toRemove removeFromSuperview]; - - [GTMUILocalizerAndLayoutTweaker - resizeViewWithoutAutoResizingSubViews:view - delta:NSMakeSize(0, -shrinkHeight)]; -} - -// Simply removes all the views in |toRemove|. -void RemoveGroupFromView(NSView* view, NSArray* toRemove) { - for (NSView* viewToRemove in toRemove) { - RemoveViewFromView(view, viewToRemove); - } -} - -// Helper to tweak the layout of the "Under the Hood" content by autosizing all -// the views and moving things up vertically. Special case the two controls for -// download location as they are horizontal, and should fill the row. Special -// case "Content Settings" and "Clear browsing data" as they are horizontal as -// well. -CGFloat AutoSizeUnderTheHoodContent(NSView* view, - NSPathControl* downloadLocationControl, - NSButton* downloadLocationButton) { - CGFloat verticalShift = 0.0; - - // Loop bottom up through the views sizing and shifting. - NSArray* views = - [[view subviews] sortedArrayUsingFunction:cocoa_l10n_util::CompareFrameY - context:NULL]; - for (NSView* view in views) { - NSSize delta = cocoa_l10n_util::WrapOrSizeToFit(view); - DCHECK_GE(delta.height, 0.0) << "Should NOT shrink in height"; - if (verticalShift) { - NSPoint origin = [view frame].origin; - origin.y += verticalShift; - [view setFrameOrigin:origin]; - } - verticalShift += delta.height; - - // The Download Location controls go in a row with the button aligned to the - // right edge and the path control using all the rest of the space. - if (view == downloadLocationButton) { - NSPoint origin = [downloadLocationButton frame].origin; - origin.x -= delta.width; - [downloadLocationButton setFrameOrigin:origin]; - NSSize controlSize = [downloadLocationControl frame].size; - controlSize.width -= delta.width; - [downloadLocationControl setFrameSize:controlSize]; - } - } - - return verticalShift; -} - -} // namespace - -//------------------------------------------------------------------------- - -@interface PreferencesWindowController(Private) -// Callback when preferences are changed. |prefName| is the name of the -// pref that has changed. -- (void)prefChanged:(std::string*)prefName; -// Callback when sync state has changed. syncService_ needs to be -// queried to find out what happened. -- (void)syncStateChanged; -// Record the user performed a certain action and save the preferences. -- (void)recordUserAction:(const UserMetricsAction&) action; -- (void)registerPrefObservers; -- (void)configureInstant; - -// KVC setter methods. -- (void)setNewTabPageIsHomePageIndex:(NSInteger)val; -- (void)setHomepageURL:(NSString*)urlString; -- (void)setRestoreOnStartupIndex:(NSInteger)type; -- (void)setShowHomeButton:(BOOL)value; -- (void)setPasswordManagerEnabledIndex:(NSInteger)value; -- (void)setIsUsingDefaultTheme:(BOOL)value; -- (void)setShowAlternateErrorPages:(BOOL)value; -- (void)setUseSuggest:(BOOL)value; -- (void)setDnsPrefetch:(BOOL)value; -- (void)setSafeBrowsing:(BOOL)value; -- (void)setMetricsReporting:(BOOL)value; -- (void)setAskForSaveLocation:(BOOL)value; -- (void)setFileHandlerUIEnabled:(BOOL)value; -- (void)setTranslateEnabled:(BOOL)value; -- (void)setTabsToLinks:(BOOL)value; -- (void)displayPreferenceViewForPage:(OptionsPage)page - animate:(BOOL)animate; -- (void)resetSubViews; -- (void)initBannerStateForPage:(OptionsPage)page; - -// KVC getter methods. -- (BOOL)fileHandlerUIEnabled; -- (BOOL)canChangeDefaultBrowser; -@end - -namespace PreferencesWindowControllerInternal { - -// A C++ class registered for changes in preferences. Bridges the -// notification back to the PWC. -class PrefObserverBridge : public NotificationObserver, - public ProfileSyncServiceObserver { - public: - PrefObserverBridge(PreferencesWindowController* controller) - : controller_(controller) {} - - virtual ~PrefObserverBridge() {} - - // Overridden from NotificationObserver: - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - if (type == NotificationType::PREF_CHANGED) - [controller_ prefChanged:Details<std::string>(details).ptr()]; - } - - // Overridden from ProfileSyncServiceObserver. - virtual void OnStateChanged() { - [controller_ syncStateChanged]; - } - - private: - PreferencesWindowController* controller_; // weak, owns us -}; - -// Tracks state for a managed prefs banner and triggers UI updates through the -// PreferencesWindowController as appropriate. -class ManagedPrefsBannerState : public policy::ManagedPrefsBannerBase { - public: - virtual ~ManagedPrefsBannerState() { } - - explicit ManagedPrefsBannerState(PreferencesWindowController* controller, - OptionsPage page, - PrefService* local_state, - PrefService* prefs) - : policy::ManagedPrefsBannerBase(local_state, prefs, page), - controller_(controller), - page_(page) { } - - BOOL IsVisible() { - return DetermineVisibility(); - } - - protected: - // Overridden from ManagedPrefsBannerBase. - virtual void OnUpdateVisibility() { - [controller_ switchToPage:page_ animate:YES]; - } - - private: - PreferencesWindowController* controller_; // weak, owns us - OptionsPage page_; // current options page -}; - -} // namespace PreferencesWindowControllerInternal - -@implementation PreferencesWindowController - -@synthesize restoreButtonsEnabled = restoreButtonsEnabled_; -@synthesize restoreURLsEnabled = restoreURLsEnabled_; -@synthesize showHomeButtonEnabled = showHomeButtonEnabled_; -@synthesize defaultSearchEngineEnabled = defaultSearchEngineEnabled_; -@synthesize passwordManagerChoiceEnabled = passwordManagerChoiceEnabled_; -@synthesize passwordManagerButtonEnabled = passwordManagerButtonEnabled_; -@synthesize autoFillSettingsButtonEnabled = autoFillSettingsButtonEnabled_; -@synthesize showAlternateErrorPagesEnabled = showAlternateErrorPagesEnabled_; -@synthesize useSuggestEnabled = useSuggestEnabled_; -@synthesize dnsPrefetchEnabled = dnsPrefetchEnabled_; -@synthesize safeBrowsingEnabled = safeBrowsingEnabled_; -@synthesize metricsReportingEnabled = metricsReportingEnabled_; -@synthesize downloadLocationEnabled = downloadLocationEnabled_; -@synthesize proxiesConfigureButtonEnabled = proxiesConfigureButtonEnabled_; - -- (id)initWithProfile:(Profile*)profile initialPage:(OptionsPage)initialPage { - DCHECK(profile); - // Use initWithWindowNibPath:: instead of initWithWindowNibName: so we - // can override it in a unit test. - NSString* nibPath = [base::mac::MainAppBundle() - pathForResource:@"Preferences" - ofType:@"nib"]; - if ((self = [super initWithWindowNibPath:nibPath owner:self])) { - profile_ = profile->GetOriginalProfile(); - initialPage_ = initialPage; - prefs_ = profile->GetPrefs(); - DCHECK(prefs_); - observer_.reset( - new PreferencesWindowControllerInternal::PrefObserverBridge(self)); - - // Set up the model for the custom home page table. The KVO observation - // tells us when the number of items in the array changes. The normal - // observation tells us when one of the URLs of an item changes. - customPagesSource_.reset([[CustomHomePagesModel alloc] - initWithProfile:profile_]); - const SessionStartupPref startupPref = - SessionStartupPref::GetStartupPref(prefs_); - [customPagesSource_ setURLs:startupPref.urls]; - - // Set up the model for the default search popup. Register for notifications - // about when the model changes so we can update the selection in the view. - searchEngineModel_.reset( - [[SearchEngineListModel alloc] - initWithModel:profile->GetTemplateURLModel()]); - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(searchEngineModelChanged:) - name:kSearchEngineListModelChangedNotification - object:searchEngineModel_.get()]; - - // This needs to be done before awakeFromNib: because the bindings set up - // in the nib rely on it. - [self registerPrefObservers]; - - // Use one animation so we can stop it if the user clicks quickly, and - // start the new animation. - animation_.reset([[NSViewAnimation alloc] init]); - // Make this the delegate so it can remove the old view at the end of the - // animation (once it is faded out). - [animation_ setDelegate:self]; - [animation_ setAnimationBlockingMode:NSAnimationNonblocking]; - - // TODO(akalin): handle incognito profiles? The windows version of this - // (in chrome/browser/ui/views/options/content_page_view.cc) just does what - // we do below. - syncService_ = profile_->GetProfileSyncService(); - - // TODO(akalin): This color is taken from kSyncLabelErrorBgColor in - // content_page_view.cc. Either decomp that color out into a - // function/variable that is referenced by both this file and - // content_page_view.cc, or maybe pick a more suitable color. - syncErrorBackgroundColor_.reset( - [[NSColor colorWithDeviceRed:0xff/255.0 - green:0x9a/255.0 - blue:0x9a/255.0 - alpha:1.0] retain]); - - // Disable the |autoFillSettingsButton_| if we have no - // |personalDataManager|. - PersonalDataManager* personalDataManager = - profile_->GetPersonalDataManager(); - [autoFillSettingsButton_ setHidden:(personalDataManager == NULL)]; - bool autofill_disabled_by_policy = - autoFillEnabled_.IsManaged() && !autoFillEnabled_.GetValue(); - [self setAutoFillSettingsButtonEnabled:!autofill_disabled_by_policy]; - [self setPasswordManagerChoiceEnabled:!askSavePasswords_.IsManaged()]; - [self setPasswordManagerButtonEnabled: - !askSavePasswords_.IsManaged() || askSavePasswords_.GetValue()]; - - // Initialize the enabled state of the elements on the general tab. - [self setShowHomeButtonEnabled:!showHomeButton_.IsManaged()]; - [self setEnabledStateOfRestoreOnStartup]; - [self setDefaultSearchEngineEnabled:![searchEngineModel_ isDefaultManaged]]; - - // Initialize UI state for the advanced page. - [self setShowAlternateErrorPagesEnabled:!alternateErrorPages_.IsManaged()]; - [self setUseSuggestEnabled:!useSuggest_.IsManaged()]; - [self setDnsPrefetchEnabled:!dnsPrefetch_.IsManaged()]; - [self setSafeBrowsingEnabled:!safeBrowsing_.IsManaged()]; - [self setMetricsReportingEnabled:!metricsReporting_.IsManaged()]; - [self setDownloadLocationEnabled:!defaultDownloadLocation_.IsManaged()]; - proxyPrefs_.reset( - PrefSetObserver::CreateProxyPrefSetObserver(prefs_, observer_.get())); - [self setProxiesConfigureButtonEnabled:!proxyPrefs_->IsManaged()]; - } - return self; -} - -- (void)awakeFromNib { - - // Validate some assumptions in debug builds. - - // "Basics", "Personal Stuff", and "Under the Hood" views should be the same - // width. They should be the same width so they are laid out to look as good - // as possible at that width with controls just having to wrap if their text - // is too long. - DCHECK_EQ(NSWidth([basicsView_ frame]), NSWidth([personalStuffView_ frame])) - << "Basics and Personal Stuff should be the same widths"; - DCHECK_EQ(NSWidth([basicsView_ frame]), NSWidth([underTheHoodView_ frame])) - << "Basics and Under the Hood should be the same widths"; - // "Under the Hood" content should always be skinnier than the scroller it - // goes into (we resize it). - DCHECK_LE(NSWidth([underTheHoodContentView_ frame]), - [underTheHoodScroller_ contentSize].width) - << "The Under the Hood content should be narrower than the content " - "of the scroller it goes into"; - -#if !defined(GOOGLE_CHROME_BUILD) - // "Enable logging" (breakpad and stats) is only in Google Chrome builds, - // remove the checkbox and slide everything above it down. - RemoveViewFromView(underTheHoodContentView_, enableLoggingCheckbox_); -#endif // !defined(GOOGLE_CHROME_BUILD) - - // There are four problem children within the groups: - // Basics - Default Browser - // Personal Stuff - Sync - // Personal Stuff - Themes - // Personal Stuff - Browser Data - // These four have buttons that with some localizations are wider then the - // view. So the four get manually laid out before doing the general work so - // the views/window can be made wide enough to fit them. The layout in the - // general pass is a noop for these buttons (since they are already sized). - - // Size the default browser button. - const NSUInteger kDefaultBrowserGroupCount = 3; - const NSUInteger kDefaultBrowserButtonIndex = 1; - DCHECK_EQ([basicsGroupDefaultBrowser_ count], kDefaultBrowserGroupCount) - << "Expected only two items in Default Browser group"; - NSButton* defaultBrowserButton = - [basicsGroupDefaultBrowser_ objectAtIndex:kDefaultBrowserButtonIndex]; - NSSize defaultBrowserChange = - [GTMUILocalizerAndLayoutTweaker sizeToFitView:defaultBrowserButton]; - DCHECK_EQ(defaultBrowserChange.height, 0.0) - << "Button should have been right height in nib"; - - [self configureInstant]; - - // Size the sync row. - CGFloat syncRowChange = SizeToFitButtonPair(syncButton_, - syncCustomizeButton_); - - // Size the themes row. - const NSUInteger kThemeGroupCount = 3; - const NSUInteger kThemeResetButtonIndex = 1; - const NSUInteger kThemeThemesButtonIndex = 2; - DCHECK_EQ([personalStuffGroupThemes_ count], kThemeGroupCount) - << "Expected only two items in Themes group"; - CGFloat themeRowChange = SizeToFitButtonPair( - [personalStuffGroupThemes_ objectAtIndex:kThemeResetButtonIndex], - [personalStuffGroupThemes_ objectAtIndex:kThemeThemesButtonIndex]); - - // Size the Privacy and Clear buttons that make a row in Under the Hood. - CGFloat privacyRowChange = SizeToFitButtonPair(contentSettingsButton_, - clearDataButton_); - // Under the Hood view is narrower (then the other panes) in the nib, subtract - // out the amount it was already going to grow to match the other panes when - // calculating how much the row needs things to grow. - privacyRowChange -= - ([underTheHoodScroller_ contentSize].width - - NSWidth([underTheHoodContentView_ frame])); - - // Find the most any row changed in size. - CGFloat maxWidthChange = std::max(defaultBrowserChange.width, syncRowChange); - maxWidthChange = std::max(maxWidthChange, themeRowChange); - maxWidthChange = std::max(maxWidthChange, privacyRowChange); - - // If any grew wider, make the views wider. If they all shrank, they fit the - // existing view widths, so no change is needed//. - if (maxWidthChange > 0.0) { - NSSize viewSize = [basicsView_ frame].size; - viewSize.width += maxWidthChange; - [basicsView_ setFrameSize:viewSize]; - viewSize = [personalStuffView_ frame].size; - viewSize.width += maxWidthChange; - [personalStuffView_ setFrameSize:viewSize]; - } - - // Now that we have the width needed for Basics and Personal Stuff, lay out - // those pages bottom up making sure the strings fit and moving things up as - // needed. - - CGFloat newWidth = NSWidth([basicsView_ frame]); - CGFloat verticalShift = 0.0; - verticalShift += AutoSizeGroup(basicsGroupDefaultBrowser_, - kAutoSizeGroupBehaviorVerticalFirstToFit, - verticalShift); - verticalShift += AutoSizeGroup( - basicsGroupSearchEngine_, - kAutoSizeGroupBehaviorFirstTwoAsRowVerticalToFit, - verticalShift); - verticalShift += AutoSizeGroup(basicsGroupToolbar_, - kAutoSizeGroupBehaviorVerticalToFit, - verticalShift); - verticalShift += AutoSizeGroup(basicsGroupHomePage_, - kAutoSizeGroupBehaviorVerticalToFit, - verticalShift); - verticalShift += AutoSizeGroup(basicsGroupStartup_, - kAutoSizeGroupBehaviorVerticalFirstToFit, - verticalShift); - [GTMUILocalizerAndLayoutTweaker - resizeViewWithoutAutoResizingSubViews:basicsView_ - delta:NSMakeSize(0.0, verticalShift)]; - - verticalShift = 0.0; - verticalShift += AutoSizeGroup(personalStuffGroupThemes_, - kAutoSizeGroupBehaviorHorizontalToFit, - verticalShift); - verticalShift += AutoSizeGroup(personalStuffGroupBrowserData_, - kAutoSizeGroupBehaviorVerticalToFit, - verticalShift); - verticalShift += AutoSizeGroup(personalStuffGroupAutofill_, - kAutoSizeGroupBehaviorVerticalToFit, - verticalShift); - verticalShift += AutoSizeGroup(personalStuffGroupPasswords_, - kAutoSizeGroupBehaviorVerticalToFit, - verticalShift); - // TODO(akalin): Here we rely on the initial contents of the sync - // group's text field/link field to be large enough to hold all - // possible messages so that we don't have to re-layout when sync - // state changes. This isn't perfect, since e.g. some sync messages - // use the user's e-mail address (which may be really long), and the - // link field is usually not shown (leaving a big empty space). - // Rethink sync preferences UI for Mac. - verticalShift += AutoSizeGroup(personalStuffGroupSync_, - kAutoSizeGroupBehaviorVerticalToFit, - verticalShift); - [GTMUILocalizerAndLayoutTweaker - resizeViewWithoutAutoResizingSubViews:personalStuffView_ - delta:NSMakeSize(0.0, verticalShift)]; - - if (syncService_) { - syncService_->AddObserver(observer_.get()); - // Update the controls according to the initial state. - [self syncStateChanged]; - } else { - // If sync is disabled we don't want to show the sync controls at all. - RemoveGroupFromView(personalStuffView_, personalStuffGroupSync_); - } - - // Make the window as wide as the views. - NSWindow* prefsWindow = [self window]; - NSView* prefsContentView = [prefsWindow contentView]; - NSRect frame = [prefsContentView convertRect:[prefsWindow frame] - fromView:nil]; - frame.size.width = newWidth; - frame = [prefsContentView convertRect:frame toView:nil]; - [prefsWindow setFrame:frame display:NO]; - - // The Under the Hood prefs is a scroller, it shouldn't get any border, so it - // gets resized to be as wide as the window ended up. - NSSize underTheHoodSize = [underTheHoodView_ frame].size; - underTheHoodSize.width = newWidth; - [underTheHoodView_ setFrameSize:underTheHoodSize]; - - // Widen the Under the Hood content so things can rewrap to the full width. - NSSize underTheHoodContentSize = [underTheHoodContentView_ frame].size; - underTheHoodContentSize.width = [underTheHoodScroller_ contentSize].width; - [underTheHoodContentView_ setFrameSize:underTheHoodContentSize]; - - // Now that Under the Hood is the right width, auto-size to the new width to - // get the final height. - verticalShift = AutoSizeUnderTheHoodContent(underTheHoodContentView_, - downloadLocationControl_, - downloadLocationButton_); - [GTMUILocalizerAndLayoutTweaker - resizeViewWithoutAutoResizingSubViews:underTheHoodContentView_ - delta:NSMakeSize(0.0, verticalShift)]; - underTheHoodContentSize = [underTheHoodContentView_ frame].size; - - // Put the Under the Hood content view into the scroller and scroll it to the - // top. - [underTheHoodScroller_ setDocumentView:underTheHoodContentView_]; - [underTheHoodContentView_ scrollPoint: - NSMakePoint(0, underTheHoodContentSize.height)]; - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - NSImage* alertIcon = rb.GetNativeImageNamed(IDR_WARNING); - DCHECK(alertIcon); - [managedPrefsBannerWarningImage_ setImage:alertIcon]; - - [self initBannerStateForPage:initialPage_]; - [self switchToPage:initialPage_ animate:NO]; - - // Save/restore position based on prefs. - if (g_browser_process && g_browser_process->local_state()) { - sizeSaver_.reset([[WindowSizeAutosaver alloc] - initWithWindow:[self window] - prefService:profile_->GetPrefs() - path:prefs::kPreferencesWindowPlacement]); - } - - // Initialize the banner gradient and stroke color. - NSColor* bannerStartingColor = - [NSColor colorWithCalibratedRed:kBannerGradientColorTop[0] - green:kBannerGradientColorTop[1] - blue:kBannerGradientColorTop[2] - alpha:1.0]; - NSColor* bannerEndingColor = - [NSColor colorWithCalibratedRed:kBannerGradientColorBottom[0] - green:kBannerGradientColorBottom[1] - blue:kBannerGradientColorBottom[2] - alpha:1.0]; - scoped_nsobject<NSGradient> bannerGradient( - [[NSGradient alloc] initWithStartingColor:bannerStartingColor - endingColor:bannerEndingColor]); - [managedPrefsBannerView_ setGradient:bannerGradient]; - - NSColor* bannerStrokeColor = - [NSColor colorWithCalibratedWhite:kBannerStrokeColor - alpha:1.0]; - [managedPrefsBannerView_ setStrokeColor:bannerStrokeColor]; - - // Set accessibility related attributes. - NSTableView* tableView = [basicsView_ viewWithTag:kBasicsStartupPageTableTag]; - NSString* description = - l10n_util::GetNSStringWithFixup(IDS_OPTIONS_STARTUP_SHOW_PAGES); - [tableView accessibilitySetOverrideValue:description - forAttribute:NSAccessibilityDescriptionAttribute]; -} - -- (void)dealloc { - if (syncService_) { - syncService_->RemoveObserver(observer_.get()); - } - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [animation_ setDelegate:nil]; - [animation_ stopAnimation]; - [super dealloc]; -} - -// Xcode 3.1.x version of Interface Builder doesn't do a lot for editing -// toolbars in XIB. So the toolbar's delegate is set to the controller so it -// can tell the toolbar what items are selectable. -- (NSArray*)toolbarSelectableItemIdentifiers:(NSToolbar*)toolbar { - DCHECK(toolbar == toolbar_); - return [[toolbar_ items] valueForKey:@"itemIdentifier"]; -} - -// Register our interest in the preferences we're displaying so if anything -// else in the UI changes them we will be updated. -- (void)registerPrefObservers { - if (!prefs_) return; - - PrefService* local = g_browser_process->local_state(); - - // Basics panel - registrar_.Init(prefs_); - registrar_.Add(prefs::kURLsToRestoreOnStartup, observer_.get()); - restoreOnStartup_.Init(prefs::kRestoreOnStartup, prefs_, observer_.get()); - newTabPageIsHomePage_.Init(prefs::kHomePageIsNewTabPage, - prefs_, observer_.get()); - homepage_.Init(prefs::kHomePage, prefs_, observer_.get()); - showHomeButton_.Init(prefs::kShowHomeButton, prefs_, observer_.get()); - instantEnabled_.Init(prefs::kInstantEnabled, prefs_, observer_.get()); - default_browser_policy_.Init(prefs::kDefaultBrowserSettingEnabled, - local, observer_.get()); - - // Personal Stuff panel - askSavePasswords_.Init(prefs::kPasswordManagerEnabled, - prefs_, observer_.get()); - autoFillEnabled_.Init(prefs::kAutoFillEnabled, prefs_, observer_.get()); - currentTheme_.Init(prefs::kCurrentThemeID, prefs_, observer_.get()); - - // Under the hood panel - alternateErrorPages_.Init(prefs::kAlternateErrorPagesEnabled, - prefs_, observer_.get()); - useSuggest_.Init(prefs::kSearchSuggestEnabled, prefs_, observer_.get()); - dnsPrefetch_.Init(prefs::kDnsPrefetchingEnabled, prefs_, observer_.get()); - safeBrowsing_.Init(prefs::kSafeBrowsingEnabled, prefs_, observer_.get()); - autoOpenFiles_.Init( - prefs::kDownloadExtensionsToOpen, prefs_, observer_.get()); - translateEnabled_.Init(prefs::kEnableTranslate, prefs_, observer_.get()); - tabsToLinks_.Init(prefs::kWebkitTabsToLinks, prefs_, observer_.get()); - - metricsReporting_.Init(prefs::kMetricsReportingEnabled, - local, observer_.get()); - defaultDownloadLocation_.Init(prefs::kDownloadDefaultDirectory, prefs_, - observer_.get()); - askForSaveLocation_.Init(prefs::kPromptForDownload, prefs_, observer_.get()); - - // We don't need to observe changes in this value. - lastSelectedPage_.Init(prefs::kOptionsWindowLastTabIndex, local, NULL); -} - -// Called when the window wants to be closed. -- (BOOL)windowShouldClose:(id)sender { - // Stop any animation and clear the delegate to avoid stale pointers. - [animation_ setDelegate:nil]; - [animation_ stopAnimation]; - - return YES; -} - -// Called when the user hits the escape key. Closes the window. -- (void)cancel:(id)sender { - [[self window] performClose:self]; -} - -// Record the user performed a certain action and save the preferences. -- (void)recordUserAction:(const UserMetricsAction &)action { - UserMetrics::RecordAction(action, profile_); - if (prefs_) - prefs_->ScheduleSavePersistentPrefs(); -} - -// Returns the set of keys that |key| depends on for its value so it can be -// re-computed when any of those change as well. -+ (NSSet*)keyPathsForValuesAffectingValueForKey:(NSString*)key { - NSSet* paths = [super keyPathsForValuesAffectingValueForKey:key]; - if ([key isEqualToString:@"isHomepageURLEnabled"]) { - paths = [paths setByAddingObject:@"newTabPageIsHomePageIndex"]; - paths = [paths setByAddingObject:@"homepageURL"]; - } else if ([key isEqualToString:@"restoreURLsEnabled"]) { - paths = [paths setByAddingObject:@"restoreOnStartupIndex"]; - } else if ([key isEqualToString:@"isHomepageChoiceEnabled"]) { - paths = [paths setByAddingObject:@"newTabPageIsHomePageIndex"]; - paths = [paths setByAddingObject:@"homepageURL"]; - } else if ([key isEqualToString:@"newTabPageIsHomePageIndex"]) { - paths = [paths setByAddingObject:@"homepageURL"]; - } else if ([key isEqualToString:@"hompageURL"]) { - paths = [paths setByAddingObject:@"newTabPageIsHomePageIndex"]; - } else if ([key isEqualToString:@"canChangeDefaultBrowser"]) { - paths = [paths setByAddingObject:@"defaultBrowser"]; - } else if ([key isEqualToString:@"defaultBrowserTextColor"]) { - paths = [paths setByAddingObject:@"defaultBrowser"]; - } else if ([key isEqualToString:@"defaultBrowserText"]) { - paths = [paths setByAddingObject:@"defaultBrowser"]; - } - return paths; -} - -// Launch the Keychain Access app. -- (void)launchKeychainAccess { - NSString* const kKeychainBundleId = @"com.apple.keychainaccess"; - [[NSWorkspace sharedWorkspace] - launchAppWithBundleIdentifier:kKeychainBundleId - options:0L - additionalEventParamDescriptor:nil - launchIdentifier:nil]; -} - -//------------------------------------------------------------------------- -// Basics panel - -// Sets the home page preferences for kNewTabPageIsHomePage and kHomePage. If a -// blank or null-host URL is passed in we revert to using NewTab page -// as the Home page. Note: using SetValue() causes the observers not to fire, -// which is actually a good thing as we could end up in a state where setting -// the homepage to an empty url would automatically reset the prefs back to -// using the NTP, so we'd be never be able to change it. -- (void)setHomepage:(const GURL&)homepage { - if (IsNewTabUIURLString(homepage)) { - newTabPageIsHomePage_.SetValueIfNotManaged(true); - homepage_.SetValueIfNotManaged(std::string()); - } else if (!homepage.is_valid()) { - newTabPageIsHomePage_.SetValueIfNotManaged(true); - if (!homepage.has_host()) - homepage_.SetValueIfNotManaged(std::string()); - } else { - homepage_.SetValueIfNotManaged(homepage.spec()); - } -} - -// Callback when preferences are changed by someone modifying the prefs backend -// externally. |prefName| is the name of the pref that has changed. Unlike on -// Windows, we don't need to use this method for initializing, that's handled by -// Cocoa Bindings. -// Handles prefs for the "Basics" panel. -- (void)basicsPrefChanged:(std::string*)prefName { - if (*prefName == prefs::kRestoreOnStartup) { - const SessionStartupPref startupPref = - SessionStartupPref::GetStartupPref(prefs_); - [self setRestoreOnStartupIndex:startupPref.type]; - [self setEnabledStateOfRestoreOnStartup]; - } else if (*prefName == prefs::kURLsToRestoreOnStartup) { - [customPagesSource_ reloadURLs]; - [self setEnabledStateOfRestoreOnStartup]; - } else if (*prefName == prefs::kHomePageIsNewTabPage) { - NSInteger useNewTabPage = newTabPageIsHomePage_.GetValue() ? 0 : 1; - [self setNewTabPageIsHomePageIndex:useNewTabPage]; - } else if (*prefName == prefs::kHomePage) { - NSString* value = base::SysUTF8ToNSString(homepage_.GetValue()); - [self setHomepageURL:value]; - } else if (*prefName == prefs::kShowHomeButton) { - [self setShowHomeButton:showHomeButton_.GetValue() ? YES : NO]; - [self setShowHomeButtonEnabled:!showHomeButton_.IsManaged()]; - } else if (*prefName == prefs::kInstantEnabled) { - [self configureInstant]; - } else if (*prefName == prefs::kDefaultBrowserSettingEnabled) { - [self willChangeValueForKey:@"defaultBrowser"]; - [self didChangeValueForKey:@"defaultBrowser"]; - } -} - -// Returns the index of the selected cell in the "on startup" matrix based -// on the "restore on startup" pref. The ordering of the cells is in the -// same order as the pref. -- (NSInteger)restoreOnStartupIndex { - const SessionStartupPref pref = SessionStartupPref::GetStartupPref(prefs_); - return pref.type; -} - -// A helper function that takes the startup session type, grabs the URLs to -// restore, and saves it all in prefs. -- (void)saveSessionStartupWithType:(SessionStartupPref::Type)type { - SessionStartupPref pref; - pref.type = type; - pref.urls = [customPagesSource_.get() URLs]; - SessionStartupPref::SetStartupPref(prefs_, pref); -} - -// Sets the pref based on the index of the selected cell in the matrix and -// marks the appropriate user metric. -- (void)setRestoreOnStartupIndex:(NSInteger)type { - SessionStartupPref::Type startupType = - static_cast<SessionStartupPref::Type>(type); - switch (startupType) { - case SessionStartupPref::DEFAULT: - [self recordUserAction:UserMetricsAction("Options_Startup_Homepage")]; - break; - case SessionStartupPref::LAST: - [self recordUserAction:UserMetricsAction("Options_Startup_LastSession")]; - break; - case SessionStartupPref::URLS: - [self recordUserAction:UserMetricsAction("Options_Startup_Custom")]; - break; - default: - NOTREACHED(); - } - [self saveSessionStartupWithType:startupType]; -} - -// Enables or disables the restoreOnStartup elements -- (void) setEnabledStateOfRestoreOnStartup { - const SessionStartupPref startupPref = - SessionStartupPref::GetStartupPref(prefs_); - [self setRestoreButtonsEnabled:!SessionStartupPref::TypeIsManaged(prefs_)]; - [self setRestoreURLsEnabled:!SessionStartupPref::URLsAreManaged(prefs_) && - [self restoreOnStartupIndex] == SessionStartupPref::URLS]; -} - -// Getter for the |customPagesSource| property for bindings. -- (CustomHomePagesModel*)customPagesSource { - return customPagesSource_.get(); -} - -// Called when the selection in the table changes. If a flag is set indicating -// that we're waiting for a special select message, edit the cell. Otherwise -// just ignore it, we don't normally care. -- (void)tableViewSelectionDidChange:(NSNotification*)aNotification { - if (pendingSelectForEdit_) { - NSTableView* table = [aNotification object]; - NSUInteger selectedRow = [table selectedRow]; - [table editColumn:0 row:selectedRow withEvent:nil select:YES]; - pendingSelectForEdit_ = NO; - } -} - -// Called when the user hits the (+) button for adding a new homepage to the -// list. This will also attempt to make the new item editable so the user can -// just start typing. -- (IBAction)addHomepage:(id)sender { - [customPagesArrayController_ add:sender]; - - // When the new item is added to the model, the array controller will select - // it. We'll watch for that notification (because we are the table view's - // delegate) and then make the cell editable. Note that this can't be - // accomplished simply by subclassing the array controller's add method (I - // did try). The update of the table is asynchronous with the controller - // updating the model. - pendingSelectForEdit_ = YES; -} - -// Called when the user hits the (-) button for removing the selected items in -// the homepage table. The controller does all the work. -- (IBAction)removeSelectedHomepages:(id)sender { - [customPagesArrayController_ remove:sender]; -} - -// Add all entries for all open browsers with our profile. -- (IBAction)useCurrentPagesAsHomepage:(id)sender { - std::vector<GURL> urls; - for (BrowserList::const_iterator browserIter = BrowserList::begin(); - browserIter != BrowserList::end(); ++browserIter) { - Browser* browser = *browserIter; - if (browser->profile() != profile_) - continue; // Only want entries for open profile. - - for (int tabIndex = 0; tabIndex < browser->tab_count(); ++tabIndex) { - TabContents* tab = browser->GetTabContentsAt(tabIndex); - if (tab->ShouldDisplayURL()) { - const GURL url = browser->GetTabContentsAt(tabIndex)->GetURL(); - if (!url.is_empty()) - urls.push_back(url); - } - } - } - [customPagesSource_ setURLs:urls]; -} - -enum { kHomepageNewTabPage, kHomepageURL }; - -// Here's a table describing the desired characteristics of the homepage choice -// radio value, it's enabled state and the URL field enabled state. They depend -// on the values of the managed bits for homepage (m_hp) and -// homepageIsNewTabPage (m_ntp) preferences, as well as the value of the -// homepageIsNewTabPage preference (ntp) and whether the homepage preference -// is equal to the new tab page URL (hpisntp). -// -// m_hp m_ntp ntp hpisntp | choice value | choice enabled | URL field enabled -// -------------------------------------------------------------------------- -// 0 0 0 0 | homepage | 1 | 1 -// 0 0 0 1 | new tab page | 1 | 0 -// 0 0 1 0 | new tab page | 1 | 0 -// 0 0 1 1 | new tab page | 1 | 0 -// 0 1 0 0 | homepage | 0 | 1 -// 0 1 0 1 | homepage | 0 | 1 -// 0 1 1 0 | new tab page | 0 | 0 -// 0 1 1 1 | new tab page | 0 | 0 -// 1 0 0 0 | homepage | 1 | 0 -// 1 0 0 1 | new tab page | 0 | 0 -// 1 0 1 0 | new tab page | 1 | 0 -// 1 0 1 1 | new tab page | 0 | 0 -// 1 1 0 0 | homepage | 0 | 0 -// 1 1 0 1 | new tab page | 0 | 0 -// 1 1 1 0 | new tab page | 0 | 0 -// 1 1 1 1 | new tab page | 0 | 0 -// -// thus, we have: -// -// choice value is new tab page === ntp || (hpisntp && (m_hp || !m_ntp)) -// choice enabled === !m_ntp && !(m_hp && hpisntp) -// URL field enabled === !ntp && !mhp && !(hpisntp && !m_ntp) -// -// which also make sense if you think about them. - -// Checks whether the homepage URL refers to the new tab page. -- (BOOL)isHomepageNewTabUIURL { - return IsNewTabUIURLString(GURL(homepage_.GetValue().c_str())); -} - -// Returns the index of the selected cell in the "home page" marix based on -// the "new tab is home page" pref. Sadly, the ordering is reversed from the -// pref value. -- (NSInteger)newTabPageIsHomePageIndex { - return newTabPageIsHomePage_.GetValue() || - ([self isHomepageNewTabUIURL] && - (homepage_.IsManaged() || !newTabPageIsHomePage_.IsManaged())) ? - kHomepageNewTabPage : kHomepageURL; -} - -// Sets the pref based on the given index into the matrix and marks the -// appropriate user metric. -- (void)setNewTabPageIsHomePageIndex:(NSInteger)index { - bool useNewTabPage = index == kHomepageNewTabPage ? true : false; - if (useNewTabPage) { - [self recordUserAction:UserMetricsAction("Options_Homepage_UseNewTab")]; - } else { - [self recordUserAction:UserMetricsAction("Options_Homepage_UseURL")]; - if ([self isHomepageNewTabUIURL]) - homepage_.SetValueIfNotManaged(std::string()); - } - newTabPageIsHomePage_.SetValueIfNotManaged(useNewTabPage); -} - -// Check whether the new tab and URL homepage radios should be enabled, i.e. if -// the corresponding preference is not managed through configuration policy. -- (BOOL)isHomepageChoiceEnabled { - return !newTabPageIsHomePage_.IsManaged() && - !(homepage_.IsManaged() && [self isHomepageNewTabUIURL]); -} - -// Returns whether or not the homepage URL text field should be enabled -// based on if the new tab page is the home page. -- (BOOL)isHomepageURLEnabled { - return !newTabPageIsHomePage_.GetValue() && !homepage_.IsManaged() && - !([self isHomepageNewTabUIURL] && !newTabPageIsHomePage_.IsManaged()); -} - -// Returns the homepage URL. -- (NSString*)homepageURL { - NSString* value = base::SysUTF8ToNSString(homepage_.GetValue()); - return [self isHomepageNewTabUIURL] ? nil : value; -} - -// Sets the homepage URL to |urlString| with some fixing up. -- (void)setHomepageURL:(NSString*)urlString { - // If the text field contains a valid URL, sync it to prefs. We run it - // through the fixer upper to allow input like "google.com" to be converted - // to something valid ("http://google.com"). - std::string unfixedURL = urlString ? base::SysNSStringToUTF8(urlString) : - chrome::kChromeUINewTabURL; - [self setHomepage:URLFixerUpper::FixupURL(unfixedURL, std::string())]; -} - -// Returns whether the home button should be checked based on the preference. -- (BOOL)showHomeButton { - return showHomeButton_.GetValue() ? YES : NO; -} - -// Sets the backend pref for whether or not the home button should be displayed -// based on |value|. -- (void)setShowHomeButton:(BOOL)value { - if (value) - [self recordUserAction:UserMetricsAction( - "Options_Homepage_ShowHomeButton")]; - else - [self recordUserAction:UserMetricsAction( - "Options_Homepage_HideHomeButton")]; - showHomeButton_.SetValueIfNotManaged(value ? true : false); -} - -// Getter for the |searchEngineModel| property for bindings. -- (id)searchEngineModel { - return searchEngineModel_.get(); -} - -// Bindings for the search engine popup. We not binding directly to the model -// in order to siphon off the setter so we can record the metric. If we're -// doing it with one, might as well do it with both. -- (NSUInteger)searchEngineSelectedIndex { - return [searchEngineModel_ defaultIndex]; -} - -- (void)setSearchEngineSelectedIndex:(NSUInteger)index { - [self recordUserAction:UserMetricsAction("Options_SearchEngineChanged")]; - [searchEngineModel_ setDefaultIndex:index]; -} - -// Called when the search engine model changes. Update the selection in the -// popup by tickling the bindings with the new value. -- (void)searchEngineModelChanged:(NSNotification*)notify { - [self setSearchEngineSelectedIndex:[self searchEngineSelectedIndex]]; - [self setDefaultSearchEngineEnabled:![searchEngineModel_ isDefaultManaged]]; - -} - -- (IBAction)manageSearchEngines:(id)sender { - [KeywordEditorCocoaController showKeywordEditor:profile_]; -} - -- (IBAction)toggleInstant:(id)sender { - if (instantEnabled_.GetValue()) { - InstantController::Disable(profile_); - } else { - [instantCheckbox_ setState:NSOffState]; - browser::ShowInstantConfirmDialogIfNecessary([self window], profile_); - } -} - -// Sets the state of the Instant checkbox and adds the type information to the -// label. -- (void)configureInstant { - bool enabled = instantEnabled_.GetValue(); - NSInteger state = enabled ? NSOnState : NSOffState; - [instantCheckbox_ setState:state]; -} - -- (IBAction)learnMoreAboutInstant:(id)sender { - browser::ShowOptionsURL(profile_, browser::InstantLearnMoreURL()); -} - -// Called when the user clicks the button to make Chromium the default -// browser. Registers http and https. -- (IBAction)makeDefaultBrowser:(id)sender { - [self willChangeValueForKey:@"defaultBrowser"]; - - ShellIntegration::SetAsDefaultBrowser(); - [self recordUserAction:UserMetricsAction("Options_SetAsDefaultBrowser")]; - // If the user made Chrome the default browser, then he/she arguably wants - // to be notified when that changes. - prefs_->SetBoolean(prefs::kCheckDefaultBrowser, true); - - // Tickle KVO so that the UI updates. - [self didChangeValueForKey:@"defaultBrowser"]; -} - -// Returns the Chromium default browser state and whether this is user -// controlled or locked by a policy. -- (BOOL)canChangeDefaultBrowser { - return !default_browser_policy_.IsManaged() && - ShellIntegration::IsDefaultBrowser() != - ShellIntegration::IS_DEFAULT_BROWSER; -} - -// Returns the text color of the "chromium is your default browser" text (green -// for yes, red for no). -- (NSColor*)defaultBrowserTextColor { - ShellIntegration::DefaultBrowserState state = - ShellIntegration::IsDefaultBrowser(); - return (state == ShellIntegration::IS_DEFAULT_BROWSER) ? - [NSColor colorWithCalibratedRed:0.0 green:135.0/255.0 blue:0 alpha:1.0] : - [NSColor colorWithCalibratedRed:135.0/255.0 green:0 blue:0 alpha:1.0]; -} - -// Returns the text for the "chromium is your default browser" string dependent -// on if Chromium actually is or not. -- (NSString*)defaultBrowserText { - ShellIntegration::DefaultBrowserState state = - ShellIntegration::IsDefaultBrowser(); - int stringId; - if (state == ShellIntegration::IS_DEFAULT_BROWSER) - stringId = IDS_OPTIONS_DEFAULTBROWSER_DEFAULT; - else if (state == ShellIntegration::NOT_DEFAULT_BROWSER) - stringId = IDS_OPTIONS_DEFAULTBROWSER_NOTDEFAULT; - else - stringId = IDS_OPTIONS_DEFAULTBROWSER_UNKNOWN; - string16 text = - l10n_util::GetStringFUTF16(stringId, - l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); - return base::SysUTF16ToNSString(text); -} - -//------------------------------------------------------------------------- -// User Data panel - -// Since passwords and forms are radio groups, 'enabled' is index 0 and -// 'disabled' is index 1. Yay. -const int kEnabledIndex = 0; -const int kDisabledIndex = 1; - -// Callback when preferences are changed. |prefName| is the name of the pref -// that has changed. Unlike on Windows, we don't need to use this method for -// initializing, that's handled by Cocoa Bindings. -// Handles prefs for the "Personal Stuff" panel. -- (void)userDataPrefChanged:(std::string*)prefName { - if (*prefName == prefs::kPasswordManagerEnabled) { - [self setPasswordManagerEnabledIndex:askSavePasswords_.GetValue() ? - kEnabledIndex : kDisabledIndex]; - [self setPasswordManagerChoiceEnabled:!askSavePasswords_.IsManaged()]; - [self setPasswordManagerButtonEnabled: - !askSavePasswords_.IsManaged() || askSavePasswords_.GetValue()]; - } - if (*prefName == prefs::kAutoFillEnabled) { - bool autofill_disabled_by_policy = - autoFillEnabled_.IsManaged() && !autoFillEnabled_.GetValue(); - [self setAutoFillSettingsButtonEnabled:!autofill_disabled_by_policy]; - } - if (*prefName == prefs::kCurrentThemeID) { - [self setIsUsingDefaultTheme:currentTheme_.GetValue().length() == 0]; - } -} - -// Called to launch the Keychain Access app to show the user's stored -// passwords. -- (IBAction)showSavedPasswords:(id)sender { - [self recordUserAction:UserMetricsAction("Options_ShowPasswordsExceptions")]; - [self launchKeychainAccess]; -} - -// Called to show the Auto Fill Settings dialog. -- (IBAction)showAutoFillSettings:(id)sender { - [self recordUserAction:UserMetricsAction("Options_ShowAutoFillSettings")]; - - PersonalDataManager* personalDataManager = profile_->GetPersonalDataManager(); - if (!personalDataManager) { - // Should not reach here because button is disabled when - // |personalDataManager| is NULL. - NOTREACHED(); - return; - } - - ShowAutoFillDialog(NULL, personalDataManager, profile_); -} - -// Called to import data from other browsers (Safari, Firefox, etc). -- (IBAction)importData:(id)sender { - UserMetrics::RecordAction(UserMetricsAction("Import_ShowDlg"), profile_); - [ImportDialogController showImportSettingsDialogForProfile:profile_]; -} - -- (IBAction)resetThemeToDefault:(id)sender { - [self recordUserAction:UserMetricsAction("Options_ThemesReset")]; - profile_->ClearTheme(); -} - -- (IBAction)themesGallery:(id)sender { - [self recordUserAction:UserMetricsAction("Options_ThemesGallery")]; - Browser* browser = BrowserList::GetLastActive(); - - if (!browser || !browser->GetSelectedTabContents()) - browser = Browser::Create(profile_); - browser->OpenThemeGalleryTabAndActivate(); -} - -// Called when the "stop syncing" confirmation dialog started by -// doSyncAction is finished. Stop syncing only If the user clicked -// OK. -- (void)stopSyncAlertDidEnd:(NSAlert*)alert - returnCode:(int)returnCode - contextInfo:(void*)contextInfo { - DCHECK(syncService_ && !syncService_->IsManaged()); - if (returnCode == NSAlertFirstButtonReturn) { - syncService_->DisableForUser(); - ProfileSyncService::SyncEvent(ProfileSyncService::STOP_FROM_OPTIONS); - } -} - -// Called when the user clicks the multi-purpose sync button in the -// "Personal Stuff" pane. -- (IBAction)doSyncAction:(id)sender { - DCHECK(syncService_ && !syncService_->IsManaged()); - if (syncService_->HasSyncSetupCompleted()) { - // If sync setup has completed that means the sync button was a - // "stop syncing" button. Bring up a confirmation dialog before - // actually stopping syncing (see stopSyncAlertDidEnd). - scoped_nsobject<NSAlert> alert([[NSAlert alloc] init]); - [alert addButtonWithTitle:l10n_util::GetNSStringWithFixup( - IDS_SYNC_STOP_SYNCING_CONFIRM_BUTTON_LABEL)]; - [alert addButtonWithTitle:l10n_util::GetNSStringWithFixup( - IDS_CANCEL)]; - [alert setMessageText:l10n_util::GetNSStringWithFixup( - IDS_SYNC_STOP_SYNCING_DIALOG_TITLE)]; - [alert setInformativeText:l10n_util::GetNSStringWithFixup( - IDS_SYNC_STOP_SYNCING_EXPLANATION_LABEL)]; - [alert setAlertStyle:NSWarningAlertStyle]; - const SEL kEndSelector = - @selector(stopSyncAlertDidEnd:returnCode:contextInfo:); - [alert beginSheetModalForWindow:[self window] - modalDelegate:self - didEndSelector:kEndSelector - contextInfo:NULL]; - } else { - // Otherwise, the sync button was a "sync my bookmarks" button. - // Kick off the sync setup process. - syncService_->ShowLoginDialog(NULL); - ProfileSyncService::SyncEvent(ProfileSyncService::START_FROM_OPTIONS); - } -} - -// Called when the user clicks on the link to the privacy dashboard. -- (IBAction)showPrivacyDashboard:(id)sender { - Browser* browser = BrowserList::GetLastActive(); - - if (!browser || !browser->GetSelectedTabContents()) - browser = Browser::Create(profile_); - browser->OpenPrivacyDashboardTabAndActivate(); -} - -// Called when the user clicks the "Customize Sync" button in the -// "Personal Stuff" pane. Spawns a dialog-modal sheet that cleans -// itself up on close. -- (IBAction)doSyncCustomize:(id)sender { - syncService_->ShowConfigure(NULL); -} - -// Called when the user clicks on the multi-purpose 'sync problem' -// link. -- (IBAction)doSyncReauthentication:(id)sender { - DCHECK(syncService_ && !syncService_->IsManaged()); - syncService_->ShowErrorUI(NULL); -} - -- (void)setPasswordManagerEnabledIndex:(NSInteger)value { - if (value == kEnabledIndex) - [self recordUserAction:UserMetricsAction( - "Options_PasswordManager_Enable")]; - else - [self recordUserAction:UserMetricsAction( - "Options_PasswordManager_Disable")]; - askSavePasswords_.SetValueIfNotManaged(value == kEnabledIndex ? true : false); -} - -- (NSInteger)passwordManagerEnabledIndex { - return askSavePasswords_.GetValue() ? kEnabledIndex : kDisabledIndex; -} - -- (void)setIsUsingDefaultTheme:(BOOL)value { - if (value) - [self recordUserAction:UserMetricsAction( - "Options_IsUsingDefaultTheme_Enable")]; - else - [self recordUserAction:UserMetricsAction( - "Options_IsUsingDefaultTheme_Disable")]; -} - -- (BOOL)isUsingDefaultTheme { - return currentTheme_.GetValue().length() == 0; -} - -//------------------------------------------------------------------------- -// Under the hood panel - -// Callback when preferences are changed. |prefName| is the name of the pref -// that has changed. Unlike on Windows, we don't need to use this method for -// initializing, that's handled by Cocoa Bindings. -// Handles prefs for the "Under the hood" panel. -- (void)underHoodPrefChanged:(std::string*)prefName { - if (*prefName == prefs::kAlternateErrorPagesEnabled) { - [self setShowAlternateErrorPages: - alternateErrorPages_.GetValue() ? YES : NO]; - [self setShowAlternateErrorPagesEnabled:!alternateErrorPages_.IsManaged()]; - } - else if (*prefName == prefs::kSearchSuggestEnabled) { - [self setUseSuggest:useSuggest_.GetValue() ? YES : NO]; - [self setUseSuggestEnabled:!useSuggest_.IsManaged()]; - } - else if (*prefName == prefs::kDnsPrefetchingEnabled) { - [self setDnsPrefetch:dnsPrefetch_.GetValue() ? YES : NO]; - [self setDnsPrefetchEnabled:!dnsPrefetch_.IsManaged()]; - } - else if (*prefName == prefs::kSafeBrowsingEnabled) { - [self setSafeBrowsing:safeBrowsing_.GetValue() ? YES : NO]; - [self setSafeBrowsingEnabled:!safeBrowsing_.IsManaged()]; - } - else if (*prefName == prefs::kMetricsReportingEnabled) { - [self setMetricsReporting:metricsReporting_.GetValue() ? YES : NO]; - [self setMetricsReportingEnabled:!metricsReporting_.IsManaged()]; - } - else if (*prefName == prefs::kDownloadDefaultDirectory) { - [self setDownloadLocationEnabled:!defaultDownloadLocation_.IsManaged()]; - // Poke KVO. - [self willChangeValueForKey:@"defaultDownloadLocation"]; - [self didChangeValueForKey:@"defaultDownloadLocation"]; - } - else if (*prefName == prefs::kPromptForDownload) { - [self setAskForSaveLocation:askForSaveLocation_.GetValue() ? YES : NO]; - } - else if (*prefName == prefs::kEnableTranslate) { - [self setTranslateEnabled:translateEnabled_.GetValue() ? YES : NO]; - } - else if (*prefName == prefs::kWebkitTabsToLinks) { - [self setTabsToLinks:tabsToLinks_.GetValue() ? YES : NO]; - } - else if (*prefName == prefs::kDownloadExtensionsToOpen) { - // Poke KVC. - [self setFileHandlerUIEnabled:[self fileHandlerUIEnabled]]; - } - else if (proxyPrefs_->IsObserved(*prefName)) { - [self setProxiesConfigureButtonEnabled:!proxyPrefs_->IsManaged()]; - } -} - -// Set the new download path and notify the UI via KVO. -- (void)downloadPathPanelDidEnd:(NSOpenPanel*)panel - code:(NSInteger)returnCode - context:(void*)context { - if (returnCode == NSOKButton) { - [self recordUserAction:UserMetricsAction("Options_SetDownloadDirectory")]; - NSURL* path = [[panel URLs] lastObject]; // We only allow 1 item. - [self willChangeValueForKey:@"defaultDownloadLocation"]; - defaultDownloadLocation_.SetValue(base::SysNSStringToUTF8([path path])); - [self didChangeValueForKey:@"defaultDownloadLocation"]; - } -} - -// Bring up an open panel to allow the user to set a new downloads location. -- (void)browseDownloadLocation:(id)sender { - NSOpenPanel* panel = [NSOpenPanel openPanel]; - [panel setAllowsMultipleSelection:NO]; - [panel setCanChooseFiles:NO]; - [panel setCanChooseDirectories:YES]; - NSString* path = base::SysUTF8ToNSString(defaultDownloadLocation_.GetValue()); - [panel beginSheetForDirectory:path - file:nil - types:nil - modalForWindow:[self window] - modalDelegate:self - didEndSelector:@selector(downloadPathPanelDidEnd:code:context:) - contextInfo:NULL]; -} - -// Called to clear user's browsing data. This puts up an application-modal -// dialog to guide the user through clearing the data. -- (IBAction)clearData:(id)sender { - [ClearBrowsingDataController - showClearBrowsingDialogForProfile:profile_]; -} - -// Opens the "Content Settings" dialog. -- (IBAction)showContentSettings:(id)sender { - [ContentSettingsDialogController - showContentSettingsForType:CONTENT_SETTINGS_TYPE_DEFAULT - profile:profile_]; -} - -- (IBAction)privacyLearnMore:(id)sender { - GURL url = google_util::AppendGoogleLocaleParam( - GURL(chrome::kPrivacyLearnMoreURL)); - // We open a new browser window so the Options dialog doesn't get lost - // behind other windows. - browser::ShowOptionsURL(profile_, url); -} - -- (IBAction)resetAutoOpenFiles:(id)sender { - profile_->GetDownloadManager()->download_prefs()->ResetAutoOpen(); - [self recordUserAction:UserMetricsAction("Options_ResetAutoOpenFiles")]; -} - -- (IBAction)openProxyPreferences:(id)sender { - NSArray* itemsToOpen = [NSArray arrayWithObject:[NSURL fileURLWithPath: - @"/System/Library/PreferencePanes/Network.prefPane"]]; - - const char* proxyPrefCommand = "Proxies"; - base::mac::ScopedAEDesc<> openParams; - OSStatus status = AECreateDesc('ptru', - proxyPrefCommand, - strlen(proxyPrefCommand), - openParams.OutPointer()); - LOG_IF(ERROR, status != noErr) << "Failed to create open params: " << status; - - LSLaunchURLSpec launchSpec = { 0 }; - launchSpec.itemURLs = (CFArrayRef)itemsToOpen; - launchSpec.passThruParams = openParams; - launchSpec.launchFlags = kLSLaunchAsync | kLSLaunchDontAddToRecents; - LSOpenFromURLSpec(&launchSpec, NULL); -} - -// Returns whether the alternate error page checkbox should be checked based -// on the preference. -- (BOOL)showAlternateErrorPages { - return alternateErrorPages_.GetValue() ? YES : NO; -} - -// Sets the backend pref for whether or not the alternate error page checkbox -// should be displayed based on |value|. -- (void)setShowAlternateErrorPages:(BOOL)value { - if (value) - [self recordUserAction:UserMetricsAction( - "Options_LinkDoctorCheckbox_Enable")]; - else - [self recordUserAction:UserMetricsAction( - "Options_LinkDoctorCheckbox_Disable")]; - alternateErrorPages_.SetValueIfNotManaged(value ? true : false); -} - -// Returns whether the suggest checkbox should be checked based on the -// preference. -- (BOOL)useSuggest { - return useSuggest_.GetValue() ? YES : NO; -} - -// Sets the backend pref for whether or not the suggest checkbox should be -// displayed based on |value|. -- (void)setUseSuggest:(BOOL)value { - if (value) - [self recordUserAction:UserMetricsAction( - "Options_UseSuggestCheckbox_Enable")]; - else - [self recordUserAction:UserMetricsAction( - "Options_UseSuggestCheckbox_Disable")]; - useSuggest_.SetValueIfNotManaged(value ? true : false); -} - -// Returns whether the DNS prefetch checkbox should be checked based on the -// preference. -- (BOOL)dnsPrefetch { - return dnsPrefetch_.GetValue() ? YES : NO; -} - -// Sets the backend pref for whether or not the DNS prefetch checkbox should be -// displayed based on |value|. -- (void)setDnsPrefetch:(BOOL)value { - if (value) - [self recordUserAction:UserMetricsAction( - "Options_DnsPrefetchCheckbox_Enable")]; - else - [self recordUserAction:UserMetricsAction( - "Options_DnsPrefetchCheckbox_Disable")]; - dnsPrefetch_.SetValueIfNotManaged(value ? true : false); -} - -// Returns whether the safe browsing checkbox should be checked based on the -// preference. -- (BOOL)safeBrowsing { - return safeBrowsing_.GetValue() ? YES : NO; -} - -// Sets the backend pref for whether or not the safe browsing checkbox should be -// displayed based on |value|. -- (void)setSafeBrowsing:(BOOL)value { - if (value) - [self recordUserAction:UserMetricsAction( - "Options_SafeBrowsingCheckbox_Enable")]; - else - [self recordUserAction:UserMetricsAction( - "Options_SafeBrowsingCheckbox_Disable")]; - safeBrowsing_.SetValueIfNotManaged(value ? true : false); - SafeBrowsingService* safeBrowsingService = - g_browser_process->resource_dispatcher_host()->safe_browsing_service(); - MessageLoop::current()->PostTask( - FROM_HERE, - NewRunnableMethod(safeBrowsingService, - &SafeBrowsingService::OnEnable, - safeBrowsing_.GetValue())); -} - -// Returns whether the metrics reporting checkbox should be checked based on the -// preference. -- (BOOL)metricsReporting { - return metricsReporting_.GetValue() ? YES : NO; -} - -// Sets the backend pref for whether or not the metrics reporting checkbox -// should be displayed based on |value|. -- (void)setMetricsReporting:(BOOL)value { - if (value) - [self recordUserAction:UserMetricsAction( - "Options_MetricsReportingCheckbox_Enable")]; - else - [self recordUserAction:UserMetricsAction( - "Options_MetricsReportingCheckbox_Disable")]; - - // TODO(pinkerton): windows shows a dialog here telling the user they need to - // restart for this to take effect. http://crbug.com/34653 - metricsReporting_.SetValueIfNotManaged(value ? true : false); - - bool enabled = metricsReporting_.GetValue(); - GoogleUpdateSettings::SetCollectStatsConsent(enabled); - bool update_pref = GoogleUpdateSettings::GetCollectStatsConsent(); - if (enabled != update_pref) { - DVLOG(1) << "GENERAL SECTION: Unable to set crash report status to " - << enabled; - } - // Only change the pref if GoogleUpdateSettings::GetCollectStatsConsent - // succeeds. - enabled = update_pref; - - MetricsService* metrics = g_browser_process->metrics_service(); - DCHECK(metrics); - if (metrics) { - metrics->SetUserPermitsUpload(enabled); - if (enabled) - metrics->Start(); - else - metrics->Stop(); - } -} - -- (NSURL*)defaultDownloadLocation { - NSString* pathString = - base::SysUTF8ToNSString(defaultDownloadLocation_.GetValue()); - return [NSURL fileURLWithPath:pathString]; -} - -- (BOOL)askForSaveLocation { - return askForSaveLocation_.GetValue(); -} - -- (void)setAskForSaveLocation:(BOOL)value { - if (value) { - [self recordUserAction:UserMetricsAction( - "Options_AskForSaveLocation_Enable")]; - } else { - [self recordUserAction:UserMetricsAction( - "Options_AskForSaveLocation_Disable")]; - } - askForSaveLocation_.SetValue(value); -} - -- (BOOL)fileHandlerUIEnabled { - if (!profile_->GetDownloadManager()) // Not set in unit tests. - return NO; - return profile_->GetDownloadManager()->download_prefs()->IsAutoOpenUsed(); -} - -- (void)setFileHandlerUIEnabled:(BOOL)value { - [resetFileHandlersButton_ setEnabled:value]; -} - -- (BOOL)translateEnabled { - return translateEnabled_.GetValue(); -} - -- (void)setTranslateEnabled:(BOOL)value { - if (value) { - [self recordUserAction:UserMetricsAction("Options_Translate_Enable")]; - } else { - [self recordUserAction:UserMetricsAction("Options_Translate_Disable")]; - } - translateEnabled_.SetValue(value); -} - -- (BOOL)tabsToLinks { - return tabsToLinks_.GetValue(); -} - -- (void)setTabsToLinks:(BOOL)value { - if (value) { - [self recordUserAction:UserMetricsAction("Options_TabsToLinks_Enable")]; - } else { - [self recordUserAction:UserMetricsAction("Options_TabsToLinks_Disable")]; - } - tabsToLinks_.SetValue(value); -} - -- (void)fontAndLanguageEndSheet:(NSWindow*)sheet - returnCode:(NSInteger)returnCode - contextInfo:(void*)context { - [sheet close]; - [sheet orderOut:self]; - fontLanguageSettings_ = nil; -} - -- (IBAction)changeFontAndLanguageSettings:(id)sender { - // Intentionally leak the controller as it will clean itself up when the - // sheet closes. - fontLanguageSettings_ = - [[FontLanguageSettingsController alloc] initWithProfile:profile_]; - [NSApp beginSheet:[fontLanguageSettings_ window] - modalForWindow:[self window] - modalDelegate:self - didEndSelector:@selector(fontAndLanguageEndSheet:returnCode:contextInfo:) - contextInfo:nil]; -} - -// Called to launch the Keychain Access app to show the user's stored -// certificates. Note there's no way to script the app to auto-select the -// certificates. -- (IBAction)showCertificates:(id)sender { - [self recordUserAction:UserMetricsAction("Options_ManagerCerts")]; - [self launchKeychainAccess]; -} - -- (IBAction)resetToDefaults:(id)sender { - // The alert will clean itself up in the did-end selector. - NSAlert* alert = [[NSAlert alloc] init]; - [alert setMessageText:l10n_util::GetNSString(IDS_OPTIONS_RESET_MESSAGE)]; - NSButton* resetButton = [alert addButtonWithTitle: - l10n_util::GetNSString(IDS_OPTIONS_RESET_OKLABEL)]; - [resetButton setKeyEquivalent:@""]; - NSButton* cancelButton = [alert addButtonWithTitle: - l10n_util::GetNSString(IDS_OPTIONS_RESET_CANCELLABEL)]; - [cancelButton setKeyEquivalent:@"\r"]; - - [alert beginSheetModalForWindow:[self window] - modalDelegate:self - didEndSelector:@selector(resetToDefaults:returned:context:) - contextInfo:nil]; -} - -- (void)resetToDefaults:(NSAlert*)alert - returned:(NSInteger)code - context:(void*)context { - if (code == NSAlertFirstButtonReturn) { - OptionsUtil::ResetToDefaults(profile_); - } - [alert autorelease]; -} - -//------------------------------------------------------------------------- - -// Callback when preferences are changed. |prefName| is the name of the -// pref that has changed and should not be NULL. -- (void)prefChanged:(std::string*)prefName { - DCHECK(prefName); - if (!prefName) return; - [self basicsPrefChanged:prefName]; - [self userDataPrefChanged:prefName]; - [self underHoodPrefChanged:prefName]; -} - -// Callback when sync service state has changed. -// -// TODO(akalin): Decomp this out since a lot of it is copied from the -// Windows version. -// TODO(akalin): Change the background of the status label/link on error. -- (void)syncStateChanged { - DCHECK(syncService_); - - string16 statusLabel, linkLabel; - sync_ui_util::MessageType status = - sync_ui_util::GetStatusLabels(syncService_, &statusLabel, &linkLabel); - bool managed = syncService_->IsManaged(); - - [syncButton_ setEnabled:!syncService_->WizardIsVisible()]; - NSString* buttonLabel; - if (syncService_->HasSyncSetupCompleted()) { - buttonLabel = l10n_util::GetNSStringWithFixup( - IDS_SYNC_STOP_SYNCING_BUTTON_LABEL); - [syncCustomizeButton_ setHidden:false]; - } else if (syncService_->SetupInProgress()) { - buttonLabel = l10n_util::GetNSStringWithFixup( - IDS_SYNC_NTP_SETUP_IN_PROGRESS); - [syncCustomizeButton_ setHidden:true]; - } else { - buttonLabel = l10n_util::GetNSStringWithFixup( - IDS_SYNC_START_SYNC_BUTTON_LABEL); - [syncCustomizeButton_ setHidden:true]; - } - [syncCustomizeButton_ setEnabled:!managed]; - [syncButton_ setTitle:buttonLabel]; - [syncButton_ setEnabled:!managed]; - - [syncStatus_ setStringValue:base::SysUTF16ToNSString(statusLabel)]; - [syncLink_ setHidden:linkLabel.empty()]; - [syncLink_ setTitle:base::SysUTF16ToNSString(linkLabel)]; - [syncLink_ setEnabled:!managed]; - - NSButtonCell* syncLinkCell = static_cast<NSButtonCell*>([syncLink_ cell]); - if (!syncStatusNoErrorBackgroundColor_) { - DCHECK(!syncLinkNoErrorBackgroundColor_); - // We assume that the sync controls start off in a non-error - // state. - syncStatusNoErrorBackgroundColor_.reset( - [[syncStatus_ backgroundColor] retain]); - syncLinkNoErrorBackgroundColor_.reset( - [[syncLinkCell backgroundColor] retain]); - } - if (status == sync_ui_util::SYNC_ERROR) { - [syncStatus_ setBackgroundColor:syncErrorBackgroundColor_]; - [syncLinkCell setBackgroundColor:syncErrorBackgroundColor_]; - } else { - [syncStatus_ setBackgroundColor:syncStatusNoErrorBackgroundColor_]; - [syncLinkCell setBackgroundColor:syncLinkNoErrorBackgroundColor_]; - } -} - -// Show the preferences window. -- (IBAction)showPreferences:(id)sender { - [self showWindow:sender]; -} - -- (IBAction)toolbarButtonSelected:(id)sender { - DCHECK([sender isKindOfClass:[NSToolbarItem class]]); - OptionsPage page = [self getPageForToolbarItem:sender]; - [self displayPreferenceViewForPage:page animate:YES]; -} - -// Helper to update the window to display a preferences view for a page. -- (void)displayPreferenceViewForPage:(OptionsPage)page - animate:(BOOL)animate { - NSWindow* prefsWindow = [self window]; - - // Needs to go *after* the call to [self window], which triggers - // awakeFromNib if necessary. - NSView* prefsView = [self getPrefsViewForPage:page]; - NSView* contentView = [prefsWindow contentView]; - - // Make sure we aren't being told to display the same thing again. - if (currentPrefsView_ == prefsView && - managedPrefsBannerVisible_ == bannerState_->IsVisible()) { - return; - } - - // Remember new options page as current page. - if (page != OPTIONS_PAGE_DEFAULT) - lastSelectedPage_.SetValue(page); - - // Stop any running animation, and reset the subviews to the new state. We - // re-add any views we need for animation later. - [animation_ stopAnimation]; - NSView* oldPrefsView = currentPrefsView_; - currentPrefsView_ = prefsView; - [self resetSubViews]; - - // Update the banner state. - [self initBannerStateForPage:page]; - BOOL showBanner = bannerState_->IsVisible(); - - // Update the window title. - NSToolbarItem* toolbarItem = [self getToolbarItemForPage:page]; - [prefsWindow setTitle:[toolbarItem label]]; - - // Calculate new frames for the subviews. - NSRect prefsViewFrame = [prefsView frame]; - NSRect contentViewFrame = [contentView frame]; - NSRect bannerViewFrame = [managedPrefsBannerView_ frame]; - - // Determine what height the managed prefs banner will use. - CGFloat bannerViewHeight = showBanner ? NSHeight(bannerViewFrame) : 0.0; - - if (animate) { - // NSViewAnimation doesn't seem to honor subview resizing as it animates the - // Window's frame. So instead of trying to get the top in the right place, - // just set the origin where it should be at the end, and let the fade/size - // slide things into the right spot. - prefsViewFrame.origin.y = 0.0; - } else { - // The prefView is anchored to the top of its parent, so set its origin so - // that the top is where it should be. When the window's frame is set, the - // origin will be adjusted to keep it in the right spot. - prefsViewFrame.origin.y = NSHeight(contentViewFrame) - - NSHeight(prefsViewFrame) - bannerViewHeight; - } - bannerViewFrame.origin.y = NSHeight(prefsViewFrame); - bannerViewFrame.size.width = NSWidth(contentViewFrame); - [prefsView setFrame:prefsViewFrame]; - - // Figure out the size of the window. - NSRect windowFrame = [contentView convertRect:[prefsWindow frame] - fromView:nil]; - CGFloat titleToolbarHeight = - NSHeight(windowFrame) - NSHeight(contentViewFrame); - windowFrame.size.height = - NSHeight(prefsViewFrame) + titleToolbarHeight + bannerViewHeight; - DCHECK_GE(NSWidth(windowFrame), NSWidth(prefsViewFrame)) - << "Initial width set wasn't wide enough."; - windowFrame = [contentView convertRect:windowFrame toView:nil]; - windowFrame.origin.y = NSMaxY([prefsWindow frame]) - NSHeight(windowFrame); - - // Now change the size. - if (animate) { - NSMutableArray* animations = [NSMutableArray arrayWithCapacity:4]; - if (oldPrefsView != prefsView) { - // Fade between prefs views if they change. - [contentView addSubview:oldPrefsView - positioned:NSWindowBelow - relativeTo:nil]; - [animations addObject: - [NSDictionary dictionaryWithObjectsAndKeys: - oldPrefsView, NSViewAnimationTargetKey, - NSViewAnimationFadeOutEffect, NSViewAnimationEffectKey, - nil]]; - [animations addObject: - [NSDictionary dictionaryWithObjectsAndKeys: - prefsView, NSViewAnimationTargetKey, - NSViewAnimationFadeInEffect, NSViewAnimationEffectKey, - nil]]; - } else { - // Make sure the prefs pane ends up in the right position in case we - // manipulate the banner. - [animations addObject: - [NSDictionary dictionaryWithObjectsAndKeys: - prefsView, NSViewAnimationTargetKey, - [NSValue valueWithRect:prefsViewFrame], - NSViewAnimationEndFrameKey, - nil]]; - } - if (showBanner != managedPrefsBannerVisible_) { - // Slide the warning banner in or out of view. - [animations addObject: - [NSDictionary dictionaryWithObjectsAndKeys: - managedPrefsBannerView_, NSViewAnimationTargetKey, - [NSValue valueWithRect:bannerViewFrame], - NSViewAnimationEndFrameKey, - nil]]; - } - // Window resize animation. - [animations addObject: - [NSDictionary dictionaryWithObjectsAndKeys: - prefsWindow, NSViewAnimationTargetKey, - [NSValue valueWithRect:windowFrame], NSViewAnimationEndFrameKey, - nil]]; - [animation_ setViewAnimations:animations]; - // The default duration is 0.5s, which actually feels slow in here, so speed - // it up a bit. - [animation_ gtm_setDuration:0.2 - eventMask:NSLeftMouseUpMask]; - [animation_ startAnimation]; - } else { - // If not animating, odds are we don't want to display either (because it - // is initial window setup). - [prefsWindow setFrame:windowFrame display:NO]; - [managedPrefsBannerView_ setFrame:bannerViewFrame]; - } - - managedPrefsBannerVisible_ = showBanner; -} - -- (void)resetSubViews { - // Reset subviews to current prefs view and banner, remove any views that - // might have been left over from previous state or animation. - NSArray* subviews = [NSArray arrayWithObjects: - currentPrefsView_, managedPrefsBannerView_, nil]; - [[[self window] contentView] setSubviews:subviews]; - [[self window] setInitialFirstResponder:currentPrefsView_]; -} - -- (void)animationDidEnd:(NSAnimation*)animation { - DCHECK_EQ(animation_.get(), animation); - // Animation finished, reset subviews to current prefs view and the banner. - [self resetSubViews]; -} - -// Reinitializes the banner state tracker object to watch for managed bits of -// preferences relevant to the given options |page|. -- (void)initBannerStateForPage:(OptionsPage)page { - page = [self normalizePage:page]; - - bannerState_.reset( - new PreferencesWindowControllerInternal::ManagedPrefsBannerState( - self, page, g_browser_process->local_state(), prefs_)); -} - -- (void)switchToPage:(OptionsPage)page animate:(BOOL)animate { - [self displayPreferenceViewForPage:page animate:animate]; - NSToolbarItem* toolbarItem = [self getToolbarItemForPage:page]; - [toolbar_ setSelectedItemIdentifier:[toolbarItem itemIdentifier]]; -} - -// Called when the window is being closed. Send out a notification that the user -// is done editing preferences. Make sure there are no pending field editors -// by clearing the first responder. -- (void)windowWillClose:(NSNotification*)notification { - // Setting the first responder to the window ends any in-progress field - // editor. This will update the model appropriately so there's nothing left - // to do. - if (![[self window] makeFirstResponder:[self window]]) { - // We've hit a recalcitrant field editor, force it to go away. - [[self window] endEditingFor:nil]; - } - [self autorelease]; -} - -- (void)controlTextDidEndEditing:(NSNotification*)notification { - [customPagesSource_ validateURLs]; -} - -@end - -@implementation PreferencesWindowController(Testing) - -- (IntegerPrefMember*)lastSelectedPage { - return &lastSelectedPage_; -} - -- (NSToolbar*)toolbar { - return toolbar_; -} - -- (NSView*)basicsView { - return basicsView_; -} - -- (NSView*)personalStuffView { - return personalStuffView_; -} - -- (NSView*)underTheHoodView { - return underTheHoodView_; -} - -- (OptionsPage)normalizePage:(OptionsPage)page { - if (page == OPTIONS_PAGE_DEFAULT) { - // Get the last visited page from local state. - page = static_cast<OptionsPage>(lastSelectedPage_.GetValue()); - if (page == OPTIONS_PAGE_DEFAULT) { - page = OPTIONS_PAGE_GENERAL; - } - } - return page; -} - -- (NSToolbarItem*)getToolbarItemForPage:(OptionsPage)page { - NSUInteger pageIndex = (NSUInteger)[self normalizePage:page]; - NSArray* items = [toolbar_ items]; - NSUInteger itemCount = [items count]; - DCHECK_GE(pageIndex, 0U); - if (pageIndex >= itemCount) { - NOTIMPLEMENTED(); - pageIndex = 0; - } - DCHECK_GT(itemCount, 0U); - return [items objectAtIndex:pageIndex]; -} - -- (OptionsPage)getPageForToolbarItem:(NSToolbarItem*)toolbarItem { - // Tags are set in the nib file. - switch ([toolbarItem tag]) { - case 0: // Basics - return OPTIONS_PAGE_GENERAL; - case 1: // Personal Stuff - return OPTIONS_PAGE_CONTENT; - case 2: // Under the Hood - return OPTIONS_PAGE_ADVANCED; - default: - NOTIMPLEMENTED(); - return OPTIONS_PAGE_GENERAL; - } -} - -- (NSView*)getPrefsViewForPage:(OptionsPage)page { - // The views will be NULL if this is mistakenly called before awakeFromNib. - DCHECK(basicsView_); - DCHECK(personalStuffView_); - DCHECK(underTheHoodView_); - page = [self normalizePage:page]; - switch (page) { - case OPTIONS_PAGE_GENERAL: - return basicsView_; - case OPTIONS_PAGE_CONTENT: - return personalStuffView_; - case OPTIONS_PAGE_ADVANCED: - return underTheHoodView_; - case OPTIONS_PAGE_DEFAULT: - case OPTIONS_PAGE_COUNT: - LOG(DFATAL) << "Invalid page value " << page; - } - return basicsView_; -} - -@end diff --git a/chrome/browser/ui/cocoa/options/preferences_window_controller_unittest.mm b/chrome/browser/ui/cocoa/options/preferences_window_controller_unittest.mm deleted file mode 100644 index 6e57e2c..0000000 --- a/chrome/browser/ui/cocoa/options/preferences_window_controller_unittest.mm +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright (c) 2011 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/ui/cocoa/options/preferences_window_controller.h" - -#import <Cocoa/Cocoa.h> - -#import "base/scoped_nsobject.h" -#include "chrome/browser/prefs/browser_prefs.h" -#include "chrome/browser/ui/cocoa/browser_test_helper.h" -#include "chrome/browser/ui/cocoa/cocoa_test_helper.h" -#import "chrome/browser/ui/cocoa/options/custom_home_pages_model.h" -#include "chrome/browser/ui/options/options_window.h" -#include "chrome/common/pref_names.h" -#include "chrome/test/testing_browser_process.h" -#include "chrome/test/testing_pref_service.h" -#include "testing/gtest/include/gtest/gtest.h" -#import "testing/gtest_mac.h" -#include "testing/platform_test.h" - -// Helper Objective-C object that sets a BOOL when we get a particular -// callback from the prefs window. -@interface PrefsClosedObserver : NSObject { - @public - BOOL gotNotification_; -} -- (void)prefsWindowClosed:(NSNotification*)notify; -@end - -@implementation PrefsClosedObserver -- (void)prefsWindowClosed:(NSNotification*)notify { - gotNotification_ = YES; -} -@end - -namespace { - -class PrefsControllerTest : public CocoaTest { - public: - virtual void SetUp() { - CocoaTest::SetUp(); - browser::RegisterLocalState(&local_state_); - local_state_.RegisterBooleanPref(prefs::kMetricsReportingEnabled, false); - browser_process_.get()->SetPrefService(&local_state_); - - pref_controller_ = [[PreferencesWindowController alloc] - initWithProfile:browser_helper_.profile() - initialPage:OPTIONS_PAGE_DEFAULT]; - EXPECT_TRUE(pref_controller_); - } - - virtual void TearDown() { - [pref_controller_ close]; - CocoaTest::TearDown(); - } - - ScopedTestingBrowserProcess browser_process_; - TestingPrefService local_state_; - BrowserTestHelper browser_helper_; - PreferencesWindowController* pref_controller_; -}; - -// Test showing the preferences window and making sure it's visible, then -// making sure we get the notification when it's closed. -TEST_F(PrefsControllerTest, ShowAndClose) { - [pref_controller_ showPreferences:nil]; - EXPECT_TRUE([[pref_controller_ window] isVisible]); - - scoped_nsobject<PrefsClosedObserver> observer( - [[PrefsClosedObserver alloc] init]); - NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter]; - [defaultCenter addObserver:observer.get() - selector:@selector(prefsWindowClosed:) - name:NSWindowWillCloseNotification - object:[pref_controller_ window]]; - [[pref_controller_ window] performClose:observer]; - EXPECT_TRUE(observer.get()->gotNotification_); - [defaultCenter removeObserver:observer.get()]; - - // Prevent pref_controller_ from being closed again in TearDown() - pref_controller_ = nil; -} - -TEST_F(PrefsControllerTest, ValidateCustomHomePagesTable) { - // First, insert two valid URLs into the CustomHomePagesModel. - GURL url1("http://www.google.com/"); - GURL url2("http://maps.google.com/"); - std::vector<GURL> urls; - urls.push_back(url1); - urls.push_back(url2); - [[pref_controller_ customPagesSource] setURLs:urls]; - EXPECT_EQ(2U, [[pref_controller_ customPagesSource] countOfCustomHomePages]); - - // Now insert a bad (empty) URL into the model. - [[pref_controller_ customPagesSource] setURLStringEmptyAt:1]; - - // Send a notification to simulate the end of editing on a cell in the table - // which should trigger validation. - [pref_controller_ controlTextDidEndEditing:[NSNotification - notificationWithName:NSControlTextDidEndEditingNotification - object:nil]]; - EXPECT_EQ(1U, [[pref_controller_ customPagesSource] countOfCustomHomePages]); -} - -TEST_F(PrefsControllerTest, NormalizePage) { - EXPECT_EQ(OPTIONS_PAGE_GENERAL, - [pref_controller_ normalizePage:OPTIONS_PAGE_GENERAL]); - EXPECT_EQ(OPTIONS_PAGE_CONTENT, - [pref_controller_ normalizePage:OPTIONS_PAGE_CONTENT]); - EXPECT_EQ(OPTIONS_PAGE_ADVANCED, - [pref_controller_ normalizePage:OPTIONS_PAGE_ADVANCED]); - - [pref_controller_ lastSelectedPage]->SetValue(OPTIONS_PAGE_ADVANCED); - EXPECT_EQ(OPTIONS_PAGE_ADVANCED, - [pref_controller_ normalizePage:OPTIONS_PAGE_DEFAULT]); - - [pref_controller_ lastSelectedPage]->SetValue(OPTIONS_PAGE_DEFAULT); - EXPECT_EQ(OPTIONS_PAGE_GENERAL, - [pref_controller_ normalizePage:OPTIONS_PAGE_DEFAULT]); -} - -TEST_F(PrefsControllerTest, GetToolbarItemForPage) { - // Trigger awakeFromNib. - [pref_controller_ window]; - - NSArray* toolbarItems = [[pref_controller_ toolbar] items]; - EXPECT_EQ([toolbarItems objectAtIndex:0], - [pref_controller_ getToolbarItemForPage:OPTIONS_PAGE_GENERAL]); - EXPECT_EQ([toolbarItems objectAtIndex:1], - [pref_controller_ getToolbarItemForPage:OPTIONS_PAGE_CONTENT]); - EXPECT_EQ([toolbarItems objectAtIndex:2], - [pref_controller_ getToolbarItemForPage:OPTIONS_PAGE_ADVANCED]); - - [pref_controller_ lastSelectedPage]->SetValue(OPTIONS_PAGE_ADVANCED); - EXPECT_EQ([toolbarItems objectAtIndex:2], - [pref_controller_ getToolbarItemForPage:OPTIONS_PAGE_DEFAULT]); - - // Out-of-range argument. - EXPECT_EQ([toolbarItems objectAtIndex:0], - [pref_controller_ getToolbarItemForPage:OPTIONS_PAGE_COUNT]); -} - -TEST_F(PrefsControllerTest, GetPageForToolbarItem) { - scoped_nsobject<NSToolbarItem> toolbarItem( - [[NSToolbarItem alloc] initWithItemIdentifier:@""]); - [toolbarItem setTag:0]; - EXPECT_EQ(OPTIONS_PAGE_GENERAL, - [pref_controller_ getPageForToolbarItem:toolbarItem]); - [toolbarItem setTag:1]; - EXPECT_EQ(OPTIONS_PAGE_CONTENT, - [pref_controller_ getPageForToolbarItem:toolbarItem]); - [toolbarItem setTag:2]; - EXPECT_EQ(OPTIONS_PAGE_ADVANCED, - [pref_controller_ getPageForToolbarItem:toolbarItem]); - - // Out-of-range argument. - [toolbarItem setTag:3]; - EXPECT_EQ(OPTIONS_PAGE_GENERAL, - [pref_controller_ getPageForToolbarItem:toolbarItem]); -} - -TEST_F(PrefsControllerTest, GetPrefsViewForPage) { - // Trigger awakeFromNib. - [pref_controller_ window]; - - EXPECT_EQ([pref_controller_ basicsView], - [pref_controller_ getPrefsViewForPage:OPTIONS_PAGE_GENERAL]); - EXPECT_EQ([pref_controller_ personalStuffView], - [pref_controller_ getPrefsViewForPage:OPTIONS_PAGE_CONTENT]); - EXPECT_EQ([pref_controller_ underTheHoodView], - [pref_controller_ getPrefsViewForPage:OPTIONS_PAGE_ADVANCED]); - - [pref_controller_ lastSelectedPage]->SetValue(OPTIONS_PAGE_ADVANCED); - EXPECT_EQ([pref_controller_ underTheHoodView], - [pref_controller_ getPrefsViewForPage:OPTIONS_PAGE_DEFAULT]); -} - -TEST_F(PrefsControllerTest, SwitchToPage) { - // Trigger awakeFromNib. - NSWindow* window = [pref_controller_ window]; - - NSView* contentView = [window contentView]; - NSView* basicsView = [pref_controller_ basicsView]; - NSView* personalStuffView = [pref_controller_ personalStuffView]; - NSView* underTheHoodView = [pref_controller_ underTheHoodView]; - NSToolbar* toolbar = [pref_controller_ toolbar]; - NSToolbarItem* basicsToolbarItem = - [pref_controller_ getToolbarItemForPage:OPTIONS_PAGE_GENERAL]; - NSToolbarItem* personalStuffToolbarItem = - [pref_controller_ getToolbarItemForPage:OPTIONS_PAGE_CONTENT]; - NSToolbarItem* underTheHoodToolbarItem = - [pref_controller_ getToolbarItemForPage:OPTIONS_PAGE_ADVANCED]; - NSString* basicsIdentifier = [basicsToolbarItem itemIdentifier]; - NSString* personalStuffIdentifier = [personalStuffToolbarItem itemIdentifier]; - NSString* underTheHoodIdentifier = [underTheHoodToolbarItem itemIdentifier]; - IntegerPrefMember* lastSelectedPage = [pref_controller_ lastSelectedPage]; - - // Test without animation. - - [pref_controller_ switchToPage:OPTIONS_PAGE_GENERAL animate:NO]; - EXPECT_TRUE([basicsView isDescendantOf:contentView]); - EXPECT_FALSE([personalStuffView isDescendantOf:contentView]); - EXPECT_FALSE([underTheHoodView isDescendantOf:contentView]); - EXPECT_NSEQ(basicsIdentifier, [toolbar selectedItemIdentifier]); - EXPECT_EQ(OPTIONS_PAGE_GENERAL, lastSelectedPage->GetValue()); - EXPECT_NSEQ([basicsToolbarItem label], [window title]); - - [pref_controller_ switchToPage:OPTIONS_PAGE_CONTENT animate:NO]; - EXPECT_FALSE([basicsView isDescendantOf:contentView]); - EXPECT_TRUE([personalStuffView isDescendantOf:contentView]); - EXPECT_FALSE([underTheHoodView isDescendantOf:contentView]); - EXPECT_NSEQ([toolbar selectedItemIdentifier], personalStuffIdentifier); - EXPECT_EQ(OPTIONS_PAGE_CONTENT, lastSelectedPage->GetValue()); - EXPECT_NSEQ([personalStuffToolbarItem label], [window title]); - - [pref_controller_ switchToPage:OPTIONS_PAGE_ADVANCED animate:NO]; - EXPECT_FALSE([basicsView isDescendantOf:contentView]); - EXPECT_FALSE([personalStuffView isDescendantOf:contentView]); - EXPECT_TRUE([underTheHoodView isDescendantOf:contentView]); - EXPECT_NSEQ([toolbar selectedItemIdentifier], underTheHoodIdentifier); - EXPECT_EQ(OPTIONS_PAGE_ADVANCED, lastSelectedPage->GetValue()); - EXPECT_NSEQ([underTheHoodToolbarItem label], [window title]); - - // Test OPTIONS_PAGE_DEFAULT. - - lastSelectedPage->SetValue(OPTIONS_PAGE_CONTENT); - [pref_controller_ switchToPage:OPTIONS_PAGE_DEFAULT animate:NO]; - EXPECT_FALSE([basicsView isDescendantOf:contentView]); - EXPECT_TRUE([personalStuffView isDescendantOf:contentView]); - EXPECT_FALSE([underTheHoodView isDescendantOf:contentView]); - EXPECT_NSEQ(personalStuffIdentifier, [toolbar selectedItemIdentifier]); - EXPECT_EQ(OPTIONS_PAGE_CONTENT, lastSelectedPage->GetValue()); - EXPECT_NSEQ([personalStuffToolbarItem label], [window title]); - - // TODO(akalin): Figure out how to test animation; we'll need everything - // to stick around until the animation finishes. -} - -// TODO(akalin): Figure out how to test sync controls. -// TODO(akalin): Figure out how to test that sync controls are not shown -// when there isn't a sync service. - -} // namespace diff --git a/chrome/browser/ui/cocoa/options/search_engine_list_model.h b/chrome/browser/ui/cocoa/options/search_engine_list_model.h deleted file mode 100644 index a83d83c..0000000 --- a/chrome/browser/ui/cocoa/options/search_engine_list_model.h +++ /dev/null @@ -1,48 +0,0 @@ -// 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_UI_COCOA_OPTIONS_SEARCH_ENGINE_LIST_MODEL_H_ -#define CHROME_BROWSER_UI_COCOA_OPTIONS_SEARCH_ENGINE_LIST_MODEL_H_ -#pragma once - -#import <Cocoa/Cocoa.h> - -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" - -class TemplateURLModel; -class SearchEngineObserver; - -// The model for the "default search engine" combobox in preferences. Bridges -// between the cross-platform TemplateURLModel and Cocoa while watching for -// changes to the cross-platform model. - -@interface SearchEngineListModel : NSObject { - @private - TemplateURLModel* model_; // weak, owned by Profile - scoped_ptr<SearchEngineObserver> observer_; // watches for model changes - scoped_nsobject<NSArray> engines_; -} - -// Initialize with the given template model. -- (id)initWithModel:(TemplateURLModel*)model; - -// Returns an array of NSString's corresponding to the user-visible names of the -// search engines. -- (NSArray*)searchEngines; - -// The index into |-searchEngines| of the current default search engine. If -// there is no default search engine, the value is -1. The setter changes the -// back-end preference. -- (NSInteger)defaultIndex; -- (void)setDefaultIndex:(NSInteger)index; -// Return TRUE if the default is managed via policy. -- (BOOL)isDefaultManaged; -@end - -// Broadcast when the cross-platform model changes. This can be used to update -// any view state that may rely on the position of items in the list. -extern NSString* const kSearchEngineListModelChangedNotification; - -#endif // CHROME_BROWSER_UI_COCOA_OPTIONS_SEARCH_ENGINE_LIST_MODEL_H_ diff --git a/chrome/browser/ui/cocoa/options/search_engine_list_model.mm b/chrome/browser/ui/cocoa/options/search_engine_list_model.mm deleted file mode 100644 index b46e571..0000000 --- a/chrome/browser/ui/cocoa/options/search_engine_list_model.mm +++ /dev/null @@ -1,136 +0,0 @@ -// 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/ui/cocoa/options/search_engine_list_model.h" - -#include "base/sys_string_conversions.h" -#include "chrome/browser/search_engines/template_url.h" -#include "chrome/browser/search_engines/template_url_model.h" -#include "chrome/browser/search_engines/template_url_model_observer.h" - -NSString* const kSearchEngineListModelChangedNotification = - @"kSearchEngineListModelChangedNotification"; - -@interface SearchEngineListModel(Private) -- (void)buildEngineList; -@end - -// C++ bridge from TemplateURLModel to our Obj-C model. When it's told about -// model changes, notifies us to rebuild the list. -class SearchEngineObserver : public TemplateURLModelObserver { - public: - SearchEngineObserver(SearchEngineListModel* notify) - : notify_(notify) { } - virtual ~SearchEngineObserver() { }; - - private: - // TemplateURLModelObserver methods. - virtual void OnTemplateURLModelChanged() { [notify_ buildEngineList]; } - - SearchEngineListModel* notify_; // weak, owns us -}; - -@implementation SearchEngineListModel - -// The windows code allows for a NULL |model| and checks for it throughout -// the code, though I'm not sure why. We follow suit. -- (id)initWithModel:(TemplateURLModel*)model { - if ((self = [super init])) { - model_ = model; - if (model_) { - observer_.reset(new SearchEngineObserver(self)); - model_->Load(); - model_->AddObserver(observer_.get()); - [self buildEngineList]; - } - } - return self; -} - -- (void)dealloc { - if (model_) - model_->RemoveObserver(observer_.get()); - [super dealloc]; -} - -// Returns an array of NSString's corresponding to the user-visible names of the -// search engines. -- (NSArray*)searchEngines { - return engines_.get(); -} - -- (void)setSearchEngines:(NSArray*)engines { - engines_.reset([engines retain]); - - // Tell anyone who's listening that something has changed so they need to - // adjust the UI. - [[NSNotificationCenter defaultCenter] - postNotificationName:kSearchEngineListModelChangedNotification - object:nil]; -} - -// Walks the model and builds an array of NSStrings to display to the user. -// Assumes there is a non-NULL model. -- (void)buildEngineList { - scoped_nsobject<NSMutableArray> engines([[NSMutableArray alloc] init]); - - typedef std::vector<const TemplateURL*> TemplateURLs; - TemplateURLs modelURLs = model_->GetTemplateURLs(); - for (size_t i = 0; i < modelURLs.size(); ++i) { - if (modelURLs[i]->ShowInDefaultList()) - [engines addObject:base::SysUTF16ToNSString(modelURLs[i]->short_name())]; - } - - [self setSearchEngines:engines.get()]; -} - -// The index into |-searchEngines| of the current default search engine. -// -1 if there is no default. -- (NSInteger)defaultIndex { - if (!model_) return -1; - - NSInteger index = 0; - const TemplateURL* defaultSearchProvider = model_->GetDefaultSearchProvider(); - if (defaultSearchProvider) { - typedef std::vector<const TemplateURL*> TemplateURLs; - TemplateURLs urls = model_->GetTemplateURLs(); - for (std::vector<const TemplateURL*>::iterator it = urls.begin(); - it != urls.end(); ++it) { - const TemplateURL* url = *it; - // Skip all the URLs not shown on the default list. - if (!url->ShowInDefaultList()) - continue; - if (url->id() == defaultSearchProvider->id()) - return index; - ++index; - } - } - return -1; -} - -- (void)setDefaultIndex:(NSInteger)index { - if (model_) { - typedef std::vector<const TemplateURL*> TemplateURLs; - TemplateURLs urls = model_->GetTemplateURLs(); - for (std::vector<const TemplateURL*>::iterator it = urls.begin(); - it != urls.end(); ++it) { - const TemplateURL* url = *it; - // Skip all the URLs not shown on the default list. - if (!url->ShowInDefaultList()) - continue; - if (0 == index) { - model_->SetDefaultSearchProvider(url); - return; - } - --index; - } - DCHECK(false); - } -} - -// Return TRUE if the default is managed via policy. -- (BOOL)isDefaultManaged { - return model_->is_default_search_managed(); -} -@end diff --git a/chrome/browser/ui/cocoa/options/search_engine_list_model_unittest.mm b/chrome/browser/ui/cocoa/options/search_engine_list_model_unittest.mm deleted file mode 100644 index b82f095..0000000 --- a/chrome/browser/ui/cocoa/options/search_engine_list_model_unittest.mm +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (c) 2011 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. - -#include "base/scoped_nsobject.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/search_engines/template_url.h" -#include "chrome/browser/search_engines/template_url_model.h" -#include "chrome/browser/ui/cocoa/browser_test_helper.h" -#import "chrome/browser/ui/cocoa/options/search_engine_list_model.h" -#include "testing/gtest/include/gtest/gtest.h" -#import "testing/gtest_mac.h" -#include "testing/platform_test.h" - -// A helper for NSNotifications. Makes a note that it's been called back. -@interface SearchEngineListHelper : NSObject { - @public - BOOL sawNotification_; -} -@end - -@implementation SearchEngineListHelper -- (void)entryChanged:(NSNotification*)notify { - sawNotification_ = YES; -} -@end - -class SearchEngineListModelTest : public PlatformTest { - public: - SearchEngineListModelTest() { - // Build a fake set of template urls. - template_model_.reset(new TemplateURLModel(helper_.profile())); - TemplateURL* t_url = new TemplateURL(); - t_url->SetURL("http://www.google.com/?q={searchTerms}", 0, 0); - t_url->set_keyword(ASCIIToUTF16("keyword")); - t_url->set_short_name(ASCIIToUTF16("google")); - t_url->set_show_in_default_list(true); - template_model_->Add(t_url); - t_url = new TemplateURL(); - t_url->SetURL("http://www.google2.com/?q={searchTerms}", 0, 0); - t_url->set_keyword(ASCIIToUTF16("keyword2")); - t_url->set_short_name(ASCIIToUTF16("google2")); - t_url->set_show_in_default_list(true); - template_model_->Add(t_url); - EXPECT_EQ(template_model_->GetTemplateURLs().size(), 2U); - - model_.reset([[SearchEngineListModel alloc] - initWithModel:template_model_.get()]); - notification_helper_.reset([[SearchEngineListHelper alloc] init]); - [[NSNotificationCenter defaultCenter] - addObserver:notification_helper_.get() - selector:@selector(entryChanged:) - name:kSearchEngineListModelChangedNotification - object:nil]; - } - ~SearchEngineListModelTest() { - [[NSNotificationCenter defaultCenter] - removeObserver:notification_helper_.get()]; - } - - BrowserTestHelper helper_; - scoped_ptr<TemplateURLModel> template_model_; - scoped_nsobject<SearchEngineListModel> model_; - scoped_nsobject<SearchEngineListHelper> notification_helper_; -}; - -TEST_F(SearchEngineListModelTest, Init) { - scoped_nsobject<SearchEngineListModel> model( - [[SearchEngineListModel alloc] initWithModel:template_model_.get()]); -} - -TEST_F(SearchEngineListModelTest, Engines) { - NSArray* engines = [model_ searchEngines]; - EXPECT_EQ([engines count], 2U); -} - -TEST_F(SearchEngineListModelTest, Default) { - EXPECT_EQ([model_ defaultIndex], -1); - - [model_ setDefaultIndex:1]; - EXPECT_EQ([model_ defaultIndex], 1); - - // Add two more URLs, neither of which are shown in the default list. - TemplateURL* t_url = new TemplateURL(); - t_url->SetURL("http://www.google3.com/?q={searchTerms}", 0, 0); - t_url->set_keyword(ASCIIToUTF16("keyword3")); - t_url->set_short_name(ASCIIToUTF16("google3 not eligible")); - t_url->set_show_in_default_list(false); - template_model_->Add(t_url); - t_url = new TemplateURL(); - t_url->SetURL("http://www.google4.com/?q={searchTerms}", 0, 0); - t_url->set_keyword(ASCIIToUTF16("keyword4")); - t_url->set_short_name(ASCIIToUTF16("google4")); - t_url->set_show_in_default_list(false); - template_model_->Add(t_url); - - // Still should only have 2 engines and not these newly added ones. - EXPECT_EQ([[model_ searchEngines] count], 2U); - - // Since keyword3 is not in the default list, the 2nd index in the default - // keyword list should be keyword4. Test for http://crbug.com/21898. - template_model_->SetDefaultSearchProvider(t_url); - EXPECT_EQ([[model_ searchEngines] count], 3U); - EXPECT_EQ([model_ defaultIndex], 2); - - NSString* defaultString = [[model_ searchEngines] objectAtIndex:2]; - EXPECT_NSEQ(@"google4", defaultString); -} - -TEST_F(SearchEngineListModelTest, DefaultChosenFromUI) { - EXPECT_EQ([model_ defaultIndex], -1); - - [model_ setDefaultIndex:1]; - EXPECT_EQ([model_ defaultIndex], 1); - - // Add two more URLs, the first one not shown in the default list. - TemplateURL* t_url = new TemplateURL(); - t_url->SetURL("http://www.google3.com/?q={searchTerms}", 0, 0); - t_url->set_keyword(ASCIIToUTF16("keyword3")); - t_url->set_short_name(ASCIIToUTF16("google3 not eligible")); - t_url->set_show_in_default_list(false); - template_model_->Add(t_url); - t_url = new TemplateURL(); - t_url->SetURL("http://www.google4.com/?q={searchTerms}", 0, 0); - t_url->set_keyword(ASCIIToUTF16("keyword4")); - t_url->set_short_name(ASCIIToUTF16("google4")); - t_url->set_show_in_default_list(true); - template_model_->Add(t_url); - - // We should have 3 engines. - EXPECT_EQ([[model_ searchEngines] count], 3U); - - // Simulate the UI setting the default to the third entry. - [model_ setDefaultIndex:2]; - EXPECT_EQ([model_ defaultIndex], 2); - - // The default search provider should be google4. - EXPECT_EQ(template_model_->GetDefaultSearchProvider(), t_url); -} - -// Make sure that when the back-end model changes that we get a notification. -TEST_F(SearchEngineListModelTest, Notification) { - // Add one more item to force a notification. - TemplateURL* t_url = new TemplateURL(); - t_url->SetURL("http://www.google3.com/foo/bar", 0, 0); - t_url->set_keyword(ASCIIToUTF16("keyword3")); - t_url->set_short_name(ASCIIToUTF16("google3")); - t_url->set_show_in_default_list(true); - template_model_->Add(t_url); - - EXPECT_TRUE(notification_helper_.get()->sawNotification_); -} diff --git a/chrome/browser/ui/cocoa/page_info_bubble_controller.h b/chrome/browser/ui/cocoa/page_info_bubble_controller.h index 1b21215..d1ca865 100644 --- a/chrome/browser/ui/cocoa/page_info_bubble_controller.h +++ b/chrome/browser/ui/cocoa/page_info_bubble_controller.h @@ -4,8 +4,8 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/page_info_model.h" #import "chrome/browser/ui/cocoa/base_bubble_controller.h" diff --git a/chrome/browser/ui/cocoa/page_info_bubble_controller.mm b/chrome/browser/ui/cocoa/page_info_bubble_controller.mm index 5a883a6..d2911d3 100644 --- a/chrome/browser/ui/cocoa/page_info_bubble_controller.mm +++ b/chrome/browser/ui/cocoa/page_info_bubble_controller.mm @@ -7,17 +7,17 @@ #include "base/message_loop.h" #include "base/sys_string_conversions.h" #include "base/task.h" -#include "chrome/browser/browser_list.h" #include "chrome/browser/google/google_util.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser_list.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/hyperlink_button_cell.h" #import "chrome/browser/ui/cocoa/info_bubble_view.h" #import "chrome/browser/ui/cocoa/info_bubble_window.h" #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" #include "chrome/common/url_constants.h" -#include "content/browser/certificate_viewer.h" #include "content/browser/cert_store.h" +#include "content/browser/certificate_viewer.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" #include "net/base/cert_status_flags.h" @@ -275,10 +275,6 @@ void ShowPageInfoBubble(gfx::NativeWindow parent, [[PageInfoContentView alloc] initWithFrame:contentFrame]); [contentView setSubviews:subviews]; - // Replace the window's content. - [[[self window] contentView] setSubviews: - [NSArray arrayWithObject:contentView]]; - NSRect windowFrame = NSMakeRect(0, 0, kWindowWidth, offset); windowFrame.size = [[[self window] contentView] convertSize:windowFrame.size toView:nil]; @@ -293,6 +289,10 @@ void ShowPageInfoBubble(gfx::NativeWindow parent, display:YES animate:[[self window] isVisible]]; + // Replace the window's content. + [[[self window] contentView] setSubviews: + [NSArray arrayWithObject:contentView]]; + NSPoint anchorPoint = [self anchorPointForWindowWithHeight:NSHeight(windowFrame) parentWindow:[self parentWindow]]; @@ -320,6 +320,7 @@ void ShowPageInfoBubble(gfx::NativeWindow parent, // in the bubble. - (void)configureTextFieldAsLabel:(NSTextField*)textField { [textField setEditable:NO]; + [textField setSelectable:YES]; [textField setDrawsBackground:NO]; [textField setBezeled:NO]; } @@ -382,8 +383,7 @@ void ShowPageInfoBubble(gfx::NativeWindow parent, scoped_refptr<net::X509Certificate> cert; CertStore::GetInstance()->RetrieveCert(certID_, &cert); - // Don't bother showing certificates if there isn't one. Gears runs - // with no OS root certificate. + // Don't bother showing certificates if there isn't one. if (!cert.get() || !cert->os_cert_handle()) { // This should only ever happen in unit tests. [certButton setEnabled:NO]; diff --git a/chrome/browser/ui/cocoa/page_info_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/page_info_bubble_controller_unittest.mm index cc640d0..52dfce5 100644 --- a/chrome/browser/ui/cocoa/page_info_bubble_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/page_info_bubble_controller_unittest.mm @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/string_util.h" #include "base/string_number_conversions.h" #include "base/sys_string_conversions.h" diff --git a/chrome/browser/ui/cocoa/profile_menu_button.h b/chrome/browser/ui/cocoa/profile_menu_button.h new file mode 100644 index 0000000..ca5dc82 --- /dev/null +++ b/chrome/browser/ui/cocoa/profile_menu_button.h @@ -0,0 +1,39 @@ +// Copyright (c) 2011 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_UI_COCOA_PROFILE_MENU_BUTTON_H_ +#define CHROME_BROWSER_UI_COCOA_PROFILE_MENU_BUTTON_H_ +#pragma once + +#import <Cocoa/Cocoa.h> + +#include "base/memory/scoped_nsobject.h" + +// PopUp button that shows the multiprofile menu. +@interface ProfileMenuButton : NSPopUpButton { + @private + BOOL shouldShowProfileDisplayName_; + scoped_nsobject<NSTextFieldCell> textFieldCell_; + + scoped_nsobject<NSImage> cachedTabImage_; + // Cache the various button states when creating |cachedTabImage_|. If + // any of these states change then the cached image is invalidated. + BOOL cachedTabImageIsPressed_; +} + +@property(assign,nonatomic) BOOL shouldShowProfileDisplayName; +@property(assign,nonatomic) NSString* profileDisplayName; + +// Gets the size of the control that would display all its contents. +- (NSSize)desiredControlSize; +// Gets the minimum size that the control should be resized to. +- (NSSize)minControlSize; + +// Public for testing. +- (void) mouseDown:(NSEvent*)event + withShowMenuTarget:(id)target; + +@end + +#endif // CHROME_BROWSER_UI_COCOA_PROFILE_MENU_BUTTON_H_ diff --git a/chrome/browser/ui/cocoa/profile_menu_button.mm b/chrome/browser/ui/cocoa/profile_menu_button.mm new file mode 100644 index 0000000..866bb40 --- /dev/null +++ b/chrome/browser/ui/cocoa/profile_menu_button.mm @@ -0,0 +1,395 @@ +// Copyright (c) 2011 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/ui/cocoa/profile_menu_button.h" + +#include <algorithm> + +#include "base/logging.h" +#import "third_party/GTM/AppKit/GTMFadeTruncatingTextFieldCell.h" + +namespace { + +const CGFloat kTabWidth = 24; +const CGFloat kTabHeight = 13; +const CGFloat kTabArrowWidth = 7; +const CGFloat kTabArrowHeight = 4; +const CGFloat kTabRoundRectRadius = 5; +const CGFloat kTabDisplayNameMarginY = 3; + +NSColor* GetWhiteWithAlpha(CGFloat alpha) { + return [NSColor colorWithCalibratedWhite:1.0 alpha:alpha]; +} + +NSColor* GetBlackWithAlpha(CGFloat alpha) { + return [NSColor colorWithCalibratedWhite:0.0 alpha:alpha]; +} + +} // namespace + +@interface ProfileMenuButton (Private) +- (void)commonInit; +- (NSPoint)popUpMenuPosition; +- (NSImage*)tabImage; +- (NSRect)textFieldRect; +- (NSBezierPath*)tabPathWithRect:(NSRect)rect + radius:(CGFloat)radius; +- (NSBezierPath*)downArrowPathWithRect:(NSRect)rect; +- (NSImage*)tabImageWithSize:(NSSize)tabSize + fillColor:(NSColor*)fillColor + isPressed:(BOOL)isPressed; +@end + +@implementation ProfileMenuButton + +@synthesize shouldShowProfileDisplayName = shouldShowProfileDisplayName_; + +- (void)commonInit { + textFieldCell_.reset( + [[GTMFadeTruncatingTextFieldCell alloc] initTextCell:@""]); + [textFieldCell_ setBackgroundStyle:NSBackgroundStyleRaised]; + [textFieldCell_ setAlignment:NSRightTextAlignment]; + [textFieldCell_ setFont:[NSFont systemFontOfSize: + [NSFont smallSystemFontSize]]]; +} + +- (id)initWithFrame:(NSRect)frame + pullsDown:(BOOL)flag { + if ((self = [super initWithFrame:frame pullsDown:flag])) + [self commonInit]; + return self; +} + +- (id)initWithCoder:(NSCoder*)decoder { + if ((self = [super initWithCoder:decoder])) + [self commonInit]; + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [super dealloc]; +} + +- (NSString*)profileDisplayName { + return [textFieldCell_ stringValue]; +} + +- (void)setProfileDisplayName:(NSString*)name { + if (![[textFieldCell_ stringValue] isEqual:name]) { + [textFieldCell_ setStringValue:name]; + [self setNeedsDisplay:YES]; + } +} + +- (void)setShouldShowProfileDisplayName:(BOOL)flag { + shouldShowProfileDisplayName_ = flag; + [self setNeedsDisplay:YES]; +} + +- (BOOL)isFlipped { + return NO; +} + +- (void)viewWillMoveToWindow:(NSWindow*)newWindow { + if ([self window] == newWindow) + return; + + if ([self window]) { + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:NSWindowDidBecomeMainNotification + object:[self window]]; + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:NSWindowDidResignMainNotification + object:[self window]]; + } + + if (newWindow) { + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(onWindowFocusChanged:) + name:NSWindowDidBecomeMainNotification + object:newWindow]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(onWindowFocusChanged:) + name:NSWindowDidResignMainNotification + object:newWindow]; + } +} + +- (void)onWindowFocusChanged:(NSNotification*)note { + [self setNeedsDisplay:YES]; +} + +- (NSRect)tabRect { + NSRect bounds = [self bounds]; + NSRect tabRect; + tabRect.size.width = kTabWidth; + tabRect.size.height = kTabHeight; + tabRect.origin.x = NSMaxX(bounds) - NSWidth(tabRect); + tabRect.origin.y = NSMaxY(bounds) - NSHeight(tabRect); + return tabRect; +} + +- (NSRect)textFieldRect { + NSRect bounds = [self bounds]; + NSSize desiredSize = [textFieldCell_ cellSize]; + + NSRect textRect = bounds; + textRect.size.height = std::min(desiredSize.height, NSHeight(bounds)); + + // For some reason there's always a 2 pixel gap on the right side of the + // text field. Fix it by moving the text field to the right by 2 pixels. + textRect.origin.x += 2; + + return textRect; +} + +- (NSView*)hitTest:(NSPoint)aPoint { + NSView* probe = [super hitTest:aPoint]; + if (probe != self) + return probe; + + NSPoint viewPoint = [self convertPoint:aPoint fromView:[self superview]]; + BOOL isFlipped = [self isFlipped]; + if (NSMouseInRect(viewPoint, [self tabRect], isFlipped)) + return self; + else + return nil; +} + +- (NSBezierPath*)tabPathWithRect:(NSRect)rect + radius:(CGFloat)radius { + const NSRect innerRect = NSInsetRect(rect, radius, radius); + NSBezierPath* path = [NSBezierPath bezierPath]; + + // Top left + [path moveToPoint:NSMakePoint(NSMinX(rect), NSMaxY(rect))]; + + // Bottom left + [path lineToPoint:NSMakePoint(NSMinX(rect), NSMinY(innerRect))]; + [path appendBezierPathWithArcWithCenter:NSMakePoint(NSMinX(innerRect), + NSMinY(innerRect)) + radius:radius + startAngle:180 + endAngle:270 + clockwise:NO]; + + // Bottom right + [path lineToPoint:NSMakePoint(NSMaxX(innerRect), NSMinY(rect))]; + [path appendBezierPathWithArcWithCenter:NSMakePoint(NSMaxX(innerRect), + NSMinY(innerRect)) + radius:radius + startAngle:270 + endAngle:360 + clockwise:NO]; + + // Top right + [path lineToPoint:NSMakePoint(NSMaxX(rect), NSMaxY(rect))]; + + [path closePath]; + return path; +} + +- (NSBezierPath*)downArrowPathWithRect:(NSRect)rect { + NSBezierPath* path = [NSBezierPath bezierPath]; + + // Top left + [path moveToPoint:NSMakePoint(NSMinX(rect), NSMaxY(rect))]; + + // Bottom middle + [path lineToPoint:NSMakePoint(NSMidX(rect), NSMinY(rect))]; + + // Top right + [path lineToPoint:NSMakePoint(NSMaxX(rect), NSMaxY(rect))]; + + [path closePath]; + return path; +} + +- (NSImage*)tabImageWithSize:(NSSize)tabSize + fillColor:(NSColor*)fillColor + isPressed:(BOOL)isPressed { + NSImage* image = [[[NSImage alloc] initWithSize:tabSize] autorelease]; + [image lockFocus]; + + // White shadow for inset look + [[NSGraphicsContext currentContext] saveGraphicsState]; + scoped_nsobject<NSShadow> tabShadow([[NSShadow alloc] init]); + [tabShadow.get() setShadowOffset:NSMakeSize(0, -1)]; + [tabShadow setShadowBlurRadius:0]; + [tabShadow.get() setShadowColor:GetWhiteWithAlpha(0.6)]; + [tabShadow set]; + + // Gray outline + NSRect tabRect = NSMakeRect(0, 1, tabSize.width, tabSize.height - 1); + NSBezierPath* outlinePath = [self tabPathWithRect:tabRect + radius:kTabRoundRectRadius]; + [[NSColor colorWithCalibratedWhite:0.44 alpha:1.0] set]; + [outlinePath fill]; + + [[NSGraphicsContext currentContext] restoreGraphicsState]; + + // Fill + NSRect fillRect = NSInsetRect(tabRect, 1, 0); + fillRect.size.height -= 1; + fillRect.origin.y += 1; + NSBezierPath* fillPath = [self tabPathWithRect:fillRect + radius:kTabRoundRectRadius - 1]; + [fillColor set]; + [fillPath fill]; + + // Shading for fill to make the bottom of the tab slightly darker. + scoped_nsobject<NSGradient> gradient([[NSGradient alloc] + initWithStartingColor:GetBlackWithAlpha(isPressed ? 0.2 : 0.0) + endingColor:GetBlackWithAlpha(0.2)]); + [gradient drawInBezierPath:fillPath angle:270]; + + // Highlight on top + NSRect highlightRect = NSInsetRect(tabRect, 1, 0); + highlightRect.size.height = 1; + highlightRect.origin.y = NSMaxY(tabRect) - highlightRect.size.height; + [GetWhiteWithAlpha(0.5) set]; + NSRectFillUsingOperation(highlightRect, NSCompositeSourceOver); + + // Arrow shadow + [[NSGraphicsContext currentContext] saveGraphicsState]; + scoped_nsobject<NSShadow> arrowShadow([[NSShadow alloc] init]); + [arrowShadow.get() setShadowOffset:NSMakeSize(0, -1)]; + [arrowShadow setShadowBlurRadius:0]; + [arrowShadow.get() setShadowColor:GetBlackWithAlpha(0.6)]; + [arrowShadow set]; + + // Down arrow + NSRect arrowRect; + arrowRect.size.width = kTabArrowWidth; + arrowRect.size.height = kTabArrowHeight; + arrowRect.origin.x = NSMinX(tabRect) + roundf((NSWidth(tabRect) - + NSWidth(arrowRect)) / 2.0); + arrowRect.origin.y = NSMinY(tabRect) + roundf((tabRect.size.height - + arrowRect.size.height) / 2.0); + NSBezierPath* arrowPath = [self downArrowPathWithRect:arrowRect]; + if (isPressed) + [[NSColor colorWithCalibratedWhite:0.8 alpha:1.0] set]; + else + [[NSColor whiteColor] set]; + [arrowPath fill]; + + [[NSGraphicsContext currentContext] restoreGraphicsState]; + + [image unlockFocus]; + return image; +} + +- (NSImage*)tabImage { + BOOL isPressed = [[self cell] isHighlighted]; + + // Invalidate the cached image if necessary. + if (cachedTabImageIsPressed_ != isPressed) { + cachedTabImageIsPressed_ = isPressed; + cachedTabImage_.reset(); + } + + if (cachedTabImage_) + return cachedTabImage_; + + // TODO: Use different colors for different profiles and tint for + // the current browser theme. + NSColor* fillColor = [NSColor colorWithCalibratedRed:122.0/255.0 + green:177.0/255.0 + blue:252.0/255.0 + alpha:1.0]; + NSRect tabRect = [self tabRect]; + cachedTabImage_.reset([[self tabImageWithSize:tabRect.size + fillColor:fillColor + isPressed:isPressed] retain]); + return cachedTabImage_; +} + +- (void)drawRect:(NSRect)rect { + CGFloat alpha = [[self window] isMainWindow] ? 1.0 : 0.5; + [[self tabImage] drawInRect:[self tabRect] + fromRect:NSZeroRect + operation:NSCompositeSourceOver + fraction:alpha]; + + if (shouldShowProfileDisplayName_) { + NSColor* textColor = [[self window] isMainWindow] ? + GetBlackWithAlpha(0.6) : GetBlackWithAlpha(0.4); + if (![[textFieldCell_ textColor] isEqual:textColor]) + [textFieldCell_ setTextColor:textColor]; + [textFieldCell_ drawWithFrame:[self textFieldRect] inView:self]; + } +} + +- (NSPoint)popUpMenuPosition { + NSPoint menuPos = [self tabRect].origin; + // By default popUpContextMenu: causes the menu to show up a few pixels above + // the point you give it. We need to shift it down a bit so that it lines up + // with the bottom of the tab. + menuPos.y -= 6; + return [self convertPoint:menuPos toView:nil]; +} + +- (void) mouseDown:(NSEvent*)event + withShowMenuTarget:(id)target { + if (![self menu]) { + [super mouseDown:event]; + return; + } + + NSPoint point = [[self superview] + convertPointFromBase:[event locationInWindow]]; + if (![[self hitTest:point] isEqual:self]) + return; + + // Draw the control as depressed. + [self highlight:YES]; + + NSEvent* fakeEvent = [NSEvent + mouseEventWithType:[event type] + location:[self popUpMenuPosition] + modifierFlags:[event modifierFlags] + timestamp:[event timestamp] + windowNumber:[event windowNumber] + context:[event context] + eventNumber:[event eventNumber] + clickCount:[event clickCount] + pressure:[event pressure]]; + DCHECK([target respondsToSelector: + @selector(popUpContextMenu:withEvent:forView:)]); + [target popUpContextMenu:[self menu] + withEvent:fakeEvent + forView:self]; + + [self highlight:NO]; +} + +- (void)mouseDown:(NSEvent*)event { + [self mouseDown:event + withShowMenuTarget:[NSMenu class]]; +} + +- (NSSize)desiredControlSize { + NSSize size = [self tabRect].size; + + if (shouldShowProfileDisplayName_) { + NSSize textFieldSize = [textFieldCell_ cellSize]; + size.width = std::max(size.width, textFieldSize.width); + size.height += textFieldSize.height + kTabDisplayNameMarginY; + } + + size.width = ceil(size.width); + size.height = ceil(size.height); + return size; +} + +- (NSSize)minControlSize { + return [self tabRect].size; +} + +@end diff --git a/chrome/browser/ui/cocoa/profile_menu_button_unittest.mm b/chrome/browser/ui/cocoa/profile_menu_button_unittest.mm new file mode 100644 index 0000000..0b96563 --- /dev/null +++ b/chrome/browser/ui/cocoa/profile_menu_button_unittest.mm @@ -0,0 +1,124 @@ +// Copyright (c) 2011 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> + +#import "chrome/browser/ui/cocoa/cocoa_test_helper.h" +#import "chrome/browser/ui/cocoa/profile_menu_button.h" +#import "chrome/browser/ui/cocoa/test_event_utils.h" +#import "testing/gtest_mac.h" + +class ProfileMenuButtonTest : public CocoaTest { + public: + ProfileMenuButtonTest() { + scoped_nsobject<ProfileMenuButton> button([[ProfileMenuButton alloc] + initWithFrame:NSMakeRect(50, 50, 100, 100) + pullsDown:NO]); + button_ = button.get(); + [[test_window() contentView] addSubview:button_]; + } + + ProfileMenuButton* button_; +}; + +// A stub to check that popUpContextMenu:withEvent:forView: is called. +@interface ProfileShowMenuHandler : NSObject { + int showMenuCount_; +} + +@property(assign, nonatomic) int showMenuCount; + +- (void)popUpContextMenu:(NSMenu*)menu + withEvent:(NSEvent*)event + forView:(NSView*)view; + +@end + +@implementation ProfileShowMenuHandler + +@synthesize showMenuCount = showMenuCount_; + +- (void)popUpContextMenu:(NSMenu*)menu + withEvent:(NSEvent*)event + forView:(NSView*)view { + showMenuCount_++; +} + +@end + + +TEST_F(ProfileMenuButtonTest, ControlSize) { + scoped_nsobject<ProfileMenuButton> button([[ProfileMenuButton alloc] + initWithFrame:NSZeroRect + pullsDown:NO]); + + NSSize minSize = [button minControlSize]; + EXPECT_TRUE(NSEqualSizes(minSize, [button desiredControlSize])); + + [button setProfileDisplayName:@"Test"]; + EXPECT_TRUE(NSEqualSizes(minSize, [button desiredControlSize])); + EXPECT_TRUE(NSEqualSizes(minSize, [button desiredControlSize])); + + [button setShouldShowProfileDisplayName:YES]; + EXPECT_TRUE(NSEqualSizes(minSize, [button minControlSize])); + EXPECT_GT([button desiredControlSize].height, minSize.height); + EXPECT_GT([button desiredControlSize].width, minSize.width); + + [button setShouldShowProfileDisplayName:NO]; + EXPECT_TRUE(NSEqualSizes(minSize, [button desiredControlSize])); + EXPECT_TRUE(NSEqualSizes(minSize, [button desiredControlSize])); +} + +// Tests display, add/remove. +TEST_VIEW(ProfileMenuButtonTest, button_); + +TEST_F(ProfileMenuButtonTest, HitTest) { + NSRect mouseRect = NSInsetRect([button_ frame], 1, 1); + NSPoint topRight = NSMakePoint(NSMaxX(mouseRect), NSMaxY(mouseRect)); + NSPoint bottomRight = NSMakePoint(NSMaxX(mouseRect), NSMinY(mouseRect)); + NSPoint outsidePoint = NSOffsetRect(mouseRect, -10, -10).origin; + + // Without profile display name. Only topRight should hit. + EXPECT_NSEQ([button_ hitTest:topRight], button_); + EXPECT_NSEQ([button_ hitTest:bottomRight], NULL); + EXPECT_NSEQ([button_ hitTest:outsidePoint], NULL); + + // With profile display name. The profile display name should not hit. + [button_ setProfileDisplayName:@"Test"]; + [button_ setShouldShowProfileDisplayName:YES]; + EXPECT_NSEQ([button_ hitTest:topRight], button_); + EXPECT_NSEQ([button_ hitTest:bottomRight], NULL); + EXPECT_NSEQ([button_ hitTest:outsidePoint], NULL); +} + +// Test drawing, mostly to ensure nothing leaks or crashes. +TEST_F(ProfileMenuButtonTest, Display) { + // With profile display name. + [button_ display]; + + // With profile display name. + [button_ setProfileDisplayName:@"Test"]; + [button_ setShouldShowProfileDisplayName:YES]; + [button_ display]; +} + +// Checks that a menu is displayed on mouse down. Also makes sure that +// nothing leaks or crashes when displaying the button in its pressed state. +TEST_F(ProfileMenuButtonTest, MenuTest) { + scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@""]); + [button_ setMenu:menu]; + + // Trigger a mouse down to show the menu. + NSPoint point = NSMakePoint(NSMaxX([button_ bounds]) - 1, + NSMaxY([button_ bounds]) - 1); + point = [button_ convertPointToBase:point]; + NSEvent* downEvent = + test_event_utils::LeftMouseDownAtPointInWindow(point, test_window()); + scoped_nsobject<ProfileShowMenuHandler> showMenuHandler( + [[ProfileShowMenuHandler alloc] init]); + [button_ mouseDown:downEvent + withShowMenuTarget:showMenuHandler]; + + EXPECT_EQ(1, [showMenuHandler showMenuCount]); +} diff --git a/chrome/browser/ui/cocoa/repost_form_warning_mac.h b/chrome/browser/ui/cocoa/repost_form_warning_mac.h index a7ca8b2..ef1ea3a 100644 --- a/chrome/browser/ui/cocoa/repost_form_warning_mac.h +++ b/chrome/browser/ui/cocoa/repost_form_warning_mac.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,7 +8,7 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_ptr.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/ui/cocoa/constrained_window_mac.h" class RepostFormWarningController; diff --git a/chrome/browser/ui/cocoa/repost_form_warning_mac.mm b/chrome/browser/ui/cocoa/repost_form_warning_mac.mm index 3bcbaf1..81a2dee 100644 --- a/chrome/browser/ui/cocoa/repost_form_warning_mac.mm +++ b/chrome/browser/ui/cocoa/repost_form_warning_mac.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. #include "chrome/browser/ui/cocoa/repost_form_warning_mac.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/browser/repost_form_warning_controller.h" #include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util_mac.h" diff --git a/chrome/browser/ui/cocoa/restart_browser.mm b/chrome/browser/ui/cocoa/restart_browser.mm index 7f0bd7a..cc7be89 100644 --- a/chrome/browser/ui/cocoa/restart_browser.mm +++ b/chrome/browser/ui/cocoa/restart_browser.mm @@ -1,16 +1,16 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/restart_browser.h" -#include "chrome/browser/browser_list.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/ui/browser_list.h" #include "chrome/common/pref_names.h" +#include "grit/app_strings.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" -#include "grit/app_strings.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_mac.h" diff --git a/chrome/browser/ui/cocoa/search_engine_dialog_controller.h b/chrome/browser/ui/cocoa/search_engine_dialog_controller.h index 0cc06f2..d1abf54 100644 --- a/chrome/browser/ui/cocoa/search_engine_dialog_controller.h +++ b/chrome/browser/ui/cocoa/search_engine_dialog_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -6,9 +6,9 @@ #include <vector> -#import "base/ref_counted.h" -#import "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#import "base/memory/ref_counted.h" +#import "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" class Profile; class SearchEngineDialogControllerBridge; diff --git a/chrome/browser/ui/cocoa/shell_dialogs_mac.mm b/chrome/browser/ui/cocoa/shell_dialogs_mac.mm index 93e031c..687ca71 100644 --- a/chrome/browser/ui/cocoa/shell_dialogs_mac.mm +++ b/chrome/browser/ui/cocoa/shell_dialogs_mac.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -16,7 +16,7 @@ #import "base/mac/cocoa_protocols.h" #include "base/mac/mac_util.h" #include "base/mac/scoped_cftyperef.h" -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #include "base/sys_string_conversions.h" #include "base/threading/thread_restrictions.h" #include "grit/generated_resources.h" @@ -54,17 +54,6 @@ class SelectFileDialogImpl : public SelectFileDialog { virtual bool IsRunning(gfx::NativeWindow parent_window) const; virtual void ListenerDestroyed(); - // SelectFileDialog implementation. - // |params| is user data we pass back via the Listener interface. - virtual void SelectFile(Type type, - const string16& title, - const FilePath& default_path, - const FileTypeInfo* file_types, - int file_type_index, - const FilePath::StringType& default_extension, - gfx::NativeWindow owning_window, - void* params); - // Callback from ObjC bridge. void FileWasSelected(NSSavePanel* dialog, NSWindow* parent_window, @@ -80,14 +69,23 @@ class SelectFileDialogImpl : public SelectFileDialog { NSWindow* owning_window; }; + protected: + // SelectFileDialog implementation. + // |params| is user data we pass back via the Listener interface. + virtual void SelectFileImpl(Type type, + const string16& title, + const FilePath& default_path, + const FileTypeInfo* file_types, + int file_type_index, + const FilePath::StringType& default_extension, + gfx::NativeWindow owning_window, + void* params); + private: // Gets the accessory view for the save dialog. NSView* GetAccessoryView(const FileTypeInfo* file_types, int file_type_index); - // The listener to be notified of selection completion. - Listener* listener_; - // The bridge for results from Cocoa to return to us. scoped_nsobject<SelectFileDialogBridge> bridge_; @@ -109,7 +107,7 @@ SelectFileDialog* SelectFileDialog::Create(Listener* listener) { } SelectFileDialogImpl::SelectFileDialogImpl(Listener* listener) - : listener_(listener), + : SelectFileDialog(listener), bridge_([[SelectFileDialogBridge alloc] initWithSelectFileDialogImpl:this]) { } @@ -138,7 +136,7 @@ void SelectFileDialogImpl::ListenerDestroyed() { listener_ = NULL; } -void SelectFileDialogImpl::SelectFile( +void SelectFileDialogImpl::SelectFileImpl( Type type, const string16& title, const FilePath& default_path, diff --git a/chrome/browser/ui/cocoa/sidebar_controller.h b/chrome/browser/ui/cocoa/sidebar_controller.h index 65955d5..1eb3c83 100644 --- a/chrome/browser/ui/cocoa/sidebar_controller.h +++ b/chrome/browser/ui/cocoa/sidebar_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,7 +8,7 @@ #import <Foundation/Foundation.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h" @class NSSplitView; diff --git a/chrome/browser/ui/cocoa/speech_input_window_controller.h b/chrome/browser/ui/cocoa/speech_input_window_controller.h index 4538a83..c472ecc 100644 --- a/chrome/browser/ui/cocoa/speech_input_window_controller.h +++ b/chrome/browser/ui/cocoa/speech_input_window_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -16,6 +16,7 @@ @interface SpeechInputWindowController : BaseBubbleController { @private SpeechInputBubble::Delegate* delegate_; // weak. + SpeechInputBubbleBase::DisplayMode displayMode_; // References below are weak, being obtained from the nib. IBOutlet NSImageView* iconImage_; @@ -41,7 +42,8 @@ // Updates the UI with data related to the given display mode. - (void)updateLayout:(SpeechInputBubbleBase::DisplayMode)mode - messageText:(const string16&)messageText; + messageText:(const string16&)messageText + iconImage:(NSImage*)iconImage; // Makes the speech input bubble visible on screen. - (void)show; diff --git a/chrome/browser/ui/cocoa/speech_input_window_controller.mm b/chrome/browser/ui/cocoa/speech_input_window_controller.mm index 5ab5db0..0f966f0 100644 --- a/chrome/browser/ui/cocoa/speech_input_window_controller.mm +++ b/chrome/browser/ui/cocoa/speech_input_window_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -18,6 +18,7 @@ const int kBubbleControlVerticalSpacing = 10; // Space between controls. const int kBubbleHorizontalMargin = 5; // Space on either sides of controls. +const int kInstructionLabelMaxWidth = 150; @interface SpeechInputWindowController (Private) - (NSSize)calculateContentSize; @@ -35,33 +36,14 @@ const int kBubbleHorizontalMargin = 5; // Space on either sides of controls. anchoredAt:anchoredAt])) { DCHECK(delegate); delegate_ = delegate; - - [self showWindow:nil]; + displayMode_ = SpeechInputBubbleBase::DISPLAY_MODE_WARM_UP; } return self; } - (void)awakeFromNib { [super awakeFromNib]; - - NSWindow* window = [self window]; [[self bubble] setArrowLocation:info_bubble::kTopLeft]; - NSImage* icon = ResourceBundle::GetSharedInstance().GetNativeImageNamed( - IDR_SPEECH_INPUT_MIC_EMPTY); - [iconImage_ setImage:icon]; - - NSSize newSize = [self calculateContentSize]; - [[self bubble] setFrameSize:newSize]; - NSSize windowDelta = NSMakeSize( - newSize.width - NSWidth([[window contentView] bounds]), - newSize.height - NSHeight([[window contentView] bounds])); - windowDelta = [[window contentView] convertSize:windowDelta toView:nil]; - NSRect newFrame = [window frame]; - newFrame.size.width += windowDelta.width; - newFrame.size.height += windowDelta.height; - [window setFrame:newFrame display:NO]; - - [self layout:newSize]; // Layout all the child controls. } - (IBAction)cancel:(id)sender { @@ -87,25 +69,44 @@ const int kBubbleHorizontalMargin = 5; // Space on either sides of controls. NSSize cancelSize = [cancelButton_ bounds].size; NSSize tryAgainSize = [tryAgainButton_ bounds].size; CGFloat newHeight = cancelSize.height + kBubbleControlVerticalSpacing; - CGFloat newWidth = cancelSize.width + tryAgainSize.width; + CGFloat newWidth = cancelSize.width; + if (![tryAgainButton_ isHidden]) + newWidth += tryAgainSize.width; + + // The size of the bubble in warm up mode is fixed to be the same as in + // recording mode, so from warm up it can transition to recording without any + // UI jank. + bool isWarmUp = (displayMode_ == + SpeechInputBubbleBase::DISPLAY_MODE_WARM_UP); if (![iconImage_ isHidden]) { NSSize size = [[iconImage_ image] size]; + if (isWarmUp) { + NSImage* volumeIcon = + ResourceBundle::GetSharedInstance().GetNativeImageNamed( + IDR_SPEECH_INPUT_MIC_EMPTY); + size = [volumeIcon size]; + } newHeight += size.height; - newWidth = std::max(newWidth, size.width); + newWidth = std::max(newWidth, size.width + 2 * kBubbleHorizontalMargin); } - if (![instructionLabel_ isHidden]) { - [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField: - instructionLabel_]; - NSSize size = [instructionLabel_ bounds].size; - newHeight += size.height + kBubbleControlVerticalSpacing; - newWidth = std::max(newWidth, size.width); + if (![instructionLabel_ isHidden] || isWarmUp) { + [instructionLabel_ sizeToFit]; + NSSize textSize = [[instructionLabel_ cell] cellSize]; + NSRect boundsRect = NSMakeRect(0, 0, kInstructionLabelMaxWidth, + CGFLOAT_MAX); + NSSize multiLineSize = + [[instructionLabel_ cell] cellSizeForBounds:boundsRect]; + if (textSize.width > multiLineSize.width) + textSize = multiLineSize; + newHeight += textSize.height + kBubbleControlVerticalSpacing; + newWidth = std::max(newWidth, textSize.width); } if (![micSettingsButton_ isHidden]) { NSSize size = [micSettingsButton_ bounds].size; - newHeight += size.height + kBubbleControlVerticalSpacing; + newHeight += size.height; newWidth = std::max(newWidth, size.width); } @@ -130,9 +131,11 @@ const int kBubbleHorizontalMargin = 5; // Space on either sides of controls. [tryAgainButton_ setFrame:tryAgainRect]; } cancelRect.origin.y = y; - [cancelButton_ setFrame:cancelRect]; - y += NSHeight(cancelRect) + kBubbleControlVerticalSpacing; + if (![cancelButton_ isHidden]) { + [cancelButton_ setFrame:cancelRect]; + y += NSHeight(cancelRect) + kBubbleControlVerticalSpacing; + } NSRect rect; if (![micSettingsButton_ isHidden]) { @@ -144,54 +147,65 @@ const int kBubbleHorizontalMargin = 5; // Space on either sides of controls. } if (![instructionLabel_ isHidden]) { - rect = [instructionLabel_ bounds]; - rect.origin.x = (size.width - NSWidth(rect)) / 2; - rect.origin.y = y; + int spaceForIcon = 0; + if (![iconImage_ isHidden]) { + spaceForIcon = [[iconImage_ image] size].height + + kBubbleControlVerticalSpacing; + } + + rect = NSMakeRect(0, y, size.width, size.height - y - spaceForIcon - + kBubbleControlVerticalSpacing * 2); [instructionLabel_ setFrame:rect]; - y += rect.size.height + kBubbleControlVerticalSpacing; + y = size.height - spaceForIcon - kBubbleControlVerticalSpacing; } if (![iconImage_ isHidden]) { rect.size = [[iconImage_ image] size]; + // In warm-up mode only the icon gets displayed so center it vertically. + if (displayMode_ == SpeechInputBubbleBase::DISPLAY_MODE_WARM_UP) + y = (size.height - rect.size.height) / 2; rect.origin.x = (size.width - NSWidth(rect)) / 2; rect.origin.y = y; [iconImage_ setFrame:rect]; } - } - (void)updateLayout:(SpeechInputBubbleBase::DisplayMode)mode - messageText:(const string16&)messageText { + messageText:(const string16&)messageText + iconImage:(NSImage*)iconImage { + // The very first time this method is called, the child views would still be + // uninitialized and null. So we invoke [self window] first and that sets up + // the child views properly so we can do the layout calculations below. + NSWindow* window = [self window]; + displayMode_ = mode; + BOOL is_message = (mode == SpeechInputBubbleBase::DISPLAY_MODE_MESSAGE); + BOOL is_recording = (mode == SpeechInputBubbleBase::DISPLAY_MODE_RECORDING); + BOOL is_warm_up = (mode == SpeechInputBubbleBase::DISPLAY_MODE_WARM_UP); + [iconImage_ setHidden:is_message]; + [tryAgainButton_ setHidden:!is_message]; + [micSettingsButton_ setHidden:!is_message]; + [instructionLabel_ setHidden:!is_message && !is_recording]; + [cancelButton_ setHidden:is_warm_up]; + // Get the right set of controls to be visible. - if (mode == SpeechInputBubbleBase::DISPLAY_MODE_MESSAGE) { + if (is_message) { [instructionLabel_ setStringValue:base::SysUTF16ToNSString(messageText)]; - [iconImage_ setHidden:YES]; - [tryAgainButton_ setHidden:NO]; - [instructionLabel_ setHidden:NO]; - [micSettingsButton_ setHidden:NO]; } else { - if (mode == SpeechInputBubbleBase::DISPLAY_MODE_RECORDING) { - [instructionLabel_ setStringValue:l10n_util::GetNSString( - IDS_SPEECH_INPUT_BUBBLE_HEADING)]; - [instructionLabel_ setHidden:NO]; - NSImage* icon = ResourceBundle::GetSharedInstance().GetNativeImageNamed( - IDR_SPEECH_INPUT_MIC_EMPTY); - [iconImage_ setImage:icon]; - } else { - [instructionLabel_ setHidden:YES]; - } - [iconImage_ setHidden:NO]; - [iconImage_ setNeedsDisplay:YES]; - [tryAgainButton_ setHidden:YES]; - [micSettingsButton_ setHidden:YES]; + [iconImage_ setImage:iconImage]; + [instructionLabel_ setStringValue:l10n_util::GetNSString( + IDS_SPEECH_INPUT_BUBBLE_HEADING)]; } NSSize newSize = [self calculateContentSize]; - NSRect rect = [[self bubble] frame]; - rect.origin.y -= newSize.height - rect.size.height; - rect.size = newSize; - [[self bubble] setFrame:rect]; - [self layout:newSize]; + [[self bubble] setFrameSize:newSize]; + + NSSize windowDelta = [[window contentView] convertSize:newSize toView:nil]; + NSRect newFrame = [window frame]; + newFrame.origin.y -= windowDelta.height - newFrame.size.height; + newFrame.size = windowDelta; + [window setFrame:newFrame display:YES]; + + [self layout:newSize]; // Layout all the child controls. } - (void)windowWillClose:(NSNotification*)notification { diff --git a/chrome/browser/ui/cocoa/ssl_client_certificate_selector.mm b/chrome/browser/ui/cocoa/ssl_client_certificate_selector.mm index 02dc33d..8cf855b 100644 --- a/chrome/browser/ui/cocoa/ssl_client_certificate_selector.mm +++ b/chrome/browser/ui/cocoa/ssl_client_certificate_selector.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,8 +9,8 @@ #include <vector> #include "base/logging.h" -#include "base/ref_counted.h" -#import "base/scoped_nsobject.h" +#include "base/memory/ref_counted.h" +#import "base/memory/scoped_nsobject.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" diff --git a/chrome/browser/ui/cocoa/status_bubble_mac.mm b/chrome/browser/ui/cocoa/status_bubble_mac.mm index aa77c16..45f2c54 100644 --- a/chrome/browser/ui/cocoa/status_bubble_mac.mm +++ b/chrome/browser/ui/cocoa/status_bubble_mac.mm @@ -391,6 +391,7 @@ void StatusBubbleMac::Create() { void StatusBubbleMac::Attach() { DCHECK(!is_attached()); + [window_ orderFront:nil]; [parent_ addChildWindow:window_ ordered:NSWindowAbove]; [[window_ contentView] setThemeProvider:parent_]; diff --git a/chrome/browser/ui/cocoa/status_bubble_mac_unittest.mm b/chrome/browser/ui/cocoa/status_bubble_mac_unittest.mm index add4f7b..6dbffec 100644 --- a/chrome/browser/ui/cocoa/status_bubble_mac_unittest.mm +++ b/chrome/browser/ui/cocoa/status_bubble_mac_unittest.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. #include <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "base/utf_string_conversions.h" #import "chrome/browser/ui/cocoa/bubble_view.h" #import "chrome/browser/ui/cocoa/browser_test_helper.h" @@ -118,7 +118,7 @@ class StatusBubbleMacTest : public CocoaTest { NSWindow* GetWindow() { return bubble_->window_; } - NSWindow* GetParent() { + NSWindow* parent() { return bubble_->parent_; } StatusBubbleMac::StatusBubbleState GetState() { diff --git a/chrome/browser/ui/cocoa/status_icons/status_icon_mac.h b/chrome/browser/ui/cocoa/status_icons/status_icon_mac.h index 122aab7..3fa6150 100644 --- a/chrome/browser/ui/cocoa/status_icons/status_icon_mac.h +++ b/chrome/browser/ui/cocoa/status_icons/status_icon_mac.h @@ -8,7 +8,7 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/string16.h" #include "chrome/browser/status_icons/status_icon.h" diff --git a/chrome/browser/ui/cocoa/styled_text_field_cell.mm b/chrome/browser/ui/cocoa/styled_text_field_cell.mm index 46fcd8b..387d243 100644 --- a/chrome/browser/ui/cocoa/styled_text_field_cell.mm +++ b/chrome/browser/ui/cocoa/styled_text_field_cell.mm @@ -1,11 +1,12 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/styled_text_field_cell.h" #include "base/logging.h" -#include "chrome/browser/themes/browser_theme_provider.h" +#include "chrome/browser/themes/theme_service.h" +#import "chrome/browser/ui/cocoa/nsview_additions.h" #import "chrome/browser/ui/cocoa/themed_window.h" #include "grit/theme_resources.h" #import "third_party/GTM/AppKit/GTMNSBezierPath+RoundRect.h" @@ -137,18 +138,21 @@ private: // calculating things like the editing area. This is probably // incorrect. I know that this affects -drawingRectForBounds:. - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { + const CGFloat lineWidth = [controlView cr_lineWidth]; + const CGFloat halfLineWidth = lineWidth / 2.0; + DCHECK([controlView isFlipped]); StyledTextFieldCellRoundedFlags roundedFlags = [self roundedFlags]; // TODO(shess): This inset is also reflected by |kFieldVisualInset| // in autocomplete_popup_view_mac.mm. - const NSRect frame = NSInsetRect(cellFrame, 0, 1); + const NSRect frame = NSInsetRect(cellFrame, 0, lineWidth); const CGFloat radius = [self cornerRadius]; // Paint button background image if there is one (otherwise the border won't // look right). - BrowserThemeProvider* themeProvider = - static_cast<BrowserThemeProvider*>([[controlView window] themeProvider]); + ThemeService* themeProvider = + static_cast<ThemeService*>([[controlView window] themeProvider]); if (themeProvider) { NSColor* backgroundImageColor = themeProvider->GetNSImageColorNamed(IDR_THEME_BUTTON_BACKGROUND, false); @@ -159,22 +163,25 @@ private: [[NSGraphicsContext currentContext] setPatternPhase:midPoint]; // NOTE(shess): This seems like it should be using a 0.0 inset, - // but AFAICT using a 0.5 inset is important in mixing the + // but AFAICT using a halfLineWidth inset is important in mixing the // toolbar background and the omnibox background. - FillRectWithInset(roundedFlags, frame, 0.5, radius, backgroundImageColor); + FillRectWithInset(roundedFlags, frame, halfLineWidth, radius, + backgroundImageColor); } // Draw the outer stroke (over the background). BOOL active = [[controlView window] isMainWindow]; NSColor* strokeColor = themeProvider->GetNSColor( - active ? BrowserThemeProvider::COLOR_TOOLBAR_BUTTON_STROKE : - BrowserThemeProvider::COLOR_TOOLBAR_BUTTON_STROKE_INACTIVE, + active ? ThemeService::COLOR_TOOLBAR_BUTTON_STROKE : + ThemeService::COLOR_TOOLBAR_BUTTON_STROKE_INACTIVE, true); - FrameRectWithInset(roundedFlags, frame, 0.0, radius, 1.0, strokeColor); + FrameRectWithInset(roundedFlags, frame, 0.0, radius, lineWidth, + strokeColor); } // Fill interior with background color. - FillRectWithInset(roundedFlags, frame, 1.0, radius, [self backgroundColor]); + FillRectWithInset(roundedFlags, frame, lineWidth, radius, + [self backgroundColor]); // Draw the shadow. For the rounded-rect case, the shadow needs to // slightly turn in at the corners. |shadowFrame| is at the same @@ -183,32 +190,34 @@ private: // will clip the bottom and right edges (and corner). { ScopedSaveGraphicsState state; - [RectPathWithInset(roundedFlags, frame, 1.0, radius) addClip]; - const NSRect shadowFrame = NSOffsetRect(frame, 0.5, 0.5); + [RectPathWithInset(roundedFlags, frame, lineWidth, radius) addClip]; + const NSRect shadowFrame = + NSOffsetRect(frame, halfLineWidth, halfLineWidth); NSColor* shadowShade = [NSColor colorWithCalibratedWhite:0.0 alpha:0.05]; - FrameRectWithInset(roundedFlags, shadowFrame, 0.5, radius - 0.5, - 1.0, shadowShade); + FrameRectWithInset(roundedFlags, shadowFrame, halfLineWidth, + radius - halfLineWidth, lineWidth, shadowShade); } // Draw optional bezel below bottom stroke. if ([self shouldDrawBezel] && themeProvider && themeProvider->UsingDefaultTheme()) { - [themeProvider->GetNSColor( - BrowserThemeProvider::COLOR_TOOLBAR_BEZEL, true) set]; + NSColor* bezelColor = themeProvider->GetNSColor( + ThemeService::COLOR_TOOLBAR_BEZEL, true); + [[bezelColor colorWithAlphaComponent:0.5] set]; NSRect bezelRect = NSMakeRect(cellFrame.origin.x, - NSMaxY(cellFrame) - 0.5, + NSMaxY(cellFrame) - lineWidth, NSWidth(cellFrame), - 1.0); - bezelRect = NSInsetRect(bezelRect, radius - 0.5, 0.0); - NSRectFill(bezelRect); + lineWidth); + bezelRect = NSInsetRect(bezelRect, radius - halfLineWidth, 0.0); + NSRectFillUsingOperation(bezelRect, NSCompositeSourceOver); } // Draw the focus ring if needed. if ([self showsFirstResponder]) { NSColor* color = [[NSColor keyboardFocusIndicatorColor] colorWithAlphaComponent:0.5]; - FrameRectWithInset(roundedFlags, frame, 0.0, radius, 2.0, color); + FrameRectWithInset(roundedFlags, frame, 0.0, radius, lineWidth * 2, color); } [self drawInteriorWithFrame:cellFrame inView:controlView]; diff --git a/chrome/browser/ui/cocoa/styled_text_field_cell_unittest.mm b/chrome/browser/ui/cocoa/styled_text_field_cell_unittest.mm index 2df3c65..076583f 100644 --- a/chrome/browser/ui/cocoa/styled_text_field_cell_unittest.mm +++ b/chrome/browser/ui/cocoa/styled_text_field_cell_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/styled_text_field_cell.h" #import "chrome/browser/ui/cocoa/styled_text_field_test_helper.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" diff --git a/chrome/browser/ui/cocoa/styled_text_field_unittest.mm b/chrome/browser/ui/cocoa/styled_text_field_unittest.mm index 6ca36bc..4b079a5 100644 --- a/chrome/browser/ui/cocoa/styled_text_field_unittest.mm +++ b/chrome/browser/ui/cocoa/styled_text_field_unittest.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/styled_text_field.h" #import "chrome/browser/ui/cocoa/styled_text_field_cell.h" #import "chrome/browser/ui/cocoa/styled_text_field_test_helper.h" diff --git a/chrome/browser/ui/cocoa/tab_contents/favicon_util.h b/chrome/browser/ui/cocoa/tab_contents/favicon_util.h new file mode 100644 index 0000000..051ef8c --- /dev/null +++ b/chrome/browser/ui/cocoa/tab_contents/favicon_util.h @@ -0,0 +1,20 @@ +// Copyright (c) 2011 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_UI_COCOA_TAB_CONTENTS_FAVICON_UTIL_H_ +#define CHROME_BROWSER_UI_COCOA_TAB_CONTENTS_FAVICON_UTIL_H_ + +@class NSImage; +class TabContents; + +namespace mac { + +// Returns an autoreleased favicon for a given TabContents. If |contents| is +// NULL or there's no favicon for the NavigationEntry, this will return the +// default image. +NSImage* FaviconForTabContents(TabContents* contents); + +} // namespace mac + +#endif // CHROME_BROWSER_UI_COCOA_TAB_CONTENTS_FAVICON_UTIL_H_ diff --git a/chrome/browser/ui/cocoa/tab_contents/favicon_util.mm b/chrome/browser/ui/cocoa/tab_contents/favicon_util.mm new file mode 100644 index 0000000..3fcba52 --- /dev/null +++ b/chrome/browser/ui/cocoa/tab_contents/favicon_util.mm @@ -0,0 +1,35 @@ +// Copyright (c) 2011 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. + +#include "chrome/browser/ui/cocoa/tab_contents/favicon_util.h" + +#import <AppKit/AppKit.h> + +#include "app/mac/nsimage_cache.h" +#include "base/mac/mac_util.h" +#include "content/browser/tab_contents/tab_contents.h" +#include "skia/ext/skia_utils_mac.h" + +namespace mac { + +NSImage* FaviconForTabContents(TabContents* contents) { + // TabContents returns IDR_DEFAULT_FAVICON, which is a rasterized version of + // the Mac PDF. Use the PDF so the icon in the Omnibox matches the default + // favicon. + if (contents && contents->FaviconIsValid()) { + CGColorSpaceRef color_space = base::mac::GetSystemColorSpace(); + NSImage* image = + gfx::SkBitmapToNSImageWithColorSpace(contents->GetFavicon(), + color_space); + // The |image| could be nil if the bitmap is null. In that case, fallback + // to the default image. + if (image) { + return image; + } + } + + return app::mac::GetCachedImageWithName(@"nav.pdf"); +} + +} // namespace mac diff --git a/chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller_unittest.mm b/chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller_unittest.mm index 3e5ea6f..cc1b902 100644 --- a/chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #include "chrome/browser/ui/cocoa/browser_test_helper.h" #include "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/tab_contents/previewable_contents_controller.h" diff --git a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm index 9c4c9b4..d772d5e 100644 --- a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm @@ -1,9 +1,9 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. #include "base/debug/debugger.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h" #import "chrome/browser/ui/cocoa/tab_contents/sad_tab_view.h" @@ -82,7 +82,7 @@ TEST_F(SadTabControllerTest, WithTabContents) { } TEST_F(SadTabControllerTest, WithoutTabContents) { - contents_.reset(); + DeleteContents(); scoped_nsobject<SadTabController> controller(CreateController()); EXPECT_TRUE(controller); NSButton* link = GetLinkButton(controller); diff --git a/chrome/browser/ui/cocoa/tab_contents/sad_tab_view.h b/chrome/browser/ui/cocoa/tab_contents/sad_tab_view.h index 8f782af..c97083c 100644 --- a/chrome/browser/ui/cocoa/tab_contents/sad_tab_view.h +++ b/chrome/browser/ui/cocoa/tab_contents/sad_tab_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -6,7 +6,7 @@ #define CHROME_BROWSER_UI_COCOA_TAB_CONTENTS_SAD_TAB_VIEW_H_ #pragma once -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/browser/ui/cocoa/base_view.h" #import <Cocoa/Cocoa.h> diff --git a/chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h b/chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h index a327e4b..358501f 100644 --- a/chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h +++ b/chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,7 +8,7 @@ #include <Cocoa/Cocoa.h> -#include "base/scoped_ptr.h" +#include "base/memory/scoped_ptr.h" class TabContents; class TabContentsNotificationBridge; diff --git a/chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.mm b/chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.mm index 6f8e630..caea8af 100644 --- a/chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.mm +++ b/chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.mm @@ -1,19 +1,19 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/tab_contents/tab_contents_controller.h" -#include "base/scoped_nsobject.h" -#include "chrome/common/notification_details.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "chrome/common/notification_source.h" -#include "chrome/common/notification_type.h" +#include "base/memory/scoped_nsobject.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/browser/renderer_host/render_widget_host_view.h" #include "content/browser/tab_contents/navigation_controller.h" #include "content/browser/tab_contents/tab_contents.h" +#include "content/common/notification_details.h" +#include "content/common/notification_observer.h" +#include "content/common/notification_registrar.h" +#include "content/common/notification_source.h" +#include "content/common/notification_type.h" @interface TabContentsController(Private) // Forwards frame update to |delegate_| (ResizeNotificationView calls it). diff --git a/chrome/browser/ui/cocoa/tab_contents/web_contents_drag_source.h b/chrome/browser/ui/cocoa/tab_contents/web_contents_drag_source.h index e611f4c..82e9131 100644 --- a/chrome/browser/ui/cocoa/tab_contents/web_contents_drag_source.h +++ b/chrome/browser/ui/cocoa/tab_contents/web_contents_drag_source.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,7 +8,7 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/browser/bookmarks/bookmark_node_data.h" @class TabContentsViewCocoa; diff --git a/chrome/browser/ui/cocoa/tab_contents/web_drag_source.h b/chrome/browser/ui/cocoa/tab_contents/web_drag_source.h index 9cfcba5..7e308a5 100644 --- a/chrome/browser/ui/cocoa/tab_contents/web_drag_source.h +++ b/chrome/browser/ui/cocoa/tab_contents/web_drag_source.h @@ -1,12 +1,12 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/file_path.h" -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "googleurl/src/gurl.h" @class TabContentsViewCocoa; diff --git a/chrome/browser/ui/cocoa/tab_contents/web_drag_source.mm b/chrome/browser/ui/cocoa/tab_contents/web_drag_source.mm index a655473..24ef3b4 100644 --- a/chrome/browser/ui/cocoa/tab_contents/web_drag_source.mm +++ b/chrome/browser/ui/cocoa/tab_contents/web_drag_source.mm @@ -1,16 +1,20 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/tab_contents/web_drag_source.h" +#include <sys/param.h> + #include "app/mac/nsimage_cache.h" #include "base/file_path.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" #include "base/task.h" #include "base/threading/thread.h" +#include "base/threading/thread_restrictions.h" #include "base/utf_string_conversions.h" +#import "chrome/app/breakpad_mac.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/download/download_manager.h" #include "chrome/browser/download/download_util.h" @@ -36,26 +40,40 @@ namespace { // |NSURLPboardType|. NSString* const kNSURLTitlePboardType = @"public.url-name"; +// Converts a string16 into a FilePath. Use this method instead of +// -[NSString fileSystemRepresentation] to prevent exceptions from being thrown. +// See http://crbug.com/78782 for more info. +FilePath FilePathFromFilename(const string16& filename) { + NSString* str = SysUTF16ToNSString(filename); + char buf[MAXPATHLEN]; + if (![str getFileSystemRepresentation:buf maxLength:sizeof(buf)]) + return FilePath(); + return FilePath(buf); +} + // Returns a filename appropriate for the drop data // TODO(viettrungluu): Refactor to make it common across platforms, // and move it somewhere sensible. FilePath GetFileNameFromDragData(const WebDropData& drop_data) { + // Set a breakpad key for the scope of this function to help debug + // http://crbug.com/78782 + static NSString* const kUrlKey = @"drop_data_url"; + NSString* value = SysUTF8ToNSString(drop_data.url.spec()); + ScopedCrashKey key(kUrlKey, value); + // Images without ALT text will only have a file extension so we need to // synthesize one from the provided extension and URL. - FilePath file_name([SysUTF16ToNSString(drop_data.file_description_filename) - fileSystemRepresentation]); + FilePath file_name(FilePathFromFilename(drop_data.file_description_filename)); file_name = file_name.BaseName().RemoveExtension(); if (file_name.empty()) { // Retrieve the name from the URL. string16 suggested_filename = net::GetSuggestedFilename(drop_data.url, "", "", string16()); - file_name = FilePath( - [SysUTF16ToNSString(suggested_filename) fileSystemRepresentation]); + file_name = FilePathFromFilename(suggested_filename); } - file_name = file_name.ReplaceExtension([SysUTF16ToNSString( - drop_data.file_extension) fileSystemRepresentation]); + file_name = file_name.ReplaceExtension(UTF16ToUTF8(drop_data.file_extension)); return file_name; } @@ -269,6 +287,12 @@ void PromiseWriterTask::Run() { NSRect screenFrame = [[[contentsView_ window] screen] frame]; screenPoint.y = screenFrame.size.height - screenPoint.y; + // If AppKit returns a copy and move operation, mask off the move bit + // because WebCore does not understand what it means to do both, which + // results in an assertion failure/renderer crash. + if (operation == (NSDragOperationMove | NSDragOperationCopy)) + operation &= ~NSDragOperationMove; + rvh->DragSourceEndedAt(localPoint.x, localPoint.y, screenPoint.x, screenPoint.y, static_cast<WebKit::WebDragOperation>(operation)); @@ -307,6 +331,11 @@ void PromiseWriterTask::Run() { GetFileNameFromDragData(*dropData_) : downloadFileName_; FilePath filePath(SysNSStringToUTF8(path)); filePath = filePath.Append(fileName); + + // CreateFileStreamForDrop() will call file_util::PathExists(), + // which is blocking. Since this operation is already blocking the + // UI thread on OSX, it should be reasonable to let it happen. + base::ThreadRestrictions::ScopedAllowIO allowIO; FileStream* fileStream = drag_download_util::CreateFileStreamForDrop(&filePath); if (!fileStream) diff --git a/chrome/browser/ui/cocoa/tab_view_picker_table.h b/chrome/browser/ui/cocoa/tab_view_picker_table.h index 5de51f4..070d7c8 100644 --- a/chrome/browser/ui/cocoa/tab_view_picker_table.h +++ b/chrome/browser/ui/cocoa/tab_view_picker_table.h @@ -1,11 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" // TabViewPickerTable is an NSOutlineView that can be used to switch between the // NSTabViewItems of an NSTabView. To use this, just create a diff --git a/chrome/browser/ui/cocoa/tab_view_picker_table_unittest.mm b/chrome/browser/ui/cocoa/tab_view_picker_table_unittest.mm index daf1340..1abbaa3 100644 --- a/chrome/browser/ui/cocoa/tab_view_picker_table_unittest.mm +++ b/chrome/browser/ui/cocoa/tab_view_picker_table_unittest.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -7,7 +7,7 @@ #import "chrome/browser/ui/cocoa/tab_view_picker_table.h" #import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" #import "testing/gtest_mac.h" diff --git a/chrome/browser/ui/cocoa/table_model_array_controller.h b/chrome/browser/ui/cocoa/table_model_array_controller.h index 850bf6d..e902a39 100644 --- a/chrome/browser/ui/cocoa/table_model_array_controller.h +++ b/chrome/browser/ui/cocoa/table_model_array_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,8 +9,8 @@ #import <Cocoa/Cocoa.h> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "ui/base/models/table_model_observer.h" class RemoveRowsObserverBridge; diff --git a/chrome/browser/ui/cocoa/table_row_nsimage_cache.h b/chrome/browser/ui/cocoa/table_row_nsimage_cache.h index 254dc3e..f6713fe 100644 --- a/chrome/browser/ui/cocoa/table_row_nsimage_cache.h +++ b/chrome/browser/ui/cocoa/table_row_nsimage_cache.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,7 +8,7 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" class SkBitmap; diff --git a/chrome/browser/ui/cocoa/tabpose_window.h b/chrome/browser/ui/cocoa/tabpose_window.h index 1737bf8..8f70c8e 100644 --- a/chrome/browser/ui/cocoa/tabpose_window.h +++ b/chrome/browser/ui/cocoa/tabpose_window.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -10,9 +10,9 @@ #include "base/mac/scoped_cftyperef.h" -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" -#include "base/scoped_vector.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" namespace tabpose { diff --git a/chrome/browser/ui/cocoa/tabpose_window.mm b/chrome/browser/ui/cocoa/tabpose_window.mm index 55b7d8f..4a0d7fd 100644 --- a/chrome/browser/ui/cocoa/tabpose_window.mm +++ b/chrome/browser/ui/cocoa/tabpose_window.mm @@ -8,13 +8,15 @@ #include <algorithm> +#include "app/mac/nsimage_cache.h" #include "base/mac/mac_util.h" #include "base/mac/scoped_cftyperef.h" -#include "base/scoped_callback_factory.h" +#include "base/memory/scoped_callback_factory.h" #include "base/sys_string_conversions.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/browser_process.h" #import "chrome/browser/debugger/devtools_window.h" +#include "chrome/browser/extensions/extension_tab_helper.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" @@ -22,6 +24,7 @@ #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_constants.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" +#import "chrome/browser/ui/cocoa/tab_contents/favicon_util.h" #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" #import "chrome/browser/ui/cocoa/tabs/tab_strip_model_observer_bridge.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" @@ -98,12 +101,12 @@ namespace tabpose { class ThumbnailLoader; } -// A CALayer that draws a thumbnail for a TabContents object. The layer tries -// to draw the TabContents's backing store directly if possible, and requests -// a thumbnail bitmap from the TabContents's renderer process if not. +// A CALayer that draws a thumbnail for a TabContentsWrapper object. The layer +// tries to draw the TabContents's backing store directly if possible, and +// requests a thumbnail bitmap from the TabContents's renderer process if not. @interface ThumbnailLayer : CALayer { - // The TabContents the thumbnail is for. - TabContents* contents_; // weak + // The TabContentsWrapper the thumbnail is for. + TabContentsWrapper* contents_; // weak // The size the thumbnail is drawn at when zoomed in. NSSize fullSize_; @@ -118,7 +121,8 @@ class ThumbnailLoader; // True if the layer already sent a thumbnail request to a renderer. BOOL didSendLoad_; } -- (id)initWithTabContents:(TabContents*)contents fullSize:(NSSize)fullSize; +- (id)initWithTabContents:(TabContentsWrapper*)contents + fullSize:(NSSize)fullSize; - (void)drawInContext:(CGContextRef)context; - (void)setThumbnail:(const SkBitmap&)bitmap; @end @@ -189,7 +193,8 @@ void ThumbnailLoader::LoadThumbnail() { @implementation ThumbnailLayer -- (id)initWithTabContents:(TabContents*)contents fullSize:(NSSize)fullSize { +- (id)initWithTabContents:(TabContentsWrapper*)contents + fullSize:(NSSize)fullSize { CHECK(contents); if ((self = [super init])) { contents_ = contents; @@ -198,7 +203,7 @@ void ThumbnailLoader::LoadThumbnail() { return self; } -- (void)setTabContents:(TabContents*)contents { +- (void)setTabContents:(TabContentsWrapper*)contents { contents_ = contents; } @@ -216,7 +221,7 @@ void ThumbnailLoader::LoadThumbnail() { // Medium term, we want to show thumbs of the actual info bar views, which // means I need to create InfoBarControllers here. - NSWindow* window = [contents_->GetNativeView() window]; + NSWindow* window = [contents_->tab_contents()->GetNativeView() window]; NSWindowController* windowController = [window windowController]; if ([windowController isKindOfClass:[BrowserWindowController class]]) { BrowserWindowController* bwc = @@ -232,7 +237,8 @@ void ThumbnailLoader::LoadThumbnail() { bool always_show_bookmark_bar = contents_->profile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); bool has_detached_bookmark_bar = - contents_->ShouldShowBookmarkBar() && !always_show_bookmark_bar; + contents_->tab_contents()->ShouldShowBookmarkBar() && + !always_show_bookmark_bar; if (has_detached_bookmark_bar) topOffset += bookmarks::kNTPBookmarkBarHeight; @@ -241,10 +247,11 @@ void ThumbnailLoader::LoadThumbnail() { - (int)bottomOffset { int bottomOffset = 0; - TabContents* devToolsContents = - DevToolsWindow::GetDevToolsContents(contents_); - if (devToolsContents && devToolsContents->render_view_host() && - devToolsContents->render_view_host()->view()) { + TabContentsWrapper* devToolsContents = + DevToolsWindow::GetDevToolsContents(contents_->tab_contents()); + if (devToolsContents && devToolsContents->tab_contents() && + devToolsContents->tab_contents()->render_view_host() && + devToolsContents->tab_contents()->render_view_host()->view()) { // The devtool's size might not be up-to-date, but since its height doesn't // change on window resize, and since most users don't use devtools, this is // good enough. @@ -431,7 +438,7 @@ class Tile { NSRect GetFaviconStartRectRelativeTo(const Tile& tile) const; NSRect favicon_rect() const { return NSIntegralRect(favicon_rect_); } - SkBitmap favicon() const; + NSImage* favicon() const; // This changes |title_rect| and |favicon_rect| such that the favicon is on // the font's baseline and that the minimum distance between thumb rect and @@ -448,10 +455,14 @@ class Tile { NSRect title_rect() const { return NSIntegralRect(title_rect_); } // Returns an unelided title. The view logic is responsible for eliding. - const string16& title() const { return contents_->GetTitle(); } + const string16& title() const { + return contents_->tab_contents()->GetTitle(); + } - TabContents* tab_contents() const { return contents_; } - void set_tab_contents(TabContents* new_contents) { contents_ = new_contents; } + TabContentsWrapper* tab_contents() const { return contents_; } + void set_tab_contents(TabContentsWrapper* new_contents) { + contents_ = new_contents; + } private: friend class TileSet; @@ -466,7 +477,7 @@ class Tile { CGFloat title_font_size_; NSRect title_rect_; - TabContents* contents_; // weak + TabContentsWrapper* contents_; // weak DISALLOW_COPY_AND_ASSIGN(Tile); }; @@ -488,13 +499,13 @@ NSRect Tile::GetFaviconStartRectRelativeTo(const Tile& tile) const { return rect; } -SkBitmap Tile::favicon() const { - if (contents_->is_app()) { - SkBitmap* icon = contents_->GetExtensionAppIcon(); - if (icon) - return *icon; +NSImage* Tile::favicon() const { + if (contents_->extension_tab_helper()->is_app()) { + SkBitmap* bitmap = contents_->extension_tab_helper()->GetExtensionAppIcon(); + if (bitmap) + return gfx::SkBitmapToNSImage(*bitmap); } - return contents_->GetFavIcon(); + return mac::FaviconForTabContents(contents_->tab_contents()); } NSRect Tile::GetTitleStartRectRelativeTo(const Tile& tile) const { @@ -559,7 +570,7 @@ class TileSet { // Inserts a new Tile object containing |contents| at |index|. Does no // relayout. - void InsertTileAt(int index, TabContents* contents); + void InsertTileAt(int index, TabContentsWrapper* contents); // Removes the Tile object at |index|. Does no relayout. void RemoveTileAt(int index); @@ -599,11 +610,11 @@ class TileSet { }; void TileSet::Build(TabStripModel* source_model) { - selected_index_ = source_model->selected_index(); + selected_index_ = source_model->active_index(); tiles_.resize(source_model->count()); for (size_t i = 0; i < tiles_.size(); ++i) { tiles_[i] = new Tile; - tiles_[i]->contents_ = source_model->GetTabContentsAt(i)->tab_contents(); + tiles_[i]->contents_ = source_model->GetTabContentsAt(i); } } @@ -825,7 +836,7 @@ int TileSet::previous_index() const { return new_index; } -void TileSet::InsertTileAt(int index, TabContents* contents) { +void TileSet::InsertTileAt(int index, TabContentsWrapper* contents) { tiles_.insert(tiles_.begin() + index, new Tile); tiles_[index]->contents_ = contents; } @@ -1067,17 +1078,8 @@ void AnimateCALayerOpacityFromTo( NSFont* font = [NSFont systemFontOfSize:tile.title_font_size()]; tile.set_font_metrics([font ascender], -[font descender]); - NSImage* nsFavicon = gfx::SkBitmapToNSImage(tile.favicon()); - // Either we don't have a valid favicon or there was some issue converting - // it from an SkBitmap. Either way, just show the default. - if (!nsFavicon) { - NSImage* defaultFavIcon = - ResourceBundle::GetSharedInstance().GetNativeImageNamed( - IDR_DEFAULT_FAVICON); - nsFavicon = defaultFavIcon; - } base::mac::ScopedCFTypeRef<CGImageRef> favicon( - base::mac::CopyNSImageToCGImage(nsFavicon)); + base::mac::CopyNSImageToCGImage(tile.favicon())); CALayer* faviconLayer = [CALayer layer]; if (showZoom) { @@ -1274,7 +1276,7 @@ void AnimateCALayerOpacityFromTo( [self fadeAwayInSlomo:([event modifierFlags] & NSShiftKeyMask) != 0]; break; case '\e': // Escape - tileSet_->set_selected_index(tabStripModel_->selected_index()); + tileSet_->set_selected_index(tabStripModel_->active_index()); [self fadeAwayInSlomo:([event modifierFlags] & NSShiftKeyMask) != 0]; break; } @@ -1444,8 +1446,8 @@ void AnimateCALayerOpacityFromTo( // Select chosen tab. if (tileSet_->selected_index() < tabStripModel_->count()) { - tabStripModel_->SelectTabContentsAt(tileSet_->selected_index(), - /*user_gesture=*/true); + tabStripModel_->ActivateTabAt(tileSet_->selected_index(), + /*user_gesture=*/true); } else { DCHECK_EQ(tileSet_->selected_index(), 0); } @@ -1565,7 +1567,7 @@ void AnimateCALayerOpacityFromTo( ScopedCAActionSetDuration durationSetter(kObserverChangeAnimationDuration); // Insert new layer and relayout. - tileSet_->InsertTileAt(index, contents->tab_contents()); + tileSet_->InsertTileAt(index, contents); tileSet_->Layout(containingRect_); [self addLayersForTile:tileSet_->tile_at(index) showZoom:NO @@ -1690,16 +1692,16 @@ void AnimateCALayerOpacityFromTo( // For now, just make sure that we don't hold on to an invalid TabContents // object. tabpose::Tile& tile = tileSet_->tile_at(index); - if (contents->tab_contents() == tile.tab_contents()) { + if (contents == tile.tab_contents()) { // TODO(thakis): Install a timer to send a thumb request/update title/update // favicon after 20ms or so, and reset the timer every time this is called // to make sure we get an updated thumb, without requesting them all over. return; } - tile.set_tab_contents(contents->tab_contents()); + tile.set_tab_contents(contents); ThumbnailLayer* thumbLayer = [allThumbnailLayers_ objectAtIndex:index]; - [thumbLayer setTabContents:contents->tab_contents()]; + [thumbLayer setTabContents:contents]; } - (void)tabStripModelDeleted { diff --git a/chrome/browser/ui/cocoa/tabpose_window_unittest.mm b/chrome/browser/ui/cocoa/tabpose_window_unittest.mm index 4375d4a..9f51763 100644 --- a/chrome/browser/ui/cocoa/tabpose_window_unittest.mm +++ b/chrome/browser/ui/cocoa/tabpose_window_unittest.mm @@ -1,11 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/tabpose_window.h" -#import "chrome/browser/browser_window.h" #include "chrome/browser/tabs/tab_strip_model.h" +#import "chrome/browser/ui/browser_window.h" #import "chrome/browser/ui/cocoa/browser_test_helper.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" diff --git a/chrome/browser/ui/cocoa/tabs/side_tab_strip_view.mm b/chrome/browser/ui/cocoa/tabs/side_tab_strip_view.mm index 80cefc1..88f06a3 100644 --- a/chrome/browser/ui/cocoa/tabs/side_tab_strip_view.mm +++ b/chrome/browser/ui/cocoa/tabs/side_tab_strip_view.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/tabs/side_tab_strip_view.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "third_party/GTM/AppKit/GTMNSColor+Luminance.h" @implementation SideTabStripView diff --git a/chrome/browser/ui/cocoa/tabs/side_tab_strip_view_unittest.mm b/chrome/browser/ui/cocoa/tabs/side_tab_strip_view_unittest.mm index 1cc5572..9c2bfd5 100644 --- a/chrome/browser/ui/cocoa/tabs/side_tab_strip_view_unittest.mm +++ b/chrome/browser/ui/cocoa/tabs/side_tab_strip_view_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/tabs/side_tab_strip_view.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/tabs/tab_controller.h b/chrome/browser/ui/cocoa/tabs/tab_controller.h index 581b82c..2833eda 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_controller.h +++ b/chrome/browser/ui/cocoa/tabs/tab_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,6 +9,7 @@ #import <Cocoa/Cocoa.h> #import "chrome/browser/ui/cocoa/hover_close_button.h" #include "chrome/browser/ui/tabs/tab_menu_model.h" +#include "googleurl/src/gurl.h" // The loading/waiting state of the tab. enum TabLoadingState { @@ -49,6 +50,7 @@ class MenuDelegate; BOOL mini_; BOOL pinned_; BOOL selected_; + GURL url_; TabLoadingState loadingState_; CGFloat iconTitleXOffset_; // between left edges of icon and title id<TabControllerTarget> target_; // weak, where actions are sent @@ -66,6 +68,7 @@ class MenuDelegate; @property(assign, nonatomic) BOOL pinned; @property(assign, nonatomic) BOOL selected; @property(assign, nonatomic) id target; +@property(assign, nonatomic) GURL url; @property(assign, nonatomic) NSView* iconView; @property(assign, nonatomic) NSTextField* titleView; @property(assign, nonatomic) HoverCloseButton* closeButton; diff --git a/chrome/browser/ui/cocoa/tabs/tab_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_controller.mm index 5f53ab5..0c7b1a9 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_controller.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_controller.mm @@ -3,8 +3,7 @@ // found in the LICENSE file. #include "base/mac/mac_util.h" -#include "chrome/browser/accessibility/browser_accessibility_state.h" -#import "chrome/browser/themes/browser_theme_provider.h" +#import "chrome/browser/themes/theme_service.h" #import "chrome/browser/ui/cocoa/menu_controller.h" #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" #import "chrome/browser/ui/cocoa/tabs/tab_controller_target.h" @@ -12,6 +11,7 @@ #import "chrome/browser/ui/cocoa/themed_window.h" #import "chrome/common/extensions/extension.h" #include "grit/generated_resources.h" +#import "third_party/GTM/AppKit/GTMFadeTruncatingTextFieldCell.h" #include "ui/base/l10n/l10n_util_mac.h" @implementation TabController @@ -22,6 +22,7 @@ @synthesize mini = mini_; @synthesize pinned = pinned_; @synthesize target = target_; +@synthesize url = url_; @synthesize iconView = iconView_; @synthesize titleView = titleView_; @synthesize closeButton = closeButton_; @@ -222,12 +223,6 @@ class MenuDelegate : public ui::SimpleMenuModel::Delegate { // Returns YES if we should be showing the close button. The selected tab // always shows the close button. - (BOOL)shouldShowCloseButton { - // Accessibility: When VoiceOver is active, it is desirable for us to hide the - // close button, so that VoiceOver does not encounter it. - // TODO(dtseng): http://crbug.com/59978 - if (BrowserAccessibilityState::GetInstance()->IsAccessibleBrowser()) - return NO; - if ([self mini]) return NO; return ([self selected] || [self iconCapacity] >= 3); @@ -278,12 +273,12 @@ class MenuDelegate : public ui::SimpleMenuModel::Delegate { ui::ThemeProvider* theme = [[[self view] window] themeProvider]; if (theme && ![self selected]) { titleColor = - theme->GetNSColor(BrowserThemeProvider::COLOR_BACKGROUND_TAB_TEXT, + theme->GetNSColor(ThemeService::COLOR_BACKGROUND_TAB_TEXT, true); } // Default to the selected text color unless told otherwise. if (theme && !titleColor) { - titleColor = theme->GetNSColor(BrowserThemeProvider::COLOR_TAB_TEXT, + titleColor = theme->GetNSColor(ThemeService::COLOR_TAB_TEXT, true); } [titleView_ setTextColor:titleColor ? titleColor : [NSColor textColor]]; diff --git a/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm b/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm index ef49850..40d177e 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #include "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" #import "chrome/browser/ui/cocoa/tabs/tab_controller_target.h" diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.h b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.h index 69ffd41..9b90daf 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.h +++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,8 +8,8 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h" #import "chrome/browser/ui/cocoa/tabs/tab_controller_target.h" #import "chrome/browser/ui/cocoa/url_drop_target.h" @@ -17,6 +17,7 @@ @class CrTrackingArea; @class NewTabButton; +@class ProfileMenuButton; @class TabContentsController; @class TabView; @class TabStripView; @@ -28,6 +29,10 @@ class TabStripModel; class TabContents; class ToolbarModel; +namespace TabStripControllerInternal { +class NotificationBridge; +} // namespace TabStripControllerInternal + // The interface for the tab strip controller's delegate. // Delegating TabStripModelObserverBridge's events (in lieu of directly // subscribing to TabStripModelObserverBridge events, as TabStripController @@ -70,6 +75,8 @@ class ToolbarModel; NSView* switchView_; // weak scoped_nsobject<NSView> dragBlockingView_; // avoid bad window server drags NewTabButton* newTabButton_; // weak, obtained from the nib. + ProfileMenuButton* profileMenuButton_; // weak, obtained from the nib. + BOOL hasUpdatedProfileMenuButtonXOffset_; // Tracks the newTabButton_ for rollovers. scoped_nsobject<CrTrackingArea> newTabTrackingArea_; @@ -132,7 +139,7 @@ class ToolbarModel; scoped_nsobject<NSMutableArray> permanentSubviews_; // The default favicon, so we can use one copy for all buttons. - scoped_nsobject<NSImage> defaultFavIcon_; + scoped_nsobject<NSImage> defaultFavicon_; // The amount by which to indent the tabs on the left (to make room for the // red/yellow/green buttons). @@ -143,6 +150,10 @@ class ToolbarModel; // Is the mouse currently inside the strip; BOOL mouseInside_; + + // Used for monitoring the profile name pref. + scoped_ptr<TabStripControllerInternal::NotificationBridge> + notificationBridge_; } @property(nonatomic) CGFloat indentForControls; diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm index 183ad6c..d114008 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -10,13 +10,16 @@ #include <string> #include "app/mac/nsimage_cache.h" +#include "base/command_line.h" #include "base/mac/mac_util.h" #include "base/sys_string_conversions.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/autocomplete/autocomplete.h" #include "chrome/browser/autocomplete/autocomplete_classifier.h" #include "chrome/browser/autocomplete/autocomplete_match.h" +#include "chrome/browser/extensions/extension_tab_helper.h" #include "chrome/browser/metrics/user_metrics.h" +#include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/debugger/devtools_window.h" #include "chrome/browser/net/url_fixer_upper.h" @@ -29,6 +32,8 @@ #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/constrained_window_mac.h" #import "chrome/browser/ui/cocoa/new_tab_button.h" +#import "chrome/browser/ui/cocoa/profile_menu_button.h" +#import "chrome/browser/ui/cocoa/tab_contents/favicon_util.h" #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" #import "chrome/browser/ui/cocoa/tabs/tab_strip_model_observer_bridge.h" #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" @@ -38,10 +43,13 @@ #include "chrome/browser/ui/find_bar/find_bar.h" #include "chrome/browser/ui/find_bar/find_bar_controller.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/pref_names.h" #include "content/browser/tab_contents/navigation_controller.h" #include "content/browser/tab_contents/navigation_entry.h" #include "content/browser/tab_contents/tab_contents.h" #include "content/browser/tab_contents/tab_contents_view.h" +#include "content/common/notification_service.h" #include "grit/app_resources.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" @@ -53,6 +61,21 @@ NSString* const kTabStripNumberOfTabsChanged = @"kTabStripNumberOfTabsChanged"; +// 10.7 adds public APIs for full-screen support. Provide the declaration so it +// can be called below when building with the 10.5 SDK. +#if !defined(MAC_OS_X_VERSION_10_7) || \ +MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 + +@interface NSWindow (LionSDKDeclarations) +- (void)toggleFullScreen:(id)sender; +@end + +enum { + NSWindowFullScreenButton = 7 +}; + +#endif // MAC_OS_X_VERSION_10_7 + namespace { // The images names used for different states of the new tab button. @@ -80,6 +103,10 @@ const CGFloat kIncognitoBadgeTabStripShrink = 18; // Time (in seconds) in which tabs animate to their final position. const NSTimeInterval kAnimationDuration = 0.125; +// The amount by wich the profile menu button is offset (from tab tabs or new +// tab button). +const CGFloat kProfileMenuButtonOffset = 6.0; + // Helper class for doing NSAnimationContext calls that takes a bool to disable // all the work. Useful for code that wants to conditionally animate. class ScopedNSAnimationContextGroup { @@ -127,7 +154,7 @@ private: - (void)addSubviewToPermanentList:(NSView*)aView; - (void)regenerateSubviewList; - (NSInteger)indexForContentsView:(NSView*)view; -- (void)updateFavIconForContents:(TabContents*)contents +- (void)updateFaviconForContents:(TabContents*)contents atIndex:(NSInteger)modelIndex; - (void)layoutTabsWithAnimation:(BOOL)animate regenerateSubviews:(BOOL)doUpdate; @@ -143,6 +170,8 @@ private: givesIndex:(NSInteger*)index disposition:(WindowOpenDisposition*)disposition; - (void)setNewTabButtonHoverState:(BOOL)showHover; +- (BOOL)shouldShowProfileMenuButton; +- (void)updateProfileMenuButton; @end // A simple view class that prevents the Window Server from dragging the area @@ -241,6 +270,39 @@ private: @end +namespace TabStripControllerInternal { + +// Bridges C++ notifications back to the TabStripController. +class NotificationBridge : public NotificationObserver { + public: + explicit NotificationBridge(TabStripController* controller, + PrefService* prefService) + : controller_(controller) { + DCHECK(prefService); + usernamePref_.Init(prefs::kGoogleServicesUsername, prefService, this); + } + + // Overridden from NotificationObserver: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK_EQ(NotificationType::PREF_CHANGED, type.value); + std::string* name = Details<std::string>(details).ptr(); + if (prefs::kGoogleServicesUsername == *name) { + [controller_ updateProfileMenuButton]; + [controller_ layoutTabsWithAnimation:NO regenerateSubviews:NO]; + } + } + + private: + TabStripController* controller_; // weak, owns us + + // The Google services user name associated with this BrowserView's profile. + StringPrefMember usernamePref_; +}; + +} // namespace TabStripControllerInternal + #pragma mark - // In general, there is a one-to-one correspondence between TabControllers, @@ -303,8 +365,8 @@ private: // (see |-addSubviewToPermanentList:|) will be wiped out. permanentSubviews_.reset([[NSMutableArray alloc] init]); - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - defaultFavIcon_.reset([rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON) retain]); + defaultFavicon_.reset( + [app::mac::GetCachedImageWithName(@"nav.pdf") retain]); [self setIndentForControls:[[self class] defaultIndentForControls]]; @@ -316,6 +378,15 @@ private: [newTabButton_ setTarget:nil]; [newTabButton_ setAction:@selector(commandDispatch:)]; [newTabButton_ setTag:IDC_NEW_TAB]; + + profileMenuButton_ = [view profileMenuButton]; + [self addSubviewToPermanentList:profileMenuButton_]; + [self updateProfileMenuButton]; + // Register pref observers for profile name. + notificationBridge_.reset( + new TabStripControllerInternal::NotificationBridge( + self, browser_->profile()->GetPrefs())); + // Set the images from code because Cocoa fails to find them in our sub // bundle during tests. [newTabButton_ setImage:app::mac::GetCachedImageWithName(kNewTabImage)]; @@ -483,6 +554,11 @@ private: // It also restores content autoresizing properties. [controller ensureContentsVisible]; + // Tell per-tab sheet manager about currently selected tab. + if (sheetController_.get()) { + [sheetController_ setActiveView:newView]; + } + // Make sure the new tabs's sheets are visible (necessary when a background // tab opened a sheet while it was in the background and now becomes active). TabContentsWrapper* newTab = tabStripModel_->GetTabContentsAt(modelIndex); @@ -501,11 +577,6 @@ private: static_cast<BrowserWindowController*>(controller)); } } - - // Tell per-tab sheet manager about currently selected tab. - if (sheetController_.get()) { - [sheetController_ setActiveView:newView]; - } } // Create a new tab view and set its cell correctly so it draws the way we want @@ -625,7 +696,7 @@ private: DCHECK([sender isKindOfClass:[NSView class]]); int index = [self modelIndexForTabView:sender]; if (tabStripModel_->ContainsIndex(index)) - tabStripModel_->SelectTabContentsAt(index, true); + tabStripModel_->ActivateTabAt(index, true); } // Called when the user closes a tab. Asks the model to close the tab. |sender| @@ -761,10 +832,19 @@ private: availableSpace = availableResizeWidth_; } else { availableSpace = NSWidth([tabStripView_ frame]); - // Account for the new tab button and the incognito badge. + + // Account for the widths of the new tab button, the incognito badge, and + // the fullscreen button if any/all are present. availableSpace -= NSWidth([newTabButton_ frame]) + kNewTabButtonOffset; if (browser_->profile()->IsOffTheRecord()) availableSpace -= kIncognitoBadgeTabStripShrink; + if ([[tabStripView_ window] + respondsToSelector:@selector(toggleFullScreen:)]) { + NSButton* fullscreenButton = [[tabStripView_ window] + standardWindowButton:NSWindowFullScreenButton]; + if (fullscreenButton) + availableSpace -= [fullscreenButton frame].size.width; + } } availableSpace -= [self indentForControls]; } @@ -946,6 +1026,49 @@ private: } } + if (profileMenuButton_ && ![profileMenuButton_ isHidden]) { + CGFloat maxX; + if ([newTabButton_ isHidden]) { + maxX = std::max(offset, NSMaxX(placeholderFrame_) - kTabOverlap); + } else { + maxX = NSMaxX(newTabTargetFrame_); + } + NSRect profileMenuButtonFrame = [profileMenuButton_ frame]; + NSSize minSize = [profileMenuButton_ minControlSize]; + + // Make room for the full screen button if necessary. + if (!hasUpdatedProfileMenuButtonXOffset_) { + hasUpdatedProfileMenuButtonXOffset_ = YES; + if ([[profileMenuButton_ window] + respondsToSelector:@selector(toggleFullScreen:)]) { + NSButton* fullscreenButton = [[profileMenuButton_ window] + standardWindowButton:NSWindowFullScreenButton]; + if (fullscreenButton) { + profileMenuButtonFrame.origin.x = NSMinX([fullscreenButton frame]) - + NSWidth(profileMenuButtonFrame) - kProfileMenuButtonOffset; + } + } + } + + // TODO(sail): Animate this. + CGFloat availableWidth = NSMaxX(profileMenuButtonFrame) - maxX - + kProfileMenuButtonOffset; + if (availableWidth > minSize.width) { + [profileMenuButton_ setShouldShowProfileDisplayName:YES]; + } else { + [profileMenuButton_ setShouldShowProfileDisplayName:NO]; + } + + NSSize desiredSize = [profileMenuButton_ desiredControlSize]; + NSRect rect; + rect.size.width = std::min(desiredSize.width, + std::max(availableWidth, minSize.width)); + rect.size.height = desiredSize.height; + rect.origin.y = NSMaxY(profileMenuButtonFrame) - rect.size.height; + rect.origin.x = NSMaxX(profileMenuButtonFrame) - rect.size.width; + [profileMenuButton_ setFrame:rect]; + } + [dragBlockingView_ setFrame:enclosingRect]; // Mark that we've successfully completed layout of at least one tab. @@ -994,6 +1117,7 @@ private: [newController setMini:tabStripModel_->IsMiniTab(modelIndex)]; [newController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; [newController setApp:tabStripModel_->IsAppTab(modelIndex)]; + [newController setUrl:contents->tab_contents()->GetURL()]; [tabArray_ insertObject:newController atIndex:index]; NSView* newView = [newController view]; @@ -1021,7 +1145,7 @@ private: // dragging a tab out into a new window, we have to put the tab's favicon // into the right state up front as we won't be told to do it from anywhere // else. - [self updateFavIconForContents:contents->tab_contents() atIndex:modelIndex]; + [self updateFaviconForContents:contents->tab_contents() atIndex:modelIndex]; // Send a broadcast that the number of tabs have changed. [[NSNotificationCenter defaultCenter] @@ -1211,27 +1335,28 @@ private: [delegate_ onTabDetachedWithContents:contents->tab_contents()]; } -// A helper routine for creating an NSImageView to hold the fav icon or app icon +// A helper routine for creating an NSImageView to hold the favicon or app icon // for |contents|. - (NSImageView*)iconImageViewForContents:(TabContents*)contents { - BOOL isApp = contents->is_app(); + TabContentsWrapper* wrapper = + TabContentsWrapper::GetCurrentWrapperForContents(contents); + BOOL isApp = wrapper->extension_tab_helper()->is_app(); NSImage* image = nil; // Favicons come from the renderer, and the renderer draws everything in the // system color space. CGColorSpaceRef colorSpace = base::mac::GetSystemColorSpace(); if (isApp) { - SkBitmap* icon = contents->GetExtensionAppIcon(); + SkBitmap* icon = wrapper->extension_tab_helper()->GetExtensionAppIcon(); if (icon) image = gfx::SkBitmapToNSImageWithColorSpace(*icon, colorSpace); } else { - image = gfx::SkBitmapToNSImageWithColorSpace(contents->GetFavIcon(), - colorSpace); + image = mac::FaviconForTabContents(contents); } // Either we don't have a valid favicon or there was some issue converting it // from an SkBitmap. Either way, just show the default. if (!image) - image = defaultFavIcon_.get(); + image = defaultFavicon_.get(); NSRect frame = NSMakeRect(0, 0, kIconWidthAndHeight, kIconWidthAndHeight); NSImageView* view = [[[NSImageView alloc] initWithFrame:frame] autorelease]; [view setImage:image]; @@ -1240,7 +1365,7 @@ private: // Updates the current loading state, replacing the icon view with a favicon, // a throbber, the default icon, or nothing at all. -- (void)updateFavIconForContents:(TabContents*)contents +- (void)updateFaviconForContents:(TabContents*)contents atIndex:(NSInteger)modelIndex { if (!contents) return; @@ -1260,7 +1385,7 @@ private: TabController* tabController = [tabArray_ objectAtIndex:index]; bool oldHasIcon = [tabController iconView] != nil; - bool newHasIcon = contents->ShouldDisplayFavIcon() || + bool newHasIcon = contents->ShouldDisplayFavicon() || tabStripModel_->IsMiniTab(modelIndex); // Always show icon if mini. TabLoadingState oldState = [tabController loadingState]; @@ -1318,7 +1443,7 @@ private: // Take closing tabs into account. NSInteger index = [self indexFromModelIndex:modelIndex]; - if (modelIndex == tabStripModel_->selected_index()) + if (modelIndex == tabStripModel_->active_index()) [delegate_ onSelectedTabChange:change]; if (change == TabStripModelObserver::TITLE_NOT_LOADING) { @@ -1332,7 +1457,7 @@ private: if (change != TabStripModelObserver::LOADING_ONLY) [self setTabTitle:tabController withContents:contents->tab_contents()]; - [self updateFavIconForContents:contents->tab_contents() atIndex:modelIndex]; + [self updateFaviconForContents:contents->tab_contents() atIndex:modelIndex]; TabContentsController* updatedController = [tabContentsArray_ objectAtIndex:index]; @@ -1383,7 +1508,8 @@ private: [tabController setMini:tabStripModel_->IsMiniTab(modelIndex)]; [tabController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; [tabController setApp:tabStripModel_->IsAppTab(modelIndex)]; - [self updateFavIconForContents:contents->tab_contents() atIndex:modelIndex]; + [tabController setUrl:contents->tab_contents()->GetURL()]; + [self updateFaviconForContents:contents->tab_contents() atIndex:modelIndex]; // If the tab is being restored and it's pinned, the mini state is set after // the tab has already been rendered, so re-layout the tabstrip. In all other // cases, the state is set before the tab is rendered so this isn't needed. @@ -1399,7 +1525,7 @@ private: } - (NSView*)selectedTabView { - int selectedIndex = tabStripModel_->selected_index(); + int selectedIndex = tabStripModel_->active_index(); // Take closing tabs into account. They can't ever be selected. selectedIndex = [self indexFromModelIndex:selectedIndex]; return [self viewAtIndex:selectedIndex]; @@ -1470,7 +1596,7 @@ private: // inherit the current tab's group. tabStripModel_->InsertTabContentsAt( modelIndex, contents, - TabStripModel::ADD_SELECTED | (pinned ? TabStripModel::ADD_PINNED : 0)); + TabStripModel::ADD_ACTIVE | (pinned ? TabStripModel::ADD_PINNED : 0)); } // Called when the tab strip view changes size. As we only registered for @@ -1716,7 +1842,7 @@ private: params.disposition = disposition; params.tabstrip_index = index; params.tabstrip_add_types = - TabStripModel::ADD_SELECTED | TabStripModel::ADD_FORCE_INDEX; + TabStripModel::ADD_ACTIVE | TabStripModel::ADD_FORCE_INDEX; browser::Navigate(¶ms); break; } @@ -1726,7 +1852,7 @@ private: tabStripModel_->GetTabContentsAt(index) ->tab_contents()->OpenURL(*url, GURL(), CURRENT_TAB, PageTransition::TYPED); - tabStripModel_->SelectTabContentsAt(index, true); + tabStripModel_->ActivateTabAt(index, true); break; default: NOTIMPLEMENTED(); @@ -1839,7 +1965,7 @@ private: } - (TabContentsController*)activeTabContentsController { - int modelIndex = tabStripModel_->selected_index(); + int modelIndex = tabStripModel_->active_index(); if (modelIndex < 0) return nil; NSInteger index = [self indexFromModelIndex:modelIndex]; @@ -1859,7 +1985,7 @@ private: NSInteger index = [self modelIndexForContentsView:view]; DCHECK(index >= 0); if (index >= 0) - tabStripModel_->SelectTabContentsAt(index, false /* not a user gesture */); + tabStripModel_->ActivateTabAt(index, false /* not a user gesture */); } - (void)attachConstrainedWindow:(ConstrainedWindowMac*)window { @@ -1906,4 +2032,37 @@ private: } } +- (BOOL)shouldShowProfileMenuButton { + if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kMultiProfiles)) + return NO; + if (browser_->profile()->IsOffTheRecord()) + return NO; + return (!browser_->profile()->GetPrefs()->GetString( + prefs::kGoogleServicesUsername).empty()); +} + +- (void)updateProfileMenuButton { + if (![self shouldShowProfileMenuButton]) { + [profileMenuButton_ setHidden:YES]; + return; + } + + std::string profileName = browser_->profile()->GetPrefs()->GetString( + prefs::kGoogleServicesUsername); + [profileMenuButton_ setProfileDisplayName: + [NSString stringWithUTF8String:profileName.c_str()]]; + [profileMenuButton_ setHidden:NO]; + + NSMenu* menu = [profileMenuButton_ menu]; + while ([menu numberOfItems] > 0) { + [menu removeItemAtIndex:0]; + } + + NSString* menuTitle = + l10n_util::GetNSStringWithFixup(IDS_PROFILES_CREATE_NEW_PROFILE_OPTION); + [menu addItemWithTitle:menuTitle + action:NULL + keyEquivalent:@""]; +} + @end diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm index 6d9e3ac..a83f0d1 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm @@ -1,18 +1,18 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> -#import "chrome/browser/browser_window.h" +#import "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/cocoa/browser_test_helper.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/new_tab_button.h" #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" -#include "content/browser/tab_contents/tab_contents.h" #include "content/browser/site_instance.h" +#include "content/browser/tab_contents/tab_contents.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_view.h b/chrome/browser/ui/cocoa/tabs/tab_strip_view.h index 704136e..eeef760 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_strip_view.h +++ b/chrome/browser/ui/cocoa/tabs/tab_strip_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,10 +8,11 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/url_drop_target.h" @class NewTabButton; +@class ProfileMenuButton; // A view class that handles rendering the tab strip and drops of URLS with // a positioning locator for drop feedback. @@ -25,6 +26,7 @@ // Weak; the following come from the nib. NewTabButton* newTabButton_; + ProfileMenuButton* profileMenuButton_; // Whether the drop-indicator arrow is shown, and if it is, the coordinate of // its tip. @@ -33,6 +35,7 @@ } @property(assign, nonatomic) IBOutlet NewTabButton* newTabButton; +@property(assign, nonatomic) IBOutlet ProfileMenuButton* profileMenuButton; @property(assign, nonatomic) BOOL dropArrowShown; @property(assign, nonatomic) NSPoint dropArrowPosition; diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_view.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_view.mm index a8a15a4..7d0c321 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_strip_view.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_strip_view.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -6,7 +6,8 @@ #include "base/logging.h" #include "base/mac/mac_util.h" -#include "chrome/browser/themes/browser_theme_provider.h" +#include "chrome/browser/themes/theme_service.h" +#import "chrome/browser/ui/cocoa/nsview_additions.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" #import "chrome/browser/ui/cocoa/view_id_util.h" @@ -14,6 +15,7 @@ @implementation TabStripView @synthesize newTabButton = newTabButton_; +@synthesize profileMenuButton = profileMenuButton_; @synthesize dropArrowShown = dropArrowShown_; @synthesize dropArrowPosition = dropArrowPosition_; @@ -34,24 +36,25 @@ // responsible for mimicking this bottom border, unless it's the selected // tab. - (void)drawBorder:(NSRect)bounds { + const CGFloat lineWidth = [self cr_lineWidth]; NSRect borderRect, contentRect; borderRect = bounds; - borderRect.origin.y = 1; - borderRect.size.height = 1; + borderRect.origin.y = lineWidth; + borderRect.size.height = lineWidth; [[NSColor colorWithCalibratedWhite:0.0 alpha:0.2] set]; NSRectFillUsingOperation(borderRect, NSCompositeSourceOver); - NSDivideRect(bounds, &borderRect, &contentRect, 1, NSMinYEdge); + NSDivideRect(bounds, &borderRect, &contentRect, lineWidth, NSMinYEdge); - BrowserThemeProvider* themeProvider = - static_cast<BrowserThemeProvider*>([[self window] themeProvider]); + ThemeService* themeProvider = + static_cast<ThemeService*>([[self window] themeProvider]); if (!themeProvider) return; NSColor* bezelColor = themeProvider->GetNSColor( themeProvider->UsingDefaultTheme() ? - BrowserThemeProvider::COLOR_TOOLBAR_BEZEL : - BrowserThemeProvider::COLOR_TOOLBAR, true); + ThemeService::COLOR_TOOLBAR_BEZEL : + ThemeService::COLOR_TOOLBAR, true); [bezelColor set]; NSRectFill(borderRect); NSRectFillUsingOperation(borderRect, NSCompositeSourceOver); diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_view_unittest.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_view_unittest.mm index 349774b..d7961aa 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_strip_view_unittest.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_strip_view_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/tabs/tab_view.h b/chrome/browser/ui/cocoa/tabs/tab_view.h index 9a86c20..17eb173 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_view.h +++ b/chrome/browser/ui/cocoa/tabs/tab_view.h @@ -11,7 +11,7 @@ #include <map> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/background_gradient_view.h" #import "chrome/browser/ui/cocoa/hover_close_button.h" diff --git a/chrome/browser/ui/cocoa/tabs/tab_view.mm b/chrome/browser/ui/cocoa/tabs/tab_view.mm index ba5d18c..ecab140 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_view.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_view.mm @@ -7,12 +7,15 @@ #include "base/logging.h" #import "base/mac/mac_util.h" #include "base/mac/scoped_cftyperef.h" -#include "chrome/browser/themes/browser_theme_provider.h" +#include "chrome/browser/themes/theme_service.h" +#import "chrome/browser/ui/cocoa/nsview_additions.h" #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" #import "chrome/browser/ui/cocoa/tabs/tab_window_controller.h" #import "chrome/browser/ui/cocoa/themed_window.h" #import "chrome/browser/ui/cocoa/view_id_util.h" +#include "grit/generated_resources.h" #include "grit/theme_resources.h" +#include "ui/base/l10n/l10n_util.h" namespace { @@ -302,12 +305,37 @@ const CGFloat kRapidCloseDist = 2.5; // Because we move views between windows, we need to handle the event loop // ourselves. Ideally we should use the standard event loop. while (1) { + const NSUInteger mask = + NSLeftMouseUpMask | NSLeftMouseDraggedMask | NSKeyUpMask; theEvent = - [NSApp nextEventMatchingMask:NSLeftMouseUpMask | NSLeftMouseDraggedMask + [NSApp nextEventMatchingMask:mask untilDate:[NSDate distantFuture] inMode:NSDefaultRunLoopMode dequeue:YES]; NSEventType type = [theEvent type]; - if (type == NSLeftMouseDragged) { + if (type == NSKeyUp) { + if ([theEvent keyCode] == kVK_Escape) { + // Cancel the drag and restore the previous state. + if (draggingWithinTabStrip_) { + // Simply pretend the tab wasn't dragged (far enough). + tabWasDragged_ = NO; + } else { + [targetController_ removePlaceholder]; + if ([sourceController_ numberOfTabs] < 2) { + // Revert to a single-tab window. + targetController_ = nil; + } else { + // Change the target to the source controller. + targetController_ = sourceController_; + [targetController_ insertPlaceholderForTab:self + frame:sourceTabFrame_ + yStretchiness:0]; + } + } + // Call the |mouseUp:| code to end the drag. + [self mouseUp:theEvent]; + break; + } + } else if (type == NSLeftMouseDragged) { [self mouseDragged:theEvent]; } else if (type == NSLeftMouseUp) { NSPoint upLocation = [theEvent locationInWindow]; @@ -620,11 +648,13 @@ const CGFloat kRapidCloseDist = 2.5; } - (void)drawRect:(NSRect)dirtyRect { + const CGFloat lineWidth = [self cr_lineWidth]; + NSGraphicsContext* context = [NSGraphicsContext currentContext]; [context saveGraphicsState]; - BrowserThemeProvider* themeProvider = - static_cast<BrowserThemeProvider*>([[self window] themeProvider]); + ThemeService* themeProvider = + static_cast<ThemeService*>([[self window] themeProvider]); [context setPatternPhase:[[self window] themePatternPhase]]; NSRect rect = [self bounds]; @@ -715,21 +745,21 @@ const CGFloat kRapidCloseDist = 2.5; NSColor* borderColor = [NSColor colorWithDeviceWhite:0.0 alpha:borderAlpha]; NSColor* highlightColor = themeProvider ? themeProvider->GetNSColor( themeProvider->UsingDefaultTheme() ? - BrowserThemeProvider::COLOR_TOOLBAR_BEZEL : - BrowserThemeProvider::COLOR_TOOLBAR, true) : nil; + ThemeService::COLOR_TOOLBAR_BEZEL : + ThemeService::COLOR_TOOLBAR, true) : nil; // Draw the top inner highlight within the currently selected tab if using // the default theme. if (selected && themeProvider && themeProvider->UsingDefaultTheme()) { NSAffineTransform* highlightTransform = [NSAffineTransform transform]; - [highlightTransform translateXBy:1.0 yBy:-1.0]; + [highlightTransform translateXBy:lineWidth yBy:-lineWidth]; scoped_nsobject<NSBezierPath> highlightPath([path copy]); [highlightPath transformUsingAffineTransform:highlightTransform]; [highlightColor setStroke]; - [highlightPath setLineWidth:1.0]; + [highlightPath setLineWidth:lineWidth]; [highlightPath stroke]; highlightTransform = [NSAffineTransform transform]; - [highlightTransform translateXBy:-2.0 yBy:0.0]; + [highlightTransform translateXBy:-2 * lineWidth yBy:0.0]; [highlightPath transformUsingAffineTransform:highlightTransform]; [highlightPath stroke]; } @@ -739,7 +769,7 @@ const CGFloat kRapidCloseDist = 2.5; // Draw the top stroke. [context saveGraphicsState]; [borderColor set]; - [path setLineWidth:1.0]; + [path setLineWidth:lineWidth]; [path stroke]; [context restoreGraphicsState]; @@ -748,8 +778,8 @@ const CGFloat kRapidCloseDist = 2.5; if (!selected) { [path addClip]; NSRect borderRect = rect; - borderRect.origin.y = 1; - borderRect.size.height = 1; + borderRect.origin.y = lineWidth; + borderRect.size.height = lineWidth; [borderColor set]; NSRectFillUsingOperation(borderRect, NSCompositeSourceOver); @@ -827,7 +857,7 @@ const CGFloat kRapidCloseDist = 2.5; - (id)accessibilityAttributeValue:(NSString*)attribute { if ([attribute isEqual:NSAccessibilityRoleAttribute]) - return NSAccessibilityButtonRole; + return l10n_util::GetNSStringWithFixup(IDS_ACCNAME_TAB); if ([attribute isEqual:NSAccessibilityTitleAttribute]) return [controller_ title]; @@ -835,19 +865,6 @@ const CGFloat kRapidCloseDist = 2.5; if ([attribute isEqual:NSAccessibilityEnabledAttribute]) return [NSNumber numberWithBool:YES]; - if ([attribute isEqual:NSAccessibilityChildrenAttribute]) { - // The subviews (icon and text) are clutter; filter out everything but - // useful controls. - NSArray* children = [super accessibilityAttributeValue:attribute]; - NSMutableArray* okChildren = [NSMutableArray array]; - for (id child in children) { - if ([child isKindOfClass:[NSButtonCell class]]) - [okChildren addObject:child]; - } - - return okChildren; - } - return [super accessibilityAttributeValue:attribute]; } @@ -1004,14 +1021,17 @@ const CGFloat kRapidCloseDist = 2.5; // Returns the bezier path used to draw the tab given the bounds to draw it in. - (NSBezierPath*)bezierPathForRect:(NSRect)rect { - // Outset by 0.5 in order to draw on pixels rather than on borders (which - // would cause blurry pixels). Subtract 1px of height to compensate, otherwise - // clipping will occur. - rect = NSInsetRect(rect, -0.5, -0.5); - rect.size.height -= 1.0; - - NSPoint bottomLeft = NSMakePoint(NSMinX(rect), NSMinY(rect) + 2); - NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect) + 2); + const CGFloat lineWidth = [self cr_lineWidth]; + const CGFloat halfLineWidth = lineWidth / 2.0; + + // Outset by halfLineWidth in order to draw on pixels rather than on borders + // (which would cause blurry pixels). Subtract lineWidth of height to + // compensate, otherwise clipping will occur. + rect = NSInsetRect(rect, -halfLineWidth, -halfLineWidth); + rect.size.height -= lineWidth; + + NSPoint bottomLeft = NSMakePoint(NSMinX(rect), NSMinY(rect) + 2 * lineWidth); + NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect) + 2 * lineWidth); NSPoint topRight = NSMakePoint(NSMaxX(rect) - kInsetMultiplier * NSHeight(rect), NSMaxY(rect)); @@ -1022,11 +1042,12 @@ const CGFloat kRapidCloseDist = 2.5; CGFloat baseControlPointOutset = NSHeight(rect) * kControlPoint1Multiplier; CGFloat bottomControlPointInset = NSHeight(rect) * kControlPoint2Multiplier; - // Outset many of these values by 1 to cause the fill to bleed outside the - // clip area. + // Outset many of these values by lineWidth to cause the fill to bleed outside + // the clip area. NSBezierPath* path = [NSBezierPath bezierPath]; - [path moveToPoint:NSMakePoint(bottomLeft.x - 1, bottomLeft.y - 2)]; - [path lineToPoint:NSMakePoint(bottomLeft.x - 1, bottomLeft.y)]; + [path moveToPoint:NSMakePoint(bottomLeft.x - lineWidth, + bottomLeft.y - (2 * lineWidth))]; + [path lineToPoint:NSMakePoint(bottomLeft.x - lineWidth, bottomLeft.y)]; [path lineToPoint:bottomLeft]; [path curveToPoint:topLeft controlPoint1:NSMakePoint(bottomLeft.x + baseControlPointOutset, @@ -1039,8 +1060,9 @@ const CGFloat kRapidCloseDist = 2.5; topRight.y) controlPoint2:NSMakePoint(bottomRight.x - baseControlPointOutset, bottomRight.y)]; - [path lineToPoint:NSMakePoint(bottomRight.x + 1, bottomRight.y)]; - [path lineToPoint:NSMakePoint(bottomRight.x + 1, bottomRight.y - 2)]; + [path lineToPoint:NSMakePoint(bottomRight.x + lineWidth, bottomRight.y)]; + [path lineToPoint:NSMakePoint(bottomRight.x + lineWidth, + bottomRight.y - (2 * lineWidth))]; return path; } diff --git a/chrome/browser/ui/cocoa/tabs/tab_view_unittest.mm b/chrome/browser/ui/cocoa/tabs/tab_view_unittest.mm index 548dd0f..0ad09b9 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_view_unittest.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_view_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/tabs/tab_view.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/tabs/tab_window_controller.h b/chrome/browser/ui/cocoa/tabs/tab_window_controller.h index db4092e..27e0cd3 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_window_controller.h +++ b/chrome/browser/ui/cocoa/tabs/tab_window_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -29,7 +29,7 @@ #import <Cocoa/Cocoa.h> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" @class FastResizeView; @class FocusTracker; diff --git a/chrome/browser/ui/cocoa/tabs/throbber_view.h b/chrome/browser/ui/cocoa/tabs/throbber_view.h index 6cbd9f8..774fd0c 100644 --- a/chrome/browser/ui/cocoa/tabs/throbber_view.h +++ b/chrome/browser/ui/cocoa/tabs/throbber_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,7 +8,7 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" @protocol ThrobberDataDelegate; diff --git a/chrome/browser/ui/cocoa/tabs/throbber_view_unittest.mm b/chrome/browser/ui/cocoa/tabs/throbber_view_unittest.mm index 35c3511..5419e5d 100644 --- a/chrome/browser/ui/cocoa/tabs/throbber_view_unittest.mm +++ b/chrome/browser/ui/cocoa/tabs/throbber_view_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/tabs/throbber_view.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "grit/app_resources.h" diff --git a/chrome/browser/ui/cocoa/task_manager_mac.h b/chrome/browser/ui/cocoa/task_manager_mac.h index 211a86d..b0518d6 100644 --- a/chrome/browser/ui/cocoa/task_manager_mac.h +++ b/chrome/browser/ui/cocoa/task_manager_mac.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -10,7 +10,7 @@ #include <vector> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/browser/task_manager/task_manager.h" #include "chrome/browser/ui/cocoa/table_row_nsimage_cache.h" diff --git a/chrome/browser/ui/cocoa/task_manager_mac_unittest.mm b/chrome/browser/ui/cocoa/task_manager_mac_unittest.mm index f5d9b2a..753d6f1 100644 --- a/chrome/browser/ui/cocoa/task_manager_mac_unittest.mm +++ b/chrome/browser/ui/cocoa/task_manager_mac_unittest.mm @@ -5,7 +5,7 @@ #import <Cocoa/Cocoa.h> #include "base/compiler_specific.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "base/utf_string_conversions.h" #import "chrome/browser/ui/cocoa/task_manager_mac.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" diff --git a/chrome/browser/ui/cocoa/theme_install_bubble_view.h b/chrome/browser/ui/cocoa/theme_install_bubble_view.h index f2a8a4a..f933d2d 100644 --- a/chrome/browser/ui/cocoa/theme_install_bubble_view.h +++ b/chrome/browser/ui/cocoa/theme_install_bubble_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -6,8 +6,8 @@ #define CHROME_BROWSER_UI_COCOA_THEME_INSTALL_BUBBLE_VIEW_H_ #pragma once -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" +#include "content/common/notification_observer.h" +#include "content/common/notification_registrar.h" @class NSWindow; @class ThemeInstallBubbleViewCocoa; diff --git a/chrome/browser/ui/cocoa/theme_install_bubble_view.mm b/chrome/browser/ui/cocoa/theme_install_bubble_view.mm index 076aabd..753f3c6 100644 --- a/chrome/browser/ui/cocoa/theme_install_bubble_view.mm +++ b/chrome/browser/ui/cocoa/theme_install_bubble_view.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -6,8 +6,8 @@ #import "chrome/browser/ui/cocoa/theme_install_bubble_view.h" -#include "base/scoped_nsobject.h" -#include "chrome/common/notification_service.h" +#include "base/memory/scoped_nsobject.h" +#include "content/common/notification_service.h" #include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util_mac.h" diff --git a/chrome/browser/ui/cocoa/toolbar/back_forward_menu_controller.h b/chrome/browser/ui/cocoa/toolbar/back_forward_menu_controller.h index 4a978b5..a72304b 100644 --- a/chrome/browser/ui/cocoa/toolbar/back_forward_menu_controller.h +++ b/chrome/browser/ui/cocoa/toolbar/back_forward_menu_controller.h @@ -8,8 +8,8 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/ui/toolbar/back_forward_menu_model.h" @class MenuButton; diff --git a/chrome/browser/ui/cocoa/toolbar/back_forward_menu_controller.mm b/chrome/browser/ui/cocoa/toolbar/back_forward_menu_controller.mm index 63bab2a..d64637f 100644 --- a/chrome/browser/ui/cocoa/toolbar/back_forward_menu_controller.mm +++ b/chrome/browser/ui/cocoa/toolbar/back_forward_menu_controller.mm @@ -5,7 +5,7 @@ #import "chrome/browser/ui/cocoa/toolbar/back_forward_menu_controller.h" #include "base/logging.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_ptr.h" #include "base/sys_string_conversions.h" #import "chrome/browser/ui/cocoa/event_utils.h" #import "chrome/browser/ui/cocoa/menu_button.h" diff --git a/chrome/browser/ui/cocoa/toolbar/reload_button.h b/chrome/browser/ui/cocoa/toolbar/reload_button.h index e42e58c..6bcebcd 100644 --- a/chrome/browser/ui/cocoa/toolbar/reload_button.h +++ b/chrome/browser/ui/cocoa/toolbar/reload_button.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,12 +8,13 @@ #import <Cocoa/Cocoa.h> -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" +#import "chrome/browser/ui/cocoa/toolbar/toolbar_button.h" -// NSButton subclass which defers certain state changes when the mouse +// ToolbarButton subclass which defers certain state changes when the mouse // is hovering over it. -@interface ReloadButton : NSButton { +@interface ReloadButton : ToolbarButton { @private // Tracks whether the mouse is hovering for purposes of not making // unexpected state changes. diff --git a/chrome/browser/ui/cocoa/toolbar/reload_button_unittest.mm b/chrome/browser/ui/cocoa/toolbar/reload_button_unittest.mm index a7f7dd1..4a46107 100644 --- a/chrome/browser/ui/cocoa/toolbar/reload_button_unittest.mm +++ b/chrome/browser/ui/cocoa/toolbar/reload_button_unittest.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -6,7 +6,7 @@ #import "chrome/browser/ui/cocoa/toolbar/reload_button.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/app/chrome_command_ids.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/test_event_utils.h" diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_button.h b/chrome/browser/ui/cocoa/toolbar/toolbar_button.h new file mode 100644 index 0000000..c35d1e5 --- /dev/null +++ b/chrome/browser/ui/cocoa/toolbar/toolbar_button.h @@ -0,0 +1,33 @@ +// Copyright (c) 2011 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_UI_COCOA_TOOLBAR_TOOLBAR_BUTTON_H_ +#define CHROME_BROWSER_UI_COCOA_TOOLBAR_TOOLBAR_BUTTON_H_ +#pragma once + +#import <Cocoa/Cocoa.h> + +// NSButton subclass which handles middle mouse clicking. + +@interface ToolbarButton : NSButton { + @protected + // YES when middle mouse clicks should be handled. + BOOL handleMiddleClick_; + + // YES when a middle mouse click is being handled. This is set to YES by an + // NSOtherMouseDown event, and NO by an NSOtherMouseUp event. While this is + // YES, other mouse button events should be ignored. + BOOL handlingMiddleClick_; +} + +// Whether or not to handle the mouse middle click events. +@property(assign, nonatomic) BOOL handleMiddleClick; + +@end + +@interface ToolbarButton (ExposedForTesting) +- (BOOL)shouldHandleEvent:(NSEvent*)theEvent; +@end + +#endif // CHROME_BROWSER_UI_COCOA_TOOLBAR_TOOLBAR_BUTTON_H_ diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_button.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_button.mm new file mode 100644 index 0000000..517e6e5 --- /dev/null +++ b/chrome/browser/ui/cocoa/toolbar/toolbar_button.mm @@ -0,0 +1,72 @@ +// Copyright (c) 2011 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/ui/cocoa/toolbar/toolbar_button.h" + +@interface ToolbarButton (Private) +- (BOOL)updateStatus:(NSEvent*)theEvent; +@end + +@implementation ToolbarButton + +@synthesize handleMiddleClick = handleMiddleClick_; + +- (void)mouseDown:(NSEvent*)theEvent { + if (!handlingMiddleClick_) + [super mouseDown:theEvent]; +} + +- (void)mouseDragged:(NSEvent*)theEvent { + if (!handlingMiddleClick_) + [super mouseDragged:theEvent]; +} + +- (void)mouseUp:(NSEvent*)theEvent { + if (!handlingMiddleClick_) + [super mouseUp:theEvent]; +} + +- (void)otherMouseDown:(NSEvent*)theEvent { + if (![self shouldHandleEvent:theEvent]) + [super otherMouseDown:theEvent]; + else + handlingMiddleClick_ = [self updateStatus:theEvent]; +} + +- (void)otherMouseDragged:(NSEvent*)theEvent { + if (!handlingMiddleClick_ || ![self shouldHandleEvent:theEvent]) + [super otherMouseDragged:theEvent]; + else + [self updateStatus:theEvent]; +} + +- (void)otherMouseUp:(NSEvent*)theEvent { + if (!handlingMiddleClick_ || ![self shouldHandleEvent:theEvent]) { + [super otherMouseUp:theEvent]; + } else { + if ([self state] == NSOnState) + [self sendAction:[self action] to:[self target]]; + + [self setState:NSOffState]; + [self highlight:NO]; + handlingMiddleClick_ = NO; + } +} + +- (BOOL)updateStatus:(NSEvent*)theEvent { + NSPoint mouseLoc = [self convertPoint:[theEvent locationInWindow] + fromView:nil]; + BOOL isInside = [self mouse:mouseLoc inRect:[self bounds]]; + [self setState:isInside ? NSOnState : NSOffState]; + [self highlight:isInside]; + return isInside; +} + +- (BOOL)shouldHandleEvent:(NSEvent*)theEvent { + // |buttonNumber| is the mouse button whose action triggered theEvent. + // 2 corresponds to the middle mouse button. + return handleMiddleClick_ && [theEvent buttonNumber] == 2; +} + +@end diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_button_unittest.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_button_unittest.mm new file mode 100644 index 0000000..3322267 --- /dev/null +++ b/chrome/browser/ui/cocoa/toolbar/toolbar_button_unittest.mm @@ -0,0 +1,302 @@ +// Copyright (c) 2011 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> + +#import "base/memory/scoped_nsobject.h" +#include "chrome/app/chrome_command_ids.h" +#import "chrome/browser/ui/cocoa/cocoa_test_helper.h" +#import "chrome/browser/ui/cocoa/test_event_utils.h" +#import "chrome/browser/ui/cocoa/toolbar/toolbar_button.h" +#import "testing/gtest_mac.h" + +@interface TestableToolbarButton : ToolbarButton { + @private + NSInteger numOfClick_; + NSInteger lastCommand_; +} + +@property(assign, nonatomic) NSInteger numOfClick; +@property(assign, nonatomic) NSInteger lastCommand; + +- (id)initWithFrame:(NSRect)frame; +- (void)doAction:(id)sender; +@end + +@implementation TestableToolbarButton + +@synthesize numOfClick = numOfClick_; +@synthesize lastCommand = lastCommand_; + +- (id)initWithFrame:(NSRect)frame { + if ((self = [super initWithFrame:frame])) { + lastCommand_ = IDC_STOP; + } + return self; +} + +- (void)doAction:(id)sender { + lastCommand_ = [sender tag]; + if (lastCommand_ == [self tag]) + ++numOfClick_; +} + +- (BOOL)shouldHandleEvent:(NSEvent*)theEvent { + return handleMiddleClick_; +} + +@end + +namespace { + +class ToolbarButtonTest : public CocoaTest { + public: + ToolbarButtonTest() { + NSRect frame = NSMakeRect(0, 0, 20, 20); + scoped_nsobject<TestableToolbarButton> button( + [[TestableToolbarButton alloc] initWithFrame:frame]); + button_ = button.get(); + + [button_ setTag:IDC_HOME]; + [button_ setTarget:button_]; + [button_ setAction:@selector(doAction:)]; + [[test_window() contentView] addSubview:button_]; + + NSRect bounds = [button_ bounds]; + NSPoint mid_point = NSMakePoint(NSMidX(bounds), NSMidY(bounds)); + NSPoint out_point = NSMakePoint(bounds.origin.x - 10, + bounds.origin.y - 10); + left_down_in_view = + test_event_utils::MouseEventAtPoint(mid_point, NSLeftMouseDown, 0); + left_up_in_view = + test_event_utils::MouseEventAtPoint(mid_point, NSLeftMouseUp, 0); + right_down_in_view = + test_event_utils::MouseEventAtPoint(mid_point, NSRightMouseDown, 0); + right_up_in_view = + test_event_utils::MouseEventAtPoint(mid_point, NSRightMouseUp, 0); + other_down_in_view = + test_event_utils::MouseEventAtPoint(mid_point, NSOtherMouseDown, 0); + other_dragged_in_view = + test_event_utils::MouseEventAtPoint(mid_point, NSOtherMouseDragged, 0); + other_up_in_view = + test_event_utils::MouseEventAtPoint(mid_point, NSOtherMouseUp, 0); + other_down_out_view = + test_event_utils::MouseEventAtPoint(out_point, NSOtherMouseDown, 0); + other_dragged_out_view = + test_event_utils::MouseEventAtPoint(out_point, NSOtherMouseDragged, 0); + other_up_out_view = + test_event_utils::MouseEventAtPoint(out_point, NSOtherMouseUp, 0); + } + + TestableToolbarButton* button_; + NSEvent* left_down_in_view; + NSEvent* left_up_in_view; + NSEvent* right_down_in_view; + NSEvent* right_up_in_view; + NSEvent* other_down_in_view; + NSEvent* other_dragged_in_view; + NSEvent* other_up_in_view; + NSEvent* other_down_out_view; + NSEvent* other_dragged_out_view; + NSEvent* other_up_out_view; +}; + +TEST_VIEW(ToolbarButtonTest, button_) + +TEST_F(ToolbarButtonTest, DoesNotSwallowClicksOnNO) { + // Middle button being down doesn't swallow right button clicks. But + // ToolbarButton doesn't handle right button events. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ rightMouseDown:right_down_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ rightMouseUp:right_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); + + // Middle button being down doesn't swallows left button clicks. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [NSApp postEvent:left_up_in_view atStart:YES]; + [button_ mouseDown:left_down_in_view]; + EXPECT_EQ(1, [button_ numOfClick]); + EXPECT_EQ(IDC_HOME, [button_ lastCommand]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(1, [button_ numOfClick]); + EXPECT_EQ(IDC_HOME, [button_ lastCommand]); +} + +TEST_F(ToolbarButtonTest, WithoutMouseDownOnNO) { + // Middle button mouse up without leading mouse down in the view. + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); + + // Middle button mouse dragged in the view and up without leading mouse down. + [button_ otherMouseDragged:other_dragged_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); +} + +TEST_F(ToolbarButtonTest, MouseClickOnNO) { + // Middle button clicking in the view. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); + + // Middle button clicking outside of the view. + [button_ otherMouseDown:other_down_out_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseUp:other_up_out_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); +} + +TEST_F(ToolbarButtonTest, MouseDraggingOnNO) { + // Middle button being down in the view and up outside of the view. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseDragged:other_dragged_out_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseUp:other_up_out_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); + + // Middle button being down on the button, move to outside and move on it + // again, then up on the button. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseDragged:other_dragged_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); +} + +TEST_F(ToolbarButtonTest, WithoutMouseDownOnYES) { + // Enable middle button handling. + [button_ setHandleMiddleClick:YES]; + + // Middle button mouse up without leading mouse down in the view. + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); + + // Middle button mouse dragged in the view and up without leading mouse down. + [button_ otherMouseDragged:other_dragged_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); +} + +TEST_F(ToolbarButtonTest, MouseClickInsideOnYES) { + // Enable middle button handling. + [button_ setHandleMiddleClick:YES]; + + // Middle button clicking in the view. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOnState, [button_ state]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(1, [button_ numOfClick]); + EXPECT_EQ(IDC_HOME, [button_ lastCommand]); +} + +TEST_F(ToolbarButtonTest, MouseClickOutsideOnYES) { + // Enable middle button handling. + [button_ setHandleMiddleClick:YES]; + + // Middle button clicking outside of the view. + [button_ otherMouseDown:other_down_out_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseUp:other_up_out_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); +} + +TEST_F(ToolbarButtonTest, MouseDraggingOnYES) { + // Enable middle button handling. + [button_ setHandleMiddleClick:YES]; + + // Middle button being down in the view and up outside of the view. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOnState, [button_ state]); + [button_ otherMouseDragged:other_dragged_out_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseUp:other_up_out_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); + + // Middle button being down on the button, move to outside and move on it + // again, then up on the button. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOnState, [button_ state]); + [button_ otherMouseDragged:other_dragged_out_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseDragged:other_dragged_in_view]; + EXPECT_EQ(NSOnState, [button_ state]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(1, [button_ numOfClick]); + EXPECT_EQ(IDC_HOME, [button_ lastCommand]); +} + +TEST_F(ToolbarButtonTest, DoesNotSwallowRightClickOnYES) { + // Enable middle button handling. + [button_ setHandleMiddleClick:YES]; + + // Middle button being down should swallow right button clicks, but + // ToolbarButton doesn't swallow it because it doesn't handle right button + // events. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOnState, [button_ state]); + [button_ rightMouseDown:right_down_in_view]; + EXPECT_EQ(NSOnState, [button_ state]); + [button_ rightMouseUp:right_up_in_view]; + EXPECT_EQ(NSOnState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(1, [button_ numOfClick]); + EXPECT_EQ(IDC_HOME, [button_ lastCommand]); +} + +TEST_F(ToolbarButtonTest, DoesSwallowLeftClickOnYES) { + // Enable middle button handling. + [button_ setHandleMiddleClick:YES]; + + // Middle button being down swallows left button clicks. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOnState, [button_ state]); + [NSApp postEvent:left_up_in_view atStart:YES]; + [button_ mouseDown:left_down_in_view]; + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(1, [button_ numOfClick]); + EXPECT_EQ(IDC_HOME, [button_ lastCommand]); +} + +} // namespace diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h index 1e48658..a9c6a5e 100644 --- a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h +++ b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h @@ -8,8 +8,8 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_ptr.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #import "chrome/browser/ui/cocoa/command_observer_bridge.h" #import "chrome/browser/ui/cocoa/tracking_area.h" #import "chrome/browser/ui/cocoa/url_drop_target.h" @@ -26,6 +26,7 @@ class CommandUpdater; class LocationBar; class LocationBarViewMac; @class MenuButton; +@class ToolbarButton; namespace ToolbarControllerInternal { class NotificationBridge; class WrenchAcceleratorDelegate; @@ -51,7 +52,7 @@ class WrenchMenuModel; IBOutlet MenuButton* backButton_; IBOutlet MenuButton* forwardButton_; IBOutlet ReloadButton* reloadButton_; - IBOutlet NSButton* homeButton_; + IBOutlet ToolbarButton* homeButton_; IBOutlet MenuButton* wrenchButton_; IBOutlet AutocompleteTextField* locationBar_; IBOutlet BrowserActionsContainerView* browserActionsContainerView_; @@ -80,7 +81,6 @@ class WrenchMenuModel; // Used for monitoring the optional toolbar button prefs. scoped_ptr<ToolbarControllerInternal::NotificationBridge> notificationBridge_; BooleanPrefMember showHomeButton_; - BooleanPrefMember showPageOptionButtons_; BOOL hasToolbar_; // If NO, we may have only the location bar. BOOL hasLocationBar_; // If |hasToolbar_| is YES, this must also be YES. BOOL locationBarAtMinSize_; // If the location bar is at the minimum size. diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm index 5828094..c681b9b 100644 --- a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm +++ b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm @@ -6,10 +6,9 @@ #include <algorithm> -#include "ui/base/l10n/l10n_util.h" #include "app/mac/nsimage_cache.h" #include "base/mac/mac_util.h" -#include "base/singleton.h" +#include "base/memory/singleton.h" #include "base/sys_string_conversions.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/autocomplete/autocomplete.h" @@ -20,8 +19,7 @@ #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search_engines/template_url_model.h" -#include "chrome/browser/themes/browser_theme_provider.h" -#include "chrome/browser/upgrade_detector.h" +#include "chrome/browser/themes/theme_service.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #import "chrome/browser/ui/cocoa/accelerators_cocoa.h" @@ -37,26 +35,29 @@ #import "chrome/browser/ui/cocoa/menu_controller.h" #import "chrome/browser/ui/cocoa/toolbar/back_forward_menu_controller.h" #import "chrome/browser/ui/cocoa/toolbar/reload_button.h" +#import "chrome/browser/ui/cocoa/toolbar/toolbar_button.h" #import "chrome/browser/ui/cocoa/toolbar/toolbar_view.h" #import "chrome/browser/ui/cocoa/view_id_util.h" #import "chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller.h" #include "chrome/browser/ui/toolbar/toolbar_model.h" #include "chrome/browser/ui/toolbar/wrench_menu_model.h" -#include "chrome/common/notification_details.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/notification_type.h" +#include "chrome/browser/upgrade_detector.h" #include "chrome/common/pref_names.h" #include "content/browser/tab_contents/tab_contents.h" +#include "content/common/notification_details.h" +#include "content/common/notification_observer.h" +#include "content/common/notification_service.h" +#include "content/common/notification_type.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_mac.h" #include "ui/base/models/accelerator_cocoa.h" #include "ui/base/models/menu_model.h" #include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/rect.h" #include "ui/gfx/image.h" +#include "ui/gfx/rect.h" namespace { @@ -249,6 +250,11 @@ class NotificationBridge : public NotificationObserver { [homeButton_ setShowsBorderOnlyWhileMouseInside:YES]; [wrenchButton_ setShowsBorderOnlyWhileMouseInside:YES]; + [backButton_ setHandleMiddleClick:YES]; + [forwardButton_ setHandleMiddleClick:YES]; + [reloadButton_ setHandleMiddleClick:YES]; + [homeButton_ setHandleMiddleClick:YES]; + [self initCommandStatus:commands_]; locationBarView_.reset(new LocationBarViewMac(locationBar_, commands_, toolbarModel_, @@ -261,8 +267,6 @@ class NotificationBridge : public NotificationObserver { PrefService* prefs = profile_->GetPrefs(); showHomeButton_.Init(prefs::kShowHomeButton, prefs, notificationBridge_.get()); - showPageOptionButtons_.Init(prefs::kShowPageOptionsButtons, prefs, - notificationBridge_.get()); [self showOptionalHomeButton]; [self installWrenchMenu]; diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_controller_unittest.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_controller_unittest.mm index 1b778d9..efdbb76 100644 --- a/chrome/browser/ui/cocoa/toolbar/toolbar_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/toolbar/toolbar_controller_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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> -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/ui/cocoa/browser_test_helper.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_view_unittest.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_view_unittest.mm index 34994d8..f6bb035 100644 --- a/chrome/browser/ui/cocoa/toolbar/toolbar_view_unittest.mm +++ b/chrome/browser/ui/cocoa/toolbar/toolbar_view_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/toolbar/toolbar_view.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/tracking_area.h b/chrome/browser/ui/cocoa/tracking_area.h index f63be3a..b044e4d 100644 --- a/chrome/browser/ui/cocoa/tracking_area.h +++ b/chrome/browser/ui/cocoa/tracking_area.h @@ -7,7 +7,7 @@ #import <AppKit/AppKit.h> -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" @class CrTrackingAreaOwnerProxy; @@ -52,6 +52,7 @@ class ScopedCrTrackingArea { ~ScopedCrTrackingArea(); // This will call |scoped_nsobject<>::reset()| to take ownership of the new + // tracking area. Note that -clearOwner is NOT called on the existing // tracking area. void reset(CrTrackingArea* tracking_area = nil); diff --git a/chrome/browser/ui/cocoa/tracking_area_unittest.mm b/chrome/browser/ui/cocoa/tracking_area_unittest.mm index a812f46..a3ebae8 100644 --- a/chrome/browser/ui/cocoa/tracking_area_unittest.mm +++ b/chrome/browser/ui/cocoa/tracking_area_unittest.mm @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "chrome/browser/ui/cocoa/objc_zombie.h" #import "chrome/browser/ui/cocoa/tracking_area.h" diff --git a/chrome/browser/ui/cocoa/translate/translate_infobar_base.h b/chrome/browser/ui/cocoa/translate/translate_infobar_base.h index 66612eb..bd51124 100644 --- a/chrome/browser/ui/cocoa/translate/translate_infobar_base.h +++ b/chrome/browser/ui/cocoa/translate/translate_infobar_base.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -10,8 +10,8 @@ #import "chrome/browser/ui/cocoa/infobars/infobar_controller.h" #import "base/mac/cocoa_protocols.h" -#import "base/scoped_nsobject.h" -#include "base/scoped_ptr.h" +#import "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/translate/languages_menu_model.h" #include "chrome/browser/translate/options_menu_model.h" #include "chrome/browser/translate/translate_infobar_delegate.h" diff --git a/chrome/browser/ui/cocoa/translate/translate_infobar_base.mm b/chrome/browser/ui/cocoa/translate/translate_infobar_base.mm index 5cac0a9..a13174c 100644 --- a/chrome/browser/ui/cocoa/translate/translate_infobar_base.mm +++ b/chrome/browser/ui/cocoa/translate/translate_infobar_base.mm @@ -70,7 +70,7 @@ void VerticallyCenterView(NSView* toMove) { // rather than in the total height (which includes the bulge). CGFloat superHeight = NSHeight(superViewFrame); if ([[toMove superview] isKindOfClass:[InfoBarGradientView class]]) - superHeight -= infobars::kAntiSpoofHeight; + superHeight = infobars::kBaseHeight; viewFrame.origin.y = floor((superHeight - NSHeight(viewFrame)) / 2.0); [toMove setFrame:viewFrame]; @@ -287,8 +287,7 @@ InfoBar* TranslateInfoBarDelegate::CreateInfoBar() { NSRect optionsFrame = [optionsPopUp_ frame]; for (NSControl* control in visibleControls) { [GTMUILocalizerAndLayoutTweaker sizeToFitView:control]; - [control setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin | - NSViewMaxYMargin]; + [control setAutoresizingMask:NSViewMaxXMargin]; // Need to check if a view is already attached since |label1_| is always // parented and we don't want to add it again. @@ -463,8 +462,7 @@ InfoBar* TranslateInfoBarDelegate::CreateInfoBar() { setTitle:GetNSStringWithFixup(IDS_TRANSLATE_INFOBAR_REVERT)]; // Add and configure controls that are visible in all modes. - [optionsPopUp_ setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin | - NSViewMaxYMargin]; + [optionsPopUp_ setAutoresizingMask:NSViewMinXMargin]; // Add "options" popup z-ordered below all other controls so when we // resize the toolbar it doesn't hide them. [infoBarView_ addSubview:optionsPopUp_ diff --git a/chrome/browser/ui/cocoa/translate/translate_infobar_unittest.mm b/chrome/browser/ui/cocoa/translate/translate_infobar_unittest.mm index 3580973..09ad581 100644 --- a/chrome/browser/ui/cocoa/translate/translate_infobar_unittest.mm +++ b/chrome/browser/ui/cocoa/translate/translate_infobar_unittest.mm @@ -4,7 +4,7 @@ #import <Cocoa/Cocoa.h> -#import "base/scoped_nsobject.h" +#import "base/memory/scoped_nsobject.h" #import "base/string_util.h" #include "base/utf_string_conversions.h" #import "chrome/app/chrome_command_ids.h" // For translate menu command ids. diff --git a/chrome/browser/ui/cocoa/vertical_gradient_view.h b/chrome/browser/ui/cocoa/vertical_gradient_view.h index 98a3a2b..2cce1be 100644 --- a/chrome/browser/ui/cocoa/vertical_gradient_view.h +++ b/chrome/browser/ui/cocoa/vertical_gradient_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -6,7 +6,7 @@ #define CHROME_BROWSER_UI_COCOA_VERTICAL_GRADIENT_VIEW_H_ #pragma once -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import <Cocoa/Cocoa.h> diff --git a/chrome/browser/ui/cocoa/vertical_gradient_view_unittest.mm b/chrome/browser/ui/cocoa/vertical_gradient_view_unittest.mm index e574a69..ac046b0 100644 --- a/chrome/browser/ui/cocoa/vertical_gradient_view_unittest.mm +++ b/chrome/browser/ui/cocoa/vertical_gradient_view_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/vertical_gradient_view.h" diff --git a/chrome/browser/ui/cocoa/window_size_autosaver.mm b/chrome/browser/ui/cocoa/window_size_autosaver.mm index 5ca9878..267a830 100644 --- a/chrome/browser/ui/cocoa/window_size_autosaver.mm +++ b/chrome/browser/ui/cocoa/window_size_autosaver.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -7,6 +7,7 @@ #import "chrome/browser/ui/cocoa/window_size_autosaver.h" #include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/prefs/scoped_user_pref_update.h" // If the window width stored in the prefs is smaller than this, the size is // not restored but instead cleared from the profile -- to protect users from @@ -52,7 +53,8 @@ const int kMinWindowHeight = 17; } - (void)save:(NSNotification*)notification { - DictionaryValue* windowPrefs = prefService_->GetMutableDictionary(path_); + DictionaryPrefUpdate update(prefService_, path_); + DictionaryValue* windowPrefs = update.Get(); NSRect frame = [window_ frame]; if ([window_ styleMask] & NSResizableWindowMask) { // Save the origin of the window. @@ -72,7 +74,7 @@ const int kMinWindowHeight = 17; - (void)restore { // Get the positioning information. - DictionaryValue* windowPrefs = prefService_->GetMutableDictionary(path_); + const DictionaryValue* windowPrefs = prefService_->GetDictionary(path_); if ([window_ styleMask] & NSResizableWindowMask) { int x1, x2, y1, y2; if (!windowPrefs->GetInteger("left", &x1) || @@ -83,10 +85,12 @@ const int kMinWindowHeight = 17; } if (x2 - x1 < kMinWindowWidth || y2 - y1 < kMinWindowHeight) { // Windows should never be very small. - windowPrefs->Remove("left", NULL); - windowPrefs->Remove("right", NULL); - windowPrefs->Remove("top", NULL); - windowPrefs->Remove("bottom", NULL); + DictionaryPrefUpdate update(prefService_, path_); + DictionaryValue* mutableWindowPrefs = update.Get(); + mutableWindowPrefs->Remove("left", NULL); + mutableWindowPrefs->Remove("right", NULL); + mutableWindowPrefs->Remove("top", NULL); + mutableWindowPrefs->Remove("bottom", NULL); } else { [window_ setFrame:NSMakeRect(x1, y1, x2 - x1, y2 - y1) display:YES]; diff --git a/chrome/browser/ui/cocoa/window_size_autosaver_unittest.mm b/chrome/browser/ui/cocoa/window_size_autosaver_unittest.mm index 3b95440..7b93717 100644 --- a/chrome/browser/ui/cocoa/window_size_autosaver_unittest.mm +++ b/chrome/browser/ui/cocoa/window_size_autosaver_unittest.mm @@ -6,8 +6,9 @@ #import "chrome/browser/ui/cocoa/window_size_autosaver.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/prefs/scoped_user_pref_update.h" #include "chrome/browser/ui/cocoa/browser_test_helper.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" @@ -95,7 +96,7 @@ TEST_F(WindowSizeAutosaverTest, RestoresAndSavesPos) { // ...and it should be in the profile, too. EXPECT_TRUE(pref->GetDictionary(path_) != NULL); int x, y; - DictionaryValue* windowPref = pref->GetMutableDictionary(path_); + const DictionaryValue* windowPref = pref->GetDictionary(path_); EXPECT_FALSE(windowPref->GetInteger("left", &x)); EXPECT_FALSE(windowPref->GetInteger("right", &x)); EXPECT_FALSE(windowPref->GetInteger("top", &x)); @@ -154,7 +155,7 @@ TEST_F(WindowSizeAutosaverTest, RestoresAndSavesRect) { // ...and it should be in the profile, too. EXPECT_TRUE(pref->GetDictionary(path_) != NULL); int x1, y1, x2, y2; - DictionaryValue* windowPref = pref->GetMutableDictionary(path_); + const DictionaryValue* windowPref = pref->GetDictionary(path_); EXPECT_FALSE(windowPref->GetInteger("x", &x1)); EXPECT_FALSE(windowPref->GetInteger("y", &x1)); ASSERT_TRUE(windowPref->GetInteger("left", &x1)); @@ -172,7 +173,8 @@ TEST_F(WindowSizeAutosaverTest, DoesNotRestoreButClearsEmptyRect) { PrefService* pref = browser_helper_.profile()->GetPrefs(); ASSERT_TRUE(pref != NULL); - DictionaryValue* windowPref = pref->GetMutableDictionary(path_); + DictionaryPrefUpdate update(pref, path_); + DictionaryValue* windowPref = update.Get(); windowPref->SetInteger("left", 50); windowPref->SetInteger("right", 50); windowPref->SetInteger("top", 60); diff --git a/chrome/browser/ui/cocoa/wrench_menu/menu_tracked_button_unittest.mm b/chrome/browser/ui/cocoa/wrench_menu/menu_tracked_button_unittest.mm index 16a529a..7b3e511 100644 --- a/chrome/browser/ui/cocoa/wrench_menu/menu_tracked_button_unittest.mm +++ b/chrome/browser/ui/cocoa/wrench_menu/menu_tracked_button_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/wrench_menu/menu_tracked_button.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/wrench_menu/menu_tracked_root_view_unittest.mm b/chrome/browser/ui/cocoa/wrench_menu/menu_tracked_root_view_unittest.mm index a853824..99932b9 100644 --- a/chrome/browser/ui/cocoa/wrench_menu/menu_tracked_root_view_unittest.mm +++ b/chrome/browser/ui/cocoa/wrench_menu/menu_tracked_root_view_unittest.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/wrench_menu/menu_tracked_root_view.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_button_cell.mm b/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_button_cell.mm index d042989..ebc8e83 100644 --- a/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_button_cell.mm +++ b/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_button_cell.mm @@ -1,10 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/ui/cocoa/wrench_menu/wrench_menu_button_cell.h" -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" @implementation WrenchMenuButtonCell diff --git a/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_button_cell_unittest.mm b/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_button_cell_unittest.mm index fc9e403..ae57132 100644 --- a/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_button_cell_unittest.mm +++ b/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_button_cell_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/app/chrome_command_ids.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/wrench_menu/wrench_menu_button_cell.h" diff --git a/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller.h b/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller.h index ec68120..b1051a2 100644 --- a/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller.h +++ b/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,7 +9,7 @@ #import <Cocoa/Cocoa.h> #import "base/mac/cocoa_protocols.h" -#include "base/scoped_ptr.h" +#include "base/memory/scoped_ptr.h" #import "chrome/browser/ui/cocoa/menu_controller.h" @class MenuTrackedRootView; diff --git a/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller.mm b/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller.mm index 6c946ab..0fd9c07 100644 --- a/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller.mm +++ b/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller.mm @@ -7,15 +7,15 @@ #include "base/sys_string_conversions.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/metrics/user_metrics.h" -#import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" -#import "chrome/browser/ui/cocoa/wrench_menu/menu_tracked_root_view.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" +#import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" +#import "chrome/browser/ui/cocoa/wrench_menu/menu_tracked_root_view.h" #include "chrome/browser/ui/toolbar/wrench_menu_model.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/notification_source.h" -#include "chrome/common/notification_type.h" +#include "content/common/notification_observer.h" +#include "content/common/notification_service.h" +#include "content/common/notification_source.h" +#include "content/common/notification_type.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" diff --git a/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller_unittest.mm b/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller_unittest.mm index 62a2475..3451179 100644 --- a/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller_unittest.mm @@ -1,8 +1,8 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. -#include "base/scoped_nsobject.h" +#include "base/memory/scoped_nsobject.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/ui/cocoa/browser_test_helper.h" #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" |