]> SALOME platform Git repositories - tools/install.git/commitdiff
Salome HOME
Merge improvements from SALOME_3 branch
authorvsr <vsr@opencascade.com>
Tue, 10 Jan 2006 15:41:18 +0000 (15:41 +0000)
committervsr <vsr@opencascade.com>
Tue, 10 Jan 2006 15:41:18 +0000 (15:41 +0000)
12 files changed:
bin/SALOME_InstallWizard
bin/extract_params.py [deleted file]
config.xml
config_Debian_3.1.xml
config_files/Numeric-23.7.sh
config_files/build.csh
config_files/common.sh
runInstall
src/SALOME_InstallWizard.cxx
src/SALOME_InstallWizard.hxx
src/globals.h
src/main.cxx

index 08dae42cbd455057a4fba23fafebe666bd4e7a42..dba449bf19f9266ff0fa1d25cbb1ed2fde09a840 100755 (executable)
Binary files a/bin/SALOME_InstallWizard and b/bin/SALOME_InstallWizard differ
diff --git a/bin/extract_params.py b/bin/extract_params.py
deleted file mode 100644 (file)
index cc988dd..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-#==============================================================
-#
-#==============================================================
-def get_help_info() :
-    return "\tUsage : \n\tpython install.py [-gui|tui] [-f <xmlfile>] [-t taget_dir] [-tmp tmp_dir]\n"
-
-#==============================================================
-#
-#==============================================================
-def error_exit (str = ""):
-    import sys
-    if len(str): res = "\n" + str + "\n"
-    else : res = ""
-    print res + \
-          get_help_info() + \
-          "\nWrong parameters\n\n";
-    sys.exit(1);
-
-
-#==============================================================
-# Cheks whether the passed parameter is a key.
-#==============================================================
-def is_key ( val ):
-    import re
-    if val is not None : 
-       return re.match(r'^-[a-zA-Z]', val)
-    return 0
-
-#==============================================================
-#
-#==============================================================
-def extract_parameter ( key, args ) : 
-    import sys
-    length = len(args);
-    if ( length == 0 ) :  return None
-   
-    found = 0;
-
-    for i in range(0, length-1):
-        if  args[i] == key : 
-            if ( is_key ( args[i+1]) ) :
-               print " No value after key ", key
-                sys.exit(1);
-           
-           value = args[i+1]
-            if ( i < length - 2  and is_key ( args[i+2] ) == 0 ) : #control that only one value follows key 
-                                                              #(not a list). In this case params are correct.
-               print "Too much values after key ", key
-                sys.exit(1);
-           
-           found = 1; break;
-    
-    if (found) : 
-       return  value 
-    
-    return None
-
-
-#===============================================================
-# extracts list of values following specified 'key' from 'args[]'
-#===============================================================
-def extract_list (key, args) : 
-
-    lenght = len(args)
-    if ( args is None or lenght == 0 ):
-       error_exit()
-
-    list=[]
-    found = 0
-
-    for i in  range(0, length) :
-        if args[i] == key  : 
-            if (is_key ( args[i+1]))  : 
-                error_exit();
-           
-            for i in range (i+1, lenght):
-                if is_key(args[i]) : break
-                list.append(args[i])
-            found =1; break
-     
-    return list; #empty list is returned if no values after key
-
-
-#==============================================================
-# Method find the $key in the list and return 1 if success
-# and 0 otherwise. 
-#==============================================================
-def find_key (key, argv) :
-
-    if (not is_key(key)) : return 0
-
-    for simbol in  argv :
-        if simbol == key:
-            return 1 
-    return 0
-
-#==============================================================
-#
-#==============================================================
-def parse_parameters (args) :
-
-    if find_key('-h', args) :
-        print get_help_info();
-        import sys
-        sys.exit(0)
-        
-    xmlfile = extract_parameter("-f", args)
-    target_dir =  extract_parameter("-t", args)
-    tmp_dir = extract_parameter("-tmp", args)
-    if find_key('-tui', args):
-        is_gui = 0
-    else : is_gui = 1
-    return [xmlfile, target_dir,  tmp_dir, is_gui]
index 8abe206af965e9705c26f1389acb1bded6afa3f4..715571c1f97add5bc0446bf28f769f45f3bcf74a 100644 (file)
@@ -4,7 +4,7 @@
           copyright="&lt;h5>Copyright (C) 2003-2005 OPEN CASCADE,&lt;br>EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&amp;D,&lt;br>LEG, PRINCIPIA R&amp;D, BUREAU VERITAS&lt;/h5>"
           license="&lt;h5>GNU LGPL&lt;/h5>"
          os="DebianSarge"/>
-  <path targetdir="${HOME}/salome"
+  <path targetdir="${HOME}/salome_3.1.0"
         tempdir="/tmp"/>
   <product name="gcc" 
            version="3.3.5" 
index 8abe206af965e9705c26f1389acb1bded6afa3f4..715571c1f97add5bc0446bf28f769f45f3bcf74a 100755 (executable)
@@ -4,7 +4,7 @@
           copyright="&lt;h5>Copyright (C) 2003-2005 OPEN CASCADE,&lt;br>EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&amp;D,&lt;br>LEG, PRINCIPIA R&amp;D, BUREAU VERITAS&lt;/h5>"
           license="&lt;h5>GNU LGPL&lt;/h5>"
          os="DebianSarge"/>
-  <path targetdir="${HOME}/salome"
+  <path targetdir="${HOME}/salome_3.1.0"
         tempdir="/tmp"/>
   <product name="gcc" 
            version="3.3.5" 
index 0f8387b5e678c1e8f59efece350be55c02bbcd6e..750f9822e80d17c74cf277cee362030620772a05 100755 (executable)
@@ -58,34 +58,51 @@ makedir ${PRODUCT_DIR}
 check_jb tar xfz ${SOURCE_DIR}/Numeric-23.7.tar.gz -C ${INSTALL_WORK}
 cd ${PRODUCT_WORK}
 
-# check existence of lapack, f77blas, cblas, atlas libraries
-found=1
-check_lib_version liblapack.so
-if [ "$?" -ne "0" ] ; then
-  found=0
-fi
-if [ "$found" -eq "1" ] ; then
-    check_lib_version libf77blas.so
-    if [ "$?" -ne "0" ] ; then
-       found=0
+# check existence of lapack, f77blas, cblas, atlas, g2c libraries
+check_lib_version liblapack.so  $LD_LIBRARY_PATH:/usr/lib
+lapack_nf=$?
+check_lib_version libf77blas.so $LD_LIBRARY_PATH:/usr/lib
+f77blas_nf=$?
+check_lib_version libcblas.so   $LD_LIBRARY_PATH:/usr/lib
+cblas_nf=$?
+check_lib_version libatlas.so   $LD_LIBRARY_PATH:/usr/lib
+atlas_nf=$?
+check_lib_version libg2c.so     $LD_LIBRARY_PATH:/usr/lib
+g2c_nf=$?
+let nfound=$lapack_nf+$f77blas_nf+$cblas_nf+$atlas_nf+$g2c_nf
+# modify build procedure according to the libraries found
+if [ $nfound -gt 0 ] ; then
+    cp setup.py setup.py.orig
+    if [ "$lapack_nf" -eq "1" ] ; then
+       sed -e "s%\(^libraries_list = \[\)\('lapack', \)\(.*\)$%\1\3%g" setup.py > _setup.py
+       mv _setup.py setup.py
     fi
-fi
-if [ "$found" -eq "1" ] ; then
-    check_lib_version libcblas.so
-    if [ "$?" -ne "0" ] ; then
-       found=0
+    if [ "$f77blas_nf" -eq "1" ] ; then 
+       sed -e "s%\(^libraries_list = \[.*\)\('f77blas', \)\(.*\)$%\1\3%g" setup.py > _setup.py
+       mv _setup.py setup.py
     fi
-fi
-if [ "$found" -eq "1" ] ; then
-    check_lib_version libatlas.so
-    if [ "$?" -ne "0" ] ; then
-       found=0
+    if [ "$cblas_nf" -eq "1" ] ; then
+       sed -e "s%\(^libraries_list = \[.*\)\('cblas', \)\(.*\)$%\1\3%g" setup.py > _setup.py
+       mv _setup.py setup.py
     fi
-fi
-# if any library is not found modify build procedure
-if [ "$found" -eq "0" ] ; then
-    cp setup.py setup.py.orig
-    sed -e "s%^use_dotblas = 1%use_dotblas = 0%g" -e "s%^libraries_list = \['lapack', 'cblas', 'f77blas', 'atlas', 'g2c'\]%libraries_list = \['g2c'\]%g" setup.py.orig > setup.py
+    if [ "$atlas_nf" -eq "1" ] ; then
+       sed -e "s%\(^libraries_list = \[.*\)\('atlas', \)\(.*\)$%\1\3%g" setup.py > _setup.py
+       mv _setup.py setup.py
+    fi
+    if [ "$g2c_nf" -eq "1" ] ; then
+       sed -e "s%\(^libraries_list = \[.*\)\('g2c'\)\(.*\)$%\1\3%g" setup.py > _setup.py
+       mv _setup.py setup.py
+    fi
+    sed -e "s%^use_dotblas = 1%use_dotblas = 0%g" setup.py > _setup.py
+    mv _setup.py setup.py
+    sed -e "s%#\(os.path.join('Src', 'blas_lite.c'),\)%\1%g" setup.py > _setup.py
+    mv _setup.py setup.py
+    sed -e "s%#\(os.path.join('Src', 'f2c_lite.c'),\)%\1%g" setup.py > _setup.py
+    mv _setup.py setup.py
+    sed -e "s%#\(os.path.join('Src', 'zlapack_lite.c'),\)%\1%g" setup.py > _setup.py
+    mv _setup.py setup.py
+    sed -e "s%#\(os.path.join('Src', 'dlapack_lite.c')\)%\1%g" setup.py > _setup.py
+    mv _setup.py setup.py
     chmod a+x setup.py
 fi
 
