X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fuisupport%2Fuistyle.cpp;h=b0db2ab28778329279fe1429a7cd138c7d24b5dc;hp=a799d33566cb6ad7ebac456b593e14b64ee4a0ec;hb=2e955358a6f3ca2a125ddcfa2a089576662611e3;hpb=4b8250614f98ae8d87e97ed0c071d6c77a29713f diff --git a/src/uisupport/uistyle.cpp b/src/uisupport/uistyle.cpp index a799d335..b0db2ab2 100644 --- a/src/uisupport/uistyle.cpp +++ b/src/uisupport/uistyle.cpp @@ -25,33 +25,28 @@ UiStyle::UiStyle(const QString &settingsKey) : _settingsKey(settingsKey) { // register FormatList if that hasn't happened yet - // FIXME I don't think this actually avoids double registration... :/ + // FIXME I don't think this actually avoids double registration... then again... does it hurt? if(QVariant::nameToType("UiStyle::FormatList") == QVariant::Invalid) { qRegisterMetaType("UiStyle::FormatList"); qRegisterMetaTypeStreamOperators("UiStyle::FormatList"); Q_ASSERT(QVariant::nameToType("UiStyle::FormatList") != QVariant::Invalid); } + _defaultFont = QFont("Monospace", QApplication::font().pointSize()); + // Default format _defaultPlainFormat.setForeground(QBrush("#000000")); - _defaultPlainFormat.setFont(QFont("Monospace", QApplication::font().pointSize())); + _defaultPlainFormat.setFont(_defaultFont); _defaultPlainFormat.font().setFixedPitch(true); _defaultPlainFormat.font().setStyleHint(QFont::TypeWriter); setFormat(None, _defaultPlainFormat, Settings::Default); - + // Load saved custom formats UiStyleSettings s(_settingsKey); foreach(FormatType type, s.availableFormats()) { _customFormats[type] = s.customFormat(type); } - // Initialize color codes according to mIRC "standard" - QStringList colors; - //colors << "white" << "black" << "navy" << "green" << "red" << "maroon" << "purple" << "orange"; - //colors << "yellow" << "lime" << "teal" << "aqua" << "royalblue" << "fuchsia" << "grey" << "silver"; - colors << "#ffffff" << "#000000" << "#000080" << "#008000" << "#ff0000" << "#800000" << "#800080" << "#ffa500"; - colors << "#ffff00" << "#00ff00" << "#008080" << "#00ffff" << "#4169E1" << "#ff00ff" << "#808080" << "#c0c0c0"; - // Now initialize the mapping between FormatCodes and FormatTypes... _formatCodes["%O"] = None; _formatCodes["%B"] = Bold; @@ -79,14 +74,21 @@ UiStyle::UiStyle(const QString &settingsKey) : _settingsKey(settingsKey) { _formatCodes["%DM"] = ModeFlags; _formatCodes["%DU"] = Url; + // Initialize color codes according to mIRC "standard" + QStringList colors; + //colors << "white" << "black" << "navy" << "green" << "red" << "maroon" << "purple" << "orange"; + //colors << "yellow" << "lime" << "teal" << "aqua" << "royalblue" << "fuchsia" << "grey" << "silver"; + colors << "#ffffff" << "#000000" << "#000080" << "#008000" << "#ff0000" << "#800000" << "#800080" << "#ffa500"; + colors << "#ffff00" << "#00ff00" << "#008080" << "#00ffff" << "#4169E1" << "#ff00ff" << "#808080" << "#c0c0c0"; + // Set color formats for(int i = 0; i < 16; i++) { QString idx = QString("%1").arg(i, (int)2, (int)10, (QChar)'0'); - _formatCodes[QString("%Dcf%1").arg(idx)] = (FormatType)(FgCol00 + i); - _formatCodes[QString("%Dcb%1").arg(idx)] = (FormatType)(BgCol00 + i); + _formatCodes[QString("%Dcf%1").arg(idx)] = (FormatType)(FgCol00 | i<<24); + _formatCodes[QString("%Dcb%1").arg(idx)] = (FormatType)(BgCol00 | i<<28); QTextCharFormat fgf, bgf; - fgf.setForeground(QBrush(QColor(colors[i]))); setFormat((FormatType)(FgCol00 + i), fgf, Settings::Default); - bgf.setBackground(QBrush(QColor(colors[i]))); setFormat((FormatType)(BgCol00 + i), bgf, Settings::Default); + fgf.setForeground(QBrush(QColor(colors[i]))); setFormat((FormatType)(FgCol00 | i<<24), fgf, Settings::Default); + bgf.setBackground(QBrush(QColor(colors[i]))); setFormat((FormatType)(BgCol00 | i<<28), bgf, Settings::Default); } // Set a few more standard formats @@ -103,7 +105,7 @@ UiStyle::UiStyle(const QString &settingsKey) : _settingsKey(settingsKey) { } UiStyle::~ UiStyle() { - + qDeleteAll(_cachedFontMetrics); } void UiStyle::setFormat(FormatType ftype, QTextCharFormat fmt, Settings::Mode mode) { @@ -131,7 +133,7 @@ QTextCharFormat UiStyle::format(FormatType ftype, Settings::Mode mode) const { // NOTE: This function is intimately tied to the values in FormatType. Don't change this // until you _really_ know what you do! QTextCharFormat UiStyle::mergedFormat(quint32 ftype) { - if(_cachedFormats.contains(ftype)) return _cachedFormats[ftype]; + if(_cachedFormats.contains(ftype)) return _cachedFormats.value(ftype); if(ftype == Invalid) return QTextCharFormat(); // Now we construct the merged format, starting with the default QTextCharFormat fmt = format(None); @@ -146,8 +148,13 @@ QTextCharFormat UiStyle::mergedFormat(quint32 ftype) { if(ftype & 0x00800000) fmt.merge(format((FormatType)(ftype & 0xf0800000))); // background // URL if(ftype & Url) fmt.merge(format(Url)); - _cachedFormats[ftype] = fmt; - return fmt; + return _cachedFormats[ftype] = fmt; +} + +QFontMetricsF *UiStyle::fontMetrics(quint32 ftype) { + // QFontMetricsF is not assignable, so we need to store pointers :/ + if(_cachedFontMetrics.contains(ftype)) return _cachedFontMetrics.value(ftype); + return (_cachedFontMetrics[ftype] = new QFontMetricsF(mergedFormat(ftype).font())); } UiStyle::FormatType UiStyle::formatType(const QString & code) const { @@ -159,14 +166,32 @@ QString UiStyle::formatCode(FormatType ftype) const { return _formatCodes.key(ftype); } +QList UiStyle::toTextLayoutList(const FormatList &formatList, int textLength) { + QList formatRanges; + QTextLayout::FormatRange range; + int i = 0; + for(i = 0; i < formatList.count(); i++) { + range.format = mergedFormat(formatList.at(i).second); + range.start = formatList.at(i).first; + if(i > 0) formatRanges.last().length = range.start - formatRanges.last().start; + formatRanges.append(range); + } + if(i > 0) formatRanges.last().length = textLength - formatRanges.last().start; + return formatRanges; +} + // This method expects a well-formatted string, there is no error checking! // Since we create those ourselves, we should be pretty safe that nobody does something crappy here. UiStyle::StyledString UiStyle::styleString(const QString &s_) { QString s = s_; + if(s.length() > 65535) { + qWarning() << QString("String too long to be styled: %1").arg(s); + return StyledString(); + } StyledString result; - result.formats.append(qMakePair(0, (quint32)None)); + result.formatList.append(qMakePair((quint16)0, (quint32)None)); quint32 curfmt = (quint32)None; - int pos = 0; int length = 0; + int pos = 0; quint16 length = 0; for(;;) { pos = s.indexOf('%', pos); if(pos < 0) break; @@ -183,7 +208,7 @@ UiStyle::StyledString UiStyle::styleString(const QString &s_) { int color = 10 * s[pos+4].digitValue() + s[pos+5].digitValue(); //TODO: use 99 as transparent color (re mirc color "standard") color &= 0x0f; - if(pos+3 == 'f') + if(s[pos+3] == 'f') curfmt |= (color << 24) | 0x00400000; else curfmt |= (color << 28) | 0x00800000; @@ -208,16 +233,16 @@ UiStyle::StyledString UiStyle::styleString(const QString &s_) { length = code.length(); } s.remove(pos, length); - if(pos == result.formats.last().first) - result.formats.last().second = curfmt; + if(pos == result.formatList.last().first) + result.formatList.last().second = curfmt; else - result.formats.append(qMakePair(pos, curfmt)); + result.formatList.append(qMakePair((quint16)pos, curfmt)); } - result.text = s; + result.plainText = s; return result; } -QString UiStyle::mircToInternal(const QString &mirc_) { +QString UiStyle::mircToInternal(const QString &mirc_) const { QString mirc = mirc_; mirc.replace('%', "%%"); // escape % just to be sure mirc.replace('\x02', "%B"); @@ -265,7 +290,7 @@ UiStyle::StyledMessage UiStyle::styleMessage(const Message &msg) { QString user = userFromMask(msg.sender()); QString host = hostFromMask(msg.sender()); QString nick = nickFromMask(msg.sender()); - QString txt = mircToInternal(msg.text()); + QString txt = mircToInternal(msg.contents()); QString bufferName = msg.bufferInfo().bufferName(); StyledMessage result; @@ -303,7 +328,7 @@ UiStyle::StyledMessage UiStyle::styleMessage(const Message &msg) { break; case Message::Nick: s = tr("%Dr<->"); - if(nick == msg.text()) t = tr("%DrYou are now known as %DN%1%DN").arg(txt); + if(nick == msg.contents()) t = tr("%DrYou are now known as %DN%1%DN").arg(txt); else t = tr("%Dr%DN%1%DN is now known as %DN%2%DN").arg(nick, txt); break; case Message::Mode: @@ -320,7 +345,7 @@ UiStyle::StyledMessage UiStyle::styleMessage(const Message &msg) { t = tr("%De[%1]").arg(txt); } result.sender = styleString(s); - result.text = styleString(t); + result.contents = styleString(t); return result; } @@ -335,12 +360,12 @@ QDataStream &operator<<(QDataStream &out, const UiStyle::FormatList &formatList) } QDataStream &operator>>(QDataStream &in, UiStyle::FormatList &formatList) { - int cnt; + quint16 cnt; in >> cnt; - for(int i = 0; i < cnt; i++) { - int pos; quint32 ftype; + for(quint16 i = 0; i < cnt; i++) { + quint16 pos; quint32 ftype; in >> pos >> ftype; - formatList.append(qMakePair(pos, ftype)); + formatList.append(qMakePair((quint16)pos, ftype)); } return in; }