1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-02-17 16:20:48 +01:00

Preserve directory structure when loading the maps

This commit is contained in:
Martin Tůma 2021-03-20 09:59:03 +01:00
parent 8196b96f65
commit 659cf4cc7a
6 changed files with 157 additions and 66 deletions

View File

@ -30,6 +30,7 @@ HEADERS += src/common/config.h \
src/common/range.h \ src/common/range.h \
src/common/rectc.h \ src/common/rectc.h \
src/common/textcodec.h \ src/common/textcodec.h \
src/common/treenode.h \
src/common/wgs84.h \ src/common/wgs84.h \
src/common/util.h \ src/common/util.h \
src/common/rtree.h \ src/common/rtree.h \

View File

@ -57,13 +57,15 @@
GUI::GUI() GUI::GUI()
{ {
TreeNode<MapAction*> mapActions;
loadPOIs(); loadPOIs();
createMapView(); createMapView();
createGraphTabs(); createGraphTabs();
createStatusBar(); createStatusBar();
createActions(); createActions(mapActions);
createMenus(); createMenus(mapActions);
createToolBars(); createToolBars();
createBrowser(); createBrowser();
@ -118,27 +120,40 @@ void GUI::createBrowser()
_browser->setFilter(Data::filter()); _browser->setFilter(Data::filter());
} }
void GUI::createMapActions() TreeNode<MapAction*> GUI::createMapActionsNode(const TreeNode<Map*> &node)
{ {
_mapsActionGroup = new QActionGroup(this); TreeNode<MapAction*> tree(node.name());
_mapsActionGroup->setExclusive(true);
QString mapDir(ProgramPaths::mapDir()); for (int i = 0; i < node.childs().size(); i++)
if (mapDir.isNull()) tree.addChild(createMapActionsNode(node.childs().at(i)));
return;
QList<Map*> maps(MapList::loadMaps(mapDir)); for (int i = 0; i < node.items().size(); i++) {
for (int i = 0; i < maps.count(); i++) { Map *map = node.items().at(i);
Map *map = maps.at(i);
if (map->isValid()) { if (map->isValid()) {
MapAction *a = createMapAction(map); MapAction *a = createMapAction(map);
connect(a, SIGNAL(loaded()), this, SLOT(mapInitialized())); connect(a, SIGNAL(loaded()), this, SLOT(mapInitialized()));
tree.addItem(a);
} else { } else {
qWarning("%s: %s", qPrintable(map->path()), qWarning("%s: %s", qPrintable(map->path()),
qPrintable(map->errorString())); qPrintable(map->errorString()));
delete map; delete map;
} }
} }
return tree;
}
TreeNode<MapAction*> GUI::createMapActions()
{
_mapsActionGroup = new QActionGroup(this);
_mapsActionGroup->setExclusive(true);
QString mapDir(ProgramPaths::mapDir());
if (mapDir.isNull())
return TreeNode<MapAction*>();
TreeNode<Map*> maps(MapList::loadMaps(mapDir));
return createMapActionsNode(maps);
} }
MapAction *GUI::createMapAction(Map *map) MapAction *GUI::createMapAction(Map *map)
@ -195,7 +210,7 @@ QAction *GUI::createPOIFileAction(const QString &fileName)
return a; return a;
} }
void GUI::createActions() void GUI::createActions(TreeNode<MapAction*> &mapActions)
{ {
QActionGroup *ag; QActionGroup *ag;
@ -300,7 +315,7 @@ void GUI::createActions()
createPOIFilesActions(); createPOIFilesActions();
// Map actions // Map actions
createMapActions(); mapActions = createMapActions();
_showMapAction = new QAction(QIcon(SHOW_MAP_ICON), tr("Show map"), _showMapAction = new QAction(QIcon(SHOW_MAP_ICON), tr("Show map"),
this); this);
_showMapAction->setEnabled(false); _showMapAction->setEnabled(false);
@ -523,7 +538,19 @@ void GUI::createActions()
connect(_firstAction, SIGNAL(triggered()), this, SLOT(first())); connect(_firstAction, SIGNAL(triggered()), this, SLOT(first()));
} }
void GUI::createMenus() void GUI::createMapNodeMenu(const TreeNode<MapAction*> &node, QMenu *menu)
{
for (int i = 0; i < node.childs().size(); i++) {
QMenu *cm = new QMenu(node.childs().at(i).name(), menu);
menu->addMenu(cm);
createMapNodeMenu(node.childs().at(i), cm);
}
for (int i = 0; i < node.items().size(); i++)
menu->addAction(node.items().at(i));
}
void GUI::createMenus(const TreeNode<MapAction*> &mapActions)
{ {
QMenu *fileMenu = menuBar()->addMenu(tr("&File")); QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(_openFileAction); fileMenu->addAction(_openFileAction);
@ -542,7 +569,7 @@ void GUI::createMenus()
#endif // Q_OS_MAC #endif // Q_OS_MAC
_mapMenu = menuBar()->addMenu(tr("&Map")); _mapMenu = menuBar()->addMenu(tr("&Map"));
_mapMenu->addActions(_mapsActionGroup->actions()); createMapNodeMenu(mapActions, _mapMenu);
_mapsEnd = _mapMenu->addSeparator(); _mapsEnd = _mapMenu->addSeparator();
_mapMenu->addAction(_loadMapAction); _mapMenu->addAction(_loadMapAction);
_mapMenu->addAction(_loadMapDirAction); _mapMenu->addAction(_loadMapDirAction);
@ -1500,15 +1527,18 @@ static MapAction *findMapAction(const QList<QAction*> &mapActions,
return 0; return 0;
} }
bool GUI::loadMap(const QString &fileName, MapAction *&action, bool silent) bool GUI::loadMapNode(const TreeNode<Map*> &node, MapAction *&action,
bool silent, const QList<QAction*> &existingActions)
{ {
QList<Map*> maps(MapList::loadMaps(fileName));
QList<QAction*> existingActions(_mapsActionGroup->actions());
MapAction *lastReady = 0;
bool valid = false; bool valid = false;
for (int i = 0; i < maps.size(); i++) { action = 0;
Map *map = maps.at(i);
for (int i = 0; i < node.childs().size(); i++)
valid = loadMapNode(node.childs().at(i), action, silent, existingActions);
for (int i = 0; i < node.items().size(); i++) {
Map *map = node.items().at(i);
MapAction *a; MapAction *a;
if (!(a = findMapAction(existingActions, map))) { if (!(a = findMapAction(existingActions, map))) {
@ -1524,7 +1554,7 @@ bool GUI::loadMap(const QString &fileName, MapAction *&action, bool silent)
_mapMenu->insertAction(_mapsEnd, a); _mapMenu->insertAction(_mapsEnd, a);
if (map->isReady()) { if (map->isReady()) {
lastReady = a; action = a;
_showMapAction->setEnabled(true); _showMapAction->setEnabled(true);
_clearMapCacheAction->setEnabled(true); _clearMapCacheAction->setEnabled(true);
} else } else
@ -1534,15 +1564,21 @@ bool GUI::loadMap(const QString &fileName, MapAction *&action, bool silent)
valid = true; valid = true;
map = a->data().value<Map*>(); map = a->data().value<Map*>();
if (map->isReady()) if (map->isReady())
lastReady = a; action = a;
} }
} }
action = lastReady;
return valid; return valid;
} }
bool GUI::loadMap(const QString &fileName, MapAction *&action, bool silent)
{
TreeNode<Map*> maps(MapList::loadMaps(fileName));
QList<QAction*> existingActions(_mapsActionGroup->actions());
return loadMapNode(maps, action, silent, existingActions);
}
void GUI::mapLoaded() void GUI::mapLoaded()
{ {
MapAction *action = static_cast<MapAction*>(QObject::sender()); MapAction *action = static_cast<MapAction*>(QObject::sender());
@ -1579,21 +1615,17 @@ void GUI::mapLoadedDir()
} }
} }
void GUI::loadMapDir() void GUI::loadMapDirNode(const TreeNode<Map *> &node, QList<MapAction*> &actions,
QMenu *menu, const QList<QAction*> &existingActions)
{ {
QString dir(QFileDialog::getExistingDirectory(this, for (int i = 0; i < node.childs().size(); i++) {
tr("Select map directory"), _mapDir, QFileDialog::ShowDirsOnly)); QMenu *cm = new QMenu(node.childs().at(i).name(), menu);
if (dir.isEmpty()) menu->addMenu(cm);
return; loadMapDirNode(node.childs().at(i), actions, cm, existingActions);
}
QList<Map*> maps(MapList::loadMaps(dir)); for (int i = 0; i < node.items().size(); i++) {
QList<MapAction*> actions; Map *map = node.items().at(i);
QList<QAction*> existingActions(_mapsActionGroup->actions());
QFileInfo fi(dir);
QMenu *menu = new QMenu(fi.fileName());
for (int i = 0; i < maps.size(); i++) {
Map *map = maps.at(i);
MapAction *a; MapAction *a;
if (!(a = findMapAction(existingActions, map))) { if (!(a = findMapAction(existingActions, map))) {
@ -1612,24 +1644,39 @@ void GUI::loadMapDir()
} else } else
connect(a, SIGNAL(loaded()), this, SLOT(mapLoadedDir())); connect(a, SIGNAL(loaded()), this, SLOT(mapLoadedDir()));
} }
_areaCount++;
} else { } else {
map = a->data().value<Map*>(); map = a->data().value<Map*>();
if (map->isReady()) if (map->isReady())
actions.append(a); actions.append(a);
} }
} }
}
void GUI::loadMapDir()
{
QString dir(QFileDialog::getExistingDirectory(this,
tr("Select map directory"), _mapDir, QFileDialog::ShowDirsOnly));
if (dir.isEmpty())
return;
QFileInfo fi(dir);
TreeNode<Map*> maps(MapList::loadMaps(dir));
QList<QAction*> existingActions(_mapsActionGroup->actions());
QList<MapAction*> actions;
QMenu *menu = new QMenu(maps.name());
loadMapDirNode(maps, actions, menu, existingActions);
_mapView->loadMaps(actions); _mapView->loadMaps(actions);
if (menu->isEmpty()) if (menu->isEmpty())
delete menu; delete menu;
else { else
menu->setStyleSheet("QMenu { menu-scrollable: 1; }");
_mapMenu->insertMenu(_mapsEnd, menu); _mapMenu->insertMenu(_mapsEnd, menu);
}
_mapDir = fi.absolutePath(); _mapDir = fi.absolutePath();
_areaCount += maps.size();
_fileActionGroup->setEnabled(true); _fileActionGroup->setEnabled(true);
_reloadFileAction->setEnabled(false); _reloadFileAction->setEnabled(false);
} }

