| 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..6651b275149db688bd7450dc444fbab5ca97c048 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,140 @@ 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). This will delete duplicate shortcuts,
|
| +// but only return each path once, even if it contained multiple deleted
|
| +// shortcuts. Both of these may be NULL.
|
| +void GetShortcutLocationsAndDeleteShortcuts(
|
| + 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 +358,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 +394,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);
|
| }
|
|
|