1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00
This commit is contained in:
krepa098 2014-11-16 12:40:44 +01:00
parent 808f8b1cc5
commit 74bd802863
24 changed files with 208 additions and 82 deletions

View File

@ -150,7 +150,9 @@ HEADERS += src/widget/form/addfriendform.h \
src/chatlog/content/text.h \
src/chatlog/content/spinner.h \
src/chatlog/content/filetransferwidget.h \
src/chatlog/chatmessage.h
src/chatlog/chatmessage.h \
src/chatlog/content/image.h \
src/chatlog/customtextdocument.h
SOURCES += \
src/widget/form/addfriendform.cpp \
@ -216,4 +218,6 @@ SOURCES += \
src/chatlog/content/text.cpp \
src/chatlog/content/spinner.cpp \
src/chatlog/content/filetransferwidget.cpp \
src/chatlog/chatmessage.cpp
src/chatlog/chatmessage.cpp \
src/chatlog/content/image.cpp \
src/chatlog/customtextdocument.cpp

View File

@ -43,6 +43,7 @@
<file>ui/chatArea/chatArea.css</file>
<file>ui/chatArea/innerStyle.css</file>
<file>ui/chatArea/spinner.png</file>
<file>ui/chatArea/info.png</file>
<file>ui/chatArea/scrollBarDownArrow.png</file>
<file>ui/chatArea/scrollBarDownArrowHover.png</file>
<file>ui/chatArea/scrollBarDownArrowPressed.png</file>

View File

@ -59,7 +59,7 @@ QString ChatLineContent::getSelectedText() const
return QString();
}
qreal ChatLineContent::firstLineVOffset()
qreal ChatLineContent::firstLineVOffset() const
{
return 0.0;
}
@ -68,8 +68,3 @@ void ChatLineContent::visibilityChanged(bool)
{
}
QString ChatLineContent::toString() const
{
return QString();
}

View File

@ -28,7 +28,7 @@ public:
virtual bool isOverSelection(QPointF scenePos) const;
virtual QString getSelectedText() const;
virtual qreal firstLineVOffset();
virtual qreal firstLineVOffset() const;
virtual QRectF boundingSceneRect() const = 0;
virtual QRectF boundingRect() const = 0;
@ -36,8 +36,6 @@ public:
virtual void visibilityChanged(bool visible);
virtual QString toString() const;
private:
friend class ChatLine;

View File

@ -4,9 +4,13 @@
#include "chatlinecontent.h"
#include "chatlinecontentproxy.h"
#include "content/text.h"
#include "content/image.h"
#include "content/filetransferwidget.h"
#include "content/spinner.h"
#include "../misc/style.h"
#include "../misc/smileypack.h"
#include <QDebug>
#include <QScrollBar>
#include <QApplication>
@ -53,20 +57,33 @@ ChatLog::~ChatLog()
delete line;
}
ChatMessage* ChatLog::addChatMessage(const QString& sender, ChatLineContent* content)
ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString &msg, bool self)
{
ChatMessage* line = new ChatMessage(scene, sender, content);
ChatMessage* line = new ChatMessage(scene, msg);
line->addColumn(new Text(sender, self ? Style::getFont(Style::MediumBold) : Style::getFont(Style::Medium), true), ColumnFormat(75.0, ColumnFormat::FixedSize, 1, ColumnFormat::Right));
line->addColumn(new Text(SmileyPack::getInstance().smileyfied(msg)), ColumnFormat(1.0, ColumnFormat::VariableSize));
line->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(50.0, ColumnFormat::FixedSize, 1, ColumnFormat::Right));
insertChatline(line);
return line;
}
ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString& msg, const QDateTime& timestamp, bool self)
{
ChatMessage* line = addChatMessage(sender, msg, self);
line->markAsSent(timestamp);
return line;
}
ChatMessage* ChatLog::addChatMessage(const QString& sender, ChatLineContent* content, const QDateTime& timestamp)
ChatMessage *ChatLog::addSystemMessage(const QString &msg, const QDateTime& timestamp)
{
ChatMessage* line = new ChatMessage(scene, sender, content);
line->markAsSent(timestamp);
insertChatline(line);
ChatMessage* line = new ChatMessage(scene, msg);
line->addColumn(new Image(QSizeF(16, 16), ":/ui/chatArea/info.png"), ColumnFormat(75.0, ColumnFormat::FixedSize, 1, ColumnFormat::Right));
line->addColumn(new Text(msg), ColumnFormat(1.0, ColumnFormat::VariableSize));
line->addColumn(new Text(timestamp.toString("hh:mm")), ColumnFormat(50.0, ColumnFormat::FixedSize, 1, ColumnFormat::Right));
insertChatline(line);
return line;
}
@ -134,9 +151,6 @@ void ChatLog::partialUpdate()
auto oldUpdateMode = viewportUpdateMode();
setViewportUpdateMode(NoViewportUpdate);
static int count = 0;
int count2 = 0;
int lastNonDirty = visibleLines.first()->getRowIndex();
bool repos;
do
{
@ -144,20 +158,15 @@ void ChatLog::partialUpdate()
if(!visibleLines.empty())
{
repos = layout(visibleLines.first()->getRowIndex(), visibleLines.last()->getRowIndex(), useableWidth());
lastNonDirty = visibleLines.last()->getRowIndex();
}
checkVisibility();
count2++;
}
while(repos);
reposition(visibleLines.last()->getRowIndex(), lines.size());
checkVisibility();
count = qMax(count, count2);
//qDebug() << "COUNT: " << count;
setViewportUpdateMode(oldUpdateMode);
updateSceneRect();
}

