示例#1
0
    def __init__(self, *args, **kwargs):
        self.sphinx_dir = kwargs.pop('sphinx_dir', mkdtemp())
        self.build_dir = osp.join(self.sphinx_dir, '_build', 'html')
        super(UrlHelp, self).__init__(*args, **kwargs)

        self.error_msg = PyErrorMessage(self)
        if with_sphinx:
            self.sphinx_thread = SphinxThread(self.sphinx_dir)
            self.sphinx_thread.html_ready[str].connect(self.browse)
            self.sphinx_thread.html_error[str].connect(
                self.error_msg.showTraceback)
            self.sphinx_thread.html_error[str].connect(logger.debug)
            rcParams.connect('help_explorer.render_docs_parallel',
                             self.reset_sphinx)
            rcParams.connect('help_explorer.use_intersphinx',
                             self.reset_sphinx)
            rcParams.connect('help_explorer.online', self.reset_sphinx)

        else:
            self.sphinx_thread = None

        self.bt_connect_console = QToolButton(self)
        self.bt_connect_console.setCheckable(True)
        if rcParams['console.connect_to_help']:
            self.bt_connect_console.setIcon(
                QIcon(get_icon('ipython_console.png')))
            self.bt_connect_console.click()
        else:
            self.bt_connect_console.setIcon(
                QIcon(get_icon('ipython_console_t.png')))
        self.bt_connect_console.clicked.connect(self.toogle_connect_console)
        rcParams.connect('console.connect_to_help',
                         self.update_connect_console)
        self.toogle_connect_console()

        # menu button with different urls
        self.bt_url_menus = QToolButton(self)
        self.bt_url_menus.setIcon(QIcon(get_icon('docu_button.png')))
        self.bt_url_menus.setToolTip('Browse documentations')
        self.bt_url_menus.setPopupMode(QToolButton.InstantPopup)

        docu_menu = QMenu(self)
        for name, url in six.iteritems(self.doc_urls):

            def to_url(b, url=url):
                self.browse(url)

            action = QAction(name, self)
            action.triggered.connect(to_url)
            docu_menu.addAction(action)
        self.bt_url_menus.setMenu(docu_menu)

        self.button_box.addWidget(self.bt_connect_console)
        self.button_box.addWidget(self.bt_url_menus)
        # toogle the lock again to set the bt_url_menus enabled state
        self.toogle_url_lock()
示例#2
0
    def __init__(self, *args, **kwargs):
        self._temp_dir = 'sphinx_dir' not in kwargs
        self.sphinx_dir = kwargs.pop('sphinx_dir', mkdtemp(prefix='psyplot_'))
        self.build_dir = osp.join(self.sphinx_dir, '_build', 'html')
        super(UrlHelp, self).__init__(*args, **kwargs)

        self.error_msg = PyErrorMessage(self)
        if with_sphinx:
            self.sphinx_thread = SphinxThread(self.sphinx_dir)
            self.sphinx_thread.html_ready[str].connect(self.browse)
            self.sphinx_thread.html_error[str].connect(
                self.error_msg.showTraceback)
            self.sphinx_thread.html_error[str].connect(logger.debug)
            rcParams.connect('help_explorer.render_docs_parallel',
                             self.reset_sphinx)
            rcParams.connect('help_explorer.use_intersphinx',
                             self.reset_sphinx)
            rcParams.connect('help_explorer.online',
                             self.reset_sphinx)

        self.bt_connect_console = QToolButton(self)
        self.bt_connect_console.setCheckable(True)
        if rcParams['console.connect_to_help']:
            self.bt_connect_console.setIcon(QIcon(get_icon(
                'ipython_console.png')))
            self.bt_connect_console.click()
        else:
            self.bt_connect_console.setIcon(QIcon(get_icon(
                'ipython_console_t.png')))
        self.bt_connect_console.clicked.connect(self.toogle_connect_console)
        rcParams.connect('console.connect_to_help',
                         self.update_connect_console)
        self.toogle_connect_console()

        # menu button with different urls
        self.bt_url_menus = QToolButton(self)
        self.bt_url_menus.setIcon(QIcon(get_icon('docu_button.png')))
        self.bt_url_menus.setToolTip('Browse documentations')
        self.bt_url_menus.setPopupMode(QToolButton.InstantPopup)

        docu_menu = QMenu(self)
        for name, url in six.iteritems(self.doc_urls):
            def to_url(b, url=url):
                self.browse(url)
            action = QAction(name, self)
            action.triggered.connect(to_url)
            docu_menu.addAction(action)
        self.bt_url_menus.setMenu(docu_menu)

        self.button_box.addWidget(self.bt_connect_console)
        self.button_box.addWidget(self.bt_url_menus)
        # toogle the lock again to set the bt_url_menus enabled state
        self.toogle_url_lock()
示例#3
0
 def initialize(self):
     """Fill the items of the :attr:`rc` into the tree"""
     rcParams = self.rc
     descriptions = self.descriptions
     self.valid = [True] * len(rcParams)
     validators = self.validators
     vcol = self.value_col
     for i, (key, val) in enumerate(sorted(rcParams.items())):
         item = QTreeWidgetItem(0)
         item.setText(0, key)
         item.setToolTip(0, key)
         item.setIcon(1, QIcon(get_icon('valid.png')))
         desc = descriptions.get(key)
         if desc:
             item.setText(vcol, desc)
             item.setToolTip(vcol, desc)
         child = QTreeWidgetItem(0)
         item.addChild(child)
         self.addTopLevelItem(item)
         editor = QTextEdit(self)
         # set maximal height of the editor to 3 rows
         editor.setMaximumHeight(4 *
                                 QtGui.QFontMetrics(editor.font()).height())
         editor.setPlainText(yaml.dump(val))
         self.setItemWidget(child, vcol, editor)
         editor.textChanged.connect(
             self.set_icon_func(i, item, validators[key]))
     self.resizeColumnToContents(0)
     self.resizeColumnToContents(1)
