OLD | NEW |
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 |
(...skipping 1122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 | 1133 |
1134 // PageActionImageView---------------------------------------------------------- | 1134 // PageActionImageView---------------------------------------------------------- |
1135 | 1135 |
1136 // The views need to load their icons asynchronously but might be deleted before | 1136 // The views need to load their icons asynchronously but might be deleted before |
1137 // the images have loaded. This class stays alive while the request is in | 1137 // the images have loaded. This class stays alive while the request is in |
1138 // progress (manages its own lifetime) and keeps track of whether the view still | 1138 // progress (manages its own lifetime) and keeps track of whether the view still |
1139 // cares about the icon loading. | 1139 // cares about the icon loading. |
1140 class LocationBarView::PageActionImageView::ImageLoadingTracker | 1140 class LocationBarView::PageActionImageView::ImageLoadingTracker |
1141 : public base::RefCountedThreadSafe<ImageLoadingTracker> { | 1141 : public base::RefCountedThreadSafe<ImageLoadingTracker> { |
1142 public: | 1142 public: |
1143 explicit ImageLoadingTracker(PageActionImageView* view) : view_(view) { | 1143 explicit ImageLoadingTracker(PageActionImageView* view, int image_count) |
| 1144 : view_(view), image_count_(image_count) { |
1144 AddRef(); // We hold on to a reference to ourself to make sure we don't | 1145 AddRef(); // We hold on to a reference to ourself to make sure we don't |
1145 // get deleted until we get a response from image loading (see | 1146 // get deleted until we get a response from image loading (see |
1146 // ImageLoadingDone). | 1147 // ImageLoadingDone). |
1147 } | 1148 } |
1148 ~ImageLoadingTracker() {} | 1149 ~ImageLoadingTracker() {} |
1149 | 1150 |
1150 void StopTrackingImageLoad() { | 1151 void StopTrackingImageLoad() { |
1151 view_ = NULL; | 1152 view_ = NULL; |
1152 } | 1153 } |
1153 | 1154 |
1154 void OnImageLoaded(SkBitmap* image) { | 1155 void OnImageLoaded(SkBitmap* image, int index) { |
1155 view_->OnImageLoaded(image); | 1156 view_->OnImageLoaded(image, index); |
1156 delete image; | 1157 delete image; |
1157 Release(); // We are no longer needed. | 1158 if (--image_count_ == 0) |
| 1159 Release(); // We are no longer needed. |
1158 } | 1160 } |
1159 | 1161 |
1160 private: | 1162 private: |
1161 | 1163 |
1162 // The view that is waiting for the image to load. | 1164 // The view that is waiting for the image to load. |
1163 PageActionImageView* view_; | 1165 PageActionImageView* view_; |
| 1166 |
| 1167 // The number of images this ImageTracker should keep track of. |
| 1168 int image_count_; |
1164 }; | 1169 }; |
1165 | 1170 |
1166 // The LoadImageTask is for asynchronously loading the image on the file thread. | 1171 // The LoadImageTask is for asynchronously loading the image on the file thread. |
1167 // If the image is successfully loaded and decoded it will report back on the | 1172 // If the image is successfully loaded and decoded it will report back on the |
1168 // |callback_loop| to let the caller know the image is done loading. | 1173 // |callback_loop| to let the caller know the image is done loading. |
1169 class LocationBarView::PageActionImageView::LoadImageTask : public Task { | 1174 class LocationBarView::PageActionImageView::LoadImageTask : public Task { |
1170 public: | 1175 public: |
| 1176 // Constructor for the LoadImageTask class. |tracker| is the object that |
| 1177 // we use to communicate back to the entity that wants the image after we |
| 1178 // decode it. |path| is the path to load the image from. |index| is an |
| 1179 // identifier for the image that we pass back to the caller. |
1171 LoadImageTask(ImageLoadingTracker* tracker, | 1180 LoadImageTask(ImageLoadingTracker* tracker, |
1172 const FilePath& path) | 1181 const FilePath& path, |
| 1182 int index) |
1173 : callback_loop_(MessageLoop::current()), | 1183 : callback_loop_(MessageLoop::current()), |
1174 tracker_(tracker), | 1184 tracker_(tracker), |
1175 path_(path) {} | 1185 path_(path), |
| 1186 index_(index) {} |
1176 | 1187 |
1177 void ReportBack(SkBitmap* image) { | 1188 void ReportBack(SkBitmap* image) { |
1178 DCHECK(image); | 1189 DCHECK(image); |
1179 callback_loop_->PostTask(FROM_HERE, NewRunnableMethod(tracker_, | 1190 callback_loop_->PostTask(FROM_HERE, NewRunnableMethod(tracker_, |
1180 &PageActionImageView::ImageLoadingTracker::OnImageLoaded, image)); | 1191 &PageActionImageView::ImageLoadingTracker::OnImageLoaded, |
| 1192 image, |
| 1193 index_)); |
1181 } | 1194 } |
1182 | 1195 |
1183 virtual void Run() { | 1196 virtual void Run() { |
1184 // Read the file from disk. | 1197 // Read the file from disk. |
1185 std::string file_contents; | 1198 std::string file_contents; |
1186 if (!file_util::PathExists(path_) || | 1199 if (!file_util::PathExists(path_) || |
1187 !file_util::ReadFileToString(path_, &file_contents)) { | 1200 !file_util::ReadFileToString(path_, &file_contents)) { |
1188 ReportBack(NULL); | 1201 ReportBack(NULL); |
1189 return; | 1202 return; |
1190 } | 1203 } |
(...skipping 25 matching lines...) Expand all Loading... |
1216 | 1229 |
1217 private: | 1230 private: |
1218 // The message loop that we need to call back on to report that we are done. | 1231 // The message loop that we need to call back on to report that we are done. |
1219 MessageLoop* callback_loop_; | 1232 MessageLoop* callback_loop_; |
1220 | 1233 |
1221 // The object that is waiting for us to respond back. | 1234 // The object that is waiting for us to respond back. |
1222 ImageLoadingTracker* tracker_; | 1235 ImageLoadingTracker* tracker_; |
1223 | 1236 |
1224 // The path to the image to load asynchronously. | 1237 // The path to the image to load asynchronously. |
1225 FilePath path_; | 1238 FilePath path_; |
| 1239 |
| 1240 // The index of the icon being loaded. |
| 1241 int index_; |
1226 }; | 1242 }; |
1227 | 1243 |
1228 LocationBarView::PageActionImageView::PageActionImageView( | 1244 LocationBarView::PageActionImageView::PageActionImageView( |
1229 LocationBarView* owner, | 1245 LocationBarView* owner, |
1230 Profile* profile, | 1246 Profile* profile, |
1231 const PageAction* page_action) | 1247 const PageAction* page_action) |
1232 : LocationBarImageView(), | 1248 : LocationBarImageView(), |
1233 owner_(owner), | 1249 owner_(owner), |
1234 profile_(profile), | 1250 profile_(profile), |
1235 page_action_(page_action), | 1251 page_action_(page_action), |
1236 tracker_(new ImageLoadingTracker(this)) { | 1252 current_tab_id_(-1), |
| 1253 tooltip_(page_action_->name()) { |
1237 // Load the images this view needs asynchronously on the file thread. We'll | 1254 // Load the images this view needs asynchronously on the file thread. We'll |
1238 // get a call back into OnImageLoaded if the image loads successfully. If not, | 1255 // get a call back into OnImageLoaded if the image loads successfully. If not, |
1239 // the ImageView will have no image and will not appear in the Omnibox. | 1256 // the ImageView will have no image and will not appear in the Omnibox. |
1240 DCHECK(!page_action->icon_path().empty()); | 1257 DCHECK(!page_action->icon_paths().empty()); |
1241 FilePath path = FilePath(page_action->icon_path()); | 1258 const std::vector<FilePath>& icon_paths = page_action->icon_paths(); |
| 1259 page_action_icons_.resize(icon_paths.size()); |
| 1260 int index = 0; |
1242 MessageLoop* file_loop = g_browser_process->file_thread()->message_loop(); | 1261 MessageLoop* file_loop = g_browser_process->file_thread()->message_loop(); |
1243 file_loop->PostTask(FROM_HERE, | 1262 tracker_ = new ImageLoadingTracker(this, icon_paths.size()); |
1244 new LoadImageTask(tracker_, page_action->icon_path())); | 1263 for (std::vector<FilePath>::const_iterator iter = icon_paths.begin(); |
| 1264 iter != icon_paths.end(); ++iter) { |
| 1265 FilePath path = *iter; |
| 1266 file_loop->PostTask(FROM_HERE, new LoadImageTask(tracker_, path, index++)); |
| 1267 } |
1245 } | 1268 } |
1246 | 1269 |
1247 LocationBarView::PageActionImageView::~PageActionImageView() { | 1270 LocationBarView::PageActionImageView::~PageActionImageView() { |
1248 if (tracker_) | 1271 if (tracker_) |
1249 tracker_->StopTrackingImageLoad(); | 1272 tracker_->StopTrackingImageLoad(); |
1250 } | 1273 } |
1251 | 1274 |
1252 bool LocationBarView::PageActionImageView::OnMousePressed( | 1275 bool LocationBarView::PageActionImageView::OnMousePressed( |
1253 const views::MouseEvent& event) { | 1276 const views::MouseEvent& event) { |
1254 // Our PageAction icon was clicked on, notify proper authorities. | 1277 // Our PageAction icon was clicked on, notify proper authorities. |
1255 ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted( | 1278 ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted( |
1256 profile_, page_action_->id(), current_tab_id_, current_url_.spec()); | 1279 profile_, page_action_->id(), current_tab_id_, current_url_.spec()); |
1257 return true; | 1280 return true; |
1258 } | 1281 } |
1259 | 1282 |
1260 void LocationBarView::PageActionImageView::ShowInfoBubble() { | 1283 void LocationBarView::PageActionImageView::ShowInfoBubble() { |
1261 SkColor text_color = SK_ColorBLACK; | 1284 SkColor text_color = SK_ColorBLACK; |
1262 ShowInfoBubbleImpl(ASCIIToWide(page_action_->name()), text_color); | 1285 ShowInfoBubbleImpl(ASCIIToWide(tooltip_), text_color); |
1263 } | 1286 } |
1264 | 1287 |
1265 void LocationBarView::PageActionImageView::UpdateVisibility( | 1288 void LocationBarView::PageActionImageView::UpdateVisibility( |
1266 TabContents* contents, GURL url) { | 1289 TabContents* contents, GURL url) { |
1267 // Save this off so we can pass it back to the extension when the action gets | 1290 // Save this off so we can pass it back to the extension when the action gets |
1268 // executed. See PageActionImageView::OnMousePressed. | 1291 // executed. See PageActionImageView::OnMousePressed. |
1269 current_tab_id_ = ExtensionTabUtil::GetTabId(contents); | 1292 current_tab_id_ = ExtensionTabUtil::GetTabId(contents); |
1270 current_url_ = url; | 1293 current_url_ = url; |
1271 | 1294 |
1272 SetVisible(contents->IsPageActionEnabled(page_action_)); | 1295 const PageActionState* state = contents->GetPageActionState(page_action_); |
| 1296 bool visible = state != NULL; |
| 1297 if (visible) { |
| 1298 // Set the tooltip. |
| 1299 if (state->title().empty()) |
| 1300 tooltip_ = page_action_->name(); |
| 1301 else |
| 1302 tooltip_ = state->title(); |
| 1303 // Set the image. |
| 1304 int index = state->icon_index(); |
| 1305 // The image index (if not within bounds) will be set to the first image. |
| 1306 if (index < 0 || index >= static_cast<int>(page_action_icons_.size())) |
| 1307 index = 0; |
| 1308 ImageView::SetImage(page_action_icons_[index]); |
| 1309 } |
| 1310 SetVisible(visible); |
1273 } | 1311 } |
1274 | 1312 |
1275 void LocationBarView::PageActionImageView::OnImageLoaded(SkBitmap* image) { | 1313 void LocationBarView::PageActionImageView::OnImageLoaded(SkBitmap* image, |
1276 tracker_ = NULL; // The tracker object will delete itself when we return. | 1314 size_t index) { |
1277 ImageView::SetImage(image); | 1315 DCHECK(index < page_action_icons_.size()); |
| 1316 if (index == page_action_icons_.size() - 1) |
| 1317 tracker_ = NULL; // The tracker object will delete itself when we return. |
| 1318 page_action_icons_[index] = *image; |
1278 owner_->UpdatePageActions(); | 1319 owner_->UpdatePageActions(); |
1279 } | 1320 } |
1280 | 1321 |
1281 //////////////////////////////////////////////////////////////////////////////// | 1322 //////////////////////////////////////////////////////////////////////////////// |
1282 // LocationBarView, LocationBar implementation: | 1323 // LocationBarView, LocationBar implementation: |
1283 | 1324 |
1284 void LocationBarView::ShowFirstRunBubble(bool use_OEM_bubble) { | 1325 void LocationBarView::ShowFirstRunBubble(bool use_OEM_bubble) { |
1285 // We wait 30 milliseconds to open. It allows less flicker. | 1326 // We wait 30 milliseconds to open. It allows less flicker. |
1286 Task* task = first_run_bubble_.NewRunnableMethod( | 1327 Task* task = first_run_bubble_.NewRunnableMethod( |
1287 &LocationBarView::ShowFirstRunBubbleInternal, use_OEM_bubble); | 1328 &LocationBarView::ShowFirstRunBubbleInternal, use_OEM_bubble); |
(...skipping 30 matching lines...) Expand all Loading... |
1318 location_entry_->SetForcedQuery(); | 1359 location_entry_->SetForcedQuery(); |
1319 } | 1360 } |
1320 | 1361 |
1321 void LocationBarView::SaveStateToContents(TabContents* contents) { | 1362 void LocationBarView::SaveStateToContents(TabContents* contents) { |
1322 location_entry_->SaveStateToTab(contents); | 1363 location_entry_->SaveStateToTab(contents); |
1323 } | 1364 } |
1324 | 1365 |
1325 void LocationBarView::Revert() { | 1366 void LocationBarView::Revert() { |
1326 location_entry_->RevertAll(); | 1367 location_entry_->RevertAll(); |
1327 } | 1368 } |
OLD | NEW |