Skip to content

Commit f06d3a3

Browse files
committed
Enable moving nodes to another database
1 parent 9a0af34 commit f06d3a3

2 files changed

Lines changed: 34 additions & 33 deletions

File tree

activity_browser/actions/activity/activity_duplicate_to_db.py

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,55 +2,56 @@
22

33
from qtpy import QtWidgets
44

5-
from activity_browser import application, settings
5+
import bw2data as bd
6+
7+
from activity_browser import application
8+
from activity_browser.bwutils import refresh_node
69
from activity_browser.actions.base import ABAction, exception_dialogs
7-
from activity_browser.bwutils import commontasks
8-
from activity_browser.mod import bw2data as bd
910
from activity_browser.ui.icons import qicons
1011

1112
from .activity_open import ActivityOpen
1213

1314

1415
class ActivityDuplicateToDB(ABAction):
15-
"""
16-
ABAction to duplicate an activity to another database. Asks the user to what database they want to copy the activity
17-
to, returns if there are no valid databases or when the user cancels. Otherwise uses the activity controller to
18-
duplicate the activities to the chosen database.
19-
"""
20-
2116
icon = qicons.duplicate_to_other_database
2217
text = "Duplicate to other database"
2318

2419
@classmethod
2520
@exception_dialogs
26-
def run(cls, activity_keys: List[tuple], to_db: str = None):
27-
# from activity_browser.bwutils.metadata import AB_metadata
28-
activities = [bd.get_activity(key) for key in activity_keys]
21+
def run(cls, nodes: List[tuple | int | bd.Node], to_db: str = None):
22+
nodes = [refresh_node(node) for node in nodes]
23+
24+
dbs = {node.get("database") for node in nodes}
25+
if not len(dbs) == 1:
26+
raise ValueError("All selected activities must be from the same database.")
27+
from_db = next(iter(dbs))
2928

3029
if to_db and not cls.confirm_db(to_db):
3130
return
3231

33-
target_db = to_db or cls.request_db(activities)
32+
to_db = to_db or cls.request_db(nodes, backend=bd.databases[from_db]["backend"])
3433

35-
if not target_db:
34+
if not to_db:
3635
return
3736

38-
new_activity_keys = []
37+
new_nodes = []
3938

40-
# otherwise move all supplied activities to the db using the controller
41-
for activity in activities:
42-
new_code = commontasks.generate_copy_code((target_db, activity["code"]))
43-
new_activity = activity.copy(code=new_code, database=target_db)
44-
new_activity_keys.append(new_activity.key)
39+
# otherwise move all supplied nodes to the db by copying them
40+
for node in nodes:
41+
new_node = node.copy(database=to_db)
42+
new_nodes.append(new_node)
4543

46-
ActivityOpen.run(new_activity_keys)
44+
ActivityOpen.run(new_nodes)
4745

4846
@staticmethod
49-
def request_db(activities):
50-
# get valid databases (not the original database, or locked databases)
51-
origin_db = next(iter(activities)).get("database")
47+
def request_db(nodes: list[bd.Node], backend: str) -> str | None:
48+
# get valid databases (not the original database, locked databases, or databases with a different backend)
49+
origin_db = next(iter(nodes)).get("database")
5250
target_dbs = [
53-
db for db in settings.project_settings.get_editable_databases() if db != origin_db
51+
db for db, meta in bd.databases.items() if
52+
db != origin_db
53+
and meta.get("read_only") is not True
54+
and meta.get("backend") == backend
5455
]
5556

5657
# return if there are no valid databases to duplicate to
@@ -65,24 +66,20 @@ def request_db(activities):
6566
# construct a dialog where the user can choose a database to duplicate to
6667
target_db, ok = QtWidgets.QInputDialog.getItem(
6768
application.main_window,
68-
"Copy activity to database",
69+
"Move node to database",
6970
"Target database:",
7071
target_dbs,
7172
0,
7273
False,
7374
)
7475

75-
# return if the user didn't choose, or canceled
76-
if not ok:
77-
return
78-
79-
return target_db
76+
return target_db if ok else None
8077

8178
@staticmethod
8279
def confirm_db(to_db: str):
8380
user_choice = QtWidgets.QMessageBox.question(
8481
application.main_window,
85-
"Duplicate to new database",
86-
f"Copy to {to_db} and open as new tab?",
82+
"Move to new database",
83+
f"Move to {to_db} and open as new tab?",
8784
)
8885
return user_choice == user_choice.Yes

activity_browser/layouts/panes/database_products.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,10 @@ class ContextMenu(ui.widgets.ABMenu):
266266
text="Duplicate process" if len(p.selected_activities) == 1 else "Duplicate processes",
267267
enable=len(p.selected_activities) > 0 and not database_is_locked(m.database_name),
268268
),
269+
lambda m, p: m.add(actions.ActivityDuplicateToDB, p.selected_activities,
270+
text="Move process" if len(p.selected_activities) == 1 else "Move processes",
271+
enable=len(p.selected_activities) > 0 and not database_is_locked(m.database_name),
272+
),
269273
lambda m: m.addSeparator(),
270274
lambda m, p: m.add(actions.ActivityDelete, p.selected_activities,
271275
text="Delete process" if len(p.selected_activities) == 1 else "Delete processes",

0 commit comments

Comments
 (0)