Exemplo n.º 1
0
 def tearDownClass(cls):
     import psyplot
     import psyplot.project as psy
     psyplot.rcParams.update_from_defaultParams()
     del cls.data
     psy.close('all')
     plt.close('all')
Exemplo n.º 2
0
 def tearDown(self):
     import psyplot.project as psy
     self.window.close()
     del self.window
     psy.close('all')
     rcParams.update_from_defaultParams()
     psy_rcParams.update_from_defaultParams()
     rcParams.disconnect()
     psy_rcParams.disconnect()
Exemplo n.º 3
0
def ds_widget(qtbot, test_ds):
    import psyplot.project as psy
    import matplotlib.pyplot as plt
    from psy_view.ds_widget import DatasetWidget
    w = DatasetWidget(test_ds)
    qtbot.addWidget(w)
    yield w
    w._sp = None
    psy.close('all')
    plt.close('all')
Exemplo n.º 4
0
 def tearDown(self):
     for identifier in list(psy.registered_plotters):
         psy.unregister_plotter(identifier)
     psy.close('all')
     plt.close('all')
     tp.results.clear()
     if remove_temp_files:
         for f in self._created_files:
             if osp.exists(f) and osp.isdir(f):
                 shutil.rmtree(f)
             elif osp.exists(f):
                 os.remove(f)
         self._created_files.clear()
Exemplo n.º 5
0
 def tearDown(self):
     import psyplot.project as psy
     import matplotlib.pyplot as plt
     if not running_in_gui:
         import psyplot_gui.main as main
         self.window.close()
         rcParams.update_from_defaultParams()
         psy_rcParams.update_from_defaultParams()
         rcParams.disconnect()
         psy_rcParams.disconnect()
         main._set_mainwindow(None)
     del self.window
     psy.close('all')
     plt.close('all')
Exemplo n.º 6
0
 def tearDown(self):
     import psyplot.project as psy
     import matplotlib.pyplot as plt
     if not running_in_gui:
         import psyplot_gui.main as main
         self.window.close()
         rcParams.update_from_defaultParams()
         psy_rcParams.update_from_defaultParams()
         rcParams.disconnect()
         psy_rcParams.disconnect()
         main._set_mainwindow(None)
     del self.window
     psy.close('all')
     plt.close('all')
Exemplo n.º 7
0
    def tearDown(self):
        import matplotlib.pyplot as plt
        from straditize.straditizer import Straditizer
        from straditize.binary import DataReader
        from psyplot.data import Signal
        import psyplot.project as psy

        # potentially recreate the straditizer control
        try:
            restart = self.straditizer_widgets.apply_button.isEnabled()
        except (AttributeError, RuntimeError):
            pass
        else:
            self.straditizer_widgets.reset_control()
            if restart:
                self.tearDownClass()
                self.setUpClass()

        for obj in gc.get_objects():
            if isinstance(obj, Signal):
                obj.disconnect()
        psy.close('all')
        plt.close('all')
        for f in self.created_files:
            if osp.exists(f):
                try:
                    os.remove(f)
                except Exception:
                    pass

        # ------- Tracking down memory leaks ---------
        # Now we check, that the straditizers are correctly garbage collected
        gc.collect()
        straditizers = [obj for obj in gc.get_objects()
                        if isinstance(obj, Straditizer)]
#        print('Straditizers:', straditizers)
#        if len(straditizers) >= 5:
#            print(gc.get_referrers(straditizers[0]))
        self.assertLess(len(straditizers), 5,
                        msg='Straditizers have not been garbage collected!')

        # And we check, for readers
        readers = [obj for obj in gc.get_objects()
                   if isinstance(obj, DataReader)]
#        print('Readers:', readers)
#        if len(readers) >= 5:
#            print(gc.get_referrers(readers[0]))
        self.assertLess(len(readers), 5,
                        msg='DataReaders have not been garbage collected!')
Exemplo n.º 8
0
    def test_main_02_alternative_ds(self):

        sp, fname1 = self._create_and_save_test_project()
        fname2 = tempfile.NamedTemporaryFile(
            suffix='.pdf', prefix='test_psyplot_').name
        self._created_files.add(fname2)
        sp.save_project(fname1, use_rel_paths=False)
        psy.close('all')
        main.main([bt.get_file('circumpolar_test.nc'), '-p', fname1,
                   '-o', fname2])
        self.assertTrue(osp.exists(fname2), msg='Missing ' + fname2)
        mp = psy.gcp(True)
        self.assertEqual(len(mp), 4)
        self.assertEqual(
             set(t[0] for t in mp._get_dsnames(mp.array_info(
                 dump=False, use_rel_paths=False))),
             {bt.get_file('circumpolar_test.nc')})
Exemplo n.º 9
0
 def test_main_01_from_project(self):
     """Test the :func:`psyplot.__main__.main` function"""
     if not six.PY2:
         with self.assertRaisesRegex(ValueError, 'filename'):
             main.main(['-o', 'test.pdf'])
     sp, fname1 = self._create_and_save_test_project()
     fname2 = tempfile.NamedTemporaryFile(
                 suffix='.pdf', prefix='test_psyplot_').name
     self._created_files.add(fname2)
     sp.save_project(fname1, use_rel_paths=False)
     psy.close('all')
     if six.PY2:
         main.main(['-p', fname1, '-o', fname2])
     else:
         with self.assertWarnsRegex(UserWarning, 'ignored'):
             main.main(['-p', fname1, '-o', fname2, '-n', 't2m'])
     self.assertTrue(osp.exists(fname2), msg='Missing ' + fname2)
     self.assertEqual(len(psy.gcp(True)), 4)
Exemplo n.º 10
0
 def setUp(self):
     psy.close('all')
     plt.close('all')
     self._created_files = set()
