1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

new chat beginning

This commit is contained in:
apprb 2014-09-06 02:27:26 +07:00
parent 502229a6f2
commit 25ee6a24d9
15 changed files with 875 additions and 148 deletions

274
filetransferinstance.cpp Normal file
View File

@ -0,0 +1,274 @@
/*
Copyright (C) 2014 by Project Tox <https://tox.im>
This file is part of qTox, a Qt-based graphical interface for Tox.
This program is libre 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 3 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 COPYING file for more details.
*/
#include "filetransferinstance.h"
#include "widget/widget.h"
#include "core.h"
#include "math.h"
#include "style.h"
#include <QFileDialog>
#include <QPixmap>
#include <QPainter>
#include <QMessageBox>
#include <QBuffer>
uint FileTransferInstance::Idconter = 0;
FileTransferInstance::FileTransferInstance(ToxFile File)
: lastUpdate{QDateTime::currentDateTime()}, lastBytesSent{0},
fileNum{File.fileNum}, friendId{File.friendId}, direction{File.direction}
{
id = Idconter++;
state = tsPending;
filename = File.fileName;
size = getHumanReadableSize(File.filesize);
speed = "0B/s";
eta = "00:00";
if (File.direction == ToxFile::SENDING)
{
QImage preview;
File.file->seek(0);
if (preview.loadFromData(File.file->readAll()))
{
pic = preview.scaledToHeight(40);
}
File.file->seek(0);
}
}
QString FileTransferInstance::getHumanReadableSize(unsigned long long size)
{
static const char* suffix[] = {"B","kiB","MiB","GiB","TiB"};
int exp = 0;
if (size)
exp = std::min( (int) (log(size) / log(1024)), (int) (sizeof(suffix) / sizeof(suffix[0]) - 1));
return QString().setNum(size / pow(1024, exp),'f',2).append(suffix[exp]);
}
void FileTransferInstance::onFileTransferInfo(int FriendId, int FileNum, int64_t Filesize, int64_t BytesSent, ToxFile::FileDirection Direction)
{
if (FileNum != fileNum || FriendId != friendId || Direction != direction)
return;
// state = tsProcessing;
QDateTime newtime = QDateTime::currentDateTime();
int timediff = lastUpdate.secsTo(newtime);
if (timediff <= 0)
return;
qint64 diff = BytesSent - lastBytesSent;
if (diff < 0)
{
qWarning() << "FileTransferInstance::onFileTransferInfo: Negative transfer speed !";
diff = 0;
}
long rawspeed = diff / timediff;
speed = getHumanReadableSize(rawspeed)+"/s";
size = getHumanReadableSize(Filesize);
if (!rawspeed)
return;
int etaSecs = (Filesize - BytesSent) / rawspeed;
QTime etaTime(0,0);
etaTime = etaTime.addSecs(etaSecs);
eta = etaTime.toString("mm:ss");
lastUpdate = newtime;
lastBytesSent = BytesSent;
emit stateUpdated();
}
void FileTransferInstance::onFileTransferCancelled(int FriendId, int FileNum, ToxFile::FileDirection Direction)
{
if (FileNum != fileNum || FriendId != friendId || Direction != direction)
return;
disconnect(Widget::getInstance()->getCore(),0,this,0);
state = tsCanceled;
emit stateUpdated();
}
void FileTransferInstance::onFileTransferFinished(ToxFile File)
{
if (File.fileNum != fileNum || File.friendId != friendId || File.direction != direction)
return;
disconnect(Widget::getInstance()->getCore(),0,this,0);
if (File.direction == ToxFile::RECEIVING)
{
QPixmap preview;
QFile previewFile(File.filePath);
if (previewFile.open(QIODevice::ReadOnly) && previewFile.size() <= 1024*1024*25) // Don't preview big (>25MiB) images
{
if (preview.loadFromData(previewFile.readAll()))
{
preview = preview.scaledToHeight(40);
// pic->setPixmap(preview);
}
previewFile.close();
}
}
state = tsFinished;
emit stateUpdated();
}
void FileTransferInstance::cancelTransfer()
{
Widget::getInstance()->getCore()->cancelFileSend(friendId, fileNum);
state = tsCanceled;
emit stateUpdated();
}
void FileTransferInstance::rejectRecvRequest()
{
Widget::getInstance()->getCore()->rejectFileRecvRequest(friendId, fileNum);
onFileTransferCancelled(friendId, fileNum, direction);
state = tsCanceled;
emit stateUpdated();
}
// for whatever the fuck reason, QFileInfo::isWritable() always fails for files that don't exist
// which makes it useless for our case
// since QDir doesn't have an isWritable(), the only option I can think of is to make/delete the file
// surely this is a common problem that has a qt-implemented solution?
bool isFileWritable(QString& path)
{
QFile file(path);
bool exists = file.exists();
bool out = file.open(QIODevice::WriteOnly);
file.close();
if (!exists)
file.remove();
return out;
}
void FileTransferInstance::acceptRecvRequest()
{
QString path;
while (true)
{
path = QFileDialog::getSaveFileName(Widget::getInstance(), tr("Save a file","Title of the file saving dialog"), QDir::current().filePath(filename));
if (path.isEmpty())
return;
else
{
//bool savable = QFileInfo(path).isWritable();
//qDebug() << path << " is writable: " << savable;
//qDebug() << "/home/bill/bliss.pdf writable: " << QFileInfo("/home/bill/bliss.pdf").isWritable();
if (isFileWritable(path))
break;
else
QMessageBox::warning(Widget::getInstance(), tr("Location not writable","Title of permissions popup"), tr("You do not have permission to write that location. Choose another, or cancel the save dialog.", "text of permissions popup"));
}
}
savePath = path;
Widget::getInstance()->getCore()->acceptFileRecvRequest(friendId, fileNum, path);
state = tsProcessing;
emit stateUpdated();
}
void FileTransferInstance::pauseResumeRecv()
{
Widget::getInstance()->getCore()->pauseResumeFileRecv(friendId, fileNum);
if (state == tsProcessing)
state = tsPaused;
else state = tsProcessing;
emit stateUpdated();
}
void FileTransferInstance::pauseResumeSend()
{
Widget::getInstance()->getCore()->pauseResumeFileSend(friendId, fileNum);
if (state == tsProcessing)
state = tsPaused;
else state = tsProcessing;
emit stateUpdated();
}
QString FileTransferInstance::getHtmlImage()
{
qDebug() << "QString FileTransferInstance::getHtmlImage()";
auto QImage2base64 = [](const QImage &img)
{
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
img.save(&buffer, "PNG"); // writes image into ba in PNG format
return ba.toBase64();
};
QString res;
if (state == tsPending || state == tsProcessing || state == tsPaused)
{
QImage rightUp(":ui/stopFileButton/default.png");
QImage rightDown(":ui/acceptFileButton/default.png");
QString widgetId = QString::number(getId());
QString strUp = "<img src=\"data:ftrans." + widgetId + ".top/png;base64," + QImage2base64(rightUp) + "\">";
QString strDown = "<img src=\"data:ftrans." + widgetId + ".bottom/png;base64," + QImage2base64(rightDown) + "\">";
res = "<table widht=100% cellspacing=\"2\">\n";
res += "<tr>\n<td width=100%>\n";
res += "<div class=quote><p>PROCESSING</p><p>" + filename + "</p><p>" + size + "</p></div>\n";
res += "</td>\n<td>\n";
res += "<table cellspacing=\"0\"><tr valign=top><td>" + strUp + "</td></tr><tr valign=bottom><td>" + strDown + "</td></tr></table>\n";
res += "</td>\n</tr>\n";
res += "</table>\n";
} else if (state == tsCanceled)
{
res = "<table widht=100% cellspacing=\"2\">\n";
res += "<tr>\n<td width=100%>\n";
res += "<div class=quote><p>CANCELED</p><p>" + filename + "</p><p>" + size + "</p></div>\n";
res += "</td>\n</tr>\n";
res += "</table>\n";
} else if (state == tsFinished)
{
res = "<table widht=100% cellspacing=\"2\">\n";
res += "<tr>\n<td width=100%>\n";
res += "<div class=quote><p>FINISHED</p><p>" + filename + "</p><p>" + size + "</p></div>\n";
res += "</td>\n</tr>\n";
res += "</table>\n";
}
return res;
}
void FileTransferInstance::pressFromHtml(QString code)
{
if (state == tsFinished || state == tsCanceled)
return;
if (direction == ToxFile::SENDING)
{
if (code == "top")
cancelTransfer();
else if (code == "bottom")
pauseResumeSend();
} else {
if (code == "top")
rejectRecvRequest();
else if (code == "bottom")
{
if (state == tsPending)
acceptRecvRequest();
else
pauseResumeRecv();
}
}
}

