// Copyright 2020 The Chromium Authors
// 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/menu/action_factory.h"
#import "base/check.h"
#import "base/metrics/histogram_functions.h"
#import "base/metrics/user_metrics.h"
#import "base/strings/sys_string_conversions.h"
#import "ios/chrome/browser/net/model/crurl.h"
#import "ios/chrome/browser/shared/model/web_state_list/tab_group.h"
#import "ios/chrome/browser/shared/public/commands/application_commands.h"
#import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
#import "ios/chrome/browser/shared/public/features/features.h"
#import "ios/chrome/browser/shared/ui/symbols/symbols.h"
#import "ios/chrome/browser/shared/ui/util/pasteboard_util.h"
#import "ios/chrome/browser/signin/model/system_identity.h"
#import "ios/chrome/browser/ui/menu/menu_action_type.h"
#import "ios/chrome/grit/ios_strings.h"
#import "ios/public/provider/chrome/browser/context_menu/context_menu_api.h"
#import "ui/base/l10n/l10n_util_mac.h"
#import "url/gurl.h"
@interface ActionFactory ()
// Histogram to record executed actions.
@property(nonatomic, assign) const char* histogram;
@end
@implementation ActionFactory
- (instancetype)initWithScenario:(MenuScenarioHistogram)scenario {
if ((self = [super init])) {
_histogram = GetActionsHistogramName(scenario);
}
return self;
}
- (UIAction*)actionWithTitle:(NSString*)title
image:(UIImage*)image
type:(MenuActionType)type
block:(ProceduralBlock)block {
// Capture only the histogram name's pointer to be copied by the block.
const char* histogram = self.histogram;
return [UIAction actionWithTitle:title
image:image
identifier:nil
handler:^(UIAction* action) {
base::UmaHistogramEnumeration(histogram, type);
if (block) {
block();
}
}];
}
- (UIAction*)actionToCopyURL:(CrURL*)URL {
UIImage* image =
DefaultSymbolWithPointSize(kLinkActionSymbol, kSymbolActionPointSize);
return [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_COPY_LINK_ACTION_TITLE)
image:image
type:MenuActionType::CopyURL
block:^{
StoreURLInPasteboard(URL.gurl);
}];
}
- (UIAction*)actionToShowFullURL:(NSString*)URLString
block:(ProceduralBlock)block {
UIAction* action = [self actionWithTitle:nil
image:nil
type:MenuActionType::ShowFullURL
block:block];
action.accessibilityLabel =
l10n_util::GetNSString(IDS_IOS_SHARE_FULL_URL_BUTTON_ACCESSIBILITY_LABEL);
action.attributes = UIMenuElementAttributesKeepsMenuPresented;
action.subtitle = ios::provider::StyledContextMenuStringForString(URLString);
return action;
}
- (UIAction*)actionToShareWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kShareSymbol, kSymbolActionPointSize);
return
[self actionWithTitle:l10n_util::GetNSString(IDS_IOS_SHARE_BUTTON_LABEL)
image:image
type:MenuActionType::Share
block:block];
}
- (UIAction*)actionToPinTabWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kPinSymbol, kSymbolActionPointSize);
return [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_PINTAB)
image:image
type:MenuActionType::PinTab
block:block];
}
- (UIAction*)actionToUnpinTabWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kPinSlashSymbol, kSymbolActionPointSize);
return [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_UNPINTAB)
image:image
type:MenuActionType::UnpinTab
block:block];
}
- (UIAction*)actionToDeleteWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kDeleteActionSymbol, kSymbolActionPointSize);
UIAction* action =
[self actionWithTitle:l10n_util::GetNSString(IDS_IOS_DELETE_ACTION_TITLE)
image:image
type:MenuActionType::Delete
block:block];
action.attributes = UIMenuElementAttributesDestructive;
return action;
}
- (UIAction*)actionToOpenInNewTabWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kNewTabActionSymbol, kSymbolActionPointSize);
ProceduralBlock completionBlock =
[self recordMobileWebContextMenuOpenTabActionWithBlock:block];
return [self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB)
image:image
type:MenuActionType::OpenInNewTab
block:completionBlock];
}
- (UIAction*)actionToOpenAllTabsWithBlock:(ProceduralBlock)block {
return [self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_CONTENT_CONTEXT_OPEN_ALL_LINKS)
image:DefaultSymbolWithPointSize(
kPlusSymbol, kSymbolActionPointSize)
type:MenuActionType::OpenAllInNewTabs
block:block];
}
- (UIAction*)actionToRemoveWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kHideActionSymbol, kSymbolActionPointSize);
UIAction* action =
[self actionWithTitle:l10n_util::GetNSString(IDS_IOS_REMOVE_ACTION_TITLE)
image:image
type:MenuActionType::Remove
block:block];
action.attributes = UIMenuElementAttributesDestructive;
return action;
}
- (UIAction*)actionToEditWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kEditActionSymbol, kSymbolActionPointSize);
return [self actionWithTitle:l10n_util::GetNSString(IDS_IOS_EDIT_ACTION_TITLE)
image:image
type:MenuActionType::Edit
block:block];
}
- (UIAction*)actionToHideWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kHideActionSymbol, kSymbolActionPointSize);
UIAction* action =
[self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_RECENT_TABS_HIDE_MENU_OPTION)
image:image
type:MenuActionType::Hide
block:block];
action.attributes = UIMenuElementAttributesDestructive;
return action;
}
- (UIAction*)actionToMoveFolderWithBlock:(ProceduralBlock)block {
// Use multi color to make sure the arrow is visible.
UIImage* image = MakeSymbolMulticolor(
CustomSymbolWithPointSize(kMoveFolderSymbol, kSymbolActionPointSize));
return [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_CONTEXT_MENU_MOVE)
image:image
type:MenuActionType::Move
block:block];
}
- (UIAction*)actionToMarkAsReadWithBlock:(ProceduralBlock)block {
UIImage* image = DefaultSymbolWithPointSize(kMarkAsReadActionSymbol,
kSymbolActionPointSize);
return [self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_READING_LIST_MARK_AS_READ_ACTION)
image:image
type:MenuActionType::Read
block:block];
}
- (UIAction*)actionToMarkAsUnreadWithBlock:(ProceduralBlock)block {
UIImage* image = DefaultSymbolWithPointSize(kMarkAsUnreadActionSymbol,
kSymbolActionPointSize);
return [self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_READING_LIST_MARK_AS_UNREAD_ACTION)
image:image
type:MenuActionType::Unread
block:block];
}
- (UIAction*)actionToOpenOfflineVersionInNewTabWithBlock:
(ProceduralBlock)block {
UIImage* image = DefaultSymbolWithPointSize(kCheckmarkCircleSymbol,
kSymbolActionPointSize);
ProceduralBlock completionBlock =
[self recordMobileWebContextMenuOpenTabActionWithBlock:block];
return [self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_READING_LIST_OPEN_OFFLINE_BUTTON)
image:image
type:MenuActionType::ViewOffline
block:completionBlock];
}
- (UIAction*)actionToAddToReadingListWithBlock:(ProceduralBlock)block {
UIImage* image = DefaultSymbolWithPointSize(kReadLaterActionSymbol,
kSymbolActionPointSize);
return [self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_CONTENT_CONTEXT_ADDTOREADINGLIST)
image:image
type:MenuActionType::AddToReadingList
block:block];
}
- (UIAction*)actionToBookmarkWithBlock:(ProceduralBlock)block {
UIImage* image = DefaultSymbolWithPointSize(kAddBookmarkActionSymbol,
kSymbolActionPointSize);
return [self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_CONTENT_CONTEXT_ADDTOBOOKMARKS)
image:image
type:MenuActionType::AddToBookmarks
block:block];
}
- (UIAction*)actionToEditBookmarkWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kEditActionSymbol, kSymbolActionPointSize);
return [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_CONTEXT_MENU_EDIT)
image:image
type:MenuActionType::EditBookmark
block:block];
}
- (UIAction*)actionToCloseRegularTabWithBlock:(ProceduralBlock)block {
NSString* title = l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_CLOSETAB);
return [self actionToCloseTabWithTitle:title block:block];
}
- (UIAction*)actionToClosePinnedTabWithBlock:(ProceduralBlock)block {
NSString* title =
l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_CLOSEPINNEDTAB);
return [self actionToCloseTabWithTitle:title block:block];
}
- (UIAction*)actionToCloseAllOtherTabsWithBlock:(ProceduralBlock)block {
NSString* title =
l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_CLOSEOTHERTABS);
UIImage* image =
DefaultSymbolWithPointSize(kXMarkSymbol, kSymbolActionPointSize);
UIAction* action = [self actionWithTitle:title
image:image
type:MenuActionType::CloseAllOtherTabs
block:block];
action.attributes = UIMenuElementAttributesDestructive;
return action;
}
- (UIAction*)actionSaveImageWithBlock:(ProceduralBlock)block {
UIImage* image = DefaultSymbolWithPointSize(kSaveImageActionSymbol,
kSymbolActionPointSize);
UIAction* action = [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_SAVEIMAGE)
image:image
type:MenuActionType::SaveImage
block:block];
return action;
}
- (UIAction*)actionCopyImageWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kCopyActionSymbol, kSymbolActionPointSize);
UIAction* action = [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_COPYIMAGE)
image:image
type:MenuActionType::CopyImage
block:block];
return action;
}
- (UIAction*)actionSearchImageWithTitle:(NSString*)title
Block:(ProceduralBlock)block {
UIImage* image = CustomSymbolWithPointSize(kPhotoBadgeMagnifyingglassSymbol,
kSymbolActionPointSize);
UIAction* action = [self actionWithTitle:title
image:image
type:MenuActionType::SearchImage
block:block];
return action;
}
- (UIAction*)actionToCloseAllTabsWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kXMarkSymbol, kSymbolActionPointSize);
int titleID = IsTabGroupSyncEnabled()
? IDS_IOS_CONTENT_CONTEXT_CLOSEALLTABSANDGROUPS
: IDS_IOS_CONTENT_CONTEXT_CLOSEALLTABS;
UIAction* action = [self actionWithTitle:l10n_util::GetNSString(titleID)
image:image
type:MenuActionType::CloseAllTabs
block:block];
action.attributes = UIMenuElementAttributesDestructive;
return action;
}
- (UIAction*)actionToSelectTabsWithBlock:(ProceduralBlock)block {
UIImage* image = DefaultSymbolWithPointSize(kCheckmarkCircleSymbol,
kSymbolActionPointSize);
UIAction* action = [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_SELECTTABS)
image:image
type:MenuActionType::SelectTabs
block:block];
return action;
}
- (UIAction*)actionToSearchImageUsingLensWithBlock:(ProceduralBlock)block {
UIImage* image =
CustomSymbolWithPointSize(kCameraLensSymbol, kSymbolActionPointSize);
UIAction* action =
[self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_CONTEXT_MENU_SEARCHIMAGEWITHGOOGLE)
image:image
type:MenuActionType::SearchImageWithLens
block:block];
return action;
}
- (ProceduralBlock)recordMobileWebContextMenuOpenTabActionWithBlock:
(ProceduralBlock)block {
return ^{
base::RecordAction(base::UserMetricsAction("MobileWebContextMenuOpenTab"));
if (block) {
block();
}
};
}
- (UIAction*)actionToAddTabsToNewGroupWithTabsNumber:(int)tabsNumber
inSubmenu:(BOOL)inSubmenu
block:(ProceduralBlock)block {
CHECK(IsTabGroupInGridEnabled())
<< "You should not be able to create a tab group context menu action "
"outside the Tab Groups experiment.";
UIImage* image = DefaultSymbolWithPointSize(kNewTabGroupActionSymbol,
kSymbolActionPointSize);
NSString* title =
inSubmenu ? l10n_util::GetNSString(
IDS_IOS_CONTENT_CONTEXT_ADDTABTONEWTABGROUP_SUBMENU)
: l10n_util::GetPluralNSStringF(
IDS_IOS_CONTENT_CONTEXT_ADDTABTONEWTABGROUP, tabsNumber);
UIAction* action = [self actionWithTitle:title
image:image
type:MenuActionType::AddTabToNewGroup
block:block];
return action;
}
- (UIAction*)actionToOpenLinkInNewGroupWithBlock:(ProceduralBlock)block
inSubmenu:(BOOL)inSubmenu {
UIImage* image = DefaultSymbolWithPointSize(kNewTabGroupActionSymbol,
kSymbolActionPointSize);
NSString* title =
inSubmenu ? l10n_util::GetNSString(
IDS_IOS_CONTENT_CONTEXT_ADDTABTONEWTABGROUP_SUBMENU)
: l10n_util::GetNSString(
IDS_IOS_CONTENT_CONTEXT_OPENLINKINNEWTABGROUP);
UIAction* action = [self actionWithTitle:title
image:image
type:MenuActionType::OpenLinkInNewGroup
block:block];
return action;
}
- (UIMenuElement*)
menuToAddTabToGroupWithGroups:(const std::set<const TabGroup*>&)groups
numberOfTabs:(int)tabsNumber
block:(void (^)(const TabGroup*))block {
CHECK(IsTabGroupInGridEnabled())
<< "You should not be able to create a tab group context menu action "
"outside the Tab Groups experiment.";
if (groups.size() == 0) {
ProceduralBlock addTabToNewGroupBlock = ^{
if (block) {
block(nil);
}
};
return [self actionToAddTabsToNewGroupWithTabsNumber:tabsNumber
inSubmenu:NO
block:addTabToNewGroupBlock];
}
NSArray<UIMenuElement*>* groupsMenu = [self groupsMenuForGroups:groups
currentGroup:nil
block:block];
UIMenu* menu = [UIMenu menuWithTitle:@""
image:nil
identifier:nil
options:UIMenuOptionsDisplayInline
children:groupsMenu];
ProceduralBlock addTabToNewGroupBlock = ^{
if (block) {
block(nil);
}
};
NSArray<UIMenuElement*>* addToGroupMenuElements = @[
[self actionToAddTabsToNewGroupWithTabsNumber:tabsNumber
inSubmenu:YES
block:addTabToNewGroupBlock],
menu
];
UIImage* image = DefaultSymbolWithPointSize(kMoveTabToGroupActionSymbol,
kSymbolActionPointSize);
return [UIMenu
menuWithTitle:l10n_util::GetPluralNSStringF(
IDS_IOS_CONTENT_CONTEXT_ADDTABTOTABGROUP, tabsNumber)
image:image
identifier:nil
options:UIMenuOptionsSingleSelection
children:addToGroupMenuElements];
}
- (UIMenuElement*)
menuToMoveTabToGroupWithGroups:(const std::set<const TabGroup*>&)groups
currentGroup:(const TabGroup*)currentGroup
moveBlock:(void (^)(const TabGroup*))moveBlock
removeBlock:(ProceduralBlock)removeBlock {
CHECK(IsTabGroupInGridEnabled())
<< "You should not be able to create a tab group context menu action "
"outside the Tab Groups experiment.";
if (groups.size() == 0) {
NOTREACHED() << "Groups cannot be empty.";
}
NSArray<UIMenuElement*>* groupsMenu = [self groupsMenuForGroups:groups
currentGroup:currentGroup
block:moveBlock];
UIMenu* menu = [UIMenu menuWithTitle:@""
image:nil
identifier:nil
options:UIMenuOptionsDisplayInline
children:groupsMenu];
NSArray<UIMenuElement*>* moveTabFromGroupMenuElements =
@[ [self actionToRemoveTabFromGroup:removeBlock], menu ];
UIImage* image = DefaultSymbolWithPointSize(kMoveTabToGroupActionSymbol,
kSymbolActionPointSize);
return [UIMenu menuWithTitle:l10n_util::GetNSString(
IDS_IOS_CONTENT_CONTEXT_MOVETABTOGROUP)
image:image
identifier:nil
options:UIMenuOptionsSingleSelection
children:moveTabFromGroupMenuElements];
}
- (UIMenuElement*)
menuToOpenLinkInGroupWithGroups:(const std::set<const TabGroup*>&)groups
block:(void (^)(const TabGroup*))block {
CHECK(IsTabGroupInGridEnabled())
<< "You should not be able to create a tab group context menu action "
"outside the Tab Groups experiment.";
if (groups.size() == 0) {
ProceduralBlock openInNewGroupBlock = ^{
if (block) {
block(nil);
}
};
return [self actionToOpenLinkInNewGroupWithBlock:openInNewGroupBlock
inSubmenu:NO];
}
NSArray<UIMenuElement*>* groupsMenu = [self groupsMenuForGroups:groups
currentGroup:nil
block:block];
UIMenu* menu = [UIMenu menuWithTitle:@""
image:nil
identifier:nil
options:UIMenuOptionsDisplayInline
children:groupsMenu];
ProceduralBlock openInNewGroupBlock = ^{
if (block) {
block(nil);
}
};
NSArray<UIMenuElement*>* openInGroupMenuElements = @[
[self actionToOpenLinkInNewGroupWithBlock:openInNewGroupBlock
inSubmenu:YES],
menu
];
UIImage* image = DefaultSymbolWithPointSize(kMoveTabToGroupActionSymbol,
kSymbolActionPointSize);
return [UIMenu menuWithTitle:l10n_util::GetNSString(
IDS_IOS_CONTENT_CONTEXT_OPENLINKINTABGROUP)
image:image
identifier:nil
options:UIMenuOptionsSingleSelection
children:openInGroupMenuElements];
}
- (UIAction*)actionToRenameTabGroupWithBlock:(ProceduralBlock)block {
CHECK(IsTabGroupInGridEnabled());
UIImage* image =
DefaultSymbolWithPointSize(kEditActionSymbol, kSymbolActionPointSize);
UIAction* action =
[self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_CONTENT_CONTEXT_RENAMEGROUP)
image:image
type:MenuActionType::RenameTabGroup
block:block];
return action;
}
- (UIAction*)actionToAddNewTabInGroupWithBlock:(ProceduralBlock)block {
CHECK(IsTabGroupInGridEnabled());
UIImage* image = DefaultSymbolWithPointSize(kNewTabGroupActionSymbol,
kSymbolActionPointSize);
UIAction* action =
[self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_CONTENT_CONTEXT_NEWTABINGROUP)
image:image
type:MenuActionType::NewTabInGroup
block:block];
return action;
}
- (UIAction*)actionToUngroupTabGroupWithBlock:(ProceduralBlock)block {
CHECK(IsTabGroupInGridEnabled());
UIImage* image = DefaultSymbolWithPointSize(kUngroupTabGroupSymbol,
kSymbolActionPointSize);
UIAction* action = [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_UNGROUP)
image:image
type:MenuActionType::UngroupTabGroup
block:block];
return action;
}
- (UIAction*)actionToDeleteTabGroupWithBlock:(ProceduralBlock)block {
CHECK(IsTabGroupInGridEnabled());
UIImage* image =
DefaultSymbolWithPointSize(kDeleteActionSymbol, kSymbolActionPointSize);
UIAction* action =
[self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_CONTENT_CONTEXT_DELETEGROUP)
image:image
type:MenuActionType::DeleteTabGroup
block:block];
action.attributes = UIMenuElementAttributesDestructive;
return action;
}
- (UIAction*)actionToCloseTabGroupWithBlock:(ProceduralBlock)block {
CHECK(IsTabGroupInGridEnabled());
CHECK(IsTabGroupSyncEnabled());
UIImage* image =
DefaultSymbolWithPointSize(kXMarkSymbol, kSymbolActionPointSize);
UIAction* action = [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_CLOSEGROUP)
image:image
type:MenuActionType::CloseTabGroup
block:block];
action.attributes = UIMenuElementAttributesDestructive;
return action;
}
#pragma mark - Private
// Creates a UIAction instance for closing a tab with a provided `title`.
- (UIAction*)actionToCloseTabWithTitle:(NSString*)title
block:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kXMarkSymbol, kSymbolActionPointSize);
UIAction* action = [self actionWithTitle:title
image:image
type:MenuActionType::CloseTab
block:block];
action.attributes = UIMenuElementAttributesDestructive;
return action;
}
// Creates a UIAction instance for removing a tab from a group.
- (UIAction*)actionToRemoveTabFromGroup:(ProceduralBlock)block {
CHECK(IsTabGroupInGridEnabled())
<< "You should not be able to create a tab group context menu action "
"outside the Tab Groups experiment.";
UIImage* image = DefaultSymbolWithPointSize(kRemoveTabFromGroupActionSymbol,
kSymbolActionPointSize);
NSString* title =
l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_REMOVEFROMGROUP);
UIAction* action = [self actionWithTitle:title
image:image
type:MenuActionType::RemoveTabFromGroup
block:block];
return action;
}
- (UIAction*)actionToShowDetailsWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kInfoCircleSymbol, kSymbolActionPointSize);
return [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_SHOW_DETAILS_ACTION_TITLE)
image:image
type:MenuActionType::ShowDetails
block:block];
}
// Returns an array of group actions for a given set of groups. If
// `currentGroup` is specified and is present in the set, it is selected.
- (NSArray<UIMenuElement*>*)
groupsMenuForGroups:(const std::set<const TabGroup*>&)groups
currentGroup:(const TabGroup*)currentGroup
block:(void (^)(const TabGroup*))block {
NSMutableArray<UIMenuElement*>* groupsMenu = [[NSMutableArray alloc] init];
UIImage* circleImage =
DefaultSymbolWithPointSize(kCircleFillSymbol, kSymbolActionPointSize);
circleImage =
[circleImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
for (const TabGroup* group : groups) {
NSString* title = group->GetTitle();
base::WeakPtr<const TabGroup> weakGroup = group->GetWeakPtr();
ProceduralBlock actionBlock = ^{
if (block) {
block(weakGroup.get());
}
};
UIAction* groupAction =
[self actionWithTitle:title
image:[circleImage imageWithTintColor:group->GetColor()]
type:MenuActionType::MoveTabToExistingGroup
block:actionBlock];
if (group == currentGroup) {
groupAction.state = UIMenuElementStateOn;
}
[groupsMenu addObject:groupAction];
}
return groupsMenu;
}
- (UIAction*)actionToSortDriveItemsByNameWithBlock:(ProceduralBlock)block {
return
[self actionWithTitle:l10n_util::GetNSString(IDS_IOS_DRIVE_SORT_BY_NAME)
image:nil
type:MenuActionType::SortDriveItemsByName
block:block];
}
- (UIAction*)actionToSortDriveItemsByModificationTimeWithBlock:
(ProceduralBlock)block {
return [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_DRIVE_SORT_BY_MODIFICATION)
image:nil
type:MenuActionType::SortDriveItemsByModificationTime
block:block];
}
- (UIAction*)actionToSortDriveItemsByOpeningTimeWithBlock:
(ProceduralBlock)block {
return [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_DRIVE_SORT_BY_OPENING)
image:nil
type:MenuActionType::SortDriveItemsByOpeningTime
block:block];
}
- (UIMenuElement*)
menuToSelectDriveIdentityWithIdentities:
(NSArray<id<SystemIdentity>>*)identities
currentIdentity:(id<SystemIdentity>)currentIdentity
block:(void (^)(const id<SystemIdentity>))
block {
NSMutableArray<UIMenuElement*>* identitiesMenuElements =
[[NSMutableArray alloc] init];
for (id<SystemIdentity> identity in identities) {
NSString* email = identity.userEmail;
ProceduralBlock actionBlock = ^{
if (block) {
block(identity);
}
};
UIAction* identityAction =
[self actionWithTitle:email
image:nil
type:MenuActionType::SelectDriveIdentity
block:actionBlock];
if (identity == currentIdentity) {
identityAction.state = UIMenuElementStateOn;
}
[identitiesMenuElements addObject:identityAction];
}
return [UIMenu menuWithTitle:@""
image:nil
identifier:nil
options:UIMenuOptionsDisplayInline
children:identitiesMenuElements];
}
- (UIAction*)actionToAddAccountForDriveWithBlock:(ProceduralBlock)block {
return [self actionWithTitle:l10n_util::GetNSString(IDS_IOS_DRIVE_ADD_ACCOUNT)
image:nil
type:MenuActionType::AddDriveAccount
block:block];
}
@end