Skip to content
This repository

Create menu bar for qtconsole #813

Closed
wants to merge 37 commits into from

6 participants

Matthias Bussonnier Thomas Kluyver Evan Patterson Fernando Perez Min RK David Warde-Farley
Matthias Bussonnier
Collaborator

Hi,
I've started hooking up some action of the qtconsole into a menubar.
As i'm not sure everybody would like a console with a menubar on top of the window,so i've made it OSX only for now (because on OSX you can't get rid of the menubar on top of the screen).

This is mainly a work in progress, and i send the pull request to ask for some advice and feedback.

My first questions are :

If I want to hook-up %autocall to a menu, as it is a 'two state' action I thought that a checkable action is the best option, but how can I get the current status send a signal if it is change ? I suppose the status is determined in the kernel , which don't run any Qt Code so no signal nor slot ?

Same for %save, I want the default value that prompt the range to the user to be 1-(end of current session)
but I don't find a way to access this number.

Maybe someone can enlighten my way...

Thank You.

Thomas Kluyver
Collaborator

Yes, the %autocall state is in the kernel, which isn't necessarily running Qt code. There was some discussion on PR #507 about publishing 'status change' messages from the kernel, which is what you'd need for this.

The length of the current session's history is len(get_ipython().history_manager.input_hist_raw).

With respect to menus, recent versions of Ubuntu also have an OS X style menubar at the top of the screen. I don't know anything about the protocols used to pull it out, but it's worth bearing in mind. I can test if you don't have an Ubuntu machine handy.

Matthias Bussonnier
Collaborator

Thank you for history length, I'll also read #507 to see if I can grab more information.

If i'm not wrong, Ubuntu menubar is automatically put on the top of the screen, but I don't see an easy way to test if IPython run on ubuntu with unity, and IMHO having a menubar should be an configurable option.

I'll be glad to have feedback with testing and first thought about the UI. Especially menu order. Does it feel natural, in the right place. For example, should the increase/decrease/restore font size be in a sub-menu...

I'm hoping to have some people in my lab drop matlab for (I)Python, and I know that User Interface is a great deal for them, and should be as natural as possible.

Thomas Kluyver
Collaborator

I'll knock out the platform test and have a go with the menubar later. If it's useful, it could make sense to enable it by default.

Evan Patterson
Collaborator

@Carreau, this is a great start. Thanks.

The actions that were added to ConsoleWidget and HistoryConsoleWidget need to be moved from the widget level to the application level. They could go into qtconsoleapp.py, but I think it would worth splitting the MainWindow class out of that file into, say, main_window.py, and then adding the actions there. This will prevent qtconsoleapp.py from growing too large.

I apologize for being so anal about this, but it's important to understand that the Qt console is both a library component and an application. Every time you add a new feature, you should ask yourself: "Is this feature core functionality that all developers using the widget will want, or is this feature application-specific and not something that all application builders will want?" If the former, the relevant code should go into ConsoleWidget, FrontendWidget, etc. as appropriate; otherwise, it should go into the application-level code.

Thanks again for the work!

Matthias Bussonnier
Collaborator

@epatters,

You're more involve in this than me, so you're better at knowing where to put the code, and I don't mind beeing corrected.

I don't really have an scheme on inheritance in my head but my thought was not to implement an action in a widget if i'm not sure the fonctionnality will be present.

(sorry, I cant find exactly how to say it in english, so i'll give an example, and don't hesitate to correct me if some sentences are incorrect)

As I'm not sure _frontend in MainWindow does have an 'history' , so I thought putting everything dealing with history the highest in the hierarchy where I know it will exist (ie HistoryConsoleWidget) . Also, some code might start messing with class internals (eg pasteMagic call the private member _keyboard_quit) , and so I thought it might be better not to add all action in qapplication. Also if there is some internal changes, definig the actions inside the widget have less chance to break something.

Of course, If you're concerned about interference with people using it as library; Maybe setting no shortcut with the action and disabling it by default might be a compromize. And those action will still be Availlable 'for free' if anyone subclass or need it.

Anyway, i'll bend to your will if you think all the code should be moved inside main_window.py.

Matthias Bussonnier
Collaborator

@takluyver, about history length (again sorry),
when you are actually wrinting in a console you can get the history length by executing len(get_ipython().history_manager.input_hist_raw)
but my question was more :
how do I get a IPython.zmq.zmqshell.ZMQInteractiveShell reference when I am actually in the code of the qt console (IPython/frontend/qt/console/console_widget.py for example)

Thomas Kluyver
Collaborator

You can't get a reference to the object, because the frontend is running in a separate process. You have to submit that expression to the kernel. You can use the user_expressions field on any execute_request. and interrogate the execute_reply. We might supply a more convenient way to do this in the future, but that's what should work now.

Matthias Bussonnier
Collaborator

@takluyver,
Thank you, with your indication and the help of the documentation, I was able to fetch the history length, and by default save the whole session.

Matthias Bussonnier
Collaborator

about splitting qtConsoleApp and mainWIndow into 2 files, is there a clean way to 'explain' it to git for the merging/rebasing to append without glitch ?

Evan Patterson
Collaborator

Don't worry about Git. It will either mark one of the new files as renamed from the old one (with modifications) or show two new files and one deleted file, depending upon the extent of the changes. In any case, you do not have to do anything special.

Matthias Bussonnier
Collaborator

Hi,
Still working on the qtconsole. I'm trying to add tabs to it, but i've a question.
IPython.frontent.qt.console.frontend_widget deal with shutdown_request adressed from another console attached to the same kernel by a sys.exit(0) ...which of course close all the tabs if you have several (and might close an application if it's using qtconsole as library ?)

Should we change it to a hook and deal with it at a higher level ?

Evan Patterson
Collaborator

@Carreau, you're absolutely right. FrontendWidget should not be implementing this logic, and it certainly shouldn't be calling sys.exit. We should move this to a higher level.

added some commits September 17, 2011
Matthias Bussonnier create menu bar on OSX with some action
	console_widget:
		modifie/create some QAction to be able to put it in menu bar
			-made print_action and export_action public
			-transform increase/decrease/rest front_size
			 to QAction
			-create qaction for undo/redo

	MainWindow
		Create the menubar with the following structure
		And link each menu with its action in console Widget
		File
		|__Print
		|__Save as XML
		|__Select ALL
		Edit
		|__Undo
		|__Redo
		Font
		|__Increase font size
		|__Decresae font size
		|__Restet Font size
		Window
		|__Minimize
		|__Maximize
		|__Full Screen
		Magic
		|__Reset
		|__History
		|__Export History
		|__Who
		|__Whos
		|__Who_ls
		Help
		|_Open online Help

		The 'Magic' Menu, execute %magic after 'exit_keyboard' and pasting
		'%magic'.  The 'Export History' menu prompt the user for a file name
		and a range before pasting `%save filename range`.

	This this also fix a bug in toggle full screen where
	Full Screen -> (try to) Minimizing -> Out Of Full Screen
	is broken (grey background for all screen), at least on OSX
b12bd0f
Matthias Bussonnier Add icon to qtconsole app
	It's clearly not definitive, as most of the file are not in the right
	location and icon should be graphically improved, so il will certainly be rebased later.
	But as it goes with UI improvemetn in the menubar I add it to this branch.

	Note: About the svg Icon, I've done it from scratch in inkscape, inspired by
	iTerm2 icon, which is under GPL
	the .icns file is OSX Specific.
2aca261
Matthias Bussonnier Fix last Commit Resources (Icones)
		Did export the wrong area with inkscape, making the Icons to Have the
		wrong aspect ratio once loaded in qt. Use this excuse to refine
		shadow/lightnig and general color
032a542
Matthias Bussonnier Improve 'save history' menu (%save)
	Real file chooser menu, get the current session history range by default.
	If the file already exist, the user will be prompted twice if he/she really
	want to be override the existing file ( by the gui, and the magic afterward)
	One might also to add the (-r) %save option into the gui.
aa1ba3b
Matthias Bussonnier disable some QAction by default, remove OSX only, wrap in try/except 4fcdef5
Matthias Bussonnier move some action in main windows as asked by @epatters.
	not all haves benn moves as i'm not sure yet how to handle some of them
786b811
Matthias Bussonnier move %history and %save action into mainwindow bf64f26
Matthias Bussonnier Just indent a commentary with the right numbur of tabs and re-wrap it 394a5b1
Matthias Bussonnier tab management new/existing kernel.
	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
b9cf9e4
Matthias Bussonnier Send all action to active front instead of first tab 6ee799b
Matthias Bussonnier trying to move closing logic on a tab basis 47eb2f2
Fernando Perez
Owner

Hey guys, just a quick note: I haven't followed the PR, but right now it doesn't merge cleanly anymore. Sorry about that, there's been enough churn on master lately that some PRs fell behind.

So this one needs a rebase before we can proceed further, let us know if you need a hand with that.

Unless you guys have decided you want to take a different approach altogether with a new PR, I'll leave that up to you. I just want to give you a heads-up b/c I'm starting to map out the landscape to plan for an 0.12 release, and un-mergeable PRs will be obviously an issue there.

Matthias Bussonnier
Collaborator

Yep, i've seen, and i've a new rebased branch on the 'fixing trailing space commit'. I can force push it.

I'm for now strugling with 'correct' tab management.
like for example if you have multiple tabs (1 master owning the kernel and N attached to the same) and close the owning tabs with all the attached tabs, it asks you N times "do you want to restart the kernel".
Of course there are way, but then some other behaviour get strange and i'm thinking of reworking tab management by keeping in mainWindow a map between frontends/kernels and who is owning what.

Won't have much time for now, but still thinking.

Thomas Kluyver
Collaborator

Off the top of my head, would it make sense to deal with a menubar for now, and look into adding tabs later?

What would the use case be for having N tabs attached to one kernel?

Matthias Bussonnier
Collaborator

If you want the menubar for 0.12, it's easier. Adding tabs change a lot of code because you need to send the action to the correct frontend even if the action is the same in the menu. That's why I thought of doing it, even if tabs may be deactivated. It foces me to write a good code that has less chances to break while adding 'only' tabs.

For the N tabs, personaly I'm using it in the way that i've some data loded on one kernel. I have the plots on 1 tab. A tab where I do some test/try some commands, and a tab where I actually do calculation on the data. Then if i'm looking for something in my history I can visually scroll up in the right tab. I would like later to be able to export/save the content/history of only one of the tabs for later use versus the history/content of the whole session.

Matthias Bussonnier
Collaborator

Hi, i've done a force push of a rebased branch.
It should merge without issues with the latest master.
I try my best not to change the current comportement when not using tabs.

The issues is that the 'first' tabs is handeld separately as it depends on the command line options.
A good idea might be to add a 'tab with custom flags' option and create it through this action.
And it is also the only one to go through the init_color.

I'm waiting for your feedback.

IPython/frontend/qt/console/application_rc.py
... ...
@@ -0,0 +1,21 @@
  1
+# -*- coding: utf-8 -*-
  2
+
  3
+# Resource object code
  4
+#
  5
+# Created: jeu. sept. 22 14:33:04 2011
  6
+#      by: The Resource Compiler for PySide (Qt v4.7.4)
  7
+#
  8
+# WARNING! All changes made in this file will be lost!
  9
+
  10
+from PySide import QtCore
2
Fernando Perez Owner
fperez added a note October 09, 2011

BTW, this can't be used as-is, as it introduces a hard dependency on PySide. All of our code must work with either pyqt or pyside, as controlled by the QT_API environment variable for user choice. If both are available, pyqt should still be preferred (more stable) unless overridden by QT_API, and if only one is available then that should be used. But there shouldn't be an open, hard dependency on pyside. You can see how the other qt-related files handle the imports for details.

Thomas Kluyver Collaborator

I think this can be handled by importing from IPython.external.qt (which handles selecting PyQt or PySide).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
IPython/frontend/qt/console/application_rc.py
... ...
@@ -0,0 +1,21 @@
  1
+# -*- coding: utf-8 -*-
  2
+
  3
+# Resource object code
  4
+#
  5
+# Created: jeu. sept. 22 14:33:04 2011
  6
+#      by: The Resource Compiler for PySide (Qt v4.7.4)
  7
+#
  8
+# WARNING! All changes made in this file will be lost!
6
Fernando Perez Owner
fperez added a note October 09, 2011

I'm also not fond at all of bundling what are effectively big binary blobs in our source tree... But I don't have real qt experience. @epatters, what's your take on this? This file (even if the pyside issue is fixed) makes me really uncomfortable.

Matthias Bussonnier Collaborator
Carreau added a note October 09, 2011

I would prefer directly importing something like a PNG or something into the code, but i'm not familiar enough with qt on How to find resources nor "compiled". I'm not sure either those files are in the right location.

Evan Patterson Collaborator
epatters added a note October 10, 2011

@Carreau, I think we should be able to skip not only the Qt resource file, but the PNG as well. Since we are already depending on SVG support, something like this should work:

base_path = os.path.abspath(os.path.dirname(__file__))
icon_path = os.path.join(base_path, 'resources', 'icon', 'IPythonConsole.svg')
icon = QtGui.QIcon(icon_path)
Matthias Bussonnier Collaborator
Carreau added a note October 11, 2011

That works perfectly !

Matthias Bussonnier Collaborator
Carreau added a note October 11, 2011

actually, some shadow casting does not appear with svg... maybe it's a specific inkscape feature, like blur or something.. not quite important.

Evan Patterson Collaborator
epatters added a note October 11, 2011

According to this:

http://doc.qt.nokia.com/stable/paintsystem-images.html

Qt supports the "static" features of SVG 1.2 Tiny. Perhaps Inkscape is using some feature outside of this subset? But like you said, it's not that important.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Fernando Perez
Owner

Just a note here: if we end up deciding that the binary files are to be avoided, we'll want to rebase this PR before merging, wiping out those commits from the history.

Fernando Perez
Owner

A bit more feedback, now that I got it running with pyside:

  • if I connect to an existing kernel, then new tabs stay with that kernel even if you request a new kernel.
  • the menu entries should have keyboard accelerators.
  • tabs should be named 'Kernel 0', 'kernel 1', etc, instead of 'no name 0'...
  • Ctrl pgup/pgdown should move between tabs, it's the standard web browser tab-navigation key binding.

But overall this is looking great! This may need more fine-tuning, but it's definitely looking excellent and useful. Thanks for the great work, and with a bit more polish, as well as @epatters' guidance on the architecture, I'm sure it will be a great contribution.

Matthias Bussonnier
Collaborator

1.) Right missed that, correction on it's way.
2.) I'll do it, but I'm not sure it will be consistent with other program..
3.) fix also on it's way.
4.) i'll add that and maybe something like setting the new tab as active. same while closing.