示例#4
0
    def __init__(self, *args, **kwargs):
        self.sphinx_dir = kwargs.pop('sphinx_dir', mkdtemp())
        self.build_dir = osp.join(self.sphinx_dir, '_build', 'html')
        super(UrlHelp, self).__init__(*args, **kwargs)

        self.error_msg = PyErrorMessage(self)
        if with_sphinx:
            self.sphinx_thread = SphinxThread(self.sphinx_dir)
            self.sphinx_thread.html_ready[str].connect(self.browse)
            self.sphinx_thread.html_error[str].connect(
                self.error_msg.showTraceback)
            self.sphinx_thread.html_error[str].connect(logger.debug)
        else:
            self.sphinx_thread = None

        #: menu button with different urls
        self.bt_url_menus = QToolButton(self)
        self.bt_url_menus.setIcon(QIcon(get_icon('docu_button.png')))
        self.bt_url_menus.setToolTip('Browse documentations')
        self.bt_url_menus.setPopupMode(QToolButton.InstantPopup)

        docu_menu = QMenu(self)
        for name, url in six.iteritems(self.doc_urls):
            def to_url(b, url=url):
                self.browse(url)
            action = QAction(name, self)
            action.triggered.connect(to_url)
            docu_menu.addAction(action)
        self.bt_url_menus.setMenu(docu_menu)

        self.button_box.addWidget(self.bt_url_menus)
示例#5
0
 def initialize(self):
     """Fill the items of the :attr:`rc` into the tree"""
     rcParams = self.rc
     descriptions = self.descriptions
     self.valid = [True] * len(rcParams)
     validators = self.validators
     vcol = self.value_col
     for i, (key, val) in enumerate(sorted(rcParams.items())):
         item = QTreeWidgetItem(0)
         item.setText(0, key)
         item.setToolTip(0, key)
         item.setIcon(1, QIcon(get_icon('valid.png')))
         desc = descriptions.get(key)
         if desc:
             item.setText(vcol, desc)
             item.setToolTip(vcol, desc)
         child = QTreeWidgetItem(0)
         item.addChild(child)
         self.addTopLevelItem(item)
         editor = QTextEdit(self)
         # set maximal height of the editor to 3 rows
         editor.setMaximumHeight(
             4 * QtGui.QFontMetrics(editor.font()).height())
         editor.setPlainText(yaml.dump(val))
         self.setItemWidget(child, vcol, editor)
         editor.textChanged.connect(
             self.set_icon_func(i, item, validators[key]))
     self.resizeColumnToContents(0)
     self.resizeColumnToContents(1)
示例#6
0
 def trigger_plot_btn():
     a = next(iter(get_artists()), None)
     if a is None:
         if can_be_plotted is None or can_be_plotted():
             plot_func()
             cb.setChecked(True)
             btn.setIcon(QIcon(get_icon('invalid.png')))
             btn.setToolTip('Remove ' + what)
             self.draw_figs(get_artists())
             cb.setEnabled(True)
     else:
         fig = a.axes.figure
         figs = {a.axes.figure for a in get_artists()}
         remove_func()
         btn.setIcon(QIcon(get_icon('valid.png')))
         btn.setToolTip('Show ' + what)
         for fig in figs:
             fig.canvas.draw_idle()
         cb.setEnabled(False)
示例#7
0
 def toogle_connect_console(self):
     """Disable (or enable) the loading of web pages in www"""
     bt = self.bt_connect_console
     connect = bt.isChecked()
     bt.setIcon(QIcon(get_icon(
         'ipython_console.png' if connect else 'ipython_console_t.png')))
     bt.setToolTip("%sonnect the console to the help explorer" % (
         "Don't c" if connect else "C"))
     if rcParams['console.connect_to_help'] is not connect:
         rcParams['console.connect_to_help'] = connect
示例#8
0
 def toogle_connect_console(self):
     """Disable (or enable) the loading of web pages in www"""
     bt = self.bt_connect_console
     connect = bt.isChecked()
     bt.setIcon(QIcon(get_icon(
         'ipython_console.png' if connect else 'ipython_console_t.png')))
     bt.setToolTip("%sonnect the console to the help explorer" % (
         "Don't c" if connect else "C"))
     if rcParams['console.connect_to_help'] is not connect:
         rcParams['console.connect_to_help'] = connect
示例#9
0
 def refresh(self):
     for row, (what, func) in enumerate(self.get_artists_funcs.items()):
         a = next(iter(func()), None)
         cb = self.cellWidget(row, 0)
         cb.setEnabled(a is not None)
         if a is not None:
             cb.setChecked(Qt.Checked if a.get_visible() else Qt.Unchecked)
         btn = self.cellWidget(row, 1)
         if btn is not None:
             can_be_plotted = self.can_be_plotted_funcs[what]
             if can_be_plotted is None or can_be_plotted():
                 if a is not None:
                     btn.setIcon(QIcon(get_icon('invalid.png')))
                     btn.setToolTip('Remove ' + what)
                 else:
                     btn.setIcon(QIcon(get_icon('valid.png')))
                     btn.setToolTip('Show ' + what)
                 btn.setEnabled(True)
             else:
                 btn.setEnabled(False)
示例#10
0
 def toogle_url_lock(self):
     """Disable (or enable) the loading of web pages in www"""
     bt = self.bt_url_lock
     bt.setIcon(QIcon(get_icon(
         'world_red.png' if bt.isChecked() else 'world.png')))
     online_message = "Go online"
     if not with_qt5:
         online_message += ("\nWARNING: This mode is unstable under Qt4 "
                            "and might result in a complete program crash!")
     bt.setToolTip(online_message if bt.isChecked() else
                   "Offline mode")
示例#11
0
 def func():
     editor = self.itemWidget(item.child(0), self.value_col)
     s = asstring(editor.toPlainText())
     try:
         val = yaml.load(s, Loader=yaml.Loader)
     except Exception as e:
         item.setIcon(1, QIcon(get_icon('warning.png')))
         item.setToolTip(1, "Could not parse yaml code: %s" % e)
         self.set_valid(i, False)
         return
     try:
         validator(val)
     except Exception as e:
         item.setIcon(1, QIcon(get_icon('invalid.png')))
         item.setToolTip(1, "Wrong value: %s" % e)
         self.set_valid(i, False)
     else:
         item.setIcon(1, QIcon(get_icon('valid.png')))
         self.set_valid(i, True)
     self.propose_changes.emit(self.parent() or self)
示例#12
0
 def func():
     editor = self.itemWidget(item.child(0), self.value_col)
     s = asstring(editor.toPlainText())
     try:
         val = yaml.load(s)
     except Exception as e:
         item.setIcon(1, QIcon(get_icon('warning.png')))
         item.setToolTip(1, "Could not parse yaml code: %s" % e)
         self.set_valid(i, False)
         return
     try:
         validator(val)
     except Exception as e:
         item.setIcon(1, QIcon(get_icon('invalid.png')))
         item.setToolTip(1, "Wrong value: %s" % e)
         self.set_valid(i, False)
     else:
         item.setIcon(1, QIcon(get_icon('valid.png')))
         self.set_valid(i, True)
     self.propose_changes.emit(self.parent() or self)