View File

@ -6,6 +6,7 @@
#include <QList> #include <QList>
#include <QDate> #include <QDate>
#include <QPrinter> #include <QPrinter>
#include "common/treenode.h"
#include "data/graph.h" #include "data/graph.h"
#include "units.h" #include "units.h"
#include "timetype.h" #include "timetype.h"
@ -113,9 +114,11 @@ private:
QAction *createPOIFileAction(const QString &fileName); QAction *createPOIFileAction(const QString &fileName);
MapAction *createMapAction(Map *map); MapAction *createMapAction(Map *map);
void createPOIFilesActions(); void createPOIFilesActions();
void createMapActions(); TreeNode<MapAction*> createMapActionsNode(const TreeNode<Map*> &node);
void createActions(); TreeNode<MapAction *> createMapActions();
void createMenus(); void createActions(TreeNode<MapAction *> &mapActions);
void createMapNodeMenu(const TreeNode<MapAction*> &node, QMenu *menu);
void createMenus(const TreeNode<MapAction *> &mapActions);
void createToolBars(); void createToolBars();
void createStatusBar(); void createStatusBar();
void createMapView(); void createMapView();
@ -125,6 +128,10 @@ private:
bool openPOIFile(const QString &fileName); bool openPOIFile(const QString &fileName);
bool loadFile(const QString &fileName, bool silent = false); bool loadFile(const QString &fileName, bool silent = false);
void loadData(const Data &data); void loadData(const Data &data);
bool loadMapNode(const TreeNode<Map*> &node, MapAction *&action,
bool silent, const QList<QAction *> &existingActions);
void loadMapDirNode(const TreeNode<Map*> &node, QList<MapAction *> &actions,
QMenu *menu, const QList<QAction*> &existingActions);
void updateStatusBarInfo(); void updateStatusBarInfo();
void updateWindowTitle(); void updateWindowTitle();
void updateNavigationActions(); void updateNavigationActions();

