Skip to content

Commit

Permalink
Rework About dialog
Browse files Browse the repository at this point in the history
This makes a few changes and additions:
- This adds a new dependency on libportal.
  It's used to detect if it's sandboxed.
- Various `GtkButton`s are added to provide
  external links.
- The Credits section has been reworked to
  prevent the about dialog from increasing.
- New System section was added to help users
  copy and paste system information for
  troubleshooting purposes.
- The about dialog is now a modal window.
  • Loading branch information
TheEvilSkeleton committed Apr 10, 2024
1 parent ce4bbf9 commit 51933c0
Show file tree
Hide file tree
Showing 8 changed files with 240 additions and 105 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
run: |
python -m pip install --upgrade pip
sudo apt-get update
sudo apt install -y meson gettext itstool libgirepository1.0-dev gir1.2-gtk-4.0 libgtksourceview-5-dev
sudo apt install -y meson gettext itstool libgirepository1.0-dev gir1.2-gtk-4.0 libgtksourceview-5-dev libportal-dev
pip install --user -e git+https://github.com/getting-things-gnome/liblarch.git#egg=liblarch
pip install --user pytest pycairo PyGObject caldav lxml
- name: Build and install GTG
Expand Down
1 change: 1 addition & 0 deletions GTG/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ def gi_version_requires():
gi.require_version('Gdk', '4.0')
gi.require_version('Gtk', '4.0')
gi.require_version('GtkSource', '5')
gi.require_version('Xdp', '1.0')
73 changes: 46 additions & 27 deletions GTG/core/info.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -30,41 +30,60 @@ from gettext import gettext as _
# These variables get used by main_window.py to set the About dialog's metadata.
# Translator credits are set dynamically in main_window.py, not hardcoded.
NAME = "Getting Things GNOME!"
AUTHORS = _("GTG contributors")
COPYRIGHT = _(f"Copyright © 2008-%d {AUTHORS}") \
% date.today().year
SHORT_DESCRIPTION = _("""A personal productivity tool for GNOME,
inspired by the GTD methodology.""") # A manual line break looks better in the About dialog.
URL = "https://wiki.gnome.org/Apps/GTG"
TRANSLATE_URL = "https://github.com/getting-things-gnome/gtg/"
CHAT_URL = "https://matrix.to/#/#gtg:gnome.org"
SOURCE_CODE_URL = "https://github.com/getting-things-gnome/gtg/"
OPENHUB_URL = "https://www.openhub.net/p/gtg/contributors"
REPORT_BUG_URL = "https://github.com/getting-things-gnome/gtg/issues/"
EMAIL = "[email protected]"
VERSION = '@VCS_TAG@'

AUTHORS_MAINTAINERS = """
• Diego Garcia Gangl
• Jean-François Fortin Tam
"""
AUTHORS_MAINTAINERS = [
"Diego Garcia Gangl",
"Jean-François Fortin Tam",
]

# Per-release stats generated as per the "release process and checklist.md" file.
# Including contributors with 2 or more commits.
# No need to add extra line breaks between commas, Python/GTK handles them.
# Don't indend lines inside a multi-line string, or it'll show in the About dialog.
AUTHORS_RELEASE_CONTRIBUTORS = """
• "Neui"
• Mohieddine Drissi
• "odoood"
• Diego Garcia Gangl
• Jean-François Fortin Tam
• Jacob Anderson
• Raidro Manchester
• Daniel Koć
• François Schmidts
• Sebastian Grabowski
• Fridolin Weisser
• Tommy Priest
• Laurent Combe
• Smitty
• Tiziana Sellitto
• "unsupported-transceiver"
"""
AUTHORS_RELEASE_CONTRIBUTORS = [
"Neui",
"Mohieddine Drissi",
"“odoood”",
"Diego Garcia Gangl",
"Jean-François Fortin Tam",
"Jacob Anderson",
"Raidro Manchester",
"Daniel Koć",
"François Schmidts",
"Sebastian Grabowski",
"Fridolin Weisser",
"Tommy Priest",
"Laurent Combe",
"Smitty",
"Tiziana Sellitto",
"“unsupported-transceiver”",
]

ARTISTS = [
"Diego Garcia Gangl (2021 logo)",
"Tobias Bernard (2021 logo)",
"Kalle Persson (2009 logo)",
"Bertrand Rousseau (UX)",
"Jean-François Fortin Tam (UX)"
]

DOCUMENTERS = [
"Danielle Vansia",
"Radina Matic",
"Jean-François Fortin Tam"
]

