From 858cba7fac9928549219de070397be65e1b92cde Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Wed, 7 May 2008 22:43:29 +0000 Subject: [PATCH] Make the new style engine compile and maybe even work. (Cached) format data is now provided as a role in ChatlineModel. Now I just need to implement the whole view thing... well, actually displaying messages is probably totally overrated anyway... --- src/common/global.cpp | 1 - src/common/message.cpp | 10 +-- src/common/message.h | 2 + src/qtui/chatitem.h | 2 +- src/qtui/chatline.cpp | 23 +++++-- src/qtui/chatline.h | 3 +- src/qtui/chatlinemodel.h | 4 ++ src/qtui/mainwin.cpp | 3 +- src/qtui/topicbutton.cpp | 6 +- src/qtui/topicbutton.h | 2 + src/uisupport/uistyle.cpp | 137 ++++++++++++++++++++++++++++++++++++++ src/uisupport/uistyle.h | 20 +++++- 12 files changed, 195 insertions(+), 18 deletions(-) diff --git a/src/common/global.cpp b/src/common/global.cpp index 9f0e224d..59afde13 100644 --- a/src/common/global.cpp +++ b/src/common/global.cpp @@ -96,7 +96,6 @@ void Global::registerMetaTypes() { qRegisterMetaTypeStreamOperators("UserId"); qRegisterMetaTypeStreamOperators("AccountId"); qRegisterMetaTypeStreamOperators("MsgId"); - } // Static variables diff --git a/src/common/message.cpp b/src/common/message.cpp index 15708b37..63446b10 100644 --- a/src/common/message.cpp +++ b/src/common/message.cpp @@ -48,6 +48,7 @@ void Message::setFlags(Flags flags) { _flags = flags; } +#ifndef SPUTDEV QString Message::mircToInternal(QString mirc) { mirc.replace('%', "%%"); // escape % just to be sure mirc.replace('\x02', "%B"); @@ -168,14 +169,7 @@ QString Message::formattedText() { format(); return _formattedText; } - -/* -QString Message::formattedToHtml(const QString &f) { - - - return f; -} -*/ +#endif /* SPUTDEV */ QDataStream &operator<<(QDataStream &out, const Message &msg) { out << msg.msgId() << (quint32)msg.timestamp().toTime_t() << (quint32)msg.type() << (quint8)msg.flags() diff --git a/src/common/message.h b/src/common/message.h index 9070b05e..c6f4e3ba 100644 --- a/src/common/message.h +++ b/src/common/message.h @@ -73,6 +73,7 @@ public: void setFlags(Flags flags); +#ifndef SPUTDEV QString formattedTimestamp(); QString formattedSender(); QString formattedText(); @@ -83,6 +84,7 @@ public: static QString mircToInternal(QString); void format(); +#endif private: QDateTime _timestamp; diff --git a/src/qtui/chatitem.h b/src/qtui/chatitem.h index 451bc98a..2b7ac8a3 100644 --- a/src/qtui/chatitem.h +++ b/src/qtui/chatitem.h @@ -43,7 +43,7 @@ class ChatItem : public QGraphicsItem { inline QPersistentModelIndex persistentIndex() const { return _index; } inline const MessageModel *model() const { return _index.isValid() ? qobject_cast(_index.model()) : 0; } inline int row() const { return _index.isValid() ? _index.row() : 0; } - QVariant data(int role) const; + virtual QVariant data(int role) const; //QString text() const; //void setText(const UiStyle::StyledText &text); diff --git a/src/qtui/chatline.cpp b/src/qtui/chatline.cpp index c3e08b9e..d4c83909 100644 --- a/src/qtui/chatline.cpp +++ b/src/qtui/chatline.cpp @@ -19,19 +19,34 @@ ***************************************************************************/ #include "chatline.h" +#include "chatlinemodel.h" +#include "qtui.h" +#include "uistyle.h" Chatline::Chatline(const Message &msg) : MessageItem(msg) { - _msg = msg; - + _msg = QtUi::style()->styleMessage(msg); } QVariant Chatline::data(int column, int role) const { switch(role) { - case MessageModel::DisplayRole: return _msg.text(); - default: return MessageItem::data(column, role); + case ChatlineModel::DisplayRole: + switch(column) { + case ChatlineModel::TimestampColumn: return _msg.timestamp.text; + case ChatlineModel::SenderColumn: return _msg.sender.text; + case ChatlineModel::TextColumn: return _msg.text.text; + } + break; + case ChatlineModel::FormatRole: + switch(column) { + case ChatlineModel::TimestampColumn: return QVariant::fromValue(_msg.timestamp.formats); + case ChatlineModel::SenderColumn: return QVariant::fromValue(_msg.sender.formats); + case ChatlineModel::TextColumn: return QVariant::fromValue(_msg.text.formats); + } + break; } + return MessageItem::data(column, role); } bool Chatline::setData(int column, const QVariant &value, int role) { diff --git a/src/qtui/chatline.h b/src/qtui/chatline.h index 24b13728..448f4dbe 100644 --- a/src/qtui/chatline.h +++ b/src/qtui/chatline.h @@ -22,6 +22,7 @@ #define CHATLINE_H_ #include "messagemodel.h" +#include "uistyle.h" class Chatline : public MessageItem { @@ -33,7 +34,7 @@ class Chatline : public MessageItem { virtual bool setData(int column, const QVariant &value, int role); private: - Message _msg; + UiStyle::StyledMessage _msg; }; #endif diff --git a/src/qtui/chatlinemodel.h b/src/qtui/chatlinemodel.h index da4a5419..3dec09c1 100644 --- a/src/qtui/chatlinemodel.h +++ b/src/qtui/chatlinemodel.h @@ -27,6 +27,10 @@ class ChatlineModel : public MessageModel { Q_OBJECT public: + enum ChatlineRole { + FormatRole = MessageModel::UserRole + }; + ChatlineModel(QObject *parent = 0); virtual ~ChatlineModel(); diff --git a/src/qtui/mainwin.cpp b/src/qtui/mainwin.cpp index 55b99f43..cbf50adc 100644 --- a/src/qtui/mainwin.cpp +++ b/src/qtui/mainwin.cpp @@ -572,12 +572,13 @@ void MainWin::receiveMessage(const Message &msg) { UiSettings uiSettings; +#ifndef SPUTDEV if(uiSettings.value("DisplayPopupMessages", QVariant(true)).toBool()) { // FIXME don't invoke style engine for this! QString text = QtUi::style()->styleString(Message::mircToInternal(msg.text())).text; displayTrayIconMessage(title, text); } - +#endif if(uiSettings.value("AnimateTrayIcon", QVariant(true)).toBool()) { QApplication::alert(this); setTrayIconActivity(true); diff --git a/src/qtui/topicbutton.cpp b/src/qtui/topicbutton.cpp index 4c26bfc3..2030a541 100644 --- a/src/qtui/topicbutton.cpp +++ b/src/qtui/topicbutton.cpp @@ -45,6 +45,8 @@ void TopicButton::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.setBackgroundMode(Qt::OpaqueMode); + // FIXME re-enable topic painting +#ifndef SPUTDEV QRect drawRect = rect(); QRect brect; QString textPart; @@ -56,6 +58,7 @@ void TopicButton::paintEvent(QPaintEvent *event) { painter.drawText(drawRect, Qt::AlignLeft|Qt::TextSingleLine, textPart, &brect); drawRect.setLeft(brect.right()); } +#endif } void TopicButton::setAndStyleText(const QString &text) { @@ -64,6 +67,7 @@ void TopicButton::setAndStyleText(const QString &text) { setText(text); // this triggers a repaint event +#ifndef SPUTDEV styledText = QtUi::style()->styleString(Message::mircToInternal(text)); int height = 1; foreach(QTextLayout::FormatRange fr, styledText.formats) { @@ -75,7 +79,7 @@ void TopicButton::setAndStyleText(const QString &text) { height = QFontMetrics(qApp->font()).height(); setFixedHeight(height); - +#endif // show topic in tooltip setToolTip(tr("%1\n\nClick to edit!").arg(QAbstractButton::text())); } diff --git a/src/qtui/topicbutton.h b/src/qtui/topicbutton.h index e0b21885..ce6aeb42 100644 --- a/src/qtui/topicbutton.h +++ b/src/qtui/topicbutton.h @@ -38,7 +38,9 @@ protected: virtual void paintEvent(QPaintEvent *event); private: +#ifndef SPUTDEV UiStyle::StyledText styledText; +#endif QSize _sizeHint; }; diff --git a/src/uisupport/uistyle.cpp b/src/uisupport/uistyle.cpp index e0d34c66..4cb7dff6 100644 --- a/src/uisupport/uistyle.cpp +++ b/src/uisupport/uistyle.cpp @@ -21,8 +21,17 @@ #include "uistyle.h" #include "uistylesettings.h" +#include "util.h" 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... :/ + if(QVariant::nameToType("UiStyle::FormatList") == QVariant::Invalid) { + qRegisterMetaType("UiStyle::FormatList"); + qRegisterMetaTypeStreamOperators("UiStyle::FormatList"); + Q_ASSERT(QVariant::nameToType("UiStyle::FormatList") != QVariant::Invalid); + } + // Default format _defaultPlainFormat.setForeground(QBrush("#000000")); _defaultPlainFormat.setFont(QFont("Monospace", QApplication::font().pointSize())); @@ -204,3 +213,131 @@ UiStyle::StyledString UiStyle::styleString(const QString &s_) { result.text = s; return result; } + +QString UiStyle::mircToInternal(const QString &mirc_) { + QString mirc = mirc_; + mirc.replace('%', "%%"); // escape % just to be sure + mirc.replace('\x02', "%B"); + mirc.replace('\x0f', "%O"); + mirc.replace('\x12', "%R"); + mirc.replace('\x16', "%R"); + mirc.replace('\x1d', "%S"); + mirc.replace('\x1f', "%U"); + + // Now we bring the color codes (\x03) in a sane format that can be parsed more easily later. + // %Dcfxx is foreground, %Dcbxx is background color, where xx is a 2 digit dec number denoting the color code. + // %Dc- turns color off. + // Note: We use the "mirc standard" as described in . + // This means that we don't accept something like \x03,5 (even though others, like WeeChat, do). + int pos = 0; + for(;;) { + pos = mirc.indexOf('\x03', pos); + if(pos < 0) break; // no more mirc color codes + QString ins, num; + int l = mirc.length(); + int i = pos + 1; + // check for fg color + if(i < l && mirc[i].isDigit()) { + num = mirc[i++]; + if(i < l && mirc[i].isDigit()) num.append(mirc[i++]); + else num.prepend('0'); + ins = QString("%Dcf%1").arg(num); + + if(i+1 < l && mirc[i] == ',' && mirc[i+1].isDigit()) { + i++; + num = mirc[i++]; + if(i < l && mirc[i].isDigit()) num.append(mirc[i++]); + else num.prepend('0'); + ins += QString("%Dcb%1").arg(num); + } + } else { + ins = "%Dc-"; + } + mirc.replace(pos, i-pos, ins); + } + return mirc; +} + +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 bufferName = msg.bufferInfo().bufferName(); + + StyledMessage result; + + result.timestamp = styleString(tr("%DT[%1]").arg(msg.timestamp().toLocalTime().toString("hh:mm:ss"))); + + QString s, t; + switch(msg.type()) { + case Message::Plain: + s = tr("%DS<%1>").arg(nick); t = tr("%D0%1").arg(txt); break; + case Message::Notice: + s = tr("%Dn[%1]").arg(nick); t = tr("%Dn%1").arg(txt); break; + case Message::Server: + s = tr("%Ds*"); t = tr("%Ds%1").arg(txt); break; + case Message::Error: + s = tr("%De*"); t = tr("%De%1").arg(txt); break; + case Message::Join: + s = tr("%Dj-->"); t = tr("%Dj%DN%1%DN %DH(%2@%3)%DH has joined %DC%4%DC").arg(nick, user, host, bufferName); break; + case Message::Part: + s = tr("%Dp<--"); t = tr("%Dp%DN%1%DN %DH(%2@%3)%DH has left %DC%4%DC").arg(nick, user, host, bufferName); + if(!txt.isEmpty()) t = QString("%1 (%2)").arg(t).arg(txt); + break; + case Message::Quit: + s = tr("%Dq<--"); t = tr("%Dq%DN%DU%1%DU%DN %DH(%2@%3)%DH has quit").arg(nick, user, host); + if(!txt.isEmpty()) t = QString("%1 (%2)").arg(t).arg(txt); + break; + case Message::Kick: + { s = tr("%Dk<-*"); + QString victim = txt.section(" ", 0, 0); + //if(victim == ui.ownNick->currentText()) victim = tr("you"); + QString kickmsg = txt.section(" ", 1); + t = tr("%Dk%DN%1%DN has kicked %DN%2%DN from %DC%3%DC").arg(nick).arg(victim).arg(bufferName); + if(!kickmsg.isEmpty()) t = QString("%1 (%2)").arg(t).arg(kickmsg); + } + break; + case Message::Nick: + s = tr("%Dr<->"); + if(nick == msg.text()) 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: + s = tr("%Dm***"); + if(nick.isEmpty()) t = tr("%DmUser mode: %DM%1%DM").arg(txt); + else t = tr("%DmMode %DM%1%DM by %DN%2%DN").arg(txt, nick); + break; + case Message::Action: + s = tr("%Da-*-"); + t = tr("%Da%DN%1%DN %2").arg(nick).arg(txt); + break; + default: + s = tr("%De%1").arg(msg.sender()); + t = tr("%De[%1]").arg(txt); + } + result.sender = styleString(s); + result.text = styleString(t); + return result; +} + +QDataStream &operator<<(QDataStream &out, const UiStyle::FormatList &formatList) { + out << formatList.count(); + UiStyle::FormatList::const_iterator it = formatList.begin(); + while(it != formatList.end()) { + out << (*it).first << (*it).second; + ++it; + } + return out; +} + +QDataStream &operator>>(QDataStream &in, UiStyle::FormatList &formatList) { + int cnt; + in >> cnt; + for(int i = 0; i < cnt; i++) { + int pos; quint32 ftype; + in >> pos >> ftype; + formatList.append(qMakePair(pos, ftype)); + } + return in; +} diff --git a/src/uisupport/uistyle.h b/src/uisupport/uistyle.h index 59841dc7..ce0735ce 100644 --- a/src/uisupport/uistyle.h +++ b/src/uisupport/uistyle.h @@ -25,6 +25,7 @@ # include "old-uistyle.h" #else +#include #include #include #include @@ -33,11 +34,14 @@ #include "settings.h" class UiStyle { + Q_DECLARE_TR_FUNCTIONS (UiStyle); public: UiStyle(const QString &settingsKey); virtual ~UiStyle(); + typedef QList > FormatList; + //! This enumerates the possible formats a text element may have. */ /** These formats are ordered on increasing importance, in cases where a given property is specified * by multiple active formats. @@ -118,10 +122,17 @@ class UiStyle { struct StyledString { QString text; - QList > formats; // starting pos, ftypes + FormatList formats; // starting pos, ftypes + }; + + struct StyledMessage { + StyledString timestamp; + StyledString sender; + StyledString text; }; StyledString styleString(const QString &); + StyledMessage styleMessage(const Message &); void setFormat(FormatType, QTextCharFormat, Settings::Mode mode/* = Settings::Custom*/); QTextCharFormat format(FormatType, Settings::Mode mode = Settings::Custom) const; @@ -134,6 +145,8 @@ class UiStyle { private: + QString mircToInternal(const QString &); + QTextCharFormat _defaultPlainFormat; QHash _defaultFormats; QHash _customFormats; @@ -143,5 +156,10 @@ class UiStyle { QString _settingsKey; }; +QDataStream &operator<<(QDataStream &out, const UiStyle::FormatList &formatList); +QDataStream &operator>>(QDataStream &in, UiStyle::FormatList &formatList); + +Q_DECLARE_METATYPE(UiStyle::FormatList); + #endif // SPUTDEV #endif -- 2.20.1