Show More
@@ -138,7 +138,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||||
138 | self._input_splitter = self._input_splitter_class(input_mode='cell') |
|
138 | self._input_splitter = self._input_splitter_class(input_mode='cell') | |
139 | self._kernel_manager = None |
|
139 | self._kernel_manager = None | |
140 | self._request_info = {} |
|
140 | self._request_info = {} | |
141 |
self._callback_dict= |
|
141 | self._callback_dict = {} | |
142 |
|
142 | |||
143 | # Configure the ConsoleWidget. |
|
143 | # Configure the ConsoleWidget. | |
144 | self.tab_width = 4 |
|
144 | self.tab_width = 4 | |
@@ -313,40 +313,43 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||||
313 | cursor.movePosition(QtGui.QTextCursor.Left, n=len(text)) |
|
313 | cursor.movePosition(QtGui.QTextCursor.Left, n=len(text)) | |
314 | self._complete_with_items(cursor, rep['content']['matches']) |
|
314 | self._complete_with_items(cursor, rep['content']['matches']) | |
315 |
|
315 | |||
316 | def _silent_exec_callback(self,expr,callback): |
|
316 | def _silent_exec_callback(self, expr, callback): | |
317 |
""" |
|
317 | """Silently execute `expr` in the kernel and call `callback` with reply | |
318 |
|
318 | |||
319 |
|
|
319 | `expr` : valid string to be executed by the kernel. | |
|
320 | `callback` : function accepting one string as argument. | |||
320 |
|
321 | |||
321 | callback a function accepting one argument (str) |
|
322 | The `callback` is called with the 'repr()' of the result of `expr` as | |
322 |
|
323 | first argument. To get the object, do 'eval()' on the passed value. | ||
323 | the callback is called with the 'repr()' of the result as first argument. |
|
|||
324 | to get the object, do 'eval()' on the passed value. |
|
|||
325 | """ |
|
324 | """ | |
326 |
|
325 | |||
327 | # generate uuid, which would be used as a indication of wether or not |
|
326 | # generate uuid, which would be used as a indication of wether or not | |
328 | # the unique request originate from here (can use msg id ?) |
|
327 | # the unique request originate from here (can use msg id ?) | |
329 | local_uuid = str(uuid.uuid1()) |
|
328 | local_uuid = str(uuid.uuid1()) | |
330 | msg_id = self.kernel_manager.shell_channel.execute('', |
|
329 | msg_id = self.kernel_manager.shell_channel.execute('', | |
331 | silent=True, |
|
330 | silent=True, user_expressions={ local_uuid:expr }) | |
332 | user_expressions={ local_uuid:expr, |
|
331 | self._callback_dict[local_uuid] = callback | |
333 | } |
|
|||
334 | ) |
|
|||
335 | self._callback_dict[local_uuid]=callback |
|
|||
336 | self._request_info['execute'] = self._ExecutionRequest(msg_id, 'silent_exec_callback') |
|
332 | self._request_info['execute'] = self._ExecutionRequest(msg_id, 'silent_exec_callback') | |
337 |
|
333 | |||
338 | def _handle_exec_callback(self,msg): |
|
334 | def _handle_exec_callback(self, msg): | |
339 | """ Called when _silent_exec_callback message comme back from the kernel. |
|
335 | """Execute `callback` corresonding to `msg` reply, after ``_silent_exec_callback`` | |
|
336 | ||||
|
337 | `msg` : raw message send by the kernel containing an `user_expressions` | |||
|
338 | and having a 'silent_exec_callback' kind. | |||
340 |
|
339 | |||
341 | Strip the message comming back from the kernel and send it to the |
|
340 | This fonction will look for a `callback` associated with the | |
342 | corresponding callback function. |
|
341 | corresponding message id. Association has been made by | |
|
342 | ``_silent_exec_callback``. `callback`is then called with the `repr()` | |||
|
343 | of the value of corresponding `user_expressions` as argument. | |||
|
344 | `callback` is then removed from the known list so that any message | |||
|
345 | coming again with the same id won't trigger it. | |||
343 | """ |
|
346 | """ | |
344 | cnt=msg['content'] |
|
347 | ||
345 | ue=cnt['user_expressions'] |
|
348 | cnt = msg['content'] | |
|
349 | ue = cnt['user_expressions'] | |||
346 | for i in ue.keys(): |
|
350 | for i in ue.keys(): | |
347 |
if i in self._callback_dict |
|
351 | if i in self._callback_dict: | |
348 |
|
|
352 | self._callback_dict[i](ue[i]) | |
349 | f(ue[i]) |
|
|||
350 | self._callback_dict.pop(i) |
|
353 | self._callback_dict.pop(i) | |
351 |
|
354 | |||
352 | def _handle_execute_reply(self, msg): |
|
355 | def _handle_execute_reply(self, msg): |
@@ -544,32 +544,54 b' class MainWindow(QtGui.QMainWindow):' | |||||
544 |
|
544 | |||
545 | self.kernel_menu.addSeparator() |
|
545 | self.kernel_menu.addSeparator() | |
546 |
|
546 | |||
|
547 | def _make_dynamic_magic(self,magic): | |||
|
548 | """Return a function `fun` that will execute `magic` on active frontend. | |||
|
549 | ||||
|
550 | `magic` : valid python string | |||
|
551 | ||||
|
552 | return `fun`, function with no parameters | |||
|
553 | ||||
|
554 | `fun` execute `magic` an active frontend at the moment it is triggerd, | |||
|
555 | not the active frontend at the moment it has been created. | |||
|
556 | ||||
|
557 | This function is mostly used to create the "All Magics..." Menu at run time. | |||
|
558 | """ | |||
|
559 | # need to level nested function to be sure to past magic | |||
|
560 | # on active frontend **at run time**. | |||
|
561 | def inner_dynamic_magic(): | |||
|
562 | self.active_frontend.execute(magic) | |||
|
563 | inner_dynamic_magic.__name__ = "dynamics_magic_s" | |||
|
564 | return inner_dynamic_magic | |||
|
565 | ||||
|
566 | def populate_all_magic_menu(self, listofmagic=None): | |||
|
567 | """Clean "All Magics..." menu and repopulate it with `listofmagic` | |||
|
568 | ||||
|
569 | `listofmagic` : string, repr() of a list of strings. | |||
|
570 | ||||
|
571 | `listofmagic`is a repr() of list because it is fed with the result of | |||
|
572 | a 'user_expression' | |||
|
573 | """ | |||
|
574 | alm_magic_menu = self.all_magic_menu | |||
|
575 | alm_magic_menu.clear() | |||
|
576 | ||||
|
577 | # list of protected magic that don't like to be called without argument | |||
|
578 | # append '?' to the end to print the docstring when called from the menu | |||
|
579 | protected_magic = set(["more","less","load_ext","pycat","loadpy","save"]) | |||
|
580 | ||||
|
581 | for magic in eval(listofmagic): | |||
|
582 | if magic in protected_magic: | |||
|
583 | pmagic = '%s%s%s'%('%',magic,'?') | |||
|
584 | else: | |||
|
585 | pmagic = '%s%s'%('%',magic) | |||
|
586 | xaction = QtGui.QAction(pmagic, | |||
|
587 | self, | |||
|
588 | triggered=self._make_dynamic_magic(pmagic) | |||
|
589 | ) | |||
|
590 | alm_magic_menu.addAction(xaction) | |||
|
591 | ||||
547 | def update_all_magic_menu(self): |
|
592 | def update_all_magic_menu(self): | |
548 | # first define a callback which will get the list of all magic and put it in the menu. |
|
593 | # first define a callback which will get the list of all magic and put it in the menu. | |
549 | def populate_all_magic_menu(val=None): |
|
594 | self.active_frontend._silent_exec_callback('get_ipython().lsmagic()',self.populate_all_magic_menu) | |
550 | alm_magic_menu = self.all_magic_menu |
|
|||
551 | alm_magic_menu.clear() |
|
|||
552 | def make_dynamic_magic(i): |
|
|||
553 | def inner_dynamic_magic(): |
|
|||
554 | self.active_frontend.execute(i) |
|
|||
555 | inner_dynamic_magic.__name__ = "dynamics_magic_s" |
|
|||
556 | return inner_dynamic_magic |
|
|||
557 |
|
||||
558 | # list of protected magic that don't like to be called without argument |
|
|||
559 | # append '?' to the end to print the docstring when called from the menu |
|
|||
560 | protected_magic= ["more","less","load_ext","pycat","loadpy","save"] |
|
|||
561 |
|
||||
562 | for magic in eval(val): |
|
|||
563 | if magic in protected_magic: |
|
|||
564 | pmagic = '%s%s%s'%('%',magic,'?') |
|
|||
565 | else: |
|
|||
566 | pmagic = '%s%s'%('%',magic) |
|
|||
567 | xaction = QtGui.QAction(pmagic, |
|
|||
568 | self, |
|
|||
569 | triggered=make_dynamic_magic(pmagic) |
|
|||
570 | ) |
|
|||
571 | alm_magic_menu.addAction(xaction) |
|
|||
572 | self.active_frontend._silent_exec_callback('get_ipython().lsmagic()',populate_all_magic_menu) |
|
|||
573 |
|
595 | |||
574 | def init_magic_menu(self): |
|
596 | def init_magic_menu(self): | |
575 | self.magic_menu = self.menuBar().addMenu("&Magic") |
|
597 | self.magic_menu = self.menuBar().addMenu("&Magic") | |
@@ -578,8 +600,7 b' class MainWindow(QtGui.QMainWindow):' | |||||
578 | # this action should not appear as it will be cleard when menu |
|
600 | # this action should not appear as it will be cleard when menu | |
579 | # will be updated at first kernel response. |
|
601 | # will be updated at first kernel response. | |
580 | self.pop = QtGui.QAction("&Update All Magic Menu ", |
|
602 | self.pop = QtGui.QAction("&Update All Magic Menu ", | |
581 | self, |
|
603 | self, triggered=self.update_all_magic_menu) | |
582 | triggered=self.update_all_magic_menu) |
|
|||
583 | self.add_menu_action(self.all_magic_menu, self.pop) |
|
604 | self.add_menu_action(self.all_magic_menu, self.pop) | |
584 |
|
605 | |||
585 | self.reset_action = QtGui.QAction("&Reset", |
|
606 | self.reset_action = QtGui.QAction("&Reset", |
@@ -452,7 +452,7 b' class IPythonQtConsoleApp(BaseIPythonApplication):' | |||||
452 | self.window.add_tab_with_frontend(self.widget) |
|
452 | self.window.add_tab_with_frontend(self.widget) | |
453 | self.window.init_menu_bar() |
|
453 | self.window.init_menu_bar() | |
454 |
|
454 | |||
455 | #we need to populate the 'Magic Menu' once the kernel has answer at least once |
|
455 | # we need to populate the 'Magic Menu' once the kernel has answer at least once | |
456 | self.kernel_manager.shell_channel.first_reply.connect(self.window.pop.trigger) |
|
456 | self.kernel_manager.shell_channel.first_reply.connect(self.window.pop.trigger) | |
457 |
|
457 | |||
458 | self.window.setWindowTitle('Python' if self.pure else 'IPython') |
|
458 | self.window.setWindowTitle('Python' if self.pure else 'IPython') |
General Comments 0
You need to be logged in to leave comments.
Login now