Adding work-in-progress for the new QGraphicsScene-based chatview.
authorManuel Nickschas <sputnick@quassel-irc.org>
Tue, 30 Oct 2007 23:17:59 +0000 (23:17 +0000)
committerManuel Nickschas <sputnick@quassel-irc.org>
Tue, 30 Oct 2007 23:17:59 +0000 (23:17 +0000)
Disabled for now, because it will require a lot of work and time I don't
have now. So we'll live with the old chatwidget (that does not display selections
anymore) until QuasselTopia is released...

29 files changed:
Quassel.kdevelop.filelist
src/client/buffer.h
src/client/quasselui.h
src/common/global.h
src/common/message.cpp
src/common/message.h
src/core/sqlitestorage.cpp
src/qtopia/chatline.cpp
src/qtopia/chatline.h
src/qtui/bufferwidget.cpp
src/qtui/bufferwidget.h
src/qtui/chatitem.cpp [new file with mode: 0644]
src/qtui/chatitem.h [new file with mode: 0644]
src/qtui/chatline-old.cpp [new file with mode: 0644]
src/qtui/chatline-old.h [new file with mode: 0644]
src/qtui/chatline.cpp
src/qtui/chatline.h
src/qtui/chatscene.cpp [new file with mode: 0644]
src/qtui/chatscene.h [new file with mode: 0644]
src/qtui/chatview.cpp [new file with mode: 0644]
src/qtui/chatview.h [new file with mode: 0644]
src/qtui/chatwidget.cpp
src/qtui/mainwin.cpp
src/qtui/qtui.pri
src/qtui/ui/bufferwidget.ui
src/uisupport/uistyle.cpp
src/uisupport/uistyle.h
templates/cpp
templates/h

index f534cf8..f9798c0 100644 (file)
@@ -469,8 +469,16 @@ src/qtui/bufferwidget.cpp
 src/qtui/bufferwidget.h
 src/qtui/channelwidgetinput.cpp
 src/qtui/channelwidgetinput.h
+src/qtui/chatitem.cpp
+src/qtui/chatitem.h
+src/qtui/chatline-old.cpp
+src/qtui/chatline-old.h
 src/qtui/chatline.cpp
 src/qtui/chatline.h
+src/qtui/chatscene.cpp
+src/qtui/chatscene.h
+src/qtui/chatview.cpp
+src/qtui/chatview.h
 src/qtui/chatwidget.cpp
 src/qtui/chatwidget.h
 src/qtui/coreconnectdlg.cpp
index 781a996..e862d5a 100644 (file)
@@ -61,8 +61,8 @@ public:
   BufferInfo bufferInfo() const;
   void updateBufferInfo(BufferInfo bufferid);
 
-  uint uid() const;
-  uint networkId() const;
+  BufferId uid() const;
+  NetworkId networkId() const;
   
   QString networkName() const;
   QString name() const;
index 327c37f..c4280ba 100644 (file)
@@ -32,7 +32,7 @@ class AbstractUiMsg {
     virtual QString text() const = 0;
     virtual MsgId msgId() const = 0;
     virtual BufferInfo bufferInfo() const = 0;
-    virtual QDateTime timeStamp() const = 0;
+    virtual QDateTime timestamp() const = 0;
 
 };
 
index fd285ca..6da6103 100644 (file)
@@ -38,6 +38,8 @@
 
 typedef uint UserId;
 typedef uint MsgId;
