Salome HOME
Merge 'oscar/porting_to_V9' branch.
authorabn <adrien.bruneton@cea.fr>
Tue, 15 Jan 2019 13:24:23 +0000 (14:24 +0100)
committerrnv <rnv@opencascade.com>
Tue, 29 Oct 2019 13:59:07 +0000 (16:59 +0300)
74 files changed:
src/LightApp/LightApp_OBSelector.cxx
src/SUIT/SUIT_TreeSync.h
tools/CurvePlot/CMakeLists.txt
tools/CurvePlot/SalomeCURVEPLOTConfig.cmake.in
tools/CurvePlot/src/cpp/CurvePlot.cxx
tools/CurvePlot/src/cpp/CurvePlot.hxx
tools/CurvePlot/src/cpp/test/CMakeLists.txt
tools/CurvePlot/src/cpp/test/test_curveplot.cxx
tools/CurvePlot/src/python/controller/CMakeLists.txt
tools/CurvePlot/src/python/controller/PlotController.py
tools/CurvePlot/src/python/controller/__init__.py
tools/CurvePlot/src/python/controller/utils.py.in
tools/CurvePlot/src/python/model/CMakeLists.txt
tools/CurvePlot/src/python/model/CurveModel.py
tools/CurvePlot/src/python/model/PlotManager.py
tools/CurvePlot/src/python/model/TableModel.py
tools/CurvePlot/src/python/model/XYPlotSetModel.py
tools/CurvePlot/src/python/pyqtside/CMakeLists.txt
tools/CurvePlot/src/python/pyqtside/QtCore.py
tools/CurvePlot/src/python/pyqtside/QtGui.py
tools/CurvePlot/src/python/pyqtside/QtWidgets.py [new file with mode: 0644]
tools/CurvePlot/src/python/pyqtside/__init__.py
tools/CurvePlot/src/python/pyqtside/pyside_dynamic.py
tools/CurvePlot/src/python/pyqtside/uic.py
tools/CurvePlot/src/python/test/CMakeLists.txt
tools/CurvePlot/src/python/test/PlotCurve_Standalone.py
tools/CurvePlot/src/python/test/PlotTestBase.py
tools/CurvePlot/src/python/test/README.txt
tools/CurvePlot/src/python/test/SalomePyQt_MockUp.py.in
tools/CurvePlot/src/python/test/TestDesktop.py
tools/CurvePlot/src/python/test/baselines/testAddCurveAppend_a.png
tools/CurvePlot/src/python/test/baselines/testAddCurve_a.png
tools/CurvePlot/src/python/test/baselines/testAddPlotSet_a.png
tools/CurvePlot/src/python/test/baselines/testClearPlotSet2_a.png
tools/CurvePlot/src/python/test/baselines/testClearPlotSet_a.png
tools/CurvePlot/src/python/test/baselines/testCopyCurve_a.png
tools/CurvePlot/src/python/test/baselines/testDeleteCurrentItem_curve_a.png
tools/CurvePlot/src/python/test/baselines/testDeleteCurrentItem_plotSet_a.png
tools/CurvePlot/src/python/test/baselines/testDeleteCurve1_a.png
tools/CurvePlot/src/python/test/baselines/testDeleteCurve2_a.png
tools/CurvePlot/src/python/test/baselines/testDeleteCurve3_a.png
tools/CurvePlot/src/python/test/baselines/testDeletePlotSet1_a.png
tools/CurvePlot/src/python/test/baselines/testDeletePlotSet2_a.png
tools/CurvePlot/src/python/test/baselines/testExtendCurve_a.png
tools/CurvePlot/src/python/test/baselines/testLockRepaint_a.png
tools/CurvePlot/src/python/test/baselines/testPlotCurveFromTable_a.png
tools/CurvePlot/src/python/test/baselines/testResetCurve_a.png
tools/CurvePlot/src/python/test/baselines/testSetCurrentCurve2_a.png
tools/CurvePlot/src/python/test/baselines/testSetCurrentCurve3_a.png
tools/CurvePlot/src/python/test/baselines/testSetCurrentCurve_a.png
tools/CurvePlot/src/python/test/baselines/testSetCurrentPlotSet_a.png
tools/CurvePlot/src/python/test/baselines/testSetCurveLabel_a.png
tools/CurvePlot/src/python/test/baselines/testSetCurveMarker_a.png
tools/CurvePlot/src/python/test/baselines/testSetLabelX_a.png
tools/CurvePlot/src/python/test/baselines/testSetLabelY_a.png
tools/CurvePlot/src/python/test/baselines/testSetLegendVisible_a.png
tools/CurvePlot/src/python/test/baselines/testSetPlotSetTitle_a.png
tools/CurvePlot/src/python/test/baselines/testSetXSciNotation_a.png
tools/CurvePlot/src/python/test/baselines/testSetYSciNotation_a.png
tools/CurvePlot/src/python/test/baselines/testSettingsCurveColor_a.png
tools/CurvePlot/src/python/test/baselines/testSettingsCurveMarker_a.png
tools/CurvePlot/src/python/test/baselines/testToggleXLog_a.png
tools/CurvePlot/src/python/test/baselines/testToggleYLog_a.png
tools/CurvePlot/src/python/test/plot_test.py
tools/CurvePlot/src/python/ui/CMakeLists.txt
tools/CurvePlot/src/python/ui/CurveTreeDockWidget.py
tools/CurvePlot/src/python/ui/PlotSettings.py
tools/CurvePlot/src/python/ui/PlotSettings.ui
tools/CurvePlot/src/python/ui/PlotWidget.py
tools/CurvePlot/src/python/views/CMakeLists.txt
tools/CurvePlot/src/python/views/CurveBrowserView.py
tools/CurvePlot/src/python/views/CurveTabsView.py
tools/CurvePlot/src/python/views/CurveView.py
tools/CurvePlot/src/python/views/XYView.py

index 75d1a1621c9f834f575243b64980a661de4ae004..b2e84dfdec36233172eec29308d8e74803c8dce7 100644 (file)
@@ -105,7 +105,9 @@ void LightApp_OBSelector::onSelectionChanged()
   mySelectedList.clear();
   selectionChanged();
   QTime t2 = QTime::currentTime();
+#ifdef _DEBUG_
   qDebug( QString( "selection time = %1 msecs" ).arg( t1.msecsTo( t2 ) ).toLatin1().constData() );
+#endif
 }
 
 /*!
index 5a0779009bb0d311f2dfdb3b61b55de62f6a1e91..a52b07ee54658c4137588f987afed6835f9b69c3 100644 (file)
@@ -131,7 +131,11 @@ TrgItem synchronize( const SrcItem& r1, const TrgItem& r2, const TreeData& td )
       const DiffItem<SrcItem,TrgItem>& item = *anIt;
       if ( item.mySrc == td.nullSrc() ) {
         if ( item.myTrg == td.nullTrg() )
+        {
+#ifdef _DEBUG_
           qDebug( "error: both null" );
+#endif
+        }
         else
           // delete item
           td.deleteItemWithChildren( item.myTrg );
index 22c1fb0cd2a06cb6d41eb66ced684052f4d635f1..45c12f8f148d9e1ef0c863c0c5f89972801f419b 100644 (file)
@@ -29,12 +29,12 @@ CMAKE_POLICY(SET CMP0003 NEW)
 # Project name, upper case
 STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC)
 
-SET(${PROJECT_NAME_UC}_MAJOR_VERSION 7)
-SET(${PROJECT_NAME_UC}_MINOR_VERSION 6)
+SET(${PROJECT_NAME_UC}_MAJOR_VERSION 9)
+SET(${PROJECT_NAME_UC}_MINOR_VERSION 2)
 SET(${PROJECT_NAME_UC}_PATCH_VERSION 0)
 SET(${PROJECT_NAME_UC}_VERSION
   ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION})
-SET(${PROJECT_NAME_UC}_VERSION_DEV 1)
+SET(${PROJECT_NAME_UC}_VERSION_DEV 0)
 
 # User options
 # ============
@@ -106,20 +106,11 @@ FIND_PACKAGE(SalomePythonInterp    REQUIRED)
 FIND_PACKAGE(SalomePythonLibs    REQUIRED)
 FIND_PACKAGE(SalomeNumPySciPy    REQUIRED)
 
-# Qt4
-FIND_PACKAGE(SalomeQt4 REQUIRED COMPONENTS QtCore QtGui)
-INCLUDE(${QT_USE_FILE})
+# Qt
+FIND_PACKAGE(SalomeQt5 REQUIRED)
+FIND_PACKAGE(SalomePyQt5 REQUIRED)
 
 # Optional products:
-
-IF(SALOME_BUILD_DOC)
-#  FIND_PACKAGE(SalomeDoxygen)
-#  FIND_PACKAGE(SalomeSphinx)
-#  SALOME_LOG_OPTIONAL_PACKAGE(Doxygen SALOME_BUILD_DOC)
-#  SALOME_LOG_OPTIONAL_PACKAGE(Sphinx SALOME_BUILD_DOC)
-#  ADD_DEFINITIONS(-DDOXYGEN_IS_OK)
-ENDIF()
-
 IF(SALOME_BUILD_TESTS)
   ENABLE_TESTING()
 ENDIF()
@@ -155,12 +146,15 @@ ENDIF()
 # Specific to CURVEPLOT:
 SET(SALOME_CURVEPLOT_INSTALL_RES_DATA "${SALOME_INSTALL_RES}/curveplot" CACHE PATH 
     "Install path: SALOME CURVEPLOT specific data")
-# Package installation path (lib/python2.7/...) 
+# Package installation path (lib/python<x.y>/...)
 SET(SALOME_CURVEPLOT_INSTALL_PYTHON ${SALOME_INSTALL_PYTHON}/curveplot CACHE INTERNAL  
     "Install path: SALOME CURVEPLOT Python packages" FORCE)
 SET(SALOME_CURVEPLOT_INSTALL_SCRIPT_PYTHON ${SALOME_INSTALL_SCRIPT_PYTHON} CACHE INTERNAL  
     "Install path: SALOME CURVEPLOT Python main entry points" FORCE)
 
+SET(CRVPLOT_TEST_INSTALL ${CMAKE_BINARY_DIR}/local/curveplot)
+SET(PYQTSIDE_TEST_INSTALL ${CMAKE_BINARY_DIR}/local/pyqtside)
+
 # Sources 
 # ========
 ADD_SUBDIRECTORY(src)
@@ -192,25 +186,25 @@ EXPORT(TARGETS ${_${PROJECT_NAME}_exposed_targets}
 #      Ensure the variables are always defined for the configure:
 SET(KERNEL_ROOT_DIR "${KERNEL_ROOT_DIR}")
 SET(GUI_ROOT_DIR "${GUI_ROOT_DIR}")
-SET(QT4_ROOT_DIR "${QT4_ROOT_DIR}")
-SET(PYQT4_ROOT_DIR "${PYQT4_ROOT_DIR}")
+SET(QT5_ROOT_DIR "${QT5_ROOT_DIR}")
+SET(PYQT5_ROOT_DIR "${PYQT5_ROOT_DIR}")
 SET(PYTHON_ROOT_DIR "${PYTHON_ROOT_DIR}")
  
 SET(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include" "${PROJECT_BINARY_DIR}/include")
 
 # Build variables that will be expanded when configuring Salome<MODULE>Config.cmake:
-SALOME_CONFIGURE_PREPARE(PyQt4 Qt4 Python)
+SALOME_CONFIGURE_PREPARE(PyQt5 Qt5 Python)
 
 CONFIGURE_PACKAGE_CONFIG_FILE(${PROJECT_NAME}Config.cmake.in 
     ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
     INSTALL_DESTINATION "${SALOME_INSTALL_CMAKE_LOCAL}"
     PATH_VARS CONF_INCLUDE_DIRS SALOME_INSTALL_CMAKE_LOCAL CMAKE_INSTALL_PREFIX
-       KERNEL_ROOT_DIR GUI_ROOT_DIR QT4_ROOT_DIR PYQT4_ROOT_DIR PYTHON_ROOT_DIR)
+       KERNEL_ROOT_DIR GUI_ROOT_DIR QT5_ROOT_DIR PYQT5_ROOT_DIR PYTHON_ROOT_DIR)
 
 WRITE_BASIC_PACKAGE_VERSION_FILE(${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
     VERSION ${${PROJECT_NAME_UC}_VERSION}
     COMPATIBILITY AnyNewerVersion)
-  
+
 # Install the CMake configuration files:
 INSTALL(FILES
   "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
@@ -222,4 +216,4 @@ IF(NOT SALOME_CURVEPLOT_STANDALONE)
     INSTALL(EXPORT ${PROJECT_NAME}TargetGroup DESTINATION "${SALOME_INSTALL_CMAKE_LOCAL}" 
         FILE ${PROJECT_NAME}Targets.cmake)
 ENDIF()
-  
+
index 9fbef2ed0f0a5d57193df63b4861b212456be2aa..0a68585054d76d51737dacc5aba80c8f369b62f4 100644 (file)
@@ -53,8 +53,8 @@ IF(SALOME_CURVEPLOT_STANDALONE)
   SET_AND_CHECK(GUI_ROOT_DIR_EXP "@PACKAGE_GUI_ROOT_DIR@")
 ENDIF()
 
-SET_AND_CHECK(QT4_ROOT_DIR_EXP "@PACKAGE_QT4_ROOT_DIR@")
-SET_AND_CHECK(PYQT4_ROOT_DIR_EXP "@PACKAGE_PYQT4_ROOT_DIR@")
+SET_AND_CHECK(QT5_ROOT_DIR_EXP "@PACKAGE_QT5_ROOT_DIR@")
+SET_AND_CHECK(PYQT5_ROOT_DIR_EXP "@PACKAGE_PYQT5_ROOT_DIR@")
 SET_AND_CHECK(PYTHON_ROOT_DIR_EXP "@PACKAGE_PYTHON_ROOT_DIR@")
 
 
index 0d54792e5d672030df95c914f2aae2536865f4a9..d1a37150e29fd9cb24be5d00069e0b233ade5e2c 100644 (file)
@@ -21,7 +21,9 @@
 
 #include <Python.h>
 
-#define PY_ARRAY_UNIQUE_SYMBOL CURVEPLOT_ARRAY_API    // see initializeCurvePlot()
+// see  https://docs.scipy.org/doc/numpy/reference/c-api.array.html?highlight=import_array
+// and  https://docs.scipy.org/doc/numpy-1.15.0/reference/c-api.deprecations.html
+#define PY_ARRAY_UNIQUE_SYMBOL CURVEPLOT_ARRAY_API
 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
 #include <numpy/ndarraytypes.h>
 #include <numpy/ndarrayobject.h>
@@ -52,12 +54,13 @@ namespace CURVEPLOT
   /**
    * To be called before doing anything
    */
