1 // SALOME SALOMEGUI : implementation of desktop and GUI kernel
3 // Copyright (C) 2003 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.
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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : QAD_Study.cxx
25 // Author : Nicolas REJNERI
30 \class QAD_Study QAD_Study.h
31 \brief Study for QAD-based application.
34 #include "QAD_PyInterp.h" // this include must be first (see PyInterp_base.h)!
36 #include "QAD_Tools.h"
37 #include "QAD_Desktop.h"
38 #include "QAD_Study.h"
39 #include "QAD_RightFrame.h"
40 #include "QAD_LeftFrame.h"
41 #include "QAD_MessageBox.h"
42 #include "QAD_Application.h"
43 #include "QAD_ObjectBrowser.h"
44 #include "QAD_Config.h"
46 #include "utilities.h"
48 #include "SALOME_Selection.h"
49 #include "SALOME_TypeFilter.hxx"
50 #include "SALOME_InteractiveObject.hxx"
51 #include "SALOME_ListIteratorOfListIO.hxx"
53 #include <SALOMEconfig.h>
54 #include CORBA_SERVER_HEADER(SALOMEDS)
56 // OPEN CASCADE Include
57 #include <Standard_Failure.hxx>
60 #include <qapplication.h>
68 static int MYDEBUG = 1;
70 static int MYDEBUG = 0;
74 class TInitStudyThread : public QThread{
76 TInitStudyThread(const TInitStudyThread&);
79 TInitStudyThread(QAD_PyInterp*& theInterp, QMutex* theMutex):
81 myStudyLock(new ThreadLock(theMutex,"TInitStudyThread::TInitStudyThread"))
83 virtual ~TInitStudyThread() {
91 ThreadLock aPyLock = GetPyThreadLock("TInitStudyThread::aPyLock");
92 if(MYDEBUG) MESSAGE("TInitStudyThread::run()");
93 myInterp = new QAD_PyInterp();
94 myInterp->initialize();
101 QAD_PyInterp*& myInterp;
102 ThreadLock* myStudyLock;
109 QAD_Study::QAD_Study(QAD_Application* theApp,
110 SALOMEDS::Study_var theStudy,
111 const QString& thePath):
113 myOperationState(Undef),
115 myActiveStudyFrame(0),
116 myStudyFrameCount(0),
118 myTitle(QAD_Tools::getFileNameFromPath(thePath,true)),
125 myInitStudyThread(0),
126 myMutex(new QMutex())
128 myStudyFrames.setAutoDelete( true );
129 myOperations.setAutoDelete( true );
130 myChildWidgets.setAutoDelete( true );
132 /* create default selection */
133 //NRI Selection( "Salome" );
134 Selection( QAD_Application::getDesktop()->getComponentUserName( "KERNEL" ) );
136 /* create python interpreter */
137 QAD_PyInterp::init_python(); // initialize Python out of qthread
138 myInitStudyThread = new TInitStudyThread(myInterp,myMutex);
139 myInitStudyThread->start();
141 /* create study frame */
142 createStudyFrame( getNextStudyFrameName() );
144 /* set default Undo/Redo limit */
145 QAD_ASSERT_DEBUG_ONLY( !myStudy->_is_nil() );
146 SALOMEDS::StudyBuilder_var SB = myStudy->NewBuilder();
148 int aLocked = myStudy->GetProperties()->IsLocked();
149 if (aLocked) myStudy->GetProperties()->SetLocked(false);
150 SB->UndoLimit(QAD_Desktop::getUndoLevel());
151 if (aLocked) myStudy->GetProperties()->SetLocked(true);
155 void QAD_Study::Init()
163 QAD_Study::~QAD_Study ()
166 //SRN: added - clear selection in case the study will be loaded again so the title will coincide
167 SALOME_Selection::RemoveSelection( QString(myTitle + "_" + mySelection) );
170 ThreadLock aLock(myMutex,"QAD_Study::~QAD_Study()");
171 delete myInitStudyThread;
179 Returns TRUE if Study is created correctly. Returns FALSE otherwise.
181 bool QAD_Study::getResult()
187 //=======================================================================//
188 // StudyFrames management //
189 //=======================================================================//
193 void QAD_Study::addStudyFrame(QAD_StudyFrame* sf )
195 myStudyFrames.append( sf );
197 sf->getRightFrame()->getViewFrame()->setPopupServer( myApp );
198 // Provide the same common popup menu commands for both the Object Browser and 3D viewer
199 sf->getLeftFrame()->getObjectBrowser()->setPopupServer( myApp );
201 /* icon of Study Frame */
202 const QPixmap& icon = myApp->getApplicationIcon();
203 if ( !icon.isNull() )
204 sf->setIcon ( icon );
207 QAD_ASSERT ( connect( sf, SIGNAL(sfStudyFrameActivated(QAD_StudyFrame*) ),
208 SLOT(onStudyFrameActivated(QAD_StudyFrame*))) );
211 QAD_ASSERT ( connect( sf,
212 SIGNAL(sfStudyFrameClosing(QAD_StudyFrame*) ),
214 SLOT(onLastStudyFrameClosing(QAD_StudyFrame*))) );
217 myActiveStudyFrame = sf;
221 Removes studyframe from the list
223 void QAD_Study::removeStudyFrame( QAD_StudyFrame* sf )
226 if (!myStudy->IsEmpty()) {
227 SALOMEDS::SObject_var fatherSF = myStudy->FindObjectID(sf->entry());
228 if (!fatherSF->_is_nil()) {
229 SALOMEDS::StudyBuilder_var aStudyBuilder = myStudy->NewBuilder();
230 int aLocked = myStudy->GetProperties()->IsLocked();
231 if (aLocked) myStudy->GetProperties()->SetLocked(false);
232 aStudyBuilder->RemoveObject(fatherSF);
233 if (aLocked) myStudy->GetProperties()->SetLocked(true);
236 updateObjBrowser( true );
239 QAD_RightFrame* rightFrame = sf->getRightFrame();
241 QAD_ViewFrame* viewFrame = rightFrame->getViewFrame();
243 emit supervStudyFrameClosing( viewFrame );
246 myStudyFrames.removeRef( sf );
251 Returns number of study frames
253 int QAD_Study::getStudyFramesCount() const
255 return myStudyFrames.count();
259 Returns study frame by its index in list
261 QAD_StudyFrame* QAD_Study::getStudyFrame( unsigned i )
263 return myStudyFrames.at(i);
267 Returns study frame by its name or null if not found
269 QAD_StudyFrame* QAD_Study::getStudyFrameByName ( const QString& name )
271 for ( QAD_StudyFrame* sf = myStudyFrames.first(); sf; sf = myStudyFrames.next() )
273 if ( sf->title().compare(name) == 0 ) {
281 Returns first study frame in the list
283 QAD_StudyFrame* QAD_Study::getFirstStudyFrame()
285 return myStudyFrames.first();
289 Returns last study frame in the list
291 QAD_StudyFrame* QAD_Study::getLastStudyFrame()
293 return myStudyFrames.last();
297 Returns the vector of studyframes
299 const QList<QAD_StudyFrame>& QAD_Study::getStudyFrames() const
301 return myStudyFrames;
305 Returns the active study frame
307 QAD_StudyFrame* QAD_Study::getActiveStudyFrame() const
309 return myActiveStudyFrame;
312 //=======================================================================//
313 // Study properties //
314 //=======================================================================//
316 Returns reference to supporting application
318 QAD_Application* QAD_Study::getApp() const
324 Returns the name of document ( filename without path and extension )
326 const QString& QAD_Study::getTitle() const
332 Returns the absolute file path of this document
334 const QString& QAD_Study::getPath() const
340 Changes the name of document
342 void QAD_Study::setTitle( const QString& path )
346 QString title = QAD_Tools::getFileNameFromPath( path, true );
347 QAD_ASSERT_DEBUG_ONLY ( !title.isNull() );
349 for ( QAD_StudyFrame* sf = myStudyFrames.first(); sf ; sf = myStudyFrames.next() )
351 QString oldName = sf->title();
352 int k = oldName.find( myTitle, 0, false );
353 QString restName = ( oldName.length() > myTitle.length() + k) ?
354 oldName.right(oldName.length() - (myTitle.length() + k) + 1) :
361 int l = restName.find( "#", 0, false );
362 int ll = restName.length();
363 newName = title + restName.mid( l, ll-l );
365 newName = oldName.mid(0, k);
366 newName = newName + title + restName;
368 sf->setTitle( newName );
373 Selection( QAD_Application::getDesktop()->getActiveComponent() );
377 Returns whether the document is active
379 bool QAD_Study::isActive() const
385 Returns whether the document is read only
387 bool QAD_Study::isReadOnly() const
393 Sets read-only property
395 void QAD_Study::setReadOnly(bool state)
397 myIsReadOnly = state;
400 bool QAD_Study::isLocked()
403 if ( !CORBA::is_nil( myStudy ) )
404 state = myStudy->GetProperties()->IsLocked();
408 //=======================================================================//
409 // Study operations //
410 //=======================================================================//
412 Performs specific study frame related actions when it is activated.
413 By default resumes all suspended operations.
415 void QAD_Study::onStudyFrameActivated( QAD_StudyFrame* activeStudyFrame )
417 // static int IS_FIRST_STUDY = 1;
418 // if(IS_FIRST_STUDY){ //for normally initialize "salome.py and ..."
419 // _interp->run(""); IS_FIRST_STUDY = 0;
421 // bool found = false;
422 for ( QPtrListIterator<QAD_StudyFrame> it( myStudyFrames ); it.current(); ++it ) {
423 if ( it.current() == activeStudyFrame) { /* one of my study frames */
425 // if ( !myActiveStudyFrame || myActiveStudyFrame != activeStudyFrame ) {
426 myActiveStudyFrame = activeStudyFrame;
427 //NRI if ( !myIsActive ) {
429 resumeAllOperations();
430 /* activate application */
431 myApp->onStudyActivated( this );
438 // myActiveStudyFrame = 0;
443 Performs specific study related actions when it is deactivated.
444 By default suspends all performing operations.
446 void QAD_Study::onStudyDeactivated()
448 // MESSAGE ("QAD_Study::onStudyDeactivated init. ");
450 suspendAllOperations();
451 // MESSAGE ("QAD_Study::onStudyDeactivated done. ");
455 Closes all study frames of the study and performs other specific study
456 related actions needed for proper closing of the study
458 void QAD_Study::close()
461 if ( !myStudy->_is_nil() )
462 abortAllOperations();
463 /* clear each study frame */
464 for ( QAD_StudyFrame* sf = myStudyFrames.first(); sf; sf = myStudyFrames.first() ) {
468 QApplication::sendPostedEvents();
469 removeStudyFrame(sf);
472 /* delete all studyframes */
473 myStudyFrames.clear();
474 myOperations.clear();
475 myChildWidgets.clear();
477 // QWorkspace* ws = QAD_Application::getDesktop()->getMainFrame();
478 // if (/* !ws->activeWindow() && */ws->windowList().count() > 0 )
479 // ws->activateWindow(ws->windowList().last());
482 //=======================================================================//
483 // Operations management //
484 //=======================================================================//
486 Returns number of completed operations
488 int QAD_Study::getOperationsCount() const
490 return myOperations.count();
494 Returns the state of the last operation
496 OperationState QAD_Study::getOperationState() const
498 return myOperationState;
502 Returns operation by its index in list
504 QAD_Operation* QAD_Study::getOperation( unsigned i)
506 return ( myOperations.isEmpty() ? 0 : myOperations.at(i) );
510 Returns performing operation launched first
512 QAD_Operation* QAD_Study::getFirstOperation()
514 return ( myOperations.isEmpty() ? 0 : myOperations.first() );
518 Returns performing operation launched last
520 QAD_Operation* QAD_Study::getLastOperation()
522 return ( myOperations.isEmpty() ? 0 : myOperations.last() );
526 Aborts all performing operations
528 void QAD_Study::abortAllOperations()
530 for ( QAD_Operation* op = myOperations.last(); op;
531 op = myOperations.prev() )
536 Resumes all performing operations
538 void QAD_Study::resumeAllOperations()
540 for ( QAD_Operation* op = myOperations.first(); op;
541 op = myOperations.next() )
546 Suspendes all performing operations
548 void QAD_Study::suspendAllOperations()
550 // MESSAGE ( " QAD_Study::suspendAllOperations init. " )
551 for ( QAD_Operation* op = myOperations.last(); op;
552 op = myOperations.prev() )
557 Initializes the operation and checks its compatibility
558 with another operation in process if any.
559 Returns 'true' if init'ed OK, 'false' otherwise.
561 bool QAD_Study::initOperation( QAD_Operation* op )
564 { /* can't start a non-const operation */
565 if ( op->changesData() )
567 QAD_MessageBox::error1( QAD_Application::getDesktop(), tr("ERR_ERROR"),
568 tr("ERR_DOC_READONLY"), tr("BUT_OK") );
573 /* Add the new operation
575 if ( myOperations.isEmpty() )
576 myOperations.append( op );
579 /* Check compatibility of new operation with the existing operations.
580 Since each operations is checked in that way, it's enough to check
581 the last operation only */
582 if ( !getLastOperation()->compatibleWith( op ) )
584 if ( QAD_MessageBox::warn2( QAD_Application::getDesktop(), tr("WRN_WARNING"),
585 tr("QUE_ABORTCURRENTOPERATION"), tr("BUT_YES"),
586 tr("BUT_NO"), QAD_YES, QAD_NO, QAD_NO )
589 getLastOperation()->abort();
591 myOperations.append( op );
597 Called when operation was finished.
598 Removes appointed operation from the list and aborted all operations
601 void QAD_Study::clearOperation( QAD_Operation* op)
603 if ( myOperations.contains( op ) )
605 /* abort all the operations launched after 'op' */
606 for ( QAD_Operation* cur = myOperations.last(); cur;
607 cur = myOperations.prev() )
609 if ( cur == op ) break;
612 myOperations.remove( op );
619 QAD_StudyFrame* QAD_Study::createStudyFrame( const QString& title, ViewType theViewType)
621 QAD_Desktop* parent = QAD_Application::getDesktop();
622 //srn: Forbid appending Interface Applicative and its children to UseCase
623 myStudy->EnableUseCaseAutoFilling(false);
625 SALOMEDS::SComponent_var father = myStudy->FindComponent("Interface Applicative");
626 SALOMEDS::StudyBuilder_var aStudyBuilder = myStudy->NewBuilder();
627 SALOMEDS::GenericAttribute_var anAttr;
628 SALOMEDS::AttributeName_var aName;
629 SALOMEDS::AttributeComment_var aComment;
630 SALOMEDS::AttributeSelectable_var aSelAttr;
632 // mpv : where is "NewCommand" call?
633 // aStudyBuilder->CommitCommand();
635 // mpv : is study is locked, then next code will raise exception. So, temporary unlock study
636 int aLocked = myStudy->GetProperties()->IsLocked();
637 if (aLocked) myStudy->GetProperties()->SetLocked(false);
639 if ( father->_is_nil() ) {
640 father = aStudyBuilder->NewComponent("Interface Applicative");
641 anAttr = aStudyBuilder->FindOrCreateAttribute(father, "AttributeName");
642 aName = SALOMEDS::AttributeName::_narrow(anAttr);
643 aName->SetValue("Interface Applicative");
645 anAttr = aStudyBuilder->FindOrCreateAttribute(father, "AttributeSelectable");
646 aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr);
647 aSelAttr->SetSelectable(false);
650 //VRV: T2.5 - add default viewer
651 if(theViewType == VIEW_TYPE_MAX) {
652 QString viewerValue = QAD_CONFIG->getSetting( "Viewer:DefaultViewer" );
654 theViewType = (ViewType)viewerValue.toInt( &ok, 10 );
655 if (!ok || theViewType < VIEW_OCC || theViewType >= VIEW_TYPE_MAX)
656 theViewType = VIEW_VTK;
658 //QApplication::restoreOverrideCursor();
659 QAD_StudyFrame* sf = NULL;
660 SALOMEDS::SObject_var newObj = aStudyBuilder->NewObject(father);
661 if ( theViewType == VIEW_OCC) {
662 // MESSAGE ("Create Study Frame for OCC viewer");
663 sf = new QAD_StudyFrame ( this, parent->getMainFrame(),
667 Standard_CString name = CORBA::string_dup(sf->title().latin1());
668 anAttr = aStudyBuilder->FindOrCreateAttribute(newObj, "AttributeName");
669 aName = SALOMEDS::AttributeName::_narrow(anAttr);
670 aName->SetValue(name);
671 anAttr = aStudyBuilder->FindOrCreateAttribute(newObj, "AttributeComment");
672 aComment = SALOMEDS::AttributeComment::_narrow(anAttr);
673 aComment->SetValue("OCC");
675 anAttr = aStudyBuilder->FindOrCreateAttribute(newObj, "AttributeSelectable");
676 aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr);
677 aSelAttr->SetSelectable(false);
679 else if ( theViewType == VIEW_VTK) {
680 // MESSAGE ("Create Study Frame for VTK viewer");
681 sf = new QAD_StudyFrame ( this, parent->getMainFrame(),
684 Standard_CString name = strdup(sf->title().latin1());
685 anAttr = aStudyBuilder->FindOrCreateAttribute(newObj, "AttributeName");
686 aName = SALOMEDS::AttributeName::_narrow(anAttr);
687 aName->SetValue(name);
688 anAttr = aStudyBuilder->FindOrCreateAttribute(newObj, "AttributeComment");
689 aComment = SALOMEDS::AttributeComment::_narrow(anAttr);
690 aComment->SetValue("VTK");
692 anAttr = aStudyBuilder->FindOrCreateAttribute(newObj, "AttributeSelectable");
693 aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr);
694 aSelAttr->SetSelectable(false);
696 else if ( theViewType == VIEW_GRAPHSUPERV) {
697 //MESSAGE ("Create Study Frame for SUPER`VISOR Graph");
698 sf = new QAD_StudyFrame ( this, parent->getMainFrame(),
699 title, VIEW_GRAPHSUPERV,
701 Standard_CString name = strdup(sf->title().latin1());
702 anAttr = aStudyBuilder->FindOrCreateAttribute(newObj, "AttributeName");
703 aName = SALOMEDS::AttributeName::_narrow(anAttr);
704 aName->SetValue(name);
705 anAttr = aStudyBuilder->FindOrCreateAttribute(newObj, "AttributeComment");
706 aComment = SALOMEDS::AttributeComment::_narrow(anAttr);
707 aComment->SetValue("GRAPH");
709 anAttr = aStudyBuilder->FindOrCreateAttribute(newObj, "AttributeSelectable");
710 aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr);
711 aSelAttr->SetSelectable(false);
713 else if ( theViewType == VIEW_PLOT2D ) {
714 sf = new QAD_StudyFrame ( this, parent->getMainFrame(),
717 Standard_CString name = strdup(sf->title().latin1());
718 anAttr = aStudyBuilder->FindOrCreateAttribute(newObj, "AttributeName");
719 aName = SALOMEDS::AttributeName::_narrow(anAttr);
720 aName->SetValue(name);
721 anAttr = aStudyBuilder->FindOrCreateAttribute(newObj, "AttributeComment");
722 aComment = SALOMEDS::AttributeComment::_narrow(anAttr);
723 aComment->SetValue("PLOT2D");
725 anAttr = aStudyBuilder->FindOrCreateAttribute(newObj, "AttributeSelectable");
726 aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr);
727 aSelAttr->SetSelectable(false);
729 //VRV: T2.5 - add default viewer
731 sf->resize( int (0.8*parent->getMainFrame()->width()),
732 int (0.8*parent->getMainFrame()->height() ));
734 sf->setEntry(newObj->GetID());
738 updateObjBrowser( true );
740 parent->setSettings();
744 if (aLocked) myStudy->GetProperties()->SetLocked(true);
746 // T2.12 - add the word "locked" to study frame captions if this study is locked
749 myStudy->EnableUseCaseAutoFilling(true);
755 Updates study frame captions according to IsLocked study flag
757 void QAD_Study::updateCaptions()
759 QString appendix("");
761 if (!myStudy->_is_nil()) {
762 SALOMEDS::AttributeStudyProperties_var propAttr = myStudy->GetProperties();
764 if (!propAttr->_is_nil() ) {
765 if ( propAttr->IsModified() )
766 appendix += " (" + tr("PRP_STUDY_MODIFIED") + ")";
768 appendix += " (" + tr("PRP_STUDY_SAVED") + ")";
772 if (!propAttr->_is_nil() && propAttr->IsLocked()) {
773 appendix += " (" + tr("PRP_STUDY_LOCKED") + ")";
777 for ( QPtrListIterator<QAD_StudyFrame> it( myStudyFrames ); it.current(); ++it ) {
778 it.current()->setCaption(it.current()->title() + appendix);
784 Shows the active study frame.
785 Called by Desktop after 'new' and 'open' commands.
787 void QAD_Study::show()
789 for ( QPtrListIterator<QAD_StudyFrame> it( myStudyFrames ); it.current(); ++it ) {
790 it.current()->show();
794 //=======================================================================//
795 // Study properties (CAF related) //
796 //=======================================================================//
799 Returns connected SALOMEDS_Study object
801 SALOMEDS::Study_var QAD_Study::getStudyDocument()
807 Returns whether the document was saved in file
809 bool QAD_Study::isSaved() const
811 return myStudy->IsSaved();
815 Returns whether the document is modified
817 bool QAD_Study::isModified() const
819 // return myStudy->IsModified(); // VSR:05/12/02 - USE PROPERTY : MODIFIED FLAG
820 if ( !myStudy->_is_nil() ) {
821 SALOMEDS::AttributeStudyProperties_var propAttr = myStudy->GetProperties();
822 if ( !propAttr->_is_nil() )
823 return propAttr->IsModified();
828 bool QAD_Study::undo()
831 SALOMEDS::StudyBuilder_var SB = myStudy->NewBuilder();
834 /* Update Object Browser */
835 updateObjBrowser( true );
837 for ( QPtrListIterator<QAD_StudyFrame> it( myStudyFrames ); it.current(); ++it ) {
839 it.current()->getRightFrame()->getViewFrame()->undo( this, it.current()->entry() );
843 // mpv 07.03.2003 SAL1805: clear selection must be called after study structure changed
844 SALOME_Selection* Sel = SALOME_Selection::Selection( getSelection() );
845 Sel->ClearIObjects();
847 // mpv : undo command can raise exception, if study is locked
848 catch ( SALOMEDS::StudyBuilder::LockProtection& ) {
849 QAD_MessageBox::warn1 ((QWidget*)QAD_Application::getDesktop(),
850 QObject::tr("WRN_WARNING"),
851 QObject::tr("WRN_STUDY_LOCKED"),
852 QObject::tr("BUT_OK"));
855 catch ( Standard_Failure ) {
863 bool QAD_Study::redo()
866 SALOMEDS::StudyBuilder_var SB = myStudy->NewBuilder();
869 /* Update Object Browser */
870 updateObjBrowser( true );
873 for ( QPtrListIterator<QAD_StudyFrame> it( myStudyFrames ); it.current(); ++it ) {
874 it.current()->getRightFrame()->getViewFrame()->redo( this, it.current()->entry() );
878 // mpv 07.03.2003 SAL1805: clear selection must be called after study structure changed
879 SALOME_Selection* Sel = SALOME_Selection::Selection( getSelection() );
880 Sel->ClearIObjects();
882 // mpv : redo command can raise exception, if study is locked
883 catch ( SALOMEDS::StudyBuilder::LockProtection& ) {
884 QAD_MessageBox::warn1 ((QWidget*)QAD_Application::getDesktop(),
885 QObject::tr("WRN_WARNING"),
886 QObject::tr("WRN_STUDY_LOCKED"),
887 QObject::tr("BUT_OK"));
890 catch ( Standard_Failure ) {
896 Check if possible to perform 'undo' command
898 bool QAD_Study::canUndo() const
900 if ( myStudy->_is_nil() )
903 SALOMEDS::StudyBuilder_var SB = myStudy->NewBuilder();
904 return (SB->GetAvailableUndos() > 0 );
908 Check if possible to perform 'redo' command
910 bool QAD_Study::canRedo() const
912 if ( myStudy->_is_nil() )
915 SALOMEDS::StudyBuilder_var SB = myStudy->NewBuilder();
916 return (SB->GetAvailableRedos() > 0 );
920 Called when operation is started
921 Returns 'true' if started OK, 'false' otherwise.
923 bool QAD_Study::onOperationStarted( QAD_Operation* op )
925 if ( !initOperation( op ) )
929 { /* start a new transaction */
930 SALOMEDS::StudyBuilder_var SB = myStudy->NewBuilder();
933 catch ( Standard_Failure )
935 /* May be, a transaction is already open,
936 it's not a problem */
938 myOperationState = Started;
943 Called when operation is finished
945 void QAD_Study::onOperationFinished( QAD_Operation* op )
948 /* transaction is completed OK */
949 SALOMEDS::StudyBuilder_var SB = myStudy->NewBuilder();
952 catch ( SALOMEDS::StudyBuilder::LockProtection& ) {
953 QApplication::restoreOverrideCursor();
954 QAD_MessageBox::warn1 ((QWidget*)QAD_Application::getDesktop(),
955 QObject::tr("WRN_WARNING"),
956 QObject::tr("WRN_STUDY_LOCKED"),
957 QObject::tr("BUT_OK"));
958 onOperationAborted(op);
959 updateObjBrowser( true );
962 catch ( Standard_Failure ) {
964 myOperationState = Finished;
965 emit docOperationTerminated( true ); /* terminated successfully */
968 // mpv: any operation must call this method, otherwise study may not be saved
969 updateObjBrowser( true );
971 clearOperation( op ); /* we don't need the operation anymore */
972 QAD_Application::getDesktop()->putInfo ( tr("INF_DOC_OPERATIONFINISHED") );
976 Called when operation is suspended
978 void QAD_Study::onOperationSuspended( QAD_Operation* op )
980 myOperationState = Suspended;
984 Called when operation is resumed
986 void QAD_Study::onOperationResumed( QAD_Operation* op )
988 myOperationState = Resumed;
992 Called when operation is aborted
994 void QAD_Study::onOperationAborted(QAD_Operation* op)
997 /* abort transaction */
998 SALOMEDS::StudyBuilder_var SB = myStudy->NewBuilder();
1001 catch ( Standard_Failure )
1004 myOperationState = Aborted;
1005 emit docOperationTerminated( false ); /* aborted */
1010 QAD_Application::getDesktop()->putInfo ( tr("INF_DOC_OPERATIONABORTED") );
1014 Call when the last study frame is closing
1016 void QAD_Study::onLastStudyFrameClosing( QAD_StudyFrame* sf )
1018 if ( myStudyFrames.count() == 1 ) {
1019 emit docClosing( this );
1021 removeStudyFrame( sf );
1023 // QWorkspace* ws = QAD_Application::getDesktop()->getMainFrame();
1024 // if ( !ws->activeWindow() && ws->windowList().count() > 0 )
1025 // ws->activatePreviousWindow();
1029 Call when created a new window3d
1031 QAD_StudyFrame* QAD_Study::newWindow3d(QString name, ViewType theViewType, bool toShow)
1033 if(name == "") name = getNextStudyFrameName();
1034 QAD_StudyFrame* sf = createStudyFrame( name, theViewType );
1036 if (toShow) showFrame(sf);
1037 // sf->compressLeft(); /* compress LeftFrame */
1038 sf->getRightFrame()->compressBottom(); /* compress BottomFrame */
1044 void QAD_Study::showFrame(QAD_StudyFrame* theFrame){
1045 theFrame->resize( (int)(0.64*QAD_Application::getDesktop()->getMainFrame()->width()),
1046 (int)(0.64*QAD_Application::getDesktop()->getMainFrame()->height()));
1054 Call when setted a message
1056 void QAD_Study::setMessage(const char* message)
1058 for ( QPtrListIterator<QAD_StudyFrame> it( myStudyFrames ); it.current(); ++it ) {
1059 it.current()->getRightFrame()->getMessage()->setMessage(message);
1064 Call when updated object browser
1066 void QAD_Study::updateObjBrowser( bool updateSelection )
1068 QAD_Desktop* parent = QAD_Application::getDesktop();
1069 SALOME_ModuleCatalog::ModuleCatalog_var Catalog = parent->getCatalogue();
1071 QString ActiveComp = parent->getActiveComponent();
1073 for ( QPtrListIterator<QAD_StudyFrame> it( myStudyFrames ); it.current(); ++it ) {
1074 it.current()->getLeftFrame()->getObjectBrowser()->Update();
1077 /* update selection */
1078 if ( updateSelection && (myStudyFrames.count() > 0) ) {
1079 SALOME_Selection* Sel = SALOME_Selection::Selection( getSelection() );
1080 SALOME_ListIteratorOfListIO It( Sel->StoredIObjects() );
1081 for(;It.More();It.Next()) {
1082 if ( Sel->AddIObject( It.Value() ) == 0 ) {
1083 highlight( It.Value(), true, false );
1087 /* update viewers */
1092 Updates only Use Case Browser
1094 void QAD_Study::updateUseCaseBrowser( bool updateSelection )
1096 for ( QPtrListIterator<QAD_StudyFrame> it( myStudyFrames ); it.current(); ++it ) {
1097 it.current()->getLeftFrame()->getObjectBrowser()->UpdateUseCaseBrowser();
1099 /* update selection */
1100 if ( updateSelection && (myStudyFrames.count() > 0) ) {
1101 SALOME_Selection* Sel = SALOME_Selection::Selection( getSelection() );
1102 SALOME_ListIteratorOfListIO It( Sel->StoredIObjects() );
1103 for(;It.More();It.Next()) {
1104 if ( Sel->AddIObject( It.Value() ) == 0 ) {
1105 highlight( It.Value(), true, false );
1108 /* update viewers */
1114 unHighlight All Interactive Objects in All Devices
1116 void QAD_Study::unHighlightAll()
1118 for ( QPtrListIterator<QAD_StudyFrame> it( myStudyFrames ); it.current(); ++it ) {
1119 /* Device = Viewers */
1120 it.current()->getRightFrame()->getViewFrame()->unHighlightAll();
1122 /* Device = ObjectBrowser */
1123 it.current()->getLeftFrame()->getObjectBrowser()->unHighlightAll();
1128 Returns type of Interactive Object
1130 int QAD_Study::typeIObject( const Handle(SALOME_InteractiveObject)& IObject )
1132 bool IsStudyObject = isInStudy( IObject );
1133 bool IsGraphicalObject = isInViewer( IObject );
1135 // MESSAGE ( "IsStudyObject : " << IsStudyObject )
1136 // MESSAGE ( "IsGraphicalObject : " << IsGraphicalObject )
1138 if ( IsStudyObject ) {
1139 if ( IsGraphicalObject )
1140 return 1; /* StudyObject and GraphicalObject */
1142 return 2; /* only StudyObject */
1144 if ( IsGraphicalObject )
1145 return 3; /* only GraphicalObject */
1147 return 4; /* may be a component */
1154 Renames the Interactive Object in All Devices
1156 void QAD_Study::renameIObject( const Handle(SALOME_InteractiveObject)& IObject, QString newName )
1158 if (myStudy->GetProperties()->IsLocked()) {
1159 QAD_MessageBox::warn1 ((QWidget*)QAD_Application::getDesktop(),
1160 QObject::tr("WRN_WARNING"),
1161 QObject::tr("WRN_STUDY_LOCKED"),
1162 QObject::tr("BUT_OK"));
1166 highlight( IObject, false );
1168 int nbFrames = myStudyFrames.count();
1169 for ( int i = 0; i < nbFrames; i++ ) {
1170 QAD_StudyFrame* sf = myStudyFrames.at( i );
1171 switch ( typeIObject(IObject) ) {
1174 /* Device = Viewers */
1175 sf->getRightFrame()->getViewFrame()->rename(IObject, newName);
1176 /* Device = ObjectBrowser */
1177 sf->getLeftFrame()->getObjectBrowser()->rename(IObject, newName);
1182 /* Device = ObjectBrowser */
1183 sf->getLeftFrame()->getObjectBrowser()->rename(IObject, newName);
1188 /* Device = Viewers */
1189 sf->getRightFrame()->getViewFrame()->rename(IObject, newName);
1194 QString ActiveComp = QAD_Application::getDesktop()->getActiveComponent();
1195 if ( !ActiveComp.isEmpty() ) {
1196 sf->getLeftFrame()->getObjectBrowser()->rename(IObject,newName);
1204 SALOMEDS::StudyBuilder_var aStudyBuilder = myStudy->NewBuilder();
1205 SALOMEDS::SObject_var obj = myStudy->FindObjectID( IObject->getEntry() );
1206 if ( !obj->_is_nil() ) {
1207 SALOMEDS::GenericAttribute_var anAttr;
1208 SALOMEDS::AttributeName_var aName;
1209 anAttr = aStudyBuilder->FindOrCreateAttribute(obj, "AttributeName");
1210 aName = SALOMEDS::AttributeName::_narrow(anAttr);
1211 aName->SetValue(newName.latin1());
1214 // VSR 13/03/03 - rename Interactive object
1215 IObject->setName( ( char* )newName.latin1() );
1217 updateObjBrowser( true );
1221 Selects the Interactive Object in All Devices
1223 void QAD_Study::highlight( const Handle(SALOME_InteractiveObject)& IObject, bool highlight,bool immediatly )
1225 // MESSAGE ( " QAD_Study::highlight : " << highlight )
1226 int typeIO = typeIObject( IObject );
1228 for ( QPtrListIterator<QAD_StudyFrame> it( myStudyFrames ); it.current(); ++it ) {
1232 /* Device = Viewer */
1233 if (it.current()->getTypeView() >= 0 ) { /* Device = Viewers */
1234 it.current()->getRightFrame()->getViewFrame()->highlight(IObject, highlight, immediatly);
1236 /* Device = ObjectBrowser */
1237 it.current()->getLeftFrame()->getObjectBrowser()->highlight(IObject, highlight);
1242 /* Device = ObjectBrowser */
1243 it.current()->getLeftFrame()->getObjectBrowser()->highlight(IObject, highlight);
1248 /* Device = Viewer */
1249 if (it.current()->getTypeView() >= 0) { /* Device = Viewers */
1250 it.current()->getRightFrame()->getViewFrame()->highlight(IObject, highlight, immediatly);
1256 QString ActiveComp = QAD_Application::getDesktop()->getActiveComponent();
1257 if ( !ActiveComp.isEmpty() ) {
1258 it.current()->getLeftFrame()->getObjectBrowser()->highlight(IObject,highlight);
1267 Returns TRUE if the IObject is a Study Object. Returns FALSE otherwise.
1269 bool QAD_Study::isInStudy( const Handle(SALOME_InteractiveObject)& IObject )
1271 return IObject->hasEntry();
1275 Returns true if the IObject has a Graphical Object. Returns FALSE otherwise.
1277 bool QAD_Study::isInViewer( const Handle(SALOME_InteractiveObject)& IObject )
1280 for ( QPtrListIterator<QAD_StudyFrame> it( myStudyFrames ); it.current(); ++it ) {
1281 found = it.current()->getRightFrame()->getViewFrame()->isInViewer(IObject);
1289 Returns true if the IObject has a Graphical Object into studyframe. Returns FALSE otherwise.
1291 bool QAD_Study::isInViewer(const char* anEntry, const char* StudyFrameEntry)
1293 SALOMEDS::SObject_var RefSO;
1294 SALOMEDS::SObject_var SO = myStudy->FindObjectID(StudyFrameEntry);
1295 SALOMEDS::ChildIterator_var it = myStudy->NewChildIterator(SO);
1296 for (; it->More();it->Next()){
1297 SALOMEDS::SObject_var CSO= it->Value();
1298 if (CSO->ReferencedObject(RefSO))
1299 if ( strcmp( anEntry, RefSO->GetID() ) == 0 )
1307 Returns title for the new studyframe window
1309 QString QAD_Study::getNextStudyFrameName()
1311 QString numStudyFrame;
1312 numStudyFrame.sprintf("%s%d", "#", ++myStudyFrameCount );
1313 return myTitle + numStudyFrame; /* return unique name ( title + unique number) */
1318 Returns the Python interpreter that belongs to this study
1320 QAD_PyInterp* QAD_Study::get_PyInterp(void)
1326 Sets current selection.
1328 void QAD_Study::Selection( QString aSelection )
1330 if ( !SALOME_Selection::FindSelection( QString(myTitle + "_" + aSelection) ) )
1331 SALOME_Selection::CreateSelection( QString(myTitle + "_" + aSelection) );
1333 SALOME_Selection* Sel = SALOME_Selection::Selection( QString(myTitle + "_" + aSelection) );
1335 mySelection = aSelection;
1339 Returns the name of current selection
1341 QString QAD_Study::getSelection() const
1343 return QString (myTitle + "_" + mySelection);
1347 Returns the study Id.
1349 int QAD_Study::getStudyId()
1351 return myStudy->StudyId();
1354 void QAD_Study::update3dViewers()
1356 for ( QPtrListIterator<QAD_StudyFrame> it( myStudyFrames ); it.current(); ++it ) {
1357 it.current()->getRightFrame()->getViewFrame()->Repaint();
1361 /* Adds new child window */
1362 void QAD_Study::addChildWidget( QWidget* child )
1364 if ( myChildWidgets.findRef( child ) < 0 ) {
1365 myChildWidgets.append( child );
1366 child->installEventFilter( this );
1371 Removes child window from the list ( and deletes it )
1373 void QAD_Study::removeChildWidget( QWidget* child )
1375 myChildWidgets.removeRef( child );
1379 bool QAD_Study::eventFilter( QObject* o, QEvent* e)
1381 int index = myChildWidgets.findRef( ( QWidget* )o );
1382 if ( index >= 0 && e->type() == QEvent::Close ) {
1383 myChildWidgets.at( index )->removeEventFilter( this );
1384 myChildWidgets.remove( ( QWidget* )o );
1387 return QObject::eventFilter( o, e );