From: jfa Date: Tue, 9 Aug 2005 11:31:29 +0000 (+0000) Subject: Add in GUI control for merging equal elements X-Git-Tag: T_3_0_2a1~34 X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=commitdiff_plain;h=60528ce3265d5130f3640c0a7947ff8f738705d5 Add in GUI control for merging equal elements --- diff --git a/Makefile.in b/Makefile.in index c659cb280..7dd628514 100644 --- a/Makefile.in +++ b/Makefile.in @@ -119,6 +119,7 @@ mesh_sew_conform_freeborders.png \ mesh_sew_bordertoside.png \ mesh_sew_sideelements.png \ mesh_merge_nodes.png \ +mesh_merge_elements.png \ select1.png \ SMESH_en.xml \ SMESH.config \ diff --git a/resources/mesh_merge_elements.png b/resources/mesh_merge_elements.png new file mode 100644 index 000000000..3bc292fc4 Binary files /dev/null and b/resources/mesh_merge_elements.png differ diff --git a/src/SMESHGUI/Makefile.in b/src/SMESHGUI/Makefile.in index 2833cf2a3..ec0cf92b5 100644 --- a/src/SMESHGUI/Makefile.in +++ b/src/SMESHGUI/Makefile.in @@ -96,6 +96,7 @@ LIB_SRC = SMESHGUI.cxx \ SMESHGUI_SymmetryDlg.cxx \ SMESHGUI_SewingDlg.cxx \ SMESHGUI_MergeNodesDlg.cxx \ + SMESHGUI_EditMeshDlg.cxx \ SMESHGUI_Utils.cxx \ SMESHGUI_GEOMGenUtils.cxx \ SMESHGUI_MeshUtils.cxx \ @@ -149,8 +150,9 @@ LIB_MOC = \ SMESHGUI_SewingDlg.h \ SMESHGUI_PrecisionDlg.h \ SMESHGUI_MergeNodesDlg.h \ + SMESHGUI_EditMeshDlg.h \ SMESHGUI_CreatePolyhedralVolumeDlg.h - + LIB_CLIENT_IDL = SALOME_Exception.idl \ GEOM_Gen.idl \ SMESH_Gen.idl \ diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index 62bc9ff88..2982dc69e 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -60,6 +60,7 @@ #include "SMESHGUI_SymmetryDlg.h" #include "SMESHGUI_SewingDlg.h" #include "SMESHGUI_MergeNodesDlg.h" +#include "SMESHGUI_EditMeshDlg.h" #include "SMESHGUI_MeshPatternDlg.h" #include "SMESHGUI_PrecisionDlg.h" #include "SMESHGUI_Selection.h" @@ -1058,7 +1059,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) SUIT_ViewWindow* view = application()->desktop()->activeWindow(); SVTK_ViewWindow* vtkwnd = dynamic_cast( view ); - QAction* act = action( theCommandID ); + //QAction* act = action( theCommandID ); switch (theCommandID) { case 33: // DELETE @@ -1145,7 +1146,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) case 302: // DISPLAY ONLY { SMESH::EDisplaing anAction; - switch(theCommandID){ + switch (theCommandID) { case 300: anAction = SMESH::eErase; break; case 301: anAction = SMESH::eDisplay; break; case 302: anAction = SMESH::eDisplayOnly; break; @@ -1153,15 +1154,17 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); SALOME_ListIO selected; - if( aSel ) + if (aSel) aSel->selectedObjects( selected ); - if ( vtkwnd ) { - SALOME_ListIteratorOfListIO It(selected); + if (vtkwnd) { + SALOME_ListIteratorOfListIO It (selected); for (; It.More(); It.Next()) { Handle(SALOME_InteractiveObject) IOS = It.Value(); if (IOS->hasEntry()) { - SMESH::UpdateView(anAction,IOS->getEntry()); + SMESH::UpdateView(anAction, IOS->getEntry()); + if (anAction == SMESH::eDisplayOnly) + anAction = SMESH::eDisplay; } } } @@ -2006,6 +2009,22 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) } break; } + case 4066: // MERGE EQUAL ELEMENTS + { + if (checkLock(aStudy)) break; + if (vtkwnd) { + EmitSignalDeactivateDialog(); + new SMESHGUI_EditMeshDlg(this, + "SMESH_MERGE_ELEMENTS_TITLE", + "ICON_DLG_MERGE_ELEMENTS", + 1); // MergeEqualElemets + } else { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } case 5000: // HYPOTHESIS @@ -2289,6 +2308,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( 4063, "SYM", "ICON_SMESH_SYMMETRY_PLANE" ); createSMESHAction( 4064, "SEW", "ICON_SMESH_SEWING_FREEBORDERS" ); createSMESHAction( 4065, "MERGE", "ICON_SMESH_MERGE_NODES" ); + createSMESHAction( 4066, "MERGE_ELEMENTS", "ICON_DLG_MERGE_ELEMENTS" ); createSMESHAction( 406, "MOVE", "ICON_DLG_MOVE_NODE" ); createSMESHAction( 407, "INV", "ICON_DLG_MESH_DIAGONAL" ); createSMESHAction( 408, "UNION2", "ICON_UNION2TRI" ); @@ -2420,6 +2440,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createMenu( 4063, transfId, -1 ); createMenu( 4064, transfId, -1 ); createMenu( 4065, transfId, -1 ); + createMenu( 4066, transfId, -1 ); createMenu( 406, modifyId, -1 ); createMenu( 407, modifyId, -1 ); @@ -2497,6 +2518,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createTool( 4063, addRemTb ); createTool( 4064, addRemTb ); createTool( 4065, addRemTb ); + createTool( 4066, addRemTb ); createTool( separator(), addRemTb ); createTool( 406, modifyTb ); @@ -2579,11 +2601,10 @@ void SMESHGUI::initialize( CAM_Application* app ) hasFaces("({'Face'} in elemTypes)"), hasVolumes("({'Volume'} in elemTypes)"); - QString aSelCount = QString( "%1 = 1" ).arg( QtxPopupMgr::Selection::defSelCountParam() ); QString lc = QtxPopupMgr::Selection::defEquality(); QString aClient = QString( "%1client in {%2}" ).arg( lc ).arg( "'VTKViewer'" ); QString aType = QString( "%1type in {%2}" ).arg( QtxPopupMgr::Selection::defEquality() ).arg( mesh_group ); - QString aMeshInVTK = aClient + "&&" + aType;// + "&&" + aSelCount; + QString aMeshInVTK = aClient + "&&" + aType; //------------------------------------------------- // Numbering @@ -2750,6 +2771,7 @@ void SMESHGUI::initialize( CAM_Application* app ) //------------------------------------------------- aClient = "($client in {'VTKViewer' 'ObjectBrowser'})"; QString anActiveVTK = QString("activeView = '%1'").arg(VTKViewer_Viewer::Type()); + QString aSelCount = QString( "%1 > 0" ).arg( QtxPopupMgr::Selection::defSelCountParam() ); QString aRule = aClient + " and " + aType + " and " + aSelCount + " and " + anActiveVTK; popupMgr()->insert( action( 301 ), -1, -1 ); // DISPLAY popupMgr()->setRule( action( 301 ), aRule + "&&" + isNotEmpty + "&&" + isInvisible, true); diff --git a/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx b/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx new file mode 100644 index 000000000..935f18bae --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx @@ -0,0 +1,323 @@ + +#include "SMESHGUI_EditMeshDlg.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" + +#include "SMESH_TypeFilter.hxx" + +#include "SUIT_Desktop.h" +#include "SUIT_Session.h" + +#include "SALOME_ListIO.hxx" + +#include "utilities.h" + +// QT Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//================================================================================= +// class : SMESHGUI_EditMeshDlg() +// purpose : +//================================================================================= +SMESHGUI_EditMeshDlg::SMESHGUI_EditMeshDlg (SMESHGUI* theModule, + const char* title, const char* icon, + int theAction) + : QDialog(SMESH::GetDesktop(theModule), "SMESHGUI_EditMeshDlg", false, WStyle_Customize | + WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | Qt::WDestructiveClose), + mySMESHGUI(theModule), + mySelectionMgr(SMESH::GetSelectionMgr(theModule)), + myAction(theAction) +{ + resize(303, 185); + setCaption(tr(title)); + + SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); + QPixmap image0 (aResMgr->loadPixmap("SMESH", tr(icon))); + QPixmap image1 (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT"))); + + setSizeGripEnabled(TRUE); + DlgLayout = new QGridLayout (this); + DlgLayout->setSpacing(6); + DlgLayout->setMargin(11); + + /***************************************************************/ + GroupConstructors = new QButtonGroup (this, "GroupConstructors"); + GroupConstructors->setExclusive(TRUE); + GroupConstructors->setColumnLayout(0, Qt::Vertical); + GroupConstructors->layout()->setSpacing(0); + GroupConstructors->layout()->setMargin(0); + GroupConstructorsLayout = new QGridLayout (GroupConstructors->layout()); + GroupConstructorsLayout->setAlignment(Qt::AlignTop); + GroupConstructorsLayout->setSpacing(6); + GroupConstructorsLayout->setMargin(11); + Constructor1 = new QRadioButton (GroupConstructors, "Constructor1"); + Constructor1->setText(tr("")); + Constructor1->setPixmap(image0); + Constructor1->setChecked(TRUE); + Constructor1->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)1, + (QSizePolicy::SizeType)0, + Constructor1->sizePolicy().hasHeightForWidth())); + Constructor1->setMinimumSize(QSize(50, 0)); + GroupConstructorsLayout->addWidget(Constructor1, 0, 0); + QSpacerItem* spacer = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + GroupConstructorsLayout->addItem(spacer, 0, 1); + DlgLayout->addWidget(GroupConstructors, 0, 0); + + /***************************************************************/ + GroupButtons = new QGroupBox (this, "GroupButtons"); + GroupButtons->setGeometry(QRect(10, 10, 281, 48)); + GroupButtons->setTitle(tr("" )); + GroupButtons->setColumnLayout(0, Qt::Vertical); + GroupButtons->layout()->setSpacing(0); + GroupButtons->layout()->setMargin(0); + GroupButtonsLayout = new QGridLayout (GroupButtons->layout()); + GroupButtonsLayout->setAlignment(Qt::AlignTop); + GroupButtonsLayout->setSpacing(6); + GroupButtonsLayout->setMargin(11); + buttonCancel = new QPushButton (GroupButtons, "buttonCancel"); + buttonCancel->setText(tr("SMESH_BUT_CLOSE" )); + buttonCancel->setAutoDefault(TRUE); + GroupButtonsLayout->addWidget(buttonCancel, 0, 3); + buttonApply = new QPushButton (GroupButtons, "buttonApply"); + buttonApply->setText(tr("SMESH_BUT_APPLY" )); + buttonApply->setAutoDefault(TRUE); + GroupButtonsLayout->addWidget(buttonApply, 0, 1); + QSpacerItem* spacer_9 = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + GroupButtonsLayout->addItem(spacer_9, 0, 2); + buttonOk = new QPushButton (GroupButtons, "buttonOk"); + buttonOk->setText(tr("SMESH_BUT_OK" )); + buttonOk->setAutoDefault(TRUE); + buttonOk->setDefault(TRUE); + GroupButtonsLayout->addWidget(buttonOk, 0, 0); + DlgLayout->addWidget(GroupButtons, 2, 0); + + /***************************************************************/ + GroupMesh = new QGroupBox (this, "GroupMesh"); + GroupMesh->setTitle(tr("SMESH_MESH" )); + GroupMesh->setMinimumSize(QSize(0, 0)); + GroupMesh->setFrameShape(QGroupBox::Box); + GroupMesh->setFrameShadow(QGroupBox::Sunken); + GroupMesh->setColumnLayout(0, Qt::Vertical); + GroupMesh->layout()->setSpacing(0); + GroupMesh->layout()->setMargin(0); + GroupMeshLayout = new QGridLayout (GroupMesh->layout()); + GroupMeshLayout->setAlignment(Qt::AlignTop); + GroupMeshLayout->setSpacing(6); + GroupMeshLayout->setMargin(11); + TextLabelMesh = new QLabel (GroupMesh, "TextLabelMesh"); + TextLabelMesh->setText(tr("SMESH_MESH")); + TextLabelMesh->setMinimumSize(QSize(50, 0)); + TextLabelMesh->setFrameShape(QLabel::NoFrame); + TextLabelMesh->setFrameShadow(QLabel::Plain); + GroupMeshLayout->addWidget(TextLabelMesh, 0, 0); + SelectButton = new QPushButton (GroupMesh, "SelectButton"); + SelectButton->setText(tr("")); + SelectButton->setPixmap(image1); + SelectButton->setToggleButton(FALSE); + GroupMeshLayout->addWidget(SelectButton, 0, 1); + LineEditMesh = new QLineEdit (GroupMesh, "LineEditMesh"); + LineEditMesh->setReadOnly(true); + GroupMeshLayout->addWidget(LineEditMesh, 0, 2); + DlgLayout->addWidget(GroupMesh, 1, 0); + + Init(); // Initialisations +} + +//================================================================================= +// function : ~SMESHGUI_EditMeshDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +SMESHGUI_EditMeshDlg::~SMESHGUI_EditMeshDlg() +{ + // no need to delete child widgets, Qt does it all for us +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void SMESHGUI_EditMeshDlg::Init() +{ + GroupMesh->show(); + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + + myMesh = SMESH::SMESH_Mesh::_nil(); + + myMeshFilter = new SMESH_TypeFilter (MESH); + + // signals and slots connections + connect(buttonOk , SIGNAL(clicked()), this, SLOT(ClickOnOk())); + connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel())); + connect(buttonApply , SIGNAL(clicked()), this, SLOT(ClickOnApply())); + + connect(SelectButton, SIGNAL(clicked()), this, SLOT(SelectionIntoArgument())); + + connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); + + connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); + connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()) , this, SLOT(ClickOnCancel())); + + // Move widget on the bottom right corner of main widget + int x, y; + mySMESHGUI->DefineDlgPosition(this, x, y); + this->move(x, y); + this->show(); // displays Dialog + + LineEditMesh->setFocus(); + mySelectionMgr->clearFilters(); + mySelectionMgr->installFilter(myMeshFilter); + + SelectionIntoArgument(); +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +void SMESHGUI_EditMeshDlg::ClickOnApply() +{ + if (!myMesh->_is_nil()) { + try { + QApplication::setOverrideCursor(Qt::waitCursor); + + if (myAction == 1) { + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); + aMeshEditor->MergeEqualElements(); + } + + QApplication::restoreOverrideCursor(); + } catch(...) { + } + + mySelectionMgr->clearSelected(); + SMESH::UpdateView(); + } +} + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void SMESHGUI_EditMeshDlg::ClickOnOk() +{ + ClickOnApply(); + ClickOnCancel(); +} + +//================================================================================= +// function : ClickOnCancel() +// purpose : +//================================================================================= +void SMESHGUI_EditMeshDlg::ClickOnCancel() +{ + mySelectionMgr->clearSelected(); + mySelectionMgr->clearFilters(); + disconnect(mySelectionMgr, 0, this, 0); + mySMESHGUI->ResetState(); + reject(); +} + +//================================================================================= +// function : SelectionIntoArgument() +// purpose : Called when selection as changed or other case +//================================================================================= +void SMESHGUI_EditMeshDlg::SelectionIntoArgument() +{ + if (!GroupButtons->isEnabled()) // inactive + return; + + QString aString = ""; + + SALOME_ListIO aList; + mySelectionMgr->selectedObjects(aList); + int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString); + + // mesh + if (nbSel != 1) { + myMesh = SMESH::SMESH_Mesh::_nil(); + aString = ""; + } else { + Handle(SALOME_InteractiveObject) IO = aList.First(); + myMesh = SMESH::IObjectToInterface(IO); + if (myMesh->_is_nil()) + aString = ""; + } + + LineEditMesh->setText(aString); + + bool isEnabled = (!myMesh->_is_nil()); + buttonOk->setEnabled(isEnabled); + buttonApply->setEnabled(isEnabled); +} + +//================================================================================= +// function : DeactivateActiveDialog() +// purpose : +//================================================================================= +void SMESHGUI_EditMeshDlg::DeactivateActiveDialog() +{ + if (GroupConstructors->isEnabled()) { + GroupConstructors->setEnabled(false); + GroupMesh->setEnabled(false); + GroupButtons->setEnabled(false); + mySMESHGUI->ResetState(); + mySMESHGUI->SetActiveDialogBox(0); + } +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void SMESHGUI_EditMeshDlg::ActivateThisDialog() +{ + /* Emit a signal to deactivate the active dialog */ + mySMESHGUI->EmitSignalDeactivateDialog(); + GroupConstructors->setEnabled(true); + GroupMesh->setEnabled(true); + GroupButtons->setEnabled(true); + + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + SelectionIntoArgument(); +} + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void SMESHGUI_EditMeshDlg::enterEvent(QEvent* e) +{ + if (GroupConstructors->isEnabled()) + return; + ActivateThisDialog(); +} + +//================================================================================= +// function : closeEvent() +// purpose : +//================================================================================= +void SMESHGUI_EditMeshDlg::closeEvent(QCloseEvent* e) +{ + /* same than click on cancel button */ + this->ClickOnCancel(); +} + +//======================================================================= +//function : hideEvent +//purpose : caused by ESC key +//======================================================================= +void SMESHGUI_EditMeshDlg::hideEvent (QHideEvent * e) +{ + if (!isMinimized()) + ClickOnCancel(); +} diff --git a/src/SMESHGUI/SMESHGUI_EditMeshDlg.h b/src/SMESHGUI/SMESHGUI_EditMeshDlg.h new file mode 100644 index 000000000..20cf71080 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_EditMeshDlg.h @@ -0,0 +1,85 @@ + +#ifndef DIALOGBOX_GETMESH_H +#define DIALOGBOX_GETMESH_H + +#include "SalomeApp_SelectionMgr.h" +#include "SUIT_SelectionFilter.h" + +// QT Includes +#include + +// Open CASCADE Includes + +class QGridLayout; +class QButtonGroup; +class QGroupBox; +class QLabel; +class QLineEdit; +class QPushButton; +class QRadioButton; +class SMESHGUI; + +// IDL Headers +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +//================================================================================= +// class : SMESHGUI_EditMeshDlg +// purpose : +//================================================================================= +class SMESHGUI_EditMeshDlg : public QDialog +{ + Q_OBJECT; + + public: + SMESHGUI_EditMeshDlg (SMESHGUI * theModule, + const char* title, + const char* icon, + int theAction); + ~SMESHGUI_EditMeshDlg(); + + private: + void Init(); + void closeEvent (QCloseEvent*); + void enterEvent (QEvent*); /* mouse enter the QWidget */ + void hideEvent (QHideEvent*); /* ESC key */ + + private: + SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ + SalomeApp_SelectionMgr* mySelectionMgr; /* User shape selection */ + + SMESH::SMESH_Mesh_var myMesh; + SUIT_SelectionFilter* myMeshFilter; + + int myAction; + + // Widgets + QButtonGroup* GroupConstructors; + QRadioButton* Constructor1; + + QGroupBox* GroupButtons; + QPushButton* buttonOk; + QPushButton* buttonCancel; + QPushButton* buttonApply; + + QGroupBox* GroupMesh; + QLabel* TextLabelMesh; + QPushButton* SelectButton; + QLineEdit* LineEditMesh; + + //protected: + QGridLayout* DlgLayout; + QGridLayout* GroupConstructorsLayout; + QGridLayout* GroupButtonsLayout; + QGridLayout* GroupMeshLayout; + + private slots: + void ClickOnOk(); + void ClickOnCancel(); + void ClickOnApply(); + void SelectionIntoArgument(); + void DeactivateActiveDialog(); + void ActivateThisDialog(); +}; + +#endif // DIALOGBOX_GETMESH_H diff --git a/src/SMESHGUI/SMESH_images.po b/src/SMESHGUI/SMESH_images.po index e98515125..70ff8ba7f 100644 --- a/src/SMESHGUI/SMESH_images.po +++ b/src/SMESHGUI/SMESH_images.po @@ -110,6 +110,10 @@ msgstr "mesh_sew_sideelements.png" msgid "ICON_SMESH_MERGE_NODES" msgstr "mesh_merge_nodes.png" +#Merge elements +msgid "ICON_DLG_MERGE_ELEMENTS" +msgstr "mesh_merge_elements.png" + #----------------------------------------------------------- # Hypothesis #----------------------------------------------------------- diff --git a/src/SMESHGUI/SMESH_msg_en.po b/src/SMESHGUI/SMESH_msg_en.po index a1f2189e5..5b353db56 100644 --- a/src/SMESHGUI/SMESH_msg_en.po +++ b/src/SMESHGUI/SMESH_msg_en.po @@ -703,6 +703,10 @@ msgstr "Sewing" msgid "SMESH_MERGE_NODES" msgstr "Merge nodes" +#Merge elements +msgid "SMESH_MERGE_ELEMENTS_TITLE" +msgstr "Merge elements" + #Extrusion msgid "SMESH_EXTRUSION" msgstr "Extrusion" @@ -1992,6 +1996,9 @@ msgstr "Sewing" msgid "MEN_MERGE" msgstr "Merge nodes" +msgid "MEN_MERGE_ELEMENTS" +msgstr "Merge elements" + msgid "MEN_MOVE" msgstr "Move Node" @@ -2318,6 +2325,9 @@ msgstr "Sewing" msgid "TOP_MERGE" msgstr "Merge nodes" +msgid "TOP_MERGE_ELEMENTS" +msgstr "Merge elements" + msgid "TOP_MOVE" msgstr "Move Node" @@ -2589,6 +2599,9 @@ msgstr "Sewing" msgid "STB_MERGE" msgstr "Merge nodes" +msgid "STB_MERGE_ELEMENTS" +msgstr "Merge elements" + msgid "STB_MOVE" msgstr "Move Node"