Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Menu bar refactor #1367

Merged
merged 5 commits into from
Sep 27, 2024
Merged
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
191 changes: 115 additions & 76 deletions activity_browser/ui/menu_bar.py
Original file line number Diff line number Diff line change
@@ -1,144 +1,181 @@
import os
from importlib.metadata import version

from PySide2 import QtGui, QtWidgets
from PySide2.QtCore import QSize, QUrl, Slot

from activity_browser import actions, signals
from activity_browser import actions, signals, application, info
from activity_browser.mod import bw2data as bd

from ..info import __version__ as ab_version
from .icons import qicons

AB_BW25 = True if os.environ.get("AB_BW25", False) else False


class MenuBar(QtWidgets.QMenuBar):
"""
Main menu bar at the top of the Activity Browser window. Contains submenus for different user interaction categories
"""
def __init__(self, window):
super().__init__(parent=window)
self.window = window
self.file_menu = QtWidgets.QMenu("&Project", self.window)
self.view_menu = QtWidgets.QMenu("&View", self.window)
self.windows_menu = QtWidgets.QMenu("&Windows", self.window)
self.tools_menu = QtWidgets.QMenu("&Tools", self.window)
self.help_menu = QtWidgets.QMenu("&Help", self.window)

self.addMenu(ProjectMenu(self))
self.addMenu(ViewMenu(self))
self.addMenu(ToolsMenu(self))
self.addMenu(HelpMenu(self))


class ProjectMenu(QtWidgets.QMenu):
"""
Project menu: contains actions related to managing the project, such as project duplication, database importing etc.
"""

def __init__(self, parent=None) -> None:
super().__init__(parent)

self.setTitle("&Project")

self.new_proj_action = actions.ProjectNew.get_QAction()
self.dup_proj_action = actions.ProjectDuplicate.get_QAction()
self.delete_proj_action = actions.ProjectDelete.get_QAction()

self.import_proj_action = actions.ProjectImport.get_QAction()
self.export_proj_action = actions.ProjectExport.get_QAction()

self.import_db_action = actions.DatabaseImport.get_QAction()
self.export_db_action = actions.DatabaseExport.get_QAction()
self.update_biosphere_action = actions.BiosphereUpdate.get_QAction()
self.manage_settings_action = actions.SettingsWizardOpen.get_QAction()
self.manage_plugins_action = actions.PluginWizardOpen.get_QAction()

self.addMenu(self.file_menu)
self.addMenu(self.view_menu)
self.addMenu(self.tools_menu)
self.addMenu(self.help_menu)
self.manage_settings_action = actions.SettingsWizardOpen.get_QAction()

self.setup_file_menu()
self.setup_view_menu()
self.setup_tools_menu()
self.setup_help_menu()
self.connect_signals()
self.addMenu(ProjectSelectionMenu(self))
self.addAction(self.new_proj_action)
self.addAction(self.dup_proj_action)
self.addAction(self.delete_proj_action)
self.addSeparator()
self.addAction(self.import_proj_action)
self.addAction(self.export_proj_action)
self.addSeparator()
self.addAction(self.import_db_action)
self.addAction(self.export_db_action)
self.addAction(self.update_biosphere_action)
self.addSeparator()
self.addMenu(MigrationsMenu(self))
self.addSeparator()
self.addAction(self.manage_settings_action)

def connect_signals(self):
bd.projects.current_changed.connect(self.biosphere_exists)
bd.databases.metadata_changed.connect(self.biosphere_exists)

def setup_file_menu(self) -> None:
"""Build the menu for specific importing/export/updating actions."""
self.file_menu.addMenu(ProjectsMenu(self))
self.file_menu.addAction(self.new_proj_action)
self.file_menu.addAction(self.dup_proj_action)
self.file_menu.addAction(self.delete_proj_action)
self.file_menu.addSeparator()
self.file_menu.addAction(self.import_proj_action)
self.file_menu.addAction(self.export_proj_action)
self.file_menu.addSeparator()
self.file_menu.addAction(self.import_db_action)
self.file_menu.addAction(self.export_db_action)
self.file_menu.addAction(self.update_biosphere_action)
self.file_menu.addSeparator()
self.file_menu.addMenu(MigrationsMenu(self))
self.file_menu.addSeparator()
self.file_menu.addAction(self.manage_settings_action)

