Salome HOME
Run SALOME with UNICODE path.
[modules/gui.git] / src / Qtx / QtxResourceMgr.cxx
index 0e74d6a8dc6da70eac854cea7db917a72024dd44..4fa61bf0f617506f1ac166cca566bcd46b953f11 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2019  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -66,8 +66,6 @@ static const char* pixmap_not_found_xpm[] = {
 "                ",
 "                "};
 
-QPixmap*  QtxResourceMgr::myDefaultPix = NULL;
-
 /*!
   \class QtxResourceMgr::Resources
   \internal
@@ -76,6 +74,10 @@ QPixmap*  QtxResourceMgr::myDefaultPix = NULL;
 
 class QtxResourceMgr::Resources
 {
+private:
+  typedef QMap<QString, Section> SectionMap;
+  typedef QMap<QString, QString> OptionsMap;
+
 public:
   Resources( QtxResourceMgr*, const QString& );
   virtual ~Resources();
@@ -83,7 +85,7 @@ public:
   QString                file() const;
   void                   setFile( const QString& );
 
-  QString                value( const QString&, const QString&, const bool ) const;
+  QString                value( const QString&, const QString&, const bool, const OptionsMap& ) const;
   void                   setValue( const QString&, const QString&, const QString& );
 
   bool                   hasSection( const QString& ) const;
@@ -92,17 +94,15 @@ public:
   void                   removeSection( const QString& );
   void                   removeValue( const QString&, const QString& );
 
-  QPixmap                loadPixmap( const QString&, const QString&, const QString& ) const;
-  QTranslator*           loadTranslator( const QString&, const QString&, const QString& ) const;
-
-  QString                makeSubstitution( const QString&, const QString&, const QString& ) const;
+  QPixmap                loadPixmap( const QString&, const QString&, const QString&, const OptionsMap& ) const;
+  QTranslator*           loadTranslator( const QString&, const QString&, const QString&, const OptionsMap& ) const;
 
   void                   clear();
 
   QStringList            sections() const;
   QStringList            parameters( const QString& ) const;
 
-  QString                path( const QString&, const QString&, const QString& ) const;
+  QString                path( const QString&, const QString&, const QString&, const OptionsMap& ) const;
 
 protected:
   QtxResourceMgr*        resMgr() const;
@@ -111,10 +111,9 @@ private:
   Section                section( const QString& );
   const Section          section( const QString& ) const;
 
-  QString                fileName( const QString&, const QString&, const QString& ) const;
+  QString                makeSubstitution( const QString&, const QString&, const QString&, const OptionsMap& ) const;
 
-private:
-  typedef QMap<QString, Section> SectionMap;
+  QString                fileName( const QString&, const QString&, const QString&, const OptionsMap& ) const;
 
 private:
   QtxResourceMgr*        myMgr;             //!< resources manager
@@ -174,7 +173,7 @@ void QtxResourceMgr::Resources::setFile( const QString& fn )
   \return parameter value or null QString if there is no such parameter
   \sa setValue(), makeSubstitution()
 */
