From f4142fe977e86848538f5adcfcb9c21eb2d318d3 Mon Sep 17 00:00:00 2001 From: akl Date: Tue, 19 May 2015 12:15:20 +0400 Subject: [PATCH] 22888: EDF 10437 GEOM: Dimensions improvements --- resources/CMakeLists.txt | 1 + resources/SalomeApp.xml.in | 5 +- resources/Y14.5M-2009.ttf | Bin 0 -> 41952 bytes src/GEOMGUI/CMakeLists.txt | 3 + src/GEOMGUI/GEOMGUI_TextTreeWdg.cxx | 421 ++++++++++++++++++ src/GEOMGUI/GEOMGUI_TextTreeWdg.h | 89 ++++ src/GEOMGUI/GEOM_Displayer.cxx | 11 +- src/GEOMGUI/GEOM_msg_en.ts | 19 +- src/GEOMGUI/GEOM_msg_fr.ts | 19 +- src/GEOMGUI/GEOM_msg_ja.ts | 23 +- src/GEOMGUI/GeometryGUI.cxx | 83 +++- src/GEOMGUI/GeometryGUI.h | 6 + .../MeasureGUI_CreateDimensionDlg.cxx | 11 +- .../MeasureGUI_ManageDimensionsDlg.cxx | 5 + 14 files changed, 665 insertions(+), 31 deletions(-) create mode 100644 resources/Y14.5M-2009.ttf create mode 100644 src/GEOMGUI/GEOMGUI_TextTreeWdg.cxx create mode 100644 src/GEOMGUI/GEOMGUI_TextTreeWdg.h diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index cef2c42f2..44d86e7bc 100755 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -35,6 +35,7 @@ SET( _res_files GEOM.config GEOMDS_Resources ShHealing + Y14.5M-2009.ttf 3dsketch.png isoline.png isoline_v.png diff --git a/resources/SalomeApp.xml.in b/resources/SalomeApp.xml.in index 84f53783c..8e83fdbc2 100644 --- a/resources/SalomeApp.xml.in +++ b/resources/SalomeApp.xml.in @@ -92,12 +92,13 @@ - + - + + diff --git a/resources/Y14.5M-2009.ttf b/resources/Y14.5M-2009.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1f1ca199a0c631f368a1e4cefc58af5b83c87d35 GIT binary patch literal 41952 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 AZ2$lO literal 0 HcmV?d00001 diff --git a/src/GEOMGUI/CMakeLists.txt b/src/GEOMGUI/CMakeLists.txt index 211156716..c5e9e928f 100755 --- a/src/GEOMGUI/CMakeLists.txt +++ b/src/GEOMGUI/CMakeLists.txt @@ -76,12 +76,14 @@ SET(GEOMGUI_HEADERS GEOMGUI_Selection.h GEOM_GEOMGUI.hxx GEOMGUI_CreationInfoWdg.h + GEOMGUI_TextTreeWdg.h GEOMGUI_DimensionProperty.h ) # header files / to be processed by moc SET(_moc_HEADERS GEOMGUI_CreationInfoWdg.h + GEOMGUI_TextTreeWdg.h GeometryGUI.h ) @@ -114,6 +116,7 @@ SET(GEOMGUI_SOURCES GEOMGUI_OCCSelector.cxx GEOMGUI_Selection.cxx GEOMGUI_CreationInfoWdg.cxx + GEOMGUI_TextTreeWdg.cxx GEOMGUI_DimensionProperty.cxx ${_moc_SOURCES} ${_rcc_SOURCES} diff --git a/src/GEOMGUI/GEOMGUI_TextTreeWdg.cxx b/src/GEOMGUI/GEOMGUI_TextTreeWdg.cxx new file mode 100644 index 000000000..2c00a3bd4 --- /dev/null +++ b/src/GEOMGUI/GEOMGUI_TextTreeWdg.cxx @@ -0,0 +1,421 @@ +// Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : GEOMGUI_TextTreeWdg.cxx +// Author : Alexander KOVALEV (akl) + +#include "GEOMGUI_TextTreeWdg.h" + +#include "GEOMGUI_DimensionProperty.h" +#include "GeometryGUI.h" +#include "GeometryGUI_Operations.h" +#include +#include + +// GUI includes +#include +#include +#include +#include +#include +#include +#include + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GEOMGUI_TextTreeWdg::GEOMGUI_TextTreeWdg( SalomeApp_Application* app ) + : myDisplayer(NULL) +{ + myStudy = dynamic_cast( app->activeStudy() ); + myDisplayer = GEOM_Displayer( myStudy ); + + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + myVisibleIcon = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_VISIBLE" ) ) ); + myInvisibleIcon = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_INVISIBLE" ) ) ); + + setWindowTitle( tr( "TEXT_TREE_VIEW_TITLE" ) ); + setObjectName( "geomTextTreeWdg" ); + + setRootIsDecorated( true ); + setSelectionMode( QAbstractItemView::ExtendedSelection ); + setAllColumnsShowFocus( true ); + setUniformRowHeights( true ); + + QStringList columnNames; + columnNames << tr("TEXT_TREE_VIEW_NAME") << ""; + QTreeWidgetItem * headerItem = new QTreeWidgetItem( columnNames ); + headerItem->setIcon( 1, myVisibleIcon ); + setHeaderItem ( headerItem ); + header()->moveSection( 1, 0 ); + header()->setResizeMode( 1, QHeaderView::ResizeToContents ); + + QStringList rootNames; + rootNames << tr("GEOM_DIMENSIONS") << ""; + myDimensionsItem = new QTreeWidgetItem( this, rootNames ); + myDimensionsItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); + addTopLevelItem( myDimensionsItem ); + + // get a free dockable window id + myWindowID = 11; + while( app->dockWindow( myWindowID )) + ++myWindowID; + ++myWindowID; + + createActions(); + setContextMenuPolicy( Qt::CustomContextMenu ); + connect( this, SIGNAL( customContextMenuRequested(const QPoint&) ), + this, SLOT( showContextMenu(const QPoint&) ) ); + + connect( myStudy, SIGNAL( objVisibilityChanged( QString, Qtx::VisibilityState ) ), + this, SLOT( updateVisibilityColumn( QString, Qtx::VisibilityState ) ) ); + connect( app->objectBrowser(), SIGNAL( updated() ), this, SLOT( updateTree() ) ); + GeometryGUI* aGeomGUI = dynamic_cast( app->module( "Geometry" ) ); + connect( aGeomGUI, SIGNAL( DimensionsUpdated( const QString& ) ), this, SLOT( updateBranch( const QString& ) ) ); + connect( this, SIGNAL( itemClicked( QTreeWidgetItem*, int) ), + this, SLOT( onItemClicked( QTreeWidgetItem*, int ) ) ); + +} + +GEOMGUI_TextTreeWdg::~GEOMGUI_TextTreeWdg() +{ + //std::cout<<"~GEOMGUI_TextTreeWdg"<setIcon( myVisibleIcon ); + myActions.insert( GEOMOp::OpShow, a ); + + QAction* b = new QAction( tr( "MEN_ERASE" ), this ); + b->setIcon( myInvisibleIcon ); + myActions.insert( GEOMOp::OpHide, b ); +} + +//================================================================================= +// function : updateTree +// purpose : +//================================================================================= +void GEOMGUI_TextTreeWdg::updateTree() +{ + myStudy = dynamic_cast( SUIT_Session::session()->activeApplication()->activeStudy() ); + _PTR(Study) aDSStudy = myStudy->studyDS(); + if ( aDSStudy ) { + _PTR(SComponent) SC ( aDSStudy->FindComponent( "GEOM" ) ); + if ( SC ) { + _PTR(ChildIterator) anIter ( aDSStudy->NewChildIterator( SC ) ); + anIter->InitEx( true ); + QList objEntries = myObjects.keys(); + while( anIter->More() ) { + _PTR(SObject) valSO ( anIter->Value() ); + _PTR(SObject) refSO; + if ( !valSO->ReferencedObject( refSO ) ) { + // update tree of object's dimensions + QString anEntry = valSO->GetID().c_str(); + updateBranch( anEntry ); + objEntries.removeAll( anEntry ); + } + anIter->Next(); + } + foreach (QString entry, objEntries) { + removeBranch( entry, true ); + } + } + } +} + +//================================================================================= +// function : updateBranch +// purpose : +//================================================================================= +void GEOMGUI_TextTreeWdg::updateBranch( const QString& theEntry ) +{ + myStudy = dynamic_cast( SUIT_Session::session()->activeApplication()->activeStudy() ); + if ( myStudy ) { + _PTR(Study) aStudyDS = myStudy->studyDS(); + if ( aStudyDS ) { + _PTR(SObject) obj( aStudyDS->FindObjectID( theEntry.toStdString() ) ); + QString aName = obj->GetName().c_str(); + + GEOMGUI_DimensionProperty aProp; + aProp.LoadFromAttribute( myStudy, theEntry.toStdString() ); + int nbProps = aProp.GetNumber(); + + QTreeWidgetItem* objectItem = itemFromEntry( theEntry ); + if ( objectItem ) { + removeBranch( theEntry, nbProps > 0 ? false : true ); + } + QStringList itemName; + if ( nbProps > 0 ) { + itemName << aName << ""; + if ( !objectItem ) { + objectItem = new QTreeWidgetItem( myDimensionsItem, itemName ); + objectItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); + objectItem->setData( 1, Qt::UserRole, theEntry ); + myDimensionsItem->addChild( objectItem ); + myObjects.insert( theEntry, objectItem ); + if ( myDimensionsItem->childCount() == 1 ) + myDimensionsItem->setExpanded( true ); + } + bool isDisplayed = myDisplayer.IsDisplayed( theEntry ); + // read dimension records from property + for ( int anIt = 0; anIt < aProp.GetNumber(); ++anIt ) + { + QString aName = aProp.GetName( anIt ); + bool isVisible = aProp.IsVisible( anIt ); + + QTreeWidgetItem* anItem = new QTreeWidgetItem; + anItem->setText( 0, aName ); + // if ( isDisplayed ) + anItem->setIcon( 1, isVisible ? myVisibleIcon : myInvisibleIcon ); + anItem->setData( 0, Qt::UserRole, anIt ); + anItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); + objectItem->addChild( anItem ); + } + } + } + } +} + +//================================================================================= +// function : removeBranch +// purpose : +//================================================================================= +void GEOMGUI_TextTreeWdg::removeBranch( const QString& theEntry, bool force ) +{ + QTreeWidgetItem* objectItem = itemFromEntry( theEntry ); + if ( !objectItem ) + return; + qDeleteAll( objectItem->takeChildren() ); + if ( force ) { + myDimensionsItem->removeChild( objectItem ); + myObjects.remove( theEntry ); + } +} + +//================================================================================= +// function : onItemClicked() +// purpose : called when tree item was clicked +//================================================================================= +void GEOMGUI_TextTreeWdg::onItemClicked( QTreeWidgetItem* theItem, int theColumn ) +{ + if( theColumn != 1 || theItem->icon( 1 ).isNull() || theItem->isDisabled() ) + return; + + std::string anEntry = entryFromItem( theItem->parent() ).toStdString(); + int aDimIndex = idFromItem( theItem ); + GEOMGUI_DimensionProperty aProp; + aProp.LoadFromAttribute( myStudy, anEntry ); + if ( aProp.IsVisible( aDimIndex ) ) { + aProp.SetVisible( aDimIndex, false ); + theItem->setIcon( 1, myInvisibleIcon ); + } else { + aProp.SetVisible( aDimIndex, true ); + theItem->setIcon( 1, myVisibleIcon ); + } + aProp.SaveToAttribute( myStudy, anEntry ); + redisplay( anEntry.c_str() ); +} + +//================================================================================= +// function : idFromItem +// purpose : +//================================================================================= +int GEOMGUI_TextTreeWdg::idFromItem( QTreeWidgetItem* theItem ) +{ + if ( !theItem ) + return -1; + + bool isIdOK = false; + const int anId = theItem->data( 0, Qt::UserRole ).toInt( &isIdOK ); + + return isIdOK ? anId : -1; +} + +//================================================================================= +// function : entryFromItem +// purpose : +//================================================================================= +QString GEOMGUI_TextTreeWdg::entryFromItem( QTreeWidgetItem* theShapeItem ) +{ + if ( !theShapeItem ) + return ""; + + return theShapeItem->data( 1, Qt::UserRole ).toString(); +} + +//================================================================================= +// function : itemFromEntry +// purpose : +//================================================================================= +QTreeWidgetItem* GEOMGUI_TextTreeWdg::itemFromEntry( QString theEntry ) +{ + if ( theEntry.isEmpty() ) + return 0; + + return myObjects.value( theEntry, 0 ); +} + +//================================================================================= +// function : updateVisibilityColumn +// purpose : Update icons of dimension items. +//================================================================================= +void GEOMGUI_TextTreeWdg::updateVisibilityColumn( QString theEntry, Qtx::VisibilityState theState ) +{ + QTreeWidgetItem* anItem = itemFromEntry( theEntry ); + if ( !anItem ) + return; + anItem->setDisabled( theState != Qtx::ShownState ); + QTreeWidgetItem* aChildItem; + GEOMGUI_DimensionProperty aProp; + for ( int i=0; i < anItem->childCount(); i++ ) { + aChildItem = anItem->child( i ); + if ( theState == Qtx::ShownState ) { + aProp.LoadFromAttribute( myStudy, theEntry.toStdString() ); + if ( aProp.GetNumber() == 0 ) + continue; + aChildItem->setIcon( 1, aProp.IsVisible( idFromItem( aChildItem ) ) ? myVisibleIcon : myInvisibleIcon ); + aChildItem->setDisabled( false ); + } else { + aChildItem->setIcon( 1, QIcon() ); + aChildItem->setDisabled( true ); + } + } +} + +//================================================================================= +// function : showContextMenu +// purpose : +//================================================================================= +void GEOMGUI_TextTreeWdg::showContextMenu( const QPoint& pos ) +{ + if ( selectedItems().isEmpty() ) + return; + QMenu aMenu; + aMenu.addAction( myActions[GEOMOp::OpShow] ); + aMenu.addAction( myActions[GEOMOp::OpHide] ); + if ( selectedItems().count() == 1 ) { + QTreeWidgetItem* anItem = selectedItems().first(); + QString anEntry = entryFromItem( anItem->parent() ); + if ( !anEntry.isEmpty() ) { + GEOMGUI_DimensionProperty aProp; + aProp.LoadFromAttribute( myStudy, anEntry.toStdString() ); + if ( aProp.GetNumber() == 0 ) + return; + aMenu.clear(); + if ( aProp.IsVisible( idFromItem( anItem ) ) ) + aMenu.addAction( myActions[GEOMOp::OpHide] ); + else + aMenu.addAction( myActions[GEOMOp::OpShow] ); + } + } + QAction* selPopupItem = aMenu.exec( viewport()->mapToGlobal(pos) ); + if ( selPopupItem == myActions[GEOMOp::OpShow] ) + setVisibility( true ); + else if ( selPopupItem == myActions[GEOMOp::OpHide] ) + setVisibility( false ); +} + +//================================================================================= +// function : setVisibility +// purpose : +//================================================================================= +void GEOMGUI_TextTreeWdg::setVisibility( bool theVisibility ) +{ + if ( myDimensionsItem->isSelected() ) { + // set visibility for all dimensions + QTreeWidgetItem* anItem; + foreach ( QString entry, myObjects.keys() ) { + anItem = itemFromEntry( entry ); + if ( !anItem->isDisabled() ) + setShapeDimensionsVisibility( entry, theVisibility ); + } + return; + } + foreach ( QTreeWidgetItem* item, selectedItems() ) { + if ( item->isDisabled() || item->parent()->isSelected() ) + continue; + QString anEntry = entryFromItem( item ); + if ( !anEntry.isEmpty() ) { + // it is a shape item + setShapeDimensionsVisibility( anEntry, theVisibility ); + } else { + // it is a dimension item + anEntry = entryFromItem( item->parent() ); + setDimensionVisibility( anEntry, item, theVisibility ); + } + } +} + +//================================================================================= +// function : setShapeDimensionsVisibility +// purpose : +//================================================================================= +void GEOMGUI_TextTreeWdg::setShapeDimensionsVisibility( QString theEntry, bool theVisibility ) +{ + QTreeWidgetItem* anItem = itemFromEntry( theEntry ); + QTreeWidgetItem* aChildItem; + for ( int i=0; i < anItem->childCount(); i++ ) { + aChildItem = anItem->child( i ); + setDimensionVisibility( theEntry, aChildItem, theVisibility ); + } + redisplay( theEntry ); +} + +//================================================================================= +// function : setDimensionVisibility +// purpose : +//================================================================================= +void GEOMGUI_TextTreeWdg::setDimensionVisibility( QString theEntry, QTreeWidgetItem* theDimItem, bool theVisibility ) +{ + GEOMGUI_DimensionProperty aProp; + aProp.LoadFromAttribute( myStudy, theEntry.toStdString() ); + int aDimIndex = idFromItem( theDimItem ); + if ( aProp.GetNumber() == 0 || aProp.IsVisible( aDimIndex ) == theVisibility ) + return;; + aProp.SetVisible( aDimIndex, theVisibility ); + aProp.SaveToAttribute( myStudy, theEntry.toStdString() ); + + theDimItem->setIcon( 1, theVisibility ? myVisibleIcon : myInvisibleIcon ); + redisplay( theEntry ); +} + +//================================================================================= +// function : redisplay +// purpose : +//================================================================================= +void GEOMGUI_TextTreeWdg::redisplay( QString theEntry ) +{ + Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject( theEntry.toLatin1().constData(), "GEOM", "TEMP_IO" ); + myDisplayer.Redisplay( io ); +} diff --git a/src/GEOMGUI/GEOMGUI_TextTreeWdg.h b/src/GEOMGUI/GEOMGUI_TextTreeWdg.h new file mode 100644 index 000000000..689a21a67 --- /dev/null +++ b/src/GEOMGUI/GEOMGUI_TextTreeWdg.h @@ -0,0 +1,89 @@ +// Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef GEOMGUI_TEXTTREEWDG_H +#define GEOMGUI_TEXTTREEWDG_H + +#include "GEOM_GEOMGUI.hxx" +#include "GEOM_Displayer.h" + +#include +#include + +#include + +class QLabel; +class QLineEdit; +class QString; +class QTreeWidgetItem; +class SalomeApp_Application; +class SalomeApp_Study; + +/*! + * \brief Tree view contains Dimension and Annotation text items: + * - text visibility in OCC viewer + * - text object name + */ +class GEOMGUI_EXPORT GEOMGUI_TextTreeWdg : public QTreeWidget +{ + Q_OBJECT + + public: + GEOMGUI_TextTreeWdg( SalomeApp_Application* app ); + ~GEOMGUI_TextTreeWdg(); + + int getWinID() { return myWindowID; } + + void removeBranch( const QString& theEntry, + bool force = true ); + int idFromItem( QTreeWidgetItem* theItem ); + QString entryFromItem( QTreeWidgetItem* theShapeItem ); + QTreeWidgetItem* itemFromEntry( QString theEntry ); + void setShapeDimensionsVisibility( QString theEntry, bool theVisibility ); + void setDimensionVisibility( QString theEntry, QTreeWidgetItem* theDimItem, bool theVisibility ); + +protected: + void createActions(); + void redisplay( QString theEntry ); + + public slots: + void updateTree(); + void updateBranch( const QString& theEntry ); + +private slots: + void onItemClicked(QTreeWidgetItem*, int ); + void updateVisibilityColumn( QString theEntry, Qtx::VisibilityState theState ); + void setVisibility( bool visibility ); + void showContextMenu( const QPoint& pos ); + + private: + + int myWindowID; + + QIcon myVisibleIcon; + QIcon myInvisibleIcon; + QHash myObjects; + SalomeApp_Study* myStudy; + QTreeWidgetItem* myDimensionsItem; + GEOM_Displayer myDisplayer; + + QMap myActions; //!< menu actions list + +}; +#endif diff --git a/src/GEOMGUI/GEOM_Displayer.cxx b/src/GEOMGUI/GEOM_Displayer.cxx index 205e9db75..3166ac20a 100644 --- a/src/GEOMGUI/GEOM_Displayer.cxx +++ b/src/GEOMGUI/GEOM_Displayer.cxx @@ -1234,11 +1234,12 @@ void GEOM_Displayer::updateDimensions( const Handle(SALOME_InteractiveObject)& t QColor aQColor = aResMgr->colorValue ( "Geometry", "dimensions_color", QColor( 0, 255, 0 ) ); int aLineWidth = aResMgr->integerValue( "Geometry", "dimensions_line_width", 1 ); - double aFontHeight = aResMgr->doubleValue ( "Geometry", "dimensions_font_height", 10 ); + QFont aFont = aResMgr->fontValue ( "Geometry", "dimensions_font", QFont("Y14.5M-2009", 14) ); double anArrowLength = aResMgr->doubleValue ( "Geometry", "dimensions_arrow_length", 5 ); bool isUnitsShown = aResMgr->booleanValue( "Geometry", "dimensions_show_units", false ); QString aUnitsLength = aResMgr->stringValue ( "Geometry", "dimensions_length_units", "m" ); QString aUnitsAngle = aResMgr->stringValue ( "Geometry", "dimensions_angle_units", "deg" ); + bool aUseText3d = aResMgr->booleanValue( "Geometry", "dimensions_use_text3d", false ); // restore dimension presentation from saved attribute or property data AIS_ListOfInteractive aRestoredDimensions; @@ -1304,10 +1305,12 @@ void GEOM_Displayer::updateDimensions( const Handle(SALOME_InteractiveObject)& t aStyle->SetCommonColor( aColor ); aStyle->MakeUnitsDisplayed( (Standard_Boolean) isUnitsShown ); - aStyle->MakeText3d( Standard_True ); + aStyle->MakeText3d( aUseText3d ); aStyle->MakeTextShaded( Standard_True ); - aStyle->SetExtensionSize( aFontHeight * 0.5 ); - aStyle->TextAspect()->SetHeight( aFontHeight ); + int fsize = aFont.pixelSize() != -1 ? aFont.pixelSize() : aFont.pointSize(); + aStyle->SetExtensionSize( fsize * 0.5 ); + aStyle->TextAspect()->SetFont( aFont.family().toLatin1().data() ); + aStyle->TextAspect()->SetHeight( fsize ); aStyle->ArrowAspect()->SetLength( anArrowLength ); aStyle->LineAspect()->SetWidth( aLineWidth ); aStyle->SetTextHorizontalPosition( aPrs->DimensionAspect()->TextHorizontalPosition() ); diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index c67b290fe..9e13e729b 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -3453,8 +3453,8 @@ Please, select face, shell or solid and try again Line width - PREF_DIMENSIONS_FONT_HEIGHT - Font height + PREF_DIMENSIONS_FONT + Font PREF_DIMENSIONS_ARROW_LENGTH @@ -3476,6 +3476,10 @@ Please, select face, shell or solid and try again PREF_DIMENSIONS_SHOW_UNITS Show units of measurement + + PREF_DIMENSIONS_USE_TEXT3D + Use 3D text + PREF_HIDE_INPUT_OBJECT Hide input objects from the viewer @@ -7238,6 +7242,17 @@ Do you want to create new material? (No info available) + + GEOMGUI_TextTreeWdg + + TEXT_TREE_VIEW_TITLE + Text + + + TEXT_TREE_VIEW_NAME + Name + + EntityGUI_IsolineDlg diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts index 0ab7e34fc..54b86aee7 100644 --- a/src/GEOMGUI/GEOM_msg_fr.ts +++ b/src/GEOMGUI/GEOM_msg_fr.ts @@ -3401,8 +3401,8 @@ Choisissez une face, une coque ou un solide et essayez de nouveau Epaisseur de la ligne - PREF_DIMENSIONS_FONT_HEIGHT - Taille de police + PREF_DIMENSIONS_FONT + Font PREF_DIMENSIONS_ARROW_LENGTH @@ -3424,6 +3424,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau PREF_DIMENSIONS_SHOW_UNITS Afficher les unités + + PREF_DIMENSIONS_USE_TEXT3D + Use 3D text + PREF_HIDE_INPUT_OBJECT Hide input objects from the viewer @@ -7171,6 +7175,17 @@ Voulez-vous en créer un nouveau ? (aucune information disponible) + + GEOMGUI_TextTreeWdg + + TEXT_TREE_VIEW_TITLE + Text + + + TEXT_TREE_VIEW_NAME + Name + + EntityGUI_IsolineDlg diff --git a/src/GEOMGUI/GEOM_msg_ja.ts b/src/GEOMGUI/GEOM_msg_ja.ts index 75807fcc7..5f181fa6e 100644 --- a/src/GEOMGUI/GEOM_msg_ja.ts +++ b/src/GEOMGUI/GEOM_msg_ja.ts @@ -3344,8 +3344,8 @@ 線幅 - PREF_DIMENSIONS_FONT_HEIGHT - フォント高さ + PREF_DIMENSIONS_FONT + Font PREF_DIMENSIONS_ARROW_LENGTH @@ -3368,8 +3368,12 @@ 測定単位の表示 - PREF_HIDE_INPUT_OBJECT - Hide input objects from the viewer + PREF_DIMENSIONS_USE_TEXT3D + Use 3D text + + + PREF_HIDE_INPUT_OBJECT + Hide input objects from the viewer PREF_ISOS @@ -7056,6 +7060,17 @@ (有効情報なし) + + GEOMGUI_TextTreeWdg + + TEXT_TREE_VIEW_TITLE + Text + + + TEXT_TREE_VIEW_NAME + Name + + EntityGUI_IsolineDlg diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index 25832ed53..ffe4ee97f 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -33,6 +33,7 @@ #include "GEOMGUI_OCCSelector.h" #include "GEOMGUI_Selection.h" #include "GEOMGUI_CreationInfoWdg.h" +#include "GEOMGUI_TextTreeWdg.h" #include "GEOMGUI_DimensionProperty.h" #include "GEOM_Constants.h" #include "GEOM_Displayer.h" @@ -86,6 +87,7 @@ #include #include +#include // External includes #include @@ -97,6 +99,7 @@ #include #include #include +#include #include #include @@ -107,6 +110,7 @@ #include #include +#include #include @@ -116,6 +120,10 @@ #include #include +#include +#include +#include + #include "GEOM_version.h" #include "GEOMImpl_Types.hxx" // dangerous hxx (defines short-name macros) - include after all @@ -218,6 +226,7 @@ GeometryGUI::GeometryGUI() : myLocalSelectionMode = GEOM_ALLOBJECTS; myCreationInfoWdg = 0; + myTextTreeWdg = 0; connect( Material_ResourceMgr::resourceMgr(), SIGNAL( changed() ), this, SLOT( updateMaterials() ) ); @@ -1783,6 +1792,11 @@ bool GeometryGUI::activateModule( SUIT_Study* study ) getApp()->insertDockWindow( myCreationInfoWdg->getWinID(), myCreationInfoWdg ); getApp()->placeDockWindow( myCreationInfoWdg->getWinID(), Qt::LeftDockWidgetArea ); + if ( !myTextTreeWdg ) + myTextTreeWdg = new GEOMGUI_TextTreeWdg( getApp() ); + getApp()->insertDockWindow( myTextTreeWdg->getWinID(), myTextTreeWdg ); + getApp()->placeDockWindow( myTextTreeWdg->getWinID(), Qt::LeftDockWidgetArea ); + //NPAL 19674 SALOME_ListIO selected; sm->selectedObjects( selected ); @@ -1844,8 +1858,15 @@ bool GeometryGUI::deactivateModule( SUIT_Study* study ) disconnect( selMrg, SIGNAL( currentSelectionChanged() ), this, SLOT( updateCreationInfo() )); disconnect( selMrg, SIGNAL( currentSelectionChanged() ), this, SLOT( updateFieldColorScale() )); - getApp()->removeDockWindow( myCreationInfoWdg->getWinID() ); - myCreationInfoWdg = 0; + if ( myCreationInfoWdg ) { + getApp()->removeDockWindow( myCreationInfoWdg->getWinID() ); + myCreationInfoWdg = 0; + } + if ( myTextTreeWdg ) { + getApp()->removeDockWindow( myTextTreeWdg->getWinID() ); + disconnect( application(), 0, myTextTreeWdg, 0 ); + myTextTreeWdg = 0; + } EmitSignalCloseAllDialogs(); @@ -1903,6 +1924,8 @@ void GeometryGUI::windows( QMap& mappa ) const mappa.insert( SalomeApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea ); if ( myCreationInfoWdg ) mappa.insert( myCreationInfoWdg->getWinID(), Qt::LeftDockWidgetArea ); + if ( myTextTreeWdg ) + mappa.insert( myTextTreeWdg->getWinID(), Qt::LeftDockWidgetArea ); } void GeometryGUI::viewManagers( QStringList& lst ) const @@ -2237,6 +2260,8 @@ void GeometryGUI::OnSetMaterial(const QString& theName) void GeometryGUI::createPreferences() { + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + int tabId = addPreference( tr( "PREF_TAB_SETTINGS" ) ); int genGroup = addPreference( tr( "PREF_GROUP_GENERAL" ), tabId ); @@ -2333,12 +2358,36 @@ void GeometryGUI::createPreferences() setPreferenceProperty( aDimLineWidthId, "min", 1 ); setPreferenceProperty( aDimLineWidthId, "max", 5 ); - int aDimFontHeightId = addPreference( tr( "PREF_DIMENSIONS_FONT_HEIGHT" ), aDimGroupId, - LightApp_Preferences::DblSpin, "Geometry", "dimensions_font_height" ); - - setPreferenceProperty( aDimFontHeightId, "min", 1e-9 ); - setPreferenceProperty( aDimFontHeightId, "max", 1e+9 ); - setPreferenceProperty( aDimFontHeightId, "precision", 9 ); + int aDimFontId = addPreference( tr( "PREF_DIMENSIONS_FONT" ), aDimGroupId, LightApp_Preferences::Font, "Geometry", "dimensions_font" ); + + int f = QtxFontEdit::Family | QtxFontEdit::Size; + setPreferenceProperty( aDimFontId, "features", f ); + setPreferenceProperty( aDimFontId, "mode", QtxFontEdit::Custom ); + + Handle(Font_FontMgr) fmgr = Font_FontMgr::GetInstance(); + QString aFontFile = ""; + resMgr->value("resources", "GEOM", aFontFile); + aFontFile = aFontFile + QDir::separator() + "Y14.5M-2009.ttf"; + // add enginier font into combobox + int fontID = QFontDatabase::addApplicationFont( aFontFile ); + Handle(Font_SystemFont) sf = new Font_SystemFont( + new TCollection_HAsciiString("Y14.5M-2009"), + Font_FA_Regular, + new TCollection_HAsciiString(aFontFile.toLatin1().data()) ); + // register font in OCC font manager + fmgr->RegisterFont( sf, Standard_False ); + + // get list of supported fonts by OCC + QStringList anOCCFonts; + TColStd_SequenceOfHAsciiString theFontsNames; + fmgr->GetAvailableFontsNames( theFontsNames ); + for(Standard_Integer i=1; i<=theFontsNames.Length(); i++) { + Handle(TCollection_HAsciiString) str = theFontsNames(i); + anOCCFonts << str->ToCString(); + } + anOCCFonts.removeDuplicates(); + // set the supported fonts into combobox to use its only + setPreferenceProperty( aDimFontId, "fonts", anOCCFonts ); int aDimArrLengthId = addPreference( tr( "PREF_DIMENSIONS_ARROW_LENGTH" ), aDimGroupId, LightApp_Preferences::DblSpin, "Geometry", "dimensions_arrow_length" ); @@ -2353,9 +2402,6 @@ void GeometryGUI::createPreferences() int anAngUnitsId = addPreference( tr( "PREF_DIMENSIONS_ANGLE_UNITS" ), aDimGroupId, LightApp_Preferences::Selector, "Geometry", "dimensions_angle_units" ); - addPreference( tr( "PREF_DIMENSIONS_SHOW_UNITS" ), aDimGroupId, - LightApp_Preferences::Bool, "Geometry", "dimensions_show_units" ); - QStringList aListOfLengthUnits; aListOfLengthUnits << "m"; aListOfLengthUnits << "cm"; @@ -2370,6 +2416,9 @@ void GeometryGUI::createPreferences() setPreferenceProperty( aLengthUnitsId, "strings", aListOfLengthUnits ); setPreferenceProperty( anAngUnitsId, "strings", aListOfAngUnits ); + addPreference( tr( "PREF_DIMENSIONS_SHOW_UNITS" ), aDimGroupId, + LightApp_Preferences::Bool, "Geometry", "dimensions_show_units" ); + int aDimDefFlyout = addPreference( tr( "PREF_DIMENSIONS_DEFAULT_FLYOUT" ), aDimGroupId, LightApp_Preferences::DblSpin, "Geometry", "dimensions_default_flyout" ); @@ -2377,6 +2426,9 @@ void GeometryGUI::createPreferences() setPreferenceProperty( aDimDefFlyout, "max", 1e+9 ); setPreferenceProperty( aDimDefFlyout, "precision", 9 ); + addPreference( tr( "PREF_DIMENSIONS_USE_TEXT3D" ), aDimGroupId, + LightApp_Preferences::Bool, "Geometry", "dimensions_use_text3d" ); + int isoGroup = addPreference( tr( "PREF_ISOS" ), tabId ); setPreferenceProperty( isoGroup, "columns", 2 ); int isoU = addPreference( tr( "PREF_ISOS_U" ), isoGroup, @@ -2483,7 +2535,6 @@ void GeometryGUI::createPreferences() QList aMarkerTypeIndicesList; QList aMarkerTypeIconsList; - SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); for ( int i = GEOM::MT_POINT; i < GEOM::MT_USER; i++ ) { QString icoFile = QString( "ICON_VERTEX_MARKER_%1" ).arg( i ); QPixmap pixmap = resMgr->loadPixmap( "GEOM", tr( qPrintable( icoFile ) ) ); @@ -2645,11 +2696,12 @@ void GeometryGUI::preferencesChanged( const QString& section, const QString& par } else if ( param == QString("dimensions_color") || param == QString("dimensions_line_width") || - param == QString("dimensions_font_height") || + param == QString("dimensions_font") || param == QString("dimensions_arrow_length") || param == QString("dimensions_show_units") || param == QString("dimensions_length_units") || param == QString("dimensions_angle_units") || + param == QString("dimensions_use_text3d") || param == QString("label_color") ) { SalomeApp_Application* anApp = getApp(); @@ -3468,3 +3520,8 @@ void GeometryGUI::dropObjects( const DataObjectList& what, SUIT_DataObject* wher // update Object browser getApp()->updateObjectBrowser( false ); } + +void GeometryGUI::emitDimensionsUpdated( QString entry ) +{ + emit DimensionsUpdated( entry ); +} diff --git a/src/GEOMGUI/GeometryGUI.h b/src/GEOMGUI/GeometryGUI.h index 53d314ed1..f0abf2da2 100644 --- a/src/GEOMGUI/GeometryGUI.h +++ b/src/GEOMGUI/GeometryGUI.h @@ -64,6 +64,7 @@ class LightApp_Selection; class SUIT_ViewManager; class SalomeApp_Study; class GEOMGUI_CreationInfoWdg; +class GEOMGUI_TextTreeWdg; //================================================================================= // class : GeometryGUI @@ -148,6 +149,8 @@ public: SUIT_DataObject* where, const int row, Qt::DropAction action ); + void emitDimensionsUpdated( QString entry ); + public slots: virtual bool deactivateModule( SUIT_Study* ); virtual bool activateModule( SUIT_Study* ); @@ -176,6 +179,7 @@ signals : void SignalDefaultStepValueChanged( double newVal ); void SignalDependencyTreeParamChanged( const QString&, const QString& ); void SignalDependencyTreeRenameObject( const QString& ); + void DimensionsUpdated( const QString& ); protected: virtual LightApp_Selection* createSelection() const; @@ -224,6 +228,8 @@ private: GEOMGUI_CreationInfoWdg* myCreationInfoWdg; + GEOMGUI_TextTreeWdg* myTextTreeWdg; + SALOME_ListIO myTopLevelIOList; friend class DisplayGUI; diff --git a/src/MeasureGUI/MeasureGUI_CreateDimensionDlg.cxx b/src/MeasureGUI/MeasureGUI_CreateDimensionDlg.cxx index 2576676b2..45ef0135f 100644 --- a/src/MeasureGUI/MeasureGUI_CreateDimensionDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_CreateDimensionDlg.cxx @@ -495,12 +495,13 @@ Handle(AIS_Dimension) MeasureGUI_CreateDimensionDlg::CreateDimension() QColor aQColor = aResMgr->colorValue ( "Geometry", "dimensions_color", QColor( 0, 255, 0 ) ); int aLineWidth = aResMgr->integerValue( "Geometry", "dimensions_line_width", 1 ); - double aFontHeight = aResMgr->doubleValue ( "Geometry", "dimensions_font_height", 10 ); + QFont aFont = aResMgr->fontValue ( "Geometry", "dimensions_font", QFont("Y14.5M-2009", 14) ); double anArrowLength = aResMgr->doubleValue ( "Geometry", "dimensions_arrow_length", 5 ); double aDefFlyout = aResMgr->doubleValue ( "Geometry", "dimensions_default_flyout", 20 ); bool isUnitsShown = aResMgr->booleanValue( "Geometry", "dimensions_show_units", false ); QString aUnitsLength = aResMgr->stringValue ( "Geometry", "dimensions_length_units", "m" ); QString aUnitsAngle = aResMgr->stringValue ( "Geometry", "dimensions_angle_units", "deg" ); + bool aUseText3d = aResMgr->booleanValue( "Geometry", "dimensions_use_text3d", false ); OCCViewer_ViewWindow* anActiveView = NULL; @@ -610,10 +611,12 @@ Handle(AIS_Dimension) MeasureGUI_CreateDimensionDlg::CreateDimension() aStyle->SetCommonColor( aColor ); aStyle->MakeUnitsDisplayed( (Standard_Boolean) isUnitsShown ); - aStyle->MakeText3d( Standard_True ); + aStyle->MakeText3d( aUseText3d ); aStyle->MakeTextShaded( Standard_True ); - aStyle->SetExtensionSize( aFontHeight * 0.5 ); - aStyle->TextAspect()->SetHeight( aFontHeight ); + int fsize = aFont.pixelSize() != -1 ? aFont.pixelSize() : aFont.pointSize(); + aStyle->SetExtensionSize( fsize * 0.5 ); + aStyle->TextAspect()->SetFont( aFont.family().toLatin1().data() ); + aStyle->TextAspect()->SetHeight( fsize ); aStyle->ArrowAspect()->SetLength( anArrowLength ); aStyle->LineAspect()->SetWidth( aLineWidth ); diff --git a/src/MeasureGUI/MeasureGUI_ManageDimensionsDlg.cxx b/src/MeasureGUI/MeasureGUI_ManageDimensionsDlg.cxx index 7dfda2db9..370204f94 100644 --- a/src/MeasureGUI/MeasureGUI_ManageDimensionsDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_ManageDimensionsDlg.cxx @@ -29,6 +29,7 @@ #include "MeasureGUI_DimensionFilter.h" #include +#include #include #include #include @@ -771,6 +772,8 @@ bool MeasureGUI_ManageDimensionsDlg::ClickOnApply() mySavedPropertyState.SaveToAttribute( aStudy, myEditObject->GetStudyEntry() ); + myGeomGUI->emitDimensionsUpdated( QString( myEditObject->GetStudyEntry() ) ); + return true; } @@ -807,6 +810,8 @@ void MeasureGUI_ManageDimensionsDlg::OnFinish() QVariant() ); redisplay( myEditObject.get() ); + + myGeomGUI->emitDimensionsUpdated( QString( myEditObject->GetStudyEntry() ) ); } //================================================================================= -- 2.39.2