-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Implement history table from dataframe view * Remove TableWidget code * Allow PandasModel to color values by both brightway and AB names
- Loading branch information
1 parent
70ec110
commit 22d92dd
Showing
2 changed files
with
77 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,70 +1,89 @@ | ||
# -*- coding: utf-8 -*- | ||
import brightway2 as bw | ||
from PyQt5 import QtCore, QtGui, QtWidgets | ||
import pandas as pd | ||
from PyQt5.QtCore import pyqtSlot | ||
from PyQt5.QtGui import QCursor | ||
from PyQt5.QtWidgets import QAbstractItemView, QMenu | ||
|
||
from . table import ABTableWidget, ABTableItem | ||
from ..icons import icons | ||
from ...signals import signals | ||
from activity_browser.app.bwutils.commontasks import bw_keys_to_AB_names | ||
from activity_browser.app.signals import signals | ||
|
||
from .views import ABDataFrameView, dataframe_sync | ||
from ..icons import qicons | ||
|
||
class ActivitiesHistoryTable(ABTableWidget): | ||
MAX_LENGTH = 40 | ||
COLUMNS = { | ||
0: "name", | ||
1: "reference product", | ||
2: "location", | ||
3: "unit", | ||
} | ||
HEADERS = ["Activity", "Reference Product", "Location", "Unit"] | ||
|
||
def __init__(self, *args): | ||
super(ActivitiesHistoryTable, self).__init__(*args) | ||
class ActivitiesHistoryTable(ABDataFrameView): | ||
COLUMNS = [ | ||
"name", | ||
"reference product", | ||
"location", | ||
"unit", | ||
] | ||
HEADERS = [bw_keys_to_AB_names[c] for c in COLUMNS] + ["key"] | ||
|
||
def __init__(self, parent=None): | ||
super().__init__(parent=parent) | ||
self.setDragEnabled(True) | ||
self.setRowCount(0) | ||
self.setColumnCount(len(self.HEADERS)) | ||
self.setup_context_menu() | ||
self.connect_signals() | ||
self.setSelectionMode(QAbstractItemView.SingleSelection) | ||
self.sync() | ||
self._connect_signals() | ||
|
||
def setup_context_menu(self): | ||
self.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) | ||
self.open_left_tab_action = QtWidgets.QAction( | ||
QtGui.QIcon(icons.left), "Open in new tab", None | ||
) | ||
self.addAction(self.open_left_tab_action) | ||
self.open_left_tab_action.triggered.connect( | ||
lambda x: signals.open_activity_tab.emit( | ||
self.currentItem().key | ||
) | ||
) | ||
def _connect_signals(self): | ||
self.doubleClicked.connect(self.open_tab_event) | ||
signals.add_activity_to_history.connect(self.add_activity) | ||
signals.project_selected.connect(self.sync) | ||
|
||
def connect_signals(self): | ||
self.itemDoubleClicked.connect( | ||
lambda x: signals.open_activity_tab.emit(self.currentItem().key) | ||
) | ||
self.itemDoubleClicked.connect( | ||
lambda x: signals.add_activity_to_history.emit(x.key) | ||
@dataframe_sync | ||
def sync(self, df=None): | ||
if df is None: | ||
df = pd.DataFrame([], columns=self.HEADERS) | ||
self.dataframe = df | ||
|
||
def contextMenuEvent(self, a0): | ||
menu = QMenu(self) | ||
menu.addAction( | ||
qicons.right, "Open in new tab", self.open_tab | ||
) | ||
signals.add_activity_to_history.connect(self.add_activity) | ||
signals.project_selected.connect(self.clear_history) | ||
menu.popup(QCursor.pos()) | ||
menu.exec() | ||
|
||
@pyqtSlot() | ||
def open_tab(self): | ||
""" Only a single row can be selected for the history, | ||
trigger the open_tab_event. | ||
""" | ||
proxy = next(i for i in self.selectedIndexes()) | ||
self.open_tab_event(proxy) | ||
|
||
def open_tab_event(self, proxy): | ||
index = self.get_source_index(proxy) | ||
key = self.dataframe.iloc[index.row(), ]["key"] | ||
signals.open_activity_tab.emit(key) | ||
self.add_activity(key) | ||
|
||
def add_activity(self, key): | ||
for row in range(self.rowCount()): | ||
if self.item(row, 0).key == key: | ||
self.removeRow(row) | ||
break # otherwise iterating over object that has changed | ||
@pyqtSlot(tuple) | ||
def add_activity(self, key: tuple) -> None: | ||
row = self.dataframe.loc[self.dataframe["key"].isin([key])] | ||
|
||
ds = bw.get_activity(key) | ||
self.insertRow(0) | ||
for col, value in self.COLUMNS.items(): | ||
if value == 'location': | ||
self.setItem(0, col, ABTableItem(str(ds.get(value, '')), key=key, color=value)) | ||
else: | ||
self.setItem(0, col, ABTableItem(ds.get(value, ''), key=key, color=value)) | ||
if not row.empty: | ||
# As data now exists in row, drop it from the dataframe | ||
self.dataframe.drop(row.index, inplace=True) | ||
else: | ||
# Data didn't exist, so build a new row with the key | ||
ds = bw.get_activity(key) | ||
data = { | ||
self.HEADERS[i]: ds.get(self.COLUMNS[i], "") | ||
for i in range(len(self.COLUMNS)) | ||
} | ||
data["key"] = key | ||
row = pd.DataFrame( | ||
[data], index=[0], columns=self.HEADERS | ||
) | ||
|
||
# Rebuild model with dataframe, added activity is placed at start | ||
self.sync(pd.concat([row, self.dataframe]).reset_index(drop=True)) | ||
|
||
def _resize(self): | ||
self.setColumnHidden(4, True) # Hide the 'key' column | ||
self.resizeColumnsToContents() | ||
self.resizeRowsToContents() | ||
|
||
def clear_history(self): | ||
self.clear() | ||
self.setHorizontalHeaderLabels(self.HEADERS) | ||
self.setRowCount(0) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters