]> SALOME platform Git repositories - tools/install.git/commitdiff
Salome HOME
Improve Installation Wizard:
authorvsr <vsr@opencascade.com>
Thu, 9 Mar 2006 09:06:56 +0000 (09:06 +0000)
committervsr <vsr@opencascade.com>
Thu, 9 Mar 2006 09:06:56 +0000 (09:06 +0000)
- introduce new runInstall script (support command line options in POSIX standard);
- provide version information
- provide About dialog box
- pass 'targe directory' and 'temp directory' parameters from command line to the GUI IW

bin/SALOME_InstallWizard
runInstall
src/InstallWizard.cpp
src/InstallWizard.h
src/Makefile
src/SALOME_InstallWizard.cxx
src/SALOME_InstallWizard.hxx
src/globals.h
src/icons.cxx
src/icons.h
src/main.cxx

index dba449bf19f9266ff0fa1d25cbb1ed2fde09a840..b11011676bbde12f94264969ae8d1fa35bc2fb2a 100755 (executable)
Binary files a/bin/SALOME_InstallWizard and b/bin/SALOME_InstallWizard differ
index 4a4796f8ec9d49e96befea1d3991293ccbfef473..8472253292766371dd5ec51a0d31aa59767c2dd4 100755 (executable)
 #!/usr/bin/env python
 
+"""
+Installation Wizard launching script.
+"""
+
+__version__ = "1.0.1"
+
+# --- avoid "deprecation" warnings --- #
 import warnings
 warnings.filterwarnings("ignore", "", DeprecationWarning)
 
+# --- imports --- #
 import xmllib
 import sys, os, string, re
-from optparse import OptionParser
+import types
+import random
 
+# --- global variables --- #
 opt_parser = None
 root_path  = None
 
+# --- XML tags definition --- #
 __TAG__SOURCES__    = "install sources"
 __TAG__BINARIES__   = "install binaries"
 __TAG__NATIVE__     = "use native"
 __TAG__PREINSTALL__ = "not install"
 
-#==============================================================
-# class Product 
-#==============================================================
+#------------------------------------------------------------------#
+#                                                                  #
+#                 COMMAND LINE ARGUMENTS PARSER                    #
+#                                                                  #
+#------------------------------------------------------------------#
 
-class Product :
-    def __init__(self,
-                 theName,
-                 theVersion            = None,
-                 theInstall            = None,
-                 theSupportred         = None,
-                 theDependencies       = None,
-                 theInstalldiskspace   = None,
-                 theTemporarydiskspace = None,
-                 theScript             = None,
-                 thePickUpEnvironment  = None):
-        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 OptBaseError : base parse error
+#===================================================================
+class OptBaseError(Exception):
+    """
+    Base option parsing exception class
+    """
+    def __init__(self, msg):
+        self.msg = msg
+    def __str__ (self):
+        return self.msg
+
+#===================================================================
+# class OptError : bad option error
+#===================================================================
+class OptError(OptBaseError):
+    """
+    Bad option exception class
+    """
+    def __init__ (self, msg, option):
+        self.msg = msg
+        self.option = option
+    def __str__ (self):
+        if self.option:
+            opt_prs = "<unknown>"
+            if self.option.short_opt and self.option.long_opt:
+                opt_prs = "%s/%s"%(self.option.short_opt,self.option.long_opt)
+            elif self.option.short_opt:
+                opt_prs = "%s"%(self.option.short_opt)
+            elif self.option.long_opt:
+                opt_prs = "%s"%(self.option.long_opt)
+            return "option %s: %s"%(opt_prs, self.msg)
+        return self.msg
+
+#===================================================================
+# class ArgError : bad option argument error
+#===================================================================
+class ArgError(OptBaseError):
+    """
+    Bad argument exception class
+    """
+    pass
+
+#===================================================================
+# class ValError : bad command line parameter error
+#===================================================================
+class ValError(OptBaseError):
+    """
+    Bad parameter exception class
+    """
+    pass
+
+#===================================================================
+# class ArgOption : command line option
+#===================================================================
+class ArgOption:
+    """
+    Option class
+    """
+    attrs   = ["short_opt", "long_opt", "dest", "action", "type", "default", "metavar", "help"]
+    actions = ["store", "store_true", "store_false"]
+    types   = ["string", "int", "float", "bool"]
+    def __init__(self, *args, **kwargs):
+        # set defaults
+        for attr in self.attrs: setattr(self, attr, None)
+        # parse arguments
+        for i in range(len(args)):
+            if i > len(self.attrs)-1:
+                msg = "Wrong number of parameters is given (maximum is %d)" % len(self.attrs)
+                raise OptBaseError(msg)
+            setattr(self, self.attrs[i], args[i])
+        for arg in kwargs:
+            if arg not in self.attrs:
+                msg = "Invalid argument: %s" % arg
+                raise OptBaseError(msg)
+            setattr(self, arg, kwargs[arg])
+        # check short option key
+        if self.short_opt and \
+               not re.match("^-[a-zA-Z]$",self.short_opt):
+            msg  = "invalid short option key; "
+            msg += "should be of the form -x (x is letter)"
+            raise OptError(msg, self)
+        # check long option key
+        if self.long_opt and \
+               not re.match("^--[a-zA-Z][a-zA-Z0-9]*(-[a-zA-Z0-9]+)*$",self.long_opt):
+            msg  = "invalid long option key; "
+            msg += "should be of the form --word[[-word]...] "
+            msg += "(word is letters and digits sequence)"
+            raise OptError(msg, self)
+        # check that at least one option key is defined
+        if not self.short_opt and not self.long_opt:
+            msg  = "invalid option; neither short nor long option key is defined"
+            raise OptError(msg, self)
+        # destination
+        if not self.dest and self.long_opt:
+            self.dest = self.long_opt[2:].replace('-','_')
+        if not self.dest and self.short_opt:
+            self.dest = self.short_opt[1:]
+        # action
+        if not self.action:
+            self.action = "store"
+        if self.action not in self.actions:
+            msg  = "invalid action: %s" % self.action
+            raise OptError(msg, self)
+        # type
+        if not self.type:
+            if self.action in ["store_true","store_false"]: self.type = "bool"
+            else: self.type = "string"
+        if self.type not in self.types:
+            msg  = "invalid type: %s" % self.type
+            raise OptError(msg, self)
+        if self.action in ["store_true","store_false"] and self.type != "bool":
+            msg  = "invalid type: %s : should be 'bool' or None" % self.type
+            raise OptError(msg, self)
+        # default
+        if self.default:
+            try:
+                if self.type == "string": self.default = str(self.default)
+                if self.type == "int":    self.default = int(self.default)
+                if self.type == "float":  self.default = float(self.default)
+                if self.type == "bool":   self.default = boolean(self.default)
+            except :
+                msg  = "invalid default value type: should be %s" % self.type
+                raise OptError(msg, self)
+            pass
+        # metavar
+        if not self.metavar:
+            self.metavar = self.dest.upper()
+        # help
+        if not self.help:
+            self.help = ""
+        pass
 
