--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D\r
+// \r
+// This library is free software; you can redistribute it and/or \r
+// modify it under the terms of the GNU Lesser General Public \r
+// License as published by the Free Software Foundation; either \r
+// version 2.1 of the License. \r
+// \r
+// This library is distributed in the hope that it will be useful, \r
+// but WITHOUT ANY WARRANTY; without even the implied warranty of \r
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU \r
+// Lesser General Public License for more details. \r
+// \r
+// You should have received a copy of the GNU Lesser General Public \r
+// License along with this library; if not, write to the Free Software \r
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA \r
+// \r
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com\r
+//\r
+\r
+#if !defined ( EVENT_H )\r
+#define EVENT_H\r
+\r
+#ifdef WIN32\r
+# ifdef EVENT_EXPORTS\r
+# define EVENT_EXPORT __declspec(dllexport)\r
+# else\r
+# define EVENT_EXPORT __declspec(dllimport)\r
+# endif\r
+#else //WIN32\r
+# define EVENT_EXPORT\r
+#endif //WIN32\r
+\r
+#if defined WIN32\r
+#pragma warning ( disable: 4251 )\r
+#endif\r
+\r
+#endif // EVENT_H\r
--- /dev/null
+TEMPLATE = lib\r
+TARGET = Event\r
+DESTDIR = ../../$(CONFIG_ID)/lib\r
+MOC_DIR = ../../moc\r
+OBJECTS_DIR = ../../$(CONFIG_ID)/obj/$$TARGET\r
+\r
+INCLUDEPATH += ../../include\r
+LIBS += \r
+\r
+CONFIG -= debug release debug_and_release\r
+CONFIG += qt thread debug dll shared\r
+\r
+win32:DEFINES += WIN32 \r
+DEFINES += EVENT_EXPORTS\r
+\r
+HEADERS = Event.h\r
+HEADERS += SALOME_Event.h\r
+\r
+SOURCES = SALOME_Event.cxx\r
+\r
+includes.files = $$HEADERS\r
+includes.path = ../../include\r
+\r
+INSTALLS += includes\r
--- /dev/null
+// KERNEL SALOME_Event : Define event posting mechanism\r
+//\r
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,\r
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS \r
+// \r
+// This library is free software; you can redistribute it and/or \r
+// modify it under the terms of the GNU Lesser General Public \r
+// License as published by the Free Software Foundation; either \r
+// version 2.1 of the License. \r
+// \r
+// This library is distributed in the hope that it will be useful, \r
+// but WITHOUT ANY WARRANTY; without even the implied warranty of \r
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU \r
+// Lesser General Public License for more details. \r
+// \r
+// You should have received a copy of the GNU Lesser General Public \r
+// License along with this library; if not, write to the Free Software \r
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA \r
+// \r
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com\r
+//\r
+// File : SALOME_Event.cxx\r
+// Author : Sergey ANIKIN\r
+\r
+#include "SALOME_Event.h"\r
+\r
+#include <QSemaphore>\r
+#include <QApplication>\r
+\r
+// asv 21.02.05 : introducing multi-platform approach of thread comparison\r
+// - on Unix using pthread_t type for storing ThreadId\r
+// - on Win32 using integer type for storing ThreadId\r
+// NOT using integer ThreadId on both Unix and Win32 because (from documentation):\r
+// "...Do not allow your program to rely on the internal structure or size of the pthread_t..."\r
+\r
+#ifdef WIN32\r
+#include <windows.h>\r
+static DWORD myThread;\r
+#else\r
+#include <pthread.h>\r
+static pthread_t myThread;\r
+#endif\r
+\r
+/*!\r
+ \class SALOME_CustomEvent\r
+ \brief Generic event class for user-defined events\r
+ \r
+ This class contains a generic void* data member that may be used\r
+ for transferring event-specific data to the receiver.\r
+\r
+ \warning The internal data is not destroyed by the class destructor.\r
+*/\r
+\r
+/*!\r
+ \brief Constructor.\r
+ \param type event type\r
+*/\r
+SALOME_CustomEvent::SALOME_CustomEvent( int type )\r
+: QEvent( (QEvent::Type)type ), d( 0 )\r
+{\r
+}\r
+\r
+/*!\r
+ \brief Constructor.\r
+ \param type event type\r
+ \param data custom data\r
+*/\r
+SALOME_CustomEvent::SALOME_CustomEvent( QEvent::Type type, void* data )\r
+: QEvent( type ), d( data )\r
+{\r
+}\r
+\r
+/*!\r
+ \brief Get custom data.\r
+ \return pointer to the internal data\r
+*/\r
+void* SALOME_CustomEvent::data() const\r
+{\r
+ return d;\r
+}\r
+\r
+/*!\r
+ \brief Set custom data.\r
+ \param data pointer to the internal data\r
+*/\r
+void SALOME_CustomEvent::setData( void* data )\r
+{\r
+ d = data;\r
+}\r
+\r
+/*!\r
+ \class SALOME_Event\r
+ \brief The class which encapsulates data and functionality required for \r
+ posting component-specific events to perform arbitrary operations \r
+ in the main GUI thread. \r
+\r
+ SALOME_Event objects can be posted by any thread belonging to the GUI process.\r
+ \r
+ It is necessary to derive a custom event class from SALOME_Event and \r
+ re-implement virtual Execute() method. This method should actually perform \r
+ the desirable operation. To pass all the required data to Execute() and \r
+ store a return value, arbitrary data fields can be added to the custom \r
+ event class. There is no need to protect such fields with a mutex, for only\r
+ one thread working with a SALOME_Event object is active at any moment.\r
+ \r
+ Usage:\r
+ - Create SALOME_Event. Components can derive their own event class from \r
+ SALOME_Event in order to pass custom data to the event handler.\r
+ - Call process() method to post the event. After process() execution\r
+ it is possible to examine fields of your custom event object.\r
+ - Perform delete operator on the event to wake up the desktop (you can also \r
+ set <autoRelease> parameter to \c true to automatically wake up desktop after \r
+ process().\r
+ \r
+ The method processed() is used by the desktop to signal that event processing \r
+ has been completed.\r
+\r
+ To make all this work, it is necessary to call static method GetSessionThread()\r
+ during the application initialization, i.e. from main() function.\r
+ It is important to call this method from the primary application thread.\r
+\r
+ Caveats: \r
+ - there are no.\r
+*/\r
+\r
+//! Total number of semaphore resources\r
+const int NumberOfResources = 2;\r
+\r
+/*!\r
+ \brief Initialize event mechanism.\r
+\r
+ This function sets up the main application thread. It should be called\r
+ during the application initialization, i.e. main() function.\r
+*/\r
+void SALOME_Event::GetSessionThread(){\r
+#ifdef WIN32\r
+ myThread = ::GetCurrentThreadId();\r
+#else\r
+ myThread = pthread_self();\r
+#endif\r
+}\r
+\r
+/*!\r
+ \brief Check if the processing is in the main application thread.\r
+ \return \c true if this method is called from the main application thread\r
+*/\r
+bool SALOME_Event::IsSessionThread(){\r
+ bool aResult = false;\r
+#ifdef WIN32\r
+ aResult = myThread == ::GetCurrentThreadId();\r
+#else\r
+ aResult = myThread == pthread_self();\r
+#endif\r
+ return aResult;\r
+}\r
+\r
+/*!\r
+ \brief Constructor.\r
+*/\r
+SALOME_Event::SALOME_Event(){\r
+ // Prepare the semaphore \r
+ mySemaphore = new QSemaphore( NumberOfResources );\r
+ mySemaphore->acquire( NumberOfResources );\r
+}\r
+\r
+/*!\r
+ \brief Destructor.\r
+*/\r
+SALOME_Event::~SALOME_Event(){\r
+ if ( mySemaphore->available() < NumberOfResources )\r
+ mySemaphore->release( NumberOfResources - mySemaphore->available() );\r
+ delete mySemaphore;\r
+}\r
+\r
+/*!\r
+ \brief Post the event and wait for its completion.\r
+ \sa processed()\r
+*/\r
+void SALOME_Event::process()\r
+{\r
+ QApplication::postEvent( qApp, new SALOME_CustomEvent( SALOME_EVENT, (void*)this ) );\r
+ mySemaphore->acquire( 1 );\r
+}\r
+\r
+/*!\r
+ \brief Use this method to signal that this event has been processed.\r
+*/\r
+void SALOME_Event::processed()\r
+{\r
+ mySemaphore->release( 1 );\r
+}\r
+\r
+/*!\r
+ \fn virtual void SALOME_Event::Execute();\r
+ \brief This method should be redefined in the successor classes\r
+ to do real work.\r
+*/\r
+ \r
+/*!\r
+ \class TMemFunEvent\r
+ \brief Template class for event which calls the function\r
+ without arguments and returning result.\r
+*/\r
+\r
+/*!\r
+ \class TVoidMemFunEvent\r
+ \brief Template class for event which calls the function\r
+ without arguments and without return value.\r
+*/\r
+\r
+/*!\r
+ \class TMemFun1ArgEvent\r
+ \brief Template class for event which calls the function\r
+ with one argument and returning result.\r
+*/\r
+\r
+/*!\r
+ \class TVoidMemFun1ArgEvent\r
+ \brief Template class for event which calls the function\r
+ with one argument and without return value.\r
+*/\r
+\r
+/*!\r
+ \class TMemFun2ArgEvent\r
+ \brief Template class for event which calls the function\r
+ with two arguments and returning result.\r
+*/\r
+\r
+/*!\r
+ \class TVoidMemFun2ArgEvent\r
+ \brief Template class for event which calls the function\r
+ with two arguments and without return value.\r
+*/\r
+\r
+/*!\r
+ \fn ProcessEvent\r
+ \brief Template function for processing events with return value.\r
+*/\r
+\r
+/*!\r
+ \fn ProcessVoidEvent\r
+ \brief Template function for processing events without return value.\r
+*/\r
--- /dev/null
+// KERNEL SALOME_Event : Define event posting mechanism\r
+//\r
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,\r
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS \r
+// \r
+// This library is free software; you can redistribute it and/or \r
+// modify it under the terms of the GNU Lesser General Public \r
+// License as published by the Free Software Foundation; either \r
+// version 2.1 of the License. \r
+// \r
+// This library is distributed in the hope that it will be useful, \r
+// but WITHOUT ANY WARRANTY; without even the implied warranty of \r
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU \r
+// Lesser General Public License for more details. \r
+// \r
+// You should have received a copy of the GNU Lesser General Public \r
+// License along with this library; if not, write to the Free Software \r
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA \r
+// \r
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com\r
+//\r
+// File : SALOME_Event.h\r
+// Author : Sergey ANIKIN\r
+\r
+#ifndef SALOME_EVENT_H\r
+#define SALOME_EVENT_H\r
+\r
+#include <Event.h>\r
+\r
+#include <QEvent>\r
+\r
+//! SALOME custom event type\r
+#define SALOME_EVENT QEvent::Type( QEvent::User + 10000 )\r
+\r
+class EVENT_EXPORT SALOME_CustomEvent : public QEvent\r
+{\r
+public:\r
+ SALOME_CustomEvent( int type );\r
+ SALOME_CustomEvent( QEvent::Type type, void* data );\r
+\r
+ void* data() const;\r
+ void setData( void* data );\r
+\r
+private:\r
+ void *d; //!< internal data\r
+};\r
+\r
+class QSemaphore;\r
+\r
+class EVENT_EXPORT SALOME_Event\r
+{\r
+public:\r
+ SALOME_Event();\r
+ virtual ~SALOME_Event();\r
+\r
+ virtual void Execute() = 0;\r
+\r
+ static bool IsSessionThread();\r
+ void process();\r
+\r
+protected:\r
+ void processed();\r
+ friend class SalomeApp_EventFilter;\r
+\r
+ static void GetSessionThread();\r
+ friend int main(int, char **);\r
+\r
+private:\r
+ QSemaphore* mySemaphore; //!< internal semaphore\r
+};\r
+\r
+template<class TObject, typename TRes> class TMemFunEvent : public SALOME_Event\r
+{\r
+public:\r
+ typedef TRes TResult;\r
+ TResult myResult;\r
+ typedef TResult (TObject::* TAction)();\r
+ TMemFunEvent(TObject* theObject, TAction theAction, \r
+ TResult theResult = TResult()):\r
+ myObject(theObject),\r
+ myAction(theAction),\r
+ myResult(theResult)\r
+ {}\r
+ virtual void Execute()\r
+ {\r
+ myResult = (myObject->*myAction)();\r
+ }\r
+private:\r
+ TObject* myObject;\r
+ TAction myAction;\r
+};\r
+\r
+template<class TObject> class TVoidMemFunEvent : public SALOME_Event\r
+{\r
+public:\r
+ typedef void (TObject::* TAction)();\r
+ TVoidMemFunEvent(TObject* theObject, TAction theAction):\r
+ myObject(theObject),\r
+ myAction(theAction)\r
+ {}\r
+ virtual void Execute()\r
+ {\r
+ (myObject->*myAction)();\r
+ }\r
+private:\r
+ TObject* myObject;\r
+ TAction myAction;\r
+};\r
+\r
+template<class TObject, typename TRes, typename TArg, typename TStoreArg = TArg> \r
+class TMemFun1ArgEvent : public SALOME_Event\r
+{\r
+public:\r
+ typedef TRes TResult;\r
+ TResult myResult;\r
+ typedef TResult (TObject::* TAction)(TArg);\r
+ TMemFun1ArgEvent(TObject* theObject, TAction theAction, TArg theArg, \r
+ TResult theResult = TResult()):\r
+ myObject(theObject),\r
+ myAction(theAction),\r
+ myResult(theResult),\r
+ myArg(theArg)\r
+ {}\r
+ virtual void Execute()\r
+ {\r
+ myResult = (myObject->*myAction)(myArg);\r
+ }\r
+private:\r
+ TObject* myObject;\r
+ TAction myAction;\r
+ TStoreArg myArg;\r
+};\r
+\r
+template<class TObject, typename TArg, typename TStoreArg = TArg> \r
+class TVoidMemFun1ArgEvent : public SALOME_Event\r
+{\r
+public:\r
+ typedef void (TObject::* TAction)(TArg);\r
+ TVoidMemFun1ArgEvent(TObject* theObject, TAction theAction, TArg theArg):\r
+ myObject(theObject),\r
+ myAction(theAction),\r
+ myArg(theArg)\r
+ {}\r
+ virtual void Execute()\r
+ {\r
+ (myObject->*myAction)(myArg);\r
+ }\r
+private:\r
+ TObject* myObject;\r
+ TAction myAction;\r
+ TStoreArg myArg;\r
+};\r
+\r
+template<class TObject, typename TRes, typename TArg, typename TArg1, typename TStoreArg = TArg, typename TStoreArg1 = TArg1>\r
+class TMemFun2ArgEvent: public SALOME_Event\r
+{\r
+public:\r
+ typedef TRes TResult;\r
+ TResult myResult;\r
+ typedef TResult (TObject::* TAction)(TArg,TArg1);\r
+ TMemFun2ArgEvent(TObject* theObject, TAction theAction, \r
+ TArg theArg, TArg1 theArg1,\r
+ TResult theResult = TResult()):\r
+ myObject(theObject),\r
+ myAction(theAction),\r
+ myResult(theResult),\r
+ myArg(theArg),\r
+ myArg1(theArg1)\r
+ {}\r
+ virtual void Execute()\r
+ {\r
+ myResult = (myObject->*myAction)(myArg,myArg1);\r
+ }\r
+private:\r
+ TObject* myObject;\r
+ TAction myAction;\r
+ TStoreArg myArg;\r
+ TStoreArg1 myArg1;\r
+};\r
+\r
+template<class TObject, typename TArg, typename TArg1, typename TStoreArg = TArg, typename TStoreArg1 = TArg1>\r
+class TVoidMemFun2ArgEvent : public SALOME_Event\r
+{\r
+public:\r
+ typedef void (TObject::* TAction)(TArg,TArg1);\r
+ TVoidMemFun2ArgEvent(TObject* theObject, TAction theAction, TArg theArg, TArg1 theArg1):\r
+ myObject(theObject),\r
+ myAction(theAction),\r
+ myArg(theArg),\r
+ myArg1(theArg1)\r
+ {}\r
+ virtual void Execute()\r
+ {\r
+ (myObject->*myAction)(myArg,myArg1);\r
+ }\r
+private:\r
+ TObject* myObject;\r
+ TAction myAction;\r
+ TStoreArg myArg;\r
+ TStoreArg1 myArg1;\r
+};\r
+\r
+template<class TEvent> inline typename TEvent::TResult ProcessEvent(TEvent* theEvent)\r
+{\r
+ typename TEvent::TResult aResult;\r
+ if(SALOME_Event::IsSessionThread()) {\r
+ theEvent->Execute();\r
+ aResult = theEvent->myResult;\r
+ }\r
+ else {\r
+ theEvent->process();\r
+ aResult = theEvent->myResult;\r
+ }\r
+ delete theEvent;\r
+ return aResult;\r
+}\r
+\r
+inline void ProcessVoidEvent(SALOME_Event* theEvent)\r
+{\r
+ if(SALOME_Event::IsSessionThread()) {\r
+ theEvent->Execute();\r
+ }\r
+ else {\r
+ theEvent->process();\r
+ }\r
+ delete theEvent;\r
+}\r
+\r
+#endif // SALOME_EVENT_H\r
// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
-//
+//
// 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
+// 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
+//
+// 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
+// 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
/*!
\brief Called when action is changed.
-
+
Update action state.
*/
void QtxActionSet::onChanged()
for ( ActionList::iterator it = mySet.begin(); it != mySet.end(); ++it )
w->removeAction( *it );
+ if ( !w->actions().contains( this ) )
+ return;
+
QAction* first = 0;
for ( int i = 0; i < mySet.count(); i++ )
{
virtual bool eventFilter( QObject*, QEvent* );
+ bool isEmpty() const;
+ bool isVisible() const;
+
protected:
+ enum { Update = QEvent::User, Remove };
+
virtual void customEvent( QEvent* );
private:
void updateCaption();
void updateVisibility();
+ void setEmpty( const bool );
+ void setVisible( const bool );
+
private:
QtxDockWidget* myCont;
bool myState;
bool myEmpty;
- bool myVisible;
+ bool myBlock;
+ bool myShown;
};
/*!
QtxDockWidget::Watcher::Watcher( QtxDockWidget* cont )
: QObject( cont ), myCont( cont ),
myState( true ),
- myEmpty( false )
+ myEmpty( false ),
+ myBlock( false )
{
myCont->installEventFilter( this );
- myVisible = myCont->isVisibleTo( myCont->parentWidget() );
installFilters();
+
+ myShown = myCont->isVisibleTo( myCont->parentWidget() );
}
/*!
e->type() == QEvent::Hide || e->type() == QEvent::HideToParent ) )
{
installFilters();
- QApplication::postEvent( this, new QEvent( QEvent::User ) );
}
if ( o == myCont && e->type() == QEvent::ChildAdded )
if ( ce->child()->isWidgetType() )
ce->child()->installEventFilter( this );
- QApplication::postEvent( this, new QEvent( QEvent::User ) );
+ QApplication::postEvent( this, new QEvent( (QEvent::Type)Update ) );
}
if ( o != myCont && e->type() == QEvent::WindowIconChange )
if ( o != myCont && e->type() == QEvent::WindowTitleChange )
updateCaption();
- if ( ( o != myCont && ( e->type() == QEvent::Hide || e->type() == QEvent::HideToParent ) ) ||
- ( o == myCont && ( e->type() == QEvent::ChildRemoved ) ) ||
- ( e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ) )
+ if ( o != myCont && ( e->type() == QEvent::HideToParent || e->type() == QEvent::ShowToParent ) )
updateVisibility();
+ if ( o == myCont && e->type() == QEvent::ChildRemoved )
+ {
+ QApplication::postEvent( this, new QEvent( (QEvent::Type)Remove ) );
+ }
+
return false;
}
if ( dw != myCont )
return;
- myVisible = true;
+ setVisible( true );
}
/*!
if ( dw != myCont )
return;
- myVisible = false;
+ setVisible( false );
+}
+
+bool QtxDockWidget::Watcher::isEmpty() const
+{
+ return myEmpty;
+}
+
+bool QtxDockWidget::Watcher::isVisible() const
+{
+ return myShown;
+}
+
+void QtxDockWidget::Watcher::setEmpty( const bool on )
+{
+ myEmpty = on;
+}
+
+void QtxDockWidget::Watcher::setVisible( const bool on )
+{
+ myShown = on;
}
/*!
if ( !myCont )
return;
+ bool vis = isVisible();
+
QtxDockWidget* cont = myCont;
myCont = 0;
cont->show();
myCont = cont;
+
+ setVisible( vis );
}
/*!
if ( !myCont )
return;
+ bool vis = isVisible();
+
QtxDockWidget* cont = myCont;
myCont = 0;
cont->hide();
myCont = cont;
+
+ setVisible( vis );
}
/*!
\brief Proces custom events.
\param e custom event (not used)
*/
-void QtxDockWidget::Watcher::customEvent( QEvent* /*e*/ )
+void QtxDockWidget::Watcher::customEvent( QEvent* e )
{
- updateIcon();
- updateCaption();
- updateVisibility();
+ if ( e->type() == Update )
+ {
+ updateIcon();
+ updateCaption();
+ updateVisibility();
+ }
+ else if ( myCont && e->type() == Remove && !myCont->widget() )
+ {
+ myCont->deleteLater();
+ myCont = 0;
+ }
}
/*!
if ( !myCont )
return;
- QLayout* l = myCont->layout();
- if ( !l )
- return;
-
bool vis = false;
- for ( int i = 0; i < (int)l->count() && !vis; i++ )
- vis = l->itemAt( i ) && l->itemAt( i )->widget() && l->itemAt( i )->widget()->isVisibleTo( myCont );
+ if ( myCont->widget() )
+ vis = myCont->widget()->isVisibleTo( myCont );
+ else
+ {
+ QLayout* l = myCont->layout();
+ if ( l )
+ {
+ for ( int i = 0; i < (int)l->count() && !vis; i++ )
+ vis = l->itemAt( i ) && l->itemAt( i )->widget() && l->itemAt( i )->widget()->isVisibleTo( myCont );
+ }
+ }
- if ( myEmpty == vis )
+ bool empty = isEmpty();
+ if ( empty == vis )
{
- myEmpty = !vis;
- if ( !myEmpty )
+ empty = !vis;
+ setEmpty( empty );
+ if ( !empty )
myCont->toggleViewAction()->setVisible( myState );
else
{
}
}
- vis = !myEmpty && myVisible;
+ vis = !empty && isVisible();
if ( vis != myCont->isVisibleTo( myCont->parentWidget() ) )
vis ? showContainer() : hideContainer();
}
*/
void QtxDockWidget::Watcher::updateIcon()
{
- if ( !myCont || !myCont->widget() )
+ if ( !myCont || !myCont->widget() || myBlock )
return;
+ myBlock = true;
myCont->setWindowIcon( myCont->widget()->windowIcon() );
+ myBlock = false;
}
/*!
/*!
\brief Constructor.
- \param watch if \c true the event filter is installed to watch wigdet state changes
+ \param watch if \c true the event filter is installed to watch wigdet state changes
to update it properly
\param parent parent widget
\param f widget flags
QSize QtxDockWidget::sizeHint() const
{
QSize sz = QDockWidget::sizeHint();
-/*
- if ( place() == InDock && isStretchable() && area() )
- {
- if ( orientation() == Horizontal )
- sz.setWidth( area()->width() );
- else
- sz.setHeight( area()->height() );
- }
-*/
+
return sz;
}
QSize QtxDockWidget::minimumSizeHint() const
{
QSize sz = QDockWidget::minimumSizeHint();
-/*
- if ( orientation() == Horizontal )
- sz = QSize( 0, QDockWidget::minimumSizeHint().height() );
- else
- sz = QSize( QDockWidget::minimumSizeHint().width(), 0 );
- if ( place() == InDock && isStretchable() && area() )
- {
- if ( orientation() == Horizontal )
- sz.setWidth( area()->width() );
- else
- sz.setHeight( area()->height() );
- }
-*/
return sz;
}
*/
void QtxDockWidget::setVisible( bool on )
{
+ updateGeometry();
+ if ( widget() )
+ widget()->updateGeometry();
+
+ QDockWidget::setVisible( on && ( myWatcher ? !myWatcher->isEmpty() : true ) );
+
if ( myWatcher )
{
if ( on )
else
myWatcher->hidden( this );
}
-
- updateGeometry();
- if ( widget() )
- widget()->updateGeometry();
-
- QDockWidget::setVisible( on );
}
/*!
#include "QtxDoubleSpinBox.h"
#include <QLineEdit>
+#include <QDoubleValidator>
/*!
\class QtxDoubleSpinBox
*/
QtxDoubleSpinBox::QtxDoubleSpinBox( QWidget* parent )
: QDoubleSpinBox( parent ),
- myCleared( false )
+ myCleared( false ),
+ myPrecision(0)
{
connect( lineEdit(), SIGNAL( textChanged( const QString& ) ),
this, SLOT( onTextChanged( const QString& ) ) );
*/
QtxDoubleSpinBox::QtxDoubleSpinBox( double min, double max, double step, QWidget* parent )
: QDoubleSpinBox( parent ),
- myCleared( false )
+ myCleared( false ),
+ myPrecision( 0 )
{
setMinimum( min );
setMaximum( max );
this, SLOT( onTextChanged( const QString& ) ) );
}
+/*!
+ \brief Constructor.
+
+ Constructs a spin box with specified minimum, maximum and step value.
+ The precision is set to 2 decimal places.
+ The value is initially set to the minimum value.
+
+ \param min spin box minimum possible value
+ \param max spin box maximum possible value
+ \param step spin box increment/decrement value
+ \param parent parent object
+*/
+QtxDoubleSpinBox::QtxDoubleSpinBox( double min, double max, double step, int prec, int dec, QWidget* parent )
+: QDoubleSpinBox( parent ),
+ myCleared( false ),
+ myPrecision( prec )
+{
+ setDecimals( dec );
+ setMinimum( min );
+ setMaximum( max );
+ setSingleStep( step );
+
+ connect( lineEdit(), SIGNAL( textChanged( const QString& ) ),
+ this, SLOT( onTextChanged( const QString& ) ) );
+}
+
/*!
\brief Destructor.
*/
/*!
\brief Check if spin box is in the "cleared" state.
\return \c true if spin box is cleared
+ \sa setCleared()
*/
bool QtxDoubleSpinBox::isCleared() const
{
/*!
\brief Change "cleared" status of the spin box.
\param on new "cleared" status
+ \sa isCleared()
*/
void QtxDoubleSpinBox::setCleared( const bool on )
{
}
/*!
- \brief Convert value to the text.
- \param val value being converted
- \return string containing the converted value
+ \brief Set precision of the spin box
+
+ If precision value is less than 0, the 'g' format is used for value output,
+ otherwise 'f' format is used.
+
+ \param prec new precision value.
+ \sa precision()
+*/
+void QtxDoubleSpinBox::setPrecision( const int prec )
+{
+ int newPrec = qMax( prec, 0 );
+ int oldPrec = qMax( myPrecision, 0 );
+ myPrecision = prec;
+ if ( newPrec != oldPrec )
+ update();
+}
+
+/*!
+ \brief Get precision value of the spin box
+ \return current prevision value
+ \sa setPrecision()
+*/
+int QtxDoubleSpinBox::getPrecision() const
+{
+ return myPrecision;
+}
+
+/*!
+ \brief Interpret text entered by the user as a value.
+ \param text text entered by the user
+ \return mapped value
+ \sa textFromValue()
+*/
+double QtxDoubleSpinBox::valueFromText( const QString& text ) const
+{
+ if (myPrecision < 0)
+ return text.toDouble();
+
+ return QDoubleSpinBox::valueFromText(text);
+}
+
+/*!
+ \brief This function is used by the spin box whenever it needs to display
+ the given value.
+
+ \param val spin box value
+ \return text representation of the value
+ \sa valueFromText()
*/
QString QtxDoubleSpinBox::textFromValue( double val ) const
{
- return myCleared ? QString() : QDoubleSpinBox::textFromValue( val );
+ QString s = QLocale().toString( val, myPrecision >= 0 ? 'f' : 'g', myPrecision == 0 ? 6 : qAbs( myPrecision ) );
+ return removeTrailingZeroes( s );
+}
+
+/*!
+ \brief Return source string with removed leading and trailing zeros.
+ \param str source string
+ \return resulting string
+*/
+QString QtxDoubleSpinBox::removeTrailingZeroes( const QString& src ) const
+{
+ QString delim( QLocale().decimalPoint() );
+
+ int idx = src.lastIndexOf( delim );
+ if ( idx == -1 )
+ return src;
+
+ QString iPart = src.left( idx );
+ QString fPart = src.mid( idx + 1 );
+
+ while ( !fPart.isEmpty() && fPart.at( fPart.length() - 1 ) == '0' )
+ fPart.remove( fPart.length() - 1, 1 );
+
+ QString res = iPart;
+ if ( !fPart.isEmpty() )
+ res += delim + fPart;
+
+ return res;
}
/*!
QDoubleSpinBox::stepBy( steps );
}
+/*!
+ \brief This function is used to determine whether input is valid.
+ \param str currently entered value
+ \param pos cursor position in the string
+ \return validating operation result
+*/
+QValidator::State QtxDoubleSpinBox::validate( QString& str, int& pos ) const
+{
+ if (myPrecision >= 0)
+ return QDoubleSpinBox::validate(str, pos);
+
+ QString pref = this->prefix();
+ QString suff = this->suffix();
+ uint overhead = pref.length() + suff.length();
+ QValidator::State state = QValidator::Invalid;
+
+ QDoubleValidator v (NULL);
+ v.setDecimals( decimals() );
+ v.setBottom( minimum() );
+ v.setTop( maximum() );
+ v.setNotation( QDoubleValidator::ScientificNotation );
+
+ if ( overhead == 0 )
+ state = v.validate( str, pos );
+ else
+ {
+ if ( str.length() >= overhead && str.startsWith( pref ) &&
+ str.right( suff.length() ) == suff )
+ {
+ QString core = str.mid( pref.length(), str.length() - overhead );
+ int corePos = pos - pref.length();
+ state = v.validate( core, corePos );
+ pos = corePos + pref.length();
+ str.replace( pref.length(), str.length() - overhead, core );
+ }
+ else
+ {
+ state = v.validate( str, pos );
+ if ( state == QValidator::Invalid )
+ {
+ QString special = this->specialValueText().trimmed();
+ QString candidate = str.trimmed();
+ if ( special.startsWith( candidate ) )
+ {
+ if ( candidate.length() == special.length() )
+ state = QValidator::Acceptable;
+ else
+ state = QValidator::Intermediate;
+ }
+ }
+ }
+ }
+ return state;
+}
+
/*!
\brief Called when user enters the text in the spin box.
\param txt current spin box text (not used)
#include "Qtx.h"
#include <QDoubleSpinBox>
+#include <QValidator>
class QTX_EXPORT QtxDoubleSpinBox : public QDoubleSpinBox
{
public:
QtxDoubleSpinBox( QWidget* = 0 );
QtxDoubleSpinBox( double, double, double = 1, QWidget* = 0 );
+ QtxDoubleSpinBox( double, double, double, int, int, QWidget* = 0 );
virtual ~QtxDoubleSpinBox();
bool isCleared() const;
virtual void setCleared( const bool );
+ int getPrecision() const ;
+ void setPrecision( const int );
+
virtual void stepBy( int );
+ virtual double valueFromText( const QString& ) const;
+ virtual QString textFromValue( double ) const;
+
+ virtual QValidator::State validate( QString&, int& ) const;
+
private slots:
virtual void onTextChanged( const QString& );
protected:
- virtual QString textFromValue( double ) const;
+ QString removeTrailingZeroes( const QString& ) const;
private:
bool myCleared;
+ int myPrecision;
};
#endif
if ( stdSets )
{
myParser->setAutoDeleteOperationSets( true );
- myParser->insertOperationSet( new QtxEvalSetArithmetic() );
myParser->insertOperationSet( new QtxEvalSetLogic() );
+ myParser->insertOperationSet( new QtxEvalSetArithmetic() );
myParser->insertOperationSet( new QtxEvalSetString() );
myParser->insertOperationSet( new QtxEvalSetMath() );
myParser->insertOperationSet( new QtxEvalSetSets() );
if ( mySets.contains( set ) )
return;
- int index = idx < 0 ? mySets.count() - 1 : idx;
- index = qMin( index, mySets.count() - 1 );
+ int index = idx < 0 ? mySets.count() : idx;
+ index = qMin( index, mySets.count() );
mySets.insert( index, set );
}
while ( pos < len && error() == QtxEvalExpr::OK )
{
PostfixItem item;
- while ( expr[pos].isSpace() && pos < len )
+ while ( pos < len && expr[pos].isSpace() )
pos++;
if ( pos >= len )
break;
for ( SetList::const_iterator it = mySets.begin(); it != mySets.end() && priority <= 0; ++it, i++ )
priority = (*it)->priority( op, isBin );
- return priority > 0 ? priority + i * 10 : 0;
+ return priority > 0 ? priority + i * 50 : 0;
}
/*!
QtxEvalExpr::Error QtxEvalSetLogic::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
{
QtxEvalExpr::Error err = QtxEvalExpr::OK;
- bool val1 = booleanValue( v1 );
- bool val2 = booleanValue( v2 );
+ int val1 = intValue( v1 );
+ int val2 = intValue( v2 );
if ( v1.isValid() && v2.isValid() )
{
if ( op == "and" || op == "&&" )
}
/*!
- \brief Convert value to the boolean.
+ \brief Convert value to the integer.
+
+ Note: the value is converted to the integer (not boolean) in order
+ to compare integer numbers correctly.
+
\param v value being converted
\return converted value
*/
-bool QtxEvalSetLogic::booleanValue( const QVariant& v ) const
+int QtxEvalSetLogic::intValue( const QVariant& v ) const
{
- bool res = false;
+ int res = 0;
switch ( v.type() )
{
case QVariant::Bool:
- res = v.toBool();
+ res = v.toBool() ? 1 : 0;
break;
case QVariant::Int:
- res = v.toInt() != 0;
- break;
case QVariant::UInt:
- res = v.toUInt() != 0;
+ res = v.toInt();
break;
default:
- res = false;
break;
}
return res;
virtual QString name() const;
private:
- bool booleanValue( const QVariant& v ) const;
+ int intValue( const QVariant& v ) const;
};
class QTX_EXPORT QtxEvalSetMath : public QtxEvalSetBase
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-// File: QtxMap.h
-// Author: Vadim SANDLER
+// File : QtxMap.h
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
#ifndef QTXMAP_H
#define QTXMAP_H
#include <QDomNode>
#endif
-#define EMULATE_GLOBAL_CONTEXT
-
#include <stdlib.h>
/*!
if ( !isHeaderEditing() )
return;
- QString oldTxt = myEditedHeader ? myEditedHeader->label( myEditedSection ) : QString::null;
+ QString oldTxt = myEditedHeader ? myEditedHeader->label( myEditedSection ) : QString();
if ( accept && myEditedHeader )
setHeaderContentFromEditor( myEditedHeader, myEditedSection, myHeaderEditor );
- QString newTxt = myEditedHeader ? myEditedHeader->label( myEditedSection ) : QString::null;
+ QString newTxt = myEditedHeader ? myEditedHeader->label( myEditedSection ) : QString();
int sec = myEditedSection;
QHeaderView* hdr = myEditedHeader;
// File: QtxTable.h
// Author: Sergey TELKOV
-#ifndef QTX_TABLE_H
-#define QTX_TABLE_H
+#ifndef QTXTABLE_H
+#define QTXTABLE_H
#include "Qtx.h"
#endif
-#endif
+#endif // QTXTABLE_H