From 366e73658adc5b049d8a13b7f00f0201af816b4c Mon Sep 17 00:00:00 2001 From: admin Date: Fri, 5 Nov 2004 12:56:39 +0000 Subject: [PATCH] This commit was generated by cvs2git to create branch 'PRAS_br3'. Cherrypick from master 2004-11-05 12:56:36 UTC prascle 'PR: mergefrom_BR_GEAY_05Nov04': examples/fedges.unv idl/SALOME_Comm.idl make_config.in salome_adm/unix/config.h.in salome_adm/unix/config_files/check_lam.m4 salome_adm/unix/config_files/check_openpbs.m4 salome_adm/unix/config_files/check_sockets.m4 src/Batch/Batch_APIInternalFailureException.cxx src/Batch/Batch_APIInternalFailureException.hxx src/Batch/Batch_BatchManager.cxx src/Batch/Batch_BatchManager.hxx src/Batch/Batch_BatchManagerCatalog.cxx src/Batch/Batch_BatchManagerCatalog.hxx src/Batch/Batch_BatchManager_PBS.cxx src/Batch/Batch_BatchManager_PBS.hxx src/Batch/Batch_BoolType.cxx src/Batch/Batch_BoolType.hxx src/Batch/Batch_CharType.cxx src/Batch/Batch_CharType.hxx src/Batch/Batch_ConnexionFailureException.cxx src/Batch/Batch_ConnexionFailureException.hxx src/Batch/Batch_Couple.cxx src/Batch/Batch_Couple.hxx src/Batch/Batch_CoupleType.cxx src/Batch/Batch_CoupleType.hxx src/Batch/Batch_Date.cxx src/Batch/Batch_Date.hxx src/Batch/Batch_DateType.cxx src/Batch/Batch_DateType.hxx src/Batch/Batch_Environnement.cxx src/Batch/Batch_Environnement.hxx src/Batch/Batch_FactBatchManager.cxx src/Batch/Batch_FactBatchManager.hxx src/Batch/Batch_FactBatchManager_PBS.cxx src/Batch/Batch_FactBatchManager_PBS.hxx src/Batch/Batch_GenericException.cxx src/Batch/Batch_GenericException.hxx src/Batch/Batch_GenericType.cxx src/Batch/Batch_GenericType.hxx src/Batch/Batch_IntType.cxx src/Batch/Batch_IntType.hxx src/Batch/Batch_InvalidArgumentException.cxx src/Batch/Batch_InvalidArgumentException.hxx src/Batch/Batch_InvalidKeyException.cxx src/Batch/Batch_InvalidKeyException.hxx src/Batch/Batch_Job.cxx src/Batch/Batch_Job.hxx src/Batch/Batch_JobId.cxx src/Batch/Batch_JobId.hxx src/Batch/Batch_JobInfo.cxx src/Batch/Batch_JobInfo.hxx src/Batch/Batch_JobInfo_PBS.cxx src/Batch/Batch_JobInfo_PBS.hxx src/Batch/Batch_Job_PBS.cxx src/Batch/Batch_Job_PBS.hxx src/Batch/Batch_ListIsFullException.cxx src/Batch/Batch_ListIsFullException.hxx src/Batch/Batch_LongType.cxx src/Batch/Batch_LongType.hxx src/Batch/Batch_MapKey.cxx src/Batch/Batch_MapKey.hxx src/Batch/Batch_NotYetImplementedException.cxx src/Batch/Batch_NotYetImplementedException.hxx src/Batch/Batch_Parametre.cxx src/Batch/Batch_Parametre.hxx src/Batch/Batch_PyVersatile.cxx src/Batch/Batch_PyVersatile.hxx src/Batch/Batch_RunTimeException.cxx src/Batch/Batch_RunTimeException.hxx src/Batch/Batch_StringType.cxx src/Batch/Batch_StringType.hxx src/Batch/Batch_TypeMismatchException.cxx src/Batch/Batch_TypeMismatchException.hxx src/Batch/Batch_Versatile.cxx src/Batch/Batch_Versatile.hxx src/Batch/Makefile.in src/Batch_SWIG/Batch_test.py src/Batch_SWIG/Makefile.in src/Batch_SWIG/libBatch_Swig.i src/Batch_SWIG/libBatch_Swig_exception.i src/Batch_SWIG/libBatch_Swig_typemap.i src/CASCatch/CASCatch_SignalsHandler.cxx src/CASCatch/CASCatch_SignalsHandler.h src/CASCatch/Makefile.in src/Communication/Makefile.in src/Communication/MultiCommException.cxx src/Communication/MultiCommException.hxx src/Communication/Receiver.cxx src/Communication/Receiver.hxx src/Communication/ReceiverFactory.cxx src/Communication/ReceiverFactory.hxx src/Communication/Receivers.cxx src/Communication/Receivers.hxx src/Communication/SALOMEMultiComm.cxx src/Communication/SALOMEMultiComm.hxx src/Communication/SALOME_Comm_i.cxx src/Communication/SALOME_Comm_i.hxx src/Communication/SenderFactory.cxx src/Communication/SenderFactory.hxx src/Container/SALOME_Container_SignalsHandler.cxx src/MSG2QM/LICENSE.QPL src/MSG2QM/README src/OCCViewer/OCCViewer_Prs.cxx src/OCCViewer/OCCViewer_Prs.h src/PatchQt/LICENSE.QPL src/PatchQt/README src/PatchQt/qfiledialogP.cxx src/PatchQt/qfiledialogP.h src/Plot2d/Plot2d_Prs.cxx src/Plot2d/Plot2d_Prs.h src/Prs/Makefile.in src/Prs/SALOME_Prs.cxx src/Prs/SALOME_Prs.h src/Session/SALOME_Session_SignalsHandler.cxx src/Utils/Utils_SignalsHandler.cxx src/Utils/Utils_SignalsHandler.h src/VTKFilter/SALOME_ShrinkFilter.cxx src/VTKFilter/SALOME_ShrinkFilter.h src/VTKViewer/VTKViewer_Actor.cxx src/VTKViewer/VTKViewer_Actor.h src/VTKViewer/VTKViewer_Algorithm.h src/VTKViewer/VTKViewer_Functor.h src/VTKViewer/VTKViewer_Prs.cxx src/VTKViewer/VTKViewer_Prs.h --- examples/fedges.unv | 2926 ++++++++ idl/SALOME_Comm.idl | 81 + make_config.in | 75 + salome_adm/unix/config.h.in | 350 + salome_adm/unix/config_files/check_lam.m4 | 74 + salome_adm/unix/config_files/check_openpbs.m4 | 57 + salome_adm/unix/config_files/check_sockets.m4 | 86 + .../Batch_APIInternalFailureException.cxx | 15 + .../Batch_APIInternalFailureException.hxx | 29 + src/Batch/Batch_BatchManager.cxx | 122 + src/Batch/Batch_BatchManager.hxx | 62 + src/Batch/Batch_BatchManagerCatalog.cxx | 73 + src/Batch/Batch_BatchManagerCatalog.hxx | 47 + src/Batch/Batch_BatchManager_PBS.cxx | 194 + src/Batch/Batch_BatchManager_PBS.hxx | 76 + src/Batch/Batch_BoolType.cxx | 43 + src/Batch/Batch_BoolType.hxx | 47 + src/Batch/Batch_CharType.cxx | 43 + src/Batch/Batch_CharType.hxx | 48 + src/Batch/Batch_ConnexionFailureException.cxx | 15 + src/Batch/Batch_ConnexionFailureException.hxx | 30 + src/Batch/Batch_Couple.cxx | 41 + src/Batch/Batch_Couple.hxx | 52 + src/Batch/Batch_CoupleType.cxx | 50 + src/Batch/Batch_CoupleType.hxx | 50 + src/Batch/Batch_Date.cxx | 169 + src/Batch/Batch_Date.hxx | 45 + src/Batch/Batch_DateType.cxx | 51 + src/Batch/Batch_DateType.hxx | 52 + src/Batch/Batch_Environnement.cxx | 16 + src/Batch/Batch_Environnement.hxx | 26 + src/Batch/Batch_FactBatchManager.cxx | 46 + src/Batch/Batch_FactBatchManager.hxx | 41 + src/Batch/Batch_FactBatchManager_PBS.cxx | 39 + src/Batch/Batch_FactBatchManager_PBS.hxx | 39 + src/Batch/Batch_GenericException.cxx | 15 + src/Batch/Batch_GenericException.hxx | 32 + src/Batch/Batch_GenericType.cxx | 42 + src/Batch/Batch_GenericType.hxx | 50 + src/Batch/Batch_IntType.cxx | 49 + src/Batch/Batch_IntType.hxx | 47 + src/Batch/Batch_InvalidArgumentException.cxx | 15 + src/Batch/Batch_InvalidArgumentException.hxx | 30 + src/Batch/Batch_InvalidKeyException.cxx | 16 + src/Batch/Batch_InvalidKeyException.hxx | 35 + src/Batch/Batch_Job.cxx | 95 + src/Batch/Batch_Job.hxx | 55 + src/Batch/Batch_JobId.cxx | 114 + src/Batch/Batch_JobId.hxx | 68 + src/Batch/Batch_JobInfo.cxx | 73 + src/Batch/Batch_JobInfo.hxx | 54 + src/Batch/Batch_JobInfo_PBS.cxx | 176 + src/Batch/Batch_JobInfo_PBS.hxx | 51 + src/Batch/Batch_Job_PBS.cxx | 450 ++ src/Batch/Batch_Job_PBS.hxx | 75 + src/Batch/Batch_ListIsFullException.cxx | 15 + src/Batch/Batch_ListIsFullException.hxx | 27 + src/Batch/Batch_LongType.cxx | 48 + src/Batch/Batch_LongType.hxx | 47 + src/Batch/Batch_MapKey.cxx | 20 + src/Batch/Batch_MapKey.hxx | 47 + .../Batch_NotYetImplementedException.cxx | 16 + .../Batch_NotYetImplementedException.hxx | 29 + src/Batch/Batch_Parametre.cxx | 248 + src/Batch/Batch_Parametre.hxx | 126 + src/Batch/Batch_PyVersatile.cxx | 179 + src/Batch/Batch_PyVersatile.hxx | 46 + src/Batch/Batch_RunTimeException.cxx | 15 + src/Batch/Batch_RunTimeException.hxx | 28 + src/Batch/Batch_StringType.cxx | 43 + src/Batch/Batch_StringType.hxx | 45 + src/Batch/Batch_TypeMismatchException.cxx | 14 + src/Batch/Batch_TypeMismatchException.hxx | 28 + src/Batch/Batch_Versatile.cxx | 300 + src/Batch/Batch_Versatile.hxx | 101 + src/Batch/Makefile.in | 130 + src/Batch_SWIG/Batch_test.py | 53 + src/Batch_SWIG/Makefile.in | 49 + src/Batch_SWIG/libBatch_Swig.i | 59 + src/Batch_SWIG/libBatch_Swig_exception.i | 24 + src/Batch_SWIG/libBatch_Swig_typemap.i | 213 + src/CASCatch/CASCatch_SignalsHandler.cxx | 29 + src/CASCatch/CASCatch_SignalsHandler.h | 34 + src/CASCatch/Makefile.in | 50 + src/Communication/Makefile.in | 34 + src/Communication/MultiCommException.cxx | 11 + src/Communication/MultiCommException.hxx | 17 + src/Communication/Receiver.cxx | 25 + src/Communication/Receiver.hxx | 20 + src/Communication/ReceiverFactory.cxx | 138 + src/Communication/ReceiverFactory.hxx | 21 + src/Communication/Receivers.cxx | 390 ++ src/Communication/Receivers.hxx | 121 + src/Communication/SALOMEMultiComm.cxx | 21 + src/Communication/SALOMEMultiComm.hxx | 21 + src/Communication/SALOME_Comm_i.cxx | 483 ++ src/Communication/SALOME_Comm_i.hxx | 162 + src/Communication/SenderFactory.cxx | 98 + src/Communication/SenderFactory.hxx | 24 + .../SALOME_Container_SignalsHandler.cxx | 36 + src/MSG2QM/LICENSE.QPL | 103 + src/MSG2QM/README | 3 + src/OCCViewer/OCCViewer_Prs.cxx | 112 + src/OCCViewer/OCCViewer_Prs.h | 69 + src/PatchQt/LICENSE.QPL | 103 + src/PatchQt/README | 2 + src/PatchQt/qfiledialogP.cxx | 5978 +++++++++++++++++ src/PatchQt/qfiledialogP.h | 528 ++ src/Plot2d/Plot2d_Prs.cxx | 95 + src/Plot2d/Plot2d_Prs.h | 59 + src/Prs/Makefile.in | 27 + src/Prs/SALOME_Prs.cxx | 364 + src/Prs/SALOME_Prs.h | 255 + src/Session/SALOME_Session_SignalsHandler.cxx | 38 + src/Utils/Utils_SignalsHandler.cxx | 119 + src/Utils/Utils_SignalsHandler.h | 49 + src/VTKFilter/SALOME_ShrinkFilter.cxx | 176 + src/VTKFilter/SALOME_ShrinkFilter.h | 61 + src/VTKViewer/VTKViewer_Actor.cxx | 233 + src/VTKViewer/VTKViewer_Actor.h | 64 + src/VTKViewer/VTKViewer_Algorithm.h | 83 + src/VTKViewer/VTKViewer_Functor.h | 98 + src/VTKViewer/VTKViewer_Prs.cxx | 97 + src/VTKViewer/VTKViewer_Prs.h | 58 + 124 files changed, 19211 insertions(+) create mode 100644 examples/fedges.unv create mode 100644 idl/SALOME_Comm.idl create mode 100755 make_config.in create mode 100755 salome_adm/unix/config.h.in create mode 100644 salome_adm/unix/config_files/check_lam.m4 create mode 100644 salome_adm/unix/config_files/check_openpbs.m4 create mode 100644 salome_adm/unix/config_files/check_sockets.m4 create mode 100644 src/Batch/Batch_APIInternalFailureException.cxx create mode 100644 src/Batch/Batch_APIInternalFailureException.hxx create mode 100644 src/Batch/Batch_BatchManager.cxx create mode 100644 src/Batch/Batch_BatchManager.hxx create mode 100644 src/Batch/Batch_BatchManagerCatalog.cxx create mode 100644 src/Batch/Batch_BatchManagerCatalog.hxx create mode 100644 src/Batch/Batch_BatchManager_PBS.cxx create mode 100644 src/Batch/Batch_BatchManager_PBS.hxx create mode 100644 src/Batch/Batch_BoolType.cxx create mode 100644 src/Batch/Batch_BoolType.hxx create mode 100644 src/Batch/Batch_CharType.cxx create mode 100644 src/Batch/Batch_CharType.hxx create mode 100644 src/Batch/Batch_ConnexionFailureException.cxx create mode 100644 src/Batch/Batch_ConnexionFailureException.hxx create mode 100644 src/Batch/Batch_Couple.cxx create mode 100644 src/Batch/Batch_Couple.hxx create mode 100644 src/Batch/Batch_CoupleType.cxx create mode 100644 src/Batch/Batch_CoupleType.hxx create mode 100644 src/Batch/Batch_Date.cxx create mode 100644 src/Batch/Batch_Date.hxx create mode 100644 src/Batch/Batch_DateType.cxx create mode 100644 src/Batch/Batch_DateType.hxx create mode 100644 src/Batch/Batch_Environnement.cxx create mode 100644 src/Batch/Batch_Environnement.hxx create mode 100644 src/Batch/Batch_FactBatchManager.cxx create mode 100644 src/Batch/Batch_FactBatchManager.hxx create mode 100644 src/Batch/Batch_FactBatchManager_PBS.cxx create mode 100644 src/Batch/Batch_FactBatchManager_PBS.hxx create mode 100644 src/Batch/Batch_GenericException.cxx create mode 100644 src/Batch/Batch_GenericException.hxx create mode 100644 src/Batch/Batch_GenericType.cxx create mode 100644 src/Batch/Batch_GenericType.hxx create mode 100644 src/Batch/Batch_IntType.cxx create mode 100644 src/Batch/Batch_IntType.hxx create mode 100644 src/Batch/Batch_InvalidArgumentException.cxx create mode 100644 src/Batch/Batch_InvalidArgumentException.hxx create mode 100644 src/Batch/Batch_InvalidKeyException.cxx create mode 100644 src/Batch/Batch_InvalidKeyException.hxx create mode 100644 src/Batch/Batch_Job.cxx create mode 100644 src/Batch/Batch_Job.hxx create mode 100644 src/Batch/Batch_JobId.cxx create mode 100644 src/Batch/Batch_JobId.hxx create mode 100644 src/Batch/Batch_JobInfo.cxx create mode 100644 src/Batch/Batch_JobInfo.hxx create mode 100644 src/Batch/Batch_JobInfo_PBS.cxx create mode 100644 src/Batch/Batch_JobInfo_PBS.hxx create mode 100644 src/Batch/Batch_Job_PBS.cxx create mode 100644 src/Batch/Batch_Job_PBS.hxx create mode 100644 src/Batch/Batch_ListIsFullException.cxx create mode 100644 src/Batch/Batch_ListIsFullException.hxx create mode 100644 src/Batch/Batch_LongType.cxx create mode 100644 src/Batch/Batch_LongType.hxx create mode 100644 src/Batch/Batch_MapKey.cxx create mode 100644 src/Batch/Batch_MapKey.hxx create mode 100644 src/Batch/Batch_NotYetImplementedException.cxx create mode 100644 src/Batch/Batch_NotYetImplementedException.hxx create mode 100644 src/Batch/Batch_Parametre.cxx create mode 100644 src/Batch/Batch_Parametre.hxx create mode 100644 src/Batch/Batch_PyVersatile.cxx create mode 100644 src/Batch/Batch_PyVersatile.hxx create mode 100644 src/Batch/Batch_RunTimeException.cxx create mode 100644 src/Batch/Batch_RunTimeException.hxx create mode 100644 src/Batch/Batch_StringType.cxx create mode 100644 src/Batch/Batch_StringType.hxx create mode 100644 src/Batch/Batch_TypeMismatchException.cxx create mode 100644 src/Batch/Batch_TypeMismatchException.hxx create mode 100644 src/Batch/Batch_Versatile.cxx create mode 100644 src/Batch/Batch_Versatile.hxx create mode 100644 src/Batch/Makefile.in create mode 100644 src/Batch_SWIG/Batch_test.py create mode 100644 src/Batch_SWIG/Makefile.in create mode 100644 src/Batch_SWIG/libBatch_Swig.i create mode 100644 src/Batch_SWIG/libBatch_Swig_exception.i create mode 100644 src/Batch_SWIG/libBatch_Swig_typemap.i create mode 100644 src/CASCatch/CASCatch_SignalsHandler.cxx create mode 100644 src/CASCatch/CASCatch_SignalsHandler.h create mode 100644 src/CASCatch/Makefile.in create mode 100644 src/Communication/Makefile.in create mode 100644 src/Communication/MultiCommException.cxx create mode 100644 src/Communication/MultiCommException.hxx create mode 100644 src/Communication/Receiver.cxx create mode 100644 src/Communication/Receiver.hxx create mode 100644 src/Communication/ReceiverFactory.cxx create mode 100644 src/Communication/ReceiverFactory.hxx create mode 100644 src/Communication/Receivers.cxx create mode 100644 src/Communication/Receivers.hxx create mode 100644 src/Communication/SALOMEMultiComm.cxx create mode 100644 src/Communication/SALOMEMultiComm.hxx create mode 100644 src/Communication/SALOME_Comm_i.cxx create mode 100644 src/Communication/SALOME_Comm_i.hxx create mode 100644 src/Communication/SenderFactory.cxx create mode 100644 src/Communication/SenderFactory.hxx create mode 100644 src/Container/SALOME_Container_SignalsHandler.cxx create mode 100644 src/MSG2QM/LICENSE.QPL create mode 100644 src/MSG2QM/README create mode 100644 src/OCCViewer/OCCViewer_Prs.cxx create mode 100644 src/OCCViewer/OCCViewer_Prs.h create mode 100644 src/PatchQt/LICENSE.QPL create mode 100644 src/PatchQt/README create mode 100644 src/PatchQt/qfiledialogP.cxx create mode 100644 src/PatchQt/qfiledialogP.h create mode 100644 src/Plot2d/Plot2d_Prs.cxx create mode 100644 src/Plot2d/Plot2d_Prs.h create mode 100755 src/Prs/Makefile.in create mode 100644 src/Prs/SALOME_Prs.cxx create mode 100644 src/Prs/SALOME_Prs.h create mode 100644 src/Session/SALOME_Session_SignalsHandler.cxx create mode 100644 src/Utils/Utils_SignalsHandler.cxx create mode 100644 src/Utils/Utils_SignalsHandler.h create mode 100644 src/VTKFilter/SALOME_ShrinkFilter.cxx create mode 100644 src/VTKFilter/SALOME_ShrinkFilter.h create mode 100644 src/VTKViewer/VTKViewer_Actor.cxx create mode 100644 src/VTKViewer/VTKViewer_Actor.h create mode 100644 src/VTKViewer/VTKViewer_Algorithm.h create mode 100644 src/VTKViewer/VTKViewer_Functor.h create mode 100644 src/VTKViewer/VTKViewer_Prs.cxx create mode 100644 src/VTKViewer/VTKViewer_Prs.h diff --git a/examples/fedges.unv b/examples/fedges.unv new file mode 100644 index 000000000..d2c47a388 --- /dev/null +++ b/examples/fedges.unv @@ -0,0 +1,2926 @@ + -1 + 2411 + 1 0 0 0 + 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 + 2 0 0 0 + 0.0000000000000000E+00 -2.3999999999999999E+00 0.0000000000000000E+00 + 3 0 0 0 + 0.0000000000000000E+00 -4.0000000000000000E+00 0.0000000000000000E+00 + 4 0 0 0 + 0.0000000000000000E+00 -5.5999999999999996E+00 0.0000000000000000E+00 + 5 0 0 0 + 0.0000000000000000E+00 -8.0000000000000000E+00 0.0000000000000000E+00 + 6 0 0 0 + 0.0000000000000000E+00 -1.0400000000000000E+01 0.0000000000000000E+00 + 7 0 0 0 + 0.0000000000000000E+00 -1.2000000000000000E+01 0.0000000000000000E+00 + 8 0 0 0 + 0.0000000000000000E+00 -1.4350000000000000E+01 0.0000000000000000E+00 + 9 0 0 0 + 0.0000000000000000E+00 -1.5500000000000000E+01 5.0000000000000000E-01 + 10 0 0 0 + 0.0000000000000000E+00 -1.6129999999999999E+01 1.7000000000000000E+00 + 11 0 0 0 + 0.0000000000000000E+00 -1.6129999999999999E+01 3.3500000000000001E+00 + 12 0 0 0 + 0.0000000000000000E+00 -1.6129999999999999E+01 4.9500000000000002E+00 + 13 0 0 0 + 0.0000000000000000E+00 -1.6129999999999999E+01 7.1550000000000002E+00 + 14 0 0 0 + 0.0000000000000000E+00 -1.6129999999999999E+01 9.3599999999999994E+00 + 15 0 0 0 + 0.0000000000000000E+00 -1.6129999999999999E+01 1.2359999999999999E+01 + 16 0 0 0 + 0.0000000000000000E+00 -1.6129999999999999E+01 1.5359999999999999E+01 + 17 0 0 0 + 0.0000000000000000E+00 -1.6129999999999999E+01 1.7609999999999999E+01 + 18 0 0 0 + 0.0000000000000000E+00 -1.6129999999999999E+01 1.8969999999999999E+01 + 19 0 0 0 + 0.0000000000000000E+00 -1.6129999999999999E+01 2.0800000000000001E+01 + 20 0 0 0 + 0.0000000000000000E+00 -2.3999999999999999E+00 2.1449999999999999E+01 + 21 0 0 0 + 0.0000000000000000E+00 -4.0000000000000000E+00 2.1449999999999999E+01 + 22 0 0 0 + 0.0000000000000000E+00 -5.5999999999999996E+00 2.1366000000000000E+01 + 23 0 0 0 + 0.0000000000000000E+00 -8.0000000000000000E+00 2.1239000000000001E+01 + 24 0 0 0 + 0.0000000000000000E+00 -1.0400000000000000E+01 2.1111999999999998E+01 + 25 0 0 0 + 0.0000000000000000E+00 -1.2000000000000000E+01 2.1027999999999999E+01 + 26 0 0 0 + 0.0000000000000000E+00 -1.4130000000000001E+01 2.0916000000000000E+01 + 27 0 0 0 + 0.0000000000000000E+00 0.0000000000000000E+00 2.0000000000000000E+00 + 28 0 0 0 + 0.0000000000000000E+00 0.0000000000000000E+00 1.8969999999999999E+01 + 29 0 0 0 + 0.0000000000000000E+00 -2.3999999999999999E+00 2.0000000000000000E+00 + 30 0 0 0 + 0.0000000000000000E+00 -4.0000000000000000E+00 2.0000000000000000E+00 + 31 0 0 0 + 0.0000000000000000E+00 -5.5999999999999996E+00 2.0000000000000000E+00 + 32 0 0 0 + 0.0000000000000000E+00 -8.0000000000000000E+00 2.0000000000000000E+00 + 33 0 0 0 + 0.0000000000000000E+00 -1.0400000000000000E+01 2.0000000000000000E+00 + 34 0 0 0 + 0.0000000000000000E+00 -1.2000000000000000E+01 2.0000000000000000E+00 + 35 0 0 0 + 0.0000000000000000E+00 -1.2877000000000001E+01 3.2160000000000002E+00 + 36 0 0 0 + 0.0000000000000000E+00 -1.4130000000000001E+01 4.9500000000000002E+00 + 37 0 0 0 + 0.0000000000000000E+00 -1.4130000000000001E+01 7.1550000000000002E+00 + 38 0 0 0 + 0.0000000000000000E+00 -1.4130000000000001E+01 9.3599999999999994E+00 + 39 0 0 0 + 0.0000000000000000E+00 -1.4130000000000001E+01 1.2359999999999999E+01 + 40 0 0 0 + 0.0000000000000000E+00 -1.4130000000000001E+01 1.5359999999999999E+01 + 41 0 0 0 + 0.0000000000000000E+00 -1.4130000000000001E+01 1.7609999999999999E+01 + 42 0 0 0 + 0.0000000000000000E+00 -1.4130000000000001E+01 1.8969999999999999E+01 + 43 0 0 0 + 0.0000000000000000E+00 -1.3600000000000000E+01 2.0000000000000000E+00 + 44 0 0 0 + 0.0000000000000000E+00 -1.5199999999999999E+01 3.8500000000000001E+00 + 45 0 0 0 + 0.0000000000000000E+00 -1.4500000000000000E+01 3.8500000000000001E+00 + 46 0 0 0 + 0.0000000000000000E+00 -1.4150000000000000E+01 3.1040000000000001E+00 + 47 0 0 0 + 0.0000000000000000E+00 -1.5199999999999999E+01 2.0000000000000000E+00 + 48 0 0 0 + 0.0000000000000000E+00 0.0000000000000000E+00 3.6600000000000001E+00 + 49 0 0 0 + 0.0000000000000000E+00 0.0000000000000000E+00 4.9500000000000002E+00 + 50 0 0 0 + 0.0000000000000000E+00 -2.3999999999999999E+00 3.0000000000000000E+00 + 51 0 0 0 + 0.0000000000000000E+00 -4.0000000000000000E+00 2.7999999999999998E+00 + 52 0 0 0 + 0.0000000000000000E+00 0.0000000000000000E+00 1.7609999999999999E+01 + 53 0 0 0 + 0.0000000000000000E+00 2.3999999999999999E+00 0.0000000000000000E+00 + 54 0 0 0 + 0.0000000000000000E+00 4.0000000000000000E+00 0.0000000000000000E+00 + 55 0 0 0 + 0.0000000000000000E+00 5.5999999999999996E+00 0.0000000000000000E+00 + 56 0 0 0 + 0.0000000000000000E+00 8.0000000000000000E+00 0.0000000000000000E+00 + 57 0 0 0 + 0.0000000000000000E+00 1.0400000000000000E+01 0.0000000000000000E+00 + 58 0 0 0 + 0.0000000000000000E+00 1.2000000000000000E+01 0.0000000000000000E+00 + 59 0 0 0 + 0.0000000000000000E+00 1.4350000000000000E+01 0.0000000000000000E+00 + 60 0 0 0 + 0.0000000000000000E+00 1.5500000000000000E+01 5.0000000000000000E-01 + 61 0 0 0 + 0.0000000000000000E+00 1.6129999999999999E+01 1.7000000000000000E+00 + 62 0 0 0 + 0.0000000000000000E+00 1.6129999999999999E+01 3.3500000000000001E+00 + 63 0 0 0 + 0.0000000000000000E+00 1.6129999999999999E+01 4.9500000000000002E+00 + 64 0 0 0 + 0.0000000000000000E+00 1.6129999999999999E+01 7.1550000000000002E+00 + 65 0 0 0 + 0.0000000000000000E+00 1.6129999999999999E+01 9.3599999999999994E+00 + 66 0 0 0 + 0.0000000000000000E+00 1.6129999999999999E+01 1.2359999999999999E+01 + 67 0 0 0 + 0.0000000000000000E+00 1.6129999999999999E+01 1.5359999999999999E+01 + 68 0 0 0 + 0.0000000000000000E+00 1.6129999999999999E+01 1.7609999999999999E+01 + 69 0 0 0 + 0.0000000000000000E+00 1.6129999999999999E+01 1.8969999999999999E+01 + 70 0 0 0 + 0.0000000000000000E+00 1.6129999999999999E+01 2.0800000000000001E+01 + 71 0 0 0 + 0.0000000000000000E+00 0.0000000000000000E+00 2.1449999999999999E+01 + 72 0 0 0 + 0.0000000000000000E+00 2.3999999999999999E+00 2.1449999999999999E+01 + 73 0 0 0 + 0.0000000000000000E+00 4.0000000000000000E+00 2.1449999999999999E+01 + 74 0 0 0 + 0.0000000000000000E+00 5.5999999999999996E+00 2.1366000000000000E+01 + 75 0 0 0 + 0.0000000000000000E+00 8.0000000000000000E+00 2.1239000000000001E+01 + 76 0 0 0 + 0.0000000000000000E+00 1.0400000000000000E+01 2.1111999999999998E+01 + 77 0 0 0 + 0.0000000000000000E+00 1.2000000000000000E+01 2.1027999999999999E+01 + 78 0 0 0 + 0.0000000000000000E+00 1.4130000000000001E+01 2.0916000000000000E+01 + 79 0 0 0 + 0.0000000000000000E+00 2.3999999999999999E+00 2.0000000000000000E+00 + 80 0 0 0 + 0.0000000000000000E+00 4.0000000000000000E+00 2.0000000000000000E+00 + 81 0 0 0 + 0.0000000000000000E+00 5.5999999999999996E+00 2.0000000000000000E+00 + 82 0 0 0 + 0.0000000000000000E+00 8.0000000000000000E+00 2.0000000000000000E+00 + 83 0 0 0 + 0.0000000000000000E+00 1.0400000000000000E+01 2.0000000000000000E+00 + 84 0 0 0 + 0.0000000000000000E+00 1.2000000000000000E+01 2.0000000000000000E+00 + 85 0 0 0 + 0.0000000000000000E+00 1.2877000000000001E+01 3.2160000000000002E+00 + 86 0 0 0 + 0.0000000000000000E+00 1.4130000000000001E+01 4.9500000000000002E+00 + 87 0 0 0 + 0.0000000000000000E+00 1.4130000000000001E+01 7.1550000000000002E+00 + 88 0 0 0 + 0.0000000000000000E+00 1.4130000000000001E+01 9.3599999999999994E+00 + 89 0 0 0 + 0.0000000000000000E+00 1.4130000000000001E+01 1.2359999999999999E+01 + 90 0 0 0 + 0.0000000000000000E+00 1.4130000000000001E+01 1.5359999999999999E+01 + 91 0 0 0 + 0.0000000000000000E+00 1.4130000000000001E+01 1.7609999999999999E+01 + 92 0 0 0 + 0.0000000000000000E+00 1.4130000000000001E+01 1.8969999999999999E+01 + 93 0 0 0 + 0.0000000000000000E+00 1.3600000000000000E+01 2.0000000000000000E+00 + 94 0 0 0 + 0.0000000000000000E+00 1.5199999999999999E+01 3.8500000000000001E+00 + 95 0 0 0 + 0.0000000000000000E+00 1.4500000000000000E+01 3.8500000000000001E+00 + 96 0 0 0 + 0.0000000000000000E+00 1.4150000000000000E+01 3.1040000000000001E+00 + 97 0 0 0 + 0.0000000000000000E+00 1.5199999999999999E+01 2.0000000000000000E+00 + 98 0 0 0 + 0.0000000000000000E+00 2.3999999999999999E+00 3.6600000000000001E+00 + 99 0 0 0 + 0.0000000000000000E+00 2.3999999999999999E+00 4.9500000000000002E+00 + 100 0 0 0 + 0.0000000000000000E+00 4.0000000000000000E+00 3.0000000000000000E+00 + 101 0 0 0 + 0.0000000000000000E+00 0.0000000000000000E+00 7.1550000000000002E+00 + 102 0 0 0 + 0.0000000000000000E+00 0.0000000000000000E+00 9.3599999999999994E+00 + 103 0 0 0 + 0.0000000000000000E+00 0.0000000000000000E+00 1.2359999999999999E+01 + 104 0 0 0 + 0.0000000000000000E+00 0.0000000000000000E+00 1.5359999999999999E+01 + 105 0 0 0 + 0.0000000000000000E+00 2.3999999999999999E+00 7.1550000000000002E+00 + 106 0 0 0 + 0.0000000000000000E+00 2.3999999999999999E+00 9.3599999999999994E+00 + 107 0 0 0 + 0.0000000000000000E+00 2.3999999999999999E+00 1.2359999999999999E+01 + 108 0 0 0 + 0.0000000000000000E+00 2.3999999999999999E+00 1.5359999999999999E+01 + 109 0 0 0 + 0.0000000000000000E+00 2.3999999999999999E+00 1.7609999999999999E+01 + 110 0 0 0 + 0.0000000000000000E+00 -1.2000000000000000E+01 3.2149999999999999E+00 + 111 0 0 0 + 0.0000000000000000E+00 -5.5999999999999996E+00 3.2149999999999999E+00 + 112 0 0 0 + 0.0000000000000000E+00 -8.0000000000000000E+00 3.2149999999999999E+00 + 113 0 0 0 + 0.0000000000000000E+00 -1.0400000000000000E+01 3.2149999999999999E+00 + 114 0 0 0 + 0.0000000000000000E+00 1.2000000000000000E+01 3.2149999999999999E+00 + 115 0 0 0 + 0.0000000000000000E+00 5.5999999999999996E+00 3.2149999999999999E+00 + 116 0 0 0 + 0.0000000000000000E+00 8.0000000000000000E+00 3.2149999999999999E+00 + 117 0 0 0 + 0.0000000000000000E+00 1.0400000000000000E+01 3.2149999999999999E+00 + 118 0 0 0 + 0.0000000000000000E+00 2.3999999999999999E+00 1.8969999999999999E+01 + 119 0 0 0 + 0.0000000000000000E+00 -1.2877000000000001E+01 4.9500000000000002E+00 + 120 0 0 0 + 0.0000000000000000E+00 -2.3999999999999999E+00 4.9500000000000002E+00 + 121 0 0 0 + 0.0000000000000000E+00 1.2877000000000001E+01 4.9500000000000002E+00 + 122 0 0 0 + 0.0000000000000000E+00 4.0000000000000000E+00 4.9500000000000002E+00 + 123 0 0 0 + 0.0000000000000000E+00 -1.2000000000000000E+01 4.9500000000000002E+00 + 124 0 0 0 + 0.0000000000000000E+00 -2.3999999999999999E+00 7.1550000000000002E+00 + 125 0 0 0 + 0.0000000000000000E+00 -1.2000000000000000E+01 1.7609999999999999E+01 + 126 0 0 0 + 0.0000000000000000E+00 -2.3999999999999999E+00 1.7609999999999999E+01 + 127 0 0 0 + 0.0000000000000000E+00 4.0000000000000000E+00 7.1550000000000002E+00 + 128 0 0 0 + 0.0000000000000000E+00 1.2000000000000000E+01 1.7609999999999999E+01 + 129 0 0 0 + 0.0000000000000000E+00 1.2000000000000000E+01 4.9500000000000002E+00 + 130 0 0 0 + 0.0000000000000000E+00 4.0000000000000000E+00 1.7609999999999999E+01 + 131 0 0 0 + 0.0000000000000000E+00 -1.2000000000000000E+01 7.1550000000000002E+00 + 132 0 0 0 + 0.0000000000000000E+00 1.2000000000000000E+01 7.1550000000000002E+00 + 133 0 0 0 + 0.0000000000000000E+00 -4.0000000000000000E+00 4.9500000000000002E+00 + 134 0 0 0 + 0.0000000000000000E+00 5.5999999999999996E+00 4.9500000000000002E+00 + 135 0 0 0 + 0.0000000000000000E+00 -1.0400000000000000E+01 4.9500000000000002E+00 + 136 0 0 0 + 0.0000000000000000E+00 -2.3999999999999999E+00 9.3599999999999994E+00 + 137 0 0 0 + 0.0000000000000000E+00 -2.3999999999999999E+00 1.2359999999999999E+01 + 138 0 0 0 + 0.0000000000000000E+00 -2.3999999999999999E+00 1.5359999999999999E+01 + 139 0 0 0 + 0.0000000000000000E+00 1.0400000000000000E+01 4.9500000000000002E+00 + 140 0 0 0 + 0.0000000000000000E+00 8.0000000000000000E+00 4.9500000000000002E+00 + 141 0 0 0 + 0.0000000000000000E+00 -1.2000000000000000E+01 1.5359999999999999E+01 + 142 0 0 0 + 0.0000000000000000E+00 -1.2000000000000000E+01 1.2359999999999999E+01 + 143 0 0 0 + 0.0000000000000000E+00 -1.2000000000000000E+01 9.3599999999999994E+00 + 144 0 0 0 + 0.0000000000000000E+00 4.0000000000000000E+00 9.3599999999999994E+00 + 145 0 0 0 + 0.0000000000000000E+00 4.0000000000000000E+00 1.2359999999999999E+01 + 146 0 0 0 + 0.0000000000000000E+00 4.0000000000000000E+00 1.5359999999999999E+01 + 147 0 0 0 + 0.0000000000000000E+00 1.2000000000000000E+01 1.5359999999999999E+01 + 148 0 0 0 + 0.0000000000000000E+00 1.2000000000000000E+01 1.2359999999999999E+01 + 149 0 0 0 + 0.0000000000000000E+00 1.2000000000000000E+01 9.3599999999999994E+00 + 150 0 0 0 + 0.0000000000000000E+00 -8.0000000000000000E+00 4.9500000000000002E+00 + 151 0 0 0 + 0.0000000000000000E+00 -5.5999999999999996E+00 4.9500000000000002E+00 + 152 0 0 0 + 0.0000000000000000E+00 4.0000000000000000E+00 1.8969999999999999E+01 + 153 0 0 0 + 0.0000000000000000E+00 5.5999999999999996E+00 1.8969999999999999E+01 + 154 0 0 0 + 0.0000000000000000E+00 8.0000000000000000E+00 1.8969999999999999E+01 + 155 0 0 0 + 0.0000000000000000E+00 1.0400000000000000E+01 1.8969999999999999E+01 + 156 0 0 0 + 0.0000000000000000E+00 1.2000000000000000E+01 1.8969999999999999E+01 + 157 0 0 0 + 0.0000000000000000E+00 -2.3999999999999999E+00 1.8969999999999999E+01 + 158 0 0 0 + 0.0000000000000000E+00 -4.0000000000000000E+00 1.8969999999999999E+01 + 159 0 0 0 + 0.0000000000000000E+00 -5.5999999999999996E+00 1.8969999999999999E+01 + 160 0 0 0 + 0.0000000000000000E+00 -8.0000000000000000E+00 1.8969999999999999E+01 + 161 0 0 0 + 0.0000000000000000E+00 -1.0400000000000000E+01 1.8969999999999999E+01 + 162 0 0 0 + 0.0000000000000000E+00 -1.2000000000000000E+01 1.8969999999999999E+01 + 163 0 0 0 + 3.3999999999999999E+00 -4.0000000000000000E+00 0.0000000000000000E+00 + 164 0 0 0 + 3.3999999999999999E+00 -2.3999999999999999E+00 0.0000000000000000E+00 + 165 0 0 0 + 3.3999999999999999E+00 4.0000000000000000E+00 0.0000000000000000E+00 + 166 0 0 0 + 3.3999999999999999E+00 2.3999999999999999E+00 0.0000000000000000E+00 + 167 0 0 0 + 3.3999999999999999E+00 0.0000000000000000E+00 0.0000000000000000E+00 + 168 0 0 0 + 3.3999999999999999E+00 0.0000000000000000E+00 3.6600000000000001E+00 + 169 0 0 0 + 3.3999999999999999E+00 -5.5999999999999996E+00 0.0000000000000000E+00 + 170 0 0 0 + 3.3999999999999999E+00 -8.0000000000000000E+00 0.0000000000000000E+00 + 171 0 0 0 + 3.3999999999999999E+00 -1.0400000000000000E+01 0.0000000000000000E+00 + 172 0 0 0 + 3.3999999999999999E+00 -4.0000000000000000E+00 2.0000000000000000E+00 + 173 0 0 0 + 3.3999999999999999E+00 -2.3999999999999999E+00 2.0000000000000000E+00 + 174 0 0 0 + 3.3999999999999999E+00 0.0000000000000000E+00 2.0000000000000000E+00 + 175 0 0 0 + 3.3999999999999999E+00 2.3999999999999999E+00 2.0000000000000000E+00 + 176 0 0 0 + 3.3999999999999999E+00 4.0000000000000000E+00 2.0000000000000000E+00 + 177 0 0 0 + 3.3999999999999999E+00 5.5999999999999996E+00 0.0000000000000000E+00 + 178 0 0 0 + 3.3999999999999999E+00 8.0000000000000000E+00 0.0000000000000000E+00 + 179 0 0 0 + 3.3999999999999999E+00 1.0400000000000000E+01 0.0000000000000000E+00 + 180 0 0 0 + 3.3999999999999999E+00 -2.3999999999999999E+00 3.0000000000000000E+00 + 181 0 0 0 + 0.0000000000000000E+00 -4.0000000000000000E+00 7.1550000000000002E+00 + 182 0 0 0 + 3.3999999999999999E+00 0.0000000000000000E+00 7.1550000000000002E+00 + 183 0 0 0 + 3.3999999999999999E+00 -8.0000000000000000E+00 2.0000000000000000E+00 + 184 0 0 0 + 3.3999999999999999E+00 -1.0400000000000000E+01 2.0000000000000000E+00 + 185 0 0 0 + 3.3999999999999999E+00 2.3999999999999999E+00 3.6600000000000001E+00 + 186 0 0 0 + 3.3999999999999999E+00 -1.2000000000000000E+01 0.0000000000000000E+00 + 187 0 0 0 + 3.3999999999999999E+00 -1.2000000000000000E+01 2.0000000000000000E+00 + 188 0 0 0 + 3.3999999999999999E+00 -1.4350000000000000E+01 0.0000000000000000E+00 + 189 0 0 0 + 0.0000000000000000E+00 -1.0400000000000000E+01 1.7609999999999999E+01 + 190 0 0 0 + 3.3999999999999999E+00 -1.2877000000000001E+01 3.2160000000000002E+00 + 191 0 0 0 + 3.3999999999999999E+00 -1.5500000000000000E+01 5.0000000000000000E-01 + 192 0 0 0 + 0.0000000000000000E+00 -4.0000000000000000E+00 1.7609999999999999E+01 + 193 0 0 0 + 3.3999999999999999E+00 2.3999999999999999E+00 1.9800000000000001E+01 + 194 0 0 0 + 3.3999999999999999E+00 -1.6129999999999999E+01 1.7000000000000000E+00 + 195 0 0 0 + 3.3999999999999999E+00 -1.6129999999999999E+01 3.3500000000000001E+00 + 196 0 0 0 + 3.3999999999999999E+00 8.0000000000000000E+00 2.0000000000000000E+00 + 197 0 0 0 + 0.0000000000000000E+00 5.5999999999999996E+00 7.1550000000000002E+00 + 198 0 0 0 + 0.0000000000000000E+00 8.0000000000000000E+00 7.1550000000000002E+00 + 199 0 0 0 + 0.0000000000000000E+00 1.0400000000000000E+01 7.1550000000000002E+00 + 200 0 0 0 + 3.3999999999999999E+00 1.2000000000000000E+01 0.0000000000000000E+00 + 201 0 0 0 + 3.3999999999999999E+00 1.0400000000000000E+01 2.0000000000000000E+00 + 202 0 0 0 + 0.0000000000000000E+00 1.0400000000000000E+01 1.7609999999999999E+01 + 203 0 0 0 + 0.0000000000000000E+00 8.0000000000000000E+00 1.7609999999999999E+01 + 204 0 0 0 + 0.0000000000000000E+00 5.5999999999999996E+00 1.7609999999999999E+01 + 205 0 0 0 + 3.3999999999999999E+00 1.4350000000000000E+01 0.0000000000000000E+00 + 206 0 0 0 + 3.3999999999999999E+00 -1.6129999999999999E+01 4.9500000000000002E+00 + 207 0 0 0 + 3.3999999999999999E+00 1.2000000000000000E+01 2.0000000000000000E+00 + 208 0 0 0 + 3.3999999999999999E+00 1.5500000000000000E+01 5.0000000000000000E-01 + 209 0 0 0 + 3.3999999999999999E+00 -1.6129999999999999E+01 7.1550000000000002E+00 + 210 0 0 0 + 3.3999999999999999E+00 0.0000000000000000E+00 1.2359999999999999E+01 + 211 0 0 0 + 0.0000000000000000E+00 -1.0400000000000000E+01 7.1550000000000002E+00 + 212 0 0 0 + 3.3999999999999999E+00 1.2877000000000001E+01 3.2160000000000002E+00 + 213 0 0 0 + 3.3999999999999999E+00 1.6129999999999999E+01 1.7000000000000000E+00 + 214 0 0 0 + 3.3999999999999999E+00 1.6129999999999999E+01 3.3500000000000001E+00 + 215 0 0 0 + 3.3999999999999999E+00 -1.4130000000000001E+01 7.1550000000000002E+00 + 216 0 0 0 + 3.3999999999999999E+00 -1.4130000000000001E+01 4.9500000000000002E+00 + 217 0 0 0 + 3.3999999999999999E+00 -1.6129999999999999E+01 9.3599999999999994E+00 + 218 0 0 0 + 3.3999999999999999E+00 -1.6129999999999999E+01 1.2359999999999999E+01 + 219 0 0 0 + 3.3999999999999999E+00 1.6129999999999999E+01 4.9500000000000002E+00 + 220 0 0 0 + 3.3999999999999999E+00 1.6129999999999999E+01 7.1550000000000002E+00 + 221 0 0 0 + 3.3999999999999999E+00 1.4130000000000001E+01 7.1550000000000002E+00 + 222 0 0 0 + 3.3999999999999999E+00 1.4130000000000001E+01 4.9500000000000002E+00 + 223 0 0 0 + 3.3999999999999999E+00 -1.4130000000000001E+01 1.2359999999999999E+01 + 224 0 0 0 + 3.3999999999999999E+00 -1.4130000000000001E+01 9.3599999999999994E+00 + 225 0 0 0 + 3.3999999999999999E+00 -1.6129999999999999E+01 1.5359999999999999E+01 + 226 0 0 0 + 3.3999999999999999E+00 -1.6129999999999999E+01 1.7609999999999999E+01 + 227 0 0 0 + 3.3999999999999999E+00 -1.6129999999999999E+01 1.8969999999999999E+01 + 228 0 0 0 + 3.3999999999999999E+00 -1.6129999999999999E+01 2.0800000000000001E+01 + 229 0 0 0 + 3.3999999999999999E+00 1.6129999999999999E+01 9.3599999999999994E+00 + 230 0 0 0 + 3.3999999999999999E+00 1.6129999999999999E+01 1.2359999999999999E+01 + 231 0 0 0 + 3.3999999999999999E+00 1.4130000000000001E+01 1.2359999999999999E+01 + 232 0 0 0 + 3.3999999999999999E+00 1.4130000000000001E+01 9.3599999999999994E+00 + 233 0 0 0 + 3.3999999999999999E+00 -1.4130000000000001E+01 1.5359999999999999E+01 + 234 0 0 0 + 3.3999999999999999E+00 1.6129999999999999E+01 1.5359999999999999E+01 + 235 0 0 0 + 3.3999999999999999E+00 1.6129999999999999E+01 1.7609999999999999E+01 + 236 0 0 0 + 3.3999999999999999E+00 1.6129999999999999E+01 1.8969999999999999E+01 + 237 0 0 0 + 3.3999999999999999E+00 1.6129999999999999E+01 2.0800000000000001E+01 + 238 0 0 0 + 3.3999999999999999E+00 -1.4130000000000001E+01 2.0916000000000000E+01 + 239 0 0 0 + 3.3999999999999999E+00 -1.4130000000000001E+01 1.8969999999999999E+01 + 240 0 0 0 + 3.3999999999999999E+00 -1.2000000000000000E+01 2.1027999999999999E+01 + 241 0 0 0 + 3.3999999999999999E+00 -1.0400000000000000E+01 2.1111999999999998E+01 + 242 0 0 0 + 3.3999999999999999E+00 -8.0000000000000000E+00 2.1239000000000001E+01 + 243 0 0 0 + 3.3999999999999999E+00 -5.5999999999999996E+00 2.1366000000000000E+01 + 244 0 0 0 + 3.3999999999999999E+00 -4.0000000000000000E+00 2.1449999999999999E+01 + 245 0 0 0 + 3.3999999999999999E+00 -2.3999999999999999E+00 2.1449999999999999E+01 + 246 0 0 0 + 3.3999999999999999E+00 0.0000000000000000E+00 2.1449999999999999E+01 + 247 0 0 0 + 3.3999999999999999E+00 2.3999999999999999E+00 2.1449999999999999E+01 + 248 0 0 0 + 0.0000000000000000E+00 -8.0000000000000000E+00 1.7609999999999999E+01 + 249 0 0 0 + 0.0000000000000000E+00 -5.5999999999999996E+00 1.7609999999999999E+01 + 250 0 0 0 + 3.3999999999999999E+00 4.0000000000000000E+00 2.1449999999999999E+01 + 251 0 0 0 + 3.3999999999999999E+00 5.5999999999999996E+00 2.1366000000000000E+01 + 252 0 0 0 + 3.3999999999999999E+00 8.0000000000000000E+00 2.1239000000000001E+01 + 253 0 0 0 + 3.3999999999999999E+00 1.0400000000000000E+01 2.1111999999999998E+01 + 254 0 0 0 + 3.3999999999999999E+00 1.2000000000000000E+01 2.1027999999999999E+01 + 255 0 0 0 + 3.3999999999999999E+00 1.4130000000000001E+01 2.0916000000000000E+01 + 256 0 0 0 + 3.3999999999999999E+00 1.4130000000000001E+01 1.8969999999999999E+01 + 257 0 0 0 + 0.0000000000000000E+00 -5.5999999999999996E+00 7.1550000000000002E+00 + 258 0 0 0 + 0.0000000000000000E+00 -8.0000000000000000E+00 7.1550000000000002E+00 + 259 0 0 0 + 3.3999999999999999E+00 1.4130000000000001E+01 1.5359999999999999E+01 + 260 0 0 0 + 2.2000000000000002E+00 2.3999999999999999E+00 4.9500000000000002E+00 + 261 0 0 0 + 3.3999999999999999E+00 0.0000000000000000E+00 9.3599999999999994E+00 + 262 0 0 0 + 2.2000000000000002E+00 2.3999999999999999E+00 9.3599999999999994E+00 + 263 0 0 0 + 3.3999999999999999E+00 0.0000000000000000E+00 1.5359999999999999E+01 + 264 0 0 0 + 2.2000000000000002E+00 2.3999999999999999E+00 1.5359999999999999E+01 + 265 0 0 0 + 3.3999999999999999E+00 0.0000000000000000E+00 1.7609999999999999E+01 + 266 0 0 0 + 3.3999999999999999E+00 -1.4130000000000001E+01 1.7609999999999999E+01 + 267 0 0 0 + 3.3999999999999999E+00 1.4130000000000001E+01 1.7609999999999999E+01 + 268 0 0 0 + 2.2000000000000002E+00 -1.2877000000000001E+01 4.9500000000000002E+00 + 269 0 0 0 + 2.2000000000000002E+00 -2.3999999999999999E+00 4.9500000000000002E+00 + 270 0 0 0 + 2.2000000000000002E+00 1.2877000000000001E+01 4.9500000000000002E+00 + 271 0 0 0 + 2.2000000000000002E+00 4.0000000000000000E+00 4.9500000000000002E+00 + 272 0 0 0 + 0.0000000000000000E+00 -4.0000000000000000E+00 9.3599999999999994E+00 + 273 0 0 0 + 0.0000000000000000E+00 -4.0000000000000000E+00 1.2359999999999999E+01 + 274 0 0 0 + 0.0000000000000000E+00 -4.0000000000000000E+00 1.5359999999999999E+01 + 275 0 0 0 + 0.0000000000000000E+00 -1.0400000000000000E+01 1.5359999999999999E+01 + 276 0 0 0 + 0.0000000000000000E+00 -1.0400000000000000E+01 1.2359999999999999E+01 + 277 0 0 0 + 3.3999999999999999E+00 -5.5999999999999996E+00 2.0000000000000000E+00 + 278 0 0 0 + 3.3999999999999999E+00 0.0000000000000000E+00 4.9500000000000002E+00 + 279 0 0 0 + 0.0000000000000000E+00 -1.0400000000000000E+01 9.3599999999999994E+00 + 280 0 0 0 + 0.0000000000000000E+00 5.5999999999999996E+00 9.3599999999999994E+00 + 281 0 0 0 + 0.0000000000000000E+00 5.5999999999999996E+00 1.2359999999999999E+01 + 282 0 0 0 + 0.0000000000000000E+00 5.5999999999999996E+00 1.5359999999999999E+01 + 283 0 0 0 + 0.0000000000000000E+00 1.0400000000000000E+01 1.2359999999999999E+01 + 284 0 0 0 + 0.0000000000000000E+00 8.0000000000000000E+00 1.2359999999999999E+01 + 285 0 0 0 + 0.0000000000000000E+00 1.0400000000000000E+01 1.5359999999999999E+01 + 286 0 0 0 + 0.0000000000000000E+00 8.0000000000000000E+00 1.5359999999999999E+01 + 287 0 0 0 + 0.0000000000000000E+00 1.0400000000000000E+01 9.3599999999999994E+00 + 288 0 0 0 + 0.0000000000000000E+00 8.0000000000000000E+00 9.3599999999999994E+00 + 289 0 0 0 + 3.3999999999999999E+00 5.5999999999999996E+00 2.0000000000000000E+00 + 290 0 0 0 + 2.2000000000000002E+00 -2.3999999999999999E+00 9.3599999999999994E+00 + 291 0 0 0 + 2.2000000000000002E+00 -2.3999999999999999E+00 1.5359999999999999E+01 + 292 0 0 0 + 2.2000000000000002E+00 -1.2000000000000000E+01 4.9500000000000002E+00 + 293 0 0 0 + 2.2000000000000002E+00 -1.2000000000000000E+01 1.5359999999999999E+01 + 294 0 0 0 + 3.3999999999999999E+00 -2.3999999999999999E+00 1.9800000000000001E+01 + 295 0 0 0 + 2.2000000000000002E+00 -1.2000000000000000E+01 9.3599999999999994E+00 + 296 0 0 0 + 2.2000000000000002E+00 4.0000000000000000E+00 9.3599999999999994E+00 + 297 0 0 0 + 3.3999999999999999E+00 -1.2000000000000000E+01 1.9527999999999999E+01 + 298 0 0 0 + 2.2000000000000002E+00 4.0000000000000000E+00 1.5359999999999999E+01 + 299 0 0 0 + 2.2000000000000002E+00 1.2000000000000000E+01 1.5359999999999999E+01 + 300 0 0 0 + 2.2000000000000002E+00 1.2000000000000000E+01 4.9500000000000002E+00 + 301 0 0 0 + 2.2000000000000002E+00 1.2000000000000000E+01 9.3599999999999994E+00 + 302 0 0 0 + 3.3999999999999999E+00 -1.3600000000000000E+01 2.0000000000000000E+00 + 303 0 0 0 + 3.3999999999999999E+00 1.2000000000000000E+01 1.9527999999999999E+01 + 304 0 0 0 + 3.3999999999999999E+00 -4.0000000000000000E+00 2.7999999999999998E+00 + 305 0 0 0 + 3.3999999999999999E+00 -2.3999999999999999E+00 3.6600000000000001E+00 + 306 0 0 0 + 2.2000000000000002E+00 -4.0000000000000000E+00 4.9500000000000002E+00 + 307 0 0 0 + 3.3999999999999999E+00 1.3600000000000000E+01 2.0000000000000000E+00 + 308 0 0 0 + 2.2000000000000002E+00 5.5999999999999996E+00 4.9500000000000002E+00 + 309 0 0 0 + 2.2000000000000002E+00 1.0400000000000000E+01 4.9500000000000002E+00 + 310 0 0 0 + 2.2000000000000002E+00 8.0000000000000000E+00 4.9500000000000002E+00 + 311 0 0 0 + 2.2000000000000002E+00 -1.0400000000000000E+01 4.9500000000000002E+00 + 312 0 0 0 + 3.3999999999999999E+00 4.0000000000000000E+00 3.0000000000000000E+00 + 313 0 0 0 + 2.2000000000000002E+00 -8.0000000000000000E+00 4.9500000000000002E+00 + 314 0 0 0 + 2.2000000000000002E+00 -5.5999999999999996E+00 4.9500000000000002E+00 + 315 0 0 0 + 3.3999999999999999E+00 -1.5199999999999999E+01 2.0000000000000000E+00 + 316 0 0 0 + 3.3999999999999999E+00 -1.4150000000000000E+01 3.1040000000000001E+00 + 317 0 0 0 + 3.3999999999999999E+00 -4.0000000000000000E+00 1.9949999999999999E+01 + 318 0 0 0 + 3.3999999999999999E+00 -1.0400000000000000E+01 1.9611999999999998E+01 + 319 0 0 0 + 3.3999999999999999E+00 2.3999999999999999E+00 4.9500000000000002E+00 + 320 0 0 0 + 3.3999999999999999E+00 2.3999999999999999E+00 1.7609999999999999E+01 + 321 0 0 0 + 3.3999999999999999E+00 4.0000000000000000E+00 1.9949999999999999E+01 + 322 0 0 0 + 3.3999999999999999E+00 1.5199999999999999E+01 2.0000000000000000E+00 + 323 0 0 0 + 3.3999999999999999E+00 1.4150000000000000E+01 3.1040000000000001E+00 + 324 0 0 0 + 3.3999999999999999E+00 1.0400000000000000E+01 1.9611999999999998E+01 + 325 0 0 0 + 3.3999999999999999E+00 -1.5199999999999999E+01 3.8500000000000001E+00 + 326 0 0 0 + 3.3999999999999999E+00 -1.4500000000000000E+01 3.8500000000000001E+00 + 327 0 0 0 + 3.3999999999999999E+00 -8.0000000000000000E+00 1.9739000000000001E+01 + 328 0 0 0 + 3.3999999999999999E+00 -5.5999999999999996E+00 1.9866000000000000E+01 + 329 0 0 0 + 3.3999999999999999E+00 8.0000000000000000E+00 1.9739000000000001E+01 + 330 0 0 0 + 3.3999999999999999E+00 5.5999999999999996E+00 1.9866000000000000E+01 + 331 0 0 0 + 3.3999999999999999E+00 1.5199999999999999E+01 3.8500000000000001E+00 + 332 0 0 0 + 3.3999999999999999E+00 1.4500000000000000E+01 3.8500000000000001E+00 + 333 0 0 0 + 0.0000000000000000E+00 -8.0000000000000000E+00 1.5359999999999999E+01 + 334 0 0 0 + 0.0000000000000000E+00 -5.5999999999999996E+00 1.5359999999999999E+01 + 335 0 0 0 + 0.0000000000000000E+00 -8.0000000000000000E+00 1.2359999999999999E+01 + 336 0 0 0 + 0.0000000000000000E+00 -5.5999999999999996E+00 1.2359999999999999E+01 + 337 0 0 0 + 0.0000000000000000E+00 -8.0000000000000000E+00 9.3599999999999994E+00 + 338 0 0 0 + 0.0000000000000000E+00 -5.5999999999999996E+00 9.3599999999999994E+00 + 339 0 0 0 + 3.3999999999999999E+00 0.0000000000000000E+00 1.8969999999999999E+01 + 340 0 0 0 + 3.3999999999999999E+00 2.3999999999999999E+00 7.1550000000000002E+00 + 341 0 0 0 + 3.3999999999999999E+00 2.3999999999999999E+00 1.5359999999999999E+01 + 342 0 0 0 + 3.3999999999999999E+00 2.3999999999999999E+00 9.3599999999999994E+00 + 343 0 0 0 + 3.3999999999999999E+00 2.3999999999999999E+00 1.2359999999999999E+01 + 344 0 0 0 + 6.7999999999999998E+00 -2.3999999999999999E+00 0.0000000000000000E+00 + 345 0 0 0 + 6.7999999999999998E+00 -4.0000000000000000E+00 0.0000000000000000E+00 + 346 0 0 0 + 6.7999999999999998E+00 0.0000000000000000E+00 0.0000000000000000E+00 + 347 0 0 0 + 6.7999999999999998E+00 2.3999999999999999E+00 0.0000000000000000E+00 + 348 0 0 0 + 6.7999999999999998E+00 4.0000000000000000E+00 0.0000000000000000E+00 + 349 0 0 0 + 6.7999999999999998E+00 0.0000000000000000E+00 2.0000000000000000E+00 + 350 0 0 0 + 6.7999999999999998E+00 -2.3999999999999999E+00 2.0000000000000000E+00 + 351 0 0 0 + 6.7999999999999998E+00 0.0000000000000000E+00 3.6600000000000001E+00 + 352 0 0 0 + 6.7999999999999998E+00 2.3999999999999999E+00 2.0000000000000000E+00 + 353 0 0 0 + 6.7999999999999998E+00 -5.5999999999999996E+00 0.0000000000000000E+00 + 354 0 0 0 + 6.7999999999999998E+00 -4.0000000000000000E+00 2.0000000000000000E+00 + 355 0 0 0 + 6.7999999999999998E+00 -8.0000000000000000E+00 0.0000000000000000E+00 + 356 0 0 0 + 6.7999999999999998E+00 -1.0400000000000000E+01 0.0000000000000000E+00 + 357 0 0 0 + 6.7999999999999998E+00 5.5999999999999996E+00 0.0000000000000000E+00 + 358 0 0 0 + 6.7999999999999998E+00 4.0000000000000000E+00 2.0000000000000000E+00 + 359 0 0 0 + 6.7999999999999998E+00 8.0000000000000000E+00 0.0000000000000000E+00 + 360 0 0 0 + 6.7999999999999998E+00 1.0400000000000000E+01 0.0000000000000000E+00 + 361 0 0 0 + 6.7999999999999998E+00 -1.2000000000000000E+01 0.0000000000000000E+00 + 362 0 0 0 + 6.7999999999999998E+00 -8.0000000000000000E+00 2.0000000000000000E+00 + 363 0 0 0 + 6.7999999999999998E+00 -1.0400000000000000E+01 2.0000000000000000E+00 + 364 0 0 0 + 6.7999999999999998E+00 0.0000000000000000E+00 7.1550000000000002E+00 + 365 0 0 0 + 6.7999999999999998E+00 -1.2000000000000000E+01 2.0000000000000000E+00 + 366 0 0 0 + 6.7999999999999998E+00 -1.4350000000000000E+01 0.0000000000000000E+00 + 367 0 0 0 + 6.7999999999999998E+00 -1.2877000000000001E+01 3.2160000000000002E+00 + 368 0 0 0 + 6.7999999999999998E+00 -1.5500000000000000E+01 5.0000000000000000E-01 + 369 0 0 0 + 6.7999999999999998E+00 1.2000000000000000E+01 0.0000000000000000E+00 + 370 0 0 0 + 6.7999999999999998E+00 -1.6129999999999999E+01 1.7000000000000000E+00 + 371 0 0 0 + 6.7999999999999998E+00 8.0000000000000000E+00 2.0000000000000000E+00 + 372 0 0 0 + 2.2000000000000002E+00 -4.0000000000000000E+00 9.3599999999999994E+00 + 373 0 0 0 + 6.7999999999999998E+00 1.0400000000000000E+01 2.0000000000000000E+00 + 374 0 0 0 + 6.7999999999999998E+00 0.0000000000000000E+00 9.3599999999999994E+00 + 375 0 0 0 + 2.2000000000000002E+00 -4.0000000000000000E+00 1.5359999999999999E+01 + 376 0 0 0 + 6.7999999999999998E+00 -1.4130000000000001E+01 4.9500000000000002E+00 + 377 0 0 0 + 6.7999999999999998E+00 1.4350000000000000E+01 0.0000000000000000E+00 + 378 0 0 0 + 6.7999999999999998E+00 -1.6129999999999999E+01 3.3500000000000001E+00 + 379 0 0 0 + 6.7999999999999998E+00 1.2000000000000000E+01 2.0000000000000000E+00 + 380 0 0 0 + 6.7999999999999998E+00 -1.6129999999999999E+01 4.9500000000000002E+00 + 381 0 0 0 + 2.2000000000000002E+00 -1.0400000000000000E+01 1.5359999999999999E+01 + 382 0 0 0 + 6.7999999999999998E+00 1.5500000000000000E+01 5.0000000000000000E-01 + 383 0 0 0 + 2.2000000000000002E+00 -1.0400000000000000E+01 9.3599999999999994E+00 + 384 0 0 0 + 6.7999999999999998E+00 -1.6129999999999999E+01 7.1550000000000002E+00 + 385 0 0 0 + 2.2000000000000002E+00 5.5999999999999996E+00 9.3599999999999994E+00 + 386 0 0 0 + 2.2000000000000002E+00 1.0400000000000000E+01 9.3599999999999994E+00 + 387 0 0 0 + 2.2000000000000002E+00 8.0000000000000000E+00 9.3599999999999994E+00 + 388 0 0 0 + 6.7999999999999998E+00 1.2877000000000001E+01 3.2160000000000002E+00 + 389 0 0 0 + 2.2000000000000002E+00 5.5999999999999996E+00 1.5359999999999999E+01 + 390 0 0 0 + 2.2000000000000002E+00 1.0400000000000000E+01 1.5359999999999999E+01 + 391 0 0 0 + 2.2000000000000002E+00 8.0000000000000000E+00 1.5359999999999999E+01 + 392 0 0 0 + 6.7999999999999998E+00 1.6129999999999999E+01 1.7000000000000000E+00 + 393 0 0 0 + 6.7999999999999998E+00 -1.4130000000000001E+01 7.1550000000000002E+00 + 394 0 0 0 + 6.7999999999999998E+00 0.0000000000000000E+00 1.2359999999999999E+01 + 395 0 0 0 + 6.7999999999999998E+00 -1.6129999999999999E+01 9.3599999999999994E+00 + 396 0 0 0 + 6.7999999999999998E+00 1.6129999999999999E+01 3.3500000000000001E+00 + 397 0 0 0 + 6.7999999999999998E+00 1.4130000000000001E+01 4.9500000000000002E+00 + 398 0 0 0 + 6.7999999999999998E+00 -1.6129999999999999E+01 1.2359999999999999E+01 + 399 0 0 0 + 6.7999999999999998E+00 -1.4130000000000001E+01 9.3599999999999994E+00 + 400 0 0 0 + 6.7999999999999998E+00 1.6129999999999999E+01 4.9500000000000002E+00 + 401 0 0 0 + 6.7999999999999998E+00 0.0000000000000000E+00 1.5359999999999999E+01 + 402 0 0 0 + 6.7999999999999998E+00 1.6129999999999999E+01 7.1550000000000002E+00 + 403 0 0 0 + 6.7999999999999998E+00 1.4130000000000001E+01 7.1550000000000002E+00 + 404 0 0 0 + 6.7999999999999998E+00 -1.4130000000000001E+01 1.2359999999999999E+01 + 405 0 0 0 + 6.7999999999999998E+00 -1.6129999999999999E+01 1.5359999999999999E+01 + 406 0 0 0 + 6.7999999999999998E+00 1.6129999999999999E+01 9.3599999999999994E+00 + 407 0 0 0 + 6.7999999999999998E+00 1.4130000000000001E+01 9.3599999999999994E+00 + 408 0 0 0 + 6.7999999999999998E+00 -1.6129999999999999E+01 1.7609999999999999E+01 + 409 0 0 0 + 6.7999999999999998E+00 -1.4130000000000001E+01 1.5359999999999999E+01 + 410 0 0 0 + 6.7999999999999998E+00 -1.6129999999999999E+01 1.8969999999999999E+01 + 411 0 0 0 + 6.7999999999999998E+00 -1.6129999999999999E+01 2.0800000000000001E+01 + 412 0 0 0 + 6.7999999999999998E+00 1.6129999999999999E+01 1.2359999999999999E+01 + 413 0 0 0 + 6.7999999999999998E+00 1.4130000000000001E+01 1.2359999999999999E+01 + 414 0 0 0 + 6.7999999999999998E+00 1.6129999999999999E+01 1.5359999999999999E+01 + 415 0 0 0 + 6.7999999999999998E+00 1.6129999999999999E+01 1.7609999999999999E+01 + 416 0 0 0 + 6.7999999999999998E+00 1.6129999999999999E+01 1.8969999999999999E+01 + 417 0 0 0 + 6.7999999999999998E+00 -1.4130000000000001E+01 2.0916000000000000E+01 + 418 0 0 0 + 6.7999999999999998E+00 -1.4130000000000001E+01 1.8969999999999999E+01 + 419 0 0 0 + 6.7999999999999998E+00 1.6129999999999999E+01 2.0800000000000001E+01 + 420 0 0 0 + 6.7999999999999998E+00 1.4130000000000001E+01 1.5359999999999999E+01 + 421 0 0 0 + 6.7999999999999998E+00 -1.2000000000000000E+01 2.1027999999999999E+01 + 422 0 0 0 + 6.7999999999999998E+00 -1.0400000000000000E+01 2.1111999999999998E+01 + 423 0 0 0 + 6.7999999999999998E+00 -8.0000000000000000E+00 2.1239000000000001E+01 + 424 0 0 0 + 6.7999999999999998E+00 -5.5999999999999996E+00 2.1366000000000000E+01 + 425 0 0 0 + 6.7999999999999998E+00 -4.0000000000000000E+00 2.1449999999999999E+01 + 426 0 0 0 + 6.7999999999999998E+00 -2.3999999999999999E+00 2.1449999999999999E+01 + 427 0 0 0 + 6.7999999999999998E+00 0.0000000000000000E+00 2.1449999999999999E+01 + 428 0 0 0 + 6.7999999999999998E+00 2.3999999999999999E+00 2.1449999999999999E+01 + 429 0 0 0 + 6.7999999999999998E+00 1.4130000000000001E+01 2.0916000000000000E+01 + 430 0 0 0 + 6.7999999999999998E+00 1.4130000000000001E+01 1.8969999999999999E+01 + 431 0 0 0 + 6.7999999999999998E+00 4.0000000000000000E+00 2.1449999999999999E+01 + 432 0 0 0 + 6.7999999999999998E+00 1.2000000000000000E+01 2.1027999999999999E+01 + 433 0 0 0 + 6.7999999999999998E+00 1.0400000000000000E+01 2.1111999999999998E+01 + 434 0 0 0 + 6.7999999999999998E+00 5.5999999999999996E+00 2.1366000000000000E+01 + 435 0 0 0 + 6.7999999999999998E+00 8.0000000000000000E+00 2.1239000000000001E+01 + 436 0 0 0 + 6.7999999999999998E+00 0.0000000000000000E+00 4.9500000000000002E+00 + 437 0 0 0 + 6.7999999999999998E+00 -5.5999999999999996E+00 2.0000000000000000E+00 + 438 0 0 0 + 6.7999999999999998E+00 -2.3999999999999999E+00 3.0000000000000000E+00 + 439 0 0 0 + 6.7999999999999998E+00 5.5999999999999996E+00 2.0000000000000000E+00 + 440 0 0 0 + 6.7999999999999998E+00 2.3999999999999999E+00 3.6600000000000001E+00 + 441 0 0 0 + 2.2000000000000002E+00 -8.0000000000000000E+00 1.5359999999999999E+01 + 442 0 0 0 + 2.2000000000000002E+00 -5.5999999999999996E+00 1.5359999999999999E+01 + 443 0 0 0 + 2.2000000000000002E+00 -8.0000000000000000E+00 9.3599999999999994E+00 + 444 0 0 0 + 2.2000000000000002E+00 -5.5999999999999996E+00 9.3599999999999994E+00 + 445 0 0 0 + 6.7999999999999998E+00 0.0000000000000000E+00 1.7609999999999999E+01 + 446 0 0 0 + 6.7999999999999998E+00 -1.4130000000000001E+01 1.7609999999999999E+01 + 447 0 0 0 + 6.7999999999999998E+00 1.4130000000000001E+01 1.7609999999999999E+01 + 448 0 0 0 + 6.7999999999999998E+00 0.0000000000000000E+00 1.8969999999999999E+01 + 449 0 0 0 + 6.7999999999999998E+00 -4.0000000000000000E+00 2.7999999999999998E+00 + 450 0 0 0 + 6.7999999999999998E+00 -2.3999999999999999E+00 3.6600000000000001E+00 + 451 0 0 0 + 6.7999999999999998E+00 4.0000000000000000E+00 3.0000000000000000E+00 + 452 0 0 0 + 6.7999999999999998E+00 -1.3600000000000000E+01 2.0000000000000000E+00 + 453 0 0 0 + 1.0199999999999999E+01 -2.3999999999999999E+00 0.0000000000000000E+00 + 454 0 0 0 + 1.0199999999999999E+01 -4.0000000000000000E+00 0.0000000000000000E+00 + 455 0 0 0 + 1.0199999999999999E+01 0.0000000000000000E+00 0.0000000000000000E+00 + 456 0 0 0 + 1.0199999999999999E+01 2.3999999999999999E+00 0.0000000000000000E+00 + 457 0 0 0 + 1.0199999999999999E+01 4.0000000000000000E+00 0.0000000000000000E+00 + 458 0 0 0 + 6.7999999999999998E+00 2.3999999999999999E+00 4.9500000000000002E+00 + 459 0 0 0 + 1.0199999999999999E+01 -2.3999999999999999E+00 2.0000000000000000E+00 + 460 0 0 0 + 1.0199999999999999E+01 0.0000000000000000E+00 2.0000000000000000E+00 + 461 0 0 0 + 1.0199999999999999E+01 2.3999999999999999E+00 2.0000000000000000E+00 + 462 0 0 0 + 1.0199999999999999E+01 0.0000000000000000E+00 3.6600000000000001E+00 + 463 0 0 0 + 1.0199999999999999E+01 -5.5999999999999996E+00 0.0000000000000000E+00 + 464 0 0 0 + 6.7999999999999998E+00 2.3999999999999999E+00 1.9800000000000001E+01 + 465 0 0 0 + 1.0199999999999999E+01 -4.0000000000000000E+00 2.0000000000000000E+00 + 466 0 0 0 + 1.0199999999999999E+01 -8.0000000000000000E+00 0.0000000000000000E+00 + 467 0 0 0 + 1.0199999999999999E+01 5.5999999999999996E+00 0.0000000000000000E+00 + 468 0 0 0 + 6.7999999999999998E+00 1.3600000000000000E+01 2.0000000000000000E+00 + 469 0 0 0 + 1.0199999999999999E+01 -1.0400000000000000E+01 0.0000000000000000E+00 + 470 0 0 0 + 1.0199999999999999E+01 4.0000000000000000E+00 2.0000000000000000E+00 + 471 0 0 0 + 1.0199999999999999E+01 8.0000000000000000E+00 0.0000000000000000E+00 + 472 0 0 0 + 1.0199999999999999E+01 1.0400000000000000E+01 0.0000000000000000E+00 + 473 0 0 0 + 1.0199999999999999E+01 -1.2000000000000000E+01 0.0000000000000000E+00 + 474 0 0 0 + 6.7999999999999998E+00 2.3999999999999999E+00 7.1550000000000002E+00 + 475 0 0 0 + 1.0199999999999999E+01 -8.0000000000000000E+00 2.0000000000000000E+00 + 476 0 0 0 + 1.0199999999999999E+01 -1.0400000000000000E+01 2.0000000000000000E+00 + 477 0 0 0 + 6.7999999999999998E+00 -1.4150000000000000E+01 3.1040000000000001E+00 + 478 0 0 0 + 1.0199999999999999E+01 -1.2000000000000000E+01 2.0000000000000000E+00 + 479 0 0 0 + 1.0199999999999999E+01 -1.4350000000000000E+01 0.0000000000000000E+00 + 480 0 0 0 + 1.0199999999999999E+01 0.0000000000000000E+00 7.1550000000000002E+00 + 481 0 0 0 + 6.7999999999999998E+00 -1.5199999999999999E+01 2.0000000000000000E+00 + 482 0 0 0 + 6.7999999999999998E+00 -1.5199999999999999E+01 3.8500000000000001E+00 + 483 0 0 0 + 6.7999999999999998E+00 -1.4500000000000000E+01 3.8500000000000001E+00 + 484 0 0 0 + 1.0199999999999999E+01 1.2000000000000000E+01 0.0000000000000000E+00 + 485 0 0 0 + 1.0199999999999999E+01 -1.2877000000000001E+01 3.2160000000000002E+00 + 486 0 0 0 + 1.0199999999999999E+01 8.0000000000000000E+00 2.0000000000000000E+00 + 487 0 0 0 + 1.0199999999999999E+01 -1.5500000000000000E+01 5.0000000000000000E-01 + 488 0 0 0 + 1.0199999999999999E+01 1.0400000000000000E+01 2.0000000000000000E+00 + 489 0 0 0 + 6.7999999999999998E+00 2.3999999999999999E+00 9.3599999999999994E+00 + 490 0 0 0 + 1.0199999999999999E+01 -1.6129999999999999E+01 1.7000000000000000E+00 + 491 0 0 0 + 1.0199999999999999E+01 1.4350000000000000E+01 0.0000000000000000E+00 + 492 0 0 0 + 1.0199999999999999E+01 0.0000000000000000E+00 9.3599999999999994E+00 + 493 0 0 0 + 1.0199999999999999E+01 1.2000000000000000E+01 2.0000000000000000E+00 + 494 0 0 0 + 6.7999999999999998E+00 1.5199999999999999E+01 2.0000000000000000E+00 + 495 0 0 0 + 1.0199999999999999E+01 -1.4130000000000001E+01 4.9500000000000002E+00 + 496 0 0 0 + 6.7999999999999998E+00 1.4150000000000000E+01 3.1040000000000001E+00 + 497 0 0 0 + 1.0199999999999999E+01 -1.6129999999999999E+01 3.3500000000000001E+00 + 498 0 0 0 + 1.0199999999999999E+01 1.5500000000000000E+01 5.0000000000000000E-01 + 499 0 0 0 + 1.0199999999999999E+01 -1.6129999999999999E+01 4.9500000000000002E+00 + 500 0 0 0 + 6.7999999999999998E+00 1.5199999999999999E+01 3.8500000000000001E+00 + 501 0 0 0 + 6.7999999999999998E+00 1.4500000000000000E+01 3.8500000000000001E+00 + 502 0 0 0 + 6.7999999999999998E+00 -1.2000000000000000E+01 1.9527999999999999E+01 + 503 0 0 0 + 1.0199999999999999E+01 1.2877000000000001E+01 3.2160000000000002E+00 + 504 0 0 0 + 1.0199999999999999E+01 -1.4130000000000001E+01 7.1550000000000002E+00 + 505 0 0 0 + 1.0199999999999999E+01 -1.6129999999999999E+01 7.1550000000000002E+00 + 506 0 0 0 + 6.7999999999999998E+00 -2.3999999999999999E+00 1.9800000000000001E+01 + 507 0 0 0 + 1.0199999999999999E+01 1.6129999999999999E+01 1.7000000000000000E+00 + 508 0 0 0 + 1.0199999999999999E+01 0.0000000000000000E+00 1.2359999999999999E+01 + 509 0 0 0 + 6.7999999999999998E+00 2.3999999999999999E+00 1.2359999999999999E+01 + 510 0 0 0 + 1.0199999999999999E+01 -1.6129999999999999E+01 9.3599999999999994E+00 + 511 0 0 0 + 6.7999999999999998E+00 1.2000000000000000E+01 1.9527999999999999E+01 + 512 0 0 0 + 1.0199999999999999E+01 -1.4130000000000001E+01 9.3599999999999994E+00 + 513 0 0 0 + 6.7999999999999998E+00 2.3999999999999999E+00 1.5359999999999999E+01 + 514 0 0 0 + 1.0199999999999999E+01 1.4130000000000001E+01 4.9500000000000002E+00 + 515 0 0 0 + 1.0199999999999999E+01 -1.6129999999999999E+01 1.2359999999999999E+01 + 516 0 0 0 + 1.0199999999999999E+01 1.6129999999999999E+01 3.3500000000000001E+00 + 517 0 0 0 + 1.0199999999999999E+01 1.6129999999999999E+01 4.9500000000000002E+00 + 518 0 0 0 + 1.0199999999999999E+01 0.0000000000000000E+00 1.5359999999999999E+01 + 519 0 0 0 + 1.0199999999999999E+01 1.4130000000000001E+01 7.1550000000000002E+00 + 520 0 0 0 + 1.0199999999999999E+01 -1.4130000000000001E+01 1.2359999999999999E+01 + 521 0 0 0 + 1.0199999999999999E+01 1.6129999999999999E+01 7.1550000000000002E+00 + 522 0 0 0 + 1.0199999999999999E+01 -1.6129999999999999E+01 1.5359999999999999E+01 + 523 0 0 0 + 6.7999999999999998E+00 2.3999999999999999E+00 1.7609999999999999E+01 + 524 0 0 0 + 1.0199999999999999E+01 1.6129999999999999E+01 9.3599999999999994E+00 + 525 0 0 0 + 1.0199999999999999E+01 1.4130000000000001E+01 9.3599999999999994E+00 + 526 0 0 0 + 1.0199999999999999E+01 -1.4130000000000001E+01 1.5359999999999999E+01 + 527 0 0 0 + 1.0199999999999999E+01 -1.6129999999999999E+01 1.7609999999999999E+01 + 528 0 0 0 + 1.0199999999999999E+01 -5.5999999999999996E+00 2.0000000000000000E+00 + 529 0 0 0 + 1.0199999999999999E+01 1.6129999999999999E+01 1.2359999999999999E+01 + 530 0 0 0 + 1.0199999999999999E+01 0.0000000000000000E+00 4.9500000000000002E+00 + 531 0 0 0 + 1.0199999999999999E+01 -1.6129999999999999E+01 1.8969999999999999E+01 + 532 0 0 0 + 1.0199999999999999E+01 1.4130000000000001E+01 1.2359999999999999E+01 + 533 0 0 0 + 1.0199999999999999E+01 -1.6129999999999999E+01 2.0800000000000001E+01 + 534 0 0 0 + 1.0199999999999999E+01 5.5999999999999996E+00 2.0000000000000000E+00 + 536 0 0 0 + 6.7999999999999998E+00 -1.0400000000000000E+01 1.9611999999999998E+01 + 538 0 0 0 + 1.0199999999999999E+01 1.6129999999999999E+01 1.5359999999999999E+01 + 539 0 0 0 + 1.0199999999999999E+01 1.4130000000000001E+01 1.5359999999999999E+01 + 540 0 0 0 + 1.0199999999999999E+01 -1.4130000000000001E+01 1.8969999999999999E+01 + 541 0 0 0 + 1.0199999999999999E+01 -1.4130000000000001E+01 2.0916000000000000E+01 + 542 0 0 0 + 1.0199999999999999E+01 1.6129999999999999E+01 1.7609999999999999E+01 + 543 0 0 0 + 6.7999999999999998E+00 -4.0000000000000000E+00 1.9949999999999999E+01 + 544 0 0 0 + 1.0199999999999999E+01 1.6129999999999999E+01 1.8969999999999999E+01 + 545 0 0 0 + 6.7999999999999998E+00 -8.0000000000000000E+00 1.9739000000000001E+01 + 546 0 0 0 + 6.7999999999999998E+00 -5.5999999999999996E+00 1.9866000000000000E+01 + 547 0 0 0 + 1.0199999999999999E+01 -1.2000000000000000E+01 2.1027999999999999E+01 + 548 0 0 0 + 1.0199999999999999E+01 1.6129999999999999E+01 2.0800000000000001E+01 + 549 0 0 0 + 6.7999999999999998E+00 4.0000000000000000E+00 1.9949999999999999E+01 + 550 0 0 0 + 1.0199999999999999E+01 -1.0400000000000000E+01 2.1111999999999998E+01 + 551 0 0 0 + 6.7999999999999998E+00 1.0400000000000000E+01 1.9611999999999998E+01 + 552 0 0 0 + 6.7999999999999998E+00 8.0000000000000000E+00 1.9739000000000001E+01 + 553 0 0 0 + 6.7999999999999998E+00 5.5999999999999996E+00 1.9866000000000000E+01 + 554 0 0 0 + 1.0199999999999999E+01 1.4130000000000001E+01 1.8969999999999999E+01 + 555 0 0 0 + 1.0199999999999999E+01 1.4130000000000001E+01 2.0916000000000000E+01 + 556 0 0 0 + 1.0199999999999999E+01 0.0000000000000000E+00 2.1449999999999999E+01 + 557 0 0 0 + 1.0199999999999999E+01 -8.0000000000000000E+00 2.1239000000000001E+01 + 558 0 0 0 + 1.0199999999999999E+01 -2.3999999999999999E+00 2.1449999999999999E+01 + 559 0 0 0 + 1.0199999999999999E+01 -4.0000000000000000E+00 2.1449999999999999E+01 + 560 0 0 0 + 1.0199999999999999E+01 -5.5999999999999996E+00 2.1366000000000000E+01 + 561 0 0 0 + 1.0199999999999999E+01 2.3999999999999999E+00 2.1449999999999999E+01 + 562 0 0 0 + 1.0199999999999999E+01 1.2000000000000000E+01 2.1027999999999999E+01 + 563 0 0 0 + 1.0199999999999999E+01 4.0000000000000000E+00 2.1449999999999999E+01 + 564 0 0 0 + 1.0199999999999999E+01 1.0400000000000000E+01 2.1111999999999998E+01 + 565 0 0 0 + 1.0199999999999999E+01 5.5999999999999996E+00 2.1366000000000000E+01 + 566 0 0 0 + 1.0199999999999999E+01 8.0000000000000000E+00 2.1239000000000001E+01 + 569 0 0 0 + 1.0199999999999999E+01 0.0000000000000000E+00 1.7609999999999999E+01 + 570 0 0 0 + 1.0199999999999999E+01 -1.4130000000000001E+01 1.7609999999999999E+01 + 583 0 0 0 + 1.0199999999999999E+01 1.4130000000000001E+01 1.7609999999999999E+01 + 591 0 0 0 + 1.0199999999999999E+01 0.0000000000000000E+00 1.8969999999999999E+01 + 592 0 0 0 + 1.0199999999999999E+01 -3.2556229999999999E-02 9.5263449999999992E+00 + -1 + -1 + 2412 + 1 44 2 1 7 4 + 1 167 164 2 + 2 44 2 1 7 4 + 167 346 344 164 + 3 44 2 1 7 4 + 346 455 453 344 + 9 44 2 1 7 4 + 2 164 163 3 + 10 44 2 1 7 4 + 164 344 345 163 + 11 44 2 1 7 4 + 344 453 454 345 + 17 44 2 1 7 4 + 3 163 169 4 + 18 44 2 1 7 4 + 163 345 353 169 + 19 44 2 1 7 4 + 345 454 463 353 + 25 44 2 1 7 4 + 4 169 170 5 + 26 44 2 1 7 4 + 169 353 355 170 + 27 44 2 1 7 4 + 353 463 466 355 + 33 44 2 1 7 4 + 5 170 171 6 + 34 44 2 1 7 4 + 170 355 356 171 + 35 44 2 1 7 4 + 355 466 469 356 + 41 44 2 1 7 4 + 6 171 186 7 + 42 44 2 1 7 4 + 171 356 361 186 + 43 44 2 1 7 4 + 356 469 473 361 + 49 44 2 1 7 4 + 7 186 188 8 + 50 44 2 1 7 4 + 186 361 366 188 + 51 44 2 1 7 4 + 361 473 479 366 + 57 44 2 1 7 4 + 8 188 191 9 + 58 44 2 1 7 4 + 188 366 368 191 + 59 44 2 1 7 4 + 366 479 487 368 + 65 44 2 1 7 4 + 9 191 194 10 + 66 44 2 1 7 4 + 191 368 370 194 + 67 44 2 1 7 4 + 368 487 490 370 + 73 44 2 1 7 4 + 10 194 195 11 + 74 44 2 1 7 4 + 194 370 378 195 + 75 44 2 1 7 4 + 370 490 497 378 + 81 44 2 1 7 4 + 11 195 206 12 + 82 44 2 1 7 4 + 195 378 380 206 + 83 44 2 1 7 4 + 378 497 499 380 + 89 44 2 1 7 4 + 12 206 209 13 + 90 44 2 1 7 4 + 206 380 384 209 + 91 44 2 1 7 4 + 380 499 505 384 + 97 44 2 1 7 4 + 13 209 217 14 + 98 44 2 1 7 4 + 209 384 395 217 + 99 44 2 1 7 4 + 384 505 510 395 + 105 44 2 1 7 4 + 14 217 218 15 + 106 44 2 1 7 4 + 217 395 398 218 + 107 44 2 1 7 4 + 395 510 515 398 + 113 44 2 1 7 4 + 15 218 225 16 + 114 44 2 1 7 4 + 218 398 405 225 + 115 44 2 1 7 4 + 398 515 522 405 + 121 44 2 1 7 4 + 16 225 226 17 + 122 44 2 1 7 4 + 225 405 408 226 + 123 44 2 1 7 4 + 405 522 527 408 + 129 44 2 1 7 4 + 17 226 227 18 + 130 44 2 1 7 4 + 226 408 410 227 + 131 44 2 1 7 4 + 408 527 531 410 + 137 44 2 1 7 4 + 18 227 228 19 + 138 44 2 1 7 4 + 227 410 411 228 + 139 44 2 1 7 4 + 410 531 533 411 + 145 44 2 1 7 4 + 20 245 244 21 + 146 44 2 1 7 4 + 245 426 425 244 + 147 44 2 1 7 4 + 426 558 559 425 + 153 44 2 1 7 4 + 21 244 243 22 + 154 44 2 1 7 4 + 244 425 424 243 + 155 44 2 1 7 4 + 425 559 560 424 + 161 44 2 1 7 4 + 22 243 242 23 + 162 44 2 1 7 4 + 243 424 423 242 + 163 44 2 1 7 4 + 424 560 557 423 + 169 44 2 1 7 4 + 23 242 241 24 + 170 44 2 1 7 4 + 242 423 422 241 + 171 44 2 1 7 4 + 423 557 550 422 + 177 44 2 1 7 4 + 24 241 240 25 + 178 44 2 1 7 4 + 241 422 421 240 + 179 44 2 1 7 4 + 422 550 547 421 + 185 44 2 1 7 4 + 25 240 238 26 + 186 44 2 1 7 4 + 240 421 417 238 + 187 44 2 1 7 4 + 421 547 541 417 + 193 44 2 1 7 4 + 26 238 228 19 + 194 44 2 1 7 4 + 238 417 411 228 + 195 44 2 1 7 4 + 417 541 533 411 + 201 44 2 1 7 4 + 27 174 173 29 + 202 44 2 1 7 4 + 174 349 350 173 + 203 44 2 1 7 4 + 349 460 459 350 + 209 44 2 1 7 4 + 29 173 172 30 + 210 44 2 1 7 4 + 173 350 354 172 + 211 44 2 1 7 4 + 350 459 465 354 + 217 44 2 1 7 4 + 30 172 277 31 + 218 44 2 1 7 4 + 172 354 437 277 + 219 44 2 1 7 4 + 354 465 528 437 + 225 44 2 1 7 4 + 31 277 183 32 + 226 44 2 1 7 4 + 277 437 362 183 + 227 44 2 1 7 4 + 437 528 475 362 + 233 44 2 1 7 4 + 32 183 184 33 + 234 44 2 1 7 4 + 183 362 363 184 + 235 44 2 1 7 4 + 362 475 476 363 + 241 44 2 1 7 4 + 33 184 187 34 + 242 44 2 1 7 4 + 184 363 365 187 + 243 44 2 1 7 4 + 363 476 478 365 + 249 44 2 1 7 4 + 34 187 190 35 + 250 44 2 1 7 4 + 187 365 367 190 + 251 44 2 1 7 4 + 365 478 485 367 + 257 44 2 1 7 4 + 36 216 215 37 + 258 44 2 1 7 4 + 216 376 393 215 + 259 44 2 1 7 4 + 376 495 504 393 + 265 44 2 1 7 4 + 37 215 224 38 + 266 44 2 1 7 4 + 215 393 399 224 + 267 44 2 1 7 4 + 393 504 512 399 + 273 44 2 1 7 4 + 38 224 223 39 + 274 44 2 1 7 4 + 224 399 404 223 + 275 44 2 1 7 4 + 399 512 520 404 + 281 44 2 1 7 4 + 39 223 233 40 + 282 44 2 1 7 4 + 223 404 409 233 + 283 44 2 1 7 4 + 404 520 526 409 + 289 44 2 1 7 4 + 40 233 266 41 + 290 44 2 1 7 4 + 233 409 446 266 + 291 44 2 1 7 4 + 409 526 570 446 + 297 44 2 1 7 4 + 41 266 239 42 + 298 44 2 1 7 4 + 266 446 418 239 + 299 44 2 1 7 4 + 446 570 540 418 + 305 44 2 1 7 4 + 42 239 238 26 + 306 44 2 1 7 4 + 239 418 417 238 + 307 44 2 1 7 4 + 418 540 541 417 + 313 44 2 1 7 4 + 2 164 173 29 + 314 44 2 1 7 4 + 164 344 350 173 + 315 44 2 1 7 4 + 344 453 459 350 + 321 44 2 1 7 4 + 4 169 277 31 + 322 44 2 1 7 4 + 169 353 437 277 + 323 44 2 1 7 4 + 353 463 528 437 + 329 44 2 1 7 4 + 7 186 187 34 + 330 44 2 1 7 4 + 186 361 365 187 + 331 44 2 1 7 4 + 361 473 478 365 + 337 44 2 1 7 4 + 36 216 206 12 + 338 44 2 1 7 4 + 216 376 380 206 + 339 44 2 1 7 4 + 376 495 499 380 + 345 44 2 1 7 4 + 38 224 217 14 + 346 44 2 1 7 4 + 224 399 395 217 + 347 44 2 1 7 4 + 399 512 510 395 + 353 44 2 1 7 4 + 40 233 225 16 + 354 44 2 1 7 4 + 233 409 405 225 + 355 44 2 1 7 4 + 409 526 522 405 + 361 44 2 1 7 4 + 35 190 216 36 + 362 44 2 1 7 4 + 190 367 376 216 + 363 44 2 1 7 4 + 367 485 495 376 + 369 44 2 1 7 4 + 1 167 166 53 + 370 44 2 1 7 4 + 167 346 347 166 + 371 44 2 1 7 4 + 346 455 456 347 + 377 44 2 1 7 4 + 53 166 165 54 + 378 44 2 1 7 4 + 166 347 348 165 + 379 44 2 1 7 4 + 347 456 457 348 + 385 44 2 1 7 4 + 54 165 177 55 + 386 44 2 1 7 4 + 165 348 357 177 + 387 44 2 1 7 4 + 348 457 467 357 + 393 44 2 1 7 4 + 55 177 178 56 + 394 44 2 1 7 4 + 177 357 359 178 + 395 44 2 1 7 4 + 357 467 471 359 + 401 44 2 1 7 4 + 56 178 179 57 + 402 44 2 1 7 4 + 178 359 360 179 + 403 44 2 1 7 4 + 359 471 472 360 + 409 44 2 1 7 4 + 57 179 200 58 + 410 44 2 1 7 4 + 179 360 369 200 + 411 44 2 1 7 4 + 360 472 484 369 + 417 44 2 1 7 4 + 58 200 205 59 + 418 44 2 1 7 4 + 200 369 377 205 + 419 44 2 1 7 4 + 369 484 491 377 + 425 44 2 1 7 4 + 59 205 208 60 + 426 44 2 1 7 4 + 205 377 382 208 + 427 44 2 1 7 4 + 377 491 498 382 + 433 44 2 1 7 4 + 60 208 213 61 + 434 44 2 1 7 4 + 208 382 392 213 + 435 44 2 1 7 4 + 382 498 507 392 + 441 44 2 1 7 4 + 61 213 214 62 + 442 44 2 1 7 4 + 213 392 396 214 + 443 44 2 1 7 4 + 392 507 516 396 + 449 44 2 1 7 4 + 62 214 219 63 + 450 44 2 1 7 4 + 214 396 400 219 + 451 44 2 1 7 4 + 396 516 517 400 + 457 44 2 1 7 4 + 63 219 220 64 + 458 44 2 1 7 4 + 219 400 402 220 + 459 44 2 1 7 4 + 400 517 521 402 + 465 44 2 1 7 4 + 64 220 229 65 + 466 44 2 1 7 4 + 220 402 406 229 + 467 44 2 1 7 4 + 402 521 524 406 + 473 44 2 1 7 4 + 65 229 230 66 + 474 44 2 1 7 4 + 229 406 412 230 + 475 44 2 1 7 4 + 406 524 529 412 + 481 44 2 1 7 4 + 66 230 234 67 + 482 44 2 1 7 4 + 230 412 414 234 + 483 44 2 1 7 4 + 412 529 538 414 + 489 44 2 1 7 4 + 67 234 235 68 + 490 44 2 1 7 4 + 234 414 415 235 + 491 44 2 1 7 4 + 414 538 542 415 + 497 44 2 1 7 4 + 68 235 236 69 + 498 44 2 1 7 4 + 235 415 416 236 + 499 44 2 1 7 4 + 415 542 544 416 + 505 44 2 1 7 4 + 69 236 237 70 + 506 44 2 1 7 4 + 236 416 419 237 + 507 44 2 1 7 4 + 416 544 548 419 + 513 44 2 1 7 4 + 71 246 247 72 + 514 44 2 1 7 4 + 246 427 428 247 + 515 44 2 1 7 4 + 427 556 561 428 + 521 44 2 1 7 4 + 72 247 250 73 + 522 44 2 1 7 4 + 247 428 431 250 + 523 44 2 1 7 4 + 428 561 563 431 + 529 44 2 1 7 4 + 73 250 251 74 + 530 44 2 1 7 4 + 250 431 434 251 + 531 44 2 1 7 4 + 431 563 565 434 + 537 44 2 1 7 4 + 74 251 252 75 + 538 44 2 1 7 4 + 251 434 435 252 + 539 44 2 1 7 4 + 434 565 566 435 + 545 44 2 1 7 4 + 75 252 253 76 + 546 44 2 1 7 4 + 252 435 433 253 + 547 44 2 1 7 4 + 435 566 564 433 + 553 44 2 1 7 4 + 76 253 254 77 + 554 44 2 1 7 4 + 253 433 432 254 + 555 44 2 1 7 4 + 433 564 562 432 + 561 44 2 1 7 4 + 77 254 255 78 + 562 44 2 1 7 4 + 254 432 429 255 + 563 44 2 1 7 4 + 432 562 555 429 + 569 44 2 1 7 4 + 78 255 237 70 + 570 44 2 1 7 4 + 255 429 419 237 + 571 44 2 1 7 4 + 429 555 548 419 + 577 44 2 1 7 4 + 27 174 175 79 + 578 44 2 1 7 4 + 174 349 352 175 + 579 44 2 1 7 4 + 349 460 461 352 + 585 44 2 1 7 4 + 79 175 176 80 + 586 44 2 1 7 4 + 175 352 358 176 + 587 44 2 1 7 4 + 352 461 470 358 + 593 44 2 1 7 4 + 80 176 289 81 + 594 44 2 1 7 4 + 176 358 439 289 + 595 44 2 1 7 4 + 358 470 534 439 + 601 44 2 1 7 4 + 81 289 196 82 + 602 44 2 1 7 4 + 289 439 371 196 + 603 44 2 1 7 4 + 439 534 486 371 + 609 44 2 1 7 4 + 82 196 201 83 + 610 44 2 1 7 4 + 196 371 373 201 + 611 44 2 1 7 4 + 371 486 488 373 + 617 44 2 1 7 4 + 83 201 207 84 + 618 44 2 1 7 4 + 201 373 379 207 + 619 44 2 1 7 4 + 373 488 493 379 + 625 44 2 1 7 4 + 84 207 212 85 + 626 44 2 1 7 4 + 207 379 388 212 + 627 44 2 1 7 4 + 379 493 503 388 + 633 44 2 1 7 4 + 86 222 221 87 + 634 44 2 1 7 4 + 222 397 403 221 + 635 44 2 1 7 4 + 397 514 519 403 + 641 44 2 1 7 4 + 87 221 232 88 + 642 44 2 1 7 4 + 221 403 407 232 + 643 44 2 1 7 4 + 403 519 525 407 + 649 44 2 1 7 4 + 88 232 231 89 + 650 44 2 1 7 4 + 232 407 413 231 + 651 44 2 1 7 4 + 407 525 532 413 + 657 44 2 1 7 4 + 89 231 259 90 + 658 44 2 1 7 4 + 231 413 420 259 + 659 44 2 1 7 4 + 413 532 539 420 + 665 44 2 1 7 4 + 90 259 267 91 + 666 44 2 1 7 4 + 259 420 447 267 + 667 44 2 1 7 4 + 420 539 583 447 + 673 44 2 1 7 4 + 91 267 256 92 + 674 44 2 1 7 4 + 267 447 430 256 + 675 44 2 1 7 4 + 447 583 554 430 + 681 44 2 1 7 4 + 92 256 255 78 + 682 44 2 1 7 4 + 256 430 429 255 + 683 44 2 1 7 4 + 430 554 555 429 + 689 44 2 1 7 4 + 53 166 175 79 + 690 44 2 1 7 4 + 166 347 352 175 + 691 44 2 1 7 4 + 347 456 461 352 + 697 44 2 1 7 4 + 55 177 289 81 + 698 44 2 1 7 4 + 177 357 439 289 + 699 44 2 1 7 4 + 357 467 534 439 + 705 44 2 1 7 4 + 58 200 207 84 + 706 44 2 1 7 4 + 200 369 379 207 + 707 44 2 1 7 4 + 369 484 493 379 + 713 44 2 1 7 4 + 86 222 219 63 + 714 44 2 1 7 4 + 222 397 400 219 + 715 44 2 1 7 4 + 397 514 517 400 + 721 44 2 1 7 4 + 88 232 229 65 + 722 44 2 1 7 4 + 232 407 406 229 + 723 44 2 1 7 4 + 407 525 524 406 + 729 44 2 1 7 4 + 90 259 234 67 + 730 44 2 1 7 4 + 259 420 414 234 + 731 44 2 1 7 4 + 420 539 538 414 + 737 44 2 1 7 4 + 85 212 222 86 + 738 44 2 1 7 4 + 212 388 397 222 + 739 44 2 1 7 4 + 388 503 514 397 + 745 44 2 1 7 4 + 1 167 174 27 + 746 44 2 1 7 4 + 167 346 349 174 + 747 44 2 1 7 4 + 346 455 460 349 + 753 44 2 1 7 4 + 27 174 168 48 + 754 44 2 1 7 4 + 174 349 351 168 + 755 44 2 1 7 4 + 349 460 462 351 + 761 44 2 1 7 4 + 48 168 278 49 + 762 44 2 1 7 4 + 168 351 436 278 + 763 44 2 1 7 4 + 351 462 530 436 + 769 44 2 1 7 4 + 49 278 182 101 + 770 44 2 1 7 4 + 278 436 364 182 + 771 44 2 1 7 4 + 436 530 480 364 + 777 44 2 1 7 4 + 101 182 261 102 + 778 44 2 1 7 4 + 182 364 374 261 + 779 44 2 1 7 4 + 364 480 492 374 + 785 44 2 1 7 4 + 102 261 210 103 + 786 44 2 1 7 4 + 261 374 394 210 + 787 44 2 1 7 4 + 374 492 508 394 + 793 44 2 1 7 4 + 103 210 263 104 + 794 44 2 1 7 4 + 210 394 401 263 + 795 44 2 1 7 4 + 394 508 518 401 + 801 44 2 1 7 4 + 104 263 265 52 + 802 44 2 1 7 4 + 263 401 445 265 + 803 44 2 1 7 4 + 401 518 569 445 + 809 44 2 1 7 4 + 52 265 339 28 + 810 44 2 1 7 4 + 265 445 448 339 + 811 44 2 1 7 4 + 445 569 591 448 + 817 44 2 1 7 4 + 71 246 339 28 + 818 44 2 1 7 4 + 246 427 448 339 + 819 44 2 1 7 4 + 427 556 591 448 + 825 44 2 1 7 4 + 71 246 245 20 + 826 44 2 1 7 4 + 246 427 426 245 + 827 44 2 1 7 4 + 427 556 558 426 + 838 11 2 1 7 2 + 0 0 0 + 450 436 + 839 11 2 1 7 2 + 0 0 0 + 305 278 + 845 11 2 1 7 2 + 0 0 0 + 449 450 + 846 11 2 1 7 2 + 0 0 0 + 304 305 + 852 11 2 1 7 2 + 0 0 0 + 437 449 + 853 11 2 1 7 2 + 0 0 0 + 277 304 + 859 11 2 1 7 2 + 0 0 0 + 350 349 + 860 11 2 1 7 2 + 0 0 0 + 173 174 + 861 11 2 1 7 2 + 0 0 0 + 29 27 + 867 11 2 1 7 2 + 0 0 0 + 346 344 + 868 11 2 1 7 2 + 0 0 0 + 167 164 + 869 11 2 1 7 2 + 0 0 0 + 1 2 + 875 11 2 1 7 2 + 0 0 0 + 477 452 + 876 11 2 1 7 2 + 0 0 0 + 316 302 + 882 11 2 1 7 2 + 0 0 0 + 483 477 + 883 11 2 1 7 2 + 0 0 0 + 326 316 + 889 11 2 1 7 2 + 0 0 0 + 482 483 + 890 11 2 1 7 2 + 0 0 0 + 325 326 + 896 11 2 1 7 2 + 0 0 0 + 481 482 + 897 11 2 1 7 2 + 0 0 0 + 315 325 + 903 11 2 1 7 2 + 0 0 0 + 452 481 + 904 11 2 1 7 2 + 0 0 0 + 302 315 + 910 11 2 1 7 2 + 0 0 0 + 446 502 + 911 11 2 1 7 2 + 0 0 0 + 266 297 + 917 11 2 1 7 2 + 0 0 0 + 502 536 + 918 11 2 1 7 2 + 0 0 0 + 297 318 + 924 11 2 1 7 2 + 0 0 0 + 536 545 + 925 11 2 1 7 2 + 0 0 0 + 318 327 + 931 11 2 1 7 2 + 0 0 0 + 545 546 + 932 11 2 1 7 2 + 0 0 0 + 327 328 + 938 11 2 1 7 2 + 0 0 0 + 546 543 + 939 11 2 1 7 2 + 0 0 0 + 328 317 + 945 11 2 1 7 2 + 0 0 0 + 543 506 + 946 11 2 1 7 2 + 0 0 0 + 317 294 + 952 11 2 1 7 2 + 0 0 0 + 506 445 + 953 11 2 1 7 2 + 0 0 0 + 294 265 + 954 11 2 1 7 2 + 0 0 0 + 216 268 + 955 11 2 1 7 2 + 0 0 0 + 268 292 + 956 11 2 1 7 2 + 0 0 0 + 292 311 + 957 11 2 1 7 2 + 0 0 0 + 311 313 + 958 11 2 1 7 2 + 0 0 0 + 313 314 + 959 11 2 1 7 2 + 0 0 0 + 314 306 + 960 11 2 1 7 2 + 0 0 0 + 306 269 + 961 11 2 1 7 2 + 0 0 0 + 224 295 + 962 11 2 1 7 2 + 0 0 0 + 295 383 + 963 11 2 1 7 2 + 0 0 0 + 383 443 + 964 11 2 1 7 2 + 0 0 0 + 443 444 + 965 11 2 1 7 2 + 0 0 0 + 444 372 + 966 11 2 1 7 2 + 0 0 0 + 372 290 + 967 11 2 1 7 2 + 0 0 0 + 233 293 + 968 11 2 1 7 2 + 0 0 0 + 293 381 + 969 11 2 1 7 2 + 0 0 0 + 381 441 + 970 11 2 1 7 2 + 0 0 0 + 441 442 + 971 11 2 1 7 2 + 0 0 0 + 442 375 + 972 11 2 1 7 2 + 0 0 0 + 375 291 + 978 11 2 1 7 2 + 0 0 0 + 451 458 + 979 11 2 1 7 2 + 0 0 0 + 312 319 + 985 11 2 1 7 2 + 0 0 0 + 439 451 + 986 11 2 1 7 2 + 0 0 0 + 289 312 + 992 11 2 1 7 2 + 0 0 0 + 352 349 + 993 11 2 1 7 2 + 0 0 0 + 175 174 + 994 11 2 1 7 2 + 0 0 0 + 79 27 + 1000 11 2 1 7 2 + 0 0 0 + 346 347 + 1001 11 2 1 7 2 + 0 0 0 + 167 166 + 1002 11 2 1 7 2 + 0 0 0 + 1 53 + 1008 11 2 1 7 2 + 0 0 0 + 496 468 + 1009 11 2 1 7 2 + 0 0 0 + 323 307 + 1015 11 2 1 7 2 + 0 0 0 + 501 496 + 1016 11 2 1 7 2 + 0 0 0 + 332 323 + 1022 11 2 1 7 2 + 0 0 0 + 500 501 + 1023 11 2 1 7 2 + 0 0 0 + 331 332 + 1029 11 2 1 7 2 + 0 0 0 + 494 500 + 1030 11 2 1 7 2 + 0 0 0 + 322 331 + 1036 11 2 1 7 2 + 0 0 0 + 468 494 + 1037 11 2 1 7 2 + 0 0 0 + 307 322 + 1043 11 2 1 7 2 + 0 0 0 + 447 511 + 1044 11 2 1 7 2 + 0 0 0 + 267 303 + 1050 11 2 1 7 2 + 0 0 0 + 511 551 + 1051 11 2 1 7 2 + 0 0 0 + 303 324 + 1057 11 2 1 7 2 + 0 0 0 + 551 552 + 1058 11 2 1 7 2 + 0 0 0 + 324 329 + 1064 11 2 1 7 2 + 0 0 0 + 552 553 + 1065 11 2 1 7 2 + 0 0 0 + 329 330 + 1071 11 2 1 7 2 + 0 0 0 + 553 549 + 1072 11 2 1 7 2 + 0 0 0 + 330 321 + 1073 11 2 1 7 2 + 0 0 0 + 222 270 + 1074 11 2 1 7 2 + 0 0 0 + 270 300 + 1075 11 2 1 7 2 + 0 0 0 + 300 309 + 1076 11 2 1 7 2 + 0 0 0 + 309 310 + 1077 11 2 1 7 2 + 0 0 0 + 310 308 + 1078 11 2 1 7 2 + 0 0 0 + 308 271 + 1079 11 2 1 7 2 + 0 0 0 + 271 260 + 1080 11 2 1 7 2 + 0 0 0 + 232 301 + 1081 11 2 1 7 2 + 0 0 0 + 301 386 + 1082 11 2 1 7 2 + 0 0 0 + 386 387 + 1083 11 2 1 7 2 + 0 0 0 + 387 385 + 1084 11 2 1 7 2 + 0 0 0 + 385 296 + 1085 11 2 1 7 2 + 0 0 0 + 296 262 + 1086 11 2 1 7 2 + 0 0 0 + 259 299 + 1087 11 2 1 7 2 + 0 0 0 + 299 390 + 1088 11 2 1 7 2 + 0 0 0 + 390 391 + 1089 11 2 1 7 2 + 0 0 0 + 391 389 + 1090 11 2 1 7 2 + 0 0 0 + 389 298 + 1091 11 2 1 7 2 + 0 0 0 + 298 264 + 1097 11 2 1 7 2 + 0 0 0 + 346 349 + 1098 11 2 1 7 2 + 0 0 0 + 167 174 + 1099 11 2 1 7 2 + 0 0 0 + 1 27 + 1100 11 2 1 7 2 + 0 0 0 + 291 263 + 1101 11 2 1 7 2 + 0 0 0 + 290 261 + 1102 11 2 1 7 2 + 0 0 0 + 269 278 + 1103 11 2 1 7 2 + 0 0 0 + 263 264 + 1104 11 2 1 7 2 + 0 0 0 + 261 262 + 1105 11 2 1 7 2 + 0 0 0 + 278 260 + 1106 11 2 1 7 2 + 0 0 0 + 319 340 + 1107 11 2 1 7 2 + 0 0 0 + 340 342 + 1108 11 2 1 7 2 + 0 0 0 + 342 343 + 1109 11 2 1 7 2 + 0 0 0 + 343 341 + 1110 11 2 1 7 2 + 0 0 0 + 341 320 + 1111 11 2 1 7 2 + 0 0 0 + 320 321 + 1112 11 2 1 7 2 + 0 0 0 + 458 474 + 1118 11 2 1 7 2 + 0 0 0 + 474 489 + 1124 11 2 1 7 2 + 0 0 0 + 489 509 + 1130 11 2 1 7 2 + 0 0 0 + 509 513 + 1136 11 2 1 7 2 + 0 0 0 + 513 523 + 1142 11 2 1 7 2 + 0 0 0 + 523 549 + 1153 11 2 1 7 2 + 0 0 0 + 448 591 + 1154 11 2 1 7 2 + 0 0 0 + 339 448 + 1155 11 2 1 7 2 + 0 0 0 + 28 339 + 1156 11 2 1 7 2 + 0 0 0 + 28 118 + 1157 11 2 1 7 2 + 0 0 0 + 118 152 + 1158 11 2 1 7 2 + 0 0 0 + 152 153 + 1159 11 2 1 7 2 + 0 0 0 + 153 154 + 1160 11 2 1 7 2 + 0 0 0 + 154 155 + 1161 11 2 1 7 2 + 0 0 0 + 28 157 + 1162 11 2 1 7 2 + 0 0 0 + 157 158 + 1163 11 2 1 7 2 + 0 0 0 + 158 159 + 1164 11 2 1 7 2 + 0 0 0 + 159 160 + 1165 11 2 1 7 2 + 0 0 0 + 155 156 + 1166 11 2 1 7 2 + 0 0 0 + 156 92 + 1167 11 2 1 7 2 + 0 0 0 + 160 161 + 1168 11 2 1 7 2 + 0 0 0 + 161 162 + 1169 11 2 1 7 2 + 0 0 0 + 162 42 + 1175 44 2 1 7 4 + 438 351 349 350 + 1176 44 2 1 7 4 + 180 168 174 173 + 1177 44 2 1 7 4 + 50 48 27 29 + 1183 44 2 1 7 4 + 450 436 351 438 + 1184 44 2 1 7 4 + 305 278 168 180 + 1190 44 2 1 7 4 + 449 438 350 354 + 1191 44 2 1 7 4 + 304 180 173 172 + 1197 44 2 1 7 4 + 354 350 344 345 + 1198 44 2 1 7 4 + 172 173 164 163 + 1199 44 2 1 7 4 + 30 29 2 3 + 1205 44 2 1 7 4 + 437 354 345 353 + 1206 44 2 1 7 4 + 277 172 163 169 + 1207 44 2 1 7 4 + 31 30 3 4 + 1213 44 2 1 7 4 + 362 437 353 355 + 1214 44 2 1 7 4 + 183 277 169 170 + 1215 44 2 1 7 4 + 32 31 4 5 + 1221 44 2 1 7 4 + 363 362 355 356 + 1222 44 2 1 7 4 + 184 183 170 171 + 1223 44 2 1 7 4 + 33 32 5 6 + 1229 44 2 1 7 4 + 365 363 356 361 + 1230 44 2 1 7 4 + 187 184 171 186 + 1236 44 2 1 7 4 + 452 365 361 366 + 1237 44 2 1 7 4 + 302 187 186 188 + 1238 44 2 1 7 4 + 43 34 7 8 + 1244 44 2 1 7 4 + 481 452 366 368 + 1245 44 2 1 7 4 + 315 302 188 191 + 1246 44 2 1 7 4 + 47 43 8 9 + 1252 44 2 1 7 4 + 477 367 365 452 + 1253 44 2 1 7 4 + 316 190 187 302 + 1254 44 2 1 7 4 + 46 35 34 43 + 1260 44 2 1 7 4 + 483 376 367 477 + 1261 44 2 1 7 4 + 326 216 190 316 + 1262 44 2 1 7 4 + 45 36 35 46 + 1268 44 2 1 7 4 + 378 482 481 370 + 1269 44 2 1 7 4 + 195 325 315 194 + 1270 44 2 1 7 4 + 11 44 47 10 + 1276 44 2 1 7 4 + 380 376 483 482 + 1277 44 2 1 7 4 + 206 216 326 325 + 1278 44 2 1 7 4 + 12 36 45 44 + 1284 44 2 1 7 4 + 384 393 376 380 + 1285 44 2 1 7 4 + 209 215 216 206 + 1286 44 2 1 7 4 + 13 37 36 12 + 1292 44 2 1 7 4 + 395 399 393 384 + 1293 44 2 1 7 4 + 217 224 215 209 + 1294 44 2 1 7 4 + 14 38 37 13 + 1300 44 2 1 7 4 + 398 404 399 395 + 1301 44 2 1 7 4 + 218 223 224 217 + 1302 44 2 1 7 4 + 15 39 38 14 + 1308 44 2 1 7 4 + 405 409 404 398 + 1309 44 2 1 7 4 + 225 233 223 218 + 1310 44 2 1 7 4 + 16 40 39 15 + 1316 44 2 1 7 4 + 408 446 409 405 + 1317 44 2 1 7 4 + 226 266 233 225 + 1318 44 2 1 7 4 + 17 41 40 16 + 1324 44 2 1 7 4 + 410 418 446 408 + 1325 44 2 1 7 4 + 227 239 266 226 + 1326 44 2 1 7 4 + 18 42 41 17 + 1332 44 2 1 7 4 + 411 417 418 410 + 1333 44 2 1 7 4 + 228 238 239 227 + 1334 44 2 1 7 4 + 19 26 42 18 + 1340 44 2 1 7 4 + 417 421 502 418 + 1341 44 2 1 7 4 + 238 240 297 239 + 1342 44 2 1 7 4 + 26 25 162 42 + 1348 44 2 1 7 4 + 421 422 536 502 + 1349 44 2 1 7 4 + 240 241 318 297 + 1350 44 2 1 7 4 + 25 24 161 162 + 1356 44 2 1 7 4 + 422 423 545 536 + 1357 44 2 1 7 4 + 241 242 327 318 + 1358 44 2 1 7 4 + 24 23 160 161 + 1364 44 2 1 7 4 + 423 424 546 545 + 1365 44 2 1 7 4 + 242 243 328 327 + 1366 44 2 1 7 4 + 23 22 159 160 + 1372 44 2 1 7 4 + 424 425 543 546 + 1373 44 2 1 7 4 + 243 244 317 328 + 1374 44 2 1 7 4 + 22 21 158 159 + 1380 44 2 1 7 4 + 425 426 506 543 + 1381 44 2 1 7 4 + 244 245 294 317 + 1382 44 2 1 7 4 + 21 20 157 158 + 1383 44 2 1 7 4 + 44 45 46 47 + 1384 44 2 1 7 4 + 110 113 33 34 + 1385 44 2 1 7 4 + 113 112 32 33 + 1386 44 2 1 7 4 + 112 111 31 32 + 1387 44 2 1 7 4 + 111 51 30 31 + 1388 44 2 1 7 4 + 51 50 29 30 + 1389 44 2 1 7 4 + 119 123 110 35 + 1390 44 2 1 7 4 + 123 135 113 110 + 1391 44 2 1 7 4 + 135 150 112 113 + 1392 44 2 1 7 4 + 150 151 111 112 + 1393 44 2 1 7 4 + 151 133 51 111 + 1394 44 2 1 7 4 + 133 120 50 51 + 1395 44 2 1 7 4 + 120 49 48 50 + 1396 44 2 1 7 4 + 37 131 119 36 + 1397 44 2 1 7 4 + 131 211 135 123 + 1398 44 2 1 7 4 + 211 258 150 135 + 1399 44 2 1 7 4 + 258 257 151 150 + 1400 44 2 1 7 4 + 257 181 133 151 + 1401 44 2 1 7 4 + 181 124 120 133 + 1402 44 2 1 7 4 + 38 143 131 37 + 1403 44 2 1 7 4 + 143 279 211 131 + 1404 44 2 1 7 4 + 279 337 258 211 + 1405 44 2 1 7 4 + 337 338 257 258 + 1406 44 2 1 7 4 + 338 272 181 257 + 1407 44 2 1 7 4 + 272 136 124 181 + 1408 44 2 1 7 4 + 39 142 143 38 + 1409 44 2 1 7 4 + 142 276 279 143 + 1410 44 2 1 7 4 + 276 335 337 279 + 1411 44 2 1 7 4 + 335 336 338 337 + 1412 44 2 1 7 4 + 336 273 272 338 + 1413 44 2 1 7 4 + 273 137 136 272 + 1414 44 2 1 7 4 + 40 141 142 39 + 1415 44 2 1 7 4 + 141 275 276 142 + 1416 44 2 1 7 4 + 275 333 335 276 + 1417 44 2 1 7 4 + 333 334 336 335 + 1418 44 2 1 7 4 + 334 274 273 336 + 1419 44 2 1 7 4 + 274 138 137 273 + 1420 44 2 1 7 4 + 41 125 141 40 + 1421 44 2 1 7 4 + 125 189 275 141 + 1422 44 2 1 7 4 + 189 248 333 275 + 1423 44 2 1 7 4 + 248 249 334 333 + 1424 44 2 1 7 4 + 249 192 274 334 + 1425 44 2 1 7 4 + 192 126 138 274 + 1426 44 2 1 7 4 + 42 162 125 41 + 1427 44 2 1 7 4 + 162 161 189 125 + 1428 44 2 1 7 4 + 161 160 248 189 + 1429 44 2 1 7 4 + 160 159 249 248 + 1430 44 2 1 7 4 + 159 158 192 249 + 1431 44 2 1 7 4 + 158 157 126 192 + 1432 44 2 1 7 4 + 268 119 123 292 + 1433 44 2 1 7 4 + 292 123 135 311 + 1434 44 2 1 7 4 + 311 135 150 313 + 1435 44 2 1 7 4 + 313 150 151 314 + 1436 44 2 1 7 4 + 314 151 133 306 + 1437 44 2 1 7 4 + 306 133 120 269 + 1438 44 2 1 7 4 + 216 36 119 268 + 1439 44 2 1 7 4 + 224 38 143 295 + 1440 44 2 1 7 4 + 295 143 279 383 + 1441 44 2 1 7 4 + 383 279 337 443 + 1442 44 2 1 7 4 + 443 337 338 444 + 1443 44 2 1 7 4 + 444 338 272 372 + 1444 44 2 1 7 4 + 372 272 136 290 + 1445 44 2 1 7 4 + 233 40 141 293 + 1446 44 2 1 7 4 + 293 141 275 381 + 1447 44 2 1 7 4 + 381 275 333 441 + 1448 44 2 1 7 4 + 441 333 334 442 + 1449 44 2 1 7 4 + 442 334 274 375 + 1450 44 2 1 7 4 + 375 274 138 291 + 1456 44 2 1 7 4 + 440 351 349 352 + 1457 44 2 1 7 4 + 185 168 174 175 + 1458 44 2 1 7 4 + 98 48 27 79 + 1464 44 2 1 7 4 + 458 436 351 440 + 1465 44 2 1 7 4 + 319 278 168 185 + 1471 44 2 1 7 4 + 451 440 352 358 + 1472 44 2 1 7 4 + 312 185 175 176 + 1478 44 2 1 7 4 + 358 352 347 348 + 1479 44 2 1 7 4 + 176 175 166 165 + 1480 44 2 1 7 4 + 80 79 53 54 + 1486 44 2 1 7 4 + 439 358 348 357 + 1487 44 2 1 7 4 + 289 176 165 177 + 1488 44 2 1 7 4 + 81 80 54 55 + 1494 44 2 1 7 4 + 371 439 357 359 + 1495 44 2 1 7 4 + 196 289 177 178 + 1496 44 2 1 7 4 + 82 81 55 56 + 1502 44 2 1 7 4 + 373 371 359 360 + 1503 44 2 1 7 4 + 201 196 178 179 + 1504 44 2 1 7 4 + 83 82 56 57 + 1510 44 2 1 7 4 + 379 373 360 369 + 1511 44 2 1 7 4 + 207 201 179 200 + 1512 44 2 1 7 4 + 84 83 57 58 + 1518 44 2 1 7 4 + 468 379 369 377 + 1519 44 2 1 7 4 + 307 207 200 205 + 1520 44 2 1 7 4 + 93 84 58 59 + 1526 44 2 1 7 4 + 494 468 377 382 + 1527 44 2 1 7 4 + 322 307 205 208 + 1528 44 2 1 7 4 + 97 93 59 60 + 1534 44 2 1 7 4 + 496 388 379 468 + 1535 44 2 1 7 4 + 323 212 207 307 + 1536 44 2 1 7 4 + 96 85 84 93 + 1542 44 2 1 7 4 + 501 397 388 496 + 1543 44 2 1 7 4 + 332 222 212 323 + 1544 44 2 1 7 4 + 95 86 85 96 + 1550 44 2 1 7 4 + 396 500 494 392 + 1551 44 2 1 7 4 + 214 331 322 213 + 1552 44 2 1 7 4 + 62 94 97 61 + 1558 44 2 1 7 4 + 400 397 501 500 + 1559 44 2 1 7 4 + 219 222 332 331 + 1560 44 2 1 7 4 + 63 86 95 94 + 1566 44 2 1 7 4 + 402 403 397 400 + 1567 44 2 1 7 4 + 220 221 222 219 + 1568 44 2 1 7 4 + 64 87 86 63 + 1574 44 2 1 7 4 + 406 407 403 402 + 1575 44 2 1 7 4 + 229 232 221 220 + 1576 44 2 1 7 4 + 65 88 87 64 + 1582 44 2 1 7 4 + 412 413 407 406 + 1583 44 2 1 7 4 + 230 231 232 229 + 1584 44 2 1 7 4 + 66 89 88 65 + 1590 44 2 1 7 4 + 414 420 413 412 + 1591 44 2 1 7 4 + 234 259 231 230 + 1592 44 2 1 7 4 + 67 90 89 66 + 1598 44 2 1 7 4 + 415 447 420 414 + 1599 44 2 1 7 4 + 235 267 259 234 + 1600 44 2 1 7 4 + 68 91 90 67 + 1606 44 2 1 7 4 + 416 430 447 415 + 1607 44 2 1 7 4 + 236 256 267 235 + 1608 44 2 1 7 4 + 69 92 91 68 + 1614 44 2 1 7 4 + 419 429 430 416 + 1615 44 2 1 7 4 + 237 255 256 236 + 1616 44 2 1 7 4 + 70 78 92 69 + 1622 44 2 1 7 4 + 429 432 511 430 + 1623 44 2 1 7 4 + 255 254 303 256 + 1624 44 2 1 7 4 + 78 77 156 92 + 1630 44 2 1 7 4 + 432 433 551 511 + 1631 44 2 1 7 4 + 254 253 324 303 + 1632 44 2 1 7 4 + 77 76 155 156 + 1638 44 2 1 7 4 + 433 435 552 551 + 1639 44 2 1 7 4 + 253 252 329 324 + 1640 44 2 1 7 4 + 76 75 154 155 + 1646 44 2 1 7 4 + 435 434 553 552 + 1647 44 2 1 7 4 + 252 251 330 329 + 1648 44 2 1 7 4 + 75 74 153 154 + 1654 44 2 1 7 4 + 434 431 549 553 + 1655 44 2 1 7 4 + 251 250 321 330 + 1656 44 2 1 7 4 + 74 73 152 153 + 1662 44 2 1 7 4 + 431 428 464 549 + 1663 44 2 1 7 4 + 250 247 193 321 + 1664 44 2 1 7 4 + 73 72 118 152 + 1670 44 2 1 7 4 + 428 427 448 464 + 1671 44 2 1 7 4 + 247 246 339 193 + 1672 44 2 1 7 4 + 72 71 28 118 + 1673 44 2 1 7 4 + 94 95 96 97 + 1674 44 2 1 7 4 + 114 117 83 84 + 1675 44 2 1 7 4 + 117 116 82 83 + 1676 44 2 1 7 4 + 116 115 81 82 + 1677 44 2 1 7 4 + 115 100 80 81 + 1678 44 2 1 7 4 + 100 98 79 80 + 1679 44 2 1 7 4 + 121 129 114 85 + 1680 44 2 1 7 4 + 129 139 117 114 + 1681 44 2 1 7 4 + 139 140 116 117 + 1682 44 2 1 7 4 + 140 134 115 116 + 1683 44 2 1 7 4 + 134 122 100 115 + 1684 44 2 1 7 4 + 122 99 98 100 + 1685 44 2 1 7 4 + 99 49 48 98 + 1686 44 2 1 7 4 + 87 132 121 86 + 1687 44 2 1 7 4 + 132 199 139 129 + 1688 44 2 1 7 4 + 199 198 140 139 + 1689 44 2 1 7 4 + 198 197 134 140 + 1690 44 2 1 7 4 + 197 127 122 134 + 1691 44 2 1 7 4 + 88 149 132 87 + 1692 44 2 1 7 4 + 149 287 199 132 + 1693 44 2 1 7 4 + 287 288 198 199 + 1694 44 2 1 7 4 + 288 280 197 198 + 1695 44 2 1 7 4 + 280 144 127 197 + 1696 44 2 1 7 4 + 89 148 149 88 + 1697 44 2 1 7 4 + 148 283 287 149 + 1698 44 2 1 7 4 + 283 284 288 287 + 1699 44 2 1 7 4 + 284 281 280 288 + 1700 44 2 1 7 4 + 281 145 144 280 + 1701 44 2 1 7 4 + 90 147 148 89 + 1702 44 2 1 7 4 + 147 285 283 148 + 1703 44 2 1 7 4 + 285 286 284 283 + 1704 44 2 1 7 4 + 286 282 281 284 + 1705 44 2 1 7 4 + 282 146 145 281 + 1706 44 2 1 7 4 + 91 128 147 90 + 1707 44 2 1 7 4 + 128 202 285 147 + 1708 44 2 1 7 4 + 202 203 286 285 + 1709 44 2 1 7 4 + 203 204 282 286 + 1710 44 2 1 7 4 + 204 130 146 282 + 1711 44 2 1 7 4 + 92 156 128 91 + 1712 44 2 1 7 4 + 156 155 202 128 + 1713 44 2 1 7 4 + 155 154 203 202 + 1714 44 2 1 7 4 + 154 153 204 203 + 1715 44 2 1 7 4 + 153 152 130 204 + 1716 44 2 1 7 4 + 270 121 129 300 + 1717 44 2 1 7 4 + 300 129 139 309 + 1718 44 2 1 7 4 + 309 139 140 310 + 1719 44 2 1 7 4 + 310 140 134 308 + 1720 44 2 1 7 4 + 308 134 122 271 + 1721 44 2 1 7 4 + 271 122 99 260 + 1722 44 2 1 7 4 + 222 86 121 270 + 1723 44 2 1 7 4 + 232 88 149 301 + 1724 44 2 1 7 4 + 301 149 287 386 + 1725 44 2 1 7 4 + 386 287 288 387 + 1726 44 2 1 7 4 + 387 288 280 385 + 1727 44 2 1 7 4 + 385 280 144 296 + 1728 44 2 1 7 4 + 259 90 147 299 + 1729 44 2 1 7 4 + 299 147 285 390 + 1730 44 2 1 7 4 + 390 285 286 391 + 1731 44 2 1 7 4 + 391 286 282 389 + 1732 44 2 1 7 4 + 389 282 146 298 + 1733 44 2 1 7 4 + 136 102 101 124 + 1734 44 2 1 7 4 + 137 103 102 136 + 1735 44 2 1 7 4 + 138 104 103 137 + 1736 44 2 1 7 4 + 124 101 49 120 + 1737 44 2 1 7 4 + 126 52 104 138 + 1738 44 2 1 7 4 + 157 28 52 126 + 1739 44 2 1 7 4 + 269 120 49 278 + 1740 44 2 1 7 4 + 290 136 102 261 + 1741 44 2 1 7 4 + 291 138 104 263 + 1742 44 2 1 7 4 + 278 49 99 260 + 1743 44 2 1 7 4 + 127 105 99 122 + 1744 44 2 1 7 4 + 105 101 49 99 + 1745 44 2 1 7 4 + 144 106 105 127 + 1746 44 2 1 7 4 + 106 102 101 105 + 1747 44 2 1 7 4 + 145 107 106 144 + 1748 44 2 1 7 4 + 107 103 102 106 + 1749 44 2 1 7 4 + 146 108 107 145 + 1750 44 2 1 7 4 + 108 104 103 107 + 1751 44 2 1 7 4 + 296 144 106 262 + 1752 44 2 1 7 4 + 262 106 102 261 + 1753 44 2 1 7 4 + 298 146 108 264 + 1754 44 2 1 7 4 + 264 108 104 263 + 1755 44 2 1 7 4 + 130 109 108 146 + 1756 44 2 1 7 4 + 109 52 104 108 + 1757 44 2 1 7 4 + 152 118 109 130 + 1758 44 2 1 7 4 + 118 28 52 109 + 1759 44 2 1 7 4 + 340 182 278 319 + 1760 44 2 1 7 4 + 342 261 182 340 + 1761 44 2 1 7 4 + 343 210 261 342 + 1762 44 2 1 7 4 + 341 263 210 343 + 1763 44 2 1 7 4 + 320 265 263 341 + 1764 44 2 1 7 4 + 193 339 265 320 + 1765 44 2 1 7 4 + 474 364 436 458 + 1771 44 2 1 7 4 + 489 374 364 474 + 1777 44 2 1 7 4 + 509 394 374 489 + 1783 44 2 1 7 4 + 513 401 394 509 + 1789 44 2 1 7 4 + 523 445 401 513 + 1795 44 2 1 7 4 + 464 448 445 523 + 1801 44 2 1 7 4 + 71 20 157 28 + 1802 44 2 1 7 4 + 246 245 294 339 + 1803 44 2 1 7 4 + 427 426 506 448 + 1809 44 2 1 7 4 + 34 33 6 7 + 1815 41 2 1 7 3 + 506 448 445 + 1816 41 2 1 7 3 + 294 339 265 + 1822 41 2 1 7 3 + 449 450 438 + 1823 41 2 1 7 3 + 304 305 180 + 1829 41 2 1 7 3 + 437 449 354 + 1830 41 2 1 7 3 + 277 304 172 + 1836 41 2 1 7 3 + 380 482 378 + 1837 41 2 1 7 3 + 206 325 195 + 1838 41 2 1 7 3 + 12 44 11 + 1843 41 2 1 7 3 + 370 481 368 + 1844 41 2 1 7 3 + 194 315 191 + 1845 41 2 1 7 3 + 10 47 9 + 1846 41 2 1 7 3 + 43 46 47 + 1847 41 2 1 7 3 + 35 110 34 + 1849 41 2 1 7 3 + 36 119 35 + 1850 41 2 1 7 3 + 131 123 119 + 1851 41 2 1 7 3 + 239 297 266 + 1852 41 2 1 7 3 + 418 502 446 + 1863 41 2 1 7 3 + 451 458 440 + 1864 41 2 1 7 3 + 312 319 185 + 1870 41 2 1 7 3 + 439 451 358 + 1871 41 2 1 7 3 + 289 312 176 + 1877 41 2 1 7 3 + 400 500 396 + 1878 41 2 1 7 3 + 219 331 214 + 1879 41 2 1 7 3 + 63 94 62 + 1884 41 2 1 7 3 + 392 494 382 + 1885 41 2 1 7 3 + 213 322 208 + 1886 41 2 1 7 3 + 61 97 60 + 1887 41 2 1 7 3 + 93 96 97 + 1888 41 2 1 7 3 + 85 114 84 + 1890 41 2 1 7 3 + 86 121 85 + 1891 41 2 1 7 3 + 132 129 121 + 1892 41 2 1 7 3 + 256 303 267 + 1893 41 2 1 7 3 + 430 511 447 + 1899 41 2 1 7 3 + 193 321 320 + 1900 41 2 1 7 3 + 464 549 523 + -1 diff --git a/idl/SALOME_Comm.idl b/idl/SALOME_Comm.idl new file mode 100644 index 000000000..a01eca1a6 --- /dev/null +++ b/idl/SALOME_Comm.idl @@ -0,0 +1,81 @@ +#include "SALOME_Exception.idl" + +module SALOME { + + enum TypeOfDataTransmitted { _DOUBLE_,_INT_ }; + + enum TypeOfCommunication { CORBA_ , MPI_ , SOCKET_ }; + + typedef sequence vectorOfDouble; + + typedef sequence vectorOfLong; + + interface MultiCommClass { + void setProtocol(in TypeOfCommunication typ); + }; + + interface ServantLifeCycle { + void release(); + }; + + interface Sender { + TypeOfDataTransmitted getTypeOfDataTransmitted(); + Sender buildOtherWithProtocol(in TypeOfCommunication type); + void release(); + }; + + //No compulsory copy between double and CORBA::Double + interface CorbaDoubleNCSender : Sender { + unsigned long getSize(); + vectorOfDouble sendPart(in unsigned long n1,in unsigned long n2); + vectorOfDouble send(); + }; + + //Compulsory copy between double and CORBA::Double + interface CorbaDoubleCSender : Sender { + unsigned long getSize(); + //unsigned long getSize2(); + vectorOfDouble sendPart(in unsigned long n1,in unsigned long n2); + }; + + //No compulsory copy between int and CORBA::Long + interface CorbaLongNCSender : Sender { + unsigned long getSize(); + vectorOfLong sendPart(in unsigned long n1,in unsigned long n2); + vectorOfLong send(); + }; + + //Compulsory copy between int and CORBA::Long + interface CorbaLongCSender : Sender { + unsigned long getSize(); + vectorOfLong sendPart(in unsigned long n1,in unsigned long n2); + }; + + interface MPISender : Sender { + typedef struct Parameter { + unsigned long myproc; + unsigned long tag1; + unsigned long tag2; + string service; + } param; + param getParam(); + void send(); + void close(in param p); + }; + + interface SocketSender : Sender { + typedef struct Parameter { + unsigned long lstart; + unsigned long lend; + unsigned long myport; + string internet_address; + } param; + param getParam(); + void initCom() raises(SALOME_Exception); + void acceptCom() raises(SALOME_Exception); + void closeCom(); + void endOfCom() raises(SALOME_Exception); + void send(); + }; + +}; diff --git a/make_config.in b/make_config.in new file mode 100755 index 000000000..64b47c344 --- /dev/null +++ b/make_config.in @@ -0,0 +1,75 @@ +# make_config.in: template for make_config script +# make_config is used by check_cas.m4 to generate +# config.h file in case it cannot be found in OCC +# and SALOME include paths +#================================================= +dnl Process this file with autoconf to produce a configure script. + +AC_INIT(salome_adm/unix) +AC_CONFIG_SRCDIR(salome_adm/unix/config.h.in) +AC_CONFIG_AUX_DIR(salome_adm/unix/config_files) +AC_CANONICAL_HOST + +AC_CONFIG_HEADERS(./salome_adm/unix/config.h) + +AC_ISC_POSIX +AC_C_BIGENDIAN + +dnl Checks for programs. +AC_PROG_CXX +AC_PROG_CC_C_O + +AC_PROG_AWK +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_YACC +AC_PROG_MAKE_SET + +dnl Replace `main' with a function in -le: +AC_CHECK_LIB(e, main) + +dnl Replace `main' with a function in -links: +AC_CHECK_LIB(inks, main) + +dnl Checks for X window system directories. +AC_PATH_X +if test "x$ac_x_includes" = "x"; then + X_INCLUDE="" +else + X_INCLUDE="-I$ac_x_includes" +fi +if test "x$ac_x_libraries" = "x"; then + X_LIBS="-lXt -lX11" +else + X_LIBS="-L$ac_x_libraries -lXt -lX11" +fi + +dnl Checks for header files. + +AC_HEADER_STDC +AC_LANG([C]) +AC_MSG_CHECKING([ for C header files ]) +AC_CHECK_HEADERS(dlfcn.h dl.h ieeefp.h time.h sys/time.h pwd.h) +AC_CHECK_HEADERS(sys/statvfs.h sys/vfs.h sys/param.h osfcn.h netdb.h) +AC_CHECK_HEADERS(sys/ioctl.h net/if.h sys/systeminfo.h sys/utsname.h) +AC_CHECK_HEADERS(sysent.h unistd.h sys/unistd.h sys/socket.h) +AC_CHECK_HEADERS(ndir.h sys/ndir.h sys/dir.h signal.h sys/signal.h) +AC_CHECK_HEADERS(sigfpe.h floatingpoint.h sys/machsig.h sys/siginfo.h) +AC_CHECK_HEADERS(malloc.h strings.h sys/stat.h sys/sem.h sys/ipc.h) +AC_CHECK_HEADERS(sys/times.h dirent.h getopt.h sys/vnode.h) + + +AC_LANG([C++]) +AC_MSG_CHECKING([ for C++ header files ]) +AC_CHECK_HEADERS(istream ostream istream fstream ios iomanip iostream ) +AC_CHECK_HEADERS(stream.h strstream.h istream.h ostream.h fstream.h stdlib.h ios.h iostream.h) +AC_CHECK_HEADERS(iomanip.h limits.h values.h float.h) +AC_CHECK_HEADERS(siginfo.h bits/sigset.h bstring.h sys/types.h sys/select.h) +AC_CHECK_HEADERS(X11/extensions/transovl.h X11/extensions/readdisplay.h) +AC_CHECK_HEADERS(X11/extensions/multibuf.h) +AC_CHECK_HEADERS(sys/filio.h sys/mman.h libc.h) + +dnl Checks for library functions. +AC_TYPE_SIGNAL + +AC_OUTPUT() diff --git a/salome_adm/unix/config.h.in b/salome_adm/unix/config.h.in new file mode 100755 index 000000000..19d28510f --- /dev/null +++ b/salome_adm/unix/config.h.in @@ -0,0 +1,350 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +#undef CRAY_STACKSEG_END + +/* Define to 1 if using `alloca.c'. */ +#undef C_ALLOCA + +/* define if the compiler allows redefinition of stream input and output */ +#undef DEF_IOS_OK + +/* Define to 1 if you have `alloca', as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#undef HAVE_ALLOCA_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_BITS_SIGSET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_BSTRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DIRENT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DPS_DPSXCLIENT_H + +/* Define if we have a function called "finite" in -lm. */ +#undef HAVE_FINITE + +/* Define to 1 if you have the header file. */ +#undef HAVE_FLOATINGPOINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FLOAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FSTREAM + +/* Define to 1 if you have the header file. */ +#undef HAVE_FSTREAM_H + +/* Define to 1 if you have the `gethostname' function. */ +#undef HAVE_GETHOSTNAME + +/* Define to 1 if you have the header file. */ +#undef HAVE_GETOPT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_IEEEFP_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_IOMANIP + +/* Define to 1 if you have the header file. */ +#undef HAVE_IOMANIP_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_IOS + +/* Define to 1 if you have the header file. */ +#undef HAVE_IOSTREAM + +/* Define to 1 if you have the header file. */ +#undef HAVE_IOSTREAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_IOS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ISTREAM + +/* Define to 1 if you have the header file. */ +#undef HAVE_ISTREAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBC_H + +/* Define to 1 if you have the `e' library (-le). */ +#undef HAVE_LIBE + +/* Define to 1 if you have the `inks' library (-links). */ +#undef HAVE_LIBINKS + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define if we have a function called "mallinfo" in -lmalloc. */ +#undef HAVE_MALLINFO + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NET_IF_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OSFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OSTREAM + +/* Define to 1 if you have the header file. */ +#undef HAVE_OSTREAM_H + +/* Define to 1 if you have the `putenv' function. */ +#undef HAVE_PUTENV + +/* Define to 1 if you have the header file. */ +#undef HAVE_PWD_H + +/* Define to 1 if you have the `regcomp' function. */ +#undef HAVE_REGCOMP + +/* Define to 1 if you have the `re_comp' function. */ +#undef HAVE_RE_COMP + +/* Define to 1 if you have the header file. */ +#undef HAVE_SIGFPE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SIGINFO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SIGNAL_H + +/* Define to 1 if you have the `statfs' function. */ +#undef HAVE_STATFS + +/* Define to 1 if you have the `statvfs' function. */ +#undef HAVE_STATVFS + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strcspn' function. */ +#undef HAVE_STRCSPN + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the header file. */ +#undef HAVE_STREAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRSTREAM_H + +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + +/* Define if we have a function called "ieee_handler" in -lsunmath. */ +#undef HAVE_SUNMATH + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYSENT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_DIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_FILIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IPC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_MACHSIG_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_MMAN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SEM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SIGINFO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SIGNAL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STATVFS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SYSTEMINFO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIMES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UNISTD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UTSNAME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_VFS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_VNODE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_VALUES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_X11_EXTENSIONS_MULTIBUF_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_X11_EXTENSIONS_READDISPLAY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_X11_EXTENSIONS_TRANSOVL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_XMU_EDITRES_H + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +#undef NO_MINUS_C_MINUS_O + +/* define if the class ostream has member function form */ +#undef OSTREAM_FORM_OK + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define if compiler has function prototypes */ +#undef PROTOTYPES + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* define if the function semctl takes a value */ +#undef SEMCTL_NO_REFERENCE + +/* define if the function semop takes a value */ +#undef SEMOP_NO_REFERENCE + +/* define if semun has member __buf */ +#undef SEMUN_BUF_DEFINED + +/* define if the union semun is in sys/sem.h */ +#undef SEMUN_DEFINED + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if your declares `struct tm'. */ +#undef TM_IN_SYS_TIME + +/* Version number of package */ +#undef VERSION + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* Define to 1 if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif + +/* Define to `unsigned' if does not define. */ +#undef size_t diff --git a/salome_adm/unix/config_files/check_lam.m4 b/salome_adm/unix/config_files/check_lam.m4 new file mode 100644 index 000000000..ab62ab44a --- /dev/null +++ b/salome_adm/unix/config_files/check_lam.m4 @@ -0,0 +1,74 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl + +AC_DEFUN([CHECK_LAM],[ + +AC_REQUIRE([AC_PROG_CC])dnl + +AC_ARG_WITH(lam, + --with-lam=DIR root directory path of LAM installation, + WITHLAM="yes",WITHLAM="no") + +MPI_INCLUDES="" +MPI_LIBS="" +if test "$WITHLAM" = yes; then + + echo + echo --------------------------------------------- + echo testing lam + echo --------------------------------------------- + echo + LAM_HOME=$withval + + if test "$LAM_HOME"; then + MPI_INCLUDES="-I$LAM_HOME/include" + MPI_LIBS="-L$LAM_HOME/lib" + fi + + CPPFLAGS_old="$CPPFLAGS" + CPPFLAGS="$MPI_INCLUDES $CPPFLAGS" + AC_CHECK_HEADER(mpi.h,WITHLAM="yes",WITHLAM="no") + CPPFLAGS="$CPPFLAGS_old" + + if test "$WITHLAM" = "yes";then + AC_CHECK_LIB(util,openpty,,WITHLAM="no") + LIBS_old="$LIBS" + LDFLAGS_old="$LDFLAGS" + LDFLAGS="$MPI_LIBS $LDFLAGS" + AC_CHECK_LIB(lam,lam_mp_init,,WITHLAM="no") + AC_CHECK_LIB(mpi,MPI_Init,WITHLAM="yes",WITHLAM="no") + AC_CHECK_LIB(mpi,MPI_Publish_name,WITHMPI2="yes",WITHMPI2="no") + LDFLAGS="$LDFLAGS_old" + LIBS="$LIBS_old" + fi + + if test "$WITHLAM" = "yes";then + mpi_ok=yes + MPI_LIBS="$MPI_LIBS -lmpi -llam" + else + mpi_ok=no + fi + +fi + + +])dnl diff --git a/salome_adm/unix/config_files/check_openpbs.m4 b/salome_adm/unix/config_files/check_openpbs.m4 new file mode 100644 index 000000000..9598285c9 --- /dev/null +++ b/salome_adm/unix/config_files/check_openpbs.m4 @@ -0,0 +1,57 @@ +# Check for OpenPBS +AC_DEFUN([CHECK_OPENPBS], +[ + AC_ARG_VAR([OPENPBS], [OpenPBS home directory]) + AC_ARG_WITH([openpbs], + AC_HELP_STRING([--with-openpbs=], + [tell configure script to use OpenPBS that is located at ]), + [test ! x"${withval}" = xyes && OPENPBS=${withval}], + []) + + dnl AC_ARG_VAR([OPENPBSSERVERNAME], [OpenPBS server_name file]) + dnl AC_ARG_WITH([openpbs-server-name], + dnl AC_HELP_STRING([--with-openpbs-server-name=], + dnl [tell configure script to use OpenPBS server_name file that is located at ]), + dnl [test ! x"${withval}" = xyes && OPENPBSSERVERNAME=${withval}], + dnl [with_openpbs_server_name=""]) + + + if test -z "${OPENPBS}" + then + AC_MSG_WARN([Environment variable OPENPBS not set. Skipping OpenPBS configuration.]) + + else + + OPENPBS_INCLUDES="-I${OPENPBS}/include" + saved_CPPFLAGS=${CPPFLAGS} + CPPFLAGS="${CPPFLAGS} ${OPENPBS_INCLUDES}" + AC_CHECK_HEADER([pbs_ifl.h], [openpbs_header_found=yes], [openpbs_header_found=no], []) + test x${openpbs_header_found} = xno && AC_MSG_WARN([OpenPBS include file not found]) + CPPFLAGS=${saved_CPPFLAGS} + AC_SUBST(OPENPBS_INCLUDES) + + OPENPBS_LIBDIR="-L${OPENPBS}/lib" + OPENPBS_LIBS="-lpbs" + saved_LDFLAGS=${LDFLAGS} + saved_LIBS=${LIBS} + LDFLAGS="${LDFLAGS} ${OPENPBS_LIBDIR}" + AC_CHECK_LIB([pbs], [pbs_connect], [openpbs_lib_found=yes], [openpbs_lib_found=no], []) + test x${openpbs_lib_found} = xno && AC_MSG_WARN([OpenPBS library not found]) + LIBS="${LIBS} ${OPENPBS_LIBS}" + LDFLAGS=${saved_LDFLAGS} + LIBS=${saved_LIBS} + AC_SUBST(OPENPBS_LIBDIR) + AC_SUBST(OPENPBS_LIBS) + + dnl test -z "${OPENPBSSERVERNAME}" && OPENPBSSERVERNAME="/usr/spool/PBS/server_name" + dnl AC_CHECK_FILE([${OPENPBSSERVERNAME}], [openpbs_server_name_found=yes], [openpbs_server_name_found=no]) + + test x${openpbs_header_found} = xyes && test x${openpbs_lib_found} = xyes && openpbs_ok="yes" + + fi + + WITHOPENPBS=$openpbs_ok + AC_SUBST(WITHOPENPBS) + +]) + diff --git a/salome_adm/unix/config_files/check_sockets.m4 b/salome_adm/unix/config_files/check_sockets.m4 new file mode 100644 index 000000000..f3086ad52 --- /dev/null +++ b/salome_adm/unix/config_files/check_sockets.m4 @@ -0,0 +1,86 @@ +AC_DEFUN([CHECK_SOCKETS],[ + +dnl Author + +dnl Warren Young +dnl M4 Source Code + +echo +echo --------------------------------------------- +echo testing sockets +echo --------------------------------------------- +echo + +AC_CACHE_CHECK(for libraries containing socket functions, +ac_cv_socket_libs, [ + oCFLAGS=$CFLAGS + + AC_TRY_LINK([ + #include + #include + #include + #include + ], + [ + struct in_addr add; + int sd = socket(AF_INET, SOCK_STREAM, 0); + inet_ntoa(add); + ], + ac_cv_socket_libs=-lc, ac_cv_socket_libs=no) + + if test x"$ac_cv_socket_libs" = "xno" + then + CFLAGS="$oCFLAGS -lsocket" + AC_TRY_LINK([ + #include + #include + #include + #include + ], + [ + struct in_addr add; + int sd = socket(AF_INET, SOCK_STREAM, 0); + inet_ntoa(add); + ], + ac_cv_socket_libs=-lsocket, ac_cv_socket_libs=no) + fi + + if test x"$ac_cv_socket_libs" = "xno" + then + CFLAGS="$oCFLAGS -lsocket -lnsl" + AC_TRY_LINK([ + #include + #include + #include + #include + ], + [ + struct in_addr add; + int sd = socket(AF_INET, SOCK_STREAM, 0); + inet_ntoa(add); + ], + ac_cv_socket_libs="-lsocket -lnsl", ac_cv_socket_libs=no) + fi + + CFLAGS=$oCFLAGS +]) + + if test x"$ac_cv_socket_libs" = "xno" + then + AC_MSG_ERROR([Cannot find socket libraries]) + elif test x"$ac_cv_socket_libs" = "x-lc" + then + SOCKETLIBS="" + CPPFLAGS="-DHAVE_SOCKET $CPPFLAGS" + CORBA_IDLCXXFLAGS="-DHAVE_SOCKET $CORBA_IDLCXXFLAGS" + CORBA_IDLPYFLAGS="-DHAVE_SOCKET $CORBA_IDLPYFLAGS" + else + SOCKETLIBS="$ac_cv_socket_libs" + CPPFLAGS="-DHAVE_SOCKET $CPPFLAGS" + CORBA_IDLCXXFLAGS="-DHAVE_SOCKET $CORBA_IDLCXXFLAGS" + CORBA_IDLPYFLAGS="-DHAVE_SOCKET $CORBA_IDLPYFLAGS" + fi + + AC_SUBST(SOCKETLIBS) + AC_SUBST(SOCKETFLAGS) +]) dnl CHECK_SOCKET diff --git a/src/Batch/Batch_APIInternalFailureException.cxx b/src/Batch/Batch_APIInternalFailureException.cxx new file mode 100644 index 000000000..42e52aa9e --- /dev/null +++ b/src/Batch/Batch_APIInternalFailureException.cxx @@ -0,0 +1,15 @@ +/* + * APIInternalFailureException.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Thu Nov 20 15:15:42 2003 + * Projet : Salome 2 + * + */ + +#include "Batch_APIInternalFailureException.hxx" + +namespace Batch { + +} diff --git a/src/Batch/Batch_APIInternalFailureException.hxx b/src/Batch/Batch_APIInternalFailureException.hxx new file mode 100644 index 000000000..14bf01f4f --- /dev/null +++ b/src/Batch/Batch_APIInternalFailureException.hxx @@ -0,0 +1,29 @@ +/* + * APIInternalFailureException.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Thu Nov 20 15:15:41 2003 + * Projet : Salome 2 + * + */ + +#ifndef _APIINTERNALFAILUREEXCEPTION_H_ +#define _APIINTERNALFAILUREEXCEPTION_H_ + + +#include "Batch_GenericException.hxx" +#include "Batch_GenericException.hxx" + +namespace Batch { + + class APIInternalFailureException : public GenericException + { + public: + // Constructeur + APIInternalFailureException(string ch = "undefined") : GenericException("APIInternalFailureException", ch) {} + }; + +} + +#endif diff --git a/src/Batch/Batch_BatchManager.cxx b/src/Batch/Batch_BatchManager.cxx new file mode 100644 index 000000000..e84d3bdaf --- /dev/null +++ b/src/Batch/Batch_BatchManager.cxx @@ -0,0 +1,122 @@ +/* + * BatchManager.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#include +#include +#include +#include +//#include "MEDMEM_STRING.hxx" +#include "Batch_Job.hxx" +#include "Batch_JobId.hxx" +#include "Batch_JobInfo.hxx" +#include "Batch_InvalidArgumentException.hxx" +#include "Batch_FactBatchManager.hxx" +#include "Batch_BatchManager.hxx" + +namespace Batch { + + // Constructeur +// BatchManager::BatchManager(string host) throw(InvalidArgumentException) : _hostname(host), jobid_map() +// { +// // On verifie que le hostname est correct +// if (!gethostbyname(_hostname.c_str())) { // hostname unknown from network +// string msg = "hostname \""; +// msg += _hostname; +// msg += "\" unknown from the network"; +// throw InvalidArgumentException(msg.c_str()); +// } +// } + BatchManager::BatchManager(const FactBatchManager * parent, const char * host) throw(InvalidArgumentException) : _hostname(host), jobid_map(), _parent(parent) + { + // On verifie que le hostname est correct + if (!gethostbyname(_hostname.c_str())) { // hostname unknown from network + string msg = "hostname \""; + msg += _hostname; + msg += "\" unknown from the network"; + throw InvalidArgumentException(msg.c_str()); + } + } + + // Destructeur + BatchManager::~BatchManager() + { + // Nothing to do + } + + string BatchManager::__repr__() const + { + ostringstream oss; + oss << "getType() : "unknown (no factory)") << "' connected to server '" << _hostname << "'>"; + return oss.str(); + } + + // Recupere le l'identifiant d'un job deja soumis au BatchManager +// const JobId BatchManager::getJobIdByReference(const string & ref) +// { +// return JobId(this, ref); +// } + const JobId BatchManager::getJobIdByReference(const char * ref) + { + return JobId(this, ref); + } + +// // Methode pour le controle des jobs : soumet un job au gestionnaire +// const JobId BatchManager::submitJob(const Job & job) +// { +// static int idx = 0; +// //MEDMEM::STRING sst; +// ostringstream sst; +// sst << "Jobid_" << idx++; +// JobId id(this, sst.str()); +// return id; +// } + +// // Methode pour le controle des jobs : retire un job du gestionnaire +// void BatchManager::deleteJob(const JobId & jobid) +// { +// // Nothing to do +// } + +// // Methode pour le controle des jobs : suspend un job en file d'attente +// void BatchManager::holdJob(const JobId & jobid) +// { +// // Nothing to do +// } + +// // Methode pour le controle des jobs : relache un job suspendu +// void BatchManager::releaseJob(const JobId & jobid) +// { +// // Nothing to do +// } + +// // Methode pour le controle des jobs : modifie un job en file d'attente +// void BatchManager::alterJob(const JobId & jobid, const Parametre & param, const Environnement & env) +// { +// // Nothing to do +// } + +// // Methode pour le controle des jobs : modifie un job en file d'attente +// void BatchManager::alterJob(const JobId & jobid, const Parametre & param) +// { +// // Nothing to do +// } + +// // Methode pour le controle des jobs : modifie un job en file d'attente +// void BatchManager::alterJob(const JobId & jobid, const Environnement & env) +// { +// // Nothing to do +// } + +// // Methode pour le controle des jobs : renvoie l'etat du job +// JobInfo BatchManager::queryJob(const JobId & jobid) +// { +// return JobInfo(); +// } + +} diff --git a/src/Batch/Batch_BatchManager.hxx b/src/Batch/Batch_BatchManager.hxx new file mode 100644 index 000000000..47820ef0b --- /dev/null +++ b/src/Batch/Batch_BatchManager.hxx @@ -0,0 +1,62 @@ +/* + * BatchManager.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#ifndef _BATCHMANAGER_H_ +#define _BATCHMANAGER_H_ + +using namespace std; +#include +#include +#include "Batch_Job.hxx" +#include "Batch_JobId.hxx" +#include "Batch_JobInfo.hxx" +#include "Batch_InvalidArgumentException.hxx" + +namespace Batch { + + class Job; + class JobId; + class JobInfo; + class FactBatchManager; + + class BatchManager + { + public: + // Constructeur et destructeur + //BatchManager(string host="localhost") throw(InvalidArgumentException); // connexion a la machine host + BatchManager(const FactBatchManager * parent, const char * host="localhost") throw(InvalidArgumentException); // connexion a la machine host + virtual ~BatchManager(); + virtual string __repr__() const; + + // Recupere le l'identifiant d'un job deja soumis au BatchManager + //virtual const JobId getJobIdByReference(const string & ref); + virtual const JobId getJobIdByReference(const char * ref); + + // Methodes pour le controle des jobs : virtuelles pures + virtual const JobId submitJob(const Job & job) = 0; // soumet un job au gestionnaire + virtual void deleteJob(const JobId & jobid) = 0; // retire un job du gestionnaire + virtual void holdJob(const JobId & jobid) = 0; // suspend un job en file d'attente + virtual void releaseJob(const JobId & jobid) = 0; // relache un job suspendu + virtual void alterJob(const JobId & jobid, const Parametre & param, const Environnement & env) = 0; // modifie un job en file d'attente + virtual void alterJob(const JobId & jobid, const Parametre & param) = 0; // modifie un job en file d'attente + virtual void alterJob(const JobId & jobid, const Environnement & env) = 0; // modifie un job en file d'attente + virtual JobInfo queryJob(const JobId & jobid) = 0; // renvoie l'etat du job + + protected: + string _hostname; // serveur ou tourne le BatchManager + map< const string, const JobId * > jobid_map; // table des jobs deja soumis + const FactBatchManager * _parent; + + private: + + }; + +} + +#endif diff --git a/src/Batch/Batch_BatchManagerCatalog.cxx b/src/Batch/Batch_BatchManagerCatalog.cxx new file mode 100644 index 000000000..437be93fb --- /dev/null +++ b/src/Batch/Batch_BatchManagerCatalog.cxx @@ -0,0 +1,73 @@ +/* + * BatchManagerCatalog.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2004 + * Projet : SALOME 2 + * + */ + +#include +#include +#include +#include "Batch_BatchManagerCatalog.hxx" +#include "Batch_FactBatchManager.hxx" + +namespace Batch { + + pthread_mutex_t BatchManagerCatalog::_mutex = PTHREAD_MUTEX_INITIALIZER; + map * BatchManagerCatalog::_p_catalog = 0; + + // Constructeur + BatchManagerCatalog::BatchManagerCatalog() + { + // Nothing to do + } + + // Destructeur + BatchManagerCatalog::~BatchManagerCatalog() + { + // Nothing to do + } + + // Functor + FactBatchManager * BatchManagerCatalog::getFactBatchManager(const char * type) + { + return (* BatchManagerCatalog::_p_catalog)[type]; + } + + void BatchManagerCatalog::addFactBatchManager(const char * type, FactBatchManager * pFBM) + { + if (pFBM) { // *** section critique *** + pthread_mutex_lock(&_mutex); + + if (! BatchManagerCatalog::_p_catalog) BatchManagerCatalog::_p_catalog = new map; + (*BatchManagerCatalog::_p_catalog)[type] = pFBM; + + pthread_mutex_unlock(&_mutex); + } + } + + FactBatchManager * BatchManagerCatalog::operator() (const char * type) const + { + return BatchManagerCatalog::getFactBatchManager(type); + } + + map * BatchManagerCatalog::dict() const + { + return _p_catalog; + } + + string BatchManagerCatalog::__repr__() const + { + ostringstream oss; + oss << "::const_iterator it = (*_p_catalog).begin(); it != (*_p_catalog).end(); it++, sep=", ") { + oss << sep << "'" << (*it).first << "' : '" << (*it).second->__repr__() << "'"; + } + oss << "}>"; + return oss.str(); + } + +} diff --git a/src/Batch/Batch_BatchManagerCatalog.hxx b/src/Batch/Batch_BatchManagerCatalog.hxx new file mode 100644 index 000000000..cff458293 --- /dev/null +++ b/src/Batch/Batch_BatchManagerCatalog.hxx @@ -0,0 +1,47 @@ +/* + * BatchManagerCatalog.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2004 + * Projet : SALOME 2 + * + */ + +#ifndef _CATALOG_H_ +#define _CATALOG_H_ + +using namespace std; +#include +#include +#include + +namespace Batch { + + class FactBatchManager; + + class BatchManagerCatalog + { + public: + // Constructeur + BatchManagerCatalog(); + // Destructeur + virtual ~BatchManagerCatalog(); + + static FactBatchManager * getFactBatchManager(const char * type); + static void addFactBatchManager(const char * type, FactBatchManager * pFBM); + virtual FactBatchManager * operator() (const char * type) const; + + virtual map * dict() const; + virtual string __repr__() const; + + protected: + static map * _p_catalog; + static pthread_mutex_t _mutex; + + private: + + }; + +} + +#endif diff --git a/src/Batch/Batch_BatchManager_PBS.cxx b/src/Batch/Batch_BatchManager_PBS.cxx new file mode 100644 index 000000000..45fceedde --- /dev/null +++ b/src/Batch/Batch_BatchManager_PBS.cxx @@ -0,0 +1,194 @@ +/* + * BatchManager_PBS.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Thu Nov 6 10:17:22 2003 + * Projet : Salome 2 + * + */ + +extern "C" { +#include +#include +} +#include +#include +#include +//#include "MEDMEM_STRING.hxx" +#include "Batch_BatchManager_PBS.hxx" + +namespace Batch { + + // Recupere le nom du serveur par defaut +// string BatchManager_PBS::getDefaultServer() { +// string server_name = "localhost"; + +// const char * server_name_path = "@openpbsspooldir@/server_name"; +// ifstream server_name_file(server_name_path); +// if (server_name_file) { +// server_name_file >> server_name; +// server_name_file.close(); +// } + +// return server_name; +// } + + // Constructeur +// BatchManager_PBS::BatchManager_PBS() throw(InvalidArgumentException,ConnexionFailureException) : BatchManager(BatchManager_PBS::getDefaultServer()) +// { +// // On se connecte au serveur PBS +// _connect = pbs_connect(const_cast< char * >(_hostname.c_str())); +// if (_connect < 0) { // si erreur +// char * errmsg = pbs_geterrmsg(_connect); +// string msg = "PBS Server on host \""; +// msg += _hostname; +// msg += "\" : "; +// msg += errmsg ? errmsg : "Reason unknown"; +// throw ConnexionFailureException(msg.c_str()); +// } +// } + + // Constructeur +// BatchManager_PBS::BatchManager_PBS(string host) throw(InvalidArgumentException,ConnexionFailureException) : BatchManager(host) +// { +// // On se connecte au serveur PBS +// _connect = pbs_connect(const_cast< char * >(_hostname.c_str())); +// if (_connect < 0) { // si erreur +// char * errmsg = pbs_geterrmsg(_connect); +// string msg = "PBS Server on host \""; +// msg += _hostname; +// msg += "\" : "; +// msg += errmsg ? errmsg : "Reason unknown"; +// throw ConnexionFailureException(msg.c_str()); +// } +// } + BatchManager_PBS::BatchManager_PBS(const FactBatchManager * parent, const char * host) throw(InvalidArgumentException,ConnexionFailureException) : BatchManager(parent, host) + { + // On se connecte au serveur PBS + _connect = pbs_connect(const_cast< char * >(_hostname.c_str())); + if (_connect < 0) { // si erreur + char * errmsg = pbs_geterrmsg(_connect); + string msg = "PBS Server on host \""; + msg += _hostname; + msg += "\" : "; + msg += errmsg ? errmsg : "Reason unknown"; + throw ConnexionFailureException(msg.c_str()); + } + } + + // Destructeur + BatchManager_PBS::~BatchManager_PBS() + { + // On se deconnecte du serveur PBS + int rc = pbs_disconnect(_connect); + if (rc < 0) { // si erreur + string msg = "PBS Server on host \""; + msg += _hostname; + msg += "\" : "; + msg += pbs_geterrmsg(_connect); + throw ConnexionFailureException(msg.c_str()); + } + } + + // Methode pour le controle des jobs : soumet un job au gestionnaire + const JobId BatchManager_PBS::submitJob(const Job & job) + { + Job_PBS jobpbs = job; + char * ref = pbs_submit(_connect, + jobpbs.getAttributesOP(), + jobpbs.getScript(), + jobpbs.getDestination(), + NULL); + if (!ref) { // si erreur + char * msg = pbs_geterrmsg(_connect); + if (!msg) msg = "unknown"; + throw APIInternalFailureException(string("PBS submit error. Reason : ") + msg); + } + + JobId id(this, string(ref)); + free(ref); + return id; + } + + // Methode pour le controle des jobs : retire un job du gestionnaire + void BatchManager_PBS::deleteJob(const JobId & jobid) + { + char * ref = const_cast< char * >(jobid.getReference().c_str()); + int rc = pbs_deljob(_connect, ref, 0); + if (rc) { // si erreur + char * msg = pbs_geterrmsg(_connect); + if (!msg) msg = "unknown"; + throw APIInternalFailureException(string("PBS deljob error. Reason : ") + msg); + } + } + + // Methode pour le controle des jobs : suspend un job en file d'attente + void BatchManager_PBS::holdJob(const JobId & jobid) + { + char * ref = const_cast< char * >(jobid.getReference().c_str()); + int rc = pbs_holdjob(_connect, ref, USER_HOLD, 0); + if (rc) { // si erreur + char * msg = pbs_geterrmsg(_connect); + if (!msg) msg = "unknown"; + throw APIInternalFailureException(string("PBS holdjob error. Reason : ") + msg); + } + } + + // Methode pour le controle des jobs : relache un job suspendu + void BatchManager_PBS::releaseJob(const JobId & jobid) + { + char * ref = const_cast< char * >(jobid.getReference().c_str()); + int rc = pbs_rlsjob(_connect, ref, USER_HOLD, 0); + if (rc) { // si erreur + char * msg = pbs_geterrmsg(_connect); + if (!msg) msg = "unknown"; + throw APIInternalFailureException(string("PBS rlsjob error. Reason : ") + msg); + } + } + + + // Methode pour le controle des jobs : modifie un job en file d'attente + void BatchManager_PBS::alterJob(const JobId & jobid, const Parametre & param, const Environnement & env) + { + Job job(param, env); + Job_PBS jobpbs(job); + + char * ref = const_cast< char * >(jobid.getReference().c_str()); + int rc = pbs_alterjob(_connect, + ref, + jobpbs.getAttributes(), + NULL); + if (rc) { // si erreur + char * msg = pbs_geterrmsg(_connect); + if (!msg) msg = "unknown"; + throw APIInternalFailureException(string("PBS alterjob error. Reason : ") + msg); + } + + } + + // Methode pour le controle des jobs : modifie un job en file d'attente + void BatchManager_PBS::alterJob(const JobId & jobid, const Parametre & param) + { + alterJob(jobid, param, Environnement()); + } + + // Methode pour le controle des jobs : modifie un job en file d'attente + void BatchManager_PBS::alterJob(const JobId & jobid, const Environnement & env) + { + alterJob(jobid, Parametre(), env); + } + + + + // Methode pour le controle des jobs : renvoie l'etat du job + JobInfo BatchManager_PBS::queryJob(const JobId & jobid) + { + char * id = const_cast< char * >(jobid.getReference().c_str()); + JobInfo_PBS ji = JobInfo_PBS(pbs_statjob(_connect, id, 0, 0), true); + return ji; + } + + + +} diff --git a/src/Batch/Batch_BatchManager_PBS.hxx b/src/Batch/Batch_BatchManager_PBS.hxx new file mode 100644 index 000000000..53c7437cc --- /dev/null +++ b/src/Batch/Batch_BatchManager_PBS.hxx @@ -0,0 +1,76 @@ +/* + * BatchManager_PBS.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Thu Nov 6 10:17:22 2003 + * Projet : Salome 2 + * + */ + +#ifndef _BATCHMANAGER_PBS_H_ +#define _BATCHMANAGER_PBS_H_ + + +#include "Batch_Job.hxx" +#include "Batch_Job.hxx" +#include "Batch_JobId.hxx" +#include "Batch_JobInfo.hxx" +#include "Batch_JobInfo_PBS.hxx" +#include "Batch_Job_PBS.hxx" +#include "Batch_InvalidArgumentException.hxx" +#include "Batch_ConnexionFailureException.hxx" +#include "Batch_APIInternalFailureException.hxx" +#include "Batch_NotYetImplementedException.hxx" +#include "Batch_BatchManager.hxx" + +namespace Batch { + + class Job; + class JobId; + class JobInfo; + class FactBatchManager; + + class BatchManager_PBS : public BatchManager + { + public: + // Constructeur et destructeur + //BatchManager_PBS() throw(InvalidArgumentException,ConnexionFailureException); // connexion au serveur par defaut + //BatchManager_PBS(string host) throw(InvalidArgumentException,ConnexionFailureException); // connexion a la machine host + BatchManager_PBS(const FactBatchManager * parent, const char * host="localhost") throw(InvalidArgumentException,ConnexionFailureException); // connexion a la machine host + virtual ~BatchManager_PBS(); + + // Recupere le nom du serveur par defaut + // static string BatchManager_PBS::getDefaultServer(); + + // Methodes pour le controle des jobs + virtual const JobId submitJob(const Job & job); // soumet un job au gestionnaire + virtual void deleteJob(const JobId & jobid); // retire un job du gestionnaire + virtual void holdJob(const JobId & jobid); // suspend un job en file d'attente + virtual void releaseJob(const JobId & jobid); // relache un job suspendu + virtual void alterJob(const JobId & jobid, const Parametre & param, const Environnement & env); // modifie un job en file d'attente + virtual void alterJob(const JobId & jobid, const Parametre & param); // modifie un job en file d'attente + virtual void alterJob(const JobId & jobid, const Environnement & env); // modifie un job en file d'attente + virtual JobInfo queryJob(const JobId & jobid); // renvoie l'etat du job + + virtual void setParametre(const JobId & jobid, const Parametre & param) { return alterJob(jobid, param); } // modifie un job en file d'attente + virtual void setEnvironnement(const JobId & jobid, const Environnement & env) { return alterJob(jobid, env); } // modifie un job en file d'attente + + + protected: + int _connect; // PBS connect id + + private: + +#ifdef SWIG + public: + // Recupere le l'identifiant d'un job deja soumis au BatchManager + //virtual const JobId getJobIdByReference(const string & ref) { return BatchManager::getJobIdByReference(ref); } + virtual const JobId getJobIdByReference(const char * ref) { return BatchManager::getJobIdByReference(ref); } +#endif + + }; + +} + +#endif diff --git a/src/Batch/Batch_BoolType.cxx b/src/Batch/Batch_BoolType.cxx new file mode 100644 index 000000000..b70696341 --- /dev/null +++ b/src/Batch/Batch_BoolType.cxx @@ -0,0 +1,43 @@ +/* + * BoolType.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#include +#include "Batch_BoolType.hxx" + +namespace Batch { + + // Conversion en chaine + string BoolType::affiche() const + { + return _data ? string("true") : string("false"); + } + + // Operateur d'affectation + BoolType & BoolType::operator =(bool b) + { + _data = b; + return *this; + } + + // Conversion en bool + BoolType::operator bool() const + { + return this->_data; + } + + // Clone duplique l'objet et en fabrique un nouveau a l'aide de new + // qu'il faudra detruire ensuite manuellement + GenericType * BoolType::clone() const + { + BoolType * pB = new BoolType(this->_data); + assert(pB != 0); + return pB; + } + +} diff --git a/src/Batch/Batch_BoolType.hxx b/src/Batch/Batch_BoolType.hxx new file mode 100644 index 000000000..1bb58d16d --- /dev/null +++ b/src/Batch/Batch_BoolType.hxx @@ -0,0 +1,47 @@ +/* + * BoolType.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#ifndef _BOOLTYPE_H_ +#define _BOOLTYPE_H_ + +using namespace std; +#include +#include "Batch_GenericType.hxx" + +namespace Batch { + + class BoolType : public GenericType + { + public: + // Constructeur + BoolType(const bool b=false) : _data(b) {} + + // Conversion en chaine + virtual string affiche() const; + + // Operateur d'affectation + virtual BoolType & operator =(bool); + + // Conversion en bool + virtual operator bool() const; + + // Clone duplique l'objet et en fabrique un nouveau a l'aide de new + // qu'il faudra detruire ensuite manuellement + virtual GenericType * clone() const; + + protected: + bool _data; + + private: + + }; + +} + +#endif diff --git a/src/Batch/Batch_CharType.cxx b/src/Batch/Batch_CharType.cxx new file mode 100644 index 000000000..66197f84c --- /dev/null +++ b/src/Batch/Batch_CharType.cxx @@ -0,0 +1,43 @@ +/* + * CharType.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#include +#include "Batch_CharType.hxx" + +namespace Batch { + + // Conversion en chaine + string CharType::affiche() const + { + return string(1, _data); + } + + // Operateur d'affectation + CharType & CharType::operator =(char c) + { + _data = c; + return *this; + } + + // Conversion en char + CharType::operator char() const + { + return this->_data; + } + + // Clone duplique l'objet et en fabrique un nouveau a l'aide de new + // qu'il faudra detruire ensuite manuellement + GenericType * CharType::clone() const + { + CharType * pC = new CharType(this->_data); + assert(pC != 0); + return pC; + } + +} diff --git a/src/Batch/Batch_CharType.hxx b/src/Batch/Batch_CharType.hxx new file mode 100644 index 000000000..0aae9f45b --- /dev/null +++ b/src/Batch/Batch_CharType.hxx @@ -0,0 +1,48 @@ +/* + * CharType.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#ifndef _CHARTYPE_H_ +#define _CHARTYPE_H_ + +using namespace std; +#include +#include "Batch_GenericType.hxx" + +namespace Batch { + + class CharType : public GenericType + { + public: + // Constructeur + CharType(const char c=0) : _data(c) {} + + // Conversion en chaine + virtual string affiche() const; + + // Operateur d'affectation + virtual CharType & operator =(char); + + // Conversion en char + virtual operator char() const; + + // Clone duplique l'objet et en fabrique un nouveau a l'aide de new + // qu'il faudra detruire ensuite manuellement + virtual GenericType * clone() const; + + protected: + char _data; + + private: + + }; + +} + +#endif + diff --git a/src/Batch/Batch_ConnexionFailureException.cxx b/src/Batch/Batch_ConnexionFailureException.cxx new file mode 100644 index 000000000..df1096fd9 --- /dev/null +++ b/src/Batch/Batch_ConnexionFailureException.cxx @@ -0,0 +1,15 @@ +/* + * ConnexionFailureException.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Thu Nov 13 11:24:31 2003 + * Projet : Salome 2 + * + */ + +#include "Batch_ConnexionFailureException.hxx" + +namespace Batch { + +} diff --git a/src/Batch/Batch_ConnexionFailureException.hxx b/src/Batch/Batch_ConnexionFailureException.hxx new file mode 100644 index 000000000..22d9584b2 --- /dev/null +++ b/src/Batch/Batch_ConnexionFailureException.hxx @@ -0,0 +1,30 @@ +/* + * ConnexionFailureException.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Thu Nov 13 11:24:31 2003 + * Projet : Salome 2 + * + */ + +#ifndef _CONNEXIONFAILUREEXCEPTION_H_ +#define _CONNEXIONFAILUREEXCEPTION_H_ + + +#include "Batch_GenericException.hxx" + +namespace Batch { + + class ConnexionFailureException : public GenericException + { + public: + // Constructeur + ConnexionFailureException(string ch = "undefined") : GenericException("ConnexionFailureException", ch) {} + + }; + +} + +#endif + diff --git a/src/Batch/Batch_Couple.cxx b/src/Batch/Batch_Couple.cxx new file mode 100644 index 000000000..8a08d7040 --- /dev/null +++ b/src/Batch/Batch_Couple.cxx @@ -0,0 +1,41 @@ +/* + * Couple.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Tue Dec 9 15:00:35 2003 + * Projet : Salome 2 + * + */ + +#include "Batch_Couple.hxx" + +namespace Batch { + + // Operateur d'affectation + Couple & Couple::operator =(const Couple & C) + { + _local = C._local; + _remote = C._remote; + return *this; + } + + // Conversion en chaine + string Couple::str() const + { + string res; + res = "Couple(local : "; + res += _local; + res += ", remote : "; + res += _remote; + res += ")"; + return res; + } + + // Operateur pour l'affichage sur un stream + ostream & operator << (ostream & os, const Couple & cp) + { + return os << cp.str(); + } + +} diff --git a/src/Batch/Batch_Couple.hxx b/src/Batch/Batch_Couple.hxx new file mode 100644 index 000000000..4efe11762 --- /dev/null +++ b/src/Batch/Batch_Couple.hxx @@ -0,0 +1,52 @@ +/* + * Couple.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Tue Dec 9 15:00:35 2003 + * Projet : Salome 2 + * + */ + +#ifndef _COUPLE_H_ +#define _COUPLE_H_ + +using namespace std; +#include + +namespace Batch { + + class Couple + { + public: + // Constructeur standard + Couple(const string & local="", const string & remote="") : _local(local), _remote(remote) {} + + // Constructeur par recopie + Couple(const Couple & C) : _local(C._local), _remote(C._remote) {} + + // Operateur pour l'affichage sur un stream + friend ostream & operator << (ostream & os, const Couple & cp); + + // Operateur d'affectation + virtual Couple & operator =(const Couple &); + + // Conversion en chaine + virtual string str() const; + + // Accesseurs + virtual string getLocal() const { return _local; } + virtual string getRemote() const { return _remote; } + + protected: + string _local; // chemin d'acces au fichier local + string _remote; // chemin d'acees au fichier distant + + private: + + }; + +} + +#endif + diff --git a/src/Batch/Batch_CoupleType.cxx b/src/Batch/Batch_CoupleType.cxx new file mode 100644 index 000000000..1de0b21f0 --- /dev/null +++ b/src/Batch/Batch_CoupleType.cxx @@ -0,0 +1,50 @@ +/* + * CoupleType.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Tue Dec 9 14:51:53 2003 + * Projet : Salome 2 + * + */ + +#include "Batch_CoupleType.hxx" + +namespace Batch { + + // Conversion en chaine + string CoupleType::affiche() const + { + return _data.str(); + } + + // Operateur d'affectation + CoupleType & CoupleType::operator =(const Couple & C) + { + _data = C; + return *this; + } + + // Conversion en char + CoupleType::operator Couple() const + { + return _data; + } + + // Conversion en chaine + CoupleType::operator string() const + { + return _data.str(); + } + + // Clone duplique l'objet et en fabrique un nouveau a l'aide de new + // qu'il faudra detruire ensuite manuellement + GenericType * CoupleType::clone() const + { + CoupleType * pC = new CoupleType(this->_data); + assert(pC != 0); + return pC; + } + +} + diff --git a/src/Batch/Batch_CoupleType.hxx b/src/Batch/Batch_CoupleType.hxx new file mode 100644 index 000000000..a8913d575 --- /dev/null +++ b/src/Batch/Batch_CoupleType.hxx @@ -0,0 +1,50 @@ +/* + * CoupleType.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Tue Dec 9 14:51:53 2003 + * Projet : Salome 2 + * + */ + +#ifndef _COUPLETYPE_H_ +#define _COUPLETYPE_H_ + +using namespace std; +#include +#include "Batch_GenericType.hxx" +#include "Batch_Couple.hxx" + +namespace Batch { + + class CoupleType : public GenericType + { + public: + // Constructeur + CoupleType(const Couple & C) : _data(C) {} + + // Conversion en chaine + virtual string affiche() const; + virtual operator string() const; + + // Operateur d'affectation + virtual CoupleType & operator =(const Couple & C); + + // Conversion en char + virtual operator Couple() const; + + // Clone duplique l'objet et en fabrique un nouveau a l'aide de new + // qu'il faudra detruire ensuite manuellement + virtual GenericType * clone() const; + + protected: + Couple _data; + + private: + + }; + +} + +#endif diff --git a/src/Batch/Batch_Date.cxx b/src/Batch/Batch_Date.cxx new file mode 100644 index 000000000..9ac52b12d --- /dev/null +++ b/src/Batch/Batch_Date.cxx @@ -0,0 +1,169 @@ +/* + * Date.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Wed Nov 26 14:11:42 2003 + * Projet : Salome 2 + * + */ + +#include +#include +#include "Batch_Date.hxx" + +namespace Batch { + + Date::Date(const long l) + { + struct tm * p_tm = localtime(&l); + _day = p_tm->tm_mday; + _month = p_tm->tm_mon + 1; + _year = p_tm->tm_year + 1900; + _hour = p_tm->tm_hour; + _min = p_tm->tm_min; + _sec = p_tm->tm_sec; + } + + Date::Date(const string s) + { + if ((s == "now") || (s == "Now") || (s == "NOW")) { + long l = time(0); + struct tm * p_tm = localtime(&l); + _day = p_tm->tm_mday; + _month = p_tm->tm_mon + 1; + _year = p_tm->tm_year + 1900; + _hour = p_tm->tm_hour; + _min = p_tm->tm_min; + _sec = p_tm->tm_sec; + + } else { + char c; +// istringstream ist(s); +// ist >> _day >> c +// >> _month >> c +// >> _year >> c +// >> _hour >> c +// >> _min >> c +// >> _sec; + sscanf(s.c_str(), "%ld/%ld/%ld-%ld:%ld:%ld", &_day, &_month, &_year, &_hour, &_min, &_sec); + } + } + + Date & Date::operator =(long l) + { + struct tm * p_tm = localtime(&l); + _day = p_tm->tm_mday; + _month = p_tm->tm_mon + 1; + _year = p_tm->tm_year + 1900; + _hour = p_tm->tm_hour; + _min = p_tm->tm_min; + _sec = p_tm->tm_sec; + + return *this; + } + + Date & Date::operator +(long l) + { + *this = epoch() + l; + return *this; + } + + Date & Date::operator -(long l) + { + *this = epoch() - l; + return *this; + } + + Date & Date::operator +=(long l) + { + *this = epoch() + l; + return *this; + } + + Date & Date::operator -=(long l) + { + *this = epoch() - l; + return *this; + } + + Date & Date::operator =(const string & s) + { + if ((s == "now") || (s == "Now") || (s == "NOW")) { + long l = time(0); + struct tm * p_tm = localtime(&l); + _day = p_tm->tm_mday; + _month = p_tm->tm_mon + 1; + _year = p_tm->tm_year + 1900; + _hour = p_tm->tm_hour; + _min = p_tm->tm_min; + _sec = p_tm->tm_sec; + + } else { + char c; +// istringstream ist(s); +// ist >> _day >> c +// >> _month >> c +// >> _year >> c +// >> _hour >> c +// >> _min >> c +// >> _sec; + sscanf(s.c_str(), "%ld/%ld/%ld-%ld:%ld:%ld", &_day, &_month, &_year, &_hour, &_min, &_sec); + } + + return *this; + } + + string Date::str() const + { + char buf[64]; + string datestr; + + // _day to char * + sprintf(buf, "%02ld", _day); + datestr += buf; + datestr += "/"; + + // _month to char * + sprintf(buf, "%02ld", _month); + datestr += buf; + datestr += "/"; + + // _year to char * + sprintf(buf, "%04ld", _year); + datestr += buf; + datestr += "-"; + + // _hour to char * + sprintf(buf, "%02ld", _hour); + datestr += buf; + datestr += ":"; + + // _min to char * + sprintf(buf, "%02ld", _min); + datestr += buf; + datestr += ":"; + + // _sec to char * + sprintf(buf, "%02ld", _sec); + datestr += buf; + + return datestr; + } + + long Date::epoch() const + { + struct tm T; + T.tm_mday = _day; + T.tm_mon = _month - 1; + T.tm_year = _year - 1900; + T.tm_hour = _hour; + T.tm_min = _min; + T.tm_sec = _sec; + return mktime(&T); + } + +} + + +// COMMENTS diff --git a/src/Batch/Batch_Date.hxx b/src/Batch/Batch_Date.hxx new file mode 100644 index 000000000..0091850d1 --- /dev/null +++ b/src/Batch/Batch_Date.hxx @@ -0,0 +1,45 @@ +/* + * Date.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Wed Nov 26 14:11:42 2003 + * Projet : Salome 2 + * + */ + +#ifndef _DATE_H_ +#define _DATE_H_ + +using namespace std; +#include + +namespace Batch { + + class Date + { + public: + Date(const long l=0); + Date(const string s); + virtual Date & operator =(long l); + virtual Date & operator +(long l); + virtual Date & operator -(long l); + virtual Date & operator +=(long l); + virtual Date & operator -=(long l); + virtual Date & operator =(const string & s); + virtual string str() const; + virtual long epoch() const; + + protected: + int _day, _month, _year; + int _hour, _min, _sec; + + private: + + }; + +} + +#endif + +// COMMENTS diff --git a/src/Batch/Batch_DateType.cxx b/src/Batch/Batch_DateType.cxx new file mode 100644 index 000000000..fac8830d6 --- /dev/null +++ b/src/Batch/Batch_DateType.cxx @@ -0,0 +1,51 @@ +/* + * DateType.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Wed Nov 26 11:15:34 2003 + * Projet : Salome 2 + * + */ +extern "C" { +#include +} +#include "Batch_DateType.hxx" + +namespace Batch { + + // Conversion en chaine + string DateType::affiche() const + { + return _data.str(); + } + + // Operateur d'affectation + DateType & DateType::operator =(const Date & d) + { + _data = d; + return *this; + } + + // Conversion en Date + DateType::operator Date() const + { + return _data; + } + + // Conversion en long + DateType::operator long() const + { + return _data.epoch(); + } + + // Clone duplique l'objet et en fabrique un nouveau a l'aide de new + // qu'il faudra detruire ensuite manuellement + GenericType * DateType::clone() const + { + DateType * pD = new DateType(this->_data); + assert(pD != 0); + return pD; + } + +} diff --git a/src/Batch/Batch_DateType.hxx b/src/Batch/Batch_DateType.hxx new file mode 100644 index 000000000..868272086 --- /dev/null +++ b/src/Batch/Batch_DateType.hxx @@ -0,0 +1,52 @@ +/* + * DateType.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Wed Nov 26 11:15:34 2003 + * Projet : Salome 2 + * + */ + +#ifndef _DATETYPE_H_ +#define _DATETYPE_H_ + +using namespace std; +#include +#include "Batch_GenericType.hxx" +#include "Batch_Date.hxx" + +namespace Batch { + + class DateType : public GenericType + { + public: + // Constructeur + DateType(const Date & d) : _data(d) {}; + + // Conversion en chaine + virtual string affiche() const; + + // Operateur d'affectation + virtual DateType & operator =(const Date &); + + // Conversion en Date + virtual operator Date() const; + + // Conversion en long + virtual operator long() const; + + // Clone duplique l'objet et en fabrique un nouveau a l'aide de new + // qu'il faudra detruire ensuite manuellement + virtual GenericType * clone() const; + + protected: + Date _data; + + private: + }; + +} + +#endif + diff --git a/src/Batch/Batch_Environnement.cxx b/src/Batch/Batch_Environnement.cxx new file mode 100644 index 000000000..d658d3855 --- /dev/null +++ b/src/Batch/Batch_Environnement.cxx @@ -0,0 +1,16 @@ +/* + * Environnement.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Thu Oct 16 11:37:47 2003 + * Projet : Salome 2 + * + */ + +#include "Batch_Environnement.hxx" + +namespace Batch { + + +} diff --git a/src/Batch/Batch_Environnement.hxx b/src/Batch/Batch_Environnement.hxx new file mode 100644 index 000000000..cda22aeff --- /dev/null +++ b/src/Batch/Batch_Environnement.hxx @@ -0,0 +1,26 @@ +/* + * Environnement.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Thu Oct 16 11:37:47 2003 + * Projet : Salome 2 + * + */ + +#ifndef _ENVIRONNEMENT_H_ +#define _ENVIRONNEMENT_H_ + + +using namespace std; +#include +#include + +namespace Batch { + + typedef map < string, string > Environnement; + +} + +#endif + diff --git a/src/Batch/Batch_FactBatchManager.cxx b/src/Batch/Batch_FactBatchManager.cxx new file mode 100644 index 000000000..c8123cbfd --- /dev/null +++ b/src/Batch/Batch_FactBatchManager.cxx @@ -0,0 +1,46 @@ +/* + * FactBatchManager.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2004 + * Projet : SALOME 2 + * + */ + +#include +#include +#include "Batch_BatchManagerCatalog.hxx" +#include "Batch_FactBatchManager.hxx" +#include "utilities.h" + +namespace Batch { + + // Constructeur + FactBatchManager::FactBatchManager(const string & _t) : type(_t) + { + BatchManagerCatalog::addFactBatchManager(type.c_str(), this); + ostringstream msg; + msg << "FactBatchManager of type '" << type << "' inserted into catalog"; + MESSAGE(msg.str().c_str()); + } + + // Destructeur + FactBatchManager::~FactBatchManager() + { + // Nothing to do + } + + // Accesseur + string FactBatchManager::getType() const + { + return type; + } + + string FactBatchManager::__repr__() const + { + ostringstream oss; + oss << ""; + return oss.str(); + } + +} diff --git a/src/Batch/Batch_FactBatchManager.hxx b/src/Batch/Batch_FactBatchManager.hxx new file mode 100644 index 000000000..4e4282344 --- /dev/null +++ b/src/Batch/Batch_FactBatchManager.hxx @@ -0,0 +1,41 @@ +/* + * FactBatchManager.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2004 + * Projet : SALOME 2 + * + */ + +#ifndef _FACTBATCHMANAGER_H_ +#define _FACTBATCHMANAGER_H_ + +using namespace std; +#include +#include + +namespace Batch { + + class BatchManager; + + class FactBatchManager + { + public: + // Constructeur et destructeur + FactBatchManager(const string & type); + virtual ~FactBatchManager(); + + virtual BatchManager * operator() (const char * hostname) const = 0; + string getType() const; + string __repr__() const; + + protected: + string type; + + private: + + }; + +} + +#endif diff --git a/src/Batch/Batch_FactBatchManager_PBS.cxx b/src/Batch/Batch_FactBatchManager_PBS.cxx new file mode 100644 index 000000000..3a0e39763 --- /dev/null +++ b/src/Batch/Batch_FactBatchManager_PBS.cxx @@ -0,0 +1,39 @@ +/* + * FactBatchManager_PBS.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2004 + * Projet : SALOME 2 + * + */ + +#include +#include "Batch_BatchManager_PBS.hxx" +#include "Batch_FactBatchManager_PBS.hxx" +#include "utilities.h" + +namespace Batch { + + static FactBatchManager_PBS sFBM_PBS; + + // Constructeur + FactBatchManager_PBS::FactBatchManager_PBS() : FactBatchManager("PBS") + { + // Nothing to do + } + + // Destructeur + FactBatchManager_PBS::~FactBatchManager_PBS() + { + // Nothing to do + } + + // Functor + BatchManager_PBS * FactBatchManager_PBS::operator() (const char * hostname) const + { + MESSAGE("Building new BatchManager_PBS on host '" << hostname << "'"); + return new BatchManager_PBS(this, hostname); + } + + +} diff --git a/src/Batch/Batch_FactBatchManager_PBS.hxx b/src/Batch/Batch_FactBatchManager_PBS.hxx new file mode 100644 index 000000000..55d4bec90 --- /dev/null +++ b/src/Batch/Batch_FactBatchManager_PBS.hxx @@ -0,0 +1,39 @@ +/* + * FactBatchManager_PBS.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2004 + * Projet : SALOME 2 + * + */ + +#ifndef _FACTBATCHMANAGER_PBS_H_ +#define _FACTBATCHMANAGER_PBS_H_ + +using namespace std; +#include +#include +#include "Batch_FactBatchManager.hxx" + +namespace Batch { + + class BatchManager_PBS; + + class FactBatchManager_PBS : public FactBatchManager + { + public: + // Constructeur et destructeur + FactBatchManager_PBS(); + virtual ~FactBatchManager_PBS(); + + virtual BatchManager_PBS * operator() (const char * hostname) const; + + protected: + + private: + + }; + +} + +#endif diff --git a/src/Batch/Batch_GenericException.cxx b/src/Batch/Batch_GenericException.cxx new file mode 100644 index 000000000..6cf7a935f --- /dev/null +++ b/src/Batch/Batch_GenericException.cxx @@ -0,0 +1,15 @@ +/* + * GenericException.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Wed Nov 26 10:15:57 2003 + * Projet : Salome 2 + * + */ + +#include "Batch_GenericException.hxx" + +namespace Batch { + +} diff --git a/src/Batch/Batch_GenericException.hxx b/src/Batch/Batch_GenericException.hxx new file mode 100644 index 000000000..59ecd8413 --- /dev/null +++ b/src/Batch/Batch_GenericException.hxx @@ -0,0 +1,32 @@ +/* + * GenericException.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Wed Nov 26 10:15:56 2003 + * Projet : Salome 2 + * + */ + +#ifndef _GENERICEXCEPTION_H_ +#define _GENERICEXCEPTION_H_ + + +using namespace std; +#include + +namespace Batch { + + class GenericException + { + public: + const string type; // la nature de l'exception + const string message; // la raison de l'exception + + // Constructeur + GenericException(const string tp = "GenericException", const string ch = "undefined") : type(tp), message(ch) {} + }; + +} + +#endif diff --git a/src/Batch/Batch_GenericType.cxx b/src/Batch/Batch_GenericType.cxx new file mode 100644 index 000000000..997222a73 --- /dev/null +++ b/src/Batch/Batch_GenericType.cxx @@ -0,0 +1,42 @@ +/* + * GenericType.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + + +#include +#include +#include "Batch_GenericType.hxx" + +namespace Batch { + + // nombre total d'objet GenericType et al. + int GenericType::_nb = 0; + + // Operateur pour l'affichage sur un stream + ostream & operator << (ostream & os, const GenericType & obj) + { + return os << obj.affiche(); + } + + // Conversion en chaine + string GenericType::affiche() const + { + return string("(GenericType : si ce message apparait, vous devez avoir un probleme)"); + } + + // Clone duplique l'objet et en fabrique un nouveau a l'aide de new + // qu'il faudra detruire ensuite manuellement + GenericType * GenericType::clone() const + { + GenericType * pG = new GenericType; + assert(pG != 0); + return pG; + } + +} + diff --git a/src/Batch/Batch_GenericType.hxx b/src/Batch/Batch_GenericType.hxx new file mode 100644 index 000000000..5a3dfe28e --- /dev/null +++ b/src/Batch/Batch_GenericType.hxx @@ -0,0 +1,50 @@ +/* + * GenericType.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#ifndef _GENERICTYPE_H_ +#define _GENERICTYPE_H_ + + +using namespace std; +#include +#include + +namespace Batch { + + class GenericType + { + public: + // Constructeur et destructeur + GenericType() { _nb++; } + virtual ~GenericType() { _nb--; } + + // Operateur pour l'affichage sur un stream + friend ostream & operator << (ostream & os, const GenericType & obj); + + // Conversion en chaine + virtual string affiche() const; + + // Clone duplique l'objet et en fabrique un nouveau a l'aide de new + // qu'il faudra detruire ensuite manuellement + virtual GenericType * clone() const; + + // Retourne le nombre d'objets GenericType et al. + static int getNb() { return _nb; } + + protected: + + private: + static int _nb; // nombre total d'objets GenericType et al. + + }; + +} + +#endif + diff --git a/src/Batch/Batch_IntType.cxx b/src/Batch/Batch_IntType.cxx new file mode 100644 index 000000000..b5b1eb9cb --- /dev/null +++ b/src/Batch/Batch_IntType.cxx @@ -0,0 +1,49 @@ +/* + * IntType.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#include +#include +//#include "MEDMEM_STRING.hxx" +#include "Batch_IntType.hxx" + + +namespace Batch { + + // Conversion en chaine + string IntType::affiche() const + { + //MEDMEM::STRING sst; + ostringstream sst; + sst << _data; + return sst.str(); + } + + // Operateur d'affectation + IntType & IntType::operator =(int i) + { + _data = i; + return *this; + } + + // Conversion en int + IntType::operator int() const + { + return this->_data; + } + + // Clone duplique l'objet et en fabrique un nouveau a l'aide de new + // qu'il faudra detruire ensuite manuellement + GenericType * IntType::clone() const + { + IntType * pI = new IntType(this->_data); + assert(pI != 0); + return pI; + } + +} diff --git a/src/Batch/Batch_IntType.hxx b/src/Batch/Batch_IntType.hxx new file mode 100644 index 000000000..6d07fe50f --- /dev/null +++ b/src/Batch/Batch_IntType.hxx @@ -0,0 +1,47 @@ +/* + * IntType.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#ifndef _INTTYPE_H_ +#define _INTTYPE_H_ + +using namespace std; +#include +#include "Batch_GenericType.hxx" + +namespace Batch { + + class IntType : public GenericType + { + public: + // Constructeur + IntType(const int i=0) : _data(i) {} + + // Conversion en chaine + virtual string affiche() const; + + // Operateur d'affectation + virtual IntType & operator =(int); + + // Conversion en int + virtual operator int() const; + + // Clone duplique l'objet et en fabrique un nouveau a l'aide de new + // qu'il faudra detruire ensuite manuellement + virtual GenericType * clone() const; + + protected: + int _data; + + private: + + }; + +} + +#endif diff --git a/src/Batch/Batch_InvalidArgumentException.cxx b/src/Batch/Batch_InvalidArgumentException.cxx new file mode 100644 index 000000000..fa077bcbb --- /dev/null +++ b/src/Batch/Batch_InvalidArgumentException.cxx @@ -0,0 +1,15 @@ +/* + * InvalidArgumentException.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Thu Oct 16 16:18:00 2003 + * Projet : Salome 2 + * + */ + +#include "Batch_InvalidArgumentException.hxx" + +namespace Batch { + +} diff --git a/src/Batch/Batch_InvalidArgumentException.hxx b/src/Batch/Batch_InvalidArgumentException.hxx new file mode 100644 index 000000000..62a972bd4 --- /dev/null +++ b/src/Batch/Batch_InvalidArgumentException.hxx @@ -0,0 +1,30 @@ +/* + * InvalidArgumentException.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Thu Oct 16 16:18:00 2003 + * Projet : Salome 2 + * + */ + +#ifndef _INVALIDARGUMENTEXCEPTION_H_ +#define _INVALIDARGUMENTEXCEPTION_H_ + + +#include "Batch_GenericException.hxx" +#include "Batch_GenericException.hxx" + +namespace Batch { + + class InvalidArgumentException : public GenericException + { + public: + // Constructeur + InvalidArgumentException(string ch = "undefined") : GenericException("InvalidArgumentException", ch) {} + }; + +} + +#endif + diff --git a/src/Batch/Batch_InvalidKeyException.cxx b/src/Batch/Batch_InvalidKeyException.cxx new file mode 100644 index 000000000..bec522ef9 --- /dev/null +++ b/src/Batch/Batch_InvalidKeyException.cxx @@ -0,0 +1,16 @@ +/* + * InvalidKeyException.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Wed Oct 15 10:39:51 2003 + * Projet : Salome 2 + * + */ + +#include "Batch_InvalidKeyException.hxx" + +namespace Batch { + +} + diff --git a/src/Batch/Batch_InvalidKeyException.hxx b/src/Batch/Batch_InvalidKeyException.hxx new file mode 100644 index 000000000..8e0c45b9c --- /dev/null +++ b/src/Batch/Batch_InvalidKeyException.hxx @@ -0,0 +1,35 @@ +/* + * InvalidKeyException.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Wed Oct 15 10:39:51 2003 + * Projet : Salome 2 + * + */ + +#ifndef _INVALIDKEYEXCEPTION_H_ +#define _INVALIDKEYEXCEPTION_H_ + + +#include "Batch_GenericException.hxx" +#include "Batch_GenericException.hxx" + +namespace Batch { + + class InvalidKeyException : public GenericException + { + public: + // Constructeur + InvalidKeyException(string ch = "undefined") : GenericException("InvalidKeyException", ch) {} + + protected: + + private: + + }; + +} + +#endif + diff --git a/src/Batch/Batch_Job.cxx b/src/Batch/Batch_Job.cxx new file mode 100644 index 000000000..6fa203ed5 --- /dev/null +++ b/src/Batch/Batch_Job.cxx @@ -0,0 +1,95 @@ +/* + * Job.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#include "Batch_Job.hxx" +#include "Batch_Parametre.hxx" +#include +//#include "MEDMEM_STRING.hxx" + +namespace Batch { + + // Constructeur + Job::Job() : _param(), _env() + { + // Nothing to do + } + + + // Constructeur + Job::Job(Parametre param) : _param(param), _env() + { + // Nothing to do + } + + + // Constructeur + Job::Job(Environnement env) : _param(), _env(env) + { + // Nothing to do + } + + + // Constructeur + Job::Job(Parametre param, Environnement env) : _param(param), _env(env) + { + // Nothing to do + } + + // Operateur pour l'affichage sur un stream + ostream & operator <<(ostream & os, const Job & job) + { + return os << job.__str__(); + } + + // Accesseur + Parametre Job::getParametre() const + { + return _param; + } + + // Accesseur + void Job::setParametre(const Parametre & param) + { + _param = param; + } + + // Accesseur + Environnement Job::getEnvironnement() const + { + return _env; + } + + // Accesseur + void Job::setEnvironnement(const Environnement & env) + { + _env = env; + } + + + // Methode pour l'interfacage avec Python (SWIG) : affichage en Python + string Job::__str__() const { + //MEDMEM::STRING str; + ostringstream str; + str << ""; + return str.str(); + } + + +} diff --git a/src/Batch/Batch_Job.hxx b/src/Batch/Batch_Job.hxx new file mode 100644 index 000000000..efd8a90ce --- /dev/null +++ b/src/Batch/Batch_Job.hxx @@ -0,0 +1,55 @@ +/* + * Job.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#ifndef _JOB_H_ +#define _JOB_H_ + + +#include "Batch_Parametre.hxx" +#include "Batch_Environnement.hxx" + +namespace Batch { + + class Job + { + public: + // Constructeurs et destructeur + Job(); + Job(Parametre param); + Job(Environnement env); + Job(Parametre param, Environnement env); + virtual ~Job() {} + + // Operateur pour l'affichage sur un stream + friend ostream & operator <<(ostream & os, const Job & job); + + // Accesseurs + Parametre getParametre() const; + void setParametre(const Parametre &); + + // Accesseurs + Environnement getEnvironnement() const; + void setEnvironnement(const Environnement &); + + // Methodes pour l'interfacage avec Python (SWIG) + // TODO : supprimer ces methodes et transferer leur definitions dans SWIG + string __str__() const; // SWIG : affichage en Python + string __repr__() const { return __str__(); }; // SWIG : affichage en Python + + protected: + Parametre _param; // table des parametres batch du job + Environnement _env; // table des variables d'environnement + + private: + + }; + +} + +#endif diff --git a/src/Batch/Batch_JobId.cxx b/src/Batch/Batch_JobId.cxx new file mode 100644 index 000000000..f642b4ce2 --- /dev/null +++ b/src/Batch/Batch_JobId.cxx @@ -0,0 +1,114 @@ +/* + * JobId.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#include "Batch_JobId.hxx" +#include "Batch_BatchManager.hxx" +#include +//#include "MEDMEM_STRING.hxx" + +namespace Batch { + + // Constructeur standard + JobId::JobId() : _p_batchmanager(), _reference("undefined") + { + // Nothing to do + } + + // Constructeur avec le pointeur sur le BatchManager associe et avec une reference + JobId::JobId(BatchManager * _p_bm, string ref) : _p_batchmanager(_p_bm), _reference(ref) + { + // Nothing to do + } + + // Destructeur + JobId::~JobId() + { + // Nothing to do + } + + // Operateur d'affectation entre objets + JobId & JobId::operator =(const JobId & jobid) + { + _p_batchmanager = jobid._p_batchmanager; + _reference = jobid._reference; + + return *this; + } + + // Constructeur par recopie + JobId::JobId(const JobId & jobid) : _p_batchmanager(jobid._p_batchmanager), _reference(jobid._reference) + { + // Nothing to do + } + + // Accesseur pour la reference interne + string JobId::getReference() const + { + return _reference; + } + + // Methode pour le controle du job : retire le job du gestionnaire + void JobId::deleteJob() const + { + assert(_p_batchmanager != 0); + _p_batchmanager->deleteJob(*this); + } + + // Methode pour le controle du job : suspend le job en file d'attente + void JobId::holdJob() const + { + assert(_p_batchmanager != 0); + _p_batchmanager->holdJob(*this); + } + + // Methode pour le controle du job : relache le job suspendu + void JobId::releaseJob() const + { + assert(_p_batchmanager != 0); + _p_batchmanager->releaseJob(*this); + } + + // Methode pour le controle du job : modifie le job en file d'attente + void JobId::alterJob(const Parametre & param, const Environnement & env) const + { + assert(_p_batchmanager != 0); + _p_batchmanager->alterJob(*this, param, env); + } + + // Methode pour le controle du job : modifie le job en file d'attente + void JobId::alterJob(const Parametre & param) const + { + assert(_p_batchmanager != 0); + _p_batchmanager->alterJob(*this, param); + } + + // Methode pour le controle du job : modifie le job en file d'attente + void JobId::alterJob(const Environnement & env) const + { + assert(_p_batchmanager != 0); + _p_batchmanager->alterJob(*this, env); + } + + // Methode pour le controle du job : renvoie l'etat du job + JobInfo JobId::queryJob() const + { + assert(_p_batchmanager != 0); + return _p_batchmanager->queryJob(*this); + } + + + // Methode pour l'interfacage avec Python (SWIG) : affichage en Python + string JobId::__str__() const { + //MEDMEM::STRING str; + ostringstream str; + str << ""; + return str.str(); + } + +} diff --git a/src/Batch/Batch_JobId.hxx b/src/Batch/Batch_JobId.hxx new file mode 100644 index 000000000..d2811bc6d --- /dev/null +++ b/src/Batch/Batch_JobId.hxx @@ -0,0 +1,68 @@ +/* + * JobId.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#ifndef _JOBID_H_ +#define _JOBID_H_ + + +#include "Batch_JobInfo.hxx" +#include "Batch_BatchManager.hxx" + +namespace Batch { + + class BatchManager; + + class JobId + { + friend class BatchManager; + + public: + // Constructeur standard et destructeur + JobId(); + virtual ~JobId(); + + // Constructeur avec le pointeur sur le BatchManager associe et avec une reference + JobId(BatchManager *, string ref); + + // Operateur d'affectation entre objets + virtual JobId & operator =(const JobId &); + + // Constructeur par recopie + JobId(const JobId &); + + // Accesseur pour la reference interne + virtual string getReference() const; + + // Methodes pour le controle du job + virtual void deleteJob() const; // retire un job du gestionnaire + virtual void holdJob() const; // suspend un job en file d'attente + virtual void releaseJob() const; // relache un job suspendu + virtual void alterJob(const Parametre & param, const Environnement & env) const; // modifie un job en file d'attente + virtual void alterJob(const Parametre & param) const; // modifie un job en file d'attente + virtual void alterJob(const Environnement & env) const; // modifie un job en file d'attente + virtual void setParametre(const Parametre & param) { return alterJob(param); } // modifie un job en file d'attente + virtual void setEnvironnement(const Environnement & env) { return alterJob(env); } // modifie un job en file d'attente + virtual Batch::JobInfo queryJob() const; // renvoie l'etat du job + + // Methodes pour l'interfacage avec Python (SWIG) + // TODO : supprimer ces methodes et transferer leur definitions dans SWIG + string __str__() const; // SWIG : affichage en Python + string __repr__() const { return __str__(); }; // SWIG : affichage en Python + + protected: + BatchManager * _p_batchmanager; // pointeur sur le BatchManager qui controle le job + string _reference; // reference du job au sein du BatchManager + + private: + + }; + +} + +#endif diff --git a/src/Batch/Batch_JobInfo.cxx b/src/Batch/Batch_JobInfo.cxx new file mode 100644 index 000000000..3192f21d5 --- /dev/null +++ b/src/Batch/Batch_JobInfo.cxx @@ -0,0 +1,73 @@ +/* + * JobInfo.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Thu Nov 6 10:05:30 2003 + * Projet : Salome 2 + * + */ + +#include +#include +#include +//#include "MEDMEM_STRING.hxx" +#include "Batch_JobInfo.hxx" + +namespace Batch { + + // Destructeur + JobInfo::~JobInfo() + { + // Nothing to do + } + + + // Operateur pour l'affichage sur un stream + ostream & operator <<(ostream & os, const JobInfo & ji) + { + return os << ji.__str__(); + } + + + // Methodes pour l'interfacage avec Python (SWIG) : affichage en Python + string JobInfo::__str__() const + { + //MEDMEM::STRING sst; + ostringstream sst; + sst << ""; + + return sst.str(); + } + + // Accesseur + Parametre JobInfo::getParametre() const + { + return _param; + } + + // Accesseur + Environnement JobInfo::getEnvironnement() const + { + return _env; + } + + +} diff --git a/src/Batch/Batch_JobInfo.hxx b/src/Batch/Batch_JobInfo.hxx new file mode 100644 index 000000000..093d8e3a9 --- /dev/null +++ b/src/Batch/Batch_JobInfo.hxx @@ -0,0 +1,54 @@ +/* + * JobInfo.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Thu Nov 6 10:05:30 2003 + * Projet : Salome 2 + * + */ + +#ifndef _JOBINFO_H_ +#define _JOBINFO_H_ + +using namespace std; +#include +#include +#include "Batch_Parametre.hxx" +#include "Batch_Environnement.hxx" + +namespace Batch { + + class JobInfo + { + public: + // Constructeur standard et destructeur + JobInfo() : _param(), _env() {}; + virtual ~JobInfo(); + + // Constructeur par recopie + JobInfo(const JobInfo & jinfo) : _param(jinfo._param), _env(jinfo._env) {}; + + // Operateur pour l'affichage sur un stream + friend ostream & operator <<(ostream & os, const JobInfo & ji); + + // Accesseurs + virtual Parametre getParametre() const; + virtual Environnement getEnvironnement() const; + + // Methodes pour l'interfacage avec Python (SWIG) + // TODO : supprimer ces methodes et transferer leur definitions dans SWIG + string __str__() const; // SWIG : affichage en Python + string __repr__() const { return __str__(); }; // SWIG : affichage en Python + + protected: + Parametre _param; // parametres du job + Environnement _env; // variables d'environnement du job + + private: + + }; + +} + +#endif diff --git a/src/Batch/Batch_JobInfo_PBS.cxx b/src/Batch/Batch_JobInfo_PBS.cxx new file mode 100644 index 000000000..a079b9249 --- /dev/null +++ b/src/Batch/Batch_JobInfo_PBS.cxx @@ -0,0 +1,176 @@ +/* + * JobInfo_PBS.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Fri Nov 21 09:42:06 2003 + * Projet : Salome 2 + * + */ + +#include +#include +//#include "MEDMEM_STRING.hxx" +#include "Batch_Parametre.hxx" +#include "Batch_Environnement.hxx" +#include "Batch_RunTimeException.hxx" +#include "Batch_JobInfo_PBS.hxx" + +namespace Batch { + + // Constructeurs + JobInfo_PBS::JobInfo_PBS(struct batch_status * list, bool tobedeleted) : JobInfo() + { + // On ne considere que le premier element de la liste + // Si tout est OK, la liste ne devrait contenir qu'un element + // Sinon on leve une exception. + struct batch_status * p_job = list; + int i; + for(i=0; p_job; p_job = p_job->next) i++; + if (i == 0) throw RunTimeException("Liste vide (le job est absent de la file)"); + if (i > 1) { + //MEDMEM::STRING sst; + ostringstream sst; + sst << "JobInfo_PBS::JobInfo_PBS(struct batch_status * list, bool tobedeleted) : la liste contient " + << i << " elements" << " (1 seul requis)" << endl; + throw RunTimeException(sst.str()); + } + p_job = list; + + // On remplit les membres _param et _env + + if (p_job->name && strlen(p_job->name)) _param[ID] = p_job->name; + if (p_job->text && strlen(p_job->text)) _param[TEXT] = p_job->text; + + for(struct attrl * p_attr = p_job->attribs; p_attr; p_attr = p_attr->next) { + + string name, res, value; + if (p_attr->name && strlen(p_attr->name)) name = p_attr->name; + if (p_attr->resource && strlen(p_attr->resource)) res = p_attr->resource; + if (p_attr->value && strlen(p_attr->value)) value = p_attr->value; + + if (name == ATTR_N) { + _param[NAME] = value; + + } else if (name == ATTR_owner) { + _param[USER] = value; + + } else if (name == ATTR_state) { + _param[STATE] = value; + + } else if (name == ATTR_queue) { + _param[QUEUE] = value; + + } else if (name == ATTR_A) { + _param[ACCOUNT] = value; + + } else if (name == ATTR_M) { + _param[MAIL] = value; + + } else if (name == ATTR_c) { + if (!strcmp(value.c_str(), CHECKPOINT_UNSPECIFIED)) _param[CHECKPOINT] = 1L; + else _param[CHECKPOINT] = 0L; + + } else if (name == ATTR_h) { + if (!strcmp(value.c_str(), NO_HOLD)) _param[HOLD] = 0L; + else _param[HOLD] = 1L; + + } else if (name == ATTR_ctime) { + _param[CREATIONTIME] = atol(value.c_str()); + + } else if (name == ATTR_etime) { + _param[ELIGIBLETIME] = atol(value.c_str()); + + } else if (name == ATTR_mtime) { + _param[MODIFICATIONTIME] = atol(value.c_str()); + + } else if (name == ATTR_qtime) { + _param[QUEUEDTIME] = atol(value.c_str()); + + } else if (name == ATTR_exechost) { + _param[EXECUTIONHOST] = value; + + } else if (name == ATTR_session) { + _param[PID] = atol(value.c_str()); + + } else if (name == ATTR_euser) { + _param[EUSER] = value; + + } else if (name == ATTR_egroup) { + _param[EGROUP] = value; + + } else if (name == ATTR_l) { + if (res == "cput") { + _param[MAXCPUTIME] = HMStoLong(value); + + } else if (res == "walltime") { + _param[MAXWALLTIME] = HMStoLong(value); + + } + + } else if (name == ATTR_used) { + if (res == "cput") { + _param[USEDCPUTIME] = HMStoLong(value); + + } else if (res == "walltime") { + _param[USEDWALLTIME] = HMStoLong(value); + + } + + } else if (name == ATTR_v) { + int deb = 0; + int pos = 0; + bool ok = true; + + while (ok) { + pos = value.find(",", deb); + string sub = value.substr(deb, pos-deb); + deb = pos + 1; + if (pos < 0) ok = false; + + int eq = sub.find("="); + _env[sub.substr(0, eq)] = sub.substr(eq+1); + } + + } + } + + + if (tobedeleted) pbs_statfree(list); + } + + // Destructeur + JobInfo_PBS::~JobInfo_PBS() + { + // Nothing to do + } + + // Convertit une date HH:MM:SS en secondes + long JobInfo_PBS::HMStoLong(const string & s) + { + long hour, min, sec; + + sscanf( s.c_str(), "%ld:%ld:%ld", &hour, &min, &sec); + return ( ( ( hour * 60L ) + min ) * 60L ) + sec; + } + + // Methode pour l'interfacage avec Python (SWIG) : affichage en Python + string JobInfo_PBS::__str__() const + { + //MEDMEM::STRING sst; + ostringstream sst; + sst << " +#include +} +#include +#include "Batch_RunTimeException.hxx" +#include "Batch_JobInfo.hxx" + +namespace Batch { + + class JobInfo_PBS : public JobInfo + { + public: + // Constructeurs et destructeur + JobInfo_PBS() : JobInfo() {}; + JobInfo_PBS(struct batch_status * stat_list, bool tobedeleted = false); + virtual ~JobInfo_PBS(); + + // Constructeur par recopie + JobInfo_PBS(const JobInfo_PBS & jinfo) : JobInfo(jinfo) {}; + + // Methodes pour l'interfacage avec Python (SWIG) + // TODO : supprimer ces methodes et transferer leur definitions dans SWIG + string __str__() const; // SWIG : affichage en Python + string __repr__() const { return __str__(); }; // SWIG : affichage en Python + + protected: + + private: + // Convertit une date HH:MM:SS en secondes + long HMStoLong(const string &); + + }; + +} + +#endif diff --git a/src/Batch/Batch_Job_PBS.cxx b/src/Batch/Batch_Job_PBS.cxx new file mode 100644 index 000000000..78450133e --- /dev/null +++ b/src/Batch/Batch_Job_PBS.cxx @@ -0,0 +1,450 @@ +/* + * Job_PBS.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Fri Nov 14 11:00:39 2003 + * Projet : Salome 2 + * + */ + +#include +#include +#include +#include "Batch_Job_PBS.hxx" + +namespace Batch { + + // Ajoute un element (name,resource,value) a la liste chainee d'attributs + operateur + void Job_PBS::setResourceAttributeOP(struct attropl ** attr_list, const char * attr_name, const char * attr_resource, const char * attr_value) + { + // L'element (name,resource,value) existe-t-il deja ? si oui ptr != 0 + struct attropl * ptr = findResourceAttributeOP(*attr_list, attr_name, attr_resource); + + if (!ptr) { // L'element n'existe pas, il faut le creer + if (ptr = lastAttributeOP(*attr_list)) { // la liste n'est pas vide + ptr->next = new struct attropl; + ptr = ptr->next; + ptr->next = 0; + + } else { // la liste est completement vide + ptr = *attr_list = new struct attropl; + ptr->next = 0; + } + + // On remplit les champs (name,resource,value) + ptr->name = new char[strlen(attr_name) + 1]; + strncpy(ptr->name, attr_name, strlen(attr_name)); + ptr->name[strlen(attr_name)] = 0; + + ptr->resource = new char[strlen(attr_resource) + 1]; + strncpy(ptr->resource, attr_resource, strlen(attr_resource)); + ptr->resource[strlen(attr_resource)] = 0; + + ptr->value = new char[strlen(attr_value) + 1]; + strncpy(ptr->value, attr_value, strlen(attr_value)); + ptr->value[strlen(attr_value)] = 0; + + } else { // L'attribut existe, on change sa valeur + delete[] ptr->value; // On efface la valeur precedente + ptr->value = new char[strlen(attr_value) + 1]; + strncpy(ptr->value, attr_value, strlen(attr_value)); + ptr->value[strlen(attr_value)] = 0; + + } + } + + + // Recherche un element (name,resource,value) dans la liste chainee d'attributs + operateur + struct attropl * Job_PBS::findResourceAttributeOP(struct attropl * attr_list, const char * attr_name, const char * attr_resource) + { + // On parcoure la liste chainee pour trouver l'element dont les champs name et resource coincident + struct attropl * ptr = attr_list; + while (ptr) { + if (!strcmp(ptr->name, attr_name) && !strcmp(ptr->resource, attr_resource)) break; + ptr = ptr->next; + } + return ptr; + } + + + // Recherche le dernier element de la liste chainee d'attributs + operateur + struct attropl * Job_PBS::lastAttributeOP(struct attropl * attr_list) + { + struct attropl * ptr = attr_list; + while (ptr && ptr->next) { + ptr = ptr->next; + } + return ptr; + } + + + // Convertit un objet Parametre en liste chainee d'attributs + operateur + struct attropl * Job_PBS::ParametreToAttributeOPList(struct attropl ** _p_attr_list, Parametre & P) + { + Parametre::iterator it; + string st_second; + for(it=P.begin(); it!=P.end(); it++) { + if ( (*it).first == ACCOUNT ) { + st_second = (*it).second.str(); + setResourceAttributeOP(_p_attr_list, ATTR_A, "", st_second.c_str()); + + + } else if ( (*it).first == CHECKPOINT ) { + setResourceAttributeOP(_p_attr_list, ATTR_c, "", "u"); + + + } else if ( (*it).first == CKPTINTERVAL ) { + // Not significant + + } else if ( (*it).first == EXECUTABLE ) { + // Already done + + } else if ( (*it).first == HOLD ) { + if (static_cast< long >((*it).second)) + setResourceAttributeOP(_p_attr_list, ATTR_h, "", USER_HOLD); + else + setResourceAttributeOP(_p_attr_list, ATTR_h, "", NO_HOLD); + + } else if ( (*it).first == INFILE ) { + Versatile V = (*it).second; + Versatile::iterator Vit; + + string sep = ""; + string stagein; + + for(Vit=V.begin(); Vit!=V.end(); Vit++, sep=",") { + CoupleType cpt = *static_cast< CoupleType * >(*Vit); + Couple cp = cpt; + string local = cp.getLocal(); + string remote = cp.getRemote(); + + // ATTENTION : les notions de fichier "local" ou "remote" sont inverses de celle de PBS qui a un point de vue serveur et non pas utilisateur + stagein += sep + remote + "@" + local; + } + + if (stagein.size()) + setResourceAttributeOP(_p_attr_list, ATTR_stagein, "", stagein.c_str()); + + + } else if ( (*it).first == MAIL ) { + st_second = (*it).second.str(); + setResourceAttributeOP(_p_attr_list, ATTR_M, "", st_second.c_str()); + + } else if ( (*it).first == MAXCPUTIME ) { + char attr_value[32]; + long secondes = (*it).second; + long heures = secondes / 3600L; + long minutes = (secondes - 3600L * heures) / 60L; + secondes = secondes % 60L; + sprintf(attr_value, "%02ld:%02ld:%02ld", heures, minutes, secondes); + + setResourceAttributeOP(_p_attr_list, ATTR_l, "cput", attr_value); + + + } else if ( (*it).first == MAXDISKSIZE ) { + + } else if ( (*it).first == MAXRAMSIZE ) { + + } else if ( (*it).first == MAXWALLTIME ) { + char attr_value[32]; + long secondes = (*it).second; + long heures = secondes / 3600L; + long minutes = (secondes - 3600L * heures) / 60L; + secondes = secondes % 60L; + sprintf(attr_value, "%02ld:%02ld:%02ld", heures, minutes, secondes); + + setResourceAttributeOP(_p_attr_list, ATTR_l, "walltime", attr_value); + + + } else if ( (*it).first == NAME ) { + st_second = (*it).second.str(); + setResourceAttributeOP(_p_attr_list, ATTR_N, "", st_second.c_str()); + + + } else if ( (*it).first == OUTFILE ) { + Versatile V = (*it).second; + Versatile::iterator Vit; + + string sep = ""; + string stageout; + + for(Vit=V.begin(); Vit!=V.end(); Vit++, sep=",") { + CoupleType cpt = *static_cast< CoupleType * >(*Vit); + Couple cp = cpt; + string local = cp.getLocal(); + string remote = cp.getRemote(); + + if (remote == "stdout") + setResourceAttributeOP(_p_attr_list, ATTR_o, "", local.c_str()); + + else if (remote == "stderr") + setResourceAttributeOP(_p_attr_list, ATTR_e, "", local.c_str()); + + else + // ATTENTION : les notions de fichier "local" ou "remote" sont inverses de celle de PBS qui a un point de vue serveur et non pas utilisateur + stageout += sep + remote + "@" + local; + } + + if (stageout.size()) + setResourceAttributeOP(_p_attr_list, ATTR_stageout, "", stageout.c_str()); + + } else if ( (*it).first == QUEUE ) { + // Already done + + } else if ( (*it).first == STARTDATE ) { + + } else if ( (*it).first == TMPDIR ) { + + } else if ( (*it).first == USER ) { + st_second = (*it).second.str(); + setResourceAttributeOP(_p_attr_list, ATTR_u, "", st_second.c_str()); + + } + } + return *_p_attr_list; + } + + + // Convertit un objet Environnement en liste chainee d'attributs + operateur + struct attropl * Job_PBS::EnvironnementToAttributeOPList(struct attropl ** _p_attr_list, Environnement & E) + { + Environnement::iterator it; + for(it=E.begin(); it!=E.end(); it++) { + setResourceAttributeOP(_p_attr_list, ATTR_v, (*it).first.c_str(), ( (*it).first + "=" + (*it).second ).c_str()); + } + return *_p_attr_list; + } + + + // Ajoute les variables d'environnement presentes dans tout job PBS + void Job_PBS::addPBSEnvironnement(Environnement & E) + { + char * c; + + c = getenv("HOME"); + if (c) E["PBS_O_HOME"] = c; + + c = getenv("LANG"); + if (c) E["PBS_O_LANG"] = c; + + c = getenv("LOGNAME"); + if (c) E["PBS_O_LOGNAME"] = c; + + c = getenv("PATH"); + if (c) E["PBS_O_PATH"] = c; + + c = getenv("LD_LIBRARY_PATH"); + if (c) E["PBS_O_LD_LIBRARY_PATH"] = c; + + c = getenv("MAIL"); + if (c) E["PBS_O_MAIL"] = c; + + c = getenv("SHELL"); + if (c) E["PBS_O_SHELL"] = c; + + c = getenv("TZ"); + if (c) E["PBS_O_TZ"] = c; + + /* Recuperation du working directory */ + size_t size = 256; + char * buf = 0; + char * rc = 0; + do { + if (buf) delete[] buf; + buf = new char[size]; + rc = getcwd(buf, size); + size += size; + } while (!rc); + E["PBS_O_WORKDIR"] = buf; + delete[] buf; + } + + + // Ajoute un element (name,resource,value) a la liste chainee d'attributs + void Job_PBS::setResourceAttribute(struct attrl ** attr_list, const char * attr_name, const char * attr_resource, const char * attr_value) + { + // L'element (name,resource,value) existe-t-il deja ? si oui ptr != 0 + struct attrl * ptr = findResourceAttribute(*attr_list, attr_name, attr_resource); + + if (!ptr) { // L'attribut n'existe pas, il faut le creer + if (ptr = lastAttribute(*attr_list)) { // la liste n'est pas vide + ptr->next = new struct attrl; + ptr = ptr->next; + ptr->next = 0; + + } else { // la liste est completement vide + ptr = *attr_list = new struct attrl; + ptr->next = 0; + } + + // On remplit les champs (name,resource,value) + ptr->name = new char[strlen(attr_name) + 1]; + strncpy(ptr->name, attr_name, strlen(attr_name)); + ptr->name[strlen(attr_name)] = 0; + + ptr->resource = new char[strlen(attr_resource) + 1]; + strncpy(ptr->resource, attr_resource, strlen(attr_resource)); + ptr->resource[strlen(attr_resource)] = 0; + + ptr->value = new char[strlen(attr_value) + 1]; + strncpy(ptr->value, attr_value, strlen(attr_value)); + ptr->value[strlen(attr_value)] = 0; + + } else { // L'attribut existe, on change sa valeur + delete[] ptr->value; // On efface la valeur precedente + ptr->value = new char[strlen(attr_value) + 1]; + strncpy(ptr->value, attr_value, strlen(attr_value)); + ptr->value[strlen(attr_value)] = 0; + + } + } + + // Recherche un element (name,resource,value) dans la liste chainee d'attributs + struct attrl * Job_PBS::findResourceAttribute(struct attrl * attr_list, const char * attr_name, const char * attr_resource) + { + // On parcoure la liste chainee pour trouver l'element dont les champs name et resource coincident + struct attrl * ptr = attr_list; + while (ptr) { + if (!strcmp(ptr->name, attr_name) && !strcmp(ptr->resource, attr_resource)) break; + ptr = ptr->next; + } + return ptr; + } + + + // Recherche le dernier element de la liste chainee d'attributs + struct attrl * Job_PBS::lastAttribute(struct attrl * attr_list) + { + struct attrl * ptr = attr_list; + while (ptr && ptr->next) { + ptr = ptr->next; + } + return ptr; + } + + + // Constructeur + Job_PBS::Job_PBS(const Job & job) : _p_attropl(0), _p_attrl(0), _script(0), _destination(0) + { + Parametre P = job.getParametre(); + Parametre::iterator it; + + // On extrait de l'objet Parametre le champ EXECUTABLE qui deviendra le script PBS + if ( (it=P.find(EXECUTABLE)) != P.end()) { + Versatile V = (*it).second; + string st_exe = V.str(); + const char * exe = st_exe.c_str(); + int lg = strlen(exe); + _script = new char[lg + 1]; + for (int ii=0; iinext; + delete[] current_p_attropl->name; + delete[] current_p_attropl->resource; + delete[] current_p_attropl->value; + delete current_p_attropl; + current_p_attropl = next; + } + + // On detruit la liste chainee d'attributs + struct attrl * current_p_attrl = _p_attrl; + while (current_p_attrl) { + struct attrl * next = current_p_attrl->next; + delete[] current_p_attrl->name; + delete[] current_p_attrl->resource; + delete[] current_p_attrl->value; + delete current_p_attrl; + current_p_attrl = next; + } + + // On detruit les champs alloues + delete[] _script; + delete[] _destination; + } + + + // Accesseur + struct attropl * Job_PBS::getAttributesOP() + { + return _p_attropl; + } + + // Accesseur + // Cette methode sert pour les pbs_alter de PBS + // Pbs_alter est buggé par rapport a la specification ers_all.ps car les + // variables d'environnement ne sont pas supportees (ATTR_v) + struct attrl * Job_PBS::getAttributes() + { + if (_p_attrl == 0) { + + // On remplit la structure attrl a partir de la strucuture attropl + // (elles ne different que par le parametre op, mais elles ne sont pas interchangeables + // dans les appels) + + struct attropl * current_p_attropl = _p_attropl; + while (current_p_attropl) { + if (strcmp(current_p_attropl->name, ATTR_v)) // Bug fix for ATTR_v + setResourceAttribute(&_p_attrl, + current_p_attropl->name, + current_p_attropl->resource, + current_p_attropl->value); + + current_p_attropl = current_p_attropl->next; + } + + } + + return _p_attrl; + } + + // Accesseur + char * Job_PBS::getScript() + { + return _script; + } + + // Accesseur + char * Job_PBS::getDestination() + { + return _destination; + } + +} diff --git a/src/Batch/Batch_Job_PBS.hxx b/src/Batch/Batch_Job_PBS.hxx new file mode 100644 index 000000000..b93c9998e --- /dev/null +++ b/src/Batch/Batch_Job_PBS.hxx @@ -0,0 +1,75 @@ +/* + * Job_PBS.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Fri Nov 14 11:00:39 2003 + * Projet : Salome 2 + * + */ + +#ifndef _JOB_PBS_H_ +#define _JOB_PBS_H_ + +extern "C" { + +#include +#include +} +#include "Batch_Job.hxx" + +namespace Batch { + + class Job_PBS + { + public: + // Constructeur et destructeur + Job_PBS(const Job & job); + virtual ~Job_PBS(); + + // Accesseurs + struct attropl * getAttributesOP(); + struct attrl * getAttributes(); + char * getScript(); + char * getDestination(); + + protected: + struct attropl * _p_attropl; // liste chainee d'attributs + operateur + struct attrl * _p_attrl; // liste chainee d'attributs + char * _script; // chemin d'acces au script du job + char * _destination; // queue dans laquelle le job est soumis + + private: + // Ajoute un element (name,resource,value) a la liste chainee d'attributs + operateur + void setResourceAttributeOP(struct attropl ** attr_list, const char * attr_name, const char * attr_resource, const char * attr_value); + + // Recherche un element (name,resource,value) dans la liste chainee d'attributs + operateur + struct attropl * findResourceAttributeOP(struct attropl * attr_list, const char * attr_name, const char * attr_resource); + + // Recherche le dernier element de la liste chainee d'attributs + operateur + struct attropl * lastAttributeOP(struct attropl * attr_list); + + // Convertit un objet Parametre en liste chainee d'attributs + operateur + struct attropl * ParametreToAttributeOPList(struct attropl ** _p_attr_list, Parametre & param); + + // Convertit un objet Environnement en liste chainee d'attributs + operateur + struct attropl * EnvironnementToAttributeOPList(struct attropl ** _p_attr_list, Environnement & env); + + // Ajoute les variables d'environnement presentes dans tout job PBS + void addPBSEnvironnement(Environnement & E); + + + // Ajoute un element (name,resource,value) a la liste chainee d'attributs + void setResourceAttribute(struct attrl ** attr_list, const char * attr_name, const char * attr_resource, const char * attr_value); + + // Recherche un element (name,resource,value) dans la liste chainee d'attributs + struct attrl * findResourceAttribute(struct attrl * attr_list, const char * attr_name, const char * attr_resource); + + // Recherche le dernier element de la liste chainee d'attributs + struct attrl * lastAttribute(struct attrl * attr_list); + + }; + +} + +#endif diff --git a/src/Batch/Batch_ListIsFullException.cxx b/src/Batch/Batch_ListIsFullException.cxx new file mode 100644 index 000000000..aba5d44ab --- /dev/null +++ b/src/Batch/Batch_ListIsFullException.cxx @@ -0,0 +1,15 @@ +/* + * ListIsFullException.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#include "Batch_ListIsFullException.hxx" + + +namespace Batch { + +} diff --git a/src/Batch/Batch_ListIsFullException.hxx b/src/Batch/Batch_ListIsFullException.hxx new file mode 100644 index 000000000..c9807b132 --- /dev/null +++ b/src/Batch/Batch_ListIsFullException.hxx @@ -0,0 +1,27 @@ +/* + * ListIsFullException.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#ifndef _LISTISFULLEXCEPTION_H_ +#define _LISTISFULLEXCEPTION_H_ + +#include "Batch_GenericException.hxx" + +namespace Batch { + + class ListIsFullException : public GenericException + { + public: + // Constructeur + ListIsFullException(string ch = "undefined") : GenericException("ListIsFullException", ch) {} + }; + +} + +#endif + diff --git a/src/Batch/Batch_LongType.cxx b/src/Batch/Batch_LongType.cxx new file mode 100644 index 000000000..2bd92c6c0 --- /dev/null +++ b/src/Batch/Batch_LongType.cxx @@ -0,0 +1,48 @@ +/* + * LongType.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#include +#include +//#include "MEDMEM_STRING.hxx" +#include "Batch_LongType.hxx" + +namespace Batch { + + // Conversion en chaine + string LongType::affiche() const + { + //MEDMEM::STRING sst; + ostringstream sst; + sst << _data; + return sst.str(); + } + + // Operateur d'affectation + LongType & LongType::operator =(long l) + { + _data = l; + return *this; + } + + // Conversion en long + LongType::operator long() const + { + return this->_data; + } + + // Clone duplique l'objet et en fabrique un nouveau a l'aide de new + // qu'il faudra detruire ensuite manuellement + GenericType * LongType::clone() const + { + LongType * pL = new LongType(this->_data); + assert(pL != 0); + return pL; + } + +} diff --git a/src/Batch/Batch_LongType.hxx b/src/Batch/Batch_LongType.hxx new file mode 100644 index 000000000..bf82d2ed3 --- /dev/null +++ b/src/Batch/Batch_LongType.hxx @@ -0,0 +1,47 @@ +/* + * LongType.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#ifndef _LONGTYPE_H_ +#define _LONGTYPE_H_ + +using namespace std; +#include +#include "Batch_GenericType.hxx" + +namespace Batch { + + class LongType : public GenericType + { + public: + // Constructeur + LongType(const long l=0L) : _data(l) {} + + // Conversion en chaine + virtual string affiche() const; + + // Operateur d'affectation + virtual LongType & operator =(long); + + // Conversion en long + virtual operator long() const; + + // Clone duplique l'objet et en fabrique un nouveau a l'aide de new + // qu'il faudra detruire ensuite manuellement + virtual GenericType * clone() const; + + protected: + long _data; + + private: + + }; + +} + +#endif diff --git a/src/Batch/Batch_MapKey.cxx b/src/Batch/Batch_MapKey.cxx new file mode 100644 index 000000000..170bd00cf --- /dev/null +++ b/src/Batch/Batch_MapKey.cxx @@ -0,0 +1,20 @@ +/* + * MapKey.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Tue Oct 14 14:00:30 2003 + * Projet : Salome 2 + * + */ + +#include +#include "Batch_MapKey.hxx" + +namespace Batch { + + +} + + +// COMMENTS diff --git a/src/Batch/Batch_MapKey.hxx b/src/Batch/Batch_MapKey.hxx new file mode 100644 index 000000000..caee3633f --- /dev/null +++ b/src/Batch/Batch_MapKey.hxx @@ -0,0 +1,47 @@ +/* + * MapKey.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Tue Oct 14 14:00:29 2003 + * Projet : Salome 2 + * + */ + +#ifndef _MAPKEY_H_ +#define _MAPKEY_H_ + + +using namespace std; +#include + +namespace Batch { + + // une classe privee pour les differents types + // ces types ne peuvent pas etre redefinis + class MapKey : public string + { + private: + friend class Parametre; // seule la classe Parametre peut creer des MapKey + MapKey() : string() {} + MapKey(const MapKey & mk, size_type pos, size_type npos) : string(mk, pos, npos) {} + MapKey(const char * s, size_type n) : string(s, n) {} + MapKey(const char * s) : string(s) {} + MapKey(size_type n, char c) : string(n, c) {} +#ifdef __STL_MEMBER_TEMPLATES + template + MapKey(InputIterator __begin, InputIterator __end) : string(__begin, __end) {} +#else + MapKey(const_iterator __begin, const_iterator __end) : string(__begin, __end) {} +#endif + + public: + MapKey(const MapKey & mk) : string(mk) {} + + }; + +} + +#endif + +// COMMENTS diff --git a/src/Batch/Batch_NotYetImplementedException.cxx b/src/Batch/Batch_NotYetImplementedException.cxx new file mode 100644 index 000000000..d5b248241 --- /dev/null +++ b/src/Batch/Batch_NotYetImplementedException.cxx @@ -0,0 +1,16 @@ +/* + * NotYetImplementedException.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Tue Nov 25 11:35:07 2003 + * Projet : Salome 2 + * + */ + +#include "Batch_NotYetImplementedException.hxx" + +namespace Batch { + +} + diff --git a/src/Batch/Batch_NotYetImplementedException.hxx b/src/Batch/Batch_NotYetImplementedException.hxx new file mode 100644 index 000000000..753290d81 --- /dev/null +++ b/src/Batch/Batch_NotYetImplementedException.hxx @@ -0,0 +1,29 @@ +/* + * NotYetImplementedException.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Tue Nov 25 11:35:07 2003 + * Projet : Salome 2 + * + */ + +#ifndef _NOTYETIMPLEMENTEDEXCEPTION_H_ +#define _NOTYETIMPLEMENTEDEXCEPTION_H_ + + +#include "Batch_GenericException.hxx" + +namespace Batch { + + class NotYetImplementedException : public GenericException + { + public: + // Constructeur + NotYetImplementedException(string ch = "undefined") : GenericException("NotYetImplementedException", ch) {} + }; + +} + +#endif + diff --git a/src/Batch/Batch_Parametre.cxx b/src/Batch/Batch_Parametre.cxx new file mode 100644 index 000000000..fb8605c1b --- /dev/null +++ b/src/Batch/Batch_Parametre.cxx @@ -0,0 +1,248 @@ +/* + * Parametre.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#include +#include "Batch_Versatile.hxx" +#include "Batch_InvalidKeyException.hxx" +#include "Batch_Parametre.hxx" + +// Definition des membres constants statiques +// Definition des noms globaux pour les clefs en tant que references +// TODO : supprimer les declarations statiques des clefs de la map +def_static_MapKey(ACCOUNT); +def_static_MapKey(CHECKPOINT); +def_static_MapKey(CKPTINTERVAL); +def_static_MapKey(CREATIONTIME); +def_static_MapKey(EGROUP); +def_static_MapKey(ELIGIBLETIME); +def_static_MapKey(EUSER); +def_static_MapKey(EXECUTABLE); +def_static_MapKey(EXECUTIONHOST); +def_static_MapKey(HOLD); +def_static_MapKey(ID); +def_static_MapKey(INFILE); +def_static_MapKey(MAIL); +def_static_MapKey(MAXCPUTIME); +def_static_MapKey(MAXDISKSIZE); +def_static_MapKey(MAXRAMSIZE); +def_static_MapKey(MAXWALLTIME); +def_static_MapKey(MODIFICATIONTIME); +def_static_MapKey(NAME); +def_static_MapKey(OUTFILE); +def_static_MapKey(PID); +def_static_MapKey(QUEUE); +def_static_MapKey(QUEUEDTIME); +def_static_MapKey(SERVER); +def_static_MapKey(STARTDATE); +def_static_MapKey(STATE); +def_static_MapKey(TEXT); +def_static_MapKey(TMPDIR); +def_static_MapKey(USEDCPUTIME); +def_static_MapKey(USEDDISKSIZE); +def_static_MapKey(USEDRAMSIZE); +def_static_MapKey(USEDWALLTIME); +def_static_MapKey(USER); + +namespace Batch { + + // Constructeur standard + // La map interne TypeMap possede les memes clefs que la map principale, mais les + // valeurs associees contiennent le type des clefs de la map principale ainsi que + // le nombre de valeurs autorisees dans l'objet Versatile (0=nombre quelconque, + // sinon valeur precisee) + Parametre::Parametre() : map< string, Versatile >() + { + TypeMap[ACCOUNT].type = STRING; + TypeMap[ACCOUNT].maxelem = 1; + + TypeMap[CHECKPOINT].type = LONG; + TypeMap[CHECKPOINT].maxelem = 1; + + TypeMap[CKPTINTERVAL].type = LONG; + TypeMap[CKPTINTERVAL].maxelem = 1; + + TypeMap[CREATIONTIME].type = LONG; + TypeMap[CREATIONTIME].maxelem = 1; + + TypeMap[EGROUP].type = STRING; + TypeMap[EGROUP].maxelem = 1; + + TypeMap[ELIGIBLETIME].type = LONG; + TypeMap[ELIGIBLETIME].maxelem = 1; + + TypeMap[EUSER].type = STRING; + TypeMap[EUSER].maxelem = 1; + + TypeMap[EXECUTABLE].type = STRING; + TypeMap[EXECUTABLE].maxelem = 1; + + TypeMap[EXECUTIONHOST].type = STRING; + TypeMap[EXECUTIONHOST].maxelem = 0; + + TypeMap[HOLD].type = LONG; + TypeMap[HOLD].maxelem = 1; + + TypeMap[ID].type = STRING; + TypeMap[ID].maxelem = 1; + + TypeMap[INFILE].type = COUPLE; + TypeMap[INFILE].maxelem = 0; + + TypeMap[MAIL].type = STRING; + TypeMap[MAIL].maxelem = 1; + + TypeMap[MAXCPUTIME].type = LONG; + TypeMap[MAXCPUTIME].maxelem = 1; + + TypeMap[MAXDISKSIZE].type = LONG; + TypeMap[MAXDISKSIZE].maxelem = 1; + + TypeMap[MAXRAMSIZE].type = LONG; + TypeMap[MAXRAMSIZE].maxelem = 1; + + TypeMap[MAXWALLTIME].type = LONG; + TypeMap[MAXWALLTIME].maxelem = 1; + + TypeMap[MODIFICATIONTIME].type = LONG; + TypeMap[MODIFICATIONTIME].maxelem = 1; + + TypeMap[NAME].type = STRING; + TypeMap[NAME].maxelem = 1; + + TypeMap[OUTFILE].type = COUPLE; + TypeMap[OUTFILE].maxelem = 0; + + TypeMap[PID].type = LONG; + TypeMap[PID].maxelem = 1; + + TypeMap[QUEUE].type = STRING; + TypeMap[QUEUE].maxelem = 1; + + TypeMap[QUEUEDTIME].type = LONG; + TypeMap[QUEUEDTIME].maxelem = 1; + + TypeMap[SERVER].type = STRING; + TypeMap[SERVER].maxelem = 1; + + TypeMap[STARTDATE].type = LONG; + TypeMap[STARTDATE].maxelem = 1; + + TypeMap[STATE].type = STRING; + TypeMap[STATE].maxelem = 1; + + TypeMap[TEXT].type = STRING; + TypeMap[TEXT].maxelem = 1; + + TypeMap[TMPDIR].type = STRING; + TypeMap[TMPDIR].maxelem = 1; + + TypeMap[USEDCPUTIME].type = LONG; + TypeMap[USEDCPUTIME].maxelem = 1; + + TypeMap[USEDDISKSIZE].type = LONG; + TypeMap[USEDDISKSIZE].maxelem = 1; + + TypeMap[USEDRAMSIZE].type = LONG; + TypeMap[USEDRAMSIZE].maxelem = 1; + + TypeMap[USEDWALLTIME].type = LONG; + TypeMap[USEDWALLTIME].maxelem = 1; + + TypeMap[USER].type = STRING; + TypeMap[USER].maxelem = 1; + } + + // Operateur de recherche dans la map + // Cet operateur agit sur les objets NON CONSTANTS, il autorise la modification de + // la valeur associée à la clef car il retourne une reference non constante + Versatile & Parametre::operator [] (const string & mk) + { + // On controle que la clef est valide + if (TypeMap.find(mk) == TypeMap.end()) throw InvalidKeyException(mk.c_str()); + + // On recherche la valeur associee... + Versatile & V = map< string, Versatile >::operator [] (mk); + + // ... et on l'initialise systematiquement + // ATTENTION : si un probleme de type survient (ie, on stocke une valeur d'un type + // different de celui inscrit dans TypeMap) une exception TypeMismatchException est + // levee + V.setName(mk); + V.setType(TypeMap[mk].type); + V.setMaxSize(TypeMap[mk].maxelem); + + return V; + } + + // Operateur de recherche dans la map + // Cet operateur agit sur les objets CONSTANTS + const Versatile & Parametre::operator [] (const string & mk) const + { + // On controle que la clef est valide + if (TypeMap.find(mk) == TypeMap.end()) throw InvalidKeyException(mk.c_str()); + + // On recherche la valeur associee + Parametre::const_iterator it = find(mk); + const Versatile & V = (*it).second; + + return V; + } + + // Operateur d'affectation + Parametre & Parametre::operator =(const Parametre & PM) + { + // On ne reaffecte pas l'objet a lui-meme, sinon aie, aie, aie + if (this == &PM) return *this; + + // On efface toute la map + erase(begin(), end()); + + // On recopie la map interne + // Meme si cela ne sert a rien pour le moment car les maps internes sont identiques, + // il n'est pas exclu que dans un avenir proche elles puissent etre differentes + (*this).TypeMap = PM.TypeMap; + + // On recree la structure interne de la map avec les valeurs de celle passee en argument + Parametre::const_iterator it; + for(it=PM.begin(); it!=PM.end(); it++) + insert(make_pair( (*it).first , + Versatile( (*it).second) + ) ); + + return *this; + } + + // Constructeur par recopie + Parametre::Parametre(const Parametre & PM) + { + // inutile car l'objet est vierge : il vient d'etre cree + // On efface toute la map + // erase(begin(), end()); + + // On recopie la map interne + (*this).TypeMap = PM.TypeMap; + + // On cree la structure interne de la map avec les valeurs de celle passee en argument + Parametre::const_iterator it; + for(it=PM.begin(); + it!=PM.end(); + it++) + insert( + make_pair( + (*it).first , + Versatile( (*it).second) + ) ); + } + + // map< string, TypeParam > Parametre::getTypeMap() const + // { + // return TypeMap; + // } + +} diff --git a/src/Batch/Batch_Parametre.hxx b/src/Batch/Batch_Parametre.hxx new file mode 100644 index 000000000..5a2d78a52 --- /dev/null +++ b/src/Batch/Batch_Parametre.hxx @@ -0,0 +1,126 @@ +/* + * Parametre.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#ifndef _PARAMETRE_H_ +#define _PARAMETRE_H_ + +using namespace std; +#include +#include +#include "Batch_InvalidKeyException.hxx" +#include "Batch_Versatile.hxx" + + +// Ces macros permettent de simplifier l'ajout de nouvelles +// clefs dans la map Parametre +// TODO : remplacer ce mecanisme statique par la lecture +// TODO : d'une descrption dans un fichier exterieur (genre XML) + +#define def_extern_MapKey(mk) extern const string & mk; +#define def_static_MapKey(mk) const string Batch::Parametre::mk(#mk); \ + const string & mk = Batch::Parametre::mk; + +namespace Batch { + + class Parametre : public map< string, Versatile > + { + public: + // Constructeur standard + Parametre(); + + // Constructeur par recopie + Parametre::Parametre(const Parametre & PM); + + // Operateur de recherche dans la map + Versatile & operator [] (const string &); + const Versatile & operator [] (const string &) const; + + // Operateur d'affectation + Parametre & operator =(const Parametre & PM); + + // Declarations statique des clefs de la map + // TODO : supprimer les declarations statiques des clefs de la map + static const string ACCOUNT; + static const string CHECKPOINT; + static const string CKPTINTERVAL; + static const string CREATIONTIME; + static const string EGROUP; + static const string ELIGIBLETIME; + static const string EUSER; + static const string EXECUTABLE; + static const string EXECUTIONHOST; + static const string HOLD; + static const string ID; + static const string INFILE; + static const string MAIL; + static const string MAXCPUTIME; + static const string MAXDISKSIZE; + static const string MAXRAMSIZE; + static const string MAXWALLTIME; + static const string MODIFICATIONTIME; + static const string NAME; + static const string OUTFILE; + static const string PID; + static const string QUEUE; + static const string QUEUEDTIME; + static const string SERVER; + static const string STARTDATE; + static const string STATE; + static const string TEXT; + static const string TMPDIR; + static const string USEDCPUTIME; + static const string USEDDISKSIZE; + static const string USEDRAMSIZE; + static const string USEDWALLTIME; + static const string USER; + + protected: + map< string, TypeParam > TypeMap; // map interne servant a controler le type de la valeur associee a chaque clef + + private: + + }; + +} + +def_extern_MapKey(ACCOUNT); +def_extern_MapKey(CHECKPOINT); +def_extern_MapKey(CKPTINTERVAL); +def_extern_MapKey(CREATIONTIME); +def_extern_MapKey(EGROUP); +def_extern_MapKey(ELIGIBLETIME); +def_extern_MapKey(EUSER); +def_extern_MapKey(EXECUTABLE); +def_extern_MapKey(EXECUTIONHOST); +def_extern_MapKey(HOLD); +def_extern_MapKey(ID); +def_extern_MapKey(INFILE); +def_extern_MapKey(MAIL); +def_extern_MapKey(MAXCPUTIME); +def_extern_MapKey(MAXDISKSIZE); +def_extern_MapKey(MAXRAMSIZE); +def_extern_MapKey(MAXWALLTIME); +def_extern_MapKey(MODIFICATIONTIME); +def_extern_MapKey(NAME); +def_extern_MapKey(OUTFILE); +def_extern_MapKey(PID); +def_extern_MapKey(QUEUE); +def_extern_MapKey(QUEUEDTIME); +def_extern_MapKey(SERVER); +def_extern_MapKey(STARTDATE); +def_extern_MapKey(STATE); +def_extern_MapKey(TEXT); +def_extern_MapKey(TMPDIR); +def_extern_MapKey(USEDCPUTIME); +def_extern_MapKey(USEDDISKSIZE); +def_extern_MapKey(USEDRAMSIZE); +def_extern_MapKey(USEDWALLTIME); +def_extern_MapKey(USER); + +#endif diff --git a/src/Batch/Batch_PyVersatile.cxx b/src/Batch/Batch_PyVersatile.cxx new file mode 100644 index 000000000..fc3a79276 --- /dev/null +++ b/src/Batch/Batch_PyVersatile.cxx @@ -0,0 +1,179 @@ +/* + * PyVersatile.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Mon Oct 13 12:01:12 2003 + * Projet : Salome 2 + * + */ + +#include +#include +#include "Batch_TypeMismatchException.hxx" +#include "Batch_ListIsFullException.hxx" +#include "Batch_InvalidArgumentException.hxx" +#include "Batch_PyVersatile.hxx" + +namespace Batch { + + // Constructeur a partir d'un objet Versatile + PyVersatile::PyVersatile(const Versatile & V) : Versatile(V) + { + // Nothing to do + } + + + // Constructeur a partir d'un PyObject + // Les objets autorises sont les strings et les ints, + // ainsi que les listes de strings + PyVersatile::PyVersatile(const PyObject * PyO) throw(TypeMismatchException, ListIsFullException, InvalidArgumentException) : Versatile() + { + PyObject * _PyO = const_cast(PyO); + + if (PyList_Check(_PyO)) { // c'est une liste + _maxsize = PyList_Size(_PyO); + for(int i=0; i<_maxsize; i++) { + PyObject * val = PyList_GetItem(_PyO, i); + if (PyString_Check(val)) { + *this += PyString_AsString(val); + + } else if (PyTuple_Check(val) && + (PyTuple_Size(val) == 2) && + PyString_Check( PyTuple_GetItem(val,0) ) && + PyString_Check( PyTuple_GetItem(val,1) ) ) { + *this += Couple( PyString_AsString( PyTuple_GetItem(val,0) ), + PyString_AsString( PyTuple_GetItem(val,1) ) + ); + + } else { + PyErr_SetString(PyExc_RuntimeWarning, "PyVersatile::PyVersatile(const PyObject * PyO) : invalid PyObject"); + } + } + + } else if (PyString_Check(_PyO)) { // c'est une string + const char * s = PyString_AsString(_PyO); + Versatile V = string(s); + *this = V; + + } else if (PyInt_Check(_PyO)) { // c'est un int + *this = PyInt_AsLong(_PyO); + + } else { // erreur + PyErr_SetString(PyExc_RuntimeWarning, "PyVersatile::PyVersatile(const PyObject * PyO) : invalid PyObject"); + } + } + + + + // Conversion de type vers un PyObject + PyVersatile::operator PyObject *() const + { + PyObject * obj; + + if (_maxsize != 1) { // une liste + obj = PyList_New(0); + for(Versatile::const_iterator it=begin(); it!=end(); it++) { + char ch[2] = {0, 0}; + string st; + Couple cp; +// PyObject * tuple; + switch (_discriminator) { + // case BOOL: + // PyList_Append(obj, PyInt_FromLong(* static_cast(*it))); + // break; + + // case CHAR: + // *ch = * static_cast(*it); + // PyList_Append(obj, PyString_FromString(ch)); + // break; + + // case INT: + // PyList_Append(obj, PyInt_FromLong(* static_cast(*it))); + // break; + + case LONG: + PyList_Append(obj, PyInt_FromLong(* static_cast(*it))); + break; + + case STRING: + st = * static_cast(*it); + PyList_Append(obj, PyString_FromString(st.c_str())); + break; + + case COUPLE: + cp = * static_cast(*it); +// tuple = PyTuple_New(2); +// PyTuple_SetItem(tuple, 0, PyString_FromString( cp.getLocal().c_str() ) ); +// PyTuple_SetItem(tuple, 1, PyString_FromString( cp.getRemote().c_str() ) ); +// PyList_Append(obj, tuple); + PyList_Append(obj, Py_BuildValue("(ss)", cp.getLocal().c_str(), cp.getRemote().c_str() )); + break; + + case UNDEFINED: + PyList_Append(obj, Py_None); + break; + } + + } + + } else { // un scalaire + char ch[2] = {0, 0}; + string st; + Couple cp; +// PyObject * tuple; + switch (_discriminator) { + // case BOOL: + // obj = PyInt_FromLong(* static_cast(front())); + // break; + + // case CHAR: + // *ch = * static_cast(front()); + // obj = PyString_FromString(ch); + // break; + + // case INT: + // obj = PyInt_FromLong(* static_cast(front())); + // break; + + case LONG: + obj = PyInt_FromLong(* static_cast(front())); + break; + + case STRING: + st = * static_cast(front()); + obj = PyString_FromString(st.c_str()); + break; + + case COUPLE: + cp = * static_cast(front()); +// tuple = PyTuple_New(2); +// PyTuple_SetItem(tuple, 0, PyString_FromString( cp.getLocal().c_str() ) ); +// PyTuple_SetItem(tuple, 1, PyString_FromString( cp.getRemote().c_str() ) ); +// obj = PyList_New(0); +// PyList_Append(obj, tuple); + obj = Py_BuildValue("[(ss)]", cp.getLocal().c_str(), cp.getRemote().c_str() ); + break; + + case UNDEFINED: + obj = Py_None; + break; + } + } + + return obj; + } + + + // Operateur d'affectation a partir d'un objet Versatile + PyVersatile & PyVersatile::operator =(const Versatile & V) + { + Versatile * me = this; + *me = V; + return *this; + } + +} + + +// COMMENTS diff --git a/src/Batch/Batch_PyVersatile.hxx b/src/Batch/Batch_PyVersatile.hxx new file mode 100644 index 000000000..c8321fb56 --- /dev/null +++ b/src/Batch/Batch_PyVersatile.hxx @@ -0,0 +1,46 @@ +/* + * PyVersatile.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Mon Oct 13 12:01:12 2003 + * Projet : Salome 2 + * + */ + +#ifndef _PYVERSATILE_H_ +#define _PYVERSATILE_H_ + + +#include +#include "Batch_Versatile.hxx" +#include "Batch_TypeMismatchException.hxx" +#include "Batch_ListIsFullException.hxx" +#include "Batch_InvalidArgumentException.hxx" + +namespace Batch { + + class PyVersatile : public Versatile + { + public: + // Constructeur a partir d'un objet Versatile + PyVersatile(const Versatile &); + + // Constructeur a partir d'un PyObject + PyVersatile(const PyObject *) throw(TypeMismatchException, ListIsFullException, InvalidArgumentException); + + // Conversion de type vers un PyObject + operator PyObject *() const; + + // Operateur d'affectation a partir d'un objet Versatile + PyVersatile & operator =(const Versatile &); + + protected: + + private: + + }; + +} + +#endif diff --git a/src/Batch/Batch_RunTimeException.cxx b/src/Batch/Batch_RunTimeException.cxx new file mode 100644 index 000000000..fd9156078 --- /dev/null +++ b/src/Batch/Batch_RunTimeException.cxx @@ -0,0 +1,15 @@ +/* + * RunTimeException.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Tue Nov 25 14:04:13 2003 + * Projet : Salome 2 + * + */ + +#include "Batch_RunTimeException.hxx" + +namespace Batch { + +} diff --git a/src/Batch/Batch_RunTimeException.hxx b/src/Batch/Batch_RunTimeException.hxx new file mode 100644 index 000000000..53194ac0b --- /dev/null +++ b/src/Batch/Batch_RunTimeException.hxx @@ -0,0 +1,28 @@ +/* + * RunTimeException.hxx : + * + * Auteur : %author% - EDF R&D + * Mail : mailto:ivan.dutka-malen@der.edf.fr + * Date : Tue Nov 25 14:04:13 2003 + * Projet : Salome 2 + * + */ + +#ifndef _RUNTIMEEXCEPTION_H_ +#define _RUNTIMEEXCEPTION_H_ + + +#include "Batch_GenericException.hxx" + +namespace Batch { + + class RunTimeException : public GenericException + { + public: + // Constructeur + RunTimeException(string ch = "undefined") : GenericException("RunTimeException", ch) {} + }; + +} + +#endif diff --git a/src/Batch/Batch_StringType.cxx b/src/Batch/Batch_StringType.cxx new file mode 100644 index 000000000..4d71c333c --- /dev/null +++ b/src/Batch/Batch_StringType.cxx @@ -0,0 +1,43 @@ +/* + * StringType.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#include +#include "Batch_StringType.hxx" + +namespace Batch { + + // Conversion en chaine + string StringType::affiche() const + { + return _data; + } + + // Operateur d'affectation + StringType & StringType::operator =(string s) + { + _data = s; + return *this; + } + + // Conversion en chaine + StringType::operator string() const + { + return this->_data; + } + + // Clone duplique l'objet et en fabrique un nouveau a l'aide de new + // qu'il faudra detruire ensuite manuellement + GenericType * StringType::clone() const + { + StringType * pS = new StringType(this->_data); + assert(pS != 0); + return pS; + } + +} diff --git a/src/Batch/Batch_StringType.hxx b/src/Batch/Batch_StringType.hxx new file mode 100644 index 000000000..4471b2976 --- /dev/null +++ b/src/Batch/Batch_StringType.hxx @@ -0,0 +1,45 @@ +/* + * StringType.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#ifndef _STRINGTYPE_H_ +#define _STRINGTYPE_H_ + +using namespace std; +#include +#include "Batch_GenericType.hxx" + +namespace Batch { + + class StringType : public GenericType + { + public: + // Constructeur + StringType(const string & s="") : _data(s) {} + + // Conversion en chaine + virtual string affiche() const; + virtual operator string() const; + + // Operateur d'affectation + virtual StringType & operator =(string); + + // Clone duplique l'objet et en fabrique un nouveau a l'aide de new + // qu'il faudra detruire ensuite manuellement + virtual GenericType * clone() const; + + protected: + string _data; + + private: + + }; + +} + +#endif diff --git a/src/Batch/Batch_TypeMismatchException.cxx b/src/Batch/Batch_TypeMismatchException.cxx new file mode 100644 index 000000000..7376eedb6 --- /dev/null +++ b/src/Batch/Batch_TypeMismatchException.cxx @@ -0,0 +1,14 @@ +/* + * TypeMismatchException.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#include "Batch_TypeMismatchException.hxx" + +namespace Batch { + +} diff --git a/src/Batch/Batch_TypeMismatchException.hxx b/src/Batch/Batch_TypeMismatchException.hxx new file mode 100644 index 000000000..fb6d1f913 --- /dev/null +++ b/src/Batch/Batch_TypeMismatchException.hxx @@ -0,0 +1,28 @@ +/* + * TypeMismatchException.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#ifndef _TYPEMISMATCHEXCEPTION_H_ +#define _TYPEMISMATCHEXCEPTION_H_ + + +#include "Batch_GenericException.hxx" + +namespace Batch { + + class TypeMismatchException : public GenericException + { + public: + // Constructeur + TypeMismatchException(string ch = "undefined") : GenericException("TypeMismatchException", ch) {} + }; + +} + +#endif + diff --git a/src/Batch/Batch_Versatile.cxx b/src/Batch/Batch_Versatile.cxx new file mode 100644 index 000000000..a0adaf1bc --- /dev/null +++ b/src/Batch/Batch_Versatile.cxx @@ -0,0 +1,300 @@ +/* + * Versatile.cxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#include +#include +#include +#include +//#include "MEDMEM_STRING.hxx" +#include "Batch_GenericType.hxx" +#include "Batch_IntType.hxx" +#include "Batch_BoolType.hxx" +#include "Batch_CharType.hxx" +#include "Batch_LongType.hxx" +#include "Batch_StringType.hxx" +#include "Batch_Versatile.hxx" +#include "Batch_TypeMismatchException.hxx" +#include "Batch_ListIsFullException.hxx" + +namespace Batch { + + // Constructeur par recopie + Versatile::Versatile(const Versatile & V) : _discriminator(V._discriminator), _maxsize(V._maxsize), _name(V._name) // , _str_value(0) + { + Versatile::const_iterator it; + + // On prend un a un les elements de l'objet passe en argument qu'on duplique + for(it=V.begin(); it!=V.end(); it++) + push_back( (*it)->clone() ); // Attention, la methode clone fait un new implicite + } + + // Destructeur + Versatile::~Versatile() + { + eraseAll(); + } + + // Operateur d'affectation entre objets + Versatile & Versatile::operator = (const Versatile & Vrhs) throw(TypeMismatchException) + { + // ATTENTION : le forçage de type leve une exception TypeMismatchException entre cas de conflit + setType(Vrhs._discriminator); + setMaxSize(Vrhs._maxsize); + _name = Vrhs._name; + + // On efface les donnees precedentes + eraseAll(); + + // On copie les donnees de Vrhs + Versatile::const_iterator it; + + for(it=Vrhs.begin(); it!=Vrhs.end(); it++) + push_back( (*it)->clone() ); // Attention, la methode clone fait un new implicite + + return *this; + } + + // Operateur d'affectation a partir d'un long + Versatile & Versatile::operator = (const long l) throw(TypeMismatchException) + { + // ATTENTION : le forçage de type leve une exception TypeMismatchException entre cas de conflit + setType(LONG); + + // On efface les donnees precedentes + eraseAll(); + + // On ajoute un element interne de type long a l'objet + LongType * pL = new LongType(l); + assert(pL != 0); + push_back(pL); + return *this; + } + + // Operateur d'affectation a partir d'une string + Versatile & Versatile::operator = (const string & ch) throw(TypeMismatchException) + { + // ATTENTION : le forçage de type leve une exception TypeMismatchException entre cas de conflit + setType(STRING); + + // On efface les donnees precedentes + eraseAll(); + + // On ajoute un element interne de type string a l'objet + StringType * pS = new StringType(ch); + assert(pS != 0); + push_back(pS); + + return *this; + } + + // Operateur de concatenation a partir d'une string + Versatile & Versatile::operator +=(const string & ch) throw(TypeMismatchException,ListIsFullException) + { + // ATTENTION : le forçage de type leve une exception TypeMismatchException entre cas de conflit + setType(STRING); + + // Si la taille maximale est atteinte, on leve une exception ListIsFullException + if (_maxsize == 0) push_back(new StringType(ch)); + else if ((_maxsize > 0) && (size() < _maxsize)) push_back(new StringType(ch)); + else { + //MEDMEM::STRING msg; + ostringstream msg; + msg << "Taille maximum : " << _maxsize; + throw(ListIsFullException(msg.str())); + } + return *this; + } + + // Operateur de concatenation a partir d'une string + Versatile & Versatile::operator , (const string & ch) throw(TypeMismatchException,ListIsFullException) + { + *this += ch; + return *this; + } + + // Operateur d'affectation a partir d'un Couple + Versatile & Versatile::operator = (const Couple & cp) throw(TypeMismatchException) + { + // ATTENTION : le forçage de type leve une exception TypeMismatchException entre cas de conflit + setType(COUPLE); + + // On efface les donnees precedentes + eraseAll(); + + // On ajoute un element interne de type Couple a l'objet + CoupleType * pC = new CoupleType(cp); + assert(pC != 0); + push_back(pC); + + return *this; + } + + // Operateur de concatenation a partir d'un Couple + Versatile & Versatile::operator +=(const Couple & cp) throw(TypeMismatchException,ListIsFullException) + { + // ATTENTION : le forçage de type leve une exception TypeMismatchException entre cas de conflit + setType(COUPLE); + + // Si la taille maximale est atteinte, on leve une exception ListIsFullException + if (_maxsize == 0) push_back(new CoupleType(cp)); + else if ((_maxsize > 0) && (size() < _maxsize)) push_back(new CoupleType(cp)); + else { + //MEDMEM::STRING msg; + ostringstream msg; + msg << "Taille maximum : " << _maxsize; + throw(ListIsFullException(msg.str())); + } + return *this; + } + + // Operateur de concatenation a partir d'un Couple + Versatile & Versatile::operator , (const Couple & cp) throw(TypeMismatchException,ListIsFullException) + { + *this += cp; + return *this; + } + + ostream & operator << (ostream & os, const Versatile & V) + { + Versatile::const_iterator it; + char * sep = ""; + + for(it=V.begin(); it!=V.end(); it++, sep=" ") { + string s = (*it)->affiche(); + os << sep << s; + } + return os; + } + + // Positionnement du type de l'element interne + void Versatile::setType(DiscriminatorType t) throw(TypeMismatchException) + { + // Si le type est deja defini et ne correspond pas au type en argument + // une exception TypeMismatchException est levee + if ( (_discriminator == UNDEFINED) || (_discriminator == t) ) + _discriminator = t; + else { + //MEDMEM::STRING sst; + ostringstream sst; + sst << "Trying to change type of Versatile object \"" + << _name << "\""; + throw(TypeMismatchException(sst.str())); + } + } + + // Positionnement du nombre d'elements internes + void Versatile::setMaxSize(int i) + { + _maxsize = i; + if (i <= 0) return; + // Si la nouvelle taille est inferieure au nombre d'elements deja + // presents, les elements en surplus sont effaces (troncature) + if (size() > _maxsize) + { + int reste = size() - _maxsize; + Versatile::iterator it; + for(it=end(); (it!=begin()) && reste; it--, reste--) + { + delete back(); + pop_back(); + } + } + } + + + // Conversion de type vers un long + Versatile::operator long() const throw(TypeMismatchException) + { + // Si le type ne correspond pas ou si la liste contient plus d'un element, + // la conversion est impossible et une exception TypeMismatchException + // est levee + if ( (_maxsize != 1) || (_discriminator != LONG) || (size() == 0) ) { + //MEDMEM::STRING sst; + ostringstream sst; + sst << "Cannot cast Versatile object \"" + << _name << "\" to long"; + throw(TypeMismatchException(sst.str())); + } + return *( static_cast(this->front()) ); + } + + // Conversion de type vers un Couple + Versatile::operator Couple() const throw(TypeMismatchException) + { + // Si le type ne correspond pas ou si la liste contient plus d'un element, + // la conversion est impossible et une exception TypeMismatchException + // est levee + if ( (_maxsize != 1) || (_discriminator != COUPLE) || (size() == 0) ) { + //MEDMEM::STRING sst; + ostringstream sst; + sst << "Cannot cast Versatile object \"" + << _name << "\" to Couple"; + throw(TypeMismatchException(sst.str())); + } + return *( static_cast(this->front()) ); + } + + // Conversion de type vers une string + string Versatile::str() const throw(TypeMismatchException) + { + // Si le type ne correspond pas, la conversion est impossible et + // une exception TypeMismatchException est levee + if ( (_discriminator != STRING) || (size() == 0) ) { + //MEDMEM::STRING sst; + ostringstream sst; + sst << "Cannot cast Versatile object \"" + << _name << "\" to string"; + throw(TypeMismatchException(sst.str())); + } + + // La chaine renvoyee est la concatenation des chaines internes + string s; + Versatile::const_iterator it; + const char * sep = ""; + for(it=begin(); it!=end(); it++, s+=sep, sep=" ") + s += *( static_cast(*it)); + + return s; + } + + // Conversion de type vers une string + Versatile::operator string () const throw(TypeMismatchException) + { + return str(); + } + + // Efface tous les elements internes de l'objet + void Versatile::eraseAll() + { + while(!empty()) + { + delete back(); + pop_back(); + } + } + + + // Recuperation du type de l'element interne + DiscriminatorType Versatile::getType() const + { + return _discriminator; + } + + // Recuperation du nom de l'objet + string Versatile::getName() const + { + return _name; + } + + // Positionnement du nom de l'objet + void Versatile::setName(const string & name) + { + _name = name; + } +} diff --git a/src/Batch/Batch_Versatile.hxx b/src/Batch/Batch_Versatile.hxx new file mode 100644 index 000000000..bf44b961e --- /dev/null +++ b/src/Batch/Batch_Versatile.hxx @@ -0,0 +1,101 @@ +/* + * Versatile.hxx : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +#ifndef _VERSATILE_H_ +#define _VERSATILE_H_ + +using namespace std; +#include +#include +#include +#include "Batch_GenericType.hxx" +#include "Batch_IntType.hxx" +#include "Batch_BoolType.hxx" +#include "Batch_CharType.hxx" +#include "Batch_LongType.hxx" +#include "Batch_StringType.hxx" +#include "Batch_CoupleType.hxx" +#include "Batch_TypeMismatchException.hxx" +#include "Batch_ListIsFullException.hxx" + +namespace Batch { + + // Les types autorises + // enum DiscriminatorType { UNDEFINED, BOOL, CHAR, INT, LONG, STRING}; + enum DiscriminatorType { UNDEFINED, LONG, STRING, COUPLE }; + + typedef struct { + DiscriminatorType type; // le type de l'element interne + int maxelem; // le nombre d'elements autorises + } TypeParam; + + class Versatile : public list< GenericType * > + { + public: + // Constructeur standard et destructeur + Versatile() : _discriminator(UNDEFINED), _maxsize(1), _name("undefined") {} + virtual ~Versatile(); + + // Constructeur par recopie + Versatile(const Versatile & V); + + // Constructeur depuis le type de "base" + Versatile(long l) : _discriminator(LONG), _maxsize(1), _name("long") { push_back(new LongType(l)); } + Versatile(const string & s) : _discriminator(STRING), _maxsize(1), _name("string") { push_back(new StringType(s)); } + Versatile(const Couple & c) : _discriminator(COUPLE), _maxsize(1), _name("couple") { push_back(new CoupleType(c)); } + + // Operateur d'affectation et de concatenation a partir d'un type de "base" + Versatile & operator = (const long l) throw(TypeMismatchException); + Versatile & operator = (const string & ch) throw(TypeMismatchException); + Versatile & operator +=(const string & ch) throw(TypeMismatchException,ListIsFullException); + Versatile & operator , (const string & ch) throw(TypeMismatchException,ListIsFullException); + Versatile & operator = (const Couple & cp) throw(TypeMismatchException); + Versatile & operator +=(const Couple & cp) throw(TypeMismatchException,ListIsFullException); + Versatile & operator , (const Couple & cp) throw(TypeMismatchException,ListIsFullException); + + // Operateur d'affectation entre objets + Versatile & operator = (const Versatile & V) throw(TypeMismatchException); + + // Conversion de type vers un type de "base" + operator long() const throw(TypeMismatchException); + operator string() const throw(TypeMismatchException); + operator Couple() const throw(TypeMismatchException); + string str() const throw(TypeMismatchException); + + // Operateur pour l'affichage sur un stream + friend ostream & operator << (ostream & os, const Versatile & ); + + // Positionnement et recuperation du type de l'element interne + void setType(DiscriminatorType) throw(TypeMismatchException); + DiscriminatorType getType() const; + + // Positionnement et recuperation du nombre d'elements internes + void setMaxSize(int i); + int getMaxSize() const { return _maxsize; } + + // Positionnement et recuperation du nom de l'objet + string getName() const; + void setName(const string & name); + + protected: + // Efface tous les elements internes de l'objet + virtual void eraseAll(); + + DiscriminatorType _discriminator; // type de l'element interne + int _maxsize; // nombre max d'elements internes + string _name; // nom de l'objet (sert pour les exceptions) + + private: + + }; + +} + +#endif + diff --git a/src/Batch/Makefile.in b/src/Batch/Makefile.in new file mode 100644 index 000000000..703e6c7e1 --- /dev/null +++ b/src/Batch/Makefile.in @@ -0,0 +1,130 @@ +# SALOME Container : implementation of container and engine for Kernel +# +# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +# +# File : Makefile.in +# Author : EDF +# Module : SALOME +# $Header$ + +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl + + +@COMMENCE@ + +EXPORT_HEADERS = \ + Batch_APIInternalFailureException.hxx \ + Batch_BatchManager.hxx \ + Batch_BatchManagerCatalog.hxx \ + Batch_BoolType.hxx \ + Batch_CharType.hxx \ + Batch_ConnexionFailureException.hxx \ + Batch_Couple.hxx \ + Batch_CoupleType.hxx \ + Batch_Date.hxx \ + Batch_DateType.hxx \ + Batch_Environnement.hxx \ + Batch_FactBatchManager.hxx \ + Batch_GenericException.hxx \ + Batch_GenericType.hxx \ + Batch_IntType.hxx \ + Batch_InvalidArgumentException.hxx \ + Batch_InvalidKeyException.hxx \ + Batch_Job.hxx \ + Batch_JobId.hxx \ + Batch_JobInfo.hxx \ + Batch_ListIsFullException.hxx \ + Batch_LongType.hxx \ + Batch_MapKey.hxx \ + Batch_NotYetImplementedException.hxx \ + Batch_Parametre.hxx \ + Batch_PyVersatile.hxx \ + Batch_RunTimeException.hxx \ + Batch_StringType.hxx \ + Batch_TypeMismatchException.hxx \ + Batch_Versatile.hxx + +# Specialisation pour OpenPBS +EXPORT_HEADERS += \ + Batch_BatchManager_PBS.hxx \ + Batch_FactBatchManager_PBS.hxx \ + Batch_JobInfo_PBS.hxx \ + Batch_Job_PBS.hxx + + +# Libraries targets + +LIB = libSalomeBatch.la +LIB_SRC = \ + Batch_APIInternalFailureException.cxx \ + Batch_BatchManager.cxx \ + Batch_BatchManagerCatalog.cxx \ + Batch_BoolType.cxx \ + Batch_CharType.cxx \ + Batch_ConnexionFailureException.cxx \ + Batch_Couple.cxx \ + Batch_CoupleType.cxx \ + Batch_Date.cxx \ + Batch_DateType.cxx \ + Batch_Environnement.cxx \ + Batch_FactBatchManager.cxx \ + Batch_GenericException.cxx \ + Batch_GenericType.cxx \ + Batch_IntType.cxx \ + Batch_InvalidArgumentException.cxx \ + Batch_InvalidKeyException.cxx \ + Batch_Job.cxx \ + Batch_JobId.cxx \ + Batch_JobInfo.cxx \ + Batch_ListIsFullException.cxx \ + Batch_LongType.cxx \ + Batch_MapKey.cxx \ + Batch_NotYetImplementedException.cxx \ + Batch_Parametre.cxx \ + Batch_PyVersatile.cxx \ + Batch_RunTimeException.cxx \ + Batch_StringType.cxx \ + Batch_TypeMismatchException.cxx \ + Batch_Versatile.cxx + +# Specialisation pour OpenPBS +LIB_SRC += \ + Batch_BatchManager_PBS.cxx \ + Batch_FactBatchManager_PBS.cxx \ + Batch_JobInfo_PBS.cxx \ + Batch_Job_PBS.cxx + +LIB_SERVER_IDL = + + +CPPFLAGS += $(PYTHON_INCLUDES) $(OPENPBS_INCLUDES) + +CXXFLAGS += $(PYTHON_INCLUDES) $(OPENPBS_INCLUDES) + +LDFLAGS += $(OPENPBS_LIBDIR) + +LIBS += $(OPENPBS_LIBS) -lSALOMELocalTrace + +@CONCLUDE@ diff --git a/src/Batch_SWIG/Batch_test.py b/src/Batch_SWIG/Batch_test.py new file mode 100644 index 000000000..b90cbc14d --- /dev/null +++ b/src/Batch_SWIG/Batch_test.py @@ -0,0 +1,53 @@ +#Batch_test.py + +# pratique +import readline +import rlcompleter +readline.parse_and_bind('tab: complete') + +# Importation de la bibliotheque de classes Batch +from libBatch_Swig import * + +def work(): + # Definition d'un job... + job=Job() + # ... de ses parametres ... + p={} + p['EXECUTABLE']='/home/dutka/tmp/job' + p['NAME']='MonJob' + p['OUTFILE']=[('/tmp/stdout', 'stdout'), ('/tmp/stderr', 'stderr')] + job.setParametre(p) + # ... et de son environnement + job.setEnvironnement({}) + print job + + # Appel au catalogue de BatchManager pour accéder au serveur cli70cu + # Instanciation du catalogue (quasi-singleton) + c=BatchManagerCatalog() + # Instanciation d'une Factory de BatchManager de type 'PBS' + # fbm=c('PBS') + + # Creation d'un BatchManager de type PBS sur le serveur cli70cu + bm=c('PBS')('cli70cu') + + # Soumission du job au BatchManager + jobid=bm.submitJob(job) + print jobid + + # Interrogation de l'etat du job + jobid.queryJob() + + # On attend que le job soit termine + try: + while 1: jinfo = jobid.queryJob() + except: + print "Job", jobid, "is done" + + pass + +if __name__ == "__main__": + work() + pass + + + diff --git a/src/Batch_SWIG/Makefile.in b/src/Batch_SWIG/Makefile.in new file mode 100644 index 000000000..89d6c9731 --- /dev/null +++ b/src/Batch_SWIG/Makefile.in @@ -0,0 +1,49 @@ +# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +# +# File : Makefile.in +# Author : Paul RASCLE, EDF +# Module : SALOME +# $Header$ + +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl + + +@COMMENCE@ + +# Libraries targets + +LIB = libBatch_Swigcmodule.la +LIB_SRC = + +SWIG_DEF = libBatch_Swig.i +EXPORT_PYSCRIPTS = libBatch_Swig.py Batch_test.py + +CPPFLAGS += $(PYTHON_INCLUDES) $(OPENPBS_INCLUDES) + +LDFLAGS += $(OPENPBS_LIBDIR) + +LIBS += $(PYTHON_LIBS) $(OPENPBS_LIBS) -lSalomeBatch + +@CONCLUDE@ diff --git a/src/Batch_SWIG/libBatch_Swig.i b/src/Batch_SWIG/libBatch_Swig.i new file mode 100644 index 000000000..1f82f0dfa --- /dev/null +++ b/src/Batch_SWIG/libBatch_Swig.i @@ -0,0 +1,59 @@ +/* + * libBatch_Swig.i : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +/* ATTENTION: + ========== + Certaines classes ont des methodes surchargees et SWIG ne gere pas bien + ces surcharges, d'ou un probleme d'utilisation en Python de celles-ci. + En bref, ça ne marche pas et il faudra corriger le probleme... + + TODO : corriger le probleme de surcharge des methodes en Python + + IDM. +*/ + + +/* Le nom du module Python tel qu'il est importe */ +%module libBatch_Swig + +/* Inclusion des conversions de type */ +%include libBatch_Swig_typemap.i + +/* Inclusion de la gestion des exceptions */ +%include libBatch_Swig_exception.i + +%{ +#include "Batch_Job.hxx" +#include "Batch_JobId.hxx" +#include "Batch_JobInfo.hxx" + +#include "Batch_BatchManager.hxx" +#include "Batch_BatchManagerCatalog.hxx" +#include "Batch_FactBatchManager.hxx" +using namespace Batch; +%} + +/* Les classes exportees en Python */ +%include Batch_Job.hxx +%include Batch_JobId.hxx +%include Batch_JobInfo.hxx + +%include Batch_BatchManager.hxx +%include Batch_BatchManagerCatalog.hxx +%include Batch_FactBatchManager.hxx + + + +/* Les methodes alterJob (surchargees et mal gerees en Python) sont + remplacees par des methodes setParametre et setEnvironnement. + cf. remarque ci-dessus. +*/ +%ignore JobId::alterJob(const Parametre & param, const Environnement & env) const; +%ignore JobId::alterJob(const Parametre & param) const; +%ignore JobId::alterJob(const Environnement & env) const; diff --git a/src/Batch_SWIG/libBatch_Swig_exception.i b/src/Batch_SWIG/libBatch_Swig_exception.i new file mode 100644 index 000000000..880ae9085 --- /dev/null +++ b/src/Batch_SWIG/libBatch_Swig_exception.i @@ -0,0 +1,24 @@ +/* + * _exception.i : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +%exception { + try { + $action + } + catch (GenericException & ex) { + string msg = ex.type + " : " + ex.message; + PyErr_SetString(PyExc_RuntimeWarning, msg.c_str()); + return NULL; + } + catch (...) { + PyErr_SetString(PyExc_RuntimeWarning, "unknown exception"); + return NULL; + } +} + diff --git a/src/Batch_SWIG/libBatch_Swig_typemap.i b/src/Batch_SWIG/libBatch_Swig_typemap.i new file mode 100644 index 000000000..9116e8798 --- /dev/null +++ b/src/Batch_SWIG/libBatch_Swig_typemap.i @@ -0,0 +1,213 @@ +/* + * _typemap.i : + * + * Auteur : Ivan DUTKA-MALEN - EDF R&D + * Date : Septembre 2003 + * Projet : SALOME 2 + * + */ + +%{ +#include +#include +#include +#include "Batch_Parametre.hxx" +#include "Batch_PyVersatile.hxx" +#include "Batch_JobId.hxx" +#include "Batch_FactBatchManager.hxx" +%} + +# // supprime toutes les definitions par defaut => sert au debug +# %typemap(in) SWIGTYPE ; + + +# // construction d'un dictionnaire Python a partir d'un objet BatchManagerCatalog C++ +%typemap(out) map * +{ + $result = PyDict_New(); + + // on itere sur toutes les clefs de la map + for(map::const_iterator it=(* $1).begin(); it!=(* $1).end(); it++) { + string key = (*it).first; + PyObject * obj = SWIG_NewPointerObj((void *) (*it).second, SWIGTYPE_p_Batch__FactBatchManager, 0); + PyDict_SetItem($result, PyString_FromString(key.c_str()), obj); + } +} + + +# // construction d'un dictionnaire Python a partir d'un objet Parametre C++ +%typemap(out) Parametre +{ + $result = PyDict_New(); + + // on itere sur toutes les clefs de la map, et on passe par la classe PyVersatile + // qui convertit un Versatile en PyObject et vice versa + for(Parametre::const_iterator it=$1.begin(); it!=$1.end(); it++) { + string key = (*it).first; + PyVersatile PyV = (*it).second; + PyDict_SetItem($result, PyString_FromString(key.c_str()), PyV); + } +} + + +# // construction d'un objet Parametre C++ a partir d'un dictionnaire Python +%typemap(in) Parametre & (Parametre PM) +{ + if (!PyDict_Check($input)) { + PyErr_SetString(PyExc_ValueError,"Expected a dictionnary"); + return NULL; + } + + try { + // on itere sur toutes les clefs du dictionnaire, et on passe par la classe PyVersatile + // qui convertit un Versatile en PyObject et vice versa + PyObject *key, *value; + int pos = 0; + while (PyDict_Next($input, &pos, &key, &value)) { + string mk = PyString_AsString(key); + PyVersatile PyV = value; + PyV.setName(mk); + PM[mk] = PyV; + } + + $1 = &PM; // $1 est une reference donc on lui passe une adresse + } + catch (GenericException & ex) { + string msg = ex.type + " : " + ex.message; + PyErr_SetString(PyExc_RuntimeWarning, msg.c_str()); + return NULL; + } + catch (...) { + PyErr_SetString(PyExc_RuntimeWarning, "unknown exception"); + return NULL; + } +} + + +# // construction d'un objet Parametre C++ a partir d'un dictionnaire Python +%typemap(in) Parametre (Parametre PM) +{ + if (!PyDict_Check($input)) { + PyErr_SetString(PyExc_ValueError,"Expected a dictionnary"); + return NULL; + } + + try { + // on itere sur toutes les clefs du dictionnaire, et on passe par la classe PyVersatile + // qui convertit un Versatile en PyObject et vice versa + PyObject *key, *value; + int pos = 0; + while (PyDict_Next($input, &pos, &key, &value)) { + string mk = PyString_AsString(key); + PyVersatile PyV = value; + PyV.setName(mk); + PM[mk] = PyV; + } + + $1 = PM; + } + catch (GenericException & ex) { + string msg = ex.type + " : " + ex.message; + PyErr_SetString(PyExc_RuntimeWarning, msg.c_str()); + return NULL; + } + catch (...) { + PyErr_SetString(PyExc_RuntimeWarning, "unknown exception"); + return NULL; + } +} + + +# // construction d'un dictionnaire Python a partir d'un objet Environnement C++ +%typemap(out) Environnement +{ + $result = PyDict_New(); + + // on itere sur toutes les clefs de la map + for(Environnement::const_iterator it=$1.begin(); it!=$1.end(); it++) { + string key = (*it).first; + string val = (*it).second; + PyDict_SetItem($result, + PyString_FromString(key.c_str()), + PyString_FromString(val.c_str())); + } +} + + +# // construction d'un objet Environnement C++ a partir d'un dictionnaire Python +%typemap(in) Environnement & (Environnement E) +{ + if (!PyDict_Check($input)) { + PyErr_SetString(PyExc_ValueError,"Expected a dictionnary"); + return NULL; + } + + // on itere sur toutes les clefs du dictionnaire + PyObject *key, *value; + int pos = 0; + while (PyDict_Next($input, &pos, &key, &value)) { + string mk = PyString_AsString(key); + string val = PyString_AsString(value); + E[mk] = val; + } + + $1 = &E; // $1 est une reference donc on lui passe une adresse +} + + + +# // construction d'un objet Environnement C++ a partir d'un dictionnaire Python +%typemap(in) Environnement (Environnement E) +{ + if (!PyDict_Check($input)) { + PyErr_SetString(PyExc_ValueError,"Expected a dictionnary"); + return NULL; + } + + // on itere sur toutes les clefs du dictionnaire + PyObject *key, *value; + int pos = 0; + while (PyDict_Next($input, &pos, &key, &value)) { + string mk = PyString_AsString(key); + string val = PyString_AsString(value); + E[mk] = val; + } + + $1 = E; +} + + + +# // construction d'une string Python a partir d'une string STL +%typemap(python,out) string +{ + $result = PyString_FromString($1.c_str()); +} + + + +# // construction d'une string STL a partir d'une string Python +#%typemap(in) string & (string S) +#{ +## if (!PyString_Check($input)) { +# PyErr_SetString(PyExc_ValueError,"Expected a string"); +# return NULL; +# } +# +# S = string(PyString_AsString($input)); +# $1 = &S; // $1 est une reference donc on lui passe une adresse +#} + + + +# // construction d'une string STL a partir d'une string Python +#%typemap(in) string (string S) +#{ +## if (!PyString_Check($input)) { +# PyErr_SetString(PyExc_ValueError,"Expected a string"); +# return NULL; +# } +# +# S = string(PyString_AsString($input)); +# $1 = S; +#} diff --git a/src/CASCatch/CASCatch_SignalsHandler.cxx b/src/CASCatch/CASCatch_SignalsHandler.cxx new file mode 100644 index 000000000..fd8cb5a0e --- /dev/null +++ b/src/CASCatch/CASCatch_SignalsHandler.cxx @@ -0,0 +1,29 @@ +// KERNEL Utils : common utils for KERNEL +// Copyright (C) 2003 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org + + +#include "CASCatch_SignalsHandler.h" +#include + + +CASCatch_SignalsHandler::CASCatch_SignalsHandler(bool theFloatingSignal) +{ + OSD::SetSignal(theFloatingSignal); +} diff --git a/src/CASCatch/CASCatch_SignalsHandler.h b/src/CASCatch/CASCatch_SignalsHandler.h new file mode 100644 index 000000000..24078c48f --- /dev/null +++ b/src/CASCatch/CASCatch_SignalsHandler.h @@ -0,0 +1,34 @@ +// KERNEL Utils : common utils for KERNEL +// Copyright (C) 2003 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org + +#ifndef _CASCATCH_SIGNALSHANDLER_H_ +#define _CASCATCH_SIGNALSHANDLER_H_ + + +#include "Utils_SignalsHandler.h" +#include + +class CASCatch_SignalsHandler: private Utils_SignalsHandler{ + public: + CASCatch_SignalsHandler(bool theFloatingSignal = true); +}; + + +#endif diff --git a/src/CASCatch/Makefile.in b/src/CASCatch/Makefile.in new file mode 100644 index 000000000..838e3e086 --- /dev/null +++ b/src/CASCatch/Makefile.in @@ -0,0 +1,50 @@ +# SALOME Utils : general SALOME's definitions and tools +# +# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +# +# File : Makefile.in +# Author : Marc Tajchman (CEA) +# Module : SALOME +# $Header$ + +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl + + +@COMMENCE@ + +# header files +EXPORT_HEADERS= CASCatch_SignalsHandler.h + +# Libraries targets +LIB = libCASCatch.la +LIB_SRC = CASCatch_SignalsHandler.cxx + +CPPFLAGS += $(OCC_INCLUDES) +CXXFLAGS += $(OCC_CXXFLAGS) +LDFLAGS+= $(CAS_KERNEL) + +@CONCLUDE@ + + diff --git a/src/Communication/Makefile.in b/src/Communication/Makefile.in new file mode 100644 index 000000000..736fbe560 --- /dev/null +++ b/src/Communication/Makefile.in @@ -0,0 +1,34 @@ + +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl + + +@COMMENCE@ + +EXPORT_PYSCRIPTS = + +EXPORT_HEADERS = \ + ReceiverFactory.hxx \ + SenderFactory.hxx \ + SALOMEMultiComm.hxx \ + MultiCommException.hxx +# Libraries targets + +LIB = libSalomeCommunication.la +LIB_SRC = SALOME_Comm_i.cxx SenderFactory.cxx Receiver.cxx MultiCommException.cxx SALOMEMultiComm.cxx ReceiverFactory.cxx +LIB_SERVER_IDL = SALOME_Comm.idl SALOME_Exception.idl + +# Executables targets +BIN = +BIN_SRC = +BIN_SERVER_IDL = + +CPPFLAGS+= $(PYTHON_INCLUDES) $(MPI_INCLUDES) + +LDFLAGS+= -lOpUtil -lSALOMELocalTrace + +LIBS += -Xlinker -export-dynamic $(PYTHON_LIBS) $(MPI_LIBS) + +@CONCLUDE@ diff --git a/src/Communication/MultiCommException.cxx b/src/Communication/MultiCommException.cxx new file mode 100644 index 000000000..d649d9652 --- /dev/null +++ b/src/Communication/MultiCommException.cxx @@ -0,0 +1,11 @@ +#include "MultiCommException.hxx" + +MultiCommException::MultiCommException(const char *message) +{ + _message=message; +} + +const char *MultiCommException::what() const +{ + return _message.c_str(); +} diff --git a/src/Communication/MultiCommException.hxx b/src/Communication/MultiCommException.hxx new file mode 100644 index 000000000..0f5466c86 --- /dev/null +++ b/src/Communication/MultiCommException.hxx @@ -0,0 +1,17 @@ +#ifndef _MULTICOMMEXCEPTION_HXX_ +#define _MULTICOMMEXCEPTION_HXX_ + +#include + +using namespace std; + +class MultiCommException { +private: + string _message; +public: + MultiCommException(const char *message); + const char *what() const; +}; + +#endif + diff --git a/src/Communication/Receiver.cxx b/src/Communication/Receiver.cxx new file mode 100644 index 000000000..dc24b200f --- /dev/null +++ b/src/Communication/Receiver.cxx @@ -0,0 +1,25 @@ +#include "Receiver.hxx" +#include + +/*! + return a deep copy of the array contained in the servant. + */ +void *Receiver::getLocalValue(long &size,SALOME_Sender_i* servant) +{ + const void *src=servant->getData(size); + long lgr=size*servant->getSizeOf(); + void *ret=new char[lgr]; + memcpy(ret,src,lgr); + return ret; + //return (void *)servant->getData(size); +} + +void *Receiver::getValue(long &size,SALOME::Sender_ptr sender) +{ + SALOME_Sender_i* data=SALOME_Sender_i::find(sender); + if(data) + return getLocalValue(size,data); + else + return getDistValue(size); +} + diff --git a/src/Communication/Receiver.hxx b/src/Communication/Receiver.hxx new file mode 100644 index 000000000..56c65ad7e --- /dev/null +++ b/src/Communication/Receiver.hxx @@ -0,0 +1,20 @@ +#ifndef _RECEIVER_HXX_ +#define _RECEIVER_HXX_ + +#include "SALOME_Comm_i.hxx" + +/*! Abstract class factorizing common methods of all the receivers. All of the receivers have to inheritate from it. + */ +class Receiver +{ +public: + virtual void *getValue(long &size)=0; + virtual ~Receiver() {} +protected: + virtual void *getValue(long &size,SALOME::Sender_ptr sender); + static inline void *getLocalValue(long &size,SALOME_Sender_i* servant); + virtual void *getDistValue(long &size)=0; +}; + +#endif + diff --git a/src/Communication/ReceiverFactory.cxx b/src/Communication/ReceiverFactory.cxx new file mode 100644 index 000000000..31bcb6768 --- /dev/null +++ b/src/Communication/ReceiverFactory.cxx @@ -0,0 +1,138 @@ +#include "ReceiverFactory.hxx" +#include "Receivers.hxx" + +#ifdef COMP_CORBA_DOUBLE +#define CorbaDNoCopyReceiver CorbaNCNoCopyReceiver +#define CorbaDWithCopyReceiver CorbaNCWithCopyReceiver +#else +#define CorbaDNoCopyReceiver CorbaWCNoCopyReceiver +#define CorbaDWithCopyReceiver CorbaWCWithCopyReceiver +#endif + +#ifdef COMP_CORBA_LONG +#define CorbaINoCopyReceiver CorbaNCNoCopyReceiver +#define CorbaIWithCopyReceiver CorbaNCWithCopyReceiver +#else +#define CorbaINoCopyReceiver CorbaWCNoCopyReceiver +#define CorbaIWithCopyReceiver CorbaWCWithCopyReceiver +#endif + +#ifdef HAVE_SOCKET +#include +#endif + +/*! + This method performs the transfert with the remote sender given. If it fails with this sender it tries with an another protocol (CORBA by default). + */ +void *ReceiverFactory::getValue(SALOME::Sender_ptr sender,long &size)throw(MultiCommException) +{ + void *ret; + try{ + ret=getValueOneShot(sender,size); + } + catch(MultiCommException&) + { + SALOME::Sender_ptr newSender=sender->buildOtherWithProtocol(SALOME::CORBA_); + MESSAGE("PROTOCOL CHANGED TO CORBA"); + sender->release(); + CORBA::release(sender); + ret=getValueOneShot(newSender,size); + } + return ret; +} + +/*! + This method performs the transfert with the remote sender given. If it fails an exception is thrown. + */ +void *ReceiverFactory::getValueOneShot(SALOME::Sender_ptr sender,long &size)throw(MultiCommException) +{ + SALOME::CorbaDoubleNCSender_ptr cncD_ptr; + SALOME::CorbaDoubleCSender_ptr cwcD_ptr; + SALOME::CorbaLongNCSender_ptr cncL_ptr; + SALOME::CorbaLongCSender_ptr cwcL_ptr; +#ifdef HAVE_MPI2 + SALOME::MPISender_ptr mpi_ptr=SALOME::MPISender::_narrow(sender); +#endif +#ifdef HAVE_SOCKET + SALOME::SocketSender_ptr sock_ptr=SALOME::SocketSender::_narrow(sender); +#endif + switch(sender->getTypeOfDataTransmitted()) + { + case SALOME::DOUBLE_: + cncD_ptr=SALOME::CorbaDoubleNCSender::_narrow(sender); + cwcD_ptr=SALOME::CorbaDoubleCSender::_narrow(sender); + if(!CORBA::is_nil(cncD_ptr)) + { + CORBA::release(sender); + CorbaDNoCopyReceiver rec(cncD_ptr); + return rec.getValue(size); + } + else if(!CORBA::is_nil(cwcD_ptr)) + { + CORBA::release(sender); + CorbaDWithCopyReceiver rec(cwcD_ptr); + return rec.getValue(size); + } +#ifdef HAVE_MPI2 + else if(!CORBA::is_nil(mpi_ptr)) + { + CORBA::release(sender); + MPIReceiver rec(mpi_ptr); + return rec.getValue(size); + } +#endif +#ifdef HAVE_SOCKET + else if(!CORBA::is_nil(sock_ptr)) + { + CORBA::release(sender); + SocketReceiver rec(sock_ptr); + return rec.getValue(size); + } +#endif + else + { + throw MultiCommException("Unknown sender protocol"); + return 0; + } + case SALOME::INT_: + cncL_ptr=SALOME::CorbaLongNCSender::_narrow(sender); + cwcL_ptr=SALOME::CorbaLongCSender::_narrow(sender); + if(!CORBA::is_nil(cncL_ptr)) + { + CORBA::release(sender); + CorbaINoCopyReceiver rec(cncL_ptr); + return rec.getValue(size); + } + else if(!CORBA::is_nil(cwcL_ptr)) + { + CORBA::release(sender); + CorbaIWithCopyReceiver rec(cwcL_ptr); + return rec.getValue(size); + } +#ifdef HAVE_MPI2 + else if(!CORBA::is_nil(mpi_ptr)) + { + CORBA::release(sender); + MPIReceiver rec(mpi_ptr); + return rec.getValue(size); + } +#endif +#ifdef HAVE_SOCKET + else if(!CORBA::is_nil(sock_ptr)) + { + CORBA::release(sender); + SocketReceiver rec(sock_ptr); + return rec.getValue(size); + } +#endif + else + { + throw MultiCommException("Unknown sender protocol"); + return 0; + } + default: + throw MultiCommException("unknown type of data transfered"); + return 0; + } +} + diff --git a/src/Communication/ReceiverFactory.hxx b/src/Communication/ReceiverFactory.hxx new file mode 100644 index 000000000..e5072c999 --- /dev/null +++ b/src/Communication/ReceiverFactory.hxx @@ -0,0 +1,21 @@ +#ifndef _RECEIVERFACTORY_HXX_ +#define _RECEIVERFACTORY_HXX_ + +#include +#include CORBA_SERVER_HEADER(SALOME_Comm) +#include "MultiCommException.hxx" + +/*! + This class internally builds a receiver associated with the sender given. It also performs transfert completely and clean up the objects. + This is the only class used client side of an array. + */ +class ReceiverFactory +{ +public: + static void *getValue(SALOME::Sender_ptr sender,long &size)throw(MultiCommException); +private: + static void *getValueOneShot(SALOME::Sender_ptr sender,long &size)throw(MultiCommException); +}; + +#endif + diff --git a/src/Communication/Receivers.cxx b/src/Communication/Receivers.cxx new file mode 100644 index 000000000..e01125aa7 --- /dev/null +++ b/src/Communication/Receivers.cxx @@ -0,0 +1,390 @@ +#include "poa.h" +#include "utilities.h" + +#define TAILLE_SPLIT 100000 +#define TIMEOUT 20 + +template +CorbaNCNoCopyReceiver::CorbaNCNoCopyReceiver(CorbaSender mySender):_mySender(mySender){ +} + +template +CorbaNCNoCopyReceiver::~CorbaNCNoCopyReceiver(){ + _mySender->release(); + CORBA::release(_mySender); +} + +template +void *CorbaNCNoCopyReceiver::getDistValue(long &size) +{ + TSeqCorba seq=_mySender->send(); + size=seq->length(); + return seq->get_buffer(1); +} + +template +void *CorbaNCNoCopyReceiver::getValue(long &size) +{ + return Receiver::getValue(size,_mySender); +} + +template +CorbaNCWithCopyReceiver::CorbaNCWithCopyReceiver(CorbaSender mySender):_mySender(mySender){ +} + +template +CorbaNCWithCopyReceiver::~CorbaNCWithCopyReceiver(){ + _mySender->release(); + CORBA::release(_mySender); +} + +template +void *CorbaNCWithCopyReceiver::getDistValue(long &size){ + size=_mySender->getSize(); + long n; + T *ret=new T[size]; + T *iter=ret; + for(long i=0;iTAILLE_SPLIT) + n=TAILLE_SPLIT; + else + n=size-i; + TSeqCorba seq=_mySender->sendPart(i,n); + T *seqd=(T *)seq->get_buffer(0); + for(long j=0;j +void *CorbaNCWithCopyReceiver::getValue(long &size) +{ + return Receiver::getValue(size,_mySender); +} + +template +CorbaWCNoCopyReceiver::CorbaWCNoCopyReceiver(CorbaSender mySender):_mySender(mySender){ +} + +template +CorbaWCNoCopyReceiver::~CorbaWCNoCopyReceiver(){ + _mySender->release(); + CORBA::release(_mySender); +} + +template +void *CorbaWCNoCopyReceiver::getDistValue(long &size){ + size=_mySender->getSize(); + long n; + T *ret=new T[size]; + T *iter=ret; + for(long i=0;iTAILLE_SPLIT) + n=TAILLE_SPLIT; + else + n=size-i; + TSeqCorba seq=_mySender->sendPart(i,n); + TCorba *seqd=seq->get_buffer(0); + for(long j=0;j +void *CorbaWCNoCopyReceiver::getValue(long &size) +{ + return Receiver::getValue(size,_mySender); +} + +template +CorbaWCWithCopyReceiver::CorbaWCWithCopyReceiver(CorbaSender mySender):_mySender(mySender){ +} + +template +CorbaWCWithCopyReceiver::~CorbaWCWithCopyReceiver(){ + _mySender->release(); + CORBA::release(_mySender); +} + +template +void *CorbaWCWithCopyReceiver::getDistValue(long &size){ + size=_mySender->getSize(); + long n; + T *ret=new T[size]; + T *iter=ret; + for(long i=0;iTAILLE_SPLIT) + n=TAILLE_SPLIT; + else + n=size-i; + TSeqCorba seq=_mySender->sendPart(i,n); + TCorba *seqd=seq->get_buffer(0); + for(long j=0;j +void *CorbaWCWithCopyReceiver::getValue(long &size) +{ + return Receiver::getValue(size,_mySender); +} + +#ifdef HAVE_MPI2 + +template +MPIReceiver::MPIReceiver(SALOME::MPISender_ptr mySender):_mySender(mySender){ +} + +template +MPIReceiver::~MPIReceiver(){ + _mySender->release(); + CORBA::release(_mySender); +} + +template +void *MPIReceiver::getDistValue(long &size){ + int i=0; + int myproc; + int sproc; + MPI_Status status; + MPI_Comm com; + char port_name_clt [MPI_MAX_PORT_NAME]; + float telps, tuser, tsys, tcpu; + T *_v; + long _n; + + + CORBA::Any a; + MPI_Comm_rank(MPI_COMM_WORLD, &myproc); + SALOME::MPISender::param_var p =_mySender->getParam(); + _mySender->send(); + sproc = p->myproc; + MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN); + while ( i != TIMEOUT && MPI_Lookup_name((char*)p->service,MPI_INFO_NULL,port_name_clt) != MPI_SUCCESS) { + i++; + } + MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_ARE_FATAL); + if ( i == TIMEOUT ) { + MPI_Finalize(); + exit(-1); + } + else{ + // Connect to service, get the inter-communicator server + // Attention MPI_Comm_connect est un appel collectif : + // - Si lancement mpirun -c n -----> uniquement MPI_COMM_SELF fonctionne + // - Si lancement client_server&client_server ----> MPI_COMM_WORLD fonctionne + + // TIMEOUT is inefficient since MPI_Comm_Connect doesn't return if we asked for + // a service that has been unpublished ! + MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN); + i = 0; + while ( i != TIMEOUT && MPI_Comm_connect(port_name_clt, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &com)!=MPI_SUCCESS ) { + i++; + } + MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_ARE_FATAL); + if ( i == TIMEOUT ) { + MPI_Finalize(); + exit(-1); + } + } + MPI_Recv( &_n, 1, MPI_LONG, sproc,p->tag1,com,&status); + _v = new T[_n]; + MPI_Recv( _v, _n, T2, sproc,p->tag2,com,&status); + _mySender->close(p); + MPI_Comm_disconnect( &com ); + size=_n; + return _v; +} + +template +void *MPIReceiver::getValue(long &size) +{ + return Receiver::getValue(size,_mySender); +} + +#endif + +#ifdef HAVE_SOCKET +#include +#include +#include +#include +#include +#include +#include + +template +SocketReceiver::SocketReceiver(SALOME::SocketSender_ptr mySender) : _mySender(mySender) +{ + _clientSockfd = -1; + _senderDestruc=true; +} + +template +SocketReceiver::~SocketReceiver() +{ + if(_senderDestruc) + { + _mySender->release(); + CORBA::release(_mySender); + } +} + +template +void *SocketReceiver::getValue(long &size) +{ + return Receiver::getValue(size,_mySender); +} + +template +void* SocketReceiver::getDistValue(long &size) +{ + int n=0, m; + T *v; + XDR xp; /* pointeur sur le decodeur XDR */ + + try{ + initCom(); + + SALOME::SocketSender::param_var p = _mySender->getParam(); + + size = p->lend - p->lstart + 1; + v = new T[size]; + + connectCom(p->internet_address, p->myport); + + _mySender->send(); + + xdrmem_create(&xp,(char*)v,size*sizeof(T),XDR_DECODE ); + while( n < size*sizeof(T) ){ + m = read(_clientSockfd, (char*)v+n, size*sizeof(T)-n); + if( m < 0 ){ + closeCom(); + delete [] v; + SALOME::ExceptionStruct es; + es.type = SALOME::COMM; + es.text = "error read Socket exception"; + throw SALOME::SALOME_Exception(es); + } + n += m; + } + xdr_vector( &xp, (char*)v, size, sizeof(T), (xdrproc_t)myFunc); + xdr_destroy( &xp ); + + _mySender->endOfCom(); + closeCom(); + } + catch(SALOME::SALOME_Exception &ex){ + if( ex.details.type == SALOME::COMM ) + { + _senderDestruc=false; + cout << ex.details.text << endl; + throw MultiCommException("Unknown sender protocol"); + } + else + throw ex; + } + + return v; +} + +template +void SocketReceiver::initCom() +{ + try{ + _mySender->initCom(); + + /* Ouverture de la socket */ + _clientSockfd = socket(AF_INET, SOCK_STREAM, 0); + if (_clientSockfd < 0) { + closeCom(); + SALOME::ExceptionStruct es; + es.type = SALOME::COMM; + es.text = "error Socket exception"; + throw SALOME::SALOME_Exception(es); + } + } + catch(SALOME::SALOME_Exception &ex){ + if( ex.details.type == SALOME::COMM ) + { + _senderDestruc=false; + cout << ex.details.text << endl; + throw MultiCommException("Unknown sender protocol"); + } + else + throw ex; + } + +} + +template +void SocketReceiver::connectCom(const char *dest_address, int port) +{ + struct sockaddr_in serv_addr; + struct hostent * server; + SALOME::ExceptionStruct es; + + try{ + /* reception of the host structure on the remote process */ + server = gethostbyname(dest_address); + if( server == NULL ) { + closeCom(); + es.type = SALOME::COMM; + es.text = "error unknown host Socket exception"; + _senderDestruc=false; + throw SALOME::SALOME_Exception(es); + } + + /* Initialisation of the socket structure */ + bzero((char*)&serv_addr,sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = INADDR_ANY; + bcopy((char *)server->h_addr, + (char *)&serv_addr.sin_addr.s_addr, + server->h_length); + serv_addr.sin_port = htons(port); + + if( connect(_clientSockfd, (struct sockaddr *) & serv_addr, sizeof(struct sockaddr)) < 0 ){ + closeCom(); + es.type = SALOME::COMM; + es.text = "error connect Socket exception"; + _senderDestruc=false; + throw SALOME::SALOME_Exception(es); + } + + _mySender->acceptCom(); + + } + catch(SALOME::SALOME_Exception &ex){ + if( ex.details.type == SALOME::COMM ) + { + _senderDestruc=false; + cout << ex.details.text << endl; + throw MultiCommException("Unknown sender protocol"); + } + else + throw ex; + } + +} + + +template +void SocketReceiver::closeCom() +{ + _mySender->closeCom(); + if( _clientSockfd >= 0 ){ + close(_clientSockfd); + _clientSockfd = -1; + } + +} + +#endif diff --git a/src/Communication/Receivers.hxx b/src/Communication/Receivers.hxx new file mode 100644 index 000000000..4fd2581ee --- /dev/null +++ b/src/Communication/Receivers.hxx @@ -0,0 +1,121 @@ +#ifndef _RECEIVERS_HXX_ +#define _RECEIVERS_HXX_ + +#include "SALOME_Comm_i.hxx" +#include "Receiver.hxx" +#ifdef HAVE_MPI2 +#include "mpi.h" +#endif + +/*! + Receiver used for transfert with CORBA when no copy is required remotely and locally. + */ +template +class CorbaNCNoCopyReceiver : public Receiver +{ +private: + CorbaSender _mySender; +public: + CorbaNCNoCopyReceiver(CorbaSender mySender); + ~CorbaNCNoCopyReceiver(); + void *getValue(long &size); +private: + void *getDistValue(long &size); +}; + +/*! + Receiver used for transfert with CORBA when copy is not required remotely but required locally. + */ +template +class CorbaNCWithCopyReceiver : public Receiver +{ +private: + CorbaSender _mySender; +public: + CorbaNCWithCopyReceiver(CorbaSender mySender); + ~CorbaNCWithCopyReceiver(); + void *getValue(long &size); +private: + void *getDistValue(long &size); +}; + +/*! + Receiver used for transfert with CORBA when copy is required remotely but not required locally. + */ +template +class CorbaWCNoCopyReceiver : public Receiver +{ +private: + CorbaSender _mySender; +public: + CorbaWCNoCopyReceiver(CorbaSender mySender); + ~CorbaWCNoCopyReceiver(); + void *getValue(long &size); +private: + void *getDistValue(long &size); +}; + +/*! + Receiver used for transfert with CORBA when copy is required both remotely and locally. + */ +template +class CorbaWCWithCopyReceiver : public Receiver +{ +private: + CorbaSender _mySender; +public: + CorbaWCWithCopyReceiver(CorbaSender mySender); + ~CorbaWCWithCopyReceiver(); + void *getValue(long &size); +private: + void *getDistValue(long &size); +}; + +#ifdef HAVE_MPI2 +/*! + Receiver for MPI transfert. + */ +template +class MPIReceiver : public Receiver +{ +private: + SALOME::MPISender_ptr _mySender; +public: + MPIReceiver(SALOME::MPISender_ptr mySender); + ~MPIReceiver(); + void *getValue(long &size); +private: + void *getDistValue(long &size); +}; +#endif + +#ifdef HAVE_SOCKET + +class XDR; + +/*! + Receiver for transfert with sockets. + */ +template +class SocketReceiver : public Receiver +{ +private: + SALOME::SocketSender_ptr _mySender; + int _clientSockfd; + bool _senderDestruc; +public: + SocketReceiver(SALOME::SocketSender_ptr mySender); + ~SocketReceiver(); + void *getValue(long &size); +private: + void *getDistValue(long &size); + void initCom(); + void connectCom(const char *, int); + void closeCom(); +}; +#endif + +#include "Receivers.cxx" + +#endif + diff --git a/src/Communication/SALOMEMultiComm.cxx b/src/Communication/SALOMEMultiComm.cxx new file mode 100644 index 000000000..71c4135e6 --- /dev/null +++ b/src/Communication/SALOMEMultiComm.cxx @@ -0,0 +1,21 @@ +#include "SALOMEMultiComm.hxx" + +SALOMEMultiComm::SALOMEMultiComm():_type(SALOME::CORBA_) +{ +} + +SALOMEMultiComm::SALOMEMultiComm(SALOME::TypeOfCommunication type):_type(type) +{ +} + +void SALOMEMultiComm::setProtocol(SALOME::TypeOfCommunication type) +{ + _type=type; +} + +SALOME::TypeOfCommunication SALOMEMultiComm::getProtocol() const +{ + return _type; +} + + diff --git a/src/Communication/SALOMEMultiComm.hxx b/src/Communication/SALOMEMultiComm.hxx new file mode 100644 index 000000000..2537dc042 --- /dev/null +++ b/src/Communication/SALOMEMultiComm.hxx @@ -0,0 +1,21 @@ +#ifndef _SALOMEMULTICOMM_HXX_ +#define _SALOMEMULTICOMM_HXX_ + +#include +#include CORBA_SERVER_HEADER(SALOME_Comm) + +/*! + Class is designed to ease the use of multi communication.\n + Simply inherite from it your servant class you want to emit data with senders. + */ +class SALOMEMultiComm : public virtual POA_SALOME::MultiCommClass { +protected: + SALOME::TypeOfCommunication _type; +public: + SALOMEMultiComm(); + SALOMEMultiComm(SALOME::TypeOfCommunication type); + virtual void setProtocol(SALOME::TypeOfCommunication type); + SALOME::TypeOfCommunication getProtocol() const; +}; + +#endif diff --git a/src/Communication/SALOME_Comm_i.cxx b/src/Communication/SALOME_Comm_i.cxx new file mode 100644 index 000000000..00fe36a11 --- /dev/null +++ b/src/Communication/SALOME_Comm_i.cxx @@ -0,0 +1,483 @@ +#include +#include "SALOME_Comm_i.hxx" +#include "poa.h" +#include "omnithread.h" +#include "Utils_SINGLETON.hxx" +#include "Utils_ORB_INIT.hxx" +#include "utilities.h" + +#include "SenderFactory.hxx" + +CORBA::ORB_var &getGlobalORB(){ + ORB_INIT &init = *SINGLETON_::Instance(); + CORBA::ORB_var &orb = init(0,0); + return orb; +} + +/*! Return the C++ data associated to the array to transmit. + Used when sender and receiver are collocalized. + */ +const void *SALOME_Sender_i::getData(long &size) const{ + size=_lgrTabToSend; + return _tabToSend; +} + +/*! Return the sizeof() of each component of the generic array + */ +int SALOME_Sender_i::getSizeOf() const { + return _sizeOf; +} + +/*! Unique constructor */ +SALOME_Sender_i::SALOME_Sender_i(SALOME::TypeOfDataTransmitted type,const void *tabToSend,long lgrTabToSend,int sizeOf):_tabToSend(tabToSend),_lgrTabToSend(lgrTabToSend),_type(type),_sizeOf(sizeOf){ +} + +/*! Method to establish if the CORBA object refered by pCorba is collocalised.\n + If it is, the pointer to the servant that incarnates the CORBA object is returned. +*/ +SALOME_Sender_i *SALOME_Sender_i::find(SALOME::Sender_ptr pCorba){ + PortableServer::ServantBase *ret; + try { + ret=PortableServer::POA::_the_root_poa()->reference_to_servant(pCorba); + } + catch(...){ + return 0; + } + ret->_remove_ref(); + return dynamic_cast(ret); +} + +/*! Method for the remote destroy of the current servant. This method is used by the receiver to destroy the sender when the transfert is complete. + */ +void SALOME_Sender_i::release() +{ + PortableServer::ObjectId_var oid = _default_POA()->servant_to_id(this); + _default_POA()->deactivate_object(oid); + _remove_ref(); +} + +/*! Return the type of the element that compose the array. Used by receiverfactory to build the correct receiver. + */ +SALOME::TypeOfDataTransmitted SALOME_Sender_i::getTypeOfDataTransmitted() +{ + return _type; +} + +/*! Return a new sender of the same array but with an another protocol. + */ +SALOME::Sender_ptr SALOME_Sender_i::buildOtherWithProtocol(SALOME::TypeOfCommunication type) +{ + return SenderFactory::buildSender(type,this); +} + +SALOME_CorbaDoubleNCSender_i::SALOME_CorbaDoubleNCSender_i(const double *tabToSend,long lgrTabToSend):SALOME_Sender_i(SALOME::DOUBLE_,tabToSend,lgrTabToSend,sizeof(double)){ +} + +SALOME_CorbaDoubleNCSender_i::~SALOME_CorbaDoubleNCSender_i(){ +} + +CORBA::ULong SALOME_CorbaDoubleNCSender_i::getSize(){ + CORBA::ULong ret=_lgrTabToSend; + return ret; +} + +SALOME::vectorOfDouble* SALOME_CorbaDoubleNCSender_i::sendPart(CORBA::ULong offset, CORBA::ULong length){ + SALOME::vectorOfDouble_var c1 = new SALOME::vectorOfDouble(length,length,(CORBA::Double *)((double *)_tabToSend+(long)offset),0); + return c1._retn(); +} + +SALOME::vectorOfDouble* SALOME_CorbaDoubleNCSender_i::send(){ + SALOME::vectorOfDouble_var c1 = new SALOME::vectorOfDouble(_lgrTabToSend,_lgrTabToSend,(CORBA::Double *)_tabToSend,0); + return c1._retn(); +} + +SALOME_CorbaDoubleCSender_i::SALOME_CorbaDoubleCSender_i(const double *tabToSend,long lgrTabToSend):SALOME_Sender_i(SALOME::DOUBLE_,tabToSend,lgrTabToSend,sizeof(double)){ +} + +SALOME_CorbaDoubleCSender_i::~SALOME_CorbaDoubleCSender_i(){ +} + +CORBA::ULong SALOME_CorbaDoubleCSender_i::getSize(){ + CORBA::ULong ret=_lgrTabToSend; + return ret; +} + +SALOME::vectorOfDouble* SALOME_CorbaDoubleCSender_i::sendPart(CORBA::ULong offset, CORBA::ULong length){ + SALOME::vectorOfDouble_var c1 = new SALOME::vectorOfDouble; + c1->length(length); + for (long i=0; ilength(length); + for (long i=0; imyproc = _cproc; + p->tag1 = _tag1; + _tag1Inst=_tag1; + p->tag2 =_tag2; + _tag2Inst=_tag2; + std::string service("toto_"); + sprintf(stag,"%d_",_tag1); + service += stag; + sprintf(stag,"%d_",p->tag2); + service += stag; + p->service = CORBA::string_dup(service.c_str()); + MPI_Open_port(MPI_INFO_NULL, _portName); + MPI_Errhandler_set(MPI_COMM_WORLD,MPI_ERRORS_RETURN); + while ( i != TIMEOUT && MPI_Publish_name((char*)service.c_str(),MPI_INFO_NULL,_portName) != MPI_SUCCESS) { + i++; + } + MPI_Errhandler_set(MPI_COMM_WORLD,MPI_ERRORS_ARE_FATAL); + if ( i == TIMEOUT ) { + MPI_Close_port(_portName); + MPI_Finalize(); + exit(-1); + } + _tag1 += 2; + _tag2 += 2; + return p._retn(); +} + +void SALOME_MPISender_i::send() +{ + _argsForThr=new (void *)[8]; + _argsForThr[0]=_portName; + _argsForThr[1]=&_lgrTabToSend; + _argsForThr[2]=(void *)_tabToSend; + _argsForThr[3]=&_cproc; + _argsForThr[4]=&_tag1Inst; + _argsForThr[5]=&_tag2Inst; + _argsForThr[6]=&_com; + _argsForThr[7]=&_type; + + _newThr=new omni_thread(SALOME_MPISender_i::myThread,_argsForThr); + _newThr->start(); +} + +void* SALOME_MPISender_i::myThread(void *args) +{ + void **argsTab=(void **)args; + long *lgrTabToSend=(long *)argsTab[1]; + int *cproc=(int *)argsTab[3]; + int *tag1=(int *)argsTab[4]; + int *tag2=(int *)argsTab[5]; + MPI_Comm *com=(MPI_Comm *)argsTab[6]; + SALOME::TypeOfDataTransmitted *type=(SALOME::TypeOfDataTransmitted *)argsTab[7]; + + MPI_Comm_accept((char *)argsTab[0],MPI_INFO_NULL,0,MPI_COMM_SELF,com); + MPI_Send(lgrTabToSend,1,MPI_LONG,*cproc,*tag1,*com); + switch(*type) + { + case SALOME::DOUBLE_: + MPI_Send(argsTab[2],*lgrTabToSend,MPI_DOUBLE,*cproc,*tag2,*com); + break; + case SALOME::INT_: + MPI_Send(argsTab[2],*lgrTabToSend,MPI_INT,*cproc,*tag2,*com); + } + omni_thread::exit(); +} + +void SALOME_MPISender_i::close(const SALOME::MPISender::param& p) +{ + std::string service(p.service); + const char *st=p.service; + void *r; + _newThr->join(&r); + MPI_Comm_free(&_com); + MPI_Unpublish_name((char *)service.c_str(),MPI_INFO_NULL,_portName); + MPI_Close_port(_portName); + delete [] _argsForThr; +} + +#endif + +#ifdef HAVE_SOCKET + +#include +#include +#include +#include +#include +#include + +SALOME_SocketSender_i::SALOME_SocketSender_i(SALOME::TypeOfDataTransmitted type,const void *tabToSend,long lgrTabToSend,int sizeOf):SALOME_Sender_i(type,tabToSend,lgrTabToSend,sizeOf){ + _IPAddress = inetAddress(); + _serverSockfd = -1; + _clientSockfd = -1; +} + +SALOME_SocketSender_i::~SALOME_SocketSender_i(){ +} + +std::string SALOME_SocketSender_i::inetAddress() +{ + char s[256]; + char t[INET_ADDRSTRLEN+1]; + struct hostent *host; + struct in_addr saddr; + + gethostname(s, 255); + + *t = '\0'; + + saddr.s_addr = inet_addr(s); + if (saddr.s_addr != -1) + inet_ntop(AF_INET, &saddr, t, INET_ADDRSTRLEN); + else { + host = gethostbyname(s); + if (host != NULL) + inet_ntop(AF_INET, (struct in_addr *) *host->h_addr_list, + t, INET_ADDRSTRLEN); + } + return std::string(t); +} + +SALOME::SocketSender::param * SALOME_SocketSender_i::getParam() +{ + + SALOME::SocketSender::param_var p = new SALOME::SocketSender::param; + + p->lstart = 0; + p->lend = _lgrTabToSend - 1; + p->myport = _port; + p->internet_address = CORBA::string_dup(_IPAddress.c_str()); + + return p._retn(); +} + +void SALOME_SocketSender_i::send() +{ + _argsForThr=new void *[6]; + _argsForThr[0]=&_serverSockfd; + _argsForThr[1]=&_clientSockfd; + _argsForThr[2]=&_lgrTabToSend; + _argsForThr[3]=(void *)_tabToSend; + _argsForThr[4]=&_errorFlag; + _argsForThr[5]=&_type; + + _newThr=new omni_thread(SALOME_SocketSender_i::myThread,_argsForThr); + _newThr->start(); +} + +void* SALOME_SocketSender_i::myThread(void *args) +{ + int n=0, m; + void **argsTab=(void **)args; + int *serverSockfd=(int *)argsTab[0]; + int *clientSockfd=(int *)argsTab[1]; + long *lgrTabToSend=(long *)argsTab[2]; + void *tabToSend=argsTab[3]; + bool *errorFlag=(bool*)argsTab[4]; + SALOME::TypeOfDataTransmitted *type=(SALOME::TypeOfDataTransmitted *)argsTab[5]; + + XDR xp; /* pointeur sur le decodeur XDR */ + + switch(*type) + { + case SALOME::DOUBLE_: + xdrmem_create(&xp,(char*)tabToSend,(*lgrTabToSend)*sizeof(double),XDR_ENCODE ); + xdr_vector( &xp, (char*)tabToSend, *lgrTabToSend, sizeof(double), (xdrproc_t)xdr_double ); + + *errorFlag = false; + while( n < *lgrTabToSend*sizeof(double) ){ + m = write(*clientSockfd, (char*)tabToSend+n, *lgrTabToSend*sizeof(double)-n); + if( m < 0 ){ + if( *clientSockfd >= 0 ){ + ::close(*clientSockfd); + *clientSockfd = -1; + } + if( *serverSockfd >= 0 ){ + ::close(*serverSockfd); + *serverSockfd = -1; + } + *errorFlag = true; + } + n += m; + } + xdr_destroy( &xp ); + + xdrmem_create(&xp,(char*)tabToSend,(*lgrTabToSend)*sizeof(double),XDR_DECODE ); + xdr_vector( &xp, (char*)tabToSend, *lgrTabToSend, sizeof(double), (xdrproc_t)xdr_double ); + xdr_destroy( &xp ); + break; + case SALOME::INT_: + xdrmem_create(&xp,(char*)tabToSend,(*lgrTabToSend)*sizeof(int),XDR_ENCODE ); + xdr_vector( &xp, (char*)tabToSend, *lgrTabToSend, sizeof(int), (xdrproc_t)xdr_int ); + + *errorFlag = false; + while( n < *lgrTabToSend*sizeof(int) ){ + m = write(*clientSockfd, (char*)tabToSend+n, *lgrTabToSend*sizeof(int)-n); + if( m < 0 ){ + if( *clientSockfd >= 0 ){ + ::close(*clientSockfd); + *clientSockfd = -1; + } + if( *serverSockfd >= 0 ){ + ::close(*serverSockfd); + *serverSockfd = -1; + } + *errorFlag = true; + } + n += m; + } + xdr_destroy( &xp ); + + xdrmem_create(&xp,(char*)tabToSend,(*lgrTabToSend)*sizeof(int),XDR_DECODE ); + xdr_vector( &xp, (char*)tabToSend, *lgrTabToSend, sizeof(int), (xdrproc_t)xdr_int ); + xdr_destroy( &xp ); + } +} + +void SALOME_SocketSender_i::initCom() throw(SALOME::SALOME_Exception) +{ + struct sockaddr_in serv_addr; + socklen_t n; + SALOME::ExceptionStruct es; + + /* Ouverture de la socket */ + _serverSockfd = socket(AF_INET , SOCK_STREAM , 0); + if(_serverSockfd < 0) { + es.type = SALOME::COMM; + es.text = "error Socket exception"; + throw SALOME::SALOME_Exception(es); + } + /* Socket structure initialisation*/ + bzero((char*)&serv_addr,sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = 0; /* asking for a free port */ + serv_addr.sin_addr.s_addr = INADDR_ANY; + + /* Association of socket with a port */ + if( ::bind(_serverSockfd, (struct sockaddr *) & serv_addr, + sizeof(struct sockaddr)) < 0 ) { + closeCom(); + es.type = SALOME::COMM; + es.text = "error bind Socket exception"; + throw SALOME::SALOME_Exception(es); + } + /* Listening to the allocated port */ + if( listen(_serverSockfd, 10) < 0 ) { + closeCom(); + es.type = SALOME::COMM; + es.text = "error listen Socket exception"; + throw SALOME::SALOME_Exception(es); + } + /* Retrieving port number*/ + if( getsockname(_serverSockfd, (struct sockaddr *) & serv_addr, &n) < 0 ){ + closeCom(); + es.type = SALOME::COMM; + es.text = "error getName Socket exception"; + throw SALOME::SALOME_Exception(es); + } + _port = htons(serv_addr.sin_port); + SCRUTE(_port); +} + +void SALOME_SocketSender_i::acceptCom() throw(SALOME::SALOME_Exception) +{ + socklen_t sin_size; + int new_fd; + struct sockaddr_in client_addr; + SALOME::ExceptionStruct es; + + sin_size = sizeof(struct sockaddr_in); + + _clientSockfd = accept(_serverSockfd, (struct sockaddr *)&client_addr, &sin_size); + if( _clientSockfd < 0 ){ + closeCom(); + es.type = SALOME::COMM; + es.text = "error accept Socket exception"; + throw SALOME::SALOME_Exception(es); + } +} + +void SALOME_SocketSender_i::closeCom() +{ + if( _clientSockfd >= 0 ){ + ::close(_clientSockfd); + _clientSockfd = -1; + } + if( _serverSockfd >= 0 ){ + ::close(_serverSockfd); + _serverSockfd = -1; + } + +} + +void SALOME_SocketSender_i::endOfCom() +{ + void *r; + _newThr->join(&r); + if(_errorFlag) + { + SALOME::ExceptionStruct es; + es.type = SALOME::COMM; + es.text = "error write Socket exception"; + throw SALOME::SALOME_Exception(es); + } + delete [] _argsForThr; +} + +#endif diff --git a/src/Communication/SALOME_Comm_i.hxx b/src/Communication/SALOME_Comm_i.hxx new file mode 100644 index 000000000..6a8c23ba9 --- /dev/null +++ b/src/Communication/SALOME_Comm_i.hxx @@ -0,0 +1,162 @@ +#ifndef _SALOME_COMM_I_HXX_ +#define _SALOME_COMM_I_HXX_ + +#include +#include +#include +#include CORBA_SERVER_HEADER(SALOME_Comm) +#ifdef HAVE_MPI2 +#include "mpi.h" +#endif + +#define TIMEOUT 20 + +using namespace std; + +/*! + Generic servant class for senders that factorizes all the common methods and attributes necessary to senders. + All servant classes for senders have to inheritate from it. + */ +class SALOME_Sender_i : public virtual POA_SALOME::Sender, + public PortableServer::RefCountServantBase { +protected: + /*! Pointer to the generic array to transmit*/ + const void *_tabToSend; + /*! Length of the generic array to transmit*/ + long _lgrTabToSend; + /*! it represents the sizeof() of each component of the generic array:\n + Practically in terms of bytes the size to be transmitted is _lgrTabToSend*_sizeOf + */ + int _sizeOf; + /*! Type the component of the array*/ + SALOME::TypeOfDataTransmitted _type; + + SALOME_Sender_i(SALOME::TypeOfDataTransmitted type,const void *tabToSend,long lgrTabToSend,int sizeOf); +public: + const void *getData(long &size) const; + int getSizeOf() const; + void release(); + SALOME::TypeOfDataTransmitted getTypeOfDataTransmitted(); + SALOME::Sender_ptr buildOtherWithProtocol(SALOME::TypeOfCommunication type); + static SALOME_Sender_i *find(SALOME::Sender_ptr pCorba); +}; + +/*! Servant class for CORBA sender for double* when no copy of array _tabToSend is required, that is to say double and CORBA::Double are binary equal. + */ +class SALOME_CorbaDoubleNCSender_i : public POA_SALOME::CorbaDoubleNCSender, + public SALOME_Sender_i +{ +public: + SALOME_CorbaDoubleNCSender_i(const double *tabToSend,long lgrTabToSend); + ~SALOME_CorbaDoubleNCSender_i(); + CORBA::ULong getSize(); + SALOME::vectorOfDouble* sendPart(CORBA::ULong offset, CORBA::ULong length); + SALOME::vectorOfDouble* send(); +}; + +/*! Servant class for CORBA sender for double* when copy of array _tabToSend is required, that is to say double and CORBA::Double are NOT binary equal. + */ +class SALOME_CorbaDoubleCSender_i : public POA_SALOME::CorbaDoubleCSender, + public SALOME_Sender_i +{ +public: + SALOME_CorbaDoubleCSender_i(const double *tabToSend,const long lgrTabToSend); + ~SALOME_CorbaDoubleCSender_i(); + CORBA::ULong getSize(); + SALOME::vectorOfDouble* sendPart(CORBA::ULong offset, CORBA::ULong length); +}; + +/*! Servant class for CORBA sender for int* when no copy of array _tabToSend is required, that is to say int and CORBA::Long are binary equal. + */ +class SALOME_CorbaLongNCSender_i : public POA_SALOME::CorbaLongNCSender, + public SALOME_Sender_i +{ +public: + SALOME_CorbaLongNCSender_i(const int *tabToSend,const long lgrTabToSend); + ~SALOME_CorbaLongNCSender_i(); + CORBA::ULong getSize(); + SALOME::vectorOfLong* sendPart(CORBA::ULong offset, CORBA::ULong length); + SALOME::vectorOfLong* send(); +}; + +/*! Servant class for CORBA sender for int* when copy of array _tabToSend is required, that is to say int and CORBA::Long are NOT binary equal. + */ +class SALOME_CorbaLongCSender_i : public POA_SALOME::CorbaLongCSender, + public SALOME_Sender_i +{ +public: + SALOME_CorbaLongCSender_i(const int *tabToSend,long lgrTabToSend); + ~SALOME_CorbaLongCSender_i(); + CORBA::ULong getSize(); + SALOME::vectorOfLong* sendPart(CORBA::ULong offset, CORBA::ULong length); + SALOME::CorbaLongCSender_ptr _this(); +}; + +#ifdef HAVE_MPI2 + +/*! Servant class of sender using MPI2. + */ +class SALOME_MPISender_i : public POA_SALOME::MPISender, + public SALOME_Sender_i +{ +private: + static unsigned long _tag1; + static unsigned long _tag2; + /*! Name of the port opened*/ + char *_portName; + int _cproc; + /*! Tag 1 that identifies the transfert*/ + int _tag1Inst; + /*! Tag 2 that identifies the transfert*/ + int _tag2Inst; + /*! MPI communicator*/ + MPI_Comm _com; + /*! Array of pointer for asynchronous invocation with omnithread*/ + void **_argsForThr; + /*! Pointer to thread created on asynchronous invocation*/ + omni_thread *_newThr; +public: + SALOME_MPISender_i(SALOME::TypeOfDataTransmitted type,const void *tabToSend,long lgrTabToSend,int sizeOf); + ~SALOME_MPISender_i(); + SALOME::MPISender::param* getParam(); + void send(); + void close(const SALOME::MPISender::param& p); +private: + static void* myThread(void *args); +}; + +#endif + +#ifdef HAVE_SOCKET + +/*! Servant class of sender using Sockets. + */ +class SALOME_SocketSender_i : public POA_SALOME::SocketSender, + public SALOME_Sender_i +{ +private: + int _serverSockfd; + int _clientSockfd; + int _port; + std::string _IPAddress; + void **_argsForThr; + omni_thread *_newThr; + bool _errorFlag; +public: + SALOME_SocketSender_i(SALOME::TypeOfDataTransmitted type,const void *tabToSend,long lgrTabToSend,int sizeOf); + ~SALOME_SocketSender_i(); + SALOME::SocketSender::param* getParam(); + void send(); + void initCom() throw(SALOME::SALOME_Exception); + void acceptCom() throw(SALOME::SALOME_Exception); + void endOfCom(); + void closeCom(); +private: + static void* myThread(void *args); + std::string inetAddress(); +}; + +#endif + +#endif + diff --git a/src/Communication/SenderFactory.cxx b/src/Communication/SenderFactory.cxx new file mode 100644 index 000000000..35b4af0b9 --- /dev/null +++ b/src/Communication/SenderFactory.cxx @@ -0,0 +1,98 @@ +#include "SenderFactory.hxx" +#include "utilities.h" +#include "SALOMEMultiComm.hxx" +#include "SALOME_Comm_i.hxx" + +#ifdef COMP_CORBA_DOUBLE +#define SALOME_CorbaDoubleSender SALOME_CorbaDoubleNCSender_i +#else +#define SALOME_CorbaDoubleSender SALOME_CorbaDoubleCSender_i +#endif + +#ifdef COMP_CORBA_LONG +#define SALOME_CorbaLongSender SALOME_CorbaLongNCSender_i +#else +#define SALOME_CorbaLongSender SALOME_CorbaLongCSender_i +#endif + +SALOME::Sender_ptr SenderFactory::buildSender(SALOMEMultiComm &multiCommunicator,const double *tab,long lgr)throw(MultiCommException){ + switch(multiCommunicator.getProtocol()) + { + case SALOME::CORBA_: + { + SALOME_CorbaDoubleSender * retc=new SALOME_CorbaDoubleSender(tab,lgr); + return retc->_this(); + } +#ifdef HAVE_MPI2 + case SALOME::MPI_: + { + SALOME_MPISender_i* retm=new SALOME_MPISender_i(SALOME::DOUBLE_,tab,lgr,sizeof(double)); + return retm->_this(); + } +#endif +#ifdef HAVE_SOCKET + case SALOME::SOCKET_: + { + SALOME_SocketSender_i* rets=new SALOME_SocketSender_i(SALOME::DOUBLE_,tab,lgr,sizeof(double)); + return rets->_this(); + } +#endif + default: + { + multiCommunicator.setProtocol(SALOME::CORBA_); + MESSAGE("PROTOCOL CHANGED TO CORBA"); + SALOME_CorbaDoubleSender * retc=new SALOME_CorbaDoubleSender(tab,lgr); + return retc->_this(); + } +// throw MultiCommException("Communication protocol not implemented"); + } +} + +SALOME::Sender_ptr SenderFactory::buildSender(SALOMEMultiComm &multiCommunicator,const int *tab,long lgr)throw(MultiCommException){ + switch(multiCommunicator.getProtocol()) + { + case SALOME::CORBA_: + { + SALOME_CorbaLongSender * retc=new SALOME_CorbaLongSender(tab,lgr); + return retc->_this(); + } +#ifdef HAVE_MPI2 + case SALOME::MPI_: + { + SALOME_MPISender_i* retm=new SALOME_MPISender_i(SALOME::INT_,tab,lgr,sizeof(int)); + return retm->_this(); + } +#endif +#ifdef HAVE_SOCKET + case SALOME::SOCKET_: + { + SALOME_SocketSender_i* rets=new SALOME_SocketSender_i(SALOME::INT_,tab,lgr,sizeof(int)); + return rets->_this(); + } +#endif + default: + { + multiCommunicator.setProtocol(SALOME::CORBA_); + SALOME_CorbaLongSender * retc=new SALOME_CorbaLongSender(tab,lgr); + return retc->_this(); + } +// throw MultiCommException("Communication protocol not implemented"); + } + } + +SALOME::Sender_ptr SenderFactory::buildSender(SALOME::TypeOfCommunication NewType,SALOME_Sender_i *src) +{ + SALOMEMultiComm mc(NewType); + long n; + const void *data=src->getData(n); + switch(src->getTypeOfDataTransmitted()) + { + case SALOME::DOUBLE_: + return buildSender(mc,(const double *)data,n); + case SALOME::INT_: + return buildSender(mc,(const int *)data,n); + } + +} + + diff --git a/src/Communication/SenderFactory.hxx b/src/Communication/SenderFactory.hxx new file mode 100644 index 000000000..d85a842ba --- /dev/null +++ b/src/Communication/SenderFactory.hxx @@ -0,0 +1,24 @@ +#ifndef _SENDERFACTORY_HXX_ +#define _SENDERFACTORY_HXX_ + +#include "MultiCommException.hxx" +#include +#include CORBA_SERVER_HEADER(SALOME_Comm) + +class SALOMEMultiComm; + +class SALOME_Sender_i; + +/*! + This class implements the factory pattern of GoF by making a sender by giving an array and a communicator.It completely hides the type of sender from the user. + */ +class SenderFactory +{ +public: + static SALOME::Sender_ptr buildSender(SALOMEMultiComm &multiCommunicator,const double *tab,long lgr) throw(MultiCommException); + static SALOME::Sender_ptr buildSender(SALOMEMultiComm &multiCommunicator,const int *tab,long lgr) throw(MultiCommException); + static SALOME::Sender_ptr buildSender(SALOME::TypeOfCommunication NewType,SALOME_Sender_i *src); +}; + +#endif + diff --git a/src/Container/SALOME_Container_SignalsHandler.cxx b/src/Container/SALOME_Container_SignalsHandler.cxx new file mode 100644 index 000000000..268de2f0b --- /dev/null +++ b/src/Container/SALOME_Container_SignalsHandler.cxx @@ -0,0 +1,36 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + + +#include +#include + +#include "CASCatch_SignalsHandler.h" // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC + + +extern "C" void HandleServerSideSignals(CORBA::ORB_ptr theORB) +{ + CASCatch_SignalsHandler aSignalsHandler; + try { + theORB->run(); + }catch(Standard_Failure){ + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + throw std::runtime_error(aFail->GetMessageString()); + } +} diff --git a/src/MSG2QM/LICENSE.QPL b/src/MSG2QM/LICENSE.QPL new file mode 100644 index 000000000..ecdad6ef5 --- /dev/null +++ b/src/MSG2QM/LICENSE.QPL @@ -0,0 +1,103 @@ + THE Q PUBLIC LICENSE + version 1.0 + + Copyright (C) 1999-2000 Trolltech AS, Norway. + Everyone is permitted to copy and + distribute this license document. + +The intent of this license is to establish freedom to share and change the +software regulated by this license under the open source model. + +This license applies to any software containing a notice placed by the +copyright holder saying that it may be distributed under the terms of +the Q Public License version 1.0. Such software is herein referred to as +the Software. This license covers modification and distribution of the +Software, use of third-party application programs based on the Software, +and development of free software which uses the Software. + + Granted Rights + +1. You are granted the non-exclusive rights set forth in this license + provided you agree to and comply with any and all conditions in this + license. Whole or partial distribution of the Software, or software + items that link with the Software, in any form signifies acceptance of + this license. + +2. You may copy and distribute the Software in unmodified form provided + that the entire package, including - but not restricted to - copyright, + trademark notices and disclaimers, as released by the initial developer + of the Software, is distributed. + +3. You may make modifications to the Software and distribute your + modifications, in a form that is separate from the Software, such as + patches. The following restrictions apply to modifications: + + a. Modifications must not alter or remove any copyright notices in + the Software. + + b. When modifications to the Software are released under this + license, a non-exclusive royalty-free right is granted to the + initial developer of the Software to distribute your modification + in future versions of the Software provided such versions remain + available under these terms in addition to any other license(s) of + the initial developer. + +4. You may distribute machine-executable forms of the Software or + machine-executable forms of modified versions of the Software, provided + that you meet these restrictions: + + a. You must include this license document in the distribution. + + b. You must ensure that all recipients of the machine-executable forms + are also able to receive the complete machine-readable source code + to the distributed Software, including all modifications, without + any charge beyond the costs of data transfer, and place prominent + notices in the distribution explaining this. + + c. You must ensure that all modifications included in the + machine-executable forms are available under the terms of this + license. + +5. You may use the original or modified versions of the Software to + compile, link and run application programs legally developed by you + or by others. + +6. You may develop application programs, reusable components and other + software items that link with the original or modified versions of the + Software. These items, when distributed, are subject to the following + requirements: + + a. You must ensure that all recipients of machine-executable forms of + these items are also able to receive and use the complete + machine-readable source code to the items without any charge + beyond the costs of data transfer. + + b. You must explicitly license all recipients of your items to use + and re-distribute original and modified versions of the items in + both machine-executable and source code forms. The recipients must + be able to do so without any charges whatsoever, and they must be + able to re-distribute to anyone they choose. + + + c. If the items are not available to the general public, and the + initial developer of the Software requests a copy of the items, + then you must supply one. + + Limitations of Liability + +In no event shall the initial developers or copyright holders be liable +for any damages whatsoever, including - but not restricted to - lost +revenue or profits or other direct, indirect, special, incidental or +consequential damages, even if they have been advised of the possibility +of such damages, except to the extent invariable law, if any, provides +otherwise. + + No Warranty + +The Software and this license document are provided AS IS with NO WARRANTY +OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. + Choice of Law + +This license is governed by the Laws of Norway. Disputes shall be settled +by Oslo City Court. diff --git a/src/MSG2QM/README b/src/MSG2QM/README new file mode 100644 index 000000000..e53a155ec --- /dev/null +++ b/src/MSG2QM/README @@ -0,0 +1,3 @@ +This package includes the msg2qm tool for resources compiling. +It is a part of Qt 3.0.5 toolkit. +The files in this package are distributed under conditions of the Q Public License. \ No newline at end of file diff --git a/src/OCCViewer/OCCViewer_Prs.cxx b/src/OCCViewer/OCCViewer_Prs.cxx new file mode 100644 index 000000000..133bd4b71 --- /dev/null +++ b/src/OCCViewer/OCCViewer_Prs.cxx @@ -0,0 +1,112 @@ +// SALOME OCCViewer : build OCC Viewer into Salome desktop +// +// Copyright (C) 2004 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : OCCViewer_Prs.cxx +// Author : Sergey ANIKIN +// Module : SALOME +// $Header$ + +#include "OCCViewer_Prs.h" + +//========================================================== +/*! + * OCCViewer_Prs::OCCViewer_Prs + * Default constructor + */ +//========================================================== +OCCViewer_Prs::OCCViewer_Prs() +{ + myToActivate = true; +} + +//========================================================== +/*! + * OCCViewer_Prs::OCCViewer_Prs + * Standard constructor + */ +//========================================================== +OCCViewer_Prs::OCCViewer_Prs( const Handle(AIS_InteractiveObject)& obj ) +{ + AddObject( obj ); +} + +//========================================================== +/*! + * OCCViewer_Prs::~OCCViewer_Prs + * Destructor + */ +//========================================================== +OCCViewer_Prs::~OCCViewer_Prs() +{ + myObjects.Clear(); +} + +//========================================================== +/*! + * OCCViewer_Prs::GetObjects + * Get interactive objects list + */ +//========================================================== +void OCCViewer_Prs::GetObjects( AIS_ListOfInteractive& list ) const +{ + list = myObjects; +} + +//========================================================== +/*! + * OCCViewer_Prs::AddObject + * Add interactive object + */ +//========================================================== +void OCCViewer_Prs::AddObject( const Handle(AIS_InteractiveObject)& obj ) +{ + myObjects.Append( obj ); +} + +//========================================================== +/*! + * OCCViewer_Prs::IsNull + * Return 0 if list of the interactive objects is empty + * [ Reimplemented from SALOME_Prs ] + */ +//========================================================== +bool OCCViewer_Prs::IsNull() const +{ + return myObjects.IsEmpty(); +} + +//================================================================= +/*! + * GEOM_Displayer::SetToActivate + * This method is used for activisation/deactivisation of + * objects in the moment of displaying +*/ +//================================================================= +void OCCViewer_Prs::SetToActivate( const bool toActivate ) +{ + myToActivate = toActivate; +} +bool OCCViewer_Prs::ToActivate() const +{ + return myToActivate; +} diff --git a/src/OCCViewer/OCCViewer_Prs.h b/src/OCCViewer/OCCViewer_Prs.h new file mode 100644 index 000000000..c79e59e3f --- /dev/null +++ b/src/OCCViewer/OCCViewer_Prs.h @@ -0,0 +1,69 @@ +// SALOME OCCViewer : build OCC Viewer into Salome desktop +// +// Copyright (C) 2004 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : OCCViewer_Prs.h +// Author : Sergey ANIKIN +// Module : SALOME +// $Header$ + +#ifndef OCCVIEWER_PRS_H +#define OCCVIEWER_PRS_H + +#include "SALOME_Prs.h" + +#include +#include + +class OCCViewer_Prs : public SALOME_OCCPrs +{ +public: + OCCViewer_Prs(); + // Default constructor + OCCViewer_Prs( const Handle(AIS_InteractiveObject)& obj ); + // Standard constructor + ~OCCViewer_Prs(); + // Destructor + + void GetObjects( AIS_ListOfInteractive& list ) const; + // Get interactive objects list + void AddObject( const Handle(AIS_InteractiveObject)& obj ); + // Add interactive object + + bool IsNull() const; + // Reimplemented from SALOME_Prs + + /* This method is used for activisation/deactivisation of + objects in the moment of displaying */ + void SetToActivate( const bool ); + bool ToActivate() const; + +private: + AIS_ListOfInteractive myObjects; // list of interactive objects + bool myToActivate; +}; + +#endif + + + + diff --git a/src/PatchQt/LICENSE.QPL b/src/PatchQt/LICENSE.QPL new file mode 100644 index 000000000..ecdad6ef5 --- /dev/null +++ b/src/PatchQt/LICENSE.QPL @@ -0,0 +1,103 @@ + THE Q PUBLIC LICENSE + version 1.0 + + Copyright (C) 1999-2000 Trolltech AS, Norway. + Everyone is permitted to copy and + distribute this license document. + +The intent of this license is to establish freedom to share and change the +software regulated by this license under the open source model. + +This license applies to any software containing a notice placed by the +copyright holder saying that it may be distributed under the terms of +the Q Public License version 1.0. Such software is herein referred to as +the Software. This license covers modification and distribution of the +Software, use of third-party application programs based on the Software, +and development of free software which uses the Software. + + Granted Rights + +1. You are granted the non-exclusive rights set forth in this license + provided you agree to and comply with any and all conditions in this + license. Whole or partial distribution of the Software, or software + items that link with the Software, in any form signifies acceptance of + this license. + +2. You may copy and distribute the Software in unmodified form provided + that the entire package, including - but not restricted to - copyright, + trademark notices and disclaimers, as released by the initial developer + of the Software, is distributed. + +3. You may make modifications to the Software and distribute your + modifications, in a form that is separate from the Software, such as + patches. The following restrictions apply to modifications: + + a. Modifications must not alter or remove any copyright notices in + the Software. + + b. When modifications to the Software are released under this + license, a non-exclusive royalty-free right is granted to the + initial developer of the Software to distribute your modification + in future versions of the Software provided such versions remain + available under these terms in addition to any other license(s) of + the initial developer. + +4. You may distribute machine-executable forms of the Software or + machine-executable forms of modified versions of the Software, provided + that you meet these restrictions: + + a. You must include this license document in the distribution. + + b. You must ensure that all recipients of the machine-executable forms + are also able to receive the complete machine-readable source code + to the distributed Software, including all modifications, without + any charge beyond the costs of data transfer, and place prominent + notices in the distribution explaining this. + + c. You must ensure that all modifications included in the + machine-executable forms are available under the terms of this + license. + +5. You may use the original or modified versions of the Software to + compile, link and run application programs legally developed by you + or by others. + +6. You may develop application programs, reusable components and other + software items that link with the original or modified versions of the + Software. These items, when distributed, are subject to the following + requirements: + + a. You must ensure that all recipients of machine-executable forms of + these items are also able to receive and use the complete + machine-readable source code to the items without any charge + beyond the costs of data transfer. + + b. You must explicitly license all recipients of your items to use + and re-distribute original and modified versions of the items in + both machine-executable and source code forms. The recipients must + be able to do so without any charges whatsoever, and they must be + able to re-distribute to anyone they choose. + + + c. If the items are not available to the general public, and the + initial developer of the Software requests a copy of the items, + then you must supply one. + + Limitations of Liability + +In no event shall the initial developers or copyright holders be liable +for any damages whatsoever, including - but not restricted to - lost +revenue or profits or other direct, indirect, special, incidental or +consequential damages, even if they have been advised of the possibility +of such damages, except to the extent invariable law, if any, provides +otherwise. + + No Warranty + +The Software and this license document are provided AS IS with NO WARRANTY +OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. + Choice of Law + +This license is governed by the Laws of Norway. Disputes shall be settled +by Oslo City Court. diff --git a/src/PatchQt/README b/src/PatchQt/README new file mode 100644 index 000000000..4a1c1a3bd --- /dev/null +++ b/src/PatchQt/README @@ -0,0 +1,2 @@ +This package includes the patch for Qt toolkit. +The files in this package are distributed under conditions of the Q Public License. \ No newline at end of file diff --git a/src/PatchQt/qfiledialogP.cxx b/src/PatchQt/qfiledialogP.cxx new file mode 100644 index 000000000..0b3ca637b --- /dev/null +++ b/src/PatchQt/qfiledialogP.cxx @@ -0,0 +1,5978 @@ +///////////////////////////////////////////////////////////////////////////// +// Module : PatchQt +// File : qfiledialogP.cxx +// Description : the patch for Qt's QFileDialog class (qfiledialog.cpp) +///////////////////////////////////////////////////////////////////////////// + +/**************************************************************************** +** $Id$ +** +** Implementation of QFileDialog class +** +** Created : 950429 +** +** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** +** This file is part of the dialogs module of the Qt GUI Toolkit. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "qplatformdefs.h" + +// Solaris redefines connect -> __xnet_connect with _XOPEN_SOURCE_EXTENDED. +#if defined(connect) +#undef connect +#endif + +#include "qfiledialogP.h" + +#ifndef QT_NO_FILEDIALOG + +#include "qlineedit.h" +#include "qcombobox.h" +#include "qlistview.h" +#include "qlistbox.h" +#include "qlabel.h" +#include "qpushbutton.h" +#include "qtoolbutton.h" +#include "qmessagebox.h" +#include "qapplication.h" +#include "private/qapplication_p.h" +#include "qlayout.h" +#include "qbitmap.h" +#include "qpopupmenu.h" +#include "qwidgetstack.h" +#include "qbuttongroup.h" +#include "qptrvector.h" +#include "qregexp.h" +#include "qstrlist.h" +#include "qtimer.h" +#include "qvbox.h" +#include "qhbox.h" +#include "qtooltip.h" +#include "qheader.h" +#include "qdragobject.h" +#include "qmime.h" +#include "qprogressbar.h" +#include "qfile.h" +#include "qcstring.h" +#include "qobjectlist.h" +#include "qcheckbox.h" +#include "qsplitter.h" +#include "qmap.h" +#include "qnetworkprotocol.h" +#include "qsemimodal.h" +#include "qpainter.h" +#include "qcleanuphandler.h" +#include "qstyle.h" +#include "qcursor.h" + +#ifndef Q_OS_TEMP +#include +#endif +#include +#include + +#ifdef Q_WS_MAC +#include "qt_mac.h" +#undef check +#endif + +#ifdef Q_WS_WIN +#include "qt_windows.h" +#endif + +/* XPM */ +static const char * const start_xpm[]={ + "16 15 8 1", + "a c #cec6bd", + "# c #000000", + "e c #ffff00", + "b c #999999", + "f c #cccccc", + "d c #dcdcdc", + "c c #ffffff", + ". c None", + ".....######aaaaa", + "...bb#cccc##aaaa", + "..bcc#cccc#d#aaa", + ".bcef#cccc#dd#aa", + ".bcfe#cccc#####a", + ".bcef#ccccccccc#", + "bbbbbbbbbbbbccc#", + "bccccccccccbbcc#", + "bcefefefefee#bc#", + ".bcefefefefef#c#", + ".bcfefefefefe#c#", + "..bcfefefefeeb##", + "..bbbbbbbbbbbbb#", + "...#############", + "................"}; + +/* XPM */ +static const char * const end_xpm[]={ + "16 15 9 1", + "d c #a0a0a0", + "c c #c3c3c3", + "# c #cec6bd", + ". c #000000", + "f c #ffff00", + "e c #999999", + "g c #cccccc", + "b c #ffffff", + "a c None", + "......####aaaaaa", + ".bbbb..###aaaaaa", + ".bbbb.c.##aaaaaa", + ".bbbb....ddeeeea", + ".bbbbbbb.bbbbbe.", + ".bbbbbbb.bcfgfe.", + "eeeeeeeeeeeeefe.", + "ebbbbbbbbbbeege.", + "ebfgfgfgfgff.ee.", + "aebfgfgfgfgfg.e.", + "aebgfgfgfgfgf.e.", + "aaebgfgfgfgffe..", + "aaeeeeeeeeeeeee.", + "aaa.............", + "aaaaaaaaaaaaaaaa"}; + +/* XPM */ +static const char* const open_xpm[]={ + "16 16 6 1", + ". c None", + "b c #ffff00", + "d c #000000", + "* c #999999", + "c c #cccccc", + "a c #ffffff", + "................", + "................", + "...*****........", + "..*aaaaa*.......", + ".*abcbcba******.", + ".*acbcbcaaaaaa*d", + ".*abcbcbcbcbcb*d", + "*************b*d", + "*aaaaaaaaaa**c*d", + "*abcbcbcbcbbd**d", + ".*abcbcbcbcbcd*d", + ".*acbcbcbcbcbd*d", + "..*acbcbcbcbb*dd", + "..*************d", + "...ddddddddddddd", + "................"}; + +/* XPM */ +static const char * const link_dir_xpm[]={ + "16 16 10 1", + "h c #808080", + "g c #a0a0a0", + "d c #000000", + "b c #ffff00", + "f c #303030", + "# c #999999", + "a c #cccccc", + "e c #585858", + "c c #ffffff", + ". c None", + "................", + "................", + "..#####.........", + ".#ababa#........", + "#abababa######..", + "#cccccccccccc#d.", + "#cbababababab#d.", + "#cabababababa#d.", + "#cbababdddddddd.", + "#cababadccccccd.", + "#cbababdcececcd.", + "#cababadcefdfcd.", + "#cbababdccgdhcd.", + "#######dccchccd.", + ".dddddddddddddd.", + "................"}; + +/* XPM */ +static const char * const link_file_xpm[]={ + "16 16 10 1", + "h c #808080", + "g c #a0a0a0", + "d c #c3c3c3", + ". c #7f7f7f", + "c c #000000", + "b c #bfbfbf", + "f c #303030", + "e c #585858", + "a c #ffffff", + "# c None", + "################", + "..........######", + ".aaaaaaaab.#####", + ".aaaaaaaaba.####", + ".aaaaaaaacccc###", + ".aaaaaaaaaabc###", + ".aaaaaaaaaabc###", + ".aaaaaaaaaadc###", + ".aaaaaaaaaadc###", + ".aaaacccccccc###", + ".aaaacaaaaaac###", + ".aaaacaeaeaac###", + ".aaaacaefcfac###", + ".aaaacaagchac###", + ".ddddcaaahaac###", + "ccccccccccccc###"}; + +/* XPM */ +static const char* const file_xpm[]={ + "16 16 5 1", + ". c #7f7f7f", + "# c None", + "c c #000000", + "b c #bfbfbf", + "a c #ffffff", + "################", + "..........######", + ".aaaaaaaab.#####", + ".aaaaaaaaba.####", + ".aaaaaaaacccc###", + ".aaaaaaaaaabc###", + ".aaaaaaaaaabc###", + ".aaaaaaaaaabc###", + ".aaaaaaaaaabc###", + ".aaaaaaaaaabc###", + ".aaaaaaaaaabc###", + ".aaaaaaaaaabc###", + ".aaaaaaaaaabc###", + ".aaaaaaaaaabc###", + ".bbbbbbbbbbbc###", + "ccccccccccccc###"}; + +/* XPM */ +static const char * const closed_xpm[]={ + "16 16 6 1", + ". c None", + "b c #ffff00", + "d c #000000", + "* c #999999", + "a c #cccccc", + "c c #ffffff", + "................", + "................", + "..*****.........", + ".*ababa*........", + "*abababa******..", + "*cccccccccccc*d.", + "*cbababababab*d.", + "*cabababababa*d.", + "*cbababababab*d.", + "*cabababababa*d.", + "*cbababababab*d.", + "*cabababababa*d.", + "*cbababababab*d.", + "**************d.", + ".dddddddddddddd.", + "................"}; + + +/* XPM */ +static const char* const cdtoparent_xpm[]={ + "15 13 3 1", + ". c None", + "* c #000000", + "a c #ffff99", + "..*****........", + ".*aaaaa*.......", + "***************", + "*aaaaaaaaaaaaa*", + "*aaaa*aaaaaaaa*", + "*aaa***aaaaaaa*", + "*aa*****aaaaaa*", + "*aaaa*aaaaaaaa*", + "*aaaa*aaaaaaaa*", + "*aaaa******aaa*", + "*aaaaaaaaaaaaa*", + "*aaaaaaaaaaaaa*", + "***************"}; + + +/* XPM */ +static const char* const newfolder_xpm[] = { + "15 14 4 1", + " c None", + ". c #000000", + "+ c #FFFF00", + "@ c #FFFFFF", + " . ", + " ", + " . ", + " . . ", + " .... . . . ", + " .+@+@. . . ", + ".......... . .", + ".@+@+@+@+@.. ", + ".+@+@+@+@+. . ", + ".@+@+@+@+@. . ", + ".+@+@+@+@+. ", + ".@+@+@+@+@. ", + ".+@+@+@+@+. ", + "........... "}; + +/* XPM */ +static const char* const detailedview_xpm[]={ + "14 11 3 1", + ". c None", + "* c #000000", + "a c #000099", + ".****.***.***.", + "..............", + "aaaaaaaaaaaaaa", + "..............", + ".****.***.***.", + "..............", + ".****.***.***.", + "..............", + ".****.***.***.", + "..............", + ".****.***.***."}; + +/* XPM */ +static const char* const previewinfoview_xpm[]={ + "13 13 4 1", + ". c #00007f", + "a c black", + "# c #cec6bd", + "b c #000000", + "..#####aaaaaa", + ".#.#bb#a#####", + "...####a#bbb#", + "#######a#####", + "#######a#bb##", + "..#####a#####", + ".#.#bb#a#bbb#", + "...####a#####", + "#######a#bb##", + "#######a#####", + "..#####a#bbb#", + ".#.#bb#a#####", + "...####aaaaaa"}; + +/* XPM */ +static const char* const previewcontentsview_xpm[]={ + "14 13 5 1", + ". c #00007f", + "a c black", + "c c #7f007f", + "# c #cec6bd", + "b c #000000", + "..#####aaaaaaa", + ".#.#bb#a#####a", + "...####a#ccc#a", + "#######a#ccc#a", + "#######a#####a", + "..#####a#bbb#a", + ".#.#bb#a#####a", + "...####a#bbb#a", + "#######a#####a", + "#######a#bbb#a", + "..#####a#####a", + ".#.#bb#a#####a", + "...####aaaaaaa"}; + +/* XPM */ +static const char* const mclistview_xpm[]={ + "15 11 4 1", + "* c None", + "b c #000000", + ". c #000099", + "a c #ffffff", + "...*****...****", + ".a.*bbb*.a.*bbb", + "...*****...****", + "***************", + "...*****...****", + ".a.*bbb*.a.*bbb", + "...*****...****", + "***************", + "...*****...****", + ".a.*bbb*.a.*bbb", + "...*****...****"}; + +/* XPM */ +static const char * const back_xpm [] = { + "13 11 3 1", + "a c #00ffff", + "# c #000000", + ". c None", + ".....#.......", + "....##.......", + "...#a#.......", + "..#aa########", + ".#aaaaaaaaaa#", + "#aaaaaaaaaaa#", + ".#aaaaaaaaaa#", + "..#aa########", + "...#a#.......", + "....##.......", + ".....#......."}; + +static QPixmap * openFolderIcon = 0; +static QPixmap * closedFolderIcon = 0; +static QPixmap * detailViewIcon = 0; +static QPixmap * multiColumnListViewIcon = 0; +static QPixmap * cdToParentIcon = 0; +static QPixmap * newFolderIcon = 0; +static QPixmap * fifteenTransparentPixels = 0; +static QPixmap * symLinkDirIcon = 0; +static QPixmap * symLinkFileIcon = 0; +static QPixmap * fileIcon = 0; +static QPixmap * startCopyIcon = 0; +static QPixmap * endCopyIcon = 0; +static QPixmap * previewContentsViewIcon = 0; +static QPixmap * previewInfoViewIcon = 0; +static QPixmap *goBackIcon = 0; +static QFileIconProviderP * fileIconProvider = 0; +static QSize *lastSize = 0; +static QString * workingDirectory = 0; + +static bool bShowHiddenFiles = FALSE; +static int sortFilesBy = (int)QDir::Name; +static bool sortAscending = TRUE; +static bool detailViewMode = FALSE; + +static QCleanupHandler qfd_cleanup_pixmap; +static QCleanupHandler qfd_cleanup_size; +static QCleanupHandler qfd_cleanup_string; + +static bool isDirectoryMode( int m ) +{ + return m == QFileDialogP::Directory || m == QFileDialogP::DirectoryOnly; +} + +#if defined(Q_WS_WIN) + +class QWindowsIconProvider : public QFileIconProviderP +{ +public: + QWindowsIconProvider( QObject *parent=0, const char *name=0 ); + ~QWindowsIconProvider(); + + const QPixmap * pixmap( const QFileInfo &fi ); + +private: + QPixmap defaultFolder; + QPixmap defaultFile; + QPixmap defaultExe; + QPixmap pix; + int pixw, pixh; + QMap< QString, QPixmap > cache; +}; +#endif + +static void makeVariables() { + if ( !openFolderIcon ) { + workingDirectory = new QString( QDir::currentDirPath() ); + qfd_cleanup_string.add( &workingDirectory ); + + openFolderIcon = new QPixmap( (const char **)open_xpm); + qfd_cleanup_pixmap.add( &openFolderIcon ); + symLinkDirIcon = new QPixmap( (const char **)link_dir_xpm); + qfd_cleanup_pixmap.add( &symLinkDirIcon ); + symLinkFileIcon = new QPixmap( (const char **)link_file_xpm); + qfd_cleanup_pixmap.add( &symLinkFileIcon ); + fileIcon = new QPixmap( (const char **)file_xpm); + qfd_cleanup_pixmap.add( &fileIcon ); + closedFolderIcon = new QPixmap( (const char **)closed_xpm); + qfd_cleanup_pixmap.add( &closedFolderIcon ); + detailViewIcon = new QPixmap( (const char **)detailedview_xpm); + qfd_cleanup_pixmap.add( &detailViewIcon ); + multiColumnListViewIcon = new QPixmap( (const char **)mclistview_xpm); + qfd_cleanup_pixmap.add( &multiColumnListViewIcon ); + cdToParentIcon = new QPixmap( (const char **)cdtoparent_xpm); + qfd_cleanup_pixmap.add( &cdToParentIcon ); + newFolderIcon = new QPixmap( (const char **)newfolder_xpm); + qfd_cleanup_pixmap.add( &newFolderIcon ); + previewInfoViewIcon + = new QPixmap( (const char **)previewinfoview_xpm ); + qfd_cleanup_pixmap.add( &previewInfoViewIcon ); + previewContentsViewIcon + = new QPixmap( (const char **)previewcontentsview_xpm ); + qfd_cleanup_pixmap.add( &previewContentsViewIcon ); + startCopyIcon = new QPixmap( (const char **)start_xpm ); + qfd_cleanup_pixmap.add( &startCopyIcon ); + endCopyIcon = new QPixmap( (const char **)end_xpm ); + qfd_cleanup_pixmap.add( &endCopyIcon ); + goBackIcon = new QPixmap( (const char **)back_xpm ); + qfd_cleanup_pixmap.add( &goBackIcon ); + fifteenTransparentPixels = new QPixmap( closedFolderIcon->width(), 1 ); + qfd_cleanup_pixmap.add( &fifteenTransparentPixels ); + QBitmap m( fifteenTransparentPixels->width(), 1 ); + m.fill( Qt::color0 ); + fifteenTransparentPixels->setMask( m ); + bShowHiddenFiles = FALSE; + sortFilesBy = (int)QDir::Name; + detailViewMode = FALSE; +#if defined(Q_WS_WIN) + if ( !fileIconProvider ) + fileIconProvider = new QWindowsIconProvider( qApp ); +#endif + } +} + +QFDProgressAnimation::QFDProgressAnimation( QWidget *parent ) + : QWidget( parent, "qt_progressanimation" ) +{ + setFixedSize( 300, 50 ); + step = -1; + next(); + timer = new QTimer( this ); + connect( timer, SIGNAL( timeout() ), + this, SLOT( next() ) ); +} + +void QFDProgressAnimation::start() +{ + timer->start( 150, FALSE ); +} + +void QFDProgressAnimation::next() +{ + ++step; + if ( step > 10 ) + step = 0; + repaint(); +} + +void QFDProgressAnimation::paintEvent( QPaintEvent * ) +{ + erase(); + + QPainter p; + p.begin( this ); + if ( step == 0 ) { + p.drawPixmap( 5, ( height() - startCopyIcon->height() ) / 2, + *startCopyIcon ); + p.drawPixmap( width() - 5 - openFolderIcon->width(), + ( height() - openFolderIcon->height() ) / 2 , *openFolderIcon ); + } else if ( step == 10 ) { + p.drawPixmap( 5, ( height() - openFolderIcon->height() ) / 2, + *openFolderIcon ); + p.drawPixmap( width() - 5 - endCopyIcon->width(), + ( height() - endCopyIcon->height() ) / 2 , *endCopyIcon ); + } else { + p.drawPixmap( 5, ( height() - openFolderIcon->height() ) / 2, + *openFolderIcon ); + p.drawPixmap( width() - 5 - openFolderIcon->width(), + ( height() - openFolderIcon->height() ) / 2 , *openFolderIcon ); + int x = 10 + openFolderIcon->width(); + int w = width() - 2 * x; + int s = w / 9; + p.drawPixmap( x + s * step, ( height() - fileIcon->height() ) / 2 - fileIcon->height(), + *fileIcon ); + } +} + +QFDProgressDialog::QFDProgressDialog( QWidget *parent, const QString &fn, int steps ) + : QDialog( parent, "", TRUE ) +{ +#ifndef QT_NO_WIDGET_TOPEXTRA + setCaption( QFileDialogP::tr( "Copy or Move a File" ) ); +#endif + QVBoxLayout *layout = new QVBoxLayout( this ); + layout->setSpacing( 5 ); + layout->setMargin( 5 ); + + animation = new QFDProgressAnimation( this ); + layout->addWidget( animation ); + + layout->addWidget( new QLabel( QFileDialogP::tr( "Read: %1" ).arg( fn ), + this, "qt_read_lbl" ) ); + readBar = new QProgressBar( steps, this, "qt_readbar" ); + readBar->reset(); + readBar->setProgress( 0 ); + layout->addWidget( readBar ); + writeLabel = new QLabel( QFileDialogP::tr( "Write: %1" ).arg( QString::null ), + this, "qt_write_lbl" ); + layout->addWidget( writeLabel ); + writeBar = new QProgressBar( steps, this, "qt_writebar" ); + writeBar->reset(); + writeBar->setProgress( 0 ); + layout->addWidget( writeBar ); + + QPushButton *b = new QPushButton( QFileDialogP::tr( "Cancel" ), this, + "qt_cancel_btn" ); + b->setFixedSize( b->sizeHint() ); + layout->addWidget( b ); + connect( b, SIGNAL( clicked() ), + this, SIGNAL( cancelled() ) ); + + animation->start(); +} + +void QFDProgressDialog::setReadProgress( int p ) +{ + readBar->setProgress( p ); +} + +void QFDProgressDialog::setWriteProgress( int p ) +{ + writeBar->setProgress( p ); +} + +void QFDProgressDialog::setWriteLabel( const QString &s ) +{ + writeLabel->setText( QFileDialogP::tr( "Write: %1" ).arg( s ) ); +} + +/************************************************************************ + * + * Private QFileDialogP members + * + ************************************************************************/ + +class QFileDialogPrivate { +public: + ~QFileDialogPrivate(); + + QStringList history; + + bool geometryDirty; + QComboBox * paths; + QComboBox * types; + QLabel * pathL; + QLabel * fileL; + QLabel * typeL; + + QVBoxLayout * topLevelLayout; + QHBoxLayout *buttonLayout, *leftLayout, *rightLayout; + QPtrList extraWidgetsLayouts; + QPtrList extraLabels; + QPtrList extraWidgets; + QPtrList extraButtons; + QPtrList toolButtons; + + QWidgetStack * stack; + + QToolButton * cdToParent, *newFolder, * detailView, * mcView, + *previewInfo, *previewContents, *goBack; + QButtonGroup * modeButtons; + + QString currentFileName; + QListViewItem *last; + + struct File: public QListViewItem { + File( QFileDialogPrivate * dlgp, + const QUrlInfo * fi, QListViewItem * parent ) + : QListViewItem( parent, dlgp->last ), info( *fi ), d(dlgp), i( 0 ), hasMimePixmap( FALSE ) + { setup(); dlgp->last = this; } + File( QFileDialogPrivate * dlgp, + const QUrlInfo * fi, QListView * parent ) + : QListViewItem( parent, dlgp->last ), info( *fi ), d(dlgp), i( 0 ), hasMimePixmap( FALSE ) + { setup(); dlgp->last = this; } + File( QFileDialogPrivate * dlgp, + const QUrlInfo * fi, QListView * parent, QListViewItem * after ) + : QListViewItem( parent, after ), info( *fi ), d(dlgp), i( 0 ), hasMimePixmap( FALSE ) + { setup(); if ( !nextSibling() ) dlgp->last = this; } + ~File(); + + QString text( int column ) const; + const QPixmap * pixmap( int ) const; + + QUrlInfo info; + QFileDialogPrivate * d; + QListBoxItem *i; + bool hasMimePixmap; + }; + + class MCItem: public QListBoxItem { + public: + MCItem( QListBox *, QListViewItem * item ); + MCItem( QListBox *, QListViewItem * item, QListBoxItem *after ); + QString text() const; + const QPixmap *pixmap() const; + int height( const QListBox * ) const; + int width( const QListBox * ) const; + void paint( QPainter * ); + QListViewItem * i; + }; + + class UrlInfoList : public QPtrList { + public: + UrlInfoList() { setAutoDelete( TRUE ); } + int compareItems( QPtrCollection::Item n1, QPtrCollection::Item n2 ) { + if ( !n1 || !n2 ) + return 0; + + QUrlInfo *i1 = ( QUrlInfo *)n1; + QUrlInfo *i2 = ( QUrlInfo *)n2; + + if ( i1->isDir() && !i2->isDir() ) + return -1; + if ( !i1->isDir() && i2->isDir() ) + return 1; + + if ( i1->name() == ".." ) + return -1; + if ( i2->name() == ".." ) + return 1; + +#if defined(Q_OS_WIN32) + if ( sortFilesBy == QDir::Name ) { + QString name1 = i1->name().lower(); + QString name2 = i2->name().lower(); + return name1.compare( name2 ); + } +#endif + if ( QUrlInfo::equal( *i1, *i2, sortFilesBy ) ) + return 0; + else if ( QUrlInfo::greaterThan( *i1, *i2, sortFilesBy ) ) + return 1; + else if ( QUrlInfo::lessThan( *i1, *i2, sortFilesBy ) ) + return -1; + // can't happen... + return 0; + } + QUrlInfo *operator[]( int i ) { + return at( i ); + } + }; + + UrlInfoList sortedList; + QPtrList pendingItems; + + QFileListBox * moreFiles; + + QFileDialogP::Mode mode; + + QString rw; + QString ro; + QString wo; + QString inaccessible; + + QString symLinkToFile; + QString file; + QString symLinkToDir; + QString dir; + QString symLinkToSpecial; + QString special; + QWidgetStack *preview; + bool infoPreview, contentsPreview; + QSplitter *splitter; + QUrlOperator url, oldUrl; + QWidget *infoPreviewWidget, *contentsPreviewWidget; + QFilePreviewP *infoPreviewer, *contentsPreviewer; + bool hadDotDot; + + bool ignoreNextKeyPress; + // ignores the next refresh operation in case the user forced a selection + bool ignoreNextRefresh; + QFDProgressDialog *progressDia; + bool checkForFilter; + bool ignoreReturn; + bool ignoreStop; + + QTimer *mimeTypeTimer; + const QNetworkOperation *currListChildren; + + // this is similar to QUrl::encode but does encode "*" and + // doesn't encode whitespaces + static QString encodeFileName( const QString& fName ) { + + QString newStr; + QCString cName = fName.utf8(); + const QCString sChars( +#ifdef Q_WS_WIN + "#%" +#else + "<>#@\"&%$:,;?={}|^~[]\'`\\*" +#endif + ); + + int len = cName.length(); + if ( !len ) + return QString::null; + for ( int i = 0; i < len ;++i ) { + uchar inCh = (uchar)cName[ i ]; + if ( inCh >= 128 || sChars.contains(inCh) ) + { + newStr += QChar( '%' ); + ushort c = inCh / 16; + c += c > 9 ? 'A' - 10 : '0'; + newStr += c; + c = inCh % 16; + c += c > 9 ? 'A' - 10 : '0'; + newStr += c; + } else { + newStr += inCh; + } + } + return newStr; + } + +}; + +QFileDialogPrivate::~QFileDialogPrivate() +{ + delete modeButtons; +} + + + +/************************************************************************ + * + * Internal class QRenameEdit + * + ************************************************************************/ + +void QRenameEdit::keyPressEvent( QKeyEvent *e ) +{ + if ( e->key() == Key_Escape ) + emit escapePressed(); + else + QLineEdit::keyPressEvent( e ); + e->accept(); +} + +void QRenameEdit::focusOutEvent( QFocusEvent * ) +{ + emit escapePressed(); +} + +/************************************************************************ + * + * Internal class QFileListBox + * + ************************************************************************/ + +QFileListBox::QFileListBox( QWidget *parent, QFileDialogP *dlg ) + : QListBox( parent, "filelistbox" ), filedialog( dlg ), + renaming( FALSE ), renameItem( 0 ), mousePressed( FALSE ), + firstMousePressEvent( TRUE ) +{ + changeDirTimer = new QTimer( this ); + QVBox *box = new QVBox( viewport(), "qt_vbox" ); + box->setFrameStyle( QFrame::Box | QFrame::Plain ); + lined = new QRenameEdit( box ); + lined->setFixedHeight( lined->sizeHint().height() ); + box->hide(); + box->setBackgroundMode( PaletteBase ); + renameTimer = new QTimer( this ); + connect( lined, SIGNAL( returnPressed() ), + this, SLOT (rename() ) ); + connect( lined, SIGNAL( escapePressed() ), + this, SLOT( cancelRename() ) ); + connect( renameTimer, SIGNAL( timeout() ), + this, SLOT( doubleClickTimeout() ) ); + connect( changeDirTimer, SIGNAL( timeout() ), + this, SLOT( changeDirDuringDrag() ) ); + connect( this, SIGNAL( contentsMoving( int, int ) ), + this, SLOT( contentsMoved( int, int ) ) ); + viewport()->setAcceptDrops( TRUE ); + dragItem = 0; +} + +void QFileListBox::show() +{ + setBackgroundMode( PaletteBase ); + viewport()->setBackgroundMode( PaletteBase ); + QListBox::show(); +} + +void QFileListBox::keyPressEvent( QKeyEvent *e ) +{ + if ( ( e->key() == Key_Enter || + e->key() == Key_Return ) && + renaming ) + return; + + QString keyPressed = ((QKeyEvent *)e)->text().lower(); + QChar keyChar = keyPressed[0]; + if ( keyChar.isLetterOrNumber() ) { + QListBoxItem * i = 0; + if ( currentItem() ) + i = item( currentItem() ); + else + i = firstItem(); + if ( i->next() ) + i = i->next(); + else + i = firstItem(); + while ( i != item( currentItem() ) ) { + QString it = text( index( i ) ); + if ( it[0].lower() == keyChar ) { + clearSelection(); + setCurrentItem( i ); + } else { + if ( i->next() ) + i = i->next(); + else + i = firstItem(); + } + } + } + cancelRename(); + QListBox::keyPressEvent( e ); +} + +void QFileListBox::viewportMousePressEvent( QMouseEvent *e ) +{ + pressPos = e->pos(); + mousePressed = FALSE; + + bool didRename = renaming; + + cancelRename(); + if ( !hasFocus() && !viewport()->hasFocus() ) + setFocus(); + + if ( e->button() != LeftButton ) { + QListBox::viewportMousePressEvent( e ); + firstMousePressEvent = FALSE; + return; + } + + int i = currentItem(); + bool wasSelected = FALSE; + if ( i != -1 ) + wasSelected = item( i )->isSelected(); + QListBox::viewportMousePressEvent( e ); + + QFileDialogPrivate::MCItem *i1 = (QFileDialogPrivate::MCItem*)item( currentItem() ); + if ( i1 ) + mousePressed = !( (QFileDialogPrivate::File*)i1->i )->info.isDir(); + + if ( itemAt( e->pos() ) != item( i ) ) { + firstMousePressEvent = FALSE; + return; + } + + if ( !firstMousePressEvent && !didRename && i == currentItem() && currentItem() != -1 && + wasSelected && filedialog->mode() != QFileDialogP::ExistingFiles && + QUrlInfo( filedialog->d->url, "." ).isWritable() && item( currentItem() )->text() != ".." ) { + renameTimer->start( QApplication::doubleClickInterval(), TRUE ); + renameItem = item( i ); + } + + firstMousePressEvent = FALSE; +} + +void QFileListBox::viewportMouseReleaseEvent( QMouseEvent *e ) +{ + dragItem = 0; + QListBox::viewportMouseReleaseEvent( e ); + mousePressed = FALSE; +} + +void QFileListBox::viewportMouseDoubleClickEvent( QMouseEvent *e ) +{ + renameTimer->stop(); + QListBox::viewportMouseDoubleClickEvent( e ); +} + +void QFileListBox::viewportMouseMoveEvent( QMouseEvent *e ) +{ + if ( !dragItem ) + dragItem = itemAt( e->pos() ); + renameTimer->stop(); +#ifndef QT_NO_DRAGANDDROP + if ( ( pressPos - e->pos() ).manhattanLength() > QApplication::startDragDistance() && mousePressed ) { + QListBoxItem *item = dragItem; + dragItem = 0; + if ( item ) { + if ( !itemRect( item ).contains( e->pos() ) ) + return; + QUriDrag* drag = new QUriDrag( viewport() ); + drag->setUnicodeUris( filedialog->selectedFiles() ); + + if ( lined->parentWidget()->isVisible() ) + cancelRename(); + + connect( drag, SIGNAL( destroyed() ), + this, SLOT( dragObjDestroyed() ) ); + drag->drag(); + + mousePressed = FALSE; + } + } else +#endif + { + QListBox::viewportMouseMoveEvent( e ); + } + +} + +void QFileListBox::dragObjDestroyed() +{ +#ifndef QT_NO_DRAGANDDROP + //####### + //filedialog->rereadDir(); +#endif +} + +#ifndef QT_NO_DRAGANDDROP +void QFileListBox::viewportDragEnterEvent( QDragEnterEvent *e ) +{ + startDragUrl = filedialog->d->url; + startDragDir = filedialog->dirPath(); + currDropItem = 0; + + if ( !QUriDrag::canDecode( e ) ) { + e->ignore(); + return; + } + + QStringList l; + QUriDrag::decodeLocalFiles( e, l ); + urls = (int)l.count(); + + if ( acceptDrop( e->pos(), e->source() ) ) { + e->accept(); + setCurrentDropItem( e->pos() ); + } else { + e->ignore(); + setCurrentDropItem( QPoint( -1, -1 ) ); + } + + oldDragPos = e->pos(); +} + +void QFileListBox::viewportDragMoveEvent( QDragMoveEvent *e ) +{ + if ( acceptDrop( e->pos(), e->source() ) ) { + switch ( e->action() ) { + case QDropEvent::Copy: + e->acceptAction(); + break; + case QDropEvent::Move: + e->acceptAction(); + break; + case QDropEvent::Link: + break; + default: + break; + } + if ( oldDragPos != e->pos() ) + setCurrentDropItem( e->pos() ); + } else { + changeDirTimer->stop(); + e->ignore(); + setCurrentDropItem( QPoint( -1, -1 ) ); + } + + oldDragPos = e->pos(); +} + +void QFileListBox::viewportDragLeaveEvent( QDragLeaveEvent * ) +{ + changeDirTimer->stop(); + setCurrentDropItem( QPoint( -1, -1 ) ); +//######## +// if ( startDragDir != filedialog->d->url ) +// filedialog->setUrl( startDragUrl ); +} + +void QFileListBox::viewportDropEvent( QDropEvent *e ) +{ + changeDirTimer->stop(); + + if ( !QUriDrag::canDecode( e ) ) { + e->ignore(); + return; + } + + QStrList l; + QUriDrag::decode( e, l ); + + bool move = e->action() == QDropEvent::Move; +// bool supportAction = move || e->action() == QDropEvent::Copy; + + QUrlOperator dest; + if ( currDropItem ) + dest = QUrlOperator( filedialog->d->url, QFileDialogPrivate::encodeFileName( currDropItem->text() ) ); + else + dest = filedialog->d->url; + QStringList lst; + for ( uint i = 0; i < l.count(); ++i ) { + lst << l.at( i ); + } + + filedialog->d->url.copy( lst, dest, move ); + + // ##### what is supportAction for? + e->acceptAction(); + currDropItem = 0; +} + +bool QFileListBox::acceptDrop( const QPoint &pnt, QWidget *source ) +{ + QListBoxItem *item = itemAt( pnt ); + if ( !item || item && !itemRect( item ).contains( pnt ) ) { + if ( source == viewport() && startDragDir == filedialog->dirPath() ) + return FALSE; + return TRUE; + } + + QUrlInfo fi( filedialog->d->url, item->text() ); + + if ( fi.isDir() && itemRect( item ).contains( pnt ) ) + return TRUE; + return FALSE; +} + +void QFileListBox::setCurrentDropItem( const QPoint &pnt ) +{ + changeDirTimer->stop(); + + QListBoxItem *item = 0; + if ( pnt != QPoint( -1, -1 ) ) + item = itemAt( pnt ); + if ( item && !QUrlInfo( filedialog->d->url, item->text() ).isDir() ) + item = 0; + if ( item && !itemRect( item ).contains( pnt ) ) + item = 0; + + currDropItem = item; + if ( currDropItem ) + setCurrentItem( currDropItem ); + changeDirTimer->start( 750 ); +} +#endif // QT_NO_DRAGANDDROP + +void QFileListBox::changeDirDuringDrag() +{ +#ifndef QT_NO_DRAGANDDROP + if ( !currDropItem ) + return; + changeDirTimer->stop(); + QUrl u( filedialog->d->url, QFileDialogPrivate::encodeFileName(currDropItem->text()) ); + filedialog->setDir( u ); + currDropItem = 0; +#endif +} + +void QFileListBox::doubleClickTimeout() +{ + startRename(); + renameTimer->stop(); +} + +void QFileListBox::startRename( bool check ) +{ + if ( check && ( !renameItem || renameItem != item( currentItem() ) ) ) + return; + + int i = currentItem(); + setSelected( i, TRUE ); + QRect r = itemRect( item( i ) ); + int bdr = item( i )->pixmap() ? + item( i )->pixmap()->width() : 16; + int x = r.x() + bdr; + int y = r.y(); + int w = item( i )->width( this ) - bdr; + int h = QMAX( lined->height() + 2, r.height() ); + y = y + r.height() / 2 - h / 2; + + lined->parentWidget()->setGeometry( x, y, w + 6, h ); + lined->setFocus(); + lined->setText( item( i )->text() ); + lined->selectAll(); + lined->setFrame( FALSE ); + lined->parentWidget()->show(); + viewport()->setFocusProxy( lined ); + renaming = TRUE; +} + +void QFileListBox::clear() +{ + cancelRename(); + QListBox::clear(); +} + +void QFileListBox::rename() +{ + if ( !lined->text().isEmpty() ) { + QString file = currentText(); + + if ( lined->text() != file ) + filedialog->d->url.rename( file, lined->text() ); + } + cancelRename(); +} + +void QFileListBox::cancelRename() +{ + renameItem = 0; + lined->parentWidget()->hide(); + viewport()->setFocusProxy( this ); + renaming = FALSE; + updateItem( currentItem() ); + if ( lined->hasFocus() ) + viewport()->setFocus(); +} + +void QFileListBox::contentsMoved( int, int ) +{ + changeDirTimer->stop(); +#ifndef QT_NO_DRAGANDDROP + setCurrentDropItem( QPoint( -1, -1 ) ); +#endif +} + +/************************************************************************ + * + * Internal class QFileListView + * + ************************************************************************/ + +QFileDialogQFileListView::QFileDialogQFileListView( QWidget *parent, QFileDialogP *dlg ) + : QListView( parent, "qt_filedlg_listview" ), renaming( FALSE ), renameItem( 0 ), + filedialog( dlg ), mousePressed( FALSE ), + firstMousePressEvent( TRUE ) +{ + changeDirTimer = new QTimer( this ); + QVBox *box = new QVBox( viewport(), "qt_vbox" ); + box->setFrameStyle( QFrame::Box | QFrame::Plain ); + lined = new QRenameEdit( box ); + lined->setFixedHeight( lined->sizeHint().height() ); + box->hide(); + box->setBackgroundMode( PaletteBase ); + renameTimer = new QTimer( this ); + connect( lined, SIGNAL( returnPressed() ), + this, SLOT (rename() ) ); + connect( lined, SIGNAL( escapePressed() ), + this, SLOT( cancelRename() ) ); + header()->setMovingEnabled( FALSE ); + connect( renameTimer, SIGNAL( timeout() ), + this, SLOT( doubleClickTimeout() ) ); + connect( changeDirTimer, SIGNAL( timeout() ), + this, SLOT( changeDirDuringDrag() ) ); + disconnect( header(), SIGNAL( sectionClicked( int ) ), + this, SLOT( changeSortColumn( int ) ) ); + connect( header(), SIGNAL( sectionClicked( int ) ), + this, SLOT( changeSortColumn2( int ) ) ); + connect( this, SIGNAL( contentsMoving( int, int ) ), + this, SLOT( contentsMoved( int, int ) ) ); + + viewport()->setAcceptDrops( TRUE ); + sortcolumn = 0; + ascending = TRUE; + dragItem = 0; +} + +void QFileDialogQFileListView::setSorting( int column, bool increasing ) +{ + if ( column == -1 ) { + QListView::setSorting( column, increasing ); + return; + } + + sortAscending = ascending = increasing; + sortcolumn = column; + switch ( column ) { + case 0: + sortFilesBy = QDir::Name; + break; + case 1: + sortFilesBy = QDir::Size; + break; + case 3: + sortFilesBy = QDir::Time; + break; + default: + sortFilesBy = QDir::Name; // #### ??? + break; + } + + filedialog->resortDir(); +} + +void QFileDialogQFileListView::changeSortColumn2( int column ) +{ + int lcol = header()->mapToLogical( column ); + setSorting( lcol, sortcolumn == lcol ? !ascending : TRUE ); +} + +void QFileDialogQFileListView::keyPressEvent( QKeyEvent *e ) +{ + if ( ( e->key() == Key_Enter || + e->key() == Key_Return ) && + renaming ) + return; + + QString keyPressed = e->text().lower(); + QChar keyChar = keyPressed[0]; + if ( keyChar.isLetterOrNumber() ) { + QListViewItem * i = 0; + if ( currentItem() ) + i = currentItem(); + else + i = firstChild(); + if ( i->nextSibling() ) + i = i->nextSibling(); + else + i = firstChild(); + while ( i != currentItem() ) { + QString it = i->text(0); + if ( it[0].lower() == keyChar ) { + clearSelection(); + ensureItemVisible( i ); + setCurrentItem( i ); + } else { + if ( i->nextSibling() ) + i = i->nextSibling(); + else + i = firstChild(); + } + } + return; + } + + cancelRename(); + QListView::keyPressEvent( e ); +} + +void QFileDialogQFileListView::viewportMousePressEvent( QMouseEvent *e ) +{ + pressPos = e->pos(); + mousePressed = FALSE; + + bool didRename = renaming; + cancelRename(); + if ( !hasFocus() && !viewport()->hasFocus() ) + setFocus(); + + if ( e->button() != LeftButton ) { + QListView::viewportMousePressEvent( e ); + firstMousePressEvent = FALSE; + return; + } + + QListViewItem *i = currentItem(); + QListView::viewportMousePressEvent( e ); + + QFileDialogPrivate::File *i1 = (QFileDialogPrivate::File*)currentItem(); + if ( i1 ) + mousePressed = !i1->info.isDir(); + + if ( itemAt( e->pos() ) != i || + e->x() + contentsX() > columnWidth( 0 ) ) { + firstMousePressEvent = FALSE; + return; + } + + if ( !firstMousePressEvent && !didRename && i == currentItem() && currentItem() && + filedialog->mode() != QFileDialogP::ExistingFiles && + QUrlInfo( filedialog->d->url, "." ).isWritable() && currentItem()->text( 0 ) != ".." ) { + renameTimer->start( QApplication::doubleClickInterval(), TRUE ); + renameItem = currentItem(); + } + + firstMousePressEvent = FALSE; +} + +void QFileDialogQFileListView::viewportMouseDoubleClickEvent( QMouseEvent *e ) +{ + renameTimer->stop(); + QListView::viewportMouseDoubleClickEvent( e ); +} + +void QFileDialogQFileListView::viewportMouseReleaseEvent( QMouseEvent *e ) +{ + QListView::viewportMouseReleaseEvent( e ); + mousePressed = FALSE; + dragItem = 0; +} + +void QFileDialogQFileListView::viewportMouseMoveEvent( QMouseEvent *e ) +{ + renameTimer->stop(); + if ( !dragItem ) + dragItem = itemAt( e->pos() ); +#ifndef QT_NO_DRAGANDDROP + if ( ( pressPos - e->pos() ).manhattanLength() > QApplication::startDragDistance() && mousePressed ) { + QListViewItem *item = dragItem; + dragItem = 0; + if ( item ) { + QUriDrag* drag = new QUriDrag( viewport() ); + drag->setUnicodeUris( filedialog->selectedFiles() ); + + if ( lined->isVisible() ) + cancelRename(); + + connect( drag, SIGNAL( destroyed() ), + this, SLOT( dragObjDestroyed() ) ); + drag->drag(); + + mousePressed = FALSE; + } + } +#endif +} + +void QFileDialogQFileListView::dragObjDestroyed() +{ +#ifndef QT_NO_DRAGANDDROP + //###### + //filedialog->rereadDir(); +#endif +} + +#ifndef QT_NO_DRAGANDDROP +void QFileDialogQFileListView::viewportDragEnterEvent( QDragEnterEvent *e ) +{ + startDragUrl = filedialog->d->url; + startDragDir = filedialog->dirPath(); + currDropItem = 0; + + if ( !QUriDrag::canDecode( e ) ) { + e->ignore(); + return; + } + + QStringList l; + QUriDrag::decodeLocalFiles( e, l ); + urls = (int)l.count(); + + if ( acceptDrop( e->pos(), e->source() ) ) { + e->accept(); + setCurrentDropItem( e->pos() ); + } else { + e->ignore(); + setCurrentDropItem( QPoint( -1, -1 ) ); + } + + oldDragPos = e->pos(); +} + +void QFileDialogQFileListView::viewportDragMoveEvent( QDragMoveEvent *e ) +{ + if ( acceptDrop( e->pos(), e->source() ) ) { + if ( oldDragPos != e->pos() ) + setCurrentDropItem( e->pos() ); + switch ( e->action() ) { + case QDropEvent::Copy: + e->acceptAction(); + break; + case QDropEvent::Move: + e->acceptAction(); + break; + case QDropEvent::Link: + break; + default: + break; + } + } else { + changeDirTimer->stop(); + e->ignore(); + setCurrentDropItem( QPoint( -1, -1 ) ); + } + + oldDragPos = e->pos(); +} + +void QFileDialogQFileListView::viewportDragLeaveEvent( QDragLeaveEvent * ) +{ + changeDirTimer->stop(); + setCurrentDropItem( QPoint( -1, -1 ) ); +//######## +// if ( startDragDir != filedialog->d->url ) +// filedialog->setUrl( startDragUrl ); +} + +void QFileDialogQFileListView::viewportDropEvent( QDropEvent *e ) +{ + changeDirTimer->stop(); + + if ( !QUriDrag::canDecode( e ) ) { + e->ignore(); + return; + } + + QStringList l; + QUriDrag::decodeToUnicodeUris( e, l ); + + bool move = e->action() == QDropEvent::Move; +// bool supportAction = move || e->action() == QDropEvent::Copy; + + QUrlOperator dest; + if ( currDropItem ) + dest = QUrlOperator( filedialog->d->url, QFileDialogPrivate::encodeFileName( currDropItem->text( 0 ) ) ); + else + dest = filedialog->d->url; + filedialog->d->url.copy( l, dest, move ); + + // ##### what is supportAction for? + e->acceptAction(); + currDropItem = 0; +} + +bool QFileDialogQFileListView::acceptDrop( const QPoint &pnt, QWidget *source ) +{ + QListViewItem *item = itemAt( pnt ); + if ( !item || item && !itemRect( item ).contains( pnt ) ) { + if ( source == viewport() && startDragDir == filedialog->dirPath() ) + return FALSE; + return TRUE; + } + + QUrlInfo fi( filedialog->d->url, item->text( 0 ) ); + + if ( fi.isDir() && itemRect( item ).contains( pnt ) ) + return TRUE; + return FALSE; +} + +void QFileDialogQFileListView::setCurrentDropItem( const QPoint &pnt ) +{ + changeDirTimer->stop(); + + QListViewItem *item = itemAt( pnt ); + if ( pnt == QPoint( -1, -1 ) ) + item = 0; + if ( item && !QUrlInfo( filedialog->d->url, item->text( 0 ) ).isDir() ) + item = 0; + + if ( item && !itemRect( item ).contains( pnt ) ) + item = 0; + + currDropItem = item; + + if ( currDropItem ) + setCurrentItem( currDropItem ); + + changeDirTimer->start( 750 ); +} +#endif // QT_NO_DRAGANDDROP + +void QFileDialogQFileListView::changeDirDuringDrag() +{ +#ifndef QT_NO_DRAGANDDROP + if ( !currDropItem ) + return; + changeDirTimer->stop(); + QUrl u( filedialog->d->url, QFileDialogPrivate::encodeFileName(currDropItem->text( 0 ) ) ); + filedialog->setDir( u ); + currDropItem = 0; +#endif // QT_NO_DRAGANDDROP +} + + +void QFileDialogQFileListView::doubleClickTimeout() +{ + startRename(); + renameTimer->stop(); +} + +void QFileDialogQFileListView::startRename( bool check ) +{ + if ( check && ( !renameItem || renameItem != currentItem() ) ) + return; + + QListViewItem *i = currentItem(); + setSelected( i, TRUE ); + + QRect r = itemRect( i ); + int bdr = i->pixmap( 0 ) ? + i->pixmap( 0 )->width() : 16; + int x = r.x() + bdr; + int y = r.y(); + int w = columnWidth( 0 ) - bdr; + int h = QMAX( lined->height() + 2, r.height() ); + y = y + r.height() / 2 - h / 2; + + lined->parentWidget()->setGeometry( x, y, w + 6, h ); + lined->setFocus(); + lined->setText( i->text( 0 ) ); + lined->selectAll(); + lined->setFrame( FALSE ); + lined->parentWidget()->show(); + viewport()->setFocusProxy( lined ); + renaming = TRUE; +} + +void QFileDialogQFileListView::clear() +{ + cancelRename(); + QListView::clear(); +} + +void QFileDialogQFileListView::rename() +{ + if ( !lined->text().isEmpty() ) { + QString file = currentItem()->text( 0 ); + + if ( lined->text() != file ) + filedialog->d->url.rename( file, lined->text() ); + } + cancelRename(); +} + +void QFileDialogQFileListView::cancelRename() +{ + renameItem = 0; + lined->parentWidget()->hide(); + viewport()->setFocusProxy( this ); + renaming = FALSE; + if ( currentItem() ) + currentItem()->repaint(); + if ( lined->hasFocus() ) + viewport()->setFocus(); +} + +void QFileDialogQFileListView::contentsMoved( int, int ) +{ + changeDirTimer->stop(); +#ifndef QT_NO_DRAGANDDROP + setCurrentDropItem( QPoint( -1, -1 ) ); +#endif +} + + +QFileDialogPrivate::File::~File() +{ + if ( d->pendingItems.findRef( this ) ) + d->pendingItems.removeRef( this ); +} + +QString QFileDialogPrivate::File::text( int column ) const +{ + makeVariables(); + + switch( column ) { + case 0: + return info.name(); + case 1: + if ( info.isFile() ) + return QString::number(info.size()); + else + return QString::fromLatin1(""); + case 2: + if ( info.isFile() && info.isSymLink() ) { + return d->symLinkToFile; + } else if ( info.isFile() ) { + return d->file; + } else if ( info.isDir() && info.isSymLink() ) { + return d->symLinkToDir; + } else if ( info.isDir() ) { + return d->dir; + } else if ( info.isSymLink() ) { + return d->symLinkToSpecial; + } else { + return d->special; + } + case 3: { + return info.lastModified().toString( Qt::LocalDate ); + } + case 4: + if ( info.isReadable() ) + return info.isWritable() ? d->rw : d->ro; + else + return info.isWritable() ? d->wo : d->inaccessible; + } + + return QString::fromLatin1("<--->"); +} + +const QPixmap * QFileDialogPrivate::File::pixmap( int column ) const +{ + if ( column ) { + return 0; + } else if ( QListViewItem::pixmap( column ) ) { + return QListViewItem::pixmap( column ); + } else if ( info.isSymLink() ) { + if ( info.isFile() ) + return symLinkFileIcon; + else + return symLinkDirIcon; + } else if ( info.isDir() ) { + return closedFolderIcon; + } else if ( info.isFile() ) { + return fileIcon; + } else { + return fifteenTransparentPixels; + } +} + +QFileDialogPrivate::MCItem::MCItem( QListBox * lb, QListViewItem * item ) + : QListBoxItem() +{ + i = item; + if ( lb ) + lb->insertItem( this ); +} + +QFileDialogPrivate::MCItem::MCItem( QListBox * lb, QListViewItem * item, QListBoxItem *after ) + : QListBoxItem() +{ + i = item; + if ( lb ) + lb->insertItem( this, after ); +} + +QString QFileDialogPrivate::MCItem::text() const +{ + return i->text( 0 ); +} + + +const QPixmap *QFileDialogPrivate::MCItem::pixmap() const +{ + return i->pixmap( 0 ); +} + + +int QFileDialogPrivate::MCItem::height( const QListBox * lb ) const +{ + if ( pixmap() ) + return QMAX( lb->fontMetrics().height(), pixmap()->height()) + 2; + + return lb->fontMetrics().height() + 2; +} + + +int QFileDialogPrivate::MCItem::width( const QListBox * lb ) const +{ + QFontMetrics fm = lb->fontMetrics(); + int w = 2; + if ( pixmap() ) + w += pixmap()->width() + 4; + else + w += 18; + w += fm.width( text() ); + w += -fm.minLeftBearing(); + w += -fm.minRightBearing(); + w += 6; + return w; +} + + +void QFileDialogPrivate::MCItem::paint( QPainter * ptr ) +{ + QFontMetrics fm = ptr->fontMetrics(); + + int h; + + if ( pixmap() ) + h = QMAX( fm.height(), pixmap()->height()) + 2; + else + h = fm.height() + 2; + + const QPixmap * pm = pixmap(); + if ( pm ) + ptr->drawPixmap( 2, 1, *pm ); + + ptr->drawText( pm ? pm->width() + 4 : 22, h - fm.descent() - 2, + text() ); +} + +static QStringList makeFiltersList( const QString &filter ) +{ + if ( filter.isEmpty() ) + return QStringList(); + + int i = filter.find( ";;", 0 ); + QString sep( ";;" ); + if ( i == -1 ) { + if ( filter.find( "\n", 0 ) != -1 ) { + sep = "\n"; + i = filter.find( sep, 0 ); + } + } + + return QStringList::split( sep, filter ); +} + +/*! + \class QFileDialogP qfiledialog.h + \brief The QFileDialogP class provides dialogs that allow users to select files or directories. + \ingroup dialogs + \mainclass + + The QFileDialogP class enables a user to traverse their file system in + order to select one or many files or a directory. + + The easiest way to create a QFileDialogP is to use the static + functions. On Windows, these static functions will call the native + Windows file dialog and on Mac OS X, these static function will call + the native Mac OS X file dialog. + + \code + QString s = QFileDialogP::getOpenFileName( + "/home", + "Images (*.png *.xpm *.jpg)", + this, + "open file dialog" + "Choose a file" ); + \endcode + + In the above example, a modal QFileDialogP is created using a static + function. The startup directory is set to "/home". The file filter + is set to "Images (*.png *.xpm *.jpg)". The parent of the file dialog + is set to \e this and it is given the identification name - "open file + dialog". The caption at the top of file dialog is set to "Choose a + file". + + You can create your own QFileDialogP without using the static + functions. By calling setMode(), you can set what can be returned by + the QFileDialogP. + + \code + QFileDialogP* fd = new QFileDialogP( this, "file dialog", TRUE ); + fd->setMode( QFileDialogP::AnyFile ); + \endcode + + In the above example, the mode of the file dialog is set to \c + AnyFile, meaning that the user can select any file, or even specify a + file that doesn't exist. This mode is useful for creating a "File Save + As" file dialog. Use \c ExistingFile if the user must select an + existing file or \c Directory if only a directory may be selected. + (See the \l QFileDialogP::Mode enum for the complete list of modes.) + + You can retrieve the dialog's mode with mode(). Use setFilter() to set + the dialog's file filter, e.g. + + \code + fd->setFilter( "Images (*.png *.xpm *.jpg)" ); + \endcode + + In the above example, the filter is set to "Images (*.png *.xpm + *.jpg)", this means that only files with the extension \c png, \c xpm + or \c jpg will be shown in the QFileDialogP. You can apply + several filters by using setFilters() and add additional filters with + addFilter(). Use setSelectedFilter() to select one of the filters + you've given as the file dialog's default filter. Whenever the user + changes the filter the filterSelected() signal is emitted. + + The file dialog has two view modes, QFileDialogP::List which simply + lists file and directory names and QFileDialogP::Detail which + displays additional information alongside each name, e.g. file size, + modification date, etc. Set the mode with setViewMode(). + + \code + fd->setViewMode( QFileDialogP::Detail ); + \endcode + + The last important function you will need to use when creating your + own file dialog is selectedFile(). + + \code + QString fileName; + if ( fd->exec() == QDialog::Accepted ) + fileName = fd->selectedFile(); + \endcode + + In the above example, a modal file dialog is created and shown. If + the user clicked OK, then the file they selected is put in \c + fileName. + + If you are using the \c ExistingFiles mode then you will need to use + selectedFiles() which will return the selected files in a QStringList. + + The dialog's working directory can be set with setDir(). The display + of hidden files is controlled with setShowHiddenFiles(). The dialog + can be forced to re-read the directory with rereadDir() and re-sort + the directory with resortDir(). All the files in the current directory + can be selected with selectAll(). + + \section1 Creating and using preview widgets + + There are two kinds of preview widgets that can be used with + QFileDialogPs: \e content preview widgets and \e information preview + widgets. They are created and used in the same way except that the + function names differ, e.g. setContentsPreview() and setInfoPreview(). + + A preview widget is a widget that is placed inside a QFileDialogP so + that the user can see either the contents of the file, or information + about the file. + + \code + class Preview : public QLabel, public QFilePreviewP + { + public: + Preview( QWidget *parent=0 ) : QLabel( parent ) {} + + void previewUrl( const QUrl &u ) + { + QString path = u.path(); + QPixmap pix( path ); + if ( pix.isNull() ) + setText( "This is not a pixmap" ); + else + setPixmap( pix ); + } + }; + \endcode + + In the above snippet, we create a preview widget which inherits from + QLabel and QFilePreviewP. File preview widgets \e must inherit from + QFilePreviewP. + + Inside the class we reimplement QFilePreviewP::previewUrl(), this is + where we determine what happens when a file is selected. In the + above example we only show a preview of the file if it is a valid + pixmap. Here's how to make a file dialog use a preview widget: + + \code + Preview* p = new Preview; + + QFileDialogP* fd = new QFileDialogP( this ); + fd->setContentsPreviewEnabled( TRUE ); + fd->setContentsPreview( p, p ); + fd->setPreviewMode( QFileDialogP::Contents ); + fd->show(); + \endcode + + The first line creates an instance of our preview widget. We then + create our file dialog and call setContentsPreviewEnabled( TRUE ), + this tell the file dialog to preview the contents of the currently + selected file. We then call setContentsPreview() -- note that we pass + the same preview widget twice. Finally, before showing the file + dialog, we call setPreviewMode() setting the mode to \e Contents which + will show the contents preview of the file that the user has selected. + + If you create another preview widget that is used for displaying + information about a file, create it in the same way as the contents + preview widget and call setInfoPreviewEnabled(), and + setInfoPreview(). Then the user will be able to switch between the + two preview modes. + + For more information about creating a QFilePreviewP widget see + \l{QFilePreviewP}. + + + +*/ + + +/*! \enum QFileDialogP::Mode + + This enum is used to indicate what the user may select in the file + dialog, i.e. what the dialog will return if the user clicks OK. + + \value AnyFile The name of a file, whether it exists or not. + \value ExistingFile The name of a single existing file. + \value Directory The name of a directory. Both files and directories + are displayed. + \value DirectoryOnly The name of a directory. The file dialog will only display directories. + \value ExistingFiles The names of zero or more existing files. + + See setMode(). +*/ + +/*! + \enum QFileDialogP::ViewMode + + This enum describes the view mode of the file dialog, i.e. what + information about each file will be displayed. + + \value List Display file and directory names with icons. + \value Detail Display file and directory names with icons plus + additional information, such as file size and modification date. + + See setViewMode(). +*/ + +/*! + \enum QFileDialogP::PreviewMode + + This enum describes the preview mode of the file dialog. + + \value NoPreview No preview is shown at all. + \value Contents Show a preview of the contents of the current file + using the contents preview widget. + \value Info Show information about the current file using the + info preview widget. + + See setPreviewMode(), setContentsPreview() and setInfoPreview(). +*/ + +/*! + \fn void QFileDialogP::detailViewSelectionChanged() + \internal +*/ + +/*! + \fn void QFileDialogP::listBoxSelectionChanged() + \internal +*/ + +extern const char qt_file_dialog_filter_reg_exp[] = + "([a-zA-Z0-9 ]*)\\(([a-zA-Z0-9_.*? +;#\\[\\]]*)\\)$"; + +/*! + Constructs a file dialog called \a name, with the parent, \a parent. + If \a modal is TRUE then the file dialog is modal; otherwise it is + modeless. +*/ + +QFileDialogP::QFileDialogP( QWidget *parent, const char *name, bool modal ) + : QDialog( parent, name, modal, + (modal ? + (WStyle_Customize | WStyle_DialogBorder | WStyle_Title | WStyle_SysMenu) : 0) ) +{ + init(); + d->mode = ExistingFile; + d->types->insertItem( tr( "All Files (*)" ) ); + emit dirEntered( d->url.dirPath() ); + rereadDir(); +} + + +/*! + Constructs a file dialog called \a name with the parent, \a parent. + If \a modal is TRUE then the file dialog is modal; otherwise it is + modeless. + + If \a dirName is specified then it will be used as the dialog's + working directory, i.e. it will be the directory that is shown when + the dialog appears. If \a filter is specified it will be used as the + dialog's file filter. + +*/ + +QFileDialogP::QFileDialogP( const QString& dirName, const QString & filter, + QWidget *parent, const char *name, bool modal ) + : QDialog( parent, name, modal, + (modal ? + (WStyle_Customize | WStyle_DialogBorder | WStyle_Title | WStyle_SysMenu) : 0) ) +{ + init(); + d->mode = ExistingFile; + rereadDir(); + if ( !dirName.isEmpty() ) + setSelection( dirName ); + else if ( workingDirectory && !workingDirectory->isEmpty() ) + setDir( *workingDirectory ); + + if ( !filter.isEmpty() ) { + setFilters( filter ); + if ( !dirName.isEmpty() ) { + int dotpos = dirName.find( QChar('.'), 0, FALSE ); + if ( dotpos != -1 ) { + for ( int b=0 ; btypes->count() ; b++ ) { + if ( d->types->text(b).contains( dirName.right( dirName.length() - dotpos ) ) ) { + d->types->setCurrentItem( b ); + setFilter( d->types->text( b ) ); + return; + } + } + } + } + } else { + d->types->insertItem( tr( "All Files (*)" ) ); + } +} + + +/*! + \internal + Initializes the file dialog. +*/ + +void QFileDialogP::init() +{ + setSizeGripEnabled( TRUE ); + d = new QFileDialogPrivate(); + d->mode = AnyFile; + d->last = 0; + d->moreFiles = 0; + d->infoPreview = FALSE; + d->contentsPreview = FALSE; + d->hadDotDot = FALSE; + d->ignoreNextKeyPress = FALSE; + d->progressDia = 0; + d->checkForFilter = FALSE; + d->ignoreReturn = FALSE; + d->ignoreNextRefresh = FALSE; + d->ignoreStop = FALSE; + d->pendingItems.setAutoDelete( FALSE ); + d->mimeTypeTimer = new QTimer( this ); + connect( d->mimeTypeTimer, SIGNAL( timeout() ), + this, SLOT( doMimeTypeLookup() ) ); + + d->url = QUrlOperator( QDir::currentDirPath() ); + d->oldUrl = d->url; + d->currListChildren = 0; + + connect( &d->url, SIGNAL( start( QNetworkOperation * ) ), + this, SLOT( urlStart( QNetworkOperation * ) ) ); + connect( &d->url, SIGNAL( finished( QNetworkOperation * ) ), + this, SLOT( urlFinished( QNetworkOperation * ) ) ); + connect( &d->url, SIGNAL( newChildren( const QValueList &, QNetworkOperation * ) ), + this, SLOT( insertEntry( const QValueList &, QNetworkOperation * ) ) ); + connect( &d->url, SIGNAL( removed( QNetworkOperation * ) ), + this, SLOT( removeEntry( QNetworkOperation * ) ) ); + connect( &d->url, SIGNAL( createdDirectory( const QUrlInfo &, QNetworkOperation * ) ), + this, SLOT( createdDirectory( const QUrlInfo &, QNetworkOperation * ) ) ); + connect( &d->url, SIGNAL( itemChanged( QNetworkOperation * ) ), + this, SLOT( itemChanged( QNetworkOperation * ) ) ); + connect( &d->url, SIGNAL( dataTransferProgress( int, int, QNetworkOperation * ) ), + this, SLOT( dataTransferProgress( int, int, QNetworkOperation * ) ) ); + + nameEdit = new QLineEdit( this, "name/filter editor" ); + nameEdit->setMaxLength( 255 ); //_POSIX_MAX_PATH + connect( nameEdit, SIGNAL(textChanged(const QString&)), + this, SLOT(fileNameEditDone()) ); + nameEdit->installEventFilter( this ); + + d->splitter = new QSplitter( this, "qt_splitter" ); + + d->stack = new QWidgetStack( d->splitter, "files and more files" ); + + d->splitter->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); + + files = new QFileDialogQFileListView( d->stack, this ); + QFontMetrics fm = fontMetrics(); + files->addColumn( tr("Name") ); + files->addColumn( tr("Size") ); + files->setColumnAlignment( 1, AlignRight ); + files->addColumn( tr("Type") ); + files->addColumn( tr("Date") ); + files->addColumn( tr("Attributes") ); + files->header()->setStretchEnabled( TRUE, 0 ); + + files->setMinimumSize( 50, 25 + 2*fm.lineSpacing() ); + + connect( files, SIGNAL( selectionChanged() ), + this, SLOT( detailViewSelectionChanged() ) ); + connect( files, SIGNAL(currentChanged(QListViewItem *)), + this, SLOT(updateFileNameEdit(QListViewItem *)) ); + connect( files, SIGNAL(doubleClicked(QListViewItem *)), + this, SLOT(selectDirectoryOrFile(QListViewItem *)) ); + connect( files, SIGNAL(returnPressed(QListViewItem *)), + this, SLOT(selectDirectoryOrFile(QListViewItem *)) ); + connect( files, SIGNAL(rightButtonPressed(QListViewItem *, + const QPoint &, int)), + this, SLOT(popupContextMenu(QListViewItem *, + const QPoint &, int)) ); + + files->installEventFilter( this ); + files->viewport()->installEventFilter( this ); + + d->moreFiles = new QFileListBox( d->stack, this ); + d->moreFiles->setRowMode( QListBox::FitToHeight ); + d->moreFiles->setVariableWidth( TRUE ); + + connect( d->moreFiles, SIGNAL(selected(QListBoxItem *)), + this, SLOT(selectDirectoryOrFile(QListBoxItem *)) ); + connect( d->moreFiles, SIGNAL( selectionChanged() ), + this, SLOT( listBoxSelectionChanged() ) ); + connect( d->moreFiles, SIGNAL(highlighted(QListBoxItem *)), + this, SLOT(updateFileNameEdit(QListBoxItem *)) ); + connect( d->moreFiles, SIGNAL( rightButtonPressed( QListBoxItem *, const QPoint & ) ), + this, SLOT( popupContextMenu( QListBoxItem *, const QPoint & ) ) ); + + d->moreFiles->installEventFilter( this ); + d->moreFiles->viewport()->installEventFilter( this ); + + okB = new QPushButton( tr("OK"), this, "OK" ); //### Or "Save (see other "OK") + okB->setDefault( TRUE ); + okB->setEnabled( FALSE ); + connect( okB, SIGNAL(clicked()), this, SLOT(okClicked()) ); + cancelB = new QPushButton( tr("Cancel") , this, "Cancel" ); + connect( cancelB, SIGNAL(clicked()), this, SLOT(cancelClicked()) ); + + d->paths = new QComboBox( TRUE, this, "directory history/editor" ); + d->paths->setDuplicatesEnabled( FALSE ); + d->paths->setInsertionPolicy( QComboBox::NoInsertion ); + const QFileInfoList * rootDrives = QDir::drives(); + QFileInfoListIterator it( *rootDrives ); + QFileInfo *fi; + makeVariables(); + + while ( (fi = it.current()) != 0 ) { + ++it; + d->paths->insertItem( *openFolderIcon, fi->absFilePath() ); + } + + if ( !!QDir::homeDirPath() ) { + if ( !d->paths->listBox()->findItem( QDir::homeDirPath() ) ) + d->paths->insertItem( *openFolderIcon, QDir::homeDirPath() ); + } + + connect( d->paths, SIGNAL(activated(const QString&)), + this, SLOT(setDir(const QString&)) ); + + d->paths->installEventFilter( this ); + QObjectList *ol = d->paths->queryList( "QLineEdit" ); + if ( ol && ol->first() ) + ( (QLineEdit*)ol->first() )->installEventFilter( this ); + delete ol; + + d->geometryDirty = TRUE; + d->types = new QComboBox( TRUE, this, "file types" ); + d->types->setDuplicatesEnabled( FALSE ); + d->types->setEditable( FALSE ); + connect( d->types, SIGNAL(activated(const QString&)), + this, SLOT(setFilter(const QString&)) ); + connect( d->types, SIGNAL(activated(const QString&)), + this, SIGNAL(filterSelected(const QString&)) ); + + d->pathL = new QLabel( d->paths, tr("Look &in:"), this, "qt_looin_lbl" ); + d->fileL = new QLabel( nameEdit, tr("File &name:"), this, "qt_filename_lbl" ); + d->typeL = new QLabel( d->types, tr("File &type:"), this, "qt_filetype_lbl" ); + +#if defined(Q_WS_WIN) + if ( qt_winver == Qt::WV_2000 || qt_winver == Qt::WV_XP ) { + d->goBack = new QToolButton( this, "go back" ); + d->goBack->setAutoRaise( TRUE ); + d->goBack->setEnabled( FALSE ); + d->goBack->setFocusPolicy( TabFocus ); + connect( d->goBack, SIGNAL( clicked() ), + this, SLOT( goBack() ) ); + QToolTip::add( d->goBack, tr( "Back" ) ); + d->goBack->setIconSet( *goBackIcon ); + } else { + d->goBack = 0; + } +#else + d->goBack = 0; +#endif + + d->cdToParent = new QToolButton( this, "cd to parent" ); +#if defined(Q_WS_WIN) + if ( qt_winver == Qt::WV_2000 || qt_winver == Qt::WV_XP ) + d->cdToParent->setAutoRaise( TRUE ); +#endif + d->cdToParent->setFocusPolicy( TabFocus ); +#ifndef QT_NO_TOOLTIP + QToolTip::add( d->cdToParent, tr( "One directory up" ) ); +#endif + d->cdToParent->setIconSet( *cdToParentIcon ); + connect( d->cdToParent, SIGNAL(clicked()), + this, SLOT(cdUpClicked()) ); + + d->newFolder = new QToolButton( this, "new folder" ); +#if defined(Q_WS_WIN) + if ( qt_winver == Qt::WV_2000 || qt_winver == Qt::WV_XP ) + d->newFolder->setAutoRaise( TRUE ); +#endif + d->newFolder->setFocusPolicy( TabFocus ); +#ifndef QT_NO_TOOLTIP + QToolTip::add( d->newFolder, tr( "Create New Folder" ) ); +#endif + d->newFolder->setIconSet( *newFolderIcon ); + connect( d->newFolder, SIGNAL(clicked()), + this, SLOT(newFolderClicked()) ); + + d->modeButtons = new QButtonGroup( 0, "invisible group" ); + connect( d->modeButtons, SIGNAL(destroyed()), + this, SLOT(modeButtonsDestroyed()) ); + d->modeButtons->setExclusive( TRUE ); + connect( d->modeButtons, SIGNAL(clicked(int)), + d->stack, SLOT(raiseWidget(int)) ); + connect( d->modeButtons, SIGNAL(clicked(int)), + this, SLOT(changeMode(int)) ); + + d->mcView = new QToolButton( this, "mclistbox view" ); +#if defined(Q_WS_WIN) + if ( qt_winver == Qt::WV_2000 || qt_winver == Qt::WV_XP ) + d->mcView->setAutoRaise( TRUE ); +#endif + d->mcView->setFocusPolicy( TabFocus ); +#ifndef QT_NO_TOOLTIP + QToolTip::add( d->mcView, tr( "List View" ) ); +#endif + d->mcView->setIconSet( *multiColumnListViewIcon ); + d->mcView->setToggleButton( TRUE ); + d->stack->addWidget( d->moreFiles, d->modeButtons->insert( d->mcView ) ); + d->detailView = new QToolButton( this, "list view" ); +#if defined(Q_WS_WIN) + if ( qt_winver == Qt::WV_2000 || qt_winver == Qt::WV_XP ) + d->detailView->setAutoRaise( TRUE ); +#endif + d->detailView->setFocusPolicy( TabFocus ); +#ifndef QT_NO_TOOLTIP + QToolTip::add( d->detailView, tr( "Detail View" ) ); +#endif + d->detailView->setIconSet( *detailViewIcon ); + d->detailView->setToggleButton( TRUE ); + d->stack->addWidget( files, d->modeButtons->insert( d->detailView ) ); + + d->previewInfo = new QToolButton( this, "preview info view" ); +#if defined(Q_WS_WIN) + if ( qt_winver == Qt::WV_2000 || qt_winver == Qt::WV_XP ) + d->previewInfo->setAutoRaise( TRUE ); +#endif + d->previewInfo->setFocusPolicy( TabFocus ); +#ifndef QT_NO_TOOLTIP + QToolTip::add( d->previewInfo, tr( "Preview File Info" ) ); +#endif + d->previewInfo->setIconSet( *previewInfoViewIcon ); + d->previewInfo->setToggleButton( TRUE ); + d->modeButtons->insert( d->previewInfo ); + + d->previewContents = new QToolButton( this, "preview info view" ); +#if defined(Q_WS_WIN) + if ( qt_winver == Qt::WV_2000 || qt_winver == Qt::WV_XP ) + d->previewContents->setAutoRaise( TRUE ); +#endif + d->previewContents->setFocusPolicy( TabFocus ); +#ifndef QT_NO_TOOLTIP + QToolTip::add( d->previewContents, tr( "Preview File Contents" ) ); +#endif + d->previewContents->setIconSet( *previewContentsViewIcon ); + d->previewContents->setToggleButton( TRUE ); + d->modeButtons->insert( d->previewContents ); + + connect( d->detailView, SIGNAL( clicked() ), + d->moreFiles, SLOT( cancelRename() ) ); + connect( d->detailView, SIGNAL( clicked() ), + files, SLOT( cancelRename() ) ); + connect( d->mcView, SIGNAL( clicked() ), + d->moreFiles, SLOT( cancelRename() ) ); + connect( d->mcView, SIGNAL( clicked() ), + files, SLOT( cancelRename() ) ); + + d->stack->raiseWidget( d->moreFiles ); + d->mcView->setOn( TRUE ); + + QHBoxLayout *lay = new QHBoxLayout( this ); + lay->setMargin( 6 ); + d->leftLayout = new QHBoxLayout( lay, 5 ); + d->topLevelLayout = new QVBoxLayout( (QWidget*)0, 5 ); + lay->addLayout( d->topLevelLayout, 1 ); + d->extraWidgetsLayouts.setAutoDelete( FALSE ); + d->extraLabels.setAutoDelete( FALSE ); + d->extraWidgets.setAutoDelete( FALSE ); + d->extraButtons.setAutoDelete( FALSE ); + d->toolButtons.setAutoDelete( FALSE ); + + QHBoxLayout * h; + + d->preview = new QWidgetStack( d->splitter, "qt_preview" ); + + d->infoPreviewWidget = new QWidget( d->preview, "qt_preview_info" ); + d->contentsPreviewWidget = new QWidget( d->preview, "qt_preview_contents" ); + d->infoPreviewer = d->contentsPreviewer = 0; + + h = new QHBoxLayout( 0 ); + d->buttonLayout = h; + d->topLevelLayout->addLayout( h ); + h->addWidget( d->pathL ); + h->addSpacing( 8 ); + h->addWidget( d->paths ); + h->addSpacing( 8 ); + if ( d->goBack ) + h->addWidget( d->goBack ); + h->addWidget( d->cdToParent ); + h->addSpacing( 2 ); + h->addWidget( d->newFolder ); + h->addSpacing( 4 ); + h->addWidget( d->mcView ); + h->addWidget( d->detailView ); + h->addWidget( d->previewInfo ); + h->addWidget( d->previewContents ); + + d->topLevelLayout->addWidget( d->splitter ); + + h = new QHBoxLayout(); + d->topLevelLayout->addLayout( h ); + h->addWidget( d->fileL ); + h->addWidget( nameEdit ); + h->addSpacing( 15 ); + h->addWidget( okB ); + + h = new QHBoxLayout(); + d->topLevelLayout->addLayout( h ); + h->addWidget( d->typeL ); + h->addWidget( d->types ); + h->addSpacing( 15 ); + h->addWidget( cancelB ); + + d->rightLayout = new QHBoxLayout( lay, 5 ); + d->topLevelLayout->setStretchFactor( d->mcView, 1 ); + d->topLevelLayout->setStretchFactor( files, 1 ); + + updateGeometries(); + + if ( d->goBack ) { + setTabOrder( d->paths, d->goBack ); + setTabOrder( d->goBack, d->cdToParent ); + } else { + setTabOrder( d->paths, d->cdToParent ); + } + setTabOrder( d->cdToParent, d->newFolder ); + setTabOrder( d->newFolder, d->mcView ); + setTabOrder( d->mcView, d->detailView ); + setTabOrder( d->detailView, d->moreFiles ); + setTabOrder( d->moreFiles, files ); + setTabOrder( files, nameEdit ); + setTabOrder( nameEdit, d->types ); + setTabOrder( d->types, okB ); + setTabOrder( okB, cancelB ); + + d->rw = tr( "Read-write" ); + d->ro = tr( "Read-only" ); + d->wo = tr( "Write-only" ); + d->inaccessible = tr( "Inaccessible" ); + + d->symLinkToFile = tr( "Symlink to File" ); + d->symLinkToDir = tr( "Symlink to Directory" ); + d->symLinkToSpecial = tr( "Symlink to Special" ); + d->file = tr( "File" ); + d->dir = tr( "Dir" ); + d->special = tr( "Special" ); + + if ( !lastSize ) { + QRect screen = QApplication::desktop()->screenGeometry( QApplication::desktop()->screenNumber( pos() ) ); + if ( screen.width() < 1024 || + screen.height() < 768 ) { + resize( QMIN(screen.width(),420), + QMIN(screen.height(),236) ); + } else { + QSize s( files->sizeHint() ); + s = QSize( s.width() + 300, s.height() + 82 ); + + if ( s.width() * 3 > screen.width() * 2 ) + s.setWidth( screen.width() * 2 / 3 ); + + if ( s.height() * 3 > screen.height() * 2 ) + s.setHeight( screen.height() * 2 / 3 ); + else if ( s.height() * 3 < screen.height() ) + s.setHeight( screen.height() / 3 ); + + resize( s ); + } + lastSize = new QSize; + qfd_cleanup_size.add( &lastSize ); + *lastSize = size(); + } else + resize( *lastSize ); + + if ( detailViewMode ) { + d->stack->raiseWidget( files ); + d->mcView->setOn( FALSE ); + d->detailView->setOn( TRUE ); + } + + d->preview->hide(); + nameEdit->setFocus(); + + connect( nameEdit, SIGNAL( returnPressed() ), + this, SLOT( fileNameEditReturnPressed() ) ); +} + +/*! + \internal +*/ + +void QFileDialogP::fileNameEditReturnPressed() +{ + d->oldUrl = d->url; + if ( !isDirectoryMode( d->mode ) ) { + okClicked(); + } else { + d->currentFileName = QString::null; + if ( nameEdit->text().isEmpty() ) { + emit fileSelected( selectedFile() ); + accept(); + } else { + QUrlInfo f; + QFileDialogPrivate::File * c + = (QFileDialogPrivate::File *)files->currentItem(); + if ( c && files->isSelected(c) ) + f = c->info; + else + f = QUrlInfo( d->url, nameEdit->text() ); + if ( f.isDir() ) { + setUrl( QUrlOperator( d->url, QFileDialogPrivate::encodeFileName(nameEdit->text() + "/" ) ) ); + d->checkForFilter = TRUE; + trySetSelection( TRUE, d->url, TRUE ); + d->checkForFilter = FALSE; + } + } + nameEdit->setText( QString::null ); + d->ignoreReturn = TRUE; + } +} + +/*! + \internal + Changes the preview mode to the mode specified at \a id. +*/ + +void QFileDialogP::changeMode( int id ) +{ + if ( !d->infoPreview && !d->contentsPreview ) + return; + + QButton *btn = (QButton*)d->modeButtons->find( id ); + if ( !btn ) + return; + + if ( btn == d->previewContents && !d->contentsPreview ) + return; + if ( btn == d->previewInfo && !d->infoPreview ) + return; + + if ( btn != d->previewContents && btn != d->previewInfo ) { + d->preview->hide(); + } else { + if ( files->currentItem() ) { + if ( d->infoPreviewer ) + d->infoPreviewer->previewUrl( QUrl( d->url, files->currentItem()->text( 0 ) ) ); + if ( d->contentsPreviewer ) + d->contentsPreviewer->previewUrl( QUrl( d->url, files->currentItem()->text( 0 ) ) ); + } + if ( btn == d->previewInfo ) + d->preview->raiseWidget( d->infoPreviewWidget ); + else + d->preview->raiseWidget( d->contentsPreviewWidget ); + d->preview->show(); + } +} + +/*! + Destroys the file dialog. +*/ + +QFileDialogP::~QFileDialogP() +{ + // since clear might call setContentsPos which would emit + // a signal and thus cause a recompute of sizes... + files->blockSignals( TRUE ); + d->moreFiles->blockSignals( TRUE ); + files->clear(); + d->moreFiles->clear(); + d->moreFiles->blockSignals( FALSE ); + files->blockSignals( FALSE ); + if ( QApplication::overrideCursor() ) + QApplication::restoreOverrideCursor(); + delete d; + d = 0; +} + + +/*! + \property QFileDialogP::selectedFile + + \brief the name of the selected file + + If a file was selected selectedFile contains the file's name including + its absolute path; otherwise selectedFile is empty. + + \sa QString::isEmpty(), selectedFiles, selectedFilter +*/ + +QString QFileDialogP::selectedFile() const +{ + QString s = d->currentFileName; + // remove the protocol because we do not want to encode it... + QString prot = QUrl( s ).protocol(); + if ( !prot.isEmpty() ) { + prot += ":"; + s.remove( 0, prot.length() ); + } + QUrl u( prot + QFileDialogPrivate::encodeFileName( s ) ); + if ( u.isLocalFile() ) { + QString s = u.toString(); + if ( s.left( 5 ) == "file:" ) + s.remove( 0, 5 ); + return s; + } + return d->currentFileName; +} + +/*! + \property QFileDialogP::selectedFilter + + \brief the filter which the user has selected in the file dialog + + \sa filterSelected(), selectedFiles, selectedFile +*/ + +QString QFileDialogP::selectedFilter() const +{ + return d->types->currentText(); +} + +/*! \overload + + Sets the current filter selected in the file dialog to the + \a{n}-th filter in the filter list. + + \sa filterSelected(), selectedFilter(), selectedFiles(), selectedFile() +*/ + +void QFileDialogP::setSelectedFilter( int n ) +{ + d->types->setCurrentItem( n ); + QString f = d->types->currentText(); + QRegExp r( QString::fromLatin1(qt_file_dialog_filter_reg_exp) ); + int index = r.search( f ); + if ( index >= 0 ) + f = r.cap( 2 ); + d->url.setNameFilter( f ); + rereadDir(); +} + +/*! + Sets the current filter selected in the file dialog to the first + one that contains the text \a mask. +*/ + +void QFileDialogP::setSelectedFilter( const QString& mask ) +{ + int n; + + for ( n = 0; n < d->types->count(); n++ ) { + if ( d->types->text( n ).contains( mask, FALSE ) ) { + d->types->setCurrentItem( n ); + QString f = mask; + QRegExp r( QString::fromLatin1(qt_file_dialog_filter_reg_exp) ); + int index = r.search( f ); + if ( index >= 0 ) + f = r.cap( 2 ); + d->url.setNameFilter( f ); + rereadDir(); + return; + } + } +} + +/*! + \property QFileDialogP::selectedFiles + + \brief the list of selected files + + If one or more files are selected, selectedFiles contains their + names including their absolute paths. If no files are selected or + the mode isn't ExistingFiles selectedFiles is an empty list. + + It is more convenient to use selectedFile() if the mode is + \c ExistingFile, \c Directory or \c DirectoryOnly. + + Note that if you want to iterate over the list, you should + iterate over a copy, e.g. + \code + QStringList list = myFileDialog.selectedFiles(); + QStringList::Iterator it = list.begin(); + while( it != list.end() ) { + myProcessing( *it ); + ++it; + } + \endcode + + \sa selectedFile, selectedFilter, QValueList::empty() +*/ + +QStringList QFileDialogP::selectedFiles() const +{ + QStringList lst; + + if ( mode() == ExistingFiles ) { + QStringList selectedLst; + QString selectedFiles = nameEdit->text(); + selectedFiles.truncate( selectedFiles.findRev( '\"' ) ); + selectedLst = selectedLst.split( QString("\" "), selectedFiles ); + for ( QStringList::Iterator it = selectedLst.begin(); it != selectedLst.end(); ++it ) { + QUrl u; + if ( (*it)[0] == '\"' ) { + u = QUrl( d->url, QFileDialogPrivate::encodeFileName( (*it).mid(1) ) ); + } else { + u = QUrl( d->url, QFileDialogPrivate::encodeFileName( (*it) ) ); + } + if ( u.isLocalFile() ) { + QString s = u.toString(); + if ( s.left( 5 ) == "file:" ) + s.remove( 0, 5 ); + lst << s; + } else { + lst << u.toString(); + } + } + } + + return lst; +} + +/*! + Sets the default selection to \a filename. If \a filename is + absolute, setDir() is also called to set the file dialog's working + directory to the filename's directory. + + \omit + Only for external use. Not useful inside QFileDialogP. + \endomit +*/ + +void QFileDialogP::setSelection( const QString & filename ) +{ + d->oldUrl = d->url; + QString nf = d->url.nameFilter(); + if ( QUrl::isRelativeUrl( filename ) ) + d->url = QUrlOperator( d->url, QFileDialogPrivate::encodeFileName( filename ) ); + else + d->url = QUrlOperator( filename ); + d->url.setNameFilter( nf ); + d->checkForFilter = TRUE; + bool isDirOk; + bool isDir = d->url.isDir( &isDirOk ); + if ( !isDirOk ) + isDir = d->url.path().right( 1 ) == "/"; + if ( !isDir ) { + QUrlOperator u( d->url ); + d->url.setPath( d->url.dirPath() ); + trySetSelection( FALSE, u, TRUE ); + d->ignoreNextRefresh = TRUE; + nameEdit->selectAll(); + rereadDir(); + emit dirEntered( d->url.dirPath() ); + } else { + if ( !d->url.path().isEmpty() && + d->url.path().right( 1 ) != "/" ) { + QString p = d->url.path(); + p += "/"; + d->url.setPath( p ); + } + trySetSelection( TRUE, d->url, FALSE ); + rereadDir(); + emit dirEntered( d->url.dirPath() ); + nameEdit->setText( QString::fromLatin1("") ); + } + d->checkForFilter = FALSE; +} + +/*! + \property QFileDialogP::dirPath + + \brief the file dialog's working directory + + \sa dir(), setDir() +*/ + +QString QFileDialogP::dirPath() const +{ + return d->url.dirPath(); +} + + +/*! + + Sets the filter used in the file dialog to \a newFilter. + + If \a newFilter contains a pair of parentheses containing one or more + of anything*something separated by spaces or by + semi-colons then only the text contained in the parentheses is used as + the filter. This means that these calls are all equivalent: + + \code + fd->setFilter( "All C++ files (*.cpp *.cc *.C *.cxx *.c++)" ); + fd->setFilter( "*.cpp *.cc *.C *.cxx *.c++" ); + fd->setFilter( "All C++ files (*.cpp;*.cc;*.C;*.cxx;*.c++)" ); + fd->setFilter( "*.cpp;*.cc;*.C;*.cxx;*.c++" ); + \endcode + + \sa setFilters() +*/ + +void QFileDialogP::setFilter( const QString & newFilter ) +{ + if ( newFilter.isEmpty() ) + return; + QString f = newFilter; + QRegExp r( QString::fromLatin1(qt_file_dialog_filter_reg_exp) ); + int index = r.search( f ); + if ( index >= 0 ) + f = r.cap( 2 ); + d->url.setNameFilter( f ); + if ( d->types->count() == 1 ) { + d->types->clear(); + d->types->insertItem( newFilter ); + } else { + for ( int i = 0; i < d->types->count(); ++i ) { + if ( d->types->text( i ).left( newFilter.length() ) == newFilter ) { + d->types->setCurrentItem( i ); + break; + } + } + } + rereadDir(); +} + + +/*! \overload + Sets the file dialog's working directory to \a pathstr. + + \sa dir() +*/ + +void QFileDialogP::setDir( const QString & pathstr ) +{ + QString dr = pathstr; + if ( dr.isEmpty() ) + return; + +#if defined(Q_OS_UNIX) + if ( dr.length() && dr[0] == '~' ) { + struct passwd *pw; + int i; + + i = 0; + while( i < (int)dr.length() && dr[i] != '/' ) + i++; + QCString user; + if ( i == 1 ) { + user = ::getlogin(); + if ( !user ) + user = getenv( "LOGNAME" ); + } else + user = dr.mid( 1, i-1 ).local8Bit(); + dr = dr.mid( i, dr.length() ); + pw = ::getpwnam( user ); + if ( pw ) + dr.prepend( QString::fromLocal8Bit(pw->pw_dir) ); + } +#endif + + setUrl( dr ); +} + +/*! + Returns the current directory shown in the file dialog. + + The ownership of the QDir pointer is transferred to the caller, so + it must be deleted by the caller when no longer required. + + \sa setDir() +*/ + +const QDir *QFileDialogP::dir() const +{ + if ( d->url.isLocalFile() ) + return new QDir( d->url.path() ); + else + return 0; +} + +/*! + Sets the file dialog's working directory to \a dir. + \sa dir() +*/ + +void QFileDialogP::setDir( const QDir &dir ) +{ + d->oldUrl = d->url; + QString nf( d->url.nameFilter() ); + d->url = dir.canonicalPath(); + d->url.setNameFilter( nf ); + QUrlInfo i( d->url, nameEdit->text() ); + d->checkForFilter = TRUE; + trySetSelection( i.isDir(), QUrlOperator( d->url, QFileDialogPrivate::encodeFileName(nameEdit->text() ) ), FALSE ); + d->checkForFilter = FALSE; + rereadDir(); + emit dirEntered( d->url.path() ); +} + +/*! + Sets the file dialog's working directory to the directory specified at \a url. + + \sa url() +*/ + +void QFileDialogP::setUrl( const QUrlOperator &url ) +{ + QString nf = d->url.nameFilter(); + + d->url = QUrl( d->url, url.toString( FALSE, FALSE ) ); + d->url.setNameFilter( nf ); + + d->checkForFilter = TRUE; + if ( !d->url.isDir() ) { + QUrlOperator u = d->url; + d->url.setPath( d->url.dirPath() ); + trySetSelection( FALSE, u, FALSE ); + rereadDir(); + emit dirEntered( d->url.dirPath() ); + QString fn = u.fileName(); + nameEdit->setText( fn ); + } else { + trySetSelection( TRUE, d->url, FALSE ); + rereadDir(); + emit dirEntered( d->url.dirPath() ); + } + d->checkForFilter = FALSE; +} + +/*! + \property QFileDialogP::showHiddenFiles + + \brief whether hidden files are shown in the file dialog + + The default is FALSE, i.e. don't show hidden files. +*/ + +void QFileDialogP::setShowHiddenFiles( bool s ) +{ + if ( s == bShowHiddenFiles ) + return; + + bShowHiddenFiles = s; + rereadDir(); +} + +bool QFileDialogP::showHiddenFiles() const +{ + return bShowHiddenFiles; +} + +/*! + Rereads the current directory shown in the file dialog. + + The only time you will need to call this function is if the contents of + the directory change and you wish to refresh the file dialog to reflect + the change. + + \sa resortDir() +*/ + +void QFileDialogP::rereadDir() +{ + if ( !QApplication::overrideCursor() ) + QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) ); + d->pendingItems.clear(); + if ( d->mimeTypeTimer->isActive() ) + d->mimeTypeTimer->stop(); + d->currListChildren = d->url.listChildren(); +} + + +/*! + \fn void QFileDialogP::fileHighlighted( const QString& ) + + This signal is emitted when the user highlights a file. + + \sa fileSelected(), filesSelected() +*/ + +/*! + \fn void QFileDialogP::fileSelected( const QString& ) + + This signal is emitted when the user selects a file. + + \sa filesSelected(), fileHighlighted(), selectedFile() +*/ + +/*! + \fn void QFileDialogP::filesSelected( const QStringList& ) + + This signal is emitted when the user selects one or more files in \e + ExistingFiles mode. + + \sa fileSelected(), fileHighlighted(), selectedFiles() +*/ + +/*! + \fn void QFileDialogP::dirEntered( const QString& ) + + This signal is emitted when the user enters a directory. + + \sa dir() +*/ + +/*! + \fn void QFileDialogP::filterSelected( const QString& ) + + This signal is emitted when the user selects a filter. + + \sa selectedFilter() +*/ + +extern bool qt_resolve_symlinks; // defined in qapplication.cpp + +/*! + This is a convenience static function that returns an existing file + selected by the user. If the user pressed Cancel, it returns a null + string. + + \code + QString s = QFileDialogP::getOpenFileName( + "/home", + "Images (*.png *.xpm *.jpg)", + this, + "open file dialog", + "Choose a file to open" ); + \endcode + + The function creates a modal file dialog called \a name, with + parent, \a parent. If a parent is not 0, the dialog will be shown + centered over the parent. + + The file dialog's working directory will be set to \a startWith. If \a + startWith includes a file name, the file will be selected. The filter + is set to \a filter so that only those files which match the filter + are shown. The filter selected is set to \a selectedFilter. The parameters + \a startWith, \a selectedFilter and \a filter may be QString::null. + + The dialog's caption is set to \a caption. If \a caption is not + specified then a default caption will be used. + + Under Windows and Mac OS X, this static function will use the native + file dialog and not a QFileDialogP, unless the style of the application + is set to something other than the native style. + + Under Unix/X11, the normal behavior of the file dialog is to resolve + and follow symlinks. For example, if /usr/tmp is a symlink to /var/tmp, + the file dialog will change to /var/tmp after entering /usr/tmp. + If \a resolveSymlinks is FALSE, the file dialog will treat + symlinks as regular directories. + + \sa getOpenFileNames(), getSaveFileName(), getExistingDirectory() +*/ + +QString QFileDialogP::getOpenFileName( const QString & startWith, + const QString& filter, + QWidget *parent, const char* name, + const QString& caption, + QString *selectedFilter, + bool resolveSymlinks ) +{ + bool save_qt_resolve_symlinks = qt_resolve_symlinks; + qt_resolve_symlinks = resolveSymlinks; + + QStringList filters; + if ( !filter.isEmpty() ) + filters = makeFiltersList( filter ); + + makeVariables(); + QString initialSelection; + //### Problem with the logic here: If a startWith is given and a file + // with that name exists in D->URL, the box will be opened at D->URL instead of + // the last directory used ('workingDirectory'). + // + // hm... isn't that problem exactly the documented behaviour? the + // documented behaviour sounds meaningful. + if ( !startWith.isEmpty() ) { + QUrlOperator u( startWith ); + if ( u.isLocalFile() && QFileInfo( u.path() ).isDir() ) { + *workingDirectory = startWith; + } else { + if ( u.isLocalFile() ) { + QFileInfo fi( u.dirPath() ); + if ( fi.exists() ) { + *workingDirectory = u.dirPath(); + initialSelection = u.fileName(); + } + } else { + *workingDirectory = u.toString(); + initialSelection = QString::null;//u.fileName(); + } + } + } + + if ( workingDirectory->isNull() ) + *workingDirectory = QDir::currentDirPath(); + +#if defined(Q_WS_WIN) + if ( qApp->style().styleHint( QStyle::SH_GUIStyle ) == WindowsStyle ) + return winGetOpenFileName( initialSelection, filter, workingDirectory, + parent, name, caption, selectedFilter ); +#elif defined(Q_WS_MAC) + if( ( qApp->style().inherits(QMAC_DEFAULT_STYLE) ) ) { + QString f = macGetOpenFileNames(filter, workingDirectory, + parent, name, caption, FALSE).first(); + return f; + } +#endif + + QFileDialogP *dlg = new QFileDialogP( *workingDirectory, QString::null, parent, name ? name : "qt_filedlg_gofn", TRUE ); + +#ifndef QT_NO_WIDGET_TOPEXTRA + if ( parent && parent->icon() && !parent->icon()->isNull() ) + dlg->setIcon( *parent->icon() ); + else if ( qApp->mainWidget() && qApp->mainWidget()->icon() && !qApp->mainWidget()->icon()->isNull() ) + dlg->setIcon( *qApp->mainWidget()->icon() ); + + if ( !caption.isNull() ) + dlg->setCaption( caption ); + else + dlg->setCaption( QFileDialogP::tr( "Open" ) ); +#endif + + dlg->setFilters( filters ); + if ( selectedFilter ) + dlg->setFilter( *selectedFilter ); + dlg->setMode( QFileDialogP::ExistingFile ); + QString result; + if ( !initialSelection.isEmpty() ) + dlg->setSelection( initialSelection ); + if ( dlg->exec() == QDialog::Accepted ) { + result = dlg->selectedFile(); + *workingDirectory = dlg->d->url; + if ( selectedFilter ) + *selectedFilter = dlg->selectedFilter(); + } + delete dlg; + + qt_resolve_symlinks = save_qt_resolve_symlinks; + + return result; +} + +/*! + This is a convenience static function that will return a file name + selected by the user. The file does not have to exist. + + It creates a modal file dialog called \a name, with parent, \a parent. + If a parent is not 0, the dialog will be shown centered over the + parent. + + \code + QString s = QFileDialogP::getSaveFileName( + "/home", + "Images (*.png *.xpm *.jpg)", + this, + "save file dialog" + "Choose a filename to save under" ); + \endcode + + The file dialog's working directory will be set to \a startWith. If \a + startWith includes a file name, the file will be selected. The filter + is set to \a filter so that only those files which match the filter + are shown. The filter selected is set to \a selectedFilter. The parameters + \a startWith, \a selectedFilter and \a filter may be QString::null. + + The dialog's caption is set to \a caption. If \a caption is not + specified then a default caption will be used. + + Under Windows and Mac OS X, this static function will use the native + file dialog and not a QFileDialogP, unless the style of the application + is set to something other than the native style. + + Under Unix/X11, the normal behavior of the file dialog is to resolve + and follow symlinks. For example, if /usr/tmp is a symlink to /var/tmp, + the file dialog will change to /var/tmp after entering /usr/tmp. + If \a resolveSymlinks is FALSE, the file dialog will treat + symlinks as regular directories. + + \sa getOpenFileName(), getOpenFileNames(), getExistingDirectory() +*/ + +QString QFileDialogP::getSaveFileName( const QString & startWith, + const QString& filter, + QWidget *parent, const char* name, + const QString& caption, + QString *selectedFilter, + bool resolveSymlinks) +{ + bool save_qt_resolve_symlinks = qt_resolve_symlinks; + qt_resolve_symlinks = resolveSymlinks; + + QStringList filters; + if ( !filter.isEmpty() ) + filters = makeFiltersList( filter ); + + makeVariables(); + QString initialSelection; + if ( !startWith.isEmpty() ) { + QUrlOperator u( startWith ); + if ( u.isLocalFile() && QFileInfo( u.path() ).isDir() ) { + *workingDirectory = startWith; + } else { + if ( u.isLocalFile() ) { + QFileInfo fi( u.dirPath() ); + if ( fi.exists() ) { + *workingDirectory = u.dirPath(); + initialSelection = u.fileName(); + } + } else { + *workingDirectory = u.toString(); + initialSelection = QString::null;//u.fileName(); + } + } + } + + if ( workingDirectory->isNull() ) + *workingDirectory = QDir::currentDirPath(); + +#if defined(Q_WS_WIN) + if ( qApp->style().styleHint( QStyle::SH_GUIStyle ) == WindowsStyle ) + return winGetSaveFileName( initialSelection, filter, workingDirectory, + parent, name, caption, selectedFilter ); +#elif defined(Q_WS_MAC) + if( ( qApp->style().inherits(QMAC_DEFAULT_STYLE) ) ) + return macGetSaveFileName( initialSelection, filter, workingDirectory, + parent, name, caption ); +#endif + + QFileDialogP *dlg = new QFileDialogP( *workingDirectory, QString::null, parent, name ? name : "qt_filedlg_gsfn", TRUE ); + + Q_CHECK_PTR( dlg ); +#ifndef QT_NO_WIDGET_TOPEXTRA + if ( parent && parent->icon() && !parent->icon()->isNull() ) + dlg->setIcon( *parent->icon() ); + else if ( qApp->mainWidget() && qApp->mainWidget()->icon() && !qApp->mainWidget()->icon()->isNull() ) + dlg->setIcon( *qApp->mainWidget()->icon() ); + + if ( !caption.isNull() ) + dlg->setCaption( caption ); + else + dlg->setCaption( QFileDialogP::tr( "Save As" ) ); +#endif + + QString result; + dlg->setFilters( filters ); + if ( selectedFilter ) + dlg->setFilter( *selectedFilter ); + dlg->setMode( QFileDialogP::AnyFile ); + if ( !initialSelection.isEmpty() ) + dlg->setSelection( initialSelection ); + if ( dlg->exec() == QDialog::Accepted ) { + result = dlg->selectedFile(); + *workingDirectory = dlg->d->url; + if ( selectedFilter ) + *selectedFilter = dlg->selectedFilter(); + } + delete dlg; + + qt_resolve_symlinks = save_qt_resolve_symlinks; + + return result; +} + +/*! + \internal + Activated when the "OK" button is clicked. +*/ + +void QFileDialogP::okClicked() +{ + QString fn( nameEdit->text() ); + +#if defined(Q_WS_WIN) + QFileInfo fi( d->url.path() + fn ); + if ( fi.isSymLink() ) { + nameEdit->setText( fi.readLink() ); + } +#endif + + if ( fn.contains("*") ) { + addFilter( fn ); + nameEdit->blockSignals( TRUE ); + nameEdit->setText( QString::fromLatin1("") ); + nameEdit->blockSignals( FALSE ); + return; + } + + *workingDirectory = d->url; + detailViewMode = files->isVisible(); + *lastSize = size(); + + if ( isDirectoryMode( d->mode ) ) { + if ( d->ignoreReturn ) { + d->ignoreReturn = FALSE; + return; + } + QUrlInfo f( d->url, nameEdit->text() ); + if ( f.isDir() ) { + d->currentFileName = d->url; + if ( d->currentFileName.right(1) != "/" ) + d->currentFileName += '/'; + if ( f.name() != "." ) + d->currentFileName += f.name(); + accept(); + return; + } + } + + // if we're in multi-selection mode and something is selected, + // accept it and be done. + if ( mode() == ExistingFiles ) { + if ( ! nameEdit->text().isEmpty() ) { + QStringList sf = selectedFiles(); + bool isdir = FALSE; + if ( sf.count() == 1 ) { + QUrlOperator u( d->url, sf[0] ); + bool ok; + isdir = u.isDir(&ok) && ok; + } + if ( !isdir ) { + emit filesSelected( sf ); + accept(); + return; + } + } + } + + if ( mode() == AnyFile ) { + QUrlOperator u( d->url, QFileDialogPrivate::encodeFileName(nameEdit->text()) ); + if ( !u.isDir() ) { + d->currentFileName = u; + emit fileSelected( selectedFile() ); + accept(); + return; + } + } + + if ( mode() == ExistingFile ) { + QUrl u( d->url, QFileDialogPrivate::encodeFileName(nameEdit->text()) ); + if ( u.isLocalFile() ) { + QFileInfo f( u.path() ); + if ( !f.exists() ) + return; + } else { + QNetworkProtocol *p = QNetworkProtocol::getNetworkProtocol( d->url.protocol() ); + if ( p && (p->supportedOperations()&QNetworkProtocol::OpListChildren) ) { + QUrlInfo ui( d->url, nameEdit->text() ); + if ( !ui.isValid() ) + return; + } + } + } + + // If selection is valid, return it, else try + // using selection as a directory to change to. + if ( !d->currentFileName.isNull() && !d->currentFileName.contains( "*" ) ) { + emit fileSelected( selectedFile() ); + accept(); + } else { + QUrlInfo f; + QFileDialogPrivate::File * c + = (QFileDialogPrivate::File *)files->currentItem(); + QFileDialogPrivate::MCItem * m + = (QFileDialogPrivate::MCItem *)d->moreFiles->item( d->moreFiles->currentItem() ); + if ( c && files->isVisible() && files->hasFocus() || + m && d->moreFiles->isVisible() && d->moreFiles->hasFocus() ) { + if ( c && files->isVisible() ) + f = c->info; + else + f = ( (QFileDialogPrivate::File*)m->i )->info; + } else { + f = QUrlInfo( d->url, nameEdit->text() ); + } + if ( f.isDir() ) { + setUrl( QUrlOperator( d->url, QFileDialogPrivate::encodeFileName(f.name() + "/" ) ) ); + d->checkForFilter = TRUE; + trySetSelection( TRUE, d->url, TRUE ); + d->checkForFilter = FALSE; + } else { + if ( !nameEdit->text().contains( "/" ) && + !nameEdit->text().contains( "\\" ) +#if defined(Q_OS_WIN32) + && nameEdit->text()[ 1 ] != ':' +#endif + ) + addFilter( nameEdit->text() ); + else if ( nameEdit->text()[ 0 ] == '/' || + nameEdit->text()[ 0 ] == '\\' +#if defined(Q_OS_WIN32) + || nameEdit->text()[ 1 ] == ':' +#endif + ) + setDir( nameEdit->text() ); + else if ( nameEdit->text().left( 3 ) == "../" || nameEdit->text().left( 3 ) == "..\\" ) + setDir( QUrl( d->url.toString(), QFileDialogPrivate::encodeFileName(nameEdit->text() ) ).toString() ); + } + nameEdit->setText( "" ); + } +} + +/*! + \internal + Activated when the "Filter" button is clicked. +*/ + +void QFileDialogP::filterClicked() +{ + // unused +} + +/*! + \internal + Activated when the "Cancel" button is clicked. +*/ + +void QFileDialogP::cancelClicked() +{ + *workingDirectory = d->url; + detailViewMode = files->isVisible(); + *lastSize = size(); + reject(); +} + + +/*!\reimp +*/ + +void QFileDialogP::resizeEvent( QResizeEvent * e ) +{ + QDialog::resizeEvent( e ); + updateGeometries(); +} + +/* + \internal + The only correct way to try to set currentFileName +*/ +bool QFileDialogP::trySetSelection( bool isDir, const QUrlOperator &u, bool updatelined ) +{ + if ( !isDir && !u.path().isEmpty() && u.path().right( 1 ) == "/" ) + isDir = TRUE; + if ( u.fileName().contains( "*") && d->checkForFilter ) { + QString fn( u.fileName() ); + if ( fn.contains( "*" ) ) { + addFilter( fn ); + d->currentFileName = QString::null; + d->url.setFileName( QString::null ); + nameEdit->setText( QString::fromLatin1("") ); + return FALSE; + } + } + + if ( isDir ) { + if ( d->preview && d->preview->isVisible() ) { + if ( d->infoPreviewer ) + d->infoPreviewer->previewUrl( u ); + if ( d->contentsPreviewer ) + d->contentsPreviewer->previewUrl( u ); + } + } + + QString old = d->currentFileName; + + if ( isDirectoryMode( mode() ) ) { + if ( isDir ) + d->currentFileName = u; + else + d->currentFileName = QString::null; + } else if ( !isDir && mode() == ExistingFiles ) { + d->currentFileName = u; + } else if ( !isDir || ( mode() == AnyFile && !isDir ) ) { + d->currentFileName = u; + } else { + d->currentFileName = QString::null; + } + if ( updatelined && !d->currentFileName.isEmpty() ) { + // If the selection is valid, or if its a directory, allow OK. + if ( !d->currentFileName.isNull() || isDir ) { + if ( u.fileName() != ".." ) { + QString fn = u.fileName(); + nameEdit->setText( fn ); + } else { + nameEdit->setText(""); + } + } else + nameEdit->setText( QString::fromLatin1("") ); + } + + if ( !d->currentFileName.isNull() || isDir ) { + okB->setEnabled( TRUE ); + } else if ( !isDirectoryMode( d->mode ) ) { + okB->setEnabled( FALSE ); + } + + if ( d->currentFileName.length() && old != d->currentFileName ) + emit fileHighlighted( selectedFile() ); + + return !d->currentFileName.isNull(); +} + + +/*! Make sure the minimum and maximum sizes of everything are sane. +*/ + +void QFileDialogP::updateGeometries() +{ + if ( !d || !d->geometryDirty ) + return; + + d->geometryDirty = FALSE; + + QSize r, t; + + // we really should have a QSize::unite() +#define RM r.setWidth( QMAX(r.width(),t.width()) ); \ +r.setHeight( QMAX(r.height(),t.height()) ) + + // labels first + r = d->pathL->sizeHint(); + t = d->fileL->sizeHint(); + RM; + t = d->typeL->sizeHint(); + RM; + d->pathL->setFixedSize( d->pathL->sizeHint() ); + d->fileL->setFixedSize( r ); + d->typeL->setFixedSize( r ); + + // single-line input areas + r = d->paths->sizeHint(); + t = nameEdit->sizeHint(); + RM; + t = d->types->sizeHint(); + RM; + r.setWidth( t.width() * 2 / 3 ); + t.setWidth( QWIDGETSIZE_MAX ); + t.setHeight( r.height() ); + d->paths->setMinimumSize( r ); + d->paths->setMaximumSize( t ); + nameEdit->setMinimumSize( r ); + nameEdit->setMaximumSize( t ); + d->types->setMinimumSize( r ); + d->types->setMaximumSize( t ); + + // buttons on top row + r = QSize( 0, d->paths->minimumSize().height() ); + t = QSize( 21, 20 ); + RM; + if ( r.height()+1 > r.width() ) + r.setWidth( r.height()+1 ); + if ( d->goBack ) + d->goBack->setFixedSize( r ); + d->cdToParent->setFixedSize( r ); + d->newFolder->setFixedSize( r ); + d->mcView->setFixedSize( r ); + d->detailView->setFixedSize( r ); + + QButton *b = 0; + if ( !d->toolButtons.isEmpty() ) { + for ( b = d->toolButtons.first(); b; b = d->toolButtons.next() ) + b->setFixedSize( b->sizeHint().width(), r.height() ); + } + + if ( d->infoPreview ) { + d->previewInfo->show(); + d->previewInfo->setFixedSize( r ); + } else { + d->previewInfo->hide(); + d->previewInfo->setFixedSize( QSize( 0, 0 ) ); + } + + if ( d->contentsPreview ) { + d->previewContents->show(); + d->previewContents->setFixedSize( r ); + } else { + d->previewContents->hide(); + d->previewContents->setFixedSize( QSize( 0, 0 ) ); + } + + // open/save, cancel + r = QSize( 75, 20 ); + t = okB->sizeHint(); + RM; + t = cancelB->sizeHint(); + RM; + + okB->setFixedSize( r ); + cancelB->setFixedSize( r ); + + d->topLevelLayout->activate(); + +#undef RM +} + + +/*! Updates the file name edit box to \a newItem in the file dialog + when the cursor moves in the listview. +*/ + +void QFileDialogP::updateFileNameEdit( QListViewItem * newItem ) +{ + if ( !newItem ) + return; + + if ( mode() == ExistingFiles ) { + detailViewSelectionChanged(); + QUrl u = QUrl( d->url, QFileDialogPrivate::encodeFileName( ((QFileDialogPrivate::File*)files->currentItem())->info.name() ) ); + QFileInfo fi( u.toString( FALSE, FALSE ) ); + if ( !fi.isDir() ) + emit fileHighlighted( u.toString( FALSE, FALSE ) ); + } else if ( files->isSelected( newItem ) ) { + QFileDialogPrivate::File * i = (QFileDialogPrivate::File *)newItem; + if ( i && i->i && !i->i->isSelected() ) { + d->moreFiles->blockSignals( TRUE ); + d->moreFiles->setSelected( i->i, TRUE ); + d->moreFiles->blockSignals( FALSE ); + } + // Encode the filename in case it had any special characters in it + QString encFile = QFileDialogPrivate::encodeFileName( newItem->text( 0 ) ); + trySetSelection( i->info.isDir(), QUrlOperator( d->url, encFile ), TRUE ); + } +} + +void QFileDialogP::detailViewSelectionChanged() +{ + if ( d->mode != ExistingFiles ) + return; + + nameEdit->clear(); + QString str; + QListViewItem * i = files->firstChild(); + d->moreFiles->blockSignals( TRUE ); + while( i ) { + if ( d->moreFiles && isVisible() ) { + if ( ( (QFileDialogPrivate::File *)i )->i->isSelected() != i->isSelected() ) + d->moreFiles->setSelected( ( (QFileDialogPrivate::File *)i )->i, i->isSelected() ); + } + if ( i->isSelected() && !( (QFileDialogPrivate::File *)i )->info.isDir() ) + str += QString( "\"%1\" " ).arg( i->text( 0 ) ); + i = i->nextSibling(); + } + d->moreFiles->blockSignals( FALSE ); + nameEdit->setText( str ); + nameEdit->setCursorPosition( str.length() ); + okB->setEnabled( TRUE ); + if ( d->preview && d->preview->isVisible() && files->currentItem() ) { + QUrl u = QUrl( d->url, QFileDialogPrivate::encodeFileName( ((QFileDialogPrivate::File*)files->currentItem())->info.name() ) ); + if ( d->infoPreviewer ) + d->infoPreviewer->previewUrl( u ); + if ( d->contentsPreviewer ) + d->contentsPreviewer->previewUrl( u ); + } +} + +void QFileDialogP::listBoxSelectionChanged() +{ + if ( d->mode != ExistingFiles ) + return; + + if ( d->ignoreNextRefresh ) { + d->ignoreNextRefresh = FALSE; + return; + } + + nameEdit->clear(); + QString str; + QListBoxItem * i = d->moreFiles->item( 0 ); + QListBoxItem * j = 0; + int index = 0; + files->blockSignals( TRUE ); + while( i ) { + if ( files && isVisible() ) { + if ( ( (QFileDialogPrivate::MCItem *)i )->i->isSelected() != i->isSelected() ) + files->setSelected( ( (QFileDialogPrivate::MCItem *)i )->i, i->isSelected() ); + } + if ( d->moreFiles->isSelected( i ) + && !( (QFileDialogPrivate::File*)( (QFileDialogPrivate::MCItem *)i )->i )->info.isDir() ) + { + str += QString( "\"%1\" " ).arg( i->text() ); + if ( j == 0 ) + j = i; + } + i = d->moreFiles->item( ++index ); + } + files->blockSignals( FALSE ); + nameEdit->setText( str ); + nameEdit->setCursorPosition( str.length() ); + okB->setEnabled( TRUE ); + if ( d->preview && d->preview->isVisible() && j ) { + QUrl u = QUrl( d->url, + QFileDialogPrivate::encodeFileName( ( (QFileDialogPrivate::File*)( (QFileDialogPrivate::MCItem*)j )->i )->info.name() ) ); + if ( d->infoPreviewer ) + d->infoPreviewer->previewUrl( u ); + if ( d->contentsPreviewer ) + d->contentsPreviewer->previewUrl( u ); + } +} + +/*! \overload */ + +void QFileDialogP::updateFileNameEdit( QListBoxItem * newItem ) +{ + if ( !newItem ) + return; + QFileDialogPrivate::MCItem * i = (QFileDialogPrivate::MCItem *)newItem; + if ( d->mode != ExistingFiles && i->i ) { + i->i->listView()->setSelected( i->i, i->isSelected() ); + updateFileNameEdit( i->i ); + } +} + + +/*! Updates the dialog when the file name edit changes. */ + +void QFileDialogP::fileNameEditDone() +{ + QUrlInfo f( d->url, nameEdit->text() ); + if ( mode() != QFileDialogP::ExistingFiles ) { + QUrlOperator u( d->url, QFileDialogPrivate::encodeFileName( nameEdit->text() ) ); + trySetSelection( f.isDir(), u, FALSE ); + if ( d->preview && d->preview->isVisible() ) { + if ( d->infoPreviewer ) + d->infoPreviewer->previewUrl( u ); + if ( d->contentsPreviewer ) + d->contentsPreviewer->previewUrl( u ); + } + } +} + + + +/*! This private slot reacts to double-clicks in the list view. The item that +was double-clicked is specified in \a newItem */ + +void QFileDialogP::selectDirectoryOrFile( QListViewItem * newItem ) +{ + + *workingDirectory = d->url; + detailViewMode = files->isVisible(); + *lastSize = size(); + + if ( !newItem ) + return; + +#if defined(Q_WS_WIN) + QFileInfo fi( d->url.path() + newItem->text(0) ); + if ( fi.isSymLink() ) { + nameEdit->setText( fi.readLink() ); + okClicked(); + return; + } +#endif + + QFileDialogPrivate::File * i = (QFileDialogPrivate::File *)newItem; + + QString oldName = nameEdit->text(); + if ( i->info.isDir() ) { + setUrl( QUrlOperator( d->url, QFileDialogPrivate::encodeFileName( i->info.name() ) + "/" ) ); + if ( isDirectoryMode( mode() ) ) { + QUrlInfo f ( d->url, QString::fromLatin1( "." ) ); + trySetSelection( f.isDir(), d->url, TRUE ); + } + } else if ( newItem->isSelectable() && + trySetSelection( i->info.isDir(), QUrlOperator( d->url, QFileDialogPrivate::encodeFileName( i->info.name() ) ), TRUE ) ) { + if ( !isDirectoryMode( mode() ) ) { + emit fileSelected( selectedFile() ); + accept(); + } + } else if ( isDirectoryMode( d->mode ) ) { + d->currentFileName = d->url; + accept(); + } + if ( !oldName.isEmpty() && !isDirectoryMode( mode() ) ) + nameEdit->setText( oldName ); +} + + +void QFileDialogP::selectDirectoryOrFile( QListBoxItem * newItem ) +{ + if ( !newItem ) + return; + + QFileDialogPrivate::MCItem * i = (QFileDialogPrivate::MCItem *)newItem; + if ( i->i ) { + i->i->listView()->setSelected( i->i, i->isSelected() ); + selectDirectoryOrFile( i->i ); + } +} + + +void QFileDialogP::popupContextMenu( QListViewItem *item, const QPoint &p, + int ) +{ + if ( item && d->mode == ExistingFiles ) + return; + if ( item ) { + files->setCurrentItem( item ); + files->setSelected( item, TRUE ); + } + + PopupAction action; + popupContextMenu( item ? item->text( 0 ) : QString::null, TRUE, action, p ); + + if ( action == PA_Open ) + selectDirectoryOrFile( item ); + else if ( action == PA_Rename ) + files->startRename( FALSE ); + else if ( action == PA_Delete ) + deleteFile( item ? item->text( 0 ) : QString::null ); + else if ( action == PA_Reload ) + rereadDir(); + else if ( action == PA_Hidden ) { + bShowHiddenFiles = !bShowHiddenFiles; + rereadDir(); + } else if ( action == PA_SortName ) { + sortFilesBy = (int)QDir::Name; + sortAscending = TRUE; + resortDir(); + } else if ( action == PA_SortSize ) { + sortFilesBy = (int)QDir::Size; + sortAscending = TRUE; + resortDir(); + } else if ( action == PA_SortDate ) { + sortFilesBy = (int)QDir::Time; + sortAscending = TRUE; + resortDir(); + } else if ( action == PA_SortUnsorted ) { + sortFilesBy = (int)QDir::Unsorted; + sortAscending = TRUE; + resortDir(); + } + +} + +void QFileDialogP::popupContextMenu( QListBoxItem *item, const QPoint & p ) +{ + if ( item && d->mode == ExistingFiles ) + return; + + PopupAction action; + popupContextMenu( item ? item->text() : QString::null, FALSE, action, p ); + + if ( action == PA_Open ) + selectDirectoryOrFile( item ); + else if ( action == PA_Rename ) + d->moreFiles->startRename( FALSE ); + else if ( action == PA_Delete ) + deleteFile( item->text() ); + else if ( action == PA_Reload ) + rereadDir(); + else if ( action == PA_Hidden ) { + bShowHiddenFiles = !bShowHiddenFiles; + rereadDir(); + } else if ( action == PA_SortName ) { + sortFilesBy = (int)QDir::Name; + sortAscending = TRUE; + resortDir(); + } else if ( action == PA_SortSize ) { + sortFilesBy = (int)QDir::Size; + sortAscending = TRUE; + resortDir(); + } else if ( action == PA_SortDate ) { + sortFilesBy = (int)QDir::Time; + sortAscending = TRUE; + resortDir(); + } else if ( action == PA_SortUnsorted ) { + sortFilesBy = (int)QDir::Unsorted; + sortAscending = TRUE; + resortDir(); + } +} + +void QFileDialogP::popupContextMenu( const QString &filename, bool, + PopupAction &action, const QPoint &p ) +{ + action = PA_Cancel; + + bool glob = filename.isEmpty(); + + QPopupMenu m( 0, "file dialog context menu" ); + m.setCheckable( TRUE ); + + if ( !glob ) { + QString okt; + if ( QUrlInfo( d->url, filename ).isDir() ) { + okt = tr( "&Open" ); + } else { + if ( mode() == AnyFile ) + okt = tr( "&Save" ); + else + okt = tr( "&Open" ); + } + int ok = m.insertItem( okt ); + + m.insertSeparator(); + int rename = m.insertItem( tr( "&Rename" ) ); + int del = m.insertItem( tr( "&Delete" ) ); + + if ( filename.isEmpty() || !QUrlInfo( d->url, filename ).isWritable() || + filename == ".." ) { + if ( filename.isEmpty() || !QUrlInfo( d->url, filename ).isReadable() ) + m.setItemEnabled( ok, FALSE ); + m.setItemEnabled( rename, FALSE ); + m.setItemEnabled( del, FALSE ); + } + + if ( mode() == QFileDialogP::ExistingFiles ) + m.setItemEnabled( rename, FALSE ); + + m.move( p ); + int res = m.exec(); + + if ( res == ok ) + action = PA_Open; + else if ( res == rename ) + action = PA_Rename; + else if ( res == del ) + action = PA_Delete; + } else { + int reload = m.insertItem( tr( "R&eload" ) ); + + QPopupMenu m2( 0, "sort menu" ); + + int sname = m2.insertItem( tr( "Sort by &Name" ) ); + //int stype = m2.insertItem( tr( "Sort by &Type" ) ); + int ssize = m2.insertItem( tr( "Sort by &Size" ) ); + int sdate = m2.insertItem( tr( "Sort by &Date" ) ); + m2.insertSeparator(); + int sunsorted = m2.insertItem( tr( "&Unsorted" ) ); + + //m2.setItemEnabled( stype, FALSE ); + + if ( sortFilesBy == (int)QDir::Name ) + m2.setItemChecked( sname, TRUE ); + else if ( sortFilesBy == (int)QDir::Size ) + m2.setItemChecked( ssize, TRUE ); +// else if ( sortFilesBy == 0x16 ) +// m2.setItemChecked( stype, TRUE ); + else if ( sortFilesBy == (int)QDir::Time ) + m2.setItemChecked( sdate, TRUE ); + else if ( sortFilesBy == (int)QDir::Unsorted ) + m2.setItemChecked( sunsorted, TRUE ); + + m.insertItem( tr( "Sort" ), &m2 ); + + m.insertSeparator(); + + int hidden = m.insertItem( tr( "Show &hidden files" ) ); + m.setItemChecked( hidden, bShowHiddenFiles ); + + m.move( p ); + int res = m.exec(); + + if ( res == reload ) + action = PA_Reload; + else if ( res == hidden ) + action = PA_Hidden; + else if ( res == sname ) + action = PA_SortName; +// else if ( res == stype ) +// action = PA_SortType; + else if ( res == sdate ) + action = PA_SortDate; + else if ( res == ssize ) + action = PA_SortSize; + else if ( res == sunsorted ) + action = PA_SortUnsorted; + } + +} + +void QFileDialogP::deleteFile( const QString &filename ) +{ + if ( filename.isEmpty() ) + return; + + QUrlInfo fi( d->url, QFileDialogPrivate::encodeFileName( filename ) ); + QString t = tr( "the file" ); + if ( fi.isDir() ) + t = tr( "the directory" ); + if ( fi.isSymLink() ) + t = tr( "the symlink" ); + + if ( QMessageBox::warning( this, + tr( "Delete %1" ).arg( t ), + tr( "Are you sure you wish to delete %1 \"%2\"?" ) + .arg( t ).arg(filename), + tr( "&Yes" ), tr( "&No" ), QString::null, 1 ) == 0 ) + d->url.remove( QFileDialogPrivate::encodeFileName( filename ) ); + +} + +void QFileDialogP::fileSelected( int ) +{ + // unused +} + +void QFileDialogP::fileHighlighted( int ) +{ + // unused +} + +void QFileDialogP::dirSelected( int ) +{ + // unused +} + +void QFileDialogP::pathSelected( int ) +{ + // unused +} + + +void QFileDialogP::cdUpClicked() +{ + QString oldName = nameEdit->text(); + setUrl( QUrlOperator( d->url, ".." ) ); + if ( !oldName.isEmpty() ) + nameEdit->setText( oldName ); +} + +void QFileDialogP::newFolderClicked() +{ + QString foldername( tr( "New Folder 1" ) ); + int i = 0; + QStringList lst; + QListViewItemIterator it( files ); + for ( ; it.current(); ++it ) + if ( it.current()->text( 0 ).contains( tr( "New Folder" ) ) ) + lst.append( it.current()->text( 0 ) ); + + if ( !lst.count() == 0 ) + while ( lst.contains( foldername ) ) + foldername = tr( "New Folder %1" ).arg( ++i ); + + d->url.mkdir( foldername ); +} + +void QFileDialogP::createdDirectory( const QUrlInfo &info, QNetworkOperation * ) +{ + resortDir(); + if ( d->moreFiles->isVisible() ) { + for ( uint i = 0; i < d->moreFiles->count(); ++i ) { + if ( d->moreFiles->text( i ) == info.name() ) { + d->moreFiles->setCurrentItem( i ); + d->moreFiles->startRename( FALSE ); + break; + } + } + } else { + QListViewItem *item = files->firstChild(); + while ( item ) { + if ( item->text( 0 ) == info.name() ) { + files->setSelected( item, TRUE ); + files->setCurrentItem( item ); + files->startRename( FALSE ); + break; + } + item = item->nextSibling(); + } + } +} + + +/*! + This is a convenience static function that will return an existing directory + selected by the user. + + \code + QString s = QFileDialogP::getExistingDirectory( + "/home", + this, + "get existing directory" + "Choose a directory", + TRUE ); + \endcode + + This function creates a modal file dialog called \a name, with + parent, \a parent. If parent is not 0, the dialog will be shown + centered over the parent. + + The dialog's working directory is set to \a dir, and the caption is + set to \a caption. Either of these may be QString::null in which case + the current directory and a default caption will be used respectively. + + If \a dirOnly is TRUE, then only directories will be shown in + the file dialog; otherwise both directories and files will be shown. + + Under Unix/X11, the normal behavior of the file dialog is to resolve + and follow symlinks. For example, if /usr/tmp is a symlink to /var/tmp, + the file dialog will change to /var/tmp after entering /usr/tmp. + If \a resolveSymlinks is FALSE, the file dialog will treat + symlinks as regular directories. + + \sa getOpenFileName(), getOpenFileNames(), getSaveFileName() +*/ + +QString QFileDialogP::getExistingDirectory( const QString & dir, + QWidget *parent, + const char* name, + const QString& caption, + bool dirOnly, + bool resolveSymlinks) +{ + bool save_qt_resolve_symlinks = qt_resolve_symlinks; + qt_resolve_symlinks = resolveSymlinks; + + makeVariables(); + QString wd; + if ( workingDirectory ) + wd = *workingDirectory; + +#if defined(Q_WS_WIN) + QString initialDir; + if ( !dir.isEmpty() ) { + QUrlOperator u( dir ); + if ( QFileInfo( u.path() ).isDir() ) + initialDir = dir; + } else + initialDir = QString::null; + if ( qApp->style().styleHint( QStyle::SH_GUIStyle ) == WindowsStyle && dirOnly ) + return winGetExistingDirectory( initialDir, parent, name, caption ); +#endif +#if defined(Q_WS_MAC) + if( ( qApp->style().inherits(QMAC_DEFAULT_STYLE) ) ) + return macGetOpenFileNames("", 0, + parent, name, caption, FALSE, TRUE).first(); +#endif + + QFileDialogP *dialog = new QFileDialogP( parent, name ? name : "qt_filedlg_ged", TRUE ); +#ifndef QT_NO_WIDGET_TOPEXTRA + if ( !caption.isNull() ) + dialog->setCaption( caption ); + else + dialog->setCaption( QFileDialogP::tr("Find Directory") ); +#endif + + dialog->setMode( dirOnly ? DirectoryOnly : Directory ); + + dialog->d->types->clear(); + dialog->d->types->insertItem( QFileDialogP::tr("Directories") ); + dialog->d->types->setEnabled( FALSE ); + + QString dir_( dir ); + dir_ = dir_.simplifyWhiteSpace(); + if ( dir_.isEmpty() && !wd.isEmpty() ) + dir_ = wd; + QUrlOperator u( dir_ ); + if ( u.isLocalFile() ) { + if ( !dir_.isEmpty() ) { + QFileInfo f( u.path() ); + if ( f.exists() ) + if ( f.isDir() ) { + dialog->setDir( dir_ ); + wd = dir_; + } + } else if ( !wd.isEmpty() ) { + QUrl tempUrl( wd ); + QFileInfo f( tempUrl.path() ); + if ( f.isDir() ) { + dialog->setDir( wd ); + } + } else { + QString theDir = dir_; + if ( theDir.isEmpty() ) { + theDir = QDir::currentDirPath(); + } if ( !theDir.isEmpty() ) { + QUrl tempUrl( theDir ); + QFileInfo f( tempUrl.path() ); + if ( f.isDir() ) { + wd = theDir; + dialog->setDir( theDir ); + } + } + } + } else { + dialog->setUrl( dir_ ); + } + + QString result; + dialog->setSelection( dialog->d->url.toString() ); + + if ( dialog->exec() == QDialog::Accepted ) { + result = dialog->selectedFile(); + wd = result; + } + delete dialog; + + if ( !result.isEmpty() && result.right( 1 ) != "/" ) + result += "/"; + + qt_resolve_symlinks = save_qt_resolve_symlinks; + + return result; +} + + +/*! + \property QFileDialogP::mode + \brief the file dialog's mode + + The default mode is \c ExistingFile. +*/ + +void QFileDialogP::setMode( Mode newMode ) +{ + if ( d->mode != newMode ) { + d->mode = newMode; + QString sel = d->currentFileName; + if ( isDirectoryMode( newMode ) ) { + files->setMultiSelection( FALSE ); + d->moreFiles->setMultiSelection( FALSE ); + if ( sel.isNull() ) + sel = QString::fromLatin1("."); + d->types->setEnabled( FALSE ); + } else if ( newMode == ExistingFiles ) { + files->setSelectionMode( QListView::Extended ); + d->moreFiles->setSelectionMode( QListBox::Extended ); + d->types->setEnabled( TRUE ); + } else { + files->setMultiSelection( FALSE ); + d->moreFiles->setMultiSelection( FALSE ); + d->types->setEnabled( TRUE ); + } + rereadDir(); + QUrlInfo f( d->url, "." ); + trySetSelection( f.isDir(), d->url, FALSE ); + } + + QString okt; + bool changeFilters = FALSE; + if ( mode() == AnyFile ) { + okt = tr("Save"); + d->fileL->setText( tr("File &name:") ); + if ( d->types->count() == 1 ) { + d->types->setCurrentItem( 0 ); + if ( d->types->currentText() == "Directories" ) { + changeFilters = TRUE; + } + } + } + else if ( mode() == Directory || mode() == DirectoryOnly ) { + okt = tr("OK"); + d->fileL->setText( tr("Directory:") ); + d->types->clear(); + d->types->insertItem( tr("Directories") ); + } + else { + okt = tr("Open"); + d->fileL->setText( tr("File &name:") ); + if ( d->types->count() == 1 ) { + d->types->setCurrentItem( 0 ); + if ( d->types->currentText() == "Directories" ) { + changeFilters = TRUE; + } + } + } + + if ( changeFilters ) { + d->types->clear(); + d->types->insertItem( tr("All Files (*)") ); + } + + okB->setText( okt ); +} + +QFileDialogP::Mode QFileDialogP::mode() const +{ + return d->mode; +} + +/*! \reimp +*/ + +void QFileDialogP::done( int i ) +{ + if ( i == QDialog::Accepted && (d->mode == ExistingFile || d->mode == ExistingFiles) ) { + QStringList selection = selectedFiles(); + for ( uint f = 0; f < selection.count(); f++ ) { + QString file = selection[f]; + if ( file.isNull() ) + continue; + if ( d->url.isLocalFile() && !QFile::exists( file ) ) { + QMessageBox::information( this, tr("Error"), tr("%1\nFile not found.\nCheck path and filename.").arg( file ) ); + return; + } + } + } + QDialog::done( i ); +} + +/*! + \property QFileDialogP::viewMode + + \brief the file dialog's view mode + + If you set the view mode to be \e Detail (the default), then you + will see the file's details, such as the size of the file and the + date the file was last modified in addition to the file's name. + + If you set the view mode to be \e List, then you will just + see a list of the files and folders. + + See \l QFileDialogP::ViewMode +*/ + + +QFileDialogP::ViewMode QFileDialogP::viewMode() const +{ + if ( detailViewMode ) + return Detail; + else + return List; +} + +void QFileDialogP::setViewMode( ViewMode m ) +{ + if ( m == Detail ) { + detailViewMode = TRUE; + d->stack->raiseWidget( files ); + d->detailView->setOn( TRUE ); + d->mcView->setOn( FALSE ); + } else if ( m == List ) { + detailViewMode = FALSE; + d->stack->raiseWidget( d->moreFiles ); + d->detailView->setOn( FALSE ); + d->mcView->setOn( TRUE ); + } +} + + +/*! + \property QFileDialogP::previewMode + + \brief the preview mode for the file dialog + + If you set the mode to be a mode other than \e NoPreview, you must + use setInfoPreview() or setContentsPreview() to set the dialog's + preview widget to your preview widget and enable the preview + widget(s) with setInfoPreviewEnabled() or + setContentsPreviewEnabled(). + + \sa infoPreview, contentsPreview, viewMode +*/ + +void QFileDialogP::setPreviewMode( PreviewMode m ) +{ + if ( m == NoPreview ) { + d->previewInfo->setOn( FALSE ); + d->previewContents->setOn( FALSE ); + } else if ( m == Info && d->infoPreview ) { + d->previewInfo->setOn( TRUE ); + d->previewContents->setOn( FALSE ); + changeMode( d->modeButtons->id( d->previewInfo ) ); + } else if ( m == Contents && d->contentsPreview ) { + d->previewInfo->setOn( FALSE ); + d->previewContents->setOn( TRUE ); + changeMode( d->modeButtons->id( d->previewContents ) ); + } +} +QFileDialogP::PreviewMode QFileDialogP::previewMode() const +{ + if ( d->infoPreview && d->previewInfo->isVisible() ) + return Info; + else if ( d->contentsPreview && d->previewContents->isVisible() ) + return Contents; + + return NoPreview; +} + + +/*! + Adds the specified widgets to the bottom of the file dialog. The + label \a l is placed underneath the "file name" and the "file types" + labels. The widget \a w is placed underneath the file types combobox. + The button \a b is placed underneath the Cancel pushbutton. + + \code + MyFileDialog::MyFileDialog( QWidget* parent, const char* name ) : + QFileDialogP( parent, name ) + { + QLabel* label = new QLabel( "Added widgets", this ); + QLineEdit* lineedit = new QLineEdit( this ); + QToolButton* toolbutton = new QToolButton( this ); + + addWidgets( label, lineedit, toolbutton ); + } + \endcode + + If you don't want to have one of the widgets added, pass 0 in that + widget's position. + + Every time you call this function, a new row of widgets will be added + to the bottom of the file dialog. + + \sa addToolButton(), addLeftWidget(), addRightWidget() +*/ + +void QFileDialogP::addWidgets( QLabel * l, QWidget * w, QPushButton * b ) +{ + if ( !l && !w && !b ) + return; + + d->geometryDirty = TRUE; + + QHBoxLayout *lay = new QHBoxLayout(); + d->extraWidgetsLayouts.append( lay ); + d->topLevelLayout->addLayout( lay ); + + if ( !l ) + l = new QLabel( this, "qt_intern_lbl" ); + d->extraLabels.append( l ); + lay->addWidget( l ); + + if ( !w ) + w = new QWidget( this, "qt_intern_widget" ); + d->extraWidgets.append( w ); + lay->addWidget( w ); + lay->addSpacing( 15 ); + + if ( b ) { + d->extraButtons.append( b ); + lay->addWidget( b ); + } else { + QWidget *wid = new QWidget( this, "qt_extrabuttons_widget" ); + d->extraButtons.append( wid ); + lay->addWidget( wid ); + } + + updateGeometries(); +} + +/*! + Adds the tool button \a b to the row of tool buttons at the top of the + file dialog. The button is appended to the right of + this row. If \a separator is TRUE, a small space is inserted between the + last button of the row and the new button \a b. + + \sa addWidgets(), addLeftWidget(), addRightWidget() +*/ + +void QFileDialogP::addToolButton( QButton *b, bool separator ) +{ + if ( !b || !d->buttonLayout ) + return; + + d->geometryDirty = TRUE; + + d->toolButtons.append( b ); + if ( separator ) + d->buttonLayout->addSpacing( 8 ); + d->buttonLayout->addWidget( b ); + + updateGeometries(); +} + +/*! + Adds the widget \a w to the left-hand side of the file dialog. + + \sa addRightWidget(), addWidgets(), addToolButton() +*/ + +void QFileDialogP::addLeftWidget( QWidget *w ) +{ + if ( !w ) + return; + d->geometryDirty = TRUE; + + d->leftLayout->addWidget( w ); + d->leftLayout->addSpacing( 5 ); + + updateGeometries(); +} + +/*! + Adds the widget \a w to the right-hand side of the file dialog. + + \sa addLeftWidget(), addWidgets(), addToolButton() +*/ + +void QFileDialogP::addRightWidget( QWidget *w ) +{ + if ( !w ) + return; + d->geometryDirty = TRUE; + + d->rightLayout->addSpacing( 5 ); + d->rightLayout->addWidget( w ); + + updateGeometries(); +} + +/*! \reimp */ + +void QFileDialogP::keyPressEvent( QKeyEvent * ke ) +{ + if ( !d->ignoreNextKeyPress && + ke && ( ke->key() == Key_Enter || + ke->key() == Key_Return ) ) { + ke->ignore(); + if ( d->paths->hasFocus() ) { + ke->accept(); + if ( d->url == QUrl(d->paths->currentText()) ) + nameEdit->setFocus(); + } else if ( d->types->hasFocus() ) { + ke->accept(); + // ### is there a suitable condition for this? only valid + // wildcards? + nameEdit->setFocus(); + } else if ( nameEdit->hasFocus() ) { + if ( d->currentFileName.isNull() ) { + // maybe change directory + QUrlInfo i( d->url, nameEdit->text() ); + if ( i.isDir() ) { + nameEdit->setText( QString::fromLatin1("") ); + setDir( QUrlOperator( d->url, QFileDialogPrivate::encodeFileName(i.name()) ) ); + } + ke->accept(); + } else if ( mode() == ExistingFiles ) { + QUrlInfo i( d->url, nameEdit->text() ); + if ( i.isFile() ) { + QListViewItem * i = files->firstChild(); + while ( i && nameEdit->text() != i->text( 0 ) ) + i = i->nextSibling(); + if ( i ) + files->setSelected( i, TRUE ); + else + ke->accept(); // strangely, means to ignore that event + } + } + } else if ( files->hasFocus() || d->moreFiles->hasFocus() ) { + ke->accept(); + } + } else if ( ke->key() == Key_Escape ) { + ke->ignore(); + } + + d->ignoreNextKeyPress = FALSE; + + if ( !ke->isAccepted() ) { + QDialog::keyPressEvent( ke ); + } +} + + +/*! \class QFileIconProviderP qfiledialog.h + + \brief The QFileIconProviderP class provides icons for QFileDialogP to + use. + + \ingroup misc + + By default QFileIconProviderP is not used, but any application or + library can subclass it, reimplement pixmap() to return a suitable + icon, and make all QFileDialogP objects use it by calling the static + function QFileDialogP::setIconProvider(). + + It is advisable to make all the icons that QFileIconProviderP returns be + the same size or at least the same width. This makes the list view + look much better. + + \sa QFileDialogP +*/ + + +/*! Constructs an empty file icon provider called \a name, with the + parent \a parent. +*/ + +QFileIconProviderP::QFileIconProviderP( QObject * parent, const char* name ) + : QObject( parent, name ) +{ + // nothing necessary +} + + +/*! + Returns a pointer to a pixmap that should be used to + signify the file with the information \a info. + + If pixmap() returns 0, QFileDialogP draws the default pixmap. + + The default implementation returns particular icons for files, directories, + link-files and link-directories. It returns a blank "icon" for other types. + + If you return a pixmap here, it should measure 16x16 pixels. +*/ + +const QPixmap * QFileIconProviderP::pixmap( const QFileInfo & info ) +{ + if ( info.isSymLink() ) { + if ( info.isFile() ) + return symLinkFileIcon; + else + return symLinkDirIcon; + } else if ( info.isDir() ) { + return closedFolderIcon; + } else if ( info.isFile() ) { + return fileIcon; + } else { + return fifteenTransparentPixels; + } +} + +/*! + Sets the QFileIconProviderP used by the file dialog to \a provider. + + The default is that there is no QFileIconProviderP and QFileDialogP + just draws a folder icon next to each directory and nothing next + to files. + + \sa QFileIconProviderP, iconProvider() +*/ + +void QFileDialogP::setIconProvider( QFileIconProviderP * provider ) +{ + fileIconProvider = provider; +} + + +/*! + Returns a pointer to the icon provider currently set on the file dialog. + By default there is no icon provider, and this function returns 0. + + \sa setIconProvider(), QFileIconProviderP +*/ + +QFileIconProviderP * QFileDialogP::iconProvider() +{ + return fileIconProvider; +} + + +#if defined(Q_WS_WIN) + +static QString getWindowsRegString( HKEY key, const char *subKey ) +{ + QString s; + char buf[512]; + DWORD bsz = sizeof(buf); +#ifdef Q_OS_TEMP + int r = RegQueryValueEx( key, (LPCTSTR)qt_winTchar(subKey, TRUE), 0, 0, (LPBYTE)buf, &bsz ); +#else + int r = RegQueryValueExA( key, subKey, 0, 0, (LPBYTE)buf, &bsz ); +#endif + if ( r == ERROR_SUCCESS ) { + s = buf; + } else if ( r == ERROR_MORE_DATA ) { + char *ptr = new char[bsz+1]; +#ifdef Q_OS_TEMP + r = RegQueryValueEx( key, (LPCTSTR)qt_winTchar(subKey, TRUE), 0, 0, (LPBYTE)ptr, &bsz ); +#else + r = RegQueryValueExA( key, subKey, 0, 0, (LPBYTE)ptr, &bsz ); +#endif + if ( r == ERROR_SUCCESS ) + s = ptr; + delete [] ptr; + } + return s; +} + +static void initPixmap( QPixmap &pm ) +{ + pm.fill( Qt::white ); +} + +QWindowsIconProvider::QWindowsIconProvider( QObject *parent, const char *name ) + : QFileIconProviderP( parent, name ) +{ + pixw = GetSystemMetrics( SM_CXSMICON ); + pixh = GetSystemMetrics( SM_CYSMICON ); + + HKEY k; + HICON si; + int r; + QString s; + UINT res; + +#ifdef Q_OS_TEMP + // ---------- get default folder pixmap + r = RegOpenKeyEx( HKEY_CLASSES_ROOT, + L"folder\\DefaultIcon", + 0, KEY_READ, &k ); +#else + // ---------- get default folder pixmap + r = RegOpenKeyExA( HKEY_CLASSES_ROOT, + "folder\\DefaultIcon", + 0, KEY_READ, &k ); +#endif + if ( r == ERROR_SUCCESS ) { + s = getWindowsRegString( k, 0 ); + RegCloseKey( k ); + + QStringList lst = QStringList::split( ",", s ); + +#ifdef Q_OS_TEMP + res = (UINT)ExtractIconEx( (LPCTSTR)qt_winTchar( lst[ 0 ].simplifyWhiteSpace(), TRUE ), + lst[ 1 ].simplifyWhiteSpace().toInt(), + 0, &si, 1 ); +#else + res = ExtractIconExA( lst[ 0 ].simplifyWhiteSpace().latin1(), + lst[ 1 ].simplifyWhiteSpace().toInt(), + 0, &si, 1 ); +#endif + + if ( res ) { + defaultFolder.resize( pixw, pixh ); + initPixmap( defaultFolder ); + QPainter p( &defaultFolder ); + DrawIconEx( p.handle(), 0, 0, si, pixw, pixh, 0, NULL, DI_NORMAL ); + p.end(); + defaultFolder.setMask( defaultFolder.createHeuristicMask() ); + *closedFolderIcon = defaultFolder; + DestroyIcon( si ); + } else { + defaultFolder = *closedFolderIcon; + } + } else { + RegCloseKey( k ); + } + +#ifdef Q_OS_TEMP + //------------------------------- get default file pixmap + res = (UINT)ExtractIconEx( L"shell32.dll", + 0, 0, &si, 1 ); +#else + //------------------------------- get default file pixmap + res = ExtractIconExA( "shell32.dll", + 0, 0, &si, 1 ); +#endif + + if ( res ) { + defaultFile.resize( pixw, pixh ); + initPixmap( defaultFile ); + QPainter p( &defaultFile ); + DrawIconEx( p.handle(), 0, 0, si, pixw, pixh, 0, NULL, DI_NORMAL ); + p.end(); + defaultFile.setMask( defaultFile.createHeuristicMask() ); + *fileIcon = defaultFile; + DestroyIcon( si ); + } else { + defaultFile = *fileIcon; + } + +#ifdef Q_OS_TEMP + //------------------------------- get default exe pixmap + res = (UINT)ExtractIconEx( L"shell32.dll", + 2, 0, &si, 1 ); +#else + //------------------------------- get default exe pixmap + res = ExtractIconExA( "shell32.dll", + 2, 0, &si, 1 ); +#endif + + if ( res ) { + defaultExe.resize( pixw, pixh ); + initPixmap( defaultExe ); + QPainter p( &defaultExe ); + DrawIconEx( p.handle(), 0, 0, si, pixw, pixh, 0, NULL, DI_NORMAL ); + p.end(); + defaultExe.setMask( defaultExe.createHeuristicMask() ); + DestroyIcon( si ); + } else { + defaultExe = *fileIcon; + } +} + +QWindowsIconProvider::~QWindowsIconProvider() +{ + if ( this == fileIconProvider ) + fileIconProvider = 0; +} + +const QPixmap * QWindowsIconProvider::pixmap( const QFileInfo &fi ) +{ + QString ext = fi.extension().upper(); + QString key = ext; + ext.prepend( "." ); + QMap< QString, QPixmap >::Iterator it; + + if ( fi.isDir() ) { + return &defaultFolder; + } else if ( ext.lower() != ".exe" ) { + it = cache.find( key ); + if ( it != cache.end() ) + return &( *it ); + + HKEY k, k2; +#ifdef Q_OS_TEMP + int r = RegOpenKeyEx( HKEY_CLASSES_ROOT, + (LPCTSTR)qt_winTchar(ext, TRUE), + 0, KEY_READ, &k ); +#else + int r = RegOpenKeyExA( HKEY_CLASSES_ROOT, + ext.latin1(), + 0, KEY_READ, &k ); +#endif + QString s; + if ( r == ERROR_SUCCESS ) { + s = getWindowsRegString( k, 0 ); + } else { + cache[ key ] = defaultFile; + RegCloseKey( k ); + return &defaultFile; + } + RegCloseKey( k ); + +#ifdef Q_OS_TEMP + r = RegOpenKeyEx( HKEY_CLASSES_ROOT, + (LPCTSTR)qt_winTchar( s + "\\DefaultIcon", TRUE ), + 0, KEY_READ, &k2 ); +#else + r = RegOpenKeyExA( HKEY_CLASSES_ROOT, + QString( s + "\\DefaultIcon" ).latin1() , + 0, KEY_READ, &k2 ); +#endif + if ( r == ERROR_SUCCESS ) { + s = getWindowsRegString( k2, 0 ); + } else { + cache[ key ] = defaultFile; + RegCloseKey( k2 ); + return &defaultFile; + } + RegCloseKey( k2 ); + + QStringList lst = QStringList::split( ",", s ); + + HICON si; + UINT res; + QString filepath = lst[ 0 ].stripWhiteSpace(); + if ( filepath.find("%1") != -1 ) { + filepath = filepath.arg( fi.filePath() ); + if ( ext.lower() == ".dll" ) { + pix = defaultFile; + return &pix; + } + } + +#ifdef Q_OS_TEMP + res = (UINT)ExtractIconEx( (LPCTSTR)qt_winTchar(filepath, TRUE), + lst[ 1 ].stripWhiteSpace().toInt(), + NULL, &si, 1 ); +#else + res = ExtractIconExA( filepath.latin1(), + lst[ 1 ].stripWhiteSpace().toInt(), + NULL, &si, 1 ); +#endif + + if ( res ) { + pix.resize( pixw, pixh ); + initPixmap( pix ); + QPainter p( &pix ); + DrawIconEx( p.handle(), 0, 0, si, pixw, pixh, 0, NULL, DI_NORMAL ); + p.end(); + pix.setMask( pix.createHeuristicMask() ); + DestroyIcon( si ); + } else { + pix = defaultFile; + } + + cache[ key ] = pix; + return &pix; + } else { + HICON si; + UINT res; +#ifdef Q_OS_TEMP + res = (UINT)ExtractIconEx( (LPCTSTR)qt_winTchar(fi.absFilePath(), TRUE), + -1, + 0, 0, 1 ); +#else + res = ExtractIconExA( fi.absFilePath().latin1(), + -1, + 0, 0, 1 ); +#endif + + if ( res == 0 ) { + return &defaultExe; + } else { +#ifdef Q_OS_TEMP + res = (UINT)ExtractIconEx( (LPCTSTR)qt_winTchar(fi.absFilePath(), TRUE), + res - 1, + 0, &si, 1 ); +#else + res = ExtractIconExA( fi.absFilePath().latin1(), + res - 1, + 0, &si, 1 ); +#endif + } + + if ( res ) { + pix.resize( pixw, pixh ); + initPixmap( pix ); + QPainter p( &pix ); + DrawIconEx( p.handle(), 0, 0, si, pixw, pixh, 0, NULL, DI_NORMAL ); + p.end(); + pix.setMask( pix.createHeuristicMask() ); + DestroyIcon( si ); + } else { + pix = defaultExe; + } + + return &pix; + } + + // can't happen! + return 0; +} +#endif + + + +/*! + \reimp +*/ +bool QFileDialogP::eventFilter( QObject * o, QEvent * e ) +{ + if ( e->type() == QEvent::KeyPress && ( (QKeyEvent*)e )->key() == Key_F5 ) { + rereadDir(); + ((QKeyEvent *)e)->accept(); + return TRUE; + } else if ( e->type() == QEvent::KeyPress && ( (QKeyEvent*)e )->key() == Key_F2 && + ( o == files || o == files->viewport() ) ) { + if ( files->isVisible() && files->currentItem() ) { + if ( mode() != QFileDialogP::ExistingFiles && + QUrlInfo( d->url, "." ).isWritable() && files->currentItem()->text( 0 ) != ".." ) { + files->renameItem = files->currentItem(); + files->startRename( TRUE ); + } + } + ((QKeyEvent *)e)->accept(); + return TRUE; + } else if ( e->type() == QEvent::KeyPress && ( (QKeyEvent*)e )->key() == Key_F2 && + ( o == d->moreFiles || o == d->moreFiles->viewport() ) ) { + if ( d->moreFiles->isVisible() && d->moreFiles->currentItem() != -1 ) { + if ( mode() != QFileDialogP::ExistingFiles && + QUrlInfo( d->url, "." ).isWritable() && + d->moreFiles->item( d->moreFiles->currentItem() )->text() != ".." ) { + d->moreFiles->renameItem = d->moreFiles->item( d->moreFiles->currentItem() ); + d->moreFiles->startRename( TRUE ); + } + } + ((QKeyEvent *)e)->accept(); + return TRUE; + } else if ( e->type() == QEvent::KeyPress && d->moreFiles->renaming ) { + d->moreFiles->lined->setFocus(); + QApplication::sendEvent( d->moreFiles->lined, e ); + ((QKeyEvent *)e)->accept(); + return TRUE; + } else if ( e->type() == QEvent::KeyPress && files->renaming ) { + files->lined->setFocus(); + QApplication::sendEvent( files->lined, e ); + ((QKeyEvent *)e)->accept(); + return TRUE; + } else if ( e->type() == QEvent::KeyPress && + ((QKeyEvent *)e)->key() == Key_Backspace && + ( o == files || + o == d->moreFiles || + o == files->viewport() || + o == d->moreFiles->viewport() ) ) { + cdUpClicked(); + ((QKeyEvent *)e)->accept(); + return TRUE; + } else if ( e->type() == QEvent::KeyPress && + ((QKeyEvent *)e)->key() == Key_Delete && + ( o == files || + o == files->viewport() ) ) { + if ( files->currentItem() ) + deleteFile( files->currentItem()->text( 0 ) ); + ((QKeyEvent *)e)->accept(); + return TRUE; + } else if ( e->type() == QEvent::KeyPress && + ((QKeyEvent *)e)->key() == Key_Delete && + ( o == d->moreFiles || + o == d->moreFiles->viewport() ) ) { + int c = d->moreFiles->currentItem(); + if ( c >= 0 ) + deleteFile( d->moreFiles->item( c )->text() ); + ((QKeyEvent *)e)->accept(); + return TRUE; + } else if ( o == files && e->type() == QEvent::FocusOut && + files->currentItem() && mode() != ExistingFiles ) { + } else if ( o == files && e->type() == QEvent::KeyPress ) { + QTimer::singleShot( 0, this, SLOT(fixupNameEdit()) ); + } else if ( o == nameEdit && e->type() == QEvent::KeyPress ) { + if ( ( nameEdit->cursorPosition() == (int)nameEdit->text().length() || nameEdit->hasSelectedText() ) && + isprint(((QKeyEvent *)e)->ascii()) ) { +#if defined(_WS_WIN_) + QString nt( nameEdit->text().lower() ); +#else + QString nt( nameEdit->text() ); +#endif + nt.truncate( nameEdit->cursorPosition() ); + nt += (char)(((QKeyEvent *)e)->ascii()); + QListViewItem * i = files->firstChild(); +#if defined(_WS_WIN_) + while( i && i->text( 0 ).left(nt.length()).lower() != nt ) +#else + while( i && i->text( 0 ).left(nt.length()) != nt ) +#endif + i = i->nextSibling(); + if ( i ) { + nt = i->text( 0 ); + int cp = nameEdit->cursorPosition()+1; + nameEdit->validateAndSet( nt, cp, cp, nt.length() ); + return TRUE; + } + } + } else if ( o == nameEdit && e->type() == QEvent::FocusIn ) { + fileNameEditDone(); + } else if ( d->moreFiles->renaming && o != d->moreFiles->lined && e->type() == QEvent::FocusIn ) { + d->moreFiles->lined->setFocus(); + return TRUE; + } else if ( files->renaming && o != files->lined && e->type() == QEvent::FocusIn ) { + files->lined->setFocus(); + return TRUE; + } else if ( ( o == d->moreFiles || o == d->moreFiles->viewport() ) && + e->type() == QEvent::FocusIn ) { + if ( o == d->moreFiles->viewport() && !d->moreFiles->viewport()->hasFocus() || + o == d->moreFiles && !d->moreFiles->hasFocus() ) + ((QWidget*)o)->setFocus(); + return FALSE; + } + + return QDialog::eventFilter( o, e ); +} + +/*! + Sets the filters used in the file dialog to \a filters. Each group + of filters must be separated by \c{;;} (\e two semi-colons). + + \code + QString types("*.png;;*.xpm;;*.jpg"); + QFileDialogP fd = new QFileDialogP( this ); + fd->setFilters( types ); + fd->show(); + \endcode + +*/ + +void QFileDialogP::setFilters( const QString &filters ) +{ + QStringList lst = makeFiltersList( filters ); + setFilters( lst ); +} + +/*! + \overload + + \a types must be a null-terminated list of strings. + +*/ + +void QFileDialogP::setFilters( const char ** types ) +{ + if ( !types || !*types ) + return; + + d->types->clear(); + while( types && *types ) { + d->types->insertItem( QString::fromLatin1(*types) ); + types++; + } + d->types->setCurrentItem( 0 ); + setFilter( d->types->text( 0 ) ); +} + + +/*! \overload void QFileDialogP::setFilters( const QStringList & ) +*/ + +void QFileDialogP::setFilters( const QStringList & types ) +{ + if ( types.count() < 1 ) + return; + + d->types->clear(); + for ( QStringList::ConstIterator it = types.begin(); it != types.end(); ++it ) + d->types->insertItem( *it ); + d->types->setCurrentItem( 0 ); + setFilter( d->types->text( 0 ) ); +} + +/*! + Adds the filter \a filter to the list of filters and makes it the + current filter. + + \code + QFileDialogP* fd = new QFileDialogP( this ); + fd->addFilter( "Images (*.png *.jpg *.xpm)" ); + fd->show(); + \endcode + + In the above example, a file dialog is created, and the file filter "Images + (*.png *.jpg *.xpm)" is added and is set as the current filter. The original + filter, "All Files (*)", is still available. + + \sa setFilter(), setFilters() +*/ + +void QFileDialogP::addFilter( const QString &filter ) +{ + if ( filter.isEmpty() ) + return; + QString f = filter; + QRegExp r( QString::fromLatin1(qt_file_dialog_filter_reg_exp) ); + int index = r.search( f ); + if ( index >= 0 ) + f = r.cap( 2 ); + for ( int i = 0; i < d->types->count(); ++i ) { + QString f2( d->types->text( i ) ); + int index = r.search( f2 ); + if ( index >= 0 ) + f2 = r.cap( 1 ); + if ( f2 == f ) { + d->types->setCurrentItem( i ); + setFilter( f2 ); + return; + } + } + + d->types->insertItem( filter ); + d->types->setCurrentItem( d->types->count() - 1 ); + setFilter( d->types->text( d->types->count() - 1 ) ); +} + +/*! + Since modeButtons is a top-level widget, it may be destroyed by the + kernel at application exit. Notice if this happens to + avoid double deletion. +*/ + +void QFileDialogP::modeButtonsDestroyed() +{ + if ( d ) + d->modeButtons = 0; +} + + +/*! + This is a convenience static function that will return one or more + existing files selected by the user. + + \code + QStringList files = QFileDialogP::getOpenFileNames( + "Images (*.png *.xpm *.jpg)", + "/home", + this, + "open files dialog" + "Select one or more files to open" ); + \endcode + + This function creates a modal file dialog called \a name, with + parent \a parent. If \a parent is not 0, the dialog will be shown + centered over the parent. + + The file dialog's working directory will be set to \a dir. If \a + dir includes a file name, the file will be selected. The filter + is set to \a filter so that only those files which match the filter + are shown. The filter selected is set to \a selectedFilter. The parameters + \a dir, \a selectedFilter and \a filter may be QString::null. + + The dialog's caption is set to \a caption. If \a caption is not + specified then a default caption will be used. + + Under Windows and Mac OS X, this static function will use the native + file dialog and not a QFileDialogP, unless the style of the application + is set to something other than the native style. + + Under Unix/X11, the normal behavior of the file dialog is to resolve + and follow symlinks. For example, if /usr/tmp is a symlink to /var/tmp, + the file dialog will change to /var/tmp after entering /usr/tmp. + If \a resolveSymlinks is FALSE, the file dialog will treat + symlinks as regular directories. + + Note that if you want to iterate over the list of files, you should + iterate over a copy, e.g. + \code + QStringList list = files; + QStringList::Iterator it = list.begin(); + while( it != list.end() ) { + myProcessing( *it ); + ++it; + } + \endcode + + \sa getOpenFileName(), getSaveFileName(), getExistingDirectory() +*/ + +QStringList QFileDialogP::getOpenFileNames( const QString & filter, + const QString& dir, + QWidget *parent, + const char* name, + const QString& caption, + QString *selectedFilter, + bool resolveSymlinks ) +{ + bool save_qt_resolve_symlinks = qt_resolve_symlinks; + qt_resolve_symlinks = resolveSymlinks; + + QStringList filters; + if ( !filter.isEmpty() ) + filters = makeFiltersList( filter ); + + makeVariables(); + + if ( workingDirectory->isNull() ) + *workingDirectory = QDir::currentDirPath(); + + if ( !dir.isEmpty() ) { + // #### works only correct for local files + QUrlOperator u( dir ); + if ( u.isLocalFile() && QFileInfo( u ).isDir() ) { + *workingDirectory = dir; + } else { + *workingDirectory = u.toString(); + } + } + +#if defined(Q_WS_WIN) + if ( qApp->style().styleHint( QStyle::SH_GUIStyle ) == WindowsStyle ) + return winGetOpenFileNames( filter, workingDirectory, parent, name, caption, selectedFilter ); +#elif defined(Q_WS_MAC) + if( ( qApp->style().inherits(QMAC_DEFAULT_STYLE) ) ) + return macGetOpenFileNames(filter, workingDirectory, parent, name, caption ); +#endif + + QFileDialogP *dlg = new QFileDialogP( *workingDirectory, QString::null, parent, name ? name : "qt_filedlg_gofns", TRUE ); + + Q_CHECK_PTR( dlg ); +#ifndef QT_NO_WIDGET_TOPEXTRA + if ( parent && parent->icon() && !parent->icon()->isNull() ) + dlg->setIcon( *parent->icon() ); + else if ( qApp->mainWidget() && qApp->mainWidget()->icon() && !qApp->mainWidget()->icon()->isNull() ) + dlg->setIcon( *qApp->mainWidget()->icon() ); +#endif + + dlg->setFilters( filters ); + if ( selectedFilter ) + dlg->setFilter( *selectedFilter ); +#ifndef QT_NO_WIDGET_TOPEXTRA + if ( !caption.isNull() ) + dlg->setCaption( caption ); + else + dlg->setCaption( QFileDialogP::tr("Open") ); +#endif + dlg->setMode( QFileDialogP::ExistingFiles ); + QString result; + QStringList lst; + if ( dlg->exec() == QDialog::Accepted ) { + lst = dlg->selectedFiles(); + *workingDirectory = dlg->d->url; + if ( selectedFilter ) + *selectedFilter = dlg->selectedFilter(); + } + delete dlg; + + qt_resolve_symlinks = save_qt_resolve_symlinks; + + return lst; +} + +/*! Updates the line edit to match the speed-key usage in QListView. */ + +void QFileDialogP::fixupNameEdit() +{ + if ( files->currentItem() && d->mode != ExistingFiles ) { + if ( ( (QFileDialogPrivate::File*)files->currentItem() )->info.isFile() ) + nameEdit->setText( files->currentItem()->text( 0 ) ); + } +} + +/*! + Returns the URL of the current working directory in the file dialog. + + \sa setUrl() +*/ + +QUrl QFileDialogP::url() const +{ + return d->url; +} + +static bool isRoot( const QUrl &u ) +{ +#if defined(Q_OS_MAC9) + QString p = QDir::convertSeparators(u.path()); + if(p.contains(':') == 1) + return TRUE; +#elif defined(Q_OS_UNIX) + if ( u.path() == "/" ) + return TRUE; +#elif defined(Q_OS_WIN32) + QString p = u.path(); + if ( p.length() == 3 && + p.right( 2 ) == ":/" ) + return TRUE; + if ( p[ 0 ] == '/' && p[ 1 ] == '/' ) { + int slashes = p.contains( '/' ); + if ( slashes <= 3 ) + return TRUE; + if ( slashes == 4 && p[ (int)p.length() - 1 ] == '/' ) + return TRUE; + } +#else +#if defined(Q_CC_GNU) +#warning "case not covered.." +#endif +#endif + + if ( !u.isLocalFile() && u.path() == "/" ) + return TRUE; + + return FALSE; +} + +void QFileDialogP::urlStart( QNetworkOperation *op ) +{ + if ( !op ) + return; + + if ( op->operation() == QNetworkProtocol::OpListChildren ) { + if ( isRoot( d->url ) ) + d->cdToParent->setEnabled( FALSE ); + else + d->cdToParent->setEnabled( TRUE ); + d->mimeTypeTimer->stop(); + d->sortedList.clear(); + d->pendingItems.clear(); + d->moreFiles->clearSelection(); + files->clearSelection(); + d->moreFiles->clear(); + files->clear(); + files->setSorting( -1 ); + + QString s = d->url.toString( FALSE, FALSE ); + bool found = FALSE; + for ( int i = 0; i < d->paths->count(); ++i ) { +#if defined(Q_WS_WIN) + if ( d->paths->text( i ).lower() == s.lower() ) { +#else + if ( d->paths->text( i ) == s ) { +#endif + found = TRUE; + d->paths->setCurrentItem( i ); + break; + } + } + if ( !found ) { + d->paths->insertItem( *openFolderIcon, s, -1 ); + d->paths->setCurrentItem( d->paths->count() - 1 ); + } + d->last = 0; + d->hadDotDot = FALSE; + + if ( d->goBack && d->history.last() != d->url.toString() ) { + d->history.append( d->url.toString() ); + if ( d->history.count() > 1 ) + d->goBack->setEnabled( TRUE ); + } + } +} + +void QFileDialogP::urlFinished( QNetworkOperation *op ) +{ + if ( !op ) + return; + + if ( op->operation() == QNetworkProtocol::OpListChildren ) { + if ( QApplication::overrideCursor() ) + QApplication::restoreOverrideCursor(); + } + if ( op->state() == QNetworkProtocol::StFailed ) { + if ( d->paths->hasFocus() ) + d->ignoreNextKeyPress = TRUE; + + if ( d->progressDia ) { + d->ignoreStop = TRUE; + d->progressDia->close(); + delete d->progressDia; + d->progressDia = 0; + } + + QMessageBox::critical( this, tr( "Error" ), op->protocolDetail() ); + + int ecode = op->errorCode(); + if ( ecode == QNetworkProtocol::ErrListChildren || ecode == QNetworkProtocol::ErrParse || + ecode == QNetworkProtocol::ErrUnknownProtocol || ecode == QNetworkProtocol::ErrLoginIncorrect || + ecode == QNetworkProtocol::ErrValid || ecode == QNetworkProtocol::ErrHostNotFound || + ecode == QNetworkProtocol::ErrFileNotExisting ) { + if (d->url != d->oldUrl) { + QString nf = d->url.nameFilter(); + d->url = d->oldUrl; + d->url.setNameFilter( nf ); + rereadDir(); + } + } else { + // another error happened, no need to go back to last dir + } + } else if ( op->operation() == QNetworkProtocol::OpListChildren && + op == d->currListChildren ) { + if ( !d->hadDotDot && !isRoot( d->url ) ) { + bool ok = TRUE; +#if defined(Q_WS_WIN) + if ( d->url.path().left( 2 ) == "//" ) + ok = FALSE; +#endif + if ( ok ) { + QUrlInfo ui( d->url, ".." ); + ui.setName( ".." ); + ui.setDir( TRUE ); + ui.setFile( FALSE ); + ui.setSymLink( FALSE ); + ui.setSize( 0 ); + QValueList lst; + lst << ui; + insertEntry( lst, 0 ); + } + } + resortDir(); + } else if ( op->operation() == QNetworkProtocol::OpGet ) { + } else if ( op->operation() == QNetworkProtocol::OpPut ) { + rereadDir(); + if ( d->progressDia ) { + d->ignoreStop = TRUE; + d->progressDia->close(); + } + delete d->progressDia; + d->progressDia = 0; + } +} + +void QFileDialogP::dataTransferProgress( int bytesDone, int bytesTotal, QNetworkOperation *op ) +{ + if ( !op ) + return; + + QString label; + QUrl u( op->arg( 0 ) ); + if ( u.isLocalFile() ) { + label = u.path(); + } else { + label = QString( "%1 (on %2)" ); + label = label.arg( u.path() ).arg( u.host() ); + } + + if ( !d->progressDia ) { + if ( bytesDone < bytesTotal) { + d->ignoreStop = FALSE; + d->progressDia = new QFDProgressDialog( this, label, bytesTotal ); + connect( d->progressDia, SIGNAL( cancelled() ), + this, SLOT( stopCopy() ) ); + d->progressDia->show(); + } else + return; + } + + if ( d->progressDia ) { + if ( op->operation() == QNetworkProtocol::OpGet ) { + if ( d->progressDia ) { + d->progressDia->setReadProgress( bytesDone ); + } + } else if ( op->operation() == QNetworkProtocol::OpPut ) { + if ( d->progressDia ) { + d->progressDia->setWriteLabel( label ); + d->progressDia->setWriteProgress( bytesDone ); + } + } else { + return; + } + } +} + +void QFileDialogP::insertEntry( const QValueList &lst, QNetworkOperation *op ) +{ + if ( op && op->operation() == QNetworkProtocol::OpListChildren && + op != d->currListChildren ) + return; + QValueList::ConstIterator it = lst.begin(); + for ( ; it != lst.end(); ++it ) { + const QUrlInfo &inf = *it; + if ( d->mode == DirectoryOnly && !inf.isDir() ) + continue; + if ( inf.name() == ".." ) { + d->hadDotDot = TRUE; + if ( isRoot( d->url ) ) + continue; +#if defined(Q_WS_WIN) + if ( d->url.path().left( 2 ) == "//" ) + continue; +#endif + } else if ( inf.name() == "." ) + continue; + +#if defined(Q_WS_WIN) + if ( !bShowHiddenFiles ) { + if ( d->url.isLocalFile() ) { + QString file = d->url.path() + inf.name(); +#if defined(UNICODE) + if ( qWinVersion() & Qt::WV_NT_based ) { + if ( GetFileAttributesW( (TCHAR*)qt_winTchar( file, TRUE ) ) & FILE_ATTRIBUTE_HIDDEN ) + continue; + } + else +#endif + { + if ( GetFileAttributesA( file.local8Bit() ) & FILE_ATTRIBUTE_HIDDEN ) + continue; + } + } else { + if ( inf.name() != ".." && inf.name()[0] == QChar('.') ) + continue; + } + } +#else + if ( !bShowHiddenFiles && inf.name() != ".." ) { + if ( inf.name()[ 0 ] == QChar( '.' ) ) + continue; + } + +#endif + if ( !d->url.isLocalFile() ) { + QFileDialogPrivate::File * i = 0; + QFileDialogPrivate::MCItem *i2 = 0; + i = new QFileDialogPrivate::File( d, &inf, files ); + i2 = new QFileDialogPrivate::MCItem( d->moreFiles, i ); + + if ( d->mode == ExistingFiles && inf.isDir() || + ( isDirectoryMode( d->mode ) && inf.isFile() ) ) { + i->setSelectable( FALSE ); + i2->setSelectable( FALSE ); + } + + i->i = i2; + } + + d->sortedList.append( new QUrlInfo( inf ) ); + } +} + +void QFileDialogP::removeEntry( QNetworkOperation *op ) +{ + if ( !op ) + return; + + QUrlInfo *i = 0; + QListViewItemIterator it( files ); + bool ok1 = FALSE, ok2 = FALSE; + for ( i = d->sortedList.first(); it.current(); ++it, i = d->sortedList.next() ) { + if ( ( (QFileDialogPrivate::File*)it.current() )->info.name() == op->arg( 0 ) ) { + d->pendingItems.removeRef( (QFileDialogPrivate::File*)it.current() ); + delete ( (QFileDialogPrivate::File*)it.current() )->i; + delete it.current(); + ok1 = TRUE; + } + if ( i && i->name() == op->arg( 0 ) ) { + d->sortedList.removeRef( i ); + i = d->sortedList.prev(); + ok2 = TRUE; + } + if ( ok1 && ok2 ) + break; + } +} + +void QFileDialogP::itemChanged( QNetworkOperation *op ) +{ + if ( !op ) + return; + + QUrlInfo *i = 0; + QListViewItemIterator it1( files ); + bool ok1 = FALSE, ok2 = FALSE; + // first check whether the new file replaces an existing file. + for ( i = d->sortedList.first(); it1.current(); ++it1, i = d->sortedList.next() ) { + if ( ( (QFileDialogPrivate::File*)it1.current() )->info.name() == op->arg( 1 ) ) { + delete ( (QFileDialogPrivate::File*)it1.current() )->i; + delete it1.current(); + ok1 = TRUE; + } + if ( i && i->name() == op->arg( 1 ) ) { + d->sortedList.removeRef( i ); + i = d->sortedList.prev(); + ok2 = TRUE; + } + if ( ok1 && ok2 ) + break; + } + + i = 0; + QListViewItemIterator it( files ); + ok1 = FALSE; + ok2 = FALSE; + for ( i = d->sortedList.first(); it.current(); ++it, i = d->sortedList.next() ) { + if ( ( (QFileDialogPrivate::File*)it.current() )->info.name() == op->arg( 0 ) ) { + ( (QFileDialogPrivate::File*)it.current() )->info.setName( op->arg( 1 ) ); + ok1 = TRUE; + } + if ( i && i->name() == op->arg( 0 ) ) { + i->setName( op->arg( 1 ) ); + ok2 = TRUE; + } + if ( ok1 && ok2 ) + break; + } + + resortDir(); +} + +/*! + \property QFileDialogP::infoPreview + + \brief whether the file dialog can provide preview information about + the currently selected file + + The default is FALSE. +*/ +bool QFileDialogP::isInfoPreviewEnabled() const +{ + return d->infoPreview; +} + +void QFileDialogP::setInfoPreviewEnabled( bool info ) +{ + if ( info == d->infoPreview ) + return; + d->geometryDirty = TRUE; + d->infoPreview = info; + updateGeometries(); +} + + +/*! + \property QFileDialogP::contentsPreview + + \brief whether the file dialog can provide a contents preview of the + currently selected file + + The default is FALSE. + + \sa setContentsPreview() setInfoPreviewEnabled() +*/ +// ### improve the above documentation: how is the preview done, how can I add +// support for customized preview, etc. + +bool QFileDialogP::isContentsPreviewEnabled() const +{ + return d->contentsPreview; +} + +void QFileDialogP::setContentsPreviewEnabled( bool contents ) +{ + if ( contents == d->contentsPreview ) + return; + d->geometryDirty = TRUE; + d->contentsPreview = contents; + updateGeometries(); +} + + +/*! + Sets the widget to be used for displaying information about the file + to the widget \a w and a preview of that information to the + QFilePreviewP \a preview. + + Normally you would create a preview widget that derives from both QWidget and + QFilePreviewP, so you should pass the same widget twice. + + \code + class Preview : public QLabel, public QFilePreviewP + { + public: + Preview( QWidget *parent=0 ) : QLabel( parent ) {} + + void previewUrl( const QUrl &u ) + { + QString path = u.path(); + QPixmap pix( path ); + if ( pix.isNull() ) + setText( "This is not a pixmap" ); + else + setText( "This is a pixmap" ); + } + }; + + //... + + int main( int argc, char** argv ) + { + Preview* p = new Preview; + + QFileDialogP* fd = new QFileDialogP( this ); + fd->setInfoPreviewEnabled( TRUE ); + fd->setInfoPreview( p, p ); + fd->setPreviewMode( QFileDialogP::Info ); + fd->show(); + } + + \endcode + + \sa setContentsPreview(), setInfoPreviewEnabled(), setPreviewMode() + +*/ + +void QFileDialogP::setInfoPreview( QWidget *w, QFilePreviewP *preview ) +{ + if ( !w || !preview ) + return; + + if ( d->infoPreviewWidget ) { + d->preview->removeWidget( d->infoPreviewWidget ); + delete d->infoPreviewWidget; + } + if ( d->infoPreviewer ) + delete d->infoPreviewer; + d->infoPreviewWidget = w; + d->infoPreviewer = preview; + w->reparent( d->preview, 0, QPoint( 0, 0 ) ); +} + +/*! + Sets the widget to be used for displaying the contents of the file + to the widget \a w and a preview of those contents to the + QFilePreviewP \a preview. + + Normally you would create a preview widget that derives from both QWidget and + QFilePreviewP, so you should pass the same widget twice. + + \code + class Preview : public QLabel, public QFilePreviewP + { + public: + Preview( QWidget *parent=0 ) : QLabel( parent ) {} + + void previewUrl( const QUrl &u ) + { + QString path = u.path(); + QPixmap pix( path ); + if ( pix.isNull() ) + setText( "This is not a pixmap" ); + else + setPixmap( pix ); + } + }; + + //... + + int main( int argc, char** argv ) + { + Preview* p = new Preview; + + QFileDialogP* fd = new QFileDialogP( this ); + fd->setContentsPreviewEnabled( TRUE ); + fd->setContentsPreview( p, p ); + fd->setPreviewMode( QFileDialogP::Contents ); + fd->show(); + } + \endcode + + \sa setContentsPreviewEnabled(), setInfoPreview(), setPreviewMode() +*/ + +void QFileDialogP::setContentsPreview( QWidget *w, QFilePreviewP *preview ) +{ + if ( !w || !preview ) + return; + + if ( d->contentsPreviewWidget ) { + d->preview->removeWidget( d->contentsPreviewWidget ); + delete d->contentsPreviewWidget; + } + if ( d->contentsPreviewer ) + delete d->contentsPreviewer; + d->contentsPreviewWidget = w; + d->contentsPreviewer = preview; + w->reparent( d->preview, 0, QPoint( 0, 0 ) ); +} + +/*! + Re-sorts the displayed directory. + + \sa rereadDir() +*/ + +void QFileDialogP::resortDir() +{ + d->mimeTypeTimer->stop(); + d->pendingItems.clear(); + + QFileDialogPrivate::File *item = 0; + QFileDialogPrivate::MCItem *item2 = 0; + + d->sortedList.sort(); + + if ( files->childCount() > 0 || d->moreFiles->count() > 0 ) { + d->moreFiles->clear(); + files->clear(); + d->last = 0; + files->setSorting( -1 ); + } + + QUrlInfo *i = sortAscending ? d->sortedList.first() : d->sortedList.last(); + for ( ; i; i = sortAscending ? d->sortedList.next() : d->sortedList.prev() ) { + item = new QFileDialogPrivate::File( d, i, files ); + item2 = new QFileDialogPrivate::MCItem( d->moreFiles, item, item2 ); + item->i = item2; + d->pendingItems.append( item ); + if ( d->mode == ExistingFiles && item->info.isDir() || + ( isDirectoryMode( d->mode ) && item->info.isFile() ) ) { + item->setSelectable( FALSE ); + item2->setSelectable( FALSE ); + } + } + + // ##### As the QFileIconProviderP only support QFileInfo and no + // QUrlInfo it can be only used for local files at the moment. In + // 3.0 we have to change the API of QFileIconProviderP to work on + // QUrlInfo so that also remote filesystems can be show mime-type + // specific icons. + if ( d->url.isLocalFile() ) + d->mimeTypeTimer->start( 0 ); +} + +/*! + Stops the current copy operation. +*/ + +void QFileDialogP::stopCopy() +{ + if ( d->ignoreStop ) + return; + + d->url.blockSignals( TRUE ); + d->url.stop(); + if ( d->progressDia ) { + d->ignoreStop = TRUE; + QTimer::singleShot( 100, this, SLOT( removeProgressDia() ) ); + } + d->url.blockSignals( FALSE ); +} + +/*! + \internal +*/ + +void QFileDialogP::removeProgressDia() +{ + if ( d->progressDia ) + delete d->progressDia; + d->progressDia = 0; +} + +/*! + \internal +*/ + +void QFileDialogP::doMimeTypeLookup() +{ + if ( !iconProvider() ) { + d->pendingItems.clear(); + d->mimeTypeTimer->stop(); + return; + } + + d->mimeTypeTimer->stop(); + if ( d->pendingItems.count() == 0 ) { + return; + } + + QRect r; + QFileDialogPrivate::File *item = d->pendingItems.first(); + if ( item ) { + QFileInfo fi; + if ( d->url.isLocalFile() ) { + fi.setFile( QUrl( d->url.path(), QFileDialogPrivate::encodeFileName( item->info.name() ) ).path( FALSE ) ); + } else + fi.setFile( item->info.name() ); // ##### + const QPixmap *p = iconProvider()->pixmap( fi ); + if ( p && p != item->pixmap( 0 ) && + ( !item->pixmap( 0 ) || p->serialNumber() != item->pixmap( 0 )->serialNumber() ) && + p != fifteenTransparentPixels ) { + item->hasMimePixmap = TRUE; + + // evil hack to avoid much too much repaints! + qApp->processEvents(); + files->setUpdatesEnabled( FALSE ); + files->viewport()->setUpdatesEnabled( FALSE ); + if ( item != d->pendingItems.first() ) + return; + item->setPixmap( 0, *p ); + qApp->processEvents(); + files->setUpdatesEnabled( TRUE ); + files->viewport()->setUpdatesEnabled( TRUE ); + + if ( files->isVisible() ) { + QRect ir( files->itemRect( item ) ); + if ( ir != QRect( 0, 0, -1, -1 ) ) { + r = r.unite( ir ); + } + } else { + QRect ir( d->moreFiles->itemRect( item->i ) ); + if ( ir != QRect( 0, 0, -1, -1 ) ) { + r = r.unite( ir ); + } + } + } + if ( d->pendingItems.count() ) + d->pendingItems.removeFirst(); + } + + if ( d->moreFiles->isVisible() ) { + d->moreFiles->viewport()->repaint( r, FALSE ); + } else { + files->viewport()->repaint( r, FALSE ); + } + + if ( d->pendingItems.count() ) + d->mimeTypeTimer->start( 0 ); + else if ( d->moreFiles->isVisible() ) + d->moreFiles->triggerUpdate( TRUE ); +} + +/*! + If \a b is TRUE then all the files in the current directory are selected; + otherwise, they are deselected. +*/ + +void QFileDialogP::selectAll( bool b ) +{ + if ( d->mode != ExistingFiles ) + return; + d->moreFiles->selectAll( b ); + files->selectAll( b ); +} + +void QFileDialogP::goBack() +{ + if ( !d->goBack || !d->goBack->isEnabled() ) + return; + d->history.remove( d->history.last() ); + if ( d->history.count() < 2 ) + d->goBack->setEnabled( FALSE ); + setUrl( d->history.last() ); +} + +// a class with wonderfully inflexible flexibility. why doesn't it +// just subclass QWidget in the first place? 'you have to derive your +// preview widget from QWidget and from this class' indeed. + +/*! + \class QFilePreviewP qfiledialog.h + \ingroup misc + \brief The QFilePreviewP class provides file previewing in QFileDialogP. + + This class is an abstract base class which is used to implement + widgets that can display a preview of a file in a QFileDialogP. + + You must derive the preview widget from both QWidget and from this + class. Then you must reimplement this class's previewUrl() function, + which is called by the file dialog if the preview of a file + (specified as a URL) should be shown. + + See also QFileDialog::setPreviewMode(), QFileDialogP::setContentsPreview(), + QFileDialogP::setInfoPreview(), QFileDialogP::setInfoPreviewEnabled(), + QFileDialogP::setContentsPreviewEnabled(). + + For an example of a preview widget see qt/examples/qdir/qdir.cpp. +*/ + +/*! + Constructs the QFilePreviewP. +*/ + +QFilePreviewP::QFilePreviewP() +{ +} + +/*! + \fn void QFilePreviewP::previewUrl( const QUrl &url ) + + This function is called by QFileDialogP if a preview + for the \a url should be shown. Reimplement this + function to provide file previewing. +*/ + +#endif diff --git a/src/PatchQt/qfiledialogP.h b/src/PatchQt/qfiledialogP.h new file mode 100644 index 000000000..f7355a193 --- /dev/null +++ b/src/PatchQt/qfiledialogP.h @@ -0,0 +1,528 @@ +///////////////////////////////////////////////////////////////////////////// +// Module : PatchQt +// File : qfiledialogP.h +// Description : the patch for Qt's QFileDialog class (qfiledialog.h) +///////////////////////////////////////////////////////////////////////////// + +/**************************************************************************** +** $Id$ +** +** Definition of QFileDialog class +** +** Created : 950428 +** +** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** +** This file is part of the dialogs module of the Qt GUI Toolkit. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef QFILEDIALOGP_H +#define QFILEDIALOGP_H + +class QPushButton; +class QButton; +class QLabel; +class QWidget; +class QFileDialog; +class QTimer; +class QNetworkOperation; +class QLineEdit; +class QListViewItem; +class QListBoxItem; +class QProgressBar; +class QFileDialogPrivate; +class QFileDialogQFileListView; + +#ifndef QT_H +#include "qdir.h" +#include "qdialog.h" +#include "qurloperator.h" +#include "qurlinfo.h" +#include "qlistbox.h" +#include "qlistview.h" +#include "qlineedit.h" +#endif // QT_H + +#ifndef QT_NO_FILEDIALOG + +class Q_EXPORT QFileIconProviderP : public QObject +{ + Q_OBJECT +public: + QFileIconProviderP( QObject * parent = 0, const char* name = 0 ); + virtual const QPixmap * pixmap( const QFileInfo & ); + +private: // Disabled copy constructor and operator= +#if defined(Q_DISABLE_COPY) + QFileIconProviderP( const QFileIconProviderP & ); + QFileIconProviderP& operator=( const QFileIconProviderP & ); +#endif +}; + +class Q_EXPORT QFilePreviewP +{ +public: + QFilePreviewP(); + virtual void previewUrl( const QUrl &url ) = 0; + +}; + +class Q_EXPORT QFileDialogP : public QDialog +{ + Q_OBJECT + Q_ENUMS( Mode ViewMode PreviewMode ) + // ##### Why are this read-only properties ? + Q_PROPERTY( QString selectedFile READ selectedFile ) + Q_PROPERTY( QString selectedFilter READ selectedFilter ) + Q_PROPERTY( QStringList selectedFiles READ selectedFiles ) + // #### Should not we be able to set the path ? + Q_PROPERTY( QString dirPath READ dirPath ) + Q_PROPERTY( bool showHiddenFiles READ showHiddenFiles WRITE setShowHiddenFiles ) + Q_PROPERTY( Mode mode READ mode WRITE setMode ) + Q_PROPERTY( ViewMode viewMode READ viewMode WRITE setViewMode ) + Q_PROPERTY( PreviewMode previewMode READ previewMode WRITE setPreviewMode ) + Q_PROPERTY( bool infoPreview READ isInfoPreviewEnabled WRITE setInfoPreviewEnabled ) + Q_PROPERTY( bool contentsPreview READ isContentsPreviewEnabled WRITE setContentsPreviewEnabled ) + +public: + QFileDialogP( const QString& dirName, const QString& filter = QString::null, + QWidget* parent=0, const char* name=0, bool modal = FALSE ); + QFileDialogP( QWidget* parent=0, const char* name=0, bool modal = FALSE ); + ~QFileDialogP(); + + // recommended static functions + + static QString getOpenFileName( const QString &initially = QString::null, + const QString &filter = QString::null, + QWidget *parent = 0, const char* name = 0, + const QString &caption = QString::null, + QString *selectedFilter = 0, + bool resolveSymlinks = TRUE); + static QString getSaveFileName( const QString &initially = QString::null, + const QString &filter = QString::null, + QWidget *parent = 0, const char* name = 0, + const QString &caption = QString::null, + QString *selectedFilter = 0, + bool resolveSymlinks = TRUE); + static QString getExistingDirectory( const QString &dir = QString::null, + QWidget *parent = 0, + const char* name = 0, + const QString &caption = QString::null, + bool dirOnly = TRUE, + bool resolveSymlinks = TRUE); + static QStringList getOpenFileNames( const QString &filter= QString::null, + const QString &dir = QString::null, + QWidget *parent = 0, + const char* name = 0, + const QString &caption = QString::null, + QString *selectedFilter = 0, + bool resolveSymlinks = TRUE); + + // other static functions + + static void setIconProvider( QFileIconProviderP * ); + static QFileIconProviderP* iconProvider(); + + // non-static function for special needs + + QString selectedFile() const; + QString selectedFilter() const; + virtual void setSelectedFilter( const QString& ); + virtual void setSelectedFilter( int ); + + void setSelection( const QString &); + + void selectAll( bool b ); + + QStringList selectedFiles() const; + + QString dirPath() const; + + void setDir( const QDir & ); + const QDir *dir() const; + + void setShowHiddenFiles( bool s ); + bool showHiddenFiles() const; + + void rereadDir(); + void resortDir(); + + enum Mode { AnyFile, ExistingFile, Directory, ExistingFiles, DirectoryOnly }; + void setMode( Mode ); + Mode mode() const; + + enum ViewMode { Detail, List }; + enum PreviewMode { NoPreview, Contents, Info }; + void setViewMode( ViewMode m ); + ViewMode viewMode() const; + void setPreviewMode( PreviewMode m ); + PreviewMode previewMode() const; + + bool eventFilter( QObject *, QEvent * ); + + bool isInfoPreviewEnabled() const; + bool isContentsPreviewEnabled() const; + void setInfoPreviewEnabled( bool ); + void setContentsPreviewEnabled( bool ); + + void setInfoPreview( QWidget *w, QFilePreviewP *preview ); + void setContentsPreview( QWidget *w, QFilePreviewP *preview ); + + QUrl url() const; + + void addFilter( const QString &filter ); + +public slots: + void done( int ); + void setDir( const QString& ); + void setUrl( const QUrlOperator &url ); + void setFilter( const QString& ); + void setFilters( const QString& ); + void setFilters( const char ** ); + void setFilters( const QStringList& ); + +protected: + void resizeEvent( QResizeEvent * ); + void keyPressEvent( QKeyEvent * ); + + void addWidgets( QLabel *, QWidget *, QPushButton * ); + void addToolButton( QButton *b, bool separator = FALSE ); + void addLeftWidget( QWidget *w ); + void addRightWidget( QWidget *w ); + +signals: + void fileHighlighted( const QString& ); + void fileSelected( const QString& ); + void filesSelected( const QStringList& ); + void dirEntered( const QString& ); + void filterSelected( const QString& ); + +private slots: + void detailViewSelectionChanged(); + void listBoxSelectionChanged(); + void changeMode( int ); + void fileNameEditReturnPressed(); + void stopCopy(); + void removeProgressDia(); + + void fileSelected( int ); + void fileHighlighted( int ); + void dirSelected( int ); + void pathSelected( int ); + + void updateFileNameEdit( QListViewItem *); + void selectDirectoryOrFile( QListViewItem * ); + void popupContextMenu( QListViewItem *, const QPoint &, int ); + void popupContextMenu( QListBoxItem *, const QPoint & ); + void updateFileNameEdit( QListBoxItem *); + void selectDirectoryOrFile( QListBoxItem * ); + void fileNameEditDone(); + + void okClicked(); + void filterClicked(); // not used + void cancelClicked(); + + void cdUpClicked(); + void newFolderClicked(); + + void fixupNameEdit(); + + void doMimeTypeLookup(); + + void updateGeometries(); + void modeButtonsDestroyed(); + void urlStart( QNetworkOperation *op ); + void urlFinished( QNetworkOperation *op ); + void dataTransferProgress( int bytesDone, int bytesTotal, QNetworkOperation * ); + void insertEntry( const QValueList &fi, QNetworkOperation *op ); + void removeEntry( QNetworkOperation * ); + void createdDirectory( const QUrlInfo &info, QNetworkOperation * ); + void itemChanged( QNetworkOperation * ); + void goBack(); + +private: + enum PopupAction { + PA_Open = 0, + PA_Delete, + PA_Rename, + PA_SortName, + PA_SortSize, + PA_SortType, + PA_SortDate, + PA_SortUnsorted, + PA_Cancel, + PA_Reload, + PA_Hidden + }; + + void init(); + bool trySetSelection( bool isDir, const QUrlOperator &, bool ); + void deleteFile( const QString &filename ); + void popupContextMenu( const QString &filename, bool withSort, + PopupAction &action, const QPoint &p ); + + QDir reserved; // was cwd + QString fileName; + + friend class QFileDialogQFileListView; + friend class QFileListBox; + + QFileDialogPrivate *d; + QFileDialogQFileListView *files; + + QLineEdit *nameEdit; // also filter + QPushButton *okB; + QPushButton *cancelB; + +#if defined(Q_WS_WIN) + static QString winGetOpenFileName( const QString &initialSelection, + const QString &filter, + QString* workingDirectory, + QWidget *parent = 0, + const char* name = 0, + const QString& caption = QString::null, + QString* selectedFilter = 0 ); + static QString winGetSaveFileName( const QString &initialSelection, + const QString &filter, + QString* workingDirectory, + QWidget *parent = 0, + const char* name = 0, + const QString& caption = QString::null, + QString* selectedFilter = 0 ); + static QStringList winGetOpenFileNames( const QString &filter, + QString* workingDirectory, + QWidget *parent = 0, + const char* name = 0, + const QString& caption = QString::null, + QString* selectedFilter = 0 ); + static QString winGetExistingDirectory( const QString &initialDirectory, + QWidget* parent = 0, + const char* name = 0, + const QString& caption = QString::null); + static QString resolveLinkFile( const QString& linkfile ); +#endif +#if defined(Q_WS_MACX) || defined(Q_WS_MAC9) + static QString macGetSaveFileName( const QString &, const QString &, + QString *, QWidget *, const char*, + const QString& ); + static QStringList macGetOpenFileNames( const QString &, QString*, + QWidget *, const char *, + const QString&, bool = TRUE, + bool = FALSE ); +#endif + + +private: // Disabled copy constructor and operator= +#if defined(Q_DISABLE_COPY) + QFileDialogP( const QFileDialogP & ); + QFileDialogP &operator=( const QFileDialogP & ); +#endif +}; + +/****************************************************************** + * + * Definitions of view classes + * + ******************************************************************/ + +class QRenameEdit : public QLineEdit +{ + Q_OBJECT + +public: + QRenameEdit( QWidget *parent ) + : QLineEdit( parent, "qt_rename_edit" ) + {} + +protected: + void keyPressEvent( QKeyEvent *e ); + void focusOutEvent( QFocusEvent *e ); + +signals: + void escapePressed(); + +}; + +class QFileListBox : public QListBox +{ + friend class QFileDialogP; + + Q_OBJECT + +private: + QFileListBox( QWidget *parent, QFileDialogP *d ); + + void clear(); + void show(); + void startRename( bool check = TRUE ); + void viewportMousePressEvent( QMouseEvent *e ); + void viewportMouseReleaseEvent( QMouseEvent *e ); + void viewportMouseDoubleClickEvent( QMouseEvent *e ); + void viewportMouseMoveEvent( QMouseEvent *e ); +#ifndef QT_NO_DRAGANDDROP + void viewportDragEnterEvent( QDragEnterEvent *e ); + void viewportDragMoveEvent( QDragMoveEvent *e ); + void viewportDragLeaveEvent( QDragLeaveEvent *e ); + void viewportDropEvent( QDropEvent *e ); + bool acceptDrop( const QPoint &pnt, QWidget *source ); + void setCurrentDropItem( const QPoint &pnt ); +#endif + void keyPressEvent( QKeyEvent *e ); + +private slots: + void rename(); + void cancelRename(); + void doubleClickTimeout(); + void changeDirDuringDrag(); + void dragObjDestroyed(); + void contentsMoved( int, int ); + +private: + QRenameEdit *lined; + QFileDialogP *filedialog; + bool renaming; + QTimer* renameTimer; + QListBoxItem *renameItem, *dragItem; + QPoint pressPos, oldDragPos; + bool mousePressed; + int urls; + QString startDragDir; + QListBoxItem *currDropItem; + QTimer *changeDirTimer; + bool firstMousePressEvent; + QUrlOperator startDragUrl; + +}; + + +class QFileDialogQFileListView : public QListView +{ + Q_OBJECT + +public: + QFileDialogQFileListView( QWidget *parent, QFileDialogP *d ); + + void clear(); + void startRename( bool check = TRUE ); + void setSorting( int column, bool increasing = TRUE ); + + QRenameEdit *lined; + bool renaming; + QListViewItem *renameItem; + +private: + void viewportMousePressEvent( QMouseEvent *e ); + void viewportMouseDoubleClickEvent( QMouseEvent *e ); + void keyPressEvent( QKeyEvent *e ); + void viewportMouseReleaseEvent( QMouseEvent *e ); + void viewportMouseMoveEvent( QMouseEvent *e ); +#ifndef QT_NO_DRAGANDDROP + void viewportDragEnterEvent( QDragEnterEvent *e ); + void viewportDragMoveEvent( QDragMoveEvent *e ); + void viewportDragLeaveEvent( QDragLeaveEvent *e ); + void viewportDropEvent( QDropEvent *e ); + bool acceptDrop( const QPoint &pnt, QWidget *source ); + void setCurrentDropItem( const QPoint &pnt ); +#endif + +private slots: + void rename(); + void cancelRename(); + void changeSortColumn2( int column ); + void doubleClickTimeout(); + void changeDirDuringDrag(); + void dragObjDestroyed(); + void contentsMoved( int, int ); + +private: + QFileDialogP *filedialog; + QTimer* renameTimer; + QPoint pressPos, oldDragPos; + bool mousePressed; + int urls; + QString startDragDir; + QListViewItem *currDropItem, *dragItem; + QTimer *changeDirTimer; + bool firstMousePressEvent; + bool ascending; + int sortcolumn; + QUrlOperator startDragUrl; + +}; + +/**************************************************************************** + * + * Classes for copy progress dialog + * + ****************************************************************************/ + +class QFDProgressAnimation : public QWidget +{ + Q_OBJECT + +public: + QFDProgressAnimation( QWidget *parent ); + void start(); + +private slots: + void next(); + +protected: + void paintEvent( QPaintEvent *e ); + +private: + int step; + QTimer *timer; + +}; + +class QFDProgressDialog : public QDialog +{ + Q_OBJECT + +public: + QFDProgressDialog( QWidget *parent, const QString &fn, int steps ); + + void setReadProgress( int p ); + void setWriteProgress( int p ); + void setWriteLabel( const QString &s ); + +signals: + void cancelled(); + +private: + QProgressBar *readBar; + QProgressBar *writeBar; + QLabel *writeLabel; + QFDProgressAnimation *animation; + +}; + +#endif + +#endif // QFILEDIALOG_H diff --git a/src/Plot2d/Plot2d_Prs.cxx b/src/Plot2d/Plot2d_Prs.cxx new file mode 100644 index 000000000..2db19dfc4 --- /dev/null +++ b/src/Plot2d/Plot2d_Prs.cxx @@ -0,0 +1,95 @@ +// SALOME OCCViewer : build OCC Viewer into Salome desktop +// +// Copyright (C) 2004 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : Plot2d_Prs.cxx +// Author : Sergey ANIKIN +// Module : SALOME +// $Header$ + +#include "Plot2d_Prs.h" + +//========================================================== +/*! + * Plot2d_Prs::Plot2d_Prs + * Default constructor + */ +//========================================================== +Plot2d_Prs::Plot2d_Prs() +{ +} + +//========================================================== +/*! + * Plot2d_Prs::Plot2d_Prs + * Standard constructor + */ +//========================================================== +Plot2d_Prs::Plot2d_Prs( const Plot2d_Curve* obj ) +{ + AddObject( obj ); +} + +//========================================================== +/*! + * Plot2d_Prs::~Plot2d_Prs + * Destructor + */ +//========================================================== +Plot2d_Prs::~Plot2d_Prs() +{ + myObjects.clear(); +} + +//========================================================== +/*! + * Plot2d_Prs::GetObjects + * Get curves list + */ +//========================================================== +Plot2d_CurveContainer Plot2d_Prs::GetObjects() const +{ + return myObjects; +} + +//========================================================== +/*! + * Plot2d_Prs::AddObject + * Add curbe + */ +//========================================================== +void Plot2d_Prs::AddObject( const Plot2d_Curve* obj ) +{ + myObjects.addCurve( (Plot2d_Curve*)obj ); +} + +//========================================================== +/*! + * Plot2d_Prs::IsNull + * Return 0 if list of the curves is empty + * [ Reimplemented from SALOME_Prs ] + */ +//========================================================== +bool Plot2d_Prs::IsNull() const +{ + return myObjects.isEmpty(); +} diff --git a/src/Plot2d/Plot2d_Prs.h b/src/Plot2d/Plot2d_Prs.h new file mode 100644 index 000000000..551f75511 --- /dev/null +++ b/src/Plot2d/Plot2d_Prs.h @@ -0,0 +1,59 @@ +// SALOME OCCViewer : build OCC Viewer into Salome desktop +// +// Copyright (C) 2004 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : Plot2d_Prs.h +// Author : Sergey ANIKIN +// Module : SALOME +// $Header$ + +#ifndef PLOT2D_PRS_H +#define PLOT2D_PRS_H + +#include "SALOME_Prs.h" +#include + +class Plot2d_Curve; + +class Plot2d_Prs : public SALOME_Prs2d +{ +public: + Plot2d_Prs(); + // Default constructor + Plot2d_Prs( const Plot2d_Curve* obj ); + // Standard constructor + ~Plot2d_Prs(); + // Destructor + + Plot2d_CurveContainer GetObjects() const; + // Get curves list + void AddObject( const Plot2d_Curve* obj ); + // Add curve + + bool IsNull() const; + // Reimplemented from SALOME_Prs + +private: + Plot2d_CurveContainer myObjects; // list of curves +}; + +#endif diff --git a/src/Prs/Makefile.in b/src/Prs/Makefile.in new file mode 100755 index 000000000..09f8a248a --- /dev/null +++ b/src/Prs/Makefile.in @@ -0,0 +1,27 @@ +# source path +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl + + +@COMMENCE@ + +EXPORT_HEADERS = SALOME_Prs.h + +# Libraries targets + +LIB = libSalomePrs.la +LIB_SRC = SALOME_Prs.cxx + +LIB_CLIENT_IDL = + +# Executables targets +BIN = +BIN_SRC = + +CPPFLAGS+= +LDFLAGS+= + + +@CONCLUDE@ diff --git a/src/Prs/SALOME_Prs.cxx b/src/Prs/SALOME_Prs.cxx new file mode 100644 index 000000000..1856fa15a --- /dev/null +++ b/src/Prs/SALOME_Prs.cxx @@ -0,0 +1,364 @@ +// File: SALOME_Prs.cxx +// Created: Wed Apr 28 15:03:43 2004 +// Author: Sergey ANIKIN +// + + +#include "SALOME_Prs.h" + +#include "utilities.h" + +using namespace std; + +//=========================================================== +/*! + * Function: SALOME_OCCPrs::DisplayIn + * Purpose: Dispatches display operation to proper Display() + * method of SALOME_View + */ +//=========================================================== +void SALOME_OCCPrs::DisplayIn( SALOME_View* v ) const +{ + if ( v ) v->Display( this ); +} + +//=========================================================== +/*! + * Function: SALOME_OCCPrs::EraseIn + * Purpose: Dispatches display operation to proper Erase() + * method of SALOME_View + */ +//=========================================================== +void SALOME_OCCPrs::EraseIn( SALOME_View* v, const bool forced ) const +{ + if ( v ) v->Erase( this, forced ); +} + +//=========================================================== +/*! + * Function: SALOME_OCCPrs::LocalSelectionIn + * Purpose: Dispatches operation to proper LocalSelectionIn() + * method of SALOME_View + */ +//=========================================================== +void SALOME_OCCPrs::LocalSelectionIn( SALOME_View* v, const int mode ) const +{ + if ( v ) v->LocalSelection( this, mode ); +} + +//=========================================================== +/*! + * Function: SALOME_OCCPrs::Update + * Purpose: Dispatches update operation to proper Update() + * method of SALOME_Displayer + */ +//=========================================================== +void SALOME_OCCPrs::Update( SALOME_Displayer* d ) +{ + if ( d ) d->Update( this ); +} + +//=========================================================== +/*! + * Function: SALOME_VTKPrs::DisplayIn + * Purpose: Dispatches display operation to proper Display() + * method of SALOME_View + */ +//=========================================================== +void SALOME_VTKPrs::DisplayIn( SALOME_View* v ) const +{ + if ( v ) v->Display( this ); +} + +//=========================================================== +/*! + * Function: SALOME_VTKPrs::EraseIn + * Purpose: Dispatches display operation to proper Erase() + * method of SALOME_View + */ +//=========================================================== +void SALOME_VTKPrs::EraseIn( SALOME_View* v, const bool forced ) const +{ + if ( v ) v->Erase( this, forced ); +} + +//=========================================================== +/*! + * Function: SALOME_VTKPrs::LocalSelectionIn + * Purpose: Dispatches operation to proper LocalSelectionIn() + * method of SALOME_View + */ +//=========================================================== +void SALOME_VTKPrs::LocalSelectionIn( SALOME_View* v, const int mode ) const +{ + if ( v ) v->LocalSelection( this, mode ); +} + +//=========================================================== +/*! + * Function: SALOME_VTKPrs::Update + * Purpose: Dispatches update operation to proper Update() + * method of SALOME_Displayer + */ +//=========================================================== +void SALOME_VTKPrs::Update( SALOME_Displayer* d ) +{ + if ( d ) d->Update( this ); +} + +//=========================================================== +/*! + * Function: SALOME_Prs2d::DisplayIn + * Purpose: Dispatches display operation to proper Display() + * method of SALOME_View + */ +//=========================================================== +void SALOME_Prs2d::DisplayIn( SALOME_View* v ) const +{ + if ( v ) v->Display( this ); +} + +//=========================================================== +/*! + * Function: SALOME_Prs2d::EraseIn + * Purpose: Dispatches display operation to proper Erase() + * method of SALOME_View + */ +//=========================================================== +void SALOME_Prs2d::EraseIn( SALOME_View* v, const bool forced ) const +{ + if ( v ) v->Erase( this, forced ); +} + +//=========================================================== +/*! + * Function: SALOME_Prs2d::LocalSelectionIn + * Purpose: Dispatches operation to proper LocalSelectionIn() + * method of SALOME_View + */ +//=========================================================== +void SALOME_Prs2d::LocalSelectionIn( SALOME_View* v, const int mode ) const +{ + if ( v ) v->LocalSelection( this, mode ); +} + +//=========================================================== +/*! + * Function: SALOME_Prs2d::Update + * Purpose: Dispatches update operation to proper Update() + * method of SALOME_Displayer + */ +//=========================================================== +void SALOME_Prs2d::Update( SALOME_Displayer* d ) +{ + if ( d ) d->Update( this ); +} + +//=========================================================== +/*! + * Function: SALOME_View::Display + * Purpose: Gives control to SALOME_Prs object, so that + * it could perform double dispatch + */ +//=========================================================== +void SALOME_View::Display( const SALOME_Prs* prs ) +{ + prs->DisplayIn( this ); +} + +//=========================================================== +/*! + * Function: SALOME_View::Erase + * Purpose: Gives control to SALOME_Prs object, so that + * it could perform double dispatch + */ +//=========================================================== +void SALOME_View::Erase( const SALOME_Prs* prs, const bool forced ) +{ + prs->EraseIn( this, forced ); +} + +//=========================================================== +/*! + * Function: SALOME_View::LocalSelection + * Purpose: Gives control to SALOME_Prs object, so that + * it could perform double dispatch + */ +//=========================================================== +void SALOME_View::LocalSelection( const SALOME_Prs* prs, const int mode ) +{ + prs->LocalSelectionIn( this, mode ); +} + +//=========================================================== +/*! + * Function: SALOME_View::Display + * Purpose: Virtual method, should be reimplemented in successors, + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::Display( const SALOME_OCCPrs* ) +{ + MESSAGE( "SALOME_View::Display( const SALOME_OCCPrs& ) called! Probably, presentation is being displayed in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_View::Display + * Purpose: Virtual method, should be reimplemented in successors, + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::Display( const SALOME_VTKPrs* ) +{ + MESSAGE( "SALOME_View::Display( const SALOME_VTKPrs& ) called! Probably, presentation is being displayed in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_View::Display + * Purpose: Virtual method, should be reimplemented in successors, + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::Display( const SALOME_Prs2d* ) +{ + MESSAGE( "SALOME_View::Display( const SALOME_Prs2d& ) called! Probably, presentation is being displayed in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_View::Erase + * Purpose: Virtual method, should be reimplemented in successors, + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::Erase( const SALOME_OCCPrs*, const bool ) +{ + MESSAGE( "SALOME_View::Erase( const SALOME_OCCPrs& ) called! Probably, presentation is being erased in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_View::Erase + * Purpose: Virtual method, should be reimplemented in successors, + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::Erase( const SALOME_VTKPrs*, const bool ) +{ + MESSAGE( "SALOME_View::Erase( const SALOME_VTKPrs& ) called! Probably, presentation is being erased in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_View::Erase + * Purpose: Virtual method, should be reimplemented in successors, + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::Erase( const SALOME_Prs2d*, const bool ) +{ + MESSAGE( "SALOME_View::Erase( const SALOME_Prs2d& ) called! Probably, presentation is being erased in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_View::LocalSelection + * Purpose: Virtual method, should be reimplemented in successors, + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::LocalSelection( const SALOME_OCCPrs*, const int ) +{ + MESSAGE( "SALOME_View::LocalSelection( const SALOME_OCCPrs* ) called! \ + Probably, selection is being activated in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_View::LocalSelection + * Purpose: Virtual method, should be reimplemented in successors, + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::LocalSelection( const SALOME_VTKPrs*, const int ) +{ + MESSAGE( "SALOME_View::LocalSelection( const SALOME_VTKPrs* ) called! \ + Probably, selection is being activated in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_View::LocalSelection + * Purpose: Virtual method, should be reimplemented in successors, + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::LocalSelection( const SALOME_Prs2d*, const int ) +{ + MESSAGE( "SALOME_View::LocalSelection( const SALOME_Prs2d* ) called! \ + Probably, selection is being activated in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_View::GlobalSelection + * Purpose: Virtual method, should be reimplemented in successors, + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_View::GlobalSelection( const bool ) const +{ + MESSAGE( "SALOME_View::GlobalSelection() called! \ + Probably, selection is being activated in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_Displayer::UpdatePrs + * Purpose: Gives control to SALOME_Prs object, so that + * it could perform double dispatch + */ +//=========================================================== +void SALOME_Displayer::UpdatePrs( SALOME_Prs* prs ) +{ + prs->Update( this ); +} + +//=========================================================== +/*! + * Function: SALOME_Displayer::Update + * Purpose: Virtual method, should be reimplemented in successors, + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_Displayer::Update( SALOME_OCCPrs* ) +{ + MESSAGE( "SALOME_Displayer::Update( SALOME_OCCPrs* ) called! Probably, presentation is being updated in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_Displayer::Update + * Purpose: Virtual method, should be reimplemented in successors, + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_Displayer::Update( SALOME_VTKPrs* ) +{ + MESSAGE( "SALOME_Displayer::Update( SALOME_VTKPrs* ) called! Probably, presentation is being updated in uncompatible viewframe." ); +} + +//=========================================================== +/*! + * Function: SALOME_Displayer::Update + * Purpose: Virtual method, should be reimplemented in successors, + * by default issues a warning and does nothing. + */ +//=========================================================== +void SALOME_Displayer::Update( SALOME_Prs2d* ) +{ + MESSAGE( "SALOME_Displayer::Update( SALOME_Prs2d* ) called! Probably, presentation is being updated in uncompatible viewframe." ); +} + diff --git a/src/Prs/SALOME_Prs.h b/src/Prs/SALOME_Prs.h new file mode 100644 index 000000000..060bf1838 --- /dev/null +++ b/src/Prs/SALOME_Prs.h @@ -0,0 +1,255 @@ +// SALOME OBJECT : implementation of interactive object visualization for OCC and VTK viewers +// +// Copyright (C) 2004 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : SALOME_Prs.h +// Author : Sergey ANIKIN +// Module : SALOME +// $Header$ + +#ifndef SALOME_PRS_H +#define SALOME_PRS_H + +class SALOME_View; +class SALOME_Displayer; + +//=========================================================== +/*! + * Class: SALOME_Prs + * Description: Base class for SALOME graphic object wrappers - presentations. + * Presentations are temporary objects, so they can be created on the stack. + */ +//=========================================================== + +class SALOME_Prs +{ +public: + virtual ~SALOME_Prs() {} + // Destructor + + virtual void DisplayIn( SALOME_View* ) const = 0; + // Key method for double dispatch of display operation + + virtual void EraseIn( SALOME_View*, const bool = false ) const = 0; + // Key method for double dispatch of erase operation + + virtual void Update( SALOME_Displayer* ) = 0; + // Key method for double dispatch of update operation + + virtual bool IsNull() const = 0; + // Should return true, if this presentation contains a graphic object + + virtual void LocalSelectionIn( SALOME_View*, const int ) const = 0; + // Key method for double dispatch of activation of subshapes selection +}; + +//=========================================================== +/*! + * Class: SALOME_OCCPrs + * Description: Base class for OpenCASCADE graphic object (AIS_InteractiveObject) wrappers. + * This intermediate class is necessary to avoid dependencies from OCC libs. + */ +//=========================================================== + +class SALOME_OCCPrs : public SALOME_Prs +{ +public: + virtual void DisplayIn( SALOME_View* ) const; + // It uses double dispatch in order to + // invoke Display() method corresponding to the actual type of presentation. + + virtual void EraseIn( SALOME_View*, const bool = false ) const; + // It uses double dispatch in order to + // invoke Erase() method corresponding to the actual type of presentation. + + virtual void Update( SALOME_Displayer* ); + // It uses double dispatch in order to + // invoke Update() method corresponding to the actual type of presentation. + + virtual void LocalSelectionIn( SALOME_View*, const int ) const; + // Key method for double dispatch of activation of subshapes selection +}; + +//=========================================================== +/*! + * Class: SALOME_VTKPrs + * Description: Base class for VTK graphic object (vtkActor) wrappers + * This intermediate class is necessary to avoid dependencies from VTK libs. + */ +//=========================================================== + +class SALOME_VTKPrs : public SALOME_Prs +{ +public: + virtual void DisplayIn( SALOME_View* ) const; + // It uses double dispatch in order to + // invoke Display() method corresponding to the actual type of presentation. + + virtual void EraseIn( SALOME_View*, const bool = false ) const; + // It uses double dispatch in order to + // invoke Erase() method corresponding to the actual type of presentation. + + virtual void Update( SALOME_Displayer* ); + // It uses double dispatch in order to + // invoke Update() method corresponding to the actual type of presentation. + + virtual void LocalSelectionIn( SALOME_View*, const int ) const; + // Key method for double dispatch of activation of subshapes selection +}; + +//=========================================================== +/*! + * Class: SALOME_Prs2d + * Description: Base class for Plot2d graphic object (Plot2d_Curve) wrappers. + */ +//=========================================================== + +class SALOME_Prs2d : public SALOME_Prs +{ +public: + virtual void DisplayIn( SALOME_View* ) const; + // It uses double dispatch in order to + // invoke Display() method corresponding to the actual type of presentation. + + virtual void EraseIn( SALOME_View*, const bool = false ) const; + // It uses double dispatch in order to + // invoke Erase() method corresponding to the actual type of presentation. + + virtual void Update( SALOME_Displayer* ); + // It uses double dispatch in order to + // invoke Update() method corresponding to the actual type of presentation. + + virtual void LocalSelectionIn( SALOME_View*, const int ) const; + // Key method for double dispatch of activation of subshapes selection +}; + +///////////////////////////////////////////////////////////////////////// +// Base classes for object wrappers for any other visualization libraries +// should be added here! +///////////////////////////////////////////////////////////////////////// + +//=========================================================== +/*! + * Class: SALOME_View + * Description: Base class for SALOME views (or view frames) + */ +//=========================================================== + +class SALOME_View +{ +public: + virtual ~SALOME_View() {} + // Destructor + + void Display( const SALOME_Prs* ); + // This Display() method should be called to display given presentation + // created anywhere by anybody. It simply passes control to SALOME_Prs object + // so that it could perform double dispatch. + void Erase( const SALOME_Prs*, const bool = false ); + // This Erase() method should be called to erase given presentation + // created anywhere by anybody. It simply passes control to SALOME_Prs object + // so that it could perform double dispatch. + + void LocalSelection( const SALOME_Prs*, const int ); + // This LocalSelection() method should be called to activate sub-shapes selection + // created anywhere by anybody. It simply passes control to SALOME_Prs object + // so that it could perform double dispatch. + + // Interface for derived views + + // Display() methods for ALL kinds of presentation should appear here + virtual void Display( const SALOME_OCCPrs* ); + virtual void Display( const SALOME_VTKPrs* ); + virtual void Display( const SALOME_Prs2d* ); + // Add new Display() methods here... + + // Erase() methods for ALL kinds of presentation should appear here + virtual void Erase( const SALOME_OCCPrs*, const bool = false ); + virtual void Erase( const SALOME_VTKPrs*, const bool = false ); + virtual void Erase( const SALOME_Prs2d*, const bool = false ); + // Add new Erase() methods here... + + // LocalSelection() methods for ALL kinds of presentation should appear here + virtual void LocalSelection( const SALOME_OCCPrs*, const int ); + virtual void LocalSelection( const SALOME_VTKPrs*, const int ); + virtual void LocalSelection( const SALOME_Prs2d* , const int ); + + virtual void GlobalSelection( const bool = false ) const; + // Deactivates selection of sub-shapes (must be redefined with OCC viewer) + + // Creates empty presenation of corresponding type + virtual SALOME_Prs* CreatePrs( const char* entry = 0 ) { return 0; } + + // Axiluary methods called before and after displaying of objects + virtual void BeforeDisplay( SALOME_Displayer* d ) {} + virtual void AfterDisplay ( SALOME_Displayer* d ) {} +}; + +//=========================================================== +/*! + * Classes: SALOME_Displayer + * Description: These classes are used to specify type of view + * VTK, OCC or Plot2d + */ +//=========================================================== + +class SALOME_OCCViewType {}; +class SALOME_VTKViewType {}; +class SALOME_Plot2dViewType {}; + +//=========================================================== +/*! + * Class: SALOME_Displayer + * Description: Base class for SALOME displayers + */ +//=========================================================== + +class SALOME_Displayer +{ +public: + virtual ~SALOME_Displayer() {} + // Destructor + + void UpdatePrs( SALOME_Prs* ); + // This Update() method should be called to update given presentation + // created anywhere by anybody. It simply passes control to SALOME_Prs object + // so that it could perform double dispatch. + + // Interface for derived displayers + + // Update() methods for ALL kinds of presentation should appear here + virtual void Update( SALOME_OCCPrs* ); + virtual void Update( SALOME_VTKPrs* ); + virtual void Update( SALOME_Prs2d* ); + // Add new Update() methods here... + + // Axiluary methods called before and after displaying of objects + virtual void BeforeDisplay( SALOME_View*, const SALOME_OCCViewType& ) {}; + virtual void AfterDisplay ( SALOME_View*, const SALOME_OCCViewType& ) {}; + virtual void BeforeDisplay( SALOME_View*, const SALOME_VTKViewType& ) {}; + virtual void AfterDisplay ( SALOME_View*, const SALOME_VTKViewType& ) {}; + virtual void BeforeDisplay( SALOME_View*, const SALOME_Plot2dViewType& ) {}; + virtual void AfterDisplay ( SALOME_View*, const SALOME_Plot2dViewType& ) {}; +}; + +#endif + diff --git a/src/Session/SALOME_Session_SignalsHandler.cxx b/src/Session/SALOME_Session_SignalsHandler.cxx new file mode 100644 index 000000000..c02f6132a --- /dev/null +++ b/src/Session/SALOME_Session_SignalsHandler.cxx @@ -0,0 +1,38 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + + +#include +#include + +#include "CASCatch_SignalsHandler.h" // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC + + +extern "C" int HandleSignals(QApplication *theQApplication) +{ + CASCatch_SignalsHandler aSignalsHandler; + int aRet = -1; + try { + aRet = theQApplication->exec(); + }catch(Standard_Failure){ + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + throw std::runtime_error(aFail->GetMessageString()); + } + return aRet; +} diff --git a/src/Utils/Utils_SignalsHandler.cxx b/src/Utils/Utils_SignalsHandler.cxx new file mode 100644 index 000000000..d72879e4b --- /dev/null +++ b/src/Utils/Utils_SignalsHandler.cxx @@ -0,0 +1,119 @@ +// KERNEL Utils : common utils for KERNEL +// Copyright (C) 2003 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org + + +#include +#include +#include + +#include "Utils_SignalsHandler.h" + + +//============================================================================ +//function : Handler +//purpose : univisal handler for signals +//============================================================================ +static void Handler(int theSigId) +{ + char aMessage[256] = ""; + sprintf(aMessage,"Signal with ID = %d was cautch!",theSigId); + throw std::runtime_error(aMessage); +} + + +//======================================================================= +//function : SetSigHandler +//purpose : Redefine signal handlers. If the handler of the signal is +// set as SIG_IGN. That's why the shells often ignore some +// signal when starting child processes. We keep it. +//======================================================================= +static void SetSignalHandler(Utils_SignalsHandler::TSigHandlerCont& theSigHandlerCont, + int theSigId) +{ + TSigHandler anOldHandler = signal(theSigId,&Handler); + if(anOldHandler == SIG_IGN) + signal(theSigId,SIG_IGN); + theSigHandlerCont[theSigId] = anOldHandler; +} + +static TSigHandler StoreSignalHandler(Utils_SignalsHandler::TSigHandlerCont& theSigHandlerCont, + int theSigId) +{ + TSigHandler anOldHandler = signal(theSigId,&Handler); + signal(theSigId,anOldHandler); + if(anOldHandler == SIG_IGN) + signal(theSigId,SIG_IGN); + theSigHandlerCont[theSigId] = anOldHandler; + return anOldHandler; +} + +static void RestoreSigHandler(TSigHandler theSigHandler, + int theSigId) +{ + signal(theSigId,theSigHandler); +} + + +//======================================================================= +//function : Utils_SignalsHandler +//purpose : Constructor +//======================================================================= +Utils_SignalsHandler::Utils_SignalsHandler() +{ + StoreSignalHandler(mySigHandlerCont,SIGHUP); // floating point exception + StoreSignalHandler(mySigHandlerCont,SIGFPE); // floating point exception + + StoreSignalHandler(mySigHandlerCont,SIGINT); // interrupt + StoreSignalHandler(mySigHandlerCont,SIGQUIT); // quit + StoreSignalHandler(mySigHandlerCont,SIGBUS); // bus error + StoreSignalHandler(mySigHandlerCont,SIGILL); // illegal instruction + StoreSignalHandler(mySigHandlerCont,SIGTERM); // termination + StoreSignalHandler(mySigHandlerCont,SIGSEGV); // segmentation + //StoreSignalHandler(mySigHandlerCont,SIGABRT); // abort (ANSI). + StoreSignalHandler(mySigHandlerCont,SIGSTKFLT); // stack fault. +} + + +//======================================================================= +//function : Utils_SignalsHandler +//purpose : destructor +//======================================================================= +Utils_SignalsHandler::~Utils_SignalsHandler() +{ + TSigHandlerCont::iterator anIter = mySigHandlerCont.begin(); + TSigHandlerCont::iterator anIterEnd = mySigHandlerCont.end(); + for(; anIter != anIterEnd; anIter++) + RestoreSigHandler(anIter->second,anIter->first); +} + + +//======================================================================= +//function : SetSigHandler +//purpose : sets new handler for pointed signal +//======================================================================= +TSigHandler Utils_SignalsHandler::SetSigHandler(int theSigId, + TSigHandler theSigHandler) +{ + TSigHandler anOldHandler = signal(theSigId,theSigHandler); + if(anOldHandler == SIG_IGN) + signal(theSigId,SIG_IGN); + mySigHandlerCont[theSigId] = anOldHandler; + return anOldHandler; +} diff --git a/src/Utils/Utils_SignalsHandler.h b/src/Utils/Utils_SignalsHandler.h new file mode 100644 index 000000000..475dcf18e --- /dev/null +++ b/src/Utils/Utils_SignalsHandler.h @@ -0,0 +1,49 @@ +// KERNEL Utils : common utils for KERNEL +// Copyright (C) 2003 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org + +#ifndef _UTILS_SIGNALSHANDLER_H_ +#define _UTILS_SIGNALSHANDLER_H_ + + +#include +typedef void (*TSigHandler)(int); + + +class Utils_SignalsHandler{ + public: + Utils_SignalsHandler(); + ~Utils_SignalsHandler(); + + TSigHandler GetSigHandler(int theSigId); + TSigHandler SetSigHandler(int theSigId, TSigHandler theSigHandler); + typedef std::map TSigHandlerCont; + + private: + TSigHandlerCont mySigHandlerCont; +}; + + +class Utils_CASSignalsHandler: private Utils_SignalsHandler{ + public: + Utils_CASSignalsHandler(); +}; + + +#endif diff --git a/src/VTKFilter/SALOME_ShrinkFilter.cxx b/src/VTKFilter/SALOME_ShrinkFilter.cxx new file mode 100644 index 000000000..1ea45c86f --- /dev/null +++ b/src/VTKFilter/SALOME_ShrinkFilter.cxx @@ -0,0 +1,176 @@ +// SALOME OBJECT : kernel of SALOME component +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SALOME_GeometryFilter.cxx +// Author : Michael ZORIN +// Module : SALOME +// $Header$ + +#include "SALOME_ShrinkFilter.h" + +#include +#include +#include +#include +#include +#include + +#ifdef _DEBUG_ +static int MYDEBUG = 0; +static int MYDEBUGWITHFILES = 0; +#else +static int MYDEBUG = 0; +static int MYDEBUGWITHFILES = 0; +#endif + +vtkCxxRevisionMacro(SALOME_ShrinkFilter, "$Revision$"); +vtkStandardNewMacro(SALOME_ShrinkFilter); + + +SALOME_ShrinkFilter::SALOME_ShrinkFilter(): + myStoreMapping(0) +{} + + +SALOME_ShrinkFilter::~SALOME_ShrinkFilter() +{} + + +void SALOME_ShrinkFilter::Execute() +{ + vtkPoints *newPts; + int i, j, numIds, abort=0; + vtkIdType cellId, numCells, numPts; + vtkIdType oldId, newId; + float center[3], *p, pt[3]; + vtkPointData *pd, *outPD;; + vtkIdList *ptIds, *newPtIds; + vtkDataSet *input= this->GetInput(); + vtkUnstructuredGrid *output = this->GetOutput(); + vtkIdType tenth; + float decimal; + + vtkDebugMacro(<<"Shrinking cells"); + + numCells=input->GetNumberOfCells(); + numPts = input->GetNumberOfPoints(); + if (numCells < 1 || numPts < 1) + { + vtkErrorMacro(<<"No data to shrink!"); + return; + } + + ptIds = vtkIdList::New(); + ptIds->Allocate(VTK_CELL_SIZE); + newPtIds = vtkIdList::New(); + newPtIds->Allocate(VTK_CELL_SIZE); + + output->Allocate(numCells); + newPts = vtkPoints::New(); + newPts->Allocate(numPts*8,numPts); + pd = input->GetPointData(); + outPD = output->GetPointData(); + outPD->CopyAllocate(pd,numPts*8,numPts); + + // Traverse all cells, obtaining node coordinates. Compute "center" of cell, + // then create new vertices shrunk towards center. + // + tenth = numCells/10 + 1; + decimal = 0.0; + if(myStoreMapping){ + myVTK2ObjIds.clear(); + myVTK2ObjIds.reserve(numCells); + } + + for (cellId=0; cellId < numCells && !abort; cellId++) + { + input->GetCellPoints(cellId, ptIds); + numIds = ptIds->GetNumberOfIds(); + + //abort/progress methods + if (cellId % tenth == 0) + { + decimal += 0.1; + this->UpdateProgress (decimal); + abort = this->GetAbortExecute(); + } + + // get the center of the cell + center[0] = center[1] = center[2] = 0.0; + for (i=0; i < numIds; i++) + { + p = input->GetPoint(ptIds->GetId(i)); + for (j=0; j < 3; j++) + { + center[j] += p[j]; + } + } + for (j=0; j<3; j++) + { + center[j] /= numIds; + } + + // Create new points and cells + newPtIds->Reset(); + for (i=0; i < numIds; i++) + { + p = input->GetPoint(ptIds->GetId(i)); + for (j=0; j < 3; j++) + { + pt[j] = center[j] + this->ShrinkFactor*(p[j] - center[j]); + } + + oldId = ptIds->GetId(i); + newId = newPts->InsertNextPoint(pt); + if(myStoreMapping) + myVTK2ObjIds.push_back(oldId); + newPtIds->InsertId(i,newId); + + outPD->CopyData(pd, oldId, newId); + } + output->InsertNextCell(input->GetCellType(cellId), newPtIds); + }//for all cells + + // Update ourselves and release memory + // + output->GetCellData()->PassData(input->GetCellData()); + + output->SetPoints(newPts); + output->Squeeze(); + + ptIds->Delete(); + newPtIds->Delete(); + newPts->Delete(); +} + + +void SALOME_ShrinkFilter::SetStoreMapping(int theStoreMapping){ + myStoreMapping = theStoreMapping; + this->Modified(); +} + + +vtkIdType SALOME_ShrinkFilter::GetNodeObjId(int theVtkID){ + if(myVTK2ObjIds.empty() || theVtkID > myVTK2ObjIds.size()) return -1; + return myVTK2ObjIds[theVtkID]; +} diff --git a/src/VTKFilter/SALOME_ShrinkFilter.h b/src/VTKFilter/SALOME_ShrinkFilter.h new file mode 100644 index 000000000..837b93978 --- /dev/null +++ b/src/VTKFilter/SALOME_ShrinkFilter.h @@ -0,0 +1,61 @@ +// SALOME OBJECT : kernel of SALOME component +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SALOME_GeometryFilter.h +// Author : Michael ZORIN +// Module : SALOME +// $Header$ + + +#ifndef __SALOME_ShrinkFilter_h +#define __SALOME_ShrinkFilter_h + +#include +#include + +class SALOME_ShrinkFilter : public vtkShrinkFilter +{ +public: + static SALOME_ShrinkFilter *New(); + vtkTypeRevisionMacro(SALOME_ShrinkFilter, vtkShrinkFilter); + + void SetStoreMapping(int theStoreMapping); + int GetStoreMapping(){ return myStoreMapping;} + + virtual vtkIdType GetNodeObjId(int theVtkID); + virtual vtkIdType GetElemObjId(int theVtkID) { return theVtkID;} + +protected: + SALOME_ShrinkFilter(); + ~SALOME_ShrinkFilter(); + + void Execute(); + void UnstructuredGridExecute(); + +private: + int myStoreMapping; + typedef std::vector TVectorId; + TVectorId myVTK2ObjIds; +}; + +#endif diff --git a/src/VTKViewer/VTKViewer_Actor.cxx b/src/VTKViewer/VTKViewer_Actor.cxx new file mode 100644 index 000000000..eb8cd140f --- /dev/null +++ b/src/VTKViewer/VTKViewer_Actor.cxx @@ -0,0 +1,233 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +#include "VTKViewer_Actor.h" + +#include "SALOME_PassThroughFilter.h" + +// VTK Includes +#include +#include +#include +#include + +#include +#include +#include + +#include "utilities.h" + +using namespace std; + +#ifdef _DEBUG_ +static int MYDEBUG = 0; +#else +static int MYDEBUG = 0; +#endif + + +static void CopyPoints(vtkUnstructuredGrid* theGrid, vtkDataSet *theSourceDataSet){ + vtkPoints *aPoints = vtkPoints::New(); + vtkIdType iEnd = theSourceDataSet->GetNumberOfPoints(); + aPoints->SetNumberOfPoints(iEnd); + for(vtkIdType i = 0; i < iEnd; i++){ + aPoints->SetPoint(i,theSourceDataSet->GetPoint(i)); + } + theGrid->SetPoints(aPoints); + aPoints->Delete(); +} + + +//======================================================================= + +vtkStandardNewMacro(VTKViewer_Actor); + +VTKViewer_Actor::VTKViewer_Actor() +{ + myRenderer = NULL; + myIsInfinite = true; + + Visibility = Pickable = false; + + myUnstructuredGrid = vtkUnstructuredGrid::New(); + myUnstructuredGrid->Allocate(); + + myIsShrunk = false; + myIsShrinkable = true; + myShrinkFilter = vtkShrinkFilter::New(); + + myMapper = vtkDataSetMapper::New(); + + myMapper->SetInput(myUnstructuredGrid); + Superclass::InitPipeLine(myMapper); + + SetResolveCoincidentTopology(false); +} + + +void VTKViewer_Actor::SetShrinkFactor(float theValue){ + myShrinkFilter->SetShrinkFactor(theValue); + Modified(); +} + + +void VTKViewer_Actor::SetShrink() +{ + if ( !myIsShrinkable ) return; + if ( vtkDataSet* aDataSet = myPassFilter[0]->GetOutput() ) + { + myShrinkFilter->SetInput( aDataSet ); + myPassFilter[1]->SetInput( myShrinkFilter->GetOutput() ); + myIsShrunk = true; + } +} + +void VTKViewer_Actor::UnShrink() +{ + if ( !myIsShrunk ) return; + if ( vtkDataSet* aDataSet = myPassFilter[0]->GetOutput() ) + { + myPassFilter[1]->SetInput( aDataSet ); + myPassFilter[1]->Modified(); + myIsShrunk = false; + Modified(); + } +} + + +//---------------------------------------------------------------------------- +VTKViewer_Actor::~VTKViewer_Actor() +{ + if(MYDEBUG) INFOS("VTKViewer_Actor::~VTKViewer_Actor()"); + + myMapper->RemoveAllInputs(); + myMapper->Delete(); + + myShrinkFilter->UnRegisterAllOutputs(); + myShrinkFilter->Delete(); + + myUnstructuredGrid->Delete(); +} + + +//---------------------------------------------------------------------------- +void VTKViewer_Actor::MapCells(SALOME_Actor* theMapActor, + const TColStd_IndexedMapOfInteger& theMapIndex) +{ + myUnstructuredGrid->Reset(); + + vtkDataSet *aSourceDataSet = theMapActor->GetInput(); + CopyPoints(myUnstructuredGrid,aSourceDataSet); + + int aNbOfParts = theMapIndex.Extent(); + for(int ind = 1; ind <= aNbOfParts; ind++){ + int aPartId = theMapIndex( ind ); + vtkCell* aCell = theMapActor->GetElemCell(aPartId); + myUnstructuredGrid->InsertNextCell(aCell->GetCellType(),aCell->GetPointIds()); + //for (int i = 0, iEnd = aCell->GetNumberOfEdges(); i < iEnd; i++){ + // vtkCell* anEdgeCell = aCell->GetEdge(i); + // myUnstructuredGrid->InsertNextCell(VTK_LINE,anEdgeCell->GetPointIds()); + //} + } + + UnShrink(); + if(theMapActor->IsShrunk()){ + SetShrinkFactor(theMapActor->GetShrinkFactor()); + SetShrink(); + } +} + + +//---------------------------------------------------------------------------- +void VTKViewer_Actor::MapPoints(SALOME_Actor* theMapActor, + const TColStd_IndexedMapOfInteger& theMapIndex) +{ + myUnstructuredGrid->Reset(); + if(int aNbOfParts = theMapIndex.Extent()){ + vtkPoints *aPoints = vtkPoints::New(); + aPoints->SetNumberOfPoints(aNbOfParts); + for(int i = 0; i < aNbOfParts; i++){ + int aPartId = theMapIndex( i+1 ); + float* aCoord = theMapActor->GetNodeCoord(aPartId); + aPoints->SetPoint(i,aCoord); + myUnstructuredGrid->InsertNextCell(VTK_VERTEX,1,&i); + } + myUnstructuredGrid->SetPoints(aPoints); + aPoints->Delete(); + } + + UnShrink(); +} + + +//---------------------------------------------------------------------------- +void VTKViewer_Actor::MapEdge(SALOME_Actor* theMapActor, + const TColStd_IndexedMapOfInteger& theMapIndex) +{ + myUnstructuredGrid->Reset(); + + vtkDataSet *aSourceDataSet = theMapActor->GetInput(); + CopyPoints(myUnstructuredGrid,aSourceDataSet); + + int iEnd = theMapIndex.Extent(); + int aCellId = -1, aCellCounter = 0; + for(int i = 1; i <= iEnd; i++){ + int anId = theMapIndex( i ); + if(anId > 0) { + aCellCounter++; + aCellId = anId; + } + } + + if(aCellCounter == 1){ + vtkCell* aCell = theMapActor->GetElemCell(aCellId); + if(aCell->GetCellType() <= VTK_LINE){ + myUnstructuredGrid->InsertNextCell(aCell->GetCellType(),aCell->GetPointIds()); + }else{ + int aNbOfParts = aCell->GetNumberOfEdges(); + for(int i = 1; i <= iEnd; i++){ + int aPartId = theMapIndex(i); + if( aPartId < 0){ + aPartId = -aPartId-1; + if(0 > aPartId || aPartId >= aNbOfParts) break; + vtkCell* anEdgeCell = aCell->GetEdge(aPartId); + myUnstructuredGrid->InsertNextCell(VTK_LINE,anEdgeCell->GetPointIds()); + } + } + } + }else{ + int aNbOfParts = aSourceDataSet->GetNumberOfCells(); + for(int i = 1; i <= iEnd; i++){ + int aPartId = theMapIndex( i ); + if(aPartId > 0){ + if(aPartId >= aNbOfParts) break; + vtkCell* aCell = aSourceDataSet->GetCell(aPartId); + myUnstructuredGrid->InsertNextCell(aCell->GetCellType(),aCell->GetPointIds()); + } + } + } + + UnShrink(); + if(theMapActor->IsShrunk()){ + SetShrinkFactor(theMapActor->GetShrinkFactor()); + SetShrink(); + } +} + +//---------------------------------------------------------------------------- diff --git a/src/VTKViewer/VTKViewer_Actor.h b/src/VTKViewer/VTKViewer_Actor.h new file mode 100644 index 000000000..a708aa63e --- /dev/null +++ b/src/VTKViewer/VTKViewer_Actor.h @@ -0,0 +1,64 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +#ifndef VTKVIEWER_ACTOR_H +#define VTKVIEWER_ACTOR_H + +#include + +class vtkRenderer; +class vtkShrinkFilter; +class vtkDataSetMapper; +class vtkUnstructuredGrid; + +#include "SALOME_Actor.h" + +class VTKViewer_Actor : public SALOME_Actor { + public: + vtkTypeMacro(VTKViewer_Actor,SALOME_Actor); + static VTKViewer_Actor* New(); + virtual ~VTKViewer_Actor(); + + void SetShrinkFactor(float value); + virtual void SetShrink(); + virtual void UnShrink(); + + void MapCells(SALOME_Actor* theMapActor, + const TColStd_IndexedMapOfInteger& theMapIndex); + + void MapPoints(SALOME_Actor* theMapActor, + const TColStd_IndexedMapOfInteger& theMapIndex); + + void MapEdge(SALOME_Actor* theMapActor, + const TColStd_IndexedMapOfInteger& theMapIndex); + + protected: + vtkUnstructuredGrid* myUnstructuredGrid; + vtkDataSetMapper* myMapper; + + vtkRenderer* myRenderer; + + vtkShrinkFilter* myShrinkFilter; + bool myIsShrinkable; + bool myIsShrunk; + + VTKViewer_Actor(); +}; + +#endif diff --git a/src/VTKViewer/VTKViewer_Algorithm.h b/src/VTKViewer/VTKViewer_Algorithm.h new file mode 100644 index 000000000..cd38a862d --- /dev/null +++ b/src/VTKViewer/VTKViewer_Algorithm.h @@ -0,0 +1,83 @@ +// SALOME VTKViewer : build VTK viewer into Salome desktop +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : VTKViewer_ViewFrame.h +// Author : Nicolas REJNERI +// Module : SALOME +// $Header$ + +#ifndef VTKViewer_Algorithm_H +#define VTKViewer_Algorithm_H + +class vtkActor; +class vtkActorCollection; + +namespace SALOME{ + namespace VTK{ + + template + TFunction ForEach(vtkActorCollection *theCollection, TFunction theFun) + { + if(theCollection){ + theCollection->InitTraversal(); + while(vtkActor *anAct = theCollection->GetNextActor()) + if(TActor *anActor = dynamic_cast(anAct)) + theFun(anActor); + } + return theFun; + } + + + template + TFunction ForEachIf(vtkActorCollection *theCollection, + TPredicate thePredicate, + TFunction theFun) + { + if(theCollection){ + theCollection->InitTraversal(); + while(vtkActor *anAct = theCollection->GetNextActor()) + if(TActor *anActor = dynamic_cast(anAct)) + if(thePredicate(anActor)) + theFun(anActor); + } + return theFun; + } + + + template + TActor* Find(vtkActorCollection *theCollection, TPredicate thePredicate) + { + if(theCollection){ + theCollection->InitTraversal(); + while(vtkActor *anAct = theCollection->GetNextActor()) + if(TActor *anActor = dynamic_cast(anAct)) + if(thePredicate(anActor)) + return anActor; + } + return NULL; + } + + } +} + +#endif diff --git a/src/VTKViewer/VTKViewer_Functor.h b/src/VTKViewer/VTKViewer_Functor.h new file mode 100644 index 000000000..825f855cb --- /dev/null +++ b/src/VTKViewer/VTKViewer_Functor.h @@ -0,0 +1,98 @@ +// SALOME VTKViewer : build VTK viewer into Salome desktop +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : VTKViewer_ViewFrame.h +// Author : Nicolas REJNERI +// Module : SALOME +// $Header$ + +#ifndef VTKViewer_Functor_H +#define VTKViewer_Functor_H + +#include + +#include +#include "SALOME_InteractiveObject.hxx" + +namespace SALOME{ + namespace VTK{ + + + template struct TIsSameEntry + { + std::string myEntry; + TIsSameEntry(const char* theEntry): myEntry(theEntry){} + bool operator()(TActor* theActor){ + if(theActor->hasIO()){ + Handle(SALOME_InteractiveObject) anIO = theActor->getIO(); + if(anIO->hasEntry()) + return myEntry == anIO->getEntry(); + } + return false; + } + }; + + + template struct TIsSameIObject + { + Handle(SALOME_InteractiveObject) myIObject; + TIsSameIObject(const Handle(SALOME_InteractiveObject)& theIObject): + myIObject(theIObject) + {} + bool operator()(TActor* theActor){ + if(theActor->hasIO()){ + Handle(SALOME_InteractiveObject) anIO = theActor->getIO(); + return myIObject->isSame(anIO); + } + return false; + } + }; + + + template struct TSetFunction + { + typedef void (TActor::* TAction)(TArg); + TAction myAction; + TStoreArg myArg; + TSetFunction(TAction theAction, TArg theArg): + myAction(theAction), myArg(theArg) + {} + void operator()(TActor* theActor){ + (theActor->*myAction)(myArg); + } + }; + + + template struct TSetVisibility: TSetFunction + { + TSetVisibility(TArg theArg): + TSetFunction(&TActor::SetVisibility,theArg) + {} + }; + + + } +} + + +#endif diff --git a/src/VTKViewer/VTKViewer_Prs.cxx b/src/VTKViewer/VTKViewer_Prs.cxx new file mode 100644 index 000000000..4d048c609 --- /dev/null +++ b/src/VTKViewer/VTKViewer_Prs.cxx @@ -0,0 +1,97 @@ +// SALOME VTKViewer : build VTK viewer into Salome desktop +// +// Copyright (C) 2004 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : VTKViewer_Prs.cxx +// Author : Sergey ANIKIN +// Module : SALOME +// $Header$ + +#include "VTKViewer_Prs.h" + +//========================================================== +/*! + * VTKViewer_Prs::VTKViewer_Prs + * Default constructor + */ +//========================================================== +VTKViewer_Prs::VTKViewer_Prs() : myObjects( 0 ) +{ +} + +//========================================================== +/*! + * VTKViewer_Prs::VTKViewer_Prs + * tandard constructora + */ +//========================================================== +VTKViewer_Prs::VTKViewer_Prs( const vtkActor* obj ) +{ + AddObject( obj ); +} + +//========================================================== +/*! + * VTKViewer_Prs::~VTKViewer_Prs + * Destructor + */ +//========================================================== +VTKViewer_Prs:: ~VTKViewer_Prs() +{ + if ( myObjects ) myObjects->Delete(); +} + +//========================================================== +/*! + * VTKViewer_Prs::GetObjects + * Get actors list + */ +//========================================================== +vtkActorCollection* VTKViewer_Prs::GetObjects() const +{ + return myObjects; +} + +//========================================================== +/*! + * VTKViewer_Prs::AddObject + * Add actor + */ +//========================================================== +void VTKViewer_Prs::AddObject( const vtkActor* obj ) +{ + if ( !myObjects) + myObjects = vtkActorCollection::New(); + myObjects->AddItem( (vtkActor*)obj ); +} + +//========================================================== +/*! + * VTKViewer_Prs::IsNull + * Return 0 if list of the actors is empty + * [ Reimplemented from SALOME_Prs ] + */ +//========================================================== +bool VTKViewer_Prs::IsNull() const +{ + return !myObjects || myObjects->GetNumberOfItems() <= 0; +} diff --git a/src/VTKViewer/VTKViewer_Prs.h b/src/VTKViewer/VTKViewer_Prs.h new file mode 100644 index 000000000..6e61c0abe --- /dev/null +++ b/src/VTKViewer/VTKViewer_Prs.h @@ -0,0 +1,58 @@ +// SALOME VTKViewer : build VTK viewer into Salome desktop +// +// Copyright (C) 2004 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : VTKViewer_Prs.h +// Author : Sergey ANIKIN +// Module : SALOME +// $Header$ + +#ifndef VTKVIEWER_PRS_H +#define VTKVIEWER_PRS_H + +#include "SALOME_Prs.h" + +#include + +class VTKViewer_Prs : public SALOME_VTKPrs +{ +public: + VTKViewer_Prs(); + // Default constructor + VTKViewer_Prs( const vtkActor* obj ); + // Standard constructor + ~VTKViewer_Prs(); + // Destructor + + vtkActorCollection* GetObjects() const; + // Get actors list + void AddObject( const vtkActor* obj ); + // Add actor + + bool IsNull() const; + // Reimplemented from SALOME_Prs + +private: + vtkActorCollection* myObjects; // list of actors +}; + +#endif -- 2.39.2