+    def to_string(self):
+        """
+        Returns string representation of the option
+        """
+        opts = []
+        opt = self.short_opt
+        if opt and self.action == "store" and self.metavar: opt += " %s" % self.metavar
+        if opt: opts.append(opt)
+        opt = self.long_opt
+        if opt and self.action == "store" and self.metavar: opt += "=%s" % self.metavar
+        if opt: opts.append(opt)
+        return (", ").join(opts)
+    
+#===================================================================
+# class Values : resulting option values
+#===================================================================
+class Values:
+    """
+    Values class
+    """
+    def __init__(self):
+        pass
+        
 #===================================================================
-# class Config
+# class ArgParser : command line arguments parser
+#===================================================================
+class ArgParser:
+    """
+    Arguments parser class
+    """
+    def __init__(self):
+        self.options = []
+        pass
+
+    def add_option(self, *args, **kwargs):
+        """Register an option"""
+        o = ArgOption(*args, **kwargs)
+        self._check_option(o)
+        self.options.append(o)
+        pass
+
+    def parse_args(self, args = None):
+        """Parse an arguments"""
+        if not args: args = sys.argv[1:]
+        values = Values()
+        for o in self.options:
+            if o.default:
+                setattr(values, o.dest, o.default)
+            elif not hasattr(values,o.dest):
+                setattr(values, o.dest, None)
+        try:
+            (values, args) = self._process_args(values, args)
+        except (ArgError, ValError), e:
+            self._error(e.msg)
+
+        return (values, args)
+            
+    def print_usage(self):
+        """Print usage"""
+        print "usage: %s [options]" % os.path.basename(sys.argv[0])
+        pass
+
+    def print_help(self):
+        """Print help"""
+        self.print_usage()
+        print ""
+        olen = 0
+        _maxwidth, _indent = 79, 2
+        if len(self.options):
+            for option in self.options:
+                if olen < len(option.to_string()): olen = len(option.to_string())
+            print "options:"
+            for option in self.options:
+                strings = []
+                for hs in option.help.split("\n"):
+                    s = ""
+                    for w in hs.split():
+                        if len("%s %s" % (s,w)) > _maxwidth:
+                            strings.append(s.strip()); s = ""
+                        s = "%s %s" % (s,w)
+                    if s.strip(): strings.append(s.strip())
+                if not strings: strings[:0] = [""]
+                print "%s%s%s" % (option.to_string(), " "*(_indent+olen-len(option.to_string())), strings[0])
+                for i in range(1, len(strings)):
+                    print "%s%s" % (" "*(olen+_indent), strings[i])
+        pass
+    
+    def _check_option(self, option):
+        o = self._get_option(option.short_opt)
+        if not o: o = self._get_option(option.long_opt)
+        if o:
+            msg = "option conflicts with previously defined option(s)"
+            raise OptError(msg, option)
+        pass
+
+    def _get_option(self, opt_key):
+        if opt_key:
+            for o in self.options:
+                if opt_key in [o.short_opt, o.long_opt]: return o
+        return None
+        
+    def _error(self, msg):
+        self.print_usage()
+        sys.exit("\n%s: error: %s\n" % (os.path.basename(sys.argv[0]), msg))
+        pass
+
+    def _check_value(self, option, value):
+        o = self._get_option(option)
+        try:
+            if o.type == "string": return str(value)
+            if o.type == "int":    return int(value)
+            if o.type == "float":  return float(value)
+            if o.type == "bool":   return boolean(value)
+        except:
+            msg  = "invalid value type for option %s: %s; " % (option, value)
+            msg += "should be %s" % o.type
+            raise ValError(msg)
+        raise OptBaseError("unknown error")
+
+    def _process_args(self, values, args):
+        res_args = []
+        cur_opt = None
+        rargs   = []
+        for index in range(len(args)):
+            a = args[index]
+            if cur_opt and cur_opt[1].action == "store":
+                setattr(values, cur_opt[1].dest, self._check_value(cur_opt[0], a))
+                cur_opt = None
+                continue
+            if a == "-":
+                rargs = args[index+1:]
+                break
+            elif re.match("^-[a-zA-Z].*", a):
+                for i in range(1,len(a)):
+                    if cur_opt and cur_opt[1].action == "store":
+                        setattr(values, cur_opt[1].dest, self._check_value(cur_opt[0], a[i:]))
+                        cur_opt = None
+                        break
+                    o = self._get_option("-%s"%a[i])
+                    if not o:
+                        raise ArgError("no such option: -%s"%a[i])
+                    if o.action == "store_true":
+                        setattr(values, o.dest, True)
+                    elif o.action == "store_false":
+                        setattr(values, o.dest, False)
+                    else:
+                        cur_opt = ("-%s"%a[i], o)
+                pass
+            elif re.match("^--[a-zA-Z][a-zA-Z0-9]*(-[a-zA-Z0-9]+)*", a):
+                oname  = ("%s="%a).split("=")[0]
+                ovalue = ("%s="%a).split("=")[1]
+                o = self._get_option(oname)
+                if not o:
+                    raise ArgError("no such option: %s" % oname)
+                if o.action == "store_true":
+                    if ovalue:
+                        raise ValError("option %s does not take a value" % oname)
+                    setattr(values, o.dest, True)
+                elif o.action == "store_false":
+                    if ovalue:
+                        raise ValError("option %s does not take a value" % oname)
+                    setattr(values, o.dest, False)
+                else:
+                    if ovalue:
+                        setattr(values, o.dest, self._check_value(oname, ovalue))
+                    else:
+                        cur_opt = (oname, o)
+                pass
+            elif a.startswith("-"):
+                raise ArgError("bad formatted option: %s" % a)
+            else:
+                rargs = args[index:]
+                break
+        if cur_opt and cur_opt[1].action == "store":
+            raise ValError("option %s requires value" % cur_opt[0])
+        return (values, rargs)
+
+#------------------------------------------------------------------#
+#                                                                  #
+#                 XML CONFIGURATION FILES PARSER                   #
+#                                                                  #
+#------------------------------------------------------------------#
+
+#===================================================================
+# class Config : general configuration options : version, OS, etc...
 #===================================================================
 class Config :
