Add connection info to title (#1645)

* add connection info to the file label

* formatting

* first attempt at title shortening

* add user to title shortening

* add settings to control connection info in title

* formatting

* move setting
This commit is contained in:
Anthony Dresser
2018-06-29 17:04:09 -07:00
committed by GitHub
parent 4bd63b615b
commit 2d80d5e611
6 changed files with 99 additions and 50 deletions

View File

@@ -38,7 +38,7 @@ export function convertEditorInput(input: EditorInput, options: IQueryEditorOpti
let uri: URI = getQueryEditorFileUri(input); let uri: URI = getQueryEditorFileUri(input);
if (uri) { if (uri) {
const queryResultsInput: QueryResultsInput = instantiationService.createInstance(QueryResultsInput, uri.toString()); const queryResultsInput: QueryResultsInput = instantiationService.createInstance(QueryResultsInput, uri.toString());
let queryInput: QueryInput = instantiationService.createInstance(QueryInput, input.getName(), '', input, queryResultsInput, undefined); let queryInput: QueryInput = instantiationService.createInstance(QueryInput, '', input, queryResultsInput, undefined);
return queryInput; return queryInput;
} }

View File

@@ -306,6 +306,11 @@ let registryProperties = {
'default': Constants.tabColorModeOff, 'default': Constants.tabColorModeOff,
'description': localize('tabColorMode', "Controls how to color tabs based on the server group of their active connection") 'description': localize('tabColorMode', "Controls how to color tabs based on the server group of their active connection")
}, },
'sql.showConnectionInfoInTitle': {
'type': 'boolean',
'description': localize('showConnectionInfoInTitle', "Controls whether to show the connection info for a tab in the title."),
'default': false
},
'mssql.intelliSense.enableIntelliSense': { 'mssql.intelliSense.enableIntelliSense': {
'type': 'boolean', 'type': 'boolean',
'default': true, 'default': true,

View File

@@ -4,17 +4,35 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import { EditorInput, EditorModel, ConfirmResult, EncodingMode, IEncodingSupport } from 'vs/workbench/common/editor'; import { localize } from 'vs/nls';
import { IConnectionManagementService, IConnectableInput, INewConnectionParams, RunQueryOnConnectionMode } from 'sql/parts/connection/common/connectionManagement';
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
import { QueryResultsInput } from 'sql/parts/query/common/queryResultsInput';
import { IQueryModelService } from 'sql/parts/query/execution/queryModel';
import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Event, Emitter } from 'vs/base/common/event'; import { Event, Emitter } from 'vs/base/common/event';
import URI from 'vs/base/common/uri'; import URI from 'vs/base/common/uri';
import { ISelectionData, ExecutionPlanOptions } from 'sqlops'; import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
import { EditorInput, EditorModel, ConfirmResult, EncodingMode, IEncodingSupport } from 'vs/workbench/common/editor';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IConnectionManagementService, IConnectableInput, INewConnectionParams, RunQueryOnConnectionMode } from 'sql/parts/connection/common/connectionManagement';
import { QueryResultsInput } from 'sql/parts/query/common/queryResultsInput';
import { IQueryModelService } from 'sql/parts/query/execution/queryModel';
import { IQueryEditorService } from 'sql/parts/query/common/queryEditorService'; import { IQueryEditorService } from 'sql/parts/query/common/queryEditorService';
import { ISelectionData, ExecutionPlanOptions } from 'sqlops';
const MAX_SIZE = 13;
function trimTitle(title: string): string {
const length = title.length;
const diff = length - MAX_SIZE;
if (Math.sign(diff) <= 0) {
return title;
} else {
const start = (length / 2) - (diff / 2);
return title.slice(0, start) + '...' + title.slice(start + diff, length);
}
}
/** /**
* Input for the QueryEditor. This input is simply a wrapper around a QueryResultsInput for the QueryResultsEditor * Input for the QueryEditor. This input is simply a wrapper around a QueryResultsInput for the QueryResultsEditor
* and a UntitledEditorInput for the SQL File Editor. * and a UntitledEditorInput for the SQL File Editor.
@@ -39,17 +57,16 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
private _currentEventCallbacks: IDisposable[]; private _currentEventCallbacks: IDisposable[];
constructor( constructor(
private _name: string,
private _description: string, private _description: string,
private _sql: UntitledEditorInput, private _sql: UntitledEditorInput,
private _results: QueryResultsInput, private _results: QueryResultsInput,
private _connectionProviderName: string, private _connectionProviderName: string,
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService, @IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
@IQueryModelService private _queryModelService: IQueryModelService, @IQueryModelService private _queryModelService: IQueryModelService,
@IQueryEditorService private _queryEditorService: IQueryEditorService @IQueryEditorService private _queryEditorService: IQueryEditorService,
@IConfigurationService private _configurationService: IConfigurationService
) { ) {
super(); super();
let self = this;
this._updateTaskbar = new Emitter<void>(); this._updateTaskbar = new Emitter<void>();
this._showQueryResultsEditor = new Emitter<void>(); this._showQueryResultsEditor = new Emitter<void>();
this._updateSelection = new Emitter<ISelectionData>(); this._updateSelection = new Emitter<ISelectionData>();
@@ -66,36 +83,44 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
// Register callbacks for the Actions // Register callbacks for the Actions
this._toDispose.push( this._toDispose.push(
this._queryModelService.onRunQueryStart(uri => { this._queryModelService.onRunQueryStart(uri => {
if (self.uri === uri) { if (this.uri === uri) {
self.onRunQuery(); this.onRunQuery();
} }
}) })
); );
this._toDispose.push( this._toDispose.push(
this._queryModelService.onRunQueryComplete(uri => { this._queryModelService.onRunQueryComplete(uri => {
if (self.uri === uri) { if (this.uri === uri) {
self.onQueryComplete(); this.onQueryComplete();
} }
}) })
); );
} }
if (this._connectionManagementService) { if (this._connectionManagementService) {
this._toDispose.push(self._connectionManagementService.onDisconnect(result => { this._toDispose.push(this._connectionManagementService.onDisconnect(result => {
if (result.connectionUri === self.uri) { if (result.connectionUri === this.uri) {
self.onDisconnect(); this.onDisconnect();
} }
})); }));
if (self.uri) { if (this.uri) {
if (this._connectionProviderName) { if (this._connectionProviderName) {
this._connectionManagementService.doChangeLanguageFlavor(self.uri, 'sql', this._connectionProviderName); this._connectionManagementService.doChangeLanguageFlavor(this.uri, 'sql', this._connectionProviderName);
} else { } else {
this._connectionManagementService.ensureDefaultLanguageFlavor(self.uri); this._connectionManagementService.ensureDefaultLanguageFlavor(this.uri);
} }
} }
} }
if (this._configurationService) {
this._configurationService.onDidChangeConfiguration(e => {
if (e.affectedKeys.includes('sql.showConnectionInfoInTitle')) {
this._onDidChangeLabel.fire();
}
});
}
this.onDisconnect(); this.onDisconnect();
this.onQueryComplete(); this.onQueryComplete();
} }
@@ -140,7 +165,27 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec
public getResource(): URI { return this._sql.getResource(); } public getResource(): URI { return this._sql.getResource(); }
public getEncoding(): string { return this._sql.getEncoding(); } public getEncoding(): string { return this._sql.getEncoding(); }
public suggestFileName(): string { return this._sql.suggestFileName(); } public suggestFileName(): string { return this._sql.suggestFileName(); }
public getName(): string { return this._sql.getName(); }
public getName(): string {
if (this._configurationService.getValue('sql.showConnectionInfoInTitle')) {
let profile = this._connectionManagementService.getConnectionProfile(this.uri);
let title = '';
if (profile) {
if (profile.userName) {
title = `${profile.serverName}.${profile.databaseName} (${profile.userName})`;
} else {
title = `${profile.serverName}.${profile.databaseName} (${profile.authenticationType})`;
}
} else {
title = localize('disconnected', 'disconnected');
}
return this._sql.getName() + ` - ${trimTitle(title)}`;
} else {
return this._sql.getName();
}
}
public get hasAssociatedFilePath(): boolean { return this._sql.hasAssociatedFilePath; } public get hasAssociatedFilePath(): boolean { return this._sql.hasAssociatedFilePath; }
public setEncoding(encoding: string, mode: EncodingMode /* ignored, we only have Encode */): void { public setEncoding(encoding: string, mode: EncodingMode /* ignored, we only have Encode */): void {

View File

@@ -93,7 +93,7 @@ export class QueryEditorService implements IQueryEditorService {
//input.resolve().then(model => this.backupFileService.backupResource(resource, model.getValue(), model.getVersionId())).done(null, errors.onUnexpectedError); //input.resolve().then(model => this.backupFileService.backupResource(resource, model.getValue(), model.getVersionId())).done(null, errors.onUnexpectedError);
const queryResultsInput: QueryResultsInput = this._instantiationService.createInstance(QueryResultsInput, docUri.toString()); const queryResultsInput: QueryResultsInput = this._instantiationService.createInstance(QueryResultsInput, docUri.toString());
let queryInput: QueryInput = this._instantiationService.createInstance(QueryInput, fileInput.getName(), '', fileInput, queryResultsInput, connectionProviderName); let queryInput: QueryInput = this._instantiationService.createInstance(QueryInput, '', fileInput, queryResultsInput, connectionProviderName);
this._editorService.openEditor(queryInput, { pinned: true }) this._editorService.openEditor(queryInput, { pinned: true })
.then((editor) => { .then((editor) => {
@@ -222,8 +222,7 @@ export class QueryEditorService implements IQueryEditorService {
} }
let uri: URI = QueryEditorService._getEditorChangeUri(editor.input, changingToSql); let uri: URI = QueryEditorService._getEditorChangeUri(editor.input, changingToSql);
if(uri.scheme === Schemas.untitled && (editor.input instanceof QueryInput || editor.input instanceof EditDataInput)) if (uri.scheme === Schemas.untitled && (editor.input instanceof QueryInput || editor.input instanceof EditDataInput)) {
{
QueryEditorService.notificationService.notify({ QueryEditorService.notificationService.notify({
severity: Severity.Error, severity: Severity.Error,
message: QueryEditorService.CHANGE_UNSUPPORTED_ERROR_MESSAGE message: QueryEditorService.CHANGE_UNSUPPORTED_ERROR_MESSAGE
@@ -331,7 +330,7 @@ export class QueryEditorService implements IQueryEditorService {
let newEditorInput: IEditorInput = undefined; let newEditorInput: IEditorInput = undefined;
if (changingToSql) { if (changingToSql) {
const queryResultsInput: QueryResultsInput = QueryEditorService.instantiationService.createInstance(QueryResultsInput, uri.toString()); const queryResultsInput: QueryResultsInput = QueryEditorService.instantiationService.createInstance(QueryResultsInput, uri.toString());
let queryInput: QueryInput = QueryEditorService.instantiationService.createInstance(QueryInput, input.getName(), '', input, queryResultsInput, undefined); let queryInput: QueryInput = QueryEditorService.instantiationService.createInstance(QueryInput, '', input, queryResultsInput, undefined);
newEditorInput = queryInput; newEditorInput = queryInput;
} else { } else {
let uriCopy: URI = URI.from({ scheme: uri.scheme, authority: uri.authority, path: uri.path, query: uri.query, fragment: uri.fragment }); let uriCopy: URI = URI.from({ scheme: uri.scheme, authority: uri.authority, path: uri.path, query: uri.query, fragment: uri.fragment });

View File

@@ -114,14 +114,14 @@ suite('SQL QueryEditor Tests', () => {
let uri: URI = URI.parse(filePath); let uri: URI = URI.parse(filePath);
let fileInput = new UntitledEditorInput(uri, false, '', '', '', instantiationService.object, undefined, undefined, undefined, undefined); let fileInput = new UntitledEditorInput(uri, false, '', '', '', instantiationService.object, undefined, undefined, undefined, undefined);
let queryResultsInput: QueryResultsInput = new QueryResultsInput(uri.fsPath); let queryResultsInput: QueryResultsInput = new QueryResultsInput(uri.fsPath);
queryInput = new QueryInput('first', 'first', fileInput, queryResultsInput, undefined, undefined, undefined, undefined); queryInput = new QueryInput('first', fileInput, queryResultsInput, undefined, undefined, undefined, undefined, undefined);
// Create a QueryInput to compare to the previous one // Create a QueryInput to compare to the previous one
let filePath2 = 'someFile2.sql'; let filePath2 = 'someFile2.sql';
let uri2: URI = URI.parse(filePath2); let uri2: URI = URI.parse(filePath2);
let fileInput2 = new UntitledEditorInput(uri2, false, '', '', '', instantiationService.object, undefined, undefined, undefined, undefined); let fileInput2 = new UntitledEditorInput(uri2, false, '', '', '', instantiationService.object, undefined, undefined, undefined, undefined);
let queryResultsInput2: QueryResultsInput = new QueryResultsInput(uri2.fsPath); let queryResultsInput2: QueryResultsInput = new QueryResultsInput(uri2.fsPath);
queryInput2 = new QueryInput('second', 'second', fileInput2, queryResultsInput2, undefined, undefined, undefined, undefined); queryInput2 = new QueryInput('second', fileInput2, queryResultsInput2, undefined, undefined, undefined, undefined, undefined);
// Mock IMessageService // Mock IMessageService
notificationService = TypeMoq.Mock.ofType(TestNotificationService, TypeMoq.MockBehavior.Loose); notificationService = TypeMoq.Mock.ofType(TestNotificationService, TypeMoq.MockBehavior.Loose);
@@ -346,13 +346,13 @@ suite('SQL QueryEditor Tests', () => {
queryModelService = TypeMoq.Mock.ofType(QueryModelService, TypeMoq.MockBehavior.Loose, undefined, undefined); queryModelService = TypeMoq.Mock.ofType(QueryModelService, TypeMoq.MockBehavior.Loose, undefined, undefined);
queryModelService.callBase = true; queryModelService.callBase = true;
queryInput = new QueryInput( queryInput = new QueryInput(
'testUri',
'', '',
fileInput, fileInput,
undefined, undefined,
undefined, undefined,
undefined, undefined,
queryModelService.object, queryModelService.object,
undefined,
undefined undefined
); );
}); });

View File

@@ -80,7 +80,7 @@ suite('TaskUtilities', function() {
// Mock the workbench service to return the active tab connection // Mock the workbench service to return the active tab connection
let tabConnectionUri = 'test_uri'; let tabConnectionUri = 'test_uri';
let editorInput = new UntitledEditorInput(URI.parse(tabConnectionUri), false, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined); let editorInput = new UntitledEditorInput(URI.parse(tabConnectionUri), false, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined);
let queryInput = new QueryInput(undefined, undefined, editorInput, undefined, undefined, undefined, undefined, undefined); let queryInput = new QueryInput(undefined, editorInput, undefined, undefined, undefined, undefined, undefined, undefined);
mockWorkbenchEditorService.setup(x => x.getActiveEditorInput()).returns(() => queryInput); mockWorkbenchEditorService.setup(x => x.getActiveEditorInput()).returns(() => queryInput);
mockConnectionManagementService.setup(x => x.getConnectionProfile(tabConnectionUri)).returns(() => tabProfile); mockConnectionManagementService.setup(x => x.getConnectionProfile(tabConnectionUri)).returns(() => tabProfile);