Skip to content

Commit

Permalink
Add message to commit viewer that explains why items may be missing
Browse files Browse the repository at this point in the history
The message hopefully helps users to understand why the viewer
sometimes shows no affected items.

Re #2602
  • Loading branch information
soininen committed Apr 16, 2024
1 parent 701309a commit 80a0360
Show file tree
Hide file tree
Showing 6 changed files with 256 additions and 39 deletions.
99 changes: 99 additions & 0 deletions spinetoolbox/spine_db_editor/ui/db_commit_viewer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# -*- coding: utf-8 -*-
######################################################################################################################
# Copyright (C) 2017-2022 Spine project consortium
# Copyright Spine Toolbox contributors
# This file is part of Spine Toolbox.
# Spine Toolbox is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General
# Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option)
# any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
# Public License for more details. You should have received a copy of the GNU Lesser General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
######################################################################################################################

################################################################################
## Form generated from reading UI file 'db_commit_viewer.ui'
##
## Created by: Qt User Interface Compiler version 6.5.2
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################

from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
QMetaObject, QObject, QPoint, QRect,
QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QFont, QFontDatabase, QGradient, QIcon,
QImage, QKeySequence, QLinearGradient, QPainter,
QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QHBoxLayout, QHeaderView, QSizePolicy,
QSplitter, QStackedWidget, QTextBrowser, QTreeWidget,
QTreeWidgetItem, QWidget)

class Ui_DBCommitViewer(object):
def setupUi(self, DBCommitViewer):
if not DBCommitViewer.objectName():
DBCommitViewer.setObjectName(u"DBCommitViewer")
DBCommitViewer.resize(716, 218)
self.horizontalLayout_2 = QHBoxLayout(DBCommitViewer)
self.horizontalLayout_2.setSpacing(0)
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
self.splitter = QSplitter(DBCommitViewer)
self.splitter.setObjectName(u"splitter")
self.splitter.setOrientation(Qt.Horizontal)
self.commit_list = QTreeWidget(self.splitter)
self.commit_list.setObjectName(u"commit_list")
self.splitter.addWidget(self.commit_list)
self.affected_items_widget_stack = QStackedWidget(self.splitter)
self.affected_items_widget_stack.setObjectName(u"affected_items_widget_stack")
self.page = QWidget()
self.page.setObjectName(u"page")
self.horizontalLayout_3 = QHBoxLayout(self.page)
self.horizontalLayout_3.setSpacing(0)
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
self.affected_items = QTreeWidget(self.page)
self.affected_items.setObjectName(u"affected_items")

self.horizontalLayout_3.addWidget(self.affected_items)

self.affected_items_widget_stack.addWidget(self.page)
self.page_2 = QWidget()
self.page_2.setObjectName(u"page_2")
self.horizontalLayout = QHBoxLayout(self.page_2)
self.horizontalLayout.setSpacing(0)
self.horizontalLayout.setObjectName(u"horizontalLayout")
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.no_affected_items_notice = QTextBrowser(self.page_2)
self.no_affected_items_notice.setObjectName(u"no_affected_items_notice")
self.no_affected_items_notice.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.no_affected_items_notice.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.no_affected_items_notice.setOpenLinks(False)

self.horizontalLayout.addWidget(self.no_affected_items_notice)

self.affected_items_widget_stack.addWidget(self.page_2)
self.splitter.addWidget(self.affected_items_widget_stack)

self.horizontalLayout_2.addWidget(self.splitter)


self.retranslateUi(DBCommitViewer)

QMetaObject.connectSlotsByName(DBCommitViewer)
# setupUi

def retranslateUi(self, DBCommitViewer):
self.no_affected_items_notice.setHtml(QCoreApplication.translate("DBCommitViewer", u"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><meta charset=\"utf-8\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"hr { height: 1px; border-width: 0; }\n"
"li.unchecked::marker { content: \"\\2610\"; }\n"
"li.checked::marker { content: \"\\2612\"; }\n"
"</style></head><body style=\" font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">No affected items found for selected commit.</p>\n"
"<p style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Note that we cannot show items that have been removed by this or a later commit.</p></body></html>", None))
pass
# retranslateUi