+    """
+    General configuration file options:
+    - Install Wizard window caption
+    - SALOME platform version
+    - Copyright and libcense info
+    - Target Linux OS version
+    """
     def __init__(self,
                  theVersion   = None,
                  theCaption   = None,
@@ -57,19 +372,60 @@ class Config :
         self.os        = strip(theOS)
 
 #===================================================================
-# class Path
+# class Path : default target, temporary directories options
 #===================================================================
 class Path :
+    """
+    Path options:
+    - default target directory
+    - default temporary directory
+    """
     def __init__(self,
                  theTargetdir = None,
                  theTmpdir    = None):
         self.targetdir = strip(theTargetdir)
         self.tmpdir    = strip(theTmpdir)
         
+#==============================================================
+# class Product : pre-requisite product options
+#==============================================================
+class Product :
+    """
+    Product options:
+    - name, version
+    - supported installation modes and the default one
+    - dependencies
+    - required disk space
+    - installation script
+    - etc...
+    """
+    def __init__(self,
+                 theName,
+                 theVersion            = None,
+                 theInstall            = None,
+                 theSupportred         = None,
+                 theDependencies       = None,
+                 theInstalldiskspace   = None,
+                 theTemporarydiskspace = None,
+                 theScript             = None,
+                 thePickUpEnvironment  = None):
+        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 ConfigParser
+# class ConfigParser : XML files parser implementation
 #===================================================================
 class ConfigParser(xmllib.XMLParser):
+    """
+    XML configuration files parser
+    """
     def __init__(self):
         xmllib.XMLParser.__init__(self)
         self.products = []
@@ -123,10 +479,19 @@ class ConfigParser(xmllib.XMLParser):
                 return product
         return None
 
+#------------------------------------------------------------------#
+#                                                                  #
+#                         SERVICE FUNCTIONS                        #
+#                                                                  #
+#------------------------------------------------------------------#
+
 #==============================================================
 # message: prints diagnostic information
 #==============================================================
 def message(msg):
+    """
+    Prints diagnostic information.
+    """
     if msg.strip():
         print ">>>", msg
     pass
@@ -135,6 +500,9 @@ def message(msg):
 # warning: prints warning
 #==============================================================
 def warning(msg):
+    """
+    Prints warning.
+    """
     if msg.strip():
         print ""
         print msg
@@ -146,6 +514,10 @@ def warning(msg):
 #              help information and quits
 #==============================================================
 def error_exit(msg = "", print_help = True):
+    """
+    Prints (optionally) error string,
+    then prints help information and quits.
+    """
     # print error message
     if len(msg.strip()):
         print ""
@@ -163,10 +535,40 @@ def error_exit(msg = "", print_help = True):
     sys.exit(1);
     pass
 
+#==============================================================
+# boolean : Converts string to boolean value.
+#==============================================================
+def boolean(val):
+    """
+    Converts string to boolean value if possible.
+    Raises exception if wrong string is used.
+    """
+    if isinstance(val, types.StringType):
+        if val.strip().lower()   in ["true",  "yes", "ok"]     : return True
+        elif val.strip().lower() in ["false", "no",  "cancel"] : return False
+        else: raise TypeError("invalid boolean value")
+    return bool(val)
+
+#=================================================================
+# check_bool : checks boolean value: yes/no, true/false, 1/0
+#=================================================================
+def check_bool(val):
+    """
+    Checks boolean value.
+    """
+    try:
+        return boolean(val)
+    except:
+        pass
+    return False
+
 #==============================================================
 # clean_all : performs system cleaning before exiting
 #==============================================================
 def clean_all():
+    """
+    Performs system cleaning before exiting.
+    """
     global root_path
     remove_dir(root_path)
     pass
@@ -175,11 +577,13 @@ def clean_all():
 # parse_parameters : parses command line arguments
 #==============================================================
 def parse_parameters():
+    """
+    Parses command line arguments.
+    """
     global opt_parser
-    opt_parser = OptionParser(add_help_option=False)
+    opt_parser = ArgParser()
+    
     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",
@@ -195,7 +599,7 @@ def parse_parameters():
     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 += "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."
@@ -214,7 +618,7 @@ def parse_parameters():
                           dest="target_dir",
                           metavar="DIR",
                           help=help_str)
-    help_str  = "The directory used for temporary files.\n"
+    help_str  = "The directory to be 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",
@@ -223,12 +627,12 @@ def parse_parameters():
                           dest="tmp_dir",
                           metavar="DIR",
                           help=help_str)
-    help_str  = "Prints this help and quits."
+    help_str  = "Prints version information and quits."
     opt_parser.add_option("-v",
                           "--version",
                           action="store_true",
                           help=help_str)
-    help_str  = "Prints version information and quits."
+    help_str  = "Prints this help and quits."
     opt_parser.add_option("-h",
                           "--help",
                           action="store_true",
@@ -250,34 +654,25 @@ def parse_parameters():
     return [options.xmlfile, options.target_dir, options.tmp_dir, options.gui]
 
 #=================================================================
-# strip : removes spaces at the beginning and at eh end of the 
+# strip : removes spaces at the beginning and at the end of the 
 #         <param> if it is of string type
 #=================================================================
 def strip(param):
-    import types
+    """
+    Removes spaces at the beginning and at the end
+    of the given parameter.
+    """
     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):
+    """
+    Gets full list of pre-requisite products.
+    """
     list = []
     for product in prods:
         deps = product.dependencies.split(",")
