##// END OF EJS Templates
Make kernel dialogs be a special type of dialog
Jessica B. Hamrick -
Show More
@@ -1,163 +1,173
1 // Copyright (c) IPython Development Team.
1 // Copyright (c) IPython Development Team.
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 define([
4 define([
5 'base/js/namespace',
5 'base/js/namespace',
6 'jquery',
6 'jquery',
7 ], function(IPython, $) {
7 ], function(IPython, $) {
8 "use strict";
8 "use strict";
9
9
10 var modal = function (options) {
10 var modal = function (options) {
11
11
12 var modal = $("<div/>")
12 var modal = $("<div/>")
13 .addClass("modal")
13 .addClass("modal")
14 .addClass("fade")
14 .addClass("fade")
15 .attr("role", "dialog");
15 .attr("role", "dialog");
16 var dialog = $("<div/>")
16 var dialog = $("<div/>")
17 .addClass("modal-dialog")
17 .addClass("modal-dialog")
18 .appendTo(modal);
18 .appendTo(modal);
19 var dialog_content = $("<div/>")
19 var dialog_content = $("<div/>")
20 .addClass("modal-content")
20 .addClass("modal-content")
21 .appendTo(dialog);
21 .appendTo(dialog);
22 dialog_content.append(
22 dialog_content.append(
23 $("<div/>")
23 $("<div/>")
24 .addClass("modal-header")
24 .addClass("modal-header")
25 .append($("<button>")
25 .append($("<button>")
26 .attr("type", "button")
26 .attr("type", "button")
27 .addClass("close")
27 .addClass("close")
28 .attr("data-dismiss", "modal")
28 .attr("data-dismiss", "modal")
29 .attr("aria-hidden", "true")
29 .attr("aria-hidden", "true")
30 .html("&times;")
30 .html("&times;")
31 ).append(
31 ).append(
32 $("<h4/>")
32 $("<h4/>")
33 .addClass('modal-title')
33 .addClass('modal-title')
34 .text(options.title || "")
34 .text(options.title || "")
35 )
35 )
36 ).append(
36 ).append(
37 $("<div/>").addClass("modal-body").append(
37 $("<div/>").addClass("modal-body").append(
38 options.body || $("<p/>")
38 options.body || $("<p/>")
39 )
39 )
40 );
40 );
41
41
42 var footer = $("<div/>").addClass("modal-footer");
42 var footer = $("<div/>").addClass("modal-footer");
43
43
44 for (var label in options.buttons) {
44 for (var label in options.buttons) {
45 var btn_opts = options.buttons[label];
45 var btn_opts = options.buttons[label];
46 var button = $("<button/>")
46 var button = $("<button/>")
47 .addClass("btn btn-default btn-sm")
47 .addClass("btn btn-default btn-sm")
48 .attr("data-dismiss", "modal")
48 .attr("data-dismiss", "modal")
49 .text(label);
49 .text(label);
50 if (btn_opts.click) {
50 if (btn_opts.click) {
51 button.click($.proxy(btn_opts.click, dialog_content));
51 button.click($.proxy(btn_opts.click, dialog_content));
52 }
52 }
53 if (btn_opts.class) {
53 if (btn_opts.class) {
54 button.addClass(btn_opts.class);
54 button.addClass(btn_opts.class);
55 }
55 }
56 footer.append(button);
56 footer.append(button);
57 }
57 }
58 dialog_content.append(footer);
58 dialog_content.append(footer);
59 // hook up on-open event
59 // hook up on-open event
60 modal.on("shown.bs.modal", function() {
60 modal.on("shown.bs.modal", function() {
61 setTimeout(function() {
61 setTimeout(function() {
62 footer.find("button").last().focus();
62 footer.find("button").last().focus();
63 if (options.open) {
63 if (options.open) {
64 $.proxy(options.open, modal)();
64 $.proxy(options.open, modal)();
65 }
65 }
66 }, 0);
66 }, 0);
67 });
67 });
68
68
69 // destroy modal on hide, unless explicitly asked not to
69 // destroy modal on hide, unless explicitly asked not to
70 if (options.destroy === undefined || options.destroy) {
70 if (options.destroy === undefined || options.destroy) {
71 modal.on("hidden.bs.modal", function () {
71 modal.on("hidden.bs.modal", function () {
72 modal.remove();
72 modal.remove();
73 });
73 });
74 }
74 }
75 modal.on("hidden.bs.modal", function () {
75 modal.on("hidden.bs.modal", function () {
76 if (options.notebook) {
76 if (options.notebook) {
77 var cell = options.notebook.get_selected_cell();
77 var cell = options.notebook.get_selected_cell();
78 if (cell) cell.select();
78 if (cell) cell.select();
79 }
79 }
80 if (options.keyboard_manager) {
80 if (options.keyboard_manager) {
81 options.keyboard_manager.enable();
81 options.keyboard_manager.enable();
82 options.keyboard_manager.command_mode();
82 options.keyboard_manager.command_mode();
83 }
83 }
84 });
84 });
85
85
86 if (options.keyboard_manager) {
86 if (options.keyboard_manager) {
87 options.keyboard_manager.disable();
87 options.keyboard_manager.disable();
88 }
88 }
89
89
90 return modal.modal(options);
90 return modal.modal(options);
91 };
91 };
92
92
93 var kernel_modal = function (options) {
94 // only one kernel dialog should be open at a time -- but
95 // other modal dialogs can still be open
96 $('.kernel-modal').modal('hide');
97 var dialog = modal(options);
98 dialog.addClass('kernel-modal');
99 return dialog;
100 };
101
93 var edit_metadata = function (options) {
102 var edit_metadata = function (options) {
94 options.name = options.name || "Cell";
103 options.name = options.name || "Cell";
95 var error_div = $('<div/>').css('color', 'red');
104 var error_div = $('<div/>').css('color', 'red');
96 var message =
105 var message =
97 "Manually edit the JSON below to manipulate the metadata for this " + options.name + "." +
106 "Manually edit the JSON below to manipulate the metadata for this " + options.name + "." +
98 " We recommend putting custom metadata attributes in an appropriately named sub-structure," +
107 " We recommend putting custom metadata attributes in an appropriately named sub-structure," +
99 " so they don't conflict with those of others.";
108 " so they don't conflict with those of others.";
100
109
101 var textarea = $('<textarea/>')
110 var textarea = $('<textarea/>')
102 .attr('rows', '13')
111 .attr('rows', '13')
103 .attr('cols', '80')
112 .attr('cols', '80')
104 .attr('name', 'metadata')
113 .attr('name', 'metadata')
105 .text(JSON.stringify(options.md || {}, null, 2));
114 .text(JSON.stringify(options.md || {}, null, 2));
106
115
107 var dialogform = $('<div/>').attr('title', 'Edit the metadata')
116 var dialogform = $('<div/>').attr('title', 'Edit the metadata')
108 .append(
117 .append(
109 $('<form/>').append(
118 $('<form/>').append(
110 $('<fieldset/>').append(
119 $('<fieldset/>').append(
111 $('<label/>')
120 $('<label/>')
112 .attr('for','metadata')
121 .attr('for','metadata')
113 .text(message)
122 .text(message)
114 )
123 )
115 .append(error_div)
124 .append(error_div)
116 .append($('<br/>'))
125 .append($('<br/>'))
117 .append(textarea)
126 .append(textarea)
118 )
127 )
119 );
128 );
120 var editor = CodeMirror.fromTextArea(textarea[0], {
129 var editor = CodeMirror.fromTextArea(textarea[0], {
121 lineNumbers: true,
130 lineNumbers: true,
122 matchBrackets: true,
131 matchBrackets: true,
123 indentUnit: 2,
132 indentUnit: 2,
124 autoIndent: true,
133 autoIndent: true,
125 mode: 'application/json',
134 mode: 'application/json',
126 });
135 });
127 var modal_obj = modal({
136 var modal_obj = modal({
128 title: "Edit " + options.name + " Metadata",
137 title: "Edit " + options.name + " Metadata",
129 body: dialogform,
138 body: dialogform,
130 buttons: {
139 buttons: {
131 OK: { class : "btn-primary",
140 OK: { class : "btn-primary",
132 click: function() {
141 click: function() {
133 // validate json and set it
142 // validate json and set it
134 var new_md;
143 var new_md;
135 try {
144 try {
136 new_md = JSON.parse(editor.getValue());
145 new_md = JSON.parse(editor.getValue());
137 } catch(e) {
146 } catch(e) {
138 console.log(e);
147 console.log(e);
139 error_div.text('WARNING: Could not save invalid JSON.');
148 error_div.text('WARNING: Could not save invalid JSON.');
140 return false;
149 return false;
141 }
150 }
142 options.callback(new_md);
151 options.callback(new_md);
143 }
152 }
144 },
153 },
145 Cancel: {}
154 Cancel: {}
146 },
155 },
147 notebook: options.notebook,
156 notebook: options.notebook,
148 keyboard_manager: options.keyboard_manager,
157 keyboard_manager: options.keyboard_manager,
149 });
158 });
150
159
151 modal_obj.on('shown.bs.modal', function(){ editor.refresh(); });
160 modal_obj.on('shown.bs.modal', function(){ editor.refresh(); });
152 };
161 };
153
162
154 var dialog = {
163 var dialog = {
155 modal : modal,
164 modal : modal,
165 kernel_modal : kernel_modal,
156 edit_metadata : edit_metadata,
166 edit_metadata : edit_metadata,
157 };
167 };
158
168
159 // Backwards compatability.
169 // Backwards compatability.
160 IPython.dialog = dialog;
170 IPython.dialog = dialog;
161
171
162 return dialog;
172 return dialog;
163 });
173 });
@@ -1,387 +1,377
1 // Copyright (c) IPython Development Team.
1 // Copyright (c) IPython Development Team.
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 define([
4 define([
5 'base/js/namespace',
5 'base/js/namespace',
6 'jquery',
6 'jquery',
7 'base/js/utils',
7 'base/js/utils',
8 'base/js/dialog',
8 'base/js/dialog',
9 'notebook/js/notificationwidget',
9 'notebook/js/notificationwidget',
10 'moment'
10 'moment'
11 ], function(IPython, $, utils, dialog, notificationwidget, moment) {
11 ], function(IPython, $, utils, dialog, notificationwidget, moment) {
12 "use strict";
12 "use strict";
13
13
14 // store reference to the NotificationWidget class
14 // store reference to the NotificationWidget class
15 var NotificationWidget = notificationwidget.NotificationWidget;
15 var NotificationWidget = notificationwidget.NotificationWidget;
16
16
17 /**
17 /**
18 * Construct the NotificationArea object. Options are:
18 * Construct the NotificationArea object. Options are:
19 * events: $(Events) instance
19 * events: $(Events) instance
20 * save_widget: SaveWidget instance
20 * save_widget: SaveWidget instance
21 * notebook: Notebook instance
21 * notebook: Notebook instance
22 * keyboard_manager: KeyboardManager instance
22 * keyboard_manager: KeyboardManager instance
23 *
23 *
24 * @constructor
24 * @constructor
25 * @param {string} selector - a jQuery selector string for the
25 * @param {string} selector - a jQuery selector string for the
26 * notification area element
26 * notification area element
27 * @param {Object} [options] - a dictionary of keyword arguments.
27 * @param {Object} [options] - a dictionary of keyword arguments.
28 */
28 */
29 var NotificationArea = function (selector, options) {
29 var NotificationArea = function (selector, options) {
30 this.selector = selector;
30 this.selector = selector;
31 this.events = options.events;
31 this.events = options.events;
32 this.save_widget = options.save_widget;
32 this.save_widget = options.save_widget;
33 this.notebook = options.notebook;
33 this.notebook = options.notebook;
34 this.keyboard_manager = options.keyboard_manager;
34 this.keyboard_manager = options.keyboard_manager;
35 if (this.selector !== undefined) {
35 if (this.selector !== undefined) {
36 this.element = $(selector);
36 this.element = $(selector);
37 }
37 }
38 this.widget_dict = {};
38 this.widget_dict = {};
39 };
39 };
40
40
41 /**
41 /**
42 * Get a widget by name, creating it if it doesn't exist.
42 * Get a widget by name, creating it if it doesn't exist.
43 *
43 *
44 * @method widget
44 * @method widget
45 * @param {string} name - the widget name
45 * @param {string} name - the widget name
46 */
46 */
47 NotificationArea.prototype.widget = function (name) {
47 NotificationArea.prototype.widget = function (name) {
48 if (this.widget_dict[name] === undefined) {
48 if (this.widget_dict[name] === undefined) {
49 return this.new_notification_widget(name);
49 return this.new_notification_widget(name);
50 }
50 }
51 return this.get_widget(name);
51 return this.get_widget(name);
52 };
52 };
53
53
54 /**
54 /**
55 * Get a widget by name, throwing an error if it doesn't exist.
55 * Get a widget by name, throwing an error if it doesn't exist.
56 *
56 *
57 * @method get_widget
57 * @method get_widget
58 * @param {string} name - the widget name
58 * @param {string} name - the widget name
59 */
59 */
60 NotificationArea.prototype.get_widget = function (name) {
60 NotificationArea.prototype.get_widget = function (name) {
61 if(this.widget_dict[name] === undefined) {
61 if(this.widget_dict[name] === undefined) {
62 throw('no widgets with this name');
62 throw('no widgets with this name');
63 }
63 }
64 return this.widget_dict[name];
64 return this.widget_dict[name];
65 };
65 };
66
66
67 /**
67 /**
68 * Create a new notification widget with the given name. The
68 * Create a new notification widget with the given name. The
69 * widget must not already exist.
69 * widget must not already exist.
70 *
70 *
71 * @method new_notification_widget
71 * @method new_notification_widget
72 * @param {string} name - the widget name
72 * @param {string} name - the widget name
73 */
73 */
74 NotificationArea.prototype.new_notification_widget = function (name) {
74 NotificationArea.prototype.new_notification_widget = function (name) {
75 if (this.widget_dict[name] !== undefined) {
75 if (this.widget_dict[name] !== undefined) {
76 throw('widget with that name already exists!');
76 throw('widget with that name already exists!');
77 }
77 }
78
78
79 // create the element for the notification widget and add it
79 // create the element for the notification widget and add it
80 // to the notification aread element
80 // to the notification aread element
81 var div = $('<div/>').attr('id', 'notification_' + name);
81 var div = $('<div/>').attr('id', 'notification_' + name);
82 $(this.selector).append(div);
82 $(this.selector).append(div);
83
83
84 // create the widget object and return it
84 // create the widget object and return it
85 this.widget_dict[name] = new NotificationWidget('#notification_' + name);
85 this.widget_dict[name] = new NotificationWidget('#notification_' + name);
86 return this.widget_dict[name];
86 return this.widget_dict[name];
87 };
87 };
88
88
89 /**
89 /**
90 * Initialize the default set of notification widgets.
90 * Initialize the default set of notification widgets.
91 *
91 *
92 * @method init_notification_widgets
92 * @method init_notification_widgets
93 */
93 */
94 NotificationArea.prototype.init_notification_widgets = function () {
94 NotificationArea.prototype.init_notification_widgets = function () {
95 this.init_kernel_notification_widget();
95 this.init_kernel_notification_widget();
96 this.init_notebook_notification_widget();
96 this.init_notebook_notification_widget();
97 };
97 };
98
98
99 /**
99 /**
100 * Initialize the notification widget for kernel status messages.
100 * Initialize the notification widget for kernel status messages.
101 *
101 *
102 * @method init_kernel_notification_widget
102 * @method init_kernel_notification_widget
103 */
103 */
104 NotificationArea.prototype.init_kernel_notification_widget = function () {
104 NotificationArea.prototype.init_kernel_notification_widget = function () {
105 var that = this;
105 var that = this;
106 var knw = this.new_notification_widget('kernel');
106 var knw = this.new_notification_widget('kernel');
107 var $kernel_ind_icon = $("#kernel_indicator_icon");
107 var $kernel_ind_icon = $("#kernel_indicator_icon");
108 var $modal_ind_icon = $("#modal_indicator_icon");
108 var $modal_ind_icon = $("#modal_indicator_icon");
109
109
110 // Command/Edit mode
110 // Command/Edit mode
111 this.events.on('edit_mode.Notebook', function () {
111 this.events.on('edit_mode.Notebook', function () {
112 that.save_widget.update_document_title();
112 that.save_widget.update_document_title();
113 $modal_ind_icon.attr('class','edit_mode_icon').attr('title','Edit Mode');
113 $modal_ind_icon.attr('class','edit_mode_icon').attr('title','Edit Mode');
114 });
114 });
115
115
116 this.events.on('command_mode.Notebook', function () {
116 this.events.on('command_mode.Notebook', function () {
117 that.save_widget.update_document_title();
117 that.save_widget.update_document_title();
118 $modal_ind_icon.attr('class','command_mode_icon').attr('title','Command Mode');
118 $modal_ind_icon.attr('class','command_mode_icon').attr('title','Command Mode');
119 });
119 });
120
120
121 // Implicitly start off in Command mode, switching to Edit mode will trigger event
121 // Implicitly start off in Command mode, switching to Edit mode will trigger event
122 $modal_ind_icon.attr('class','command_mode_icon').attr('title','Command Mode');
122 $modal_ind_icon.attr('class','command_mode_icon').attr('title','Command Mode');
123
123
124 // Kernel events
124 // Kernel events
125
125
126 // this can be either kernel_created.Kernel or kernel_created.Session
126 // this can be either kernel_created.Kernel or kernel_created.Session
127 this.events.on('kernel_created.Kernel kernel_created.Session', function () {
127 this.events.on('kernel_created.Kernel kernel_created.Session', function () {
128 knw.info("Kernel Created", 500);
128 knw.info("Kernel Created", 500);
129 });
129 });
130
130
131 this.events.on('status_reconnecting.Kernel', function () {
131 this.events.on('status_reconnecting.Kernel', function () {
132 knw.warning("Connecting to kernel");
132 knw.warning("Connecting to kernel");
133 });
133 });
134
134
135 this.events.on('status_connected.Kernel', function () {
135 this.events.on('status_connected.Kernel', function () {
136 knw.info("Connected", 500);
136 knw.info("Connected", 500);
137 });
137 });
138
138
139 this.events.on('status_restarting.Kernel', function () {
139 this.events.on('status_restarting.Kernel', function () {
140 that.save_widget.update_document_title();
140 that.save_widget.update_document_title();
141 knw.set_message("Restarting kernel", 2000);
141 knw.set_message("Restarting kernel", 2000);
142 });
142 });
143
143
144 this.events.on('status_autorestarting.Kernel', function (evt, info) {
144 this.events.on('status_autorestarting.Kernel', function (evt, info) {
145 // Only show the dialog on the first restart attempt. This
145 // Only show the dialog on the first restart attempt. This
146 // number gets tracked by the `Kernel` object and passed
146 // number gets tracked by the `Kernel` object and passed
147 // along here, because we don't want to show the user 5
147 // along here, because we don't want to show the user 5
148 // dialogs saying the same thing (which is the number of
148 // dialogs saying the same thing (which is the number of
149 // times it tries restarting).
149 // times it tries restarting).
150 if (info.attempt === 1) {
150 if (info.attempt === 1) {
151
151
152 // hide existing modal dialog
152 dialog.kernel_modal({
153 $(".modal").modal('hide');
154
155 dialog.modal({
156 notebook: that.notebook,
153 notebook: that.notebook,
157 keyboard_manager: that.keyboard_manager,
154 keyboard_manager: that.keyboard_manager,
158 title: "Kernel Restarting",
155 title: "Kernel Restarting",
159 body: "The kernel appears to have died. It will restart automatically.",
156 body: "The kernel appears to have died. It will restart automatically.",
160 buttons: {
157 buttons: {
161 OK : {
158 OK : {
162 class : "btn-primary"
159 class : "btn-primary"
163 }
160 }
164 }
161 }
165 });
162 });
166 };
163 };
167
164
168 that.save_widget.update_document_title();
165 that.save_widget.update_document_title();
169 knw.danger("Dead kernel");
166 knw.danger("Dead kernel");
170 $kernel_ind_icon.attr('class','kernel_dead_icon').attr('title','Kernel Dead');
167 $kernel_ind_icon.attr('class','kernel_dead_icon').attr('title','Kernel Dead');
171 });
168 });
172
169
173 this.events.on('status_interrupting.Kernel', function () {
170 this.events.on('status_interrupting.Kernel', function () {
174 knw.set_message("Interrupting kernel", 2000);
171 knw.set_message("Interrupting kernel", 2000);
175 });
172 });
176
173
177 this.events.on('status_disconnected.Kernel', function () {
174 this.events.on('status_disconnected.Kernel', function () {
178 $kernel_ind_icon
175 $kernel_ind_icon
179 .attr('class', 'kernel_disconnected_icon')
176 .attr('class', 'kernel_disconnected_icon')
180 .attr('title', 'No Connection to Kernel');
177 .attr('title', 'No Connection to Kernel');
181 });
178 });
182
179
183 this.events.on('connection_failed.Kernel', function (evt, info) {
180 this.events.on('connection_failed.Kernel', function (evt, info) {
184 // only show the dialog if this is the first failed
181 // only show the dialog if this is the first failed
185 // connect attempt, because the kernel will continue
182 // connect attempt, because the kernel will continue
186 // trying to reconnect and we don't want to spam the user
183 // trying to reconnect and we don't want to spam the user
187 // with messages
184 // with messages
188 if (info.attempt === 1) {
185 if (info.attempt === 1) {
189 // hide existing dialog
190 $(".modal").modal('hide');
191
186
192 var msg = "A connection to the notebook server could not be established." +
187 var msg = "A connection to the notebook server could not be established." +
193 " The notebook will continue trying to reconnect, but" +
188 " The notebook will continue trying to reconnect, but" +
194 " until it does, you will NOT be able to run code. Check your" +
189 " until it does, you will NOT be able to run code. Check your" +
195 " network connection or notebook server configuration.";
190 " network connection or notebook server configuration.";
196
191
197 dialog.modal({
192 dialog.kernel_modal({
198 title: "Connection failed",
193 title: "Connection failed",
199 body: msg,
194 body: msg,
200 keyboard_manager: that.keyboard_manager,
195 keyboard_manager: that.keyboard_manager,
201 notebook: that.notebook,
196 notebook: that.notebook,
202 buttons : {
197 buttons : {
203 "OK": {}
198 "OK": {}
204 }
199 }
205 });
200 });
206 }
201 }
207 });
202 });
208
203
209 this.events.on('status_killed.Kernel status_killed.Session', function () {
204 this.events.on('status_killed.Kernel status_killed.Session', function () {
210 that.save_widget.update_document_title();
205 that.save_widget.update_document_title();
211 knw.danger("Dead kernel");
206 knw.danger("Dead kernel");
212 $kernel_ind_icon.attr('class','kernel_dead_icon').attr('title','Kernel Dead');
207 $kernel_ind_icon.attr('class','kernel_dead_icon').attr('title','Kernel Dead');
213 });
208 });
214
209
215 this.events.on('kernel_dead.Kernel', function () {
210 this.events.on('kernel_dead.Kernel', function () {
216
211
217 var showMsg = function () {
212 var showMsg = function () {
218 // hide existing dialog
219 $(".modal").modal('hide');
220
213
221 var msg = 'The kernel has died, and the automatic restart has failed.' +
214 var msg = 'The kernel has died, and the automatic restart has failed.' +
222 ' It is possible the kernel cannot be restarted.' +
215 ' It is possible the kernel cannot be restarted.' +
223 ' If you are not able to restart the kernel, you will still be able to save' +
216 ' If you are not able to restart the kernel, you will still be able to save' +
224 ' the notebook, but running code will no longer work until the notebook' +
217 ' the notebook, but running code will no longer work until the notebook' +
225 ' is reopened.';
218 ' is reopened.';
226
219
227 dialog.modal({
220 dialog.kernel_modal({
228 title: "Dead kernel",
221 title: "Dead kernel",
229 body : msg,
222 body : msg,
230 keyboard_manager: that.keyboard_manager,
223 keyboard_manager: that.keyboard_manager,
231 notebook: that.notebook,
224 notebook: that.notebook,
232 buttons : {
225 buttons : {
233 "Manual Restart": {
226 "Manual Restart": {
234 class: "btn-danger",
227 class: "btn-danger",
235 click: function () {
228 click: function () {
236 that.notebook.start_session();
229 that.notebook.start_session();
237 }
230 }
238 },
231 },
239 "Don't restart": {}
232 "Don't restart": {}
240 }
233 }
241 });
234 });
242
235
243 return false;
236 return false;
244 };
237 };
245
238
246 that.save_widget.update_document_title();
239 that.save_widget.update_document_title();
247 knw.danger("Dead kernel", undefined, showMsg);
240 knw.danger("Dead kernel", undefined, showMsg);
248 $kernel_ind_icon.attr('class','kernel_dead_icon').attr('title','Kernel Dead');
241 $kernel_ind_icon.attr('class','kernel_dead_icon').attr('title','Kernel Dead');
249
242
250 showMsg();
243 showMsg();
251 });
244 });
252
245
253 this.events.on('kernel_dead.Session', function (evt, info) {
246 this.events.on('kernel_dead.Session', function (evt, info) {
254 var full = info.xhr.responseJSON.message;
247 var full = info.xhr.responseJSON.message;
255 var short = info.xhr.responseJSON.short_message || 'Kernel error';
248 var short = info.xhr.responseJSON.short_message || 'Kernel error';
256 var traceback = info.xhr.responseJSON.traceback;
249 var traceback = info.xhr.responseJSON.traceback;
257
250
258 var showMsg = function () {
251 var showMsg = function () {
259 var msg = $('<div/>').append($('<p/>').text(full));
252 var msg = $('<div/>').append($('<p/>').text(full));
260 var cm, cm_elem, cm_open;
253 var cm, cm_elem, cm_open;
261
254
262 if (traceback) {
255 if (traceback) {
263 cm_elem = $('<div/>')
256 cm_elem = $('<div/>')
264 .css('margin-top', '1em')
257 .css('margin-top', '1em')
265 .css('padding', '1em')
258 .css('padding', '1em')
266 .addClass('output_scroll');
259 .addClass('output_scroll');
267 msg.append(cm_elem);
260 msg.append(cm_elem);
268 cm = CodeMirror(cm_elem.get(0), {
261 cm = CodeMirror(cm_elem.get(0), {
269 mode: "python",
262 mode: "python",
270 readOnly : true
263 readOnly : true
271 });
264 });
272 cm.setValue(traceback);
265 cm.setValue(traceback);
273 cm_open = $.proxy(cm.refresh, cm);
266 cm_open = $.proxy(cm.refresh, cm);
274 }
267 }
275
268
276 // hide existing modal dialog
269 dialog.kernel_modal({
277 $(".modal").modal('hide');
278
279 dialog.modal({
280 title: "Failed to start the kernel",
270 title: "Failed to start the kernel",
281 body : msg,
271 body : msg,
282 keyboard_manager: that.keyboard_manager,
272 keyboard_manager: that.keyboard_manager,
283 notebook: that.notebook,
273 notebook: that.notebook,
284 open: cm_open,
274 open: cm_open,
285 buttons : {
275 buttons : {
286 "Ok": { class: 'btn-primary' }
276 "Ok": { class: 'btn-primary' }
287 }
277 }
288 });
278 });
289
279
290 return false;
280 return false;
291 };
281 };
292
282
293 that.save_widget.update_document_title();
283 that.save_widget.update_document_title();
294 $kernel_ind_icon.attr('class','kernel_dead_icon').attr('title','Kernel Dead');
284 $kernel_ind_icon.attr('class','kernel_dead_icon').attr('title','Kernel Dead');
295 knw.danger(short, undefined, showMsg);
285 knw.danger(short, undefined, showMsg);
296 });
286 });
297
287
298 this.events.on('status_starting.Kernel', function () {
288 this.events.on('status_starting.Kernel', function () {
299 window.document.title='(Starting) '+window.document.title;
289 window.document.title='(Starting) '+window.document.title;
300 $kernel_ind_icon.attr('class','kernel_busy_icon').attr('title','Kernel Busy');
290 $kernel_ind_icon.attr('class','kernel_busy_icon').attr('title','Kernel Busy');
301 knw.set_message("Kernel starting, please wait...");
291 knw.set_message("Kernel starting, please wait...");
302 });
292 });
303
293
304 this.events.on('status_ready.Kernel', function () {
294 this.events.on('status_ready.Kernel', function () {
305 that.save_widget.update_document_title();
295 that.save_widget.update_document_title();
306 $kernel_ind_icon.attr('class','kernel_idle_icon').attr('title','Kernel Idle');
296 $kernel_ind_icon.attr('class','kernel_idle_icon').attr('title','Kernel Idle');
307 knw.info("Kernel ready", 500);
297 knw.info("Kernel ready", 500);
308 });
298 });
309
299
310 this.events.on('status_idle.Kernel', function () {
300 this.events.on('status_idle.Kernel', function () {
311 that.save_widget.update_document_title();
301 that.save_widget.update_document_title();
312 $kernel_ind_icon.attr('class','kernel_idle_icon').attr('title','Kernel Idle');
302 $kernel_ind_icon.attr('class','kernel_idle_icon').attr('title','Kernel Idle');
313 });
303 });
314
304
315 this.events.on('status_busy.Kernel', function () {
305 this.events.on('status_busy.Kernel', function () {
316 window.document.title='(Busy) '+window.document.title;
306 window.document.title='(Busy) '+window.document.title;
317 $kernel_ind_icon.attr('class','kernel_busy_icon').attr('title','Kernel Busy');
307 $kernel_ind_icon.attr('class','kernel_busy_icon').attr('title','Kernel Busy');
318 });
308 });
319
309
320 // Start the kernel indicator in the busy state, and send a kernel_info request.
310 // Start the kernel indicator in the busy state, and send a kernel_info request.
321 // When the kernel_info reply arrives, the kernel is idle.
311 // When the kernel_info reply arrives, the kernel is idle.
322 $kernel_ind_icon.attr('class','kernel_busy_icon').attr('title','Kernel Busy');
312 $kernel_ind_icon.attr('class','kernel_busy_icon').attr('title','Kernel Busy');
323 };
313 };
324
314
325 /**
315 /**
326 * Initialize the notification widget for notebook status messages.
316 * Initialize the notification widget for notebook status messages.
327 *
317 *
328 * @method init_notebook_notification_widget
318 * @method init_notebook_notification_widget
329 */
319 */
330 NotificationArea.prototype.init_notebook_notification_widget = function () {
320 NotificationArea.prototype.init_notebook_notification_widget = function () {
331 var nnw = this.new_notification_widget('notebook');
321 var nnw = this.new_notification_widget('notebook');
332
322
333 // Notebook events
323 // Notebook events
334 this.events.on('notebook_loading.Notebook', function () {
324 this.events.on('notebook_loading.Notebook', function () {
335 nnw.set_message("Loading notebook",500);
325 nnw.set_message("Loading notebook",500);
336 });
326 });
337 this.events.on('notebook_loaded.Notebook', function () {
327 this.events.on('notebook_loaded.Notebook', function () {
338 nnw.set_message("Notebook loaded",500);
328 nnw.set_message("Notebook loaded",500);
339 });
329 });
340 this.events.on('notebook_saving.Notebook', function () {
330 this.events.on('notebook_saving.Notebook', function () {
341 nnw.set_message("Saving notebook",500);
331 nnw.set_message("Saving notebook",500);
342 });
332 });
343 this.events.on('notebook_saved.Notebook', function () {
333 this.events.on('notebook_saved.Notebook', function () {
344 nnw.set_message("Notebook saved",2000);
334 nnw.set_message("Notebook saved",2000);
345 });
335 });
346 this.events.on('notebook_save_failed.Notebook', function (evt, xhr, status, data) {
336 this.events.on('notebook_save_failed.Notebook', function (evt, xhr, status, data) {
347 nnw.warning(data || "Notebook save failed");
337 nnw.warning(data || "Notebook save failed");
348 });
338 });
349
339
350 // Checkpoint events
340 // Checkpoint events
351 this.events.on('checkpoint_created.Notebook', function (evt, data) {
341 this.events.on('checkpoint_created.Notebook', function (evt, data) {
352 var msg = "Checkpoint created";
342 var msg = "Checkpoint created";
353 if (data.last_modified) {
343 if (data.last_modified) {
354 var d = new Date(data.last_modified);
344 var d = new Date(data.last_modified);
355 msg = msg + ": " + moment(d).format("HH:mm:ss");
345 msg = msg + ": " + moment(d).format("HH:mm:ss");
356 }
346 }
357 nnw.set_message(msg, 2000);
347 nnw.set_message(msg, 2000);
358 });
348 });
359 this.events.on('checkpoint_failed.Notebook', function () {
349 this.events.on('checkpoint_failed.Notebook', function () {
360 nnw.warning("Checkpoint failed");
350 nnw.warning("Checkpoint failed");
361 });
351 });
362 this.events.on('checkpoint_deleted.Notebook', function () {
352 this.events.on('checkpoint_deleted.Notebook', function () {
363 nnw.set_message("Checkpoint deleted", 500);
353 nnw.set_message("Checkpoint deleted", 500);
364 });
354 });
365 this.events.on('checkpoint_delete_failed.Notebook', function () {
355 this.events.on('checkpoint_delete_failed.Notebook', function () {
366 nnw.warning("Checkpoint delete failed");
356 nnw.warning("Checkpoint delete failed");
367 });
357 });
368 this.events.on('checkpoint_restoring.Notebook', function () {
358 this.events.on('checkpoint_restoring.Notebook', function () {
369 nnw.set_message("Restoring to checkpoint...", 500);
359 nnw.set_message("Restoring to checkpoint...", 500);
370 });
360 });
371 this.events.on('checkpoint_restore_failed.Notebook', function () {
361 this.events.on('checkpoint_restore_failed.Notebook', function () {
372 nnw.warning("Checkpoint restore failed");
362 nnw.warning("Checkpoint restore failed");
373 });
363 });
374
364
375 // Autosave events
365 // Autosave events
376 this.events.on('autosave_disabled.Notebook', function () {
366 this.events.on('autosave_disabled.Notebook', function () {
377 nnw.set_message("Autosave disabled", 2000);
367 nnw.set_message("Autosave disabled", 2000);
378 });
368 });
379 this.events.on('autosave_enabled.Notebook', function (evt, interval) {
369 this.events.on('autosave_enabled.Notebook', function (evt, interval) {
380 nnw.set_message("Saving every " + interval / 1000 + "s", 1000);
370 nnw.set_message("Saving every " + interval / 1000 + "s", 1000);
381 });
371 });
382 };
372 };
383
373
384 IPython.NotificationArea = NotificationArea;
374 IPython.NotificationArea = NotificationArea;
385
375
386 return {'NotificationArea': NotificationArea};
376 return {'NotificationArea': NotificationArea};
387 });
377 });
General Comments 0
You need to be logged in to leave comments. Login now