Copy all messages when selecting all (#3818)

* copy all messages when selecting all

* added functionality for keyboard shortcuts

* fixed bug when select all then selection made

* made output similar to debug console
This commit is contained in:
Aditya Bist
2019-01-25 12:10:00 -08:00
committed by GitHub
parent bfa77aebfc
commit 7804f94d8b
2 changed files with 80 additions and 44 deletions

View File

@@ -19,6 +19,9 @@ import { Table } from 'sql/base/browser/ui/table/table';
import { GridTableState } from 'sql/parts/query/editor/gridPanel'; import { GridTableState } from 'sql/parts/query/editor/gridPanel';
import { QueryEditor } from './queryEditor'; import { QueryEditor } from './queryEditor';
import { CellSelectionModel } from 'sql/base/browser/ui/table/plugins/cellSelectionModel.plugin'; import { CellSelectionModel } from 'sql/base/browser/ui/table/plugins/cellSelectionModel.plugin';
import { MessagePanel } from 'sql/parts/query/editor/messagePanel';
import { isWindows } from 'vs/base/common/platform';
import { removeAnsiEscapeCodes } from 'vs/base/common/strings';
export interface IGridActionContext { export interface IGridActionContext {
cell: { row: number; cell: number; }; cell: { row: number; cell: number; };
@@ -129,6 +132,7 @@ export class CopyMessagesAction extends Action {
public static LABEL = localize('copyMessages', 'Copy'); public static LABEL = localize('copyMessages', 'Copy');
constructor( constructor(
private messagePanel: MessagePanel,
@IClipboardService private clipboardService: IClipboardService @IClipboardService private clipboardService: IClipboardService
) { ) {
super(CopyMessagesAction.ID, CopyMessagesAction.LABEL); super(CopyMessagesAction.ID, CopyMessagesAction.LABEL);
@@ -140,21 +144,31 @@ export class CopyMessagesAction extends Action {
} }
} }
export class SelectAllMessagesAction extends Action { const lineDelimiter = isWindows ? '\r\n' : '\n';
public static ID = 'grid.messages.selectAll'; export class CopyAllMessagesAction extends Action {
public static LABEL = localize('selectAll', 'Select All'); public static ID = 'grid.messages.copyAll';
public static LABEL = localize('copyAll', "Copy All");
constructor() { constructor(
super(SelectAllMessagesAction.ID, SelectAllMessagesAction.LABEL); private tree: ITree,
@IClipboardService private clipboardService: IClipboardService)
{
super(CopyAllMessagesAction.ID, CopyAllMessagesAction.LABEL);
} }
public run(context: IMessagesActionContext): TPromise<boolean> { public run(): TPromise<any> {
let range = document.createRange(); let text = '';
range.selectNodeContents(context.tree.getHTMLElement()); const navigator = this.tree.getNavigator();
let sel = document.getSelection(); // skip first navigator element - the root node
sel.removeAllRanges(); while (navigator.next()) {
sel.addRange(range); if (text) {
return TPromise.as(true); text += lineDelimiter;
}
text += (navigator.current()).message;
}
this.clipboardService.writeText(removeAnsiEscapeCodes(text));
return TPromise.as(null);
} }
} }

View File

@@ -5,7 +5,7 @@
'use strict'; 'use strict';
import 'vs/css!./media/messagePanel'; import 'vs/css!./media/messagePanel';
import { IMessagesActionContext, SelectAllMessagesAction, CopyMessagesAction } from './actions'; import { IMessagesActionContext, CopyMessagesAction, CopyAllMessagesAction } from './actions';
import QueryRunner from 'sql/parts/query/execution/queryRunner'; import QueryRunner from 'sql/parts/query/execution/queryRunner';
import { QueryInput } from 'sql/parts/query/common/queryInput'; import { QueryInput } from 'sql/parts/query/common/queryInput';
@@ -30,6 +30,7 @@ import { isArray, isUndefinedOrNull } from 'vs/base/common/types';
import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ScrollbarVisibility } from 'vs/base/common/scrollable'; import { ScrollbarVisibility } from 'vs/base/common/scrollable';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
export interface IResultMessageIntern extends IResultMessage { export interface IResultMessageIntern extends IResultMessage {
id?: string; id?: string;
@@ -88,6 +89,7 @@ export class MessagePanel extends ViewletPanel {
private _state: MessagePanelState; private _state: MessagePanelState;
private tree: ITree; private tree: ITree;
private _selectAllMessages: boolean;
constructor( constructor(
options: IViewletPanelOptions, options: IViewletPanelOptions,
@@ -95,7 +97,8 @@ export class MessagePanel extends ViewletPanel {
@IContextMenuService contextMenuService: IContextMenuService, @IContextMenuService contextMenuService: IContextMenuService,
@IConfigurationService configurationService: IConfigurationService, @IConfigurationService configurationService: IConfigurationService,
@IThemeService private themeService: IThemeService, @IThemeService private themeService: IThemeService,
@IInstantiationService instantiationService: IInstantiationService @IInstantiationService instantiationService: IInstantiationService,
@IClipboardService private clipboardService: IClipboardService
) { ) {
super(options, keybindingService, contextMenuService, configurationService); super(options, keybindingService, contextMenuService, configurationService);
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 = instantiationService.createInstance(MessageController, { openMode: OpenMode.SINGLE_CLICK, clickBehavior: ClickBehavior.ON_MOUSE_UP /* do not change, to preserve focus behaviour in input field */ });
@@ -116,6 +119,55 @@ export class MessagePanel extends ViewletPanel {
this.state.collapsed = !this.isExpanded(); this.state.collapsed = !this.isExpanded();
} }
}); });
this.controller.onKeyDown = (tree, event) => {
if (event.ctrlKey) {
let context: IMessagesActionContext = {
selection: document.getSelection(),
tree: this.tree,
};
// Ctrl + C for copy
if (event.code === 'KeyC') {
let copyMessageAction = instantiationService.createInstance(CopyMessagesAction, this, this.clipboardService);
copyMessageAction.run(context);
}
}
event.preventDefault();
event.stopPropagation();
return true;
};
this.controller.onContextMenu = (tree, element, event) => {
if (event.target && event.target.tagName && event.target.tagName.toLowerCase() === 'input') {
return false; // allow context menu on input fields
}
// Prevent native context menu from showing up
if (event) {
event.preventDefault();
event.stopPropagation();
}
const selection = document.getSelection();
this.contextMenuService.showContextMenu({
getAnchor: () => {
return { x: event.posx, y: event.posy };
},
getActions: () => {
return TPromise.as([
instantiationService.createInstance(CopyMessagesAction, this, this.clipboardService),
instantiationService.createInstance(CopyAllMessagesAction, this.tree, this.clipboardService)
]);
},
getActionsContext: () => {
return <IMessagesActionContext>{
selection,
tree
};
}
});
return true;
};
} }
protected renderBody(container: HTMLElement): void { protected renderBody(container: HTMLElement): void {
@@ -346,36 +398,6 @@ export class MessageController extends WorkbenchTreeController {
} }
public onContextMenu(tree: ITree, element: any, event: ContextMenuEvent): boolean { public onContextMenu(tree: ITree, element: any, event: ContextMenuEvent): boolean {
if (event.target && event.target.tagName && event.target.tagName.toLowerCase() === 'input') {
return false; // allow context menu on input fields
}
// Prevent native context menu from showing up
if (event) {
event.preventDefault();
event.stopPropagation();
}
const selection = document.getSelection();
this.contextMenuService.showContextMenu({
getAnchor: () => {
return { x: event.posx, y: event.posy };
},
getActions: () => {
return TPromise.as([
this.instantiationService.createInstance(CopyMessagesAction),
new SelectAllMessagesAction()
]);
},
getActionsContext: () => {
return <IMessagesActionContext>{
selection,
tree
};
}
});
return true; return true;
} }
} }