-// File: SALOME_Event.cxx
-// Created: Tue Mar 30 15:06:32 2004
-// Author: Sergey ANIKIN
-// <san@startrex.nnov.opencascade.com>
-
+// KERNEL SALOME_Event : Define event posting mechanism
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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.
+//
+// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SALOME_Event.cxx
+// Author : Sergey ANIKIN
+// Module : KERNEL
+// $Header$
#include "SALOME_Event.hxx"
#include "utilities.h"
-//===========================================================================
-// ~SALOME_Semaphore
-//===========================================================================
-SALOME_Semaphore::~SALOME_Semaphore()
+#include <qsemaphore.h>
+#include <qapplication.h>
+#include <qthread.h>
+
+//===========================================================
+/*!
+ * SALOME_Event::SALOME_Event
+ * Constructor
+ */
+//===========================================================
+SALOME_Event::SALOME_Event( int salomeEventType, bool wait )
+: myType( salomeEventType ),
+ myWait( wait )
+{
+ MESSAGE( "SALOME_Event::SALOME_Event(): myType = "<<myType<<", myWait = "<<myWait );
+ if ( wait ) {
+ // Prepare the semaphore
+ mySemaphore = new QSemaphore( 1 );
+ mySemaphore->operator++( 1 );
+ }
+}
+
+//===========================================================
+/*!
+ * SALOME_Event::~SALOME_Event
+ * Destructor
+ */
+//===========================================================
+SALOME_Event::~SALOME_Event()
{
+ MESSAGE( "SALOME_Event::~SALOME_Event(): myType = "<<myType<<", myWait = "<<myWait );
+ if ( myWait ) {
+ if ( mySemaphore->available() < mySemaphore->total() )
+ mySemaphore->operator-=( mySemaphore->total() - mySemaphore->available() );
+ delete mySemaphore;
+ }
}
-//===========================================================================
-// SALOME_Event
-//===========================================================================
-SALOME_Event::SALOME_Event( int salomeEventType, SALOME_Semaphore* s )
-: QCustomEvent( (QEvent::Type)(QEvent::User + 1), (void*)s ),
- myType( salomeEventType )
+//===========================================================
+/*!
+ * SALOME_Event::process
+ * Posts the event and optionally waits for its completion
+ */
+//===========================================================
+void SALOME_Event::process()
{
- MESSAGE( "SALOME_Event::SALOME_Event(): type = " << myType << ", semaphore = " << s );
- if ( s ) {
- MESSAGE( "SALOME_Event::SALOME_Event(): available = " << s->available() );
- ASSERT( s->available() == 1 );
- s->operator++( 1 );
+ MESSAGE( "SALOME_Event::process(): myType = "<<myType<<",myWait = "<<myWait );
+ QThread::postEvent( qApp, new QCustomEvent( SALOME_EVENT, (void*)this ) );
+ if ( myWait ) {
+ MESSAGE( "SALOME_Event::process(): available = " << mySemaphore->available() );
+ if ( !mySemaphore->available() )
+ mySemaphore->operator++( 1 );
+
+ MESSAGE( "SALOME_Event::process() COMPLETED: myType = "<<myType<<",myWait = "<<myWait );
+
+ // processed() waits for this loop to complete
+ while ( mySemaphore->available() < mySemaphore->total() )
+ mySemaphore->operator--( 1 );
}
}
-//===========================================================================
-// processed
-//===========================================================================
+//===========================================================
+/*!
+ * SALOME_Event::processed
+ * Signals that this event has been processsed
+ */
+//===========================================================
void SALOME_Event::processed()
{
- MESSAGE( "SALOME_Event::processed()" );
- if ( getSemaphore() && !getSemaphore()->available() ) {
- MESSAGE( "SALOME_Event::SALOME_Event(): available = " << getSemaphore()->available() );
- getSemaphore()->operator--( 1 );
+ MESSAGE( "SALOME_Event::processed(): myType = "<<myType<<",myWait = "<<myWait );
+ if ( myWait ) {
+ MESSAGE( "SALOME_Event::processed(): available = " << mySemaphore->available() );
+ if ( !mySemaphore->available() )
+ // process() takes control over mySemaphore after the next line is executed
+ mySemaphore->operator--( 1 );
+
+ // Current thread will block here until process() completes
+ mySemaphore->operator+=( mySemaphore->total() );
}
+ MESSAGE( "SALOME_Event::processed() COMPLETED: myType = "<<myType<<",myWait = "<<myWait );
}
-// File: SALOME_Event.hxx
-// Created: Mon Mar 29 16:36:52 2004
-// Author: Sergey ANIKIN
-// <san@startrex.nnov.opencascade.com>
+// KERNEL SALOME_Event : Define event posting mechanism
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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.
+//
+// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SALOME_Event.hxx
+// Author : Sergey ANIKIN
+// Module : KERNEL
+// $Header$
#ifndef SALOME_Event_HeaderFile
#define SALOME_Event_HeaderFile
#include <qevent.h>
-#include <qsemaphore.h>
-class SALOME_Semaphore : public QSemaphore
-{
-public:
- SALOME_Semaphore() : QSemaphore( 1 ) {}
- virtual ~SALOME_Semaphore();
-};
+#define SALOME_EVENT QEvent::Type( QEvent::User + 10000 )
+
+class QSemaphore;
-class SALOME_Event : public QCustomEvent
+//===========================================================
+/*!
+ * Class: SALOME_Event
+ * Description:
+ * This class encapsulates data and functionality required for
+ * posting component-specific events. These events are then dispatched
+ * by QAD_Desktop to corresponding component GUI object, on the basis of
+ * <type> value passed to the constructor. SALOME_Event objects can be used
+ * by any thread belonging to the GUI process.
+ *
+ * It is possible to make the thread that creates SALOME_Event
+ * wait until the event is processed by the component GUI, SALOME_Event
+ * should be constructed with <wait> == TRUE in such a case.
+ *
+ * SALOME_Event objects should be created on the heap. QAD_Desktop deletes
+ * these objects as soon as they have been processed.
+ *
+ * Usage:
+ * - create SALOME_Event object on the heap with proper <type> and <wait> parameters.
+ * Components can derive their own event class from SALOME_Event
+ * in order to pass custom data to the event handler.
+ * - call process() method to post the event.
+ *
+ * processed() method is used by the desktop to signal that event processing
+ * has been completed.
+ *
+ * NOTE:
+ * 1. Never create SALOME_Event with <wait> == TRUE in code that is
+ * supposed to be called from built-in GUI Python console, for this will result
+ * in GUI process deadlock.
+ * 2. Never use pointers to the event after it has been processed to avoid
+ * application crashes!
+ */
+//===========================================================
+
+class SALOME_Event
{
public:
- SALOME_Event( int salomeEventType, SALOME_Semaphore* s = 0 );
+ SALOME_Event( int salomeEventType, bool wait );
+ virtual ~SALOME_Event();
int getType() const { return myType; }
+
+ void process();
void processed();
-
-private:
- SALOME_Semaphore* getSemaphore() { return (SALOME_Semaphore*)data(); }
private:
- int myType;
+ int myType;
+ bool myWait;
+ QSemaphore* mySemaphore;
};
#endif
#endif
// Open CASCADE Includes
+#include <OSD_SharedLibrary.hxx>
#include <OSD_LoadMode.hxx>
#include <OSD_Function.hxx>
#include <TCollection_AsciiString.hxx>
}
}
}
- else if ( e->type() == QEvent::User + 1 ) { // SALOME_Event has type QEvent::User + 1
- SALOME_Event* aSE = (SALOME_Event*)e;
- MESSAGE( "QAD_Desktop::eventFilter - SALOME_Event handling - 1 : o = " << o << ", e = " << e);
- // here we do the job...
- sleep( 5 );
+ else if ( e->type() == SALOME_EVENT ) {
+ SALOME_Event* aSE = (SALOME_Event*)((QCustomEvent*)e)->data();
+ MESSAGE( "QAD_Desktop::eventFilter - SALOME_Event handling - 1 : o = " << o << ", e = " << aSE);
+ processEvent( aSE );
MESSAGE( "QAD_Desktop::eventFilter - SALOME_Event handling - 2" );
+
+ // Signal the calling thread that the event has been processed
aSE->processed();
MESSAGE( "QAD_Desktop::eventFilter - SALOME_Event handling - 3" );
+
+ ((QCustomEvent*)e)->setData( 0 );
+ delete aSE;
return TRUE;
}
return QMainWindow::eventFilter( o, e );
}
+/*!
+ Dispatches <theEvent> to the target component GUI
+*/
+void QAD_Desktop::processEvent( SALOME_Event* theEvent )
+{
+ if ( !theEvent )
+ return;
+
+ for ( ComponentMap::iterator it = myComponents.begin(); it != myComponents.end(); it++ ) {
+ if ( it.data()->CanProcessEvent( theEvent ) && it.data()->ProcessEvent( theEvent ) )
+ break;
+ }
+}
+
/*!
Creates and initializes the standard file operations
such as 'New/Open/Save/SaveAs/Close' and 'Help'.
#include <qfiledialog.h>
#include <qtoolbutton.h>
-// Open CASCADE Includes
-#include <OSD_SharedLibrary.hxx>
-
class QAD_XmlHandler;
class SALOMEGUI;
+class SALOME_Event;
class QAD_EXPORT QAD_Desktop : public QMainWindow
{
QMap<QString,QString> mapComponentName;
+private:
+ void processEvent( SALOME_Event* );
+
private:
typedef QMap<QString, SALOMEGUI*> ComponentMap;
{
return QAD_Application::getDesktop()->getComponentUserName( ComponentName );
}
+/*!
+ Loads component GUI library if not yet loaded
+*/
+void SALOMEGUI_Swig::loadComponentGUI( const char* ComponentName )
+{
+ QAD_Application::getDesktop()->getComponentGUI( QAD_Application::getDesktop()->getComponentUserName( ComponentName ) );
+}
/*!
Returns the number of selected objects.
/* component name */
const char* getComponentName( const char* ComponentUserName );
const char* getComponentUserName( const char* ComponentName );
+ void loadComponentGUI( const char* ComponentName );
protected:
int _studyId;
/* component name */
const char* getComponentName( const char* ComponentUserName );
const char* getComponentUserName( const char* ComponentName );
+
+ void loadComponentGUI( const char* ComponentName );
};