Exemplo n.º 11
0
    def __init__(self, show=True):
        """
        Parameters
        ----------
        show: bool
            If True, the created mainwindow is show
        """
        if sys.stdout is None:
            sys.stdout = StreamToLogger(self.logger)
        if sys.stderr is None:
            sys.stderr = StreamToLogger(self.logger)
        super(MainWindow, self).__init__()
        self.setWindowIcon(QIcon(get_icon('logo.png')))

        #: list of figures from the psyplot backend
        self.figures = []
        self.error_msg = PyErrorMessage(self)
        self.setDockOptions(QMainWindow.AnimatedDocks
                            | QMainWindow.AllowNestedDocks
                            | QMainWindow.AllowTabbedDocks)
        #: Inprocess console
        self.console = ConsoleWidget(self)
        self.project_actions = {}

        self.config_pages = []

        self.open_file_options = OrderedDict([
            ('new psyplot plot from dataset', self.open_external_files),
            ('new psyplot project', partial(self.open_external_files, [])),
        ])

        # ---------------------------------------------------------------------
        # ----------------------------- Menus ---------------------------------
        # ---------------------------------------------------------------------

        # ######################## File menu ##################################

        # --------------------------- New plot --------------------------------

        self.file_menu = QMenu('File', parent=self)
        self.new_plot_action = QAction('New plot', self)
        self.new_plot_action.setStatusTip(
            'Use an existing dataset (or open a new one) to create one or '
            'more plots')
        self.register_shortcut(self.new_plot_action, QKeySequence.New)
        self.new_plot_action.triggered.connect(lambda: self.new_plots(True))
        self.file_menu.addAction(self.new_plot_action)

        # --------------------------- Open project ----------------------------

        self.open_project_menu = QMenu('Open project', self)
        self.file_menu.addMenu(self.open_project_menu)

        self.open_mp_action = QAction('New main project', self)
        self.register_shortcut(self.open_mp_action, QKeySequence.Open)
        self.open_mp_action.setStatusTip('Open a new main project')
        self.open_mp_action.triggered.connect(self.open_mp)
        self.open_project_menu.addAction(self.open_mp_action)

        self.open_sp_action = QAction('Add to current', self)

        self.register_shortcut(
            self.open_sp_action,
            QKeySequence('Ctrl+Shift+O', QKeySequence.NativeText))
        self.open_sp_action.setStatusTip(
            'Load a project as a sub project and add it to the current main '
            'project')
        self.open_sp_action.triggered.connect(self.open_sp)
        self.open_project_menu.addAction(self.open_sp_action)

        # ---------------------- load preset menu -----------------------------

        self.load_preset_menu = QMenu('Load preset', parent=self)
        self.file_menu.addMenu(self.load_preset_menu)

        self.load_sp_preset_action = self.load_preset_menu.addAction(
            "For selection", self.load_sp_preset)
        self.load_sp_preset_action.setStatusTip(
            "Load a preset for the selected project")

        self.load_mp_preset_action = self.load_preset_menu.addAction(
            "For full project", self.load_mp_preset)
        self.load_sp_preset_action.setStatusTip(
            "Load a preset for the full project")

        # ----------------------- Save project --------------------------------

        self.save_project_menu = QMenu('Save', parent=self)
        self.file_menu.addMenu(self.save_project_menu)

        self.save_mp_action = QAction('Full psyplot project', self)
        self.save_mp_action.setStatusTip(
            'Save the entire project into a pickle file')
        self.register_shortcut(self.save_mp_action, QKeySequence.Save)
        self.save_mp_action.triggered.connect(self.save_mp)
        self.save_project_menu.addAction(self.save_mp_action)

        self.save_sp_action = QAction('Selected psyplot project', self)
        self.save_sp_action.setStatusTip(
            'Save the selected sub project into a pickle file')
        self.save_sp_action.triggered.connect(self.save_sp)
        self.save_project_menu.addAction(self.save_sp_action)

        # ------------------------ Save project as ----------------------------

        self.save_project_as_menu = QMenu('Save as', parent=self)
        self.file_menu.addMenu(self.save_project_as_menu)

        self.save_mp_as_action = QAction('Full psyplot project', self)
        self.save_mp_as_action.setStatusTip(
            'Save the entire project into a pickle file')
        self.register_shortcut(self.save_mp_as_action, QKeySequence.SaveAs)
        self.save_mp_as_action.triggered.connect(
            partial(self.save_mp, new_fname=True))
        self.save_project_as_menu.addAction(self.save_mp_as_action)

        self.save_sp_as_action = QAction('Selected psyplot project', self)
        self.save_sp_as_action.setStatusTip(
            'Save the selected sub project into a pickle file')
        self.save_sp_as_action.triggered.connect(
            partial(self.save_sp, new_fname=True))
        self.save_project_as_menu.addAction(self.save_sp_as_action)

        # ------------------------ Save preset --------------------------------

        self.save_preset_menu = QMenu('Save preset', parent=self)
        self.file_menu.addMenu(self.save_preset_menu)

        self.save_sp_preset_action = self.save_preset_menu.addAction(
            "Selection", self.save_sp_preset)
        self.save_sp_preset_action.setStatusTip(
            "Save the formatoptions of the selected project as a preset")

        self.save_mp_preset_action = self.save_preset_menu.addAction(
            "Full project", self.save_mp_preset)
        self.save_sp_preset_action.setStatusTip(
            "Save the formatoptions of the full project as a preset")

        # -------------------------- Pack project -----------------------------

        self.pack_project_menu = QMenu('Zip project files', parent=self)
        self.file_menu.addMenu(self.pack_project_menu)

        self.pack_mp_action = QAction('Full psyplot project', self)
        self.pack_mp_action.setStatusTip(
            'Pack all the data of the main project into one folder')
        self.pack_mp_action.triggered.connect(partial(self.save_mp, pack=True))
        self.pack_project_menu.addAction(self.pack_mp_action)

        self.pack_sp_action = QAction('Selected psyplot project', self)
        self.pack_sp_action.setStatusTip(
            'Pack all the data of the current sub project into one folder')
        self.pack_sp_action.triggered.connect(partial(self.save_sp, pack=True))
        self.pack_project_menu.addAction(self.pack_sp_action)

        # ------------------------ Export figures -----------------------------

        self.export_project_menu = QMenu('Export figures', parent=self)
        self.file_menu.addMenu(self.export_project_menu)

        self.export_mp_action = QAction('Full psyplot project', self)
        self.export_mp_action.setStatusTip(
            'Pack all the data of the main project into one folder')
        self.export_mp_action.triggered.connect(self.export_mp)
        self.register_shortcut(self.export_mp_action,
                               QKeySequence('Ctrl+E', QKeySequence.NativeText))
        self.export_project_menu.addAction(self.export_mp_action)

        self.export_sp_action = QAction('Selected psyplot project', self)
        self.export_sp_action.setStatusTip(
            'Pack all the data of the current sub project into one folder')
        self.register_shortcut(
            self.export_sp_action,
            QKeySequence('Ctrl+Shift+E', QKeySequence.NativeText))
        self.export_sp_action.triggered.connect(self.export_sp)
        self.export_project_menu.addAction(self.export_sp_action)

        # ------------------------ Close project ------------------------------

        self.file_menu.addSeparator()

        self.close_project_menu = QMenu('Close project', parent=self)
        self.file_menu.addMenu(self.close_project_menu)

        self.close_mp_action = QAction('Full psyplot project', self)
        self.register_shortcut(
            self.close_mp_action,
            QKeySequence('Ctrl+Shift+W', QKeySequence.NativeText))
        self.close_mp_action.setStatusTip(
            'Close the main project and delete all data and plots out of '
            'memory')
        self.close_mp_action.triggered.connect(
            lambda: psy.close(psy.gcp(True).num))
        self.close_project_menu.addAction(self.close_mp_action)

        self.close_sp_action = QAction('Selected psyplot project', self)
        self.close_sp_action.setStatusTip(
            'Close the selected arrays project and delete all data and plots '
            'out of memory')
        self.register_shortcut(self.close_sp_action, QKeySequence.Close)
        self.close_sp_action.triggered.connect(
            lambda: psy.gcp().close(True, True))
        self.close_project_menu.addAction(self.close_sp_action)

        # ----------------------------- Quit ----------------------------------

        if sys.platform != 'darwin':  # mac os makes this anyway
            self.quit_action = QAction('Quit', self)
            self.quit_action.triggered.connect(self.close)
            self.quit_action.triggered.connect(
                QtCore.QCoreApplication.instance().quit)
            self.register_shortcut(self.quit_action, QKeySequence.Quit)
            self.file_menu.addAction(self.quit_action)

        self.menuBar().addMenu(self.file_menu)

        # ######################## Console menu ###############################

        self.console_menu = QMenu('Console', self)
        self.console_menu.addActions(self.console.actions())
        self.menuBar().addMenu(self.console_menu)

        # ######################## Windows menu ###############################

        self.windows_menu = QMenu('Windows', self)
        self.menuBar().addMenu(self.windows_menu)

        # ############################ Help menu ##############################

        self.help_menu = QMenu('Help', parent=self)
        self.menuBar().addMenu(self.help_menu)

        # -------------------------- Preferences ------------------------------

        self.help_action = QAction('Preferences', self)
        self.help_action.triggered.connect(lambda: self.edit_preferences(True))
        self.register_shortcut(self.help_action, QKeySequence.Preferences)
        self.help_menu.addAction(self.help_action)

        # ---------------------------- About ----------------------------------

        self.about_action = QAction('About', self)
        self.about_action.triggered.connect(self.about)
        self.help_menu.addAction(self.about_action)

        # ---------------------------- Dependencies ---------------------------

        self.dependencies_action = QAction('Dependencies', self)
        self.dependencies_action.triggered.connect(
            lambda: self.show_dependencies(True))
        self.help_menu.addAction(self.dependencies_action)

        self.dockwidgets = []

        # ---------------------------------------------------------------------
        # -------------------------- Dock windows -----------------------------
        # ---------------------------------------------------------------------
        #: tab widget displaying the arrays in current main and sub project
        #: tree widget displaying the open datasets
        self.project_content = ProjectContentWidget(parent=self)
        self.ds_tree = DatasetTree(parent=self)
        #: tree widget displaying the open figures
        self.figures_tree = FiguresTree(parent=self)
        #: help explorer
        self.help_explorer = help_explorer = HelpExplorer(parent=self)
        if 'HTML help' in help_explorer.viewers and help_explorer.viewers[
                'HTML help'].sphinx_thread is not None:
            help_explorer.viewers[
                'HTML help'].sphinx_thread.html_ready.connect(
                    self.focus_on_console)
        #: the DataFrameEditor widgets
        self.dataframeeditors = []
        #: general formatoptions widget
        self.fmt_widget = FormatoptionWidget(parent=self,
                                             help_explorer=help_explorer,
                                             console=self.console)

        # load plugin widgets
        self.plugins = plugins = OrderedDict([
            ('console', self.console),
            ('project_content', self.project_content),
            ('ds_tree', self.ds_tree),
            ('figures_tree', self.figures_tree),
            ('help_explorer', self.help_explorer),
            ('fmt_widget', self.fmt_widget),
        ])
        self.default_plugins = list(plugins)
        for plugin_name, w_class in six.iteritems(rcParams.load_plugins()):
            plugins[plugin_name] = w_class(parent=self)

        self.add_mp_to_menu()
        psy.Project.oncpchange.connect(self.eventually_add_mp_to_menu)
        self.windows_menu.addSeparator()

        self.window_layouts_menu = QMenu('Window layouts', self)
        self.restore_layout_action = QAction('Restore default layout', self)
        self.restore_layout_action.triggered.connect(self.setup_default_layout)
        self.window_layouts_menu.addAction(self.restore_layout_action)
        self.windows_menu.addMenu(self.window_layouts_menu)

        self.panes_menu = QMenu('Panes', self)
        self.windows_menu.addMenu(self.panes_menu)

        self.dataframe_menu = QMenu('DataFrame editors', self)
        self.dataframe_menu.addAction(
            'New Editor',
            partial(self.new_data_frame_editor, None, 'DataFrame Editor'))
        self.dataframe_menu.addSeparator()
        self.windows_menu.addMenu(self.dataframe_menu)

        self.central_widgets_menu = menu = QMenu('Central widget', self)
        self.windows_menu.addMenu(menu)
        self.central_widgets_actions = group = QActionGroup(self)
        group.setExclusive(True)

        # ---------------------------------------------------------------------
        # -------------------------- connections ------------------------------
        # ---------------------------------------------------------------------

        self.console.help_explorer = help_explorer
        psyp.default_print_func = partial(help_explorer.show_rst,
                                          oname='formatoption_docs')
        psy.PlotterInterface._print_func = psyp.default_print_func
        self.setCentralWidget(self.console)

        # make sure that the plots are shown between the project content and
        # the help explorer widget
        self.setCorner(Qt.TopLeftCorner, Qt.LeftDockWidgetArea)
        self.setCorner(Qt.TopRightCorner, Qt.RightDockWidgetArea)

        # make sure that the formatoption widgets are shown between the
        # project content and the help explorer widget
        self.setCorner(Qt.BottomLeftCorner, Qt.LeftDockWidgetArea)
        self.setCorner(Qt.BottomRightCorner, Qt.RightDockWidgetArea)

        # ---------------------------------------------------------------------
        # ------------------------------ closure ------------------------------
        # ---------------------------------------------------------------------
        if show:
            self.help_explorer.show_intro(self.console.intro_msg)

        # ---------------------------------------------------------------------
        # ------------------------- open_files_server -------------------------
        # ---------------------------------------------------------------------
        self.callbacks = {
            'new_plot': self.open_external.emit,
            'change_cwd': self._change_cwd,
            'run_script': self.console.run_script.emit,
            'command': self.console.run_command.emit,
        }

        # Server to open external files on a single instance
        self.open_files_server = socket.socket(socket.AF_INET,
                                               socket.SOCK_STREAM,
                                               socket.IPPROTO_TCP)

        if rcParams['main.listen_to_port']:
            self._file_thread = Thread(target=self.start_open_files_server)
            self._file_thread.setDaemon(True)
            self._file_thread.start()

            self.open_external.connect(self._open_external_files)

        self.config_pages.extend([GuiRcParamsWidget, PsyRcParamsWidget])

        # display the statusBar
        statusbar = self.statusBar()
        self.figures_label = QLabel()
        statusbar.addWidget(self.figures_label)
        self.plugin_label = QLabel()
        statusbar.addWidget(self.plugin_label)

        self.default_widths = {}

        self.setup_default_layout()

        if show:
            self.showMaximized()

        # save the default widths after they have been shown
        for w in self.plugins.values():
            if w.dock is not None:
                self.default_widths[w] = w.dock.size().width()

        # hide plugin widgets that should be hidden at startup. Although this
        # has been executed by :meth:`setup_default_layout`, we have to execute
        # it again after the call of showMaximized
        for name, w in self.plugins.items():
            if name != self.central_widget_key:
                w.to_dock(self)
                if w.hidden:
                    w.hide_plugin()
            else:
                w.create_central_widget_action(self).setChecked(True)

        self._is_open = True
