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