View File

@ -16,8 +16,10 @@ public:
explicit ChatLog(QWidget* parent = 0);
virtual ~ChatLog();
ChatMessage* addChatMessage(const QString& sender, ChatLineContent* content, const QDateTime& timestamp);
ChatMessage* addChatMessage(const QString& sender, ChatLineContent* content);
ChatMessage* addChatMessage(const QString& sender, const QString& msg, const QDateTime& timestamp, bool self);
ChatMessage* addChatMessage(const QString& sender, const QString& msg, bool self);
ChatMessage* addSystemMessage(const QString& msg, const QDateTime& timestamp);
void insertChatline(ChatLine* l);
@ -26,10 +28,6 @@ public:
void copySelectedText() const;
QString getSelectedText() const;
signals:
public slots:
protected:
QRect getVisibleRect() const;
ChatLineContent* getContentFromPos(QPointF scenePos) const;

View File

@ -4,23 +4,22 @@
#include <QDateTime>
ChatMessage::ChatMessage(QGraphicsScene *scene, const QString& author ,ChatLineContent *content)
ChatMessage::ChatMessage(QGraphicsScene* scene, const QString& rawMessage)
: ChatLine(scene)
, rawString(rawMessage)
{
addColumn(new Text(author, true), ColumnFormat(75.0, ColumnFormat::FixedSize, 1, ColumnFormat::Right));
addColumn(content, ColumnFormat(1.0, ColumnFormat::VariableSize));
addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(50.0, ColumnFormat::FixedSize, 1, ColumnFormat::Right));
midColumn = content;
// addColumn(new Text(author, true), ColumnFormat(75.0, ColumnFormat::FixedSize, 1, ColumnFormat::Right));
// addColumn(content, ColumnFormat(1.0, ColumnFormat::VariableSize));
// addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(50.0, ColumnFormat::FixedSize, 1, ColumnFormat::Right));
}
void ChatMessage::markAsSent(const QDateTime &time)
{
// remove the spinner and replace it by $time
replaceContent(2, new Text(time.toString("hh:mm"), true));
replaceContent(2, new Text(time.toString("hh:mm")));
}
QString ChatMessage::toString() const
{
return midColumn->toString();
return rawString;
}

View File

@ -8,13 +8,14 @@ class QGraphicsScene;
class ChatMessage : public ChatLine
{
public:
ChatMessage(QGraphicsScene* scene, const QString &author, ChatLineContent* content);
ChatMessage(QGraphicsScene* scene, const QString& rawMessage);
void markAsSent(const QDateTime& time);
QString toString() const;
private:
ChatLineContent* midColumn = nullptr;
QString rawString;
};
#endif // CHATMESSAGE_H

