]> sigrok.org Git - pulseview.git/blobdiff - pv/util.cpp
Session: Fix issue #67 by improving error handling
[pulseview.git] / pv / util.cpp
index 8f2d7d2544cd8e30301a28c56f6537269dbe759a..dfb8c72b43504a95ad1f107c66a16e289858ba82 100644 (file)
@@ -110,25 +110,31 @@ static QTextStream& operator<<(QTextStream& stream, const Timestamp& t)
        return stream << QString::fromStdString(str);
 }
 
-QString format_time_si(const Timestamp& v, SIPrefix prefix,
-       unsigned int precision, QString unit, bool sign)
+SIPrefix determine_value_prefix(double v)
 {
-       if (prefix == SIPrefix::unspecified) {
-               // No prefix given, calculate it
-
-               if (v.is_zero()) {
-                       prefix = SIPrefix::none;
-               } else {
-                       int exp = exponent(SIPrefix::yotta);
-                       prefix = SIPrefix::yocto;
-                       while ((fabs(v) * pow(Timestamp(10), exp)) > 999 &&
-                                       prefix < SIPrefix::yotta) {
-                               prefix = successor(prefix);
-                               exp -= 3;
-                       }
+       SIPrefix prefix;
+
+       if (v == 0) {
+               prefix = SIPrefix::none;
+       } else {
+               int exp = exponent(SIPrefix::yotta);
+               prefix = SIPrefix::yocto;
+               while ((fabs(v) * pow(10, exp)) > 999 &&
+                               prefix < SIPrefix::yotta) {
+                       prefix = successor(prefix);
+                       exp -= 3;
                }
        }
 
+       return prefix;
+}
+
+QString format_time_si(const Timestamp& v, SIPrefix prefix,
+       unsigned int precision, QString unit, bool sign)
+{
+       if (prefix == SIPrefix::unspecified)
+               prefix = determine_value_prefix(v.convert_to<double>());
+
        assert(prefix >= SIPrefix::yocto);
        assert(prefix <= SIPrefix::yotta);
 
@@ -137,9 +143,36 @@ QString format_time_si(const Timestamp& v, SIPrefix prefix,
        QString s;
        QTextStream ts(&s);
        if (sign && !v.is_zero())
-               ts << forcesign;
-       ts << qSetRealNumberPrecision(precision) << (v * multiplier) << ' '
-               << prefix << unit;
+               ts.setNumberFlags(ts.numberFlags() | QTextStream::ForceSign);
+       ts << qSetRealNumberPrecision(precision) << (v * multiplier);
+       ts << ' ' << prefix << unit;
+
+       return s;
+}
+
+QString format_value_si(double v, SIPrefix prefix, unsigned precision,
+       QString unit, bool sign)
+{
+       if (prefix == SIPrefix::unspecified) {
+               prefix = determine_value_prefix(v);
+
+               const int prefix_order = -exponent(prefix);
+               precision = (prefix >= SIPrefix::none) ? max((int)(precision + prefix_order), 0) :
+                       max((int)(precision - prefix_order), 0);
+       }
+
+       assert(prefix >= SIPrefix::yocto);
+       assert(prefix <= SIPrefix::yotta);
+
+       const double multiplier = pow(10.0, -exponent(prefix));
+
+       QString s;
+       QTextStream ts(&s);
+       if (sign && (v != 0))
+               ts.setNumberFlags(ts.numberFlags() | QTextStream::ForceSign);
+       ts.setRealNumberNotation(QTextStream::FixedNotation);
+       ts.setRealNumberPrecision(precision);
+       ts << (v * multiplier) << ' ' << prefix << unit;
 
        return s;
 }
@@ -224,5 +257,44 @@ QString format_time_minutes(const Timestamp& t, signed precision, bool sign)
        return s;
 }
 
+/**
+ * Split a string into tokens at occurences of the separator.
+ *
+ * @param[in] text The input string to split.
+ * @param[in] separator The delimiter between tokens.
+ *
+ * @return A vector of broken down tokens.
+ */
+vector<string> split_string(string text, string separator)
+{
+       vector<string> result;
+       size_t pos;
+
+       while ((pos = text.find(separator)) != std::string::npos) {
+               result.push_back(text.substr(0, pos));
+               text = text.substr(pos + separator.length());
+       }
+       result.push_back(text);
+
+       return result;
+}
+
+/**
+ * Return the width of a string in a given font.
+ *
+ * @param[in] metric metrics of the font
+ * @param[in] string the string whose width should be determined
+ *
+ * @return width of the string in pixels
+ */
+std::streamsize text_width(const QFontMetrics &metric, const QString &string)
+{
+#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
+       return metric.horizontalAdvance(string);
+#else
+       return metric.width(string);
+#endif
+}
+
 } // namespace util
 } // namespace pv