Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(434)

Side by Side Diff: chrome/browser/views/create_application_shortcut_view.cc

Issue 482003: Get web app icon via FavIconHelper and auto repair/update (Closed)
Patch Set: miranda's review 1 Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #include "chrome/browser/views/create_application_shortcut_view.h" 5 #include "chrome/browser/views/create_application_shortcut_view.h"
6 6
7 #include "app/gfx/canvas.h" 7 #include "app/gfx/canvas.h"
8 #include "app/gfx/codec/png_codec.h" 8 #include "app/gfx/codec/png_codec.h"
9 #include "app/l10n_util.h" 9 #include "app/l10n_util.h"
10 #include "app/resource_bundle.h" 10 #include "app/resource_bundle.h"
(...skipping 17 matching lines...) Expand all
28 #include "views/window/window.h" 28 #include "views/window/window.h"
29 29
30 #if defined(OS_WIN) 30 #if defined(OS_WIN)
31 #include "base/win_util.h" 31 #include "base/win_util.h"
32 #endif // defined(OS_WIN) 32 #endif // defined(OS_WIN)
33 33
34 namespace { 34 namespace {
35 35
36 const int kAppIconSize = 32; 36 const int kAppIconSize = 32;
37 37
38 bool IconPrecedes(
39 const webkit_glue::WebApplicationInfo::IconInfo& left,
40 const webkit_glue::WebApplicationInfo::IconInfo& right) {
41 return left.width < right.width;
42 }
43
44 // AppInfoView shows the application icon and title. 38 // AppInfoView shows the application icon and title.
45 class AppInfoView : public views::View { 39 class AppInfoView : public views::View {
46 public: 40 public:
47 AppInfoView(const string16& title, 41 AppInfoView(const string16& title,
48 const string16& description, 42 const string16& description,
49 const SkBitmap& icon); 43 const SkBitmap& icon);
50 44
51 // Updates the title/description of the web app. 45 // Updates the title/description of the web app.
52 void UpdateText(const string16& title, const string16& description); 46 void UpdateText(const string16& title, const string16& description);
53 47
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 namespace browser { 190 namespace browser {
197 191
198 void ShowCreateShortcutsDialog(gfx::NativeWindow parent_window, 192 void ShowCreateShortcutsDialog(gfx::NativeWindow parent_window,
199 TabContents* tab_contents) { 193 TabContents* tab_contents) {
200 views::Window::CreateChromeWindow(parent_window, gfx::Rect(), 194 views::Window::CreateChromeWindow(parent_window, gfx::Rect(),
201 new CreateApplicationShortcutView(tab_contents))->Show(); 195 new CreateApplicationShortcutView(tab_contents))->Show();
202 } 196 }
203 197
204 }; // namespace browser 198 }; // namespace browser
205 199
200 class CreateApplicationShortcutView::IconDownloadCallbackFunctor {
201 public:
202 explicit IconDownloadCallbackFunctor(CreateApplicationShortcutView* owner)
203 : owner_(owner) {
204 }
205
206 void Run(int download_id, bool errored, const SkBitmap& image) {
207 if (owner_)
208 owner_->OnIconDownloaded(errored, image);
209 delete this;
210 }
211
212 void Cancel() {
213 owner_ = NULL;
214 }
215
216 private:
217 CreateApplicationShortcutView* owner_;
218 };
219
206 CreateApplicationShortcutView::CreateApplicationShortcutView( 220 CreateApplicationShortcutView::CreateApplicationShortcutView(
207 TabContents* tab_contents) 221 TabContents* tab_contents)
208 : tab_contents_(tab_contents) { 222 : tab_contents_(tab_contents),
223 pending_download_(NULL) {
209 Init(); 224 Init();
210 } 225 }
211 226
212 CreateApplicationShortcutView::~CreateApplicationShortcutView() { 227 CreateApplicationShortcutView::~CreateApplicationShortcutView() {
228 if (pending_download_)
229 pending_download_->Cancel();
213 } 230 }
214 231
215 void CreateApplicationShortcutView::Init() { 232 void CreateApplicationShortcutView::Init() {
216 // Prepare data 233 // Prepare data
234 web_app::GetShortcutInfoForTab(tab_contents_, &shortcut_info_);
235
217 const webkit_glue::WebApplicationInfo& app_info = 236 const webkit_glue::WebApplicationInfo& app_info =
218 tab_contents_->web_app_info(); 237 tab_contents_->web_app_info();
219
220 url_ = app_info.app_url.is_empty() ? tab_contents_->GetURL() :
221 app_info.app_url;
222 title_ = app_info.title.empty() ? tab_contents_->GetTitle() :
223 app_info.title;
224 description_ = app_info.description;
225
226 icon_ = tab_contents_->GetFavIcon();
227 if (!app_info.icons.empty()) { 238 if (!app_info.icons.empty()) {
228 SetIconsInfo(app_info.icons); 239 web_app::GetIconsInfo(app_info, &unprocessed_icons_);
229 FetchIcon(); 240 FetchIcon();
230 } 241 }
231 242
232 if (title_.empty())
233 title_ = UTF8ToUTF16(url_.spec());
234
235 // Create controls 243 // Create controls
236 app_info_ = new AppInfoView(title_, description_, icon_); 244 app_info_ = new AppInfoView(shortcut_info_.title, shortcut_info_.description,
245 shortcut_info_.favicon);
237 create_shortcuts_label_ = new views::Label( 246 create_shortcuts_label_ = new views::Label(
238 l10n_util::GetString(IDS_CREATE_SHORTCUTS_LABEL)); 247 l10n_util::GetString(IDS_CREATE_SHORTCUTS_LABEL));
239 create_shortcuts_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); 248 create_shortcuts_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
240 249
241 Profile* profile = tab_contents_->profile(); 250 Profile* profile = tab_contents_->profile();
242 251
243 desktop_check_box_ = AddCheckbox( 252 desktop_check_box_ = AddCheckbox(
244 l10n_util::GetString(IDS_CREATE_SHORTCUTS_DESKTOP_CHKBOX), 253 l10n_util::GetString(IDS_CREATE_SHORTCUTS_DESKTOP_CHKBOX),
245 profile->GetPrefs()->GetBoolean(prefs::kWebAppCreateOnDesktop)); 254 profile->GetPrefs()->GetBoolean(prefs::kWebAppCreateOnDesktop));
246 255
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 361
353 std::wstring CreateApplicationShortcutView::GetWindowTitle() const { 362 std::wstring CreateApplicationShortcutView::GetWindowTitle() const {
354 return l10n_util::GetString(IDS_CREATE_SHORTCUTS_TITLE); 363 return l10n_util::GetString(IDS_CREATE_SHORTCUTS_TITLE);
355 } 364 }
356 365
357 bool CreateApplicationShortcutView::Accept() { 366 bool CreateApplicationShortcutView::Accept() {
358 if (!IsDialogButtonEnabled(MessageBoxFlags::DIALOGBUTTON_OK)) { 367 if (!IsDialogButtonEnabled(MessageBoxFlags::DIALOGBUTTON_OK)) {
359 return false; 368 return false;
360 } 369 }
361 370
362 ShellIntegration::ShortcutInfo shortcut_info; 371 shortcut_info_.create_on_desktop = desktop_check_box_->checked();
363 shortcut_info.url = url_; 372 shortcut_info_.create_in_applications_menu = menu_check_box_ == NULL ? false :
364 shortcut_info.title = title_;
365 shortcut_info.description = description_;
366 shortcut_info.favicon = icon_;
367 shortcut_info.create_on_desktop = desktop_check_box_->checked();
368 shortcut_info.create_in_applications_menu = menu_check_box_ == NULL ? false :
369 menu_check_box_->checked(); 373 menu_check_box_->checked();
370 374
371 #if defined(OS_WIN) 375 #if defined(OS_WIN)
372 shortcut_info.create_in_quick_launch_bar = quick_launch_check_box_ == NULL ? 376 shortcut_info_.create_in_quick_launch_bar = quick_launch_check_box_ == NULL ?
373 NULL : quick_launch_check_box_->checked(); 377 NULL : quick_launch_check_box_->checked();
374 #elif defined(OS_POSIX) 378 #elif defined(OS_POSIX)
375 // Create shortcut in Mac dock or as Linux (gnome/kde) application launcher 379 // Create shortcut in Mac dock or as Linux (gnome/kde) application launcher
376 // are not implemented yet. 380 // are not implemented yet.
377 shortcut_info.create_in_quick_launch_bar = false; 381 shortcut_info_.create_in_quick_launch_bar = false;
378 #endif 382 #endif
379 383
380 web_app::CreateShortcut( 384 web_app::CreateShortcut(web_app::GetDataDir(tab_contents_->profile()),
381 tab_contents_->profile()->GetPath().Append(chrome::kWebAppDirname), 385 shortcut_info_,
382 shortcut_info, NULL); 386 NULL);
383 387
384 if (tab_contents_->delegate()) 388 if (tab_contents_->delegate())
385 tab_contents_->delegate()->ConvertContentsToApplication(tab_contents_); 389 tab_contents_->delegate()->ConvertContentsToApplication(tab_contents_);
386 return true; 390 return true;
387 } 391 }
388 392
389 views::View* CreateApplicationShortcutView::GetContentsView() { 393 views::View* CreateApplicationShortcutView::GetContentsView() {
390 return this; 394 return this;
391 } 395 }
392 396
393 views::Checkbox* CreateApplicationShortcutView::AddCheckbox( 397 views::Checkbox* CreateApplicationShortcutView::AddCheckbox(
394 const std::wstring& text, bool checked) { 398 const std::wstring& text, bool checked) {
395 views::Checkbox* checkbox = new views::Checkbox(text); 399 views::Checkbox* checkbox = new views::Checkbox(text);
396 checkbox->SetChecked(checked); 400 checkbox->SetChecked(checked);
397 checkbox->set_listener(this); 401 checkbox->set_listener(this);
398 return checkbox; 402 return checkbox;
399 } 403 }
400 404
401 void CreateApplicationShortcutView::SetIconsInfo(const IconInfoList& icons) {
402 unprocessed_icons_.clear();
403 for (size_t i = 0; i < icons.size(); ++i) {
404 // We only take square shaped icons (i.e. width == height).
405 if (icons[i].width == icons[i].height) {
406 unprocessed_icons_.push_back(icons[i]);
407 }
408 }
409
410 std::sort(unprocessed_icons_.begin(), unprocessed_icons_.end(),
411 &IconPrecedes);
412 }
413
414 void CreateApplicationShortcutView::FetchIcon() { 405 void CreateApplicationShortcutView::FetchIcon() {
415 // There should only be fetch job at a time. 406 // There should only be fetch job at a time.
416 DCHECK(icon_fetcher_ == NULL); 407 DCHECK(pending_download_ == NULL);
417 408
418 if (unprocessed_icons_.empty()) { 409 if (unprocessed_icons_.empty()) {
419 // No icons to fetch. 410 // No icons to fetch.
420 return; 411 return;
421 } 412 }
422 413
423 icon_fetcher_.reset(new URLFetcher(unprocessed_icons_.back().url, 414 pending_download_ = new IconDownloadCallbackFunctor(this);
424 URLFetcher::GET, 415 DCHECK(pending_download_);
425 this)); 416
426 DCHECK(icon_fetcher_.get() != NULL); 417 tab_contents_->fav_icon_helper().DownloadImage(
418 unprocessed_icons_.back().url,
419 std::max(unprocessed_icons_.back().width,
420 unprocessed_icons_.back().height),
421 NewCallback(pending_download_, &IconDownloadCallbackFunctor::Run));
422
427 unprocessed_icons_.pop_back(); 423 unprocessed_icons_.pop_back();
428
429 icon_fetcher_->set_load_flags(icon_fetcher_->load_flags() |
430 net::LOAD_IS_DOWNLOAD);
431 icon_fetcher_->set_request_context(
432 tab_contents_->profile()->GetRequestContext());
433 icon_fetcher_->Start();
434 } 424 }
435 425
436 void CreateApplicationShortcutView::ButtonPressed(views::Button* sender, 426 void CreateApplicationShortcutView::ButtonPressed(views::Button* sender,
437 const views::Event& event) { 427 const views::Event& event) {
438 Profile* profile = tab_contents_->profile(); 428 Profile* profile = tab_contents_->profile();
439 if (sender == desktop_check_box_) 429 if (sender == desktop_check_box_)
440 profile->GetPrefs()->SetBoolean(prefs::kWebAppCreateOnDesktop, 430 profile->GetPrefs()->SetBoolean(prefs::kWebAppCreateOnDesktop,
441 desktop_check_box_->checked() ? true : false); 431 desktop_check_box_->checked() ? true : false);
442 else if (sender == menu_check_box_) 432 else if (sender == menu_check_box_)
443 profile->GetPrefs()->SetBoolean(prefs::kWebAppCreateInAppsMenu, 433 profile->GetPrefs()->SetBoolean(prefs::kWebAppCreateInAppsMenu,
444 menu_check_box_->checked() ? true : false); 434 menu_check_box_->checked() ? true : false);
445 else if (sender == quick_launch_check_box_) 435 else if (sender == quick_launch_check_box_)
446 profile->GetPrefs()->SetBoolean(prefs::kWebAppCreateInQuickLaunchBar, 436 profile->GetPrefs()->SetBoolean(prefs::kWebAppCreateInQuickLaunchBar,
447 quick_launch_check_box_->checked() ? true : false); 437 quick_launch_check_box_->checked() ? true : false);
448 438
449 // When no checkbox is checked we should not have the action button enabled. 439 // When no checkbox is checked we should not have the action button enabled.
450 GetDialogClientView()->UpdateDialogButtons(); 440 GetDialogClientView()->UpdateDialogButtons();
451 } 441 }
452 442
453 void CreateApplicationShortcutView::OnURLFetchComplete(const URLFetcher* source, 443 void CreateApplicationShortcutView::OnIconDownloaded(bool errored,
454 const GURL& url, 444 const SkBitmap& image) {
455 const URLRequestStatus& status, 445 pending_download_ = NULL;
456 int response_code,
457 const ResponseCookies& cookies,
458 const std::string& data) {
459 // Delete the fetcher on this function's exit.
460 scoped_ptr<URLFetcher> clean_up_fetcher(icon_fetcher_.release());
461 446
462 bool success = status.is_success() && (response_code == 200) && !data.empty(); 447 if (!errored && !image.isNull()) {
463 448 shortcut_info_.favicon = image;
464 if (success) { 449 static_cast<AppInfoView*>(app_info_)->UpdateIcon(shortcut_info_.favicon);
465 success = gfx::PNGCodec::Decode( 450 } else {
466 reinterpret_cast<const unsigned char*>(data.c_str()), 451 FetchIcon();
467 data.size(),
468 &icon_);
469
470 if (success)
471 static_cast<AppInfoView*>(app_info_)->UpdateIcon(icon_);
472 } 452 }
473
474 if (!success)
475 FetchIcon();
476 } 453 }
OLDNEW
« no previous file with comments | « chrome/browser/views/create_application_shortcut_view.h ('k') | chrome/browser/web_applications/web_app.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698