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

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

Issue 5273004: Add "create Application Shortcut" to the app menu on NTP. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase for commit. Created 10 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "app/resource_bundle.h" 8 #include "app/resource_bundle.h"
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
11 #include "base/win/windows_version.h" 11 #include "base/win/windows_version.h"
12 #include "chrome/browser/prefs/pref_service.h" 12 #include "chrome/browser/prefs/pref_service.h"
13 #include "chrome/browser/profile.h" 13 #include "chrome/browser/profile.h"
14 #include "chrome/browser/tab_contents/tab_contents.h" 14 #include "chrome/browser/tab_contents/tab_contents.h"
15 #include "chrome/browser/tab_contents/tab_contents_delegate.h" 15 #include "chrome/browser/tab_contents/tab_contents_delegate.h"
16 #include "chrome/common/chrome_constants.h" 16 #include "chrome/common/chrome_constants.h"
17 #include "chrome/common/extensions/extension.h"
18 #include "chrome/common/extensions/extension_resource.h"
17 #include "chrome/common/pref_names.h" 19 #include "chrome/common/pref_names.h"
18 #include "gfx/canvas_skia.h" 20 #include "gfx/canvas_skia.h"
19 #include "gfx/codec/png_codec.h" 21 #include "gfx/codec/png_codec.h"
20 #include "grit/generated_resources.h" 22 #include "grit/generated_resources.h"
21 #include "grit/locale_settings.h" 23 #include "grit/locale_settings.h"
22 #include "net/base/load_flags.h" 24 #include "net/base/load_flags.h"
23 #include "net/url_request/url_request.h" 25 #include "net/url_request/url_request.h"
24 #include "third_party/skia/include/core/SkRect.h" 26 #include "third_party/skia/include/core/SkRect.h"
25 #include "third_party/skia/include/core/SkPaint.h" 27 #include "third_party/skia/include/core/SkPaint.h"
26 #include "views/controls/button/checkbox.h" 28 #include "views/controls/button/checkbox.h"
27 #include "views/controls/image_view.h" 29 #include "views/controls/image_view.h"
28 #include "views/controls/label.h" 30 #include "views/controls/label.h"
29 #include "views/grid_layout.h" 31 #include "views/grid_layout.h"
30 #include "views/standard_layout.h" 32 #include "views/standard_layout.h"
31 #include "views/window/window.h" 33 #include "views/window/window.h"
32 34
35
33 #if defined(OS_WIN) 36 #if defined(OS_WIN)
34 #include "base/win_util.h" 37 #include "base/win_util.h"
35 #endif // defined(OS_WIN) 38 #endif // defined(OS_WIN)
36 39
37 namespace { 40 namespace {
38 41
39 const int kAppIconSize = 32; 42 const int kAppIconSize = 32;
40 43
41 // AppInfoView shows the application icon and title. 44 // AppInfoView shows the application icon and title.
42 class AppInfoView : public views::View { 45 class AppInfoView : public views::View {
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 border_rect.fBottom - SkDoubleToScalar(0.5), 184 border_rect.fBottom - SkDoubleToScalar(0.5),
182 }; 185 };
183 186
184 SkPaint inner_paint; 187 SkPaint inner_paint;
185 inner_paint.setAntiAlias(true); 188 inner_paint.setAntiAlias(true);
186 inner_paint.setARGB(0xFF, 0xF8, 0xF8, 0xF8); 189 inner_paint.setARGB(0xFF, 0xF8, 0xF8, 0xF8);
187 canvas->AsCanvasSkia()->drawRoundRect( 190 canvas->AsCanvasSkia()->drawRoundRect(
188 inner_rect, SkIntToScalar(1.5), SkIntToScalar(1.5), inner_paint); 191 inner_rect, SkIntToScalar(1.5), SkIntToScalar(1.5), inner_paint);
189 } 192 }
190 193
191 }; // namespace 194 } // namespace
192 195
193 namespace browser { 196 namespace browser {
194 197
195 void ShowCreateShortcutsDialog(gfx::NativeWindow parent_window, 198 void ShowCreateWebAppShortcutsDialog(gfx::NativeWindow parent_window,
196 TabContents* tab_contents) { 199 TabContents* tab_contents) {
197 views::Window::CreateChromeWindow(parent_window, gfx::Rect(), 200 views::Window::CreateChromeWindow(parent_window, gfx::Rect(),
198 new CreateApplicationShortcutView(tab_contents))->Show(); 201 new CreateUrlApplicationShortcutView(tab_contents))->Show();
199 } 202 }
200 203
201 }; // namespace browser 204 void ShowCreateChromeAppShortcutsDialog(gfx::NativeWindow parent_window,
205 Profile* profile,
206 const Extension* app) {
207 views::Window::CreateChromeWindow(parent_window, gfx::Rect(),
208 new CreateChromeApplicationShortcutView(profile, app))->Show();
209 }
202 210
203 class CreateApplicationShortcutView::IconDownloadCallbackFunctor { 211 } // namespace browser
212
213 class CreateUrlApplicationShortcutView::IconDownloadCallbackFunctor {
204 public: 214 public:
205 explicit IconDownloadCallbackFunctor(CreateApplicationShortcutView* owner) 215 explicit IconDownloadCallbackFunctor(CreateUrlApplicationShortcutView* owner)
206 : owner_(owner) { 216 : owner_(owner) {
207 } 217 }
208 218
209 void Run(int download_id, bool errored, const SkBitmap& image) { 219 void Run(int download_id, bool errored, const SkBitmap& image) {
210 if (owner_) 220 if (owner_)
211 owner_->OnIconDownloaded(errored, image); 221 owner_->OnIconDownloaded(errored, image);
212 delete this; 222 delete this;
213 } 223 }
214 224
215 void Cancel() { 225 void Cancel() {
216 owner_ = NULL; 226 owner_ = NULL;
217 } 227 }
218 228
219 private: 229 private:
220 CreateApplicationShortcutView* owner_; 230 CreateUrlApplicationShortcutView* owner_;
221 }; 231 };
222 232
223 CreateApplicationShortcutView::CreateApplicationShortcutView( 233 CreateApplicationShortcutView::CreateApplicationShortcutView(Profile* profile)
224 TabContents* tab_contents) 234 : profile_(profile) {}
225 : tab_contents_(tab_contents),
226 pending_download_(NULL) {
227 Init();
228 }
229 235
230 CreateApplicationShortcutView::~CreateApplicationShortcutView() { 236 CreateApplicationShortcutView::~CreateApplicationShortcutView() {}
231 if (pending_download_)
232 pending_download_->Cancel();
233 }
234 237
235 void CreateApplicationShortcutView::Init() { 238 void CreateApplicationShortcutView::InitControls() {
236 // Prepare data
237 web_app::GetShortcutInfoForTab(tab_contents_, &shortcut_info_);
238
239 const WebApplicationInfo& app_info = tab_contents_->web_app_info();
240 if (!app_info.icons.empty()) {
241 web_app::GetIconsInfo(app_info, &unprocessed_icons_);
242 FetchIcon();
243 }
244
245 // Create controls 239 // Create controls
246 app_info_ = new AppInfoView(shortcut_info_.title, shortcut_info_.description, 240 app_info_ = new AppInfoView(shortcut_info_.title, shortcut_info_.description,
247 shortcut_info_.favicon); 241 shortcut_info_.favicon);
248 create_shortcuts_label_ = new views::Label( 242 create_shortcuts_label_ = new views::Label(
249 l10n_util::GetString(IDS_CREATE_SHORTCUTS_LABEL)); 243 l10n_util::GetString(IDS_CREATE_SHORTCUTS_LABEL));
250 create_shortcuts_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); 244 create_shortcuts_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
251 245
252 Profile* profile = tab_contents_->profile();
253
254 desktop_check_box_ = AddCheckbox( 246 desktop_check_box_ = AddCheckbox(
255 l10n_util::GetString(IDS_CREATE_SHORTCUTS_DESKTOP_CHKBOX), 247 l10n_util::GetString(IDS_CREATE_SHORTCUTS_DESKTOP_CHKBOX),
256 profile->GetPrefs()->GetBoolean(prefs::kWebAppCreateOnDesktop)); 248 profile_->GetPrefs()->GetBoolean(prefs::kWebAppCreateOnDesktop));
257 249
258 menu_check_box_ = NULL; 250 menu_check_box_ = NULL;
259 quick_launch_check_box_ = NULL; 251 quick_launch_check_box_ = NULL;
260 252
261 #if defined(OS_WIN) 253 #if defined(OS_WIN)
262 menu_check_box_ = AddCheckbox( 254 menu_check_box_ = AddCheckbox(
263 l10n_util::GetString(IDS_CREATE_SHORTCUTS_START_MENU_CHKBOX), 255 l10n_util::GetString(IDS_CREATE_SHORTCUTS_START_MENU_CHKBOX),
264 profile->GetPrefs()->GetBoolean(prefs::kWebAppCreateInAppsMenu)); 256 profile_->GetPrefs()->GetBoolean(prefs::kWebAppCreateInAppsMenu));
265 257
266 quick_launch_check_box_ = AddCheckbox( 258 quick_launch_check_box_ = AddCheckbox(
267 (base::win::GetVersion() >= base::win::VERSION_WIN7) ? 259 (base::win::GetVersion() >= base::win::VERSION_WIN7) ?
268 l10n_util::GetString(IDS_PIN_TO_TASKBAR_CHKBOX) : 260 l10n_util::GetString(IDS_PIN_TO_TASKBAR_CHKBOX) :
269 l10n_util::GetString(IDS_CREATE_SHORTCUTS_QUICK_LAUNCH_BAR_CHKBOX), 261 l10n_util::GetString(IDS_CREATE_SHORTCUTS_QUICK_LAUNCH_BAR_CHKBOX),
270 profile->GetPrefs()->GetBoolean(prefs::kWebAppCreateInQuickLaunchBar)); 262 profile_->GetPrefs()->GetBoolean(prefs::kWebAppCreateInQuickLaunchBar));
271 #elif defined(OS_LINUX) 263 #elif defined(OS_LINUX)
272 menu_check_box_ = AddCheckbox( 264 menu_check_box_ = AddCheckbox(
273 l10n_util::GetString(IDS_CREATE_SHORTCUTS_MENU_CHKBOX), 265 l10n_util::GetString(IDS_CREATE_SHORTCUTS_MENU_CHKBOX),
274 profile->GetPrefs()->GetBoolean(prefs::kWebAppCreateInAppsMenu)); 266 profile_->GetPrefs()->GetBoolean(prefs::kWebAppCreateInAppsMenu));
275 #endif 267 #endif
276 268
277 // Layout controls 269 // Layout controls
278 views::GridLayout* layout = CreatePanelGridLayout(this); 270 views::GridLayout* layout = CreatePanelGridLayout(this);
279 SetLayoutManager(layout); 271 SetLayoutManager(layout);
280 272
281 static const int kHeaderColumnSetId = 0; 273 static const int kHeaderColumnSetId = 0;
282 views::ColumnSet* column_set = layout->AddColumnSet(kHeaderColumnSetId); 274 views::ColumnSet* column_set = layout->AddColumnSet(kHeaderColumnSetId);
283 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, 275 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER,
284 100.0f, views::GridLayout::FIXED, 0, 0); 276 100.0f, views::GridLayout::FIXED, 0, 0);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 352
361 bool CreateApplicationShortcutView::IsModal() const { 353 bool CreateApplicationShortcutView::IsModal() const {
362 return true; 354 return true;
363 } 355 }
364 356
365 std::wstring CreateApplicationShortcutView::GetWindowTitle() const { 357 std::wstring CreateApplicationShortcutView::GetWindowTitle() const {
366 return l10n_util::GetString(IDS_CREATE_SHORTCUTS_TITLE); 358 return l10n_util::GetString(IDS_CREATE_SHORTCUTS_TITLE);
367 } 359 }
368 360
369 bool CreateApplicationShortcutView::Accept() { 361 bool CreateApplicationShortcutView::Accept() {
370 if (!IsDialogButtonEnabled(MessageBoxFlags::DIALOGBUTTON_OK)) { 362 if (!IsDialogButtonEnabled(MessageBoxFlags::DIALOGBUTTON_OK))
371 return false; 363 return false;
372 }
373 364
374 shortcut_info_.create_on_desktop = desktop_check_box_->checked(); 365 shortcut_info_.create_on_desktop = desktop_check_box_->checked();
375 shortcut_info_.create_in_applications_menu = menu_check_box_ == NULL ? false : 366 shortcut_info_.create_in_applications_menu = menu_check_box_ == NULL ? false :
376 menu_check_box_->checked(); 367 menu_check_box_->checked();
377 368
378 #if defined(OS_WIN) 369 #if defined(OS_WIN)
379 shortcut_info_.create_in_quick_launch_bar = quick_launch_check_box_ == NULL ? 370 shortcut_info_.create_in_quick_launch_bar = quick_launch_check_box_ == NULL ?
380 NULL : quick_launch_check_box_->checked(); 371 NULL : quick_launch_check_box_->checked();
381 #elif defined(OS_POSIX) 372 #elif defined(OS_POSIX)
382 // Create shortcut in Mac dock or as Linux (gnome/kde) application launcher 373 // Create shortcut in Mac dock or as Linux (gnome/kde) application launcher
383 // are not implemented yet. 374 // are not implemented yet.
384 shortcut_info_.create_in_quick_launch_bar = false; 375 shortcut_info_.create_in_quick_launch_bar = false;
385 #endif 376 #endif
386 377
387 web_app::CreateShortcut(tab_contents_->profile()->GetPath(), 378 web_app::CreateShortcut(profile_->GetPath(),
388 shortcut_info_, 379 shortcut_info_,
389 NULL); 380 NULL);
390
391 tab_contents_->SetAppIcon(shortcut_info_.favicon);
392 if (tab_contents_->delegate())
393 tab_contents_->delegate()->ConvertContentsToApplication(tab_contents_);
394 return true; 381 return true;
395 } 382 }
396 383
384
397 views::View* CreateApplicationShortcutView::GetContentsView() { 385 views::View* CreateApplicationShortcutView::GetContentsView() {
398 return this; 386 return this;
399 } 387 }
400 388
401 views::Checkbox* CreateApplicationShortcutView::AddCheckbox( 389 views::Checkbox* CreateApplicationShortcutView::AddCheckbox(
402 const std::wstring& text, bool checked) { 390 const std::wstring& text, bool checked) {
403 views::Checkbox* checkbox = new views::Checkbox(text); 391 views::Checkbox* checkbox = new views::Checkbox(text);
404 checkbox->SetChecked(checked); 392 checkbox->SetChecked(checked);
405 checkbox->set_listener(this); 393 checkbox->set_listener(this);
406 return checkbox; 394 return checkbox;
407 } 395 }
408 396
409 void CreateApplicationShortcutView::FetchIcon() { 397 void CreateApplicationShortcutView::ButtonPressed(views::Button* sender,
398 const views::Event& event) {
399 if (sender == desktop_check_box_)
400 profile_->GetPrefs()->SetBoolean(prefs::kWebAppCreateOnDesktop,
401 desktop_check_box_->checked() ? true : false);
402 else if (sender == menu_check_box_)
403 profile_->GetPrefs()->SetBoolean(prefs::kWebAppCreateInAppsMenu,
404 menu_check_box_->checked() ? true : false);
405 else if (sender == quick_launch_check_box_)
406 profile_->GetPrefs()->SetBoolean(prefs::kWebAppCreateInQuickLaunchBar,
407 quick_launch_check_box_->checked() ? true : false);
408
409 // When no checkbox is checked we should not have the action button enabled.
410 GetDialogClientView()->UpdateDialogButtons();
411 }
412
413 CreateUrlApplicationShortcutView::CreateUrlApplicationShortcutView(
414 TabContents* tab_contents)
415 : CreateApplicationShortcutView(tab_contents->profile()),
416 tab_contents_(tab_contents),
417 pending_download_(NULL) {
418
419 web_app::GetShortcutInfoForTab(tab_contents_, &shortcut_info_);
420 const WebApplicationInfo& app_info = tab_contents_->web_app_info();
421 if (!app_info.icons.empty()) {
422 web_app::GetIconsInfo(app_info, &unprocessed_icons_);
423 FetchIcon();
424 }
425
426 InitControls();
427 }
428
429 CreateUrlApplicationShortcutView::~CreateUrlApplicationShortcutView() {
430 if (pending_download_)
431 pending_download_->Cancel();
432 }
433
434 bool CreateUrlApplicationShortcutView::Accept() {
435 if (!CreateApplicationShortcutView::Accept())
436 return false;
437
438 tab_contents_->SetAppIcon(shortcut_info_.favicon);
439 if (tab_contents_->delegate())
440 tab_contents_->delegate()->ConvertContentsToApplication(tab_contents_);
441 return true;
442 }
443
444 void CreateUrlApplicationShortcutView::FetchIcon() {
410 // There should only be fetch job at a time. 445 // There should only be fetch job at a time.
411 DCHECK(pending_download_ == NULL); 446 DCHECK(pending_download_ == NULL);
412 447
413 if (unprocessed_icons_.empty()) { 448 if (unprocessed_icons_.empty()) // No icons to fetch.
414 // No icons to fetch.
415 return; 449 return;
416 }
417 450
418 pending_download_ = new IconDownloadCallbackFunctor(this); 451 pending_download_ = new IconDownloadCallbackFunctor(this);
419 DCHECK(pending_download_); 452 DCHECK(pending_download_);
420 453
421 tab_contents_->fav_icon_helper().DownloadImage( 454 tab_contents_->fav_icon_helper().DownloadImage(
422 unprocessed_icons_.back().url, 455 unprocessed_icons_.back().url,
423 std::max(unprocessed_icons_.back().width, 456 std::max(unprocessed_icons_.back().width,
424 unprocessed_icons_.back().height), 457 unprocessed_icons_.back().height),
425 NewCallback(pending_download_, &IconDownloadCallbackFunctor::Run)); 458 NewCallback(pending_download_, &IconDownloadCallbackFunctor::Run));
426 459
427 unprocessed_icons_.pop_back(); 460 unprocessed_icons_.pop_back();
428 } 461 }
429 462
430 void CreateApplicationShortcutView::ButtonPressed(views::Button* sender, 463 void CreateUrlApplicationShortcutView::OnIconDownloaded(bool errored,
431 const views::Event& event) { 464 const SkBitmap& image) {
432 Profile* profile = tab_contents_->profile();
433 if (sender == desktop_check_box_)
434 profile->GetPrefs()->SetBoolean(prefs::kWebAppCreateOnDesktop,
435 desktop_check_box_->checked() ? true : false);
436 else if (sender == menu_check_box_)
437 profile->GetPrefs()->SetBoolean(prefs::kWebAppCreateInAppsMenu,
438 menu_check_box_->checked() ? true : false);
439 else if (sender == quick_launch_check_box_)
440 profile->GetPrefs()->SetBoolean(prefs::kWebAppCreateInQuickLaunchBar,
441 quick_launch_check_box_->checked() ? true : false);
442
443 // When no checkbox is checked we should not have the action button enabled.
444 GetDialogClientView()->UpdateDialogButtons();
445 }
446
447 void CreateApplicationShortcutView::OnIconDownloaded(bool errored,
448 const SkBitmap& image) {
449 pending_download_ = NULL; 465 pending_download_ = NULL;
450 466
451 if (!errored && !image.isNull()) { 467 if (!errored && !image.isNull()) {
452 shortcut_info_.favicon = image; 468 shortcut_info_.favicon = image;
453 static_cast<AppInfoView*>(app_info_)->UpdateIcon(shortcut_info_.favicon); 469 static_cast<AppInfoView*>(app_info_)->UpdateIcon(shortcut_info_.favicon);
454 } else { 470 } else {
455 FetchIcon(); 471 FetchIcon();
456 } 472 }
457 } 473 }
474
475 CreateChromeApplicationShortcutView::CreateChromeApplicationShortcutView(
476 Profile* profile,
477 const Extension* app) :
478 CreateApplicationShortcutView(profile),
479 app_(app),
480 ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)) {
481
482 shortcut_info_.extension_id = UTF8ToUTF16(app_->id());
483 shortcut_info_.url = GURL(app_->launch_web_url());
484 shortcut_info_.title = UTF8ToUTF16(app_->name());
485 shortcut_info_.description = UTF8ToUTF16(app_->description());
486
487 // The icon will be resized to |max_size|.
488 const gfx::Size max_size(kAppIconSize, kAppIconSize);
489
490 // Look for an icon. If there is no icon at the ideal size,
491 // we will resize whatever we can get. Making a large icon smaller
492 // is prefered to making a small icon larger, so look for a larger
493 // icon first:
494 ExtensionResource icon_resource = app_->GetIconResource(
495 kAppIconSize,
496 ExtensionIconSet::MATCH_BIGGER);
497
498 // If no icon exists that is the desired size or larger, get the
499 // largest icon available:
500 if (icon_resource.empty()) {
501 icon_resource = app_->GetIconResource(
502 kAppIconSize,
503 ExtensionIconSet::MATCH_SMALLER);
504 }
505
506 tracker_.LoadImage(app_,
507 icon_resource,
508 max_size,
509 ImageLoadingTracker::DONT_CACHE);
510
511 InitControls();
512 }
513
514 CreateChromeApplicationShortcutView::~CreateChromeApplicationShortcutView() {}
515
516 // Called by tracker_ when the app's icon is loaded.
517 void CreateChromeApplicationShortcutView::OnImageLoaded(
518 SkBitmap* image, ExtensionResource resource, int index) {
519 if (image->isNull()) {
520 NOTREACHED() << "Corrupt image in profile?";
521 return;
522 }
523 shortcut_info_.favicon = *image;
524 static_cast<AppInfoView*>(app_info_)->UpdateIcon(shortcut_info_.favicon);
525 }
526
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/create_application_shortcut_view.h ('k') | chrome/browser/ui/views/frame/browser_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698