X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESHGUI%2FSMESHGUI_MeshInfo.cxx;h=07239f41cbe9902820144ae1a33c6ca8df2c56b2;hp=4fb23cb4eb9458873dc9d758e081fd77eb4f13b6;hb=cc85955178440fffe36eef234d759e3c3590248f;hpb=9d296302bce45a19ce73bcb52e86884ba38f1199 diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx index 4fb23cb4e..07239f41c 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx @@ -19,18 +19,11 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : SMESHGUI_MeshInfo.cxx -// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) #include "SMESHGUI_MeshInfo.h" -#include "SMDSAbs_ElementType.hxx" -#include "SMDS_BallElement.hxx" -#include "SMDS_EdgePosition.hxx" -#include "SMDS_FacePosition.hxx" #include "SMDS_Mesh.hxx" -#include "SMDS_VolumeTool.hxx" -#include "SMESHDS_Mesh.hxx" +#include "SMESH_Actor.h" #include "SMESHGUI.h" #include "SMESHGUI_FilterUtils.h" #include "SMESHGUI_IdPreview.h" @@ -38,21 +31,20 @@ #include "SMESHGUI_SpinBox.h" #include "SMESHGUI_Utils.h" #include "SMESHGUI_VTKUtils.h" -#include "SMESH_Actor.h" -#include #include #include #include #include #include +#include #include -#include #include #include #include +#include #include #include #include @@ -63,67 +55,406 @@ #include #include #include -#include #include -#include +#include +#include #include #include +#include +#include +#include #include -#include "utilities.h" +//////////////////////////////////////////////////////////////////////////////// +/// \class Field +/// \brief Field widget. +/// \internal +//////////////////////////////////////////////////////////////////////////////// -#include -#include CORBA_SERVER_HEADER(GEOM_Gen) +class Field : public QLabel +{ +public: + Field( QWidget*, const QString& = QString() ); + bool event( QEvent* ); +}; -namespace { +/*! + \brief Constructor. + \param parent Parent widget. + \param name Field name. Defauls to null string. +*/ +Field::Field( QWidget* parent, const QString& name ): QLabel( parent ) +{ + setFrameStyle( QLabel::StyledPanel | QLabel::Sunken ); + setAlignment( Qt::AlignCenter ); + setAutoFillBackground( true ); + QPalette pal = palette(); + QColor base = QApplication::palette().color( QPalette::Active, QPalette::Base ); + pal.setColor( QPalette::Window, base ); + setPalette( pal ); + setMinimumWidth( 60 ); + if ( !name.isEmpty() ) + setObjectName( name ); +} - const int SPACING = 6; - const int MARGIN = 9; - const int MAXITEMS = 10; - const int GROUPS_ID = 100; - const int SUBMESHES_ID = 200; - const int SPACING_INFO = 2; +/*! + \brief Event handler. Redefined from QLabel. +*/ +bool Field::event( QEvent* e ) +{ + if ( e->type() == QEvent::DynamicPropertyChange ) + { + QDynamicPropertyChangeEvent* ce = (QDynamicPropertyChangeEvent*)e; + if ( ce->propertyName() == "value" && property( "value" ).isValid() ) + { + setText( QString::number( property( "value" ).toInt() ) ); + setProperty( "value", QVariant() ); + return true; + } + } + return QLabel::event( e ); +} - const char* id_preview_resource = "id_preview_resource"; +//////////////////////////////////////////////////////////////////////////////// +/// \class TreeItemCreator +/// \brief Generic tree item creator. +/// \internal +//////////////////////////////////////////////////////////////////////////////// - enum InfoRole { +class TreeItemCreator +{ +public: + TreeItemCreator() {} + virtual ~TreeItemCreator() {} + virtual QTreeWidgetItem* createItem( QTreeWidgetItem*, int ) = 0; +}; + +//////////////////////////////////////////////////////////////////////////////// +// General purpose services. +//////////////////////////////////////////////////////////////////////////////// + +namespace +{ + const int SPACING = 6; + const int MARGIN = 9; + + enum + { + Bold = 0x01, + Italic = 0x02, + AllColumns = 0x04, + Expanded = 0x08, + Editable = 0x10 + }; + + enum + { + GroupsId = 100, + SubMeshesId + }; + + enum + { TypeRole = Qt::UserRole + 10, IdRole, }; - enum InfoType { + enum + { NodeConnectivity = 100, ElemConnectivity, }; -} // namesapce + + /*! + \brief Get item's depth in the tree. + \param item Tree widget item. + \return Item's depth in the tree widget (top-level item has zero depth). + \internal + */ + int itemDepth( QTreeWidgetItem* item ) + { + QList parents; + parents << item; + while ( parents.last()->parent() ) + parents << parents.last()->parent(); + return parents.size()-1; + } + + /*! + \brief Get chunk size. + \return Chunk size. + \internal + */ + int blockSize() + { + return 10; + } + + /*! + \brief Get spacer. + \return Spacer string. + \internal + */ + QString spacing() + { + static int size = 1; + static QChar spacer = ' '; + return QString( size, spacer ); + } + + /*! + \brief Get indent. + \param length Indent size. Defaults to 1. + \return Indentation string. + \internal + */ + QString indent( int length = 1 ) + { + static int size = 4; + static QChar spacer = ' '; + return QString( size * length, spacer ); + } + + /*! + \brief Get indent. + \param spacer Spacer. + \param length Indent size. Defaults to 1. + \return Indentation string. + \internal + */ + QString indent( const QString& spacer, uint length = 1 ) + { + QString result; + while( length-- > 0 ) + result += spacer; + return result; + } + + /*! + \brief Get group separator. + \param length Length of ruler (number of symbols). Defaults to 80. + \return Ruler string. + \internal + */ + QString ruler( int length = 80 ) + { + static QChar ruler = '-'; + return QString( length, ruler ); + } + + /*! + \brief Get text value from label. + \param w Widget (QLabel). + \return Value string. + \internal + */ + QString widgetValue( QWidget* w ) + { + QString v; + if ( qobject_cast( w ) ) + v = qobject_cast( w )->text(); + return v; + } + + /*! + \brief Get font for given options. + \param font Initial font. + \param options Font attributes. + \return Font. + */ + QFont fontFromOptions( const QFont& font, int options ) + { + QFont f = font; + f.setBold( options & Bold ); + f.setItalic( options & Italic ); + return f; + } + + /*! + \brief Set font attributes to given widget. + \param w Widget. + \param options Font attributes. + */ + void setFontAttributes( QWidget* w, int options ) + { + if ( w ) + w->setFont( fontFromOptions( w->font(), options ) ); + } + + /*! + \brief Set attributes to given tree item. + \param item Tree widget item. + \param options Item attributes. + */ + void setTreeItemAttributes( QTreeWidgetItem* item, int options ) + { + if ( item && item->treeWidget() ) + { + for ( int i = 0; i < item->treeWidget()->columnCount(); i++ ) + { + if ( i == 0 || options & AllColumns ) + item->setFont( i, fontFromOptions( item->font( 0 ), options) ); + } + } + if ( options & Expanded ) + item->setExpanded( true ); + if ( options & Editable ) + item->setFlags( item->flags() | Qt::ItemIsEditable ); + } + + /*! + \brief Create label. + \param parent Parent widget. + \param options Label options. Defaults to 0 (none). + \return New label. + */ + QLabel* createLabel( QWidget* parent, int options = 0 ) + { + QLabel* lab = new QLabel( parent ); + setFontAttributes( lab, options ); + return lab; + } + + /*! + \brief Create label. + \param text Label text. + \param parent Parent widget. + \param options Label options. Defaults to 0 (none). + \return New label. + */ + QLabel* createLabel( const QString& text, QWidget* parent, int options = 0 ) + { + QLabel* lab = createLabel( parent, options ); + lab->setText( text ); + return lab; + } + + /*! + \brief Create information field. + \param parent Parent widget. + \param name Field's object. Default to null string. + \return New field. + */ + QLabel* createField( QWidget* parent, const QString& name = QString() ) + { + return new Field( parent, name ); + } + + /*! + \brief Create information field. + \param parent Parent widget. + \param options Label options. + \param name Field's object. Default to null string. + \return New field. + */ + QLabel* createField( QWidget* parent, int options, const QString& name = QString() ) + { + QLabel* field = createField( parent, name ); + setFontAttributes( field, options ); + return field; + } + + /*! + \brief Create ruler. + \param parent Parent widget. + \param orientation Ruler orientation. Defaults to horizontal. + \return New ruler. + */ + QWidget* createSeparator( QWidget* parent, Qt::Orientation orientation = Qt::Horizontal ) + { + QFrame* line = new QFrame( parent ); + line->setFrameShape( orientation == Qt::Horizontal ? QFrame::HLine : QFrame::HLine ); + line->setFrameShadow( QFrame::Sunken ); + return line; + } + + /*! + \brief Decorate text as bold. + \param text Initial text. + \return Decorated text. + */ + QString bold( const QString& text ) + { + return QString("%1").arg( text ); + } + + /*! + \brief Format connectivity data to string representation. + \param connectivity Connectivity map. + \param type Element type or face index if negative + \return Stringifed representation of the connectivity. + */ + QString formatConnectivity( SMESH::Connectivity connectivity, int type ) + { + QStringList str; + QString result; + bool isNodal = ( type == SMDSAbs_Node || type < 0 ); + type = qAbs( type ); + if ( connectivity.contains( type )) + { + QList elements = connectivity[ type ]; + if ( !isNodal ) // order of nodes is important + qSort( elements ); + foreach( int id, elements ) + str << QString::number( id ); + + // wrap IDs into an html link, to be treated by QTextBrowser used by SMESHGUI_SimpleElemInfo + QString s = str.join( " " ); + result = ( "" + // path + s + "" ); // anchor text + } + return result; + } +} // end of anonymous namespace + +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_Info +/// \brief Base widget for all information panes. +//////////////////////////////////////////////////////////////////////////////// /*! - \class ExtraWidget - \internal + \brief Constructor. + \param parent Parent widget. Defaults to 0. */ +SMESHGUI_Info::SMESHGUI_Info( QWidget* parent ): QWidget( parent ) +{ +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class ExtraWidget +/// \brief Auxiliary widget to browse between chunks of information. +/// \internal +//////////////////////////////////////////////////////////////////////////////// + class ExtraWidget : public QWidget { public: ExtraWidget( QWidget*, bool = false ); - ~ExtraWidget(); - - void updateControls( int, int, int = MAXITEMS ); + void updateControls( int, int ); public: - QLabel* current; + QLabel* current; QPushButton* prev; QPushButton* next; - bool brief; + bool brief; }; -ExtraWidget::ExtraWidget( QWidget* parent, bool b ) : QWidget( parent ), brief( b ) +/* + \brief Constructor. + \param parent Parent widget. + \param briefSummary Show summary in brief format. Defaults to \c false. +*/ +ExtraWidget::ExtraWidget( QWidget* parent, bool briefSummary ): QWidget( parent ), brief( briefSummary ) { current = new QLabel( this ); current->setAlignment( Qt::AlignRight | Qt::AlignVCenter ); - prev = new QPushButton( tr( "<<" ), this ); - next = new QPushButton( tr( ">>" ), this ); + prev = new QPushButton( "<<", this ); + next = new QPushButton( ">>", this ); QHBoxLayout* hbl = new QHBoxLayout( this ); - hbl->setContentsMargins( 0, SPACING, 0, 0 ); + hbl->setMargin( 0 ); hbl->setSpacing( SPACING ); hbl->addStretch(); hbl->addWidget( current ); @@ -131,884 +462,1049 @@ ExtraWidget::ExtraWidget( QWidget* parent, bool b ) : QWidget( parent ), brief( hbl->addWidget( next ); } -ExtraWidget::~ExtraWidget() -{ -} - -void ExtraWidget::updateControls( int total, int index, int blockSize ) +/* + \brief Update controls. + \param total Total number of items. + \param index Current index. +*/ +void ExtraWidget::updateControls( int total, int index ) { - setVisible( total > blockSize ); + setVisible( total > blockSize() ); QString format = brief ? QString( "%1-%2 / %3" ) : SMESHGUI_MeshInfoDlg::tr( "X_FROM_Y_ITEMS_SHOWN" ); - current->setText( format.arg( index*blockSize+1 ).arg( qMin( index*blockSize+blockSize, total )).arg( total )); + current->setText( format.arg( index*blockSize()+1 ).arg( qMin( index*blockSize()+blockSize(), total ) ).arg( total ) ); prev->setEnabled( index > 0 ); - next->setEnabled( (index+1)*blockSize < total ); + next->setEnabled( (index+1)*blockSize() < total ); } -/*! - \class DumpFileDlg - \brief Customization of standard "Save file" dialog box for dump info operation - \internal -*/ +//////////////////////////////////////////////////////////////////////////////// +/// \class DumpFileDlg +/// \brief Standard Save File dialog box, customized for dump info operation. +/// \internal +//////////////////////////////////////////////////////////////////////////////// class DumpFileDlg : public SUIT_FileDlg { + QMap myControls; public: - DumpFileDlg( QWidget* parent ); - - QCheckBox* myBaseChk; - QCheckBox* myElemChk; - QCheckBox* myAddChk; - QCheckBox* myCtrlChk; + DumpFileDlg( QWidget*, bool = true ); + bool isChecked( int ) const; + void setChecked( int, bool ); }; /*! - \brief Constructor + \brief Constructor. + \param parent Parent widget. + \param showControls Show additional controls. Defaults to \c true. \internal */ -DumpFileDlg::DumpFileDlg( QWidget* parent ) : SUIT_FileDlg( parent, false, true, true ) +DumpFileDlg::DumpFileDlg( QWidget* parent, bool showControls ): SUIT_FileDlg( parent, false, true, true ) { - QGridLayout* grid = ::qobject_cast( layout() ); - if ( grid ) { + if ( showControls ) + { QWidget* hB = new QWidget( this ); - myBaseChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_BASE_INFO" ), hB ); - myElemChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ELEM_INFO" ), hB ); - myAddChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ADD_INFO" ), hB ); - myCtrlChk = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_CTRL_INFO" ), hB ); + myControls[SMESHGUI_MeshInfoDlg::BaseInfo] = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_BASE_INFO" ), hB ); + myControls[SMESHGUI_MeshInfoDlg::ElemInfo] = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ELEM_INFO" ), hB ); + myControls[SMESHGUI_MeshInfoDlg::AddInfo] = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ADD_INFO" ), hB ); + myControls[SMESHGUI_MeshInfoDlg::CtrlInfo] = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_CTRL_INFO" ), hB ); QGridLayout* layout = new QGridLayout( hB ); - layout->addWidget( myBaseChk, 0, 0 ); - layout->addWidget( myElemChk, 0, 1 ); - layout->addWidget( myAddChk, 1, 0 ); - layout->addWidget( myCtrlChk, 1, 1 ); + layout->setMargin( 0 ); + layout->addWidget( myControls[SMESHGUI_MeshInfoDlg::BaseInfo], 0, 0 ); + layout->addWidget( myControls[SMESHGUI_MeshInfoDlg::ElemInfo], 0, 1 ); + layout->addWidget( myControls[SMESHGUI_MeshInfoDlg::AddInfo], 1, 0 ); + layout->addWidget( myControls[SMESHGUI_MeshInfoDlg::CtrlInfo], 1, 1 ); - QPushButton* pb = new QPushButton( this ); - - int row = grid->rowCount(); - grid->addWidget( new QLabel( "", this ), row, 0 ); - grid->addWidget( hB, row, 1, 1, 3 ); - grid->addWidget( pb, row, 5 ); - - pb->hide(); + addWidgets( 0, hB, 0 ); } } /*! - \brief Get depth of the tree item + \brief Get control's value. + \param option Control identifier. + \return Control value. \internal - \param theItem tree widget item - \return item's depth in tree widget (where top-level items have zero depth) */ -static int itemDepth( QTreeWidgetItem* item ) +bool DumpFileDlg::isChecked( int option ) const { - int d = 0; - QTreeWidgetItem* p = item->parent(); - while ( p ) { - d++; - p = p->parent(); - } - return d; + return myControls.contains( option ) ? myControls[option]->isChecked() : false; } /*! - \class SMESHGUI_MeshInfo - \brief Base mesh information widget - - Displays the base information about mesh object: mesh, sub-mesh, group or arbitrary ID source. + \brief Set control's initial value. + \param option Control identifier. + \param value Control value. + \internal */ +void DumpFileDlg::setChecked( int option, bool value ) +{ + if ( myControls.contains( option ) ) + myControls[option]->setChecked( value ); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_BaseInfo +/// \brief Show basic information on selected object. +/// +/// Displays the base information about selected object: mesh, sub-mesh, group +/// or arbitrary ID source. +/// \todo Hide unnecessary widgets (e.g. for mesh group). +//////////////////////////////////////////////////////////////////////////////// /*! \brief Constructor. - \param parent parent widget + \param parent Parent widget. Defaults to 0. */ -SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent ) - : QFrame( parent ), myWidgets( iElementsEnd ) +SMESHGUI_BaseInfo::SMESHGUI_BaseInfo( QWidget* parent ): SMESHGUI_Info( parent ) { - setFrameStyle( StyledPanel | Sunken ); - QGridLayout* l = new QGridLayout( this ); l->setMargin( MARGIN ); l->setSpacing( SPACING ); - int index = 0; - - // object - QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this ); - QLabel* aName = createField(); - aName->setObjectName("meshName"); - aName->setMinimumWidth( 150 ); - QLabel* aObjLab = new QLabel( tr( "OBJECT_LAB" ), this ); - QLabel* aObj = createField(); - aObj->setObjectName("meshType"); - aObj->setMinimumWidth( 150 ); - myWidgets[ index++ ] << aNameLab << aName; - myWidgets[ index++ ] << aObjLab << aObj; - - // nodes - QWidget* aNodesLine = createLine(); - QLabel* aNodesLab = new QLabel( tr( "NODES_LAB" ), this ); - QLabel* aNodes = createField(); - aNodes->setObjectName("nbNodes"); - myWidgets[ index++ ] << aNodesLine; - myWidgets[ index++ ] << aNodesLab << aNodes; - - // elements - QWidget* aElemLine = createLine(); - QLabel* aElemLab = new QLabel( tr( "ELEMENTS_LAB" ), this ); - QLabel* aElemTotal = new QLabel( tr( "TOTAL_LAB" ), this ); - QLabel* aElemLin = new QLabel( tr( "LINEAR_LAB" ), this ); - QLabel* aElemQuad = new QLabel( tr( "QUADRATIC_LAB" ), this ); - QLabel* aElemBiQuad = new QLabel( tr( "BI_QUADRATIC_LAB" ), this ); - myWidgets[ index++ ] << aElemLine; - myWidgets[ index++ ] << aElemLab << aElemTotal << aElemLin << aElemQuad << aElemBiQuad; - - // ... Number elements - QWidget* aNbLine = createLine(); - QLabel* aNbTotal = createField(); - aNbTotal->setObjectName("totalNbElems"); - QLabel* aNbLin = createField(); - aNbLin->setObjectName("totalNbLinearElems"); - QLabel* aNbQuad = createField(); - aNbQuad->setObjectName("totalNbQuadraticElems"); - QLabel* aNbBiQuad = createField(); - aNbBiQuad->setObjectName("totalNbBiQuadraticElems"); - myWidgets[ index++ ] << aNbLine; - myWidgets[ index++ ] << new QLabel( "", this ) << aNbTotal << aNbLin << aNbQuad << aNbBiQuad; - - // ... 0D elements - QWidget* a0DLine = createLine(); - QLabel* a0DLab = new QLabel( tr( "0D_LAB" ), this ); - QLabel* a0DTotal = createField(); - a0DTotal->setObjectName("nb0D"); - - myWidgets[ index++ ] << a0DLine; - myWidgets[ index++ ] << a0DLab << a0DTotal; - - // ... Ball elements - QWidget* aBallLine = createLine(); - QLabel* aBallLab = new QLabel( tr( "BALL_LAB" ), this ); - QLabel* aBallTotal = createField(); - aBallTotal->setObjectName("nbBall"); - myWidgets[ index++ ] << aBallLine; - myWidgets[ index++ ] << aBallLab << aBallTotal; - - // ... 1D elements - QWidget* a1DLine = createLine(); - QLabel* a1DLab = new QLabel( tr( "1D_LAB" ), this ); - QLabel* a1DTotal = createField(); - a1DTotal->setObjectName("nb1D"); - QLabel* a1DLin = createField(); - a1DLin->setObjectName("nbLinear1D"); - QLabel* a1DQuad = createField(); - a1DQuad->setObjectName("nbQuadratic1D"); - myWidgets[ index++ ] << a1DLine; - myWidgets[ index++ ] << a1DLab << a1DTotal << a1DLin << a1DQuad; - - // ... 2D elements - QWidget* a2DLine = createLine(); - QLabel* a2DLab = new QLabel( tr( "2D_LAB" ), this ); - QLabel* a2DTotal = createField(); - a2DTotal->setObjectName("nb2D"); - QLabel* a2DLin = createField(); - a2DLin->setObjectName("nbLinear2D"); - QLabel* a2DQuad = createField(); - a2DQuad->setObjectName("nbQuadratic2D"); - QLabel* a2DBiQuad = createField(); - a2DBiQuad->setObjectName("nbBiQuadratic2D"); - QLabel* a2DTriLab = new QLabel( tr( "TRIANGLES_LAB" ), this ); - QLabel* a2DTriTotal = createField(); - a2DTriTotal->setObjectName("nbTriangle"); - QLabel* a2DTriLin = createField(); - a2DTriLin->setObjectName("nbLinearTriangle"); - QLabel* a2DTriQuad = createField(); - a2DTriQuad->setObjectName("nbQuadraticTriangle"); - QLabel* a2DTriBiQuad = createField(); - a2DTriBiQuad->setObjectName("nbBiQuadraticTriangle"); - QLabel* a2DQuaLab = new QLabel( tr( "QUADRANGLES_LAB" ), this ); - QLabel* a2DQuaTotal = createField(); - a2DQuaTotal->setObjectName("nbQuadrangle"); - QLabel* a2DQuaLin = createField(); - a2DQuaLin->setObjectName("nbLinearQuadrangle"); - QLabel* a2DQuaQuad = createField(); - a2DQuaQuad->setObjectName("nbQuadraticQuadrangle"); - QLabel* a2DQuaBiQuad = createField(); - a2DQuaBiQuad->setObjectName("nbBiQuadraticQuadrangle"); - QLabel* a2DPolLab = new QLabel( tr( "POLYGONS_LAB" ), this ); - QLabel* a2DPolTotal = createField(); - a2DPolTotal->setObjectName("nbPolygon"); - QLabel* a2DPolLin = createField(); - a2DPolLin->setObjectName("nbLinearPolygon"); - QLabel* a2DPolQuad = createField(); - a2DPolQuad->setObjectName("nbQuadraticPolygon"); - myWidgets[ index++ ] << a2DLine; - myWidgets[ index++ ] << a2DLab << a2DTotal << a2DLin << a2DQuad << a2DBiQuad; - myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad << a2DTriBiQuad; - myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad << a2DQuaBiQuad; - myWidgets[ index++ ] << a2DPolLab << a2DPolTotal << a2DPolLin << a2DPolQuad; - - // ... 3D elements - QWidget* a3DLine = createLine(); - QLabel* a3DLab = new QLabel( tr( "3D_LAB" ), this ); - QLabel* a3DTotal = createField(); - a3DTotal->setObjectName("nb3D"); - QLabel* a3DLin = createField(); - a3DLin->setObjectName("nbLinear3D"); - QLabel* a3DQuad = createField(); - a3DQuad->setObjectName("nbQuadratic3D"); - QLabel* a3DBiQuad = createField(); - a3DBiQuad->setObjectName("nbBiQuadratic3D"); - QLabel* a3DTetLab = new QLabel( tr( "TETRAHEDRONS_LAB" ), this ); - QLabel* a3DTetTotal = createField(); - a3DTetTotal->setObjectName("nbTetrahedron"); - QLabel* a3DTetLin = createField(); - a3DTetLin->setObjectName("nbLinearTetrahedron"); - QLabel* a3DTetQuad = createField(); - a3DTetQuad->setObjectName("nbQudraticTetrahedron"); - QLabel* a3DHexLab = new QLabel( tr( "HEXAHEDONRS_LAB" ), this ); - QLabel* a3DHexTotal = createField(); - a3DHexTotal->setObjectName("nbHexahedron"); - QLabel* a3DHexLin = createField(); - a3DHexLin->setObjectName("nbLinearHexahedron"); - QLabel* a3DHexQuad = createField(); - a3DHexQuad->setObjectName("nbQuadraticHexahedron"); - QLabel* a3DHexBiQuad = createField(); - a3DHexBiQuad->setObjectName("nbBiQuadraticHexahedron"); - QLabel* a3DPyrLab = new QLabel( tr( "PYRAMIDS_LAB" ), this ); - QLabel* a3DPyrTotal = createField(); - a3DPyrTotal->setObjectName("nbPyramid"); - QLabel* a3DPyrLin = createField(); - a3DPyrLin->setObjectName("nbLinearPyramid"); - QLabel* a3DPyrQuad = createField(); - a3DPyrQuad->setObjectName("nbQuadraticPyramid"); - QLabel* a3DPriLab = new QLabel( tr( "PRISMS_LAB" ), this ); - QLabel* a3DPriTotal = createField(); - a3DPriTotal->setObjectName("nbPrism"); - QLabel* a3DPriLin = createField(); - a3DPriLin->setObjectName("nbLinearPrism"); - QLabel* a3DPriQuad = createField(); - a3DPriQuad->setObjectName("nbQuadraticPrism"); - QLabel* a3DPriBiQuad = createField(); - a3DPriBiQuad->setObjectName("nbBiQuadraticPrism"); - QLabel* a3DHexPriLab = new QLabel( tr( "HEX_PRISMS_LAB" ), this ); - QLabel* a3DHexPriTotal = createField(); - a3DHexPriTotal->setObjectName("nbHexagonalPrism"); - QLabel* a3DPolLab = new QLabel( tr( "POLYHEDRONS_LAB" ), this ); - QLabel* a3DPolTotal = createField(); - a3DPolTotal->setObjectName("nbPolyhedron"); - myWidgets[ index++ ] << a3DLine; - myWidgets[ index++ ] << a3DLab << a3DTotal << a3DLin << a3DQuad << a3DBiQuad; - myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad; - myWidgets[ index++ ] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad << a3DHexBiQuad; - myWidgets[ index++ ] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad; - myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad << a3DPriBiQuad; - myWidgets[ index++ ] << a3DHexPriLab << a3DHexPriTotal; - myWidgets[ index++ ] << a3DPolLab << a3DPolTotal; - - myLoadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this ); - myLoadBtn->setAutoDefault( true ); - connect( myLoadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() )); - - setFontAttributes( aNameLab, Bold ); - setFontAttributes( aObjLab, Bold ); - setFontAttributes( aNodesLab, Bold ); - setFontAttributes( aElemLab, Bold ); - setFontAttributes( aElemTotal, Italic ); - setFontAttributes( aElemLin, Italic ); - setFontAttributes( aElemQuad, Italic ); - setFontAttributes( aElemBiQuad, Italic ); - setFontAttributes( a0DLab, Bold ); - setFontAttributes( aBallLab, Bold ); - setFontAttributes( a1DLab, Bold ); - setFontAttributes( a2DLab, Bold ); - setFontAttributes( a3DLab, Bold ); - - l->addWidget( aNameLab, 0, 0 ); - l->addWidget( aName, 0, 1, 1, 4 ); - l->addWidget( aObjLab, 1, 0 ); - l->addWidget( aObj, 1, 1, 1, 4 ); - l->addWidget( aNodesLine, 2, 0, 1, 5 ); - l->addWidget( aNodesLab, 3, 0 ); - l->addWidget( aNodes, 3, 1 ); - l->addWidget( aElemLine, 4, 0, 1, 5 ); - l->addWidget( aElemLab, 5, 0 ); - l->addWidget( aElemTotal, 5, 1 ); - l->addWidget( aElemLin, 5, 2 ); - l->addWidget( aElemQuad, 5, 3 ); - l->addWidget( aElemBiQuad, 5, 4 ); - l->addWidget( aNbLine, 6, 1, 1, 4 ); - l->addWidget( aNbTotal, 7, 1 ); - l->addWidget( aNbLin, 7, 2 ); - l->addWidget( aNbQuad, 7, 3 ); - l->addWidget( aNbBiQuad, 7, 4 ); - l->addWidget( a0DLine, 8, 1, 1, 4 ); - l->addWidget( a0DLab, 9, 0 ); - l->addWidget( a0DTotal, 9, 1 ); - l->addWidget( aBallLine, 10, 1, 1, 4 ); - l->addWidget( aBallLab, 11, 0 ); - l->addWidget( aBallTotal, 11, 1 ); - l->addWidget( a1DLine, 12, 1, 1, 4 ); - l->addWidget( a1DLab, 13, 0 ); - l->addWidget( a1DTotal, 13, 1 ); - l->addWidget( a1DLin, 13, 2 ); - l->addWidget( a1DQuad, 13, 3 ); - l->addWidget( a2DLine, 14, 1, 1, 4 ); - l->addWidget( a2DLab, 15, 0 ); - l->addWidget( a2DTotal, 15, 1 ); - l->addWidget( a2DLin, 15, 2 ); - l->addWidget( a2DQuad, 15, 3 ); - l->addWidget( a2DBiQuad, 15, 4 ); - l->addWidget( a2DTriLab, 16, 0 ); - l->addWidget( a2DTriTotal, 16, 1 ); - l->addWidget( a2DTriLin, 16, 2 ); - l->addWidget( a2DTriQuad, 16, 3 ); - l->addWidget( a2DTriBiQuad, 16, 4 ); - l->addWidget( a2DQuaLab, 17, 0 ); - l->addWidget( a2DQuaTotal, 17, 1 ); - l->addWidget( a2DQuaLin, 17, 2 ); - l->addWidget( a2DQuaQuad, 17, 3 ); - l->addWidget( a2DQuaBiQuad, 17, 4 ); - l->addWidget( a2DPolLab, 18, 0 ); - l->addWidget( a2DPolTotal, 18, 1 ); - l->addWidget( a2DPolLin, 18, 2 ); - l->addWidget( a2DPolQuad, 18, 3 ); - l->addWidget( a3DLine, 19, 1, 1, 4 ); - l->addWidget( a3DLab, 20, 0 ); - l->addWidget( a3DTotal, 20, 1 ); - l->addWidget( a3DLin, 20, 2 ); - l->addWidget( a3DQuad, 20, 3 ); - l->addWidget( a3DBiQuad, 20, 4 ); - l->addWidget( a3DTetLab, 21, 0 ); - l->addWidget( a3DTetTotal, 21, 1 ); - l->addWidget( a3DTetLin, 21, 2 ); - l->addWidget( a3DTetQuad, 21, 3 ); - l->addWidget( a3DHexLab, 22, 0 ); - l->addWidget( a3DHexTotal, 22, 1 ); - l->addWidget( a3DHexLin, 22, 2 ); - l->addWidget( a3DHexQuad, 22, 3 ); - l->addWidget( a3DHexBiQuad, 22, 4 ); - l->addWidget( a3DPyrLab, 23, 0 ); - l->addWidget( a3DPyrTotal, 23, 1 ); - l->addWidget( a3DPyrLin, 23, 2 ); - l->addWidget( a3DPyrQuad, 23, 3 ); - l->addWidget( a3DPriLab, 24, 0 ); - l->addWidget( a3DPriTotal, 24, 1 ); - l->addWidget( a3DPriLin, 24, 2 ); - l->addWidget( a3DPriQuad, 24, 3 ); - l->addWidget( a3DPriBiQuad, 24, 4 ); - l->addWidget( a3DHexPriLab, 25, 0 ); - l->addWidget( a3DHexPriTotal, 25, 1 ); - l->addWidget( a3DPolLab, 26, 0 ); - l->addWidget( a3DPolTotal, 26, 1 ); - l->addWidget( myLoadBtn, 28, 1, 1, 4 ); - - l->setColumnStretch( 0, 0 ); - l->setColumnStretch( 1, 5 ); - l->setColumnStretch( 2, 5 ); - l->setColumnStretch( 3, 5 ); - l->setColumnStretch( 4, 5 ); - l->setRowStretch( 27, 5 ); - + // object info + // - name + addWidget( createLabel( tr( "NAME_LAB" ), this, Bold ), iName, iLabel ); + addWidget( createField( this, "meshName" ), iName, iSingle, 4 )->setMinimumWidth( 150 ); + // - type + addWidget( createLabel( tr( "OBJECT_LAB" ), this, Bold ), iObject, iLabel ); + addWidget( createField( this, "meshType" ), iObject, iSingle, 4 )->setMinimumWidth( 150 ); + // - --- (separator) + addWidget( createSeparator( this ), iObjectEnd, iLabel, 5 ); + + // node info + // - info + addWidget( createLabel( tr( "NODES_LAB" ), this, Bold ), iNodes, iLabel ); + addWidget( createField( this, "nbNodes" ), iNodes, iTotal ); + // - --- (separator) + addWidget( createSeparator( this ), iNodesEnd, iLabel, 5 ); + + // element info + // - title + addWidget( createLabel( tr( "ELEMENTS_LAB" ), this, Bold ), iElementsTitle, iLabel ); + addWidget( createLabel( tr( "TOTAL_LAB" ), this, Italic ), iElementsTitle, iTotal ); + addWidget( createLabel( tr( "LINEAR_LAB" ), this, Italic ), iElementsTitle, iLinear ); + addWidget( createLabel( tr( "QUADRATIC_LAB" ), this, Italic ), iElementsTitle, iQuadratic ); + addWidget( createLabel( tr( "BI_QUADRATIC_LAB" ), this, Italic ), iElementsTitle, iBiQuadratic ); + // - --- (separator) + addWidget( createSeparator( this ), iElementsTitleEnd, iTotal, 4 ); + // - summary + addWidget( createField( this, "totalNbElems" ), iElementsTotal, iTotal ); + addWidget( createField( this, "totalNbLinearElems" ), iElementsTotal, iLinear ); + addWidget( createField( this, "totalNbQuadraticElems" ), iElementsTotal, iQuadratic ); + addWidget( createField( this, "totalNbBiQuadraticElems" ), iElementsTotal, iBiQuadratic ); + // - --- (separator) + addWidget( createSeparator( this ), iElementsTotalEnd, iTotal, 4 ); + // - 0D elements info + addWidget( createLabel( tr( "0D_LAB" ), this, Bold | Italic ), i0D, iLabel ); + addWidget( createField( this, "nb0D" ), i0D, iTotal ); + // - --- (separator) + addWidget( createSeparator( this ), i0DEnd, iTotal, 4 ); + // - balls info + addWidget( createLabel( tr( "BALL_LAB" ), this, Bold | Italic ), iBalls, iLabel ); + addWidget( createField( this, "nbBall" ), iBalls, iTotal ); + // - --- (separator) + addWidget( createSeparator( this ), iBallsEnd, iTotal, 4 ); + // - 1D elements info + addWidget( createLabel( tr( "1D_LAB" ), this, Bold | Italic ), i1D, iLabel ); + addWidget( createField( this, "nb1D" ), i1D, iTotal ); + addWidget( createField( this, "nbLinear1D" ), i1D, iLinear ); + addWidget( createField( this, "nbQuadratic1D" ), i1D, iQuadratic ); + // - --- (separator) + addWidget( createSeparator( this ), i1DEnd, iTotal, 4 ); + // - 2D elements info + // --+ summary + addWidget( createLabel( tr( "2D_LAB" ), this, Bold | Italic ), i2D, iLabel ); + addWidget( createField( this, "nb2D" ), i2D, iTotal ); + addWidget( createField( this, "nbLinear2D" ), i2D, iLinear ); + addWidget( createField( this, "nbQuadratic2D" ), i2D, iQuadratic ); + addWidget( createField( this, "nbBiQuadratic2D" ), i2D, iBiQuadratic ); + // --+ triangles + addWidget( createLabel( tr( "TRIANGLES_LAB" ), this, Italic ), i2DTriangles, iLabel ); + addWidget( createField( this, Italic, "nbTriangle" ), i2DTriangles, iTotal ); + addWidget( createField( this, Italic, "nbLinearTriangle" ), i2DTriangles, iLinear ); + addWidget( createField( this, Italic, "nbQuadraticTriangle" ), i2DTriangles, iQuadratic ); + addWidget( createField( this, Italic, "nbBiQuadraticTriangle" ), i2DTriangles, iBiQuadratic ); + // --+ quadrangles + addWidget( createLabel( tr( "QUADRANGLES_LAB" ), this, Italic ), i2DQuadrangles, iLabel ); + addWidget( createField( this, Italic, "nbQuadrangle" ), i2DQuadrangles, iTotal ); + addWidget( createField( this, Italic, "nbLinearQuadrangle" ), i2DQuadrangles, iLinear ); + addWidget( createField( this, Italic, "nbQuadraticQuadrangle" ), i2DQuadrangles, iQuadratic ); + addWidget( createField( this, Italic, "nbBiQuadraticQuadrangle" ), i2DQuadrangles, iBiQuadratic ); + // --+ polygons + addWidget( createLabel( tr( "POLYGONS_LAB" ), this, Italic ), i2DPolygons, iLabel ); + addWidget( createField( this, Italic, "nbPolygon" ), i2DPolygons, iTotal ); + addWidget( createField( this, Italic, "nbLinearPolygon" ), i2DPolygons, iLinear ); + addWidget( createField( this, Italic, "nbQuadraticPolygon" ), i2DPolygons, iQuadratic ); + // - --- (separator) + addWidget( createSeparator( this ), i2DEnd, iTotal, 4 ); + // - 3D elements info + // --+ summary + addWidget( createLabel( tr( "3D_LAB" ), this, Bold | Italic ), i3D, iLabel ); + addWidget( createField( this, "nb3D" ), i3D, iTotal ); + addWidget( createField( this, "nbLinear3D" ), i3D, iLinear ); + addWidget( createField( this, "nbQuadratic3D" ), i3D, iQuadratic ); + addWidget( createField( this, "nbBiQuadratic3D" ), i3D, iBiQuadratic ); + // --+ tetras + addWidget( createLabel( tr( "TETRAHEDRONS_LAB" ), this, Italic ), i3DTetrahedrons, iLabel ); + addWidget( createField( this, Italic, "nbTetrahedron" ), i3DTetrahedrons, iTotal ); + addWidget( createField( this, Italic, "nbLinearTetrahedron" ), i3DTetrahedrons, iLinear ); + addWidget( createField( this, Italic, "nbQudraticTetrahedron" ), i3DTetrahedrons, iQuadratic ); + // --+ hexas + addWidget( createLabel( tr( "HEXAHEDONRS_LAB" ), this, Italic ), i3DHexahedrons, iLabel ); + addWidget( createField( this, Italic, "nbHexahedron" ), i3DHexahedrons, iTotal ); + addWidget( createField( this, Italic, "nbLinearHexahedron" ), i3DHexahedrons, iLinear ); + addWidget( createField( this, Italic, "nbQuadraticHexahedron" ), i3DHexahedrons, iQuadratic ); + addWidget( createField( this, Italic, "nbBiQuadraticHexahedron" ), i3DHexahedrons, iBiQuadratic ); + // --+ pyramids + addWidget( createLabel( tr( "PYRAMIDS_LAB" ), this, Italic ), i3DPyramids, iLabel ); + addWidget( createField( this, Italic, "nbPyramid" ), i3DPyramids, iTotal ); + addWidget( createField( this, Italic, "nbLinearPyramid" ), i3DPyramids, iLinear ); + addWidget( createField( this, Italic, "nbQuadraticPyramid" ), i3DPyramids, iQuadratic ); + // --+ prisms + addWidget( createLabel( tr( "PRISMS_LAB" ), this, Italic ), i3DPrisms, iLabel ); + addWidget( createField( this, Italic, "nbPrism" ), i3DPrisms, iTotal ); + addWidget( createField( this, Italic, "nbLinearPrism" ), i3DPrisms, iLinear ); + addWidget( createField( this, Italic, "nbQuadraticPrism" ), i3DPrisms, iQuadratic ); + addWidget( createField( this, Italic, "nbBiQuadraticPrism" ), i3DPrisms, iBiQuadratic ); + // --+ hexagonal prisms + addWidget( createLabel( tr( "HEX_PRISMS_LAB" ), this, Italic ), i3DHexaPrisms, iLabel ); + addWidget( createField( this, Italic, "nbHexagonalPrism" ), i3DHexaPrisms, iTotal ); + // --+ polyhedrons + addWidget( createLabel( tr( "POLYHEDRONS_LAB" ), this, Italic ), i3DPolyhedrons, iLabel ); + addWidget( createField( this, Italic, "nbPolyhedron" ), i3DPolyhedrons, iTotal ); + + // load button + QPushButton* loadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this ); + loadBtn->setAutoDefault( true ); + connect( loadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() ) ); + addWidget( loadBtn, iEnd, iSingle, 4 ); + + // additional layout set-up + l->setColumnStretch( iLabel, 0 ); + l->setColumnStretch( iTotal, 5 ); + l->setColumnStretch( iLinear, 5 ); + l->setColumnStretch( iQuadratic, 5 ); + l->setColumnStretch( iBiQuadratic, 5 ); + l->setRowStretch( iElementsEnd, 5 ); + + // set initial values clear(); } /*! - \brief Destructor + \brief Destructor. */ -SMESHGUI_MeshInfo::~SMESHGUI_MeshInfo() +SMESHGUI_BaseInfo::~SMESHGUI_BaseInfo() { } /*! - \brief Show information on the mesh object. - \param obj object being processed (mesh, sub-mesh, group, ID source) + \brief Show information on given object. + \param proxy Object to show information on (mesh, sub-mesh, group, ID source). */ -void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) +void SMESHGUI_BaseInfo::showInfo( const SMESH::SelectionProxy& proxy ) { + // reset panel clear(); - if ( !CORBA::is_nil( obj )) { - _PTR(SObject) sobj = SMESH::ObjectToSObject( obj ); - if ( sobj ) - myWidgets[iName][iSingle]->setProperty( "text", sobj->GetName().c_str() ); - SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj ); - SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj ); - SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj ); - if ( !aMesh->_is_nil() ) { - myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_MESH" )); + + // then fill panel with data if object is not null + if ( proxy ) + { + myProxy = proxy; + + SMESH::MeshInfo info = proxy.meshInfo(); + + // object info + // - name + widget( iName, iSingle )->setProperty( "text", proxy.name() ); + // - type + QString typeName; + SMESH::SelectionProxy::Type type = proxy.type(); + if ( type == SMESH::SelectionProxy::Mesh ) + { + typeName = tr( "OBJECT_MESH" ); } - else if ( !aSubMesh->_is_nil() ) { - myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_SUBMESH" )); + else if ( type == SMESH::SelectionProxy::Submesh ) + { + typeName = tr( "OBJECT_SUBMESH" ); } - else if ( !aGroup->_is_nil() ) { - QString objType; - switch( aGroup->GetType() ) { - case SMESH::NODE: objType = tr( "OBJECT_GROUP_NODES" );break; - case SMESH::EDGE: objType = tr( "OBJECT_GROUP_EDGES" );break; - case SMESH::FACE: objType = tr( "OBJECT_GROUP_FACES" );break; - case SMESH::VOLUME:objType = tr( "OBJECT_GROUP_VOLUMES" );break; - case SMESH::ELEM0D:objType = tr( "OBJECT_GROUP_0DELEMS" );break; - case SMESH::BALL: objType = tr( "OBJECT_GROUP_BALLS" );break; - default: objType = tr( "OBJECT_GROUP" );break; + else if ( type >= SMESH::SelectionProxy::Group ) + { + switch( proxy.groupElementType() ) + { + case SMESH::NODE: typeName = tr( "OBJECT_GROUP_NODES" ); break; + case SMESH::EDGE: typeName = tr( "OBJECT_GROUP_EDGES" ); break; + case SMESH::FACE: typeName = tr( "OBJECT_GROUP_FACES" ); break; + case SMESH::VOLUME: typeName = tr( "OBJECT_GROUP_VOLUMES" ); break; + case SMESH::ELEM0D: typeName = tr( "OBJECT_GROUP_0DELEMS" ); break; + case SMESH::BALL: typeName = tr( "OBJECT_GROUP_BALLS" ); break; + default: typeName = tr( "OBJECT_GROUP" ); break; } - myWidgets[iObject][iSingle]->setProperty( "text", objType ); + QString subType; + if ( type == SMESH::SelectionProxy::GroupStd ) + subType = tr( "OBJECT_GROUP_STANDALONE" ); + else if ( type == SMESH::SelectionProxy::GroupGeom ) + subType = tr( "OBJECT_GROUP_GEOM" ); + else if ( type == SMESH::SelectionProxy::GroupFilter ) + subType = tr( "OBJECT_GROUP_FILTER" ); + if ( !subType.isEmpty() ) + typeName = QString( "%1 %2" ).arg( typeName, subType ); } - SMESH::long_array_var info = obj->GetMeshInfo(); - myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Node] )); - myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_0D] )); - myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Ball] )); - long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge]; - myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( nbEdges )); - myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Edge] )); - myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] )); - long nbTriangles = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_BiQuad_Triangle]; - long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle]; - long nb2DPolygons = info[SMDSEntity_Polygon] + info[SMDSEntity_Quad_Polygon]; - long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon]; - long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_Quad_Polygon]; - long nb2DBiQuadratic = info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_BiQuad_Quadrangle]; - long nb2DTotal = nb2DLinear + nb2DQuadratic + nb2DBiQuadratic; - - myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( nb2DTotal )); - myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( nb2DLinear )); - myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( nb2DQuadratic )); - myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( nb2DBiQuadratic )); - myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( nbTriangles )); - myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Triangle] )); - myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Triangle] )); - myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Triangle] )); - myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( nbQuadrangles )); - myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] )); - myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] )); - myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Quadrangle] )); - myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( nb2DPolygons )); - myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] )); - myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Polygon] )); - long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra]; - long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa]; - long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid]; - long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta] + info[SMDSEntity_BiQuad_Penta]; - long nb3DLinear = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism]; - long nb3DQuadratic = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta]; - long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa] + info[SMDSEntity_BiQuad_Penta]; - long nb3DTotal = nb3DLinear + nb3DQuadratic + nb3DBiQuadratic; - myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( nb3DTotal )); - myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( nb3DLinear )); - myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( nb3DQuadratic )); - myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( nb3DBiQuadratic )); - myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( nbTetrahedrons )); - myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Tetra] )); - myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Tetra] )); - myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( nbHexahedrons )); - myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Hexa] )); - myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Hexa] )); - myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_TriQuad_Hexa] )); - myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( nbPyramids )); - myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Pyramid] )); - myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Pyramid] )); - myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( nbPrisms )); - myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Penta] )); - myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] )); - myWidgets[i3DPrisms][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Penta] )); - myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] )); - myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] )); - long nbElemTotal = info[SMDSEntity_0D] + info[SMDSEntity_Ball] + nbEdges + nb2DTotal + nb3DTotal; - long nbElemLinerial = info[SMDSEntity_Edge] + nb2DLinear + nb3DLinear; - long nbElemQuadratic = info[SMDSEntity_Quad_Edge] + nb2DQuadratic + nb3DQuadratic; - long nbElemBiQuadratic = nb2DBiQuadratic + nb3DBiQuadratic; - myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( nbElemTotal )); - myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( nbElemLinerial )); - myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( nbElemQuadratic )); - myWidgets[iNb][iBiQuadratic]->setProperty( "text", QString::number( nbElemBiQuadratic )); - // before full loading from study file, type of elements in a sub-mesh can't be defined - // in some cases - bool infoOK = obj->IsMeshInfoCorrect(); - myLoadBtn->setVisible( !infoOK ); - if ( !infoOK ) + widget( iObject, iSingle )->setProperty( "text", typeName ); + + // node info + uint nbNodes = info[SMDSEntity_Node]; + widget( iNodes, iTotal )->setProperty( "value", nbNodes ); + + // element info + // - 0D elements info + uint nb0d = info[SMDSEntity_0D]; + widget( i0D, iTotal )->setProperty( "value", nb0d ); + // - balls info + uint nbBalls = info[SMDSEntity_Ball]; + widget( iBalls, iTotal )->setProperty( "value", nbBalls ); + // - 1D elements info + uint nb1dLin = info[SMDSEntity_Edge]; + uint nb1dQua = info[SMDSEntity_Quad_Edge]; + uint nb1d = nb1dLin + nb1dQua; + widget( i1D, iLinear )->setProperty( "value", nb1dLin ); + widget( i1D, iQuadratic )->setProperty( "value", nb1dQua ); + widget( i1D, iTotal )->setProperty( "value", nb1d ); + // - 2D elements info + // --+ triangles + uint nbTriLin = info[SMDSEntity_Triangle]; + uint nbTriQua = info[SMDSEntity_Quad_Triangle]; + uint nbTriBiq = info[SMDSEntity_BiQuad_Triangle]; + uint nbTri = nbTriLin + nbTriQua + nbTriBiq; + widget( i2DTriangles, iLinear )->setProperty( "value", nbTriLin ); + widget( i2DTriangles, iQuadratic )->setProperty( "value", nbTriQua ); + widget( i2DTriangles, iBiQuadratic )->setProperty( "value", nbTriBiq ); + widget( i2DTriangles, iTotal )->setProperty( "value", nbTri ); + // --+ quadrangles + uint nbQuadLin = info[SMDSEntity_Quadrangle]; + uint nbQuadQua = info[SMDSEntity_Quad_Quadrangle]; + uint nbQuadBiq = info[SMDSEntity_BiQuad_Quadrangle]; + uint nbQuad = nbQuadLin + nbQuadQua + nbQuadBiq; + widget( i2DQuadrangles, iLinear )->setProperty( "value", nbQuadLin ); + widget( i2DQuadrangles, iQuadratic )->setProperty( "value", nbQuadQua ); + widget( i2DQuadrangles, iBiQuadratic )->setProperty( "value", nbQuadBiq ); + widget( i2DQuadrangles, iTotal )->setProperty( "value", nbQuad ); + // --+ polygons + uint nbPolyLin = info[SMDSEntity_Polygon]; + uint nbPolyQua = info[SMDSEntity_Quad_Polygon]; + uint nbPoly = nbPolyLin + nbPolyQua; + widget( i2DPolygons, iLinear )->setProperty( "value", nbPolyLin ); + widget( i2DPolygons, iQuadratic )->setProperty( "value", nbPolyQua ); + widget( i2DPolygons, iTotal )->setProperty( "value", nbPoly ); + // --+ summary + uint nb2dLin = nbTriLin + nbQuadLin + nbPolyLin; + uint nb2dQua = nbTriQua + nbQuadQua + nbPolyQua; + uint nb2dBiq = nbTriBiq + nbQuadBiq; + uint nb2d = nb2dLin + nb2dQua + nb2dBiq; + widget( i2D, iLinear )->setProperty( "value", nb2dLin ); + widget( i2D, iQuadratic )->setProperty( "value", nb2dQua ); + widget( i2D, iBiQuadratic )->setProperty( "value", nb2dBiq ); + widget( i2D, iTotal )->setProperty( "value", nb2d ); + // - 3D elements info + // --+ tetras + uint nbTetraLin = info[SMDSEntity_Tetra]; + uint nbTetraQua = info[SMDSEntity_Quad_Tetra]; + uint nbTetra = nbTetraLin + nbTetraQua; + widget( i3DTetrahedrons, iLinear )->setProperty( "value", nbTetraLin ); + widget( i3DTetrahedrons, iQuadratic )->setProperty( "value", nbTetraQua ); + widget( i3DTetrahedrons, iTotal )->setProperty( "value", nbTetra ); + // --+ hexas + uint nbHexaLin = info[SMDSEntity_Hexa]; + uint nbHexaQua = info[SMDSEntity_Quad_Hexa]; + uint nbHexaBiq = info[SMDSEntity_TriQuad_Hexa]; + uint nbHexa = nbHexaLin + nbHexaQua + nbHexaBiq; + widget( i3DHexahedrons, iLinear )->setProperty( "value", nbHexaLin ); + widget( i3DHexahedrons, iQuadratic )->setProperty( "value", nbHexaQua ); + widget( i3DHexahedrons, iBiQuadratic )->setProperty( "value", nbHexaBiq ); + widget( i3DHexahedrons, iTotal )->setProperty( "value", nbHexa ); + // --+ pyramids + uint nbPyraLin = info[SMDSEntity_Pyramid]; + uint nbPyraQua = info[SMDSEntity_Quad_Pyramid]; + uint nbPyra = nbPyraLin + nbPyraQua; + widget( i3DPyramids, iLinear )->setProperty( "value", nbPyraLin ); + widget( i3DPyramids, iQuadratic )->setProperty( "value", nbPyraQua ); + widget( i3DPyramids, iTotal )->setProperty( "value", nbPyra ); + // --+ prisms + uint nbPentaLin = info[SMDSEntity_Penta]; + uint nbPentaQua = info[SMDSEntity_Quad_Penta]; + uint nbPentaBiq = info[SMDSEntity_BiQuad_Penta]; + uint nbPenta = nbPentaLin + nbPentaQua + nbPentaBiq; + widget( i3DPrisms, iLinear )->setProperty( "value", nbPentaLin ); + widget( i3DPrisms, iQuadratic )->setProperty( "value", nbPentaQua ); + widget( i3DPrisms, iBiQuadratic )->setProperty( "value", nbPentaBiq ); + widget( i3DPrisms, iTotal )->setProperty( "value", nbPenta ); + // --+ hexagonal prisms + uint nbHexaPri = info[SMDSEntity_Hexagonal_Prism]; + widget( i3DHexaPrisms, iTotal )->setProperty( "value", nbHexaPri ); + // --+ polyhedrons + uint nbPolyhedra = info[SMDSEntity_Polyhedra]; + widget( i3DPolyhedrons, iTotal )->setProperty( "value", nbPolyhedra ); + // --+ summary + uint nb3dLin = nbTetraLin + nbHexaLin + nbPyraLin + nbPentaLin + nbHexaPri + nbPolyhedra; + uint nb3dQua = nbTetraQua + nbHexaQua + nbPyraQua + nbPentaQua; + uint nb3dBiq = nbHexaBiq + nbPentaBiq; + uint nb3d = nb3dLin + nb3dQua + nb3dBiq; + widget( i3D, iLinear )->setProperty( "value", nb3dLin ); + widget( i3D, iQuadratic )->setProperty( "value", nb3dQua ); + widget( i3D, iBiQuadratic )->setProperty( "value", nb3dBiq ); + widget( i3D, iTotal )->setProperty( "value", nb3d ); + // - summary + uint nbElemLin = nb1dLin + nb2dLin + nb3dLin; + uint nbElemQua = nb1dQua + nb2dQua + nb3dQua; + uint nbElemBiq = nb2dBiq + nb3dBiq; + uint nbElem = nb0d + nbBalls + nb1d + nb2d + nb3d; + widget( iElementsTotal, iLinear )->setProperty( "value", nbElemLin ); + widget( iElementsTotal, iQuadratic )->setProperty( "value", nbElemQua ); + widget( iElementsTotal, iBiQuadratic )->setProperty( "value", nbElemBiq ); + widget( iElementsTotal, iTotal )->setProperty( "value", nbElem ); + + // show 'Load' button if data was not loaded yet + widget( iEnd, iSingle )->setVisible( !proxy.isValid() ); + + // until data is loaded from study file, type of elements in a sub-mesh or group + // can be undefined in some cases + if ( !proxy.isValid() ) { - // two options: - // 1. Type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh) - // 2. No info at all (for a group on geom or filter) - bool hasAnyInfo = false; - for ( size_t i = 0; i < info->length() && !hasAnyInfo; ++i ) - hasAnyInfo = info[i]; - if ( hasAnyInfo ) // believe it is a sub-mesh + // two cases are possible: + // 1. type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh) + // 2. there is no info at all (for a group on geom or on filter) + if ( info.count( SMDSEntity_Node, SMDSEntity_Last ) > 0 ) // believe it is a sub-mesh { - if ( nb2DLinear + nb2DQuadratic + nb2DBiQuadratic > 0 ) + if ( nb2dLin + nb2dQua + nb2dBiq > 0 ) { - myWidgets[i2D][iLinear] ->setProperty( "text", "?" ); - myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" ); - myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" ); - myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" ); - myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" ); - myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DPolygons][iLinear] ->setProperty( "text", "?" ); - myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" ); - myWidgets[iNb][iTotal] ->setProperty( "text", "?" ); - myWidgets[iNb][iLinear] ->setProperty( "text", "?" ); - myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" ); + // we know nothing about triangles, quadranges and polygons + for ( int i = i2DTriangles; i < i2DEnd; i++ ) + { + for ( int j = iTotal; j < iNbColumns; j++ ) + { + if ( widget( i, j ) ) + widget( i, j )->setProperty( "text", "?" ); + } + } + // we don't know if elements are linear, quadratic or bi-quadratic + for ( int j = iLinear; j < iNbColumns; j++ ) + { + if ( widget( i2D, j ) ) + widget( i2D, j )->setProperty( "text", "?" ); + if ( widget( iElementsTotal, j ) ) + widget( iElementsTotal, j )->setProperty( "text", "?" ); + } } - else if ( nb3DLinear + nb3DQuadratic + nb3DBiQuadratic > 0 ) + else if ( nb3dLin + nb3dQua + nb3dBiq > 0 ) { - myWidgets[i3D][iLinear] ->setProperty( "text", "?" ); - myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i3D][iBiQuadratic] ->setProperty( "text", "?" ); - myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" ); - myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" ); - myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" ); - myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" ); - myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" ); - myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" ); - myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" ); - myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" ); - myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" ); - myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" ); - myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" ); - myWidgets[iNb][iTotal] ->setProperty( "text", "?" ); - myWidgets[iNb][iLinear] ->setProperty( "text", "?" ); - myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" ); + // we know nothing about tetras, hexas, etc. + for ( int i = i3DTetrahedrons; i < i3DEnd; i++ ) + { + for ( int j = iTotal; j < iNbColumns; j++ ) + { + if ( widget( i, j ) ) + widget( i, j )->setProperty( "text", "?" ); + } + } + // we don't know if elements are linear, quadratic or bi-quadratic + for ( int j = iLinear; j < iNbColumns; j++ ) + { + if ( widget( i3D, j ) ) + widget( i3D, j )->setProperty( "text", "?" ); + if ( widget( iElementsTotal, j ) ) + widget( iElementsTotal, j )->setProperty( "text", "?" ); + } } } else { - myWidgets[iNodes][iTotal] ->setProperty( "text", "?" ); - myWidgets[i0D][iTotal] ->setProperty( "text", "?" ); - myWidgets[iBalls][iTotal] ->setProperty( "text", "?" ); - myWidgets[i1D][iTotal] ->setProperty( "text", "?" ); - myWidgets[i1D][iLinear] ->setProperty( "text", "?" ); - myWidgets[i1D][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2D][iTotal] ->setProperty( "text", "?" ); - myWidgets[i2D][iLinear] ->setProperty( "text", "?" ); - myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2D][iBiQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" ); - myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" ); - myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" ); - myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" ); - myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" ); - myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" ); - myWidgets[i3D][iTotal] ->setProperty( "text", "?" ); - myWidgets[i3D][iLinear] ->setProperty( "text", "?" ); - myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" ); - myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" ); - myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" ); - myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" ); - myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", "?" ); - myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" ); - myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" ); - myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" ); - myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" ); - myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" ); - myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" ); - myWidgets[iNb][iTotal] ->setProperty( "text", "?" ); - myWidgets[iNb][iLinear] ->setProperty( "text", "?" ); - myWidgets[iNb][iQuadratic] ->setProperty( "text", "?" ); - myWidgets[iNb][iBiQuadratic] ->setProperty( "text", "?" ); + // we know nothing about nodes :( + widget( iNodes, iTotal )->setProperty( "text", "?" ); + // we know nothing about elements :( + for ( int i = iElementsTotal; i < iElementsEnd; i++ ) + { + for ( int j = iTotal; j < iNbColumns; j++ ) + { + if ( widget( i, j ) ) + widget( i, j )->setProperty( "text", "?" ); + } + } } } } } /*! - \brief Load mesh from a study file + \brief Update information in panel. */ -void SMESHGUI_MeshInfo::loadMesh() +void SMESHGUI_BaseInfo::updateInfo() { - SUIT_OverrideCursor wc; + showInfo( myProxy ); +} - SALOME_ListIO selected; - SMESHGUI::selectionMgr()->selectedObjects( selected ); +/*! + \brief Load mesh from a study file. +*/ +void SMESHGUI_BaseInfo::loadMesh() +{ + SUIT_OverrideCursor wc; + if ( myProxy ) + { + myProxy.load(); + updateInfo(); + } +} - if ( selected.Extent() == 1 ) { - Handle(SALOME_InteractiveObject) IO = selected.First(); - SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO ); - if ( !CORBA::is_nil( obj )) { - SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); - if ( !mesh->_is_nil() ) - { - mesh->Load(); - showInfo( obj ); - } +/*! + \brief Reset panel (clear all data). +*/ +void SMESHGUI_BaseInfo::clear() +{ + // - name + widget( iName, iSingle )->setProperty( "text", QString() ); + // - type + widget( iObject, iSingle )->setProperty( "text", QString() ); + // - nodes + widget( iNodes, iTotal )->setProperty( "value", 0 ); + // - elements + for ( int i = iElementsTotal; i < iElementsEnd; i++ ) + { + for ( int j = iTotal; j < iNbColumns; j++ ) + { + if ( widget( i, j ) ) + widget( i, j )->setProperty( "value", 0 ); } } + // hide 'Load' button + widget( iEnd, iSingle )->setVisible( false ); } /*! - \brief Reset the widget to the initial state (nullify all fields). + \brief Register widget in a grid. + \param w Widget being added. + \param row Row index in a grid. + \param column Column index in a grid. + \param colspan Number of columns to span in a grid. Defaults to 1. + \return Just added widget. */ -void SMESHGUI_MeshInfo::clear() +QWidget* SMESHGUI_BaseInfo::addWidget( QWidget* w, int row, int column, int colspan ) { - myWidgets[iName][iSingle] ->setProperty( "text", QString() ); - myWidgets[iObject][iSingle] ->setProperty( "text", QString() ); - myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i1D][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2D][iBiQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DTriangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3D][iBiQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DTetrahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DHexahedrons][iBiQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[iNb][iTotal] ->setProperty( "text", QString::number( 0 )); - myWidgets[iNb][iLinear] ->setProperty( "text", QString::number( 0 )); - myWidgets[iNb][iQuadratic] ->setProperty( "text", QString::number( 0 )); - myWidgets[iNb][iBiQuadratic] ->setProperty( "text", QString::number( 0 )); -} - -/*! - \brief Create info field - \return new info field -*/ -QLabel* SMESHGUI_MeshInfo::createField() -{ - QLabel* lab = new QLabel( this ); - lab->setFrameStyle( StyledPanel | Sunken ); - lab->setAlignment( Qt::AlignCenter ); - lab->setAutoFillBackground( true ); - QPalette pal = lab->palette(); - pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base )); - lab->setPalette( pal ); - lab->setMinimumWidth( 70 ); - return lab; -} - -/*! - \brief Create horizontal rule. - \return new line object -*/ -QWidget* SMESHGUI_MeshInfo::createLine() -{ - QFrame* line = new QFrame( this ); - line->setFrameStyle( HLine | Sunken ); - return line; -} - -/*! - \brief Change widget font attributes (bold, italic, ...). - \param w widget - \param attr font attributes (XORed flags) - \param val value to be set to attributes -*/ -void SMESHGUI_MeshInfo::setFontAttributes( QWidget* w, int attr, bool val ) -{ - if ( w && attr ) { - QFont f = w->font(); - if ( attr & Bold ) f.setBold( val ); - if ( attr & Italic ) f.setItalic( val ); - w->setFont( f ); - } -} - -/*! - \brief Show/hide group(s) of fields. - \param start beginning of the block - \param end end of the block - \param on visibility flag -*/ -void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on ) -{ - start = qMax( 0, start ); - end = qMin( end, (int)iElementsEnd ); - for ( int i = start; i < end; i++ ) { - wlist wl = myWidgets[i]; - foreach ( QWidget* w, wl ) w->setVisible( on ); - } -} - -void SMESHGUI_MeshInfo::saveInfo( QTextStream &out ) -{ - out << QString( 9, '-' ) << "\n"; - out << tr( "BASE_INFO" ) << "\n"; - out << QString( 9, '-' ) << "\n"; - out << tr( "NAME_LAB" ) << " " << ( myWidgets[iName][iSingle]->property( "text" )).toString() << "\n"; - out << tr( "OBJECT_LAB" ) << " " << ( myWidgets[iObject][iSingle]->property( "text" )).toString() << "\n"; - out << tr( "NODES_LAB" ) << " " << ( myWidgets[iNodes][iTotal]->property( "text" )).toString() << "\n"; - out << tr( "ELEMENTS_LAB" ) << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iNb][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[iNb][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[iNb][iBiQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "0D_LAB" ) << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i0D][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "BALL_LAB" ) << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[iBalls][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "1D_LAB" ) << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i1D][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i1D][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i1D][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "2D_LAB" ) << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2D][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2D][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2D][iBiQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "TRIANGLES_LAB" ) << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DTriangles][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DTriangles][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DTriangles][iBiQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRANGLES_LAB" ) << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iBiQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYGONS_LAB" ) << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DPolygons][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DPolygons][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DPolygons][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "3D_LAB" ) << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3D][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3D][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3D][iBiQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "TETRAHEDRONS_LAB" ) << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DTetrahedrons][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "HEXAHEDONRS_LAB" ) << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DHexahedrons][iBiQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "PYRAMIDS_LAB" ) << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPyramids][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPyramids][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPyramids][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "PRISMS_LAB" ) << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPrisms][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3DPrisms][iLinear]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i3DPrisms][iQuadratic]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "HEX_PRISMS_LAB" ) << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DHexaPrisms][iTotal]->property( "text" )).toString() << "\n"; - out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYHEDRONS_LAB" ) << "\n"; - out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3DPolyhedrons][iTotal]->property( "text" )).toString() << "\n" << "\n"; -} - -/*! - \class SMESHGUI_ElemInfo - \brief Base class for the mesh element information widget. + if ( !myWidgets.contains( row ) ) + myWidgets[row] = wlist(); + myWidgets[row][column] = w; + dynamic_cast( layout() )->addWidget( w, row, column, 1, colspan ); + return w; +} + +/*! + \brief Get registered widget. + \param row Row index in a grid. + \param column Column index in a grid. + \return Widget stored in a given grid cell (0 if there's no widget). */ +QWidget* SMESHGUI_BaseInfo::widget( int row, int column ) const +{ + return myWidgets.contains( row ) && myWidgets[row].contains( column ) ? myWidgets[row][column] : 0; +} /*! - \brief Constructor - \param parent parent widget + \brief Get text value from registered widget. + \param row Row index in a grid. + \param column Column index in a grid. + \return Value string (empty string if no label in given cell). +*/ +QString SMESHGUI_BaseInfo::value( int row, int column ) const +{ + return widgetValue( widget( row, column ) ); +} + +/*! + \brief Show/hide group(s) of widgets. + \param startRow Starting grid row. + \param lastRow Last grid row. + \param on Visibility flag. +*/ +void SMESHGUI_BaseInfo::setFieldsVisible( int startRow, int lastRow, bool on ) +{ + startRow = qMax( 0, startRow ); + lastRow = qMin( lastRow, (int)iEnd ); + for ( int i = startRow; i <= lastRow; i++ ) + { + wlist widgets = myWidgets[i]; + foreach ( QWidget* w, widgets ) + w->setVisible( on ); + } +} + +/*! + \brief Write information from panel to ouput stream. + \param out Text stream output. +*/ +void SMESHGUI_BaseInfo::saveInfo( QTextStream& out ) +{ + // title + QString title = tr( "BASE_INFO" ); + out << ruler( title.size() ) << endl; + out << title << endl; + out << ruler( title.size() ) << endl; + out << endl; + + // object info + // - name + out << tr( "NAME_LAB" ) << spacing() << value( iName, iSingle ) << endl; + // - type + out << tr( "OBJECT_LAB" ) << spacing() << value( iObject, iSingle ) << endl; + // - --- (separator) + out << endl; + + // node info + out << tr( "NODES_LAB" ) << spacing() << value( iNodes, iTotal ) << endl; + // - --- (separator) + out << endl; + + // element info + QString lin = tr( "LINEAR_LAB" ) + ":" + spacing(); + QString qua = tr( "QUADRATIC_LAB" ) + ":" + spacing(); + QString biq = tr( "BI_QUADRATIC_LAB" ) + ":" + spacing(); + // - summary + out << tr( "ELEMENTS_LAB" ) << spacing() << value( iElementsTotal, iTotal ) << endl; + out << indent(1) << lin << value( iElementsTotal, iLinear ) << endl; + out << indent(1) << qua << value( iElementsTotal, iQuadratic ) << endl; + out << indent(1) << biq << value( iElementsTotal, iBiQuadratic ) << endl; + // - --- (separator) + out << endl; + // - 0D elements info + out << indent(1) << tr( "0D_LAB" ) << spacing() << value( i0D, iTotal ) << endl; + // - --- (separator) + out << endl; + // - balls info + out << indent(1) << tr( "BALL_LAB" ) << spacing() << value( iBalls, iTotal ) << endl; + // - --- (separator) + out << endl; + // - 1D elements info + out << indent(1) << tr( "1D_LAB" ) << spacing() << value( i1D, iTotal ) << endl; + out << indent(2) << lin << value( i1D, iLinear ) << endl; + out << indent(2) << qua << value( i1D, iQuadratic ) << endl; + // - --- (separator) + out << endl; + // - 2D elements info + // - summary + out << indent(1) << tr( "2D_LAB" ) << spacing() << value( i2D, iTotal ) << endl; + out << indent(2) << lin << value( i2D, iLinear ) << endl; + out << indent(2) << qua << value( i2D, iQuadratic ) << endl; + out << indent(2) << biq << value( i2D, iBiQuadratic ) << endl; + // - --- (separator) + out << endl; + // --+ triangles + out << indent(2) << tr( "TRIANGLES_LAB" ) << spacing() << value( i2DTriangles, iTotal ) << endl; + out << indent(3) << lin << value( i2DTriangles, iLinear ) << endl; + out << indent(3) << qua << value( i2DTriangles, iQuadratic ) << endl; + out << indent(3) << biq << value( i2DTriangles, iBiQuadratic ) << endl; + // --+ quadrangles + out << indent(2) << tr( "QUADRANGLES_LAB" ) << spacing() << value( i2DQuadrangles, iTotal ) << endl; + out << indent(3) << lin << value( i2DQuadrangles, iLinear ) << endl; + out << indent(3) << qua << value( i2DQuadrangles, iQuadratic ) << endl; + out << indent(3) << biq << value( i2DQuadrangles, iBiQuadratic ) << endl; + // --+ polygons + out << indent(2) << tr( "POLYGONS_LAB" ) << spacing() << value( i2DPolygons, iTotal ) << endl; + out << indent(3) << lin << value( i2DPolygons, iLinear ) << endl; + out << indent(3) << qua << value( i2DPolygons, iQuadratic ) << endl; + // - --- (separator) + out << endl; + // - 3D elements info + // --+ summary + out << indent(1) << tr( "3D_LAB" ) << spacing() << value( i3D, iTotal ) << endl; + out << indent(2) << lin << value( i3D, iLinear ) << endl; + out << indent(2) << qua << value( i3D, iQuadratic ) << endl; + out << indent(2) << biq << value( i3D, iBiQuadratic ) << endl; + // - --- (separator) + out << endl; + // --+ tetras + out << indent(2) << tr( "TETRAHEDRONS_LAB" ) << spacing() << value( i3DTetrahedrons, iTotal ) << endl; + out << indent(3) << lin << value( i3DTetrahedrons, iLinear ) << endl; + out << indent(3) << qua << value( i3DTetrahedrons, iQuadratic ) << endl; + // --+ hexas + out << indent(2) << tr( "HEXAHEDONRS_LAB" ) << spacing() << value( i3DHexahedrons, iTotal ) << endl; + out << indent(3) << lin << value( i3DHexahedrons, iLinear ) << endl; + out << indent(3) << qua << value( i3DHexahedrons, iQuadratic ) << endl; + out << indent(3) << biq << value( i3DHexahedrons, iBiQuadratic ) << endl; + // --+ pyramids + out << indent(2) << tr( "PYRAMIDS_LAB" ) << spacing() << value( i3DPyramids, iTotal ) << endl; + out << indent(3) << lin << value( i3DPyramids, iLinear ) << endl; + out << indent(3) << qua << value( i3DPyramids, iQuadratic ) << endl; + // --+ prisms + out << indent(2) << tr( "PRISMS_LAB" ) << spacing() << value( i3DPrisms, iTotal ) << endl; + out << indent(3) << lin << value( i3DPrisms, iLinear ) << endl; + out << indent(3) << qua << value( i3DPrisms, iQuadratic ) << endl; + out << indent(3) << biq << value( i3DPrisms, iBiQuadratic ) << endl; + // --+ hexagonal prisms + out << indent(2) << tr( "HEX_PRISMS_LAB" ) << spacing() << value( i3DHexaPrisms, iTotal ) << endl; + // --+ polyhedrons + out << indent(2) << tr( "POLYHEDRONS_LAB" ) << spacing() << value( i3DPolyhedrons, iTotal ) << endl; + // - --- (separator) + out << endl; +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class InfoWriter +/// \brief Base info writer class. +/// \internal +//////////////////////////////////////////////////////////////////////////////// + +class InfoWriter +{ +protected: + int myPrecision; + bool myRecursive; +public: + InfoWriter( bool = false ); + void write( const QString&, bool = false ); + void write( const QString&, const QString&, bool = false ); + void write( const QString&, int, bool = false ); + void write( const QString&, double, bool = false ); + void write( const QString&, const SMESH::XYZ&, bool = false ); + virtual void indent() {} + virtual void unindent() {} + virtual void separator() {} +protected: + virtual void put( const QString&, const QString&, bool = false ) = 0; +}; + +InfoWriter::InfoWriter( bool r ): myRecursive(r) +{ + myPrecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); +} + +void InfoWriter::write( const QString& key, bool emphasize ) +{ + put( key, QString(), emphasize ); +} + +void InfoWriter::write( const QString& key, const QString& value, bool emphasize ) +{ + put( key, value, emphasize ); +} + +void InfoWriter::write( const QString& key, int value, bool emphasize ) +{ + put( key, QString::number( value ), emphasize ); +} + +void InfoWriter::write( const QString& key, double value, bool emphasize ) +{ + put( key, QString::number( value, myPrecision > 0 ? 'f' : 'g', qAbs( myPrecision ) ), emphasize ); +} + +void InfoWriter::write( const QString& key, const SMESH::XYZ& value, bool emphasize ) +{ + if ( myRecursive ) + { + write( key, emphasize ); + indent(); + write( "X", value.x() ); + write( "Y", value.y() ); + write( "Z", value.z() ); + unindent(); + } + else + { + QStringList vl; + vl << QString::number( value.x(), myPrecision > 0 ? 'f' : 'g', qAbs( myPrecision ) ); + vl << QString::number( value.y(), myPrecision > 0 ? 'f' : 'g', qAbs( myPrecision ) ); + vl << QString::number( value.z(), myPrecision > 0 ? 'f' : 'g', qAbs( myPrecision ) ); + put( key, vl.join( ", " ), emphasize ); + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class SimpleWriter +/// \brief Base text writer. +/// \internal +//////////////////////////////////////////////////////////////////////////////// + +class SimpleWriter: public InfoWriter +{ +protected: + int myIndent; +public: + SimpleWriter(); + void indent(); + void unindent(); + void separator(); +protected: + void put( const QString&, const QString&, bool ); + virtual QString spacer() const; + virtual QString decorate( const QString& ) const; + virtual void dumpLine( const QString& ) = 0; +}; + +SimpleWriter::SimpleWriter(): InfoWriter(false), myIndent(0) +{ +} + +void SimpleWriter::indent() +{ + myIndent += 1; +} + +void SimpleWriter::unindent() +{ + myIndent = qMax( myIndent-1, 0 ); +} + +void SimpleWriter::separator() +{ + write( "" ); +} + +QString SimpleWriter::spacer() const +{ + return " "; +} + +QString SimpleWriter::decorate( const QString& s ) const +{ + return s; +} + +void SimpleWriter::put( const QString& key, const QString& value, bool emphasize ) +{ + QString line; + line += ::indent( spacer(), myIndent*4 ); + line += decorate( key ); + if ( !value.isEmpty() ) + { + line += ":"; + line += emphasize ? decorate( value ) : value; + } + dumpLine( line ); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class StreamWriter +/// \brief Writer for QTextStream. +/// \internal +//////////////////////////////////////////////////////////////////////////////// + +class StreamWriter: public SimpleWriter +{ + QTextStream& myOut; +public: + StreamWriter( QTextStream& ); +protected: + void dumpLine( const QString& ); +}; + +StreamWriter::StreamWriter( QTextStream& out ): SimpleWriter(), myOut(out) +{ +} + +void StreamWriter::dumpLine( const QString& line ) +{ + myOut << line; + myOut << endl; +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class TextWriter +/// \brief Writer for QTextBrowser. +/// \internal +//////////////////////////////////////////////////////////////////////////////// + +class TextWriter: public SimpleWriter +{ + QTextBrowser* myInfo; +public: + TextWriter( QTextBrowser* ); +protected: + QString spacer() const; + QString decorate( const QString& ) const; + void dumpLine( const QString& ); +}; + +TextWriter::TextWriter( QTextBrowser* w ): SimpleWriter(), myInfo(w) +{ +} + +QString TextWriter::spacer() const +{ + return " "; +} + +QString TextWriter::decorate( const QString& s ) const +{ + return bold( s ); +} + +void TextWriter::dumpLine( const QString& line ) +{ + myInfo->append( line ); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class TreeWriter +/// \brief Writer for QTreeWidget. +/// \internal +//////////////////////////////////////////////////////////////////////////////// + +class TreeWriter: public InfoWriter +{ + QTreeWidget* myInfo; + QTreeWidgetItem* myCurrentItem; + TreeItemCreator* myCreator; +public: + TreeWriter( QTreeWidget*, TreeItemCreator* ); + ~TreeWriter(); + void indent(); + void unindent(); +protected: + void put( const QString&, const QString&, bool = false ); +}; + +TreeWriter::TreeWriter( QTreeWidget* w, TreeItemCreator* c ): + InfoWriter(true), myInfo(w), myCurrentItem(0), myCreator(c) +{ +} + +TreeWriter::~TreeWriter() +{ + delete myCreator; +} + +void TreeWriter::put( const QString& key, const QString& value, bool emphasize ) +{ + //std::string sss = myCurrentItem ? myCurrentItem->text(0).toStdString() : ""; + int options = Bold; + if ( emphasize ) options |= AllColumns; + QTreeWidgetItem* item = myCreator->createItem( myCurrentItem, options ); + item->setText( 0, key ); + if ( !value.isEmpty() ) + { + QString val = value; + if ( value.startsWith( "1 2 + { + int role = ( value[11] == 'n' ) ? NodeConnectivity : ElemConnectivity; + val = value.mid( value.lastIndexOf( '>', -5 ) + 1 ); // ==> 1 2 + val.chop( 4 ); + item->setData( 1, TypeRole, role ); + } + item->setText( 1, val ); + } +} + +void TreeWriter::indent() +{ + QTreeWidgetItem* item = myCurrentItem ? myCurrentItem : myInfo->invisibleRootItem(); + if ( item->childCount() > 0 ) + myCurrentItem = item->child( item->childCount()-1 ); +} + +void TreeWriter::unindent() +{ + if ( myCurrentItem ) + myCurrentItem = myCurrentItem->parent(); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_ElemInfo +/// \brief Base class for the mesh element information widget. +/// +/// Displays the detail information about given mesh node(s) or element(s). +/// Default class does not provide working implementation but onle general +/// functionalities; main work is done in sub-classes. +//////////////////////////////////////////////////////////////////////////////// + +/*! + \brief Constructor. + \param parent Parent widget. Defaults to 0. */ -SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent ) - : QWidget( parent ), myActor( 0 ), myIsElement( -1 ) +SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent ): SMESHGUI_Info( parent ), myWhat( ShowNone ) { myFrame = new QWidget( this ); myExtra = new ExtraWidget( this ); + QVBoxLayout* vbl = new QVBoxLayout( this ); vbl->setMargin( 0 ); - vbl->setSpacing( 0 ); + vbl->setSpacing( SPACING ); vbl->addWidget( myFrame ); vbl->addWidget( myExtra ); - connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() )); - connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() )); + + connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() ) ); + connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() ) ); + clear(); } /*! - \brief Destructor + \brief Destructor. */ SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo() { } /*! - \brief Set mesh data source (actor) - \param actor mesh object actor -*/ -void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor, SMESH::SMESH_IDSource_var obj ) -{ - if ( myActor != actor ) { - myActor = actor; - myIsElement = -1; - SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); - myMeshHasShape = ( !mesh->_is_nil() && mesh->HasShapeToMesh() ); - clear(); - } -} - -/*! - \brief Show mesh element information - \param id mesh node / element ID - \param isElem show mesh element information if \c true or mesh node information if \c false + \brief Show information on given node / element. + \param proxy Object to compute information on (mesh, sub-mesh, group, ID source). + \param id Mesh node / element ID. + \param isElement If \c true, show element info; otherwise show node info. */ -void SMESHGUI_ElemInfo::showInfo( long id, bool isElem ) +void SMESHGUI_ElemInfo::showInfo( const SMESH::SelectionProxy& proxy, uint id, bool isElement ) { - QSet ids; + QSet ids; ids << id; - showInfo( ids, isElem ); + showInfo( proxy, ids, isElement ); } /*! - \brief Show mesh element information - \param ids mesh nodes / elements identifiers - \param isElem show mesh element information if \c true or mesh node information if \c false + \brief Show information on given nodes / elements. + \param proxy Object to compute information on (mesh, sub-mesh, group, ID source). + \param ids Mesh nodes / elements IDs. + \param isElement If \c true, show element info; otherwise show node info. */ -void SMESHGUI_ElemInfo::showInfo( QSet ids, bool isElem ) +void SMESHGUI_ElemInfo::showInfo( const SMESH::SelectionProxy& proxy, QSet ids, bool isElement ) { - QList newIds = ids.toList(); + if ( !proxy ) + { + clear(); + return; + } + + QList newIds = ids.toList(); qSort( newIds ); - if ( myIDs == newIds && myIsElement == isElem ) return; + int what = isElement ? ShowElements : ShowNodes; + + if ( myProxy == proxy && myIDs == newIds && myWhat == what ) + return; + + myProxy = proxy; + myProxy.refresh(); // try to re-initialize actor + + clear(); myIDs = newIds; - myIsElement = isElem; + myWhat = what; myIndex = 0; + updateControls(); - information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS )); + information( myIDs.mid( myIndex*blockSize(), blockSize() ) ); } /*! - \brief Clear mesh element information widget + \brief Show information on given group. + \param proxy Object to compute information on (group). +*/ +void SMESHGUI_ElemInfo::showInfo( const SMESH::SelectionProxy& proxy ) +{ + if ( !proxy || proxy.groupElementType() == SMESH::ALL ) // null proxy or not a group + { + clear(); + return; + } + + showInfo( proxy, proxy.ids(), proxy.groupElementType() != SMESH::NODE ); +} + +/*! + \brief Reset panel (clear all data). */ void SMESHGUI_ElemInfo::clear() { @@ -1019,136 +1515,483 @@ void SMESHGUI_ElemInfo::clear() } /*! - \brief Get central area widget - \return central widget + \brief Get central area widget. + \return Central widget. */ -QWidget* SMESHGUI_ElemInfo::frame() const +QWidget* SMESHGUI_ElemInfo::centralWidget() const { return myFrame; } /*! - \brief Get actor - \return actor being used + \brief Get current mesh proxy object information is shown on. + \return Current proxy. */ -SMESH_Actor* SMESHGUI_ElemInfo::actor() const +SMESH::SelectionProxy SMESHGUI_ElemInfo::proxy() const { - return myActor; + return myProxy; } /*! \brief Get current info mode. - \return \c true if mesh element information is shown or \c false if node information is shown + \return Current panel mode. */ -bool SMESHGUI_ElemInfo::isElements() const +int SMESHGUI_ElemInfo::what() const { - return myIsElement; + return myWhat; } /*! - \fn void SMESHGUI_ElemInfo::information( const QList& ids ) - \brief Show information on the specified nodes / elements - - This function is to be redefined in sub-classes. - - \param ids nodes / elements identifiers information is to be shown on + \brief Get title for given element type. + \param type Mesh element type. + \param multiple Use plural form. Defaults to \c false. + \return Element type's title. */ +QString SMESHGUI_ElemInfo::type2str( int type, bool multiple ) +{ + QString title; + switch ( type ) + { + case SMDSAbs_Edge: + title = multiple ? tr( "EDGES" ) : tr( "EDGE" ) ; break; + case SMDSAbs_Face: + title = multiple ? tr( "FACES" ) : tr( "FACE" ); break; + case SMDSAbs_Volume: + title = multiple ? tr( "VOLUMES" ) : tr( "VOLUME" ); break; + case SMDSAbs_0DElement: + title = multiple ? tr( "0D_ELEMENTS" ) : tr( "0D_ELEMENT" ); break; + case SMDSAbs_Ball: + title = multiple ? tr( "BALL_ELEMENTS" ) : tr( "BALL" ); break; + default: + break; + } + return title; +} /*! - \brief Internal clean-up (reset widget) + \brief Get title for given shape type. + \param type Shape type. + \return Shape type's title. */ -void SMESHGUI_ElemInfo::clearInternal() +QString SMESHGUI_ElemInfo::stype2str( int type ) { + QString title; + switch ( type ) + { + case GEOM::VERTEX: + title = tr( "GEOM_VERTEX" ); break; + case GEOM::EDGE: + title = tr( "GEOM_EDGE" ); break; + case GEOM::FACE: + title = tr( "GEOM_FACE" ); break; + case GEOM::SOLID: + default: + title = tr( "GEOM_SOLID" ); break; + break; + } + return title; } /*! - \brief Get node connectivity - \param node mesh node - \return node connectivity map + \brief Get title for given element type. + \param type Mesh element type. + \return Element type's title. */ -SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node ) +QString SMESHGUI_ElemInfo::etype2str( int type ) { - Connectivity elmap; - if ( node ) { - SMDS_ElemIteratorPtr it = node->GetInverseElementIterator(); - while ( it && it->more() ) { - const SMDS_MeshElement* ne = it->next(); - elmap[ ne->GetType() ] << ne->GetID(); - } + QString title; + switch ( type ) + { + case SMESH::Entity_0D: + title = tr( "SMESH_ELEM0D" ); break; + case SMESH::Entity_Edge: + title = tr( "SMESH_EDGE" ); break; + case SMESH::Entity_Quad_Edge: + title = tr( "SMESH_QUADRATIC_EDGE" ); break; + case SMESH::Entity_Triangle: + title = tr( "SMESH_TRIANGLE" ); break; + case SMESH::Entity_Quad_Triangle: + title = tr( "SMESH_QUADRATIC_TRIANGLE" ); break; + case SMESH::Entity_BiQuad_Triangle: + title = tr( "SMESH_BIQUADRATIC_TRIANGLE" ); break; + case SMESH::Entity_Quadrangle: + title = tr( "SMESH_QUADRANGLE" ); break; + case SMESH::Entity_Quad_Quadrangle: + title = tr( "SMESH_QUADRATIC_QUADRANGLE" ); break; + case SMESH::Entity_BiQuad_Quadrangle: + title = tr( "SMESH_BIQUADRATIC_QUADRANGLE" ); break; + case SMESH::Entity_Polygon: + title = tr( "SMESH_POLYGON" ); break; + case SMESH::Entity_Quad_Polygon: + title = tr( "SMESH_QUADRATIC_POLYGON" ); break; + case SMESH::Entity_Tetra: + title = tr( "SMESH_TETRAHEDRON" ); break; + case SMESH::Entity_Quad_Tetra: + title = tr( "SMESH_QUADRATIC_TETRAHEDRON" ); break; + case SMESH::Entity_Pyramid: + title = tr( "SMESH_PYRAMID" ); break; + case SMESH::Entity_Quad_Pyramid: + title = tr( "SMESH_QUADRATIC_PYRAMID" ); break; + case SMESH::Entity_Hexa: + title = tr( "SMESH_HEXAHEDRON" ); break; + case SMESH::Entity_Quad_Hexa: + title = tr( "SMESH_QUADRATIC_HEXAHEDRON" ); break; + case SMESH::Entity_TriQuad_Hexa: + title = tr( "SMESH_TRIQUADRATIC_HEXAHEDRON" ); break; + case SMESH::Entity_Penta: + title = tr( "SMESH_PENTA" ); break; + case SMESH::Entity_Quad_Penta: + title = tr( "SMESH_QUADRATIC_PENTAHEDRON" ); break; + case SMESH::Entity_BiQuad_Penta: + title = tr( "SMESH_BIQUADRATIC_PENTAHEDRON" ); break; + case SMESH::Entity_Hexagonal_Prism: + title = tr( "SMESH_HEX_PRISM" ); break; + case SMESH::Entity_Polyhedra: + title = tr( "SMESH_POLYEDRON" ); break; + case SMESH::Entity_Quad_Polyhedra: + title = tr( "SMESH_QUADRATIC_POLYEDRON" ); break; + case SMESH::Entity_Ball: + title = tr( "SMESH_BALL" ); break; + default: + break; } - return elmap; + return title; } /*! - \brief Format connectivity data to string representation - \param connectivity connetivity map - \param type element type - \return string representation of the connectivity + \brief Get title for given quality control. + \param type Mesh control type. + \return Quality control's title. */ -QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type ) +QString SMESHGUI_ElemInfo::ctrl2str( int control ) { - QStringList str; - if ( connectivity.contains( type )) { - QList elements = connectivity[ type ]; - qSort( elements ); - foreach( int id, elements ) - str << QString::number( id ); + QString title; + switch ( control ) + { + case SMESH::FT_AspectRatio: + title = tr( "ASPECTRATIO_ELEMENTS" ); break; + case SMESH::FT_AspectRatio3D: + title = tr( "ASPECTRATIO_3D_ELEMENTS" ); break; + case SMESH::FT_Warping: + title = tr( "WARP_ELEMENTS" ); break; + case SMESH::FT_MinimumAngle: + title = tr( "MINIMUMANGLE_ELEMENTS" ); break; + case SMESH::FT_Taper: + title = tr( "TAPER_ELEMENTS" ); break; + case SMESH::FT_Skew: + title = tr( "SKEW_ELEMENTS" ); break; + case SMESH::FT_Area: + title = tr( "AREA_ELEMENTS" ); break; + case SMESH::FT_Volume3D: + title = tr( "VOLUME_3D_ELEMENTS" ); break; + case SMESH::FT_MaxElementLength2D: + title = tr( "MAX_ELEMENT_LENGTH_2D" ); break; + case SMESH::FT_MaxElementLength3D: + title = tr( "MAX_ELEMENT_LENGTH_3D" ); break; + case SMESH::FT_Length: + title = tr( "LENGTH_EDGES" ); break; + case SMESH::FT_Length2D: + case SMESH::FT_Length3D: + title = tr( "MIN_ELEM_EDGE" ); break; + case SMESH::FT_BallDiameter: + title = tr( "BALL_DIAMETER" ); break; + default: + break; } - return str.join( " " ); + return title; } /*! - \brief Calculate gravity center of the mesh element - \param element mesh element + \brief Write information on given mesh nodes / elements. + \param writer Information writer. + \param ids Nodes / elements IDs. */ -SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element ) +void SMESHGUI_ElemInfo::writeInfo( InfoWriter* writer, const QList& ids ) { - XYZ xyz; - if ( element ) { - SMDS_ElemIteratorPtr nodeIt = element->nodesIterator(); - while ( nodeIt->more() ) { - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - xyz.add( node->X(), node->Y(), node->Z() ); + if ( !proxy() ) + return; + + bool grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false ); + int cprecision = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) ? + SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 ) : -1; + + SMESH::XYZ xyz; + SMESH::Connectivity connectivity; + SMESH::Position position; + bool ok; + + foreach ( uint id, ids ) + { + writer->separator(); + + if ( what() == ShowNodes ) + { + // show node info + // - check that node exists + if ( !proxy().hasNode( id ) ) + continue; + // - id + writer->write( tr( "NODE" ), (int)id, true ); + writer->indent(); + // - coordinates + ok = proxy().nodeCoordinates( id, xyz ); + if ( ok ) + { + writer->write( tr( "COORDINATES" ), xyz ); + } + // - connectivity + ok = proxy().nodeConnectivity( id, connectivity ); + if ( ok ) + { + if ( !connectivity.isEmpty() ) + { + writer->write( tr( "CONNECTIVITY" ) ); + writer->indent(); + for ( int i = SMDSAbs_Edge; i <= SMDSAbs_Ball; i++ ) + { + QString formatted = formatConnectivity( connectivity, i ); + if ( !formatted.isEmpty() ) + writer->write( type2str( i, true ), formatted ); + } + writer->unindent(); + } + else + { + writer->write( tr( "CONNECTIVITY" ), tr( "FREE_NODE" ) ); + } + } + // - position + ok = proxy().nodePosition( id, position ); + if ( ok && position.isValid() ) + { + writer->write( tr( "POSITION" ), (stype2str( position.shapeType() ) + " #%1").arg( position.shapeId() ) ); + writer->indent(); + if ( position.hasU() ) + writer->write( tr("U_POSITION"), position.u() ); + if ( position.hasV() ) + writer->write( tr("V_POSITION"), position.v() ); + writer->unindent(); + } + // - groups node belongs to + QList groups = proxy().nodeGroups( id ); + bool topCreated = false; + foreach( SMESH::SelectionProxy group, groups ) + { + if ( group && !group.name().isEmpty() ) + { + if ( !topCreated ) + { + writer->write( SMESHGUI_AddInfo::tr( "GROUPS" ) ); + writer->indent(); + topCreated = true; + } + writer->write( group.name().trimmed() ); // trim name + if ( grp_details ) + { + writer->indent(); + int type = group.type(); + if ( type == SMESH::SelectionProxy::GroupStd ) + { + writer->write( SMESHGUI_AddInfo::tr( "TYPE" ), SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ); + } + else if ( type == SMESH::SelectionProxy::GroupGeom ) + { + writer->write( SMESHGUI_AddInfo::tr( "TYPE" ), SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ); + writer->write( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ), group.shapeName() ); + } + else if ( type == SMESH::SelectionProxy::GroupFilter ) + { + writer->write( SMESHGUI_AddInfo::tr( "TYPE" ), SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ); + } + int size = group.size(); + if ( size != -1 ); + writer->write( SMESHGUI_AddInfo::tr( "SIZE" ), size ); + QColor color = group.color(); + if ( color.isValid() ) + writer->write( SMESHGUI_AddInfo::tr( "COLOR" ), color.name() ); + writer->unindent(); + } + } + } + if ( topCreated ) + writer->unindent(); + writer->unindent(); } - xyz.divide( element->NbNodes() ); - } - return xyz; + else if ( what() == ShowElements ) + { + // show element info + // - check that element exists + if ( !proxy().hasElement( id ) ) + continue; + // - id & type + int type = proxy().elementType( id ); + if ( type == SMESH::ALL ) + continue; + writer->write( type2str( type ), (int)id, true ); + writer->indent(); + // - geometry type + type = proxy().elementEntityType( id ); + writer->write( tr( "TYPE" ), etype2str( type ) ); + // - connectivity + if ( type == SMESH::Entity_Polyhedra || + type == SMESH::Entity_Quad_Polyhedra ) + { + int nbNodes; + ok = proxy().perFaceConnectivity( id, connectivity, nbNodes ); + if ( ok && !connectivity.isEmpty() ) + { + writer->write( tr( "NB_NODES" ), nbNodes ); + writer->write( tr( "CONNECTIVITY" ) ); + writer->indent(); + int nbFaces = connectivity.size(); + for ( int iF = 1; iF <= nbFaces; ++iF ) + { + QString formatted = formatConnectivity( connectivity, -iF ); + writer->write(( type2str( SMDSAbs_Face, 0 ) + " %1 / %2" ).arg( iF ).arg( nbFaces ), + formatted ); + } + writer->unindent(); + } + } + else + { + ok = proxy().elementConnectivity( id, connectivity ); + if ( ok && !connectivity.isEmpty() ) + { + QString formatted = formatConnectivity( connectivity, SMDSAbs_Node ); + if ( !formatted.isEmpty() ) + { + writer->write( tr( "NB_NODES" ), connectivity[ SMDSAbs_Node ].size() ); + writer->write( tr( "CONNECTIVITY" ), formatted ); //todo: TypeRole: ElemConnectivity + } + } + } + // - position + ok = proxy().elementPosition( id, position ); + if ( ok && position.isValid() ) + { + writer->write( tr( "POSITION" ), (stype2str( position.shapeType() ) + " #%1").arg( position.shapeId() ) ); + } + // - gravity center + ok = proxy().elementGravityCenter( id, xyz ); + if ( ok ) + { + writer->write( tr( "GRAVITY_CENTER" ), xyz ); + } + // - normal vector + ok = proxy().elementNormal( id, xyz ); + if ( ok ) + { + writer->write( tr( "NORMAL_VECTOR" ), xyz ); + } + // - controls + bool topCreated = false; + for ( int i = SMESH::FT_AspectRatio; i < SMESH::FT_Undefined; i++ ) + { + QString ctrlTitle = ctrl2str( i ); + if ( ctrlTitle.isEmpty() ) + continue; + if ( !topCreated ) + { + writer->write( tr( "CONTROLS" ) ); + writer->indent(); + topCreated = true; + } + double value; + if ( proxy().elementControl( id, i, cprecision, value ) ) + writer->write( ctrlTitle, value ); + } + if ( topCreated ) + writer->unindent(); + // - groups element belongs to + QList groups = proxy().elementGroups( id ); + topCreated = false; + foreach( SMESH::SelectionProxy group, groups ) + { + if ( group && !group.name().isEmpty() ) + { + if ( !topCreated ) + { + writer->write( SMESHGUI_AddInfo::tr( "GROUPS" ) ); + writer->indent(); + topCreated = true; + } + writer->write( group.name().trimmed() ); // trim name + if ( grp_details ) + { + writer->indent(); + int type = group.type(); + if ( type == SMESH::SelectionProxy::GroupStd ) + { + writer->write( SMESHGUI_AddInfo::tr( "TYPE" ), SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) ); + } + else if ( type == SMESH::SelectionProxy::GroupGeom ) + { + writer->write( SMESHGUI_AddInfo::tr( "TYPE" ), SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) ); + writer->write( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ), group.shapeName() ); + } + else if ( type == SMESH::SelectionProxy::GroupFilter ) + { + writer->write( SMESHGUI_AddInfo::tr( "TYPE" ), SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) ); + } + int size = group.size(); + if ( size != -1 ); + writer->write( SMESHGUI_AddInfo::tr( "SIZE" ), size ); + QColor color = group.color(); + if ( color.isValid() ) + writer->write( SMESHGUI_AddInfo::tr( "COLOR" ), color.name() ); + writer->unindent(); + } + } + } + if ( topCreated ) + writer->unindent(); + writer->unindent(); + } + } } /*! - \brief Calculate normal vector to the mesh face - \param element mesh face + \fn void SMESHGUI_ElemInfo::information( const QList& ids ) + \brief Show information on given mesh nodes / elements. + + This function has to be redefined in sub-classes. + + \param ids Nodes / elements IDs. */ -SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::normal( const SMDS_MeshElement* element ) + +/*! + \brief Internal clean-up (reset panel). + + Default implementation does nothing; the method has to be redefined + in sub-classes to perform internal clean-up. +*/ +void SMESHGUI_ElemInfo::clearInternal() { - gp_XYZ n = SMESH::getNormale( dynamic_cast( element )); - return XYZ(n.X(), n.Y(), n.Z()); } /*! - \brief This slot is called from "Show Previous" button click. - Shows information on the previous group of the items. + \brief Show previous chunk of information. */ void SMESHGUI_ElemInfo::showPrevious() { myIndex = qMax( 0, myIndex-1 ); updateControls(); - information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS )); + information( myIDs.mid( myIndex*blockSize(), blockSize() ) ); } /*! - \brief This slot is called from "Show Next" button click. - Shows information on the next group of the items. + \brief Show next chunk of information. */ void SMESHGUI_ElemInfo::showNext() { - myIndex = qMin( myIndex+1, myIDs.count() / MAXITEMS ); + myIndex = qMin( myIndex+1, myIDs.count() / blockSize() ); updateControls(); - information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS )); + information( myIDs.mid( myIndex*blockSize(), blockSize() ) ); } /*! - \brief Update widgets state + \brief Update control widget state. */ void SMESHGUI_ElemInfo::updateControls() { @@ -1156,448 +1999,53 @@ void SMESHGUI_ElemInfo::updateControls() } /*! - \class SMESHGUI_SimpleElemInfo - \brief Represents mesh element information in the simple text area. + \brief Write information from panel to ouput stream. + \param out Text stream output. */ +void SMESHGUI_ElemInfo::saveInfo( QTextStream &out ) +{ + // title + QString title = tr( "ELEM_INFO" ); + out << ruler( title.size() ) << endl; + out << title << endl; + out << ruler( title.size() ) << endl; + // out << endl; + + // info + StreamWriter writer( out ); + writeInfo( &writer, myIDs ); + out << endl; +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_SimpleElemInfo +/// \brief Show mesh element information in the simple text area. +//////////////////////////////////////////////////////////////////////////////// /*! - \brief Constructor - \param parent parent widget + \brief Constructor. + \param parent Parent widget. Defaults to 0. */ SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent ) : SMESHGUI_ElemInfo( parent ) { - myInfo = new QTextBrowser( frame() ); - QVBoxLayout* l = new QVBoxLayout( frame() ); + myInfo = new QTextBrowser( centralWidget() ); + QVBoxLayout* l = new QVBoxLayout( centralWidget() ); l->setMargin( 0 ); l->addWidget( myInfo ); + + connect( myInfo, SIGNAL( anchorClicked(QUrl)), this, SLOT( connectivityClicked( QUrl ))); } /*! - \brief Show mesh element information - \param ids mesh nodes / elements identifiers + \brief Show mesh element information. + \param ids Nodes / elements IDs. */ -void SMESHGUI_SimpleElemInfo::information( const QList& ids ) +void SMESHGUI_SimpleElemInfo::information( const QList& ids ) { clearInternal(); - - if ( actor() ) { - int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false ); - int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); - int cprecision = -1; - if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false )) - cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 ); - foreach ( long id, ids ) { - if ( !isElements() ) { - // - // show node info - // - const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id ); - if ( !node ) return; - - // node ID - myInfo->append( QString( "%1 #%2" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( id )); - // separator - myInfo->append( "" ); - // coordinates - myInfo->append( QString( "%1: (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" )). - arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )). - arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )). - arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )) ); - // separator - myInfo->append( "" ); - // connectivity - Connectivity connectivity = nodeConnectivity( node ); - if ( !connectivity.isEmpty() ) { - myInfo->append( QString( "%1:" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )) ); - QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )).arg( con )); - con = formatConnectivity( connectivity, SMDSAbs_Edge ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" )).arg( con )); - con = formatConnectivity( connectivity, SMDSAbs_Ball ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" )).arg( con )); - con = formatConnectivity( connectivity, SMDSAbs_Face ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" )).arg( con )); - con = formatConnectivity( connectivity, SMDSAbs_Volume ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" )).arg( con )); - } - else { - myInfo->append( QString( "%1" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" )).arg( id )); - } - // node position - SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer(); - if ( !CORBA::is_nil( aMeshPtr )) { - SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id ); - int shapeID = pos->shapeID; - if ( shapeID > 0 ) { - QString shapeType; - double u = 0, v = 0; - switch ( pos->shapeType ) { - case GEOM::EDGE: - shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); - if ( pos->params.length() == 1 ) - u = pos->params[0]; - break; - case GEOM::FACE: - shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); - if ( pos->params.length() == 2 ) { - u = pos->params[0]; - v = pos->params[1]; - } - break; - case GEOM::VERTEX: - shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); - break; - default: - shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); - break; - } - // separator - myInfo->append( "" ); - myInfo->append( QString( "%1:" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" )) ); - myInfo->append( QString( "- %1: #%2" ).arg( shapeType ).arg( shapeID )); - if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) { - myInfo->append( QString( "- %1: #%2" ).arg( SMESHGUI_ElemInfo::tr( "U_POSITION" )). - arg( QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )) )); - if ( pos->shapeType == GEOM::FACE ) { - myInfo->append( QString( "- %1: #%2" ).arg( SMESHGUI_ElemInfo::tr( "V_POSITION" )). - arg( QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )) )); - } - } - } - } - // groups node belongs to - SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer(); - if ( !CORBA::is_nil( aMesh )) { - SMESH::ListOfGroups_var groups = aMesh->GetGroups(); - myInfo->append( "" ); // separator - bool top_created = false; - for ( CORBA::ULong i = 0; i < groups->length(); i++ ) { - SMESH::SMESH_GroupBase_var aGrp = groups[i]; - if ( CORBA::is_nil( aGrp )) continue; - QString aName = aGrp->GetName(); - if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) { - if ( !top_created ) { - myInfo->append( QString( "%1:" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" )) ); - top_created = true; - } - myInfo->append( QString( "+ %1:" ).arg( aName.trimmed() )); - if ( grp_details ) { - SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp ); - SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp ); - SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp ); - - // type : group on geometry, standalone group, group on filter - if ( !CORBA::is_nil( aStdGroup )) { - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). - arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" )) ); - } - else if ( !CORBA::is_nil( aGeomGroup )) { - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). - arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" )) ); - GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape(); - _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj ); - if ( sobj ) { - myInfo->append( QString( " - %1: %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). - arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" )).arg( sobj->GetName().c_str() )); - } - } - else if ( !CORBA::is_nil( aFltGroup )) { - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). - arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )) ); - } - - // size - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" )). - arg( QString::number( aGrp->Size() )) ); - - // color - SALOMEDS::Color color = aGrp->GetColor(); - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" )). - arg( QColor( color.R*255., color.G*255., color.B*255. ).name() )); - } - } - } - } - } - else { - // - // show element info - // - const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id ); - SMESH::Controls::NumericalFunctorPtr afunctor; - if ( !e ) return; - - // Element ID && Type - QString stype; - switch( e->GetType() ) { - case SMDSAbs_0DElement: - stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break; - case SMDSAbs_Ball: - stype = SMESHGUI_ElemInfo::tr( "BALL" ); break; - case SMDSAbs_Edge: - stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break; - case SMDSAbs_Face: - stype = SMESHGUI_ElemInfo::tr( "FACE" ); break; - case SMDSAbs_Volume: - stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break; - default: - break; - } - if ( stype.isEmpty() ) return; - myInfo->append( QString( "%1 #%2" ).arg( stype ).arg( id )); - // separator - myInfo->append( "" ); - - // Geometry type - QString gtype; - switch( e->GetEntityType() ) { - case SMDSEntity_Triangle: - case SMDSEntity_Quad_Triangle: - case SMDSEntity_BiQuad_Triangle: - gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break; - case SMDSEntity_Quadrangle: - case SMDSEntity_Quad_Quadrangle: - case SMDSEntity_BiQuad_Quadrangle: - gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break; - case SMDSEntity_Polygon: - case SMDSEntity_Quad_Polygon: - gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break; - case SMDSEntity_Tetra: - case SMDSEntity_Quad_Tetra: - gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break; - case SMDSEntity_Pyramid: - case SMDSEntity_Quad_Pyramid: - gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break; - case SMDSEntity_Hexa: - case SMDSEntity_Quad_Hexa: - case SMDSEntity_TriQuad_Hexa: - gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break; - case SMDSEntity_Penta: - case SMDSEntity_Quad_Penta: - case SMDSEntity_BiQuad_Penta: - gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break; - case SMDSEntity_Hexagonal_Prism: - gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break; - case SMDSEntity_Polyhedra: - case SMDSEntity_Quad_Polyhedra: - gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break; - default: - break; - } - if ( !gtype.isEmpty() ) - myInfo->append( QString( "%1: %2" ).arg( SMESHGUI_ElemInfo::tr( "TYPE" )).arg( gtype )); - - // Quadratic flag (any element except 0D) - if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) { - myInfo->append( QString( "%1? %2" ).arg( SMESHGUI_ElemInfo::tr( "QUADRATIC" )).arg( e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" )) ); - } - if ( const SMDS_BallElement* ball = dynamic_cast( e )) { - // Ball diameter - myInfo->append( QString( "%1: %2" ).arg( SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" )).arg( ball->GetDiameter() )); - } - // separator - myInfo->append( "" ); - - // Connectivity - SMDS_ElemIteratorPtr nodeIt = e->nodesIterator(); - for ( int idx = 1; nodeIt->more(); idx++ ) { - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - // node number and ID - myInfo->append( QString( "%1 %2/%3 - #%4" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() )); - // node coordinates - myInfo->append( QString( "%1: (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "COORDINATES" )). - arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )). - arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )). - arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision )) ); - // node connectivity - Connectivity connectivity = nodeConnectivity( node ); - if ( !connectivity.isEmpty() ) { - myInfo->append( QString( "%1:" ).arg( SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )) ); - QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )).arg( con )); - con = formatConnectivity( connectivity, SMDSAbs_Edge ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( SMESHGUI_ElemInfo::tr( "EDGES" )).arg( con )); - con = formatConnectivity( connectivity, SMDSAbs_Face ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( SMESHGUI_ElemInfo::tr( "FACES" )).arg( con )); - con = formatConnectivity( connectivity, SMDSAbs_Volume ); - if ( !con.isEmpty() ) - myInfo->append( QString( "- %1: %2" ).arg( SMESHGUI_ElemInfo::tr( "VOLUMES" )).arg( con )); - } - else { - myInfo->append( QString( "%1" ).arg( SMESHGUI_ElemInfo::tr( "FREE_NODE" )).arg( id )); - } - } - // separator - myInfo->append( "" ); - - // Controls - myInfo->append( QString( "%1:" ).arg( SMESHGUI_ElemInfo::tr( "CONTROLS" )) ); - //Length - if ( e->GetType() == SMDSAbs_Edge ) { - afunctor.reset( new SMESH::Controls::Length() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "LENGTH_EDGES" )).arg( afunctor->GetValue( id )) ); - } - if( e->GetType() == SMDSAbs_Face ) { - //Area - afunctor.reset( new SMESH::Controls::Area() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "AREA_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //Taper - afunctor.reset( new SMESH::Controls::Taper() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "TAPER_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //AspectRatio2D - afunctor.reset( new SMESH::Controls::AspectRatio() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "ASPECTRATIO_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //Minimum angle - afunctor.reset( new SMESH::Controls::MinimumAngle() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "MINIMUMANGLE_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //Warping angle - afunctor.reset( new SMESH::Controls::Warping() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "WARP_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //Skew - afunctor.reset( new SMESH::Controls::Skew() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "SKEW_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //ElemDiam2D - afunctor.reset( new SMESH::Controls::MaxElementLength2D() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "MAX_ELEMENT_LENGTH_2D" )).arg( afunctor->GetValue( id )) ); - //min edge length - afunctor.reset( new SMESH::Controls::Length2D() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "MIN_ELEM_EDGE" )).arg( afunctor->GetValue( id )) ); - } - if( e->GetType() == SMDSAbs_Volume ) { - //AspectRatio3D - afunctor.reset( new SMESH::Controls::AspectRatio3D() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "ASPECTRATIO_3D_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //Volume - afunctor.reset( new SMESH::Controls::Volume() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "VOLUME_3D_ELEMENTS" )).arg( afunctor->GetValue( id )) ); - //ElementDiameter3D - afunctor.reset( new SMESH::Controls::Volume() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - myInfo->append( QString( "- %1: %2" ).arg( tr( "MAX_ELEMENT_LENGTH_3D" )).arg( afunctor->GetValue( id )) ); - } - // separator - myInfo->append( "" ); - - // Gravity center - XYZ gc = gravityCenter( e ); - myInfo->append( QString( "%1: (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" )).arg( gc.x() ).arg( gc.y() ).arg( gc.z() )); - - // Normal vector - if( e->GetType() == SMDSAbs_Face ) { - XYZ gc = normal( e ); - myInfo->append( QString( "%1: (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" )).arg( gc.x() ).arg( gc.y() ).arg( gc.z() )); - } - - // Element position - if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) { - SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer(); - if ( !CORBA::is_nil( aMesh )) { - SMESH::ElementPosition pos = aMesh->GetElementPosition( id ); - int shapeID = pos.shapeID; - if ( shapeID > 0 ) { - myInfo->append( "" ); // separator - QString shapeType; - switch ( pos.shapeType ) { - case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break; - case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break; - case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break; - case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break; - case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break; - default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break; - } - myInfo->append( QString( "%1: %2 #%3" ).arg( SMESHGUI_ElemInfo::tr( "POSITION" )).arg( shapeType ).arg( shapeID )); - } - } - } - - // Groups the element belongs to - SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer(); - if ( !CORBA::is_nil( aMesh )) { - SMESH::ListOfGroups_var groups = aMesh->GetGroups(); - myInfo->append( "" ); // separator - bool top_created = false; - for ( CORBA::ULong i = 0; i < groups->length(); i++ ) { - SMESH::SMESH_GroupBase_var aGrp = groups[i]; - if ( CORBA::is_nil( aGrp )) continue; - QString aName = aGrp->GetName(); - if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) { - if ( !top_created ) { - myInfo->append( QString( "%1:" ).arg( SMESHGUI_AddInfo::tr( "GROUPS" )) ); - top_created = true; - } - myInfo->append( QString( "+ %1:" ).arg( aName.trimmed() )); - if ( grp_details ) { - SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp ); - SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp ); - SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp ); - - // type : group on geometry, standalone group, group on filter - if ( !CORBA::is_nil( aStdGroup )) { - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). - arg( SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" )) ); - } - else if ( !CORBA::is_nil( aGeomGroup )) { - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). - arg( SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" )) ); - GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape(); - _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj ); - if ( sobj ) { - myInfo->append( QString( " - %1: %2: %3" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). - arg( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" )).arg( sobj->GetName().c_str() )); - } - } - else if ( !CORBA::is_nil( aFltGroup )) { - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "TYPE" )). - arg( SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )) ); - } - - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "SIZE" )). - arg( QString::number( aGrp->Size() )) ); - - // color - SALOMEDS::Color color = aGrp->GetColor(); - myInfo->append( QString( " - %1: %2" ).arg( SMESHGUI_AddInfo::tr( "COLOR" )). - arg( QColor( color.R*255., color.G*255., color.B*255. ).name() )); - } - } - } - } - } - // separator - if ( ids.count() > 1 ) { - myInfo->append( "" ); - myInfo->append( "------" ); - myInfo->append( "" ); - } - } - } + TextWriter writer( myInfo ); + writeInfo( &writer, ids ); } /*! @@ -1608,21 +2056,19 @@ void SMESHGUI_SimpleElemInfo::clearInternal() myInfo->clear(); } -void SMESHGUI_SimpleElemInfo::saveInfo( QTextStream &out ) +void SMESHGUI_SimpleElemInfo::connectivityClicked(const QUrl & url) { - out << QString( 12, '-' ) << "\n"; - out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n"; - out << QString( 12, '-' ) << "\n"; - out << myInfo->toPlainText(); - out << "\n"; + int type = ( url.scheme()[0] == 'n' ) ? NodeConnectivity : ElemConnectivity; + QString ids = url.path(); // excess chars will be filtered off by SMESHGUI_IdValidator + emit( itemInfo( type, ids )); } +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_TreeElemInfo::ItemDelegate +/// \brief Item delegate for tree mesh info widget. +/// \internal +//////////////////////////////////////////////////////////////////////////////// -/*! - \class SMESHGUI_TreeElemInfo::ItemDelegate - \brief Item delegate for tree mesh info widget - \internal -*/ class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate { public: @@ -1631,567 +2077,99 @@ public: }; /*! - \brief Constructor + \brief Constructor. \internal */ -SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent ) +SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ): QItemDelegate( parent ) { } /*! - \brief Create item editor widget + \brief Redefined from QItemDelegate. \internal */ QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const { QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index ); - if ( qobject_cast( w )) qobject_cast( w )->setReadOnly( true ); + if ( qobject_cast( w ) ) + qobject_cast( w )->setReadOnly( true ); return w; } +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_TreeElemInfo::ItemCreator +/// \brief Item creator for tree mesh info widget. +/// \internal +//////////////////////////////////////////////////////////////////////////////// + +class SMESHGUI_TreeElemInfo::ItemCreator : public TreeItemCreator +{ + SMESHGUI_TreeElemInfo* myView; +public: + ItemCreator( SMESHGUI_TreeElemInfo* ); + QTreeWidgetItem* createItem( QTreeWidgetItem*, int ); +}; + /*! - \class SMESHGUI_TreeElemInfo - \brief Represents mesh element information in the tree-like form. + \brief Constructor. + \param view Parent view. + \internal */ +SMESHGUI_TreeElemInfo::ItemCreator::ItemCreator( SMESHGUI_TreeElemInfo* view ): TreeItemCreator(), myView( view ) +{ +} /*! - \brief Constructor - \param parent parent widget + \brief Create new tree item. + \param parent Parent tree item. + \param options Item options. + \return New tree widget item. + \internal +*/ +QTreeWidgetItem* SMESHGUI_TreeElemInfo::ItemCreator::createItem( QTreeWidgetItem* parent, int options ) +{ + return myView->createItem( parent, options ); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_TreeElemInfo +/// \brief Show mesh element information as the tree. +//////////////////////////////////////////////////////////////////////////////// + +/*! + \brief Constructor. + \param parent Parent widget. Defaults to 0. */ SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent ) : SMESHGUI_ElemInfo( parent ) { - myInfo = new QTreeWidget( frame() ); + myInfo = new QTreeWidget( centralWidget() ); myInfo->setColumnCount( 2 ); - myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" )); + myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ) ); myInfo->header()->setStretchLastSection( true ); #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents ); #else myInfo->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents ); #endif - myInfo->setItemDelegate( new ItemDelegate( myInfo )); - QVBoxLayout* l = new QVBoxLayout( frame() ); + myInfo->setItemDelegate( new ItemDelegate( myInfo ) ); + QVBoxLayout* l = new QVBoxLayout( centralWidget() ); l->setMargin( 0 ); l->addWidget( myInfo ); - connect( myInfo, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int )), this, SLOT( itemDoubleClicked( QTreeWidgetItem*, int )) ); + connect( myInfo, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( itemDoubleClicked( QTreeWidgetItem*, int ) ) ); connect( myInfo, SIGNAL( itemCollapsed( QTreeWidgetItem* )), this, SLOT( saveExpanded( QTreeWidgetItem* )) ); connect( myInfo, SIGNAL( itemExpanded( QTreeWidgetItem* )), this, SLOT( saveExpanded( QTreeWidgetItem* )) ); } /*! - \brief Show mesh element information - \param ids mesh nodes / elements identifiers + \brief Show mesh element information. + \param ids Nodes / elements IDs. */ -void SMESHGUI_TreeElemInfo::information( const QList& ids ) +void SMESHGUI_TreeElemInfo::information( const QList& ids ) { clearInternal(); - - if ( actor() ) { - int grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false ); - int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); - int cprecision = -1; - if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false )) - cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 ); - foreach ( long id, ids ) { - if ( !isElements() ) { - // - // show node info - // - const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id ); - if ( !e ) return; - const SMDS_MeshNode* node = static_cast( e ); - - // node ID - QTreeWidgetItem* nodeItem = createItem( 0, Bold | All ); - nodeItem->setText( 0, SMESHGUI_ElemInfo::tr( "NODE" )); - nodeItem->setText( 1, QString( "#%1" ).arg( id )); - // coordinates - QTreeWidgetItem* coordItem = createItem( nodeItem, Bold ); - coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" )); - QTreeWidgetItem* xItem = createItem( coordItem ); - xItem->setText( 0, "X" ); - xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision )) ); - QTreeWidgetItem* yItem = createItem( coordItem ); - yItem->setText( 0, "Y" ); - yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision )) ); - QTreeWidgetItem* zItem = createItem( coordItem ); - zItem->setText( 0, "Z" ); - zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision )) ); - // connectivity - QTreeWidgetItem* conItem = createItem( nodeItem, Bold ); - conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )); - Connectivity connectivity = nodeConnectivity( node ); - if ( !connectivity.isEmpty() ) { - QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( conItem ); - i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )); - i->setText( 1, con ); - } - con = formatConnectivity( connectivity, SMDSAbs_Ball ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( conItem ); - i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" )); - i->setText( 1, con ); - i->setData( 1, TypeRole, NodeConnectivity ); - } - con = formatConnectivity( connectivity, SMDSAbs_Edge ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( conItem ); - i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" )); - i->setText( 1, con ); - i->setData( 1, TypeRole, NodeConnectivity ); - } - con = formatConnectivity( connectivity, SMDSAbs_Face ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( conItem ); - i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" )); - i->setText( 1, con ); - i->setData( 1, TypeRole, NodeConnectivity ); - } - con = formatConnectivity( connectivity, SMDSAbs_Volume ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( conItem ); - i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" )); - i->setText( 1, con ); - i->setData( 1, TypeRole, NodeConnectivity ); - } - } - else { - conItem->setText( 1, SMESHGUI_ElemInfo::tr( "FREE_NODE" )); - } - // node position - SMESH::SMESH_Mesh_ptr aMeshPtr = actor()->GetObject()->GetMeshServer(); - if ( !CORBA::is_nil( aMeshPtr )) { - SMESH::NodePosition_var pos = aMeshPtr->GetNodePosition( id ); - int shapeID = pos->shapeID; - if ( shapeID > 0 ) { - QString shapeType; - double u = 0, v = 0; - switch ( pos->shapeType ) { - case GEOM::EDGE: - shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); - if ( pos->params.length() == 1 ) - u = pos->params[0]; - break; - case GEOM::FACE: - shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); - if ( pos->params.length() == 2 ) { - u = pos->params[0]; - v = pos->params[1]; - } - break; - case GEOM::VERTEX: - shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); - break; - default: - shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); - break; - } - QTreeWidgetItem* posItem = createItem( nodeItem, Bold ); - posItem->setText( 0, SMESHGUI_ElemInfo::tr("POSITION") ); - posItem->setText( 1, (shapeType + " #%1").arg( shapeID )); - if ( pos->shapeType == GEOM::EDGE || pos->shapeType == GEOM::FACE ) { - QTreeWidgetItem* uItem = createItem( posItem ); - uItem->setText( 0, SMESHGUI_ElemInfo::tr("U_POSITION") ); - uItem->setText( 1, QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision ))); - if ( pos->shapeType == GEOM::FACE ) { - QTreeWidgetItem* vItem = createItem( posItem ); - vItem->setText( 0, SMESHGUI_ElemInfo::tr("V_POSITION") ); - vItem->setText( 1, QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision ))); - } - } - } - } - // groups node belongs to - SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer(); - if ( !CORBA::is_nil( aMesh )) { - SMESH::ListOfGroups_var groups = aMesh->GetGroups(); - QTreeWidgetItem* groupsItem = 0; - for ( CORBA::ULong i = 0; i < groups->length(); i++ ) { - SMESH::SMESH_GroupBase_var aGrp = groups[i]; - if ( CORBA::is_nil( aGrp )) continue; - QString aName = aGrp->GetName(); - if ( aGrp->GetType() == SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) { - if ( !groupsItem ) { - groupsItem = createItem( nodeItem, Bold ); - groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" )); - } - QTreeWidgetItem* it = createItem( groupsItem, Bold ); - it->setText( 0, aName.trimmed() ); - if ( grp_details ) { - SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp ); - SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp ); - SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp ); - - // type : group on geometry, standalone group, group on filter - QTreeWidgetItem* typeItem = createItem( it ); - typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" )); - if ( !CORBA::is_nil( aStdGroup )) { - typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" )); - } - else if ( !CORBA::is_nil( aGeomGroup )) { - typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" )); - GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape(); - _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj ); - if ( sobj ) { - QTreeWidgetItem* gobjItem = createItem( typeItem ); - gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" )); - gobjItem->setText( 1, sobj->GetName().c_str() ); - } - } - else if ( !CORBA::is_nil( aFltGroup )) { - typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )); - } - - // size - QTreeWidgetItem* sizeItem = createItem( it ); - sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" )); - sizeItem->setText( 1, QString::number( aGrp->Size() )); - - // color - SALOMEDS::Color color = aGrp->GetColor(); - QTreeWidgetItem* colorItem = createItem( it ); - colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" )); - colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) )); - } - } - } - } - } - else { - // - // show element info - // - const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id ); - SMESH::Controls::NumericalFunctorPtr afunctor; - if ( !e ) return; - - // element ID && type - QString stype; - switch( e->GetType() ) { - case SMDSAbs_0DElement: stype = SMESHGUI_ElemInfo::tr( "0D_ELEMENT" ); break; - case SMDSAbs_Ball: stype = SMESHGUI_ElemInfo::tr( "BALL" ); break; - case SMDSAbs_Edge: stype = SMESHGUI_ElemInfo::tr( "EDGE" ); break; - case SMDSAbs_Face: stype = SMESHGUI_ElemInfo::tr( "FACE" ); break; - case SMDSAbs_Volume: stype = SMESHGUI_ElemInfo::tr( "VOLUME" ); break; - default:; - } - if ( stype.isEmpty() ) return; - QTreeWidgetItem* elemItem = createItem( 0, Bold | All ); - elemItem->setText( 0, stype ); - elemItem->setText( 1, QString( "#%1" ).arg( id )); - // geometry type - QString gtype; - switch( e->GetEntityType() ) { - case SMDSEntity_Triangle: - case SMDSEntity_Quad_Triangle: - case SMDSEntity_BiQuad_Triangle: - gtype = SMESHGUI_ElemInfo::tr( "TRIANGLE" ); break; - case SMDSEntity_Quadrangle: - case SMDSEntity_Quad_Quadrangle: - case SMDSEntity_BiQuad_Quadrangle: - gtype = SMESHGUI_ElemInfo::tr( "QUADRANGLE" ); break; - case SMDSEntity_Polygon: - case SMDSEntity_Quad_Polygon: - gtype = SMESHGUI_ElemInfo::tr( "POLYGON" ); break; - case SMDSEntity_Tetra: - case SMDSEntity_Quad_Tetra: - gtype = SMESHGUI_ElemInfo::tr( "TETRAHEDRON" ); break; - case SMDSEntity_Pyramid: - case SMDSEntity_Quad_Pyramid: - gtype = SMESHGUI_ElemInfo::tr( "PYRAMID" ); break; - case SMDSEntity_Hexa: - case SMDSEntity_Quad_Hexa: - case SMDSEntity_TriQuad_Hexa: - gtype = SMESHGUI_ElemInfo::tr( "HEXAHEDRON" ); break; - case SMDSEntity_Penta: - case SMDSEntity_Quad_Penta: - case SMDSEntity_BiQuad_Penta: - gtype = SMESHGUI_ElemInfo::tr( "PRISM" ); break; - case SMDSEntity_Hexagonal_Prism: - gtype = SMESHGUI_ElemInfo::tr( "HEX_PRISM" ); break; - case SMDSEntity_Polyhedra: - case SMDSEntity_Quad_Polyhedra: - gtype = SMESHGUI_ElemInfo::tr( "POLYHEDRON" ); break; - default: - break; - } - if ( !gtype.isEmpty() ) { - QTreeWidgetItem* typeItem = createItem( elemItem, Bold ); - typeItem->setText( 0, SMESHGUI_ElemInfo::tr( "TYPE" )); - typeItem->setText( 1, gtype ); - } - // quadratic flag (for edges, faces and volumes) - if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) { - // quadratic flag - QTreeWidgetItem* quadItem = createItem( elemItem, Bold ); - quadItem->setText( 0, SMESHGUI_ElemInfo::tr( "QUADRATIC" )); - quadItem->setText( 1, e->IsQuadratic() ? SMESHGUI_ElemInfo::tr( "YES" ) : SMESHGUI_ElemInfo::tr( "NO" )); - } - if ( const SMDS_BallElement* ball = dynamic_cast( e )) { - // ball diameter - QTreeWidgetItem* diamItem = createItem( elemItem, Bold ); - diamItem->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_DIAMETER" )); - diamItem->setText( 1, QString( "%1" ).arg( ball->GetDiameter() )); - } - // connectivity - QTreeWidgetItem* conItem = createItem( elemItem, Bold ); - conItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )); - - - if( e->GetGeomType() != SMDSGeom_POLYHEDRA ) { - SMDS_ElemIteratorPtr nodeIt = e->nodesIterator(); - for ( int idx = 1; nodeIt->more(); idx++ ) { - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - nodeInfo( node, idx, e->NbNodes(), conItem ); - } - } - else { - const SMDS_VtkVolume* aVtkVolume = dynamic_cast(e); - SMDS_ElemIteratorPtr nodeIt = aVtkVolume->uniqueNodesIterator(); - QList uniqueNodes; - while ( nodeIt->more() ) - uniqueNodes.append( nodeIt->next() ); - - SMDS_VolumeTool vtool( e ); - const int nbFaces = vtool.NbFaces(); - for( int face_id = 0; face_id < nbFaces; face_id++ ) { - QTreeWidgetItem* faceItem = createItem( conItem, Bold ); - faceItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "FACE" )).arg( face_id + 1 ).arg( nbFaces )); - faceItem->setExpanded( true ); - - const SMDS_MeshNode** aNodeIds = vtool.GetFaceNodes( face_id ); - const int nbNodes = vtool.NbFaceNodes( face_id ); - for( int node_id = 0; node_id < nbNodes; node_id++ ) { - const SMDS_MeshNode* node = aNodeIds[node_id]; - nodeInfo( node, uniqueNodes.indexOf(node) + 1, aVtkVolume->NbUniqueNodes(), faceItem ); - } - } - } - //Controls - QTreeWidgetItem* cntrItem = createItem( elemItem, Bold ); - cntrItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONTROLS" )); - //Length - if( e->GetType()==SMDSAbs_Edge){ - afunctor.reset( new SMESH::Controls::Length() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - QTreeWidgetItem* lenItem = createItem( cntrItem, Bold ); - lenItem->setText( 0, tr( "LENGTH_EDGES" )); - lenItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - } - if( e->GetType() == SMDSAbs_Face ) { - //Area - afunctor.reset( new SMESH::Controls::Area() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - QTreeWidgetItem* areaItem = createItem( cntrItem, Bold ); - areaItem->setText( 0, tr( "AREA_ELEMENTS" )); - areaItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue(id) )); - //Taper - if ( e->NbNodes() == 4 ) // see SMESH_Controls.cxx - { - afunctor.reset( new SMESH::Controls::Taper() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold ); - taperlItem->setText( 0, tr( "TAPER_ELEMENTS" )); - taperlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - //Warping angle - afunctor.reset( new SMESH::Controls::Warping() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - QTreeWidgetItem* warpItem = createItem( cntrItem, Bold ); - warpItem->setText( 0, tr( "WARP_ELEMENTS" )); - warpItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - } - //AspectRatio2D - if ( !e->IsPoly() ) - { - afunctor.reset( new SMESH::Controls::AspectRatio() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - QTreeWidgetItem* ratlItem = createItem( cntrItem, Bold ); - ratlItem->setText( 0, tr( "ASPECTRATIO_ELEMENTS" )); - ratlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - } - //Minimum angle - afunctor.reset( new SMESH::Controls::MinimumAngle() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - QTreeWidgetItem* minanglItem = createItem( cntrItem, Bold ); - minanglItem->setText( 0, tr( "MINIMUMANGLE_ELEMENTS" )); - minanglItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - //Skew - if ( e->NbNodes() == 3 || e->NbNodes() == 4 ) - { - afunctor.reset( new SMESH::Controls::Skew() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - QTreeWidgetItem* skewItem = createItem( cntrItem, Bold ); - skewItem->setText( 0, tr( "SKEW_ELEMENTS" )); - skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - } - //Deflection - if ( hasShapeToMesh() ) - { - afunctor.reset( new SMESH::Controls::Deflection2D() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - QTreeWidgetItem* deflItem = createItem( cntrItem, Bold ); - deflItem->setText( 0, tr( "DEFLECTION_2D" )); - deflItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - } - //ElemDiam2D - if ( !e->IsPoly() ) - { - afunctor.reset( new SMESH::Controls::MaxElementLength2D() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - QTreeWidgetItem* diamItem = createItem( cntrItem, Bold ); - diamItem->setText( 0, tr( "MAX_ELEMENT_LENGTH_2D" )); - diamItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - } - } - if( e->GetType() == SMDSAbs_Volume ) { - if ( !e->IsPoly() ) - { - //AspectRatio3D - afunctor.reset( new SMESH::Controls::AspectRatio3D() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - QTreeWidgetItem* ratlItem3 = createItem( cntrItem, Bold ); - ratlItem3->setText( 0, tr( "ASPECTRATIO_3D_ELEMENTS" )); - ratlItem3->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - } - //Volume - afunctor.reset( new SMESH::Controls::Volume() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - QTreeWidgetItem* volItem = createItem( cntrItem, Bold ); - volItem->setText( 0, tr( "VOLUME_3D_ELEMENTS" )); - volItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - //ElementDiameter3D - afunctor.reset( new SMESH::Controls::MaxElementLength3D() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - QTreeWidgetItem* diam3Item = createItem( cntrItem, Bold ); - diam3Item->setText( 0, tr( "MAX_ELEMENT_LENGTH_3D" )); - diam3Item->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - } - - //min edge length - afunctor.reset( new SMESH::Controls::Length2D() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - QTreeWidgetItem* minEdgeItem = createItem( cntrItem, Bold ); - minEdgeItem->setText( 0, tr( "MIN_ELEM_EDGE" )); - minEdgeItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id )) ); - - // gravity center - XYZ gc = gravityCenter( e ); - QTreeWidgetItem* gcItem = createItem( elemItem, Bold ); - gcItem->setText( 0, SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" )); - QTreeWidgetItem* xItem = createItem( gcItem ); - xItem->setText( 0, "X" ); - xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision )) ); - QTreeWidgetItem* yItem = createItem( gcItem ); - yItem->setText( 0, "Y" ); - yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision )) ); - QTreeWidgetItem* zItem = createItem( gcItem ); - zItem->setText( 0, "Z" ); - zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision )) ); - - // normal vector - if( e->GetType() == SMDSAbs_Face ) { - XYZ gc = normal( e ); - QTreeWidgetItem* nItem = createItem( elemItem, Bold ); - nItem->setText( 0, SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" )); - QTreeWidgetItem* xItem = createItem( nItem ); - xItem->setText( 0, "X" ); - xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision )) ); - QTreeWidgetItem* yItem = createItem( nItem ); - yItem->setText( 0, "Y" ); - yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision )) ); - QTreeWidgetItem* zItem = createItem( nItem ); - zItem->setText( 0, "Z" ); - zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision )) ); - } - - // element position - SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer(); - if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) { - if ( !CORBA::is_nil( aMesh )) { - SMESH::ElementPosition pos = aMesh->GetElementPosition( id ); - int shapeID = pos.shapeID; - if ( shapeID > 0 ) { - QTreeWidgetItem* shItem = createItem( elemItem, Bold ); - QString shapeType; - switch ( pos.shapeType ) { - case GEOM::EDGE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_EDGE" ); break; - case GEOM::FACE: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_FACE" ); break; - case GEOM::VERTEX: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_VERTEX" ); break; - case GEOM::SOLID: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SOLID" ); break; - case GEOM::SHELL: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHELL" ); break; - default: shapeType = SMESHGUI_ElemInfo::tr( "GEOM_SHAPE" ); break; - } - shItem->setText( 0, SMESHGUI_ElemInfo::tr( "POSITION" )); - shItem->setText( 1, QString( "%1 #%2" ).arg( shapeType ).arg( shapeID )); - } - } - } - // groups element belongs to - if ( !CORBA::is_nil( aMesh )) { - SMESH::ListOfGroups_var groups = aMesh->GetGroups(); - QTreeWidgetItem* groupsItem = 0; - for ( CORBA::ULong i = 0; i < groups->length(); i++ ) { - SMESH::SMESH_GroupBase_var aGrp = groups[i]; - if ( CORBA::is_nil( aGrp )) continue; - QString aName = aGrp->GetName(); - if ( aGrp->GetType() != SMESH::NODE && !aName.isEmpty() && aGrp->Contains( id )) { - if ( !groupsItem ) { - groupsItem = createItem( elemItem, Bold ); - groupsItem->setText( 0, SMESHGUI_AddInfo::tr( "GROUPS" )); - } - QTreeWidgetItem* it = createItem( groupsItem, Bold ); - it->setText( 0, aName.trimmed() ); - if ( grp_details ) { - SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( aGrp ); - SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGrp ); - SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGrp ); - - // type : group on geometry, standalone group, group on filter - QTreeWidgetItem* typeItem = createItem( it ); - typeItem->setText( 0, SMESHGUI_AddInfo::tr( "TYPE" )); - if ( !CORBA::is_nil( aStdGroup )) { - typeItem->setText( 1, SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" )); - } - else if ( !CORBA::is_nil( aGeomGroup )) { - typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" )); - GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape(); - _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj ); - if ( sobj ) { - QTreeWidgetItem* gobjItem = createItem( typeItem ); - gobjItem->setText( 0, SMESHGUI_AddInfo::tr( "GEOM_OBJECT" )); - gobjItem->setText( 1, sobj->GetName().c_str() ); - } - } - else if ( !CORBA::is_nil( aFltGroup )) { - typeItem->setText( 1, SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" )); - } - - // size - QTreeWidgetItem* sizeItem = createItem( it ); - sizeItem->setText( 0, SMESHGUI_AddInfo::tr( "SIZE" )); - sizeItem->setText( 1, QString::number( aGrp->Size() )); - - // color - SALOMEDS::Color color = aGrp->GetColor(); - QTreeWidgetItem* colorItem = createItem( it ); - colorItem->setText( 0, SMESHGUI_AddInfo::tr( "COLOR" )); - colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) )); - } - } - } - } - } - } - } + TreeWriter writer( myInfo, new ItemCreator( this ) ); + writeInfo( &writer, ids ); } /*! @@ -2204,66 +2182,66 @@ void SMESHGUI_TreeElemInfo::information( const QList& ids ) void SMESHGUI_TreeElemInfo::nodeInfo( const SMDS_MeshNode* node, int index, int nbNodes, QTreeWidgetItem* parentItem ) { - int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); - // node number and ID - QTreeWidgetItem* nodeItem = createItem( parentItem, Bold ); - nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( index ).arg( nbNodes )); - nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() )); - nodeItem->setData( 1, TypeRole, ElemConnectivity ); - nodeItem->setData( 1, IdRole, node->GetID() ); - nodeItem->setExpanded( false ); - // node coordinates - QTreeWidgetItem* coordItem = createItem( nodeItem ); - coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" )); - QTreeWidgetItem* xItem = createItem( coordItem ); - xItem->setText( 0, "X" ); - xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision )) ); - QTreeWidgetItem* yItem = createItem( coordItem ); - yItem->setText( 0, "Y" ); - yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision )) ); - QTreeWidgetItem* zItem = createItem( coordItem ); - zItem->setText( 0, "Z" ); - zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision )) ); - // node connectivity - QTreeWidgetItem* nconItem = createItem( nodeItem ); - nconItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )); - Connectivity connectivity = nodeConnectivity( node ); - if ( !connectivity.isEmpty() ) { - QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( nconItem ); - i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )); - i->setText( 1, con ); - } - con = formatConnectivity( connectivity, SMDSAbs_Edge ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( nconItem ); - i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" )); - i->setText( 1, con ); - i->setData( 1, TypeRole, NodeConnectivity ); - } - con = formatConnectivity( connectivity, SMDSAbs_Ball ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( nconItem ); - i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" )); - i->setText( 1, con ); - i->setData( 1, TypeRole, NodeConnectivity ); - } - con = formatConnectivity( connectivity, SMDSAbs_Face ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( nconItem ); - i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" )); - i->setText( 1, con ); - i->setData( 1, TypeRole, NodeConnectivity ); - } - con = formatConnectivity( connectivity, SMDSAbs_Volume ); - if ( !con.isEmpty() ) { - QTreeWidgetItem* i = createItem( nconItem ); - i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" )); - i->setText( 1, con ); - i->setData( 1, TypeRole, NodeConnectivity ); - } - } + // int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); + // // node number and ID + // QTreeWidgetItem* nodeItem = createItem( parentItem, Bold ); + // nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( index ).arg( nbNodes )); + // nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() )); + // nodeItem->setData( 1, TypeRole, ElemConnectivity ); + // nodeItem->setData( 1, IdRole, node->GetID() ); + // nodeItem->setExpanded( false ); + // // node coordinates + // QTreeWidgetItem* coordItem = createItem( nodeItem ); + // coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" )); + // QTreeWidgetItem* xItem = createItem( coordItem ); + // xItem->setText( 0, "X" ); + // xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision )) ); + // QTreeWidgetItem* yItem = createItem( coordItem ); + // yItem->setText( 0, "Y" ); + // yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision )) ); + // QTreeWidgetItem* zItem = createItem( coordItem ); + // zItem->setText( 0, "Z" ); + // zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision )) ); + // // node connectivity + // QTreeWidgetItem* nconItem = createItem( nodeItem ); + // nconItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" )); + // Connectivity connectivity = nodeConnectivity( node ); + // if ( !connectivity.isEmpty() ) { + // QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); + // if ( !con.isEmpty() ) { + // QTreeWidgetItem* i = createItem( nconItem ); + // i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" )); + // i->setText( 1, con ); + // } + // con = formatConnectivity( connectivity, SMDSAbs_Edge ); + // if ( !con.isEmpty() ) { + // QTreeWidgetItem* i = createItem( nconItem ); + // i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" )); + // i->setText( 1, con ); + // i->setData( 1, TypeRole, NodeConnectivity ); + // } + // con = formatConnectivity( connectivity, SMDSAbs_Ball ); + // if ( !con.isEmpty() ) { + // QTreeWidgetItem* i = createItem( nconItem ); + // i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" )); + // i->setText( 1, con ); + // i->setData( 1, TypeRole, NodeConnectivity ); + // } + // con = formatConnectivity( connectivity, SMDSAbs_Face ); + // if ( !con.isEmpty() ) { + // QTreeWidgetItem* i = createItem( nconItem ); + // i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" )); + // i->setText( 1, con ); + // i->setData( 1, TypeRole, NodeConnectivity ); + // } + // con = formatConnectivity( connectivity, SMDSAbs_Volume ); + // if ( !con.isEmpty() ) { + // QTreeWidgetItem* i = createItem( nconItem ); + // i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" )); + // i->setText( 1, con ); + // i->setData( 1, TypeRole, NodeConnectivity ); + // } + // } } /*! \brief Internal clean-up (reset widget) @@ -2275,35 +2253,22 @@ void SMESHGUI_TreeElemInfo::clearInternal() } /*! - \brief Create new tree item. - \param parent parent tree widget item - \param flags item flag - \return new tree widget item + \brief Create new item and add it to the tree. + \param parent Parent tree widget item. Defaults to 0 (top-level item). + \param options Item flags. Defaults to 0 (none). + \return New tree widget item. */ -QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags ) +QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int options ) { - QTreeWidgetItem* item; - if ( parent ) - item = new QTreeWidgetItem( parent ); - else - item = new QTreeWidgetItem( myInfo ); - - item->setFlags( item->flags() | Qt::ItemIsEditable ); - - QFont f = item->font( 0 ); - f.setBold( true ); - for ( int i = 0; i < myInfo->columnCount(); i++ ) { - if ( ( flags & Bold ) && ( i == 0 || flags & All )) - item->setFont( i, f ); - } + QTreeWidgetItem* item = new QTreeWidgetItem( parent ? parent : myInfo->invisibleRootItem() ); + setTreeItemAttributes( item, options | Expanded | Editable ); if ( parent && parent->childCount() == 1 && itemDepth( parent ) == 1 ) { QString resName = expandedResource( parent ); parent->setExpanded( SMESHGUI::resourceMgr()->booleanValue("SMESH", resName, true )); } - - item->setExpanded( true ); + return item; } @@ -2313,24 +2278,21 @@ void SMESHGUI_TreeElemInfo::contextMenuEvent( QContextMenuEvent* e ) if ( widgets.isEmpty() ) return; QTreeWidgetItem* aTreeItem = widgets.first(); int type = aTreeItem->data( 1, TypeRole ).toInt(); - int id = aTreeItem->data( 1, IdRole ).toInt(); - QMenu menu; - QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" )); - if ( type == ElemConnectivity && id > 0 && menu.exec( e->globalPos() ) == a ) - emit( itemInfo( id )); - else if ( type == NodeConnectivity && menu.exec( e->globalPos() ) == a ) - emit( itemInfo( aTreeItem->text( 1 )) ); + if (( type == ElemConnectivity || type == NodeConnectivity ) && + ( !aTreeItem->text( 1 ).isEmpty() )) + { + QMenu menu; + QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" )); + if ( menu.exec( e->globalPos() ) == a ) + emit( itemInfo( type, aTreeItem->text( 1 )) ); + } } void SMESHGUI_TreeElemInfo::itemDoubleClicked( QTreeWidgetItem* theItem, int theColumn ) { if ( theItem ) { int type = theItem->data( 1, TypeRole ).toInt(); - int id = theItem->data( 1, IdRole ).toInt(); - if ( type == ElemConnectivity && id > 0 ) - emit( itemInfo( id )); - else if ( type == NodeConnectivity ) - emit( itemInfo( theItem->text( 1 )) ); + emit( itemInfo( type, theItem->text( 1 )) ); } } @@ -2342,482 +2304,527 @@ void SMESHGUI_TreeElemInfo::saveExpanded( QTreeWidgetItem* theItem ) QString SMESHGUI_TreeElemInfo::expandedResource( QTreeWidgetItem* theItem ) { - return QString("Expanded_") + ( isElements() ? "E_" : "N_" ) + theItem->text(0); + return QString("Expanded_") + ( what()==ShowElements ? "E_" : "N_" ) + theItem->text(0); } -void SMESHGUI_TreeElemInfo::saveInfo( QTextStream &out ) -{ - out << QString( 12, '-' ) << "\n"; - out << SMESHGUI_ElemInfo::tr( "ELEM_INFO" ) << "\n"; - out << QString( 12, '-' ) << "\n"; - - QTreeWidgetItemIterator it( myInfo ); - while ( *it ) { - if ( !( *it )->text(0).isEmpty() ) { - out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0); - if ( !( *it )->text(1).isEmpty() ) out << ": " << ( *it )->text(1); - out << "\n"; - } - ++it; - } - out << "\n"; -} +//////////////////////////////////////////////////////////////////////////////// +/// \class InfoComputor +/// \brief Mesh information computor. +/// \internal +/// +/// The class is created for different computation operations. Currently it is +/// used to compute size and number of underlying nodes for given group. +//////////////////////////////////////////////////////////////////////////////// /*! - \class GrpComputor - \brief Mesh information computer + \brief Constructor. + \param parent Parent object. + \param proxy Object to compute information on (group). + \param item Tree widget item, referenced by this computer. + \param operation Value to compute. \internal - - The class is created for different computation operation. Currently it is used - to compute number of underlying nodes for the groups. -*/ - -/*! - \brief Contructor */ -GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp, - QTreeWidgetItem* item, - QObject* parent, - bool toComputeSize) - : QObject( parent ), myItem( item ), myToComputeSize( toComputeSize ) +InfoComputor::InfoComputor( QObject* parent, const SMESH::SelectionProxy& proxy, int operation ) + : QObject( parent ), myProxy( proxy ), myOperation( operation ) { - myGroup = SMESH::SMESH_GroupBase::_narrow( grp ); } /*! - \brief Compute function + \brief Compute requested information. + \internal */ -void GrpComputor::compute() +void InfoComputor::compute() { - if ( !CORBA::is_nil( myGroup ) && myItem ) { + if ( myProxy ) + { SUIT_OverrideCursor wc; - QTreeWidgetItem* item = myItem; - myItem = 0; - int nb = myToComputeSize ? myGroup->Size() : myGroup->GetNumberOfNodes(); - item->treeWidget()->removeItemWidget( item, 1 ); - item->setText( 1, QString::number( nb )); + switch ( myOperation ) + { + case GrpSize: + myProxy.size( true ); // force size computation + emit computed(); + break; + case GrpNbNodes: + myProxy.nbNodes( true ); // force size computation + emit computed(); + break; + default: + break; + } } } -/*! - \class SMESHGUI_AddInfo - \brief The wigdet shows additional information on the mesh object. -*/ +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_AddInfo +/// \brief Show additional information on selected object. +/// +/// Displays an additional information about selected object: mesh, sub-mesh +/// or group. +/// +/// \todo Rewrite saveInfo() method to print all data, not currently shown only. +//////////////////////////////////////////////////////////////////////////////// /*! - \brief Constructor - \param parent parent widget + \brief Constructor. + \param parent Parent widget. Defaults to 0. */ -SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent ) - : QTreeWidget( parent ) +SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent ): SMESHGUI_Info( parent ) { - setColumnCount( 2 ); - header()->setStretchLastSection( true ); + QVBoxLayout* l = new QVBoxLayout( this ); + l->setMargin( 0 ); + l->setSpacing( SPACING ); + + myTree = new QTreeWidget( this ); + + myTree->setColumnCount( 2 ); + myTree->header()->setStretchLastSection( true ); #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - header()->setResizeMode( 0, QHeaderView::ResizeToContents ); + myTree->header()->setResizeMode( 0, QHeaderView::ResizeToContents ); #else - header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents ); + myTree->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents ); #endif - header()->hide(); + myTree->header()->hide(); + + l->addWidget( myTree ); } /*! - \brief Destructor + \brief Destructor. */ SMESHGUI_AddInfo::~SMESHGUI_AddInfo() { } /*! - \brief Show additional information on the selected object - \param obj object being processed (mesh, sub-mesh, group, ID source) + \brief Show information on given object. + \param proxy Object to show information on (mesh, sub-mesh, group). */ -void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) +void SMESHGUI_AddInfo::showInfo( const SMESH::SelectionProxy& proxy ) { + // reset panel setProperty( "group_index", 0 ); setProperty( "submesh_index", 0 ); myComputors.clear(); - clear(); + myTree->clear(); - if ( CORBA::is_nil( obj )) return; - - _PTR(SObject) sobj = SMESH::ObjectToSObject( obj ); - if ( !sobj ) return; - - // name - QTreeWidgetItem* nameItem = createItem( 0, Bold | All ); - nameItem->setText( 0, tr( "NAME" )); - nameItem->setText( 1, sobj->GetName().c_str() ); - - SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj ); - SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj ); - SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj ); - - if ( !aMesh->_is_nil() ) - meshInfo( aMesh, nameItem ); - else if ( !aSubMesh->_is_nil() ) - subMeshInfo( aSubMesh, nameItem ); - else if ( !aGroup->_is_nil() ) - groupInfo( aGroup.in(), nameItem ); + // then fill panel with data if object is not null + if ( proxy ) + { + myProxy = proxy; + + // name + QTreeWidgetItem* nameItem = createItem( 0, Bold | AllColumns ); + nameItem->setText( 0, tr( "NAME" ) ); + nameItem->setText( 1, proxy.name() ); + + // object info + if ( proxy.type() == SMESH::SelectionProxy::Mesh ) + meshInfo( proxy, nameItem ); + else if ( proxy.type() == SMESH::SelectionProxy::Submesh ) + subMeshInfo( proxy, nameItem ); + else if ( proxy.type() >= SMESH::SelectionProxy::Group ) + groupInfo( proxy, nameItem ); + } } /*! - \brief Create new tree item. - \param parent parent tree widget item - \param flags item flag - \return new tree widget item + \brief Update information in panel. */ -QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags ) +void SMESHGUI_AddInfo::updateInfo() { - QTreeWidgetItem* item; - - if ( parent ) - item = new QTreeWidgetItem( parent ); - else - item = new QTreeWidgetItem( this ); - - //item->setFlags( item->flags() | Qt::ItemIsEditable ); + showInfo( myProxy ); +} - QFont f = item->font( 0 ); - f.setBold( true ); - for ( int i = 0; i < columnCount(); i++ ) { - if ( ( flags & Bold ) && ( i == 0 || flags & All )) - item->setFont( i, f ); - } +/*! + \brief Reset panel (clear all data). +*/ +void SMESHGUI_AddInfo::clear() +{ + myTree->clear(); +} - item->setExpanded( true ); +/*! + \brief Create new item and add it to the tree. + \param parent Parent tree widget item. Defaults to 0 (top-level item). + \param options Item flags. Defaults to 0 (none). + \return New tree widget item. +*/ +QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int options ) +{ + QTreeWidgetItem* item = parent ? new QTreeWidgetItem( parent ) : + new QTreeWidgetItem( myTree->invisibleRootItem() ); + setTreeItemAttributes( item, options | Expanded ); return item; } /*! - \brief Show mesh info - \param mesh mesh object - \param parent parent tree item + \brief Show information on mesh. + \param proxy Proxy object (mesh). + \param parent Parent tree item. */ -void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent ) +void SMESHGUI_AddInfo::meshInfo( const SMESH::SelectionProxy& proxy, QTreeWidgetItem* parent ) { + if ( !proxy ) + return; + + QString shapeName = proxy.shapeName(); + SMESH::MedInfo inf = proxy.medFileInfo(); + // type - GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh(); - SMESH::MedFileInfo_var inf = mesh->GetMEDFileInfo(); QTreeWidgetItem* typeItem = createItem( parent, Bold ); - typeItem->setText( 0, tr( "TYPE" )); - if ( !CORBA::is_nil( shape )) { - typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" )); - _PTR(SObject) sobj = SMESH::ObjectToSObject( shape ); - if ( sobj ) { - QTreeWidgetItem* gobjItem = createItem( typeItem ); - gobjItem->setText( 0, tr( "GEOM_OBJECT" )); - gobjItem->setText( 1, sobj->GetName().c_str() ); - } + typeItem->setText( 0, tr( "TYPE" ) ); + if ( !shapeName.isEmpty() ) + { + typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ) ); + // shape + QTreeWidgetItem* gobjItem = createItem( parent, Bold ); + gobjItem->setText( 0, tr( "GEOM_OBJECT" ) ); + gobjItem->setText( 1, shapeName ); } - else if ( strlen( (char*)inf->fileName ) > 0 ) { - typeItem->setText( 1, tr( "MESH_FROM_FILE" )); - QTreeWidgetItem* fileItem = createItem( typeItem ); - fileItem->setText( 0, tr( "FILE_NAME" )); - fileItem->setText( 1, (char*)inf->fileName ); + else if ( inf.isValid() ) + { + typeItem->setText( 1, tr( "MESH_FROM_FILE" ) ); + // med file information + QTreeWidgetItem* fileItem = createItem( parent, Bold ); + fileItem->setText( 0, tr( "FILE_NAME" ) ); + fileItem->setText( 1, inf.fileName() ); + QTreeWidgetItem* sizeItem = createItem( parent, Bold ); + sizeItem->setText( 0, tr( "FILE_SIZE" ) ); + sizeItem->setText( 1, QString::number( inf.size() ) ); + QTreeWidgetItem* versionItem = createItem( parent, Bold ); + versionItem->setText( 0, tr( "FILE_VERSION" ) ); + versionItem->setText( 1, inf.version() != "0" ? inf.version() : tr( "VERSION_UNKNOWN" ) ); } - else { - typeItem->setText( 1, tr( "STANDALONE_MESH" )); + else + { + typeItem->setText( 1, tr( "STANDALONE_MESH" ) ); } // groups - myGroups = mesh->GetGroups(); + myGroups = proxy.groups(); showGroups(); // sub-meshes - mySubMeshes = mesh->GetSubMeshes(); + mySubMeshes = proxy.submeshes(); showSubMeshes(); } /*! - \brief Show sub-mesh info - \param subMesh sub-mesh object - \param parent parent tree item + \brief Show information on sub-mesh. + \param proxy Proxy object (sub-mesh). + \param parent Parent tree item. */ -void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent ) +void SMESHGUI_AddInfo::subMeshInfo( const SMESH::SelectionProxy& proxy, QTreeWidgetItem* parent ) { + if ( !proxy ) + return; + bool isShort = parent->parent() != 0; - if ( !isShort ) { + if ( !isShort ) + { // parent mesh - _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() ); - if ( sobj ) { + SMESH::SelectionProxy meshProxy = proxy.mesh(); + if ( meshProxy ) + { QTreeWidgetItem* nameItem = createItem( parent, Bold ); - nameItem->setText( 0, tr( "PARENT_MESH" )); - nameItem->setText( 1, sobj->GetName().c_str() ); + nameItem->setText( 0, tr( "PARENT_MESH" ) ); + nameItem->setText( 1, meshProxy.name() ); } } // shape - GEOM::GEOM_Object_var gobj = subMesh->GetSubShape(); - _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj ); - if ( sobj ) { + QString shapeName = proxy.shapeName(); + if ( !shapeName.isEmpty() ) + { QTreeWidgetItem* gobjItem = createItem( parent, Bold ); - gobjItem->setText( 0, tr( "GEOM_OBJECT" )); - gobjItem->setText( 1, sobj->GetName().c_str() ); + gobjItem->setText( 1, shapeName ); } } /*! - \brief Show group info - \param grp mesh group object - \param parent parent tree item + \brief Show information on group. + \param proxy Proxy object (group). + \param parent Parent tree item. */ -void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent ) +void SMESHGUI_AddInfo::groupInfo( const SMESH::SelectionProxy& proxy, QTreeWidgetItem* parent ) { - bool isShort = parent->parent() != 0; + if ( !proxy ) + return; - SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( grp ); - SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp ); - SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( grp ); + bool isShort = parent->parent() != 0; - if ( !isShort ) { + if ( !isShort ) + { // parent mesh - _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() ); - if ( sobj ) { + SMESH::SelectionProxy meshProxy = proxy.mesh(); + if ( meshProxy ) + { QTreeWidgetItem* nameItem = createItem( parent, Bold ); - nameItem->setText( 0, tr( "PARENT_MESH" )); - nameItem->setText( 1, sobj->GetName().c_str() ); + nameItem->setText( 0, tr( "PARENT_MESH" ) ); + nameItem->setText( 1, meshProxy.name() ); } } - // type : group on geometry, standalone group, group on filter + // type + SMESH::SelectionProxy::Type type = proxy.type(); QTreeWidgetItem* typeItem = createItem( parent, Bold ); - typeItem->setText( 0, tr( "TYPE" )); - if ( !CORBA::is_nil( aStdGroup )) { - typeItem->setText( 1, tr( "STANDALONE_GROUP" )); - } - else if ( !CORBA::is_nil( aGeomGroup )) { - typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" )); - GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape(); - _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj ); - if ( sobj ) { - QTreeWidgetItem* gobjItem = createItem( typeItem ); - gobjItem->setText( 0, tr( "GEOM_OBJECT" )); - gobjItem->setText( 1, sobj->GetName().c_str() ); - } + typeItem->setText( 0, tr( "TYPE" ) ); + if ( type == SMESH::SelectionProxy::GroupStd ) + { + typeItem->setText( 1, tr( "STANDALONE_GROUP" ) ); } - else if ( !CORBA::is_nil( aFltGroup )) { - typeItem->setText( 1, tr( "GROUP_ON_FILTER" )); + else if ( type == SMESH::SelectionProxy::GroupGeom ) + { + typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ) ); + // shape + QTreeWidgetItem* gobjItem = createItem( parent, Bold ); + gobjItem->setText( 0, tr( "GEOM_OBJECT" ) ); + gobjItem->setText( 1, proxy.shapeName() ); + } + else if ( type == SMESH::SelectionProxy::GroupFilter ) + { + typeItem->setText( 1, tr( "GROUP_ON_FILTER" ) ); } - if ( !isShort ) { - // entity type - QString etype = tr( "UNKNOWN" ); - switch( grp->GetType() ) { + // element type + int etype = proxy.groupElementType(); + if ( !isShort ) + { + QString typeName = tr( "UNKNOWN" ); + switch( etype ) + { case SMESH::NODE: - etype = tr( "NODE" ); + typeName = tr( "NODE" ); break; case SMESH::EDGE: - etype = tr( "EDGE" ); + typeName = tr( "EDGE" ); break; case SMESH::FACE: - etype = tr( "FACE" ); + typeName = tr( "FACE" ); break; case SMESH::VOLUME: - etype = tr( "VOLUME" ); + typeName = tr( "VOLUME" ); break; case SMESH::ELEM0D: - etype = tr( "0DELEM" ); + typeName = tr( "0DELEM" ); break; case SMESH::BALL: - etype = tr( "BALL" ); + typeName = tr( "BALL" ); break; default: break; } QTreeWidgetItem* etypeItem = createItem( parent, Bold ); - etypeItem->setText( 0, tr( "ENTITY_TYPE" )); - etypeItem->setText( 1, etype ); + etypeItem->setText( 0, tr( "ENTITY_TYPE" ) ); + etypeItem->setText( 1, typeName ); } - SMESH::SMESH_Mesh_var mesh = grp->GetMesh(); - bool meshLoaded = mesh->IsLoaded(); - - // size. Don't call grp->Size() for GroupOnFilter - issue IPAL52831 - int groupSize = -1; - if ( grp->IsNodeInfoAvailable() || CORBA::is_nil( aFltGroup )) - groupSize = grp->Size(); + // size + // note: size is not computed for group on filter for performance reasons, see IPAL52831 + bool meshLoaded = proxy.isMeshLoaded(); + int size = proxy.size(); QTreeWidgetItem* sizeItem = createItem( parent, Bold ); - sizeItem->setText( 0, tr( "SIZE" )); - if ( groupSize > -1 ) { - sizeItem->setText( 1, QString::number( groupSize )); + sizeItem->setText( 0, tr( "SIZE" ) ); + if ( size >= 0 ) + { + sizeItem->setText( 1, QString::number( size ) ); } - else { - QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this ); - setItemWidget( sizeItem, 1, btn ); - GrpComputor* comp = new GrpComputor( grp, sizeItem, this, /*size=*/true ); - connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() )); + else + { + QPushButton* btn = new QPushButton( meshLoaded ? tr( "COMPUTE" ) : tr( "LOAD" ), this ); + myTree->setItemWidget( sizeItem, 1, btn ); + InfoComputor* comp = new InfoComputor( this, proxy, InfoComputor::GrpSize ); + connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) ); + connect( comp, SIGNAL( computed() ), this, SLOT( updateInfo() ) ); myComputors.append( comp ); - if ( !meshLoaded ) - connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() )); } // color - SALOMEDS::Color color = grp->GetColor(); QTreeWidgetItem* colorItem = createItem( parent, Bold ); - colorItem->setText( 0, tr( "COLOR" )); - colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) )); + colorItem->setText( 0, tr( "COLOR" ) ); + colorItem->setBackground( 1, proxy.color() ); // nb of underlying nodes - if ( grp->GetType() != SMESH::NODE) { + if ( etype != SMESH::NODE ) + { QTreeWidgetItem* nodesItem = createItem( parent, Bold ); - nodesItem->setText( 0, tr( "NB_NODES" )); - int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 ); - bool toShowNodes = groupSize >= 0 ? ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || groupSize <= nbNodesLimit ) : false; - if ( toShowNodes && meshLoaded ) { - // already calculated and up-to-date - nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() )); + nodesItem->setText( 0, tr( "NB_NODES" ) ); + + int nbNodes = proxy.nbNodes(); + if ( nbNodes >= 0 ) + { + nodesItem->setText( 1, QString::number( nbNodes ) ); } - else { - QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this ); - setItemWidget( nodesItem, 1, btn ); - GrpComputor* comp = new GrpComputor( grp, nodesItem, this ); - connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() )); + else + { + QPushButton* btn = new QPushButton( meshLoaded ? tr( "COMPUTE" ) : tr( "LOAD" ), this ); + myTree->setItemWidget( nodesItem, 1, btn ); + InfoComputor* comp = new InfoComputor( this, proxy, InfoComputor::GrpNbNodes ); + connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) ); + connect( comp, SIGNAL( computed() ), this, SLOT( updateInfo() ) ); myComputors.append( comp ); - if ( !meshLoaded ) - connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() )); } } } +/*! + \brief Update information on child groups. +*/ void SMESHGUI_AddInfo::showGroups() { + // remove all computors myComputors.clear(); - QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item - if ( !parent ) return; + // tree root should be the first top level item + QTreeWidgetItem* parent = myTree->topLevelItemCount() > 0 ? myTree->topLevelItem( 0 ) : 0; + if ( !parent ) + return; int idx = property( "group_index" ).toInt(); + // find sub-meshes top-level container item QTreeWidgetItem* itemGroups = 0; - for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) { - if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) { + for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) + { + if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GroupsId ) + { itemGroups = parent->child( i ); - ExtraWidget* extra = dynamic_cast( itemWidget( itemGroups, 1 )); + // update controls + ExtraWidget* extra = dynamic_cast( myTree->itemWidget( itemGroups, 1 ) ); if ( extra ) - extra->updateControls( myGroups->length(), idx ); - while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items + extra->updateControls( myGroups.count(), idx ); + // clear: remove all group items + while ( itemGroups->childCount() ) + delete itemGroups->child( 0 ); } } QMap grpItems; - for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) { - SMESH::SMESH_GroupBase_var grp = myGroups[i]; - if ( CORBA::is_nil( grp )) continue; - _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp ); - if ( !grpSObj ) continue; - - int grpType = grp->GetType(); - - if ( !itemGroups ) { - // create top-level groups container item - itemGroups = createItem( parent, Bold | All ); - itemGroups->setText( 0, tr( "GROUPS" )); - itemGroups->setData( 0, Qt::UserRole, GROUPS_ID ); - - // total number of groups > 10, show extra widgets for info browsing - if ((int) myGroups->length() > MAXITEMS ) { + for ( int i = idx*blockSize() ; i < qMin( (idx+1)*blockSize(), (int)myGroups.count() ); i++ ) + { + SMESH::SelectionProxy grp = myGroups[i]; + if ( !grp ) + continue; + + int grpType = grp.groupElementType(); + + // create top-level groups container item if it does not exist + if ( !itemGroups ) + { + itemGroups = createItem( parent, Bold | AllColumns ); + itemGroups->setText( 0, tr( "GROUPS" ) ); + itemGroups->setData( 0, Qt::UserRole, GroupsId ); + + // if necessary, create extra widget to show information by chunks + if ( myGroups.count() > blockSize() ) + { ExtraWidget* extra = new ExtraWidget( this, true ); - connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() )); - connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() )); - setItemWidget( itemGroups, 1, extra ); - extra->updateControls( myGroups->length(), idx ); + connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ) ); + connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ) ); + myTree->setItemWidget( itemGroups, 1, extra ); + extra->updateControls( myGroups.count(), idx ); } } - if ( grpItems.find( grpType ) == grpItems.end() ) { - grpItems[ grpType ] = createItem( itemGroups, Bold | All ); - grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() )); - itemGroups->insertChild( grpType-1, grpItems[ grpType ] ); + // create container item corresponding to particular element type + if ( !grpItems.contains( grpType ) ) + { + grpItems[ grpType ] = createItem( itemGroups, Bold | AllColumns ); + grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ) ); + itemGroups->insertChild( grpType-1, grpItems[ grpType ] ); // -1 needed since 0 corresponds to SMESH::ALL } - // group name - QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] ); - grpNameItem->setText( 0, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed + // name + QTreeWidgetItem* nameItem = createItem( grpItems[ grpType ] ); + nameItem->setText( 0, grp.name().trimmed() ); // trim name // group info - groupInfo( grp.in(), grpNameItem ); + groupInfo( grp, nameItem ); } } +/*! + \brief Update information on child sub-meshes. +*/ void SMESHGUI_AddInfo::showSubMeshes() { - QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item - if ( !parent ) return; + // tree root should be the first top level item + QTreeWidgetItem* parent = myTree->topLevelItemCount() > 0 ? myTree->topLevelItem( 0 ) : 0; + if ( !parent ) + return; int idx = property( "submesh_index" ).toInt(); + // find sub-meshes top-level container item QTreeWidgetItem* itemSubMeshes = 0; - for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) { - if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) { + for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) + { + if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SubMeshesId ) + { itemSubMeshes = parent->child( i ); - ExtraWidget* extra = dynamic_cast( itemWidget( itemSubMeshes, 1 )); + // update controls + ExtraWidget* extra = dynamic_cast( myTree->itemWidget( itemSubMeshes, 1 ) ); if ( extra ) - extra->updateControls( mySubMeshes->length(), idx ); - while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items + extra->updateControls( mySubMeshes.count(), idx ); + // clear: remove all sub-mesh items + while ( itemSubMeshes->childCount() ) + delete itemSubMeshes->child( 0 ); } } QMap smItems; - for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) { - SMESH::SMESH_subMesh_var sm = mySubMeshes[i]; - if ( CORBA::is_nil( sm )) continue; - _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm ); - if ( !smSObj ) continue; - - GEOM::GEOM_Object_var gobj = sm->GetSubShape(); - if ( CORBA::is_nil(gobj )) continue; + for ( int i = idx*blockSize() ; i < qMin( (idx+1)*blockSize(), mySubMeshes.count() ); i++ ) + { + SMESH::SelectionProxy sm = mySubMeshes[i]; + if ( !sm ) + continue; - int smType = gobj->GetShapeType(); - if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND; - - if ( !itemSubMeshes ) { - itemSubMeshes = createItem( parent, Bold | All ); - itemSubMeshes->setText( 0, tr( "SUBMESHES" )); - itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID ); + int smType = sm.shapeType(); + if ( smType < 0 ) + continue; + else if ( smType == GEOM::COMPSOLID ) + smType = GEOM::COMPOUND; + + // create top-level sub-meshes container item if it does not exist + if ( !itemSubMeshes ) + { + itemSubMeshes = createItem( parent, Bold | AllColumns ); + itemSubMeshes->setText( 0, tr( "SUBMESHES" ) ); + itemSubMeshes->setData( 0, Qt::UserRole, SubMeshesId ); - // total number of sub-meshes > 10, show extra widgets for info browsing - if ((int) mySubMeshes->length() > MAXITEMS ) { + // if necessary, create extra widget to show information by chunks + if ( mySubMeshes.count() > blockSize() ) + { ExtraWidget* extra = new ExtraWidget( this, true ); - connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() )); - connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() )); - setItemWidget( itemSubMeshes, 1, extra ); - extra->updateControls( mySubMeshes->length(), idx ); + connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ) ); + connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ) ); + myTree->setItemWidget( itemSubMeshes, 1, extra ); + extra->updateControls( mySubMeshes.count(), idx ); } } - - if ( smItems.find( smType ) == smItems.end() ) { - smItems[ smType ] = createItem( itemSubMeshes, Bold | All ); - smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() )); - itemSubMeshes->insertChild( smType, smItems[ smType ] ); - } - - // submesh name - QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] ); - smNameItem->setText( 0, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed - - // submesh info - subMeshInfo( sm.in(), smNameItem ); - } -} -/*! - * \brief Change button label of "nb underlying node" group from "Load" to "Compute" - */ -void SMESHGUI_AddInfo::changeLoadToCompute() -{ - for ( int i = 0; i < myComputors.count(); ++i ) - { - if ( QTreeWidgetItem* item = myComputors[i]->getItem() ) + // create container item corresponding to particular shape type + if ( !smItems.contains( smType ) ) { - if ( QPushButton* btn = qobject_cast( itemWidget ( item, 1 )) ) - btn->setText( tr("COMPUTE") ); + smItems[ smType ] = createItem( itemSubMeshes, Bold | AllColumns ); + smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ) ); + itemSubMeshes->insertChild( smType, smItems[ smType ] ); } + + // name + QTreeWidgetItem* nameItem = createItem( smItems[ smType ] ); + nameItem->setText( 0, sm.name().trimmed() ); // trim name + + // submesh info + subMeshInfo( sm, nameItem ); } } +/*! + \brief Show previous chunk of information on child groups. +*/ void SMESHGUI_AddInfo::showPreviousGroups() { int idx = property( "group_index" ).toInt(); @@ -2825,6 +2832,9 @@ void SMESHGUI_AddInfo::showPreviousGroups() showGroups(); } +/*! + \brief Show next chunk of information on child groups. +*/ void SMESHGUI_AddInfo::showNextGroups() { int idx = property( "group_index" ).toInt(); @@ -2832,6 +2842,9 @@ void SMESHGUI_AddInfo::showNextGroups() showGroups(); } +/*! + \brief Show previous chunk of information on child sub-meshes. +*/ void SMESHGUI_AddInfo::showPreviousSubMeshes() { int idx = property( "submesh_index" ).toInt(); @@ -2839,6 +2852,9 @@ void SMESHGUI_AddInfo::showPreviousSubMeshes() showSubMeshes(); } +/*! + \brief Show next chunk of information on child sub-meshes. +*/ void SMESHGUI_AddInfo::showNextSubMeshes() { int idx = property( "submesh_index" ).toInt(); @@ -2846,50 +2862,161 @@ void SMESHGUI_AddInfo::showNextSubMeshes() showSubMeshes(); } +/*! + \brief Write information from panel to ouput stream. + \param out Text stream output. +*/ void SMESHGUI_AddInfo::saveInfo( QTextStream &out ) { - out << QString( 15, '-') << "\n"; - out << tr( "ADDITIONAL_INFO" ) << "\n"; - out << QString( 15, '-' ) << "\n"; - QTreeWidgetItemIterator it( this ); - while ( *it ) { - if ( !( ( *it )->text(0) ).isEmpty() ) { - out << QString( SPACING_INFO * itemDepth( *it ), ' ' ) << ( *it )->text(0); - if ( ( *it )->text(0) == tr( "COLOR" )) { - out << ": " << ( ( ( *it )->background(1) ).color() ).name(); - } - else if ( !( ( *it )->text(1) ).isEmpty() ) out << ": " << ( *it )->text(1); - out << "\n"; + // title + QString title = tr( "ADDITIONAL_INFO" ); + out << ruler( title.size() ) << endl; + out << title << endl; + out << ruler( title.size() ) << endl; + out << endl; + + // info + QTreeWidgetItemIterator it( myTree ); + while ( *it ) + { + if ( !( ( *it )->text(0) ).isEmpty() ) + { + out << indent( itemDepth( *it ) ) << ( *it )->text(0); + if ( ( *it )->text(0) == tr( "COLOR" ) ) + out << ":" << spacing() << ( ( ( *it )->background(1) ).color() ).name(); + else if ( !( ( *it )->text(1) ).isEmpty() ) + out << ":" << spacing() << ( *it )->text(1); + out << endl; } ++it; } - out << "\n"; + out << endl; +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class GroupCombo +/// \brief Customized combo box to manage list of mesh groups. +/// \internal +//////////////////////////////////////////////////////////////////////////////// + +class GroupCombo: public QComboBox +{ + class Item: public QStandardItem + { + public: + SMESH::SelectionProxy myGroup; + Item( const SMESH::SelectionProxy& group ) + { + myGroup = group; + setText( myGroup.name() ); + } + SMESH::SelectionProxy group() + { + return myGroup; + } + }; + + SMESH::SelectionProxy myProxy; + +public: + GroupCombo( QWidget* ); + void setSource( const SMESH::SelectionProxy& ); + SMESH::SelectionProxy currentGroup() const; +}; + +/*! + \brief Contructor. + \param parent Parent widget. + \internal +*/ +GroupCombo::GroupCombo( QWidget* parent ): QComboBox( parent ) +{ + setModel( new QStandardItemModel( this ) ); +} + +/*! + \brief Set mesh source. + \param obj Mesh source. + \internal +*/ +void GroupCombo::setSource( const SMESH::SelectionProxy& proxy ) +{ + if ( myProxy == proxy ) + return; + + myProxy = proxy; + + bool blocked = blockSignals( true ); + QStandardItemModel* m = dynamic_cast( model() ); + m->clear(); + + if ( myProxy ) + { + if ( myProxy.type() == SMESH::SelectionProxy::Mesh ) + { + QList groups = myProxy.groups(); + for ( int i = 0; i < groups.count(); ++i ) + { + if ( groups[i] ) + { + QString name = groups[i].name(); + if ( !name.isEmpty() ) + m->appendRow( new Item( groups[i] ) ); + } + } + setCurrentIndex( -1 ); // for performance reasons + } + else if ( myProxy.type() >= SMESH::SelectionProxy::Group ) + { + m->appendRow( new Item( myProxy ) ); + setCurrentIndex( 0 ); + } + } + + blockSignals( blocked ); } /*! - \class SMESHGUI_MeshInfoDlg - \brief Mesh information dialog box + \brief Get currently selected group. + \return Selected group. + \internal */ +SMESH::SelectionProxy GroupCombo::currentGroup() const +{ + SMESH::SelectionProxy group; + QStandardItemModel* m = dynamic_cast( model() ); + if ( currentIndex() >= 0 ) + group = dynamic_cast( m->item( currentIndex() ) )->group(); + return group; +} + +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_MeshInfoDlg +/// \brief Mesh information dialog box +/// +/// \todo Move all business logic for element info to SMESHGUI_ElemInfo class. +/// \todo Add selection button to reactivate selection on move from other dlg. +//////////////////////////////////////////////////////////////////////////////// /*! \brief Constructor - \param parent parent widget - \param page specifies the dialog page to be shown at the start-up + \param parent Parent widget. + \param page Dialog page to show at start-up. Defaults to \c BaseInfo. */ SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page ) - : QDialog( parent ), myActor( 0 ) + : QDialog( parent ) { setModal( false ); setAttribute( Qt::WA_DeleteOnClose, true ); - setWindowTitle( tr( "MESH_INFO" )); + setWindowTitle( tr( "MESH_INFO" ) ); setSizeGripEnabled( true ); myTabWidget = new QTabWidget( this ); // base info - myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget ); - myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" )); + myBaseInfo = new SMESHGUI_BaseInfo( myTabWidget ); + myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ) ); // elem info @@ -2898,40 +3025,47 @@ SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page ) myMode = new QButtonGroup( this ); myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode ); myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode ); + myMode->addButton( new QRadioButton( tr( "GROUP_MODE" ), w ), GroupMode ); myMode->button( NodeMode )->setChecked( true ); myID = new QLineEdit( w ); - myID->setValidator( new SMESHGUI_IdValidator( this )); + myID->setValidator( new SMESHGUI_IdValidator( this ) ); + myGroups = new GroupCombo( w ); + QStackedWidget* stack = new QStackedWidget( w ); + stack->addWidget( myID ); + stack->addWidget( myGroups ); myIDPreviewCheck = new QCheckBox( tr( "SHOW_IDS" ), w ); - myIDPreview = new SMESHGUI_IdPreview( SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() )); + myIDPreview = new SMESHGUI_IdPreview( SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() ) ); int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 ); - mode = qMin( 1, qMax( 0, mode )); + mode = qMin( 1, qMax( 0, mode ) ); if ( mode == 0 ) myElemInfo = new SMESHGUI_SimpleElemInfo( w ); else myElemInfo = new SMESHGUI_TreeElemInfo( w ); + stack->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ); QGridLayout* elemLayout = new QGridLayout( w ); elemLayout->setMargin( MARGIN ); elemLayout->setSpacing( SPACING ); elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 ); elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 ); - elemLayout->addWidget( myID, 0, 2 ); - elemLayout->addWidget( myIDPreviewCheck, 1, 0, 1, 2 ); - elemLayout->addWidget( myElemInfo, 2, 0, 1, 3 ); + elemLayout->addWidget( myMode->button( GroupMode ), 0, 2 ); + elemLayout->addWidget( stack, 0, 3 ); + elemLayout->addWidget( myIDPreviewCheck, 1, 0, 1, 4 ); + elemLayout->addWidget( myElemInfo, 2, 0, 1, 4 ); - myTabWidget->addTab( w, tr( "ELEM_INFO" )); + myTabWidget->addTab( w, tr( "ELEM_INFO" ) ); // additional info myAddInfo = new SMESHGUI_AddInfo( myTabWidget ); - myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" )); + myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ) ); // controls info myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget ); - myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" )); + myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ) ); // buttons @@ -2953,33 +3087,41 @@ SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page ) btnLayout->addStretch( 10 ); btnLayout->addWidget( helpBtn ); + // arrange widgets + QVBoxLayout* l = new QVBoxLayout ( this ); l->setMargin( MARGIN ); l->setSpacing( SPACING ); l->addWidget( myTabWidget ); l->addLayout( btnLayout ); - myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ))); + // set initial page + + myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ) ) ); - connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() )); - connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() )); - connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() )); - connect( myTabWidget, SIGNAL( currentChanged( int )), this, SLOT( updateSelection() )); - connect( myMode, SIGNAL( buttonClicked( int )), this, SLOT( modeChanged() )); - connect( myID, SIGNAL( textChanged( QString )), this, SLOT( idChanged() )); - connect( myIDPreviewCheck, SIGNAL( toggled(bool) ), this, SLOT( idPreviewChange(bool) )); - connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() )); - connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() )); - connect( myElemInfo, SIGNAL( itemInfo( int )), this, SLOT( showItemInfo( int ))); - connect( myElemInfo, SIGNAL( itemInfo( QString )), this, SLOT( showItemInfo( QString ))); + // set-up connections - myIDPreviewCheck->setChecked( SMESHGUI::resourceMgr()->booleanValue( "SMESH", id_preview_resource, false )); + connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) ); + connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) ); + connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) ); + connect( myMode, SIGNAL( buttonClicked( int ) ), this, SLOT( modeChanged() ) ); + connect( myGroups, SIGNAL( currentIndexChanged( int ) ), this, SLOT( modeChanged() ) ); + connect( myID, SIGNAL( textChanged( QString ) ), this, SLOT( idChanged() ) ); + connect( myIDPreviewCheck, SIGNAL( toggled( bool ) ), this, SLOT( idPreviewChange( bool ) ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) ); + connect( myElemInfo, SIGNAL( itemInfo( int, QString ) ), this, SLOT( showItemInfo( int, QString ) ) ); + connect( this, SIGNAL( switchMode( int ) ), stack, SLOT( setCurrentIndex( int ) ) ); + // initialize + + myIDPreviewCheck->setChecked( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "id_preview_resource", false ) ); updateSelection(); } /*! - \brief Destructor + \brief Destructor. */ SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg() { @@ -2987,66 +3129,105 @@ SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg() } /*! - \brief Show mesh information - \param IO interactive object + \brief Show mesh information on given object. + \param io Interactive object. */ -void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO ) +void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& io ) { - if ( !IO.IsNull() ) - myIO = IO; + if ( !io.IsNull() ) + showInfo( SMESH::SelectionProxy( io ) ); +} - SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO ); - if ( !CORBA::is_nil( obj )) - { - myAddInfo->showInfo( obj ); // nb of nodes in a group can be computed by myAddInfo, - myBaseInfo->showInfo( obj ); // and it will be used by myBaseInfo (IPAL52871) - if ( myTabWidget->currentIndex() == CtrlInfo ) - myCtrlInfo->showInfo( obj ); +/*! + \brief Show mesh information on given object. + \param proxy Selection proxy. +*/ +void SMESHGUI_MeshInfoDlg::showInfo( const SMESH::SelectionProxy& proxy ) +{ + SUIT_OverrideCursor wc; - { - myActor = SMESH::FindActorByEntry( IO->getEntry() ); - SVTK_Selector* selector = SMESH::GetSelector(); - QString ID; - int nb = 0; - if ( myActor && selector ) { - nb = myMode->checkedId() == NodeMode ? - SMESH::GetNameOfSelectedElements( selector, IO, ID ) : - SMESH::GetNameOfSelectedNodes( selector, IO, ID ); - } - myElemInfo->setSource( myActor, obj ) ; - if ( nb > 0 ) { - myID->setText( ID.trimmed() ); - QSet ids; - QStringList idTxt = ID.split( " ", QString::SkipEmptyParts ); - foreach ( ID, idTxt ) - ids << ID.trimmed().toLong(); - myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode ); - } - else { - myID->clear(); - myElemInfo->clear(); - } + if ( !proxy ) + return; + + myProxy = proxy; + + SMESH::SMESH_IDSource_var obj = myProxy.object(); + + // "Base info" tab + myBaseInfo->showInfo( proxy ); + + // "Additional info" tab + myAddInfo->showInfo( proxy ); + + // "Quality info" tab + // Note: for performance reasons we update it only if it is currently active + if ( myTabWidget->currentIndex() == CtrlInfo ) + myCtrlInfo->showInfo( proxy ); + + // "Element info" tab + myGroups->setSource( proxy ); + if ( myMode->checkedId() == GroupMode ) { + SMESH::SelectionProxy group = myGroups->currentGroup(); + if ( group ) + myElemInfo->showInfo( group ); + else + myElemInfo->clear(); + } + else { + SVTK_Selector* selector = SMESH::GetSelector(); + QString ID; + int nb = 0; + if ( myProxy.actor() && selector ) { //todo: actor()? + nb = myMode->checkedId() == NodeMode ? + SMESH::GetNameOfSelectedElements( selector, myProxy.io(), ID ) : + SMESH::GetNameOfSelectedNodes( selector, myProxy.io(), ID ); + } + if ( nb > 0 ) { + myID->setText( ID.trimmed() ); + QSet ids; + QStringList idTxt = ID.split( " ", QString::SkipEmptyParts ); + foreach ( ID, idTxt ) + ids << ID.trimmed().toUInt(); + myElemInfo->showInfo( proxy, ids, myMode->checkedId() == ElemMode ); + } + else { + myID->clear(); + myElemInfo->clear(); } } } /*! - \brief Perform clean-up actions on the dialog box closing. + \brief Update information. +*/ +void SMESHGUI_MeshInfoDlg::updateInfo() +{ + SALOME_ListIO selected; + SMESHGUI::selectionMgr()->selectedObjects( selected ); + + if ( selected.Extent() == 1 ) + showInfo( selected.First() ); + else + showInfo( myProxy ); +} + +/*! + \brief Clean-up on dialog closing. */ void SMESHGUI_MeshInfoDlg::reject() { LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr(); selMgr->clearFilters(); SMESH::SetPointRepresentation( false ); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) - aViewWindow->SetSelectionMode( ActorSelection ); + if ( SVTK_ViewWindow* viewWindow = SMESH::GetViewWindow() ) + viewWindow->SetSelectionMode( ActorSelection ); QDialog::reject(); - myIDPreview->SetPointsLabeled(false); + myIDPreview->SetPointsLabeled( false ); } /*! - \brief Process keyboard event - \param e key press event + \brief Process keyboard event. + \param e Key press event. */ void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e ) { @@ -3058,15 +3239,7 @@ void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e ) } /*! - \brief Reactivate dialog box, when mouse pointer goes into it. -*/ -void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* ) -{ - //activate(); -} - -/*! - \brief Setup selection mode depending on the current dialog box state. + \brief Set-up selection mode for currently selected page. */ void SMESHGUI_MeshInfoDlg::updateSelection() { @@ -3075,86 +3248,60 @@ void SMESHGUI_MeshInfoDlg::updateSelection() disconnect( selMgr, 0, this, 0 ); selMgr->clearFilters(); - if ( myTabWidget->currentIndex() == BaseInfo || - myTabWidget->currentIndex() == AddInfo || - myTabWidget->currentIndex() == CtrlInfo ) { - SMESH::SetPointRepresentation( false ); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) - aViewWindow->SetSelectionMode( ActorSelection ); - } - else { - if ( myMode->checkedId() == NodeMode ) { - SMESH::SetPointRepresentation( true ); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) - aViewWindow->SetSelectionMode( NodeSelection ); - } - else { - SMESH::SetPointRepresentation( false ); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) - aViewWindow->SetSelectionMode( CellSelection ); - } - } + int selMode = ActorSelection; + if ( myTabWidget->currentIndex() == ElemInfo && myMode->checkedId() == NodeMode ) + selMode = NodeSelection; + else if ( myTabWidget->currentIndex() == ElemInfo && myMode->checkedId() == ElemMode ) + selMode = CellSelection; + SMESH::SetPointRepresentation( selMode == NodeSelection ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( selMode ); - QString oldID = myID->text().trimmed(); - SMESH_Actor* oldActor = myActor; + SMESH::SelectionProxy previous = myProxy; + QString ids = myID->text().trimmed(); myID->clear(); - connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() )); + connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) ); updateInfo(); - if ( oldActor == myActor && myActor && !oldID.isEmpty() ) { - myID->setText( oldID ); + if ( myProxy && myProxy == previous && !ids.isEmpty() ) { + myID->setText( ids ); idChanged(); } } /*! - \brief Show help page + \brief Show documentation on selected dialog page. */ void SMESHGUI_MeshInfoDlg::help() { - SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ? - "mesh_infos_page.html#advanced_mesh_infos_anchor" : - "mesh_infos_page.html#mesh_element_info_anchor" ); -} - -/*! - \brief Show mesh information -*/ -void SMESHGUI_MeshInfoDlg::updateInfo() -{ - SUIT_OverrideCursor wc; - - SALOME_ListIO selected; - SMESHGUI::selectionMgr()->selectedObjects( selected ); - - if ( selected.Extent() == 1 ) { - Handle(SALOME_InteractiveObject) IO = selected.First(); - showInfo( IO ); - } - else { - showInfo( myIO ); + QString helpPage = "mesh_infos.html"; + switch ( myTabWidget->currentIndex() ) + { + case BaseInfo: + helpPage += "#advanced-mesh-infos-anchor"; + break; + case ElemInfo: + helpPage += "#mesh-element-info-anchor"; + break; + case AddInfo: + helpPage += "#mesh-addition-info-anchor"; + break; + case CtrlInfo: + helpPage += "#mesh-quality-info-anchor"; + break; + default: + break; } + SMESH::ShowHelpFile( helpPage ); } /*! - \brief Activate dialog box -*/ -void SMESHGUI_MeshInfoDlg::activate() -{ - SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog(); - SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this ); - myTabWidget->setEnabled( true ); - updateSelection(); -} - -/*! - \brief Deactivate dialog box + \brief Deactivate dialog box. */ void SMESHGUI_MeshInfoDlg::deactivate() { - myTabWidget->setEnabled( false ); - disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() )); + disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) ); } /*! @@ -3162,6 +3309,7 @@ void SMESHGUI_MeshInfoDlg::deactivate() */ void SMESHGUI_MeshInfoDlg::modeChanged() { + emit( switchMode( myMode->checkedId() == GroupMode ? 1 : 0 ) ); myID->clear(); updateSelection(); } @@ -3173,46 +3321,48 @@ void SMESHGUI_MeshInfoDlg::idChanged() { myIDPreview->SetPointsLabeled( false ); - SVTK_Selector* selector = SMESH::GetSelector(); - if ( myActor && selector ) { - Handle(SALOME_InteractiveObject) IO = myActor->getIO(); + if ( myProxy ) { TColStd_MapOfInteger ID; - QSet ids; + QSet ids; std::vector idVec; std::list< gp_XYZ > aGrCentersXYZ; + SMESH::XYZ xyz; + const bool isElem = ( myMode->checkedId() == ElemMode ); QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts ); foreach ( QString tid, idTxt ) { - long id = tid.trimmed().toLong(); - const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ? - myActor->GetObject()->GetMesh()->FindElement( id ) : - myActor->GetObject()->GetMesh()->FindNode( id ); - if ( e ) { + long id = tid.toUInt(); + if ( isElem ? myProxy.hasElement( id ) : myProxy.hasNode( id )) + { ID.Add( id ); ids << id; - if ( myMode->checkedId() == ElemMode ) + if ( isElem && myProxy.actor() && myProxy.elementGravityCenter( id, xyz )) { idVec.push_back( id ); - aGrCentersXYZ.push_back( myElemInfo->getGravityCenter( e )); + aGrCentersXYZ.push_back( xyz ); } } } - selector->AddOrRemoveIndex( IO, ID, false ); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) { - - if ( myMode->checkedId() == NodeMode ) - myIDPreview->SetPointsData( myActor->GetObject()->GetMesh(), ID ); - else - myIDPreview->SetElemsData( idVec, aGrCentersXYZ ); - - bool showIDs = ( !ID.IsEmpty() && - myIDPreviewCheck->isChecked() && - myTabWidget->currentIndex() == ElemInfo ); - myIDPreview->SetPointsLabeled( showIDs, myActor->GetVisibility() ); - - aViewWindow->highlight( IO, true, true ); - aViewWindow->Repaint(); + SVTK_Selector* selector = SMESH::GetSelector(); + if ( myProxy.actor() && selector ) { + Handle(SALOME_InteractiveObject) IO = myProxy.actor()->getIO(); + selector->AddOrRemoveIndex( IO, ID, false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + { + if ( myMode->checkedId() == NodeMode ) + myIDPreview->SetPointsData( myProxy.actor()->GetObject()->GetMesh(), ID ); + else + myIDPreview->SetElemsData( idVec, aGrCentersXYZ ); + + bool showIDs = ( !ID.IsEmpty() && + myIDPreviewCheck->isChecked() && + myTabWidget->currentIndex() == ElemInfo ); + myIDPreview->SetPointsLabeled( showIDs, myProxy.actor()->GetVisibility() ); + + aViewWindow->highlight( IO, true, true ); + aViewWindow->Repaint(); + } } - myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode ); + myElemInfo->showInfo( myProxy, ids, isElem ); } } @@ -3222,151 +3372,112 @@ void SMESHGUI_MeshInfoDlg::idChanged() void SMESHGUI_MeshInfoDlg::idPreviewChange( bool isOn ) { myIDPreview->SetPointsLabeled( isOn && !myID->text().simplified().isEmpty() ); - SMESHGUI::resourceMgr()->setValue("SMESH", id_preview_resource, isOn ); + SMESHGUI::resourceMgr()->setValue("SMESH", "id_preview_resource", isOn ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) aViewWindow->Repaint(); } -void SMESHGUI_MeshInfoDlg::showItemInfo( int id ) -{ - if ( id > 0 && myActor->GetObject()->GetMesh()->FindNode( id )) { - myMode->button( NodeMode )->click(); - myID->setText( QString::number( id )); - } -} - -void SMESHGUI_MeshInfoDlg::showItemInfo( const QString& theStr ) +void SMESHGUI_MeshInfoDlg::showItemInfo( int type, const QString& ids ) { - if ( !theStr.isEmpty() ) { - myMode->button( ElemMode )->click(); - myID->setText( theStr ); + if ( !ids.isEmpty() && ( type == NodeConnectivity || type == ElemConnectivity )) { + myMode->button( type - NodeConnectivity )->click(); + myID->setText( ids ); } } +/*! + \brief Dump information to file. +*/ void SMESHGUI_MeshInfoDlg::dump() { - SUIT_Application* app = SUIT_Session::session()->activeApplication(); - if ( !app ) return; - SalomeApp_Study* appStudy = dynamic_cast( app->activeStudy() ); - if ( !appStudy ) return; - _PTR( Study ) aStudy = appStudy->studyDS(); - - QStringList aFilters; - aFilters.append( tr( "TEXT_FILES" )); - - bool anIsBase = true; - bool anIsElem = true; - bool anIsAdd = true; - bool anIsCtrl = true; - - if ( SUIT_ResourceMgr* aResourceMgr = SMESHGUI::resourceMgr() ) { - anIsBase = aResourceMgr->booleanValue( "SMESH", "info_dump_base", anIsBase ); - anIsElem = aResourceMgr->booleanValue( "SMESH", "info_dump_elem", anIsElem ); - anIsAdd = aResourceMgr->booleanValue( "SMESH", "info_dump_add", anIsAdd ); - anIsCtrl = aResourceMgr->booleanValue( "SMESH", "info_dump_ctrl", anIsCtrl ); - } - DumpFileDlg fd( this ); - fd.setWindowTitle( tr( "SAVE_INFO" )); - fd.setNameFilters( aFilters ); - fd.myBaseChk->setChecked( anIsBase ); - fd.myElemChk->setChecked( anIsElem ); - fd.myAddChk ->setChecked( anIsAdd ); - fd.myCtrlChk->setChecked( anIsCtrl ); + fd.setWindowTitle( tr( "SAVE_INFO" ) ); + fd.setNameFilters( QStringList() << tr( "TEXT_FILES" ) ); + fd.setChecked( BaseInfo, SMESHGUI::resourceMgr()->booleanValue( "SMESH", "info_dump_base", true ) ); + fd.setChecked( ElemInfo, SMESHGUI::resourceMgr()->booleanValue( "SMESH", "info_dump_elem", true ) ); + fd.setChecked( AddInfo, SMESHGUI::resourceMgr()->booleanValue( "SMESH", "info_dump_add", true ) ); + fd.setChecked( CtrlInfo, SMESHGUI::resourceMgr()->booleanValue( "SMESH", "info_dump_ctrl", true ) ); if ( fd.exec() == QDialog::Accepted ) { - QString aFileName = fd.selectedFile(); - - bool toBase = fd.myBaseChk->isChecked(); - bool toElem = fd.myElemChk->isChecked(); - bool toAdd = fd.myAddChk->isChecked(); - bool toCtrl = fd.myCtrlChk->isChecked(); - - if ( !aFileName.isEmpty() ) { - QFileInfo aFileInfo( aFileName ); - if ( aFileInfo.isDir() ) - return; - - QFile aFile( aFileName ); - if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text )) + QString fileName = fd.selectedFile(); + if ( !fileName.isEmpty() ) { + QFile file( fileName ); + if ( !file.open( QIODevice::WriteOnly | QIODevice::Text ) ) return; - - QTextStream out( &aFile ); - - if ( toBase ) myBaseInfo->saveInfo( out ); - if ( toElem ) myElemInfo->saveInfo( out ); - if ( toAdd ) myAddInfo ->saveInfo( out ); - if ( toCtrl ) myCtrlInfo->saveInfo( out ); + + QTextStream out( &file ); + if ( fd.isChecked( BaseInfo ) ) myBaseInfo->saveInfo( out ); + if ( fd.isChecked( ElemInfo ) ) myElemInfo->saveInfo( out ); + if ( fd.isChecked( AddInfo ) ) myAddInfo->saveInfo( out ); + if ( fd.isChecked( CtrlInfo ) ) myCtrlInfo->saveInfo( out ); } } } -/*! - \class SMESHGUI_CtrlInfo - \brief Class for the mesh controls information widget. -*/ +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_CtrlInfo +/// \brief Show quality statistics information on selected object. +/// +/// Displays quality controls statistics about selected object: mesh, sub-mesh, +/// group or arbitrary ID source. +//////////////////////////////////////////////////////////////////////////////// /*! - \brief Constructor - \param parent parent widget + \brief Constructor. + \param parent Parent widget. Defaults to 0. */ -SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent ) - : QFrame( parent ), myPlot( 0 ), myPlot3D( 0 ) +SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent ): SMESHGUI_Info( parent ) { - setFrameStyle( StyledPanel | Sunken ); + QGridLayout* l = new QGridLayout( this ); + l->setMargin( MARGIN ); + l->setSpacing( SPACING ); - myMainLayout = new QGridLayout( this ); - myMainLayout->setMargin( MARGIN ); - myMainLayout->setSpacing( SPACING ); + QIcon aComputeIcon( SUIT_Session::session()->resourceMgr()->loadPixmap( "SMESH", tr( "ICON_COMPUTE" ) ) ); + SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager(); // name - QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this ); - QLabel* aName = createField(); + QLabel* aNameLab = createLabel( tr( "NAME_LAB" ), this, Bold ); + QLabel* aName = createField( this, "ctrlName" ); aName->setMinimumWidth( 150 ); myWidgets << aName; - SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); - QIcon aComputeIcon( aResMgr->loadPixmap( "SMESH", tr( "ICON_COMPUTE" )) ); - - SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager(); - // nodes info - QLabel* aNodesLab = new QLabel( tr( "NODES_INFO" ), this ); + QLabel* aNodesLab = createLabel( tr( "NODES_INFO" ), this, Bold ); QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this ); - QLabel* aNodesFree = createField(); + QLabel* aNodesFree = createField( this, "ctrlNodesFree" ); myWidgets << aNodesFree; myPredicates << aFilterMgr->CreateFreeNodes(); // QLabel* aNodesNbConnLab = new QLabel( tr( "MAX_NODE_CONNECTIVITY" ), this ); - QLabel* aNodesNbConn = createField(); + QLabel* aNodesNbConn = createField( this, "ctrlNodesCnty" ); myWidgets << aNodesNbConn; myNodeConnFunctor = aFilterMgr->CreateNodeConnectivityNumber(); // QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this ); - QLabel* aNodesDouble = createField(); + QLabel* aNodesDouble = createField( this, "ctrlNodesDouble" ); myWidgets << aNodesDouble; myPredicates << aFilterMgr->CreateEqualNodes(); QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this ); myToleranceWidget = new SMESHGUI_SpinBox( this ); myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" ); myToleranceWidget->setAcceptNames( false ); - myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 )); + myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ) ); // edges info - QLabel* anEdgesLab = new QLabel( tr( "EDGES_INFO" ), this ); + QLabel* anEdgesLab = createLabel( tr( "EDGES_INFO" ), this, Bold ); QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this ); - QLabel* anEdgesDouble = createField(); + QLabel* anEdgesDouble = createField( this, "ctrlEdgesDouble" ); myWidgets << anEdgesDouble; myPredicates << aFilterMgr->CreateEqualEdges(); // faces info - QLabel* aFacesLab = new QLabel( tr( "FACES_INFO" ), this ); + QLabel* aFacesLab = createLabel( tr( "FACES_INFO" ), this, Bold ); QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this ); - QLabel* aFacesDouble = createField(); + QLabel* aFacesDouble = createField( this, "ctrlFacesDouble" ); myWidgets << aFacesDouble; myPredicates << aFilterMgr->CreateEqualFaces(); QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this ); - QLabel* aFacesOver = createField(); + QLabel* aFacesOver = createField( this, "ctrlFacesOver" ); myWidgets << aFacesOver; myPredicates << aFilterMgr->CreateOverConstrainedFace(); QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this ); @@ -3374,13 +3485,13 @@ SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent ) myAspectRatio = aFilterMgr->CreateAspectRatio(); // volumes info - QLabel* aVolumesLab = new QLabel( tr( "VOLUMES_INFO" ), this ); + QLabel* aVolumesLab = createLabel( tr( "VOLUMES_INFO" ), this, Bold ); QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this ); - QLabel* aVolumesDouble = createField(); + QLabel* aVolumesDouble = createField( this, "ctrlVolumesDouble" ); myWidgets << aVolumesDouble; myPredicates << aFilterMgr->CreateEqualVolumes(); QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this ); - QLabel* aVolumesOver = createField(); + QLabel* aVolumesOver = createField( this, "ctrlVolumesOver" ); myWidgets << aVolumesOver; myPredicates << aFilterMgr->CreateOverConstrainedVolume(); QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this ); @@ -3427,112 +3538,77 @@ SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent ) aComputeVolumeBtn->setIcon(aComputeIcon); myButtons << aComputeVolumeBtn; //9 - connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() )); - connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() )); - connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() )); - connect( aNodesNbConnBtn, SIGNAL( clicked() ), this, SLOT( computeNodesNbConnInfo() )); - connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() )); - connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() )); - connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() )); - connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() )); - connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() )); - connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() )); - connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double ))); - - setFontAttributes( aNameLab ); - setFontAttributes( aNodesLab ); - setFontAttributes( anEdgesLab ); - setFontAttributes( aFacesLab ); - setFontAttributes( aVolumesLab ); - - myMainLayout->addWidget( aNameLab, 0, 0 ); //0 - myMainLayout->addWidget( aName, 0, 1, 1, 2 ); //1 - myMainLayout->addWidget( aNodesLab, 1, 0, 1, 3 ); //2 - myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3 - myMainLayout->addWidget( aNodesFree, 2, 1 ); //4 - myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5 - myMainLayout->addWidget( aNodesNbConnLab, 3, 0 ); //6 - myMainLayout->addWidget( aNodesNbConn, 3, 1 ); //7 - myMainLayout->addWidget( aNodesNbConnBtn, 3, 2 ); //8 - myMainLayout->addWidget( aNodesDoubleLab, 4, 0 ); //9 - myMainLayout->addWidget( aNodesDouble, 4, 1 ); //10 - myMainLayout->addWidget( aDoubleNodesBtn, 4, 2 ); //11 - myMainLayout->addWidget( aToleranceLab, 5, 0 ); //12 - myMainLayout->addWidget( myToleranceWidget, 5, 1 ); //13 - myMainLayout->addWidget( anEdgesLab, 6, 0, 1, 3 ); //14 - myMainLayout->addWidget( anEdgesDoubleLab, 7, 0 ); //15 - myMainLayout->addWidget( anEdgesDouble, 7, 1 ); //16 - myMainLayout->addWidget( aDoubleEdgesBtn, 7, 2 ); //17 - myMainLayout->addWidget( aFacesLab, 8, 0, 1, 3 ); //18 - myMainLayout->addWidget( aFacesDoubleLab, 9, 0 ); //19 - myMainLayout->addWidget( aFacesDouble, 9, 1 ); //20 - myMainLayout->addWidget( aDoubleFacesBtn, 9, 2 ); //21 - myMainLayout->addWidget( aFacesOverLab, 10, 0 ); //22 - myMainLayout->addWidget( aFacesOver, 10, 1 ); //23 - myMainLayout->addWidget( aOverContFacesBtn, 10, 2 ); //24 - myMainLayout->addWidget( anAspectRatioLab, 11, 0 ); //25 - myMainLayout->addWidget( aComputeFaceBtn, 11, 2 ); //26 - myMainLayout->addWidget( myPlot, 12, 0, 1, 3 );//27 - myMainLayout->addWidget( aVolumesLab, 13, 0, 1, 3 );//28 - myMainLayout->addWidget( aVolumesDoubleLab, 14, 0 ); //29 - myMainLayout->addWidget( aVolumesDouble, 14, 1 ); //30 - myMainLayout->addWidget( aDoubleVolumesBtn, 14, 2 ); //31 - myMainLayout->addWidget( aVolumesOverLab, 15, 0 ); //32 - myMainLayout->addWidget( aVolumesOver, 15, 1 ); //33 - myMainLayout->addWidget( aOverContVolumesBtn,15, 2 ); //34 - myMainLayout->addWidget( anAspectRatio3DLab, 16, 0 ); //35 - myMainLayout->addWidget( aComputeVolumeBtn, 16, 2 ); //36 - myMainLayout->addWidget( myPlot3D, 17, 0, 1, 3 );//37 + connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ) ); + connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ) ); + connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) ); + connect( aNodesNbConnBtn, SIGNAL( clicked() ), this, SLOT( computeNodesNbConnInfo() ) ); + connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ) ); + connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ) ); + connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ) ); + connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ) ); + connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ) ); + connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) ); + connect( myToleranceWidget, SIGNAL( valueChanged( double ) ), this, SLOT( setTolerance( double ) ) ); + + l->addWidget( aNameLab, 0, 0 ); //0 + l->addWidget( aName, 0, 1, 1, 2 ); //1 + l->addWidget( aNodesLab, 1, 0, 1, 3 ); //2 + l->addWidget( aNodesFreeLab, 2, 0 ); //3 + l->addWidget( aNodesFree, 2, 1 ); //4 + l->addWidget( aFreeNodesBtn, 2, 2 ); //5 + l->addWidget( aNodesNbConnLab, 3, 0 ); //6 + l->addWidget( aNodesNbConn, 3, 1 ); //7 + l->addWidget( aNodesNbConnBtn, 3, 2 ); //8 + l->addWidget( aNodesDoubleLab, 4, 0 ); //9 + l->addWidget( aNodesDouble, 4, 1 ); //10 + l->addWidget( aDoubleNodesBtn, 4, 2 ); //11 + l->addWidget( aToleranceLab, 5, 0 ); //12 + l->addWidget( myToleranceWidget, 5, 1 ); //13 + l->addWidget( anEdgesLab, 6, 0, 1, 3 ); //14 + l->addWidget( anEdgesDoubleLab, 7, 0 ); //15 + l->addWidget( anEdgesDouble, 7, 1 ); //16 + l->addWidget( aDoubleEdgesBtn, 7, 2 ); //17 + l->addWidget( aFacesLab, 8, 0, 1, 3 ); //18 + l->addWidget( aFacesDoubleLab, 9, 0 ); //19 + l->addWidget( aFacesDouble, 9, 1 ); //20 + l->addWidget( aDoubleFacesBtn, 9, 2 ); //21 + l->addWidget( aFacesOverLab, 10, 0 ); //22 + l->addWidget( aFacesOver, 10, 1 ); //23 + l->addWidget( aOverContFacesBtn, 10, 2 ); //24 + l->addWidget( anAspectRatioLab, 11, 0 ); //25 + l->addWidget( aComputeFaceBtn, 11, 2 ); //26 + l->addWidget( myPlot, 12, 0, 1, 3 );//27 + l->addWidget( aVolumesLab, 13, 0, 1, 3 );//28 + l->addWidget( aVolumesDoubleLab, 14, 0 ); //29 + l->addWidget( aVolumesDouble, 14, 1 ); //30 + l->addWidget( aDoubleVolumesBtn, 14, 2 ); //31 + l->addWidget( aVolumesOverLab, 15, 0 ); //32 + l->addWidget( aVolumesOver, 15, 1 ); //33 + l->addWidget( aOverContVolumesBtn,15, 2 ); //34 + l->addWidget( anAspectRatio3DLab, 16, 0 ); //35 + l->addWidget( aComputeVolumeBtn, 16, 2 ); //36 + l->addWidget( myPlot3D, 17, 0, 1, 3 );//37 - myMainLayout->setColumnStretch( 0, 0 ); - myMainLayout->setColumnStretch( 1, 5 ); - myMainLayout->setRowStretch ( 11, 5 ); - myMainLayout->setRowStretch ( 16, 5 ); - myMainLayout->setRowStretch ( 17, 1 ); + l->setColumnStretch( 0, 0 ); + l->setColumnStretch( 1, 5 ); + l->setRowStretch ( 12, 5 ); + l->setRowStretch ( 17, 5 ); + l->setRowStretch ( 18, 1 ); clearInternal(); } /*! - \brief Destructor + \brief Destructor. */ SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo() -{} - -/*! - \brief Change widget font attributes (bold, ...). - \param w widget - \param attr font attributes (XORed flags) -*/ -void SMESHGUI_CtrlInfo::setFontAttributes( QWidget* w ) -{ - if ( w ) { - QFont f = w->font(); - f.setBold( true ); - w->setFont( f ); - } -} - -/*! - \brief Create info field - \return new info field -*/ -QLabel* SMESHGUI_CtrlInfo::createField() { - QLabel* lab = new QLabel( this ); - lab->setFrameStyle( StyledPanel | Sunken ); - lab->setAlignment( Qt::AlignCenter ); - lab->setAutoFillBackground( true ); - QPalette pal = lab->palette(); - pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base )); - lab->setPalette( pal ); - lab->setMinimumWidth( 60 ); - return lab; } /*! - \brief Create QwtPlot - \return new QwtPlot + \brief Create plot widget. + \param parent Parent widget. + \return New plot widget. */ QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent ) { @@ -3549,17 +3625,20 @@ QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent ) } /*! - \brief Show controls information on the selected object + \brief Show information on given object. + \param proxy Object to show information on (mesh, sub-mesh, group, ID source). */ -void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) +void SMESHGUI_CtrlInfo::showInfo( const SMESH::SelectionProxy& proxy ) { clearInternal(); - myObject = SMESH::SMESH_IDSource::_duplicate( obj ); - if ( myObject->_is_nil() ) return; + if ( !proxy ) + return; - if ( _PTR(SObject) aSO = SMESH::FindSObject( obj )) - myWidgets[0]->setText( aSO->GetName().c_str() ); + myProxy = proxy; + SMESH::SMESH_IDSource_var obj = proxy.object(); + + myWidgets[0]->setText( proxy.name() ); SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); if ( mesh->_is_nil() ) return; @@ -3578,17 +3657,17 @@ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) // nodes info const CORBA::Long nbNodes = nbElemsByType[ SMESH::NODE ]; - const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] + - nbElemsByType[ SMESH::FACE ] + - nbElemsByType[ SMESH::VOLUME ] ); - if ( nbNodes + nbElems > 0 ) { - if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) { + // const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] + + // nbElemsByType[ SMESH::FACE ] + + // nbElemsByType[ SMESH::VOLUME ] ); + if ( nbNodes > 0 ) { + if ( nbNodes <= ctrlLimit ) { // free nodes computeFreeNodesInfo(); + // node connectivity number computeNodesNbConnInfo(); // double nodes - if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit ) - computeDoubleNodesInfo(); + computeDoubleNodesInfo(); } else { myButtons[0]->setEnabled( true ); @@ -3597,8 +3676,8 @@ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) } } else { - for( int i=2; i<=11; i++) - myMainLayout->itemAt(i)->widget()->setVisible( false ); + for( int i=2; i<=13; i++) + dynamic_cast(layout())->itemAt(i)->widget()->setVisible( false ); } // edges info @@ -3610,10 +3689,10 @@ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) myButtons[3]->setEnabled( true ); } else { - for( int i=11; i<=14; i++) - myMainLayout->itemAt(i)->widget()->setVisible( false ); + for( int i=14; i<=17; i++) + dynamic_cast(layout())->itemAt(i)->widget()->setVisible( false ); } - + // faces info if ( nbElemsByType[ SMESH::FACE ] > 0 ) { if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) { @@ -3630,15 +3709,13 @@ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) myButtons[6]->setEnabled( true ); } #ifdef DISABLE_PLOT2DVIEWER - myMainLayout->setRowStretch(12,0); for( int i=25; i<=27; i++) - myMainLayout->itemAt(i)->widget()->setVisible( false ); + dynamic_cast(layout())->itemAt(i)->widget()->setVisible( false ); #endif } else { - myMainLayout->setRowStretch(12,0); for( int i=18; i<=27; i++) - myMainLayout->itemAt(i)->widget()->setVisible( false ); + dynamic_cast(layout())->itemAt(i)->widget()->setVisible( false ); } // volumes info @@ -3657,15 +3734,13 @@ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) myButtons[9]->setEnabled( true ); } #ifdef DISABLE_PLOT2DVIEWER - myMainLayout->setRowStretch(17,0); for( int i=35; i<=37; i++) - myMainLayout->itemAt(i)->widget()->setVisible( false ); + dynamic_cast(layout())->itemAt(i)->widget()->setVisible( false ); #endif } else { - myMainLayout->setRowStretch(17,0); for( int i=28; i<=37; i++) - myMainLayout->itemAt(i)->widget()->setVisible( false ); + dynamic_cast(layout())->itemAt(i)->widget()->setVisible( false ); } } @@ -3682,15 +3757,19 @@ void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg ) { myButtons[ iBut ]->setEnabled( false ); myWidgets[ iWdg ]->setText( "" ); - if ( myObject->_is_nil() ) return; + + if ( !myProxy ) + return; SUIT_OverrideCursor wc; - SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + SMESH::SMESH_IDSource_var obj = myProxy.object(); + SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); + if ( !mesh->_is_nil() && !mesh->IsLoaded() ) { mesh->Load(); - this->showInfo( myObject ); // try to show all values + showInfo( myProxy ); // try to show all values if ( !myWidgets[ iWdg ]->text().isEmpty() ) return; // predicate already computed } @@ -3698,8 +3777,8 @@ void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg ) for ( int i = 0; i < myPredicates.count(); ++i ) if ( myPredicates[i]->GetFunctorType() == ft ) { - CORBA::Long nb = myPredicates[i]->NbSatisfying( myObject ); - myWidgets[ iWdg ]->setText( QString::number( nb )); + CORBA::Long nb = myPredicates[i]->NbSatisfying( obj ); + myWidgets[ iWdg ]->setText( QString::number( nb ) ); } } @@ -3742,20 +3821,27 @@ void SMESHGUI_CtrlInfo::computeNodesNbConnInfo() { myButtons[ 1 ]->setEnabled( false ); myWidgets[ 2 ]->setText( "" ); - SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); - if ( mesh->_is_nil() ) return; + + if ( !myProxy ) + return; + + SUIT_OverrideCursor wc; + + SMESH::SMESH_IDSource_var obj = myProxy.object(); + SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); + if ( !mesh->IsLoaded() ) { mesh->Load(); - this->showInfo( myObject ); // try to show all values + showInfo( myProxy ); // try to show all values if ( !myWidgets[ 2 ]->text().isEmpty() ) return; // already computed } myNodeConnFunctor->SetMesh( mesh ); SMESH::Histogram_var histogram = - myNodeConnFunctor->GetLocalHistogram( 1, /*isLogarithmic=*/false, myObject ); + myNodeConnFunctor->GetLocalHistogram( 1, /*isLogarithmic=*/false, obj ); - myWidgets[ 2 ]->setText( QString::number( histogram[0].max )); + myWidgets[ 2 ]->setText( QString::number( histogram[0].max ) ); } void SMESHGUI_CtrlInfo::computeAspectRatio() @@ -3763,10 +3849,14 @@ void SMESHGUI_CtrlInfo::computeAspectRatio() #ifndef DISABLE_PLOT2DVIEWER myButtons[6]->setEnabled( false ); - if ( myObject->_is_nil() ) return; + if ( !myProxy ) + return; SUIT_OverrideCursor wc; + SMESH::SMESH_IDSource_var obj = myProxy.object(); + SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); + Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio ); if ( aHistogram && !aHistogram->isEmpty() ) { QwtPlotItem* anItem = aHistogram->createPlotItem(); @@ -3782,10 +3872,14 @@ void SMESHGUI_CtrlInfo::computeAspectRatio3D() #ifndef DISABLE_PLOT2DVIEWER myButtons[9]->setEnabled( false ); - if ( myObject->_is_nil() ) return; + if ( !myProxy ) + return; SUIT_OverrideCursor wc; + SMESH::SMESH_IDSource_var obj = myProxy.object(); + SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); + Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D ); if ( aHistogram && !aHistogram->isEmpty() ) { QwtPlotItem* anItem = aHistogram->createPlotItem(); @@ -3801,8 +3895,8 @@ void SMESHGUI_CtrlInfo::computeAspectRatio3D() */ void SMESHGUI_CtrlInfo::clearInternal() { - for( int i=0; i<=35; i++) - myMainLayout->itemAt(i)->widget()->setVisible( true ); + for( int i=0; i<=37; i++) + dynamic_cast(layout())->itemAt(i)->widget()->setVisible( true ); for( int i=0; i<=9; i++) myButtons[i]->setEnabled( false ); myPlot->detachItems(); @@ -3812,8 +3906,6 @@ void SMESHGUI_CtrlInfo::clearInternal() myWidgets[0]->setText( QString() ); for ( int i = 1; i < myWidgets.count(); i++ ) myWidgets[i]->setText( "" ); - myMainLayout->setRowStretch(11,5); - myMainLayout->setRowStretch(16,5); } void SMESHGUI_CtrlInfo::setTolerance( double theTolerance ) @@ -3826,14 +3918,17 @@ void SMESHGUI_CtrlInfo::setTolerance( double theTolerance ) #ifndef DISABLE_PLOT2DVIEWER Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun ) { - SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); - if ( mesh->_is_nil() ) return 0; + SUIT_OverrideCursor wc; + + SMESH::SMESH_IDSource_var obj = myProxy.object(); + SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); + if ( !mesh->IsLoaded() ) mesh->Load(); aNumFun->SetMesh( mesh ); CORBA::Long cprecision = 6; - if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false )) + if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) ) cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 ); aNumFun->SetPrecision( cprecision ); @@ -3841,9 +3936,9 @@ Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr a SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals, /*isLogarithmic=*/false, - myObject ); + obj ); Plot2d_Histogram* aHistogram = new Plot2d_Histogram(); - aHistogram->setColor( palette().color( QPalette::Highlight )); + aHistogram->setColor( palette().color( QPalette::Highlight ) ); if ( &histogramVar.in() ) { for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ ) @@ -3855,28 +3950,35 @@ Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr a } #endif -void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) { - out << QString( 20, '-' ) << "\n"; - out << tr( "CTRL_INFO" ) << "\n"; - out << QString( 20, '-' ) << "\n"; - out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << "\n"; - out << tr( "NODES_INFO" ) << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << "\n"; - out << tr( "EDGES_INFO" ) << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << "\n"; - out << tr( "FACES_INFO" ) << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << "\n"; - out << tr( "VOLUMES_INFO" ) << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << "\n"; - out << QString( SPACING_INFO, ' ' ) << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << "\n"; +void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) +{ + // title + QString title = tr( "CTRL_INFO" ); + out << ruler( title.size() ) << endl; + out << title << endl; + out << ruler( title.size() ) << endl; + out << endl; + + // info + out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << endl; + out << tr( "NODES_INFO" ) << endl; + out << indent() << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << endl; + out << indent() << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[2]->text() << endl; + out << tr( "EDGES_INFO" ) << endl; + out << indent() << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[3]->text() << endl; + out << tr( "FACES_INFO" ) << endl; + out << indent() << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[4]->text() << endl; + out << indent() << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[5]->text() << endl; + out << tr( "VOLUMES_INFO" ) << endl; + out << indent() << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[6]->text() << endl; + out << indent() << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[7]->text() << endl; } -/*! - \class SMESHGUI_CtrlInfoDlg - \brief Controls information dialog box -*/ +//////////////////////////////////////////////////////////////////////////////// +/// \class SMESHGUI_CtrlInfoDlg +/// \brief Overall Mesh Quality dialog. +/// \todo Add selection button to reactivate selection on move from other dlg. +//////////////////////////////////////////////////////////////////////////////// /*! \brief Constructor @@ -3886,7 +3988,7 @@ SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent ) : QDialog( parent ) { setAttribute( Qt::WA_DeleteOnClose, true ); - setWindowTitle( tr( "CTRL_INFO" )); + setWindowTitle( tr( "CTRL_INFO" ) ); setMinimumSize( 400, 600 ); myCtrlInfo = new SMESHGUI_CtrlInfo( this ); @@ -3911,16 +4013,16 @@ SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent ) btnLayout->addWidget( helpBtn ); QVBoxLayout* l = new QVBoxLayout ( this ); - l->setMargin( MARGIN ); + l->setMargin( 0 ); l->setSpacing( SPACING ); l->addWidget( myCtrlInfo ); l->addLayout( btnLayout ); - connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() )); - connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() )); - connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() )); - connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() )); - connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() )); + connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) ); + connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) ); updateSelection(); } @@ -3933,34 +4035,28 @@ SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg() } /*! - \brief Show controls information - \param IO interactive object + \brief Show mesh quality information on given object. + \param io Interactive object. */ -void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO ) +void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& io ) { - if ( SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO )) - myCtrlInfo->showInfo( obj ); + if ( !io.IsNull() ) + showInfo( SMESH::SelectionProxy( io ) ); } /*! - \brief Perform clean-up actions on the dialog box closing. + \brief Show mesh quality information on given object. + \param proxy Selection proxy. */ -void SMESHGUI_CtrlInfoDlg::reject() +void SMESHGUI_CtrlInfoDlg::showInfo( const SMESH::SelectionProxy& proxy ) { - SMESH::SetPointRepresentation( false ); - QDialog::reject(); -} + SUIT_OverrideCursor wc; -/*! - \brief Setup selection mode depending on the current dialog box state. -*/ -void SMESHGUI_CtrlInfoDlg::updateSelection() -{ - LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr(); - disconnect( selMgr, 0, this, 0 ); - SMESH::SetPointRepresentation( false ); - connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() )); - updateInfo(); + if ( !proxy ) + return; + + myProxy = proxy; + myCtrlInfo->showInfo( proxy ); } /*! @@ -3968,78 +4064,70 @@ void SMESHGUI_CtrlInfoDlg::updateSelection() */ void SMESHGUI_CtrlInfoDlg::updateInfo() { - SUIT_OverrideCursor wc; - SALOME_ListIO selected; SMESHGUI::selectionMgr()->selectedObjects( selected ); - if ( selected.Extent() == 1 ) { - Handle(SALOME_InteractiveObject) IO = selected.First(); - showInfo( IO ); - } + if ( selected.Extent() == 1 ) + showInfo( selected.First() ); + else + showInfo( myProxy ); } /*! - \brief Activate dialog box + \brief Perform clean-up actions on the dialog box closing. */ -void SMESHGUI_CtrlInfoDlg::activate() +void SMESHGUI_CtrlInfoDlg::reject() { - SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog(); - SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this ); - updateSelection(); + SMESH::SetPointRepresentation( false ); + QDialog::reject(); +} + +/*! + \brief Setup selection mode depending on the current dialog box state. +*/ +void SMESHGUI_CtrlInfoDlg::updateSelection() +{ + LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr(); + disconnect( selMgr, 0, this, 0 ); + SMESH::SetPointRepresentation( false ); + connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) ); + updateInfo(); } /*! - \brief Deactivate dialog box + \brief Deactivate dialog box. */ void SMESHGUI_CtrlInfoDlg::deactivate() { - disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() )); + disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) ); } /*! - * \brief Dump contents into a file - */ + \brief Dump information to file. +*/ void SMESHGUI_CtrlInfoDlg::dump() { - SUIT_Application* app = SUIT_Session::session()->activeApplication(); - if ( !app ) return; - SalomeApp_Study* appStudy = dynamic_cast( app->activeStudy() ); - if ( !appStudy ) return; - _PTR( Study ) aStudy = appStudy->studyDS(); - - QStringList aFilters; - aFilters.append( tr( "TEXT_FILES" )); - - DumpFileDlg fd( this ); - fd.setWindowTitle( tr( "SAVE_INFO" )); - fd.setNameFilters( aFilters ); - fd.myBaseChk->hide(); - fd.myElemChk->hide(); - fd.myAddChk ->hide(); - fd.myCtrlChk->hide(); + DumpFileDlg fd( this, false ); + fd.setWindowTitle( tr( "SAVE_INFO" ) ); + fd.setNameFilters( QStringList() << tr( "TEXT_FILES" ) ); if ( fd.exec() == QDialog::Accepted ) { - QString aFileName = fd.selectedFile(); - if ( !aFileName.isEmpty() ) { - QFileInfo aFileInfo( aFileName ); - if ( aFileInfo.isDir() ) - return; - - QFile aFile( aFileName ); - if ( !aFile.open( QIODevice::WriteOnly | QIODevice::Text )) + QString fileName = fd.selectedFile(); + if ( !fileName.isEmpty() ) { + QFile file( fileName ); + if ( !file.open( QIODevice::WriteOnly | QIODevice::Text ) ) return; - - QTextStream out( &aFile ); + + QTextStream out( &file ); myCtrlInfo->saveInfo( out ); } } } /*! - * \brief Show help - */ + \brief Show documentation on dialog. +*/ void SMESHGUI_CtrlInfoDlg::help() { - SMESH::ShowHelpFile("mesh_infos_page.html#mesh_quality_info_anchor"); + SMESH::ShowHelpFile( "mesh_infos.html#mesh-quality-info-anchor" ); }