##// END OF EJS Templates
Introduce a doclkable widget that will substitute "all magics" menu....
Dimitry Kloper -
Show More
@@ -813,6 +813,162 b' class MainWindow(QtGui.QMainWindow):'
813 813 triggered=self._open_online_help)
814 814 self.add_menu_action(self.help_menu, self.onlineHelpAct)
815 815
816 def init_magic_helper(self):
817 self.magic_helper_data = None
818 self.magic_helper = QtGui.QDockWidget("Magics", self)
819 self.magic_helper.setAllowedAreas(QtCore.Qt.LeftDockWidgetArea |
820 QtCore.Qt.RightDockWidgetArea)
821 self.magic_helper.setVisible(False)
822
823 class MinListWidget(QtGui.QListWidget):
824 def sizeHint(self):
825 s = QtCore.QSize()
826 s.setHeight(super(MinListWidget,self).sizeHint().height())
827 s.setWidth(self.sizeHintForColumn(0))
828 return s
829
830 self.magic_helper_frame = QtGui.QFrame()
831 self.magic_helper_searchl = QtGui.QLabel("Search:")
832 self.magic_helper_search = QtGui.QLineEdit()
833 self.magic_helper_class = QtGui.QComboBox()
834 self.magic_helper_list = MinListWidget()
835 self.magic_helper_paste = QtGui.QPushButton("Paste")
836 self.magic_helper_run = QtGui.QPushButton("Run")
837
838 main_layout = QtGui.QVBoxLayout()
839 search_layout = QtGui.QHBoxLayout()
840 search_layout.addWidget(self.magic_helper_searchl)
841 search_layout.addWidget(self.magic_helper_search, 10)
842 main_layout.addLayout(search_layout)
843 main_layout.addWidget(self.magic_helper_class)
844 main_layout.addWidget(self.magic_helper_list, 10)
845 action_layout = QtGui.QHBoxLayout()
846 action_layout.addWidget(self.magic_helper_paste)
847 action_layout.addWidget(self.magic_helper_run)
848 main_layout.addLayout(action_layout)
849
850 self.magic_helper_frame.setLayout(main_layout)
851 self.magic_helper.setWidget(self.magic_helper_frame)
852
853 self.magic_helper.visibilityChanged[bool].connect(
854 self.update_magic_helper
855 )
856 self.magic_helper_class.activated[int].connect(
857 self.magic_helper_class_selected
858 )
859 self.magic_helper_search.textChanged[str].connect(
860 self.magic_helper_search_changed
861 )
862 self.magic_helper_list.itemDoubleClicked[QtGui.QListWidgetItem].connect(
863 self.magic_helper_paste_requested
864 )
865 self.magic_helper_paste.clicked[bool].connect(
866 self.magic_helper_paste_requested
867 )
868 self.magic_helper_run.clicked[bool].connect(
869 self.magic_helper_run_requested
870 )
871
872 self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.magic_helper)
873 self.add_menu_action(self.magic_menu,
874 self.magic_helper.toggleViewAction())
875
876 def update_magic_helper(self, visible):
877 if not visible or self.magic_helper_data != None:
878 return
879 self.magic_helper_data = {}
880 self.magic_helper_class.clear()
881 self.magic_helper_class.addItem("Populating...")
882 self.active_frontend._silent_exec_callback(
883 'get_ipython().magic("lsmagic")',
884 self.populate_magic_helper
885 )
886
887 def populate_magic_helper(self, data):
888 if not data:
889 return
890
891 if data['status'] != 'ok':
892 self.log.warn("%%lsmagic user-expression failed: {}".format(data))
893 return
894
895 self.magic_helper_class.clear()
896 self.magic_helper_list.clear()
897
898 self.magic_helper_data = json.loads(
899 data['data'].get('application/json', {})
900 )
901
902 self.magic_helper_class.addItem('All Magics', 'any')
903 classes = set()
904
905 for mtype in sorted(self.magic_helper_data):
906 subdict = self.magic_helper_data[mtype]
907 for name in sorted(subdict):
908 classes.add(subdict[name])
909
910 for cls in sorted(classes):
911 label = re.sub("([a-zA-Z]+)([A-Z][a-z])","\g<1> \g<2>", cls)
912 self.magic_helper_class.addItem(label, cls)
913
914 self.filter_magic_helper('.', 'any')
915
916 def magic_helper_class_selected(self, index):
917 item = self.magic_helper_class.itemData(index)
918 regex = self.magic_helper_search.text()
919 self.filter_magic_helper(regex = regex, cls = item)
920
921 def magic_helper_search_changed(self, search_string):
922 item = self.magic_helper_class.itemData(
923 self.magic_helper_class.currentIndex()
924 )
925 self.filter_magic_helper(regex = search_string, cls = item)
926
927 def _magic_helper_get_current(self, item = None):
928 text = None
929 if not isinstance(item, QtGui.QListWidgetItem):
930 item = self.magic_helper_list.currentItem()
931 text = item.text()
932 return text
933
934 def _set_active_frontend_focus(self):
935 # this is a hack, self.active_frontend._control seems to be
936 # a private member. Unfortunately this is the only method
937 # to set focus reliably
938 QtCore.QTimer.singleShot(200, self.active_frontend._control.setFocus)
939
940 def magic_helper_paste_requested(self, item = None):
941 text = self._magic_helper_get_current(item)
942 if text != None:
943 self.active_frontend.input_buffer = text
944 self._set_active_frontend_focus()
945
946 def magic_helper_run_requested(self, item = None):
947 text = self._magic_helper_get_current(item)
948 if text != None:
949 self.active_frontend.execute(text)
950 self._set_active_frontend_focus()
951
952 def filter_magic_helper(self, regex, cls):
953 if regex == "" or regex == None:
954 regex = '.'
955 if cls == None:
956 cls = 'any'
957
958 self.magic_helper_list.clear()
959 for mtype in sorted(self.magic_helper_data):
960 subdict = self.magic_helper_data[mtype]
961 prefix = magic_escapes[mtype]
962
963 for name in sorted(subdict):
964 mclass = subdict[name]
965 pmagic = prefix + name
966
967 if (re.match(regex, name) or re.match(regex, pmagic)) and \
968 (cls == 'any' or cls == mclass):
969 self.magic_helper_list.addItem(pmagic)
970
971
816 972 # minimize/maximize/fullscreen actions:
817 973
818 974 def toggle_menu_bar(self):
@@ -272,6 +272,7 b' class IPythonQtConsoleApp(BaseIPythonApplication, IPythonConsoleApp):'
272 272 self.window.log = self.log
273 273 self.window.add_tab_with_frontend(self.widget)
274 274 self.window.init_menu_bar()
275 self.window.init_magic_helper()
275 276
276 277 # Ignore on OSX, where there is always a menu bar
277 278 if sys.platform != 'darwin' and self.hide_menubar:
General Comments 0
You need to be logged in to leave comments. Login now