Exemplo n.º 12
0
 def tearDown(self):
     import psyplot.project as psy
     super(FormatoptionWidgetTest, self).tearDown()
     psy.close('all')
     del self.project
Exemplo n.º 13
0
    def __init__(self):
        super(MainWindow, self).__init__()

        #: list of figures from the psyplot backend
        self.figures = []
        self.error_msg = PyErrorMessage(self)
        self.setDockOptions(
            QMainWindow.AnimatedDocks | QMainWindow.AllowNestedDocks |
            QMainWindow.AllowTabbedDocks)
        #: Inprocess console
        self.console = ConsoleWidget(parent=self)
        self.project_actions = {}

        # ---------------------------------------------------------------------
        # ----------------------------- Menus ---------------------------------
        # ---------------------------------------------------------------------

        # ######################## File menu ##################################

        # --------------------------- New plot --------------------------------

        self.file_menu = QMenu('File', parent=self)
        self.new_plot_action = QAction('New plot', self)
        self.new_plot_action.setStatusTip(
            'Use an existing dataset (or open a new one) to create one or '
            'more plots')
        self.new_plot_action.setShortcut(QKeySequence.New)
        self.new_plot_action.triggered.connect(self.new_plots)
        self.file_menu.addAction(self.new_plot_action)

        # --------------------------- Open project ----------------------------

        self.open_project_menu = QMenu('Open project', self)
        self.file_menu.addMenu(self.open_project_menu)

        self.open_mp_action = QAction('New main project', self)
        self.open_mp_action.setShortcut(QKeySequence.Open)
        self.open_mp_action.setStatusTip('Open a new main project')
        self.open_mp_action.triggered.connect(self.open_mp)
        self.open_project_menu.addAction(self.open_mp_action)

        self.open_sp_action = QAction('Add to current', self)
        self.open_sp_action.setShortcut(QKeySequence(
            'Ctrl+Shift+O', QKeySequence.NativeText))
        self.open_sp_action.setStatusTip(
            'Load a project as a sub project and add it to the current main '
            'project')
        self.open_sp_action.triggered.connect(self.open_sp)
        self.open_project_menu.addAction(self.open_sp_action)

        # ----------------------- Save project --------------------------------

        self.save_project_menu = QMenu('Save project', parent=self)
        self.file_menu.addMenu(self.save_project_menu)

        self.save_mp_action = QAction('All', self)
        self.save_mp_action.setStatusTip(
            'Save the entire project into a pickle file')
        self.save_mp_action.setShortcut(QKeySequence.Save)
        self.save_mp_action.triggered.connect(self.save_mp)
        self.save_project_menu.addAction(self.save_mp_action)

        self.save_sp_action = QAction('Selected', self)
        self.save_sp_action.setStatusTip(
            'Save the selected sub project into a pickle file')
        self.save_sp_action.triggered.connect(self.save_sp)
        self.save_project_menu.addAction(self.save_sp_action)

        # ------------------------ Save project as ----------------------------

        self.save_project_menu = QMenu('Save project', parent=self)
        self.file_menu.addMenu(self.save_project_menu)

        self.save_project_as_menu = QMenu('Save project as', parent=self)
        self.file_menu.addMenu(self.save_project_as_menu)

        self.save_mp_as_action = QAction('All', self)
        self.save_mp_as_action.setStatusTip(
            'Save the entire project into a pickle file')
        self.save_mp_as_action.setShortcut(QKeySequence.SaveAs)
        self.save_mp_as_action.triggered.connect(
            partial(self.save_mp, new_name=True))
        self.save_project_as_menu.addAction(self.save_mp_as_action)

        self.save_sp_as_action = QAction('Selected', self)
        self.save_sp_as_action.setStatusTip(
            'Save the selected sub project into a pickle file')
        self.save_sp_as_action.triggered.connect(
            partial(self.save_sp, new_name=True))
        self.save_project_as_menu.addAction(self.save_sp_as_action)

        # -------------------------- Pack project -----------------------------

        self.pack_project_menu = QMenu('Zip project files', parent=self)
        self.file_menu.addMenu(self.pack_project_menu)

        self.pack_mp_action = QAction('All', self)
        self.pack_mp_action.setStatusTip(
            'Pack all the data of the main project into one folder')
        self.pack_mp_action.triggered.connect(partial(self.save_mp, pack=True))
        self.pack_project_menu.addAction(self.pack_mp_action)

        self.pack_sp_action = QAction('Selected', self)
        self.pack_sp_action.setStatusTip(
            'Pack all the data of the current sub project into one folder')
        self.pack_sp_action.triggered.connect(partial(self.save_sp, pack=True))
        self.pack_project_menu.addAction(self.pack_sp_action)

        # ------------------------ Export figures -----------------------------

        self.export_project_menu = QMenu('Export figures', parent=self)
        self.file_menu.addMenu(self.export_project_menu)

        self.export_mp_action = QAction('All', self)
        self.export_mp_action.setStatusTip(
            'Pack all the data of the main project into one folder')
        self.export_mp_action.triggered.connect(self.export_mp)
        self.export_mp_action.setShortcut(QKeySequence(
            'Ctrl+E', QKeySequence.NativeText))
        self.export_project_menu.addAction(self.export_mp_action)

        self.export_sp_action = QAction('Selected', self)
        self.export_sp_action.setStatusTip(
            'Pack all the data of the current sub project into one folder')
        self.export_sp_action.setShortcut(QKeySequence(
            'Ctrl+Shift+E', QKeySequence.NativeText))
        self.export_sp_action.triggered.connect(self.export_sp)
        self.export_project_menu.addAction(self.export_sp_action)

        # ------------------------ Close project ------------------------------

        self.file_menu.addSeparator()

        self.close_project_menu = QMenu('Close project', parent=self)
        self.file_menu.addMenu(self.close_project_menu)

        self.close_mp_action = QAction('Main project', self)
        self.close_mp_action.setStatusTip(
            'Close the main project and delete all data and plots out of '
            'memory')
        self.close_mp_action.setShortcut(QKeySequence.Close)
        self.close_mp_action.triggered.connect(
            lambda: psy.close(psy.gcp(True).num))
        self.close_project_menu.addAction(self.close_mp_action)

        self.close_sp_action = QAction('Only selected', self)
        self.close_sp_action.setStatusTip(
            'Close the selected arrays project and delete all data and plots '
            'out of memory')
        self.close_sp_action.setShortcut(QKeySequence(
            'Ctrl+Shift+W', QKeySequence.NativeText))
        self.close_sp_action.triggered.connect(
            lambda: psy.gcp().close(True, True))
        self.close_project_menu.addAction(self.close_sp_action)

        # ------------------------ Quit ------------------------------

        if sys.platform != 'darwin':  # mac os makes this anyway
            self.quit_action = QAction('Quit', self)
            self.quit_action.triggered.connect(
                QtCore.QCoreApplication.instance().quit)
            self.quit_action.setShortcut(QKeySequence.Quit)
            self.file_menu.addAction(self.quit_action)

        self.menuBar().addMenu(self.file_menu)

        # ######################## Console menu ###############################

        self.console_menu = QMenu('Console', self)
        self.console_menu.addActions(self.console.actions())
        self.menuBar().addMenu(self.console_menu)

        # ######################## Windows menu ###############################

        self.windows_menu = QMenu('Windows', self)
        self.menuBar().addMenu(self.windows_menu)

        # ---------------------------------------------------------------------
        # -------------------------- Dock windows -----------------------------
        # ---------------------------------------------------------------------
        #: tab widget displaying the arrays in current main and sub project
        self.project_content = ProjectContentWidget(parent=self)
        self.addDockWidget(Qt.LeftDockWidgetArea,
                           self.project_content.to_dock('Plot objects', self),
                           'pane')
        #: tree widget displaying the open datasets
        self.ds_tree = DatasetTree(parent=self)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.ds_tree.to_dock(
            'Datasets', self), 'pane')
        #: tree widget displaying the open figures
        self.figures_tree = FiguresTree(parent=self)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.figures_tree.to_dock(
            'Figures', self), 'pane')
        #: help explorer
        self.help_explorer = help_explorer = HelpExplorer(parent=self)
        self.addDockWidget(Qt.RightDockWidgetArea, help_explorer.to_dock(
            'Help explorer', self), 'pane')
        #: general formatoptions widget
        self.fmt_widget = FormatoptionWidget(
            parent=self, help_explorer=help_explorer,
            shell=self.console.kernel_client.kernel.shell)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.fmt_widget.to_dock(
            'Formatoptions', self), 'pane')

        self.windows_menu.addSeparator()
        self.add_mp_to_menu()
        psy.Project.oncpchange.connect(self.eventually_add_mp_to_menu)

        # ---------------------------------------------------------------------
        # -------------------------- connections ------------------------------
        # ---------------------------------------------------------------------

        self.console.help_explorer = help_explorer
        psyp.default_print_func = partial(help_explorer.show_rst,
                                          oname='formatoption_docs')
        psy._PlotterInterface._print_func = psyp.default_print_func
        self.setCentralWidget(self.console)

        # make sure that the plots are shown between the project content and
        # the help explorer widget
        self.setCorner(Qt.TopLeftCorner, Qt.LeftDockWidgetArea)
        self.setCorner(Qt.TopRightCorner, Qt.RightDockWidgetArea)

        # make sure that the formatoption widgets are shown between the
        # project content and the help explorer widget
        self.setCorner(Qt.BottomLeftCorner, Qt.LeftDockWidgetArea)
        self.setCorner(Qt.BottomRightCorner, Qt.RightDockWidgetArea)

        # Server to open external files on a single instance
        self.open_files_server = socket.socket(socket.AF_INET,
                                               socket.SOCK_STREAM,
                                               socket.IPPROTO_TCP)

        self.showMaximized()

        self._file_thread = Thread(target=self.start_open_files_server)
        self._file_thread.setDaemon(True)
        self._file_thread.start()

        self.open_external.connect(self.open_external_files)

        # ---------------------------------------------------------------------
        # ------------------------------ closure ------------------------------
        # ---------------------------------------------------------------------
        self.help_explorer.show_intro(self.console.intro_msg)