View File

@ -0,0 +1,39 @@
#include "image.h"
#include <QPainter>
Image::Image(QSizeF Size, const QString& filename)
: size(Size)
{
pmap.load(filename);
}
QRectF Image::boundingRect() const
{
return QRectF(QPointF(-size.width() / 2.0, -size.height() / 2.0), size);
}
QRectF Image::boundingSceneRect() const
{
return QRectF(scenePos(), size);
}
qreal Image::firstLineVOffset() const
{
return size.height() / 4.0;
}
void Image::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
painter->translate(-size.width() / 2.0, -size.height() / 2.0);
painter->setRenderHint(QPainter::SmoothPixmapTransform);
painter->drawPixmap(0, 0, size.width(), size.height(), pmap);
Q_UNUSED(option)
Q_UNUSED(widget)
}
void Image::setWidth(qreal width)
{
Q_UNUSED(width)
}

View File

@ -0,0 +1,23 @@
#ifndef IMAGE_H
#define IMAGE_H
#include "../chatlinecontent.h"
class Image : public QObject, public ChatLineContent
{
public:
Image(QSizeF size, const QString &filename);
virtual QRectF boundingRect() const;
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
virtual void setWidth(qreal width);
virtual QRectF boundingSceneRect() const;
virtual qreal firstLineVOffset() const;
private:
QSizeF size;
QPixmap pmap;
};
#endif // IMAGE_H

View File

