Ejemplo n.º 1
0
    def __init__(self, app, tree, confirm_exit, config=None):
        """ Create a MainWindow for the application
        
        Parameters
        ----------
        
        app : reference to QApplication parent
        """

        super(MainWindow, self).__init__()
        self.resize(1000, 800)
        self._app = app
        self._app.setStyle("QMacStyle")
        self.config = config
        self.confirm_exit = confirm_exit
        self.default_directory = os.path.expanduser('~')
        self.copied_node = None

        mainwindow = QtGui.QWidget()

        rightpane = QtGui.QWidget()

        self.plotview = NXPlotView(parent=rightpane)
        self.plotview.setMinimumSize(700, 600)

        self.console = IPythonWidget(config=self.config, parent=rightpane)
        self.console.setMinimumSize(700, 200)
        self.console.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
        self.console._confirm_exit = self.confirm_exit
        self.console.gui_completion = 'droplist'
        self.console.kernel_manager = QtKernelManager(config=self.config)
        self.console.kernel_manager.start_kernel()
        self.console.kernel_manager.start_channels()
        self.shell = self.console.kernel_manager.kernel.shell
        self.user_ns = self.console.kernel_manager.kernel.shell.user_ns

        rightlayout = QtGui.QVBoxLayout()        
        rightlayout.addWidget(self.plotview)
        rightlayout.addWidget(self.console)
        rightlayout.setContentsMargins(0, 0, 0, 0)
        rightpane.setLayout(rightlayout)
        
        self.tree = tree
        self.treeview = NXTreeView(self.tree,parent=mainwindow)
        self.treeview.setMinimumWidth(200)
        self.treeview.setMaximumWidth(400)
        self.treeview.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding)
        self.user_ns['plotview'] = self.plotview
        self.user_ns['treeview'] = self.treeview
        self.user_ns['tree'] = self.tree
        self.user_ns['mainwindow'] = self

        mainlayout = QtGui.QHBoxLayout()
        mainlayout.addWidget(self.treeview)
        mainlayout.addWidget(rightpane)
        mainlayout.setContentsMargins(0, 0, 0, 0)
        mainwindow.setLayout(mainlayout)

        self.setCentralWidget(mainwindow)

        base_path = os.path.abspath(os.path.dirname(__file__))
        icon_path = os.path.join(base_path, 'resources', 'icon', 'NeXpy.svg')
        self.import_path = os.path.join(os.path.abspath(os.path.dirname(base_path)), 
                                        'readers')
        self._app.icon = QtGui.QIcon(icon_path)
        QtGui.QApplication.setWindowIcon(self._app.icon)

        self.init_menu_bar()

        self.setWindowTitle('NeXpy')
        self.statusBar().showMessage('Ready')
        self.console._control.setFocus()