-  void InitializeCurvePlot()
+  void* InitializeCurvePlot()
   {
     PyLockWrapper lock;
     // TODO: discuss where the below should really happen:
     // doc: http://docs.scipy.org/doc/numpy/reference/c-api.array.html#importing-the-api
-    import_array(); // a macro really!
+    import_array(); // a macro really which contains a return
+    return NULL;
   }
 
   class ColumnVector::Internal
@@ -153,9 +156,11 @@ namespace CURVEPLOT
                  PyObject_CallMethod((PyObject *)_impl->_npArray, (char *)"__str__", NULL)
                  );
        // Now extract the returned string
-       if(!PyString_Check(ret_py))
+       if(!PyUnicode_Check(ret_py))
          throw Exception("CurvePlot::toStdString(): Unexpected returned type!");
-       ret_str = std::string(PyString_AsString(ret_py));
+       Py_ssize_t size;
+       char *ptr = PyUnicode_AsUTF8AndSize(ret_py, &size);
+       ret_str = std::string(ptr);
     }
     return ret_str;
   }
@@ -188,13 +193,13 @@ namespace CURVEPLOT
 
   CurvePlot::CurvePlot(bool test_mode)
   {
-    // TODO: do use an intermediate variable '__cont', but use directly Py***CallMethod()
+    // TODO: do not use an intermediate variable '__cont', but use directly Py***CallMethod()
     _impl = new Internal();
     {
     PyLockWrapper lock;
     std::string code;
     if (test_mode)
-       code = std::string("import curveplot; from SalomePyQt_MockUp import SalomePyQt;") +
+       code = std::string("import curveplot; from curveplot.SalomePyQt_MockUp import SalomePyQt;") +
            std::string("__cont=curveplot.PlotController.GetInstance(sgPyQt=SalomePyQt())");
     else
        code = std::string("import curveplot;")+
@@ -266,13 +271,13 @@ namespace CURVEPLOT
     if(!PyTuple_Check(ret))
         throw Exception("CurvePlot::AddCurve(): Unexpected returned type!");
     PyObject * o1 = PyTuple_GetItem(ret, 0);
-    if (!PyInt_Check(o1))
+    if (!PyLong_Check(o1))
       throw Exception("CurvePlot::AddCurve(): Unexpected returned type!");
-    PlotID curveId = PyInt_AsLong(o1);
+    PlotID curveId = PyLong_AsLong(o1);
     PyObject * o2 = PyTuple_GetItem(ret, 1);
-    if (!PyInt_Check(o2))
+    if (!PyLong_Check(o2))
       throw Exception("CurvePlot::AddCurve(): Unexpected returned type!");
-    plot_set_id = PyInt_AsLong(o2);
+    plot_set_id = PyLong_AsLong(o2);
     return curveId;
   }
 
index aad7447080fd33c5af646ee15ec3d5b97e6b7fc5..92b86802b527de320b683e3095eb4d96d7a6cc43 100644 (file)
@@ -32,7 +32,7 @@ namespace CURVEPLOT
   /**
    * This function should be called before doing anything in the CURVEPLOT namespace.
    */
-  void InitializeCurvePlot();
+  void* InitializeCurvePlot();
 
   class ColumnVector
   {
index 436ffa7ff14ce643757a51792c649d87beeb77a8..77d01edb7e09774d5fc870928483b4b192cb686a 100644 (file)
@@ -44,7 +44,7 @@ SET(_other_SOURCES
 # --- rules ---
 
 # sources / moc wrappings
-QT4_WRAP_CPP(_moc_SOURCES ${_moc_HEADERS})
+QT5_WRAP_CPP(_moc_SOURCES ${_moc_HEADERS})
 
 ADD_EXECUTABLE(test_curveplot ${_other_SOURCES} ${_moc_SOURCES})
 TARGET_LINK_LIBRARIES(test_curveplot ${_link_LIBRARIES})
index 1114fd614844df1a7cc2faae0b223be665c59980..26b2d2ee8a6ba8b0dac77bbef4daf5b2d73b8eaf 100644 (file)
 // Author : Adrien BRUNETON
 //
 
+#include <PyInterp_Utils.h>  // GUI - must come first to avoid conflict on the token "slots" defined in both Qt and Python ...
+
 #include "test_curveplot.hxx"
 
-#include <PyInterp_Utils.h>  // GUI
 #include <iostream>
 #include <vector>
 #include "CurvePlot.hxx"
@@ -70,14 +71,20 @@ void TestCurvePlot::onClicked()
   std::cout << "setting X label " << CurvePlot::SetXLabel("tôtô") << std::endl;
 }
 
+/*!
+ * Similar to: SUIT_PYTHON::init_python() from GUI
+ *  or         KERNEL_PYTHON::init_python() from KERNEL
+ */
 void initPython()
 {
   if (!Py_IsInitialized()){
       // Python is not initialized
       Py_Initialize(); // Initialize the interpreter
 
-      PyEval_InitThreads(); // Create (and acquire) the Python global interpreter lock (GIL)
-      PyEval_ReleaseLock();
+      PyRun_SimpleString("import threading\n");
+
+      PyThreadState *pts = PyGILState_GetThisThreadState();
+      PyEval_ReleaseThread(pts);
   }
 }
 
@@ -107,7 +114,7 @@ int main(int argc, char ** argv)
   mw.resize((int)(dw->width()*0.25), (int)(dw->height()*0.7));
   mw.show();
 
-  initPython();
+  initPython();   // mimic SALOME Python's initialisation.
   InitializeCurvePlot();
 
   {
index e5636a8a889fb57b17c28881e000bcd9918c5c7f..b7e6bca218fb263999e0f524839fed5084625ea4 100644 (file)
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
+SET(SALOME_CURVEPLOT_TEST_MODE "0")
 SALOME_CONFIGURE_FILE(utils.py.in ${CMAKE_CURRENT_BINARY_DIR}/utils.py)
 
+# For test purposes:
+SET(SALOME_CURVEPLOT_TEST_MODE "1")
+SALOME_CONFIGURE_FILE(utils.py.in ${CMAKE_CURRENT_BINARY_DIR}/utils_test.py)
+SET(SALOME_CURVEPLOT_TEST_MODE "0")
+
 SET(_all_lib_SCRIPTS
     PlotController.py
     __init__.py
-    ${CMAKE_CURRENT_BINARY_DIR}/utils.py
 )
 
+SET(_util_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/utils.py)
+
 SALOME_INSTALL_SCRIPTS("${_all_lib_SCRIPTS}" ${SALOME_CURVEPLOT_INSTALL_PYTHON})
+SALOME_INSTALL_SCRIPTS("${_util_SCRIPT}" ${SALOME_CURVEPLOT_INSTALL_PYTHON})
+
+# For test purposes
+FILE(COPY ${_all_lib_SCRIPTS} DESTINATION ${CRVPLOT_TEST_INSTALL})
+FILE(COPY ${CMAKE_CURRENT_BINARY_DIR}/utils_test.py DESTINATION ${CRVPLOT_TEST_INSTALL})
+FILE(RENAME ${CRVPLOT_TEST_INSTALL}/utils_test.py ${CRVPLOT_TEST_INSTALL}/utils.py)
index 4967fe6b1060c2889cf31e3772a47ba97be7fc16..267eb3acddff34037cfd4d5c715e63487389d7c8 100644 (file)
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-from CurveBrowserView import CurveBrowserView
-from PlotManager import PlotManager
-from CurveTabsView import CurveTabsView
-from CurveModel import CurveModel
-from TableModel import TableModel
-from utils import Logger
+from .CurveBrowserView import CurveBrowserView
+from .PlotManager import PlotManager
+from .CurveTabsView import CurveTabsView
+from .CurveModel import CurveModel
+from .TableModel import TableModel
+from .utils import Logger
 import numpy as np
 
 class PlotController(object):
   """ Controller for 2D curve plotting functionalities.
   """
   __UNIQUE_INSTANCE = None  # my poor impl. of a singleton
-  
+
   ## For testing purposes:
   WITH_CURVE_BROWSER = True
   WITH_CURVE_TABS = True
-  
+
   def __init__(self, sgPyQt=None):
     if self.__UNIQUE_INSTANCE is None:
       self.__trueInit(sgPyQt)
@@ -50,32 +50,32 @@ class PlotController(object):
     self._blockNotifications = False
     self._blockViewClosing = False
     self._callbacks = []
-    
+
     self._plotManager = PlotManager(self)
-    
+
     if self.WITH_CURVE_BROWSER:
       self._curveBrowserView = CurveBrowserView(self)
       self.associate(self._plotManager, self._curveBrowserView)
     else:
-      self._curveBrowserView = None  
+      self._curveBrowserView = None
     if self.WITH_CURVE_TABS:
       self._curveTabsView = CurveTabsView(self)
       self.associate(self._plotManager, self._curveTabsView)
     else:
       self._curveTabsView = None
     PlotController.__UNIQUE_INSTANCE = self
-  
+
   @classmethod
   def GetInstance(cls, sgPyQt=None):
     if cls.__UNIQUE_INSTANCE is None:
       # First instanciation:
       PlotController(sgPyQt)
     return cls.__UNIQUE_INSTANCE
-  
+
   @classmethod
   def Destroy(cls):
     cls.__UNIQUE_INSTANCE = None
-  
+
   def setFixedSizeWidget(self):
     """ For testing purposes - ensure visible Qt widgets have a fixed size.
     """
@@ -83,7 +83,7 @@ class PlotController(object):
       self._curveBrowserView.treeWidget.resize(100,200)
     if self.WITH_CURVE_TABS:
       self._sgPyQt._tabWidget.resize(600,600)
-  
+
   def associate(self, model, view):
     """
     Associates a model to a view, and sets the view to listen to this model 
@@ -92,28 +92,28 @@ class PlotController(object):
     :param model: Model -- The model to be associated to the view.
     :param view: View -- The view.
     
-    """    
+    """
     if model is None or view is None:
         return
-  
+
     view.setModel(model)
     self.setModelListener(model, view)
-  
+
   def setModelListener(self, model, view):
     """
     Sets a view to listen to all changes of the given model
     """
     l = self._modelViews.setdefault(model, [])
     if not view in l and view is not None:
-      l.append(view) 
-  
+      l.append(view)
+
   def removeModelListeners(self, model):
     """ 
     Removes the given model from the list of listeners. All views previously connected to this model
     won't receive its update notification anymore.
     """
     self._modelViews.pop(model)
-  
+
   def notify(self, model, what=""):
     """
     Notifies the view when model changes.
@@ -122,10 +122,10 @@ class PlotController(object):
     """
     if model is None or self._blockNotifications:
       return
-    
+
     if model not in self._modelViews:
       return
-    
+
     for view in self._modelViews[model]:
       method = "on%s" % what
       if what != "" and what is not None and hasattr(view, method):
@@ -133,27 +133,27 @@ class PlotController(object):
       elif hasattr(view, "update"):
         # Generic update:
         view.update()
-    
+
   def setBrowserContextualMenu(self, menu):
     """ Provide a menu to be contextually shown in the curve browser """
     self._browserContextualMenu = menu
-    
+
   def setCurvePlotRequestingClose(self, bool):
     self._blockViewClosing = bool
-    
+
   def onCurrentCurveChange(self):
     ps = self._plotManager.getCurrentPlotSet()
     if not ps is None:
       crv = ps.getCurrentCurve()
       if crv is not None:
-        crv_id = crv.getID() 
+        crv_id = crv.getID()
         for c in self._callbacks:
           c(crv_id)
-    
+
   #####
   ##### Public static API
   #####
-  
+
   @classmethod
   def AddCurve(cls, x, y, curve_label="", x_label="", y_label="", append=True):
     """ Add a new curve and make the plot set where it is drawn the active one.
@@ -167,7 +167,7 @@ class PlotController(object):
         @param append whether to add the curve to the active plot set (default) or into a new one.
         @return the id of the created curve, and the id of the corresponding plot set.
     """
-    from XYView import XYView
+    from .XYView import XYView
     control = cls.GetInstance()
     pm = control._plotManager
     t = TableModel(control)
@@ -177,18 +177,18 @@ class PlotController(object):
     prevLock = pm.isRepaintLocked()
     if not prevLock:
       pm.lockRepaint()
-    curveID, plotSetID = control.plotCurveFromTable(t, x_col_index=0, y_col_index=1, 
+    curveID, plotSetID = control.plotCurveFromTable(t, x_col_index=0, y_col_index=1,
                                                     curve_label=curve_label, append=append)
     ps = pm._plotSets[plotSetID]
     if x_label != "":
       ps.setXLabel(x_label)
-    if y_label != "": 
+    if y_label != "":
       ps.setYLabel(y_label)
     if not prevLock:
       pm.unlockRepaint()
     return curveID, plotSetID
 
-  @classmethod  
+  @classmethod
   def ExtendCurve(cls, crv_id, x, y):
     """ Add new points to an already created curve
     @raise if invalid plot set ID is given
@@ -200,7 +200,7 @@ class PlotController(object):
     crv_mod = ps._curves[crv_id]
     data = np.transpose(np.vstack([x, y]))
     crv_mod.extendData(data)
-    
+
   @classmethod
   def ResetCurve(cls, crv_id):
     """ Reset a given curve: all data are cleared, but the curve is still 
@@ -214,7 +214,7 @@ class PlotController(object):
       raise ValueError("Curve ID (%d) not found for reset!" % crv_id)
     crv_mod = ps._curves[crv_id]
     crv_mod.resetData()
-    
+
   @classmethod
   def AddPlotSet(cls, title=""):
     """ Creates a new plot set (a tab with several curves) and returns its ID. A title can be passed,
@@ -229,7 +229,7 @@ class PlotController(object):
     if title != "":
       ps.setTitle(title)
     return ps.getID()
-            
+
   @classmethod
   def CopyCurve(cls, curve_id, plot_set_id):
     """ Copy a given curve to a given plot set ID
@@ -248,7 +248,7 @@ class PlotController(object):
     control.setModelListener(new_crv, control._curveBrowserView)
     plot_set_tgt.addCurve(new_crv)
     return new_crv.getID()
-      
+
   @classmethod
   def DeleteCurve(cls, curve_id=-1):
     """ By default, delete the current curve, if any. Otherwise do nothing.
@@ -261,8 +261,8 @@ class PlotController(object):
       curve_id = cls.GetCurrentCurveID()
       if curve_id == -1:
         # No current curve, do nothing
-        return -1 
-      
+        return -1
+
     psID = cls.GetPlotSetID(curve_id)
     if psID == -1:
       raise ValueError("Curve ID (%d) not found for deletion!" % curve_id)
@@ -270,7 +270,7 @@ class PlotController(object):
     control._plotManager._plotSets[psID].removeCurve(curve_id)
     control.removeModelListeners(crv)
     return curve_id
-  
+
   @classmethod
   def DeletePlotSet(cls, plot_set_id=-1):
     """ By default, delete the current plot set, if any. Otherwise do nothing.
@@ -290,11 +290,11 @@ class PlotController(object):
     for _, crv in list(ps._curves.items()):
       control.removeModelListeners(crv)
     control.removeModelListeners(ps)
-    psets = control._plotManager._plotSets 
+    psets = control._plotManager._plotSets
     if len(psets):
       control._plotManager.setCurrentPlotSet(list(psets.keys())[-1])
     return plot_set_id
-  
+
   @classmethod
   def usedMem(cls):
       import gc
@@ -302,7 +302,7 @@ class PlotController(object):
       import resource
       m = resource.getrusage(resource.RUSAGE_SELF)[2]*resource.getpagesize()/1e6
       print("** Used memory: %.2f Mb" % m)
-  
+
   @classmethod
   def DeleteCurrentItem(cls):
     """ Delete currently active item, be it a plot set or a curve.
@@ -315,7 +315,7 @@ class PlotController(object):
     if ps_id == -1:
       Logger.Info("PlotController.DeleteCurrentItem(): nothing selected, nothing to delete!")
       return True,-1
-    # Do we delete a curve or a full plot set    
+    # Do we delete a curve or a full plot set
     if c_id == -1:
       cls.DeletePlotSet(ps_id)
       ret = True, ps_id
@@ -323,7 +323,7 @@ class PlotController(object):
       cls.DeleteCurve(c_id)
       ret = False, c_id
     return ret
-  
+
   @classmethod
   def ClearPlotSet(cls, ps_id=-1):
     """ Clear all curves in a given plot set. By default clear the current plot set without deleting it,
@@ -341,7 +341,7 @@ class PlotController(object):
       raise ValueError("Invalid plot set ID (%d)!" % ps_id)
     ps.eraseAll()
     return ps_id
-  
+
 #   @classmethod
 #   def ClearAll(cls):
 #     # TODO: optimize
@@ -349,7 +349,7 @@ class PlotController(object):
 #     ids = pm._plotSets.keys()
 #     for i in ids:
 #       cls.DeletePlotSet(i)
-  
+
   @classmethod
   def SetXLabel(cls, x_label, plot_set_id=-1):
     """  By default set the X axis label for the current plot set, if any. Otherwise do nothing.
@@ -360,14 +360,14 @@ class PlotController(object):
       plot_set_id = cls.GetCurrentPlotSetID()
       if plot_set_id == -1:
         # Do nothing
-        return False 
+        return False
     ps = pm._plotSets.get(plot_set_id, None)
     if ps is None:
       raise Exception("Invalid plot set ID (%d)!" % plot_set_id)
     ps.setXLabel(x_label)
     return True
-     
-  @classmethod 
+
+  @classmethod
   def SetYLabel(cls, y_label, plot_set_id=-1):
     """ By default set the Y axis label for the current plot set, if any. Otherwise do nothing.
          @return True if the label was set
@@ -377,14 +377,14 @@ class PlotController(object):
       plot_set_id = cls.GetCurrentPlotSetID()
       if plot_set_id == -1:
         # Do nothing
-        return False 
+        return False
     ps = pm._plotSets.get(plot_set_id, None)
     if ps is None:
       raise Exception("Invalid plot set ID (%d)!" % plot_set_id)
     ps.setYLabel(y_label)
     return True
-     
-  @classmethod 
+
+  @classmethod
   def SetPlotSetTitle(cls, title, plot_set_id=-1):
     """ By default set the title for the current plot set, if any. Otherwise do nothing.
          @return True if the title was set
@@ -394,13 +394,13 @@ class PlotController(object):
       plot_set_id = cls.GetCurrentPlotSetID()
       if plot_set_id == -1:
         # Do nothing
-        return False 
+        return False
     ps = pm._plotSets.get(plot_set_id, None)
     if ps is None:
       raise Exception("Invalid plot set ID (%d)!" % plot_set_id)
     ps.setTitle(title)
     return True
-  
+
   @classmethod
   def GetPlotSetID(cls, curve_id):
     """ @return plot set id for a given curve or -1 if invalid curve ID
@@ -410,17 +410,17 @@ class PlotController(object):
     if cps is None:
       return -1
     return cps.getID()
-  
+
   @classmethod
   def GetPlotSetIDByName(cls, name):
     """ @return the first plot set whose name matches the provided name. Otherwise returns -1
-    """ 
+    """
     pm = cls.GetInstance()._plotManager
     for _, ps in list(pm._plotSets.items()):
       if ps._title == name:
         return ps.getID()
     return -1
-  
+
   @classmethod
   def GetAllPlotSets(cls):
     """ @return two lists: plot set names, and corresponding plot set IDs
@@ -428,12 +428,12 @@ class PlotController(object):
     pm = cls.GetInstance()._plotManager
     it = list(pm._plotSets.items())
     ids, inst, titles = [], [], []
-    if len(it):  
-      ids, inst = list(zip(*it))        
+    if len(it):
+      ids, inst = list(zip(*it))
     if len(inst):
       titles = [i.getTitle() for i in inst]
     return list(ids), titles
-  
+
   @classmethod
   def GetCurrentCurveID(cls):
     """ @return current curve ID or -1 if no curve is currently active
@@ -443,8 +443,8 @@ class PlotController(object):
     if crv is None:
       return -1
     return crv.getID()
-     
-  @classmethod   
+
+  @classmethod
   def GetCurrentPlotSetID(cls):
     """ @return current plot set ID or -1 if no plot set is currently active
     """
@@ -452,7 +452,7 @@ class PlotController(object):
     cps = control._plotManager.getCurrentPlotSet()
     if cps is None:
       return -1
-    return cps.getID()  
+    return cps.getID()
 
   @classmethod
   def SetCurrentPlotSet(cls, ps_id):
@@ -489,7 +489,7 @@ class PlotController(object):
     if cls.__UNIQUE_INSTANCE is not None:
       raise Exception("ToggleCurveBrowser() must be invoked before doing anything in plot2D!")
     cls.WITH_CURVE_BROWSER = active
-    
+
   @classmethod
   def IsValidPlotSetID(cls, plot_set_id):
     """ 
@@ -548,11 +548,11 @@ class PlotController(object):
                    ]
     @raise if invalid curve ID or marker
     """
-    from XYView import XYView
-    from CurveView import CurveView
+    from .XYView import XYView
+    from .CurveView import CurveView
     if not marker in XYView.CURVE_MARKERS:
       raise ValueError("Invalid marker: '%s'" % marker)
-    
+
     cont = cls.GetInstance()
     for mod, views in list(cont._modelViews.items()):
       if isinstance(mod, CurveModel) and mod.getID() == crv_id:
@@ -563,7 +563,7 @@ class PlotController(object):
             v._parentXYView.repaint()
             v._parentXYView.showHideLegend()
             found = True
-        
+
     if not found:
       raise Exception("Invalid curve ID or curve currently not displayed (curve_id=%d)!" % crv_id)
 
@@ -581,9 +581,9 @@ class PlotController(object):
   @classmethod
   def __XYViewOperation(cls, func, ps_id, args, kwargs):
     """ Private. To factorize methods accessing the XYView to change a display element. """
-    from XYPlotSetModel import XYPlotSetModel
-    from XYView import XYView
-    
+    from .XYPlotSetModel import XYPlotSetModel
+    from .XYView import XYView
+
     cont = cls.GetInstance()
     for mod, views in list(cont._modelViews.items()):
       if isinstance(mod, XYPlotSetModel) and mod.getID() == ps_id:
@@ -614,7 +614,7 @@ class PlotController(object):
     """
     args, kwargs = [log], {}
     cls.__XYViewOperation("setYLog", ps_id, args, kwargs)
-     
+
   @classmethod
   def SetXSciNotation(cls, ps_id, sciNotation=False):
     """ Change the format (scientific notation or not) of the X axis.
@@ -624,7 +624,7 @@ class PlotController(object):
     """
     args, kwargs = [sciNotation], {}
     cls.__XYViewOperation("setXSciNotation", ps_id, args, kwargs)
-   
+
   @classmethod
   def SetYSciNotation(cls, ps_id, sciNotation=False):
     """ Change the format (scientific notation or not) of the Y axis.
@@ -644,7 +644,7 @@ class PlotController(object):
     """
     args, kwargs = [visible], {}
     cls.__XYViewOperation("setLegendVisible", ps_id, args, kwargs)
-    
+
 
   ###
   ### More advanced functions
@@ -653,28 +653,28 @@ class PlotController(object):
   def RegisterCallback(cls, callback):
     cont = cls.GetInstance()
     cont._callbacks.append(callback)
-  
+
   @classmethod
   def ClearCallbacks(cls):
     cont = cls.GetInstance()
     cont._callbacks = []
-  
+
   @classmethod
   def LockRepaint(cls):
     control = cls.GetInstance()
     control._plotManager.lockRepaint()
-  
+
   @classmethod
   def UnlockRepaint(cls):
     control = cls.GetInstance()
-    control._plotManager.unlockRepaint()  
-  
+    control._plotManager.unlockRepaint()
+
   def createTable(self, data, table_name="table"):
     t = TableModel(self)
     t.setData(data)
     t.setTitle(table_name)
     return t
-     
+
   def plotCurveFromTable(self, table, x_col_index=0, y_col_index=1, curve_label="", append=True):
     """
     :returns: a tuple containing the unique curve ID and the plot set ID 
@@ -690,15 +690,15 @@ class PlotController(object):
       cps_title = None
 
     cps = self._plotManager.getCurrentPlotSet()
-    
+
     cm = CurveModel(self, table, y_col_index)
     cm.setXAxisIndex(x_col_index)
-    
+
     # X axis label
     tix = table.getColumnTitle(x_col_index)
     if tix != "":
       cps.setXLabel(tix)
-    
+
     # Curve label
     if curve_label != "":
       cm.setTitle(curve_label)
@@ -709,21 +709,21 @@ class PlotController(object):
 
     # Plot set title
     if cps_title != "" and cps_title is not None:
-      Logger.Debug("about to set title to: " + cps_title)  
+      Logger.Debug("about to set title to: " + cps_title)
       cps.setTitle(cps_title)
-    
+
     cps.addCurve(cm)
     mp = self._curveTabsView.mapModId2ViewId()
     xyview_id = mp[cps.getID()]
     xyview = self._curveTabsView._XYViews[xyview_id]
-    
+
     if cps_title is None:  # no plot set was created above
       self._plotManager.setCurrentPlotSet(cps.getID())
-      
+
     # Make CurveBrowser and CurveView depend on changes in the curve itself:
     self.setModelListener(cm, self._curveBrowserView)
     self.setModelListener(cm, xyview._curveViews[cm.getID()])
     # Upon change on the curve also update the full plot, notably for the auto-fit and the legend:
     self.setModelListener(cm, xyview)
-        
+
     return cm.getID(),cps.getID()
index 7c79ebaf38c92847d95823b2685349dc36e50e99..611ba7ff8a01d64a69108773f64de402308180f4 100644 (file)
@@ -25,19 +25,19 @@ try:
   # and the Bitstream font which is the first one by default. Try to use DejaVu which is more 
   # comprehensive.
   ## !!Order of the sequence below is highly sensitive!!
-  import pyqtside   # will trigger the PySide/PyQt4 switch
+  import pyqtside   # will trigger the PySide/PyQt switch
   import matplotlib
-  matplotlib.use('Qt4Agg')
-  import matplotlib.pyplot as plt  # must come after the PySide/PyQt4 switch!
+  matplotlib.use('Qt5Agg')
+  import matplotlib.pyplot as plt  # must come after the PySide/PyQt switch!
   plt.rcParams['font.sans-serif'].insert(0, "DejaVu Sans")
 except:
-  print("Warning: could not switch matplotlib to 'Qt4agg' backend. Some characters might be displayed improperly!")
+  print("Warning: could not switch matplotlib to 'Qt5agg' backend. Some characters might be displayed improperly!")
 
 from .PlotController import PlotController
-from TableModel import TableModel
-from CurveModel import CurveModel
-from PlotManager import PlotManager
-from XYPlotSetModel import XYPlotSetModel
+from .TableModel import TableModel
+from .CurveModel import CurveModel
+from .PlotManager import PlotManager
+from .XYPlotSetModel import XYPlotSetModel
 
 ## The static API of PlotController is the main interface of the package and is hence exposed at package level:
 AddCurve = PlotController.AddCurve
index e2f0d27788947837fc068b6dd578294024c7f51f..f70feed06e90d3de4175c83713faa37656c49a25 100644 (file)
@@ -78,20 +78,20 @@ class Logger(object):
       
 def trQ(tag, context="CURVEPLOT"):
   """ @return a QString read from the translation file """
-  from pyqtside.QtGui import QApplication 
+  from pyqtside.QtWidgets import QApplication 
   return QApplication.translate(context, tag) 
 
 def trU(tag, context="CURVEPLOT"):
   """ @return same as above, but returns a Python unicode string.  """
   qs = trQ(tag, context)
-  return unicode(qs, 'utf-8')
+  return str(qs, 'utf-8')
 
 def toUnicodeWithWarning(s, method_name):
   try: 
-    s = unicode(s)
+    s = str(s)
   except:
     Logger.Warning("%s - warning, passing non-unicode, non-ASCII string '%s'! Trying to convert myself to UTF-8 ..." % (method_name, s))
-    s = unicode(s, 'utf-8')
+    s = str(s, 'utf-8')
   return s
 
 def completeResPath(fileName):
@@ -100,5 +100,7 @@ def completeResPath(fileName):
   rd = os.environ.get("CURVEPLOT_ROOT_DIR", None)
   if rd is None:
     raise Exception("CURVEPLOT_ROOT_DIR is not defined!")
+  if @SALOME_CURVEPLOT_TEST_MODE@:   # do not remove automatically modified in CMake config
+    subPath = "@CRVPLOT_TEST_INSTALL@"
   filePath = os.path.join(rd, subPath, fileName)
   return filePath
index 4ebc34f0a5e4fdb597b4305c0fc94d0c07381c88..7101e91aa3a559d2cfe70e0584c20f38b838699a 100644 (file)
@@ -24,5 +24,8 @@ SET(_all_lib_SCRIPTS
     PlotManager.py
     XYPlotSetModel.py
 )
-    
+
 SALOME_INSTALL_SCRIPTS("${_all_lib_SCRIPTS}" ${SALOME_CURVEPLOT_INSTALL_PYTHON})
+
+# For test purposes
+FILE(COPY ${_all_lib_SCRIPTS} DESTINATION ${CRVPLOT_TEST_INSTALL})
index ce39144a0a904a04a4b5d77d284be530ce2093a7..73b2bdf5ae4f8df63f4a8f2f4fde9ae71274976d 100644 (file)
@@ -17,8 +17,8 @@
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-from Model import Model
-from utils import toUnicodeWithWarning
+from .Model import Model
+from .utils import toUnicodeWithWarning
 
 class CurveModel(Model):  
   def __init__(self, controller, table=None, index=-1):
index 5d8187976b9fdc8d238c8bfdcf45568390d708ae..5bf00384d761dccb079ce5d3478afe5daacfd818 100644 (file)
@@ -17,9 +17,9 @@
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-from Model import Model
-from XYPlotSetModel import XYPlotSetModel
-from utils import Logger
+from .Model import Model
+from .XYPlotSetModel import XYPlotSetModel
+from .utils import Logger
 
 class PlotManager(Model):
   def __init__(self, controller):
@@ -30,52 +30,52 @@ class PlotManager(Model):
                                       # when removing elemetns, we can easily re-select the last-but-one.
     self._lockRepaint = False  # if True, repaint routines are blocked.
     self._plotSetsRepaint = set() # plot waiting for repaint/update while repaint is locked
-  
+
   def isEmpty(self):
     return len(self._plotSets) == 0
-  
+
   def setCurrentPlotSet(self, plotSetID, silent=False):
     if plotSetID not in self._plotSets and plotSetID != -1:
       raise ValueError("Invalid plot set ID (%d)!" % plotSetID)
     self._currentPlotSet = self._plotSets.get(plotSetID, None)
     if not silent:
-      self.notifyChange("CurrentPlotSetChange") 
-  
+      self.notifyChange("CurrentPlotSetChange")
+
   def getCurrentPlotSet(self):
     return self._currentPlotSet
-  
+
   def getPlotSetContainingCurve(self, curveID):
     for ps in list(self._plotSets.values()):
       if curveID in ps._curves:
         return ps
     return None
-  
+
   def setCurrentCurve(self, curveId):
     ps = self.getPlotSetContainingCurve(curveId)
     if ps is None and curveId != -1:
       raise ValueError("Invalid curve ID (%d)!" % curveId)
     self.clearAllCurrentCurve()
-    if curveId == -1:      
+    if curveId == -1:
       return -1
     ps_id = ps.getID()
     currPs = self.getCurrentPlotSet()
-    if currPs is None or currPs.getID() != ps_id: 
+    if currPs is None or currPs.getID() != ps_id:
       self.setCurrentPlotSet(ps_id)
     ps.setCurrentCurve(curveId)
     return ps_id
-  
+
   def getCurrentCurve(self):
     ps = self.getCurrentPlotSet()
     if ps is None:
       return None
     return ps.getCurrentCurve()
-  
+
   def clearAllCurrentCurve(self, silent=False):
     for psID in self._plotSets:
       self._plotSets[psID].setCurrentCurve(-1)
     if not silent:
       self.notifyChange("CurrentCurveChange")
-  
+
   def createXYPlotSet(self, silent=False):
     cv = XYPlotSetModel(self._controller)
     self._plotSets[cv.getID()] = cv
@@ -83,7 +83,7 @@ class PlotManager(Model):
     if not silent:
       self.notifyChange("NewPlotSet")
     return cv
-  
+
   def removeXYPlotSet(self, plotSetID):
     Logger.Debug("====> PlotManager::removeXYPlotSet() %d" % plotSetID)
     if plotSetID not in self._plotSets:
@@ -94,25 +94,25 @@ class PlotManager(Model):
       self._currentPlotSet = None
     self.notifyChange("RemovePlotSet")
     return ps
-  
+
   def clearAll(self):
     self._plotSets = {}
     self._currentPlotSet = None
     self.notifyChange("ClearAll")
-    
+
   def lockRepaint(self):
     self._lockRepaint = True
     self._plotSetsRepaint = set()
-    
+
   def isRepaintLocked(self):
     return self._lockRepaint
-  
+
   def registerRepaint(self, ps_id):
     self._plotSetsRepaint.add(ps_id)
-    
+
   def unlockRepaint(self):
     self._lockRepaint = False
     for obj in self._plotSetsRepaint:
       obj.notifyChange()
     self._plotSetsRepaint = set()
-    
\ No newline at end of file
+
index 4f9f48cd526b3ed346a4681f2ee61195cdd4376e..8b371b35238db826a95e8e2c25e5d359476f5d9d 100644 (file)
@@ -18,8 +18,8 @@
 #
 
 import numpy as np
-from Model import Model
-from utils import toUnicodeWithWarning, Logger
+from .Model import Model
+from .utils import toUnicodeWithWarning, Logger
 
 class TableModel(Model):
   def __init__(self, controller):
index dc39ff02681c95749799a78660a6613548c18c8e..e079758bc235a113c3d774b4c0a012523581298d 100644 (file)
@@ -17,8 +17,8 @@
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-from Model import Model
-from utils import toUnicodeWithWarning
+from .Model import Model
+from .utils import toUnicodeWithWarning
 
 class XYPlotSetModel(Model):
   
index 2879ed22ca0c8c9ab35b434d1dbff7f45b6f4bcc..3964034b7229b2f5cd4101254f9f944c7fcabfc8 100644 (file)
@@ -21,8 +21,12 @@ SET(_pyqtside_SCRIPTS
     __init__.py
     QtCore.py
     QtGui.py
+    QtWidgets.py
     pyside_dynamic.py
     uic.py
 )
 
 SALOME_INSTALL_SCRIPTS("${_pyqtside_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/pyqtside)
+
+# For test purposes
+FILE(COPY ${_pyqtside_SCRIPTS} DESTINATION ${PYQTSIDE_TEST_INSTALL})
index ccfe52c2c0a7a73c1f32ae5c70dddfbe2aa7d61e..fbd5e29f25cc8d8e942656be298b55d186173601 100644 (file)
@@ -19,8 +19,8 @@
 
 from . import _use_pyqt
 if _use_pyqt:
-  from PyQt4.QtCore import *
-  Slot = pyqtSlot  
-  Signal = pyqtSignal 
+  from PyQt5.QtCore import *
+  Slot = pyqtSlot
+  Signal = pyqtSignal
 else:
   from PySide.QtCore import *
index 266a839039c24f42e8d052cfa0e55831e7a8732e..0abe36df8c11308514c04c0b8b854afb32465782 100644 (file)
 
 from . import _use_pyqt
 if _use_pyqt:
-  from PyQt4.QtGui import *
-  
-  # Make QVariant invisible in PyQt4 since they don't exist in
+  from PyQt5.QtGui import *
+
+  # Make QVariant invisible in PyQt5 since they don't exist in
   # PySide ...
-  __original_itemData = QComboBox.itemData
-  def new_itemData(*args, **kargs):
-    from PyQt4.QtCore import QVariant
-    variant = __original_itemData(*args, **kargs)
-    funcS = lambda : (str(variant.toString()), True)
-    dico = {QVariant.Int: variant.toInt, QVariant.String: funcS,
-     QVariant.Bool: variant.toBool, QVariant.Double: variant.toDouble}
-    conv = dico.get(variant.type(), None)
-    if conv is None:
-      raise Exception("Unsupported variant type in pyqtside: '%s'!" % variant.typeName())
-    return conv()[0]
-  
-  QComboBox.itemData = new_itemData 
+#  __original_itemData = QComboBox.itemData
+#  def new_itemData(*args, **kargs):
+#    from PyQt5.QtCore import QVariant
+#    variant = __original_itemData(*args, **kargs)
+#    funcS = lambda : (str(variant.toString()), True)
+#    dico = {QVariant.Int: variant.toInt, QVariant.String: funcS,
+#     QVariant.Bool: variant.toBool, QVariant.Double: variant.toDouble}
+#    conv = dico.get(variant.type(), None)
+#    if conv is None:
+#      raise Exception("Unsupported variant type in pyqtside: '%s'!" % variant.typeName())
+#    return conv()[0]
+#
+#  QComboBox.itemData = new_itemData 
 else:
   from PySide.QtGui import *
-  
+
   __original_ofn = QFileDialog.getOpenFileName
   __original_sfn = QFileDialog.getSaveFileName
-  
-  # In PySide, getOpenFileName and co returns 2 values, and only one in PyQt4 ...
+
+  # In PySide, getOpenFileName and co returns 2 values, and only one in PyQt ...
   def newOfn(cls,*args, **kargs):
     tup = __original_ofn(*args, **kargs)
     return tup[0]
-    
+
   def newSfn(cls,*args, **kargs):
     tup = __original_sfn(*args, **kargs)
     return tup[0]
-    
+
   QFileDialog.getOpenFileName = classmethod(newOfn)
   QFileDialog.getSaveFileName = classmethod(newSfn)
 
diff --git a/tools/CurvePlot/src/python/pyqtside/QtWidgets.py b/tools/CurvePlot/src/python/pyqtside/QtWidgets.py
new file mode 100644 (file)
index 0000000..dd00a92
--- /dev/null
@@ -0,0 +1,5 @@
+from . import _use_pyqt
+if _use_pyqt:
+  from PyQt5.QtWidgets import *
+else:
+  from PySide.QtWidgets import *
index d4f988fa7a96755d346fc5a6a40f4ee4331efc81..4ab1737f108cfc870c015bc83aa25bfa4bfdbb42 100644 (file)
 #
 
 """
-Group under one hat PySide and PyQt4. PyQt4 is tried first.
+Group under one hat PySide and PyQt5. PyQt5 is tried first.
 """
 
 try:
   import os
   if os.getenv("CURVEPLOT_FORCE_PYSIDE") is not None:
     raise Exception
-  import PyQt4
+  import PyQt5
   _use_pyqt = True
-  print("Using PyQt4 run-time ...")
+  print("Using PyQt5 run-time ...")
 except:
   try:
     import PySide
     _use_pyqt = False
     print("Using PySide run-time ...")
   except:
-    raise Exception("Neither PyQt4 nor PySide could be imported!")
+    raise Exception("Neither PyQt5 nor PySide could be imported!")
 
 # Matplotlib has to be handled very early, otherwise it will switch to whatever it
 # finds first on the machine
 try: 
   import matplotlib
-  if _use_pyqt:  back = 'PyQt4'
+  if _use_pyqt:  back = 'PyQt5'
   else:          back = 'PySide'
-  matplotlib.rcParams['backend.qt4'] = back
+  # As advised by MatPlotlib:
+  #   "The backend.qt5 rcParam was deprecated in version 2.2.  In order to force the use of a specific Qt binding, either import that binding first, or set the QT_API environment variable.
+  #   mplDeprecation)"
+  from matplotlib.backends import backend_qt5agg
   print("Matplotlib found - Set matplotlib backend to '%s'!" % back) 
 except:
   # No matplotlib, silently discard err message.
index a3ab6046d95d1c1e3c3fac9527d6b2c0fac93dbc..38a82e3b680c81911141883a3be47c5915ac650e 100644 (file)
@@ -14,7 +14,7 @@ class UiLoader(QUiLoader):
     create a new instance of the top-level widget, but creates the user
     interface in an existing instance of the top-level class.
 
-    This mimics the behaviour of :func:`PyQt4.uic.loadUi`.
+    This mimics the behaviour of :func:`PyQt5.uic.loadUi`.
     """
     def __init__(self, baseinstance, customWidgets=None):
         """
index 44ac1b74451d6b6e121bdae3f2c990c0802015e4..b37ffa493ff94bd0a6055eaf540f8fd6f1dc4f7a 100644 (file)
@@ -19,8 +19,8 @@
 
 from . import _use_pyqt
 if _use_pyqt:
-  from PyQt4.uic import loadUi as loadUiGen
-else: 
+  from PyQt5.uic import loadUi as loadUiGen
+else:
   from .pyside_dynamic import loadUi as loadUiGen
 
 
index 88afa57c2455fe4711fe568e8acb78285012314e..6d5e1319497cbb303957d8a4a695a5451118a0d3 100644 (file)
@@ -26,20 +26,23 @@ SET(_all_SCRIPTS
     TestDesktop.py
 )
 
+SET(_test_SCRIPTS
+    ${CMAKE_CURRENT_BINARY_DIR}/mockup/SalomePyQt_MockUp.py
+    PlotTestBase.py
+    TestDesktop.py
+)
+
 SALOME_INSTALL_SCRIPTS("${_all_SCRIPTS}" ${SALOME_INSTALL_SCRIPT_PYTHON}/tests)
 SALOME_INSTALL_SCRIPTS(${CMAKE_CURRENT_BINARY_DIR}/mockup/SalomePyQt_MockUp.py ${SALOME_INSTALL_SCRIPT_PYTHON}/tests)
 
 INSTALL(DIRECTORY baselines DESTINATION ${SALOME_INSTALL_SCRIPT_PYTHON}/tests)
 
-SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH ${CMAKE_CURRENT_SOURCE_DIR}/../model)
-SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH ${CMAKE_CURRENT_SOURCE_DIR}/../ui)
-SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH ${CMAKE_CURRENT_SOURCE_DIR}/../views)
-SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH ${CMAKE_CURRENT_SOURCE_DIR}/../controller)
-SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH ${CMAKE_CURRENT_SOURCE_DIR}/..)
-SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH ${PROJECT_BINARY_DIR}/src/python/ui)  # for the generated PY files (from UI files)
-SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH ${PROJECT_BINARY_DIR}/src/python/controller)  # for utils.py
+SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH ${CMAKE_BINARY_DIR}/local)  # point to local curveplot package in BUILD dir
 SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env)
 
 ADD_TEST(CurvePlotUnitTests ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/plot_test.py)
 SET_TESTS_PROPERTIES(CurvePlotUnitTests PROPERTIES ENVIRONMENT "${tests_env}")
 