示例#13
0
 def toogle_url_lock(self):
     """Disable (or enable) the loading of web pages in www"""
     bt = self.bt_url_lock
     offline = bt.isChecked()
     bt.setIcon(QIcon(
         get_icon('world_red.png' if offline else 'world.png')))
     online_message = "Go online"
     if not with_qt5:
         online_message += ("\nWARNING: This mode is unstable under Qt4 "
                            "and might result in a complete program crash!")
     bt.setToolTip(online_message if offline else "Offline mode")
     if rcParams['help_explorer.online'] is offline:
         rcParams['help_explorer.online'] = not offline
示例#14
0
    def __init__(self, df, straditizer, fname=None, *args, **kwargs):
        """
        Parameters
        ----------
        df: pandas.DataFrame
            The DataFrame to be exported
        straditizer: straditize.straditizer.Straditizer
            The source straditizer
        fname: str
            The file name to export to
        """
        super().__init__(*args, **kwargs)
        self.df = df
        self.stradi = straditizer
        self.txt_fname = QLineEdit()
        self.bt_open_file = QToolButton()
        self.bt_open_file.setIcon(QIcon(get_icon('run_arrow.png')))
        self.bt_open_file.setToolTip('Select the export file on your drive')

        self.cb_include_meta = QCheckBox('Include meta data')
        self.cb_include_meta.setChecked(True)

        self.bbox = bbox = QDialogButtonBox(QDialogButtonBox.Ok
                                            | QDialogButtonBox.Cancel)

        # ---------------------------------------------------------------------
        # --------------------------- Layouts ---------------------------------
        # ---------------------------------------------------------------------
        vbox = QVBoxLayout()

        hbox = QHBoxLayout()
        hbox.addWidget(QLabel('Export to:'))
        hbox.addWidget(self.txt_fname)
        hbox.addWidget(self.bt_open_file)
        vbox.addLayout(hbox)

        vbox.addWidget(self.cb_include_meta)

        vbox.addWidget(bbox)
        self.setLayout(vbox)

        # ---------------------------------------------------------------------
        # --------------------------- Connections -----------------------------
        # ---------------------------------------------------------------------
        bbox.accepted.connect(self._export)
        bbox.rejected.connect(self.reject)
        self.bt_open_file.clicked.connect(self.get_open_file_name)

        if fname is not None:
            self.txt_fname.setText(fname)
            self._export()
示例#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)

        # ---------------------- 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
示例#16
0
    def __init__(self, *args, **kwargs):
        super(UrlBrowser, self).__init__(*args, **kwargs)

        # ---------------------------------------------------------------------
        # ---------------------------- upper buttons --------------------------
        # ---------------------------------------------------------------------
        # adress line
        self.tb_url = UrlCombo(self)
        # button to go to previous url
        self.bt_back = QToolButton(self)
        # button to go to next url
        self.bt_ahead = QToolButton(self)
        # refresh the current url
        self.bt_refresh = QToolButton(self)
        # button to go lock to the current url
        self.bt_lock = QToolButton(self)
        # button to disable browsing in www
        self.bt_url_lock = QToolButton(self)

        # ---------------------------- buttons settings -----------------------
        self.bt_back.setIcon(QIcon(get_icon('previous.png')))
        self.bt_back.setToolTip('Go back one page')
        self.bt_ahead.setIcon(QIcon(get_icon('next.png')))
        self.bt_back.setToolTip('Go forward one page')

        self.bt_refresh.setIcon(QIcon(get_icon('refresh.png')))
        self.bt_refresh.setToolTip('Refresh the current page')

        self.bt_lock.setCheckable(True)
        self.bt_url_lock.setCheckable(True)

        if not with_qt5 and rcParams['help_explorer.online'] is None:
            # We now that the browser can crash with Qt4, therefore we disable
            # the browing in the internet
            self.bt_url_lock.click()
            rcParams['help_explorer.online'] = False
        elif rcParams['help_explorer.online'] is False:
            self.bt_url_lock.click()
        elif rcParams['help_explorer.online'] is None:
            rcParams['help_explorer.online'] = True
        rcParams.connect('help_explorer.online', self.update_url_lock_from_rc)

        self.bt_url_lock.clicked.connect(self.toogle_url_lock)
        self.bt_lock.clicked.connect(self.toogle_lock)

        # tooltip and icons of lock and url_lock are set in toogle_lock and
        # toogle_url_lock
        self.toogle_lock()
        self.toogle_url_lock()

        # ---------------------------------------------------------------------
        # --------- initialization and connection of the web view -------------
        # ---------------------------------------------------------------------

        #: The actual widget showing the html content
        self.html = QWebEngineView(parent=self)
        self.html.loadStarted.connect(self.completed)
        self.html.loadFinished.connect(self.completed)

        self.tb_url.currentIndexChanged[str].connect(self.browse)
        self.bt_back.clicked.connect(self.html.back)
        self.bt_ahead.clicked.connect(self.html.forward)
        self.bt_refresh.clicked.connect(self.html.reload)
        self.html.urlChanged.connect(self.url_changed)

        # ---------------------------------------------------------------------
        # ---------------------------- layouts --------------------------------
        # ---------------------------------------------------------------------

        # The upper part of the browser containing all the buttons
        self.button_box = button_box = QHBoxLayout()

        button_box.addWidget(self.bt_back)
        button_box.addWidget(self.bt_ahead)
        button_box.addWidget(self.tb_url)
        button_box.addWidget(self.bt_refresh)
        button_box.addWidget(self.bt_lock)
        button_box.addWidget(self.bt_url_lock)

        # The upper most layout aranging the button box and the html widget
        self.vbox = vbox = QVBoxLayout()
        self.vbox.setContentsMargins(0, 0, 0, 0)
        vbox.addLayout(button_box)

        vbox.addWidget(self.html)

        self.setLayout(vbox)

        if self.default_url is not None:
            self.tb_url.addItem(self.default_url)
