Denio
4 years ago
committed by
GitHub
16 changed files with 548 additions and 386 deletions
@ -0,0 +1,40 @@ |
|||
#ifndef CHAT_H |
|||
#define CHAT_H |
|||
|
|||
class Chat // Chat Controller
|
|||
{ |
|||
private: |
|||
std::map<QString, ChatItem> chatItems; |
|||
QTableView* parent; |
|||
Ui::MainWindow* ui; |
|||
MainWindow* main; |
|||
std::map<QString, QString> cidMap; |
|||
std::map<QString, QString> requestZaddrMap; |
|||
public: |
|||
ChatModel() {}; |
|||
ChatModel(std::map<QString, ChatItem> chatItems); |
|||
ChatModel(std::vector<ChatItem> chatItems); |
|||
QString generateChatItemID(ChatItem item); // helper
|
|||
std::map<QString, ChatItem> getItems(); |
|||
void setItems(std::map<QString, ChatItem> items); |
|||
QString zaddr(); |
|||
void setItems(std::vector<ChatItem> items); |
|||
void renderChatBox(Ui::MainWindow* ui, QListView &view); // action
|
|||
void renderChatBox(Ui::MainWindow* ui, QListView *view); // action
|
|||
// void renderContactRequest();
|
|||
void triggerRequest(); |
|||
void showMessages(); |
|||
void clear(); |
|||
//void renderContactRequest(Ui::MainWindow* ui, QListView *view);
|
|||
void addMessage(ChatItem item); |
|||
void addMessage(QString timestamp, ChatItem item); |
|||
void addCid(QString tx, QString cid); |
|||
void addrequestZaddr(QString tx, QString requestZaddr); |
|||
QString getCidByTx(QString tx); |
|||
QString getrequestZaddrByTx(QString tx); |
|||
void killCidCache(); |
|||
void killrequestZaddrCache(); |
|||
|
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,148 @@ |
|||
#ifndef CHATDELEGATOR_H |
|||
#define CHATDELEGATOR_H |
|||
|
|||
#include <QString> |
|||
#include <QStandardItemModel> |
|||
#include <QAbstractItemDelegate> |
|||
#include <QPainter> |
|||
|
|||
class ListViewDelegate : public QAbstractItemDelegate |
|||
{ |
|||
int d_radius; |
|||
int d_toppadding; |
|||
int d_bottompadding; |
|||
int d_leftpadding; |
|||
int d_rightpadding; |
|||
int d_verticalmargin; |
|||
int d_horizontalmargin; |
|||
int d_pointerwidth; |
|||
int d_pointerheight; |
|||
float d_widthfraction; |
|||
public: |
|||
inline ListViewDelegate(QObject *parent = nullptr); |
|||
|
|||
protected: |
|||
inline void paint(QPainter *painter, QStyleOptionViewItem const &option, QModelIndex const &index) const; |
|||
inline QSize sizeHint(QStyleOptionViewItem const &option, QModelIndex const &index) const; |
|||
}; |
|||
|
|||
inline ListViewDelegate::ListViewDelegate(QObject *parent): QAbstractItemDelegate(parent), d_radius(5), d_toppadding(5), d_bottompadding(3), d_leftpadding(5), d_rightpadding(5), d_verticalmargin(15), d_horizontalmargin(10), d_pointerwidth(10), d_pointerheight(17), d_widthfraction(.7) |
|||
{ |
|||
|
|||
} |
|||
|
|||
inline void ListViewDelegate::paint(QPainter *painter, QStyleOptionViewItem const &option, QModelIndex const &index) const |
|||
{ |
|||
QTextDocument bodydoc; |
|||
QTextOption textOption(bodydoc.defaultTextOption()); |
|||
textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); |
|||
bodydoc.setDefaultTextOption(textOption); |
|||
bodydoc.setDefaultFont(QFont("Roboto", 12)); |
|||
QString bodytext(index.data(Qt::DisplayRole).toString()); |
|||
bodydoc.setHtml(bodytext); |
|||
qreal contentswidth = option.rect.width() * d_widthfraction - d_horizontalmargin - d_pointerwidth - d_leftpadding - d_rightpadding; |
|||
bodydoc.setTextWidth(contentswidth); |
|||
qreal bodyheight = bodydoc.size().height(); |
|||
bool outgoing = index.data(Qt::UserRole + 1).toString() == "Outgoing"; |
|||
painter->save(); |
|||
painter->setRenderHint(QPainter::Antialiasing); |
|||
|
|||
// uncomment to see the area provided to paint this item
|
|||
|
|||
//painter->drawRect(option.rect);
|
|||
|
|||
painter->translate(option.rect.left() + d_horizontalmargin, option.rect.top() + ((index.row() == 0) ? d_verticalmargin : 0)); |
|||
|
|||
// background color for chat bubble
|
|||
QColor bgcolor("#535353"); |
|||
if (outgoing) |
|||
bgcolor = "#eeeeee"; |
|||
|
|||
// create chat bubble
|
|||
QPainterPath pointie; |
|||
|
|||
// left bottom
|
|||
pointie.moveTo(0, bodyheight + d_toppadding + d_bottompadding); |
|||
|
|||
// right bottom
|
|||
pointie.lineTo(0 + contentswidth + d_pointerwidth + d_leftpadding + d_rightpadding - d_radius, |
|||
bodyheight + d_toppadding + d_bottompadding); |
|||
pointie.arcTo(0 + contentswidth + d_pointerwidth + d_leftpadding + d_rightpadding - 2 * d_radius, |
|||
bodyheight + d_toppadding + d_bottompadding - 2 * d_radius, |
|||
2 * d_radius, 2 * d_radius, 270, 90); |
|||
|
|||
// right top
|
|||
pointie.lineTo(0 + contentswidth + d_pointerwidth + d_leftpadding + d_rightpadding, 0 + d_radius); |
|||
pointie.arcTo(0 + contentswidth + d_pointerwidth + d_leftpadding + d_rightpadding - 2 * d_radius, 0, |
|||
2 * d_radius, 2 * d_radius, 0, 90); |
|||
|
|||
// left top
|
|||
pointie.lineTo(0 + d_pointerwidth + d_radius, 0); |
|||
pointie.arcTo(0 + d_pointerwidth, 0, 2 * d_radius, 2 * d_radius, 90, 90); |
|||
|
|||
// left bottom almost (here is the pointie)
|
|||
pointie.lineTo(0 + d_pointerwidth, bodyheight + d_toppadding + d_bottompadding - d_pointerheight); |
|||
pointie.closeSubpath(); |
|||
|
|||
// rotate bubble for outgoing messages
|
|||
if (outgoing) |
|||
{ |
|||
painter->translate(option.rect.width() - pointie.boundingRect().width() - d_horizontalmargin - d_pointerwidth, 0); |
|||
painter->translate(pointie.boundingRect().center()); |
|||
painter->rotate(180); |
|||
painter->translate(-pointie.boundingRect().center()); |
|||
} |
|||
|
|||
// now paint it!
|
|||
painter->setPen(QPen(bgcolor)); |
|||
painter->drawPath(pointie); |
|||
painter->fillPath(pointie, QBrush(bgcolor)); |
|||
|
|||
// rotate back or painter is going to paint the text rotated...
|
|||
if (outgoing) |
|||
{ |
|||
painter->translate(pointie.boundingRect().center()); |
|||
painter->rotate(-180); |
|||
painter->translate(-pointie.boundingRect().center()); |
|||
} |
|||
|
|||
// set text color used to draw message body
|
|||
QAbstractTextDocumentLayout::PaintContext ctx; |
|||
if (outgoing) |
|||
ctx.palette.setColor(QPalette::Text, QColor("black")); |
|||
else |
|||
ctx.palette.setColor(QPalette::Text, QColor("white")); |
|||
|
|||
// draw body text
|
|||
painter->translate((outgoing ? 0 : d_pointerwidth) + d_leftpadding, 0); |
|||
bodydoc.documentLayout()->draw(painter, ctx); |
|||
|
|||
painter->restore(); |
|||
} |
|||
|
|||
inline QSize ListViewDelegate::sizeHint(QStyleOptionViewItem const &option, QModelIndex const &index) const |
|||
{ |
|||
QTextDocument bodydoc; |
|||
QTextOption textOption(bodydoc.defaultTextOption()); |
|||
textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); |
|||
bodydoc.setDefaultTextOption(textOption); |
|||
bodydoc.setDefaultFont(QFont("Roboto", 12)); |
|||
QString bodytext(index.data(Qt::DisplayRole).toString()); |
|||
bodydoc.setHtml(bodytext); |
|||
|
|||
// the width of the contents are the (a fraction of the window width) minus (margins + padding + width of the bubble's tail)
|
|||
qreal contentswidth = option.rect.width() * d_widthfraction - d_horizontalmargin - d_pointerwidth - d_leftpadding - d_rightpadding; |
|||
|
|||
// set this available width on the text document
|
|||
bodydoc.setTextWidth(contentswidth); |
|||
|
|||
QSize size(bodydoc.idealWidth() + d_horizontalmargin + d_pointerwidth + d_leftpadding + d_rightpadding, |
|||
bodydoc.size().height() + d_bottompadding + d_toppadding + d_verticalmargin + 1); // I dont remember why +1, haha, might not be necessary
|
|||
|
|||
if (index.row() == 0) // have extra margin at top of first item
|
|||
size += QSize(0, d_verticalmargin); |
|||
|
|||
return size; |
|||
} |
|||
|
|||
#endif |
@ -0,0 +1,28 @@ |
|||
#include "ChatIDGenerator.h" |
|||
|
|||
ChatIDGenerator* ChatIDGenerator::getInstance() |
|||
{ |
|||
if(ChatIDGenerator::instance == nullptr) |
|||
ChatIDGenerator::instance = new ChatIDGenerator(); |
|||
|
|||
return ChatIDGenerator::instance; |
|||
} |
|||
|
|||
QString ChatIDGenerator::generateID(ChatItem item) |
|||
{ |
|||
QString key = QString::number(item.getTimestamp()) + QString("-"); |
|||
key += QString( |
|||
QCryptographicHash::hash( |
|||
QString( |
|||
QString::number(item.getTimestamp()) + |
|||
item.getAddress() + |
|||
item.getContact() + |
|||
item.getMemo() |
|||
).toUtf8(), |
|||
QCryptographicHash::Md5 |
|||
).toHex() |
|||
); |
|||
return key; |
|||
} |
|||
|
|||
ChatIDGenerator* ChatIDGenerator::instance = nullptr; |
@ -0,0 +1,18 @@ |
|||
#ifndef CHATIDGENERATOR_H |
|||
#define CHATIDGENERATOR_H |
|||
|
|||
#include <QString> |
|||
#include <QUuid> |
|||
#include "../../Model/ChatItem.h" |
|||
|
|||
class ChatIDGenerator |
|||
{ |
|||
private: |
|||
static ChatIDGenerator* instance; |
|||
|
|||
public: |
|||
static ChatIDGenerator* getInstance(); |
|||
QString generateID(ChatItem item); |
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,135 @@ |
|||
#include "ChatItem.h" |
|||
|
|||
ChatItem::ChatItem() {} |
|||
|
|||
ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid) |
|||
{ |
|||
_timestamp = timestamp; |
|||
_address = address; |
|||
_contact = contact; |
|||
_memo = memo; |
|||
_requestZaddr = requestZaddr; |
|||
_type = type; |
|||
_cid = cid; |
|||
_txid = txid; |
|||
_outgoing = false; |
|||
} |
|||
|
|||
ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, bool outgoing) |
|||
{ |
|||
_timestamp = timestamp; |
|||
_address = address; |
|||
_contact = contact; |
|||
_memo = memo; |
|||
_requestZaddr = requestZaddr; |
|||
_type = type; |
|||
_cid = cid; |
|||
_txid = txid; |
|||
_outgoing = outgoing; |
|||
} |
|||
|
|||
long ChatItem::getTimestamp() |
|||
{ |
|||
return _timestamp; |
|||
} |
|||
|
|||
QString ChatItem::getAddress() |
|||
{ |
|||
return _address; |
|||
} |
|||
|
|||
QString ChatItem::getContact() |
|||
{ |
|||
return _contact; |
|||
} |
|||
|
|||
QString ChatItem::getMemo() |
|||
{ |
|||
return _memo; |
|||
} |
|||
|
|||
QString ChatItem::getRequestZaddr() |
|||
{ |
|||
return _requestZaddr; |
|||
} |
|||
QString ChatItem::getType() |
|||
{ |
|||
return _type; |
|||
} |
|||
|
|||
QString ChatItem::getCid() |
|||
{ |
|||
return _cid; |
|||
} |
|||
|
|||
QString ChatItem::getTxid() |
|||
{ |
|||
return _txid; |
|||
} |
|||
|
|||
bool ChatItem::isOutgoing() |
|||
{ |
|||
return _outgoing; |
|||
} |
|||
|
|||
void ChatItem::setTimestamp(long timestamp) |
|||
{ |
|||
_timestamp = timestamp; |
|||
} |
|||
|
|||
void ChatItem::setAddress(QString address) |
|||
{ |
|||
_address = address; |
|||
} |
|||
|
|||
void ChatItem::setContact(QString contact) |
|||
{ |
|||
_contact = contact; |
|||
} |
|||
|
|||
void ChatItem::setMemo(QString memo) |
|||
{ |
|||
_memo = memo; |
|||
} |
|||
|
|||
void ChatItem::setRequestZaddr(QString requestZaddr) |
|||
{ |
|||
_requestZaddr = requestZaddr; |
|||
} |
|||
|
|||
void ChatItem::setType(QString type) |
|||
{ |
|||
_type = type; |
|||
} |
|||
|
|||
void ChatItem::setCid(QString cid) |
|||
{ |
|||
_cid = cid; |
|||
} |
|||
void ChatItem::setTxid(QString txid) |
|||
{ |
|||
_txid = txid; |
|||
} |
|||
|
|||
void ChatItem::toggleOutgo() |
|||
{ |
|||
_outgoing = true; |
|||
} |
|||
|
|||
QString ChatItem::toChatLine() |
|||
{ |
|||
QDateTime myDateTime; |
|||
myDateTime.setTime_t(_timestamp); |
|||
QString line = QString("[") + myDateTime.toString("d.M.yy hh:mm") + QString("] "); |
|||
line += QString("") + QString(_memo) + QString("\n\n"); |
|||
return line; |
|||
} |
|||
|
|||
ChatItem::~ChatItem() |
|||
{ |
|||
/*delete timestamp;
|
|||
delete address; |
|||
delete contact; |
|||
delete memo; |
|||
delete outgoing;*/ |
|||
} |
@ -0,0 +1,45 @@ |
|||
#ifndef CHATITEM_H |
|||
#define CHATITEM_H |
|||
|
|||
#include <QString> |
|||
|
|||
class ChatItem |
|||
{ |
|||
private: |
|||
long _timestamp; |
|||
QString _address; |
|||
QString _contact; |
|||
QString _memo; |
|||
QString _requestZaddr; |
|||
QString _type; |
|||
QString _cid; |
|||
QString _txid; |
|||
bool _outgoing = false; |
|||
|
|||
public: |
|||
ChatItem(); |
|||
ChatItem(long timestamp, QString address, QString contact, QString memo,QString requestZaddr, QString type, QString cid, QString txid); |
|||
ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, bool outgoing); |
|||
long getTimestamp(); |
|||
QString getAddress(); |
|||
QString getContact(); |
|||
QString getMemo(); |
|||
QString getRequestZaddr(); |
|||
QString getType(); |
|||
QString getCid(); |
|||
QString getTxid(); |
|||
bool isOutgoing(); |
|||
void setTimestamp(long timestamp); |
|||
void setAddress(QString address); |
|||
void setContact(QString contact); |
|||
void setMemo(QString memo); |
|||
void setRequestZaddr(QString requestZaddr); |
|||
void setType(QString type); |
|||
void setCid(QString cid); |
|||
void setTxid(QString txid); |
|||
void toggleOutgo(); |
|||
QString toChatLine(); |
|||
~ChatItem(); |
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,66 @@ |
|||
#include "ContactItem.h" |
|||
|
|||
ContactItem::ContactItem() {} |
|||
|
|||
ContactItem::ContactItem(QString name, QString partnerAddress, QString myAddress, QString cid, QString avatar) |
|||
{ |
|||
_name = name; |
|||
_myAddress = myAddress; |
|||
_partnerAddress = partnerAddress; |
|||
_cid = cid; |
|||
_avatar = avatar; |
|||
} |
|||
|
|||
QString ContactItem::getName() const |
|||
{ |
|||
return _name; |
|||
} |
|||
|
|||
QString ContactItem::getMyAddress() const |
|||
{ |
|||
return _myAddress; |
|||
} |
|||
|
|||
QString ContactItem::getPartnerAddress() const |
|||
{ |
|||
return _partnerAddress; |
|||
} |
|||
|
|||
QString ContactItem::getCid() const |
|||
{ |
|||
return _cid; |
|||
} |
|||
|
|||
QString ContactItem::getAvatar() const |
|||
{ |
|||
return _avatar; |
|||
} |
|||
|
|||
void ContactItem::setName(QString name) |
|||
{ |
|||
_name = name; |
|||
} |
|||
|
|||
void ContactItem::setMyAddress(QString myAddress) |
|||
{ |
|||
_myAddress = myAddress; |
|||
} |
|||
|
|||
void ContactItem::setPartnerAddress(QString partnerAddress) |
|||
{ |
|||
_partnerAddress = partnerAddress; |
|||
} |
|||
|
|||
void ContactItem::setcid(QString cid) |
|||
{ |
|||
_cid = cid; |
|||
} |
|||
void ContactItem::setAvatar(QString avatar) |
|||
{ |
|||
_avatar = avatar; |
|||
} |
|||
|
|||
QString ContactItem::toQTString() |
|||
{ |
|||
return _name + "|" + _partnerAddress + "|" + _myAddress + "|" + _cid + "|" + _avatar; |
|||
} |
@ -0,0 +1,32 @@ |
|||
#ifndef CONTACTITEM_H |
|||
#define CONTACTITEM_H |
|||
|
|||
#include <vector> |
|||
#include <QString> |
|||
|
|||
class ContactItem |
|||
{ |
|||
private: |
|||
QString _myAddress; |
|||
QString _partnerAddress; |
|||
QString _name; |
|||
QString _cid; |
|||
QString _avatar; |
|||
|
|||
public: |
|||
ContactItem(); |
|||
ContactItem(QString name, QString partnerAddress, QString myAddress, QString cid, QString avatar); |
|||
QString getName() const; |
|||
QString getMyAddress() const; |
|||
QString getPartnerAddress() const; |
|||
QString getCid() const; |
|||
QString getAvatar() const; |
|||
void setName(QString name); |
|||
void setMyAddress(QString myAddress); |
|||
void setPartnerAddress(QString partnerAddress); |
|||
void setcid(QString cid); |
|||
void setAvatar(QString avatar); |
|||
QString toQTString(); |
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1 @@ |
|||
#include "ContactRequestChatItem.h" |
@ -0,0 +1,11 @@ |
|||
#ifdef CONTACTREQUESTCHATITEM_H |
|||
#define CONTACTREQUESTCHATITEM_H |
|||
|
|||
#include "ChatItem.h" |
|||
|
|||
class ContactRequestChatItem : ChatItem |
|||
{ |
|||
|
|||
}; |
|||
|
|||
#endif |
Loading…
Reference in new issue