index 9334e9a1d46ed53a7c9c813058f52dccca890cb0..a9f0a441cecf48e1d9ed52c53a5b31a530c76d18 100755 (executable)
@@ -1,7 +1,7 @@
 #! /bin/csh -f
 ##################################################################################################
 # Name       : build.csh
-# Description: Build and install SALOME2 modules from sources
+# Description: Build and install SALOME modules from sources
 # Author     : Vadim SANDLER (VSR), Open CASCADE S.A.
 # Created    : 27.01.2005
 ##################################################################################################
index 395a2de67949b0e5f453d2673b0b9d0a03421ff0..f48202c07f3f103e8f0e77fcf224dfa4af439ecc 100755 (executable)
@@ -18,7 +18,6 @@
 export DELIM="------"
 export SHRC="salome.sh"
 export CSHRC="salome.csh"
-export DEBUG=1
 
 #this function takes several parameters
 #first parameter contains descriptor of output file
@@ -29,19 +28,21 @@ check_job()
 {
   out=$1
   shift
-  echo -e "`pwd` -> $* >> $out" 
-  if [ $DEBUG == 0 ] ; then
-    $* | tee $out
+  errfile=/tmp/errlog
+  if [ -n "$INSTALL_WORK" ] ; then errfile=$INSTALL_WORK/errlog; fi
+  cmd="`pwd` -> $*"
+  if [ "$out" != "1" ] ; then cmd="$cmd >> $out" ; fi
+  echo -e $cmd
+  if [ "$out" != "1" ] ; then
+      $* >> $out 2>$errfile
   else
-    if [ $out == "1" ] ; then
       $*
-    else
-      $* >> $out 2>&1
-    fi 
   fi
   if [ "$?" -ne "0" ] ; then
     if [ $out != "1" ] ; then
       cat $out
+      cat $errfile >&2
+      cat $errfile >> $out
     fi
     # VSR : 10/11/05: disable answer mode ==>
     #echo -n " " >&2
@@ -129,7 +130,8 @@ done
 # 1. first dump all environment files into the $SHRC file
 product_sequence="$2"
 for i in $product_sequence ; do
-    cat ${install_work}/env_${i}.sh >> ${install_work}/$SHRC 2>/dev/null
+    env_file=${install_work}/env_${i}.sh
+    ( test -e $env_file && cat $env_file >> ${install_work}/$SHRC 2>/dev/null )
 done
 
 # 2. writing global functions to _salome.sh file
index d5cf9148407153c8befed7a075e9c8ffe17b5b29..4a4796f8ec9d49e96befea1d3991293ccbfef473 100755 (executable)
@@ -5,353 +5,66 @@ warnings.filterwarnings("ignore", "", DeprecationWarning)
 
 import xmllib
 import sys, os, string, re
+from optparse import OptionParser
 
-#==============================================================
-# get_help_info
-#==============================================================
-def get_help_info() :
-    str = "\nSALOME Installation Wizard\n\n"
-    str = str + "\tUsage : \n\tInstall [-g|b] [-f <xml-file>] [-t <target-dir>] [-tmp <tmp-dir>]\n"
-    str = str + "\n"
-    str = str + " -g              Runs the Installation Wizard in the GUI mode.\n"
-    str = str + "                 In this case only <xmlfile> is taken into account \n"
-    str = str + "                 from the parameters list. This key is used by default.\n"
-    str = str + "\n"
-    str = str + " -b              Runs the Installation Wizard in the batch mode.\n"
-    str = str + "                 All the found parameters are taken in to account.\n"
-    str = str + "\n"
-    str = str + " -f <xml-file>   The configuration file to be parsed by the Installation Wizard.\n" 
-    str = str + "                 If this parameter is missed then the script tries to define\n"
-    str = str + "                 the Red Hat version and use the corresponding xml. For example,\n"
-    str = str + "                 for Red Hat 8.0 config_RedHat_8.0.xml file is supposed to be used\n"
-    str = str + "                 by default. If the appropriate xml file is not found, the config.xml\n"
-    str = str + "                 is used by default.\n"
-    str = str + "\n"
-    str = str + " -t <target-dir> The target directory the products to be installed to.\n"
-    str = str + "                 This parameter overloads the target directory described in the\n"
-    str = str + "                 configuration file.\n"
-    str = str + "\n"
-    str = str + " -tmp <tmp-dir>  The directory which should be used for the temporary files.\n"
-    str = str + "                 This parameter overloads the temporary directory described in the\n"
-    str = str + "                 configuration file.\n"
-    str = str + "\n"
-    str = str + " -h              Prints this help information.\n" 
-    return str
-
-#==============================================================
-# message finction
-#==============================================================
-def message(msg):
-    print ">>>", msg
-    
-#==============================================================
-# error_exit
-#==============================================================
-def error_exit (str = ""):
-    import sys
-    if len(str): res = "\n" + str + "\n"
-    else : res = ""
-    print res + \
-          get_help_info() 
-    sys.exit(1);
-
-
-#==============================================================
-# Cheks whether the passed parameter is a key.
-#==============================================================
-def is_key ( val ):
-    import re
-    if val is not None : 
-       return re.match(r'^-[a-zA-Z]', val)
-    return 0
-
-#==============================================================
-# From the list of parameters extracts value following 'key' 
-#==============================================================
-def extract_parameter ( key, args ) :
-    import sys
-    length = len(args);
-    if ( length == 0 ) :  return None
-   
-    found = 0;
-
-    for i in range(0, length-1):
-        if  args[i] == key : 
-            if ( is_key ( args[i+1]) ) :
-               print " No value after key ", key
-                sys.exit(1);
-           
-           value = args[i+1]
-            if ( i < length - 2  and is_key ( args[i+2] ) == 0 ) : #control that only one value follows key 
-                                                              #(not a list). In this case params are correct.
-               print "Too much values after key ", key
-                sys.exit(1);
-           
-           found = 1; break;
-    
-    if (found) : 
-       return  value 
-    
-    return None
-
-
-#===============================================================
-# Extracts list of values following specified 'key' from 'args[]'
-#===============================================================
-def extract_list (key, args) : 
-
-    lenght = len(args)
-    if ( args is None or lenght == 0 ):
-       error_exit()
-
-    list=[]
-    found = 0
-
-    for i in  range(0, length) :
-        if args[i] == key  : 
-            if (is_key ( args[i+1]))  : 
-                error_exit();
-           
-            for i in range (i+1, lenght):
-                if is_key(args[i]) : break
-                list.append(args[i])
-            found =1; break
-     
-    return list; #empty list is returned if no values after key
-
+opt_parser = None
+root_path  = None
 
-#==============================================================
-# Method find the $key in the list and return 1 if success
-# and 0 otherwise. 
-#==============================================================
-def find_key (key, argv) :
-
-    if (not is_key(key)) : return 0
-
-    for simbol in  argv :
-        if simbol == key:
-            return 1 
-    return 0
-
-#==============================================================
-# Parse the list of parameters
-#==============================================================
-def parse_parameters (args) :
-
-    if find_key('-h', args) :
-        print get_help_info();
-        import sys
-        sys.exit(0)
-        
-    xmlfile = extract_parameter("-f", args)
-    target_dir =  extract_parameter("-t", args)
-    tmp_dir = extract_parameter("-tmp", args)
-    if find_key('-b', args):
-        is_gui = 0
-    else : is_gui = 1
-    return [xmlfile, target_dir,  tmp_dir, is_gui]
-
-
-#=================================================================
-# Checks boolean value: yes/no, true/false, 1/0
-#=================================================================
-def check_bool(val):
-    return str(val).strip() in ["yes","true", "1"]
-
-#=================================================================
-# The first algorithm to create the dependencies list by their level
-#=================================================================
-def get_next_level(list, products):
-    
-    import re
-    result = []
-    expr = "(" + list[0].name
-    for i in range(1, len(list)):
-        expr = expr + "|"+ list[i].name
-    
-    expr = expr + ")$"
-    #expr=re.compile(expr)
-
-    for product in products:
-        deps = re.sub(r'\s+', "", product.dependencies)
-        if re.search(expr,  deps):
-            result.append(product)
-
-    return result
-
-
-def create_levels(prods):
-    import copy
-    
-    products = copy.deepcopy(prods)
-    
-    result = {}
-    import re
-    #1. find the products with empty lists of dependencies
-    list = []
-    for product in products:
-        if len(re.sub(r'\s', "", product.dependencies)) == 0 :
-            list.append(product)
-
-    if len(list) == 0 :
-        raise RuntimeError, "Products that depend on nothing are not found"
-
-    # remove the first level products from the common list of products
-    for product in list :
-        products.remove(product)
-
-    ind = 0; 
-    result[0] = list
-
-    while (len(products)) :
-        res = get_next_level(list, products)
-        if len(res) == 0 :
-            raise RuntimeError, "Empty list of products is found"
-
-        for product in res :
-            products.remove(product)
-
-        ind = ind +1
-        result[ind] =  res
-        list = res
-            
-    str = ""
-    for i in result.keys():
-        for product in  result[i]:
-            str = str + product.name + " "
-
-    return str;
-            
-#=================================================================
-# The second algorithm
-#=================================================================
-def get_dependencies_set(prods) :
-    import copy
-    import re
-
-    products = copy.deepcopy(prods)
-    deps = ""
-    list = []
-
-    while (len(products)) :
-
-        tmplist = []
-        #find the products with empty list of dependencies
-        for product in products:
-            product.dependencies = re.sub(r'\s+$', "", product.dependencies)
-            product.dependencies = re.sub(r'^\s+', "", product.dependencies)
-           
-            if len(product.dependencies) == 0 :
-               tmplist.append(product); 
-               deps = deps + " " + product.name
-
-        list.append(tmplist)
-
-        #remove the products names from other products dependencies
-        for item in tmplist:
-            products.remove(item)
-
-            regexpr1 = "((^|,(\s+)?)"+item.name+"$|^"+item.name+"(\s+)?,(\s+)?)"
-            regexpr2 = ",(\s+)?"+item.name+"(\s+)?,(\s+)?"
-
-            for product in products:
-                product.dependencies = re.sub(r'\s+$', "", product.dependencies)
-                product.dependencies = re.sub(r'^\s+', "", product.dependencies)
-
-                product.dependencies = re.sub(regexpr1, "", product.dependencies)
-                product.dependencies = re.sub(regexpr2, ",", product.dependencies)
-
-    return deps 
-    
-#=================================================================
-# The third algorithm (same as SALOME_InstallWizard.cxx uses)
-#=================================================================
-def get_dependencies(prods) :
-    list = []
-    for product in prods:
-        if check_bool(product.disable): continue
-        
-        deps = product.dependencies.split(",")
-        for dep in deps:
-            if dep and not dep in list:
-                list.append( dep )
-                
-        if product and not product in list:
-            list.append( product.name )
-            
-    return " ".join( list )
-
-#==============================================================
-# Creates dir, returns the part of path that existed early.
-# Access may be defined.
-#==============================================================
-def create_dir (directory, access = 0777):
-    import string, os
-    dirs = string.split(directory, "/")
-    existing = ""; dir = ""
-    root = ""
-    for item in dirs:
-        if len(item) == 0:  continue
-        dir = dir + "/"+item
-        if os.path.exists(dir):
-            existing = dir
-        else:
-            os.mkdir(dir, access )
-            #root= existing + "/"+item
-            if dir == existing + "/"+item :
-                root = dir
-            #else : root = existing
-    
-    return root
+__TAG__SOURCES__    = "install sources"
+__TAG__BINARIES__   = "install binaries"
+__TAG__NATIVE__     = "use native"
+__TAG__PREINSTALL__ = "not install"
 
 #==============================================================
 # class Product 
 #==============================================================
 
 class Product :
-    def __init__(self, theName,
+    def __init__(self,
+                 theName,
                  theVersion            = None,
                  theInstall            = None,
                  theSupportred         = None,
-                 theDisable            = None,
                  theDependencies       = None,
                  theInstalldiskspace   = None,
                  theTemporarydiskspace = None,
                  theScript             = None,
                  thePickUpEnvironment  = None):
-        
-
-        self.name               = theName
-        self.version            = theVersion
-        self.install            = theInstall
-        self.supported          = theSupportred
-        self.disable            = theDisable
-        self.dependencies       = theDependencies
-        self.installdiskspace   = theInstalldiskspace
-        self.temporarydiskspace = theTemporarydiskspace
-        self.script             = theScript
-        self.pickupEnv          = thePickUpEnvironment
+        self.name               = strip(theName)
+        self.version            = strip(theVersion)
+        self.install            = strip(theInstall)
+        self.supported          = strip(theSupportred)
+        self.dependencies       = strip(theDependencies)
+        self.installdiskspace   = strip(theInstalldiskspace)
+        self.temporarydiskspace = strip(theTemporarydiskspace)
+        self.script             = strip(theScript)
+        self.pickupEnv          = strip(thePickUpEnvironment)
 
 #===================================================================
 # class Config
 #===================================================================
 class Config :
-    def __init__(self, theVersion='', theCaption='', theCopyright='', theLicense='', theOS=''):
-        self.version   = theVersion
-        self.caption   = theCaption
-        self.copyright = theCopyright
-        self.license   = theLicense
-        self.os        = theOS
-
+    def __init__(self,
+                 theVersion   = None,
+                 theCaption   = None,
+                 theCopyright = None,
+                 theLicense   = None,
+                 theOS        = None):
+        self.version   = strip(theVersion)
+        self.caption   = strip(theCaption)
+        self.copyright = strip(theCopyright)
+        self.license   = strip(theLicense)
+        self.os        = strip(theOS)
 
 #===================================================================
 # class Path
 #===================================================================
 class Path :
-    def __init__(self, theTargetdir=".", theTmpdir="."):
-        self.targetdir = theTargetdir
-        self.tmpdir    = theTmpdir
-
+    def __init__(self,
+                 theTargetdir = None,
+                 theTmpdir    = None):
+        self.targetdir = strip(theTargetdir)
+        self.tmpdir    = strip(theTmpdir)
         
 #===================================================================
 # class ConfigParser
@@ -368,36 +81,38 @@ class ConfigParser(xmllib.XMLParser):
         self.currentdata.append(data)
         
     def start_product(self, attrs):
-        aProduct = Product(attrs['name'],
-                           attrs['version'],
-                           attrs['install'],
-                           attrs['supported'],
-                           attrs['disable'],
-                           attrs['dependancies'],
-                           attrs['installdiskspace'],
-                           attrs['temporarydiskspace'],
-                           attrs['script'])
-
-        if attrs.has_key( 'pickupenv' ):
-            aProduct.pickupEnv = attrs['pickupenv']
-
+        if not attrs.get('name', '').strip():         return
+        if check_bool(attrs.get('disable', 'false')): return
+        aProduct = Product(attrs.get('name'),
+                           attrs.get('version',            None),
+                           attrs.get('install',            None),
+                           attrs.get('supported',          None),
+                           attrs.get('dependancies',       None),
+                           attrs.get('installdiskspace',   None),
+                           attrs.get('temporarydiskspace', None),
+                           attrs.get('script',             None),
+                           attrs.get('pickupenv',          None))
         self.products.append(aProduct)
+        pass
 
     def end_product(self):
         pass
 
     def start_config(self, attrs):
-        self.config = Config(attrs['version'],
-                             attrs['caption'],
-                             attrs['copyright'],
-                             attrs['license'],
-                             attrs['os'])
+        self.config = Config(attrs.get('version',   None),
+                             attrs.get('caption',   None),
+                             attrs.get('copyright', None),
+                             attrs.get('license',   None),
+                             attrs.get('os',        None))
+        pass
+    
     def end_config(self):
         pass
 
     def start_path (self, attrs):
-        self.path = Path(attrs['targetdir'],
-                         attrs['tempdir'])
+        self.path = Path(attrs.get('targetdir', None),
+                         attrs.get('tempdir',   None))
+        pass
         
     def end_path(self):
         pass
@@ -408,84 +123,303 @@ class ConfigParser(xmllib.XMLParser):
                 return product
         return None
 
+#==============================================================
+# message: prints diagnostic information
+#==============================================================
+def message(msg):
+    if msg.strip():
+        print ">>>", msg
+    pass
+
+#==============================================================
+# warning: prints warning
+#==============================================================
+def warning(msg):
+    if msg.strip():
+        print ""
+        print msg
+        print ""
+    pass
+
+#==============================================================
+# error_exit : prints (optionally) error string, then prints
+#              help information and quits
+#==============================================================
+def error_exit(msg = "", print_help = True):
+    # print error message
+    if len(msg.strip()):
+        print ""
+        print msg
+        print ""
+    # print help information
+    if print_help:
+        global opt_parser
+        if opt_parser:
+            opt_parser.print_help() 
+            print ""
+    # cleaning 
+    clean_all()
+    # quit
+    sys.exit(1);
+    pass
+
+#==============================================================
+# clean_all : performs system cleaning before exiting
+#==============================================================
+def clean_all():
+    global root_path
+    remove_dir(root_path)
+    pass
+
+#==============================================================
+# parse_parameters : parses command line arguments
+#==============================================================
+def parse_parameters():
+    global opt_parser
+    opt_parser = OptionParser(add_help_option=False)
+    help_str  = "Runs the Installation Wizard in the GUI mode [default].\n"
+    help_str += "In this case only -f option is taken into account. "
+    help_str += "Other options are ignored."
+    opt_parser.add_option("-g",
+                          "--gui",
+                          action="store_true",
+                          dest="gui",
+                          default=True,
+                          help=help_str)
+    help_str  = "Runs the Installation Wizard in the TUI mode."
+    opt_parser.add_option("-b",
+                          "--batch",
+                          action="store_false",
+                          dest="gui",
+                          help=help_str)
+    help_str  = "The configuration xml file.\n"
+    help_str += "If this parameter is missing, then the program tries to define the "
+    help_str += "Linux platform and use the corresponding xml file. For example, "
+    help_str += "for Red Hat 8.0 config_RedHat_8.0.xml file is used in this case."
+    help_str += "If program fails to define target Linux platform or the corresponding "
+    help_str += "xml file is not provided with the Installation Wizard, then default "
+    help_str += "config.xml file is used."
+    opt_parser.add_option("-f",
+                          "--file",
+                          action="store",
+                          dest="xmlfile",
+                          metavar="FILE",
+                          help=help_str)
+    help_str  = "The target directory the products to be installed to.\n"
+    help_str += "When used this parameter overrides the default target directory "
+    help_str += "defined in the configuration xml file."
+    opt_parser.add_option("-d",
+                          "--target",
+                          action="store",
+                          dest="target_dir",
+                          metavar="DIR",
+                          help=help_str)
+    help_str  = "The directory used for temporary files.\n"
+    help_str += "When used this parameter overrides the default temporary directory "
+    help_str += "defined in the configuration xml file."
+    opt_parser.add_option("-t",
+                          "--tmp",
+                          action="store",
+                          dest="tmp_dir",
+                          metavar="DIR",
+                          help=help_str)
+    help_str  = "Prints this help and quits."
+    opt_parser.add_option("-v",
+                          "--version",
+                          action="store_true",
+                          help=help_str)
+    help_str  = "Prints version information and quits."
+    opt_parser.add_option("-h",
+                          "--help",
+                          action="store_true",
+                          help=help_str)
+    (options, args) = opt_parser.parse_args()
+    if options.help:
+        # print help info and quit
+        print "\nSALOME Installation Wizard\n"
+        opt_parser.print_help()
+        print ""
+        sys.exit(0)
+    if options.version:
+        # print version info and quit
+        print ""
+        cmd = "./bin/SALOME_InstallWizard --version"
+        os.system(cmd)
+        print ""
+        sys.exit(0)
+    return [options.xmlfile, options.target_dir, options.tmp_dir, options.gui]
+
+#=================================================================
+# strip : removes spaces at the beginning and at eh end of the 
+#         <param> if it is of string type
+#=================================================================
+def strip(param):
+    import types
+    if type(param) == types.StringType:
+        return param.strip()
+    return param
+    
+#=================================================================
+# check_bool : checks boolean value: yes/no, true/false, 1/0
+#=================================================================
+def check_bool(val):
+    if str(val).lower().strip() in ["yes","true", "1"]:
+        return True
+    if str(val).lower().strip() in ["no","false", "0"]:
+        return False
+    try:
+        val = int(val)
+        return val != 0
+    except:
+        pass
+    return False
+
+#=================================================================
+# get_dependencies : extract products dependencies
+#=================================================================
+def get_dependencies(prods):
+    list = []
+    for product in prods:
+        deps = product.dependencies.split(",")
+        for dep in deps:
+            if dep and not dep in list:
+                list.append( dep )
+                
+        if product and not product in list:
+            list.append( product.name )
+            
+    return " ".join( list )
+
+#==============================================================
+# create_dir : creates a directory with (optional) permissions,
+#              returns the part of path that existed before
+#              directory creation; exits with error if access
+#              is denied
+#==============================================================
+def create_dir(directory, access = 0777):
+    import string, os
+    dirs = string.split(directory, "/")
+    existing = "";
+    dir = ""
+    root = ""
+    for subdir in dirs:
+        if len(subdir) == 0:  continue
+        dir = "%s/%s"%(dir, subdir)
+        if os.path.exists(dir):
+            existing = dir
+        else:
+            try:
+                os.mkdir(dir, access)
+            except:
+                error_exit("Can't create directory: %s.\nAccess is denied."%directory)
+            if dir == "%s/%s"%(existing, subdir):
+                root = dir
+    return root
+
+#==============================================================
+# substituteVars : performes environment variables substistution
+#                  the given string; if varibale is not defined
+#                  it is substituted by the empty string
+#==============================================================
+def substituteVars(str):
+    str = os.path.expanduser(str)
+    str = os.path.expandvars(str)
+    return str
+
 #================================================================
-# get the path using file name
+# get_program_path : gets program's directory path
+#                    (and performs 'cd' command there) 
 #================================================================
-def get_current_path(file_name):
-    path = "."; where = string.rfind(file_name,'/');
-    if (where != -1):
-        path = (file_name)[: where]
-        os.chdir(path);
-    path = os.getcwd() + "/"
-    return path
+def get_program_path():
+    path = os.path.dirname(sys.argv[0])
+    if path:
+        os.chdir(path)
+    return os.getcwd()
 
 #================================================================
-# checks dir existing 
+# check_dir : checks directory existence
 #================================================================
 def check_dir(dir):
-    if (os.path.islink(dir)) :
-        native_dir = os.readlink(dir)
-        if not os.path.exists(native_dir) :
-            print "Invalid link " + dir + ". The directory " + native_dir + " a link points to does not exist."
-            return 0 # problem
-    else :
+    if (os.path.islink(dir)):
+        realpath = os.path.realpath(dir)
+        if not os.path.exists(realpath):
+            msg = "Invalid link %s.\nThe directory %s a link points to does not exist."%(dir,realpath)
+            error_exit(msg, False)
+    else:
         if not os.path.exists(dir):
-            print "Directory " + dir + " does not exist"
-            return 0
-    return 1
+            msg = "Directory %s does not exist."%dir
+            error_exit(msg, False)
+    pass
 
 #===============================================================
-# Checks the disk space. Exit from interpreter if there is no
-# enough disk space.
+# check_disk_space : checks the disk space;
+#                    quits if there is no enough disk space
 #===============================================================
-def check_disk_space(products, script_dir, target_dir, tmp_dir):
-    import re, string, os
+def check_disk_space(products, scripts_dir, target_dir, tmp_dir):
     install_space = 0
     temporary_space = 0
-    for product in products :
-        product.install = re.sub(r'^\s+', "", product.install)
-        product.install = re.sub(r'\s+$', "", product.install)
-        
-        if check_bool(product.disable) or product.install == "use native" or product.install == "not install":
+    for product in products:
+        if product.install in [__TAG__NATIVE__, __TAG__PREINSTALL__]:
             continue
-        spaces = string.split( product.installdiskspace,',')
+        spaces = string.split(product.installdiskspace, ',')
         prod_space = spaces[0]
-        if (len(spaces) == 2 ) and (product.install == "install binaries") :
+        if (len(spaces) > 1 ) and (product.install == __TAG__SOURCES__):
             prod_space = spaces[1]
         install_space = install_space + string.atoi(prod_space)
-        temporary_space = temporary_space + string.atoi(product.temporarydiskspace)
-    res = os.system(scripts_dir + "checkSize.sh" + " " + target_dir + " " + str(install_space))
+        if product.install == __TAG__SOURCES__:
+            temporary_space = max(temporary_space, string.atoi(product.temporarydiskspace))
+
+    res = os.system("%s/%s %s %d"%(scripts_dir, "checkSize.sh", target_dir, install_space))
     if res:
-        print "There is no enough space to install the products."
-        return 0
+        msg = "There is no enough space to install the products."
+        error_exit(msg, False)
     
-    res = os.system(scripts_dir + "checkSize.sh" + " " + tmp_dir + " " + str(temporary_space))
+    res = os.system("%s/%s %s %d"%(scripts_dir, "checkSize.sh", tmp_dir, temporary_space))
     if res:
-        print "There is no enough space for tmp directory."
-        return 0
-    
-    return 1
+        msg = "There is no enough space for temporary directory."
+        error_exit(msg, False)
+    pass
  
 #===============================================================
-# Removes temporary directory
+# remove_dir : removes temporary directory
 #===============================================================
-def remove_dir( rem_path = "" ):
-    if len( rem_path ) and os.path.exists( rem_path ):
-        os.system( "rm -rf " + rem_path )
+def remove_dir(path):
+    if path and os.path.exists(path):
+        os.system("rm -rf " + path)
     pass
-    
+
+#==============================================================
+# has_binaries : returns True if some product is installed from
+#                binaries
+#===============================================================
+def has_binaries(products):
+    for product in products:
+        if product.install == __TAG__BINARIES__:
+            return True
+    return False
+
+#==============================================================
+# has_sources : returns True if some product is installed from
+#               sources
+#===============================================================
+def has_sources(products):
+    for product in products:
+        if product.install == __TAG__SOURCES__:
+            return True
+    return False
+
 #================================================================
 # main
 #================================================================
     
 if __name__ == "__main__":
-    
-    cur_dir = get_current_path(sys.argv[0])
-   
-    [xml_file, target_dir, tmp_dir, is_gui]  = parse_parameters(sys.argv)
+    # get program dir
+    cur_dir = get_program_path()
+    # parse command line
+    [xml_file, target_dir, tmp_dir, is_gui] = parse_parameters()
 
-    # define xml file -----------------
-    if (xml_file is None) :
+    # define xml file to be used
+    if (xml_file is None):
         plt_name = ""
         plt_ver  = ""
         xml_file_name = "config.xml"
@@ -504,45 +438,42 @@ if __name__ == "__main__":
             plt_name = "Debian"
             plt_ver = open("/etc/debian_version").readline().strip()
         _xml_file_name = "config_%s_%s.xml"%(plt_name, plt_ver)
-        if plt_name and plt_ver and os.path.exists(cur_dir + _xml_file_name):
+        if plt_name and plt_ver and os.path.exists("%s/%s"%(cur_dir, _xml_file_name)):
             xml_file_name = _xml_file_name
         else:
-            print ""
-            print "Not supported Linux platform!"
-            print "Trying to use default configuration!"
-            print ""
+            msg  = "Not supported Linux platform!\n"
+            msg += "Trying to use default configuration file!"
+            warning(msg)
 
-        xml_file = cur_dir +  xml_file_name
+        xml_file = "%s/%s"%(cur_dir, xml_file_name)
 
     if not xml_file or not os.path.exists(xml_file):
-        msg  = "Configuration file %s is not found!"%xml_file
-        msg += "\nTry to run with -f <xmlfile> option."
+        msg = "Configuration file %s is not found!"%xml_file
         error_exit(msg)
 
     if not os.access(xml_file, os.R_OK):
-        print "There is no read access for %s file!"%xml_file
-        sys.exit(1)
+        msg = "There is no read access for %s file!"%xml_file
+        error_exit(msg)
 
     #---- GUI ----------------
+
     if is_gui : 
         env = os.environ
         if not env.has_key("PATH") :
             env["PATH"] = ""
         if not env.has_key("LD_LIBRARY_PATH") :
-            env["LD_LIBRARY_PATH"] ""
+            env["LD_LIBRARY_PATH"] = ""
 
-        env["LD_LIBRARY_PATH"] =  ".:" +  env["LD_LIBRARY_PATH"]
-        env["PATH"] = ".:"+ env["PATH"]
+        env["LD_LIBRARY_PATH"] =  ".:" + env["LD_LIBRARY_PATH"]
+        env["PATH"] = ".:" + env["PATH"]
 
-        sys.exit(os.system("cd " + cur_dir + "; ./bin/SALOME_InstallWizard " + xml_file +"&"))
-        
-        
+        cmd = "./bin/SALOME_InstallWizard %s &"%xml_file
+        sys.exit(os.system(cmd))
 
     #-----  TUI ---------------------
 
-    #print xml_file, target_dir, tmp_dir, is_gui
-
-    message("Parsing xml config file: " + xml_file)
+    # parse XML file -----------
+    message("Parsing XML configuration file: %s"%xml_file)
     filehandle = open(xml_file)
     data = filehandle.read()
     filehandle.close()
@@ -550,103 +481,114 @@ if __name__ == "__main__":
     parser.feed(data)
     parser.close()
 
-    # definitions :
-    # map
-    what_to_do = { "install sources"  : "install_source",
-                   "install binaries" : "install_binary",
-                   "use native"       : "try_native",
-                   "not install"      : "try_preinstalled"}
-    # define tmp dir  -----------
-    if tmp_dir is None:
-        tmp_dir = parser.path.tmpdir
-    if tmp_dir is None or tmp_dir == "":
-        tmp_dir = "/tmp"
-    import random
-    tmp_dir = tmp_dir + "/INSTALLWORK" + str(random.randint(10000,100000))
-    root_path = ""
-    if not os.path.exists(tmp_dir):
-        message("Creating temporary directory: " + tmp_dir); root_path = create_dir(tmp_dir, 0755) ; 
-    if not os.path.exists(tmp_dir):
-        error_exit("Invalid temporary directory " + tmp_dir + ". Use -tmp key to set directory or correct xml file\n\n")
-
-    if not os.access(tmp_dir, os.W_OK) :
-        str = "There is no write permissions for directory " + tmp_dir + ". Use -tmp key to set temporary directory or correct xml file"
-        error_exit(str)
-        
-    # define target dir  --------
+    # actions map
+    what_to_do = { __TAG__SOURCES__    : "install_source",
+                   __TAG__BINARIES__   : "install_binary",
+                   __TAG__NATIVE__     : "try_native",
+                   __TAG__PREINSTALL__ : "try_preinstalled"}
+    # source directory map
+    bin_dir = ""
+    if parser.config.os:
+        bin_dir += "/%s"%parser.config.os
+    subdir = { __TAG__SOURCES__    : "SOURCES",
+               __TAG__BINARIES__   : "BINARIES" + bin_dir,
+               __TAG__NATIVE__     : "",
+               __TAG__PREINSTALL__ : ""}
+
+    # check scripts directory -----------
+    scripts_dir = "%s/%s"%(cur_dir, "config_files")
+    check_dir(scripts_dir)
+
+    # check products archives directories -----------
+    has_bin = has_binaries(parser.products)
+    has_src = has_sources(parser.products)
+    source_dir = "%s/%s"%(cur_dir, "Products")
+
+    if has_src or has_bin:
+        check_dir(source_dir)
+
+    if has_src:
+        check_dir("%s/%s"%(source_dir,subdir[__TAG__SOURCES__]))
+
+    if has_bin:
+        check_dir("%s/%s"%(source_dir,subdir[__TAG__BINARIES__]))
+
+    # check/create target dir -----------
     if target_dir is None:
         target_dir = parser.path.targetdir
+    target_dir = substituteVars(target_dir)
+
+    message("Creating target directory: " + target_dir)
+    create_dir(target_dir, 0755)
 
     if not os.path.exists(target_dir):
-        message("Creating target directory: " + target_dir); create_dir(target_dir, 0755)
-    if not os.path.exists(target_dir):
-        error_exit("Invalid target directory " + target_dir + ". Use -t key to set directory or correct xml file\n\n")
+        error_exit("Invalid target directory: " + target_dir)
 
     if not os.access(target_dir, os.W_OK) :
-        str = "There is no write permissions for directory " + target_dir + ". Use -t key to set target directory or correct xml file."
-        error_exit(str)
-
-    # define products dir ------------
-    source_dir =  cur_dir + "Products" ; 
-    if not check_dir(source_dir):
-        remove_dir(root_path)
-        sys.exit(1)
-       
-    subdir = {"install sources"  : "SOURCES",
-              "install binaries" : "BINARIES/"+parser.config.os,
-              "use native"       : "",
-              "not install"      : ""}
-
-
-    #  define scripts dir ------------
-    scripts_dir = cur_dir + "config_files/"
-    if not check_dir(scripts_dir):
-        remove_dir(root_path)
-        sys.exit(1)
-    os.chdir(scripts_dir)
+        error_exit("There is no write permissions for the directory: " + target_dir)
+
+    # check/create temporary dir -----------
+    if tmp_dir is None:
+        tmp_dir = parser.path.tmpdir
+    if not tmp_dir:
+        tmp_dir = "/tmp"
+    tmp_dir = substituteVars(tmp_dir)
+    import random
+    tmp_dir = "%s/INSTALLWORK%d"%(tmp_dir, random.randint(10000,100000))
 
-    #list_of_dep =  create_levels(parser.products)
-    #list_of_dep =  get_dependencies_set(parser.products)
-    list_of_dep =  get_dependencies(parser.products)
+    message("Creating temporary directory: " + tmp_dir)
+    root_path = create_dir(tmp_dir, 0755)
+   
+    if not os.path.exists(tmp_dir):
+        error_exit("Invalid temporary directory: " + tmp_dir)
 
+    if not os.access(tmp_dir, os.W_OK) :
+        error_exit("There is no write permissions for the directory: " + tmp_dir)
+        
+    # check available disk space
     message("Checking available disk space")
-    if check_disk_space(parser.products, scripts_dir, target_dir, tmp_dir) :
-
-        message("Starting...")
-        # install products
-        for product in parser.products :
+    check_disk_space(parser.products, scripts_dir, target_dir, tmp_dir)
 
-            if check_bool(product.disable): continue
+    # change current directory
+    os.chdir(scripts_dir)
 
-            message("Processing " + product.name + "...")
-            cmd = scripts_dir +  product.script + " " + \
-                  what_to_do[product.install]+ " " + \
-                  tmp_dir + " " + \
-                  source_dir + "/" + subdir[product.install] + " " + \
-                  target_dir + " " + \
-                  '"' + list_of_dep + '"' + " " + \
-                  product.name
+    # get dependencies list
+    list_of_dep = get_dependencies(parser.products)
 
+    # starting
+    message("Starting ...")
+    
+    # install products
+    for product in parser.products:
+        message("... processing %s ..."%product.name)
+        cmd = '%s/%s %s %s %s/%s %s "%s" %s'%(scripts_dir,
+                                              product.script,
+                                              what_to_do[product.install],
+                                              tmp_dir,
+                                              source_dir,
+                                              subdir[product.install],
+                                              target_dir,
+                                              list_of_dep,
+                                              product.name)
+        res = os.system(cmd)
+
+    # pickup environment
+    message("Creating environment files")
+    for product in parser.products :
+        if check_bool(product.pickupEnv):
+            cmd = '%s/%s pickup_env %s %s/%s %s "%s" %s'%(scripts_dir,
+                                                          product.script,
+                                                          tmp_dir,
+                                                          source_dir,
+                                                          subdir[product.install],
+                                                          target_dir,
+                                                          list_of_dep,
+                                                          product.name)
             res = os.system(cmd)
-            #if res : break; # try_preinstalled can return 1
-
-        # pickup environment
-        message("Creating environment files")
-        for product in parser.products :
-
-            if check_bool(product.disable): continue
-
-            if check_bool(product.pickupEnv):
-                cmd = scripts_dir +  product.script + " " + \
-                      "pickup_env " + \
-                      tmp_dir + " " + \
-                      source_dir + "/" + subdir[product.install] + " " + \
-                      target_dir + " " + \
-                      '"' + list_of_dep + '"' + " " + \
-                      product.name
-                
-                res = os.system(cmd)
 
+    # clean temporary directory
     message("Cleaning temporary directory")
-    remove_dir(root_path)
+    clean_all()
+    # finishing
     message("Finished!")
+    pass
index f85b34b686e5cc486b17e59db88a0ee1d47ce441..3968afcca35da5b990725dfb1b8ab8429f43657f 100644 (file)
@@ -38,6 +38,7 @@
 #include <qwaitcondition.h>
 #include <qmutex.h>
 #include <qstringlist.h>
+#include <qpopupmenu.h>
 
 #ifdef WNT
 #include <iostream.h>
@@ -56,17 +57,17 @@ QString tmpDirName() { return QString(  "/INSTALLWORK" ) + QString::number( getp
 
 // ================================================================
 /*!
- *  QProcessThread
+ *  ProcessThread
  *  Class for executing systen commands
  */
 // ================================================================
 static QMutex myMutex(false);
 static QWaitCondition myWC;
-class QProcessThread: public QThread
+class ProcessThread: public QThread
 {
   typedef QPtrList<QCheckListItem> ItemList;
 public:
-  QProcessThread( SALOME_InstallWizard* iw ) : QThread(), myWizard( iw ) { myItems.setAutoDelete( false ); }
+  ProcessThread( SALOME_InstallWizard* iw ) : QThread(), myWizard( iw ) { myItems.setAutoDelete( false ); }
 
   void addCommand( QCheckListItem* item, const QString& cmd ) {
     myItems.append( item );
@@ -78,9 +79,9 @@ public:
 
   virtual void run() {
     while ( hasCommands() ) {
-      ___MESSAGE___( "QProcessThread::run - Processing command : " << myCommands[ 0 ].latin1() );
+      ___MESSAGE___( "ProcessThread::run - Processing command : " << myCommands[ 0 ].latin1() );
       int result = system( myCommands[ 0 ] ) / 256; // return code is <errno> * 256 
-      ___MESSAGE___( "QProcessThread::run - Result : " << result );
+      ___MESSAGE___( "ProcessThread::run - Result : " << result );
       QCheckListItem* item = myItems.first();
       myCommands.pop_front();
       myItems.removeFirst();
@@ -124,8 +125,11 @@ class WarnDialog: public QDialog
   }
   void accept() { return; }
   void reject() { return; }
-  void closeEvent( QCloseEvent* e) { if ( !myCloseFlag ) return; QDialog::closeEvent( e ); }
-  
+  void closeEvent( QCloseEvent* e )
+  { if ( !myCloseFlag ) return; 
+    e->accept();
+    QDialog::closeEvent( e );
+  }
   ~WarnDialog() { myDlg = 0; }
 public:
   static void showWarnDlg( QWidget* parent, bool show ) {
@@ -151,6 +155,48 @@ public:
 };
 WarnDialog* WarnDialog::myDlg = 0;
 
+// ================================================================
+/*!
+ *  InstallInfo
+ *  Installation progress info window class
+ */
+// ================================================================
+class InstallInfo : public QTextEdit
+{
+public:
+  InstallInfo( QWidget* parent ) : QTextEdit( parent ), finished( false ) {}
+  void setFinished( const bool f ) { finished = f; }
+protected:
+  QPopupMenu* createPopupMenu( const QPoint& )
+  {
+    int para1, col1, para2, col2;
+    getSelection(&para1, &col1, &para2, &col2);
+    bool allSelected = hasSelectedText() &&
+      para1 == 0 && para2 == paragraphs()-1 && col1 == 0 && col2 == paragraphLength(para2);
+    QPopupMenu* popup = new QPopupMenu( this );
+    int id = popup->insertItem( tr( "&Copy" ) );
+    popup->setItemEnabled( id, hasSelectedText() );
+    popup->connectItem ( id, this, SLOT( copy() ) );
+    id = popup->insertItem( tr( "Select &All" ) );
+    popup->setItemEnabled( id, (bool)text().length() && !allSelected );
+    popup->connectItem ( id, this, SLOT( selectAll() ) );
+    if ( finished ) {
+      QWidget* p = parentWidget();
+      while ( p && !p->inherits( "SALOME_InstallWizard" ) )
+       p = p->parentWidget();
+      if ( p && p->inherits( "SALOME_InstallWizard" ) ) {
+       popup->insertSeparator();
+       id = popup->insertItem( tr( "&Save Log" ) );
+       popup->setItemEnabled( id, (bool)text().length() );
+       popup->connectItem ( id, (SALOME_InstallWizard*)p, SLOT( saveLog() ) );
+      }
+    }
+    return popup;
+  }
+private:
+  bool finished;
+};
+
 // ================================================================
 /*!
  *  DefineDependeces [ static ]
@@ -368,7 +414,7 @@ SALOME_InstallWizard::SALOME_InstallWizard(QString aXmlFileName)
   connect(shellProcess, SIGNAL( wroteToStdin() ),    this, SLOT( wroteToStdin() ) );
 
   // create validation thread
-  myThread = new QProcessThread( this );
+  myThread = new ProcessThread( this );
 }
 // ================================================================
 /*!
@@ -687,7 +733,7 @@ void SALOME_InstallWizard::setupProgressPage()
   QGridLayout* layout = new QGridLayout( widget ); 
   layout->setMargin( 0 ); layout->setSpacing( 6 );
   // installation progress view box
-  installInfo = new QTextEdit( widget );
+  installInfo = new InstallInfo( widget );
   installInfo->setReadOnly( true );
   installInfo->setTextFormat( RichText );
   installInfo->setUndoRedoEnabled ( false );
@@ -747,7 +793,7 @@ void SALOME_InstallWizard::setupReadmePage()
   readme = new QTextEdit( readmePage );
   readme->setReadOnly( true );
   readme->setTextFormat( PlainText );
-  readme->setFont( QFont( "Fixed", 10 ) );
+  readme->setFont( QFont( "Fixed", 12 ) );
   readme->setUndoRedoEnabled ( false );
   QWhatsThis::add( readme, tr( "Displays README information" ) );
   QToolTip::add  ( readme, tr( "Displays README information" ) );
@@ -797,16 +843,16 @@ void SALOME_InstallWizard::showChoiceInfo()
     text += "<br>";
   }
   if ( !myOS.isEmpty() ) {
-    text += tr( "Target platform" ) + ": <b>" + myOS + "</b><br>";
+    text += tr( "Reference Linux platform" ) + ": <b>" + myOS + "</b><br>";
     text += "<br>";
   }
-  text += tr( "Products to be used" ) + ":<ul>";
+  text += tr( "Native products to be used" ) + ":<ul>";
   QCheckListItem* item = (QCheckListItem*)( productsView->firstChild() );
   while( item ) {
     if ( productsMap.contains( item ) ) {
       if ( item->childCount() > 0 ) {
         if ( productsView->isNative( item ) ) {
-          text += "<li><b>" + item->text() + "</b> " + tr( "as native" ) + "<br>";
+          text += "<li><b>" + item->text() + "</b><br>";
           nbProd++;
         }
       }
@@ -824,11 +870,11 @@ void SALOME_InstallWizard::showChoiceInfo()
     if ( productsMap.contains( item ) ) {
       if ( item->childCount() > 0 ) {
         if ( productsView->isBinaries( item ) ) {
-          text += "<li><b>" + item->text() + "</b> " + tr( "as binaries" ) + "<br>";
+          text += "<li><b>" + item->text() + " " + item->text(1) + "</b> " + tr( "as binaries" ) + "<br>";
           nbProd++;
         }
         else if ( productsView->isSources( item ) ) {
-          text+= "<li><b>" + item->text() + "</b> " + tr( "as sources" ) + "<br>";
+          text+= "<li><b>" + item->text() + " " + item->text(1) + "</b> " + tr( "as sources" ) + "<br>";
           nbProd++;
         }
       }
@@ -850,7 +896,7 @@ void SALOME_InstallWizard::showChoiceInfo()
   // VSR: Temporary folder is used always now and it is not necessary to disable it -->
   // if ( tempSize > 0 )
   // VSR: <----------------------------------------------------------------------------
-  text += tr( "Temp directory:" ) + " <b>" + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + "</b><br>";
+  text += tr( "Temporary directory:" ) + " <b>" + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + "</b><br>";
   text += "<br>";
   choices->setText( text );
 }
@@ -907,7 +953,7 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
        QMessageBox::warning( this, 
                              tr( "Warning" ), 
                              tr( "The directory %1 doesn't exist.\n"
-                                 "Do you want to create directory?" ).arg( fi.absFilePath() ), 
+                                 "Create directory?" ).arg( fi.absFilePath() ), 
                              QMessageBox::Yes, 
                              QMessageBox::No,
                              QMessageBox::NoButton ) == QMessageBox::Yes;
@@ -926,7 +972,7 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
     if ( !fi.isDir() ) {
       QMessageBox::warning( this, 
                             tr( "Warning" ), 
-                            tr( "The directory %1 is not a directory.\n"
+                            tr( "%1 is not a directory.\n"
                                "Please, enter valid target directory path" ).arg( fi.absFilePath() ), 
                             QMessageBox::Ok, 
                             QMessageBox::NoButton,
@@ -973,7 +1019,7 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
     if ( system( script ) ) {
       QMessageBox::critical( this, 
                              tr( "Out of space" ), 
-                             tr( "There is not available disk space for installing of selected products" ), 
+                             tr( "There is no available disk space for installing of selected products" ), 
                              QMessageBox::Ok, 
                              QMessageBox::NoButton, 
                              QMessageBox::NoButton );
@@ -984,7 +1030,7 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
       if ( moreMode ) {
        QMessageBox::warning( this, 
                              tr( "Warning" ), 
-                             tr( "Please, enter valid temp directory path" ), 
+                             tr( "Please, enter valid temporary directory path" ), 
                              QMessageBox::Ok, 
                              QMessageBox::NoButton,
                              QMessageBox::NoButton );
@@ -1015,7 +1061,7 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
     if ( system( tscript ) ) {
       QMessageBox::critical( this, 
                             tr( "Out of space" ), 
-                            tr( "There is not available disk space for the temporary files" ), 
+                            tr( "There is no available disk space for the temporary files" ), 
                             QMessageBox::Ok, 
                             QMessageBox::NoButton, 
                             QMessageBox::NoButton );
@@ -1028,11 +1074,12 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
     while( item ) {
       if ( productsMap.contains( item ) ) {
        if ( item->childCount() > 0 ) {
-         if ( !productsView->isNone( item ) ) {
+         // VSR : 29/01/05 : Check installation script even if product is not being installed
+         //      if ( !productsView->isNone( item ) ) {
            if ( item->text(2).isEmpty() || item->text(2).isNull() ) {
              QMessageBox::warning( this, 
                                    tr( "Error" ), 
-                                   tr( "You don't have a defined script for %1").arg(item->text(0)), 
+                                   tr( "The installation script for %1 is not defined.").arg(item->text(0)), 
                                    QMessageBox::Ok, 
                                    QMessageBox::NoButton, 
                                    QMessageBox::NoButton );
@@ -1045,10 +1092,10 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
              return false;
            } else {
              QFileInfo fi( QString("./config_files/") + item->text(2) );
-             if ( !fi.exists() ) {
+             if ( !fi.exists() || !fi.isExecutable() ) {
                QMessageBox::warning( this, 
                                      tr( "Error" ),  
-                                     tr( "%1 required for %2 doesn't exist.").arg("./config_files/" + item->text(2)).arg(item->text(0)),  
+                                     tr( "The script %1 required for %2 doesn't exist or doesn't have execute permissions.").arg("./config_files/" + item->text(2)).arg(item->text(0)),  
                                      QMessageBox::Ok, 
                                      QMessageBox::NoButton, 
                                      QMessageBox::NoButton );
@@ -1061,7 +1108,7 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
                return false;
              }       
            }
-         }
+           //    }
          // collect native products
          if ( productsView->isNative( item ) ) {
            if ( natives.find( item->text(0) ) == natives.end() )
@@ -1077,9 +1124,9 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
              } 
              else {
                QMessageBox::warning( this, 
-                                     tr( "Warning" ), 
+                                     tr( "Error" ), 
                                      tr( "%1 is required for %2 %3 installation.\n"
-                                         "Please, add this product in config.xml file.").arg(dependOn[ i ]).arg(item->text(0)).arg(item->text(1)), 
+                                         "This product is missing in the configuration file %4.").arg(dependOn[ i ]).arg(item->text(0)).arg(item->text(1)).arg(xmlFileName), 
                                      QMessageBox::Ok, 
                                      QMessageBox::NoButton, 
                                      QMessageBox::NoButton );
@@ -1109,7 +1156,7 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
          QMessageBox::warning( this, 
                                tr( "Warning" ), 
                                tr( "%The product %1 %2 required for installation.\n"
-                                   "Please, add this product in config.xml file.").arg(item->text(0)).arg(item->text(1)),
+                                   "This product is missing in the configuration file %4.").arg(item->text(0)).arg(item->text(1)).arg(xmlFileName),
                                QMessageBox::Ok, 
                                QMessageBox::NoButton, 
                                QMessageBox::NoButton );
@@ -1366,6 +1413,7 @@ void SALOME_InstallWizard::launchScript()
   passedParams->clear();
   passedParams->setEnabled( false );
   QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
+  installInfo->setFinished( true );
   if ( isMinimized() )
     showNormal();
   raise();
@@ -1410,15 +1458,15 @@ void SALOME_InstallWizard::onLaunchSalome()
   QCheckListItem* item = findItem( "KERNEL-Bin" );
   if ( item ) {
     QFileInfo fi( targetFolder->text() + "/KERNEL_" + item->text(1) + "/bin/salome/runSalome" );
-    QFileInfo fienv( targetFolder->text() + "/KERNEL_" + item->text(1) + "/salome.csh" );
+    QFileInfo fienv( targetFolder->text() + "/KERNEL_" + item->text(1) + "/salome.sh" );
     if ( fienv.exists() ) {
       if ( fi.exists() ) {
        QString script;
        script += "cd " + targetFolder->text() + "/KERNEL_" + item->text(1) + "; ";
-       script += "source salome.csh; ";
+       script += "source salome.sh; ";
        script += "cd bin/salome; ";
        script += "runSalome > /dev/null";
-       script = "(csh -c '" + script + "')";
+       script = "(bash -c '" + script + "')";
        ___MESSAGE___( "script: " << script.latin1() );
        if ( !system( script.latin1() ) )
          return;
@@ -1575,6 +1623,7 @@ void SALOME_InstallWizard::pageChanged( const QString & mytitle)
       // progress page
       progressView->clear();
       installInfo->clear();
+      installInfo->setFinished( false );
       passedParams->clear();
       passedParams->setEnabled( false );
       QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
@@ -1667,6 +1716,17 @@ void SALOME_InstallWizard::directoryChanged( const QString& /*text*/ )
 // ================================================================
 void SALOME_InstallWizard::onStart()
 {
+  if ( nextButton()->text() == tr( "&Stop" ) ) {
+    shellProcess->kill();
+    while( shellProcess->isRunning() );
+    return;
+  }
+  progressView->clear();
+  installInfo->clear();
+  installInfo->setFinished( false );
+  passedParams->clear();
+  passedParams->setEnabled( false );
+  QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
   // clear list of products to install ...
   toInstall.clear();
   // ... and fill it for new process
@@ -1682,7 +1742,10 @@ void SALOME_InstallWizard::onStart()
   if ( !toInstall.isEmpty() ) {
     clean(false); // VSR 07/02/05 - bug fix: first we should clear temporary directory
     // disable <Next> button
-    setNextEnabled( false );
+    //setNextEnabled( false );
+    nextButton()->setText( tr( "&Stop" ) );
+    QWhatsThis::add( nextButton(), tr( "Aborts installation process" ) );
+    QToolTip::add  ( nextButton(), tr( "Aborts installation process" ) );
     // disable <Back> button
     setBackEnabled( false );
     // enable script parameters line edit
@@ -1742,14 +1805,22 @@ void SALOME_InstallWizard::productInstalled( )
     passedParams->clear();
     passedParams->setEnabled( false );
     QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
+    installInfo->setFinished( true );
     // enable <Next> button
     setNextEnabled( true );
-    nextButton()->setText( tr( "&Next >" ) );
-    QWhatsThis::add( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
-    QToolTip::add  ( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
+    nextButton()->setText( tr( "&Start" ) );
+    QWhatsThis::add( nextButton(), tr( "Starts installation process" ) );
+    QToolTip::add  ( nextButton(), tr( "Starts installation process" ) );
+    // reconnect Next button - to use it as Start button
     disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
     disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
-    connect(    this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
+    connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+    //nextButton()->setText( tr( "&Next >" ) );
+    //QWhatsThis::add( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
+    //QToolTip::add  ( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
+    //disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
+    //disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+    //connect(    this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
     // enable <Back> button
     setBackEnabled( true );
   }
@@ -2005,6 +2076,41 @@ void SALOME_InstallWizard::polish()
   InstallWizard::polish();
 }
 // ================================================================
+/*!
+ *  SALOME_InstallWizard::saveLog
+ *  Save installation log to file
+ */
+// ================================================================
+void SALOME_InstallWizard::saveLog()
+{
+  QString txt = installInfo->text();
+  if ( txt.length() <= 0 )
+    return;
+  QDateTime dt = QDateTime::currentDateTime();
+  QString fileName = dt.toString("ddMMyy-hhmm");
+  fileName.prepend("install-"); fileName.append(".html");
+  fileName = QFileDialog::getSaveFileName( fileName,
+                                          QString( "HTML files (*.htm *.html)" ),
+                                          this, 0,
+                                          tr( "Save Log file" ) );
+  if ( !fileName.isEmpty() ) {
+    QFile f( fileName );
+    if ( f.open( IO_WriteOnly ) ) {
+      QTextStream stream( &f );
+      stream << txt;
+      f.close();
+    }
+    else {
+      QMessageBox::critical( this, 
+                            tr( "Error" ), 
+                            tr( "Can't save file %1.\nCheck path and permissions.").arg( fileName ), 
+                            QMessageBox::Ok, 
+                            QMessageBox::NoButton, 
+                            QMessageBox::NoButton );
+    }
+  }
+}
+// ================================================================
 /*!
  *  SALOME_InstallWizard::updateCaption
  *  Updates caption according to the current page number
index dd9e4d76a706851baef3ea376d44ddf771ee95ca..37800cdc8b7f6d7a2155ee45cd70ebd844b7728d 100644 (file)
@@ -97,10 +97,11 @@ class QProcess;
 class QCheckBox;
 class QSplitter;
 class QMyCheckBox;
-class QProcessThread;
+class ProcessThread;
 class ProductsView;
 class ProgressView;
 class HelpWindow;
+class InstallInfo;
 
 typedef QMap<QCheckListItem*, Dependancies> MapProducts;
 
@@ -153,6 +154,9 @@ class SALOME_InstallWizard: public InstallWizard
   QString getOS() { return myOS; }
   // get InstallWizard's name
   QString getIWName() { return myIWName; }
+  
+  // save install log to file
+  void saveLog();
 
  protected:
   // updates caption according to the current page number
@@ -235,63 +239,63 @@ class SALOME_InstallWizard: public InstallWizard
   void readFromStderr();
 
  private:
-  QString       myIWName;       // Installation Wizard's name
-  QString       myVersion;      // version info
-  QString       myCaption;      // application name
-  QString       myCopyright;    // copyright info 
-  QString       myLicense;      // license info
-  QString       myOS;           // operation system
+  QString          myIWName;       // Installation Wizard's name
+  QString          myVersion;      // version info
+  QString          myCaption;      // application name
+  QString          myCopyright;    // copyright info 
+  QString          myLicense;      // license info
+  QString          myOS;           // operation system
   
-  HelpWindow*   helpWindow;     // help window
-  QProcess*     shellProcess;   // shell process (install script)
-  MapProducts   productsMap;    // products info (name, dependancies, disk space )
-  QStringList   toInstall;      // list of products being installed
-  QString       xmlFileName;    // xml file
-  bool          moreMode;       // advanced mode flag
-  QWidget*      previousPage;   // previous page
-  QString       tmpCreated;     // created temporary directory
-  bool          exitConfirmed;  // flag: "Exit confirmed"
+  HelpWindow*      helpWindow;     // help window
+  QProcess*        shellProcess;   // shell process (install script)
+  MapProducts      productsMap;    // products info (name, dependancies, disk space )
+  QStringList      toInstall;      // list of products being installed
+  QString          xmlFileName;    // xml file
+  bool             moreMode;       // advanced mode flag
+  QWidget*         previousPage;   // previous page
+  QString          tmpCreated;     // created temporary directory
+  bool             exitConfirmed;  // flag: "Exit confirmed"
   // Widgets
   // --> introduction page
-  QWidget*      introPage;      // page itself
-  QLabel*       logoLab;        // logo pixmap
-  QLabel*       versionLab;     // vesrsion info
-  QLabel*       copyrightLab;   // copyright info
-  QLabel*       licenseLab;     // license info
-  QLabel*       info;           // program info
+  QWidget*         introPage;      // page itself
+  QLabel*          logoLab;        // logo pixmap
+  QLabel*          versionLab;     // vesrsion info
+  QLabel*          copyrightLab;   // copyright info
+  QLabel*          licenseLab;     // license info
+  QLabel*          info;           // program info
   // --> products page
-  QWidget*      productsPage;   // page itself
-  QLineEdit*    targetFolder;   // target directory for installing of products
-  QPushButton*  targetBtn;      // browse target directory button
-  QLineEdit*    tempFolder;     // directory for the temporary files: /tmp by default
-  QPushButton*  tempBtn;        // browse temp directory button
-  QLabel*       requiredSize;   // <Total disk space required> label
-  QLabel*       requiredTemp;   // <Space required for temporary files> label
-  QPushButton*  moreBtn;        // <More...> button
-  QWidget*      moreBox;        // container for the <More...> mode widgets
-  ProductsView* productsView;   // products list view
-  QTextBrowser* productsInfo;   // products info box
-  QCheckBox*    prerequisites;  // <Auto check prerequisites products> checkbox
-  QMyCheckBox*  selectSrcBtn;   // <SALOME sources> check box 
-  QMyCheckBox*  selectBinBtn;   // <SALOME binaries> check box 
-  QPushButton*  unselectBtn;    // <Unselect All> button
+  QWidget*         productsPage;   // page itself
+  QLineEdit*       targetFolder;   // target directory for installing of products
+  QPushButton*     targetBtn;      // browse target directory button
+  QLineEdit*       tempFolder;     // directory for the temporary files: /tmp by default
+  QPushButton*     tempBtn;        // browse temp directory button
+  QLabel*          requiredSize;   // <Total disk space required> label
+  QLabel*          requiredTemp;   // <Space required for temporary files> label
+  QPushButton*     moreBtn;        // <More...> button
+  QWidget*         moreBox;        // container for the <More...> mode widgets
+  ProductsView*    productsView;   // products list view
+  QTextBrowser*    productsInfo;   // products info box
+  QCheckBox*       prerequisites;  // <Auto check prerequisites products> checkbox
+  QMyCheckBox*     selectSrcBtn;   // <SALOME sources> check box 
+  QMyCheckBox*     selectBinBtn;   // <SALOME binaries> check box 
+  QPushButton*     unselectBtn;    // <Unselect All> button
   // --> prestart page
-  QWidget*      prestartPage;   // page itself
-  QTextEdit*    choices;        // choice text view
+  QWidget*         prestartPage;   // page itself
+  QTextEdit*       choices;        // choice text view
   // --> progress page
-  QWidget*      progressPage;   // page itself
-  QSplitter*    splitter;       // splitter window
-  QTextEdit*    installInfo;    // information about running installation scripts
-  QLabel*       parametersLab;  // answer field's label
-  QLineEdit*    passedParams;   // user can pass data to running script
-  QTextEdit*    installProgress;// contains information about progress of installing selected products
-  ProgressView* progressView;   // displays information about progress of installing selected products
+  QWidget*         progressPage;   // page itself
+  QSplitter*       splitter;       // splitter window
+  InstallInfo*     installInfo;    // information about running installation scripts
+  QLabel*          parametersLab;  // answer field's label
+  QLineEdit*       passedParams;   // user can pass data to running script
+  QTextEdit*       installProgress;// contains information about progress of installing selected products
+  ProgressView*    progressView;   // displays information about progress of installing selected products
   // --> readme page
-  QWidget*      readmePage;     // page itself
-  QTextEdit*    readme;         // Readme information window
-  QPushButton*  runSalomeBtn;   // <Launch Salome> buttnon
+  QWidget*         readmePage;     // page itself
+  QTextEdit*       readme;         // Readme information window
+  QPushButton*     runSalomeBtn;   // <Launch Salome> buttnon
 
-  QProcessThread* myThread;     // validation thread
+  ProcessThread*   myThread;       // validation thread
 };
 
 #endif
index cb6868bcc45a27bd4abc2971329e6fc3a33fd9ca..1a7c36941ce47450c498833811285942d7975779 100644 (file)
 // ========================
 
 #include <qglobal.h>
+#include <iostream>
 
 #ifdef QT_DEBUG
 
-#define ___MESSAGE___( x ) cout << x << endl;
+#define ___MESSAGE___( x ) std::cout << x << std::endl;
 
 #else
 
index 63cfd193db20d3bb4df6020c685743591e55ea62..e828213558a23c3756e3b589989752a186fd5ce1 100644 (file)
 #include <qfile.h>
 #include <qmessagebox.h>
 
+#define __IW_VERSION__ 0x010000
+
 // ================================================================
 /*!
  *  MessageOutput
  *  Qt's messages handler funcion
  */
 // ================================================================
-void MessageOutput( QtMsgType type, const char *msg )
+void MessageOutput( QtMsgType type, 
+#ifdef QT_DEBUG
+                   const char* msg
+#else
+                   const char*
+#endif
+                   )
 {
   switch ( type ) {
   case QtDebugMsg:
@@ -42,10 +50,30 @@ void MessageOutput( QtMsgType type, const char *msg )
 int main( int argc, char **argv )
 {
   qInstallMsgHandler( MessageOutput );
+
+  QString xmlFileName;
+  for( int i = 1; i < argc; i++ ) {
+    QString a = QString( argv[i] );
+    if ( a == "--version" || a == "-v" ) {
+      printf("SALOME Installation Wizard version %d.%d.%d ",
+            ( __IW_VERSION__ >> 16 ) & 0xFF,
+            ( __IW_VERSION__ >>  8 ) & 0xFF,
+            ( __IW_VERSION__       ) & 0xFF );
+      printf("(Qt version %d.%d.%d)\n",
+            ( QT_VERSION >> 16 ) & 0xFF,
+            ( QT_VERSION >> 8  ) & 0xFF,
+            ( QT_VERSION       ) & 0xFF );
+      return 0;
+    }
+    if ( xmlFileName.isEmpty() )
+      xmlFileName = a;
+  }
+  if ( xmlFileName.isEmpty() )
+    xmlFileName = "config.xml";
+
   QApplication a( argc, argv );
-  a.setFont( QFont("Helvetica", 9 ) );
-  QString xmlFileName( argc == 2 ? argv[1] : "config.xml" );
-  
+  a.setFont( QFont( "Sans", 12 ) );
+
   int result = -1;
   QFile xmlfile(xmlFileName);
   if ( xmlfile.exists() ) {