2015-01-15 17:07:43 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2007,2008 Petri Damstén <damu@iki.fi>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
* published by the Free Software Foundation; either version 2 of
|
|
|
|
* the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "converterrunner.h"
|
|
|
|
#include <QApplication>
|
|
|
|
#include <QClipboard>
|
|
|
|
#include <QSet>
|
|
|
|
#include <KIcon>
|
|
|
|
#include <KDebug>
|
|
|
|
#include <KToolInvocation>
|
2021-07-17 23:53:25 +03:00
|
|
|
#include <kunitconversion.h>
|
2015-01-15 17:07:43 +00:00
|
|
|
|
|
|
|
#define CONVERSION_CHAR QLatin1Char( '>' )
|
|
|
|
|
|
|
|
class StringParser
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum GetType
|
|
|
|
{
|
|
|
|
GetString = 1,
|
|
|
|
GetDigit = 2
|
|
|
|
};
|
|
|
|
|
|
|
|
StringParser(const QString &s) : m_index(0), m_s(s) {};
|
|
|
|
~StringParser() {};
|
|
|
|
|
|
|
|
QString get(int type)
|
|
|
|
{
|
|
|
|
QChar current;
|
|
|
|
QString result;
|
|
|
|
|
|
|
|
passWhiteSpace();
|
|
|
|
while (true) {
|
|
|
|
current = next();
|
|
|
|
if (current.isNull()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (current.isSpace()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
bool number = isNumber(current);
|
|
|
|
if (type == GetDigit && !number) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (type == GetString && number) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(current == QLatin1Char( CONVERSION_CHAR )) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++m_index;
|
|
|
|
result += current;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isNumber(const QChar &ch)
|
|
|
|
{
|
|
|
|
if (ch.isNumber()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (QString(QLatin1String( ".,-+" )).contains( ch )) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString rest()
|
|
|
|
{
|
|
|
|
return m_s.mid(m_index).simplified();
|
|
|
|
}
|
|
|
|
|
|
|
|
void pass(const QStringList &strings)
|
|
|
|
{
|
|
|
|
passWhiteSpace();
|
|
|
|
const QString temp = m_s.mid(m_index);
|
|
|
|
|
|
|
|
foreach (const QString& s, strings) {
|
|
|
|
if (temp.startsWith(s)) {
|
|
|
|
m_index += s.length();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
void passWhiteSpace()
|
|
|
|
{
|
|
|
|
while (next().isSpace()) {
|
|
|
|
++m_index;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QChar next()
|
|
|
|
{
|
|
|
|
if (m_index >= m_s.size()) {
|
2019-05-15 00:24:16 +00:00
|
|
|
return QChar();
|
2015-01-15 17:07:43 +00:00
|
|
|
}
|
|
|
|
return m_s.at(m_index);
|
|
|
|
}
|
|
|
|
|
|
|
|
int m_index;
|
|
|
|
QString m_s;
|
|
|
|
};
|
|
|
|
|
|
|
|
ConverterRunner::ConverterRunner(QObject* parent, const QVariantList &args)
|
|
|
|
: Plasma::AbstractRunner(parent, args)
|
|
|
|
{
|
|
|
|
Q_UNUSED(args)
|
|
|
|
setObjectName(QLatin1String( "Converter" ));
|
|
|
|
|
|
|
|
m_separators << QString( CONVERSION_CHAR );
|
|
|
|
m_separators << i18nc("list of words that can used as amount of 'unit1' [in|to|as] 'unit2'",
|
|
|
|
"in;to;as").split(QLatin1Char( ';' ));
|
|
|
|
|
|
|
|
//can not ignore commands: we have things like m4
|
|
|
|
setIgnoredTypes(Plasma::RunnerContext::Directory | Plasma::RunnerContext::File |
|
|
|
|
Plasma::RunnerContext::NetworkLocation);
|
|
|
|
|
|
|
|
QString description = i18n("Converts the value of :q: when :q: is made up of "
|
|
|
|
"\"value unit [>, to, as, in] unit\". You can use the "
|
|
|
|
"Unit converter applet to find all available units.");
|
|
|
|
addSyntax(Plasma::RunnerSyntax(QLatin1String(":q:"), description));
|
|
|
|
}
|
|
|
|
|
|
|
|
ConverterRunner::~ConverterRunner()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConverterRunner::match(Plasma::RunnerContext &context)
|
|
|
|
{
|
|
|
|
const QString term = context.query();
|
|
|
|
if (term.size() < 2) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
StringParser cmd(term);
|
|
|
|
QString unit1;
|
|
|
|
QString value;
|
|
|
|
QString unit2;
|
|
|
|
|
|
|
|
unit1 = cmd.get(StringParser::GetString);
|
|
|
|
value = cmd.get(StringParser::GetDigit);
|
|
|
|
if (value.isEmpty()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (unit1.isEmpty()) {
|
|
|
|
unit1 = cmd.get(StringParser::GetString | StringParser::GetDigit);
|
|
|
|
if (unit1.isEmpty()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const QString s = cmd.get(StringParser::GetString);
|
|
|
|
|
|
|
|
if (!s.isEmpty() && !m_separators.contains(s)) {
|
2021-07-17 23:53:25 +03:00
|
|
|
unit1 += QLatin1Char(' ') + s;
|
2015-01-15 17:07:43 +00:00
|
|
|
}
|
|
|
|
if (s.isEmpty() || !m_separators.contains(s)) {
|
|
|
|
cmd.pass(m_separators);
|
|
|
|
}
|
|
|
|
unit2 = cmd.rest();
|
|
|
|
|
2021-07-17 23:53:25 +03:00
|
|
|
bool unit1valid = false;
|
|
|
|
QString description;
|
|
|
|
QStringList suggestions;
|
|
|
|
double unit1value = value.toDouble();
|
|
|
|
|
|
|
|
// qDebug() << Q_FUNC_INFO << unit1 << unit2 << unit1value;
|
|
|
|
|
|
|
|
KTemperature temp(unit1value, unit1);
|
|
|
|
if (temp.unitEnum() != KTemperature::Invalid) {
|
|
|
|
description = KTemperature::description();
|
|
|
|
unit1valid = true;
|
|
|
|
KTemperature temp2(0.0, unit2);
|
|
|
|
if (temp2.unitEnum() != KTemperature::Invalid) {
|
|
|
|
const double result = temp.convertTo(temp2.unitEnum());
|
|
|
|
Plasma::QueryMatch match(this);
|
|
|
|
match.setType(Plasma::QueryMatch::InformationalMatch);
|
|
|
|
match.setIcon(KIcon(QLatin1String("edit-copy")));
|
|
|
|
match.setText(QString::fromLatin1("%1 (%2)").arg(QString::number(result), temp2.unit()));
|
|
|
|
match.setData(result);
|
|
|
|
context.addMatch(term, match);
|
2015-01-15 17:07:43 +00:00
|
|
|
return;
|
|
|
|
}
|
2021-07-17 23:53:25 +03:00
|
|
|
for (int i = 0; i < KTemperature::UnitCount; i++) {
|
|
|
|
suggestions.append(temp.unitDescription(static_cast<KTemperature::KTempUnit>(i)));
|
|
|
|
}
|
2015-01-15 17:07:43 +00:00
|
|
|
}
|
|
|
|
|
2021-07-17 23:53:25 +03:00
|
|
|
if (!unit1valid) {
|
|
|
|
suggestions.clear();
|
|
|
|
description = KVelocity::description();
|
|
|
|
KVelocity velo(unit1value, unit1);
|
|
|
|
if (velo.unitEnum() != KVelocity::Invalid) {
|
|
|
|
unit1valid = true;
|
|
|
|
KVelocity velo2(0.0, unit2);
|
|
|
|
if (velo2.unitEnum() != KVelocity::Invalid) {
|
|
|
|
const double result = velo.convertTo(velo2.unitEnum());
|
|
|
|
Plasma::QueryMatch match(this);
|
|
|
|
match.setType(Plasma::QueryMatch::InformationalMatch);
|
|
|
|
match.setIcon(KIcon(QLatin1String("edit-copy")));
|
|
|
|
match.setText(QString::fromLatin1("%1 (%2)").arg(QString::number(result), velo2.unit()));
|
|
|
|
match.setData(result);
|
|
|
|
context.addMatch(term, match);
|
|
|
|
return;
|
2015-01-15 17:07:43 +00:00
|
|
|
}
|
2021-07-17 23:53:25 +03:00
|
|
|
for (int i = 0; i < KVelocity::UnitCount; i++) {
|
|
|
|
suggestions.append(velo.unitDescription(static_cast<KVelocity::KVeloUnit>(i)));
|
2015-01-15 17:07:43 +00:00
|
|
|
}
|
|
|
|
}
|
2021-07-17 23:53:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!unit1valid) {
|
|
|
|
suggestions.clear();
|
|
|
|
description = KPressure::description();
|
|
|
|
KPressure pres(unit1value, unit1);
|
|
|
|
if (pres.unitEnum() != KPressure::Invalid) {
|
|
|
|
unit1valid = true;
|
|
|
|
KPressure pres2(0.0, unit2);
|
|
|
|
if (pres2.unitEnum() != KPressure::Invalid) {
|
|
|
|
const double result = pres.convertTo(pres2.unitEnum());
|
|
|
|
Plasma::QueryMatch match(this);
|
|
|
|
match.setType(Plasma::QueryMatch::InformationalMatch);
|
|
|
|
match.setIcon(KIcon(QLatin1String("edit-copy")));
|
|
|
|
match.setText(QString::fromLatin1("%1 (%2)").arg(QString::number(result), pres2.unit()));
|
|
|
|
match.setData(result);
|
|
|
|
context.addMatch(term, match);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (int i = 0; i < KPressure::UnitCount; i++) {
|
|
|
|
suggestions.append(pres.unitDescription(static_cast<KPressure::KPresUnit>(i)));
|
|
|
|
}
|
2015-01-15 17:07:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-17 23:53:25 +03:00
|
|
|
if (!unit1valid) {
|
|
|
|
suggestions.clear();
|
|
|
|
description = KLength::description();
|
|
|
|
KLength leng(unit1value, unit1);
|
|
|
|
if (leng.unitEnum() != KLength::Invalid) {
|
|
|
|
unit1valid = true;
|
|
|
|
KLength leng2(0.0, unit2);
|
|
|
|
if (leng2.unitEnum() != KLength::Invalid) {
|
|
|
|
const double result = leng.convertTo(leng2.unitEnum());
|
|
|
|
Plasma::QueryMatch match(this);
|
|
|
|
match.setType(Plasma::QueryMatch::InformationalMatch);
|
|
|
|
match.setIcon(KIcon(QLatin1String("edit-copy")));
|
|
|
|
match.setText(QString::fromLatin1("%1 (%2)").arg(QString::number(result), leng2.unit()));
|
|
|
|
match.setData(result);
|
|
|
|
context.addMatch(term, match);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (int i = 0; i < KLength::UnitCount; i++) {
|
|
|
|
suggestions.append(leng.unitDescription(static_cast<KLength::KLengUnit>(i)));
|
|
|
|
}
|
2015-01-15 17:07:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-17 23:53:25 +03:00
|
|
|
// suggest the units
|
|
|
|
if (unit1valid) {
|
|
|
|
foreach (const QString &unit, suggestions) {
|
|
|
|
Plasma::QueryMatch match(this);
|
|
|
|
match.setType(Plasma::QueryMatch::CompletionMatch);
|
|
|
|
match.setIcon(KIcon(QLatin1String("ktip"))); // non-standard
|
|
|
|
match.setText(unit);
|
|
|
|
match.setData(description);
|
|
|
|
context.addMatch(term, match);
|
|
|
|
}
|
2015-01-15 17:07:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConverterRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match)
|
|
|
|
{
|
|
|
|
Q_UNUSED(context)
|
|
|
|
const QString data = match.data().toString();
|
|
|
|
if (data.startsWith(QLatin1String("http://"))) {
|
|
|
|
KToolInvocation::invokeBrowser(data);
|
|
|
|
} else {
|
|
|
|
QApplication::clipboard()->setText(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-27 11:02:43 +00:00
|
|
|
#include "moc_converterrunner.cpp"
|