diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 929692f..2f4a208 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,7 +1,14 @@ v1.2.5 ====== +Changed +------- - psyplot-gui has been moved from https://github.com/Chilipp/psyplot-gui to https://github.com/psyplot/psyplot-gui, see `#10 `__ +- variables in the dataset tree show now more content, + see `#16 `__ + +Added +----- - Add option to start the GUI without importing QtWebEngineWidgets `#11 `__ - Dockmixins (i.e. plugins) can now reimplement the `position_dock` method that diff --git a/appveyor.yml b/appveyor.yml index 72eb041..72e8238 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,10 +20,10 @@ install: - cmd: set CONDA_REPO_TOKEN= # conda config - conda config --set always_yes yes --set changeps1 no - - IF NOT DEFINED BUILD_STR_END (conda config --add channels chilipp/label/conda-forge) ELSE (conda config --add channels conda-forge) - - conda config --add channels psyplot - conda update -q conda - conda install conda-build anaconda-client + - IF NOT DEFINED BUILD_STR_END (conda config --add channels chilipp/label/conda-forge) ELSE (conda config --add channels conda-forge) + - conda config --add channels psyplot - conda info -a - conda list # windows config diff --git a/psyplot_gui/content_widget.py b/psyplot_gui/content_widget.py index 5c0de9a..fb5ab98 100644 --- a/psyplot_gui/content_widget.py +++ b/psyplot_gui/content_widget.py @@ -9,6 +9,7 @@ import sys import six import os.path as osp +import re import sip import weakref from itertools import chain @@ -377,22 +378,85 @@ def add_variables(self, ds=None): coords.addChild(item) else: variables.addChild(item) - desc = QTreeWidgetItem(0) if rcParams['content.load_tooltips']: item.setToolTip( 0, '
' + escape_html(str(variable)) + '
') - item.addChild(desc) - def add_attrs(self, attrs=None): + # Add shape + shape_item = QTreeWidgetItem(0) + shape_item.setText(0, 'shape') + shape_item.setText(1, str(variable.shape)) + item.addChild(shape_item) + + + # Add dimensions + dims_item = QTreeWidgetItem(0) + dims_item.setText(0, 'dims') + dims_item.setText(1, ', '.join(variable.dims)) + item.addChild(dims_item) + + # add open plots + plots_item = QTreeWidgetItem(0) + plots_item.setText(0, 'Plots') + self.refresh_plots_item(plots_item, vname) + item.addChild(plots_item) + + # add variable attribute + attrs_item = QTreeWidgetItem(0) + attrs_item.setText(0, 'Attributes') + self.add_attrs(variable.attrs, attrs_item) + item.addChild(attrs_item) + + # add variable encoding + encoding_item = QTreeWidgetItem(0) + encoding_item.setText(0, 'Encoded attributes') + self.add_attrs(variable.encoding, encoding_item) + item.addChild(encoding_item) + + def get_plots_item(self, item): + for child in map(item.child, range(item.childCount())): + if child.text(0) == 'Plots': + return child + + def refresh_plots_item(self, item, vname, mp=None, sp=None): + expand = item.isExpanded() + item.takeChildren() + try: + num = self.ds().psy.num + except AttributeError: + return + if mp is None: + mp = gcp(True) + if sp is None: + sp = gcp() + for i in range(len(mp)): + sub = mp[i:i+1] + array_info = sub.array_info(ds_description={'arr', 'num'}) + arrs = sub._get_ds_descriptions(array_info).get(num, {}) + if arrs and any(vname in arr.psy.base_variables + for arr in arrs['arr']): + child = QTreeWidgetItem(0) + prefix = '*' if sub[0] in sp else '' + text = sub[0].psy._short_info() + child.setText(0, prefix + text) + child.setToolTip(0, text) + item.addChild(child) + if expand and item.childCount(): + item.setExpanded(True) + + + def add_attrs(self, attrs=None, item=None): if attrs is None: attrs = self.ds().attrs self.attrs.takeChildren() - top = self.attrs + if item is None: + item = self.attrs for key, val in attrs.items(): child = QTreeWidgetItem(0) child.setText(0, key) child.setText(1, str(val)) - top.addChild(child) + child.setToolTip(1, '{}: {}'.format(key, str(val))) + item.addChild(child) class DatasetTree(QTreeWidget, DockMixin): @@ -412,11 +476,24 @@ def __init__(self, *args, **kwargs): self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.open_menu) Project.oncpchange.connect(self.add_datasets_from_cp) + self.hideColumn(1) + + @staticmethod + def is_variable(item): + return re.match(r'variables \(\d+\)', item.parent().text(0)) + + @staticmethod + def is_coord(item): + return re.match(r'coords\(\d+\)', item.parent().text(0)) def load_variable_desc(self, item): - # if we are not at the lowest level or the item has already label, pass - if item.child(0).childCount() or self.itemWidget(item.child(0), 0): + parent = item.parent() + if parent is self or parent is None or not (self.is_variable(item) or + self.is_coord(item)): return + if self.isColumnHidden(1): + self.showColumn(1) + self.resizeColumnToContents(0) top = item while top.parent() and top.parent() is not self: @@ -424,13 +501,8 @@ def load_variable_desc(self, item): ds = top.ds() if ds is None: return - widget = QScrollArea() - label = QLabel( - '
' + escape_html(str(ds.variables[item.text(0)])) + '
') - label.setTextFormat(Qt.RichText) - widget.setWidget(label) - self.setItemWidget(item.child(0), 0, widget) - item.child(0).setFirstColumnSpanned(True) + desc = escape_html(str(ds.variables[item.text(0)])) + item.setToolTip(0, '
' + desc + '
') def create_dataset_tree(self): """Set up the columns and insert the :class:`DatasetTreeItem` @@ -438,7 +510,7 @@ def create_dataset_tree(self): self.set_columns() self.add_datasets_from_cp(gcp()) - def set_columns(self, columns=['long_name', 'dims', 'shape']): + def set_columns(self, columns=['Value']): """Set up the columns in the DatasetTree. Parameters @@ -446,7 +518,11 @@ def set_columns(self, columns=['long_name', 'dims', 'shape']): columns: list of str A list of netCDF attributes that shall be shown in columns""" self.setColumnCount(len(columns) + 1) - self.setHeaderLabels(['Dataset'] + list(columns)) + if columns: + self.setHeaderHidden(False) + self.setHeaderLabels(['Dataset'] + list(columns)) + else: + self.setHeaderHidden(True) self.attr_columns = columns def expanded_items(self): @@ -527,7 +603,7 @@ def expand_items(self, expanded_items): def open_menu(self, pos): menu = QMenu() item = self.itemAt(pos) - parent, item_type = self._get_toplevel_item(item) + parent, item_type, vname = self._get_toplevel_item(item) # ---- Refresh the selected item action refresh_action = QAction('Refresh', self) refresh_action.setToolTip(self.tooltips['Refresh']) @@ -543,7 +619,7 @@ def open_menu(self, pos): # ---- add plot option if item_type == 'variable': - add2p_action = QAction('Add to project', self) + add2p_action = QAction(f'Add new plot of {vname}', self) add2p_action.setToolTip(self.tooltips['Add to project']) add2p_action.triggered.connect(lambda: self.make_plot( parent.ds(), item.text(0), True)) @@ -576,14 +652,17 @@ def _get_toplevel_item(self, item): else: parent = item.parent() item_type = None + vname = None while parent is not None: - if parent.text(0) == 'variables': + if self.is_variable(item): + vname = item.text(0) item_type = 'variable' - elif parent.text(0) == 'coords': + elif self.is_coord(item): + vname = item.text(0) item_type = 'coord' item = item.parent() parent = item.parent() - return item, item_type + return item, item_type, vname class FiguresTreeItem(QTreeWidgetItem):