gtk: Add a TagList listmodel
This includes a treemodel property that is intended to be set on a listview to show our tag tree. Signed-off-by: Anna Schumaker <anna@nowheycreamery.com>
This commit is contained in:
parent
ce2c36a0dd
commit
11941c3bd3
|
@ -267,3 +267,64 @@ class TestTagDeviceList(unittest.TestCase):
|
|||
then = now - datetime.timedelta(seconds=42)
|
||||
self.tag.add_run(2, "/dev/vda2", then)
|
||||
self.assertEqual(self.tag.get_earliest_run().runid, 2)
|
||||
|
||||
|
||||
class TestTagList(unittest.TestCase):
|
||||
"""Test case for our TagList ListModel."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
self.xfstestsdb = xfstestsdb.Command()
|
||||
with unittest.mock.patch("sys.stdout"):
|
||||
self.xfstestsdb.run(["new", "/dev/vda2"])
|
||||
self.xfstestsdb.run(["new", "/dev/vda1"])
|
||||
self.xfstestsdb.run(["new", "/dev/vda1"])
|
||||
self.xfstestsdb.run(["new", "/dev/vda3"])
|
||||
|
||||
self.xfstestsdb.run(["tag", "1", "mytag2"])
|
||||
self.xfstestsdb.run(["tag", "2", "mytag2"])
|
||||
self.xfstestsdb.run(["tag", "4", "mytag1"])
|
||||
|
||||
self.taglist = xfstestsdb.gtk.tree.TagList(self.xfstestsdb.sql)
|
||||
|
||||
def test_init(self):
|
||||
"""Test that the TagList was set up properly."""
|
||||
self.assertIsInstance(self.taglist, GObject.GObject)
|
||||
self.assertIsInstance(self.taglist, Gio.ListModel)
|
||||
|
||||
def test_get_item_type(self):
|
||||
"""Test the get_item_type() function."""
|
||||
self.assertEqual(self.taglist.get_item_type(),
|
||||
xfstestsdb.gtk.tree.TagDeviceList.__gtype__)
|
||||
|
||||
def test_get_n_items(self):
|
||||
"""Test the get_n_items() function."""
|
||||
self.assertEqual(self.taglist.get_n_items(), 2)
|
||||
self.assertEqual(self.taglist.n_items, 2)
|
||||
|
||||
def test_get_item(self):
|
||||
"""Test the get_item() function."""
|
||||
self.assertIsInstance(self.taglist.get_item(0),
|
||||
xfstestsdb.gtk.tree.TagDeviceList)
|
||||
self.assertIsInstance(self.taglist[0][0][0].timestamp,
|
||||
datetime.datetime)
|
||||
self.assertEqual(self.taglist.get_item(0).name, "mytag1")
|
||||
self.assertEqual(self.taglist.get_item(1).name, "mytag2")
|
||||
|
||||
def test_treemodel(self):
|
||||
"""Test the treemodel property."""
|
||||
self.assertIsInstance(self.taglist.treemodel, Gtk.TreeListModel)
|
||||
self.assertFalse(self.taglist.treemodel.props.passthrough)
|
||||
self.assertFalse(self.taglist.treemodel.props.autoexpand)
|
||||
|
||||
tree = self.taglist.treemodel
|
||||
self.assertEqual(tree[0].get_item().name, "mytag1")
|
||||
tree[0].set_expanded(True)
|
||||
self.assertEqual(tree[1].get_item().name, "/dev/vda3")
|
||||
tree[1].set_expanded(True)
|
||||
self.assertEqual(tree[2].get_item().runid, 4)
|
||||
|
||||
self.assertEqual(tree[3].get_item().name, "mytag2")
|
||||
tree[3].set_expanded(True)
|
||||
self.assertEqual(tree[4].get_item().name, "/dev/vda1")
|
||||
self.assertEqual(tree[5].get_item().name, "/dev/vda2")
|
||||
|
|
|
@ -180,3 +180,45 @@ class TagDeviceList(GObject.GObject, Gio.ListModel):
|
|||
"""Get the earliest run added to the tag."""
|
||||
runs = [d.get_earliest_run() for d in self.__devices]
|
||||
return min(runs, default=None)
|
||||
|
||||
|
||||
class TagList(GObject.GObject, Gio.ListModel):
|
||||
"""A list containing all tagged xfstests runs."""
|
||||
|
||||
n_items = GObject.Property(type=int)
|
||||
treemodel = GObject.Property(type=Gtk.TreeListModel)
|
||||
|
||||
def __init__(self, sql: sqlite.Connection) -> None:
|
||||
"""Initialize our TagList."""
|
||||
super().__init__()
|
||||
|
||||
tags = {}
|
||||
for row in sql("""SELECT DISTINCT runid, device, timestamp, tag
|
||||
FROM tagged_runs WHERE tag IS NOT NULL""").fetchall():
|
||||
if (tag := tags.get(row['tag'])) is None:
|
||||
tags[row['tag']] = tag = TagDeviceList(row['tag'])
|
||||
ts = datetime.datetime.fromisoformat(row['timestamp'])
|
||||
tag.add_run(row['runid'], row['device'], ts)
|
||||
|
||||
self.__items = sorted(tags.values())
|
||||
self.n_items = len(self.__items)
|
||||
self.treemodel = Gtk.TreeListModel.new(root=self, passthrough=False,
|
||||
autoexpand=False,
|
||||
create_func=self.__create_func)
|
||||
|
||||
def __create_func(self, item: GObject.GObject) -> Gio.ListModel:
|
||||
if isinstance(item, TagDeviceList | DeviceRunsList):
|
||||
return item
|
||||
return None
|
||||
|
||||
def do_get_item_type(self) -> GObject.GType:
|
||||
"""Get the type of objects in the list."""
|
||||
return TagDeviceList.__gtype__
|
||||
|
||||
def do_get_n_items(self) -> int:
|
||||
"""Get the number of items in the list."""
|
||||
return self.n_items
|
||||
|
||||
def do_get_item(self, n: int) -> TagDeviceList:
|
||||
"""Get a specific item in the list."""
|
||||
return self.__items[n]
|
||||
|
|
Loading…
Reference in New Issue