4#include "abstractcommand.h"
35 #
if (QT_VERSION < QT_VERSION_CHECK(6, 2, 0))
38 &PokitDiscoveryAgent::errorOccurred,
41 qCWarning(lc).noquote() <<
tr(
"Bluetooth discovery error:") << error;
112 return uR
"("%1")"_s.arg(QString(field).replace('"'_L1, uR
"("")"_s));
131template<
typename R>
constexpr Ratio makeRatio() {
return Ratio{ R::num, R::den }; }
153 {
'E'_L1, makeRatio<std::exa>() },
154 {
'P'_L1, makeRatio<std::peta>() },
155 {
'T'_L1, makeRatio<std::tera>() },
156 {
'G'_L1, makeRatio<std::giga>() },
157 {
'M'_L1, makeRatio<std::mega>() },
158 {
'K'_L1, makeRatio<std::kilo>() },
159 {
'k'_L1, makeRatio<std::kilo>() },
160 {
'h'_L1, makeRatio<std::hecto>() },
161 {
'd'_L1, makeRatio<std::deci>() },
162 {
'c'_L1, makeRatio<std::centi>() },
163 {
'm'_L1, makeRatio<std::milli>() },
164 {
'u'_L1, makeRatio<std::micro>() },
165 {
QChar(0x00B5), makeRatio<std::micro>() },
166 {
'n'_L1, makeRatio<std::nano>() },
167 {
'p'_L1, makeRatio<std::pico>() },
168 {
'f'_L1, makeRatio<std::femto>() },
169 {
'a'_L1, makeRatio<std::atto>() },
177 ratio = makeRatio<std::ratio<1>>();
182 #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
185 const QChar siPrefix = number.
at(number.
size() - 1);
187 const auto iter = unitPrefixScaleMap.constFind(siPrefix);
188 if (iter != unitPrefixScaleMap.constEnd()) {
189 Q_ASSERT(iter->isValid());
195 #define DOKIT_RESULT(var) (var * ratio.num * R::den / ratio.den / R::num)
198 qulonglong integer = locale.
toULongLong(number, &ok);
204 for (ratio = makeRatio<R>(); DOKIT_RESULT(integer) < sensibleMinimum; ratio.
num *= 1000);
206 return (integer == 0) ? 0u : (quint32)DOKIT_RESULT(integer);
210 if (
const double dbl = locale.
toDouble(number, &ok); (ok) && (dbl > 0.0)) {
212 for (ratio = makeRatio<R>(); DOKIT_RESULT(dbl) < sensibleMinimum; ratio.
num *= 1000);
214 return static_cast<quint32
>(std::llround(DOKIT_RESULT(dbl)));
220#define DOKIT_INSTANTIATE_TEMPLATE_FUNCTION(type) template \
221quint32 AbstractCommand::parseNumber<type>(const QString &value, const QString &unit, const quint32 sensibleMinimum)
222DOKIT_INSTANTIATE_TEMPLATE_FUNCTION(std::exa);
223DOKIT_INSTANTIATE_TEMPLATE_FUNCTION(std::peta);
224DOKIT_INSTANTIATE_TEMPLATE_FUNCTION(std::tera);
225DOKIT_INSTANTIATE_TEMPLATE_FUNCTION(std::giga);
226DOKIT_INSTANTIATE_TEMPLATE_FUNCTION(std::mega);
227DOKIT_INSTANTIATE_TEMPLATE_FUNCTION(std::kilo);
228DOKIT_INSTANTIATE_TEMPLATE_FUNCTION(std::hecto);
229DOKIT_INSTANTIATE_TEMPLATE_FUNCTION(std::deca);
230DOKIT_INSTANTIATE_TEMPLATE_FUNCTION(std::ratio<1>);
231DOKIT_INSTANTIATE_TEMPLATE_FUNCTION(std::deci);
232DOKIT_INSTANTIATE_TEMPLATE_FUNCTION(std::centi);
233DOKIT_INSTANTIATE_TEMPLATE_FUNCTION(std::milli);
234DOKIT_INSTANTIATE_TEMPLATE_FUNCTION(std::micro);
235DOKIT_INSTANTIATE_TEMPLATE_FUNCTION(std::nano);
236DOKIT_INSTANTIATE_TEMPLATE_FUNCTION(std::pico);
237DOKIT_INSTANTIATE_TEMPLATE_FUNCTION(std::femto);
238DOKIT_INSTANTIATE_TEMPLATE_FUNCTION(std::atto);
239#undef DOKIT_INSTANTIATE_TEMPLATE_FUNCTION
270 for (
const QString &option: suppliedOptionNames) {
271 if (!supportedOptionNames.
contains(option)) {
272 qCInfo(lc).noquote() <<
tr(
"Ignoring option: %1").
arg(option);
278 if (parser.
isSet(u
"device"_s)) {
283 if ((supportedOptionNames.
contains(u
"output"_s)) &&
284 (parser.
isSet(u
"output"_s)))
287 if (output == u
"csv"_s) {
289 }
else if (output == u
"json"_s) {
291 }
else if (output == u
"text"_s) {
294 errors.
append(
tr(
"Unknown output format: %1").arg(output));
299 if (parser.
isSet(u
"timeout"_s)) {
302 errors.
append(
tr(
"Invalid timeout: %1").arg(parser.
value(u
"timeout"_s)));
304 qCWarning(lc).noquote() <<
tr(
"Platform does not support Bluetooth scan timeout");
307 qCDebug(lc).noquote() <<
tr(
"Set scan timeout to %1").
arg(
314 for (
const QString &option: requiredOptionNames) {
315 if (!parser.
isSet(option)) {
316 errors.
append(
tr(
"Missing required option: %1").arg(option));
QString deviceToScanFor
Device (if any) that were passed to processOptions().
AbstractCommand(QObject *const parent=nullptr)
Constructs a new command with parent.
virtual QStringList supportedOptions(const QCommandLineParser &parser) const
Returns a list of CLI option names supported by this command.
static quint32 parseNumber(const QString &value, const QString &unit, const quint32 sensibleMinimum=0)
Returns value as an integer multiple of the ratio R.
virtual void deviceDiscovered(const QBluetoothDeviceInfo &info)=0
Handles PokitDiscoveryAgent::pokitDeviceDiscovered signal.
PokitDiscoveryAgent * discoveryAgent
Agent for Pokit device discovery.
OutputFormat format
Selected output format.
@ Text
Plain unstructured text.
@ Csv
RFC 4180 compliant CSV text.
@ Json
RFC 8259 compliant JSON text.
virtual QStringList processOptions(const QCommandLineParser &parser)
Processes the relevant options from the command line parser.
virtual void deviceDiscoveryFinished()=0
Handles PokitDiscoveryAgent::deviceDiscoveryFinished signal.
static QString escapeCsvField(const QString &field)
Returns an RFC 4180 compliant version of field.
virtual QStringList requiredOptions(const QCommandLineParser &parser) const
Returns a list of CLI option names required by this command.
The PokitDiscoveryAgent class discovers nearby Pokit devices.
void pokitDeviceDiscovered(const QBluetoothDeviceInfo &info)
This signal is emitted when the Pokit device described by info is discovered.
Declares the PokitDevice class.
Declares the PokitDiscoveryAgent class.
QBluetoothDeviceDiscoveryAgent::Error error() const const
bool isSet(const QString &name) const const
QStringList optionNames() const const
QString value(const QString &optionName) const const
void exit(int returnCode)
QCoreApplication * instance()
void append(const T &value)
double toDouble(const QString &s, bool *ok) const const
qulonglong toULongLong(const QString &s, bool *ok) const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
QString tr(const char *sourceText, const char *disambiguation, int n)
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
const QChar at(int position) const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString toLower() const const
QString trimmed() const const
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
Declares the DOKIT_USE_STRINGLITERALS macro, and related functions.
#define DOKIT_USE_STRINGLITERALS
Internal macro for using either official Qt string literals (added in Qt 6.4), or our own equivalent ...
std::intmax_t num
Numerator.
bool isValid() const
Returns true if both num and den are non-zero.