From d531555fe3483fac7676aa634f3787e8eab9b67f Mon Sep 17 00:00:00 2001 From: Matthias Baumgartner Date: Wed, 25 Jan 2023 17:31:10 +0100 Subject: grouping --- .gitignore | 1 + tagit/actions/__init__.py | 10 +- tagit/actions/grouping.py | 65 ++++----- tagit/apps/port-config.yaml | 17 ++- tagit/assets/icons/scalable/grouping/add.svg | 147 +++++++++++++++++++++ tagit/assets/icons/scalable/grouping/create.svg | 135 +++++++++++++++++++ tagit/assets/icons/scalable/grouping/group.svg | 127 ++++++++++++++++++ tagit/assets/icons/scalable/grouping/remove.svg | 133 +++++++++++++++++++ tagit/assets/icons/scalable/grouping/represent.svg | 133 +++++++++++++++++++ tagit/assets/icons/scalable/grouping/ungroup.svg | 134 +++++++++++++++++++ 10 files changed, 861 insertions(+), 41 deletions(-) create mode 100644 tagit/assets/icons/scalable/grouping/add.svg create mode 100644 tagit/assets/icons/scalable/grouping/create.svg create mode 100644 tagit/assets/icons/scalable/grouping/group.svg create mode 100644 tagit/assets/icons/scalable/grouping/remove.svg create mode 100644 tagit/assets/icons/scalable/grouping/represent.svg create mode 100644 tagit/assets/icons/scalable/grouping/ungroup.svg diff --git a/.gitignore b/.gitignore index 5c8310a..084e82d 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,7 @@ tagit/external/setproperty/setproperty.cpython* # assets tagit/assets/icons/kivy/browser* tagit/assets/icons/kivy/filter* +tagit/assets/icons/kivy/grouping* tagit/assets/icons/kivy/misc* tagit/assets/icons/kivy/planes* tagit/assets/icons/kivy/search* diff --git a/tagit/actions/__init__.py b/tagit/actions/__init__.py index 6416a4b..7144e44 100644 --- a/tagit/actions/__init__.py +++ b/tagit/actions/__init__.py @@ -13,7 +13,7 @@ from tagit.utils.builder import BuilderBase # inner-module imports from . import browser from . import filter -#from . import grouping +from . import grouping from . import misc #from . import objects from . import planes @@ -67,10 +67,10 @@ class ActionBuilder(BuilderBase): #'SearchByAddressOnce': filter.SearchByAddressOnce, #'SearchmodeSwitch': filter.SearchmodeSwitch, ## grouping - #'CreateGroup': grouping.CreateGroup, - #'DissolveGroup': grouping.DissolveGroup, - #'AddToGroup': grouping.AddToGroup, - #'OpenGroup': grouping.OpenGroup, + 'CreateGroup': grouping.CreateGroup, + 'DissolveGroup': grouping.DissolveGroup, + 'AddToGroup': grouping.AddToGroup, + 'OpenGroup': grouping.OpenGroup, #'RepresentGroup': grouping.RepresentGroup, #'RemoveFromGroup': grouping.RemoveFromGroup, ## misc diff --git a/tagit/actions/grouping.py b/tagit/actions/grouping.py index eddaeb6..05c651e 100644 --- a/tagit/actions/grouping.py +++ b/tagit/actions/grouping.py @@ -15,14 +15,16 @@ import kivy.properties as kp # tagit imports from tagit import config, dialogues -#from tagit.parsing.search import ast # FIXME: mb/port -#from tagit.storage.broker import Representative # FIXME: mb/port +from tagit.utils import Frame, ns +from tagit.utils.bsfs import Namespace, ast, uuid from tagit.widgets import Binding -from tagit.utils import Frame # inner-module imports from .action import Action +# constants +GROUP_PREFIX = Namespace('http://example.com/me/group') + # exports __all__ = [] @@ -54,30 +56,30 @@ class CreateGroup(Action): if len(self.root.browser.selection) > 1: with self.root.browser as browser, \ self.root.session as session: - # create group - grp = Group.Create() + grp = session.storage.node(ns.bsfs.Group, GROUP_PREFIX[uuid.UUID()()]) if label is not None: - grp.label = label + grp.set(ns.bsg.label, label) # add items to group - ents = self.root.session.storage.entities(browser.unfold(browser.selection)) - ents.group += grp + ents = browser.unfold(browser.selection) + ents.set(ns.bse.group, grp) # select a random representative - grp.represented_by = random.choice(ents) + rep = random.choice(list(ents)) + grp.set(ns.bsg.represented_by, rep) # set selection and cursor to representative # the representative will become valid after the search was re-applied browser.selection.clear() - browser.selection.add(grp.represented_by) + browser.selection.add(rep) browser.cursor = rep # notification - logger.info(f'Grouped {len(items)} items') + logger.info(f'Grouped {len(ents)} items') # change event - session.dispatch('on_predicate_modified', 'group', items, {grp}) + session.dispatch('on_predicate_modified', ns.bse.group, ents, {grp}) # jump to cursor # needs to be done *after* the browser was updated @@ -96,13 +98,11 @@ class DissolveGroup(Action): self.root.session as session: cursor = browser.cursor if cursor is not None and cursor in browser.folds: - # remove tag from items - items = list(cursor.members()) - #ents = ... - #grp = ... - #ents.group -= grp - for obj in items: - obj.group -= [cursor.represents()] # FIXME + grp = browser.folds[cursor].group + ents = session.storage.get(ns.bsfs.Entity, + ast.filter.Any(ns.bse.group, ast.filter.Is(grp))) + #ents.remove(ns.bse.group, grp) # FIXME: mb/port + #grp.delete() # FIXME: mb/port # FIXME: fix cursor and selection # cursor: leave at item that was the representative @@ -110,10 +110,10 @@ class DissolveGroup(Action): browser.frame = Frame() # notification - logger.info(f'Ungrouped {len(items)} items') + logger.info(f'Ungrouped {len(ents)} items') # change event - session.dispatch('on_predicate_modified', 'group', items, {cursor.represents()}) + session.dispatch('on_predicate_modified', ns.bse.group, ents, {grp}) self.root.trigger('JumpToCursor') @@ -130,12 +130,14 @@ class AddToGroup(Action): self.root.session as session: cursor = browser.cursor if cursor is not None and cursor in browser.folds: - items = browser.unfold(browser.selection) - for obj in items: + grp = browser.folds[cursor].group + ents = browser.unfold(browser.selection) + + for obj in ents: if obj == cursor: # don't add group to itself continue - obj.group += [cursor.represents()] # FIXME: Not quite sure how to handle this + obj.set(ns.bse.group, gr) # all selected items will be folded, hence it becomes empty if cursor in browser.selection: @@ -144,7 +146,7 @@ class AddToGroup(Action): browser.selection.clear() # change event - session.dispatch('on_predicate_modified', 'group', items, {cursor.represents()}) + session.dispatch('on_predicate_modified', ns.bse.group, ents, {grp}) class OpenGroup(Action): @@ -155,11 +157,12 @@ class OpenGroup(Action): return Binding.check(evt, self.cfg('bindings', 'grouping', 'open')) def apply(self, cursor=None): - if cursor is None: - cursor = self.root.browser.cursor - if cursor is not None and cursor in self.root.browser.folds: - token = ast.Token('group', ast.SetInclude(cursor.represents())) - self.root.trigger('AddToken', token) + if cursor is None: + cursor = self.root.browser.cursor + elif cursor in self.root.browser.folds: + grp = self.root.browser.folds[cursor].group + self.root.trigger('AddToken', ast.filter.Any( + ns.bse.group, ast.filter.Is(grp))) class RepresentGroup(Action): @@ -170,6 +173,7 @@ class RepresentGroup(Action): return Binding.check(evt, self.cfg('bindings', 'grouping', 'represent')) def apply(self): + return # FIXME: mb/port with self.root.browser as browser, \ self.root.filter as filter, \ self.root.session as session: @@ -191,6 +195,7 @@ class RemoveFromGroup(Action): return Binding.check(evt, self.cfg('bindings', 'grouping', 'remove')) def apply(self): + return # FIXME: mb/port with self.root.browser as browser, \ self.root.filter as filter, \ self.root.session as session: diff --git a/tagit/apps/port-config.yaml b/tagit/apps/port-config.yaml index 33afbbd..6b0b06d 100644 --- a/tagit/apps/port-config.yaml +++ b/tagit/apps/port-config.yaml @@ -20,6 +20,9 @@ ui: standalone: plane: browsing keytriggers: + - CreateGroup + - DissolveGroup + - AddToGroup - MoveCursorUp - MoveCursorDown - MoveCursorLeft @@ -39,6 +42,8 @@ ui: - SelectRange - AddTag - EditTag + - OpenGroup + #- RepresentGroup - ShowHelp browser: maxcols: 8 @@ -50,8 +55,8 @@ ui: - AddToken - AddTag - EditTag - #- CreateGroup - #- DissolveGroup + - CreateGroup + - DissolveGroup - SelectAll - SelectNone - SelectInvert @@ -76,10 +81,10 @@ ui: # clipboard: # - ClipboardCopy # - ClipboardPaste - # grouping: - # - CreateGroup - # - DissolveGroup - # - AddToGroup + grouping: + - CreateGroup + - DissolveGroup + - AddToGroup # - RepresentGroup # - RemoveFromGroup # root: diff --git a/tagit/assets/icons/scalable/grouping/add.svg b/tagit/assets/icons/scalable/grouping/add.svg new file mode 100644 index 0000000..3069273 --- /dev/null +++ b/tagit/assets/icons/scalable/grouping/add.svg @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tagit/assets/icons/scalable/grouping/create.svg b/tagit/assets/icons/scalable/grouping/create.svg new file mode 100644 index 0000000..549f27e --- /dev/null +++ b/tagit/assets/icons/scalable/grouping/create.svg @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/tagit/assets/icons/scalable/grouping/group.svg b/tagit/assets/icons/scalable/grouping/group.svg new file mode 100644 index 0000000..975f413 --- /dev/null +++ b/tagit/assets/icons/scalable/grouping/group.svg @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tagit/assets/icons/scalable/grouping/remove.svg b/tagit/assets/icons/scalable/grouping/remove.svg new file mode 100644 index 0000000..ebf8ed9 --- /dev/null +++ b/tagit/assets/icons/scalable/grouping/remove.svg @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/tagit/assets/icons/scalable/grouping/represent.svg b/tagit/assets/icons/scalable/grouping/represent.svg new file mode 100644 index 0000000..c7b5850 --- /dev/null +++ b/tagit/assets/icons/scalable/grouping/represent.svg @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/tagit/assets/icons/scalable/grouping/ungroup.svg b/tagit/assets/icons/scalable/grouping/ungroup.svg new file mode 100644 index 0000000..0e656b7 --- /dev/null +++ b/tagit/assets/icons/scalable/grouping/ungroup.svg @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + -- cgit v1.2.3