Skip to content

Commit 84f033a

Browse files
committed
Show save on close messages
1 parent b407d0a commit 84f033a

File tree

5 files changed

+112
-73
lines changed

5 files changed

+112
-73
lines changed

arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts

+4
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ import {
275275
IDEUpdaterDialogWidget,
276276
} from './dialogs/ide-updater/ide-updater-dialog';
277277
import { ElectronIpcConnectionProvider } from '@theia/core/lib/electron-browser/messaging/electron-ipc-connection-provider';
278+
import { ShutdownRoutine } from './contributions/shutdown-routine';
278279

279280
const ElementQueries = require('css-element-queries/src/ElementQueries');
280281

@@ -300,6 +301,9 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
300301
bind(ArduinoToolbarContribution).toSelf().inSingletonScope();
301302
bind(FrontendApplicationContribution).toService(ArduinoToolbarContribution);
302303

304+
bind(ShutdownRoutine).toSelf().inSingletonScope();
305+
bind(FrontendApplicationContribution).toService(ShutdownRoutine);
306+
303307
// Renderer for both the library and the core widgets.
304308
bind(ListItemRenderer).toSelf().inSingletonScope();
305309

arduino-ide-extension/src/browser/arduino-preferences.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export const ArduinoConfigSchema: PreferenceSchema = {
8383
default: 'https://downloads.arduino.cc/arduino-ide',
8484
description: nls.localize(
8585
'arduino/preferences/ide.updateBaseUrl',
86-
`The base URL where to download updates from. Defaults to 'https://downloads.arduino.cc/arduino-ide'`
86+
"The base URL where to download updates from. Defaults to 'https://downloads.arduino.cc/arduino-ide'"
8787
),
8888
},
8989
'arduino.board.certificates': {

arduino-ide-extension/src/browser/contributions/close.ts

+1-72
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import { inject, injectable } from 'inversify';
2-
import { toArray } from '@phosphor/algorithm';
32
import * as remote from '@theia/core/electron-shared/@electron/remote';
43
import { MonacoEditor } from '@theia/monaco/lib/browser/monaco-editor';
54
import { EditorManager } from '@theia/editor/lib/browser/editor-manager';
65
import { ApplicationShell } from '@theia/core/lib/browser/shell/application-shell';
76
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
87
import { ArduinoMenus } from '../menu/arduino-menus';
9-
import { SaveAsSketch } from './save-as-sketch';
108
import {
119
SketchContribution,
1210
Command,
@@ -33,76 +31,7 @@ export class Close extends SketchContribution {
3331

3432
registerCommands(registry: CommandRegistry): void {
3533
registry.registerCommand(Close.Commands.CLOSE, {
36-
execute: async () => {
37-
// Close current editor if closeable.
38-
const { currentEditor } = this.editorManager;
39-
if (currentEditor && currentEditor.title.closable) {
40-
currentEditor.close();
41-
return;
42-
}
43-
44-
// Close current widget from the main area if possible.
45-
const { currentWidget } = this.shell;
46-
if (currentWidget) {
47-
const currentWidgetInMain = toArray(
48-
this.shell.mainPanel.widgets()
49-
).find((widget) => widget === currentWidget);
50-
if (currentWidgetInMain && currentWidgetInMain.title.closable) {
51-
return currentWidgetInMain.close();
52-
}
53-
}
54-
55-
// Close the sketch (window).
56-
const sketch = await this.sketchServiceClient.currentSketch();
57-
if (!sketch) {
58-
return;
59-
}
60-
const isTemp = await this.sketchService.isTemp(sketch);
61-
const uri = await this.sketchServiceClient.currentSketchFile();
62-
if (!uri) {
63-
return;
64-
}
65-
if (isTemp && (await this.wasTouched(uri))) {
66-
const { response } = await remote.dialog.showMessageBox({
67-
type: 'question',
68-
buttons: [
69-
nls.localize(
70-
'vscode/abstractTaskService/saveBeforeRun.dontSave',
71-
"Don't Save"
72-
),
73-
nls.localize('vscode/issueMainService/cancel', 'Cancel'),
74-
nls.localize(
75-
'vscode/abstractTaskService/saveBeforeRun.save',
76-
'Save'
77-
),
78-
],
79-
message: nls.localize(
80-
'arduino/common/saveChangesToSketch',
81-
'Do you want to save changes to this sketch before closing?'
82-
),
83-
detail: nls.localize(
84-
'arduino/common/loseChanges',
85-
"If you don't save, your changes will be lost."
86-
),
87-
});
88-
if (response === 1) {
89-
// Cancel
90-
return;
91-
}
92-
if (response === 2) {
93-
// Save
94-
const saved = await this.commandService.executeCommand(
95-
SaveAsSketch.Commands.SAVE_AS_SKETCH.id,
96-
{ openAfterMove: false, execOnlyIfTemp: true }
97-
);
98-
if (!saved) {
99-
// If it was not saved, do bail the close.
100-
return;
101-
}
102-
}
103-
}
104-
window.close();
105-
},
34+
execute: () => remote.getCurrentWindow().close()
10635
});
10736
}
10837

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import { FrontendApplicationContribution } from "@theia/core/lib/browser/frontend-application";
2+
import { inject, injectable } from "@theia/core/shared/inversify";
3+
import * as remote from '@theia/core/electron-shared/@electron/remote';
4+
import { SketchesServiceClientImpl } from "../../common/protocol/sketches-service-client-impl";
5+
import { SketchesService } from "../../common/protocol/sketches-service";
6+
import { Dialog } from "@theia/core/lib/browser/dialogs";
7+
import { nls } from "@theia/core/lib/common/nls";
8+
import { CommandRegistry } from "@theia/core/lib/common/command";
9+
import { ApplicationShell } from "@theia/core/lib/browser/shell/application-shell";
10+
import { SaveAsSketch } from "./save-as-sketch";
11+
12+
@injectable()
13+
export class ShutdownRoutine implements FrontendApplicationContribution {
14+
15+
@inject(SketchesServiceClientImpl)
16+
protected readonly sketchServiceClient: SketchesServiceClientImpl;
17+
18+
@inject(SketchesService)
19+
protected readonly sketchService: SketchesService;
20+
21+
@inject(CommandRegistry)
22+
protected readonly commandRegistry: CommandRegistry;
23+
24+
@inject(ApplicationShell)
25+
protected readonly appShell: ApplicationShell;
26+
27+
initialize(): void {
28+
this.setupShutdownRoutine(remote.getCurrentWindow());
29+
}
30+
31+
setupShutdownRoutine(electronWindow: Electron.BrowserWindow): void {
32+
window.addEventListener('beforeunload', event => {
33+
event.preventDefault();
34+
event.returnValue = false;
35+
this.confirmShutdown(electronWindow).then(result => {
36+
if (result) {
37+
electronWindow.destroy();
38+
}
39+
})
40+
});
41+
}
42+
43+
private async confirmShutdown(window: Electron.BrowserWindow): Promise<boolean> {
44+
const sketch = await this.sketchServiceClient.currentSketch();
45+
if (sketch) {
46+
const isTemp = await this.sketchService.isTemp(sketch);
47+
if (isTemp) {
48+
return this.showTempSketchDialog(window);
49+
} else if (this.appShell.canSaveAll()) {
50+
const dialogResult = await remote.dialog.showMessageBox(window, {
51+
title: nls.localize('theia/core/quitTitle', 'Are you sure you want to quit?'),
52+
message: nls.localize('theia/core/quitMessage', 'Any unsaved changes will not be saved.'),
53+
buttons: [
54+
Dialog.NO,
55+
Dialog.YES
56+
]
57+
});
58+
return dialogResult.response === 1;
59+
}
60+
}
61+
return true;
62+
}
63+
64+
private async showTempSketchDialog(window: Electron.BrowserWindow): Promise<boolean> {
65+
const sketch = await this.sketchServiceClient.currentSketch();
66+
if (!sketch) {
67+
return true;
68+
}
69+
const isTemp = await this.sketchService.isTemp(sketch);
70+
if (!isTemp) {
71+
return true;
72+
}
73+
const messageBoxResult = await remote.dialog.showMessageBox(
74+
window,
75+
{
76+
message: nls.localize('arduino/sketch/saveTempSketch', 'Save your sketch to open it again later.'),
77+
title: 'Arduino-IDE',
78+
type: 'question',
79+
buttons: [
80+
Dialog.CANCEL,
81+
nls.localizeByDefault('Save As...'),
82+
nls.localizeByDefault("Don't Save"),
83+
],
84+
}
85+
)
86+
const result = messageBoxResult.response;
87+
if (result === 2) {
88+
return true;
89+
} else if (result === 1) {
90+
return !!(await this.commandRegistry.executeCommand(
91+
SaveAsSketch.Commands.SAVE_AS_SKETCH.id,
92+
{
93+
execOnlyIfTemp: false,
94+
openAfterMove: false,
95+
wipeOriginal: true
96+
}
97+
));
98+
}
99+
return false
100+
}
101+
102+
}

arduino-ide-extension/src/electron-browser/electron-window-service.ts

+4
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,8 @@ export class ElectronWindowService extends TheiaElectronWindowService {
5555
});
5656
return response === 0; // 'Yes', close the window.
5757
}
58+
59+
protected registerUnloadListeners(): void {
60+
// NOOP
61+
}
5862
}

0 commit comments

Comments
 (0)