Chromium Code Reviews| Index: chrome/browser/web_applications/web_app_win.cc |
| diff --git a/chrome/browser/web_applications/web_app_win.cc b/chrome/browser/web_applications/web_app_win.cc |
| index f101f6996d15d73898d206f72288402923399f91..3ad77fd281ed91cbdc22a527e80c57d6f9d3a9bd 100644 |
| --- a/chrome/browser/web_applications/web_app_win.cc |
| +++ b/chrome/browser/web_applications/web_app_win.cc |
| @@ -129,55 +129,15 @@ std::vector<base::FilePath> MatchingShortcutsForProfileAndExtension( |
| return shortcut_paths; |
| } |
| -} // namespace |
| - |
| -namespace web_app { |
| - |
| -namespace internals { |
| - |
| -// Saves |image| to |icon_file| if the file is outdated and refresh shell's |
| -// icon cache to ensure correct icon is displayed. Returns true if icon_file |
| -// is up to date or successfully updated. |
| -bool CheckAndSaveIcon(const base::FilePath& icon_file, |
| - const gfx::ImageFamily& image) { |
| - if (ShouldUpdateIcon(icon_file, image)) { |
| - if (SaveIconWithCheckSum(icon_file, image)) { |
| - // Refresh shell's icon cache. This call is quite disruptive as user would |
| - // see explorer rebuilding the icon cache. It would be great that we find |
| - // a better way to achieve this. |
| - SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSHNOWAIT, |
| - NULL, NULL); |
| - } else { |
| - return false; |
| - } |
| - } |
| - |
| - return true; |
| -} |
| - |
| -bool CreatePlatformShortcuts( |
| +// Creates application shortcuts in a given set of paths. |
| +// |shortcut_paths| is a list of directories in which shortcuts should be |
| +// created. |
| +// Returns true on success, false on failure. |
| +// Must be called on the FILE thread. |
| +bool CreateShortcutsInPaths( |
| const base::FilePath& web_app_path, |
| const ShellIntegration::ShortcutInfo& shortcut_info, |
| - const ShellIntegration::ShortcutLocations& creation_locations) { |
| - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
| - |
| - // Shortcut paths under which to create shortcuts. |
| - std::vector<base::FilePath> shortcut_paths = |
| - GetShortcutPaths(creation_locations); |
| - |
| - bool pin_to_taskbar = creation_locations.in_quick_launch_bar && |
| - (base::win::GetVersion() >= base::win::VERSION_WIN7); |
| - |
| - // Create/update the shortcut in the web app path for the "Pin To Taskbar" |
| - // option in Win7. We use the web app path shortcut because we will overwrite |
| - // it rather than appending unique numbers if the shortcut already exists. |
| - // This prevents pinned apps from having unique numbers in their names. |
| - if (pin_to_taskbar) |
| - shortcut_paths.push_back(web_app_path); |
| - |
| - if (shortcut_paths.empty()) |
| - return false; |
| - |
| + const std::vector<base::FilePath>& shortcut_paths) { |
| // Ensure web_app_path exists. |
| if (!file_util::PathExists(web_app_path) && |
| !file_util::CreateDirectory(web_app_path)) { |
| @@ -257,20 +217,138 @@ bool CreatePlatformShortcuts( |
| base::win::SHORTCUT_CREATE_ALWAYS) && success; |
| } |
| - if (success && pin_to_taskbar) { |
| + return success; |
| +} |
| + |
| +// Gets the directories with shortcuts for an app, and deletes the shortcuts. |
| +// This will search the standard locations for shortcuts named |title| that open |
| +// in the profile with |profile_path|. |
| +// |was_pinned_to_taskbar| will be set to true if there was previously a |
| +// shortcut pinned to the taskbar for this app; false otherwise. |
| +// |shortcut_paths| will be populated with a list of directories where shortcuts |
| +// for this app were found (and deleted). Both of these may be NULL. |
| +void GetShortcutLocationsAndDeleteShortcuts( |
|
Matt Giuca
2013/05/28 01:09:14
This was renamed at Sam's request: the new name is
benwells
2013/05/28 02:14:07
Could you add a comment somewhere that duplicates
Matt Giuca
2013/05/28 03:10:07
Done.
|
| + const base::FilePath& web_app_path, |
| + const base::FilePath& profile_path, |
| + const string16& title, |
| + bool* was_pinned_to_taskbar, |
| + std::vector<base::FilePath>* shortcut_paths) { |
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
| + |
| + // Get all possible locations for shortcuts. |
| + ShellIntegration::ShortcutLocations all_shortcut_locations; |
| + all_shortcut_locations.in_applications_menu = true; |
| + all_shortcut_locations.in_quick_launch_bar = true; |
| + all_shortcut_locations.on_desktop = true; |
| + // Delete shortcuts from the Chrome Apps subdirectory. |
| + // This matches the subdir name set by CreateApplicationShortcutView::Accept |
| + // for Chrome apps (not URL apps, but this function does not apply for them). |
| + all_shortcut_locations.applications_menu_subdir = |
| + web_app::GetAppShortcutsSubdirName(); |
| + std::vector<base::FilePath> all_paths = web_app::internals::GetShortcutPaths( |
| + all_shortcut_locations); |
| + if (base::win::GetVersion() >= base::win::VERSION_WIN7) |
| + all_paths.push_back(web_app_path); |
| + |
| + if (was_pinned_to_taskbar) { |
| + // Determine if there is a link to this app in the TaskBar pin directory. |
| + base::FilePath taskbar_pin_path; |
| + if (PathService::Get(base::DIR_TASKBAR_PINS, &taskbar_pin_path)) { |
| + std::vector<base::FilePath> taskbar_pin_files = |
| + MatchingShortcutsForProfileAndExtension(taskbar_pin_path, |
| + profile_path, title); |
| + *was_pinned_to_taskbar = !taskbar_pin_files.empty(); |
| + } else { |
| + *was_pinned_to_taskbar = false; |
| + } |
| + } |
| + |
| + for (std::vector<base::FilePath>::const_iterator i = all_paths.begin(); |
| + i != all_paths.end(); ++i) { |
| + std::vector<base::FilePath> shortcut_files = |
| + MatchingShortcutsForProfileAndExtension(*i, profile_path, title); |
| + if (shortcut_paths && !shortcut_files.empty()) { |
| + shortcut_paths->push_back(*i); |
| + } |
| + for (std::vector<base::FilePath>::const_iterator j = shortcut_files.begin(); |
| + j != shortcut_files.end(); ++j) { |
| + // Any shortcut could have been pinned, either by chrome or the user, so |
| + // they are all unpinned. |
| + base::win::TaskbarUnpinShortcutLink(j->value().c_str()); |
| + file_util::Delete(*j, false); |
| + } |
| + } |
| +} |
| + |
| +} // namespace |
| + |
| +namespace web_app { |
| + |
| +namespace internals { |
| + |
| +// Saves |image| to |icon_file| if the file is outdated and refresh shell's |
| +// icon cache to ensure correct icon is displayed. Returns true if icon_file |
| +// is up to date or successfully updated. |
| +bool CheckAndSaveIcon(const base::FilePath& icon_file, |
| + const gfx::ImageFamily& image) { |
| + if (ShouldUpdateIcon(icon_file, image)) { |
| + if (SaveIconWithCheckSum(icon_file, image)) { |
| + // Refresh shell's icon cache. This call is quite disruptive as user would |
| + // see explorer rebuilding the icon cache. It would be great that we find |
| + // a better way to achieve this. |
| + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSHNOWAIT, |
| + NULL, NULL); |
| + } else { |
| + return false; |
| + } |
| + } |
| + |
| + return true; |
| +} |
| + |
| +bool CreatePlatformShortcuts( |
| + const base::FilePath& web_app_path, |
| + const ShellIntegration::ShortcutInfo& shortcut_info, |
| + const ShellIntegration::ShortcutLocations& creation_locations) { |
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
| + |
| + // Shortcut paths under which to create shortcuts. |
| + std::vector<base::FilePath> shortcut_paths = |
| + GetShortcutPaths(creation_locations); |
| + |
| + bool pin_to_taskbar = creation_locations.in_quick_launch_bar && |
| + (base::win::GetVersion() >= base::win::VERSION_WIN7); |
| + |
| + // Create/update the shortcut in the web app path for the "Pin To Taskbar" |
| + // option in Win7. We use the web app path shortcut because we will overwrite |
| + // it rather than appending unique numbers if the shortcut already exists. |
| + // This prevents pinned apps from having unique numbers in their names. |
| + if (pin_to_taskbar) |
| + shortcut_paths.push_back(web_app_path); |
| + |
| + if (shortcut_paths.empty()) |
| + return false; |
| + |
| + if (!CreateShortcutsInPaths(web_app_path, shortcut_info, shortcut_paths)) |
| + return false; |
| + |
| + if (pin_to_taskbar) { |
| + base::FilePath file_name = |
| + web_app::internals::GetSanitizedFileName(shortcut_info.title); |
| // Use the web app path shortcut for pinning to avoid having unique numbers |
| // in the application name. |
| base::FilePath shortcut_to_pin = web_app_path.Append(file_name). |
| AddExtension(installer::kLnkExt); |
| - success = base::win::TaskbarPinShortcutLink( |
| - shortcut_to_pin.value().c_str()) && success; |
| + if (!base::win::TaskbarPinShortcutLink(shortcut_to_pin.value().c_str())) |
| + return false; |
| } |
| - return success; |
| + return true; |
| } |
| void UpdatePlatformShortcuts( |
| const base::FilePath& web_app_path, |
| + const string16& old_app_title, |
| const ShellIntegration::ShortcutInfo& shortcut_info) { |
| DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
| @@ -278,6 +356,30 @@ void UpdatePlatformShortcuts( |
| base::FilePath file_name = |
| web_app::internals::GetSanitizedFileName(shortcut_info.title); |
| + if (old_app_title != shortcut_info.title) { |
| + // The app's title has changed. Delete all existing app shortcuts and |
| + // recreate them in any locations they already existed (but do not add them |
| + // to locations where they do not currently exist). |
| + bool was_pinned_to_taskbar; |
| + std::vector<base::FilePath> shortcut_paths; |
| + GetShortcutLocationsAndDeleteShortcuts( |
| + web_app_path, shortcut_info.profile_path, old_app_title, |
| + &was_pinned_to_taskbar, &shortcut_paths); |
| + CreateShortcutsInPaths(web_app_path, shortcut_info, shortcut_paths); |
| + // If the shortcut was pinned to the taskbar, |
| + // GetShortcutLocationsAndDeleteShortcuts will have deleted it. In that |
| + // case, re-pin it. |
| + if (was_pinned_to_taskbar) { |
| + base::FilePath file_name = |
| + web_app::internals::GetSanitizedFileName(shortcut_info.title); |
| + // Use the web app path shortcut for pinning to avoid having unique |
| + // numbers in the application name. |
| + base::FilePath shortcut_to_pin = web_app_path.Append(file_name). |
| + AddExtension(installer::kLnkExt); |
| + base::win::TaskbarPinShortcutLink(shortcut_to_pin.value().c_str()); |
| + } |
| + } |
| + |
| // If an icon file exists, and is out of date, replace it with the new icon |
| // and let the shell know the icon has been modified. |
| base::FilePath icon_file = web_app_path.Append(file_name).AddExtension( |
| @@ -290,41 +392,14 @@ void UpdatePlatformShortcuts( |
| void DeletePlatformShortcuts( |
| const base::FilePath& web_app_path, |
| const ShellIntegration::ShortcutInfo& shortcut_info) { |
| - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
| - |
| - // Get all possible locations for shortcuts. |
| - ShellIntegration::ShortcutLocations all_shortcut_locations; |
| - all_shortcut_locations.in_applications_menu = true; |
| - all_shortcut_locations.in_quick_launch_bar = true; |
| - all_shortcut_locations.on_desktop = true; |
| - // Delete shortcuts from the Chrome Apps subdirectory. |
| - // This matches the subdir name set by CreateApplicationShortcutView::Accept |
| - // for Chrome apps (not URL apps, but this function does not apply for them). |
| - string16 start_menu_subdir = GetAppShortcutsSubdirName(); |
| - all_shortcut_locations.applications_menu_subdir = start_menu_subdir; |
| - std::vector<base::FilePath> shortcut_paths = GetShortcutPaths( |
| - all_shortcut_locations); |
| - if (base::win::GetVersion() >= base::win::VERSION_WIN7) |
| - shortcut_paths.push_back(web_app_path); |
| - |
| - for (std::vector<base::FilePath>::const_iterator i = shortcut_paths.begin(); |
| - i != shortcut_paths.end(); ++i) { |
| - std::vector<base::FilePath> shortcut_files = |
| - MatchingShortcutsForProfileAndExtension(*i, shortcut_info.profile_path, |
| - shortcut_info.title); |
| - for (std::vector<base::FilePath>::const_iterator j = shortcut_files.begin(); |
| - j != shortcut_files.end(); ++j) { |
| - // Any shortcut could have been pinned, either by chrome or the user, so |
| - // they are all unpinned. |
| - base::win::TaskbarUnpinShortcutLink(j->value().c_str()); |
| - file_util::Delete(*j, false); |
| - } |
| - } |
| + GetShortcutLocationsAndDeleteShortcuts( |
| + web_app_path, shortcut_info.profile_path, shortcut_info.title, NULL, |
| + NULL); |
| // If there are no more shortcuts in the Chrome Apps subdirectory, remove it. |
| base::FilePath chrome_apps_dir; |
| if (PathService::Get(base::DIR_START_MENU, &chrome_apps_dir)) { |
| - chrome_apps_dir = chrome_apps_dir.Append(start_menu_subdir); |
| + chrome_apps_dir = chrome_apps_dir.Append(GetAppShortcutsSubdirName()); |
| if (file_util::IsDirectoryEmpty(chrome_apps_dir)) |
| file_util::Delete(chrome_apps_dir, false); |
| } |