X-Git-Url: https://git.quassel-irc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fuisupport%2Fmultilineedit.cpp;h=02e9df2e23b5d80565dbcdd092cb05ab78cd593f;hb=d37d8399f02fcdd9093d17f728c71af445ca56df;hp=699d4ec825eac48b46b122340146da61df96e0a9;hpb=09d19fe065125ccc6e406fa325d675387788ab3c;p=quassel.git diff --git a/src/uisupport/multilineedit.cpp b/src/uisupport/multilineedit.cpp index 699d4ec8..02e9df2e 100644 --- a/src/uisupport/multilineedit.cpp +++ b/src/uisupport/multilineedit.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005/06 by the Quassel Project * + * Copyright (C) 2005-2010 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -59,6 +59,24 @@ MultiLineEdit::MultiLineEdit(QWidget *parent) reset(); connect(this, SIGNAL(textChanged()), this, SLOT(on_textChanged())); + + _mircColorMap["00"] = "#ffffff"; + _mircColorMap["01"] = "#000000"; + _mircColorMap["02"] = "#000080"; + _mircColorMap["03"] = "#008000"; + _mircColorMap["04"] = "#ff0000"; + _mircColorMap["05"] = "#800000"; + _mircColorMap["06"] = "#800080"; + _mircColorMap["07"] = "#ffa500"; + _mircColorMap["08"] = "#ffff00"; + _mircColorMap["09"] = "#00ff00"; + _mircColorMap["10"] = "#008080"; + _mircColorMap["11"] = "#00ffff"; + _mircColorMap["12"] = "#4169e1"; + _mircColorMap["13"] = "#ff00ff"; + _mircColorMap["14"] = "#808080"; + _mircColorMap["15"] = "#c0c0c0"; + } MultiLineEdit::~MultiLineEdit() { @@ -171,7 +189,7 @@ void MultiLineEdit::setPasteProtectionEnabled(bool enable, QWidget *) { } void MultiLineEdit::historyMoveBack() { - addToHistory(text(), true); + addToHistory(convertRichtextToMircCodes(), true); if(idx > 0) { idx--; @@ -180,7 +198,7 @@ void MultiLineEdit::historyMoveBack() { } void MultiLineEdit::historyMoveForward() { - addToHistory(text(), true); + addToHistory(convertRichtextToMircCodes(), true); if(idx < history.count()) { idx++; @@ -189,7 +207,7 @@ void MultiLineEdit::historyMoveForward() { else reset(); // equals clear() in this case } else { - addToHistory(text()); + addToHistory(convertRichtextToMircCodes()); reset(); } } @@ -231,8 +249,11 @@ void MultiLineEdit::keyPressEvent(QKeyEvent *event) { # endif #endif - if(_mode == SingleLine) + if(_mode == SingleLine) { + event->accept(); + on_returnPressed(); return; + } #ifdef HAVE_KDE KTextEdit::keyPressEvent(event); #else @@ -296,8 +317,202 @@ void MultiLineEdit::keyPressEvent(QKeyEvent *event) { #endif } +QString MultiLineEdit::convertRichtextToMircCodes() { + bool underline, bold, italic, color; + QString mircText, mircFgColor, mircBgColor; + QTextCursor cursor = textCursor(); + QTextCursor peekcursor = textCursor(); + cursor.movePosition(QTextCursor::Start); + + underline = bold = italic = color = false; + + while (cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor)) { + + if (cursor.selectedText() == QString(QChar(QChar::LineSeparator))) { + if (color) { + color = false; + mircText.append('\x03'); + } + if (underline) { + underline = false; + mircText.append('\x1f'); + } + if (italic) { + italic = false; + mircText.append('\x1d'); + } + if (bold) { + bold = false; + mircText.append('\x02'); + } + mircText.append('\n'); + } + else { + if (!bold && cursor.charFormat().font().bold()) { + bold = true; + mircText.append('\x02'); + } + if (!italic && cursor.charFormat().fontItalic()) { + italic = true; + mircText.append('\x1d'); + } + if (!underline && cursor.charFormat().fontUnderline()) { + underline = true; + mircText.append('\x1f'); + } + if (!color && (cursor.charFormat().foreground().isOpaque() || cursor.charFormat().background().isOpaque())) { + color = true; + mircText.append('\x03'); + mircFgColor = _mircColorMap.key(cursor.charFormat().foreground().color().name()); + mircBgColor = _mircColorMap.key(cursor.charFormat().background().color().name()); + + if (mircFgColor.isEmpty()) { + mircFgColor = "01"; //use black if the current foreground color can't be converted + } + + mircText.append(mircFgColor); + if (cursor.charFormat().background().isOpaque()) + mircText.append("," + mircBgColor); + } + + mircText.append(cursor.selectedText()); + + peekcursor.setPosition(cursor.position()); + peekcursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + + if (mircCodesChanged(cursor, peekcursor)) { + if (color) { + color = false; + mircText.append('\x03'); + } + if (underline) { + underline = false; + mircText.append('\x1f'); + } + if (italic) { + italic = false; + mircText.append('\x1d'); + } + if (bold) { + bold = false; + mircText.append('\x02'); + } + } + } + + cursor.clearSelection(); + } + if (color) { + color = false; + mircText.append('\x03'); + } + if (underline) { + underline = false; + mircText.append('\x1f'); + } + if (italic) { + italic = false; + mircText.append('\x1d'); + } + if (bold) { + bold = false; + mircText.append('\x02'); + } + + return mircText; +} + +bool MultiLineEdit::mircCodesChanged(QTextCursor &cursor, QTextCursor &peekcursor) { + bool changed = false; + if (cursor.charFormat().font().bold() != peekcursor.charFormat().font().bold()) + changed = true; + if (cursor.charFormat().fontItalic() != peekcursor.charFormat().fontItalic()) + changed = true; + if (cursor.charFormat().fontUnderline() != peekcursor.charFormat().fontUnderline()) + changed = true; + if (cursor.charFormat().foreground().color() != peekcursor.charFormat().foreground().color()) + changed = true; + if (cursor.charFormat().background().color() != peekcursor.charFormat().background().color()) + changed = true; + return changed; +} + +QString MultiLineEdit::convertMircCodesToHtml(const QString &text) { + QStringList words; + QRegExp mircCode = QRegExp("(|||)", Qt::CaseSensitive); + + int posLeft = 0; + int posRight = 0; + + for(;;) { + posRight = mircCode.indexIn(text, posLeft); + + if(posRight < 0) { + words << text.mid(posLeft); + break; // no more mirc color codes + } + + if (posLeft < posRight) { + words << text.mid(posLeft, posRight - posLeft); + posLeft = posRight; + } + + posRight = text.indexOf(mircCode.cap(), posRight + 1); + words << text.mid(posLeft, posRight + 1 - posLeft); + posLeft = posRight + 1; + } + + for (int i = 0; i < words.count(); i++) { + QString style; + if (words[i].contains('\x02')) { + style.append(" font-weight:600;"); + words[i].replace('\x02',""); + } + if (words[i].contains('\x1d')) { + style.append(" font-style:italic;"); + words[i].replace('\x1d',""); + } + if (words[i].contains('\x1f')) { + style.append(" text-decoration: underline;"); + words[i].replace('\x1f',""); + } + if (words[i].contains('\x03')) { + int pos = words[i].indexOf('\x03'); + int len = 3; + QString fg = words[i].mid(pos + 1,2); + QString bg; + if (words[i][pos+3] == ',') + bg = words[i].mid(pos+4,2); + + style.append(" color:"); + style.append(_mircColorMap[fg]); + style.append(";"); + + if (!bg.isEmpty()) { + style.append(" background-color:"); + style.append(_mircColorMap[bg]); + style.append(";"); + len = 6; + } + words[i].replace(pos, len, ""); + words[i].replace('\x03',""); + } + words[i].replace("&","&"); + words[i].replace("<", "<"); + words[i].replace(">", ">"); + words[i].replace("\"", """); + if (style.isEmpty()) { + words[i] = "" + words[i] + ""; + } + else { + words[i] = "" + words[i] + ""; + } + } + return words.join("").replace("\n","
"); +} + void MultiLineEdit::on_returnPressed() { - on_returnPressed(text()); + on_returnPressed(convertRichtextToMircCodes()); } void MultiLineEdit::on_returnPressed(const QString & text) { @@ -310,6 +525,8 @@ void MultiLineEdit::on_returnPressed(const QString & text) { } reset(); tempHistory.clear(); + } else { + emit noTextEntered(); } } @@ -358,6 +575,7 @@ void MultiLineEdit::on_textChanged() { on_documentHeightChanged(_lastDocumentHeight); } updateSizeHint(); + ensureCursorVisible(); } void MultiLineEdit::on_documentHeightChanged(qreal) { @@ -376,7 +594,7 @@ void MultiLineEdit::reset() { void MultiLineEdit::showHistoryEntry() { // if the user changed the history, display the changed line - setPlainText(tempHistory.contains(idx) ? tempHistory[idx] : history[idx]); + setHtml(convertMircCodesToHtml(tempHistory.contains(idx) ? tempHistory[idx] : history[idx])); QTextCursor cursor = textCursor(); QTextBlockFormat format = cursor.blockFormat(); format.setLeftMargin(leftMargin); // we want a little space between the frame and the contents