1 // Copyright (C) 2007-2023 CEA, EDF, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "SMESHGUI_MeshInfo.h"
25 #include "SMDS_Mesh.hxx"
26 #include "SMESH_Actor.h"
28 #include "SMESHGUI_FilterUtils.h"
29 #include "SMESHGUI_IdPreview.h"
30 #include "SMESHGUI_IdValidator.h"
31 #include "SMESHGUI_SpinBox.h"
32 #include "SMESHGUI_Utils.h"
33 #include "SMESHGUI_VTKUtils.h"
35 #include <SUIT_FileDlg.h>
36 #include <SUIT_OverrideCursor.h>
37 #include <SUIT_ResourceMgr.h>
38 #include <SUIT_Session.h>
39 #include <SVTK_ViewWindow.h>
40 #include <LightApp_SelectionMgr.h>
42 #include <SALOMEDSClient_Study.hxx>
44 #include <QApplication>
45 #include <QButtonGroup>
48 #include <QContextMenuEvent>
49 #include <QGridLayout>
50 #include <QHBoxLayout>
51 #include <QHeaderView>
52 #include <QItemDelegate>
57 #include <QPushButton>
58 #include <QRadioButton>
59 #include <QStackedWidget>
60 #include <QStandardItemModel>
62 #include <QTextBrowser>
63 #include <QTextStream>
64 #include <QToolButton>
65 #include <QTreeWidget>
66 #include <QVBoxLayout>
68 ////////////////////////////////////////////////////////////////////////////////
70 /// \brief FieldInfo widget.
72 ////////////////////////////////////////////////////////////////////////////////
74 class FieldInfo : public QLabel
77 FieldInfo( QWidget*, const QString& = QString() );
78 bool event( QEvent* );
83 \param parent Parent widget.
84 \param name FieldInfo name. Defaults to null string.
86 FieldInfo::FieldInfo( QWidget* parent, const QString& name ): QLabel( parent )
88 setFrameStyle( QLabel::StyledPanel | QLabel::Sunken );
89 setAlignment( Qt::AlignCenter );
90 setAutoFillBackground( true );
91 QPalette pal = palette();
92 QColor base = QApplication::palette().color( QPalette::Active, QPalette::Base );
93 pal.setColor( QPalette::Window, base );
95 setMinimumWidth( 60 );
96 if ( !name.isEmpty() )
97 setObjectName( name );
101 \brief Event handler. Redefined from QLabel.
103 bool FieldInfo::event( QEvent* e )
105 if ( e->type() == QEvent::DynamicPropertyChange )
107 QDynamicPropertyChangeEvent* ce = (QDynamicPropertyChangeEvent*)e;
108 if ( ce->propertyName() == "value" && property( "value" ).isValid() )
110 setText( QString::number( property( "value" ).toInt() ) );
111 setProperty( "value", QVariant() );
115 return QLabel::event( e );
118 ////////////////////////////////////////////////////////////////////////////////
119 /// \class TreeItemCreator
120 /// \brief Generic tree item creator.
122 ////////////////////////////////////////////////////////////////////////////////
124 class TreeItemCreator
128 virtual ~TreeItemCreator() {}
129 virtual QTreeWidgetItem* createItem( QTreeWidgetItem*, int ) = 0;
132 ////////////////////////////////////////////////////////////////////////////////
133 // General purpose services.
134 ////////////////////////////////////////////////////////////////////////////////
138 const int SPACING = 6;
139 const int MARGIN = 9;
158 TypeRole = Qt::UserRole + 10,
164 NodeConnectivity = 100,
169 \brief Get item's depth in the tree.
170 \param item Tree widget item.
171 \return Item's depth in the tree widget (top-level item has zero depth).
174 int itemDepth( QTreeWidgetItem* item )
176 QList<QTreeWidgetItem*> parents;
178 while ( parents.last()->parent() )
179 parents << parents.last()->parent();
180 return parents.size()-1;
184 \brief Get chunk size.
195 \return Spacer string.
201 static QChar spacer = ' ';
202 return QString( size, spacer );
207 \param length Indent size. Defaults to 1.
208 \return Indentation string.
211 QString indent( int length = 1 )
214 static QChar spacer = ' ';
215 return QString( size * length, spacer );
220 \param spacer Spacer.
221 \param length Indent size. Defaults to 1.
222 \return Indentation string.
225 QString indent( const QString& spacer, uint length = 1 )
228 while( length-- > 0 )
234 \brief Get group separator.
235 \param length Length of ruler (number of symbols). Defaults to 80.
236 \return Ruler string.
239 QString ruler( int length = 80 )
241 static QChar ruler = '-';
242 return QString( length, ruler );
246 \brief Get text value from label.
247 \param w Widget (QLabel).
248 \return Value string.
251 QString widgetValue( QWidget* w )
254 if ( qobject_cast<QLabel*>( w ) )
255 v = qobject_cast<QLabel*>( w )->text();
260 \brief Get font for given options.
261 \param font Initial font.
262 \param options Font attributes.
265 QFont fontFromOptions( const QFont& font, int options )
268 f.setBold( options & Bold );
269 f.setItalic( options & Italic );
274 \brief Set font attributes to given widget.
276 \param options Font attributes.
278 void setFontAttributes( QWidget* w, int options )
281 w->setFont( fontFromOptions( w->font(), options ) );
285 \brief Set attributes to given tree item.
286 \param item Tree widget item.
287 \param options Item attributes.
289 void setTreeItemAttributes( QTreeWidgetItem* item, int options )
291 if ( item && item->treeWidget() )
293 for ( int i = 0; i < item->treeWidget()->columnCount(); i++ )
295 if ( i == 0 || options & AllColumns )
296 item->setFont( i, fontFromOptions( item->font( 0 ), options) );
299 if ( options & Expanded )
300 item->setExpanded( true );
301 if ( options & Editable )
302 item->setFlags( item->flags() | Qt::ItemIsEditable );
307 \param parent Parent widget.
308 \param options Label options. Defaults to 0 (none).
311 QLabel* createLabel( QWidget* parent, int options = 0 )
313 QLabel* lab = new QLabel( parent );
314 setFontAttributes( lab, options );
320 \param text Label text.
321 \param parent Parent widget.
322 \param options Label options. Defaults to 0 (none).
325 QLabel* createLabel( const QString& text, QWidget* parent, int options = 0 )
327 QLabel* lab = createLabel( parent, options );
328 lab->setText( text );
333 \brief Create information field.
334 \param parent Parent widget.
335 \param name FieldInfo's object. Default to null string.
336 \return New FieldInfo.
338 QLabel* createField( QWidget* parent, const QString& name = QString() )
340 return new FieldInfo( parent, name );
344 \brief Create information field.
345 \param parent Parent widget.
346 \param options Label options.
347 \param name Field's object. Default to null string.
350 QLabel* createField( QWidget* parent, int options, const QString& name = QString() )
352 QLabel* field = createField( parent, name );
353 setFontAttributes( field, options );
359 \param parent Parent widget.
360 \param orientation Ruler orientation. Defaults to horizontal.
363 QWidget* createSeparator( QWidget* parent, Qt::Orientation orientation = Qt::Horizontal )
365 QFrame* line = new QFrame( parent );
366 line->setFrameShape( orientation == Qt::Horizontal ? QFrame::HLine : QFrame::HLine );
367 line->setFrameShadow( QFrame::Sunken );
372 \brief Decorate text as bold.
373 \param text Initial text.
374 \return Decorated text.
376 QString bold( const QString& text )
378 return QString("<b>%1</b>").arg( text );
382 \brief Format connectivity data to string representation.
383 \param connectivity Connectivity map.
384 \param type Element type or face index if negative
385 \return Stringified representation of the connectivity.
387 QString formatConnectivity( SMESH::Connectivity connectivity, int type )
391 bool isNodal = ( type == SMDSAbs_Node || type < 0 );
393 if ( connectivity.contains( type ))
395 QList<int> elements = connectivity[ type ];
396 if ( !isNodal ) // order of nodes is important
398 foreach( int id, elements )
399 str << QString::number( id );
401 // wrap IDs into an html link, to be treated by QTextBrowser used by SMESHGUI_SimpleElemInfo
402 QString s = str.join( " " );
403 result = ( "<a href = \"" + // URL:
404 QString( isNodal ? "nodes" : "elems" ) + "://" + // protocol
405 QString( "host.com/") + // QUrl return nothing if host missing
407 s + "</a>" ); // anchor text
411 } // end of anonymous namespace
413 ////////////////////////////////////////////////////////////////////////////////
414 /// \class SMESHGUI_Info
415 /// \brief Base widget for all information panes.
416 ////////////////////////////////////////////////////////////////////////////////
420 \param parent Parent widget. Defaults to 0.
422 SMESHGUI_Info::SMESHGUI_Info( QWidget* parent ): QWidget( parent )
426 ////////////////////////////////////////////////////////////////////////////////
427 /// \class ExtraWidget
428 /// \brief Auxiliary widget to browse between chunks of information.
430 ////////////////////////////////////////////////////////////////////////////////
432 class ExtraWidget : public QWidget
435 ExtraWidget( QWidget*, bool = false );
436 void updateControls( int, int );
447 \param parent Parent widget.
448 \param briefSummary Show summary in brief format. Defaults to \c false.
450 ExtraWidget::ExtraWidget( QWidget* parent, bool briefSummary ): QWidget( parent ), brief( briefSummary )
452 current = new QLabel( this );
453 current->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
454 prev = new QPushButton( "<<", this );
455 next = new QPushButton( ">>", this );
456 QHBoxLayout* hbl = new QHBoxLayout( this );
458 hbl->setSpacing( SPACING );
460 hbl->addWidget( current );
461 hbl->addWidget( prev );
462 hbl->addWidget( next );
466 \brief Update controls.
467 \param total Total number of items.
468 \param index Current index.
470 void ExtraWidget::updateControls( int total, int index )
472 setVisible( total > blockSize() );
473 QString format = brief ? QString( "%1-%2 / %3" ) : SMESHGUI_MeshInfoDlg::tr( "X_FROM_Y_ITEMS_SHOWN" );
474 current->setText( format.arg( index*blockSize()+1 ).arg( qMin( index*blockSize()+blockSize(), total ) ).arg( total ) );
475 prev->setEnabled( index > 0 );
476 next->setEnabled( (index+1)*blockSize() < total );
479 ////////////////////////////////////////////////////////////////////////////////
480 /// \class DumpFileDlg
481 /// \brief Standard Save File dialog box, customized for dump info operation.
483 ////////////////////////////////////////////////////////////////////////////////
485 class DumpFileDlg : public SUIT_FileDlg
487 QMap<int, QCheckBox*> myControls;
489 DumpFileDlg( QWidget*, bool = true );
490 bool isChecked( int ) const;
491 void setChecked( int, bool );
496 \param parent Parent widget.
497 \param showControls Show additional controls. Defaults to \c true.
500 DumpFileDlg::DumpFileDlg( QWidget* parent, bool showControls ): SUIT_FileDlg( parent, false, true, true )
504 QWidget* hB = new QWidget( this );
505 myControls[SMESHGUI_MeshInfoDlg::BaseInfo] = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_BASE_INFO" ), hB );
506 myControls[SMESHGUI_MeshInfoDlg::ElemInfo] = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ELEM_INFO" ), hB );
507 myControls[SMESHGUI_MeshInfoDlg::AddInfo] = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_ADD_INFO" ), hB );
508 myControls[SMESHGUI_MeshInfoDlg::CtrlInfo] = new QCheckBox( SMESHGUI::tr( "PREF_DUMP_CTRL_INFO" ), hB );
510 QGridLayout* layout = new QGridLayout( hB );
511 layout->setMargin( 0 );
512 layout->addWidget( myControls[SMESHGUI_MeshInfoDlg::BaseInfo], 0, 0 );
513 layout->addWidget( myControls[SMESHGUI_MeshInfoDlg::ElemInfo], 0, 1 );
514 layout->addWidget( myControls[SMESHGUI_MeshInfoDlg::AddInfo], 1, 0 );
515 layout->addWidget( myControls[SMESHGUI_MeshInfoDlg::CtrlInfo], 1, 1 );
517 addWidgets( 0, hB, 0 );
522 \brief Get control's value.
523 \param option Control identifier.
524 \return Control value.
527 bool DumpFileDlg::isChecked( int option ) const
529 return myControls.contains( option ) ? myControls[option]->isChecked() : false;
533 \brief Set control's initial value.
534 \param option Control identifier.
535 \param value Control value.
538 void DumpFileDlg::setChecked( int option, bool value )
540 if ( myControls.contains( option ) )
541 myControls[option]->setChecked( value );
544 ////////////////////////////////////////////////////////////////////////////////
545 /// \class SMESHGUI_BaseInfo
546 /// \brief Show basic information on selected object.
548 /// Displays the base information about selected object: mesh, sub-mesh, group
549 /// or arbitrary ID source.
550 /// \todo Hide unnecessary widgets (e.g. for mesh group).
551 ////////////////////////////////////////////////////////////////////////////////
555 \param parent Parent widget. Defaults to 0.
557 SMESHGUI_BaseInfo::SMESHGUI_BaseInfo( QWidget* parent ): SMESHGUI_Info( parent )
559 QGridLayout* l = new QGridLayout( this );
560 l->setMargin( MARGIN );
561 l->setSpacing( SPACING );
565 addWidget( createLabel( tr( "NAME_LAB" ), this, Bold ), iName, iLabel );
566 addWidget( createField( this, "meshName" ), iName, iSingle, 4 )->setMinimumWidth( 150 );
568 addWidget( createLabel( tr( "OBJECT_LAB" ), this, Bold ), iObject, iLabel );
569 addWidget( createField( this, "meshType" ), iObject, iSingle, 4 )->setMinimumWidth( 150 );
571 addWidget( createSeparator( this ), iObjectEnd, iLabel, 5 );
575 addWidget( createLabel( tr( "NODES_LAB" ), this, Bold ), iNodes, iLabel );
576 addWidget( createField( this, "nbNodes" ), iNodes, iTotal );
578 addWidget( createSeparator( this ), iNodesEnd, iLabel, 5 );
582 addWidget( createLabel( tr( "ELEMENTS_LAB" ), this, Bold ), iElementsTitle, iLabel );
583 addWidget( createLabel( tr( "TOTAL_LAB" ), this, Italic ), iElementsTitle, iTotal );
584 addWidget( createLabel( tr( "LINEAR_LAB" ), this, Italic ), iElementsTitle, iLinear );
585 addWidget( createLabel( tr( "QUADRATIC_LAB" ), this, Italic ), iElementsTitle, iQuadratic );
586 addWidget( createLabel( tr( "BI_QUADRATIC_LAB" ), this, Italic ), iElementsTitle, iBiQuadratic );
588 addWidget( createSeparator( this ), iElementsTitleEnd, iTotal, 4 );
590 addWidget( createField( this, "totalNbElems" ), iElementsTotal, iTotal );
591 addWidget( createField( this, "totalNbLinearElems" ), iElementsTotal, iLinear );
592 addWidget( createField( this, "totalNbQuadraticElems" ), iElementsTotal, iQuadratic );
593 addWidget( createField( this, "totalNbBiQuadraticElems" ), iElementsTotal, iBiQuadratic );
595 addWidget( createSeparator( this ), iElementsTotalEnd, iTotal, 4 );
596 // - 0D elements info
597 addWidget( createLabel( tr( "0D_LAB" ), this, Bold | Italic ), i0D, iLabel );
598 addWidget( createField( this, "nb0D" ), i0D, iTotal );
600 addWidget( createSeparator( this ), i0DEnd, iTotal, 4 );
602 addWidget( createLabel( tr( "BALL_LAB" ), this, Bold | Italic ), iBalls, iLabel );
603 addWidget( createField( this, "nbBall" ), iBalls, iTotal );
605 addWidget( createSeparator( this ), iBallsEnd, iTotal, 4 );
606 // - 1D elements info
607 addWidget( createLabel( tr( "1D_LAB" ), this, Bold | Italic ), i1D, iLabel );
608 addWidget( createField( this, "nb1D" ), i1D, iTotal );
609 addWidget( createField( this, "nbLinear1D" ), i1D, iLinear );
610 addWidget( createField( this, "nbQuadratic1D" ), i1D, iQuadratic );
612 addWidget( createSeparator( this ), i1DEnd, iTotal, 4 );
613 // - 2D elements info
615 addWidget( createLabel( tr( "2D_LAB" ), this, Bold | Italic ), i2D, iLabel );
616 addWidget( createField( this, "nb2D" ), i2D, iTotal );
617 addWidget( createField( this, "nbLinear2D" ), i2D, iLinear );
618 addWidget( createField( this, "nbQuadratic2D" ), i2D, iQuadratic );
619 addWidget( createField( this, "nbBiQuadratic2D" ), i2D, iBiQuadratic );
621 addWidget( createLabel( tr( "TRIANGLES_LAB" ), this, Italic ), i2DTriangles, iLabel );
622 addWidget( createField( this, Italic, "nbTriangle" ), i2DTriangles, iTotal );
623 addWidget( createField( this, Italic, "nbLinearTriangle" ), i2DTriangles, iLinear );
624 addWidget( createField( this, Italic, "nbQuadraticTriangle" ), i2DTriangles, iQuadratic );
625 addWidget( createField( this, Italic, "nbBiQuadraticTriangle" ), i2DTriangles, iBiQuadratic );
627 addWidget( createLabel( tr( "QUADRANGLES_LAB" ), this, Italic ), i2DQuadrangles, iLabel );
628 addWidget( createField( this, Italic, "nbQuadrangle" ), i2DQuadrangles, iTotal );
629 addWidget( createField( this, Italic, "nbLinearQuadrangle" ), i2DQuadrangles, iLinear );
630 addWidget( createField( this, Italic, "nbQuadraticQuadrangle" ), i2DQuadrangles, iQuadratic );
631 addWidget( createField( this, Italic, "nbBiQuadraticQuadrangle" ), i2DQuadrangles, iBiQuadratic );
633 addWidget( createLabel( tr( "POLYGONS_LAB" ), this, Italic ), i2DPolygons, iLabel );
634 addWidget( createField( this, Italic, "nbPolygon" ), i2DPolygons, iTotal );
635 addWidget( createField( this, Italic, "nbLinearPolygon" ), i2DPolygons, iLinear );
636 addWidget( createField( this, Italic, "nbQuadraticPolygon" ), i2DPolygons, iQuadratic );
638 addWidget( createSeparator( this ), i2DEnd, iTotal, 4 );
639 // - 3D elements info
641 addWidget( createLabel( tr( "3D_LAB" ), this, Bold | Italic ), i3D, iLabel );
642 addWidget( createField( this, "nb3D" ), i3D, iTotal );
643 addWidget( createField( this, "nbLinear3D" ), i3D, iLinear );
644 addWidget( createField( this, "nbQuadratic3D" ), i3D, iQuadratic );
645 addWidget( createField( this, "nbBiQuadratic3D" ), i3D, iBiQuadratic );
647 addWidget( createLabel( tr( "TETRAHEDRONS_LAB" ), this, Italic ), i3DTetrahedrons, iLabel );
648 addWidget( createField( this, Italic, "nbTetrahedron" ), i3DTetrahedrons, iTotal );
649 addWidget( createField( this, Italic, "nbLinearTetrahedron" ), i3DTetrahedrons, iLinear );
650 addWidget( createField( this, Italic, "nbQudraticTetrahedron" ), i3DTetrahedrons, iQuadratic );
652 addWidget( createLabel( tr( "HEXAHEDONRS_LAB" ), this, Italic ), i3DHexahedrons, iLabel );
653 addWidget( createField( this, Italic, "nbHexahedron" ), i3DHexahedrons, iTotal );
654 addWidget( createField( this, Italic, "nbLinearHexahedron" ), i3DHexahedrons, iLinear );
655 addWidget( createField( this, Italic, "nbQuadraticHexahedron" ), i3DHexahedrons, iQuadratic );
656 addWidget( createField( this, Italic, "nbBiQuadraticHexahedron" ), i3DHexahedrons, iBiQuadratic );
658 addWidget( createLabel( tr( "PYRAMIDS_LAB" ), this, Italic ), i3DPyramids, iLabel );
659 addWidget( createField( this, Italic, "nbPyramid" ), i3DPyramids, iTotal );
660 addWidget( createField( this, Italic, "nbLinearPyramid" ), i3DPyramids, iLinear );
661 addWidget( createField( this, Italic, "nbQuadraticPyramid" ), i3DPyramids, iQuadratic );
663 addWidget( createLabel( tr( "PRISMS_LAB" ), this, Italic ), i3DPrisms, iLabel );
664 addWidget( createField( this, Italic, "nbPrism" ), i3DPrisms, iTotal );
665 addWidget( createField( this, Italic, "nbLinearPrism" ), i3DPrisms, iLinear );
666 addWidget( createField( this, Italic, "nbQuadraticPrism" ), i3DPrisms, iQuadratic );
667 addWidget( createField( this, Italic, "nbBiQuadraticPrism" ), i3DPrisms, iBiQuadratic );
668 // --+ hexagonal prisms
669 addWidget( createLabel( tr( "HEX_PRISMS_LAB" ), this, Italic ), i3DHexaPrisms, iLabel );
670 addWidget( createField( this, Italic, "nbHexagonalPrism" ), i3DHexaPrisms, iTotal );
672 addWidget( createLabel( tr( "POLYHEDRONS_LAB" ), this, Italic ), i3DPolyhedrons, iLabel );
673 addWidget( createField( this, Italic, "nbPolyhedron" ), i3DPolyhedrons, iTotal );
676 QPushButton* loadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this );
677 loadBtn->setAutoDefault( true );
678 connect( loadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() ) );
679 addWidget( loadBtn, iEnd, iSingle, 4 );
681 // additional layout set-up
682 l->setColumnStretch( iLabel, 0 );
683 l->setColumnStretch( iTotal, 5 );
684 l->setColumnStretch( iLinear, 5 );
685 l->setColumnStretch( iQuadratic, 5 );
686 l->setColumnStretch( iBiQuadratic, 5 );
687 l->setRowStretch( iElementsEnd, 5 );
689 // set initial values
696 SMESHGUI_BaseInfo::~SMESHGUI_BaseInfo()
701 \brief Show information on given object.
702 \param proxy Object to show information on (mesh, sub-mesh, group, ID source).
704 void SMESHGUI_BaseInfo::showInfo( const SMESH::SelectionProxy& proxy )
709 // then fill panel with data if object is not null
714 SMESH::MeshInfo info = proxy.meshInfo();
718 widget( iName, iSingle )->setProperty( "text", proxy.name() );
721 SMESH::SelectionProxy::Type type = proxy.type();
722 if ( type == SMESH::SelectionProxy::Mesh )
724 typeName = tr( "OBJECT_MESH" );
726 else if ( type == SMESH::SelectionProxy::Submesh )
728 typeName = tr( "OBJECT_SUBMESH" );
730 else if ( type >= SMESH::SelectionProxy::Group )
732 switch( proxy.groupElementType() )
734 case SMESH::NODE: typeName = tr( "OBJECT_GROUP_NODES" ); break;
735 case SMESH::EDGE: typeName = tr( "OBJECT_GROUP_EDGES" ); break;
736 case SMESH::FACE: typeName = tr( "OBJECT_GROUP_FACES" ); break;
737 case SMESH::VOLUME: typeName = tr( "OBJECT_GROUP_VOLUMES" ); break;
738 case SMESH::ELEM0D: typeName = tr( "OBJECT_GROUP_0DELEMS" ); break;
739 case SMESH::BALL: typeName = tr( "OBJECT_GROUP_BALLS" ); break;
740 default: typeName = tr( "OBJECT_GROUP" ); break;
743 if ( type == SMESH::SelectionProxy::GroupStd )
744 subType = tr( "OBJECT_GROUP_STANDALONE" );
745 else if ( type == SMESH::SelectionProxy::GroupGeom )
746 subType = tr( "OBJECT_GROUP_GEOM" );
747 else if ( type == SMESH::SelectionProxy::GroupFilter )
748 subType = tr( "OBJECT_GROUP_FILTER" );
749 if ( !subType.isEmpty() )
750 typeName = QString( "%1 %2" ).arg( typeName, subType );
752 widget( iObject, iSingle )->setProperty( "text", typeName );
755 uint nbNodes = info[SMDSEntity_Node];
756 widget( iNodes, iTotal )->setProperty( "value", nbNodes );
759 // - 0D elements info
760 uint nb0d = info[SMDSEntity_0D];
761 widget( i0D, iTotal )->setProperty( "value", nb0d );
763 uint nbBalls = info[SMDSEntity_Ball];
764 widget( iBalls, iTotal )->setProperty( "value", nbBalls );
765 // - 1D elements info
766 uint nb1dLin = info[SMDSEntity_Edge];
767 uint nb1dQua = info[SMDSEntity_Quad_Edge];
768 uint nb1d = nb1dLin + nb1dQua;
769 widget( i1D, iLinear )->setProperty( "value", nb1dLin );
770 widget( i1D, iQuadratic )->setProperty( "value", nb1dQua );
771 widget( i1D, iTotal )->setProperty( "value", nb1d );
772 // - 2D elements info
774 uint nbTriLin = info[SMDSEntity_Triangle];
775 uint nbTriQua = info[SMDSEntity_Quad_Triangle];
776 uint nbTriBiq = info[SMDSEntity_BiQuad_Triangle];
777 uint nbTri = nbTriLin + nbTriQua + nbTriBiq;
778 widget( i2DTriangles, iLinear )->setProperty( "value", nbTriLin );
779 widget( i2DTriangles, iQuadratic )->setProperty( "value", nbTriQua );
780 widget( i2DTriangles, iBiQuadratic )->setProperty( "value", nbTriBiq );
781 widget( i2DTriangles, iTotal )->setProperty( "value", nbTri );
783 uint nbQuadLin = info[SMDSEntity_Quadrangle];
784 uint nbQuadQua = info[SMDSEntity_Quad_Quadrangle];
785 uint nbQuadBiq = info[SMDSEntity_BiQuad_Quadrangle];
786 uint nbQuad = nbQuadLin + nbQuadQua + nbQuadBiq;
787 widget( i2DQuadrangles, iLinear )->setProperty( "value", nbQuadLin );
788 widget( i2DQuadrangles, iQuadratic )->setProperty( "value", nbQuadQua );
789 widget( i2DQuadrangles, iBiQuadratic )->setProperty( "value", nbQuadBiq );
790 widget( i2DQuadrangles, iTotal )->setProperty( "value", nbQuad );
792 uint nbPolyLin = info[SMDSEntity_Polygon];
793 uint nbPolyQua = info[SMDSEntity_Quad_Polygon];
794 uint nbPoly = nbPolyLin + nbPolyQua;
795 widget( i2DPolygons, iLinear )->setProperty( "value", nbPolyLin );
796 widget( i2DPolygons, iQuadratic )->setProperty( "value", nbPolyQua );
797 widget( i2DPolygons, iTotal )->setProperty( "value", nbPoly );
799 uint nb2dLin = nbTriLin + nbQuadLin + nbPolyLin;
800 uint nb2dQua = nbTriQua + nbQuadQua + nbPolyQua;
801 uint nb2dBiq = nbTriBiq + nbQuadBiq;
802 uint nb2d = nb2dLin + nb2dQua + nb2dBiq;
803 widget( i2D, iLinear )->setProperty( "value", nb2dLin );
804 widget( i2D, iQuadratic )->setProperty( "value", nb2dQua );
805 widget( i2D, iBiQuadratic )->setProperty( "value", nb2dBiq );
806 widget( i2D, iTotal )->setProperty( "value", nb2d );
807 // - 3D elements info
809 uint nbTetraLin = info[SMDSEntity_Tetra];
810 uint nbTetraQua = info[SMDSEntity_Quad_Tetra];
811 uint nbTetra = nbTetraLin + nbTetraQua;
812 widget( i3DTetrahedrons, iLinear )->setProperty( "value", nbTetraLin );
813 widget( i3DTetrahedrons, iQuadratic )->setProperty( "value", nbTetraQua );
814 widget( i3DTetrahedrons, iTotal )->setProperty( "value", nbTetra );
816 uint nbHexaLin = info[SMDSEntity_Hexa];
817 uint nbHexaQua = info[SMDSEntity_Quad_Hexa];
818 uint nbHexaBiq = info[SMDSEntity_TriQuad_Hexa];
819 uint nbHexa = nbHexaLin + nbHexaQua + nbHexaBiq;
820 widget( i3DHexahedrons, iLinear )->setProperty( "value", nbHexaLin );
821 widget( i3DHexahedrons, iQuadratic )->setProperty( "value", nbHexaQua );
822 widget( i3DHexahedrons, iBiQuadratic )->setProperty( "value", nbHexaBiq );
823 widget( i3DHexahedrons, iTotal )->setProperty( "value", nbHexa );
825 uint nbPyraLin = info[SMDSEntity_Pyramid];
826 uint nbPyraQua = info[SMDSEntity_Quad_Pyramid];
827 uint nbPyra = nbPyraLin + nbPyraQua;
828 widget( i3DPyramids, iLinear )->setProperty( "value", nbPyraLin );
829 widget( i3DPyramids, iQuadratic )->setProperty( "value", nbPyraQua );
830 widget( i3DPyramids, iTotal )->setProperty( "value", nbPyra );
832 uint nbPentaLin = info[SMDSEntity_Penta];
833 uint nbPentaQua = info[SMDSEntity_Quad_Penta];
834 uint nbPentaBiq = info[SMDSEntity_BiQuad_Penta];
835 uint nbPenta = nbPentaLin + nbPentaQua + nbPentaBiq;
836 widget( i3DPrisms, iLinear )->setProperty( "value", nbPentaLin );
837 widget( i3DPrisms, iQuadratic )->setProperty( "value", nbPentaQua );
838 widget( i3DPrisms, iBiQuadratic )->setProperty( "value", nbPentaBiq );
839 widget( i3DPrisms, iTotal )->setProperty( "value", nbPenta );
840 // --+ hexagonal prisms
841 uint nbHexaPri = info[SMDSEntity_Hexagonal_Prism];
842 widget( i3DHexaPrisms, iTotal )->setProperty( "value", nbHexaPri );
844 uint nbPolyhedra = info[SMDSEntity_Polyhedra];
845 widget( i3DPolyhedrons, iTotal )->setProperty( "value", nbPolyhedra );
847 uint nb3dLin = nbTetraLin + nbHexaLin + nbPyraLin + nbPentaLin + nbHexaPri + nbPolyhedra;
848 uint nb3dQua = nbTetraQua + nbHexaQua + nbPyraQua + nbPentaQua;
849 uint nb3dBiq = nbHexaBiq + nbPentaBiq;
850 uint nb3d = nb3dLin + nb3dQua + nb3dBiq;
851 widget( i3D, iLinear )->setProperty( "value", nb3dLin );
852 widget( i3D, iQuadratic )->setProperty( "value", nb3dQua );
853 widget( i3D, iBiQuadratic )->setProperty( "value", nb3dBiq );
854 widget( i3D, iTotal )->setProperty( "value", nb3d );
856 uint nbElemLin = nb1dLin + nb2dLin + nb3dLin;
857 uint nbElemQua = nb1dQua + nb2dQua + nb3dQua;
858 uint nbElemBiq = nb2dBiq + nb3dBiq;
859 uint nbElem = nb0d + nbBalls + nb1d + nb2d + nb3d;
860 widget( iElementsTotal, iLinear )->setProperty( "value", nbElemLin );
861 widget( iElementsTotal, iQuadratic )->setProperty( "value", nbElemQua );
862 widget( iElementsTotal, iBiQuadratic )->setProperty( "value", nbElemBiq );
863 widget( iElementsTotal, iTotal )->setProperty( "value", nbElem );
865 // show 'Load' button if data was not loaded yet
866 widget( iEnd, iSingle )->setVisible( !proxy.isValid() );
868 // until data is loaded from study file, type of elements in a sub-mesh or group
869 // can be undefined in some cases
870 if ( !proxy.isValid() )
872 // two cases are possible:
873 // 1. type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh)
874 // 2. there is no info at all (for a group on geom or on filter)
875 if ( info.count( SMDSEntity_Node, SMDSEntity_Last ) > 0 ) // believe it is a sub-mesh
877 if ( nb2dLin + nb2dQua + nb2dBiq > 0 )
879 // we know nothing about triangles, quadranges and polygons
880 for ( int i = i2DTriangles; i < i2DEnd; i++ )
882 for ( int j = iTotal; j < iNbColumns; j++ )
884 if ( widget( i, j ) )
885 widget( i, j )->setProperty( "text", "?" );
888 // we don't know if elements are linear, quadratic or bi-quadratic
889 for ( int j = iLinear; j < iNbColumns; j++ )
891 if ( widget( i2D, j ) )
892 widget( i2D, j )->setProperty( "text", "?" );
893 if ( widget( iElementsTotal, j ) )
894 widget( iElementsTotal, j )->setProperty( "text", "?" );
897 else if ( nb3dLin + nb3dQua + nb3dBiq > 0 )
899 // we know nothing about tetras, hexas, etc.
900 for ( int i = i3DTetrahedrons; i < i3DEnd; i++ )
902 for ( int j = iTotal; j < iNbColumns; j++ )
904 if ( widget( i, j ) )
905 widget( i, j )->setProperty( "text", "?" );
908 // we don't know if elements are linear, quadratic or bi-quadratic
909 for ( int j = iLinear; j < iNbColumns; j++ )
911 if ( widget( i3D, j ) )
912 widget( i3D, j )->setProperty( "text", "?" );
913 if ( widget( iElementsTotal, j ) )
914 widget( iElementsTotal, j )->setProperty( "text", "?" );
920 // we know nothing about nodes :(
921 widget( iNodes, iTotal )->setProperty( "text", "?" );
922 // we know nothing about elements :(
923 for ( int i = iElementsTotal; i < iElementsEnd; i++ )
925 for ( int j = iTotal; j < iNbColumns; j++ )
927 if ( widget( i, j ) )
928 widget( i, j )->setProperty( "text", "?" );
937 \brief Update information in panel.
939 void SMESHGUI_BaseInfo::updateInfo()
945 \brief Load mesh from a study file.
947 void SMESHGUI_BaseInfo::loadMesh()
949 SUIT_OverrideCursor wc;
958 \brief Reset panel (clear all data).
960 void SMESHGUI_BaseInfo::clear()
963 widget( iName, iSingle )->setProperty( "text", QString() );
965 widget( iObject, iSingle )->setProperty( "text", QString() );
967 widget( iNodes, iTotal )->setProperty( "value", 0 );
969 for ( int i = iElementsTotal; i < iElementsEnd; i++ )
971 for ( int j = iTotal; j < iNbColumns; j++ )
973 if ( widget( i, j ) )
974 widget( i, j )->setProperty( "value", 0 );
977 // hide 'Load' button
978 widget( iEnd, iSingle )->setVisible( false );
982 \brief Register widget in a grid.
983 \param w Widget being added.
984 \param row Row index in a grid.
985 \param column Column index in a grid.
986 \param colspan Number of columns to span in a grid. Defaults to 1.
987 \return Just added widget.
989 QWidget* SMESHGUI_BaseInfo::addWidget( QWidget* w, int row, int column, int colspan )
991 if ( !myWidgets.contains( row ) )
992 myWidgets[row] = wlist();
993 myWidgets[row][column] = w;
994 dynamic_cast<QGridLayout*>( layout() )->addWidget( w, row, column, 1, colspan );
999 \brief Get registered widget.
1000 \param row Row index in a grid.
1001 \param column Column index in a grid.
1002 \return Widget stored in a given grid cell (0 if there's no widget).
1004 QWidget* SMESHGUI_BaseInfo::widget( int row, int column ) const
1006 return myWidgets.contains( row ) && myWidgets[row].contains( column ) ? myWidgets[row][column] : 0;
1010 \brief Get text value from registered widget.
1011 \param row Row index in a grid.
1012 \param column Column index in a grid.
1013 \return Value string (empty string if no label in given cell).
1015 QString SMESHGUI_BaseInfo::value( int row, int column ) const
1017 return widgetValue( widget( row, column ) );
1021 \brief Show/hide group(s) of widgets.
1022 \param startRow Starting grid row.
1023 \param lastRow Last grid row.
1024 \param on Visibility flag.
1026 void SMESHGUI_BaseInfo::setFieldsVisible( int startRow, int lastRow, bool on )
1028 startRow = qMax( 0, startRow );
1029 lastRow = qMin( lastRow, (int)iEnd );
1030 for ( int i = startRow; i <= lastRow; i++ )
1032 wlist widgets = myWidgets[i];
1033 foreach ( QWidget* w, widgets )
1034 w->setVisible( on );
1039 \brief Write information from panel to output stream.
1040 \param out Text stream output.
1042 void SMESHGUI_BaseInfo::saveInfo( QTextStream& out )
1045 QString title = tr( "BASE_INFO" );
1046 out << ruler( title.size() ) << endl;
1047 out << title << endl;
1048 out << ruler( title.size() ) << endl;
1053 out << tr( "NAME_LAB" ) << spacing() << value( iName, iSingle ) << endl;
1055 out << tr( "OBJECT_LAB" ) << spacing() << value( iObject, iSingle ) << endl;
1056 // - --- (separator)
1060 out << tr( "NODES_LAB" ) << spacing() << value( iNodes, iTotal ) << endl;
1061 // - --- (separator)
1065 QString lin = tr( "LINEAR_LAB" ) + ":" + spacing();
1066 QString qua = tr( "QUADRATIC_LAB" ) + ":" + spacing();
1067 QString biq = tr( "BI_QUADRATIC_LAB" ) + ":" + spacing();
1069 out << tr( "ELEMENTS_LAB" ) << spacing() << value( iElementsTotal, iTotal ) << endl;
1070 out << indent(1) << lin << value( iElementsTotal, iLinear ) << endl;
1071 out << indent(1) << qua << value( iElementsTotal, iQuadratic ) << endl;
1072 out << indent(1) << biq << value( iElementsTotal, iBiQuadratic ) << endl;
1073 // - --- (separator)
1075 // - 0D elements info
1076 out << indent(1) << tr( "0D_LAB" ) << spacing() << value( i0D, iTotal ) << endl;
1077 // - --- (separator)
1080 out << indent(1) << tr( "BALL_LAB" ) << spacing() << value( iBalls, iTotal ) << endl;
1081 // - --- (separator)
1083 // - 1D elements info
1084 out << indent(1) << tr( "1D_LAB" ) << spacing() << value( i1D, iTotal ) << endl;
1085 out << indent(2) << lin << value( i1D, iLinear ) << endl;
1086 out << indent(2) << qua << value( i1D, iQuadratic ) << endl;
1087 // - --- (separator)
1089 // - 2D elements info
1091 out << indent(1) << tr( "2D_LAB" ) << spacing() << value( i2D, iTotal ) << endl;
1092 out << indent(2) << lin << value( i2D, iLinear ) << endl;
1093 out << indent(2) << qua << value( i2D, iQuadratic ) << endl;
1094 out << indent(2) << biq << value( i2D, iBiQuadratic ) << endl;
1095 // - --- (separator)
1098 out << indent(2) << tr( "TRIANGLES_LAB" ) << spacing() << value( i2DTriangles, iTotal ) << endl;
1099 out << indent(3) << lin << value( i2DTriangles, iLinear ) << endl;
1100 out << indent(3) << qua << value( i2DTriangles, iQuadratic ) << endl;
1101 out << indent(3) << biq << value( i2DTriangles, iBiQuadratic ) << endl;
1103 out << indent(2) << tr( "QUADRANGLES_LAB" ) << spacing() << value( i2DQuadrangles, iTotal ) << endl;
1104 out << indent(3) << lin << value( i2DQuadrangles, iLinear ) << endl;
1105 out << indent(3) << qua << value( i2DQuadrangles, iQuadratic ) << endl;
1106 out << indent(3) << biq << value( i2DQuadrangles, iBiQuadratic ) << endl;
1108 out << indent(2) << tr( "POLYGONS_LAB" ) << spacing() << value( i2DPolygons, iTotal ) << endl;
1109 out << indent(3) << lin << value( i2DPolygons, iLinear ) << endl;
1110 out << indent(3) << qua << value( i2DPolygons, iQuadratic ) << endl;
1111 // - --- (separator)
1113 // - 3D elements info
1115 out << indent(1) << tr( "3D_LAB" ) << spacing() << value( i3D, iTotal ) << endl;
1116 out << indent(2) << lin << value( i3D, iLinear ) << endl;
1117 out << indent(2) << qua << value( i3D, iQuadratic ) << endl;
1118 out << indent(2) << biq << value( i3D, iBiQuadratic ) << endl;
1119 // - --- (separator)
1122 out << indent(2) << tr( "TETRAHEDRONS_LAB" ) << spacing() << value( i3DTetrahedrons, iTotal ) << endl;
1123 out << indent(3) << lin << value( i3DTetrahedrons, iLinear ) << endl;
1124 out << indent(3) << qua << value( i3DTetrahedrons, iQuadratic ) << endl;
1126 out << indent(2) << tr( "HEXAHEDONRS_LAB" ) << spacing() << value( i3DHexahedrons, iTotal ) << endl;
1127 out << indent(3) << lin << value( i3DHexahedrons, iLinear ) << endl;
1128 out << indent(3) << qua << value( i3DHexahedrons, iQuadratic ) << endl;
1129 out << indent(3) << biq << value( i3DHexahedrons, iBiQuadratic ) << endl;
1131 out << indent(2) << tr( "PYRAMIDS_LAB" ) << spacing() << value( i3DPyramids, iTotal ) << endl;
1132 out << indent(3) << lin << value( i3DPyramids, iLinear ) << endl;
1133 out << indent(3) << qua << value( i3DPyramids, iQuadratic ) << endl;
1135 out << indent(2) << tr( "PRISMS_LAB" ) << spacing() << value( i3DPrisms, iTotal ) << endl;
1136 out << indent(3) << lin << value( i3DPrisms, iLinear ) << endl;
1137 out << indent(3) << qua << value( i3DPrisms, iQuadratic ) << endl;
1138 out << indent(3) << biq << value( i3DPrisms, iBiQuadratic ) << endl;
1139 // --+ hexagonal prisms
1140 out << indent(2) << tr( "HEX_PRISMS_LAB" ) << spacing() << value( i3DHexaPrisms, iTotal ) << endl;
1142 out << indent(2) << tr( "POLYHEDRONS_LAB" ) << spacing() << value( i3DPolyhedrons, iTotal ) << endl;
1143 // - --- (separator)
1147 ////////////////////////////////////////////////////////////////////////////////
1148 /// \class InfoWriter
1149 /// \brief Base info writer class.
1151 ////////////////////////////////////////////////////////////////////////////////
1159 InfoWriter( bool = false );
1160 void write( const QString&, bool = false );
1161 void write( const QString&, const QString&, bool = false );
1162 void write( const QString&, int, bool = false );
1163 void write( const QString&, double, bool = false );
1164 void write( const QString&, const SMESH::XYZ&, bool = false );
1165 virtual void indent() {}
1166 virtual void unindent() {}
1167 virtual void separator() {}
1169 virtual void put( const QString&, const QString&, bool = false ) = 0;
1172 InfoWriter::InfoWriter( bool r ): myRecursive(r)
1174 myPrecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
1177 void InfoWriter::write( const QString& key, bool emphasize )
1179 put( key, QString(), emphasize );
1182 void InfoWriter::write( const QString& key, const QString& value, bool emphasize )
1184 put( key, value, emphasize );
1187 void InfoWriter::write( const QString& key, int value, bool emphasize )
1189 put( key, QString::number( value ), emphasize );
1192 void InfoWriter::write( const QString& key, double value, bool emphasize )
1194 put( key, QString::number( value, myPrecision > 0 ? 'f' : 'g', qAbs( myPrecision ) ), emphasize );
1197 void InfoWriter::write( const QString& key, const SMESH::XYZ& value, bool emphasize )
1201 write( key, emphasize );
1203 write( "X", value.x() );
1204 write( "Y", value.y() );
1205 write( "Z", value.z() );
1211 vl << QString::number( value.x(), myPrecision > 0 ? 'f' : 'g', qAbs( myPrecision ) );
1212 vl << QString::number( value.y(), myPrecision > 0 ? 'f' : 'g', qAbs( myPrecision ) );
1213 vl << QString::number( value.z(), myPrecision > 0 ? 'f' : 'g', qAbs( myPrecision ) );
1214 put( key, vl.join( ", " ), emphasize );
1218 ////////////////////////////////////////////////////////////////////////////////
1219 /// \class SimpleWriter
1220 /// \brief Base text writer.
1222 ////////////////////////////////////////////////////////////////////////////////
1224 class SimpleWriter: public InfoWriter
1234 void put( const QString&, const QString&, bool );
1235 virtual QString spacer() const;
1236 virtual QString decorate( const QString& ) const;
1237 virtual void dumpLine( const QString& ) = 0;
1240 SimpleWriter::SimpleWriter(): InfoWriter(false), myIndent(0)
1244 void SimpleWriter::indent()
1249 void SimpleWriter::unindent()
1251 myIndent = qMax( myIndent-1, 0 );
1254 void SimpleWriter::separator()
1259 QString SimpleWriter::spacer() const
1264 QString SimpleWriter::decorate( const QString& s ) const
1269 void SimpleWriter::put( const QString& key, const QString& value, bool emphasize )
1272 line += ::indent( spacer(), myIndent*4 );
1273 line += decorate( key );
1274 if ( !value.isEmpty() )
1277 line += emphasize ? decorate( value ) : value;
1282 ////////////////////////////////////////////////////////////////////////////////
1283 /// \class StreamWriter
1284 /// \brief Writer for QTextStream.
1286 ////////////////////////////////////////////////////////////////////////////////
1288 class StreamWriter: public SimpleWriter
1292 StreamWriter( QTextStream& );
1294 void dumpLine( const QString& );
1297 StreamWriter::StreamWriter( QTextStream& out ): SimpleWriter(), myOut(out)
1301 void StreamWriter::dumpLine( const QString& line )
1307 ////////////////////////////////////////////////////////////////////////////////
1308 /// \class TextWriter
1309 /// \brief Writer for QTextBrowser.
1311 ////////////////////////////////////////////////////////////////////////////////
1313 class TextWriter: public SimpleWriter
1315 QTextBrowser* myInfo;
1317 TextWriter( QTextBrowser* );
1319 QString spacer() const;
1320 QString decorate( const QString& ) const;
1321 void dumpLine( const QString& );
1324 TextWriter::TextWriter( QTextBrowser* w ): SimpleWriter(), myInfo(w)
1328 QString TextWriter::spacer() const
1333 QString TextWriter::decorate( const QString& s ) const
1338 void TextWriter::dumpLine( const QString& line )
1340 myInfo->append( line );
1343 ////////////////////////////////////////////////////////////////////////////////
1344 /// \class TreeWriter
1345 /// \brief Writer for QTreeWidget.
1347 ////////////////////////////////////////////////////////////////////////////////
1349 class TreeWriter: public InfoWriter
1351 QTreeWidget* myInfo;
1352 QTreeWidgetItem* myCurrentItem;
1353 TreeItemCreator* myCreator;
1355 TreeWriter( QTreeWidget*, TreeItemCreator* );
1360 void put( const QString&, const QString&, bool = false );
1363 TreeWriter::TreeWriter( QTreeWidget* w, TreeItemCreator* c ):
1364 InfoWriter(true), myInfo(w), myCurrentItem(0), myCreator(c)
1368 TreeWriter::~TreeWriter()
1373 void TreeWriter::put( const QString& key, const QString& value, bool emphasize )
1375 //std::string sss = myCurrentItem ? myCurrentItem->text(0).toStdString() : "";
1377 if ( emphasize ) options |= AllColumns;
1378 QTreeWidgetItem* item = myCreator->createItem( myCurrentItem, options );
1379 item->setText( 0, key );
1380 if ( !value.isEmpty() )
1382 QString val = value;
1383 if ( value.startsWith( "<a href" )) // connectivity encoded as: <a href = "nodes://host/1 2">1 2</a>
1385 int role = ( value[11] == 'n' ) ? NodeConnectivity : ElemConnectivity;
1386 val = value.mid( value.lastIndexOf( '>', -5 ) + 1 ); // ==> 1 2</a>
1388 item->setData( 1, TypeRole, role );
1390 item->setText( 1, val );
1394 void TreeWriter::indent()
1396 QTreeWidgetItem* item = myCurrentItem ? myCurrentItem : myInfo->invisibleRootItem();
1397 if ( item->childCount() > 0 )
1398 myCurrentItem = item->child( item->childCount()-1 );
1401 void TreeWriter::unindent()
1403 if ( myCurrentItem )
1404 myCurrentItem = myCurrentItem->parent();
1407 ////////////////////////////////////////////////////////////////////////////////
1408 /// \class SMESHGUI_ElemInfo
1409 /// \brief Base class for the mesh element information widget.
1411 /// Displays the detail information about given mesh node(s) or element(s).
1412 /// Default class does not provide working implementation but onle general
1413 /// functionalities; main work is done in sub-classes.
1414 ////////////////////////////////////////////////////////////////////////////////
1418 \param parent Parent widget. Defaults to 0.
1420 SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent ): SMESHGUI_Info( parent ), myWhat( ShowNone )
1422 myFrame = new QWidget( this );
1423 myExtra = new ExtraWidget( this );
1425 QVBoxLayout* vbl = new QVBoxLayout( this );
1426 vbl->setMargin( 0 );
1427 vbl->setSpacing( SPACING );
1428 vbl->addWidget( myFrame );
1429 vbl->addWidget( myExtra );
1431 connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() ) );
1432 connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() ) );
1440 SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo()
1445 \brief Show information on given node / element.
1446 \param proxy Object to compute information on (mesh, sub-mesh, group, ID source).
1447 \param id Mesh node / element ID.
1448 \param isElement If \c true, show element info; otherwise show node info.
1450 void SMESHGUI_ElemInfo::showInfo( const SMESH::SelectionProxy& proxy, uint id, bool isElement )
1454 showInfo( proxy, ids, isElement );
1458 \brief Show information on given nodes / elements.
1459 \param proxy Object to compute information on (mesh, sub-mesh, group, ID source).
1460 \param ids Mesh nodes / elements IDs.
1461 \param isElement If \c true, show element info; otherwise show node info.
1463 void SMESHGUI_ElemInfo::showInfo( const SMESH::SelectionProxy& proxy, QSet<uint> ids, bool isElement )
1471 QList<uint> newIds = ids.toList();
1473 int what = isElement ? ShowElements : ShowNodes;
1475 if ( myProxy == proxy && myIDs == newIds && myWhat == what )
1479 myProxy.refresh(); // try to re-initialize actor
1488 information( myIDs.mid( myIndex*blockSize(), blockSize() ) );
1492 \brief Show information on given group.
1493 \param proxy Object to compute information on (group).
1495 void SMESHGUI_ElemInfo::showInfo( const SMESH::SelectionProxy& proxy )
1497 if ( !proxy || proxy.groupElementType() == SMESH::ALL ) // null proxy or not a group
1503 showInfo( proxy, proxy.ids(), proxy.groupElementType() != SMESH::NODE );
1507 \brief Reset panel (clear all data).
1509 void SMESHGUI_ElemInfo::clear()
1518 \brief Get central area widget.
1519 \return Central widget.
1521 QWidget* SMESHGUI_ElemInfo::centralWidget() const
1527 \brief Get current mesh proxy object information is shown on.
1528 \return Current proxy.
1530 SMESH::SelectionProxy SMESHGUI_ElemInfo::proxy() const
1536 \brief Get current info mode.
1537 \return Current panel mode.
1539 int SMESHGUI_ElemInfo::what() const
1545 \brief Get title for given element type.
1546 \param type Mesh element type.
1547 \param multiple Use plural form. Defaults to \c false.
1548 \return Element type's title.
1550 QString SMESHGUI_ElemInfo::type2str( int type, bool multiple )
1556 title = multiple ? tr( "EDGES" ) : tr( "EDGE" ) ; break;
1558 title = multiple ? tr( "FACES" ) : tr( "FACE" ); break;
1559 case SMDSAbs_Volume:
1560 title = multiple ? tr( "VOLUMES" ) : tr( "VOLUME" ); break;
1561 case SMDSAbs_0DElement:
1562 title = multiple ? tr( "0D_ELEMENTS" ) : tr( "0D_ELEMENT" ); break;
1564 title = multiple ? tr( "BALL_ELEMENTS" ) : tr( "BALL" ); break;
1572 \brief Get title for given shape type.
1573 \param type Shape type.
1574 \return Shape type's title.
1576 QString SMESHGUI_ElemInfo::stype2str( int type )
1582 title = tr( "GEOM_VERTEX" ); break;
1584 title = tr( "GEOM_EDGE" ); break;
1586 title = tr( "GEOM_FACE" ); break;
1589 title = tr( "GEOM_SOLID" ); break;
1596 \brief Get title for given element type.
1597 \param type Mesh element type.
1598 \return Element type's title.
1600 QString SMESHGUI_ElemInfo::etype2str( int type )
1605 case SMESH::Entity_0D:
1606 title = tr( "SMESH_ELEM0D" ); break;
1607 case SMESH::Entity_Edge:
1608 title = tr( "SMESH_EDGE" ); break;
1609 case SMESH::Entity_Quad_Edge:
1610 title = tr( "SMESH_QUADRATIC_EDGE" ); break;
1611 case SMESH::Entity_Triangle:
1612 title = tr( "SMESH_TRIANGLE" ); break;
1613 case SMESH::Entity_Quad_Triangle:
1614 title = tr( "SMESH_QUADRATIC_TRIANGLE" ); break;
1615 case SMESH::Entity_BiQuad_Triangle:
1616 title = tr( "SMESH_BIQUADRATIC_TRIANGLE" ); break;
1617 case SMESH::Entity_Quadrangle:
1618 title = tr( "SMESH_QUADRANGLE" ); break;
1619 case SMESH::Entity_Quad_Quadrangle:
1620 title = tr( "SMESH_QUADRATIC_QUADRANGLE" ); break;
1621 case SMESH::Entity_BiQuad_Quadrangle:
1622 title = tr( "SMESH_BIQUADRATIC_QUADRANGLE" ); break;
1623 case SMESH::Entity_Polygon:
1624 title = tr( "SMESH_POLYGON" ); break;
1625 case SMESH::Entity_Quad_Polygon:
1626 title = tr( "SMESH_QUADRATIC_POLYGON" ); break;
1627 case SMESH::Entity_Tetra:
1628 title = tr( "SMESH_TETRAHEDRON" ); break;
1629 case SMESH::Entity_Quad_Tetra:
1630 title = tr( "SMESH_QUADRATIC_TETRAHEDRON" ); break;
1631 case SMESH::Entity_Pyramid:
1632 title = tr( "SMESH_PYRAMID" ); break;
1633 case SMESH::Entity_Quad_Pyramid:
1634 title = tr( "SMESH_QUADRATIC_PYRAMID" ); break;
1635 case SMESH::Entity_Hexa:
1636 title = tr( "SMESH_HEXAHEDRON" ); break;
1637 case SMESH::Entity_Quad_Hexa:
1638 title = tr( "SMESH_QUADRATIC_HEXAHEDRON" ); break;
1639 case SMESH::Entity_TriQuad_Hexa:
1640 title = tr( "SMESH_TRIQUADRATIC_HEXAHEDRON" ); break;
1641 case SMESH::Entity_Penta:
1642 title = tr( "SMESH_PENTA" ); break;
1643 case SMESH::Entity_Quad_Penta:
1644 title = tr( "SMESH_QUADRATIC_PENTAHEDRON" ); break;
1645 case SMESH::Entity_BiQuad_Penta:
1646 title = tr( "SMESH_BIQUADRATIC_PENTAHEDRON" ); break;
1647 case SMESH::Entity_Hexagonal_Prism:
1648 title = tr( "SMESH_HEX_PRISM" ); break;
1649 case SMESH::Entity_Polyhedra:
1650 title = tr( "SMESH_POLYEDRON" ); break;
1651 case SMESH::Entity_Quad_Polyhedra:
1652 title = tr( "SMESH_QUADRATIC_POLYEDRON" ); break;
1653 case SMESH::Entity_Ball:
1654 title = tr( "SMESH_BALL" ); break;
1662 \brief Get title for given quality control.
1663 \param type Mesh control type.
1664 \return Quality control's title.
1666 QString SMESHGUI_ElemInfo::ctrl2str( int control )
1671 case SMESH::FT_AspectRatio:
1672 title = tr( "ASPECTRATIO_ELEMENTS" ); break;
1673 case SMESH::FT_AspectRatio3D:
1674 title = tr( "ASPECTRATIO_3D_ELEMENTS" ); break;
1675 case SMESH::FT_Warping:
1676 title = tr( "WARP_ELEMENTS" ); break;
1677 case SMESH::FT_MinimumAngle:
1678 title = tr( "MINIMUMANGLE_ELEMENTS" ); break;
1679 case SMESH::FT_Taper:
1680 title = tr( "TAPER_ELEMENTS" ); break;
1681 case SMESH::FT_Skew:
1682 title = tr( "SKEW_ELEMENTS" ); break;
1683 case SMESH::FT_Area:
1684 title = tr( "AREA_ELEMENTS" ); break;
1685 case SMESH::FT_Volume3D:
1686 title = tr( "VOLUME_3D_ELEMENTS" ); break;
1687 case SMESH::FT_ScaledJacobian:
1688 title = tr( "SCALED_JACOBIAN" ); break;
1689 case SMESH::FT_MaxElementLength2D:
1690 title = tr( "MAX_ELEMENT_LENGTH_2D" ); break;
1691 case SMESH::FT_MaxElementLength3D:
1692 title = tr( "MAX_ELEMENT_LENGTH_3D" ); break;
1693 case SMESH::FT_Length:
1694 title = tr( "LENGTH_EDGES" ); break;
1695 case SMESH::FT_Length2D:
1696 case SMESH::FT_Length3D:
1697 title = tr( "MIN_ELEM_EDGE" ); break;
1698 case SMESH::FT_BallDiameter:
1699 title = tr( "BALL_DIAMETER" ); break;
1707 \brief Write information on given mesh nodes / elements.
1708 \param writer Information writer.
1709 \param ids Nodes / elements IDs.
1711 void SMESHGUI_ElemInfo::writeInfo( InfoWriter* writer, const QList<uint>& ids )
1716 bool grp_details = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "elem_info_grp_details", false );
1717 int cprecision = SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) ?
1718 SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 ) : -1;
1721 SMESH::Connectivity connectivity;
1722 SMESH::Position position;
1725 foreach ( uint id, ids )
1727 writer->separator();
1729 if ( what() == ShowNodes )
1732 // - check that node exists
1733 if ( !proxy().hasNode( id ) )
1736 writer->write( tr( "NODE" ), (int)id, true );
1739 ok = proxy().nodeCoordinates( id, xyz );
1742 writer->write( tr( "COORDINATES" ), xyz );
1745 ok = proxy().nodeConnectivity( id, connectivity );
1748 if ( !connectivity.isEmpty() )
1750 writer->write( tr( "CONNECTIVITY" ) );
1752 for ( int i = SMDSAbs_Edge; i <= SMDSAbs_Ball; i++ )
1754 QString formatted = formatConnectivity( connectivity, i );
1755 if ( !formatted.isEmpty() )
1756 writer->write( type2str( i, true ), formatted );
1762 writer->write( tr( "CONNECTIVITY" ), tr( "FREE_NODE" ) );
1766 ok = proxy().nodePosition( id, position );
1767 if ( ok && position.isValid() )
1769 writer->write( tr( "POSITION" ), (stype2str( position.shapeType() ) + " #%1").arg( position.shapeId() ) );
1771 if ( position.hasU() )
1772 writer->write( tr("U_POSITION"), position.u() );
1773 if ( position.hasV() )
1774 writer->write( tr("V_POSITION"), position.v() );
1777 // - groups node belongs to
1778 QList<SMESH::SelectionProxy> groups = proxy().nodeGroups( id );
1779 bool topCreated = false;
1780 foreach( SMESH::SelectionProxy group, groups )
1782 if ( group && !group.name().isEmpty() )
1786 writer->write( SMESHGUI_AddInfo::tr( "GROUPS" ) );
1790 writer->write( group.name().trimmed() ); // trim name
1794 int type = group.type();
1795 if ( type == SMESH::SelectionProxy::GroupStd )
1797 writer->write( SMESHGUI_AddInfo::tr( "TYPE" ), SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) );
1799 else if ( type == SMESH::SelectionProxy::GroupGeom )
1801 writer->write( SMESHGUI_AddInfo::tr( "TYPE" ), SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) );
1802 writer->write( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ), group.shapeName() );
1804 else if ( type == SMESH::SelectionProxy::GroupFilter )
1806 writer->write( SMESHGUI_AddInfo::tr( "TYPE" ), SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) );
1808 int size = group.size();
1810 writer->write( SMESHGUI_AddInfo::tr( "SIZE" ), size );
1811 QColor color = group.color();
1812 if ( color.isValid() )
1813 writer->write( SMESHGUI_AddInfo::tr( "COLOR" ), color.name() );
1822 else if ( what() == ShowElements )
1824 // show element info
1825 // - check that element exists
1826 if ( !proxy().hasElement( id ) )
1829 int type = proxy().elementType( id );
1830 if ( type == SMESH::ALL )
1832 writer->write( type2str( type ), (int)id, true );
1835 type = proxy().elementEntityType( id );
1836 writer->write( tr( "TYPE" ), etype2str( type ) );
1838 if ( type == SMESH::Entity_Polyhedra ||
1839 type == SMESH::Entity_Quad_Polyhedra )
1842 ok = proxy().perFaceConnectivity( id, connectivity, nbNodes );
1843 if ( ok && !connectivity.isEmpty() )
1845 writer->write( tr( "NB_NODES" ), nbNodes );
1846 writer->write( tr( "CONNECTIVITY" ) );
1848 int nbFaces = connectivity.size();
1849 for ( int iF = 1; iF <= nbFaces; ++iF )
1851 QString formatted = formatConnectivity( connectivity, -iF );
1852 writer->write(( type2str( SMDSAbs_Face, 0 ) + " %1 / %2" ).arg( iF ).arg( nbFaces ),
1860 ok = proxy().elementConnectivity( id, connectivity );
1861 if ( ok && !connectivity.isEmpty() )
1863 QString formatted = formatConnectivity( connectivity, SMDSAbs_Node );
1864 if ( !formatted.isEmpty() )
1866 writer->write( tr( "NB_NODES" ), connectivity[ SMDSAbs_Node ].size() );
1867 writer->write( tr( "CONNECTIVITY" ), formatted ); //todo: TypeRole: ElemConnectivity
1872 ok = proxy().elementPosition( id, position );
1873 if ( ok && position.isValid() )
1875 writer->write( tr( "POSITION" ), (stype2str( position.shapeType() ) + " #%1").arg( position.shapeId() ) );
1878 ok = proxy().elementGravityCenter( id, xyz );
1881 writer->write( tr( "GRAVITY_CENTER" ), xyz );
1884 ok = proxy().elementNormal( id, xyz );
1887 writer->write( tr( "NORMAL_VECTOR" ), xyz );
1890 bool topCreated = false;
1891 for ( int i = SMESH::FT_AspectRatio; i < SMESH::FT_Undefined; i++ )
1893 QString ctrlTitle = ctrl2str( i );
1894 if ( ctrlTitle.isEmpty() )
1898 writer->write( tr( "CONTROLS" ) );
1903 if ( proxy().elementControl( id, i, cprecision, value ) )
1904 writer->write( ctrlTitle, value );
1908 // - groups element belongs to
1909 QList<SMESH::SelectionProxy> groups = proxy().elementGroups( id );
1911 foreach( SMESH::SelectionProxy group, groups )
1913 if ( group && !group.name().isEmpty() )
1917 writer->write( SMESHGUI_AddInfo::tr( "GROUPS" ) );
1921 writer->write( group.name().trimmed() ); // trim name
1925 int type = group.type();
1926 if ( type == SMESH::SelectionProxy::GroupStd )
1928 writer->write( SMESHGUI_AddInfo::tr( "TYPE" ), SMESHGUI_AddInfo::tr( "STANDALONE_GROUP" ) );
1930 else if ( type == SMESH::SelectionProxy::GroupGeom )
1932 writer->write( SMESHGUI_AddInfo::tr( "TYPE" ), SMESHGUI_AddInfo::tr( "GROUP_ON_GEOMETRY" ) );
1933 writer->write( SMESHGUI_AddInfo::tr( "GEOM_OBJECT" ), group.shapeName() );
1935 else if ( type == SMESH::SelectionProxy::GroupFilter )
1937 writer->write( SMESHGUI_AddInfo::tr( "TYPE" ), SMESHGUI_AddInfo::tr( "GROUP_ON_FILTER" ) );
1939 int size = group.size();
1941 writer->write( SMESHGUI_AddInfo::tr( "SIZE" ), size );
1942 QColor color = group.color();
1943 if ( color.isValid() )
1944 writer->write( SMESHGUI_AddInfo::tr( "COLOR" ), color.name() );
1957 \fn void SMESHGUI_ElemInfo::information( const QList<uint>& ids )
1958 \brief Show information on given mesh nodes / elements.
1960 This function has to be redefined in sub-classes.
1962 \param ids Nodes / elements IDs.
1966 \brief Internal clean-up (reset panel).
1968 Default implementation does nothing; the method has to be redefined
1969 in sub-classes to perform internal clean-up.
1971 void SMESHGUI_ElemInfo::clearInternal()
1976 \brief Show previous chunk of information.
1978 void SMESHGUI_ElemInfo::showPrevious()
1980 myIndex = qMax( 0, myIndex-1 );
1982 information( myIDs.mid( myIndex*blockSize(), blockSize() ) );
1986 \brief Show next chunk of information.
1988 void SMESHGUI_ElemInfo::showNext()
1990 myIndex = qMin( myIndex+1, myIDs.count() / blockSize() );
1992 information( myIDs.mid( myIndex*blockSize(), blockSize() ) );
1996 \brief Update control widget state.
1998 void SMESHGUI_ElemInfo::updateControls()
2000 myExtra->updateControls( myIDs.count(), myIndex );
2004 \brief Write information from panel to output stream.
2005 \param out Text stream output.
2007 void SMESHGUI_ElemInfo::saveInfo( QTextStream &out )
2010 QString title = tr( "ELEM_INFO" );
2011 out << ruler( title.size() ) << endl;
2012 out << title << endl;
2013 out << ruler( title.size() ) << endl;
2017 StreamWriter writer( out );
2018 writeInfo( &writer, myIDs );
2022 ////////////////////////////////////////////////////////////////////////////////
2023 /// \class SMESHGUI_SimpleElemInfo
2024 /// \brief Show mesh element information in the simple text area.
2025 ////////////////////////////////////////////////////////////////////////////////
2029 \param parent Parent widget. Defaults to 0.
2031 SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent )
2032 : SMESHGUI_ElemInfo( parent )
2034 myInfo = new QTextBrowser( centralWidget() );
2035 QVBoxLayout* l = new QVBoxLayout( centralWidget() );
2037 l->addWidget( myInfo );
2039 connect( myInfo, SIGNAL( anchorClicked(QUrl)), this, SLOT( connectivityClicked( QUrl )));
2043 \brief Show mesh element information.
2044 \param ids Nodes / elements IDs.
2046 void SMESHGUI_SimpleElemInfo::information( const QList<uint>& ids )
2049 TextWriter writer( myInfo );
2050 writeInfo( &writer, ids );
2054 \brief Internal clean-up (reset widget)
2056 void SMESHGUI_SimpleElemInfo::clearInternal()
2061 void SMESHGUI_SimpleElemInfo::connectivityClicked(const QUrl & url)
2063 int type = ( url.scheme()[0] == 'n' ) ? NodeConnectivity : ElemConnectivity;
2064 QString ids = url.path(); // excess chars will be filtered off by SMESHGUI_IdValidator
2065 emit( itemInfo( type, ids ));
2068 ////////////////////////////////////////////////////////////////////////////////
2069 /// \class SMESHGUI_TreeElemInfo::ItemDelegate
2070 /// \brief Item delegate for tree mesh info widget.
2072 ////////////////////////////////////////////////////////////////////////////////
2074 class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate
2077 ItemDelegate( QObject* );
2078 QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
2085 SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ): QItemDelegate( parent )
2090 \brief Redefined from QItemDelegate.
2093 QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
2095 QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index );
2096 if ( qobject_cast<QLineEdit*>( w ) )
2097 qobject_cast<QLineEdit*>( w )->setReadOnly( true );
2101 ////////////////////////////////////////////////////////////////////////////////
2102 /// \class SMESHGUI_TreeElemInfo::ItemCreator
2103 /// \brief Item creator for tree mesh info widget.
2105 ////////////////////////////////////////////////////////////////////////////////
2107 class SMESHGUI_TreeElemInfo::ItemCreator : public TreeItemCreator
2109 SMESHGUI_TreeElemInfo* myView;
2111 ItemCreator( SMESHGUI_TreeElemInfo* );
2112 QTreeWidgetItem* createItem( QTreeWidgetItem*, int );
2117 \param view Parent view.
2120 SMESHGUI_TreeElemInfo::ItemCreator::ItemCreator( SMESHGUI_TreeElemInfo* view ): TreeItemCreator(), myView( view )
2125 \brief Create new tree item.
2126 \param parent Parent tree item.
2127 \param options Item options.
2128 \return New tree widget item.
2131 QTreeWidgetItem* SMESHGUI_TreeElemInfo::ItemCreator::createItem( QTreeWidgetItem* parent, int options )
2133 return myView->createItem( parent, options );
2136 ////////////////////////////////////////////////////////////////////////////////
2137 /// \class SMESHGUI_TreeElemInfo
2138 /// \brief Show mesh element information as the tree.
2139 ////////////////////////////////////////////////////////////////////////////////
2143 \param parent Parent widget. Defaults to 0.
2145 SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent )
2146 : SMESHGUI_ElemInfo( parent )
2148 myInfo = new QTreeWidget( centralWidget() );
2149 myInfo->setColumnCount( 2 );
2150 myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ) );
2151 myInfo->header()->setStretchLastSection( true );
2152 myInfo->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
2153 myInfo->setItemDelegate( new ItemDelegate( myInfo ) );
2154 QVBoxLayout* l = new QVBoxLayout( centralWidget() );
2156 l->addWidget( myInfo );
2157 connect( myInfo, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( itemDoubleClicked( QTreeWidgetItem*, int ) ) );
2158 connect( myInfo, SIGNAL( itemCollapsed( QTreeWidgetItem* )), this, SLOT( saveExpanded( QTreeWidgetItem* )) );
2159 connect( myInfo, SIGNAL( itemExpanded( QTreeWidgetItem* )), this, SLOT( saveExpanded( QTreeWidgetItem* )) );
2163 \brief Show mesh element information.
2164 \param ids Nodes / elements IDs.
2166 void SMESHGUI_TreeElemInfo::information( const QList<uint>& ids )
2169 TreeWriter writer( myInfo, new ItemCreator( this ) );
2170 writeInfo( &writer, ids );
2174 \brief Show node information
2175 \param node mesh node for showing
2176 \param index index of current node
2177 \param nbNodes number of unique nodes in element
2178 \param parentItem parent item of tree
2180 void SMESHGUI_TreeElemInfo::nodeInfo( const SMDS_MeshNode* /*node*/, int /*index*/,
2181 int /*nbNodes*/, QTreeWidgetItem* /*parentItem*/ )
2183 // int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
2184 // // node number and ID
2185 // QTreeWidgetItem* nodeItem = createItem( parentItem, Bold );
2186 // nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( SMESHGUI_ElemInfo::tr( "NODE" )).arg( index ).arg( nbNodes ));
2187 // nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ));
2188 // nodeItem->setData( 1, TypeRole, ElemConnectivity );
2189 // nodeItem->setData( 1, IdRole, node->GetID() );
2190 // nodeItem->setExpanded( false );
2191 // // node coordinates
2192 // QTreeWidgetItem* coordItem = createItem( nodeItem );
2193 // coordItem->setText( 0, SMESHGUI_ElemInfo::tr( "COORDINATES" ));
2194 // QTreeWidgetItem* xItem = createItem( coordItem );
2195 // xItem->setText( 0, "X" );
2196 // xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2197 // QTreeWidgetItem* yItem = createItem( coordItem );
2198 // yItem->setText( 0, "Y" );
2199 // yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2200 // QTreeWidgetItem* zItem = createItem( coordItem );
2201 // zItem->setText( 0, "Z" );
2202 // zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision )) );
2203 // // node connectivity
2204 // QTreeWidgetItem* nconItem = createItem( nodeItem );
2205 // nconItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONNECTIVITY" ));
2206 // Connectivity connectivity = nodeConnectivity( node );
2207 // if ( !connectivity.isEmpty() ) {
2208 // QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
2209 // if ( !con.isEmpty() ) {
2210 // QTreeWidgetItem* i = createItem( nconItem );
2211 // i->setText( 0, SMESHGUI_ElemInfo::tr( "0D_ELEMENTS" ));
2212 // i->setText( 1, con );
2214 // con = formatConnectivity( connectivity, SMDSAbs_Edge );
2215 // if ( !con.isEmpty() ) {
2216 // QTreeWidgetItem* i = createItem( nconItem );
2217 // i->setText( 0, SMESHGUI_ElemInfo::tr( "EDGES" ));
2218 // i->setText( 1, con );
2219 // i->setData( 1, TypeRole, NodeConnectivity );
2221 // con = formatConnectivity( connectivity, SMDSAbs_Ball );
2222 // if ( !con.isEmpty() ) {
2223 // QTreeWidgetItem* i = createItem( nconItem );
2224 // i->setText( 0, SMESHGUI_ElemInfo::tr( "BALL_ELEMENTS" ));
2225 // i->setText( 1, con );
2226 // i->setData( 1, TypeRole, NodeConnectivity );
2228 // con = formatConnectivity( connectivity, SMDSAbs_Face );
2229 // if ( !con.isEmpty() ) {
2230 // QTreeWidgetItem* i = createItem( nconItem );
2231 // i->setText( 0, SMESHGUI_ElemInfo::tr( "FACES" ));
2232 // i->setText( 1, con );
2233 // i->setData( 1, TypeRole, NodeConnectivity );
2235 // con = formatConnectivity( connectivity, SMDSAbs_Volume );
2236 // if ( !con.isEmpty() ) {
2237 // QTreeWidgetItem* i = createItem( nconItem );
2238 // i->setText( 0, SMESHGUI_ElemInfo::tr( "VOLUMES" ));
2239 // i->setText( 1, con );
2240 // i->setData( 1, TypeRole, NodeConnectivity );
2245 \brief Internal clean-up (reset widget)
2247 void SMESHGUI_TreeElemInfo::clearInternal()
2254 \brief Create new item and add it to the tree.
2255 \param parent Parent tree widget item. Defaults to 0 (top-level item).
2256 \param options Item flags. Defaults to 0 (none).
2257 \return New tree widget item.
2259 QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int options )
2261 QTreeWidgetItem* item = new QTreeWidgetItem( parent ? parent : myInfo->invisibleRootItem() );
2262 setTreeItemAttributes( item, options | Expanded | Editable );
2264 if ( parent && parent->childCount() == 1 && itemDepth( parent ) == 1 )
2266 QString resName = expandedResource( parent );
2267 parent->setExpanded( SMESHGUI::resourceMgr()->booleanValue("SMESH", resName, true ));
2273 void SMESHGUI_TreeElemInfo::contextMenuEvent( QContextMenuEvent* e )
2275 QList< QTreeWidgetItem* > widgets = myInfo->selectedItems();
2276 if ( widgets.isEmpty() ) return;
2277 QTreeWidgetItem* aTreeItem = widgets.first();
2278 int type = aTreeItem->data( 1, TypeRole ).toInt();
2279 if (( type == ElemConnectivity || type == NodeConnectivity ) &&
2280 ( !aTreeItem->text( 1 ).isEmpty() ))
2283 QAction* a = menu.addAction( tr( "SHOW_ITEM_INFO" ));
2284 if ( menu.exec( e->globalPos() ) == a )
2285 emit( itemInfo( type, aTreeItem->text( 1 )) );
2289 void SMESHGUI_TreeElemInfo::itemDoubleClicked( QTreeWidgetItem* theItem, int /*theColumn*/ )
2292 int type = theItem->data( 1, TypeRole ).toInt();
2293 emit( itemInfo( type, theItem->text( 1 )) );
2297 void SMESHGUI_TreeElemInfo::saveExpanded( QTreeWidgetItem* theItem )
2300 SMESHGUI::resourceMgr()->setValue("SMESH", expandedResource( theItem ), theItem->isExpanded() );
2303 QString SMESHGUI_TreeElemInfo::expandedResource( QTreeWidgetItem* theItem )
2305 return QString("Expanded_") + ( what()==ShowElements ? "E_" : "N_" ) + theItem->text(0);
2308 ////////////////////////////////////////////////////////////////////////////////
2309 /// \class InfoComputor
2310 /// \brief Mesh information computor.
2313 /// The class is created for different computation operations. Currently it is
2314 /// used to compute size and number of underlying nodes for given group.
2315 ////////////////////////////////////////////////////////////////////////////////
2319 \param parent Parent object.
2320 \param proxy Object to compute information on (group).
2321 \param item Tree widget item, referenced by this computer.
2322 \param operation Value to compute.
2325 InfoComputor::InfoComputor( QObject* parent, const SMESH::SelectionProxy& proxy, int operation )
2326 : QObject( parent ), myProxy( proxy ), myOperation( operation )
2331 \brief Compute requested information.
2334 void InfoComputor::compute()
2338 SUIT_OverrideCursor wc;
2340 switch ( myOperation )
2343 myProxy.size( true ); // force size computation
2347 myProxy.nbNodes( true ); // force size computation
2356 ////////////////////////////////////////////////////////////////////////////////
2357 /// \class SMESHGUI_AddInfo
2358 /// \brief Show additional information on selected object.
2360 /// Displays an additional information about selected object: mesh, sub-mesh
2363 /// \todo Rewrite saveInfo() method to print all data, not currently shown only.
2364 ////////////////////////////////////////////////////////////////////////////////
2368 \param parent Parent widget. Defaults to 0.
2370 SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent ): SMESHGUI_Info( parent )
2372 QVBoxLayout* l = new QVBoxLayout( this );
2374 l->setSpacing( SPACING );
2376 myTree = new QTreeWidget( this );
2378 myTree->setColumnCount( 2 );
2379 myTree->header()->setStretchLastSection( true );
2380 myTree->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
2381 myTree->header()->hide();
2383 l->addWidget( myTree );
2389 SMESHGUI_AddInfo::~SMESHGUI_AddInfo()
2394 \brief Show information on given object.
2395 \param proxy Object to show information on (mesh, sub-mesh, group).
2397 void SMESHGUI_AddInfo::showInfo( const SMESH::SelectionProxy& proxy )
2400 setProperty( "group_index", 0 );
2401 setProperty( "submesh_index", 0 );
2402 myComputors.clear();
2405 // then fill panel with data if object is not null
2411 QTreeWidgetItem* nameItem = createItem( 0, Bold | AllColumns );
2412 nameItem->setText( 0, tr( "NAME" ) );
2413 nameItem->setText( 1, proxy.name() );
2416 if ( proxy.type() == SMESH::SelectionProxy::Mesh )
2417 meshInfo( proxy, nameItem );
2418 else if ( proxy.type() == SMESH::SelectionProxy::Submesh )
2419 subMeshInfo( proxy, nameItem );
2420 else if ( proxy.type() >= SMESH::SelectionProxy::Group )
2421 groupInfo( proxy, nameItem );
2426 \brief Update information in panel.
2428 void SMESHGUI_AddInfo::updateInfo()
2430 showInfo( myProxy );
2434 \brief Reset panel (clear all data).
2436 void SMESHGUI_AddInfo::clear()
2442 \brief Create new item and add it to the tree.
2443 \param parent Parent tree widget item. Defaults to 0 (top-level item).
2444 \param options Item flags. Defaults to 0 (none).
2445 \return New tree widget item.
2447 QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int options )
2449 QTreeWidgetItem* item = parent ? new QTreeWidgetItem( parent ) :
2450 new QTreeWidgetItem( myTree->invisibleRootItem() );
2451 setTreeItemAttributes( item, options | Expanded );
2456 \brief Show information on mesh.
2457 \param proxy Proxy object (mesh).
2458 \param parent Parent tree item.
2460 void SMESHGUI_AddInfo::meshInfo( const SMESH::SelectionProxy& proxy, QTreeWidgetItem* parent )
2465 QString shapeName = proxy.shapeName();
2466 SMESH::MedInfo inf = proxy.medFileInfo();
2469 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2470 typeItem->setText( 0, tr( "TYPE" ) );
2471 if ( !shapeName.isEmpty() )
2473 typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ) );
2475 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2476 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2477 gobjItem->setText( 1, shapeName );
2479 else if ( inf.isValid() )
2481 typeItem->setText( 1, tr( "MESH_FROM_FILE" ) );
2482 // med file information
2483 QTreeWidgetItem* fileItem = createItem( parent, Bold );
2484 fileItem->setText( 0, tr( "FILE_NAME" ) );
2485 fileItem->setText( 1, inf.fileName() );
2486 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2487 sizeItem->setText( 0, tr( "FILE_SIZE" ) );
2488 sizeItem->setText( 1, QString::number( inf.size() ) );
2489 QTreeWidgetItem* versionItem = createItem( parent, Bold );
2490 versionItem->setText( 0, tr( "FILE_VERSION" ) );
2491 versionItem->setText( 1, inf.version() != "0" ? inf.version() : tr( "VERSION_UNKNOWN" ) );
2495 typeItem->setText( 1, tr( "STANDALONE_MESH" ) );
2499 myGroups = proxy.groups();
2503 mySubMeshes = proxy.submeshes();
2508 \brief Show information on sub-mesh.
2509 \param proxy Proxy object (sub-mesh).
2510 \param parent Parent tree item.
2512 void SMESHGUI_AddInfo::subMeshInfo( const SMESH::SelectionProxy& proxy, QTreeWidgetItem* parent )
2517 bool isShort = parent->parent() != 0;
2522 SMESH::SelectionProxy meshProxy = proxy.mesh();
2525 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2526 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2527 nameItem->setText( 1, meshProxy.name() );
2532 QString shapeName = proxy.shapeName();
2533 if ( !shapeName.isEmpty() )
2535 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2536 gobjItem->setText( 1, shapeName );
2541 \brief Show information on group.
2542 \param proxy Proxy object (group).
2543 \param parent Parent tree item.
2545 void SMESHGUI_AddInfo::groupInfo( const SMESH::SelectionProxy& proxy, QTreeWidgetItem* parent )
2550 bool isShort = parent->parent() != 0;
2555 SMESH::SelectionProxy meshProxy = proxy.mesh();
2558 QTreeWidgetItem* nameItem = createItem( parent, Bold );
2559 nameItem->setText( 0, tr( "PARENT_MESH" ) );
2560 nameItem->setText( 1, meshProxy.name() );
2565 SMESH::SelectionProxy::Type type = proxy.type();
2566 QTreeWidgetItem* typeItem = createItem( parent, Bold );
2567 typeItem->setText( 0, tr( "TYPE" ) );
2568 if ( type == SMESH::SelectionProxy::GroupStd )
2570 typeItem->setText( 1, tr( "STANDALONE_GROUP" ) );
2572 else if ( type == SMESH::SelectionProxy::GroupGeom )
2574 typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ) );
2576 QTreeWidgetItem* gobjItem = createItem( parent, Bold );
2577 gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
2578 gobjItem->setText( 1, proxy.shapeName() );
2580 else if ( type == SMESH::SelectionProxy::GroupFilter )
2582 typeItem->setText( 1, tr( "GROUP_ON_FILTER" ) );
2586 int etype = proxy.groupElementType();
2589 QString typeName = tr( "UNKNOWN" );
2593 typeName = tr( "NODE" );
2596 typeName = tr( "EDGE" );
2599 typeName = tr( "FACE" );
2602 typeName = tr( "VOLUME" );
2605 typeName = tr( "0DELEM" );
2608 typeName = tr( "BALL" );
2613 QTreeWidgetItem* etypeItem = createItem( parent, Bold );
2614 etypeItem->setText( 0, tr( "ENTITY_TYPE" ) );
2615 etypeItem->setText( 1, typeName );
2619 // note: size is not computed for group on filter for performance reasons, see IPAL52831
2620 bool meshLoaded = proxy.isMeshLoaded();
2621 int size = proxy.size();
2623 QTreeWidgetItem* sizeItem = createItem( parent, Bold );
2624 sizeItem->setText( 0, tr( "SIZE" ) );
2627 sizeItem->setText( 1, QString::number( size ) );
2631 QPushButton* btn = new QPushButton( meshLoaded ? tr( "COMPUTE" ) : tr( "LOAD" ), this );
2632 myTree->setItemWidget( sizeItem, 1, btn );
2633 InfoComputor* comp = new InfoComputor( this, proxy, InfoComputor::GrpSize );
2634 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2635 connect( comp, SIGNAL( computed() ), this, SLOT( updateInfo() ) );
2636 myComputors.append( comp );
2640 QTreeWidgetItem* colorItem = createItem( parent, Bold );
2641 colorItem->setText( 0, tr( "COLOR" ) );
2642 colorItem->setBackground( 1, proxy.color() );
2644 // nb of underlying nodes
2645 if ( etype != SMESH::NODE )
2647 QTreeWidgetItem* nodesItem = createItem( parent, Bold );
2648 nodesItem->setText( 0, tr( "NB_NODES" ) );
2650 int nbNodes = proxy.nbNodes();
2653 nodesItem->setText( 1, QString::number( nbNodes ) );
2657 QPushButton* btn = new QPushButton( meshLoaded ? tr( "COMPUTE" ) : tr( "LOAD" ), this );
2658 myTree->setItemWidget( nodesItem, 1, btn );
2659 InfoComputor* comp = new InfoComputor( this, proxy, InfoComputor::GrpNbNodes );
2660 connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
2661 connect( comp, SIGNAL( computed() ), this, SLOT( updateInfo() ) );
2662 myComputors.append( comp );
2668 \brief Update information on child groups.
2670 void SMESHGUI_AddInfo::showGroups()
2672 // remove all computors
2673 myComputors.clear();
2675 // tree root should be the first top level item
2676 QTreeWidgetItem* parent = myTree->topLevelItemCount() > 0 ? myTree->topLevelItem( 0 ) : 0;
2680 int idx = property( "group_index" ).toInt();
2682 // find sub-meshes top-level container item
2683 QTreeWidgetItem* itemGroups = 0;
2684 for ( int i = 0; i < parent->childCount() && !itemGroups; i++ )
2686 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GroupsId )
2688 itemGroups = parent->child( i );
2690 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( myTree->itemWidget( itemGroups, 1 ) );
2692 extra->updateControls( myGroups.count(), idx );
2693 // clear: remove all group items
2694 while ( itemGroups->childCount() )
2695 delete itemGroups->child( 0 );
2699 QMap<int, QTreeWidgetItem*> grpItems;
2700 for ( int i = idx*blockSize() ; i < qMin( (idx+1)*blockSize(), (int)myGroups.count() ); i++ )
2702 SMESH::SelectionProxy grp = myGroups[i];
2706 int grpType = grp.groupElementType();
2708 // create top-level groups container item if it does not exist
2711 itemGroups = createItem( parent, Bold | AllColumns );
2712 itemGroups->setText( 0, tr( "GROUPS" ) );
2713 itemGroups->setData( 0, Qt::UserRole, GroupsId );
2715 // if necessary, create extra widget to show information by chunks
2716 if ( myGroups.count() > blockSize() )
2718 ExtraWidget* extra = new ExtraWidget( this, true );
2719 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ) );
2720 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ) );
2721 myTree->setItemWidget( itemGroups, 1, extra );
2722 extra->updateControls( myGroups.count(), idx );
2726 // create container item corresponding to particular element type
2727 if ( !grpItems.contains( grpType ) )
2729 grpItems[ grpType ] = createItem( itemGroups, Bold | AllColumns );
2730 grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ) );
2731 itemGroups->insertChild( grpType-1, grpItems[ grpType ] ); // -1 needed since 0 corresponds to SMESH::ALL
2735 QTreeWidgetItem* nameItem = createItem( grpItems[ grpType ] );
2736 nameItem->setText( 0, grp.name().trimmed() ); // trim name
2739 groupInfo( grp, nameItem );
2744 \brief Update information on child sub-meshes.
2746 void SMESHGUI_AddInfo::showSubMeshes()
2748 // tree root should be the first top level item
2749 QTreeWidgetItem* parent = myTree->topLevelItemCount() > 0 ? myTree->topLevelItem( 0 ) : 0;
2753 int idx = property( "submesh_index" ).toInt();
2755 // find sub-meshes top-level container item
2756 QTreeWidgetItem* itemSubMeshes = 0;
2757 for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ )
2759 if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SubMeshesId )
2761 itemSubMeshes = parent->child( i );
2763 ExtraWidget* extra = dynamic_cast<ExtraWidget*>( myTree->itemWidget( itemSubMeshes, 1 ) );
2765 extra->updateControls( mySubMeshes.count(), idx );
2766 // clear: remove all sub-mesh items
2767 while ( itemSubMeshes->childCount() )
2768 delete itemSubMeshes->child( 0 );
2772 QMap<int, QTreeWidgetItem*> smItems;
2773 for ( int i = idx*blockSize() ; i < qMin( (idx+1)*blockSize(), mySubMeshes.count() ); i++ )
2775 SMESH::SelectionProxy sm = mySubMeshes[i];
2779 int smType = sm.shapeType();
2782 else if ( smType == GEOM::COMPSOLID )
2783 smType = GEOM::COMPOUND;
2785 // create top-level sub-meshes container item if it does not exist
2786 if ( !itemSubMeshes )
2788 itemSubMeshes = createItem( parent, Bold | AllColumns );
2789 itemSubMeshes->setText( 0, tr( "SUBMESHES" ) );
2790 itemSubMeshes->setData( 0, Qt::UserRole, SubMeshesId );
2792 // if necessary, create extra widget to show information by chunks
2793 if ( mySubMeshes.count() > blockSize() )
2795 ExtraWidget* extra = new ExtraWidget( this, true );
2796 connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ) );
2797 connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ) );
2798 myTree->setItemWidget( itemSubMeshes, 1, extra );
2799 extra->updateControls( mySubMeshes.count(), idx );
2803 // create container item corresponding to particular shape type
2804 if ( !smItems.contains( smType ) )
2806 smItems[ smType ] = createItem( itemSubMeshes, Bold | AllColumns );
2807 smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ) );
2808 itemSubMeshes->insertChild( smType, smItems[ smType ] );
2812 QTreeWidgetItem* nameItem = createItem( smItems[ smType ] );
2813 nameItem->setText( 0, sm.name().trimmed() ); // trim name
2816 subMeshInfo( sm, nameItem );
2821 \brief Show previous chunk of information on child groups.
2823 void SMESHGUI_AddInfo::showPreviousGroups()
2825 int idx = property( "group_index" ).toInt();
2826 setProperty( "group_index", idx-1 );
2831 \brief Show next chunk of information on child groups.
2833 void SMESHGUI_AddInfo::showNextGroups()
2835 int idx = property( "group_index" ).toInt();
2836 setProperty( "group_index", idx+1 );
2841 \brief Show previous chunk of information on child sub-meshes.
2843 void SMESHGUI_AddInfo::showPreviousSubMeshes()
2845 int idx = property( "submesh_index" ).toInt();
2846 setProperty( "submesh_index", idx-1 );
2851 \brief Show next chunk of information on child sub-meshes.
2853 void SMESHGUI_AddInfo::showNextSubMeshes()
2855 int idx = property( "submesh_index" ).toInt();
2856 setProperty( "submesh_index", idx+1 );
2861 \brief Write information from panel to output stream.
2862 \param out Text stream output.
2864 void SMESHGUI_AddInfo::saveInfo( QTextStream &out )
2867 QString title = tr( "ADDITIONAL_INFO" );
2868 out << ruler( title.size() ) << endl;
2869 out << title << endl;
2870 out << ruler( title.size() ) << endl;
2874 QTreeWidgetItemIterator it( myTree );
2877 if ( !( ( *it )->text(0) ).isEmpty() )
2879 out << indent( itemDepth( *it ) ) << ( *it )->text(0);
2880 if ( ( *it )->text(0) == tr( "COLOR" ) )
2881 out << ":" << spacing() << ( ( ( *it )->background(1) ).color() ).name();
2882 else if ( !( ( *it )->text(1) ).isEmpty() )
2883 out << ":" << spacing() << ( *it )->text(1);
2891 ////////////////////////////////////////////////////////////////////////////////
2892 /// \class GroupCombo
2893 /// \brief Customized combo box to manage list of mesh groups.
2895 ////////////////////////////////////////////////////////////////////////////////
2897 class GroupCombo: public QComboBox
2899 class Item: public QStandardItem
2902 SMESH::SelectionProxy myGroup;
2903 Item( const SMESH::SelectionProxy& group )
2906 setText( myGroup.name() );
2908 SMESH::SelectionProxy group()
2914 SMESH::SelectionProxy myProxy;
2917 GroupCombo( QWidget* );
2918 void setSource( const SMESH::SelectionProxy& );
2919 SMESH::SelectionProxy currentGroup() const;
2924 \param parent Parent widget.
2927 GroupCombo::GroupCombo( QWidget* parent ): QComboBox( parent )
2929 setModel( new QStandardItemModel( this ) );
2933 \brief Set mesh source.
2934 \param obj Mesh source.
2937 void GroupCombo::setSource( const SMESH::SelectionProxy& proxy )
2939 if ( myProxy == proxy )
2944 bool blocked = blockSignals( true );
2945 QStandardItemModel* m = dynamic_cast<QStandardItemModel*>( model() );
2950 if ( myProxy.type() == SMESH::SelectionProxy::Mesh )
2952 QList<SMESH::SelectionProxy> groups = myProxy.groups();
2953 for ( int i = 0; i < groups.count(); ++i )
2957 QString name = groups[i].name();
2958 if ( !name.isEmpty() )
2959 m->appendRow( new Item( groups[i] ) );
2962 setCurrentIndex( -1 ); // for performance reasons
2964 else if ( myProxy.type() >= SMESH::SelectionProxy::Group )
2966 m->appendRow( new Item( myProxy ) );
2967 setCurrentIndex( 0 );
2971 blockSignals( blocked );
2975 \brief Get currently selected group.
2976 \return Selected group.
2979 SMESH::SelectionProxy GroupCombo::currentGroup() const
2981 SMESH::SelectionProxy group;
2982 QStandardItemModel* m = dynamic_cast<QStandardItemModel*>( model() );
2983 if ( currentIndex() >= 0 )
2984 group = dynamic_cast<Item*>( m->item( currentIndex() ) )->group();
2988 ////////////////////////////////////////////////////////////////////////////////
2989 /// \class SMESHGUI_MeshInfoDlg
2990 /// \brief Mesh information dialog box
2992 /// \todo Move all business logic for element info to SMESHGUI_ElemInfo class.
2993 /// \todo Add selection button to reactivate selection on move from other dlg.
2994 ////////////////////////////////////////////////////////////////////////////////
2998 \param parent Parent widget.
2999 \param page Dialog page to show at start-up. Defaults to \c BaseInfo.
3001 SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
3005 setAttribute( Qt::WA_DeleteOnClose, true );
3006 setWindowTitle( tr( "MESH_INFO" ) );
3007 setSizeGripEnabled( true );
3009 myTabWidget = new QTabWidget( this );
3013 myBaseInfo = new SMESHGUI_BaseInfo( myTabWidget );
3014 myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ) );
3018 QWidget* w = new QWidget( myTabWidget );
3020 myMode = new QButtonGroup( this );
3021 myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
3022 myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
3023 myMode->addButton( new QRadioButton( tr( "GROUP_MODE" ), w ), GroupMode );
3024 myMode->button( NodeMode )->setChecked( true );
3025 myID = new QLineEdit( w );
3026 myID->setValidator( new SMESHGUI_IdValidator( this ) );
3027 myGroups = new GroupCombo( w );
3028 QStackedWidget* stack = new QStackedWidget( w );
3029 stack->addWidget( myID );
3030 stack->addWidget( myGroups );
3031 myIDPreviewCheck = new QCheckBox( tr( "SHOW_IDS" ), w );
3032 myIDPreview = new SMESHGUI_IdPreview( SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() ) );
3034 int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
3035 mode = qMin( 1, qMax( 0, mode ) );
3038 myElemInfo = new SMESHGUI_SimpleElemInfo( w );
3040 myElemInfo = new SMESHGUI_TreeElemInfo( w );
3041 stack->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
3043 QGridLayout* elemLayout = new QGridLayout( w );
3044 elemLayout->setMargin( MARGIN );
3045 elemLayout->setSpacing( SPACING );
3046 elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
3047 elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
3048 elemLayout->addWidget( myMode->button( GroupMode ), 0, 2 );
3049 elemLayout->addWidget( stack, 0, 3 );
3050 elemLayout->addWidget( myIDPreviewCheck, 1, 0, 1, 4 );
3051 elemLayout->addWidget( myElemInfo, 2, 0, 1, 4 );
3053 myTabWidget->addTab( w, tr( "ELEM_INFO" ) );
3057 myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
3058 myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ) );
3062 myCtrlInfo = new SMESHGUI_CtrlInfo( myTabWidget );
3063 myTabWidget->addTab( myCtrlInfo, tr( "CTRL_INFO" ) );
3067 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
3068 okBtn->setAutoDefault( true );
3069 okBtn->setDefault( true );
3071 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
3072 dumpBtn->setAutoDefault( true );
3073 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
3074 helpBtn->setAutoDefault( true );
3076 QHBoxLayout* btnLayout = new QHBoxLayout;
3077 btnLayout->setSpacing( SPACING );
3078 btnLayout->setMargin( 0 );
3080 btnLayout->addWidget( okBtn );
3081 btnLayout->addWidget( dumpBtn );
3082 btnLayout->addStretch( 10 );
3083 btnLayout->addWidget( helpBtn );
3087 QVBoxLayout* l = new QVBoxLayout ( this );
3088 l->setMargin( MARGIN );
3089 l->setSpacing( SPACING );
3090 l->addWidget( myTabWidget );
3091 l->addLayout( btnLayout );
3095 myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ) ) );
3097 // set-up connections
3099 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
3100 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
3101 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
3102 connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) );
3103 connect( myMode, SIGNAL( buttonClicked( int ) ), this, SLOT( modeChanged() ) );
3104 connect( myGroups, SIGNAL( currentIndexChanged( int ) ), this, SLOT( modeChanged() ) );
3105 connect( myID, SIGNAL( textChanged( QString ) ), this, SLOT( idChanged() ) );
3106 connect( myIDPreviewCheck, SIGNAL( toggled( bool ) ), this, SLOT( idPreviewChange( bool ) ) );
3107 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
3108 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
3109 connect( myElemInfo, SIGNAL( itemInfo( int, QString ) ), this, SLOT( showItemInfo( int, QString ) ) );
3110 connect( this, SIGNAL( switchMode( int ) ), stack, SLOT( setCurrentIndex( int ) ) );
3114 myIDPreviewCheck->setChecked( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "id_preview_resource", false ) );
3121 SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
3127 \brief Show mesh information on given object.
3128 \param io Interactive object.
3130 void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& io )
3133 showInfo( SMESH::SelectionProxy( io ) );
3137 \brief Show mesh information on given object.
3138 \param proxy Selection proxy.
3140 void SMESHGUI_MeshInfoDlg::showInfo( const SMESH::SelectionProxy& proxy )
3142 SUIT_OverrideCursor wc;
3149 SMESH::SMESH_IDSource_var obj = myProxy.object();
3152 myBaseInfo->showInfo( proxy );
3154 // "Additional info" tab
3155 myAddInfo->showInfo( proxy );
3157 // "Quality info" tab
3158 // Note: for performance reasons we update it only if it is currently active
3159 if ( myTabWidget->currentIndex() == CtrlInfo )
3160 myCtrlInfo->showInfo( proxy );
3162 // "Element info" tab
3163 myGroups->setSource( proxy );
3164 if ( myMode->checkedId() == GroupMode ) {
3165 SMESH::SelectionProxy group = myGroups->currentGroup();
3167 myElemInfo->showInfo( group );
3169 myElemInfo->clear();
3172 SVTK_Selector* selector = SMESH::GetSelector();
3175 if ( myProxy.actor() && selector ) { //todo: actor()?
3176 nb = myMode->checkedId() == NodeMode ?
3177 SMESH::GetNameOfSelectedElements( selector, myProxy.io(), ID ) :
3178 SMESH::GetNameOfSelectedNodes( selector, myProxy.io(), ID );
3181 myID->setText( ID.trimmed() );
3183 QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
3184 foreach ( ID, idTxt )
3185 ids << ID.trimmed().toUInt();
3186 myElemInfo->showInfo( proxy, ids, myMode->checkedId() == ElemMode );
3190 myElemInfo->clear();
3196 \brief Update information.
3198 void SMESHGUI_MeshInfoDlg::updateInfo()
3200 SALOME_ListIO selected;
3201 SMESHGUI::selectionMgr()->selectedObjects( selected );
3203 if ( selected.Extent() == 1 )
3204 showInfo( selected.First() );
3206 showInfo( myProxy );
3210 \brief Clean-up on dialog closing.
3212 void SMESHGUI_MeshInfoDlg::reject()
3214 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3215 selMgr->clearFilters();
3216 SMESH::SetPointRepresentation( false );
3217 if ( SVTK_ViewWindow* viewWindow = SMESH::GetViewWindow() )
3218 viewWindow->SetSelectionMode( ActorSelection );
3220 myIDPreview->SetPointsLabeled( false );
3224 \brief Process keyboard event.
3225 \param e Key press event.
3227 void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
3229 QDialog::keyPressEvent( e );
3230 if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
3237 \brief Set-up selection mode for currently selected page.
3239 void SMESHGUI_MeshInfoDlg::updateSelection()
3241 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
3243 disconnect( selMgr, 0, this, 0 );
3244 selMgr->clearFilters();
3246 int selMode = ActorSelection;
3247 if ( myTabWidget->currentIndex() == ElemInfo && myMode->checkedId() == NodeMode )
3248 selMode = NodeSelection;
3249 else if ( myTabWidget->currentIndex() == ElemInfo && myMode->checkedId() == ElemMode )
3250 selMode = CellSelection;
3251 SMESH::SetPointRepresentation( selMode == NodeSelection );
3252 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3253 aViewWindow->SetSelectionMode( selMode );
3255 SMESH::SelectionProxy previous = myProxy;
3256 QString ids = myID->text().trimmed();
3259 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3262 if ( myProxy && myProxy == previous && !ids.isEmpty() ) {
3263 myID->setText( ids );
3269 \brief Show documentation on selected dialog page.
3271 void SMESHGUI_MeshInfoDlg::help()
3273 QString helpPage = "mesh_infos.html";
3274 switch ( myTabWidget->currentIndex() )
3277 helpPage += "#advanced-mesh-infos-anchor";
3280 helpPage += "#mesh-element-info-anchor";
3283 helpPage += "#mesh-addition-info-anchor";
3286 helpPage += "#mesh-quality-info-anchor";
3291 SMESH::ShowHelpFile( helpPage );
3295 \brief Deactivate dialog box.
3297 void SMESHGUI_MeshInfoDlg::deactivate()
3299 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
3303 \brief Called when users switches between node / element modes.
3305 void SMESHGUI_MeshInfoDlg::modeChanged()
3307 emit( switchMode( myMode->checkedId() == GroupMode ? 1 : 0 ) );
3313 \brief Called when users prints mesh element ID in the corresponding field.
3315 void SMESHGUI_MeshInfoDlg::idChanged()
3317 myIDPreview->SetPointsLabeled( false );
3322 std::vector<int> idVec;
3323 std::list< gp_XYZ > aGrCentersXYZ;
3325 const bool isElem = ( myMode->checkedId() == ElemMode );
3326 QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
3327 foreach ( QString tid, idTxt ) {
3328 long id = tid.toUInt();
3329 if ( isElem ? myProxy.hasElement( id ) : myProxy.hasNode( id ))
3333 if ( isElem && myProxy.actor() && myProxy.elementGravityCenter( id, xyz ))
3335 idVec.push_back( id );
3336 aGrCentersXYZ.push_back( xyz );
3340 SVTK_Selector* selector = SMESH::GetSelector();
3341 if ( myProxy.actor() && selector ) {
3342 Handle(SALOME_InteractiveObject) IO = myProxy.actor()->getIO();
3343 selector->AddOrRemoveIndex( IO, ID, false );
3344 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3346 if ( myMode->checkedId() == NodeMode )
3347 myIDPreview->SetPointsData( myProxy.actor()->GetObject()->GetMesh(), ID );
3349 myIDPreview->SetElemsData( idVec, aGrCentersXYZ );
3351 bool showIDs = ( !ID.IsEmpty() &&
3352 myIDPreviewCheck->isChecked() &&
3353 myTabWidget->currentIndex() == ElemInfo );
3354 myIDPreview->SetPointsLabeled( showIDs, myProxy.actor()->GetVisibility() );
3356 aViewWindow->highlight( IO, true, true );
3357 aViewWindow->Repaint();
3360 myElemInfo->showInfo( myProxy, ids, isElem );
3365 * \brief Show IDs clicked
3367 void SMESHGUI_MeshInfoDlg::idPreviewChange( bool isOn )
3369 myIDPreview->SetPointsLabeled( isOn && !myID->text().simplified().isEmpty() );
3370 SMESHGUI::resourceMgr()->setValue("SMESH", "id_preview_resource", isOn );
3371 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
3372 aViewWindow->Repaint();
3375 void SMESHGUI_MeshInfoDlg::showItemInfo( int type, const QString& ids )
3377 if ( !ids.isEmpty() && ( type == NodeConnectivity || type == ElemConnectivity )) {
3378 myMode->button( type - NodeConnectivity )->click();
3379 myID->setText( ids );
3384 \brief Dump information to file.
3386 void SMESHGUI_MeshInfoDlg::dump()
3388 DumpFileDlg fd( this );
3389 fd.setWindowTitle( tr( "SAVE_INFO" ) );
3390 fd.setNameFilters( QStringList() << tr( "TEXT_FILES" ) );
3391 fd.setChecked( BaseInfo, SMESHGUI::resourceMgr()->booleanValue( "SMESH", "info_dump_base", true ) );
3392 fd.setChecked( ElemInfo, SMESHGUI::resourceMgr()->booleanValue( "SMESH", "info_dump_elem", true ) );
3393 fd.setChecked( AddInfo, SMESHGUI::resourceMgr()->booleanValue( "SMESH", "info_dump_add", true ) );
3394 fd.setChecked( CtrlInfo, SMESHGUI::resourceMgr()->booleanValue( "SMESH", "info_dump_ctrl", true ) );
3395 if ( fd.exec() == QDialog::Accepted )
3397 QString fileName = fd.selectedFile();
3398 if ( !fileName.isEmpty() ) {
3399 QFile file( fileName );
3400 if ( !file.open( QIODevice::WriteOnly | QIODevice::Text ) )
3403 QTextStream out( &file );
3404 if ( fd.isChecked( BaseInfo ) ) myBaseInfo->saveInfo( out );
3405 if ( fd.isChecked( ElemInfo ) ) myElemInfo->saveInfo( out );
3406 if ( fd.isChecked( AddInfo ) ) myAddInfo->saveInfo( out );
3407 if ( fd.isChecked( CtrlInfo ) )
3409 myCtrlInfo->showInfo( myProxy ); // it saves what is shown only
3410 myCtrlInfo->saveInfo( out );
3416 ////////////////////////////////////////////////////////////////////////////////
3417 /// \class SMESHGUI_CtrlInfo
3418 /// \brief Show quality statistics information on selected object.
3420 /// Displays quality controls statistics about selected object: mesh, sub-mesh,
3421 /// group or arbitrary ID source.
3422 ////////////////////////////////////////////////////////////////////////////////
3426 \param parent Parent widget. Defaults to 0.
3428 SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent ): SMESHGUI_Info( parent )
3430 QGridLayout* l = new QGridLayout( this );
3431 l->setMargin( MARGIN );
3432 l->setSpacing( SPACING );
3434 QIcon aComputeIcon( SUIT_Session::session()->resourceMgr()->loadPixmap( "SMESH", tr( "ICON_COMPUTE" ) ) );
3435 SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
3437 // QToolBox with MeshInfo
3438 myMeshTB = new QToolBox(this);
3441 QLabel* aNameLab = createLabel( tr( "NAME_LAB" ), this, Bold );
3442 QLabel* aName = createField( this, "ctrlName" );
3443 aName->setMinimumWidth( 150 );
3447 QLabel* aNodesLab = createLabel( tr( "NODES_INFO" ), this, Bold );
3448 QLabel* aNodesFreeLab = new QLabel( tr( "NUMBER_OF_THE_FREE_NODES" ), this );
3449 QLabel* aNodesFree = createField( this, "ctrlNodesFree" );
3450 myWidgets << aNodesFree;
3451 myPredicates << aFilterMgr->CreateFreeNodes();
3453 QLabel* aNodesNbConnLab = new QLabel( tr( "MAX_NODE_CONNECTIVITY" ), this );
3454 QLabel* aNodesNbConn = createField( this, "ctrlNodesCnty" );
3455 myWidgets << aNodesNbConn;
3456 myNodeConnFunctor = aFilterMgr->CreateNodeConnectivityNumber();
3458 QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this );
3459 QLabel* aNodesDouble = createField( this, "ctrlNodesDouble" );
3460 myWidgets << aNodesDouble;
3461 myPredicates << aFilterMgr->CreateEqualNodes();
3462 QLabel* aToleranceLab = new QLabel( tr( "DOUBLE_NODES_TOLERANCE" ), this );
3463 myToleranceWidget = new SMESHGUI_SpinBox( this );
3464 myToleranceWidget->RangeStepAndValidator(0.0000000001, 1000000.0, 0.0000001, "length_precision" );
3465 myToleranceWidget->setAcceptNames( false );
3466 myToleranceWidget->SetValue( SMESHGUI::resourceMgr()->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 ) );
3469 QLabel* anEdgesLab = createLabel( tr( "EDGES_INFO" ), this, Bold );
3470 QLabel* anEdgesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_EDGES" ), this );
3471 QLabel* anEdgesDouble = createField( this, "ctrlEdgesDouble" );
3472 myWidgets << anEdgesDouble;
3473 myPredicates << aFilterMgr->CreateEqualEdges();
3476 QLabel* aFacesLab = createLabel( tr( "FACES_INFO" ), this, Bold );
3477 QLabel* aFacesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_FACES" ), this );
3478 QLabel* aFacesDouble = createField( this, "ctrlFacesDouble" );
3479 myWidgets << aFacesDouble;
3480 myPredicates << aFilterMgr->CreateEqualFaces();
3481 QLabel* aFacesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3482 QLabel* aFacesOver = createField( this, "ctrlFacesOver" );
3483 myWidgets << aFacesOver;
3484 myPredicates << aFilterMgr->CreateOverConstrainedFace();
3485 QLabel* anAspectRatioLab = new QLabel( tr( "ASPECT_RATIO_HISTOGRAM" ), this );
3486 myPlot = createPlot( this );
3487 myAspectRatio = aFilterMgr->CreateAspectRatio();
3490 QLabel* aVolumesLab = createLabel( tr( "VOLUMES_INFO" ), this, Bold );
3491 QLabel* aVolumesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ), this );
3492 QLabel* aVolumesDouble = createField( this, "ctrlVolumesDouble" );
3493 myWidgets << aVolumesDouble;
3494 myPredicates << aFilterMgr->CreateEqualVolumes();
3495 QLabel* aVolumesOverLab = new QLabel( tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ), this );
3496 QLabel* aVolumesOver = createField( this, "ctrlVolumesOver" );
3497 myWidgets << aVolumesOver;
3498 myPredicates << aFilterMgr->CreateOverConstrainedVolume();
3499 QLabel* anAspectRatio3DLab = new QLabel( tr( "ASPECT_RATIO_3D_HISTOGRAM" ), this );
3500 myPlot3D = createPlot( this );
3501 myAspectRatio3D = aFilterMgr->CreateAspectRatio3D();
3503 QToolButton* aFreeNodesBtn = new QToolButton( this );
3504 aFreeNodesBtn->setIcon(aComputeIcon);
3505 myButtons << aFreeNodesBtn; //0
3507 QToolButton* aNodesNbConnBtn = new QToolButton( this );
3508 aNodesNbConnBtn->setIcon(aComputeIcon);
3509 myButtons << aNodesNbConnBtn; //1
3511 QToolButton* aDoubleNodesBtn = new QToolButton( this );
3512 aDoubleNodesBtn->setIcon(aComputeIcon);
3513 myButtons << aDoubleNodesBtn; //2
3515 QToolButton* aDoubleEdgesBtn = new QToolButton( this );
3516 aDoubleEdgesBtn->setIcon(aComputeIcon);
3517 myButtons << aDoubleEdgesBtn; //3
3519 QToolButton* aDoubleFacesBtn = new QToolButton( this );
3520 aDoubleFacesBtn->setIcon(aComputeIcon);
3521 myButtons << aDoubleFacesBtn; //4
3523 QToolButton* aOverContFacesBtn = new QToolButton( this );
3524 aOverContFacesBtn->setIcon(aComputeIcon);
3525 myButtons << aOverContFacesBtn; //5
3527 QToolButton* aComputeFaceBtn = new QToolButton( this );
3528 aComputeFaceBtn->setIcon(aComputeIcon);
3529 myButtons << aComputeFaceBtn; //6
3531 QToolButton* aDoubleVolumesBtn = new QToolButton( this );
3532 aDoubleVolumesBtn->setIcon(aComputeIcon);
3533 myButtons << aDoubleVolumesBtn; //7
3535 QToolButton* aOverContVolumesBtn = new QToolButton( this );
3536 aOverContVolumesBtn->setIcon(aComputeIcon);
3537 myButtons << aOverContVolumesBtn; //8
3539 QToolButton* aComputeVolumeBtn = new QToolButton( this );
3540 aComputeVolumeBtn->setIcon(aComputeIcon);
3541 myButtons << aComputeVolumeBtn; //9
3543 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ) );
3544 connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ) );
3545 connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) );
3546 connect( aNodesNbConnBtn, SIGNAL( clicked() ), this, SLOT( computeNodesNbConnInfo() ) );
3547 connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ) );
3548 connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ) );
3549 connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ) );
3550 connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ) );
3551 connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ) );
3552 connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) );
3553 connect( myToleranceWidget, SIGNAL( valueChanged( double ) ), this, SLOT( setTolerance( double ) ) );
3554 this->setTolerance(myToleranceWidget->GetValue());
3556 l->addWidget( aNameLab, 0, 0 ); //0
3557 l->addWidget( aName, 0, 1 ); //1
3560 QWidget* NodeGrp = new QWidget();
3561 QGridLayout* NodeLayout = new QGridLayout(NodeGrp);
3562 NodeLayout->setSpacing(SPACING); NodeLayout->setMargin(MARGIN);
3564 NodeLayout->addWidget( aNodesFreeLab, 0, 0 );
3565 NodeLayout->addWidget( aNodesFree, 0, 1 );
3566 NodeLayout->addWidget( aFreeNodesBtn, 0, 2 );
3567 NodeLayout->addWidget( aNodesNbConnLab, 1, 0 );
3568 NodeLayout->addWidget( aNodesNbConn, 1, 1 );
3569 NodeLayout->addWidget( aNodesNbConnBtn, 1, 2 );
3570 NodeLayout->addWidget( aNodesDoubleLab, 2, 0 );
3571 NodeLayout->addWidget( aNodesDouble, 2, 1 );
3572 NodeLayout->addWidget( aDoubleNodesBtn, 2, 2 );
3573 NodeLayout->addWidget( aToleranceLab, 3, 0 );
3574 NodeLayout->addWidget( myToleranceWidget, 3, 1 );
3575 NodeLayout->addWidget( myToleranceWidget, 3, 1 );
3576 NodeLayout->setRowStretch(4, 5);
3578 myMeshTB->addItem(NodeGrp, aNodesLab->text());
3579 aNodesLab->setVisible(false);
3582 QWidget* EdgeGrp = new QWidget();
3583 QGridLayout* EdgeLayout = new QGridLayout(EdgeGrp);
3584 EdgeLayout->setSpacing(SPACING); EdgeLayout->setMargin(MARGIN);
3586 EdgeLayout->addWidget( anEdgesDoubleLab, 0, 0 );
3587 EdgeLayout->addWidget( anEdgesDouble, 0, 1 );
3588 EdgeLayout->addWidget( aDoubleEdgesBtn, 0, 2 );
3589 EdgeLayout->setRowStretch(1, 5);
3591 myMeshTB->addItem(EdgeGrp, anEdgesLab->text());
3592 anEdgesLab->setVisible(false);
3595 QWidget* FaceGrp = new QWidget();
3596 QGridLayout* FaceLayout = new QGridLayout(FaceGrp);
3597 FaceLayout->setSpacing(SPACING); FaceLayout->setMargin(MARGIN);
3599 FaceLayout->addWidget( aFacesDoubleLab, 0, 0 );
3600 FaceLayout->addWidget( aFacesDouble, 0, 1 );
3601 FaceLayout->addWidget( aDoubleFacesBtn, 0, 2 );
3602 FaceLayout->addWidget( aFacesOverLab, 1, 0 );
3603 FaceLayout->addWidget( aFacesOver, 1, 1 );
3604 FaceLayout->addWidget( aOverContFacesBtn, 1, 2 );
3605 FaceLayout->addWidget( anAspectRatioLab, 2, 0 );
3606 FaceLayout->addWidget( aComputeFaceBtn, 2, 2 );
3607 FaceLayout->addWidget( myPlot, 3, 0, 1, 3 );
3609 myMeshTB->addItem(FaceGrp, aFacesLab->text());
3610 aFacesLab->setVisible(false);
3613 QWidget* VolumeGrp = new QWidget();
3614 QGridLayout* VolumeLayout = new QGridLayout(VolumeGrp);
3615 VolumeLayout->setSpacing(SPACING); VolumeLayout->setMargin(MARGIN);
3617 VolumeLayout->addWidget( aVolumesDoubleLab, 0, 0 );
3618 VolumeLayout->addWidget( aVolumesDouble, 0, 1 );
3619 VolumeLayout->addWidget( aDoubleVolumesBtn, 0, 2 );
3620 VolumeLayout->addWidget( aVolumesOverLab, 1, 0 );
3621 VolumeLayout->addWidget( aVolumesOver, 1, 1 );
3622 VolumeLayout->addWidget( aOverContVolumesBtn,1, 2 );
3623 VolumeLayout->addWidget( anAspectRatio3DLab, 2, 0 );
3624 VolumeLayout->addWidget( aComputeVolumeBtn, 2, 2 );
3625 VolumeLayout->addWidget( myPlot3D, 3, 0, 1, 3 );
3627 myMeshTB->addItem(VolumeGrp, aVolumesLab->text());
3628 aVolumesLab->setVisible(false);
3630 l->addWidget( myMeshTB, 1, 0, 1, 2 ); //2
3631 l->setRowStretch( 2, 5 );
3639 SMESHGUI_CtrlInfo::~SMESHGUI_CtrlInfo()
3644 \brief Create plot widget.
3645 \param parent Parent widget.
3646 \return New plot widget.
3648 QwtPlot* SMESHGUI_CtrlInfo::createPlot( QWidget* parent )
3650 QwtPlot* aPlot = new QwtPlot( parent );
3651 aPlot->setMinimumSize( 100, 100 );
3652 QFont xFont = aPlot->axisFont( QwtPlot::xBottom );
3653 xFont.setPointSize( 5 );
3654 QFont yFont = aPlot->axisFont( QwtPlot::yLeft );
3655 yFont.setPointSize( 5 );
3656 aPlot->setAxisFont( QwtPlot::xBottom, xFont );
3657 aPlot->setAxisFont( QwtPlot::yLeft, yFont );
3663 \brief Show information on given object.
3664 \param proxy Object to show information on (mesh, sub-mesh, group, ID source).
3666 void SMESHGUI_CtrlInfo::showInfo( const SMESH::SelectionProxy& proxy )
3674 SMESH::SMESH_IDSource_var obj = proxy.object();
3676 myWidgets[0]->setText( proxy.name() );
3678 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3679 if ( mesh->_is_nil() ) return;
3681 const bool meshLoaded = mesh->IsLoaded();
3682 if ( !meshLoaded ) // mesh not yet loaded from the hdf file
3683 // enable Compute buttons, just in case obj->GetNbElementsByType() fails
3684 for ( int i = 0; i < myButtons.count(); ++i )
3685 myButtons[i]->setEnabled( true );
3687 SMESH::smIdType_array_var nbElemsByType = obj->GetNbElementsByType();
3688 if ( ! &nbElemsByType.in() ) return;
3690 const CORBA::Long ctrlLimit =
3691 meshLoaded ? SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_controls_limit", 3000 ) : -1;
3694 const SMESH::smIdType nbNodes = nbElemsByType[ SMESH::NODE ];
3695 // const CORBA::Long nbElems = ( nbElemsByType[ SMESH::EDGE ] +
3696 // nbElemsByType[ SMESH::FACE ] +
3697 // nbElemsByType[ SMESH::VOLUME ] );
3698 if ( nbNodes > 0 ) {
3699 if ( nbNodes <= ctrlLimit ) {
3701 computeFreeNodesInfo();
3702 // node connectivity number
3703 computeNodesNbConnInfo();
3705 computeDoubleNodesInfo();
3708 myButtons[0]->setEnabled( true );
3709 myButtons[1]->setEnabled( true );
3710 myButtons[2]->setEnabled( true );
3714 myMeshTB->setItemEnabled(0, false );
3715 myMeshTB->widget(0)->setVisible( false );
3719 if ( nbElemsByType[ SMESH::EDGE ] > 0 ) {
3721 if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit )
3722 computeDoubleEdgesInfo();
3724 myButtons[3]->setEnabled( true );
3727 myMeshTB->setItemEnabled(1, false );
3728 myMeshTB->widget(1)->setVisible( false );
3732 if ( nbElemsByType[ SMESH::FACE ] > 0 ) {
3733 if ( nbElemsByType[ SMESH::FACE ] <= ctrlLimit ) {
3735 computeDoubleFacesInfo();
3736 // over constrained faces
3737 computeOverConstrainedFacesInfo();
3738 // aspect Ratio histogram
3739 computeAspectRatio();
3742 myButtons[4]->setEnabled( true );
3743 myButtons[5]->setEnabled( true );
3744 myButtons[6]->setEnabled( true );
3748 myMeshTB->setItemEnabled(2, false );
3749 myMeshTB->widget(2)->setVisible( false );
3753 if ( nbElemsByType[ SMESH::VOLUME ] > 0 ) {
3754 if ( nbElemsByType[ SMESH::VOLUME ] <= ctrlLimit ) {
3756 computeDoubleVolumesInfo();
3757 // over constrained volumes
3758 computeOverConstrainedVolumesInfo();
3759 // aspect Ratio 3D histogram
3760 computeAspectRatio3D();
3763 myButtons[7]->setEnabled( true );
3764 myButtons[8]->setEnabled( true );
3765 myButtons[9]->setEnabled( true );
3769 myMeshTB->setItemEnabled(3, false );
3770 myMeshTB->widget(3)->setVisible( false );
3772 myMeshTB->setCurrentIndex(0);
3773 myMeshTB->setVisible( (nbNodes + nbElemsByType[ SMESH::EDGE ] +
3774 nbElemsByType[ SMESH::FACE ] +
3775 nbElemsByType[ SMESH::VOLUME ]) > 0 );
3778 //================================================================================
3780 * \brief Computes and shows nb of elements satisfying a given predicate
3781 * \param [in] ft - a predicate type (SMESH::FunctorType)
3782 * \param [in] iBut - index of one of myButtons to disable
3783 * \param [in] iWdg - index of one of myWidgets to show the computed number
3785 //================================================================================
3787 void SMESHGUI_CtrlInfo::computeNb( int ft, int iBut, int iWdg )
3789 myButtons[ iBut ]->setEnabled( false );
3790 myWidgets[ iWdg ]->setText( "" );
3795 SUIT_OverrideCursor wc;
3797 SMESH::SMESH_IDSource_var obj = myProxy.object();
3798 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3800 if ( !mesh->_is_nil() && !mesh->IsLoaded() )
3803 showInfo( myProxy ); // try to show all values
3804 if ( !myWidgets[ iWdg ]->text().isEmpty() )
3805 return; // <ft> predicate already computed
3807 // look for a predicate of type <ft>
3808 for ( int i = 0; i < myPredicates.count(); ++i )
3809 if ( myPredicates[i]->GetFunctorType() == ft )
3811 CORBA::Long nb = myPredicates[i]->NbSatisfying( obj );
3812 myWidgets[ iWdg ]->setText( QString::number( nb ) );
3816 void SMESHGUI_CtrlInfo::computeFreeNodesInfo()
3818 computeNb( SMESH::FT_FreeNodes, 0, 1 );
3821 void SMESHGUI_CtrlInfo::computeDoubleNodesInfo()
3823 computeNb( SMESH::FT_EqualNodes, 2, 3 );
3826 void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo()
3828 computeNb( SMESH::FT_EqualEdges, 3, 4 );
3831 void SMESHGUI_CtrlInfo::computeDoubleFacesInfo()
3833 computeNb( SMESH::FT_EqualFaces, 4, 5 );
3836 void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo()
3838 computeNb( SMESH::FT_OverConstrainedFace, 5, 6 );
3841 void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo()
3843 computeNb( SMESH::FT_EqualVolumes, 7, 7 );
3846 void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
3848 computeNb( SMESH::FT_OverConstrainedVolume, 8, 8 );
3851 void SMESHGUI_CtrlInfo::computeNodesNbConnInfo()
3853 myButtons[ 1 ]->setEnabled( false );
3854 myWidgets[ 2 ]->setText( "" );
3859 SUIT_OverrideCursor wc;
3861 SMESH::SMESH_IDSource_var obj = myProxy.object();
3862 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3864 if ( !mesh->IsLoaded() )
3867 showInfo( myProxy ); // try to show all values
3868 if ( !myWidgets[ 2 ]->text().isEmpty() )
3869 return; // already computed
3871 myNodeConnFunctor->SetMesh( mesh );
3872 SMESH::Histogram_var histogram =
3873 myNodeConnFunctor->GetLocalHistogram( 1, /*isLogarithmic=*/false, obj );
3875 myWidgets[ 2 ]->setText( QString::number( histogram[0].max ) );
3878 void SMESHGUI_CtrlInfo::computeAspectRatio()
3880 #ifndef DISABLE_PLOT2DVIEWER
3881 myButtons[6]->setEnabled( false );
3886 SUIT_OverrideCursor wc;
3888 SMESH::SMESH_IDSource_var obj = myProxy.object();
3889 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3891 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio );
3892 if ( aHistogram && !aHistogram->isEmpty() ) {
3893 QwtPlotItem* anItem = aHistogram->createPlotItem();
3894 anItem->attach( myPlot );
3901 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
3903 #ifndef DISABLE_PLOT2DVIEWER
3904 myButtons[9]->setEnabled( false );
3909 SUIT_OverrideCursor wc;
3911 SMESH::SMESH_IDSource_var obj = myProxy.object();
3912 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3914 Plot2d_Histogram* aHistogram = getHistogram( myAspectRatio3D );
3915 if ( aHistogram && !aHistogram->isEmpty() ) {
3916 QwtPlotItem* anItem = aHistogram->createPlotItem();
3917 anItem->attach( myPlot3D );
3925 \brief Internal clean-up (reset widget)
3927 void SMESHGUI_CtrlInfo::clearInternal()
3929 for (int i=0; i<=3;i++) {
3930 myMeshTB->setItemEnabled(i, true );
3931 myMeshTB->widget(i)->setVisible( true );
3933 for( int i=0; i<=9; i++)
3934 myButtons[i]->setEnabled( false );
3935 myPlot->detachItems();
3936 myPlot3D->detachItems();
3939 myWidgets[0]->setText( QString() );
3940 for ( int i = 1; i < myWidgets.count(); i++ )
3941 myWidgets[i]->setText( "" );
3944 void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
3946 myButtons[2]->setEnabled( true );
3947 myWidgets[3]->setText("");
3948 for ( int i = 0; i < myPredicates.count(); ++i )
3949 if ( myPredicates[i]->GetFunctorType() == SMESH::FT_EqualNodes )
3951 SMESH::EqualNodes_var functor = SMESH::EqualNodes::_narrow( myPredicates[i] );
3952 if ( !functor->_is_nil() )
3953 functor->SetTolerance( theTolerance );
3957 #ifndef DISABLE_PLOT2DVIEWER
3958 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
3960 SUIT_OverrideCursor wc;
3962 SMESH::SMESH_IDSource_var obj = myProxy.object();
3963 SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
3965 if ( !mesh->IsLoaded() )
3967 aNumFun->SetMesh( mesh );
3969 CORBA::Long cprecision = 6;
3970 if ( SMESHGUI::resourceMgr()->booleanValue( "SMESH", "use_precision", false ) )
3971 cprecision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "controls_precision", -1 );
3972 aNumFun->SetPrecision( cprecision );
3974 int nbIntervals = SMESHGUI::resourceMgr()->integerValue( "SMESH", "scalar_bar_num_colors", false );
3976 SMESH::Histogram_var histogramVar = aNumFun->GetLocalHistogram( nbIntervals,
3977 /*isLogarithmic=*/false,
3979 Plot2d_Histogram* aHistogram = new Plot2d_Histogram();
3980 aHistogram->setColor( palette().color( QPalette::Highlight ) );
3981 if ( &histogramVar.in() )
3983 for ( size_t i = 0, nb = histogramVar->length(); i < nb; i++ )
3984 aHistogram->addPoint( 0.5 * ( histogramVar[i].min + histogramVar[i].max ), histogramVar[i].nbEvents );
3985 if ( histogramVar->length() >= 2 )
3986 aHistogram->setWidth( ( histogramVar[0].max - histogramVar[0].min ) * 0.8 );
3992 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out )
3995 QString title = tr( "CTRL_INFO" );
3996 out << ruler( title.size() ) << endl;
3997 out << title << endl;
3998 out << ruler( title.size() ) << endl;
4002 out << tr( "NAME_LAB" ) << " " << myWidgets[0]->text() << endl;
4003 out << tr( "NODES_INFO" ) << endl;
4004 out << indent() << tr( "NUMBER_OF_THE_FREE_NODES" ) << ": " << myWidgets[1]->text() << endl;
4005 out << indent() << tr( "NUMBER_OF_THE_DOUBLE_NODES" ) << ": " << myWidgets[3]->text() << endl;
4006 out << tr( "EDGES_INFO" ) << endl;
4007 out << indent() << tr( "NUMBER_OF_THE_DOUBLE_EDGES" ) << ": " << myWidgets[4]->text() << endl;
4008 out << tr( "FACES_INFO" ) << endl;
4009 out << indent() << tr( "NUMBER_OF_THE_DOUBLE_FACES" ) << ": " << myWidgets[5]->text() << endl;
4010 out << indent() << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[6]->text() << endl;
4011 out << tr( "VOLUMES_INFO" ) << endl;
4012 out << indent() << tr( "NUMBER_OF_THE_DOUBLE_VOLUMES" ) << ": " << myWidgets[7]->text() << endl;
4013 out << indent() << tr( "NUMBER_OF_THE_OVER_CONSTRAINED" ) << ": " << myWidgets[8]->text() << endl;
4016 ////////////////////////////////////////////////////////////////////////////////
4017 /// \class SMESHGUI_CtrlInfoDlg
4018 /// \brief Overall Mesh Quality dialog.
4019 /// \todo Add selection button to reactivate selection on move from other dlg.
4020 ////////////////////////////////////////////////////////////////////////////////
4024 \param parent parent widget
4026 SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent )
4029 setAttribute( Qt::WA_DeleteOnClose, true );
4030 setWindowTitle( tr( "CTRL_INFO" ) );
4031 setMinimumSize( 400, 600 );
4033 myCtrlInfo = new SMESHGUI_CtrlInfo( this );
4036 QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
4037 okBtn->setAutoDefault( true );
4038 okBtn->setDefault( true );
4040 QPushButton* dumpBtn = new QPushButton( tr( "BUT_DUMP_MESH" ), this );
4041 dumpBtn->setAutoDefault( true );
4042 QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
4043 helpBtn->setAutoDefault( true );
4045 QHBoxLayout* btnLayout = new QHBoxLayout;
4046 btnLayout->setSpacing( SPACING );
4047 btnLayout->setMargin( 0 );
4049 btnLayout->addWidget( okBtn );
4050 btnLayout->addWidget( dumpBtn );
4051 btnLayout->addStretch( 10 );
4052 btnLayout->addWidget( helpBtn );
4054 QVBoxLayout* l = new QVBoxLayout ( this );
4056 l->setSpacing( SPACING );
4057 l->addWidget( myCtrlInfo );
4058 l->addLayout( btnLayout );
4060 connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
4061 connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dump() ) );
4062 connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) );
4063 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
4064 connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
4072 SMESHGUI_CtrlInfoDlg::~SMESHGUI_CtrlInfoDlg()
4077 \brief Show mesh quality information on given object.
4078 \param io Interactive object.
4080 void SMESHGUI_CtrlInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& io )
4083 showInfo( SMESH::SelectionProxy( io ) );
4087 \brief Show mesh quality information on given object.
4088 \param proxy Selection proxy.
4090 void SMESHGUI_CtrlInfoDlg::showInfo( const SMESH::SelectionProxy& proxy )
4092 SUIT_OverrideCursor wc;
4098 myCtrlInfo->showInfo( proxy );
4102 \brief Show mesh information
4104 void SMESHGUI_CtrlInfoDlg::updateInfo()
4106 SALOME_ListIO selected;
4107 SMESHGUI::selectionMgr()->selectedObjects( selected );
4109 if ( selected.Extent() == 1 )
4110 showInfo( selected.First() );
4112 showInfo( myProxy );
4116 \brief Perform clean-up actions on the dialog box closing.
4118 void SMESHGUI_CtrlInfoDlg::reject()
4120 SMESH::SetPointRepresentation( false );
4125 \brief Setup selection mode depending on the current dialog box state.
4127 void SMESHGUI_CtrlInfoDlg::updateSelection()
4129 LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
4130 disconnect( selMgr, 0, this, 0 );
4131 SMESH::SetPointRepresentation( false );
4132 connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
4137 \brief Deactivate dialog box.
4139 void SMESHGUI_CtrlInfoDlg::deactivate()
4141 disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
4145 \brief Dump information to file.
4147 void SMESHGUI_CtrlInfoDlg::dump()
4149 DumpFileDlg fd( this, false );
4150 fd.setWindowTitle( tr( "SAVE_INFO" ) );
4151 fd.setNameFilters( QStringList() << tr( "TEXT_FILES" ) );
4152 if ( fd.exec() == QDialog::Accepted )
4154 QString fileName = fd.selectedFile();
4155 if ( !fileName.isEmpty() ) {
4156 QFile file( fileName );
4157 if ( !file.open( QIODevice::WriteOnly | QIODevice::Text ) )
4160 QTextStream out( &file );
4161 myCtrlInfo->saveInfo( out );
4167 \brief Show documentation on dialog.
4169 void SMESHGUI_CtrlInfoDlg::help()
4171 SMESH::ShowHelpFile( "mesh_infos.html#mesh-quality-info-anchor" );