Skip to content

prettyuistrings.py

Thursday, 13 December 2007  |  jason harris

I posted this to k-c-d a couple days ago, but it generated zero response, so I thought I'd post it to the ol' blog in case any non k-c-d types might be interested.

Qt designer is, shall we say, quite verbose when it comes to encoding rich text. For example, if you put a couple of words in bold in a text field, this is what you get in your UI file:

You may now download optional data files to enhance KStars, such as Messier object images, or a more complete NGC/IC catalog. Press the Download Extra Data button to proceed.

You can also use this tool later, by selecting Download data from the File menu.

My goodness. Needless to say, that's not exactly easy for the translators to deal with, as Luciano Montanaro recently pointed out to me. As far as either of us knows, the remedy for this is currently to manually edit the ui files by hand. But I decided to try to automate it a bit, and came up with a python script that will detect all HTML blocks in your UI files and clean them up. For example, the above block looks like this after my script gets done with it:

You may now download optional data files to enhance KStars, such as Messier object images, or a more complete NGC/IC catalog. Press the Download Extra Data button to proceed.

You can also use this tool later, by selecting Download data from the File menu.

Better, no?

My idea was to try to get this added to kdesdk, so it can be run on UI files along with fixuifiles (or maybe the functionality in my script can simply be merged into fixuifiles). As written, it might be too fragile for use without human eyeballs checking the result...but maybe it's a good start.

Here is the script:

#!/usr/bin/env python
#
# prettyuistrings: If you use rich text in Qt designer, the
# html generated is difficult to read and filled with unneeded cruft.
# This script will simplify the html in all of your ui files.
#
# Just run "./prettyuifiles.py" in your topmost source directory, and it
# will recursively find all your *.ui files, and modify those which
# contain HTML.
#
# Warning: This code has only been lightly tested ("works for me"), and
# may not be bulletproof.
#
# Author: Jason Harris <kstars@30doradus.org>

import os, string, fnmatch

def main():
    for root, dirs, files in os.walk('.'):
        files = fnmatch.filter( files, "*.ui" )
        for f in files:
            fname = os.path.join( root, f )

            f = open( fname )
            sfile = f.read()
            f.close()
        
            #Skip UI files that don't contain HTML
            if sfile.find( "html>" ) <0:
                print fname+": Ok"
                continue
        
            #isolate the text inside each <string></string> tag
            #replace the text with a "pretty" version
            istring = sfile.find( "<string>" )
            iend = sfile.find( "</string>", istring )
            while istring >=0:
                
                sfile = sfile[:istring+8] + pretty( sfile[istring+8:iend] ) + sfile[iend:]
        
                istring = sfile.find( "<string>", istring+1 )
                iend = sfile.find( "</string>", istring )
        

            f = open( fname, 'w' )
            f.write( sfile )
            f.close()

            print fname+": Made pretty"


                
def pretty( s ):
    s = s.replace( "&lt;", "<" )
    s = s.replace( "&quot;", "\"" )

    if s.find( "<html>" ) < 0:
        return s

    r = "<html><head></head><body>"

    #Find each <p> tag
    ip = s.find( "<p" )
    istart = s.find( ">", ip ) + 1
    iend = s.find( "</p>", ip )
    while ip >= 0:
        pstring = s[istart:iend]

        r = r + "<p>" + pstring + "</p>"

        ip = s.find( "<p", ip + 1 )
        istart = s.find( ">", ip ) + 1
        iend = s.find( "</p>", ip )

    r = r + "</body></html>"

    return r

main()