Skip to content

Commit

Permalink
add cansavecontextkey (#80337)
Browse files Browse the repository at this point in the history
* add cansavecontextkey

* use save logic for save active editor ctx key

* use context key plus explorer focus

* remove unused imports

* feedback
  • Loading branch information
sbatten authored Sep 11, 2019
1 parent 2afeba7 commit 1b9a873
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 12 deletions.
14 changes: 12 additions & 2 deletions src/vs/workbench/browser/contextkeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { IContextKeyService, IContextKey, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { InputFocusedContext } from 'vs/platform/contextkey/common/contextkeys';
import { IWindowsConfiguration } from 'vs/platform/windows/common/windows';
import { ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, TEXT_DIFF_EDITOR_ID, SplitEditorsVertically, InEditorZenModeContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext } from 'vs/workbench/common/editor';
import { ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, TEXT_DIFF_EDITOR_ID, SplitEditorsVertically, InEditorZenModeContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorIsSaveableContext, toResource, SideBySideEditor } from 'vs/workbench/common/editor';
import { trackFocus, addDisposableListener, EventType } from 'vs/base/browser/dom';
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
Expand All @@ -21,6 +21,8 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { isMacintosh, isLinux, isWindows, isWeb } from 'vs/base/common/platform';
import { PanelPositionContext } from 'vs/workbench/common/panel';
import { getRemoteName } from 'vs/platform/remote/common/remoteHosts';
import { IFileService } from 'vs/platform/files/common/files';
import { Schemas } from 'vs/base/common/network';

export const IsMacContext = new RawContextKey<boolean>('isMac', isMacintosh);
export const IsLinuxContext = new RawContextKey<boolean>('isLinux', isLinux);
Expand Down Expand Up @@ -52,6 +54,7 @@ export class WorkbenchContextKeysHandler extends Disposable {
private inputFocusedContext: IContextKey<boolean>;

private activeEditorContext: IContextKey<string | null>;
private activeEditorIsSaveable: IContextKey<boolean>;

private activeEditorGroupEmpty: IContextKey<boolean>;
private activeEditorGroupIndex: IContextKey<number>;
Expand Down Expand Up @@ -80,7 +83,8 @@ export class WorkbenchContextKeysHandler extends Disposable {
@IEditorService private editorService: IEditorService,
@IEditorGroupsService private editorGroupService: IEditorGroupsService,
@IWorkbenchLayoutService private layoutService: IWorkbenchLayoutService,
@IViewletService private viewletService: IViewletService
@IViewletService private viewletService: IViewletService,
@IFileService private fileService: IFileService
) {
super();

Expand Down Expand Up @@ -142,6 +146,7 @@ export class WorkbenchContextKeysHandler extends Disposable {

// Editors
this.activeEditorContext = ActiveEditorContext.bindTo(this.contextKeyService);
this.activeEditorIsSaveable = ActiveEditorIsSaveableContext.bindTo(this.contextKeyService);
this.editorsVisibleContext = EditorsVisibleContext.bindTo(this.contextKeyService);
this.textCompareEditorVisibleContext = TextCompareEditorVisibleContext.bindTo(this.contextKeyService);
this.textCompareEditorActiveContext = TextCompareEditorActiveContext.bindTo(this.contextKeyService);
Expand Down Expand Up @@ -214,8 +219,13 @@ export class WorkbenchContextKeysHandler extends Disposable {

if (activeControl) {
this.activeEditorContext.set(activeControl.getId());

const resource = toResource(activeControl.input, { supportSideBySide: SideBySideEditor.MASTER });
const canSave = resource ? this.fileService.canHandleResource(resource) || resource.scheme === Schemas.untitled : false;
this.activeEditorIsSaveable.set(canSave);
} else {
this.activeEditorContext.reset();
this.activeEditorIsSaveable.reset();
}
}

Expand Down
37 changes: 30 additions & 7 deletions src/vs/workbench/browser/parts/titlebar/menubarControl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ export class CustomMenubarControl extends MenubarControl {
private menubar: MenuBar;
private container: HTMLElement;
private alwaysOnMnemonics: boolean;
private focusInsideMenubar: boolean;

private readonly _onVisibilityChange: Emitter<boolean>;
private readonly _onFocusStateChange: Emitter<boolean>;
Expand Down Expand Up @@ -480,9 +481,27 @@ export class CustomMenubarControl extends MenubarControl {
this.menubar.update({ enableMnemonics: this.currentEnableMenuBarMnemonics, disableAltFocus: this.currentDisableMenuBarAltFocus, visibility: this.currentMenubarVisibility, getKeybinding: (action) => this.keybindingService.lookupKeybinding(action.id), alwaysOnMnemonics: this.alwaysOnMnemonics });
});

this._register(this.menubar.onFocusStateChange(e => this._onFocusStateChange.fire(e)));
this._register(this.menubar.onFocusStateChange(focused => {
this._onFocusStateChange.fire(focused);

// When the menubar loses focus, update it to clear any pending updates
if (!focused) {
this.updateMenubar();
this.focusInsideMenubar = false;
}
}));

this._register(this.menubar.onVisibilityChange(e => this._onVisibilityChange.fire(e)));

// Before we focus the menubar, stop updates to it so that focus-related context keys will work
this._register(DOM.addDisposableListener(this.container, DOM.EventType.FOCUS_IN, () => {
this.focusInsideMenubar = true;
}));

this._register(DOM.addDisposableListener(this.container, DOM.EventType.FOCUS_OUT, () => {
this.focusInsideMenubar = false;
}));

this._register(attachMenuStyler(this.menubar, this.themeService));
} else {
this.menubar.update({ enableMnemonics: this.currentEnableMenuBarMnemonics, disableAltFocus: this.currentDisableMenuBarAltFocus, visibility: this.currentMenubarVisibility, getKeybinding: (action) => this.keybindingService.lookupKeybinding(action.id), alwaysOnMnemonics: this.alwaysOnMnemonics });
Expand All @@ -502,9 +521,11 @@ export class CustomMenubarControl extends MenubarControl {
this.menus[action.item.submenu] = this.menuService.createMenu(action.item.submenu, this.contextKeyService);
const submenu = this.menus[action.item.submenu];
this._register(submenu!.onDidChange(() => {
const actions: IAction[] = [];
updateActions(menu, actions, topLevelTitle);
this.menubar.updateMenu({ actions: actions, label: mnemonicMenuLabel(this.topLevelTitles[topLevelTitle]) });
if (!this.focusInsideMenubar) {
const actions: IAction[] = [];
updateActions(menu, actions, topLevelTitle);
this.menubar.updateMenu({ actions: actions, label: mnemonicMenuLabel(this.topLevelTitles[topLevelTitle]) });
}
}, this));
}

Expand All @@ -528,9 +549,11 @@ export class CustomMenubarControl extends MenubarControl {
const menu = this.menus[title];
if (firstTime && menu) {
this._register(menu.onDidChange(() => {
const actions: IAction[] = [];
updateActions(menu, actions, title);
this.menubar.updateMenu({ actions: actions, label: mnemonicMenuLabel(this.topLevelTitles[title]) });
if (!this.focusInsideMenubar) {
const actions: IAction[] = [];
updateActions(menu, actions, title);
this.menubar.updateMenu({ actions: actions, label: mnemonicMenuLabel(this.topLevelTitles[title]) });
}
}));
}

Expand Down
1 change: 1 addition & 0 deletions src/vs/workbench/common/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { IPathData } from 'vs/platform/windows/common/windows';
import { coalesce } from 'vs/base/common/arrays';

export const ActiveEditorContext = new RawContextKey<string | null>('activeEditor', null);
export const ActiveEditorIsSaveableContext = new RawContextKey<boolean>('activeEditorIsSaveable', false);
export const EditorsVisibleContext = new RawContextKey<boolean>('editorIsOpen', false);
export const EditorPinnedContext = new RawContextKey<boolean>('editorPinned', false);
export const EditorGroupActiveEditorDirtyContext = new RawContextKey<boolean>('groupActiveEditorDirty', false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { CommandsRegistry, ICommandHandler } from 'vs/platform/commands/common/c
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { isWindows, isMacintosh, isWeb } from 'vs/base/common/platform';
import { FilesExplorerFocusCondition, ExplorerRootContext, ExplorerFolderContext, ExplorerResourceNotReadonlyContext, ExplorerResourceCut, IExplorerService, ExplorerResourceMoveableToTrash } from 'vs/workbench/contrib/files/common/files';
import { FilesExplorerFocusCondition, ExplorerRootContext, ExplorerFolderContext, ExplorerResourceNotReadonlyContext, ExplorerResourceCut, IExplorerService, ExplorerResourceMoveableToTrash, ExplorerViewletVisibleContext } from 'vs/workbench/contrib/files/common/files';
import { ADD_ROOT_FOLDER_COMMAND_ID, ADD_ROOT_FOLDER_LABEL } from 'vs/workbench/browser/actions/workspaceCommands';
import { CLOSE_SAVED_EDITORS_COMMAND_ID, CLOSE_EDITORS_IN_GROUP_COMMAND_ID, CLOSE_EDITOR_COMMAND_ID, CLOSE_OTHER_EDITORS_IN_GROUP_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands';
import { AutoSaveContext } from 'vs/workbench/services/textfile/common/textfiles';
Expand All @@ -26,6 +26,8 @@ import { Schemas } from 'vs/base/common/network';
import { SupportsWorkspacesContext, IsWebContext, RemoteFileDialogContext, WorkspaceFolderCountContext } from 'vs/workbench/browser/contextkeys';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { OpenFileFolderAction, OpenLocalFileFolderCommand, OpenFileAction, OpenFolderAction, OpenLocalFileCommand, OpenLocalFolderCommand, OpenWorkspaceAction, SaveLocalFileCommand } from 'vs/workbench/browser/actions/workspaceActions';
import { ActiveEditorIsSaveableContext } from 'vs/workbench/common/editor';
import { SidebarFocusContext } from 'vs/workbench/common/viewlet';
import { registerAndGetAmdImageURL } from 'vs/base/common/amd';

// Contribute Global Actions
Expand Down Expand Up @@ -626,7 +628,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
group: '4_save',
command: {
id: SAVE_FILE_COMMAND_ID,
title: nls.localize({ key: 'miSave', comment: ['&& denotes a mnemonic'] }, "&&Save")
title: nls.localize({ key: 'miSave', comment: ['&& denotes a mnemonic'] }, "&&Save"),
precondition: ContextKeyExpr.or(ActiveEditorIsSaveableContext, ContextKeyExpr.and(ExplorerViewletVisibleContext, SidebarFocusContext))
},
order: 1
});
Expand All @@ -635,7 +638,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
group: '4_save',
command: {
id: SAVE_FILE_AS_COMMAND_ID,
title: nls.localize({ key: 'miSaveAs', comment: ['&& denotes a mnemonic'] }, "Save &&As...")
title: nls.localize({ key: 'miSaveAs', comment: ['&& denotes a mnemonic'] }, "Save &&As..."),
precondition: ContextKeyExpr.or(ActiveEditorIsSaveableContext, ContextKeyExpr.and(ExplorerViewletVisibleContext, SidebarFocusContext))
},
order: 2
});
Expand Down

0 comments on commit 1b9a873

Please sign in to comment.