1
0

fb2code.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include "fb2code.hpp"
  2. #ifdef USE_SCINTILLA
  3. /////////////////////////////////////////////////////////////////////////////
  4. //
  5. // http://qtcoder.blogspot.com/2010/10/qscintills.html
  6. // http://www.riverbankcomputing.co.uk/static/Docs/QScintilla2/classQsciScintilla.html
  7. //
  8. /////////////////////////////////////////////////////////////////////////////
  9. #include <Qsci/qscilexerxml.h>
  10. #include <QtDebug>
  11. Fb2CodeEdit::Fb2CodeEdit(QWidget *parent) :
  12. QsciScintilla(parent)
  13. {
  14. zoomTo(1);
  15. setUtf8(true);
  16. setCaretLineVisible(true);
  17. setCaretLineBackgroundColor(QColor("gainsboro"));
  18. setWrapMode(QsciScintilla::WrapWord);
  19. /*
  20. //setup autocompletion
  21. setAutoCompletionSource(QsciScintilla::AcsAll);
  22. setAutoCompletionCaseSensitivity(true);
  23. setAutoCompletionReplaceWord(true);
  24. setAutoCompletionShowSingle(true);
  25. setAutoCompletionThreshold(2);
  26. */
  27. //setup margins
  28. setMarginsBackgroundColor(QColor("gainsboro"));
  29. setMarginLineNumbers(0, true);
  30. setFolding(QsciScintilla::BoxedFoldStyle, 1);
  31. //setup brace matching
  32. setBraceMatching(QsciScintilla::SloppyBraceMatch);
  33. setMatchedBraceBackgroundColor(Qt::yellow);
  34. setUnmatchedBraceForegroundColor(Qt::blue);
  35. //setup end-of-line mode
  36. #if defined Q_WS_X11
  37. setEolMode(QsciScintilla::EolUnix);
  38. #elif defined Q_WS_WIN
  39. setEolMode(QsciScintilla::EolWindows);
  40. #elif defined Q_WS_MAC
  41. setEolMode(QsciScintilla::EolMac);
  42. #endif
  43. //setup auto-indentation
  44. setAutoIndent(true);
  45. setIndentationGuides(true);
  46. setIndentationsUseTabs(false);
  47. setIndentationWidth(2);
  48. QsciLexerXML * lexer = new QsciLexerXML;
  49. lexer->setFoldPreprocessor(true);
  50. #ifdef Q_WS_WIN
  51. lexer->setFont(QFont("Courier New", 8));
  52. #else
  53. lexer->setFont(QFont("Monospace", 8));
  54. #endif
  55. setLexer(lexer);
  56. connect(this, SIGNAL(linesChanged()), SLOT(linesChanged()));
  57. }
  58. void Fb2CodeEdit::linesChanged()
  59. {
  60. QString width = QString().setNum(lines() * 10);
  61. setMarginWidth(0, width);
  62. }
  63. void Fb2CodeEdit::load(const QByteArray &array, const QList<int> &folds)
  64. {
  65. SendScintilla(SCI_SETTEXT, array.constData());
  66. SendScintilla(SCI_EMPTYUNDOBUFFER);
  67. foldAll(false);
  68. foldLine(1);
  69. for (QList<int>::const_iterator it = folds.constBegin(); it != folds.constEnd(); it++) {
  70. foldLine(*it);
  71. }
  72. }
  73. #else // USE_SCINTILLA
  74. #include <QtGui>
  75. Fb2CodeEdit::Fb2CodeEdit(QWidget *parent) : QPlainTextEdit(parent)
  76. {
  77. lineNumberArea = new LineNumberArea(this);
  78. connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
  79. connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int)));
  80. connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine()));
  81. #ifdef Q_WS_WIN
  82. setFont(QFont("Courier New", 8));
  83. #else
  84. setFont(QFont("Monospace", 8));
  85. #endif
  86. updateLineNumberAreaWidth(0);
  87. highlightCurrentLine();
  88. }
  89. int Fb2CodeEdit::lineNumberAreaWidth()
  90. {
  91. int digits = 1;
  92. int max = qMax(1, blockCount());
  93. while (max >= 10) {
  94. max /= 10;
  95. ++digits;
  96. }
  97. int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits;
  98. return space;
  99. }
  100. void Fb2CodeEdit::updateLineNumberAreaWidth(int /* newBlockCount */)
  101. {
  102. setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
  103. }
  104. void Fb2CodeEdit::updateLineNumberArea(const QRect &rect, int dy)
  105. {
  106. if (dy)
  107. lineNumberArea->scroll(0, dy);
  108. else
  109. lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());
  110. if (rect.contains(viewport()->rect()))
  111. updateLineNumberAreaWidth(0);
  112. }
  113. void Fb2CodeEdit::resizeEvent(QResizeEvent *e)
  114. {
  115. QPlainTextEdit::resizeEvent(e);
  116. QRect cr = contentsRect();
  117. lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
  118. }
  119. void Fb2CodeEdit::highlightCurrentLine()
  120. {
  121. QList<QTextEdit::ExtraSelection> extraSelections;
  122. if (!isReadOnly()) {
  123. QTextEdit::ExtraSelection selection;
  124. QColor lineColor = QColor(Qt::yellow).lighter(160);
  125. selection.format.setBackground(lineColor);
  126. selection.format.setProperty(QTextFormat::FullWidthSelection, true);
  127. selection.cursor = textCursor();
  128. selection.cursor.clearSelection();
  129. extraSelections.append(selection);
  130. }
  131. setExtraSelections(extraSelections);
  132. }
  133. void Fb2CodeEdit::lineNumberAreaPaintEvent(QPaintEvent *event)
  134. {
  135. QPainter painter(lineNumberArea);
  136. painter.fillRect(event->rect(), Qt::lightGray);
  137. QTextBlock block = firstVisibleBlock();
  138. int blockNumber = block.blockNumber();
  139. int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
  140. int bottom = top + (int) blockBoundingRect(block).height();
  141. while (block.isValid() && top <= event->rect().bottom()) {
  142. if (block.isVisible() && bottom >= event->rect().top()) {
  143. QString number = QString::number(blockNumber + 1);
  144. painter.setPen(Qt::black);
  145. painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(),
  146. Qt::AlignRight, number);
  147. }
  148. block = block.next();
  149. top = bottom;
  150. bottom = top + (int) blockBoundingRect(block).height();
  151. ++blockNumber;
  152. }
  153. }
  154. #endif // USE_SCINTILLA