sort menu items

This commit is contained in:
2021-11-27 09:42:25 +01:00
parent 5c08dc4a5a
commit 6bacfc065b
5 changed files with 95 additions and 7 deletions

View File

@@ -11,7 +11,7 @@ import urlutils
from aboutdialog import AboutDialog from aboutdialog import AboutDialog
from cutesettings import CuteSettings from cutesettings import CuteSettings
from raven.pluginregistry import PluginRegistry from raven.pluginregistry import PluginRegistry
from raven.plugins.domain.menucontribution import MenuContribution from raven.plugins.domain.menucontribution import MenuContribution, sort_menu_contributions
from raven.plugins.domain.raction import RAction from raven.plugins.domain.raction import RAction
from raven.plugins.domain.rmenu import RMenu from raven.plugins.domain.rmenu import RMenu
from settingsstore import SettingsStore from settingsstore import SettingsStore
@@ -62,6 +62,8 @@ class MainWindow(QMainWindow):
menu_contributions.append(MenuContribution("settings", action=self._action_highlight_search_terms())) menu_contributions.append(MenuContribution("settings", action=self._action_highlight_search_terms()))
menu_contributions.append(MenuContribution("settings", action=self._action_new_tab())) menu_contributions.append(MenuContribution("settings", action=self._action_new_tab()))
menu_contributions = sort_menu_contributions(menu_contributions)
known_menus = [ known_menus = [
("file", self.tr("&File")), ("file", self.tr("&File")),
("settings", self.tr("&Settings")), ("settings", self.tr("&Settings")),

View File

@@ -1,11 +1,51 @@
from raven.plugins.domain.raction import RAction from raven.plugins.domain.raction import RAction
from raven.plugins.domain.rmenu import RMenu from raven.plugins.domain.rmenu import RMenu
id_counter = 0
def next_id() -> str:
global id_counter
id_counter = id_counter + 1
return "action_%d" % id_counter
class MenuContribution(): class MenuContribution():
def __init__(self, menu_id: str, action: RAction = None, menu: RMenu = None, action_id=None): def __init__(self,
menu_id: str,
action: RAction = None,
menu: RMenu = None,
action_id=None,
after=None):
super(MenuContribution, self).__init__() super(MenuContribution, self).__init__()
self.menu_id = menu_id self.menu_id = menu_id
self.action = action self.action = action
self.menu = menu self.menu = menu
self.action_id = action_id self.action_id = action_id if action_id else next_id()
self.after = after
def _sort_by_action_id(menu_contributions: [MenuContribution]) -> [MenuContribution]:
return sorted(menu_contributions, key=lambda mc: mc.action_id)
def sort_menu_contributions(menu_contributions: [MenuContribution]) -> [MenuContribution]:
result = []
items = _sort_by_action_id(menu_contributions[:])
_recursive_half_order_adder(result, items, None)
# add remaining items to the end (ordered by their action_id)
# This resolves cycles.
for item in items:
result.append(item)
return result
def _recursive_half_order_adder(result: [MenuContribution], items: [MenuContribution], parent):
for item in items:
mc: MenuContribution = item
if not mc.after:
result.append(mc)
items.remove(mc)
_recursive_half_order_adder(result, items, mc.action_id)

View File

@@ -0,0 +1,45 @@
import unittest
from random import shuffle
from raven.plugins.domain.menucontribution import MenuContribution, sort_menu_contributions
class MyTestCase(unittest.TestCase):
def test_sort(self):
items = [
MenuContribution("menuId", action_id="a", after=None),
MenuContribution("menuId", action_id="b", after="a"),
MenuContribution("menuId", action_id="c", after="a"),
MenuContribution("menuId", action_id="d", after="b"),
MenuContribution("menuId", action_id="e", after="d"),
]
shuffle(items)
actual = sort_menu_contributions(items)
ordered_ids = ""
for a in actual:
ordered_ids = ordered_ids + a.action_id
self.assertEqual("abcde", ordered_ids)
def test_sort_with_cycle(self):
"""
There is a cycle between a and b. This is resolved, because neither is set in the recursive
part of the method. After the recursive part the remaining items are added in order of
their action_id.
:return:
"""
items = [
MenuContribution("menuId", action_id="a", after="b"),
MenuContribution("menuId", action_id="b", after="a"),
]
shuffle(items)
actual = sort_menu_contributions(items)
ordered_ids = ""
for a in actual:
ordered_ids = ordered_ids + a.action_id
self.assertEqual("ab", ordered_ids)
if __name__ == '__main__':
unittest.main()

View File

@@ -15,7 +15,8 @@ from settings import Settings
class OpenFilePlugin(PluginBase): class OpenFilePlugin(PluginBase):
def __init__(self): def __init__(self):
super(OpenFilePlugin, self).__init__() super(OpenFilePlugin, self).__init__()
print("init OpenFilePlugin") self.settings = None
self.tr = None
def set_settings(self, settings: Settings): def set_settings(self, settings: Settings):
self.settings = settings self.settings = settings
@@ -24,7 +25,7 @@ class OpenFilePlugin(PluginBase):
self.tr = tr self.tr = tr
def _action_open_file(self) -> RAction: def _action_open_file(self) -> RAction:
open_file = RAction(self.tr("&Open..."), self._open_file_dialog, shortcut='Ctrl+O', open_file = RAction("&Open...", self._open_file_dialog, shortcut='Ctrl+O',
icon_from_theme="document-open") icon_from_theme="document-open")
return open_file return open_file

View File

@@ -22,8 +22,8 @@ class RavenLogPlugin(PluginBase):
def get_menu_contributions(self) -> [MenuContribution]: def get_menu_contributions(self) -> [MenuContribution]:
return [ return [
MenuContribution("file", action=self._action_close(), action_id="close application"), MenuContribution("file", action=self._action_close(), action_id="close application", after="<last>"),
MenuContribution("help", action=self._action_about(), action_id="open about dialog"), MenuContribution("help", action=self._action_about(), action_id="open about dialog", after="<last>"),
] ]
def current_file(self) -> Optional[str]: def current_file(self) -> Optional[str]: