提交 ebbdd353 编写于 作者: S Sandeep Somavarapu

Show disable / enable options as dropdown

上级 49f15b9f
......@@ -83,8 +83,12 @@ export interface IExtensionsRuntimeService {
/**
* Enable or disable the given extension.
* if `workspace` is `true` then enablement is done for workspace, otherwise globally.
*
* Returns a promise that resolves to boolean value.
* if resolves to `true` then requires restart for the change to take effect.
*
* Throws error if enablement is requested for workspace and there is no workspace
*/
setEnablement(identifier: string, enable: boolean, displayName: string): TPromise<boolean>;
setEnablement(identifier: string, enable: boolean, displayName: string, workspace?: boolean): TPromise<boolean>;
}
......@@ -188,7 +188,18 @@ export class ExtensionEditor extends BaseEditor {
this.description = append(details, $('.description'));
const extensionActions = append(details, $('.actions'));
this.extensionActionBar = new ActionBar(extensionActions, { animated: false });
this.extensionActionBar = new ActionBar(extensionActions, {
animated: false,
actionItemProvider: (action: Action) => {
if (action.id === EnableAction.ID) {
return (<EnableAction>action).actionItem;
}
if (action.id === DisableAction.ID) {
return (<DisableAction>action).actionItem;
}
return null;
}
});
this.disposables.push(this.extensionActionBar);
chain(fromEventEmitter<{ error?: any; }>(this.extensionActionBar, 'run'))
......
......@@ -72,7 +72,7 @@ export interface IExtensionsWorkbenchService {
install(vsix: string): TPromise<void>;
install(extension: IExtension, promptToInstallDependencies?: boolean): TPromise<void>;
uninstall(extension: IExtension): TPromise<void>;
setEnablement(extension: IExtension, enable: boolean): TPromise<void>;
setEnablement(extension: IExtension, enable: boolean, workspace?: boolean): TPromise<void>;
loadDependencies(extension: IExtension): TPromise<IExtensionDependencies>;
open(extension: IExtension, sideByside?: boolean): TPromise<any>;
}
......
......@@ -6,10 +6,13 @@
import 'vs/css!./media/extensionActions';
import { localize } from 'vs/nls';
import { TPromise } from 'vs/base/common/winjs.base';
import { Action } from 'vs/base/common/actions';
import { IAction, Action } from 'vs/base/common/actions';
import * as DOM from 'vs/base/browser/dom';
import severity from 'vs/base/common/severity';
import paths = require('vs/base/common/paths');
import Event from 'vs/base/common/event';
import { ActionItem, IActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { ReloadWindowAction } from 'vs/workbench/electron-browser/actions';
import { IExtension, ExtensionState, IExtensionsWorkbenchService, VIEWLET_ID, IExtensionsViewlet, ConfigurationKey } from './extensions';
......@@ -252,20 +255,111 @@ export class UpdateAction extends Action {
}
}
export interface IExtensionAction extends IAction {
extension: IExtension;
}
export class DropDownMenuActionItem extends ActionItem {
private disposables: IDisposable[] = [];
private _extension: IExtension;
constructor(action: IAction, private menuActions: IExtensionAction[], private contextMenuService: IContextMenuService) {
super(null, action, { icon: true, label: true });
this.disposables = [...menuActions];
}
get extension(): IExtension { return this._extension; }
set extension(extension: IExtension) {
this._extension = extension;
for (const menuAction of this.menuActions) {
menuAction.extension = extension;
}
}
public onClick(event: any): void {
DOM.EventHelper.stop(event, true);
let elementPosition = DOM.getDomNodePagePosition(this.builder.getHTMLElement());
const anchor = { x: elementPosition.left, y: elementPosition.top + elementPosition.height + 10 };
this.contextMenuService.showContextMenu({
getAnchor: () => anchor,
getActions: () => TPromise.wrap(this.menuActions),
});
}
dispose(): void {
super.dispose();
this.disposables = dispose(this.disposables);
}
}
export class EnableForWorkspaceAction extends Action {
private _extension: IExtension;
get extension(): IExtension { return this._extension; }
set extension(extension: IExtension) { this._extension = extension; this.update(); }
constructor(
@IWorkspaceContextService private workspaceContextService: IWorkspaceContextService,
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
@IExtensionsRuntimeService private extensionsRuntimeService: IExtensionsRuntimeService
) {
super('extensions.enableForWorkspace', localize('enableForWorkspaceAction', "Workspace"), '', !!workspaceContextService.getWorkspace());
}
private update(): void {
if (!!this.workspaceContextService.getWorkspace()) {
this.enabled = this.extensionsRuntimeService.getDisabledExtensions(true).indexOf(this.extension.identifier) !== -1;
}
}
run(): TPromise<any> {
return this.extensionsWorkbenchService.setEnablement(this.extension, true, true);
}
}
export class EnableGloballyAction extends Action {
private _extension: IExtension;
get extension(): IExtension { return this._extension; }
set extension(extension: IExtension) { this._extension = extension; }
constructor(
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService
) {
super('extensions.enableGlobally', localize('enableGloballyAction', "Global"), '', true);
}
run(): TPromise<any> {
return this.extensionsWorkbenchService.setEnablement(this.extension, true, false);
}
}
export class EnableAction extends Action {
static ID = 'extensions.enable';
private static EnabledClass = 'extension-action enable';
private static DisabledClass = `${EnableAction.EnabledClass} disabled`;
private disposables: IDisposable[] = [];
private _actionItem: EnableActionItem;
get actionItem(): IActionItem { return this._actionItem; }
private _extension: IExtension;
get extension(): IExtension { return this._extension; }
set extension(extension: IExtension) { this._extension = extension; this.update(); }
set extension(extension: IExtension) { this._extension = extension; this._actionItem.extension = extension; this.update(); }
constructor(
@IInstantiationService private instantiationService: IInstantiationService,
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService
) {
super('extensions.enable', localize('enableAction', "Enable"), EnableAction.DisabledClass, false);
super(EnableAction.ID, localize('enableAction', "Enable"), EnableAction.DisabledClass, false);
this._actionItem = this.instantiationService.createInstance(EnableActionItem, this);
this.disposables.push(this._actionItem);
this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update()));
this.update();
......@@ -282,25 +376,71 @@ export class EnableAction extends Action {
this.class = this.enabled ? EnableAction.EnabledClass : EnableAction.DisabledClass;
}
dispose(): void {
super.dispose();
this.disposables = dispose(this.disposables);
}
}
export class DisableForWorkspaceAction extends Action {
private _extension: IExtension;
get extension(): IExtension { return this._extension; }
set extension(extension: IExtension) { this._extension = extension; }
constructor(
@IWorkspaceContextService private workspaceContextService: IWorkspaceContextService,
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService
) {
super('extensions.disableForWorkspace', localize('disableForWorkspaceAction', "Workspace"), '', !!workspaceContextService.getWorkspace());
}
run(): TPromise<any> {
return this.extensionsWorkbenchService.setEnablement(this.extension, false, true);
}
}
export class DisableGloballyAction extends Action {
private _extension: IExtension;
get extension(): IExtension { return this._extension; }
set extension(extension: IExtension) { this._extension = extension; }
constructor(
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService
) {
super('extensions.disableGlobally', localize('disableGloballyAction', "Global"), '', true);
}
run(): TPromise<any> {
return this.extensionsWorkbenchService.setEnablement(this.extension, true);
return this.extensionsWorkbenchService.setEnablement(this.extension, false, false);
}
}
export class DisableAction extends Action {
static ID = 'extensions.disable';
private static EnabledClass = 'extension-action disable';
private static DisabledClass = `${DisableAction.EnabledClass} disabled`;
private disposables: IDisposable[] = [];
private _actionItem: DisableActionItem;
get actionItem(): IActionItem { return this._actionItem; }
private _extension: IExtension;
get extension(): IExtension { return this._extension; }
set extension(extension: IExtension) { this._extension = extension; this.update(); }
set extension(extension: IExtension) { this._extension = extension; this._actionItem.extension = extension; this.update(); }
constructor(
@IInstantiationService private instantiationService: IInstantiationService,
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
) {
super('extensions.disable', localize('disableAction', "Disable"), DisableAction.DisabledClass, false);
super(DisableAction.ID, localize('disableAction', "Disable"), DisableAction.DisabledClass, false);
this._actionItem = this.instantiationService.createInstance(DisableActionItem, this);
this.disposables.push(this._actionItem);
this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update()));
this.update();
......@@ -317,8 +457,27 @@ export class DisableAction extends Action {
this.class = this.enabled ? DisableAction.EnabledClass : DisableAction.DisabledClass;
}
run(): TPromise<any> {
return this.extensionsWorkbenchService.setEnablement(this.extension, false);
dispose(): void {
super.dispose();
this.disposables = dispose(this.disposables);
}
}
export class EnableActionItem extends DropDownMenuActionItem {
constructor(
action: IAction,
@IInstantiationService instantiationService: IInstantiationService,
@IContextMenuService contextMenuService: IContextMenuService) {
super(action, [instantiationService.createInstance(EnableForWorkspaceAction), instantiationService.createInstance(EnableGloballyAction)], contextMenuService);
}
}
export class DisableActionItem extends DropDownMenuActionItem {
constructor(
action: IAction,
@IInstantiationService instantiationService: IInstantiationService,
@IContextMenuService contextMenuService: IContextMenuService) {
super(action, [instantiationService.createInstance(DisableForWorkspaceAction), instantiationService.createInstance(DisableGloballyAction)], contextMenuService);
}
}
......
......@@ -7,6 +7,7 @@
import { append, $, addClass, removeClass } from 'vs/base/browser/dom';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Action } from 'vs/base/common/actions';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IMessageService, Severity } from 'vs/platform/message/common/message';
......@@ -63,7 +64,18 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
const description = append(details, $('.description.ellipsis'));
const footer = append(details, $('.footer'));
const author = append(footer, $('.author.ellipsis'));
const actionbar = new ActionBar(footer, { animated: false });
const actionbar = new ActionBar(footer, {
animated: false,
actionItemProvider: (action: Action) => {
if (action.id === EnableAction.ID) {
return (<EnableAction>action).actionItem;
}
if (action.id === DisableAction.ID) {
return (<DisableAction>action).actionItem;
}
return null;
}
});
actionbar.addListener2(EventType.RUN, ({ error }) => error && this.messageService.show(Severity.Error, error));
......
......@@ -480,9 +480,8 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
return this.extensionService.installFromGallery(gallery, promptToInstallDependencies);
}
setEnablement(extension: IExtension, enable: boolean): TPromise<any> {
return this.extensionsRuntimeService.setEnablement(extension.identifier, enable, extension.displayName).then(restart => {
// this.promptToRestart(extension, enable);
setEnablement(extension: IExtension, enable: boolean, workspace: boolean = false): TPromise<any> {
return this.extensionsRuntimeService.setEnablement(extension.identifier, enable, extension.displayName, workspace).then(restart => {
(<Extension>extension).needsReload = restart;
this.telemetryService.publicLog(enable ? 'extension:enable' : 'extension:disable', extension.telemetryData);
this._onChange.fire();
......
......@@ -13,7 +13,7 @@ import { ExtensionScanner, MessagesCollector } from 'vs/workbench/node/extension
import { IWorkspaceContextService, IWorkspace } from 'vs/platform/workspace/common/workspace';
import { IExtensionsRuntimeService, IExtensionDescription, IMessage } from 'vs/platform/extensions/common/extensions';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IChoiceService, Severity, IMessageService } from 'vs/platform/message/common/message';
import { Severity, IMessageService } from 'vs/platform/message/common/message';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
......@@ -36,7 +36,6 @@ export class ExtensionsRuntimeService implements IExtensionsRuntimeService {
constructor(
@IStorageService private storageService: IStorageService,
@IChoiceService private choiceService: IChoiceService,
@IWorkspaceContextService contextService: IWorkspaceContextService,
@IMessageService private messageService: IMessageService,
@IEnvironmentService private environmentService: IEnvironmentService
......@@ -57,48 +56,27 @@ export class ExtensionsRuntimeService implements IExtensionsRuntimeService {
});
}
public setEnablement(identifier: string, enable: boolean, displayName: string): TPromise<boolean> {
public setEnablement(identifier: string, enable: boolean, displayName: string, workspace: boolean = false): TPromise<boolean> {
const disabled = this.getDisabledExtensionsFromStorage().indexOf(identifier) !== -1;
if (!enable === disabled) {
return TPromise.wrap(true);
}
if (!this.workspace) {
return this.setGlobalEnablement(identifier, enable, displayName);
if (workspace && !this.workspace) {
return TPromise.wrapError(localize('noWorkspace', "No workspace."));
}
if (enable) {
if (this.getDisabledExtensionsFromStorage(StorageScope.GLOBAL).indexOf(identifier) !== -1) {
return this.choiceService.choose(Severity.Info, localize('enableExtensionGlobally', "Would you like to enable '{0}' extension globally?", displayName),
[localize('yes', "Yes"), localize('no', "No")])
.then((option) => {
if (option === 0) {
return TPromise.join([this.enableExtension(identifier, StorageScope.GLOBAL), this.enableExtension(identifier, StorageScope.WORKSPACE)]).then(() => true);
}
return TPromise.wrap(false);
});
if (workspace) {
return this.enableExtension(identifier, StorageScope.WORKSPACE);
}
return this.choiceService.choose(Severity.Info, localize('enableExtensionForWorkspace', "Would you like to enable '{0}' extension for this workspace?", displayName),
[localize('yes', "Yes"), localize('no', "No")])
.then((option) => {
if (option === 0) {
return this.enableExtension(identifier, StorageScope.WORKSPACE).then(() => true);
}
return TPromise.wrap(false);
});
return this.enableExtension(identifier, StorageScope.GLOBAL);
} else {
return this.choiceService.choose(Severity.Info, localize('disableExtension', "Would you like to disable '{0}' extension for this workspace or globally?", displayName),
[localize('workspace', "Workspace"), localize('globally', "Globally"), localize('cancel', "Cancel")])
.then((option) => {
switch (option) {
case 0:
return this.disableExtension(identifier, StorageScope.WORKSPACE);
case 1:
return this.disableExtension(identifier, StorageScope.GLOBAL);
default: return TPromise.wrap(false);
}
});
if (workspace) {
return this.disableExtension(identifier, StorageScope.WORKSPACE);
}
return this.disableExtension(identifier, StorageScope.GLOBAL);
}
}
......@@ -130,28 +108,6 @@ export class ExtensionsRuntimeService implements IExtensionsRuntimeService {
return [...globallyDisabled, ...workspaceDisabled];
}
private setGlobalEnablement(identifier: string, enable: boolean, displayName: string): TPromise<boolean> {
if (enable) {
return this.choiceService.choose(Severity.Info, localize('enableExtensionGloballyNoWorkspace', "Would you like to enable '{0}' extension globally?", displayName),
[localize('yes', "Yes"), localize('no', "No")])
.then((option) => {
if (option === 0) {
return this.enableExtension(identifier, StorageScope.GLOBAL).then(() => true);
}
return TPromise.wrap(false);
});
} else {
return this.choiceService.choose(Severity.Info, localize('disableExtensionGlobally', "Would you like to disable '{0}' extension globally?", displayName),
[localize('yes', "Yes"), localize('no', "No")])
.then((option) => {
if (option === 0) {
return this.disableExtension(identifier, StorageScope.GLOBAL).then(() => true);
}
return TPromise.wrap(false);
});
}
}
private disableExtension(identifier: string, scope: StorageScope): TPromise<boolean> {
let disabledExtensions = this._getDisabledExtensions(scope);
disabledExtensions.push(identifier);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册