+# For test purposes
+FILE(COPY ${_test_SCRIPTS} DESTINATION ${CRVPLOT_TEST_INSTALL})
+FILE(COPY baselines DESTINATION ${CRVPLOT_TEST_INSTALL})
index 92b3e1e0668d3bb0cf55d47689385be39bd1b096..1b57e801727342b12e9a2b8f065f7de9137a2c23 100755 (executable)
@@ -22,8 +22,8 @@
 #
 # Author : A. Bruneton
 #
-from pyqtside.QtGui import QApplication 
-from pyqtside.QtCore import SIGNAL, SLOT, QTimer, QTranslator
+from pyqtside.QtWidgets import QApplication
+from pyqtside.QtCore import QTimer, QTranslator
 
 from TestDesktop import TestDesktop
 import SalomePyQt_MockUp
@@ -43,31 +43,23 @@ def activeViewChanged( viewID ):
 
 def main(args) :
     global desktop
-      
+
     app = QApplication(args)
-    ts_files = ["/export/home/adrien/Projets/salome/modules/V7_main/CURVEPLOT_INSTALL/share/salome/resources/curveplot/CURVEPLOT_msg_fr.qm",
-                "/export/home/adrien/Projets/salome/modules/V7_main/CURVEPLOT_INSTALL/share/salome/resources/curveplot/CURVEPLOT_msg_en.qm"
-                ]
-    trans = QTranslator()
-    for f in ts_files:
-      if not trans.load(f):
-        print("could not load translation %s!" % f)
-    app.installTranslator(trans)
     dw = app.desktop()
     x, y = dw.width()*0.25, dw.height()*0.7
