fstl

A fast STL file viewer
git clone https://git.sinitax.com/fstl/fstl
Log | Files | Refs | README | sfeed.txt

commit 9daf792a09bda1d9dd59d9d5a073cfde1424dd68
parent 4aeed9723029d1c3be3dc12dbfa9a2946dde1090
Author: Matt Keeter <matt.j.keeter@gmail.com>
Date:   Sat, 20 Oct 2018 16:32:29 -0400

Merge pull request #38 from phreaker0/folder-navigation

folder navigation
Diffstat:
Msrc/window.cpp | 135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/window.h | 11+++++++++++
2 files changed, 146 insertions(+), 0 deletions(-)

diff --git a/src/window.cpp b/src/window.cpp @@ -248,6 +248,11 @@ void Window::on_load_recent(QAction* a) load_stl(a->data().toString()); } +void Window::on_loaded(const QString& filename) +{ + current_file = filename; +} + void Window::rebuild_recent_files() { QSettings settings; @@ -320,6 +325,8 @@ bool Window::load_stl(const QString& filename, bool is_reload) this, &Window::setWindowTitle); connect(loader, &Loader::loaded_file, this, &Window::set_watched); + connect(loader, &Loader::loaded_file, + this, &Window::on_loaded); autoreload_action->setEnabled(true); reload_action->setEnabled(true); } @@ -342,3 +349,131 @@ void Window::dropEvent(QDropEvent *event) { load_stl(event->mimeData()->urls().front().toLocalFile()); } + +void Window::sorted_insert(QStringList& list, const QCollator& collator, const QString& value) +{ + int start = 0; + int end = list.size() - 1; + int index = 0; + while (start <= end){ + int mid = (start+end)/2; + if (list[mid] == value) { + return; + } + int compare = collator.compare(value, list[mid]); + if (compare < 0) { + end = mid-1; + index = mid; + } else { + start = mid+1; + index = start; + } + } + + list.insert(index, value); +} + +void Window::build_folder_file_list() +{ + QString current_folder_path = QFileInfo(current_file).absoluteDir().absolutePath(); + if (!lookup_folder_files.isEmpty()) + { + if (current_folder_path == lookup_folder) { + return; + } + + lookup_folder_files.clear(); + } + lookup_folder = current_folder_path; + + QCollator collator; + collator.setNumericMode(true); + + QDirIterator dirIterator(lookup_folder, QStringList() << "*.stl", QDir::Files | QDir::Readable | QDir::Hidden); + while (dirIterator.hasNext()) { + dirIterator.next(); + + QString name = dirIterator.fileName(); + sorted_insert(lookup_folder_files, collator, name); + } +} + +QPair<QString, QString> Window::get_file_neighbors() +{ + if (current_file.isEmpty()) { + return QPair<QString, QString>(QString::null, QString::null); + } + + build_folder_file_list(); + + QFileInfo fileInfo(current_file); + + QString current_dir = fileInfo.absoluteDir().absolutePath(); + QString current_name = fileInfo.fileName(); + + QString prev = QString::null; + QString next = QString::null; + + QListIterator<QString> fileIterator(lookup_folder_files); + while (fileIterator.hasNext()) { + QString name = fileIterator.next(); + + if (name == current_name) { + if (fileIterator.hasNext()) { + next = current_dir + QDir::separator() + fileIterator.next(); + } + break; + } + + prev = name; + } + + if (!prev.isEmpty()) { + prev.prepend(QDir::separator()); + prev.prepend(current_dir); + } + + return QPair<QString, QString>(prev, next); +} + +bool Window::load_prev(void) +{ + QPair<QString, QString> neighbors = get_file_neighbors(); + if (neighbors.first.isEmpty()) { + return false; + } + + return load_stl(neighbors.first); +} + +bool Window::load_next(void) +{ + QPair<QString, QString> neighbors = get_file_neighbors(); + if (neighbors.second.isEmpty()) { + return false; + } + + return load_stl(neighbors.second); +} + +void Window::keyPressEvent(QKeyEvent* event) +{ + if (!open_action->isEnabled()) + { + QMainWindow::keyPressEvent(event); + return; + } + + if (event->key() == Qt::Key_Left) + { + load_prev(); + return; + } + else if (event->key() == Qt::Key_Right) + { + load_next(); + return; + } + + QMainWindow::keyPressEvent(event); +} diff --git a/src/window.h b/src/window.h @@ -4,6 +4,7 @@ #include <QMainWindow> #include <QActionGroup> #include <QFileSystemWatcher> +#include <QCollator> class Canvas; @@ -13,10 +14,13 @@ class Window : public QMainWindow public: explicit Window(QWidget* parent=0); bool load_stl(const QString& filename, bool is_reload=false); + bool load_prev(void); + bool load_next(void); protected: void dragEnterEvent(QDragEnterEvent* event) override; void dropEvent(QDropEvent* event) override; + void keyPressEvent(QKeyEvent* event) override; public slots: void on_open(); @@ -39,9 +43,13 @@ private slots: void on_autoreload_triggered(bool r); void on_clear_recent(); void on_load_recent(QAction* a); + void on_loaded(const QString& filename); private: void rebuild_recent_files(); + void sorted_insert(QStringList& list, const QCollator& collator, const QString& value); + void build_folder_file_list(); + QPair<QString, QString> get_file_neighbors(); QAction* const open_action; QAction* const about_action; @@ -58,6 +66,9 @@ private: QAction* const recent_files_clear_action; const static int MAX_RECENT_FILES=8; const static QString RECENT_FILE_KEY; + QString current_file; + QString lookup_folder; + QStringList lookup_folder_files; QFileSystemWatcher* watcher;