I'll also take a look at the qt resources files.

added some commits October 10, 2011
Matthias Bussonnier fx tab name and already existing kernel before application launch
	tabs are now names "kernel i"

	starting the application with --existing ... use to attached all new tabs
	to the same kernel. New tab attached to new kernel now start a local kernel
	on random port and connect to it.

	rename some variable to be more explicit.
68621a1
Matthias Bussonnier Fix: crash when cancel closing slave tab 1eac761
Matthias Bussonnier New tab on focus when created 970facc
Matthias Bussonnier Add Shortcut Next/Previous tab 8171dad
Matthias Bussonnier Create Keyboard Accelerator for MenuBar 6a5c149
Matthias Bussonnier Break Hard dependency to Pyside ? 60cdd23
Matthias Bussonnier don't quit if asked once not to shutdown a kernel 4d22e9a
Matthias Bussonnier
Collaborator

Could you try 60cdd23 , I've issues with PyQt4/matplotlib on my side and can't test if it's really avoiding dependency on PySide.

Also Mac os doesn't have Keyboard Accelerator, So if you can test and tell me if it feel consistent with other applications.

Note that for now, the last closing widget might not own the last existing kernel.
Do you think we should allow the last frontend to be closed with kernels still running or prompt the user with a "close all remainig kernel?". Maybe add more kernel managing option from the menu bar when there are no more frontend attached to it ?

