##// END OF EJS Templates
Fix tab and menubar shortcuts
MinRK -
Show More
@@ -1,782 +1,782 b''
1 """The Qt MainWindow for the QtConsole
1 """The Qt MainWindow for the QtConsole
2
2
3 This is a tabbed pseudo-terminal of IPython sessions, with a menu bar for
3 This is a tabbed pseudo-terminal of IPython sessions, with a menu bar for
4 common actions.
4 common actions.
5
5
6 Authors:
6 Authors:
7
7
8 * Evan Patterson
8 * Evan Patterson
9 * Min RK
9 * Min RK
10 * Erik Tollerud
10 * Erik Tollerud
11 * Fernando Perez
11 * Fernando Perez
12 * Bussonnier Matthias
12 * Bussonnier Matthias
13 * Thomas Kluyver
13 * Thomas Kluyver
14
14
15 """
15 """
16
16
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 # Imports
18 # Imports
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20
20
21 # stdlib imports
21 # stdlib imports
22 import sys
22 import sys
23 import webbrowser
23 import webbrowser
24
24
25 # System library imports
25 # System library imports
26 from IPython.external.qt import QtGui,QtCore
26 from IPython.external.qt import QtGui,QtCore
27
27
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29 # Classes
29 # Classes
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31
31
32 class MainWindow(QtGui.QMainWindow):
32 class MainWindow(QtGui.QMainWindow):
33
33
34 #---------------------------------------------------------------------------
34 #---------------------------------------------------------------------------
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, frontend, existing=False, may_close=True,
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 ):
42 """ Create a tabbed MainWindow for managing IPython FrontendWidgets
42 """ Create a tabbed MainWindow for managing IPython FrontendWidgets
43
43
44 Parameters
44 Parameters
45 ----------
45 ----------
46
46
47 app : reference to QApplication parent
47 app : reference to QApplication parent
48 frontend : IPythonWidget
48 frontend : IPythonWidget
49 The first IPython frontend to start with
49 The first IPython frontend to start with
50 existing : bool, optional
50 existing : bool, optional
51 Whether the first frontend is connected to en existing Kernel,
51 Whether the first frontend is connected to en existing Kernel,
52 or if we own it.
52 or if we own it.
53 may_close : bool, optional
53 may_close : bool, optional
54 Whether we are permitted to close the kernel (determines close dialog behavior)
54 Whether we are permitted to close the kernel (determines close dialog behavior)
55 confirm_exit : bool, optional
55 confirm_exit : bool, optional
56 Whether we should prompt on close of tabs
56 Whether we should prompt on close of tabs
57 new_frontend_factory : callable
57 new_frontend_factory : callable
58 A callable that returns a new IPythonWidget instance, attached to
58 A callable that returns a new IPythonWidget instance, attached to
59 its own running kernel.
59 its own running kernel.
60 slave_frontend_factory : callable
60 slave_frontend_factory : callable
61 A callable that takes an existing IPythonWidget, and returns a new
61 A callable that takes an existing IPythonWidget, and returns a new
62 IPythonWidget instance, attached to the same kernel.
62 IPythonWidget instance, attached to the same kernel.
63 """
63 """
64
64
65 super(MainWindow, self).__init__()
65 super(MainWindow, self).__init__()
66 self._app = app
66 self._app = app
67 self.new_frontend_factory = new_frontend_factory
67 self.new_frontend_factory = new_frontend_factory
68 self.slave_frontend_factory = slave_frontend_factory
68 self.slave_frontend_factory = slave_frontend_factory
69
69
70 self.tab_widget = QtGui.QTabWidget(self)
70 self.tab_widget = QtGui.QTabWidget(self)
71 self.tab_widget.setDocumentMode(True)
71 self.tab_widget.setDocumentMode(True)
72 self.tab_widget.setTabsClosable(True)
72 self.tab_widget.setTabsClosable(True)
73 self.tab_widget.tabCloseRequested[int].connect(self.close_tab)
73 self.tab_widget.tabCloseRequested[int].connect(self.close_tab)
74
74
75 self.setCentralWidget(self.tab_widget)
75 self.setCentralWidget(self.tab_widget)
76 self.update_tab_bar_visibility()
76 self.update_tab_bar_visibility()
77
77
78 def update_tab_bar_visibility(self):
78 def update_tab_bar_visibility(self):
79 """ update visibility of the tabBar depending of the number of tab
79 """ update visibility of the tabBar depending of the number of tab
80
80
81 0 or 1 tab, tabBar hidden
81 0 or 1 tab, tabBar hidden
82 2+ tabs, tabBar visible
82 2+ tabs, tabBar visible
83
83
84 send a self.close if number of tab ==0
84 send a self.close if number of tab ==0
85
85
86 need to be called explicitely, or be connected to tabInserted/tabRemoved
86 need to be called explicitely, or be connected to tabInserted/tabRemoved
87 """
87 """
88 if self.tab_widget.count() <= 1:
88 if self.tab_widget.count() <= 1:
89 self.tab_widget.tabBar().setVisible(False)
89 self.tab_widget.tabBar().setVisible(False)
90 else:
90 else:
91 self.tab_widget.tabBar().setVisible(True)
91 self.tab_widget.tabBar().setVisible(True)
92 if self.tab_widget.count()==0 :
92 if self.tab_widget.count()==0 :
93 self.close()
93 self.close()
94
94
95 @property
95 @property
96 def active_frontend(self):
96 def active_frontend(self):
97 return self.tab_widget.currentWidget()
97 return self.tab_widget.currentWidget()
98
98
99 def create_tab_with_new_frontend(self):
99 def create_tab_with_new_frontend(self):
100 """create a new frontend and attach it to a new tab"""
100 """create a new frontend and attach it to a new tab"""
101 widget = self.new_frontend_factory()
101 widget = self.new_frontend_factory()
102 self.add_tab_with_frontend(widget)
102 self.add_tab_with_frontend(widget)
103
103
104 def create_tab_with_current_kernel(self):
104 def create_tab_with_current_kernel(self):
105 """create a new frontend attached to the same kernel as the current tab"""
105 """create a new frontend attached to the same kernel as the current tab"""
106 current_widget = self.tab_widget.currentWidget()
106 current_widget = self.tab_widget.currentWidget()
107 current_widget_index = self.tab_widget.indexOf(current_widget)
107 current_widget_index = self.tab_widget.indexOf(current_widget)
108 current_widget_name = self.tab_widget.tabText(current_widget_index)
108 current_widget_name = self.tab_widget.tabText(current_widget_index)
109 widget = self.slave_frontend_factory(current_widget)
109 widget = self.slave_frontend_factory(current_widget)
110 if 'slave' in current_widget_name:
110 if 'slave' in current_widget_name:
111 # don't keep stacking slaves
111 # don't keep stacking slaves
112 name = current_widget_name
112 name = current_widget_name
113 else:
113 else:
114 name = str('('+current_widget_name+') slave')
114 name = str('('+current_widget_name+') slave')
115 self.add_tab_with_frontend(widget,name=name)
115 self.add_tab_with_frontend(widget,name=name)
116
116
117 def close_tab(self,current_tab):
117 def close_tab(self,current_tab):
118 """ Called when you need to try to close a tab.
118 """ Called when you need to try to close a tab.
119
119
120 It takes the number of the tab to be closed as argument, or a referece
120 It takes the number of the tab to be closed as argument, or a referece
121 to the wiget insite this tab
121 to the wiget insite this tab
122 """
122 """
123
123
124 # let's be sure "tab" and "closing widget are respectivey the index of the tab to close
124 # let's be sure "tab" and "closing widget are respectivey the index of the tab to close
125 # and a reference to the trontend to close
125 # and a reference to the trontend to close
126 if type(current_tab) is not int :
126 if type(current_tab) is not int :
127 current_tab = self.tab_widget.indexOf(current_tab)
127 current_tab = self.tab_widget.indexOf(current_tab)
128 closing_widget=self.tab_widget.widget(current_tab)
128 closing_widget=self.tab_widget.widget(current_tab)
129
129
130
130
131 # when trying to be closed, widget might re-send a request to be closed again, but will
131 # when trying to be closed, widget might re-send a request to be closed again, but will
132 # be deleted when event will be processed. So need to check that widget still exist and
132 # be deleted when event will be processed. So need to check that widget still exist and
133 # skip if not. One example of this is when 'exit' is send in a slave tab. 'exit' will be
133 # skip if not. One example of this is when 'exit' is send in a slave tab. 'exit' will be
134 # re-send by this fonction on the master widget, which ask all slaves widget to exit
134 # re-send by this fonction on the master widget, which ask all slaves widget to exit
135 if closing_widget==None:
135 if closing_widget==None:
136 return
136 return
137
137
138 #get a list of all wwidget not owning the kernel.
138 #get a list of all wwidget not owning the kernel.
139 slave_tabs=self.find_slaves_tabs(closing_widget)
139 slave_tabs=self.find_slaves_tabs(closing_widget)
140
140
141 keepkernel = None #Use the prompt by default
141 keepkernel = None #Use the prompt by default
142 if hasattr(closing_widget,'_keep_kernel_on_exit'): #set by exit magic
142 if hasattr(closing_widget,'_keep_kernel_on_exit'): #set by exit magic
143 keepkernel = closing_widget._keep_kernel_on_exit
143 keepkernel = closing_widget._keep_kernel_on_exit
144 # If signal sent by exist magic (_keep_kernel_on_exit, exist and not None)
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
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'
146 # restart when they litt get the signal. and the "forward" the 'exit'
147 # to the main win
147 # to the main win
148 if keepkernel is not None:
148 if keepkernel is not None:
149 for tab in slave_tabs:
149 for tab in slave_tabs:
150 tab._hidden = True
150 tab._hidden = True
151 if closing_widget in slave_tabs :
151 if closing_widget in slave_tabs :
152 try :
152 try :
153 self.find_master_tab(closing_widget).execute('exit')
153 self.find_master_tab(closing_widget).execute('exit')
154 except AttributeError:
154 except AttributeError:
155 self.log.info("Master already closed or not local, closing only current tab")
155 self.log.info("Master already closed or not local, closing only current tab")
156 self.tab_widget.removeTab(current_tab)
156 self.tab_widget.removeTab(current_tab)
157 return
157 return
158
158
159 kernel_manager = closing_widget.kernel_manager
159 kernel_manager = closing_widget.kernel_manager
160
160
161 if keepkernel is None and not closing_widget._confirm_exit:
161 if keepkernel is None and not closing_widget._confirm_exit:
162 # don't prompt, just terminate the kernel if we own it
162 # don't prompt, just terminate the kernel if we own it
163 # or leave it alone if we don't
163 # or leave it alone if we don't
164 keepkernel = not closing_widget._existing
164 keepkernel = not closing_widget._existing
165
165
166 if keepkernel is None: #show prompt
166 if keepkernel is None: #show prompt
167 if kernel_manager and kernel_manager.channels_running:
167 if kernel_manager and kernel_manager.channels_running:
168 title = self.window().windowTitle()
168 title = self.window().windowTitle()
169 cancel = QtGui.QMessageBox.Cancel
169 cancel = QtGui.QMessageBox.Cancel
170 okay = QtGui.QMessageBox.Ok
170 okay = QtGui.QMessageBox.Ok
171 if closing_widget._may_close:
171 if closing_widget._may_close:
172 msg = "You are closing the tab : "+'"'+self.tab_widget.tabText(current_tab)+'"'
172 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?"
173 info = "Would you like to quit the Kernel and all attached Consoles as well?"
174 justthis = QtGui.QPushButton("&No, just this Console", self)
174 justthis = QtGui.QPushButton("&No, just this Console", self)
175 justthis.setShortcut('N')
175 justthis.setShortcut('N')
176 closeall = QtGui.QPushButton("&Yes, quit everything", self)
176 closeall = QtGui.QPushButton("&Yes, quit everything", self)
177 closeall.setShortcut('Y')
177 closeall.setShortcut('Y')
178 box = QtGui.QMessageBox(QtGui.QMessageBox.Question,
178 box = QtGui.QMessageBox(QtGui.QMessageBox.Question,
179 title, msg)
179 title, msg)
180 box.setInformativeText(info)
180 box.setInformativeText(info)
181 box.addButton(cancel)
181 box.addButton(cancel)
182 box.addButton(justthis, QtGui.QMessageBox.NoRole)
182 box.addButton(justthis, QtGui.QMessageBox.NoRole)
183 box.addButton(closeall, QtGui.QMessageBox.YesRole)
183 box.addButton(closeall, QtGui.QMessageBox.YesRole)
184 box.setDefaultButton(closeall)
184 box.setDefaultButton(closeall)
185 box.setEscapeButton(cancel)
185 box.setEscapeButton(cancel)
186 pixmap = QtGui.QPixmap(self._app.icon.pixmap(QtCore.QSize(64,64)))
186 pixmap = QtGui.QPixmap(self._app.icon.pixmap(QtCore.QSize(64,64)))
187 box.setIconPixmap(pixmap)
187 box.setIconPixmap(pixmap)
188 reply = box.exec_()
188 reply = box.exec_()
189 if reply == 1: # close All
189 if reply == 1: # close All
190 for slave in slave_tabs:
190 for slave in slave_tabs:
191 self.tab_widget.removeTab(self.tab_widget.indexOf(slave))
191 self.tab_widget.removeTab(self.tab_widget.indexOf(slave))
192 closing_widget.execute("exit")
192 closing_widget.execute("exit")
193 self.tab_widget.removeTab(current_tab)
193 self.tab_widget.removeTab(current_tab)
194 elif reply == 0: # close Console
194 elif reply == 0: # close Console
195 if not closing_widget._existing:
195 if not closing_widget._existing:
196 # Have kernel: don't quit, just close the window
196 # Have kernel: don't quit, just close the window
197 self._app.setQuitOnLastWindowClosed(False)
197 self._app.setQuitOnLastWindowClosed(False)
198 closing_widget.execute("exit True")
198 closing_widget.execute("exit True")
199 else:
199 else:
200 reply = QtGui.QMessageBox.question(self, title,
200 reply = QtGui.QMessageBox.question(self, title,
201 "Are you sure you want to close this Console?"+
201 "Are you sure you want to close this Console?"+
202 "\nThe Kernel and other Consoles will remain active.",
202 "\nThe Kernel and other Consoles will remain active.",
203 okay|cancel,
203 okay|cancel,
204 defaultButton=okay
204 defaultButton=okay
205 )
205 )
206 if reply == okay:
206 if reply == okay:
207 self.tab_widget.removeTab(current_tab)
207 self.tab_widget.removeTab(current_tab)
208 elif keepkernel: #close console but leave kernel running (no prompt)
208 elif keepkernel: #close console but leave kernel running (no prompt)
209 if kernel_manager and kernel_manager.channels_running:
209 if kernel_manager and kernel_manager.channels_running:
210 if not closing_widget._existing:
210 if not closing_widget._existing:
211 # I have the kernel: don't quit, just close the window
211 # I have the kernel: don't quit, just close the window
212 self.tab_widget.removeTab(current_tab)
212 self.tab_widget.removeTab(current_tab)
213 else: #close console and kernel (no prompt)
213 else: #close console and kernel (no prompt)
214 if kernel_manager and kernel_manager.channels_running:
214 if kernel_manager and kernel_manager.channels_running:
215 for slave in slave_tabs:
215 for slave in slave_tabs:
216 self.tab_widget.removeTab(self.tab_widget.indexOf(slave))
216 self.tab_widget.removeTab(self.tab_widget.indexOf(slave))
217 self.tab_widget.removeTab(current_tab)
217 self.tab_widget.removeTab(current_tab)
218 kernel_manager.shutdown_kernel()
218 kernel_manager.shutdown_kernel()
219 self.update_tab_bar_visibility()
219 self.update_tab_bar_visibility()
220
220
221 def add_tab_with_frontend(self,frontend,name=None):
221 def add_tab_with_frontend(self,frontend,name=None):
222 """ insert a tab with a given frontend in the tab bar, and give it a name
222 """ insert a tab with a given frontend in the tab bar, and give it a name
223
223
224 """
224 """
225 if not name:
225 if not name:
226 name=str('kernel '+str(self.tab_widget.count()))
226 name=str('kernel '+str(self.tab_widget.count()))
227 self.tab_widget.addTab(frontend,name)
227 self.tab_widget.addTab(frontend,name)
228 self.update_tab_bar_visibility()
228 self.update_tab_bar_visibility()
229 self.make_frontend_visible(frontend)
229 self.make_frontend_visible(frontend)
230 frontend.exit_requested.connect(self.close_tab)
230 frontend.exit_requested.connect(self.close_tab)
231
231
232 def next_tab(self):
232 def next_tab(self):
233 self.tab_widget.setCurrentIndex((self.tab_widget.currentIndex()+1))
233 self.tab_widget.setCurrentIndex((self.tab_widget.currentIndex()+1))
234
234
235 def prev_tab(self):
235 def prev_tab(self):
236 self.tab_widget.setCurrentIndex((self.tab_widget.currentIndex()-1))
236 self.tab_widget.setCurrentIndex((self.tab_widget.currentIndex()-1))
237
237
238 def make_frontend_visible(self,frontend):
238 def make_frontend_visible(self,frontend):
239 widget_index=self.tab_widget.indexOf(frontend)
239 widget_index=self.tab_widget.indexOf(frontend)
240 if widget_index > 0 :
240 if widget_index > 0 :
241 self.tab_widget.setCurrentIndex(widget_index)
241 self.tab_widget.setCurrentIndex(widget_index)
242
242
243 def find_master_tab(self,tab,as_list=False):
243 def find_master_tab(self,tab,as_list=False):
244 """
244 """
245 Try to return the frontend that own the kernel attached to the given widget/tab.
245 Try to return the frontend that own the kernel attached to the given widget/tab.
246
246
247 Only find frontend owed by the current application. Selection
247 Only find frontend owed by the current application. Selection
248 based on port of the kernel, might be inacurate if several kernel
248 based on port of the kernel, might be inacurate if several kernel
249 on different ip use same port number.
249 on different ip use same port number.
250
250
251 This fonction does the conversion tabNumber/widget if needed.
251 This fonction does the conversion tabNumber/widget if needed.
252 Might return None if no master widget (non local kernel)
252 Might return None if no master widget (non local kernel)
253 Will crash IPython if more than 1 masterWidget
253 Will crash IPython if more than 1 masterWidget
254
254
255 When asList set to True, always return a list of widget(s) owning
255 When asList set to True, always return a list of widget(s) owning
256 the kernel. The list might be empty or containing several Widget.
256 the kernel. The list might be empty or containing several Widget.
257 """
257 """
258
258
259 #convert from/to int/richIpythonWidget if needed
259 #convert from/to int/richIpythonWidget if needed
260 if type(tab) == int:
260 if type(tab) == int:
261 tab = self.tab_widget.widget(tab)
261 tab = self.tab_widget.widget(tab)
262 km=tab.kernel_manager;
262 km=tab.kernel_manager;
263
263
264 #build list of all widgets
264 #build list of all widgets
265 widget_list = [self.tab_widget.widget(i) for i in range(self.tab_widget.count())]
265 widget_list = [self.tab_widget.widget(i) for i in range(self.tab_widget.count())]
266
266
267 # widget that are candidate to be the owner of the kernel does have all the same port of the curent widget
267 # 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
268 # And should have a _may_close attribute
269 filtred_widget_list = [ widget for widget in widget_list if
269 filtred_widget_list = [ widget for widget in widget_list if
270 widget.kernel_manager.connection_file == km.connection_file and
270 widget.kernel_manager.connection_file == km.connection_file and
271 hasattr(widget,'_may_close') ]
271 hasattr(widget,'_may_close') ]
272 # the master widget is the one that may close the kernel
272 # 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]
273 master_widget= [ widget for widget in filtred_widget_list if widget._may_close]
274 if as_list:
274 if as_list:
275 return master_widget
275 return master_widget
276 assert(len(master_widget)<=1 )
276 assert(len(master_widget)<=1 )
277 if len(master_widget)==0:
277 if len(master_widget)==0:
278 return None
278 return None
279
279
280 return master_widget[0]
280 return master_widget[0]
281
281
282 def find_slaves_tabs(self,tab):
282 def find_slaves_tabs(self,tab):
283 """
283 """
284 Try to return all the frontend 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
285
286 Only find frontend owed by the current application. Selection
286 Only find frontend owed by the current application. Selection
287 based on port of the kernel, might be innacurate if several kernel
287 based on port of the kernel, might be innacurate if several kernel
288 on different ip use same port number.
288 on different ip use same port number.
289
289
290 This fonction does the conversion tabNumber/widget if needed.
290 This fonction does the conversion tabNumber/widget if needed.
291 """
291 """
292 #convert from/to int/richIpythonWidget if needed
292 #convert from/to int/richIpythonWidget if needed
293 if type(tab) == int:
293 if type(tab) == int:
294 tab = self.tab_widget.widget(tab)
294 tab = self.tab_widget.widget(tab)
295 km=tab.kernel_manager;
295 km=tab.kernel_manager;
296
296
297 #build list of all widgets
297 #build list of all widgets
298 widget_list = [self.tab_widget.widget(i) for i in range(self.tab_widget.count())]
298 widget_list = [self.tab_widget.widget(i) for i in range(self.tab_widget.count())]
299
299
300 # widget that are candidate not to be the owner of the kernel does have all the same port of the curent widget
300 # widget that are candidate not to be the owner of the kernel does have all the same port of the curent widget
301 filtered_widget_list = ( widget for widget in widget_list if
301 filtered_widget_list = ( widget for widget in widget_list if
302 widget.kernel_manager.connection_file == km.connection_file)
302 widget.kernel_manager.connection_file == km.connection_file)
303 # Get a list of all widget owning the same kernel and removed it from
303 # Get a list of all widget owning the same kernel and removed it from
304 # the previous cadidate. (better using sets ?)
304 # the previous cadidate. (better using sets ?)
305 master_widget_list = self.find_master_tab(tab,as_list=True)
305 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]
306 slave_list = [widget for widget in filtered_widget_list if widget not in master_widget_list]
307
307
308 return slave_list
308 return slave_list
309
309
310 # Populate the menu bar with common actions and shortcuts
310 # Populate the menu bar with common actions and shortcuts
311 def add_menu_action(self, menu, action):
311 def add_menu_action(self, menu, action):
312 """Add action to menu as well as self
312 """Add action to menu as well as self
313
313
314 So that when the menu bar is invisible, its actions are still available.
314 So that when the menu bar is invisible, its actions are still available.
315 """
315 """
316 menu.addAction(action)
316 menu.addAction(action)
317 self.addAction(action)
317 self.addAction(action)
318
318
319 def init_menu_bar(self):
319 def init_menu_bar(self):
320 #create menu in the order they should appear in the menu bar
320 #create menu in the order they should appear in the menu bar
321 self.init_file_menu()
321 self.init_file_menu()
322 self.init_edit_menu()
322 self.init_edit_menu()
323 self.init_view_menu()
323 self.init_view_menu()
324 self.init_kernel_menu()
324 self.init_kernel_menu()
325 self.init_magic_menu()
325 self.init_magic_menu()
326 self.init_window_menu()
326 self.init_window_menu()
327 self.init_help_menu()
327 self.init_help_menu()
328
328
329 def init_file_menu(self):
329 def init_file_menu(self):
330 self.file_menu = self.menuBar().addMenu("&File")
330 self.file_menu = self.menuBar().addMenu("&File")
331
331
332 self.new_kernel_tab_act = QtGui.QAction("New Tab with &New kernel",
332 self.new_kernel_tab_act = QtGui.QAction("New Tab with &New kernel",
333 self,
333 self,
334 shortcut="Ctrl+T",
334 shortcut="Ctrl+T",
335 triggered=self.create_tab_with_new_frontend)
335 triggered=self.create_tab_with_new_frontend)
336 self.add_menu_action(self.file_menu, self.new_kernel_tab_act)
336 self.add_menu_action(self.file_menu, self.new_kernel_tab_act)
337
337
338 self.slave_kernel_tab_act = QtGui.QAction("New Tab with Sa&me kernel",
338 self.slave_kernel_tab_act = QtGui.QAction("New Tab with Sa&me kernel",
339 self,
339 self,
340 shortcut="Ctrl+Shift+T",
340 shortcut="Ctrl+Shift+T",
341 triggered=self.create_tab_with_current_kernel)
341 triggered=self.create_tab_with_current_kernel)
342 self.add_menu_action(self.file_menu, self.slave_kernel_tab_act)
342 self.add_menu_action(self.file_menu, self.slave_kernel_tab_act)
343
343
344 self.file_menu.addSeparator()
344 self.file_menu.addSeparator()
345
345
346 self.close_action=QtGui.QAction("&Close Tab",
346 self.close_action=QtGui.QAction("&Close Tab",
347 self,
347 self,
348 shortcut="Ctrl+W",
348 shortcut="Ctrl+W",
349 triggered=self.close_active_frontend
349 triggered=self.close_active_frontend
350 )
350 )
351 self.add_menu_action(self.file_menu, self.close_action)
351 self.add_menu_action(self.file_menu, self.close_action)
352
352
353 self.export_action=QtGui.QAction("&Save to HTML/XHTML",
353 self.export_action=QtGui.QAction("&Save to HTML/XHTML",
354 self,
354 self,
355 shortcut="Ctrl+S",
355 shortcut="Ctrl+S",
356 triggered=self.export_action_active_frontend
356 triggered=self.export_action_active_frontend
357 )
357 )
358 self.add_menu_action(self.file_menu, self.export_action)
358 self.add_menu_action(self.file_menu, self.export_action)
359
359
360 self.file_menu.addSeparator()
360 self.file_menu.addSeparator()
361
361
362 # Ctrl actually maps to Cmd on OSX, which avoids conflict with history
362 # Ctrl actually maps to Cmd on OSX, which avoids conflict with history
363 # action, which is already bound to true Ctrl+P
363 # action, which is already bound to true Ctrl+P
364 print_shortcut = "Ctrl+P" if sys.platform == 'darwin' else 'Ctrl+Shift+P'
364 print_shortcut = "Ctrl+P" if sys.platform == 'darwin' else 'Ctrl+Shift+P'
365 self.print_action = QtGui.QAction("&Print",
365 self.print_action = QtGui.QAction("&Print",
366 self,
366 self,
367 shortcut=print_shortcut,
367 shortcut=print_shortcut,
368 triggered=self.print_action_active_frontend)
368 triggered=self.print_action_active_frontend)
369 self.add_menu_action(self.file_menu, self.print_action)
369 self.add_menu_action(self.file_menu, self.print_action)
370
370
371 if sys.platform == 'darwin':
371 if sys.platform == 'darwin':
372 # OSX always has Quit in the Application menu, only add it
372 # OSX always has Quit in the Application menu, only add it
373 # to the File menu elsewhere.
373 # to the File menu elsewhere.
374
374
375 self.file_menu.addSeparator()
375 self.file_menu.addSeparator()
376
376
377 self.quit_action = QtGui.QAction("&Quit",
377 self.quit_action = QtGui.QAction("&Quit",
378 self,
378 self,
379 shortcut=QtGui.QKeySequence.Quit,
379 shortcut=QtGui.QKeySequence.Quit,
380 triggered=self.close,
380 triggered=self.close,
381 )
381 )
382 self.add_menu_action(self.file_menu, self.quit_action)
382 self.add_menu_action(self.file_menu, self.quit_action)
383
383
384
384
385 def init_edit_menu(self):
385 def init_edit_menu(self):
386 self.edit_menu = self.menuBar().addMenu("&Edit")
386 self.edit_menu = self.menuBar().addMenu("&Edit")
387
387
388 self.undo_action = QtGui.QAction("&Undo",
388 self.undo_action = QtGui.QAction("&Undo",
389 self,
389 self,
390 shortcut="Ctrl+Z",
390 shortcut="Ctrl+Z",
391 statusTip="Undo last action if possible",
391 statusTip="Undo last action if possible",
392 triggered=self.undo_active_frontend
392 triggered=self.undo_active_frontend
393 )
393 )
394 self.add_menu_action(self.edit_menu, self.undo_action)
394 self.add_menu_action(self.edit_menu, self.undo_action)
395
395
396 self.redo_action = QtGui.QAction("&Redo",
396 self.redo_action = QtGui.QAction("&Redo",
397 self,
397 self,
398 shortcut="Ctrl+Shift+Z",
398 shortcut="Ctrl+Shift+Z",
399 statusTip="Redo last action if possible",
399 statusTip="Redo last action if possible",
400 triggered=self.redo_active_frontend)
400 triggered=self.redo_active_frontend)
401 self.add_menu_action(self.edit_menu, self.redo_action)
401 self.add_menu_action(self.edit_menu, self.redo_action)
402
402
403 self.edit_menu.addSeparator()
403 self.edit_menu.addSeparator()
404
404
405 self.cut_action = QtGui.QAction("&Cut",
405 self.cut_action = QtGui.QAction("&Cut",
406 self,
406 self,
407 shortcut=QtGui.QKeySequence.Cut,
407 shortcut=QtGui.QKeySequence.Cut,
408 triggered=self.cut_active_frontend
408 triggered=self.cut_active_frontend
409 )
409 )
410 self.add_menu_action(self.edit_menu, self.cut_action)
410 self.add_menu_action(self.edit_menu, self.cut_action)
411
411
412 self.copy_action = QtGui.QAction("&Copy",
412 self.copy_action = QtGui.QAction("&Copy",
413 self,
413 self,
414 shortcut=QtGui.QKeySequence.Copy,
414 shortcut=QtGui.QKeySequence.Copy,
415 triggered=self.copy_active_frontend
415 triggered=self.copy_active_frontend
416 )
416 )
417 self.add_menu_action(self.edit_menu, self.copy_action)
417 self.add_menu_action(self.edit_menu, self.copy_action)
418
418
419 self.copy_raw_action = QtGui.QAction("Copy (&Raw Text)",
419 self.copy_raw_action = QtGui.QAction("Copy (&Raw Text)",
420 self,
420 self,
421 shortcut="Ctrl+Shift+C",
421 shortcut="Ctrl+Shift+C",
422 triggered=self.copy_raw_active_frontend
422 triggered=self.copy_raw_active_frontend
423 )
423 )
424 self.add_menu_action(self.edit_menu, self.copy_raw_action)
424 self.add_menu_action(self.edit_menu, self.copy_raw_action)
425
425
426 self.paste_action = QtGui.QAction("&Paste",
426 self.paste_action = QtGui.QAction("&Paste",
427 self,
427 self,
428 shortcut=QtGui.QKeySequence.Paste,
428 shortcut=QtGui.QKeySequence.Paste,
429 triggered=self.paste_active_frontend
429 triggered=self.paste_active_frontend
430 )
430 )
431 self.add_menu_action(self.edit_menu, self.paste_action)
431 self.add_menu_action(self.edit_menu, self.paste_action)
432
432
433 self.edit_menu.addSeparator()
433 self.edit_menu.addSeparator()
434
434
435 self.select_all_action = QtGui.QAction("Select &All",
435 self.select_all_action = QtGui.QAction("Select &All",
436 self,
436 self,
437 shortcut="Ctrl+A",
437 shortcut="Ctrl+A",
438 triggered=self.select_all_active_frontend
438 triggered=self.select_all_active_frontend
439 )
439 )
440 self.add_menu_action(self.edit_menu, self.select_all_action)
440 self.add_menu_action(self.edit_menu, self.select_all_action)
441
441
442
442
443 def init_view_menu(self):
443 def init_view_menu(self):
444 self.view_menu = self.menuBar().addMenu("&View")
444 self.view_menu = self.menuBar().addMenu("&View")
445
445
446 if sys.platform != 'darwin':
446 if sys.platform != 'darwin':
447 # disable on OSX, where there is always a menu bar
447 # disable on OSX, where there is always a menu bar
448 self.toggle_menu_bar_act = QtGui.QAction("Toggle &Menu Bar",
448 self.toggle_menu_bar_act = QtGui.QAction("Toggle &Menu Bar",
449 self,
449 self,
450 shortcut="Ctrl+Meta+M",
450 shortcut="Ctrl+Shift+M",
451 statusTip="Toggle visibility of menubar",
451 statusTip="Toggle visibility of menubar",
452 triggered=self.toggle_menu_bar)
452 triggered=self.toggle_menu_bar)
453 self.add_menu_action(self.view_menu, self.toggle_menu_bar_act)
453 self.add_menu_action(self.view_menu, self.toggle_menu_bar_act)
454
454
455 fs_key = "Ctrl+Meta+F" if sys.platform == 'darwin' else "F11"
455 fs_key = "Ctrl+Meta+F" if sys.platform == 'darwin' else "F11"
456 self.full_screen_act = QtGui.QAction("&Full Screen",
456 self.full_screen_act = QtGui.QAction("&Full Screen",
457 self,
457 self,
458 shortcut=fs_key,
458 shortcut=fs_key,
459 statusTip="Toggle between Fullscreen and Normal Size",
459 statusTip="Toggle between Fullscreen and Normal Size",
460 triggered=self.toggleFullScreen)
460 triggered=self.toggleFullScreen)
461 self.add_menu_action(self.view_menu, self.full_screen_act)
461 self.add_menu_action(self.view_menu, self.full_screen_act)
462
462
463 self.view_menu.addSeparator()
463 self.view_menu.addSeparator()
464
464
465 self.increase_font_size = QtGui.QAction("Zoom &In",
465 self.increase_font_size = QtGui.QAction("Zoom &In",
466 self,
466 self,
467 shortcut="Ctrl++",
467 shortcut="Ctrl++",
468 triggered=self.increase_font_size_active_frontend
468 triggered=self.increase_font_size_active_frontend
469 )
469 )
470 self.add_menu_action(self.view_menu, self.increase_font_size)
470 self.add_menu_action(self.view_menu, self.increase_font_size)
471
471
472 self.decrease_font_size = QtGui.QAction("Zoom &Out",
472 self.decrease_font_size = QtGui.QAction("Zoom &Out",
473 self,
473 self,
474 shortcut="Ctrl+-",
474 shortcut="Ctrl+-",
475 triggered=self.decrease_font_size_active_frontend
475 triggered=self.decrease_font_size_active_frontend
476 )
476 )
477 self.add_menu_action(self.view_menu, self.decrease_font_size)
477 self.add_menu_action(self.view_menu, self.decrease_font_size)
478
478
479 self.reset_font_size = QtGui.QAction("Zoom &Reset",
479 self.reset_font_size = QtGui.QAction("Zoom &Reset",
480 self,
480 self,
481 shortcut="Ctrl+0",
481 shortcut="Ctrl+0",
482 triggered=self.reset_font_size_active_frontend
482 triggered=self.reset_font_size_active_frontend
483 )
483 )
484 self.add_menu_action(self.view_menu, self.reset_font_size)
484 self.add_menu_action(self.view_menu, self.reset_font_size)
485
485
486 self.view_menu.addSeparator()
486 self.view_menu.addSeparator()
487
487
488 self.clear_action = QtGui.QAction("&Clear Screen",
488 self.clear_action = QtGui.QAction("&Clear Screen",
489 self,
489 self,
490 shortcut='Ctrl+L',
490 shortcut='Ctrl+L',
491 statusTip="Clear the console",
491 statusTip="Clear the console",
492 triggered=self.clear_magic_active_frontend)
492 triggered=self.clear_magic_active_frontend)
493 self.add_menu_action(self.view_menu, self.clear_action)
493 self.add_menu_action(self.view_menu, self.clear_action)
494
494
495 def init_kernel_menu(self):
495 def init_kernel_menu(self):
496 self.kernel_menu = self.menuBar().addMenu("&Kernel")
496 self.kernel_menu = self.menuBar().addMenu("&Kernel")
497 # Qt on OSX maps Ctrl to Cmd, and Meta to Ctrl
497 # Qt on OSX maps Ctrl to Cmd, and Meta to Ctrl
498 # keep the signal shortcuts to ctrl, rather than
498 # keep the signal shortcuts to ctrl, rather than
499 # platform-default like we do elsewhere.
499 # platform-default like we do elsewhere.
500
500
501 ctrl = "Meta" if sys.platform == 'darwin' else "Ctrl"
501 ctrl = "Meta" if sys.platform == 'darwin' else "Ctrl"
502
502
503 self.interrupt_kernel_action = QtGui.QAction("Interrupt current Kernel",
503 self.interrupt_kernel_action = QtGui.QAction("Interrupt current Kernel",
504 self,
504 self,
505 triggered=self.interrupt_kernel_active_frontend,
505 triggered=self.interrupt_kernel_active_frontend,
506 shortcut=ctrl+"+C",
506 shortcut=ctrl+"+C",
507 )
507 )
508 self.add_menu_action(self.kernel_menu, self.interrupt_kernel_action)
508 self.add_menu_action(self.kernel_menu, self.interrupt_kernel_action)
509
509
510 self.restart_kernel_action = QtGui.QAction("Restart current Kernel",
510 self.restart_kernel_action = QtGui.QAction("Restart current Kernel",
511 self,
511 self,
512 triggered=self.restart_kernel_active_frontend,
512 triggered=self.restart_kernel_active_frontend,
513 shortcut=ctrl+"+.",
513 shortcut=ctrl+"+.",
514 )
514 )
515 self.add_menu_action(self.kernel_menu, self.restart_kernel_action)
515 self.add_menu_action(self.kernel_menu, self.restart_kernel_action)
516
516
517 self.kernel_menu.addSeparator()
517 self.kernel_menu.addSeparator()
518
518
519 def init_magic_menu(self):
519 def init_magic_menu(self):
520 self.magic_menu = self.menuBar().addMenu("&Magic")
520 self.magic_menu = self.menuBar().addMenu("&Magic")
521 self.all_magic_menu = self.magic_menu.addMenu("&All Magics")
521 self.all_magic_menu = self.magic_menu.addMenu("&All Magics")
522
522
523 self.reset_action = QtGui.QAction("&Reset",
523 self.reset_action = QtGui.QAction("&Reset",
524 self,
524 self,
525 statusTip="Clear all varible from workspace",
525 statusTip="Clear all varible from workspace",
526 triggered=self.reset_magic_active_frontend)
526 triggered=self.reset_magic_active_frontend)
527 self.add_menu_action(self.magic_menu, self.reset_action)
527 self.add_menu_action(self.magic_menu, self.reset_action)
528
528
529 self.history_action = QtGui.QAction("&History",
529 self.history_action = QtGui.QAction("&History",
530 self,
530 self,
531 statusTip="show command history",
531 statusTip="show command history",
532 triggered=self.history_magic_active_frontend)
532 triggered=self.history_magic_active_frontend)
533 self.add_menu_action(self.magic_menu, self.history_action)
533 self.add_menu_action(self.magic_menu, self.history_action)
534
534
535 self.save_action = QtGui.QAction("E&xport History ",
535 self.save_action = QtGui.QAction("E&xport History ",
536 self,
536 self,
537 statusTip="Export History as Python File",
537 statusTip="Export History as Python File",
538 triggered=self.save_magic_active_frontend)
538 triggered=self.save_magic_active_frontend)
539 self.add_menu_action(self.magic_menu, self.save_action)
539 self.add_menu_action(self.magic_menu, self.save_action)
540
540
541 self.who_action = QtGui.QAction("&Who",
541 self.who_action = QtGui.QAction("&Who",
542 self,
542 self,
543 statusTip="List interactive variable",
543 statusTip="List interactive variable",
544 triggered=self.who_magic_active_frontend)
544 triggered=self.who_magic_active_frontend)
545 self.add_menu_action(self.magic_menu, self.who_action)
545 self.add_menu_action(self.magic_menu, self.who_action)
546
546
547 self.who_ls_action = QtGui.QAction("Wh&o ls",
547 self.who_ls_action = QtGui.QAction("Wh&o ls",
548 self,
548 self,
549 statusTip="Return a list of interactive variable",
549 statusTip="Return a list of interactive variable",
550 triggered=self.who_ls_magic_active_frontend)
550 triggered=self.who_ls_magic_active_frontend)
551 self.add_menu_action(self.magic_menu, self.who_ls_action)
551 self.add_menu_action(self.magic_menu, self.who_ls_action)
552
552
553 self.whos_action = QtGui.QAction("Who&s",
553 self.whos_action = QtGui.QAction("Who&s",
554 self,
554 self,
555 statusTip="List interactive variable with detail",
555 statusTip="List interactive variable with detail",
556 triggered=self.whos_magic_active_frontend)
556 triggered=self.whos_magic_active_frontend)
557 self.add_menu_action(self.magic_menu, self.whos_action)
557 self.add_menu_action(self.magic_menu, self.whos_action)
558
558
559 # allmagics submenu:
559 # allmagics submenu:
560
560
561 #for now this is just a copy and paste, but we should get this dynamically
561 #for now this is just a copy and paste, but we should get this dynamically
562 magiclist=["%alias", "%autocall", "%automagic", "%bookmark", "%cd", "%clear",
562 magiclist=["%alias", "%autocall", "%automagic", "%bookmark", "%cd", "%clear",
563 "%colors", "%debug", "%dhist", "%dirs", "%doctest_mode", "%ed", "%edit", "%env", "%gui",
563 "%colors", "%debug", "%dhist", "%dirs", "%doctest_mode", "%ed", "%edit", "%env", "%gui",
564 "%guiref", "%hist", "%history", "%install_default_config", "%install_profiles",
564 "%guiref", "%hist", "%history", "%install_default_config", "%install_profiles",
565 "%less", "%load_ext", "%loadpy", "%logoff", "%logon", "%logstart", "%logstate",
565 "%less", "%load_ext", "%loadpy", "%logoff", "%logon", "%logstart", "%logstate",
566 "%logstop", "%lsmagic", "%macro", "%magic", "%man", "%more", "%notebook", "%page",
566 "%logstop", "%lsmagic", "%macro", "%magic", "%man", "%more", "%notebook", "%page",
567 "%pastebin", "%pdb", "%pdef", "%pdoc", "%pfile", "%pinfo", "%pinfo2", "%popd", "%pprint",
567 "%pastebin", "%pdb", "%pdef", "%pdoc", "%pfile", "%pinfo", "%pinfo2", "%popd", "%pprint",
568 "%precision", "%profile", "%prun", "%psearch", "%psource", "%pushd", "%pwd", "%pycat",
568 "%precision", "%profile", "%prun", "%psearch", "%psource", "%pushd", "%pwd", "%pycat",
569 "%pylab", "%quickref", "%recall", "%rehashx", "%reload_ext", "%rep", "%rerun",
569 "%pylab", "%quickref", "%recall", "%rehashx", "%reload_ext", "%rep", "%rerun",
570 "%reset", "%reset_selective", "%run", "%save", "%sc", "%sx", "%tb", "%time", "%timeit",
570 "%reset", "%reset_selective", "%run", "%save", "%sc", "%sx", "%tb", "%time", "%timeit",
571 "%unalias", "%unload_ext", "%who", "%who_ls", "%whos", "%xdel", "%xmode"]
571 "%unalias", "%unload_ext", "%who", "%who_ls", "%whos", "%xdel", "%xmode"]
572
572
573 def make_dynamic_magic(i):
573 def make_dynamic_magic(i):
574 def inner_dynamic_magic():
574 def inner_dynamic_magic():
575 self.active_frontend.execute(i)
575 self.active_frontend.execute(i)
576 inner_dynamic_magic.__name__ = "dynamics_magic_%s" % i
576 inner_dynamic_magic.__name__ = "dynamics_magic_%s" % i
577 return inner_dynamic_magic
577 return inner_dynamic_magic
578
578
579 for magic in magiclist:
579 for magic in magiclist:
580 xaction = QtGui.QAction(magic,
580 xaction = QtGui.QAction(magic,
581 self,
581 self,
582 triggered=make_dynamic_magic(magic)
582 triggered=make_dynamic_magic(magic)
583 )
583 )
584 self.all_magic_menu.addAction(xaction)
584 self.all_magic_menu.addAction(xaction)
585
585
586 def init_window_menu(self):
586 def init_window_menu(self):
587 self.window_menu = self.menuBar().addMenu("&Window")
587 self.window_menu = self.menuBar().addMenu("&Window")
588 if sys.platform == 'darwin':
588 if sys.platform == 'darwin':
589 # add min/maximize actions to OSX, which lacks default bindings.
589 # add min/maximize actions to OSX, which lacks default bindings.
590 self.minimizeAct = QtGui.QAction("Mini&mize",
590 self.minimizeAct = QtGui.QAction("Mini&mize",
591 self,
591 self,
592 shortcut="Ctrl+m",
592 shortcut="Ctrl+m",
593 statusTip="Minimize the window/Restore Normal Size",
593 statusTip="Minimize the window/Restore Normal Size",
594 triggered=self.toggleMinimized)
594 triggered=self.toggleMinimized)
595 # maximize is called 'Zoom' on OSX for some reason
595 # maximize is called 'Zoom' on OSX for some reason
596 self.maximizeAct = QtGui.QAction("&Zoom",
596 self.maximizeAct = QtGui.QAction("&Zoom",
597 self,
597 self,
598 shortcut="Ctrl+Shift+M",
598 shortcut="Ctrl+Shift+M",
599 statusTip="Maximize the window/Restore Normal Size",
599 statusTip="Maximize the window/Restore Normal Size",
600 triggered=self.toggleMaximized)
600 triggered=self.toggleMaximized)
601
601
602 self.add_menu_action(self.window_menu, self.minimizeAct)
602 self.add_menu_action(self.window_menu, self.minimizeAct)
603 self.add_menu_action(self.window_menu, self.maximizeAct)
603 self.add_menu_action(self.window_menu, self.maximizeAct)
604 self.window_menu.addSeparator()
604 self.window_menu.addSeparator()
605
605
606 prev_key = "Ctrl+Shift+Left" if sys.platform == 'darwin' else "Ctrl+PgDown"
606 prev_key = "Ctrl+Shift+Left" if sys.platform == 'darwin' else "Ctrl+PgUp"
607 self.prev_tab_act = QtGui.QAction("Pre&vious Tab",
607 self.prev_tab_act = QtGui.QAction("Pre&vious Tab",
608 self,
608 self,
609 shortcut=prev_key,
609 shortcut=prev_key,
610 statusTip="Select previous tab",
610 statusTip="Select previous tab",
611 triggered=self.prev_tab)
611 triggered=self.prev_tab)
612 self.add_menu_action(self.window_menu, self.prev_tab_act)
612 self.add_menu_action(self.window_menu, self.prev_tab_act)
613
613
614 next_key = "Ctrl+Shift+Right" if sys.platform == 'darwin' else "Ctrl+PgUp"
614 next_key = "Ctrl+Shift+Right" if sys.platform == 'darwin' else "Ctrl+PgDown"
615 self.next_tab_act = QtGui.QAction("Ne&xt Tab",
615 self.next_tab_act = QtGui.QAction("Ne&xt Tab",
616 self,
616 self,
617 shortcut=next_key,
617 shortcut=next_key,
618 statusTip="Select next tab",
618 statusTip="Select next tab",
619 triggered=self.next_tab)
619 triggered=self.next_tab)
620 self.add_menu_action(self.window_menu, self.next_tab_act)
620 self.add_menu_action(self.window_menu, self.next_tab_act)
621
621
622 def init_help_menu(self):
622 def init_help_menu(self):
623 # please keep the Help menu in Mac Os even if empty. It will
623 # please keep the Help menu in Mac Os even if empty. It will
624 # automatically contain a search field to search inside menus and
624 # automatically contain a search field to search inside menus and
625 # please keep it spelled in English, as long as Qt Doesn't support
625 # please keep it spelled in English, as long as Qt Doesn't support
626 # a QAction.MenuRole like HelpMenuRole otherwise it will loose
626 # a QAction.MenuRole like HelpMenuRole otherwise it will loose
627 # this search field fonctionality
627 # this search field fonctionality
628
628
629 self.help_menu = self.menuBar().addMenu("&Help")
629 self.help_menu = self.menuBar().addMenu("&Help")
630
630
631
631
632 # Help Menu
632 # Help Menu
633
633
634 self.intro_active_frontend_action = QtGui.QAction("&Intro to IPython",
634 self.intro_active_frontend_action = QtGui.QAction("&Intro to IPython",
635 self,
635 self,
636 triggered=self.intro_active_frontend
636 triggered=self.intro_active_frontend
637 )
637 )
638 self.add_menu_action(self.help_menu, self.intro_active_frontend_action)
638 self.add_menu_action(self.help_menu, self.intro_active_frontend_action)
639
639
640 self.quickref_active_frontend_action = QtGui.QAction("IPython &Cheat Sheet",
640 self.quickref_active_frontend_action = QtGui.QAction("IPython &Cheat Sheet",
641 self,
641 self,
642 triggered=self.quickref_active_frontend
642 triggered=self.quickref_active_frontend
643 )
643 )
644 self.add_menu_action(self.help_menu, self.quickref_active_frontend_action)
644 self.add_menu_action(self.help_menu, self.quickref_active_frontend_action)
645
645
646 self.guiref_active_frontend_action = QtGui.QAction("&Qt Console",
646 self.guiref_active_frontend_action = QtGui.QAction("&Qt Console",
647 self,
647 self,
648 triggered=self.guiref_active_frontend
648 triggered=self.guiref_active_frontend
649 )
649 )
650 self.add_menu_action(self.help_menu, self.guiref_active_frontend_action)
650 self.add_menu_action(self.help_menu, self.guiref_active_frontend_action)
651
651
652 self.onlineHelpAct = QtGui.QAction("Open Online &Help",
652 self.onlineHelpAct = QtGui.QAction("Open Online &Help",
653 self,
653 self,
654 triggered=self._open_online_help)
654 triggered=self._open_online_help)
655 self.add_menu_action(self.help_menu, self.onlineHelpAct)
655 self.add_menu_action(self.help_menu, self.onlineHelpAct)
656
656
657 # minimize/maximize/fullscreen actions:
657 # minimize/maximize/fullscreen actions:
658
658
659 def toggle_menu_bar(self):
659 def toggle_menu_bar(self):
660 menu_bar = self.menuBar();
660 menu_bar = self.menuBar();
661 if menu_bar.isVisible():
661 if menu_bar.isVisible():
662 menu_bar.setVisible(False)
662 menu_bar.setVisible(False)
663 else:
663 else:
664 menu_bar.setVisible(True)
664 menu_bar.setVisible(True)
665
665
666 def toggleMinimized(self):
666 def toggleMinimized(self):
667 if not self.isMinimized():
667 if not self.isMinimized():
668 self.showMinimized()
668 self.showMinimized()
669 else:
669 else:
670 self.showNormal()
670 self.showNormal()
671
671
672 def _open_online_help(self):
672 def _open_online_help(self):
673 filename="http://ipython.org/ipython-doc/stable/index.html"
673 filename="http://ipython.org/ipython-doc/stable/index.html"
674 webbrowser.open(filename, new=1, autoraise=True)
674 webbrowser.open(filename, new=1, autoraise=True)
675
675
676 def toggleMaximized(self):
676 def toggleMaximized(self):
677 if not self.isMaximized():
677 if not self.isMaximized():
678 self.showMaximized()
678 self.showMaximized()
679 else:
679 else:
680 self.showNormal()
680 self.showNormal()
681
681
682 # Min/Max imizing while in full screen give a bug
682 # Min/Max imizing while in full screen give a bug
683 # when going out of full screen, at least on OSX
683 # when going out of full screen, at least on OSX
684 def toggleFullScreen(self):
684 def toggleFullScreen(self):
685 if not self.isFullScreen():
685 if not self.isFullScreen():
686 self.showFullScreen()
686 self.showFullScreen()
687 if sys.platform == 'darwin':
687 if sys.platform == 'darwin':
688 self.maximizeAct.setEnabled(False)
688 self.maximizeAct.setEnabled(False)
689 self.minimizeAct.setEnabled(False)
689 self.minimizeAct.setEnabled(False)
690 else:
690 else:
691 self.showNormal()
691 self.showNormal()
692 if sys.platform == 'darwin':
692 if sys.platform == 'darwin':
693 self.maximizeAct.setEnabled(True)
693 self.maximizeAct.setEnabled(True)
694 self.minimizeAct.setEnabled(True)
694 self.minimizeAct.setEnabled(True)
695
695
696 def close_active_frontend(self):
696 def close_active_frontend(self):
697 self.close_tab(self.active_frontend)
697 self.close_tab(self.active_frontend)
698
698
699 def restart_kernel_active_frontend(self):
699 def restart_kernel_active_frontend(self):
700 self.active_frontend.request_restart_kernel()
700 self.active_frontend.request_restart_kernel()
701
701
702 def interrupt_kernel_active_frontend(self):
702 def interrupt_kernel_active_frontend(self):
703 self.active_frontend.request_interrupt_kernel()
703 self.active_frontend.request_interrupt_kernel()
704
704
705 def cut_active_frontend(self):
705 def cut_active_frontend(self):
706 self.active_frontend.cut_action.trigger()
706 self.active_frontend.cut_action.trigger()
707
707
708 def copy_active_frontend(self):
708 def copy_active_frontend(self):
709 self.active_frontend.copy_action.trigger()
709 self.active_frontend.copy_action.trigger()
710
710
711 def copy_raw_active_frontend(self):
711 def copy_raw_active_frontend(self):
712 self.active_frontend._copy_raw_action.trigger()
712 self.active_frontend._copy_raw_action.trigger()
713
713
714 def paste_active_frontend(self):
714 def paste_active_frontend(self):
715 self.active_frontend.paste_action.trigger()
715 self.active_frontend.paste_action.trigger()
716
716
717 def undo_active_frontend(self):
717 def undo_active_frontend(self):
718 self.active_frontend.undo()
718 self.active_frontend.undo()
719
719
720 def redo_active_frontend(self):
720 def redo_active_frontend(self):
721 self.active_frontend.redo()
721 self.active_frontend.redo()
722
722
723 def reset_magic_active_frontend(self):
723 def reset_magic_active_frontend(self):
724 self.active_frontend.execute("%reset")
724 self.active_frontend.execute("%reset")
725
725
726 def history_magic_active_frontend(self):
726 def history_magic_active_frontend(self):
727 self.active_frontend.execute("%history")
727 self.active_frontend.execute("%history")
728
728
729 def save_magic_active_frontend(self):
729 def save_magic_active_frontend(self):
730 self.active_frontend.save_magic()
730 self.active_frontend.save_magic()
731
731
732 def clear_magic_active_frontend(self):
732 def clear_magic_active_frontend(self):
733 self.active_frontend.execute("%clear")
733 self.active_frontend.execute("%clear")
734
734
735 def who_magic_active_frontend(self):
735 def who_magic_active_frontend(self):
736 self.active_frontend.execute("%who")
736 self.active_frontend.execute("%who")
737
737
738 def who_ls_magic_active_frontend(self):
738 def who_ls_magic_active_frontend(self):
739 self.active_frontend.execute("%who_ls")
739 self.active_frontend.execute("%who_ls")
740
740
741 def whos_magic_active_frontend(self):
741 def whos_magic_active_frontend(self):
742 self.active_frontend.execute("%whos")
742 self.active_frontend.execute("%whos")
743
743
744 def print_action_active_frontend(self):
744 def print_action_active_frontend(self):
745 self.active_frontend.print_action.trigger()
745 self.active_frontend.print_action.trigger()
746
746
747 def export_action_active_frontend(self):
747 def export_action_active_frontend(self):
748 self.active_frontend.export_action.trigger()
748 self.active_frontend.export_action.trigger()
749
749
750 def select_all_active_frontend(self):
750 def select_all_active_frontend(self):
751 self.active_frontend.select_all_action.trigger()
751 self.active_frontend.select_all_action.trigger()
752
752
753 def increase_font_size_active_frontend(self):
753 def increase_font_size_active_frontend(self):
754 self.active_frontend.increase_font_size.trigger()
754 self.active_frontend.increase_font_size.trigger()
755
755
756 def decrease_font_size_active_frontend(self):
756 def decrease_font_size_active_frontend(self):
757 self.active_frontend.decrease_font_size.trigger()
757 self.active_frontend.decrease_font_size.trigger()
758
758
759 def reset_font_size_active_frontend(self):
759 def reset_font_size_active_frontend(self):
760 self.active_frontend.reset_font_size.trigger()
760 self.active_frontend.reset_font_size.trigger()
761
761
762 def guiref_active_frontend(self):
762 def guiref_active_frontend(self):
763 self.active_frontend.execute("%guiref")
763 self.active_frontend.execute("%guiref")
764
764
765 def intro_active_frontend(self):
765 def intro_active_frontend(self):
766 self.active_frontend.execute("?")
766 self.active_frontend.execute("?")
767
767
768 def quickref_active_frontend(self):
768 def quickref_active_frontend(self):
769 self.active_frontend.execute("%quickref")
769 self.active_frontend.execute("%quickref")
770 #---------------------------------------------------------------------------
770 #---------------------------------------------------------------------------
771 # QWidget interface
771 # QWidget interface
772 #---------------------------------------------------------------------------
772 #---------------------------------------------------------------------------
773
773
774 def closeEvent(self, event):
774 def closeEvent(self, event):
775 """ Forward the close event to every tabs contained by the windows
775 """ Forward the close event to every tabs contained by the windows
776 """
776 """
777 # Do Not loop on the widget count as it change while closing
777 # 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())]
778 widget_list=[ self.tab_widget.widget(i) for i in range(self.tab_widget.count())]
779 for widget in widget_list:
779 for widget in widget_list:
780 self.close_tab(widget)
780 self.close_tab(widget)
781 event.accept()
781 event.accept()
782
782
General Comments 0
You need to be logged in to leave comments. Login now