Salome HOME
Merge remote branch 'origin/V7_dev' into V8_0_0_BR
[modules/geom.git] / src / GEOMToolsGUI / GEOMToolsGUI_PublishDlg.cxx
1 // Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // GEOM GEOMGUI : GUI for Geometry component
24 // File   : GEOMToolsGUI_PublishDlg.cxx
25 // Author : Roman NIKOLAEV, Open CASCADE S.A.S.
26 //
27
28 #include "GEOMToolsGUI_PublishDlg.h"
29 #include "GEOM_Displayer.h"
30 #include "GeometryGUI.h"
31
32 //SALOME GUI includes
33 #include <SUIT_Session.h>
34 #include <SUIT_DataObject.h>
35 #include <SUIT_ResourceMgr.h>
36
37 #include <CAM_DataModel.h>
38
39 #include <SalomeApp_DataObject.h>
40
41 #include <SalomeApp_Application.h>
42 #include <SalomeApp_Module.h>
43 #include <SalomeApp_Study.h>
44
45
46 //QT includes
47 #include <QHeaderView>
48 #include <QGridLayout>
49 #include <QTreeWidget>
50 #include <QPushButton>
51
52 #define  DEFAULT_MARGIN 11
53 #define  DEFAULT_SPACING 6
54
55 #define VISIBILITY_COLUMN_WIDTH 25
56
57 GEOMToolsGUI_PublishDlg::GEOMToolsGUI_PublishDlg(QWidget* parent):
58   QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint)
59 {
60    setObjectName( "GEOMToolsGUI_PublishDlg" );
61    setModal( false );
62    setWindowTitle( tr( "GEOM_PUBLISH_OBJECTS_TLT" ) );
63
64    setAttribute(Qt::WA_DeleteOnClose);
65    
66    //List of the objects
67    myTreeWidget = new QTreeWidget(this);
68    //myTreeWidget->setRootIsDecorated(false);
69    //myTreeWidget->setUniformRowHeights(true);
70    myTreeWidget->setAllColumnsShowFocus(true);
71    myTreeWidget->setColumnCount(3);
72
73    QStringList columnNames;
74    columnNames.append(tr("OBJECT_NAME"));
75    columnNames.append(tr("OBJECT_ENTRY"));
76    columnNames.append("");
77    QTreeWidgetItem * headerItem = new QTreeWidgetItem(columnNames);
78    SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
79    headerItem->setIcon( 2, QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_VISIBLE" ) ) ) );
80    myTreeWidget->setHeaderItem ( headerItem );
81 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
82    myTreeWidget->header()->setClickable( true );
83 #else
84    myTreeWidget->header()->setSectionsClickable( true );
85 #endif
86    myTreeWidget->header()->setSortIndicatorShown( true );
87    myTreeWidget->header()->moveSection( 2, 0 );
88    myTreeWidget->setSortingEnabled( true );
89    myTreeWidget->setColumnWidth( 2, VISIBILITY_COLUMN_WIDTH );
90
91    //Select All button
92    QPushButton* selectAllButton = new  QPushButton( tr("SELECT_ALL"),this );
93
94    //Unselect Select All button
95    QPushButton* unselectAllButton = new  QPushButton( tr("UNSELECT_ALL"),this );
96
97    //Publish button
98    QPushButton* publishButton = new QPushButton( tr("GEOM_PUBLISH_BTN"),this );
99
100    //Publish and Close button
101    QPushButton* publishCloseButton = new QPushButton( tr("GEOM_PUBLISH_CLOSE_BTN"), this );
102    
103    //Close button
104    QPushButton* closeButton = new QPushButton( tr("GEOM_BUT_CLOSE"), this );
105    
106    QGridLayout* gridLayout = new QGridLayout(this);
107    gridLayout->setMargin(DEFAULT_MARGIN);
108    gridLayout->setSpacing(DEFAULT_SPACING);
109
110    gridLayout->addWidget(myTreeWidget, 0, 0, 3, 3);
111    gridLayout->addWidget(selectAllButton, 0, 3, 1, 1);
112    gridLayout->addWidget(unselectAllButton, 1, 3, 1, 1);
113    gridLayout->addItem( new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 2, 3, 1, 1);
114    gridLayout->addWidget(publishCloseButton, 3, 0, 1, 1); 
115    gridLayout->addWidget(publishButton, 3, 1, 1, 1);
116    gridLayout->addItem( new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum), 3, 2, 1, 1);
117    gridLayout->addWidget(closeButton, 3, 3, 1, 1);
118
119    //Connect signals and slots
120    connect( myTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(onItemClicked(QTreeWidgetItem*, int)) );
121
122    connect( selectAllButton, SIGNAL(clicked()), this, SLOT(clickOnSelectAll()) );
123    connect( unselectAllButton, SIGNAL(clicked()), this, SLOT(clickOnUnSelectAll()) );
124    
125    connect(publishCloseButton, SIGNAL(clicked()), this, SLOT(clickOnOk()));
126    connect(publishButton, SIGNAL(clicked()), this, SLOT(clickOnApply()));
127    connect(closeButton, SIGNAL(clicked()), this, SLOT(reject()));
128
129    initData();
130 }
131
132 //=================================================================================
133 // function : ~GEOMToolsGUI_PublishDlg()
134 // purpose  : Destroys the object and frees any allocated resources
135 //=================================================================================
136 GEOMToolsGUI_PublishDlg::~GEOMToolsGUI_PublishDlg()
137 {
138   SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
139   if ( app ) {
140     SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
141     if ( appStudy ) {
142       _PTR(Study) aStudy = appStudy->studyDS();
143       if ( aStudy ) {
144         GEOM_Displayer displayer ( appStudy );
145         QTreeWidgetItemIterator it( myTreeWidget );
146         while ( *it ) {
147           QString entry = myEntryToItem.key( *it );
148           _PTR(SObject) SO ( aStudy->FindObjectID( qPrintable( entry ) ) );
149           if ( SO ) {
150             GEOM::GEOM_Object_var aGeomObject = GEOM::GEOM_Object::_narrow( GeometryGUI::ClientSObjectToObject( SO ) );
151             if ( CORBA::is_nil( aGeomObject ) ) continue;
152             if ( displayer.IsDisplayed( aGeomObject->GetStudyEntry() ) ) {
153               Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject( aGeomObject->GetStudyEntry(), "GEOM", "" );
154               displayer.Erase( io );
155             }
156           }
157           ++it;
158         }
159         displayer.UpdateViewer();
160       }
161     }
162   }
163 }
164
165 //=================================================================================
166 // function : initData()
167 // purpose  : Fill dialog after opening
168 //=================================================================================
169 void GEOMToolsGUI_PublishDlg::initData() {
170   SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
171   if(!app)
172     return;
173   
174   SalomeApp_Module* module = dynamic_cast<SalomeApp_Module*>(app->activeModule());
175   
176   if(!module)
177     return;
178
179   CAM_DataModel* dataModel = module->dataModel();
180   if(!dataModel)
181     return;
182   
183   myGeomRoot = dynamic_cast<SalomeApp_DataObject*>(dataModel->root());
184
185   if(!myGeomRoot)
186     return;
187
188   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
189   if(!appStudy ) 
190     return;
191
192   _PTR(Study) aStudy = appStudy->studyDS();
193   if(!aStudy)
194     return;
195
196   buildTree(aStudy, myGeomRoot);
197
198   myTreeWidget->resizeColumnToContents(0);
199   myTreeWidget->resizeColumnToContents(1);
200   myTreeWidget->sortByColumn(0, Qt::AscendingOrder);
201 }
202
203 //=================================================================================
204 // function : createItem()
205 // purpose  :
206 //=================================================================================
207 QTreeWidgetItem* GEOMToolsGUI_PublishDlg::createItem(QTreeWidgetItem* theParent, Pair theAttributes, bool isCheckable) {
208   QStringList aList;
209   aList<<theAttributes.second<<theAttributes.first<<"";
210   QTreeWidgetItem* anItem = new QTreeWidgetItem(aList);
211   
212   if(isCheckable)
213     anItem->setCheckState(0, Qt::Unchecked);
214   else {
215     anItem->setFlags(anItem->flags() & ~Qt::ItemIsUserCheckable);
216   }
217   
218   if(theParent)
219     theParent->addChild(anItem);
220   else 
221     myTreeWidget->addTopLevelItem(anItem);
222
223   myEntryToItem.insert(theAttributes.first, anItem);
224   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
225   anItem->setIcon( 2, QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_INVISIBLE" ) ) ) );
226   anItem->setExpanded(true);
227   return anItem;
228 }
229
230 //=================================================================================
231 // function : findParentItem()
232 // purpose  :
233 //=================================================================================
234 QTreeWidgetItem* GEOMToolsGUI_PublishDlg::findParentItem(_PTR(Study) theStudy, SalomeApp_DataObject* theObject, BufferedList& theList ) {
235   
236   QTreeWidgetItem* aResult = NULL;
237   SalomeApp_DataObject* aParrent = dynamic_cast<SalomeApp_DataObject*>(theObject->parent());
238   if(aParrent) {
239     QString targetEntry = aParrent->entry();
240     if( !(aResult = myEntryToItem.value(targetEntry)) ) {
241       if( aParrent != myGeomRoot ) {
242         QString aName;
243         _PTR(SObject) aSO ( theStudy->FindObjectID(qPrintable(aParrent->entry())));
244         _PTR(GenericAttribute) anAttr;
245         if ( aSO->FindAttribute(anAttr, "AttributeName") ) {
246           _PTR(AttributeName) anAttrName (anAttr);
247           aName = anAttrName->Value().c_str();
248         }
249         theList.push_front(qMakePair(targetEntry, aName));
250         aResult = findParentItem(theStudy,aParrent,theList);
251       } else {
252         //Publish List
253         for(int i = 0; i < theList.size(); i++ ) {
254           aResult = createItem(aResult, theList[i], false);
255         }
256         theList.clear();
257       }
258     } else {
259       //Publish List
260       for(int i = 0; i < theList.size(); i++ ) {
261         aResult = createItem(aResult, theList[i], false);
262       }
263       theList.clear();
264     }
265   }
266   return aResult;
267 }
268
269 //=================================================================================
270 // function : buildTree()
271 // purpose  :
272 //=================================================================================
273 void GEOMToolsGUI_PublishDlg::buildTree(_PTR(Study) theStudy, SalomeApp_DataObject* theItem) {
274   if(!theItem || theItem->isReference())
275     return;
276   
277   if(theItem != myGeomRoot) {
278
279     //If object hasn't "AttributeDrawable" => it visible
280     bool isDrawable = true;
281     _PTR(SObject) SO ( theStudy->FindObjectID(qPrintable(theItem->entry())));
282     _PTR(GenericAttribute) anAttr;
283     if ( SO && SO->FindAttribute(anAttr, "AttributeDrawable") ) {
284       _PTR(AttributeDrawable) aDrw (anAttr);
285       isDrawable = aDrw->IsDrawable();
286     }
287     
288     if(!isDrawable) {
289       QString aName;
290       if ( SO->FindAttribute(anAttr, "AttributeName") ) {
291         _PTR(AttributeName) aAttrName (anAttr);
292         aName = aAttrName->Value().c_str();
293       }
294       BufferedList aList;
295       QTreeWidgetItem* parentItem = findParentItem(theStudy, theItem, aList);
296       createItem(parentItem,qMakePair(theItem->entry(),aName),true);
297     }
298   }
299   
300   DataObjectList listObj = theItem->children( false );
301   DataObjectList::iterator itr = listObj.begin();
302   while( itr != listObj.end()) {
303     buildTree(theStudy, dynamic_cast<SalomeApp_DataObject*>(*itr));
304     itr++;
305   }
306 }
307
308 //=================================================================================
309 // function : clickOnApply()
310 // purpose  : Called then "Publish" button clicked
311 //=================================================================================
312 void GEOMToolsGUI_PublishDlg::clickOnApply() {
313   SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
314   if(!app)
315     return;
316   
317   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
318   if(!appStudy ) 
319     return;
320
321   _PTR(Study) aStudy = appStudy->studyDS();
322   if(!aStudy)
323     return;
324
325
326   QList<QTreeWidgetItem*> toProcess;
327   getDrawableList(myTreeWidget->invisibleRootItem(), toProcess);
328
329   _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
330   for( int i = 0; i < toProcess.count(); i++) {
331     QTreeWidgetItem* item = toProcess[i];
332     if(item) {
333       QString entry = myEntryToItem.key(item);
334       _PTR(SObject) SO ( aStudy->FindObjectID(qPrintable(entry)) );
335       if(!SO) continue;
336       _PTR(AttributeDrawable) aDrw = aBuilder->FindOrCreateAttribute( SO, "AttributeDrawable" );
337       aDrw->SetDrawable( true );
338       //Remove or change item
339       if( item != myTreeWidget->invisibleRootItem() ){
340         if( item->data(0,Qt::UserRole).toBool() ) {
341           delete item;
342         } else {
343           item->setFlags(item->flags() & ~Qt::ItemIsUserCheckable);
344           item->setData(0,Qt::CheckStateRole,QVariant());
345         }
346       }
347       // show references if any
348       std::vector< _PTR(SObject) > vso = aStudy->FindDependances(SO);
349       for ( int i = 0; i < vso.size(); i++ ) {
350         _PTR(SObject) refObj = vso[i];
351         aDrw = aBuilder->FindOrCreateAttribute( refObj, "AttributeDrawable" );
352         aDrw->SetDrawable( true );
353       }
354     }
355   }
356   toProcess.clear();
357   getTails(myTreeWidget->invisibleRootItem(), toProcess);
358   for( int i = 0; i < toProcess.count(); i++) {
359     if( toProcess[i] != myTreeWidget->invisibleRootItem() )
360       delete toProcess[i];
361   }
362       
363   app->updateObjectBrowser( false );
364   app->updateActions();
365 }
366
367 //=================================================================================
368 // function : clickOnOk()
369 // purpose  : Called then "Publish And Close" button clicked
370 //=================================================================================
371 void GEOMToolsGUI_PublishDlg::clickOnOk() {
372   clickOnApply();
373   accept();
374 }
375
376 //=================================================================================
377 // function : clickOnSelectAll()
378 // purpose  : Called then "Select All" button clicked
379 //=================================================================================
380 void GEOMToolsGUI_PublishDlg::clickOnSelectAll() {
381   processAll(myTreeWidget->invisibleRootItem(),Qt::Checked);
382 }
383
384 //=================================================================================
385 // function : clickOnUnSelectAll()
386 // purpose  : Called then "Unselect All" button clicked
387 //=================================================================================
388 void GEOMToolsGUI_PublishDlg::clickOnUnSelectAll() {
389   processAll(myTreeWidget->invisibleRootItem(),Qt::Unchecked);
390 }
391
392 //=================================================================================
393 // function : processAll()
394 // purpose  : 
395 //=================================================================================
396 void GEOMToolsGUI_PublishDlg::processAll(QTreeWidgetItem* theItem, Qt::CheckState state) {
397   
398     
399   if((theItem->flags() & Qt::ItemIsUserCheckable))
400     theItem->setCheckState(0,state);
401   
402   int i = 0;
403   while(i < theItem->childCount()) {
404     processAll(theItem->child(i), state);
405     i++;
406   }
407 }
408
409 //=================================================================================
410 // function : processAll()
411 // purpose  : 
412 //=================================================================================
413 void GEOMToolsGUI_PublishDlg::getDrawableList(QTreeWidgetItem* theItem, QList<QTreeWidgetItem*>& theList) {
414   
415   theItem->setData(0, Qt::UserRole, true);
416
417   if((theItem->flags() & Qt::ItemIsUserCheckable) ) {
418     theItem->setData(0, Qt::UserRole,theItem->checkState(0) == Qt::Checked);
419   }
420   
421   int i = 0;
422   while(i < theItem->childCount()) {
423     getDrawableList(theItem->child(i), theList);
424     theItem->setData( 0, Qt::UserRole, (theItem->data(0,Qt::UserRole).toBool() && theItem->child(i)->data(0,Qt::UserRole).toBool()) );
425     i++;
426   } 
427
428   if( (theItem->flags() & Qt::ItemIsUserCheckable) && (theItem->checkState(0) == Qt::Checked))
429     theList.push_back(theItem);
430 }
431
432
433 void GEOMToolsGUI_PublishDlg::getTails(QTreeWidgetItem* theItem, QList<QTreeWidgetItem*>& theList) {
434   int i = 0;
435   while(i < theItem->childCount()) {
436     getTails(theItem->child(i),theList);
437     i++;
438   }
439
440   if(theItem->data(0,Qt::UserRole).toBool())
441     theList.push_back(theItem);
442 }
443
444 //=================================================================================
445 // function : onItemClicked()
446 // purpose  : Called then treeItem clicked
447 //=================================================================================
448 void GEOMToolsGUI_PublishDlg::onItemClicked(QTreeWidgetItem* theItem, int theColumn) {
449   if ( theColumn == 2 ) {
450     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
451     if ( !app ) return;
452     SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
453     if ( !appStudy ) return;
454     _PTR(Study) aStudy = appStudy->studyDS();
455     if ( !aStudy ) return;
456     QString entry = myEntryToItem.key( theItem );
457     _PTR(SObject) SO ( aStudy->FindObjectID( qPrintable( entry ) ) );
458     if ( !SO ) return;
459     GEOM::GEOM_Object_var aGeomObject = GEOM::GEOM_Object::_narrow( GeometryGUI::ClientSObjectToObject( SO ) );
460     if ( CORBA::is_nil( aGeomObject ) ) return;
461     GEOM_Displayer displayer ( appStudy );
462     SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
463     Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject( aGeomObject->GetStudyEntry(), "GEOM", "" );
464     if ( displayer.IsDisplayed( aGeomObject->GetStudyEntry() ) ) {
465       theItem->setIcon( 2, QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_INVISIBLE" ) ) ) );
466       displayer.Erase( io );
467     }
468     else {
469       theItem->setIcon( 2, QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_VISIBLE" ) ) ) );
470       displayer.Display( io );
471     }
472     displayer.UpdateViewer();
473   }
474 }
475