IPython/frontend/qt/console/console_widget.py
@@ -579,12 +602,14 @@ class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):
579 602
 
580 603
     font = property(_get_font, _set_font)
581 604
 
582  
-    def paste(self, mode=QtGui.QClipboard.Clipboard):
583  
-        """ Paste the contents of the clipboard into the input region.
  605
+    def paste(self, mode=QtGui.QClipboard.Clipboard,text=None):
2
Evan Patterson Collaborator
epatters added a note October 10, 2011

Inserting arbitrary text into the input buffer is not 'pasting', so that functionality does not belong here. Since it looks like you're using this only internally, you could just call the protected method _insert_plain_text_into_buffer directly. That said, I think you want to replace the input buffer instead of inserting into it in the instances where you're calling pasteMagic, e.g. in exit_magic, who_magic, etc. In that case, you can just use self.input_buffer = text.

Evan Patterson Collaborator
epatters added a note October 10, 2011

Actually, that last sentence is not quite right. See my comment below.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
IPython/frontend/qt/console/console_widget.py
((7 lines not shown))
601 627
             self._insert_plain_text_into_buffer(cursor, dedent(text))
602 628
 
  629
+    def pasteMagic(self,text):
2
Evan Patterson Collaborator
epatters added a note October 10, 2011

Since these should all become one-liners (e.g. self.execute("%exit")), there's no reason to pollute ConsoleWidget with them. Just make them lambda functions or methods in the application.

Matthias Bussonnier Collaborator
Carreau added a note October 11, 2011

I was thinking that execute() wouldn't replace the current buffer... but as it does, i'll change the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Evan Patterson
Collaborator

This coming along nicely. Thanks @Carreau!

I commented on the RC issue above, as well as a few other issues. My only other comment at this point is that you should try to avoid camel case names unless Qt requires that you use one.

I still need to review the changes to the main application file, but I cannot at this moment. I will take a closer look soon.

Matthias Bussonnier
Collaborator

@epatters , I've change most of what you asked.
and changed cammelCase to name_with_underscore in afew not-verry-descriptive commits. I just push as it is and re-work on it later.

added some commits October 11, 2011
Matthias Bussonnier one commit again of decamelcasify. 67c77ed
Matthias Bussonnier use svg icon also for dialog box.
	Note that svg doesn't render the shadow casting in QT, Maybe it's an
	inkscape specific feature
4cb0fbb
Fernando Perez
Owner

Hey @Carreau,

sorry this is taking a while, but since it's effectively making a 'real app' out of the little terminal, we really want to spend some time polishing things so it's as good as can be. We appreciate your patience with the feedback, I think this is going to be a big usability plus that will make both new and experienced users happy (as there's a litlte bit for each kind). Some more comments, now in what I think is the homestretch of polish so we can merge:

  • The help menu currently doesn't do anything. At the very least, it could offer the following entries:
  • Intro to IPython: basically call ?, which shows a little intro in the pager.
  • IPython quick reference: call %quickref
  • IPython Qt console quick reference: call %guiref
  • IPython documentation: use the webbrowser module to open the IPython documentation url at http://ipython.org/ipython-doc/stable/index.html.

  • I'm not totally sold on the magic menu. We have a ton of them, what's your design vision here? To offer a subset of common/useful ones? If so, what was your selection criterium for discarding some?

  • There should be a keybinding to hide/show the menubar itself, probably ctrl-m, along with a menu entry for it. That's par for the course in terminals, as experienced users tend to be super-minimalistic and like their terminals very clean.

  • A screen clear is a good candidate for a menu entry. Ctrl-L does it, but most people don't know this. Probably in the window menu.

  • Entries to interrupt (ctrl-C) and restart (Ctrl-.) kernels.

  • The edit menu should have the various select/cut/copy options that are in the right-click menu.

Thinking more about the above, here's a suggestion for menu restructuring:

  • New top-level Kernel menu with the content of the current window menu (since those are really about starting/accessing kernels).

  • Window menu: move the font stuff thre, as well as the menubar toggle and screen clear entries.

  • Font menu: remove.

  • Edit menu: add shortcuts as indicated above.

  • Help menu: see above.

  • Magic menu: see discussion above.

If you think you can do this, it would be awesome. And as far as I'm concerned, we'd be good to go. I will however hold off for the final OK from @epatters on the Qt code architecture, as I'm not really qualified to review that code at this point.

Thanks again for this great work!

Fernando Perez
Owner

Oops: I have no idea why, but at least on my system, with this branch, the resulting consoles don't close anymore. Whether I type exit or try to close the window, nothing happens. I can only kill it by going to the starting terminal and killing the process. At that point, I see the terminal is being flooded with messages like that say QCoreApplication::exec: The event loop is already running. Once I interrupt, the traceback is:

KeyboardInterrupt                         Traceback (most recent call last)
/home/fperez/usr/lib/python2.6/site-packages/IPython/zmq/ipkernel.pyc in do_one_iteration(self=)
    120             self.handlers[msg_type] = getattr(self, msg_type)
    121 
--> 122     def do_one_iteration(self):
        global d = undefined
        global i = undefined
        global t = undefined
    123         """Do one iteration of the kernel's evaluation loop.
    124         """

KeyboardInterrupt: 

So there's definitely a problem here at the moment...

IPython/frontend/qt/console/console_widget.py
@@ -597,7 +620,8 @@ class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):
597 620
 
598 621
             # Remove any trailing newline, which confuses the GUI and forces the
599 622
             # user to backspace.
600  
-            text = QtGui.QApplication.clipboard().text(mode).rstrip()
2
Evan Patterson Collaborator
epatters added a note October 13, 2011

This diff looks like a leftover from an old, revised commit. text is not a parameter to this method.

Matthias Bussonnier Collaborator
Carreau added a note October 14, 2011

right, I'll fix it...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
IPython/frontend/qt/console/history_console_widget.py
@@ -204,6 +204,50 @@ class HistoryConsoleWidget(ConsoleWidget):
204 204
         """