@@ -297,7 +692,12 @@ def get_dependencies(prods):
 #              is denied
 #==============================================================
 def create_dir(directory, access = 0777):
-    import string, os
+    """
+    Creates a directory with (optional) permissions,
+    returns the part of path that existed before
+    directory creation; exits with error if access
+    is denied.
+    """
     dirs = string.split(directory, "/")
     existing = "";
     dir = ""
@@ -322,6 +722,9 @@ def create_dir(directory, access = 0777):
 #                  it is substituted by the empty string
 #==============================================================
 def substituteVars(str):
+    """
+    Performes environment variables substistution.
+    """
     str = os.path.expanduser(str)
     str = os.path.expandvars(str)
     return str
@@ -331,6 +734,10 @@ def substituteVars(str):
 #                    (and performs 'cd' command there) 
 #================================================================
 def get_program_path():
+    """
+    Returns the program directory path
+    (and make this directory current).
+    """
     path = os.path.dirname(sys.argv[0])
     if path:
         os.chdir(path)
@@ -340,14 +747,17 @@ def get_program_path():
 # check_dir : checks directory existence
 #================================================================
 def check_dir(dir):
+    """
+    Checks directory existence.
+    """
     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)
+            msg = "Invalid link %s.\nThe directory %s a link points to does not exist. Stopped..."%(dir,realpath)
             error_exit(msg, False)
     else:
         if not os.path.exists(dir):
-            msg = "Directory %s does not exist."%dir
+            msg = "Directory %s does not exist. Stopped..."%dir
             error_exit(msg, False)
     pass
 
@@ -356,6 +766,10 @@ def check_dir(dir):
 #                    quits if there is no enough disk space
 #===============================================================
 def check_disk_space(products, scripts_dir, target_dir, tmp_dir):
+    """
+    Checks if there is enough disk space to install products.
+    Quits with error if there is no enough disk space.
+    """
     install_space = 0
     temporary_space = 0
     for product in products:
@@ -371,12 +785,12 @@ def check_disk_space(products, scripts_dir, target_dir, tmp_dir):
 
     res = os.system("%s/%s %s %d"%(scripts_dir, "checkSize.sh", target_dir, install_space))
     if res:
-        msg = "There is no enough space to install the products."
+        msg = "There is no enough space to install the products. Stopped..."
         error_exit(msg, False)
     
     res = os.system("%s/%s %s %d"%(scripts_dir, "checkSize.sh", tmp_dir, temporary_space))
     if res:
-        msg = "There is no enough space for temporary directory."
+        msg = "There is no enough space for temporary directory. Stopped..."
         error_exit(msg, False)
     pass
  
@@ -384,6 +798,9 @@ def check_disk_space(products, scripts_dir, target_dir, tmp_dir):
 # remove_dir : removes temporary directory
 #===============================================================
 def remove_dir(path):
+    """
+    Removes temporary directory.
+    """
     if path and os.path.exists(path):
         os.system("rm -rf " + path)
     pass
@@ -393,6 +810,9 @@ def remove_dir(path):
 #                binaries
 #===============================================================
 def has_binaries(products):
+    """
+    Returns True if some product is installed in 'binaries' mode.
+    """
     for product in products:
         if product.install == __TAG__BINARIES__:
             return True
@@ -403,14 +823,35 @@ def has_binaries(products):
 #               sources
 #===============================================================
 def has_sources(products):
+    """
+    Returns True if some product is installed in 'sources' mode.
+    """
     for product in products:
         if product.install == __TAG__SOURCES__:
             return True
     return False
 
-#================================================================
-# main
-#================================================================
+#==============================================================
+# get_tmp_dir : gets temporary directory name
+#===============================================================
+def get_tmp_dir(dir):
+    """
+    Gets temporary directory path.
+    """
+    max_attempts = 100
+    dir_prefix="INSTALLWORK"
+    range_bottom = 0; range_top = 999999
+    for i in xrange(max_attempts):
+        tmp_dir = "%s/%s%d"%(dir, dir_prefix, random.randint(range_bottom,range_top))
+        if not os.path.exists( tmp_dir ):
+            return tmp_dir
+    return "%s/%s%d"%(dir, dir_prefix, random.randint(range_bottom,range_top))
+    
+#------------------------------------------------------------------#
+#                                                                  #
+#                    EXECUTION STARTS HERE                         #
+#                                                                  #
+#------------------------------------------------------------------#
     
 if __name__ == "__main__":
     # get program dir
@@ -467,7 +908,12 @@ if __name__ == "__main__":
         env["LD_LIBRARY_PATH"] =  ".:" + env["LD_LIBRARY_PATH"]
         env["PATH"] = ".:" + env["PATH"]
 
-        cmd = "./bin/SALOME_InstallWizard %s &"%xml_file
+        cmd = "./bin/SALOME_InstallWizard --file %s"%xml_file
+        if target_dir is not None:
+            cmd += " --target %s"%target_dir
+        if tmp_dir is not None:
+            cmd += " --tmp %s"%tmp_dir
+        cmd += "&"
         sys.exit(os.system(cmd))
 
     #-----  TUI ---------------------
@@ -533,8 +979,7 @@ if __name__ == "__main__":
     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))
+    tmp_dir = get_tmp_dir(tmp_dir)
 
     message("Creating temporary directory: " + tmp_dir)
     root_path = create_dir(tmp_dir, 0755)
@@ -545,20 +990,20 @@ if __name__ == "__main__":
     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
+    # check available disk space -----------
     message("Checking available disk space")
     check_disk_space(parser.products, scripts_dir, target_dir, tmp_dir)
 
-    # change current directory
+    # change current directory -----------
     os.chdir(scripts_dir)
 
-    # get dependencies list
+    # get dependencies list -----------
     list_of_dep = get_dependencies(parser.products)
 
-    # starting
+    # starting -----------
     message("Starting ...")
     
-    # install products
+    # install products -----------
     for product in parser.products:
         message("... processing %s ..."%product.name)
         cmd = '%s/%s %s %s %s/%s %s "%s" %s'%(scripts_dir,
@@ -572,7 +1017,7 @@ if __name__ == "__main__":
                                               product.name)
         res = os.system(cmd)
 
-    # pickup environment
+    # pickup environment -----------
     message("Creating environment files")
     for product in parser.products :
         if check_bool(product.pickupEnv):
