Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/gui.git] / src / SUIT / SUIT_TreeModel.cxx
index 718d42514683d4bee88e974fc1fc5299b367a5b1..9e45581385b0201a3e381128fa200c99d7fc96c2 100755 (executable)
@@ -1,35 +1,36 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  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
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File:   SUIT_TreeModel.cxx
 // Author: Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
-//
+
+#include "SUIT_Session.h"
 #include "SUIT_TreeModel.h"
 #include "SUIT_TreeSync.h"
 #include "SUIT_DataObject.h"
+#include "SUIT_ResourceMgr.h"
 
 #include <QApplication>
 #include <QHash>
+#include <QMimeData>
 
-SUIT_AbstractModel::SUIT_AbstractModel()
+SUIT_AbstractModel::SUIT_AbstractModel() : mySearcher( 0 )
 {
 }
 
@@ -48,9 +49,15 @@ SUIT_AbstractModel::operator const QObject*() const
   return dynamic_cast<const QObject*>( this );
 }
 
+SUIT_DataSearcher* SUIT_AbstractModel::searcher() const
+{
+  return mySearcher;
+}
 
-
-
+void SUIT_AbstractModel::setSearcher( SUIT_DataSearcher* s )
+{
+  mySearcher = s;
+}
 
 
 /*!
@@ -70,6 +77,7 @@ public:
   SUIT_DataObject*      dataObject() const;
   TreeItem*             parent() const;
   int                   position() const;
+  void                  setPosition(int position) {_position=position;};
   int                   childCount() const;
   TreeItem*             child( const int i );
   QList<TreeItem*>      children() const;
@@ -80,6 +88,7 @@ private:
   TreeItem*             myParent;
   QList<TreeItem*>      myChildren;
   SUIT_DataObject*      myObj;
+  int _position;
 };
 
 /*!
@@ -90,10 +99,11 @@ private:
   \param after tree item after each this one should be inserted
 */
 SUIT_TreeModel::TreeItem::TreeItem( SUIT_DataObject*          obj, 
-                                   SUIT_TreeModel::TreeItem* parent,
-                                   SUIT_TreeModel::TreeItem* after )
+                                    SUIT_TreeModel::TreeItem* parent,
+                                    SUIT_TreeModel::TreeItem* after )
 : myParent( parent ),
-  myObj( obj )
+  myObj( obj ),
+  _position(-1)
 {
   // Add <this> to the parent's children list
   if ( myParent )
@@ -123,12 +133,12 @@ SUIT_TreeModel::TreeItem::~TreeItem()
   \param after tree item after each \a child should be inserted
 */
 void SUIT_TreeModel::TreeItem::insertChild( SUIT_TreeModel::TreeItem* child, 
-                                           SUIT_TreeModel::TreeItem* after )
+                                            SUIT_TreeModel::TreeItem* after )
 {
   if ( !child )
     return;
 
-  int index = after ? myChildren.indexOf( after ) + 1 : 0;
+  int index = after ? after->position() + 1 : 0;
   myChildren.insert( index, child );
 }
 
@@ -171,7 +181,7 @@ SUIT_TreeModel::TreeItem* SUIT_TreeModel::TreeItem::parent() const
 */
 int SUIT_TreeModel::TreeItem::position() const
 {
-  return myParent ? myParent->myChildren.indexOf( (TreeItem*)this ) : -1;
+  return _position;
 }
 
 /*!
@@ -303,8 +313,8 @@ SUIT_TreeModel::ItemPtr SUIT_TreeModel::TreeSync::nullTrg() const
   \return created item
 */
 SUIT_TreeModel::ItemPtr SUIT_TreeModel::TreeSync::createItem( const ObjPtr&  obj,
-                                                             const ItemPtr& parent, 
-                                                             const ItemPtr& after ) const
+                                                              const ItemPtr& parent, 
+                                                              const ItemPtr& after ) const
 {
   ItemPtr item = myModel ? myModel->createItem( obj, parent, after ) : 0;
 
@@ -325,7 +335,7 @@ void SUIT_TreeModel::TreeSync::updateItem( const ObjPtr& obj, const ItemPtr& ite
   if( obj )
     obj->update();
   if ( item && needUpdate( item ) ) 
-    myModel->updateItem( item );
+    myModel->updateItem( item, false );
 }
 
 /*!
@@ -401,21 +411,21 @@ bool SUIT_TreeModel::TreeSync::needUpdate( const ItemPtr& item ) const
 /*      update = ( item->text( 0 ) != obj->name() ) || myBrowser->needToUpdateTexts( item );
 
       if ( !update ) { 
-       // 2. check pixmap (compare serialNumber()-s)
-       QPixmap objPix = obj->icon();
-       const QPixmap* itemPix = item->pixmap( 0 );
-       update = (  objPix.isNull() && (  itemPix && !itemPix->isNull() ) ) || 
-                ( !objPix.isNull() && ( !itemPix ||  itemPix->isNull() ) ); 
-       if ( !update && !objPix.isNull() && itemPix && !itemPix->isNull() ) {
-         int aIconW = objPix.width();
-         if( aIconW > 20 ) {
-           QWMatrix aM;
-           double aScale = 20.0 / aIconW;
-           aM.scale( aScale, aScale );
-           objPix = objPix.xForm( aM );
-         }
-         update = ( objPix.serialNumber() != itemPix->serialNumber() );
-       }
+        // 2. check pixmap (compare serialNumber()-s)
+        QPixmap objPix = obj->icon();
+        const QPixmap* itemPix = item->pixmap( 0 );
+        update = (  objPix.isNull() && (  itemPix && !itemPix->isNull() ) ) || 
+                 ( !objPix.isNull() && ( !itemPix ||  itemPix->isNull() ) ); 
+        if ( !update && !objPix.isNull() && itemPix && !itemPix->isNull() ) {
+          int aIconW = objPix.width();
+          if( aIconW > 20 ) {
+            QWMatrix aM;
+            double aScale = 20.0 / aIconW;
+            aM.scale( aScale, aScale );
+            objPix = objPix.xForm( aM );
+          }
+          update = ( objPix.serialNumber() != itemPix->serialNumber() );
+        }
       }*/
     }
   }
@@ -441,7 +451,8 @@ SUIT_TreeModel::SUIT_TreeModel( QObject* parent )
   myRoot( 0 ),
   myRootItem( 0 ),
   myAutoDeleteTree( false ),
