Skip to content
Snippets Groups Projects
Commit e17832b6 authored by Allen, Bruce (CIV)'s avatar Allen, Bruce (CIV)
Browse files

fix navigation controls to work when sorting and filtering

parent 74bc0a9d
No related branches found
No related tags found
No related merge requests found
Showing
with 645 additions and 341 deletions
......@@ -91,7 +91,7 @@ class EventMenu(QObject):
"Manage event visibility")
def _set_menu_visibility(self):
if self.scene.selected_graph_index == -1 \
if self.scene.graph_index == -1 \
or not self.scene.graph_item.has_trace():
# no graph
......
......@@ -59,10 +59,11 @@ def _log_status(status, trace_filename):
log("Exported trace image file %s" % trace_filename)
class ExportTraceManager(QObject):
def __init__(self, parent_w, graphs_manager):
def __init__(self, parent_w, graphs_manager, graph_list_view):
super().__init__()
self.parent_w = parent_w
self.graphs_manager = graphs_manager
self.graph_list_view = graph_list_view
# action export trace as image file
self.action_export_trace = QAction("&Export graph view...")
......@@ -81,7 +82,8 @@ class ExportTraceManager(QObject):
@Slot()
def select_and_export_trace(self):
graph_index = self.graphs_manager.selected_graph_index
graph_index, graph_item \
= self.graph_list_view.selected_graph_index_and_item()
if graph_index == -1:
log("Error exporting graph: No graph selected.")
return
......@@ -102,7 +104,6 @@ class ExportTraceManager(QObject):
preferences["preferred_trace_dir"] = head
# export the trace as image file
graph_item = self.graphs_manager.graphs[graph_index]
status = _export_trace(filename, graph_item, graph_index, scope)
_log_status(status, filename)
......
......@@ -12,12 +12,12 @@ import resources_rc
class GraphListFilterManager(QObject):
"""Oversees filtering: Provides the filter menu, wraps filter inputs,
and calls sort_filter_proxy_model set_filter."""
and calls graph_list_proxy_model set_filter."""
def __init__(self, gui_manager):
super().__init__()
self.sort_filter_proxy_model = gui_manager.graph_list_table \
.sort_filter_proxy_model
self.graph_list_proxy_model = gui_manager.graph_list_view \
.graph_list_proxy_model
self.filter_event_dialog_wrapper = FilterEventDialogWrapper(
gui_manager.w, gui_manager.graphs_manager,
......@@ -174,7 +174,7 @@ class GraphListFilterManager(QObject):
}
# apply the filter
self.sort_filter_proxy_model.set_filter(filter_selections)
self.graph_list_proxy_model.set_filter(filter_selections)
@Slot()
def _reset_state(self):
......
......@@ -11,15 +11,14 @@ PROBABILITY_COLUMN = 3 # float 0.0 to 1.0
SIZE_COLUMN = 4 # int, see implementation
COLUMN_COUNT = 5 # number of columns
# GraphListTableModel
class GraphListTableModel(QAbstractTableModel):
class GraphListModel(QAbstractTableModel):
"""Provides a graph list table data model for displaying the graph views.
We use a table model instead of a list so we can define various columns
for sorting or filtering.
The first row displayed in the graph list is the global view. The
remaining rows show the trace views. This model provides both views
as though they are homogeneous types. Sort and filter operations
as though they are homogeneous types. Sort and filter operations must
keep the global view, if present, visible and on the top.
"""
......@@ -29,10 +28,10 @@ class GraphListTableModel(QAbstractTableModel):
# connect
graphs_manager.signal_graphs_loaded.connect(
self._reset_graph_list_table)
self._reset_graph_list)
@Slot()
def _reset_graph_list_table(self):
def _reset_graph_list(self):
self.beginResetModel()
# graphs_manager has already updated graphs
self.endResetModel()
......@@ -58,7 +57,7 @@ class GraphListTableModel(QAbstractTableModel):
column = model_index.column()
gry_graph = self.graphs_manager.graphs[row].gry_graph
if column == GRAPH_COLUMN:
# graph_list_table_view_delegate renders this
# graph_list_view_delegate renders this
return None # QVariant()
if column == TRACE_INDEX_COLUMN:
return row
......
......@@ -4,34 +4,31 @@ from PySide6.QtWidgets import QWidget, QLabel, QSpinBox, QHBoxLayout, \
QToolButton
from PySide6.QtWidgets import QAbstractSpinBox
from PySide6.QtWidgets import QSizePolicy
from PySide6.QtCore import QObject
from PySide6.QtCore import QObject, QModelIndex
class GraphListSelectionSpinner(QObject):
"""The trace selection spinner."""
"""Trace selection navigation."""
@Slot()
def _navigate_left(self):
selected_graph_index = self.graphs_manager.selected_graph_index
self.graphs_manager.set_selection(selected_graph_index - 1)
@Slot()
def _navigate_right(self):
selected_graph_index = self.graphs_manager.selected_graph_index
self.graphs_manager.set_selection(selected_graph_index + 1)
def __init__(self, graph_list_view):
super().__init__()
def __init__(self, graphs_manager, graph_list_table):
super(GraphListSelectionSpinner, self).__init__()
self.graph_list_view = graph_list_view
self.graphs_manager = graphs_manager
self.graph_list_table = graph_list_table
# connect
graph_list_view.model().modelReset.connect(self._set_spinner_range)
graph_list_view.selectionModel().currentChanged.connect(
self._set_spinner_value)
# state
self.disabled_for_compiler = False
# connect for filter
# https://stackoverflow.com/questions/29824591/qsortfilterproxymodel-filtering-complete-signal
graph_list_view.graph_list_proxy_model.rowsRemoved.connect(
self._set_spinner_range)
graph_list_view.graph_list_proxy_model.rowsInserted.connect(
self._set_spinner_range)
# connect
graphs_manager.signal_graphs_loaded.connect(self.set_range)
graphs_manager.signal_graph_selection_changed.connect(
self._set_selected_graph_index)
# connect for sort
graph_list_view.graph_list_proxy_model.layoutChanged.connect(
self._set_spinner_range)
# left and right arrow buttons
self.left_arrow_pb = QToolButton()
......@@ -48,7 +45,8 @@ class GraphListSelectionSpinner(QObject):
self.spinner.setSizePolicy(QSizePolicy.Policy.Maximum,
QSizePolicy.Policy.Maximum)
self.spinner.setButtonSymbols(QAbstractSpinBox.ButtonSymbols.NoButtons)
self.spinner.valueChanged.connect(self._value_changed)
self.spinner.setWrapping(True)
self.spinner.valueChanged.connect(self._spinner_value_changed)
self.total_count_label = QLabel()
# layout
......@@ -62,70 +60,90 @@ class GraphListSelectionSpinner(QObject):
# container
self.container = QWidget()
self.container.setLayout(layout)
self._ignore_selection_change = False
self.set_range()
# We want the spinner disabled while compiling, when there are no graphs,
# and when the global view at index 0 is selected.
def set_disable_for_compiler(self, disable):
self.disabled_for_compiler = disable
self._maybe_set_disabled()
def _maybe_set_disabled(self):
# maybe disable the whole container
if self.disabled_for_compiler:
self.container.setDisabled(True)
# this encompases all available inputs
return
else:
self.container.setDisabled(False)
self._ignore_value_change = False
self._set_spinner_range()
# enable or disable inputs inside the container based on state
graph_size = len(self.graphs_manager.graphs)
selected_graph_index = self.graphs_manager.selected_graph_index
# left arrow
if self.graphs_manager.has_non_empty_global_view:
smallest = 0
else:
smallest = 1
self.left_arrow_pb.setDisabled(selected_graph_index <= smallest)
def _maybe_set_disabled(self, row_count):
# right arrow
self.right_arrow_pb.setDisabled(selected_graph_index >= graph_size - 1)
# spinner and text
has_graphs = bool(self.graphs_manager.graphs)
self.spinner.setDisabled(not has_graphs)
self.total_count_label.setDisabled(not has_graphs)
# enable or disable inputs inside the container based on state
do_disable_navigation = row_count < 2
do_disable_label = row_count == 0
self.left_arrow_pb.setDisabled(do_disable_navigation)
self.right_arrow_pb.setDisabled(do_disable_navigation)
self.spinner.setDisabled(do_disable_navigation)
self.total_count_label.setDisabled(do_disable_label)
@Slot()
def set_range(self):
self._ignore_selection_change = True
if self.graphs_manager.graphs:
count = len(self.graphs_manager.graphs)
self.spinner.setRange(0, count - 1)
self.total_count_label.setText(
"of %d"%(count - 1))
def _navigate_left(self):
# decrement with wrap-around
row_count = self.graph_list_view.model().rowCount()
index = self.spinner.value()
hide_global_view = self.graph_list_view.graph_list_proxy_model \
.hide_global_view
if hide_global_view:
if index == 1:
new_index = row_count
else:
new_index = index - 1
else:
self.spinner.setRange(0,0)
self.total_count_label.setText("of 0")
self._maybe_set_disabled()
self._ignore_selection_change = False
if index == 0:
new_index = row_count - 1
else:
new_index = index - 1
self.spinner.setValue(new_index)
# set current trace number using this event
@Slot(int)
def _set_selected_graph_index(self, selected_graph_index):
self._ignore_selection_change = True
self.spinner.setValue(selected_graph_index)
self._ignore_selection_change = False
self._maybe_set_disabled()
@Slot()
def _navigate_right(self):
# increment with wrap-around
row_count = self.graph_list_view.model().rowCount()
index = self.spinner.value()
hide_global_view = self.graph_list_view.graph_list_proxy_model \
.hide_global_view
if hide_global_view:
if index == row_count:
new_index = 1
else:
new_index = index + 1
else:
if index == row_count:
new_index = 0
else:
new_index = index + 1
self.spinner.setValue(new_index)
# entry for spinner
# proxy range changes when the filter changes
@Slot()
def _set_spinner_range(self):
row_count = self.graph_list_view.model().rowCount()
if self.graph_list_view.graph_list_proxy_model.hide_global_view \
and row_count > 0:
self.spinner.setRange(1, row_count)
else:
self.spinner.setRange(0, row_count - 1)
self.total_count_label.setText("of %d"%(row_count))
self._maybe_set_disabled(row_count)
# set selection
selection_model = self.graph_list_view.selectionModel()
if selection_model.hasSelection():
self._set_spinner_value(selection_model.selectedIndexes()[0],
QModelIndex())
# set spinner value to match the graph list selection
@Slot(QModelIndex, QModelIndex)
def _set_spinner_value(self, current_index, _previous_index):
value = current_index.row()
if self.graph_list_view.graph_list_proxy_model.hide_global_view:
value += 1
self._ignore_value_change = True
self.spinner.setValue(value)
self._ignore_value_change = False
# spinner value changed
@Slot(int)
def _value_changed(self, selected_graph_index):
if not self._ignore_selection_change:
self.graphs_manager.set_selection(selected_graph_index)
self._maybe_set_disabled()
def _spinner_value_changed(self, value):
if not self._ignore_value_change:
if self.graph_list_view.graph_list_proxy_model.hide_global_view:
value -= 1
self.graph_list_view.select_proxy_index(value)
from PySide6.QtCore import Qt
from PySide6.QtCore import QSortFilterProxyModel
from graph_list_table_model import MARK_COLUMN
from graph_list_table_view import GraphListTableView
from graph_list_model import MARK_COLUMN
class GraphListSortFilterProxyModel(QSortFilterProxyModel):
def __init__(self, source_model):
......
......@@ -9,7 +9,7 @@ from PySide6.QtWidgets import QMenu
from PySide6.QtWidgets import QCheckBox, QPushButton
from PySide6.QtWidgets import QSizePolicy
from mp_style import mp_menu_button
from graph_list_table_model import GRAPH_COLUMN, TRACE_INDEX_COLUMN, \
from graph_list_model import GRAPH_COLUMN, TRACE_INDEX_COLUMN, \
MARK_COLUMN, PROBABILITY_COLUMN, SIZE_COLUMN
from filter_duplicate_traces import removable_traces
import resources_rc
......@@ -20,8 +20,8 @@ class GraphListSortManager(QObject):
def __init__(self, gui_manager):
super().__init__()
self.sort_filter_proxy_model = \
gui_manager.graph_list_table.sort_filter_proxy_model
self.graph_list_proxy_model = \
gui_manager.graph_list_view.graph_list_proxy_model
# connect to reset selections on graphs loaded event
gui_manager.graphs_manager.signal_graphs_loaded.connect(
......@@ -32,7 +32,7 @@ class GraphListSortManager(QObject):
def _triggered_function_function(self, sort_column, direction):
@Slot(bool)
def _triggered_function(_is_checked):
self.sort_filter_proxy_model.sort(sort_column, direction)
self.graph_list_proxy_model.sort(sort_column, direction)
return _triggered_function
......@@ -93,6 +93,6 @@ class GraphListSortManager(QObject):
@Slot()
def _reset_selections(self):
self.sort_group.actions()[0].setChecked(True)
self.sort_filter_proxy_model.sort(TRACE_INDEX_COLUMN,
self.graph_list_proxy_model.sort(TRACE_INDEX_COLUMN,
Qt.SortOrder.AscendingOrder)
from PySide6.QtCore import QObject # for signal/slot support
from PySide6.QtCore import Signal
from PySide6.QtCore import Slot
from PySide6.QtCore import Qt
from PySide6.QtCore import QSortFilterProxyModel
from PySide6.QtCore import QModelIndex
from graph_list_table_model import GraphListTableModel, GRAPH_COLUMN, \
TRACE_INDEX_COLUMN, MARK_COLUMN, PROBABILITY_COLUMN, SIZE_COLUMN
from graph_list_sort_filter_proxy_model import GraphListSortFilterProxyModel
from graph_list_table_view import GraphListTableView
class GraphListTable(QObject):
"""GraphListTableWidget provides the graph list. It wraps details of parts,
ref. http://doc.qt.io/qt-5/model-view-programming.html.
Sort and filter functions apply to columns in graph_list_table_model
Parts:
* GraphListTableModel Provides graphs from graph_manager
* GraphListTableViewDelegate Performs the rendering
* GraphListTableView Manages view
Sockets:
* signal_graph_selection_changed(graph_index)
* signal_graphs_loaded()
* signal_graph_index_view_changed calls graph_index_view_changed
"""
@Slot()
def _reset_scrollbar(self):
self.view.verticalScrollBar().setValue(0)
@Slot()
def _settings_changed(self):
# meaningless index works instead of len(data)
self.sort_filter_proxy_model.dataChanged.emit(
self.sort_filter_proxy_model.index(0, 0),
self.sort_filter_proxy_model.index(
self.sort_filter_proxy_model.rowCount(), 0))
def __init__(self, main_splitter, graphs_manager,
navigation_column_width_manager,
signal_settings_changed,
preferences_manager):
super(GraphListTable, self).__init__()
self.graphs_manager = graphs_manager
# model and view services
self.source_model = GraphListTableModel(graphs_manager)
self.sort_filter_proxy_model = GraphListSortFilterProxyModel(
self.source_model)
self.sort_filter_proxy_model.setSourceModel(self.source_model)
self.view = GraphListTableView(main_splitter, self,
navigation_column_width_manager,
preferences_manager)
# connect move scrollbar to top when graph is reloaded
graphs_manager.signal_graphs_loaded.connect(self._reset_scrollbar)
# connect select row when asked
graphs_manager.signal_graph_selection_changed.connect(self.select_graph)
# connect to redraw everything when settings changed
signal_settings_changed.connect(self._settings_changed)
# connect to redraw everything when probability view preference changes
preferences_manager.signal_show_type_1_probability_changed.connect(
self._settings_changed)
# convert graph index(row, 0) to proxy table model index(row, col)
def graph_index_to_proxy_model_index(self, graph_index):
if graph_index >= 0:
proxy_model_index = self.sort_filter_proxy_model.mapFromSource(
self.source_model.index(graph_index, 0))
else:
proxy_model_index = QModelIndex()
return proxy_model_index
# convert proxy table model to graph index
# a blank model index maps to -1
def proxy_model_index_to_graph_index(self, proxy_model_index):
model_index = self.sort_filter_proxy_model.mapToSource(
proxy_model_index)
graph_index, graph_column = model_index.row(), model_index.column()
return graph_index, graph_column
# programmatically select the table's row
@Slot(int)
def select_graph(self, graph_index):
proxy_model_index = self.graph_index_to_proxy_model_index(graph_index)
self.view.setCurrentIndex(proxy_model_index)
self.view.scrollTo(proxy_model_index)
# get the graph index that is selected in the model else -1
def selected_graph(self):
return self.proxy_model_index_to_graph_index(
self.view.currentIndex())[0]
# get the graph item that is selected in the model else None
def selected_graph_item(self):
index = self.selected_graph()
if index >= 0:
return self.graphs_manager.graphs[index]
else:
return None
# tell the table that the graph item at this index needs repainted
@Slot(int)
def graph_index_view_changed(self, graph_index):
proxy_model_index = self.graph_index_to_proxy_model_index(graph_index)
self.view.update(proxy_model_index)
from PySide6.QtCore import Slot
from PySide6.QtCore import QModelIndex
from PySide6.QtWidgets import QTableView
from PySide6.QtWidgets import QHeaderView
from PySide6.QtWidgets import QAbstractItemView
from graph_list_table_view_delegate import GraphListTableViewDelegate
from graph_list_table_model import COLUMN_COUNT
class GraphListTableView(QTableView):
def __init__(self, parent, graph_list_table,
navigation_column_width_manager, preferences_manager):
super(GraphListTableView, self).__init__(parent)
self.graph_list_table = graph_list_table
self.setModel(graph_list_table.sort_filter_proxy_model)
for i in range(1, COLUMN_COUNT):
self.setColumnHidden(i, True)
self.setColumnWidth(0, 20) # otherwise minimum is 100
self.horizontalHeader().hide()
self.verticalHeader().hide()
self.setShowGrid(False)
view_delegate = GraphListTableViewDelegate(graph_list_table,
navigation_column_width_manager)
self.setItemDelegate(view_delegate)
self.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
self.horizontalHeader().setStretchLastSection(True)
self.verticalHeader().setSectionResizeMode(
QHeaderView.ResizeMode.ResizeToContents)
navigation_column_width_manager.signal_navigation_column_width_changed\
.connect(self.changed_width)
# connect preferences
preferences_manager.signal_scroll_mode_changed.connect(
self._set_scroll_mode)
self._set_scroll_mode(preferences_manager.scroll_mode())
# user selection changed
def currentChanged(self, current, _previous):
graph_index, _column = self.graph_list_table\
.proxy_model_index_to_graph_index(current)
self.graph_list_table.graphs_manager.set_selection(graph_index)
# width changed
@Slot(int)
def changed_width(self, _width):
self.resizeRowsToContents()
# scroll mode preference changed
@Slot(str)
def _set_scroll_mode(self, scroll_mode):
if scroll_mode == "scroll_per_pixel":
self.setVerticalScrollMode(
QAbstractItemView.ScrollMode.ScrollPerPixel)
elif scroll_mode == "scroll_per_item":
self.setVerticalScrollMode(
QAbstractItemView.ScrollMode.ScrollPerItem)
else:
raise RuntimeError("bad")
from PySide6.QtCore import QObject # for signal/slot support
from PySide6.QtCore import Signal
from PySide6.QtCore import Slot
from PySide6.QtCore import Qt
from PySide6.QtCore import QModelIndex
from PySide6.QtCore import QItemSelectionModel
from PySide6.QtWidgets import QAbstractItemView, QTableView, QHeaderView
from graph_list_model import GRAPH_COLUMN, TRACE_INDEX_COLUMN, MARK_COLUMN, \
PROBABILITY_COLUMN, SIZE_COLUMN, COLUMN_COUNT
from graph_list_model import GraphListModel
from graph_list_sort_filter_proxy_model import GraphListSortFilterProxyModel
from graph_list_view_delegate import GraphListViewDelegate
class GraphListView(QTableView):
"""GraphListView provides the graph view. It holds the view delegate,
table model, and the proxy model.
Interfaces:
* graph_index() - the graph subscript
* proxy_index() - the proxy's subscript
* set_graph_index() - the graph subscript
* set_proxy_index() - the proxy's subscript
Singals:
* selectionChanged
#zzold
# Parts:
# * GraphListTableModel Provides graphs from graph_manager
# * GraphListTableViewDelegate Performs the rendering
# * GraphListTableView Manages view
#
# Sockets:
# * signal_graph_selection_changed(graph_index)
# * signal_graphs_loaded()
# * signal_graph_index_view_changed calls graph_index_view_changed
"""
def __init__(self, main_splitter,
graphs_manager,
navigation_column_width_manager,
signal_settings_changed,
preferences_manager):
super().__init__(main_splitter)
self.graphs_manager = graphs_manager
self.graph_list_model = GraphListModel(graphs_manager)
self.graph_list_proxy_model = GraphListSortFilterProxyModel(
self.graph_list_model)
self.graph_list_proxy_model.setSourceModel(self.graph_list_model)
# the data model
self.setModel(self.graph_list_proxy_model)
# table appearance
for i in range(1, COLUMN_COUNT):
self.setColumnHidden(i, True)
self.setColumnWidth(0, 20) # otherwise minimum is 100
self.horizontalHeader().hide()
self.verticalHeader().hide()
self.setShowGrid(False)
self.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
self.horizontalHeader().setStretchLastSection(True)
self.verticalHeader().setSectionResizeMode(
QHeaderView.ResizeMode.ResizeToContents)
self._set_scroll_mode(preferences_manager.scroll_mode())
# the delegate which will paint the graphs in the list
view_delegate = GraphListViewDelegate(self,
navigation_column_width_manager)
self.setItemDelegate(view_delegate)
# connect width changed
navigation_column_width_manager.signal_navigation_column_width_changed\
.connect(self._changed_width)
# connect scroll mode changed
preferences_manager.signal_scroll_mode_changed.connect(
self._set_scroll_mode)
# connect move scrollbar to top when graph is reloaded
graphs_manager.signal_graphs_loaded.connect(self._reset_scrollbar)
# connect to redraw everything when settings changed
signal_settings_changed.connect(self._settings_changed)
# connect to redraw everything when probability view preference changes
preferences_manager.signal_show_type_1_probability_changed.connect(
self._settings_changed)
def select_graph_index(self, graph_index):
graph_model_index = self.graph_list_model.index(graph_index, 0)
proxy_model_index = self.graph_list_proxy_model.mapFromSource(
graph_model_index)
self.selectionModel().setCurrentIndex(proxy_model_index,
QItemSelectionModel.SelectionFlag.ClearAndSelect)
def select_proxy_index(self, proxy_index):
proxy_model_index = self.graph_list_proxy_model.index(proxy_index, 0)
self.selectionModel().setCurrentIndex(proxy_model_index,
QItemSelectionModel.SelectionFlag.ClearAndSelect)
def selected_graph_index(self):
proxy_model_index = self.currentIndex()
graph_model_index = self.graph_list_proxy_model.mapToSource(
proxy_model_index)
return graph_model_index.row()
def selected_proxy_index(self):
proxy_model_index = self.currentIndex()
return proxy_model_index.row()
# graph item or None if row is -1
# useful for GraphListViewDelegate.paint
def graph_index_and_item(self, proxy_model_index):
graph_model_index = self.graph_list_proxy_model.mapToSource(
proxy_model_index)
row = graph_model_index.row()
if row >= 0:
graph_item = self.graphs_manager.graphs[graph_model_index.row()]
else:
graph_item = None
return row, graph_item
def selected_graph_index_and_item(self):
proxy_model_index = self.currentIndex()
return self.graph_index_and_item(proxy_model_index)
@Slot()
def _reset_scrollbar(self):
self.verticalScrollBar().setValue(0)
@Slot()
def _settings_changed(self):
# meaningless index works instead of len(data)
self.graph_list_proxy_model.dataChanged.emit(
self.graph_list_proxy_model.index(0, 0),
self.graph_list_proxy_model.index(
self.graph_list_proxy_model.rowCount(), 0))
# width changed
@Slot(int)
def _changed_width(self, _width):
self.resizeRowsToContents()
# scroll mode preference changed
@Slot(str)
def _set_scroll_mode(self, scroll_mode):
if scroll_mode == "scroll_per_pixel":
self.setVerticalScrollMode(
QAbstractItemView.ScrollMode.ScrollPerPixel)
elif scroll_mode == "scroll_per_item":
self.setVerticalScrollMode(
QAbstractItemView.ScrollMode.ScrollPerItem)
else:
raise RuntimeError("bad")
# # convert graph index(row, 0) to proxy table model index(row, col)
# def graph_index_to_proxy_model_index(self, graph_index):
# if graph_index >= 0:
# proxy_model_index = self.graph_list_proxy_model.mapFromSource(
# self.graph_list_model.index(graph_index, 0))
# else:
# proxy_model_index = QModelIndex()
# return proxy_model_index
#
# # convert proxy table model to graph index
# # a blank model index maps to -1
# def proxy_model_index_to_graph_index(self, proxy_model_index):
# model_index = self.graph_list_proxy_model.mapToSource(
# proxy_model_index)
# graph_index, graph_column = model_index.row(), model_index.column()
# return graph_index, graph_column
#
# # programmatically select the table's row
# @Slot(int)
# def select_graph(self, graph_index):
# proxy_model_index = self.graph_index_to_proxy_model_index(graph_index)
# self.view.setCurrentIndex(proxy_model_index)
# self.view.scrollTo(proxy_model_index)
#
# # get the graph index that is selected in the model else -1
# def selected_graph(self):
# return self.proxy_model_index_to_graph_index(
# self.view.currentIndex())[0]
#
# # tell the table that the graph item at this index needs repainted
# @Slot(int)
# def graph_index_view_changed(self, graph_index):
# proxy_model_index = self.graph_index_to_proxy_model_index(graph_index)
# self.view.update(proxy_model_index)
......@@ -7,20 +7,20 @@ from PySide6.QtWidgets import QStyledItemDelegate
from PySide6.QtWidgets import QStyle
from paint_graph_item import paint_graph_item
from graph_list_table_model import GRAPH_COLUMN
from graph_list_model import GRAPH_COLUMN
from font_helper import cell_height
# ref. https://github.com/scopchanov/CustomList/blob/master/app/src/Delegate.cpp
class GraphListTableViewDelegate(QStyledItemDelegate):
class GraphListViewDelegate(QStyledItemDelegate):
def __init__(self, graph_list_table, navigation_column_width_manager):
super(GraphListTableViewDelegate, self).__init__()
self.graph_list_table = graph_list_table
def __init__(self, graph_list_view, navigation_column_width_manager):
super().__init__()
self.graph_list_view = graph_list_view
self.navigation_column_width_manager = navigation_column_width_manager
# paint
def paint(self, painter, option, proxy_model_index):
# all but column 0 should be hidden in graph_list_table_view
# all but column 0 should be hidden in graph_list_view
if proxy_model_index.column() != GRAPH_COLUMN:
raise Exception("Bad")
......@@ -32,11 +32,8 @@ class GraphListTableViewDelegate(QStyledItemDelegate):
painter.translate(option.rect.x(), option.rect.y())
# this graph
graph_index, column = self.graph_list_table\
.proxy_model_index_to_graph_index(proxy_model_index)
if column != GRAPH_COLUMN:
raise RuntimeError("bad")
graph_item = self.graph_list_table.graphs_manager.graphs[graph_index]
graph_index, graph_item = self.graph_list_view.graph_index_and_item(
proxy_model_index)
# paint the graph within the bounds defined in option.rect
_scope = 0
......
......@@ -23,14 +23,10 @@ class GraphsManager(QObject):
Signals:
* signal_graphs_loaded()
* signal_graph_selection_changed(graph_index) - graph selection changed,
call this when the selection changes. selection can happen from
loading or navigating the graph list table.
"""
# signals
signal_graphs_loaded = Signal(name='graphsLoaded')
signal_graph_selection_changed = Signal(int, name='graphSelectionChanged')
def __init__(self, settings_manager):
super(GraphsManager, self).__init__()
......@@ -79,7 +75,7 @@ class GraphsManager(QObject):
self.ad_v_spacing = settings["ad_v_spacing"]
# instantiate graphs, set settings, then signal
def set_graphs(self, mp_code, gry_graphs, scope, selected_graph_index):
def set_graphs(self, mp_code, gry_graphs, scope):
self.mp_code = mp_code
self.mp_code_event_dict = event_dict(mp_code)
self.mp_code_event_list = event_list(self.mp_code_event_dict)
......@@ -92,22 +88,15 @@ class GraphsManager(QObject):
for gry_graph in gry_graphs:
self.graphs.append(GraphItem(gry_graph))
self.set_selection(selected_graph_index)
# remember spacing for reference in case spacing changes
self._remember_spacing()
# signal
self.signal_graphs_loaded.emit()
self.signal_graph_selection_changed.emit(self.selected_graph_index)
def clear_graphs(self):
self.set_graphs("", [], 1, -1)
# graph selection index
def set_selection(self, graph_index):
self.selected_graph_index = graph_index
self.signal_graph_selection_changed.emit(graph_index)
self.set_graphs("", [], 1)
def has_non_empty_global_view(self):
return bool(self.graphs and self.graphs[0].has_non_trace())
......
......@@ -15,11 +15,12 @@ class GryManager(QObject):
"""
def __init__(self, parent_w, graphs_manager, mp_code_manager,
settings_manager):
graph_list_view, settings_manager):
super().__init__()
self.parent_w = parent_w
self.graphs_manager = graphs_manager
self.mp_code_manager = mp_code_manager
self.graph_list_view = graph_list_view
self.settings_manager = settings_manager
# action import JSON .gry file
......@@ -55,10 +56,11 @@ class GryManager(QObject):
gry_data["mp_code"],
gry_data["graphs"],
gry_data["scope"],
gry_data["selected_graph_index"],
)
timestamp("Created graphs from gry")
show_timestamps()
self.graph_list_view.select_graph_index(
gry_data["selected_graph_index"])
self.mp_code_manager.set_text(gry_data["mp_code"])
self.settings_manager.change_settings(gry_data["settings"])
......
......@@ -18,8 +18,9 @@ from main_splitter import MainSplitter
from mp_code_column import MPCodeColumn
from navigation_column import NavigationColumn
from graph_list_selection_spinner import GraphListSelectionSpinner
from graph_main_widget import GraphMainWidget
from graph_list_table import GraphListTable
from main_graph_scene import MainGraphScene
from main_graph_view import MainGraphView
from graph_list_view import GraphListView
from navigation_column_width_manager import NavigationColumnWidthManager
from scope_spinner import ScopeSpinner
from graph_metadata_label import GraphMetadataLabel
......@@ -79,12 +80,15 @@ class GUIManager(QObject):
# the main window
self.w = MPMainWindow(self)
self.w.setWindowTitle("Monterey Phoenix v4 - Gryphon GUI %s"%VERSION)
self.w.setWindowIcon(QIcon(":/icons/mp_logo"))
# graph settings manager
self.settings_manager = SettingsManager(self.w)
# user preferences manager
self.preferences_manager = PreferencesManager(self)
self.preferences_manager.set_w_geometry()
# default settings includes referencing dark mode preference
set_default_settings(self.w)
......@@ -103,30 +107,25 @@ class GUIManager(QObject):
self.w.style().pixelMetric(
QStyle.PixelMetric.PM_ScrollBarExtent))
# main window decoration
self.preferences_manager.set_w_geometry()
self.w.setWindowTitle("Monterey Phoenix v4 - Gryphon GUI %s"%VERSION)
self.w.setWindowIcon(QIcon(":/icons/mp_logo"))
# the main splitter which emits size_changed
self.main_splitter = MainSplitter(self.navigation_column_width_manager)
# the graph list table which responds to events
self.graph_list_table = GraphListTable(
# the graph list view
self.graph_list_view = GraphListView(
self.main_splitter,
self.graphs_manager,
self.navigation_column_width_manager,
self.settings_manager.signal_settings_changed,
self.preferences_manager)
# the graph main widget
self.graph_main_widget = GraphMainWidget(self.graphs_manager,
self.settings_manager)
self.graph_main_widget.view.scale_view(preferences["graph_pane_scale"])
# graph list table signal
self.graph_main_widget.scene.signal_graph_index_view_changed.connect(
self.graph_list_table.graph_index_view_changed)
# the main graph scene and view
self.main_graph_scene = MainGraphScene(self.graphs_manager,
self.graph_list_view,
self.settings_manager)
self.main_graph_view = MainGraphView(
self.graphs_manager.signal_graphs_loaded)
self.main_graph_view.setScene(self.main_graph_scene)
self.main_graph_view.scale_view(preferences["graph_pane_scale"])
# the schema name and scope metadata label
self.graph_metadata_label = GraphMetadataLabel(self.graphs_manager)
......@@ -173,6 +172,7 @@ class GUIManager(QObject):
# .gry manager
self.gry_manager = GryManager(self.w, self.graphs_manager,
self.mp_code_manager,
self.graph_list_view,
self.settings_manager)
# the scope spinner containing spinner=QSpinBox
......@@ -181,7 +181,8 @@ class GUIManager(QObject):
# export trace manager
self.export_trace_manager = ExportTraceManager(self.w,
self.graphs_manager)
self.graphs_manager,
self.main_graph_scene)
# setup
self.define_actions()
......@@ -189,7 +190,7 @@ class GUIManager(QObject):
# graph list selection spinner
self.graph_list_selection_spinner = GraphListSelectionSpinner(
self.graphs_manager, self.graph_list_table)
self.graph_list_view)
# the central widget containing the main split pane
self.mp_code_column = MPCodeColumn(self)
......@@ -197,7 +198,7 @@ class GUIManager(QObject):
preferences["code_column_splitter_sizes"])
self.navigation_column = NavigationColumn(self)
self.main_splitter.addWidget(self.mp_code_column)
self.main_splitter.addWidget(self.graph_main_widget.view)
self.main_splitter.addWidget(self.main_graph_view)
self.main_splitter.addWidget(self.navigation_column)
self.main_splitter.setSizes(preferences["main_splitter_sizes"])
self.w.setCentralWidget(self.main_splitter)
......@@ -210,11 +211,11 @@ class GUIManager(QObject):
# do these before shutdown
application.aboutToQuit.connect(
self.graph_main_widget.scene.edge_grip_manager\
self.main_graph_scene.edge_grip_manager\
.unhighlight_edge) # avoid RuntimeError:
# wrapped C/C++ object of type EdgeGrip has been deleted
application.aboutToQuit.connect(
self.graph_main_widget.scene.view_ad_edge_grip_manager\
self.main_graph_scene.view_ad_edge_grip_manager\
.unhighlight_edge) # dispose grips to avoid RuntimeError
application.aboutToQuit.connect(
......@@ -342,14 +343,14 @@ class GUIManager(QObject):
"Zoom in", self)
self.action_zoom_in.setStatusTip("Zoom the graph pane in")
self.action_zoom_in.triggered.connect(
self.graph_main_widget.view.scale_view_in)
self.main_graph_view.scale_view_in)
# action zoom the graph pane out
self.action_zoom_out = QAction(QIcon(":/icons/zoom_out"),
"Zoom out", self)
self.action_zoom_out.setStatusTip("Zoom the graph pane out")
self.action_zoom_out.triggered.connect(
self.graph_main_widget.view.scale_view_out)
self.main_graph_view.scale_view_out)
# action zoom the graph pane reset to default scale
self.action_zoom_reset = QAction(QIcon(":/icons/zoom_reset"),
......@@ -357,7 +358,7 @@ class GUIManager(QObject):
self.action_zoom_reset.setStatusTip(
"Zoom the graph pane to its default scale")
self.action_zoom_reset.triggered.connect(
self.graph_main_widget.view.scale_view_reset)
self.main_graph_view.scale_view_reset)
def _fill_examples_menu(self):
if os.path.exists(examples_paths["models"]):
......@@ -527,8 +528,7 @@ class GUIManager(QObject):
toolbar.addWidget(QLabel("Scope"))
toolbar.addWidget(self.scope_spinner.spinner)
toolbar.addSeparator()
toolbar.addWidget(self.graph_main_widget.scene.event_menu \
.event_menu_button)
toolbar.addWidget(self.main_graph_scene.event_menu.event_menu_button)
toolbar.addSeparator()
toolbar.addAction(self.action_zoom_in)
toolbar.addAction(self.action_zoom_out)
......@@ -680,6 +680,9 @@ class GUIManager(QObject):
# set mp code
self.mp_code_manager.set_text(mp_code_text)
# clear the selection
self.graph_list_view.select_graph_index(-1)
# clear the graph
self.graphs_manager.clear_graphs()
......@@ -689,6 +692,9 @@ class GUIManager(QObject):
# set mp code
self.mp_code_manager.set_text("")
# clear the selection
self.graph_list_view.select_graph_index(-1)
# clear the graph
self.graphs_manager.clear_graphs()
......@@ -730,23 +736,23 @@ class GUIManager(QObject):
gry_graphs = tg_to_gry_graphs(tg_data)
timestamp("Created gry from tg")
scope = self.scope_spinner.scope()
# the default selected graph index is 1 else 0
if "traces" in tg_data and len(tg_data["traces"]) > 0:
selected_graph_index = 1
else:
selected_graph_index = 0
log("Compiled %s"%self._proposed_schema_name)
# gry data
self.graphs_manager.set_graphs(
self._proposed_mp_code,
gry_graphs,
self._proposed_scope,
selected_graph_index,
)
log("Compiled %s"%self._proposed_schema_name)
timestamp("Created graphs from gry")
# the default selected graph index is 1 else 0
if "traces" in tg_data and len(tg_data["traces"]) > 0:
selected_graph_index = 1
else:
selected_graph_index = 0
self.graph_list_view.select_graph_index(selected_graph_index)
# for diagnostics only, and only if it is not large,
# write .tg generated .gry JSON, indented with sorted keys
gry_data = {
......@@ -809,7 +815,7 @@ class GUIManager(QObject):
self.export_trace_manager.action_export_all_traces.setDisabled(
is_compiling)
self.open_menu_button.setDisabled(is_compiling)
self.graph_main_widget.scene.event_menu.event_menu_button \
self.main_graph_scene.event_menu.event_menu_button \
.setDisabled(is_compiling)
self.scope_spinner.spinner.setDisabled(is_compiling)
# Adapted from https://raw.githubusercontent.com/baoboa/pyqt5/master/examples/graphicsview/elasticnodes.py
import math
from PySide6.QtCore import QRectF, Qt
from PySide6.QtCore import Signal
from PySide6.QtCore import Slot
from PySide6.QtCore import QObject
from PySide6.QtCore import QModelIndex
from PySide6.QtGui import QTransform
from PySide6.QtGui import QCursor
from PySide6.QtWidgets import QGraphicsView
from PySide6.QtWidgets import QGraphicsScene
from PySide6.QtWidgets import QMenu
from edge_grip_manager import EdgeGripManager
from view_ad_edge_grip_manager import ViewADEdgeGripManager
from reset_scene_singleton import set_reset_scene_function
from event_menu import EventMenu
from os_compatibility import control_modifier
class MainGraphScene(QGraphicsScene):
# reset bounding rectangle, possibly centering the graph
def _set_scene_rect(self):
scene_rect = self.itemsBoundingRect()
self.setSceneRect(scene_rect)
def __init__(self, graphs_manager, graph_list_view, settings_manager):
super().__init__()
set_reset_scene_function(self.set_scene)
self.graphs_manager = graphs_manager
self.graph_list_view = graph_list_view
self.settings_manager = settings_manager
self._in_set_scene_rect = False
# the event menu which applies to any selected graph_item
self.event_menu = EventMenu(self, settings_manager)
# the scene's edge grip manager
self.edge_grip_manager = EdgeGripManager(self)
# the scene's AD edge grip manager
self.view_ad_edge_grip_manager = ViewADEdgeGripManager(self)
# connect to set main scene
graph_list_view.selectionModel().currentChanged.connect(
self._set_scene)
# connect to realign bounding rect
settings_manager.signal_settings_changed.connect(self._set_scene_rect)
self.graph_item = None
# set scene on selection, collapse/expand, or main view geometry change
def set_scene(self):
self._clear_scene()
_graph_index, self.graph_item \
= self.graph_list_view.selected_graph_index_and_item()
if self.graph_item:
# optimization: just-in-time for display, see graph_item.py
self.graph_item.initialize_items()
# add top level parent graph item to this scene
self.addItem(self.graph_item.background_box)
# set initial size
self._set_scene_rect()
# populate scene with QGraphicsItem items
@Slot(QModelIndex, QModelIndex)
def _set_scene(self, _current_proxy_model_index,
_previous_proxy_model_index):
self.set_scene()
def _clear_scene(self):
# remove any edge selection
self.edge_grip_manager.unhighlight_edge()
self.view_ad_edge_grip_manager.unhighlight_edge()
# remove the top level parent graph item from this scene
if self.graph_item:
self.removeItem(self.graph_item.background_box)
# clear graph_item pointer
self.graph_item = None
# set initial size
self._set_scene_rect()
def keyPressEvent(self, event):
# keystroke controls
key = event.key()
if key == Qt.Key.Key_A and event.modifiers() \
== Qt.KeyboardModifier.ControlModifier:
self.graph_item.trace.select_all_nodes()
elif key == Qt.Key.Key_H and event.modifiers() == control_modifier():
self.graph_item.trace.unhide_all_nodes()
elif key == Qt.Key.Key_H:
self.graph_item.trace.toggle_hide_unhide()
elif key == Qt.Key.Key_C:
self.graph_item.trace.toggle_collapse_uncollapse()
else:
super().keyPressEvent(event)
def mousePressEvent(self, event):
# do this so QGraphicsScene size can shrink back
self._set_scene_rect()
super().mousePressEvent(event)
def mouseMoveEvent(self, _event):
# do this so QGraphicsScene size can shrink back
if self._in_set_scene_rect:
# Avoid possible recursion that has been observed when
# overly zoomed in.
print("MainGraphScene._set_scene_rect comment: skipping "
"to avoid recursion")
super().mouseMoveEvent(_event)
else:
self._in_set_scene_rect = True
self._set_scene_rect()
super().mouseMoveEvent(_event)
self._in_set_scene_rect = False
def _show_scene_menu(self):
menu = QMenu()
menu.addAction(self.graphs_manager.action_show_hidden_components)
menu.addAction(
self.graphs_manager.action_show_hidden_components_all_graphs)
_action = menu.exec(QCursor.pos())
def contextMenuEvent(self, event):
item_under_cursor = self.itemAt(event.scenePos(), QTransform())
if item_under_cursor:
# forward event to item
item_under_cursor.contextMenuEvent(event)
else:
self._show_scene_menu()
# Adapted from https://raw.githubusercontent.com/baoboa/pyqt5/master/examples/graphicsview/elasticnodes.py
import math
from PySide6.QtCore import QRectF, Qt
from PySide6.QtCore import Signal
from PySide6.QtCore import Qt
from PySide6.QtCore import Slot
from PySide6.QtCore import QObject
from PySide6.QtGui import QBrush, QColor, QLinearGradient, QPainter
from PySide6.QtGui import QTransform
from PySide6.QtGui import QCursor
from PySide6.QtWidgets import QGraphicsView
from PySide6.QtWidgets import QGraphicsScene
from PySide6.QtWidgets import QGraphicsSceneContextMenuEvent
from PySide6.QtWidgets import QMenu
from settings_manager import settings
from preferences_manager import DEFAULT_GRAPH_PANE_SCALE
from edge_grip_manager import EdgeGripManager
from view_ad_edge_grip_manager import ViewADEdgeGripManager
from reset_scene_singleton import set_reset_scene_function
from event_menu import EventMenu
from os_compatibility import control_modifier
# GraphicsView
class GraphMainView(QGraphicsView):
class MainGraphView(QGraphicsView):
def __init__(self, signal_graphs_loaded):
super(GraphMainView, self).__init__()
super().__init__()
self.viewport_cursor = Qt.CursorShape.ArrowCursor
self.setViewportUpdateMode(
......@@ -68,7 +55,7 @@ class GraphMainView(QGraphicsView):
pass
else:
super(GraphMainView, self).keyPressEvent(event)
super().keyPressEvent(event)
def mousePressEvent(self, event):
# view mode
......@@ -78,11 +65,11 @@ class GraphMainView(QGraphicsView):
self.setDragMode(QGraphicsView.DragMode.RubberBandDrag)
self.viewport().setCursor(self.viewport_cursor)
super(GraphMainView, self).mousePressEvent(event)
super().mousePressEvent(event)
def mouseReleaseEvent(self, event):
# view mode
super(GraphMainView, self).mouseReleaseEvent(event)
super().mouseReleaseEvent(event)
self.setDragMode(QGraphicsView.DragMode.ScrollHandDrag)
self.viewport().setCursor(self.viewport_cursor)
......@@ -130,167 +117,3 @@ class GraphMainView(QGraphicsView):
def _reset_viewport(self):
self.centerOn(0, 0)
class GraphMainScene(QGraphicsScene):
# signals
signal_graph_index_view_changed = Signal(int,
name='graphIndexViewChanged')
# reset bounding rectangle, possibly centering the graph
def _set_scene_rect(self):
scene_rect = self.itemsBoundingRect()
self.setSceneRect(scene_rect)
# call this to emit indication that the main view geometry changed somehow
@Slot('QList<QRectF>')
def changed_main_view(self, _region):
if self.graph_item:
self.signal_graph_index_view_changed.emit(
self.selected_graph_index)
def __init__(self, graphs_manager, settings_manager):
super(GraphMainScene, self).__init__()
set_reset_scene_function(self.reset_scene)
self.graphs_manager = graphs_manager
self.settings_manager = settings_manager
self.selected_graph_index = -1
self._in_set_scene_rect = False
# the event menu which applies to any selected graph_item
self.event_menu = EventMenu(self, settings_manager)
# the scene's edge grip manager
self.edge_grip_manager = EdgeGripManager(self)
# the scene's AD edge grip manager
self.view_ad_edge_grip_manager = ViewADEdgeGripManager(self)
# connect to set main scene
graphs_manager.signal_graph_selection_changed.connect(self.set_scene)
# connect to know when graph_item geometry changes in order to
# emit need to repaint
self.changed.connect(self.changed_main_view)
# connect to realign bounding rect
settings_manager.signal_settings_changed.connect(self._set_scene_rect)
self.graph_item = None
# populate scene with QGraphicsItem items
@Slot(int)
def set_scene(self, selected_graph_index):
self.selected_graph_index = selected_graph_index
self.clear_scene()
if selected_graph_index == -1:
return
# keep for access
self.graph_item = self.graphs_manager.graphs[selected_graph_index]
# optimization: just-in-time for display, see graph_item.py
self.graph_item.initialize_items()
# add top level parent graph item to this scene
self.addItem(self.graph_item.background_box)
# set initial size
self._set_scene_rect()
# reset scene on collapse/expand or main view geometry change
def reset_scene(self):
self.set_scene(self.selected_graph_index)
# clear_scene
def clear_scene(self):
# remove any edge selection
self.edge_grip_manager.unhighlight_edge()
self.view_ad_edge_grip_manager.unhighlight_edge()
# remove the top level parent graph item from this scene
if self.graph_item:
self.removeItem(self.graph_item.background_box)
# clear graph_item pointer
self.graph_item = None
# set initial size
self._set_scene_rect()
def keyPressEvent(self, event):
# keystroke controls
key = event.key()
if key == Qt.Key.Key_A and event.modifiers() \
== Qt.KeyboardModifier.ControlModifier:
self.graph_item.trace.select_all_nodes()
elif key == Qt.Key.Key_H and event.modifiers() == control_modifier():
self.graph_item.trace.unhide_all_nodes()
elif key == Qt.Key.Key_H:
self.graph_item.trace.toggle_hide_unhide()
elif key == Qt.Key.Key_C:
self.graph_item.trace.toggle_collapse_uncollapse()
else:
super(GraphMainScene, self).keyPressEvent(event)
def mousePressEvent(self, event):
# do this so QGraphicsScene size can shrink back
self._set_scene_rect()
super(GraphMainScene, self).mousePressEvent(event)
def mouseMoveEvent(self, _event):
# do this so QGraphicsScene size can shrink back
if self._in_set_scene_rect:
# Avoid possible recursion that has been observed when
# overly zoomed in.
print("GraphMainScene._set_scene_rect comment: skipping "
"to avoid recursion")
super(GraphMainScene, self).mouseMoveEvent(_event)
else:
self._in_set_scene_rect = True
self._set_scene_rect()
super(GraphMainScene, self).mouseMoveEvent(_event)
self._in_set_scene_rect = False
def _show_scene_menu(self):
menu = QMenu()
menu.addAction(self.graphs_manager.action_show_hidden_components)
menu.addAction(
self.graphs_manager.action_show_hidden_components_all_graphs)
_action = menu.exec(QCursor.pos())
def contextMenuEvent(self, event):
item_under_cursor = self.itemAt(event.scenePos(), QTransform())
if item_under_cursor:
# forward event to item
item_under_cursor.contextMenuEvent(event)
else:
self._show_scene_menu()
# GraphMainWidget
class GraphMainWidget(QObject):
"""GraphMainWidget provides the main QGraphicsView. It manages signals
and wraps these:
* GraphMainView
* GraphMainScene
"""
def __init__(self, graphs_manager, settings_manager):
super(GraphMainWidget, self).__init__()
# GraphMainWidget's scene and view objects
self.scene = GraphMainScene(graphs_manager, settings_manager)
self.view = GraphMainView(graphs_manager.signal_graphs_loaded)
self.view.setScene(self.scene)
# graph manager
self.graphs_manager = graphs_manager
......@@ -30,8 +30,8 @@ class NavigationColumn(QWidget):
layout.addWidget(container_h)
# graph list
layout.addWidget(gui_manager.graph_list_table.view)
gui_manager.graph_list_table.view.setMinimumWidth(50)
layout.addWidget(gui_manager.graph_list_view)
gui_manager.graph_list_view.setMinimumWidth(50)
# set layout
self.setLayout(layout)
......
......@@ -172,7 +172,7 @@ class PreferencesManager(QObject):
preferences["use_auto_indent"] = self.use_auto_indent()
preferences["scroll_mode"] = self.scroll_mode()
preferences["graph_pane_scale"] \
= self.gui_manager.graph_main_widget.view.transform().m11()
= self.gui_manager.main_graph_view.transform().m11()
# export preferences in JSON
try:
......@@ -404,6 +404,6 @@ class PreferencesManager(QObject):
self.signal_scroll_mode_changed.emit(preferences["scroll_mode"])
self.action_use_dark_mode.setChecked(preferences["use_dark_mode"])
self._set_use_dark_mode(preferences["use_dark_mode"])
self.gui_manager.graph_main_widget.view.scale_view(
self.gui_manager.main_graph_view.scale_view(
preferences["graph_pane_scale"])
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment