Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

### Added

- Added interface language support for English and Simplified Chinese, with a
system-language option in Settings. Scientific database content, activity
names, methods, units, and exported source data remain unchanged.
- ([#512](https://github.com/LCA-ActivityBrowser/activity-browser/pull/512))
Added a number of small improvements to the AB, users can now copy existing
LCA setups. Additionally, multiple activities can now be duplicated, deleted
Expand Down
2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ recursive-include activity_browser *.js
recursive-include activity_browser *.css
recursive-include activity_browser *.txt
recursive-include activity_browser *.zip
recursive-include activity_browser *.json
recursive-include activity_browser *.qm
6 changes: 6 additions & 0 deletions activity_browser/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@
from .application import application
from .signals import signals
from .settings import ab_settings, project_settings
from .i18n import translation_manager
from .info import __version__ as version

# Install the selected interface language before importing or constructing UI
# classes. The setting itself changes only on restart in the first release.
translation_manager.install(application, ab_settings.language)

from .layouts.main import MainWindow
from .plugin import Plugin
from .controllers import *
Expand Down
17 changes: 9 additions & 8 deletions activity_browser/actions/activity/activity_delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from activity_browser import application
from activity_browser.actions.base import ABAction, exception_dialogs
from activity_browser.i18n import _
from activity_browser.mod import bw2data as bd
from activity_browser.mod.bw2data.parameters import (ActivityParameter, Group,
GroupDependency,
Expand All @@ -27,20 +28,23 @@ def run(activity_keys: List[tuple]):
# retrieve activity objects from the controller using the provided keys
activities = [bd.get_activity(key) for key in activity_keys]

warning_text = f"Are you certain you want to delete {len(activities)} activity/activities?"
warning_text = _(
"Are you certain you want to delete {count} activities?",
count=len(activities),
)

# check for downstream processes
if any(len(act.upstream()) > 0 for act in activities):
# warning text
warning_text += (
"\n\nOne or more activities have downstream processes. Deleting these activities will remove the "
"exchange from the downstream processes as well."
warning_text += _(
"\n\nOne or more activities have downstream processes. Deleting these "
"activities will also remove their exchanges from downstream processes."
)

# alert the user
choice = QtWidgets.QMessageBox.warning(
application.main_window,
"Deleting activity/activities",
_("Delete activities"),
warning_text,
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
QtWidgets.QMessageBox.No,
Expand All @@ -49,9 +53,6 @@ def run(activity_keys: List[tuple]):
# return if the user cancels
if choice == QtWidgets.QMessageBox.No:
return



# use the activity controller to delete multiple activities
for act in activities:
db, code = act.key
Expand Down
16 changes: 10 additions & 6 deletions activity_browser/actions/activity/activity_duplicate_to_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from activity_browser import application, project_settings
from activity_browser.actions.base import ABAction, exception_dialogs
from activity_browser.bwutils import commontasks
from activity_browser.i18n import _
from activity_browser.mod import bw2data as bd
from activity_browser.ui.icons import qicons

Expand Down Expand Up @@ -57,16 +58,19 @@ def request_db(activities):
if not target_dbs:
QtWidgets.QMessageBox.warning(
application.main_window,
"No target database",
"No valid target databases available. Create a new database or set one to writable (not read-only).",
_("No target database"),
_(
"No valid target databases are available. Create a new database "
"or make an existing database writable."
),
)
return

# construct a dialog where the user can choose a database to duplicate to
target_db, ok = QtWidgets.QInputDialog.getItem(
application.main_window,
"Copy activity to database",
"Target database:",
_("Copy activity to database"),
_("Target database:"),
target_dbs,
0,
False,
Expand All @@ -82,7 +86,7 @@ def request_db(activities):
def confirm_db(to_db: str):
user_choice = QtWidgets.QMessageBox.question(
application.main_window,
"Duplicate to new database",
f"Copy to {to_db} and open as new tab?",
_("Duplicate to new database"),
_("Copy to {database} and open it in a new tab?", database=to_db),
)
return user_choice == user_choice.Yes
5 changes: 3 additions & 2 deletions activity_browser/actions/activity/activity_new.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from activity_browser import application
from activity_browser.actions.base import ABAction, exception_dialogs
from activity_browser.i18n import _
from activity_browser.mod.bw2data import Database
from activity_browser.ui.icons import qicons

Expand All @@ -25,8 +26,8 @@ def run(database_name: str):
# ask the user to provide a name for the new activity
name, ok = QtWidgets.QInputDialog.getText(
application.main_window,
"Create new technosphere activity",
"Please specify an activity name:" + " " * 10,
_("Create new technosphere activity"),
_("Please specify an activity name:") + " " * 10,
QtWidgets.QLineEdit.Normal,
)

Expand Down
18 changes: 13 additions & 5 deletions activity_browser/actions/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from PySide2 import QtCore, QtGui, QtWidgets

from activity_browser import application
from activity_browser.i18n import _


class ABAction:
Expand All @@ -21,8 +22,9 @@ def triggered(cls, *args, **kwargs):

@classmethod
def get_QAction(cls, *args, **kwargs) -> QtWidgets.QAction:
action = QtWidgets.QAction(cls.icon, cls.text, None)
action.setToolTip(cls.tooltip)
action = QtWidgets.QAction(cls.icon, _(cls.text) if cls.text else "", None)
tooltip = cls.tooltip or getattr(cls, "tool_tip", None)
action.setToolTip(_(tooltip) if tooltip else "")

action.triggered.connect(lambda: cls.triggered(*args, **kwargs))

Expand All @@ -33,7 +35,7 @@ def get_QButton(cls, *args, **kwargs):
"""Convenience function to return a button that has this ABAction as default action."""
button = QtWidgets.QPushButton(
cls.icon,
cls.text
_(cls.text) if cls.text else "",
)
button.clicked.connect(lambda x: cls.triggered(*args, **kwargs))
return button
Expand All @@ -46,8 +48,14 @@ def wrapper(*args, **kwargs):
except Exception as e:
QtWidgets.QMessageBox.critical(
application.main_window,
f"An error occurred: {type(e).__name__}",
f"An error occurred, check the logs for more information \n\n {str(e)}",
_(
"An error occurred: {error_type}",
error_type=type(e).__name__,
),
_(
"An error occurred, check the logs for more information\n\n{error}",
error=str(e),
),
QtWidgets.QMessageBox.Ok,
)
raise e
Expand Down
11 changes: 7 additions & 4 deletions activity_browser/actions/biosphere_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from activity_browser import application
from activity_browser.actions.base import ABAction, exception_dialogs
from activity_browser.info import __ei_versions__
from activity_browser.i18n import _
from activity_browser.ui.widgets import (BiosphereUpdater,
EcoinventVersionDialog)
from activity_browser.utils import sort_semantic_versions
Expand All @@ -25,10 +26,12 @@ def run():
# warn user of consequences of updating
warn_dialog = QtWidgets.QMessageBox.question(
application.main_window,
"Update biosphere3?",
"Newer versions of the biosphere database may not\n"
"always be compatible with older ecoinvent versions.\n"
"\nUpdating the biosphere3 database cannot be undone!\n",
_("Update biosphere3?"),
_(
"Newer versions of the biosphere database may not always be "
"compatible with older ecoinvent versions.\n\nUpdating the "
"biosphere3 database cannot be undone!"
),
QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Abort,
QtWidgets.QMessageBox.Abort,
)
Expand Down
9 changes: 5 additions & 4 deletions activity_browser/actions/calculation_setup/cs_delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from activity_browser import application, signals
from activity_browser.actions.base import ABAction, exception_dialogs
from activity_browser.i18n import _
from activity_browser.mod import bw2data as bd
from activity_browser.ui.icons import qicons

Expand All @@ -25,8 +26,8 @@ def run(cs_name: str):
# ask the user whether they are sure to delete the calculation setup
warning = QtWidgets.QMessageBox.warning(
application.main_window,
f"Deleting Calculation Setup: {cs_name}",
"Are you sure you want to delete this calculation setup?",
_("Delete calculation setup: {name}", name=cs_name),
_("Are you sure you want to delete this calculation setup?"),
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
QtWidgets.QMessageBox.No,
)
Expand All @@ -41,7 +42,7 @@ def run(cs_name: str):

QtWidgets.QMessageBox.information(
application.main_window,
f"Deleting Calculation Setup: {cs_name}",
"Calculation setup was succesfully deleted.",
_("Delete calculation setup: {name}", name=cs_name),
_("The calculation setup was successfully deleted."),
QtWidgets.QMessageBox.Ok,
)
9 changes: 5 additions & 4 deletions activity_browser/actions/calculation_setup/cs_duplicate.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from activity_browser import application, signals
from activity_browser.actions.base import ABAction, exception_dialogs
from activity_browser.i18n import _
from activity_browser.mod import bw2data as bd
from activity_browser.ui.icons import qicons

Expand All @@ -26,8 +27,8 @@ def run(cs_name: str):
# prompt the user to give a name for the new calculation setup
new_name, ok = QtWidgets.QInputDialog.getText(
application.main_window,
f"Duplicate '{cs_name}'",
"Name of the duplicated calculation setup:" + " " * 10,
_("Duplicate '{name}'", name=cs_name),
_("Name of the duplicated calculation setup:") + " " * 10,
)

# return if the user cancels or gives no name
Expand All @@ -38,8 +39,8 @@ def run(cs_name: str):
if new_name in bd.calculation_setups:
QtWidgets.QMessageBox.warning(
application.main_window,
"Not possible",
"A calculation setup with this name already exists.",
_("Not possible"),
_("A calculation setup with this name already exists."),
)
return

Expand Down
9 changes: 5 additions & 4 deletions activity_browser/actions/calculation_setup/cs_new.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from activity_browser import application, signals
from activity_browser.actions.base import ABAction, exception_dialogs
from activity_browser.i18n import _
from activity_browser.mod import bw2data as bd
from activity_browser.ui.icons import qicons

Expand All @@ -26,8 +27,8 @@ def run():
# prompt the user to give a name for the new calculation setup
name, ok = QtWidgets.QInputDialog.getText(
application.main_window,
"Create new calculation setup",
"Name of new calculation setup:" + " " * 10,
_("Create new calculation setup"),
_("Name of new calculation setup:") + " " * 10,
)

# return if the user cancels or gives no name
Expand All @@ -38,8 +39,8 @@ def run():
if name in bd.calculation_setups:
QtWidgets.QMessageBox.warning(
application.main_window,
"Not possible",
"A calculation setup with this name already exists.",
_("Not possible"),
_("A calculation setup with this name already exists."),
)
return

Expand Down
9 changes: 5 additions & 4 deletions activity_browser/actions/calculation_setup/cs_rename.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from activity_browser import application, signals
from activity_browser.actions.base import ABAction, exception_dialogs
from activity_browser.i18n import _
from activity_browser.mod import bw2data as bd
from activity_browser.ui.icons import qicons

Expand All @@ -26,8 +27,8 @@ def run(cs_name: str):
# prompt the user to give a name for the new calculation setup
new_name, ok = QtWidgets.QInputDialog.getText(
application.main_window,
f"Rename '{cs_name}'",
"New name of this calculation setup:" + " " * 10,
_("Rename '{name}'", name=cs_name),
_("New name of this calculation setup:") + " " * 10,
)

# return if the user cancels or gives no name
Expand All @@ -38,8 +39,8 @@ def run(cs_name: str):
if new_name in bd.calculation_setups:
QtWidgets.QMessageBox.warning(
application.main_window,
"Not possible",
"A calculation setup with this name already exists.",
_("Not possible"),
_("A calculation setup with this name already exists."),
)
return

Expand Down
35 changes: 29 additions & 6 deletions activity_browser/actions/database/database_delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from activity_browser import application, project_settings
from activity_browser.actions.base import ABAction, exception_dialogs
from activity_browser.i18n import _
from activity_browser.mod import bw2data as bd
from activity_browser.mod.bw2data.backends.proxies import (ExchangeDataset,
Exchanges)
Expand Down Expand Up @@ -39,16 +40,38 @@ def run(db_name: str):
n_upstream_excs = len(excs)

# construct warning text
text = f"Are you sure you want to delete database '{db_name}'?"
if n_records:
text += f" It contains {n_records} activities"
if n_upstream_excs:
text += f" and {n_upstream_excs} exchanges to other databases"
if n_records and n_upstream_excs:
text = _(
"Are you sure you want to delete database '{database}'? It contains "
"{activities} activities and {exchanges} exchanges to other databases.",
database=db_name,
activities=n_records,
exchanges=n_upstream_excs,
)
elif n_records:
text = _(
"Are you sure you want to delete database '{database}'? It contains "
"{activities} activities.",
database=db_name,
activities=n_records,
)
elif n_upstream_excs:
text = _(
"Are you sure you want to delete database '{database}'? It has "
"{exchanges} exchanges to other databases.",
database=db_name,
exchanges=n_upstream_excs,
)
else:
text = _(
"Are you sure you want to delete database '{database}'?",
database=db_name,
)

# ask the user for confirmation
QtWidgets.QApplication.restoreOverrideCursor()
response = QtWidgets.QMessageBox.question(
application.main_window, "Delete database?", text
application.main_window, _("Delete database?"), text
)

# return if the user cancels
Expand Down
Loading