Make the new style engine compile and maybe even work. (Cached) format data is now
authorManuel Nickschas <sputnick@quassel-irc.org>
Wed, 7 May 2008 22:43:29 +0000 (22:43 +0000)
committerManuel Nickschas <sputnick@quassel-irc.org>
Wed, 7 May 2008 22:43:29 +0000 (22:43 +0000)
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...

12 files changed:
src/common/global.cpp
src/common/message.cpp
src/common/message.h
src/qtui/chatitem.h
src/qtui/chatline.cpp
src/qtui/chatline.h
src/qtui/chatlinemodel.h
src/qtui/mainwin.cpp
src/qtui/topicbutton.cpp
src/qtui/topicbutton.h
src/uisupport/uistyle.cpp
src/uisupport/uistyle.h

index 9f0e224..59afde1 100644 (file)
@@ -96,7 +96,6 @@ void Global::registerMetaTypes() {
   qRegisterMetaTypeStreamOperators<UserId>("UserId");
   qRegisterMetaTypeStreamOperators<AccountId>("AccountId");
   qRegisterMetaTypeStreamOperators<MsgId>("MsgId");
-
 }
 
 // Static variables
index 15708b3..63446b1 100644 (file)
@@ -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()
index 9070b05..c6f4e3b 100644 (file)
@@ -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;
index 451bc98..2b7ac8a 100644 (file)
@@ -43,7 +43,7 @@ class ChatItem : public QGraphicsItem {
     inline QPersistentModelIndex persistentIndex() const { return _index; }
     inline const MessageModel *model() const { return _index.isValid() ? qobject_cast<const MessageModel *>(_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);
 
index c3e08b9..d4c8390 100644 (file)
  ***************************************************************************/
 
 #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<UiStyle::FormatList>(_msg.timestamp.formats);
+        case ChatlineModel::SenderColumn:    return QVariant::fromValue<UiStyle::FormatList>(_msg.sender.formats);
+        case ChatlineModel::TextColumn:      return QVariant::fromValue<UiStyle::FormatList>(_msg.text.formats);
+      }
+      break;
   }
+  return MessageItem::data(column, role);
 }
 
 bool Chatline::setData(int column, const QVariant &value, int role) {
index 24b1372..448f4db 100644 (file)
@@ -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
index da4a541..3dec09c 100644 (file)
@@ -27,6 +27,10 @@ class ChatlineModel : public MessageModel {
   Q_OBJECT
 
   public:
+    enum ChatlineRole {
+      FormatRole = MessageModel::UserRole
+    };
+
     ChatlineModel(QObject *parent = 0);
     virtual ~ChatlineModel();
 
index 55b99f4..cbf50ad 100644 (file)
@@ -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);
index 4c26bfc..2030a54 100644 (file)
@@ -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()));
 }
index e0b2188..ce6aeb4 100644 (file)
@@ -38,7 +38,9 @@ protected:
   virtual void paintEvent(QPaintEvent *event);
 
 private:
+#ifndef SPUTDEV
   UiStyle::StyledText styledText;
+#endif
   QSize _sizeHint;
 };
 
index e0d34c6..4cb7dff 100644 (file)
 
 #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<FormatList>("UiStyle::FormatList");
+    qRegisterMetaTypeStreamOperators<FormatList>("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 <http://www.mirc.co.uk/help/color.txt>.
+  //       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;
+}
index 59841dc..ce0735c 100644 (file)
@@ -25,6 +25,7 @@
 # include "old-uistyle.h"
 #else
 
+#include <QDataStream>
 #include <QTextCharFormat>
 #include <QTextLayout>
 #include <QUrl>
 #include "settings.h"
 
 class UiStyle {
+  Q_DECLARE_TR_FUNCTIONS (UiStyle);
 
   public:
     UiStyle(const QString &settingsKey);
     virtual ~UiStyle();
 
+    typedef QList<QPair<int, quint32> > 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<QPair<int, quint32> > 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<FormatType, QTextCharFormat> _defaultFormats;
     QHash<FormatType, QTextCharFormat> _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