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

Side by Side Diff: ios/chrome/browser/ui/history/history_entry_inserter.mm

Issue 2590473002: Upstream Chrome on iOS source code [5/11]. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import "ios/chrome/browser/ui/history/history_entry_inserter.h"
6
7 #import "base/ios/weak_nsobject.h"
8 #include "base/mac/foundation_util.h"
9 #include "base/mac/scoped_nsobject.h"
10 #include "base/strings/sys_string_conversions.h"
11 #include "base/time/time.h"
12 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h "
13 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
14 #import "ios/chrome/browser/ui/history/history_entry_item.h"
15 #include "ios/chrome/browser/ui/history/history_util.h"
16 #include "url/gurl.h"
17
18 @interface HistoryEntryInserter () {
19 // Delegate for the HistoryEntryInserter.
20 base::WeakNSProtocol<id<HistoryEntryInserterDelegate>> _delegate;
21 // CollectionViewModel in which to insert history entries.
22 base::scoped_nsobject<CollectionViewModel> _collectionViewModel;
23 // The index of the first section to contain history entries.
24 NSInteger _firstSectionIndex;
25 // Number of assigned section identifiers.
26 NSInteger _sectionIdentifierCount;
27 // Sorted set of dates that have history entries.
28 base::scoped_nsobject<NSMutableOrderedSet> _dates;
29 // Mapping from dates to section identifiers.
30 base::scoped_nsobject<NSMutableDictionary> _sectionIdentifiers;
31 }
32
33 @end
34
35 @implementation HistoryEntryInserter
36
37 - (instancetype)initWithModel:(CollectionViewModel*)collectionViewModel {
38 if ((self = [super init])) {
39 _collectionViewModel.reset([collectionViewModel retain]);
40 _firstSectionIndex = [collectionViewModel numberOfSections];
41 _dates.reset([[NSMutableOrderedSet alloc] init]);
42 _sectionIdentifiers.reset([[NSMutableDictionary dictionary] retain]);
43 }
44 return self;
45 }
46
47 - (id<HistoryEntryInserterDelegate>)delegate {
48 return _delegate;
49 }
50
51 - (void)setDelegate:(id<HistoryEntryInserterDelegate>)delegate {
52 _delegate.reset(delegate);
53 }
54
55 - (void)insertHistoryEntryItem:(HistoryEntryItem*)item {
56 NSInteger sectionIdentifier =
57 [self sectionIdentifierForTimestamp:item.timestamp];
58
59 NSComparator objectComparator = ^(id obj1, id obj2) {
60 HistoryEntryItem* firstObject =
61 base::mac::ObjCCastStrict<HistoryEntryItem>(obj1);
62 HistoryEntryItem* secondObject =
63 base::mac::ObjCCastStrict<HistoryEntryItem>(obj2);
64 if ([firstObject isEqualToHistoryEntryItem:secondObject])
65 return NSOrderedSame;
66
67 // History entries are ordered from most to least recent.
68 if (firstObject.timestamp > secondObject.timestamp)
69 return NSOrderedAscending;
70 if (firstObject.timestamp < secondObject.timestamp)
71 return NSOrderedDescending;
72 return firstObject.URL < secondObject.URL ? NSOrderedAscending
73 : NSOrderedDescending;
74 };
75
76 NSArray* items =
77 [_collectionViewModel itemsInSectionWithIdentifier:sectionIdentifier];
78 NSRange range = NSMakeRange(0, [items count]);
79 // If the object is not already in the section, insert it.
80 if ([items indexOfObject:item
81 inSortedRange:range
82 options:NSBinarySearchingFirstEqual
83 usingComparator:objectComparator] == NSNotFound) {
84 // Insert the object at the appropriate index to keep the section sorted.
85 NSUInteger index = [items indexOfObject:item
86 inSortedRange:range
87 options:NSBinarySearchingInsertionIndex
88 usingComparator:objectComparator];
89 [_collectionViewModel insertItem:item
90 inSectionWithIdentifier:sectionIdentifier
91 atIndex:index];
92 NSIndexPath* indexPath = [NSIndexPath
93 indexPathForItem:index
94 inSection:[_collectionViewModel
95 sectionForSectionIdentifier:sectionIdentifier]];
96 [self.delegate historyEntryInserter:self
97 didInsertItemAtIndexPath:indexPath];
98 }
99 }
100
101 - (NSUInteger)sectionIdentifierForTimestamp:(base::Time)timestamp {
102 base::TimeDelta timeDelta =
103 timestamp.LocalMidnight() - base::Time::UnixEpoch();
104 NSDate* date = [NSDate dateWithTimeIntervalSince1970:timeDelta.InSeconds()];
105
106 NSInteger sectionIdentifier =
107 [[_sectionIdentifiers objectForKey:date] integerValue];
108 // If there is a section identifier for the date, return it.
109 if (sectionIdentifier) {
110 return sectionIdentifier;
111 }
112
113 // Get the next section identifier, and add a section for date.
114 sectionIdentifier =
115 kSectionIdentifierEnumZero + _firstSectionIndex + _sectionIdentifierCount;
116 ++_sectionIdentifierCount;
117 [_sectionIdentifiers setObject:@(sectionIdentifier) forKey:date];
118
119 NSComparator comparator = ^(id obj1, id obj2) {
120 // Dates are ordered from most to least recent.
121 return [obj2 compare:obj1];
122 };
123 NSUInteger index = [_dates indexOfObject:date
124 inSortedRange:NSMakeRange(0, [_dates count])
125 options:NSBinarySearchingInsertionIndex
126 usingComparator:comparator];
127 [_dates insertObject:date atIndex:index];
128 NSInteger insertionIndex = _firstSectionIndex + index;
129 CollectionViewTextItem* header = [[[CollectionViewTextItem alloc]
130 initWithType:kItemTypeEnumZero] autorelease];
131 header.text =
132 base::SysUTF16ToNSString(history::GetRelativeDateLocalized(timestamp));
133 [_collectionViewModel insertSectionWithIdentifier:sectionIdentifier
134 atIndex:insertionIndex];
135 [_collectionViewModel setHeader:header
136 forSectionWithIdentifier:sectionIdentifier];
137 [self.delegate historyEntryInserter:self
138 didInsertSectionAtIndex:insertionIndex];
139 return sectionIdentifier;
140 }
141
142 - (void)removeSection:(NSInteger)sectionIndex {
143 NSUInteger sectionIdentifier =
144 [_collectionViewModel sectionIdentifierForSection:sectionIndex];
145
146 // Sections should not be removed unless there are no items in that section.
147 DCHECK(![[_collectionViewModel itemsInSectionWithIdentifier:sectionIdentifier]
148 count]);
149 [_collectionViewModel removeSectionWithIdentifier:sectionIdentifier];
150
151 NSEnumerator* dateEnumerator = [_sectionIdentifiers keyEnumerator];
152 NSDate* date = nil;
153 while ((date = [dateEnumerator nextObject])) {
154 if ([[_sectionIdentifiers objectForKey:date] unsignedIntegerValue] ==
155 sectionIdentifier) {
156 [_sectionIdentifiers removeObjectForKey:date];
157 [_dates removeObject:date];
158 break;
159 }
160 }
161 [self.delegate historyEntryInserter:self
162 didRemoveSectionAtIndex:sectionIndex];
163 }
164
165 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698