diff --git a/app.pro b/app.pro index 1683219..89128c3 100644 --- a/app.pro +++ b/app.pro @@ -5,7 +5,6 @@ TEMPLATE = app QT += network -#LIBS += -Lmonav -lgpsgridclient -lcontractionhierarchiesclient INCLUDEPATH += monav SOURCES += main.cpp \ @@ -22,6 +21,7 @@ SOURCES += main.cpp \ mapwidget.cpp \ markerlist.cpp \ downloadwidget.cpp \ + fileselector.cpp \ searchwidget.cpp \ gpsclient.cpp @@ -38,5 +38,9 @@ HEADERS += mainwidget.h \ mapwidget.h \ markerlist.h \ downloadwidget.h \ + fileselector.h \ searchwidget.h \ gpsclient.h + +RESOURCES = pics/icons.qrc + diff --git a/fileselector.cpp b/fileselector.cpp new file mode 100644 index 0000000..e38fb05 --- /dev/null +++ b/fileselector.cpp @@ -0,0 +1,225 @@ +/* + * Copyright 2010-2011 Niels Kummerfeldt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "fileselector.h" + +#include +#include +#include +#include +#include + +FileSelector::FileSelector(QWidget *parent) + : QWidget(parent), + m_view(new QListView(this)), + m_model(new QFileSystemModel(this)), + m_title(new QLabel(this)), + m_path(new QLabel(this)), + m_bookmarkButton(new QPushButton(this)), + m_bookmarkMenu(new QMenu(this)), + m_bookmarks(), + m_signalMapper(new QSignalMapper(this)) +{ + QGridLayout *layout = new QGridLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->setRowStretch(5, 1); + layout->setSpacing(0); + + m_title->setAlignment(Qt::AlignCenter); + layout->addWidget(m_title, 0, 0, 1, 2); + layout->addWidget(m_path, 1, 0, 1, 2); + + m_view->setModel(m_model); + connect(m_view, SIGNAL(activated(QModelIndex)), this, SLOT(enter(QModelIndex))); + layout->addWidget(m_view, 2, 0, 6, 1); + m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_view->setSelectionMode(QListView::ExtendedSelection); + QFont font = m_view->font(); + font.setPointSize(8); + m_view->setFont(font); + + m_model->setNameFilterDisables(false); + m_model->setRootPath("/"); + + connect(m_signalMapper, SIGNAL(mapped(QString)), this, SLOT(setCurrentDirectory(QString))); + + m_bookmarkButton->setIcon(QIcon(":nobookmark.png")); + m_bookmarkButton->setShortcut(QKeySequence(Qt::ALT+Qt::Key_B)); + connect(m_bookmarkButton, SIGNAL(clicked()), this, SLOT(toggleBookmark())); + layout->addWidget(m_bookmarkButton, 2, 1); + + QPushButton *button = new QPushButton(); + button->setIcon(QIcon(":up.png")); + button->setShortcut(QKeySequence(Qt::ALT+Qt::Key_Up)); + connect(button, SIGNAL(clicked()), this, SLOT(goUp())); + layout->addWidget(button, 3, 1); + + button = new QPushButton(); + button->setIcon(QIcon(":ok.png")); + connect(button, SIGNAL(clicked()), this, SLOT(accept())); + layout->addWidget(button, 6, 1); + + button = new QPushButton(); + button->setIcon(QIcon(":cancel.png")); + button->setShortcut(QKeySequence(Qt::Key_Escape)); + connect(button, SIGNAL(clicked()), this, SIGNAL(cancel())); + layout->addWidget(button, 7, 1); + + QSettings conf(QDir::homePath()+"Maps/nanomap.conf", QSettings::NativeFormat); + conf.beginGroup("fileselector"); + m_bookmarks = conf.value("bookmarks").toStringList(); + conf.endGroup(); + + setCurrentDirectory(m_model->index(QDir::homePath())); + updateBookmarkMenu(); + + m_view->setFocus(Qt::OtherFocusReason); + resize(320, 240); +} + +FileSelector::~FileSelector() +{ + QSettings conf(QDir::homePath()+"Maps/nanomap.conf", QSettings::NativeFormat); + conf.beginGroup("fileselector"); + conf.setValue("bookmarks", m_bookmarks); + conf.endGroup(); +} + +void FileSelector::setTitle(const QString &title) +{ + m_title->setText(""+title+""); +} + +void FileSelector::setFileTypes(const QStringList &types) +{ + m_model->setNameFilters(types); +} + +void FileSelector::keyPressEvent(QKeyEvent *event) +{ + if (event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_B) { + m_bookmarkMenu->popup(mapToGlobal(QPoint(0, 0))); + } +} + +void FileSelector::toggleBookmark() +{ + QString path = m_model->filePath(m_view->rootIndex()); + if (m_bookmarks.contains(path)) { + m_bookmarks.removeAll(path); + m_bookmarkButton->setIcon(QIcon(":nobookmark.png")); + } else { + m_bookmarks.append(path); + m_bookmarkButton->setIcon(QIcon(":bookmark.png")); + } + updateBookmarkMenu(); +} + +void FileSelector::goUp() +{ + QModelIndex current = m_view->rootIndex(); + if (current.isValid()) { + QModelIndex up = current.parent(); + if (up.isValid()) { + setCurrentDirectory(up); + } + } +} + +void FileSelector::accept() +{ + QModelIndex index = m_view->currentIndex(); + if (index.isValid()) { + if (!m_model->isDir(index)) { + emit fileSelected(m_model->filePath(index)); + } + } +} + +void FileSelector::enter(const QModelIndex &index) +{ + if (m_model->isDir(index)) { + setCurrentDirectory(index); + } else { + QModelIndexList selected = m_view->selectionModel()->selectedIndexes(); + QStringList files; + foreach (const QModelIndex &i, selected) { + files << m_model->filePath(i); + } + emit fileSelected(files.first()); + } +} + +void FileSelector::setCurrentDirectory(const QString &dir) +{ + setCurrentDirectory(m_model->index(dir)); +} + +void FileSelector::setCurrentDirectory(const QModelIndex &dir) +{ + m_view->setRootIndex(dir); + QString path = m_model->filePath(dir); + setPathLabel(path); + if (m_bookmarks.contains(path)) { + m_bookmarkButton->setIcon(QIcon(":bookmark.png")); + } else { + m_bookmarkButton->setIcon(QIcon(":nobookmark.png")); + } +} + +void FileSelector::updateBookmarkMenu() +{ + m_bookmarkMenu->clear(); + + if (m_bookmarks.isEmpty()) { + QAction *action = new QAction("No bookmarks", m_bookmarkMenu); + action->setIcon(QIcon(":nobookmark.png")); + m_bookmarkMenu->addAction(action); + return; + } + + foreach (const QString &bm, m_bookmarks) { + QAction *action = new QAction(shortText(bm, 290), m_bookmarkMenu); + action->setIcon(QIcon(":bookmark.png")); + m_bookmarkMenu->addAction(action); + connect(action, SIGNAL(triggered()), m_signalMapper, SLOT(map())); + m_signalMapper->setMapping(action, bm); + } +} + +void FileSelector::setPathLabel(const QString &dir) +{ + m_path->setText(shortText(dir, 310)); +} + +QString FileSelector::shortText(const QString &text, int width) +{ + QFontMetrics fm(m_path->font()); + + QString shortText = text; + int n = 0; + while (fm.width(shortText) > width) { + ++n; + shortText = text; + shortText.replace(0, n, "..."); + } + + return shortText; +} + diff --git a/fileselector.h b/fileselector.h new file mode 100644 index 0000000..5b41e72 --- /dev/null +++ b/fileselector.h @@ -0,0 +1,71 @@ +/* + * Copyright 2010-2011 Niels Kummerfeldt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef FILESELECTOR_H +#define FILESELECTOR_H + +#include +#include +#include +#include +#include +#include +#include + +class FileSelector : public QWidget +{ + Q_OBJECT +public: + FileSelector(QWidget *parent = 0); + ~FileSelector(); + + void setTitle(const QString &title); + void setFileTypes(const QStringList &types); + +signals: + void fileSelected(const QString &fileName); + void cancel(); + +protected: + void keyPressEvent(QKeyEvent *event); + +private slots: + void toggleBookmark(); + void goUp(); + void accept(); + void enter(const QModelIndex &index); + void setCurrentDirectory(const QString &dir); + +private: + void setCurrentDirectory(const QModelIndex &dir); + void updateBookmarkMenu(); + void setPathLabel(const QString &dir); + QString shortText(const QString &text, int width); + + QListView *m_view; + QFileSystemModel *m_model; + QLabel *m_title, *m_path; + QPushButton *m_bookmarkButton; + QMenu *m_bookmarkMenu; + QStringList m_bookmarks; + QSignalMapper *m_signalMapper; + +}; + +#endif // FILESELECTOR_H diff --git a/main.cpp b/main.cpp index ba596f7..da3d904 100644 --- a/main.cpp +++ b/main.cpp @@ -28,7 +28,7 @@ int main(int argc, char *argv[]) MainWidget w; if (QApplication::arguments().count() > 1) { - w.loadFile(QApplication::arguments().at(1), ""); + w.loadFile(QApplication::arguments().at(1)); } QObject::connect(&w, SIGNAL(close()), &a, SLOT(quit())); diff --git a/mainwidget.cpp b/mainwidget.cpp index 58f00fa..50cc57e 100644 --- a/mainwidget.cpp +++ b/mainwidget.cpp @@ -20,6 +20,7 @@ #include "mainwidget.h" #include "downloadwidget.h" +#include "fileselector.h" #include "mapwidget.h" #include "markerlist.h" #include "searchwidget.h" @@ -42,6 +43,7 @@ MainWidget::MainWidget(QWidget *parent) m_map(new MapWidget(this)), m_markerList(new MarkerList(this)), m_dlWidget(new DownloadWidget(this)), + m_fileSelector(new FileSelector(this)), m_search(new SearchWidget(this)) { QHBoxLayout *layout = new QHBoxLayout(this); @@ -73,6 +75,7 @@ MainWidget::MainWidget(QWidget *parent) connect(m_map, SIGNAL(close()), this, SIGNAL(close())); connect(m_map, SIGNAL(showMarkerList()), this, SLOT(showList())); connect(m_map, SIGNAL(downloadArea(int, QRectF)), this, SLOT(downloadArea(int, QRectF))); + connect(m_map, SIGNAL(loadFile()), this, SLOT(showFileSelector())); connect(m_map, SIGNAL(search()), this, SLOT(search())); m_stack->insertWidget(0, m_map); @@ -88,6 +91,11 @@ MainWidget::MainWidget(QWidget *parent) connect(m_search, SIGNAL(centerOn(qreal, qreal)), this, SLOT(showMap(qreal, qreal))); m_stack->insertWidget(3, m_search); + m_fileSelector->setFileTypes(QStringList() << "*.gpx" << "*.osm"); + connect(m_fileSelector, SIGNAL(cancel()), this, SLOT(showMap())); + connect(m_fileSelector, SIGNAL(fileSelected(QString)), this, SLOT(loadFile(QString))); + m_stack->insertWidget(4, m_fileSelector); + resize(320, 240); } @@ -95,6 +103,11 @@ MainWidget::~MainWidget() { } +void MainWidget::loadFile(const QString &fileName) +{ + loadFile(fileName, ""); +} + void MainWidget::loadFile(const QString &fileName, const QString &title) { if (fileName.endsWith(".gpx")) { @@ -108,6 +121,7 @@ void MainWidget::loadFile(const QString &fileName, const QString &title) QString t = title.isEmpty() ? "Points Of Interest" : title; m_map->addLayer(l, 3, t); } + showMap(); } void MainWidget::showList() @@ -123,6 +137,7 @@ void MainWidget::markerAdded(const QString &name) void MainWidget::showMap() { m_stack->setCurrentIndex(0); + m_map->setFocus(Qt::OtherFocusReason); } void MainWidget::showMap(qreal lon, qreal lat) @@ -143,3 +158,8 @@ void MainWidget::search() m_stack->setCurrentIndex(3); } +void MainWidget::showFileSelector() +{ + m_stack->setCurrentIndex(4); +} + diff --git a/mainwidget.h b/mainwidget.h index 0f3d297..cce1360 100644 --- a/mainwidget.h +++ b/mainwidget.h @@ -25,6 +25,7 @@ #include class DownloadWidget; +class FileSelector; class MapWidget; class MarkerList; class SearchWidget; @@ -37,6 +38,7 @@ public: ~MainWidget(); public slots: + void loadFile(const QString &fileName); void loadFile(const QString &fileName, const QString &title); signals: @@ -49,12 +51,14 @@ private slots: void showMap(qreal lon, qreal lat); void downloadArea(int level, const QRectF &rect); void search(); + void showFileSelector(); private: QStackedWidget *m_stack; MapWidget *m_map; MarkerList *m_markerList; DownloadWidget *m_dlWidget; + FileSelector *m_fileSelector; SearchWidget *m_search; }; diff --git a/mapwidget.cpp b/mapwidget.cpp index a70966c..c86cf16 100644 --- a/mapwidget.cpp +++ b/mapwidget.cpp @@ -273,6 +273,8 @@ void MapWidget::keyPressEvent(QKeyEvent *event) if (event->modifiers() == Qt::NoModifier) { changeZoomLevel(-1); reloadPixmaps(); + } else if (event->modifiers() == Qt::ControlModifier) { + emit loadFile(); } break; } @@ -414,11 +416,12 @@ void MapWidget::paintEvent(QPaintEvent *event) usage << "l: Show/hide individual layers"; usage << "tab: Show/hide marker list"; if (m_networkMode) { - usage << "d: Download tiles for visible area"; + usage << "d: Download map data for visible area"; painter.drawText(30, 200, 260, 20, Qt::AlignCenter, "Map data: (C) OpenStreetMap.org"); } else if (!m_copyright.isEmpty()) { painter.drawText(30, 200, 260, 20, Qt::AlignCenter, "Map data: (C) "+m_copyright); } + usage << "Ctrl+o: Load POI / Track file"; painter.drawText(30, 10, 260, 20, Qt::AlignCenter, "NanoMap - Usage"); painter.drawLine(70, 27, 250, 27); painter.drawText(30, 30, 260, 200, Qt::AlignLeft, usage.join("\n")); diff --git a/mapwidget.h b/mapwidget.h index a5b316b..3333e39 100644 --- a/mapwidget.h +++ b/mapwidget.h @@ -49,6 +49,7 @@ signals: void close(); void showMarkerList(); void downloadArea(int level, const QRectF &rect); + void loadFile(); void search(); protected: diff --git a/pics/bookmark.png b/pics/bookmark.png new file mode 100644 index 0000000..34e72c3 Binary files /dev/null and b/pics/bookmark.png differ diff --git a/pics/cancel.png b/pics/cancel.png new file mode 100644 index 0000000..45f8949 Binary files /dev/null and b/pics/cancel.png differ diff --git a/pics/icons.qrc b/pics/icons.qrc new file mode 100644 index 0000000..75ead96 --- /dev/null +++ b/pics/icons.qrc @@ -0,0 +1,9 @@ + + + up.png + ok.png + cancel.png + bookmark.png + nobookmark.png + + diff --git a/pics/nobookmark.png b/pics/nobookmark.png new file mode 100644 index 0000000..1ce6d3e Binary files /dev/null and b/pics/nobookmark.png differ diff --git a/pics/ok.png b/pics/ok.png new file mode 100644 index 0000000..c173526 Binary files /dev/null and b/pics/ok.png differ diff --git a/pics/up.png b/pics/up.png new file mode 100644 index 0000000..b3d9cef Binary files /dev/null and b/pics/up.png differ