2 #include "preferences.h"
5 #include <QApplication>
10 #include <QScrollArea>
13 const int GAP_LINE_TEXT = 1;
14 const int MARGIN_RIGHT = 1;
16 TextView::TextView(QScrollArea *parent) :
19 m_scrollArea = parent;
20 m_scrollArea->setWidget(this);
21 setObjectName("textView");
26 void TextView::setData(const QByteArray &data)
30 std::string code = detectCode(data.left(1024));
31 convertFrom(code.c_str());
34 void TextView::adjust()
39 for (; offset < m_data.size(); ++offset) {
40 if (m_data[offset] == '\r') {
41 if (offset + 1 < m_data.size() && m_data[offset + 1] == '\n') {
46 else if (m_data[offset] == '\n') {
52 int lineNumWidth = m_charWidth * lineNumChars(lineNum);
54 int xPosText = lineNumWidth + GAP_LINE_TEXT * m_charWidth;
56 setMinimumWidth(xPosText + m_charWidth * 4);
59 m_viewPositions.clear();
64 const int lineMaxWidth = width() - xPosText - MARGIN_RIGHT * m_charWidth;
65 for (lineNum = 1, offset = 0; offset < m_data.size(); ++offset) {
67 if (m_data[offset] == '\r') {
69 if (offset < m_data.size() - 1 && m_data[offset + 1] == '\n') {
73 if (m_data[offset] == '\n') {
78 vPos.lineNum = lineNum;
81 int charWidth = fontMetrics().width(m_data.mid(offset, 1));
84 charWidth = fontMetrics().width(0x21B5);
86 else if (m_data[offset] == '\t') {
87 tabIndent = ((lineWidth + m_tabWidth) / m_tabWidth) * m_tabWidth - lineWidth;
88 charWidth = fontMetrics().width("^");
91 if (x + charWidth >= lineMaxWidth) {
96 vPos.x = xPosText + x;
97 vPos.y = y + wrapLine * m_charHeight;
98 m_viewPositions << vPos;
103 y += (wrapLine + 1) * m_charHeight;
108 if (m_data[offset] == '\t') {
110 if (x > lineMaxWidth) {
111 x = x - lineMaxWidth;
118 lineWidth += charWidth + tabIndent;
122 if (!m_viewPositions.isEmpty()) {
123 setMinimumHeight(m_viewPositions.last().y + m_charHeight);
127 void TextView::convertFrom(const char *code)
129 QTextCodec *codec = QTextCodec::codecForName(code);
130 m_data = codec->toUnicode(m_source);
135 emit statusChanged(code);
138 int TextView::cursorPos(const QPoint &pos)
142 for (n = 0; n < m_viewPositions.size(); n++) {
143 if (pos.y() < m_viewPositions[n].y) {
144 y = m_viewPositions[n].y;
149 for(; n < m_viewPositions.size(); n++) {
150 if (pos.x() < m_viewPositions[n].x) {
153 if (y < m_viewPositions[n].y) {
161 int TextView::lineNumChars(int lines) const
164 if (m_viewPositions.isEmpty()) {
167 lines = m_viewPositions.last().lineNum;
169 return QString("%1").arg(lines).size() + 1;
172 void TextView::resetSelection(int index)
174 m_selectionInit = index;
175 m_selectionBegin = index;
176 m_selectionEnd = index;
178 emit copyAvailable(false);
181 void TextView::setSelection(int index)
183 if (index > m_selectionInit) {
184 m_selectionBegin = m_selectionInit;
185 m_selectionEnd = index;
188 m_selectionBegin = index;
189 m_selectionEnd = m_selectionInit;
192 emit copyAvailable(m_selectionBegin != m_selectionEnd);
195 void TextView::onConvertFromEUC()
197 convertFrom("EUC-JP");
200 void TextView::onConvertFromJIS()
202 convertFrom("ISO 2022-JP");
205 void TextView::onConvertFromSJIS()
207 convertFrom("Shift-JIS");
210 void TextView::onConvertFromUTF8()
212 convertFrom("UTF-8");
215 void TextView::onConvertFromUTF16()
217 convertFrom("UTF-16");
220 void TextView::onConvertFromUTF16BE()
222 convertFrom("UTF-16BE");
225 void TextView::onConvertFromUTF16LE()
227 convertFrom("UTF-16LE");
230 void TextView::onCopy()
233 int length = m_viewPositions[m_selectionEnd].offset -
234 m_viewPositions[m_selectionBegin].offset;
236 selected = m_data.mid(m_viewPositions[m_selectionBegin].offset, length);
238 QClipboard *clipboard = qApp->clipboard();
239 clipboard->setText(selected);
242 void TextView::onScaleDown()
244 Preferences prefs(this);
245 QFont font = prefs.getTextViewFont();
246 font.setPointSize(font.pointSize() - 1);
247 prefs.setTextViewFont(font);
254 void TextView::onScaleUp()
256 Preferences prefs(this);
257 QFont font = prefs.getTextViewFont();
258 font.setPointSize(font.pointSize() + 1);
259 prefs.setTextViewFont(font);
266 void TextView::onSelectAll()
269 m_selectionBegin = 0;
270 m_selectionEnd = m_viewPositions.size();
273 void TextView::setVisible(bool visible)
276 Preferences prefs(this);
277 QPalette pal = this->palette();
278 pal.setColor(this->backgroundRole(), prefs.getTextViewBgColor());
279 pal.setColor(this->foregroundRole(), prefs.getTextViewFgColor());
280 pal.setBrush(QPalette::BrightText, prefs.getTextViewCtrlColor());
281 this->setPalette(pal);
282 this->setAutoFillBackground(true);
283 this->setFont(prefs.getTextViewFont());
285 m_charHeight = fontMetrics().height();
286 m_charWidth = fontMetrics().width('9');
287 m_tabWidth = 8 * m_charWidth;
290 QWidget::setVisible(visible);
293 void TextView::mousePressEvent(QMouseEvent *e)
295 if (e->button() == Qt::LeftButton) {
296 int cPos = cursorPos(e->pos());
297 resetSelection(cPos);
303 void TextView::mouseDoubleClickEvent(QMouseEvent *e)
305 if (e->button() == Qt::LeftButton) {
306 int cPos = cursorPos(e->pos());
307 if (cPos >= m_viewPositions.size()) {
308 cPos = m_viewPositions.size() - 1;
310 int y = m_viewPositions[cPos].y;
313 for (n = cPos; n >= 0; n--) {
314 if (m_viewPositions[n].y != y) {
321 for (n = cPos; n < m_viewPositions.size(); n++) {
322 if (m_viewPositions[n].y != y) {
332 void TextView::mouseMoveEvent(QMouseEvent *e)
334 m_scrollArea->ensureVisible(e->x(), e->y());
336 int cPos = cursorPos(e->pos());
341 void TextView::paintEvent(QPaintEvent *e)
343 QPainter painter(this);
346 QRect lineNumRect(e->rect());
347 lineNumRect.setLeft(0);
348 lineNumRect.setWidth(m_charWidth * lineNumChars());
349 painter.fillRect(lineNumRect, Qt::gray);
354 idx < m_viewPositions.size() &&
355 m_viewPositions[idx].y < e->rect().top();
358 prevLine = m_viewPositions[idx].lineNum;
361 painter.setPen(this->palette().color(this->foregroundRole()));
363 idx < m_viewPositions.size() &&
364 m_viewPositions[idx].y <= e->rect().bottom() + m_charHeight;
367 const ViewPosition &vPos = m_viewPositions[idx];
370 if (vPos.lineNum != prevLine) {
371 prevLine = vPos.lineNum;
372 painter.setPen(Qt::black);
373 painter.setBackgroundMode(Qt::TransparentMode);
374 QString lineNumber = QString("%1").arg(vPos.lineNum);
376 lineNumRect.right() - fontMetrics().width(lineNumber),
381 if (m_selectionBegin <= idx && idx < m_selectionEnd) {
382 painter.setBackground(this->palette().highlight());
383 painter.setBackgroundMode(Qt::OpaqueMode);
384 painter.setPen(this->palette().highlightedText().color());
387 painter.setPen(this->palette().color(this->foregroundRole()));
388 painter.setBackgroundMode(Qt::TransparentMode);
391 QString ch = m_data.mid(vPos.offset, 1);
392 if (ch == "\r" || ch == "\n") {
393 painter.setPen(this->palette().color(QPalette::BrightText));
394 painter.drawText(vPos.x, vPos.y, QChar(0x21B5));
395 painter.setPen(this->palette().color(this->foregroundRole()));
397 else if (ch == "\t") {
398 painter.setPen(this->palette().color(QPalette::BrightText));
399 painter.drawText(vPos.x, vPos.y, "^");
400 painter.setPen(this->palette().color(this->foregroundRole()));
403 painter.drawText(vPos.x, vPos.y, ch);
408 void TextView::resizeEvent(QResizeEvent *e)
410 QWidget::resizeEvent(e);