76
filetransferinstance.h Normal file
View File

@ -0,0 +1,76 @@
/*
Copyright (C) 2014 by Project Tox <https://tox.im>
This file is part of qTox, a Qt-based graphical interface for Tox.
This program is libre 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 3 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 COPYING file for more details.
*/
#ifndef FILETRANSFERINSTANCE_H
#define FILETRANSFERINSTANCE_H
#include <QObject>
#include <QLabel>
#include <QPushButton>
#include <QProgressBar>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QDateTime>
#include "core.h"
struct ToxFile;
class FileTransferInstance : public QObject
{
Q_OBJECT
public:
explicit FileTransferInstance(ToxFile File);
QString getHtmlImage();
uint getId(){return id;}
public slots:
void onFileTransferInfo(int FriendId, int FileNum, int64_t Filesize, int64_t BytesSent, ToxFile::FileDirection Direction);
void onFileTransferCancelled(int FriendId, int FileNum, ToxFile::FileDirection Direction);
void onFileTransferFinished(ToxFile File);
void pressFromHtml(QString);
signals:
void stateUpdated();
private slots:
void cancelTransfer();
void rejectRecvRequest();
void acceptRecvRequest();
void pauseResumeRecv();
void pauseResumeSend();
private:
QString getHumanReadableSize(unsigned long long size);
private:
enum TransfState {tsPending, tsProcessing, tsPaused, tsFinished, tsCanceled};
static uint Idconter;
uint id;
TransfState state;
QImage pic;
QString filename, size, speed, eta;
QDateTime lastUpdate;
long long lastBytesSent;
int fileNum;
int friendId;
QString savePath;
ToxFile::FileDirection direction;
QString stopFileButtonStylesheet, pauseFileButtonStylesheet, acceptFileButtonStylesheet;
};
#endif // FILETRANSFERINSTANCE_H

View File

@ -102,7 +102,10 @@ HEADERS += widget/form/addfriendform.h \
widget/croppinglabel.h \ widget/croppinglabel.h \
widget/friendlistwidget.h \ widget/friendlistwidget.h \
widget/genericchatroomwidget.h \ widget/genericchatroomwidget.h \
widget/form/genericchatform.h widget/form/genericchatform.h \
widget/tool/genericchataction.h \
widget/chatareawidget.h \
filetransferinstance.h
SOURCES += \ SOURCES += \
widget/form/addfriendform.cpp \ widget/form/addfriendform.cpp \
@ -136,4 +139,7 @@ SOURCES += \
widget/friendlistwidget.cpp \ widget/friendlistwidget.cpp \
coreav.cpp \ coreav.cpp \
widget/genericchatroomwidget.cpp \ widget/genericchatroomwidget.cpp \
widget/form/genericchatform.cpp widget/form/genericchatform.cpp \
widget/tool/genericchataction.cpp \
widget/chatareawidget.cpp \
filetransferinstance.cpp

View File