Ejemplo n.º 2
0
class MainWindow(QtGui.QMainWindow):

    #---------------------------------------------------------------------------
    # 'object' interface
    #---------------------------------------------------------------------------

    def __init__(self, app, tree, confirm_exit, config=None):
        """ Create a MainWindow for the application
        
        Parameters
        ----------
        
        app : reference to QApplication parent
        """

        super(MainWindow, self).__init__()
        self.resize(1000, 800)
        self._app = app
        self._app.setStyle("QMacStyle")
        self.config = config
        self.confirm_exit = confirm_exit
        self.default_directory = os.path.expanduser('~')
        self.copied_node = None

        mainwindow = QtGui.QWidget()

        rightpane = QtGui.QWidget()

        self.plotview = NXPlotView(parent=rightpane)
        self.plotview.setMinimumSize(700, 600)

        self.console = IPythonWidget(config=self.config, parent=rightpane)
        self.console.setMinimumSize(700, 200)
        self.console.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
        self.console._confirm_exit = self.confirm_exit
        self.console.gui_completion = 'droplist'
        self.console.kernel_manager = QtKernelManager(config=self.config)
        self.console.kernel_manager.start_kernel()
        self.console.kernel_manager.start_channels()
        self.shell = self.console.kernel_manager.kernel.shell
        self.user_ns = self.console.kernel_manager.kernel.shell.user_ns

        rightlayout = QtGui.QVBoxLayout()        
        rightlayout.addWidget(self.plotview)
        rightlayout.addWidget(self.console)
        rightlayout.setContentsMargins(0, 0, 0, 0)
        rightpane.setLayout(rightlayout)
        
        self.tree = tree
        self.treeview = NXTreeView(self.tree,parent=mainwindow)
        self.treeview.setMinimumWidth(200)
        self.treeview.setMaximumWidth(400)
        self.treeview.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding)
        self.user_ns['plotview'] = self.plotview
        self.user_ns['treeview'] = self.treeview
        self.user_ns['tree'] = self.tree
        self.user_ns['mainwindow'] = self

        mainlayout = QtGui.QHBoxLayout()
        mainlayout.addWidget(self.treeview)
        mainlayout.addWidget(rightpane)
        mainlayout.setContentsMargins(0, 0, 0, 0)
        mainwindow.setLayout(mainlayout)

        self.setCentralWidget(mainwindow)

        base_path = os.path.abspath(os.path.dirname(__file__))
        icon_path = os.path.join(base_path, 'resources', 'icon', 'NeXpy.svg')
        self.import_path = os.path.join(os.path.abspath(os.path.dirname(base_path)), 
                                        'readers')
        self._app.icon = QtGui.QIcon(icon_path)
        QtGui.QApplication.setWindowIcon(self._app.icon)

        self.init_menu_bar()

        self.setWindowTitle('NeXpy')
        self.statusBar().showMessage('Ready')
        self.console._control.setFocus()

    def close(self,current):
        """ Called when you need to try to close the console widget.
        """

        title = self.window().windowTitle()
        cancel = QtGui.QMessageBox.Cancel
        okay = QtGui.QMessageBox.Ok
        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:
            pass

    # Populate the menu bar with common actions and shortcuts
    def add_menu_action(self, menu, action, defer_shortcut=False):
        """Add action to menu as well as self
        
        So that when the menu bar is invisible, its actions are still available.
        
        If defer_shortcut is True, set the shortcut context to widget-only,
        where it will avoid conflict with shortcuts already bound to the
        widgets themselves.
        """
        menu.addAction(action)
        self.addAction(action)

        if defer_shortcut:
            action.setShortcutContext(QtCore.Qt.WidgetShortcut)
    
    def init_menu_bar(self):
        #create menu in the order they should appear in the menu bar
        self.init_file_menu()
        self.init_edit_menu()
        self.init_data_menu()
        self.init_view_menu()
        self.init_magic_menu()
        self.init_window_menu()
        self.init_help_menu()
    
    def init_file_menu(self):
        self.file_menu = self.menuBar().addMenu("&File")
        
        self.file_menu.addSeparator()

        self.newworkspace_action=QtGui.QAction("&New...",
            self,
            shortcut=QtGui.QKeySequence.New,
            triggered=self.new_workspace
            )
        self.add_menu_action(self.file_menu, self.newworkspace_action, True)  
        
        self.openfile_action=QtGui.QAction("&Open (read only)",
            self,
            shortcut=QtGui.QKeySequence.Open,
            triggered=self.open_file
            )
        self.add_menu_action(self.file_menu, self.openfile_action, True)  
        
        self.openeditablefile_action=QtGui.QAction("Open (read/write)",
            self,
            shortcut=QtGui.QKeySequence("Ctrl+Shift+O"),
            triggered=self.open_editable_file
            )
        self.add_menu_action(self.file_menu, self.openeditablefile_action, True)  

        self.savefile_action=QtGui.QAction("&Save",
            self,
            shortcut=QtGui.QKeySequence.Save,
            triggered=self.save_file
            )
        self.add_menu_action(self.file_menu, self.savefile_action, True)  
        
        self.savefileas_action=QtGui.QAction("Save as...",
            self,
            shortcut=QtGui.QKeySequence.SaveAs,
            triggered=self.save_file_as
            )
        self.add_menu_action(self.file_menu, self.savefileas_action, True)  
        
        self.file_menu.addSeparator()

        self.init_import_menu()
        
        self.file_menu.addSeparator()
        
        printkey = QtGui.QKeySequence(QtGui.QKeySequence.Print)
        if printkey.matches("Ctrl+P") and sys.platform != 'darwin':
            # Only override the default if there is a collision.
            # Qt ctrl = cmd on OSX, so the match gets a false positive on OSX.
            printkey = "Ctrl+Shift+P"
        self.print_action = QtGui.QAction("&Print Shell",
            self,
            shortcut=printkey,
            triggered=self.print_action_console)
        self.add_menu_action(self.file_menu, self.print_action, True)
        
        if sys.platform != 'darwin':
            # OSX always has Quit in the Application menu, only add it
            # to the File menu elsewhere.

            self.file_menu.addSeparator()

            self.quit_action = QtGui.QAction("&Quit",
                self,
                shortcut=QtGui.QKeySequence.Quit,
                triggered=self.close,
            )
            self.add_menu_action(self.file_menu, self.quit_action)

    def init_edit_menu(self):
        self.edit_menu = self.menuBar().addMenu("&Edit")
        
        self.undo_action = QtGui.QAction("&Undo",
            self,
            shortcut=QtGui.QKeySequence.Undo,
            statusTip="Undo last action if possible",
            triggered=self.undo_console
            )
        self.add_menu_action(self.edit_menu, self.undo_action)

        self.redo_action = QtGui.QAction("&Redo",
            self,
            shortcut=QtGui.QKeySequence.Redo,
            statusTip="Redo last action if possible",
            triggered=self.redo_console)
        self.add_menu_action(self.edit_menu, self.redo_action)

        self.edit_menu.addSeparator()

        self.cut_action = QtGui.QAction("&Cut",
            self,
            shortcut=QtGui.QKeySequence.Cut,
            triggered=self.cut_console
            )
        self.add_menu_action(self.edit_menu, self.cut_action, True)

        self.copy_action = QtGui.QAction("&Copy",
            self,
            shortcut=QtGui.QKeySequence.Copy,
            triggered=self.copy_console
            )
        self.add_menu_action(self.edit_menu, self.copy_action, True)

        self.copy_raw_action = QtGui.QAction("Copy (&Raw Text)",
            self,
            shortcut="Ctrl+Shift+C",
            triggered=self.copy_raw_console
            )
        self.add_menu_action(self.edit_menu, self.copy_raw_action, True)

        self.paste_action = QtGui.QAction("&Paste",
            self,
            shortcut=QtGui.QKeySequence.Paste,
            triggered=self.paste_console
            )
        self.add_menu_action(self.edit_menu, self.paste_action, True)

        self.edit_menu.addSeparator()
        
        selectall = QtGui.QKeySequence(QtGui.QKeySequence.SelectAll)
        if selectall.matches("Ctrl+A") and sys.platform != 'darwin':
            # Only override the default if there is a collision.
            # Qt ctrl = cmd on OSX, so the match gets a false positive on OSX.
            selectall = "Ctrl+Shift+A"
        self.select_all_action = QtGui.QAction("Select &All",
            self,
            shortcut=selectall,
            triggered=self.select_all_console
            )
        self.add_menu_action(self.edit_menu, self.select_all_action, True)
    
    def init_data_menu(self):
        self.data_menu = self.menuBar().addMenu("Data")
        
        self.plot_data_action=QtGui.QAction("Plot Data",
            self,
            triggered=self.plot_data
            )
        self.add_menu_action(self.data_menu, self.plot_data_action, True)  
        
        self.overplot_data_action=QtGui.QAction("Overplot Data",
            self,
            triggered=self.overplot_data
            )
        self.add_menu_action(self.data_menu, self.overplot_data_action, True)  

        self.data_menu.addSeparator()

        self.add_action=QtGui.QAction("Add Data",
            self,
            triggered=self.add_data
            )
        self.add_menu_action(self.data_menu, self.add_action, True)  

        self.rename_action=QtGui.QAction("Rename Data",
            self,
            triggered=self.rename_data
            )
        self.add_menu_action(self.data_menu, self.rename_action, True)  

        self.copy_action=QtGui.QAction("Copy Data",
            self,
            triggered=self.copy_data
            )
        self.add_menu_action(self.data_menu, self.copy_action, True)  

        self.paste_action=QtGui.QAction("Paste Data",
            self,
            triggered=self.paste_data
            )
        self.add_menu_action(self.data_menu, self.paste_action, True)  

        self.delete_action=QtGui.QAction("Delete Data",
            self,
            triggered=self.delete_data
            )
        self.add_menu_action(self.data_menu, self.delete_action, True)  

        self.data_menu.addSeparator()
 
        self.signal_action=QtGui.QAction("Set Signal",
            self,
            triggered=self.set_signal
            )
        self.add_menu_action(self.data_menu, self.signal_action, True)  

        self.data_menu.addSeparator()

        self.fit_action=QtGui.QAction("Fit Data",
            self,
            triggered=self.fit_data
            )
        self.add_menu_action(self.data_menu, self.fit_action, True)

        
    def init_view_menu(self):
        self.view_menu = self.menuBar().addMenu("&View")

        if sys.platform != 'darwin':
            # disable on OSX, where there is always a menu bar
            self.toggle_menu_bar_act = QtGui.QAction("Toggle &Menu Bar",
                self,
                shortcut="Ctrl+Shift+M",
                statusTip="Toggle visibility of menubar",
                triggered=self.toggle_menu_bar)
            self.add_menu_action(self.view_menu, self.toggle_menu_bar_act)
        
        fs_key = "Ctrl+Meta+F" if sys.platform == 'darwin' else "F11"
        self.full_screen_act = QtGui.QAction("&Full Screen",
            self,
            shortcut=fs_key,
            statusTip="Toggle between Fullscreen and Normal Size",
            triggered=self.toggleFullScreen)
        self.add_menu_action(self.view_menu, self.full_screen_act)

        self.view_menu.addSeparator()

        self.increase_font_size = QtGui.QAction("Zoom &In",
            self,
            shortcut=QtGui.QKeySequence.ZoomIn,
            triggered=self.increase_font_size_console
            )
        self.add_menu_action(self.view_menu, self.increase_font_size, True)

        self.decrease_font_size = QtGui.QAction("Zoom &Out",
            self,
            shortcut=QtGui.QKeySequence.ZoomOut,
            triggered=self.decrease_font_size_console
            )
        self.add_menu_action(self.view_menu, self.decrease_font_size, True)

        self.reset_font_size = QtGui.QAction("Zoom &Reset",
            self,
            shortcut="Ctrl+0",
            triggered=self.reset_font_size_console
            )
        self.add_menu_action(self.view_menu, self.reset_font_size, True)

        self.view_menu.addSeparator()

        self.clear_action = QtGui.QAction("&Clear Screen",
            self,
            shortcut='Ctrl+L',
            statusTip="Clear the console",
            triggered=self.clear_magic_console)
        self.add_menu_action(self.view_menu, self.clear_action)

    def init_import_menu(self):
        """Add an import menu item for every module in self.import_path"""
        self.import_names = set()
        self.import_menu = self.file_menu.addMenu("Import")
        private_path = os.path.join(os.path.expanduser('~'), '.nexpy', 'readers')
        if os.path.isdir(private_path):
            sys.path.append(private_path)
            for file in os.listdir(private_path):
                name, ext = os.path.splitext(file)
                if name <> '__init__' and ext.startswith('.py'):
                    self.import_names.add(name)
        sys.path.append(self.import_path)
        for file in os.listdir(self.import_path):
            name, ext = os.path.splitext(file)
            if name <> '__init__' and ext.startswith('.py'):
                self.import_names.add(name)
        self.importer = {}
        for import_name in sorted(self.import_names):
            fp, pathname, description = imp.find_module(import_name)
            try:
                import_module = imp.load_module(import_name, fp, pathname, description)
            finally:
                if fp:
                    fp.close()
            import_action = QtGui.QAction("Import "+import_module.filetype, self,
                                          triggered=self.show_import_dialog)
            self.add_menu_action(self.import_menu, import_action, self)
            self.importer[import_action] = import_module

    def show_import_dialog(self):
        import_module = self.importer[self.sender()]
        self.import_dialog = import_module.ImportDialog()
        self.import_dialog.show()

    def import_data(self):
        if self.import_dialog.accepted:
            workspace = self.treeview.tree.get_new_name()
            self.treeview.tree[workspace] = self.import_dialog.get_data()

    def new_workspace(self):
        default_name = self.treeview.tree.get_new_name()
        name, ok = QtGui.QInputDialog.getText(self, 'New Workspace', 
                         'Workspace Name:', text=default_name)        
        if name and ok:
            self.treeview.tree[name] = NXroot(NXentry())
  
    def open_file(self):
        fname, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open File (Read Only)',
                         self.default_directory, 
                         "NeXus Files (*.nxs *.nx5 *.h5 *.nx4 *.hdf *.xml)")
        workspace = self.treeview.tree.get_name(fname)
        self.treeview.tree[workspace] = self.user_ns[workspace] = nxload(fname)
        self.default_directory = os.path.dirname(fname)
  
    def open_editable_file(self):
        fname, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open File (Read/Write)',
                         self.default_directory, 
                         "NeXus Files (*.nxs *.nx5 *.h5 *.nx4 *.hdf *.xml)")
        workspace = self.treeview.tree.get_name(fname)
        self.treeview.tree[workspace] = self.user_ns[workspace] = nxload(fname, 'rw')
        self.default_directory = os.path.dirname(fname)

    def save_file(self):
        node = self.treeview.getnode()
        if node is None:
            return
        elif node.nxfile and isinstance(node, NXroot):
            try:
                node.save()
            except NeXusError, error_message:
                QtGui.QMessageBox.critical(
                      self, "Error saving file", str(error_message),
                      QtGui.QMessageBox.Ok, QtGui.QMessageBox.NoButton)
        else: