Completed: Missing feature request: Save as XML (#3729)

* Save as XML feature added to grid

* Unrelated code removed
This commit is contained in:
Mustafa Sadedil
2019-01-16 01:36:42 +03:00
committed by Karl Burtram
parent 5c16ceb2fa
commit 4de3cc8a09
16 changed files with 121 additions and 1 deletions

View File

@@ -62,6 +62,12 @@
<trans-unit id="sql.saveAsCsv.encoding"> <trans-unit id="sql.saveAsCsv.encoding">
<source xml:lang="en">[Optional] File encoding used when saving results as CSV</source> <source xml:lang="en">[Optional] File encoding used when saving results as CSV</source>
</trans-unit> </trans-unit>
<trans-unit id="sql.saveAsXml.formatted">
<source xml:lang="en">[Optional] When true, XML output will be formatted when saving results as XML</source>
</trans-unit>
<trans-unit id="sql.saveAsXml.encoding">
<source xml:lang="en">[Optional] File encoding used when saving results as XML</source>
</trans-unit>
<trans-unit id="sql.copyIncludeHeaders"> <trans-unit id="sql.copyIncludeHeaders">
<source xml:lang="en">[Optional] Configuration options for copying results from the Results View</source> <source xml:lang="en">[Optional] Configuration options for copying results from the Results View</source>
</trans-unit> </trans-unit>
@@ -596,6 +602,9 @@
<trans-unit id="saveAsExcel"> <trans-unit id="saveAsExcel">
<source xml:lang="en">Save As Excel</source> <source xml:lang="en">Save As Excel</source>
</trans-unit> </trans-unit>
<trans-unit id="saveAsXml">
<source xml:lang="en">Save As XML</source>
</trans-unit>
<trans-unit id="copySelection"> <trans-unit id="copySelection">
<source xml:lang="en">Copy</source> <source xml:lang="en">Copy</source>
</trans-unit> </trans-unit>
@@ -1142,6 +1151,9 @@
<trans-unit id="saveExcelLabel"> <trans-unit id="saveExcelLabel">
<source xml:lang="en">Save as Excel</source> <source xml:lang="en">Save as Excel</source>
</trans-unit> </trans-unit>
<trans-unit id="saveXMLLabel">
<source xml:lang="en">Save as XML</source>
</trans-unit>
<trans-unit id="viewChartLabel"> <trans-unit id="viewChartLabel">
<source xml:lang="en">View as Chart</source> <source xml:lang="en">View as Chart</source>
</trans-unit> </trans-unit>

View File

@@ -17,6 +17,7 @@ export let SelectAllMessages = 'SelectAllMessages';
export let SaveAsCsv = 'SaveAsCSV'; export let SaveAsCsv = 'SaveAsCSV';
export let SaveAsJSON = 'SaveAsJSON'; export let SaveAsJSON = 'SaveAsJSON';
export let SaveAsExcel = 'SaveAsExcel'; export let SaveAsExcel = 'SaveAsExcel';
export let SaveAsXML = 'SaveAsXML';
export let ViewAsChart = 'ViewAsChart'; export let ViewAsChart = 'ViewAsChart';
export let GoToNextQueryOutputTab = 'GoToNextQueryOutputTab'; export let GoToNextQueryOutputTab = 'GoToNextQueryOutputTab';
export let GoToNextGrid = 'GoToNextGrid'; export let GoToNextGrid = 'GoToNextGrid';

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="saveXml" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polygon id="canvas" fill="#F6F6F6" fill-rule="nonzero" opacity="0" points="16 16 0 16 0 0 16 0"></polygon>
<polygon id="&lt;-&gt;" fill="#424242" points="14.3701172 10.7222222 9.41870773 15 9.41870773 12.3454861 12.9578306 9.5 9.41870773 6.6640625 9.41870773 4 14.3701172 8.296875"></polygon>
<polygon id="colorAction" fill="#00539C" fill-rule="nonzero" points="8 4 5 7 3 7 5 5 1 5 1 3 5 3 3 1 5 1"></polygon>
<path d="M2.32152009,8 L5.28619938,8 L3.4164898,9.5 L6.95140946,12.3454861 L6.95140946,15 L2,10.7222222 L2,8.27777778 L2.32152009,8 Z" id="Combined-Shape" fill="#424242"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 877 B

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="saveXmlInverse" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polygon id="canvas" fill="#F6F6F6" fill-rule="nonzero" opacity="0" points="16 16 0 16 0 0 16 0"></polygon>
<polygon id="&lt;-&gt;" fill="#C5C5C5" points="14.3701172 10.7222222 9.41870773 15 9.41870773 12.3454861 12.9578306 9.5 9.41870773 6.6640625 9.41870773 4 14.3701172 8.296875"></polygon>
<polygon id="colorAction" fill="#75BEFF" fill-rule="nonzero" points="8 4 5 7 3 7 5 5 1 5 1 3 5 3 3 1 5 1"></polygon>
<path d="M2.32152009,8 L5.28619938,8 L3.4164898,9.5 L6.95140946,12.3454861 L6.95140946,15 L2,10.7222222 L2,8.27777778 L2.32152009,8 Z" id="Combined-Shape" fill="#C5C5C5"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 884 B

View File

@@ -112,6 +112,11 @@
background-image: url("saveExcel.svg"); background-image: url("saveExcel.svg");
} }
.vs .icon.saveXml {
/* ResultToXML_16x_vscode */
background-image: url("saveXml.svg");
}
.vs .icon.viewChart { .vs .icon.viewChart {
/* ResultToXlsx_16x_vscode */ /* ResultToXlsx_16x_vscode */
background-image: url("viewChart.svg"); background-image: url("viewChart.svg");
@@ -243,6 +248,12 @@
background-image: url("saveExcel_inverse.svg"); background-image: url("saveExcel_inverse.svg");
} }
.vs-dark .icon.saveXml,
.hc-black .icon.saveXml {
/* ResultToXml_16x_vscode_inverse.svg */
background-image: url("saveXml_inverse.svg");
}
.vs-dark .icon.viewChart, .vs-dark .icon.viewChart,
.hc-black .icon.viewChart { .hc-black .icon.viewChart {
/* ResultToXlsx_16x_vscode */ /* ResultToXlsx_16x_vscode */

View File

@@ -17,6 +17,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
export const GRID_SAVECSV_ID = 'grid.saveAsCsv'; export const GRID_SAVECSV_ID = 'grid.saveAsCsv';
export const GRID_SAVEJSON_ID = 'grid.saveAsJson'; export const GRID_SAVEJSON_ID = 'grid.saveAsJson';
export const GRID_SAVEEXCEL_ID = 'grid.saveAsExcel'; export const GRID_SAVEEXCEL_ID = 'grid.saveAsExcel';
export const GRID_SAVEXML_ID = 'grid.saveAsXml';
export const GRID_COPY_ID = 'grid.copySelection'; export const GRID_COPY_ID = 'grid.copySelection';
export const GRID_COPYWITHHEADERS_ID = 'grid.copyWithHeaders'; export const GRID_COPYWITHHEADERS_ID = 'grid.copyWithHeaders';
export const GRID_SELECTALL_ID = 'grid.selectAll'; export const GRID_SELECTALL_ID = 'grid.selectAll';
@@ -46,6 +47,7 @@ export class GridActionProvider {
actions.push(new SaveResultAction(SaveResultAction.SAVECSV_ID, SaveResultAction.SAVECSV_LABEL, SaveFormat.CSV, this._dataService)); actions.push(new SaveResultAction(SaveResultAction.SAVECSV_ID, SaveResultAction.SAVECSV_LABEL, SaveFormat.CSV, this._dataService));
actions.push(new SaveResultAction(SaveResultAction.SAVEJSON_ID, SaveResultAction.SAVEJSON_LABEL, SaveFormat.JSON, this._dataService)); actions.push(new SaveResultAction(SaveResultAction.SAVEJSON_ID, SaveResultAction.SAVEJSON_LABEL, SaveFormat.JSON, this._dataService));
actions.push(new SaveResultAction(SaveResultAction.SAVEEXCEL_ID, SaveResultAction.SAVEEXCEL_LABEL, SaveFormat.EXCEL, this._dataService)); actions.push(new SaveResultAction(SaveResultAction.SAVEEXCEL_ID, SaveResultAction.SAVEEXCEL_LABEL, SaveFormat.EXCEL, this._dataService));
actions.push(new SaveResultAction(SaveResultAction.SAVEXML_ID, SaveResultAction.SAVEXML_LABEL, SaveFormat.XML, this._dataService));
actions.push(new SelectAllGridAction(SelectAllGridAction.ID, SelectAllGridAction.LABEL, this._selectAllCallback)); actions.push(new SelectAllGridAction(SelectAllGridAction.ID, SelectAllGridAction.LABEL, this._selectAllCallback));
actions.push(new CopyResultAction(CopyResultAction.COPY_ID, CopyResultAction.COPY_LABEL, false, this._dataService)); actions.push(new CopyResultAction(CopyResultAction.COPY_ID, CopyResultAction.COPY_LABEL, false, this._dataService));
actions.push(new CopyResultAction(CopyResultAction.COPYWITHHEADERS_ID, CopyResultAction.COPYWITHHEADERS_LABEL, true, this._dataService)); actions.push(new CopyResultAction(CopyResultAction.COPYWITHHEADERS_ID, CopyResultAction.COPYWITHHEADERS_LABEL, true, this._dataService));
@@ -74,6 +76,9 @@ export class SaveResultAction extends Action {
public static SAVEEXCEL_ID = GRID_SAVEEXCEL_ID; public static SAVEEXCEL_ID = GRID_SAVEEXCEL_ID;
public static SAVEEXCEL_LABEL = localize('saveAsExcel', 'Save As Excel'); public static SAVEEXCEL_LABEL = localize('saveAsExcel', 'Save As Excel');
public static SAVEXML_ID = GRID_SAVEXML_ID;
public static SAVEXML_LABEL = localize('saveAsXml', 'Save As XML');
constructor( constructor(
id: string, id: string,
label: string, label: string,

View File

@@ -69,6 +69,10 @@ export const saveAsExcel = (accessor: ServicesAccessor) => {
runActionOnActiveResultsEditor(accessor, GridContentEvents.SaveAsExcel); runActionOnActiveResultsEditor(accessor, GridContentEvents.SaveAsExcel);
}; };
export const saveAsXml = (accessor: ServicesAccessor) => {
runActionOnActiveResultsEditor(accessor, GridContentEvents.SaveAsXML);
};
export const selectAll = (accessor: ServicesAccessor) => { export const selectAll = (accessor: ServicesAccessor) => {
runActionOnActiveResultsEditor(accessor, GridContentEvents.SelectAll); runActionOnActiveResultsEditor(accessor, GridContentEvents.SelectAll);
}; };

View File

@@ -154,6 +154,9 @@ export abstract class GridParentComponent {
case GridContentEvents.SaveAsExcel: case GridContentEvents.SaveAsExcel:
self.sendSaveRequest(SaveFormat.EXCEL); self.sendSaveRequest(SaveFormat.EXCEL);
break; break;
case GridContentEvents.SaveAsXML:
self.sendSaveRequest(SaveFormat.XML);
break;
case GridContentEvents.GoToNextQueryOutputTab: case GridContentEvents.GoToNextQueryOutputTab:
self.goToNextQueryOutputTab(); self.goToNextQueryOutputTab();
break; break;
@@ -320,6 +323,9 @@ export abstract class GridParentComponent {
'SaveAsExcel': () => { 'SaveAsExcel': () => {
this.sendSaveRequest(SaveFormat.EXCEL); this.sendSaveRequest(SaveFormat.EXCEL);
}, },
'SaveAsXML': () => {
this.sendSaveRequest(SaveFormat.XML);
},
'GoToNextQueryOutputTab': () => { 'GoToNextQueryOutputTab': () => {
this.goToNextQueryOutputTab(); this.goToNextQueryOutputTab();
} }
@@ -345,6 +351,9 @@ export abstract class GridParentComponent {
case 'saveexcel': case 'saveexcel':
this.dataService.sendSaveRequest({ batchIndex: event.batchId, resultSetNumber: event.resultId, format: SaveFormat.EXCEL, selection: event.selection }); this.dataService.sendSaveRequest({ batchIndex: event.batchId, resultSetNumber: event.resultId, format: SaveFormat.EXCEL, selection: event.selection });
break; break;
case 'savexml':
this.dataService.sendSaveRequest({ batchIndex: event.batchId, resultSetNumber: event.resultId, format: SaveFormat.XML, selection: event.selection });
break;
case 'selectall': case 'selectall':
this.activeGrid = event.index; this.activeGrid = event.index;
this.onSelectAllForActiveGrid(); this.onSelectAllForActiveGrid();

View File

@@ -127,6 +127,19 @@ export class QueryComponent extends GridParentComponent implements OnInit, OnDes
} }
} }
}, },
{
showCondition: () => { return true; },
icon: () => { return 'saveXml'; },
hoverText: () => { return LocalizedConstants.saveXMLLabel; },
functionality: (batchId, resultId, index) => {
let selection = this.getSelection(index);
if (selection.length <= 1) {
this.handleContextClick({ type: 'savexml', batchId: batchId, resultId: resultId, index: index, selection: selection });
} else {
this.dataService.showWarning(LocalizedConstants.msgCannotSaveMultipleSelections);
}
}
},
{ {
showCondition: () => { showCondition: () => {
return this.configurationService.getValue('workbench')['enablePreviewFeatures']; return this.configurationService.getValue('workbench')['enablePreviewFeatures'];

View File

@@ -5,6 +5,7 @@
export const copyIncludeHeaders = 'copyIncludeHeaders'; export const copyIncludeHeaders = 'copyIncludeHeaders';
export const configSaveAsCsv = 'saveAsCsv'; export const configSaveAsCsv = 'saveAsCsv';
export const configSaveAsXml = 'saveAsXml';
export const configCopyRemoveNewLine = 'copyRemoveNewLine'; export const configCopyRemoveNewLine = 'copyRemoveNewLine';
export const configShowBatchTime = 'showBatchTime'; export const configShowBatchTime = 'showBatchTime';
export const querySection = 'query'; export const querySection = 'query';

View File

@@ -24,6 +24,7 @@ export const restoreLabel = localize('resultsPane.restoreLabel', 'Restore');
export const saveCSVLabel = localize('saveCSVLabel', 'Save as CSV'); export const saveCSVLabel = localize('saveCSVLabel', 'Save as CSV');
export const saveJSONLabel = localize('saveJSONLabel', 'Save as JSON'); export const saveJSONLabel = localize('saveJSONLabel', 'Save as JSON');
export const saveExcelLabel = localize('saveExcelLabel', 'Save as Excel'); export const saveExcelLabel = localize('saveExcelLabel', 'Save as Excel');
export const saveXMLLabel = localize('saveXMLLabel', 'Save as XML');
export const viewChartLabel = localize('viewChartLabel', 'View as Chart'); export const viewChartLabel = localize('viewChartLabel', 'View as Chart');
export const resultPaneLabel = localize('resultPaneLabel', 'Results'); export const resultPaneLabel = localize('resultPaneLabel', 'Results');

View File

@@ -233,6 +233,14 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
handler: gridCommands.saveAsExcel handler: gridCommands.saveAsExcel
}); });
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: gridActions.GRID_SAVEXML_ID,
weight: KeybindingWeight.EditorContrib,
when: ResultsGridFocusCondition,
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_R, KeyMod.CtrlCmd | KeyCode.KEY_X),
handler: gridCommands.saveAsXml
});
KeybindingsRegistry.registerCommandAndKeybindingRule({ KeybindingsRegistry.registerCommandAndKeybindingRule({
id: gridActions.GRID_VIEWASCHART_ID, id: gridActions.GRID_VIEWASCHART_ID,
weight: KeybindingWeight.EditorContrib, weight: KeybindingWeight.EditorContrib,
@@ -310,6 +318,16 @@ let registryProperties = {
'description': localize('sql.results.streaming', 'Enable results streaming; contains few minor visual issues'), 'description': localize('sql.results.streaming', 'Enable results streaming; contains few minor visual issues'),
'default': false 'default': false
}, },
'sql.saveAsXml.formatted': {
'type': 'string',
'description': localize('sql.saveAsXml.formatted', '[Optional] When true, XML output will be formatted when saving results as XML'),
'default': true
},
'sql.saveAsXml.encoding': {
'type': 'string',
'description': localize('sql.saveAsXml.encoding', '[Optional] File encoding used when saving results as XML'),
'default': 'utf-8'
},
'sql.copyIncludeHeaders': { 'sql.copyIncludeHeaders': {
'type': 'boolean', 'type': 'boolean',
'description': localize('sql.copyIncludeHeaders', '[Optional] Configuration options for copying results from the Results View'), 'description': localize('sql.copyIncludeHeaders', '[Optional] Configuration options for copying results from the Results View'),

View File

@@ -254,6 +254,24 @@ export class ResultSerializer {
return config; return config;
} }
private getConfigForXml(): SaveResultsRequestParams {
let saveResultsParams = <SaveResultsRequestParams>{ resultFormat: SaveFormat.XML as string };
// get save results config from vscode config
let saveConfig = WorkbenchUtils.getSqlConfigSection(this._workspaceConfigurationService, Constants.configSaveAsXml);
// if user entered config, set options
if (saveConfig) {
if (saveConfig.formatted !== undefined) {
saveResultsParams.formatted = saveConfig.formatted;
}
if (saveConfig.encoding !== undefined) {
saveResultsParams.encoding = saveConfig.encoding;
}
}
return saveResultsParams;
}
private getParameters(filePath: string, batchIndex: number, resultSetNo: number, format: string, selection: Slick.Range): SaveResultsRequestParams { private getParameters(filePath: string, batchIndex: number, resultSetNo: number, format: string, selection: Slick.Range): SaveResultsRequestParams {
let saveResultsParams: SaveResultsRequestParams; let saveResultsParams: SaveResultsRequestParams;
if (!path.isAbsolute(filePath)) { if (!path.isAbsolute(filePath)) {
@@ -268,6 +286,8 @@ export class ResultSerializer {
saveResultsParams = this.getConfigForJson(); saveResultsParams = this.getConfigForJson();
} else if (format === SaveFormat.EXCEL) { } else if (format === SaveFormat.EXCEL) {
saveResultsParams = this.getConfigForExcel(); saveResultsParams = this.getConfigForExcel();
} else if (format === SaveFormat.XML) {
saveResultsParams = this.getConfigForXml();
} }
saveResultsParams.filePath = this._filePath; saveResultsParams.filePath = this._filePath;

View File

@@ -57,6 +57,10 @@ export class SaveResultAction extends Action {
public static SAVEEXCEL_LABEL = localize('saveAsExcel', 'Save As Excel'); public static SAVEEXCEL_LABEL = localize('saveAsExcel', 'Save As Excel');
public static SAVEEXCEL_ICON = 'saveExcel'; public static SAVEEXCEL_ICON = 'saveExcel';
public static SAVEXML_ID = 'grid.saveAsXml';
public static SAVEXML_LABEL = localize('saveAsXml', 'Save As XML');
public static SAVEXML_ICON = 'saveXml';
constructor( constructor(
id: string, id: string,
label: string, label: string,

View File

@@ -695,6 +695,7 @@ class GridTable<T> extends Disposable implements IView {
new SaveResultAction(SaveResultAction.SAVECSV_ID, SaveResultAction.SAVECSV_LABEL, SaveResultAction.SAVECSV_ICON, SaveFormat.CSV), new SaveResultAction(SaveResultAction.SAVECSV_ID, SaveResultAction.SAVECSV_LABEL, SaveResultAction.SAVECSV_ICON, SaveFormat.CSV),
new SaveResultAction(SaveResultAction.SAVEEXCEL_ID, SaveResultAction.SAVEEXCEL_LABEL, SaveResultAction.SAVEEXCEL_ICON, SaveFormat.EXCEL), new SaveResultAction(SaveResultAction.SAVEEXCEL_ID, SaveResultAction.SAVEEXCEL_LABEL, SaveResultAction.SAVEEXCEL_ICON, SaveFormat.EXCEL),
new SaveResultAction(SaveResultAction.SAVEJSON_ID, SaveResultAction.SAVEJSON_LABEL, SaveResultAction.SAVEJSON_ICON, SaveFormat.JSON), new SaveResultAction(SaveResultAction.SAVEJSON_ID, SaveResultAction.SAVEJSON_LABEL, SaveResultAction.SAVEJSON_ICON, SaveFormat.JSON),
new SaveResultAction(SaveResultAction.SAVEXML_ID, SaveResultAction.SAVEXML_LABEL, SaveResultAction.SAVEXML_ICON, SaveFormat.XML),
this.instantiationService.createInstance(ChartDataAction) this.instantiationService.createInstance(ChartDataAction)
); );
@@ -753,6 +754,7 @@ class GridTable<T> extends Disposable implements IView {
new SaveResultAction(SaveResultAction.SAVECSV_ID, SaveResultAction.SAVECSV_LABEL, SaveResultAction.SAVECSV_ICON, SaveFormat.CSV), new SaveResultAction(SaveResultAction.SAVECSV_ID, SaveResultAction.SAVECSV_LABEL, SaveResultAction.SAVECSV_ICON, SaveFormat.CSV),
new SaveResultAction(SaveResultAction.SAVEEXCEL_ID, SaveResultAction.SAVEEXCEL_LABEL, SaveResultAction.SAVEEXCEL_ICON, SaveFormat.EXCEL), new SaveResultAction(SaveResultAction.SAVEEXCEL_ID, SaveResultAction.SAVEEXCEL_LABEL, SaveResultAction.SAVEEXCEL_ICON, SaveFormat.EXCEL),
new SaveResultAction(SaveResultAction.SAVEJSON_ID, SaveResultAction.SAVEJSON_LABEL, SaveResultAction.SAVEJSON_ICON, SaveFormat.JSON), new SaveResultAction(SaveResultAction.SAVEJSON_ID, SaveResultAction.SAVEJSON_LABEL, SaveResultAction.SAVEJSON_ICON, SaveFormat.JSON),
new SaveResultAction(SaveResultAction.SAVEXML_ID, SaveResultAction.SAVEXML_LABEL, SaveResultAction.SAVEXML_ICON, SaveFormat.XML),
new Separator(), new Separator(),
new CopyResultAction(CopyResultAction.COPY_ID, CopyResultAction.COPY_LABEL, false), new CopyResultAction(CopyResultAction.COPY_ID, CopyResultAction.COPY_LABEL, false),
new CopyResultAction(CopyResultAction.COPYWITHHEADERS_ID, CopyResultAction.COPYWITHHEADERS_LABEL, true) new CopyResultAction(CopyResultAction.COPYWITHHEADERS_ID, CopyResultAction.COPYWITHHEADERS_LABEL, true)

3
src/sql/sqlops.d.ts vendored
View File

@@ -882,7 +882,7 @@ declare module 'sqlops' {
// Save Results =============================================================================== // Save Results ===============================================================================
export interface SaveResultsRequestParams { export interface SaveResultsRequestParams {
/** /**
* 'csv', 'json', 'excel' * 'csv', 'json', 'excel', 'xml'
*/ */
resultFormat: string; resultFormat: string;
ownerUri: string; ownerUri: string;
@@ -898,6 +898,7 @@ declare module 'sqlops' {
lineSeperator?: string; lineSeperator?: string;
textIdentifier?: string; textIdentifier?: string;
encoding?: string; encoding?: string;
formatted?: boolean;
} }
export interface SaveResultRequestResult { export interface SaveResultRequestResult {