Skip to content

Commit

Permalink
Handle unprefixed applications.menu, show diagnostics on menu load fa…
Browse files Browse the repository at this point in the history
…ilure (#67)
  • Loading branch information
bluesabre committed Sep 17, 2021
1 parent f525b00 commit 9fd2ce7
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 61 deletions.
29 changes: 26 additions & 3 deletions menulibre/MenuEditor.py
Expand Up @@ -46,7 +46,20 @@

def get_default_menu():
"""Return the filename of the default application menu."""
return '%s%s' % (util.getDefaultMenuPrefix(), 'applications.menu')
prefixes = [
util.getDefaultMenuPrefix(),
''
]
user_basedir = util.getUserMenuPath()
for prefix in prefixes:
filename = '%s%s' % (prefix, 'applications.menu')
user_dir = os.path.join(user_basedir, filename)
if os.path.exists(user_dir):
return filename
system_dir = util.getSystemMenuPath(filename)
if system_dir:
return filename
return None


def load_fallback_icon(icon_size):
Expand Down Expand Up @@ -119,8 +132,10 @@ def get_treestore():
# Filename, exp, show
treestore = Gtk.TreeStore(str, str, str, int, Gio.Icon, str, str, bool,
bool)
menu = get_menus()[0]
return menu_to_treestore(treestore, None, menu)
menus = get_menus()
if not menus:
return None
return menu_to_treestore(treestore, None, menus[0])


def get_submenus(menu, tree_dir):
Expand Down Expand Up @@ -189,6 +204,8 @@ def get_submenus(menu, tree_dir):
def get_menus():
"""Get the menus from the MenuEditor"""
menu = MenuEditor()
if not menu.loaded:
return None
structure = []
toplevels = []
global menu_name
Expand Down Expand Up @@ -230,12 +247,16 @@ def getUserMenuXml(tree):
class MenuEditor(object):
"""MenuEditor class, adapted and minimized from Alacarte Menu Editor."""

loaded = False

def __init__(self, basename=None):
"""init"""

# Remember to keep menulibre-menu-validate's GMenu object creation
# in-sync with this code
basename = basename or get_default_menu()
if basename is None:
return

self.tree = GMenu.Tree.new(basename,
GMenu.TreeFlags.SHOW_EMPTY |
Expand All @@ -250,6 +271,8 @@ def __init__(self, basename=None):
logger.debug("Using menu: %s" % self.path)
self.loadDOM()

self.loaded = True

def loadDOM(self):
"""loadDOM"""
try:
Expand Down
35 changes: 35 additions & 0 deletions menulibre/MenulibreApplication.py
Expand Up @@ -281,6 +281,39 @@ def root_lockout(self):
dialog.run()
sys.exit(1)

def menu_load_failure(self):
primary = _("MenuLibre failed to load.")

docs_url = "https://github.com/bluesabre/menulibre/wiki/Frequently-Asked-Questions"

# Translators: This link goes to the online documentation with more
# information.
secondary = _("The default menu could not be found. Please see the "
"<a href='%s'>online documentation</a> "
"for more information.") % docs_url

secondary += "\n\n<big><b>%s</b></big>" % _("Diagnostics")

diagnostics = util.getMenuDiagnostics()
for k, v in diagnostics.items():
secondary += "\n<b>%s</b>: %s" % (k, v)

dialog = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR,
Gtk.ButtonsType.CLOSE, primary)
dialog.format_secondary_markup(secondary)

try:
box = dialog.get_children()[0]
box = box.get_children()[0]
box = box.get_children()[1]
label = box.get_children()[1]
label.set_selectable(True)
except AttributeError:
pass

dialog.run()
sys.exit(1)

def configure_application_window(self, builder, app):
"""Glade is currently unable to create a GtkApplicationWindow. This
function takes the GtkWindow from the UI file and reparents the
Expand Down Expand Up @@ -592,6 +625,8 @@ def configure_application_toolbar(self, builder):
def configure_application_treeview(self, builder):
"""Configure the menu-browsing GtkTreeView."""
self.treeview = MenulibreTreeview.Treeview(self, builder)
if not self.treeview.loaded:
self.menu_load_failure()
treeview = self.treeview.get_treeview()
treeview.set_search_entry(self.search_box)
self.search_box.connect('changed', self.on_app_search_changed,
Expand Down
11 changes: 10 additions & 1 deletion menulibre/MenulibreTreeview.py
Expand Up @@ -40,12 +40,17 @@ class Treeview(GObject.GObject):
(GObject.TYPE_BOOLEAN,)),
}

loaded = False

def __init__(self, parent, builder):
GObject.GObject.__init__(self)
self.parent = parent

# Configure Widgets
self._configure_treeview(builder)
if self._configure_treeview(builder):
self.loaded = True
else:
return
self._configure_toolbar(builder)

# Defaults
Expand All @@ -57,6 +62,8 @@ def _configure_treeview(self, builder):
"""Configure the TreeView widget."""
# Get the menu treestore.
treestore = MenuEditor.get_treestore()
if not treestore:
return False

self._treeview = builder.get_object('classic_view_treeview')

Expand Down Expand Up @@ -105,6 +112,8 @@ def _configure_treeview(self, builder):

self.menu_timeout_id = 0

return True

def _configure_toolbar(self, builder):
"""Configure the toolbar widget."""
self._toolbar = builder.get_object('browser_toolbar')
Expand Down
28 changes: 28 additions & 0 deletions menulibre/util.py
Expand Up @@ -207,6 +207,34 @@ def getDefaultMenuPrefix(): # noqa
return prefix


def getMenuDiagnostics():
diagnostics = {}
keys = [
"XDG_CURRENT_DESKTOP",
"XDG_MENU_PREFIX",
"DESKTOP_SESSION",
"KDE_SESSION_VERSION"
]
for k in keys:
diagnostics[k] = os.environ.get(k, "None")

menu_dirs = [
getUserMenuPath()
]
for path in GLib.get_system_config_dirs():
menu_dirs.append(os.path.join(path, 'menus'))
menus = []
for menu_dir in menu_dirs:
for filename in os.listdir(menu_dir):
if filename.endswith(".menu"):
menus.append(os.path.join(menu_dir, filename))
menus.sort()

diagnostics["MENUS"] = ", ".join(menus)

return diagnostics


def getItemPath(file_id):
"""Return the path to the system-installed .desktop file."""
for path in GLib.get_system_data_dirs():
Expand Down

0 comments on commit 9fd2ce7

Please sign in to comment.