-    
+
     desktop = TestDesktop(None)
     sgPyQt = SalomePyQt_MockUp.SalomePyQt(desktop)
     sgPyQt.currentTabChanged.connect(activeViewChanged)
-    desktop._sgPyQt = sgPyQt 
+    desktop._sgPyQt = sgPyQt
     desktop.initialize()
     desktop.resize(x,y)
     desktop.show()
     activate()
     #
-    QTimer.singleShot(200, desktop, SLOT("curveSameFig()"))
+    QTimer.singleShot(200, desktop.curveSameFig)
     #
-    app.connect(app,SIGNAL("lastWindowClosed()"),app,SLOT("quit()"))
+    app.lastWindowClosed.connect(app.quit)
     app.exec_()
 
 if __name__ == "__main__" :
index d93f0a673fcb449e1405cfcdd267c4500954df4b..232e7b6bf495b117a35bd5ddfce7dea3bf096ff3 100644 (file)
 # Author : A. Bruneton
 #
 import unittest, sys, os, filecmp, shutil, tempfile
-from pyqtside.QtGui import QApplication, QPixmap, QPainter
-from PlotController import PlotController
-from XYView import XYView
+from pyqtside.QtWidgets import QApplication
+from pyqtside.QtGui import QPixmap, QPainter
+from pyqtside.QtCore import QTimer
+
+from curveplot.PlotController import PlotController
+from curveplot.XYView import XYView
+from PyQt5.Qt import QMainWindow
 
 def runOnly(func):
   func.__runOnly__ = True
