##// END OF EJS Templates
cleanup some closing logic...
MinRK -
Show More
@@ -35,7 +35,7 b' class MainWindow(QtGui.QMainWindow):'
35 35 # 'object' interface
36 36 #---------------------------------------------------------------------------
37 37
38 def __init__(self, app, frontend, existing=False, may_close=True,
38 def __init__(self, app,
39 39 confirm_exit=True,
40 40 new_frontend_factory=None, slave_frontend_factory=None,
41 41 ):
@@ -45,13 +45,6 b' class MainWindow(QtGui.QMainWindow):'
45 45 ----------
46 46
47 47 app : reference to QApplication parent
48 frontend : IPythonWidget
49 The first IPython frontend to start with
50 existing : bool, optional
51 Whether the first frontend is connected to en existing Kernel,
52 or if we own it.
53 may_close : bool, optional
54 Whether we are permitted to close the kernel (determines close dialog behavior)
55 48 confirm_exit : bool, optional
56 49 Whether we should prompt on close of tabs
57 50 new_frontend_factory : callable
@@ -64,6 +57,7 b' class MainWindow(QtGui.QMainWindow):'
64 57
65 58 super(MainWindow, self).__init__()
66 59 self._app = app
60 self.confirm_exit = confirm_exit
67 61 self.new_frontend_factory = new_frontend_factory
68 62 self.slave_frontend_factory = slave_frontend_factory
69 63
@@ -73,7 +67,7 b' class MainWindow(QtGui.QMainWindow):'
73 67 self.tab_widget.tabCloseRequested[int].connect(self.close_tab)
74 68
75 69 self.setCentralWidget(self.tab_widget)
76 self.update_tab_bar_visibility()
70 self.tab_widget.tabBar().setVisible(False)
77 71
78 72 def update_tab_bar_visibility(self):
79 73 """ update visibility of the tabBar depending of the number of tab
@@ -135,16 +129,16 b' class MainWindow(QtGui.QMainWindow):'
135 129 if closing_widget==None:
136 130 return
137 131
138 #get a list of all wwidget not owning the kernel.
139 slave_tabs=self.find_slaves_tabs(closing_widget)
132 #get a list of all slave widgets on the same kernel.
133 slave_tabs = self.find_slave_widgets(closing_widget)
140 134
141 135 keepkernel = None #Use the prompt by default
142 136 if hasattr(closing_widget,'_keep_kernel_on_exit'): #set by exit magic
143 137 keepkernel = closing_widget._keep_kernel_on_exit
144 # If signal sent by exist magic (_keep_kernel_on_exit, exist and not None)
145 # we set local slave tabs._hidden to True to avoit prompting for kernel
146 # restart when they litt get the signal. and the "forward" the 'exit'
147 # to the main win
138 # If signal sent by exit magic (_keep_kernel_on_exit, exist and not None)
139 # we set local slave tabs._hidden to True to avoid prompting for kernel
140 # restart when they get the signal. and then "forward" the 'exit'
141 # to the main window
148 142 if keepkernel is not None:
149 143 for tab in slave_tabs:
150 144 tab._hidden = True
@@ -154,6 +148,7 b' class MainWindow(QtGui.QMainWindow):'
154 148 except AttributeError:
155 149 self.log.info("Master already closed or not local, closing only current tab")
156 150 self.tab_widget.removeTab(current_tab)
151 self.update_tab_bar_visibility()
157 152 return
158 153
159 154 kernel_manager = closing_widget.kernel_manager
@@ -161,8 +156,7 b' class MainWindow(QtGui.QMainWindow):'
161 156 if keepkernel is None and not closing_widget._confirm_exit:
162 157 # don't prompt, just terminate the kernel if we own it
163 158 # or leave it alone if we don't
164 keepkernel = not closing_widget._existing
165
159 keepkernel = closing_widget._existing
166 160 if keepkernel is None: #show prompt
167 161 if kernel_manager and kernel_manager.channels_running:
168 162 title = self.window().windowTitle()
@@ -170,10 +164,10 b' class MainWindow(QtGui.QMainWindow):'
170 164 okay = QtGui.QMessageBox.Ok
171 165 if closing_widget._may_close:
172 166 msg = "You are closing the tab : "+'"'+self.tab_widget.tabText(current_tab)+'"'
173 info = "Would you like to quit the Kernel and all attached Consoles as well?"
174 justthis = QtGui.QPushButton("&No, just this Console", self)
167 info = "Would you like to quit the Kernel and close all attached Consoles as well?"
168 justthis = QtGui.QPushButton("&No, just this Tab", self)
175 169 justthis.setShortcut('N')
176 closeall = QtGui.QPushButton("&Yes, quit everything", self)
170 closeall = QtGui.QPushButton("&Yes, close all", self)
177 171 closeall.setShortcut('Y')
178 172 box = QtGui.QMessageBox(QtGui.QMessageBox.Question,
179 173 title, msg)
@@ -193,9 +187,9 b' class MainWindow(QtGui.QMainWindow):'
193 187 self.tab_widget.removeTab(current_tab)
194 188 elif reply == 0: # close Console
195 189 if not closing_widget._existing:
196 # Have kernel: don't quit, just close the window
197 self._app.setQuitOnLastWindowClosed(False)
190 # Have kernel: don't quit, just close the tab
198 191 closing_widget.execute("exit True")
192 self.tab_widget.removeTab(current_tab)
199 193 else:
200 194 reply = QtGui.QMessageBox.question(self, title,
201 195 "Are you sure you want to close this Console?"+
@@ -206,16 +200,17 b' class MainWindow(QtGui.QMainWindow):'
206 200 if reply == okay:
207 201 self.tab_widget.removeTab(current_tab)
208 202 elif keepkernel: #close console but leave kernel running (no prompt)
209 if kernel_manager and kernel_manager.channels_running:
210 if not closing_widget._existing:
211 # I have the kernel: don't quit, just close the window
212 203 self.tab_widget.removeTab(current_tab)
204 if kernel_manager and kernel_manager.channels_running:
205 kernel_manager.stop_channels()
213 206 else: #close console and kernel (no prompt)
207 self.tab_widget.removeTab(current_tab)
214 208 if kernel_manager and kernel_manager.channels_running:
209 kernel_manager.shutdown_kernel()
215 210 for slave in slave_tabs:
211 slave.kernel_manager.stop_channels()
216 212 self.tab_widget.removeTab(self.tab_widget.indexOf(slave))
217 self.tab_widget.removeTab(current_tab)
218 kernel_manager.shutdown_kernel()
213
219 214 self.update_tab_bar_visibility()
220 215
221 216 def add_tab_with_frontend(self,frontend,name=None):
@@ -257,20 +252,20 b' class MainWindow(QtGui.QMainWindow):'
257 252 """
258 253
259 254 #convert from/to int/richIpythonWidget if needed
260 if type(tab) == int:
255 if isinstance(tab, int):
261 256 tab = self.tab_widget.widget(tab)
262 km=tab.kernel_manager;
257 km=tab.kernel_manager
263 258
264 259 #build list of all widgets
265 260 widget_list = [self.tab_widget.widget(i) for i in range(self.tab_widget.count())]
266 261
267 262 # widget that are candidate to be the owner of the kernel does have all the same port of the curent widget
268 263 # And should have a _may_close attribute
269 filtred_widget_list = [ widget for widget in widget_list if
264 filtered_widget_list = [ widget for widget in widget_list if
270 265 widget.kernel_manager.connection_file == km.connection_file and
271 266 hasattr(widget,'_may_close') ]
272 267 # the master widget is the one that may close the kernel
273 master_widget= [ widget for widget in filtred_widget_list if widget._may_close]
268 master_widget= [ widget for widget in filtered_widget_list if widget._may_close]
274 269 if as_list:
275 270 return master_widget
276 271 assert(len(master_widget)<=1 )
@@ -279,20 +274,18 b' class MainWindow(QtGui.QMainWindow):'
279 274
280 275 return master_widget[0]
281 276
282 def find_slaves_tabs(self,tab):
283 """
284 Try to return all the frontend that do not own the kernel attached to the given widget/tab.
277 def find_slave_widgets(self,tab):
278 """return all the frontends that do not own the kernel attached to the given widget/tab.
285 279
286 Only find frontend owed by the current application. Selection
287 based on port of the kernel, might be innacurate if several kernel
288 on different ip use same port number.
280 Only find frontends owned by the current application. Selection
281 based on connection file of the kernel.
289 282
290 This fonction does the conversion tabNumber/widget if needed.
283 This function does the conversion tabNumber/widget if needed.
291 284 """
292 285 #convert from/to int/richIpythonWidget if needed
293 if type(tab) == int:
286 if isinstance(tab, int):
294 287 tab = self.tab_widget.widget(tab)
295 km=tab.kernel_manager;
288 km=tab.kernel_manager
296 289
297 290 #build list of all widgets
298 291 widget_list = [self.tab_widget.widget(i) for i in range(self.tab_widget.count())]
@@ -657,7 +650,7 b' class MainWindow(QtGui.QMainWindow):'
657 650 # minimize/maximize/fullscreen actions:
658 651
659 652 def toggle_menu_bar(self):
660 menu_bar = self.menuBar();
653 menu_bar = self.menuBar()
661 654 if menu_bar.isVisible():
662 655 menu_bar.setVisible(False)
663 656 else:
@@ -774,9 +767,40 b' class MainWindow(QtGui.QMainWindow):'
774 767 def closeEvent(self, event):
775 768 """ Forward the close event to every tabs contained by the windows
776 769 """
770 if self.tab_widget.count() == 0:
771 # no tabs, just close
772 event.accept()
773 return
777 774 # Do Not loop on the widget count as it change while closing
778 widget_list=[ self.tab_widget.widget(i) for i in range(self.tab_widget.count())]
779 for widget in widget_list:
775 title = self.window().windowTitle()
776 cancel = QtGui.QMessageBox.Cancel
777 okay = QtGui.QMessageBox.Ok
778
779 if self.confirm_exit:
780 msg = "Close all tabs, stop all kernels, and Quit?"
781 closeall = QtGui.QPushButton("&Yes, quit everything", self)
782 closeall.setShortcut('Y')
783 box = QtGui.QMessageBox(QtGui.QMessageBox.Question,
784 title, msg)
785 # box.setInformativeText(info)
786 box.addButton(cancel)
787 box.addButton(closeall, QtGui.QMessageBox.YesRole)
788 box.setDefaultButton(closeall)
789 box.setEscapeButton(cancel)
790 pixmap = QtGui.QPixmap(self._app.icon.pixmap(QtCore.QSize(64,64)))
791 box.setIconPixmap(pixmap)
792 reply = box.exec_()
793 else:
794 reply = okay
795
796 if reply == cancel:
797 return
798 if reply == okay:
799 while self.tab_widget.count() >= 1:
800 # prevent further confirmations:
801 widget = self.active_frontend
802 widget._confirm_exit = False
780 803 self.close_tab(widget)
804
781 805 event.accept()
782 806
@@ -391,8 +391,8 b' class IPythonQtConsoleApp(BaseIPythonApplication):'
391 391 local_kernel=True)
392 392 widget.kernel_manager = kernel_manager
393 393 widget._existing=False
394 widget._confirm_exit=True
395 394 widget._may_close=True
395 widget._confirm_exit = self.confirm_exit
396 396 return widget
397 397
398 398 def new_frontend_slave(self, current_widget):
@@ -411,8 +411,9 b' class IPythonQtConsoleApp(BaseIPythonApplication):'
411 411 kernel_manager.start_channels()
412 412 widget = self.widget_factory(config=self.config,
413 413 local_kernel=False)
414 widget._confirm_exit=True;
415 widget._may_close=False;
414 widget._existing = True
415 widget._may_close = False
416 widget._confirm_exit = False
416 417 widget.kernel_manager = kernel_manager
417 418 return widget
418 419
@@ -428,13 +429,12 b' class IPythonQtConsoleApp(BaseIPythonApplication):'
428 429 local_kernel = (not self.existing) or self.ip in LOCAL_IPS
429 430 self.widget = self.widget_factory(config=self.config,
430 431 local_kernel=local_kernel)
431 self.widget._existing = self.existing;
432 self.widget._may_close = not self.existing;
433 self.widget._confirm_exit = not self.existing;
432 self.widget._existing = self.existing
433 self.widget._may_close = not self.existing
434 self.widget._confirm_exit = self.confirm_exit
434 435
435 436 self.widget.kernel_manager = self.kernel_manager
436 self.window = MainWindow(self.app, self.widget, self.existing,
437 may_close=local_kernel,
437 self.window = MainWindow(self.app,
438 438 confirm_exit=self.confirm_exit,
439 439 new_frontend_factory=self.new_frontend_master,
440 440 slave_frontend_factory=self.new_frontend_slave,
General Comments 0
You need to be logged in to leave comments. Login now