205 205
         return self._history[-n:]
206 206
 
  207
+    def history_magic(self):
1
Evan Patterson Collaborator
epatters added a note October 13, 2011

No reason to have this one-liner here. Move to the application like the other magic actions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Evan Patterson epatters commented on the diff October 13, 2011
IPython/frontend/qt/console/history_console_widget.py
((12 lines not shown))
  215
+                }
  216
+            )
  217
+        self._request_info['execute'] = self._ExecutionRequest(msg_id, 'save_magic')
  218
+
  219
+    def _handle_execute_reply(self, msg):
  220
+        """ Handles replies for code execution, here only session history length
  221
+        """
  222
+        info = self._request_info.get('execute')
  223
+        if info and info.id == msg['parent_header']['msg_id'] and \
  224
+                info.kind == 'save_magic' and not self._hidden:
  225
+            content = msg['content']
  226
+            status = content['status']
  227
+            if status == 'ok':
  228
+                self._max_session_history=(int(content['user_expressions']['hlen']))
  229
+
  230
+    def save_magic(self):
1
Evan Patterson Collaborator
epatters added a note October 13, 2011

There's no guarantee this request will return before the user enters the filename. It probably will, but we don't know for sure. In any case, I would simplify this by doing away with the history size request. Instead, I would just pick some default value (say 1000) and indicate that it is the maximum history size.

