QGIS/tools/qgis-qt3to4.pl
2012-10-06 13:32:08 +02:00

444 lines
9.9 KiB
Perl

#!/usr/bin/perl
###########################################################################
# qgis-qt3to4.pl
# ---------------------
# begin : August 2005
# copyright : (C) 2005 by Brendan Morley
# email : morb at ozemail dot com dot au
###########################################################################
# #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation; either version 2 of the License, or #
# (at your option) any later version. #
# #
###########################################################################
#
# WARNING: PROOF OF CONCEPT ONLY. DO NOT RUN UNLESS YOU KNOW WHAT YOU ARE DOING.
# REQUIRES QTDIR to be set!! [gsherman]
#
#
# This program will convert the given directory from Qt3 code
# to Qt4-with-Qt3Support code.
#
# Run this on a backup of your CVS working directory repository
# first, and don't commit any of the converted files!
# At least not until the QGIS developer community are ready to
# sever ties with the Qt3 libraries.
#
# Synopsis:
# This perl script will run the qt3to4 program included in the
# Qt4 distribution. Then it will do several more involved fixups
# that qt3to4 missed.
#
# It assumes that all .cpp and .h files in the directory are to
# be converted (sorry, Makefiles and *.pro files are ignored).
#
# $Id$
#
sub RunQt3to4
{
my($directory, $direntry) = @_;
if (-f ($directory.$direntry.".portinglog.txt"))
{
print "$directory$direntry was already processed by qt3to4.\n";
return;
}
# Copy old version for backup purposes
my($cmd) = "cp $directory$direntry $directory$direntry.qt3.old";
print "About to run '$cmd'\n";
`$cmd`;
my($cmd) = "$ENV{'QTDIR'}/bin/qt3to4 -alwaysOverwrite $directory$direntry";
print "About to run '$cmd'\n";
`$cmd`;
$cmd = "mv portinglog.txt ".$directory.$direntry.".portinglog.txt";
print "About to run '$cmd'\n";
`$cmd`;
}
sub Qt3to4File
{
my($filename) = @_;
print "Doing custom conversions to '$filename' ...\n";
open(CPP, $filename) || die "Can't open file $filename: $!";
my($cppqt4) = "";
while (<CPP>)
{
my($line) = $_;
# Start applying coding hacks:
# String substitutions:
# 1. Use of QStrings in std::ostream operator<< context
#
# Qt3:
# QString foo; foo.ascii();
#
# Qt4:
# QString foo; foo.toAscii().data();
# Restricted to filenames as we now use "local8Bit" in ostreams and it also breaks QKeyEvent's "ascii()"
if ($filename =~ /qgsrasterlayer\.cpp$/)
{
$line =~ s/ascii\(\)/toAscii\(\)\.data\(\)/g;
}
# 1a. Use of QStrings in std::ostream operator<< context
#
# Qt3:
# QString foo; foo.local8Bit();
#
# Qt4:
# QString foo; foo.toLocal8Bit().data();
$line =~ s/local8Bit\(\)/toLocal8Bit\(\)\.data\(\)/g;
# 2. Fix qt3to4's use of QImageIO to QPictureIO
#
# Qt3:
# #include <QImageIO>
# QImageIO::outputFormats().count();
#
# Qt4:
# #include <QPictureIO>
# QPictureIO::outputFormats().count();
$line =~ s/\#include \<QImageIO\>/\#include \<QPictureIO\>/;
$line =~ s/QImageIO\:\:/QPictureIO\:\:/g;
# 2.a. QImage scale
#
# Qt3:
# QImage foo;
# foo.scale(10,10);
#
# Qt4:
# QImage foo;
# foo.scaled(10,10);
# Commented out in favour of using Qt version ifdef
# since this broke QMatrix.scale()
#$line =~ s/\.scale\(/\.scaled\(/g;
# 3. Fix qt3to4's oversight of QCanvas to Q3Canvas
#
# Qt3:
# #include <qcanvas.h>
# class QgsComposerView: public QCanvasView
#
# Qt4:
# #include <Q3CanvasView>
# class QgsComposerView: public Q3CanvasView
$line =~ s/\#include \<qcanvas.h\>/\#include \<Q3CanvasView\>/;
$line =~ s/public QCanvasView/public Q3CanvasView/g;
# Menu substitutions:
# 4. Qt3 QPopupMenu vs. Qt4 QMenu
#
# Qt3:
# QPopupMenu *foo;
# foo->indexOf(a);
#
# Qt4:
# QMenu *foo;
# foo->actions().indexOf(a);
# for this one, use specific cases, not a general "indexOf" grep, as it may be too wide a net
# Commented out in favour of using Qt version ifdef
#$line =~ s/popupMenuFile\-\>indexOf/popupMenuFile\-\>actions\(\)\.indexOf/g;
# FileInfo substitutions:
# 5. Base Names
#
# Qt3:
# QFileInfo foo;
# foo.baseName(TRUE);
#
# Qt4:
# QFileInfo foo;
# foo.completeBaseName();
$line =~ s/baseName\(TRUE\)/completeBaseName\(\)/g;
# QIODevice substitutions:
# 5.a.a. end-of-line terminators
#
# Qt3:
# QFile foo;
# foo.open(IO_Translate);
#
# after qt3to4:
# QFile foo;
# foo.open(QIODevice::Translate);
#
# Qt4:
# QFile foo;
# foo.open(QIODevice::Text);
$line =~ s/QIODevice\:\:Translate/QIODevice\:\:Text/g;
# Widget substitutions:
# 5.a. StrongFocus
#
# Qt3:
# QWidget foo;
# foo.setFocusPolicy(QWidget::StrongFocus);
#
# Qt4:
# QWidget foo;
# foo.setFocusPolicy(Qt::StrongFocus);
$line =~ s/QWidget\:\:StrongFocus/Qt\:\:StrongFocus/g;
# QProgressDialog substitutions:
# 5.b. wasCancelled - now American spelling
#
# Qt3:
# QProgressDialog foo;
# if (foo.wasCancelled()) { ... ]
#
# Qt4:
# Q3ProgressDialog foo;
# if (foo.wasCanceled()) { ... ]
$line =~ s/\.wasCancelled\(\)/\.wasCanceled\(\)/g;
# Additional items for specific files
# 6. Add <QDesktopWidget> include to qgisapp.cpp AND splashscreen.cpp
if (
($filename =~ /qgisapp\.cpp$/) or
($filename =~ /splashscreen\.cpp$/)
)
{
if ($line =~ /Added by qt3to4\:/) # Good as place as any to add it
{
$line .= "#include <QDesktopWidget>\n";
}
}
# 6a. Add <QTextOStream> include to qgscoordinatetransform.cpp
if ($filename =~ /qgscoordinatetransform\.cpp$/)
{
if ($line =~ /Qt4-only includes to go here/) # Good as place as any to add it
{
$line .= "#include <QTextOStream>\n";
}
}
# 6b. Add <QStringList> include to qgsprojectproperty.cpp
if ($filename =~ /qgsprojectproperty\.cpp$/)
{
if ($line =~ /Qt4-only includes to go here/) # Good as place as any to add it
{
$line .= "#include <QStringList>\n";
}
}
# 7. Mop up overzealous color conversions by qt3to4 to qgscontinuouscolrenderer.cpp
# Qt::red -> red,
# Qt::green -> green,
# Qt::blue -> blue.
if ($filename =~ /qgscontinuouscolrenderer\.cpp$/)
{
$line =~ s/Qt\:\:red/red/g;
$line =~ s/Qt\:\:green/green/g;
$line =~ s/Qt\:\:blue/blue/g;
}
# End of substitutions
$cppqt4 .= $line;
}
close(CPP);
open(CPPQT4, ">$filename") || die "Can't create file $filename: $!";
print CPPQT4 $cppqt4;
close(CPPQT4);
}
sub Qt3to4UicFile
{
my($filename) = @_;
print "Doing custom UIC conversions to '$filename' ... ";
open(UIC, $filename) || die "Can't open file $filename: $!";
my($uicqt4) = "";
while (<UIC>)
{
my($line) = $_;
# Start applying coding hacks:
# String substitutions:
# 1. Remove "menubar->setFrameShape(QMenuBar::MenuBarPanel)"
next if ( $line =~ /menubar\-\>setFrameShape\(QMenuBar\:\:MenuBarPanel\)/ );
# 2. Remove "menubar->setFrameShadow(QMenuBar::Raised)"
next if ( $line =~ /menubar\-\>setFrameShadow\(QMenuBar\:\:Raised\)/ );
$uicqt4 .= $line;
}
close(UIC);
# Rename old version for backup purposes
my($cmd) = "mv $filename $filename.qt3.old";
print "About to run '$cmd'\n";
`$cmd`;
open(UICQT4, ">$filename") || die "Can't overwrite file $filename: $!";
print UICQT4 $uicqt4;
close(UICQT4);
print "Done.\n";
}
sub ProcessQt3to4
{
my($directory, $direntry) = @_;
&RunQt3to4($directory, $direntry);
&Qt3to4File($directory.$direntry);
}
sub ProcessQt3to4Uic
{
my($filename) = @_;
&Qt3to4UicFile($filename);
}
sub ParseDirectory
{
my($directory) = @_;
if (!$directory)
{
$directory = "./";
}
if ($directory !~ /\/$/) # no trailing slash
{
$directory .= "/"; # add slash
}
print "Opening $directory\n";
opendir(DIR, $directory) || die "Can't open directory $directory: $!";
my(@direntry) = ();
my($direntry);
while ($direntry = readdir(DIR))
{
push(@direntry, $direntry);
}
closedir(DIR);
foreach $direntry (@direntry)
{
print "Checking directory entry '$directory$direntry' ...\n";
if (-d $directory.$direntry)
{
# Is a directory, recurse if not ./ or ../
if (
($direntry ne ".") and
($direntry ne "..")
)
{
&ParseDirectory("$directory$direntry/");
}
}
if (-f $directory.$direntry)
{
if ($direntry !~ /\.(moc|uic)\./) # not moc or uic compiled files
{
if ($direntry =~ /.*\.cpp$/) # ends with ".cpp"
{
print " Found a .cpp file.\n";
&ProcessQt3to4($directory, $direntry);
}
if ($direntry =~ /.*\.h$/) # ends with ".h"
{
print " Found an .h file.\n";
&ProcessQt3to4($directory, $direntry);
}
}
}
}
}
# Check for QTDIR and exit if not set
if(length($ENV{'QTDIR'}) == 0){
print<<EOF
QTDIR must be set to the Qt 4 directory:
export QTDIR=/my/path/to/qt
You should also set the PATH to use the Qt 4 binaries:
PATH=\$QTDIR/bin:\$PATH
QTDIR not set -- exiting.
EOF
;
exit;
}
print "Starting $0...\n";
if ($ARGV[0] eq "-uic")
{
# .uic.h one-shot conversion mode
&Qt3to4UicFile($ARGV[1]);
}
else
{
# .cpp and .h bulk-conversion mode
&ParseDirectory($ARGV[0]);
}
print "$0 complete.\n";
#
# ENDS
#