Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Read Only mode #106323

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions src/vs/workbench/browser/parts/editor/editorStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ class StateChange {
tabFocusMode: boolean = false;
columnSelectionMode: boolean = false;
screenReaderMode: boolean = false;
readOnlyMode: boolean = false;
metadata: boolean = false;

combine(other: StateChange) {
Expand All @@ -156,6 +157,7 @@ class StateChange {
this.tabFocusMode = this.tabFocusMode || other.tabFocusMode;
this.columnSelectionMode = this.columnSelectionMode || other.columnSelectionMode;
this.screenReaderMode = this.screenReaderMode || other.screenReaderMode;
this.readOnlyMode = this.readOnlyMode || other.readOnlyMode;
this.metadata = this.metadata || other.metadata;
}

Expand All @@ -168,6 +170,7 @@ class StateChange {
|| this.tabFocusMode
|| this.columnSelectionMode
|| this.screenReaderMode
|| this.readOnlyMode
|| this.metadata;
}
}
Expand All @@ -181,6 +184,7 @@ type StateDelta = (
| { type: 'tabFocusMode'; tabFocusMode: boolean; }
| { type: 'columnSelectionMode'; columnSelectionMode: boolean; }
| { type: 'screenReaderMode'; screenReaderMode: boolean; }
| { type: 'readOnlyMode'; readOnlyMode: boolean; }
| { type: 'metadata'; metadata: string | undefined; }
);

Expand Down Expand Up @@ -210,6 +214,9 @@ class State {
private _screenReaderMode: boolean | undefined;
get screenReaderMode(): boolean | undefined { return this._screenReaderMode; }

private _readOnlyMode: boolean | undefined;
get readOnlyMode(): boolean | undefined { return this._readOnlyMode; }

private _metadata: string | undefined;
get metadata(): string | undefined { return this._metadata; }

Expand Down Expand Up @@ -272,6 +279,13 @@ class State {
}
}

if (update.type === 'readOnlyMode') {
if (this._readOnlyMode !== update.readOnlyMode) {
this._readOnlyMode = update.readOnlyMode;
change.readOnlyMode = true;
}
}

if (update.type === 'metadata') {
if (this._metadata !== update.metadata) {
this._metadata = update.metadata;
Expand All @@ -294,6 +308,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
private readonly tabFocusModeElement = this._register(new MutableDisposable<IStatusbarEntryAccessor>());
private readonly columnSelectionModeElement = this._register(new MutableDisposable<IStatusbarEntryAccessor>());
private readonly screenRedearModeElement = this._register(new MutableDisposable<IStatusbarEntryAccessor>());
private readonly readOnlyModeElement = this._register(new MutableDisposable<IStatusbarEntryAccessor>());
private readonly indentationElement = this._register(new MutableDisposable<IStatusbarEntryAccessor>());
private readonly selectionElement = this._register(new MutableDisposable<IStatusbarEntryAccessor>());
private readonly encodingElement = this._register(new MutableDisposable<IStatusbarEntryAccessor>());
Expand Down Expand Up @@ -450,6 +465,23 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
}
}

private updateReadOnlyModeElement(visible: boolean): void {
if (visible) {
if (!this.readOnlyModeElement.value) {
const text = nls.localize('readOnlyModeEnabled', "Read Only Mode");
this.readOnlyModeElement.value = this.statusbarService.addEntry({
text,
ariaLabel: text,
command: 'workbench.action.toggleReadOnlyMode',
backgroundColor: themeColorFromId(STATUS_BAR_PROMINENT_ITEM_BACKGROUND),
color: themeColorFromId(STATUS_BAR_PROMINENT_ITEM_FOREGROUND)
}, 'status.editor.readOnlyMode', nls.localize('status.editor.readOnlyMode', "Read Only Mode"), StatusbarAlignment.RIGHT, 100.9);
}
} else {
this.readOnlyModeElement.clear();
}
}

private updateSelectionElement(text: string | undefined): void {
if (!text) {
this.selectionElement.clear();
Expand Down Expand Up @@ -580,6 +612,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
this.updateTabFocusModeElement(!!this.state.tabFocusMode);
this.updateColumnSelectionModeElement(!!this.state.columnSelectionMode);
this.updateScreenReaderModeElement(!!this.state.screenReaderMode);
this.updateReadOnlyModeElement(!!this.state.readOnlyMode);
this.updateIndentationElement(this.state.indentation);
this.updateSelectionElement(this.state.selectionStatus);
this.updateEncodingElement(this.state.encoding);
Expand Down Expand Up @@ -620,6 +653,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
// Update all states
this.onColumnSelectionModeChange(activeCodeEditor);
this.onScreenReaderModeChange(activeCodeEditor);
this.onReadOnlyModeChange(activeCodeEditor);
this.onSelectionChange(activeCodeEditor);
this.onModeChange(activeCodeEditor, activeInput);
this.onEOLChange(activeCodeEditor);
Expand All @@ -634,6 +668,13 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
// Attach new listeners to active editor
if (activeCodeEditor) {

// Register listener for Read Only Mode
this._register(this.configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration('workbench.editor.readOnlyMode')) {
this.onReadOnlyModeChange(activeCodeEditor);
}
}));

// Hook Listener for Configuration changes
this.activeEditorListeners.add(activeCodeEditor.onDidChangeConfiguration((event: ConfigurationChangedEvent) => {
if (event.hasChanged(EditorOption.columnSelection)) {
Expand Down Expand Up @@ -882,6 +923,17 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
this.updateState(info);
}

private onReadOnlyModeChange(editorWidget: ICodeEditor | undefined): void {
let readOnlyMode = false;

if (editorWidget) {
readOnlyMode = this.configurationService.getValue<boolean>('workbench.editor.readOnlyMode');
editorWidget.updateOptions({ readOnly: readOnlyMode });
}

this.updateState({ type: 'readOnlyMode', readOnlyMode: readOnlyMode });
}

private isActiveEditor(control: IEditorPane): boolean {
const activeEditorPane = this.editorService.activeEditorPane;

Expand Down
5 changes: 5 additions & 0 deletions src/vs/workbench/browser/workbench.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@ import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuratio
'default': false,
'description': nls.localize('perEditorGroup', "Controls if the limit of maximum opened editors should apply per editor group or across all editor groups.")
},
'workbench.editor.readOnlyMode': {
'type': 'boolean',
'default': false,
'description': nls.localize('readOnlyMode', "Controls whether the editor should be read-only.")
},
'workbench.commandPalette.history': {
'type': 'number',
'description': nls.localize('commandHistory', "Controls the number of recently used commands to keep in history for the command palette. Set to 0 to disable command history."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import './saveParticipants';
import './toggleColumnSelection';
import './toggleMinimap';
import './toggleMultiCursorModifier';
import './toggleReadOnlyMode';
import './toggleRenderControlCharacter';
import './toggleRenderWhitespace';
import './toggleWordWrap';
Expand Down
53 changes: 53 additions & 0 deletions src/vs/workbench/contrib/codeEditor/browser/toggleReadOnlyMode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as nls from 'vs/nls';
import { Action } from 'vs/base/common/actions';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { MenuId, MenuRegistry, SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { Registry } from 'vs/platform/registry/common/platform';
import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions';

export class ToggleReadOnlyModeAction extends Action {

public static readonly ID = 'workbench.action.toggleReadOnlyMode';
public static readonly LABEL = nls.localize('toggleReadOnlyMode', "Toggle Read Only Mode");

constructor(
id: string,
label: string,
@IConfigurationService private readonly _configurationService: IConfigurationService,
@INotificationService private readonly notificationService: INotificationService
) {
super(id, label);
}

public run(): Promise<any> {
let newReadOnlyMode = !this._configurationService.getValue<boolean>('workbench.editor.readOnlyMode');

if (newReadOnlyMode) {
this.notificationService.info(nls.localize('toggle.readOnlyMode.on', "Read Only Mode has been turned on."));
} else {
this.notificationService.info(nls.localize('toggle.readOnlyMode.off', "Read Only Mode has been turned off."));
}

return this._configurationService.updateValue('workbench.editor.readOnlyMode', newReadOnlyMode, ConfigurationTarget.USER);
}
}

const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleReadOnlyModeAction), 'View: Toggle Read Only Mode', nls.localize('view', "View"));

MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, {
group: '5_editor',
command: {
id: ToggleReadOnlyModeAction.ID,
title: nls.localize({ key: 'miToggleReadOnlyMode', comment: ['&& denotes a mnemonic'] }, "Toggle &&Read Only Mode"),
toggled: ContextKeyExpr.equals('config.workbench.editor.readOnlyMode', true)
},
order: 5
});