#pragma once #include "model/Annotation.h" #include #include #include #include namespace ws::model { class EditorDocument : public QObject { Q_OBJECT public: explicit EditorDocument(QObject* parent = nullptr); void set_base_image(const QImage& image); [[nodiscard]] const QImage& base_image() const; void add_annotation(const Annotation& annotation); bool select_at(const QPointF& point); void clear_selection(); bool move_selected_by(const QPointF& delta); bool update_annotation(const Annotation& annotation); bool delete_selected(); [[nodiscard]] const std::vector& annotations() const; [[nodiscard]] const Annotation* selected_annotation() const; [[nodiscard]] AnnotationStyle current_style() const; void set_current_style(const AnnotationStyle& style); [[nodiscard]] bool can_undo() const; [[nodiscard]] bool can_redo() const; bool undo(); bool redo(); [[nodiscard]] QImage render_to_image() const; [[nodiscard]] bool is_dirty() const; void mark_clean(); signals: void document_changed(); void selection_changed(); void history_changed(); void dirty_changed(bool dirty); private: struct Snapshot { std::vector annotations; std::optional selected; }; void push_undo_state(); void emit_dirty_if_changed(bool previous_dirty); [[nodiscard]] Annotation* find_annotation(const QUuid& id); [[nodiscard]] const Annotation* find_annotation(const QUuid& id) const; QImage base_image_; std::vector annotations_; std::optional selected_id_; AnnotationStyle current_style_; std::vector undo_stack_; std::vector redo_stack_; bool dirty_ = false; }; } // namespace ws::model