2 * This file is part of the SmuView project.
4 * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
5 * Copyright (C) 2017-2022 Frank Stettner <frank-stettner@gmx.net>
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
31 #include <boost/serialization/nvp.hpp>
32 #include <boost/multiprecision/cpp_dec_float.hpp>
35 #include <libsigrokcxx/libsigrokcxx.hpp>
65 /// Returns the exponent that corresponds to a given prefix.
66 int exponent(SIPrefix prefix
);
68 /// Timestamp type providing yoctosecond resolution.
69 typedef boost::multiprecision::number
<
70 boost::multiprecision::cpp_dec_float
<24>,
71 boost::multiprecision::et_off
> Timestamp
;
74 * Returns the SI prefix as `int` based on the `value` and the sigrok digits.
76 * @param value The value.
77 * @param sr_digits The digits from the sigrok analog payload. Something like
78 * exponent with reversed polarity.
82 int prefix_from_value(const double value
, const int sr_digits
);
85 * Returns the number of decimal places based on the `prefix` and the sigrok digits.
87 * @param prefix The SI prefix as an `int`.
88 * @param sr_digits The digits from the sigrok analog payload. Something like
89 * exponent with reversed polarity.
93 int decimal_places_from_prefix(const int prefix
, const int sr_digits
);
96 * Formats and rescales a given double value and stores the results in
97 * `value_str` and `si_prefix`.
99 * @param value The value to format.
100 * @param total_digits The number of total digits (incl. the decimal places)
101 * for `value_str`. This is directly passed to
102 * `QString.arg()` as `fieldWidth`.
103 * @param sr_digits The digits from the sigrok analog payload. Something like
104 * exponent with reversed polarity.
105 * @param value_str A reference to a `QString` to stre the digits to.
106 * @param si_prefix A reference to a `QString` to store the SI prefix to.
107 * @param use_locale Format `value_str` by using the locale settings, otherwise
108 * the "C" locale will be used.
112 void format_value_si(
113 const double value
, const int total_digits
, const int sr_digits
,
114 QString
&value_str
, QString
&si_prefix_str
, const bool use_locale
= true);
116 void format_value_si_autoscale(
117 const double value
, const int total_digits
, const int decimal_places
,
118 QString
&value_str
, QString
&si_prefix_str
, const bool use_locale
= true);
121 * Formats a given timestamp with the specified SI prefix.
123 * If 'prefix' is left 'unspecified', the function chooses a prefix so that
124 * the value in front of the decimal point is between 1 and 999.
126 * The default value "s" for the unit argument makes the most sense when
127 * formatting time values, but a different value can be given if the function
128 * is reused to format a value of another quantity.
130 * @param timestamp The value to format.
131 * @param prefix The SI prefix to use.
132 * @param precision The number of digits after the decimal separator.
133 * @param unit The unit of quantity.
134 * @param sign Whether or not to add a sign also for positive numbers.
136 * @return The formatted value.
140 QString
format_time_si(const Timestamp
& timestamp
,
141 SIPrefix prefix
= SIPrefix::unspecified
, unsigned precision
= 0,
142 const QString
&unit
= "s", bool sign
= true);
145 * Wrapper around 'format_time_si()' that interprets the given 'precision'
146 * value as the number of decimal places if the timestamp would be formatted
147 * without a SI prefix (using 'SIPrefix::none') and adjusts the precision to
148 * match the given 'prefix'
150 * @param timestamp The value to format.
151 * @param prefix The SI prefix to use.
152 * @param precision The number of digits after the decimal separator if the
153 * 'prefix' would be 'SIPrefix::none', see above for more information.
154 * @param unit The unit of quantity.
155 * @param sign Whether or not to add a sign also for positive numbers.
157 * @return The formatted value.
161 QString
format_time_si_adjusted(const Timestamp
& timestamp
, SIPrefix prefix
,
162 unsigned precision
= 0, const QString
&unit
= "s", bool sign
= true);
165 * Formats the given timestamp using "[+-]DD:HH:MM:SS.mmm uuu nnn ppp..." format.
167 * "DD" and "HH" are left out if they would be "00" (but if "DD" is generated,
168 * "HH" is also always generated. The "MM:SS" part is always produced, the
169 * number of subsecond digits can be influenced using the 'precision' parameter.
171 * @param timestamp The value to format.
172 * @param precision The number of digits after the decimal separator.
173 * @param sign Whether or not to add a sign also for positive numbers.
175 * @return The formatted value.
179 QString
format_time_minutes(const Timestamp
& timestamp
, signed precision
= 0,
183 * Formats the given timestamp as a date using
184 * "yyyy.MM.dd hh:mm:ss.zzz" QDateTime.toString() format.
186 * The number of subsecond digits can be influenced using the
187 * 'precision' parameter.
189 * @param timestamp The value to format.
190 * @param precision The number of digits after the decimal separator.
192 * @return The formatted date.
196 QString
format_time_date(double timestamp
);
199 * Format the given UUID as a string without braches.
201 * @param uuid The UUID to format.
203 * @return The formated UUID.
205 string
format_uuid(QUuid uuid
);
208 * Split a string into tokens at occurences of the separator.
210 * @param[in] text The input string to split.
211 * @param[in] separator The delimiter between tokens.
213 * @return A vector of broken down tokens.
215 vector
<string
> split_string(string text
, const string
&separator
);
218 * Check if a string 'str' starts with the string 'start_str'.
220 * @param[in] str The string to check.
221 * @param[in] start_str The start string.
223 * @return True if string str starts with string start_str.
225 bool starts_with(const string
&str
, const string
&start_str
);
228 * Counts the number of digits for the given integer.
230 * @param[in] int The integers digits to count.
232 * @return Number of total digits.
234 int count_int_digits(int number
);
237 * Get the number of digits for the given double.
239 * @param[in] value The value of the double.
240 * @param[in] step Step size of the double.
242 * @return Number of total digits
244 int count_double_digits(double value
, double step
);
247 * Count the number of decimal places (number of digits after the decimal point)
249 * @param[in] step The step size from which to calculate the decimal places
251 * @return Number of decimal places
253 int count_decimal_places(double step
);
257 * Get the sr_digits as used in the analog payload from the step size.
259 * @param[in] step The step size from which to calculate the decimal places
261 * @return The sr_digits
263 int get_sr_digits(double step
);
266 * Parse a single CSV line.
267 * Based on https://stackoverflow.com/a/30338543
269 * @param[in] line The CSV line to parse.
271 * @return A vector of the values.
273 vector
<string
> parse_csv_line(const string
&line
);
278 Q_DECLARE_METATYPE(sv::util::Timestamp
)