@@ -586,9 +1031,10 @@ if __name__ == "__main__":
                                                           product.name)
             res = os.system(cmd)
 
-    # clean temporary directory
+    # clean temporary directory -----------
     message("Cleaning temporary directory")
     clean_all()
-    # finishing
+    
+    # finishing -----------
     message("Finished!")
     pass
index f2628e384605fcca61dca97f12b07a28c234ec33..d4bd4da508824be8ebbccc78a47bdf427883564a 100644 (file)
@@ -39,6 +39,7 @@
 
 #include <qlayout.h>
 #include <qpushbutton.h>
+#include <qtoolbutton.h>
 #include <qcursor.h>
 #include <qlabel.h>
 #include <qwidgetstack.h>
@@ -95,6 +96,7 @@ public:
   QPushButton * cancelButton;
   QPushButton * helpButton;
   QFrame * hbar1, * hbar2;
+  QToolButton * aboutButton;
   
 #ifndef QT_NO_ACCEL
   QAccel * accel;
@@ -128,11 +130,13 @@ InstallWizard::InstallWizard( QWidget *parent, const char *name, bool modal,
   d->ws = new QWidgetStack( this, "qt_widgetstack" );
   d->pages.setAutoDelete( TRUE );
   d->titleBox = new QHBox( this, "title box" );
+  d->aboutButton = new QToolButton( d->titleBox, "about button");
+  d->aboutButton->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
+  d->aboutButton->setAutoRaise( true );
   d->title = new QLabel( d->titleBox, "title label" );
   d->logoBox = new QHBox( d->titleBox, "logo box" );
   d->logoBox->setSpacing( 2 );
   d->titleBox->setStretchFactor( d->title, 10 );
-  
   // create in nice tab order
   d->nextButton = new QPushButton( this, "next" );
   d->finishButton = new QPushButton( this, "finish" );
@@ -168,6 +172,8 @@ InstallWizard::InstallWizard( QWidget *parent, const char *name, bool modal,
     this, SLOT(reject()) );
   connect( d->helpButton, SIGNAL(clicked()),
     this, SLOT(help()) );
+  connect( d->aboutButton, SIGNAL(clicked()),
+    this, SIGNAL(aboutClicked()) );
   
 #ifndef QT_NO_ACCEL
   d->accel = new QAccel( this, "arrow-key accel" );
@@ -176,6 +182,8 @@ InstallWizard::InstallWizard( QWidget *parent, const char *name, bool modal,
   d->nextAccel = d->accel->insertItem( Qt::ALT + Qt::Key_Right );
   d->accel->connectItem( d->nextAccel, this, SIGNAL(nextClicked()) );
 #endif
+
+  showAboutBtn( false );
 }
 
 
@@ -416,7 +424,9 @@ void InstallWizard::help()
   emit helpClicked();
 }
 
-
+/*!
+  Enables/disables <Back> button
+ */
 void InstallWizard::setBackEnabled( bool enable )
 {
   d->backButton->setEnabled( enable );
@@ -425,7 +435,9 @@ void InstallWizard::setBackEnabled( bool enable )
 #endif
 }
 
-
+/*!
+  Enables/disables <Next> button
+ */
 void InstallWizard::setNextEnabled( bool enable )
 {
   d->nextButton->setEnabled( enable );
@@ -434,13 +446,14 @@ void InstallWizard::setNextEnabled( bool enable )
 #endif
 }
 
-
+/*!
+  Enables/disables <Help> button
+ */
 void InstallWizard::setHelpEnabled( bool enable )
 {
   d->helpButton->setEnabled( enable );
 }
 
-
 /*!
 \fn void InstallWizard::setFinish( QWidget *, bool )
 \obsolete
@@ -914,6 +927,22 @@ void InstallWizard::removeLogos()
   delete children;
 }
 
+/*!
+Show/hide "About" button
+*/
+void InstallWizard::showAboutBtn( bool show )
+{
+  show ? d->aboutButton->show() : d->aboutButton->hide();
+}
+
+/*!
+Set icon for "About" button
+*/
+void InstallWizard::setAboutIcon( const QPixmap& px )
+{
+  d->aboutButton->setIconSet( px );
+}
+
 /*!
 Posts validation event
 */
index 8b36597894b3ab9e91682c7c4c9e8f251eae02fe..180ccab42b06a2566b5841d536b0444fe99b677d 100644 (file)
@@ -78,13 +78,16 @@ public:
   QWidget * currentPage() const;
   
   QWidget* page( int ) const;
-  QWidget* page( const QString& title ) const;
+  QWidget* page( const QString& ) const;
   int pageCount() const;
   int indexOf( QWidget* ) const;
 
-  void addLogo( const QPixmap& pm );
+  void addLogo( const QPixmap& );
   void removeLogos();
   
+  void showAboutBtn( bool );
+  void setAboutIcon( const QPixmap& );
+  
   virtual bool appropriate( QWidget * ) const;
   virtual void setAppropriate( QWidget *, bool );
   
@@ -115,6 +118,7 @@ signals:
   void nextClicked();
   void backClicked();
   void helpClicked();
+  void aboutClicked();
   void selected( const QString& );
   
 protected:
index b9c1406905a8293fb53e3b78539bc3c9a38f3425..078d0b87b8fe1e5d036b79e99e21979d85685bca 100644 (file)
@@ -1,6 +1,6 @@
 #############################################################################
 # Makefile for building: ../bin/SALOME_InstallWizard
-# Generated by qmake (1.03a) on: Fri Jul  1 17:48:15 2005
+# Generated by qmake (1.03a) on: Tue Mar  7 14:46:50 2006
 # Project:  SALOME_INSTALL.pro
 # Template: app
 # Command: $(QMAKE) SALOME_INSTALL.pro
@@ -12,8 +12,8 @@ CC       = gcc
 CXX      = g++
 LEX      = flex
 YACC     = yacc
