Skip to content

Commit 0add813

Browse files
committed
Show save on close messages
1 parent b407d0a commit 0add813

File tree

6 files changed

+111
-73
lines changed

6 files changed

+111
-73
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/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': {

Diff for: 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,100 @@
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(window: Electron.BrowserWindow): void {
32+
window.on('close', async event => {
33+
event.preventDefault();
34+
const result = await this.confirmShutdown(window);
35+
if (result) {
36+
window.destroy();
37+
}
38+
});
39+
}
40+
41+
private async confirmShutdown(window: Electron.BrowserWindow): Promise<boolean> {
42+
const sketch = await this.sketchServiceClient.currentSketch();
43+
if (sketch) {
44+
const isTemp = await this.sketchService.isTemp(sketch);
45+
if (isTemp) {
46+
return this.showTempSketchDialog(window);
47+
} else if (this.appShell.canSaveAll()) {
48+
const dialogResult = await remote.dialog.showMessageBox(window, {
49+
title: nls.localize('theia/core/quitTitle', 'Are you sure you want to quit?'),
50+
message: nls.localize('theia/core/quitMessage', 'Any unsaved changes will not be saved.'),
51+
buttons: [
52+
Dialog.NO,
53+
Dialog.YES
54+
]
55+
});
56+
return dialogResult.response === 1;
57+
}
58+
}
59+
return true;
60+
}
61+
62+
private async showTempSketchDialog(window: Electron.BrowserWindow): Promise<boolean> {
63+
const sketch = await this.sketchServiceClient.currentSketch();
64+
if (!sketch) {
65+
return true;
66+
}
67+
const isTemp = await this.sketchService.isTemp(sketch);
68+
if (!isTemp) {
69+
return true;
70+
}
71+
const messageBoxResult = await remote.dialog.showMessageBox(
72+
window,
73+
{
74+
message: nls.localize('arduino/sketch/saveTempSketch', 'Save your sketch to open it again later.'),
75+
title: 'Arduino-IDE',
76+
type: 'question',
77+
buttons: [
78+
Dialog.CANCEL,
79+
nls.localizeByDefault('Save As...'),
80+
nls.localizeByDefault("Don't Save"),
81+
],
82+
}
83+
)
84+
const result = messageBoxResult.response;
85+
if (result === 2) {
86+
return true;
87+
} else if (result === 1) {
88+
return !!(await this.commandRegistry.executeCommand(
89+
SaveAsSketch.Commands.SAVE_AS_SKETCH.id,
90+
{
91+
execOnlyIfTemp: false,
92+
openAfterMove: false,
93+
wipeOriginal: true
94+
}
95+
));
96+
}
97+
return false
98+
}
99+
100+
}

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

Diff for: arduino-ide-extension/src/electron-main/theia/electron-main-application.ts

+1
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
272272
}
273273
});
274274
this.attachClosedWorkspace(electronWindow);
275+
this.attachCloseListeners(electronWindow, options);
275276
this.attachReadyToShow(electronWindow);
276277
this.attachSaveWindowState(electronWindow);
277278
this.attachGlobalShortcuts(electronWindow);

0 commit comments

Comments
 (0)