]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Merging GUI_SRC module with the BR_V5_DEV branch.
authornds <nds@opencascade.com>
Wed, 8 Oct 2008 03:31:53 +0000 (03:31 +0000)
committernds <nds@opencascade.com>
Wed, 8 Oct 2008 03:31:53 +0000 (03:31 +0000)
14 files changed:
src/Event/Event.h [new file with mode: 0755]
src/Event/Event.pro [new file with mode: 0644]
src/Event/SALOME_Event.cxx [new file with mode: 0755]
src/Event/SALOME_Event.h [new file with mode: 0644]
src/Qtx/QtxActionSet.cxx
src/Qtx/QtxDockWidget.cxx
src/Qtx/QtxDoubleSpinBox.cxx
src/Qtx/QtxDoubleSpinBox.h
src/Qtx/QtxEvalExpr.cxx
src/Qtx/QtxEvalExpr.h
src/Qtx/QtxMap.h
src/Qtx/QtxResourceMgr.cxx
src/Qtx/QtxTable.cxx
src/Qtx/QtxTable.h

diff --git a/src/Event/Event.h b/src/Event/Event.h
new file mode 100755 (executable)
index 0000000..db337d4
--- /dev/null
@@ -0,0 +1,37 @@
+//  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
diff --git a/src/Event/Event.pro b/src/Event/Event.pro
new file mode 100644 (file)
index 0000000..c808735
--- /dev/null
@@ -0,0 +1,24 @@
+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
diff --git a/src/Event/SALOME_Event.cxx b/src/Event/SALOME_Event.cxx
new file mode 100755 (executable)
index 0000000..c48945f
--- /dev/null
@@ -0,0 +1,243 @@
+//  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
diff --git a/src/Event/SALOME_Event.h b/src/Event/SALOME_Event.h
new file mode 100644 (file)
index 0000000..c44cc6d
--- /dev/null
@@ -0,0 +1,229 @@
+//  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
index da8d7630dda2e6891c4a6e7bc65e845d9872c4e3..916ce7ec8afdc4f5decc69761018f6efa46ccd3d 100644 (file)
@@ -1,17 +1,17 @@
 // 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
@@ -212,7 +212,7 @@ void QtxActionSet::clear()
 
 /*!
   \brief Called when action is changed.
-  
+
   Update action state.
 */
 void QtxActionSet::onChanged()