@ -42,6 +42,7 @@
<file>ui/callButton/callButtonYellowHover.png</file> <file>ui/callButton/callButtonYellowHover.png</file>
<file>ui/callButton/callButtonYellowPressed.png</file> <file>ui/callButton/callButtonYellowPressed.png</file>
<file>ui/chatArea/chatArea.css</file> <file>ui/chatArea/chatArea.css</file>
<file>ui/chatArea/innerStyle.css</file>
<file>ui/chatArea/scrollBarDownArrow.png</file> <file>ui/chatArea/scrollBarDownArrow.png</file>
<file>ui/chatArea/scrollBarDownArrowHover.png</file> <file>ui/chatArea/scrollBarDownArrowHover.png</file>
<file>ui/chatArea/scrollBarDownArrowPressed.png</file> <file>ui/chatArea/scrollBarDownArrowPressed.png</file>
@ -57,6 +58,7 @@
<file>ui/fileButton/fileButton.png</file> <file>ui/fileButton/fileButton.png</file>
<file>ui/fileButton/fileButtonHover.png</file> <file>ui/fileButton/fileButtonHover.png</file>
<file>ui/fileButton/fileButtonPressed.png</file> <file>ui/fileButton/fileButtonPressed.png</file>
<file>ui/fileButton/fileButtonDisabled.png</file>
<file>ui/msgEdit/msgEdit.css</file> <file>ui/msgEdit/msgEdit.css</file>
<file>ui/pauseFileButton/default.png</file> <file>ui/pauseFileButton/default.png</file>
<file>ui/pauseFileButton/hover.png</file> <file>ui/pauseFileButton/hover.png</file>
@ -124,6 +126,5 @@
<file>ui/micButton/micButtonPressed.png</file> <file>ui/micButton/micButtonPressed.png</file>
<file>ui/micButton/micButton.css</file> <file>ui/micButton/micButton.css</file>
<file>ui/volButton/volButton.css</file> <file>ui/volButton/volButton.css</file>
<file>ui/fileButton/fileButtonDisabled.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -0,0 +1,37 @@
div.name_me {
color: #646464;
font-weight: bold;
padding-right: 3px;
}
div.message_me {
color: #646464;
padding-right: 3px;
padding-left: 3px;
}
div.date_me {
color: #646464;
padding-left: 3px;
}
div.quote {
background-color: #6bc260;
}
div.name {
color: #000000;
font-weight: bold;
padding-right: 3px;
}
div.message {
color: #000000;
padding-right: 3px;
padding-left: 3px;
}
div.date {
color: #000000;
padding-left: 3px;
}

56
widget/chatareawidget.cpp Normal file
View File

@ -0,0 +1,56 @@
/*
Copyright (C) 2014 by Project Tox <https://tox.im>
This file is part of qTox, a Qt-based graphical interface for Tox.
This program is libre 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 3 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 COPYING file for more details.
*/
#include "chatareawidget.h"
#include <QAbstractTextDocumentLayout>
#include <QMessageBox>
ChatAreaWidget::ChatAreaWidget(QWidget *parent) :
QTextEdit(parent)
{
setReadOnly(true);
viewport()->setCursor(Qt::ArrowCursor);
setContextMenuPolicy(Qt::CustomContextMenu);
}
void ChatAreaWidget::mouseReleaseEvent(QMouseEvent * event)
{
QTextEdit::mouseReleaseEvent(event);
int pos = this->document()->documentLayout()->hitTest(event->pos(), Qt::ExactHit);
if (pos > 0)
{
QTextCursor cursor(document());
cursor.setPosition(pos);
if( ! cursor.atEnd() )
{
cursor.setPosition(pos+1);
QTextFormat format = cursor.charFormat();
if (format.isImageFormat())
{
QString image = format.toImageFormat().name();
if (QRegExp("^data:ftrans.*").exactMatch(image))
{
image = image.right(image.length() - 12);
int endpos = image.indexOf("/png;base64");
image = image.left(endpos);
int middlepos = image.indexOf(".");
emit onFileTranfertInterract(image.left(middlepos),image.right(image.length() - middlepos - 1));
}
}
}
}
}

38
widget/chatareawidget.h Normal file
View File

@ -0,0 +1,38 @@
/*
Copyright (C) 2014 by Project Tox <https://tox.im>
This file is part of qTox, a Qt-based graphical interface for Tox.
This program is libre 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 3 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 COPYING file for more details.
*/
#ifndef CHATAREAWIDGET_H
#define CHATAREAWIDGET_H
#include <QTextEdit>
class ChatAreaWidget : public QTextEdit
{
Q_OBJECT
public:
explicit ChatAreaWidget(QWidget *parent = 0);
signals:
void onFileTranfertInterract(QString widgetName, QString buttonName);
protected:
void mouseReleaseEvent(QMouseEvent * event);
public slots:
};
#endif // CHATAREAWIDGET_H

View File

