1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
from copy import copy
import json
from os import path, makedirs
from AnyQt.QtGui import QImage, QPainter
from AnyQt.QtWidgets import QGraphicsScene, QApplication, QWidget, QGraphicsView, QHBoxLayout
from AnyQt.QtCore import QRectF, Qt, QTimer
# QWebEngineWidgets must be imported before QCoreApplication is created.
# It will fail with an import error if imported (first time) after.
import AnyQt.QtWebEngineWidgets # pylint: disable=unused-import
from orangecanvas.canvas.items import NodeItem
from orangecanvas.help import HelpManager
from orangecanvas.registry import WidgetRegistry
from Orange.canvas.config import Config as OConfig
class WidgetCatalog:
def __init__(self, output_dir, image_url_prefix):
self.output_dir = output_dir
self.image_url_prefix = image_url_prefix
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
QApplication.setAttribute(Qt.AA_ShareOpenGLContexts)
self.app = QApplication([])
print("Generating widget repository")
self.registry = self.__get_widget_registry()
print("Locating help files")
self.help_manager = HelpManager()
self.help_manager.set_registry(self.registry)
# Help manager needs QApplication running to get the urls
# of widget documentation. 5 seconds should be enough.
QTimer.singleShot(5000, self.app.quit)
self.app.exec()
self.__scene = QGraphicsScene()
self.__nodes = []
print("Ready to go")
def create(self):
print("Generating catalog")
try:
makedirs(path.join(self.output_dir, "icons"))
except FileExistsError:
pass
result = []
for category in self.registry.categories():
widgets = []
result.append((category.name, widgets))
for widget in category.widgets:
widgets.append({
"text": widget.name,
"doc": self.__get_help(widget),
"img": self.__get_icon(widget, category),
"keyword": widget.keywords,
})
with open(path.join(self.output_dir, "widgets.json"), 'wt') as f:
json.dump(result, f, indent=1)
print("Done")
@staticmethod
def __get_widget_registry():
widget_registry = WidgetRegistry()
widget_discovery = OConfig.widget_discovery(widget_registry)
widget_discovery.run(OConfig.widgets_entry_points())
# Fixup category.widgets list
for cat, widgets in widget_registry._categories_dict.values():
cat.widgets = widgets
return widget_registry
def __get_icon(self, widget, category=None):
# Set remove inputs/outputs so the "ears" are not drawn
widget = copy(widget)
widget.inputs = []
widget.outputs = []
w = IconWidget()
w.set_widget(widget, category)
w.show()
#self.app.processEvents()
filename = "icons/{}.png".format(widget.qualified_name)
w.render_as_png(path.join(self.output_dir, filename))
w.hide()
if self.image_url_prefix:
return self.image_url_prefix + filename
else:
return filename
def __get_help(self, widget):
query = dict(id=widget.qualified_name)
try:
return self.help_manager.search(query).url()
except KeyError:
return None
class IconWidget(QWidget):
def __init__(self):
super().__init__()
self.setLayout(QHBoxLayout())
self.layout().setContentsMargins(0, 0, 0, 0)
self.setFixedSize(50, 50)
view = QGraphicsView()
self.layout().addWidget(view)
self.scene = QGraphicsScene(view)
view.setScene(self.scene)
def set_widget(self, widget_description, category_description):
node = NodeItem(widget_description)
if category_description is not None:
node.setWidgetCategory(category_description)
self.scene.addItem(node)
def render_as_png(self, filename):
img = QImage(50, 50, QImage.Format_ARGB32)
img.fill(Qt.transparent)
painter = QPainter(img)
painter.setRenderHint(QPainter.Antialiasing, 1)
self.scene.render(painter, QRectF(0, 0, 50, 50), QRectF(-25, -25, 50, 50))
painter.end()
img.save(filename)
if __name__ == '__main__':
from optparse import OptionParser
parser = OptionParser(usage="usage: %prog --output <outputdir> [options]")
parser.add_option('--url-prefix', dest="prefix",
help="prefix to prepend to image urls")
parser.add_option('--output', dest="output",
help="path where widgets.json will be created")
options, args = parser.parse_args()
if not options.output:
parser.error("Please specify the output dir")
w = WidgetCatalog(output_dir=options.output, image_url_prefix=options.prefix)
w.create()
|