##// END OF EJS Templates
Create all_magic_menu. use webbrowser to open url
Create all_magic_menu. use webbrowser to open url

File last commit:

r5059:58e0679d
r5059:58e0679d
Show More
qtconsoleapp.py
1111 lines | 44.3 KiB | text/x-python | PythonLexer
epatters
Created a proper IPython script from the console frontend demo.
r2801 """ A minimal application using the Qt console-style IPython frontend.
MinRK
code updates per review of PR #454
r4021
This is not a complete console app, as subprocess will not be able to receive
input, there is no real readline support, among other limitations.
Authors:
* Evan Patterson
* Min RK
* Erik Tollerud
* Fernando Perez
epatters
* The SVG payload matplotlib backend now works....
r2758 """
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 #-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
MinRK
QtConsole now uses newapp
r3971 # stdlib imports
MinRK
protect kernelapp/qtconsole from invalid connection files...
r4986 import json
MinRK
QtConsole now uses newapp
r3971 import os
import signal
import sys
Matthias BUSSONNIER
Create all_magic_menu. use webbrowser to open url
r5059 import webbrowser
from getpass import getpass
MinRK
QtConsole now uses newapp
r3971
# System library imports
Matthias BUSSONNIER
create menu bar on OSX with some action...
r5027 from IPython.external.qt import QtGui,QtCore
MinRK
exposed pygments styles as ipythonqt options
r3170 from pygments.styles import get_all_styles
Evan Patterson
Paved the way for PySide support....
r3304
epatters
* The SVG payload matplotlib backend now works....
r2758 # Local imports
MinRK
add confirm_exit option to qtconsole to suppress exit dialog
r3983 from IPython.config.application import boolean_flag
MinRK
move ipcluster create|list to `ipython profile create|list`...
r4024 from IPython.core.application import BaseIPythonApplication
from IPython.core.profiledir import ProfileDir
MinRK
split qtconsole's connection-file search into lib.kernel...
r4972 from IPython.lib.kernel import tunnel_to_kernel, find_connection_file
epatters
Created a proper IPython script from the console frontend demo.
r2801 from IPython.frontend.qt.console.frontend_widget import FrontendWidget
from IPython.frontend.qt.console.ipython_widget import IPythonWidget
from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
MinRK
exposed pygments styles as ipythonqt options
r3170 from IPython.frontend.qt.console import styles
epatters
* The SVG payload matplotlib backend now works....
r2758 from IPython.frontend.qt.kernelmanager import QtKernelManager
MinRK
use connection files instead of ports to connect to kernels...
r4958 from IPython.utils.path import filefind
MinRK
py3compat pass on Session.key...
r4967 from IPython.utils.py3compat import str_to_bytes
MinRK
QtConsole now uses newapp
r3971 from IPython.utils.traitlets import (
MinRK
add confirm_exit option to qtconsole to suppress exit dialog
r3983 Dict, List, Unicode, Int, CaselessStrEnum, CBool, Any
MinRK
QtConsole now uses newapp
r3971 )
from IPython.zmq.ipkernel import (
flags as ipkernel_flags,
aliases as ipkernel_aliases,
IPKernelApp
)
MinRK
enable HMAC message signing by default in kernels...
r4962 from IPython.zmq.session import Session, default_secure
MinRK
QtConsole now uses newapp
r3971 from IPython.zmq.zmqshell import ZMQInteractiveShell
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 #-----------------------------------------------------------------------------
MinRK
Possible fix for GH-169
r3144 # Network Constants
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 #-----------------------------------------------------------------------------
MinRK
Possible fix for GH-169
r3144 from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS
epatters
Added arguments to the Qt console frontend script for connecting to an existing kernel and for specifying an IP and specific ports.
r2823
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 #-----------------------------------------------------------------------------
Brian Granger
More work on adding examples to help strings.
r4216 # Globals
#-----------------------------------------------------------------------------
_examples = """
ipython qtconsole # start the qtconsole
ipython qtconsole --pylab=inline # start with pylab in inline plotting mode
"""
#-----------------------------------------------------------------------------
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 # Classes
#-----------------------------------------------------------------------------
class MainWindow(QtGui.QMainWindow):
#---------------------------------------------------------------------------
# 'object' interface
#---------------------------------------------------------------------------
Matthias BUSSONNIER
create menu bar on OSX with some action...
r5027
MinRK
add confirm_exit option to qtconsole to suppress exit dialog
r3983 def __init__(self, app, frontend, existing=False, may_close=True,
confirm_exit=True):
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 """ Create a MainWindow for the specified FrontendWidget.
MinRK
review fixes
r3100
MinRK
comment/doc logic cleanup
r3105 The app is passed as an argument to allow for different
closing behavior depending on whether we are the Kernel's parent.
MinRK
prevent remote frontends from closing the kernel
r3142 If existing is True, then this Console does not own the Kernel.
If may_close is True, then this Console is permitted to close the kernel
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 """
Matthias BUSSONNIER
trying to move closing logic on a tab basis
r5037
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 super(MainWindow, self).__init__()
MinRK
changed close Console behavior to leave Kernel alive
r3104 self._app = app
Matthias BUSSONNIER
add fullscreen support for QtConsole throught shortcut...
r4817
Matthias BUSSONNIER
decamelCaseify : tabWidget -> tab_widget
r5047 self.tab_widget = QtGui.QTabWidget(self)
self.tab_widget.setDocumentMode(True)
self.tab_widget.setTabsClosable(True)
Matthias BUSSONNIER
decamelcasify : closeTab close_tab
r5048 self.tab_widget.tabCloseRequested[int].connect(self.close_tab)
Matthias BUSSONNIER
tab management new/existing kernel....
r5035
Matthias BUSSONNIER
decamelCaseify : tabWidget -> tab_widget
r5047 self.setCentralWidget(self.tab_widget)
Matthias BUSSONNIER
decamelcasify: 3 more changes
r5049 self.update_tab_bar_visibility()
Matthias BUSSONNIER
tab management new/existing kernel....
r5035
Matthias BUSSONNIER
decamelcasify: 3 more changes
r5049 def update_tab_bar_visibility(self):
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 """ update visibility of the tabBar depending of the number of tab
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 0 or 1 tab, tabBar hidden
2+ tabs, tabBar visible
send a self.close if number of tab ==0
Matthias BUSSONNIER
tab management new/existing kernel....
r5035
need to be called explicitely, or be connected to tabInserted/tabRemoved
"""
Matthias BUSSONNIER
decamelCaseify : tabWidget -> tab_widget
r5047 if self.tab_widget.count() <= 1:
self.tab_widget.tabBar().setVisible(False)
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 else:
Matthias BUSSONNIER
decamelCaseify : tabWidget -> tab_widget
r5047 self.tab_widget.tabBar().setVisible(True)
if self.tab_widget.count()==0 :
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 self.close()
Matthias BUSSONNIER
tab management new/existing kernel....
r5035
Matthias BUSSONNIER
trying to move closing logic on a tab basis
r5037 @property
Matthias BUSSONNIER
decamelcase : activeFrontend active_frontend
r5050 def active_frontend(self):
Matthias BUSSONNIER
decamelCaseify : tabWidget -> tab_widget
r5047 return self.tab_widget.currentWidget()
Matthias BUSSONNIER
tab management new/existing kernel....
r5035
Matthias BUSSONNIER
decamelcasify: a few more
r5051 def close_tab(self,current_tab):
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 """ Called when you need to try to close a tab.
Matthias BUSSONNIER
tab management new/existing kernel....
r5035
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 It takes the number of the tab to be closed as argument, or a referece
to the wiget insite this tab
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 """
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038
# let's be sure "tab" and "closing widget are respectivey the index of the tab to close
# and a reference to the trontend to close
Matthias BUSSONNIER
decamelcasify: a few more
r5051 if type(current_tab) is not int :
current_tab = self.tab_widget.indexOf(current_tab)
closing_widget=self.tab_widget.widget(current_tab)
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038
# when trying to be closed, widget might re-send a request to be closed again, but will
# be deleted when event will be processed. So need to check that widget still exist and
# skip if not. One example of this is when 'exit' is send in a slave tab. 'exit' will be
# re-send by this fonction on the master widget, which ask all slaves widget to exit
if closing_widget==None:
return
#get a list of all wwidget not owning the kernel.
Matthias BUSSONNIER
a few more deCamelCasification
r5052 slave_tabs=self.find_slaves_tabs(closing_widget)
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038
Matthias BUSSONNIER
trying to move closing logic on a tab basis
r5037 keepkernel = None #Use the prompt by default
if hasattr(closing_widget,'_keep_kernel_on_exit'): #set by exit magic
keepkernel = closing_widget._keep_kernel_on_exit
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 # If signal sent by exist magic (_keep_kernel_on_exit, exist and not None)
# we set local slave tabs._hidden to True to avoit prompting for kernel
# restart when they litt get the signal. and the "forward" the 'exit'
# to the main win
if keepkernel is not None:
Matthias BUSSONNIER
decamelcasify: a few more
r5051 for tab in slave_tabs:
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 tab._hidden = True
Matthias BUSSONNIER
decamelcasify: a few more
r5051 if closing_widget in slave_tabs :
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 try :
Matthias BUSSONNIER
decamelcasify: a few more
r5051 self.find_master_tab(closing_widget).execute('exit')
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 except AttributeError:
self.log.info("Master already closed or not local, closing only current tab")
Matthias BUSSONNIER
decamelcasify: a few more
r5051 self.tab_widget.removeTab(current_tab)
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 return
Matthias BUSSONNIER
trying to move closing logic on a tab basis
r5037
kernel_manager = closing_widget.kernel_manager
if keepkernel is None and not closing_widget._confirm_exit:
# don't prompt, just terminate the kernel if we own it
# or leave it alone if we don't
keepkernel = not closing_widget._existing
if keepkernel is None: #show prompt
if kernel_manager and kernel_manager.channels_running:
title = self.window().windowTitle()
cancel = QtGui.QMessageBox.Cancel
okay = QtGui.QMessageBox.Ok
if closing_widget._may_close:
Matthias BUSSONNIER
decamelcasify: a few more
r5051 msg = "You are closing the tab : "+'"'+self.tab_widget.tabText(current_tab)+'"'
Matthias BUSSONNIER
trying to move closing logic on a tab basis
r5037 info = "Would you like to quit the Kernel and all attached Consoles as well?"
justthis = QtGui.QPushButton("&No, just this Console", self)
justthis.setShortcut('N')
closeall = QtGui.QPushButton("&Yes, quit everything", self)
closeall.setShortcut('Y')
box = QtGui.QMessageBox(QtGui.QMessageBox.Question,
title, msg)
box.setInformativeText(info)
box.addButton(cancel)
box.addButton(justthis, QtGui.QMessageBox.NoRole)
box.addButton(closeall, QtGui.QMessageBox.YesRole)
box.setDefaultButton(closeall)
box.setEscapeButton(cancel)
Matthias BUSSONNIER
use svg icon also for dialog box....
r5055 pixmap = QtGui.QPixmap(self._app.icon.pixmap(QtCore.QSize(64,64)))
box.setIconPixmap(pixmap)
Matthias BUSSONNIER
trying to move closing logic on a tab basis
r5037 reply = box.exec_()
if reply == 1: # close All
Matthias BUSSONNIER
decamelcasify: a few more
r5051 for slave in slave_tabs:
Matthias BUSSONNIER
decamelCaseify : tabWidget -> tab_widget
r5047 self.tab_widget.removeTab(self.tab_widget.indexOf(slave))
Matthias BUSSONNIER
remove duplicate function "pasteMagic", and change code not to use it
r5046 closing_widget.execute("exit")
Matthias BUSSONNIER
decamelcasify: a few more
r5051 self.tab_widget.removeTab(current_tab)
Matthias BUSSONNIER
trying to move closing logic on a tab basis
r5037 elif reply == 0: # close Console
if not closing_widget._existing:
# Have kernel: don't quit, just close the window
Matthias BUSSONNIER
don't quit if asked once not to shutdown a kernel
r5045 self._app.setQuitOnLastWindowClosed(False)
Matthias BUSSONNIER
remove duplicate function "pasteMagic", and change code not to use it
r5046 closing_widget.execute("exit True")
Matthias BUSSONNIER
trying to move closing logic on a tab basis
r5037 else:
reply = QtGui.QMessageBox.question(self, title,
"Are you sure you want to close this Console?"+
"\nThe Kernel and other Consoles will remain active.",
okay|cancel,
defaultButton=okay
)
if reply == okay:
Matthias BUSSONNIER
decamelcasify: a few more
r5051 self.tab_widget.removeTab(current_tab)
Matthias BUSSONNIER
trying to move closing logic on a tab basis
r5037 elif keepkernel: #close console but leave kernel running (no prompt)
if kernel_manager and kernel_manager.channels_running:
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 if not closing_widget._existing:
Matthias BUSSONNIER
trying to move closing logic on a tab basis
r5037 # I have the kernel: don't quit, just close the window
Matthias BUSSONNIER
decamelcasify: a few more
r5051 self.tab_widget.removeTab(current_tab)
Matthias BUSSONNIER
trying to move closing logic on a tab basis
r5037 else: #close console and kernel (no prompt)
if kernel_manager and kernel_manager.channels_running:
Matthias BUSSONNIER
decamelcasify: a few more
r5051 for slave in slave_tabs:
Matthias BUSSONNIER
decamelCaseify : tabWidget -> tab_widget
r5047 self.tab_widget.removeTab(self.tab_widget.indexOf(slave))
Matthias BUSSONNIER
decamelcasify: a few more
r5051 self.tab_widget.removeTab(current_tab)
Matthias BUSSONNIER
trying to move closing logic on a tab basis
r5037 kernel_manager.shutdown_kernel()
Matthias BUSSONNIER
decamelcasify: 3 more changes
r5049 self.update_tab_bar_visibility()
Matthias BUSSONNIER
tab management new/existing kernel....
r5035
Matthias BUSSONNIER
decamelcasify: a few more
r5051 def add_tab_with_frontend(self,frontend,name=None):
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 """ insert a tab with a given frontend in the tab bar, and give it a name
"""
if not name:
Matthias BUSSONNIER
decamelCaseify : tabWidget -> tab_widget
r5047 name=str('kernel '+str(self.tab_widget.count()))
self.tab_widget.addTab(frontend,name)
Matthias BUSSONNIER
decamelcasify: 3 more changes
r5049 self.update_tab_bar_visibility()
Matthias BUSSONNIER
decamelcasify: a few more
r5051 self.make_frontend_visible(frontend)
Matthias BUSSONNIER
decamelcasify : closeTab close_tab
r5048 frontend.exit_requested.connect(self.close_tab)
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038
Matthias BUSSONNIER
decamelcasify: 3 more changes
r5049 def next_tab(self):
Matthias BUSSONNIER
decamelCaseify : tabWidget -> tab_widget
r5047 self.tab_widget.setCurrentIndex((self.tab_widget.currentIndex()+1))
Matthias BUSSONNIER
Add Shortcut Next/Previous tab
r5042
Matthias BUSSONNIER
decamelcasify: 3 more changes
r5049 def prev_tab(self):
Matthias BUSSONNIER
decamelCaseify : tabWidget -> tab_widget
r5047 self.tab_widget.setCurrentIndex((self.tab_widget.currentIndex()-1))
Matthias BUSSONNIER
Add Shortcut Next/Previous tab
r5042
Matthias BUSSONNIER
decamelcasify: a few more
r5051 def make_frontend_visible(self,frontend):
Matthias BUSSONNIER
a few more deCamelCasification
r5052 widget_index=self.tab_widget.indexOf(frontend)
if widget_index > 0 :
self.tab_widget.setCurrentIndex(widget_index)
Matthias BUSSONNIER
New tab on focus when created
r5041
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 def find_master_tab(self,tab,as_list=False):
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 """
Try to return the frontend that own the kernel attached to the given widget/tab.
Only find frontend owed by the current application. Selection
based on port of the kernel, might be inacurate if several kernel
on different ip use same port number.
This fonction does the conversion tabNumber/widget if needed.
Might return None if no master widget (non local kernel)
Will crash IPython if more than 1 masterWidget
When asList set to True, always return a list of widget(s) owning
the kernel. The list might be empty or containing several Widget.
"""
#convert from/to int/richIpythonWidget if needed
if type(tab) == int:
Matthias BUSSONNIER
decamelCaseify : tabWidget -> tab_widget
r5047 tab = self.tab_widget.widget(tab)
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 km=tab.kernel_manager;
#build list of all widgets
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 widget_list = [self.tab_widget.widget(i) for i in range(self.tab_widget.count())]
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038
# widget that are candidate to be the owner of the kernel does have all the same port of the curent widget
# And should have a _may_close attribute
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 filtred_widget_list = [ widget for widget in widget_list if
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 widget.kernel_manager.shell_address == km.shell_address and
widget.kernel_manager.sub_address == km.sub_address and
widget.kernel_manager.stdin_address == km.stdin_address and
widget.kernel_manager.hb_address == km.hb_address and
hasattr(widget,'_may_close') ]
# the master widget is the one that may close the kernel
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 master_widget= [ widget for widget in filtred_widget_list if widget._may_close]
if as_list:
return master_widget
assert(len(master_widget)<=1 )
if len(master_widget)==0:
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 return None
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 return master_widget[0]
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038
Matthias BUSSONNIER
a few more deCamelCasification
r5052 def find_slaves_tabs(self,tab):
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 """
Try to return all the frontend that do not own the kernel attached to the given widget/tab.
Only find frontend owed by the current application. Selection
based on port of the kernel, might be innacurate if several kernel
on different ip use same port number.
This fonction does the conversion tabNumber/widget if needed.
"""
#convert from/to int/richIpythonWidget if needed
if type(tab) == int:
Matthias BUSSONNIER
decamelCaseify : tabWidget -> tab_widget
r5047 tab = self.tab_widget.widget(tab)
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 km=tab.kernel_manager;
#build list of all widgets
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 widget_list = [self.tab_widget.widget(i) for i in range(self.tab_widget.count())]
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038
# widget that are candidate not to be the owner of the kernel does have all the same port of the curent widget
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 filtered_widget_list = ( widget for widget in widget_list if
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 widget.kernel_manager.shell_address == km.shell_address and
widget.kernel_manager.sub_address == km.sub_address and
widget.kernel_manager.stdin_address == km.stdin_address and
widget.kernel_manager.hb_address == km.hb_address)
# Get a list of all widget owning the same kernel and removed it from
# the previous cadidate. (better using sets ?)
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 master_widget_list = self.find_master_tab(tab,as_list=True)
slave_list = [widget for widget in filtered_widget_list if widget not in master_widget_list]
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 return slave_list
Matthias BUSSONNIER
tab management new/existing kernel....
r5035
Matthias BUSSONNIER
Just indent a commentary with the right numbur of tabs and re-wrap it
r5034 # MenuBar is always present on Mac Os, so let's populate it with possible
# action, don't do it on other platform as some user might not want the
# menu bar, or give them an option to remove it
Matthias BUSSONNIER
a few more deCamelCasification
r5052 def init_menu_bar(self):
Matthias BUSSONNIER
disable some QAction by default, remove OSX only, wrap in try/except
r5031 #create menu in the order they should appear in the menu bar
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 self.file_menu = self.menuBar().addMenu("&File")
self.edit_menu = self.menuBar().addMenu("&Edit")
self.font_menu = self.menuBar().addMenu("F&ont")
self.window_menu = self.menuBar().addMenu("&Window")
self.magic_menu = self.menuBar().addMenu("&Magic")
Matthias BUSSONNIER
Create all_magic_menu. use webbrowser to open url
r5059 self.all_magic_menu = self.magic_menu.addMenu("&All Magic")
Matthias BUSSONNIER
disable some QAction by default, remove OSX only, wrap in try/except
r5031
# please keep the Help menu in Mac Os even if empty. It will
# automatically contain a search field to search inside menus and
# please keep it spelled in English, as long as Qt Doesn't support
# a QAction.MenuRole like HelpMenuRole otherwise it will loose
# this search field fonctionnality
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 self.help_menu = self.menuBar().addMenu("&Help")
Matthias BUSSONNIER
disable some QAction by default, remove OSX only, wrap in try/except
r5031
# sould wrap every line of the following block into a try/except,
# as we are not sure of instanciating a _frontend which support all
# theses actions, but there might be a better way
Matthias BUSSONNIER
unwrap adding action from try/except, add %guiref and '?' in help menu
r5057 self.print_action = QtGui.QAction("&Print",
self,
shortcut="Ctrl+P",
triggered=self.print_action_active_frontend)
self.file_menu.addAction(self.print_action)
self.export_action=QtGui.QAction("E&xport",
self,
shortcut="Ctrl+S",
triggered=self.export_action_active_frontend
)
self.file_menu.addAction(self.export_action)
self.select_all_action = QtGui.QAction("Select &All",
self,
shortcut="Ctrl+A",
triggered=self.select_all_active_frontend
)
self.file_menu.addAction(self.select_all_action)
self.undo_action = QtGui.QAction("&Undo",
self,
shortcut="Ctrl+Z",
statusTip="Undo last action if possible",
triggered=self.undo_active_frontend
)
self.edit_menu.addAction(self.undo_action)
self.redo_action = QtGui.QAction("&Redo",
self,
shortcut="Ctrl+Shift+Z",
statusTip="Redo last action if possible",
triggered=self.redo_active_frontend)
self.edit_menu.addAction(self.redo_action)
self.increase_font_size = QtGui.QAction("&Increase Font Size",
self,
shortcut="Ctrl++",
triggered=self.increase_font_size_active_frontend
)
self.font_menu.addAction(self.increase_font_size)
self.decrease_font_size = QtGui.QAction("&Decrease Font Size",
self,
shortcut="Ctrl+-",
triggered=self.decrease_font_size_active_frontend
)
self.font_menu.addAction(self.decrease_font_size)
self.reset_font_size = QtGui.QAction("&Reset Font Size",
self,
shortcut="Ctrl+0",
triggered=self.reset_font_size_active_frontend
)
self.font_menu.addAction(self.reset_font_size)
self.reset_action = QtGui.QAction("&Reset",
self,
statusTip="Clear all varible from workspace",
triggered=self.reset_magic_active_frontend)
self.magic_menu.addAction(self.reset_action)
self.history_action = QtGui.QAction("&History",
self,
statusTip="show command history",
triggered=self.history_magic_active_frontend)
self.magic_menu.addAction(self.history_action)
self.save_action = QtGui.QAction("E&xport History ",
self,
statusTip="Export History as Python File",
triggered=self.save_magic_active_frontend)
self.magic_menu.addAction(self.save_action)
self.clear_action = QtGui.QAction("&Clear",
self,
statusTip="Clear the console",
triggered=self.clear_magic_active_frontend)
self.magic_menu.addAction(self.clear_action)
self.who_action = QtGui.QAction("&Who",
self,
statusTip="List interactive variable",
triggered=self.who_magic_active_frontend)
self.magic_menu.addAction(self.who_action)
self.who_ls_action = QtGui.QAction("Wh&o ls",
self,
statusTip="Return a list of interactive variable",
triggered=self.who_ls_magic_active_frontend)
self.magic_menu.addAction(self.who_ls_action)
self.whos_action = QtGui.QAction("Who&s",
self,
statusTip="List interactive variable with detail",
triggered=self.whos_magic_active_frontend)
self.magic_menu.addAction(self.whos_action)
Matthias BUSSONNIER
Create all_magic_menu. use webbrowser to open url
r5059 self.intro_active_frontend_action = QtGui.QAction("Intro",
Matthias BUSSONNIER
unwrap adding action from try/except, add %guiref and '?' in help menu
r5057 self,
triggered=self.intro_active_frontend
)
self.help_menu.addAction(self.intro_active_frontend_action)
Matthias BUSSONNIER
Create all_magic_menu. use webbrowser to open url
r5059 self.guiref_active_frontend_action = QtGui.QAction("Gui references",
Matthias BUSSONNIER
unwrap adding action from try/except, add %guiref and '?' in help menu
r5057 self,
triggered=self.guiref_active_frontend
)
self.help_menu.addAction(self.guiref_active_frontend_action)
Matthias BUSSONNIER
disable some QAction by default, remove OSX only, wrap in try/except
r5031
Matthias BUSSONNIER
Create all_magic_menu. use webbrowser to open url
r5059 self.quickref_active_frontend_action = QtGui.QAction("Quick references",
self,
triggered=self.quickref_active_frontend
)
self.help_menu.addAction(self.quickref_active_frontend_action)
magiclist=["%alias", "%autocall", "%automagic", "%bookmark", "%cd", "%clear",
"%colors", "%debug", "%dhist", "%dirs", "%doctest_mode", "%ed", "%edit", "%env", "%gui",
"%guiref", "%hist", "%history", "%install_default_config", "%install_profiles",
"%less", "%load_ext", "%loadpy", "%logoff", "%logon", "%logstart", "%logstate",
"%logstop", "%lsmagic", "%macro", "%magic", "%man", "%more", "%notebook", "%page",
"%pastebin", "%pdb", "%pdef", "%pdoc", "%pfile", "%pinfo", "%pinfo2", "%popd", "%pprint",
"%precision", "%profile", "%prun", "%psearch", "%psource", "%pushd", "%pwd", "%pycat",
"%pylab", "%quickref", "%recall", "%rehashx", "%reload_ext", "%rep", "%rerun",
"%reset", "%reset_selective", "%run", "%save", "%sc", "%sx", "%tb", "%time", "%timeit",
"%unalias", "%unload_ext", "%who", "%who_ls", "%whos", "%xdel", "%xmode"]
def make_dynamic_magic(i):
def inner_dynamic_magic():
self.active_frontend.execute(i)
inner_dynamic_magic.__name__ = "dynamics_magic_%s" % i
return inner_dynamic_magic
for magic in magiclist:
xaction = QtGui.QAction(magic,
self,
triggered=make_dynamic_magic(magic)
)
self.all_magic_menu.addAction(xaction)
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 def undo_active_frontend(self):
Matthias BUSSONNIER
decamelcase : activeFrontend active_frontend
r5050 self.active_frontend.undo()
Matthias BUSSONNIER
tab management new/existing kernel....
r5035
def redo_active_frontend(self):
Matthias BUSSONNIER
decamelcase : activeFrontend active_frontend
r5050 self.active_frontend.redo()
Matthias BUSSONNIER
add some blank lines
r5058
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 def reset_magic_active_frontend(self):
Matthias BUSSONNIER
decamelcase : activeFrontend active_frontend
r5050 self.active_frontend.execute("%reset")
Matthias BUSSONNIER
add some blank lines
r5058
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 def history_magic_active_frontend(self):
Matthias BUSSONNIER
decamelcase : activeFrontend active_frontend
r5050 self.active_frontend.history_magic()
Matthias BUSSONNIER
add some blank lines
r5058
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 def save_magic_active_frontend(self):
Matthias BUSSONNIER
decamelcase : activeFrontend active_frontend
r5050 self.active_frontend.save_magic()
Matthias BUSSONNIER
add some blank lines
r5058
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 def clear_magic_active_frontend(self):
Matthias BUSSONNIER
decamelcase : activeFrontend active_frontend
r5050 self.active_frontend.execute("%clear")
Matthias BUSSONNIER
add some blank lines
r5058
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 def who_magic_active_frontend(self):
Matthias BUSSONNIER
decamelcase : activeFrontend active_frontend
r5050 self.active_frontend.execute("%who")
Matthias BUSSONNIER
add some blank lines
r5058
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 def who_ls_magic_active_frontend(self):
Matthias BUSSONNIER
decamelcase : activeFrontend active_frontend
r5050 self.active_frontend.execute("%who_ls")
Matthias BUSSONNIER
add some blank lines
r5058
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 def whos_magic_active_frontend(self):
Matthias BUSSONNIER
decamelcase : activeFrontend active_frontend
r5050 self.active_frontend.execute("%whos")
Matthias BUSSONNIER
tab management new/existing kernel....
r5035
def print_action_active_frontend(self):
Matthias BUSSONNIER
decamelcase : activeFrontend active_frontend
r5050 self.active_frontend.print_action.trigger()
Matthias BUSSONNIER
tab management new/existing kernel....
r5035
def export_action_active_frontend(self):
Matthias BUSSONNIER
decamelcase : activeFrontend active_frontend
r5050 self.active_frontend.export_action.trigger()
Matthias BUSSONNIER
tab management new/existing kernel....
r5035
Matthias BUSSONNIER
Send all action to active front instead of first tab
r5036 def select_all_active_frontend(self):
Matthias BUSSONNIER
decamelcase : activeFrontend active_frontend
r5050 self.active_frontend.select_all_action.trigger()
Matthias BUSSONNIER
tab management new/existing kernel....
r5035
def increase_font_size_active_frontend(self):
Matthias BUSSONNIER
decamelcase : activeFrontend active_frontend
r5050 self.active_frontend.increase_font_size.trigger()
Matthias BUSSONNIER
add some blank lines
r5058
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 def decrease_font_size_active_frontend(self):
Matthias BUSSONNIER
decamelcase : activeFrontend active_frontend
r5050 self.active_frontend.decrease_font_size.trigger()
Matthias BUSSONNIER
add some blank lines
r5058
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 def reset_font_size_active_frontend(self):
Matthias BUSSONNIER
decamelcase : activeFrontend active_frontend
r5050 self.active_frontend.reset_font_size.trigger()
Matthias BUSSONNIER
unwrap adding action from try/except, add %guiref and '?' in help menu
r5057
def guiref_active_frontend(self):
self.active_frontend.execute("%guiref")
def intro_active_frontend(self):
self.active_frontend.execute("?")
Matthias BUSSONNIER
Create all_magic_menu. use webbrowser to open url
r5059
def quickref_active_frontend(self):
self.active_frontend.execute("%quickref")
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 #---------------------------------------------------------------------------
# QWidget interface
#---------------------------------------------------------------------------
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 def closeEvent(self, event):
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 """ Forward the close event to every tabs contained by the windows
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 """
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 # Do Not loop on the widget count as it change while closing
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 widget_list=[ self.tab_widget.widget(i) for i in range(self.tab_widget.count())]
for widget in widget_list:
Matthias BUSSONNIER
decamelcasify : closeTab close_tab
r5048 self.close_tab(widget)
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 event.accept()
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961
#-----------------------------------------------------------------------------
MinRK
QtConsole now uses newapp
r3971 # Aliases and Flags
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 #-----------------------------------------------------------------------------
epatters
* The SVG payload matplotlib backend now works....
r2758
MinRK
QtConsole now uses newapp
r3971 flags = dict(ipkernel_flags)
MinRK
command-line pass...
r4247 qt_flags = {
MinRK
use connection files instead of ports to connect to kernels...
r4958 'existing' : ({'IPythonQtConsoleApp' : {'existing' : 'kernel*.json'}},
"Connect to an existing kernel. If no argument specified, guess most recent"),
MinRK
QtConsole now uses newapp
r3971 'pure' : ({'IPythonQtConsoleApp' : {'pure' : True}},
"Use a pure Python kernel instead of an IPython kernel."),
'plain' : ({'ConsoleWidget' : {'kind' : 'plain'}},
"Disable rich text support."),
MinRK
command-line pass...
r4247 }
qt_flags.update(boolean_flag(
MinRK
add confirm_exit option to qtconsole to suppress exit dialog
r3983 'gui-completion', 'ConsoleWidget.gui_completion',
"use a GUI widget for tab completion",
"use plaintext output for completion"
))
MinRK
command-line pass...
r4247 qt_flags.update(boolean_flag(
MinRK
add confirm_exit option to qtconsole to suppress exit dialog
r3983 'confirm-exit', 'IPythonQtConsoleApp.confirm_exit',
"""Set to display confirmation dialog on exit. You can always use 'exit' or 'quit',
to force a direct exit without any confirmation.
""",
"""Don't prompt the user when exiting. This will terminate the kernel
if it is owned by the frontend, and leave it alive if it is external.
"""
))
MinRK
command-line pass...
r4247 flags.update(qt_flags)
MinRK
QtConsole now uses newapp
r3971
aliases = dict(ipkernel_aliases)
MinRK
command-line pass...
r4247 qt_aliases = dict(
MinRK
QtConsole now uses newapp
r3971 hb = 'IPythonQtConsoleApp.hb_port',
shell = 'IPythonQtConsoleApp.shell_port',
iopub = 'IPythonQtConsoleApp.iopub_port',
stdin = 'IPythonQtConsoleApp.stdin_port',
ip = 'IPythonQtConsoleApp.ip',
MinRK
use connection files instead of ports to connect to kernels...
r4958 existing = 'IPythonQtConsoleApp.existing',
f = 'IPythonQtConsoleApp.connection_file',
MinRK
QtConsole now uses newapp
r3971
style = 'IPythonWidget.syntax_style',
stylesheet = 'IPythonQtConsoleApp.stylesheet',
colors = 'ZMQInteractiveShell.colors',
editor = 'IPythonWidget.editor',
MinRK
fix qtconsole description...
r4222 paging = 'ConsoleWidget.paging',
MinRK
add ssh tunnel support to qtconsole
r4594 ssh = 'IPythonQtConsoleApp.sshserver',
MinRK
command-line pass...
r4247 )
aliases.update(qt_aliases)
MinRK
fix qtconsole description...
r4222
MinRK
QtConsole now uses newapp
r3971
#-----------------------------------------------------------------------------
# IPythonQtConsole
#-----------------------------------------------------------------------------
Brian Granger
Command line examples added for non-parallel apps.
r4215
MinRK
QtConsole now uses newapp
r3971 class IPythonQtConsoleApp(BaseIPythonApplication):
name = 'ipython-qtconsole'
default_config_file_name='ipython_config.py'
MinRK
code updates per review of PR #454
r4021
description = """
The IPython QtConsole.
This launches a Console-style application using Qt. It is not a full
MinRK
fix qtconsole description...
r4222 console, in that launched terminal subprocesses will not be able to accept
input.
The QtConsole supports various extra features beyond the Terminal IPython
shell, such as inline plotting with matplotlib, via:
ipython qtconsole --pylab=inline
MinRK
code updates per review of PR #454
r4021
MinRK
fix qtconsole description...
r4222 as well as saving your session as HTML, and printing the output.
MinRK
code updates per review of PR #454
r4021
"""
Brian Granger
More work on adding examples to help strings.
r4216 examples = _examples
Brian Granger
Command line examples added for non-parallel apps.
r4215
MinRK
finish plumbing config to Session objects...
r4015 classes = [IPKernelApp, IPythonWidget, ZMQInteractiveShell, ProfileDir, Session]
MinRK
QtConsole now uses newapp
r3971 flags = Dict(flags)
aliases = Dict(aliases)
kernel_argv = List(Unicode)
MinRK
create missing profiles by default in qtconsole...
r4265 # create requested profiles by default, if they don't exist:
auto_create = CBool(True)
MinRK
QtConsole now uses newapp
r3971 # connection info:
ip = Unicode(LOCALHOST, config=True,
help="""Set the kernel\'s IP address [default localhost].
If the IP address is something other than localhost, then
Consoles on other machines will be able to connect
to the Kernel, so be careful!"""
)
MinRK
add ssh tunnel support to qtconsole
r4594
sshserver = Unicode('', config=True,
help="""The SSH server to use to connect to the kernel.""")
sshkey = Unicode('', config=True,
help="""Path to the ssh key to use for logging in to the ssh server.""")
MinRK
QtConsole now uses newapp
r3971 hb_port = Int(0, config=True,
help="set the heartbeat port [default: random]")
shell_port = Int(0, config=True,
help="set the shell (XREP) port [default: random]")
iopub_port = Int(0, config=True,
help="set the iopub (PUB) port [default: random]")
stdin_port = Int(0, config=True,
help="set the stdin (XREQ) port [default: random]")
MinRK
use connection files instead of ports to connect to kernels...
r4958 connection_file = Unicode('', config=True,
help="""JSON file in which to store connection info [default: kernel-<pid>.json]
MinRK
QtConsole now uses newapp
r3971
MinRK
use connection files instead of ports to connect to kernels...
r4958 This file will contain the IP, ports, and authentication key needed to connect
clients to this kernel. By default, this file will be created in the security-dir
of the current profile, but can be specified by absolute path.
""")
def _connection_file_default(self):
return 'kernel-%i.json' % os.getpid()
existing = Unicode('', config=True,
help="""Connect to an already running kernel""")
MinRK
QtConsole now uses newapp
r3971
stylesheet = Unicode('', config=True,
help="path to a custom CSS stylesheet")
MinRK
add confirm_exit option to qtconsole to suppress exit dialog
r3983 pure = CBool(False, config=True,
MinRK
QtConsole now uses newapp
r3971 help="Use a pure Python kernel instead of an IPython kernel.")
MinRK
add confirm_exit option to qtconsole to suppress exit dialog
r3983 plain = CBool(False, config=True,
MinRK
update docs/default config for qtconsole
r3976 help="Use a plaintext widget instead of rich text (plain can't print/save).")
MinRK
QtConsole now uses newapp
r3971
def _pure_changed(self, name, old, new):
kind = 'plain' if self.plain else 'rich'
self.config.ConsoleWidget.kind = kind
if self.pure:
self.widget_factory = FrontendWidget
elif self.plain:
self.widget_factory = IPythonWidget
MinRK
color settings from ipythonqt propagate down to the ZMQInteractiveShell in the Kernel
r3173 else:
MinRK
QtConsole now uses newapp
r3971 self.widget_factory = RichIPythonWidget
_plain_changed = _pure_changed
MinRK
add confirm_exit option to qtconsole to suppress exit dialog
r3983 confirm_exit = CBool(True, config=True,
help="""
Set to display confirmation dialog on exit. You can always use 'exit' or 'quit',
to force a direct exit without any confirmation.""",
)
MinRK
QtConsole now uses newapp
r3971 # the factory for creating a widget
widget_factory = Any(RichIPythonWidget)
def parse_command_line(self, argv=None):
super(IPythonQtConsoleApp, self).parse_command_line(argv)
if argv is None:
argv = sys.argv[1:]
self.kernel_argv = list(argv) # copy
MinRK
add config file inheritance to kernelapp...
r4118 # kernel should inherit default config file from frontend
MinRK
disallow no-prefix `ipython foo=bar` argument style....
r4197 self.kernel_argv.append("--KernelApp.parent_appname='%s'"%self.name)
MinRK
fix kernel_argv scrubbing to cover args passed with space...
r4957 # Scrub frontend-specific flags
MinRK
QtConsole now uses newapp
r3971 for a in argv:
MinRK
fix kernel_argv scrubbing to cover args passed with space...
r4957 if a.startswith('-') and a.lstrip('-') in qt_flags:
self.kernel_argv.remove(a)
swallow_next = False
for a in argv:
if swallow_next:
self.kernel_argv.remove(a)
swallow_next = False
continue
MinRK
command-line pass...
r4247 if a.startswith('-'):
MinRK
fix typo in stripping kernel args in nb and qt...
r5015 split = a.lstrip('-').split('=')
MinRK
fix kernel_argv scrubbing to cover args passed with space...
r4957 alias = split[0]
if alias in qt_aliases:
MinRK
command-line pass...
r4247 self.kernel_argv.remove(a)
MinRK
fix kernel_argv scrubbing to cover args passed with space...
r4957 if len(split) == 1:
# alias passed with arg via space
swallow_next = True
MinRK
add ssh tunnel support to qtconsole
r4594
MinRK
use connection files instead of ports to connect to kernels...
r4958 def init_connection_file(self):
MinRK
cleanup pass on qtconsoleap per review...
r4969 """find the connection file, and load the info if found.
The current working directory and the current profile's security
directory will be searched for the file if it is not given by
absolute path.
When attempting to connect to an existing kernel and the `--existing`
argument does not match an existing file, it will be interpreted as a
fileglob, and the matching file in the current profile's security dir
with the latest access time will be used.
"""
MinRK
use connection files instead of ports to connect to kernels...
r4958 if self.existing:
try:
MinRK
split qtconsole's connection-file search into lib.kernel...
r4972 cf = find_connection_file(self.existing)
except Exception:
self.log.critical("Could not find existing kernel connection file %s", self.existing)
self.exit(1)
MinRK
use connection files instead of ports to connect to kernels...
r4958 self.log.info("Connecting to existing kernel: %s" % cf)
self.connection_file = cf
# should load_connection_file only be used for existing?
# as it is now, this allows reusing ports if an existing
# file is requested
MinRK
protect kernelapp/qtconsole from invalid connection files...
r4986 try:
self.load_connection_file()
except Exception:
self.log.error("Failed to load connection file: %r", self.connection_file, exc_info=True)
self.exit(1)
MinRK
use connection files instead of ports to connect to kernels...
r4958
def load_connection_file(self):
"""load ip/port/hmac config from JSON connection file"""
# this is identical to KernelApp.load_connection_file
# perhaps it can be centralized somewhere?
try:
fname = filefind(self.connection_file, ['.', self.profile_dir.security_dir])
except IOError:
self.log.debug("Connection File not found: %s", self.connection_file)
return
self.log.debug(u"Loading connection file %s", fname)
with open(fname) as f:
s = f.read()
cfg = json.loads(s)
if self.ip == LOCALHOST and 'ip' in cfg:
# not overridden by config or cl_args
self.ip = cfg['ip']
for channel in ('hb', 'shell', 'iopub', 'stdin'):
name = channel + '_port'
if getattr(self, name) == 0 and name in cfg:
# not overridden by config or cl_args
setattr(self, name, cfg[name])
if 'key' in cfg:
MinRK
py3compat pass on Session.key...
r4967 self.config.Session.key = str_to_bytes(cfg['key'])
MinRK
use connection files instead of ports to connect to kernels...
r4958
MinRK
add ssh tunnel support to qtconsole
r4594 def init_ssh(self):
MinRK
Remove IPython dependency in external.ssh...
r4595 """set up ssh tunnels, if needed."""
MinRK
add ssh tunnel support to qtconsole
r4594 if not self.sshserver and not self.sshkey:
return
if self.sshkey and not self.sshserver:
MinRK
split QtConsole.init_ssh into generic tunnel_to_kernel...
r4971 # specifying just the key implies that we are connecting directly
MinRK
add ssh tunnel support to qtconsole
r4594 self.sshserver = self.ip
MinRK
split QtConsole.init_ssh into generic tunnel_to_kernel...
r4971 self.ip = LOCALHOST
MinRK
add ssh tunnel support to qtconsole
r4594
MinRK
split QtConsole.init_ssh into generic tunnel_to_kernel...
r4971 # build connection dict for tunnels:
info = dict(ip=self.ip,
shell_port=self.shell_port,
iopub_port=self.iopub_port,
stdin_port=self.stdin_port,
hb_port=self.hb_port
)
MinRK
add ssh tunnel support to qtconsole
r4594
MinRK
split QtConsole.init_ssh into generic tunnel_to_kernel...
r4971 self.log.info("Forwarding connections to %s via %s"%(self.ip, self.sshserver))
MinRK
add ssh tunnel support to qtconsole
r4594
MinRK
split QtConsole.init_ssh into generic tunnel_to_kernel...
r4971 # tunnels return a new set of ports, which will be on localhost:
self.ip = LOCALHOST
try:
newports = tunnel_to_kernel(info, self.sshserver, self.sshkey)
except:
# even catch KeyboardInterrupt
self.log.error("Could not setup tunnels", exc_info=True)
self.exit(1)
MinRK
add ssh tunnel support to qtconsole
r4594
MinRK
split QtConsole.init_ssh into generic tunnel_to_kernel...
r4971 self.shell_port, self.iopub_port, self.stdin_port, self.hb_port = newports
MinRK
add ssh tunnel support to qtconsole
r4594
MinRK
allow reuse of connection file with ssh tunnels
r4961 cf = self.connection_file
base,ext = os.path.splitext(cf)
base = os.path.basename(base)
self.connection_file = os.path.basename(base)+'-ssh'+ext
self.log.critical("To connect another client via this tunnel, use:")
self.log.critical("--existing %s" % self.connection_file)
Paul Ivanov
Faciliate ssh tunnel sharing by announcing ports
r4846
MinRK
QtConsole now uses newapp
r3971 def init_kernel_manager(self):
# Don't let Qt or ZMQ swallow KeyboardInterupts.
signal.signal(signal.SIGINT, signal.SIG_DFL)
MinRK
use connection files instead of ports to connect to kernels...
r4958 sec = self.profile_dir.security_dir
try:
cf = filefind(self.connection_file, ['.', sec])
except IOError:
MinRK
cleanup pass on qtconsoleap per review...
r4969 # file might not exist
MinRK
use connection files instead of ports to connect to kernels...
r4958 if self.connection_file == os.path.basename(self.connection_file):
# just shortname, put it in security dir
cf = os.path.join(sec, self.connection_file)
else:
cf = self.connection_file
MinRK
QtConsole now uses newapp
r3971
# Create a KernelManager and start a kernel.
MinRK
use connection files instead of ports to connect to kernels...
r4958 self.kernel_manager = QtKernelManager(
ip=self.ip,
MinRK
KernelManager has port traits instead of multiple ip/port pairs...
r4956 shell_port=self.shell_port,
MinRK
fix remaining sub_port -> iopub_port in kernelmanager
r4959 iopub_port=self.iopub_port,
MinRK
KernelManager has port traits instead of multiple ip/port pairs...
r4956 stdin_port=self.stdin_port,
hb_port=self.hb_port,
MinRK
use connection files instead of ports to connect to kernels...
r4958 connection_file=cf,
MinRK
KernelManager has port traits instead of multiple ip/port pairs...
r4956 config=self.config,
MinRK
QtConsole now uses newapp
r3971 )
# start the kernel
if not self.existing:
MinRK
use connection files instead of ports to connect to kernels...
r4958 kwargs = dict(ipython=not self.pure)
MinRK
QtConsole now uses newapp
r3971 kwargs['extra_arguments'] = self.kernel_argv
self.kernel_manager.start_kernel(**kwargs)
MinRK
allow reuse of connection file with ssh tunnels
r4961 elif self.sshserver:
# ssh, write new connection file
self.kernel_manager.write_connection_file()
MinRK
QtConsole now uses newapp
r3971 self.kernel_manager.start_channels()
Matthias BUSSONNIER
decamelcasify: a few more
r5051 def create_tab_with_new_frontend(self):
Matthias BUSSONNIER
fx tab name and already existing kernel before application launch...
r5039 """ Create new tab attached to new kernel, launched on localhost.
"""
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 kernel_manager = QtKernelManager(
Matthias BUSSONNIER
fx tab name and already existing kernel before application launch...
r5039 shell_address=(LOCALHOST,0 ),
sub_address=(LOCALHOST, 0),
stdin_address=(LOCALHOST, 0),
hb_address=(LOCALHOST, 0),
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 config=self.config
)
# start the kernel
Matthias BUSSONNIER
fx tab name and already existing kernel before application launch...
r5039 kwargs = dict(ip=LOCALHOST, ipython=not self.pure)
kwargs['extra_arguments'] = self.kernel_argv
kernel_manager.start_kernel(**kwargs)
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 kernel_manager.start_channels()
Matthias BUSSONNIER
fx tab name and already existing kernel before application launch...
r5039 local_kernel = (not False) or self.ip in LOCAL_IPS
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 widget = self.widget_factory(config=self.config,
local_kernel=local_kernel)
widget.kernel_manager = kernel_manager
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 widget._existing=False;
Matthias BUSSONNIER
trying to move closing logic on a tab basis
r5037 widget._confirm_exit=True;
widget._may_close=True;
Matthias BUSSONNIER
decamelcasify: a few more
r5051 self.window.add_tab_with_frontend(widget)
Matthias BUSSONNIER
tab management new/existing kernel....
r5035
Matthias BUSSONNIER
decamelcasify: a few more
r5051 def create_tab_attached_to_current_tab_kernel(self):
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 current_widget = self.window.tab_widget.currentWidget()
current_widget_index = self.window.tab_widget.indexOf(current_widget)
current_widget.kernel_manager = current_widget.kernel_manager;
current_widget_name = self.window.tab_widget.tabText(current_widget_index);
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 kernel_manager = QtKernelManager(
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 shell_address = current_widget.kernel_manager.shell_address,
sub_address = current_widget.kernel_manager.sub_address,
stdin_address = current_widget.kernel_manager.stdin_address,
hb_address = current_widget.kernel_manager.hb_address,
Matthias BUSSONNIER
fx tab name and already existing kernel before application launch...
r5039 config = self.config
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 )
kernel_manager.start_channels()
local_kernel = (not self.existing) or self.ip in LOCAL_IPS
widget = self.widget_factory(config=self.config,
local_kernel=False)
Matthias BUSSONNIER
trying to move closing logic on a tab basis
r5037 widget._confirm_exit=True;
widget._may_close=False;
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 widget.kernel_manager = kernel_manager
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 self.window.add_tab_with_frontend(widget,name=str('('+current_widget_name+') slave'))
MinRK
QtConsole now uses newapp
r3971
def init_qt_elements(self):
# Create the widget.
self.app = QtGui.QApplication([])
Matthias BUSSONNIER
remove all binary trace from Icons, use directly SVG
r5053
base_path = os.path.abspath(os.path.dirname(__file__))
icon_path = os.path.join(base_path, 'resources', 'icon', 'IPythonConsole.svg')
Matthias BUSSONNIER
use svg icon also for dialog box....
r5055 self.app.icon = QtGui.QIcon(icon_path)
QtGui.QApplication.setWindowIcon(self.app.icon)
Matthias BUSSONNIER
Add icon to qtconsole app...
r5028
MinRK
QtConsole now uses newapp
r3971 local_kernel = (not self.existing) or self.ip in LOCAL_IPS
self.widget = self.widget_factory(config=self.config,
local_kernel=local_kernel)
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 self.widget._existing = self.existing;
self.widget._may_close = not self.existing;
self.widget._confirm_exit = not self.existing;
MinRK
QtConsole now uses newapp
r3971 self.widget.kernel_manager = self.kernel_manager
self.window = MainWindow(self.app, self.widget, self.existing,
MinRK
add confirm_exit option to qtconsole to suppress exit dialog
r3983 may_close=local_kernel,
confirm_exit=self.confirm_exit)
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 self.window.log = self.log
Matthias BUSSONNIER
decamelcasify: a few more
r5051 self.window.add_tab_with_frontend(self.widget)
Matthias BUSSONNIER
a few more deCamelCasification
r5052 self.window.init_menu_bar()
MinRK
QtConsole now uses newapp
r3971 self.window.setWindowTitle('Python' if self.pure else 'IPython')
def init_colors(self):
"""Configure the coloring of the widget"""
# Note: This will be dramatically simplified when colors
# are removed from the backend.
if self.pure:
# only IPythonWidget supports styling
return
# parse the colors arg down to current known labels
try:
colors = self.config.ZMQInteractiveShell.colors
except AttributeError:
colors = None
try:
style = self.config.IPythonWidget.colors
except AttributeError:
style = None
# find the value for colors:
if colors:
colors=colors.lower()
if colors in ('lightbg', 'light'):
colors='lightbg'
elif colors in ('dark', 'linux'):
colors='linux'
else:
colors='nocolor'
elif style:
if style=='bw':
colors='nocolor'
elif styles.dark_style(style):
colors='linux'
else:
colors='lightbg'
MinRK
color settings from ipythonqt propagate down to the ZMQInteractiveShell in the Kernel
r3173 else:
MinRK
QtConsole now uses newapp
r3971 colors=None
# Configure the style.
widget = self.widget
if style:
widget.style_sheet = styles.sheet_from_template(style, colors)
widget.syntax_style = style
MinRK
exposed pygments styles as ipythonqt options
r3170 widget._syntax_style_changed()
widget._style_sheet_changed()
MinRK
added --colors flag to ipythonqt
r3171 elif colors:
# use a default style
widget.set_default_style(colors=colors)
MinRK
exposed pygments styles as ipythonqt options
r3170 else:
# this is redundant for now, but allows the widget's
# defaults to change
MinRK
added --colors flag to ipythonqt
r3171 widget.set_default_style()
MinRK
exposed pygments styles as ipythonqt options
r3170
MinRK
QtConsole now uses newapp
r3971 if self.stylesheet:
MinRK
exposed pygments styles as ipythonqt options
r3170 # we got an expicit stylesheet
MinRK
QtConsole now uses newapp
r3971 if os.path.isfile(self.stylesheet):
with open(self.stylesheet) as f:
MinRK
exposed pygments styles as ipythonqt options
r3170 sheet = f.read()
widget.style_sheet = sheet
widget._style_sheet_changed()
else:
MinRK
QtConsole now uses newapp
r3971 raise IOError("Stylesheet %r not found."%self.stylesheet)
def initialize(self, argv=None):
super(IPythonQtConsoleApp, self).initialize(argv)
MinRK
use connection files instead of ports to connect to kernels...
r4958 self.init_connection_file()
MinRK
enable HMAC message signing by default in kernels...
r4962 default_secure(self.config)
MinRK
allow reuse of connection file with ssh tunnels
r4961 self.init_ssh()
MinRK
QtConsole now uses newapp
r3971 self.init_kernel_manager()
self.init_qt_elements()
self.init_colors()
Matthias BUSSONNIER
add fullscreen support for QtConsole throught shortcut...
r4817 self.init_window_shortcut()
def init_window_shortcut(self):
Matthias BUSSONNIER
decamelcasify: 3 more changes
r5049 self.prev_tab_act = QtGui.QAction("Pre&vious Tab",
Matthias BUSSONNIER
Add Shortcut Next/Previous tab
r5042 self.window,
shortcut="Ctrl+PgDown",
statusTip="Cahange to next tab",
Matthias BUSSONNIER
decamelcasify: 3 more changes
r5049 triggered=self.window.prev_tab)
Matthias BUSSONNIER
Add Shortcut Next/Previous tab
r5042
Matthias BUSSONNIER
decamelcasify: 3 more changes
r5049 self.next_tab_act = QtGui.QAction("Ne&xt Tab",
Matthias BUSSONNIER
Add Shortcut Next/Previous tab
r5042 self.window,
shortcut="Ctrl+PgUp",
statusTip="Cahange to next tab",
Matthias BUSSONNIER
decamelcasify: 3 more changes
r5049 triggered=self.window.next_tab)
Matthias BUSSONNIER
Add Shortcut Next/Previous tab
r5042
Matthias BUSSONNIER
Create Keyboard Accelerator for MenuBar
r5043 self.fullScreenAct = QtGui.QAction("&Full Screen",
Matthias BUSSONNIER
create menu bar on OSX with some action...
r5027 self.window,
shortcut="Ctrl+Meta+Space",
statusTip="Toggle between Fullscreen and Normal Size",
triggered=self.toggleFullScreen)
Matthias BUSSONNIER
Create Keyboard Accelerator for MenuBar
r5043 self.tabAndNewKernelAct =QtGui.QAction("Tab with &New kernel",
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 self.window,
shortcut="Ctrl+T",
Matthias BUSSONNIER
decamelcasify: a few more
r5051 triggered=self.create_tab_with_new_frontend)
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 self.window.window_menu.addAction(self.tabAndNewKernelAct)
Matthias BUSSONNIER
Create Keyboard Accelerator for MenuBar
r5043 self.tabSameKernalAct =QtGui.QAction("Tab with Sa&me kernel",
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 self.window,
shortcut="Ctrl+Shift+T",
Matthias BUSSONNIER
decamelcasify: a few more
r5051 triggered=self.create_tab_attached_to_current_tab_kernel)
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 self.window.window_menu.addAction(self.tabSameKernalAct)
self.window.window_menu.addSeparator()
Matthias BUSSONNIER
create menu bar on OSX with some action...
r5027
Matthias BUSSONNIER
move open online help to be on all plateform
r5056 self.onlineHelpAct = QtGui.QAction("Open Online &Help",
self.window,
triggered=self._open_online_help)
self.window.help_menu.addAction(self.onlineHelpAct)
Matthias BUSSONNIER
create menu bar on OSX with some action...
r5027 # creating shortcut in menubar only for Mac OS as I don't
# know the shortcut or if the windows manager assign it in
# other platform.
if sys.platform == 'darwin':
Matthias BUSSONNIER
Create Keyboard Accelerator for MenuBar
r5043 self.minimizeAct = QtGui.QAction("Mini&mize",
Matthias BUSSONNIER
create menu bar on OSX with some action...
r5027 self.window,
shortcut="Ctrl+m",
statusTip="Minimize the window/Restore Normal Size",
triggered=self.toggleMinimized)
Matthias BUSSONNIER
Create Keyboard Accelerator for MenuBar
r5043 self.maximizeAct = QtGui.QAction("Ma&ximize",
Matthias BUSSONNIER
create menu bar on OSX with some action...
r5027 self.window,
shortcut="Ctrl+Shift+M",
statusTip="Maximize the window/Restore Normal Size",
triggered=self.toggleMaximized)
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 self.window_menu = self.window.window_menu
Matthias BUSSONNIER
Add Shortcut Next/Previous tab
r5042
Matthias BUSSONNIER
one commit again of decamelcasify.
r5054 self.window_menu.addAction(self.next_tab_act)
self.window_menu.addAction(self.prev_tab_act)
self.window_menu.addSeparator()
self.window_menu.addAction(self.minimizeAct)
self.window_menu.addAction(self.maximizeAct)
self.window_menu.addSeparator()
self.window_menu.addAction(self.fullScreenAct)
Matthias BUSSONNIER
create menu bar on OSX with some action...
r5027
else:
# if we don't put it in a menu, we add it to the window so
# that it can still be triggerd by shortcut
self.window.addAction(self.fullScreenAct)
def toggleMinimized(self):
if not self.window.isMinimized():
self.window.showMinimized()
else:
self.window.showNormal()
def _open_online_help(self):
Matthias BUSSONNIER
Create all_magic_menu. use webbrowser to open url
r5059 filename="http://ipython.org/ipython-doc/stable/index.html"
webbrowser.open(filename, new=1, autoraise=True)
Matthias BUSSONNIER
create menu bar on OSX with some action...
r5027
def toggleMaximized(self):
if not self.window.isMaximized():
self.window.showMaximized()
else:
self.window.showNormal()
# Min/Max imizing while in full screen give a bug
# when going out of full screen, at least on OSX
Matthias BUSSONNIER
add fullscreen support for QtConsole throught shortcut...
r4817 def toggleFullScreen(self):
if not self.window.isFullScreen():
self.window.showFullScreen()
Matthias BUSSONNIER
create menu bar on OSX with some action...
r5027 if sys.platform == 'darwin':
self.maximizeAct.setEnabled(False)
self.minimizeAct.setEnabled(False)
Matthias BUSSONNIER
add fullscreen support for QtConsole throught shortcut...
r4817 else:
self.window.showNormal()
Matthias BUSSONNIER
create menu bar on OSX with some action...
r5027 if sys.platform == 'darwin':
self.maximizeAct.setEnabled(True)
self.minimizeAct.setEnabled(True)
MinRK
QtConsole now uses newapp
r3971
def start(self):
# draw the window
self.window.show()
MinRK
exposed pygments styles as ipythonqt options
r3170
MinRK
QtConsole now uses newapp
r3971 # Start the application main loop.
self.app.exec_()
epatters
* Tab completion now uses the correct cursor position....
r2841
MinRK
QtConsole now uses newapp
r3971 #-----------------------------------------------------------------------------
# Main entry point
#-----------------------------------------------------------------------------
def main():
app = IPythonQtConsoleApp()
app.initialize()
app.start()
epatters
* The SVG payload matplotlib backend now works....
r2758
if __name__ == '__main__':
main()