#pragma once #include #include #include #include #include "dialog_model.h" #include "key_event.h" #include "list_model.h" #include "services/storage_service.h" #include "services/update_service.h" #include "text_pager.h" #include "ui/canvas.h" #include "ui/theme.h" namespace roro { // Looks inside a file for the Storage App (F1, Q134), by type: text read as it's scrolled, a hex // dump, a Capture's packets, a Track's summary, an Update File's version and whether it's // genuine. Tab switches to the text or the hex of the same file. Nothing here changes a file. class FileViewer { public: FileViewer(StorageService& storage, UpdateService& update) : storage_(storage), update_(update) {} void open(const std::string& path, uint32_t size); void close(); bool onKey(const KeyEvent& e); // false: leave the viewer bool update(uint32_t nowMs); // true: draw again void draw(Canvas& c); private: enum class Mode { Text, Hex, Gpx, Pcap, Packet, Ota }; static constexpr int kRows = 8; static constexpr int kCols = 38; struct Scan; // what a storage job reads through a whole file for: shared with that job size_t readAt(uint32_t offset, uint8_t* into, size_t len); void show(Mode mode); void startScan(Mode mode); void refresh(); // reads what the screen shows, when it has moved void openPacket(int index); void scroll(int lines); std::string title() const; StorageService& storage_; UpdateService& update_; std::string path_; uint32_t size_ = 0; Mode mode_ = Mode::Text, base_ = Mode::Text; std::shared_ptr file_; // opened and read on the storage task only std::unique_ptr pager_; uint32_t hexTop_ = 0; // in rows of eight bytes std::vector shown_; // the rows on screen bool stale_ = true; std::shared_ptr scan_; bool scanShown_ = false; int shownPercent_ = -1; ListModel packets_{kRows}; int rowsFrom_ = -1; std::vector details_; int detailsTop_ = 0; std::unique_ptr confirm_; }; } // namespace roro