Skip to content

Commit

Permalink
tab management new/existing kernel.
Browse files Browse the repository at this point in the history
	working 2 kinds of tab
	with Ctrl+Shift+T -> tab attached on same kernel
	with Ctrl+T -> tab attached on new kernel

	closing event management is way far from the one of the mainWindow
	and "first tab" is still handeled differently as the other ones as some action
	are still attaches to it directly
  • Loading branch information
Carreau authored and fperez committed Oct 17, 2011
1 parent 3bdac69 commit eb0e7f3
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 27 deletions.
6 changes: 3 additions & 3 deletions IPython/frontend/qt/console/frontend_widget.py
Expand Up @@ -102,7 +102,7 @@ class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
executed = QtCore.Signal(object) executed = QtCore.Signal(object)


# Emitted when an exit request has been received from the kernel. # Emitted when an exit request has been received from the kernel.
exit_requested = QtCore.Signal() exit_requested = QtCore.Signal(object)


# Protected class variables. # Protected class variables.
_CallTipRequest = namedtuple('_CallTipRequest', ['id', 'pos']) _CallTipRequest = namedtuple('_CallTipRequest', ['id', 'pos'])
Expand Down Expand Up @@ -422,7 +422,7 @@ def _handle_shutdown_reply(self, msg):
"Close the Console?", "Close the Console?",
QtGui.QMessageBox.Yes,QtGui.QMessageBox.No) QtGui.QMessageBox.Yes,QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes: if reply == QtGui.QMessageBox.Yes:
sys.exit(0) self.exit_requested.emit(self)
else: else:
reply = QtGui.QMessageBox.question(self, title, reply = QtGui.QMessageBox.question(self, title,
"Kernel has been reset. Clear the Console?", "Kernel has been reset. Clear the Console?",
Expand Down Expand Up @@ -583,7 +583,7 @@ def _process_execute_error(self, msg):
if content['ename']=='SystemExit': if content['ename']=='SystemExit':
keepkernel = content['evalue']=='-k' or content['evalue']=='True' keepkernel = content['evalue']=='-k' or content['evalue']=='True'
self._keep_kernel_on_exit = keepkernel self._keep_kernel_on_exit = keepkernel
self.exit_requested.emit() self.exit_requested.emit(self)
else: else:
traceback = ''.join(content['traceback']) traceback = ''.join(content['traceback'])
self._append_plain_text(traceback) self._append_plain_text(traceback)
Expand Down
2 changes: 1 addition & 1 deletion IPython/frontend/qt/console/ipython_widget.py
Expand Up @@ -503,7 +503,7 @@ def _handle_payload_edit(self, item):


def _handle_payload_exit(self, item): def _handle_payload_exit(self, item):
self._keep_kernel_on_exit = item['keepkernel'] self._keep_kernel_on_exit = item['keepkernel']
self.exit_requested.emit() self.exit_requested.emit(self)


def _handle_payload_next_input(self, item): def _handle_payload_next_input(self, item):
self.input_buffer = dedent(item['text'].rstrip()) self.input_buffer = dedent(item['text'].rstrip())
Expand Down
197 changes: 174 additions & 23 deletions IPython/frontend/qt/console/qtconsoleapp.py
Expand Up @@ -97,8 +97,66 @@ def __init__(self, app, frontend, existing=False, may_close=True,
self._may_close = True self._may_close = True
self._frontend.exit_requested.connect(self.close) self._frontend.exit_requested.connect(self.close)
self._confirm_exit = confirm_exit self._confirm_exit = confirm_exit
self.setCentralWidget(frontend)


self.tabWidget = QtGui.QTabWidget(self)
self.tabWidget.setDocumentMode(True)
self.tabWidget.setTabsClosable(True)
self.tabWidget.addTab(frontend,"QtConsole1")
self.tabWidget.tabCloseRequested[int].connect(self.closetab)

self.setCentralWidget(self.tabWidget)
self.updateTabBarVisibility()

def updateTabBarVisibility(self):
""" update visibility of the tabBar depending of the number of tab
0 or 1 tab, tabBar hiddent
2+ tabs, tabbarHidden
need to be called explicitely, or be connected to tabInserted/tabRemoved
"""
if self.tabWidget.count() <= 1:
self.tabWidget.tabBar().setVisible(False)
else:
self.tabWidget.tabBar().setVisible(True)

def activeFrontend(self):
return self.tabWidget.currentWidget()

def closetab(self,tab):
""" Called when a user try to close a tab
It takes the number of the tab to be closed as argument, (does not for
now, but should) take care of whether or not shuting down the kernel
attached to the frontend
"""
print "closing tab",tab
try:
if self.tabWidget.widget(tab)._local_kernel:
kernel_manager = self.tabWidget.widget(tab).kernel_manager.shutdown_kernel()
else:
print "not owning the kernel"
except:
print "can't ask the kernel to shutdown"
#if self.tabWidget.count() == 1:
#self.close()
self.tabWidget.removeTab(tab)
self.updateTabBarVisibility()

def addTabWithFrontend(self,frontend,name=None):
""" insert a tab with a given frontend in the tab bar, and give it a name
"""
if not name:
name=str('no Name '+str(self.tabWidget.count()))
self.tabWidget.addTab(frontend,name)
self.updateTabBarVisibility()
frontend.exit_requested.connect(self.irequest)

def irequest(self,obj):
print "I request to exit",obj
print "which is tab:",self.tabWidget.indexOf(obj)
self.closetab(self.tabWidget.indexOf(obj))
# MenuBar is always present on Mac Os, so let's populate it with possible # 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 # 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 # menu bar, or give them an option to remove it
Expand All @@ -123,14 +181,24 @@ def initMenuBar(self):
# as we are not sure of instanciating a _frontend which support all # as we are not sure of instanciating a _frontend which support all
# theses actions, but there might be a better way # theses actions, but there might be a better way
try: try:
self.fileMenu.addAction(self._frontend.print_action) pass
self.print_action = QtGui.QAction("Print",
self,
shortcut="Ctrl+P",
triggered=self.undo_active_frontend)
self.fileMenu.addAction(self.print_action)
except AttributeError: except AttributeError:
print "trying to add unexisting action, skipping" print "trying to add unexisting action (print), skipping"


try: try:
self.fileMenu.addAction(self._frontend.export_action) self.export_action=QtGui.QAction("Export",
self,
shortcut="Ctrl+S",
triggered=self.export_action_active_frontend
)
self.fileMenu.addAction(self.export_action)
except AttributeError: except AttributeError:
print "trying to add unexisting action, skipping" print "trying to add unexisting action (Export), skipping"


try: try:
self.fileMenu.addAction(self._frontend.select_all_action) self.fileMenu.addAction(self._frontend.select_all_action)
Expand All @@ -142,42 +210,42 @@ def initMenuBar(self):
self, self,
shortcut="Ctrl+Z", shortcut="Ctrl+Z",
statusTip="Undo last action if possible", statusTip="Undo last action if possible",
triggered=self._frontend.undo) triggered=self.undo_active_frontend)


self.editMenu.addAction(self.undo_action) self.editMenu.addAction(self.undo_action)
except AttributeError: except AttributeError:
print "trying to add unexisting action, skipping" print "trying to add unexisting action (undo), skipping"


try: try:
self.redo_action = QtGui.QAction("Redo", self.redo_action = QtGui.QAction("Redo",
self, self,
shortcut="Ctrl+Shift+Z", shortcut="Ctrl+Shift+Z",
statusTip="Redo last action if possible", statusTip="Redo last action if possible",
triggered=self._frontend.redo) triggered=self.redo_active_frontend)
self.editMenu.addAction(self.redo_action) self.editMenu.addAction(self.redo_action)
except AttributeError: except AttributeError:
print "trying to add unexisting action, skipping" print "trying to add unexisting action(redo), skipping"


try: try:
self.fontMenu.addAction(self._frontend.increase_font_size) pass#self.fontMenu.addAction(self.increase_font_size_active_frontend)
except AttributeError: except AttributeError:
print "trying to add unexisting action, skipping" print "trying to add unexisting action (increase font size), skipping"


try: try:
self.fontMenu.addAction(self._frontend.decrease_font_size) pass#self.fontMenu.addAction(self.decrease_font_size_active_frontend)
except AttributeError: except AttributeError:
print "trying to add unexisting action, skipping" print "trying to add unexisting action (decrease font size), skipping"


try: try:
self.fontMenu.addAction(self._frontend.reset_font_size) pass#self.fontMenu.addAction(self.reset_font_size_active_frontend)
except AttributeError: except AttributeError:
print "trying to add unexisting action, skipping" print "trying to add unexisting action (reset font size), skipping"


try: try:
self.reset_action = QtGui.QAction("Reset", self.reset_action = QtGui.QAction("Reset",
self, self,
statusTip="Clear all varible from workspace", statusTip="Clear all varible from workspace",
triggered=self._frontend.reset_magic) triggered=self.reset_magic_active_frontend)
self.magicMenu.addAction(self.reset_action) self.magicMenu.addAction(self.reset_action)
except AttributeError: except AttributeError:
print "trying to add unexisting action (reset), skipping" print "trying to add unexisting action (reset), skipping"
Expand All @@ -186,7 +254,7 @@ def initMenuBar(self):
self.history_action = QtGui.QAction("History", self.history_action = QtGui.QAction("History",
self, self,
statusTip="show command history", statusTip="show command history",
triggered=self._frontend.history_magic) triggered=self.history_magic_active_frontend)
self.magicMenu.addAction(self.history_action) self.magicMenu.addAction(self.history_action)
except AttributeError: except AttributeError:
print "trying to add unexisting action (history), skipping" print "trying to add unexisting action (history), skipping"
Expand All @@ -195,7 +263,7 @@ def initMenuBar(self):
self.save_action = QtGui.QAction("Export History ", self.save_action = QtGui.QAction("Export History ",
self, self,
statusTip="Export History as Python File", statusTip="Export History as Python File",
triggered=self._frontend.save_magic) triggered=self.save_magic_active_frontend)
self.magicMenu.addAction(self.save_action) self.magicMenu.addAction(self.save_action)
except AttributeError: except AttributeError:
print "trying to add unexisting action (save), skipping" print "trying to add unexisting action (save), skipping"
Expand All @@ -204,7 +272,7 @@ def initMenuBar(self):
self.clear_action = QtGui.QAction("Clear", self.clear_action = QtGui.QAction("Clear",
self, self,
statusTip="Clear the console", statusTip="Clear the console",
triggered=self._frontend.clear_magic) triggered=self.clear_magic_active_frontend)
self.magicMenu.addAction(self.clear_action) self.magicMenu.addAction(self.clear_action)
except AttributeError: except AttributeError:
print "trying to add unexisting action, skipping" print "trying to add unexisting action, skipping"
Expand All @@ -213,7 +281,7 @@ def initMenuBar(self):
self.who_action = QtGui.QAction("Who", self.who_action = QtGui.QAction("Who",
self, self,
statusTip="List interactive variable", statusTip="List interactive variable",
triggered=self._frontend.who_magic) triggered=self.who_magic_active_frontend)
self.magicMenu.addAction(self.who_action) self.magicMenu.addAction(self.who_action)
except AttributeError: except AttributeError:
print "trying to add unexisting action (who), skipping" print "trying to add unexisting action (who), skipping"
Expand All @@ -222,7 +290,7 @@ def initMenuBar(self):
self.who_ls_action = QtGui.QAction("Who ls", self.who_ls_action = QtGui.QAction("Who ls",
self, self,
statusTip="Return a list of interactive variable", statusTip="Return a list of interactive variable",
triggered=self._frontend.who_ls_magic) triggered=self.who_ls_magic_active_frontend)
self.magicMenu.addAction(self.who_ls_action) self.magicMenu.addAction(self.who_ls_action)
except AttributeError: except AttributeError:
print "trying to add unexisting action (who_ls), skipping" print "trying to add unexisting action (who_ls), skipping"
Expand All @@ -231,12 +299,46 @@ def initMenuBar(self):
self.whos_action = QtGui.QAction("Whos", self.whos_action = QtGui.QAction("Whos",
self, self,
statusTip="List interactive variable with detail", statusTip="List interactive variable with detail",
triggered=self._frontend.whos_magic) triggered=self.whos_magic_active_frontend)
self.magicMenu.addAction(self.whos_action) self.magicMenu.addAction(self.whos_action)
except AttributeError: except AttributeError:
print "trying to add unexisting action (whos), skipping" print "trying to add unexisting action (whos), skipping"



def undo_active_frontend(self):
self.activeFrontend().undo()

def redo_active_frontend(self):
self.activeFrontend().redo()
def reset_magic_active_frontend(self):
self.activeFrontend().reset_magic()
def history_magic_active_frontend(self):
self.activeFrontend().history_magic()
def save_magic_active_frontend(self):
self.activeFrontend().save_magic()
def clear_magic_active_frontend(self):
self.activeFrontend().clear_magic()
def who_magic_active_frontend(self):
self.activeFrontend().who_magic()
def who_ls_magic_active_frontend(self):
self.activeFrontend().who_ls_magic()
def whos_magic_active_frontend(self):
self.activeFrontend().whos_magic()

def print_action_active_frontend(self):
self.activeFrontend().print_action()

def export_action_active_frontend(self):
self.activeFrontend().export_action()

def select_all_action_frontend(self):
self.activeFrontend().select_all_action()

def increase_font_size_active_frontend(self):
self.activeFrontend().increase_font_size()
def decrease_font_size_active_frontend(self):
self.activeFrontend().decrease_font_size()
def reset_font_size_active_frontend(self):
self.activeFrontend().reset_font_size()
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# QWidget interface # QWidget interface
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
Expand Down Expand Up @@ -617,6 +719,44 @@ def init_kernel_manager(self):
self.kernel_manager.write_connection_file() self.kernel_manager.write_connection_file()
self.kernel_manager.start_channels() self.kernel_manager.start_channels()


def createTabWithNewFrontend(self):
kernel_manager = QtKernelManager(
shell_address=(self.ip, self.shell_port),
sub_address=(self.ip, self.iopub_port),
stdin_address=(self.ip, self.stdin_port),
hb_address=(self.ip, self.hb_port),
config=self.config
)
# start the kernel
if not self.existing:
kwargs = dict(ip=self.ip, ipython=not self.pure)
kwargs['extra_arguments'] = self.kernel_argv
kernel_manager.start_kernel(**kwargs)
kernel_manager.start_channels()
local_kernel = (not self.existing) or self.ip in LOCAL_IPS
widget = self.widget_factory(config=self.config,
local_kernel=local_kernel)
widget.kernel_manager = kernel_manager
self.window.addTabWithFrontend(widget)

def createTabAttachedToCurrentTabKernel(self):
currentWidget=self.window.tabWidget.currentWidget()
currentWidgetIndex=self.window.tabWidget.indexOf(currentWidget)
ckm=currentWidget.kernel_manager;
cwname=self.window.tabWidget.tabText(currentWidgetIndex);
kernel_manager = QtKernelManager(
shell_address=ckm.shell_address,
sub_address=ckm.sub_address,
stdin_address=ckm.stdin_address,
hb_address=ckm.hb_address,
config=self.config
)
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)
widget.kernel_manager = kernel_manager
self.window.addTabWithFrontend(widget,name=str('('+cwname+') slave'))


def init_qt_elements(self): def init_qt_elements(self):
# Create the widget. # Create the widget.
Expand Down Expand Up @@ -716,6 +856,17 @@ def init_window_shortcut(self):
statusTip="Toggle between Fullscreen and Normal Size", statusTip="Toggle between Fullscreen and Normal Size",
triggered=self.toggleFullScreen) triggered=self.toggleFullScreen)


self.tabAndNewKernelAct =QtGui.QAction("Tab with New kernel",
self.window,
shortcut="Ctrl+T",
triggered=self.createTabWithNewFrontend)
self.window.windowMenu.addAction(self.tabAndNewKernelAct)
self.tabSameKernalAct =QtGui.QAction("Tab with Same kernel",
self.window,
shortcut="Ctrl+Shift+T",
triggered=self.createTabAttachedToCurrentTabKernel)
self.window.windowMenu.addAction(self.tabSameKernalAct)
self.window.windowMenu.addSeparator()


# creating shortcut in menubar only for Mac OS as I don't # creating shortcut in menubar only for Mac OS as I don't
# know the shortcut or if the windows manager assign it in # know the shortcut or if the windows manager assign it in
Expand Down

0 comments on commit eb0e7f3

Please sign in to comment.