@ -23,11 +23,15 @@
#include <QPixmap> #include <QPixmap>
#include <QPainter> #include <QPainter>
#include <QMessageBox> #include <QMessageBox>
#include <QBuffer>
uint FileTransfertWidget::Idconter = 0;
FileTransfertWidget::FileTransfertWidget(ToxFile File) FileTransfertWidget::FileTransfertWidget(ToxFile File)
: lastUpdate{QDateTime::currentDateTime()}, lastBytesSent{0}, : lastUpdate{QDateTime::currentDateTime()}, lastBytesSent{0},
fileNum{File.fileNum}, friendId{File.friendId}, direction{File.direction} fileNum{File.fileNum}, friendId{File.friendId}, direction{File.direction}
{ {
id = Idconter++;
pic=new QLabel(), filename=new QLabel(), size=new QLabel(), speed=new QLabel(), eta=new QLabel(); pic=new QLabel(), filename=new QLabel(), size=new QLabel(), speed=new QLabel(), eta=new QLabel();
topright = new QPushButton(), bottomright = new QPushButton(); topright = new QPushButton(), bottomright = new QPushButton();
progress = new QProgressBar(); progress = new QProgressBar();
@ -182,6 +186,7 @@ void FileTransfertWidget::onFileTransferInfo(int FriendId, int FileNum, int64_t
} }
lastUpdate = newtime; lastUpdate = newtime;
lastBytesSent = BytesSent; lastBytesSent = BytesSent;
emit stateUpdated();
} }
void FileTransfertWidget::onFileTransferCancelled(int FriendId, int FileNum, ToxFile::FileDirection Direction) void FileTransfertWidget::onFileTransferCancelled(int FriendId, int FileNum, ToxFile::FileDirection Direction)
@ -206,6 +211,8 @@ void FileTransfertWidget::onFileTransferCancelled(int FriendId, int FileNum, Tox
//Toggle window visibility to fix draw order bug //Toggle window visibility to fix draw order bug
this->hide(); this->hide();
this->show(); this->show();
emit stateUpdated();
} }
void FileTransfertWidget::onFileTransferFinished(ToxFile File) void FileTransfertWidget::onFileTransferFinished(ToxFile File)
@ -245,17 +252,21 @@ void FileTransfertWidget::onFileTransferFinished(ToxFile File)
previewFile.close(); previewFile.close();
} }
} }
emit stateUpdated();
} }
void FileTransfertWidget::cancelTransfer() void FileTransfertWidget::cancelTransfer()
{ {
Widget::getInstance()->getCore()->cancelFileSend(friendId, fileNum); Widget::getInstance()->getCore()->cancelFileSend(friendId, fileNum);
emit stateUpdated();
} }
void FileTransfertWidget::rejectRecvRequest() void FileTransfertWidget::rejectRecvRequest()
{ {
Widget::getInstance()->getCore()->rejectFileRecvRequest(friendId, fileNum); Widget::getInstance()->getCore()->rejectFileRecvRequest(friendId, fileNum);
onFileTransferCancelled(friendId, fileNum, direction); onFileTransferCancelled(friendId, fileNum, direction);
emit stateUpdated();
} }
// for whatever the fuck reason, QFileInfo::isWritable() always fails for files that don't exist // for whatever the fuck reason, QFileInfo::isWritable() always fails for files that don't exist
@ -299,16 +310,20 @@ void FileTransfertWidget::acceptRecvRequest()
bottomright->disconnect(); bottomright->disconnect();
connect(bottomright, SIGNAL(clicked()), this, SLOT(pauseResumeRecv())); connect(bottomright, SIGNAL(clicked()), this, SLOT(pauseResumeRecv()));
Widget::getInstance()->getCore()->acceptFileRecvRequest(friendId, fileNum, path); Widget::getInstance()->getCore()->acceptFileRecvRequest(friendId, fileNum, path);
emit stateUpdated();
} }
void FileTransfertWidget::pauseResumeRecv() void FileTransfertWidget::pauseResumeRecv()
{ {
Widget::getInstance()->getCore()->pauseResumeFileRecv(friendId, fileNum); Widget::getInstance()->getCore()->pauseResumeFileRecv(friendId, fileNum);
emit stateUpdated();
} }
void FileTransfertWidget::pauseResumeSend() void FileTransfertWidget::pauseResumeSend()
{ {
Widget::getInstance()->getCore()->pauseResumeFileSend(friendId, fileNum); Widget::getInstance()->getCore()->pauseResumeFileSend(friendId, fileNum);
emit stateUpdated();
} }
void FileTransfertWidget::paintEvent(QPaintEvent *) void FileTransfertWidget::paintEvent(QPaintEvent *)
@ -317,4 +332,56 @@ void FileTransfertWidget::paintEvent(QPaintEvent *)
opt.init(this); opt.init(this);
QPainter p(this); QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
emit stateUpdated();
}
QString FileTransfertWidget::getHtmlImage()
{
qDebug() << "QString FileTransfertWidget::getHtmlImage()";
auto QImage2base64 = [](const QImage &img)
{
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
img.save(&buffer, "PNG"); // writes image into ba in PNG format
return ba.toBase64();
};
auto renderButton = [](QPushButton *pb)
{
QImage bitmap(pb->size(), QImage::Format_ARGB32);
bitmap.fill(Qt::transparent);
QPainter painter(&bitmap);
pb->render(&painter, QPoint(), QRegion(), QWidget::DrawChildren);
return bitmap;
};
// QImage rightUp = renderButton(topright);
// QImage rightDown = renderButton(bottomright);
QImage rightUp(":ui/stopFileButton/default.png");
QImage rightDown(":ui/acceptFileButton/default.png");
QString res;
QString widgetId = QString::number(getId());
QString strUp = "<img src=\"data:ftrans." + widgetId + ".top/png;base64," + QImage2base64(rightUp) + "\">";
QString strDown = "<img src=\"data:ftrans." + widgetId + ".bottom/png;base64," + QImage2base64(rightDown) + "\">";
res = "<table widht=100% cellspacing=\"2\">\n";
res += "<tr>\n<td width=100%>\n";
res += "<div class=quote></div>\n";
res += "</td>\n<td>\n";
if (topright->isVisible() && bottomright->isVisible())
res += "<table cellspacing=\"0\"><tr valign=top><td>" + strUp + "</td></tr><tr valign=bottom><td>" + strDown + "</td></tr></table>\n";
res += "</td>\n</tr>\n";
res += "</table>\n";
return res;
}
void FileTransfertWidget::pressFromHtml(QString code)
{
if (code == "top")
topright->clicked();
else if (code == "bottom")
bottomright->clicked();
} }

View File

@ -35,12 +35,19 @@ class FileTransfertWidget : public QWidget
public: public:
FileTransfertWidget(ToxFile File); FileTransfertWidget(ToxFile File);
QString getHtmlImage();
uint getId(){return id;}
public slots: public slots:
void onFileTransferInfo(int FriendId, int FileNum, int64_t Filesize, int64_t BytesSent, ToxFile::FileDirection Direction); void onFileTransferInfo(int FriendId, int FileNum, int64_t Filesize, int64_t BytesSent, ToxFile::FileDirection Direction);
void onFileTransferCancelled(int FriendId, int FileNum, ToxFile::FileDirection Direction); void onFileTransferCancelled(int FriendId, int FileNum, ToxFile::FileDirection Direction);
void onFileTransferFinished(ToxFile File); void onFileTransferFinished(ToxFile File);
void pressFromHtml(QString);
signals:
void stateUpdated();
private slots: private slots:
void cancelTransfer(); void cancelTransfer();
void rejectRecvRequest(); void rejectRecvRequest();
@ -52,6 +59,10 @@ private:
QString getHumanReadableSize(unsigned long long size); QString getHumanReadableSize(unsigned long long size);
private: private:
static uint Idconter;
uint id;
QLabel *pic, *filename, *size, *speed, *eta; QLabel *pic, *filename, *size, *speed, *eta;
QPushButton *topright, *bottomright; QPushButton *topright, *bottomright;
QProgressBar *progress; QProgressBar *progress;

View File