Exemplo n.º 14
0
 def tearDown(self):
     import psyplot.project as psy
     super(FormatoptionWidgetTest, self).tearDown()
     psy.close('all')
     del self.project
Exemplo n.º 15
0
    def __init__(self, show=True):
        """
        Parameters
        ----------
        show: bool
            If True, the created mainwindow is show
        """
        if sys.stdout is None:
            sys.stdout = StreamToLogger(self.logger)
        if sys.stderr is None:
            sys.stderr = StreamToLogger(self.logger)
        super(MainWindow, self).__init__()
        self.setWindowIcon(QIcon(get_icon('logo.png')))

        #: list of figures from the psyplot backend
        self.figures = []
        self.error_msg = PyErrorMessage(self)
        self.setDockOptions(
            QMainWindow.AnimatedDocks | QMainWindow.AllowNestedDocks |
            QMainWindow.AllowTabbedDocks)
        #: Inprocess console
        self.console = ConsoleWidget(self)
        self.project_actions = {}

        self.config_pages = []

        self.open_file_options = OrderedDict([
            ('new psyplot plot from dataset', self.open_external_files),
            ('new psyplot project', partial(self.open_external_files, [])),
            ])

        # ---------------------------------------------------------------------
        # ----------------------------- Menus ---------------------------------
        # ---------------------------------------------------------------------

        # ######################## File menu ##################################

        # --------------------------- New plot --------------------------------

        self.file_menu = QMenu('File', parent=self)
        self.new_plot_action = QAction('New plot', self)
        self.new_plot_action.setStatusTip(
            'Use an existing dataset (or open a new one) to create one or '
            'more plots')
        self.register_shortcut(self.new_plot_action, QKeySequence.New)
        self.new_plot_action.triggered.connect(lambda: self.new_plots(True))
        self.file_menu.addAction(self.new_plot_action)

        # --------------------------- Open project ----------------------------

        self.open_project_menu = QMenu('Open project', self)
        self.file_menu.addMenu(self.open_project_menu)

        self.open_mp_action = QAction('New main project', self)
        self.register_shortcut(self.open_mp_action, QKeySequence.Open)
        self.open_mp_action.setStatusTip('Open a new main project')
        self.open_mp_action.triggered.connect(self.open_mp)
        self.open_project_menu.addAction(self.open_mp_action)

        self.open_sp_action = QAction('Add to current', self)

        self.register_shortcut(
            self.open_sp_action, QKeySequence(
                'Ctrl+Shift+O', QKeySequence.NativeText))
        self.open_sp_action.setStatusTip(
            'Load a project as a sub project and add it to the current main '
            'project')
        self.open_sp_action.triggered.connect(self.open_sp)
        self.open_project_menu.addAction(self.open_sp_action)

        # ----------------------- Save project --------------------------------

        self.save_project_menu = QMenu('Save', parent=self)
        self.file_menu.addMenu(self.save_project_menu)

        self.save_mp_action = QAction('Full psyplot project', self)
        self.save_mp_action.setStatusTip(
            'Save the entire project into a pickle file')
        self.register_shortcut(self.save_mp_action, QKeySequence.Save)
        self.save_mp_action.triggered.connect(self.save_mp)
        self.save_project_menu.addAction(self.save_mp_action)

        self.save_sp_action = QAction('Selected psyplot project', self)
        self.save_sp_action.setStatusTip(
            'Save the selected sub project into a pickle file')
        self.save_sp_action.triggered.connect(self.save_sp)
        self.save_project_menu.addAction(self.save_sp_action)

        # ------------------------ Save project as ----------------------------

        self.save_project_as_menu = QMenu('Save as', parent=self)
        self.file_menu.addMenu(self.save_project_as_menu)

        self.save_mp_as_action = QAction('Full psyplot project', self)
        self.save_mp_as_action.setStatusTip(
            'Save the entire project into a pickle file')
        self.register_shortcut(self.save_mp_as_action,
                                       QKeySequence.SaveAs)
        self.save_mp_as_action.triggered.connect(
            partial(self.save_mp, new_fname=True))
        self.save_project_as_menu.addAction(self.save_mp_as_action)

        self.save_sp_as_action = QAction('Selected psyplot project', self)
        self.save_sp_as_action.setStatusTip(
            'Save the selected sub project into a pickle file')
        self.save_sp_as_action.triggered.connect(
            partial(self.save_sp, new_fname=True))
        self.save_project_as_menu.addAction(self.save_sp_as_action)

        # -------------------------- Pack project -----------------------------

        self.pack_project_menu = QMenu('Zip project files', parent=self)
        self.file_menu.addMenu(self.pack_project_menu)

        self.pack_mp_action = QAction('Full psyplot project', self)
        self.pack_mp_action.setStatusTip(
            'Pack all the data of the main project into one folder')
        self.pack_mp_action.triggered.connect(partial(self.save_mp, pack=True))
        self.pack_project_menu.addAction(self.pack_mp_action)

        self.pack_sp_action = QAction('Selected psyplot project', self)
        self.pack_sp_action.setStatusTip(
            'Pack all the data of the current sub project into one folder')
        self.pack_sp_action.triggered.connect(partial(self.save_sp, pack=True))
        self.pack_project_menu.addAction(self.pack_sp_action)

        # ------------------------ Export figures -----------------------------

        self.export_project_menu = QMenu('Export figures', parent=self)
        self.file_menu.addMenu(self.export_project_menu)

        self.export_mp_action = QAction('Full psyplot project', self)
        self.export_mp_action.setStatusTip(
            'Pack all the data of the main project into one folder')
        self.export_mp_action.triggered.connect(self.export_mp)
        self.register_shortcut(
            self.export_mp_action, QKeySequence(
                'Ctrl+E', QKeySequence.NativeText))
        self.export_project_menu.addAction(self.export_mp_action)

        self.export_sp_action = QAction('Selected psyplot project', self)
        self.export_sp_action.setStatusTip(
            'Pack all the data of the current sub project into one folder')
        self.register_shortcut(
            self.export_sp_action, QKeySequence(
                'Ctrl+Shift+E', QKeySequence.NativeText))
        self.export_sp_action.triggered.connect(self.export_sp)
        self.export_project_menu.addAction(self.export_sp_action)

        # ------------------------ Close project ------------------------------

        self.file_menu.addSeparator()

        self.close_project_menu = QMenu('Close project', parent=self)
        self.file_menu.addMenu(self.close_project_menu)

        self.close_mp_action = QAction('Full psyplot project', self)
        self.register_shortcut(
            self.close_mp_action, QKeySequence(
                'Ctrl+Shift+W', QKeySequence.NativeText))
        self.close_mp_action.setStatusTip(
            'Close the main project and delete all data and plots out of '
            'memory')
        self.close_mp_action.triggered.connect(
            lambda: psy.close(psy.gcp(True).num))
        self.close_project_menu.addAction(self.close_mp_action)

        self.close_sp_action = QAction('Selected psyplot project', self)
        self.close_sp_action.setStatusTip(
            'Close the selected arrays project and delete all data and plots '
            'out of memory')
        self.register_shortcut(self.close_sp_action, QKeySequence.Close)
        self.close_sp_action.triggered.connect(
            lambda: psy.gcp().close(True, True))
        self.close_project_menu.addAction(self.close_sp_action)

        # ----------------------------- Quit ----------------------------------

        if sys.platform != 'darwin':  # mac os makes this anyway
            self.quit_action = QAction('Quit', self)
            self.quit_action.triggered.connect(self.close)
            self.quit_action.triggered.connect(
                QtCore.QCoreApplication.instance().quit)
            self.register_shortcut(
                self.quit_action, QKeySequence.Quit)
            self.file_menu.addAction(self.quit_action)

        self.menuBar().addMenu(self.file_menu)

        # ######################## Console menu ###############################

        self.console_menu = QMenu('Console', self)
        self.console_menu.addActions(self.console.actions())
        self.menuBar().addMenu(self.console_menu)

        # ######################## Windows menu ###############################

        self.windows_menu = QMenu('Windows', self)
        self.menuBar().addMenu(self.windows_menu)

        # ############################ Help menu ##############################

        self.help_menu = QMenu('Help', parent=self)
        self.menuBar().addMenu(self.help_menu)

        # -------------------------- Preferences ------------------------------

        self.help_action = QAction('Preferences', self)
        self.help_action.triggered.connect(lambda: self.edit_preferences(True))
        self.register_shortcut(self.help_action,
                                       QKeySequence.Preferences)
        self.help_menu.addAction(self.help_action)

        # ---------------------------- About ----------------------------------

        self.about_action = QAction('About', self)
        self.about_action.triggered.connect(self.about)
        self.help_menu.addAction(self.about_action)

        # ---------------------------- Dependencies ---------------------------

        self.dependencies_action = QAction('Dependencies', self)
        self.dependencies_action.triggered.connect(
            lambda: self.show_dependencies(True))
        self.help_menu.addAction(self.dependencies_action)

        self.dockwidgets = []

        # ---------------------------------------------------------------------
        # -------------------------- Dock windows -----------------------------
        # ---------------------------------------------------------------------
        #: tab widget displaying the arrays in current main and sub project
        #: tree widget displaying the open datasets
        self.project_content = ProjectContentWidget(parent=self)
        self.ds_tree = DatasetTree(parent=self)
        #: tree widget displaying the open figures
        self.figures_tree = FiguresTree(parent=self)
        #: help explorer
        self.help_explorer = help_explorer = HelpExplorer(parent=self)
        if help_explorer.viewers['HTML help'].sphinx_thread is not None:
            help_explorer.viewers[
                'HTML help'].sphinx_thread.html_ready.connect(
                    self.focus_on_console)
        #: the DataFrameEditor widgets
        self.dataframeeditors = []
        #: general formatoptions widget
        self.fmt_widget = FormatoptionWidget(
            parent=self, help_explorer=help_explorer,
            console=self.console)

        # load plugin widgets
        self.plugins = plugins = OrderedDict([
            ('console', self.console),
            ('project_content', self.project_content),
            ('ds_tree', self.ds_tree),
            ('figures_tree', self.figures_tree),
            ('help_explorer', self.help_explorer),
            ('fmt_widget', self.fmt_widget),
            ])
        self.default_plugins = list(plugins)
        for plugin_name, w_class in six.iteritems(rcParams.load_plugins()):
            plugins[plugin_name] = w_class(parent=self)

        self.add_mp_to_menu()
        psy.Project.oncpchange.connect(self.eventually_add_mp_to_menu)
        self.windows_menu.addSeparator()

        self.window_layouts_menu = QMenu('Window layouts', self)
        self.restore_layout_action = QAction('Restore default layout', self)
        self.restore_layout_action.triggered.connect(self.setup_default_layout)
        self.window_layouts_menu.addAction(self.restore_layout_action)
        self.windows_menu.addMenu(self.window_layouts_menu)

        self.panes_menu = QMenu('Panes', self)
        self.windows_menu.addMenu(self.panes_menu)

        self.dataframe_menu = QMenu('DataFrame editors', self)
        self.dataframe_menu.addAction(
            'New Editor', partial(self.new_data_frame_editor, None,
                                  'DataFrame Editor'))
        self.dataframe_menu.addSeparator()
        self.windows_menu.addMenu(self.dataframe_menu)

        self.central_widgets_menu = menu = QMenu('Central widget', self)
        self.windows_menu.addMenu(menu)
        self.central_widgets_actions = group = QActionGroup(self)
        group.setExclusive(True)

        # ---------------------------------------------------------------------
        # -------------------------- connections ------------------------------
        # ---------------------------------------------------------------------

        self.console.help_explorer = help_explorer
        psyp.default_print_func = partial(help_explorer.show_rst,
                                          oname='formatoption_docs')
        psy.PlotterInterface._print_func = psyp.default_print_func
        self.setCentralWidget(self.console)

        # make sure that the plots are shown between the project content and
        # the help explorer widget
        self.setCorner(Qt.TopLeftCorner, Qt.LeftDockWidgetArea)
        self.setCorner(Qt.TopRightCorner, Qt.RightDockWidgetArea)

        # make sure that the formatoption widgets are shown between the
        # project content and the help explorer widget
        self.setCorner(Qt.BottomLeftCorner, Qt.LeftDockWidgetArea)
        self.setCorner(Qt.BottomRightCorner, Qt.RightDockWidgetArea)

        # ---------------------------------------------------------------------
        # ------------------------------ closure ------------------------------
        # ---------------------------------------------------------------------
        if show:
            self.help_explorer.show_intro(self.console.intro_msg)

        # ---------------------------------------------------------------------
        # ------------------------- open_files_server -------------------------
        # ---------------------------------------------------------------------
        self.callbacks = {'new_plot': self.open_external.emit,
                          'change_cwd': self._change_cwd,
                          'run_script': self.console.run_script.emit,
                          'command': self.console.run_command.emit,
                          }

        # Server to open external files on a single instance
        self.open_files_server = socket.socket(socket.AF_INET,
                                               socket.SOCK_STREAM,
                                               socket.IPPROTO_TCP)

        if rcParams['main.listen_to_port']:
            self._file_thread = Thread(target=self.start_open_files_server)
            self._file_thread.setDaemon(True)
            self._file_thread.start()

            self.open_external.connect(self._open_external_files)

        self.config_pages.extend([GuiRcParamsWidget, PsyRcParamsWidget])

        # display the statusBar
        statusbar = self.statusBar()
        self.figures_label = QLabel()
        statusbar.addWidget(self.figures_label)
        self.plugin_label = QLabel()
        statusbar.addWidget(self.plugin_label)

        self.default_widths = {}

        self.setup_default_layout()

        if show:
            self.showMaximized()

        # save the default widths after they have been shown
        for w in self.plugins.values():
            if w.dock is not None:
                self.default_widths[w] = w.dock.size().width()

        # hide plugin widgets that should be hidden at startup. Although this
        # has been executed by :meth:`setup_default_layout`, we have to execute
        # it again after the call of showMaximized
        for name, w in self.plugins.items():
            if name != self.central_widget_key:
                w.to_dock(self)
                if w.hidden:
                    w.hide_plugin()
            else:
                w.create_central_widget_action(self).setChecked(True)

        self._is_open = True