-  myAutoUpdate( true )
+  myAutoUpdate( true ),
+  myUpdateModified( false )
 {
   initialize();
 }
@@ -456,7 +467,8 @@ SUIT_TreeModel::SUIT_TreeModel( SUIT_DataObject* root, QObject* parent )
   myRoot( root ),
   myRootItem( 0 ),
   myAutoDeleteTree( false ),
-  myAutoUpdate( true )
+  myAutoUpdate( true ),
+  myUpdateModified( false )
 {
   initialize();
 }
@@ -468,9 +480,9 @@ SUIT_TreeModel::~SUIT_TreeModel()
 {
   if ( autoDeleteTree() ) {
     SUIT_DataObject::disconnect( SIGNAL( inserted( SUIT_DataObject*, SUIT_DataObject* ) ),
-                                this, SLOT( onInserted( SUIT_DataObject*, SUIT_DataObject* ) ) );
+                                 this, SLOT( onInserted( SUIT_DataObject*, SUIT_DataObject* ) ) );
     SUIT_DataObject::disconnect( SIGNAL( removed( SUIT_DataObject*, SUIT_DataObject* ) ),
-                                this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) );
+                                 this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) );
     delete myRoot;
   }
 
@@ -486,22 +498,22 @@ SUIT_TreeModel::~SUIT_TreeModel()
 void SUIT_TreeModel::registerColumn( const int group_id, const QString& name, const int custom_id )
 {
   bool found = false;
-  for( int i=0, n=myColumns.size(); i<n && !found; i++ )
-    if( name==myColumns[i].myName )
-       {
-         myColumns[i].myIds.insert( group_id, custom_id );
-         found = true;
-       }
-  if( !found )
-  {
-       ColumnInfo inf;
-       inf.myName = name;
-       inf.myIds.insert( group_id, custom_id );
-       inf.myAppropriate = Qtx::Shown;
-       int n = myColumns.size();
-       myColumns.resize( n+1 );
-       myColumns[n] = inf;
-       reset();
+  for ( int i=0, n=myColumns.size(); i<n && !found; i++ ) {
+    if ( name == myColumns[i].myName ) {
+      myColumns[i].myIds.insert( group_id, custom_id );
+      found = true;
+    }
+  }
+  if ( !found ) {
+    ColumnInfo inf;
+    inf.myName = name;
+    inf.myIds.insert( group_id, custom_id );
+    inf.myAppropriate = Qtx::Shown;
+    inf.myHeaderFlags = Qtx::ShowAll;
+    int n = myColumns.size();
+    myColumns.resize( n+1 );
+    myColumns[n] = inf;
+    reset();
   }
 }
 
@@ -518,17 +530,16 @@ void SUIT_TreeModel::registerColumn( const int group_id, const QString& name, co
  */
 void SUIT_TreeModel::unregisterColumn( const int group_id, const QString& name )
 {
-  for( int i=0, n=myColumns.size(); i<n; i++ )
-    if( myColumns[i].myName==name )
-       {
-         myColumns[i].myIds.remove( group_id );
-         if( myColumns[i].myIds.isEmpty() )
-         {
-           myColumns.remove( i );
-               reset();
-         }
-         break;
+  for ( int i = 0, n = myColumns.size(); i < n; i++ ) {
+    if ( myColumns[i].myName == name ) {
+      myColumns[i].myIds.remove( group_id );
+      if ( myColumns[i].myIds.isEmpty() ) {
+       myColumns.remove( i );
+       reset();
+      }
+      break;
     }
+  }
 }
 
 /*!
@@ -539,12 +550,12 @@ void SUIT_TreeModel::unregisterColumn( const int group_id, const QString& name )
 */
 void SUIT_TreeModel::setColumnIcon( const QString& name, const QPixmap& icon )
 {
-  for( int i=0, n=myColumns.size(); i<n; i++ )
-    if( myColumns[i].myName==name )
-       {
-         myColumns[i].myIcon = icon;
-         break;
-       }
+  for ( int i = 0, n = myColumns.size(); i < n; i++ ) {
+    if ( myColumns[i].myName == name ) {
+      myColumns[i].myIcon = icon;
+      break;
+    }
+  }
 }
 
 /*!
@@ -556,12 +567,12 @@ void SUIT_TreeModel::setColumnIcon( const QString& name, const QPixmap& icon )
 QPixmap SUIT_TreeModel::columnIcon( const QString& name ) const
 {
   QPixmap res;
-  for( int i=0, n=myColumns.size(); i<n; i++ )
-    if( myColumns[i].myName==name )
-       {
-         res = myColumns[i].myIcon;
-         break;
-       }
+  for ( int i = 0, n = myColumns.size(); i < n; i++ ) {
+    if ( myColumns[i].myName == name ) {
+      res = myColumns[i].myIcon;
+      break;
+    }
+  }
   return res;
 }
 
@@ -579,13 +590,13 @@ QPixmap SUIT_TreeModel::columnIcon( const QString& name ) const
 */
 void SUIT_TreeModel::setAppropriate( const QString& name, const Qtx::Appropriate appr )
 {
-  for( int i=0, n=myColumns.size(); i<n; i++ )
-    if( myColumns[i].myName==name )
-       {
-         myColumns[i].myAppropriate = appr;
-         emit headerDataChanged( Qt::Horizontal, i, i );
-         break;
-       }
+  for ( int i = 0, n = myColumns.size(); i < n; i++ ) {
+    if ( myColumns[i].myName == name && myColumns[i].myAppropriate != appr ) {
+      myColumns[i].myAppropriate = appr;
+      emit headerDataChanged( Qt::Horizontal, i, i );
+      break;
+    }
+  }
 }
 
 /*!
@@ -601,16 +612,144 @@ void SUIT_TreeModel::setAppropriate( const QString& name, const Qtx::Appropriate
 Qtx::Appropriate SUIT_TreeModel::appropriate( const QString& name ) const
 {
   Qtx::Appropriate appr = Qtx::Shown;
-  for( int i=0, n=myColumns.size(); i<n; i++ )
-    if( myColumns[i].myName==name )
-       {
-         appr = myColumns[i].myAppropriate;
-         break;
-       }
+  for ( int i = 0, n = myColumns.size(); i < n; i++ ) {
+    if ( myColumns[i].myName == name ) {
+      appr = myColumns[i].myAppropriate;
+      break;
+    }
+  }
   return appr;
 }
 
 
+/*!
+  \brief Set header flags.
+  
+  These flags allow show in the header of the column text (name of the column),
+  icon or both text and icon.
+  
+  \param name - column name
+  \param flags - header flags
+
+*/
+void SUIT_TreeModel::setHeaderFlags( const QString& name, const Qtx::HeaderViewFlags flags )
+{
+  for ( int i = 0, n = myColumns.size(); i < n; i++ ) {
+    if ( myColumns[i].myName == name && myColumns[i].myHeaderFlags != flags ) {
+      myColumns[i].myHeaderFlags = flags;
+      emit headerDataChanged( Qt::Horizontal, i, i );
+      break;
+    }
+  }
+}
+
+/*!
+  \brief Get the  header flags.
+  
+  These flags allow show in the header of the column text (name of the column),
+  icon or both text and icon.
+  
+  \param name - column name
+  \return header flags
+*/
+Qtx::HeaderViewFlags SUIT_TreeModel::headerFlags( const QString& name ) const
+{
+  Qtx::HeaderViewFlags flags;
+  for ( int i = 0, n = myColumns.size(); i < n; i++ ) {
+    if ( myColumns[i].myName == name ) {
+      flags = myColumns[i].myHeaderFlags;
+      break;
+    }
+  }
+  return flags;
+}
+
+/*!
+  \brief Set visibility state of the object.
+  
+  \param id - column name
+  \param state - visible state
+*/
+void SUIT_TreeModel::setVisibilityState( const QString& id, Qtx::VisibilityState state )
+{
+  VisibilityMap::const_iterator it = myVisibilityMap.find( id );
+  if ( it != myVisibilityMap.end() && it.value() == state )
+    return;
+  
+  bool needSignal = false;
+  if ( state != Qtx::UnpresentableState ) {
+    myVisibilityMap.insert( id, state );
+    needSignal = true;
+  }
+  else {
+    needSignal = myVisibilityMap.remove( id ) > 0;
+  }
+  if ( needSignal ) {
+    QModelIndexList lst;
+    if ( searcher() ) {
+      SUIT_DataObject* o = searcher()->findObject( id );
+      if ( o ) lst << index( o );
+    }
+    else {
+      lst = match( index( 0, root()->customData( Qtx::IdType ).toInt() ), DisplayRole, id, 1, Qt::MatchExactly | Qt::MatchRecursive );
+    }
+    if ( !lst.isEmpty() ) {
+      QModelIndex idx = index( lst.first().row(), SUIT_DataObject::VisibilityId, lst.first().parent() );
+      emit dataChanged( idx, idx );
+    }
+  }
+}
+
+/*!
+  \brief Set visibility state for all objects.
+  
+  \param id - column name
+  \param state - visible state
+*/
+void SUIT_TreeModel::setVisibilityStateForAll( Qtx::VisibilityState state )
+{
+  if ( state != Qtx::UnpresentableState ) {
+    VisibilityMap::ConstIterator it = myVisibilityMap.begin();
+    while ( it != myVisibilityMap.end() ) {
+      if ( it.value() != state )
+       setVisibilityState( it.key(), state );
+      it++;
+    }
+  }
+  else {
+    QList<QString> anIds = myVisibilityMap.keys();
+    myVisibilityMap.clear();
+    QList<QString>::ConstIterator it = anIds.begin();
+    while ( it != anIds.end() ) {
+      QModelIndexList lst;
+      if ( searcher() ) {
+       SUIT_DataObject* o = searcher()->findObject( *it );
+       if ( o ) lst << index( o );
+      }
+      else {
+       lst = match( index( 0, root()->customData( Qtx::IdType ).toInt() ), DisplayRole, (*it), 1, Qt::MatchExactly | Qt::MatchRecursive );
+      }
+      if ( !lst.isEmpty() ) {
+       QModelIndex idx = index( lst.first().row(), SUIT_DataObject::VisibilityId ,lst.first().parent() );
+       emit dataChanged( idx, idx );
+      }
+      it++;
+    }
+  }
+}
+
+/*!
+  \brief Get visibility state of the object.
+  
+  \param id - column name
+  \return visible state
+*/
+Qtx::VisibilityState SUIT_TreeModel::visibilityState( const QString& id ) const
+{
+  VisibilityMap::const_iterator it = myVisibilityMap.find( id );
+  return it != myVisibilityMap.end() ? it.value() : Qtx::UnpresentableState;
+}
+
 /*!
   \brief Get data tree root object.
   \return data tree root
@@ -633,9 +772,9 @@ void SUIT_TreeModel::setRoot( SUIT_DataObject* r )
 
   if ( autoDeleteTree() ) {
     SUIT_DataObject::disconnect( SIGNAL( inserted( SUIT_DataObject*, SUIT_DataObject* ) ),
-                                this, SLOT( onInserted( SUIT_DataObject*, SUIT_DataObject* ) ) );
+                                 this, SLOT( onInserted( SUIT_DataObject*, SUIT_DataObject* ) ) );
     SUIT_DataObject::disconnect( SIGNAL( removed( SUIT_DataObject*, SUIT_DataObject* ) ),
-                                this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) );
+                                 this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) );
     delete myRoot;
   }
 
@@ -659,6 +798,8 @@ QVariant SUIT_TreeModel::data( const QModelIndex& index, int role ) const
     return QVariant();
 
   SUIT_DataObject* obj = object( index );
+  if ( !obj )
+    return QVariant();
 
   QColor c;
   QVariant val;
@@ -678,15 +819,38 @@ QVariant SUIT_TreeModel::data( const QModelIndex& index, int role ) const
   if ( obj )
   {
     switch ( role )
-       {
+        {
     case DisplayRole:
       // data object text for the specified column
-      val = obj->text( id ); 
+      val = obj->text( id );
       break;
-    case DecorationRole:
-      // data object icon for the specified column
-      val = obj->icon( id ); 
+    case EditRole:
+      // data object text for the specified column (for editor)
+      val = obj->text( id );
       break;
+    case DecorationRole: {
+      // icon
+      if ( id == SUIT_DataObject::VisibilityId ) {
+       // for visibility column, icon is defined specifically (using data object id)
+       QString objId = objectId( index );
+       if ( myVisibilityMap.contains( objId ) ) {
+         // visibility status is defined -> return proper icon
+         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();      
+         val  = ( myVisibilityMap.value( objId ) == Qtx::ShownState ) ? 
+           resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_VISIBLE" ) ) : 
+           resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_INVISIBLE" ) );
+       } 
+       else {
+         // visibility status is undefined -> no icon
+         val = QIcon();
+       }
+      }
+      else {
+       // for other columns get icon from the object
+       val = obj->icon( id );
+      }
+      break;
+    }
     case ToolTipRole:
       // data object tooltip for the specified column
       val = obj->toolTip( id ); 
@@ -711,7 +875,7 @@ QVariant SUIT_TreeModel::data( const QModelIndex& index, int role ) const
       // data background color for the specified column
       c = obj->color( SUIT_DataObject::Background, id );
       if( !c.isValid() ) // default value
-           c = QApplication::palette().color( QPalette::Base );
+            c = QApplication::palette().color( QPalette::Base );
       c.setAlpha( 0 );
       val = c; 
       break;
@@ -719,42 +883,42 @@ QVariant SUIT_TreeModel::data( const QModelIndex& index, int role ) const
       // data foreground (text) color for the specified column
       c = obj->color( SUIT_DataObject::Foreground, id );
       if( !c.isValid() ) // default value
-           c = QApplication::palette().color( QPalette::Foreground );
+            c = QApplication::palette().color( QPalette::Foreground );
       val = c; 
       break;
     case BaseColorRole:
       // editor background color for the specified column
       c = obj->color( SUIT_DataObject::Base, id );
       if( !c.isValid() ) // default value
-           c = QApplication::palette().color( QPalette::Base );
+            c = QApplication::palette().color( QPalette::Base );
       val = c; 
       break;
     case TextColorRole:
       // editor foreground (text) color for the specified column
       c = obj->color( SUIT_DataObject::Text, id );
       if( !c.isValid() ) // default value
-           c = QApplication::palette().color( QPalette::Text );
+            c = QApplication::palette().color( QPalette::Text );
       val = c; 
       break;
     case HighlightRole:
       // adta object highlighted background color for the specified column
       c = obj->color( SUIT_DataObject::Highlight, id );
       if( !c.isValid() ) // default value
-           c = QApplication::palette().color( QPalette::Highlight );
+            c = QApplication::palette().color( QPalette::Highlight );
       val = c; 
       break;
     case HighlightedTextRole:
       // data object highlighted foreground (text) color for the specified column
       c = obj->color( SUIT_DataObject::HighlightedText, id );
       if( !c.isValid() ) // default value
-           c = QApplication::palette().color( QPalette::HighlightedText );
+            c = QApplication::palette().color( QPalette::HighlightedText );
       val = c; 
       break;
     case CheckStateRole:
       // data object checked state for the specified column
       // NOTE! three-state check is not supported currently
       if( obj->isCheckable( id ) )
-           val = obj->isOn( id ) ? Qt::Checked : Qt::Unchecked; 
+            val = obj->isOn( id ) ? Qt::Checked : Qt::Unchecked; 
       break;
     case SizeHintRole:
       // data size hint
@@ -776,7 +940,7 @@ QVariant SUIT_TreeModel::data( const QModelIndex& index, int role ) const
   \sa data()
 */
 bool SUIT_TreeModel::setData( const QModelIndex& index, 
-                             const QVariant& value, int role )
+                              const QVariant& value, int role )
 {
   if ( index.isValid() && value.isValid() ) {
     SUIT_DataObject* obj = object( index );
@@ -784,15 +948,24 @@ bool SUIT_TreeModel::setData( const QModelIndex& index,
       // NOTE! only 'check state' data is supported by default
       switch ( role ) {
       case CheckStateRole:
-       // checked state
-       if ( obj->isCheckable( index.column() ) ) {
-         obj->setOn( value.toBool(), index.column() );
-         emit( dataChanged( index, index ) );
+        // checked state
+        if ( obj->isCheckable( index.column() ) ) {
+          obj->setOn( value.toBool(), index.column() );
+          emit( dataChanged( index, index ) );
+          return true;
+        }
+        break;
+      case EditRole: {
+       QString val = value.toString();
+        if ( !val.isEmpty() && obj->setName(val) ) {
+          emit( dataChanged( index, index ) );
          return true;
        }
-       break;
+       return false;
+        break;
+      }
       default:
-       break;
+        break;
       }
     }
   }
@@ -806,28 +979,48 @@ bool SUIT_TreeModel::setData( const QModelIndex& index,
 */
 Qt::ItemFlags SUIT_TreeModel::flags( const QModelIndex& index ) const
 {
-  if ( !index.isValid() )
-    return 0;
-
-  SUIT_DataObject* obj = object( index );
   Qt::ItemFlags f = 0;
 
-  if ( obj ) {
+  if (!index.isValid())
+    //return Qt::ItemIsDropEnabled; // items can be dropped into the top level of the model
+    return f;
+
+  SUIT_DataObject* obj = object(index);
+
+  if (obj) {
     // data object is enabled
-    if ( obj->isEnabled() )
+    if (obj->isEnabled())
       f = f | Qt::ItemIsEnabled;
 
     // data object is selectable
-    if ( obj->isSelectable() )
+    if (obj->isSelectable())
       f = f | Qt::ItemIsSelectable;
 
     // data object is checkable
-    if ( obj->isCheckable( index.column() ) )
+    if (obj->isCheckable(index.column()))
       f = f | Qt::ItemIsUserCheckable;
+    
+    // data object can be renamed
+    if (obj->renameAllowed(index.column()))
+      f = f | Qt::ItemIsEditable;
+    
+    // data object can be dragged
+    if (obj->isDraggable())
+      f = f | Qt::ItemIsDragEnabled;
+    
+    // another data object(s) can be dropped on this one
+    if (obj->isDropAccepted())
+      f = f | Qt::ItemIsDropEnabled;
   }
+
   return f;
 }
 
+Qt::DropActions SUIT_TreeModel::supportedDropActions() const
+{
+  return Qt::CopyAction | Qt::MoveAction;
+}
+
 /*!
   \brief Get header data (can be used in any data view).
   \param column column number
@@ -842,14 +1035,22 @@ QVariant SUIT_TreeModel::headerData( int column, Qt::Orientation orientation, in
   if ( root() && orientation == Qt::Horizontal )
   {
     switch ( role )
-       {
+        {
     case DisplayRole:
       // column title
-      d = myColumns[column].myName;
+      if((myColumns[column].myHeaderFlags & Qtx::ShowText) || 
+        (myColumns[column].myHeaderFlags == Qtx::ShowAll)) 
+       d = myColumns[column].myName;
+      else
+       d = QString();
       break;
     case DecorationRole:
       // column icon
-      d = myColumns[column].myIcon;
+      if((myColumns[column].myHeaderFlags & Qtx::ShowIcon) || 
+        (myColumns[column].myHeaderFlags == Qtx::ShowAll)) 
+       d = myColumns[column].myIcon;
+      else
+       d = QIcon();      
       break;
     case AppropriateRole:
       // appropriate flag (can column be hidden via context popup menu)
@@ -870,7 +1071,7 @@ QVariant SUIT_TreeModel::headerData( int column, Qt::Orientation orientation, in
   \return model index
 */
 QModelIndex SUIT_TreeModel::index( int row, int column, 
-                                  const QModelIndex& parent ) const
+                                   const QModelIndex& parent ) const
 {
   if( hasIndex( row, column, parent ) )
   {
@@ -879,7 +1080,7 @@ QModelIndex SUIT_TreeModel::index( int row, int column,
     {
       TreeItem* childItem = parentItem->child( row );
       if( childItem )
-       return createIndex( row, column, childItem );
+        return createIndex( row, column, childItem );
     }
   }
   return QModelIndex();
@@ -923,8 +1124,10 @@ int SUIT_TreeModel::columnCount( const QModelIndex& /*parent*/ ) const
 */
 int SUIT_TreeModel::rowCount( const QModelIndex& parent ) const
 {
-  if ( parent.column() > 0 )
-    return 0;
+  // Commented by rnv in the frame of the 
+  // "20830: EDF 1357 GUI : Hide/Show Icon" imp
+  // if ( parent.column() > 0 )
+  // return 0;
 
   TreeItem* parentItem = treeItem( parent );
 
@@ -1006,21 +1209,37 @@ void SUIT_TreeModel::setAutoUpdate( const bool on )
     return;
 
   SUIT_DataObject::disconnect( SIGNAL( inserted( SUIT_DataObject*, SUIT_DataObject* ) ),
-                              this, SLOT( onInserted( SUIT_DataObject*, SUIT_DataObject* ) ) );
+                               this, SLOT( onInserted( SUIT_DataObject*, SUIT_DataObject* ) ) );
   SUIT_DataObject::disconnect( SIGNAL( removed( SUIT_DataObject*, SUIT_DataObject* ) ),
-                              this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) );
+                               this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) );
   myAutoUpdate = on;
 
   if ( myAutoUpdate ) {
     SUIT_DataObject::connect( SIGNAL( inserted( SUIT_DataObject*, SUIT_DataObject* ) ),
-                             this, SLOT( onInserted( SUIT_DataObject*, SUIT_DataObject* ) ) );
+                              this, SLOT( onInserted( SUIT_DataObject*, SUIT_DataObject* ) ) );
     SUIT_DataObject::connect( SIGNAL( removed( SUIT_DataObject*, SUIT_DataObject* ) ),
-                             this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) );
+                              this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) );
 
     updateTree();
   }
 }
 
