diff --git a/src/sql/workbench/parts/query/browser/messagePanel.ts b/src/sql/workbench/parts/query/browser/messagePanel.ts index 781c22b454..6e40f0e41f 100644 --- a/src/sql/workbench/parts/query/browser/messagePanel.ts +++ b/src/sql/workbench/parts/query/browser/messagePanel.ts @@ -6,15 +6,12 @@ import 'vs/css!./media/messagePanel'; import { IMessagesActionContext, CopyMessagesAction, CopyAllMessagesAction } from './actions'; import QueryRunner, { IQueryMessage } from 'sql/platform/query/common/queryRunner'; -import { QueryInput } from 'sql/workbench/parts/query/common/queryInput'; import { IExpandableTree } from 'sql/workbench/parts/objectExplorer/browser/treeUpdateUtils'; import { ISelectionData } from 'azdata'; -import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; import { IDataSource, ITree, IRenderer, ContextMenuEvent } from 'vs/base/parts/tree/browser/tree'; import { generateUuid } from 'vs/base/common/uuid'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { Tree } from 'vs/base/parts/tree/browser/treeImpl'; @@ -24,12 +21,14 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { OpenMode, ClickBehavior, ICancelableEvent, IControllerOptions } from 'vs/base/parts/tree/browser/treeDefaults'; import { WorkbenchTreeController } from 'vs/platform/list/browser/listService'; import { IMouseEvent } from 'vs/base/browser/mouseEvent'; -import { isArray, isUndefinedOrNull } from 'vs/base/common/types'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { isArray } from 'vs/base/common/types'; +import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ScrollbarVisibility } from 'vs/base/common/scrollable'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; -import { $ } from 'vs/base/browser/dom'; +import { $, Dimension } from 'vs/base/browser/dom'; +import { QueryEditor } from 'sql/workbench/parts/query/browser/queryEditor'; +import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; export interface IResultMessageIntern extends IQueryMessage { id?: string; @@ -62,21 +61,13 @@ const TemplateIds = { export class MessagePanelState { public scrollPosition: number; - public collapsed = false; - - constructor(@IConfigurationService configurationService: IConfigurationService) { - let messagesOpenedSettings = configurationService.getValue('sql.messagesDefaultOpen'); - if (!isUndefinedOrNull(messagesOpenedSettings)) { - this.collapsed = !messagesOpenedSettings; - } - } dispose() { } } -export class MessagePanel extends ViewletPanel { +export class MessagePanel extends Disposable { private messageLineCountMap = new Map(); private ds = new MessageDataSource(); private renderer = new MessageRenderer(this.messageLineCountMap); @@ -90,23 +81,19 @@ export class MessagePanel extends ViewletPanel { private tree: ITree; constructor( - options: IViewletPanelOptions, - @IKeybindingService keybindingService: IKeybindingService, - @IContextMenuService contextMenuService: IContextMenuService, - @IConfigurationService configurationService: IConfigurationService, - @IThemeService private themeService: IThemeService, @IInstantiationService instantiationService: IInstantiationService, - @IClipboardService private clipboardService: IClipboardService + @IThemeService private readonly themeService: IThemeService, + @IClipboardService private readonly clipboardService: IClipboardService, + @IContextMenuService private readonly contextMenuService: IContextMenuService ) { - super(options, keybindingService, contextMenuService, configurationService); + super(); this.controller = instantiationService.createInstance(MessageController, { openMode: OpenMode.SINGLE_CLICK, clickBehavior: ClickBehavior.ON_MOUSE_UP /* do not change, to preserve focus behaviour in input field */ }); this.controller.toFocusOnClick = this.model; - this.tree = new Tree(this.container, { + this.tree = this._register(new Tree(this.container, { dataSource: this.ds, renderer: this.renderer, controller: this.controller - }, { keyboardSupport: false, horizontalScrollMode: ScrollbarVisibility.Auto }); - this.disposables.push(this.tree); + }, { keyboardSupport: false, horizontalScrollMode: ScrollbarVisibility.Auto })); this.tree.onDidScroll(e => { // convert to old VS Code tree interface with expandable methods let expandableTree: IExpandableTree = this.tree; @@ -115,11 +102,6 @@ export class MessagePanel extends ViewletPanel { this.state.scrollPosition = expandableTree.getScrollPosition(); } }); - this.onDidChange(e => { - if (this.state) { - this.state.collapsed = !this.isExpanded(); - } - }); this.controller.onKeyDown = (tree, event) => { if (event.ctrlKey) { let context: IMessagesActionContext = { @@ -171,20 +153,20 @@ export class MessagePanel extends ViewletPanel { }; } - protected renderBody(container: HTMLElement): void { + public render(container: HTMLElement): void { this.container.style.width = '100%'; this.container.style.height = '100%'; - this.disposables.push(attachListStyler(this.tree, this.themeService)); + this._register(attachListStyler(this.tree, this.themeService)); container.appendChild(this.container); this.tree.setInput(this.model); } - protected layoutBody(size: number): void { + public layout(size: Dimension): void { // convert to old VS Code tree interface with expandable methods let expandableTree: IExpandableTree = this.tree; const previousScrollPosition = expandableTree.getScrollPosition(); - this.tree.layout(size); + this.tree.layout(size.height); if (this.state && this.state.scrollPosition) { expandableTree.setScrollPosition(this.state.scrollPosition); } else { @@ -204,21 +186,11 @@ export class MessagePanel extends ViewletPanel { } private onMessage(message: IQueryMessage | IQueryMessage[]) { - let hasError = false; - let lines: number; if (isArray(message)) { - hasError = message.find(e => e.isError) ? true : false; - lines = message.reduce((currentTotal, resultMessage) => currentTotal + this.countMessageLines(resultMessage), 0); this.model.messages.push(...message); } else { - hasError = message.isError; - lines = this.countMessageLines(message); this.model.messages.push(message); } - this.maximumBodySize += lines * 22; - if (hasError) { - this.setExpanded(true); - } // convert to old VS Code tree interface with expandable methods let expandableTree: IExpandableTree = this.tree; if (this.state.scrollPosition) { @@ -237,12 +209,6 @@ export class MessagePanel extends ViewletPanel { } } - private countMessageLines(resultMessage: IQueryMessage): number { - let lines = resultMessage.message.split('\n').length; - this.messageLineCountMap.set(resultMessage, lines); - return lines; - } - private reset() { this.model.messages = []; this.model.totalExecuteMessage = undefined; @@ -256,7 +222,6 @@ export class MessagePanel extends ViewletPanel { if (this.state.scrollPosition) { expandableTree.setScrollPosition(this.state.scrollPosition); } - this.setExpanded(!this.state.collapsed); } public get state(): MessagePanelState { @@ -404,8 +369,10 @@ export class MessageController extends WorkbenchTreeController { if (element.selection) { let selection: ISelectionData = element.selection; // this is a batch statement - let input = this.workbenchEditorService.activeEditor as QueryInput; - input.updateSelection(selection); + let editor = this.workbenchEditorService.activeControl as QueryEditor; + const codeEditor = editor.getControl(); + codeEditor.focus(); + codeEditor.setSelection({ endColumn: selection.endColumn + 1, endLineNumber: selection.endLine + 1, startColumn: selection.startColumn + 1, startLineNumber: selection.startLine + 1 }); } return true; diff --git a/src/sql/workbench/parts/query/browser/query.contribution.ts b/src/sql/workbench/parts/query/browser/query.contribution.ts index 2e13e4e6c1..5b45347299 100644 --- a/src/sql/workbench/parts/query/browser/query.contribution.ts +++ b/src/sql/workbench/parts/query/browser/query.contribution.ts @@ -294,11 +294,6 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ // Intellisense and other configuration options let registryProperties = { - 'sql.messagesDefaultOpen': { - 'type': 'boolean', - 'description': localize('sql.messagesDefaultOpen', 'True for the messages pane to be open by default; false for closed'), - 'default': true - }, 'sql.saveAsCsv.includeHeaders': { 'type': 'boolean', 'description': localize('sql.saveAsCsv.includeHeaders', '[Optional] When true, column headers are included when saving results as CSV'), diff --git a/src/sql/workbench/parts/query/browser/queryResultsView.ts b/src/sql/workbench/parts/query/browser/queryResultsView.ts index 9c41f6d1bc..c891aec59d 100644 --- a/src/sql/workbench/parts/query/browser/queryResultsView.ts +++ b/src/sql/workbench/parts/query/browser/queryResultsView.ts @@ -3,74 +3,33 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { QueryResultsInput, ResultsViewState } from 'sql/workbench/parts/query/common/queryResultsInput'; +import { QueryResultsInput } from 'sql/workbench/parts/query/common/queryResultsInput'; import { TabbedPanel, IPanelTab, IPanelView } from 'sql/base/browser/ui/panel/panel'; import { IQueryModelService } from 'sql/platform/query/common/queryModel'; import QueryRunner from 'sql/platform/query/common/queryRunner'; -import { MessagePanel } from './messagePanel'; -import { GridPanel } from '../electron-browser/gridPanel'; -import { ChartTab } from '../../charts/browser/chartTab'; +import { MessagePanel, MessagePanelState } from 'sql/workbench/parts/query/browser/messagePanel'; +import { GridPanel, GridPanelState } from 'sql/workbench/parts/query/electron-browser/gridPanel'; +import { ChartTab } from 'sql/workbench/parts/charts/browser/chartTab'; import { QueryPlanTab } from 'sql/workbench/parts/queryPlan/electron-browser/queryPlan'; import { TopOperationsTab } from 'sql/workbench/parts/queryPlan/browser/topOperations'; import { QueryModelViewTab } from 'sql/workbench/parts/query/modelViewTab/queryModelViewTab'; import * as nls from 'vs/nls'; -import { PanelViewlet } from 'vs/workbench/browser/parts/views/panelViewlet'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import * as DOM from 'vs/base/browser/dom'; -import { Event } from 'vs/base/common/event'; import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; import { attachTabbedPanelStyler } from 'sql/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -class ResultsView extends Disposable implements IPanelView { - private panelViewlet: PanelViewlet; - private gridPanel: GridPanel; +class MessagesView extends Disposable implements IPanelView { private messagePanel: MessagePanel; private container = document.createElement('div'); - private currentDimension: DOM.Dimension; - private _state: ResultsViewState; + private _state: MessagePanelState; constructor(private instantiationService: IInstantiationService) { super(); - this.panelViewlet = this._register(this.instantiationService.createInstance(PanelViewlet, 'resultsView', { showHeaderInTitleWhenSingleView: false })); - this.gridPanel = this._register(this.instantiationService.createInstance(GridPanel, { title: nls.localize('gridPanel', 'Results'), id: 'gridPanel' })); - this.messagePanel = this._register(this.instantiationService.createInstance(MessagePanel, { title: nls.localize('messagePanel', 'Messages'), minimumBodySize: 0, id: 'messagePanel' })); - this.gridPanel.render(); - this.messagePanel.render(); - this.panelViewlet.create(this.container); - this.gridPanel.setVisible(false); - this.panelViewlet.addPanels([ - { panel: this.messagePanel, size: this.messagePanel.minimumSize, index: 1 } - ]); - Event.any(this.gridPanel.onDidChange, this.messagePanel.onDidChange)(e => { - let size = this.gridPanel.maximumBodySize; - if (size < 1 && this.gridPanel.isVisible()) { - this.gridPanel.setVisible(false); - this.panelViewlet.removePanels([this.gridPanel]); - this.gridPanel.layout(0); - } else if (size > 0 && !this.gridPanel.isVisible()) { - this.gridPanel.setVisible(true); - this.panelViewlet.addPanels([{ panel: this.gridPanel, index: 0, size: 200 }]); - } - if (this.gridPanel.isVisible()) { - if (this.state.messagePanelSize) { - this.panelViewlet.resizePanel(this.messagePanel, this.state.messagePanelSize); - } - this.panelViewlet.resizePanel(this.gridPanel, this.getGridPanelSize()); - } - }); - - this.panelViewlet.onDidSashChange(e => { - if (this.state) { - if (this.gridPanel.isExpanded()) { - this.state.gridPanelSize = this.panelViewlet.getPanelSize(this.gridPanel); - } - if (this.messagePanel.isExpanded()) { - this.state.messagePanelSize = this.panelViewlet.getPanelSize(this.messagePanel); - } - } - }); + this.messagePanel = this._register(this.instantiationService.createInstance(MessagePanel)); + this.messagePanel.render(this.container); } render(container: HTMLElement): void { @@ -78,29 +37,12 @@ class ResultsView extends Disposable implements IPanelView { } layout(dimension: DOM.Dimension): void { - this.panelViewlet.layout(dimension); - // the grid won't be resized if the height has not changed so we need to do it manually - if (this.currentDimension && dimension.height === this.currentDimension.height) { - this.gridPanel.layout(dimension.height); - } - this.currentDimension = dimension; - - // resize the messages and grid panels - this.panelViewlet.resizePanel(this.gridPanel, this.getGridPanelSize()); - // we have the right scroll position saved as part of gridPanel state, use this to re-position scrollbar - this.gridPanel.resetScrollPosition(); - - if (this.state.messagePanelSize) { - this.panelViewlet.resizePanel(this.messagePanel, this.state.messagePanelSize); - } - } - - dispose() { - super.dispose(); + this.container.style.width = `${dimension.width}px`; + this.container.style.height = `${dimension.height}px`; + this.messagePanel.layout(dimension); } public clear() { - this.gridPanel.clear(); this.messagePanel.clear(); } @@ -109,32 +51,59 @@ class ResultsView extends Disposable implements IPanelView { } public set queryRunner(runner: QueryRunner) { - this.gridPanel.queryRunner = runner; this.messagePanel.queryRunner = runner; } - public hideResultHeader() { - this.gridPanel.headerVisible = false; - } - - public set state(val: ResultsViewState) { + public set state(val: MessagePanelState) { this._state = val; - this.gridPanel.state = val.gridPanelState; - this.messagePanel.state = val.messagePanelState; + this.messagePanel.state = val; } - public get state(): ResultsViewState { + public get state(): MessagePanelState { return this._state; } +} - private getGridPanelSize(): number { - if (this.state && this.state.gridPanelSize) { - return this.state.gridPanelSize; - } else if (this.currentDimension) { - return Math.round(Math.max(this.currentDimension.height * 0.7, this.currentDimension.height - 150)); - } else { - return 200; - } +class ResultsView extends Disposable implements IPanelView { + private gridPanel: GridPanel; + private container = document.createElement('div'); + private _state: GridPanelState; + + constructor(private instantiationService: IInstantiationService) { + super(); + this.gridPanel = this._register(this.instantiationService.createInstance(GridPanel)); + this.gridPanel.render(this.container); + } + + render(container: HTMLElement): void { + container.appendChild(this.container); + } + + layout(dimension: DOM.Dimension): void { + this.container.style.width = `${dimension.width}px`; + this.container.style.height = `${dimension.height}px`; + this.gridPanel.layout(dimension); + } + + public clear() { + this.gridPanel.clear(); + } + + remove(): void { + this.container.remove(); + } + + public set queryRunner(runner: QueryRunner) { + this.gridPanel.queryRunner = runner; + } + + public set state(val: GridPanelState) { + this._state = val; + this.gridPanel.state = val; + } + + public get state(): GridPanelState { + return this._state; } } @@ -160,10 +129,33 @@ class ResultsTab implements IPanelTab { } } +class MessagesTab implements IPanelTab { + public readonly title = nls.localize('messagesTabTitle', 'Messages'); + public readonly identifier = 'messagesTab'; + public readonly view: MessagesView; + + constructor(instantiationService: IInstantiationService) { + this.view = new MessagesView(instantiationService); + } + + public set queryRunner(runner: QueryRunner) { + this.view.queryRunner = runner; + } + + public dispose() { + dispose(this.view); + } + + public clear() { + this.view.clear(); + } +} + export class QueryResultsView extends Disposable { private _panelView: TabbedPanel; private _input: QueryResultsInput; private resultsTab: ResultsTab; + private messagesTab: MessagesTab; private chartTab: ChartTab; private qpTab: QueryPlanTab; private topOperationsTab: TopOperationsTab; @@ -179,6 +171,7 @@ export class QueryResultsView extends Disposable { ) { super(); this.resultsTab = this._register(new ResultsTab(instantiationService)); + this.messagesTab = this._register(new MessagesTab(instantiationService)); this.chartTab = this._register(new ChartTab(instantiationService)); this._panelView = this._register(new TabbedPanel(container, { showHeaderWhenSingleView: false })); attachTabbedPanelStyler(this._panelView, themeService); @@ -188,6 +181,7 @@ export class QueryResultsView extends Disposable { attachTabbedPanelStyler(this._panelView, themeService); this._panelView.pushTab(this.resultsTab); + this._panelView.pushTab(this.messagesTab); this._register(this._panelView.onTabChange(e => { if (this.input) { this.input.state.activeTab = e; @@ -200,6 +194,7 @@ export class QueryResultsView extends Disposable { private setQueryRunner(runner: QueryRunner) { this.resultsTab.queryRunner = runner; + this.messagesTab.queryRunner = runner; this.chartTab.queryRunner = runner; this.runnerDisposables.push(runner.onQueryStart(e => { this.hideChart(); @@ -249,6 +244,8 @@ export class QueryResultsView extends Disposable { })); if (this.input.state.activeTab) { this._panelView.showTab(this.input.state.activeTab); + } else { + this._panelView.showTab(this.resultsTab.identifier); // our default tab is the results view } } @@ -256,7 +253,8 @@ export class QueryResultsView extends Disposable { this._input = input; dispose(this.runnerDisposables); this.runnerDisposables = []; - this.resultsTab.view.state = this.input.state; + this.resultsTab.view.state = this.input.state.gridPanelState; + this.messagesTab.view.state = this.input.state.messagePanelState; this.qpTab.view.state = this.input.state.queryPlanState; this.topOperationsTab.view.state = this.input.state.topOperationsState; this.chartTab.view.state = this.input.state.chartState; @@ -278,6 +276,7 @@ export class QueryResultsView extends Disposable { clearInput() { this._input = undefined; this.resultsTab.clear(); + this.messagesTab.clear(); this.qpTab.clear(); this.topOperationsTab.clear(); this.chartTab.clear(); diff --git a/src/sql/workbench/parts/query/common/queryResultsInput.ts b/src/sql/workbench/parts/query/common/queryResultsInput.ts index 91869262a6..19b4fc40fa 100644 --- a/src/sql/workbench/parts/query/common/queryResultsInput.ts +++ b/src/sql/workbench/parts/query/common/queryResultsInput.ts @@ -6,7 +6,6 @@ import { localize } from 'vs/nls'; import { EditorInput } from 'vs/workbench/common/editor'; import { Emitter } from 'vs/base/common/event'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { GridPanelState } from 'sql/workbench/parts/query/electron-browser/gridPanel'; import { MessagePanelState } from 'sql/workbench/parts/query/browser/messagePanel'; @@ -16,19 +15,13 @@ import { TopOperationsState } from 'sql/workbench/parts/queryPlan/browser/topOpe export class ResultsViewState { public gridPanelState: GridPanelState = new GridPanelState(); - public messagePanelState: MessagePanelState = new MessagePanelState(this.configurationService); + public messagePanelState: MessagePanelState = new MessagePanelState(); public chartState: ChartState = new ChartState(); public queryPlanState: QueryPlanState = new QueryPlanState(); public topOperationsState = new TopOperationsState(); - public gridPanelSize: number; - public messagePanelSize: number; public activeTab: string; public visibleTabs: Set = new Set(); - constructor(@IConfigurationService private configurationService: IConfigurationService) { - - } - dispose() { this.gridPanelState.dispose(); this.messagePanelState.dispose(); @@ -56,15 +49,13 @@ export class QueryResultsInput extends EditorInput { public readonly onRestoreViewStateEmitter = new Emitter(); public readonly onSaveViewStateEmitter = new Emitter(); - private _state = new ResultsViewState(this.configurationService); + private _state = new ResultsViewState(); public get state(): ResultsViewState { return this._state; } - constructor(private _uri: string, - @IConfigurationService private configurationService: IConfigurationService - ) { + constructor(private _uri: string) { super(); this._visible = false; this._hasBootstrapped = false; diff --git a/src/sql/workbench/parts/query/electron-browser/gridPanel.ts b/src/sql/workbench/parts/query/electron-browser/gridPanel.ts index 54c34a058c..2fb931ff76 100644 --- a/src/sql/workbench/parts/query/electron-browser/gridPanel.ts +++ b/src/sql/workbench/parts/query/electron-browser/gridPanel.ts @@ -24,19 +24,17 @@ import { ITableStyles, ITableMouseEvent } from 'sql/base/browser/ui/table/interf import * as azdata from 'azdata'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { Emitter, Event } from 'vs/base/common/event'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { range } from 'vs/base/common/arrays'; import { Orientation } from 'vs/base/browser/ui/splitview/splitview'; import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; import { generateUuid } from 'vs/base/common/uuid'; import { Separator, ActionBar, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar'; -import { isInDOM } from 'vs/base/browser/dom'; +import { isInDOM, Dimension } from 'vs/base/browser/dom'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; @@ -60,7 +58,6 @@ const MIN_GRID_HEIGHT = (MIN_GRID_HEIGHT_ROWS * ROW_HEIGHT) + HEADER_HEIGHT + ES export class GridPanelState { public tableStates: GridTableState[] = []; public scrollPosition: number; - public collapsed = false; dispose() { dispose(this.tableStates); @@ -115,7 +112,7 @@ export class GridTableState extends Disposable { } } -export class GridPanel extends ViewletPanel { +export class GridPanel { private container = document.createElement('div'); private splitView: ScrollableSplitView; private tables: GridTable[] = []; @@ -129,42 +126,33 @@ export class GridPanel extends ViewletPanel { private _state: GridPanelState; constructor( - options: IViewletPanelOptions, - @IKeybindingService keybindingService: IKeybindingService, - @IContextMenuService contextMenuService: IContextMenuService, - @IConfigurationService configurationService: IConfigurationService, - @IThemeService private themeService: IThemeService, - @IInstantiationService private instantiationService: IInstantiationService, - @ILogService private logService: ILogService + @IConfigurationService private readonly configurationService: IConfigurationService, + @IThemeService private readonly themeService: IThemeService, + @IInstantiationService private readonly instantiationService: IInstantiationService, + @ILogService private readonly logService: ILogService ) { - super(options, keybindingService, contextMenuService, configurationService); this.splitView = new ScrollableSplitView(this.container, { enableResizing: false, verticalScrollbarVisibility: ScrollbarVisibility.Visible }); this.splitView.onScroll(e => { if (this.state && this.splitView.length !== 0) { this.state.scrollPosition = e; } }); - this.onDidChange(e => { - if (this.state) { - this.state.collapsed = !this.isExpanded(); - } - }); } - protected renderBody(container: HTMLElement): void { + public render(container: HTMLElement): void { this.container.style.width = '100%'; this.container.style.height = '100%'; container.appendChild(this.container); } - protected layoutBody(size: number): void { - this.splitView.layout(size); + public layout(size: Dimension): void { + this.splitView.layout(size.height); // if the size hasn't change it won't layout our table so we have to do it manually - if (size === this.currentHeight) { + if (size.height === this.currentHeight) { this.tables.map(e => e.layout()); } - this.currentHeight = size; + this.currentHeight = size.height; } public set queryRunner(runner: QueryRunner) { @@ -188,9 +176,6 @@ export class GridPanel extends ViewletPanel { } return p; }, [])); - this.maximumBodySize = this.tables.reduce((p, c) => { - return p + c.maximumSize; - }, 0); if (this.state && this.state.scrollPosition) { this.splitView.setScrollPosition(this.state.scrollPosition); @@ -213,10 +198,6 @@ export class GridPanel extends ViewletPanel { t.state.canBeMaximized = this.tables.length > 1; }); - this.maximumBodySize = this.tables.reduce((p, c) => { - return p + c.maximumSize; - }, 0); - if (this.state && this.state.scrollPosition) { this.splitView.setScrollPosition(this.state.scrollPosition); } @@ -243,10 +224,6 @@ export class GridPanel extends ViewletPanel { } const sizeChanges = () => { - this.maximumBodySize = this.tables.reduce((p, c) => { - return p + c.maximumSize; - }, 0); - if (this.state && this.state.scrollPosition) { this.splitView.setScrollPosition(this.state.scrollPosition); } @@ -325,10 +302,6 @@ export class GridPanel extends ViewletPanel { this.tableDisposable = []; this.tables = []; this.maximizedGrid = undefined; - - this.maximumBodySize = this.tables.reduce((p, c) => { - return p + c.maximumSize; - }, 0); } private maximizeTable(tableid: string): void { @@ -367,7 +340,6 @@ export class GridPanel extends ViewletPanel { t.state = state; } }); - this.setExpanded(!this.state.collapsed); } public get state(): GridPanelState { @@ -380,7 +352,6 @@ export class GridPanel extends ViewletPanel { dispose(this.tables); this.tableDisposable = undefined; this.tables = undefined; - super.dispose(); } } @@ -816,8 +787,12 @@ class GridTable extends Disposable implements IView { public dispose() { this.container.remove(); - this.table.dispose(); - this.actionBar.dispose(); + if (this.table) { + this.table.dispose(); + } + if (this.actionBar) { + this.actionBar.dispose(); + } super.dispose(); } } diff --git a/src/sqltest/parts/query/editor/queryEditor.test.ts b/src/sqltest/parts/query/editor/queryEditor.test.ts index e30bedc495..c583078c6d 100644 --- a/src/sqltest/parts/query/editor/queryEditor.test.ts +++ b/src/sqltest/parts/query/editor/queryEditor.test.ts @@ -317,7 +317,7 @@ suite('SQL QueryEditor Tests', () => { assert.equal(queryInput.state.connecting, false, 'query state should be not connecting'); }); test('Test that we attempt to dispose query when the queryInput is disposed', () => { - let queryResultsInput = new QueryResultsInput('testUri', configurationService.object); + let queryResultsInput = new QueryResultsInput('testUri'); queryInput['_results'] = queryResultsInput; queryInput.close(); queryModelService.verify(x => x.disposeQuery(TypeMoq.It.isAnyString()), TypeMoq.Times.once());