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

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

Issue 195050: Linux: implement Page Actions support. (Closed)
Patch Set: comment clarification Created 11 years, 3 months 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
« no previous file with comments | « chrome/browser/views/location_bar_view.h ('k') | chrome/chrome.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/location_bar_view.h" 5 #include "chrome/browser/views/location_bar_view.h"
6 6
7 #if defined(OS_LINUX) 7 #if defined(OS_LINUX)
8 #include <gtk/gtk.h> 8 #include <gtk/gtk.h>
9 #endif 9 #endif
10 10
11 #include "build/build_config.h" 11 #include "build/build_config.h"
12 12
13 #include "app/gfx/canvas.h" 13 #include "app/gfx/canvas.h"
14 #include "app/gfx/color_utils.h" 14 #include "app/gfx/color_utils.h"
15 #include "app/gfx/favicon_size.h"
16 #include "app/l10n_util.h" 15 #include "app/l10n_util.h"
17 #include "app/resource_bundle.h" 16 #include "app/resource_bundle.h"
18 #include "base/file_util.h" 17 #include "base/file_util.h"
19 #include "base/keyboard_codes.h" 18 #include "base/keyboard_codes.h"
20 #include "base/path_service.h" 19 #include "base/path_service.h"
21 #include "base/string_util.h" 20 #include "base/string_util.h"
22 #include "chrome/app/chrome_dll_resource.h" 21 #include "chrome/app/chrome_dll_resource.h"
23 #include "chrome/browser/alternate_nav_url_fetcher.h" 22 #include "chrome/browser/alternate_nav_url_fetcher.h"
24 #include "chrome/browser/browser.h" 23 #include "chrome/browser/browser.h"
25 #include "chrome/browser/browser_list.h" 24 #include "chrome/browser/browser_list.h"
26 #include "chrome/browser/browser_process.h"
27 #include "chrome/browser/command_updater.h" 25 #include "chrome/browser/command_updater.h"
28 #include "chrome/browser/extensions/extension_browser_event_router.h" 26 #include "chrome/browser/extensions/extension_browser_event_router.h"
29 #include "chrome/browser/extensions/extension_tabs_module.h" 27 #include "chrome/browser/extensions/extension_tabs_module.h"
30 #include "chrome/browser/extensions/extensions_service.h" 28 #include "chrome/browser/extensions/extensions_service.h"
31 #include "chrome/browser/page_info_window.h" 29 #include "chrome/browser/page_info_window.h"
32 #include "chrome/browser/profile.h" 30 #include "chrome/browser/profile.h"
33 #include "chrome/browser/search_engines/template_url.h" 31 #include "chrome/browser/search_engines/template_url.h"
34 #include "chrome/browser/search_engines/template_url_model.h" 32 #include "chrome/browser/search_engines/template_url_model.h"
35 #include "chrome/browser/tab_contents/navigation_entry.h" 33 #include "chrome/browser/tab_contents/navigation_entry.h"
36 #include "chrome/browser/view_ids.h" 34 #include "chrome/browser/view_ids.h"
37 #include "chrome/browser/views/info_bubble.h" 35 #include "chrome/browser/views/info_bubble.h"
38 #include "chrome/common/extensions/extension.h" 36 #include "chrome/common/extensions/extension.h"
39 #include "chrome/common/page_action.h" 37 #include "chrome/common/page_action.h"
40 #include "grit/generated_resources.h" 38 #include "grit/generated_resources.h"
41 #include "grit/theme_resources.h" 39 #include "grit/theme_resources.h"
42 #include "skia/ext/image_operations.h"
43 #include "views/focus/focus_manager.h" 40 #include "views/focus/focus_manager.h"
44 #include "views/widget/root_view.h" 41 #include "views/widget/root_view.h"
45 #include "views/widget/widget.h" 42 #include "views/widget/widget.h"
46 #include "webkit/glue/image_decoder.h"
47 43
48 #if defined(OS_WIN) 44 #if defined(OS_WIN)
49 #include "app/win_util.h" 45 #include "app/win_util.h"
50 #include "chrome/browser/views/first_run_bubble.h" 46 #include "chrome/browser/views/first_run_bubble.h"
51 #endif 47 #endif
52 48
53 using views::View; 49 using views::View;
54 50
55 // static 51 // static
56 const int LocationBarView::kVertMargin = 2; 52 const int LocationBarView::kVertMargin = 2;
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 void LocationBarView::DeletePageActionViews() { 646 void LocationBarView::DeletePageActionViews() {
651 if (!page_action_image_views_.empty()) { 647 if (!page_action_image_views_.empty()) {
652 for (size_t i = 0; i < page_action_image_views_.size(); ++i) 648 for (size_t i = 0; i < page_action_image_views_.size(); ++i)
653 RemoveChildView(page_action_image_views_[i]); 649 RemoveChildView(page_action_image_views_[i]);
654 STLDeleteContainerPointers(page_action_image_views_.begin(), 650 STLDeleteContainerPointers(page_action_image_views_.begin(),
655 page_action_image_views_.end()); 651 page_action_image_views_.end());
656 page_action_image_views_.clear(); 652 page_action_image_views_.clear();
657 } 653 }
658 } 654 }
659 655
660 std::vector<PageAction*> LocationBarView::GetPageActions() {
661 std::vector<PageAction*> result;
662 if (!profile_->GetExtensionsService())
663 return result;
664
665 // Query the extension system to see how many page actions we have.
666 // TODO(finnur): Sort the page icons in some meaningful way.
667 const ExtensionList* extensions =
668 profile_->GetExtensionsService()->extensions();
669 for (ExtensionList::const_iterator iter = extensions->begin();
670 iter != extensions->end(); ++iter) {
671 const PageActionMap& page_actions = (*iter)->page_actions();
672 for (PageActionMap::const_iterator i(page_actions.begin());
673 i != page_actions.end(); ++i) {
674 result.push_back(i->second);
675 }
676 }
677
678 return result;
679 }
680
681 void LocationBarView::RefreshPageActionViews() { 656 void LocationBarView::RefreshPageActionViews() {
682 std::vector<PageAction*> page_actions = GetPageActions(); 657 std::vector<PageAction*> page_actions;
658 if (profile_->GetExtensionsService())
659 page_actions = profile_->GetExtensionsService()->GetPageActions();
683 660
684 // On startup we sometimes haven't loaded any extensions. This makes sure 661 // On startup we sometimes haven't loaded any extensions. This makes sure
685 // we catch up when the extensions (and any page actions) load. 662 // we catch up when the extensions (and any page actions) load.
686 if (page_actions.size() != page_action_image_views_.size()) { 663 if (page_actions.size() != page_action_image_views_.size()) {
687 DeletePageActionViews(); // Delete the old views (if any). 664 DeletePageActionViews(); // Delete the old views (if any).
688 665
689 page_action_image_views_.resize(page_actions.size()); 666 page_action_image_views_.resize(page_actions.size());
690 667
691 for (size_t i = 0; i < page_actions.size(); ++i) { 668 for (size_t i = 0; i < page_actions.size(); ++i) {
692 page_action_image_views_[i] = 669 page_action_image_views_[i] =
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 void LocationBarView::SecurityImageView::ShowInfoBubble() { 1178 void LocationBarView::SecurityImageView::ShowInfoBubble() {
1202 std::wstring text; 1179 std::wstring text;
1203 model_->GetIconHoverText(&text); 1180 model_->GetIconHoverText(&text);
1204 ShowInfoBubbleImpl(text, GetColor( 1181 ShowInfoBubbleImpl(text, GetColor(
1205 model_->GetSecurityLevel() == ToolbarModel::SECURE, 1182 model_->GetSecurityLevel() == ToolbarModel::SECURE,
1206 SECURITY_INFO_BUBBLE_TEXT)); 1183 SECURITY_INFO_BUBBLE_TEXT));
1207 } 1184 }
1208 1185
1209 // PageActionImageView---------------------------------------------------------- 1186 // PageActionImageView----------------------------------------------------------
1210 1187
1211 // The views need to load their icons asynchronously but might be deleted before
1212 // the images have loaded. This class stays alive while the request is in
1213 // progress (manages its own lifetime) and keeps track of whether the view still
1214 // cares about the icon loading.
1215 class LocationBarView::PageActionImageView::ImageLoadingTracker
1216 : public base::RefCountedThreadSafe<ImageLoadingTracker> {
1217 public:
1218 explicit ImageLoadingTracker(PageActionImageView* view, int image_count)
1219 : view_(view), image_count_(image_count) {
1220 AddRef(); // We hold on to a reference to ourself to make sure we don't
1221 // get deleted until we get a response from image loading (see
1222 // ImageLoadingDone).
1223 }
1224 ~ImageLoadingTracker() {}
1225
1226 void StopTrackingImageLoad() {
1227 view_ = NULL;
1228 }
1229
1230 void OnImageLoaded(SkBitmap* image, int index) {
1231 if (image == NULL) {
1232 NOTREACHED() << "Image failed to decode.";
1233 image = new SkBitmap();
1234 }
1235 if (view_)
1236 view_->OnImageLoaded(image, index);
1237 delete image;
1238 if (--image_count_ == 0)
1239 Release(); // We are no longer needed.
1240 }
1241
1242 private:
1243
1244 // The view that is waiting for the image to load.
1245 PageActionImageView* view_;
1246
1247 // The number of images this ImageTracker should keep track of.
1248 int image_count_;
1249 };
1250
1251 // The LoadImageTask is for asynchronously loading the image on the file thread.
1252 // If the image is successfully loaded and decoded it will report back on the
1253 // |callback_loop| to let the caller know the image is done loading.
1254 class LocationBarView::PageActionImageView::LoadImageTask : public Task {
1255 public:
1256 // Constructor for the LoadImageTask class. |tracker| is the object that
1257 // we use to communicate back to the entity that wants the image after we
1258 // decode it. |path| is the path to load the image from. |index| is an
1259 // identifier for the image that we pass back to the caller.
1260 LoadImageTask(ImageLoadingTracker* tracker,
1261 const FilePath& path,
1262 int index)
1263 : callback_loop_(MessageLoop::current()),
1264 tracker_(tracker),
1265 path_(path),
1266 index_(index) {}
1267
1268 void ReportBack(SkBitmap* image) {
1269 DCHECK(image);
1270 callback_loop_->PostTask(FROM_HERE, NewRunnableMethod(tracker_,
1271 &PageActionImageView::ImageLoadingTracker::OnImageLoaded,
1272 image,
1273 index_));
1274 }
1275
1276 virtual void Run() {
1277 // Read the file from disk.
1278 std::string file_contents;
1279 if (!file_util::PathExists(path_) ||
1280 !file_util::ReadFileToString(path_, &file_contents)) {
1281 ReportBack(NULL);
1282 return;
1283 }
1284
1285 // Decode the image using WebKit's image decoder.
1286 const unsigned char* data =
1287 reinterpret_cast<const unsigned char*>(file_contents.data());
1288 webkit_glue::ImageDecoder decoder(gfx::Size(kFavIconSize, kFavIconSize));
1289 scoped_ptr<SkBitmap> decoded(new SkBitmap());
1290 *decoded = decoder.Decode(data, file_contents.length());
1291 if (decoded->empty()) {
1292 ReportBack(NULL);
1293 return; // Unable to decode.
1294 }
1295
1296 if (decoded->width() != kFavIconSize || decoded->height() != kFavIconSize) {
1297 // The bitmap is not the correct size, re-sample.
1298 int new_width = decoded->width();
1299 int new_height = decoded->height();
1300 // Calculate what dimensions to use within the constraints (16x16 max).
1301 calc_favicon_target_size(&new_width, &new_height);
1302 *decoded = skia::ImageOperations::Resize(
1303 *decoded, skia::ImageOperations::RESIZE_LANCZOS3,
1304 new_width, new_height);
1305 }
1306
1307 ReportBack(decoded.release());
1308 }
1309
1310 private:
1311 // The message loop that we need to call back on to report that we are done.
1312 MessageLoop* callback_loop_;
1313
1314 // The object that is waiting for us to respond back.
1315 ImageLoadingTracker* tracker_;
1316
1317 // The path to the image to load asynchronously.
1318 FilePath path_;
1319
1320 // The index of the icon being loaded.
1321 int index_;
1322 };
1323
1324 LocationBarView::PageActionImageView::PageActionImageView( 1188 LocationBarView::PageActionImageView::PageActionImageView(
1325 LocationBarView* owner, 1189 LocationBarView* owner,
1326 Profile* profile, 1190 Profile* profile,
1327 const PageAction* page_action) 1191 const PageAction* page_action)
1328 : LocationBarImageView(), 1192 : LocationBarImageView(),
1329 owner_(owner), 1193 owner_(owner),
1330 profile_(profile), 1194 profile_(profile),
1331 page_action_(page_action), 1195 page_action_(page_action),
1332 current_tab_id_(-1), 1196 current_tab_id_(-1),
1333 tooltip_(page_action_->name()) { 1197 tooltip_(page_action_->name()) {
1334 Extension* extension = profile->GetExtensionsService()->GetExtensionById( 1198 Extension* extension = profile->GetExtensionsService()->GetExtensionById(
1335 page_action->extension_id()); 1199 page_action->extension_id());
1336 DCHECK(extension); 1200 DCHECK(extension);
1337 1201
1338 // Load the images this view needs asynchronously on the file thread. We'll 1202 // Load the images this view needs asynchronously on the file thread. We'll
1339 // get a call back into OnImageLoaded if the image loads successfully. If not, 1203 // get a call back into OnImageLoaded if the image loads successfully. If not,
1340 // the ImageView will have no image and will not appear in the Omnibox. 1204 // the ImageView will have no image and will not appear in the Omnibox.
1341 DCHECK(!page_action->icon_paths().empty()); 1205 DCHECK(!page_action->icon_paths().empty());
1342 const std::vector<std::string>& icon_paths = page_action->icon_paths(); 1206 const std::vector<std::string>& icon_paths = page_action->icon_paths();
1343 page_action_icons_.resize(icon_paths.size()); 1207 page_action_icons_.resize(icon_paths.size());
1344 int index = 0;
1345 MessageLoop* file_loop = g_browser_process->file_thread()->message_loop();
1346 tracker_ = new ImageLoadingTracker(this, icon_paths.size()); 1208 tracker_ = new ImageLoadingTracker(this, icon_paths.size());
1347 for (std::vector<std::string>::const_iterator iter = icon_paths.begin(); 1209 for (std::vector<std::string>::const_iterator iter = icon_paths.begin();
1348 iter != icon_paths.end(); ++iter) { 1210 iter != icon_paths.end(); ++iter) {
1349 FilePath path = extension->GetResourcePath(*iter); 1211 FilePath path = extension->GetResourcePath(*iter);
1350 file_loop->PostTask(FROM_HERE, new LoadImageTask(tracker_, path, index++)); 1212 tracker_->PostLoadImageTask(path);
1351 } 1213 }
1352 } 1214 }
1353 1215
1354 LocationBarView::PageActionImageView::~PageActionImageView() { 1216 LocationBarView::PageActionImageView::~PageActionImageView() {
1355 if (tracker_) 1217 if (tracker_)
1356 tracker_->StopTrackingImageLoad(); 1218 tracker_->StopTrackingImageLoad();
1357 } 1219 }
1358 1220
1359 bool LocationBarView::PageActionImageView::OnMousePressed( 1221 bool LocationBarView::PageActionImageView::OnMousePressed(
1360 const views::MouseEvent& event) { 1222 const views::MouseEvent& event) {
1361 // Our PageAction icon was clicked on, notify proper authorities. 1223 // Our PageAction icon was clicked on, notify proper authorities.
1362 ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted( 1224 ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted(
1363 profile_, page_action_->extension_id(), page_action_->id(), 1225 profile_, page_action_->extension_id(), page_action_->id(),
1364 current_tab_id_, current_url_.spec()); 1226 current_tab_id_, current_url_.spec());
1365 return true; 1227 return true;
1366 } 1228 }
1367 1229
1368 void LocationBarView::PageActionImageView::ShowInfoBubble() { 1230 void LocationBarView::PageActionImageView::ShowInfoBubble() {
1369 ShowInfoBubbleImpl(ASCIIToWide(tooltip_), GetColor(false, TEXT)); 1231 ShowInfoBubbleImpl(ASCIIToWide(tooltip_), GetColor(false, TEXT));
1370 } 1232 }
1371 1233
1234 void LocationBarView::PageActionImageView::OnImageLoaded(SkBitmap* image,
1235 size_t index) {
1236 DCHECK(index < page_action_icons_.size());
1237 if (index == page_action_icons_.size() - 1)
1238 tracker_ = NULL; // The tracker object will delete itself when we return.
1239 page_action_icons_[index] = *image;
1240 owner_->UpdatePageActions();
1241 }
1242
1372 void LocationBarView::PageActionImageView::UpdateVisibility( 1243 void LocationBarView::PageActionImageView::UpdateVisibility(
1373 TabContents* contents, GURL url) { 1244 TabContents* contents, GURL url) {
1374 // Save this off so we can pass it back to the extension when the action gets 1245 // Save this off so we can pass it back to the extension when the action gets
1375 // executed. See PageActionImageView::OnMousePressed. 1246 // executed. See PageActionImageView::OnMousePressed.
1376 current_tab_id_ = ExtensionTabUtil::GetTabId(contents); 1247 current_tab_id_ = ExtensionTabUtil::GetTabId(contents);
1377 current_url_ = url; 1248 current_url_ = url;
1378 1249
1379 const PageActionState* state = contents->GetPageActionState(page_action_); 1250 const PageActionState* state = contents->GetPageActionState(page_action_);
1380 bool visible = state != NULL; 1251 bool visible = state != NULL;
1381 if (visible) { 1252 if (visible) {
1382 // Set the tooltip. 1253 // Set the tooltip.
1383 if (state->title().empty()) 1254 if (state->title().empty())
1384 tooltip_ = page_action_->name(); 1255 tooltip_ = page_action_->name();
1385 else 1256 else
1386 tooltip_ = state->title(); 1257 tooltip_ = state->title();
1387 // Set the image. 1258 // Set the image.
1388 int index = state->icon_index(); 1259 int index = state->icon_index();
1389 // The image index (if not within bounds) will be set to the first image. 1260 // The image index (if not within bounds) will be set to the first image.
1390 if (index < 0 || index >= static_cast<int>(page_action_icons_.size())) 1261 if (index < 0 || index >= static_cast<int>(page_action_icons_.size()))
1391 index = 0; 1262 index = 0;
1392 ImageView::SetImage(page_action_icons_[index]); 1263 ImageView::SetImage(page_action_icons_[index]);
1393 } 1264 }
1394 SetVisible(visible); 1265 SetVisible(visible);
1395 } 1266 }
1396 1267
1397 void LocationBarView::PageActionImageView::OnImageLoaded(SkBitmap* image,
1398 size_t index) {
1399 DCHECK(index < page_action_icons_.size());
1400 if (index == page_action_icons_.size() - 1)
1401 tracker_ = NULL; // The tracker object will delete itself when we return.
1402 page_action_icons_[index] = *image;
1403 owner_->UpdatePageActions();
1404 }
1405
1406 //////////////////////////////////////////////////////////////////////////////// 1268 ////////////////////////////////////////////////////////////////////////////////
1407 // LocationBarView, LocationBar implementation: 1269 // LocationBarView, LocationBar implementation:
1408 1270
1409 void LocationBarView::ShowFirstRunBubble(bool use_OEM_bubble) { 1271 void LocationBarView::ShowFirstRunBubble(bool use_OEM_bubble) {
1410 // We wait 30 milliseconds to open. It allows less flicker. 1272 // We wait 30 milliseconds to open. It allows less flicker.
1411 Task* task = first_run_bubble_.NewRunnableMethod( 1273 Task* task = first_run_bubble_.NewRunnableMethod(
1412 &LocationBarView::ShowFirstRunBubbleInternal, use_OEM_bubble); 1274 &LocationBarView::ShowFirstRunBubbleInternal, use_OEM_bubble);
1413 MessageLoop::current()->PostDelayedTask(FROM_HERE, task, 30); 1275 MessageLoop::current()->PostDelayedTask(FROM_HERE, task, 30);
1414 } 1276 }
1415 1277
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 } 1314 }
1453 1315
1454 int LocationBarView::PageActionVisibleCount() { 1316 int LocationBarView::PageActionVisibleCount() {
1455 int result = 0; 1317 int result = 0;
1456 for (size_t i = 0; i < page_action_image_views_.size(); i++) { 1318 for (size_t i = 0; i < page_action_image_views_.size(); i++) {
1457 if (page_action_image_views_[i]->IsVisible()) 1319 if (page_action_image_views_[i]->IsVisible())
1458 ++result; 1320 ++result;
1459 } 1321 }
1460 return result; 1322 return result;
1461 } 1323 }
OLDNEW
« no previous file with comments | « chrome/browser/views/location_bar_view.h ('k') | chrome/chrome.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698