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