+/*!
+  \brief Get 'updateModified' flag value.
+  \return 'updateModified' flag value
+*/
+bool SUIT_TreeModel::updateModified() const
+{
+  return myUpdateModified;
+}
+/*!
+  \brief Set 'updateModified' flag value.
+  \param on 'updateModified' flag value
+*/
+void SUIT_TreeModel::setUpdateModified(const bool on)
+{
+  myUpdateModified=on;
+}
 
 /*!
   \brief Check if the specified column supports custom sorting.
@@ -1033,6 +1252,11 @@ bool SUIT_TreeModel::customSorting( const int column ) const
   return root() ? root()->customSorting( column ) : false;
 }
 
+void SUIT_TreeModel::forgetObject( const SUIT_DataObject* obj )
+{
+  removeItem( treeItem( obj ) );
+}
+
 /*!
   \brief Compares two model indexes for the sorting purposes.
 
@@ -1060,6 +1284,19 @@ QAbstractItemDelegate* SUIT_TreeModel::delegate() const
   return new SUIT_ItemDelegate( const_cast<SUIT_TreeModel*>( this ) );
 }
 
+
+void SUIT_TreeModel::emitClicked( SUIT_DataObject* obj, const QModelIndex& index) {
+  int obj_group_id = obj->groupId();
+  const ColumnInfo& inf = myColumns[index.column()];
+
+  int id = -1;
+  if( inf.myIds.contains( 0 ) )
+    id = inf.myIds[0];
+  if( inf.myIds.contains( obj_group_id ) )
+    id = inf.myIds[obj_group_id];
+  emit clicked(obj, id);
+}
+
 /*!
   \brief Update tree model.
 
@@ -1075,6 +1312,68 @@ void SUIT_TreeModel::updateTree( const QModelIndex& index )
   updateTree( object( index ) );
 }
 
+
+void SUIT_TreeModel::updateTreeModel(SUIT_DataObject* obj,TreeItem* item)
+{
+  int kobj=0;
+  int kitem=0;
+  int nobjchild=obj->childCount();
+  SUIT_DataObject* sobj=obj->childObject(kobj);
+  TreeItem* sitem = item->child(kitem);
+
+  while(kobj < nobjchild)
+    {
+      if(sitem==0)
+        {
+          //end of item list
+          if(kitem==0)
+            sitem=createItemAtPos(sobj,item,0);
+          else
+            sitem=createItemAtPos(sobj,item,kitem);
+          updateTreeModel(sobj,sitem);
+          kobj++;
+          kitem++;
+          sobj=obj->childObject(kobj);
+          sitem = item->child(kitem);
+        }
+      else if(sitem->dataObject() != sobj)
+        {
+          if(treeItem(sobj))
+            {
+              // item : to remove
+              removeItem(sitem);
+              sitem = item->child(kitem);
+            }
+          else
+            {
+              // obj : new object
+              createItemAtPos(sobj,item,kitem);
+              kobj++;
+              kitem++;
+              sobj=obj->childObject(kobj);
+              sitem = item->child(kitem);
+            }
+        }
+      else
+        {
+          //obj and item are synchronised : go to next ones
+          updateTreeModel(sobj,sitem);
+          if(sobj->modified()) updateItem(sitem, true);
+          if( sobj ) sobj->update();
+          kobj++;
+          kitem++;
+          sobj=obj->childObject(kobj);
+          sitem = item->child(kitem);
+        }
+    }
+  //remove remaining items
+  for(int i = item->childCount(); i > kitem;i--)
+    {
+      sitem = item->child(i-1);
+      removeItem(sitem);
+    }
+}
+
 /*!
   \brief Update tree model.
 
@@ -1093,9 +1392,16 @@ void SUIT_TreeModel::updateTree( SUIT_DataObject* obj )
   else if ( obj->root() != root() )
     return;
 
-  synchronize<ObjPtr,ItemPtr,SUIT_TreeModel::TreeSync>( obj, 
-                                                       treeItem( obj ), 
-                                                       SUIT_TreeModel::TreeSync( this ) );
+  if(updateModified())
+    {
+      updateTreeModel(obj,treeItem( obj ));
+    }
+  else
+    {
+      synchronize<ObjPtr,ItemPtr,SUIT_TreeModel::TreeSync>( obj,
+                                                            treeItem( obj ),
+                                                            SUIT_TreeModel::TreeSync( this ) );
+    }
   emit modelUpdated();
 }
 
@@ -1105,14 +1411,14 @@ void SUIT_TreeModel::updateTree( SUIT_DataObject* obj )
 void SUIT_TreeModel::initialize()
 {
   SUIT_DataObject::disconnect( SIGNAL( inserted( SUIT_DataObject*, SUIT_DataObject* ) ),
-                              this, SLOT( onInserted( SUIT_DataObject*, SUIT_DataObject* ) ) );
+                               this, SLOT( onInserted( SUIT_DataObject*, SUIT_DataObject* ) ) );
   SUIT_DataObject::disconnect( SIGNAL( removed( SUIT_DataObject*, SUIT_DataObject* ) ),
-                              this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) );
+                               this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) );
   if ( autoUpdate() ) {
     SUIT_DataObject::connect( SIGNAL( inserted( SUIT_DataObject*, SUIT_DataObject* ) ),
-                             this, SLOT( onInserted( SUIT_DataObject*, SUIT_DataObject* ) ) );
+                              this, SLOT( onInserted( SUIT_DataObject*, SUIT_DataObject* ) ) );
     SUIT_DataObject::connect( SIGNAL( removed( SUIT_DataObject*, SUIT_DataObject* ) ),
-                             this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) );
+                              this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) );
   }
 
   myItems.clear(); // ????? is it really necessary
@@ -1121,6 +1427,14 @@ void SUIT_TreeModel::initialize()
     myRootItem = new TreeItem( 0 );
 
   registerColumn( 0, QObject::tr( "NAME_COLUMN" ), SUIT_DataObject::NameId );
+
+  QString visCol = QObject::tr( "VISIBILITY_COLUMN" );
+  registerColumn( 0, visCol, SUIT_DataObject::VisibilityId );
+
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+  setColumnIcon( visCol, resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_VISIBLE" ) ));
+  setHeaderFlags( visCol, Qtx::ShowIcon);
+
   updateTree();
 }
 
@@ -1174,6 +1488,28 @@ SUIT_DataObject* SUIT_TreeModel::object( const SUIT_TreeModel::TreeItem* item )
   return myItems.contains( obj ) ? obj : 0;
 }
 
+/*!
+  \brief Get unique object identifier
+  
+  Object identifier is customized via the Qtx::IdType custom data
+
+  \param index model index
+  \return object identifier or null string if it isn't specified
+  \sa SUIT_DataObject::customData()
+*/
+QString SUIT_TreeModel::objectId( const QModelIndex& index ) const
+{
+  QString objId;
+  if ( index.isValid() ) {
+    SUIT_DataObject* obj = object( index );
+    if ( obj ) {
+      int anId = obj->customData( Qtx::IdType ).toInt(); 
+      objId = data( createIndex( index.row(), anId, index.internalPointer() ) ).toString();
+    }
+  }
+  return objId;
+}
+
 /*!
   \brief Create an item corresponding to the data object.
   \param obj source data object
@@ -1182,8 +1518,8 @@ SUIT_DataObject* SUIT_TreeModel::object( const SUIT_TreeModel::TreeItem* item )
   \return created tree item or 0 if item could not be created
 */
 SUIT_TreeModel::TreeItem* SUIT_TreeModel::createItem( SUIT_DataObject* obj,
-                                                     SUIT_TreeModel::TreeItem* parent, 
-                                                     SUIT_TreeModel::TreeItem* after )
+                                                      SUIT_TreeModel::TreeItem* parent, 
+                                                      SUIT_TreeModel::TreeItem* after )
 {
   if ( !obj )
     return 0;
@@ -1198,16 +1534,57 @@ SUIT_TreeModel::TreeItem* SUIT_TreeModel::createItem( SUIT_DataObject* obj,
 
   myItems[ obj ] = new TreeItem( obj, parent, after );
 
+  for(int pos=row;pos < parent->childCount();pos++)
+    parent->child(pos)->setPosition(pos);
+
   endInsertRows();
 
+  obj->setModified(false);
+
   return myItems[ obj ];
 }
 
+/*!
+  \brief Create an item corresponding to the data object.
+  \param obj source data object
+  \param parent parent tree item
+  \param pos tree item position into which new item should be inserted
+  \return created tree item or 0 if item could not be created
+*/
+SUIT_TreeModel::TreeItem* SUIT_TreeModel::createItemAtPos( SUIT_DataObject* obj,
+                                                           SUIT_TreeModel::TreeItem* parent,
+                                                           int pos )
+{
+  if ( !obj )
+    return 0;
+
+  SUIT_DataObject* parentObj = object( parent );
+  QModelIndex parentIdx = index( parentObj );
+
+  int row = pos ;
+  SUIT_TreeModel::TreeItem* after = pos>0 ? parent->child(pos-1) : 0 ;
+
+  beginInsertRows( parentIdx, row, row );
+
+  SUIT_TreeModel::TreeItem* item = new TreeItem( obj, parent, after );
+  myItems[ obj ] = item;
+
+  for(int pos=row;pos < parent->childCount();pos++)
+    parent->child(pos)->setPosition(pos);
+
+  endInsertRows();
+
+  obj->setModified(false);
+
+  return item;
+}
+
 /*!
   \brief Update tree item.
   \param item tree item to be updated
+  \param emitLayoutChanged if signal about changed layout should be emitted
 */
-void SUIT_TreeModel::updateItem( SUIT_TreeModel::TreeItem* item )
+void SUIT_TreeModel::updateItem( SUIT_TreeModel::TreeItem* item, bool emitLayoutChanged )
 {
   if ( !item )
     return;
@@ -1217,9 +1594,13 @@ void SUIT_TreeModel::updateItem( SUIT_TreeModel::TreeItem* item )
     return;
   
   // update all columns corresponding to the given data object
+  //emit layoutAboutToBeChanged(); // VSR 25/04/2011: fix crash on delete objects
   QModelIndex firstIdx = index( obj, 0 );
   QModelIndex lastIdx  = index( obj, columnCount() - 1 );
   emit dataChanged( firstIdx, lastIdx );
+  obj->setModified(false);
+  if( emitLayoutChanged )
+    emit layoutChanged();
 }
 
 /*!
@@ -1241,7 +1622,8 @@ void SUIT_TreeModel::removeItem( SUIT_TreeModel::TreeItem* item )
   
   // Warning! obj can be deleted at this point!
 
-  SUIT_DataObject* parentObj = object( item->parent() );
+  TreeItem* parent=item->parent();
+  SUIT_DataObject* parentObj = object( parent );
   QModelIndex parentIdx = index( parentObj, 0 );
   int row = item->position();
   
@@ -1250,8 +1632,12 @@ void SUIT_TreeModel::removeItem( SUIT_TreeModel::TreeItem* item )
 
   if ( obj == root() )
     setRoot( 0 );
-  else if ( item->parent() )
-    item->parent()->removeChild( item );
+  else if ( parent )
+    {
+      parent->removeChild( item );
+      for(int pos=row;pos < parent->childCount();pos++)
+        parent->child(pos)->setPosition(pos);
+    }
 
   delete item;
 
@@ -1280,9 +1666,85 @@ void SUIT_TreeModel::onRemoved( SUIT_DataObject* /*object*/, SUIT_DataObject* pa
     updateTree( parent );
 }
 
+/*!
+  \brief Drag and Drop support.
+*/
+QStringList SUIT_TreeModel::mimeTypes() const
+{
+  QStringList types;
+  types << "application/vnd.text.list";
+  return types;
+}
+
+/*!
+  \brief Called when the data objects are exported(dragged) from the tree.
+  \param indexes the list of exported objects
+*/
+QMimeData* SUIT_TreeModel::mimeData( const QModelIndexList& indexes ) const
+{
+  QMimeData* mimeData = new QMimeData();
+  QByteArray encodedData;
+
+  QDataStream stream( &encodedData, QIODevice::WriteOnly );
+
+  foreach ( QModelIndex index, indexes ) {
+    QString id = objectId( index );
+    // we have to check only 0 column in order to avoid repeating items in the drag object
+    // - QTreeView tries to drag indices for all visible columns
+    if ( index.isValid() && index.column() == 0 && !id.isEmpty() )
+      stream << id;
+  }
+
+  mimeData->setData( "application/vnd.text.list", encodedData );
+  return mimeData;
+}
+
+bool SUIT_TreeModel::dropMimeData( const QMimeData* data, Qt::DropAction action,
+                                   int row, int column, const QModelIndex& parent )
+{
+  if ( action == Qt::IgnoreAction )
+    // do nothing with data
+    return false;
+
+  if ( !data->hasFormat( "application/vnd.text.list" ) )
+    // not supported data dropped
+    return false;
+
+  if ( !parent.isValid() )
+    // dropping into the top level of the model is not allowed
+    return false;
+
+  // get parent object
+  SUIT_DataObject* pobj = object( parent );
+  if ( !pobj )
+    // invalid parent
+    return false;
+
+  // decode mime data and collect data objects being dropped
+  QByteArray encodedData = data->data( "application/vnd.text.list" );
+  QDataStream stream( &encodedData, QIODevice::ReadOnly );
+  
+  DataObjectList objects;
+
+  while ( !stream.atEnd() ) {
+    QString id;
+    stream >> id;
+    if ( !id.isEmpty() && searcher() ) {
+      SUIT_DataObject* obj = searcher()->findObject( id );
+      if ( obj ) objects << obj;
+    }
+  }
+
+  // emit signal
+  emit dropped( objects, pobj, row, action );
+
+  // return true if there's any to drop
+  return !objects.isEmpty();
+}
+
 /*!
   \class SUIT_ProxyModel
-  \brief Proxy model which can be used above the SUIT_TreeMovel class
+  \brief Proxy model which can be used above the SUIT_TreeModel class
   to enable custom sorting/filtering of the data.
 
   The SUIT_TreeModel class does not support custom sorting/filtering of the data.
@@ -1300,7 +1762,11 @@ SUIT_ProxyModel::SUIT_ProxyModel( QObject* parent )
 {
   SUIT_TreeModel* model = new SUIT_TreeModel( this );
   connect( model, SIGNAL( modelUpdated() ), this, SIGNAL( modelUpdated() ) );
+  connect( model, SIGNAL( clicked( SUIT_DataObject*, int ) ), this, SIGNAL(clicked( SUIT_DataObject*, int ) ) );
+  connect( model, SIGNAL( dropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ),
+           this,  SIGNAL( dropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ) );
   setSourceModel( model );
+  setDynamicSortFilter( true );
 }
 
 /*!
@@ -1314,7 +1780,11 @@ SUIT_ProxyModel::SUIT_ProxyModel( SUIT_DataObject* root, QObject* parent )
 {
   SUIT_TreeModel* model = new SUIT_TreeModel( root, this );
   connect( model, SIGNAL( modelUpdated() ), this, SIGNAL( modelUpdated() ) );
+  connect( model, SIGNAL( clicked( SUIT_DataObject*, int ) ), this, SIGNAL( clicked( SUIT_DataObject*, int ) ) );
+  connect( model, SIGNAL( dropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ),
+           this,  SIGNAL( dropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ) );
   setSourceModel( model );
+  setDynamicSortFilter( true );
 }
 
 /*!
@@ -1327,7 +1797,11 @@ SUIT_ProxyModel::SUIT_ProxyModel( SUIT_AbstractModel* model, QObject* parent )
   mySortingEnabled( true )
 {
   connect( *model, SIGNAL( modelUpdated() ), this, SIGNAL( modelUpdated() ) );
+  connect( *model, SIGNAL( clicked( SUIT_DataObject*, int ) ), this, SIGNAL( clicked( SUIT_DataObject*, int ) ) );
+  connect( *model, SIGNAL( dropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ),
+           this,   SIGNAL( dropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ) );
   setSourceModel( *model );
+  setDynamicSortFilter( true );
 }
 
 /*!
@@ -1414,6 +1888,28 @@ bool SUIT_ProxyModel::autoUpdate() const
   return treeModel() ? treeModel()->autoUpdate() : false;
 }
 
+/*!
+  \brief Get 'updateModified' flag value.
+  \return 'updateModified' flag value
+*/
+bool SUIT_ProxyModel::updateModified() const
+{
+  return treeModel() ? treeModel()->updateModified() : false;
+}
+/*!
+  \brief Set 'updateModified' flag value.
+
+  If this flag is set to \c true (default=false), the model is updated by updateTreeModel that 
+  uses the isModified flag to update only modified objects
+
+  \param on 'updateModified' flag value
+*/
+void SUIT_ProxyModel::setUpdateModified( const bool on )
+{
+  if ( treeModel() )
+    treeModel()->setUpdateModified( on );
+}
+
 /*!
   \brief Set 'auto-update tree' flag value.
 
@@ -1439,6 +1935,16 @@ bool SUIT_ProxyModel::isSortingEnabled() const
   return mySortingEnabled;
 }
 
+SUIT_DataSearcher* SUIT_ProxyModel::searcher() const
+{
+  return treeModel() ? treeModel()->searcher() : 0;
+}
+
+void SUIT_ProxyModel::setSearcher( SUIT_DataSearcher* s )
+{
+  if ( treeModel() ) treeModel()->setSearcher( s );
+}
+
 /*!
   \brief Get item delegate for the model.
   \return new item delegate
@@ -1480,6 +1986,12 @@ void SUIT_ProxyModel::updateTree( SUIT_DataObject* obj )
     treeModel()->updateTree( obj );
 }
 
+void SUIT_ProxyModel::forgetObject( const SUIT_DataObject* obj )
+{
+  if ( treeModel() )
+    treeModel()->forgetObject( obj );
+}
+
 /*!
   \brief Compares two model indexes for the sorting purposes.
   \param left first index to compare
@@ -1528,6 +2040,19 @@ SUIT_AbstractModel* SUIT_ProxyModel::treeModel() const
   return dynamic_cast<SUIT_AbstractModel*>( sourceModel() );
 }
 
+/*!
+  \brief Filter rows
+  \param sourceRow row index of the source data model
+  \param sourceParent parent model index of the source data model
+  \return \c true if the specified row should be filtered out (i.e. not displayed) or \c false otherwise
+*/
+bool SUIT_ProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const
+{
+  SUIT_DataObject* o = treeModel()->object( sourceModel()->index( sourceRow, 0, sourceParent ) );
+  SUIT_DataObject* p = o ? o->parent() : 0;
+  return ( !p || p->expandable() ) && o && o->isVisible();
+}
+
 /*!
   \brief Register new column in the model
   \param group_id - unique data object identificator allowing the classification of objects 
@@ -1613,10 +2138,76 @@ Qtx::Appropriate SUIT_ProxyModel::appropriate( const QString& name ) const
   return treeModel() ? treeModel()->appropriate( name ) : Qtx::Shown;
 }
 
+/*!
+  \brief Set header flags.
+  
+  These flags allow show in the header of the column text (name of the column),
+  icon or both text and icon.
+  
+  \param name - column name
+  \param flags - header flags
+
+*/
+void SUIT_ProxyModel::setHeaderFlags( const QString& name, const Qtx::HeaderViewFlags flags )
+{
+  if(treeModel())
+    treeModel()->setHeaderFlags(name, flags);
+}
+
+/*!
+  \brief Get the  header flags.
+  
+  These flags allow show in the header of the column text (name of the column),
+  icon or both text and icon.
+  
+  \param name - column name
+  \return header flags
+*/
+Qtx::HeaderViewFlags SUIT_ProxyModel::headerFlags( const QString& name ) const
+{
+  return treeModel() ? treeModel()->headerFlags( name ) : Qtx::ShowAll;
+}
 