@@ -363,6 +363,9 @@ void QtxActionSet::updateAction( QWidget* w )
   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++ )
   {
index fd6f003714d12dcb0fb779ee6814236f0ba8ddcf..fde9657d5fb036a128ea7b94e1e4a640b64bbb30 100644 (file)
@@ -43,7 +43,12 @@ public:
 
   virtual bool   eventFilter( QObject*, QEvent* );
 
+  bool           isEmpty() const;
+  bool           isVisible() const;
+
 protected:
+  enum { Update = QEvent::User, Remove };
+
   virtual void   customEvent( QEvent* );
 
 private:
@@ -56,11 +61,15 @@ 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;
 };
 
 /*!
@@ -70,12 +79,14 @@ private:
 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() );
 }
 
 /*!
@@ -90,7 +101,6 @@ bool QtxDockWidget::Watcher::eventFilter( QObject* o, QEvent* e )
                         e->type() == QEvent::Hide || e->type() == QEvent::HideToParent ) )
   {
     installFilters();
-    QApplication::postEvent( this, new QEvent( QEvent::User ) );
   }
 
   if ( o == myCont && e->type() == QEvent::ChildAdded )
@@ -99,7 +109,7 @@ bool QtxDockWidget::Watcher::eventFilter( QObject* o, QEvent* e )
     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 )
@@ -108,11 +118,14 @@ bool QtxDockWidget::Watcher::eventFilter( QObject* o, QEvent* e )
   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;
 }
 
@@ -125,7 +138,7 @@ void QtxDockWidget::Watcher::shown( QtxDockWidget* dw )
   if ( dw != myCont )
     return;
 
-  myVisible = true;
+  setVisible( true );
 }
 
 /*!
@@ -137,7 +150,27 @@ void QtxDockWidget::Watcher::hidden( QtxDockWidget* dw )
   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;
 }
 
 /*!
@@ -148,10 +181,14 @@ void QtxDockWidget::Watcher::showContainer()
   if ( !myCont )
     return;
 
+  bool vis = isVisible();
+
   QtxDockWidget* cont = myCont;
   myCont = 0;
   cont->show();
   myCont = cont;
+
+  setVisible( vis );
 }
 
 /*!
@@ -162,21 +199,33 @@ void QtxDockWidget::Watcher::hideContainer()
   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;
+  }
 }
 
 /*!
@@ -208,18 +257,25 @@ void QtxDockWidget::Watcher::updateVisibility()
   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
     {
@@ -228,7 +284,7 @@ void QtxDockWidget::Watcher::updateVisibility()
     }
   }
 
-  vis = !myEmpty && myVisible;
+  vis = !empty && isVisible();
   if ( vis != myCont->isVisibleTo( myCont->parentWidget() ) )
     vis ? showContainer() : hideContainer();
 }
@@ -238,10 +294,12 @@ void QtxDockWidget::Watcher::updateVisibility()
 */
 void QtxDockWidget::Watcher::updateIcon()
 {
-  if ( !myCont || !myCont->widget() )
+  if ( !myCont || !myCont->widget() || myBlock )
     return;
 
+  myBlock = true;
   myCont->setWindowIcon( myCont->widget()->windowIcon() );
+  myBlock = false;
 }
 
 /*!
@@ -274,7 +332,7 @@ QtxDockWidget::QtxDockWidget( const QString& title, QWidget* parent, Qt::WindowF
 
 /*!
   \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
@@ -315,15 +373,7 @@ QtxDockWidget::~QtxDockWidget()
 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;
 }
 
@@ -334,20 +384,7 @@ QSize QtxDockWidget::sizeHint() const
 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;
 }
 
@@ -357,6 +394,12 @@ QSize QtxDockWidget::minimumSizeHint() const
 */
 void QtxDockWidget::setVisible( bool on )
 {
+  updateGeometry();
+  if ( widget() )
+    widget()->updateGeometry();
+
+  QDockWidget::setVisible( on && ( myWatcher ? !myWatcher->isEmpty() : true )  );
+
   if ( myWatcher )
   {
     if ( on )
@@ -364,12 +407,6 @@ void QtxDockWidget::setVisible( bool on )
     else
       myWatcher->hidden( this );
   }
-
-  updateGeometry();
-  if ( widget() )
-    widget()->updateGeometry();
-
-  QDockWidget::setVisible( on );
 }
 
 /*!
index c79e581c0354790b962700ab7b9fefbfa7e545c8..ba8585f4a00c60ecad4b2fea2659e9f61cece6cc 100644 (file)
@@ -22,6 +22,7 @@
 #include "QtxDoubleSpinBox.h"
 
 #include <QLineEdit>
+#include <QDoubleValidator>
 
 /*!
   \class QtxDoubleSpinBox
@@ -57,7 +58,8 @@
 */
 QtxDoubleSpinBox::QtxDoubleSpinBox( QWidget* parent )
 : QDoubleSpinBox( parent ),
