SQL Operations Studio Public Preview 1 (0.23) release source code

This commit is contained in:
Karl Burtram
2017-11-09 14:30:27 -08:00
parent b88ecb8d93
commit 3cdac41339
8829 changed files with 759707 additions and 286 deletions

View File

@@ -0,0 +1,58 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.monaco-workbench > .part.statusbar {
box-sizing: border-box;
width: 100%;
height: 22px;
font-size: 12px;
padding: 0 10px;
overflow: hidden;
}
.monaco-workbench > .part.statusbar > .statusbar-item {
display: inline-block;
line-height: 22px;
height: 100%;
vertical-align: top;
}
.monaco-workbench > .part.statusbar > .statusbar-item.left > :first-child {
margin-right: 5px;
}
.monaco-workbench > .part.statusbar > .statusbar-item.right {
float: right;
}
.monaco-workbench > .part.statusbar > .statusbar-item.right > :first-child {
margin-left: 5px;
}
.monaco-workbench > .part.statusbar > .statusbar-item a:not([disabled]):not(.disabled) {
cursor: pointer;
display: inline-block;
height: 100%;
}
.monaco-workbench > .part.statusbar > .statusbar-entry > span {
cursor: default;
height: 100%;
}
.monaco-workbench > .part.statusbar > .statusbar-entry > span,
.monaco-workbench > .part.statusbar > .statusbar-entry > a:not([disabled]) {
padding: 0 5px 0 5px;
white-space: pre; /* gives some degree of styling */
}
.monaco-workbench > .part.statusbar > .statusbar-entry span.octicon {
text-align: center;
font-size: 14px;
}
.monaco-workbench > .part.statusbar > .statusbar-item a:hover:not([disabled]):not(.disabled) {
text-decoration: none;
}

View File

@@ -0,0 +1,58 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { Registry } from 'vs/platform/registry/common/platform';
import { IDisposable } from 'vs/base/common/lifecycle';
import * as statusbarService from 'vs/platform/statusbar/common/statusbar';
import { SyncDescriptor0, createSyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IConstructorSignature0 } from 'vs/platform/instantiation/common/instantiation';
export interface IStatusbarItem {
render(element: HTMLElement): IDisposable;
}
export import StatusbarAlignment = statusbarService.StatusbarAlignment;
export class StatusbarItemDescriptor {
public syncDescriptor: SyncDescriptor0<IStatusbarItem>;
public alignment: StatusbarAlignment;
public priority: number;
constructor(ctor: IConstructorSignature0<IStatusbarItem>, alignment?: StatusbarAlignment, priority?: number) {
this.syncDescriptor = createSyncDescriptor(ctor);
this.alignment = alignment || StatusbarAlignment.LEFT;
this.priority = priority || 0;
}
}
export interface IStatusbarRegistry {
registerStatusbarItem(descriptor: StatusbarItemDescriptor): void;
items: StatusbarItemDescriptor[];
}
class StatusbarRegistry implements IStatusbarRegistry {
private _items: StatusbarItemDescriptor[];
constructor() {
this._items = [];
}
public get items(): StatusbarItemDescriptor[] {
return this._items;
}
public registerStatusbarItem(descriptor: StatusbarItemDescriptor): void {
this._items.push(descriptor);
}
}
export const Extensions = {
Statusbar: 'workbench.contributions.statusbar'
};
Registry.add(Extensions.Statusbar, new StatusbarRegistry());

View File

