1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-07-23 23:24:24 +02:00

Compare commits

...

18 Commits

Author SHA1 Message Date
03711ede97 Re-introduce the zoom level offset
Most Mapsforge themes expect the zoom levels to be offset by one from
the standard OSM zoom levels. Additionally, the rendering is much faster
which always helps when dealing with a format that slow like Mapsforge...
2023-08-13 13:00:05 +02:00
ab8ab9d731 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (468 of 468 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/zh_Hans/
2023-08-12 19:29:39 +02:00
d2d529b574 Translated using Weblate (Hungarian)
Currently translated at 100.0% (468 of 468 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/hu/
2023-08-12 19:29:38 +02:00
8647898d2a Translated using Weblate (Turkish)
Currently translated at 100.0% (468 of 468 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/tr/
2023-08-12 19:29:38 +02:00
a91f0d183f Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (468 of 468 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/nb_NO/
2023-08-12 19:29:38 +02:00
15add7652d Translated using Weblate (Danish)
Currently translated at 100.0% (468 of 468 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/da/
2023-08-12 19:29:37 +02:00
ced2b37ebc Translated using Weblate (Swedish)
Currently translated at 100.0% (468 of 468 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2023-08-12 19:29:37 +02:00
2315f1d5e9 Translated using Weblate (Russian)
Currently translated at 100.0% (468 of 468 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2023-08-12 19:29:37 +02:00
984a8b6afc Try to open all files when browsing using the keys 2023-08-12 07:44:36 +02:00
aa72e6e2ad Updated German translations 2023-08-12 07:02:04 +02:00
09df5589b6 Updated Czech translations 2023-08-12 07:01:35 +02:00
1b3d7b9b0f Localization update 2023-08-12 06:58:28 +02:00
f998148fec Added option to surpress error messages
Closes #487
2023-08-12 06:55:50 +02:00
183c35ec7a Merge branch 'origin/master' into Weblate. 2023-08-09 01:19:29 +02:00
7e10e6640c Added support for the "base-stroke-width" rendertheme parameters 2023-08-09 01:19:41 +02:00
97b61451b1 Removed the zoom level offset hack
In the Mapsforge library the offset is dependent on the tile size which is
in turn dependent on whether the tiles are hidpi or not. In other words
the Mapsforge library is broken and inconsistent between hidpi/non-hdpi
displays. GPXSee is consistent here and we have thus tochoose one zoom level
mapping (i.e. what zoom level corresponds to what resolution). Lets choose
"no offset" = more details on a given zoom level/resolution.
2023-08-09 01:12:42 +02:00
b6ef58e342 Merge branch 'origin/master' into Weblate. 2023-08-08 00:52:31 +02:00
4d6d9b3e4f Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (467 of 467 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/zh_Hans/
2023-08-07 11:51:35 +02:00
26 changed files with 4152 additions and 4009 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -86,14 +86,16 @@ int App::run()
{
MapAction *lastReady = 0;
QStringList args(arguments());
int silent = 0;
int showError = (args.count() - 1 > 1) ? 2 : 1;
_gui->show();
for (int i = 1; i < args.count(); i++) {
if (!_gui->openFile(args.at(i), true)) {
if (!_gui->openFile(args.at(i), false, silent)) {
MapAction *a;
if (!_gui->loadMap(args.at(i), a, true))
_gui->openFile(args.at(i), false);
_gui->openFile(args.at(i), true, showError);
else {
if (a)
lastReady = a;
@ -116,10 +118,13 @@ void App::appStateChanged(Qt::ApplicationState state)
QJniObject activity = QNativeInterface::QAndroidApplication::context();
QString path(activity.callObjectMethod<jstring>("intentPath").toString());
if (!path.isEmpty()) {
if (!_gui->openFile(path, true)) {
int silent = 0;
int showError = 1;
if (!_gui->openFile(path, false, silent)) {
MapAction *a;
if (!_gui->loadMap(path, a, true))
_gui->openFile(path, false);
_gui->openFile(path, true, showError);
else {
if (a)
a->trigger();
@ -132,13 +137,16 @@ void App::appStateChanged(Qt::ApplicationState state)
bool App::event(QEvent *event)
{
int silent = 0;
int showError = 1;
if (event->type() == QEvent::FileOpen) {
QFileOpenEvent *e = static_cast<QFileOpenEvent *>(event);
if (!_gui->openFile(e->file(), true)) {
if (!_gui->openFile(e->file(), false, silent)) {
MapAction *a;
if (!_gui->loadMap(e->file(), a, true))
return _gui->openFile(e->file(), false);
return _gui->openFile(e->file(), true, showError);
else {
if (a)
a->trigger();

View File

@ -4,6 +4,7 @@
#include <QMenuBar>
#include <QStatusBar>
#include <QMessageBox>
#include <QCheckBox>
#include <QFileDialog>
#include <QPrintDialog>
#include <QPainter>
@ -947,9 +948,10 @@ void GUI::openFile()
QStringList files(QFileDialog::getOpenFileNames(this, tr("Open file"),
_dataDir, Data::formats()));
#endif // Q_OS_ANDROID
int showError = (files.size() > 1) ? 2 : 1;
for (int i = 0; i < files.size(); i++)
openFile(files.at(i));
openFile(files.at(i), true, showError);
if (!files.isEmpty())
_dataDir = QFileInfo(files.last()).path();
}
@ -959,20 +961,21 @@ void GUI::openDir()
{
QString dir(QFileDialog::getExistingDirectory(this, tr("Open directory"),
_dataDir));
int showError = 1;
if (!dir.isEmpty()) {
_browser->setCurrentDir(dir);
openFile(_browser->current());
openFile(_browser->current(), true, showError);
}
}
#endif // Q_OS_ANDROID
bool GUI::openFile(const QString &fileName, bool silent)
bool GUI::openFile(const QString &fileName, bool tryUnknown, int &showError)
{
if (_files.contains(fileName))
return true;
if (!loadFile(fileName, silent))
if (!loadFile(fileName, tryUnknown, showError))
return false;
_files.append(fileName);
@ -991,14 +994,14 @@ bool GUI::openFile(const QString &fileName, bool silent)
return true;
}
bool GUI::loadFile(const QString &fileName, bool silent)
bool GUI::loadFile(const QString &fileName, bool tryUnknown, int &showError)
{
Data data(fileName, !silent);
Data data(fileName, tryUnknown);
if (data.isValid()) {
loadData(data);
return true;
} else if (!silent) {
} else {
updateNavigationActions();
updateStatusBarInfo();
updateWindowTitle();
@ -1007,14 +1010,26 @@ bool GUI::loadFile(const QString &fileName, bool silent)
if (_files.isEmpty())
_fileActionGroup->setEnabled(false);
QString error = tr("Error loading data file:") + "\n\n"
+ Util::displayName(fileName) + "\n\n" + data.errorString();
if (data.errorLine())
error.append("\n" + tr("Line: %1").arg(data.errorLine()));
QMessageBox::critical(this, APP_NAME, error);
return false;
} else
if (showError) {
QString error = tr("Error loading data file:") + "\n"
+ Util::displayName(fileName) + ": " + data.errorString();
if (data.errorLine())
error.append("\n" + tr("Line: %1").arg(data.errorLine()));
if (showError > 1) {
QMessageBox message(QMessageBox::Critical, APP_NAME, error,
QMessageBox::Ok, this);
QCheckBox checkBox(tr("Don't show again"));
message.setCheckBox(&checkBox);
message.exec();
if (checkBox.isChecked())
showError = 0;
} else
QMessageBox::critical(this, APP_NAME, error);
}
return false;
}
}
void GUI::loadData(const Data &data)
@ -1108,8 +1123,8 @@ bool GUI::openPOIFile(const QString &fileName)
return true;
} else {
QString error = tr("Error loading POI file:") + "\n\n"
+ Util::displayName(fileName) + "\n\n" + _poi->errorString();
QString error = tr("Error loading POI file:") + "\n"
+ Util::displayName(fileName) + ": " + _poi->errorString();
if (_poi->errorLine())
error.append("\n" + tr("Line: %1").arg(_poi->errorLine()));
QMessageBox::critical(this, APP_NAME, error);
@ -1466,8 +1481,9 @@ void GUI::reloadFiles()
_tabs.at(i)->clear();
_mapView->clear();
int showError = 2;
for (int i = 0; i < _files.size(); i++) {
if (!loadFile(_files.at(i))) {
if (!loadFile(_files.at(i), true, showError)) {
_files.removeAt(i);
i--;
}
@ -1692,8 +1708,8 @@ bool GUI::loadMapNode(const TreeNode<Map*> &node, MapAction *&action,
if (!map->isValid()) {
if (!silent)
QMessageBox::critical(this, APP_NAME,
tr("Error loading map:") + "\n\n"
+ Util::displayName(map->path()) + "\n\n"
tr("Error loading map:") + "\n"
+ Util::displayName(map->path()) + ": "
+ map->errorString());
delete map;
} else {
@ -1737,8 +1753,8 @@ void GUI::mapLoaded()
_showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true);
} else {
QString error = tr("Error loading map:") + "\n\n"
+ Util::displayName(map->path()) + "\n\n" + map->errorString();
QString error = tr("Error loading map:") + "\n"
+ Util::displayName(map->path()) + ": " + map->errorString();
QMessageBox::critical(this, APP_NAME, error);
action->deleteLater();
}
@ -1756,8 +1772,8 @@ void GUI::mapLoadedDir()
actions.append(action);
_mapView->loadMaps(actions);
} else {
QString error = tr("Error loading map:") + "\n\n"
+ Util::displayName(map->path()) + "\n\n" + map->errorString();
QString error = tr("Error loading map:") + "\n"
+ Util::displayName(map->path()) + ": " + map->errorString();
QMessageBox::critical(this, APP_NAME, error);
action->deleteLater();
}
@ -1779,7 +1795,7 @@ void GUI::loadMapDirNode(const TreeNode<Map *> &node, QList<MapAction*> &actions
if (!(a = findMapAction(existingActions, map))) {
if (!map->isValid()) {
QMessageBox::critical(this, APP_NAME, tr("Error loading map:")
+ "\n\n" + Util::displayName(map->path()) + "\n\n"
+ "\n" + Util::displayName(map->path()) + ": "
+ map->errorString());
delete map;
} else {
@ -2080,48 +2096,53 @@ void GUI::setGraphType(GraphType type)
void GUI::next()
{
int showError = 1;
QString file = _browser->next();
if (file.isNull())
return;
closeFiles();
openFile(file);
openFile(file, true, showError);
}
void GUI::prev()
{
int showError = 1;
QString file = _browser->prev();
if (file.isNull())
return;
closeFiles();
openFile(file);
openFile(file, true, showError);
}
void GUI::last()
{
int showError = 1;
QString file = _browser->last();
if (file.isNull())
return;
closeFiles();
openFile(file);
openFile(file, true, showError);
}
void GUI::first()
{
int showError = 1;
QString file = _browser->first();
if (file.isNull())
return;
closeFiles();
openFile(file);
openFile(file, true, showError);
}
#ifndef Q_OS_ANDROID
void GUI::keyPressEvent(QKeyEvent *event)
{
QString file;
int showError = 1;
switch (event->key()) {
case PREV_KEY:
@ -2167,7 +2188,7 @@ void GUI::keyPressEvent(QKeyEvent *event)
if (!file.isNull()) {
if (!(event->modifiers() & MODIFIER))
closeFiles();
openFile(file);
openFile(file, true, showError);
return;
}
@ -2200,14 +2221,16 @@ void GUI::dropEvent(QDropEvent *event)
{
MapAction *lastReady = 0;
QList<QUrl> urls(event->mimeData()->urls());
int silent = 0;
int showError = (urls.size() > 1) ? 2 : 1;
for (int i = 0; i < urls.size(); i++) {
QString file(urls.at(i).toLocalFile());
if (!openFile(file, true)) {
if (!openFile(file, false, silent)) {
MapAction *a;
if (!loadMap(file, a, true))
openFile(file, false);
openFile(file, true, showError);
else {
if (a)
lastReady = a;

View File

@ -44,7 +44,7 @@ class GUI : public QMainWindow
public:
GUI();
bool openFile(const QString &fileName, bool silent = false);
bool openFile(const QString &fileName, bool tryUnknown, int &showError);
bool loadMap(const QString &fileName, MapAction *&action,
bool silent = false);
void show();
@ -151,7 +151,7 @@ private:
void createBrowser();
bool openPOIFile(const QString &fileName);
bool loadFile(const QString &fileName, bool silent = false);
bool loadFile(const QString &fileName, bool tryUnknown, int &showError);
void loadData(const Data &data);
bool loadMapNode(const TreeNode<Map*> &node, MapAction *&action,
bool silent, const QList<QAction*> &existingActions);

View File

@ -13,7 +13,7 @@
class Data
{
public:
Data(const QString &fileName, bool full = true);
Data(const QString &fileName, bool tryUnknown = true);
bool isValid() const {return _valid;}
const QString &errorString() const {return _errorString;}

View File

@ -14,9 +14,10 @@ namespace Mapsforge {
class RasterTile
{
public:
/* Mapsforge maps zoom levels are offset by one against the standard OSM
zoom levels! We decrease the zoom level internaly here when initializing
_zoom and return the propper/increased value back in zoom() */
/* Most Mapsforge themes expect the zoom levels to be offset by one from
the standard OSM zoom levels! We decrease the zoom level internaly
here when initializing _zoom and return the propper (increased) value
back in zoom() */
RasterTile(const Projection &proj, const Transform &transform,
const Style *style, MapData *data, int zoom, const QRect &rect,
qreal ratio) : _proj(proj), _transform(transform), _style(style),

View File

@ -177,7 +177,7 @@ bool Style::Rule::match(int zoom, const QVector<MapData::Tag> &tags) const
}
void Style::area(QXmlStreamReader &reader, const QString &dir, qreal ratio,
const Rule &rule)
qreal baseStrokeWidth, const Rule &rule)
{
PathRender ri(rule, _paths.size() + _circles.size());
const QXmlStreamAttributes &attr = reader.attributes();
@ -192,7 +192,8 @@ void Style::area(QXmlStreamReader &reader, const QString &dir, qreal ratio,
if (attr.hasAttribute("stroke"))
ri._strokeColor = QColor(attr.value("stroke").toString());
if (attr.hasAttribute("stroke-width")) {
ri._strokeWidth = attr.value("stroke-width").toFloat(&ok);
ri._strokeWidth = attr.value("stroke-width").toFloat(&ok)
* baseStrokeWidth;
if (!ok || ri._strokeWidth < 0) {
reader.raiseError("invalid stroke-width value");
return;
@ -240,7 +241,8 @@ void Style::area(QXmlStreamReader &reader, const QString &dir, qreal ratio,
reader.skipCurrentElement();
}
void Style::line(QXmlStreamReader &reader, const Rule &rule)
void Style::line(QXmlStreamReader &reader, qreal baseStrokeWidth,
const Rule &rule)
{
PathRender ri(rule, _paths.size() + _circles.size());
const QXmlStreamAttributes &attr = reader.attributes();
@ -251,7 +253,8 @@ void Style::line(QXmlStreamReader &reader, const Rule &rule)
if (attr.hasAttribute("stroke"))
ri._strokeColor = QColor(attr.value("stroke").toString());
if (attr.hasAttribute("stroke-width")) {
ri._strokeWidth = attr.value("stroke-width").toFloat(&ok);
ri._strokeWidth = attr.value("stroke-width").toFloat(&ok)
* baseStrokeWidth;
if (!ok || ri._strokeWidth < 0) {
reader.raiseError("invalid stroke-width value");
return;
@ -299,7 +302,7 @@ void Style::line(QXmlStreamReader &reader, const Rule &rule)
ri._curve = true;
}
if (attr.hasAttribute("dy")) {
ri._dy = attr.value("dy").toDouble(&ok);
ri._dy = attr.value("dy").toDouble(&ok) * baseStrokeWidth;
if (!ok) {
reader.raiseError("invalid dy value");
return;
@ -312,7 +315,8 @@ void Style::line(QXmlStreamReader &reader, const Rule &rule)
reader.skipCurrentElement();
}
void Style::circle(QXmlStreamReader &reader, const Rule &rule)
void Style::circle(QXmlStreamReader &reader, qreal baseStrokeWidth,
const Rule &rule)
{
CircleRender ri(rule, _paths.size() + _circles.size());
const QXmlStreamAttributes &attr = reader.attributes();
@ -325,14 +329,14 @@ void Style::circle(QXmlStreamReader &reader, const Rule &rule)
if (attr.hasAttribute("stroke"))
strokeColor = QColor(attr.value("stroke").toString());
if (attr.hasAttribute("stroke-width")) {
strokeWidth = attr.value("stroke-width").toFloat(&ok);
strokeWidth = attr.value("stroke-width").toFloat(&ok) * baseStrokeWidth;
if (!ok || strokeWidth < 0) {
reader.raiseError("invalid stroke-width value");
return;
}
}
if (attr.hasAttribute("radius")) {
ri._radius = attr.value("radius").toDouble(&ok);
ri._radius = attr.value("radius").toDouble(&ok) * baseStrokeWidth;
if (!ok || ri._radius <= 0) {
reader.raiseError("invalid radius value");
return;
@ -495,8 +499,8 @@ void Style::symbol(QXmlStreamReader &reader, const QString &dir, qreal ratio,
}
void Style::rule(QXmlStreamReader &reader, const QString &dir,
const MapData &data, qreal ratio, const QSet<QString> &cats,
const Rule &parent)
const MapData &data, qreal ratio, qreal baseStrokeWidth,
const QSet<QString> &cats, const Rule &parent)
{
Rule r(parent);
const QXmlStreamAttributes &attr = reader.attributes();
@ -541,13 +545,13 @@ void Style::rule(QXmlStreamReader &reader, const QString &dir,
while (reader.readNextStartElement()) {
if (reader.name() == QLatin1String("rule"))
rule(reader, dir, data, ratio, cats, r);
rule(reader, dir, data, ratio, baseStrokeWidth, cats, r);
else if (reader.name() == QLatin1String("area"))
area(reader, dir, ratio, r);
area(reader, dir, ratio, baseStrokeWidth, r);
else if (reader.name() == QLatin1String("line"))
line(reader, r);
line(reader, baseStrokeWidth, r);
else if (reader.name() == QLatin1String("circle"))
circle(reader, r);
circle(reader, baseStrokeWidth, r);
else if (reader.name() == QLatin1String("pathText")) {
QList<QList<TextRender>*> list;
list.append(&_pathLabels);
@ -635,10 +639,21 @@ void Style::rendertheme(QXmlStreamReader &reader, const QString &dir,
{
Rule r;
QSet<QString> cats;
qreal baseStrokeWidth = 1.0;
const QXmlStreamAttributes &attr = reader.attributes();
if (attr.hasAttribute("base-stroke-width")) {
bool ok;
baseStrokeWidth = attr.value("base-stroke-width").toFloat(&ok);
if (!ok || baseStrokeWidth < 0) {
reader.raiseError("invalid base-stroke-width value");
return;
}
}
while (reader.readNextStartElement()) {
if (reader.name() == QLatin1String("rule"))
rule(reader, dir, data, ratio, cats, r);
rule(reader, dir, data, ratio, baseStrokeWidth, cats, r);
else if (reader.name() == QLatin1String("stylemenu")) {
Menu menu(stylemenu(reader));
cats = menu.cats();

View File

@ -298,11 +298,13 @@ private:
Menu stylemenu(QXmlStreamReader &reader);
QString cat(QXmlStreamReader &reader);
void rule(QXmlStreamReader &reader, const QString &dir, const MapData &data,
qreal ratio, const QSet<QString> &cats, const Rule &parent);
qreal ratio, qreal baseStrokeWidth, const QSet<QString> &cats,
const Rule &parent);
void area(QXmlStreamReader &reader, const QString &dir, qreal ratio,
qreal baseStrokeWidth, const Rule &rule);
void line(QXmlStreamReader &reader, qreal baseStrokeWidth, const Rule &rule);
void circle(QXmlStreamReader &reader, qreal baseStrokeWidth,
const Rule &rule);
void line(QXmlStreamReader &reader, const Rule &rule);
void circle(QXmlStreamReader &reader, const Rule &rule);
void text(QXmlStreamReader &reader, const MapData &data, const Rule &rule,
QList<QList<TextRender> *> &lists);
void symbol(QXmlStreamReader &reader, const QString &dir, qreal ratio,