scripts/reporter/testchooser.py

164 lines
5.9 KiB
Python

#!/usr/bin/python
import pathlib
from . import common
from gi.repository import GObject
from gi.repository import Gtk
from gi.repository import Gio
class Path(GObject.GObject):
def __init__(self, path):
GObject.GObject.__init__(self)
self.path = path
def __lt__(self, rhs): return self.path < rhs.path
def get_is_test_result(self):
return False not in [ f.is_file() for f in self.path.iterdir() ]
def get_name(self): return self.path.name
def get_model(self):
if not self.get_is_test_result():
return DirectoryModel(self.path)
class DirectoryModel(GObject.GObject, Gio.ListModel):
def __init__(self, path=None):
GObject.GObject.__init__(self)
self.children = [ ]
self.set_path(path)
def do_get_item_type(self): return GObject.TYPE_PYOBJECT
def do_get_n_items(self): return len(self.children)
def do_get_item(self, n): return self.children[n]
def set_path(self, path):
rm = len(self.children)
self.children.clear()
self.path = path if path and path.is_dir() else None
if self.path:
self.children = sorted([ Path(c) for c in path.iterdir() ])
self.emit("items-changed", 0, rm, len(self.children))
class DirectoryWindow(Gtk.ScrolledWindow):
def __init__(self, path=None, autoexpand=True):
Gtk.ScrolledWindow.__init__(self, vexpand=True,
hscrollbar_policy=Gtk.PolicyType.NEVER)
self.dirtree = Gtk.TreeListModel.new(root=DirectoryModel(path),
passthrough=False,
autoexpand=autoexpand,
create_func=self.create_func)
self.selection = Gtk.SingleSelection.new(self.dirtree)
self.selection.set_autoselect(False)
self.selection.set_can_unselect(True)
self.selection.connect("selection-changed", self.selection_changed)
self.factory = Gtk.SignalListItemFactory()
self.factory.connect("setup", self.on_setup)
self.factory.connect("bind", self.on_bind)
self.factory.connect("unbind", self.on_unbind)
self.factory.connect("teardown", self.on_teardown)
self.listview = Gtk.ListView.new(self.selection, self.factory)
self.set_child(self.listview)
def create_func(self, path):
return path.get_model()
def on_setup(self, factory, listitem):
listitem.set_child(Gtk.TreeExpander(child=Gtk.Label(xalign=0)))
def on_bind(self, factory, listitem):
treerow = listitem.get_item()
filepath = treerow.get_item()
expander = listitem.get_child()
expander.set_list_row(treerow)
expander.get_child().set_text(filepath.get_name())
listitem.set_selectable(filepath.get_is_test_result())
def on_unbind(self, factory, listitem):
expander = listitem.get_child()
expander.set_list_row(None)
expander.get_child().set_text("")
def on_teardown(self, factory, treeitem):
treeitem.set_child(None)
def set_directory(self, path):
self.dirtree.get_model().set_path(path)
def selection_changed(self, selection, position, n_items):
treeitem = self.selection.get_selected_item()
self.emit("test-selected", treeitem.get_item() if treeitem else None)
def select_none(self):
self.selection.unselect_item(self.selection.get_selected())
@GObject.Signal(arg_types=(Path,))
def test_selected(self, filepath): pass
class Calendar(Gtk.Calendar):
def __init__(self):
Gtk.Calendar.__init__(self, show_day_names=True)
self.connect("next-month", self.view_changed)
self.connect("next-year", self.view_changed)
self.connect("prev-month", self.view_changed)
self.connect("prev-year", self.view_changed)
common.SizeGroup.add_widget(self)
self.view_changed(self)
def get_month_directory(self):
date = self.get_date()
month = common.XFSTESTS_DATE / f"{date.get_year():04}" / f"{date.get_month():02}"
return month if month.is_dir() else None
def get_selected_day(self):
if month := self.get_month_directory():
day = month / f"{self.get_date().get_day_of_month():02}"
return day if day.is_dir() else None
def view_changed(self, calendar):
self.clear_marks()
if month := self.get_month_directory():
for day in month.iterdir():
self.mark_day(int(day.stem))
self.emit("day-selected")
class DatePage(Gtk.Box):
def __init__(self):
Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL, spacing=5)
self.calendar = Calendar()
self.dirwin = DirectoryWindow(self.calendar.get_selected_day())
self.append(self.calendar)
self.append(self.dirwin)
self.get_first_child().connect("day-selected", self.on_day_selected)
def on_day_selected(self, calendar):
self.dirwin.set_directory(self.calendar.get_selected_day())
def select_none(self):
self.dirwin.select_none()
class Stack(Gtk.Stack):
def __init__(self):
Gtk.Stack.__init__(self, transition_type=Gtk.StackTransitionType.OVER_LEFT_RIGHT)
self.date = DatePage()
self.tags = DirectoryWindow(common.XFSTESTS_TAGS, autoexpand=False)
self.add_titled(self.date, "Date", "Date")
self.add_titled(self.tags, "Tags", "Tags")
self.date.dirwin.connect("test-selected", self.on_test_selected)
self.tags.connect("test-selected", self.on_test_selected)
self.connect("notify::visible-child", self.on_page_changed)
def on_test_selected(self, widget, test):
self.emit("test-selected", test)
def on_page_changed(self, stack, param):
stack.get_visible_child().select_none()
self.emit("test-selected", None)
@GObject.Signal(arg_types=(Path,))
def test_selected(self, path): pass