|
@@ -29,6 +29,10 @@ import {
|
|
|
Widget, Title
|
|
|
} from 'phosphor-widget';
|
|
|
|
|
|
+import {
|
|
|
+ showDialog
|
|
|
+} from '../dialog';
|
|
|
+
|
|
|
import {
|
|
|
JupyterCodeMirrorWidget as CodeMirrorWidget
|
|
|
} from './widget';
|
|
@@ -235,16 +239,10 @@ abstract class AbstractFileHandler<T extends Widget> implements IMessageFilter {
|
|
|
if (!widget) {
|
|
|
return Promise.resolve(false);
|
|
|
}
|
|
|
- if (widget.hasClass(DIRTY_CLASS)) {
|
|
|
- // TODO: implement a dialog here.
|
|
|
- console.log('CLOSING DIRTY FILE');
|
|
|
- }
|
|
|
- widget.dispose();
|
|
|
- let index = this._widgets.indexOf(widget);
|
|
|
- this._widgets.splice(index, 1);
|
|
|
- if (widget === this.activeWidget) {
|
|
|
- this._activeWidget = null;
|
|
|
+ if (this.isDirty(widget)) {
|
|
|
+ return this._maybeClose(widget);
|
|
|
}
|
|
|
+ this._close(widget);
|
|
|
return Promise.resolve(true);
|
|
|
}
|
|
|
|
|
@@ -329,6 +327,24 @@ abstract class AbstractFileHandler<T extends Widget> implements IMessageFilter {
|
|
|
return model.name;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Resolve a given widget.
|
|
|
+ */
|
|
|
+ protected resolveWidget(widget: T): T {
|
|
|
+ widget = widget || this.activeWidget;
|
|
|
+ if (this._widgets.indexOf(widget) === -1) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ return widget;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Find a widget given a model.
|
|
|
+ */
|
|
|
+ protected findWidgetByModel(model: IContentsModel): T {
|
|
|
+ return arrays.find(this._widgets, widget => this._getModel(widget).path === model.path);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Get the model for a given widget.
|
|
|
*/
|
|
@@ -344,21 +360,31 @@ abstract class AbstractFileHandler<T extends Widget> implements IMessageFilter {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Resolve a given widget.
|
|
|
+ * Ask the user whether to close an unsaved file.
|
|
|
*/
|
|
|
- protected resolveWidget(widget: T): T {
|
|
|
- widget = widget || this.activeWidget;
|
|
|
- if (this._widgets.indexOf(widget) === -1) {
|
|
|
- return;
|
|
|
- }
|
|
|
- return widget;
|
|
|
+ private _maybeClose(widget: T): Promise<boolean> {
|
|
|
+ return showDialog({
|
|
|
+ title: 'Close without saving?',
|
|
|
+ body: `File "${widget.title.text}" has unsaved changes, close without saving?`
|
|
|
+ }).then(value => {
|
|
|
+ if (value.text === 'OK') {
|
|
|
+ this._close(widget);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Find a widget given a model.
|
|
|
+ * Actually close the file.
|
|
|
*/
|
|
|
- protected findWidgetByModel(model: IContentsModel): T {
|
|
|
- return arrays.find(this._widgets, widget => this._getModel(widget).path === model.path);
|
|
|
+ private _close(widget: T): void {
|
|
|
+ widget.dispose();
|
|
|
+ let index = this._widgets.indexOf(widget);
|
|
|
+ this._widgets.splice(index, 1);
|
|
|
+ if (widget === this.activeWidget) {
|
|
|
+ this._activeWidget = null;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -402,7 +428,10 @@ class FileHandler extends AbstractFileHandler<CodeMirrorWidget> {
|
|
|
*/
|
|
|
protected createWidget(model: IContentsModel): CodeMirrorWidget {
|
|
|
let widget = new CodeMirrorWidget();
|
|
|
- widget.editor.on('change', () => this.setDirty(widget));
|
|
|
+ CodeMirror.on(widget.editor.getDoc(), 'change', () => {
|
|
|
+ this.setDirty(widget);
|
|
|
+ console.log('changed')
|
|
|
+ });
|
|
|
return widget;
|
|
|
}
|
|
|
|