Merge pull request #11166 from sethlu/openrecent
feat: Recent documents menu item
This commit is contained in:
commit
b161a4f515
4 changed files with 106 additions and 6 deletions
|
@ -50,10 +50,17 @@ Role kRolesMap[] = {
|
|||
{ @selector(selectPreviousTab:), "selectprevioustab" },
|
||||
{ @selector(mergeAllWindows:), "mergeallwindows" },
|
||||
{ @selector(moveTabToNewWindow:), "movetabtonewwindow" },
|
||||
{ @selector(clearRecentDocuments:), "clearrecentdocuments" },
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// Menu item is located for ease of removing it from the parent owner
|
||||
static base::scoped_nsobject<NSMenuItem> recentDocumentsMenuItem_;
|
||||
|
||||
// Submenu retained to be swapped back to |recentDocumentsMenuItem_|
|
||||
static base::scoped_nsobject<NSMenu> recentDocumentsMenuSwap_;
|
||||
|
||||
@implementation AtomMenuController
|
||||
|
||||
@synthesize model = model_;
|
||||
|
@ -75,7 +82,8 @@ Role kRolesMap[] = {
|
|||
// while its context menu is still open.
|
||||
[self cancel];
|
||||
|
||||
model_ = nullptr;
|
||||
model_ = nil;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -87,6 +95,14 @@ Role kRolesMap[] = {
|
|||
if (!menu_)
|
||||
return;
|
||||
|
||||
if (!recentDocumentsMenuItem_) {
|
||||
// Locate & retain the recent documents menu item
|
||||
recentDocumentsMenuItem_.reset([[[[[NSApp mainMenu]
|
||||
itemWithTitle:@"Electron"] submenu]
|
||||
itemWithTitle:@"Open Recent"]
|
||||
retain]);
|
||||
}
|
||||
|
||||
model_ = model;
|
||||
[menu_ removeAllItems];
|
||||
|
||||
|
@ -132,6 +148,42 @@ Role kRolesMap[] = {
|
|||
[menu insertItem:separator atIndex:index];
|
||||
}
|
||||
|
||||
// Empties the source menu items to the destination.
|
||||
- (void)moveMenuItems:(NSMenu*)source
|
||||
to:(NSMenu*)destination {
|
||||
const long count = [source numberOfItems];
|
||||
for (long index = 0; index < count; index++) {
|
||||
NSMenuItem* removedItem = [[[source itemAtIndex:0] retain] autorelease];
|
||||
[source removeItemAtIndex:0];
|
||||
[destination addItem:removedItem];
|
||||
}
|
||||
}
|
||||
|
||||
// Replaces the item's submenu instance with the singleton recent documents
|
||||
// menu. Previously replaced menu items will be recovered.
|
||||
- (void)replaceSubmenuShowingRecentDocuments:(NSMenuItem*)item {
|
||||
NSMenu* recentDocumentsMenu = [[[recentDocumentsMenuItem_ submenu]
|
||||
retain] autorelease];
|
||||
|
||||
// Remove menu items in recent documents back to swap menu
|
||||
[self moveMenuItems:recentDocumentsMenu
|
||||
to:recentDocumentsMenuSwap_];
|
||||
// Swap back the submenu
|
||||
[recentDocumentsMenuItem_ setSubmenu:recentDocumentsMenuSwap_];
|
||||
|
||||
// Retain the item's submenu for a future recovery
|
||||
recentDocumentsMenuSwap_.reset([[item submenu] retain]);
|
||||
|
||||
// Repopulate with items from the submenu to be replaced
|
||||
[self moveMenuItems:recentDocumentsMenuSwap_
|
||||
to:recentDocumentsMenu];
|
||||
// Replace submenu
|
||||
[item setSubmenu:recentDocumentsMenu];
|
||||
|
||||
// Remember the new menu item that carries the recent documents menu
|
||||
recentDocumentsMenuItem_.reset([item retain]);
|
||||
}
|
||||
|
||||
// Adds an item or a hierarchical menu to the item at the |index|,
|
||||
// associated with the entry in the model identified by |modelIndex|.
|
||||
- (void)addItemToMenu:(NSMenu*)menu
|
||||
|
@ -139,6 +191,7 @@ Role kRolesMap[] = {
|
|||
fromModel:(atom::AtomMenuModel*)model {
|
||||
base::string16 label16 = model->GetLabelAt(index);
|
||||
NSString* label = l10n_util::FixUpWindowsStyleLabel(label16);
|
||||
|
||||
base::scoped_nsobject<NSMenuItem> item(
|
||||
[[NSMenuItem alloc] initWithTitle:label
|
||||
action:@selector(itemSelected:)
|
||||
|
@ -149,6 +202,7 @@ Role kRolesMap[] = {
|
|||
if (model->GetIconAt(index, &icon) && !icon.IsEmpty())
|
||||
[item setImage:icon.ToNSImage()];
|
||||
|
||||
base::string16 role = model->GetRoleAt(index);
|
||||
atom::AtomMenuModel::ItemType type = model->GetTypeAt(index);
|
||||
if (type == atom::AtomMenuModel::TYPE_SUBMENU) {
|
||||
// Recursively build a submenu from the sub-model at this index.
|
||||
|
@ -161,14 +215,14 @@ Role kRolesMap[] = {
|
|||
[item setSubmenu:submenu];
|
||||
|
||||
// Set submenu's role.
|
||||
base::string16 role = model->GetRoleAt(index);
|
||||
if (role == base::ASCIIToUTF16("window") && [submenu numberOfItems])
|
||||
[NSApp setWindowsMenu:submenu];
|
||||
else if (role == base::ASCIIToUTF16("help"))
|
||||
[NSApp setHelpMenu:submenu];
|
||||
|
||||
if (role == base::ASCIIToUTF16("services"))
|
||||
else if (role == base::ASCIIToUTF16("services"))
|
||||
[NSApp setServicesMenu:submenu];
|
||||
else if (role == base::ASCIIToUTF16("recentdocuments"))
|
||||
[self replaceSubmenuShowingRecentDocuments:item];
|
||||
} else {
|
||||
// The MenuModel works on indexes so we can't just set the command id as the
|
||||
// tag like we do in other menus. Also set the represented object to be
|
||||
|
@ -192,7 +246,6 @@ Role kRolesMap[] = {
|
|||
}
|
||||
|
||||
// Set menu item's role.
|
||||
base::string16 role = model->GetRoleAt(index);
|
||||
[item setTarget:self];
|
||||
if (!role.empty()) {
|
||||
for (const Role& pair : kRolesMap) {
|
||||
|
|
|
@ -65,6 +65,22 @@
|
|||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="1025936716">
|
||||
<reference key="NSMenu" ref="110575045"/>
|
||||
<string key="NSTitle">Open Recent</string>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<bool key="NSIsHidden">YES</bool>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
<string key="NSAction">submenuAction:</string>
|
||||
<object class="NSMenu" key="NSSubmenu" id="1065607017">
|
||||
<string key="NSTitle">Open Recent</string>
|
||||
<array class="NSMutableArray" key="NSMenuItems"></array>
|
||||
<string key="NSName">_NSRecentDocumentsMenu</string>
|
||||
</object>
|
||||
</object>
|
||||
</array>
|
||||
<string key="NSName">_NSAppleMenu</string>
|
||||
</object>
|
||||
|
@ -115,6 +131,7 @@
|
|||
<reference key="object" ref="903638069"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
<!-- NSMenu Main Menu -->
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">29</int>
|
||||
<reference key="object" ref="649796088"/>
|
||||
|
@ -123,6 +140,7 @@
|
|||
</array>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
<!-- NSMenuItem Electron -->
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">56</int>
|
||||
<reference key="object" ref="694149608"/>
|
||||
|
@ -131,30 +149,51 @@
|
|||
</array>
|
||||
<reference key="parent" ref="649796088"/>
|
||||
</object>
|
||||
<!-- NSMenu Electron -->
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">57</int>
|
||||
<reference key="object" ref="110575045"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="632727374"/>
|
||||
<reference ref="1025936716"/>
|
||||
</array>
|
||||
<reference key="parent" ref="694149608"/>
|
||||
</object>
|
||||
<!-- NSMenuItem Quit -->
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">136</int>
|
||||
<reference key="object" ref="632727374"/>
|
||||
<reference key="parent" ref="110575045"/>
|
||||
</object>
|
||||
<!-- NSMenuItem Open Recent -->
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">124</int>
|
||||
<reference key="object" ref="1025936716"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="1065607017"/>
|
||||
</array>
|
||||
<reference key="parent" ref="110575045"/>
|
||||
</object>
|
||||
<!-- NSMenu Open Recent -->
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">125</int>
|
||||
<reference key="object" ref="1065607017"/>
|
||||
<array class="NSMutableArray" key="children"></array>
|
||||
<reference key="parent" ref="1025936716"/>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<dictionary class="NSMutableDictionary" key="flattenedProperties">
|
||||
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="136.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="29.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="371.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="56.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="57.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="136.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="124.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="125.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
|
||||
<nil key="activeLocalization"/>
|
||||
|
|
|
@ -88,6 +88,8 @@ The following additional roles are available on macOS:
|
|||
* `window` - The submenu is a "Window" menu
|
||||
* `help` - The submenu is a "Help" menu
|
||||
* `services` - The submenu is a "Services" menu
|
||||
* `recentdocuments` - The submenu is an "Open Recent" menu
|
||||
* `clearrecentdocuments` - Map to the `clearRecentDocuments` action
|
||||
|
||||
When specifying a `role` on macOS, `label` and `accelerator` are the only
|
||||
options that will affect the menu item. All other options will be ignored.
|
||||
|
|
|
@ -102,6 +102,12 @@ const roles = {
|
|||
services: {
|
||||
label: 'Services'
|
||||
},
|
||||
recentdocuments: {
|
||||
label: 'Open Recent'
|
||||
},
|
||||
clearrecentdocuments: {
|
||||
label: 'Clear Menu'
|
||||
},
|
||||
startspeaking: {
|
||||
label: 'Start Speaking'
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue