Skip to content

Commit

Permalink
Some improvements to save/load state
Browse files Browse the repository at this point in the history
  • Loading branch information
manuelma committed Sep 19, 2023
1 parent c9b6c17 commit 38810ee
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 24 deletions.
7 changes: 5 additions & 2 deletions spinetoolbox/spine_db_editor/graphics_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -921,7 +921,7 @@ def _place_resizers(self):
for anchor, resizer in self._resizers.items():
getter, _ = self._getter_setter[anchor]
resizer.setPos(
getattr(self.rect(), getter)() - resizer.rect().center() / self.scale() / self._scaling_factor
getattr(self.rect(), getter)() - getattr(resizer.rect(), getter)() / self.scale() / self._scaling_factor
)

def _resize(self, anchor, delta, strong):
Expand Down Expand Up @@ -950,6 +950,9 @@ def fit_rect(self, rect):
rect = QRectF(*rect)
self._do_resize(rect, True)

def scene_rect(self):
return self.mapToScene(self.rect()).boundingRect()

def fit_coordinates(self, p1, p2, scen1, scen2):
# NOTE: not in use at the moment
size = self._renderer.defaultSize()
Expand Down Expand Up @@ -1002,7 +1005,7 @@ class _Resizer(QGraphicsRectItem):
class SignalsProvider(QObject):
resized = Signal(QPointF, bool)

def __init__(self, rect=QRectF(0, 0, 12, 12), parent=None):
def __init__(self, rect=QRectF(0, 0, 20, 20), parent=None):
super().__init__(rect, parent)
self._original_rect = self.rect()
self._press_pos = None
Expand Down
49 changes: 30 additions & 19 deletions spinetoolbox/spine_db_editor/widgets/custom_qgraphicsviews.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import tempfile
from contextlib import contextmanager
from PySide6.QtCore import Qt, QTimeLine, Signal, Slot, QRectF
from PySide6.QtWidgets import QMenu, QGraphicsView, QInputDialog, QColorDialog
from PySide6.QtWidgets import QMenu, QGraphicsView, QInputDialog, QColorDialog, QMessageBox, QLineEdit
from PySide6.QtGui import QCursor, QPainter, QIcon, QAction, QPageSize, QPixmap
from PySide6.QtPrintSupport import QPrinter
from PySide6.QtSvg import QSvgGenerator
Expand Down Expand Up @@ -125,6 +125,7 @@ def __init__(self, parent):
self.name_parameter = ""
self.color_parameter = ""
self.arc_width_parameter = ""
self._current_state_name = ""
self._margin = 0.05
self._bg_item = None
self.selected_items = []
Expand Down Expand Up @@ -175,6 +176,18 @@ def __init__(self, parent):
self._items_per_class = {}
self._db_map_graph_data_by_name = {}

@property
def _qsettings(self):
return self._spine_db_editor.qsettings

@property
def db_mngr(self):
return self._spine_db_editor.db_mngr

@property
def entity_items(self):
return [x for x in self.scene().items() if isinstance(x, EntityItem) and x not in self.removed_items]

def get_property(self, name):
return self._properties[name].value

Expand Down Expand Up @@ -202,18 +215,6 @@ def get_pruned_entity_ids(self, db_map):
def get_pruned_db_map_entity_ids(self):
return [db_map_id for db_map_ids in self.pruned_db_map_entity_ids.values() for db_map_id in db_map_ids]

@property
def _qsettings(self):
return self._spine_db_editor.qsettings

@property
def db_mngr(self):
return self._spine_db_editor.db_mngr

@property
def entity_items(self):
return [x for x in self.scene().items() if isinstance(x, EntityItem) and x not in self.removed_items]

@Slot()
def handle_scene_selection_changed(self):
"""Filters parameters by selected objects in the graph."""
Expand Down Expand Up @@ -293,17 +294,26 @@ def populate_context_menu(self):
self._menu.aboutToShow.connect(self._update_actions_visibility)

def _save_state(self):
name, ok = QInputDialog.getText(self, "Save state...", "Enter a name for the state.")
name, ok = QInputDialog.getText(
self, "Save state...", "Enter a name for the state.", QLineEdit.Normal, self._current_state_name
)
if not ok:
return
if name in self._db_map_graph_data_by_name:
self._spine_db_editor.msg_error.emit(f"State {name} already exists")
db_map_graph_data = self._db_map_graph_data_by_name.get(name)
if db_map_graph_data is not None:
button = QMessageBox.question(
self._spine_db_editor,
self._spine_db_editor.windowTitle(),
f"State {name} already exists. Do you want to overwrite it?",
)
if button == QMessageBox.StandardButton.Yes:
self._spine_db_editor.overwrite_graph_data(db_map_graph_data)
return
self._spine_db_editor.save_graph_data(name)

@Slot(QAction)
def _load_state(self, action):
name = action.text()
self._current_state_name = name = action.text()
db_map_graph_data = self._db_map_graph_data_by_name.get(name)
self._spine_db_editor.load_graph_data(db_map_graph_data)

Expand Down Expand Up @@ -558,7 +568,8 @@ def _clear_positions(self, items):
return
db_map_ids = {}
for item in items:
db_map_ids.setdefault(item.db_map, set()).add(item.entity_id)
for db_map, entity_id in item.db_map_ids:
db_map_ids.setdefault(db_map, set()).add(entity_id)
db_map_typed_data = {}
for db_map, ids in db_map_ids.items():
db_map_typed_data[db_map] = {
Expand Down Expand Up @@ -603,7 +614,7 @@ def set_bg_rect(self, rect):

def get_bg_rect(self):
if self._bg_item is not None:
rect = self._bg_item.rect()
rect = self._bg_item.scene_rect()
return rect.x(), rect.y(), rect.width(), rect.height()

def clear_scene(self):
Expand Down
19 changes: 16 additions & 3 deletions spinetoolbox/spine_db_editor/widgets/graph_view_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,8 @@ def rebuild_graph(self, _checked=False):
self.db_map_entity_id_sets.clear()
self.build_graph()

def save_graph_data(self, name):
db_map_data = {}
def _get_db_map_graph_data(self):
db_map_graph_data = {}
for db_map in self.db_maps:
graph_data = {
"type": "graph_data",
Expand All @@ -359,10 +359,22 @@ def save_graph_data(self, name):
"bg_rect": self.ui.graphicsView.get_bg_rect(),
"properties": self.ui.graphicsView.get_all_properties(),
}
db_map_data[db_map] = [{"name": name, "value": json.dumps(graph_data)}]
db_map_graph_data[db_map] = json.dumps(graph_data)
return db_map_graph_data

def save_graph_data(self, name):
db_map_graph_data = self._get_db_map_graph_data()
db_map_data = {db_map: [{"name": name, "value": gd}] for db_map, gd in db_map_graph_data.items()}
self.db_mngr.add_metadata(db_map_data)
# TODO: also add entity_metadata so it sticks

def overwrite_graph_data(self, db_map_graph_data):
db_map_graph_data_ = self._get_db_map_graph_data()
db_map_data = {
db_map: [{"id": db_map_graph_data[db_map]["id"], "value": gd}] for db_map, gd in db_map_graph_data_.items()
}
self.db_mngr.update_metadata(db_map_data)

def get_db_map_graph_data_by_name(self):
db_map_graph_data_by_name = {}
for db_map in self.db_maps:
Expand All @@ -372,6 +384,7 @@ def get_db_map_graph_data_by_name(self):
except json.decoder.JSONDecodeError:
continue
if isinstance(graph_data, dict) and graph_data.get("type") == "graph_data":
graph_data["id"] = metadata_item["id"]
db_map_graph_data_by_name.setdefault(metadata_item["name"], {})[db_map] = graph_data
return db_map_graph_data_by_name

Expand Down

0 comments on commit 38810ee

Please sign in to comment.