+/*!
+  \brief Set visibility state of the object.
+  
+  \param id - column name
+  \param state - visible state
+*/
+void SUIT_ProxyModel::setVisibilityState(const QString& id, Qtx::VisibilityState state)
+{
+  if(treeModel())
+    treeModel()->setVisibilityState(id,state);
+}
 
+/*!
+  \brief Set visibility state for all objects.
+  
+  \param id - column name
+  \param state - visible state
+*/
+void SUIT_ProxyModel::setVisibilityStateForAll(Qtx::VisibilityState state)
+{
+  if(treeModel())
+    treeModel()->setVisibilityStateForAll(state);
+}
 
+/*!
+  \brief Get visibility state of the object.
+  
+  \param id - column name
+  \return visible state
+*/
+Qtx::VisibilityState SUIT_ProxyModel::visibilityState(const QString& id) const
+{
+  return treeModel() ? treeModel()->visibilityState(id) : Qtx::UnpresentableState;
+}
 
+void SUIT_ProxyModel::emitClicked( SUIT_DataObject* obj, const QModelIndex& index)
+{
+  if(treeModel())
+    treeModel()->emitClicked(obj,index);
+}
 
 /*!
   \class SUIT_ItemDelegate
@@ -1647,8 +2238,8 @@ SUIT_ItemDelegate::SUIT_ItemDelegate( QObject* parent )
   \param index model index being rendered
 */
 void SUIT_ItemDelegate::paint( QPainter* painter, 
-                              const QStyleOptionViewItem& option,
-                              const QModelIndex& index ) const
+                               const QStyleOptionViewItem& option,
+                               const QModelIndex& index ) const
 {
   QStyleOptionViewItem opt = option;
   if ( index.isValid() ) {
@@ -1668,7 +2259,16 @@ void SUIT_ItemDelegate::paint( QPainter* painter,
       opt.palette.setBrush( QPalette::Highlight, val.value<QColor>() );
     val = index.data( SUIT_TreeModel::HighlightedTextRole );
     if ( val.isValid() && val.value<QColor>().isValid() )
-      opt.palette.setBrush( QPalette::HighlightedText, val.value<QColor>() );
+      opt.palette.setBrush( QPalette::HighlightedText, val.value<QColor>() );      
   }
   QItemDelegate::paint( painter, opt, index );
 }
+
+QSize SUIT_ItemDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const
+{
+    QSize size = QItemDelegate::sizeHint ( option, index );
+#if QT_VERSION >= 0x040500
+    size.setHeight( size.height() + 1 );
+#endif
+    return size;
+}