mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-05 17:23:51 -05:00
Merge VS Code 1.21 source code (#1067)
* Initial VS Code 1.21 file copy with patches * A few more merges * Post npm install * Fix batch of build breaks * Fix more build breaks * Fix more build errors * Fix more build breaks * Runtime fixes 1 * Get connection dialog working with some todos * Fix a few packaging issues * Copy several node_modules to package build to fix loader issues * Fix breaks from master * A few more fixes * Make tests pass * First pass of license header updates * Second pass of license header updates * Fix restore dialog issues * Remove add additional themes menu items * fix select box issues where the list doesn't show up * formatting * Fix editor dispose issue * Copy over node modules to correct location on all platforms
This commit is contained in:
@@ -19,13 +19,13 @@ import { IPathWithLineAndColumn, parseLineAndColumnAware } from 'vs/code/node/pa
|
||||
import { ILifecycleService, UnloadReason, IWindowUnloadEvent } from 'vs/platform/lifecycle/electron-main/lifecycleMain';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IWindowSettings, OpenContext, IPath, IWindowConfiguration, INativeOpenDialogOptions, ReadyState, IPathsToWaitFor, IEnterWorkspaceResult } from 'vs/platform/windows/common/windows';
|
||||
import { IWindowSettings, OpenContext, IPath, IWindowConfiguration, INativeOpenDialogOptions, ReadyState, IPathsToWaitFor, IEnterWorkspaceResult, IMessageBoxResult } from 'vs/platform/windows/common/windows';
|
||||
import { getLastActiveWindow, findBestWindowOrFolderForFile, findWindowOnWorkspace, findWindowOnExtensionDevelopmentPath, findWindowOnWorkspaceOrFolderPath } from 'vs/code/node/windowsFinder';
|
||||
import CommonEvent, { Emitter } from 'vs/base/common/event';
|
||||
import product from 'vs/platform/node/product';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { isEqual } from 'vs/base/common/paths';
|
||||
import { IWindowsMainService, IOpenConfiguration, IWindowsCountChangedEvent } from 'vs/platform/windows/electron-main/windows';
|
||||
import { IWindowsMainService, IOpenConfiguration, IWindowsCountChangedEvent, ICodeWindow } from 'vs/platform/windows/electron-main/windows';
|
||||
import { IHistoryMainService } from 'vs/platform/history/common/history';
|
||||
import { IProcessEnvironment, isLinux, isMacintosh, isWindows } from 'vs/base/common/platform';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
@@ -35,6 +35,7 @@ import { mnemonicButtonLabel } from 'vs/base/common/labels';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { normalizeNFC } from 'vs/base/common/strings';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { Queue } from 'vs/base/common/async';
|
||||
|
||||
enum WindowError {
|
||||
UNRESPONSIVE,
|
||||
@@ -45,10 +46,6 @@ interface INewWindowState extends ISingleWindowState {
|
||||
hasDefaultState?: boolean;
|
||||
}
|
||||
|
||||
interface ILegacyWindowState extends IWindowState {
|
||||
workspacePath?: string;
|
||||
}
|
||||
|
||||
interface IWindowState {
|
||||
workspace?: IWorkspaceIdentifier;
|
||||
folderPath?: string;
|
||||
@@ -56,10 +53,6 @@ interface IWindowState {
|
||||
uiState: ISingleWindowState;
|
||||
}
|
||||
|
||||
interface ILegacyWindowsState extends IWindowsState {
|
||||
openedFolders?: IWindowState[];
|
||||
}
|
||||
|
||||
interface IWindowsState {
|
||||
lastActiveWindow?: IWindowState;
|
||||
lastPluginDevelopmentHostWindow?: IWindowState;
|
||||
@@ -116,7 +109,7 @@ export class WindowsManager implements IWindowsMainService {
|
||||
private windowsState: IWindowsState;
|
||||
private lastClosedWindowState: IWindowState;
|
||||
|
||||
private fileDialog: FileDialog;
|
||||
private dialogs: Dialogs;
|
||||
private workspacesManager: WorkspacesManager;
|
||||
|
||||
private _onWindowReady = new Emitter<CodeWindow>();
|
||||
@@ -151,39 +144,12 @@ export class WindowsManager implements IWindowsMainService {
|
||||
@IInstantiationService private instantiationService: IInstantiationService
|
||||
) {
|
||||
this.windowsState = this.stateService.getItem<IWindowsState>(WindowsManager.windowsStateStorageKey) || { openedWindows: [] };
|
||||
|
||||
this.fileDialog = new FileDialog(environmentService, telemetryService, stateService, this);
|
||||
this.workspacesManager = new WorkspacesManager(workspacesMainService, backupMainService, environmentService, this);
|
||||
|
||||
this.migrateLegacyWindowState();
|
||||
}
|
||||
|
||||
private migrateLegacyWindowState(): void {
|
||||
const state: ILegacyWindowsState = this.windowsState;
|
||||
|
||||
// TODO@Ben migration from previous openedFolders to new openedWindows property
|
||||
if (Array.isArray(state.openedFolders) && state.openedFolders.length > 0) {
|
||||
state.openedWindows = state.openedFolders;
|
||||
state.openedFolders = void 0;
|
||||
} else if (!state.openedWindows) {
|
||||
state.openedWindows = [];
|
||||
if (!Array.isArray(this.windowsState.openedWindows)) {
|
||||
this.windowsState.openedWindows = [];
|
||||
}
|
||||
|
||||
// TODO@Ben migration from previous workspacePath in window state to folderPath
|
||||
const states: ILegacyWindowState[] = [];
|
||||
states.push(state.lastActiveWindow);
|
||||
states.push(state.lastPluginDevelopmentHostWindow);
|
||||
states.push(...state.openedWindows);
|
||||
states.forEach(state => {
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof state.workspacePath === 'string') {
|
||||
state.folderPath = state.workspacePath;
|
||||
state.workspacePath = void 0;
|
||||
}
|
||||
});
|
||||
this.dialogs = new Dialogs(environmentService, telemetryService, stateService, this);
|
||||
this.workspacesManager = new WorkspacesManager(workspacesMainService, backupMainService, environmentService, this);
|
||||
}
|
||||
|
||||
public ready(initialUserEnv: IProcessEnvironment): void {
|
||||
@@ -277,7 +243,7 @@ export class WindowsManager implements IWindowsMainService {
|
||||
// - closeAll(2): onBeforeWindowClose(2, false), onBeforeWindowClose(2, false), onBeforeQuit(0)
|
||||
//
|
||||
private onBeforeQuit(): void {
|
||||
const currentWindowsState: ILegacyWindowsState = {
|
||||
const currentWindowsState: IWindowsState = {
|
||||
openedWindows: [],
|
||||
lastPluginDevelopmentHostWindow: this.windowsState.lastPluginDevelopmentHostWindow,
|
||||
lastActiveWindow: this.lastClosedWindowState
|
||||
@@ -403,7 +369,7 @@ export class WindowsManager implements IWindowsMainService {
|
||||
let foldersToRestore: string[] = [];
|
||||
let workspacesToRestore: IWorkspaceIdentifier[] = [];
|
||||
let emptyToRestore: string[] = [];
|
||||
if (openConfig.initialStartup && !openConfig.cli.extensionDevelopmentPath) {
|
||||
if (openConfig.initialStartup && !openConfig.cli.extensionDevelopmentPath && !openConfig.cli['disable-restore-windows']) {
|
||||
foldersToRestore = this.backupMainService.getFolderBackupPaths();
|
||||
|
||||
workspacesToRestore = this.backupMainService.getWorkspaceBackups(); // collect from workspaces with hot-exit backups
|
||||
@@ -825,12 +791,7 @@ export class WindowsManager implements IWindowsMainService {
|
||||
noLink: true
|
||||
};
|
||||
|
||||
const activeWindow = BrowserWindow.getFocusedWindow();
|
||||
if (activeWindow) {
|
||||
dialog.showMessageBox(activeWindow, options);
|
||||
} else {
|
||||
dialog.showMessageBox(options);
|
||||
}
|
||||
this.dialogs.showMessageBox(options, this.getFocusedWindow());
|
||||
}
|
||||
|
||||
return path;
|
||||
@@ -940,10 +901,6 @@ export class WindowsManager implements IWindowsMainService {
|
||||
const windowConfig = this.configurationService.getValue<IWindowSettings>('window');
|
||||
restoreWindows = ((windowConfig && windowConfig.restoreWindows) || 'one') as RestoreWindowsSetting;
|
||||
|
||||
if (restoreWindows === 'one' /* default */ && windowConfig && windowConfig.reopenFolders) {
|
||||
restoreWindows = windowConfig.reopenFolders; // TODO@Ben migration from deprecated window.reopenFolders setting
|
||||
}
|
||||
|
||||
if (['all', 'folders', 'one', 'none'].indexOf(restoreWindows) === -1) {
|
||||
restoreWindows = 'one';
|
||||
}
|
||||
@@ -987,10 +944,14 @@ export class WindowsManager implements IWindowsMainService {
|
||||
};
|
||||
}
|
||||
|
||||
// Folder
|
||||
return {
|
||||
folderPath: candidate
|
||||
};
|
||||
// Folder (we check for isDirectory() because e.g. paths like /dev/null
|
||||
// are neither file nor folder but some external tools might pass them
|
||||
// over to us)
|
||||
else if (candidateStat.isDirectory()) {
|
||||
return {
|
||||
folderPath: candidate
|
||||
};
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
this.historyMainService.removeFromRecentlyOpened([candidate]); // since file does not seem to exist anymore, remove from recent
|
||||
@@ -1361,7 +1322,10 @@ export class WindowsManager implements IWindowsMainService {
|
||||
}
|
||||
|
||||
if (e.window.config && !!e.window.config.extensionDevelopmentPath) {
|
||||
return; // do not ask to save workspace when doing extension development
|
||||
// do not ask to save workspace when doing extension development
|
||||
// but still delete it.
|
||||
this.workspacesMainService.deleteUntitledWorkspaceSync(workspace);
|
||||
return;
|
||||
}
|
||||
|
||||
if (windowClosing && !isMacintosh && this.getWindowCount() === 1) {
|
||||
@@ -1369,7 +1333,17 @@ export class WindowsManager implements IWindowsMainService {
|
||||
}
|
||||
|
||||
// Handle untitled workspaces with prompt as needed
|
||||
this.workspacesManager.promptToSaveUntitledWorkspace(e, workspace);
|
||||
e.veto(this.workspacesManager.promptToSaveUntitledWorkspace(this.getWindowById(e.window.id), workspace).then(veto => {
|
||||
if (veto) {
|
||||
return veto;
|
||||
}
|
||||
|
||||
// Bug in electron: somehow we need this timeout so that the window closes properly. That
|
||||
// might be related to the fact that the untitled workspace prompt shows up async and this
|
||||
// code can execute before the dialog is fully closed which then blocks the window from closing.
|
||||
// Issue: https://github.com/Microsoft/vscode/issues/41989
|
||||
return TPromise.timeout(0).then(() => veto);
|
||||
}));
|
||||
}
|
||||
|
||||
public focusLastActive(cli: ParsedArgs, context: OpenContext): CodeWindow {
|
||||
@@ -1457,48 +1431,48 @@ export class WindowsManager implements IWindowsMainService {
|
||||
|
||||
// Unresponsive
|
||||
if (error === WindowError.UNRESPONSIVE) {
|
||||
const result = dialog.showMessageBox(window.win, {
|
||||
this.dialogs.showMessageBox({
|
||||
title: product.nameLong,
|
||||
type: 'warning',
|
||||
buttons: [mnemonicButtonLabel(localize({ key: 'reopen', comment: ['&& denotes a mnemonic'] }, "&&Reopen")), mnemonicButtonLabel(localize({ key: 'wait', comment: ['&& denotes a mnemonic'] }, "&&Keep Waiting")), mnemonicButtonLabel(localize({ key: 'close', comment: ['&& denotes a mnemonic'] }, "&&Close"))],
|
||||
message: localize('appStalled', "The window is no longer responding"),
|
||||
detail: localize('appStalledDetail', "You can reopen or close the window or keep waiting."),
|
||||
noLink: true
|
||||
}, window).then(result => {
|
||||
if (!window.win) {
|
||||
return; // Return early if the window has been going down already
|
||||
}
|
||||
|
||||
if (result.button === 0) {
|
||||
window.reload();
|
||||
} else if (result.button === 2) {
|
||||
this.onBeforeWindowClose(window); // 'close' event will not be fired on destroy(), so run it manually
|
||||
window.win.destroy(); // make sure to destroy the window as it is unresponsive
|
||||
}
|
||||
});
|
||||
|
||||
if (!window.win) {
|
||||
return; // Return early if the window has been going down already
|
||||
}
|
||||
|
||||
if (result === 0) {
|
||||
window.reload();
|
||||
} else if (result === 2) {
|
||||
this.onBeforeWindowClose(window); // 'close' event will not be fired on destroy(), so run it manually
|
||||
window.win.destroy(); // make sure to destroy the window as it is unresponsive
|
||||
}
|
||||
}
|
||||
|
||||
// Crashed
|
||||
else {
|
||||
const result = dialog.showMessageBox(window.win, {
|
||||
this.dialogs.showMessageBox({
|
||||
title: product.nameLong,
|
||||
type: 'warning',
|
||||
buttons: [mnemonicButtonLabel(localize({ key: 'reopen', comment: ['&& denotes a mnemonic'] }, "&&Reopen")), mnemonicButtonLabel(localize({ key: 'close', comment: ['&& denotes a mnemonic'] }, "&&Close"))],
|
||||
message: localize('appCrashed', "The window has crashed"),
|
||||
detail: localize('appCrashedDetail', "We are sorry for the inconvenience! You can reopen the window to continue where you left off."),
|
||||
noLink: true
|
||||
}, window).then(result => {
|
||||
if (!window.win) {
|
||||
return; // Return early if the window has been going down already
|
||||
}
|
||||
|
||||
if (result.button === 0) {
|
||||
window.reload();
|
||||
} else if (result.button === 1) {
|
||||
this.onBeforeWindowClose(window); // 'close' event will not be fired on destroy(), so run it manually
|
||||
window.win.destroy(); // make sure to destroy the window as it has crashed
|
||||
}
|
||||
});
|
||||
|
||||
if (!window.win) {
|
||||
return; // Return early if the window has been going down already
|
||||
}
|
||||
|
||||
if (result === 0) {
|
||||
window.reload();
|
||||
} else if (result === 1) {
|
||||
this.onBeforeWindowClose(window); // 'close' event will not be fired on destroy(), so run it manually
|
||||
window.win.destroy(); // make sure to destroy the window as it has crashed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1558,7 +1532,19 @@ export class WindowsManager implements IWindowsMainService {
|
||||
}
|
||||
}
|
||||
|
||||
this.fileDialog.pickAndOpen(internalOptions);
|
||||
this.dialogs.pickAndOpen(internalOptions);
|
||||
}
|
||||
|
||||
public showMessageBox(options: Electron.MessageBoxOptions, win?: CodeWindow): TPromise<IMessageBoxResult> {
|
||||
return this.dialogs.showMessageBox(options, win);
|
||||
}
|
||||
|
||||
public showSaveDialog(options: Electron.SaveDialogOptions, win?: CodeWindow): TPromise<string> {
|
||||
return this.dialogs.showSaveDialog(options, win);
|
||||
}
|
||||
|
||||
public showOpenDialog(options: Electron.OpenDialogOptions, win?: CodeWindow): TPromise<string[]> {
|
||||
return this.dialogs.showOpenDialog(options, win);
|
||||
}
|
||||
|
||||
public quit(): void {
|
||||
@@ -1584,20 +1570,25 @@ interface IInternalNativeOpenDialogOptions extends INativeOpenDialogOptions {
|
||||
pickFiles?: boolean;
|
||||
}
|
||||
|
||||
class FileDialog {
|
||||
class Dialogs {
|
||||
|
||||
private static readonly workingDirPickerStorageKey = 'pickerWorkingDir';
|
||||
|
||||
private mapWindowToDialogQueue: Map<number, Queue<any>>;
|
||||
private noWindowDialogQueue: Queue<any>;
|
||||
|
||||
constructor(
|
||||
private environmentService: IEnvironmentService,
|
||||
private telemetryService: ITelemetryService,
|
||||
private stateService: IStateService,
|
||||
private windowsMainService: IWindowsMainService
|
||||
private windowsMainService: IWindowsMainService,
|
||||
) {
|
||||
this.mapWindowToDialogQueue = new Map<number, Queue<any>>();
|
||||
this.noWindowDialogQueue = new Queue<any>();
|
||||
}
|
||||
|
||||
public pickAndOpen(options: INativeOpenDialogOptions): void {
|
||||
this.getFileOrFolderPaths(options, (paths: string[]) => {
|
||||
this.getFileOrFolderPaths(options).then(paths => {
|
||||
const numberOfPaths = paths ? paths.length : 0;
|
||||
|
||||
// Telemetry
|
||||
@@ -1623,7 +1614,7 @@ class FileDialog {
|
||||
});
|
||||
}
|
||||
|
||||
private getFileOrFolderPaths(options: IInternalNativeOpenDialogOptions, clb: (paths: string[]) => void): void {
|
||||
private getFileOrFolderPaths(options: IInternalNativeOpenDialogOptions): TPromise<string[]> {
|
||||
|
||||
// Ensure dialog options
|
||||
if (!options.dialogOptions) {
|
||||
@@ -1632,7 +1623,7 @@ class FileDialog {
|
||||
|
||||
// Ensure defaultPath
|
||||
if (!options.dialogOptions.defaultPath) {
|
||||
options.dialogOptions.defaultPath = this.stateService.getItem<string>(FileDialog.workingDirPickerStorageKey);
|
||||
options.dialogOptions.defaultPath = this.stateService.getItem<string>(Dialogs.workingDirPickerStorageKey);
|
||||
}
|
||||
|
||||
// Ensure properties
|
||||
@@ -1654,28 +1645,86 @@ class FileDialog {
|
||||
|
||||
// Show Dialog
|
||||
const focusedWindow = this.windowsMainService.getWindowById(options.windowId) || this.windowsMainService.getFocusedWindow();
|
||||
let paths = dialog.showOpenDialog(focusedWindow && focusedWindow.win, options.dialogOptions);
|
||||
if (paths && paths.length > 0) {
|
||||
if (isMacintosh) {
|
||||
|
||||
return this.showOpenDialog(options.dialogOptions, focusedWindow).then(paths => {
|
||||
if (paths && paths.length > 0) {
|
||||
|
||||
// Remember path in storage for next time
|
||||
this.stateService.setItem(Dialogs.workingDirPickerStorageKey, dirname(paths[0]));
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
return void 0;
|
||||
});
|
||||
}
|
||||
|
||||
private getDialogQueue(window?: ICodeWindow): Queue<any> {
|
||||
if (!window) {
|
||||
return this.noWindowDialogQueue;
|
||||
}
|
||||
|
||||
let windowDialogQueue = this.mapWindowToDialogQueue.get(window.id);
|
||||
if (!windowDialogQueue) {
|
||||
windowDialogQueue = new Queue<any>();
|
||||
this.mapWindowToDialogQueue.set(window.id, windowDialogQueue);
|
||||
}
|
||||
|
||||
return windowDialogQueue;
|
||||
}
|
||||
|
||||
public showMessageBox(options: Electron.MessageBoxOptions, window?: ICodeWindow): TPromise<IMessageBoxResult> {
|
||||
return this.getDialogQueue(window).queue(() => {
|
||||
return new TPromise((c, e) => {
|
||||
dialog.showMessageBox(window ? window.win : void 0, options, (response: number, checkboxChecked: boolean) => {
|
||||
c({ button: response, checkboxChecked });
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public showSaveDialog(options: Electron.SaveDialogOptions, window?: ICodeWindow): TPromise<string> {
|
||||
function normalizePath(path: string): string {
|
||||
if (path && isMacintosh) {
|
||||
path = normalizeNFC(path); // normalize paths returned from the OS
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
return this.getDialogQueue(window).queue(() => {
|
||||
return new TPromise((c, e) => {
|
||||
dialog.showSaveDialog(window ? window.win : void 0, options, path => {
|
||||
c(normalizePath(path));
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public showOpenDialog(options: Electron.OpenDialogOptions, window?: ICodeWindow): TPromise<string[]> {
|
||||
function normalizePaths(paths: string[]): string[] {
|
||||
if (paths && paths.length > 0 && isMacintosh) {
|
||||
paths = paths.map(path => normalizeNFC(path)); // normalize paths returned from the OS
|
||||
}
|
||||
|
||||
// Remember path in storage for next time
|
||||
this.stateService.setItem(FileDialog.workingDirPickerStorageKey, dirname(paths[0]));
|
||||
|
||||
// Return
|
||||
return clb(paths);
|
||||
return paths;
|
||||
}
|
||||
|
||||
return clb(void (0));
|
||||
return this.getDialogQueue(window).queue(() => {
|
||||
return new TPromise((c, e) => {
|
||||
dialog.showOpenDialog(window ? window.win : void 0, options, paths => {
|
||||
c(normalizePaths(paths));
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class WorkspacesManager {
|
||||
|
||||
constructor(
|
||||
private workspacesService: IWorkspacesMainService,
|
||||
private backupService: IBackupMainService,
|
||||
private workspacesMainService: IWorkspacesMainService,
|
||||
private backupMainService: IBackupMainService,
|
||||
private environmentService: IEnvironmentService,
|
||||
private windowsMainService: IWindowsMainService
|
||||
) {
|
||||
@@ -1690,26 +1739,33 @@ class WorkspacesManager {
|
||||
}
|
||||
|
||||
public createAndEnterWorkspace(window: CodeWindow, folders?: IWorkspaceFolderCreationData[], path?: string): TPromise<IEnterWorkspaceResult> {
|
||||
if (!window || !window.win || window.readyState !== ReadyState.READY || !this.isValidTargetWorkspacePath(window, path)) {
|
||||
if (!window || !window.win || window.readyState !== ReadyState.READY) {
|
||||
return TPromise.as(null); // return early if the window is not ready or disposed
|
||||
}
|
||||
|
||||
return this.workspacesService.createWorkspace(folders).then(workspace => {
|
||||
return this.doSaveAndOpenWorkspace(window, workspace, path);
|
||||
return this.isValidTargetWorkspacePath(window, path).then(isValid => {
|
||||
if (!isValid) {
|
||||
return TPromise.as(null); // return early if the workspace is not valid
|
||||
}
|
||||
|
||||
return this.workspacesMainService.createWorkspace(folders).then(workspace => {
|
||||
return this.doSaveAndOpenWorkspace(window, workspace, path);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private isValidTargetWorkspacePath(window: CodeWindow, path?: string): boolean {
|
||||
private isValidTargetWorkspacePath(window: CodeWindow, path?: string): TPromise<boolean> {
|
||||
if (!path) {
|
||||
return true;
|
||||
return TPromise.wrap(true);
|
||||
}
|
||||
|
||||
if (window.openedWorkspace && window.openedWorkspace.configPath === path) {
|
||||
return false; // window is already opened on a workspace with that path
|
||||
return TPromise.wrap(false); // window is already opened on a workspace with that path
|
||||
}
|
||||
|
||||
// Prevent overwriting a workspace that is currently opened in another window
|
||||
if (findWindowOnWorkspace(this.windowsMainService.getWindows(), { id: this.workspacesService.getWorkspaceId(path), configPath: path })) {
|
||||
if (findWindowOnWorkspace(this.windowsMainService.getWindows(), { id: this.workspacesMainService.getWorkspaceId(path), configPath: path })) {
|
||||
const options: Electron.MessageBoxOptions = {
|
||||
title: product.nameLong,
|
||||
type: 'info',
|
||||
@@ -1719,23 +1775,16 @@ class WorkspacesManager {
|
||||
noLink: true
|
||||
};
|
||||
|
||||
const activeWindow = BrowserWindow.getFocusedWindow();
|
||||
if (activeWindow) {
|
||||
dialog.showMessageBox(activeWindow, options);
|
||||
} else {
|
||||
dialog.showMessageBox(options);
|
||||
}
|
||||
|
||||
return false;
|
||||
return this.windowsMainService.showMessageBox(options, this.windowsMainService.getFocusedWindow()).then(() => false);
|
||||
}
|
||||
|
||||
return true; // OK
|
||||
return TPromise.wrap(true); // OK
|
||||
}
|
||||
|
||||
private doSaveAndOpenWorkspace(window: CodeWindow, workspace: IWorkspaceIdentifier, path?: string): TPromise<IEnterWorkspaceResult> {
|
||||
let savePromise: TPromise<IWorkspaceIdentifier>;
|
||||
if (path) {
|
||||
savePromise = this.workspacesService.saveWorkspace(workspace, path);
|
||||
savePromise = this.workspacesMainService.saveWorkspace(workspace, path);
|
||||
} else {
|
||||
savePromise = TPromise.as(workspace);
|
||||
}
|
||||
@@ -1746,7 +1795,7 @@ class WorkspacesManager {
|
||||
// Register window for backups and migrate current backups over
|
||||
let backupPath: string;
|
||||
if (!window.config.extensionDevelopmentPath) {
|
||||
backupPath = this.backupService.registerWorkspaceBackupSync(workspace, window.config.backupPath);
|
||||
backupPath = this.backupMainService.registerWorkspaceBackupSync(workspace, window.config.backupPath);
|
||||
}
|
||||
|
||||
// Update window configuration properly based on transition to workspace
|
||||
@@ -1776,7 +1825,7 @@ class WorkspacesManager {
|
||||
});
|
||||
}
|
||||
|
||||
public promptToSaveUntitledWorkspace(e: IWindowUnloadEvent, workspace: IWorkspaceIdentifier): void {
|
||||
public promptToSaveUntitledWorkspace(window: ICodeWindow, workspace: IWorkspaceIdentifier): TPromise<boolean> {
|
||||
enum ConfirmResult {
|
||||
SAVE,
|
||||
DONT_SAVE,
|
||||
@@ -1810,41 +1859,35 @@ class WorkspacesManager {
|
||||
options.defaultId = 2;
|
||||
}
|
||||
|
||||
const res = dialog.showMessageBox(e.window.win, options);
|
||||
return this.windowsMainService.showMessageBox(options, window).then(res => {
|
||||
switch (buttons[res.button].result) {
|
||||
|
||||
switch (buttons[res].result) {
|
||||
// Cancel: veto unload
|
||||
case ConfirmResult.CANCEL:
|
||||
return true;
|
||||
|
||||
// Cancel: veto unload
|
||||
case ConfirmResult.CANCEL:
|
||||
e.veto(true);
|
||||
break;
|
||||
// Don't Save: delete workspace
|
||||
case ConfirmResult.DONT_SAVE:
|
||||
this.workspacesMainService.deleteUntitledWorkspaceSync(workspace);
|
||||
return false;
|
||||
|
||||
// Don't Save: delete workspace
|
||||
case ConfirmResult.DONT_SAVE:
|
||||
this.workspacesService.deleteUntitledWorkspaceSync(workspace);
|
||||
e.veto(false);
|
||||
break;
|
||||
// Save: save workspace, but do not veto unload
|
||||
case ConfirmResult.SAVE: {
|
||||
return this.windowsMainService.showSaveDialog({
|
||||
buttonLabel: mnemonicButtonLabel(localize({ key: 'save', comment: ['&& denotes a mnemonic'] }, "&&Save")),
|
||||
title: localize('saveWorkspace', "Save Workspace"),
|
||||
filters: WORKSPACE_FILTER,
|
||||
defaultPath: this.getUntitledWorkspaceSaveDialogDefaultPath(workspace)
|
||||
}, window).then(target => {
|
||||
if (target) {
|
||||
return this.workspacesMainService.saveWorkspace(workspace, target).then(() => false, () => false);
|
||||
}
|
||||
|
||||
// Save: save workspace, but do not veto unload
|
||||
case ConfirmResult.SAVE: {
|
||||
let target = dialog.showSaveDialog(e.window.win, {
|
||||
buttonLabel: mnemonicButtonLabel(localize({ key: 'save', comment: ['&& denotes a mnemonic'] }, "&&Save")),
|
||||
title: localize('saveWorkspace', "Save Workspace"),
|
||||
filters: WORKSPACE_FILTER,
|
||||
defaultPath: this.getUntitledWorkspaceSaveDialogDefaultPath(workspace)
|
||||
});
|
||||
|
||||
if (target) {
|
||||
if (isMacintosh) {
|
||||
target = normalizeNFC(target); // normalize paths returned from the OS
|
||||
}
|
||||
|
||||
e.veto(this.workspacesService.saveWorkspace(workspace, target).then(() => false, () => false));
|
||||
} else {
|
||||
e.veto(true); // keep veto if no target was provided
|
||||
return true; // keep veto if no target was provided
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private getUntitledWorkspaceSaveDialogDefaultPath(workspace?: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier): string {
|
||||
@@ -1853,7 +1896,7 @@ class WorkspacesManager {
|
||||
return dirname(workspace);
|
||||
}
|
||||
|
||||
const resolvedWorkspace = this.workspacesService.resolveWorkspaceSync(workspace.configPath);
|
||||
const resolvedWorkspace = this.workspacesMainService.resolveWorkspaceSync(workspace.configPath);
|
||||
if (resolvedWorkspace && resolvedWorkspace.folders.length > 0) {
|
||||
for (const folder of resolvedWorkspace.folders) {
|
||||
if (folder.uri.scheme === Schemas.file) {
|
||||
|
||||
Reference in New Issue
Block a user