add copy keybind (#2445)

This commit is contained in:
Anthony Dresser
2018-09-06 17:00:30 -07:00
committed by GitHub
parent efee27559b
commit 81ff542d0b
3 changed files with 100 additions and 3 deletions

View File

@@ -0,0 +1,62 @@
/*---------------------------------------------------------------------------------------------
* 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 { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { Emitter, Event } from 'vs/base/common/event';
import { isUndefinedOrNull } from 'vs/base/common/types';
/**
* Implements the various additional navigation keybindings we want out of slickgrid
*/
export class CopyKeybind<T> implements Slick.Plugin<T> {
private grid: Slick.Grid<T>;
private handler = new Slick.EventHandler();
private _onCopy = new Emitter<Slick.Range[]>();
public onCopy: Event<Slick.Range[]> = this._onCopy.event;
public init(grid: Slick.Grid<T>) {
this.grid = grid;
this.handler.subscribe(this.grid.onKeyDown, (e, args) => this.handleKeyDown(e, args));
}
public destroy() {
this.handler.unsubscribeAll();
}
private handleKeyDown(e: KeyboardEvent, args: Slick.OnKeyDownEventArgs<T>): void {
let event = new StandardKeyboardEvent(e);
let handled = false;
if (event.equals(KeyCode.KEY_C | KeyMod.CtrlCmd)) {
handled = true;
let selectionModel = this.grid.getSelectionModel();
let ranges: Slick.Range[];
// check to see if we can get the range from the model directly
if (selectionModel && (<any>selectionModel).getSelectedRanges) {
ranges = (<any>selectionModel).getSelectedRanges();
} else {
let selectedRows = this.grid.getSelectedRows();
let startColumn = 0;
// check for number column
if (!isUndefinedOrNull(this.grid.getColumns()[0].selectable) && !this.grid.getColumns()[0].selectable) {
startColumn = 1;
}
ranges = [new Slick.Range(selectedRows[0], startColumn, selectedRows[selectedRows.length - 1], this.grid.getColumns().length)]
}
this._onCopy.fire(ranges);
}
if (handled) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
}
}
}

View File

@@ -34,6 +34,14 @@ export interface IMessagesActionContext {
tree: ITree;
}
function mapForNumberColumn(ranges: Slick.Range[]): Slick.Range[] {
if (ranges) {
return ranges.map(e => new Slick.Range(e.fromRow, e.fromCell - 1, e.toRow, e.toCell ? e.toCell - 1 : undefined));
} else {
return undefined;
}
}
export class SaveResultAction extends Action {
public static SAVECSV_ID = 'grid.saveAsCsv';
public static SAVECSV_LABEL = localize('saveAsCsv', 'Save As CSV');
@@ -51,13 +59,19 @@ export class SaveResultAction extends Action {
id: string,
label: string,
icon: string,
private format: SaveFormat
private format: SaveFormat,
private accountForNumberColumn = true
) {
super(id, label, icon);
}
public run(context: IGridActionContext): TPromise<boolean> {
context.runner.serializeResults(context.batchId, context.resultId, this.format, context.selection);
if (this.accountForNumberColumn) {
context.runner.serializeResults(context.batchId, context.resultId, this.format,
mapForNumberColumn(context.selection));
} else {
context.runner.serializeResults(context.batchId, context.resultId, this.format, context.selection);
}
return TPromise.as(true);
}
}
@@ -73,12 +87,19 @@ export class CopyResultAction extends Action {
id: string,
label: string,
private copyHeader: boolean,
private accountForNumberColumn = true
) {
super(id, label);
}
public run(context: IGridActionContext): TPromise<boolean> {
context.runner.copyResults(context.selection, context.batchId, context.resultId, this.copyHeader);
if (this.accountForNumberColumn) {
context.runner.copyResults(
mapForNumberColumn(context.selection),
context.batchId, context.resultId, this.copyHeader);
} else {
context.runner.copyResults(context.selection, context.batchId, context.resultId, this.copyHeader);
}
return TPromise.as(true);
}
}

View File

@@ -38,6 +38,7 @@ import { Dimension, getContentWidth } 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';
import { CopyKeybind } from 'sql/base/browser/ui/table/plugins/copyKeybind.plugin';
const ROW_HEIGHT = 29;
const HEADER_HEIGHT = 26;
@@ -295,11 +296,24 @@ class GridTable<T> extends Disposable implements IView {
this.renderGridDataRowsRange(startIndex, count);
});
let numberColumn = new RowNumberColumn({ numberOfRows: this.resultSet.rowCount });
let copyHandler = new CopyKeybind();
copyHandler.onCopy(e => {
new CopyResultAction(CopyResultAction.COPY_ID, CopyResultAction.COPY_LABEL, false).run({
selection: e,
batchId: this.resultSet.batchId,
resultId: this.resultSet.id,
cell: this.table.grid.getActiveCell(),
runner: this.runner,
table: this.table,
tableState: this.state
});
});
this.columns.unshift(numberColumn.getColumnDefinition());
this.table = this._register(new Table(tableContainer, { dataProvider: new AsyncDataProvider(collection), columns: this.columns }, { rowHeight: ROW_HEIGHT, showRowNumber: true }));
this.table.setSelectionModel(this.selectionModel);
this.table.registerPlugin(new MouseWheelSupport());
this.table.registerPlugin(new AutoColumnSize());
this.table.registerPlugin(copyHandler);
this.table.registerPlugin(numberColumn);
this._register(this.table.onContextMenu(this.contextMenu, this));
this._register(this.table.onClick(this.onTableClick, this));