提交 c21b4f4b 编写于 作者: B Benjamin Pasero

fix #50957

上级 1a8ea64a
...@@ -398,7 +398,6 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ ...@@ -398,7 +398,6 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
mac: openPreviousEditorKeybinding.mac mac: openPreviousEditorKeybinding.mac
}); });
// Editor Commands // Editor Commands
editorCommands.setup(); editorCommands.setup();
...@@ -440,73 +439,97 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands. ...@@ -440,73 +439,97 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands.
MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands.CLOSE_EDITORS_IN_GROUP_COMMAND_ID, title: nls.localize('closeAll', "Close All") }, group: '5_close', order: 10, when: ContextKeyExpr.has('config.workbench.editor.showTabs') }); MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands.CLOSE_EDITORS_IN_GROUP_COMMAND_ID, title: nls.localize('closeAll', "Close All") }, group: '5_close', order: 10, when: ContextKeyExpr.has('config.workbench.editor.showTabs') });
MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands.CLOSE_SAVED_EDITORS_COMMAND_ID, title: nls.localize('closeAllSaved', "Close Saved") }, group: '5_close', order: 20, when: ContextKeyExpr.has('config.workbench.editor.showTabs') }); MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands.CLOSE_SAVED_EDITORS_COMMAND_ID, title: nls.localize('closeAllSaved', "Close Saved") }, group: '5_close', order: 20, when: ContextKeyExpr.has('config.workbench.editor.showTabs') });
interface IEditorToolItem { id: string; title: string; iconDark: string; iconLight: string; }
function appendEditorToolItem(primary: IEditorToolItem, alternative: IEditorToolItem, when: ContextKeyExpr, order: number): void {
MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
command: {
id: primary.id,
title: primary.title,
iconPath: {
dark: URI.parse(require.toUrl(`vs/workbench/browser/parts/editor/media/${primary.iconDark}`)).fsPath,
light: URI.parse(require.toUrl(`vs/workbench/browser/parts/editor/media/${primary.iconLight}`)).fsPath
}
},
alt: {
id: alternative.id,
title: alternative.title,
iconPath: {
dark: URI.parse(require.toUrl(`vs/workbench/browser/parts/editor/media/${alternative.iconDark}`)).fsPath,
light: URI.parse(require.toUrl(`vs/workbench/browser/parts/editor/media/${alternative.iconLight}`)).fsPath
}
},
group: 'navigation',
when,
order
});
}
// Editor Title Menu: Split Editor // Editor Title Menu: Split Editor
MenuRegistry.appendMenuItem(MenuId.EditorTitle, { appendEditorToolItem(
command: { {
id: SplitEditorAction.ID, id: SplitEditorAction.ID,
title: nls.localize('splitEditorRight', "Split Editor Right"), title: nls.localize('splitEditorRight', "Split Editor Right"),
iconPath: { iconDark: 'split-editor-horizontal-inverse.svg',
dark: URI.parse(require.toUrl('vs/workbench/browser/parts/editor/media/split-editor-horizontal-inverse.svg')).fsPath, iconLight: 'split-editor-horizontal.svg'
light: URI.parse(require.toUrl('vs/workbench/browser/parts/editor/media/split-editor-horizontal.svg')).fsPath }, {
}
},
alt: {
id: editorCommands.SPLIT_EDITOR_DOWN, id: editorCommands.SPLIT_EDITOR_DOWN,
title: nls.localize('splitEditorDown', "Split Editor Down"), title: nls.localize('splitEditorDown', "Split Editor Down"),
iconPath: { iconDark: 'split-editor-vertical-inverse.svg',
dark: URI.parse(require.toUrl('vs/workbench/browser/parts/editor/media/split-editor-vertical-inverse.svg')).fsPath, iconLight: 'split-editor-vertical.svg'
light: URI.parse(require.toUrl('vs/workbench/browser/parts/editor/media/split-editor-vertical.svg')).fsPath
}
}, },
group: 'navigation', ContextKeyExpr.not('splitEditorsVertically'),
when: ContextKeyExpr.not('splitEditorsVertically'), 100000 /* towards the end */
order: 100000 // towards the end );
});
MenuRegistry.appendMenuItem(MenuId.EditorTitle, { appendEditorToolItem(
command: { {
id: SplitEditorAction.ID, id: SplitEditorAction.ID,
title: nls.localize('splitEditorDown', "Split Editor Down"), title: nls.localize('splitEditorDown', "Split Editor Down"),
iconPath: { iconDark: 'split-editor-vertical-inverse.svg',
dark: URI.parse(require.toUrl('vs/workbench/browser/parts/editor/media/split-editor-vertical-inverse.svg')).fsPath, iconLight: 'split-editor-vertical.svg'
light: URI.parse(require.toUrl('vs/workbench/browser/parts/editor/media/split-editor-vertical.svg')).fsPath }, {
}
},
alt: {
id: editorCommands.SPLIT_EDITOR_RIGHT, id: editorCommands.SPLIT_EDITOR_RIGHT,
title: nls.localize('splitEditorRight', "Split Editor Right"), title: nls.localize('splitEditorRight', "Split Editor Right"),
iconPath: { iconDark: 'split-editor-horizontal-inverse.svg',
dark: URI.parse(require.toUrl('vs/workbench/browser/parts/editor/media/split-editor-horizontal-inverse.svg')).fsPath, iconLight: 'split-editor-horizontal.svg'
light: URI.parse(require.toUrl('vs/workbench/browser/parts/editor/media/split-editor-horizontal.svg')).fsPath
}
}, },
group: 'navigation', ContextKeyExpr.has('splitEditorsVertically'),
when: ContextKeyExpr.has('splitEditorsVertically'), 100000 // towards the end
order: 100000 // towards the end );
});
// Editor Title Menu: Close Group (tabs disabled) // Editor Title Menu: Close Group (tabs disabled)
MenuRegistry.appendMenuItem(MenuId.EditorTitle, { appendEditorToolItem(
command: { {
id: editorCommands.CLOSE_EDITOR_COMMAND_ID, id: editorCommands.CLOSE_EDITOR_COMMAND_ID,
title: nls.localize('close', "Close"), title: nls.localize('close', "Close"),
iconPath: { iconDark: 'close-editor-inverse.svg',
dark: URI.parse(require.toUrl('vs/workbench/browser/parts/editor/media/close-editor-inverse.svg')).fsPath, iconLight: 'close-editor.svg'
light: URI.parse(require.toUrl('vs/workbench/browser/parts/editor/media/close-editor.svg')).fsPath }, {
} id: editorCommands.CLOSE_EDITORS_IN_GROUP_COMMAND_ID,
title: nls.localize('closeAll', "Close All"),
iconDark: 'closeall-editors-inverse.svg',
iconLight: 'closeall-editors.svg'
}, },
alt: { ContextKeyExpr.and(ContextKeyExpr.not('config.workbench.editor.showTabs'), ContextKeyExpr.not('groupActiveEditorDirty')),
1000000 // towards the end
);
appendEditorToolItem(
{
id: editorCommands.CLOSE_EDITOR_COMMAND_ID,
title: nls.localize('close', "Close"),
iconDark: 'close-dirty-inverse.svg',
iconLight: 'close-dirty.svg'
}, {
id: editorCommands.CLOSE_EDITORS_IN_GROUP_COMMAND_ID, id: editorCommands.CLOSE_EDITORS_IN_GROUP_COMMAND_ID,
title: nls.localize('closeAll', "Close All"), title: nls.localize('closeAll', "Close All"),
iconPath: { iconDark: 'closeall-editors-inverse.svg',
dark: URI.parse(require.toUrl('vs/workbench/browser/parts/editor/media/closeall-editors-inverse.svg')).fsPath, iconLight: 'closeall-editors.svg'
light: URI.parse(require.toUrl('vs/workbench/browser/parts/editor/media/closeall-editors.svg')).fsPath
}
}, },
group: 'navigation', ContextKeyExpr.and(ContextKeyExpr.not('config.workbench.editor.showTabs'), ContextKeyExpr.has('groupActiveEditorDirty')),
when: ContextKeyExpr.not('config.workbench.editor.showTabs'), 1000000 // towards the end
order: 1000000 // towards the end );
});
// Editor Commands for Command Palette // Editor Commands for Command Palette
MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: editorCommands.KEEP_EDITOR_COMMAND_ID, title: nls.localize('keepEditor', "Keep Editor"), category }, when: ContextKeyExpr.has('config.workbench.editor.enablePreview') }); MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: editorCommands.KEEP_EDITOR_COMMAND_ID, title: nls.localize('keepEditor', "Keep Editor"), category }, when: ContextKeyExpr.has('config.workbench.editor.enablePreview') });
......
...@@ -425,8 +425,10 @@ function registerCloseEditorCommands() { ...@@ -425,8 +425,10 @@ function registerCloseEditorCommands() {
handler: (accessor, resourceOrContext: URI | IEditorCommandsContext, context?: IEditorCommandsContext) => { handler: (accessor, resourceOrContext: URI | IEditorCommandsContext, context?: IEditorCommandsContext) => {
const editorGroupService = accessor.get(IEditorGroupsService); const editorGroupService = accessor.get(IEditorGroupsService);
const contexts = getMultiSelectedEditorContexts(getCommandsContext(resourceOrContext, context), accessor.get(IListService), editorGroupService); const contexts = getMultiSelectedEditorContexts(getCommandsContext(resourceOrContext, context), accessor.get(IListService), editorGroupService);
if (contexts.length === 0 && editorGroupService.activeGroup) {
contexts.push({ groupId: editorGroupService.activeGroup.id }); // If command is triggered from the command palette use the active group const activeGroup = editorGroupService.activeGroup;
if (contexts.length === 0) {
contexts.push({ groupId: activeGroup.id }); // active group as fallback
} }
return TPromise.join(distinct(contexts.map(c => c.groupId)).map(groupId => return TPromise.join(distinct(contexts.map(c => c.groupId)).map(groupId =>
...@@ -464,15 +466,20 @@ function registerCloseEditorCommands() { ...@@ -464,15 +466,20 @@ function registerCloseEditorCommands() {
handler: (accessor, resourceOrContext: URI | IEditorCommandsContext, context?: IEditorCommandsContext) => { handler: (accessor, resourceOrContext: URI | IEditorCommandsContext, context?: IEditorCommandsContext) => {
const editorGroupService = accessor.get(IEditorGroupsService); const editorGroupService = accessor.get(IEditorGroupsService);
const contexts = getMultiSelectedEditorContexts(getCommandsContext(resourceOrContext, context), accessor.get(IListService), editorGroupService); const contexts = getMultiSelectedEditorContexts(getCommandsContext(resourceOrContext, context), accessor.get(IListService), editorGroupService);
const activeGroup = editorGroupService.activeGroup; const activeGroup = editorGroupService.activeGroup;
if (contexts.length === 0 && activeGroup && activeGroup.activeEditor) { if (contexts.length === 0 && activeGroup.activeEditor) {
contexts.push({ groupId: activeGroup.id, editorIndex: activeGroup.getIndexOfEditor(activeGroup.activeEditor) }); contexts.push({ groupId: activeGroup.id, editorIndex: activeGroup.getIndexOfEditor(activeGroup.activeEditor) }); // active editor as fallback
} }
const groupIds = distinct(contexts.map(context => context.groupId)); const groupIds = distinct(contexts.map(context => context.groupId));
return TPromise.join(groupIds.map(groupId => { return TPromise.join(groupIds.map(groupId => {
const group = editorGroupService.getGroup(groupId); const group = editorGroupService.getGroup(groupId);
const editors = contexts.filter(c => c.groupId === groupId).map(c => group.getEditor(c.editorIndex)); const editors = contexts
.filter(context => context.groupId === groupId)
.map(context => typeof context.editorIndex === 'number' ? group.getEditor(context.editorIndex) : group.activeEditor);
return group.closeEditors(editors); return group.closeEditors(editors);
})); }));
} }
...@@ -509,19 +516,18 @@ function registerCloseEditorCommands() { ...@@ -509,19 +516,18 @@ function registerCloseEditorCommands() {
const editorGroupService = accessor.get(IEditorGroupsService); const editorGroupService = accessor.get(IEditorGroupsService);
const contexts = getMultiSelectedEditorContexts(getCommandsContext(resourceOrContext, context), accessor.get(IListService), editorGroupService); const contexts = getMultiSelectedEditorContexts(getCommandsContext(resourceOrContext, context), accessor.get(IListService), editorGroupService);
if (contexts.length === 0) { const activeGroup = editorGroupService.activeGroup;
// Cover the case when run from command palette if (contexts.length === 0 && activeGroup.activeEditor) {
const activeGroup = editorGroupService.activeGroup; contexts.push({ groupId: activeGroup.id, editorIndex: activeGroup.getIndexOfEditor(activeGroup.activeEditor) }); // active editor as fallback
if (activeGroup && activeGroup.activeEditor) {
contexts.push({ groupId: activeGroup.id, editorIndex: activeGroup.getIndexOfEditor(activeGroup.activeEditor) });
}
} }
const groupIds = distinct(contexts.map(context => context.groupId)); const groupIds = distinct(contexts.map(context => context.groupId));
return TPromise.join(groupIds.map(groupId => { return TPromise.join(groupIds.map(groupId => {
const group = editorGroupService.getGroup(groupId); const group = editorGroupService.getGroup(groupId);
const editors = contexts.filter(c => c.groupId === groupId).map(c => group.getEditor(c.editorIndex)); const editors = contexts
.filter(context => context.groupId === groupId)
.map(context => typeof context.editorIndex === 'number' ? group.getEditor(context.editorIndex) : group.activeEditor);
const editorsToClose = group.editors.filter(e => editors.indexOf(e) === -1); const editorsToClose = group.editors.filter(e => editors.indexOf(e) === -1);
return group.closeEditors(editorsToClose); return group.closeEditors(editorsToClose);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
import 'vs/css!./media/editorgroupview'; import 'vs/css!./media/editorgroupview';
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import { EditorGroup, IEditorOpenOptions, EditorCloseEvent, ISerializedEditorGroup, isSerializedEditorGroup } from 'vs/workbench/common/editor/editorGroup'; import { EditorGroup, IEditorOpenOptions, EditorCloseEvent, ISerializedEditorGroup, isSerializedEditorGroup } from 'vs/workbench/common/editor/editorGroup';
import { EditorInput, EditorOptions, GroupIdentifier, ConfirmResult, SideBySideEditorInput, CloseDirection, IEditorCloseEvent } from 'vs/workbench/common/editor'; import { EditorInput, EditorOptions, GroupIdentifier, ConfirmResult, SideBySideEditorInput, CloseDirection, IEditorCloseEvent, EditorGroupActiveEditorDirtyContext } from 'vs/workbench/common/editor';
import { Event, Emitter, once } from 'vs/base/common/event'; import { Event, Emitter, once } from 'vs/base/common/event';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { addClass, addClasses, Dimension, trackFocus, toggleClass, removeClass, addDisposableListener, EventType, EventHelper, findParentWithClass, clearNode, isAncestor } from 'vs/base/browser/dom'; import { addClass, addClasses, Dimension, trackFocus, toggleClass, removeClass, addDisposableListener, EventType, EventHelper, findParentWithClass, clearNode, isAncestor } from 'vs/base/browser/dom';
...@@ -27,7 +27,7 @@ import { ProgressService } from 'vs/workbench/services/progress/browser/progress ...@@ -27,7 +27,7 @@ import { ProgressService } from 'vs/workbench/services/progress/browser/progress
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { isPromiseCanceledError, isErrorWithActions, IErrorWithActions } from 'vs/base/common/errors'; import { isPromiseCanceledError, isErrorWithActions, IErrorWithActions } from 'vs/base/common/errors';
import { dispose } from 'vs/base/common/lifecycle'; import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { Severity, INotificationService, INotificationActions } from 'vs/platform/notification/common/notification'; import { Severity, INotificationService, INotificationActions } from 'vs/platform/notification/common/notification';
import { toErrorMessage } from 'vs/base/common/errorMessage'; import { toErrorMessage } from 'vs/base/common/errorMessage';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
...@@ -172,12 +172,16 @@ export class EditorGroupView extends Themable implements IEditorGroupView { ...@@ -172,12 +172,16 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
this._register(attachProgressBarStyler(this.progressBar, this.themeService)); this._register(attachProgressBarStyler(this.progressBar, this.themeService));
this.progressBar.hide(); this.progressBar.hide();
// Scoped instantiator // Scoped services
const scopedContextKeyService = this._register(this.contextKeyService.createScoped(this.element));
this.scopedInstantiationService = this.instantiationService.createChild(new ServiceCollection( this.scopedInstantiationService = this.instantiationService.createChild(new ServiceCollection(
[IContextKeyService, this._register(this.contextKeyService.createScoped(this.element))], [IContextKeyService, scopedContextKeyService],
[IProgressService, new ProgressService(this.progressBar)] [IProgressService, new ProgressService(this.progressBar)]
)); ));
// Context keys
this.handleGroupContextKeys(scopedContextKeyService);
// Title container // Title container
this.titleContainer = document.createElement('div'); this.titleContainer = document.createElement('div');
addClass(this.titleContainer, 'title'); addClass(this.titleContainer, 'title');
...@@ -205,6 +209,34 @@ export class EditorGroupView extends Themable implements IEditorGroupView { ...@@ -205,6 +209,34 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
this.updateStyles(); this.updateStyles();
} }
private handleGroupContextKeys(contextKeyServcie: IContextKeyService): void {
const groupActiveEditorDirtyContextKey = EditorGroupActiveEditorDirtyContext.bindTo(contextKeyServcie);
let activeEditorListener: IDisposable;
const observeActiveEditor = () => {
activeEditorListener = dispose(activeEditorListener);
const activeEditor = this._group.activeEditor;
if (activeEditor) {
groupActiveEditorDirtyContextKey.set(activeEditor.isDirty());
activeEditorListener = activeEditor.onDidChangeDirty(() => groupActiveEditorDirtyContextKey.set(activeEditor.isDirty()));
} else {
groupActiveEditorDirtyContextKey.set(false);
}
};
// Track the active editor and update context key that reflects
// the dirty state of this editor
this._register(this.onDidGroupChange(e => {
if (e.kind === GroupChangeKind.EDITOR_ACTIVE) {
observeActiveEditor();
}
}));
observeActiveEditor();
}
private registerContainerListeners(): void { private registerContainerListeners(): void {
// Open new file via doubleclick on empty container // Open new file via doubleclick on empty container
......
...@@ -26,22 +26,4 @@ ...@@ -26,22 +26,4 @@
.monaco-workbench > .part.editor > .content .editor-group-container.active > .title .title-actions { .monaco-workbench > .part.editor > .content .editor-group-container.active > .title .title-actions {
opacity: 1; opacity: 1;
}
.vs .monaco-workbench > .part.editor > .content .editor-group-container > .title.dirty .title-actions .close-editor-action {
background: url('close-dirty.svg') center center no-repeat;
}
.vs-dark .monaco-workbench > .part.editor > .content .editor-group-container > .title.dirty .title-actions .close-editor-action,
.hc-black .monaco-workbench > .part.editor > .content .editor-group-container > .title.dirty .title-actions .close-editor-action {
background: url('close-dirty-inverse.svg') center center no-repeat;
}
.vs .monaco-workbench > .part.editor > .content .editor-group-container > .title.dirty .title-actions .close-editor-action:hover {
background: url('close.svg') center center no-repeat;
}
.vs-dark .monaco-workbench > .part.editor > .content .editor-group-container > .title.dirty .title-actions .close-editor-action:hover,
.hc-black .monaco-workbench > .part.editor > .content .editor-group-container > .title.dirty .title-actions .close-editor-action:hover {
background: url('close-inverse.svg') center center no-repeat;
} }
\ No newline at end of file
...@@ -7,12 +7,14 @@ ...@@ -7,12 +7,14 @@
import 'vs/css!./media/notabstitlecontrol'; import 'vs/css!./media/notabstitlecontrol';
import { toResource, Verbosity, IEditorInput } from 'vs/workbench/common/editor'; import { toResource, Verbosity, IEditorInput } from 'vs/workbench/common/editor';
import { TitleControl } from 'vs/workbench/browser/parts/editor/titleControl'; import { TitleControl, IToolbarActions } from 'vs/workbench/browser/parts/editor/titleControl';
import { ResourceLabel } from 'vs/workbench/browser/labels'; import { ResourceLabel } from 'vs/workbench/browser/labels';
import { TAB_ACTIVE_FOREGROUND, TAB_UNFOCUSED_ACTIVE_FOREGROUND } from 'vs/workbench/common/theme'; import { TAB_ACTIVE_FOREGROUND, TAB_UNFOCUSED_ACTIVE_FOREGROUND } from 'vs/workbench/common/theme';
import { EventType as TouchEventType, GestureEvent, Gesture } from 'vs/base/browser/touch'; import { EventType as TouchEventType, GestureEvent, Gesture } from 'vs/base/browser/touch';
import { addDisposableListener, EventType, addClass, EventHelper, removeClass } from 'vs/base/browser/dom'; import { addDisposableListener, EventType, addClass, EventHelper, removeClass } from 'vs/base/browser/dom';
import { IEditorPartOptions } from 'vs/workbench/browser/parts/editor/editor'; import { IEditorPartOptions } from 'vs/workbench/browser/parts/editor/editor';
import { IAction } from 'vs/base/common/actions';
import { CLOSE_EDITOR_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands';
export class NoTabsTitleControl extends TitleControl { export class NoTabsTitleControl extends TitleControl {
private titleContainer: HTMLElement; private titleContainer: HTMLElement;
...@@ -205,4 +207,16 @@ export class NoTabsTitleControl extends TitleControl { ...@@ -205,4 +207,16 @@ export class NoTabsTitleControl extends TitleControl {
default: return Verbosity.MEDIUM; default: return Verbosity.MEDIUM;
} }
} }
protected prepareEditorActions(editorActions: IToolbarActions): { primaryEditorActions: IAction[], secondaryEditorActions: IAction[] } {
const isGroupActive = this.accessor.activeGroup === this.group;
// Group active: show all actions
if (isGroupActive) {
return super.prepareEditorActions(editorActions);
}
// Group inactive: only show close action
return { primaryEditorActions: editorActions.primary.filter(action => action.id === CLOSE_EDITOR_COMMAND_ID), secondaryEditorActions: [] };
}
} }
...@@ -6,11 +6,9 @@ ...@@ -6,11 +6,9 @@
'use strict'; 'use strict';
import 'vs/css!./media/tabstitlecontrol'; import 'vs/css!./media/tabstitlecontrol';
import { TPromise } from 'vs/base/common/winjs.base';
import { isMacintosh } from 'vs/base/common/platform'; import { isMacintosh } from 'vs/base/common/platform';
import { shorten } from 'vs/base/common/labels'; import { shorten } from 'vs/base/common/labels';
import { ActionRunner, IAction } from 'vs/base/common/actions'; import { toResource, GroupIdentifier, IEditorInput, Verbosity, EditorCommandsContextActionRunner } from 'vs/workbench/common/editor';
import { toResource, GroupIdentifier, IEditorInput, Verbosity } from 'vs/workbench/common/editor';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { EventType as TouchEventType, GestureEvent, Gesture } from 'vs/base/browser/touch'; import { EventType as TouchEventType, GestureEvent, Gesture } from 'vs/base/browser/touch';
import { KeyCode } from 'vs/base/common/keyCodes'; import { KeyCode } from 'vs/base/common/keyCodes';
...@@ -393,7 +391,7 @@ export class TabsTitleControl extends TitleControl { ...@@ -393,7 +391,7 @@ export class TabsTitleControl extends TitleControl {
addClass(tabCloseContainer, 'tab-close'); addClass(tabCloseContainer, 'tab-close');
tabContainer.appendChild(tabCloseContainer); tabContainer.appendChild(tabCloseContainer);
const tabActionRunner = new TabActionRunner(() => this.group.id, index); const tabActionRunner = new EditorCommandsContextActionRunner({ groupId: this.group.id, editorIndex: index });
const tabActionBar = new ActionBar(tabCloseContainer, { ariaLabel: localize('araLabelTabActions', "Tab actions"), actionRunner: tabActionRunner }); const tabActionBar = new ActionBar(tabCloseContainer, { ariaLabel: localize('araLabelTabActions', "Tab actions"), actionRunner: tabActionRunner });
tabActionBar.push(this.closeOneEditorAction, { icon: true, label: false, keybinding: this.getKeybindingLabel(this.closeOneEditorAction) }); tabActionBar.push(this.closeOneEditorAction, { icon: true, label: false, keybinding: this.getKeybindingLabel(this.closeOneEditorAction) });
...@@ -1011,25 +1009,6 @@ export class TabsTitleControl extends TitleControl { ...@@ -1011,25 +1009,6 @@ export class TabsTitleControl extends TitleControl {
} }
} }
class TabActionRunner extends ActionRunner {
constructor(
private groupId: () => GroupIdentifier,
private index: number
) {
super();
}
run(action: IAction, context?: any): TPromise<void> {
const groupId = this.groupId();
if (typeof groupId !== 'number') {
return TPromise.as(void 0);
}
return super.run(action, { groupId, editorIndex: this.index });
}
}
registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
// Styling with Outline color (e.g. high contrast theme) // Styling with Outline color (e.g. high contrast theme)
......
...@@ -12,7 +12,7 @@ import { IAction, Action, IRunEvent } from 'vs/base/common/actions'; ...@@ -12,7 +12,7 @@ import { IAction, Action, IRunEvent } from 'vs/base/common/actions';
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
import * as arrays from 'vs/base/common/arrays'; import * as arrays from 'vs/base/common/arrays';
import { toResource, IEditorCommandsContext, IEditorInput } from 'vs/workbench/common/editor'; import { toResource, IEditorCommandsContext, IEditorInput, EditorCommandsContextActionRunner } from 'vs/workbench/common/editor';
import { IActionItem, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar'; import { IActionItem, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar'; import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
...@@ -91,15 +91,18 @@ export abstract class TitleControl extends Themable { ...@@ -91,15 +91,18 @@ export abstract class TitleControl extends Themable {
protected abstract create(parent: HTMLElement): void; protected abstract create(parent: HTMLElement): void;
protected createEditorActionsToolBar(container: HTMLElement): void { protected createEditorActionsToolBar(container: HTMLElement): void {
const context = { groupId: this.group.id } as IEditorCommandsContext;
this.editorActionsToolbar = this._register(new ToolBar(container, this.contextMenuService, { this.editorActionsToolbar = this._register(new ToolBar(container, this.contextMenuService, {
actionItemProvider: action => this.actionItemProvider(action as Action), actionItemProvider: action => this.actionItemProvider(action as Action),
orientation: ActionsOrientation.HORIZONTAL, orientation: ActionsOrientation.HORIZONTAL,
ariaLabel: localize('araLabelEditorActions', "Editor actions"), ariaLabel: localize('araLabelEditorActions', "Editor actions"),
getKeyBinding: action => this.getKeybinding(action) getKeyBinding: action => this.getKeybinding(action),
actionRunner: this._register(new EditorCommandsContextActionRunner(context))
})); }));
// Context // Context
this.editorActionsToolbar.context = { groupId: this.group.id } as IEditorCommandsContext; this.editorActionsToolbar.context = context;
// Action Run Handling // Action Run Handling
this._register(this.editorActionsToolbar.actionRunner.onDidRun((e: IRunEvent) => { this._register(this.editorActionsToolbar.actionRunner.onDidRun((e: IRunEvent) => {
...@@ -138,21 +141,9 @@ export abstract class TitleControl extends Themable { ...@@ -138,21 +141,9 @@ export abstract class TitleControl extends Themable {
} }
protected updateEditorActionsToolbar(): void { protected updateEditorActionsToolbar(): void {
const isGroupActive = this.accessor.activeGroup === this.group;
// Update Editor Actions Toolbar // Update Editor Actions Toolbar
let primaryEditorActions: IAction[] = []; const { primaryEditorActions, secondaryEditorActions } = this.prepareEditorActions(this.getEditorActions());
let secondaryEditorActions: IAction[] = [];
const editorActions = this.getEditorActions();
// Primary actions only for the active group
if (isGroupActive) {
primaryEditorActions = prepareActions(editorActions.primary);
}
// Secondary actions for all groups
secondaryEditorActions = prepareActions(editorActions.secondary);
// Only update if something actually has changed // Only update if something actually has changed
const primaryEditorActionIds = primaryEditorActions.map(a => a.id); const primaryEditorActionIds = primaryEditorActions.map(a => a.id);
...@@ -170,6 +161,23 @@ export abstract class TitleControl extends Themable { ...@@ -170,6 +161,23 @@ export abstract class TitleControl extends Themable {
} }
} }
protected prepareEditorActions(editorActions: IToolbarActions): { primaryEditorActions: IAction[]; secondaryEditorActions: IAction[]; } {
let primaryEditorActions: IAction[];
let secondaryEditorActions: IAction[];
// Primary actions only for the active group
if (this.accessor.activeGroup === this.group) {
primaryEditorActions = prepareActions(editorActions.primary);
} else {
primaryEditorActions = [];
}
// Secondary actions for all groups
secondaryEditorActions = prepareActions(editorActions.secondary);
return { primaryEditorActions, secondaryEditorActions };
}
private getEditorActions(): IToolbarActions { private getEditorActions(): IToolbarActions {
const primary: IAction[] = []; const primary: IAction[] = [];
const secondary: IAction[] = []; const secondary: IAction[] = [];
...@@ -199,9 +207,7 @@ export abstract class TitleControl extends Themable { ...@@ -199,9 +207,7 @@ export abstract class TitleControl extends Themable {
const titleBarMenu = this.menuService.createMenu(MenuId.EditorTitle, scopedContextKeyService); const titleBarMenu = this.menuService.createMenu(MenuId.EditorTitle, scopedContextKeyService);
this.editorToolBarMenuDisposables.push(titleBarMenu); this.editorToolBarMenuDisposables.push(titleBarMenu);
this.editorToolBarMenuDisposables.push(titleBarMenu.onDidChange(() => { this.editorToolBarMenuDisposables.push(titleBarMenu.onDidChange(() => {
this.updateEditorActionsToolbar(); // Update editor toolbar whenever contributed actions change
// Update editor toolbar whenever contributed actions change
this.updateEditorActionsToolbar();
})); }));
fillInActionBarActions(titleBarMenu, { arg: this.resourceContext.get(), shouldForwardArgs: true }, { primary, secondary }); fillInActionBarActions(titleBarMenu, { arg: this.resourceContext.get(), shouldForwardArgs: true }, { primary, secondary });
......
...@@ -20,8 +20,10 @@ import { Schemas } from 'vs/base/common/network'; ...@@ -20,8 +20,10 @@ import { Schemas } from 'vs/base/common/network';
import { LRUCache } from 'vs/base/common/map'; import { LRUCache } from 'vs/base/common/map';
import { IEditorGroupsService, IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService'; import { IEditorGroupsService, IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService';
import { ICompositeControl } from 'vs/workbench/common/composite'; import { ICompositeControl } from 'vs/workbench/common/composite';
import { ActionRunner, IAction } from 'vs/base/common/actions';
export const EditorsVisibleContext = new RawContextKey<boolean>('editorIsOpen', false); export const EditorsVisibleContext = new RawContextKey<boolean>('editorIsOpen', false);
export const EditorGroupActiveEditorDirtyContext = new RawContextKey<boolean>('groupActiveEditorDirty', false);
export const NoEditorsVisibleContext: ContextKeyExpr = EditorsVisibleContext.toNegated(); export const NoEditorsVisibleContext: ContextKeyExpr = EditorsVisibleContext.toNegated();
export const TextCompareEditorVisibleContext = new RawContextKey<boolean>('textCompareEditorVisible', false); export const TextCompareEditorVisibleContext = new RawContextKey<boolean>('textCompareEditorVisible', false);
export const ActiveEditorGroupEmptyContext = new RawContextKey<boolean>('activeEditorGroupEmpty', false); export const ActiveEditorGroupEmptyContext = new RawContextKey<boolean>('activeEditorGroupEmpty', false);
...@@ -924,6 +926,19 @@ export interface IEditorCommandsContext { ...@@ -924,6 +926,19 @@ export interface IEditorCommandsContext {
editorIndex?: number; editorIndex?: number;
} }
export class EditorCommandsContextActionRunner extends ActionRunner {
constructor(
private context: IEditorCommandsContext
) {
super();
}
run(action: IAction, context?: any): TPromise<void> {
return super.run(action, this.context);
}
}
export interface IEditorCloseEvent extends IEditorIdentifier { export interface IEditorCloseEvent extends IEditorIdentifier {
replaced: boolean; replaced: boolean;
index: number; index: number;
......
...@@ -31,7 +31,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView ...@@ -31,7 +31,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
import { Disposable } from 'vs/base/common/lifecycle'; import { Disposable } from 'vs/base/common/lifecycle';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IPartService } from 'vs/workbench/services/part/common/partService'; import { IPartService } from 'vs/workbench/services/part/common/partService';
import { DelegatingWorkbenchEditorService } from 'vs/workbench/services/editor/browser/editorService'; import { DelegatingEditorService } from 'vs/workbench/services/editor/browser/editorService';
import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEditorOptions } from 'vs/platform/editor/common/editor'; import { IEditorOptions } from 'vs/platform/editor/common/editor';
...@@ -189,7 +189,7 @@ export class ExplorerViewlet extends PersistentViewsViewlet implements IExplorer ...@@ -189,7 +189,7 @@ export class ExplorerViewlet extends PersistentViewsViewlet implements IExplorer
// without causing the animation in the opened editors view to kick in and change scroll position. // without causing the animation in the opened editors view to kick in and change scroll position.
// We try to be smart and only use the delay if we recognize that the user action is likely to cause // We try to be smart and only use the delay if we recognize that the user action is likely to cause
// a new entry in the opened editors view. // a new entry in the opened editors view.
const delegatingEditorService = this.instantiationService.createInstance(DelegatingWorkbenchEditorService); const delegatingEditorService = this.instantiationService.createInstance(DelegatingEditorService);
delegatingEditorService.setEditorOpenHandler((group: IEditorGroup, editor: IEditorInput, options?: IEditorOptions) => { delegatingEditorService.setEditorOpenHandler((group: IEditorGroup, editor: IEditorInput, options?: IEditorOptions) => {
let openEditorsView = this.getOpenEditorsView(); let openEditorsView = this.getOpenEditorsView();
if (openEditorsView) { if (openEditorsView) {
......
...@@ -594,7 +594,7 @@ export interface IEditorOpenHandler { ...@@ -594,7 +594,7 @@ export interface IEditorOpenHandler {
* The delegating workbench editor service can be used to override the behaviour of the openEditor() * The delegating workbench editor service can be used to override the behaviour of the openEditor()
* method by providing a IEditorOpenHandler. * method by providing a IEditorOpenHandler.
*/ */
export class DelegatingWorkbenchEditorService extends EditorService { export class DelegatingEditorService extends EditorService {
private editorOpenHandler: IEditorOpenHandler; private editorOpenHandler: IEditorOpenHandler;
constructor( constructor(
......
...@@ -15,7 +15,7 @@ import { EditorInput, EditorOptions, IFileEditorInput, IEditorInput } from 'vs/w ...@@ -15,7 +15,7 @@ import { EditorInput, EditorOptions, IFileEditorInput, IEditorInput } from 'vs/w
import { workbenchInstantiationService } from 'vs/workbench/test/workbenchTestServices'; import { workbenchInstantiationService } from 'vs/workbench/test/workbenchTestServices';
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
import { EditorService, DelegatingWorkbenchEditorService } from 'vs/workbench/services/editor/browser/editorService'; import { EditorService, DelegatingEditorService } from 'vs/workbench/services/editor/browser/editorService';
import { IEditorGroup, IEditorGroupsService, GroupDirection } from 'vs/workbench/services/group/common/editorGroupsService'; import { IEditorGroup, IEditorGroupsService, GroupDirection } from 'vs/workbench/services/group/common/editorGroupsService';
import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart'; import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart';
import { Dimension } from 'vs/base/browser/dom'; import { Dimension } from 'vs/base/browser/dom';
...@@ -260,7 +260,7 @@ suite('Editor service', () => { ...@@ -260,7 +260,7 @@ suite('Editor service', () => {
const ed = instantiationService.createInstance(MyEditor, 'my.editor'); const ed = instantiationService.createInstance(MyEditor, 'my.editor');
const inp = instantiationService.createInstance(ResourceEditorInput, 'name', 'description', URI.parse('my://resource')); const inp = instantiationService.createInstance(ResourceEditorInput, 'name', 'description', URI.parse('my://resource'));
const delegate = instantiationService.createInstance(DelegatingWorkbenchEditorService); const delegate = instantiationService.createInstance(DelegatingEditorService);
delegate.setEditorOpenHandler((group: IEditorGroup, input: IEditorInput, options?: EditorOptions) => { delegate.setEditorOpenHandler((group: IEditorGroup, input: IEditorInput, options?: EditorOptions) => {
assert.strictEqual(input, inp); assert.strictEqual(input, inp);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册