diff --git a/CMakeLists.txt b/CMakeLists.txt
index be96b53b5c..0aa79ddfc1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -157,6 +157,17 @@ elseif(CCACHE)
set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE})
endif()
+# Prevent long command lines on Windows
+
+if(WIN32)
+ set(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS TRUE)
+ set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS TRUE)
+
+ if("${CMAKE_GENERATOR}" STREQUAL "Ninja")
+ set(CMAKE_NINJA_FORCE_RESPONSE_FILE TRUE)
+ endif()
+endif()
+
# Keep track of some basic information about Qt, after making sure that we have
# the version of Qt that we need
diff --git a/doc/downloads/index.js b/doc/downloads/index.js
index b5538e92a1..0f42e12713 100644
--- a/doc/downloads/index.js
+++ b/doc/downloads/index.js
@@ -38,6 +38,7 @@ var jsonData = { "versions": [
],
"changes": [
{ "change": "General: only handle a URL when OpenCOR is visible and no modal dialog is active (see issue #1802)." },
+ { "change": "Simulation Experiment view: provide more user-friendly simulation time information (see issue #1804)." },
{ "change": "Third-party libraries: upgraded libgit2 to version 0.27.4 (see issue #1799)." }
]
},
diff --git a/src/plugins/miscellaneous/Core/i18n/Core_fr.ts b/src/plugins/miscellaneous/Core/i18n/Core_fr.ts
index 7228d59ea3..5ddd30acab 100644
--- a/src/plugins/miscellaneous/Core/i18n/Core_fr.ts
+++ b/src/plugins/miscellaneous/Core/i18n/Core_fr.ts
@@ -467,5 +467,25 @@
Veuillez choisir un répertoire vide.
+
+
+ j
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/miscellaneous/Core/src/corecliutils.cpp b/src/plugins/miscellaneous/Core/src/corecliutils.cpp
index 3d68d52ebf..505701b511 100644
--- a/src/plugins/miscellaneous/Core/src/corecliutils.cpp
+++ b/src/plugins/miscellaneous/Core/src/corecliutils.cpp
@@ -261,6 +261,45 @@ QString sizeAsString(quint64 pSize, int pPrecision)
//==============================================================================
+QString formatTime(qint64 pTime)
+{
+ // Convert the given time (in milliseconds) to a string and return it
+ // Note: normally, we would for example have something like
+ // int h = int(msToH*time);
+ // with msToH being
+ // static double msToH = 1.0/3600000.0;
+ // However, with pTime=3600000, h equals 0 due, I imagine, to the
+ // internal representation of the floating point number prior to its
+ // conversion to an int. So, instead, we explicitly divide things...
+
+ QString res = QString();
+ qint64 time = pTime;
+ int d = int(time/86400000.0); time -= 86400000*d;
+ int h = int(time/3600000.0); time -= 3600000*h;
+ int m = int(time/60000.0); time -= 60000*m;
+ int s = int(time/1000.0); time -= 1000*s;
+ int ms = int(time);
+
+ if (d || ((h || m || s || ms) && !res.isEmpty()))
+ res += (res.isEmpty()?QString():" ")+QString::number(d)+QObject::tr("d");
+
+ if (h || ((m || s || ms) && !res.isEmpty()))
+ res += (res.isEmpty()?QString():" ")+QString::number(h)+QObject::tr("h");
+
+ if (m || ((s || ms) && !res.isEmpty()))
+ res += (res.isEmpty()?QString():" ")+QString::number(m)+QObject::tr("m");
+
+ if (s || (ms && !res.isEmpty()))
+ res += (res.isEmpty()?QString():" ")+QString::number(s)+QObject::tr("s");
+
+ if (ms || res.isEmpty())
+ res += (res.isEmpty()?QString():" ")+QString::number(ms)+QObject::tr("ms");
+
+ return res;
+}
+
+//==============================================================================
+
QString sha1(const QByteArray &pByteArray)
{
// Return the SHA-1 value of the given byte array
diff --git a/src/plugins/miscellaneous/Core/src/corecliutils.h b/src/plugins/miscellaneous/Core/src/corecliutils.h
index 72ab7b5e33..c0b87a0039 100644
--- a/src/plugins/miscellaneous/Core/src/corecliutils.h
+++ b/src/plugins/miscellaneous/Core/src/corecliutils.h
@@ -122,6 +122,8 @@ QString CORE_EXPORT digitGroupNumber(const QString &pNumber);
QString CORE_EXPORT sizeAsString(quint64 pSize, int pPrecision = 1);
+QString CORE_EXPORT formatTime(qint64 pTime);
+
QString CORE_EXPORT sha1(const QByteArray &pByteArray);
QString CORE_EXPORT sha1(const QString &pString);
diff --git a/src/plugins/miscellaneous/Core/tests/generaltests.cpp b/src/plugins/miscellaneous/Core/tests/generaltests.cpp
index ecbd64d0f0..737294b588 100644
--- a/src/plugins/miscellaneous/Core/tests/generaltests.cpp
+++ b/src/plugins/miscellaneous/Core/tests/generaltests.cpp
@@ -57,6 +57,32 @@ void GeneralTests::sizeAsStringTests()
//==============================================================================
+void GeneralTests::formatTimeTests()
+{
+ // Test the formatTime() method
+
+ QCOMPARE(OpenCOR::Core::formatTime(0), QString("0ms"));
+ QCOMPARE(OpenCOR::Core::formatTime(999), QString("999ms"));
+ QCOMPARE(OpenCOR::Core::formatTime(1000), QString("1s"));
+ QCOMPARE(OpenCOR::Core::formatTime(59999), QString("59s 999ms"));
+ QCOMPARE(OpenCOR::Core::formatTime(60000), QString("1m"));
+ QCOMPARE(OpenCOR::Core::formatTime(60999), QString("1m 0s 999ms"));
+ QCOMPARE(OpenCOR::Core::formatTime(61000), QString("1m 1s"));
+ QCOMPARE(OpenCOR::Core::formatTime(3599999), QString("59m 59s 999ms"));
+ QCOMPARE(OpenCOR::Core::formatTime(3600000), QString("1h"));
+ QCOMPARE(OpenCOR::Core::formatTime(3600999), QString("1h 0m 0s 999ms"));
+ QCOMPARE(OpenCOR::Core::formatTime(3601000), QString("1h 0m 1s"));
+ QCOMPARE(OpenCOR::Core::formatTime(3660000), QString("1h 1m"));
+ QCOMPARE(OpenCOR::Core::formatTime(86399999), QString("23h 59m 59s 999ms"));
+ QCOMPARE(OpenCOR::Core::formatTime(86400000), QString("1d"));
+ QCOMPARE(OpenCOR::Core::formatTime(86400999), QString("1d 0h 0m 0s 999ms"));
+ QCOMPARE(OpenCOR::Core::formatTime(86401000), QString("1d 0h 0m 1s"));
+ QCOMPARE(OpenCOR::Core::formatTime(86460000), QString("1d 0h 1m"));
+ QCOMPARE(OpenCOR::Core::formatTime(90000000), QString("1d 1h"));
+}
+
+//==============================================================================
+
void GeneralTests::sha1Tests()
{
// Test the sha1() method
diff --git a/src/plugins/miscellaneous/Core/tests/generaltests.h b/src/plugins/miscellaneous/Core/tests/generaltests.h
index 757451bacf..fe31be8d22 100644
--- a/src/plugins/miscellaneous/Core/tests/generaltests.h
+++ b/src/plugins/miscellaneous/Core/tests/generaltests.h
@@ -41,6 +41,7 @@ private slots:
void initTestCase();
void sizeAsStringTests();
+ void formatTimeTests();
void sha1Tests();
void stringPositionAsLineColumnTests();
void stringLineColumnAsPositionTests();
diff --git a/src/plugins/simulation/SimulationExperimentView/i18n/SimulationExperimentView_fr.ts b/src/plugins/simulation/SimulationExperimentView/i18n/SimulationExperimentView_fr.ts
index 2a93714f2c..f891a37ce3 100644
--- a/src/plugins/simulation/SimulationExperimentView/i18n/SimulationExperimentView_fr.ts
+++ b/src/plugins/simulation/SimulationExperimentView/i18n/SimulationExperimentView_fr.ts
@@ -617,8 +617,8 @@
Temps de simulation :
-
- %1 s avec %2
+
+ %1 avec %2
diff --git a/src/plugins/simulation/SimulationExperimentView/src/simulationexperimentviewsimulationwidget.cpp b/src/plugins/simulation/SimulationExperimentView/src/simulationexperimentviewsimulationwidget.cpp
index bb3b15395f..93010621bb 100644
--- a/src/plugins/simulation/SimulationExperimentView/src/simulationexperimentviewsimulationwidget.cpp
+++ b/src/plugins/simulation/SimulationExperimentView/src/simulationexperimentviewsimulationwidget.cpp
@@ -3258,8 +3258,8 @@ void SimulationExperimentViewSimulationWidget::simulationStopped(qint64 pElapsed
if (!mSimulation->data()->nlaSolverName().isEmpty())
solversInformation += "+"+mSimulation->data()->nlaSolverName();
- output(QString(OutputTab+""+tr("Simulation time:")+" "+tr("%1 s using %2").arg(QString::number(0.001*pElapsedTime, 'g', 3))
- .arg(solversInformation)+"."+OutputBrLn));
+ output(QString(OutputTab+""+tr("Simulation time:")+" "+tr("%1 using %2").arg(Core::formatTime(pElapsedTime))
+ .arg(solversInformation)+"."+OutputBrLn));
}
// Update our parameters and simulation mode