summaryrefslogtreecommitdiffstats
path: root/src/designer/data/generate_ui
blob: 62a9a5de4121eacab15ed44e86048b0ab4b4ae38 (plain)
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
#!/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;
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');