summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryangfl <yangfl@users.noreply.github.com>2018-04-29 20:08:55 +0800
committerChristoph Reiter <reiter.christoph@gmail.com>2018-05-03 13:20:36 +0000
commitd0b219ca50b52fe219ceb90e80eca833fbba05ab (patch)
treee38876977910239ff4cf99d77477d662e00cee1f
parentdceb3e339149f0bc7e9f004632a6a24f38ca60ad (diff)
downloadpygobject-d0b219ca50b52fe219ceb90e80eca833fbba05ab.tar.gz
Add ActionMap and ActionMap.add_action_entries() to overrides. Fixes #29
Adds ActionMap and ActionMap.add_action_entries() to allow for adding multiple actions as a list of tuples in which each element defines a single action like the GActionEntry C struct. https://bugzilla.gnome.org/show_bug.cgi?id=678655 Original Author: Micah Carrick <micah@quixotix.com>
-rw-r--r--gi/overrides/Gio.py78
-rw-r--r--tests/test_overrides_gio.py34
2 files changed, 112 insertions, 0 deletions
diff --git a/gi/overrides/Gio.py b/gi/overrides/Gio.py
index f3c26b8d..b282c2aa 100644
--- a/gi/overrides/Gio.py
+++ b/gi/overrides/Gio.py
@@ -64,6 +64,84 @@ VolumeMonitor = override(VolumeMonitor)
__all__.append('VolumeMonitor')
+class ActionMap(Gio.ActionMap):
+ def add_action_entries(self, entries, user_data=None):
+ """
+ The add_action_entries() method is a convenience function for creating
+ multiple Gio.SimpleAction instances and adding them to a Gio.ActionMap.
+ Each action is constructed as per one entry.
+
+ :param list entries:
+ List of entry tuples for add_action() method. The entry tuple can
+ vary in size with the following information:
+
+ * The name of the action. Must be specified.
+ * The callback to connect to the "activate" signal of the
+ action. Since GLib 2.40, this can be None for stateful
+ actions, in which case the default handler is used. For
+ boolean-stated actions with no parameter, this is a toggle.
+ For other state types (and parameter type equal to the state
+ type) this will be a function that just calls change_state
+ (which you should provide).
+ * The type of the parameter that must be passed to the activate
+ function for this action, given as a single GLib.Variant type
+ string (or None for no parameter)
+ * The initial state for this action, given in GLib.Variant text
+ format. The state is parsed with no extra type information, so
+ type tags must be added to the string if they are necessary.
+ Stateless actions should give None here.
+ * The callback to connect to the "change-state" signal of the
+ action. All stateful actions should provide a handler here;
+ stateless actions should not.
+
+ :param user_data:
+ The user data for signal connections, or None
+ """
+ try:
+ iter(entries)
+ except (TypeError):
+ raise TypeError('entries must be iterable')
+
+ def _process_action(name, activate=None, parameter_type=None,
+ state=None, change_state=None):
+ if parameter_type:
+ if not GLib.VariantType.string_is_valid(parameter_type):
+ raise TypeError("The type string '%s' given as the "
+ "parameter type for action '%s' is "
+ "not a valid GVariant type string. " %
+ (parameter_type, name))
+ variant_parameter = GLib.VariantType.new(parameter_type)
+ else:
+ variant_parameter = None
+
+ if state is not None:
+ # stateful action
+ variant_state = GLib.Variant.parse(None, state, None, None)
+ action = Gio.SimpleAction.new_stateful(name, variant_parameter,
+ variant_state)
+ if change_state is not None:
+ action.connect('change-state', change_state, user_data)
+ else:
+ # stateless action
+ if change_state is not None:
+ raise ValueError("Stateless action '%s' should give "
+ "None for 'change_state', not '%s'." %
+ (name, change_state))
+ action = Gio.SimpleAction(name=name, parameter_type=variant_parameter)
+
+ if activate is not None:
+ action.connect('activate', activate, user_data)
+ self.add_action(action)
+
+ for entry in entries:
+ # using inner function above since entries can leave out optional arguments
+ _process_action(*entry)
+
+
+ActionMap = override(ActionMap)
+__all__.append('ActionMap')
+
+
class FileEnumerator(Gio.FileEnumerator):
def __iter__(self):
return self
diff --git a/tests/test_overrides_gio.py b/tests/test_overrides_gio.py
index 79f3085c..b6516f9b 100644
--- a/tests/test_overrides_gio.py
+++ b/tests/test_overrides_gio.py
@@ -310,3 +310,37 @@ def test_list_store_setitem_slice():
with pytest.raises(TypeError):
store[:] = [Item(), object()]
assert len(store) == 0
+
+
+def test_action_map_add_action_entries():
+ actionmap = Gio.SimpleActionGroup()
+
+ test_data = []
+
+ def f(action, parameter, data):
+ test_data.append('test back')
+
+ actionmap.add_action_entries((
+ ("simple", f),
+ ("with_type", f, "i"),
+ ("with_state", f, "s", "'left'", f),
+ ))
+ assert actionmap.has_action("simple")
+ assert actionmap.has_action("with_type")
+ assert actionmap.has_action("with_state")
+ actionmap.add_action_entries((
+ ("with_user_data", f),
+ ), "user_data")
+ assert actionmap.has_action("with_user_data")
+
+ with pytest.raises(TypeError):
+ actionmap.add_action_entries((
+ ("invaild_type_string", f, 'asdf'),
+ ))
+ with pytest.raises(ValueError):
+ actionmap.add_action_entries((
+ ("stateless_with_change_state", f, None, None, f),
+ ))
+
+ actionmap.activate_action("simple")
+ assert test_data[0] == 'test back'