Also, like the history magic, this should go in the application.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
IPython/frontend/qt/console/qtconsoleapp.py
((126 lines not shown))
  327
+        self.edit_menu = self.menuBar().addMenu("&Edit")
  328
+        self.font_menu = self.menuBar().addMenu("F&ont")
  329
+        self.window_menu = self.menuBar().addMenu("&Window")
  330
+        self.magic_menu = self.menuBar().addMenu("&Magic")
  331
+
  332
+        # please keep the Help menu in Mac Os even if empty. It will
  333
+        # automatically contain a search field to search inside menus and
  334
+        # please keep it spelled in English, as long as Qt Doesn't support
  335
+        # a QAction.MenuRole like HelpMenuRole otherwise it will loose
  336
+        # this search field fonctionnality
  337
+
  338
+        self.help_menu = self.menuBar().addMenu("&Help")
  339
+
  340
+        # sould wrap every line of the following block into a try/except,
  341
+        # as we are not sure of instanciating a _frontend which support all
  342
+        # theses actions, but there might be a better way
2
Evan Patterson Collaborator
epatters added a note October 13, 2011

I agree that this smells funny. In fact, I don't really understand why you have to check for attribute errors here. Could you explain your reasoning?

Matthias Bussonnier Collaborator
Carreau added a note October 14, 2011

When there was only one frontend in the window, I used to directly link to the action of _frontend. But as I wasn't sure of what class _frontend inherited, or if it would have changed, I wraped every adding action into a try/except to avoid crash at startup when initiating menubar.

Still, I'm not sure everything work depending on type of widget widget_factory return.

[Edit] Actually, everything based on magic fail ( but not crash ) on a --pure kernel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Matthias Bussonnier
Collaborator

@fperez,

The help menu currently doesn't do anything. At the very least, it could offer the following entries:
Intro to IPython: basically call ?, which shows a little intro in the pager.
IPython quick reference: call %quickref
IPython Qt console quick reference: call %guiref

I'll do it

IPython documentation: use the webbrowser module to open the IPython documentation url at http://ipython.org/ipython-doc/stable/index.html.

That's a mistake there is an _open_online_help(), but i've put it on darwin only, I'll fixe.

I'm not totally sold on the magic menu. We have a ton of them, what's your design vision here? To offer a subset of common/useful ones? If so, what was your selection criterium for discarding some?

I was thinking of using '%ls_magic' to fetch everything availlable and 'build' an "other magic" menu
with maybe a filtering of specially handled magic, with shortcut etc... but i'm not sure how to do it.
I'm stuck on the fact that the action in menu should not trigger an action on a widget, but on the 'current' widget

There should be a keybinding to hide/show the menubar itself, probably ctrl-m, along with a menu entry for it. That's par >for the course in terminals, as experienced users tend to be super-minimalistic and like their terminals very clean.

I totally agree

A screen clear is a good candidate for a menu entry. Ctrl-L does it, but most people don't know this. Probably in the >window menu.

should decide of the how to handle all magic before