@@ -51,7 +55,7 @@ def processDecorator(mod_name):
           # Note the "not":
           if p.startswith("test") and not hasattr(obj.__dict__[p], "__runOnly__"):
             delattr(obj, p)
+
 class PlotTestBase(unittest.TestCase):
   """ Unit test suite for the curve plotter. This class deals with the set up and the screenshot generation/
   comparison. The tests themselves are stored in the derived class PlotTest below.
@@ -61,31 +65,30 @@ class PlotTestBase(unittest.TestCase):
   The baselines directory is set relative to the path of this script.
   """
   REBUILD_BASELINES = False
-  
+
   __BASE_LINE_DIR = "baselines"
   __FORMAT = "png"
-  
+
   def __init__(self, methodName):
     unittest.TestCase.__init__(self, methodName)
-     
+
     if self.REBUILD_BASELINES:
       self.tmpBaselineDir = os.path.join(tempfile.gettempdir(), "curveplot_baselines")
       if not os.path.isdir(self.tmpBaselineDir):
         os.mkdir(self.tmpBaselineDir)
       print("### Rebuilding base lines. Reference files will be saved to '%s'" % self.tmpBaselineDir)
-       
+
     PlotController.WITH_CURVE_BROWSER = True
     XYView._DEFAULT_LEGEND_STATE = True   # always show legend by default
     self._this_dir = os.path.dirname(os.path.realpath(__file__))
-    
-#     import matplotlib as mpl
-#     mpl.use('Agg')
-  
+
   def setUp(self):
-    from SalomePyQt_MockUp import SalomePyQt
-    from TableModel import TableModel
-    from CurveModel import CurveModel
-    from XYPlotSetModel import XYPlotSetModel
+    import sys
+    from curveplot.SalomePyQt_MockUp import SalomePyQt
+    from curveplot.TableModel import TableModel
+    from curveplot.CurveModel import CurveModel
+    from curveplot.XYPlotSetModel import XYPlotSetModel
+    from curveplot.TestDesktop import TestDesktop
 
     self.qpixmap = None
     self.keepDir = False
@@ -93,21 +96,30 @@ class PlotTestBase(unittest.TestCase):
       self.tmpDir = tempfile.mkdtemp(prefix="curveplot_tests")
     else:
       self.tmpDir = None
+
     # Minimal UI setup:
-    self.sgPyQt = SalomePyQt()
-    # Reinstanciate from scratch the PlotController:
+    self.app = QApplication(sys.argv)
+    desktop = TestDesktop(None)
+    self.sgPyQt = SalomePyQt(desktop)
+    desktop._sgPyQt = self.sgPyQt
+    desktop.initialize()
     self.plotController = PlotController.GetInstance(self.sgPyQt)
-    self.plotController.setFixedSizeWidget()
+    desktop.resize(800, 600)
+    desktop.show()
+    self._execQtWasCalled = False # Used to automatically finish Qt execution loop on tests not doing a screenshot
+
     # Reset some class var to make sure IDs appearing in screenshots do not depend on test seq order:
     CurveModel.START_ID = -1
     TableModel.START_ID = -1
     XYPlotSetModel.START_ID = -1
-        
+
   def tearDown(self):
     if not self.REBUILD_BASELINES:
       # Clean up temp dir where the file comparison has been made:
       if not self.keepDir:
         shutil.rmtree(self.tmpDir, False)
+    if not self._execQtWasCalled:
+      self._execQt(withShot=False)
     PlotController.Destroy()
 
   def getTestName(self):
@@ -118,7 +130,29 @@ class PlotTestBase(unittest.TestCase):
     self.qpixmap.save(fileName, self.__FORMAT)
     return fileName
 
-  def areScreenshotEqual(self, widget, suffix=""):
+  def _execQt(self, withShot=False):
+    if withShot:
+      QTimer.singleShot(50, self._shotEvent)  # take picture
+    QTimer.singleShot(200, self.app.quit)    # quit
+    self.app.exec_()  # will hang till quit is fired
+
+    # Important make sure previous app is properly killed before launching next test!
+    # Qt doesn't like multiple running instance
+    import gc
+    gc.collect()
+
+  def areScreenshotEqual(self, widget):
+    """ Finish the launching of the Qt application so that the widgets and the curve have a chance to display
+     and trigger snapshot comparison """
+    self.saveW = widget
+    self._execQtWasCalled = True
+    self._execQt(withShot=True)
+    return self.retValue
+
+  def _shotEvent(self):
+    self.retValue = self._snapAndCompare(self.saveW)
+
+  def _snapAndCompare(self, widget, suffix=""):
     """ Test equality between a reference file saved in the baseline directory, and whose name is built as
           "<test_name><suffix>.png"
         and the file generated on the fly by taking a snapshot of the widget provided in argument.
@@ -126,13 +160,16 @@ class PlotTestBase(unittest.TestCase):
     """
     import glob
     # Smiiiile :-)
-    self.qpixmap = QPixmap.grabWidget(widget)
-    
+    self.qpixmap = QPixmap(widget.size())
+    widget.repaint()
+    widget.render(self.qpixmap)
+    #self.qpixmap = widget.grab()
+
     # Nothing to compare if rebuilding base lines, just saving file:
     if self.REBUILD_BASELINES:
       self.saveCurrentPix(self.tmpBaselineDir, suffix)
       return True
-    
+
     gen_path = self.saveCurrentPix(self.tmpDir, suffix)
     base_ref = os.path.join(self._this_dir, self.__BASE_LINE_DIR, self.getTestName() + suffix)
     ret = False
@@ -147,13 +184,13 @@ class PlotTestBase(unittest.TestCase):
       # Keep file if assert is false
       self.keepDir = True
       print("[%s] -- Failed screenshot equality, or unable to open baseline file - directory is kept alive: %s" % (self.getTestName(), self.tmpDir))
-    return ret 
-  
+    return ret
+
   def showTabWidget(self):
     tabW = self.plotController._sgPyQt._tabWidget
     # No simpler way found so far:
     tabW.show()
     return tabW
-    
+
   def getBrowserWidget(self):
     return self.plotController._curveBrowserView._treeWidget
index bdb40251fb72bf99c069d41ba3b0afeae4cb472d..cbc22eaf7921f90ace4cd3a14deaee8680e7609b 100644 (file)
@@ -1,4 +1,12 @@
-Unit tests are in plot_test.py
+Unit tests are in plot_test.py.
+
+They should be run: 
+    - without any install of CurvePlot, to be sure there is no conflict
+    - with the ctest command 
+
+If anything is changed in the code, be sure to explicitely call
+    cmake .
+in the build directory to update the local replica of the 'curveplot' package.
 
 PlotCurve_Standalone is a standalone Python executable that shows the
 various functionalities of the package.
index 0d2bc0c75ec3f188dc6420702846e1c0cf3de0a4..98a5dd1fea5592b8fc1f397d73e70e5f2b03f670 100644 (file)
 # Author : A. Bruneton
 #
 
-from pyqtside.QtGui import QApplication, QTabWidget 
-from pyqtside.QtGui import QAction, QMenu, QIcon, QPixmap, QDesktopWidget, QFileDialog
-from pyqtside.QtCore import SIGNAL, SLOT, QObject, Slot, Signal
+from pyqtside.QtWidgets import QApplication, QTabWidget 
+from pyqtside.QtWidgets import QAction, QMenu, QDesktopWidget, QFileDialog
+from pyqtside.QtGui import QIcon, QPixmap
+from pyqtside.QtCore import QObject, pyqtSlot, pyqtSignal
 
 RESOURCE_DIR = "@SGPYQT_RES_DIR@"
 
