diff --git a/viewr/__init__.py b/viewr/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/viewr/__main__.py b/viewr/__main__.py new file mode 100644 index 0000000..e69de29 diff --git a/viewr/xdsample.py b/viewr/xdsample.py new file mode 100644 index 0000000..a1120a9 --- /dev/null +++ b/viewr/xdsample.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 +# +# Copyright 2008 Jose Fonseca +# +# This program 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 program 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 . +# + + +import operator +import re +import sys + +import gi + +gi.require_version("Gtk", "3.0") + +import xdot.ui +from gi.repository import Gio, Gtk + + +def __icon_button__(icon_name: str) -> Gtk.Button: + icon = Gio.ThemedIcon(name=icon_name) + image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON) + button = Gtk.Button() + button.add(image) + return button + + +class MyDotWindow(Gtk.Window): + def __init__(self): + super().__init__(title="Test") + self.set_border_width(10) + self.set_default_size(400, 200) + self.dot = xdot.ui.DotWidget() + + hb = Gtk.HeaderBar() + hb.set_show_close_button(True) + self.set_titlebar(hb) + + box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) + Gtk.StyleContext.add_class(box.get_style_context(), "linked") + button = __icon_button__("zoom-in") + button.connect("clicked", self.dot.on_zoom_in) + box.add(button) + button = __icon_button__("zoom-out") + button.connect("clicked", self.dot.on_zoom_out) + box.add(button) + box.add(Gtk.SeparatorToolItem()) + button = __icon_button__("zoom-fit-best") + button.connect("clicked", self.dot.on_zoom_fit) + box.add(button) + button = __icon_button__("zoom-original") + button.connect("clicked", self.dot.on_zoom_100) + box.add(button) + + hb.pack_start(box) + + box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) + Gtk.StyleContext.add_class(box.get_style_context(), "linked") + self.search_entry = Gtk.Entry() + self.search_entry.connect("activate", self.search) + self.search_entry.connect("changed", self.search) + self.search_entry.set_placeholder_text("Search...") + + box.add(self.search_entry) + button = __icon_button__("find") + button.connect("clicked", self.search) + box.add(button) + + hb.pack_end(box) + + self.add(self.dot) + + self.set_focus(self.dot) + + def set_dotcode(self, code): + self.dot.set_dotcode(code) + + def find_text(self, entry_text): + found_items = [] + dot_widget = self.dot + try: + regexp = re.compile(entry_text) + except re.error as err: + sys.stderr.write('warning: re.compile() failed with error "%s"\n' % err) + return [] + for element in ( + dot_widget.graph.nodes + dot_widget.graph.edges + dot_widget.graph.shapes + ): + if element.search_text(regexp): + found_items.append(element) + return sorted(found_items, key=operator.methodcaller("get_text")) + + def search(self, _): + txt = self.search_entry.get_text() + if txt: + items = self.find_text(txt) + self.dot.set_highlight(items, search=True) + else: + self.dot.set_highlight(None, search=True) + + +dotcode = b""" +digraph G { + Hello [URL="http://en.wikipedia.org/wiki/Hello"] + World [URL="http://en.wikipedia.org/wiki/World"] + Hello -> World +} +""" + + +def main(): + window = MyDotWindow() + window.set_dotcode(dotcode) + window.connect("delete-event", Gtk.main_quit) + window.show_all() + Gtk.main() + + +if __name__ == "__main__": + main()