+typedef uint BufferId;
+typedef uint NetworkId;
 
 namespace Global {
   enum RunMode { Monolithic, ClientOnly, CoreOnly };
index 46ae484..fc4dfcc 100644 (file)
 
 Message::Message(BufferInfo __buffer, Type __type, QString __text, QString __sender, quint8 __flags)
   : _buffer(__buffer), _text(__text), _sender(__sender), _type(__type), _flags(__flags) {
-  _timeStamp = QDateTime::currentDateTime().toUTC();
+  _timestamp = QDateTime::currentDateTime().toUTC();
 }
 
 Message::Message(QDateTime __ts, BufferInfo __buffer, Type __type, QString __text, QString __sender, quint8 __flags)
-  : _timeStamp(__ts), _buffer(__buffer), _text(__text), _sender(__sender), _type(__type), _flags(__flags) {
+  : _timestamp(__ts), _buffer(__buffer), _text(__text), _sender(__sender), _type(__type), _flags(__flags) {
 
 }
 
@@ -62,8 +62,8 @@ quint8 Message::flags() const {
    return _flags;
 }
 
-QDateTime Message::timeStamp() const {
-  return _timeStamp;
+QDateTime Message::timestamp() const {
+  return _timestamp;
 }
 
 QString Message::mircToInternal(QString mirc) {
@@ -118,7 +118,7 @@ void Message::format() {
   QString networkName = buffer().network();
   QString bufferName = buffer().buffer();
 
-  _formattedTimeStamp = tr("%DT[%1]").arg(timeStamp().toLocalTime().toString("hh:mm:ss"));
+  _formattedTimestamp = tr("%DT[%1]").arg(timestamp().toLocalTime().toString("hh:mm:ss"));
 
   QString s, t;
   switch(type()) {
@@ -169,9 +169,9 @@ void Message::format() {
   _formattedText = t;
 }
 
-QString Message::formattedTimeStamp() {
+QString Message::formattedTimestamp() {
   format();
-  return _formattedTimeStamp;
+  return _formattedTimestamp;
 }
 
 QString Message::formattedSender() {
@@ -193,7 +193,7 @@ QString Message::formattedToHtml(const QString &f) {
 */
 
 QDataStream &operator<<(QDataStream &out, const Message &msg) {
-  out << (quint32)msg.timeStamp().toTime_t() << (quint8)msg.type() << (quint8)msg.flags()
+  out << (quint32)msg.timestamp().toTime_t() << (quint8)msg.type() << (quint8)msg.flags()
       << msg.buffer() << msg.sender().toUtf8() << msg.text().toUtf8();
   return out;
 }
@@ -207,7 +207,7 @@ QDataStream &operator>>(QDataStream &in, Message &msg) {
   msg._type = (Message::Type)t;
   msg._flags = (quint8)f;
   msg._buffer = buf;
-  msg._timeStamp = QDateTime::fromTime_t(ts);
+  msg._timestamp = QDateTime::fromTime_t(ts);
   msg._sender = QString::fromUtf8(s);
   msg._text = QString::fromUtf8(m);
   return in;
index 68047db..4374283 100644 (file)
@@ -48,9 +48,9 @@ class Message {
     QString sender() const;
     Type type() const;
     quint8 flags() const;
-    QDateTime timeStamp() const;
+    QDateTime timestamp() const;
 
-    QString formattedTimeStamp();
+    QString formattedTimestamp();
     QString formattedSender();
     QString formattedText();
 
@@ -59,7 +59,7 @@ class Message {
     void format();
 
   private:
-    QDateTime _timeStamp;
+    QDateTime _timestamp;
     MsgId _msgId;
     BufferInfo _buffer;
     QString _text;
@@ -67,7 +67,7 @@ class Message {
     Type _type;
     quint8 _flags;
 
-    QString _formattedTimeStamp, _formattedSender, _formattedText; // cache
+    QString _formattedTimestamp, _formattedSender, _formattedText; // cache
 
     /** Convert mIRC control codes to our own */
     QString mircToInternal(QString);
index 4e22c07..f148db9 100644 (file)
@@ -356,7 +356,7 @@ QList<BufferInfo> SqliteStorage::requestBuffers(UserId user, QDateTime since) {
 }
 
 MsgId SqliteStorage::logMessage(Message msg) {
-  logMessageQuery->bindValue(":time", msg.timeStamp().toTime_t());
+  logMessageQuery->bindValue(":time", msg.timestamp().toTime_t());
   logMessageQuery->bindValue(":bufferid", msg.buffer().uid());
   logMessageQuery->bindValue(":type", msg.type());
   logMessageQuery->bindValue(":flags", msg.flags());
@@ -376,7 +376,7 @@ MsgId SqliteStorage::logMessage(Message msg) {
     }
   }
 
-  getLastMessageIdQuery->bindValue(":time", msg.timeStamp().toTime_t());
+  getLastMessageIdQuery->bindValue(":time", msg.timestamp().toTime_t());
   getLastMessageIdQuery->bindValue(":bufferid", msg.buffer().uid());
   getLastMessageIdQuery->bindValue(":type", msg.type());
   getLastMessageIdQuery->bindValue(":sender", msg.sender());
@@ -385,7 +385,7 @@ MsgId SqliteStorage::logMessage(Message msg) {
   if(getLastMessageIdQuery->first()) {
     return getLastMessageIdQuery->value(0).toUInt();
   } else { // somethin went wrong... :(
-    qDebug() << getLastMessageIdQuery->lastQuery() << "time/bufferid/type/sender:" << msg.timeStamp().toTime_t() << msg.buffer().uid() << msg.type() << msg.sender();
+    qDebug() << getLastMessageIdQuery->lastQuery() << "time/bufferid/type/sender:" << msg.timestamp().toTime_t() << msg.buffer().uid() << msg.type() << msg.sender();
     Q_ASSERT(false);
     return 0;
   }
index 531fe28..52f3138 100644 (file)
 ChatLine::ChatLine(Message msg) {
   _text = msg.text();  // FIXME
   _sender = msg.sender();
-  _timeStamp = msg.timeStamp();
+  _timestamp = msg.timestamp();
   _msgId = msg.msgId();
   _bufferInfo = msg.buffer();
 
   _htmlSender = formattedToHtml(msg.formattedSender());
   _htmlText = formattedToHtml(msg.formattedText());
-  _htmlTimeStamp = formattedToHtml(msg.formattedTimeStamp());
+  _htmlTimestamp = formattedToHtml(msg.formattedTimestamp());
 }
 
 QString ChatLine::sender() const {
@@ -50,8 +50,8 @@ BufferInfo ChatLine::bufferInfo() const {
   return _bufferInfo;
 }
 
-QDateTime ChatLine::timeStamp() const {
-  return _timeStamp;
+QDateTime ChatLine::timestamp() const {
+  return _timestamp;
 }
 
 QString ChatLine::htmlSender() const {
@@ -62,8 +62,8 @@ QString ChatLine::htmlText() const {
   return _htmlText;
 }
 
-QString ChatLine::htmlTimeStamp() const {
-  return _htmlTimeStamp;
+QString ChatLine::htmlTimestamp() const {
+  return _htmlTimestamp;
 }
 
 
index c03f21a..0477da3 100644 (file)
@@ -31,17 +31,17 @@ class ChatLine : public AbstractUiMsg {
     QString text() const;
     MsgId msgId() const;
     BufferInfo bufferInfo() const;
-    QDateTime timeStamp() const;
+    QDateTime timestamp() const;
 
     QString htmlSender() const;
     QString htmlText() const;
-    QString htmlTimeStamp() const;
+    QString htmlTimestamp() const;
 
   private:
-    QString _sender, _text, _htmlSender, _htmlText, _htmlTimeStamp;
+    QString _sender, _text, _htmlSender, _htmlText, _htmlTimestamp;
     MsgId _msgId;
     BufferInfo _bufferInfo;
-    QDateTime _timeStamp;
+    QDateTime _timestamp;
 
     QString formattedToHtml(const QString &);
 
index 5448221..9bb2cab 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "bufferwidget.h"
 #include "buffer.h"
-#include "chatline.h"
+#include "chatline-old.h"
 #include "chatwidget.h"
 #include "settings.h"
 
@@ -30,18 +30,40 @@ BufferWidget::BufferWidget(QWidget *parent) : QWidget(parent) {
 }
 
 void BufferWidget::init() {
+
 }
 
 BufferWidget::~BufferWidget() {
+
 }
 
 void BufferWidget::setBuffer(Buffer *buf) {
+  /*
+  ChatView *chatView;
+  if(_chatViews.contains(buf->uid())) {
+    chatView = _chatViews[buf->uid()];
+  } else {
+    chatView = new ChatView(buf, this);
+    ui.stackedWidget->addWidget(chatView);
+    _chatViews[buf->uid()] = chatView;
+  }
+  ui.stackedWidget->setCurrentWidget(chatView);
+  disconnect(this, SIGNAL(userInput(QString)), 0, 0);
+  connect(this, SIGNAL(userInput(QString)), buf, SLOT(processUserInput(QString)));
+  //chatView->setFocusProxy(ui.inputEdit);
+  ui.inputEdit->setFocus();
+  ui.ownNick->clear();  // TODO add nick history
+}
+  */
+  
+  // ui.ownNick->addItem(state->ownNick);
+
   ChatWidget *chatWidget;
   if(_chatWidgets.contains(buf->uid())) {
      chatWidget = _chatWidgets[buf->uid()];
   } else {
     chatWidget = new ChatWidget(this);
-    chatWidget->init(networkName, bufferName);
+    chatWidget->init(buf->networkName(), buf->name());
     QList<ChatLine *> lines;
     QList<AbstractUiMsg *> msgs = buf->contents();
     foreach(AbstractUiMsg *msg, msgs) {
@@ -63,6 +85,7 @@ void BufferWidget::setBuffer(Buffer *buf) {
 }
 
 void BufferWidget::saveState() {
+
 }
 
 QSize BufferWidget::sizeHint() const {
index c3c7aa3..79786db 100644 (file)
 
 #include "ui_bufferwidget.h"
 
+#include "chatview.h"
 #include "global.h"
 
 class Buffer;
-struct BufferState;
+class ChatView;
 class ChatWidget;
 class LayoutThread;
 
-//!\brief Displays the contents of a Buffer.
-/** A BufferWidget usually includes a topic line, a nicklist, the chat itself, and an input line.
- * For server buffers or queries, there is of course no nicklist.
- * The contents of the chat is rendered by a ChatWidget.
- */
+//! Displays the contents of a Buffer.
+/**
+*/
 class BufferWidget : public QWidget {
   Q_OBJECT
 
@@ -48,23 +47,24 @@ public:
 signals:
   void userInput(QString msg);
   void aboutToClose();
-    
+
 public slots:
   void setBuffer(Buffer *);
   void saveState();
-                 
+
 private slots:
   void enterPressed();
   void setActive(bool act = true);
-  
-  
+
+
 private:
   Ui::BufferWidget ui;
-  QHash<uint, ChatWidget*> _chatWidgets;
+  //QHash<BufferId, ChatView*> _chatViews;
+  QHash<BufferId, ChatWidget *> _chatWidgets;
   bool active;
-  
-  QString networkName;
-  QString bufferName;
+
+  QString _networkName;
+  QString _bufferName;
 };
 
 
diff --git a/src/qtui/chatitem.cpp b/src/qtui/chatitem.cpp
new file mode 100644 (file)
index 0000000..08d9f11
--- /dev/null
@@ -0,0 +1,119 @@
+/***************************************************************************
+ *   Copyright (C) 2005-07 by the Quassel IRC Team                         *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include <QFontMetrics>
+#include <QGraphicsSceneMouseEvent>
+#include <QTextCursor>
+#include <QTextDocument>
+
+#include <QtGui>
+
+#include "chatitem.h"
+
+ChatItem::ChatItem(QGraphicsItem *parent) : QGraphicsItem(parent) {
+  _width = 0;
+  //if(_wrapMode == WordWrap) {
+  //  setFlags(QGraphicsItem::ItemClipsToShape, true);
+  //}
+}
+
+ChatItem::~ChatItem() {
+
+}
+
+void ChatItem::setWidth(int w) {
+  _width = w;
+  layout();
+}
+
+void ChatItem::setTextOption(const QTextOption &option) {
+  _textOption = option;
+  layout();
+}
+
+QTextOption ChatItem::textOption() const {
+  return _textOption;
+}
+
+QString ChatItem::text() const {
+  return _layout.text();
+}
+
+void ChatItem::setText(const UiStyle::StyledText &text) {
+  _layout.setText(text.text);
+  _layout.setAdditionalFormats(text.formats);
+  layout();
+}
+
+void ChatItem::layout() {
+  if(!_layout.additionalFormats().count()) return; // no text set
+  if(_width <= 0) return;
+  prepareGeometryChange();
+  QFontMetrics metrics(_layout.additionalFormats()[0].format.font());
+  int leading = metrics.leading();
+  int height = 0;
+  _layout.setTextOption(textOption());
+  _layout.beginLayout();
+  while(1) {
+    QTextLine line = _layout.createLine();
+    if(!line.isValid()) break;
+    line.setLineWidth(_width);
+    if(textOption().wrapMode() != QTextOption::NoWrap && line.naturalTextWidth() > _width) {
+      // word did not fit, we need to wrap it in the middle
+      // this is a workaround for Qt failing to handle WrapAtWordBoundaryOrAnywhere correctly
+      QTextOption::WrapMode mode = textOption().wrapMode();
+      textOption().setWrapMode(QTextOption::WrapAnywhere);
+      _layout.setTextOption(textOption());
+      line.setLineWidth(_width);
+      textOption().setWrapMode(mode);
+      _layout.setTextOption(textOption());
+    }
+    height += leading;
+    line.setPosition(QPoint(0, height));
+    height += line.height();
+  }
+  _layout.endLayout();
+  update();
+}
+
+QRectF ChatItem::boundingRect() const {
+  return _layout.boundingRect();
+}
+
+void ChatItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
+  Q_UNUSED(option); Q_UNUSED(widget);
+  _layout.draw(painter, QPointF(0, 0));
+
+}
+
+/*
+void ChatItem::mouseMoveEvent ( QGraphicsSceneMouseEvent * event ) {
+  qDebug() << (void*)this << "moving" << event->pos();
+  if(event->pos().y() < 0) {
+    QTextCursor cursor(document());
+    //cursor.insertText("foo");
+    //cursor.select(QTextCursor::Document);
+    event->ignore();
+  } else QGraphicsTextItem::mouseMoveEvent(event);
+}
+*/
+
+
+
diff --git a/src/qtui/chatitem.h b/src/qtui/chatitem.h
new file mode 100644 (file)
index 0000000..4ffb944
--- /dev/null
@@ -0,0 +1,59 @@
+/***************************************************************************
+ *   Copyright (C) 2005-07 by the Quassel IRC Team                         *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifndef _CHATITEM_H_
+#define _CHATITEM_H_
+
+#include <QGraphicsItem>
+#include <QTextLayout>
+#include <QTextOption>
+
+#include "uistyle.h"
+
+class QGraphicsSceneMouseEvent;
+
+class ChatItem : public QGraphicsItem {
+
+  public:
+    ChatItem(QGraphicsItem *parent = 0);
+    virtual ~ChatItem();
+
+    virtual QRectF boundingRect() const;
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    QString text() const;
+    void setText(const UiStyle::StyledText &text);
+
+    QTextOption textOption() const;
+    void setTextOption(const QTextOption &option);
+
+    void setWidth(int width);
+    virtual void layout();
+
+  protected:
+    //void mouseMoveEvent ( QGraphicsSceneMouseEvent * event );
+
+  private:
+    int _width;
+    QTextLayout _layout;
+    QTextOption _textOption;
+};
+
+#endif
diff --git a/src/qtui/chatline-old.cpp b/src/qtui/chatline-old.cpp
new file mode 100644 (file)
index 0000000..32d4656
--- /dev/null
@@ -0,0 +1,373 @@
+/***************************************************************************
+ *   Copyright (C) 2005-07 by The Quassel IRC Development Team             *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include "chatline-old.h"
+#include "qtui.h"
+
+//!\brief Construct a ChatLine object from a message.
+/**
+ * \param m   The message to be layouted and rendered
+ * \param net The network name
+ * \param buf The buffer name
+ */
+ChatLine::ChatLine(Message m) {
+  hght = 0;
+  //networkName = m.buffer.network();
+  //bufferName = m.buffer.buffer();
+  msg = m;
+  selectionMode = None;
+  formatMsg(msg);
+}
+
+ChatLine::~ChatLine() {
+
+}
+
+void ChatLine::formatMsg(Message msg) {
+  QTextOption tsOption, senderOption, textOption;
+  styledTimeStamp = QtUi::style()->styleString(msg.formattedTimestamp());
+  styledSender = QtUi::style()->styleString(msg.formattedSender());
+  styledText = QtUi::style()->styleString(msg.formattedText());
+  precomputeLine();
+}
+
+// This function is almost obsolete, since with the new style engine, we already get a list of formats...
+// We don't know yet if we keep this implementation of ChatLine, so I won't bother making this actually nice.
+// Also, the additional format is ignored for now, which means that you won't see a selection...
+// FIXME TODO
+QList<ChatLine::FormatRange> ChatLine::calcFormatRanges(const UiStyle::StyledText &fs, QTextLayout::FormatRange additional) {
+  QList<FormatRange> ranges;
+
+  foreach(QTextLayout::FormatRange f, fs.formats) {
+    FormatRange range;
+    range.start = f.start;
+    range.length = f.length;
+    range.format = f.format;
+    QFontMetrics metrics(range.format.font());
+    range.height = metrics.lineSpacing();
+    ranges.append(range);
+  }
+  /*
+  QList<QTextLayout::FormatRange> formats = fs.formats;
+  formats.append(additional);
+  int cur = -1;
+  FormatRange range, lastrange;
+  for(int i = 0; i < fs.text.length(); i++) {
+    QTextCharFormat format;
+    foreach(QTextLayout::FormatRange f, formats) {
+      if(i >= f.start && i < f.start + f.length) format.merge(f.format);
+    }
+    if(cur < 0) {
+      range.start = 0; range.length = 1; range.format= format;
+      cur = 0;
+    } else {
+      if(format == range.format) range.length++;
+      else {
+        QFontMetrics metrics(range.format.font());
+        range.height = metrics.lineSpacing();
+        ranges.append(range);
+        range.start = i; range.length = 1; range.format = format;
+        cur++;
+      }
+    }
+  }
+  if(cur >= 0) {
+    QFontMetrics metrics(range.format.font());
+    range.height = metrics.lineSpacing();
+    ranges.append(range);
+  }
+  */
+  return ranges;
+}
+
+void ChatLine::setSelection(SelectionMode mode, int start, int end) {
+  selectionMode = mode;
+  //tsFormat.clear(); senderFormat.clear(); textFormat.clear();
+  QPalette pal = QApplication::palette();
+  QTextLayout::FormatRange tsSel, senderSel, textSel;
+  switch (mode) {
+    case None:
+      tsFormat = calcFormatRanges(styledTimeStamp);
+      senderFormat = calcFormatRanges(styledSender);
+      textFormat = calcFormatRanges(styledText);
+      break;
+    case Partial:
+      selectionStart = qMin(start, end); selectionEnd = qMax(start, end);
+      textSel.format.setForeground(pal.brush(QPalette::HighlightedText));
+      textSel.format.setBackground(pal.brush(QPalette::Highlight));
+      textSel.start = selectionStart;
+      textSel.length = selectionEnd - selectionStart;
+      //textFormat.append(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 = 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 = 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 = styledText.text.length();
+      textFormat = calcFormatRanges(styledText, textSel);
+      break;
+  }
+}
+
+uint ChatLine::msgId() const {
+  return msg.buffer().uid();
+}
+
+BufferInfo ChatLine::bufferInfo() const {
+  return msg.buffer();
+}
+
+QDateTime ChatLine::timestamp() const {
+  return msg.timestamp();
+}
+
+QString ChatLine::sender() const {
+  return styledSender.text;
+}
+
+QString ChatLine::text() const {
+  return styledText.text;
+}
+
+bool ChatLine::isUrl(int c) const {
+  if(c < 0 || c >= charUrlIdx.count()) return false;;
+  return charUrlIdx[c] >= 0;
+}
+
+QUrl ChatLine::getUrl(int c) const {
+  if(c < 0 || c >= charUrlIdx.count()) return QUrl();
+  int i = charUrlIdx[c];
+  if(i >= 0) return styledText.urls[i].url;
+  else return QUrl();
+}
+
+//!\brief Return the cursor position for the given coordinate pos.
+/**
+ * \param pos The position relative to the ChatLine
+ * \return The cursor position, [or -3 for invalid,] or -2 for timestamp, or -1 for sender
+ */
+int ChatLine::posToCursor(QPointF pos) {
+  if(pos.x() < tsWidth + (int)QtUi::style()->sepTsSender()/2) return -2;
+  qreal textStart = tsWidth + QtUi::style()->sepTsSender() + senderWidth + QtUi::style()->sepSenderText();
+  if(pos.x() < textStart) return -1;
+  int x = (int)(pos.x() - textStart);
+  for(int l = lineLayouts.count() - 1; l >=0; l--) {
+    LineLayout line = lineLayouts[l];
+    if(pos.y() >= line.y) {
+      int offset = charPos[line.start]; x += offset;
+      for(int i = line.start + line.length - 1; i >= line.start; i--) {
+        if((charPos[i] + charPos[i+1])/2 <= x) return i+1; // FIXME: Optimize this!
+      }
+      return line.start;
+    }
+  }
+  return 0;
+}
+
+void ChatLine::precomputeLine() {
+  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(styledText.text.length() + 1);
+  charHeights.resize(styledText.text.length());
+  charUrlIdx.fill(-1, styledText.text.length());
+  for(int i = 0; i < styledText.urls.count(); i++) {
+    QtUiStyle::UrlInfo url = styledText.urls[i];
+    for(int j = url.start; j < url.end; j++) charUrlIdx[j] = i;
+  }
+  if(!textFormat.count()) return;
+  int idx = 0; int cnt = 0; int w = 0;
+  QFontMetrics metrics(textFormat[0].format.font());
+  Word wr;
+  wr.start = -1; wr.trailing = -1;
+  for(int i = 0; i < styledText.text.length(); ) {
+    charPos[i] = w; charHeights[i] = textFormat[idx].height;
+    w += metrics.charWidth(styledText.text, i);
+    if(!styledText.text[i].isSpace()) {
+      if(wr.trailing >= 0) {
+        // new word after space
+        words.append(wr);
+        wr.start = -1;
+      }
+      if(wr.start < 0) {
+        wr.start = i; wr.length = 1; wr.trailing = -1; wr.height = textFormat[idx].height;
+      } else {
+        wr.length++; wr.height = qMax(wr.height, textFormat[idx].height);
+      }
+    } else {
+      if(wr.start < 0) {
+        wr.start = i; wr.length = 0; wr.trailing = 1; wr.height = 0;
+      } else {
+        wr.trailing++;
+      }
+    }
+    if(++i < styledText.text.length() && ++cnt >= textFormat[idx].length) {
+      cnt = 0; idx++;
+      Q_ASSERT(idx < textFormat.count());
+      metrics = QFontMetrics(textFormat[idx].format.font());
+    }
+  }
+  charPos[styledText.text.length()] = w;
+  if(wr.start >= 0) words.append(wr);
+}
+
+qreal ChatLine::layout(qreal tsw, qreal senderw, qreal textw) {
+  tsWidth = tsw; senderWidth = senderw; textWidth = textw;
+  if(textw <= 0) return minHeight;
+  lineLayouts.clear(); LineLayout line;
+  int h = 0;
+  int offset = 0; int numWords = 0;
+  line.y = 0;
+  line.start = 0;
+  line.height = minHeight;  // first line needs room for ts and sender
+  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);
+      line.length = words[i].start + words[i].length - line.start;
+      numWords++;
+    } else {
+      // we need to wrap!
+      if(numWords > 0) {
+        // ok, we had some words before, so store the layout and start a new line
+        h += line.height;
+        line.length = words[i-1].start + words[i-1].length - line.start;
+        lineLayouts.append(line);
+        line.y += line.height;
+        line.start = words[i].start;
+        line.height = words[i].height;
+        offset = charPos[words[i].start];
+      }
+      numWords = 1;
+      // check if the word fits into the current line
+      if(lastpos - offset <= textw) {
+        line.length = words[i].length;
+      } else {
+        // we need to break a word in the middle
+        int border = (int)textw + offset; // save some additions
+        line.start = words[i].start;
+        line.length = 1;
+        line.height = charHeights[line.start];
+        int j = line.start + 1;
+        for(int l = 1; l < words[i].length; j++, l++) {
+          if(charPos[j+1] < border) {
+            line.length++;
+            line.height = qMax(line.height, charHeights[j]);
+            continue;
+          } else {
+            h += line.height;
+            lineLayouts.append(line);
+            line.y += line.height;
+            line.start = j;
+            line.height = charHeights[j];
+            line.length = 1;
+            offset = charPos[j];
+            border = (int)textw + offset;
+          }
+        }
+      }
+    }
+  }
+  h += line.height;
+  if(numWords > 0) {
+    lineLayouts.append(line);
+  }
+  hght = h;
+  return hght;
+}
+
+//!\brief Draw ChatLine on the given QPainter at the given position.
+void ChatLine::draw(QPainter *p, const QPointF &pos) {
+  QPalette pal = QApplication::palette();
+
+  if(selectionMode == Full) {
+    p->setPen(Qt::NoPen);
+    p->setBrush(pal.brush(QPalette::Highlight));
+    p->drawRect(QRectF(pos, QSizeF(tsWidth + QtUi::style()->sepTsSender() + senderWidth + QtUi::style()->sepSenderText() + textWidth, height())));
+  } else if(selectionMode == Partial) {
+
+  } /*
+  p->setClipRect(QRectF(pos, QSizeF(tsWidth, height())));
+  tsLayout.draw(p, pos, tsFormat);
+  p->setClipRect(QRectF(pos + QPointF(tsWidth + Style::sepTsSender(), 0), QSizeF(senderWidth, height())));
+  senderLayout.draw(p, pos + QPointF(tsWidth + Style::sepTsSender(), 0), senderFormat);
+  p->setClipping(false);
+  textLayout.draw(p, pos + QPointF(tsWidth + Style::sepTsSender() + senderWidth + Style::sepSenderText(), 0), textFormat);
+    */
+  //p->setClipRect(QRectF(pos, QSizeF(tsWidth, 15)));
+  //p->drawRect(QRectF(pos, QSizeF(tsWidth, minHeight)));
+  p->setBackgroundMode(Qt::OpaqueMode);
+  QPointF tp = pos;
+  QRectF rect(pos, QSizeF(tsWidth, minHeight));
+  QRectF brect;
+  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, styledTimeStamp.text.mid(fr.start, fr.length), &brect);
+    rect.setLeft(brect.right());
+  }
+  rect = QRectF(pos + QPointF(tsWidth + QtUi::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, styledSender.text.mid(fr.start, fr.length), &brect);
+    rect.setRight(brect.left());
+  }
+  QPointF tpos = pos + QPointF(tsWidth + QtUi::style()->sepTsSender() + senderWidth + QtUi::style()->sepSenderText(), 0);
+  qreal h = 0; int l = 0;
+  rect = QRectF(tpos + QPointF(0, h), QSizeF(textWidth, lineLayouts[l].height));
+  int offset = 0;
+  foreach(FormatRange fr, textFormat) {
+    if(l >= lineLayouts.count()) break;
+    p->setFont(fr.format.font()); p->setPen(QPen(fr.format.foreground(), 0)); p->setBackground(fr.format.background());
+    int start, end, frend, llend;
+    do {
+      frend = fr.start + fr.length;
+      if(frend <= lineLayouts[l].start) break;
+      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, styledText.text.mid(start, end - start), &brect);
+      if(llend <= end) {
+        h += lineLayouts[l].height;
+        l++;
+        if(l < lineLayouts.count()) {
+          rect = QRectF(tpos + QPointF(0, h), QSizeF(textWidth, lineLayouts[l].height));
+          offset = charPos[lineLayouts[l].start];
+        }
+      }
+    } while(end < frend && l < lineLayouts.count());
+  }
+}
diff --git a/src/qtui/chatline-old.h b/src/qtui/chatline-old.h
new file mode 100644 (file)
index 0000000..5b5bffc
--- /dev/null
@@ -0,0 +1,109 @@
+/***************************************************************************
+ *   Copyright (C) 2005-07 by The Quassel IRC Development Team             *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifndef _CHATLINE_H_
+#define _CHATLINE_H_
+
+#include <QtGui>
+
+#include "util.h"
+#include "uistyle.h"
+#include "quasselui.h"
+
+//FIXME: chatline doku
+//!\brief Containing the layout and providing the rendering of a single message.
+/** A ChatLine takes a Message object,
+ * formats it (by turning the various message types into a human-readable form and afterwards pumping it through
+ * our Style engine), and stores it as a number of QTextLayouts representing the three fields of a chat line
+ * (timestamp, sender and text). These layouts already include any rendering information such as font,
+ * color, or selected characters. By calling layout(), they can be quickly layouted to fit a given set of field widths.
+ * Afterwards, they can quickly be painted whenever necessary.
+ *
+ * By separating the complex and slow task of interpreting and formatting Message objects (which happens exactly once
+ * per message) from the actual layouting and painting, we gain a lot of speed compared to the standard Qt rendering
+ * functions.
+ */
+class ChatLine : public QObject, public AbstractUiMsg {
+  Q_OBJECT
+
+  public:
+    ChatLine(Message message);
+    virtual ~ChatLine();
+
+    qreal layout(qreal tsWidth, qreal nickWidth, qreal textWidth);
+    qreal height() const { return hght; }
+    int posToCursor(QPointF pos);
+    void draw(QPainter *p, const QPointF &pos);
+
+    enum SelectionMode { None, Partial, Full };
+    void setSelection(SelectionMode, int start = 0, int end = 0);
+
+    QDateTime timestamp() const;
+    QString sender() const;
+    QString text() const;
+    MsgId msgId() const;
+    BufferInfo bufferInfo() const;
+
+    bool isUrl(int pos) const;
+    QUrl getUrl(int pos) const;
+
+  public slots:
+
+  private:
+    qreal hght;
+    Message msg;
+    qreal tsWidth, senderWidth, textWidth;
+    UiStyle::StyledText styledTimeStamp, styledSender, styledText;
+
+    struct FormatRange {
+      int start;
+      int length;
+      int height;
+      QTextCharFormat format;
+    };
+    struct Word {
+      int start;
+      int length;
+      int trailing;
+      int height;
+    };
+    struct LineLayout {
+      int y;
+      int height;
+      int start;
+      int length;
+    };
+    QVector<int> charPos;
+    QVector<int> charWidths;
+    QVector<int> charHeights;
+    QVector<int> charUrlIdx;
+    QList<FormatRange> tsFormat, senderFormat, textFormat;
+    QList<Word> words;
+    QList<LineLayout> lineLayouts;
+    int minHeight;
+
+    SelectionMode selectionMode;
+    int selectionStart, selectionEnd;
+    void formatMsg(Message);
+    void precomputeLine();
+    QList<FormatRange> calcFormatRanges(const UiStyle::StyledText &, QTextLayout::FormatRange additional = QTextLayout::FormatRange());
+};
+
+#endif
index f3b4a35..7121c21 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2005-07 by The Quassel IRC Development Team             *
+ *   Copyright (C) 2005-07 by the Quassel IRC Team                         *
  *   devel@quassel-irc.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
+#include <QDateTime>
+#include <QString>
+#include <QtGui>
+
+#include "bufferinfo.h"
+#include "chatitem.h"
 #include "chatline.h"
 #include "qtui.h"
 
-//!\brief Construct a ChatLine object from a message.
-/**
- * \param m   The message to be layouted and rendered
- * \param net The network name
- * \param buf The buffer name
- */
-ChatLine::ChatLine(Message m) {
-  hght = 0;
-  //networkName = m.buffer.network();
-  //bufferName = m.buffer.buffer();
-  msg = m;
-  selectionMode = None;
-  formatMsg(msg);
-}
-
-ChatLine::~ChatLine() {
-
-}
-
-void ChatLine::formatMsg(Message msg) {
-  QTextOption tsOption, senderOption, textOption;
-  styledTimeStamp = QtUi::style()->styleString(msg.formattedTimeStamp());
-  styledSender = QtUi::style()->styleString(msg.formattedSender());
-  styledText = QtUi::style()->styleString(msg.formattedText());
-  precomputeLine();
-}
-
-// This function is almost obsolete, since with the new style engine, we already get a list of formats...
-// We don't know yet if we keep this implementation of ChatLine, so I won't bother making this actually nice.
-// Also, the additional format is ignored for now, which means that you won't see a selection...
-// FIXME TODO
-QList<ChatLine::FormatRange> ChatLine::calcFormatRanges(const UiStyle::StyledString &fs, QTextLayout::FormatRange additional) {
-  QList<FormatRange> ranges;
+ChatLine::ChatLine(Message msg) : QGraphicsItem(), AbstractUiMsg() {
+  _styledTimestamp = QtUi::style()->styleString(msg.formattedTimestamp());
+  _styledSender = QtUi::style()->styleString(msg.formattedSender());
+  _styledText = QtUi::style()->styleString(msg.formattedText());
+  _msgId = msg.msgId();
+  _timestamp = msg.timestamp();
 
-  foreach(QTextLayout::FormatRange f, fs.formats) {
-    FormatRange range;
-    range.start = f.start;
-    range.length = f.length;
-    range.format = f.format;
-    QFontMetrics metrics(range.format.font());
-    range.height = metrics.lineSpacing();
-    ranges.append(range);
-  }
-  /*
-  QList<QTextLayout::FormatRange> formats = fs.formats;
-  formats.append(additional);
-  int cur = -1;
-  FormatRange range, lastrange;
-  for(int i = 0; i < fs.text.length(); i++) {
-    QTextCharFormat format;
-    foreach(QTextLayout::FormatRange f, formats) {
-      if(i >= f.start && i < f.start + f.length) format.merge(f.format);
-    }
-    if(cur < 0) {
-      range.start = 0; range.length = 1; range.format= format;
-      cur = 0;
-    } else {
-      if(format == range.format) range.length++;
-      else {
-        QFontMetrics metrics(range.format.font());
-        range.height = metrics.lineSpacing();
-        ranges.append(range);
-        range.start = i; range.length = 1; range.format = format;
-        cur++;
-      }
-    }
-  }
-  if(cur >= 0) {
-    QFontMetrics metrics(range.format.font());
-    range.height = metrics.lineSpacing();
-    ranges.append(range);
-  }
-  */
-  return ranges;
-}
+  _tsColWidth = _senderColWidth = _textColWidth = 0;
+  QTextOption option;
+  option.setWrapMode(QTextOption::NoWrap);
+  _tsItem = new ChatItem(this);
+  _tsItem->setTextOption(option);
+  _tsItem->setText(_styledTimestamp);
 
-void ChatLine::setSelection(SelectionMode mode, int start, int end) {
-  selectionMode = mode;
-  //tsFormat.clear(); senderFormat.clear(); textFormat.clear();
-  QPalette pal = QApplication::palette();
-  QTextLayout::FormatRange tsSel, senderSel, textSel;
-  switch (mode) {
-    case None:
-      tsFormat = calcFormatRanges(styledTimeStamp);
-      senderFormat = calcFormatRanges(styledSender);
-      textFormat = calcFormatRanges(styledText);
-      break;
-    case Partial:
-      selectionStart = qMin(start, end); selectionEnd = qMax(start, end);
-      textSel.format.setForeground(pal.brush(QPalette::HighlightedText));
-      textSel.format.setBackground(pal.brush(QPalette::Highlight));
-      textSel.start = selectionStart;
-      textSel.length = selectionEnd - selectionStart;
-      //textFormat.append(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 = 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 = 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 = styledText.text.length();
-      textFormat = calcFormatRanges(styledText, textSel);
-      break;
-  }
-}
+  option.setAlignment(Qt::AlignRight);
+  _senderItem = new ChatItem(this);
+  _senderItem->setTextOption(option);
+  _senderItem->setText(_styledSender);
 
-uint ChatLine::msgId() const {
-  return msg.buffer().uid();
-}
+  option.setAlignment(Qt::AlignLeft);
+  option.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
+  _textItem = new ChatItem(this);
+  _textItem->setTextOption(option);
+  _textItem->setText(_styledText);
 
-BufferInfo ChatLine::bufferInfo() const {
-  return msg.buffer();
 }
 
-QDateTime ChatLine::timeStamp() const {
-  return msg.timeStamp();
+ChatLine::~ChatLine() {
+  
 }
 
 QString ChatLine::sender() const {
-  return styledSender.text;
+  return QString();
 }
 
 QString ChatLine::text() const {
-  return styledText.text;
+  return QString();
 }
 
-bool ChatLine::isUrl(int c) const {
-  if(c < 0 || c >= charUrlIdx.count()) return false;;
-  return charUrlIdx[c] >= 0;
+MsgId ChatLine::msgId() const {
+  return 0;
 }
 
-QUrl ChatLine::getUrl(int c) const {
-  if(c < 0 || c >= charUrlIdx.count()) return QUrl();
-  int i = charUrlIdx[c];
-  if(i >= 0) return styledText.urls[i].url;
-  else return QUrl();
+BufferInfo ChatLine::bufferInfo() const {
+  Q_ASSERT(false); // do we actually need this function???
+  return BufferInfo();
 }
 
-//!\brief Return the cursor position for the given coordinate pos.
-/**
- * \param pos The position relative to the ChatLine
- * \return The cursor position, [or -3 for invalid,] or -2 for timestamp, or -1 for sender
- */
-int ChatLine::posToCursor(QPointF pos) {
-  if(pos.x() < tsWidth + (int)QtUi::style()->sepTsSender()/2) return -2;
-  qreal textStart = tsWidth + QtUi::style()->sepTsSender() + senderWidth + QtUi::style()->sepSenderText();
-  if(pos.x() < textStart) return -1;
-  int x = (int)(pos.x() - textStart);
-  for(int l = lineLayouts.count() - 1; l >=0; l--) {
-    LineLayout line = lineLayouts[l];
-    if(pos.y() >= line.y) {
-      int offset = charPos[line.start]; x += offset;
-      for(int i = line.start + line.length - 1; i >= line.start; i--) {
-        if((charPos[i] + charPos[i+1])/2 <= x) return i+1; // FIXME: Optimize this!
-      }
-      return line.start;
-    }
-  }
-  return 0;
+QDateTime ChatLine::timestamp() const {
+  return QDateTime();
 }
 
-void ChatLine::precomputeLine() {
-  tsFormat = calcFormatRanges(styledTimeStamp);
-  senderFormat = calcFormatRanges(styledSender);
-  textFormat = calcFormatRanges(styledText);
+QRectF ChatLine::boundingRect () const {
+  return childrenBoundingRect();
+}
 
-  minHeight = 0;
-  foreach(FormatRange fr, tsFormat) minHeight = qMax(minHeight, fr.height);
-  foreach(FormatRange fr, senderFormat) minHeight = qMax(minHeight, fr.height);
+void ChatLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
 
-  words.clear();
-  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++) {
-    QtUiStyle::UrlInfo url = styledText.urls[i];
-    for(int j = url.start; j < url.end; j++) charUrlIdx[j] = i;
-  }
-  if(!textFormat.count()) return;
-  int idx = 0; int cnt = 0; int w = 0;
-  QFontMetrics metrics(textFormat[0].format.font());
-  Word wr;
-  wr.start = -1; wr.trailing = -1;
-  for(int i = 0; i < styledText.text.length(); ) {
-    charPos[i] = w; charHeights[i] = textFormat[idx].height;
-    w += metrics.charWidth(styledText.text, i);
-    if(!styledText.text[i].isSpace()) {
-      if(wr.trailing >= 0) {
-        // new word after space
-        words.append(wr);
-        wr.start = -1;
-      }
-      if(wr.start < 0) {
-        wr.start = i; wr.length = 1; wr.trailing = -1; wr.height = textFormat[idx].height;
-      } else {
-        wr.length++; wr.height = qMax(wr.height, textFormat[idx].height);
-      }
-    } else {
-      if(wr.start < 0) {
-        wr.start = i; wr.length = 0; wr.trailing = 1; wr.height = 0;
-      } else {
-        wr.trailing++;
-      }
-    }
-    if(++i < styledText.text.length() && ++cnt >= textFormat[idx].length) {
-      cnt = 0; idx++;
-      Q_ASSERT(idx < textFormat.count());
-      metrics = QFontMetrics(textFormat[idx].format.font());
-    }
-  }
-  charPos[styledText.text.length()] = w;
-  if(wr.start >= 0) words.append(wr);
 }
 
-qreal ChatLine::layout(qreal tsw, qreal senderw, qreal textw) {
-  tsWidth = tsw; senderWidth = senderw; textWidth = textw;
-  if(textw <= 0) return minHeight;
-  lineLayouts.clear(); LineLayout line;
-  int h = 0;
-  int offset = 0; int numWords = 0;
-  line.y = 0;
-  line.start = 0;
-  line.height = minHeight;  // first line needs room for ts and sender
-  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);
-      line.length = words[i].start + words[i].length - line.start;
-      numWords++;
-    } else {
-      // we need to wrap!
-      if(numWords > 0) {
-        // ok, we had some words before, so store the layout and start a new line
-        h += line.height;
-        line.length = words[i-1].start + words[i-1].length - line.start;
-        lineLayouts.append(line);
-        line.y += line.height;
-        line.start = words[i].start;
-        line.height = words[i].height;
-        offset = charPos[words[i].start];
-      }
-      numWords = 1;
-      // check if the word fits into the current line
-      if(lastpos - offset <= textw) {
-        line.length = words[i].length;
-      } else {
-        // we need to break a word in the middle
-        int border = (int)textw + offset; // save some additions
-        line.start = words[i].start;
-        line.length = 1;
-        line.height = charHeights[line.start];
-        int j = line.start + 1;
-        for(int l = 1; l < words[i].length; j++, l++) {
-          if(charPos[j+1] < border) {
-            line.length++;
-            line.height = qMax(line.height, charHeights[j]);
-            continue;
-          } else {
-            h += line.height;
-            lineLayouts.append(line);
-            line.y += line.height;
-            line.start = j;
-            line.height = charHeights[j];
-            line.length = 1;
-            offset = charPos[j];
-            border = (int)textw + offset;
-          }
-        }
-      }
-    }
+void ChatLine::setColumnWidths(int tsColWidth, int senderColWidth, int textColWidth) {
+  if(tsColWidth >= 0) {
+    _tsColWidth = tsColWidth;
+    _tsItem->setWidth(tsColWidth);
+  }
+  if(senderColWidth >= 0) {
+    _senderColWidth = senderColWidth;
+    _senderItem->setWidth(senderColWidth);
   }
-  h += line.height;
-  if(numWords > 0) {
-    lineLayouts.append(line);
+  if(textColWidth >= 0) {
+    _textColWidth = textColWidth;
+    _textItem->setWidth(textColWidth);
   }
-  hght = h;
-  return hght;
+  layout();
 }
 
-//!\brief Draw ChatLine on the given QPainter at the given position.
-void ChatLine::draw(QPainter *p, const QPointF &pos) {
-  QPalette pal = QApplication::palette();
+void ChatLine::layout() {
+  prepareGeometryChange();
+  _tsItem->setPos(QPointF(0, 0));
+  _senderItem->setPos(QPointF(_tsColWidth + QtUi::style()->sepTsSender(), 0));
+  _textItem->setPos(QPointF(_tsColWidth + QtUi::style()->sepTsSender() + _senderColWidth + QtUi::style()->sepSenderText(), 0));
+}
 
-  if(selectionMode == Full) {
-    p->setPen(Qt::NoPen);
-    p->setBrush(pal.brush(QPalette::Highlight));
-    p->drawRect(QRectF(pos, QSizeF(tsWidth + QtUi::style()->sepTsSender() + senderWidth + QtUi::style()->sepSenderText() + textWidth, height())));
-  } else if(selectionMode == Partial) {
 
-  } /*
-  p->setClipRect(QRectF(pos, QSizeF(tsWidth, height())));
-  tsLayout.draw(p, pos, tsFormat);
-  p->setClipRect(QRectF(pos + QPointF(tsWidth + Style::sepTsSender(), 0), QSizeF(senderWidth, height())));
-  senderLayout.draw(p, pos + QPointF(tsWidth + Style::sepTsSender(), 0), senderFormat);
-  p->setClipping(false);
-  textLayout.draw(p, pos + QPointF(tsWidth + Style::sepTsSender() + senderWidth + Style::sepSenderText(), 0), textFormat);
-    */
-  //p->setClipRect(QRectF(pos, QSizeF(tsWidth, 15)));
-  //p->drawRect(QRectF(pos, QSizeF(tsWidth, minHeight)));
-  p->setBackgroundMode(Qt::OpaqueMode);
-  QPointF tp = pos;
-  QRectF rect(pos, QSizeF(tsWidth, minHeight));
-  QRectF brect;
-  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, styledTimeStamp.text.mid(fr.start, fr.length), &brect);
-    rect.setLeft(brect.right());
-  }
-  rect = QRectF(pos + QPointF(tsWidth + QtUi::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, styledSender.text.mid(fr.start, fr.length), &brect);
-    rect.setRight(brect.left());
-  }
-  QPointF tpos = pos + QPointF(tsWidth + QtUi::style()->sepTsSender() + senderWidth + QtUi::style()->sepSenderText(), 0);
-  qreal h = 0; int l = 0;
-  rect = QRectF(tpos + QPointF(0, h), QSizeF(textWidth, lineLayouts[l].height));
-  int offset = 0;
-  foreach(FormatRange fr, textFormat) {
-    if(l >= lineLayouts.count()) break;
-    p->setFont(fr.format.font()); p->setPen(QPen(fr.format.foreground(), 0)); p->setBackground(fr.format.background());
-    int start, end, frend, llend;
-    do {
-      frend = fr.start + fr.length;
-      if(frend <= lineLayouts[l].start) break;
-      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, styledText.text.mid(start, end - start), &brect);
-      if(llend <= end) {
-        h += lineLayouts[l].height;
-        l++;
-        if(l < lineLayouts.count()) {
-          rect = QRectF(tpos + QPointF(0, h), QSizeF(textWidth, lineLayouts[l].height));
-          offset = charPos[lineLayouts[l].start];
-        }
-      }
-    } while(end < frend && l < lineLayouts.count());
-  }
+bool ChatLine::sceneEvent ( QEvent * event ) {
+  qDebug() <<(void*)this<< "receiving event";
+  event->ignore();
+  return false;
 }
+
+
index be84f24..cd3e4ae 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2005-07 by The Quassel IRC Development Team             *
+ *   Copyright (C) 2005-07 by the Quassel IRC Team                         *
  *   devel@quassel-irc.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
 #ifndef _CHATLINE_H_
 #define _CHATLINE_H_
 
-#include <QtGui>
+#include <QGraphicsItem>
 
-#include "util.h"
-#include "uistyle.h"
+#include "message.h"
 #include "quasselui.h"
+#include "uistyle.h"
+
+class ChatItem;
 
-//FIXME: chatline doku
-//!\brief Containing the layout and providing the rendering of a single message.
-/** A ChatLine takes a Message object,
- * formats it (by turning the various message types into a human-readable form and afterwards pumping it through
- * our Style engine), and stores it as a number of QTextLayouts representing the three fields of a chat line
- * (timestamp, sender and text). These layouts already include any rendering information such as font,
- * color, or selected characters. By calling layout(), they can be quickly layouted to fit a given set of field widths.
- * Afterwards, they can quickly be painted whenever necessary.
- *
- * By separating the complex and slow task of interpreting and formatting Message objects (which happens exactly once
- * per message) from the actual layouting and painting, we gain a lot of speed compared to the standard Qt rendering
- * functions.
- */
-class ChatLine : public QObject, public AbstractUiMsg {
-  Q_OBJECT
+class ChatLine : public QGraphicsItem, public AbstractUiMsg {
 
   public:
-    ChatLine(Message message);
+    ChatLine(Message);
     virtual ~ChatLine();
+    virtual QString sender() const;
+    virtual QString text() const;
+    virtual MsgId msgId() const;
+    virtual BufferInfo bufferInfo() const;
+    virtual QDateTime timestamp() const;
 
-    qreal layout(qreal tsWidth, qreal nickWidth, qreal textWidth);
-    qreal height() const { return hght; }
-    int posToCursor(QPointF pos);
-    void draw(QPainter *p, const QPointF &pos);
+    virtual QRectF boundingRect () const;
+    virtual void paint (QPainter * painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+    void layout();
 
-    enum SelectionMode { None, Partial, Full };
-    void setSelection(SelectionMode, int start = 0, int end = 0);
+    void setColumnWidths(int tsColWidth, int senderColWidth, int textColWidth);
 
-    QDateTime timeStamp() const;
-    QString sender() const;
-    QString text() const;
-    MsgId msgId() const;
-    BufferInfo bufferInfo() const;
+    void myMousePressEvent ( QGraphicsSceneMouseEvent * event ) { qDebug() << "press"; mousePressEvent(event); }
 
-    bool isUrl(int pos) const;
-    QUrl getUrl(int pos) const;
-
-  public slots:
+  protected:
+    bool sceneEvent ( QEvent * event );
 
   private:
-    qreal hght;
-    Message msg;
-    qreal tsWidth, senderWidth, textWidth;
-    UiStyle::StyledString styledTimeStamp, styledSender, styledText;
-
-    struct FormatRange {
-      int start;
-      int length;
-      int height;
-      QTextCharFormat format;
-    };
-    struct Word {
-      int start;
-      int length;
-      int trailing;
-      int height;
-    };
-    struct LineLayout {
-      int y;
-      int height;
-      int start;
-      int length;
-    };
-    QVector<int> charPos;
-    QVector<int> charWidths;
-    QVector<int> charHeights;
-    QVector<int> charUrlIdx;
-    QList<FormatRange> tsFormat, senderFormat, textFormat;
-    QList<Word> words;
-    QList<LineLayout> lineLayouts;
-    int minHeight;
+    UiStyle::StyledText _styledTimestamp, _styledText, _styledSender;
+    QDateTime _timestamp;
+    MsgId _msgId;
 
-    SelectionMode selectionMode;
-    int selectionStart, selectionEnd;
-    void formatMsg(Message);
-    void precomputeLine();
-    QList<FormatRange> calcFormatRanges(const UiStyle::StyledString &, QTextLayout::FormatRange additional = QTextLayout::FormatRange());
+    ChatItem *_tsItem, *_senderItem, *_textItem;
+    int _tsColWidth, _senderColWidth, _textColWidth;
 };
 
 #endif
diff --git a/src/qtui/chatscene.cpp b/src/qtui/chatscene.cpp
new file mode 100644 (file)
index 0000000..8914540
--- /dev/null
@@ -0,0 +1,69 @@
+/***************************************************************************
+ *   Copyright (C) 2005-07 by the Quassel IRC Team                         *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include <QGraphicsSceneMouseEvent>
+
+#include "buffer.h"
+#include "chatitem.h"
+#include "chatline.h"
+#include "chatscene.h"
+#include "quasselui.h"
+
+ChatScene::ChatScene(Buffer *buf, QObject *parent) : QGraphicsScene(parent) {
+  _buffer = buf;
+
+  foreach(AbstractUiMsg *msg, buf->contents()) {
+    appendMsg(msg);
+  }
+  connect(buf, SIGNAL(msgAppended(AbstractUiMsg *)), this, SLOT(appendMsg(AbstractUiMsg *)));
+  connect(buf, SIGNAL(msgPrepended(AbstractUiMsg *)), this, SLOT(prependMsg(AbstractUiMsg *)));
+}
+
+ChatScene::~ChatScene() {
+
+
+}
+
+void ChatScene::appendMsg(AbstractUiMsg * msg) {
+  ChatLine *line = dynamic_cast<ChatLine*>(msg);
+  Q_ASSERT(line);
+  _lines.append(line);
+  addItem(line);
+  line->setPos(0, _lines.count() * 30);
+  line->setColumnWidths(80, 80, 400);
+}
+
+void ChatScene::prependMsg(AbstractUiMsg * msg) {
+  ChatLine *line = dynamic_cast<ChatLine*>(msg);
+  Q_ASSERT(line); qDebug() << "prepending";
+  _lines.prepend(line);
+  addItem(line);
+  line->setPos(0, _lines.count() * 30);
+}
+
+void ChatScene::mousePressEvent ( QGraphicsSceneMouseEvent * mouseEvent ) {
+  qDebug() << "recv" << mouseEvent->scenePos();
+  ChatLine *line = static_cast<ChatLine*>(itemAt(mouseEvent->scenePos()));
+  ChatItem *item = static_cast<ChatItem*>(itemAt(mouseEvent->scenePos()));
+  qDebug() << (void*)line << (void*)item;
+  if(line) {
+    line->myMousePressEvent(mouseEvent);
+  } else  QGraphicsScene::mousePressEvent(mouseEvent);
+}
diff --git a/src/qtui/chatscene.h b/src/qtui/chatscene.h
new file mode 100644 (file)
index 0000000..0963afa
--- /dev/null
@@ -0,0 +1,54 @@
+/***************************************************************************
+ *   Copyright (C) 2005-07 by the Quassel IRC Team                         *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifndef _CHATSCENE_H_
+#define _CHATSCENE_H_
+
+#include <QGraphicsScene>
+
+class AbstractUiMsg;
+class Buffer;
+class ChatLine;
+class QGraphicsSceneMouseEvent;
+
+class ChatScene : public QGraphicsScene {
+  Q_OBJECT
+
+  public:
+    ChatScene(Buffer *buffer, QObject *parent);
+    virtual ~ChatScene();
+
+    Buffer *buffer() const;
+
+  public slots:
+
+  protected slots:
+    void appendMsg(AbstractUiMsg *msg);
+    void prependMsg(AbstractUiMsg *msg);
+
+    void mousePressEvent ( QGraphicsSceneMouseEvent * mouseEvent );
+
+  private:
+    Buffer *_buffer;
+    QList<ChatLine*> _lines;
+
+};
+
+#endif
diff --git a/src/qtui/chatview.cpp b/src/qtui/chatview.cpp
new file mode 100644 (file)
index 0000000..ab55507
--- /dev/null
@@ -0,0 +1,87 @@
+/***************************************************************************
+ *   Copyright (C) 2005-07 by the Quassel IRC Team                         *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include <QGraphicsTextItem>
+
+#include "buffer.h"
+#include "chatline.h"
+#include "chatscene.h"
+#include "chatview.h"
+#include "quasselui.h"
+
+ChatView::ChatView(Buffer *buf, QWidget *parent) : QGraphicsView(parent) {
+  _scene = new ChatScene(buf, this);
+  setScene(_scene);
+
+  QGraphicsTextItem *item = scene()->addText(buf->name());
+
+}
+
+
+ChatView::~ChatView() {
+
+}
+
+
+ChatScene *ChatView::scene() const {
+  return _scene;
+}
+
+/*
+void ChatView::clear()
+{
+}
+
+void ChatView::prependMsg(AbstractUiMsg *msg) {
+  ChatLine *line = dynamic_cast<ChatLine*>(msg);
+  Q_ASSERT(line);
+  prependChatLine(line);
+}
+
+void ChatView::prependChatLine(ChatLine *line) {
+  qDebug() << "prepending";
+}
+
+void ChatView::prependChatLines(QList<ChatLine *> clist) {
+
+}
+
+void ChatView::appendMsg(AbstractUiMsg *msg) {
+  ChatLine *line = dynamic_cast<ChatLine*>(msg);
+  Q_ASSERT(line);
+  appendChatLine(line);
+}
+
+void ChatView::appendChatLine(ChatLine *line) {
+  qDebug() << "appending";
+}
+
+
+void ChatView::appendChatLines(QList<ChatLine *> list) {
+  foreach(ChatLine *line, list) {
+    
+  }
+}
+
+void ChatView::setContents(QList<ChatLine *> list) {
+  qDebug() << "setting" << list.count();
+  appendChatLines(list);
+}
+*/
diff --git a/src/qtui/chatview.h b/src/qtui/chatview.h
new file mode 100644 (file)
index 0000000..b2341f3
--- /dev/null
@@ -0,0 +1,58 @@
+/***************************************************************************
+ *   Copyright (C) 2005-07 by the Quassel IRC Team                         *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifndef _CHATVIEW_H_
+#define _CHATVIEW_H_
+
+#include <QGraphicsView>
+
+class AbstractUiMsg;
+class Buffer;
+class ChatLine;
+class ChatScene;
+
+class ChatView : public QGraphicsView {
+  Q_OBJECT
+
+  public:
+    ChatView(Buffer *, QWidget *parent = 0);
+    ~ChatView();
+
+    ChatScene *scene() const;
+
+  public slots:
+/*
+    void clear();
+
+    void prependMsg(AbstractUiMsg *);
+    void appendMsg(AbstractUiMsg *);
+
+    void prependChatLine(ChatLine *);
+    void appendChatLine(ChatLine *);
+    void prependChatLines(QList<ChatLine *>);
+    void appendChatLines(QList<ChatLine *>);
+
+    void setContents(QList<ChatLine *>);
+*/
+  private:
+    ChatScene *_scene;
+};
+
+#endif
index 68d63da..004ca93 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "util.h"
 #include "chatwidget.h"
-#include "chatline.h"
+#include "chatline-old.h"
 #include "qtui.h"
 
 
@@ -534,7 +534,7 @@ QString ChatWidget::selectionToString() {
   if(selectionMode == LinesSelected) {
     QString result;
     for(int l = selectionStart; l <= selectionEnd; l++) {
-      result += QString("[%1] %2 %3\n").arg(lines[l]->timeStamp().toLocalTime().toString("hh:mm:ss"))
+      result += QString("[%1] %2 %3\n").arg(lines[l]->timestamp().toLocalTime().toString("hh:mm:ss"))
           .arg(lines[l]->sender()).arg(lines[l]->text());
     }
     return result;
index 6f62adf..4bd2c96 100644 (file)
@@ -21,7 +21,7 @@
 #include "mainwin.h"
 
 #include "bufferview.h"
-#include "chatline.h"
+#include "chatline-old.h"
 #include "client.h"
 #include "coreconnectdlg.h"
 #include "serverlist.h"
index 714a8c0..73cfc07 100644 (file)
@@ -1,12 +1,12 @@
-DEPMOD = uisupport common client contrib/qxt
+DEPMOD = uisupport common client
 QT_MOD = core gui network
 
-SRCS += bufferview.cpp bufferviewfilter.cpp bufferwidget.cpp channelwidgetinput.cpp chatline.cpp \
-       chatwidget.cpp coreconnectdlg.cpp \
-       guisettings.cpp identities.cpp mainwin.cpp qtui.cpp qtuistyle.cpp serverlist.cpp settingsdlg.cpp tabcompleter.cpp topicwidget.cpp
+SRCS += bufferview.cpp bufferviewfilter.cpp bufferwidget.cpp channelwidgetinput.cpp chatline-old.cpp \
+        chatwidget.cpp coreconnectdlg.cpp \
+        guisettings.cpp identities.cpp mainwin.cpp qtui.cpp qtuistyle.cpp serverlist.cpp settingsdlg.cpp tabcompleter.cpp topicwidget.cpp
 
-HDRS += bufferview.h bufferviewfilter.h bufferwidget.h channelwidgetinput.h chatline.h chatwidget.h coreconnectdlg.h \
-       guisettings.h identities.h mainwin.h qtui.h qtuistyle.h serverlist.h settingsdlg.h settingspage.h tabcompleter.h topicwidget.h
+HDRS += bufferview.h bufferviewfilter.h bufferwidget.h channelwidgetinput.h chatline-old.h chatwidget.h \
+        coreconnectdlg.h guisettings.h identities.h mainwin.h qtui.h qtuistyle.h serverlist.h settingsdlg.h settingspage.h tabcompleter.h topicwidget.h
 
 
 FORMNAMES = identitiesdlg.ui identitieseditdlg.ui networkeditdlg.ui mainwin.ui nickeditdlg.ui serverlistdlg.ui \
index 68c8950..f62031e 100644 (file)
             <property name="text" >
              <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
 p, li { white-space: pre-wrap; }
-&lt;/style>&lt;/head>&lt;body style=" font-family:'Trebuchet MS'; font-size:14pt; font-weight:400; font-style:normal;">
-&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;">&lt;span style=" font-size:89pt;">Yarrrrr!&lt;/span>&lt;/p>
-&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:49pt;">&lt;span style=" font-size:22pt;">Avast, ye scurvy dogs!&lt;/span>&lt;/p>&lt;/body>&lt;/html></string>
+&lt;/style>&lt;/head>&lt;body style=" font-family:'Trebuchet MS'; font-size:10pt; font-weight:400; font-style:normal;">
+&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;">&lt;span style=" font-size:89pt; color:#483d8b;">Quassel IRC&lt;/span>&lt;/p>
+&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:49pt;">&lt;span style=" font-size:22pt;">Think less. Chat more.&lt;/span>&lt;/p>&lt;/body>&lt;/html></string>
             </property>
             <property name="scaledContents" >
              <bool>true</bool>
index 3fc53bd..e14208b 100644 (file)
@@ -104,8 +104,8 @@ QString UiStyle::formatCode(FormatType ftype) const {
   return _formatCodes.key(ftype);
 }
 
-UiStyle::StyledString UiStyle::styleString(QString s) {
-  StyledString result;
+UiStyle::StyledText UiStyle::styleString(QString s) {
+  StyledText result;
   QList<FormatType> fmtList;
   fmtList.append(None);
   QTextLayout::FormatRange curFmtRng;
index 0ddc1b8..f09cdbc 100644 (file)
@@ -51,13 +51,13 @@ class UiStyle {
       QUrl url;
     };
 
-    struct StyledString {
+    struct StyledText {
       QString text;
       QList<QTextLayout::FormatRange> formats;
       QList<UrlInfo> urls;
     };
 
-    StyledString styleString(QString);
+    StyledText styleString(QString);
 
     void setFormat(FormatType, QTextCharFormat);
     QTextCharFormat format(FormatType) const;
index 9151cb7..82c47e0 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2005-07 by The Quassel IRC Development Team             *
+ *   Copyright (C) 2005-07 by the Quassel IRC Team                         *
  *   devel@quassel-irc.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
index 2a25675..0beb198 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2005-07 by The Quassel IRC Development Team             *
+ *   Copyright (C) 2005-07 by the Quassel IRC Team                         *
  *   devel@quassel-irc.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *