diff options
Diffstat (limited to 'zen/format_unit.cpp')
-rwxr-xr-x | zen/format_unit.cpp | 402 |
1 files changed, 201 insertions, 201 deletions
diff --git a/zen/format_unit.cpp b/zen/format_unit.cpp index a2208b3e..c0667fb1 100755 --- a/zen/format_unit.cpp +++ b/zen/format_unit.cpp @@ -1,201 +1,201 @@ -// *****************************************************************************
-// * This file is part of the FreeFileSync project. It is distributed under *
-// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 *
-// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved *
-// *****************************************************************************
-
-#include "format_unit.h"
-//#include <cwchar> //swprintf
-#include <ctime>
-#include <cstdio>
-#include "basic_math.h"
-#include "i18n.h"
-#include "time.h"
-#include "globals.h"
-
- #include <clocale> //thousands separator
- #include "utf.h" //
-
-using namespace zen;
-
-
-std::wstring zen::formatTwoDigitPrecision(double value)
-{
- //print two digits: 0,1 | 1,1 | 11
- if (numeric::abs(value) < 9.95) //9.99 must not be formatted as "10.0"
- return printNumber<std::wstring>(L"%.1f", value);
- return numberTo<std::wstring>(numeric::round(value));
-}
-
-
-std::wstring zen::formatThreeDigitPrecision(double value)
-{
- //print three digits: 0,01 | 0,11 | 1,11 | 11,1 | 111
- if (numeric::abs(value) < 9.995) //9.999 must not be formatted as "10.00"
- return printNumber<std::wstring>(L"%.2f", value);
- if (numeric::abs(value) < 99.95) //99.99 must not be formatted as "100.0"
- return printNumber<std::wstring>(L"%.1f", value);
- return numberTo<std::wstring>(numeric::round(value));
-}
-
-
-std::wstring zen::filesizeToShortString(int64_t size)
-{
- //if (size < 0) return _("Error"); -> really?
-
- if (numeric::abs(size) <= 999)
- return _P("1 byte", "%x bytes", static_cast<int>(size));
-
- double sizeInUnit = static_cast<double>(size);
-
- auto formatUnit = [&](const std::wstring& unitTxt) { return replaceCpy(unitTxt, L"%x", formatThreeDigitPrecision(sizeInUnit)); };
-
- sizeInUnit /= 1024;
- if (numeric::abs(sizeInUnit) < 999.5)
- return formatUnit(_("%x KB"));
-
- sizeInUnit /= 1024;
- if (numeric::abs(sizeInUnit) < 999.5)
- return formatUnit(_("%x MB"));
-
- sizeInUnit /= 1024;
- if (numeric::abs(sizeInUnit) < 999.5)
- return formatUnit(_("%x GB"));
-
- sizeInUnit /= 1024;
- if (numeric::abs(sizeInUnit) < 999.5)
- return formatUnit(_("%x TB"));
-
- sizeInUnit /= 1024;
- return formatUnit(_("%x PB"));
-}
-
-
-namespace
-{
-enum UnitRemTime
-{
- URT_SEC,
- URT_MIN,
- URT_HOUR,
- URT_DAY
-};
-
-
-std::wstring formatUnitTime(int val, UnitRemTime unit)
-{
- switch (unit)
- {
- case URT_SEC:
- return _P("1 sec", "%x sec", val);
- case URT_MIN:
- return _P("1 min", "%x min", val);
- case URT_HOUR:
- return _P("1 hour", "%x hours", val);
- case URT_DAY:
- return _P("1 day", "%x days", val);
- }
- assert(false);
- return _("Error");
-}
-
-
-template <int M, int N>
-std::wstring roundToBlock(double timeInHigh,
- UnitRemTime unitHigh, const int (&stepsHigh)[M],
- int unitLowPerHigh,
- UnitRemTime unitLow, const int (&stepsLow)[N])
-{
- assert(unitLowPerHigh > 0);
- const double granularity = 0.1;
- const double timeInLow = timeInHigh * unitLowPerHigh;
- const int blockSizeLow = granularity * timeInHigh < 1 ?
- numeric::nearMatch(granularity * timeInLow, std::begin(stepsLow), std::end(stepsLow)):
- numeric::nearMatch(granularity * timeInHigh, std::begin(stepsHigh), std::end(stepsHigh)) * unitLowPerHigh;
- const int roundedtimeInLow = numeric::round(timeInLow / blockSizeLow) * blockSizeLow;
-
- std::wstring output = formatUnitTime(roundedtimeInLow / unitLowPerHigh, unitHigh);
- if (unitLowPerHigh > blockSizeLow)
- output += L" " + formatUnitTime(roundedtimeInLow % unitLowPerHigh, unitLow);
- return output;
-};
-}
-
-
-std::wstring zen::remainingTimeToString(double timeInSec)
-{
- const int steps10[] = { 1, 2, 5, 10 };
- const int steps24[] = { 1, 2, 3, 4, 6, 8, 12, 24 };
- const int steps60[] = { 1, 2, 5, 10, 15, 20, 30, 60 };
-
- //determine preferred unit
- double timeInUnit = timeInSec;
- if (timeInUnit <= 60)
- return roundToBlock(timeInUnit, URT_SEC, steps60, 1, URT_SEC, steps60);
-
- timeInUnit /= 60;
- if (timeInUnit <= 60)
- return roundToBlock(timeInUnit, URT_MIN, steps60, 60, URT_SEC, steps60);
-
- timeInUnit /= 60;
- if (timeInUnit <= 24)
- return roundToBlock(timeInUnit, URT_HOUR, steps24, 60, URT_MIN, steps60);
-
- timeInUnit /= 24;
- return roundToBlock(timeInUnit, URT_DAY, steps10, 24, URT_HOUR, steps24);
- //note: for 10% granularity steps10 yields a valid blocksize only up to timeInUnit == 100!
- //for larger time sizes this results in a finer granularity than expected: 10 days -> should not be a problem considering "usual" remaining time for synchronization
-}
-
-
-//std::wstring zen::fractionToString1Dec(double fraction)
-//{
-// return printNumber<std::wstring>(L"%.1f", fraction * 100.0) + L'%'; //no need to internationalize fraction!?
-//}
-
-
-std::wstring zen::fractionToString(double fraction)
-{
- return printNumber<std::wstring>(L"%.2f", fraction * 100.0) + L'%'; //no need to internationalize fraction!?
-}
-
-
-
-
-std::wstring zen::ffs_Impl::includeNumberSeparator(const std::wstring& number)
-{
- //we have to include thousands separator ourselves; this doesn't work for all countries (e.g india), but is better than nothing
-
- //::setlocale (LC_ALL, ""); -> implicitly called by wxLocale
- const lconv* localInfo = ::localeconv(); //always bound according to doc
- const std::wstring& thousandSep = utfTo<std::wstring>(localInfo->thousands_sep);
-
- // THOUSANDS_SEPARATOR = std::use_facet<std::numpunct<wchar_t>>(std::locale("")).thousands_sep(); - why not working?
- // DECIMAL_POINT = std::use_facet<std::numpunct<wchar_t>>(std::locale("")).decimal_point();
-
- std::wstring output(number);
- size_t i = output.size();
- for (;;)
- {
- if (i <= 3)
- break;
- i -= 3;
- if (!isDigit(output[i - 1])) //stop on +, - signs
- break;
- output.insert(i, thousandSep);
- }
- return output;
-}
-
-
-std::wstring zen::utcToLocalTimeString(int64_t utcTime)
-{
- auto errorMsg = [&] { return _("Error") + L" (time_t: " + numberTo<std::wstring>(utcTime) + L")"; };
-
- TimeComp loc = getLocalTime(utcTime);
-
- std::wstring dateString = formatTime<std::wstring>(L"%x %X", loc);
- return !dateString.empty() ? dateString : errorMsg();
-}
-
-
+// ***************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 * +// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved * +// ***************************************************************************** + +#include "format_unit.h" +//#include <cwchar> //swprintf +#include <ctime> +#include <cstdio> +#include "basic_math.h" +#include "i18n.h" +#include "time.h" +#include "globals.h" + + #include <clocale> //thousands separator + #include "utf.h" // + +using namespace zen; + + +std::wstring zen::formatTwoDigitPrecision(double value) +{ + //print two digits: 0,1 | 1,1 | 11 + if (numeric::abs(value) < 9.95) //9.99 must not be formatted as "10.0" + return printNumber<std::wstring>(L"%.1f", value); + return numberTo<std::wstring>(numeric::round(value)); +} + + +std::wstring zen::formatThreeDigitPrecision(double value) +{ + //print three digits: 0,01 | 0,11 | 1,11 | 11,1 | 111 + if (numeric::abs(value) < 9.995) //9.999 must not be formatted as "10.00" + return printNumber<std::wstring>(L"%.2f", value); + if (numeric::abs(value) < 99.95) //99.99 must not be formatted as "100.0" + return printNumber<std::wstring>(L"%.1f", value); + return numberTo<std::wstring>(numeric::round(value)); +} + + +std::wstring zen::filesizeToShortString(int64_t size) +{ + //if (size < 0) return _("Error"); -> really? + + if (numeric::abs(size) <= 999) + return _P("1 byte", "%x bytes", static_cast<int>(size)); + + double sizeInUnit = static_cast<double>(size); + + auto formatUnit = [&](const std::wstring& unitTxt) { return replaceCpy(unitTxt, L"%x", formatThreeDigitPrecision(sizeInUnit)); }; + + sizeInUnit /= 1024; + if (numeric::abs(sizeInUnit) < 999.5) + return formatUnit(_("%x KB")); + + sizeInUnit /= 1024; + if (numeric::abs(sizeInUnit) < 999.5) + return formatUnit(_("%x MB")); + + sizeInUnit /= 1024; + if (numeric::abs(sizeInUnit) < 999.5) + return formatUnit(_("%x GB")); + + sizeInUnit /= 1024; + if (numeric::abs(sizeInUnit) < 999.5) + return formatUnit(_("%x TB")); + + sizeInUnit /= 1024; + return formatUnit(_("%x PB")); +} + + +namespace +{ +enum UnitRemTime +{ + URT_SEC, + URT_MIN, + URT_HOUR, + URT_DAY +}; + + +std::wstring formatUnitTime(int val, UnitRemTime unit) +{ + switch (unit) + { + case URT_SEC: + return _P("1 sec", "%x sec", val); + case URT_MIN: + return _P("1 min", "%x min", val); + case URT_HOUR: + return _P("1 hour", "%x hours", val); + case URT_DAY: + return _P("1 day", "%x days", val); + } + assert(false); + return _("Error"); +} + + +template <int M, int N> +std::wstring roundToBlock(double timeInHigh, + UnitRemTime unitHigh, const int (&stepsHigh)[M], + int unitLowPerHigh, + UnitRemTime unitLow, const int (&stepsLow)[N]) +{ + assert(unitLowPerHigh > 0); + const double granularity = 0.1; + const double timeInLow = timeInHigh * unitLowPerHigh; + const int blockSizeLow = granularity * timeInHigh < 1 ? + numeric::nearMatch(granularity * timeInLow, std::begin(stepsLow), std::end(stepsLow)): + numeric::nearMatch(granularity * timeInHigh, std::begin(stepsHigh), std::end(stepsHigh)) * unitLowPerHigh; + const int roundedtimeInLow = numeric::round(timeInLow / blockSizeLow) * blockSizeLow; + + std::wstring output = formatUnitTime(roundedtimeInLow / unitLowPerHigh, unitHigh); + if (unitLowPerHigh > blockSizeLow) + output += L" " + formatUnitTime(roundedtimeInLow % unitLowPerHigh, unitLow); + return output; +}; +} + + +std::wstring zen::remainingTimeToString(double timeInSec) +{ + const int steps10[] = { 1, 2, 5, 10 }; + const int steps24[] = { 1, 2, 3, 4, 6, 8, 12, 24 }; + const int steps60[] = { 1, 2, 5, 10, 15, 20, 30, 60 }; + + //determine preferred unit + double timeInUnit = timeInSec; + if (timeInUnit <= 60) + return roundToBlock(timeInUnit, URT_SEC, steps60, 1, URT_SEC, steps60); + + timeInUnit /= 60; + if (timeInUnit <= 60) + return roundToBlock(timeInUnit, URT_MIN, steps60, 60, URT_SEC, steps60); + + timeInUnit /= 60; + if (timeInUnit <= 24) + return roundToBlock(timeInUnit, URT_HOUR, steps24, 60, URT_MIN, steps60); + + timeInUnit /= 24; + return roundToBlock(timeInUnit, URT_DAY, steps10, 24, URT_HOUR, steps24); + //note: for 10% granularity steps10 yields a valid blocksize only up to timeInUnit == 100! + //for larger time sizes this results in a finer granularity than expected: 10 days -> should not be a problem considering "usual" remaining time for synchronization +} + + +//std::wstring zen::fractionToString1Dec(double fraction) +//{ +// return printNumber<std::wstring>(L"%.1f", fraction * 100.0) + L'%'; //no need to internationalize fraction!? +//} + + +std::wstring zen::fractionToString(double fraction) +{ + return printNumber<std::wstring>(L"%.2f", fraction * 100.0) + L'%'; //no need to internationalize fraction!? +} + + + + +std::wstring zen::ffs_Impl::includeNumberSeparator(const std::wstring& number) +{ + //we have to include thousands separator ourselves; this doesn't work for all countries (e.g india), but is better than nothing + + //::setlocale (LC_ALL, ""); -> implicitly called by wxLocale + const lconv* localInfo = ::localeconv(); //always bound according to doc + const std::wstring& thousandSep = utfTo<std::wstring>(localInfo->thousands_sep); + + // THOUSANDS_SEPARATOR = std::use_facet<std::numpunct<wchar_t>>(std::locale("")).thousands_sep(); - why not working? + // DECIMAL_POINT = std::use_facet<std::numpunct<wchar_t>>(std::locale("")).decimal_point(); + + std::wstring output(number); + size_t i = output.size(); + for (;;) + { + if (i <= 3) + break; + i -= 3; + if (!isDigit(output[i - 1])) //stop on +, - signs + break; + output.insert(i, thousandSep); + } + return output; +} + + +std::wstring zen::utcToLocalTimeString(int64_t utcTime) +{ + auto errorMsg = [&] { return _("Error") + L" (time_t: " + numberTo<std::wstring>(utcTime) + L")"; }; + + TimeComp loc = getLocalTime(utcTime); + + std::wstring dateString = formatTime<std::wstring>(L"%x %X", loc); + return !dateString.empty() ? dateString : errorMsg(); +} + + |