Skip to content

Commit 9e96731

Browse files
committed
Show save on close messages
1 parent 522a5c6 commit 9e96731

File tree

5 files changed

+122
-71
lines changed

5 files changed

+122
-71
lines changed

Diff for: 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

Diff for: arduino-ide-extension/src/browser/contributions/close.ts

+1-71
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { EditorManager } from '@theia/editor/lib/browser/editor-manager';
66
import { ApplicationShell } from '@theia/core/lib/browser/shell/application-shell';
77
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
88
import { ArduinoMenus } from '../menu/arduino-menus';
9-
import { SaveAsSketch } from './save-as-sketch';
109
import {
1110
SketchContribution,
1211
Command,
@@ -33,76 +32,7 @@ export class Close extends SketchContribution {
3332

3433
registerCommands(registry: CommandRegistry): void {
3534
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-
},
35+
execute: () => remote.getCurrentWindow().close()
10636
});
10737
}
10838

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

Diff for: arduino-ide-extension/src/browser/dialogs/ide-updater/ide-updater-dialog.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ export class IDEUpdaterDialogWidget extends ReactWidget {
8989
}
9090

9191
onCloseAndInstall(): void {
92+
this.windowService.setSafeToShutDown();
9293
this.updater.quitAndInstall();
9394
}
9495

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

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

0 commit comments

Comments
 (0)