diff --git a/spinetoolbox/spine_db_editor/ui/db_commit_viewer.py b/spinetoolbox/spine_db_editor/ui/db_commit_viewer.py
new file mode 100644
index 000000000..b9d750e60
--- /dev/null
+++ b/spinetoolbox/spine_db_editor/ui/db_commit_viewer.py
@@ -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 .
+######################################################################################################################
+
+################################################################################
+## 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"\n"
+"
\n"
+"No affected items found for selected commit.
\n"
+"Note that we cannot show items that have been removed by this or a later commit.
", None))
+ pass
+ # retranslateUi
+
diff --git a/spinetoolbox/spine_db_editor/ui/db_commit_viewer.ui b/spinetoolbox/spine_db_editor/ui/db_commit_viewer.ui
new file mode 100644
index 000000000..9a09ab605
--- /dev/null
+++ b/spinetoolbox/spine_db_editor/ui/db_commit_viewer.ui
@@ -0,0 +1,121 @@
+
+
+
+ DBCommitViewer
+
+
+
+ 0
+ 0
+ 716
+ 218
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ Qt::ScrollBarAlwaysOff
+
+
+ Qt::ScrollBarAlwaysOff
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+hr { height: 1px; border-width: 0; }
+li.unchecked::marker { content: "\2610"; }
+li.checked::marker { content: "\2612"; }
+</style></head><body style=" font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;">
+<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>
+<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>
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spinetoolbox/spine_db_editor/widgets/commit_viewer.py b/spinetoolbox/spine_db_editor/widgets/commit_viewer.py
index 047178508..4576f9d63 100644
--- a/spinetoolbox/spine_db_editor/widgets/commit_viewer.py
+++ b/spinetoolbox/spine_db_editor/widgets/commit_viewer.py
@@ -15,7 +15,6 @@
QMainWindow,
QTabWidget,
QWidget,
- QVBoxLayout,
QGridLayout,
QTreeWidget,
QTreeWidgetItem,
@@ -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):
diff --git a/spinetoolbox/spine_db_editor/widgets/custom_qtreeview.py b/spinetoolbox/spine_db_editor/widgets/custom_qtreeview.py
index bdea9bf53..5ae9633d2 100644
--- a/spinetoolbox/spine_db_editor/widgets/custom_qtreeview.py
+++ b/spinetoolbox/spine_db_editor/widgets/custom_qtreeview.py
@@ -10,12 +10,12 @@
# this program. If not, see .
######################################################################################################################
-"""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
diff --git a/spinetoolbox/spine_db_manager.py b/spinetoolbox/spine_db_manager.py
index ee6087879..294bdd796 100644
--- a/spinetoolbox/spine_db_manager.py
+++ b/spinetoolbox/spine_db_manager.py
@@ -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)
diff --git a/tests/spine_db_editor/widgets/test_commit_viewer.py b/tests/spine_db_editor/widgets/test_commit_viewer.py
index 26ef8e9aa..1e746bf53 100644
--- a/tests/spine_db_editor/widgets/test_commit_viewer.py
+++ b/tests/spine_db_editor/widgets/test_commit_viewer.py
@@ -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")
@@ -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")