diff --git a/qt/aqt/forms/BUILD.bazel b/qt/aqt/forms/BUILD.bazel index aedbaf453..327352f92 100644 --- a/qt/aqt/forms/BUILD.bazel +++ b/qt/aqt/forms/BUILD.bazel @@ -2,31 +2,16 @@ load("@rules_python//python:defs.bzl", "py_binary") load("compile.bzl", "compile_all") py_binary( - name = "build_ui_qt5", - srcs = ["build_ui_qt5.py"], - legacy_create_init = False, - deps = ["@pyqt5//:pkg"], -) - -py_binary( - name = "build_ui_qt6", - srcs = ["build_ui_qt6.py"], + name = "build_ui", + srcs = ["build_ui.py"], legacy_create_init = False, deps = ["@pyqt6//:pkg"], ) compile_all( - name = "forms_qt5", + name = "generated_forms", srcs = glob(["*.ui"]), - builder = "build_ui_qt5", - suffix = "_qt5", -) - -compile_all( - name = "forms_qt6", - srcs = glob(["*.ui"]), - builder = "build_ui_qt6", - suffix = "_qt6", + builder = "build_ui", ) filegroup( @@ -39,8 +24,7 @@ filegroup( "build_ui*.py", ], ) + [ - ":forms_qt6", - ":forms_qt5", + ":generated_forms", ], visibility = [ "//qt/aqt:__pkg__", diff --git a/qt/aqt/forms/build_ui.py b/qt/aqt/forms/build_ui.py new file mode 100644 index 000000000..357584e3c --- /dev/null +++ b/qt/aqt/forms/build_ui.py @@ -0,0 +1,55 @@ +import re +import sys +import io +from PyQt6.uic import compileUi + +def compile(ui_file: str) -> str: + buf = io.StringIO() + compileUi(open(ui_file), buf) + return buf.getvalue() + +def with_fixes_for_qt6(code: str) -> str: + code = code.replace( + "from PyQt6 import QtCore, QtGui, QtWidgets", + "from PyQt6 import QtCore, QtGui, QtWidgets\nfrom aqt.utils import tr\n" + ) + code = re.sub( + r'(?:QtGui\.QApplication\.)?_?translate\(".*?", "(.*?)"', "tr.\\1(", code + ) + outlines = [] + qt_bad_types = [ + ".connect(", + ] + for line in code.splitlines(): + for substr in qt_bad_types: + if substr in line: + line = line + " # type: ignore" + break + if line == "from . import icons_rc": + continue + line = line.replace(":/icons/", "icons:") + line = line.replace("QAction.PreferencesRole", "QAction.MenuRole.PreferencesRole") + line = line.replace("QAction.AboutRole", "QAction.MenuRole.AboutRole") + line = line.replace("QComboBox.AdjustToMinimumContentsLength", "QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLength") + outlines.append(line) + return "\n".join(outlines) + +def with_fixes_for_qt5(code: str) -> str: + code = code.replace("Qt6", "Qt5") + code = code.replace("QtGui.QAction", "QtWidgets.QAction") + return code + +if __name__ == "__main__": + ui_file = sys.argv[1] + py5_file = sys.argv[2] + py6_file = sys.argv[3] + + stock = compile(ui_file) + for_qt6 = with_fixes_for_qt6(stock) + for_qt5 = with_fixes_for_qt5(for_qt6) + + with open(py5_file, "w") as file: + file.write(for_qt5) + + with open(py6_file, "w") as file: + file.write(for_qt6) diff --git a/qt/aqt/forms/compile.bzl b/qt/aqt/forms/compile.bzl index 4b6751c0f..3ceedcc93 100644 --- a/qt/aqt/forms/compile.bzl +++ b/qt/aqt/forms/compile.bzl @@ -1,12 +1,13 @@ -def compile(name, ui_file, py_file, builder): +def compile(name, ui_file, qt5_file, qt6_file, builder): native.genrule( name = name, srcs = [ui_file], - outs = [py_file], - cmd = "$(location {builder}) $(location {ui_file}) $(location {py_file})".format( + outs = [qt5_file, qt6_file], + cmd = "$(location {builder}) $(location {ui_file}) $(location {qt5_file}) $(location {qt6_file})".format( builder = builder, ui_file = ui_file, - py_file = py_file, + qt5_file = qt5_file, + qt6_file = qt6_file, ), tools = [ builder, @@ -14,13 +15,14 @@ def compile(name, ui_file, py_file, builder): message = "Building UI", ) -def compile_all(name, builder, srcs, suffix): +def compile_all(name, builder, srcs): py_files = [] for ui_file in srcs: - fname = ui_file.replace(".ui", "") + suffix - py_file = fname + ".py" - py_files.append(py_file) - compile(fname, ui_file, py_file, builder) + base = ui_file.replace(".ui", "") + qt5_file = base + "_qt5.py" + qt6_file = base + "_qt6.py" + py_files.extend([qt5_file, qt6_file]) + compile(base, ui_file, qt5_file, qt6_file, builder) native.filegroup( name = name,