ARTISTS = ["Diego Garcia Gangl (2021 logo)", "Tobias Bernard (2021 logo)", "Kalle Persson (2009 logo)", "Bertrand Rousseau (UX)", "Jean-François Fortin Tam (UX)"]
AUTHORS_MAINTAINERS.sort()
AUTHORS_RELEASE_CONTRIBUTORS.sort()
ARTISTS.sort()
DOCUMENTERS = [ "Danielle Vansia", "Radina Matic", "Jean-François Fortin Tam"]
DOCUMENTERS.sort()
1 change: 1 addition & 0 deletions GTG/core/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ gtg_core_sources = [
'datastore.py',
'filters.py',
'sorters.py',
'system_info.py',
]

gtg_core_plugin_sources = [
Expand Down
117 changes: 117 additions & 0 deletions GTG/core/system_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# system_info.py: Collect system information
# Copyright (C) 2024 GTG Contributors
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.


from datetime import date
import gi
import os
import platform
import importlib

from GTG.core import info

from gi.repository import Gdk, Gtk, GObject, GLib, Xdp


class SystemInfo:
def get_system_info(self, report: bool = False) -> str:
"""
Get system information based on their
availability and installed version.
"""
self.report = report

sys_info = ""
sys_info += self.__format_info("GTG", info.VERSION)

if Xdp.Portal.running_under_flatpak():
sys_info += self.__format_info("Flatpak", self.__get_flatpak_version())
else:
sys_info += self.__format_info("Flatpak", "False")

sys_info += self.__format_info("Snap", Xdp.Portal.running_under_snap())
sys_info += self.__format_info("Display Name", Gdk.Display.get_default().get_name())
sys_info += self.__format_info("Desktop", os.environ.get("XDG_CURRENT_DESKTOP"))

sys_info += "\n"
sys_info += self.__format_info("lxml", self.__get_python_module("lxml"))
sys_info += self.__format_info("caldav", self.__get_python_module("caldav"))
sys_info += self.__format_info("liblarch", self.__get_python_module("liblarch"))
sys_info += self.__format_info("Cheetah3", self.__get_python_module("Cheetah"))
sys_info += self.__format_info("dbus-python", self.__get_python_module("dbus"))
sys_info += self.__format_info("pdflatex", self.__get_python_module("pdflatex"))
sys_info += self.__format_info("pypdftk", self.__get_python_module("pdftk"))

# Only display OS info when user isn't running as Flatpak/Snap
if not Xdp.Portal.running_under_sandbox():
sys_info += "\n"
sys_info += self.__format_info("OS", GLib.get_os_info("PRETTY_NAME"))

sys_info += self.__format_info(
"Python", f"{platform.python_implementation()} {platform.python_version()}"
)

sys_info += self.__format_info("GLib", self.__version_to_string(GLib.glib_version))
sys_info += self.__format_info("PyGLib", self.__version_to_string(GLib.pyglib_version))

sys_info += self.__format_info(
"PyGObject", self.__version_to_string(GObject.pygobject_version)
)

sys_info += self.__format_info("GTK", self.__version_to_string(self.__get_gtk_version()))

return sys_info


def __version_to_string(self, version: tuple) -> str:
"""
Convert version tuple (major, micro, minor)
version to string (major.micro.minor).
"""
return ".".join(map(str, version))


def __format_info(self, lib: str, getter) -> str:
"""
Pretty-format library and availability
"""
if self.report:
return f"**{lib}:** {getter}\n"
else:
return f"{lib}: {getter}\n"


def __get_flatpak_version(self) -> str:
"""Get Flatpak version."""
with open("/.flatpak-info") as flatpak_info:
for line in flatpak_info:
if line.startswith("flatpak-version"):
flatpak_version = line.split("=")[1].strip()
return flatpak_version


def __get_gtk_version(self) -> str:
"""Get GTK version."""
return (
Gtk.get_major_version(),
Gtk.get_micro_version(),
Gtk.get_minor_version(),
)


def __get_python_module(self, module: str) -> bool:
"""Check if Python module is installed."""
return bool(importlib.util.find_spec(module))
81 changes: 54 additions & 27 deletions GTG/gtk/browser/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@
from typing import Optional

from gi.repository import GObject, Gtk, Gdk, Gio, GLib
from webbrowser import open as openurl
from textwrap import dedent

from GTG.core import info
from GTG.core.system_info import SystemInfo
from GTG.backends.backend_signals import BackendSignals
from GTG.core.dirs import ICONS_DIR
from GTG.core.search import parse_search_query, InvalidQuery
Expand Down Expand Up @@ -319,51 +322,75 @@ def _init_about_dialog(self):
"""
Show the about dialog
"""
# These lines should be in info.py, but due to their dynamic nature
# there'd be no way to show them translated in Gtk's About dialog:

translated_copyright = _("Copyright © 2008-%d the GTG contributors.") \
% datetime.date.today().year

ohstats_url = '<a href="https://www.openhub.net/p/gtg/contributors">OpenHub</a>'
ghstats_url = \
'<a href="https://github.com/getting-things-gnome/gtg/graphs/contributors">GitHub</a>'

UNITED_AUTHORS_OF_GTGETTON = [
# GTK prefixes the first line with "Created by ",
# but we can't split the string because it would cause trouble for some languages.
_("GTG was made by many contributors around the world."),
_("The GTG project is maintained/administered by:"),
info.AUTHORS_MAINTAINERS,
_("This release was brought to you by the efforts of these people:"),
info.AUTHORS_RELEASE_CONTRIBUTORS,
_("Many others contributed to GTG over the years.\n" \
"You can see them on {OH_stats} and {GH_stats}.").format(
OH_stats=ohstats_url, GH_stats=ghstats_url),
"\n"]

# Create `GtkButton`s and add to size group
def create_uri_button(string=None, uri=None):
btn = Gtk.Button.new_with_mnemonic(string)
btn.connect("clicked", lambda _: openurl(uri))
btn.set_tooltip_text(uri)
size_group.add_widget(btn)
return btn

ohstats_url = f'<a href="{info.OPENHUB_URL}">OpenHub</a>'
ghstats_url = '<a href="https://github.com/getting-things-gnome/gtg/graphs/contributors">GitHub</a>'

UNITED_AUTHORS_OF_GTGETTON = dedent(
_(
"""\
Many others contributed to GTG over the years.
You can find them on {OH_stats} and {GH_stats}."""
).format(OH_stats=ohstats_url, GH_stats=ghstats_url)
)

self.about.set_transient_for(self)
self.about.set_modal(True)
self.about.set_program_name(info.NAME)
self.about.set_website(info.URL)
self.about.set_logo_icon_name(self.app.props.application_id)
self.about.set_website_label(_("GTG website"))
self.about.set_version(info.VERSION)

# This line translated in info.py works, as it has no strings replacements
self.about.set_comments(_(info.SHORT_DESCRIPTION))

self.about.set_copyright(translated_copyright)
self.about.set_copyright(info.COPYRIGHT)
self.about.set_license_type(Gtk.License.GPL_3_0)

self.about.set_authors(UNITED_AUTHORS_OF_GTGETTON)
self.about.set_authors([info.AUTHORS])
self.about.set_artists(info.ARTISTS)
self.about.set_documenters(info.DOCUMENTERS)

self.about.set_system_information(SystemInfo().get_system_info())

self.about.add_credit_section(
_("Maintained/Administered by"), info.AUTHORS_MAINTAINERS
)

authors = info.AUTHORS_RELEASE_CONTRIBUTORS
authors.append(UNITED_AUTHORS_OF_GTGETTON)

self.about.add_credit_section(
_("Contributed by"), info.AUTHORS_RELEASE_CONTRIBUTORS
)

# Translators for a particular language should put their names here.
# Please keep the width at 80 chars max, as GTK3's About dialog won't wrap text.
# Please keep the width at 80 chars max, as GTK4's About dialog won't wrap text.
# GtkAboutDialog will detect if “translator-credits” is untranslated and auto-hide the tab.
self.about.set_translator_credits(_("translator-credits"))

# Retrieve the `GtkBox` within GtkDialog,
# and create `GtkSizeGroup` to group buttons
about_box = self.about.get_first_child()
size_group = Gtk.SizeGroup.new(Gtk.SizeGroupMode.HORIZONTAL)

# Create new `GtkBox` to add button links
uri_box = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 6)
uri_box.set_halign(Gtk.Align.CENTER)
uri_box.append(create_uri_button(_("_Website"), info.URL))
uri_box.append(create_uri_button(_("_Dev Chatroom"), info.CHAT_URL))
uri_box.append(create_uri_button(_("_GitHub"), info.SOURCE_CODE_URL))

about_box.append(uri_box)


def _init_signal_connections(self):
"""
connects signals on UI elements
Expand Down
Loading

0 comments on commit 51933c0

Please sign in to comment.