From 2224f0958c651c0d74180c62da7b1f56e9f2a715 Mon Sep 17 00:00:00 2001 From: James Westman Date: Fri, 12 Nov 2021 16:50:35 -0600 Subject: [PATCH] Add Gtk.SizeGroup --- gtkblueprinttool/extensions/__init__.py | 9 +- gtkblueprinttool/extensions/gtk_size_group.py | 82 +++++++++++++++++++ tests/sample_errors/size_group_non_widget.blp | 9 ++ tests/sample_errors/size_group_non_widget.err | 1 + tests/sample_errors/size_group_obj_dne.blp | 7 ++ tests/sample_errors/size_group_obj_dne.err | 1 + tests/samples/size_group.blp | 9 ++ tests/samples/size_group.ui | 13 +++ tests/test_samples.py | 3 + 9 files changed, 130 insertions(+), 4 deletions(-) create mode 100644 gtkblueprinttool/extensions/gtk_size_group.py create mode 100644 tests/sample_errors/size_group_non_widget.blp create mode 100644 tests/sample_errors/size_group_non_widget.err create mode 100644 tests/sample_errors/size_group_obj_dne.blp create mode 100644 tests/sample_errors/size_group_obj_dne.err create mode 100644 tests/samples/size_group.blp create mode 100644 tests/samples/size_group.ui diff --git a/gtkblueprinttool/extensions/__init__.py b/gtkblueprinttool/extensions/__init__.py index 79988ca..47a1c18 100644 --- a/gtkblueprinttool/extensions/__init__.py +++ b/gtkblueprinttool/extensions/__init__.py @@ -2,11 +2,12 @@ templates. """ from .gtk_a11y import a11y -from .gtk_menu import menu -from .gtk_styles import styles -from .gtk_layout import layout from .gtk_file_filter import mime_types, patterns, suffixes +from .gtk_layout import layout +from .gtk_menu import menu +from .gtk_size_group import widgets +from .gtk_styles import styles OBJECT_HOOKS = [menu] -OBJECT_CONTENT_HOOKS = [a11y, styles, layout, mime_types, patterns, suffixes] +OBJECT_CONTENT_HOOKS = [a11y, styles, layout, mime_types, patterns, suffixes, widgets] diff --git a/gtkblueprinttool/extensions/gtk_size_group.py b/gtkblueprinttool/extensions/gtk_size_group.py new file mode 100644 index 0000000..7ce26b5 --- /dev/null +++ b/gtkblueprinttool/extensions/gtk_size_group.py @@ -0,0 +1,82 @@ +# gtk_size_group.py +# +# Copyright 2021 James Westman +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This file 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program. If not, see . +# +# SPDX-License-Identifier: LGPL-3.0-or-later + + +from .. import ast +from ..ast_utils import AstNode, validate +from ..completions_utils import * +from ..lsp_utils import Completion, CompletionItemKind +from ..parse_tree import * +from ..parser_utils import * +from ..xml_emitter import XmlEmitter + + +class Widgets(AstNode): + def emit_xml(self, xml: XmlEmitter): + xml.start_tag("widgets") + for child in self.children: + child.emit_xml(xml) + xml.end_tag() + + +class Widget(AstNode): + @validate("name") + def obj_widget(self): + object = self.root.objects_by_id.get(self.tokens["name"]) + type = self.root.gir.get_type("Widget", "Gtk") + if object is None: + raise CompileError( + f"Could not find object with ID {self.tokens['name']}", + did_you_mean=(self.tokens['name'], self.root.objects_by_id.keys()), + ) + elif object.gir_class and not object.gir_class.assignable_to(type): + raise CompileError( + f"Cannot assign {object.gir_class.full_name} to {type.full_name}" + ) + + def emit_xml(self, xml: XmlEmitter): + xml.put_self_closing("widget", name=self.tokens["name"]) + + +widgets = Group( + Widgets, + Statement( + Keyword("widgets"), + Op(":"), + OpenBracket(), + Delimited( + Group( + Widget, + UseIdent("name"), + ), + Comma(), + ), + CloseBracket(), + ) +) + + +@completer( + applies_in=[ast.ObjectContent], + matches=new_statement_patterns, +) +def file_filter_completer(ast_node, match_variables): + file_filter = ast_node.root.gir.get_type("SizeGroup", "Gtk") + if ast_node.gir_class and ast_node.gir_class.assignable_to(file_filter): + yield Completion("widgets", CompletionItemKind.Snippet, snippet="mime-types: [$0];") diff --git a/tests/sample_errors/size_group_non_widget.blp b/tests/sample_errors/size_group_non_widget.blp new file mode 100644 index 0000000..935a113 --- /dev/null +++ b/tests/sample_errors/size_group_non_widget.blp @@ -0,0 +1,9 @@ +using Gtk 4.0; +using GObject 2.0; + +SizeGroup { + mode: horizontal; + widgets: [object]; +} + +GObject.Object object {} diff --git a/tests/sample_errors/size_group_non_widget.err b/tests/sample_errors/size_group_non_widget.err new file mode 100644 index 0000000..872f533 --- /dev/null +++ b/tests/sample_errors/size_group_non_widget.err @@ -0,0 +1 @@ +6,13,6,Cannot assign GObject.Object to Gtk.Widget diff --git a/tests/sample_errors/size_group_obj_dne.blp b/tests/sample_errors/size_group_obj_dne.blp new file mode 100644 index 0000000..603e1b8 --- /dev/null +++ b/tests/sample_errors/size_group_obj_dne.blp @@ -0,0 +1,7 @@ +using Gtk 4.0; +using GObject 2.0; + +SizeGroup { + mode: horizontal; + widgets: [object]; +} diff --git a/tests/sample_errors/size_group_obj_dne.err b/tests/sample_errors/size_group_obj_dne.err new file mode 100644 index 0000000..8e64afd --- /dev/null +++ b/tests/sample_errors/size_group_obj_dne.err @@ -0,0 +1 @@ +6,13,6,Could not find object with ID object diff --git a/tests/samples/size_group.blp b/tests/samples/size_group.blp new file mode 100644 index 0000000..47dd56e --- /dev/null +++ b/tests/samples/size_group.blp @@ -0,0 +1,9 @@ +using Gtk 4.0; + +SizeGroup { + mode: horizontal; + widgets: [label, button]; +} + +Label label {} +Button button {} diff --git a/tests/samples/size_group.ui b/tests/samples/size_group.ui new file mode 100644 index 0000000..6d92edd --- /dev/null +++ b/tests/samples/size_group.ui @@ -0,0 +1,13 @@ + + + + + horizontal + + + + + + + + diff --git a/tests/test_samples.py b/tests/test_samples.py index 3db1406..d987584 100644 --- a/tests/test_samples.py +++ b/tests/test_samples.py @@ -103,6 +103,7 @@ class TestSamples(unittest.TestCase): self.assert_sample("object_prop") self.assert_sample("property") self.assert_sample("signal") + self.assert_sample("size_group") self.assert_sample("strings") self.assert_sample("style") self.assert_sample("template") @@ -125,5 +126,7 @@ class TestSamples(unittest.TestCase): self.assert_sample_error("obj_prop_type") self.assert_sample_error("property_dne") self.assert_sample_error("signal_dne") + self.assert_sample_error("size_group_non_widget") + self.assert_sample_error("size_group_obj_dne") self.assert_sample_error("two_templates") self.assert_sample_error("using_invalid_namespace")