@ -43,6 +43,7 @@ ChatForm::ChatForm(Friend* chatFriend)
connect(videoButton, &QPushButton::clicked, this, &ChatForm::onVideoCallTriggered); connect(videoButton, &QPushButton::clicked, this, &ChatForm::onVideoCallTriggered);
connect(msgEdit, &ChatTextEdit::enterPressed, this, &ChatForm::onSendTriggered); connect(msgEdit, &ChatTextEdit::enterPressed, this, &ChatForm::onSendTriggered);
connect(micButton, SIGNAL(clicked()), this, SLOT(onMicMuteToggle())); connect(micButton, SIGNAL(clicked()), this, SLOT(onMicMuteToggle()));
connect(newChatForm, SIGNAL(onFileTranfertInterract(QString,QString)), this, SLOT(onFileTansBtnClicked(QString,QString)));
} }
ChatForm::~ChatForm() ChatForm::~ChatForm()
@ -94,36 +95,42 @@ void ChatForm::startFileSend(ToxFile file)
if (file.friendId != f->friendId) if (file.friendId != f->friendId)
return; return;
QLabel *author = new QLabel(Widget::getInstance()->getUsername()); // QLabel *author = new QLabel(Widget::getInstance()->getUsername());
QLabel *date = new QLabel(QTime::currentTime().toString("hh:mm")); // QLabel *date = new QLabel(QTime::currentTime().toString("hh:mm"));
QScrollBar* scroll = chatArea->verticalScrollBar(); // QScrollBar* scroll = chatArea->verticalScrollBar();
lockSliderToBottom = scroll && scroll->value() == scroll->maximum(); // lockSliderToBottom = scroll && scroll->value() == scroll->maximum();
author->setAlignment(Qt::AlignTop | Qt::AlignRight); // author->setAlignment(Qt::AlignTop | Qt::AlignRight);
date->setAlignment(Qt::AlignTop); // date->setAlignment(Qt::AlignTop);
QPalette pal; // QPalette pal;
pal.setColor(QPalette::WindowText, Qt::gray); // pal.setColor(QPalette::WindowText, Qt::gray);
author->setPalette(pal); // author->setPalette(pal);
if (previousName.isEmpty() || previousName != author->text()) // if (previousName.isEmpty() || previousName != author->text())
{ // {
if (curRow) // if (curRow)
{ // {
mainChatLayout->setRowStretch(curRow, 0); // mainChatLayout->setRowStretch(curRow, 0);
mainChatLayout->addItem(new QSpacerItem(0,AUTHOR_CHANGE_SPACING),curRow,0,1,3); // mainChatLayout->addItem(new QSpacerItem(0,AUTHOR_CHANGE_SPACING),curRow,0,1,3);
curRow++; // curRow++;
} // }
mainChatLayout->addWidget(author, curRow, 0); // mainChatLayout->addWidget(author, curRow, 0);
} // }
FileTransfertWidget* fileTrans = new FileTransfertWidget(file);
previousName = author->text();
mainChatLayout->addWidget(fileTrans, curRow, 1);
mainChatLayout->addWidget(date, curRow, 3);
mainChatLayout->setRowStretch(curRow+1, 1);
mainChatLayout->setRowStretch(curRow, 0);
curRow++;
connect(Widget::getInstance()->getCore(), &Core::fileTransferInfo, fileTrans, &FileTransfertWidget::onFileTransferInfo); FileTransferInstance* fileTrans = new FileTransferInstance(file);
connect(Widget::getInstance()->getCore(), &Core::fileTransferCancelled, fileTrans, &FileTransfertWidget::onFileTransferCancelled); ftransWidgets.insert(fileTrans->getId(), fileTrans);
connect(Widget::getInstance()->getCore(), &Core::fileTransferFinished, fileTrans, &FileTransfertWidget::onFileTransferFinished); // previousName = author->text();
// mainChatLayout->addWidget(fileTrans, curRow, 1);
// mainChatLayout->addWidget(date, curRow, 3);
// mainChatLayout->setRowStretch(curRow+1, 1);
// mainChatLayout->setRowStretch(curRow, 0);
// curRow++;
connect(Widget::getInstance()->getCore(), &Core::fileTransferInfo, fileTrans, &FileTransferInstance::onFileTransferInfo);
connect(Widget::getInstance()->getCore(), &Core::fileTransferCancelled, fileTrans, &FileTransferInstance::onFileTransferCancelled);
connect(Widget::getInstance()->getCore(), &Core::fileTransferFinished, fileTrans, &FileTransferInstance::onFileTransferFinished);
connect(fileTrans, SIGNAL(stateUpdated()), this, SLOT(updateChatContent()));
messages.append(new FileTransferAction(fileTrans, Widget::getInstance()->getUsername(), QTime::currentTime().toString("hh:mm")));
updateChatContent();
} }
void ChatForm::onFileRecvRequest(ToxFile file) void ChatForm::onFileRecvRequest(ToxFile file)
@ -131,33 +138,35 @@ void ChatForm::onFileRecvRequest(ToxFile file)
if (file.friendId != f->friendId) if (file.friendId != f->friendId)
return; return;
QLabel *author = new QLabel(f->getName()); // QLabel *author = new QLabel(f->getName());
QLabel *date = new QLabel(QTime::currentTime().toString("hh:mm")); // QLabel *date = new QLabel(QTime::currentTime().toString("hh:mm"));
QScrollBar* scroll = chatArea->verticalScrollBar(); // QScrollBar* scroll = chatArea->verticalScrollBar();
lockSliderToBottom = scroll && scroll->value() == scroll->maximum(); // lockSliderToBottom = scroll && scroll->value() == scroll->maximum();
author->setAlignment(Qt::AlignTop | Qt::AlignRight); // author->setAlignment(Qt::AlignTop | Qt::AlignRight);
date->setAlignment(Qt::AlignTop); // date->setAlignment(Qt::AlignTop);
if (previousName.isEmpty() || previousName != author->text()) // if (previousName.isEmpty() || previousName != author->text())
{ // {
if (curRow) // if (curRow)
{ // {
mainChatLayout->setRowStretch(curRow, 0); // mainChatLayout->setRowStretch(curRow, 0);
mainChatLayout->addItem(new QSpacerItem(0,AUTHOR_CHANGE_SPACING),curRow,0,1,3); // mainChatLayout->addItem(new QSpacerItem(0,AUTHOR_CHANGE_SPACING),curRow,0,1,3);
curRow++; // curRow++;
} // }
mainChatLayout->addWidget(author, curRow, 0); // mainChatLayout->addWidget(author, curRow, 0);
} // }
FileTransfertWidget* fileTrans = new FileTransfertWidget(file); FileTransferInstance* fileTrans = new FileTransferInstance(file);
previousName = author->text(); ftransWidgets.insert(fileTrans->getId(), fileTrans);
mainChatLayout->addWidget(fileTrans, curRow, 1); // previousName = author->text();
mainChatLayout->addWidget(date, curRow, 3); // mainChatLayout->addWidget(fileTrans, curRow, 1);
mainChatLayout->setRowStretch(curRow+1, 1); // mainChatLayout->addWidget(date, curRow, 3);
mainChatLayout->setRowStretch(curRow, 0); // mainChatLayout->setRowStretch(curRow+1, 1);
curRow++; // mainChatLayout->setRowStretch(curRow, 0);
// curRow++;
connect(Widget::getInstance()->getCore(), &Core::fileTransferInfo, fileTrans, &FileTransfertWidget::onFileTransferInfo); connect(Widget::getInstance()->getCore(), &Core::fileTransferInfo, fileTrans, &FileTransferInstance::onFileTransferInfo);
connect(Widget::getInstance()->getCore(), &Core::fileTransferCancelled, fileTrans, &FileTransfertWidget::onFileTransferCancelled); connect(Widget::getInstance()->getCore(), &Core::fileTransferCancelled, fileTrans, &FileTransferInstance::onFileTransferCancelled);
connect(Widget::getInstance()->getCore(), &Core::fileTransferFinished, fileTrans, &FileTransfertWidget::onFileTransferFinished); connect(Widget::getInstance()->getCore(), &Core::fileTransferFinished, fileTrans, &FileTransferInstance::onFileTransferFinished);
connect(fileTrans, SIGNAL(stateUpdated()), this, SLOT(updateChatContent()));
Widget* w = Widget::getInstance(); Widget* w = Widget::getInstance();
if (!w->isFriendWidgetCurActiveWidget(f)|| w->getIsWindowMinimized() || !w->isActiveWindow()) if (!w->isFriendWidgetCurActiveWidget(f)|| w->getIsWindowMinimized() || !w->isActiveWindow())
@ -166,6 +175,9 @@ void ChatForm::onFileRecvRequest(ToxFile file)
f->hasNewEvents=true; f->hasNewEvents=true;
f->widget->updateStatusLight(); f->widget->updateStatusLight();
} }
messages.append(new FileTransferAction(fileTrans, f->getName(), QTime::currentTime().toString("hh:mm")));
updateChatContent();
} }
void ChatForm::onAvInvite(int FriendId, int CallId, bool video) void ChatForm::onAvInvite(int FriendId, int CallId, bool video)
@ -461,3 +473,16 @@ void ChatForm::onMicMuteToggle()
} }
} }
} }
void ChatForm::onFileTansBtnClicked(QString widgetName, QString buttonName)
{
uint id = widgetName.toUInt();
auto it = ftransWidgets.find(id);
if (it != ftransWidgets.end())
it.value()->pressFromHtml(buttonName);
else
qDebug() << "no filetransferwidget: " << id;
// QMessageBox::information(nullptr, message, message);
}