def setup_view_menu(self) -> None:
"""Build the menu for viewing or hiding specific tabs"""
self.view_menu.addAction(
def biosphere_exists(self) -> None:
"""Test if the default biosphere exists as a database in the project"""
exists = True if bd.config.biosphere in bd.databases else False
self.update_biosphere_action.setEnabled(exists)
self.import_db_action.setEnabled(exists)


class ViewMenu(QtWidgets.QMenu):
"""
View menu: contains actions in regard to hiding and showing specific UI elements.
"""

def __init__(self, parent=None) -> None:
super().__init__(parent)

self.setTitle("&View")

self.addAction(
qicons.graph_explorer,
"&Graph Explorer",
lambda: signals.toggle_show_or_hide_tab.emit("Graph Explorer"),
)
self.view_menu.addAction(
self.addAction(
qicons.history,
"&Activity History",
lambda: signals.toggle_show_or_hide_tab.emit("History"),
)
self.view_menu.addAction(
self.addAction(
qicons.welcome,
"&Welcome screen",
lambda: signals.toggle_show_or_hide_tab.emit("Welcome"),
)

def setup_tools_menu(self) -> None:
"""Build the tools menu for the menubar."""
self.tools_menu.addAction(self.manage_plugins_action)

def setup_help_menu(self) -> None:
"""Build the help menu for the menubar."""
self.help_menu.addAction(
self.window.icon, "&About Activity Browser", self.about
class ToolsMenu(QtWidgets.QMenu):
"""
Tools Menu: contains actions in regard to special tooling aspects of the AB
"""

def __init__(self, parent=None) -> None:
super().__init__(parent)
self.setTitle("&Tools")

self.manage_plugins_action = actions.PluginWizardOpen.get_QAction()

self.addAction(self.manage_plugins_action)


class HelpMenu(QtWidgets.QMenu):
"""
Help Menu: contains actions that show info to the user or redirect them to online resources
"""

def __init__(self, parent=None) -> None:
super().__init__(parent)
self.setTitle("&Help")

self.addAction(
qicons.ab, "&About Activity Browser", self.about
)
self.help_menu.addAction(
"&About Qt", lambda: QtWidgets.QMessageBox.aboutQt(self.window)
self.addAction(
"&About Qt", lambda: QtWidgets.QMessageBox.aboutQt(application.main_window)
)
self.help_menu.addAction(
self.addAction(
qicons.question, "&Get help on the wiki", self.open_wiki
)
self.help_menu.addAction(
self.addAction(
qicons.issue, "&Report an idea/issue on GitHub", self.raise_issue_github
)

def about(self):
text = """
Activity Browser - a graphical interface for Brightway2.<br><br>
Application version: <b>{}</b><br><br>
All development happens on <a href="https://github.com/LCA-ActivityBrowser/activity-browser">github</a>.<br><br>
For copyright information please see the copyright on <a href="https://github.com/LCA-ActivityBrowser/activity-browser/tree/main#copyright">this page</a>.<br><br>
For license information please see the copyright on <a href="https://github.com/LCA-ActivityBrowser/activity-browser/blob/main/LICENSE.txt">this page</a>.<br><br>
"""
msgBox = QtWidgets.QMessageBox(parent=self.window)
msgBox.setWindowTitle("About the Activity Browser")
pixmap = self.window.icon.pixmap(QSize(150, 150))
msgBox.setIconPixmap(pixmap)
msgBox.setWindowIcon(self.window.icon)
msgBox.setText(text.format(ab_version))
msgBox.exec_()
"""Displays an 'about' window to the user containing e.g. the version of the AB and copyright info"""
# set the window text in html format
text = f"""
Activity Browser - a graphical interface for Brightway2.<br><br>
Application version: <b>{version("activity_browser")}</b><br>
bw2data version: <b>{version("bw2data")}</b><br>
bw2io version: <b>{version("bw2calc")}</b><br>
bw2calc version: <b>{version("bw2io")}</b><br><br>
All development happens on <a href="https://github.com/LCA-ActivityBrowser/activity-browser">github</a>.<br><br>
For copyright information please see the copyright on <a href="https://github.com/LCA-ActivityBrowser/activity-browser/tree/main#copyright">this page</a>.<br><br>
For license information please see the copyright on <a href="https://github.com/LCA-ActivityBrowser/activity-browser/blob/main/LICENSE.txt">this page</a>.<br><br>
"""

# set up the window
about_window = QtWidgets.QMessageBox(parent=application.main_window)
about_window.setWindowTitle("About the Activity Browser")
about_window.setIconPixmap(qicons.ab.pixmap(QSize(150, 150)))
about_window.setText(text)

# execute
about_window.exec_()

def open_wiki(self):
"""Opens the AB github wiki in the users default browser"""
url = QUrl(
"https://github.com/LCA-ActivityBrowser/activity-browser/wiki"
)
QtGui.QDesktopServices.openUrl(url)

def raise_issue_github(self):
"""Opens the github create issue page in the users default browser"""
url = QUrl(
"https://github.com/LCA-ActivityBrowser/activity-browser/issues/new/choose"
)
QtGui.QDesktopServices.openUrl(url)

@Slot(name="testBiosphereExists")
def biosphere_exists(self) -> None:
"""Test if the default biosphere exists as a database in the project"""
exists = True if bd.config.biosphere in bd.databases else False
self.update_biosphere_action.setEnabled(exists)
self.import_db_action.setEnabled(exists)


class ProjectsMenu(QtWidgets.QMenu):
class ProjectSelectionMenu(QtWidgets.QMenu):
"""
Menu that lists all the projects available through bw2data.projects
"""
Expand Down Expand Up @@ -180,6 +217,8 @@ def populate(self):


class MigrationsMenu(QtWidgets.QMenu):
"""Menu that shows actions that regard to brightway migrations"""

def __init__(self, parent=None) -> None:
super().__init__(parent)

Expand Down
Loading