121 changes: 121 additions & 0 deletions spinetoolbox/spine_db_editor/ui/db_commit_viewer.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
######################################################################################################################
# Copyright (C) 2017-2022 Spine project consortium
# Copyright Spine Toolbox contributors
# This file is part of Spine Toolbox.
# Spine Toolbox is free software: you can redistribute it and\/or modify it under the terms of the GNU Lesser General
# Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option)
# any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
# Public License for more details. You should have received a copy of the GNU Lesser General Public License along with
# this program. If not, see <http:\/\/www.gnu.org\/licenses\/>.
######################################################################################################################
-->
<ui version="4.0">
<class>DBCommitViewer</class>
<widget class="QWidget" name="DBCommitViewer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>716</width>
<height>218</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QTreeWidget" name="commit_list"/>
<widget class="QStackedWidget" name="affected_items_widget_stack">
<widget class="QWidget" name="page">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTreeWidget" name="affected_items"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_2">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTextBrowser" name="no_affected_items_notice">
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;meta charset=&quot;utf-8&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
hr { height: 1px; border-width: 0; }
li.unchecked::marker { content: &quot;\2610&quot;; }
li.checked::marker { content: &quot;\2612&quot;; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;No affected items found for selected commit.&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Note that we cannot show items that have been removed by this or a later commit.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openLinks">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
61 changes: 29 additions & 32 deletions spinetoolbox/spine_db_editor/widgets/commit_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
QMainWindow,
QTabWidget,
QWidget,
QVBoxLayout,
QGridLayout,
QTreeWidget,
QTreeWidgetItem,
Expand All @@ -28,57 +27,55 @@

class _DBCommitViewer(QWidget):
def __init__(self, db_mngr, db_map, parent=None):
from ..ui.db_commit_viewer import Ui_DBCommitViewer

super().__init__(parent=parent)
self._ui = Ui_DBCommitViewer()
self._ui.setupUi(self)
self._db_mngr = db_mngr
self._db_map = db_map
self._commit_list = QTreeWidget(self)
self._commit_list.setHeaderLabel("Commits")
self._commit_list.setIndentation(0)
self.splitter = QSplitter(self)
self.splitter.setChildrenCollapsible(False)
self.splitter.setSizes([0.3, 0.7])
self._affected_items = QTreeWidget(self)
self._affected_items.setHeaderLabel("Affected items")
self.splitter.addWidget(self._commit_list)
self.splitter.addWidget(self._affected_items)
self.splitter.setStretchFactor(0, 0)
self.splitter.setStretchFactor(1, 1)
layout = QVBoxLayout(self)
self.setLayout(layout)
layout = self.layout()
layout.addWidget(self.splitter)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(0)
self._ui.commit_list.setHeaderLabel("Commits")
self._ui.commit_list.setIndentation(0)
self._ui.affected_items.setHeaderLabel("Affected items")
self._ui.splitter.setSizes([0.3, 0.7])
self._ui.splitter.setStretchFactor(0, 0)
self._ui.splitter.setStretchFactor(1, 1)
for commit in reversed(db_map.get_items("commit")):
tree_item = QTreeWidgetItem(self._commit_list)
tree_item = QTreeWidgetItem(self._ui.commit_list)
tree_item.setData(0, Qt.ItemDataRole.UserRole + 1, commit["id"])
self._commit_list.addTopLevelItem(tree_item)
index = self._commit_list.indexFromItem(tree_item)
self._ui.commit_list.addTopLevelItem(tree_item)
index = self._ui.commit_list.indexFromItem(tree_item)
widget = _CommitItem(commit)
self._commit_list.setIndexWidget(index, widget)
self._commit_list.currentItemChanged.connect(self._select_commit)
self._ui.commit_list.setIndexWidget(index, widget)
self._ui.commit_list.currentItemChanged.connect(self._select_commit)

@property
def splitter(self) -> QSplitter:
return self._ui.splitter

@Slot(QTreeWidgetItem, QTreeWidgetItem)
def _select_commit(self, current, previous):
self._commit_list.setDisabled(True)
self._ui.commit_list.setDisabled(True)
self._do_select_commit(current)
self._commit_list.setEnabled(True)
self._ui.commit_list.setEnabled(True)

@busy_effect
def _do_select_commit(self, current):
commit_id = current.data(0, Qt.ItemDataRole.UserRole + 1)
self._affected_items.clear()
# TODO: If no items, show message that data was overwritten by a further commit
self._ui.affected_items_widget_stack.setCurrentIndex(0)
self._ui.affected_items.clear()
for item_type, ids in self._db_mngr.get_items_for_commit(self._db_map, commit_id).items():
top_level_item = QTreeWidgetItem([item_type])
self._affected_items.addTopLevelItem(top_level_item)
self._ui.affected_items.addTopLevelItem(top_level_item)
bottom_level_item = QTreeWidgetItem(top_level_item)
bottom_level_item.setFlags(bottom_level_item.flags() & ~Qt.ItemIsSelectable)
index = self._affected_items.indexFromItem(bottom_level_item)
index = self._ui.affected_items.indexFromItem(bottom_level_item)
items = [self._db_mngr.get_item(self._db_map, item_type, id_) for id_ in ids]
widget = _AffectedItemsFromOneTable(items, parent=self._affected_items)
self._affected_items.setIndexWidget(index, widget)
widget = _AffectedItemsFromOneTable(items, parent=self._ui.affected_items)
self._ui.affected_items.setIndexWidget(index, widget)
top_level_item.setExpanded(True)
if self._ui.affected_items.topLevelItemCount() == 0:
self._ui.affected_items_widget_stack.setCurrentIndex(1)


class _CommitItem(QWidget):
Expand Down
6 changes: 3 additions & 3 deletions spinetoolbox/spine_db_editor/widgets/custom_qtreeview.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
######################################################################################################################

"""Classes for custom QTreeView."""
from PySide6.QtWidgets import QApplication, QHeaderView, QMenu, QAbstractItemView
"""Classes for custom QTreeViews and QTreeWidgets."""
from PySide6.QtWidgets import QApplication, QHeaderView, QMenu, QAbstractItemView, QTreeWidget, QTreeWidgetItem
from PySide6.QtCore import Signal, Slot, Qt, QEvent, QTimer, QModelIndex, QItemSelection, QSignalBlocker
from PySide6.QtGui import QMouseEvent, QIcon, QGuiApplication
from spinetoolbox.widgets.custom_qtreeview import CopyPasteTreeView
from spinetoolbox.helpers import busy_effect, CharIconEngine
from spinetoolbox.helpers import busy_effect, CharIconEngine, DB_ITEM_SEPARATOR
from .custom_delegates import ScenarioDelegate, AlternativeDelegate, ParameterValueListDelegate
from .scenario_generator import ScenarioGenerator
from ..mvcmodels import mime_types
Expand Down
2 changes: 1 addition & 1 deletion spinetoolbox/spine_db_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,7 @@ def get_value(self, db_map, item_type, id_, role=Qt.ItemDataRole.DisplayRole):
"""Returns the value or default value of a parameter.
Args:
db_map (DiffDatabaseMapping)
db_map (DatabaseMapping)
item_type (str): either "parameter_definition", "parameter_value", or "list_value"
id_ (int): The parameter_value or definition id
role (int, optional)
Expand Down
6 changes: 3 additions & 3 deletions tests/spine_db_editor/widgets/test_commit_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def test_initial_commit_shows_in_list(self):
tab_widget = self._commit_viewer.centralWidget()
self.assertEqual(tab_widget.currentIndex(), 0)
current_tab = tab_widget.currentWidget()
commit_list = current_tab._commit_list
commit_list = current_tab._ui.commit_list
self.assertEqual(commit_list.topLevelItemCount(), 1)
initial_commit_item = commit_list.topLevelItem(0)
commit_db_items = self._db_map.get_items("commit")
Expand All @@ -66,10 +66,10 @@ def test_selecting_initial_commit_shows_base_alternative(self):
tab_widget = self._commit_viewer.centralWidget()
self.assertEqual(tab_widget.currentIndex(), 0)
current_tab = tab_widget.currentWidget()
commit_list = current_tab._commit_list
commit_list = current_tab._ui.commit_list
initial_commit_item = commit_list.topLevelItem(0)
commit_list.setCurrentItem(initial_commit_item)
affected_list = current_tab._affected_items
affected_list = current_tab._ui.affected_items
self.assertEqual(affected_list.topLevelItemCount(), 1)
affected_item = affected_list.topLevelItem(0)
self.assertEqual(affected_item.data(0, Qt.ItemDataRole.DisplayRole), "alternative")
Expand Down

0 comments on commit 80a0360

Please sign in to comment.