View File

@ -22,6 +22,7 @@
#include "widget/netcamview.h" #include "widget/netcamview.h"
struct Friend; struct Friend;
class FileTransferInstance;
class ChatForm : public GenericChatForm class ChatForm : public GenericChatForm
{ {
@ -63,6 +64,7 @@ private slots:
void onAnswerCallTriggered(); void onAnswerCallTriggered();
void onHangupCallTriggered(); void onHangupCallTriggered();
void onCancelCallTriggered(); void onCancelCallTriggered();
void onFileTansBtnClicked(QString widgetName, QString buttonName);
private: private:
Friend* f; Friend* f;
@ -70,6 +72,8 @@ private:
NetCamView* netcam; NetCamView* netcam;
bool audioInputFlag; bool audioInputFlag;
int callId; int callId;
QHash<uint, FileTransferInstance*> ftransWidgets;
}; };
#endif // CHATFORM_H #endif // CHATFORM_H

View File

@ -23,6 +23,7 @@
#include "widget/emoticonswidget.h" #include "widget/emoticonswidget.h"
#include "style.h" #include "style.h"
#include "widget/widget.h" #include "widget/widget.h"
#include "settings.h"
GenericChatForm::GenericChatForm(QObject *parent) : GenericChatForm::GenericChatForm(QObject *parent) :
QObject(parent) QObject(parent)
@ -40,6 +41,10 @@ GenericChatForm::GenericChatForm(QObject *parent) :
QVBoxLayout *footButtonsSmall = new QVBoxLayout(), *volMicLayout = new QVBoxLayout(); QVBoxLayout *footButtonsSmall = new QVBoxLayout(), *volMicLayout = new QVBoxLayout();
mainChatLayout = new QGridLayout(); mainChatLayout = new QGridLayout();
newChatForm = new ChatAreaWidget();
newChatForm->document()->setDefaultStyleSheet(Style::get(":ui/chatArea/innerStyle.css"));
newChatForm->setStyleSheet(Style::get(":/ui/chatArea/chatArea.css"));
msgEdit = new ChatTextEdit(); msgEdit = new ChatTextEdit();
sendButton = new QPushButton(); sendButton = new QPushButton();
@ -112,6 +117,7 @@ GenericChatForm::GenericChatForm(QObject *parent) :
mainWidget->setLayout(mainLayout); mainWidget->setLayout(mainLayout);
mainLayout->addWidget(chatArea); mainLayout->addWidget(chatArea);
mainLayout->addWidget(newChatForm);
mainLayout->addLayout(mainFootLayout); mainLayout->addLayout(mainFootLayout);
mainLayout->setMargin(0); mainLayout->setMargin(0);
@ -147,8 +153,8 @@ GenericChatForm::GenericChatForm(QObject *parent) :
emoteButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); emoteButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
connect(emoteButton, SIGNAL(clicked()), this, SLOT(onEmoteButtonClicked())); connect(emoteButton, SIGNAL(clicked()), this, SLOT(onEmoteButtonClicked()));
connect(chatArea, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onChatContextMenuRequested(QPoint))); connect(newChatForm, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onChatContextMenuRequested(QPoint)));
connect(chatArea->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(onSliderRangeChanged())); connect(newChatForm->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(onSliderRangeChanged()));
} }
void GenericChatForm::setName(const QString &newName) void GenericChatForm::setName(const QString &newName)
@ -176,14 +182,14 @@ void GenericChatForm::onChatContextMenuRequested(QPoint pos)
void GenericChatForm::onSliderRangeChanged() void GenericChatForm::onSliderRangeChanged()
{ {
QScrollBar* scroll = chatArea->verticalScrollBar(); QScrollBar* scroll = newChatForm->verticalScrollBar();
if (lockSliderToBottom) if (lockSliderToBottom)
scroll->setValue(scroll->maximum()); scroll->setValue(scroll->maximum());
} }
void GenericChatForm::onSaveLogClicked() void GenericChatForm::onSaveLogClicked()
{ {
QString path = QFileDialog::getSaveFileName(0,tr("Save chat log")); QString path = QFileDialog::getSaveFileName(0, tr("Save chat log"));
if (path.isEmpty()) if (path.isEmpty())
return; return;
@ -192,96 +198,28 @@ void GenericChatForm::onSaveLogClicked()
return; return;
QString log; QString log;
QList<QLabel*> labels = chatAreaWidget->findChildren<QLabel*>(); log = newChatForm->toPlainText();
int i=0;
for (QLabel* label : labels)
{
log += label->text();
if (i==2)
{
i=0;
log += '\n';
}
else
{
log += '\t';
i++;
}
}
file.write(log.toUtf8()); file.write(log.toUtf8());
file.close(); file.close();
} }
void GenericChatForm::addMessage(QString author, QString message, QString date) void GenericChatForm::addMessage(QString author, QString message, QDateTime datetime)
{ {
QLabel *authorLabel = new QLabel(author); QString date = datetime.toString(Settings::getInstance().getTimestampFormat());
QLabel *messageLabel = new QLabel(); if (previousName == author)
QLabel *dateLabel = new QLabel(date); messages.append(new MessageAction("", message, date));
else messages.append(new MessageAction(author , message, date));
QScrollBar* scroll = chatArea->verticalScrollBar();
lockSliderToBottom = scroll && scroll->value() == scroll->maximum();
authorLabel->setAlignment(Qt::AlignTop | Qt::AlignRight);
dateLabel->setAlignment(Qt::AlignTop);
messageLabel->setWordWrap(true);
messageLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
authorLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
dateLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
if (author == Widget::getInstance()->getUsername())
{
QPalette pal;
pal.setColor(QPalette::WindowText, QColor(100,100,100));
authorLabel->setPalette(pal);
messageLabel->setPalette(pal);
}
if (previousName.isEmpty() || previousName != author)
{
if (curRow)
{
mainChatLayout->setRowStretch(curRow, 0);
mainChatLayout->addItem(new QSpacerItem(0,AUTHOR_CHANGE_SPACING),curRow,0,1,3);
}
previousName = author; previousName = author;
curRow++; updateChatContent();
}
else if (curRow)// onSaveLogClicked expects 0 or 3 QLabel per line
authorLabel->setText("");
QColor greentext(61,204,61);
QString fontTemplate = "<font color='%1'>%2</font>";
QString finalMessage;
QStringList messageLines = message.split("\n");
for (QString& s : messageLines)
{
if (QRegExp("^[ ]*>.*").exactMatch(s))
finalMessage += fontTemplate.arg(greentext.name(), toHtmlChars(s));
else
finalMessage += toHtmlChars(s);
finalMessage += "<br>";
}
messageLabel->setText(finalMessage.left(finalMessage.length()-4));
messageLabel->setText(SmileyPack::getInstance().smileyfied(messageLabel->text()));
messageLabel->setTextFormat(Qt::RichText);
mainChatLayout->addWidget(authorLabel, curRow, 0);
mainChatLayout->addWidget(messageLabel, curRow, 1);
mainChatLayout->addWidget(dateLabel, curRow, 3);
mainChatLayout->setRowStretch(curRow+1, 1);
mainChatLayout->setRowStretch(curRow, 0);
curRow++;
authorLabel->setContextMenuPolicy(Qt::CustomContextMenu);
messageLabel->setContextMenuPolicy(Qt::CustomContextMenu);
dateLabel->setContextMenuPolicy(Qt::CustomContextMenu);
connect(authorLabel, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onChatContextMenuRequested(QPoint)));
connect(messageLabel, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onChatContextMenuRequested(QPoint)));
connect(dateLabel, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onChatContextMenuRequested(QPoint)));
} }
GenericChatForm::~GenericChatForm() GenericChatForm::~GenericChatForm()
{ {
delete mainWidget; delete mainWidget;
delete headWidget; delete headWidget;
for (ChatAction *it : messages)
delete it;
} }
void GenericChatForm::onEmoteButtonClicked() void GenericChatForm::onEmoteButtonClicked()
@ -311,13 +249,22 @@ void GenericChatForm::onEmoteInsertRequested(QString str)
msgEdit->setFocus(); // refocus so that we can continue typing msgEdit->setFocus(); // refocus so that we can continue typing
} }
QString GenericChatForm::toHtmlChars(const QString &str) QString GenericChatForm::getHtmledMessages()
{ {
static QList<QPair<QString, QString>> replaceList = {{"&","&amp;"}, {" ","&nbsp;"}, {">","&gt;"}, {"<","&lt;"}}; QString res("<table width=100%>\n");
QString res = str;
for (auto &it : replaceList)
res = res.replace(it.first,it.second);
for (ChatAction *it : messages)
{
res += it->getHtml();
}
res += "</table>";
return res; return res;
} }
void GenericChatForm::updateChatContent()
{
QScrollBar* scroll = newChatForm->verticalScrollBar();
lockSliderToBottom = scroll && scroll->value() == scroll->maximum();
newChatForm->setHtml(getHtmledMessages());
}