-CFLAGS   = -pipe -Wall -W -O2 -D_REENTRANT  -DQT_NO_DEBUG -DQT_THREAD_SUPPORT
-CXXFLAGS = -pipe -Wall -W -O2 -D_REENTRANT  -DQT_NO_DEBUG -DQT_THREAD_SUPPORT
+CFLAGS   = -pipe -Wno-deprecated -Wall -W -O2 -D_REENTRANT  -DQT_NO_DEBUG -DQT_THREAD_SUPPORT
+CXXFLAGS = -pipe -Wno-deprecated -Wall -W -O2 -D_REENTRANT  -DQT_NO_DEBUG -DQT_THREAD_SUPPORT
 LEXFLAGS = 
 YACCFLAGS= -d
 INCPATH  = -I$(QTDIR)/include -I$(QTDIR)/mkspecs/default
index 3968afcca35da5b990725dfb1b8ab8429f43657f..36737b440493ebbe8847e78848bf61a1a4dcc872 100644 (file)
@@ -317,6 +317,31 @@ static bool hasSpace( const QString& dir )
   return false;
 }
 
+// ================================================================
+/*!
+ *  makeTitle
+ *  Creates HTML-wrapped title text
+ */
+// ================================================================
+QString makeTitle( const QString& text, const QString& separator = " ", bool fl = true )
+{
+  QStringList words = QStringList::split( separator, text );
+  if ( fl ) {
+    for ( uint i = 0; i < words.count(); i++ )
+      words[i] = QString( "<font color=red>%1</font>" ).arg( words[i].left(1) ) + words[i].mid(1);
+  }
+  else {
+    if ( words.count() > 0 )
+      words[0] = QString( "<font color=red>%1</font>" ).arg( words[0] );
+    if ( words.count() > 1 )
+      words[words.count()-1] = QString( "<font color=red>%1</font>" ).arg( words[words.count()-1] );
+  }
+  QString res = words.join( separator );
+  if ( !res.isEmpty() )
+    res = QString( "<b>%1</b>" ).arg( res );
+  return res;
+}
+
 // ================================================================
 /*!
  *  QMyCheckBox class : custom check box
@@ -330,23 +355,117 @@ public:
   void setState ( ToggleState s ) { QCheckBox::setState( s ); }
 };
 
+// ================================================================
+/*!
+ *  AboutDlg
+ *  "About dialog box.
+ */
+// ================================================================
+class AboutDlg: public QDialog
+{
+public:
+  AboutDlg( SALOME_InstallWizard* parent ) : QDialog( parent, "About dialog box", true )
+  {
+    // caption
+    setCaption( QString( "About %1" ).arg( parent->getIWName() ) );
+    // palette
+    QPalette pal = palette();
+    QColorGroup cg = pal.active();
+    cg.setColor( QColorGroup::Foreground, Qt::darkBlue );
+    cg.setColor( QColorGroup::Background, Qt::white );
+    pal.setActive( cg ); pal.setInactive( cg ); pal.setDisabled( cg );
+    setPalette( pal );
+    // layout
+    QGridLayout* main = new QGridLayout( this, 1, 1, 11, 6 );
+    // image
+    QLabel* logo = new QLabel( this, "logo" );
+    logo->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
+    logo->setMinimumSize( 32, 32 ); logo->setMaximumSize( 32, 32 );
+    logo->setPaletteBackgroundColor( QColor( 234, 250, 234 ) );
+    logo->setFrameStyle( QLabel::NoFrame | QLabel::Plain );
+    logo->setPixmap( pixmap( pxAbout ) );
+    logo->setScaledContents( false );
+    logo->setAlignment( QLabel::AlignCenter );
+    // decoration
+    QLabel* decorLeft = new QLabel( this, "decorLeft" );
+    decorLeft->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Expanding ) );
+    decorLeft->setMinimumWidth( 32 ); decorLeft->setMaximumWidth( 32 );
+    decorLeft->setPaletteBackgroundColor( QColor( 234, 250, 234 ) );
+    decorLeft->setScaledContents( false );
+    QLabel* decorTop = new QLabel( this, "decorTop" );
+    decorTop->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+    decorTop->setMinimumHeight( 32 ); decorTop->setMaximumHeight( 32 );
+    decorTop->setPaletteBackgroundColor( QColor( 234, 250, 234 ) );
+    decorTop->setScaledContents( false );
+    // contents
+    QLabel* title = new QLabel( this, "title" );
+    QString tlt = parent->getIWName();
+    title->setText( makeTitle( tlt ) );
+    QLabel* version = new QLabel( this, "version" );
+    version->setText( QString( "<b>Version</b>: %1.%1.%1" ).arg( __IW_VERSION_MAJOR__ ) \
+                     .arg( __IW_VERSION_MINOR__ ) \
+                     .arg( __IW_VERSION_PATCH__ ) );
+    QLabel* copyright = new QLabel( this, "copyright" );
+    copyright->setText( "<b>Copyright</b> &copy; 2004-2006 CEA" );
+    QFont font = title->font();
+    font.setPointSize( (int)( font.pointSize() * 1.8 ) );
+    title->setFont( font );
+    QFrame* line = new QFrame( this, "line" );
+    line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+    QLabel* url = new QLabel( this, "url" );
+    url->setText( makeTitle( "www.salome-platform.org", ".", false ) );
+    url->setAlignment( AlignRight );
+    font = version->font();
+    font.setPointSize( (int)( font.pointSize() / 1.2 ) );
+    version->setFont( font );
+    copyright->setFont( font );
+    url->setFont( font );
+    // layout
+    main->addWidget( logo, 0, 0 );
+    main->addMultiCellWidget( decorLeft, 1, 5, 0, 0 );
+    main->addWidget( decorTop, 0, 1 );
+    main->addWidget( title, 1, 1 );
+    main->addWidget( version, 2, 1 );
+    main->addWidget( copyright, 3, 1 );
+    main->addWidget( line, 4, 1 );
+    main->addWidget( url, 5, 1 );
+    // resize
+    QFontMetrics fm( title->font() );
+    int width = (int)( fm.width( tlt ) * 1.5 );
+    title->setMinimumWidth( width );
+    setMaximumSize( minimumSize() );
+  }
+  void mousePressEvent( QMouseEvent* )
+  {
+    accept();
+  }
+};
+
 // ================================================================
 /*!
  *  SALOME_InstallWizard::SALOME_InstallWizard
  *  Constructor
  */
 // ================================================================
