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

Side by Side Diff: ios/chrome/browser/ui/open_in_controller.mm

Issue 2804703002: [ObjC ARC] Converts ios/chrome/browser/ui:ui_internal_arc to ARC. (Closed)
Patch Set: comments Created 3 years, 8 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
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 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 #import "ios/chrome/browser/ui/open_in_controller.h" 5 #import "ios/chrome/browser/ui/open_in_controller.h"
6 6
7 #include "base/files/file_path.h" 7 #include "base/files/file_path.h"
8 #include "base/ios/weak_nsobject.h"
9 #include "base/location.h" 8 #include "base/location.h"
10 #include "base/logging.h" 9 #include "base/logging.h"
11 #import "base/mac/bind_objc_block.h" 10 #import "base/mac/bind_objc_block.h"
12 #include "base/mac/objc_property_releaser.h" 11
13 #include "base/sequenced_task_runner.h" 12 #include "base/sequenced_task_runner.h"
14 #include "base/strings/sys_string_conversions.h" 13 #include "base/strings/sys_string_conversions.h"
15 #include "base/threading/sequenced_worker_pool.h" 14 #include "base/threading/sequenced_worker_pool.h"
16 #include "base/threading/thread_restrictions.h" 15 #include "base/threading/thread_restrictions.h"
17 #include "components/strings/grit/components_strings.h" 16 #include "components/strings/grit/components_strings.h"
18 #import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h" 17 #import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h"
19 #import "ios/chrome/browser/ui/open_in_controller_testing.h" 18 #import "ios/chrome/browser/ui/open_in_controller_testing.h"
20 #include "ios/chrome/browser/ui/ui_util.h" 19 #include "ios/chrome/browser/ui/ui_util.h"
21 #import "ios/chrome/browser/ui/uikit_ui_util.h" 20 #import "ios/chrome/browser/ui/uikit_ui_util.h"
22 #include "ios/chrome/grit/ios_strings.h" 21 #include "ios/chrome/grit/ios_strings.h"
23 #include "ios/web/public/web_thread.h" 22 #include "ios/web/public/web_thread.h"
24 #import "ios/web/web_state/ui/crw_web_controller.h" 23 #import "ios/web/web_state/ui/crw_web_controller.h"
25 #include "net/base/load_flags.h" 24 #include "net/base/load_flags.h"
26 #include "net/url_request/url_fetcher.h" 25 #include "net/url_request/url_fetcher.h"
27 #include "net/url_request/url_fetcher_delegate.h" 26 #include "net/url_request/url_fetcher_delegate.h"
28 #include "net/url_request/url_request_context_getter.h" 27 #include "net/url_request/url_request_context_getter.h"
29 #include "ui/base/l10n/l10n_util_mac.h" 28 #include "ui/base/l10n/l10n_util_mac.h"
30 #import "ui/gfx/ios/NSString+CrStringDrawing.h" 29 #import "ui/gfx/ios/NSString+CrStringDrawing.h"
31 #include "url/gurl.h" 30 #include "url/gurl.h"
32 31
32 #if !defined(__has_feature) || !__has_feature(objc_arc)
33 #error "This file requires ARC support."
34 #endif
35
33 namespace { 36 namespace {
34 // The path in the temp directory containing documents that are to be opened in 37 // The path in the temp directory containing documents that are to be opened in
35 // other applications. 38 // other applications.
36 static NSString* const kDocumentsTempPath = @"OpenIn"; 39 static NSString* const kDocumentsTempPath = @"OpenIn";
37 40
38 static const int kHTTPResponseCodeSucceeded = 200; 41 static const int kHTTPResponseCodeSucceeded = 200;
39 42
40 // Duration of the show/hide animation for the |openInToolbar_|. 43 // Duration of the show/hide animation for the |openInToolbar_|.
41 const NSTimeInterval kOpenInToolbarAnimationDuration = 0.2; 44 const NSTimeInterval kOpenInToolbarAnimationDuration = 0.2;
42 45
(...skipping 14 matching lines...) Expand all
57 const CGFloat kOverlayedViewLabelWidthPercentage = 0.7; 60 const CGFloat kOverlayedViewLabelWidthPercentage = 0.7;
58 61
59 // Bottom margin for the label displayed on the |overlayedView_|. 62 // Bottom margin for the label displayed on the |overlayedView_|.
60 const CGFloat kOverlayedViewLabelBottomMargin = 60; 63 const CGFloat kOverlayedViewLabelBottomMargin = 60;
61 64
62 } // anonymous namespace 65 } // anonymous namespace
63 66
64 @interface OpenInController () { 67 @interface OpenInController () {
65 // AlertCoordinator for showing an alert if no applications were found to open 68 // AlertCoordinator for showing an alert if no applications were found to open
66 // the current document. 69 // the current document.
67 base::scoped_nsobject<AlertCoordinator> _alertCoordinator; 70 AlertCoordinator* _alertCoordinator;
68 } 71 }
69 72
70 // URLFetcher delegate method called when |fetcher_| completes a request. 73 // URLFetcher delegate method called when |fetcher_| completes a request.
71 - (void)urlFetchDidComplete:(const net::URLFetcher*)source; 74 - (void)urlFetchDidComplete:(const net::URLFetcher*)source;
72 // Ensures the destination directory is created and any contained obsolete files 75 // Ensures the destination directory is created and any contained obsolete files
73 // are deleted. Returns YES if the directory is created successfully. 76 // are deleted. Returns YES if the directory is created successfully.
74 + (BOOL)createDestinationDirectoryAndRemoveObsoleteFiles; 77 + (BOOL)createDestinationDirectoryAndRemoveObsoleteFiles;
75 // Starts downloading the file at path |kDocumentsTempPath| with the name 78 // Starts downloading the file at path |kDocumentsTempPath| with the name
76 // |suggestedFilename_|. 79 // |suggestedFilename_|.
77 - (void)startDownload; 80 - (void)startDownload;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 // |OpenInController| destroys the fetcher and cancels the callback. This is 145 // |OpenInController| destroys the fetcher and cancels the callback. This is
143 // why |OnURLFetchComplete| will neved be called after |owner_| is disabled. 146 // why |OnURLFetchComplete| will neved be called after |owner_| is disabled.
144 owner_ = nil; 147 owner_ = nil;
145 } 148 }
146 149
147 protected: 150 protected:
148 friend base::RefCountedThreadSafe<OpenInControllerBridge>; 151 friend base::RefCountedThreadSafe<OpenInControllerBridge>;
149 ~OpenInControllerBridge() override {} 152 ~OpenInControllerBridge() override {}
150 153
151 private: 154 private:
152 OpenInController* owner_; // weak 155 __weak OpenInController* owner_;
153 }; 156 };
154 157
155 @implementation OpenInController { 158 @implementation OpenInController {
156 // Bridge from C++ to Obj-C class. 159 // Bridge from C++ to Obj-C class.
157 scoped_refptr<OpenInControllerBridge> bridge_; 160 scoped_refptr<OpenInControllerBridge> bridge_;
158 161
159 // URL of the document. 162 // URL of the document.
160 GURL documentURL_; 163 GURL documentURL_;
161 164
162 // Controller for opening documents in other applications. 165 // Controller for opening documents in other applications.
163 base::scoped_nsobject<UIDocumentInteractionController> documentController_; 166 UIDocumentInteractionController* documentController_;
164 167
165 // Toolbar overlay to be displayed on tap. 168 // Toolbar overlay to be displayed on tap.
166 base::scoped_nsobject<OpenInToolbar> openInToolbar_; 169 OpenInToolbar* openInToolbar_;
167 170
168 // Timer used to automatically hide the |openInToolbar_| after a period. 171 // Timer used to automatically hide the |openInToolbar_| after a period.
169 base::scoped_nsobject<NSTimer> openInTimer_; 172 NSTimer* openInTimer_;
170 173
171 // Gesture recognizer to catch taps on the document. 174 // Gesture recognizer to catch taps on the document.
172 base::scoped_nsobject<UITapGestureRecognizer> tapRecognizer_; 175 UITapGestureRecognizer* tapRecognizer_;
173 176
174 // Suggested filename for the document. 177 // Suggested filename for the document.
175 base::scoped_nsobject<NSString> suggestedFilename_; 178 NSString* suggestedFilename_;
176 179
177 // Fetcher used to redownload the document and save it in the sandbox. 180 // Fetcher used to redownload the document and save it in the sandbox.
178 std::unique_ptr<net::URLFetcher> fetcher_; 181 std::unique_ptr<net::URLFetcher> fetcher_;
179 182
180 // CRWWebController used to check if the tap is not on a link and the 183 // CRWWebController used to check if the tap is not on a link and the
181 // |openInToolbar_| should be displayed. 184 // |openInToolbar_| should be displayed.
182 base::scoped_nsobject<CRWWebController> webController_; 185 CRWWebController* webController_;
183 186
184 // URLRequestContextGetter needed for the URLFetcher. 187 // URLRequestContextGetter needed for the URLFetcher.
185 scoped_refptr<net::URLRequestContextGetter> requestContext_; 188 scoped_refptr<net::URLRequestContextGetter> requestContext_;
186 189
187 // Spinner view displayed while the file is downloading. 190 // Spinner view displayed while the file is downloading.
188 base::scoped_nsobject<UIView> overlayedView_; 191 UIView* overlayedView_;
189 192
190 // The location where the "Open in..." menu is anchored. 193 // The location where the "Open in..." menu is anchored.
191 CGRect anchorLocation_; 194 CGRect anchorLocation_;
192 195
193 // YES if the file download was canceled. 196 // YES if the file download was canceled.
194 BOOL downloadCanceled_; 197 BOOL downloadCanceled_;
195 198
196 // YES if the OpenIn menu is displayed. 199 // YES if the OpenIn menu is displayed.
197 BOOL isOpenInMenuDisplayed_; 200 BOOL isOpenInMenuDisplayed_;
198 201
199 // YES if the toolbar is displayed. 202 // YES if the toolbar is displayed.
200 BOOL isOpenInToolbarDisplayed_; 203 BOOL isOpenInToolbarDisplayed_;
201 204
202 // Task runner on which file operations should happen. 205 // Task runner on which file operations should happen.
203 scoped_refptr<base::SequencedTaskRunner> sequencedTaskRunner_; 206 scoped_refptr<base::SequencedTaskRunner> sequencedTaskRunner_;
204
205 base::mac::ObjCPropertyReleaser propertyReleaser_OpenInController_;
206 } 207 }
207 208
208 - (id)initWithRequestContext:(net::URLRequestContextGetter*)requestContext 209 - (id)initWithRequestContext:(net::URLRequestContextGetter*)requestContext
209 webController:(CRWWebController*)webController { 210 webController:(CRWWebController*)webController {
210 self = [super init]; 211 self = [super init];
211 if (self) { 212 if (self) {
212 requestContext_ = requestContext; 213 requestContext_ = requestContext;
213 webController_.reset([webController retain]); 214 webController_ = webController;
214 tapRecognizer_.reset([[UITapGestureRecognizer alloc] 215 tapRecognizer_ = [[UITapGestureRecognizer alloc]
215 initWithTarget:self 216 initWithTarget:self
216 action:@selector(handleTapFrom:)]); 217 action:@selector(handleTapFrom:)];
217 [tapRecognizer_ setDelegate:self]; 218 [tapRecognizer_ setDelegate:self];
218 base::SequencedWorkerPool* pool = web::WebThread::GetBlockingPool(); 219 base::SequencedWorkerPool* pool = web::WebThread::GetBlockingPool();
219 sequencedTaskRunner_ = 220 sequencedTaskRunner_ =
220 pool->GetSequencedTaskRunner(pool->GetSequenceToken()); 221 pool->GetSequencedTaskRunner(pool->GetSequenceToken());
221 isOpenInMenuDisplayed_ = NO; 222 isOpenInMenuDisplayed_ = NO;
222 propertyReleaser_OpenInController_.Init(self, [OpenInController class]);
223 } 223 }
224 return self; 224 return self;
225 } 225 }
226 226
227 - (void)enableWithDocumentURL:(const GURL&)documentURL 227 - (void)enableWithDocumentURL:(const GURL&)documentURL
228 suggestedFilename:(NSString*)suggestedFilename { 228 suggestedFilename:(NSString*)suggestedFilename {
229 documentURL_ = GURL(documentURL); 229 documentURL_ = GURL(documentURL);
230 suggestedFilename_.reset([suggestedFilename retain]); 230 suggestedFilename_ = suggestedFilename;
231 [webController_ addGestureRecognizerToWebView:tapRecognizer_]; 231 [webController_ addGestureRecognizerToWebView:tapRecognizer_];
232 [self openInToolbar].alpha = 0.0f; 232 [self openInToolbar].alpha = 0.0f;
233 [webController_ addToolbarViewToWebView:[self openInToolbar]]; 233 [webController_ addToolbarViewToWebView:[self openInToolbar]];
234 [self showOpenInToolbar]; 234 [self showOpenInToolbar];
235 } 235 }
236 236
237 - (void)disable { 237 - (void)disable {
238 [self openInToolbar].alpha = 0.0f; 238 [self openInToolbar].alpha = 0.0f;
239 [openInTimer_ invalidate]; 239 [openInTimer_ invalidate];
240 if (bridge_.get()) 240 if (bridge_.get())
241 bridge_->OnOwnerDisabled(); 241 bridge_->OnOwnerDisabled();
242 bridge_ = nil; 242 bridge_ = nil;
243 [webController_ removeGestureRecognizerFromWebView:tapRecognizer_]; 243 [webController_ removeGestureRecognizerFromWebView:tapRecognizer_];
244 [webController_ removeToolbarViewFromWebView:[self openInToolbar]]; 244 [webController_ removeToolbarViewFromWebView:[self openInToolbar]];
245 [documentController_ dismissMenuAnimated:NO]; 245 [documentController_ dismissMenuAnimated:NO];
246 [documentController_ setDelegate:nil]; 246 [documentController_ setDelegate:nil];
247 documentURL_ = GURL(); 247 documentURL_ = GURL();
248 suggestedFilename_.reset(); 248 suggestedFilename_ = nil;
249 fetcher_.reset(); 249 fetcher_.reset();
250 } 250 }
251 251
252 - (void)detachFromWebController { 252 - (void)detachFromWebController {
253 [self disable]; 253 [self disable];
254 // Animation blocks may be keeping this object alive; don't extend the 254 // Animation blocks may be keeping this object alive; don't extend the
255 // lifetime of CRWWebController. 255 // lifetime of CRWWebController.
256 webController_.reset(); 256 webController_ = nil;
257 } 257 }
258 258
259 - (void)dealloc { 259 - (void)dealloc {
260 [self disable]; 260 [self disable];
261 [super dealloc];
262 } 261 }
263 262
264 - (void)handleTapFrom:(UIGestureRecognizer*)gestureRecognizer { 263 - (void)handleTapFrom:(UIGestureRecognizer*)gestureRecognizer {
265 if ([gestureRecognizer state] == UIGestureRecognizerStateEnded) { 264 if ([gestureRecognizer state] == UIGestureRecognizerStateEnded) {
266 if (isOpenInToolbarDisplayed_) { 265 if (isOpenInToolbarDisplayed_) {
267 [self hideOpenInToolbar]; 266 [self hideOpenInToolbar];
268 } else { 267 } else {
269 [self showOpenInToolbar]; 268 [self showOpenInToolbar];
270 } 269 }
271 } 270 }
272 } 271 }
273 272
274 - (void)showOpenInToolbar { 273 - (void)showOpenInToolbar {
275 if ([openInTimer_ isValid]) { 274 if ([openInTimer_ isValid]) {
276 [openInTimer_ setFireDate:([NSDate dateWithTimeIntervalSinceNow: 275 [openInTimer_ setFireDate:([NSDate dateWithTimeIntervalSinceNow:
277 kOpenInToolbarDisplayDuration])]; 276 kOpenInToolbarDisplayDuration])];
278 } else { 277 } else {
279 openInTimer_.reset( 278 openInTimer_ =
280 [[NSTimer scheduledTimerWithTimeInterval:kOpenInToolbarDisplayDuration 279 [NSTimer scheduledTimerWithTimeInterval:kOpenInToolbarDisplayDuration
281 target:self 280 target:self
282 selector:@selector(hideOpenInToolbar) 281 selector:@selector(hideOpenInToolbar)
283 userInfo:nil 282 userInfo:nil
284 repeats:NO] retain]); 283 repeats:NO];
285 UIView* openInToolbar = [self openInToolbar]; 284 UIView* openInToolbar = [self openInToolbar];
286 [UIView animateWithDuration:kOpenInToolbarAnimationDuration 285 [UIView animateWithDuration:kOpenInToolbarAnimationDuration
287 animations:^{ 286 animations:^{
288 [openInToolbar setAlpha:1.0]; 287 [openInToolbar setAlpha:1.0];
289 }]; 288 }];
290 } 289 }
291 isOpenInToolbarDisplayed_ = YES; 290 isOpenInToolbarDisplayed_ = YES;
292 } 291 }
293 292
294 - (void)hideOpenInToolbar { 293 - (void)hideOpenInToolbar {
(...skipping 30 matching lines...) Expand all
325 base::Callback<void(BOOL)> reply = base::Bind( 324 base::Callback<void(BOOL)> reply = base::Bind(
326 &OpenInControllerBridge::OnDestinationDirectoryCreated, bridge_); 325 &OpenInControllerBridge::OnDestinationDirectoryCreated, bridge_);
327 base::PostTaskAndReplyWithResult(sequencedTaskRunner_.get(), FROM_HERE, task, 326 base::PostTaskAndReplyWithResult(sequencedTaskRunner_.get(), FROM_HERE, task,
328 reply); 327 reply);
329 } 328 }
330 329
331 - (void)startDownload { 330 - (void)startDownload {
332 NSString* tempDirPath = [NSTemporaryDirectory() 331 NSString* tempDirPath = [NSTemporaryDirectory()
333 stringByAppendingPathComponent:kDocumentsTempPath]; 332 stringByAppendingPathComponent:kDocumentsTempPath];
334 NSString* filePath = 333 NSString* filePath =
335 [tempDirPath stringByAppendingPathComponent:suggestedFilename_.get()]; 334 [tempDirPath stringByAppendingPathComponent:suggestedFilename_];
336 335
337 // In iPad the toolbar has to be displayed to anchor the "Open in" menu. 336 // In iPad the toolbar has to be displayed to anchor the "Open in" menu.
338 if (!IsIPadIdiom()) 337 if (!IsIPadIdiom())
339 [self hideOpenInToolbar]; 338 [self hideOpenInToolbar];
340 339
341 // Show an overlayed view to indicate a download is in progress. On tap this 340 // Show an overlayed view to indicate a download is in progress. On tap this
342 // view can be dismissed and the download canceled. 341 // view can be dismissed and the download canceled.
343 [self showDownloadOverlayView]; 342 [self showDownloadOverlayView];
344 downloadCanceled_ = NO; 343 downloadCanceled_ = NO;
345 344
(...skipping 18 matching lines...) Expand all
364 [self removeOverlayedView]; 363 [self removeOverlayedView];
365 if (IsIPadIdiom()) 364 if (IsIPadIdiom())
366 [self hideOpenInToolbar]; 365 [self hideOpenInToolbar];
367 downloadCanceled_ = YES; 366 downloadCanceled_ = YES;
368 } 367 }
369 368
370 - (void)removeOverlayedView { 369 - (void)removeOverlayedView {
371 if (!overlayedView_) 370 if (!overlayedView_)
372 return; 371 return;
373 372
374 UIView* overlayedView = overlayedView_.get(); 373 UIView* overlayedView = overlayedView_;
375 [UIView animateWithDuration:kOverlayViewAnimationDuration 374 [UIView animateWithDuration:kOverlayViewAnimationDuration
376 animations:^{ 375 animations:^{
377 [overlayedView setAlpha:0.0]; 376 [overlayedView setAlpha:0.0];
378 } 377 }
379 completion:^(BOOL finished) { 378 completion:^(BOOL finished) {
380 [overlayedView removeFromSuperview]; 379 [overlayedView removeFromSuperview];
381 }]; 380 }];
382 overlayedView_.reset(); 381 overlayedView_ = nil;
383 } 382 }
384 383
385 - (void)showErrorWithMessage:(NSString*)message { 384 - (void)showErrorWithMessage:(NSString*)message {
386 UIViewController* topViewController = 385 UIViewController* topViewController =
387 [[[UIApplication sharedApplication] keyWindow] rootViewController]; 386 [[[UIApplication sharedApplication] keyWindow] rootViewController];
388 387
389 _alertCoordinator.reset([[AlertCoordinator alloc] 388 _alertCoordinator =
390 initWithBaseViewController:topViewController 389 [[AlertCoordinator alloc] initWithBaseViewController:topViewController
391 title:nil 390 title:nil
392 message:message]); 391 message:message];
393 392
394 [_alertCoordinator addItemWithTitle:l10n_util::GetNSString(IDS_OK) 393 [_alertCoordinator addItemWithTitle:l10n_util::GetNSString(IDS_OK)
395 action:nil 394 action:nil
396 style:UIAlertActionStyleDefault]; 395 style:UIAlertActionStyleDefault];
397 396
398 [_alertCoordinator start]; 397 [_alertCoordinator start];
399 } 398 }
400 399
401 - (void)presentOpenInMenuForFileAtURL:(NSURL*)fileURL { 400 - (void)presentOpenInMenuForFileAtURL:(NSURL*)fileURL {
402 if (!webController_) 401 if (!webController_)
403 return; 402 return;
404 403
405 if (requestContext_.get()) { 404 if (requestContext_.get()) {
406 // |requestContext_| is nil only if this is called from a unit test, in 405 // |requestContext_| is nil only if this is called from a unit test, in
407 // which case the |documentController_| was set already. 406 // which case the |documentController_| was set already.
408 documentController_.reset([[UIDocumentInteractionController 407 documentController_ =
409 interactionControllerWithURL:fileURL] retain]); 408 [UIDocumentInteractionController interactionControllerWithURL:fileURL];
410 } 409 }
411 410
412 // TODO(cgrigoruta): The UTI is hardcoded for now, change this when we add 411 // TODO(cgrigoruta): The UTI is hardcoded for now, change this when we add
413 // support for other file types as well. 412 // support for other file types as well.
414 [documentController_ setUTI:@"com.adobe.pdf"]; 413 [documentController_ setUTI:@"com.adobe.pdf"];
415 [documentController_ setDelegate:self]; 414 [documentController_ setDelegate:self];
416 BOOL success = 415 BOOL success =
417 [documentController_ presentOpenInMenuFromRect:anchorLocation_ 416 [documentController_ presentOpenInMenuFromRect:anchorLocation_
418 inView:[webController_ view] 417 inView:[webController_ view]
419 animated:YES]; 418 animated:YES];
420 if (requestContext_.get()) { 419 if (requestContext_.get()) {
421 [self removeOverlayedView]; 420 [self removeOverlayedView];
422 if (!success) { 421 if (!success) {
423 if (IsIPadIdiom()) 422 if (IsIPadIdiom())
424 [self hideOpenInToolbar]; 423 [self hideOpenInToolbar];
425 NSString* errorMessage = 424 NSString* errorMessage =
426 l10n_util::GetNSStringWithFixup(IDS_IOS_OPEN_IN_NO_APPS_REGISTERED); 425 l10n_util::GetNSStringWithFixup(IDS_IOS_OPEN_IN_NO_APPS_REGISTERED);
427 [self showErrorWithMessage:errorMessage]; 426 [self showErrorWithMessage:errorMessage];
428 } else { 427 } else {
429 isOpenInMenuDisplayed_ = YES; 428 isOpenInMenuDisplayed_ = YES;
430 } 429 }
431 } 430 }
432 } 431 }
433 432
434 - (void)showDownloadOverlayView { 433 - (void)showDownloadOverlayView {
435 UIViewController* topViewController = 434 UIViewController* topViewController =
436 [[[UIApplication sharedApplication] keyWindow] rootViewController]; 435 [[[UIApplication sharedApplication] keyWindow] rootViewController];
437 UIView* topView = topViewController.view; 436 UIView* topView = topViewController.view;
438 overlayedView_.reset([[UIView alloc] initWithFrame:[topView bounds]]); 437 overlayedView_ = [[UIView alloc] initWithFrame:[topView bounds]];
439 [overlayedView_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | 438 [overlayedView_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth |
440 UIViewAutoresizingFlexibleHeight)]; 439 UIViewAutoresizingFlexibleHeight)];
441 base::scoped_nsobject<UIView> grayBackgroundView( 440 UIView* grayBackgroundView =
442 [[UIView alloc] initWithFrame:[overlayedView_ frame]]); 441 [[UIView alloc] initWithFrame:[overlayedView_ frame]];
443 [grayBackgroundView setBackgroundColor:[UIColor darkGrayColor]]; 442 [grayBackgroundView setBackgroundColor:[UIColor darkGrayColor]];
444 [grayBackgroundView setAlpha:kOverlayedViewBackgroundAlpha]; 443 [grayBackgroundView setAlpha:kOverlayedViewBackgroundAlpha];
445 [grayBackgroundView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | 444 [grayBackgroundView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth |
446 UIViewAutoresizingFlexibleHeight)]; 445 UIViewAutoresizingFlexibleHeight)];
447 [overlayedView_ addSubview:grayBackgroundView]; 446 [overlayedView_ addSubview:grayBackgroundView];
448 447
449 base::scoped_nsobject<UIActivityIndicatorView> spinner([ 448 UIActivityIndicatorView* spinner = [[UIActivityIndicatorView alloc]
450 [UIActivityIndicatorView alloc] 449 initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
451 initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]);
452 [spinner setFrame:[overlayedView_ frame]]; 450 [spinner setFrame:[overlayedView_ frame]];
453 [spinner setHidesWhenStopped:YES]; 451 [spinner setHidesWhenStopped:YES];
454 [spinner setUserInteractionEnabled:NO]; 452 [spinner setUserInteractionEnabled:NO];
455 [spinner startAnimating]; 453 [spinner startAnimating];
456 [spinner setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | 454 [spinner setAutoresizingMask:(UIViewAutoresizingFlexibleWidth |
457 UIViewAutoresizingFlexibleHeight)]; 455 UIViewAutoresizingFlexibleHeight)];
458 [overlayedView_ addSubview:spinner]; 456 [overlayedView_ addSubview:spinner];
459 457
460 base::scoped_nsobject<UILabel> label([[UILabel alloc] init]); 458 UILabel* label = [[UILabel alloc] init];
461 [label setTextColor:[UIColor whiteColor]]; 459 [label setTextColor:[UIColor whiteColor]];
462 [label setFont:GetUIFont(FONT_HELVETICA, true, kLabelTextSize)]; 460 [label setFont:GetUIFont(FONT_HELVETICA, true, kLabelTextSize)];
463 [label setNumberOfLines:0]; 461 [label setNumberOfLines:0];
464 [label setShadowColor:[UIColor blackColor]]; 462 [label setShadowColor:[UIColor blackColor]];
465 [label setShadowOffset:CGSizeMake(0.0, 1.0)]; 463 [label setShadowOffset:CGSizeMake(0.0, 1.0)];
466 [label setBackgroundColor:[UIColor clearColor]]; 464 [label setBackgroundColor:[UIColor clearColor]];
467 [label setText:l10n_util::GetNSString(IDS_IOS_OPEN_IN_FILE_DOWNLOAD_CANCEL)]; 465 [label setText:l10n_util::GetNSString(IDS_IOS_OPEN_IN_FILE_DOWNLOAD_CANCEL)];
468 [label setLineBreakMode:NSLineBreakByWordWrapping]; 466 [label setLineBreakMode:NSLineBreakByWordWrapping];
469 [label setTextAlignment:NSTextAlignmentCenter]; 467 [label setTextAlignment:NSTextAlignmentCenter];
470 CGFloat labelWidth = 468 CGFloat labelWidth =
471 [overlayedView_ frame].size.width * kOverlayedViewLabelWidthPercentage; 469 [overlayedView_ frame].size.width * kOverlayedViewLabelWidthPercentage;
472 CGFloat originX = ([overlayedView_ frame].size.width - labelWidth) / 2; 470 CGFloat originX = ([overlayedView_ frame].size.width - labelWidth) / 2;
473 471
474 CGFloat labelHeight = 472 CGFloat labelHeight =
475 [[label text] cr_boundingSizeWithSize:CGSizeMake(labelWidth, CGFLOAT_MAX) 473 [[label text] cr_boundingSizeWithSize:CGSizeMake(labelWidth, CGFLOAT_MAX)
476 font:[label font]] 474 font:[label font]]
477 .height; 475 .height;
478 CGFloat originY = 476 CGFloat originY =
479 [overlayedView_ center].y - labelHeight - kOverlayedViewLabelBottomMargin; 477 [overlayedView_ center].y - labelHeight - kOverlayedViewLabelBottomMargin;
480 [label setFrame:CGRectMake(originX, originY, labelWidth, labelHeight)]; 478 [label setFrame:CGRectMake(originX, originY, labelWidth, labelHeight)];
481 [overlayedView_ addSubview:label]; 479 [overlayedView_ addSubview:label];
482 480
483 base::scoped_nsobject<UITapGestureRecognizer> tapRecognizer( 481 UITapGestureRecognizer* tapRecognizer = [[UITapGestureRecognizer alloc]
484 [[UITapGestureRecognizer alloc] 482 initWithTarget:self
485 initWithTarget:self 483 action:@selector(handleTapOnOverlayedView:)];
486 action:@selector(handleTapOnOverlayedView:)]);
487 [tapRecognizer setDelegate:self]; 484 [tapRecognizer setDelegate:self];
488 [overlayedView_ addGestureRecognizer:tapRecognizer]; 485 [overlayedView_ addGestureRecognizer:tapRecognizer];
489 486
490 [overlayedView_ setAlpha:0.0]; 487 [overlayedView_ setAlpha:0.0];
491 [topView addSubview:overlayedView_]; 488 [topView addSubview:overlayedView_];
492 UIView* overlayedView = overlayedView_.get(); 489 UIView* overlayedView = overlayedView_;
493 [UIView animateWithDuration:kOverlayViewAnimationDuration 490 [UIView animateWithDuration:kOverlayViewAnimationDuration
494 animations:^{ 491 animations:^{
495 [overlayedView setAlpha:1.0]; 492 [overlayedView setAlpha:1.0];
496 }]; 493 }];
497 } 494 }
498 495
499 - (UIView*)openInToolbar { 496 - (UIView*)openInToolbar {
500 if (!openInToolbar_) { 497 if (!openInToolbar_) {
501 openInToolbar_.reset([[OpenInToolbar alloc] 498 openInToolbar_ = [[OpenInToolbar alloc]
502 initWithTarget:self 499 initWithTarget:self
503 action:@selector(exportFileWithOpenInMenuAnchoredAt:)]); 500 action:@selector(exportFileWithOpenInMenuAnchoredAt:)];
504 } 501 }
505 return openInToolbar_.get(); 502 return openInToolbar_;
506 } 503 }
507 504
508 #pragma mark - 505 #pragma mark -
509 #pragma mark File management 506 #pragma mark File management
510 507
511 - (void)removeDocumentAtPath:(NSString*)path { 508 - (void)removeDocumentAtPath:(NSString*)path {
512 base::ThreadRestrictions::AssertIOAllowed(); 509 base::ThreadRestrictions::AssertIOAllowed();
513 NSFileManager* fileManager = [NSFileManager defaultManager]; 510 NSFileManager* fileManager = [NSFileManager defaultManager];
514 NSError* error = nil; 511 NSError* error = nil;
515 if (![fileManager removeItemAtPath:path error:&error]) { 512 if (![fileManager removeItemAtPath:path error:&error]) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 - (void)urlFetchDidComplete:(const net::URLFetcher*)fetcher { 572 - (void)urlFetchDidComplete:(const net::URLFetcher*)fetcher {
576 DCHECK(fetcher); 573 DCHECK(fetcher);
577 if (requestContext_.get()) 574 if (requestContext_.get())
578 DCHECK_CURRENTLY_ON(web::WebThread::UI); 575 DCHECK_CURRENTLY_ON(web::WebThread::UI);
579 base::FilePath filePath; 576 base::FilePath filePath;
580 if (fetcher->GetResponseCode() == kHTTPResponseCodeSucceeded && 577 if (fetcher->GetResponseCode() == kHTTPResponseCodeSucceeded &&
581 fetcher->GetResponseAsFilePath(true, &filePath)) { 578 fetcher->GetResponseAsFilePath(true, &filePath)) {
582 NSURL* fileURL = 579 NSURL* fileURL =
583 [NSURL fileURLWithPath:base::SysUTF8ToNSString(filePath.value())]; 580 [NSURL fileURLWithPath:base::SysUTF8ToNSString(filePath.value())];
584 if (downloadCanceled_) { 581 if (downloadCanceled_) {
585 sequencedTaskRunner_->PostTask(FROM_HERE, base::BindBlock(^{ 582 sequencedTaskRunner_->PostTask(FROM_HERE, base::BindBlockArc(^{
586 [self 583 [self
587 removeDocumentAtPath:[fileURL path]]; 584 removeDocumentAtPath:[fileURL path]];
588 })); 585 }));
589 } else { 586 } else {
590 [self presentOpenInMenuForFileAtURL:fileURL]; 587 [self presentOpenInMenuForFileAtURL:fileURL];
591 } 588 }
592 } else if (!downloadCanceled_) { 589 } else if (!downloadCanceled_) {
593 if (IsIPadIdiom()) 590 if (IsIPadIdiom())
594 [self hideOpenInToolbar]; 591 [self hideOpenInToolbar];
595 [self removeOverlayedView]; 592 [self removeOverlayedView];
596 [self showErrorWithMessage:l10n_util::GetNSStringWithFixup( 593 [self showErrorWithMessage:l10n_util::GetNSStringWithFixup(
597 IDS_IOS_OPEN_IN_FILE_DOWNLOAD_FAILED)]; 594 IDS_IOS_OPEN_IN_FILE_DOWNLOAD_FAILED)];
598 } 595 }
599 } 596 }
600 597
601 #pragma mark - 598 #pragma mark -
602 #pragma mark UIDocumentInteractionControllerDelegate Methods 599 #pragma mark UIDocumentInteractionControllerDelegate Methods
603 600
604 - (void)documentInteractionController:(UIDocumentInteractionController*)contr 601 - (void)documentInteractionController:(UIDocumentInteractionController*)contr
605 didEndSendingToApplication:(NSString*)application { 602 didEndSendingToApplication:(NSString*)application {
606 sequencedTaskRunner_->PostTask(FROM_HERE, base::BindBlock(^{ 603 sequencedTaskRunner_->PostTask(FROM_HERE, base::BindBlockArc(^{
607 [self 604 [self
608 removeDocumentAtPath:[[contr URL] path]]; 605 removeDocumentAtPath:[[contr URL] path]];
609 })); 606 }));
610 if (IsIPadIdiom()) { 607 if (IsIPadIdiom()) {
611 // Call the |documentInteractionControllerDidDismissOpenInMenu:| method 608 // Call the |documentInteractionControllerDidDismissOpenInMenu:| method
612 // as this is not called on the iPad after the document has been opened 609 // as this is not called on the iPad after the document has been opened
613 // in another application. 610 // in another application.
614 [self documentInteractionControllerDidDismissOpenInMenu:contr]; 611 [self documentInteractionControllerDidDismissOpenInMenu:contr];
615 } 612 }
616 } 613 }
617 614
618 - (void)documentInteractionControllerDidDismissOpenInMenu: 615 - (void)documentInteractionControllerDidDismissOpenInMenu:
619 (UIDocumentInteractionController*)controller { 616 (UIDocumentInteractionController*)controller {
620 if (!IsIPadIdiom()) { 617 if (!IsIPadIdiom()) {
621 isOpenInMenuDisplayed_ = NO; 618 isOpenInMenuDisplayed_ = NO;
622 // On the iPhone the |openInToolber_| is hidden already. 619 // On the iPhone the |openInToolber_| is hidden already.
623 return; 620 return;
624 } 621 }
625 622
626 // On iPad this method is called whenever the device changes orientation, 623 // On iPad this method is called whenever the device changes orientation,
627 // even thought the OpenIn menu is not displayed. To distinguish the cases 624 // even thought the OpenIn menu is not displayed. To distinguish the cases
628 // when this method is called after the OpenIn menu is dismissed, we 625 // when this method is called after the OpenIn menu is dismissed, we
629 // check the BOOL |isOpenInMenuDisplayed|. 626 // check the BOOL |isOpenInMenuDisplayed|.
630 if (isOpenInMenuDisplayed_) { 627 if (isOpenInMenuDisplayed_) {
631 openInTimer_.reset( 628 openInTimer_ =
632 [[NSTimer scheduledTimerWithTimeInterval:kOpenInToolbarDisplayDuration 629 [NSTimer scheduledTimerWithTimeInterval:kOpenInToolbarDisplayDuration
633 target:self 630 target:self
634 selector:@selector(hideOpenInToolbar) 631 selector:@selector(hideOpenInToolbar)
635 userInfo:nil 632 userInfo:nil
636 repeats:NO] retain]); 633 repeats:NO];
637 } 634 }
638 isOpenInMenuDisplayed_ = NO; 635 isOpenInMenuDisplayed_ = NO;
639 } 636 }
640 637
641 #pragma mark - 638 #pragma mark -
642 #pragma mark UIGestureRecognizerDelegate Methods 639 #pragma mark UIGestureRecognizerDelegate Methods
643 640
644 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer*)gestureRecognizer { 641 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer*)gestureRecognizer {
645 if ([gestureRecognizer.view isEqual:overlayedView_]) 642 if ([gestureRecognizer.view isEqual:overlayedView_])
646 return YES; 643 return YES;
647 644
648 CGPoint location = [gestureRecognizer locationInView:[self openInToolbar]]; 645 CGPoint location = [gestureRecognizer locationInView:[self openInToolbar]];
649 return ![[self openInToolbar] pointInside:location withEvent:nil]; 646 return ![[self openInToolbar] pointInside:location withEvent:nil];
650 } 647 }
651 648
652 #pragma mark - TestingAditions 649 #pragma mark - TestingAditions
653 650
654 - (void)setDocumentInteractionController: 651 - (void)setDocumentInteractionController:
655 (UIDocumentInteractionController*)controller { 652 (UIDocumentInteractionController*)controller {
656 documentController_.reset([controller retain]); 653 documentController_ = controller;
657 } 654 }
658 655
659 - (NSString*)suggestedFilename { 656 - (NSString*)suggestedFilename {
660 return suggestedFilename_.get(); 657 return suggestedFilename_;
661 } 658 }
662 659
663 @end 660 @end
OLDNEW
« no previous file with comments | « ios/chrome/browser/ui/key_commands_provider.mm ('k') | ios/chrome/browser/ui/open_in_toolbar.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698