M changelog.md => changelog.md +1 -0
@@ 21,6 21,7 @@
* `[GUI][messages]` Fixed not showing number on deleting temporary contact
* `[GUI]` Fixed filling Label with color
+* `[calculator]` Fix phone hanging when pressing '='.
## [0.44.1 2020-10-30]
M module-apps/application-calculator/data/CalculatorUtility.cpp => module-apps/application-calculator/data/CalculatorUtility.cpp +2 -7
@@ 5,6 5,7 @@
#include "application-calculator/widgets/CalculatorStyle.hpp"
#include <module-utils/tinyexpr/tinyexpr.h>
#include <module-utils/i18/i18.hpp>
+#include <Utils.hpp>
#include <cmath>
Result Calculator::calculate(std::string source)
@@ 13,13 14,7 @@ Result Calculator::calculate(std::string source)
int error;
double result = te_interp(source.c_str(), &error);
if (error == 0 && !std::isinf(result) && !std::isnan(result)) {
- auto output = std::to_string(result);
- if (output.find_last_not_of('0') != std::string::npos) {
- output.erase(output.find_last_not_of('0') + 1);
- }
- if (output.find_last_not_of(style::calculator::symbols::strings::full_stop) != std::string::npos) {
- output.erase(output.find_last_not_of(style::calculator::symbols::strings::full_stop) + 1);
- }
+ auto output = utils::to_string(result);
if (utils::localize.get("app_calculator_decimal_separator") == style::calculator::symbols::strings::comma) {
output.replace(output.find(style::calculator::symbols::strings::full_stop),
style::calculator::symbols::strings::full_stop.length(),
M module-apps/application-calculator/windows/CalculatorMainWindow.cpp => module-apps/application-calculator/windows/CalculatorMainWindow.cpp +4 -4
@@ 108,16 108,16 @@ namespace gui
if (!mathOperationInput->getText().empty()) {
if (lastCharIsSymbol && symbol != style::calculator::symbols::strings::minus) {
- mathOperationInput->setText(
+ mathOperationInput->setRichText(
std::string(mathOperationInput->getText()).erase(mathOperationInput->getText().length() - 1) +
symbol.c_str());
}
else {
- mathOperationInput->setText(mathOperationInput->getText() + symbol);
+ mathOperationInput->setRichText(mathOperationInput->getText() + symbol);
}
}
else if (symbol == style::calculator::symbols::strings::minus) {
- mathOperationInput->setText(mathOperationInput->getText() + symbol);
+ mathOperationInput->setRichText(mathOperationInput->getText() + symbol);
}
}
@@ 156,7 156,7 @@ namespace gui
if (inputEvent.keyCode == gui::KeyCode::KEY_ENTER) {
auto result = Calculator().calculate(std::string(mathOperationInput->getText()));
- mathOperationInput->setText(result.value);
+ mathOperationInput->setRichText(result.value);
clearInput = result.isError;
return true;
}
M module-utils/Utils.hpp => module-utils/Utils.hpp +51 -2
@@ 7,6 7,7 @@
#include <log/log.hpp>
#include <sstream>
#include <iomanip>
+#include <cmath>
#define MAGIC_ENUM_RANGE_MAX 256
#include <magic_enum.hpp>
@@ 89,14 90,62 @@ namespace utils
return rtrim(ltrim(s));
}
- template <typename T> std::string to_string(T t, size_t minStringLength = 0)
+ static inline std::string addLeadingZeros(std::string base, size_t minStringLength = 0)
{
+ if (base.length() >= minStringLength) {
+ return base;
+ }
constexpr auto leadingDigit = '0';
+ base.insert(0, minStringLength - base.length(), leadingDigit);
+ return base;
+ }
+
+ template <typename T> std::string to_string(T t)
+ {
std::ostringstream ss;
- ss << std::setfill(leadingDigit) << std::setw(minStringLength) << t;
+ ss << t;
return ss.str();
}
+ template <> inline std::string to_string<long double>(long double t)
+ {
+ uint32_t precision = 6;
+ int base = static_cast<int>(t);
+ long double frac = (t - base) * pow(10, precision);
+ auto baseAsStr = std::to_string(base);
+ if (t < 0) {
+ frac *= -1;
+ if (base == 0) {
+ baseAsStr = "-0";
+ }
+ }
+ auto fractionalPart = static_cast<unsigned long int>(roundl(frac));
+ if (fractionalPart == 0) {
+ if (baseAsStr == "-0") {
+ return "0";
+ }
+ return baseAsStr;
+ }
+ auto fractionalAsStr = std::to_string(fractionalPart);
+ if (fractionalAsStr.size() < precision) {
+ fractionalAsStr.insert(0, precision - fractionalAsStr.size(), '0');
+ }
+ if (fractionalAsStr.find_last_not_of('0') != std::string::npos) {
+ fractionalAsStr.erase(fractionalAsStr.find_last_not_of('0') + 1);
+ }
+ return baseAsStr + "." + fractionalAsStr;
+ }
+
+ template <> inline std::string to_string<float>(float t)
+ {
+ return to_string((long double)(t));
+ }
+
+ template <> inline std::string to_string<double>(double t)
+ {
+ return to_string((long double)(t));
+ }
+
template <typename T>[[nodiscard]] const std::string enumToString(const T &t)
{
static_assert(std::is_enum_v<T>);
M module-utils/test/unittest_utils.cpp => module-utils/test/unittest_utils.cpp +61 -0
@@ 208,3 208,64 @@ TEST_CASE("Swap endianness")
REQUIRE(((as_long >> 8 * 0) & 0xFF) == ((as_long_swapped >> 8 * 3) & 0xFF));
}
}
+
+TEST_CASE("Floating point to string")
+{
+ SECTION("Double")
+ {
+ double test = 15.0965432456321;
+ REQUIRE(utils::to_string(test) == "15.096543");
+ }
+
+ SECTION("Negative double")
+ {
+ double test = -15.0965432456321;
+ REQUIRE(utils::to_string(test) == "-15.096543");
+ }
+
+ SECTION("Double between 0 and 1")
+ {
+ double test = 0.08654328765876;
+ REQUIRE(utils::to_string(test) == "0.086543");
+ }
+
+ SECTION("Double between -1 and 0")
+ {
+ double test = -0.08654328765876;
+ REQUIRE(utils::to_string(test) == "-0.086543");
+ }
+
+ SECTION("Float")
+ {
+ float test = 15.0543212;
+ REQUIRE(utils::to_string(test) == "15.054321");
+ }
+
+ SECTION("Negative float")
+ {
+ float test = -15.0543212;
+ REQUIRE(utils::to_string(test) == "-15.054321");
+ }
+
+ SECTION("Float between 0 and 1")
+ {
+ float test = 0.0453212;
+ REQUIRE(utils::to_string(test) == "0.045321");
+ }
+
+ SECTION("Float between -1 and 0")
+ {
+ float test = -0.0453212;
+ REQUIRE(utils::to_string(test) == "-0.045321");
+ }
+}
+
+TEST_CASE("Fill leading digit in string")
+{
+ std::string test = "45";
+ REQUIRE(utils::addLeadingZeros(test) == "45");
+ REQUIRE(utils::addLeadingZeros(test, 1) == "45");
+ REQUIRE(utils::addLeadingZeros(test, 2) == "45");
+ REQUIRE(utils::addLeadingZeros(test, 3) == "045");
+ REQUIRE(utils::addLeadingZeros(test, 4) == "0045");
+}
M module-utils/time/time_conversion.cpp => module-utils/time/time_conversion.cpp +8 -4
@@ 264,10 264,14 @@ namespace utils
utils::findAndReplaceAll(format, "%M", utils::to_string(minutes));
utils::findAndReplaceAll(format, "%N", utils::to_string(hmminutes));
utils::findAndReplaceAll(format, "%S", utils::to_string(seconds));
- utils::findAndReplaceAll(format, "%0H", utils::to_string(hours, numberOfLeadingDigits));
- utils::findAndReplaceAll(format, "%0M", utils::to_string(minutes, numberOfLeadingDigits));
- utils::findAndReplaceAll(format, "%0N", utils::to_string(hmminutes, numberOfLeadingDigits));
- utils::findAndReplaceAll(format, "%0S", utils::to_string(seconds, numberOfLeadingDigits));
+ utils::findAndReplaceAll(
+ format, "%0H", utils::addLeadingZeros(utils::to_string(hours), numberOfLeadingDigits));
+ utils::findAndReplaceAll(
+ format, "%0M", utils::addLeadingZeros(utils::to_string(minutes), numberOfLeadingDigits));
+ utils::findAndReplaceAll(
+ format, "%0N", utils::addLeadingZeros(utils::to_string(hmminutes), numberOfLeadingDigits));
+ utils::findAndReplaceAll(
+ format, "%0S", utils::addLeadingZeros(utils::to_string(seconds), numberOfLeadingDigits));
}
void Duration::calculate()