View File

@ -28,7 +28,9 @@
#include <QPushButton> #include <QPushButton>
#include <QGridLayout> #include <QGridLayout>
#include "widget/chatareawidget.h"
#include "widget/tool/chattextedit.h" #include "widget/tool/chattextedit.h"
#include "widget/tool/genericchataction.h"
// Spacing in px inserted when the author of the last message changes // Spacing in px inserted when the author of the last message changes
#define AUTHOR_CHANGE_SPACING 5 #define AUTHOR_CHANGE_SPACING 5
@ -46,7 +48,7 @@ public:
virtual void setName(const QString &newName); virtual void setName(const QString &newName);
virtual void show(Ui::MainWindow &ui); virtual void show(Ui::MainWindow &ui);
void addMessage(QString author, QString message, QString date=QTime::currentTime().toString("hh:mm")); void addMessage(QString author, QString message, QDateTime datetime=QDateTime::currentDateTime());
signals: signals:
void sendMessage(int, QString); void sendMessage(int, QString);
@ -59,6 +61,7 @@ protected slots:
void onSaveLogClicked(); void onSaveLogClicked();
void onEmoteButtonClicked(); void onEmoteButtonClicked();
void onEmoteInsertRequested(QString str); void onEmoteInsertRequested(QString str);
void updateChatContent();
protected: protected:
QLabel *nameLabel, *avatarLabel; QLabel *nameLabel, *avatarLabel;
@ -70,11 +73,14 @@ protected:
ChatTextEdit *msgEdit; ChatTextEdit *msgEdit;
QPushButton *sendButton; QPushButton *sendButton;
QString previousName; QString previousName;
ChatAreaWidget *newChatForm;
int curRow; int curRow;
bool lockSliderToBottom; bool lockSliderToBottom;
QList<ChatAction*> messages;
private: private:
QString toHtmlChars(const QString &str); QString getHtmledMessages();
}; };
#endif // GENERICCHATFORM_H #endif // GENERICCHATFORM_H