-SALOME_InstallWizard::SALOME_InstallWizard(QString aXmlFileName)
+SALOME_InstallWizard::SALOME_InstallWizard(const QString& aXmlFileName,
+                                          const QString& aTargetDir,
+                                          const QString& aTmpDir)
      : InstallWizard( qApp->desktop(), "SALOME_InstallWizard", false, 0 ), 
        helpWindow( NULL ), 
        moreMode( false ), 
        previousPage( 0 ), 
        exitConfirmed( false )
 {
-  myIWName = tr( "Installation Wizard" );
-  tmpCreated = QString::null;
-  xmlFileName = aXmlFileName;
-  QFont fnt = font(); fnt.setPointSize( 14 ); fnt.setBold( true );
+  myIWName      = tr( "Installation Wizard" );
+  tmpCreated    = QString::null;
+  xmlFileName   = aXmlFileName;
+  targetDirPath = aTargetDir;
+  tmpDirPath    = aTmpDir;
+
+  // set application font
+  QFont fnt = font();
+  fnt.setPointSize( 14 );
+  fnt.setBold( true );
   setTitleFont( fnt );
 
   // set icon
@@ -364,7 +483,9 @@ SALOME_InstallWizard::SALOME_InstallWizard(QString aXmlFileName)
   setLicense( tr( "All right reserved" ) );
   setOS( "" );
 
-  ___MESSAGE___( "Config. file : " << xmlFileName );
+  ___MESSAGE___( "Configuration file : " << xmlFileName );
+  ___MESSAGE___( "Target directory   : " << targetDirPath );
+  ___MESSAGE___( "Temporary directory: " << tmpDirPath );
 
   // xml reader
   QFile xmlfile(xmlFileName);
@@ -405,8 +526,10 @@ SALOME_InstallWizard::SALOME_InstallWizard(QString aXmlFileName)
   
   // common signals connections
   connect( this, SIGNAL( selected( const QString& ) ),
-                                          this, SLOT( pageChanged( const QString& ) ) );
-  connect( this, SIGNAL( helpClicked() ), this, SLOT( helpClicked() ) );
+                                           this, SLOT( pageChanged( const QString& ) ) );
+  connect( this, SIGNAL( helpClicked() ),  this, SLOT( helpClicked() ) );
+  connect( this, SIGNAL( aboutClicked() ), this, SLOT( onAbout() ) );
+
   // catch signals from launched script
   connect(shellProcess, SIGNAL( readyReadStdout() ), this, SLOT( readFromStdout() ) );
   connect(shellProcess, SIGNAL( readyReadStderr() ), this, SLOT( readFromStderr() ) );
@@ -415,6 +538,10 @@ SALOME_InstallWizard::SALOME_InstallWizard(QString aXmlFileName)
 
   // create validation thread
   myThread = new ProcessThread( this );