示例#17
0
    def __init__(self, *args, **kwargs):
        super(DataFrameEditor, self).__init__(*args, **kwargs)
        self.error_msg = PyErrorMessage(self)

        # Label for displaying the DataFrame size
        self.lbl_size = QLabel()

        # A Checkbox for enabling and disabling the editability of the index
        self.cb_index_editable = QCheckBox('Index editable')

        # A checkbox for enabling and disabling the change of data types
        self.cb_dtypes_changeable = QCheckBox('Datatypes changeable')

        # A checkbox for enabling and disabling sorting
        self.cb_enable_sort = QCheckBox('Enable sorting')

        # A button to open a dataframe from the file
        self.btn_open_df = QToolButton(parent=self)
        self.btn_open_df.setIcon(QIcon(get_icon('run_arrow.png')))
        self.btn_open_df.setToolTip('Open a DataFrame from your disk')

        self.btn_from_console = LoadFromConsoleButton(pd.DataFrame)
        self.btn_from_console.setToolTip('Show a DataFrame from the console')

        # The table to display the DataFrame
        self.table = DataFrameView(pd.DataFrame(), self)

        # format line edit
        self.format_editor = QLineEdit()
        self.format_editor.setText(self.table.model()._format)

        # format update button
        self.btn_change_format = QPushButton('Update')
        self.btn_change_format.setEnabled(False)

        # table clearing button
        self.btn_clear = QPushButton('Clear')
        self.btn_clear.setToolTip(
            'Clear the table and disconnect from the DataFrame')

        # refresh button
        self.btn_refresh = QToolButton()
        self.btn_refresh.setIcon(QIcon(get_icon('refresh.png')))
        self.btn_refresh.setToolTip('Refresh the table')

        # close button
        self.btn_close = QPushButton('Close')
        self.btn_close.setToolTip('Close this widget permanentely')

        # ---------------------------------------------------------------------
        # ------------------------ layout --------------------------------
        # ---------------------------------------------------------------------
        vbox = QVBoxLayout()
        self.top_hbox = hbox = QHBoxLayout()
        hbox.addWidget(self.cb_index_editable)
        hbox.addWidget(self.cb_dtypes_changeable)
        hbox.addWidget(self.cb_enable_sort)
        hbox.addWidget(self.lbl_size)
        hbox.addStretch(0)
        hbox.addWidget(self.btn_open_df)
        hbox.addWidget(self.btn_from_console)
        vbox.addLayout(hbox)
        vbox.addWidget(self.table)
        self.bottom_hbox = hbox = QHBoxLayout()
        hbox.addWidget(self.format_editor)
        hbox.addWidget(self.btn_change_format)
        hbox.addStretch(0)
        hbox.addWidget(self.btn_clear)
        hbox.addWidget(self.btn_close)
        hbox.addWidget(self.btn_refresh)
        vbox.addLayout(hbox)
        self.setLayout(vbox)

        # ---------------------------------------------------------------------
        # ------------------------ Connections --------------------------------
        # ---------------------------------------------------------------------
        self.cb_dtypes_changeable.stateChanged.connect(
            self.set_dtypes_changeable)
        self.cb_index_editable.stateChanged.connect(self.set_index_editable)
        self.btn_from_console.object_loaded.connect(self._open_ds_from_console)
        self.rows_inserted.connect(lambda i, n: self.set_lbl_size_text())
        self.format_editor.textChanged.connect(self.toggle_fmt_button)
        self.btn_change_format.clicked.connect(self.update_format)
        self.btn_clear.clicked.connect(self.clear_table)
        self.btn_close.clicked.connect(self.clear_table)
        self.btn_close.clicked.connect(lambda: self.close())
        self.btn_refresh.clicked.connect(self.table.reset_model)
        self.btn_open_df.clicked.connect(self._open_dataframe)
        self.table.set_index_action.triggered.connect(
            self.update_index_editable)
        self.table.append_index_action.triggered.connect(
            self.update_index_editable)
        self.cb_enable_sort.stateChanged.connect(
            self.table.setSortingEnabled)