View File

@ -0,0 +1,116 @@
/*
Copyright (C) 2014 by Project Tox <https://tox.im>
This file is part of qTox, a Qt-based graphical interface for Tox.
This program is libre 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 3 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 COPYING file for more details.
*/
#include "genericchataction.h"
#include "smileypack.h"
#include <QStringList>
#include <QBuffer>
QString ChatAction::toHtmlChars(const QString &str)
{
static QList<QPair<QString, QString>> replaceList = {{"&","&amp;"}, {" ","&nbsp;"}, {">","&gt;"}, {"<","&lt;"}};
QString res = str;
for (auto &it : replaceList)
res = res.replace(it.first,it.second);
return res;
}
QString ChatAction::QImage2base64(const QImage &img)
{
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
img.save(&buffer, "PNG"); // writes image into ba in PNG format
return ba.toBase64();
}
QString ChatAction::wrapName(const QString &name)
{
QString res = "<td><div class=name>" + name + "</div></td>\n";
return res;
}
QString ChatAction::wrapDate(const QString &date)
{
QString res = "<td align=right><div class=date>" + date + "</div></td>\n";
return res;
}
QString ChatAction::wrapMessage(const QString &message)
{
QString res = "<td width=100%><div class=message>" + message + "</div></td>\n";
return res;
}
QString ChatAction::wrapWholeLine(const QString &line)
{
QString res = "<tr>\n" + line + "</tr>\n";
return res;
}
MessageAction::MessageAction(const QString &author, const QString &message, const QString &date)
{
QString message_ = SmileyPack::getInstance().smileyfied(toHtmlChars(message));
QStringList messageLines = message_.split("\n");
message_ = "";
for (QString& s : messageLines)
{
if (QRegExp("^[ ]*&gt;.*").exactMatch(s))
message_ += "<div class=quote>" + s.right(s.length()-4) + "</div><br>";
else
message_ += s + "<br>";
}
message_ = message_.left(message_.length()-4);
content = wrapWholeLine(wrapName(author) + wrapMessage(message_) + wrapDate(date));
}
QString MessageAction::getHtml()
{
return content;
}
FileTransferAction::FileTransferAction(FileTransferInstance *widget, const QString &author, const QString &date) :
sender(author),
timestamp(date)
{
w = widget;
}
FileTransferAction::~FileTransferAction()
{
}
QString FileTransferAction::getHtml()
{
QString widgetHtml;
if (w != nullptr)
widgetHtml = w->getHtmlImage();
else
widgetHtml = "<div class=quote>EMPTY CONTENT</div>";
QString res = wrapWholeLine(wrapName(sender) + wrapMessage(widgetHtml) + wrapDate(timestamp));;
return res;
}
QString FileTransferAction::wrapMessage(const QString &message)
{
QString res = "<td width=100%>" + message + "</td>\n";
return res;
}

View File

@ -0,0 +1,63 @@
/*
Copyright (C) 2014 by Project Tox <https://tox.im>
This file is part of qTox, a Qt-based graphical interface for Tox.
This program is libre 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 3 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 COPYING file for more details.
*/
#ifndef CHATACTION_H
#define CHATACTION_H
#include <QString>
#include "filetransferinstance.h"
class ChatAction
{
public:
virtual ~ChatAction(){;}
virtual QString getHtml() = 0;
protected:
QString toHtmlChars(const QString &str);
QString QImage2base64(const QImage &img);
virtual QString wrapName(const QString &name);
virtual QString wrapDate(const QString &date);
virtual QString wrapMessage(const QString &message);
virtual QString wrapWholeLine(const QString &line);
};
class MessageAction : public ChatAction
{
public:
MessageAction(const QString &author, const QString &message, const QString &date);
virtual ~MessageAction(){;}
virtual QString getHtml();
private:
QString content;
};
class FileTransferAction : public ChatAction
{
public:
FileTransferAction(FileTransferInstance *widget, const QString &author, const QString &date);
virtual ~FileTransferAction();
virtual QString getHtml();
virtual QString wrapMessage(const QString &message);
private:
FileTransferInstance *w;
QString sender, timestamp;
};
#endif // CHATACTION_H