diff --git a/gpxsee.pro b/gpxsee.pro index e8ecd1d9..ac6d2db1 100644 --- a/gpxsee.pro +++ b/gpxsee.pro @@ -24,6 +24,7 @@ HEADERS += src/common/config.h \ src/GUI/marginswidget.h \ src/GUI/markerinfoitem.h \ src/GUI/planeitem.h \ + src/GUI/poiaction.h \ src/GUI/popup.h \ src/common/garmin.h \ src/common/coordinates.h \ diff --git a/src/GUI/gui.cpp b/src/GUI/gui.cpp index 7a010be3..11cc6230 100644 --- a/src/GUI/gui.cpp +++ b/src/GUI/gui.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -50,6 +49,7 @@ #include "pathitem.h" #include "mapitem.h" #include "mapaction.h" +#include "poiaction.h" #include "gui.h" @@ -58,16 +58,16 @@ GUI::GUI() { TreeNode mapActions; + TreeNode poiActions; - loadPOIs(); + _poi = new POI(this); createMapView(); createGraphTabs(); createStatusBar(); - createActions(mapActions); - createMenus(mapActions); + createActions(mapActions, poiActions); + createMenus(mapActions, poiActions); createToolBars(); - createBrowser(); _splitter = new QSplitter(); @@ -105,21 +105,27 @@ GUI::GUI() updateStatusBarInfo(); } -void GUI::loadPOIs() -{ - _poi = new POI(this); - - QString poiDir(ProgramPaths::poiDir()); - if (!poiDir.isNull()) - _poi->loadDir(poiDir); -} - void GUI::createBrowser() { _browser = new FileBrowser(this); _browser->setFilter(Data::filter()); } +TreeNode GUI::createMapActions() +{ + _mapsActionGroup = new QActionGroup(this); + _mapsActionGroup->setExclusive(true); + connect(_mapsActionGroup, SIGNAL(triggered(QAction*)), this, + SLOT(mapChanged(QAction*))); + + QString mapDir(ProgramPaths::mapDir()); + if (mapDir.isNull()) + return TreeNode(); + + TreeNode maps(MapList::loadMaps(mapDir)); + return createMapActionsNode(maps); +} + TreeNode GUI::createMapActionsNode(const TreeNode &node) { TreeNode tree(node.name()); @@ -130,7 +136,7 @@ TreeNode GUI::createMapActionsNode(const TreeNode &node) for (int i = 0; i < node.items().size(); i++) { Map *map = node.items().at(i); if (map->isValid()) { - MapAction *a = createMapAction(map); + MapAction *a = new MapAction(map, _mapsActionGroup); connect(a, SIGNAL(loaded()), this, SLOT(mapInitialized())); tree.addItem(a); } else { @@ -143,29 +149,6 @@ TreeNode GUI::createMapActionsNode(const TreeNode &node) return tree; } -TreeNode GUI::createMapActions() -{ - _mapsActionGroup = new QActionGroup(this); - _mapsActionGroup->setExclusive(true); - - QString mapDir(ProgramPaths::mapDir()); - if (mapDir.isNull()) - return TreeNode(); - - TreeNode maps(MapList::loadMaps(mapDir)); - return createMapActionsNode(maps); -} - -MapAction *GUI::createMapAction(Map *map) -{ - MapAction *a = new MapAction(map, _mapsActionGroup); - a->setMenuRole(QAction::NoRole); - a->setCheckable(true); - connect(a, SIGNAL(triggered()), this, SLOT(mapChanged())); - - return a; -} - void GUI::mapInitialized() { MapAction *action = static_cast(QObject::sender()); @@ -182,35 +165,35 @@ void GUI::mapInitialized() } } -void GUI::createPOIFilesActions() +TreeNode GUI::createPOIActions() { - _poiFilesSignalMapper = new QSignalMapper(this); -#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) - connect(_poiFilesSignalMapper, SIGNAL(mapped(int)), this, - SLOT(poiFileChecked(int))); -#else // QT 5.15 - connect(_poiFilesSignalMapper, SIGNAL(mappedInt(int)), this, - SLOT(poiFileChecked(int))); -#endif // QT 5.15 + _poisActionGroup = new QActionGroup(this); + _poisActionGroup->setExclusive(false); + connect(_poisActionGroup, SIGNAL(triggered(QAction*)), this, + SLOT(poiFileChecked(QAction*))); - for (int i = 0; i < _poi->files().count(); i++) - createPOIFileAction(_poi->files().at(i)); + TreeNode poiFiles; + QString poiDir(ProgramPaths::poiDir()); + if (!poiDir.isNull()) + poiFiles = _poi->loadDir(poiDir); + + return createPOIActionsNode(poiFiles); } -QAction *GUI::createPOIFileAction(const QString &fileName) +TreeNode GUI::createPOIActionsNode(const TreeNode &node) { - QAction *a = new QAction(QFileInfo(fileName).fileName(), this); - a->setMenuRole(QAction::NoRole); - a->setCheckable(true); + TreeNode tree(node.name()); - _poiFilesActions.append(a); - _poiFilesSignalMapper->setMapping(a, _poiFilesActions.size() - 1); - connect(a, SIGNAL(triggered()), _poiFilesSignalMapper, SLOT(map())); + for (int i = 0; i < node.childs().size(); i++) + tree.addChild(createPOIActionsNode(node.childs().at(i))); + for (int i = 0; i < node.items().size(); i++) + tree.addItem(new POIAction(node.items().at(i), _poisActionGroup)); - return a; + return tree; } -void GUI::createActions(TreeNode &mapActions) +void GUI::createActions(TreeNode &mapActions, + TreeNode &poiActions) { QActionGroup *ag; @@ -291,10 +274,6 @@ void GUI::createActions(TreeNode &mapActions) this); _openPOIAction->setMenuRole(QAction::NoRole); connect(_openPOIAction, SIGNAL(triggered()), this, SLOT(openPOIFile())); - _closePOIAction = new QAction(QIcon(CLOSE_FILE_ICON), tr("Close POI files"), - this); - _closePOIAction->setMenuRole(QAction::NoRole); - connect(_closePOIAction, SIGNAL(triggered()), this, SLOT(closePOIFiles())); _overlapPOIAction = new QAction(tr("Overlap POIs"), this); _overlapPOIAction->setMenuRole(QAction::NoRole); _overlapPOIAction->setCheckable(true); @@ -312,7 +291,7 @@ void GUI::createActions(TreeNode &mapActions) connect(_showPOIAction, SIGNAL(triggered(bool)), _mapView, SLOT(showPOI(bool))); addAction(_showPOIAction); - createPOIFilesActions(); + poiActions = createPOIActions(); // Map actions mapActions = createMapActions(); @@ -550,7 +529,20 @@ void GUI::createMapNodeMenu(const TreeNode &node, QMenu *menu) menu->addAction(node.items().at(i)); } -void GUI::createMenus(const TreeNode &mapActions) +void GUI::createPOINodeMenu(const TreeNode &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); + createPOINodeMenu(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 &mapActions, + const TreeNode &poiActions) { QMenu *fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(_openFileAction); @@ -588,17 +580,15 @@ void GUI::createMenus(const TreeNode &mapActions) graphMenu->addSeparator(); graphMenu->addAction(_showGraphsAction); - QMenu *poiMenu = menuBar()->addMenu(tr("&POI")); - _poiFilesMenu = poiMenu->addMenu(tr("POI files")); - _poiFilesMenu->addActions(_poiFilesActions); - poiMenu->addSeparator(); - poiMenu->addAction(_openPOIAction); - poiMenu->addAction(_closePOIAction); - poiMenu->addSeparator(); - poiMenu->addAction(_showPOILabelsAction); - poiMenu->addAction(_overlapPOIAction); - poiMenu->addSeparator(); - poiMenu->addAction(_showPOIAction); + _poiMenu = menuBar()->addMenu(tr("&POI")); + createPOINodeMenu(poiActions, _poiMenu); + _poisEnd = _poiMenu->addSeparator(); + _poiMenu->addAction(_openPOIAction); + _poiMenu->addSeparator(); + _poiMenu->addAction(_showPOILabelsAction); + _poiMenu->addAction(_overlapPOIAction); + _poiMenu->addSeparator(); + _poiMenu->addAction(_showPOIAction); QMenu *dataMenu = menuBar()->addMenu(tr("&Data")); dataMenu->addAction(_showWaypointLabelsAction); @@ -937,15 +927,15 @@ void GUI::openPOIFile() bool GUI::openPOIFile(const QString &fileName) { - if (_poi->files().contains(fileName)) + if (_poi->isLoaded(fileName)) return true; if (_poi->loadFile(fileName)) { _mapView->showPOI(true); _showPOIAction->setChecked(true); - QAction *action = createPOIFileAction(fileName); + QAction *action = new POIAction(fileName, _poisActionGroup); action->setChecked(true); - _poiFilesMenu->addAction(action); + _poiMenu->insertAction(_poisEnd, action); return true; } else { @@ -959,16 +949,6 @@ bool GUI::openPOIFile(const QString &fileName) } } -void GUI::closePOIFiles() -{ - _poiFilesMenu->clear(); - - qDeleteAll(_poiFilesActions); - _poiFilesActions.clear(); - - _poi->clear(); -} - void GUI::openOptions() { #define SET_VIEW_OPTION(option, action) \ @@ -1550,7 +1530,7 @@ bool GUI::loadMapNode(const TreeNode &node, MapAction *&action, delete map; } else { valid = true; - a = createMapAction(map); + a = new MapAction(map, _mapsActionGroup); _mapMenu->insertAction(_mapsEnd, a); if (map->isReady()) { @@ -1634,7 +1614,7 @@ void GUI::loadMapDirNode(const TreeNode &node, QList &actions + "\n\n" + map->path() + "\n\n" + map->errorString()); delete map; } else { - a = createMapAction(map); + a = new MapAction(map, _mapsActionGroup); menu->addAction(a); if (map->isReady()) { @@ -1726,9 +1706,9 @@ void GUI::updateWindowTitle() setWindowTitle(APP_NAME); } -void GUI::mapChanged() +void GUI::mapChanged(QAction *action) { - _map = _mapsActionGroup->checkedAction()->data().value(); + _map = action->data().value(); _mapView->setMap(_map); } @@ -1764,10 +1744,9 @@ void GUI::prevMap() } } -void GUI::poiFileChecked(int index) +void GUI::poiFileChecked(QAction *action) { - _poi->enableFile(_poi->files().at(index), - _poiFilesActions.at(index)->isChecked()); + _poi->enableFile(action->data().value(), action->isChecked()); } void GUI::graphChanged(int index) @@ -2069,12 +2048,14 @@ void GUI::writeSettings() settings.setValue(OVERLAP_POI_SETTING, _overlapPOIAction->isChecked()); int j = 0; - for (int i = 0; i < _poiFilesActions.count(); i++) { - if (!_poiFilesActions.at(i)->isChecked()) { + QList poiActions(_poisActionGroup->actions()); + for (int i = 0; i < poiActions.count(); i++) { + POIAction *a = static_cast(poiActions.at(i)); + if (!a->isChecked()) { if (j == 0) settings.beginWriteArray(DISABLED_POI_FILE_SETTINGS_PREFIX); settings.setArrayIndex(j++); - settings.setValue(DISABLED_POI_FILE_SETTING, _poi->files().at(i)); + settings.setValue(DISABLED_POI_FILE_SETTING, a->data().toString()); } } if (j != 0) @@ -2351,16 +2332,17 @@ void GUI::readSettings() _showPOIAction->setChecked(true); else _mapView->showPOI(false); - for (int i = 0; i < _poiFilesActions.count(); i++) - _poiFilesActions.at(i)->setChecked(true); + QList poiActions(_poisActionGroup->actions()); + for (int i = 0; i < poiActions.count(); i++) + poiActions.at(i)->setChecked(true); int size = settings.beginReadArray(DISABLED_POI_FILE_SETTINGS_PREFIX); for (int i = 0; i < size; i++) { settings.setArrayIndex(i); - int index = _poi->files().indexOf(settings.value( - DISABLED_POI_FILE_SETTING).toString()); - if (index >= 0) { - _poi->enableFile(_poi->files().at(index), false); - _poiFilesActions.at(index)->setChecked(false); + QString file(settings.value(DISABLED_POI_FILE_SETTING).toString()); + if (_poi->enableFile(file, false)) { + for (int j = 0; j < poiActions.size(); j++) + if (poiActions.at(j)->data().toString() == file) + poiActions.at(j)->setChecked(false); } } settings.endArray(); diff --git a/src/GUI/gui.h b/src/GUI/gui.h index 6b027eb2..59585565 100644 --- a/src/GUI/gui.h +++ b/src/GUI/gui.h @@ -22,7 +22,6 @@ class QActionGroup; class QAction; class QLabel; class QSplitter; -class QSignalMapper; class QPrinter; class FileBrowser; class GraphTab; @@ -31,6 +30,7 @@ class Map; class POI; class QScreen; class MapAction; +class POIAction; class Data; class GUI : public QMainWindow @@ -57,7 +57,6 @@ private slots: void reloadFiles(); void statistics(); void openPOIFile(); - void closePOIFiles(); void showGraphs(bool show); void showGraphGrids(bool show); void showGraphSliderInfo(bool show); @@ -73,9 +72,9 @@ private slots: void openOptions(); void clearMapCache(); - void mapChanged(); + void mapChanged(QAction *action); void graphChanged(int); - void poiFileChecked(int); + void poiFileChecked(QAction *action); void next(); void prev(); @@ -103,7 +102,6 @@ private slots: private: typedef QPair DateTimeRange; - void loadPOIs(); void closeFiles(); void plot(QPrinter *printer); void plotMainPage(QPainter *painter, const QRectF &rect, qreal ratio, @@ -111,14 +109,16 @@ private: void plotGraphsPage(QPainter *painter, const QRectF &rect, qreal ratio); qreal graphPlotHeight(const QRectF &rect, qreal ratio); - QAction *createPOIFileAction(const QString &fileName); - MapAction *createMapAction(Map *map); - void createPOIFilesActions(); + TreeNode createPOIActions(); + TreeNode createPOIActionsNode(const TreeNode &node); + TreeNode createMapActions(); TreeNode createMapActionsNode(const TreeNode &node); - TreeNode createMapActions(); - void createActions(TreeNode &mapActions); + void createActions(TreeNode &mapActions, + TreeNode &poiActions); void createMapNodeMenu(const TreeNode &node, QMenu *menu); - void createMenus(const TreeNode &mapActions); + void createPOINodeMenu(const TreeNode &node, QMenu *menu); + void createMenus(const TreeNode &mapActions, + const TreeNode &poiActions); void createToolBars(); void createStatusBar(); void createMapView(); @@ -129,8 +129,8 @@ private: bool loadFile(const QString &fileName, bool silent = false); void loadData(const Data &data); bool loadMapNode(const TreeNode &node, MapAction *&action, - bool silent, const QList &existingActions); - void loadMapDirNode(const TreeNode &node, QList &actions, + bool silent, const QList &existingActions); + void loadMapDirNode(const TreeNode &node, QList &actions, QMenu *menu, const QList &existingActions); void updateStatusBarInfo(); void updateWindowTitle(); @@ -159,12 +159,13 @@ private: QToolBar *_fileToolBar; QToolBar *_showToolBar; QToolBar *_navigationToolBar; - QMenu *_poiFilesMenu; + QMenu *_poiMenu; QMenu *_mapMenu; QActionGroup *_fileActionGroup; QActionGroup *_navigationActionGroup; QActionGroup *_mapsActionGroup; + QActionGroup *_poisActionGroup; QAction *_exitAction; QAction *_keysAction; QAction *_pathsAction; @@ -178,7 +179,6 @@ private: QAction *_reloadFileAction; QAction *_statisticsAction; QAction *_openPOIAction; - QAction *_closePOIAction; QAction *_showPOIAction; QAction *_overlapPOIAction; QAction *_showPOILabelsAction; @@ -221,9 +221,7 @@ private: QAction *_showCoordinatesAction; QAction *_openOptionsAction; QAction *_mapsEnd; - - QList _poiFilesActions; - QSignalMapper *_poiFilesSignalMapper; + QAction *_poisEnd; QLabel *_fileNameLabel; QLabel *_distanceLabel; diff --git a/src/GUI/mapaction.h b/src/GUI/mapaction.h index 43f656cc..33facc37 100644 --- a/src/GUI/mapaction.h +++ b/src/GUI/mapaction.h @@ -12,8 +12,12 @@ public: MapAction(Map *map, QObject *parent = 0) : QAction(map->name(), parent) { map->setParent(this); + setData(QVariant::fromValue(map)); setEnabled(map->isReady()); + setMenuRole(QAction::NoRole); + setCheckable(true); + connect(map, SIGNAL(mapLoaded()), this, SLOT(mapLoaded())); } diff --git a/src/GUI/poiaction.h b/src/GUI/poiaction.h new file mode 100644 index 00000000..eca5a17c --- /dev/null +++ b/src/GUI/poiaction.h @@ -0,0 +1,21 @@ +#ifndef POIACTION_H +#define POIACTION_H + +#include +#include "common/util.h" + +class POIAction : public QAction +{ + Q_OBJECT + +public: + POIAction(const QString &path, QObject *parent = 0) + : QAction(Util::file2name(path), parent) + { + setMenuRole(QAction::NoRole); + setCheckable(true); + setData(path); + } +}; + +#endif // POIACTION_H diff --git a/src/common/treenode.h b/src/common/treenode.h index ba182302..664e25d1 100644 --- a/src/common/treenode.h +++ b/src/common/treenode.h @@ -12,17 +12,25 @@ public: TreeNode(const QString &name) : _name(name) {} const QString &name() const {return _name;} - const QList &childs() const {return _childs;} + const QList > &childs() const {return _childs;} const QList &items() const {return _items;} void addItem(T node) {_items.append(node);} void addChild(const TreeNode &child) {_childs.append(child);} bool isEmpty() const {return _childs.isEmpty() && _items.isEmpty();} + void clear() {clear(*this);} private: + void clear(TreeNode &node) + { + for (int i = 0; i < node._childs.size(); i++) + clear(node._childs[i]); + node._items.clear(); + } + QString _name; - QList _childs; + QList > _childs; QList _items; }; diff --git a/src/data/poi.cpp b/src/data/poi.cpp index d535e7e1..e8cf6a68 100644 --- a/src/data/poi.cpp +++ b/src/data/poi.cpp @@ -10,19 +10,35 @@ #include "poi.h" +POI::File::File(int start, int end, const QVector &data) + : _enabled(true) +{ + qreal c[2]; + + for (int i = start; i <= end; i++) { + const Coordinates &p = data.at(i).coordinates(); + + c[0] = p.lon(); + c[1] = p.lat(); + _tree.Insert(c, c, i); + } +} + + POI::POI(QObject *parent) : QObject(parent) { _errorLine = 0; _radius = 1000; } +POI::~POI() +{ + qDeleteAll(_files); +} + bool POI::loadFile(const QString &path) { Data data(path); - FileIndex index; - - index.enabled = true; - index.start = _data.size(); if (!data.isValid()) { _errorString = data.errorString(); @@ -30,42 +46,41 @@ bool POI::loadFile(const QString &path) return false; } - for (int i = 0; i < data.waypoints().size(); i++) - _data.append(data.waypoints().at(i)); - index.end = _data.size() - 1; + int start = _data.size(); + _data.append(data.waypoints()); - for (int i = index.start; i <= index.end; i++) { - const Coordinates &p = _data.at(i).coordinates(); - qreal c[2]; - c[0] = p.lon(); - c[1] = p.lat(); - _tree.Insert(c, c, i); - } - - _files.append(path); - _indexes.append(index); + _files.insert(path, new File(start, _data.size() - 1, _data)); emit pointsChanged(); return true; } -void POI::loadDir(const QString &path) +TreeNode POI::loadDir(const QString &path) { QDir md(path); md.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); + md.setSorting(QDir::DirsFirst); QFileInfoList fl = md.entryInfoList(); + TreeNode tree(md.dirName()); for (int i = 0; i < fl.size(); i++) { const QFileInfo &fi = fl.at(i); - if (fi.isDir()) - loadDir(fi.absoluteFilePath()); - else - if (!loadFile(fi.absoluteFilePath())) + if (fi.isDir()) { + TreeNode child(loadDir(fi.absoluteFilePath())); + if (!child.isEmpty()) + tree.addChild(child); + } else { + if (loadFile(fi.absoluteFilePath())) + tree.addItem(fi.absoluteFilePath()); + else qWarning("%s: %s", qPrintable(fi.absoluteFilePath()), qPrintable(_errorString)); + } } + + return tree; } static bool cb(size_t data, void* context) @@ -80,24 +95,30 @@ void POI::search(const RectC &rect, QSet &set) const { qreal min[2], max[2]; - if (rect.left() > rect.right()) { - min[0] = rect.topLeft().lon(); - min[1] = rect.bottomRight().lat(); - max[0] = 180.0; - max[1] = rect.topLeft().lat(); - _tree.Search(min, max, cb, &set); + for (ConstIterator it = _files.constBegin(); it != _files.constEnd(); ++it) { + const File *file = *it; - min[0] = -180.0; - min[1] = rect.bottomRight().lat(); - max[0] = rect.bottomRight().lon(); - max[1] = rect.topLeft().lat(); - _tree.Search(min, max, cb, &set); - } else { - min[0] = rect.topLeft().lon(); - min[1] = rect.bottomRight().lat(); - max[0] = rect.bottomRight().lon(); - max[1] = rect.topLeft().lat(); - _tree.Search(min, max, cb, &set); + if (file->isEnabled()) { + if (rect.left() > rect.right()) { + min[0] = rect.topLeft().lon(); + min[1] = rect.bottomRight().lat(); + max[0] = 180.0; + max[1] = rect.topLeft().lat(); + file->tree().Search(min, max, cb, &set); + + min[0] = -180.0; + min[1] = rect.bottomRight().lat(); + max[0] = rect.bottomRight().lon(); + max[1] = rect.topLeft().lat(); + file->tree().Search(min, max, cb, &set); + } else { + min[0] = rect.topLeft().lon(); + min[1] = rect.bottomRight().lat(); + max[0] = rect.bottomRight().lon(); + max[1] = rect.topLeft().lat(); + file->tree().Search(min, max, cb, &set); + } + } } } @@ -170,40 +191,17 @@ QList POI::points(const RectC &rect) const return ret; } -void POI::enableFile(const QString &fileName, bool enable) +bool POI::enableFile(const QString &fileName, bool enable) { - int i; + Iterator it = _files.find(fileName); + if (it == _files.end()) + return false; - i = _files.indexOf(fileName); - Q_ASSERT(i >= 0); - _indexes[i].enabled = enable; - - _tree.RemoveAll(); - for (int i = 0; i < _indexes.count(); i++) { - FileIndex idx = _indexes.at(i); - if (!idx.enabled) - continue; - - for (int j = idx.start; j <= idx.end; j++) { - const Coordinates &p = _data.at(j).coordinates(); - qreal c[2]; - c[0] = p.lon(); - c[1] = p.lat(); - _tree.Insert(c, c, j); - } - } + (*it)->enable(enable); emit pointsChanged(); -} -void POI::clear() -{ - _tree.RemoveAll(); - _data.clear(); - _files.clear(); - _indexes.clear(); - - emit pointsChanged(); + return true; } void POI::setRadius(unsigned radius) diff --git a/src/data/poi.h b/src/data/poi.h index 8a1a4a4e..0da9fcb4 100644 --- a/src/data/poi.h +++ b/src/data/poi.h @@ -6,6 +6,7 @@ #include #include #include "common/rtree.h" +#include "common/treenode.h" #include "waypoint.h" class Path; @@ -17,9 +18,10 @@ class POI : public QObject public: POI(QObject *parent = 0); + ~POI(); bool loadFile(const QString &path); - void loadDir(const QString &path); + TreeNode loadDir(const QString &path); const QString &errorString() const {return _errorString;} int errorLine() const {return _errorLine;} @@ -30,28 +32,33 @@ public: QList points(const Waypoint &point) const; QList points(const RectC &rect) const; - const QStringList &files() const {return _files;} - void enableFile(const QString &fileName, bool enable); - void clear(); + bool isLoaded(const QString &path) const {return _files.contains(path);} + bool enableFile(const QString &fileName, bool enable); signals: void pointsChanged(); private: typedef RTree POITree; - struct FileIndex { - int start; - int end; - bool enabled; - }; + class File { + public: + File(int start, int end, const QVector &data); + + const POITree &tree() const {return _tree;} + bool isEnabled() const {return _enabled;} + void enable(bool enable) {_enabled = enable;} + + private: + bool _enabled; + POITree _tree; + }; + typedef QHash::const_iterator ConstIterator; + typedef QHash::iterator Iterator; - bool loadFile(const QString &path, bool dir); void search(const RectC &rect, QSet &set) const; - POITree _tree; QVector _data; - QStringList _files; - QList _indexes; + QHash _files; unsigned _radius;