示例#18
0
    def __init__(self, *args, **kwargs):
        """
        Parameters
        ----------
        help_explorer: psyplot_gui.help_explorer.HelpExplorer
            The help explorer to show the documentation of one formatoption
        console: psyplot_gui.console.ConsoleWidget
            The console that can be used to update the current subproject via::

                psy.gcp().update(**kwargs)

            where ``**kwargs`` is defined through the selected formatoption
            in the :attr:`fmt_combo` combobox and the value in the
            :attr:`line_edit` editor
        ``*args, **kwargs``
            Any other keyword for the QWidget class
        """
        help_explorer = kwargs.pop('help_explorer', None)
        console = kwargs.pop('console', None)
        super(FormatoptionWidget, self).__init__(*args, **kwargs)
        self.help_explorer = help_explorer
        self.console = console
        self.error_msg = PyErrorMessage(self)

        # ---------------------------------------------------------------------
        # -------------------------- Child widgets ----------------------------
        # ---------------------------------------------------------------------
        self.group_combo = QComboBox(parent=self)
        self.fmt_combo = QComboBox(parent=self)
        self.line_edit = QLineEdit(parent=self)
        self.text_edit = QTextEdit(parent=self)
        self.run_button = QToolButton(parent=self)

        # completer for the fmto widget
        self.fmt_combo.setEditable(True)
        self.fmt_combo.setInsertPolicy(QComboBox.NoInsert)
        self.fmto_completer = completer = QCompleter(
            ['time', 'lat', 'lon', 'lev'])
        completer.setCompletionMode(
            QCompleter.PopupCompletion)
        completer.activated[str].connect(self.set_fmto)
        if with_qt5:
            completer.setFilterMode(Qt.MatchContains)
        completer.setModel(QStandardItemModel())
        self.fmt_combo.setCompleter(completer)

        self.dim_widget = DimensionsWidget(parent=self)
        self.dim_widget.setVisible(False)

        self.multiline_button = QPushButton('Multiline', parent=self)
        self.multiline_button.setCheckable(True)

        self.yaml_cb = QCheckBox('Yaml syntax')
        self.yaml_cb.setChecked(True)

        self.keys_button = QPushButton('Keys', parent=self)
        self.summaries_button = QPushButton('Summaries', parent=self)
        self.docs_button = QPushButton('Docs', parent=self)

        self.grouped_cb = QCheckBox('grouped', parent=self)
        self.all_groups_cb = QCheckBox('all groups', parent=self)
        self.include_links_cb = QCheckBox('include links', parent=self)

        self.text_edit.setVisible(False)

        # ---------------------------------------------------------------------
        # -------------------------- Descriptions -----------------------------
        # ---------------------------------------------------------------------

        self.group_combo.setToolTip('Select the formatoption group')
        self.fmt_combo.setToolTip('Select the formatoption to update')
        self.line_edit.setToolTip(
            'Insert the value which what you want to update the selected '
            'formatoption and hit right button. The code is executed in the '
            'main console.')
        self.yaml_cb.setToolTip(
            "Use the yaml syntax for the values inserted in the above cell. "
            "Otherwise the content there is evaluated as a python expression "
            "in the terminal")
        self.text_edit.setToolTip(self.line_edit.toolTip())
        self.run_button.setIcon(QIcon(get_icon('run_arrow.png')))
        self.run_button.setToolTip('Update the selected formatoption')
        self.multiline_button.setToolTip(
            'Allow linebreaks in the text editor line above.')
        self.keys_button.setToolTip(
            'Show the formatoption keys in this group (or in all '
            'groups) in the help explorer')
        self.summaries_button.setToolTip(
            'Show the formatoption summaries in this group (or in all '
            'groups) in the help explorer')
        self.docs_button.setToolTip(
            'Show the formatoption documentations in this group (or in all '
            'groups) in the help explorer')
        self.grouped_cb.setToolTip(
            'Group the formatoptions before displaying them in the help '
            'explorer')
        self.all_groups_cb.setToolTip('Use all groups when displaying the '
                                      'keys, docs or summaries')
        self.include_links_cb.setToolTip(
            'Include links to remote documentations when showing the '
            'keys, docs and summaries in the help explorer (requires '
            'intersphinx)')

        # ---------------------------------------------------------------------
        # -------------------------- Connections ------------------------------
        # ---------------------------------------------------------------------
        self.group_combo.currentIndexChanged[int].connect(self.fill_fmt_combo)
        self.fmt_combo.currentIndexChanged[int].connect(self.show_fmt_info)
        self.fmt_combo.currentIndexChanged[int].connect(self.load_fmt_widget)
        self.fmt_combo.currentIndexChanged[int].connect(
            self.set_current_fmt_value)
        self.run_button.clicked.connect(self.run_code)
        self.line_edit.returnPressed.connect(self.run_button.click)
        self.multiline_button.clicked.connect(self.toggle_line_edit)
        self.keys_button.clicked.connect(
            partial(self.show_all_fmt_info, 'keys'))
        self.summaries_button.clicked.connect(
            partial(self.show_all_fmt_info, 'summaries'))
        self.docs_button.clicked.connect(
            partial(self.show_all_fmt_info, 'docs'))

        # ---------------------------------------------------------------------
        # ------------------------------ Layouts ------------------------------
        # ---------------------------------------------------------------------
        self.combos = QHBoxLayout()
        self.combos.addWidget(self.group_combo)
        self.combos.addWidget(self.fmt_combo)

        self.execs = QHBoxLayout()
        self.execs.addWidget(self.line_edit)
        self.execs.addWidget(self.text_edit)
        self.execs.addWidget(self.run_button)

        self.info_box = QHBoxLayout()
        self.info_box.addWidget(self.multiline_button)
        self.info_box.addWidget(self.yaml_cb)
        self.info_box.addStretch(0)
        for w in [self.keys_button, self.summaries_button, self.docs_button,
                  self.all_groups_cb, self.grouped_cb, self.include_links_cb]:
            self.info_box.addWidget(w)

        self.vbox = QVBoxLayout()
        self.vbox.addLayout(self.combos)
        self.vbox.addWidget(self.dim_widget)
        self.vbox.addLayout(self.execs)
        self.vbox.addLayout(self.info_box)

        self.vbox.setSpacing(0)

        self.setLayout(self.vbox)

        # fill with content
        self.fill_combos_from_project(psy.gcp())
        psy.Project.oncpchange.connect(self.fill_combos_from_project)
        rcParams.connect('fmt.sort_by_key', self.refill_from_rc)
示例#19
0
 def icon(self):
     """The icon of this instance in the :class:`Preferences` dialog"""
     return QIcon(get_icon('rcParams.png'))
示例#20
0
    def __init__(self, *args, **kwargs):
        super(UrlBrowser, self).__init__(*args, **kwargs)

        # ---------------------------------------------------------------------
        # ---------------------------- upper buttons --------------------------
        # ---------------------------------------------------------------------
        # adress line
        self.tb_url = UrlCombo(self)
        # button to go to previous url
        self.bt_back = QToolButton(self)
        # button to go to next url
        self.bt_ahead = QToolButton(self)
        # refresh the current url
        self.bt_refresh = QToolButton(self)
        # button to go lock to the current url
        self.bt_lock = QToolButton(self)
        # button to disable browsing in www
        self.bt_url_lock = QToolButton(self)

        # ---------------------------- buttons settings -----------------------
        self.bt_back.setIcon(QIcon(get_icon('previous.png')))
        self.bt_back.setToolTip('Go back one page')
        self.bt_ahead.setIcon(QIcon(get_icon('next.png')))
        self.bt_back.setToolTip('Go forward one page')

        self.bt_refresh.setIcon(QIcon(get_icon('refresh.png')))
        self.bt_refresh.setToolTip('Refresh the current page')

        self.bt_lock.setCheckable(True)
        self.bt_url_lock.setCheckable(True)

        if not with_qt5 and rcParams['help_explorer.online'] is None:
            # We now that the browser can crash with Qt4, therefore we disable
            # the browing in the internet
            self.bt_url_lock.click()
            rcParams['help_explorer.online'] = False
        elif rcParams['help_explorer.online'] is False:
            self.bt_url_lock.click()
        elif rcParams['help_explorer.online'] is None:
            rcParams['help_explorer.online'] = True
        rcParams.connect('help_explorer.online', self.update_url_lock_from_rc)

        self.bt_url_lock.clicked.connect(self.toogle_url_lock)
        self.bt_lock.clicked.connect(self.toogle_lock)

        # tooltip and icons of lock and url_lock are set in toogle_lock and
        # toogle_url_lock
        self.toogle_lock()
        self.toogle_url_lock()

        # ---------------------------------------------------------------------
        # --------- initialization and connection of the web view -------------
        # ---------------------------------------------------------------------

        #: The actual widget showing the html content
        self.html = QWebEngineView(parent=self)
        self.html.loadStarted.connect(self.completed)
        self.html.loadFinished.connect(self.completed)

        self.tb_url.currentIndexChanged[str].connect(self.browse)
        self.bt_back.clicked.connect(self.html.back)
        self.bt_ahead.clicked.connect(self.html.forward)
        self.bt_refresh.clicked.connect(self.html.reload)
        self.html.urlChanged.connect(self.url_changed)

        # ---------------------------------------------------------------------
        # ---------------------------- layouts --------------------------------
        # ---------------------------------------------------------------------

        # The upper part of the browser containing all the buttons
        self.button_box = button_box = QHBoxLayout()

        button_box.addWidget(self.bt_back)
        button_box.addWidget(self.bt_ahead)
        button_box.addWidget(self.tb_url)
        button_box.addWidget(self.bt_refresh)
        button_box.addWidget(self.bt_lock)
        button_box.addWidget(self.bt_url_lock)

        # The upper most layout aranging the button box and the html widget
        self.vbox = vbox = QVBoxLayout()
        self.vbox.setContentsMargins(0, 0, 0, 0)
        vbox.addLayout(button_box)

        vbox.addWidget(self.html)

        self.setLayout(vbox)

        if self.default_url is not None:
            self.tb_url.addItem(self.default_url)
