Improve FIT locations support
[GPXSee.git] / src / common / util.cpp
blobee7929d93de058d7dc36bbfa721e1175df5b343d
1 #include <cctype>
2 #include <cmath>
3 #include <QFileInfo>
4 #include <QTemporaryDir>
5 #include <QImageReader>
6 #ifdef Q_OS_ANDROID
7 #include <QUrl>
8 #include <QCoreApplication>
9 #include <QJniEnvironment>
10 #include <QJniObject>
11 #endif // Q_OS_ANDROID
12 #include "util.h"
14 #define SQLITE_DB_MAGIC "SQLite format 3"
16 #ifdef Q_OS_ANDROID
17 static QString documentName(const QString &path)
19 QJniEnvironment env;
21 QJniObject urlString = QJniObject::fromString(path);
22 QJniObject uri = QJniObject::callStaticObjectMethod("android/net/Uri",
23 "parse", "(Ljava/lang/String;)Landroid/net/Uri;",
24 urlString.object<jstring>());
25 if (!uri.isValid()) {
26 env->ExceptionClear();
27 return QString();
29 QJniObject context = QNativeInterface::QAndroidApplication::context();
30 if (!context.isValid()) {
31 env->ExceptionClear();
32 return QString();
34 QJniObject contentResolver = context.callObjectMethod(
35 "getContentResolver", "()Landroid/content/ContentResolver;");
36 if (!contentResolver.isValid()) {
37 env->ExceptionClear();
38 return QString();
40 QJniObject columnName = QJniObject::getStaticObjectField<jstring>(
41 "android/provider/MediaStore$MediaColumns", "DISPLAY_NAME");
42 if (!columnName.isValid()) {
43 env->ExceptionClear();
44 return QString();
46 jobjectArray stringArray = env->NewObjectArray(
47 1, env->FindClass("java/lang/String"), 0);
48 env->SetObjectArrayElement(stringArray, 0, columnName.object<jstring>());
49 QJniObject cursor = contentResolver.callObjectMethod("query",
50 "(Landroid/net/Uri;[Ljava/lang/String;Landroid/os/Bundle;"
51 "Landroid/os/CancellationSignal;)Landroid/database/Cursor;",
52 uri.object(), stringArray, 0, 0);
53 if (!cursor.isValid()) {
54 env->ExceptionClear();
55 return QString();
57 if (!cursor.callMethod<jboolean>("moveToFirst")) {
58 env->ExceptionClear();
59 return QString();
61 QJniObject str = cursor.callObjectMethod("getString",
62 "(I)Ljava/lang/String;", 0);
63 if (!str.isValid()) {
64 env->ExceptionClear();
65 return QString();
68 return str.toString();
70 #endif // Q_OS_ANDROID
72 int Util::str2int(const char *str, int len)
74 int res = 0;
76 for (const char *sp = str; sp < str + len; sp++) {
77 if (::isdigit(*sp))
78 res = res * 10 + *sp - '0';
79 else
80 return -1;
83 return res;
86 double Util::niceNum(double x, bool round)
88 int expv;
89 double f;
90 double nf;
92 expv = (int)floor(log10(x));
93 f = x / pow(10.0, expv);
95 if (round) {
96 if (f < 1.5)
97 nf = 1.0;
98 else if (f < 3.0)
99 nf = 2.0;
100 else if (f < 7.0)
101 nf = 5.0;
102 else
103 nf = 10.0;
104 } else {
105 if (f <= 1.0)
106 nf = 1.0;
107 else if (f <= 2.0)
108 nf = 2.0;
109 else if (f <= 5.0)
110 nf = 5.0;
111 else
112 nf = 10.0;
115 return nf * pow(10.0, expv);
118 int Util::log2i(unsigned val)
120 int ret = 0;
122 while (val >>= 1)
123 ret++;
125 return ret;
128 QString Util::file2name(const QString &path)
130 QFileInfo fi(displayName(path));
131 return fi.baseName().replace('_', ' ');
134 QString Util::displayName(const QString &path)
136 #ifdef Q_OS_ANDROID
137 QUrl url(path);
139 // Not an Android URL, return standard filename.
140 if (url.scheme() != "content") {
141 QFileInfo fi(path);
142 return fi.fileName();
143 // Directory browsing URLs. Those can not be translated using the Android
144 // content resolver but we can get the filename from the URL path.
145 } else if (url.path().startsWith("/tree/")) {
146 QFileInfo fi(url.fileName());
147 return fi.fileName();
148 // Translate all "regular" android URLs using the Android content resolver.
149 } else
150 return documentName(path);
151 #else
152 return path;
153 #endif // Q_OS_ANDROID
156 const QTemporaryDir &Util::tempDir()
158 static QTemporaryDir dir;
159 return dir;
162 bool Util::isSQLiteDB(const QString &path, QString &errorString)
164 QFile file(path);
165 char magic[sizeof(SQLITE_DB_MAGIC)];
167 if (!file.open(QFile::ReadOnly)) {
168 errorString = file.errorString();
169 return false;
171 if ((file.read(magic, sizeof(magic)) < (qint64)sizeof(magic))
172 || memcmp(SQLITE_DB_MAGIC, magic, sizeof(SQLITE_DB_MAGIC))) {
173 errorString = "Not a SQLite database file";
174 return false;
177 return true;
180 QImage Util::svg2img(const QString &path, qreal ratio)
182 QImageReader ir(path, "svg");
183 QSize s(ir.size());
184 if (!s.isValid())
185 return QImage();
187 ir.setScaledSize(QSize(s.width() * ratio, s.height() * ratio));
188 QImage img(ir.read());
189 img.setDevicePixelRatio(ratio);
191 return img;