diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 22c76794b9aa1e4fbbd46f60c5357862f14edbcb..c61670d64018d4f1b16efd94e84c9869bd7fb23a 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -25,7 +25,7 @@ import {EventType as WorkbenchEventType, EditorEvent} from 'vs/workbench/common/ import {IEditorRegistry, Extensions as EditorExtensions, BaseEditor, EditorDescriptor} from 'vs/workbench/browser/parts/editor/baseEditor'; import {EditorInput, EditorOptions, TextEditorOptions} from 'vs/workbench/common/editor'; import {BaseTextEditor} from 'vs/workbench/browser/parts/editor/textEditor'; -import {SideBySideEditorControl, Rochade, ISideBySideEditorControl} from 'vs/workbench/browser/parts/editor/sideBySideEditorControl'; +import {SideBySideEditorControl, Rochade, ISideBySideEditorControl, ProgressState} from 'vs/workbench/browser/parts/editor/sideBySideEditorControl'; import {WorkbenchProgressService} from 'vs/workbench/services/progress/browser/progressService'; import {EditorArrangement} from 'vs/workbench/services/editor/common/editorService'; import {IEditorPart} from 'vs/workbench/services/editor/browser/editorService'; @@ -212,7 +212,7 @@ export class EditorPart extends Part implements IEditorPart { const editorOpenToken = this.editorOpenToken[position]; const monitor = new ProgressMonitor(editorOpenToken, TPromise.timeout(this.partService.isCreated() ? 800 : 3200 /* less ugly initial startup */).then(() => { if (editorOpenToken === this.editorOpenToken[position]) { - this.sideBySideControl.getProgressBar(position).infinite().getContainer().show(); + this.sideBySideControl.updateProgress(position, ProgressState.INFINITE); this.sideBySideControl.setLoading(position, input); } })); @@ -423,15 +423,14 @@ export class EditorPart extends Part implements IEditorPart { } // Progress Done - this.sideBySideControl.getProgressBar(position).done().getContainer().hide(); + this.sideBySideControl.updateProgress(position, ProgressState.DONE); - // Update Title Area if input changed if (inputChanged) { + + // Update Title Area if input changed this.sideBySideControl.updateEditorTitleArea(); - } - // Emit Input-Changed Event (if input changed) - if (inputChanged) { + // Emit Input-Changed Event (if input changed) this.emit(WorkbenchEventType.EDITOR_INPUT_CHANGED, new EditorEvent(editor, editor.getId(), input, options, position)); } @@ -439,48 +438,52 @@ export class EditorPart extends Part implements IEditorPart { // Fullfill promise with Editor that is being used return editor; - }, (e: any) => { - // Keep counter - this.editorSetInputErrorCounter[position]++; + }, (e: any) => this.doHandleSetInputError(e, editor, input, oldInput, options, position, monitor)); + } - // Stop loading promise if any - monitor.cancel(); + private doHandleSetInputError(e: Error | IMessageWithAction, editor: BaseEditor, input: EditorInput, oldInput: EditorInput, options: EditorOptions, position: Position, monitor: ProgressMonitor): void { - // Report error only if this was not us restoring previous error state - if (this.partService.isCreated() && !errors.isPromiseCanceledError(e)) { - let errorMessage = nls.localize('editorOpenError', "Unable to open '{0}': {1}.", input.getName(), errors.toErrorMessage(e)); + // Keep counter + this.editorSetInputErrorCounter[position]++; - let error: any; - if (e && (e).actions && (e).actions.length) { - error = errors.create(errorMessage, { actions: (e).actions }); // Support error actions from thrower - } else { - error = errorMessage; - } + // Stop loading promise if any + monitor.cancel(); + + // Report error only if this was not us restoring previous error state + if (this.partService.isCreated() && !errors.isPromiseCanceledError(e)) { + let errorMessage = nls.localize('editorOpenError', "Unable to open '{0}': {1}.", input.getName(), errors.toErrorMessage(e)); - this.messageService.show(Severity.Error, types.isString(error) ? new Error(error) : error); + let error: any; + if (e && (e).actions && (e).actions.length) { + error = errors.create(errorMessage, { actions: (e).actions }); // Support error actions from thrower + } else { + error = errorMessage; } - this.sideBySideControl.getProgressBar(position).done().getContainer().hide(); - this.emit(WorkbenchEventType.EDITOR_SET_INPUT_ERROR, new EditorEvent(editor, editor.getId(), input, options, position)); + this.messageService.show(Severity.Error, types.isString(error) ? new Error(error) : error); + } - // Recover from this error by closing the editor if the attempt of setInput failed and we are not having any previous input - if (!oldInput && this.visibleInputs[position] === input && input) { - this.openEditor(null, null, position).done(null, errors.onUnexpectedError); - } + this.sideBySideControl.updateProgress(position, ProgressState.DONE); + + this.emit(WorkbenchEventType.EDITOR_SET_INPUT_ERROR, new EditorEvent(editor, editor.getId(), input, options, position)); - // We need to check our error counter here to prevent reentrant setInput() calls. If the workbench is in error state - // to the disk, opening a file would fail and we would try to open the previous file which would fail too. So we - // stop trying to open a previous file if we detect that we failed more than once already - else if (this.editorSetInputErrorCounter[position] > 1) { - this.openEditor(null, null, position).done(null, errors.onUnexpectedError); - } + // Recover from this error by closing the editor if the attempt of setInput failed and we are not having any previous input + if (!oldInput && this.visibleInputs[position] === input && input) { + this.openEditor(null, null, position).done(null, errors.onUnexpectedError); + } - // Otherwise if we had oldInput, properly restore it so that the active input points to the previous one - else if (oldInput) { - this.openEditor(oldInput, null, position).done(null, errors.onUnexpectedError); - } - }); + // We need to check our error counter here to prevent reentrant setInput() calls. If the workbench is in error state + // to the disk, opening a file would fail and we would try to open the previous file which would fail too. So we + // stop trying to open a previous file if we detect that we failed more than once already + else if (this.editorSetInputErrorCounter[position] > 1) { + this.openEditor(null, null, position).done(null, errors.onUnexpectedError); + } + + // Otherwise if we had oldInput, properly restore it so that the active input points to the previous one + else if (oldInput) { + this.openEditor(oldInput, null, position).done(null, errors.onUnexpectedError); + } } private doCloseEditor(input: EditorInput, position: Position): TPromise { @@ -525,7 +528,7 @@ export class EditorPart extends Part implements IEditorPart { let rochade = this.sideBySideControl.hide(editor, editorContainer, position, layoutAndRochade); // Clear any running Progress - this.sideBySideControl.getProgressBar(position).stop().getContainer().hide(); + this.sideBySideControl.updateProgress(position, ProgressState.STOP); // Clear Listeners while (this.visibleEditorListeners[position].length) { @@ -672,7 +675,7 @@ export class EditorPart extends Part implements IEditorPart { if (editorState && editorState.editors) { // Find inputs to restore - let registry = (Registry.as(EditorExtensions.Editors)); + let registry = Registry.as(EditorExtensions.Editors); let inputs: EditorInput[] = []; widthRatios = editorState.widthRatio; @@ -791,7 +794,7 @@ export class EditorPart extends Part implements IEditorPart { } private saveEditorState(): void { - let registry = (Registry.as(EditorExtensions.Editors)); + let registry = Registry.as(EditorExtensions.Editors); let editors = this.getVisibleEditors(); let activeEditor = this.getActiveEditor(); diff --git a/src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts b/src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts index 9b116244dffd2d64c0fa28cd9926a5fee7e34ad1..0324f87f392b2373d82e0486b4720ac65c9c3d66 100644 --- a/src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts +++ b/src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts @@ -44,6 +44,12 @@ export enum Rochade { CENTER_AND_RIGHT_TO_LEFT } +export enum ProgressState { + INFINITE, + DONE, + STOP +} + interface IEditorActions { primary: IAction[]; secondary: IAction[]; @@ -64,8 +70,12 @@ export interface ISideBySideEditorControl { move(from: Position, to: Position): void; isDragging(): boolean; + setLoading(position: Position, input: EditorInput): void; + getProgressBar(position: Position): ProgressBar; + updateProgress(position: Position, state: ProgressState): void; + layout(dimension: Dimension): void; layout(position: Position): void; @@ -1212,7 +1222,7 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti return actionItem; } - public setTitle(position: Position, input: EditorInput, primaryActions: IAction[], secondaryActions: IAction[], isActive: boolean): void { + private setTitle(position: Position, input: EditorInput, primaryActions: IAction[], secondaryActions: IAction[], isActive: boolean): void { // Activity class if (isActive) { @@ -1238,11 +1248,7 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti this.titleDescription[position].title(verboseDescription); // Editor Input State Description - if (input) { - this.setEditorInputStateIndicator(input, input.getStatus(), position); - } else { - this.setEditorInputStateIndicator(null, null, null); - } + this.setEditorInputStateIndicator(input, input.getStatus(), position); // Support split editor action if visible editor count is < 3 and editor supports it if (isActive && this.getVisibleEditorCount() < 3 && this.lastActiveEditor.supportsSplitEditor()) { @@ -1253,9 +1259,7 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti this.editorActionsToolbar[position].setActions(primaryActions, secondaryActions)(); // Add a close action - if (input) { - this.editorActionsToolbar[position].addPrimaryAction(this.closeEditorAction[position])(); - } + this.editorActionsToolbar[position].addPrimaryAction(this.closeEditorAction[position])(); } public setLoading(position: Position, input: EditorInput): void { @@ -1268,9 +1272,7 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti this.editorActionsToolbar[position].setActions([], [])(); // Add a close action - if (input) { - this.editorActionsToolbar[position].addPrimaryAction(this.closeEditorAction[position])(); - } + this.editorActionsToolbar[position].addPrimaryAction(this.closeEditorAction[position])(); } public clearTitle(position: Position): void { @@ -1597,6 +1599,20 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti return this.progressBar[position]; } + public updateProgress(position: Position, state: ProgressState): void { + switch (state) { + case ProgressState.INFINITE: + this.progressBar[position].infinite().getContainer().show(); + break; + case ProgressState.DONE: + this.progressBar[position].done().getContainer().hide(); + break; + case ProgressState.STOP: + this.progressBar[position].stop().getContainer().hide(); + break; + } + } + public dispose(): void { // Positions