示例#21
0
 def toogle_lock(self):
     """Disable (or enable) the changing of the current webpage"""
     bt = self.bt_lock
     bt.setIcon(QIcon(get_icon(
         'lock.png' if bt.isChecked() else 'lock_open.png')))
     bt.setToolTip("Unlock" if bt.isChecked() else "Lock to current page")
示例#22
0
    def __init__(self, *args, **kwargs):
        """
        Parameters
        ----------
        help_explorer: psyplot_gui.help_explorer.HelpExplorer
            The help explorer to show the documentation of one formatoption
        shell: IPython.core.interactiveshell.InteractiveShell
            The shell that can be used to update the current subproject via::

                psy.gcp().update(**kwargs)

            where ``**kwargs`` is defined through the selected formatoption
            in the :attr:`fmt_combo` combobox and the value in the
            :attr:`line_edit` editor
        ``*args, **kwargs``
            Any other keyword for the QWidget class
        """
        help_explorer = kwargs.pop('help_explorer', None)
        shell = kwargs.pop('shell', None)
        super(FormatoptionWidget, self).__init__(*args, **kwargs)
        self.help_explorer = help_explorer
        self.shell = shell

        # ---------------------------------------------------------------------
        # -------------------------- Child widgets ----------------------------
        # ---------------------------------------------------------------------
        self.group_combo = QComboBox(parent=self)
        self.fmt_combo = QComboBox(parent=self)
        self.line_edit = QLineEdit(parent=self)
        self.run_button = QToolButton(parent=self)

        self.keys_button = QPushButton('Formatoption keys', parent=self)
        self.summaries_button = QPushButton('Summaries', parent=self)
        self.docs_button = QPushButton('Docs', parent=self)

        self.grouped_cb = QCheckBox('grouped', parent=self)
        self.all_groups_cb = QCheckBox('all groups', parent=self)
        self.include_links_cb = QCheckBox('include links', parent=self)

        # ---------------------------------------------------------------------
        # -------------------------- Descriptions -----------------------------
        # ---------------------------------------------------------------------

        self.group_combo.setToolTip('Select the formatoption group')
        self.fmt_combo.setToolTip('Select the formatoption to update')
        self.line_edit.setToolTip(
            'Insert the value which what you want to update the selected '
            'formatoption and hit right button. The code is executed in the '
            'main console.')
        self.run_button.setIcon(QIcon(get_icon('run_arrow.png')))
        self.run_button.setToolTip('Update the selected formatoption')
        self.keys_button.setToolTip(
            'Show the formatoption keys in this group (or in all '
            'groups) in the help explorer')
        self.summaries_button.setToolTip(
            'Show the formatoption summaries in this group (or in all '
            'groups) in the help explorer')
        self.docs_button.setToolTip(
            'Show the formatoption documentations in this group (or in all '
            'groups) in the help explorer')
        self.grouped_cb.setToolTip(
            'Group the formatoptions before displaying them in the help '
            'explorer')
        self.all_groups_cb.setToolTip('Use all groups when displaying the '
                                      'keys, docs or summaries')
        self.include_links_cb.setToolTip(
            'Include links to remote documentations when showing the '
            'keys, docs and summaries in the help explorer (requires '
            'intersphinx)')

        # ---------------------------------------------------------------------
        # -------------------------- Connections ------------------------------
        # ---------------------------------------------------------------------
        self.group_combo.currentIndexChanged[int].connect(self.fill_fmt_combo)
        self.fmt_combo.currentIndexChanged[int].connect(self.show_fmt_info)
        self.run_button.clicked.connect(self.run_code)
        self.line_edit.returnPressed.connect(self.run_button.click)
        self.keys_button.clicked.connect(
            partial(self.show_all_fmt_info, 'keys'))
        self.summaries_button.clicked.connect(
            partial(self.show_all_fmt_info, 'summaries'))
        self.docs_button.clicked.connect(
            partial(self.show_all_fmt_info, 'docs'))

        # ---------------------------------------------------------------------
        # ------------------------------ Layouts ------------------------------
        # ---------------------------------------------------------------------
        self.combos = QHBoxLayout()
        self.combos.addWidget(self.group_combo)
        self.combos.addWidget(self.fmt_combo)

        self.execs = QHBoxLayout()
        self.execs.addWidget(self.line_edit)
        self.execs.addWidget(self.run_button)

        self.info_box = QHBoxLayout()
        self.info_box.addStretch(0)
        for w in [
                self.keys_button, self.summaries_button, self.docs_button,
                self.all_groups_cb, self.grouped_cb, self.include_links_cb
        ]:
            self.info_box.addWidget(w)

        self.vbox = QVBoxLayout()
        self.vbox.addLayout(self.combos)
        self.vbox.addLayout(self.execs)
        self.vbox.addLayout(self.info_box)

        self.setLayout(self.vbox)

        # fill with content
        self.fill_combos_from_project(psy.gcp())
        psy.Project.oncpchange.connect(self.fill_combos_from_project)
示例#23
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
示例#24
0
 def toogle_lock(self):
     """Disable (or enable) the changing of the current webpage"""
     bt = self.bt_lock
     bt.setIcon(
         QIcon(get_icon('lock.png' if bt.isChecked() else 'lock_open.png')))
     bt.setToolTip("Unlock" if bt.isChecked() else "Lock to current page")