Entries to interrupt (ctrl-C) and restart (Ctrl-.) kernels.
The edit menu should have the various select/cut/copy options that are in the right-click menu.

I agree also

Thinking more about the above, here's a suggestion for menu restructuring:
New top-level Kernel menu with the content of the current window menu (since those are really about starting/accessing kernels).

I've plan for kernel, not sure how now, but I should keep track of 'orphan' kernel and give a way to reattach console ok kill them

Window menu: move the font stuff thre, as well as the menubar toggle and screen clear entries.
Font menu: remove.
Edit menu: add shortcuts as indicated above.
Help menu: see above.

Will add some conditionnal code for mac at least

Magic menu: see discussion above.

If you think you can do this, it would be awesome. And as far as I'm concerned, we'd be good to go. I will however hold >off for the final OK from @epatters on the Qt code architecture, as I'm not really qualified to review that code at this point.

I'll do my best, but i'm not sure i'll find the right way to do things. especially for '%ls_magic' to generate a menu.

Thanks again for this great work!

about your exiting problem. the only things I see can affect the behaviour is in frontend_widget.py where i change the exit_request() and sys.exit() by exit_request(*self*)

@epatters,
try/except might be from the time when there wasn't any tabs... will try to see if it is still necessary and why it was.

Will patch/comment on other message later
--
Matthias

Min RK
Owner

This is looking good! I was worried that it would conflict with recently merged PR #847, but in fact it still merges cleanly.

A few changes would need to be made, as KernelManagers are now created a little bit differently (via connection files instead of specifying all the addresses, and the KernelManager has one ip and a set of ports, rather than a collection of ip/port addresses).

Matthias Bussonnier
Collaborator

Hi,
Could someone test showing/hiding menubar as it can't be hidden on mac ?
Are shortcut still availlable when hidden ?

I've also not yet assigned shortcut to interupt/restart kernel, because Ctrl+C is used for both Interrupting end Copy. I need to test if it's preventing one or the other event to go through if assigned. And if it is the case find a better way to handle it.

I suppose I can retrieve the content of %lsmagic by using user_expressions, is there a better way ? like dirrectly all magic strings in a list ?

Fernando Perez
Owner
Matthias Bussonnier
Collaborator

just have been robed, all my laptop stolen... won't be back for a while...
good luck

Thomas Kluyver
Collaborator

Sorry to hear that; good luck getting it sorted out.

Fernando Perez
Owner
Evan Patterson
Collaborator

That's a shame. I hope you get everything sorted out. Thanks for the all the work you've done on this. It's a large contribution.

David Warde-Farley
dwf commented October 15, 2011

Just caught this unfortunate news in my GitHub news feed. Evan's right, this is indeed a wonderful contribution and it's a real shame that someone would go and do that. Best of luck recovering, I know how violating it can be to be the victim of major property theft.

Fernando Perez fperez referenced this pull request October 17, 2011
Merged

Qtconsole menu #887

Fernando Perez
Owner

@Carreau, I'm closing this PR here but continuing it as #887, it's just that we'll do it off a branch that @epatters and the rest of us can commit to. I rebased your commits so they would merge, and we'll see if it's feasible for us to finish what you started in time for 0.12. Feel free to join the discussion there, and if it turns out that you can resume regular activities earlier than planned, we'll be happy to move the work back into your branch.

One way or another, we'll do our best to ensure your work isn't lost, and we wish you the best in recovering from this crime.

Fernando Perez fperez closed this October 17, 2011
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 37 unique commits by 1 author.

Oct 04, 2011
Matthias Bussonnier create menu bar on OSX with some action
	console_widget:
		modifie/create some QAction to be able to put it in menu bar
			-made print_action and export_action public
			-transform increase/decrease/rest front_size
			 to QAction
			-create qaction for undo/redo

	MainWindow
		Create the menubar with the following structure
		And link each menu with its action in console Widget
		File
		|__Print
		|__Save as XML
		|__Select ALL
		Edit
		|__Undo
		|__Redo
		Font
		|__Increase font size
		|__Decresae font size
		|__Restet Font size
		Window
		|__Minimize
		|__Maximize
		|__Full Screen
		Magic
		|__Reset
		|__History
		|__Export History
		|__Who
		|__Whos
		|__Who_ls
		Help
		|_Open online Help

		The 'Magic' Menu, execute %magic after 'exit_keyboard' and pasting
		'%magic'.  The 'Export History' menu prompt the user for a file name
		and a range before pasting `%save filename range`.

	This this also fix a bug in toggle full screen where
	Full Screen -> (try to) Minimizing -> Out Of Full Screen
	is broken (grey background for all screen), at least on OSX