+
+  // show about button
+  setAboutIcon( pixmap( pxAbout ) );
+  showAboutBtn( true );
 }
 // ================================================================
 /*!
@@ -656,6 +783,12 @@ void SALOME_InstallWizard::setupProductsPage()
     reader.setContentHandler( handler );
     reader.parse( source );  
   }
+  // take into account command line parameters
+  if ( !targetDirPath.isEmpty() )
+    targetFolder->setText( targetDirPath );
+  if ( !tmpDirPath.isEmpty() )
+    tempFolder->setText( tmpDirPath );
+
   // set first item to be selected
   if ( productsView->childCount() > 0 ) {
     productsView->setSelected( productsView->firstChild(), true );
@@ -1486,6 +1619,19 @@ void SALOME_InstallWizard::onLaunchSalome()
                        QMessageBox::NoButton,
                        QMessageBox::NoButton );
 }
+
+// ================================================================
+/*!
+ *  SALOME_InstallWizard::onAbout
+ *  <About> button slot: shows <About> dialog box
+ */
+// ================================================================
+void SALOME_InstallWizard::onAbout()
+{
+  AboutDlg d( this );
+  d.exec();
+}
+
 // ================================================================
 /*!
  *  SALOME_InstallWizard::findItem
index 37800cdc8b7f6d7a2155ee45cd70ebd844b7728d..ee7af23440509216b1f17813f48cea1419862dcc 100644 (file)
@@ -114,7 +114,9 @@ class SALOME_InstallWizard: public InstallWizard
     
  public:
   // constructor
-  SALOME_InstallWizard(QString aXmlFileName);
+  SALOME_InstallWizard(const QString& aXmlFileName,
+                      const QString& aTargetDir = QString::null,
+                      const QString& aTmpDir    = QString::null);
   // destructor
   virtual ~SALOME_InstallWizard( );
 
@@ -229,6 +231,8 @@ class SALOME_InstallWizard: public InstallWizard
   void onMoreBtn();
   // <Launch Salome> button slot
   void onLaunchSalome();
+  // <About> button slot
+  void onAbout();
 
   // QProcess slots:
   // -->something was written to stdin
@@ -251,6 +255,8 @@ class SALOME_InstallWizard: public InstallWizard
   MapProducts      productsMap;    // products info (name, dependancies, disk space )
   QStringList      toInstall;      // list of products being installed
   QString          xmlFileName;    // xml file
+  QString          targetDirPath;  // target directory
+  QString          tmpDirPath;     // temporary directory
   bool             moreMode;       // advanced mode flag
   QWidget*         previousPage;   // previous page
   QString          tmpCreated;     // created temporary directory
index 160f26eed5e250f59a9d12a101cf8940ec2fab4b..10fffb1e0ab93e92dcf69092452182a799db1c97 100644 (file)
@@ -17,7 +17,7 @@
 
 #define __IW_VERSION_MAJOR__ 1
 #define __IW_VERSION_MINOR__ 0
-#define __IW_VERSION_PATCH__ 0
+#define __IW_VERSION_PATCH__ 1
 
 #define __IW_VERSION__ (__IW_VERSION_MAJOR__*10000 + \
                         __IW_VERSION_MINOR__*100   + \
index 04409e187bba546e524b8679171f4ceb013e5c0e..560e4d4d10030f4a6ca4e9e5ce13f65f15d2cbf5 100644 (file)
@@ -30812,6 +30812,85 @@ static const char* const image_zoom_out[] = {
 "2 2 [.h+h+H.                i+j+k+l+m+n+",
 "                              W o+p+|+q+"};
 
+static const char* const image_about[] = { 
+"16 16 5 1",
+"      c None",
+".     c #5151C1",
+"+     c #1414C1",
+"@     c #7C7CC1",
+"#     c #A5A5C3",
+"                ",
+".+@             ",
+".+@             ",
+".+@             ",
+".+@             ",
+".+@@+@  @+@  @+@",
+".+@.+@  .+@  .+@",
+".+@.+@  .+@  .+@",
+".+@.+@ #.+@ #.+@",
+".+@.+@#.++@#.++@",
+"###.+..+++..++.#",
+"   .++++@++++@# ",
+"   .++.@#++.@#  ",
+"   .+@#  +@#    ",
+"                ",
+"                "};
+
+static const char* const image_about1[] = { 
+"16 16 8 1",
+"      c None",
+".     c #C15151",
+"+     c #C3A5A5",
+"@     c #C11414",
+"#     c #5151C1",
+"$     c #1414C1",
+"%     c #7C7CC1",
+"&     c #A5A5C3",
+"          .+@+. ",
+"          +.@.+ ",
+"#$%       @@@@@ ",
+"#$%       +.@.+ ",
+"#$%       .+@+. ",
+"#$%             ",
+"#$%%$%  %$%  %$%",
+"#$%#$%  #$%  #$%",
+"#$%#$%  #$%  #$%",
+"#$%#$% &#$% &#$%",
+"#$%#$%&#$$%&#$$%",
+"&&&#$##$$$##$$#&",
+"   #$$$$%$$$$%& ",
+"   #$$#%&$$#%&  ",
+"   #$%&  $%&    ",
+"                "};
+
+static const char* const image_about2[] = { 
+"16 16 9 1",
+"      c None",
+".     c #C15151",
+"+     c #C11414",
+"@     c #C17C7C",
+"#     c #C3A5A5",
+"$     c #5151C1",
+"%     c #1414C1",
+"&     c #7C7CC1",
+"*     c #A5A5C3",
+".+@             ",
+".+@             ",
+"###             ",
+"$%&             ",
+"$%&             ",
+"$%&             ",
+"$%&             ",
+"$%&&%&  &%&  &%&",
+"$%&$%&  $%&  $%&",
+"$%&$%&  $%&  $%&",
+"$%&$%& *$%& *$%&",
+"$%&$%&*$%%&*$%%&",
+"***$%$$%%%$$%%$*",
+"   $%%%%&%%%%&* ",
+"   $%%$&*%%$&*  ",
+"   $%&*  %&*    "};
+
 QPixmap pixmap( const int type )
 {
   switch ( type ) {
@@ -30819,6 +30898,8 @@ QPixmap pixmap( const int type )
     return QPixmap( ( const char** )image_SALOME );
   case pxLogo:         // small logo
     return QPixmap( ( const char** )image_logo );
+  case pxAbout:        // about icon
+    return QPixmap( ( const char** )image_about2 );
   case pxIcon:         // title icon
     return QPixmap( ( const char** )image_icon );
   case pxClose:        // help window : close window
index 8e5f201e615061373faca54f0ffcc0bfeed9b927..4a62bb6063f49700d3b119ca9fbc455b9ab087d0 100644 (file)
@@ -12,6 +12,7 @@
 
 enum { pxBigLogo,      // SALOME Logo
        pxLogo,         // small logo
+       pxAbout,        // about icon
        pxIcon,         // title icon
        pxClose,        // help window : close window
        pxHome,         // help window : go home
index 3e1697f5e74ead131ce98f371adea9cc66d80115..b508de0ac113be19fb47a099452f4d4e9cd2f808 100644 (file)
@@ -50,6 +50,11 @@ int main( int argc, char **argv )
   qInstallMsgHandler( MessageOutput );
 
   QString xmlFileName;
+  QString targetDirPath;
+  QString tmpDirPath;
+  bool has_xml    = false;
+  bool has_target = false;
+  bool has_tmp    = false;
   for( int i = 1; i < argc; i++ ) {
     QString a = QString( argv[i] );
     if ( a == "--version" || a == "-v" ) {
@@ -63,9 +68,50 @@ int main( int argc, char **argv )
             ( QT_VERSION       ) & 0xFF );
       return 0;
     }
-    if ( xmlFileName.isEmpty() )
-      xmlFileName = a;
+    else if ( a == "--target" || a == "-d" ) {
+      has_target = true;
+      if ( i < argc-1 && !QString( argv[i+1] ).startsWith("-") ) {
+       targetDirPath = argv[i+1]; 
+       i++;
+      }
+      else {
+       tmpDirPath = QString::null;
+      }
+    }
+    else if ( a == "--tmp" || a == "-t" ) {
+      has_tmp = true;
+      if ( i < argc-1 && !QString( argv[i+1] ).startsWith("-") ) {
+       tmpDirPath = argv[i+1]; 
+       i++;
+      }
+      else {
+       tmpDirPath = QString::null;
+      }
+    }
+    else if ( a == "--file" || a == "-f" ) {
+      has_xml = true;
+      if ( i < argc-1 && !QString( argv[i+1] ).startsWith("-") ) {
+       xmlFileName = argv[i+1]; 
+       i++;
+      }
+      else {
+       xmlFileName = QString::null;
+      }
+    }
+  }
+  if ( has_xml && xmlFileName.isEmpty() ) {
+    printf("Please specify the configuration XML file!\n");
+    return 1;
   }
+  if ( has_target && targetDirPath.isEmpty() ) {
+    printf("Please specify the target directory path!\n");
+    return 1;
+  }
+  if ( has_tmp && tmpDirPath.isEmpty() ) {
+    printf("Please specify the temprary directory path!\n");
+    return 1;
+  }
+
   if ( xmlFileName.isEmpty() )
     xmlFileName = "config.xml";
 
@@ -75,7 +121,7 @@ int main( int argc, char **argv )
   int result = -1;
   QFile xmlfile(xmlFileName);
   if ( xmlfile.exists() ) {
-    SALOME_InstallWizard wizard(xmlFileName);
+    SALOME_InstallWizard wizard(xmlFileName, targetDirPath, tmpDirPath);
     a.setMainWidget( &wizard );
     wizard.show();
     result = a.exec();