示例#25
0
    def __init__(self, *args, **kwargs):
        super(DataFrameEditor, self).__init__(*args, **kwargs)
        self.error_msg = PyErrorMessage(self)

        # Label for displaying the DataFrame size
        self.lbl_size = QLabel()

        # A Checkbox for enabling and disabling the editability of the index
        self.cb_index_editable = QCheckBox('Index editable')

        # A checkbox for enabling and disabling the change of data types
        self.cb_dtypes_changeable = QCheckBox('Datatypes changeable')

        # A checkbox for enabling and disabling sorting
        self.cb_enable_sort = QCheckBox('Enable sorting')

        # A button to open a dataframe from the file
        self.btn_open_df = QToolButton(parent=self)
        self.btn_open_df.setIcon(QIcon(get_icon('run_arrow.png')))
        self.btn_open_df.setToolTip('Open a DataFrame from your disk')

        self.btn_from_console = LoadFromConsoleButton(pd.DataFrame)
        self.btn_from_console.setToolTip('Show a DataFrame from the console')

        # The table to display the DataFrame
        self.table = DataFrameView(pd.DataFrame(), self)

        # format line edit
        self.format_editor = QLineEdit()
        self.format_editor.setText(self.table.model()._format)

        # format update button
        self.btn_change_format = QPushButton('Update')
        self.btn_change_format.setEnabled(False)

        # table clearing button
        self.btn_clear = QPushButton('Clear')
        self.btn_clear.setToolTip(
            'Clear the table and disconnect from the DataFrame')

        # refresh button
        self.btn_refresh = QToolButton()
        self.btn_refresh.setIcon(QIcon(get_icon('refresh.png')))
        self.btn_refresh.setToolTip('Refresh the table')

        # close button
        self.btn_close = QPushButton('Close')
        self.btn_close.setToolTip('Close this widget permanentely')

        # ---------------------------------------------------------------------
        # ------------------------ layout --------------------------------
        # ---------------------------------------------------------------------
        vbox = QVBoxLayout()
        self.top_hbox = hbox = QHBoxLayout()
        hbox.addWidget(self.cb_index_editable)
        hbox.addWidget(self.cb_dtypes_changeable)
        hbox.addWidget(self.cb_enable_sort)
        hbox.addWidget(self.lbl_size)
        hbox.addStretch(0)
        hbox.addWidget(self.btn_open_df)
        hbox.addWidget(self.btn_from_console)
        vbox.addLayout(hbox)
        vbox.addWidget(self.table)
        self.bottom_hbox = hbox = QHBoxLayout()
        hbox.addWidget(self.format_editor)
        hbox.addWidget(self.btn_change_format)
        hbox.addStretch(0)
        hbox.addWidget(self.btn_clear)
        hbox.addWidget(self.btn_close)
        hbox.addWidget(self.btn_refresh)
        vbox.addLayout(hbox)
        self.setLayout(vbox)

        # ---------------------------------------------------------------------
        # ------------------------ Connections --------------------------------
        # ---------------------------------------------------------------------
        self.cb_dtypes_changeable.stateChanged.connect(
            self.set_dtypes_changeable)
        self.cb_index_editable.stateChanged.connect(self.set_index_editable)
        self.btn_from_console.object_loaded.connect(self._open_ds_from_console)
        self.rows_inserted.connect(lambda i, n: self.set_lbl_size_text())
        self.format_editor.textChanged.connect(self.toggle_fmt_button)
        self.btn_change_format.clicked.connect(self.update_format)
        self.btn_clear.clicked.connect(self.clear_table)
        self.btn_close.clicked.connect(self.clear_table)
        self.btn_close.clicked.connect(lambda: self.close())
        self.btn_refresh.clicked.connect(self.table.reset_model)
        self.btn_open_df.clicked.connect(self._open_dataframe)
        self.table.set_index_action.triggered.connect(
            self.update_index_editable)
        self.table.append_index_action.triggered.connect(
            self.update_index_editable)
        self.cb_enable_sort.stateChanged.connect(
            self.table.setSortingEnabled)
示例#26
0
    def add_item(self,
                 what,
                 get_artists,
                 plot_func=None,
                 remove_func=None,
                 can_be_plotted=None):
        """Add a plot object to the table

        Parameters
        ----------
        what: str
            The description of the plot object
        get_artists: function
            A function that takes no arguments and returns the artists
        plot_func: function, optional
            A function that takes no arguments and makes the plot.
        remove_func: function, optional
            A function that takes no arguments and removes the plot.
        can_be_plotted: function, optional
            A function that takes no argument and returns True if the plot can
            be made.
        """
        def hide_or_show(checked):
            checked = checked is True or checked == Qt.Checked
            artist = None
            for artist in get_artists():
                artist.set_visible(checked)
            if artist is not None:
                self.draw_figs(get_artists())

        def trigger_plot_btn():
            a = next(iter(get_artists()), None)
            if a is None:
                if can_be_plotted is None or can_be_plotted():
                    plot_func()
                    cb.setChecked(True)
                    btn.setIcon(QIcon(get_icon('invalid.png')))
                    btn.setToolTip('Remove ' + what)
                    self.draw_figs(get_artists())
                    cb.setEnabled(True)
            else:
                fig = a.axes.figure
                figs = {a.axes.figure for a in get_artists()}
                remove_func()
                btn.setIcon(QIcon(get_icon('valid.png')))
                btn.setToolTip('Show ' + what)
                for fig in figs:
                    fig.canvas.draw_idle()
                cb.setEnabled(False)

        self.get_artists_funcs[what] = get_artists

        a = next(iter(get_artists()), None)

        cb = QCheckBox()
        cb.label = what
        self.hide_funcs[what] = hide_or_show
        cb.setChecked(
            Qt.Checked if a is not None and a.get_visible() else Qt.Unchecked)
        cb.stateChanged.connect(hide_or_show)

        row = self.rowCount()
        self.setRowCount(row + 1)
        self.setVerticalHeaderLabels(list(self.get_artists_funcs))

        self.setCellWidget(row, 0, cb)

        if plot_func is not None:
            btn = QToolButton()
            btn.setIcon(
                QIcon(get_icon(('in' if a is None else '') + 'valid.png')))
            btn.clicked.connect(trigger_plot_btn)
            btn.setEnabled(can_be_plotted is None or can_be_plotted())
            btn.setToolTip(('Remove ' if a else 'Show ') + what)
            self.can_be_plotted_funcs[what] = can_be_plotted
            btn.label = what

            self.setCellWidget(row, 1, btn)
示例#27
0
 def icon(self):
     """The icon of this instance in the :class:`Preferences` dialog"""
     return QIcon(get_icon('rcParams.png'))