@ -54,6 +54,11 @@ void Spinner::visibilityChanged(bool visible)
timer.stop();
}
qreal Spinner::firstLineVOffset() const
{
return size.height() / 4.0;
}
void Spinner::timeout()
{
rot += 8;

View File

@ -17,6 +17,7 @@ public:
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
virtual void setWidth(qreal width);
virtual void visibilityChanged(bool visible);
virtual qreal firstLineVOffset() const;
private slots:
void timeout();

View File

@ -1,5 +1,7 @@
#include "text.h"
#include "../customtextdocument.h"
#include <QFontMetrics>
#include <QPainter>
#include <QPalette>
@ -11,9 +13,10 @@
#include <QFontMetrics>
#include <QDesktopServices>
Text::Text(const QString& txt, bool enableElide)
Text::Text(const QString& txt, QFont font, bool enableElide)
: ChatLineContent()
, elide(enableElide)
, defFont(font)
{
setText(txt);
setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton);
@ -142,7 +145,7 @@ void Text::visibilityChanged(bool visible)
freeResources();
}
qreal Text::firstLineVOffset()
qreal Text::firstLineVOffset() const
{
return vOffset;
}
@ -162,18 +165,14 @@ void Text::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
QDesktopServices::openUrl(anchor);
}
QString Text::toString() const
{
return text;
}
void Text::ensureIntegrity()
{
if(!doc)
{
doc = new QTextDocument();
doc = new CustomTextDocument();
doc->setUndoRedoEnabled(false);
doc->setUseDesignMetrics(true);
doc->setDefaultFont(defFont);
if(!elide)
{

View File

@ -6,13 +6,12 @@
#include <QTextDocument>
#include <QTextCursor>
class ChatLine;
class QTextLayout;
class CustomTextDocument;
class Text : public ChatLineContent
{
public:
Text(const QString& txt = "", bool enableElide = false);
Text(const QString& txt = "", QFont font = QFont(), bool enableElide = false);
virtual ~Text();
void setText(const QString& txt);
@ -32,12 +31,10 @@ public:
virtual void visibilityChanged(bool isVisible);
virtual qreal firstLineVOffset();
virtual qreal firstLineVOffset() const;
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
virtual QString toString() const;
protected:
// dynamic resource management
void ensureIntegrity();
@ -47,7 +44,7 @@ protected:
int cursorFromPos(QPointF scenePos) const;
private:
QTextDocument* doc = nullptr;
CustomTextDocument* doc = nullptr;
QString text;
QString elidedText;
QSizeF size;
@ -56,6 +53,7 @@ private:
QTextCursor cursor;
qreal vOffset = 0.0;
qreal width = 0.0;
QFont defFont;
};

View File

@ -0,0 +1,19 @@
#include "customtextdocument.h"
#include "../misc/smileypack.h"
#include <QIcon>
#include <QDebug>
CustomTextDocument::CustomTextDocument(QObject *parent)
: QTextDocument(parent)
{
}
QVariant CustomTextDocument::loadResource(int type, const QUrl &name)
{
if (type == QTextDocument::ImageResource && name.scheme() == "key")
return SmileyPack::getInstance().getAsImage(name.fileName());
return QTextDocument::loadResource(type, name);
}

View File

@ -0,0 +1,16 @@
#ifndef CUSTOMTEXTDOCUMENT_H
#define CUSTOMTEXTDOCUMENT_H
#include <QTextDocument>
class CustomTextDocument : public QTextDocument
{
Q_OBJECT
public:
explicit CustomTextDocument(QObject *parent = 0);
protected:
virtual QVariant loadResource(int type, const QUrl &name);
};
#endif // CUSTOMTEXTDOCUMENT_H

View File

@ -53,6 +53,11 @@ bool ToxID::isMine() const
return *this == Core::getInstance()->getSelfId();
}
void ToxID::clear()
{
publicKey.clear();
}
bool ToxID::isToxId(const QString& value)
{
const QRegularExpression hexRegExp("^[A-Fa-f0-9]+$");

View File

@ -27,6 +27,7 @@ struct ToxID
bool operator==(const ToxID& other) const;
bool operator!=(const ToxID& other) const;
bool isMine() const;
void clear();
};
struct DhtServer

View File

@ -183,7 +183,8 @@ QList<QStringList> SmileyPack::getEmoticons() const
QString SmileyPack::getAsRichText(const QString &key)
{
return "<img title=\""%key%"\" src=\"data:image/png;base64," % QString(getCachedSmiley(key).toBase64()) % "\">";
return QString("<img title=\"%1\" src=\"key:%1\"\\>").arg(key);
//return "<img title=\""%key%"\" src=\"data:image/png;base64," % QString(getCachedSmiley(key).toBase64()) % "\">";
}
QIcon SmileyPack::getAsIcon(const QString &key)
@ -193,6 +194,14 @@ QIcon SmileyPack::getAsIcon(const QString &key)
return QIcon(pm);
}
QImage SmileyPack::getAsImage(const QString &key)
{
QImage img;
img.loadFromData(getCachedSmiley(key), "PNG");
return img;
}
void SmileyPack::cacheSmiley(const QString &name)
{
// The -1 is to avoid having the space for descenders under images move the text down

View File

@ -41,6 +41,7 @@ public:
QList<QStringList> getEmoticons() const;
QString getAsRichText(const QString& key);
QIcon getAsIcon(const QString& key);
QImage getAsImage(const QString& key);
private slots:
void onSmileyPackChanged();

View File

@ -206,7 +206,10 @@ void GenericChatForm::onSaveLogClicked()
ChatMessage* GenericChatForm::addMessage(const ToxID& author, const QString &message, bool isAction,
const QDateTime &datetime, bool isSent)
{
ChatMessage* msg = chatWidget->addChatMessage(Core::getInstance()->getPeerName(author), new Text(SmileyPack::getInstance().smileyfied(message)), datetime);
QString authorStr = previousId != author ? Core::getInstance()->getPeerName(author) : QString();
previousId = author;
ChatMessage* msg = chatWidget->addChatMessage(authorStr, message, datetime, false);
if(isSent)
msg->markAsSent(datetime);
@ -215,7 +218,10 @@ ChatMessage* GenericChatForm::addMessage(const ToxID& author, const QString &mes
ChatMessage* GenericChatForm::addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime, bool isSent)
{
return chatWidget->addChatMessage(Core::getInstance()->getUsername(), new Text(SmileyPack::getInstance().smileyfied(message)));
QString authorStr = previousId != Core::getInstance()->getSelfId() ? Core::getInstance()->getUsername() : QString();
previousId = Core::getInstance()->getSelfId();
return chatWidget->addChatMessage(authorStr, message, true);
}
/**
@ -231,13 +237,13 @@ ChatMessage* GenericChatForm::addSelfMessage(const QString &message, bool isActi
// previousId.publicKey = author;
//}
//void GenericChatForm::addAlertMessage(const ToxID &author, QString message, QDateTime datetime)
//{
void GenericChatForm::addAlertMessage(const ToxID &author, QString message, QDateTime datetime)
{
// QString authorStr = Core::getInstance()->getPeerName(author);
// QString date = datetime.toString(Settings::getInstance().getTimestampFormat());
// chatWidget->insertMessage(ChatActionPtr(new AlertAction(authorStr, message, date)));
// previousId = author;
//}
}
void GenericChatForm::onEmoteButtonClicked()
{
@ -271,11 +277,11 @@ void GenericChatForm::focusInput()
msgEdit->setFocus();
}
//void GenericChatForm::addSystemInfoMessage(const QString &message, const QString &type, const QDateTime &datetime)
//{
// ChatActionPtr ca = genSystemInfoAction(message, type, datetime);
// chatWidget->insertMessage(ca);
//}
void GenericChatForm::addSystemInfoMessage(const QString &message, const QString &type, const QDateTime &datetime)
{
previousId.clear();
chatWidget->addSystemMessage(message, datetime);
}
//QString GenericChatForm::getElidedName(const QString& name)
//{
@ -287,19 +293,19 @@ void GenericChatForm::focusInput()
void GenericChatForm::clearChatArea(bool notinform)
{
// chatWidget->clearChatArea();
// previousId = ToxID();
chatWidget->clear();
previousId = ToxID();
// if (!notinform)
// addSystemInfoMessage(tr("Cleared"), "white", QDateTime::currentDateTime());
if (!notinform)
addSystemInfoMessage(tr("Cleared"), "white", QDateTime::currentDateTime());
// if (earliestMessage)
// {
// delete earliestMessage;
// earliestMessage = nullptr;
// }
if (earliestMessage)
{
delete earliestMessage;
earliestMessage = nullptr;
}
// emit chatAreaCleared();
emit chatAreaCleared();
}
/**
@ -419,7 +425,7 @@ void GenericChatForm::clearChatArea(bool notinform)
// return res;
//}
//ChatActionPtr GenericChatForm::genSystemInfoAction(const QString &message, const QString &type, const QDateTime &datetime)
//ChatMessage* GenericChatForm::genSystemInfoAction(const QString &message, const QString &type, const QDateTime &datetime)
//{
// previousId = ToxID();
// QString date = datetime.toString(Settings::getInstance().getTimestampFormat());

View File

@ -78,7 +78,7 @@ protected:
//TODO: MessageActionPtr genMessageActionAction(const QString& author, QString message, bool isAction, const QDateTime &datetime); ///< Deprecated
// MessageActionPtr genMessageActionAction(const ToxID& author, QString message, bool isAction, const QDateTime &datetime);
// MessageActionPtr genSelfActionAction(QString message, bool isAction, const QDateTime &datetime);
// ChatActionPtr genSystemInfoAction(const QString &message, const QString &type, const QDateTime &datetime);
// ChatMessage* genSystemInfoAction(const QString &message, const QString &type, const QDateTime &datetime);
ToxID previousId;
QMenu menu;

View File

@ -687,10 +687,9 @@ void Widget::onFriendStatusChanged(int friendId, Status status)
default:
fStatus = tr("online", "contact status"); break;
}
//TODO:
// if (isActualChange)
// f->getChatForm()->addSystemInfoMessage(tr("%1 is now %2", "e.g. \"Dubslow is now online\"").arg(f->getDisplayedName()).arg(fStatus),
// "white", QDateTime::currentDateTime());
if (isActualChange)
f->getChatForm()->addSystemInfoMessage(tr("%1 is now %2", "e.g. \"Dubslow is now online\"").arg(f->getDisplayedName()).arg(fStatus),
"white", QDateTime::currentDateTime());
}
if (isActualChange && status != Status::Offline)

BIN
ui/chatArea/info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 791 B