29
src/common/treenode.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef TREENODE_H
#define TREENODE_H
#include <QList>
#include <QString>
template <typename T>
class TreeNode
{
public:
TreeNode() {}
TreeNode(const QString &name) : _name(name) {}
const QString &name() const {return _name;}
const QList<TreeNode> &childs() const {return _childs;}
const QList<T> &items() const {return _items;}
void addItem(T node) {_items.append(node);}
void addChild(const TreeNode<T> &child) {_childs.append(child);}
bool isEmpty() const {return _childs.isEmpty() && _items.isEmpty();}
private:
QString _name;
QList<TreeNode> _childs;
QList<T> _items;
};
#endif // TREENODE_H

View File

@ -18,23 +18,23 @@
#include "maplist.h" #include "maplist.h"
Map *MapList::loadFile(const QString &path, bool *terminate) Map *MapList::loadFile(const QString &path, bool *isDir)
{ {
QFileInfo fi(path); QFileInfo fi(path);
QString suffix = fi.suffix().toLower(); QString suffix = fi.suffix().toLower();
Map *map = 0; Map *map = 0;
if (Atlas::isAtlas(path)) { if (Atlas::isAtlas(path)) {
if (terminate) if (isDir)
*terminate = true; *isDir = true;
map = new Atlas(path); map = new Atlas(path);
} else if (suffix == "xml") { } else if (suffix == "xml") {
if (MapSource::isMap(path)) { if (MapSource::isMap(path)) {
map = MapSource::loadMap(path); map = MapSource::loadMap(path);
} else if (GMAP::isGMAP(path)) { } else if (GMAP::isGMAP(path)) {
map = new IMGMap(path); map = new IMGMap(path);
if (terminate) if (isDir)
*terminate = true; *isDir = true;
} }
} else if (suffix == "jnx") } else if (suffix == "jnx")
map = new JNXMap(path); map = new JNXMap(path);
@ -60,39 +60,44 @@ Map *MapList::loadFile(const QString &path, bool *terminate)
return map ? map : new InvalidMap(path, "Unknown file format"); return map ? map : new InvalidMap(path, "Unknown file format");
} }
QList<Map*> MapList::loadDir(const QString &path) TreeNode<Map *> MapList::loadDir(const QString &path, TreeNode<Map *> *parent)
{ {
QDir md(path); QDir md(path);
md.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); md.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
md.setSorting(QDir::DirsLast); md.setSorting(QDir::DirsLast);
QFileInfoList ml = md.entryInfoList(); QFileInfoList ml = md.entryInfoList();
QList<Map*> list; TreeNode<Map*> tree(md.dirName());
for (int i = 0; i < ml.size(); i++) { for (int i = 0; i < ml.size(); i++) {
const QFileInfo &fi = ml.at(i); const QFileInfo &fi = ml.at(i);
QString suffix = fi.suffix().toLower(); QString suffix = fi.suffix().toLower();
bool terminate = false;
if (fi.isDir() && fi.fileName() != "set") if (fi.isDir()) {
list.append(loadDir(fi.absoluteFilePath())); TreeNode<Map*> child(loadDir(fi.absoluteFilePath(), &tree));
else if (filter().contains("*." + suffix)) { if (!child.isEmpty())
list.append(loadFile(fi.absoluteFilePath(), &terminate)); tree.addChild(child);
if (terminate) } else if (filter().contains("*." + suffix)) {
bool isDir = false;
Map *map = loadFile(fi.absoluteFilePath(), &isDir);
if (isDir) {
parent->addItem(map);
break; break;
} else
tree.addItem(map);
} }
} }
return list; return tree;
} }
QList<Map*> MapList::loadMaps(const QString &path) TreeNode<Map *> MapList::loadMaps(const QString &path)
{ {
if (QFileInfo(path).isDir()) if (QFileInfo(path).isDir())
return loadDir(path); return loadDir(path);
else { else {
QList<Map*> list; TreeNode<Map*> tree;
list.append(loadFile(path, 0)); tree.addItem(loadFile(path));
return list; return tree;
} }
} }

View File

@ -2,19 +2,21 @@
#define MAPLIST_H #define MAPLIST_H
#include <QString> #include <QString>
#include "common/treenode.h"
class Map; class Map;
class MapList class MapList
{ {
public: public:
static QList<Map*> loadMaps(const QString &path); static TreeNode<Map*> loadMaps(const QString &path);
static QString formats(); static QString formats();
static QStringList filter(); static QStringList filter();
private: private:
static Map *loadFile(const QString &path, bool *terminate); static Map *loadFile(const QString &path, bool *isDir = 0);
static QList<Map*> loadDir(const QString &path); static TreeNode<Map*> loadDir(const QString &path,
TreeNode<Map *> *parent = 0);
}; };
#endif // MAPLIST_H #endif // MAPLIST_H