示例#28
0
    def __init__(self, *args, **kwargs):
        """
        Parameters
        ----------
        help_explorer: psyplot_gui.help_explorer.HelpExplorer
            The help explorer to show the documentation of one formatoption
        console: psyplot_gui.console.ConsoleWidget
            The console that can be used to update the current subproject via::

                psy.gcp().update(**kwargs)

            where ``**kwargs`` is defined through the selected formatoption
            in the :attr:`fmt_combo` combobox and the value in the
            :attr:`line_edit` editor
        ``*args, **kwargs``
            Any other keyword for the QWidget class
        """
        help_explorer = kwargs.pop('help_explorer', None)
        console = kwargs.pop('console', None)
        super(FormatoptionWidget, self).__init__(*args, **kwargs)
        self.help_explorer = help_explorer
        self.console = console
        self.error_msg = PyErrorMessage(self)

        # ---------------------------------------------------------------------
        # -------------------------- Child widgets ----------------------------
        # ---------------------------------------------------------------------
        self.group_combo = QComboBox(parent=self)
        self.fmt_combo = QComboBox(parent=self)
        self.line_edit = QLineEdit(parent=self)
        self.text_edit = QTextEdit(parent=self)
        self.run_button = QToolButton(parent=self)

        # completer for the fmto widget
        self.fmt_combo.setEditable(True)
        self.fmt_combo.setInsertPolicy(QComboBox.NoInsert)
        self.fmto_completer = completer = QCompleter(
            ['time', 'lat', 'lon', 'lev'])
        completer.setCompletionMode(QCompleter.PopupCompletion)
        completer.activated[str].connect(self.set_fmto)
        if with_qt5:
            completer.setFilterMode(Qt.MatchContains)
        completer.setModel(QStandardItemModel())
        self.fmt_combo.setCompleter(completer)

        self.dim_widget = DimensionsWidget(parent=self)
        self.dim_widget.setVisible(False)

        self.multiline_button = QPushButton('Multiline', parent=self)
        self.multiline_button.setCheckable(True)

        self.yaml_cb = QCheckBox('Yaml syntax')
        self.yaml_cb.setChecked(True)

        self.keys_button = QPushButton('Keys', parent=self)
        self.summaries_button = QPushButton('Summaries', parent=self)
        self.docs_button = QPushButton('Docs', parent=self)

        self.grouped_cb = QCheckBox('grouped', parent=self)
        self.all_groups_cb = QCheckBox('all groups', parent=self)
        self.include_links_cb = QCheckBox('include links', parent=self)

        self.text_edit.setVisible(False)

        # ---------------------------------------------------------------------
        # -------------------------- Descriptions -----------------------------
        # ---------------------------------------------------------------------

        self.group_combo.setToolTip('Select the formatoption group')
        self.fmt_combo.setToolTip('Select the formatoption to update')
        self.line_edit.setToolTip(
            'Insert the value which what you want to update the selected '
            'formatoption and hit right button. The code is executed in the '
            'main console.')
        self.yaml_cb.setToolTip(
            "Use the yaml syntax for the values inserted in the above cell. "
            "Otherwise the content there is evaluated as a python expression "
            "in the terminal")
        self.text_edit.setToolTip(self.line_edit.toolTip())
        self.run_button.setIcon(QIcon(get_icon('run_arrow.png')))
        self.run_button.setToolTip('Update the selected formatoption')
        self.multiline_button.setToolTip(
            'Allow linebreaks in the text editor line above.')
        self.keys_button.setToolTip(
            'Show the formatoption keys in this group (or in all '
            'groups) in the help explorer')
        self.summaries_button.setToolTip(
            'Show the formatoption summaries in this group (or in all '
            'groups) in the help explorer')
        self.docs_button.setToolTip(
            'Show the formatoption documentations in this group (or in all '
            'groups) in the help explorer')
        self.grouped_cb.setToolTip(
            'Group the formatoptions before displaying them in the help '
            'explorer')
        self.all_groups_cb.setToolTip('Use all groups when displaying the '
                                      'keys, docs or summaries')
        self.include_links_cb.setToolTip(
            'Include links to remote documentations when showing the '
            'keys, docs and summaries in the help explorer (requires '
            'intersphinx)')

        # ---------------------------------------------------------------------
        # -------------------------- Connections ------------------------------
        # ---------------------------------------------------------------------
        self.group_combo.currentIndexChanged[int].connect(self.fill_fmt_combo)
        self.fmt_combo.currentIndexChanged[int].connect(self.show_fmt_info)
        self.fmt_combo.currentIndexChanged[int].connect(self.load_fmt_widget)
        self.fmt_combo.currentIndexChanged[int].connect(
            self.set_current_fmt_value)
        self.run_button.clicked.connect(self.run_code)
        self.line_edit.returnPressed.connect(self.run_button.click)
        self.multiline_button.clicked.connect(self.toggle_line_edit)
        self.keys_button.clicked.connect(
            partial(self.show_all_fmt_info, 'keys'))
        self.summaries_button.clicked.connect(
            partial(self.show_all_fmt_info, 'summaries'))
        self.docs_button.clicked.connect(
            partial(self.show_all_fmt_info, 'docs'))

        # ---------------------------------------------------------------------
        # ------------------------------ Layouts ------------------------------
        # ---------------------------------------------------------------------
        self.combos = QHBoxLayout()
        self.combos.addWidget(self.group_combo)
        self.combos.addWidget(self.fmt_combo)

        self.execs = QHBoxLayout()
        self.execs.addWidget(self.line_edit)
        self.execs.addWidget(self.text_edit)
        self.execs.addWidget(self.run_button)

        self.info_box = QHBoxLayout()
        self.info_box.addWidget(self.multiline_button)
        self.info_box.addWidget(self.yaml_cb)
        self.info_box.addStretch(0)
        for w in [
                self.keys_button, self.summaries_button, self.docs_button,
                self.all_groups_cb, self.grouped_cb, self.include_links_cb
        ]:
            self.info_box.addWidget(w)

        self.vbox = QVBoxLayout()
        self.vbox.addLayout(self.combos)
        self.vbox.addWidget(self.dim_widget)
        self.vbox.addLayout(self.execs)
        self.vbox.addLayout(self.info_box)

        self.vbox.setSpacing(0)

        self.setLayout(self.vbox)

        # fill with content
        self.fill_combos_from_project(psy.gcp())
        psy.Project.oncpchange.connect(self.fill_combos_from_project)
        rcParams.connect('fmt.sort_by_key', self.refill_from_rc)