vplaintextedit.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #ifndef VPLAINTEXTEDIT_H
  2. #define VPLAINTEXTEDIT_H
  3. #include <QPlainTextEdit>
  4. #include <QPlainTextDocumentLayout>
  5. #include <QTextBlock>
  6. #include "vlinenumberarea.h"
  7. class QTextDocument;
  8. class VImageResourceManager;
  9. class QPaintEvent;
  10. class QPainter;
  11. class QResizeEvent;
  12. struct VBlockImageInfo
  13. {
  14. public:
  15. VBlockImageInfo()
  16. : m_blockNumber(-1), m_margin(0), m_imageWidth(0), m_imageHeight(0)
  17. {
  18. }
  19. VBlockImageInfo(int p_blockNumber,
  20. const QString &p_imageName,
  21. int p_margin = 0)
  22. : m_blockNumber(p_blockNumber),
  23. m_imageName(p_imageName),
  24. m_margin(p_margin),
  25. m_imageWidth(0),
  26. m_imageHeight(0)
  27. {
  28. }
  29. // Block number.
  30. int m_blockNumber;
  31. // The name of the image corresponding to this block.
  32. QString m_imageName;
  33. // Left margin of the image.
  34. int m_margin;
  35. private:
  36. // Width and height of the image display.
  37. int m_imageWidth;
  38. int m_imageHeight;
  39. friend class VImageResourceManager;
  40. friend class VPlainTextEdit;
  41. friend class VPlainTextDocumentLayout;
  42. };
  43. class VPlainTextEdit : public QPlainTextEdit, public VTextEditWithLineNumber
  44. {
  45. Q_OBJECT
  46. public:
  47. explicit VPlainTextEdit(QWidget *p_parent = nullptr);
  48. explicit VPlainTextEdit(const QString &p_text, QWidget *p_parent = nullptr);
  49. virtual ~VPlainTextEdit();
  50. // Update images of these given blocks.
  51. // Images of blocks not given here will be clear.
  52. void updateBlockImages(const QVector<VBlockImageInfo> &p_blocksInfo);
  53. void clearBlockImages();
  54. // Whether the resoruce manager contains image of name @p_imageName.
  55. bool containsImage(const QString &p_imageName) const;
  56. // Add an image to the resources.
  57. void addImage(const QString &p_imageName, const QPixmap &p_image);
  58. void setBlockImageEnabled(bool p_enabled);
  59. void setImageWidthConstrainted(bool p_enabled);
  60. void paintLineNumberArea(QPaintEvent *p_event) Q_DECL_OVERRIDE;
  61. void setLineNumberType(LineNumberType p_type);
  62. // The minimum width of an image in pixels.
  63. static const int c_minimumImageWidth;
  64. protected:
  65. // Most logics are copied from QPlainTextEdit.
  66. // Differences: draw images for blocks with preview image.
  67. void paintEvent(QPaintEvent *p_event) Q_DECL_OVERRIDE;
  68. void resizeEvent(QResizeEvent *p_event) Q_DECL_OVERRIDE;
  69. private slots:
  70. // Update viewport margin to hold the line number area.
  71. void updateLineNumberAreaMargin();
  72. void updateLineNumberArea();
  73. private:
  74. void init();
  75. // @p_blockRect: the content rect of @p_block.
  76. void drawImageOfBlock(const QTextBlock &p_block,
  77. QPainter *p_painter,
  78. const QRectF &p_blockRect);
  79. QRectF originalBlockBoundingRect(const QTextBlock &p_block) const;
  80. VPlainTextDocumentLayout *getLayout() const;
  81. // Widget to display line number area.
  82. VLineNumberArea *m_lineNumberArea;
  83. VImageResourceManager *m_imageMgr;
  84. bool m_blockImageEnabled;
  85. // Whether constraint the width of image to the width of the viewport.
  86. bool m_imageWidthConstrainted;
  87. // Maximum width of the images.
  88. int m_maximumImageWidth;
  89. LineNumberType m_lineNumberType;
  90. };
  91. class VPlainTextDocumentLayout : public QPlainTextDocumentLayout
  92. {
  93. Q_OBJECT
  94. public:
  95. explicit VPlainTextDocumentLayout(QTextDocument *p_document,
  96. VImageResourceManager *p_imageMgr,
  97. bool p_blockImageEnabled = false);
  98. // Will adjust the rect if there is an image for this block.
  99. QRectF blockBoundingRect(const QTextBlock &p_block) const Q_DECL_OVERRIDE;
  100. QRectF frameBoundingRect(QTextFrame *p_frame) const Q_DECL_OVERRIDE;
  101. QSizeF documentSize() const Q_DECL_OVERRIDE;
  102. void setBlockImageEnabled(bool p_enabled);
  103. void setMaximumImageWidth(int p_width);
  104. private:
  105. VImageResourceManager *m_imageMgr;
  106. bool m_blockImageEnabled;
  107. int m_maximumImageWidth;
  108. };
  109. inline void VPlainTextDocumentLayout::setBlockImageEnabled(bool p_enabled)
  110. {
  111. m_blockImageEnabled = p_enabled;
  112. }
  113. inline void VPlainTextDocumentLayout::setMaximumImageWidth(int p_width)
  114. {
  115. m_maximumImageWidth = p_width;
  116. }
  117. inline void VPlainTextEdit::setLineNumberType(LineNumberType p_type)
  118. {
  119. if (p_type == m_lineNumberType) {
  120. return;
  121. }
  122. m_lineNumberType = p_type;
  123. updateLineNumberArea();
  124. }
  125. #endif // VPLAINTEXTEDIT_H