@@ -33,7 +34,7 @@ class SalomePyQt(QObject):
   This class can be used to mimick the true SALOME object without having to launch 
   SALOME
   """  
-  currentTabChanged = Signal(int)
+  currentTabChanged = pyqtSignal(int)
   
   START_VIEW_ID = 0
   
@@ -47,7 +48,7 @@ class SalomePyQt(QObject):
     if self._mainWindow:
       self._menuBar = self._mainWindow.menuBar()
       self._mainWindow.setCentralWidget(self._tabWidget)
-    self.connect(self._tabWidget, SIGNAL("currentChanged(int)"), self, SLOT("onTabChanged(int)"))
+    self._tabWidget.currentChanged.connect(self.onTabChanged)
     self._blockSignal = False
   
   def getDesktop(self):
@@ -58,12 +59,12 @@ class SalomePyQt(QObject):
     return QFileDialog.getSaveFileName(parent=parent_widget,
                                        caption=caption, directory=initial, filter=fil);
   
-  @Slot(int)
+  @pyqtSlot(int)
   def onTabChanged(self, index):
     if self._blockSignal:
       return
     invDict = dict([(v, k) for k,v in self._viewIDs.items()])
-    if invDict.has_key(index):
+    if index in invDict:
       self._blockSignal = True
       self.currentTabChanged.emit(invDict[index])
       self._blockSignal = False
index 3fffbaf3a874fbff9f7965624f60bb635a61cd1a..11d777046f78758fc378c717f2a45c742a4b6dee 100644 (file)
@@ -23,8 +23,8 @@
 # Author : A. Bruneton
 #
 
-from pyqtside.QtCore import SIGNAL, SLOT, Slot, Qt, QTimer
-from pyqtside.QtGui import QMainWindow,QMenu
+from pyqtside.QtCore import Qt, QTimer, pyqtSlot
+from pyqtside.QtWidgets import QMainWindow,QMenu
 import numpy as np
 
 import curveplot
@@ -70,15 +70,15 @@ class TestDesktop(QMainWindow):
         self.createMenus()
         self.createView()
         
-        self.connect(self.curveSameFigAction,SIGNAL("activated()"),self.curveSameFig)
-        self.connect(self.curveNewFigAction,SIGNAL("activated()"),self.curveNewFig)
-        self.connect(self.itemDelAction,SIGNAL("activated()"),self.itemDel)
-        self.connect(self.cpsAction,SIGNAL("activated()"),self.clearPlotSet)
-        self.connect(self.plotTableAction,SIGNAL("activated()"),self.plotTable)
-        self.connect(self.addPSAction,SIGNAL("activated()"),self.addPS)
-        self.connect(self.addTabAction,SIGNAL("activated()"),self.addTab)
-        self.connect(self.memAction,SIGNAL("activated()"),self.memPrint)
-        self.connect(self.perfTestAction,SIGNAL("activated()"),self.perfTest)
+        self.curveSameFigAction.triggered.connect(self.curveSameFig)
+        self.curveNewFigAction.triggered.connect(self.curveNewFig)
+        self.itemDelAction.triggered.connect(self.itemDel)
+        self.cpsAction.triggered.connect(self.clearPlotSet)
+        self.plotTableAction.triggered.connect(self.plotTable)
+        self.addPSAction.triggered.connect(self.addPS)
+        self.addTabAction.triggered.connect(self.addTab)
+        self.memAction.triggered.connect(self.memPrint)
+        self.perfTestAction.triggered.connect(self.perfTest)
 
     def generateID(self):
         self._currID += 1
@@ -152,7 +152,7 @@ class TestDesktop(QMainWindow):
 #       y = x
       return x, y
        
-    @Slot()  
+    @pyqtSlot()
     def curveSameFig(self):
       x, y = self.__generateRandomData()
       _, ps_id = curveplot.AddCurve(x, y, x_label="the x axis", y_label="the y axis", append=True)
@@ -164,13 +164,13 @@ class TestDesktop(QMainWindow):
       x, y = self.__generateRandomData()
       curveplot.AddCurve(x, y, x_label="the x axis", y_label="the y axis", append=False)
     
-    @Slot()
+    @pyqtSlot()
     def itemDel(self):
       curveplot.DeleteCurrentItem()
       if self.cnt >= 0:
         QTimer.singleShot(self.timeLap, self, SLOT("memPrint()"))
 
-    @Slot()
+    @pyqtSlot()
     def perfTest(self):
       lx, ly = [], []
       nC = 200
@@ -195,7 +195,7 @@ class TestDesktop(QMainWindow):
       
     def addTab(self):
       pass
-#      from PyQt4.QtGui import QPushButton
+#      from PyQt5.QtWidgets import QPushButton
 #      self.qp = QPushButton("Hi!")
 #      self._sgPyQt.createView("Dummy", self.qp)  
       
@@ -213,7 +213,7 @@ class TestDesktop(QMainWindow):
       cont.plotCurveFromTable(t, y_col_index=1, append=False)
       cont.plotCurveFromTable(t, y_col_index=2, append=True)
     
-    @Slot()
+    @pyqtSlot()
     def memPrint(self):
       i, t = curveplot.GetAllPlotSets()
       print(list(zip(i, t)))
@@ -224,4 +224,4 @@ class TestDesktop(QMainWindow):
       print("** Used memory: %.2f Mb" % m)
       if self.cnt >= 0 and self.cnt < self.MAX_CNT:
         self.cnt += 1
-        QTimer.singleShot(self.timeLap, self, SLOT("curveSameFig()"))
+        QTimer.singleShot(self.timeLap, self.curveSameFig)
index be7de68bbfbda5902d9eec6e719601cf06324ecf..0f251a0651cdbd4af45291be7cc2f9a19899038c 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testAddCurveAppend_a.png and b/tools/CurvePlot/src/python/test/baselines/testAddCurveAppend_a.png differ
index 69de6919bf82a968b235f6de9d9bc37678e8b167..79645403b6de8071a67222bb2a83defc66be8743 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testAddCurve_a.png and b/tools/CurvePlot/src/python/test/baselines/testAddCurve_a.png differ
index 4a7417bd84340cddb428c54b04b248201a6f9cf3..6667d06d77ba95d1f98524a5f97ed02fff5d78a0 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testAddPlotSet_a.png and b/tools/CurvePlot/src/python/test/baselines/testAddPlotSet_a.png differ
index 4a7417bd84340cddb428c54b04b248201a6f9cf3..6667d06d77ba95d1f98524a5f97ed02fff5d78a0 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testClearPlotSet2_a.png and b/tools/CurvePlot/src/python/test/baselines/testClearPlotSet2_a.png differ
index c9144c243ab561f0323f46310257ca2452979151..7e2f7abe35ce7f0a44b83e0d197d2bffc7acc9e0 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testClearPlotSet_a.png and b/tools/CurvePlot/src/python/test/baselines/testClearPlotSet_a.png differ
index a08cf1b226183f2e41c3752b9c1d7c322817be62..be7e36eab382187251b74190998e5ee004fa2cfc 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testCopyCurve_a.png and b/tools/CurvePlot/src/python/test/baselines/testCopyCurve_a.png differ
index 2b16e2ce27a52d72b2908d8740e7ab303be1742d..c896b6f07990a884164c3bbec7142a2dfdc8b202 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testDeleteCurrentItem_curve_a.png and b/tools/CurvePlot/src/python/test/baselines/testDeleteCurrentItem_curve_a.png differ
index b84993bbb630e25aec1920a4c16f85b551a80211..43858fff82b7f8c9170a8f7665ff0ee70dc433e6 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testDeleteCurrentItem_plotSet_a.png and b/tools/CurvePlot/src/python/test/baselines/testDeleteCurrentItem_plotSet_a.png differ
index 1043c947d4d8f15edda56f9fc317baf293d50702..744a6f5ccbec399671a95ff6b4ab9cbfe4c4b5f9 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testDeleteCurve1_a.png and b/tools/CurvePlot/src/python/test/baselines/testDeleteCurve1_a.png differ
index 1043c947d4d8f15edda56f9fc317baf293d50702..744a6f5ccbec399671a95ff6b4ab9cbfe4c4b5f9 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testDeleteCurve2_a.png and b/tools/CurvePlot/src/python/test/baselines/testDeleteCurve2_a.png differ
index e9f8ed691412081d701693f12ba42404a0ebc71f..45ec73a43856bacc90b893d5e59b49a85bea1210 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testDeleteCurve3_a.png and b/tools/CurvePlot/src/python/test/baselines/testDeleteCurve3_a.png differ
index 24895028c748facf6d88da1eff36bece7d25b316..0d80b2384fde48b42e926bf4d5d87386b7c4b4db 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testDeletePlotSet1_a.png and b/tools/CurvePlot/src/python/test/baselines/testDeletePlotSet1_a.png differ
index 24895028c748facf6d88da1eff36bece7d25b316..0d80b2384fde48b42e926bf4d5d87386b7c4b4db 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testDeletePlotSet2_a.png and b/tools/CurvePlot/src/python/test/baselines/testDeletePlotSet2_a.png differ
index 1476e781b83d1391fb7924c1da0b28dc4c80e9d7..ad04b34c23068f643079eb410ff6ddc157280137 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testExtendCurve_a.png and b/tools/CurvePlot/src/python/test/baselines/testExtendCurve_a.png differ
index 98b167091dd9c0cba30837f97fc73b7f39b177f5..58fa9fcd92f7e1be708e37e9627d3f576e7089b0 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testLockRepaint_a.png and b/tools/CurvePlot/src/python/test/baselines/testLockRepaint_a.png differ
index 91bfc40128f7b0feb49e26a5b35e1163fbf0a380..4ac74a1114e4fec00692adefc356dd78d90b6ab2 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testPlotCurveFromTable_a.png and b/tools/CurvePlot/src/python/test/baselines/testPlotCurveFromTable_a.png differ
index ba52552a162f0ae80aeb6e21b99843f70a770aff..2c1a0c30f913202f48b963cda38f90940e409ca1 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testResetCurve_a.png and b/tools/CurvePlot/src/python/test/baselines/testResetCurve_a.png differ
index 01ea93a6a67f69d66b0d9405eec425066708c738..94d929b542baf765b9808be377045312992158cc 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testSetCurrentCurve2_a.png and b/tools/CurvePlot/src/python/test/baselines/testSetCurrentCurve2_a.png differ
index 2b16e2ce27a52d72b2908d8740e7ab303be1742d..c896b6f07990a884164c3bbec7142a2dfdc8b202 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testSetCurrentCurve3_a.png and b/tools/CurvePlot/src/python/test/baselines/testSetCurrentCurve3_a.png differ
index 1d5c9219661de27cfaba78e8590831f38cb6456d..bfb41d673ab4988f38418f2f30387796d961e20f 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testSetCurrentCurve_a.png and b/tools/CurvePlot/src/python/test/baselines/testSetCurrentCurve_a.png differ
index e890d57d321b098fab781dbfed21ea8e910c33aa..7b2ca2a0a72ec4927116e6547ec8f2ccb1e247bd 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testSetCurrentPlotSet_a.png and b/tools/CurvePlot/src/python/test/baselines/testSetCurrentPlotSet_a.png differ
index 8d4ffb317a4269018575f16dd63a0d882f4d5f75..0ae41d13871550a51d0fc95ac2594139b18eb8f5 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testSetCurveLabel_a.png and b/tools/CurvePlot/src/python/test/baselines/testSetCurveLabel_a.png differ
index 9f6eebc49eb5991189e863686e3308182d92fb01..a126ef86a6792fa18b1a3c7550fa6ac7738075f3 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testSetCurveMarker_a.png and b/tools/CurvePlot/src/python/test/baselines/testSetCurveMarker_a.png differ
index f261e736d712f561d7925b56be7907ed0ed9e965..08537dbf10f64463d15140c45850c00ec13940b4 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testSetLabelX_a.png and b/tools/CurvePlot/src/python/test/baselines/testSetLabelX_a.png differ
index 4a7417bd84340cddb428c54b04b248201a6f9cf3..d917195d8a8254e0d3f5939bc72cefb2ed7bdfdd 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testSetLabelY_a.png and b/tools/CurvePlot/src/python/test/baselines/testSetLabelY_a.png differ
index 0dae71d2552a95d5d5e201a9f8359e511c43164b..55e35a9457bce9f12431e7819502aee08a3b6787 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testSetLegendVisible_a.png and b/tools/CurvePlot/src/python/test/baselines/testSetLegendVisible_a.png differ
index e805f17cd9f747cc22f5f0b261296e471ed6807b..6920c0117d27e1970bf9dfcaa6673e10be410f25 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testSetPlotSetTitle_a.png and b/tools/CurvePlot/src/python/test/baselines/testSetPlotSetTitle_a.png differ
index 336bbeb935f5fb98af3ddae4e07f89bbc1e55fea..649579cd7b5b998a50e1f3f46d1f351f109cba2d 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testSetXSciNotation_a.png and b/tools/CurvePlot/src/python/test/baselines/testSetXSciNotation_a.png differ
index 44e29e678091d4ab885308da1d0e99391a46dceb..3dc38aa608256551002c6ae73caac1e084d6a998 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testSetYSciNotation_a.png and b/tools/CurvePlot/src/python/test/baselines/testSetYSciNotation_a.png differ
index 5dbdbd7e101b78e1f9db440cb18550aafb63c45b..bdf2ac5b0648d16bde7e731355332465cc2b853b 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testSettingsCurveColor_a.png and b/tools/CurvePlot/src/python/test/baselines/testSettingsCurveColor_a.png differ
index e9df517a754e4a6658f8db6edf4582497be0f14e..a5f8fe88f4d9b56091c060bd997e24d38b40846f 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testSettingsCurveMarker_a.png and b/tools/CurvePlot/src/python/test/baselines/testSettingsCurveMarker_a.png differ
index 5fb1fcdf910c7eff55237f42dfdafc88e0cff547..96319afe40b9ca009bbc9f3717ff385e2b7b0ccd 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testToggleXLog_a.png and b/tools/CurvePlot/src/python/test/baselines/testToggleXLog_a.png differ
index 0db30fb2b081f246c6949fc74ae05c138b6d45ce..cdfe1e72805a9dfcfce633f8d39b1ca4c72f9b1b 100644 (file)
Binary files a/tools/CurvePlot/src/python/test/baselines/testToggleYLog_a.png and b/tools/CurvePlot/src/python/test/baselines/testToggleYLog_a.png differ
index 39f9feb2d2f6a0140d4fdf993b0317ccca05f0d3..b9878a791857d21036d42e84947791a08687836e 100644 (file)
 #
 # Author : A. Bruneton
 #
+from curveplot import *
+from curveplot.PlotTestBase import PlotTestBase, processDecorator
+from curveplot.PlotSettings import PlotSettings
 
-from PlotTestBase import PlotTestBase, runOnly, processDecorator
-
-from PlotController import PlotController
-from PlotSettings import PlotSettings
-
-from pyqtside.QtGui import QApplication
+from pyqtside.QtWidgets import QApplication
 import sys
-qapp = QApplication(sys.argv)  
-  
+qapp = QApplication(sys.argv)
+
 class PlotTest(PlotTestBase):
   """ Unit test suite for the curve plotter. The tests themselves are stored in this class,
   the screenshot comparison logic is in PlotTestBase.