b12bd0f
Matthias Bussonnier Add icon to qtconsole app
	It's clearly not definitive, as most of the file are not in the right
	location and icon should be graphically improved, so il will certainly be rebased later.
	But as it goes with UI improvemetn in the menubar I add it to this branch.

	Note: About the svg Icon, I've done it from scratch in inkscape, inspired by
	iTerm2 icon, which is under GPL
	the .icns file is OSX Specific.
2aca261
Matthias Bussonnier Fix last Commit Resources (Icones)
		Did export the wrong area with inkscape, making the Icons to Have the
		wrong aspect ratio once loaded in qt. Use this excuse to refine
		shadow/lightnig and general color
032a542
Matthias Bussonnier Improve 'save history' menu (%save)
	Real file chooser menu, get the current session history range by default.
	If the file already exist, the user will be prompted twice if he/she really
	want to be override the existing file ( by the gui, and the magic afterward)
	One might also to add the (-r) %save option into the gui.
aa1ba3b
Matthias Bussonnier disable some QAction by default, remove OSX only, wrap in try/except 4fcdef5
Matthias Bussonnier move some action in main windows as asked by @epatters.
	not all haves benn moves as i'm not sure yet how to handle some of them
786b811
Matthias Bussonnier move %history and %save action into mainwindow bf64f26
Matthias Bussonnier Just indent a commentary with the right numbur of tabs and re-wrap it 394a5b1
Matthias Bussonnier tab management new/existing kernel.
	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
b9cf9e4
Matthias Bussonnier Send all action to active front instead of first tab 6ee799b
Matthias Bussonnier trying to move closing logic on a tab basis 47eb2f2
Oct 09, 2011
Matthias Bussonnier Handle all the case of tab closing and clean the code 26be4c1
Oct 10, 2011
Matthias Bussonnier fx tab name and already existing kernel before application launch
	tabs are now names "kernel i"

	starting the application with --existing ... use to attached all new tabs
	to the same kernel. New tab attached to new kernel now start a local kernel
	on random port and connect to it.

	rename some variable to be more explicit.
68621a1
Matthias Bussonnier Fix: crash when cancel closing slave tab 1eac761
Matthias Bussonnier New tab on focus when created 970facc
Matthias Bussonnier Add Shortcut Next/Previous tab 8171dad
Matthias Bussonnier Create Keyboard Accelerator for MenuBar 6a5c149
Matthias Bussonnier Break Hard dependency to Pyside ? 60cdd23
Matthias Bussonnier don't quit if asked once not to shutdown a kernel 4d22e9a
Oct 11, 2011
Matthias Bussonnier remove duplicate function "pasteMagic", and change code not to use it f0cb759
Matthias Bussonnier decamelCaseify : tabWidget -> tab_widget 4c02061
Matthias Bussonnier decamelcasify : closeTab close_tab 085a4c0
Matthias Bussonnier decamelcasify: 3 more changes 8b21e27
Matthias Bussonnier decamelcase : activeFrontend active_frontend 7155e50
Matthias Bussonnier decamelcasify: a few more db16f8a
Matthias Bussonnier a few more deCamelCasification e9bfcd5
Matthias Bussonnier remove all binary trace from Icons, use directly SVG 89f0723
Matthias Bussonnier one commit again of decamelcasify. 67c77ed
Matthias Bussonnier use svg icon also for dialog box.
	Note that svg doesn't render the shadow casting in QT, Maybe it's an
	inkscape specific feature
4cb0fbb
Oct 14, 2011
Matthias Bussonnier move open online help to be on all plateform e5cb5af
Matthias Bussonnier unwrap adding action from try/except, add %guiref and '?' in help menu 714e5d3
Matthias Bussonnier add some blank lines f284719
Matthias Bussonnier Create all_magic_menu. use webbrowser to open url 15758f5
Matthias Bussonnier reorganise menu
	add cut,copy paste, toggle menu bar (but not on os x)
	remove history oneliner from history console
e7f65be
Matthias Bussonnier remove old comment no longer usefull bd16fa0
Matthias Bussonnier move tab management to "Kernel" menu a1df136
Oct 15, 2011
Matthias Bussonnier add copy_raw, interrupt kernel and restart kernel into menu d8927e7
Something went wrong with that request. Please try again.