1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-27 21:24:47 +01:00

Improved file browsing

This commit is contained in:
Martin Tůma 2015-10-20 22:18:41 +02:00
parent 5fce0980e5
commit fd9e504c89
10 changed files with 218 additions and 80 deletions

View File

@ -22,7 +22,8 @@ HEADERS += src/config.h \
src/infoitem.h \ src/infoitem.h \
src/elevationgraph.h \ src/elevationgraph.h \
src/speedgraph.h \ src/speedgraph.h \
src/sliderinfoitem.h src/sliderinfoitem.h \
src/filebrowser.h
SOURCES += src/main.cpp \ SOURCES += src/main.cpp \
src/gui.cpp \ src/gui.cpp \
src/gpx.cpp \ src/gpx.cpp \
@ -39,7 +40,8 @@ SOURCES += src/main.cpp \
src/infoitem.cpp \ src/infoitem.cpp \
src/elevationgraph.cpp \ src/elevationgraph.cpp \
src/speedgraph.cpp \ src/speedgraph.cpp \
src/sliderinfoitem.cpp src/sliderinfoitem.cpp \
src/filebrowser.cpp
RESOURCES += gpxsee.qrc RESOURCES += gpxsee.qrc
TRANSLATIONS = lang/gpxsee_cs.ts TRANSLATIONS = lang/gpxsee_cs.ts
macx:ICON = icons/gpxsee.icns macx:ICON = icons/gpxsee.icns

View File

@ -1,5 +1,5 @@
<RCC> <RCC>
<qresource> <qresource prefix="/">
<file>icons/dialog-close.png</file> <file>icons/dialog-close.png</file>
<file>icons/document-open.png</file> <file>icons/document-open.png</file>
<file>icons/document-save-as.png</file> <file>icons/document-save-as.png</file>
@ -7,9 +7,7 @@
<file>icons/flag.png</file> <file>icons/flag.png</file>
<file>icons/gpxsee.png</file> <file>icons/gpxsee.png</file>
<file>icons/application-exit.png</file> <file>icons/application-exit.png</file>
</qresource> <file>icons/view-refresh.png</file>
<qresource>
<file>lang/gpxsee_cs.qm</file> <file>lang/gpxsee_cs.qm</file>
</qresource> </qresource>
</RCC> </RCC>

BIN
icons/view-refresh.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

69
src/filebrowser.cpp Normal file
View File

@ -0,0 +1,69 @@
#include <QFileSystemWatcher>
#include <QDir>
#include "filebrowser.h"
#include <QDebug>
FileBrowser::FileBrowser(QObject *parent) : QObject(parent)
{
_watcher = new QFileSystemWatcher(this);
connect(_watcher, SIGNAL(directoryChanged(const QString &)), this,
SLOT(reloadDirectory(const QString &)));
_index = -1;
}
FileBrowser::~FileBrowser()
{
delete _watcher;
}
void FileBrowser::setCurrent(const QString &path)
{
QFileInfo file(path);
QDir dir = file.absoluteDir();
if (_files.isEmpty() || _files.last().canonicalPath()
!= dir.canonicalPath()) {
if (!_watcher->directories().isEmpty())
_watcher->removePaths(_watcher->directories());
_watcher->addPath(dir.canonicalPath());
_files = dir.entryInfoList(_filter, QDir::Files);
}
_index = _files.empty() ? -1 : _files.indexOf(file);
}
void FileBrowser::setFilter(const QStringList &filter)
{
_filter = filter;
if (!_files.isEmpty())
reloadDirectory(_files.last().canonicalPath());
}
QString FileBrowser::next()
{
if (_index < 0 || _index == _files.size() - 1)
return QString();
return _files.at(++_index).absoluteFilePath();
}
QString FileBrowser::prev()
{
if (_index <= 0)
return QString();
return _files.at(--_index).absoluteFilePath();
}
void FileBrowser::reloadDirectory(const QString &path)
{
QDir dir(path);
QFileInfo current = _files.at(_index);
_files = dir.entryInfoList(_filter, QDir::Files);
_index = _files.empty() ? -1 : _files.indexOf(current);
}