@@ -43,10 +41,10 @@ class PlotTest(PlotTestBase):
   The decorator @runOnly can be used to run/rebuild a single test.
   """
   REBUILD_BASELINES = False
-  
+
   def __init__(self, methodName):
     PlotTestBase.__init__(self, methodName)
-  
+
   ###
   ### Data generation
   ###
@@ -55,24 +53,24 @@ class PlotTest(PlotTestBase):
     x = np.arange(100)
     y = np.sin(x*alpha/np.pi)
     return x, y
-  
+
   def generateExp(self, alpha=1.0):
     import numpy as np
     x = np.arange(20) + 1.0
     y = np.exp(x*alpha)
     return x, y
-   
+
   ###
   ### The tests themselves
   ###
-    
+
   #
   # Non GUI tests (some of them still need to show the widget to work properly but no
   # screenshot comparison is made).
   #
   def testTableModel(self):
     import numpy as np
-    from TableModel import TableModel
+    from curveplot.TableModel import TableModel
     t = TableModel(None)
     t.setTitle("coucou")
     t.addColumn([1.0,2.0,3.0,4.0])
@@ -85,25 +83,25 @@ class PlotTest(PlotTestBase):
     t.setColumnTitle(1, "a title")
     self.assertEqual("a title", t.getColumnTitle(1))
     self.assertEqual("", t.getColumnTitle(0))
-       
+
   def testGetAllPlotSets(self):
     self.showTabWidget()
     ids, titles = PlotController.GetAllPlotSets()
     self.assertEqual([], ids)
     self.assertEqual([], titles)
-         
+
     id1 = PlotController.AddPlotSet("toto")
     id2 = PlotController.AddPlotSet("tutu")
     id3 = PlotController.AddPlotSet("titi")
     ids, titles = PlotController.GetAllPlotSets()
     self.assertEqual([id1,id2,id3], ids)
     self.assertEqual(["toto","tutu","titi"], titles)
-     
+
   def testGetCurrentXX(self):
     self.showTabWidget()
     self.assertEqual(-1, PlotController.GetCurrentCurveID())
     self.assertEqual(-1, PlotController.GetCurrentPlotSetID())
-      
+
     x, y = self.generateSine()
     _, psID1 = PlotController.AddCurve(x, y, append=False)
     self.assertEqual(psID1, PlotController.GetCurrentPlotSetID())
@@ -116,7 +114,7 @@ class PlotTest(PlotTestBase):
     PlotController.DeletePlotSet(psID2)
     self.assertEqual(-1, PlotController.GetCurrentCurveID())
     self.assertEqual(-1, PlotController.GetCurrentPlotSetID())
-         
+
   def testGetPlotSetID(self):
     self.showTabWidget()
     x, y = self.generateSine()
@@ -125,7 +123,7 @@ class PlotTest(PlotTestBase):
     self.assertEqual(-1, PlotController.GetPlotSetID(145))  # invalid ID
     PlotController.DeletePlotSet(psID)
     self.assertEqual(-1, PlotController.GetPlotSetID(crvID))  # invalid ID
-        
+
   def testGetPlotSetIDByName(self):
     self.showTabWidget()
     self.assertEqual(-1,PlotController.GetPlotSetIDByName("invalid"))
@@ -133,7 +131,7 @@ class PlotTest(PlotTestBase):
     self.assertEqual(psID,PlotController.GetPlotSetIDByName("ps"))
     PlotController.DeletePlotSet(psID)
     self.assertEqual(-1,PlotController.GetPlotSetIDByName("ps"))
-        
+
   def testIsValidPlotSetID(self):
     self.showTabWidget()
     self.assertEqual(False,PlotController.IsValidPlotSetID(0))
@@ -141,16 +139,16 @@ class PlotTest(PlotTestBase):
     self.assertEqual(True,PlotController.IsValidPlotSetID(psID))
     PlotController.DeletePlotSet(psID)
     self.assertEqual(False,PlotController.IsValidPlotSetID(psID))
-      
+
   #
   # GUI tests
-  #    
+  #
   def testAddCurve(self):
     x, y = self.generateSine()
     tw = self.showTabWidget()
     PlotController.AddCurve(x, y, curve_label="My curve", x_label="Lèés X (unicode!)", y_label="Et des Å·", append=False)
     self.assertTrue(self.areScreenshotEqual(tw))
-      
+
   def testAddCurveAppend(self):
     x, y = self.generateSine()
     tw = self.showTabWidget()
@@ -162,12 +160,12 @@ class PlotTest(PlotTestBase):
     tw = self.showTabWidget()
     PlotController.AddPlotSet("My plotset")
     self.assertTrue(self.areScreenshotEqual(tw))
-          
+
   def testClearPlotSet(self):
     x, y = self.generateSine()
     tw = self.showTabWidget()
     PlotController.AddCurve(x, y, curve_label="My curve", x_label="The X-s", y_label="The Y-s", append=False)
-    _, psID = PlotController.AddCurve(x, y, curve_label="My curve 2", append=True)    
+    _, psID = PlotController.AddCurve(x, y, curve_label="My curve 2", append=True)
     clearedID = PlotController.ClearPlotSet()
     self.assertEqual(clearedID, psID)
     self.assertTrue(self.areScreenshotEqual(tw))
@@ -179,7 +177,7 @@ class PlotTest(PlotTestBase):
     clearedID = PlotController.ClearPlotSet(psID)
     self.assertEqual(psID, clearedID)
     self.assertTrue(self.areScreenshotEqual(tw))
-          
+
   def testCopyCurve(self):
     x, y = self.generateSine()
     tw = self.showTabWidget()
@@ -189,7 +187,7 @@ class PlotTest(PlotTestBase):
     PlotController.SetCurrentPlotSet(psID)
     self.assertNotEqual(crvID, newID)
     self.assertTrue(self.areScreenshotEqual(tw))
-          
+
   def testDeleteCurrentItem_curve(self):
     x, y = self.generateSine()
     tw = self.showTabWidget()
@@ -200,7 +198,7 @@ class PlotTest(PlotTestBase):
     self.assertFalse(b)
     self.assertEqual(crvID, anID)
     self.assertTrue(self.areScreenshotEqual(tw))
-          
+
   def testDeleteCurrentItem_plotSet(self):
     tw = self.showTabWidget()
     PlotController.AddPlotSet("tutu")
@@ -209,13 +207,13 @@ class PlotTest(PlotTestBase):
     self.assertTrue(b)
     self.assertEqual(psID, anID)
     self.assertTrue(self.areScreenshotEqual(tw))
-            
+
   def testDeleteCurrentItem_void(self):
     self.showTabWidget()
-    b, anID = PlotController.DeleteCurrentItem()  # nothing selected 
+    b, anID = PlotController.DeleteCurrentItem()  # nothing selected
     self.assertTrue(b)
     self.assertEqual(-1, anID)
-          
+
   def testDeleteCurve1(self):
     tw = self.showTabWidget()
     x, y = self.generateSine()
@@ -224,7 +222,7 @@ class PlotTest(PlotTestBase):
     cID = PlotController.DeleteCurve(crvID)
     self.assertEqual(crvID, cID)
     self.assertTrue(self.areScreenshotEqual(tw))
-        
+
   def testDeleteCurve2(self):
     tw = self.showTabWidget()
     x, y = self.generateSine()
@@ -234,16 +232,16 @@ class PlotTest(PlotTestBase):
     cID = PlotController.DeleteCurve()   # current curve
     self.assertEqual(crvID, cID)
     self.assertTrue(self.areScreenshotEqual(tw))
-     
+
   def testDeleteCurve3(self):
     """ resulting in an empty plot set, legend should be hidden """
     tw = self.showTabWidget()
     x, y = self.generateSine()
     crvID, _ = PlotController.AddCurve(x, y, append=False)
-    cID = PlotController.DeleteCurve(crvID) 
+    cID = PlotController.DeleteCurve(crvID)
     self.assertEqual(crvID, cID)
     self.assertTrue(self.areScreenshotEqual(tw))
-        
+
   def testDeletePlotSet1(self):
     tw = self.showTabWidget()
     psID = PlotController.AddPlotSet("tutu")
@@ -251,7 +249,7 @@ class PlotTest(PlotTestBase):
     psID2 = PlotController.DeletePlotSet(psID)
     self.assertEqual(psID2, psID)
     self.assertTrue(self.areScreenshotEqual(tw))
-        
+
   def testDeletePlotSet2(self):
     tw = self.showTabWidget()
     psID1 = PlotController.DeletePlotSet()
@@ -262,7 +260,7 @@ class PlotTest(PlotTestBase):
     psID3 = PlotController.DeletePlotSet()  # current plot set
     self.assertEqual(psID3, psID2)
     self.assertTrue(self.areScreenshotEqual(tw))
-        
+
   def testSetCurrentCurve(self):
     tw = self.showTabWidget()
     self.assertRaises(ValueError, PlotController.SetCurrentCurve, 23)
@@ -272,7 +270,7 @@ class PlotTest(PlotTestBase):
     psID2 = PlotController.SetCurrentCurve(crvID)
     self.assertEqual(psID, psID2)
     self.assertTrue(self.areScreenshotEqual(tw))
-        
+
   def testSetCurrentCurve2(self):
     tw = self.showTabWidget()
     x, y = self.generateSine()
@@ -283,7 +281,7 @@ class PlotTest(PlotTestBase):
     # on first plot set curve should not be selected anymore
     PlotController.SetCurrentPlotSet(psID)
     self.assertTrue(self.areScreenshotEqual(tw))
-  
+
   def testSetCurrentCurve3(self):
     tw = self.showTabWidget()
     x, y = self.generateSine()
@@ -292,7 +290,7 @@ class PlotTest(PlotTestBase):
     PlotController.SetCurrentCurve(crvID)
     PlotController.SetCurrentCurve(-1)
     self.assertTrue(self.areScreenshotEqual(tw))
-        
+
   def testSetCurrentPlotSet(self):
     tw = self.showTabWidget()
     psID = PlotController.AddPlotSet("tutu")
@@ -300,7 +298,7 @@ class PlotTest(PlotTestBase):
     PlotController.SetCurrentPlotSet(psID)
     self.assertTrue(self.areScreenshotEqual(tw))
     self.assertRaises(ValueError, PlotController.SetCurrentPlotSet, 124) # invalid ps_id
-     
+
   def testSetLabelX(self):
     tw = self.showTabWidget()
     ps_id = PlotController.AddPlotSet("My plotset")
@@ -321,14 +319,14 @@ class PlotTest(PlotTestBase):
     PlotController.SetPlotSetTitle("un titre Ã Ã©", ps_id)
     PlotController.SetCurrentPlotSet(ps_id)
     self.assertTrue(self.areScreenshotEqual(tw))
-        
+
 #   def testToggleCurveBrowser(self):
 #     # hard to test ...
 #     raise NotImplementedError
-          
+
   def testPlotCurveFromTable(self):
     tw = self.showTabWidget()
-    from TableModel import TableModel
+    from curveplot.TableModel import TableModel
     t = TableModel(None)
     t.setTitle("coucou")
     t.addColumn([1.0,2.0,3.0,4.0])
@@ -352,21 +350,21 @@ class PlotTest(PlotTestBase):
     def fun():
       dlg_test.setRGB(0,0,0)
       dlg_test.showLegendCheckBox.setChecked(True)
-      return True  
+      return True
     dlg_test.exec_ = fun
     t = list(PlotController.GetInstance()._curveTabsView._XYViews.items())
-    t[0][1].onSettings(dlg_test=dlg_test)  
+    t[0][1].onSettings(dlg_test=dlg_test)
     self.assertTrue(self.areScreenshotEqual(tw))
+
   def testExtendCurve(self):
     tw = self.showTabWidget()
     x, y = self.generateSine()
     crvID, _ = PlotController.AddCurve(x, y, append=False)
     PlotController.SetCurrentCurve(crvID)
     PlotController.ExtendCurve(crvID, x+100.0, y*2.0)
-    # Curve must remain blue, bold and with first marker:      
+    # Curve must remain blue, bold and with first marker:
     self.assertTrue(self.areScreenshotEqual(tw))
-     
+
   def testResetCurve(self):
     tw = self.showTabWidget()
     x, y = self.generateSine()
@@ -374,7 +372,7 @@ class PlotTest(PlotTestBase):
     PlotController.SetCurrentCurve(crvID)
     PlotController.ResetCurve(crvID)
     PlotController.ExtendCurve(crvID, x+100.0, y*x)
-    # Curve must remain blue, bold and with first marker:      
+    # Curve must remain blue, bold and with first marker:
     self.assertTrue(self.areScreenshotEqual(tw))
 
   def testSettingsCurveMarker(self):
@@ -387,19 +385,19 @@ class PlotTest(PlotTestBase):
     def fun():
       dlg_test.markerCurve.setCurrentIndex(2)
       dlg_test.showLegendCheckBox.setChecked(True)
-      return True  
+      return True
     dlg_test.exec_ = fun
     t = list(PlotController.GetInstance()._curveTabsView._XYViews.items())
-    t[0][1].onSettings(dlg_test=dlg_test)  
+    t[0][1].onSettings(dlg_test=dlg_test)
     self.assertTrue(self.areScreenshotEqual(tw))
-    
+
   def testSetCurveMarker(self):
     tw = self.showTabWidget()
     x, y = self.generateSine()
     crvID, _ = PlotController.AddCurve(x, y, append=False)
     PlotController.SetCurveMarker(crvID, "v")
     self.assertTrue(self.areScreenshotEqual(tw))
-  
+
   def testSetCurveLabel(self):
     tw = self.showTabWidget()
     x, y = self.generateSine()
@@ -408,7 +406,7 @@ class PlotTest(PlotTestBase):
     PlotController.SetCurrentCurve(crvID)
     PlotController.SetCurveLabel(crvID, "tata")
     self.assertTrue(self.areScreenshotEqual(tw))
-    
+
   def testToggleXLog(self):
     tw = self.showTabWidget()
     x, y = self.generateExp()
@@ -424,7 +422,7 @@ class PlotTest(PlotTestBase):
     PlotController.SetYLog(psID, True)
     PlotController.SetYSciNotation(psID, True)
     self.assertTrue(self.areScreenshotEqual(tw))
-  
+
   def testSetXSciNotation(self):
     tw = self.showTabWidget()
     x, y = self.generateSine()
@@ -438,7 +436,7 @@ class PlotTest(PlotTestBase):
     _, psID = PlotController.AddCurve(x*1.0e6, y*1.0e6, curve_label="titi", append=False)
     PlotController.SetYSciNotation(psID, True)
     self.assertTrue(self.areScreenshotEqual(tw))
-  
+
   def testRegisterCallback(self):
     global a_callb
     a_callb = 0
@@ -466,7 +464,7 @@ class PlotTest(PlotTestBase):
     PlotController.SetCurrentCurve(crvId)
     _, _ = PlotController.AddCurve(x, y)
     self.assertEqual(crvId, a_callb)
-    
+
   def testAddCurveEmptyPs(self):
     """ Adding a curve when no ps was active was buggy """
     self.showTabWidget()
@@ -478,7 +476,7 @@ class PlotTest(PlotTestBase):
     PlotController.AddCurve(x, y, append=True)
     l, _ = PlotController.GetAllPlotSets()
     self.assertEqual(2, len(l))
-    
+
   def test_onCurrentCurveChange(self):
     self.showTabWidget()
     x, y = self.generateSine()
@@ -517,10 +515,10 @@ class PlotTest(PlotTestBase):
     self.assertEqual(psID0, psID2)
     l, _ = PlotController.GetAllPlotSets()
     self.assertEqual(1, len(l))
-    
+
 # Even if not in main:
 processDecorator(__name__)
 
 if __name__ == "__main__":
-  import unittest    
+  import unittest
   unittest.main()
index 34cc77030e2030f24a2addee7bf2e472d51a6001..3c8f19ecd23cb6cab0cba8e33ca0b6c5d391e4bd 100644 (file)
@@ -36,5 +36,10 @@ SET(_all_lib_SCRIPTS
 # --- rules ---
 SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_CURVEPLOT_INSTALL_PYTHON})
 SALOME_INSTALL_SCRIPTS("${_all_lib_SCRIPTS}" ${SALOME_CURVEPLOT_INSTALL_PYTHON})
-
 INSTALL(FILES ${_pyuic_files} DESTINATION ${SALOME_CURVEPLOT_INSTALL_PYTHON})
+
+# For test purposes
+FILE(COPY ${_pyuic_SCRIPTS} DESTINATION ${CRVPLOT_TEST_INSTALL})
+FILE(COPY ${_pyuic_files} DESTINATION ${CRVPLOT_TEST_INSTALL})
+FILE(COPY ${_all_lib_SCRIPTS} DESTINATION ${CRVPLOT_TEST_INSTALL})
+
index 7dfb994aedb71230b6996bc10a004678c74ef6d9..251d13d4bef77399ca5bb5d01d45472672a8a2fb 100644 (file)
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-from pyqtside import QtGui, QtCore
+from pyqtside import QtWidgets, QtCore
 from pyqtside.uic import loadUiGen
-from utils import completeResPath
+from .utils import completeResPath
 
-class CurveTreeDockWidget(QtGui.QDockWidget):
+class CurveTreeDockWidget(QtWidgets.QDockWidget):
   def __init__(self):
-    QtGui.QDockWidget.__init__(self)
+    QtWidgets.QDockWidget.__init__(self)
     loadUiGen(completeResPath("CurveTreeDockWidget.ui"), self)
     self.treeWidget.setHeaderLabel ("Plots")
     self.treeWidget.sortByColumn(0, QtCore.Qt.AscendingOrder)
     self.treeWidget.setSortingEnabled(True);
     self.treeWidget.setColumnHidden(1, True);
-            
+
   def getTreeWidget(self):
       """
       :returns: QTreeWidget -- the (curve) browser
index b4623a5e356fbceea8d2d9eaba62f7cff426f4ce..530ea469c013345afc2983d112ea43210134c051 100644 (file)
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-from pyqtside import QtGui, QtCore
+from pyqtside.QtWidgets import QDialog, QColorDialog, QMessageBox
+from pyqtside.QtGui import QIcon, QPixmap, QColor
+from pyqtside.QtCore import pyqtSlot
 from pyqtside.uic import loadUiGen
-from utils import completeResPath
+from .utils import completeResPath, Logger
 
-class PlotSettings(QtGui.QDialog):
+class PlotSettings(QDialog):
   def __init__(self):
-    QtGui.QDialog.__init__(self)
+    QDialog.__init__(self)
     loadUiGen(completeResPath("PlotSettings.ui"), self)
     self.initialize()
 
@@ -33,41 +35,44 @@ class PlotSettings(QtGui.QDialog):
     self._r = 0
     self._g = 0
     self._b = 1
-   
-  @QtCore.Slot(int)
+
+  @pyqtSlot(int)
   def onShowLegend(self, index):
     if index > 0 :
       self.legendPositionComboBox.setEnabled(True)
     else :
       self.legendPositionComboBox.setEnabled(False)
-  
-  @QtCore.Slot() 
+
+  @pyqtSlot()
   def onChangeColor(self):
-    col = QtGui.QColorDialog.getColor()
+    col = QColorDialog.getColor()
 
     if col.isValid():
       r, g, b = [c/255.0 for c in col.getRgb()[:3]]
       self.setRGB(r, g, b)