-  myCleared( false )
+  myCleared( false ),
+  myPrecision(0)
 {
   connect( lineEdit(), SIGNAL( textChanged( const QString& ) ), 
           this, SLOT( onTextChanged( const QString& ) ) );
@@ -77,7 +79,8 @@ QtxDoubleSpinBox::QtxDoubleSpinBox( QWidget* parent )
 */
 QtxDoubleSpinBox::QtxDoubleSpinBox( double min, double max, double step, QWidget* parent )
 : QDoubleSpinBox( parent ),
-  myCleared( false )
+  myCleared( false ),
+  myPrecision( 0 )
 {
   setMinimum( min );
   setMaximum( max );
@@ -87,6 +90,32 @@ QtxDoubleSpinBox::QtxDoubleSpinBox( double min, double max, double step, QWidget
           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.
 */
@@ -97,6 +126,7 @@ QtxDoubleSpinBox::~QtxDoubleSpinBox()
 /*!
   \brief Check if spin box is in the "cleared" state.
   \return \c true if spin box is cleared
+  \sa setCleared()
 */
 bool QtxDoubleSpinBox::isCleared() const
 {
@@ -106,6 +136,7 @@ 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 )
 {
@@ -117,13 +148,85 @@ 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;
 }
 
 /*!
@@ -142,6 +245,61 @@ void QtxDoubleSpinBox::stepBy( int steps )
   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)
index 45ef5434b517feb359106ad160dbd11dd3dd68c4..29958dcfb8d9cb770569bff6b7238d4de2d7ec02 100644 (file)
@@ -25,6 +25,7 @@
 #include "Qtx.h"
 
 #include <QDoubleSpinBox>
+#include <QValidator>
 
 class QTX_EXPORT QtxDoubleSpinBox : public QDoubleSpinBox
 {
@@ -33,21 +34,31 @@ 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
index 75bcb7c433f3ef09f29ea3af2675bd62f9a4810e..f892bfb6ef6eeb5c085bf91332d22a84595a8e30 100644 (file)
@@ -72,8 +72,8 @@ void QtxEvalExpr::intialize( const bool stdSets, const QString& expr )
   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() );
@@ -266,8 +266,8 @@ void QtxEvalParser::insertOperationSet( QtxEvalSet* set, const int idx )
   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 );
 }
 
@@ -371,7 +371,7 @@ bool QtxEvalParser::prepare( const QString& expr, Postfix& post )
   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;
@@ -1181,7 +1181,7 @@ int QtxEvalParser::priority( const QString& op, bool isBin ) const
   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;
 }
 
 /*!
@@ -1761,8 +1761,8 @@ int QtxEvalSetLogic::priority( const QString& op, bool isBin ) const
 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 == "&&" )
@@ -1783,26 +1783,27 @@ QtxEvalExpr::Error QtxEvalSetLogic::calculate( const QString& op, QVariant& v1,
 }
 
 /*!
-  \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;
index 34acd474789d0f8615d236bbe8865406a82e372a..6679d7e8659380949e617a6e6bef90ab166c4979 100644 (file)
@@ -247,7 +247,7 @@ public:
   virtual QString            name() const;
 
 private:
-  bool                       booleanValue( const QVariant& v ) const;
+  int                        intValue( const QVariant& v ) const;
 };
 
 class QTX_EXPORT QtxEvalSetMath : public QtxEvalSetBase
index 403fc3284804237b51864eb2517703b847ef2a13..98dec2975669c4a7744a02eb60469295d7f40005 100644 (file)
@@ -16,8 +16,9 @@
 //
 // 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
index 273c491597ceb211dbc2039e02be528569354e96..80812a2f18ca3df926d835295fcbe56992dea5ac 100644 (file)
@@ -33,8 +33,6 @@
 #include <QDomNode>
 #endif
 
-#define EMULATE_GLOBAL_CONTEXT
-
 #include <stdlib.h>
 
 /*!
index 64f9ae5c7471c788bf4f2bd3e1a6d2f9e4ec1550..630694b454196ae8784558313efa3489d9da54e1 100644 (file)
@@ -1510,12 +1510,12 @@ void QtxTable::endHeaderEdit( const bool accept )
   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;
index ea93a37c91e0e6cd60c590be1d0f8bace0ce02aa..52443ffab8ef033f943a7d169328089498ef2b7b 100644 (file)
@@ -19,8 +19,8 @@
 // File:      QtxTable.h
 // Author:    Sergey TELKOV
 
-#ifndef QTX_TABLE_H
-#define QTX_TABLE_H
+#ifndef QTXTABLE_H
+#define QTXTABLE_H
 
 #include "Qtx.h"
 
@@ -199,4 +199,4 @@ private:
 
 #endif
 
-#endif
+#endif // QTXTABLE_H