GTextDocument.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #pragma once
  2. #include <AK/Badge.h>
  3. #include <AK/HashTable.h>
  4. #include <AK/NonnullOwnPtrVector.h>
  5. #include <AK/NonnullRefPtr.h>
  6. #include <AK/RefCounted.h>
  7. #include <LibDraw/Color.h>
  8. #include <LibDraw/Font.h>
  9. #include <LibGUI/GTextRange.h>
  10. class GTextEditor;
  11. class GTextDocumentLine;
  12. struct GTextDocumentSpan {
  13. GTextRange range;
  14. Color color;
  15. Optional<Color> background_color;
  16. bool is_skippable { false };
  17. const Font* font { nullptr };
  18. void* data { nullptr };
  19. };
  20. class GTextDocument : public RefCounted<GTextDocument> {
  21. public:
  22. enum class SearchShouldWrap {
  23. No = 0,
  24. Yes
  25. };
  26. class Client {
  27. public:
  28. virtual ~Client();
  29. virtual void document_did_append_line() = 0;
  30. virtual void document_did_insert_line(int) = 0;
  31. virtual void document_did_remove_line(int) = 0;
  32. virtual void document_did_remove_all_lines() = 0;
  33. virtual void document_did_change() = 0;
  34. };
  35. static NonnullRefPtr<GTextDocument> create(Client* client = nullptr)
  36. {
  37. return adopt(*new GTextDocument(client));
  38. }
  39. int line_count() const { return m_lines.size(); }
  40. const GTextDocumentLine& line(int line_index) const { return m_lines[line_index]; }
  41. GTextDocumentLine& line(int line_index) { return m_lines[line_index]; }
  42. void set_spans(const Vector<GTextDocumentSpan>& spans) { m_spans = spans; }
  43. void set_text(const StringView&);
  44. const NonnullOwnPtrVector<GTextDocumentLine>& lines() const { return m_lines; }
  45. NonnullOwnPtrVector<GTextDocumentLine>& lines() { return m_lines; }
  46. bool has_spans() const { return !m_spans.is_empty(); }
  47. const Vector<GTextDocumentSpan>& spans() const { return m_spans; }
  48. void set_span_at_index(int index, GTextDocumentSpan span) { m_spans[index] = move(span); }
  49. void append_line(NonnullOwnPtr<GTextDocumentLine>);
  50. void remove_line(int line_index);
  51. void remove_all_lines();
  52. void insert_line(int line_index, NonnullOwnPtr<GTextDocumentLine>);
  53. void register_client(Client&);
  54. void unregister_client(Client&);
  55. void update_views(Badge<GTextDocumentLine>);
  56. String text_in_range(const GTextRange&) const;
  57. Vector<GTextRange> find_all(const StringView& needle) const;
  58. GTextRange find_next(const StringView&, const GTextPosition& start = {}, SearchShouldWrap = SearchShouldWrap::Yes) const;
  59. GTextRange find_previous(const StringView&, const GTextPosition& start = {}, SearchShouldWrap = SearchShouldWrap::Yes) const;
  60. GTextPosition next_position_after(const GTextPosition&, SearchShouldWrap = SearchShouldWrap::Yes) const;
  61. GTextPosition previous_position_before(const GTextPosition&, SearchShouldWrap = SearchShouldWrap::Yes) const;
  62. char character_at(const GTextPosition&) const;
  63. Optional<GTextDocumentSpan> first_non_skippable_span_before(const GTextPosition&) const;
  64. Optional<GTextDocumentSpan> first_non_skippable_span_after(const GTextPosition&) const;
  65. private:
  66. explicit GTextDocument(Client* client);
  67. NonnullOwnPtrVector<GTextDocumentLine> m_lines;
  68. Vector<GTextDocumentSpan> m_spans;
  69. HashTable<Client*> m_clients;
  70. };
  71. class GTextDocumentLine {
  72. friend class GTextEditor;
  73. friend class GTextDocument;
  74. public:
  75. explicit GTextDocumentLine(GTextDocument&);
  76. explicit GTextDocumentLine(GTextDocument&, const StringView&);
  77. StringView view() const { return { characters(), length() }; }
  78. const char* characters() const { return m_text.data(); }
  79. int length() const { return m_text.size() - 1; }
  80. void set_text(GTextDocument&, const StringView&);
  81. void append(GTextDocument&, char);
  82. void prepend(GTextDocument&, char);
  83. void insert(GTextDocument&, int index, char);
  84. void remove(GTextDocument&, int index);
  85. void append(GTextDocument&, const char*, int);
  86. void truncate(GTextDocument&, int length);
  87. void clear(GTextDocument&);
  88. int first_non_whitespace_column() const;
  89. private:
  90. // NOTE: This vector is null terminated.
  91. Vector<char> m_text;
  92. };