-      
+
   def setSelectedCurveName(self, name):
+    self.nameCurve.setText(name)
     if name :
+      Logger.Debug("show curve panel")
       self.selectedCurvePanel.setTitle("Selected curve : " + name)
       self.selectedCurvePanel.show()
     else :
+      Logger.Debug("hide curve panel")
       self.selectedCurvePanel.hide()
-   
+
   def setRGB(self, r, g, b):
     self._r = r
     self._g = g
     self._b = b
-    self.colorCurve.setIcon(QtGui.QIcon(self.drawColorPixmap(int(r*255), int(g*255), int(b*255))))
-   
+    self.colorCurve.setIcon(QIcon(self.drawColorPixmap(int(r*255), int(g*255), int(b*255))))
+
   def getRGB(self):
     return self._r, self._g, self._b
-   
+
   def drawColorPixmap(self, r, g, b):
-    pix = QtGui.QPixmap( 16, 16 )
-    color = QtGui.QColor(r, g, b)
+    pix = QPixmap( 16, 16 )
+    color = QColor(r, g, b)
     pix.fill(color)
     return pix
 
@@ -77,32 +82,32 @@ class PlotSettings(QtGui.QDialog):
     yminText = str(self.axisYMinEdit.text())
     ymaxText = str(self.axisYMaxEdit.text())
     if (yminText == "" or ymaxText == "") :
-      QtGui.QMessageBox.critical(self, "Plot settings", "A field \"YMin\" or \"YMax\" is empty")
+      QMessageBox.critical(self, "Plot settings", "A field \"YMin\" or \"YMax\" is empty")
     else :
       try:
         xmin = float(xminText)
       except ValueError:
-        QtGui.QMessageBox.critical(self, "Plot settings", "It is not possible to convert XMin")
+        QMessageBox.critical(self, "Plot settings", "It is not possible to convert XMin")
       try:
         xmax = float(xmaxText)
       except ValueError:
-        QtGui.QMessageBox.critical(self, "Plot settings", "It is not possible to convert XMax")
+        QMessageBox.critical(self, "Plot settings", "It is not possible to convert XMax")
       try:
         ymin = float(yminText)
       except ValueError:
-        QtGui.QMessageBox.critical(self, "Plot settings", "It is not possible to convert YMin")
+        QMessageBox.critical(self, "Plot settings", "It is not possible to convert YMin")
       try:
         ymax = float(ymaxText)
       except ValueError:
-        QtGui.QMessageBox.critical(self, "Plot settings", "It is not possible to convert YMax")
+        QMessageBox.critical(self, "Plot settings", "It is not possible to convert YMax")
       if ((xmax-xmin) == 0) :
-        QtGui.QMessageBox.critical(self, "Plot settings", "XMax is is equal to XMin.")
+        QMessageBox.critical(self, "Plot settings", "XMax is is equal to XMin.")
         return
       if ((ymax-ymin) == 0) :
-        QtGui.QMessageBox.critical(self, "Plot settings", "YMax is is equal to YMin.")
+        QMessageBox.critical(self, "Plot settings", "YMax is is equal to YMin.")
         return
       if ((xmax-xmin) < 0) :
-        QtGui.QMessageBox.warning(self, "Plot settings", "XMax is less than XMin.")
+        QMessageBox.warning(self, "Plot settings", "XMax is less than XMin.")
       if ((ymax-ymin) < 0) :
-        QtGui.QMessageBox.warning(self, "Plot settings", "YMax is less than YMin.")
+        QMessageBox.warning(self, "Plot settings", "YMax is less than YMin.")
       super(PlotSettings, self).accept()
index 687e47a206c50f1d7cd20d3d4c8a2103c135ef00..0672d6f55118f98940f4560cad53c4fd4d9805dd 100644 (file)
           <x>11</x>
           <y>35</y>
           <width>291</width>
-          <height>57</height>
+          <height>74</height>
          </rect>
         </property>
         <layout class="QVBoxLayout" name="verticalLayout_6">
            </item>
            <item>
             <widget class="QLineEdit" name="nameCurve">
-             <property name="palette">
-              <palette>
-               <active>
-                <colorrole role="WindowText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>145</red>
-                   <green>145</green>
-                   <blue>145</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Text">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>105</red>
-                   <green>105</green>
-                   <blue>105</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-               </active>
-               <inactive>
-                <colorrole role="WindowText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>145</red>
-                   <green>145</green>
-                   <blue>145</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Text">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>105</red>
-                   <green>105</green>
-                   <blue>105</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-               </inactive>
-               <disabled>
-                <colorrole role="WindowText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>149</red>
-                   <green>151</green>
-                   <blue>153</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Text">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>158</red>
-                   <green>158</green>
-                   <blue>158</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-               </disabled>
-              </palette>
+             <property name="enabled">
+              <bool>true</bool>
+             </property>
+             <property name="text">
+              <string/>
              </property>
              <property name="readOnly">
-              <bool>true</bool>
+              <bool>false</bool>
              </property>
             </widget>
            </item>
index aca4c80f38cb7fd37f44a96eecd0a2782b544eba..82646fd6291a9cb5507d4a267c55dc9d3602b351 100644 (file)
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-from pyqtside import QtGui
+from pyqtside import QtWidgets
 from pyqtside.uic import loadUiGen
-from utils import completeResPath
+from .utils import completeResPath
 
-class PlotWidget(QtGui.QMainWindow):
+class PlotWidget(QtWidgets.QMainWindow):
   def __init__(self):
-    QtGui.QMainWindow.__init__(self)
+    QtWidgets.QMainWindow.__init__(self)
     loadUiGen(completeResPath("PlotWidget.ui"), self)
-    
+
   def clearAll(self):
     """ In test context, the PlotWidget is never fully deleted (because the PyQt binding
     of QTabWidget doesn't remove completly the references it holds).
index 87c73823394801bd5fb163133cbba0d73c47fab8..2f5a177425b6629c48660c8607d57d53fd153d8c 100644 (file)
@@ -24,5 +24,8 @@ SET(_all_lib_SCRIPTS
     CurveView.py
     XYView.py
 )
-    
+
 SALOME_INSTALL_SCRIPTS("${_all_lib_SCRIPTS}" ${SALOME_CURVEPLOT_INSTALL_PYTHON})
+
+# For test purposes
+FILE(COPY ${_all_lib_SCRIPTS} DESTINATION ${CRVPLOT_TEST_INSTALL})
index c0c8f9215ad948f8f226b1760e12065e8d758e50..68589a03986c8a3c4a1d1176f3eb4482bc49c322 100644 (file)
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-from pyqtside import QtGui
-from pyqtside.QtGui import QMenu
+from pyqtside import QtWidgets
+from pyqtside.QtWidgets import QMenu
 from pyqtside.QtCore import Qt
 
-from View import View
-from CurveTreeDockWidget import CurveTreeDockWidget
-from utils import Logger
+from .View import View
+from .CurveTreeDockWidget import CurveTreeDockWidget
+from .utils import Logger
 
 class CurveBrowserView( View, CurveTreeDockWidget) :
 
@@ -55,10 +55,10 @@ class CurveBrowserView( View, CurveTreeDockWidget) :
             
         # The second (hidden) column in the tree bares the ID of the object and its nature (plotset or curve)
         for p in list(plotSets.values()):
-          item = QtGui.QTreeWidgetItem([str(p.getTitle()), str(p.getID()) + '_set'])
+          item = QtWidgets.QTreeWidgetItem([str(p.getTitle()), str(p.getID()) + '_set'])
           treeWidget.addTopLevelItem(item)
           for c in list(p._curves.values()):
-            chld = QtGui.QTreeWidgetItem([str(c.getTitle()), str(c.getID()) + '_crv'])
+            chld = QtWidgets.QTreeWidgetItem([str(c.getTitle()), str(c.getID()) + '_crv'])
             item.addChild(chld)
           
         treeWidget.expandAll()
index d58feff49de0157cc07695c4894d98db3571c694..4f7870a2ea7c13b83a8f6c02c6b4113b0ae02a32 100644 (file)
@@ -17,9 +17,9 @@
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-from View import View
-from XYView import XYView
-from utils import Logger
+from .View import View
+from .XYView import XYView
+from .utils import Logger
 
 class CurveTabsView(View):
   def __init__(self, controller):
index 0a1d50a4b60a6911e2e102100ffccc08ad5f1111..406e94338acdedcfd7c676dd9acc78b88eb939f6 100644 (file)
@@ -17,8 +17,8 @@
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-from View import View
-from utils import Logger
+from .View import View
+from .utils import Logger
 
 class CurveView(View):
   _PICKER_PRECISION = 20  #pts
index 4714b7ebe53175fe9a27419b26120a49c31d3b64..f0ba245ac4a332112aeca1772583aa59fa1078f5 100644 (file)
 
 import matplotlib.pyplot as plt
 import matplotlib.colors as colors
-from View import View
-from CurveView import CurveView
-
-from utils import Logger, trQ
-from PlotWidget import PlotWidget
-from PlotSettings import PlotSettings
-from pyqtside import QtGui, QtCore
+from pyqtside import QtWidgets, QtCore
 from pyqtside.QtCore import QObject
 from matplotlib.figure import Figure
-from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg, NavigationToolbar2QT
+from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg, NavigationToolbar2QT
+
+from .View import View
+from .CurveView import CurveView
+from .PlotWidget import PlotWidget
+from .PlotSettings import PlotSettings
+from .utils import Logger, trQ
 
 class EventHandler(QObject):
   """ Handle the right-click properly so that it only triggers the contextual menu """
@@ -201,7 +201,7 @@ class XYView(View):
     self._toolbar = self._plotWidget.toolBar
     self.populateToolbar()
 
-    self._popupMenu = QtGui.QMenu()
+    self._popupMenu = QtWidgets.QMenu()
     self._popupMenu.addAction(self._actionLegend)
 
     # Connect evenement for the graphic scene
@@ -227,7 +227,7 @@ class XYView(View):
     self._panAction.setCheckable(True)
     self._toolbar.addSeparator()
     # Actions to change the representation of curves
-    self._curveActionGroup = QtGui.QActionGroup(self._plotWidget)
+    self._curveActionGroup = QtWidgets.QActionGroup(self._plotWidget)
     self._pointsAction = self.createAndAddLocalAction("draw_points.png", trQ("DRAW_POINTS_TXT"))
     self._pointsAction.setCheckable(True)
     self._linesAction = self.createAndAddLocalAction("draw_lines.png", trQ("DRAW_LINES_TXT"))
@@ -239,7 +239,7 @@ class XYView(View):
     self._curveActionGroup.setExclusive(True)
     self._toolbar.addSeparator()
     # Actions to draw horizontal curves as linear or logarithmic
-    self._horActionGroup = QtGui.QActionGroup(self._plotWidget)
+    self._horActionGroup = QtWidgets.QActionGroup(self._plotWidget)
     self._horLinearAction = self.createAndAddLocalAction("hor_linear.png", trQ("HOR_LINEAR_TXT"))
     self._horLinearAction.setCheckable(True)
     self._horLogarithmicAction = self.createAndAddLocalAction("hor_logarithmic.png", trQ("HOR_LOGARITHMIC_TXT"))
@@ -250,7 +250,7 @@ class XYView(View):
     self._horActionGroup.triggered.connect(self.onViewHorizontalMode)
     self._toolbar.addSeparator()
     # Actions to draw vertical curves as linear or logarithmic
-    self._verActionGroup = QtGui.QActionGroup(self._plotWidget)
+    self._verActionGroup = QtWidgets.QActionGroup(self._plotWidget)
     self._verLinearAction = self.createAndAddLocalAction("ver_linear.png", trQ("VER_LINEAR_TXT"))
     self._verLinearAction.setCheckable(True)
     self._verLogarithmicAction = self.createAndAddLocalAction("ver_logarithmic.png", trQ("VER_LOGARITHMIC_TXT"))
@@ -289,12 +289,14 @@ class XYView(View):
     pass
 
   def autoFit(self, check=True, repaint=True):
+    import numpy as np
     if self.__repaintOK():
       self._mplAxes.relim()
       xm, xM = self._mplAxes.xaxis.get_data_interval()
       ym, yM = self._mplAxes.yaxis.get_data_interval()
       i = yM-ym
-      self._mplAxes.axis([xm, xM, ym-i*self.AUTOFIT_MARGIN, yM+i*self.AUTOFIT_MARGIN])
+      if np.isfinite(xm) and np.isfinite(xM) and np.isfinite(ym) and np.isfinite(yM):
+        self._mplAxes.axis([xm, xM, ym-i*self.AUTOFIT_MARGIN, yM+i*self.AUTOFIT_MARGIN])
       if repaint:
         self.repaint()
 
@@ -501,7 +503,7 @@ class XYView(View):
       dlg.colorCurve.setEnabled(True)
       dlg.markerCurve.setEnabled(True)
       name = curr_crv.getTitle()
-      dlg.nameCurve.setText(name)
+      dlg.setSelectedCurveName(name)
       view = self._curveViews[curr_crv.getID()]
       marker = view.getMarker()
       color = view.getColor()
@@ -512,7 +514,7 @@ class XYView(View):
     else :
       dlg.colorCurve.setEnabled(False)
       dlg.markerCurve.setEnabled(False)
-      dlg.nameCurve.setText("")
+      dlg.setSelectedCurveName("")
       view = None
     if self._legend is None:
       dlg.showLegendCheckBox.setChecked(False)
@@ -561,6 +563,10 @@ class XYView(View):
       if view:
         view.setColor(dlg.getRGB())
         view.setMarker(self.CURVE_MARKERS[dlg.markerCurve.currentIndex()])
+        crvModel = view._model
+        if dlg.nameCurve.text() != crvModel.getTitle():
+          Logger.Debug("XYView : about to cahnge crv title after settings")
+          view._model.setTitle(dlg.nameCurve.text())
       self.showHideLegend(repaint=True)
       self._mplCanvas.draw()
     pass
@@ -577,6 +583,7 @@ class XYView(View):
     pass
 
   def onCurrentCurveChange(self):
+    Logger.Debug("XYView::onCurrentCurveChange()")
     curr_crv2 = self._model.getCurrentCurve()
     if curr_crv2 != self._currCrv:
       if self._currCrv is not None:
@@ -628,7 +635,7 @@ class XYView(View):
 
     if not len(self._curveViews):
       # Reset color cycle
-      self._mplAxes.set_color_cycle(None)
+      self._mplAxes.set_prop_cycle(None)
 
     for a in added:
       self.appendCurve(a)
@@ -645,7 +652,8 @@ class XYView(View):
     self.changeFormatAxis()
 
     # Redo auto-fit
-    self.autoFit(repaint=False)
+    if len(self._curveViews):
+      self.autoFit(repaint=False)
     self.repaint()
 
   def onDataChange(self):