34
src/filebrowser.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef FILEBROWSER_H
#define FILEBROWSER_H
#include <QObject>
#include <QFileInfo>
#include <QStringList>
class QFileSystemWatcher;
class FileBrowser : public QObject
{
Q_OBJECT
public:
FileBrowser(QObject *parent = 0);
~FileBrowser();
void setFilter(const QStringList &filter);
void setCurrent(const QString &path);
QString next();
QString prev();
private slots:
void reloadDirectory(const QString &path);
private:
QFileSystemWatcher *_watcher;
QStringList _filter;
QFileInfoList _files;
int _index;
};
#endif // FILEBROWSER_H

View File

@ -16,12 +16,12 @@
#include "speedgraph.h" #include "speedgraph.h"
#include "track.h" #include "track.h"
#include "infoitem.h" #include "infoitem.h"
#include "filebrowser.h"
#include "gui.h" #include "gui.h"
#include <QDebug> #include <QDebug>
static QString timeSpan(qreal time) static QString timeSpan(qreal time)
{ {
unsigned h, m, s; unsigned h, m, s;
@ -34,6 +34,7 @@ static QString timeSpan(qreal time)
.arg(s,2, 10, QChar('0')); .arg(s,2, 10, QChar('0'));
} }
GUI::GUI() GUI::GUI()
{ {
createActions(); createActions();
@ -48,6 +49,9 @@ GUI::GUI()
connect(_speedGraph, SIGNAL(sliderPositionChanged(qreal)), _track, connect(_speedGraph, SIGNAL(sliderPositionChanged(qreal)), _track,
SLOT(movePositionMarker(qreal))); SLOT(movePositionMarker(qreal)));
_browser = new FileBrowser(this);
_browser->setFilter(QStringList("*.gpx"));
QVBoxLayout *layout = new QVBoxLayout; QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(_track); layout->addWidget(_track);
layout->addWidget(_trackGraphs); layout->addWidget(_trackGraphs);
@ -59,8 +63,6 @@ GUI::GUI()
setWindowTitle(APP_NAME); setWindowTitle(APP_NAME);
setUnifiedTitleAndToolBarOnMac(true); setUnifiedTitleAndToolBarOnMac(true);
_dirIndex = -1;
_files = 0;
_distance = 0; _distance = 0;
_time = 0; _time = 0;
@ -106,6 +108,11 @@ void GUI::createActions()
_closeFileAction->setShortcut(QKeySequence::Close); _closeFileAction->setShortcut(QKeySequence::Close);
_closeFileAction->setActionGroup(_fileActionGroup); _closeFileAction->setActionGroup(_fileActionGroup);
connect(_closeFileAction, SIGNAL(triggered()), this, SLOT(closeFile())); connect(_closeFileAction, SIGNAL(triggered()), this, SLOT(closeFile()));
_reloadFileAction = new QAction(QIcon(QPixmap(RELOAD_FILE_ICON)),
tr("Reload"), this);
_reloadFileAction->setShortcut(QKeySequence::Refresh);
_reloadFileAction->setActionGroup(_fileActionGroup);
connect(_reloadFileAction, SIGNAL(triggered()), this, SLOT(reloadFile()));
// POI actions // POI actions
_openPOIAction = new QAction(QIcon(QPixmap(OPEN_FILE_ICON)), _openPOIAction = new QAction(QIcon(QPixmap(OPEN_FILE_ICON)),
@ -125,6 +132,8 @@ void GUI::createMenus()
_fileMenu->addAction(_saveFileAction); _fileMenu->addAction(_saveFileAction);
_fileMenu->addAction(_saveAsAction); _fileMenu->addAction(_saveAsAction);
_fileMenu->addSeparator(); _fileMenu->addSeparator();
_fileMenu->addAction(_reloadFileAction);
_fileMenu->addSeparator();
_fileMenu->addAction(_closeFileAction); _fileMenu->addAction(_closeFileAction);
#ifndef __APPLE__ #ifndef __APPLE__
_fileMenu->addSeparator(); _fileMenu->addSeparator();
@ -145,6 +154,7 @@ void GUI::createToolBars()
_fileToolBar = addToolBar(tr("File")); _fileToolBar = addToolBar(tr("File"));
_fileToolBar->addAction(_openFileAction); _fileToolBar->addAction(_openFileAction);
_fileToolBar->addAction(_saveFileAction); _fileToolBar->addAction(_saveFileAction);
_fileToolBar->addAction(_reloadFileAction);
_fileToolBar->addAction(_closeFileAction); _fileToolBar->addAction(_closeFileAction);
#ifdef __APPLE__ #ifdef __APPLE__
_fileToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); _fileToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
@ -207,21 +217,30 @@ void GUI::openFile()
{ {
QStringList files = QFileDialog::getOpenFileNames(this, tr("Open file")); QStringList files = QFileDialog::getOpenFileNames(this, tr("Open file"));
QStringList list = files; QStringList list = files;
QString lastFile;
for (QStringList::Iterator it = list.begin(); it != list.end(); it++) for (QStringList::Iterator it = list.begin(); it != list.end(); it++)
if (openFile(*it)) openFile(*it);
lastFile = *it;
if (!lastFile.isEmpty())
setDir(lastFile);
} }
bool GUI::openFile(const QString &fileName) bool GUI::openFile(const QString &fileName)
{
if (fileName.isEmpty() || _files.contains(fileName))
return false;
if (loadFile(fileName)) {
_files.append(fileName);
_browser->setCurrent(fileName);
updateStatusBarInfo();
_fileActionGroup->setEnabled(true);
return true;
} else
return false;
}
bool GUI::loadFile(const QString &fileName)
{ {
GPX gpx; GPX gpx;
if (!fileName.isEmpty()) {
if (gpx.loadFile(fileName)) { if (gpx.loadFile(fileName)) {
_elevationGraph->loadGPX(gpx); _elevationGraph->loadGPX(gpx);
_speedGraph->loadGPX(gpx); _speedGraph->loadGPX(gpx);
@ -232,18 +251,12 @@ bool GUI::openFile(const QString &fileName)
_distance += gpx.distance(); _distance += gpx.distance();
_time += gpx.time(); _time += gpx.time();
updateStatusBarInfo(fileName);
_fileActionGroup->setEnabled(true);
return true; return true;
} else { } else {
QMessageBox::critical(this, tr("Error"), fileName + QString("\n\n") QMessageBox::critical(this, tr("Error"), fileName + QString("\n\n")
+ tr("Error loading GPX file:\n%1").arg(gpx.errorString())); + tr("Error loading GPX file:\n%1").arg(gpx.errorString()));
}
}
return false; return false;
}
} }
void GUI::openPOIFile() void GUI::openPOIFile()
@ -314,20 +327,42 @@ void GUI::saveFile(const QString &fileName)
p.end(); p.end();
} }
void GUI::closeFile() void GUI::reloadFile()
{ {
_files = 0;
_distance = 0; _distance = 0;
_time = 0; _time = 0;
_elevationGraph->clear(); _elevationGraph->clear();
_speedGraph->clear(); _speedGraph->clear();
_track->clear(); _track->clear();
_fileNameLabel->clear();
_distanceLabel->clear(); for (int i = 0; i < _files.size(); i++) {
_timeLabel->clear(); if (!loadFile(_files.at(i))) {
_files.removeAt(i);
i--;
}
}
updateStatusBarInfo();
if (_files.isEmpty())
_fileActionGroup->setEnabled(false);
else
_browser->setCurrent(_files.last());
}
void GUI::closeFile()
{
_distance = 0;
_time = 0;
_elevationGraph->clear();
_speedGraph->clear();
_track->clear();
_files.clear();
_fileActionGroup->setEnabled(false); _fileActionGroup->setEnabled(false);
updateStatusBarInfo();
} }
void GUI::showPOI() void GUI::showPOI()
@ -338,12 +373,20 @@ void GUI::showPOI()
_track->clearPOI(); _track->clearPOI();
} }
void GUI::updateStatusBarInfo(const QString &fileName)
void GUI::updateStatusBarInfo()
{ {
if (++_files > 1) int files = _files.size();
_fileNameLabel->setText(tr("%1 tracks").arg(_files));
if (files == 0) {
_fileNameLabel->clear();
_distanceLabel->clear();
_timeLabel->clear();
return;
} else if (files == 1)
_fileNameLabel->setText(_files.at(0));
else else
_fileNameLabel->setText(fileName); _fileNameLabel->setText(tr("%1 tracks").arg(_files.size()));
_distanceLabel->setText(QString::number(_distance / 1000, 'f', 1) _distanceLabel->setText(QString::number(_distance / 1000, 'f', 1)
+ " " + tr("km")); + " " + tr("km"));
@ -361,26 +404,16 @@ void GUI::graphChanged(int index)
void GUI::keyPressEvent(QKeyEvent *event) void GUI::keyPressEvent(QKeyEvent *event)
{ {
if (_dirIndex < 0 || _dirFiles.count() == 1) QString file;
return;
if (event->key() == PREV_KEY) { if (event->key() == PREV_KEY)
if (_dirIndex == 0) file = _browser->prev();
return; if (event->key() == NEXT_KEY)
file = _browser->next();
if (!file.isNull()) {
if (!(event->modifiers() & MODIFIER))
closeFile(); closeFile();
openFile(_dirFiles.at(--_dirIndex).absoluteFilePath()); openFile(file);
}
if (event->key() == NEXT_KEY) {
if (_dirIndex == _dirFiles.size() - 1)
return;
closeFile();
openFile(_dirFiles.at(++_dirIndex).absoluteFilePath());
} }
} }
void GUI::setDir(const QString &file)
{
QDir dir = QFileInfo(file).absoluteDir();
_dirFiles = dir.entryInfoList(QStringList("*.gpx"), QDir::Files);
_dirIndex = _dirFiles.empty() ? -1 : _dirFiles.indexOf(file);
}

View File

@ -12,6 +12,8 @@
#include <QFileInfoList> #include <QFileInfoList>
#include "poi.h" #include "poi.h"
class FileBrowser;
class ElevationGraph; class ElevationGraph;
class SpeedGraph; class SpeedGraph;
class Track; class Track;
@ -24,7 +26,6 @@ public:
GUI(); GUI();
bool openFile(const QString &fileName); bool openFile(const QString &fileName);
void setDir(const QString &file);
private slots: private slots:
void about(); void about();
@ -32,8 +33,10 @@ private slots:
void saveAs(); void saveAs();
void openFile(); void openFile();
void closeFile(); void closeFile();
void reloadFile();
void openPOIFile(); void openPOIFile();
void showPOI(); void showPOI();
void graphChanged(int); void graphChanged(int);
private: private:
@ -44,8 +47,9 @@ private:
void createTrackView(); void createTrackView();
void createTrackGraphs(); void createTrackGraphs();
bool loadFile(const QString &fileName);
void saveFile(const QString &fileName); void saveFile(const QString &fileName);
void updateStatusBarInfo(const QString &fileName); void updateStatusBarInfo();
void keyPressEvent(QKeyEvent * event); void keyPressEvent(QKeyEvent * event);
@ -65,6 +69,7 @@ private:
QAction *_saveAsAction; QAction *_saveAsAction;
QAction *_openFileAction; QAction *_openFileAction;
QAction *_closeFileAction; QAction *_closeFileAction;
QAction *_reloadFileAction;
QAction *_openPOIAction; QAction *_openPOIAction;
QAction *_showPOIAction; QAction *_showPOIAction;
@ -78,11 +83,9 @@ private:
POI _poi; POI _poi;
QFileInfoList _dirFiles; FileBrowser *_browser;
int _dirIndex; QList<QString> _files;
QString _saveFileName; QString _saveFileName;
unsigned _files;
qreal _distance; qreal _distance;
qreal _time; qreal _time;

View File

@ -8,5 +8,6 @@
#define CLOSE_FILE_ICON ":/icons/dialog-close.png" #define CLOSE_FILE_ICON ":/icons/dialog-close.png"
#define SHOW_POI_ICON ":/icons/flag.png" #define SHOW_POI_ICON ":/icons/flag.png"
#define QUIT_ICON ":/icons/application-exit.png" #define QUIT_ICON ":/icons/application-exit.png"
#define RELOAD_FILE_ICON ":/icons/view-refresh.png"
#endif /* ICONS_H */ #endif /* ICONS_H */

View File

@ -3,5 +3,6 @@
#define NEXT_KEY Qt::Key_Space #define NEXT_KEY Qt::Key_Space
#define PREV_KEY Qt::Key_Backspace #define PREV_KEY Qt::Key_Backspace
#define MODIFIER Qt::ShiftModifier
#endif // KEYS_H #endif // KEYS_H

View File

@ -24,8 +24,5 @@ int main(int argc, char *argv[])
for (int i = 1; i < argc; i++) for (int i = 1; i < argc; i++)
gui.openFile(argv[i]); gui.openFile(argv[i]);
if (argc > 1)
gui.setDir(QString(argv[argc - 1]));
return app.exec(); return app.exec();
} }