#include "gui/regui.hpp"
#include <QPaintEvent>
+QStringList ReEdit::m_tabStrings;
+// left arrow:
+QChar ReEdit::m_tabChar = QChar(2192);
+int ReEdit::m_tabWidth = 3;
+
/**
* Calculates the full line height (with gap between lines)
*
m_cursorLine(0),
m_cursorCol(-1),
m_cursorVisible(true),
+ m_widthEdit(0),
+ m_heightEdit(0),
m_insertMode(true),
m_breakLines(false),
m_widthLineNo(50),
- m_widthVScrollBar(0),
- m_widthHScrollBar(0),
+ m_widthVScrollBar(20),
+ m_heightHScrollBar(20),
m_lines(NULL),
m_looks(),
m_standardBrush(new QBrush(Qt::SolidPattern)),
+ m_scrollbarBrush(new QBrush(Qt::SolidPattern)),
+ m_sliderBrush(new QBrush(Qt::ConicalGradientPattern)),
m_brushColors(),
m_standardPen(new QPen(Qt::SolidLine)),
m_standardFont(NULL),
m_standardFont->setPixelSize(16);
m_standardMetrics = new QFontMetrics(*m_standardFont);
m_standardBrush->setColor(Qt::white);
+ QColor color1(214, 210, 208);
+ m_scrollbarBrush->setColor(color1);
+ m_sliderBrush->setColor(Qt::lightGray);
memset(m_looks, 0, sizeof m_looks);
memset(m_brushColors, 0, sizeof m_brushColors);
m_fontColors[ReLook::FG_STANDARD] = new QColor(Qt::black);
m_keyControl[Qt::Key_Delete] = EA_DEL_END_OF_LINE;
m_keyShift[Qt::Key_Delete] = EA_DEL_BEGIN_OF_LINE;
m_keyAlt[Qt::Key_Delete] = EA_DEL_LINE;
+ setTabStrings(3);
}
/**
void ReEdit::paintEvent(QPaintEvent* event){
QRect rect = event->rect();
m_widthEdit = rect.width();
+ m_heightEdit = rect.height();
int lineHeight = heightToFullHeight(m_standardMetrics->height());
- int pageSize = rect.height() / lineHeight;
+ int pageSize = (rect.height() - m_heightHScrollBar) / lineHeight;
int firstLine = m_paragraphs.firstLine();
m_paragraphs.load(firstLine, pageSize, this);
QPainter painter(this);
ReLook* look = lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD);
painter.setBrush(*look->m_brush);
- QRect editArea(rect.left() + m_widthLineNo, rect.top(), rect.right(),
- rect.bottom());
+ QRect editArea(rect.left() + m_widthLineNo, rect.top(),
+ rect.right() - m_widthVScrollBar, rect.bottom() - m_heightHScrollBar);
painter.drawRect(editArea);
m_paragraphs.draw(painter, rect.top(), rect.left() + m_widthLineNo);
int left = rect.left() + m_widthLineNo - 3;
painter.setPen(*look->m_pen);
painter.drawLine(x, y, x, y + lineHeight);
}
+ int maxWidth = max(1, m_paragraphs.maxLineLength());
+ int width = (rect.width() - m_widthLineNo - m_widthVScrollBar)
+ / m_standardMetrics->width('x');
+ int maxLines = max(1, m_lines->lineCount() - pageSize);
+ drawScrollbars(painter, rect, pageSize * 100 / maxLines,
+ m_paragraphs.firstLine() * 100 / maxLines, width * 100 / maxWidth, 0);
+}
+
+void calcSliderSize(int size, int minSize, int sizePercent, int posPercent,
+ int& position, int& length){
+ if (sizePercent > 100)
+ sizePercent = 100;
+ if (posPercent > 100)
+ posPercent = 100;
+ length = size * sizePercent / 100;
+ if (length < minSize)
+ length = minSize;
+ position = (size - length) * posPercent / 100;
}
+/**
+ * Draws the scrollbars.
+ *
+ * @param painter the paint unit
+ * @param rect the full area of the edit field
+ * @param sizeVertical the size of the scrollbar (in %)
+ * @param posVertical the position of the scrollbar (in %)
+ * @param sizeHorizontal the size of the scrollbar (in %)
+ * @param posHorizontal the position of the scrollbar (in %)
+ */
+void ReEdit::drawScrollbars(QPainter& painter, const QRect& rect,
+ int sizeVertical, int posVertical, int sizeHorizontal, int posHorizontal){
+ // We paint the vertical scrollbar:
+ painter.setBrush(*m_scrollbarBrush);
+ int x = rect.right() - m_widthVScrollBar;
+ painter.drawRect(x, rect.top(), m_widthVScrollBar,
+ rect.height() - m_heightHScrollBar);
+
+ // We paint the horizontal scrollbar:
+ painter.drawRect(rect.left() + m_widthLineNo,
+ rect.bottom() - m_heightHScrollBar,
+ rect.width() - m_widthVScrollBar - m_widthLineNo, m_heightHScrollBar);
+
+ // Slider (vertical)
+ painter.setBrush(*m_sliderBrush);
+ int sliderSize = 0;
+ int sliderPos = 0;
+ calcSliderSize(rect.height() - m_heightHScrollBar, m_heightHScrollBar,
+ sizeVertical, posVertical, sliderPos, sliderSize);
+ painter.drawRect(x + 1, rect.top() + sliderPos, m_widthVScrollBar - 2,
+ sliderSize);
+ // Slider (horizontal)
+ calcSliderSize(rect.width() - m_widthLineNo - m_widthVScrollBar,
+ m_heightHScrollBar, sizeHorizontal, posHorizontal, sliderPos, sliderSize);
+ painter.drawRect(rect.left() + m_widthLineNo + sliderPos,
+ rect.bottom() - m_heightHScrollBar + 1, sliderSize,
+ m_heightHScrollBar - 2);
+}
/**
* Handles the mouse click event.
*
}
emit repaint();
}
+/**
+ * Calculates the tabulator expanding strings.
+ *
+ * Example (tab width = 3):
+ * <pre>
+ * "\tz" -> ' z' -> '\t' + ' '
+ * "x\tz" -> 'x z' -> '\t' + ' '
+ * "xy\tz" -> 'xy z' -> '\t'
+ * </pre>
+ * @param tabWidth
+ */
+void ReEdit::setTabStrings(int tabWidth){
+ m_tabWidth = tabWidth;
+ m_tabStrings.clear();
+ QString blanks;
+ blanks.fill(' ', tabWidth);
+ for (int ix = 0; ix < tabWidth - 1; ix++){
+ m_tabStrings.append(m_tabChar + blanks.mid(0, tabWidth - 1 - ix));
+ }
+}
/**
* Returns the line number of the cursor line.
emit repaint();
}
+/**
+ * Constructor.
+ */
+ReParagraphs::ReParagraphs() :
+ m_builders(),
+ m_firstLine(0),
+ m_lines(NULL),
+ m_list(),
+ m_maxLineLength(0){
+
+}
+
/**
* Destructor.
*/
* Makes the list empty and frees the resources.
*/
void ReParagraphs::clear(){
+ m_maxLineLength = 0;
for (int ix = m_list.length() - 1; ix >= 0; ix--){
ReParagraph* current = m_list.at(ix);
delete current;
*/
void ReParagraphs::load(int lineNo, int count, ReEdit* edit){
clear();
+ m_maxLineLength = 0;
m_firstLine = lineNo;
for (int ix = lineNo; ix < lineNo + count; ix++){
ReParagraph* para = new ReParagraph();
m_list.append(para);
for (int builder = 0; builder < m_builders.length(); builder++)
m_builders.at(builder)->buildParagraph(*para, ix, edit);
+ int current = para->m_columns;
+ if (current > m_maxLineLength)
+ m_maxLineLength = current;
}
}
ReEdit* edit){
if (paragraph.length() == 0){
const QString& text = edit->lines().lineAt(lineNo);
- ReEditText* part = new ReEditText(text,
- edit->lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD));
+ ReLook* look = edit->lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD);
+ paragraph.m_columns = 0;
+ int ixTab;
+ ReEditText* part;
+ int start = 0;
+ while ((ixTab = text.indexOf('\t', start)) >= 0){
+ if (ixTab > start){
+ part = new ReEditText(text.mid(start, ixTab - start), look);
+ paragraph.append(part);
+ paragraph.m_columns += ixTab - start;
+ }
+ paragraph.append(
+ new ReEditText(ReEdit::tabString(paragraph.m_columns), look));
+ start = ixTab + 1;
+ }
+
+ part = new ReEditText(start == 0 ? text : text.mid(start), look);
+ paragraph.m_columns += part->text().length();
paragraph.append(part);
}
}
void ReParagraph::draw(QPainter& painter, int& top, int left){
int x = left;
QFontMetrics* metrics = at(0)->look()->m_metrics;
+ x += metrics->width('x') / 2;
int height = metrics->height();
int y = top + height - metrics->descent();
top += heightToFullHeight(height);
for (int ix = 0; ix < length(); ix++){
ReEditText* current = at(ix);
-#if 0
- QBrush& brush = *current->look()->m_brush;
- brush.setColor(Qt::lightGray);
- painter.setBackground(brush);
-#endif
QFont& font = *current->look()->m_font;
painter.setFont(font);
QPen& pen = *current->look()->m_pen;
- //pen.setColor(Qt::blue);
- //QColor color1 = pen.color();
painter.setPen(pen);
painter.drawText(x, y, current->text());
x += metrics->width(current->text());
}
}
+
virtual ~ReParagraph();
public:
void draw(QPainter& painter, int& top, int left);
+public:
+ // number of columns of the paragraph (length with expanded tabs).
+ int m_columns;
};
/**
*/
class ReParagraphs {
public:
+ ReParagraphs();
virtual ~ReParagraphs();
public:
/** Appends a paragraph builder to the list
QList <ReParagraph*>& list(){
return m_list;
}
+ /** Returns the maximal line length of all lines in the paragraph list.
+ * @return the maximal line length
+ */
+ inline
+ int maxLineLength() const{
+ return m_maxLineLength;
+ }
protected:
QList <ReParagraphBuilder*> m_builders;
int m_firstLine;
ReLines* m_lines;
QList <ReParagraph*> m_list;
+ int m_maxLineLength;
};
/**
protected:
int columnToTextIndex(int cursorCol);
QBrush* createBrush(ReLook::BackGround background);
+ void drawScrollbars(QPainter& painter, const QRect& rect, int sizeVertical,
+ int posVertical, int sizeHorizontal, int posHorizontal);
void ensureCursorVisible(int cursorLine = -1);
void reposition(int firstLine);
int textIndexToColumn(int index);
void paintEvent(QPaintEvent *);
void mousePressEvent(QMouseEvent* event);
void keyPressEvent(QKeyEvent* event);
+public:
+ /** Returns the tabulator expanding string.
+ * @param position the position of the tabulator (0..N-1)
+ * @return the tabulator expanding string
+ */
+ inline static const QString& tabString(int position){
+ return m_tabStrings.at(position % m_tabWidth);
+ }
+ static void setTabStrings(int tabWidth);
protected:
/// the lines to display
ReParagraphs m_paragraphs;
bool m_cursorVisible;
// number of pixels of the width of the edit field
int m_widthEdit;
+ // number of pixels of the height of the edit field
+ int m_heightEdit;
/// true: keys will be inserted at the cursor position
bool m_insertMode;
/// true: a file line will be displayed in multiple lines (if long enough)
/// number of pixels for the right scroll bar
int m_widthVScrollBar;
/// number of pixels for the bottom scroll bar
- int m_widthHScrollBar;
+ int m_heightHScrollBar;
ReLines* m_lines;
ReLook* m_looks[ReLook::BG_COUNT * ReLook::FG_COUNT];
QBrush* m_standardBrush;
+ QBrush* m_scrollbarBrush;
+ QBrush* m_sliderBrush;
QColor* m_brushColors[ReLook::BG_COUNT];
QPen* m_standardPen;
QFont* m_standardFont;
QMap <int, EditorAction> m_keyControlShift;
QMap <int, EditorAction> m_keyRaw;
QMap <int, EditorAction> m_keyShift;
+protected:
+ static QStringList m_tabStrings;
+ static QChar m_tabChar;
+ static int m_tabWidth;
};
#endif // REEDITOR_HPP