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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: ios/chrome/browser/ui/history/history_entry_inserter.mm
diff --git a/ios/chrome/browser/ui/history/history_entry_inserter.mm b/ios/chrome/browser/ui/history/history_entry_inserter.mm
new file mode 100644
index 0000000000000000000000000000000000000000..f442455d57322239b7cb46fbaabd2762a1aa8425
--- /dev/null
+++ b/ios/chrome/browser/ui/history/history_entry_inserter.mm
@@ -0,0 +1,165 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/history/history_entry_inserter.h"
+
+#import "base/ios/weak_nsobject.h"
+#include "base/mac/foundation_util.h"
+#include "base/mac/scoped_nsobject.h"
+#include "base/strings/sys_string_conversions.h"
+#include "base/time/time.h"
+#import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
+#import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
+#import "ios/chrome/browser/ui/history/history_entry_item.h"
+#include "ios/chrome/browser/ui/history/history_util.h"
+#include "url/gurl.h"
+
+@interface HistoryEntryInserter () {
+ // Delegate for the HistoryEntryInserter.
+ base::WeakNSProtocol<id<HistoryEntryInserterDelegate>> _delegate;
+ // CollectionViewModel in which to insert history entries.
+ base::scoped_nsobject<CollectionViewModel> _collectionViewModel;
+ // The index of the first section to contain history entries.
+ NSInteger _firstSectionIndex;
+ // Number of assigned section identifiers.
+ NSInteger _sectionIdentifierCount;
+ // Sorted set of dates that have history entries.
+ base::scoped_nsobject<NSMutableOrderedSet> _dates;
+ // Mapping from dates to section identifiers.
+ base::scoped_nsobject<NSMutableDictionary> _sectionIdentifiers;
+}
+
+@end
+
+@implementation HistoryEntryInserter
+
+- (instancetype)initWithModel:(CollectionViewModel*)collectionViewModel {
+ if ((self = [super init])) {
+ _collectionViewModel.reset([collectionViewModel retain]);
+ _firstSectionIndex = [collectionViewModel numberOfSections];
+ _dates.reset([[NSMutableOrderedSet alloc] init]);
+ _sectionIdentifiers.reset([[NSMutableDictionary dictionary] retain]);
+ }
+ return self;
+}
+
+- (id<HistoryEntryInserterDelegate>)delegate {
+ return _delegate;
+}
+
+- (void)setDelegate:(id<HistoryEntryInserterDelegate>)delegate {
+ _delegate.reset(delegate);
+}
+
+- (void)insertHistoryEntryItem:(HistoryEntryItem*)item {
+ NSInteger sectionIdentifier =
+ [self sectionIdentifierForTimestamp:item.timestamp];
+
+ NSComparator objectComparator = ^(id obj1, id obj2) {
+ HistoryEntryItem* firstObject =
+ base::mac::ObjCCastStrict<HistoryEntryItem>(obj1);
+ HistoryEntryItem* secondObject =
+ base::mac::ObjCCastStrict<HistoryEntryItem>(obj2);
+ if ([firstObject isEqualToHistoryEntryItem:secondObject])
+ return NSOrderedSame;
+
+ // History entries are ordered from most to least recent.
+ if (firstObject.timestamp > secondObject.timestamp)
+ return NSOrderedAscending;
+ if (firstObject.timestamp < secondObject.timestamp)
+ return NSOrderedDescending;
+ return firstObject.URL < secondObject.URL ? NSOrderedAscending
+ : NSOrderedDescending;
+ };
+
+ NSArray* items =
+ [_collectionViewModel itemsInSectionWithIdentifier:sectionIdentifier];
+ NSRange range = NSMakeRange(0, [items count]);
+ // If the object is not already in the section, insert it.
+ if ([items indexOfObject:item
+ inSortedRange:range
+ options:NSBinarySearchingFirstEqual
+ usingComparator:objectComparator] == NSNotFound) {
+ // Insert the object at the appropriate index to keep the section sorted.
+ NSUInteger index = [items indexOfObject:item
+ inSortedRange:range
+ options:NSBinarySearchingInsertionIndex
+ usingComparator:objectComparator];
+ [_collectionViewModel insertItem:item
+ inSectionWithIdentifier:sectionIdentifier
+ atIndex:index];
+ NSIndexPath* indexPath = [NSIndexPath
+ indexPathForItem:index
+ inSection:[_collectionViewModel
+ sectionForSectionIdentifier:sectionIdentifier]];
+ [self.delegate historyEntryInserter:self
+ didInsertItemAtIndexPath:indexPath];
+ }
+}
+
+- (NSUInteger)sectionIdentifierForTimestamp:(base::Time)timestamp {
+ base::TimeDelta timeDelta =
+ timestamp.LocalMidnight() - base::Time::UnixEpoch();
+ NSDate* date = [NSDate dateWithTimeIntervalSince1970:timeDelta.InSeconds()];
+
+ NSInteger sectionIdentifier =
+ [[_sectionIdentifiers objectForKey:date] integerValue];
+ // If there is a section identifier for the date, return it.
+ if (sectionIdentifier) {
+ return sectionIdentifier;
+ }
+
+ // Get the next section identifier, and add a section for date.
+ sectionIdentifier =
+ kSectionIdentifierEnumZero + _firstSectionIndex + _sectionIdentifierCount;
+ ++_sectionIdentifierCount;
+ [_sectionIdentifiers setObject:@(sectionIdentifier) forKey:date];
+
+ NSComparator comparator = ^(id obj1, id obj2) {
+ // Dates are ordered from most to least recent.
+ return [obj2 compare:obj1];
+ };
+ NSUInteger index = [_dates indexOfObject:date
+ inSortedRange:NSMakeRange(0, [_dates count])
+ options:NSBinarySearchingInsertionIndex
+ usingComparator:comparator];
+ [_dates insertObject:date atIndex:index];
+ NSInteger insertionIndex = _firstSectionIndex + index;
+ CollectionViewTextItem* header = [[[CollectionViewTextItem alloc]
+ initWithType:kItemTypeEnumZero] autorelease];
+ header.text =
+ base::SysUTF16ToNSString(history::GetRelativeDateLocalized(timestamp));
+ [_collectionViewModel insertSectionWithIdentifier:sectionIdentifier
+ atIndex:insertionIndex];
+ [_collectionViewModel setHeader:header
+ forSectionWithIdentifier:sectionIdentifier];
+ [self.delegate historyEntryInserter:self
+ didInsertSectionAtIndex:insertionIndex];
+ return sectionIdentifier;
+}
+
+- (void)removeSection:(NSInteger)sectionIndex {
+ NSUInteger sectionIdentifier =
+ [_collectionViewModel sectionIdentifierForSection:sectionIndex];
+
+ // Sections should not be removed unless there are no items in that section.
+ DCHECK(![[_collectionViewModel itemsInSectionWithIdentifier:sectionIdentifier]
+ count]);
+ [_collectionViewModel removeSectionWithIdentifier:sectionIdentifier];
+
+ NSEnumerator* dateEnumerator = [_sectionIdentifiers keyEnumerator];
+ NSDate* date = nil;
+ while ((date = [dateEnumerator nextObject])) {
+ if ([[_sectionIdentifiers objectForKey:date] unsignedIntegerValue] ==
+ sectionIdentifier) {
+ [_sectionIdentifiers removeObjectForKey:date];
+ [_dates removeObject:date];
+ break;
+ }
+ }
+ [self.delegate historyEntryInserter:self
+ didRemoveSectionAtIndex:sectionIndex];
+}
+
+@end

Powered by Google App Engine
This is Rietveld 408576698