@@ -0,0 +1,352 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import 'vs/css!./media/statusbarpart';
import dom = require('vs/base/browser/dom');
import nls = require('vs/nls');
import { toErrorMessage } from 'vs/base/common/errorMessage';
import { TPromise } from 'vs/base/common/winjs.base';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { Builder, $ } from 'vs/base/browser/builder';
import { OcticonLabel } from 'vs/base/browser/ui/octiconLabel/octiconLabel';
import { Registry } from 'vs/platform/registry/common/platform';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { Part } from 'vs/workbench/browser/part';
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actionRegistry';
import { StatusbarAlignment, IStatusbarRegistry, Extensions, IStatusbarItem } from 'vs/workbench/browser/parts/statusbar/statusbar';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IMessageService, Severity } from 'vs/platform/message/common/message';
import { IStatusbarService, IStatusbarEntry } from 'vs/platform/statusbar/common/statusbar';
import { getCodeEditor } from 'vs/editor/common/services/codeEditorService';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { Action } from 'vs/base/common/actions';
import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
import { STATUS_BAR_BACKGROUND, STATUS_BAR_FOREGROUND, STATUS_BAR_NO_FOLDER_BACKGROUND, STATUS_BAR_ITEM_HOVER_BACKGROUND, STATUS_BAR_ITEM_ACTIVE_BACKGROUND, STATUS_BAR_PROMINENT_ITEM_BACKGROUND, STATUS_BAR_PROMINENT_ITEM_HOVER_BACKGROUND, STATUS_BAR_BORDER, STATUS_BAR_NO_FOLDER_FOREGROUND, STATUS_BAR_NO_FOLDER_BORDER } from 'vs/workbench/common/theme';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { contrastBorder } from 'vs/platform/theme/common/colorRegistry';
import { isThemeColor } from 'vs/editor/common/editorCommon';
import { Color } from 'vs/base/common/color';
export class StatusbarPart extends Part implements IStatusbarService {
public _serviceBrand: any;
private static PRIORITY_PROP = 'priority';
private static ALIGNMENT_PROP = 'alignment';
private statusItemsContainer: Builder;
private statusMsgDispose: IDisposable;
constructor(
id: string,
@IInstantiationService private instantiationService: IInstantiationService,
@IThemeService themeService: IThemeService,
@IWorkspaceContextService private contextService: IWorkspaceContextService
) {
super(id, { hasTitle: false }, themeService);
this.registerListeners();
}
private registerListeners(): void {
this.toUnbind.push(this.contextService.onDidChangeWorkspaceRoots(() => this.updateStyles()));
}
public addEntry(entry: IStatusbarEntry, alignment: StatusbarAlignment, priority: number = 0): IDisposable {
// Render entry in status bar
const el = this.doCreateStatusItem(alignment, priority);
const item = this.instantiationService.createInstance(StatusBarEntryItem, entry);
const toDispose = item.render(el);
// Insert according to priority
const container = this.statusItemsContainer.getHTMLElement();
const neighbours = this.getEntries(alignment);
let inserted = false;
for (let i = 0; i < neighbours.length; i++) {
const neighbour = neighbours[i];
const nPriority = $(neighbour).getProperty(StatusbarPart.PRIORITY_PROP);
if (
alignment === StatusbarAlignment.LEFT && nPriority < priority ||
alignment === StatusbarAlignment.RIGHT && nPriority > priority
) {
container.insertBefore(el, neighbour);
inserted = true;
break;
}
}
if (!inserted) {
container.appendChild(el);
}
return {
dispose: () => {
$(el).destroy();
if (toDispose) {
toDispose.dispose();
}
}
};
}
private getEntries(alignment: StatusbarAlignment): HTMLElement[] {
const entries: HTMLElement[] = [];
const container = this.statusItemsContainer.getHTMLElement();
const children = container.children;
for (let i = 0; i < children.length; i++) {
const childElement = <HTMLElement>children.item(i);
if ($(childElement).getProperty(StatusbarPart.ALIGNMENT_PROP) === alignment) {
entries.push(childElement);
}
}
return entries;
}
public createContentArea(parent: Builder): Builder {
this.statusItemsContainer = $(parent);
// Fill in initial items that were contributed from the registry
const registry = Registry.as<IStatusbarRegistry>(Extensions.Statusbar);
const leftDescriptors = registry.items.filter(d => d.alignment === StatusbarAlignment.LEFT).sort((a, b) => b.priority - a.priority);
const rightDescriptors = registry.items.filter(d => d.alignment === StatusbarAlignment.RIGHT).sort((a, b) => a.priority - b.priority);
const descriptors = rightDescriptors.concat(leftDescriptors); // right first because they float
this.toUnbind.push(...descriptors.map(descriptor => {
const item = this.instantiationService.createInstance(descriptor.syncDescriptor);
const el = this.doCreateStatusItem(descriptor.alignment, descriptor.priority);
const dispose = item.render(el);
this.statusItemsContainer.append(el);
return dispose;
}));
return this.statusItemsContainer;
}
protected updateStyles(): void {
super.updateStyles();
const container = this.getContainer();
container.style('color', this.getColor(this.contextService.hasWorkspace() ? STATUS_BAR_FOREGROUND : STATUS_BAR_NO_FOLDER_FOREGROUND));
container.style('background-color', this.getColor(this.contextService.hasWorkspace() ? STATUS_BAR_BACKGROUND : STATUS_BAR_NO_FOLDER_BACKGROUND));
const borderColor = this.getColor(this.contextService.hasWorkspace() ? STATUS_BAR_BORDER : STATUS_BAR_NO_FOLDER_BORDER) || this.getColor(contrastBorder);
container.style('border-top-width', borderColor ? '1px' : null);
container.style('border-top-style', borderColor ? 'solid' : null);
container.style('border-top-color', borderColor);
}
private doCreateStatusItem(alignment: StatusbarAlignment, priority: number = 0): HTMLElement {
const el = document.createElement('div');
dom.addClass(el, 'statusbar-item');
if (alignment === StatusbarAlignment.RIGHT) {
dom.addClass(el, 'right');
} else {
dom.addClass(el, 'left');
}
$(el).setProperty(StatusbarPart.PRIORITY_PROP, priority);
$(el).setProperty(StatusbarPart.ALIGNMENT_PROP, alignment);
return el;
}
public setStatusMessage(message: string, autoDisposeAfter: number = -1, delayBy: number = 0): IDisposable {
if (this.statusMsgDispose) {
this.statusMsgDispose.dispose(); // dismiss any previous
}
// Create new
let statusDispose: IDisposable;
let showHandle = setTimeout(() => {
statusDispose = this.addEntry({ text: message }, StatusbarAlignment.LEFT, -Number.MAX_VALUE /* far right on left hand side */);
showHandle = null;
}, delayBy);
let hideHandle: number;
// Dispose function takes care of timeouts and actual entry
const dispose = {
dispose: () => {
if (showHandle) {
clearTimeout(showHandle);
}
if (hideHandle) {
clearTimeout(hideHandle);
}
if (statusDispose) {
statusDispose.dispose();
}
}
};
this.statusMsgDispose = dispose;
if (typeof autoDisposeAfter === 'number' && autoDisposeAfter > 0) {
hideHandle = setTimeout(() => dispose.dispose(), autoDisposeAfter);
}
return dispose;
}
}
let manageExtensionAction: ManageExtensionAction;
class StatusBarEntryItem implements IStatusbarItem {
private entry: IStatusbarEntry;
constructor(
entry: IStatusbarEntry,
@ICommandService private commandService: ICommandService,
@IInstantiationService private instantiationService: IInstantiationService,
@IMessageService private messageService: IMessageService,
@ITelemetryService private telemetryService: ITelemetryService,
@IContextMenuService private contextMenuService: IContextMenuService,
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
@IThemeService private themeService: IThemeService
) {
this.entry = entry;
if (!manageExtensionAction) {
manageExtensionAction = this.instantiationService.createInstance(ManageExtensionAction);
}
}
public render(el: HTMLElement): IDisposable {
let toDispose: IDisposable[] = [];
dom.addClass(el, 'statusbar-entry');
// Text Container
let textContainer: HTMLElement;
if (this.entry.command) {
textContainer = document.createElement('a');
$(textContainer).on('click', () => this.executeCommand(this.entry.command, this.entry.arguments), toDispose);
} else {
textContainer = document.createElement('span');
}
// Label
new OcticonLabel(textContainer).text = this.entry.text;
// Tooltip
if (this.entry.tooltip) {
$(textContainer).title(this.entry.tooltip);
}
// Color
let color = this.entry.color;
if (color) {
if (isThemeColor(color)) {
let colorId = color.id;
color = (this.themeService.getTheme().getColor(colorId) || Color.transparent).toString();
toDispose.push(this.themeService.onThemeChange(theme => {
let colorValue = (this.themeService.getTheme().getColor(colorId) || Color.transparent).toString();
$(textContainer).color(colorValue);
}));
}
$(textContainer).color(color);
}
// Context Menu
if (this.entry.extensionId) {
$(textContainer).on('contextmenu', e => {
dom.EventHelper.stop(e, true);
this.contextMenuService.showContextMenu({
getAnchor: () => el,
getActionsContext: () => this.entry.extensionId,
getActions: () => TPromise.as([manageExtensionAction])
});
}, toDispose);
}
el.appendChild(textContainer);
return {
dispose: () => {
toDispose = dispose(toDispose);
}
};
}
private executeCommand(id: string, args?: any[]) {
args = args || [];
// Lookup built in commands
const builtInActionDescriptor = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions).getWorkbenchAction(id);
if (builtInActionDescriptor) {
const action = this.instantiationService.createInstance(builtInActionDescriptor.syncDescriptor);
if (action.enabled) {
this.telemetryService.publicLog('workbenchActionExecuted', { id: action.id, from: 'status bar' });
(action.run() || TPromise.as(null)).done(() => {
action.dispose();
}, (err) => this.messageService.show(Severity.Error, toErrorMessage(err)));
} else {
this.messageService.show(Severity.Warning, nls.localize('canNotRun', "Command '{0}' is currently not enabled and can not be run.", action.label || id));
}
return;
}
// Maintain old behaviour of always focusing the editor here
const activeEditor = this.editorService.getActiveEditor();
const codeEditor = getCodeEditor(activeEditor);
if (codeEditor) {
codeEditor.focus();
}
// Fallback to the command service for any other case
this.commandService.executeCommand(id, ...args).done(undefined, err => this.messageService.show(Severity.Error, toErrorMessage(err)));
}
}
class ManageExtensionAction extends Action {
constructor(
@ICommandService private commandService: ICommandService
) {
super('statusbar.manage.extension', nls.localize('manageExtension', "Manage Extension"));
}
public run(extensionId: string): TPromise<any> {
return this.commandService.executeCommand('_extensions.manage', extensionId);
}
}
registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
const statusBarItemHoverBackground = theme.getColor(STATUS_BAR_ITEM_HOVER_BACKGROUND);
if (statusBarItemHoverBackground) {
collector.addRule(`.monaco-workbench > .part.statusbar > .statusbar-item a:hover:not([disabled]):not(.disabled) { background-color: ${statusBarItemHoverBackground}; }`);
}
const statusBarItemActiveBackground = theme.getColor(STATUS_BAR_ITEM_ACTIVE_BACKGROUND);
if (statusBarItemActiveBackground) {
collector.addRule(`.monaco-workbench > .part.statusbar > .statusbar-item a:active:not([disabled]):not(.disabled) { background-color: ${statusBarItemActiveBackground}; }`);
}
const statusBarProminentItemBackground = theme.getColor(STATUS_BAR_PROMINENT_ITEM_BACKGROUND);
if (statusBarProminentItemBackground) {
collector.addRule(`.monaco-workbench > .part.statusbar > .statusbar-item .status-bar-info { background-color: ${statusBarProminentItemBackground}; }`);
}
const statusBarProminentItemHoverBackground = theme.getColor(STATUS_BAR_PROMINENT_ITEM_HOVER_BACKGROUND);
if (statusBarProminentItemHoverBackground) {
collector.addRule(`.monaco-workbench > .part.statusbar > .statusbar-item a.status-bar-info:hover:not([disabled]):not(.disabled) { background-color: ${statusBarProminentItemHoverBackground}; }`);
}
});