1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-24 03:35:53 +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/rectc.h \
src/common/textcodec.h \
src/common/treenode.h \
src/common/wgs84.h \
src/common/util.h \
src/common/rtree.h \

View File

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

View File

@ -6,6 +6,7 @@
#include <QList>
#include <QDate>
#include <QPrinter>
#include "common/treenode.h"
#include "data/graph.h"
#include "units.h"
#include "timetype.h"
@ -113,9 +114,11 @@ private:
QAction *createPOIFileAction(const QString &fileName);
MapAction *createMapAction(Map *map);
void createPOIFilesActions();
void createMapActions();
void createActions();
void createMenus();
TreeNode<MapAction*> createMapActionsNode(const TreeNode<Map*> &node);
TreeNode<MapAction *> createMapActions();
void createActions(TreeNode<MapAction *> &mapActions);
void createMapNodeMenu(const TreeNode<MapAction*> &node, QMenu *menu);
void createMenus(const TreeNode<MapAction *> &mapActions);
void createToolBars();
void createStatusBar();
void createMapView();
@ -125,6 +128,10 @@ private:
bool openPOIFile(const QString &fileName);
bool loadFile(const QString &fileName, bool silent = false);
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 updateWindowTitle();
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"
Map *MapList::loadFile(const QString &path, bool *terminate)
Map *MapList::loadFile(const QString &path, bool *isDir)
{
QFileInfo fi(path);
QString suffix = fi.suffix().toLower();
Map *map = 0;
if (Atlas::isAtlas(path)) {
if (terminate)
*terminate = true;
if (isDir)
*isDir = true;
map = new Atlas(path);
} else if (suffix == "xml") {
if (MapSource::isMap(path)) {
map = MapSource::loadMap(path);
} else if (GMAP::isGMAP(path)) {
map = new IMGMap(path);
if (terminate)
*terminate = true;
if (isDir)
*isDir = true;
}
} else if (suffix == "jnx")
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");
}
QList<Map*> MapList::loadDir(const QString &path)
TreeNode<Map *> MapList::loadDir(const QString &path, TreeNode<Map *> *parent)
{
QDir md(path);
md.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
md.setSorting(QDir::DirsLast);
QFileInfoList ml = md.entryInfoList();
QList<Map*> list;
TreeNode<Map*> tree(md.dirName());
for (int i = 0; i < ml.size(); i++) {
const QFileInfo &fi = ml.at(i);
QString suffix = fi.suffix().toLower();
bool terminate = false;
if (fi.isDir() && fi.fileName() != "set")
list.append(loadDir(fi.absoluteFilePath()));
else if (filter().contains("*." + suffix)) {
list.append(loadFile(fi.absoluteFilePath(), &terminate));
if (terminate)
if (fi.isDir()) {
TreeNode<Map*> child(loadDir(fi.absoluteFilePath(), &tree));
if (!child.isEmpty())
tree.addChild(child);
} else if (filter().contains("*." + suffix)) {
bool isDir = false;
Map *map = loadFile(fi.absoluteFilePath(), &isDir);
if (isDir) {
parent->addItem(map);
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())
return loadDir(path);
else {
QList<Map*> list;
list.append(loadFile(path, 0));
return list;
TreeNode<Map*> tree;
tree.addItem(loadFile(path));
return tree;
}
}

View File

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