OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ios/chrome/browser/ui/history/history_collection_view_controller.h" | 5 #include "ios/chrome/browser/ui/history/history_collection_view_controller.h" |
6 | 6 |
7 #import <MobileCoreServices/MobileCoreServices.h> | 7 #import <MobileCoreServices/MobileCoreServices.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 | 10 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 @property(nonatomic, assign, getter=isLoading) BOOL loading; | 101 @property(nonatomic, assign, getter=isLoading) BOOL loading; |
102 // YES if there are no more history entries to load. | 102 // YES if there are no more history entries to load. |
103 @property(nonatomic, assign, getter=hasFinishedLoading) BOOL finishedLoading; | 103 @property(nonatomic, assign, getter=hasFinishedLoading) BOOL finishedLoading; |
104 // YES if the collection should be filtered by the next received query result. | 104 // YES if the collection should be filtered by the next received query result. |
105 @property(nonatomic, assign) BOOL filterQueryResult; | 105 @property(nonatomic, assign) BOOL filterQueryResult; |
106 | 106 |
107 // Fetches history prior to |time| for search text |query|. If |query| is nil or | 107 // Fetches history prior to |time| for search text |query|. If |query| is nil or |
108 // the empty string, all history is fetched. | 108 // the empty string, all history is fetched. |
109 - (void)fetchHistoryForQuery:(NSString*)query | 109 - (void)fetchHistoryForQuery:(NSString*)query |
110 priorToTime:(const base::Time&)time; | 110 priorToTime:(const base::Time&)time; |
| 111 // Updates various elements after history items have been deleted from the |
| 112 // CollectionView. |
| 113 - (void)updateCollectionViewAfterDeletingEntries; |
111 // Updates header section to provide relevant information about the currently | 114 // Updates header section to provide relevant information about the currently |
112 // displayed history entries. | 115 // displayed history entries. |
113 - (void)updateEntriesStatusMessage; | 116 - (void)updateEntriesStatusMessage; |
114 // Removes selected items from the visible collection, but does not delete them | 117 // Removes selected items from the visible collection, but does not delete them |
115 // from browser history. | 118 // from browser history. |
116 - (void)removeSelectedItemsFromCollection; | 119 - (void)removeSelectedItemsFromCollection; |
117 // Removes all items in the collection that are not included in entries. | 120 // Selects all items in the collection that are not included in entries. |
118 - (void)filterForHistoryEntries:(NSArray*)entries; | 121 - (void)filterForHistoryEntries:(NSArray*)entries; |
| 122 // Deletes all items in the collection which indexes are included in indexArray, |
| 123 // needs to be run inside a performBatchUpdates block. |
| 124 - (void)deleteItemsFromCollectionViewModelWithIndex:(NSArray*)indexArray; |
119 // Adds loading indicator to the top of the history collection, if one is not | 125 // Adds loading indicator to the top of the history collection, if one is not |
120 // already present. | 126 // already present. |
121 - (void)addLoadingIndicator; | 127 - (void)addLoadingIndicator; |
122 // Displays context menu on cell pressed with gestureRecognizer. | 128 // Displays context menu on cell pressed with gestureRecognizer. |
123 - (void)displayContextMenuInvokedByGestureRecognizer: | 129 - (void)displayContextMenuInvokedByGestureRecognizer: |
124 (UILongPressGestureRecognizer*)gestureRecognizer; | 130 (UILongPressGestureRecognizer*)gestureRecognizer; |
125 // Opens URL in the current tab and dismisses the history view. | 131 // Opens URL in the current tab and dismisses the history view. |
126 - (void)openURL:(const GURL&)URL; | 132 - (void)openURL:(const GURL&)URL; |
127 // Opens URL in a new non-incognito tab and dismisses the history view. | 133 // Opens URL in a new non-incognito tab and dismisses the history view. |
128 - (void)openURLInNewTab:(const GURL&)URL; | 134 - (void)openURLInNewTab:(const GURL&)URL; |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 [[HistoryEntryItem alloc] initWithType:ItemTypeHistoryEntry | 369 [[HistoryEntryItem alloc] initWithType:ItemTypeHistoryEntry |
364 historyEntry:entry | 370 historyEntry:entry |
365 browserState:_browserState | 371 browserState:_browserState |
366 delegate:self]; | 372 delegate:self]; |
367 [self.entryInserter insertHistoryEntryItem:item]; | 373 [self.entryInserter insertHistoryEntryItem:item]; |
368 if ([self isSearching] || self.filterQueryResult) { | 374 if ([self isSearching] || self.filterQueryResult) { |
369 [filterResults addObject:item]; | 375 [filterResults addObject:item]; |
370 } | 376 } |
371 } | 377 } |
372 [self.delegate historyCollectionViewControllerDidChangeEntries:self]; | 378 [self.delegate historyCollectionViewControllerDidChangeEntries:self]; |
| 379 if (([self isSearching] && [searchQuery length] > 0 && |
| 380 [self.currentQuery isEqualToString:searchQuery]) || |
| 381 self.filterQueryResult) { |
| 382 // If in search mode, filter out entries that are not |
| 383 // part of the search result. |
| 384 [self filterForHistoryEntries:filterResults]; |
| 385 NSArray* deletedIndexPaths = |
| 386 self.collectionView.indexPathsForSelectedItems; |
| 387 [self deleteItemsFromCollectionViewModelWithIndex:deletedIndexPaths]; |
| 388 self.filterQueryResult = NO; |
| 389 } |
373 } | 390 } |
374 completion:^(BOOL) { | 391 completion:^(BOOL) { |
375 if (([self isSearching] && [searchQuery length] > 0 && | 392 [self updateCollectionViewAfterDeletingEntries]; |
376 [self.currentQuery isEqualToString:searchQuery]) || | |
377 self.filterQueryResult) { | |
378 // If in search mode, filter out entries that are not | |
379 // part of the search result. | |
380 [self filterForHistoryEntries:filterResults]; | |
381 self.filterQueryResult = NO; | |
382 } | |
383 }]; | 393 }]; |
384 } | 394 } |
385 | 395 |
386 - (void)historyServiceFacade:(HistoryServiceFacade*)facade | 396 - (void)historyServiceFacade:(HistoryServiceFacade*)facade |
387 shouldShowNoticeAboutOtherFormsOfBrowsingHistory:(BOOL)shouldShowNotice { | 397 shouldShowNoticeAboutOtherFormsOfBrowsingHistory:(BOOL)shouldShowNotice { |
388 self.shouldShowNoticeAboutOtherFormsOfBrowsingHistory = shouldShowNotice; | 398 self.shouldShowNoticeAboutOtherFormsOfBrowsingHistory = shouldShowNotice; |
389 // Update the history entries status message if there is no query in progress. | 399 // Update the history entries status message if there is no query in progress. |
390 if (!self.isLoading) { | 400 if (!self.isLoading) { |
391 [self updateEntriesStatusMessage]; | 401 [self updateEntriesStatusMessage]; |
392 } | 402 } |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 : history::QueryOptions::REMOVE_ALL_DUPLICATES; | 567 : history::QueryOptions::REMOVE_ALL_DUPLICATES; |
558 options.max_count = kMaxFetchCount; | 568 options.max_count = kMaxFetchCount; |
559 options.matching_algorithm = | 569 options.matching_algorithm = |
560 query_parser::MatchingAlgorithm::ALWAYS_PREFIX_SEARCH; | 570 query_parser::MatchingAlgorithm::ALWAYS_PREFIX_SEARCH; |
561 _historyServiceFacade->QueryHistory(queryString, options); | 571 _historyServiceFacade->QueryHistory(queryString, options); |
562 // Also determine whether notice regarding other forms of browsing history | 572 // Also determine whether notice regarding other forms of browsing history |
563 // should be shown. | 573 // should be shown. |
564 _historyServiceFacade->QueryOtherFormsOfBrowsingHistory(); | 574 _historyServiceFacade->QueryOtherFormsOfBrowsingHistory(); |
565 } | 575 } |
566 | 576 |
| 577 - (void)updateCollectionViewAfterDeletingEntries { |
| 578 // If only the header section remains, there are no history entries. |
| 579 if ([self.collectionViewModel numberOfSections] == 1) { |
| 580 self.entriesType = NO_ENTRIES; |
| 581 } |
| 582 [self updateEntriesStatusMessage]; |
| 583 [self.delegate historyCollectionViewControllerDidChangeEntries:self]; |
| 584 } |
| 585 |
567 - (void)updateEntriesStatusMessage { | 586 - (void)updateEntriesStatusMessage { |
568 CollectionViewItem* entriesStatusItem = nil; | 587 CollectionViewItem* entriesStatusItem = nil; |
569 if (!self.hasHistoryEntries) { | 588 if (!self.hasHistoryEntries) { |
570 CollectionViewTextItem* noResultsItem = | 589 CollectionViewTextItem* noResultsItem = |
571 [[CollectionViewTextItem alloc] initWithType:ItemTypeEntriesStatus]; | 590 [[CollectionViewTextItem alloc] initWithType:ItemTypeEntriesStatus]; |
572 noResultsItem.text = | 591 noResultsItem.text = |
573 self.isSearching ? l10n_util::GetNSString(IDS_HISTORY_NO_SEARCH_RESULTS) | 592 self.isSearching ? l10n_util::GetNSString(IDS_HISTORY_NO_SEARCH_RESULTS) |
574 : l10n_util::GetNSString(IDS_HISTORY_NO_RESULTS); | 593 : l10n_util::GetNSString(IDS_HISTORY_NO_RESULTS); |
575 entriesStatusItem = noResultsItem; | 594 entriesStatusItem = noResultsItem; |
576 } else { | 595 } else { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 [self.collectionViewModel addItem:entriesStatusItem | 630 [self.collectionViewModel addItem:entriesStatusItem |
612 toSectionWithIdentifier:kEntriesStatusSectionIdentifier]; | 631 toSectionWithIdentifier:kEntriesStatusSectionIdentifier]; |
613 [self.collectionView insertItemsAtIndexPaths:@[ indexPath ]]; | 632 [self.collectionView insertItemsAtIndexPaths:@[ indexPath ]]; |
614 } | 633 } |
615 completion:nil]; | 634 completion:nil]; |
616 } | 635 } |
617 | 636 |
618 - (void)removeSelectedItemsFromCollection { | 637 - (void)removeSelectedItemsFromCollection { |
619 NSArray* deletedIndexPaths = self.collectionView.indexPathsForSelectedItems; | 638 NSArray* deletedIndexPaths = self.collectionView.indexPathsForSelectedItems; |
620 [self.collectionView performBatchUpdates:^{ | 639 [self.collectionView performBatchUpdates:^{ |
621 [self collectionView:self.collectionView | 640 [self deleteItemsFromCollectionViewModelWithIndex:deletedIndexPaths]; |
622 willDeleteItemsAtIndexPaths:deletedIndexPaths]; | 641 } |
623 [self.collectionView deleteItemsAtIndexPaths:deletedIndexPaths]; | 642 completion:^(BOOL) { |
| 643 [self updateCollectionViewAfterDeletingEntries]; |
| 644 }]; |
| 645 } |
624 | 646 |
625 // Remove any empty sections, except the header section. | 647 - (void)deleteItemsFromCollectionViewModelWithIndex:(NSArray*)indexArray { |
626 for (int section = self.collectionView.numberOfSections - 1; section > 0; | 648 [self collectionView:self.collectionView |
627 --section) { | 649 willDeleteItemsAtIndexPaths:indexArray]; |
628 if (![self.collectionViewModel numberOfItemsInSection:section]) { | 650 [self.collectionView deleteItemsAtIndexPaths:indexArray]; |
629 [self.entryInserter removeSection:section]; | 651 |
630 } | 652 // Remove any empty sections, except the header section. |
| 653 for (int section = self.collectionView.numberOfSections - 1; section > 0; |
| 654 --section) { |
| 655 if (![self.collectionViewModel numberOfItemsInSection:section]) { |
| 656 [self.entryInserter removeSection:section]; |
631 } | 657 } |
632 } | 658 } |
633 completion:^(BOOL) { | |
634 // If only the header section remains, there are no history entries. | |
635 if ([self.collectionViewModel numberOfSections] == 1) { | |
636 self.entriesType = NO_ENTRIES; | |
637 } | |
638 [self updateEntriesStatusMessage]; | |
639 [self.delegate historyCollectionViewControllerDidChangeEntries:self]; | |
640 }]; | |
641 } | 659 } |
642 | 660 |
643 - (void)filterForHistoryEntries:(NSArray*)entries { | 661 - (void)filterForHistoryEntries:(NSArray*)entries { |
644 self.collectionView.allowsMultipleSelection = YES; | 662 self.collectionView.allowsMultipleSelection = YES; |
645 for (int section = 1; section < [self.collectionViewModel numberOfSections]; | 663 for (int section = 1; section < [self.collectionViewModel numberOfSections]; |
646 ++section) { | 664 ++section) { |
647 NSInteger sectionIdentifier = | 665 NSInteger sectionIdentifier = |
648 [self.collectionViewModel sectionIdentifierForSection:section]; | 666 [self.collectionViewModel sectionIdentifierForSection:section]; |
649 if ([self.collectionViewModel | 667 if ([self.collectionViewModel |
650 hasSectionForSectionIdentifier:sectionIdentifier]) { | 668 hasSectionForSectionIdentifier:sectionIdentifier]) { |
651 NSArray* items = [self.collectionViewModel | 669 NSArray* items = [self.collectionViewModel |
652 itemsInSectionWithIdentifier:sectionIdentifier]; | 670 itemsInSectionWithIdentifier:sectionIdentifier]; |
653 for (id item in items) { | 671 for (id item in items) { |
654 HistoryEntryItem* historyItem = | 672 HistoryEntryItem* historyItem = |
655 base::mac::ObjCCastStrict<HistoryEntryItem>(item); | 673 base::mac::ObjCCastStrict<HistoryEntryItem>(item); |
656 if (![entries containsObject:historyItem]) { | 674 if (![entries containsObject:historyItem]) { |
657 NSIndexPath* indexPath = | 675 NSIndexPath* indexPath = |
658 [self.collectionViewModel indexPathForItem:historyItem | 676 [self.collectionViewModel indexPathForItem:historyItem |
659 inSectionWithIdentifier:sectionIdentifier]; | 677 inSectionWithIdentifier:sectionIdentifier]; |
660 [self.collectionView | 678 [self.collectionView |
661 selectItemAtIndexPath:indexPath | 679 selectItemAtIndexPath:indexPath |
662 animated:NO | 680 animated:NO |
663 scrollPosition:UICollectionViewScrollPositionNone]; | 681 scrollPosition:UICollectionViewScrollPositionNone]; |
664 } | 682 } |
665 } | 683 } |
666 } | 684 } |
667 } | 685 } |
668 [self removeSelectedItemsFromCollection]; | |
669 } | 686 } |
670 | 687 |
671 - (void)addLoadingIndicator { | 688 - (void)addLoadingIndicator { |
672 NSIndexPath* indexPath = [NSIndexPath indexPathForItem:0 inSection:0]; | 689 NSIndexPath* indexPath = [NSIndexPath indexPathForItem:0 inSection:0]; |
673 if ([self.collectionViewModel hasItemAtIndexPath:indexPath] && | 690 if ([self.collectionViewModel hasItemAtIndexPath:indexPath] && |
674 [self.collectionViewModel itemTypeForIndexPath:indexPath] == | 691 [self.collectionViewModel itemTypeForIndexPath:indexPath] == |
675 ItemTypeActivityIndicator) { | 692 ItemTypeActivityIndicator) { |
676 // Do not add indicator a second time. | 693 // Do not add indicator a second time. |
677 return; | 694 return; |
678 } | 695 } |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
797 shouldCloseWithCompletion:^{ | 814 shouldCloseWithCompletion:^{ |
798 [self.URLLoader webPageOrderedOpen:copiedURL | 815 [self.URLLoader webPageOrderedOpen:copiedURL |
799 referrer:web::Referrer() | 816 referrer:web::Referrer() |
800 inIncognito:YES | 817 inIncognito:YES |
801 inBackground:NO | 818 inBackground:NO |
802 appendTo:kLastTab]; | 819 appendTo:kLastTab]; |
803 }]; | 820 }]; |
804 } | 821 } |
805 | 822 |
806 @end | 823 @end |
OLD | NEW |