Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "chrome/browser/app_controller_mac.h" | 5 #import "chrome/browser/app_controller_mac.h" |
| 6 | 6 |
| 7 #include "app/l10n_util.h" | |
| 7 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/mac_util.h" | |
| 8 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| 9 #include "base/sys_string_conversions.h" | 11 #include "base/sys_string_conversions.h" |
| 10 #include "chrome/app/chrome_dll_resource.h" | 12 #include "chrome/app/chrome_dll_resource.h" |
| 11 #include "chrome/browser/browser.h" | 13 #include "chrome/browser/browser.h" |
| 12 #include "chrome/browser/browser_init.h" | 14 #include "chrome/browser/browser_init.h" |
| 13 #include "chrome/browser/browser_list.h" | 15 #include "chrome/browser/browser_list.h" |
| 14 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
| 15 #include "chrome/browser/browser_shutdown.h" | 17 #include "chrome/browser/browser_shutdown.h" |
| 16 #include "chrome/browser/browser_window.h" | 18 #include "chrome/browser/browser_window.h" |
| 17 #import "chrome/browser/cocoa/about_window_controller.h" | 19 #import "chrome/browser/cocoa/about_window_controller.h" |
| 18 #import "chrome/browser/cocoa/bookmark_menu_bridge.h" | 20 #import "chrome/browser/cocoa/bookmark_menu_bridge.h" |
| 19 #import "chrome/browser/cocoa/history_menu_bridge.h" | 21 #import "chrome/browser/cocoa/history_menu_bridge.h" |
| 20 #import "chrome/browser/cocoa/clear_browsing_data_controller.h" | 22 #import "chrome/browser/cocoa/clear_browsing_data_controller.h" |
| 21 #import "chrome/browser/cocoa/encoding_menu_controller_delegate_mac.h" | 23 #import "chrome/browser/cocoa/encoding_menu_controller_delegate_mac.h" |
| 22 #import "chrome/browser/cocoa/preferences_window_controller.h" | 24 #import "chrome/browser/cocoa/preferences_window_controller.h" |
| 23 #import "chrome/browser/cocoa/tab_strip_controller.h" | 25 #import "chrome/browser/cocoa/tab_strip_controller.h" |
| 24 #import "chrome/browser/cocoa/tab_window_controller.h" | 26 #import "chrome/browser/cocoa/tab_window_controller.h" |
| 25 #include "chrome/browser/command_updater.h" | 27 #include "chrome/browser/command_updater.h" |
| 28 #include "chrome/browser/download/download_manager.h" | |
| 26 #include "chrome/browser/sessions/tab_restore_service.h" | 29 #include "chrome/browser/sessions/tab_restore_service.h" |
| 27 #include "chrome/common/pref_names.h" | 30 #include "chrome/common/pref_names.h" |
| 28 #include "chrome/common/pref_service.h" | 31 #include "chrome/common/pref_service.h" |
| 29 #include "chrome/browser/profile_manager.h" | 32 #include "chrome/browser/profile_manager.h" |
| 30 #include "chrome/common/temp_scaffolding_stubs.h" | 33 #include "chrome/common/temp_scaffolding_stubs.h" |
| 34 #include "grit/generated_resources.h" | |
| 31 #import "xib_localizers/main_menu_localizer.h" | 35 #import "xib_localizers/main_menu_localizer.h" |
| 32 | 36 |
| 33 @interface AppController(PRIVATE) | 37 @interface AppController(PRIVATE) |
| 34 - (void)initMenuState; | 38 - (void)initMenuState; |
| 35 - (void)openURLs:(const std::vector<GURL>&)urls; | 39 - (void)openURLs:(const std::vector<GURL>&)urls; |
| 36 - (void)openPendingURLs; | 40 - (void)openPendingURLs; |
| 37 - (void)getUrl:(NSAppleEventDescriptor*)event | 41 - (void)getUrl:(NSAppleEventDescriptor*)event |
| 38 withReply:(NSAppleEventDescriptor*)reply; | 42 withReply:(NSAppleEventDescriptor*)reply; |
| 39 - (void)openFiles:(NSAppleEventDescriptor*)event | 43 - (void)openFiles:(NSAppleEventDescriptor*)event |
| 40 withReply:(NSAppleEventDescriptor*)reply; | 44 withReply:(NSAppleEventDescriptor*)reply; |
| 41 - (void)windowLayeringDidChange:(NSNotification*)inNotification; | 45 - (void)windowLayeringDidChange:(NSNotification*)inNotification; |
| 46 - (BOOL)shouldQuitWithInProgressDownloads; | |
| 42 @end | 47 @end |
| 43 | 48 |
| 44 @implementation AppController | 49 @implementation AppController |
| 45 | 50 |
| 46 // This method is called very early in application startup (ie, before | 51 // This method is called very early in application startup (ie, before |
| 47 // the profile is loaded or any preferences have been registered). Defer any | 52 // the profile is loaded or any preferences have been registered). Defer any |
| 48 // user-data initialization until -applicationDidFinishLaunching:. | 53 // user-data initialization until -applicationDidFinishLaunching:. |
| 49 - (void)awakeFromNib { | 54 - (void)awakeFromNib { |
| 50 pendingURLs_.reset(new std::vector<GURL>()); | 55 pendingURLs_.reset(new std::vector<GURL>()); |
| 51 | 56 |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 235 // Build up the encoding menu, the order of the items differs based on the | 240 // Build up the encoding menu, the order of the items differs based on the |
| 236 // current locale (see http://crbug.com/7647 for details). | 241 // current locale (see http://crbug.com/7647 for details). |
| 237 // We need a valid g_browser_process to get the profile which is why we can't | 242 // We need a valid g_browser_process to get the profile which is why we can't |
| 238 // call this from awakeFromNib. | 243 // call this from awakeFromNib. |
| 239 EncodingMenuControllerDelegate::BuildEncodingMenu([self defaultProfile]); | 244 EncodingMenuControllerDelegate::BuildEncodingMenu([self defaultProfile]); |
| 240 | 245 |
| 241 // Now that we're initialized we can open any URLs we've been holding onto. | 246 // Now that we're initialized we can open any URLs we've been holding onto. |
| 242 [self openPendingURLs]; | 247 [self openPendingURLs]; |
| 243 } | 248 } |
| 244 | 249 |
| 250 // Check all browsers for in progress downloads, and if we find any, prompt the | |
| 251 // user to see if we should continue to exit (and thus cancel the downloads), or | |
| 252 // if we should wait. | |
| 253 - (BOOL)shouldQuitWithInProgressDownloads { | |
| 254 BrowserList::const_iterator it = BrowserList::begin(); | |
| 255 for (; it != BrowserList::end(); ++it) { | |
| 256 Browser* browser = *it; | |
| 257 Profile* profile = browser->profile(); | |
| 258 if (!profile) | |
| 259 continue; | |
| 260 | |
| 261 DownloadManager* download_manager = profile->GetDownloadManager(); | |
| 262 if (!download_manager || download_manager->in_progress_count() == 0) | |
| 263 continue; | |
| 264 | |
| 265 // There are downloads in progress so run the dialog asking if we should | |
| 266 // exit. There can be multiple windows (i.e. browsers) open, but we don't | |
| 267 // want to prompt for each one. Use the first browser with downloads in | |
| 268 // progress. | |
| 269 NSString* descriptionText = nil; | |
| 270 NSString* waitButton = nil; | |
| 271 NSString* exitButton = nil; | |
| 272 | |
| 273 // Set the dialog text based on whether or not there are multiple downloads. | |
| 274 if (download_manager->in_progress_count() == 1) { | |
| 275 // Dialog text. | |
| 276 descriptionText = | |
| 277 base::SysWideToNSString( | |
| 278 l10n_util::GetString(IDS_SINGLE_DOWNLOAD_REMOVE_CONFIRM_TITLE)); | |
| 279 | |
| 280 // Cancel downloads and exit button text. | |
| 281 exitButton = | |
| 282 base::SysWideToNSString( | |
| 283 l10n_util::GetString( | |
| 284 IDS_SINGLE_DOWNLOAD_REMOVE_CONFIRM_OK_BUTTON_LABEL)); | |
| 285 | |
| 286 // Wait for downloads button text. | |
| 287 waitButton = | |
| 288 base::SysWideToNSString( | |
| 289 l10n_util::GetString( | |
| 290 IDS_SINGLE_DOWNLOAD_REMOVE_CONFIRM_CANCEL_BUTTON_LABEL)); | |
| 291 } else { | |
| 292 // Dialog text. | |
| 293 descriptionText = | |
| 294 base::SysWideToNSString( | |
| 295 l10n_util::GetStringF(IDS_MULTIPLE_DOWNLOADS_REMOVE_CONFIRM_TITLE, | |
| 296 download_manager->in_progress_count())); | |
| 297 | |
| 298 // Cancel downloads and exit button text. | |
| 299 exitButton = | |
| 300 base::SysWideToNSString( | |
| 301 l10n_util::GetString( | |
| 302 IDS_MULTIPLE_DOWNLOADS_REMOVE_CONFIRM_OK_BUTTON_LABEL)); | |
| 303 | |
| 304 // Wait for downloads button text. | |
| 305 waitButton = | |
| 306 base::SysWideToNSString( | |
| 307 l10n_util::GetString( | |
| 308 IDS_MULTIPLE_DOWNLOADS_REMOVE_CONFIRM_CANCEL_BUTTON_LABEL)); | |
| 309 } | |
| 310 | |
| 311 // 'waitButton' is the default choice. | |
| 312 int choice = NSRunAlertPanel(nil, descriptionText, | |
| 313 waitButton, exitButton, nil); | |
| 314 if (choice == NSAlertDefaultReturn) { | |
| 315 // We're not going to exit, so show the user the download page so they can | |
| 316 // see the in progress downloads. | |
| 317 browser->ShowDownloadsTab(); | |
| 318 return NO; | |
| 319 } | |
| 320 break; | |
| 321 } | |
| 322 | |
| 323 // Okay to exit. | |
| 324 return YES; | |
| 325 } | |
| 326 | |
| 245 // We can't use the standard terminate: method because it will abruptly exit | 327 // We can't use the standard terminate: method because it will abruptly exit |
| 246 // the app and leave things on the stack in an unfinalized state. We need to | 328 // the app and leave things on the stack in an unfinalized state. We need to |
| 247 // post a quit message to our run loop so the stack can gracefully unwind. | 329 // post a quit message to our run loop so the stack can gracefully unwind. |
| 248 - (IBAction)quit:(id)sender { | 330 - (IBAction)quit:(id)sender { |
| 249 // TODO(pinkerton): | 331 // TODO(pinkerton): |
| 250 // since we have to roll it ourselves, ask the delegate (ourselves, really) | 332 // since we have to roll it ourselves, ask the delegate (ourselves, really) |
| 251 // if we should terminate. For example, we might not want to if the user | 333 // if we should terminate. For example, we might not want to if the user |
| 252 // has ongoing downloads or multiple windows/tabs open. However, this would | 334 // has ongoing downloads or multiple windows/tabs open. However, this would |
| 253 // require posting UI and may require spinning up another run loop to | 335 // require posting UI and may require spinning up another run loop to |
| 254 // handle it. If it says to continue, post the quit message, otherwise | 336 // handle it. If it says to continue, post the quit message, otherwise |
| 255 // go back to normal. | 337 // go back to normal. |
| 256 | 338 |
| 339 // Check for in-progress downloads, and prompt the user if they really want to | |
| 340 // quit (and thus cancel the downloads). | |
| 341 if (![self shouldQuitWithInProgressDownloads]) | |
| 342 return; | |
|
Nico
2009/08/04 04:26:07
Isn't this something that should be done in |appli
| |
| 343 | |
| 257 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager]; | 344 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager]; |
| 258 [em removeEventHandlerForEventClass:kInternetEventClass | 345 [em removeEventHandlerForEventClass:kInternetEventClass |
| 259 andEventID:kAEGetURL]; | 346 andEventID:kAEGetURL]; |
| 260 [em removeEventHandlerForEventClass:'WWW!' | 347 [em removeEventHandlerForEventClass:'WWW!' |
| 261 andEventID:'OURL']; | 348 andEventID:'OURL']; |
| 262 [em removeEventHandlerForEventClass:kCoreEventClass | 349 [em removeEventHandlerForEventClass:kCoreEventClass |
| 263 andEventID:kAEOpenDocuments]; | 350 andEventID:kAEOpenDocuments]; |
| 264 | 351 |
| 265 // TODO(pinkerton): Not sure where this should live, including it here | 352 // TODO(pinkerton): Not sure where this should live, including it here |
| 266 // causes all sorts of asserts from the open renderers. On Windows, it | 353 // causes all sorts of asserts from the open renderers. On Windows, it |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 528 name:kUserClosedAboutNotification | 615 name:kUserClosedAboutNotification |
| 529 object:aboutController_.get()]; | 616 object:aboutController_.get()]; |
| 530 } | 617 } |
| 531 if (![[aboutController_ window] isVisible]) | 618 if (![[aboutController_ window] isVisible]) |
| 532 [[aboutController_ window] center]; | 619 [[aboutController_ window] center]; |
| 533 [aboutController_ showWindow:self]; | 620 [aboutController_ showWindow:self]; |
| 534 #endif | 621 #endif |
| 535 } | 622 } |
| 536 | 623 |
| 537 @end | 624 @end |
| OLD | NEW |