OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/bookmarks/bookmark_home_tablet_ntp_controller.h" | 5 #import "ios/chrome/browser/ui/bookmarks/bookmark_home_tablet_ntp_controller.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/ios/block_types.h" | 9 #include "base/ios/block_types.h" |
10 #import "base/ios/weak_nsobject.h" | |
11 #include "base/logging.h" | 10 #include "base/logging.h" |
12 #include "base/mac/objc_property_releaser.h" | |
13 #include "base/mac/scoped_nsobject.h" | |
14 #include "base/metrics/user_metrics.h" | 11 #include "base/metrics/user_metrics.h" |
15 #include "base/metrics/user_metrics_action.h" | 12 #include "base/metrics/user_metrics_action.h" |
16 #include "base/strings/sys_string_conversions.h" | 13 #include "base/strings/sys_string_conversions.h" |
17 #include "components/bookmarks/browser/bookmark_model.h" | 14 #include "components/bookmarks/browser/bookmark_model.h" |
18 #include "components/strings/grit/components_strings.h" | 15 #include "components/strings/grit/components_strings.h" |
19 #include "google_apis/gaia/google_service_auth_error.h" | 16 #include "google_apis/gaia/google_service_auth_error.h" |
20 #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" | 17 #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" |
21 #include "ios/chrome/browser/bookmarks/bookmarks_utils.h" | 18 #include "ios/chrome/browser/bookmarks/bookmarks_utils.h" |
22 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" | 19 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" |
23 #import "ios/chrome/browser/metrics/new_tab_page_uma.h" | 20 #import "ios/chrome/browser/metrics/new_tab_page_uma.h" |
(...skipping 15 matching lines...) Expand all Loading... |
39 #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" | 36 #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" |
40 #import "ios/chrome/browser/ui/rtl_geometry.h" | 37 #import "ios/chrome/browser/ui/rtl_geometry.h" |
41 #import "ios/chrome/browser/ui/uikit_ui_util.h" | 38 #import "ios/chrome/browser/ui/uikit_ui_util.h" |
42 #import "ios/chrome/browser/ui/url_loader.h" | 39 #import "ios/chrome/browser/ui/url_loader.h" |
43 #include "ios/chrome/grit/ios_strings.h" | 40 #include "ios/chrome/grit/ios_strings.h" |
44 #include "ios/web/public/referrer.h" | 41 #include "ios/web/public/referrer.h" |
45 #include "ui/base/l10n/l10n_util.h" | 42 #include "ui/base/l10n/l10n_util.h" |
46 #include "ui/base/l10n/l10n_util_mac.h" | 43 #include "ui/base/l10n/l10n_util_mac.h" |
47 #include "ui/base/page_transition_types.h" | 44 #include "ui/base/page_transition_types.h" |
48 | 45 |
| 46 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 47 #error "This file requires ARC support." |
| 48 #endif |
| 49 |
49 using bookmarks::BookmarkNode; | 50 using bookmarks::BookmarkNode; |
50 | 51 |
51 namespace { | 52 namespace { |
52 // The width of the bookmark menu, displaying the different sections. | 53 // The width of the bookmark menu, displaying the different sections. |
53 const CGFloat kMenuWidth = 264.0; | 54 const CGFloat kMenuWidth = 264.0; |
54 // The margin on top to the navigation bar. | 55 // The margin on top to the navigation bar. |
55 const CGFloat kNavigationBarTopMargin = 8.0; | 56 const CGFloat kNavigationBarTopMargin = 8.0; |
56 } // namespace | 57 } // namespace |
57 | 58 |
58 // A simple UIView subclass to pass on relayout information to its delegate. | 59 // A simple UIView subclass to pass on relayout information to its delegate. |
59 @protocol ContentViewDelegate<NSObject> | 60 @protocol ContentViewDelegate<NSObject> |
60 - (void)willLayoutSubviews; | 61 - (void)willLayoutSubviews; |
61 @end | 62 @end |
62 | 63 |
63 @interface ContentView : UIView | 64 @interface ContentView : UIView |
64 @property(nonatomic, assign) id<ContentViewDelegate> delegate; | 65 @property(nonatomic, weak) id<ContentViewDelegate> delegate; |
65 @end | 66 @end |
66 | 67 |
67 @implementation ContentView | 68 @implementation ContentView |
68 @synthesize delegate = _delegate; | 69 @synthesize delegate = _delegate; |
69 | 70 |
70 - (void)layoutSubviews { | 71 - (void)layoutSubviews { |
71 [self.delegate willLayoutSubviews]; | 72 [self.delegate willLayoutSubviews]; |
72 [super layoutSubviews]; | 73 [super layoutSubviews]; |
73 } | 74 } |
74 @end | 75 @end |
75 | 76 |
76 @interface BookmarkHomeTabletNTPController ()< | 77 @interface BookmarkHomeTabletNTPController ()< |
77 BookmarkEditViewControllerDelegate, | 78 BookmarkEditViewControllerDelegate, |
78 BookmarkFolderCollectionViewDelegate, | 79 BookmarkFolderCollectionViewDelegate, |
79 BookmarkFolderEditorViewControllerDelegate, | 80 BookmarkFolderEditorViewControllerDelegate, |
80 BookmarkFolderViewControllerDelegate, | 81 BookmarkFolderViewControllerDelegate, |
81 BookmarkMenuViewDelegate, | 82 BookmarkMenuViewDelegate, |
82 BookmarkModelBridgeObserver, | 83 BookmarkModelBridgeObserver, |
83 BookmarkPromoControllerDelegate, | 84 BookmarkPromoControllerDelegate, |
84 ContentViewDelegate> { | 85 ContentViewDelegate> { |
85 // Bridge to register for bookmark changes. | 86 // Bridge to register for bookmark changes. |
86 std::unique_ptr<bookmarks::BookmarkModelBridge> _bridge; | 87 std::unique_ptr<bookmarks::BookmarkModelBridge> _bridge; |
87 ios::ChromeBrowserState* _browserState; // Weak. | 88 ios::ChromeBrowserState* _browserState; // Weak. |
88 id<UrlLoader> _loader; // Weak. | 89 __weak id<UrlLoader> _loader; |
89 | 90 |
90 // The following 2 ivars both represent the set of nodes being edited. | 91 // The following 2 ivars both represent the set of nodes being edited. |
91 // The set is for fast lookup. | 92 // The set is for fast lookup. |
92 // The vector maintains the order that edit nodes were added. | 93 // The vector maintains the order that edit nodes were added. |
93 // Use the relevant instance methods to modify these two ivars in tandem. | 94 // Use the relevant instance methods to modify these two ivars in tandem. |
94 // DO NOT modify these two ivars directly. | 95 // DO NOT modify these two ivars directly. |
95 std::set<const BookmarkNode*> _editNodes; | 96 std::set<const BookmarkNode*> _editNodes; |
96 std::vector<const BookmarkNode*> _editNodesOrdered; | 97 std::vector<const BookmarkNode*> _editNodesOrdered; |
97 | |
98 base::mac::ObjCPropertyReleaser | |
99 _propertyReleaser_BookmarkHomeTabletNTPController; | |
100 } | 98 } |
101 | 99 |
102 @property(nonatomic, retain) BookmarkPanelView* panelView; | 100 @property(nonatomic, strong) BookmarkPanelView* panelView; |
103 | 101 |
104 #pragma mark - Properties and methods akin to BookmarkHomeViewController | 102 #pragma mark - Properties and methods akin to BookmarkHomeViewController |
105 | 103 |
106 // Whether the view controller is in editing mode. | 104 // Whether the view controller is in editing mode. |
107 @property(nonatomic, assign) BOOL editing; | 105 @property(nonatomic, assign) BOOL editing; |
108 // The set of edited index paths. | 106 // The set of edited index paths. |
109 @property(nonatomic, retain) NSMutableArray* editIndexPaths; | 107 @property(nonatomic, strong) NSMutableArray* editIndexPaths; |
110 // The bookmark model used. | 108 // The bookmark model used. |
111 @property(nonatomic, assign, readonly) bookmarks::BookmarkModel* bookmarks; | 109 @property(nonatomic, assign, readonly) bookmarks::BookmarkModel* bookmarks; |
112 // The user's browser state model used. | 110 // The user's browser state model used. |
113 @property(nonatomic, assign, readonly) | 111 @property(nonatomic, assign, readonly) |
114 ios::ChromeBrowserState* browserState; // from superclass. | 112 ios::ChromeBrowserState* browserState; // from superclass. |
115 | 113 |
116 // Replaces |_editNodes| and |_editNodesOrdered| with new container objects. | 114 // Replaces |_editNodes| and |_editNodesOrdered| with new container objects. |
117 - (void)resetEditNodes; | 115 - (void)resetEditNodes; |
118 // Adds |node| corresponding to a |cell| if it isn't already present. | 116 // Adds |node| corresponding to a |cell| if it isn't already present. |
119 - (void)insertEditNode:(const BookmarkNode*)node | 117 - (void)insertEditNode:(const BookmarkNode*)node |
120 atIndexPath:(NSIndexPath*)indexPath; | 118 atIndexPath:(NSIndexPath*)indexPath; |
121 // Removes |node| corresponding to a |cell| if it's present. | 119 // Removes |node| corresponding to a |cell| if it's present. |
122 - (void)removeEditNode:(const BookmarkNode*)node | 120 - (void)removeEditNode:(const BookmarkNode*)node |
123 atIndexPath:(NSIndexPath*)indexPath; | 121 atIndexPath:(NSIndexPath*)indexPath; |
124 // This method updates the property, and resets the edit nodes. | 122 // This method updates the property, and resets the edit nodes. |
125 - (void)setEditing:(BOOL)editing animated:(BOOL)animated; | 123 - (void)setEditing:(BOOL)editing animated:(BOOL)animated; |
126 | 124 |
127 #pragma mark - Properties and methods akin to BookmarkHomeHandsetViewController | 125 #pragma mark - Properties and methods akin to BookmarkHomeHandsetViewController |
128 | 126 |
129 // This views holds the primary content of this controller. At any point in | 127 // This views holds the primary content of this controller. At any point in |
130 // time, it contains exactly one of the BookmarkCollectionView subclasses. | 128 // time, it contains exactly one of the BookmarkCollectionView subclasses. |
131 @property(nonatomic, retain) ContentView* contentView; | 129 @property(nonatomic, strong) ContentView* contentView; |
132 // The possible views that can be shown from the menu. | 130 // The possible views that can be shown from the menu. |
133 @property(nonatomic, retain) BookmarkFolderCollectionView* folderView; | 131 @property(nonatomic, strong) BookmarkFolderCollectionView* folderView; |
134 // This view is created and used if the model is not fully loaded yet by the | 132 // This view is created and used if the model is not fully loaded yet by the |
135 // time this controller starts. | 133 // time this controller starts. |
136 @property(nonatomic, retain) BookmarkHomeWaitingView* waitForModelView; | 134 @property(nonatomic, strong) BookmarkHomeWaitingView* waitForModelView; |
137 | 135 |
138 // The menu with all the folders and special entries. | 136 // The menu with all the folders and special entries. |
139 @property(nonatomic, retain) BookmarkMenuView* menuView; | 137 @property(nonatomic, strong) BookmarkMenuView* menuView; |
140 // At any point in time, there is exactly one collection view whose view is part | 138 // At any point in time, there is exactly one collection view whose view is part |
141 // of the view hierarchy. This property determines which collection view is | 139 // of the view hierarchy. This property determines which collection view is |
142 // visible. Not by accident, this property also reflects the selected menu item | 140 // visible. Not by accident, this property also reflects the selected menu item |
143 // in the BookmarkMenuView. | 141 // in the BookmarkMenuView. |
144 @property(nonatomic, retain) BookmarkMenuItem* primaryMenuItem; | 142 @property(nonatomic, strong) BookmarkMenuItem* primaryMenuItem; |
145 // When the view is first shown on the screen, this property represents the | 143 // When the view is first shown on the screen, this property represents the |
146 // cached value of the y of the content offset of the primary view. This | 144 // cached value of the y of the content offset of the primary view. This |
147 // property is set to nil after it is used. | 145 // property is set to nil after it is used. |
148 @property(nonatomic, retain) | 146 @property(nonatomic, strong) |
149 NSNumber* cachedContentPosition; // FIXME: INACTIVE | 147 NSNumber* cachedContentPosition; // FIXME: INACTIVE |
150 | 148 |
151 // The navigation bar sits on top of the main content. | 149 // The navigation bar sits on top of the main content. |
152 @property(nonatomic, retain) BookmarkNavigationBar* navigationBar; | 150 @property(nonatomic, strong) BookmarkNavigationBar* navigationBar; |
153 // The editing bar present when items are selected. | 151 // The editing bar present when items are selected. |
154 @property(nonatomic, retain) BookmarkEditingBar* editingBar; | 152 @property(nonatomic, strong) BookmarkEditingBar* editingBar; |
155 | 153 |
156 // The action sheet coordinator used when trying to edit a single bookmark. | 154 // The action sheet coordinator used when trying to edit a single bookmark. |
157 @property(nonatomic, retain) ActionSheetCoordinator* actionSheetCoordinator; | 155 @property(nonatomic, strong) ActionSheetCoordinator* actionSheetCoordinator; |
158 // The view controller used to view and edit a single bookmark. | 156 // The view controller used to view and edit a single bookmark. |
159 @property(nonatomic, retain) BookmarkEditViewController* editViewController; | 157 @property(nonatomic, strong) BookmarkEditViewController* editViewController; |
160 // The view controller used to pick a folder in which to move the selected | 158 // The view controller used to pick a folder in which to move the selected |
161 // bookmarks. | 159 // bookmarks. |
162 @property(nonatomic, retain) BookmarkFolderViewController* folderSelector; | 160 @property(nonatomic, strong) BookmarkFolderViewController* folderSelector; |
163 // The view controller to present when editing the current folder. | 161 // The view controller to present when editing the current folder. |
164 @property(nonatomic, retain) | 162 @property(nonatomic, strong) |
165 BookmarkFolderEditorViewController* folderEditor; // FIX | 163 BookmarkFolderEditorViewController* folderEditor; // FIX |
166 // The controller managing the display of the promo cell and the promo view | 164 // The controller managing the display of the promo cell and the promo view |
167 // controller. | 165 // controller. |
168 @property(nonatomic, retain) BookmarkPromoController* bookmarkPromoController; | 166 @property(nonatomic, strong) BookmarkPromoController* bookmarkPromoController; |
169 | 167 |
170 #pragma mark Specific to this class. | 168 #pragma mark Specific to this class. |
171 | 169 |
172 // Either the menu or the primaryView can scrollToTop. | 170 // Either the menu or the primaryView can scrollToTop. |
173 @property(nonatomic, assign) BOOL scrollToTop; | 171 @property(nonatomic, assign) BOOL scrollToTop; |
174 | 172 |
175 // Opens the url. | 173 // Opens the url. |
176 - (void)loadURL:(const GURL&)url; | 174 - (void)loadURL:(const GURL&)url; |
177 #pragma mark View loading, laying out, and switching. | 175 #pragma mark View loading, laying out, and switching. |
178 // This method is called if the view needs to be loaded and the model is not | 176 // This method is called if the view needs to be loaded and the model is not |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 // Property declared in NewTabPagePanelProtocol. | 298 // Property declared in NewTabPagePanelProtocol. |
301 @synthesize delegate = _delegate; | 299 @synthesize delegate = _delegate; |
302 | 300 |
303 - (id)initWithLoader:(id<UrlLoader>)loader | 301 - (id)initWithLoader:(id<UrlLoader>)loader |
304 browserState:(ios::ChromeBrowserState*)browserState { | 302 browserState:(ios::ChromeBrowserState*)browserState { |
305 self = [super init]; | 303 self = [super init]; |
306 if (self) { | 304 if (self) { |
307 DCHECK(browserState); | 305 DCHECK(browserState); |
308 _browserState = browserState->GetOriginalChromeBrowserState(); | 306 _browserState = browserState->GetOriginalChromeBrowserState(); |
309 _loader = loader; | 307 _loader = loader; |
310 _propertyReleaser_BookmarkHomeTabletNTPController.Init( | |
311 self, [BookmarkHomeTabletNTPController class]); | |
312 | 308 |
313 _bookmarks = ios::BookmarkModelFactory::GetForBrowserState(_browserState); | 309 _bookmarks = ios::BookmarkModelFactory::GetForBrowserState(_browserState); |
314 _bridge.reset(new bookmarks::BookmarkModelBridge(self, _bookmarks)); | 310 _bridge.reset(new bookmarks::BookmarkModelBridge(self, _bookmarks)); |
315 _editIndexPaths = [[NSMutableArray alloc] init]; | 311 _editIndexPaths = [[NSMutableArray alloc] init]; |
316 // It is important to initialize the promo controller with the browser state | 312 // It is important to initialize the promo controller with the browser state |
317 // passed in, as it could be incognito. | 313 // passed in, as it could be incognito. |
318 _bookmarkPromoController = | 314 _bookmarkPromoController = |
319 [[BookmarkPromoController alloc] initWithBrowserState:browserState | 315 [[BookmarkPromoController alloc] initWithBrowserState:browserState |
320 delegate:self]; | 316 delegate:self]; |
321 } | 317 } |
322 return self; | 318 return self; |
323 } | 319 } |
324 | 320 |
325 - (void)dealloc { | 321 - (void)dealloc { |
326 _contentView.delegate = nil; | 322 _contentView.delegate = nil; |
327 | 323 |
328 _folderView.delegate = nil; | 324 _folderView.delegate = nil; |
329 | 325 |
330 _menuView.delegate = nil; | 326 _menuView.delegate = nil; |
331 | 327 |
332 _editViewController.delegate = nil; | 328 _editViewController.delegate = nil; |
333 _folderSelector.delegate = nil; | 329 _folderSelector.delegate = nil; |
334 | |
335 [super dealloc]; | |
336 } | 330 } |
337 | 331 |
338 - (ios::ChromeBrowserState*)browserState { | 332 - (ios::ChromeBrowserState*)browserState { |
339 return _browserState; | 333 return _browserState; |
340 } | 334 } |
341 | 335 |
342 #pragma mark - ContentViewDelegate method. | 336 #pragma mark - ContentViewDelegate method. |
343 | 337 |
344 - (void)willLayoutSubviews { | 338 - (void)willLayoutSubviews { |
345 if (![self primaryView] && ![self primaryMenuItem] && | 339 if (![self primaryView] && ![self primaryMenuItem] && |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 rendererInitiated:NO]; | 433 rendererInitiated:NO]; |
440 } | 434 } |
441 | 435 |
442 #pragma mark - Views | 436 #pragma mark - Views |
443 | 437 |
444 - (void)loadWaitingView { | 438 - (void)loadWaitingView { |
445 DCHECK(!self.waitForModelView); | 439 DCHECK(!self.waitForModelView); |
446 DCHECK(self.contentView); | 440 DCHECK(self.contentView); |
447 | 441 |
448 // Present a waiting view. | 442 // Present a waiting view. |
449 base::scoped_nsobject<BookmarkHomeWaitingView> waitingView( | 443 BookmarkHomeWaitingView* waitingView = |
450 [[BookmarkHomeWaitingView alloc] initWithFrame:self.view.bounds]); | 444 [[BookmarkHomeWaitingView alloc] initWithFrame:self.view.bounds]; |
451 self.waitForModelView = waitingView; | 445 self.waitForModelView = waitingView; |
452 [self.view addSubview:self.waitForModelView]; | 446 [self.view addSubview:self.waitForModelView]; |
453 [self.waitForModelView startWaiting]; | 447 [self.waitForModelView startWaiting]; |
454 } | 448 } |
455 | 449 |
456 - (void)updateMenuViewLayout { | 450 - (void)updateMenuViewLayout { |
457 LayoutRect menuLayout = | 451 LayoutRect menuLayout = |
458 LayoutRectMake(0, self.view.bounds.size.width, 0, self.menuWidth, | 452 LayoutRectMake(0, self.view.bounds.size.width, 0, self.menuWidth, |
459 self.view.bounds.size.height); | 453 self.view.bounds.size.height); |
460 self.menuView.frame = LayoutRectGetRect(menuLayout); | 454 self.menuView.frame = LayoutRectGetRect(menuLayout); |
461 } | 455 } |
462 | 456 |
463 - (void)loadBookmarkViews { | 457 - (void)loadBookmarkViews { |
464 DCHECK(self.bookmarks->loaded()); | 458 DCHECK(self.bookmarks->loaded()); |
465 | 459 |
466 // Create the menu. | 460 // Create the menu. |
467 LayoutRect menuLayout = | 461 LayoutRect menuLayout = |
468 LayoutRectMake(0, self.view.bounds.size.width, 0, self.menuWidth, | 462 LayoutRectMake(0, self.view.bounds.size.width, 0, self.menuWidth, |
469 self.view.bounds.size.height); | 463 self.view.bounds.size.height); |
470 self.menuView = | 464 self.menuView = [[BookmarkMenuView alloc] |
471 base::scoped_nsobject<BookmarkMenuView>([[BookmarkMenuView alloc] | 465 initWithBrowserState:self.browserState |
472 initWithBrowserState:self.browserState | 466 frame:LayoutRectGetRect(menuLayout)]; |
473 frame:LayoutRectGetRect(menuLayout)]); | |
474 self.menuView.delegate = self; | 467 self.menuView.delegate = self; |
475 self.menuView.autoresizingMask = UIViewAutoresizingFlexibleHeight; | 468 self.menuView.autoresizingMask = UIViewAutoresizingFlexibleHeight; |
476 | 469 |
477 [self moveMenuAndPrimaryViewToAdequateParent]; | 470 [self moveMenuAndPrimaryViewToAdequateParent]; |
478 | 471 |
479 // Load the last primary menu item which the user had active. | 472 // Load the last primary menu item which the user had active. |
480 BookmarkMenuItem* item = nil; | 473 BookmarkMenuItem* item = nil; |
481 CGFloat position = 0; | 474 CGFloat position = 0; |
482 BOOL found = | 475 BOOL found = |
483 bookmark_utils_ios::GetPositionCache(self.bookmarks, &item, &position); | 476 bookmark_utils_ios::GetPositionCache(self.bookmarks, &item, &position); |
(...skipping 14 matching lines...) Expand all Loading... |
498 // out. | 491 // out. |
499 self.cachedContentPosition = [NSNumber numberWithFloat:position]; | 492 self.cachedContentPosition = [NSNumber numberWithFloat:position]; |
500 } | 493 } |
501 } | 494 } |
502 } | 495 } |
503 | 496 |
504 - (void)ensureFolderViewExists { | 497 - (void)ensureFolderViewExists { |
505 if (self.folderView) | 498 if (self.folderView) |
506 return; | 499 return; |
507 | 500 |
508 base::scoped_nsobject<BookmarkFolderCollectionView> view( | 501 BookmarkFolderCollectionView* view = [[BookmarkFolderCollectionView alloc] |
509 [[BookmarkFolderCollectionView alloc] | 502 initWithBrowserState:self.browserState |
510 initWithBrowserState:self.browserState | 503 frame:CGRectZero]; |
511 frame:CGRectZero]); | |
512 self.folderView = view; | 504 self.folderView = view; |
513 self.folderView.delegate = self; | 505 self.folderView.delegate = self; |
514 [self.folderView setEditing:self.editing animated:NO]; | 506 [self.folderView setEditing:self.editing animated:NO]; |
515 self.folderView.autoresizingMask = | 507 self.folderView.autoresizingMask = |
516 UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; | 508 UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; |
517 } | 509 } |
518 | 510 |
519 - (void)updatePrimaryMenuItem:(BookmarkMenuItem*)menuItem | 511 - (void)updatePrimaryMenuItem:(BookmarkMenuItem*)menuItem |
520 animated:(BOOL)animated { | 512 animated:(BOOL)animated { |
521 DCHECK(menuItem.type == bookmarks::MenuItemFolder); | 513 DCHECK(menuItem.type == bookmarks::MenuItemFolder); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 [self.menuView removeFromSuperview]; | 566 [self.menuView removeFromSuperview]; |
575 if ([self.panelView superview]) | 567 if ([self.panelView superview]) |
576 [self.panelView removeFromSuperview]; | 568 [self.panelView removeFromSuperview]; |
577 UIView* primaryView = [self primaryView]; | 569 UIView* primaryView = [self primaryView]; |
578 if ([primaryView superview]) | 570 if ([primaryView superview]) |
579 [primaryView removeFromSuperview]; | 571 [primaryView removeFromSuperview]; |
580 | 572 |
581 if ([self shouldPresentMenuInSlideInPanel]) { | 573 if ([self shouldPresentMenuInSlideInPanel]) { |
582 // Create (if needed), and add the panelView to the view hierarchy. | 574 // Create (if needed), and add the panelView to the view hierarchy. |
583 if (!self.panelView) { | 575 if (!self.panelView) { |
584 self.panelView = base::scoped_nsobject<BookmarkPanelView>( | 576 self.panelView = |
585 [[BookmarkPanelView alloc] initWithFrame:CGRectZero | 577 [[BookmarkPanelView alloc] initWithFrame:CGRectZero |
586 menuViewWidth:[self menuWidth]]); | 578 menuViewWidth:[self menuWidth]]; |
587 } | 579 } |
588 [self.view addSubview:self.panelView]; | 580 [self.view addSubview:self.panelView]; |
589 CGSize size = self.contentView.bounds.size; | 581 CGSize size = self.contentView.bounds.size; |
590 CGFloat navBarHeight = CGRectGetHeight([self navigationBarFrame]); | 582 CGFloat navBarHeight = CGRectGetHeight([self navigationBarFrame]); |
591 LayoutRect panelLayout = LayoutRectMake( | 583 LayoutRect panelLayout = LayoutRectMake( |
592 0, size.width, navBarHeight, size.width, size.height - navBarHeight); | 584 0, size.width, navBarHeight, size.width, size.height - navBarHeight); |
593 | 585 |
594 // Initialize the panelView with the menuView and the primaryView. | 586 // Initialize the panelView with the menuView and the primaryView. |
595 [self.panelView setFrame:LayoutRectGetRect(panelLayout)]; | 587 [self.panelView setFrame:LayoutRectGetRect(panelLayout)]; |
596 [self.panelView.menuView addSubview:self.menuView]; | 588 [self.panelView.menuView addSubview:self.menuView]; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 } | 621 } |
630 | 622 |
631 - (void)updateEditingStateAnimated:(BOOL)animated { | 623 - (void)updateEditingStateAnimated:(BOOL)animated { |
632 if (!self.editing) { | 624 if (!self.editing) { |
633 [self hideEditingBarAnimated:animated]; | 625 [self hideEditingBarAnimated:animated]; |
634 [self updateEditBarShadow]; | 626 [self updateEditBarShadow]; |
635 return; | 627 return; |
636 } | 628 } |
637 | 629 |
638 if (!self.editingBar) { | 630 if (!self.editingBar) { |
639 self.editingBar = base::scoped_nsobject<BookmarkEditingBar>( | 631 self.editingBar = |
640 [[BookmarkEditingBar alloc] initWithFrame:[self editingBarFrame]]); | 632 [[BookmarkEditingBar alloc] initWithFrame:[self editingBarFrame]]; |
641 [self.editingBar setCancelTarget:self action:@selector(editingBarCancel)]; | 633 [self.editingBar setCancelTarget:self action:@selector(editingBarCancel)]; |
642 [self.editingBar setDeleteTarget:self action:@selector(editingBarDelete)]; | 634 [self.editingBar setDeleteTarget:self action:@selector(editingBarDelete)]; |
643 [self.editingBar setMoveTarget:self action:@selector(editingBarMove)]; | 635 [self.editingBar setMoveTarget:self action:@selector(editingBarMove)]; |
644 [self.editingBar setEditTarget:self action:@selector(editingBarEdit)]; | 636 [self.editingBar setEditTarget:self action:@selector(editingBarEdit)]; |
645 | 637 |
646 [self.view addSubview:self.editingBar]; | 638 [self.view addSubview:self.editingBar]; |
647 self.editingBar.hidden = YES; | 639 self.editingBar.hidden = YES; |
648 } | 640 } |
649 | 641 |
650 int bookmarkCount = 0; | 642 int bookmarkCount = 0; |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
814 [self loadURL:localUrl]; | 806 [self loadURL:localUrl]; |
815 }); | 807 }); |
816 } | 808 } |
817 | 809 |
818 - (void)bookmarkCollectionView:(BookmarkCollectionView*)collectionView | 810 - (void)bookmarkCollectionView:(BookmarkCollectionView*)collectionView |
819 wantsMenuForBookmark:(const BookmarkNode*)node | 811 wantsMenuForBookmark:(const BookmarkNode*)node |
820 onView:(UIView*)view | 812 onView:(UIView*)view |
821 forCell:(BookmarkItemCell*)cell { | 813 forCell:(BookmarkItemCell*)cell { |
822 DCHECK(!self.editViewController); | 814 DCHECK(!self.editViewController); |
823 DCHECK(!self.actionSheetCoordinator); | 815 DCHECK(!self.actionSheetCoordinator); |
824 self.actionSheetCoordinator = [[[ActionSheetCoordinator alloc] | 816 self.actionSheetCoordinator = [[ActionSheetCoordinator alloc] |
825 initWithBaseViewController:self.view.window.rootViewController | 817 initWithBaseViewController:self.view.window.rootViewController |
826 title:nil | 818 title:nil |
827 message:nil | 819 message:nil |
828 rect:view.bounds | 820 rect:view.bounds |
829 view:view] autorelease]; | 821 view:view]; |
830 base::WeakNSObject<BookmarkHomeTabletNTPController> weakSelf(self); | 822 __weak BookmarkHomeTabletNTPController* weakSelf = self; |
831 | 823 |
832 // Select action. | 824 // Select action. |
833 [self.actionSheetCoordinator | 825 [self.actionSheetCoordinator |
834 addItemWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_ACTION_SELECT) | 826 addItemWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_ACTION_SELECT) |
835 action:^{ | 827 action:^{ |
836 [weakSelf selectFirstNode:node withCell:cell]; | 828 [weakSelf selectFirstNode:node withCell:cell]; |
837 weakSelf.get().actionSheetCoordinator = nil; | 829 weakSelf.actionSheetCoordinator = nil; |
838 } | 830 } |
839 style:UIAlertActionStyleDefault]; | 831 style:UIAlertActionStyleDefault]; |
840 | 832 |
841 // Edit action. | 833 // Edit action. |
842 [self.actionSheetCoordinator | 834 [self.actionSheetCoordinator |
843 addItemWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_ACTION_EDIT) | 835 addItemWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_ACTION_EDIT) |
844 action:^{ | 836 action:^{ |
845 BookmarkItemCell* itemCell = nil; | 837 BookmarkItemCell* itemCell = nil; |
846 if ([cell isKindOfClass:[BookmarkItemCell class]]) | 838 if ([cell isKindOfClass:[BookmarkItemCell class]]) |
847 itemCell = static_cast<BookmarkItemCell*>(cell); | 839 itemCell = static_cast<BookmarkItemCell*>(cell); |
848 [weakSelf editNode:node withCell:itemCell]; | 840 [weakSelf editNode:node withCell:itemCell]; |
849 weakSelf.get().actionSheetCoordinator = nil; | 841 weakSelf.actionSheetCoordinator = nil; |
850 } | 842 } |
851 style:UIAlertActionStyleDefault]; | 843 style:UIAlertActionStyleDefault]; |
852 | 844 |
853 // Move action. | 845 // Move action. |
854 [self.actionSheetCoordinator | 846 [self.actionSheetCoordinator |
855 addItemWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_ACTION_MOVE) | 847 addItemWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_ACTION_MOVE) |
856 action:^{ | 848 action:^{ |
857 std::set<const BookmarkNode*> nodes; | 849 std::set<const BookmarkNode*> nodes; |
858 nodes.insert(node); | 850 nodes.insert(node); |
859 [weakSelf moveNodes:nodes]; | 851 [weakSelf moveNodes:nodes]; |
860 weakSelf.get().actionSheetCoordinator = nil; | 852 weakSelf.actionSheetCoordinator = nil; |
861 } | 853 } |
862 style:UIAlertActionStyleDefault]; | 854 style:UIAlertActionStyleDefault]; |
863 | 855 |
864 // Delete action. | 856 // Delete action. |
865 [self.actionSheetCoordinator | 857 [self.actionSheetCoordinator |
866 addItemWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_ACTION_DELETE) | 858 addItemWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_ACTION_DELETE) |
867 action:^{ | 859 action:^{ |
868 std::set<const BookmarkNode*> nodes; | 860 std::set<const BookmarkNode*> nodes; |
869 nodes.insert(node); | 861 nodes.insert(node); |
870 [weakSelf deleteNodes:nodes]; | 862 [weakSelf deleteNodes:nodes]; |
871 weakSelf.get().actionSheetCoordinator = nil; | 863 weakSelf.actionSheetCoordinator = nil; |
872 } | 864 } |
873 style:UIAlertActionStyleDestructive]; | 865 style:UIAlertActionStyleDestructive]; |
874 | 866 |
875 // Cancel action. | 867 // Cancel action. |
876 [self.actionSheetCoordinator | 868 [self.actionSheetCoordinator |
877 addItemWithTitle:l10n_util::GetNSString(IDS_CANCEL) | 869 addItemWithTitle:l10n_util::GetNSString(IDS_CANCEL) |
878 action:^{ | 870 action:^{ |
879 weakSelf.get().actionSheetCoordinator = nil; | 871 weakSelf.actionSheetCoordinator = nil; |
880 } | 872 } |
881 style:UIAlertActionStyleCancel]; | 873 style:UIAlertActionStyleCancel]; |
882 | 874 |
883 [self.actionSheetCoordinator start]; | 875 [self.actionSheetCoordinator start]; |
884 } | 876 } |
885 | 877 |
886 - (void)bookmarkCollectionView:(BookmarkCollectionView*)view | 878 - (void)bookmarkCollectionView:(BookmarkCollectionView*)view |
887 didLongPressCell:(UICollectionViewCell*)cell | 879 didLongPressCell:(UICollectionViewCell*)cell |
888 forBookmark:(const BookmarkNode*)node { | 880 forBookmark:(const BookmarkNode*)node { |
889 DCHECK(!self.editing); | 881 DCHECK(!self.editing); |
(...skipping 29 matching lines...) Expand all Loading... |
919 if (node->is_folder()) { | 911 if (node->is_folder()) { |
920 BookmarkFolderEditorViewController* folderEditor = | 912 BookmarkFolderEditorViewController* folderEditor = |
921 [BookmarkFolderEditorViewController | 913 [BookmarkFolderEditorViewController |
922 folderEditorWithBookmarkModel:self.bookmarks | 914 folderEditorWithBookmarkModel:self.bookmarks |
923 folder:node | 915 folder:node |
924 browserState:self.browserState]; | 916 browserState:self.browserState]; |
925 folderEditor.delegate = self; | 917 folderEditor.delegate = self; |
926 self.folderEditor = folderEditor; | 918 self.folderEditor = folderEditor; |
927 editorController = folderEditor; | 919 editorController = folderEditor; |
928 } else { | 920 } else { |
929 base::scoped_nsobject<BookmarkEditViewController> controller([ | 921 BookmarkEditViewController* controller = |
930 [BookmarkEditViewController alloc] initWithBookmark:node | 922 [[BookmarkEditViewController alloc] initWithBookmark:node |
931 browserState:self.browserState]); | 923 browserState:self.browserState]; |
932 self.editViewController = controller; | 924 self.editViewController = controller; |
933 self.editViewController.delegate = self; | 925 self.editViewController.delegate = self; |
934 editorController = self.editViewController; | 926 editorController = self.editViewController; |
935 } | 927 } |
936 DCHECK(editorController); | 928 DCHECK(editorController); |
937 base::scoped_nsobject<UINavigationController> navController( | 929 UINavigationController* navController = [[BookmarkNavigationController alloc] |
938 [[BookmarkNavigationController alloc] | 930 initWithRootViewController:editorController]; |
939 initWithRootViewController:editorController]); | 931 navController.modalPresentationStyle = UIModalPresentationFormSheet; |
940 navController.get().modalPresentationStyle = UIModalPresentationFormSheet; | |
941 [self.view.window.rootViewController presentViewController:navController | 932 [self.view.window.rootViewController presentViewController:navController |
942 animated:YES | 933 animated:YES |
943 completion:NULL]; | 934 completion:NULL]; |
944 } | 935 } |
945 | 936 |
946 - (void)moveNodes:(const std::set<const BookmarkNode*>&)nodes { | 937 - (void)moveNodes:(const std::set<const BookmarkNode*>&)nodes { |
947 DCHECK(!self.folderSelector); | 938 DCHECK(!self.folderSelector); |
948 DCHECK(nodes.size() > 0); | 939 DCHECK(nodes.size() > 0); |
949 const BookmarkNode* editedNode = *(nodes.begin()); | 940 const BookmarkNode* editedNode = *(nodes.begin()); |
950 const BookmarkNode* selectedFolder = editedNode->parent(); | 941 const BookmarkNode* selectedFolder = editedNode->parent(); |
951 self.folderSelector = base::scoped_nsobject<BookmarkFolderViewController>( | 942 self.folderSelector = [[BookmarkFolderViewController alloc] |
952 [[BookmarkFolderViewController alloc] | 943 initWithBookmarkModel:self.bookmarks |
953 initWithBookmarkModel:self.bookmarks | 944 allowsNewFolders:YES |
954 allowsNewFolders:YES | 945 editedNodes:nodes |
955 editedNodes:nodes | 946 allowsCancel:YES |
956 allowsCancel:YES | 947 selectedFolder:selectedFolder]; |
957 selectedFolder:selectedFolder]); | |
958 self.folderSelector.delegate = self; | 948 self.folderSelector.delegate = self; |
959 base::scoped_nsobject<UINavigationController> controller( | 949 UINavigationController* controller = [[BookmarkNavigationController alloc] |
960 [[BookmarkNavigationController alloc] | 950 initWithRootViewController:self.folderSelector]; |
961 initWithRootViewController:self.folderSelector]); | 951 controller.modalPresentationStyle = UIModalPresentationFormSheet; |
962 controller.get().modalPresentationStyle = UIModalPresentationFormSheet; | |
963 [self.view.window.rootViewController presentViewController:controller | 952 [self.view.window.rootViewController presentViewController:controller |
964 animated:YES | 953 animated:YES |
965 completion:NULL]; | 954 completion:NULL]; |
966 } | 955 } |
967 | 956 |
968 - (void)deleteNodes:(const std::set<const BookmarkNode*>&)nodes { | 957 - (void)deleteNodes:(const std::set<const BookmarkNode*>&)nodes { |
969 DCHECK_GE(nodes.size(), 1u); | 958 DCHECK_GE(nodes.size(), 1u); |
970 bookmark_utils_ios::DeleteBookmarksWithUndoToast(nodes, self.bookmarks, | 959 bookmark_utils_ios::DeleteBookmarksWithUndoToast(nodes, self.bookmarks, |
971 self.browserState); | 960 self.browserState); |
972 } | 961 } |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 DCHECK(self.primaryMenuItem.type == bookmarks::MenuItemFolder); | 1122 DCHECK(self.primaryMenuItem.type == bookmarks::MenuItemFolder); |
1134 const BookmarkNode* folder = self.primaryMenuItem.folder; | 1123 const BookmarkNode* folder = self.primaryMenuItem.folder; |
1135 BookmarkFolderEditorViewController* folderEditor = | 1124 BookmarkFolderEditorViewController* folderEditor = |
1136 [BookmarkFolderEditorViewController | 1125 [BookmarkFolderEditorViewController |
1137 folderEditorWithBookmarkModel:self.bookmarks | 1126 folderEditorWithBookmarkModel:self.bookmarks |
1138 folder:folder | 1127 folder:folder |
1139 browserState:self.browserState]; | 1128 browserState:self.browserState]; |
1140 folderEditor.delegate = self; | 1129 folderEditor.delegate = self; |
1141 self.folderEditor = folderEditor; | 1130 self.folderEditor = folderEditor; |
1142 | 1131 |
1143 base::scoped_nsobject<BookmarkNavigationController> navController( | 1132 BookmarkNavigationController* navController = |
1144 [[BookmarkNavigationController alloc] | 1133 [[BookmarkNavigationController alloc] |
1145 initWithRootViewController:self.folderEditor]); | 1134 initWithRootViewController:self.folderEditor]; |
1146 navController.get().modalPresentationStyle = UIModalPresentationFormSheet; | 1135 navController.modalPresentationStyle = UIModalPresentationFormSheet; |
1147 [self.view.window.rootViewController presentViewController:navController | 1136 [self.view.window.rootViewController presentViewController:navController |
1148 animated:YES | 1137 animated:YES |
1149 completion:NULL]; | 1138 completion:NULL]; |
1150 } | 1139 } |
1151 | 1140 |
1152 - (void)navigationBarBack:(id)sender { | 1141 - (void)navigationBarBack:(id)sender { |
1153 DCHECK([self shouldShowBackButton]); | 1142 DCHECK([self shouldShowBackButton]); |
1154 | 1143 |
1155 // Go to the parent folder. | 1144 // Go to the parent folder. |
1156 DCHECK(self.primaryMenuItem.type == bookmarks::MenuItemFolder); | 1145 DCHECK(self.primaryMenuItem.type == bookmarks::MenuItemFolder); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1191 self.scrollToTop = enabled; | 1180 self.scrollToTop = enabled; |
1192 [[self primaryView] setScrollsToTop:self.scrollToTop]; | 1181 [[self primaryView] setScrollsToTop:self.scrollToTop]; |
1193 } | 1182 } |
1194 | 1183 |
1195 - (UIView*)view { | 1184 - (UIView*)view { |
1196 if (!self.contentView) { | 1185 if (!self.contentView) { |
1197 _contentView = [[ContentView alloc] initWithFrame:CGRectZero]; | 1186 _contentView = [[ContentView alloc] initWithFrame:CGRectZero]; |
1198 _contentView.delegate = self; | 1187 _contentView.delegate = self; |
1199 self.contentView.backgroundColor = | 1188 self.contentView.backgroundColor = |
1200 bookmark_utils_ios::mainBackgroundColor(); | 1189 bookmark_utils_ios::mainBackgroundColor(); |
1201 base::scoped_nsobject<BookmarkNavigationBar> bar( | 1190 BookmarkNavigationBar* bar = |
1202 [[BookmarkNavigationBar alloc] initWithFrame:CGRectZero]); | 1191 [[BookmarkNavigationBar alloc] initWithFrame:CGRectZero]; |
1203 self.navigationBar = bar; | 1192 self.navigationBar = bar; |
1204 self.navigationBar.autoresizingMask = UIViewAutoresizingFlexibleWidth; | 1193 self.navigationBar.autoresizingMask = UIViewAutoresizingFlexibleWidth; |
1205 | 1194 |
1206 [self.navigationBar setEditTarget:self | 1195 [self.navigationBar setEditTarget:self |
1207 action:@selector(navigationBarWantsEditing:)]; | 1196 action:@selector(navigationBarWantsEditing:)]; |
1208 [self.navigationBar setBackTarget:self | 1197 [self.navigationBar setBackTarget:self |
1209 action:@selector(navigationBarBack:)]; | 1198 action:@selector(navigationBarBack:)]; |
1210 | 1199 |
1211 [self.navigationBar setMenuTarget:self | 1200 [self.navigationBar setMenuTarget:self |
1212 action:@selector(toggleMenuAnimated)]; | 1201 action:@selector(toggleMenuAnimated)]; |
(...skipping 12 matching lines...) Expand all Loading... |
1225 return 0; | 1214 return 0; |
1226 } | 1215 } |
1227 | 1216 |
1228 #pragma mark - BookmarkModelBridgeObserver | 1217 #pragma mark - BookmarkModelBridgeObserver |
1229 | 1218 |
1230 - (void)bookmarkModelLoaded { | 1219 - (void)bookmarkModelLoaded { |
1231 if (!self.contentView) | 1220 if (!self.contentView) |
1232 return; | 1221 return; |
1233 | 1222 |
1234 DCHECK(self.waitForModelView); | 1223 DCHECK(self.waitForModelView); |
1235 base::WeakNSObject<BookmarkHomeTabletNTPController> weakSelf(self); | 1224 __weak BookmarkHomeTabletNTPController* weakSelf = self; |
1236 [self.waitForModelView stopWaitingWithCompletion:^{ | 1225 [self.waitForModelView stopWaitingWithCompletion:^{ |
1237 base::scoped_nsobject<BookmarkHomeTabletNTPController> strongSelf( | 1226 BookmarkHomeTabletNTPController* strongSelf = weakSelf; |
1238 [weakSelf retain]); | |
1239 // Early return if the controller has been deallocated. | 1227 // Early return if the controller has been deallocated. |
1240 if (!strongSelf) | 1228 if (!strongSelf) |
1241 return; | 1229 return; |
1242 [UIView animateWithDuration:0.2 | 1230 [UIView animateWithDuration:0.2 |
1243 animations:^{ | 1231 animations:^{ |
1244 strongSelf.get().waitForModelView.alpha = 0.0; | 1232 strongSelf.waitForModelView.alpha = 0.0; |
1245 } | 1233 } |
1246 completion:^(BOOL finished) { | 1234 completion:^(BOOL finished) { |
1247 [strongSelf.get().waitForModelView removeFromSuperview]; | 1235 [strongSelf.waitForModelView removeFromSuperview]; |
1248 strongSelf.get().waitForModelView = nil; | 1236 strongSelf.waitForModelView = nil; |
1249 }]; | 1237 }]; |
1250 [strongSelf loadBookmarkViews]; | 1238 [strongSelf loadBookmarkViews]; |
1251 }]; | 1239 }]; |
1252 } | 1240 } |
1253 | 1241 |
1254 - (void)bookmarkNodeChanged:(const BookmarkNode*)bookmarkNode { | 1242 - (void)bookmarkNodeChanged:(const BookmarkNode*)bookmarkNode { |
1255 // The title of the folder may have changed. | 1243 // The title of the folder may have changed. |
1256 if (self.primaryMenuItem.type == bookmarks::MenuItemFolder && | 1244 if (self.primaryMenuItem.type == bookmarks::MenuItemFolder && |
1257 self.primaryMenuItem.folder == bookmarkNode) { | 1245 self.primaryMenuItem.folder == bookmarkNode) { |
1258 UIInterfaceOrientation orient = GetInterfaceOrientation(); | 1246 UIInterfaceOrientation orient = GetInterfaceOrientation(); |
(...skipping 30 matching lines...) Expand all Loading... |
1289 } | 1277 } |
1290 | 1278 |
1291 - (NSIndexPath*)indexPathForCell:(UICollectionViewCell*)cell { | 1279 - (NSIndexPath*)indexPathForCell:(UICollectionViewCell*)cell { |
1292 DCHECK([self primaryView].collectionView); | 1280 DCHECK([self primaryView].collectionView); |
1293 NSIndexPath* indexPath = | 1281 NSIndexPath* indexPath = |
1294 [[self primaryView].collectionView indexPathForCell:cell]; | 1282 [[self primaryView].collectionView indexPathForCell:cell]; |
1295 return indexPath; | 1283 return indexPath; |
1296 } | 1284 } |
1297 | 1285 |
1298 @end | 1286 @end |
OLD | NEW |