diff options
-rwxr-xr-x | src/designer/data/generate_ui | 211 |
1 files changed, 91 insertions, 120 deletions
diff --git a/src/designer/data/generate_ui b/src/designer/data/generate_ui index 62a9a5de4..ba8a2c86b 100755 --- a/src/designer/data/generate_ui +++ b/src/designer/data/generate_ui @@ -1,125 +1,96 @@ -#!/usr/bin/perl -w -#################################################################################################### -# -# Helper script for Qt 5 -# -# Copyright (C) 2015 The Qt Company Ltd. -# Contact: http://www.qt.io/licensing/ -# -#################################################################################################### - -############################################################################################ -# -# Generates the source files ui4.cpp, ui4.h used in the uic tool, the QtUiTools library and -# Qt Designer from the XML schema used for .ui files. -# -############################################################################################ - -use strict; - -use File::Basename; -use File::Spec; -use File::Copy; -use IO::File; -use File::Path; -use File::Temp; - -my $USAGE=<<EOF; +#!/usr/bin/python3 + +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import subprocess + +from argparse import ArgumentParser, RawTextHelpFormatter +from pathlib import Path +from tempfile import NamedTemporaryFile + + +DESCRIPTION = """ Usage: generate_ui Generates the source files ui4.cpp, ui4.h used in the uic tool, the QtUiTools library and Qt Designer from the XML schema used for .ui files. -Requires the environment variable QTDIR to point to qtbase and xalan. -EOF - -my $qtDir = $ENV{'QTDIR'}; -die ('QTDIR not set') unless defined $qtDir && -d $qtDir; - -print 'Generating ui4.cpp/ui4.h ',$qtDir,"\n"; - -my $uicDir = File::Spec->catfile($qtDir, 'src', 'tools', 'uic'); -my $toolsDir = File::Spec->catfile($qtDir, '..', 'qttools'); -my $designerDir = File::Spec->catfile($toolsDir, 'src', 'designer'); -my $uiLibDir = File::Spec->catfile($designerDir, 'src', 'lib', 'uilib'); -my $xmlDir = File::Spec->catfile($designerDir, 'data'); - -print 'uic at: ',$uicDir, ' Designer at: ',$designerDir, ' uilib at: ',$uiLibDir,' XML at ',$xmlDir,"\n"; -die ('Invalid folder structure') unless -d $xmlDir && -d $uicDir && -d $uiLibDir; - -# Read out license delimited by '/** .. **/' from a C++ source -sub readCppLicense -{ - my ($fileName) = @_; - my $license = ''; - my $file = new IO::File('<' . $fileName) or die ('Unable to open ' . $fileName . ' for reading: ' . $!); - while (my $line = <$file>) { - $license .= $line; - last if index($line, 'SPDX-License-Identifier') >= 0; - } - $file->close(); - return $license; -} - -# Replace special keys in XSL files and return a handle to temporary file -sub replaceXslKeys -{ - my ($xslSourceFileName, $license, $uiHeaderName) = @_; - - my $xslSourceFile = new IO::File('<' . $xslSourceFileName) or die ('Unable to open ' . $xslSourceFileName . ' for reading: ' . $!); - my $xsl = ''; - while (my $line = <$xslSourceFile>) { - $xsl .= $line; - } - $xslSourceFile->close(); - $xsl =~ s/\@LICENSE\@/$license/g; - $xsl =~ s/\@HEADER\@/$uiHeaderName/g if defined $uiHeaderName; - - my $xslHandle = File::Temp->new(DIR => dirname($xslSourceFileName), SUFFIX => '.xsl'); - print $xslHandle $xsl; - $xslHandle->close(); - return $xslHandle; -} - -# Run xalan. Note: xmlpatterns currently reports a syntax error on the sheets -sub runXSLT -{ - my ($source, $sheet, $target) = @_; - my $rc = system('xalan', '-in', $source, '-xsl', $sheet, '-out', $target); -# my $rc = system($qtXmlPatterns, '-output', $target, $sheet, $source); - die ('Xalan failed on ' . $source . ' ' . $sheet) unless $rc == 0; -} - -# Generate uilib header and source. - -my $uiLibImpl = File::Spec->catfile($uiLibDir, 'ui4.cpp'); -my $uiLibHeader = File::Spec->catfile($uiLibDir, 'ui4_p.h'); -my $license = readCppLicense($uiLibImpl); - -print "Running XSLT processor for uilib header...\n"; - -my $ui4Xsd = File::Spec->catfile($xmlDir, 'ui4.xsd'); -my $headerXslSource = File::Spec->catfile($xmlDir, 'generate_header.xsl'); -my $headerXsl = replaceXslKeys($headerXslSource, $license); -runXSLT($ui4Xsd, $headerXsl->filename, $uiLibHeader); - -print "Running XSLT processor for uilib source...\n"; -my $implXslSource = File::Spec->catfile($xmlDir, 'generate_impl.xsl'); -my $implXsl = replaceXslKeys($implXslSource, $license, 'ui4_p.h'); -runXSLT($ui4Xsd, $implXsl->filename, $uiLibImpl); - -# uic: Header is called 'ui4.h' instead of 'ui4_p.h' - -my $uicImpl = File::Spec->catfile($uicDir, 'ui4.cpp'); -my $uicHeader = File::Spec->catfile($uicDir, 'ui4.h'); -$license = readCppLicense($uicImpl); - -print "Running XSLT processor for uic header...\n"; -$headerXsl = replaceXslKeys($headerXslSource, $license); -runXSLT($ui4Xsd, $headerXsl->filename, $uicHeader); - -print "Running XSLT processor for uic source...\n"; -$implXsl = replaceXslKeys($implXslSource, $license, 'ui4.h'); -runXSLT($ui4Xsd, $implXsl->filename, $uicImpl); - -system('git', 'diff'); +Requires xalan. +""" + + +opt_delete_temp_files = True + + +def read_cpp_license(path): + """Read out the license from a C++ source""" + result = "" + for line in path.read_text().splitlines(): + result += line + "\n" + if 'SPDX-License-Identifier' in line: + break + return result + + +def replace_xsl_keys(xsl_source_file, license, ui_header_name=None): + """Replace special keys in XSL files and return a handle to temporary file""" + xsl = xsl_source_file.read_text() + xsl = xsl.replace("@LICENSE@", license) + if ui_header_name: + xsl = xsl.replace("@HEADER@", ui_header_name) + + result = NamedTemporaryFile(mode='w', suffix='.xsl', + dir=Path.cwd(), + delete=opt_delete_temp_files) + result.write(xsl) + return result + + +def run_xslt(source, sheet, target): + """Run xalan.""" + cmd = ['xalan', '-in', os.fspath(source), '-xsl', os.fspath(sheet), + '-out', os.fspath(target)] + subprocess.check_call(cmd) + + +if __name__ == '__main__': + argument_parser = ArgumentParser(description=DESCRIPTION, + formatter_class=RawTextHelpFormatter) + argument_parser.add_argument('--keep', '-k', action='store_true', + help='Keep temporary files') + options = argument_parser.parse_args() + opt_delete_temp_files = not options.keep + + # Generate uilib header and source. + xml_dir = Path(__file__).parent.resolve() + ui4_xsd = xml_dir / 'ui4.xsd' + + designer_dir = xml_dir.parent + uilib_dir = designer_dir / "src" / "lib" / "uilib" + uilib_impl = uilib_dir / 'ui4.cpp' + license = read_cpp_license(uilib_impl) + + print("Running XSLT processor for uilib header...\n") + header_xsl_source = xml_dir / 'generate_header.xsl' + header_xsl = replace_xsl_keys(header_xsl_source, license) + run_xslt(ui4_xsd, header_xsl.name, uilib_dir / 'ui4_p.h') + + print("Running XSLT processor for uilib source...\n") + impl_xsl_source = xml_dir / 'generate_impl.xsl' + impl_xsl = replace_xsl_keys(impl_xsl_source, license, 'ui4_p.h') + run_xslt(ui4_xsd, impl_xsl.name, uilib_impl) + + # uic: Header is called 'ui4.h' instead of 'ui4_p.h' + uic_dir = designer_dir.parents[2] / "qtbase" / "src" / "tools" / "uic" + uic_impl = uic_dir / 'ui4.cpp' + license = read_cpp_license(uic_impl) + print("Running XSLT processor for uic header...\n") + header_xsl = replace_xsl_keys(header_xsl_source, license) + run_xslt(ui4_xsd, header_xsl.name, uic_dir / 'ui4.h') + print("Running XSLT processor for uic source...\n") + impl_xsl = replace_xsl_keys(impl_xsl_source, license, 'ui4.h') + run_xslt(ui4_xsd, impl_xsl.name, uic_impl) + + subprocess.call(['git', 'diff']) |