-QString QtxResourceMgr::Resources::value( const QString& sect, const QString& name, const bool subst ) const
+QString QtxResourceMgr::Resources::value( const QString& sect, const QString& name, const bool subst, const OptionsMap& constants ) const
 {
   QString val;
 
@@ -182,7 +181,7 @@ QString QtxResourceMgr::Resources::value( const QString& sect, const QString& na
   {
     val = section( sect )[name];
     if ( subst )
-      val = makeSubstitution( val, sect, name );
+      val = makeSubstitution( val, sect, name, constants );
   }
   return val;
 }
@@ -293,9 +292,9 @@ QStringList QtxResourceMgr::Resources::parameters( const QString& sec ) const
   \return absolute file path or null QString if file does not exist
   \sa fileName(), file(), makeSubstitution()
 */
-QString QtxResourceMgr::Resources::path( const QString& sec, const QString& prefix, const QString& name ) const
+QString QtxResourceMgr::Resources::path( const QString& sec, const QString& prefix, const QString& name, const OptionsMap& constants ) const
 {
-  QString filePath = fileName( sec, prefix, name );
+  QString filePath = fileName( sec, prefix, name, constants );
   if ( !filePath.isEmpty() )
   {
     if ( !QFileInfo( filePath ).exists() )
@@ -356,7 +355,7 @@ const QtxResourceMgr::Section QtxResourceMgr::Resources::section( const QString&
           does not exist in section \sec
   \sa path(), file(), makeSubstitution()
 */
-QString QtxResourceMgr::Resources::fileName( const QString& sect, const QString& prefix, const QString& name ) const
+QString QtxResourceMgr::Resources::fileName( const QString& sect, const QString& prefix, const QString& name, const OptionsMap& constants ) const
 {
   QString path;
   if ( !QFileInfo( name ).isRelative() )
@@ -367,7 +366,7 @@ QString QtxResourceMgr::Resources::fileName( const QString& sect, const QString&
   {
     if ( hasValue( sect, prefix ) )
     {
-      path = value( sect, prefix, true );
+      path = value( sect, prefix, true, constants );
       if ( !path.isEmpty() )
       {
        if ( QFileInfo( path ).isRelative() )
@@ -379,7 +378,7 @@ QString QtxResourceMgr::Resources::fileName( const QString& sect, const QString&
   }
   if( !path.isEmpty() )
   {
-    QString fname = QDir::convertSeparators( path );
+    QString fname = QDir::toNativeSeparators( path );
     QFileInfo inf( fname );
     fname = inf.absoluteFilePath();
     return fname;
@@ -399,9 +398,9 @@ QString QtxResourceMgr::Resources::fileName( const QString& sect, const QString&
   \param name pixmap file name
   \return pixmap loaded from file
 */
-QPixmap QtxResourceMgr::Resources::loadPixmap( const QString& sect, const QString& prefix, const QString& name ) const
+QPixmap QtxResourceMgr::Resources::loadPixmap( const QString& sect, const QString& prefix, const QString& name, const OptionsMap& constants ) const
 {
-  QString fname = fileName( sect, prefix, name );
+  QString fname = fileName( sect, prefix, name, constants );
   bool toCache = resMgr() ? resMgr()->isPixmapCached() : false;
   QPixmap p;
   if( toCache && myPixmapCache.contains( fname ) )
@@ -422,10 +421,10 @@ QPixmap QtxResourceMgr::Resources::loadPixmap( const QString& sect, const QStrin
   \param name translation file name
   \return just created and loaded translator or 0 in case of error
 */
-QTranslator* QtxResourceMgr::Resources::loadTranslator( const QString& sect, const QString& prefix, const QString& name ) const
+QTranslator* QtxResourceMgr::Resources::loadTranslator( const QString& sect, const QString& prefix, const QString& name, const OptionsMap& constants ) const
 {
   QTranslator* trans = new QtxTranslator( 0 );
-  QString fname = QDir::convertSeparators( fileName( sect, prefix, name ) );
+  QString fname = QDir::toNativeSeparators( fileName( sect, prefix, name, constants ) );
   if ( !trans->load( Qtx::file( fname, false ), Qtx::dir( fname ) ) )
   {
     delete trans;
@@ -445,7 +444,7 @@ QTranslator* QtxResourceMgr::Resources::loadTranslator( const QString& sect, con
   \param name name of variable which must be ignored during substitution
   \return processed string (with all substitutions made)
 */
-QString QtxResourceMgr::Resources::makeSubstitution( const QString& str, const QString& sect, const QString& name ) const
+QString QtxResourceMgr::Resources::makeSubstitution( const QString& str, const QString& sect, const QString& name, const OptionsMap& constants ) const
 {
   QString res = str;
 
@@ -459,11 +458,15 @@ QString QtxResourceMgr::Resources::makeSubstitution( const QString& str, const Q
     if ( envName.isNull() )
       break;
 
-    QString newStr;
-    if ( ::getenv( envName.toLatin1() ) )
-      newStr = QString( ::getenv( envName.toLatin1() ) );
+    // First we look in the constants map
+    QString newStr = constants.value( envName, QString() );
+
+    // Then we check for environment variable
+       QString tmpValue = Qtx::getenv( envName );
+    if ( newStr.isEmpty() && !tmpValue.isEmpty() )
+      newStr = tmpValue;
 
-    if ( newStr.isNull() )
+    if ( newStr.isEmpty() )
     {
       if ( ignoreMap.contains( envName ) )
       {
@@ -472,7 +475,7 @@ QString QtxResourceMgr::Resources::makeSubstitution( const QString& str, const Q
       }
 
       if ( hasValue( sect, envName ) )
-        newStr = value( sect, envName, false );
+        newStr = value( sect, envName, false, constants );
       ignoreMap.insert( envName, 0 );
     }
     res.replace( start, len, newStr );
@@ -612,7 +615,7 @@ bool QtxResourceMgr::IniFormat::load( const QString& fname, QMap<QString, Sectio
     }
     else if ( section == "import" )
     {
-      QString impFile = QDir::convertSeparators( Qtx::makeEnvVarSubst( data, Qtx::Always ) );
+      QString impFile = QDir::toNativeSeparators( Qtx::makeEnvVarSubst( data, Qtx::Always ) );
       QFileInfo impFInfo( impFile );
       if ( impFInfo.isRelative() )
              impFInfo.setFile( aFinfo.absoluteDir(), impFile );
@@ -850,7 +853,7 @@ bool QtxResourceMgr::XmlFormat::load( const QString& fname, QMap<QString, Sectio
       }
       else if ( sectElem.tagName() == importTag() && sectElem.hasAttribute( nameAttribute() ) )
       {
-         QString impFile = QDir::convertSeparators( Qtx::makeEnvVarSubst( sectElem.attribute( nameAttribute() ), Qtx::Always ) );
+         QString impFile = QDir::toNativeSeparators( Qtx::makeEnvVarSubst( sectElem.attribute( nameAttribute() ), Qtx::Always ) );
              QFileInfo impFInfo( impFile );
              if ( impFInfo.isRelative() )
                 impFInfo.setFile( aFinfo.absoluteDir(), impFile );
@@ -1239,6 +1242,7 @@ bool QtxResourceMgr::Format::save( Resources* res )
 QtxResourceMgr::QtxResourceMgr( const QString& appName, const QString& resVarTemplate )
 : myAppName( appName ),
   myCheckExist( true ),
+  myDefaultPix( 0 ),
   myIsPixmapCached( true ),
   myHasUserValues( true ),
   myWorkingMode( AllowUserValues )
@@ -1248,8 +1252,9 @@ QtxResourceMgr::QtxResourceMgr( const QString& appName, const QString& resVarTem
     envVar = envVar.arg( appName );
 
   QString dirs;
-  if ( ::getenv( envVar.toLatin1() ) )
-    dirs = ::getenv( envVar.toLatin1() );
+  QString tmpValue = Qtx::getenv( envVar );
+  if ( !tmpValue.isEmpty() )
+    dirs = tmpValue;
 #ifdef WIN32
   QString dirsep = ";";      // for Windows: ";" is used as directories separator
 #else
@@ -1276,6 +1281,8 @@ QtxResourceMgr::~QtxResourceMgr()
 
   qDeleteAll( myResources );
   qDeleteAll( myFormats );
+
+  delete myDefaultPix;
 }
 
 /*!
@@ -1408,11 +1415,14 @@ QtxResourceMgr::WorkingMode QtxResourceMgr::workingMode() const
   Note, that setValue() method always put the value to the user settings file.
   
   \param mode new working mode
+  \return previous working mode
   \sa workingMode(), value(), hasValue(), hasSection(), setValue()
 */
-void QtxResourceMgr::setWorkingMode( WorkingMode mode )
+QtxResourceMgr::WorkingMode QtxResourceMgr::setWorkingMode( WorkingMode mode )
 {
+  WorkingMode m = myWorkingMode;
   myWorkingMode = mode;
+  return m;
 }
 
 /*!
@@ -1569,23 +1579,31 @@ bool QtxResourceMgr::value( const QString& sect, const QString& name, QByteArray
   if ( !value( sect, name, val, true ) )
     return false;
 
-  baVal.clear();
-  QStringList lst = val.split( QRegExp( "[\\s|,]" ), QString::SkipEmptyParts );
-  for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it )
-  {
-    int base = 10;
-    QString str = *it;
-    if ( str.startsWith( "#" ) )
+  if ( val.startsWith( "@ByteArray(" ) && val.endsWith( ')' ) ) {
+    baVal = QByteArray( val.midRef( 11, val.size() - 12 ).toLatin1() );
+  }
+  else  {
+    if ( val.startsWith( "@ByteArray[" ) && val.endsWith( ']' ) ) {
+      val = val.mid( 11, val.size() - 12 );
+    }
+    baVal.clear();
+    QStringList lst = val.split( QRegExp( "[\\s|,]" ), QString::SkipEmptyParts );
+    for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it )
     {
-      base = 16;
-      str = str.mid( 1 );
+      int base = 10;
+      QString str = *it;
+      if ( str.startsWith( "#" ) )
+      {
+        base = 16;
+        str = str.mid( 1 );
+      }
+      bool ok = false;
+      int num = str.toInt( &ok, base );
+      if ( !ok || num < 0 || num > 255 )
+        continue;
+      
+      baVal.append( (char)num );
     }
-    bool ok = false;
-    int num = str.toInt( &ok, base );
-    if ( !ok || num < 0 || num > 255 )
-      continue;
-
-    baVal.append( (char)num );
   }
   return !baVal.isEmpty();
 }
@@ -1682,7 +1700,7 @@ bool QtxResourceMgr::value( const QString& sect, const QString& name, QString& v
   {
     ok = (*it)->hasValue( sect, name );
     if ( ok )
-      val = (*it)->value( sect, name, subst );
+      val = (*it)->value( sect, name, subst, myConstants );
   }
 
   return ok;
@@ -1793,10 +1811,10 @@ QColor QtxResourceMgr::colorValue( const QString& sect, const QString& name, con
   \param def default value
   \return parameter value (or default value if parameter is not found)
 */
-QString QtxResourceMgr::stringValue( const QString& sect, const QString& name, const QString& def ) const
+QString QtxResourceMgr::stringValue( const QString& sect, const QString& name, const QString& def, const bool subst ) const
 {
   QString val;
-  if ( !value( sect, name, val ) )
+  if ( !value( sect, name, val, subst ) )
     val = def;
   return val;
 }
@@ -2055,7 +2073,9 @@ void QtxResourceMgr::setValue( const QString& sect, const QString& name, const Q
     ::sprintf( buf, "#%02X", (unsigned char)val.at( i ) );
     lst.append( QString( buf ) );
   }
-  setResource( sect, name, lst.join( " " ) );
+
+  QString result = QString( "@ByteArray[%1]" ).arg( lst.join( " " ) );
+  setResource( sect, name, result );
 }
 
 /*!
@@ -2258,6 +2278,42 @@ void QtxResourceMgr::setOption( const QString& opt, const QString& val )
   myOptions.insert( opt, val );
 }
 
+/*!
+  \brief Get names of all known constants.
+  \return list of constants names
+  \sa constant(), setConstant
+*/
+QStringList QtxResourceMgr::constants() const
+{
+  return myConstants.keys();
+}
+
+/*!
+  \brief Get the value of the known constant.
+
+  If constant is not set, null QString is returned.
+
+  \param name constant name
+  \return constant value
+  \sa setConstant(), constants()
+*/
+QString QtxResourceMgr::constant( const QString& name ) const
+{
+  return myConstants.value( name, QString() );
+}
+
+/*!
+  \brief Set the value of the constant.
+  \param name constant name
+  \param value constant value
+  \sa constants(), constants()
+*/
+void QtxResourceMgr::setConstant( const QString& name, const QString& value )
+{
+  if ( !name.isEmpty() )
+    myConstants.insert( name, value );
+}
+
 /*!
   \brief Load all resources from all resource files (global and user).
   \return \c true on success and \c false on error
@@ -2480,7 +2536,7 @@ QString QtxResourceMgr::path( const QString& sect, const QString& prefix, const
     ++it;
 
   for ( ; it != myResources.end() && res.isEmpty(); ++it )
-    res = (*it)->path( sect, prefix, name );
+    res = (*it)->path( sect, prefix, name, myConstants );
   return res;
 }
 
@@ -2543,15 +2599,13 @@ QString QtxResourceMgr::sectionsToken() const
   \return default pixmap
   \sa setDefaultPixmap(), loadPixmap()
 */
-QPixmap QtxResourceMgr::defaultPixmap()
+QPixmap QtxResourceMgr::defaultPixmap() const
 {
-  QPixmap res;
-  if(!myDefaultPix)
-    myDefaultPix = new QPixmap( pixmap_not_found_xpm );
-  
-  if ( myDefaultPix && !myDefaultPix->isNull() )
-    res = *myDefaultPix;
-  return res;
+  static QPixmap* defpx = 0;
+  if ( !defpx ) 
+    defpx = new QPixmap( pixmap_not_found_xpm );
+
+  return myDefaultPix ? *myDefaultPix : *defpx;
 }
 
 /*!
@@ -2568,7 +2622,7 @@ void QtxResourceMgr::setDefaultPixmap( const QPixmap& pix )
   if ( pix.isNull() )
     myDefaultPix = 0;
   else
-    myDefaultPix = new QPixmap( pix ); 
+    myDefaultPix = new QPixmap( pix );
 }
 
 /*!
@@ -2618,12 +2672,20 @@ QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name,
     ++it;
 
   for ( ; it != myResources.end() && pix.isNull(); ++it )
-    pix = (*it)->loadPixmap( resSection(), prefix, name );
+    pix = (*it)->loadPixmap( resSection(), prefix, name, myConstants );
   if ( pix.isNull() )
     pix = defPix;
   return pix;
 }
 
+/*!
+  \brief Specify default language for the application.
+*/
+QString QtxResourceMgr::defaultLanguage() const
+{
+  return "";
+}
+
 /*!
   \brief Load translation files according to the specified language.
 
@@ -2655,6 +2717,8 @@ void QtxResourceMgr::loadLanguage( const QString& pref, const QString& l )
   substMap.insert( 'A', appName() );
 
   QString lang = l;
+  if ( lang.isEmpty() )
+    lang = defaultLanguage();
   if ( lang.isEmpty() )
     value( langSection(), "language", lang );
 
@@ -2695,15 +2759,11 @@ void QtxResourceMgr::loadLanguage( const QString& pref, const QString& l )
   if ( pref.isEmpty() && lang != "en" ) {
     // load Qt resources
     QString qt_translations = QLibraryInfo::location( QLibraryInfo::TranslationsPath );
-    QString qt_dir_trpath;
-    if ( ::getenv( "QTDIR" ) )
-      qt_dir_trpath = QString( ::getenv( "QTDIR" ) );
-    if ( !qt_dir_trpath.isEmpty() )
-      qt_dir_trpath = QDir( qt_dir_trpath ).absoluteFilePath( "translations" );
-
+    QString qt_dir_trpath = Qtx::qtDir( "translations" );
     QTranslator* trans = new QtxTranslator( 0 );
-    if ( trans->load( QString("qt_%1").arg( lang ), qt_translations ) || trans->load( QString("qt_%1").arg( lang ), qt_dir_trpath ) )
-      QApplication::instance()->installTranslator( trans );
+    if ( trans->load( QString("qt_%1").arg( lang ), qt_translations ) || trans->load( QString("qt_%1").arg( lang ), qt_dir_trpath ) ) {
+      if ( QApplication::instance() ) QApplication::instance()->installTranslator( trans );
+    }
   }
 
   for ( QStringList::ConstIterator iter = prefixList.begin(); iter != prefixList.end(); ++iter )
@@ -2744,12 +2804,12 @@ void QtxResourceMgr::loadTranslators( const QString& prefix, const QStringList&
   {
     for ( QStringList::ConstIterator itr = translators.begin(); itr != translators.end(); ++itr )
     {
-      trans = (*it)->loadTranslator( resSection(), prefix, *itr );
+      trans = (*it)->loadTranslator( resSection(), prefix, *itr, myConstants );
       if ( trans )
       {
         if ( !myTranslator[prefix].contains( trans ) )
           myTranslator[prefix].append( trans );
-        QApplication::instance()->installTranslator( trans );
+        if ( QApplication::instance() ) QApplication::instance()->installTranslator( trans );
       }
     }
   }
@@ -2776,12 +2836,30 @@ void QtxResourceMgr::loadTranslator( const QString& prefix, const QString& name
     Resources* r = it.previous();
     if ( r == ur ) break;
 
-    trans = r->loadTranslator( resSection(), prefix, name );
+    trans = r->loadTranslator( resSection(), prefix, name, myConstants );
     if ( trans )
     {
       if ( !myTranslator[prefix].contains( trans ) )
         myTranslator[prefix].append( trans );
-      QApplication::instance()->installTranslator( trans );
+      if ( QApplication::instance() ) QApplication::instance()->installTranslator( trans );
+    }
+  }
+}
+
+/*!
+  \brief Add custom translator.
+  \param prefix parameter which defines translation context (for example, package name)
+  \param translator translator being installed
+  \sa loadLanguage(), loadTranslators()
+*/
+void QtxResourceMgr::addTranslator( const QString& prefix, QTranslator* translator )
+{
+  if ( translator )
+  {
+    if ( !myTranslator[prefix].contains( translator ) ) {
+      myTranslator[prefix].append( translator );
+      if ( QApplication::instance() )
+        QApplication::instance()->installTranslator( translator );
     }
   }
 }
@@ -2797,7 +2875,7 @@ void QtxResourceMgr::removeTranslators( const QString& prefix )
 
   for ( TransList::Iterator it = myTranslator[prefix].begin(); it != myTranslator[prefix].end(); ++it )
   {
-    QApplication::instance()->removeTranslator( *it );
+    if ( QApplication::instance() ) QApplication::instance()->removeTranslator( *it );
     delete *it;
   }
 
@@ -2816,8 +2894,10 @@ void QtxResourceMgr::raiseTranslators( const QString& prefix )
 
   for ( TransList::Iterator it = myTranslator[prefix].begin(); it != myTranslator[prefix].end(); ++it )
   {
-    QApplication::instance()->removeTranslator( *it );
-    QApplication::instance()->installTranslator( *it );
+    if ( QApplication::instance() ) {
+      QApplication::instance()->removeTranslator( *it );
+      QApplication::instance()->installTranslator( *it );
+    }
   }
 }