From: Manuel Nickschas Date: Sat, 13 Aug 2011 00:44:54 +0000 (+0200) Subject: Implement the ChatLine element in C++ X-Git-Url: https://git.quassel-irc.org/?a=commitdiff_plain;h=aebd09e08b2afb4e21fa0f5a0044be6d80e8f52e;p=quassel.git Implement the ChatLine element in C++ Now that I get my brain wrapped around QML a bit, let's take things more seriously. Turns out, while Text elements seem to be efficient enough, TextEdit elements (needed for selection and mousehandling) are not, so resizing is sluggish. Thus, instead of using any of the stock elements, we're now implementing this ourselves in C++, and will probably do much the same as we did for the QGV-based ChatView (minus some of the hackery, if we're lucky). This means layouting and drawing the text ourselves. On the upside, we can just keep using the old styleengine for now... Here's hoping that things will turn out to be more efficient anyway, because ListView seems to be creating and discarding its items as needed; so there shouldn't be a scene with thousands of items involved to manage... --- diff --git a/src/qmlui/CMakeLists.txt b/src/qmlui/CMakeLists.txt index ab6808cd..59998a8d 100644 --- a/src/qmlui/CMakeLists.txt +++ b/src/qmlui/CMakeLists.txt @@ -6,12 +6,14 @@ include(${QT_USE_FILE}) set(SOURCES + qmlchatline.cpp qmlchatview.cpp qmlmessagemodel.cpp qmlmessagemodelitem.cpp ) set(MOC_HDRS + qmlchatline.h qmlchatview.h qmlmessagemodel.h ) diff --git a/src/qmlui/qml/ChatLine.qml b/src/qmlui/qml/ChatLine.qml deleted file mode 100644 index 1cf3ae8f..00000000 --- a/src/qmlui/qml/ChatLine.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 1.1 - -Item { - Row { - id: chatLine - Text { text: timestamp; wrapMode: Text.NoWrap; width: 100 } - Text { text: sender; wrapMode: Text.NoWrap; width: 100 } - Text { text: contents; wrapMode: Text.Wrap; width: chatView.width-200} - } - height: chatLine.height -} diff --git a/src/qmlui/qml/ChatView.qml b/src/qmlui/qml/ChatView.qml index 5781fc78..aa72fb4c 100644 --- a/src/qmlui/qml/ChatView.qml +++ b/src/qmlui/qml/ChatView.qml @@ -1,6 +1,8 @@ -import QtQuick 1.0 +import QtQuick 1.1 // import Qt.components 1.0 +import eu.quassel.qmlui 1.0 + Rectangle { id: container @@ -8,14 +10,40 @@ Rectangle { id: chatView anchors.fill: parent model: msgModel + delegate: Component { - ChatLine { } + ChatLine { + chatLineData: chatLineDataRole + } } + //interactive: false + boundsBehavior: Flickable.StopAtBounds + + property int timestampWidth: 50 + property int senderWidth: 80 + property int contentsWidth: width - timestampWidth - senderWidth - 30; + Connections { target: msgModel onRowsInserted: chatView.positionViewAtEnd(); } +/* + MouseArea { + id: mouseArea + anchors.fill: parent + acceptedButtons: Qt.LeftButton + + onClicked: { + console.log("clicked") + parent.senderWidth = parent.senderWidth + 10 + } + onPositionChanged: { + console.log("changed" + mouseX + mouseY) + } + + } +*/ Rectangle { id: scrollbar diff --git a/src/qmlui/qml/qml.qrc b/src/qmlui/qml/qml.qrc index 9da24580..d58f0f6c 100644 --- a/src/qmlui/qml/qml.qrc +++ b/src/qmlui/qml/qml.qrc @@ -1,7 +1,6 @@ - ChatLine.qml ChatView.qml diff --git a/src/qmlui/qmlchatline.cpp b/src/qmlui/qmlchatline.cpp new file mode 100644 index 00000000..874437cc --- /dev/null +++ b/src/qmlui/qmlchatline.cpp @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2005-2011 by the Quassel Project * + * 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) version 3. * + * * + * 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 + +#include "qmlchatline.h" + +void QmlChatLine::registerTypes() { + qRegisterMetaType("QmlChatLine::Data"); + qRegisterMetaTypeStreamOperators("QmlChatLine::Data"); + qmlRegisterType("eu.quassel.qmlui", 1, 0, "ChatLine"); +} + +QDataStream &operator<<(QDataStream &out, const QmlChatLine::Data &data) { + out << data.timestamp.text << data.timestamp.formats + << data.sender.text << data.sender.formats + << data.contents.text << data.contents.formats; + return out; +} + +QDataStream &operator>>(QDataStream &in, QmlChatLine::Data &data) { + in >> data.timestamp.text >> data.timestamp.formats + >> data.sender.text >> data.sender.formats + >> data.contents.text >> data.contents.formats; + return in; +} + +QmlChatLine::QmlChatLine(QDeclarativeItem *parent) : QDeclarativeItem(parent) { + setFlag(ItemHasNoContents, false); + setImplicitHeight(20); + setImplicitWidth(100); +} + +QmlChatLine::~QmlChatLine() { + +} + +void QmlChatLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { + painter->drawText(0, 0, data().contents.text); + +} + + diff --git a/src/qmlui/qmlchatline.h b/src/qmlui/qmlchatline.h new file mode 100644 index 00000000..12ce82e9 --- /dev/null +++ b/src/qmlui/qmlchatline.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) 2005-2011 by the Quassel Project * + * 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) version 3. * + * * + * 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 QMLCHATLINE_H_ +#define QMLCHATLINE_H_ + +#include + +#include "uistyle.h" + +class QmlChatLine : public QDeclarativeItem { + Q_OBJECT + + Q_PROPERTY(QVariant chatLineData READ chatLineData WRITE setChatLineData) + + //Q_PROPERTY(QVariant ) + +public: + //! Contains all data needed to render a QmlChatLine + struct Data { + struct ChatLineColumnData { + QString text; + UiStyle::FormatList formats; + }; + + ChatLineColumnData timestamp; + ChatLineColumnData sender; + ChatLineColumnData contents; + }; + + QmlChatLine(QDeclarativeItem *parent = 0); + virtual ~QmlChatLine(); + + inline Data data() const { return _data; } + inline QVariant chatLineData() const { return QVariant::fromValue(_data); } + inline void setChatLineData(const QVariant &data) { _data = data.value(); } + + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + + static void registerTypes(); + +private: + Data _data; +}; + +QDataStream &operator<<(QDataStream &out, const QmlChatLine::Data &data); +QDataStream &operator>>(QDataStream &in, QmlChatLine::Data &data); + +Q_DECLARE_METATYPE(QmlChatLine::Data) + +#endif diff --git a/src/qmlui/qmlmessagemodel.cpp b/src/qmlui/qmlmessagemodel.cpp index 45ebc31e..fc7ecc3b 100644 --- a/src/qmlui/qmlmessagemodel.cpp +++ b/src/qmlui/qmlmessagemodel.cpp @@ -18,17 +18,19 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#include + #include "qmlmessagemodel.h" +#include "qmlchatline.h" QmlMessageModel::QmlMessageModel(QObject *parent) : MessageModel(parent) { + QmlChatLine::registerTypes(); + QHash roles; - roles[TimestampRole] = "timestamp"; - roles[SenderRole] = "sender"; - roles[ContentsRole] = "contents"; + roles[ChatLineDataRole] = "chatLineDataRole"; setRoleNames(roles); - } void QmlMessageModel::insertMessages__(int pos, const QList &messages) { diff --git a/src/qmlui/qmlmessagemodel.h b/src/qmlui/qmlmessagemodel.h index 052db04a..92ce1e7d 100644 --- a/src/qmlui/qmlmessagemodel.h +++ b/src/qmlui/qmlmessagemodel.h @@ -31,9 +31,7 @@ class QmlMessageModel : public MessageModel { public: enum QmlMessageModelRole { - TimestampRole = MessageModel::UserRole, - SenderRole, - ContentsRole, + ChatLineDataRole = MessageModel::UserRole, UserRole }; diff --git a/src/qmlui/qmlmessagemodelitem.cpp b/src/qmlui/qmlmessagemodelitem.cpp index 864790ae..561c9b7b 100644 --- a/src/qmlui/qmlmessagemodelitem.cpp +++ b/src/qmlui/qmlmessagemodelitem.cpp @@ -18,8 +18,10 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#include "qmlchatline.h" #include "qmlmessagemodel.h" #include "qmlmessagemodelitem.h" +#include "uistyle.h" QmlMessageModelItem::QmlMessageModelItem(const Message &msg) : MessageModelItem(), @@ -29,28 +31,19 @@ QmlMessageModelItem::QmlMessageModelItem(const Message &msg) _styledMsg.setFlags(msg.flags() |= Message::ServerMsg); } -bool QmlMessageModelItem::setData(int column, const QVariant &value, int role) { - switch(role) { - case MessageModel::FlagsRole: - _styledMsg.setFlags((Message::Flags)value.toUInt()); - return true; - default: - return MessageModelItem::setData(column, value, role); - } -} - QVariant QmlMessageModelItem::data(int column, int role) const { QVariant variant; switch(role) { - case QmlMessageModel::TimestampRole: - variant = _styledMsg.timestamp(); - break; - case QmlMessageModel::SenderRole: - variant = _styledMsg.sender(); - break; - case QmlMessageModel::ContentsRole: - variant = _styledMsg.contents(); - break; + case QmlMessageModel::ChatLineDataRole: { + QmlChatLine::Data data; + data.timestamp.text = _styledMsg.decoratedTimestamp(); + data.timestamp.formats = UiStyle::FormatList() << qMakePair((quint16)0, (quint32)UiStyle::formatType(_styledMsg.type()) | UiStyle::Timestamp); + data.sender.text = _styledMsg.decoratedSender(); + data.sender.formats = UiStyle::FormatList() << qMakePair((quint16)0, (quint32)UiStyle::formatType(_styledMsg.type()) | UiStyle::Sender); + data.contents.text = _styledMsg.plainContents(); + data.contents.formats = _styledMsg.contentsFormatList(); + return QVariant::fromValue(data); + } default: break; } @@ -58,28 +51,3 @@ QVariant QmlMessageModelItem::data(int column, int role) const { return MessageModelItem::data(column, role); return variant; } - -QVariant QmlMessageModelItem::timestampData(int role) const { - switch(role) { - case MessageModel::DisplayRole: - return _styledMsg.timestamp(); - } - return QVariant(); -} - -QVariant QmlMessageModelItem::senderData(int role) const { - switch(role) { - case MessageModel::DisplayRole: - return _styledMsg.sender(); - } - return QVariant(); -} - -QVariant QmlMessageModelItem::contentsData(int role) const { - switch(role) { - case MessageModel::DisplayRole: - return _styledMsg.contents(); - } - return QVariant(); -} - diff --git a/src/qmlui/qmlmessagemodelitem.h b/src/qmlui/qmlmessagemodelitem.h index 47d46cf7..7138df3c 100644 --- a/src/qmlui/qmlmessagemodelitem.h +++ b/src/qmlui/qmlmessagemodelitem.h @@ -22,13 +22,13 @@ #define QMLMESSAGEMODELITEM_H_ #include "messagemodel.h" +#include "uistyle.h" class QmlMessageModelItem : public MessageModelItem { public: QmlMessageModelItem(const Message &msg); virtual QVariant data(int column, int role) const; - virtual bool setData(int column, const QVariant &value, int role); virtual inline const Message &message() const { return _styledMsg; } virtual inline const QDateTime ×tamp() const { return _styledMsg.timestamp(); } @@ -39,11 +39,7 @@ public: virtual inline Message::Flags msgFlags() const { return _styledMsg.flags(); } private: - QVariant timestampData(int role) const; - QVariant senderData(int role) const; - QVariant contentsData(int role) const; - - Message _styledMsg; + UiStyle::StyledMessage _styledMsg; }; #endif