Ok this is the major rework of quassel we've all been waiting for. For the actual...
[quassel.git] / src / qtgui / chatline.cpp
index 5d0a973..335e15b 100644 (file)
@@ -40,67 +40,14 @@ ChatLine::~ChatLine() {
 }
 
 void ChatLine::formatMsg(Message msg) {
-  QString user = userFromMask(msg.sender);
-  QString host = hostFromMask(msg.sender);
-  QString nick = nickFromMask(msg.sender);
-  QString text = Style::mircToInternal(msg.text);
-  QString networkName = msg.buffer.network();
-  QString bufferName = msg.buffer.buffer();
-
-  QString c = 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(text); break;
-    case Message::Server:
-      s = tr("%Ds*"); t = tr("%Ds%1").arg(text); break;
-    case Message::Error:
-      s = tr("%De*"); t = tr("%De%1").arg(text); break;
-    case Message::Join:
-      s = tr("%Dj-->"); t = tr("%Dj%DN%DU%1%DU%DN %DH(%2@%3)%DH has joined %DC%DU%4%DU%DC").arg(nick, user, host, bufferName); break;
-    case Message::Part:
-      s = tr("%Dp<--"); t = tr("%Dp%DN%DU%1%DU%DN %DH(%2@%3)%DH has left %DC%DU%4%DU%DC").arg(nick, user, host, bufferName);
-      if(!text.isEmpty()) t = QString("%1 (%2)").arg(t).arg(text);
-      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(!text.isEmpty()) t = QString("%1 (%2)").arg(t).arg(text);
-      break;
-    case Message::Kick:
-    { s = tr("%Dk<-*");
-    QString victim = text.section(" ", 0, 0);
-        //if(victim == ui.ownNick->currentText()) victim = tr("you");
-    QString kickmsg = text.section(" ", 1);
-    t = tr("%Dk%DN%DU%1%DU%DN has kicked %DN%DU%2%DU%DN from %DC%DU%3%DU%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(msg.text);
-      else t = tr("%Dr%DN%1%DN is now known as %DN%DU%2%DU%DN").arg(nick, msg.text);
-      break;
-    case Message::Mode:
-      s = tr("%Dm***");
-      if(nick.isEmpty()) t = tr("%DmUser mode: %DM%1%DM").arg(msg.text);
-      else t = tr("%DmMode %DM%1%DM by %DN%DU%2%DU%DN").arg(msg.text, nick);
-      break;
-    case Message::Action:
-      s = tr("%Da-*-");
-      t = tr("%Da%DN%DU%1%DU%DN %2").arg(nick).arg(msg.text);
-      break;
-    default:
-      s = tr("%De%1").arg(msg.sender);
-      t = tr("%De[%1]").arg(msg.text);
-  }
   QTextOption tsOption, senderOption, textOption;
-  tsFormatted = Style::internalToFormatted(c);
-  senderFormatted = Style::internalToFormatted(s);
-  textFormatted = Style::internalToFormatted(t);
+  styledTimeStamp = Style::formattedToStyled(msg.formattedTimeStamp());
+  styledSender = Style::formattedToStyled(msg.formattedSender());
+  styledText = Style::formattedToStyled(msg.formattedText());
   precomputeLine();
 }
 
-QList<ChatLine::FormatRange> ChatLine::calcFormatRanges(const Style::FormattedString &fs, QTextLayout::FormatRange additional) {
+QList<ChatLine::FormatRange> ChatLine::calcFormatRanges(const Style::StyledString &fs, QTextLayout::FormatRange additional) {
   QList<FormatRange> ranges;
   QList<QTextLayout::FormatRange> formats = fs.formats;
   formats.append(additional);
@@ -140,9 +87,9 @@ void ChatLine::setSelection(SelectionMode mode, int start, int end) {
   QTextLayout::FormatRange tsSel, senderSel, textSel;
   switch (mode) {
     case None:
-      tsFormat = calcFormatRanges(tsFormatted);
-      senderFormat = calcFormatRanges(senderFormatted);
-      textFormat = calcFormatRanges(textFormatted);
+      tsFormat = calcFormatRanges(styledTimeStamp);
+      senderFormat = calcFormatRanges(styledSender);
+      textFormat = calcFormatRanges(styledText);
       break;
     case Partial:
       selectionStart = qMin(start, end); selectionEnd = qMax(start, end);
@@ -151,44 +98,44 @@ void ChatLine::setSelection(SelectionMode mode, int start, int end) {
       textSel.start = selectionStart;
       textSel.length = selectionEnd - selectionStart;
       //textFormat.append(textSel);
-      textFormat = calcFormatRanges(textFormatted, textSel);
+      textFormat = calcFormatRanges(styledText, textSel);
       foreach(FormatRange fr, textFormat);
       break;
     case Full:
       tsSel.format.setForeground(pal.brush(QPalette::HighlightedText));
       tsSel.format.setBackground(pal.brush(QPalette::Highlight));
-      tsSel.start = 0; tsSel.length = tsFormatted.text.length();
-      tsFormat = calcFormatRanges(tsFormatted, tsSel);
+      tsSel.start = 0; tsSel.length = styledTimeStamp.text.length();
+      tsFormat = calcFormatRanges(styledTimeStamp, tsSel);
       senderSel.format.setForeground(pal.brush(QPalette::HighlightedText));
       senderSel.format.setBackground(pal.brush(QPalette::Highlight));
-      senderSel.start = 0; senderSel.length = senderFormatted.text.length();
-      senderFormat = calcFormatRanges(senderFormatted, senderSel);
+      senderSel.start = 0; senderSel.length = styledSender.text.length();
+      senderFormat = calcFormatRanges(styledSender, senderSel);
       textSel.format.setForeground(pal.brush(QPalette::HighlightedText));
       textSel.format.setBackground(pal.brush(QPalette::Highlight));
-      textSel.start = 0; textSel.length = textFormatted.text.length();
-      textFormat = calcFormatRanges(textFormatted, textSel);
+      textSel.start = 0; textSel.length = styledText.text.length();
+      textFormat = calcFormatRanges(styledText, textSel);
       break;
   }
 }
 
 uint ChatLine::msgId() const {
-  return msg.buffer.uid();
+  return msg.buffer().uid();
 }
 
-BufferId ChatLine::bufferId() const {
-  return msg.buffer;
+BufferInfo ChatLine::bufferInfo() const {
+  return msg.buffer();
 }
 
 QDateTime ChatLine::timeStamp() const {
-  return msg.timeStamp;
+  return msg.timeStamp();
 }
 
 QString ChatLine::sender() const {
-  return senderFormatted.text;
+  return styledSender.text;
 }
 
 QString ChatLine::text() const {
-  return textFormatted.text;
+  return styledText.text;
 }
 
 bool ChatLine::isUrl(int c) const {
@@ -199,7 +146,7 @@ bool ChatLine::isUrl(int c) const {
 QUrl ChatLine::getUrl(int c) const {
   if(c < 0 || c >= charUrlIdx.count()) return QUrl();
   int i = charUrlIdx[c];
-  if(i >= 0) return textFormatted.urls[i].url;
+  if(i >= 0) return styledText.urls[i].url;
   else return QUrl();
 }
 
@@ -227,20 +174,20 @@ int ChatLine::posToCursor(QPointF pos) {
 }
 
 void ChatLine::precomputeLine() {
-  tsFormat = calcFormatRanges(tsFormatted);
-  senderFormat = calcFormatRanges(senderFormatted);
-  textFormat = calcFormatRanges(textFormatted);
+  tsFormat = calcFormatRanges(styledTimeStamp);
+  senderFormat = calcFormatRanges(styledSender);
+  textFormat = calcFormatRanges(styledText);
 
   minHeight = 0;
   foreach(FormatRange fr, tsFormat) minHeight = qMax(minHeight, fr.height);
   foreach(FormatRange fr, senderFormat) minHeight = qMax(minHeight, fr.height);
 
   words.clear();
-  charPos.resize(textFormatted.text.length() + 1);
-  charHeights.resize(textFormatted.text.length());
-  charUrlIdx.fill(-1, textFormatted.text.length());
-  for(int i = 0; i < textFormatted.urls.count(); i++) {
-    Style::UrlInfo url = textFormatted.urls[i];
+  charPos.resize(styledText.text.length() + 1);
+  charHeights.resize(styledText.text.length());
+  charUrlIdx.fill(-1, styledText.text.length());
+  for(int i = 0; i < styledText.urls.count(); i++) {
+    Style::UrlInfo url = styledText.urls[i];
     for(int j = url.start; j < url.end; j++) charUrlIdx[j] = i;
   }
   if(!textFormat.count()) return;
@@ -248,10 +195,10 @@ void ChatLine::precomputeLine() {
   QFontMetrics metrics(textFormat[0].format.font());
   Word wr;
   wr.start = -1; wr.trailing = -1;
-  for(int i = 0; i < textFormatted.text.length(); ) {
+  for(int i = 0; i < styledText.text.length(); ) {
     charPos[i] = w; charHeights[i] = textFormat[idx].height;
-    w += metrics.charWidth(textFormatted.text, i);
-    if(!textFormatted.text[i].isSpace()) {
+    w += metrics.charWidth(styledText.text, i);
+    if(!styledText.text[i].isSpace()) {
       if(wr.trailing >= 0) {
         // new word after space
         words.append(wr);
@@ -269,13 +216,13 @@ void ChatLine::precomputeLine() {
         wr.trailing++;
       }
     }
-    if(++i < textFormatted.text.length() && ++cnt >= textFormat[idx].length) {
+    if(++i < styledText.text.length() && ++cnt >= textFormat[idx].length) {
       cnt = 0; idx++;
       Q_ASSERT(idx < textFormat.count());
       metrics = QFontMetrics(textFormat[idx].format.font());
     }
   }
-  charPos[textFormatted.text.length()] = w;
+  charPos[styledText.text.length()] = w;
   if(wr.start >= 0) words.append(wr);
 }
 
@@ -288,7 +235,7 @@ qreal ChatLine::layout(qreal tsw, qreal senderw, qreal textw) {
   line.y = 0;
   line.start = 0;
   line.height = minHeight;  // first line needs room for ts and sender
-  for(int i = 0; i < words.count(); i++) {
+  for(uint i = 0; i < (uint)words.count(); i++) {
     int lastpos = charPos[words[i].start + words[i].length]; // We use charPos[lastchar + 1], 'coz last char needs to fit
     if(lastpos - offset <= textw) {
       line.height = qMax(line.height, words[i].height);
@@ -371,14 +318,14 @@ void ChatLine::draw(QPainter *p, const QPointF &pos) {
   foreach(FormatRange fr, tsFormat) {
     p->setFont(fr.format.font());
     p->setPen(QPen(fr.format.foreground(), 0)); p->setBackground(fr.format.background());
-    p->drawText(rect, Qt::AlignLeft|Qt::TextSingleLine, tsFormatted.text.mid(fr.start, fr.length), &brect);
+    p->drawText(rect, Qt::AlignLeft|Qt::TextSingleLine, styledTimeStamp.text.mid(fr.start, fr.length), &brect);
     rect.setLeft(brect.right());
   }
   rect = QRectF(pos + QPointF(tsWidth + Style::sepTsSender(), 0), QSizeF(senderWidth, minHeight));
   for(int i = senderFormat.count() - 1; i >= 0; i--) {
     FormatRange fr = senderFormat[i];
     p->setFont(fr.format.font()); p->setPen(QPen(fr.format.foreground(), 0)); p->setBackground(fr.format.background());
-    p->drawText(rect, Qt::AlignRight|Qt::TextSingleLine, senderFormatted.text.mid(fr.start, fr.length), &brect);
+    p->drawText(rect, Qt::AlignRight|Qt::TextSingleLine, styledSender.text.mid(fr.start, fr.length), &brect);
     rect.setRight(brect.left());
   }
   QPointF tpos = pos + QPointF(tsWidth + Style::sepTsSender() + senderWidth + Style::sepSenderText(), 0);
@@ -395,7 +342,7 @@ void ChatLine::draw(QPainter *p, const QPointF &pos) {
       llend = lineLayouts[l].start + lineLayouts[l].length;
       start = qMax(fr.start, lineLayouts[l].start); end = qMin(frend, llend);
       rect.setLeft(tpos.x() + charPos[start] - offset);
-      p->drawText(rect, Qt::AlignLeft|Qt::TextSingleLine, textFormatted.text.mid(start, end - start), &brect);
+      p->drawText(rect, Qt::AlignLeft|Qt::TextSingleLine, styledText.text.mid(start, end - start), &brect);
       if(llend <= end) {
         h += lineLayouts[l].height;
         l++;