Salome HOME
Merge from V6_main 11/02/2013
[modules/geom.git] / src / GEOMToolsGUI / GEOMToolsGUI_MarkerDlg.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // File   : GEOMToolsGUI_MarkerDlg.cxx
21 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
22
23 #include "GEOMToolsGUI_MarkerDlg.h"
24
25 #include <GeometryGUI.h>
26 #include <GEOM_Constants.h>
27 #include <GEOM_Displayer.h>
28
29 #include <Basics_OCCTVersion.hxx>
30
31 #include <QtxComboBox.h>
32 #include <SUIT_ResourceMgr.h>
33 #include <SUIT_Session.h>
34 #include <SUIT_ViewWindow.h>
35 #include <SUIT_Desktop.h>
36 #include <SUIT_ViewManager.h>
37 #include <LightApp_SelectionMgr.h>
38 #include <SalomeApp_Application.h>
39 #include <SalomeApp_Study.h>
40 #include <SALOME_ListIO.hxx>
41 #include <SALOME_ListIteratorOfListIO.hxx>
42
43 #include <QButtonGroup>
44 #include <QGridLayout>
45 #include <QHBoxLayout>
46 #include <QKeyEvent>
47 #include <QLabel>
48 #include <QPushButton>
49 #include <QRadioButton>
50 #include <QStackedWidget>
51
52 #define MARGIN  9
53 #define SPACING 6
54
55 GEOMToolsGUI_MarkerDlg::GEOMToolsGUI_MarkerDlg( QWidget* parent )
56   : QDialog ( parent )
57 {
58   setWindowTitle( tr( "SET_MARKER_TLT" ) );
59   setSizeGripEnabled( true );
60   setModal( true );
61
62   // ---
63
64   QRadioButton* aStandardTypeRB = new QRadioButton( tr( "STANDARD_MARKER" ), this );
65   QRadioButton* aCustomTypeRB   = new QRadioButton( tr( "CUSTOM_MARKER" ), this );
66   myTypeGroup = new QButtonGroup( this );
67   myTypeGroup->addButton( aStandardTypeRB, 0 );
68   myTypeGroup->addButton( aCustomTypeRB,   1 );
69
70   QHBoxLayout* aRadioLayout = new QHBoxLayout;
71   aRadioLayout->setMargin( 0 );
72   aRadioLayout->setSpacing( SPACING );
73   aRadioLayout->addWidget( aStandardTypeRB );
74   aRadioLayout->addWidget( aCustomTypeRB );
75
76   // ---
77
78   myWGStack = new QStackedWidget( this );
79   myWGStack->setFrameStyle( QFrame::Box | QFrame::Sunken );
80
81   // ---
82
83   QWidget* aStdWidget = new QWidget( myWGStack );
84
85   QLabel* aTypeLab  = new QLabel( tr( "TYPE" ),  aStdWidget );
86   QLabel* aScaleLab = new QLabel( tr( "SCALE" ), aStdWidget );
87
88   myStdTypeCombo  = new QtxComboBox( aStdWidget );
89   myStdScaleCombo = new QtxComboBox( aStdWidget );
90
91   QGridLayout* aStdLayout = new QGridLayout;
92   aStdLayout->setMargin( MARGIN );
93   aStdLayout->setSpacing( SPACING );
94   aStdLayout->addWidget( aTypeLab,        0, 0 );
95   aStdLayout->addWidget( myStdTypeCombo,  0, 1 );
96   aStdLayout->addWidget( aScaleLab,       1, 0 );
97   aStdLayout->addWidget( myStdScaleCombo, 1, 1 );
98   aStdWidget->setLayout( aStdLayout );
99
100   // ---
101
102   QWidget* aCustomWidget = new QWidget( myWGStack );
103
104   QLabel* aCustomLab = new QLabel( tr( "CUSTOM" ), aCustomWidget );
105   myCustomTypeCombo = new QtxComboBox( aCustomWidget );
106   QPushButton* aBrowseBtn = new QPushButton( tr( "BROWSE" ), aCustomWidget );
107
108   QGridLayout* aCustomLayout = new QGridLayout;
109   aCustomLayout->setMargin( MARGIN );
110   aCustomLayout->setSpacing( SPACING );
111   aCustomLayout->addWidget( aCustomLab,        0, 0 );
112   aCustomLayout->addWidget( myCustomTypeCombo, 0, 1 );
113   aCustomLayout->addWidget( aBrowseBtn,       0, 2 );
114   aCustomLayout->setRowStretch( 1, 5 );
115   aCustomWidget->setLayout( aCustomLayout );
116
117   // ---
118   
119   myWGStack->insertWidget( 0, aStdWidget );
120   myWGStack->insertWidget( 1, aCustomWidget );
121
122   // ---
123   
124   QPushButton* aOkBtn     = new QPushButton( tr( "OK_BTN" ),     this );
125   aOkBtn->setAutoDefault( true ); aOkBtn->setDefault( true ); 
126   QPushButton* aCancelBtn = new QPushButton( tr( "CANCEL_BTN" ), this );
127   aCancelBtn->setAutoDefault( true );
128   QPushButton* aHelpBtn   = new QPushButton( tr( "HELP_BTN" ), this );
129   aHelpBtn->setAutoDefault( true );
130
131   QHBoxLayout* aBtnLayout = new QHBoxLayout;
132   aBtnLayout->setMargin( 0 );
133   aBtnLayout->setSpacing( SPACING );
134   aBtnLayout->addWidget( aOkBtn );
135   aBtnLayout->addSpacing( 10 );
136   aBtnLayout->addStretch();
137   aBtnLayout->addWidget( aCancelBtn );
138   aBtnLayout->addWidget( aHelpBtn );
139
140   // ---
141
142   QVBoxLayout* aTopLayout = new QVBoxLayout;
143   aTopLayout->setMargin( MARGIN );
144   aTopLayout->setSpacing( SPACING );
145   aTopLayout->addLayout( aRadioLayout );
146   aTopLayout->addWidget( myWGStack );
147   aTopLayout->addLayout( aBtnLayout );
148   setLayout( aTopLayout );
149
150   // ---
151
152   connect( myTypeGroup, SIGNAL( buttonClicked( int ) ), myWGStack, SLOT( setCurrentIndex( int ) ) );
153   connect( aBrowseBtn,  SIGNAL( clicked() ), this, SLOT( browse() ) );
154   connect( aOkBtn,      SIGNAL( clicked() ), this, SLOT( accept() ) );
155   connect( aCancelBtn,  SIGNAL( clicked() ), this, SLOT( reject() ) );
156   connect( aHelpBtn,    SIGNAL( clicked() ), this, SLOT( help() ) );
157
158   // ---
159
160   aStandardTypeRB->setChecked( true );
161   init();
162 }
163
164 GEOMToolsGUI_MarkerDlg::~GEOMToolsGUI_MarkerDlg()
165 {
166   myOperation->UnRegister();
167 }
168
169 void GEOMToolsGUI_MarkerDlg::setStandardMarker( GEOM::marker_type type, GEOM::marker_size size )
170 {
171   if ( type > GEOM::MT_NONE && type < GEOM::MT_USER ) {
172     myTypeGroup->button( 0 )->setChecked( true );
173     myWGStack->setCurrentIndex( 0 );
174     myStdTypeCombo->setCurrentIndex( (int)type - 1 );
175 #ifdef WNT
176     int asize = max( (int)GEOM::MS_10, min( (int)GEOM::MS_70, (int)size ) );
177 #else
178     int asize = std::max( (int)GEOM::MS_10, std::min( (int)GEOM::MS_70, (int)size ) );
179 #endif
180     myStdScaleCombo->setCurrentIndex( asize-1 );
181   }
182 }
183
184 void GEOMToolsGUI_MarkerDlg::setCustomMarker( int id )
185 {
186   if ( id > 0 ) {
187     myTypeGroup->button( 1 )->setChecked( true );
188     myWGStack->setCurrentIndex( 1 );
189     addTexture( id );
190     myCustomTypeCombo->setCurrentId( id );
191   }
192 }
193
194 GEOM::marker_type GEOMToolsGUI_MarkerDlg::getMarkerType() const
195 {
196   return myWGStack->currentIndex() == 0 ? (GEOM::marker_type)myStdTypeCombo->currentId() : GEOM::MT_USER;
197 }
198
199 GEOM::marker_size GEOMToolsGUI_MarkerDlg::getStandardMarkerScale() const
200 {
201   return myWGStack->currentIndex() == 0 ? (GEOM::marker_size)myStdScaleCombo->currentId() : GEOM::MS_NONE;
202 }
203
204 int GEOMToolsGUI_MarkerDlg::getCustomMarkerID() const
205 {
206   return myWGStack->currentIndex() == 1 ? myCustomTypeCombo->currentId() : 0;
207 }
208
209 void GEOMToolsGUI_MarkerDlg::accept()
210 {
211   if ( getStudy() ) {
212     LightApp_SelectionMgr* selMgr = qobject_cast<SalomeApp_Application*>( getStudy()->application() )->selectionMgr();
213     
214     SUIT_ViewWindow* window =  getStudy()->application()->desktop()->activeWindow();
215     if (window && window->getViewManager()) {
216       int mgrId = window->getViewManager()->getGlobalId();
217       if ( selMgr ) {
218         SALOME_ListIO selected;
219         selMgr->selectedObjects( selected );
220         if ( !selected.IsEmpty() ) {
221           _PTR(Study) study = getStudy()->studyDS();
222           for ( SALOME_ListIteratorOfListIO it( selected ); it.More(); it.Next() ) {
223             _PTR(SObject) aSObject( study->FindObjectID( it.Value()->getEntry() ) );
224             GEOM::GEOM_Object_var anObject =
225               GEOM::GEOM_Object::_narrow( GeometryGUI::ClientSObjectToObject( aSObject ) );
226             if ( !anObject->_is_nil() ) {
227               if ( myWGStack->currentIndex() == 0 ) {
228                 anObject->SetMarkerStd( getMarkerType(), getStandardMarkerScale() );
229                 QString aMarker = "%1%2%3";
230                 aMarker = aMarker.arg(getMarkerType());
231                 aMarker = aMarker.arg(GEOM::subSectionSeparator());
232                 aMarker = aMarker.arg(getStandardMarkerScale());
233                 getStudy()->setObjectProperty(mgrId ,it.Value()->getEntry(),GEOM::propertyName( GEOM::PointMarker ), aMarker);
234               }
235               else if ( getCustomMarkerID() > 0 ) {
236                 anObject->SetMarkerTexture( getCustomMarkerID() );
237                 getStudy()->setObjectProperty(mgrId ,it.Value()->getEntry(),GEOM::propertyName( GEOM::PointMarker ), QString::number(getCustomMarkerID()));
238               }
239             }
240           }
241           GEOM_Displayer displayer( getStudy() );
242           displayer.Redisplay( selected, true );
243           selMgr->setSelectedObjects( selected );
244         }
245       }
246     }
247   }
248   QDialog::accept();
249 }
250
251 void GEOMToolsGUI_MarkerDlg::keyPressEvent( QKeyEvent* e )
252 {
253   if ( e->key() == Qt::Key_F1 )
254     help();
255   QDialog::keyPressEvent( e );
256 }
257
258 void GEOMToolsGUI_MarkerDlg::init()
259 {
260   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
261
262   // ---
263
264   for ( int i = GEOM::MT_POINT; i < GEOM::MT_USER; i++ ) {
265     QString icoFile = QString( "ICON_VERTEX_MARKER_%1" ).arg( i );
266     QPixmap pixmap = resMgr->loadPixmap( "GEOM", tr( qPrintable( icoFile ) ) );
267     myStdTypeCombo->addItem( pixmap, QString() );
268     myStdTypeCombo->setId( myStdTypeCombo->count()-1, i );
269   }
270
271   // ---
272
273   for ( int i = GEOM::MS_10; i <= GEOM::MS_70; i++ ) {
274     myStdScaleCombo->addItem( QString::number( (i-1)*0.5 + 1.0 ) );
275     myStdScaleCombo->setId( myStdScaleCombo->count()-1, i );
276   }
277
278   // ---
279   
280   GEOM::GEOM_Gen_var engine = GeometryGUI::GetGeomGen();
281   myOperation = engine->GetIInsertOperations( getStudy()->id() );
282   GEOM::ListOfLong_var ids = myOperation->GetAllTextures();
283   for ( int i = 0; i < ids->length(); i++ )
284     addTexture( ids[i] );
285
286   // ---
287
288   GEOM::marker_type aType    = (GEOM::marker_type)-1;
289   GEOM::marker_size aSize    = (GEOM::marker_size)-1;
290   int               aTexture = 0;
291   if ( getStudy() ) {
292     LightApp_SelectionMgr* selMgr = qobject_cast<SalomeApp_Application*>( getStudy()->application() )->selectionMgr();
293     if ( selMgr ) {
294       SALOME_ListIO selected;
295       selMgr->selectedObjects( selected );
296       if ( !selected.IsEmpty() ) {
297         _PTR(Study) study = getStudy()->studyDS();
298         for ( SALOME_ListIteratorOfListIO it( selected ); it.More(); it.Next() ) {
299           _PTR(SObject) aSObject( study->FindObjectID( it.Value()->getEntry() ) );
300           GEOM::GEOM_Object_var anObject =
301             GEOM::GEOM_Object::_narrow( GeometryGUI::ClientSObjectToObject( aSObject ) );
302           if ( !anObject->_is_nil() ) {
303             GEOM::marker_type mtype = anObject->GetMarkerType();
304             if ( aType == -1 )
305               aType = mtype;
306             else if ( aType != mtype ) {
307               aType = (GEOM::marker_type)-1;
308               break;
309             }
310             if ( mtype > GEOM::MT_NONE && mtype < GEOM::MT_USER ) {
311               GEOM::marker_size msize = anObject->GetMarkerSize();
312               if ( aSize == -1 )
313                 aSize = msize;
314               else if ( aSize != msize )
315                 break;
316             }
317             else if ( mtype == GEOM::MT_USER ) {
318               int mtexture = anObject->GetMarkerTexture();
319               if ( aTexture == 0 )
320                 aTexture = mtexture;
321               else if ( aTexture != mtexture )
322                 break;
323             }
324           }
325         }
326       }
327     }
328   }
329   if ( aType > GEOM::MT_NONE && aType < GEOM::MT_USER )
330     setStandardMarker( aType, aSize );
331   else if ( aType == GEOM::MT_USER )
332     setCustomMarker( aTexture );
333   else
334     setStandardMarker((GEOM::marker_type)(resMgr->integerValue("Geometry", "type_of_marker", (int)Aspect_TOM_PLUS) + 1),
335                       (GEOM::marker_size)(resMgr->integerValue("Geometry", "marker_scale", 1)));
336 }
337
338 void GEOMToolsGUI_MarkerDlg::addTexture( int id, bool select ) const
339 {
340   if ( id > 0 && myCustomTypeCombo->index( id ) == -1 ) {
341     int tWidth, tHeight;
342
343 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
344     Handle(TColStd_HArray1OfByte) texture = GeometryGUI::getTexture(getStudy(), id, tWidth, tHeight);
345 #else
346     Handle(Graphic3d_HArray1OfBytes) texture = GeometryGUI::getTexture(getStudy(), id, tWidth, tHeight);
347 #endif
348
349     if ( !texture.IsNull() && texture->Length() == tWidth*tHeight/8 ) {
350       QImage image( tWidth, tHeight, QImage::Format_Mono );
351       image.setColor( 0, qRgba( 0, 0, 0, 0   ) );
352       image.setColor( 1, qRgba( 0, 0, 0, 255 ) );
353       int bytesperline = tWidth/8;
354       for ( int j = texture->Lower(); j <= texture->Upper(); j++ ) {
355         uchar val = (uchar)texture->Value( j );
356         for ( int k = 0; k < 8; k++ ) {
357           int row = ( j - texture->Lower() ) / bytesperline;
358           int col = ( ( j - texture->Lower() ) % bytesperline ) * 8 + k;
359           image.setPixel( row, col, ( val & (1<<(8-k-1)) ) ? 1 : 0 );
360         }
361       }
362       QPixmap pixmap = QPixmap::fromImage( image );
363       if ( !pixmap.isNull() ) {
364         myCustomTypeCombo->addItem( pixmap, QString::number( id ) );
365         myCustomTypeCombo->setId( myCustomTypeCombo->count()-1, id );
366         if ( select ) myCustomTypeCombo->setCurrentId( id );
367       }
368     }
369   }
370 }
371
372 SalomeApp_Study* GEOMToolsGUI_MarkerDlg::getStudy() const
373 {
374   return qobject_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
375 }
376
377 void GEOMToolsGUI_MarkerDlg::browse()
378 {
379   QStringList filters;
380   filters << tr( "Texture files (*.dat)" ) << tr( "All files (*)" );
381   QString aFileName = SUIT_Session::session()->activeApplication()->getFileName( true, QString(), filters.join( ";;" ), tr( "LOAD_TEXTURE_TLT" ), this );
382   if ( !aFileName.isEmpty() ) {
383     addTexture( myOperation->LoadTexture( aFileName.toLatin1().constData() ), true );
384   }
385 }
386
387 void GEOMToolsGUI_MarkerDlg::help()
388 {
389   if ( getStudy() ) {
390     SalomeApp_Application* app = qobject_cast<SalomeApp_Application*>( getStudy()->application() );
391     app->onHelpContextModule( "GEOM", "point_marker_page.html" );
392   }
393 }