From de52bad1dbae2aad556d38e81bc42b85b65e5681 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 12 Nov 2014 14:11:25 +0100 Subject: [PATCH 001/203] initial commit --- qtox.pro | 37 +- src/chatlog/chatline.cpp | 178 ++++++ src/chatlog/chatline.h | 83 +++ src/chatlog/chatlinecontent.cpp | 70 +++ src/chatlog/chatlinecontent.h | 51 ++ src/chatlog/chatlinecontentproxy.cpp | 29 + src/chatlog/chatlinecontentproxy.h | 21 + src/chatlog/chatlog.cpp | 519 ++++++++++++++++++ src/chatlog/chatlog.h | 84 +++ src/chatlog/chatmessage.cpp | 5 + src/chatlog/chatmessage.h | 12 + src/chatlog/content/filetransferwidget.cpp | 34 ++ src/chatlog/content/filetransferwidget.h | 29 + src/chatlog/content/filetransferwidget.ui | 127 +++++ src/chatlog/content/spinner.cpp | 61 ++ src/chatlog/content/spinner.h | 32 ++ src/chatlog/content/text.cpp | 228 ++++++++ src/chatlog/content/text.h | 62 +++ src/widget/chatareawidget.cpp | 207 ------- src/widget/chatareawidget.h | 65 --- src/widget/form/chatform.cpp | 184 +++---- src/widget/form/chatform.h | 4 +- src/widget/form/genericchatform.cpp | 352 ++++++------ src/widget/form/genericchatform.h | 17 +- src/widget/tool/chatactions/actionaction.cpp | 39 -- src/widget/tool/chatactions/actionaction.h | 38 -- src/widget/tool/chatactions/alertaction.cpp | 27 - src/widget/tool/chatactions/alertaction.h | 35 -- src/widget/tool/chatactions/chataction.cpp | 116 ---- src/widget/tool/chatactions/chataction.h | 66 --- .../tool/chatactions/filetransferaction.cpp | 89 --- .../tool/chatactions/filetransferaction.h | 37 -- src/widget/tool/chatactions/messageaction.cpp | 96 ---- src/widget/tool/chatactions/messageaction.h | 43 -- .../tool/chatactions/systemmessageaction.cpp | 29 - .../tool/chatactions/systemmessageaction.h | 37 -- src/widget/widget.cpp | 19 +- 37 files changed, 1931 insertions(+), 1231 deletions(-) create mode 100644 src/chatlog/chatline.cpp create mode 100644 src/chatlog/chatline.h create mode 100644 src/chatlog/chatlinecontent.cpp create mode 100644 src/chatlog/chatlinecontent.h create mode 100644 src/chatlog/chatlinecontentproxy.cpp create mode 100644 src/chatlog/chatlinecontentproxy.h create mode 100644 src/chatlog/chatlog.cpp create mode 100644 src/chatlog/chatlog.h create mode 100644 src/chatlog/chatmessage.cpp create mode 100644 src/chatlog/chatmessage.h create mode 100644 src/chatlog/content/filetransferwidget.cpp create mode 100644 src/chatlog/content/filetransferwidget.h create mode 100644 src/chatlog/content/filetransferwidget.ui create mode 100644 src/chatlog/content/spinner.cpp create mode 100644 src/chatlog/content/spinner.h create mode 100644 src/chatlog/content/text.cpp create mode 100644 src/chatlog/content/text.h delete mode 100644 src/widget/chatareawidget.cpp delete mode 100644 src/widget/chatareawidget.h delete mode 100644 src/widget/tool/chatactions/actionaction.cpp delete mode 100644 src/widget/tool/chatactions/actionaction.h delete mode 100644 src/widget/tool/chatactions/alertaction.cpp delete mode 100644 src/widget/tool/chatactions/alertaction.h delete mode 100644 src/widget/tool/chatactions/chataction.cpp delete mode 100644 src/widget/tool/chatactions/chataction.h delete mode 100644 src/widget/tool/chatactions/filetransferaction.cpp delete mode 100644 src/widget/tool/chatactions/filetransferaction.h delete mode 100644 src/widget/tool/chatactions/messageaction.cpp delete mode 100644 src/widget/tool/chatactions/messageaction.h delete mode 100644 src/widget/tool/chatactions/systemmessageaction.cpp delete mode 100644 src/widget/tool/chatactions/systemmessageaction.h diff --git a/qtox.pro b/qtox.pro index 2b0f79d19..14303d207 100644 --- a/qtox.pro +++ b/qtox.pro @@ -33,7 +33,8 @@ FORMS += \ src/widget/form/settings/privacysettings.ui \ src/widget/form/loadhistorydialog.ui \ src/widget/form/inputpassworddialog.ui \ - src/widget/form/setpassworddialog.ui + src/widget/form/setpassworddialog.ui \ + src/chatlog/content/filetransferwidget.ui CONFIG += c++11 @@ -118,17 +119,10 @@ HEADERS += src/widget/form/addfriendform.h \ src/widget/friendlistwidget.h \ src/widget/genericchatroomwidget.h \ src/widget/form/genericchatform.h \ - src/widget/tool/chatactions/chataction.h \ - src/widget/chatareawidget.h \ src/filetransferinstance.h \ src/corestructs.h \ src/coredefines.h \ src/coreav.h \ - src/widget/tool/chatactions/messageaction.h \ - src/widget/tool/chatactions/filetransferaction.h \ - src/widget/tool/chatactions/systemmessageaction.h \ - src/widget/tool/chatactions/actionaction.h \ - src/widget/tool/chatactions/alertaction.h \ src/widget/maskablepixmapwidget.h \ src/video/videosource.h \ src/video/cameraworker.h \ @@ -148,7 +142,15 @@ HEADERS += src/widget/form/addfriendform.h \ src/toxdns.h \ src/widget/toxsave.h \ src/autoupdate.h \ - src/misc/serialize.h + src/misc/serialize.h \ + src/chatlog/chatlog.h \ + src/chatlog/chatline.h \ + src/chatlog/chatlinecontent.h \ + src/chatlog/chatlinecontentproxy.h \ + src/chatlog/content/text.h \ + src/chatlog/content/spinner.h \ + src/chatlog/content/filetransferwidget.h \ + src/chatlog/chatmessage.h SOURCES += \ src/widget/form/addfriendform.cpp \ @@ -185,15 +187,8 @@ SOURCES += \ src/coreav.cpp \ src/widget/genericchatroomwidget.cpp \ src/widget/form/genericchatform.cpp \ - src/widget/tool/chatactions/chataction.cpp \ - src/widget/chatareawidget.cpp \ src/filetransferinstance.cpp \ src/corestructs.cpp \ - src/widget/tool/chatactions/messageaction.cpp \ - src/widget/tool/chatactions/filetransferaction.cpp \ - src/widget/tool/chatactions/systemmessageaction.cpp \ - src/widget/tool/chatactions/actionaction.cpp \ - src/widget/tool/chatactions/alertaction.cpp \ src/widget/maskablepixmapwidget.cpp \ src/video/cameraworker.cpp \ src/widget/videosurface.cpp \ @@ -213,4 +208,12 @@ SOURCES += \ src/ipc.cpp \ src/widget/toxsave.cpp \ src/autoupdate.cpp \ - src/misc/serialize.cpp + src/misc/serialize.cpp \ + src/chatlog/chatlog.cpp \ + src/chatlog/chatline.cpp \ + src/chatlog/chatlinecontent.cpp \ + src/chatlog/chatlinecontentproxy.cpp \ + src/chatlog/content/text.cpp \ + src/chatlog/content/spinner.cpp \ + src/chatlog/content/filetransferwidget.cpp \ + src/chatlog/chatmessage.cpp diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp new file mode 100644 index 000000000..a531b42f4 --- /dev/null +++ b/src/chatlog/chatline.cpp @@ -0,0 +1,178 @@ +#include "chatline.h" +#include "chatlog.h" +#include "chatlinecontent.h" + +#include +#include +#include + +ChatLine::ChatLine(QGraphicsScene* grScene) + : scene(grScene) +{ + +} + +ChatLine::~ChatLine() +{ + for(ChatLineContent* c : content) + { + scene->removeItem(c); + delete c; + } +} + +void ChatLine::setRowIndex(int idx) +{ + rowIndex = idx; + + for(int c = 0; c < content.size(); ++c) + content[c]->setIndex(rowIndex, c); +} + +void ChatLine::visibilityChanged(bool visible) +{ + if(isVisible != visible) + { + for(ChatLineContent* c : content) + c->visibilityChanged(visible); + } + + isVisible = visible; +} + +int ChatLine::getRowIndex() const +{ + return rowIndex; +} + +void ChatLine::selectionCleared() +{ + for(ChatLineContent* c : content) + c->selectionCleared(); +} + +void ChatLine::selectionCleared(int col) +{ + if(col < content.size() && content[col]) + content[col]->selectionCleared(); +} + +void ChatLine::selectAll() +{ + for(ChatLineContent* c : content) + c->selectAll(); +} + +void ChatLine::selectAll(int col) +{ + if(col < content.size() && content[col]) + content[col]->selectAll(); +} + +int ChatLine::getColumnCount() +{ + return content.size(); +} + +void ChatLine::updateBBox() +{ + bbox = QRectF(); + bbox.setTop(pos.y()); + bbox.setLeft(pos.x()); + bbox.setWidth(width); + + for(ChatLineContent* c : content) + bbox.setHeight(qMax(c->sceneBoundingRect().height(), bbox.height())); +} + +QRectF ChatLine::boundingSceneRect() const +{ + return bbox; +} + +void ChatLine::addColumn(ChatLineContent* item, ColumnFormat fmt) +{ + if(!item) + return; + + item->setChatLine(this); + scene->addItem(item); + + format << fmt; + content << item; +} + +void ChatLine::layout(qreal w, QPointF scenePos) +{ + width = w; + pos = scenePos; + + qreal fixedWidth = 0.0; + qreal varWidth = 0.0; // used for normalisation + + for(int i = 0; i < format.size(); ++i) + { + if(format[i].policy == ColumnFormat::FixedSize) + fixedWidth += format[i].size; + else + varWidth += format[i].size; + } + + if(varWidth == 0.0) + varWidth = 1.0; + + qreal leftover = qMax(0.0, width - fixedWidth); + + qreal xOffset = 0.0; + for(int i = 0; i < content.size(); ++i) + { + // calculate the effective width of the current column + qreal width; + if(format[i].policy == ColumnFormat::FixedSize) + width = format[i].size; + else + width = format[i].size / varWidth * leftover; + + // set the width of the current column as + // firstLineVOffset() may depend on the current width + content[i]->setWidth(width); + + // calculate vertical alignment + qreal yOffset = 0.0; + if(format[i].vAlignCol >= 0 && format[i].vAlignCol < content.size()) + yOffset = content[format[i].vAlignCol]->firstLineVOffset() - content[i]->firstLineVOffset(); + + // calculate horizontal alignment + qreal xAlign = 0.0; + switch(format[i].hAlign) + { + case ColumnFormat::Right: + xAlign = width - content[i]->boundingRect().width(); + break; + case ColumnFormat::Center: + xAlign = (width - content[i]->boundingRect().width()) / 2.0; + break; + default: + break; + } + + // reposition + content[i]->setPos(pos.x() + xOffset + xAlign, pos.y() + yOffset); + + xOffset += width; + } + + updateBBox(); +} + +void ChatLine::layout(QPointF scenePos) +{ + // reposition only + QPointF offset = pos - scenePos; + for(ChatLineContent* c : content) + c->setPos(c->pos() - offset); + + pos = scenePos; + + updateBBox(); +} diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h new file mode 100644 index 000000000..13038b434 --- /dev/null +++ b/src/chatlog/chatline.h @@ -0,0 +1,83 @@ +#ifndef CHATLINE_H +#define CHATLINE_H + +#include + +class ChatLog; +class ChatLineContent; +class QGraphicsScene; +class QStyleOptionGraphicsItem; + +struct ColumnFormat +{ + enum Policy { + FixedSize, + VariableSize, + }; + + enum Align { + Left, + Center, + Right, + }; + + ColumnFormat() {} + ColumnFormat(qreal s, Policy p, int valign = -1, Align halign = Left) + : size(s) + , policy(p) + , vAlignCol(valign) + , hAlign(halign) + {} + + qreal size = 1.0; + Policy policy = VariableSize; + int vAlignCol = -1; + Align hAlign = Left; +}; + +using ColumnFormats = QVector; + +class ChatLine +{ +public: + explicit ChatLine(QGraphicsScene* scene); + virtual ~ChatLine(); + + virtual QRectF boundingSceneRect() const; + + void addColumn(ChatLineContent* item, ColumnFormat fmt); + + void layout(qreal width, QPointF scenePos); + void layout(QPointF scenePos); + + void selectionCleared(); + void selectionCleared(int col); + void selectAll(); + void selectAll(int col); + + int getColumnCount(); + int getRowIndex() const; + + bool isOverSelection(QPointF scenePos); + +private: + QPointF mapToContent(ChatLineContent* c, QPointF pos); + void updateBBox(); + + friend class ChatLog; + void setRowIndex(int idx); + void visibilityChanged(bool visible); + +private: + int rowIndex = -1; + QGraphicsScene* scene = nullptr; + QVector content; // 3 columns + QVector format; + qreal width; + QRectF bbox; + QPointF pos; + bool isVisible = false; + +}; + +#endif // CHATLINE_H diff --git a/src/chatlog/chatlinecontent.cpp b/src/chatlog/chatlinecontent.cpp new file mode 100644 index 000000000..1cfc61dc6 --- /dev/null +++ b/src/chatlog/chatlinecontent.cpp @@ -0,0 +1,70 @@ +#include "chatlinecontent.h" + +void ChatLineContent::setChatLine(ChatLine* chatline) +{ + line = chatline; +} + +ChatLine* ChatLineContent::getChatLine() const +{ + return line; +} + +void ChatLineContent::setIndex(int r, int c) +{ + row = r; + col = c; +} + +int ChatLineContent::getColumn() const +{ + return col; +} + +int ChatLineContent::getRow() const +{ + return row; +} + +int ChatLineContent::type() const +{ + return GraphicsItemType::ChatLineContentType; +} + +void ChatLineContent::selectionMouseMove(QPointF) +{ + +} + +void ChatLineContent::selectionStarted(QPointF) +{ + +} + +void ChatLineContent::selectionCleared() +{ +} + +void ChatLineContent::selectAll() +{ +} + +bool ChatLineContent::isOverSelection(QPointF) const +{ + return false; +} + +QString ChatLineContent::getSelectedText() const +{ + return QString(); +} + +qreal ChatLineContent::firstLineVOffset() +{ + return 0.0; +} + +void ChatLineContent::visibilityChanged(bool) +{ + +} diff --git a/src/chatlog/chatlinecontent.h b/src/chatlog/chatlinecontent.h new file mode 100644 index 000000000..32d08d7c8 --- /dev/null +++ b/src/chatlog/chatlinecontent.h @@ -0,0 +1,51 @@ +#ifndef CHATLINECONTENT_H +#define CHATLINECONTENT_H + +#include + +class ChatLine; + +class ChatLineContent : public QGraphicsItem +{ +public: + enum GraphicsItemType + { + ChatLineContentType = QGraphicsItem::UserType + 1, + }; + + ChatLine* getChatLine() const; + + int getColumn() const; + int getRow() const; + + virtual void setWidth(qreal width) = 0; + virtual int type() const final; + + virtual void selectionMouseMove(QPointF scenePos); + virtual void selectionStarted(QPointF scenePos); + virtual void selectionCleared(); + virtual void selectAll(); + virtual bool isOverSelection(QPointF scenePos) const; + virtual QString getSelectedText() const; + + virtual qreal firstLineVOffset(); + + virtual QRectF boundingSceneRect() const = 0; + virtual QRectF boundingRect() const = 0; + virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) = 0; + + virtual void visibilityChanged(bool visible); + +private: + friend class ChatLine; + + void setIndex(int row, int col); + void setChatLine(ChatLine* chatline); + +private: + ChatLine* line = nullptr; + int row = -1; + int col = -1; +}; + +#endif // CHATLINECONTENT_H diff --git a/src/chatlog/chatlinecontentproxy.cpp b/src/chatlog/chatlinecontentproxy.cpp new file mode 100644 index 000000000..28eac44ef --- /dev/null +++ b/src/chatlog/chatlinecontentproxy.cpp @@ -0,0 +1,29 @@ +#include "chatlinecontentproxy.h" +#include +#include + +ChatLineContentProxy::ChatLineContentProxy(QWidget* widget) +{ + proxy = new QGraphicsProxyWidget(this); + proxy->setWidget(widget); +} + +QRectF ChatLineContentProxy::boundingRect() const +{ + return proxy->boundingRect(); +} + +QRectF ChatLineContentProxy::boundingSceneRect() const +{ + return proxy->boundingRect().translated(scenePos()); +} + +void ChatLineContentProxy::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + proxy->paint(painter, option, widget); +} + +void ChatLineContentProxy::setWidth(qreal width) +{ + proxy->widget()->setFixedWidth(qMax(width,0.0)); +} diff --git a/src/chatlog/chatlinecontentproxy.h b/src/chatlog/chatlinecontentproxy.h new file mode 100644 index 000000000..aa69fae36 --- /dev/null +++ b/src/chatlog/chatlinecontentproxy.h @@ -0,0 +1,21 @@ +#ifndef CHATLINECONTENTPROXY_H +#define CHATLINECONTENTPROXY_H + +#include +#include "chatlinecontent.h" + +class ChatLineContentProxy : public ChatLineContent +{ +public: + ChatLineContentProxy(QWidget* widget); + + virtual QRectF boundingRect() const; + virtual QRectF boundingSceneRect() const; + virtual void setWidth(qreal width); + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + +private: + QGraphicsProxyWidget* proxy; +}; + +#endif // CHATLINECONTENTPROXY_H diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp new file mode 100644 index 000000000..e3f8c2d1f --- /dev/null +++ b/src/chatlog/chatlog.cpp @@ -0,0 +1,519 @@ +#include "chatlog.h" +#include "chatline.h" +#include "chatlinecontent.h" +#include "chatlinecontentproxy.h" +#include "content/text.h" +#include "content/filetransferwidget.h" +#include "content/spinner.h" + +#include +#include +#include +#include +#include + +template +T clamp(T x, T min, T max) +{ + if(x > max) + return max; + if(x < min) + return min; + return x; +} + +ChatLog::ChatLog(QWidget* parent) + : QGraphicsView(parent) +{ + scene = new QGraphicsScene(this); + scene->setItemIndexMethod(QGraphicsScene::NoIndex); + setScene(scene); + + setInteractive(true); + setAlignment(Qt::AlignTop | Qt::AlignLeft); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setDragMode(QGraphicsView::NoDrag); + setViewportUpdateMode(SmartViewportUpdate); + //setRenderHint(QPainter::TextAntialiasing); + + // copy action + copyAction = new QAction(this); + copyAction->setShortcut(QKeySequence::Copy); + addAction(copyAction); + connect(copyAction, &QAction::triggered, this, [ = ](bool) + { + copySelectedText(); + }); +} + +ChatLog::~ChatLog() +{ + for(ChatLine* line : lines) + delete line; +} + +void ChatLog::addTextLine(const QString& sender, const QString& text, QDateTime timestamp) +{ + ChatLine* line = new ChatLine(scene); + + line->addColumn(new Text(sender, true), ColumnFormat(75.0, ColumnFormat::FixedSize, 1, ColumnFormat::Right)); + line->addColumn(new Text(text), ColumnFormat(1.0, ColumnFormat::VariableSize)); + line->addColumn(new Text(timestamp.toString("hh:mm")), ColumnFormat(50.0, ColumnFormat::FixedSize, 1)); + + insertChatline(line); +} + +void ChatLog::addWidgetLine(const QString& sender, QDateTime timestamp) +{ + ChatLine* line = new ChatLine(scene); + + line->addColumn(new Text(sender, true), ColumnFormat(75.0, ColumnFormat::FixedSize, 1)); + line->addColumn(new ChatLineContentProxy(new FileTransferWidget()), ColumnFormat(1.0, ColumnFormat::VariableSize)); + line->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(50.0, ColumnFormat::FixedSize, 1, ColumnFormat::Right)); + + insertChatline(line); +} + +void ChatLog::clearSelection() +{ + if(selStartRow >= 0) + for(int r = qMin(selStartRow, selLastRow); r <= qMax(selLastRow, selStartRow) && r < lines.size(); ++r) + lines[r]->selectionCleared(); + + selStartRow = -1; + selStartCol = -1; + selLastRow = -1; + selLastCol = -1; +} + +void ChatLog::dbgPopulate() +{ + for(int i = 0; i < 2000; i++) + addTextLine("Jemp longlong name foo moth", "Line " + QString::number(i) + + " Lorem ipsum Hello dolor sit amet, " + "consectetur adipisicing elit, sed do eiusmod " + "tempor incididunt ut labore et dolore magna " + "aliqua. Ut enim ad minim veniam, quis nostrud " + "exercitation ullamco laboris nisi ut aliquip ex " + "ea commodo consequat. "); +} + +QRect ChatLog::getVisibleRect() const +{ + return mapToScene(viewport()->rect()).boundingRect().toRect(); +} + +void ChatLog::updateSceneRect() +{ + setSceneRect(QRectF(0, 0, width(), lines.empty() ? 0.0 : lines.last()->boundingSceneRect().bottom())); +} + +bool ChatLog::layout(int start, int end, qreal width) +{ + //qDebug() << "layout " << start << end; + if(lines.empty()) + return false; + + start = clamp(start, 0, lines.size() - 1); + end = clamp(end + 1, 0, lines.size()); + + qreal h = lines[start]->boundingSceneRect().top(); + + bool needsReposition = false; + for(int i = start; i < end; ++i) + { + ChatLine* l = lines[i]; + + qreal oldHeight = l->boundingSceneRect().height(); + l->layout(width, QPointF(0, h)); + + if(oldHeight != l->boundingSceneRect().height()) + needsReposition = true; + + h += l->boundingSceneRect().height() + lineSpacing; + } + + // move up + if(needsReposition) + reposition(end-1, end+10); + + return needsReposition; +} + +void ChatLog::partialUpdate() +{ + checkVisibility(); + + if(visibleLines.empty()) + return; + + auto oldUpdateMode = viewportUpdateMode(); + setViewportUpdateMode(NoViewportUpdate); + + static int count = 0; + int count2 = 0; + int lastNonDirty = visibleLines.first()->getRowIndex(); + bool repos; + do + { + repos = false; + 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(); +} + +void ChatLog::fullUpdate() +{ + layout(0, lines.size(), useableWidth()); + checkVisibility(); + updateSceneRect(); +} + +void ChatLog::mousePressEvent(QMouseEvent* ev) +{ + QGraphicsView::mousePressEvent(ev); + + QPointF scenePos = mapToScene(ev->pos()); + + if(ev->button() == Qt::LeftButton) + { + clickPos = ev->pos(); + clearSelection(); + } + + if(ev->button() == Qt::RightButton) + { + if(!isOverSelection(scenePos)) + clearSelection(); + + showContextMenu(ev->globalPos(), scenePos); + } +} + +void ChatLog::mouseReleaseEvent(QMouseEvent* ev) +{ + QGraphicsView::mouseReleaseEvent(ev); + + if(ev->button() == Qt::LeftButton) + selecting = false; +} + +void ChatLog::mouseMoveEvent(QMouseEvent* ev) +{ + QGraphicsView::mouseMoveEvent(ev); + + QPointF scenePos = mapToScene(ev->pos()); + + if(ev->buttons() & Qt::LeftButton) + { + if(!selecting && (clickPos - ev->pos()).manhattanLength() > QApplication::startDragDistance()) + { + QPointF sceneClickPos = mapToScene(clickPos.toPoint()); + + ChatLineContent* content = getContentFromPos(sceneClickPos); + if(content) + { + selStartRow = content->getRow(); + selStartCol = content->getColumn(); + selLastRow = selStartRow; + selLastCol = selStartCol; + + content->selectionStarted(sceneClickPos); + + selecting = true; + + // ungrab mouse grabber + if(scene->mouseGrabberItem()) + scene->mouseGrabberItem()->ungrabMouse(); + } + } + } + + if(selecting && ev->pos() != lastPos) + { + lastPos = ev->pos(); + + ChatLineContent* content = getContentFromPos(scenePos); + + if(content) + { + // TODO: turn this into a sane algo. + int row = content->getRow(); + int col = content->getColumn(); + int firstRow = selStartRow; + + // selection + for(int r = qMin(firstRow, row + 1); r < qMax(row, firstRow); r++) + lines[r]->selectAll(); + + if(row != selStartRow) + for(int c = 0; c < col; c++) + lines[selStartRow]->selectAll(); + + if(row == selStartRow) + content->selectionMouseMove(scenePos); + else + { + lines[row]->selectAll(); + selStartCol = 0; + selLastCol = lines[row]->getColumnCount(); + } + + // de-selection + if(row < selStartRow) + selLastRow = qMin(row, selLastRow); + else + selLastRow = qMax(row, selLastRow); + + if(col < selStartCol) + selLastCol = qMin(col, selLastCol); + else + selLastCol = qMax(col, selLastCol); + + for(int r = qMin(row, selLastRow); r < qMax(row, selLastRow + 1) && r < lines.size(); ++r) + if(r != row) + lines[r]->selectionCleared(); + + if(row == selStartRow) + for(int c = col + 1; c < lines[row]->getColumnCount() && c < selLastCol; ++c) + lines[row]->selectionCleared(c); + + } + } +} + +ChatLineContent* ChatLog::getContentFromPos(QPointF scenePos) const +{ + QGraphicsItem* item = scene->itemAt(scenePos, QTransform()); + + if(item && item->type() == ChatLineContent::ChatLineContentType) + return static_cast(item); + + return nullptr; +} + +bool ChatLog::isOverSelection(QPointF scenePos) +{ + ChatLineContent* content = getContentFromPos(scenePos); + + if(content) + return content->isOverSelection(scenePos); + + return false; +} + +int ChatLog::useableWidth() +{ + return width() - verticalScrollBar()->sizeHint().width(); +} + +void ChatLog::reposition(int start, int end) +{ + if(lines.isEmpty()) + return; + + start = clamp(start, 0, lines.size() - 1); + end = clamp(end + 1, 0, lines.size()); + + qreal h = lines[start]->boundingSceneRect().bottom() + lineSpacing; + + for(int i = start + 1; i < end; ++i) + { + ChatLine* l = lines[i]; + l->layout(QPointF(0, h)); + h += l->boundingSceneRect().height() + lineSpacing; + } +} + +void ChatLog::repositionDownTo(int start, qreal end) +{ + if(lines.isEmpty()) + return; + + start = clamp(start, 0, lines.size() - 1); + + qreal h = lines[start]->boundingSceneRect().bottom() + lineSpacing; + + for(int i = start + 1; i < lines.size(); ++i) + { + ChatLine* l = lines[i]; + l->layout(QPointF(0, h)); + h += l->boundingSceneRect().height() + lineSpacing; + + if(h > end) + break; + } +} + +void ChatLog::insertChatline(ChatLine* l) +{ + stickToBtm = stickToBottom(); + + l->setRowIndex(lines.size()); + lines.append(l); + + layout(lines.last()->getRowIndex() - 1, lines.size(), useableWidth()); + updateSceneRect(); + + if(stickToBtm) + scrollToBottom(); + + checkVisibility(); +} + +bool ChatLog::stickToBottom() +{ + return verticalScrollBar()->value() == verticalScrollBar()->maximum(); +} + +void ChatLog::scrollToBottom() +{ + verticalScrollBar()->setValue(verticalScrollBar()->maximum()); + updateGeometry(); + checkVisibility(); +} + +QString ChatLog::getSelectedText() const +{ + QString ret; + + const int rowStart = qMin(selStartRow, selLastRow); + const int rowLast = qMax(selStartRow, selLastRow); + + const int colStart = qMin(selStartCol, selLastCol); + const int colLast = qMax(selStartCol, selLastCol); + + for(int r = rowStart; r <= rowLast && r < lines.size(); ++r) + for(int c = colStart; c <= colLast && c < lines[r]->getColumnCount(); ++c) + ret.append(lines[r]->content[c]->getSelectedText() + '\n'); + + return ret; +} + +void ChatLog::showContextMenu(const QPoint& globalPos, const QPointF& scenePos) +{ + QMenu menu; + + // populate + QAction* copyAction = menu.addAction(QIcon::fromTheme("edit-copy"), "Copy"); + menu.addSeparator(); + QAction* clearAction = menu.addAction("Clear log"); + + if(!isOverSelection(scenePos)) + copyAction->setDisabled(true); + + // show + QAction* action = menu.exec(globalPos); + + if(action == copyAction) + copySelectedText(); + + if(action == clearAction) + clear(); +} + +void ChatLog::clear() +{ + visibleLines.clear(); + clearSelection(); + + for(ChatLine* line : lines) + delete line; + + lines.clear(); + updateSceneRect(); +} + +void ChatLog::copySelectedText() const +{ + QString text = getSelectedText(); + + QClipboard* clipboard = QApplication::clipboard(); + clipboard->setText(text); +} + +void ChatLog::checkVisibility() +{ + // find first visible row + QList::const_iterator upperBound; + upperBound = std::upper_bound(lines.cbegin(), lines.cend(), getVisibleRect().top(), [](const qreal lhs, const ChatLine* rhs) + { + return lhs < rhs->boundingSceneRect().bottom(); + }); + + if(upperBound == lines.end()) + upperBound = lines.begin(); + + // find last visible row + QList::const_iterator lowerBound; + lowerBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().bottom(), [](const ChatLine* lhs, const qreal rhs) + { + return lhs->boundingSceneRect().bottom() < rhs; + }); + + if(lowerBound == lines.end()) + lowerBound = lines.end(); + + // set visibilty + QList newVisibleLines; + for(auto itr = upperBound; itr <= lowerBound && itr != lines.end(); ++itr) + { + newVisibleLines.append(*itr); + + if(!visibleLines.contains(*itr)) + (*itr)->visibilityChanged(true); + + visibleLines.removeOne(*itr); + } + + for(ChatLine* line : visibleLines) + line->visibilityChanged(false); + + visibleLines = newVisibleLines; + + // assure order + std::sort(visibleLines.begin(), visibleLines.end(), [](const ChatLine* lhs, const ChatLine* rhs) + { + return lhs->getRowIndex() < rhs->getRowIndex(); + }); + + //if(!visibleLines.empty()) + // qDebug() << "visible from " << visibleLines.first()->getRowIndex() << "to " << visibleLines.last()->getRowIndex() << " total " << visibleLines.size(); +} + +void ChatLog::scrollContentsBy(int dx, int dy) +{ + QGraphicsView::scrollContentsBy(dx, dy); + partialUpdate(); +} + +void ChatLog::resizeEvent(QResizeEvent* ev) +{ + bool stb = stickToBottom(); + + QGraphicsView::resizeEvent(ev); + + if(lines.count() > 300) + partialUpdate(); + else + fullUpdate(); + + if(stb) + scrollToBottom(); +} diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h new file mode 100644 index 000000000..5a9b31fb4 --- /dev/null +++ b/src/chatlog/chatlog.h @@ -0,0 +1,84 @@ +#ifndef CHATLOG_H +#define CHATLOG_H + +#include +#include + +class QGraphicsScene; +class ChatLine; +class ChatLineContent; + +class ChatLog : public QGraphicsView +{ + Q_OBJECT +public: + explicit ChatLog(QWidget* parent = 0); + virtual ~ChatLog(); + + void addTextLine(const QString& sender, const QString& text, QDateTime timestamp = QDateTime::currentDateTime()); + void addWidgetLine(const QString& sender, QDateTime timestamp = QDateTime::currentDateTime()); + void insertChatline(ChatLine* l); + + void clearSelection(); + void clear(); + void copySelectedText() const; + QString getSelectedText() const; + + void dbgPopulate(); + +signals: + +public slots: + +protected: + QRect getVisibleRect() const; + ChatLineContent* getContentFromPos(QPointF scenePos) const; + + bool layout(int start, int end, qreal width); + bool isOverSelection(QPointF scenePos); + bool stickToBottom(); + + int useableWidth(); + + void reposition(int start, int end); + void repositionDownTo(int start, qreal end); + void updateSceneRect(); + void partialUpdate(); + void fullUpdate(); + void checkVisibility(); + void scrollToBottom(); + void showContextMenu(const QPoint& globalPos, const QPointF& scenePos); + + virtual void mousePressEvent(QMouseEvent* ev); + virtual void mouseReleaseEvent(QMouseEvent* ev); + virtual void mouseMoveEvent(QMouseEvent* ev); + virtual void scrollContentsBy(int dx, int dy); + virtual void resizeEvent(QResizeEvent *ev); + +private: + QGraphicsScene* scene = nullptr; + QList lines; + QList visibleLines; + + bool multiLineInsert = false; + bool stickToBtm = false; + int insertStartIndex = -1; + + // selection + int selStartRow = -1; + int selStartCol = -1; + int selLastRow = -1; + int selLastCol = -1; + bool selecting = false; + QPointF clickPos; + QPointF lastPos; + + // actions + QAction* copyAction = nullptr; + + // layout + qreal lineSpacing = 10.0f; + +}; + +#endif // CHATLOG_H diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp new file mode 100644 index 000000000..a6350843e --- /dev/null +++ b/src/chatlog/chatmessage.cpp @@ -0,0 +1,5 @@ +#include "chatmessage.h" + +ChatMessage::ChatMessage() +{ +} diff --git a/src/chatlog/chatmessage.h b/src/chatlog/chatmessage.h new file mode 100644 index 000000000..a0d487292 --- /dev/null +++ b/src/chatlog/chatmessage.h @@ -0,0 +1,12 @@ +#ifndef CHATMESSAGE_H +#define CHATMESSAGE_H + +#include "chatline.h" + +class ChatMessage : public ChatLine +{ +public: + ChatMessage(); +}; + +#endif // CHATMESSAGE_H diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp new file mode 100644 index 000000000..fef501647 --- /dev/null +++ b/src/chatlog/content/filetransferwidget.cpp @@ -0,0 +1,34 @@ +#include "filetransferwidget.h" +#include "ui_filetransferwidget.h" + +#include +#include + +FileTransferWidget::FileTransferWidget(QWidget *parent) : + QWidget(parent), + ui(new Ui::FileTransferWidget) +{ + ui->setupUi(this); + + setFixedHeight(100); +} + +FileTransferWidget::~FileTransferWidget() +{ + delete ui; +} + +void FileTransferWidget::on_pushButton_2_clicked() +{ + qDebug() << "Button Cancel Clicked"; +} + +void FileTransferWidget::on_pushButton_clicked() +{ + qDebug() << "Button Resume Clicked"; +} + +void FileTransferWidget::on_pushButton_2_pressed() +{ + qDebug() << "Button Resume Clicked"; +} diff --git a/src/chatlog/content/filetransferwidget.h b/src/chatlog/content/filetransferwidget.h new file mode 100644 index 000000000..b09c09023 --- /dev/null +++ b/src/chatlog/content/filetransferwidget.h @@ -0,0 +1,29 @@ +#ifndef FILETRANSFERWIDGET_H +#define FILETRANSFERWIDGET_H + +#include +#include "../chatlinecontent.h" + +namespace Ui { +class FileTransferWidget; +} + +class FileTransferWidget : public QWidget +{ + Q_OBJECT + +public: + explicit FileTransferWidget(QWidget *parent = 0); + virtual ~FileTransferWidget(); + +private: + Ui::FileTransferWidget *ui; + +private slots: + void on_pushButton_2_clicked(); + void on_pushButton_clicked(); + void on_pushButton_2_pressed(); + +}; + +#endif // FILETRANSFERWIDGET_H diff --git a/src/chatlog/content/filetransferwidget.ui b/src/chatlog/content/filetransferwidget.ui new file mode 100644 index 000000000..4e2cca60d --- /dev/null +++ b/src/chatlog/content/filetransferwidget.ui @@ -0,0 +1,127 @@ + + + FileTransferWidget + + + + 0 + 0 + 729 + 124 + + + + Form + + + false + + + background-color:transparent; + + + + + + QFrame { +border-radius:10; +background-color:green; +} + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + color:white; + + + SomeRandomFile.7z + + + + + + + color:white; + + + 142/1742 YiB + + + + + + + color:white; + + + 24 + + + + + + + + + + + + 0 + 0 + + + + + 50 + 50 + + + + background-color:red; + + + Cancel + + + + + + + + 0 + 0 + + + + + 50 + 50 + + + + background-color:rgb(0, 255, 0); + + + Resume + + + + + + + + + + + + + diff --git a/src/chatlog/content/spinner.cpp b/src/chatlog/content/spinner.cpp new file mode 100644 index 000000000..67330f862 --- /dev/null +++ b/src/chatlog/content/spinner.cpp @@ -0,0 +1,61 @@ +#include "spinner.h" + +#include +#include + +Spinner::Spinner(QSizeF Size) + : size(Size) +{ + pmap.load(":/media/spinner.png"); + + timer.setInterval(33); // 30Hz + timer.setSingleShot(false); + timer.start(); + + QObject::connect(&timer, &QTimer::timeout, this, &Spinner::timeout); +} + +QRectF Spinner::boundingRect() const +{ + return QRectF(QPointF(-size.width() / 2.0, -size.height() / 2.0), size); +} + +QRectF Spinner::boundingSceneRect() const +{ + return QRectF(scenePos(), size); +} + +void Spinner::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) +{ + QTransform rotMat; + rotMat.translate(size.width() / 2.0, size.height() / 2.0); + rotMat.rotate(rot); + rotMat.translate(-size.width() / 2.0, -size.height() / 2.0); + + painter->translate(-size.width() / 2.0, -size.height() / 2.0); + painter->setTransform(rotMat, true); + painter->setRenderHint(QPainter::SmoothPixmapTransform); + painter->drawPixmap(0, 0, size.width(), size.height(), pmap); + + Q_UNUSED(option) + Q_UNUSED(widget) +} + +void Spinner::setWidth(qreal width) +{ + Q_UNUSED(width) +} + +void Spinner::visibilityChanged(bool visible) +{ + if(visible) + timer.start(); + else + timer.stop(); +} + +void Spinner::timeout() +{ + rot += 8; + update(); +} diff --git a/src/chatlog/content/spinner.h b/src/chatlog/content/spinner.h new file mode 100644 index 000000000..81dc6f835 --- /dev/null +++ b/src/chatlog/content/spinner.h @@ -0,0 +1,32 @@ +#ifndef SPINNER_H +#define SPINNER_H + +#include "../chatlinecontent.h" + +#include +#include + +class Spinner : public QObject, public ChatLineContent +{ + Q_OBJECT +public: + Spinner(QSizeF size); + + virtual QRectF boundingRect() const; + virtual QRectF boundingSceneRect() const; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + virtual void setWidth(qreal width); + virtual void visibilityChanged(bool visible); + +private slots: + void timeout(); + +private: + QSizeF size; + QPixmap pmap; + qreal rot; + QTimer timer; + +}; + +#endif // SPINNER_H diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp new file mode 100644 index 000000000..37e0ed74c --- /dev/null +++ b/src/chatlog/content/text.cpp @@ -0,0 +1,228 @@ +#include "text.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int Text::count = 0; + +Text::Text(const QString& txt, bool enableElide) + : ChatLineContent() + , elide(enableElide) +{ + setText(txt); + setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton); + //setCacheMode(QGraphicsItem::DeviceCoordinateCache); +} + +Text::~Text() +{ + delete doc; +} + +void Text::setText(const QString& txt) +{ + text = txt; + text.replace("\n", "
"); + + ensureIntegrity(); + freeResources(); +} + +void Text::setWidth(qreal w) +{ + if(w == width) + return; + + width = w; + + if(elide) + { + QFontMetrics metrics = QFontMetrics(QFont()); + elidedText = metrics.elidedText(text, Qt::ElideRight, width); + } + + ensureIntegrity(); + freeResources(); +} + +void Text::selectionMouseMove(QPointF scenePos) +{ + ensureIntegrity(); + int cur = cursorFromPos(scenePos); + if(cur >= 0) + cursor.setPosition(cur, QTextCursor::KeepAnchor); + + update(); +} + +void Text::selectionStarted(QPointF scenePos) +{ + ensureIntegrity(); + int cur = cursorFromPos(scenePos); + if(cur >= 0) + cursor.setPosition(cur); +} + +void Text::selectionCleared() +{ + ensureIntegrity(); + cursor.setPosition(0); + freeResources(); + + update(); +} + +void Text::selectAll() +{ + ensureIntegrity(); + cursor.select(QTextCursor::Document); + update(); +} + +bool Text::isOverSelection(QPointF scenePos) const +{ + int cur = cursorFromPos(scenePos); + if(cur >= 0 && cursor.selectionStart() < cur && cursor.selectionEnd() >= cur) + return true; + + return false; +} + +QString Text::getSelectedText() const +{ + return cursor.selectedText(); +} + +QRectF Text::boundingSceneRect() const +{ + return QRectF(scenePos(), size); +} + +QRectF Text::boundingRect() const +{ + return QRectF(QPointF(0, 0), size); +} + +void Text::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) +{ + if(doc) + { + // draw selection + QAbstractTextDocumentLayout::PaintContext ctx; + QAbstractTextDocumentLayout::Selection sel; + sel.cursor = cursor; + sel.format.setBackground(QApplication::palette().color(QPalette::Highlight)); + sel.format.setForeground(QApplication::palette().color(QPalette::HighlightedText)); + ctx.selections.append(sel); + + // draw text + doc->documentLayout()->draw(painter, ctx); + } + + Q_UNUSED(option) + Q_UNUSED(widget) +} + +void Text::visibilityChanged(bool visible) +{ + isVisible = visible; + + if(visible) + ensureIntegrity(); + else + freeResources(); +} + +qreal Text::firstLineVOffset() +{ + return vOffset; +} + +void Text::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if(event->button() == Qt::LeftButton) + event->accept(); // grabber +} + +void Text::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + QString anchor = doc->documentLayout()->anchorAt(event->pos()); + + // open anchors in browser + if(!anchor.isEmpty()) + QDesktopServices::openUrl(anchor); +} + +void Text::ensureIntegrity() +{ + if(!doc) + { + doc = new QTextDocument(); + doc->setUndoRedoEnabled(false); + doc->setUseDesignMetrics(true); + + if(!elide) + { + doc->setHtml(text); + } + else + { + QTextOption opt; + opt.setWrapMode(QTextOption::NoWrap); + doc->setDefaultTextOption(opt); + doc->setPlainText(elidedText); + + } + + cursor = QTextCursor(doc); + count++; + } + + doc->setTextWidth(width); + doc->documentLayout()->update(); + + if(doc->firstBlock().layout()->lineCount() > 0) + vOffset = doc->firstBlock().layout()->lineAt(0).ascent(); + + if(size != idealSize()) + { + prepareGeometryChange(); + size = idealSize(); + } +} + +void Text::freeResources() +{ + if(doc && !isVisible && !cursor.hasSelection()) + { + delete doc; + doc = nullptr; + cursor = QTextCursor(); + + count--; + } +} + +QSizeF Text::idealSize() +{ + if(doc) + return QSizeF(doc->idealWidth(), doc->size().height()); + + return QSizeF(); +} + +int Text::cursorFromPos(QPointF scenePos) const +{ + if(doc) + return doc->documentLayout()->hitTest(mapFromScene(scenePos), Qt::ExactHit); + + return -1; +} diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h new file mode 100644 index 000000000..edcdd486d --- /dev/null +++ b/src/chatlog/content/text.h @@ -0,0 +1,62 @@ +#ifndef TEXT_H +#define TEXT_H + +#include "../chatlinecontent.h" + +#include +#include + +class ChatLine; +class QTextLayout; + +class Text : public ChatLineContent +{ +public: + Text(const QString& txt = "", bool enableElide = false); + virtual ~Text(); + + void setText(const QString& txt); + + virtual void setWidth(qreal width); + + virtual void selectionMouseMove(QPointF scenePos); + virtual void selectionStarted(QPointF scenePos); + virtual void selectionCleared(); + virtual void selectAll(); + virtual bool isOverSelection(QPointF scenePos) const; + virtual QString getSelectedText() const; + + virtual QRectF boundingSceneRect() const; + virtual QRectF boundingRect() const; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + virtual void visibilityChanged(bool isVisible); + + virtual qreal firstLineVOffset(); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + + static int count; + +protected: + // dynamic resource management + void ensureIntegrity(); + void freeResources(); + QSizeF idealSize(); + + int cursorFromPos(QPointF scenePos) const; + +private: + QTextDocument* doc = nullptr; + QString text; + QString elidedText; + QSizeF size; + bool isVisible = false; + bool elide = false; + QTextCursor cursor; + qreal vOffset = 0.0; + qreal width = 0.0; + +}; + +#endif // TEXT_H diff --git a/src/widget/chatareawidget.cpp b/src/widget/chatareawidget.cpp deleted file mode 100644 index 393a01c0e..000000000 --- a/src/widget/chatareawidget.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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 "tool/chatactions/chataction.h" -#include -#include -#include -#include -#include -#include -#include - -ChatAreaWidget::ChatAreaWidget(QWidget *parent) - : QTextBrowser(parent) - , tableFrmt(nullptr) - , nameWidth(75) - , empty{true} -{ - setReadOnly(true); - viewport()->setCursor(Qt::ArrowCursor); - setContextMenuPolicy(Qt::CustomContextMenu); - setUndoRedoEnabled(false); - - setOpenExternalLinks(false); - setOpenLinks(false); - setAcceptRichText(false); - setFrameStyle(QFrame::NoFrame); - - nameFormat.setAlignment(Qt::AlignRight); - nameFormat.setNonBreakableLines(true); - dateFormat.setAlignment(Qt::AlignLeft); - dateFormat.setNonBreakableLines(true); - - connect(this, &ChatAreaWidget::anchorClicked, this, &ChatAreaWidget::onAnchorClicked); - connect(verticalScrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(onSliderRangeChanged())); -} - -ChatAreaWidget::~ChatAreaWidget() -{ - if (tableFrmt) - delete tableFrmt; -} - -void ChatAreaWidget::mouseReleaseEvent(QMouseEvent * event) -{ - QTextEdit::mouseReleaseEvent(event); - QPointF documentHitPost(event->pos().x() + horizontalScrollBar()->value(), event->pos().y() + verticalScrollBar()->value()); - int pos = this->document()->documentLayout()->hitTest(documentHitPost, 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 imageName = format.toImageFormat().name(); - if (QRegExp("^data:ftrans.*").exactMatch(imageName)) - { - QString data = imageName.right(imageName.length() - 12); - int endpos = data.indexOf("/png;base64"); - data = data.left(endpos); - int middlepos = data.indexOf("."); - QString widgetID = data.left(middlepos); - QString widgetBtn = data.right(data.length() - middlepos - 1); - qDebug() << "ChatAreaWidget::mouseReleaseEvent:" << widgetID << widgetBtn; - emit onFileTranfertInterract(widgetID, widgetBtn); - } - } - } - } -} - -void ChatAreaWidget::onAnchorClicked(const QUrl &url) -{ - QDesktopServices::openUrl(url); -} - -void ChatAreaWidget::insertMessage(ChatActionPtr msgAction, QTextCursor::MoveOperation pos) -{ - if (msgAction == nullptr) - return; - - checkSlider(); - - QTextTable *chatTextTable = getMsgTable(pos); - msgAction->assignPlace(chatTextTable, this); - msgAction->dispaly(); - - /* - QTextCursor cur = chatTextTable->cellAt(0, 2).firstCursorPosition(); - cur.clearSelection(); - cur.setKeepPositionOnInsert(true); - chatTextTable->cellAt(0, 0).firstCursorPosition().setBlockFormat(nameFormat); - chatTextTable->cellAt(0, 0).firstCursorPosition().insertHtml(msgAction->getName()); - chatTextTable->cellAt(0, 2).firstCursorPosition().insertHtml(msgAction->getMessage()); - chatTextTable->cellAt(0, 4).firstCursorPosition().setBlockFormat(dateFormat); - chatTextTable->cellAt(0, 4).firstCursorPosition().insertHtml(msgAction->getDate()); - msgAction->setup(cur, this); - */ - - if (msgAction->isInteractive()) - messages.append(msgAction); - - empty = false; -} - -bool ChatAreaWidget::isEmpty() -{ - return empty; -} - -void ChatAreaWidget::onSliderRangeChanged() -{ - QScrollBar* scroll = verticalScrollBar(); - if (lockSliderToBottom) - scroll->setValue(scroll->maximum()); -} - -void ChatAreaWidget::checkSlider() -{ - QScrollBar* scroll = verticalScrollBar(); - lockSliderToBottom = scroll && scroll->value() == scroll->maximum(); -} - -QTextTable *ChatAreaWidget::getMsgTable(QTextCursor::MoveOperation pos) -{ - if (tableFrmt == nullptr) - { - tableFrmt = new QTextTableFormat(); - tableFrmt->setCellSpacing(2); - tableFrmt->setBorderStyle(QTextFrameFormat::BorderStyle_None); - tableFrmt->setColumnWidthConstraints({QTextLength(QTextLength::FixedLength,nameWidth), - QTextLength(QTextLength::FixedLength,2), - QTextLength(QTextLength::PercentageLength,100), - QTextLength(QTextLength::FixedLength,2), - QTextLength(QTextLength::VariableLength,0)}); - } - - QTextCursor tc = textCursor(); - tc.movePosition(pos); - - QTextTable *chatTextTable = tc.insertTable(1, 5, *tableFrmt); - - return chatTextTable; -} - -void ChatAreaWidget::setNameColWidth(int w) -{ - if (tableFrmt != nullptr) - { - delete tableFrmt; - tableFrmt = nullptr; - } - - nameWidth = w; -} - -void ChatAreaWidget::clearChatArea() -{ - QList newMsgs; - for (ChatActionPtr message : messages) - { - if (message->isInteractive()) - { - newMsgs.append(message); - } - } - messages.clear(); - this->clear(); - empty = true; - - for (ChatActionPtr message : newMsgs) - { - insertMessage(message); - } -} - -void ChatAreaWidget::insertMessagesTop(QList &list) -{ - std::reverse(list.begin(), list.end()); - - for (ChatActionPtr it : list) - { - insertMessage(it, QTextCursor::Start); - } - - empty = false; -} diff --git a/src/widget/chatareawidget.h b/src/widget/chatareawidget.h deleted file mode 100644 index 2eda1aad4..000000000 --- a/src/widget/chatareawidget.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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 -#include -#include - -class QTextTable; - -class ChatAreaWidget : public QTextBrowser -{ - Q_OBJECT -public: - explicit ChatAreaWidget(QWidget *parent = 0); - virtual ~ChatAreaWidget(); - void insertMessage(ChatActionPtr msgAction, QTextCursor::MoveOperation pos = QTextCursor::End); - void insertMessagesTop(QList &list); - - int nameColWidth() {return nameWidth;} - void setNameColWidth(int w); - bool isEmpty(); - -public slots: - void clearChatArea(); - -signals: - void onFileTranfertInterract(QString widgetName, QString buttonName); - -protected: - void mouseReleaseEvent(QMouseEvent * event); - -private slots: - void onAnchorClicked(const QUrl& url); - void onSliderRangeChanged(); - -private: - void checkSlider(); - QTextTable* getMsgTable(QTextCursor::MoveOperation pos = QTextCursor::End); - - QTextTableFormat* tableFrmt; - QList messages; - bool lockSliderToBottom; - int sliderPosition; - int nameWidth; - QTextBlockFormat nameFormat, dateFormat; - bool empty; -}; - -#endif // CHATAREAWIDGET_H diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 9850e4c36..23b8d9da7 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -29,9 +29,7 @@ #include "src/friend.h" #include "src/widget/friendwidget.h" #include "src/filetransferinstance.h" -#include "src/widget/tool/chatactions/filetransferaction.h" #include "src/widget/netcamview.h" -#include "src/widget/chatareawidget.h" #include "src/widget/tool/chattextedit.h" #include "src/core.h" #include "src/widget/widget.h" @@ -75,7 +73,7 @@ ChatForm::ChatForm(Friend* chatFriend) connect(msgEdit, &ChatTextEdit::enterPressed, this, &ChatForm::onSendTriggered); connect(micButton, SIGNAL(clicked()), this, SLOT(onMicMuteToggle())); connect(volButton, SIGNAL(clicked()), this, SLOT(onVolMuteToggle())); - connect(chatWidget, &ChatAreaWidget::onFileTranfertInterract, this, &ChatForm::onFileTansBtnClicked); + //TODO: connect(chatWidget, &ChatAreaWidget::onFileTranfertInterract, this, &ChatForm::onFileTansBtnClicked); connect(Core::getInstance(), &Core::fileSendFailed, this, &ChatForm::onFileSendFailed); connect(this, SIGNAL(chatAreaCleared()), this, SLOT(clearReciepts())); @@ -121,7 +119,7 @@ void ChatForm::onSendTriggered() int id = HistoryKeeper::getInstance()->addChatEntry(f->getToxID().publicKey, qt_msg_hist, Core::getInstance()->getSelfId().publicKey, timestamp, status); - MessageActionPtr ma = addSelfMessage(msg, isAction, timestamp, false); + //MessageActionPtr ma = addSelfMessage(msg, isAction, timestamp, false); int rec; if (isAction) @@ -129,7 +127,7 @@ void ChatForm::onSendTriggered() else rec = Core::getInstance()->sendMessage(f->getFriendID(), msg); - registerReceipt(rec, id, ma); + //registerReceipt(rec, id, ma); } msgEdit->clear(); @@ -183,8 +181,9 @@ void ChatForm::startFileSend(ToxFile file) previousId = core->getSelfId(); } - chatWidget->insertMessage(ChatActionPtr(new FileTransferAction(fileTrans, getElidedName(name), - QTime::currentTime().toString("hh:mm"), true))); + //TODO: +// chatWidget->insertMessage(ChatActionPtr(new FileTransferAction(fileTrans, getElidedName(name), +// QTime::currentTime().toString("hh:mm"), true))); } void ChatForm::onFileRecvRequest(ToxFile file) @@ -219,8 +218,8 @@ void ChatForm::onFileRecvRequest(ToxFile file) previousId = friendId; } - chatWidget->insertMessage(ChatActionPtr(new FileTransferAction(fileTrans, getElidedName(name), - QTime::currentTime().toString("hh:mm"), false))); + //TODO: chatWidget->insertMessage(ChatActionPtr(new FileTransferAction(fileTrans, getElidedName(name), + // QTime::currentTime().toString("hh:mm"), false))); if (!Settings::getInstance().getAutoAcceptDir(Core::getInstance()->getFriendAddress(f->getFriendID())).isEmpty() || Settings::getInstance().getAutoSaveEnabled()) @@ -253,7 +252,7 @@ void ChatForm::onAvInvite(int FriendId, int CallId, bool video) connect(callButton, SIGNAL(clicked()), this, SLOT(onAnswerCallTriggered())); } - addSystemInfoMessage(tr("%1 calling").arg(f->getDisplayedName()), "white", QDateTime::currentDateTime()); + //TODO: addSystemInfoMessage(tr("%1 calling").arg(f->getDisplayedName()), "white", QDateTime::currentDateTime()); Widget* w = Widget::getInstance(); if (!w->isFriendWidgetCurActiveWidget(f)|| w->isMinimized() || !w->isActiveWindow()) @@ -322,7 +321,7 @@ void ChatForm::onAvCancel(int FriendId, int) netcam->hide(); - addSystemInfoMessage(tr("%1 stopped calling").arg(f->getDisplayedName()), "white", QDateTime::currentDateTime()); + //TODO: addSystemInfoMessage(tr("%1 stopped calling").arg(f->getDisplayedName()), "white", QDateTime::currentDateTime()); } void ChatForm::onAvEnd(int FriendId, int) @@ -378,7 +377,7 @@ void ChatForm::onAvRinging(int FriendId, int CallId, bool video) connect(callButton, SIGNAL(clicked()), this, SLOT(onCancelCallTriggered())); } - addSystemInfoMessage(tr("Calling to %1").arg(f->getDisplayedName()), "white", QDateTime::currentDateTime()); + //TODO: addSystemInfoMessage(tr("Calling to %1").arg(f->getDisplayedName()), "white", QDateTime::currentDateTime()); } void ChatForm::onAvStarting(int FriendId, int CallId, bool video) @@ -519,7 +518,7 @@ void ChatForm::onAvRejected(int FriendId, int) connect(callButton, SIGNAL(clicked()), this, SLOT(onCallTriggered())); connect(videoButton, SIGNAL(clicked()), this, SLOT(onVideoCallTriggered())); - addSystemInfoMessage(tr("Call rejected"), "white", QDateTime::currentDateTime()); + //TODO: addSystemInfoMessage(tr("Call rejected"), "white", QDateTime::currentDateTime()); netcam->hide(); } @@ -670,7 +669,7 @@ void ChatForm::onFileSendFailed(int FriendId, const QString &fname) if (FriendId != f->getFriendID()) return; - addSystemInfoMessage("File: \"" + fname + "\" failed to send.", "red", QDateTime::currentDateTime()); + //TODO: addSystemInfoMessage("File: \"" + fname + "\" failed to send.", "red", QDateTime::currentDateTime()); } void ChatForm::onAvatarChange(int FriendId, const QPixmap &pic) @@ -731,49 +730,49 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) ToxID storedPrevId; std::swap(storedPrevId, previousId); - QList historyMessages; + //QList historyMessages; - QDate lastDate(1,0,0); - for (const auto &it : msgs) - { - // Show the date every new day - QDateTime msgDateTime = it.timestamp.toLocalTime(); - QDate msgDate = msgDateTime.date(); - if (msgDate > lastDate) - { - lastDate = msgDate; - historyMessages.append(genSystemInfoAction(msgDate.toString(),"",QDateTime())); - } +// QDate lastDate(1,0,0); +// for (const auto &it : msgs) +// { +// // Show the date every new day +// QDateTime msgDateTime = it.timestamp.toLocalTime(); +// QDate msgDate = msgDateTime.date(); +// if (msgDate > lastDate) +// { +// lastDate = msgDate; +// historyMessages.append(genSystemInfoAction(msgDate.toString(),"",QDateTime())); +// } - // Show each messages - MessageActionPtr ca = genMessageActionAction(ToxID::fromString(it.sender), it.message, false, msgDateTime); - if (it.isSent) - { - ca->markAsSent(); - } else { - if (processUndelivered) - { - int rec; - if (ca->isAction()) - rec = Core::getInstance()->sendAction(f->getFriendID(), ca->getRawMessage()); - else - rec = Core::getInstance()->sendMessage(f->getFriendID(), ca->getRawMessage()); - registerReceipt(rec, it.id, ca); - } - } - historyMessages.append(ca); - } - std::swap(storedPrevId, previousId); +// // Show each messages +// MessageActionPtr ca = genMessageActionAction(ToxID::fromString(it.sender), it.message, false, msgDateTime); +// if (it.isSent) +// { +// ca->markAsSent(); +// } else { +// if (processUndelivered) +// { +// int rec; +// if (ca->isAction()) +// rec = Core::getInstance()->sendAction(f->getFriendID(), ca->getRawMessage()); +// else +// rec = Core::getInstance()->sendMessage(f->getFriendID(), ca->getRawMessage()); +// registerReceipt(rec, it.id, ca); +// } +// } +// historyMessages.append(ca); +// } +// std::swap(storedPrevId, previousId); - int savedSliderPos = chatWidget->verticalScrollBar()->maximum() - chatWidget->verticalScrollBar()->value(); +// int savedSliderPos = chatWidget->verticalScrollBar()->maximum() - chatWidget->verticalScrollBar()->value(); - if (earliestMessage != nullptr) - *earliestMessage = since; +// if (earliestMessage != nullptr) +// *earliestMessage = since; - chatWidget->insertMessagesTop(historyMessages); +// chatWidget->insertMessagesTop(historyMessages); - savedSliderPos = chatWidget->verticalScrollBar()->maximum() - savedSliderPos; - chatWidget->verticalScrollBar()->setValue(savedSliderPos); +// savedSliderPos = chatWidget->verticalScrollBar()->maximum() - savedSliderPos; +// chatWidget->verticalScrollBar()->setValue(savedSliderPos); } void ChatForm::onLoadHistory() @@ -803,9 +802,10 @@ void ChatForm::stopCounter() { if(timer) { - addSystemInfoMessage(tr("Call with %1 ended. %2").arg(f->getDisplayedName(), - secondsToDHMS(timeElapsed.elapsed()/1000)), - "white", QDateTime::currentDateTime()); + //TODO: +// addSystemInfoMessage(tr("Call with %1 ended. %2").arg(f->getDisplayedName(), +// secondsToDHMS(timeElapsed.elapsed()/1000)), +// "white", QDateTime::currentDateTime()); timer->stop(); callDuration->setText(""); callDuration->hide(); @@ -842,52 +842,52 @@ QString ChatForm::secondsToDHMS(quint32 duration) return cD + res.sprintf("%dd%02dh %02dm %02ds", days, hours, minutes, seconds); } -void ChatForm::registerReceipt(int receipt, int messageID, MessageActionPtr msg) -{ - receipts[receipt] = messageID; - undeliveredMsgs[messageID] = msg; -} +//void ChatForm::registerReceipt(int receipt, int messageID, MessageActionPtr msg) +//{ +// receipts[receipt] = messageID; +// undeliveredMsgs[messageID] = msg; +//} -void ChatForm::dischargeReceipt(int receipt) -{ - auto it = receipts.find(receipt); - if (it != receipts.end()) - { - int mID = it.value(); - auto msgIt = undeliveredMsgs.find(mID); - if (msgIt != undeliveredMsgs.end()) - { - HistoryKeeper::getInstance()->markAsSent(mID); - msgIt.value()->markAsSent(); - msgIt.value()->featureUpdate(); - undeliveredMsgs.erase(msgIt); - } - receipts.erase(it); - } -} +//void ChatForm::dischargeReceipt(int receipt) +//{ +// auto it = receipts.find(receipt); +// if (it != receipts.end()) +// { +// int mID = it.value(); +// auto msgIt = undeliveredMsgs.find(mID); +// if (msgIt != undeliveredMsgs.end()) +// { +// HistoryKeeper::getInstance()->markAsSent(mID); +// msgIt.value()->markAsSent(); +// msgIt.value()->featureUpdate(); +// undeliveredMsgs.erase(msgIt); +// } +// receipts.erase(it); +// } +//} void ChatForm::clearReciepts() { - receipts.clear(); - undeliveredMsgs.clear(); +// receipts.clear(); +// undeliveredMsgs.clear(); } void ChatForm::deliverOfflineMsgs() { - if (!Settings::getInstance().getFauxOfflineMessaging()) - return; +// if (!Settings::getInstance().getFauxOfflineMessaging()) +// return; - QMap msgs = undeliveredMsgs; - clearReciepts(); +// QMap msgs = undeliveredMsgs; +// clearReciepts(); - for (auto iter = msgs.begin(); iter != msgs.end(); iter++) - { - QString messageText = iter.value()->getRawMessage(); - int rec; - if (iter.value()->isAction()) - rec = Core::getInstance()->sendAction(f->getFriendID(), messageText); - else - rec = Core::getInstance()->sendMessage(f->getFriendID(), messageText); - registerReceipt(rec, iter.key(), iter.value()); - } +// for (auto iter = msgs.begin(); iter != msgs.end(); iter++) +// { +// QString messageText = iter.value()->getRawMessage(); +// int rec; +// if (iter.value()->isAction()) +// rec = Core::getInstance()->sendAction(f->getFriendID(), messageText); +// else +// rec = Core::getInstance()->sendMessage(f->getFriendID(), messageText); +// registerReceipt(rec, iter.key(), iter.value()); +// } } diff --git a/src/widget/form/chatform.h b/src/widget/form/chatform.h index 2a051f84e..faf1b5400 100644 --- a/src/widget/form/chatform.h +++ b/src/widget/form/chatform.h @@ -89,7 +89,7 @@ protected: // drag & drop void dragEnterEvent(QDragEnterEvent* ev); void dropEvent(QDropEvent* ev); - void registerReceipt(int receipt, int messageID, MessageActionPtr msg); + //TODO: void registerReceipt(int receipt, int messageID, MessageActionPtr msg); private: Friend* f; @@ -107,7 +107,7 @@ private: void stopCounter(); QString secondsToDHMS(quint32 duration); QHash receipts; - QMap undeliveredMsgs; + //TODO: QMap undeliveredMsgs; }; #endif // CHATFORM_H diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index ffe6f8ecb..785b63354 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -23,16 +23,12 @@ #include "src/misc/style.h" #include "src/widget/widget.h" #include "src/misc/settings.h" -#include "src/widget/tool/chatactions/messageaction.h" -#include "src/widget/tool/chatactions/systemmessageaction.h" -#include "src/widget/tool/chatactions/actionaction.h" -#include "src/widget/tool/chatactions/alertaction.h" -#include "src/widget/chatareawidget.h" #include "src/widget/tool/chattextedit.h" #include "src/widget/maskablepixmapwidget.h" #include "src/core.h" #include "src/friendlist.h" #include "src/friend.h" +#include "src/chatlog/chatlog.h" GenericChatForm::GenericChatForm(QWidget *parent) : QWidget(parent), @@ -52,7 +48,7 @@ GenericChatForm::GenericChatForm(QWidget *parent) : QVBoxLayout *mainLayout = new QVBoxLayout(); QVBoxLayout *footButtonsSmall = new QVBoxLayout(), *volMicLayout = new QVBoxLayout(); - chatWidget = new ChatAreaWidget(); + chatWidget = new ChatLog(this); msgEdit = new ChatTextEdit(); @@ -146,16 +142,16 @@ GenericChatForm::GenericChatForm(QWidget *parent) : connect(emoteButton, SIGNAL(clicked()), this, SLOT(onEmoteButtonClicked())); connect(chatWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onChatContextMenuRequested(QPoint))); - chatWidget->document()->setDefaultStyleSheet(Style::getStylesheet(":ui/chatArea/innerStyle.css")); - chatWidget->setStyleSheet(Style::getStylesheet(":/ui/chatArea/chatArea.css")); + //chatWidget->document()->setDefaultStyleSheet(Style::getStylesheet(":ui/chatArea/innerStyle.css")); + //chatWidget->setStyleSheet(Style::getStylesheet(":/ui/chatArea/chatArea.css")); headWidget->setStyleSheet(Style::getStylesheet(":/ui/chatArea/chatHead.css")); - ChatAction::setupFormat(); + //ChatAction::setupFormat(); } bool GenericChatForm::isEmpty() { - return chatWidget->isEmpty(); + //return chatWidget->isEmpty(); } void GenericChatForm::setName(const QString &newName) @@ -181,70 +177,70 @@ void GenericChatForm::onChatContextMenuRequested(QPoint pos) void GenericChatForm::onSaveLogClicked() { - QString path = QFileDialog::getSaveFileName(0, tr("Save chat log")); - if (path.isEmpty()) - return; +// QString path = QFileDialog::getSaveFileName(0, tr("Save chat log")); +// if (path.isEmpty()) +// return; - QFile file(path); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) - return; +// QFile file(path); +// if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) +// return; - QString log; - log = chatWidget->toPlainText(); +// QString log; +// log = chatWidget->toPlainText(); - file.write(log.toUtf8()); - file.close(); +// file.write(log.toUtf8()); +// file.close(); } /** * @deprecated The only reason it's still alive is because the groupchat API is a bit limited */ -void GenericChatForm::addMessage(const QString& author, const QString &message, bool isAction, const QDateTime &datetime) -{ - MessageActionPtr ca = genMessageActionAction(author, message, isAction, datetime); - ca->markAsSent(); - chatWidget->insertMessage(ca); -} +//void GenericChatForm::addMessage(const QString& author, const QString &message, bool isAction, const QDateTime &datetime) +//{ +// MessageActionPtr ca = genMessageActionAction(author, message, isAction, datetime); +// ca->markAsSent(); +// chatWidget->insertMessage(ca); +//} -MessageActionPtr GenericChatForm::addMessage(const ToxID& author, const QString &message, bool isAction, - const QDateTime &datetime, bool isSent) -{ - MessageActionPtr ca = genMessageActionAction(author, message, isAction, datetime); - if (isSent) - ca->markAsSent(); - chatWidget->insertMessage(ca); - return ca; -} +//MessageActionPtr GenericChatForm::addMessage(const ToxID& author, const QString &message, bool isAction, +// const QDateTime &datetime, bool isSent) +//{ +// MessageActionPtr ca = genMessageActionAction(author, message, isAction, datetime); +// if (isSent) +// ca->markAsSent(); +// chatWidget->insertMessage(ca); +// return ca; +//} -MessageActionPtr GenericChatForm::addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime, bool isSent) -{ - MessageActionPtr ca = genSelfActionAction(message, isAction, datetime); - if (isSent) - ca->markAsSent(); - chatWidget->insertMessage(ca); - return ca; -} +//MessageActionPtr GenericChatForm::addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime, bool isSent) +//{ +// MessageActionPtr ca = genSelfActionAction(message, isAction, datetime); +// if (isSent) +// ca->markAsSent(); +// chatWidget->insertMessage(ca); +// return ca; +//} /** * @deprecated The only reason it's still alive is because the groupchat API is a bit limited */ -void GenericChatForm::addAlertMessage(const QString& author, QString message, QDateTime datetime) -{ - QString date = datetime.toString(Settings::getInstance().getTimestampFormat()); - AlertAction *alact = new AlertAction(author, message, date); - alact->markAsSent(); - chatWidget->insertMessage(ChatActionPtr(alact)); +//void GenericChatForm::addAlertMessage(const QString& author, QString message, QDateTime datetime) +//{ +// QString date = datetime.toString(Settings::getInstance().getTimestampFormat()); +// AlertAction *alact = new AlertAction(author, message, date); +// alact->markAsSent(); +// chatWidget->insertMessage(ChatActionPtr(alact)); - previousId.publicKey = author; -} +// previousId.publicKey = author; +//} -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::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() { @@ -278,158 +274,158 @@ 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) +//{ +// ChatActionPtr ca = genSystemInfoAction(message, type, datetime); +// chatWidget->insertMessage(ca); +//} -QString GenericChatForm::getElidedName(const QString& name) -{ - // update this whenever you change the font in innerStyle.css - QFontMetrics fm(Style::getFont(Style::BigBold)); +//QString GenericChatForm::getElidedName(const QString& name) +//{ +// // update this whenever you change the font in innerStyle.css +// QFontMetrics fm(Style::getFont(Style::BigBold)); - return fm.elidedText(name, Qt::ElideRight, chatWidget->nameColWidth()); -} +// return fm.elidedText(name, Qt::ElideRight, chatWidget->nameColWidth()); +//} void GenericChatForm::clearChatArea(bool notinform) { - chatWidget->clearChatArea(); - previousId = ToxID(); +// chatWidget->clearChatArea(); +// 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(); } /** * @deprecated The only reason it's still alive is because the groupchat API is a bit limited */ -MessageActionPtr GenericChatForm::genMessageActionAction(const QString &author, QString message, bool isAction, - const QDateTime &datetime) -{ - if (earliestMessage == nullptr) - { - earliestMessage = new QDateTime(datetime); - } +//MessageActionPtr GenericChatForm::genMessageActionAction(const QString &author, QString message, bool isAction, +// const QDateTime &datetime) +//{ +// if (earliestMessage == nullptr) +// { +// earliestMessage = new QDateTime(datetime); +// } - QString date = datetime.toString(Settings::getInstance().getTimestampFormat()); - bool isMe = (author == Widget::getInstance()->getUsername()); +// QString date = datetime.toString(Settings::getInstance().getTimestampFormat()); +// bool isMe = (author == Widget::getInstance()->getUsername()); - if (!isAction && message.startsWith("/me ")) - { // always render actions regardless of what core thinks - isAction = true; - message = message.right(message.length()-4); - } +// if (!isAction && message.startsWith("/me ")) +// { // always render actions regardless of what core thinks +// isAction = true; +// message = message.right(message.length()-4); +// } - if (isAction) - { - previousId = ToxID(); // next msg has a name regardless - return MessageActionPtr(new ActionAction (getElidedName(author), message, date, isMe)); - } +// if (isAction) +// { +// previousId = ToxID(); // next msg has a name regardless +// return MessageActionPtr(new ActionAction (getElidedName(author), message, date, isMe)); +// } - MessageActionPtr res; - if (previousId.publicKey == author) - res = MessageActionPtr(new MessageAction(QString(), message, date, isMe)); - else - res = MessageActionPtr(new MessageAction(getElidedName(author), message, date, isMe)); +// MessageActionPtr res; +// if (previousId.publicKey == author) +// res = MessageActionPtr(new MessageAction(QString(), message, date, isMe)); +// else +// res = MessageActionPtr(new MessageAction(getElidedName(author), message, date, isMe)); - previousId.publicKey = author; - return res; -} +// previousId.publicKey = author; +// return res; +//} -MessageActionPtr GenericChatForm::genMessageActionAction(const ToxID& author, QString message, bool isAction, const QDateTime &datetime) -{ - if (earliestMessage == nullptr) - { - earliestMessage = new QDateTime(datetime); - } +//MessageActionPtr GenericChatForm::genMessageActionAction(const ToxID& author, QString message, bool isAction, const QDateTime &datetime) +//{ +// if (earliestMessage == nullptr) +// { +// earliestMessage = new QDateTime(datetime); +// } - const Core* core = Core::getInstance(); +// const Core* core = Core::getInstance(); - QString date = datetime.toString(Settings::getInstance().getTimestampFormat()); - bool isMe = (author == core->getSelfId()); - QString authorStr; - if (isMe) - authorStr = core->getUsername(); - else { - Friend *f = FriendList::findFriend(author.publicKey); - if (f) - authorStr = f->getDisplayedName(); - else - authorStr = core->getPeerName(author); - } +// QString date = datetime.toString(Settings::getInstance().getTimestampFormat()); +// bool isMe = (author == core->getSelfId()); +// QString authorStr; +// if (isMe) +// authorStr = core->getUsername(); +// else { +// Friend *f = FriendList::findFriend(author.publicKey); +// if (f) +// authorStr = f->getDisplayedName(); +// else +// authorStr = core->getPeerName(author); +// } - if (authorStr.isEmpty()) // Fallback if we can't find a username - authorStr = author.toString(); +// if (authorStr.isEmpty()) // Fallback if we can't find a username +// authorStr = author.toString(); - if (!isAction && message.startsWith("/me ")) - { // always render actions regardless of what core thinks - isAction = true; - message = message.right(message.length()-4); - } +// if (!isAction && message.startsWith("/me ")) +// { // always render actions regardless of what core thinks +// isAction = true; +// message = message.right(message.length()-4); +// } - if (isAction) - { - previousId = ToxID(); // next msg has a name regardless - return MessageActionPtr(new ActionAction (getElidedName(authorStr), message, date, isMe)); - } +// if (isAction) +// { +// previousId = ToxID(); // next msg has a name regardless +// return MessageActionPtr(new ActionAction (getElidedName(authorStr), message, date, isMe)); +// } - MessageActionPtr res; - if (previousId == author) - res = MessageActionPtr(new MessageAction(QString(), message, date, isMe)); - else - res = MessageActionPtr(new MessageAction(getElidedName(authorStr), message, date, isMe)); +// MessageActionPtr res; +// if (previousId == author) +// res = MessageActionPtr(new MessageAction(QString(), message, date, isMe)); +// else +// res = MessageActionPtr(new MessageAction(getElidedName(authorStr), message, date, isMe)); - previousId = author; - return res; -} +// previousId = author; +// return res; +//} -MessageActionPtr GenericChatForm::genSelfActionAction(QString message, bool isAction, const QDateTime &datetime) -{ - if (earliestMessage == nullptr) - { - earliestMessage = new QDateTime(datetime); - } +//MessageActionPtr GenericChatForm::genSelfActionAction(QString message, bool isAction, const QDateTime &datetime) +//{ +// if (earliestMessage == nullptr) +// { +// earliestMessage = new QDateTime(datetime); +// } - const Core* core = Core::getInstance(); +// const Core* core = Core::getInstance(); - QString date = datetime.toString(Settings::getInstance().getTimestampFormat()); - QString author = core->getUsername();; +// QString date = datetime.toString(Settings::getInstance().getTimestampFormat()); +// QString author = core->getUsername();; - if (!isAction && message.startsWith("/me ")) - { // always render actions regardless of what core thinks - isAction = true; - message = message.right(message.length()-4); - } +// if (!isAction && message.startsWith("/me ")) +// { // always render actions regardless of what core thinks +// isAction = true; +// message = message.right(message.length()-4); +// } - if (isAction) - { - previousId = ToxID(); // next msg has a name regardless - return MessageActionPtr(new ActionAction (getElidedName(author), message, date, true)); - } +// if (isAction) +// { +// previousId = ToxID(); // next msg has a name regardless +// return MessageActionPtr(new ActionAction (getElidedName(author), message, date, true)); +// } - MessageActionPtr res; - if (previousId.isMine()) - res = MessageActionPtr(new MessageAction(QString(), message, date, true)); - else - res = MessageActionPtr(new MessageAction(getElidedName(author), message, date, true)); +// MessageActionPtr res; +// if (previousId.isMine()) +// res = MessageActionPtr(new MessageAction(QString(), message, date, true)); +// else +// res = MessageActionPtr(new MessageAction(getElidedName(author), message, date, true)); - previousId = Core::getInstance()->getSelfId(); - return res; -} +// previousId = Core::getInstance()->getSelfId(); +// return res; +//} -ChatActionPtr GenericChatForm::genSystemInfoAction(const QString &message, const QString &type, const QDateTime &datetime) -{ - previousId = ToxID(); - QString date = datetime.toString(Settings::getInstance().getTimestampFormat()); +//ChatActionPtr GenericChatForm::genSystemInfoAction(const QString &message, const QString &type, const QDateTime &datetime) +//{ +// previousId = ToxID(); +// QString date = datetime.toString(Settings::getInstance().getTimestampFormat()); - return ChatActionPtr(new SystemMessageAction(message, type, date)); -} +// return ChatActionPtr(new SystemMessageAction(message, type, date)); +//} diff --git a/src/widget/form/genericchatform.h b/src/widget/form/genericchatform.h index ddd451ca7..9d967125a 100644 --- a/src/widget/form/genericchatform.h +++ b/src/widget/form/genericchatform.h @@ -21,7 +21,6 @@ #include #include #include -#include "src/widget/tool/chatactions/messageaction.h" #include "src/corestructs.h" // Spacing in px inserted when the author of the last message changes @@ -32,7 +31,7 @@ class QVBoxLayout; class QPushButton; class CroppingLabel; class ChatTextEdit; -class ChatAreaWidget; +class ChatLog; class MaskablePixmapWidget; struct ToxID; @@ -50,8 +49,8 @@ public: virtual void show(Ui::MainWindow &ui); void addMessage(const QString& author, const QString &message, bool isAction, const QDateTime &datetime); ///< Deprecated - MessageActionPtr addMessage(const ToxID& author, const QString &message, bool isAction, const QDateTime &datetime, bool isSent); - MessageActionPtr addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime, bool isSent); +// TODO: MessageActionPtr addMessage(const ToxID& author, const QString &message, bool isAction, const QDateTime &datetime, bool isSent); +// MessageActionPtr addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime, bool isSent); void addSystemInfoMessage(const QString &message, const QString &type, const QDateTime &datetime); void addAlertMessage(const QString& author, QString message, QDateTime datetime); ///< Deprecated void addAlertMessage(const ToxID& author, QString message, QDateTime datetime); @@ -74,10 +73,10 @@ protected slots: protected: QString getElidedName(const QString& name); - 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); +//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); ToxID previousId; QMenu menu; @@ -89,7 +88,7 @@ protected: QVBoxLayout *headTextLayout; ChatTextEdit *msgEdit; QPushButton *sendButton; - ChatAreaWidget *chatWidget; + ChatLog *chatWidget; QDateTime *earliestMessage; }; diff --git a/src/widget/tool/chatactions/actionaction.cpp b/src/widget/tool/chatactions/actionaction.cpp deleted file mode 100644 index 1063f070b..000000000 --- a/src/widget/tool/chatactions/actionaction.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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 "actionaction.h" -#include - -ActionAction::ActionAction(const QString &author, QString message, const QString &date, const bool& me) : - MessageAction(author, author+" "+message, date, me) -{ - rawMessage = message; -} - -QString ActionAction::getName() -{ - return QString("
*
"); -} - -QString ActionAction::getMessage() -{ - return MessageAction::getMessage("action"); -} - -QString ActionAction::getRawMessage() -{ - return rawMessage; -} diff --git a/src/widget/tool/chatactions/actionaction.h b/src/widget/tool/chatactions/actionaction.h deleted file mode 100644 index 62b101ef0..000000000 --- a/src/widget/tool/chatactions/actionaction.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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 ACTIONACTION_H -#define ACTIONACTION_H - -#include "messageaction.h" - -class ActionAction : public MessageAction -{ -public: - ActionAction(const QString &author, QString message, const QString& date, const bool&); - virtual ~ActionAction(){;} - virtual QString getRawMessage(); - virtual bool isAction() {return true;} - -protected: - virtual QString getMessage(); - virtual QString getName(); - -private: - QString message, rawMessage; -}; - -#endif // MESSAGEACTION_H diff --git a/src/widget/tool/chatactions/alertaction.cpp b/src/widget/tool/chatactions/alertaction.cpp deleted file mode 100644 index 23179340d..000000000 --- a/src/widget/tool/chatactions/alertaction.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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 "alertaction.h" - -AlertAction::AlertAction(const QString &author, const QString &message, const QString &date) : - MessageAction(author, message, date, false) -{ -} - -QString AlertAction::getMessage() -{ - return MessageAction::getMessage("alert"); -} diff --git a/src/widget/tool/chatactions/alertaction.h b/src/widget/tool/chatactions/alertaction.h deleted file mode 100644 index d37f355bd..000000000 --- a/src/widget/tool/chatactions/alertaction.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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 ALERTACTION_H -#define ALERTACTION_H - -#include "messageaction.h" - -class AlertAction : public MessageAction -{ -public: - AlertAction(const QString &author, const QString &message, const QString& date); - virtual ~AlertAction(){;} - -protected: - virtual QString getMessage(); - -private: - QString message; -}; - -#endif // MESSAGEACTION_H diff --git a/src/widget/tool/chatactions/chataction.cpp b/src/widget/tool/chatactions/chataction.cpp deleted file mode 100644 index a2aa3e140..000000000 --- a/src/widget/tool/chatactions/chataction.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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 "chataction.h" -#include -#include -#include -#include -#include - -QTextBlockFormat ChatAction::nameFormat, ChatAction::dateFormat; - -QString ChatAction::toHtmlChars(const QString &str) -{ - static QList> replaceList = {{"&","&"}, {">",">"}, {"<","<"}}; - 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::getName() -{ - if (isMe) - return QString("
%2
").arg("name_me").arg(toHtmlChars(name)); - else - return QString("
%2
").arg("name").arg(toHtmlChars(name)); -} - -QString ChatAction::getDate() -{ - if (isMe) - return QString("
" + toHtmlChars(date) + "
"); - else - return QString("
" + toHtmlChars(date) + "
"); -} - -void ChatAction::assignPlace(QTextTable *position, QTextEdit *te) -{ - textTable = position; - cur = position->cellAt(0, 2).firstCursorPosition(); - cur.clearSelection(); - cur.setKeepPositionOnInsert(true); - textEdit = te; -} - -void ChatAction::dispaly() -{ - textTable->cellAt(0, 0).firstCursorPosition().setBlockFormat(nameFormat); - textTable->cellAt(0, 0).firstCursorPosition().insertHtml(getName()); - textTable->cellAt(0, 2).firstCursorPosition().insertHtml(getMessage()); - textTable->cellAt(0, 4).firstCursorPosition().setBlockFormat(dateFormat); - textTable->cellAt(0, 4).firstCursorPosition().insertHtml(getDate()); - - cur.setKeepPositionOnInsert(true); - int end=cur.selectionEnd(); - cur.setPosition(cur.position()); - cur.setPosition(end, QTextCursor::KeepAnchor); - - featureUpdate(); -} - -void ChatAction::setupFormat() -{ - nameFormat.setAlignment(Qt::AlignRight); - nameFormat.setNonBreakableLines(true); - dateFormat.setAlignment(Qt::AlignLeft); - dateFormat.setNonBreakableLines(true); -} - -void ChatAction::updateContent() -{ - if (cur.isNull() || !textEdit) - return; - - int vSliderVal = textEdit->verticalScrollBar()->value(); - - // update content - int pos = cur.selectionStart(); - cur.removeSelectedText(); - cur.setKeepPositionOnInsert(false); - cur.insertHtml(getMessage()); - cur.setKeepPositionOnInsert(true); - int end = cur.position(); - cur.setPosition(pos); - cur.setPosition(end, QTextCursor::KeepAnchor); - - // restore old slider value - textEdit->verticalScrollBar()->setValue(vSliderVal); - - featureUpdate(); -} diff --git a/src/widget/tool/chatactions/chataction.h b/src/widget/tool/chatactions/chataction.h deleted file mode 100644 index b007ecb60..000000000 --- a/src/widget/tool/chatactions/chataction.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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 -#include -#include - -class FileTransferInstance; -class QTextEdit; -class QTextTable; - -class ChatAction : public QObject -{ - Q_OBJECT -public: - ChatAction(const bool &me, const QString &author, const QString &date) : isMe(me), name(author), date(date) {;} - virtual ~ChatAction(){;} - - void assignPlace(QTextTable *position, QTextEdit* te); - virtual void dispaly(); - virtual bool isInteractive(){return false;} - virtual void featureUpdate() {;} - - static void setupFormat(); - -public slots: - void updateContent(); - -protected: - virtual QString getName(); - virtual QString getMessage() = 0; - virtual QString getDate(); - - QString toHtmlChars(const QString &str); - QString QImage2base64(const QImage &img); - -protected: - bool isMe; - QString name, date; - - QTextTable *textTable; - QTextEdit *textEdit; - QTextCursor cur; - - static QTextBlockFormat nameFormat, dateFormat; -}; - -typedef QSharedPointer ChatActionPtr; - -#endif // CHATACTION_H diff --git a/src/widget/tool/chatactions/filetransferaction.cpp b/src/widget/tool/chatactions/filetransferaction.cpp deleted file mode 100644 index 103e72f36..000000000 --- a/src/widget/tool/chatactions/filetransferaction.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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 "filetransferaction.h" -#include "src/filetransferinstance.h" - -#include -#include - -FileTransferAction::FileTransferAction(FileTransferInstance *widget, const QString &author, const QString &date, const bool &me) - : ChatAction(me, author, date) -{ - w = widget; - - connect(w, &FileTransferInstance::stateUpdated, this, &FileTransferAction::updateContent); -} - -FileTransferAction::~FileTransferAction() -{ -} - -QString FileTransferAction::getMessage() -{ - QString widgetHtml; - if (w != nullptr) - widgetHtml = w->getHtmlImage(); - else - widgetHtml = "
EMPTY CONTENT
"; - return widgetHtml; -} - -/* -void FileTransferAction::setup(QTextCursor cursor, QTextEdit *textEdit) -{ - cur = cursor; - cur.setKeepPositionOnInsert(true); - int end=cur.selectionEnd(); - cur.setPosition(cur.position()); - cur.setPosition(end, QTextCursor::KeepAnchor); - - edit = textEdit; -} -*/ -/* -void FileTransferAction::updateHtml() -{ - if (cur.isNull() || !edit) - return; - - // save old slider value - int vSliderVal = edit->verticalScrollBar()->value(); - - // update content - int pos = cur.selectionStart(); - cur.removeSelectedText(); - cur.setKeepPositionOnInsert(false); - cur.insertHtml(getMessage()); - cur.setKeepPositionOnInsert(true); - int end = cur.position(); - cur.setPosition(pos); - cur.setPosition(end, QTextCursor::KeepAnchor); - - // restore old slider value - edit->verticalScrollBar()->setValue(vSliderVal); -} -*/ -bool FileTransferAction::isInteractive() -{ - if (w->getState() == FileTransferInstance::TransfState::tsCanceled - || w->getState() == FileTransferInstance::TransfState::tsFinished) - { - return false; - } - - return true; -} diff --git a/src/widget/tool/chatactions/filetransferaction.h b/src/widget/tool/chatactions/filetransferaction.h deleted file mode 100644 index 696d4a5c0..000000000 --- a/src/widget/tool/chatactions/filetransferaction.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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 FILETRANSFERACTION_H -#define FILETRANSFERACTION_H - -#include "chataction.h" - -class FileTransferAction : public ChatAction -{ - Q_OBJECT -public: - FileTransferAction(FileTransferInstance *widget, const QString &author, const QString &date, const bool &me); - virtual ~FileTransferAction(); - virtual bool isInteractive(); - -protected: - virtual QString getMessage(); - -private: - FileTransferInstance *w; -}; - -#endif // FILETRANSFERACTION_H diff --git a/src/widget/tool/chatactions/messageaction.cpp b/src/widget/tool/chatactions/messageaction.cpp deleted file mode 100644 index 42e46bc79..000000000 --- a/src/widget/tool/chatactions/messageaction.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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 "messageaction.h" -#include "src/misc/smileypack.h" -#include "src/misc/settings.h" -#include - -MessageAction::MessageAction(const QString &author, const QString &message, const QString &date, const bool &me) : - ChatAction(me, author, date), - message(message) -{ - isProcessed = false; -} - -QString MessageAction::getMessage(QString div) -{ - QString message_; - if(Settings::getInstance().getUseEmoticons()) - message_ = SmileyPack::getInstance().smileyfied(toHtmlChars(message)); - else - message_ = toHtmlChars(message); - - // detect urls - QRegExp exp("(?:\\b)(www\\.|http[s]?:\\/\\/|ftp:\\/\\/|tox:\\/\\/|tox:)\\S+"); - int offset = 0; - while ((offset = exp.indexIn(message_, offset)) != -1) - { - QString url = exp.cap(); - - // add scheme if not specified - if (exp.cap(1) == "www.") - url.prepend("http://"); - - QString htmledUrl = QString("%1").arg(url); - message_.replace(offset, exp.cap().length(), htmledUrl); - - offset += htmledUrl.length(); - } - - // detect text quotes - QStringList messageLines = message_.split("\n"); - message_ = ""; - for (QString& s : messageLines) - { - if (QRegExp("^[ ]*>.*").exactMatch(s)) - message_ += "" + s + "
"; - else - message_ += s + "
"; - } - message_ = message_.left(message_.length()-4); - - return QString(QString("
").arg(div) + message_ + "
"); -} - -QString MessageAction::getMessage() -{ - if (isMe) - return getMessage("message_me"); - else - return getMessage("message"); -} - -void MessageAction::featureUpdate() -{ - QTextTableCell cell = textTable->cellAt(0,3); - QTextTableCellFormat format; - if (!isProcessed) - format.setBackground(QColor(Qt::red)); - else - format.setBackground(QColor(Qt::white)); - cell.setFormat(format); -} - -void MessageAction::markAsSent() -{ - isProcessed = true; -} - -QString MessageAction::getRawMessage() -{ - return message; -} diff --git a/src/widget/tool/chatactions/messageaction.h b/src/widget/tool/chatactions/messageaction.h deleted file mode 100644 index 9c11bbda4..000000000 --- a/src/widget/tool/chatactions/messageaction.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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 MESSAGEACTION_H -#define MESSAGEACTION_H - -#include "chataction.h" - -class MessageAction : public ChatAction -{ -public: - MessageAction(const QString &author, const QString &message, const QString &date, const bool &me); - virtual ~MessageAction(){;} - virtual void featureUpdate(); - void markAsSent(); - virtual QString getRawMessage(); - virtual bool isAction() {return false;} - -protected: - virtual QString getMessage(); - virtual QString getMessage(QString div); - -protected: - QString message; - bool isProcessed; -}; - -typedef QSharedPointer MessageActionPtr; - -#endif // MESSAGEACTION_H diff --git a/src/widget/tool/chatactions/systemmessageaction.cpp b/src/widget/tool/chatactions/systemmessageaction.cpp deleted file mode 100644 index 506370871..000000000 --- a/src/widget/tool/chatactions/systemmessageaction.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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 "systemmessageaction.h" - -SystemMessageAction::SystemMessageAction(const QString &message, const QString &type, const QString &date) : - ChatAction(false, QString(), date), - message(message), - type(type) -{ -} - -QString SystemMessageAction::getMessage() -{ - return QString("
" + message + "
"); -} diff --git a/src/widget/tool/chatactions/systemmessageaction.h b/src/widget/tool/chatactions/systemmessageaction.h deleted file mode 100644 index 99740cedc..000000000 --- a/src/widget/tool/chatactions/systemmessageaction.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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 SYSTEMMESSAGEACTION_H -#define SYSTEMMESSAGEACTION_H - -#include "chataction.h" - -class SystemMessageAction : public ChatAction -{ -public: - SystemMessageAction(const QString &message, const QString& type, const QString &date); - virtual ~SystemMessageAction(){;} - -protected: - virtual QString getName() {return QString();} - virtual QString getMessage(); - -private: - QString message; - QString type; -}; - -#endif // SYSTEMMESSAGEACTION_H diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index a7802bba1..7623baa25 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -687,9 +687,10 @@ void Widget::onFriendStatusChanged(int friendId, Status status) default: fStatus = tr("online", "contact status"); break; } - if (isActualChange) - f->getChatForm()->addSystemInfoMessage(tr("%1 is now %2", "e.g. \"Dubslow is now online\"").arg(f->getDisplayedName()).arg(fStatus), - "white", QDateTime::currentDateTime()); + //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 && status != Status::Offline) @@ -742,7 +743,7 @@ void Widget::onFriendMessageReceived(int friendId, const QString& message, bool return; QDateTime timestamp = QDateTime::currentDateTime(); - f->getChatForm()->addMessage(f->getToxID(), message, isAction, timestamp, true); + //TODO: f->getChatForm()->addMessage(f->getToxID(), message, isAction, timestamp, true); if (isAction) HistoryKeeper::getInstance()->addChatEntry(f->getToxID().publicKey, "/me " + message, f->getToxID().publicKey, timestamp, true); @@ -772,7 +773,7 @@ void Widget::onReceiptRecieved(int friendId, int receipt) if (!f) return; - f->getChatForm()->dischargeReceipt(receipt); + //TODO: f->getChatForm()->dischargeReceipt(receipt); } void Widget::newMessageAlert(GenericChatroomWidget* chat) @@ -900,9 +901,9 @@ void Widget::onGroupMessageReceived(int groupnumber, const QString& message, con bool targeted = (author != name) && message.contains(name, Qt::CaseInsensitive); if (targeted) - g->chatForm->addAlertMessage(author, message, QDateTime::currentDateTime()); + ;//TODO: g->chatForm->addAlertMessage(author, message, QDateTime::currentDateTime()); else - g->chatForm->addMessage(author, message, isAction, QDateTime::currentDateTime()); + ;//TODO: g->chatForm->addMessage(author, message, isAction, QDateTime::currentDateTime()); if ((static_cast(g->widget) != activeChatroomWidget) || isMinimized() || !isActiveWindow()) { @@ -1086,7 +1087,7 @@ void Widget::onGroupSendResult(int groupId, const QString& message, int result) return; if (result == -1) - g->chatForm->addSystemInfoMessage(tr("Message failed to send"), "red", QDateTime::currentDateTime()); + ;//TODO: g->chatForm->addSystemInfoMessage(tr("Message failed to send"), "red", QDateTime::currentDateTime()); } void Widget::getPassword(QString info, int passtype, uint8_t* salt) @@ -1158,6 +1159,6 @@ void Widget::clearAllReceipts() QList frnds = FriendList::getAllFriends(); for (Friend *f : frnds) { - f->getChatForm()->clearReciepts(); + //TODO: f->getChatForm()->clearReciepts(); } } From 3a346789007d50256daaeae265bf0af848fe2e6c Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 12 Nov 2014 16:45:24 +0100 Subject: [PATCH 002/203] progress --- res.qrc | 1 + src/chatlog/chatline.cpp | 12 +++++++ src/chatlog/chatline.h | 1 + src/chatlog/chatlog.cpp | 36 ++++++-------------- src/chatlog/chatlog.h | 8 ++--- src/chatlog/chatmessage.cpp | 16 ++++++++- src/chatlog/chatmessage.h | 6 +++- src/chatlog/content/spinner.cpp | 2 +- src/widget/form/chatform.cpp | 49 ++++++++++++++-------------- src/widget/form/chatform.h | 4 +-- src/widget/form/genericchatform.cpp | 28 ++++++---------- src/widget/form/genericchatform.h | 6 ++-- ui/chatArea/spinner.png | Bin 0 -> 1044 bytes 13 files changed, 90 insertions(+), 79 deletions(-) create mode 100644 ui/chatArea/spinner.png diff --git a/res.qrc b/res.qrc index 239df056e..4e2db2712 100644 --- a/res.qrc +++ b/res.qrc @@ -42,6 +42,7 @@ ui/callButton/callButtonYellowPressed.png ui/chatArea/chatArea.css ui/chatArea/innerStyle.css + ui/chatArea/spinner.png ui/chatArea/scrollBarDownArrow.png ui/chatArea/scrollBarDownArrowHover.png ui/chatArea/scrollBarDownArrowPressed.png diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index a531b42f4..39254da0f 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -102,6 +102,18 @@ void ChatLine::addColumn(ChatLineContent* item, ColumnFormat fmt) content << item; } +void ChatLine::replaceContent(int col, ChatLineContent *lineContent) +{ + if(col >= 0 && col < content.size() && lineContent) + { + scene->removeItem(content[col]); + delete content[col]; + + content[col] = lineContent; + scene->addItem(content[col]); + } +} + void ChatLine::layout(qreal w, QPointF scenePos) { width = w; diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index 13038b434..1354dab5e 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -46,6 +46,7 @@ public: virtual QRectF boundingSceneRect() const; void addColumn(ChatLineContent* item, ColumnFormat fmt); + void replaceContent(int col, ChatLineContent* lineContent); void layout(qreal width, QPointF scenePos); void layout(QPointF scenePos); diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index e3f8c2d1f..d4158778a 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -1,5 +1,6 @@ #include "chatlog.h" #include "chatline.h" +#include "chatmessage.h" #include "chatlinecontent.h" #include "chatlinecontentproxy.h" #include "content/text.h" @@ -52,26 +53,21 @@ ChatLog::~ChatLog() delete line; } -void ChatLog::addTextLine(const QString& sender, const QString& text, QDateTime timestamp) +ChatMessage* ChatLog::addChatMessage(const QString& sender, ChatLineContent* content) { - ChatLine* line = new ChatLine(scene); - - line->addColumn(new Text(sender, true), ColumnFormat(75.0, ColumnFormat::FixedSize, 1, ColumnFormat::Right)); - line->addColumn(new Text(text), ColumnFormat(1.0, ColumnFormat::VariableSize)); - line->addColumn(new Text(timestamp.toString("hh:mm")), ColumnFormat(50.0, ColumnFormat::FixedSize, 1)); - + ChatMessage* line = new ChatMessage(scene, sender, content); insertChatline(line); + + return line; } -void ChatLog::addWidgetLine(const QString& sender, QDateTime timestamp) +ChatMessage* ChatLog::addChatMessage(const QString& sender, ChatLineContent* content, const QDateTime& timestamp) { - ChatLine* line = new ChatLine(scene); - - line->addColumn(new Text(sender, true), ColumnFormat(75.0, ColumnFormat::FixedSize, 1)); - line->addColumn(new ChatLineContentProxy(new FileTransferWidget()), ColumnFormat(1.0, ColumnFormat::VariableSize)); - line->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(50.0, ColumnFormat::FixedSize, 1, ColumnFormat::Right)); - + ChatMessage* line = new ChatMessage(scene, sender, content); + line->markAsSent(timestamp); insertChatline(line); + + return line; } void ChatLog::clearSelection() @@ -86,18 +82,6 @@ void ChatLog::clearSelection() selLastCol = -1; } -void ChatLog::dbgPopulate() -{ - for(int i = 0; i < 2000; i++) - addTextLine("Jemp longlong name foo moth", "Line " + QString::number(i) + - " Lorem ipsum Hello dolor sit amet, " - "consectetur adipisicing elit, sed do eiusmod " - "tempor incididunt ut labore et dolore magna " - "aliqua. Ut enim ad minim veniam, quis nostrud " - "exercitation ullamco laboris nisi ut aliquip ex " - "ea commodo consequat. "); -} - QRect ChatLog::getVisibleRect() const { return mapToScene(viewport()->rect()).boundingRect().toRect(); diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 5a9b31fb4..a4ff93c57 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -7,6 +7,7 @@ class QGraphicsScene; class ChatLine; class ChatLineContent; +class ChatMessage; class ChatLog : public QGraphicsView { @@ -15,8 +16,9 @@ public: explicit ChatLog(QWidget* parent = 0); virtual ~ChatLog(); - void addTextLine(const QString& sender, const QString& text, QDateTime timestamp = QDateTime::currentDateTime()); - void addWidgetLine(const QString& sender, QDateTime timestamp = QDateTime::currentDateTime()); + ChatMessage* addChatMessage(const QString& sender, ChatLineContent* content, const QDateTime& timestamp); + ChatMessage* addChatMessage(const QString& sender, ChatLineContent* content); + void insertChatline(ChatLine* l); void clearSelection(); @@ -24,8 +26,6 @@ public: void copySelectedText() const; QString getSelectedText() const; - void dbgPopulate(); - signals: public slots: diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index a6350843e..1136d453c 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -1,5 +1,19 @@ #include "chatmessage.h" +#include "content/text.h" +#include "content/spinner.h" -ChatMessage::ChatMessage() +#include + +ChatMessage::ChatMessage(QGraphicsScene *scene, const QString& author ,ChatLineContent *content) + : ChatLine(scene) { + 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)); } diff --git a/src/chatlog/chatmessage.h b/src/chatlog/chatmessage.h index a0d487292..f61b744b5 100644 --- a/src/chatlog/chatmessage.h +++ b/src/chatlog/chatmessage.h @@ -3,10 +3,14 @@ #include "chatline.h" +class QGraphicsScene; + class ChatMessage : public ChatLine { public: - ChatMessage(); + ChatMessage(QGraphicsScene* scene, const QString &author, ChatLineContent* content); + + void markAsSent(const QDateTime& time); }; #endif // CHATMESSAGE_H diff --git a/src/chatlog/content/spinner.cpp b/src/chatlog/content/spinner.cpp index 67330f862..39d15c772 100644 --- a/src/chatlog/content/spinner.cpp +++ b/src/chatlog/content/spinner.cpp @@ -6,7 +6,7 @@ Spinner::Spinner(QSizeF Size) : size(Size) { - pmap.load(":/media/spinner.png"); + pmap.load(":/ui/chatArea/spinner.png"); timer.setInterval(33); // 30Hz timer.setSingleShot(false); diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 23b8d9da7..0245e8343 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -38,6 +38,7 @@ #include "src/misc/style.h" #include "src/misc/settings.h" #include "src/misc/cstring.h" +#include "src/chatlog/chatmessage.h" ChatForm::ChatForm(Friend* chatFriend) : f(chatFriend) @@ -119,7 +120,8 @@ void ChatForm::onSendTriggered() int id = HistoryKeeper::getInstance()->addChatEntry(f->getToxID().publicKey, qt_msg_hist, Core::getInstance()->getSelfId().publicKey, timestamp, status); - //MessageActionPtr ma = addSelfMessage(msg, isAction, timestamp, false); + + ChatMessage* ma = addSelfMessage(msg, isAction, timestamp, false); int rec; if (isAction) @@ -127,7 +129,7 @@ void ChatForm::onSendTriggered() else rec = Core::getInstance()->sendMessage(f->getFriendID(), msg); - //registerReceipt(rec, id, ma); + registerReceipt(rec, id, ma); } msgEdit->clear(); @@ -842,29 +844,28 @@ QString ChatForm::secondsToDHMS(quint32 duration) return cD + res.sprintf("%dd%02dh %02dm %02ds", days, hours, minutes, seconds); } -//void ChatForm::registerReceipt(int receipt, int messageID, MessageActionPtr msg) -//{ -// receipts[receipt] = messageID; -// undeliveredMsgs[messageID] = msg; -//} +void ChatForm::registerReceipt(int receipt, int messageID, ChatMessage* msg) +{ + receipts[receipt] = messageID; + undeliveredMsgs[messageID] = msg; +} -//void ChatForm::dischargeReceipt(int receipt) -//{ -// auto it = receipts.find(receipt); -// if (it != receipts.end()) -// { -// int mID = it.value(); -// auto msgIt = undeliveredMsgs.find(mID); -// if (msgIt != undeliveredMsgs.end()) -// { -// HistoryKeeper::getInstance()->markAsSent(mID); -// msgIt.value()->markAsSent(); -// msgIt.value()->featureUpdate(); -// undeliveredMsgs.erase(msgIt); -// } -// receipts.erase(it); -// } -//} +void ChatForm::dischargeReceipt(int receipt) +{ + auto it = receipts.find(receipt); + if (it != receipts.end()) + { + int mID = it.value(); + auto msgIt = undeliveredMsgs.find(mID); + if (msgIt != undeliveredMsgs.end()) + { + HistoryKeeper::getInstance()->markAsSent(mID); + msgIt.value()->markAsSent(QDateTime::currentDateTime()); + undeliveredMsgs.erase(msgIt); + } + receipts.erase(it); + } +} void ChatForm::clearReciepts() { diff --git a/src/widget/form/chatform.h b/src/widget/form/chatform.h index faf1b5400..2f9ee98d5 100644 --- a/src/widget/form/chatform.h +++ b/src/widget/form/chatform.h @@ -89,7 +89,7 @@ protected: // drag & drop void dragEnterEvent(QDragEnterEvent* ev); void dropEvent(QDropEvent* ev); - //TODO: void registerReceipt(int receipt, int messageID, MessageActionPtr msg); + void registerReceipt(int receipt, int messageID, ChatMessage* msg); private: Friend* f; @@ -107,7 +107,7 @@ private: void stopCounter(); QString secondsToDHMS(quint32 duration); QHash receipts; - //TODO: QMap undeliveredMsgs; + QMap undeliveredMsgs; }; #endif // CHATFORM_H diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index 785b63354..adbf37767 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -28,7 +28,7 @@ #include "src/core.h" #include "src/friendlist.h" #include "src/friend.h" -#include "src/chatlog/chatlog.h" +#include "src/chatlog/content/text.h" GenericChatForm::GenericChatForm(QWidget *parent) : QWidget(parent), @@ -202,24 +202,16 @@ void GenericChatForm::onSaveLogClicked() // chatWidget->insertMessage(ca); //} -//MessageActionPtr GenericChatForm::addMessage(const ToxID& author, const QString &message, bool isAction, -// const QDateTime &datetime, bool isSent) -//{ -// MessageActionPtr ca = genMessageActionAction(author, message, isAction, datetime); -// if (isSent) -// ca->markAsSent(); -// chatWidget->insertMessage(ca); -// return ca; -//} +ChatMessage* GenericChatForm::addMessage(const ToxID& author, const QString &message, bool isAction, + const QDateTime &datetime, bool isSent) +{ + return chatWidget->addChatMessage(Core::getInstance()->getPeerName(author), new Text(message), datetime); +} -//MessageActionPtr GenericChatForm::addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime, bool isSent) -//{ -// MessageActionPtr ca = genSelfActionAction(message, isAction, datetime); -// if (isSent) -// ca->markAsSent(); -// chatWidget->insertMessage(ca); -// return ca; -//} +ChatMessage* GenericChatForm::addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime, bool isSent) +{ + return chatWidget->addChatMessage(Core::getInstance()->getUsername(), new Text(message)); +} /** * @deprecated The only reason it's still alive is because the groupchat API is a bit limited diff --git a/src/widget/form/genericchatform.h b/src/widget/form/genericchatform.h index 9d967125a..29828ffb8 100644 --- a/src/widget/form/genericchatform.h +++ b/src/widget/form/genericchatform.h @@ -22,6 +22,7 @@ #include #include #include "src/corestructs.h" +#include "src/chatlog/chatlog.h" // Spacing in px inserted when the author of the last message changes #define AUTHOR_CHANGE_SPACING 5 // why the hell is this a thing? surely the different font is enough? @@ -32,6 +33,7 @@ class QPushButton; class CroppingLabel; class ChatTextEdit; class ChatLog; +class ChatMessage; class MaskablePixmapWidget; struct ToxID; @@ -49,8 +51,8 @@ public: virtual void show(Ui::MainWindow &ui); void addMessage(const QString& author, const QString &message, bool isAction, const QDateTime &datetime); ///< Deprecated -// TODO: MessageActionPtr addMessage(const ToxID& author, const QString &message, bool isAction, const QDateTime &datetime, bool isSent); -// MessageActionPtr addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime, bool isSent); + ChatMessage* addMessage(const ToxID& author, const QString &message, bool isAction, const QDateTime &datetime, bool isSent); + ChatMessage* addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime, bool isSent); void addSystemInfoMessage(const QString &message, const QString &type, const QDateTime &datetime); void addAlertMessage(const QString& author, QString message, QDateTime datetime); ///< Deprecated void addAlertMessage(const ToxID& author, QString message, QDateTime datetime); diff --git a/ui/chatArea/spinner.png b/ui/chatArea/spinner.png new file mode 100644 index 0000000000000000000000000000000000000000..22a1d8b2ee9eb49dbb9b1701ea73deabe642ab3e GIT binary patch literal 1044 zcmV+v1nc{WP)Gc$|L)Rbo4Kq{5Gtz0foh{!X*wkGNZBJ!4qWU|@pFKq*4GMU)o;^Hyj z72xJ3jO+EUs!o>6<>Rxnvr8=jjE;_OFPF<70Q=i8uGeqY+J4{nzi$d4l}g=FsZ>4# z?%4$Ms;+i)bnKg&n)<0Bfa|(90bc+QHYj#YM9!+}8Q?5%tE%>i$S$C-!MO!%?LOc4 zFE#=w0EZ(A6jk-5rKP3!3WdV8umsn2p9IE%MsQrJA`YGc zju>MuMa0+1^SooK`g%n8HDgR>9e{|4>$>x*x+~mV1o6V*JSZhOPx2it0RREzgJEAXaK0vWpTwtX;)dTFg z(Ew|$*z>$uRXtJ{4^;J$d_F(lu0cAT?pj`6J}Dx%*Y2z8l|&-3x3&|W2sz&&B6I0< zx~pA)QmOQ+i0lRKs$C*-Vq#*VvIfxG+xsDKKBUHdrBW$ssx_47dHt-6=6V%@H=%AE zyRLf}D1;Rgk-5&!&KD;qCyULPCzHwNL}Uht*T+=#jeI^oz5!qr;#1(Uh`N_VWH6V@ zos2Rb85!AWtvw1n8PF~K>FQH_4&2fJqE-EEt$o7x{V!`bov_SoHhT`(!^%x(GqemG zsyB}W05HZ}s8lKs18)PiO=AV#2X-1`PK6~jbv5%m?*Uak4jd%<`>uCZ{a8fCjWORe z%4-Uss-dBw-grEIsP1yQ4fvIs%c Date: Thu, 13 Nov 2014 18:27:32 +0100 Subject: [PATCH 003/203] progress --- src/chatlog/chatline.cpp | 26 ++++++++++++++------ src/chatlog/chatlinecontent.cpp | 5 ++++ src/chatlog/chatlinecontent.h | 2 ++ src/chatlog/chatmessage.cpp | 7 ++++++ src/chatlog/chatmessage.h | 4 +++ src/chatlog/content/text.cpp | 16 ++++++------ src/chatlog/content/text.h | 2 +- src/misc/smileypack.cpp | 2 +- src/widget/form/chatform.cpp | 38 ++++++++++++++--------------- src/widget/form/genericchatform.cpp | 9 +++++-- src/widget/widget.cpp | 4 +-- 11 files changed, 75 insertions(+), 40 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index 39254da0f..cad1b0f82 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -111,6 +111,10 @@ void ChatLine::replaceContent(int col, ChatLineContent *lineContent) content[col] = lineContent; scene->addItem(content[col]); + + layout(width, pos); + content[col]->visibilityChanged(isVisible); + content[col]->update(); } } @@ -145,15 +149,9 @@ void ChatLine::layout(qreal w, QPointF scenePos) else width = format[i].size / varWidth * leftover; - // set the width of the current column as - // firstLineVOffset() may depend on the current width + // set the width of the current column content[i]->setWidth(width); - // calculate vertical alignment - qreal yOffset = 0.0; - if(format[i].vAlignCol >= 0 && format[i].vAlignCol < content.size()) - yOffset = content[format[i].vAlignCol]->firstLineVOffset() - content[i]->firstLineVOffset(); - // calculate horizontal alignment qreal xAlign = 0.0; switch(format[i].hAlign) @@ -169,11 +167,23 @@ void ChatLine::layout(qreal w, QPointF scenePos) } // reposition - content[i]->setPos(pos.x() + xOffset + xAlign, pos.y() + yOffset); + content[i]->setPos(pos.x() + xOffset + xAlign, pos.y()); xOffset += width; } + for(int i = 0; i < content.size(); ++i) + { + // calculate vertical alignment + // vertical alignment may depend on width, so we do it in a second pass + qreal yOffset = 0.0; + if(format[i].vAlignCol >= 0 && format[i].vAlignCol < content.size()) + yOffset = content[format[i].vAlignCol]->firstLineVOffset() - content[i]->firstLineVOffset(); + + // reposition + content[i]->setPos(content[i]->pos().x(), content[i]->pos().y() + yOffset); + } + updateBBox(); } diff --git a/src/chatlog/chatlinecontent.cpp b/src/chatlog/chatlinecontent.cpp index 1cfc61dc6..de5a8358e 100644 --- a/src/chatlog/chatlinecontent.cpp +++ b/src/chatlog/chatlinecontent.cpp @@ -68,3 +68,8 @@ void ChatLineContent::visibilityChanged(bool) { } + +QString ChatLineContent::toString() const +{ + return QString(); +} diff --git a/src/chatlog/chatlinecontent.h b/src/chatlog/chatlinecontent.h index 32d08d7c8..64e0ef5f6 100644 --- a/src/chatlog/chatlinecontent.h +++ b/src/chatlog/chatlinecontent.h @@ -36,6 +36,8 @@ public: virtual void visibilityChanged(bool visible); + virtual QString toString() const; + private: friend class ChatLine; diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 1136d453c..c241ea4e8 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -10,6 +10,8 @@ ChatMessage::ChatMessage(QGraphicsScene *scene, const QString& author ,ChatLineC 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; } void ChatMessage::markAsSent(const QDateTime &time) @@ -17,3 +19,8 @@ void ChatMessage::markAsSent(const QDateTime &time) // remove the spinner and replace it by $time replaceContent(2, new Text(time.toString("hh:mm"), true)); } + +QString ChatMessage::toString() const +{ + return midColumn->toString(); +} diff --git a/src/chatlog/chatmessage.h b/src/chatlog/chatmessage.h index f61b744b5..dee1714cc 100644 --- a/src/chatlog/chatmessage.h +++ b/src/chatlog/chatmessage.h @@ -11,6 +11,10 @@ public: ChatMessage(QGraphicsScene* scene, const QString &author, ChatLineContent* content); void markAsSent(const QDateTime& time); + QString toString() const; + +private: + ChatLineContent* midColumn = nullptr; }; #endif // CHATMESSAGE_H diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 37e0ed74c..4b17526aa 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -11,14 +11,15 @@ #include #include -int Text::count = 0; - Text::Text(const QString& txt, bool enableElide) : ChatLineContent() , elide(enableElide) { setText(txt); setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton); + + ensureIntegrity(); + freeResources(); //setCacheMode(QGraphicsItem::DeviceCoordinateCache); } @@ -161,6 +162,11 @@ void Text::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QDesktopServices::openUrl(anchor); } +QString Text::toString() const +{ + return text; +} + void Text::ensureIntegrity() { if(!doc) @@ -179,18 +185,16 @@ void Text::ensureIntegrity() opt.setWrapMode(QTextOption::NoWrap); doc->setDefaultTextOption(opt); doc->setPlainText(elidedText); - } cursor = QTextCursor(doc); - count++; } doc->setTextWidth(width); doc->documentLayout()->update(); if(doc->firstBlock().layout()->lineCount() > 0) - vOffset = doc->firstBlock().layout()->lineAt(0).ascent(); + vOffset = doc->firstBlock().layout()->lineAt(0).height(); if(size != idealSize()) { @@ -206,8 +210,6 @@ void Text::freeResources() delete doc; doc = nullptr; cursor = QTextCursor(); - - count--; } } diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index edcdd486d..22e75ac70 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -36,7 +36,7 @@ public: virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); - static int count; + virtual QString toString() const; protected: // dynamic resource management diff --git a/src/misc/smileypack.cpp b/src/misc/smileypack.cpp index 1ec70f954..152a391d5 100644 --- a/src/misc/smileypack.cpp +++ b/src/misc/smileypack.cpp @@ -198,7 +198,7 @@ void SmileyPack::cacheSmiley(const QString &name) // The -1 is to avoid having the space for descenders under images move the text down // We can't remove it because Qt doesn't support CSS display or vertical-align int fontHeight = QFontInfo(Style::getFont(Style::Big)).pixelSize() - 1; - QSize size(fontHeight, fontHeight); + QSize size(16, 16); QString filename = QDir(path).filePath(name); QImage img(filename); diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 0245e8343..e12cc9d60 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -732,7 +732,7 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) ToxID storedPrevId; std::swap(storedPrevId, previousId); - //QList historyMessages; +// QList historyMessages; // QDate lastDate(1,0,0); // for (const auto &it : msgs) @@ -743,11 +743,11 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) // if (msgDate > lastDate) // { // lastDate = msgDate; -// historyMessages.append(genSystemInfoAction(msgDate.toString(),"",QDateTime())); +// //TODO: historyMessages.append(genSystemInfoAction(msgDate.toString(),"",QDateTime())); // } // // Show each messages -// MessageActionPtr ca = genMessageActionAction(ToxID::fromString(it.sender), it.message, false, msgDateTime); +// ChatMessage* ca = genMessageActionAction(ToxID::fromString(it.sender), it.message, false, msgDateTime); // if (it.isSent) // { // ca->markAsSent(); @@ -869,26 +869,26 @@ void ChatForm::dischargeReceipt(int receipt) void ChatForm::clearReciepts() { -// receipts.clear(); -// undeliveredMsgs.clear(); + receipts.clear(); + undeliveredMsgs.clear(); } void ChatForm::deliverOfflineMsgs() { -// if (!Settings::getInstance().getFauxOfflineMessaging()) -// return; + if (!Settings::getInstance().getFauxOfflineMessaging()) + return; -// QMap msgs = undeliveredMsgs; -// clearReciepts(); + QMap msgs = undeliveredMsgs; + clearReciepts(); -// for (auto iter = msgs.begin(); iter != msgs.end(); iter++) -// { -// QString messageText = iter.value()->getRawMessage(); -// int rec; -// if (iter.value()->isAction()) -// rec = Core::getInstance()->sendAction(f->getFriendID(), messageText); -// else -// rec = Core::getInstance()->sendMessage(f->getFriendID(), messageText); -// registerReceipt(rec, iter.key(), iter.value()); -// } + for (auto iter = msgs.begin(); iter != msgs.end(); iter++) + { + QString messageText = iter.value()->toString(); + int rec; + //if (iter.value()->isAction()) + ;//TODO: rec = Core::getInstance()->sendAction(f->getFriendID(), messageText); + //else + rec = Core::getInstance()->sendMessage(f->getFriendID(), messageText); + registerReceipt(rec, iter.key(), iter.value()); + } } diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index adbf37767..5180424fd 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -29,6 +29,7 @@ #include "src/friendlist.h" #include "src/friend.h" #include "src/chatlog/content/text.h" +#include "src/chatlog/chatmessage.h" GenericChatForm::GenericChatForm(QWidget *parent) : QWidget(parent), @@ -205,12 +206,16 @@ void GenericChatForm::onSaveLogClicked() ChatMessage* GenericChatForm::addMessage(const ToxID& author, const QString &message, bool isAction, const QDateTime &datetime, bool isSent) { - return chatWidget->addChatMessage(Core::getInstance()->getPeerName(author), new Text(message), datetime); + ChatMessage* msg = chatWidget->addChatMessage(Core::getInstance()->getPeerName(author), new Text(SmileyPack::getInstance().smileyfied(message)), datetime); + if(isSent) + msg->markAsSent(datetime); + + return msg; } ChatMessage* GenericChatForm::addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime, bool isSent) { - return chatWidget->addChatMessage(Core::getInstance()->getUsername(), new Text(message)); + return chatWidget->addChatMessage(Core::getInstance()->getUsername(), new Text(SmileyPack::getInstance().smileyfied(message))); } /** diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 7623baa25..48c3b3024 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -743,7 +743,7 @@ void Widget::onFriendMessageReceived(int friendId, const QString& message, bool return; QDateTime timestamp = QDateTime::currentDateTime(); - //TODO: f->getChatForm()->addMessage(f->getToxID(), message, isAction, timestamp, true); + f->getChatForm()->addMessage(f->getToxID(), message, isAction, timestamp, true); if (isAction) HistoryKeeper::getInstance()->addChatEntry(f->getToxID().publicKey, "/me " + message, f->getToxID().publicKey, timestamp, true); @@ -773,7 +773,7 @@ void Widget::onReceiptRecieved(int friendId, int receipt) if (!f) return; - //TODO: f->getChatForm()->dischargeReceipt(receipt); + f->getChatForm()->dischargeReceipt(receipt); } void Widget::newMessageAlert(GenericChatroomWidget* chat) From 74bd80286314a85115f835185f312a146f534b96 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 16 Nov 2014 12:40:44 +0100 Subject: [PATCH 004/203] progress --- qtox.pro | 8 +++-- res.qrc | 1 + src/chatlog/chatlinecontent.cpp | 7 +--- src/chatlog/chatlinecontent.h | 4 +-- src/chatlog/chatlog.cpp | 37 +++++++++++++-------- src/chatlog/chatlog.h | 10 +++--- src/chatlog/chatmessage.cpp | 15 ++++----- src/chatlog/chatmessage.h | 3 +- src/chatlog/content/image.cpp | 39 ++++++++++++++++++++++ src/chatlog/content/image.h | 23 +++++++++++++ src/chatlog/content/spinner.cpp | 5 +++ src/chatlog/content/spinner.h | 1 + src/chatlog/content/text.cpp | 15 ++++----- src/chatlog/content/text.h | 12 +++---- src/chatlog/customtextdocument.cpp | 19 +++++++++++ src/chatlog/customtextdocument.h | 16 ++++++++++ src/corestructs.cpp | 5 +++ src/corestructs.h | 1 + src/misc/smileypack.cpp | 11 ++++++- src/misc/smileypack.h | 1 + src/widget/form/genericchatform.cpp | 48 ++++++++++++++++------------ src/widget/form/genericchatform.h | 2 +- src/widget/widget.cpp | 7 ++-- ui/chatArea/info.png | Bin 0 -> 791 bytes 24 files changed, 208 insertions(+), 82 deletions(-) create mode 100644 src/chatlog/content/image.cpp create mode 100644 src/chatlog/content/image.h create mode 100644 src/chatlog/customtextdocument.cpp create mode 100644 src/chatlog/customtextdocument.h create mode 100644 ui/chatArea/info.png diff --git a/qtox.pro b/qtox.pro index 14303d207..a5a8b58ca 100644 --- a/qtox.pro +++ b/qtox.pro @@ -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 diff --git a/res.qrc b/res.qrc index 4e2db2712..dc829079a 100644 --- a/res.qrc +++ b/res.qrc @@ -43,6 +43,7 @@ ui/chatArea/chatArea.css ui/chatArea/innerStyle.css ui/chatArea/spinner.png + ui/chatArea/info.png ui/chatArea/scrollBarDownArrow.png ui/chatArea/scrollBarDownArrowHover.png ui/chatArea/scrollBarDownArrowPressed.png diff --git a/src/chatlog/chatlinecontent.cpp b/src/chatlog/chatlinecontent.cpp index de5a8358e..f51cd3179 100644 --- a/src/chatlog/chatlinecontent.cpp +++ b/src/chatlog/chatlinecontent.cpp @@ -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(); -} diff --git a/src/chatlog/chatlinecontent.h b/src/chatlog/chatlinecontent.h index 64e0ef5f6..25f51e91e 100644 --- a/src/chatlog/chatlinecontent.h +++ b/src/chatlog/chatlinecontent.h @@ -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; diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index d4158778a..fcb1e09a3 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -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 #include #include @@ -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(); } diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index a4ff93c57..dec719b79 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -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; diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index c241ea4e8..0c577a4ae 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -4,23 +4,22 @@ #include -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; } diff --git a/src/chatlog/chatmessage.h b/src/chatlog/chatmessage.h index dee1714cc..8ea906a5b 100644 --- a/src/chatlog/chatmessage.h +++ b/src/chatlog/chatmessage.h @@ -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 diff --git a/src/chatlog/content/image.cpp b/src/chatlog/content/image.cpp new file mode 100644 index 000000000..ec87ae456 --- /dev/null +++ b/src/chatlog/content/image.cpp @@ -0,0 +1,39 @@ +#include "image.h" + +#include + +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) +} diff --git a/src/chatlog/content/image.h b/src/chatlog/content/image.h new file mode 100644 index 000000000..633bc4c01 --- /dev/null +++ b/src/chatlog/content/image.h @@ -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 diff --git a/src/chatlog/content/spinner.cpp b/src/chatlog/content/spinner.cpp index 39d15c772..0f1a17887 100644 --- a/src/chatlog/content/spinner.cpp +++ b/src/chatlog/content/spinner.cpp @@ -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; diff --git a/src/chatlog/content/spinner.h b/src/chatlog/content/spinner.h index 81dc6f835..c31e93af7 100644 --- a/src/chatlog/content/spinner.h +++ b/src/chatlog/content/spinner.h @@ -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(); diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 4b17526aa..8760e02e4 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -1,5 +1,7 @@ #include "text.h" +#include "../customtextdocument.h" + #include #include #include @@ -11,9 +13,10 @@ #include #include -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) { diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index 22e75ac70..c43c64ff1 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -6,13 +6,12 @@ #include #include -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; }; diff --git a/src/chatlog/customtextdocument.cpp b/src/chatlog/customtextdocument.cpp new file mode 100644 index 000000000..6aa560b91 --- /dev/null +++ b/src/chatlog/customtextdocument.cpp @@ -0,0 +1,19 @@ +#include "customtextdocument.h" +#include "../misc/smileypack.h" + +#include +#include + +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); +} diff --git a/src/chatlog/customtextdocument.h b/src/chatlog/customtextdocument.h new file mode 100644 index 000000000..7a8478925 --- /dev/null +++ b/src/chatlog/customtextdocument.h @@ -0,0 +1,16 @@ +#ifndef CUSTOMTEXTDOCUMENT_H +#define CUSTOMTEXTDOCUMENT_H + +#include + +class CustomTextDocument : public QTextDocument +{ + Q_OBJECT +public: + explicit CustomTextDocument(QObject *parent = 0); + +protected: + virtual QVariant loadResource(int type, const QUrl &name); +}; + +#endif // CUSTOMTEXTDOCUMENT_H diff --git a/src/corestructs.cpp b/src/corestructs.cpp index c9712d1fe..ecdca2abd 100644 --- a/src/corestructs.cpp +++ b/src/corestructs.cpp @@ -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]+$"); diff --git a/src/corestructs.h b/src/corestructs.h index 82848695e..1453db415 100644 --- a/src/corestructs.h +++ b/src/corestructs.h @@ -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 diff --git a/src/misc/smileypack.cpp b/src/misc/smileypack.cpp index 152a391d5..be05d89e2 100644 --- a/src/misc/smileypack.cpp +++ b/src/misc/smileypack.cpp @@ -183,7 +183,8 @@ QList SmileyPack::getEmoticons() const QString SmileyPack::getAsRichText(const QString &key) { - return ""; + return QString("").arg(key); + //return ""; } 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 diff --git a/src/misc/smileypack.h b/src/misc/smileypack.h index e5bea3509..5f54cb607 100644 --- a/src/misc/smileypack.h +++ b/src/misc/smileypack.h @@ -41,6 +41,7 @@ public: QList getEmoticons() const; QString getAsRichText(const QString& key); QIcon getAsIcon(const QString& key); + QImage getAsImage(const QString& key); private slots: void onSmileyPackChanged(); diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index 5180424fd..9774ce119 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -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()); diff --git a/src/widget/form/genericchatform.h b/src/widget/form/genericchatform.h index 29828ffb8..3e54b6554 100644 --- a/src/widget/form/genericchatform.h +++ b/src/widget/form/genericchatform.h @@ -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; diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 48c3b3024..06ac1f5de 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -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) diff --git a/ui/chatArea/info.png b/ui/chatArea/info.png new file mode 100644 index 0000000000000000000000000000000000000000..47e7b0f3dbf28964c25b5f5d9fd9ace63babb1d3 GIT binary patch literal 791 zcmV+y1L*vTP){I&hbH6QWLqhZ0eQ@L+*A zPg>wbFgzR4@YLB9x(H$?AxJO}LdYacsH+{?p>hy2CIq2WZtuNchiy97a&Mc?zOci1 z`~N?mxA*`5-tRA}N+l6QCe}tnULYNIM8W{JYSLta$?3kilv3G*;zwX=eahao6aAuk z7Z^}zD=o(ku%aT%txjY$+7oqZ78u_c8AQz!prfqm@x&2ta<*$>sVaf7&Eb&c*^8+5 zRtPR4NX#|P(6gJ*Q@#Zryt#i(g;zkNCiqbjqTHG3p5H1fkb}PknobFx&z>l^iY1N- zjBO5wEZ2IEk30YJ`YRt_e8SCmh=Jxv6J3vQlpB_CEw{7qahSrZmS->efdl;hen5IZ zgL~lO{Bqg<_S4U>NRDxsLxJpS_rKtR%>nES7GeZr3ym!e{syY{j&F<%=D&)nX7{G@ua?I=_$W=Js@iJb?k9z*AaGq%kBIDc}@H_Cw z_8#jG-<7;}>(O;uu3Yvz)qo&kCe}tn|Ele!QpsJOI1jWAtyCu9K;21a_wT=29lt!>!a?09a8}4SRMvz@%(dLkQgHa6k7k8A*Td=GkkdV${{fff VQq`^3EQA06002ovPDHLkV1h5Aai9PI literal 0 HcmV?d00001 From fd1063eb2c433dd8160647c0e9457661edca85fe Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 16 Nov 2014 12:52:53 +0100 Subject: [PATCH 005/203] bye bye base64 emoticons --- src/chatlog/customtextdocument.cpp | 2 +- src/misc/smileypack.cpp | 39 ++++++------------------ src/misc/smileypack.h | 8 ++--- src/widget/emoticonswidget.cpp | 2 +- src/widget/form/settings/generalform.cpp | 10 +++--- 5 files changed, 21 insertions(+), 40 deletions(-) diff --git a/src/chatlog/customtextdocument.cpp b/src/chatlog/customtextdocument.cpp index 6aa560b91..ddcec13f0 100644 --- a/src/chatlog/customtextdocument.cpp +++ b/src/chatlog/customtextdocument.cpp @@ -13,7 +13,7 @@ CustomTextDocument::CustomTextDocument(QObject *parent) QVariant CustomTextDocument::loadResource(int type, const QUrl &name) { if (type == QTextDocument::ImageResource && name.scheme() == "key") - return SmileyPack::getInstance().getAsImage(name.fileName()); + return SmileyPack::getInstance().getAsPixmap(name.fileName()); return QTextDocument::loadResource(type, name); } diff --git a/src/misc/smileypack.cpp b/src/misc/smileypack.cpp index be05d89e2..a6b5c86a6 100644 --- a/src/misc/smileypack.cpp +++ b/src/misc/smileypack.cpp @@ -91,7 +91,7 @@ bool SmileyPack::load(const QString& filename) { // discard old data filenameTable.clear(); - imgCache.clear(); + pixmapCache.clear(); emoticons.clear(); path.clear(); @@ -134,11 +134,8 @@ bool SmileyPack::load(const QString& filename) filenameTable.insert(emoticon, file); cacheSmiley(file); // preload all smileys - - QPixmap pm; - pm.loadFromData(getCachedSmiley(emoticon), "PNG"); - - if(pm.size().width() > 0) + + if(!getCachedSmiley(emoticon).size().isEmpty()) emoticonSet.push_back(emoticon); stringElement = stringElement.nextSibling().toElement(); @@ -184,22 +181,11 @@ QList SmileyPack::getEmoticons() const QString SmileyPack::getAsRichText(const QString &key) { return QString("").arg(key); - //return ""; } -QIcon SmileyPack::getAsIcon(const QString &key) +QPixmap SmileyPack::getAsPixmap(const QString &key) { - QPixmap pm; - pm.loadFromData(getCachedSmiley(key), "PNG"); - return QIcon(pm); -} - -QImage SmileyPack::getAsImage(const QString &key) -{ - QImage img; - img.loadFromData(getCachedSmiley(key), "PNG"); - - return img; + return getCachedSmiley(key); } void SmileyPack::cacheSmiley(const QString &name) @@ -214,28 +200,23 @@ void SmileyPack::cacheSmiley(const QString &name) if (!img.isNull()) { QImage scaledImg = img.scaled(size, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); - - QByteArray scaledImgData; - QBuffer buffer(&scaledImgData); - scaledImg.save(&buffer, "PNG"); - - imgCache.insert(name, scaledImgData); + pixmapCache.insert(name, QPixmap::fromImage(scaledImg)); } } -QByteArray SmileyPack::getCachedSmiley(const QString &key) +QPixmap SmileyPack::getCachedSmiley(const QString &key) { // valid key? if (!filenameTable.contains(key)) - return QByteArray(); + return QPixmap(); // cache it if needed QString file = filenameTable.value(key); - if (!imgCache.contains(file)) { + if (!pixmapCache.contains(file)) { cacheSmiley(file); } - return imgCache.value(file); + return pixmapCache.value(file); } void SmileyPack::onSmileyPackChanged() diff --git a/src/misc/smileypack.h b/src/misc/smileypack.h index 5f54cb607..b88c33503 100644 --- a/src/misc/smileypack.h +++ b/src/misc/smileypack.h @@ -21,6 +21,7 @@ #include #include #include +#include #define SMILEYPACK_SEARCH_PATHS \ { \ @@ -40,8 +41,7 @@ public: QString smileyfied(QString msg); QList getEmoticons() const; QString getAsRichText(const QString& key); - QIcon getAsIcon(const QString& key); - QImage getAsImage(const QString& key); + QPixmap getAsPixmap(const QString& key); private slots: void onSmileyPackChanged(); @@ -52,10 +52,10 @@ private: SmileyPack& operator=(const SmileyPack&) = delete; void cacheSmiley(const QString& name); - QByteArray getCachedSmiley(const QString& key); + QPixmap getCachedSmiley(const QString& key); QHash filenameTable; // matches an emoticon to its corresponding smiley ie. ":)" -> "happy.png" - QHash imgCache; // (scaled) representation of a smiley ie. "happy.png" -> data + QHash pixmapCache; // (scaled) representation of a smiley ie. "happy.png" -> data QList emoticons; // {{ ":)", ":-)" }, {":(", ...}, ... } QString path; // directory containing the cfg and image files }; diff --git a/src/widget/emoticonswidget.cpp b/src/widget/emoticonswidget.cpp index a605d8700..55558945a 100644 --- a/src/widget/emoticonswidget.cpp +++ b/src/widget/emoticonswidget.cpp @@ -81,7 +81,7 @@ EmoticonsWidget::EmoticonsWidget(QWidget *parent) : for (const QStringList& set : emoticons) { QPushButton* button = new QPushButton; - button->setIcon(SmileyPack::getInstance().getAsIcon(set[0])); + button->setIcon(SmileyPack::getInstance().getAsPixmap(set[0])); button->setToolTip(set.join(" ")); button->setProperty("sequence", set[0]); button->setCursor(Qt::PointingHandCursor); diff --git a/src/widget/form/settings/generalform.cpp b/src/widget/form/settings/generalform.cpp index 496dccc9f..7e875e246 100644 --- a/src/widget/form/settings/generalform.cpp +++ b/src/widget/form/settings/generalform.cpp @@ -279,11 +279,11 @@ void GeneralForm::reloadSmiles() smiles.push_front(emoticons.at(i).first()); int pixSize = 30; - bodyUI->smile1->setPixmap(SmileyPack::getInstance().getAsIcon(smiles[0]).pixmap(pixSize, pixSize)); - bodyUI->smile2->setPixmap(SmileyPack::getInstance().getAsIcon(smiles[1]).pixmap(pixSize, pixSize)); - bodyUI->smile3->setPixmap(SmileyPack::getInstance().getAsIcon(smiles[2]).pixmap(pixSize, pixSize)); - bodyUI->smile4->setPixmap(SmileyPack::getInstance().getAsIcon(smiles[3]).pixmap(pixSize, pixSize)); - bodyUI->smile5->setPixmap(SmileyPack::getInstance().getAsIcon(smiles[4]).pixmap(pixSize, pixSize)); + bodyUI->smile1->setPixmap(SmileyPack::getInstance().getAsPixmap(smiles[0])); + bodyUI->smile2->setPixmap(SmileyPack::getInstance().getAsPixmap(smiles[1])); + bodyUI->smile3->setPixmap(SmileyPack::getInstance().getAsPixmap(smiles[2])); + bodyUI->smile4->setPixmap(SmileyPack::getInstance().getAsPixmap(smiles[3])); + bodyUI->smile5->setPixmap(SmileyPack::getInstance().getAsPixmap(smiles[4])); bodyUI->smile1->setToolTip(smiles[0]); bodyUI->smile2->setToolTip(smiles[1]); From 4ea21c2d194a66c393b19238651d9d85b5537cd7 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 16 Nov 2014 12:58:43 +0100 Subject: [PATCH 006/203] (c) --- src/chatlog/chatline.cpp | 16 ++++++++++++++++ src/chatlog/chatline.h | 16 ++++++++++++++++ src/chatlog/chatlinecontent.cpp | 16 ++++++++++++++++ src/chatlog/chatlinecontent.h | 16 ++++++++++++++++ src/chatlog/chatlinecontentproxy.cpp | 16 ++++++++++++++++ src/chatlog/chatlinecontentproxy.h | 16 ++++++++++++++++ src/chatlog/chatlog.cpp | 16 ++++++++++++++++ src/chatlog/chatlog.h | 16 ++++++++++++++++ src/chatlog/chatmessage.cpp | 20 +++++++++++++++++--- src/chatlog/chatmessage.h | 16 ++++++++++++++++ src/chatlog/content/filetransferwidget.cpp | 16 ++++++++++++++++ src/chatlog/content/filetransferwidget.h | 16 ++++++++++++++++ src/chatlog/content/image.cpp | 16 ++++++++++++++++ src/chatlog/content/image.h | 16 ++++++++++++++++ src/chatlog/content/spinner.cpp | 16 ++++++++++++++++ src/chatlog/content/spinner.h | 16 ++++++++++++++++ src/chatlog/content/text.cpp | 16 ++++++++++++++++ src/chatlog/content/text.h | 16 ++++++++++++++++ src/chatlog/customtextdocument.cpp | 16 ++++++++++++++++ src/chatlog/customtextdocument.h | 16 ++++++++++++++++ src/misc/smileypack.cpp | 2 +- 21 files changed, 322 insertions(+), 4 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index cad1b0f82..e26969d7f 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 "chatline.h" #include "chatlog.h" #include "chatlinecontent.h" diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index 1354dab5e..78e225ed3 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 CHATLINE_H #define CHATLINE_H diff --git a/src/chatlog/chatlinecontent.cpp b/src/chatlog/chatlinecontent.cpp index f51cd3179..0881a8b87 100644 --- a/src/chatlog/chatlinecontent.cpp +++ b/src/chatlog/chatlinecontent.cpp @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 "chatlinecontent.h" void ChatLineContent::setChatLine(ChatLine* chatline) diff --git a/src/chatlog/chatlinecontent.h b/src/chatlog/chatlinecontent.h index 25f51e91e..bd2017653 100644 --- a/src/chatlog/chatlinecontent.h +++ b/src/chatlog/chatlinecontent.h @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 CHATLINECONTENT_H #define CHATLINECONTENT_H diff --git a/src/chatlog/chatlinecontentproxy.cpp b/src/chatlog/chatlinecontentproxy.cpp index 28eac44ef..8ac308ae1 100644 --- a/src/chatlog/chatlinecontentproxy.cpp +++ b/src/chatlog/chatlinecontentproxy.cpp @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 "chatlinecontentproxy.h" #include #include diff --git a/src/chatlog/chatlinecontentproxy.h b/src/chatlog/chatlinecontentproxy.h index aa69fae36..bf225a17c 100644 --- a/src/chatlog/chatlinecontentproxy.h +++ b/src/chatlog/chatlinecontentproxy.h @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 CHATLINECONTENTPROXY_H #define CHATLINECONTENTPROXY_H diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index fcb1e09a3..8d47ebeae 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 "chatlog.h" #include "chatline.h" #include "chatmessage.h" diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index dec719b79..6177819a0 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 CHATLOG_H #define CHATLOG_H diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 0c577a4ae..10ec4b94c 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 "chatmessage.h" #include "content/text.h" #include "content/spinner.h" @@ -8,9 +24,7 @@ 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)); + } void ChatMessage::markAsSent(const QDateTime &time) diff --git a/src/chatlog/chatmessage.h b/src/chatlog/chatmessage.h index 8ea906a5b..282bd0703 100644 --- a/src/chatlog/chatmessage.h +++ b/src/chatlog/chatmessage.h @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 CHATMESSAGE_H #define CHATMESSAGE_H diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index fef501647..ca81bdbcf 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 "filetransferwidget.h" #include "ui_filetransferwidget.h" diff --git a/src/chatlog/content/filetransferwidget.h b/src/chatlog/content/filetransferwidget.h index b09c09023..e5158caf3 100644 --- a/src/chatlog/content/filetransferwidget.h +++ b/src/chatlog/content/filetransferwidget.h @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 FILETRANSFERWIDGET_H #define FILETRANSFERWIDGET_H diff --git a/src/chatlog/content/image.cpp b/src/chatlog/content/image.cpp index ec87ae456..79cab6df0 100644 --- a/src/chatlog/content/image.cpp +++ b/src/chatlog/content/image.cpp @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 "image.h" #include diff --git a/src/chatlog/content/image.h b/src/chatlog/content/image.h index 633bc4c01..ad84bd0fa 100644 --- a/src/chatlog/content/image.h +++ b/src/chatlog/content/image.h @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 IMAGE_H #define IMAGE_H diff --git a/src/chatlog/content/spinner.cpp b/src/chatlog/content/spinner.cpp index 0f1a17887..554e6a5bc 100644 --- a/src/chatlog/content/spinner.cpp +++ b/src/chatlog/content/spinner.cpp @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 "spinner.h" #include diff --git a/src/chatlog/content/spinner.h b/src/chatlog/content/spinner.h index c31e93af7..c2553dd67 100644 --- a/src/chatlog/content/spinner.h +++ b/src/chatlog/content/spinner.h @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 SPINNER_H #define SPINNER_H diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 8760e02e4..81a613511 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 "text.h" #include "../customtextdocument.h" diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index c43c64ff1..a2a83096e 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -8,6 +8,22 @@ class CustomTextDocument; +/* + Copyright (C) 2014 by Project Tox + + 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. +*/ + class Text : public ChatLineContent { public: diff --git a/src/chatlog/customtextdocument.cpp b/src/chatlog/customtextdocument.cpp index ddcec13f0..676fbae09 100644 --- a/src/chatlog/customtextdocument.cpp +++ b/src/chatlog/customtextdocument.cpp @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 "customtextdocument.h" #include "../misc/smileypack.h" diff --git a/src/chatlog/customtextdocument.h b/src/chatlog/customtextdocument.h index 7a8478925..ed6a065db 100644 --- a/src/chatlog/customtextdocument.h +++ b/src/chatlog/customtextdocument.h @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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 CUSTOMTEXTDOCUMENT_H #define CUSTOMTEXTDOCUMENT_H diff --git a/src/misc/smileypack.cpp b/src/misc/smileypack.cpp index a6b5c86a6..aacbf1d25 100644 --- a/src/misc/smileypack.cpp +++ b/src/misc/smileypack.cpp @@ -192,7 +192,7 @@ void SmileyPack::cacheSmiley(const QString &name) { // The -1 is to avoid having the space for descenders under images move the text down // We can't remove it because Qt doesn't support CSS display or vertical-align - int fontHeight = QFontInfo(Style::getFont(Style::Big)).pixelSize() - 1; + //TODO: int fontHeight = QFontInfo(Style::getFont(Style::Big)).pixelSize() - 1; QSize size(16, 16); QString filename = QDir(path).filePath(name); QImage img(filename); From 3facab1db41d50de8da6bbcde84dc76c2f4a9359 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 16 Nov 2014 13:01:26 +0100 Subject: [PATCH 007/203] artwork --- ui/chatArea/symbols.svg | 94 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 ui/chatArea/symbols.svg diff --git a/ui/chatArea/symbols.svg b/ui/chatArea/symbols.svg new file mode 100644 index 000000000..45f26aec3 --- /dev/null +++ b/ui/chatArea/symbols.svg @@ -0,0 +1,94 @@ + + + + + + + + + image/svg+xml + + + + + + + + + ! + + + i + + + i + + From 4ca45fd4f96234c993ac1dd12ed5a58793002b1f Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 16 Nov 2014 13:13:39 +0100 Subject: [PATCH 008/203] progress --- src/widget/form/chatform.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index e12cc9d60..f7fc7829c 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -323,7 +323,7 @@ void ChatForm::onAvCancel(int FriendId, int) netcam->hide(); - //TODO: addSystemInfoMessage(tr("%1 stopped calling").arg(f->getDisplayedName()), "white", QDateTime::currentDateTime()); + addSystemInfoMessage(tr("%1 stopped calling").arg(f->getDisplayedName()), "white", QDateTime::currentDateTime()); } void ChatForm::onAvEnd(int FriendId, int) @@ -379,7 +379,7 @@ void ChatForm::onAvRinging(int FriendId, int CallId, bool video) connect(callButton, SIGNAL(clicked()), this, SLOT(onCancelCallTriggered())); } - //TODO: addSystemInfoMessage(tr("Calling to %1").arg(f->getDisplayedName()), "white", QDateTime::currentDateTime()); + addSystemInfoMessage(tr("Calling to %1").arg(f->getDisplayedName()), "white", QDateTime::currentDateTime()); } void ChatForm::onAvStarting(int FriendId, int CallId, bool video) @@ -671,7 +671,7 @@ void ChatForm::onFileSendFailed(int FriendId, const QString &fname) if (FriendId != f->getFriendID()) return; - //TODO: addSystemInfoMessage("File: \"" + fname + "\" failed to send.", "red", QDateTime::currentDateTime()); + addSystemInfoMessage("File: \"" + fname + "\" failed to send.", "red", QDateTime::currentDateTime()); } void ChatForm::onAvatarChange(int FriendId, const QPixmap &pic) @@ -804,10 +804,8 @@ void ChatForm::stopCounter() { if(timer) { - //TODO: -// addSystemInfoMessage(tr("Call with %1 ended. %2").arg(f->getDisplayedName(), -// secondsToDHMS(timeElapsed.elapsed()/1000)), -// "white", QDateTime::currentDateTime()); + addSystemInfoMessage(tr("Call with %1 ended. %2").arg(f->getDisplayedName(),secondsToDHMS(timeElapsed.elapsed()/1000)), + "white", QDateTime::currentDateTime()); timer->stop(); callDuration->setText(""); callDuration->hide(); From 1cf9fe347452ab2ec5a3c2346038fba6ec309b12 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 16 Nov 2014 20:01:37 +0100 Subject: [PATCH 009/203] filetransferwidget: first steps --- res.qrc | 5 + src/chatlog/chatlog.cpp | 11 ++ src/chatlog/chatlog.h | 2 + src/chatlog/content/filetransferwidget.cpp | 31 ++-- src/chatlog/content/filetransferwidget.h | 12 +- src/chatlog/content/filetransferwidget.ui | 186 +++++++++++++++------ src/widget/form/chatform.cpp | 21 +-- ui/fileTransferInstance/arrow_white_2x.png | Bin 0 -> 214 bytes ui/fileTransferInstance/background_red.png | Bin 0 -> 493 bytes ui/fileTransferInstance/no_2x.png | Bin 0 -> 265 bytes ui/fileTransferInstance/pause_2x.png | Bin 0 -> 129 bytes ui/fileTransferInstance/yes_2x.png | Bin 0 -> 267 bytes 12 files changed, 187 insertions(+), 81 deletions(-) create mode 100644 ui/fileTransferInstance/arrow_white_2x.png create mode 100644 ui/fileTransferInstance/background_red.png create mode 100644 ui/fileTransferInstance/no_2x.png create mode 100644 ui/fileTransferInstance/pause_2x.png create mode 100644 ui/fileTransferInstance/yes_2x.png diff --git a/res.qrc b/res.qrc index dc829079a..249642bfb 100644 --- a/res.qrc +++ b/res.qrc @@ -94,6 +94,11 @@ translations/fr.qm translations/ru.qm ui/fileTransferWidget/fileTransferWidget.css + ui/fileTransferInstance/background_red.png + ui/fileTransferInstance/pause_2x.png + ui/fileTransferInstance/no_2x.png + ui/fileTransferInstance/yes_2x.png + ui/fileTransferInstance/arrow_white_2x.png ui/statusButton/dot_away.png ui/statusButton/dot_busy.png ui/statusButton/dot_idle.png diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 8d47ebeae..9fdcc4621 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -103,6 +103,17 @@ ChatMessage *ChatLog::addSystemMessage(const QString &msg, const QDateTime& time return line; } +ChatMessage *ChatLog::addFileTransferMessage(const QString &sender, const ToxFile &file, const QDateTime& timestamp, bool self) +{ + ChatMessage* line = new ChatMessage(scene, QString()); + 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 ChatLineContentProxy(new FileTransferWidget(0, file)), 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; +} + void ChatLog::clearSelection() { if(selStartRow >= 0) diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 6177819a0..3a0e0baae 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -24,6 +24,7 @@ class QGraphicsScene; class ChatLine; class ChatLineContent; class ChatMessage; +class ToxFile; class ChatLog : public QGraphicsView { @@ -36,6 +37,7 @@ public: ChatMessage* addChatMessage(const QString& sender, const QString& msg, bool self); ChatMessage* addSystemMessage(const QString& msg, const QDateTime& timestamp); + ChatMessage* addFileTransferMessage(const QString& sender, const ToxFile& file, const QDateTime ×tamp, bool self); void insertChatline(ChatLine* l); diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index ca81bdbcf..3b66f14ff 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -17,15 +17,23 @@ #include "filetransferwidget.h" #include "ui_filetransferwidget.h" +#include "src/core.h" + #include #include -FileTransferWidget::FileTransferWidget(QWidget *parent) : - QWidget(parent), - ui(new Ui::FileTransferWidget) +FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) + : QWidget(parent) + , ui(new Ui::FileTransferWidget) + , fileInfo(file) { ui->setupUi(this); + ui->filenameLabel->setText(file.fileName); + ui->progressBar->setValue(0); + + connect(Core::getInstance(), &Core::fileTransferInfo, this, &FileTransferWidget::onFileTransferInfo); + setFixedHeight(100); } @@ -34,17 +42,12 @@ FileTransferWidget::~FileTransferWidget() delete ui; } -void FileTransferWidget::on_pushButton_2_clicked() +void FileTransferWidget::onFileTransferInfo(int FriendId, int FileNum, int64_t Filesize, int64_t BytesSent, ToxFile::FileDirection direction) { - qDebug() << "Button Cancel Clicked"; -} + if(FileNum != fileInfo.fileNum) + return; -void FileTransferWidget::on_pushButton_clicked() -{ - qDebug() << "Button Resume Clicked"; -} - -void FileTransferWidget::on_pushButton_2_pressed() -{ - qDebug() << "Button Resume Clicked"; + // update progress + qreal progress = static_cast(Filesize)/static_cast(BytesSent); + ui->progressBar->setValue(static_cast(progress * 100.0)); } diff --git a/src/chatlog/content/filetransferwidget.h b/src/chatlog/content/filetransferwidget.h index e5158caf3..e25a280b5 100644 --- a/src/chatlog/content/filetransferwidget.h +++ b/src/chatlog/content/filetransferwidget.h @@ -19,6 +19,7 @@ #include #include "../chatlinecontent.h" +#include "../../corestructs.h" namespace Ui { class FileTransferWidget; @@ -29,16 +30,15 @@ class FileTransferWidget : public QWidget Q_OBJECT public: - explicit FileTransferWidget(QWidget *parent = 0); + explicit FileTransferWidget(QWidget *parent, ToxFile file); virtual ~FileTransferWidget(); +protected slots: + void onFileTransferInfo(int FriendId, int FileNum, int64_t Filesize, int64_t BytesSent, ToxFile::FileDirection direction); + private: Ui::FileTransferWidget *ui; - -private slots: - void on_pushButton_2_clicked(); - void on_pushButton_clicked(); - void on_pushButton_2_pressed(); + ToxFile fileInfo; }; diff --git a/src/chatlog/content/filetransferwidget.ui b/src/chatlog/content/filetransferwidget.ui index 4e2cca60d..11a0a63b0 100644 --- a/src/chatlog/content/filetransferwidget.ui +++ b/src/chatlog/content/filetransferwidget.ui @@ -6,8 +6,8 @@ 0 0 - 729 - 124 + 619 + 86 @@ -19,99 +19,181 @@ background-color:transparent; - + - + QFrame { -border-radius:10; -background-color:green; + border-image: url(:/ui/fileTransferInstance/background_red.png); + border-left:25;padding-top:-30; + border-top:28; + border-right:25; padding-right:-28; + border-bottom:28;padding-bottom:-30; + color:white; +} + +QPushButton { + margin:0; } - QFrame::StyledPanel + QFrame::NoFrame - QFrame::Raised + QFrame::Plain - + + 0 + + - - - color:white; - + - SomeRandomFile.7z + Filename - - - color:white; - - - 142/1742 YiB - - + + + + + 10Mb + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + 24% + + + Qt::AlignCenter + + + + + + + ETA:10:10 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 16777215 + 14 + + - color:white; + QProgressBar { + border: 2px solid black; + border-radius: 0px; + color: white; + background-color:white; +} + +QProgressBar::chunk { + background-color: black; + width: 20px; +} 24 + + Qt::Horizontal + + + false + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + 0 + - - - - 0 - 0 - + + + - + + + :/ui/fileTransferInstance/pause_2x.png:/ui/fileTransferInstance/pause_2x.png + + - 50 - 50 + 25 + 28 - - background-color:red; - - - Cancel + + true - - - - 0 - 0 - + + + Qt::Vertical - + - 50 - 50 + 20 + 40 - - background-color:rgb(0, 255, 0); - + + + + - Resume + + + + + :/ui/fileTransferInstance/arrow_white_2x.png:/ui/fileTransferInstance/arrow_white_2x.png + + + + 25 + 28 + + + + true @@ -122,6 +204,8 @@ background-color:green; - + + + diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index f7fc7829c..2d81700e1 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -164,16 +164,18 @@ void ChatForm::startFileSend(ToxFile file) if (file.friendId != f->getFriendID()) return; + + FileTransferInstance* fileTrans = new FileTransferInstance(file); ftransWidgets.insert(fileTrans->getId(), fileTrans); - connect(Core::getInstance(), &Core::fileTransferInfo, fileTrans, &FileTransferInstance::onFileTransferInfo); - connect(Core::getInstance(), &Core::fileTransferCancelled, fileTrans, &FileTransferInstance::onFileTransferCancelled); - connect(Core::getInstance(), &Core::fileTransferFinished, fileTrans, &FileTransferInstance::onFileTransferFinished); - connect(Core::getInstance(), SIGNAL(fileTransferAccepted(ToxFile)), fileTrans, SLOT(onFileTransferAccepted(ToxFile))); - connect(Core::getInstance(), SIGNAL(fileTransferPaused(int,int,ToxFile::FileDirection)), fileTrans, SLOT(onFileTransferPaused(int,int,ToxFile::FileDirection))); - connect(Core::getInstance(), SIGNAL(fileTransferRemotePausedUnpaused(ToxFile,bool)), fileTrans, SLOT(onFileTransferRemotePausedUnpaused(ToxFile,bool))); - connect(Core::getInstance(), SIGNAL(fileTransferBrokenUnbroken(ToxFile, bool)), fileTrans, SLOT(onFileTransferBrokenUnbroken(ToxFile, bool))); +// connect(Core::getInstance(), &Core::fileTransferInfo, fileTrans, &FileTransferInstance::onFileTransferInfo); +// connect(Core::getInstance(), &Core::fileTransferCancelled, fileTrans, &FileTransferInstance::onFileTransferCancelled); +// connect(Core::getInstance(), &Core::fileTransferFinished, fileTrans, &FileTransferInstance::onFileTransferFinished); +// connect(Core::getInstance(), SIGNAL(fileTransferAccepted(ToxFile)), fileTrans, SLOT(onFileTransferAccepted(ToxFile))); +// connect(Core::getInstance(), SIGNAL(fileTransferPaused(int,int,ToxFile::FileDirection)), fileTrans, SLOT(onFileTransferPaused(int,int,ToxFile::FileDirection))); +// connect(Core::getInstance(), SIGNAL(fileTransferRemotePausedUnpaused(ToxFile,bool)), fileTrans, SLOT(onFileTransferRemotePausedUnpaused(ToxFile,bool))); +// connect(Core::getInstance(), SIGNAL(fileTransferBrokenUnbroken(ToxFile, bool)), fileTrans, SLOT(onFileTransferBrokenUnbroken(ToxFile, bool))); QString name; if (!previousId.isMine()) @@ -183,9 +185,8 @@ void ChatForm::startFileSend(ToxFile file) previousId = core->getSelfId(); } - //TODO: -// chatWidget->insertMessage(ChatActionPtr(new FileTransferAction(fileTrans, getElidedName(name), -// QTime::currentTime().toString("hh:mm"), true))); + + chatWidget->addFileTransferMessage(name, file, QDateTime::currentDateTime(), true); } void ChatForm::onFileRecvRequest(ToxFile file) diff --git a/ui/fileTransferInstance/arrow_white_2x.png b/ui/fileTransferInstance/arrow_white_2x.png new file mode 100644 index 0000000000000000000000000000000000000000..646dd5ad8f0eb32b03b0bec218dce78ccb119712 GIT binary patch literal 214 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CH!3HFy_x^nYq*#ibJVQ8upoSx*1IXtr@Q5r1 zsyPC}j8nDwq=AAJo-U3d8WX2p3gkWHAmDnDoohk^i;4oHriTNQ(1eB-FHOFJf*%>% za-=fK^FRH2ruJD)SeRdC!rCL#>%X5|1o(*Wj`E#?e}RcfD)Et8&+}31xA=`yQ%P zZd+#}pWrP~c&%XR&L>9uTdta~Y-LxPHLSr@;v!@r;4SzrRvLTwe=G5I&Fz3HfF|6u2HL; zpLwAAn%d3vzyCdd`s+Zz_TE@KvHQ2*s-3((=dw-5_DNN4nYY$0k$X04o7T#BTi@tu zHqYN5tQT=+JjT?+D#2|amY{PWqG2OL@<0m&1c~cs-&(pPZ^gAO#h$TG*JduCv}AU5 z7yHGjuZw<^z4Lq*v-{oe!#_;#98cK3Wo7LvUuNa?sUDw>Z{^wlPRRJ@w$o(=z^GyH MboFyt=akR{07r_y#sB~S literal 0 HcmV?d00001 diff --git a/ui/fileTransferInstance/no_2x.png b/ui/fileTransferInstance/no_2x.png new file mode 100644 index 0000000000000000000000000000000000000000..86c05eb5a378e1a9c6f906843e7fd7434076db6d GIT binary patch literal 265 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE;=WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8)t)YnAr-ggT)oKKYQVu7@Q9`Fk%w&WM45wvB~7P{6QqKk zeDZkbKXtOnQm?(`mrPD--fY{dvpQw^hPAyjM7yNYjFVdQ&MBb@0D!(`cmMzZ literal 0 HcmV?d00001 diff --git a/ui/fileTransferInstance/pause_2x.png b/ui/fileTransferInstance/pause_2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6ee39a91e3cd34fe44f599dd3f7791f6aa733426 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRp!3HFQtmCqPlw^r(L`iUdT1k0gQ7VIDN`6wR zf@f}GdTLN=VoGJ<$y6JlB4tk($B>F!Nq_iRcxE(AWHfgOJa3V8U8U}fi7AzZCsS>Jiq?9%IEGZ*+H&P0Z?gdp%Y{vh${QSS_vV?nz2NAX5P0K2 zsfrJC)*X>}oxA*u_JSSkf;%T>U(uPh Date: Mon, 17 Nov 2014 16:05:14 +0100 Subject: [PATCH 010/203] hooked up filetransferwidget --- res.qrc | 7 + src/chatlog/content/filetransferwidget.cpp | 186 +++++++++++- src/chatlog/content/filetransferwidget.h | 21 +- src/chatlog/content/filetransferwidget.ui | 271 ++++++++++-------- src/core.cpp | 25 +- src/core.h | 6 +- src/corestructs.cpp | 10 + src/corestructs.h | 8 +- src/widget/form/chatform.cpp | 14 +- ui/fileTransferInstance/background_green.png | Bin 0 -> 495 bytes ui/fileTransferInstance/background_grey.png | Bin 0 -> 487 bytes ui/fileTransferInstance/background_yellow.png | Bin 0 -> 495 bytes 12 files changed, 396 insertions(+), 152 deletions(-) create mode 100644 ui/fileTransferInstance/background_green.png create mode 100644 ui/fileTransferInstance/background_grey.png create mode 100644 ui/fileTransferInstance/background_yellow.png diff --git a/res.qrc b/res.qrc index 249642bfb..6c35d1e48 100644 --- a/res.qrc +++ b/res.qrc @@ -94,7 +94,14 @@ translations/fr.qm translations/ru.qm ui/fileTransferWidget/fileTransferWidget.css + ui/fileTransferInstance/red.css + ui/fileTransferInstance/green.css + ui/fileTransferInstance/grey.css + ui/fileTransferInstance/yellow.css ui/fileTransferInstance/background_red.png + ui/fileTransferInstance/background_yellow.png + ui/fileTransferInstance/background_green.png + ui/fileTransferInstance/background_grey.png ui/fileTransferInstance/pause_2x.png ui/fileTransferInstance/no_2x.png ui/fileTransferInstance/yes_2x.png diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index 3b66f14ff..a753ea741 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -18,6 +18,7 @@ #include "ui_filetransferwidget.h" #include "src/core.h" +#include "src/misc/style.h" #include #include @@ -26,15 +27,28 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) : QWidget(parent) , ui(new Ui::FileTransferWidget) , fileInfo(file) + , lastTick(QTime::currentTime()) { ui->setupUi(this); ui->filenameLabel->setText(file.fileName); ui->progressBar->setValue(0); + ui->fileSizeLabel->setText(getHumanReadableSize(file.filesize)); + ui->progressLabel->setText("0%"); + ui->etaLabel->setText("--:--"); + + setStyleSheet(Style::getStylesheet(":/ui/fileTransferInstance/grey.css")); + Style::repolish(this); connect(Core::getInstance(), &Core::fileTransferInfo, this, &FileTransferWidget::onFileTransferInfo); + connect(Core::getInstance(), &Core::fileTransferAccepted, this, &FileTransferWidget::onFileTransferAccepted); + connect(Core::getInstance(), &Core::fileTransferCancelled, this, &FileTransferWidget::onFileTransferCancelled); + connect(Core::getInstance(), &Core::fileTransferPaused, this, &FileTransferWidget::onFileTransferPaused); + connect(Core::getInstance(), &Core::fileTransferFinished, this, &FileTransferWidget::onFileTransferFinished); - setFixedHeight(100); + setupButtons(); + + setFixedHeight(85); } FileTransferWidget::~FileTransferWidget() @@ -42,12 +56,176 @@ FileTransferWidget::~FileTransferWidget() delete ui; } -void FileTransferWidget::onFileTransferInfo(int FriendId, int FileNum, int64_t Filesize, int64_t BytesSent, ToxFile::FileDirection direction) +void FileTransferWidget::onFileTransferInfo(ToxFile file) { - if(FileNum != fileInfo.fileNum) + if(fileInfo != file) return; + fileInfo = file; + // update progress - qreal progress = static_cast(Filesize)/static_cast(BytesSent); + qreal progress = static_cast(file.bytesSent) / static_cast(file.filesize); ui->progressBar->setValue(static_cast(progress * 100.0)); + + // eta, speed + QTime now = QTime::currentTime(); + qreal deltaSecs = lastTick.msecsTo(now) / 1000.0; + + if(deltaSecs >= 1.0) + { + qint64 deltaBytes = file.bytesSent - lastBytesSent; + qint64 bytesPerSec = static_cast(static_cast(deltaBytes) / deltaSecs); + + if(bytesPerSec > 0) + { + QTime toGo(0,0,file.filesize / bytesPerSec); + ui->etaLabel->setText(toGo.toString("mm:ss")); + } + else + { + ui->etaLabel->setText("--:--"); + } + + ui->progressLabel->setText(getHumanReadableSize(bytesPerSec) + "/s"); + + lastTick = now; + lastBytesSent = file.bytesSent; + } + + setupButtons(); + + repaint(); +} + +void FileTransferWidget::onFileTransferAccepted(ToxFile file) +{ + if(fileInfo != file) + return; + + fileInfo = file; + + setStyleSheet(Style::getStylesheet(":/ui/fileTransferInstance/yellow.css")); + Style::repolish(this); + + setupButtons(); +} + +void FileTransferWidget::onFileTransferCancelled(ToxFile file) +{ + if(fileInfo != file) + return; + + fileInfo = file; + + setStyleSheet(Style::getStylesheet(":/ui/fileTransferInstance/red.css")); + Style::repolish(this); + + setupButtons(); + hideWidgets(); + + disconnect(Core::getInstance()); +} + +void FileTransferWidget::onFileTransferPaused(ToxFile file) +{ + if(fileInfo != file) + return; + + fileInfo = file; + + setStyleSheet(Style::getStylesheet(":/ui/fileTransferInstance/grey.css")); + Style::repolish(this); + + setupButtons(); +} + +void FileTransferWidget::onFileTransferFinished(ToxFile file) +{ + if(fileInfo != file) + return; + + fileInfo = file; + + setStyleSheet(Style::getStylesheet(":/ui/fileTransferInstance/green.css")); + Style::repolish(this); + + setupButtons(); + hideWidgets(); + + disconnect(Core::getInstance()); +} + +QString FileTransferWidget::getHumanReadableSize(qint64 size) +{ + static const char* suffix[] = {"B","kiB","MiB","GiB","TiB"}; + int exp = 0; + + if (size > 0) + 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 FileTransferWidget::hideWidgets() +{ + ui->buttonWidget->hide(); + ui->progressBar->hide(); + ui->progressLabel->hide(); + ui->etaLabel->hide(); +} + +void FileTransferWidget::setupButtons() +{ + switch(fileInfo.status) + { + case ToxFile::TRANSMITTING: + ui->topButton->setIcon(QIcon(":/ui/fileTransferInstance/no_2x.png")); + ui->topButton->setObjectName("cancel"); + + ui->bottomButton->setIcon(QIcon(":/ui/fileTransferInstance/pause_2x.png")); + ui->bottomButton->setObjectName("pause"); + break; + case ToxFile::PAUSED: + ui->topButton->setIcon(QIcon(":/ui/fileTransferInstance/no_2x.png")); + ui->topButton->setObjectName("cancel"); + + ui->bottomButton->setIcon(QIcon(":/ui/fileTransferInstance/arrow_white_2x.png")); + ui->bottomButton->setObjectName("resume"); + break; + case ToxFile::STOPPED: + case ToxFile::BROKEN: //TODO: ? + break; + } +} + +void FileTransferWidget::handleButton(QPushButton *btn) +{ + if(fileInfo.direction == ToxFile::SENDING) + { + if(btn->objectName() == "cancel") + Core::getInstance()->cancelFileSend(fileInfo.friendId, fileInfo.fileNum); + if(btn->objectName() == "pause") + Core::getInstance()->pauseResumeFileSend(fileInfo.friendId, fileInfo.fileNum); + if(btn->objectName() == "resume") + Core::getInstance()->pauseResumeFileSend(fileInfo.friendId, fileInfo.fileNum); + } + else + { + if(btn->objectName() == "cancel") + Core::getInstance()->cancelFileRecv(fileInfo.friendId, fileInfo.fileNum); + if(btn->objectName() == "pause") + Core::getInstance()->pauseResumeFileRecv(fileInfo.friendId, fileInfo.fileNum); + if(btn->objectName() == "resume") + Core::getInstance()->pauseResumeFileRecv(fileInfo.friendId, fileInfo.fileNum); + } +} + +void FileTransferWidget::on_topButton_clicked() +{ + handleButton(ui->topButton); +} + +void FileTransferWidget::on_bottomButton_clicked() +{ + handleButton(ui->bottomButton); } diff --git a/src/chatlog/content/filetransferwidget.h b/src/chatlog/content/filetransferwidget.h index e25a280b5..d4a32e6e0 100644 --- a/src/chatlog/content/filetransferwidget.h +++ b/src/chatlog/content/filetransferwidget.h @@ -18,6 +18,7 @@ #define FILETRANSFERWIDGET_H #include +#include #include "../chatlinecontent.h" #include "../../corestructs.h" @@ -25,6 +26,8 @@ namespace Ui { class FileTransferWidget; } +class QPushButton; + class FileTransferWidget : public QWidget { Q_OBJECT @@ -34,11 +37,27 @@ public: virtual ~FileTransferWidget(); protected slots: - void onFileTransferInfo(int FriendId, int FileNum, int64_t Filesize, int64_t BytesSent, ToxFile::FileDirection direction); + void onFileTransferInfo(ToxFile file); + void onFileTransferAccepted(ToxFile file); + void onFileTransferCancelled(ToxFile file); + void onFileTransferPaused(ToxFile file); + void onFileTransferFinished(ToxFile file); + +protected: + QString getHumanReadableSize(qint64 size); + void hideWidgets(); + void setupButtons(); + void handleButton(QPushButton* btn); + +private slots: + void on_topButton_clicked(); + void on_bottomButton_clicked(); private: Ui::FileTransferWidget *ui; ToxFile fileInfo; + QTime lastTick; + qint64 lastBytesSent = 0; }; diff --git a/src/chatlog/content/filetransferwidget.ui b/src/chatlog/content/filetransferwidget.ui index 11a0a63b0..7467ee60e 100644 --- a/src/chatlog/content/filetransferwidget.ui +++ b/src/chatlog/content/filetransferwidget.ui @@ -6,35 +6,29 @@ 0 0 - 619 - 86 + 544 + 207 Form - - false - - background-color:transparent; + #FileTransferWidget { + background-color:transparent; +} - + + + + 0 + 0 + + - QFrame { - border-image: url(:/ui/fileTransferInstance/background_red.png); - border-left:25;padding-top:-30; - border-top:28; - border-right:25; padding-right:-28; - border-bottom:28;padding-bottom:-30; - color:white; -} - -QPushButton { - margin:0; -} + QFrame::NoFrame @@ -45,70 +39,89 @@ QPushButton { 0 - + + + 6 + + + 6 + + + + 0 + 0 + + Filename - - - - - 10Mb - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - 24% - - - Qt::AlignCenter - - - - - - - ETA:10:10 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 10Mb + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + 24% + + + Qt::AlignCenter + + + + + + + ETA:10:10 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + 16777215 - 14 + 10 - QProgressBar { - border: 2px solid black; - border-radius: 0px; - color: white; - background-color:white; -} - -QProgressBar::chunk { - background-color: black; - width: 20px; -} + 24 @@ -140,64 +153,78 @@ QProgressBar::chunk { - - - 0 - - - - - - - - - :/ui/fileTransferInstance/pause_2x.png:/ui/fileTransferInstance/pause_2x.png - - - - 25 - 28 - - - - true - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - :/ui/fileTransferInstance/arrow_white_2x.png:/ui/fileTransferInstance/arrow_white_2x.png - - - - 25 - 28 - - - - true - - - - + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + :/ui/fileTransferInstance/pause_2x.png:/ui/fileTransferInstance/pause_2x.png + + + + 25 + 28 + + + + true + + + + + + + Qt::Vertical + + + + 20 + 92 + + + + + + + + + + + + :/ui/fileTransferInstance/arrow_white_2x.png:/ui/fileTransferInstance/arrow_white_2x.png + + + + 25 + 28 + + + + true + + + + + diff --git a/src/core.cpp b/src/core.cpp index f9bbd2cf4..f13948cd8 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -567,7 +567,7 @@ void Core::onFileControlCallback(Tox* tox, int32_t friendnumber, uint8_t receive qDebug() << QString("Core::onFileControlCallback: Transfer of file %1 cancelled by friend %2") .arg(file->fileNum).arg(file->friendId); file->status = ToxFile::STOPPED; - emit static_cast(core)->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); + emit static_cast(core)->fileTransferCancelled(*file); // Wait for sendAllFileData to return before deleting the ToxFile, we MUST ensure this or we'll use after free if (file->sendTimer) { @@ -594,7 +594,7 @@ void Core::onFileControlCallback(Tox* tox, int32_t friendnumber, uint8_t receive qDebug() << QString("Core::onFileControlCallback: Transfer of file %1 cancelled by friend %2") .arg(file->fileNum).arg(file->friendId); file->status = ToxFile::STOPPED; - emit static_cast(core)->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::RECEIVING); + emit static_cast(core)->fileTransferCancelled(*file); removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); } else if (receive_send == 0 && control_type == TOX_FILECONTROL_FINISHED) @@ -669,8 +669,7 @@ void Core::onFileDataCallback(Tox*, int32_t friendnumber, uint8_t filenumber, co file->file->write((char*)data,length); file->bytesSent += length; //qDebug() << QString("Core::onFileDataCallback: received %1/%2 bytes").arg(file->bytesSent).arg(file->filesize); - emit static_cast(core)->fileTransferInfo(file->friendId, file->fileNum, - file->filesize, file->bytesSent, ToxFile::RECEIVING); + emit static_cast(core)->fileTransferInfo(*file); } void Core::onAvatarInfoCallback(Tox*, int32_t friendnumber, uint8_t format, @@ -852,7 +851,7 @@ void Core::pauseResumeFileSend(int friendId, int fileNum) if (file->status == ToxFile::TRANSMITTING) { file->status = ToxFile::PAUSED; - emit fileTransferPaused(file->friendId, file->fileNum, ToxFile::SENDING); + emit fileTransferPaused(*file); tox_file_send_control(tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_PAUSE, nullptr, 0); } else if (file->status == ToxFile::PAUSED) @@ -884,7 +883,7 @@ void Core::pauseResumeFileRecv(int friendId, int fileNum) if (file->status == ToxFile::TRANSMITTING) { file->status = ToxFile::PAUSED; - emit fileTransferPaused(file->friendId, file->fileNum, ToxFile::RECEIVING); + emit fileTransferPaused(*file); tox_file_send_control(tox, file->friendId, 1, file->fileNum, TOX_FILECONTROL_PAUSE, nullptr, 0); } else if (file->status == ToxFile::PAUSED) @@ -914,7 +913,7 @@ void Core::cancelFileSend(int friendId, int fileNum) return; } file->status = ToxFile::STOPPED; - emit fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); + emit fileTransferCancelled(*file); tox_file_send_control(tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); while (file->sendTimer) QThread::msleep(1); // Wait until sendAllFileData returns before deleting removeFileFromQueue(true, friendId, fileNum); @@ -937,7 +936,7 @@ void Core::cancelFileRecv(int friendId, int fileNum) return; } file->status = ToxFile::STOPPED; - emit fileTransferCancelled(file->friendId, file->fileNum, ToxFile::RECEIVING); + emit fileTransferCancelled(*file); tox_file_send_control(tox, file->friendId, 1, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); removeFileFromQueue(true, friendId, fileNum); } @@ -959,7 +958,7 @@ void Core::rejectFileRecvRequest(int friendId, int fileNum) return; } file->status = ToxFile::STOPPED; - emit fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); + emit fileTransferCancelled(*file); tox_file_send_control(tox, file->friendId, 1, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); removeFileFromQueue(false, friendId, fileNum); } @@ -1557,14 +1556,14 @@ void Core::sendAllFileData(Core *core, ToxFile* file) file->sendTimer = nullptr; return; } - emit core->fileTransferInfo(file->friendId, file->fileNum, file->filesize, file->bytesSent, ToxFile::SENDING); + emit core->fileTransferInfo(*file); // qApp->processEvents(); long long chunkSize = tox_file_data_size(core->tox, file->friendId); if (chunkSize == -1) { qWarning("Core::fileHeartbeat: Error getting preffered chunk size, aborting file send"); file->status = ToxFile::STOPPED; - emit core->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); + emit core->fileTransferCancelled(*file); tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); removeFileFromQueue(true, file->friendId, file->fileNum); return; @@ -1579,7 +1578,7 @@ void Core::sendAllFileData(Core *core, ToxFile* file) qWarning() << QString("Core::sendAllFileData: Error reading from file: %1").arg(file->file->errorString()); delete[] data; file->status = ToxFile::STOPPED; - emit core->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); + emit core->fileTransferCancelled(*file); tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); removeFileFromQueue(true, file->friendId, file->fileNum); return; @@ -1589,7 +1588,7 @@ void Core::sendAllFileData(Core *core, ToxFile* file) qWarning() << QString("Core::sendAllFileData: Nothing to read from file: %1").arg(file->file->errorString()); delete[] data; file->status = ToxFile::STOPPED; - emit core->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); + emit core->fileTransferCancelled(*file); tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); removeFileFromQueue(true, file->friendId, file->fileNum); return; diff --git a/src/core.h b/src/core.h index 0c393ebfc..60ec5e67e 100644 --- a/src/core.h +++ b/src/core.h @@ -173,12 +173,12 @@ signals: void fileSendStarted(ToxFile file); void fileReceiveRequested(ToxFile file); void fileTransferAccepted(ToxFile file); - void fileTransferCancelled(int FriendId, int FileNum, ToxFile::FileDirection direction); + void fileTransferCancelled(ToxFile file); void fileTransferFinished(ToxFile file); void fileUploadFinished(const QString& path); void fileDownloadFinished(const QString& path); - void fileTransferPaused(int FriendId, int FileNum, ToxFile::FileDirection direction); - void fileTransferInfo(int FriendId, int FileNum, int64_t Filesize, int64_t BytesSent, ToxFile::FileDirection direction); + void fileTransferPaused(ToxFile file); + void fileTransferInfo(ToxFile file); void fileTransferRemotePausedUnpaused(ToxFile file, bool paused); void fileTransferBrokenUnbroken(ToxFile file, bool broken); diff --git a/src/corestructs.cpp b/src/corestructs.cpp index ecdca2abd..3f66354de 100644 --- a/src/corestructs.cpp +++ b/src/corestructs.cpp @@ -12,6 +12,16 @@ ToxFile::ToxFile(int FileNum, int FriendId, QByteArray FileName, QString FilePat { } +bool ToxFile::operator==(const ToxFile &other) const +{ + return fileNum == other.fileNum && friendId && other.friendId; +} + +bool ToxFile::operator!=(const ToxFile &other) const +{ + return !(*this == other); +} + void ToxFile::setFilePath(QString path) { filePath=path; diff --git a/src/corestructs.h b/src/corestructs.h index 1453db415..9826b4c0a 100644 --- a/src/corestructs.h +++ b/src/corestructs.h @@ -57,6 +57,10 @@ struct ToxFile ToxFile()=default; ToxFile(int FileNum, int FriendId, QByteArray FileName, QString FilePath, FileDirection Direction); ~ToxFile(){} + + bool operator==(const ToxFile& other) const; + bool operator!=(const ToxFile& other) const; + void setFilePath(QString path); bool open(bool write); @@ -65,8 +69,8 @@ struct ToxFile QByteArray fileName; QString filePath; QFile* file; - long long bytesSent; - long long filesize; + qint64 bytesSent; + qint64 filesize; FileStatus status; FileDirection direction; QTimer* sendTimer; diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 2d81700e1..9a6aaac6d 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -197,13 +197,13 @@ void ChatForm::onFileRecvRequest(ToxFile file) FileTransferInstance* fileTrans = new FileTransferInstance(file); ftransWidgets.insert(fileTrans->getId(), fileTrans); - connect(Core::getInstance(), &Core::fileTransferInfo, fileTrans, &FileTransferInstance::onFileTransferInfo); - connect(Core::getInstance(), &Core::fileTransferCancelled, fileTrans, &FileTransferInstance::onFileTransferCancelled); - connect(Core::getInstance(), &Core::fileTransferFinished, fileTrans, &FileTransferInstance::onFileTransferFinished); - connect(Core::getInstance(), SIGNAL(fileTransferAccepted(ToxFile)), fileTrans, SLOT(onFileTransferAccepted(ToxFile))); - connect(Core::getInstance(), SIGNAL(fileTransferPaused(int,int,ToxFile::FileDirection)), fileTrans, SLOT(onFileTransferPaused(int,int,ToxFile::FileDirection))); - connect(Core::getInstance(), SIGNAL(fileTransferRemotePausedUnpaused(ToxFile,bool)), fileTrans, SLOT(onFileTransferRemotePausedUnpaused(ToxFile,bool))); - connect(Core::getInstance(), SIGNAL(fileTransferBrokenUnbroken(ToxFile, bool)), fileTrans, SLOT(onFileTransferBrokenUnbroken(ToxFile, bool))); +// connect(Core::getInstance(), &Core::fileTransferInfo, fileTrans, &FileTransferInstance::onFileTransferInfo); +// connect(Core::getInstance(), &Core::fileTransferCancelled, fileTrans, &FileTransferInstance::onFileTransferCancelled); +// connect(Core::getInstance(), &Core::fileTransferFinished, fileTrans, &FileTransferInstance::onFileTransferFinished); +// connect(Core::getInstance(), SIGNAL(fileTransferAccepted(ToxFile)), fileTrans, SLOT(onFileTransferAccepted(ToxFile))); +// connect(Core::getInstance(), SIGNAL(fileTransferPaused(int,int,ToxFile::FileDirection)), fileTrans, SLOT(onFileTransferPaused(int,int,ToxFile::FileDirection))); +// connect(Core::getInstance(), SIGNAL(fileTransferRemotePausedUnpaused(ToxFile,bool)), fileTrans, SLOT(onFileTransferRemotePausedUnpaused(ToxFile,bool))); +// connect(Core::getInstance(), SIGNAL(fileTransferBrokenUnbroken(ToxFile, bool)), fileTrans, SLOT(onFileTransferBrokenUnbroken(ToxFile, bool))); Widget* w = Widget::getInstance(); if (!w->isFriendWidgetCurActiveWidget(f)|| w->isMinimized() || !w->isActiveWindow()) diff --git a/ui/fileTransferInstance/background_green.png b/ui/fileTransferInstance/background_green.png new file mode 100644 index 0000000000000000000000000000000000000000..07c072b7b18bd8ef50fc271e8f05e0d21c9aa3a1 GIT binary patch literal 495 zcmeAS@N?(olHy`uVBq!ia0vp^-as6}!3HExojbJzNU;<lp#TxLhx5%tV>z@BxLtNt=*sXF)LF_T-k2zORO~cYgooUkP zbSux?Z~m{*#?-?q!EGRxpmQLiVIxB_tAqNq+hxWy*b_qPu_~szqm}~02vOiTYm0vXE9NmA2DWo~s;J`5pB-vFc*);~9w(_a@h<|BT5v;C@a0 z=GCbB`|J35N^f6zy4rfK-)t3oZ@1Di?$m34 zKYiYlgI~8^JN(7;&e4SJUovZN`7#TyPxUBz9@S>g&SLcH>Fic(V5Bg3y85}Sb4q9e E0HL0>9RL6T literal 0 HcmV?d00001 diff --git a/ui/fileTransferInstance/background_yellow.png b/ui/fileTransferInstance/background_yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..1ba362293bd38ab3f3d16d1175c498ded3a6e936 GIT binary patch literal 495 zcmeAS@N?(olHy`uVBq!ia0vp^-as6}!3HExojbJzNU;<lp#TxLhx5%tV>#wYiU|a^=`r2TnieE~TIrO+DW(~ZB0W@BR=8X`vyzkN z`Q*->#Yeoa)J|Ua`jYiK@zW}+RX(d+R#EMLKIh4lClgYPv&(M(JG$icE}8G$&sF3- z@3~2Rn6}mP+UB(HpGzteR=obD_kQyG_0v-)oi|**Q+U1V*PcroLOpHInC8RCAV8If-xN94VJ?{prO Date: Mon, 17 Nov 2014 20:08:55 +0100 Subject: [PATCH 011/203] more work on filetransferwidget --- src/chatlog/content/filetransferwidget.cpp | 57 +++++++++++++++++++++- src/chatlog/content/filetransferwidget.h | 1 + src/chatlog/content/filetransferwidget.ui | 32 +++++++++--- src/corestructs.cpp | 2 +- src/widget/form/chatform.cpp | 35 ++----------- ui/fileTransferInstance/green.css | 27 ++++++++++ ui/fileTransferInstance/grey.css | 27 ++++++++++ ui/fileTransferInstance/red.css | 27 ++++++++++ ui/fileTransferInstance/yellow.css | 27 ++++++++++ 9 files changed, 196 insertions(+), 39 deletions(-) create mode 100644 ui/fileTransferInstance/green.css create mode 100644 ui/fileTransferInstance/grey.css create mode 100644 ui/fileTransferInstance/red.css create mode 100644 ui/fileTransferInstance/yellow.css diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index a753ea741..33fcc505e 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -21,6 +21,10 @@ #include "src/misc/style.h" #include +#include +#include +#include +#include #include FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) @@ -31,6 +35,10 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) { ui->setupUi(this); + // hide the QWidget background (background-color: transparent doesn't seem to work) + setAttribute(Qt::WA_TranslucentBackground, true); + + ui->previewLabel->hide(); ui->filenameLabel->setText(file.fileName); ui->progressBar->setValue(0); ui->fileSizeLabel->setText(getHumanReadableSize(file.filesize)); @@ -48,6 +56,10 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) setupButtons(); + //preview + if(fileInfo.direction == ToxFile::SENDING) + showPreview(fileInfo.filePath); + setFixedHeight(85); } @@ -123,7 +135,7 @@ void FileTransferWidget::onFileTransferCancelled(ToxFile file) setupButtons(); hideWidgets(); - disconnect(Core::getInstance()); + disconnect(Core::getInstance(), 0, this, 0); } void FileTransferWidget::onFileTransferPaused(ToxFile file) @@ -152,7 +164,11 @@ void FileTransferWidget::onFileTransferFinished(ToxFile file) setupButtons(); hideWidgets(); - disconnect(Core::getInstance()); + // preview + if(fileInfo.direction == ToxFile::RECEIVING) + showPreview(fileInfo.filePath); + + disconnect(Core::getInstance(), 0, this, 0); } QString FileTransferWidget::getHumanReadableSize(qint64 size) @@ -194,6 +210,19 @@ void FileTransferWidget::setupButtons() break; case ToxFile::STOPPED: case ToxFile::BROKEN: //TODO: ? + ui->topButton->setIcon(QIcon(":/ui/fileTransferInstance/no_2x.png")); + ui->topButton->setObjectName("cancel"); + + if(fileInfo.direction == ToxFile::SENDING) + { + ui->bottomButton->setIcon(QIcon(":/ui/fileTransferInstance/pause_2x.png")); + ui->bottomButton->setObjectName("pause"); + } + else + { + ui->bottomButton->setIcon(QIcon(":/ui/fileTransferInstance/yes_2x.png")); + ui->bottomButton->setObjectName("accept"); + } break; } } @@ -217,9 +246,33 @@ void FileTransferWidget::handleButton(QPushButton *btn) Core::getInstance()->pauseResumeFileRecv(fileInfo.friendId, fileInfo.fileNum); if(btn->objectName() == "resume") Core::getInstance()->pauseResumeFileRecv(fileInfo.friendId, fileInfo.fileNum); + if(btn->objectName() == "accept") + { + QString path = QFileDialog::getSaveFileName(0, tr("Save a file","Title of the file saving dialog"), QDir::home().filePath(fileInfo.fileName)); + + if(!QFileInfo(QDir(path).path()).isWritable()) + { + QMessageBox::warning(0, + 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")); + + return; + } + + if(!path.isEmpty()) + Core::getInstance()->acceptFileRecvRequest(fileInfo.friendId, fileInfo.fileNum, path); + } } } +void FileTransferWidget::showPreview(const QString &filename) +{ + //QPixmap pmap = QPixmap(filename).scaled(QSize(ui->previewLabel->maximumWidth(), maximumHeight()), Qt::KeepAspectRatio, Qt::SmoothTransformation); + QPixmap pmap = QPixmap(filename).scaledToWidth(ui->previewLabel->maximumWidth(), Qt::SmoothTransformation); + ui->previewLabel->setPixmap(pmap); + ui->previewLabel->show(); +} + void FileTransferWidget::on_topButton_clicked() { handleButton(ui->topButton); diff --git a/src/chatlog/content/filetransferwidget.h b/src/chatlog/content/filetransferwidget.h index d4a32e6e0..11d6b52ee 100644 --- a/src/chatlog/content/filetransferwidget.h +++ b/src/chatlog/content/filetransferwidget.h @@ -48,6 +48,7 @@ protected: void hideWidgets(); void setupButtons(); void handleButton(QPushButton* btn); + void showPreview(const QString& filename); private slots: void on_topButton_clicked(); diff --git a/src/chatlog/content/filetransferwidget.ui b/src/chatlog/content/filetransferwidget.ui index 7467ee60e..7992bce16 100644 --- a/src/chatlog/content/filetransferwidget.ui +++ b/src/chatlog/content/filetransferwidget.ui @@ -13,12 +13,7 @@ Form - - #FileTransferWidget { - background-color:transparent; -} - - + @@ -40,6 +35,31 @@ 0 + + 0 + + + 0 + + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + [preview] + + + diff --git a/src/corestructs.cpp b/src/corestructs.cpp index 3f66354de..5ed31df65 100644 --- a/src/corestructs.cpp +++ b/src/corestructs.cpp @@ -14,7 +14,7 @@ ToxFile::ToxFile(int FileNum, int FriendId, QByteArray FileName, QString FilePat bool ToxFile::operator==(const ToxFile &other) const { - return fileNum == other.fileNum && friendId && other.friendId; + return (fileNum == other.fileNum) && (friendId == other.friendId) && (direction == other.direction); } bool ToxFile::operator!=(const ToxFile &other) const diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 9a6aaac6d..467258633 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -164,19 +164,6 @@ void ChatForm::startFileSend(ToxFile file) if (file.friendId != f->getFriendID()) return; - - - FileTransferInstance* fileTrans = new FileTransferInstance(file); - ftransWidgets.insert(fileTrans->getId(), fileTrans); - -// connect(Core::getInstance(), &Core::fileTransferInfo, fileTrans, &FileTransferInstance::onFileTransferInfo); -// connect(Core::getInstance(), &Core::fileTransferCancelled, fileTrans, &FileTransferInstance::onFileTransferCancelled); -// connect(Core::getInstance(), &Core::fileTransferFinished, fileTrans, &FileTransferInstance::onFileTransferFinished); -// connect(Core::getInstance(), SIGNAL(fileTransferAccepted(ToxFile)), fileTrans, SLOT(onFileTransferAccepted(ToxFile))); -// connect(Core::getInstance(), SIGNAL(fileTransferPaused(int,int,ToxFile::FileDirection)), fileTrans, SLOT(onFileTransferPaused(int,int,ToxFile::FileDirection))); -// connect(Core::getInstance(), SIGNAL(fileTransferRemotePausedUnpaused(ToxFile,bool)), fileTrans, SLOT(onFileTransferRemotePausedUnpaused(ToxFile,bool))); -// connect(Core::getInstance(), SIGNAL(fileTransferBrokenUnbroken(ToxFile, bool)), fileTrans, SLOT(onFileTransferBrokenUnbroken(ToxFile, bool))); - QString name; if (!previousId.isMine()) { @@ -194,17 +181,6 @@ void ChatForm::onFileRecvRequest(ToxFile file) if (file.friendId != f->getFriendID()) return; - FileTransferInstance* fileTrans = new FileTransferInstance(file); - ftransWidgets.insert(fileTrans->getId(), fileTrans); - -// connect(Core::getInstance(), &Core::fileTransferInfo, fileTrans, &FileTransferInstance::onFileTransferInfo); -// connect(Core::getInstance(), &Core::fileTransferCancelled, fileTrans, &FileTransferInstance::onFileTransferCancelled); -// connect(Core::getInstance(), &Core::fileTransferFinished, fileTrans, &FileTransferInstance::onFileTransferFinished); -// connect(Core::getInstance(), SIGNAL(fileTransferAccepted(ToxFile)), fileTrans, SLOT(onFileTransferAccepted(ToxFile))); -// connect(Core::getInstance(), SIGNAL(fileTransferPaused(int,int,ToxFile::FileDirection)), fileTrans, SLOT(onFileTransferPaused(int,int,ToxFile::FileDirection))); -// connect(Core::getInstance(), SIGNAL(fileTransferRemotePausedUnpaused(ToxFile,bool)), fileTrans, SLOT(onFileTransferRemotePausedUnpaused(ToxFile,bool))); -// connect(Core::getInstance(), SIGNAL(fileTransferBrokenUnbroken(ToxFile, bool)), fileTrans, SLOT(onFileTransferBrokenUnbroken(ToxFile, bool))); - Widget* w = Widget::getInstance(); if (!w->isFriendWidgetCurActiveWidget(f)|| w->isMinimized() || !w->isActiveWindow()) { @@ -221,12 +197,11 @@ void ChatForm::onFileRecvRequest(ToxFile file) previousId = friendId; } - //TODO: chatWidget->insertMessage(ChatActionPtr(new FileTransferAction(fileTrans, getElidedName(name), - // QTime::currentTime().toString("hh:mm"), false))); - - if (!Settings::getInstance().getAutoAcceptDir(Core::getInstance()->getFriendAddress(f->getFriendID())).isEmpty() - || Settings::getInstance().getAutoSaveEnabled()) - fileTrans->pressFromHtml("btnB"); + chatWidget->addFileTransferMessage(name, file, QDateTime::currentDateTime(), false); +//TODO: +// if (!Settings::getInstance().getAutoAcceptDir(Core::getInstance()->getFriendAddress(f->getFriendID())).isEmpty() +// || Settings::getInstance().getAutoSaveEnabled()) +// fileTrans->pressFromHtml("btnB"); } void ChatForm::onAvInvite(int FriendId, int CallId, bool video) diff --git a/ui/fileTransferInstance/green.css b/ui/fileTransferInstance/green.css new file mode 100644 index 000000000..9a37b0b0b --- /dev/null +++ b/ui/fileTransferInstance/green.css @@ -0,0 +1,27 @@ +QFrame { + border-image: url(:/ui/fileTransferInstance/background_green.png); + border-left:25;padding-top:-30; + border-top:28; + border-right:25; padding-right:-28; + border-bottom:28;padding-bottom:-30; +} + +QLabel { + color:white; +} + +QPushButton { + margin:0; +} + +QProgressBar { + border: 2px solid black; + border-radius: 0px; + color: white; + background-color:white; +} + +QProgressBar::chunk { + background-color: black; + width: 20px; +} \ No newline at end of file diff --git a/ui/fileTransferInstance/grey.css b/ui/fileTransferInstance/grey.css new file mode 100644 index 000000000..1d390374d --- /dev/null +++ b/ui/fileTransferInstance/grey.css @@ -0,0 +1,27 @@ +QFrame { + border-image: url(:/ui/fileTransferInstance/background_grey.png); + border-left:25;padding-top:-30; + border-top:28; + border-right:25; padding-right:-28; + border-bottom:28;padding-bottom:-30; +} + +QLabel { + color:black; +} + +QPushButton { + margin:0; +} + +QProgressBar { + border: 2px solid black; + border-radius: 0px; + color: white; + background-color:white; +} + +QProgressBar::chunk { + background-color: black; + width: 20px; +} \ No newline at end of file diff --git a/ui/fileTransferInstance/red.css b/ui/fileTransferInstance/red.css new file mode 100644 index 000000000..13800e049 --- /dev/null +++ b/ui/fileTransferInstance/red.css @@ -0,0 +1,27 @@ +QFrame { + border-image: url(:/ui/fileTransferInstance/background_red.png); + border-left:25;padding-top:-30; + border-top:28; + border-right:25; padding-right:-28; + border-bottom:28;padding-bottom:-30; +} + +QLabel { + color:white; +} + +QPushButton { + margin:0; +} + +QProgressBar { + border: 2px solid black; + border-radius: 0px; + color: white; + background-color:white; +} + +QProgressBar::chunk { + background-color: black; + width: 20px; +} \ No newline at end of file diff --git a/ui/fileTransferInstance/yellow.css b/ui/fileTransferInstance/yellow.css new file mode 100644 index 000000000..f748c7975 --- /dev/null +++ b/ui/fileTransferInstance/yellow.css @@ -0,0 +1,27 @@ +QFrame { + border-image: url(:/ui/fileTransferInstance/background_yellow.png); + border-left:25;padding-top:-30; + border-top:28; + border-right:25; padding-right:-28; + border-bottom:28;padding-bottom:-30; +} + +QLabel { + color:black; +} + +QPushButton { + margin:0; +} + +QProgressBar { + border: 2px solid black; + border-radius: 0px; + color: white; + background-color:white; +} + +QProgressBar::chunk { + background-color: black; + width: 20px; +} \ No newline at end of file From fdee08df3241e6edf13c97da2f996e0de2380673 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 7 Dec 2014 20:52:01 +0100 Subject: [PATCH 012/203] ui tweaks --- src/chatlog/content/filetransferwidget.cpp | 17 +++++++++++------ src/chatlog/content/filetransferwidget.ui | 22 ++++++++++++++++++++-- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index 33fcc505e..f9578b8c8 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -42,8 +42,8 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) ui->filenameLabel->setText(file.fileName); ui->progressBar->setValue(0); ui->fileSizeLabel->setText(getHumanReadableSize(file.filesize)); - ui->progressLabel->setText("0%"); - ui->etaLabel->setText("--:--"); + ui->progressLabel->setText("0kiB/s"); + ui->etaLabel->setText("-:-"); setStyleSheet(Style::getStylesheet(":/ui/fileTransferInstance/grey.css")); Style::repolish(this); @@ -267,10 +267,15 @@ void FileTransferWidget::handleButton(QPushButton *btn) void FileTransferWidget::showPreview(const QString &filename) { - //QPixmap pmap = QPixmap(filename).scaled(QSize(ui->previewLabel->maximumWidth(), maximumHeight()), Qt::KeepAspectRatio, Qt::SmoothTransformation); - QPixmap pmap = QPixmap(filename).scaledToWidth(ui->previewLabel->maximumWidth(), Qt::SmoothTransformation); - ui->previewLabel->setPixmap(pmap); - ui->previewLabel->show(); + static const QStringList previewExtensions = { "png", "jpeg", "jpg", "gif" }; + + if(previewExtensions.contains(QFileInfo(filename).suffix())) + { + //QPixmap pmap = QPixmap(filename).scaled(QSize(ui->previewLabel->maximumWidth(), maximumHeight()), Qt::KeepAspectRatio, Qt::SmoothTransformation); + QPixmap pmap = QPixmap(filename).scaledToWidth(ui->previewLabel->maximumWidth(), Qt::SmoothTransformation); + ui->previewLabel->setPixmap(pmap); + ui->previewLabel->show(); + } } void FileTransferWidget::on_topButton_clicked() diff --git a/src/chatlog/content/filetransferwidget.ui b/src/chatlog/content/filetransferwidget.ui index 7992bce16..aaad82199 100644 --- a/src/chatlog/content/filetransferwidget.ui +++ b/src/chatlog/content/filetransferwidget.ui @@ -71,7 +71,7 @@ - + 0 0 @@ -101,6 +101,12 @@ + + + 0 + 0 + + 10Mb @@ -111,8 +117,14 @@ + + + 0 + 0 + + - 24% + 0kb/s Qt::AlignCenter @@ -121,6 +133,12 @@ + + + 0 + 0 + + ETA:10:10 From a1cfbeffcbe9ad523caed6c8e7e038ecf997ccc1 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 8 Dec 2014 22:08:23 +0100 Subject: [PATCH 013/203] removed ChatLine vAlignCol --- src/chatlog/chatline.cpp | 9 +++++++-- src/chatlog/chatline.h | 4 +--- src/chatlog/chatlog.cpp | 12 ++++++------ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index e26969d7f..7298e65e5 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -155,9 +155,13 @@ void ChatLine::layout(qreal w, QPointF scenePos) qreal leftover = qMax(0.0, width - fixedWidth); + qreal maxVOffset = 0.0; qreal xOffset = 0.0; + for(int i = 0; i < content.size(); ++i) { + maxVOffset = qMax(maxVOffset, content[i]->firstLineVOffset()); + // calculate the effective width of the current column qreal width; if(format[i].policy == ColumnFormat::FixedSize) @@ -193,8 +197,9 @@ void ChatLine::layout(qreal w, QPointF scenePos) // calculate vertical alignment // vertical alignment may depend on width, so we do it in a second pass qreal yOffset = 0.0; - if(format[i].vAlignCol >= 0 && format[i].vAlignCol < content.size()) - yOffset = content[format[i].vAlignCol]->firstLineVOffset() - content[i]->firstLineVOffset(); + + if(content[i]->firstLineVOffset() > 0.0) + yOffset = maxVOffset - content[i]->firstLineVOffset(); // reposition content[i]->setPos(content[i]->pos().x(), content[i]->pos().y() + yOffset); diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index 78e225ed3..bebc5d8cf 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -38,16 +38,14 @@ struct ColumnFormat }; ColumnFormat() {} - ColumnFormat(qreal s, Policy p, int valign = -1, Align halign = Left) + ColumnFormat(qreal s, Policy p, Align halign = Left) : size(s) , policy(p) - , vAlignCol(valign) , hAlign(halign) {} qreal size = 1.0; Policy policy = VariableSize; - int vAlignCol = -1; Align hAlign = Left; }; diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 9fdcc4621..d844c30b3 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -76,9 +76,9 @@ ChatLog::~ChatLog() ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString &msg, bool self) { 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(sender, self ? Style::getFont(Style::MediumBold) : Style::getFont(Style::Medium), true), ColumnFormat(75.0, ColumnFormat::FixedSize, 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)); + line->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(50.0, ColumnFormat::FixedSize, ColumnFormat::Right)); insertChatline(line); return line; @@ -95,9 +95,9 @@ ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString& msg, ChatMessage *ChatLog::addSystemMessage(const QString &msg, const QDateTime& timestamp) { 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 Image(QSizeF(16, 16), ":/ui/chatArea/info.png"), ColumnFormat(75.0, ColumnFormat::FixedSize, 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)); + line->addColumn(new Text(timestamp.toString("hh:mm")), ColumnFormat(50.0, ColumnFormat::FixedSize, ColumnFormat::Right)); insertChatline(line); return line; @@ -106,9 +106,9 @@ ChatMessage *ChatLog::addSystemMessage(const QString &msg, const QDateTime& time ChatMessage *ChatLog::addFileTransferMessage(const QString &sender, const ToxFile &file, const QDateTime& timestamp, bool self) { ChatMessage* line = new ChatMessage(scene, QString()); - 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(sender, self ? Style::getFont(Style::MediumBold) : Style::getFont(Style::Medium), true), ColumnFormat(75.0, ColumnFormat::FixedSize, ColumnFormat::Right)); line->addColumn(new ChatLineContentProxy(new FileTransferWidget(0, file)), ColumnFormat(1.0, ColumnFormat::VariableSize)); - line->addColumn(new Text(timestamp.toString("hh:mm")), ColumnFormat(50.0, ColumnFormat::FixedSize, 1, ColumnFormat::Right)); + line->addColumn(new Text(timestamp.toString("hh:mm")), ColumnFormat(50.0, ColumnFormat::FixedSize, ColumnFormat::Right)); insertChatline(line); return line; From c91b7cb03c746b4e3a94afc7217b3b08afdef678 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 9 Dec 2014 13:11:42 +0100 Subject: [PATCH 014/203] don't depend on valid cursur --- src/chatlog/content/text.cpp | 16 +++++++++++++++- src/chatlog/content/text.h | 31 +++++++++++++++++-------------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 81a613511..c3510a346 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -78,7 +78,10 @@ void Text::selectionMouseMove(QPointF scenePos) ensureIntegrity(); int cur = cursorFromPos(scenePos); if(cur >= 0) + { cursor.setPosition(cur, QTextCursor::KeepAnchor); + selectedText = cursor.selectedText(); + } update(); } @@ -89,12 +92,17 @@ void Text::selectionStarted(QPointF scenePos) int cur = cursorFromPos(scenePos); if(cur >= 0) cursor.setPosition(cur); + + selectedText.clear(); + selectedText.squeeze(); } void Text::selectionCleared() { ensureIntegrity(); cursor.setPosition(0); + selectedText.clear(); + selectedText.squeeze(); freeResources(); update(); @@ -104,6 +112,7 @@ void Text::selectAll() { ensureIntegrity(); cursor.select(QTextCursor::Document); + selectedText = text; update(); } @@ -118,7 +127,7 @@ bool Text::isOverSelection(QPointF scenePos) const QString Text::getSelectedText() const { - return cursor.selectedText(); + return selectedText; } QRectF Text::boundingSceneRect() const @@ -181,6 +190,11 @@ void Text::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QDesktopServices::openUrl(anchor); } +QString Text::getText() const +{ + return text; +} + void Text::ensureIntegrity() { if(!doc) diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index a2a83096e..d218e72ae 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -32,24 +32,26 @@ public: void setText(const QString& txt); - virtual void setWidth(qreal width); + virtual void setWidth(qreal width) override; - virtual void selectionMouseMove(QPointF scenePos); - virtual void selectionStarted(QPointF scenePos); - virtual void selectionCleared(); - virtual void selectAll(); - virtual bool isOverSelection(QPointF scenePos) const; - virtual QString getSelectedText() const; + virtual void selectionMouseMove(QPointF scenePos) override; + virtual void selectionStarted(QPointF scenePos) override; + virtual void selectionCleared() override; + virtual void selectAll() override; + virtual bool isOverSelection(QPointF scenePos) const override; + virtual QString getSelectedText() const override; - virtual QRectF boundingSceneRect() const; - virtual QRectF boundingRect() const; - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + virtual QRectF boundingSceneRect() const override; + virtual QRectF boundingRect() const override; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; - virtual void visibilityChanged(bool isVisible); + virtual void visibilityChanged(bool isVisible) override; - virtual qreal firstLineVOffset() const; - virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); - virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual qreal firstLineVOffset() const override; + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override; + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; + + virtual QString getText() const override; protected: // dynamic resource management @@ -63,6 +65,7 @@ private: CustomTextDocument* doc = nullptr; QString text; QString elidedText; + QString selectedText; QSizeF size; bool isVisible = false; bool elide = false; From 661a8c4da4ce471959c0c1e130f588c2b5a5d577 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 9 Dec 2014 13:17:08 +0100 Subject: [PATCH 015/203] revisited selection --- src/chatlog/chatlinecontent.cpp | 5 ++ src/chatlog/chatlinecontent.h | 2 + src/chatlog/chatlog.cpp | 138 ++++++++++++++++++-------------- src/chatlog/chatlog.h | 16 +++- 4 files changed, 96 insertions(+), 65 deletions(-) diff --git a/src/chatlog/chatlinecontent.cpp b/src/chatlog/chatlinecontent.cpp index 0881a8b87..f6ba3b0ba 100644 --- a/src/chatlog/chatlinecontent.cpp +++ b/src/chatlog/chatlinecontent.cpp @@ -84,3 +84,8 @@ void ChatLineContent::visibilityChanged(bool) { } + +QString ChatLineContent::getText() const +{ + return QString(); +} diff --git a/src/chatlog/chatlinecontent.h b/src/chatlog/chatlinecontent.h index bd2017653..da1249923 100644 --- a/src/chatlog/chatlinecontent.h +++ b/src/chatlog/chatlinecontent.h @@ -44,6 +44,8 @@ public: virtual bool isOverSelection(QPointF scenePos) const; virtual QString getSelectedText() const; + virtual QString getText() const; + virtual qreal firstLineVOffset() const; virtual QRectF boundingSceneRect() const = 0; diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index d844c30b3..6930e7cec 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -57,6 +57,12 @@ ChatLog::ChatLog(QWidget* parent) setViewportUpdateMode(SmartViewportUpdate); //setRenderHint(QPainter::TextAntialiasing); + selGraphItem = new QGraphicsRectItem(); + selGraphItem->setZValue(-10.0); //behind all items + selGraphItem->setBrush(QBrush(QColor(166,225,255))); + + scene->addItem(selGraphItem); + // copy action copyAction = new QAction(this); copyAction->setShortcut(QKeySequence::Copy); @@ -116,14 +122,17 @@ ChatMessage *ChatLog::addFileTransferMessage(const QString &sender, const ToxFil void ChatLog::clearSelection() { - if(selStartRow >= 0) - for(int r = qMin(selStartRow, selLastRow); r <= qMax(selLastRow, selStartRow) && r < lines.size(); ++r) - lines[r]->selectionCleared(); + for(int i=selFirstRow; i<=selLastRow && i= 0; ++i) + lines[i]->selectionCleared(); - selStartRow = -1; - selStartCol = -1; + selGraphItem->hide(); + + selFirstRow = -1; selLastRow = -1; - selLastCol = -1; + selClickedCol = -1; + selClickedRow = -1; + + selectionMode = None; } QRect ChatLog::getVisibleRect() const @@ -229,9 +238,6 @@ void ChatLog::mousePressEvent(QMouseEvent* ev) void ChatLog::mouseReleaseEvent(QMouseEvent* ev) { QGraphicsView::mouseReleaseEvent(ev); - - if(ev->button() == Qt::LeftButton) - selecting = false; } void ChatLog::mouseMoveEvent(QMouseEvent* ev) @@ -242,21 +248,21 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) if(ev->buttons() & Qt::LeftButton) { - if(!selecting && (clickPos - ev->pos()).manhattanLength() > QApplication::startDragDistance()) + if(selectionMode == None && (clickPos - ev->pos()).manhattanLength() > QApplication::startDragDistance()) { QPointF sceneClickPos = mapToScene(clickPos.toPoint()); ChatLineContent* content = getContentFromPos(sceneClickPos); if(content) { - selStartRow = content->getRow(); - selStartCol = content->getColumn(); - selLastRow = selStartRow; - selLastCol = selStartCol; + selClickedRow = content->getRow(); + selClickedCol = content->getColumn(); + selFirstRow = content->getRow(); + selLastRow = content->getRow(); content->selectionStarted(sceneClickPos); - selecting = true; + selectionMode = Precise; // ungrab mouse grabber if(scene->mouseGrabberItem()) @@ -265,7 +271,7 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) } } - if(selecting && ev->pos() != lastPos) + if(selectionMode != None && ev->pos() != lastPos) { lastPos = ev->pos(); @@ -273,47 +279,35 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) if(content) { - // TODO: turn this into a sane algo. int row = content->getRow(); int col = content->getColumn(); - int firstRow = selStartRow; - // selection - for(int r = qMin(firstRow, row + 1); r < qMax(row, firstRow); r++) - lines[r]->selectAll(); + if(row >= selClickedRow) + selLastRow = row; - if(row != selStartRow) - for(int c = 0; c < col; c++) - lines[selStartRow]->selectAll(); + if(row <= selClickedRow) + selFirstRow = row; + + if(row == selClickedRow && col == selClickedCol) + { + selectionMode = Precise; - if(row == selStartRow) content->selectionMouseMove(scenePos); + selGraphItem->hide(); + } else { - lines[row]->selectAll(); - selStartCol = 0; - selLastCol = lines[row]->getColumnCount(); + selectionMode = Multi; + + lines[selClickedRow]->selectionCleared(); + + QRectF selBBox; + selBBox = selBBox.united(lines[selFirstRow]->boundingSceneRect()); + selBBox = selBBox.united(lines[selLastRow]->boundingSceneRect()); + + selGraphItem->setRect(selBBox); + selGraphItem->show(); } - - // de-selection - if(row < selStartRow) - selLastRow = qMin(row, selLastRow); - else - selLastRow = qMax(row, selLastRow); - - if(col < selStartCol) - selLastCol = qMin(col, selLastCol); - else - selLastCol = qMax(col, selLastCol); - - for(int r = qMin(row, selLastRow); r < qMax(row, selLastRow + 1) && r < lines.size(); ++r) - if(r != row) - lines[r]->selectionCleared(); - - if(row == selStartRow) - for(int c = col + 1; c < lines[row]->getColumnCount() && c < selLastCol; ++c) - lines[row]->selectionCleared(c); - } } } @@ -330,17 +324,25 @@ ChatLineContent* ChatLog::getContentFromPos(QPointF scenePos) const bool ChatLog::isOverSelection(QPointF scenePos) { - ChatLineContent* content = getContentFromPos(scenePos); + if(selectionMode == Precise) + { + ChatLineContent* content = getContentFromPos(scenePos); - if(content) - return content->isOverSelection(scenePos); + if(content) + return content->isOverSelection(scenePos); + } + else if(selectionMode == Multi) + { + if(selGraphItem->rect().contains(scenePos)) + return true; + } return false; } int ChatLog::useableWidth() { - return width() - verticalScrollBar()->sizeHint().width(); + return width() - verticalScrollBar()->sizeHint().width() - 10.0; } void ChatLog::reposition(int start, int end) @@ -411,19 +413,33 @@ void ChatLog::scrollToBottom() QString ChatLog::getSelectedText() const { - QString ret; + if(selectionMode == Precise) + { + return lines[selClickedRow]->content[selClickedCol]->getSelectedText(); + } + else if(selectionMode == Multi) + { + // build a nicely formatted message + QString out; - const int rowStart = qMin(selStartRow, selLastRow); - const int rowLast = qMax(selStartRow, selLastRow); + QString lastSender; + for(int i=selFirstRow; i<=selLastRow && i>=0 && icontent[0]->getText() && !lines[i]->content[0]->getText().isEmpty()) + { + //author changed + out += lines[i]->content[0]->getText() + ":\n"; + lastSender = lines[i]->content[0]->getText(); + } - const int colStart = qMin(selStartCol, selLastCol); - const int colLast = qMax(selStartCol, selLastCol); + out += lines[i]->content[1]->getText(); + out += "\n\n"; + } - for(int r = rowStart; r <= rowLast && r < lines.size(); ++r) - for(int c = colStart; c <= colLast && c < lines[r]->getColumnCount(); ++c) - ret.append(lines[r]->content[c]->getSelectedText() + '\n'); + return out; + } - return ret; + return QString(); } void ChatLog::showContextMenu(const QPoint& globalPos, const QPointF& scenePos) diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 3a0e0baae..f78c94d49 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -21,6 +21,7 @@ #include class QGraphicsScene; +class QGraphicsRectItem; class ChatLine; class ChatLineContent; class ChatMessage; @@ -72,6 +73,12 @@ protected: virtual void resizeEvent(QResizeEvent *ev); private: + enum SelectionMode { + None, + Precise, + Multi, + }; + QGraphicsScene* scene = nullptr; QList lines; QList visibleLines; @@ -81,13 +88,14 @@ private: int insertStartIndex = -1; // selection - int selStartRow = -1; - int selStartCol = -1; + int selClickedRow = -1; + int selClickedCol = -1; + int selFirstRow = -1; int selLastRow = -1; - int selLastCol = -1; - bool selecting = false; + SelectionMode selectionMode = None; QPointF clickPos; QPointF lastPos; + QGraphicsRectItem* selGraphItem = nullptr; // actions QAction* copyAction = nullptr; From 2b20a23c3d6e7881ee42bfe30f50eff699072968 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 9 Dec 2014 19:24:01 +0100 Subject: [PATCH 016/203] changed color of selGraphItem --- src/chatlog/chatlog.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 6930e7cec..e004a1569 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -57,11 +57,9 @@ ChatLog::ChatLog(QWidget* parent) setViewportUpdateMode(SmartViewportUpdate); //setRenderHint(QPainter::TextAntialiasing); - selGraphItem = new QGraphicsRectItem(); + const QColor selGraphColor = QColor(166,225,255); + selGraphItem = scene->addRect(0,0,0,0,selGraphColor.darker(120),selGraphColor); selGraphItem->setZValue(-10.0); //behind all items - selGraphItem->setBrush(QBrush(QColor(166,225,255))); - - scene->addItem(selGraphItem); // copy action copyAction = new QAction(this); From 0f2a339a98b80b0f5674c925bc0aecfcc908a31f Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 9 Dec 2014 21:47:25 +0100 Subject: [PATCH 017/203] margins, update selection rect during resize --- src/chatlog/chatlog.cpp | 38 ++++++++++++++++++++++++++------------ src/chatlog/chatlog.h | 6 +++++- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index e004a1569..8f641d535 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -123,14 +123,14 @@ void ChatLog::clearSelection() for(int i=selFirstRow; i<=selLastRow && i= 0; ++i) lines[i]->selectionCleared(); - selGraphItem->hide(); - selFirstRow = -1; selLastRow = -1; selClickedCol = -1; selClickedRow = -1; selectionMode = None; + + updateMultiSelectionRect(); } QRect ChatLog::getVisibleRect() const @@ -140,7 +140,7 @@ QRect ChatLog::getVisibleRect() const void ChatLog::updateSceneRect() { - setSceneRect(QRectF(0, 0, width(), lines.empty() ? 0.0 : lines.last()->boundingSceneRect().bottom())); + setSceneRect(QRectF(-margins.left(), -margins.top(), useableWidth(), (lines.empty() ? 0.0 : lines.last()->boundingSceneRect().bottom()) + margins.bottom() + margins.top())); } bool ChatLog::layout(int start, int end, qreal width) @@ -160,7 +160,7 @@ bool ChatLog::layout(int start, int end, qreal width) ChatLine* l = lines[i]; qreal oldHeight = l->boundingSceneRect().height(); - l->layout(width, QPointF(0, h)); + l->layout(width, QPointF(0.0, h)); if(oldHeight != l->boundingSceneRect().height()) needsReposition = true; @@ -299,12 +299,7 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) lines[selClickedRow]->selectionCleared(); - QRectF selBBox; - selBBox = selBBox.united(lines[selFirstRow]->boundingSceneRect()); - selBBox = selBBox.united(lines[selLastRow]->boundingSceneRect()); - - selGraphItem->setRect(selBBox); - selGraphItem->show(); + updateMultiSelectionRect(); } } } @@ -338,9 +333,9 @@ bool ChatLog::isOverSelection(QPointF scenePos) return false; } -int ChatLog::useableWidth() +qreal ChatLog::useableWidth() { - return width() - verticalScrollBar()->sizeHint().width() - 10.0; + return width() - verticalScrollBar()->sizeHint().width() - margins.right() - margins.left(); } void ChatLog::reposition(int start, int end) @@ -550,4 +545,23 @@ void ChatLog::resizeEvent(QResizeEvent* ev) if(stb) scrollToBottom(); + + updateMultiSelectionRect(); +} + +void ChatLog::updateMultiSelectionRect() +{ + if(selectionMode == Multi && selFirstRow >= 0 && selLastRow >= 0) + { + QRectF selBBox; + selBBox = selBBox.united(lines[selFirstRow]->boundingSceneRect()); + selBBox = selBBox.united(lines[selLastRow]->boundingSceneRect()); + + selGraphItem->setRect(selBBox); + selGraphItem->show(); + } + else + { + selGraphItem->hide(); + } } diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index f78c94d49..64b1ef549 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -19,6 +19,7 @@ #include #include +#include class QGraphicsScene; class QGraphicsRectItem; @@ -55,7 +56,7 @@ protected: bool isOverSelection(QPointF scenePos); bool stickToBottom(); - int useableWidth(); + qreal useableWidth(); void reposition(int start, int end); void repositionDownTo(int start, qreal end); @@ -72,6 +73,8 @@ protected: virtual void scrollContentsBy(int dx, int dy); virtual void resizeEvent(QResizeEvent *ev); + void updateMultiSelectionRect(); + private: enum SelectionMode { None, @@ -101,6 +104,7 @@ private: QAction* copyAction = nullptr; // layout + QMarginsF margins = QMarginsF(10.0,10.0,10.0,10.0); qreal lineSpacing = 10.0f; }; From 5ae506fe3bfcad367744d2f4766e15a1a9969682 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 10 Dec 2014 10:35:56 +0100 Subject: [PATCH 018/203] filetransferwidget: added open (browse?) button, fixed layout --- res.qrc | 29 +++---- src/chatlog/chatline.cpp | 2 +- src/chatlog/content/filetransferwidget.cpp | 16 +++- src/chatlog/content/filetransferwidget.ui | 35 +++++++-- src/chatlog/content/text.cpp | 2 +- ui/fileTransferInstance/browse.svg | 86 +++++++++++++++++++++ ui/fileTransferInstance/browse_path.png | Bin 0 -> 462 bytes ui/fileTransferInstance/green.css | 8 +- ui/fileTransferInstance/grey.css | 8 +- ui/fileTransferInstance/red.css | 8 +- ui/fileTransferInstance/yellow.css | 8 +- 11 files changed, 161 insertions(+), 41 deletions(-) create mode 100644 ui/fileTransferInstance/browse.svg create mode 100644 ui/fileTransferInstance/browse_path.png diff --git a/res.qrc b/res.qrc index 6c35d1e48..569965528 100644 --- a/res.qrc +++ b/res.qrc @@ -42,8 +42,8 @@ ui/callButton/callButtonYellowPressed.png ui/chatArea/chatArea.css ui/chatArea/innerStyle.css - ui/chatArea/spinner.png - ui/chatArea/info.png + ui/chatArea/spinner.png + ui/chatArea/info.png ui/chatArea/scrollBarDownArrow.png ui/chatArea/scrollBarDownArrowHover.png ui/chatArea/scrollBarDownArrowPressed.png @@ -94,18 +94,18 @@ translations/fr.qm translations/ru.qm ui/fileTransferWidget/fileTransferWidget.css - ui/fileTransferInstance/red.css - ui/fileTransferInstance/green.css - ui/fileTransferInstance/grey.css - ui/fileTransferInstance/yellow.css - ui/fileTransferInstance/background_red.png - ui/fileTransferInstance/background_yellow.png - ui/fileTransferInstance/background_green.png - ui/fileTransferInstance/background_grey.png - ui/fileTransferInstance/pause_2x.png - ui/fileTransferInstance/no_2x.png - ui/fileTransferInstance/yes_2x.png - ui/fileTransferInstance/arrow_white_2x.png + ui/fileTransferInstance/red.css + ui/fileTransferInstance/green.css + ui/fileTransferInstance/grey.css + ui/fileTransferInstance/yellow.css + ui/fileTransferInstance/background_red.png + ui/fileTransferInstance/background_yellow.png + ui/fileTransferInstance/background_green.png + ui/fileTransferInstance/background_grey.png + ui/fileTransferInstance/pause_2x.png + ui/fileTransferInstance/no_2x.png + ui/fileTransferInstance/yes_2x.png + ui/fileTransferInstance/arrow_white_2x.png ui/statusButton/dot_away.png ui/statusButton/dot_busy.png ui/statusButton/dot_idle.png @@ -229,5 +229,6 @@ smileys/cylgom/yawn.png translations/bg.qm translations/sv.qm + ui/fileTransferInstance/browse_path.png diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index 7298e65e5..ac404f3bc 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -198,7 +198,7 @@ void ChatLine::layout(qreal w, QPointF scenePos) // vertical alignment may depend on width, so we do it in a second pass qreal yOffset = 0.0; - if(content[i]->firstLineVOffset() > 0.0) + //if(content[i]->firstLineVOffset() > 0.0) yOffset = maxVOffset - content[i]->firstLineVOffset(); // reposition diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index f9578b8c8..a2ff659f0 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) @@ -60,7 +61,7 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) if(fileInfo.direction == ToxFile::SENDING) showPreview(fileInfo.filePath); - setFixedHeight(85); + setFixedHeight(69); } FileTransferWidget::~FileTransferWidget() @@ -164,6 +165,10 @@ void FileTransferWidget::onFileTransferFinished(ToxFile file) setupButtons(); hideWidgets(); + ui->bottomButton->show(); + ui->bottomButton->setIcon(QIcon(":/ui/fileTransferInstance/browse_path.png")); + ui->bottomButton->setObjectName("browse"); + // preview if(fileInfo.direction == ToxFile::RECEIVING) showPreview(fileInfo.filePath); @@ -184,7 +189,9 @@ QString FileTransferWidget::getHumanReadableSize(qint64 size) void FileTransferWidget::hideWidgets() { - ui->buttonWidget->hide(); + ui->topButton->hide(); + ui->bottomButton->hide(); + //ui->buttonWidget->hide(); ui->progressBar->hide(); ui->progressLabel->hide(); ui->etaLabel->hide(); @@ -263,6 +270,11 @@ void FileTransferWidget::handleButton(QPushButton *btn) Core::getInstance()->acceptFileRecvRequest(fileInfo.friendId, fileInfo.fileNum, path); } } + + if(btn->objectName() == "browse") + { + QDesktopServices::openUrl("file://" + fileInfo.filePath); + } } void FileTransferWidget::showPreview(const QString &filename) diff --git a/src/chatlog/content/filetransferwidget.ui b/src/chatlog/content/filetransferwidget.ui index aaad82199..b3d75d77f 100644 --- a/src/chatlog/content/filetransferwidget.ui +++ b/src/chatlog/content/filetransferwidget.ui @@ -14,6 +14,21 @@ Form + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + @@ -36,10 +51,10 @@ - 0 + 6 - 0 + 6 @@ -61,17 +76,23 @@ - + + + 6 + 6 + + 6 + 6 - + 0 0 @@ -102,7 +123,7 @@ - + 0 0 @@ -118,7 +139,7 @@ - + 0 0 @@ -134,7 +155,7 @@ - + 0 0 diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index c3510a346..d8e73ac06 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -39,7 +39,7 @@ Text::Text(const QString& txt, QFont font, bool enableElide) ensureIntegrity(); freeResources(); - //setCacheMode(QGraphicsItem::DeviceCoordinateCache); + setCacheMode(QGraphicsItem::DeviceCoordinateCache); } Text::~Text() diff --git a/ui/fileTransferInstance/browse.svg b/ui/fileTransferInstance/browse.svg new file mode 100644 index 000000000..e545118aa --- /dev/null +++ b/ui/fileTransferInstance/browse.svg @@ -0,0 +1,86 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/ui/fileTransferInstance/browse_path.png b/ui/fileTransferInstance/browse_path.png new file mode 100644 index 0000000000000000000000000000000000000000..5fe4251a61cced23c94f46cc7f40e85a5be13585 GIT binary patch literal 462 zcmV;<0WtoGP)X1^@s6FWx?200004b3#c}2nYxW zd^!M!40?wSrUy- zq9W0`0val%WPLR{63IqMVmp;k$fGc_^3NP|#!SSoI`e+~p7YK*IZ#vTZ*^PkuG^an z=u$WQuO0PA+mPPExKjseUt5r$>R}1wO@GvZDxb&zO#)-Z=LoP;toMPvVtpAA=bsrQ z1)X{~$!eY6t_Iv%y-h%szr8I`t==AW85rz{uSdjfN&OA*b~Z<4hUyTo*b)9m;>u1W zOhO$|r&Cv2ohUQR9$%dS{sPy)DR8fDsr|VIl@qDs>SLmIx6O&xfZjxIzL@qy<$``S z%x8nltZNK9smLF<1zG~061km-IBNwI5m&$*aP= Date: Wed, 10 Dec 2014 10:41:22 +0100 Subject: [PATCH 019/203] chatline: fixed bbox height calculation --- src/chatlog/chatline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index ac404f3bc..bffbbb1af 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -98,7 +98,7 @@ void ChatLine::updateBBox() bbox.setWidth(width); for(ChatLineContent* c : content) - bbox.setHeight(qMax(c->sceneBoundingRect().height(), bbox.height())); + bbox.setHeight(qMax(c->sceneBoundingRect().bottom() - pos.y(), bbox.height())); } QRectF ChatLine::boundingSceneRect() const From ba24da31847fa0eefb1bdb87586564f176c8bff5 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 10 Dec 2014 10:57:09 +0100 Subject: [PATCH 020/203] filetransferwidget.ui: reverted margins. chatlinecontentproxy: calculate firstLineVOffset --- src/chatlog/chatlinecontentproxy.cpp | 6 ++++++ src/chatlog/chatlinecontentproxy.h | 2 ++ src/chatlog/content/filetransferwidget.cpp | 2 +- src/chatlog/content/filetransferwidget.ui | 15 --------------- 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/chatlog/chatlinecontentproxy.cpp b/src/chatlog/chatlinecontentproxy.cpp index 8ac308ae1..a2d2b7817 100644 --- a/src/chatlog/chatlinecontentproxy.cpp +++ b/src/chatlog/chatlinecontentproxy.cpp @@ -15,6 +15,7 @@ */ #include "chatlinecontentproxy.h" +#include #include #include @@ -39,6 +40,11 @@ void ChatLineContentProxy::paint(QPainter *painter, const QStyleOptionGraphicsIt proxy->paint(painter, option, widget); } +qreal ChatLineContentProxy::firstLineVOffset() const +{ + return proxy->widget()->layout()->contentsMargins().top() + proxy->widget()->layout()->contentsMargins().bottom(); +} + void ChatLineContentProxy::setWidth(qreal width) { proxy->widget()->setFixedWidth(qMax(width,0.0)); diff --git a/src/chatlog/chatlinecontentproxy.h b/src/chatlog/chatlinecontentproxy.h index bf225a17c..3a0f9874b 100644 --- a/src/chatlog/chatlinecontentproxy.h +++ b/src/chatlog/chatlinecontentproxy.h @@ -29,9 +29,11 @@ public: virtual QRectF boundingSceneRect() const; virtual void setWidth(qreal width); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + virtual qreal firstLineVOffset() const; private: QGraphicsProxyWidget* proxy; + }; #endif // CHATLINECONTENTPROXY_H diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index a2ff659f0..83f7e11a1 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -61,7 +61,7 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) if(fileInfo.direction == ToxFile::SENDING) showPreview(fileInfo.filePath); - setFixedHeight(69); + setFixedHeight(85); } FileTransferWidget::~FileTransferWidget() diff --git a/src/chatlog/content/filetransferwidget.ui b/src/chatlog/content/filetransferwidget.ui index b3d75d77f..e43b8c091 100644 --- a/src/chatlog/content/filetransferwidget.ui +++ b/src/chatlog/content/filetransferwidget.ui @@ -14,21 +14,6 @@ Form - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - From 26718f7147afdc8006a0804d67e1f5c4d939e7fd Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 10 Dec 2014 10:59:10 +0100 Subject: [PATCH 021/203] cleanup --- src/chatlog/chatline.cpp | 3 +-- src/chatlog/content/filetransferwidget.cpp | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index bffbbb1af..c051b455d 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -198,8 +198,7 @@ void ChatLine::layout(qreal w, QPointF scenePos) // vertical alignment may depend on width, so we do it in a second pass qreal yOffset = 0.0; - //if(content[i]->firstLineVOffset() > 0.0) - yOffset = maxVOffset - content[i]->firstLineVOffset(); + yOffset = maxVOffset - content[i]->firstLineVOffset(); // reposition content[i]->setPos(content[i]->pos().x(), content[i]->pos().y() + yOffset); diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index 83f7e11a1..6d24b0378 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -191,7 +191,6 @@ void FileTransferWidget::hideWidgets() { ui->topButton->hide(); ui->bottomButton->hide(); - //ui->buttonWidget->hide(); ui->progressBar->hide(); ui->progressLabel->hide(); ui->etaLabel->hide(); From 2003f7c5aacd8a327178c1830a77a812e4e9cf5a Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 10 Dec 2014 16:35:07 +0100 Subject: [PATCH 022/203] Text: use ascent rather than height --- src/chatlog/content/text.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index d8e73ac06..f53b20d83 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -223,7 +223,7 @@ void Text::ensureIntegrity() doc->documentLayout()->update(); if(doc->firstBlock().layout()->lineCount() > 0) - vOffset = doc->firstBlock().layout()->lineAt(0).height(); + vOffset = doc->firstBlock().layout()->lineAt(0).ascent(); if(size != idealSize()) { From 0692c484f0a8d1dfb2fd0569eb6dd36b24288f4f Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 10 Dec 2014 16:42:12 +0100 Subject: [PATCH 023/203] adjusted Image, Spinner, ChatLineContentProxy vOffset --- src/chatlog/chatlinecontentproxy.cpp | 2 +- src/chatlog/content/image.cpp | 2 +- src/chatlog/content/spinner.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/chatlog/chatlinecontentproxy.cpp b/src/chatlog/chatlinecontentproxy.cpp index a2d2b7817..72441cacc 100644 --- a/src/chatlog/chatlinecontentproxy.cpp +++ b/src/chatlog/chatlinecontentproxy.cpp @@ -42,7 +42,7 @@ void ChatLineContentProxy::paint(QPainter *painter, const QStyleOptionGraphicsIt qreal ChatLineContentProxy::firstLineVOffset() const { - return proxy->widget()->layout()->contentsMargins().top() + proxy->widget()->layout()->contentsMargins().bottom(); + return proxy->widget()->layout()->contentsMargins().top(); } void ChatLineContentProxy::setWidth(qreal width) diff --git a/src/chatlog/content/image.cpp b/src/chatlog/content/image.cpp index 79cab6df0..3885d7281 100644 --- a/src/chatlog/content/image.cpp +++ b/src/chatlog/content/image.cpp @@ -36,7 +36,7 @@ QRectF Image::boundingSceneRect() const qreal Image::firstLineVOffset() const { - return size.height() / 4.0; + return 0.0; } void Image::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) diff --git a/src/chatlog/content/spinner.cpp b/src/chatlog/content/spinner.cpp index 554e6a5bc..642a92bed 100644 --- a/src/chatlog/content/spinner.cpp +++ b/src/chatlog/content/spinner.cpp @@ -72,7 +72,7 @@ void Spinner::visibilityChanged(bool visible) qreal Spinner::firstLineVOffset() const { - return size.height() / 4.0; + return 0.0; } void Spinner::timeout() From fd7fe15e3133b0da184adbe54af91a67c384bb97 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 10 Dec 2014 16:45:12 +0100 Subject: [PATCH 024/203] renamed firstLineVOffset to getAscent --- src/chatlog/chatline.cpp | 4 ++-- src/chatlog/chatlinecontent.cpp | 2 +- src/chatlog/chatlinecontent.h | 2 +- src/chatlog/chatlinecontentproxy.cpp | 2 +- src/chatlog/chatlinecontentproxy.h | 2 +- src/chatlog/content/image.cpp | 2 +- src/chatlog/content/image.h | 2 +- src/chatlog/content/spinner.cpp | 2 +- src/chatlog/content/spinner.h | 2 +- src/chatlog/content/text.cpp | 2 +- src/chatlog/content/text.h | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index c051b455d..928dcb7ca 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -160,7 +160,7 @@ void ChatLine::layout(qreal w, QPointF scenePos) for(int i = 0; i < content.size(); ++i) { - maxVOffset = qMax(maxVOffset, content[i]->firstLineVOffset()); + maxVOffset = qMax(maxVOffset, content[i]->getAscent()); // calculate the effective width of the current column qreal width; @@ -198,7 +198,7 @@ void ChatLine::layout(qreal w, QPointF scenePos) // vertical alignment may depend on width, so we do it in a second pass qreal yOffset = 0.0; - yOffset = maxVOffset - content[i]->firstLineVOffset(); + yOffset = maxVOffset - content[i]->getAscent(); // reposition content[i]->setPos(content[i]->pos().x(), content[i]->pos().y() + yOffset); diff --git a/src/chatlog/chatlinecontent.cpp b/src/chatlog/chatlinecontent.cpp index f6ba3b0ba..0250b3674 100644 --- a/src/chatlog/chatlinecontent.cpp +++ b/src/chatlog/chatlinecontent.cpp @@ -75,7 +75,7 @@ QString ChatLineContent::getSelectedText() const return QString(); } -qreal ChatLineContent::firstLineVOffset() const +qreal ChatLineContent::getAscent() const { return 0.0; } diff --git a/src/chatlog/chatlinecontent.h b/src/chatlog/chatlinecontent.h index da1249923..4796ac511 100644 --- a/src/chatlog/chatlinecontent.h +++ b/src/chatlog/chatlinecontent.h @@ -46,7 +46,7 @@ public: virtual QString getText() const; - virtual qreal firstLineVOffset() const; + virtual qreal getAscent() const; virtual QRectF boundingSceneRect() const = 0; virtual QRectF boundingRect() const = 0; diff --git a/src/chatlog/chatlinecontentproxy.cpp b/src/chatlog/chatlinecontentproxy.cpp index 72441cacc..dc12b96ed 100644 --- a/src/chatlog/chatlinecontentproxy.cpp +++ b/src/chatlog/chatlinecontentproxy.cpp @@ -40,7 +40,7 @@ void ChatLineContentProxy::paint(QPainter *painter, const QStyleOptionGraphicsIt proxy->paint(painter, option, widget); } -qreal ChatLineContentProxy::firstLineVOffset() const +qreal ChatLineContentProxy::getAscent() const { return proxy->widget()->layout()->contentsMargins().top(); } diff --git a/src/chatlog/chatlinecontentproxy.h b/src/chatlog/chatlinecontentproxy.h index 3a0f9874b..d9686e96f 100644 --- a/src/chatlog/chatlinecontentproxy.h +++ b/src/chatlog/chatlinecontentproxy.h @@ -29,7 +29,7 @@ public: virtual QRectF boundingSceneRect() const; virtual void setWidth(qreal width); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - virtual qreal firstLineVOffset() const; + virtual qreal getAscent() const; private: QGraphicsProxyWidget* proxy; diff --git a/src/chatlog/content/image.cpp b/src/chatlog/content/image.cpp index 3885d7281..768a3418b 100644 --- a/src/chatlog/content/image.cpp +++ b/src/chatlog/content/image.cpp @@ -34,7 +34,7 @@ QRectF Image::boundingSceneRect() const return QRectF(scenePos(), size); } -qreal Image::firstLineVOffset() const +qreal Image::getAscent() const { return 0.0; } diff --git a/src/chatlog/content/image.h b/src/chatlog/content/image.h index ad84bd0fa..471596f6d 100644 --- a/src/chatlog/content/image.h +++ b/src/chatlog/content/image.h @@ -28,7 +28,7 @@ public: virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); virtual void setWidth(qreal width); virtual QRectF boundingSceneRect() const; - virtual qreal firstLineVOffset() const; + virtual qreal getAscent() const; private: QSizeF size; diff --git a/src/chatlog/content/spinner.cpp b/src/chatlog/content/spinner.cpp index 642a92bed..a07d933e2 100644 --- a/src/chatlog/content/spinner.cpp +++ b/src/chatlog/content/spinner.cpp @@ -70,7 +70,7 @@ void Spinner::visibilityChanged(bool visible) timer.stop(); } -qreal Spinner::firstLineVOffset() const +qreal Spinner::getAscent() const { return 0.0; } diff --git a/src/chatlog/content/spinner.h b/src/chatlog/content/spinner.h index c2553dd67..6ab2e4b07 100644 --- a/src/chatlog/content/spinner.h +++ b/src/chatlog/content/spinner.h @@ -33,7 +33,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; + virtual qreal getAscent() const; private slots: void timeout(); diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index f53b20d83..4b2e9e05c 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -170,7 +170,7 @@ void Text::visibilityChanged(bool visible) freeResources(); } -qreal Text::firstLineVOffset() const +qreal Text::getAscent() const { return vOffset; } diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index d218e72ae..4739abab2 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -47,7 +47,7 @@ public: virtual void visibilityChanged(bool isVisible) override; - virtual qreal firstLineVOffset() const override; + virtual qreal getAscent() const override; virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override; virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; From 170e2e6e2904182e6d9a3095c6acbb6bec68610c Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 10 Dec 2014 19:31:27 +0100 Subject: [PATCH 025/203] Text: selection use fuzzy hit --- src/chatlog/content/text.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 4b2e9e05c..118c8d25c 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -253,7 +253,7 @@ QSizeF Text::idealSize() int Text::cursorFromPos(QPointF scenePos) const { if(doc) - return doc->documentLayout()->hitTest(mapFromScene(scenePos), Qt::ExactHit); + return doc->documentLayout()->hitTest(mapFromScene(scenePos), Qt::FuzzyHit); return -1; } From 380d7b9a0702807b680a3379934cd485ea241d8e Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 10 Dec 2014 19:56:08 +0100 Subject: [PATCH 026/203] Text: detect anchors --- src/chatlog/content/text.cpp | 29 +++++++++++++++++++++++++++++ src/chatlog/content/text.h | 22 ++++++++++++---------- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 118c8d25c..032b85c8b 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include Text::Text(const QString& txt, QFont font, bool enableElide) @@ -52,6 +53,7 @@ void Text::setText(const QString& txt) text = txt; text.replace("\n", "
"); + detectAnchors(); ensureIntegrity(); freeResources(); } @@ -257,3 +259,30 @@ int Text::cursorFromPos(QPointF scenePos) const return -1; } + +void Text::detectAnchors() +{ + // detect urls + QRegExp exp("(?:\\b)(www\\.|http[s]?:\\/\\/|ftp:\\/\\/|tox:\\/\\/|tox:)\\S+"); + int offset = 0; + while ((offset = exp.indexIn(text, offset)) != -1) + { + QString url = exp.cap(); + + // If there's a trailing " it's a HTML attribute, e.g. a smiley img's title=":tox:" + if (url == "tox:\"") + { + offset += url.length(); + continue; + } + + // add scheme if not specified + if (exp.cap(1) == "www.") + url.prepend("http://"); + + QString htmledUrl = QString("%1").arg(url); + text.replace(offset, exp.cap().length(), htmledUrl); + + offset += htmledUrl.length(); + } +} diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index 4739abab2..61b5ee866 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -1,13 +1,3 @@ -#ifndef TEXT_H -#define TEXT_H - -#include "../chatlinecontent.h" - -#include -#include - -class CustomTextDocument; - /* Copyright (C) 2014 by Project Tox @@ -24,6 +14,16 @@ class CustomTextDocument; See the COPYING file for more details. */ +#ifndef TEXT_H +#define TEXT_H + +#include "../chatlinecontent.h" + +#include +#include + +class CustomTextDocument; + class Text : public ChatLineContent { public: @@ -61,6 +61,8 @@ protected: int cursorFromPos(QPointF scenePos) const; + void detectAnchors(); + private: CustomTextDocument* doc = nullptr; QString text; From 3190530686dd350a185ca12fba92eb1a7b71dfbc Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 13 Dec 2014 21:11:03 +0100 Subject: [PATCH 027/203] filling the gaps --- src/chatlog/chatline.cpp | 8 ++ src/chatlog/chatline.h | 1 + src/chatlog/chatlog.cpp | 25 ++++++ src/chatlog/chatlog.h | 4 + src/chatlog/chatmessage.cpp | 10 +++ src/chatlog/chatmessage.h | 3 + src/chatlog/content/filetransferwidget.cpp | 28 +++--- src/chatlog/content/filetransferwidget.h | 2 + src/core.cpp | 2 +- src/widget/form/chatform.cpp | 99 ++++++++++------------ src/widget/form/chatform.h | 1 - src/widget/form/genericchatform.cpp | 35 ++++---- src/widget/form/genericchatform.h | 6 +- src/widget/widget.cpp | 9 +- 14 files changed, 139 insertions(+), 94 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index 928dcb7ca..69ae5c991 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -61,6 +61,14 @@ int ChatLine::getRowIndex() const return rowIndex; } +ChatLineContent *ChatLine::getContent(int col) const +{ + if(col < content.size() && col >= 0) + return content[col]; + + return nullptr; +} + void ChatLine::selectionCleared() { for(ChatLineContent* c : content) diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index bebc5d8cf..a5cda1e4d 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -72,6 +72,7 @@ public: int getColumnCount(); int getRowIndex() const; + ChatLineContent* getContent(int col) const; bool isOverSelection(QPointF scenePos); diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 8f641d535..8447e1186 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -96,6 +96,26 @@ ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString& msg, return line; } +ChatMessage *ChatLog::addChatAction(const QString &sender, const QString &msg, const QDateTime ×tamp) +{ + ChatMessage* line = addChatAction(sender, msg); + line->markAsSent(timestamp); + + return line; +} + +ChatMessage *ChatLog::addChatAction(const QString &sender, const QString &msg) +{ + ChatMessage* line = new ChatMessage(scene, msg); + line->addColumn(new Text("", Style::getFont(Style::Medium), true), ColumnFormat(75.0, ColumnFormat::FixedSize, ColumnFormat::Right)); + line->addColumn(new Text("*" + sender + " " + SmileyPack::getInstance().smileyfied(msg) + ""), ColumnFormat(1.0, ColumnFormat::VariableSize)); + line->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(50.0, ColumnFormat::FixedSize, ColumnFormat::Right)); + line->setAsAction(); + + insertChatline(line); + return line; +} + ChatMessage *ChatLog::addSystemMessage(const QString &msg, const QDateTime& timestamp) { ChatMessage* line = new ChatMessage(scene, msg); @@ -435,6 +455,11 @@ QString ChatLog::getSelectedText() const return QString(); } +bool ChatLog::isEmpty() const +{ + return lines.isEmpty(); +} + void ChatLog::showContextMenu(const QPoint& globalPos, const QPointF& scenePos) { QMenu menu; diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 64b1ef549..c0bff59dc 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -37,6 +37,8 @@ public: ChatMessage* addChatMessage(const QString& sender, const QString& msg, const QDateTime& timestamp, bool self); ChatMessage* addChatMessage(const QString& sender, const QString& msg, bool self); + ChatMessage* addChatAction(const QString& sender, const QString& msg, const QDateTime& timestamp); + ChatMessage* addChatAction(const QString& sender, const QString& msg); ChatMessage* addSystemMessage(const QString& msg, const QDateTime& timestamp); ChatMessage* addFileTransferMessage(const QString& sender, const ToxFile& file, const QDateTime ×tamp, bool self); @@ -48,6 +50,8 @@ public: void copySelectedText() const; QString getSelectedText() const; + bool isEmpty() const; + protected: QRect getVisibleRect() const; ChatLineContent* getContentFromPos(QPointF scenePos) const; diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 10ec4b94c..57c38cef3 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -37,3 +37,13 @@ QString ChatMessage::toString() const { return rawString; } + +bool ChatMessage::isAction() const +{ + return action; +} + +void ChatMessage::setAsAction() +{ + action = true; +} diff --git a/src/chatlog/chatmessage.h b/src/chatlog/chatmessage.h index 282bd0703..9e4b2a27e 100644 --- a/src/chatlog/chatmessage.h +++ b/src/chatlog/chatmessage.h @@ -28,10 +28,13 @@ public: void markAsSent(const QDateTime& time); QString toString() const; + bool isAction() const; + void setAsAction(); private: ChatLineContent* midColumn = nullptr; QString rawString; + bool action = false; }; #endif // CHATMESSAGE_H diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index 6d24b0378..cca195cc7 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -69,6 +69,21 @@ FileTransferWidget::~FileTransferWidget() delete ui; } +void FileTransferWidget::acceptTransfer(const QString &path) +{ + if(!QFileInfo(QDir(path).path()).isWritable()) + { + QMessageBox::warning(0, + 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")); + + return; + } + + if(!path.isEmpty()) + Core::getInstance()->acceptFileRecvRequest(fileInfo.friendId, fileInfo.fileNum, path); +} + void FileTransferWidget::onFileTransferInfo(ToxFile file) { if(fileInfo != file) @@ -255,18 +270,7 @@ void FileTransferWidget::handleButton(QPushButton *btn) if(btn->objectName() == "accept") { QString path = QFileDialog::getSaveFileName(0, tr("Save a file","Title of the file saving dialog"), QDir::home().filePath(fileInfo.fileName)); - - if(!QFileInfo(QDir(path).path()).isWritable()) - { - QMessageBox::warning(0, - 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")); - - return; - } - - if(!path.isEmpty()) - Core::getInstance()->acceptFileRecvRequest(fileInfo.friendId, fileInfo.fileNum, path); + acceptTransfer(path); } } diff --git a/src/chatlog/content/filetransferwidget.h b/src/chatlog/content/filetransferwidget.h index 11d6b52ee..90a3e2eee 100644 --- a/src/chatlog/content/filetransferwidget.h +++ b/src/chatlog/content/filetransferwidget.h @@ -36,6 +36,8 @@ public: explicit FileTransferWidget(QWidget *parent, ToxFile file); virtual ~FileTransferWidget(); + void acceptTransfer(const QString& path); + protected slots: void onFileTransferInfo(ToxFile file); void onFileTransferAccepted(ToxFile file); diff --git a/src/core.cpp b/src/core.cpp index f13948cd8..679ced5f1 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -1054,7 +1054,7 @@ void Core::setAvatar(uint8_t format, const QByteArray& data) ToxID Core::getSelfId() const { - uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE]; + uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE] = {0}; tox_get_address(tox, friendAddress); return ToxID::fromString(CFriendAddress::toString(friendAddress)); } diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 467258633..f6f39eed1 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -39,6 +39,7 @@ #include "src/misc/settings.h" #include "src/misc/cstring.h" #include "src/chatlog/chatmessage.h" +#include "src/chatlog/content/filetransferwidget.h" ChatForm::ChatForm(Friend* chatFriend) : f(chatFriend) @@ -74,7 +75,6 @@ ChatForm::ChatForm(Friend* chatFriend) connect(msgEdit, &ChatTextEdit::enterPressed, this, &ChatForm::onSendTriggered); connect(micButton, SIGNAL(clicked()), this, SLOT(onMicMuteToggle())); connect(volButton, SIGNAL(clicked()), this, SLOT(onVolMuteToggle())); - //TODO: connect(chatWidget, &ChatAreaWidget::onFileTranfertInterract, this, &ChatForm::onFileTansBtnClicked); connect(Core::getInstance(), &Core::fileSendFailed, this, &ChatForm::onFileSendFailed); connect(this, SIGNAL(chatAreaCleared()), this, SLOT(clearReciepts())); @@ -197,11 +197,14 @@ void ChatForm::onFileRecvRequest(ToxFile file) previousId = friendId; } - chatWidget->addFileTransferMessage(name, file, QDateTime::currentDateTime(), false); -//TODO: -// if (!Settings::getInstance().getAutoAcceptDir(Core::getInstance()->getFriendAddress(f->getFriendID())).isEmpty() -// || Settings::getInstance().getAutoSaveEnabled()) -// fileTrans->pressFromHtml("btnB"); + ChatMessage* msg = chatWidget->addFileTransferMessage(name, file, QDateTime::currentDateTime(), false); + if (!Settings::getInstance().getAutoAcceptDir(Core::getInstance()->getFriendAddress(f->getFriendID())).isEmpty() + || Settings::getInstance().getAutoSaveEnabled()) + { + FileTransferWidget* tfWidget = dynamic_cast(msg->getContent(1)); + if(tfWidget) + tfWidget->acceptTransfer(Settings::getInstance().getAutoAcceptDir(Core::getInstance()->getFriendAddress(f->getFriendID()))); + } } void ChatForm::onAvInvite(int FriendId, int CallId, bool video) @@ -230,7 +233,7 @@ void ChatForm::onAvInvite(int FriendId, int CallId, bool video) connect(callButton, SIGNAL(clicked()), this, SLOT(onAnswerCallTriggered())); } - //TODO: addSystemInfoMessage(tr("%1 calling").arg(f->getDisplayedName()), "white", QDateTime::currentDateTime()); + chatWidget->addSystemMessage(tr("%1 calling").arg(f->getDisplayedName()), QDateTime::currentDateTime()); Widget* w = Widget::getInstance(); if (!w->isFriendWidgetCurActiveWidget(f)|| w->isMinimized() || !w->isActiveWindow()) @@ -496,7 +499,7 @@ void ChatForm::onAvRejected(int FriendId, int) connect(callButton, SIGNAL(clicked()), this, SLOT(onCallTriggered())); connect(videoButton, SIGNAL(clicked()), this, SLOT(onVideoCallTriggered())); - //TODO: addSystemInfoMessage(tr("Call rejected"), "white", QDateTime::currentDateTime()); + chatWidget->addSystemMessage(tr("Call rejected"), QDateTime::currentDateTime()); netcam->hide(); } @@ -630,18 +633,6 @@ void ChatForm::onVolMuteToggle() } } - -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; -} - void ChatForm::onFileSendFailed(int FriendId, const QString &fname) { if (FriendId != f->getFriendID()) @@ -708,39 +699,39 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) ToxID storedPrevId; std::swap(storedPrevId, previousId); -// QList historyMessages; + QList historyMessages; -// QDate lastDate(1,0,0); -// for (const auto &it : msgs) -// { -// // Show the date every new day -// QDateTime msgDateTime = it.timestamp.toLocalTime(); -// QDate msgDate = msgDateTime.date(); -// if (msgDate > lastDate) -// { -// lastDate = msgDate; -// //TODO: historyMessages.append(genSystemInfoAction(msgDate.toString(),"",QDateTime())); -// } + //TODO: possibly broken + QDate lastDate(1,0,0); + for (const auto &it : msgs) + { + // Show the date every new day + QDateTime msgDateTime = it.timestamp.toLocalTime(); + QDate msgDate = msgDateTime.date(); + if (msgDate > lastDate) + { + lastDate = msgDate; + chatWidget->addSystemMessage(msgDate.toString(), QDateTime()); + } -// // Show each messages -// ChatMessage* ca = genMessageActionAction(ToxID::fromString(it.sender), it.message, false, msgDateTime); -// if (it.isSent) -// { -// ca->markAsSent(); -// } else { -// if (processUndelivered) -// { -// int rec; -// if (ca->isAction()) -// rec = Core::getInstance()->sendAction(f->getFriendID(), ca->getRawMessage()); -// else -// rec = Core::getInstance()->sendMessage(f->getFriendID(), ca->getRawMessage()); -// registerReceipt(rec, it.id, ca); -// } -// } -// historyMessages.append(ca); -// } -// std::swap(storedPrevId, previousId); + // Show each messages + ToxID id = ToxID::fromString(it.sender); + ChatMessage* msg = chatWidget->addChatMessage(Core::getInstance()->getPeerName(id), it.message, id.isMine()); + if (it.isSent) + { + msg->markAsSent(msgDateTime); + } + else + { + if (processUndelivered) + { + int rec = Core::getInstance()->sendMessage(f->getFriendID(), msg->toString()); + registerReceipt(rec, it.id, msg); + } + } + historyMessages.append(msg); + } + std::swap(storedPrevId, previousId); // int savedSliderPos = chatWidget->verticalScrollBar()->maximum() - chatWidget->verticalScrollBar()->value(); @@ -859,9 +850,9 @@ void ChatForm::deliverOfflineMsgs() { QString messageText = iter.value()->toString(); int rec; - //if (iter.value()->isAction()) - ;//TODO: rec = Core::getInstance()->sendAction(f->getFriendID(), messageText); - //else + if (iter.value()->isAction()) + rec = Core::getInstance()->sendAction(f->getFriendID(), messageText); + else rec = Core::getInstance()->sendMessage(f->getFriendID(), messageText); registerReceipt(rec, iter.key(), iter.value()); } diff --git a/src/widget/form/chatform.h b/src/widget/form/chatform.h index 2f9ee98d5..34be1a11b 100644 --- a/src/widget/form/chatform.h +++ b/src/widget/form/chatform.h @@ -79,7 +79,6 @@ private slots: void onAnswerCallTriggered(); void onHangupCallTriggered(); void onCancelCallTriggered(); - void onFileTansBtnClicked(QString widgetName, QString buttonName); void onFileSendFailed(int FriendId, const QString &fname); void onLoadHistory(); void updateTime(); diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index 9774ce119..f44d92b63 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -152,7 +152,12 @@ GenericChatForm::GenericChatForm(QWidget *parent) : bool GenericChatForm::isEmpty() { - //return chatWidget->isEmpty(); + return chatWidget->isEmpty(); +} + +ChatLog *GenericChatForm::getChatLog() const +{ + return chatWidget; } void GenericChatForm::setName(const QString &newName) @@ -193,35 +198,29 @@ void GenericChatForm::onSaveLogClicked() // file.close(); } -/** - * @deprecated The only reason it's still alive is because the groupchat API is a bit limited - */ -//void GenericChatForm::addMessage(const QString& author, const QString &message, bool isAction, const QDateTime &datetime) -//{ -// MessageActionPtr ca = genMessageActionAction(author, message, isAction, datetime); -// ca->markAsSent(); -// chatWidget->insertMessage(ca); -//} - ChatMessage* GenericChatForm::addMessage(const ToxID& author, const QString &message, bool isAction, const QDateTime &datetime, bool isSent) { - QString authorStr = previousId != author ? Core::getInstance()->getPeerName(author) : QString(); - previousId = author; + QString authorStr = (author.isMine() ? Core::getInstance()->getUsername() : Core::getInstance()->getPeerName(author)); + + ChatMessage* msg = nullptr; + if(isAction) + msg = chatWidget->addChatAction(authorStr, message); + else + msg = chatWidget->addChatMessage(author != previousId ? authorStr : QString(), message, author.isMine()); - ChatMessage* msg = chatWidget->addChatMessage(authorStr, message, datetime, false); if(isSent) msg->markAsSent(datetime); + if(!isAction) + previousId = author; + return msg; } ChatMessage* GenericChatForm::addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime, bool isSent) { - QString authorStr = previousId != Core::getInstance()->getSelfId() ? Core::getInstance()->getUsername() : QString(); - previousId = Core::getInstance()->getSelfId(); - - return chatWidget->addChatMessage(authorStr, message, true); + return addMessage(Core::getInstance()->getSelfId(), message, isAction, datetime, isSent); } /** diff --git a/src/widget/form/genericchatform.h b/src/widget/form/genericchatform.h index 3e54b6554..88fa3a238 100644 --- a/src/widget/form/genericchatform.h +++ b/src/widget/form/genericchatform.h @@ -58,6 +58,8 @@ public: void addAlertMessage(const ToxID& author, QString message, QDateTime datetime); bool isEmpty(); + ChatLog* getChatLog() const; + signals: void sendMessage(int, QString); void sendAction(int, QString); @@ -75,10 +77,6 @@ protected slots: protected: QString getElidedName(const QString& name); -//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); -// ChatMessage* genSystemInfoAction(const QString &message, const QString &type, const QDateTime &datetime); ToxID previousId; QMenu menu; diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 06ac1f5de..ecdfd3144 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -902,6 +902,7 @@ void Widget::onGroupMessageReceived(int groupnumber, const QString& message, con if (targeted) ;//TODO: g->chatForm->addAlertMessage(author, message, QDateTime::currentDateTime()); else + ;//TODO: g->chatForm->addMessage(author, message, isAction, QDateTime::currentDateTime()); if ((static_cast(g->widget) != activeChatroomWidget) || isMinimized() || !isActiveWindow()) @@ -932,14 +933,14 @@ void Widget::onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t Cha if (name.isEmpty()) name = tr("", "Placeholder when we don't know someone's name in a group chat"); g->addPeer(peernumber,name); - //g->chatForm->addSystemInfoMessage(tr("%1 has joined the chat").arg(name), "green"); + g->chatForm->getChatLog()->addSystemMessage(tr("%1 has joined the chat").arg(name), QDateTime::currentDateTime()); // we can't display these messages until irungentoo fixes peernumbers // https://github.com/irungentoo/toxcore/issues/1128 } else if (change == TOX_CHAT_CHANGE_PEER_DEL) { g->removePeer(peernumber); - //g->chatForm->addSystemInfoMessage(tr("%1 has left the chat").arg(name), "silver"); + g->chatForm->getChatLog()->addSystemMessage(tr("%1 has left the chat").arg(name), QDateTime::currentDateTime()); } else if (change == TOX_CHAT_CHANGE_PEER_NAME) // core overwrites old name before telling us it changed... g->updatePeer(peernumber,core->getGroupPeerName(groupnumber, peernumber)); @@ -1086,7 +1087,7 @@ void Widget::onGroupSendResult(int groupId, const QString& message, int result) return; if (result == -1) - ;//TODO: g->chatForm->addSystemInfoMessage(tr("Message failed to send"), "red", QDateTime::currentDateTime()); + g->chatForm->getChatLog()->addSystemMessage(tr("Message failed to send"), QDateTime::currentDateTime()); } void Widget::getPassword(QString info, int passtype, uint8_t* salt) @@ -1158,6 +1159,6 @@ void Widget::clearAllReceipts() QList frnds = FriendList::getAllFriends(); for (Friend *f : frnds) { - //TODO: f->getChatForm()->clearReciepts(); + f->getChatForm()->clearReciepts(); } } From 7a4af239b0d49f7d073e3b6e1fd1dd30a184ac6a Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 31 Dec 2014 09:59:35 +0100 Subject: [PATCH 028/203] Text: toHtmlChars --- src/chatlog/content/text.cpp | 11 +++++++++++ src/chatlog/content/text.h | 1 + 2 files changed, 12 insertions(+) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 032b85c8b..7660af746 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -286,3 +286,14 @@ void Text::detectAnchors() offset += htmledUrl.length(); } } + +QString Text::toHtmlChars(const QString &str) +{ + static QList> replaceList = {{"&","&"}, {">",">"}, {"<","<"}}; + QString res = str; + + for (auto &it : replaceList) + res = res.replace(it.first,it.second); + + return res; +} diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index 61b5ee866..8ef17499b 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -62,6 +62,7 @@ protected: int cursorFromPos(QPointF scenePos) const; void detectAnchors(); + QString toHtmlChars(const QString& str); private: CustomTextDocument* doc = nullptr; From f1f42fc23776850f8ecb601ac9227f2c7d1efc8c Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 31 Dec 2014 13:42:06 +0100 Subject: [PATCH 029/203] innerStyle, groupchats --- src/chatlog/chatlog.cpp | 26 +++++++----- src/chatlog/chatlog.h | 4 +- src/chatlog/customtextdocument.cpp | 3 +- src/widget/form/chatform.cpp | 2 +- src/widget/form/genericchatform.cpp | 40 ++++++++++--------- src/widget/widget.cpp | 5 +-- ui/chatArea/innerStyle.css | 62 ----------------------------- 7 files changed, 44 insertions(+), 98 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 8447e1186..ca5b09e8a 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -77,20 +77,24 @@ ChatLog::~ChatLog() delete line; } -ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString &msg, bool self) +ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString &msg, bool self, bool alert) { + QString txt = SmileyPack::getInstance().smileyfied(msg); + if(alert) + txt = "
" + txt + "
"; + 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, ColumnFormat::Right)); - line->addColumn(new Text(SmileyPack::getInstance().smileyfied(msg)), ColumnFormat(1.0, ColumnFormat::VariableSize)); + line->addColumn(new Text(sender, self ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(75.0, ColumnFormat::FixedSize, ColumnFormat::Right)); + line->addColumn(new Text(txt, Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); line->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(50.0, ColumnFormat::FixedSize, ColumnFormat::Right)); insertChatline(line); return line; } -ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString& msg, const QDateTime& timestamp, bool self) +ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString& msg, const QDateTime& timestamp, bool self, bool alert) { - ChatMessage* line = addChatMessage(sender, msg, self); + ChatMessage* line = addChatMessage(sender, msg, self, alert); line->markAsSent(timestamp); return line; @@ -107,8 +111,8 @@ ChatMessage *ChatLog::addChatAction(const QString &sender, const QString &msg, c ChatMessage *ChatLog::addChatAction(const QString &sender, const QString &msg) { ChatMessage* line = new ChatMessage(scene, msg); - line->addColumn(new Text("", Style::getFont(Style::Medium), true), ColumnFormat(75.0, ColumnFormat::FixedSize, ColumnFormat::Right)); - line->addColumn(new Text("*" + sender + " " + SmileyPack::getInstance().smileyfied(msg) + ""), ColumnFormat(1.0, ColumnFormat::VariableSize)); + line->addColumn(new Text(""), ColumnFormat(75.0, ColumnFormat::FixedSize, ColumnFormat::Right)); + line->addColumn(new Text("
*" + sender + " " + SmileyPack::getInstance().smileyfied(msg) + "
", Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); line->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(50.0, ColumnFormat::FixedSize, ColumnFormat::Right)); line->setAsAction(); @@ -120,8 +124,8 @@ ChatMessage *ChatLog::addSystemMessage(const QString &msg, const QDateTime& time { ChatMessage* line = new ChatMessage(scene, msg); line->addColumn(new Image(QSizeF(16, 16), ":/ui/chatArea/info.png"), ColumnFormat(75.0, ColumnFormat::FixedSize, 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, ColumnFormat::Right)); + line->addColumn(new Text(msg, Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); + line->addColumn(new Text(timestamp.toString("hh:mm"), Style::getFont(Style::Big)), ColumnFormat(50.0, ColumnFormat::FixedSize, ColumnFormat::Right)); insertChatline(line); return line; @@ -130,9 +134,9 @@ ChatMessage *ChatLog::addSystemMessage(const QString &msg, const QDateTime& time ChatMessage *ChatLog::addFileTransferMessage(const QString &sender, const ToxFile &file, const QDateTime& timestamp, bool self) { ChatMessage* line = new ChatMessage(scene, QString()); - line->addColumn(new Text(sender, self ? Style::getFont(Style::MediumBold) : Style::getFont(Style::Medium), true), ColumnFormat(75.0, ColumnFormat::FixedSize, ColumnFormat::Right)); + line->addColumn(new Text(sender, self ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(75.0, ColumnFormat::FixedSize, ColumnFormat::Right)); line->addColumn(new ChatLineContentProxy(new FileTransferWidget(0, file)), ColumnFormat(1.0, ColumnFormat::VariableSize)); - line->addColumn(new Text(timestamp.toString("hh:mm")), ColumnFormat(50.0, ColumnFormat::FixedSize, ColumnFormat::Right)); + line->addColumn(new Text(timestamp.toString("hh:mm"), Style::getFont(Style::Big)), ColumnFormat(50.0, ColumnFormat::FixedSize, ColumnFormat::Right)); insertChatline(line); return line; diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index c0bff59dc..7a6a5b14f 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -35,8 +35,8 @@ public: explicit ChatLog(QWidget* parent = 0); virtual ~ChatLog(); - ChatMessage* addChatMessage(const QString& sender, const QString& msg, const QDateTime& timestamp, bool self); - ChatMessage* addChatMessage(const QString& sender, const QString& msg, bool self); + ChatMessage* addChatMessage(const QString& sender, const QString& msg, const QDateTime& timestamp, bool self, bool alert); + ChatMessage* addChatMessage(const QString& sender, const QString& msg, bool self, bool alert); ChatMessage* addChatAction(const QString& sender, const QString& msg, const QDateTime& timestamp); ChatMessage* addChatAction(const QString& sender, const QString& msg); diff --git a/src/chatlog/customtextdocument.cpp b/src/chatlog/customtextdocument.cpp index 676fbae09..e75dd4225 100644 --- a/src/chatlog/customtextdocument.cpp +++ b/src/chatlog/customtextdocument.cpp @@ -16,6 +16,7 @@ #include "customtextdocument.h" #include "../misc/smileypack.h" +#include "../misc/style.h" #include #include @@ -23,7 +24,7 @@ CustomTextDocument::CustomTextDocument(QObject *parent) : QTextDocument(parent) { - + setDefaultStyleSheet(Style::getStylesheet(":ui/chatArea/innerStyle.css")); } QVariant CustomTextDocument::loadResource(int type, const QUrl &name) diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index f6f39eed1..a3e44ea11 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -716,7 +716,7 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) // Show each messages ToxID id = ToxID::fromString(it.sender); - ChatMessage* msg = chatWidget->addChatMessage(Core::getInstance()->getPeerName(id), it.message, id.isMine()); + ChatMessage* msg = chatWidget->addChatMessage(Core::getInstance()->getPeerName(id), it.message, id.isMine(), false); if (it.isSent) { msg->markAsSent(msgDateTime); diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index f44d92b63..50b9b6626 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -174,6 +174,18 @@ void GenericChatForm::show(Ui::MainWindow &ui) QWidget::show(); } +void GenericChatForm::addMessage(const QString &author, const QString &message, bool isAction, const QDateTime &datetime) +{ + if(!isAction) + { + chatWidget->addChatMessage(author, message, datetime, false, false); + } + else + { + chatWidget->addChatAction(author, message, datetime); + } +} + void GenericChatForm::onChatContextMenuRequested(QPoint pos) { QWidget* sender = (QWidget*)QObject::sender(); @@ -207,7 +219,7 @@ ChatMessage* GenericChatForm::addMessage(const ToxID& author, const QString &mes if(isAction) msg = chatWidget->addChatAction(authorStr, message); else - msg = chatWidget->addChatMessage(author != previousId ? authorStr : QString(), message, author.isMine()); + msg = chatWidget->addChatMessage(author != previousId ? authorStr : QString(), message, author.isMine(), false); if(isSent) msg->markAsSent(datetime); @@ -223,25 +235,11 @@ ChatMessage* GenericChatForm::addSelfMessage(const QString &message, bool isActi return addMessage(Core::getInstance()->getSelfId(), message, isAction, datetime, isSent); } -/** - * @deprecated The only reason it's still alive is because the groupchat API is a bit limited - */ -//void GenericChatForm::addAlertMessage(const QString& author, QString message, QDateTime datetime) -//{ -// QString date = datetime.toString(Settings::getInstance().getTimestampFormat()); -// AlertAction *alact = new AlertAction(author, message, date); -// alact->markAsSent(); -// chatWidget->insertMessage(ChatActionPtr(alact)); - -// previousId.publicKey = author; -//} - 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; + QString authorStr = Core::getInstance()->getPeerName(author); + chatWidget->addChatMessage(author != previousId ? authorStr : QString(), message, author.isMine(), true); + previousId = author; } void GenericChatForm::onEmoteButtonClicked() @@ -282,6 +280,12 @@ void GenericChatForm::addSystemInfoMessage(const QString &message, const QString chatWidget->addSystemMessage(message, datetime); } +void GenericChatForm::addAlertMessage(const QString &author, QString message, QDateTime datetime) +{ + ChatMessage* msg = chatWidget->addChatMessage(author, message, false, true); + msg->markAsSent(datetime); +} + //QString GenericChatForm::getElidedName(const QString& name) //{ // // update this whenever you change the font in innerStyle.css diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index ecdfd3144..013121bfb 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -900,10 +900,9 @@ void Widget::onGroupMessageReceived(int groupnumber, const QString& message, con bool targeted = (author != name) && message.contains(name, Qt::CaseInsensitive); if (targeted) - ;//TODO: g->chatForm->addAlertMessage(author, message, QDateTime::currentDateTime()); + g->chatForm->addAlertMessage(author, message, QDateTime::currentDateTime()); else - - ;//TODO: g->chatForm->addMessage(author, message, isAction, QDateTime::currentDateTime()); + g->chatForm->addMessage(author, message, isAction, QDateTime::currentDateTime()); if ((static_cast(g->widget) != activeChatroomWidget) || isMinimized() || !isActiveWindow()) { diff --git a/ui/chatArea/innerStyle.css b/ui/chatArea/innerStyle.css index dc1f46d73..63d833105 100644 --- a/ui/chatArea/innerStyle.css +++ b/ui/chatArea/innerStyle.css @@ -1,8 +1,3 @@ -div.name { - color: @black; - font: @bigBold; -} - div.message { color: @black; font: @big; @@ -13,60 +8,10 @@ div.action { font: @big; } -div.date { - color: @black; - font: @big; -} - -div.name_me { - color: @mediumGrey; - font: @big; -} - -div.message_me { - color: @black; - font: @big; -} - -div.date_me { - color: @black; - font: @big; -} - span.quote { color: #6bc260; } -div.green { - margin-top: 6px; - margin-bottom: 6px; - margin-left: 0px; - margin-right: 0px; - color: @white; - background-color: @green; - font: @small; -} - -div.silver { - margin-top: 6px; - margin-bottom: 6px; - margin-left: 0px; - margin-right: 0px; - color: @black; - background-color: @lightGrey; - font: @small; -} - -div.red { - margin-top: 6px; - margin-bottom: 6px; - margin-left: 0px; - margin-right: 0px; - color: @white; - background-color: @red; - font: @small; -} - div.alert { margin-left: 0px; margin-right: 0px; @@ -80,10 +25,3 @@ div.alert_name { background-color: @orange; font: @bigBold; } - -div.button { - margin-top: 0px; - margin-bottom: 0px; - margin-left: 0px; - color: @white; -} From eecd886745ab60a73d1d71190beae703c27369d5 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 2 Jan 2015 11:14:50 +0100 Subject: [PATCH 030/203] filetransferwidget layout changes --- src/chatlog/content/filetransferwidget.cpp | 2 +- src/chatlog/content/filetransferwidget.ui | 32 ++++++++++++---------- ui/fileTransferInstance/grey.css | 1 + 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index cca195cc7..d1f49ebd6 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -61,7 +61,7 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) if(fileInfo.direction == ToxFile::SENDING) showPreview(fileInfo.filePath); - setFixedHeight(85); + setFixedHeight(90); } FileTransferWidget::~FileTransferWidget() diff --git a/src/chatlog/content/filetransferwidget.ui b/src/chatlog/content/filetransferwidget.ui index e43b8c091..030d52326 100644 --- a/src/chatlog/content/filetransferwidget.ui +++ b/src/chatlog/content/filetransferwidget.ui @@ -6,8 +6,8 @@ 0 0 - 544 - 207 + 532 + 90
@@ -66,13 +66,13 @@ 6 - 6 + 0 6 - 6 + 0 @@ -216,13 +216,15 @@
+ + + 0 + 0 + + - - - :/ui/fileTransferInstance/pause_2x.png:/ui/fileTransferInstance/pause_2x.png - 25 @@ -249,13 +251,15 @@ + + + 0 + 0 + + - - - :/ui/fileTransferInstance/arrow_white_2x.png:/ui/fileTransferInstance/arrow_white_2x.png - 25 @@ -275,8 +279,6 @@
- - - + diff --git a/ui/fileTransferInstance/grey.css b/ui/fileTransferInstance/grey.css index 099434acc..fbfe9f81f 100644 --- a/ui/fileTransferInstance/grey.css +++ b/ui/fileTransferInstance/grey.css @@ -8,6 +8,7 @@ QFrame { QLabel { color:black; + font:@medium; } QPushButton { From 4997788b13a9be5ffd5cfd1ee332985dbf76e513 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 2 Jan 2015 11:25:07 +0100 Subject: [PATCH 031/203] fix selection --- src/chatlog/chatlog.cpp | 50 ++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index ca5b09e8a..d9eb9a9f1 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -291,39 +291,39 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) scene->mouseGrabberItem()->ungrabMouse(); } } - } - if(selectionMode != None && ev->pos() != lastPos) - { - lastPos = ev->pos(); - - ChatLineContent* content = getContentFromPos(scenePos); - - if(content) + if(selectionMode != None && ev->pos() != lastPos) { - int row = content->getRow(); - int col = content->getColumn(); + lastPos = ev->pos(); - if(row >= selClickedRow) - selLastRow = row; + ChatLineContent* content = getContentFromPos(scenePos); - if(row <= selClickedRow) - selFirstRow = row; - - if(row == selClickedRow && col == selClickedCol) + if(content) { - selectionMode = Precise; + int row = content->getRow(); + int col = content->getColumn(); - content->selectionMouseMove(scenePos); - selGraphItem->hide(); - } - else - { - selectionMode = Multi; + if(row >= selClickedRow) + selLastRow = row; - lines[selClickedRow]->selectionCleared(); + if(row <= selClickedRow) + selFirstRow = row; - updateMultiSelectionRect(); + if(row == selClickedRow && col == selClickedCol) + { + selectionMode = Precise; + + content->selectionMouseMove(scenePos); + selGraphItem->hide(); + } + else + { + selectionMode = Multi; + + lines[selClickedRow]->selectionCleared(); + + updateMultiSelectionRect(); + } } } } From 3c9e071a39b657003daba1b127d8cf45e97b98d6 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 2 Jan 2015 11:34:28 +0100 Subject: [PATCH 032/203] chatlinecontentproxy: scaling behaviour --- src/chatlog/chatlinecontentproxy.cpp | 6 ++++-- src/chatlog/chatlinecontentproxy.h | 5 +++-- src/chatlog/chatlog.cpp | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/chatlog/chatlinecontentproxy.cpp b/src/chatlog/chatlinecontentproxy.cpp index dc12b96ed..0325763fc 100644 --- a/src/chatlog/chatlinecontentproxy.cpp +++ b/src/chatlog/chatlinecontentproxy.cpp @@ -19,7 +19,9 @@ #include #include -ChatLineContentProxy::ChatLineContentProxy(QWidget* widget) +ChatLineContentProxy::ChatLineContentProxy(QWidget* widget, int minWidth, float widthInPercent) + : widthMin(minWidth) + , widthPercent(widthInPercent) { proxy = new QGraphicsProxyWidget(this); proxy->setWidget(widget); @@ -47,5 +49,5 @@ qreal ChatLineContentProxy::getAscent() const void ChatLineContentProxy::setWidth(qreal width) { - proxy->widget()->setFixedWidth(qMax(width,0.0)); + proxy->widget()->setFixedWidth(qMax(static_cast(width*widthPercent), widthMin)); } diff --git a/src/chatlog/chatlinecontentproxy.h b/src/chatlog/chatlinecontentproxy.h index d9686e96f..da435fd91 100644 --- a/src/chatlog/chatlinecontentproxy.h +++ b/src/chatlog/chatlinecontentproxy.h @@ -23,7 +23,7 @@ class ChatLineContentProxy : public ChatLineContent { public: - ChatLineContentProxy(QWidget* widget); + ChatLineContentProxy(QWidget* widget, int minWidth, float widthInPercent = 1.0f); virtual QRectF boundingRect() const; virtual QRectF boundingSceneRect() const; @@ -33,7 +33,8 @@ public: private: QGraphicsProxyWidget* proxy; - + int widthMin; + float widthPercent; }; #endif // CHATLINECONTENTPROXY_H diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index d9eb9a9f1..309828756 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -135,7 +135,7 @@ ChatMessage *ChatLog::addFileTransferMessage(const QString &sender, const ToxFil { ChatMessage* line = new ChatMessage(scene, QString()); line->addColumn(new Text(sender, self ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(75.0, ColumnFormat::FixedSize, ColumnFormat::Right)); - line->addColumn(new ChatLineContentProxy(new FileTransferWidget(0, file)), ColumnFormat(1.0, ColumnFormat::VariableSize)); + line->addColumn(new ChatLineContentProxy(new FileTransferWidget(0, file), 380, 0.6f), ColumnFormat(1.0, ColumnFormat::VariableSize)); line->addColumn(new Text(timestamp.toString("hh:mm"), Style::getFont(Style::Big)), ColumnFormat(50.0, ColumnFormat::FixedSize, ColumnFormat::Right)); insertChatline(line); From 1c653c5f65a22bf067db595b7169b542b60df03d Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 2 Jan 2015 11:36:24 +0100 Subject: [PATCH 033/203] filetransferwidget: use CroppingLabel --- src/chatlog/content/filetransferwidget.ui | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/chatlog/content/filetransferwidget.ui b/src/chatlog/content/filetransferwidget.ui index 030d52326..868adf74e 100644 --- a/src/chatlog/content/filetransferwidget.ui +++ b/src/chatlog/content/filetransferwidget.ui @@ -75,7 +75,7 @@ 0 - + 0 @@ -279,6 +279,13 @@
+ + + CroppingLabel + QLabel +
src/widget/croppinglabel.h
+
+
From b0c3b4032f3e222a8820acb59e1bec7ea9fcb14c Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 2 Jan 2015 12:04:04 +0100 Subject: [PATCH 034/203] chatlog: save chat log --- src/chatlog/chatlog.cpp | 42 +++++++++++++++++++++++++++-- src/chatlog/chatlog.h | 1 + src/widget/form/genericchatform.cpp | 21 --------------- src/widget/form/genericchatform.h | 1 - 4 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 309828756..a6d08e6ae 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -32,6 +32,8 @@ #include #include #include +#include +#include template T clamp(T x, T min, T max) @@ -459,6 +461,27 @@ QString ChatLog::getSelectedText() const return QString(); } +QString ChatLog::toPlainText() const +{ + QString out; + QString lastSender; + + for(ChatLine* l : lines) + { + if(lastSender != l->content[0]->getText() && !l->content[0]->getText().isEmpty()) + { + //author changed + out += l->content[0]->getText() + ":\n"; + lastSender = l->content[0]->getText(); + } + + out += l->content[1]->getText(); + out += "\n\n"; + } + + return out; +} + bool ChatLog::isEmpty() const { return lines.isEmpty(); @@ -469,9 +492,10 @@ void ChatLog::showContextMenu(const QPoint& globalPos, const QPointF& scenePos) QMenu menu; // populate - QAction* copyAction = menu.addAction(QIcon::fromTheme("edit-copy"), "Copy"); + QAction* copyAction = menu.addAction(QIcon::fromTheme("edit-copy"), tr("Copy")); menu.addSeparator(); - QAction* clearAction = menu.addAction("Clear log"); + QAction* clearAction = menu.addAction(QIcon::fromTheme("edit-clear") ,tr("Clear chat log")); + QAction* saveAction = menu.addAction(QIcon::fromTheme("document-save") ,tr("Save chat log")); if(!isOverSelection(scenePos)) copyAction->setDisabled(true); @@ -484,6 +508,20 @@ void ChatLog::showContextMenu(const QPoint& globalPos, const QPointF& scenePos) if(action == clearAction) clear(); + + if(action == saveAction) + { + QString path = QFileDialog::getSaveFileName(0, tr("Save chat log")); + if (path.isEmpty()) + return; + + QFile file(path); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) + return; + + file.write(toPlainText().toUtf8()); + file.close(); + } } void ChatLog::clear() diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 7a6a5b14f..714ec9963 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -49,6 +49,7 @@ public: void clear(); void copySelectedText() const; QString getSelectedText() const; + QString toPlainText() const; bool isEmpty() const; diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index 076690924..8fc54c439 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -143,10 +143,6 @@ GenericChatForm::GenericChatForm(QWidget *parent) : fileButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); emoteButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); - menu.addAction(tr("Save chat log"), this, SLOT(onSaveLogClicked())); - menu.addAction(tr("Clear displayed messages"), this, SLOT(clearChatArea(bool))); - menu.addSeparator(); - connect(emoteButton, SIGNAL(clicked()), this, SLOT(onEmoteButtonClicked())); connect(chatWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onChatContextMenuRequested(QPoint))); connect(chatWidget, SIGNAL(onClick()), this, SLOT(onChatWidgetClicked())); @@ -189,23 +185,6 @@ void GenericChatForm::onChatContextMenuRequested(QPoint pos) menu.exec(pos); } -void GenericChatForm::onSaveLogClicked() -{ -// QString path = QFileDialog::getSaveFileName(0, tr("Save chat log")); -// if (path.isEmpty()) -// return; - -// QFile file(path); -// if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) -// return; - -// QString log; -// log = chatWidget->toPlainText(); - -// file.write(log.toUtf8()); -// file.close(); -} - ChatMessage* GenericChatForm::addMessage(const ToxID& author, const QString &message, bool isAction, const QDateTime &datetime, bool isSent) { diff --git a/src/widget/form/genericchatform.h b/src/widget/form/genericchatform.h index 570bff8fd..37a63faee 100644 --- a/src/widget/form/genericchatform.h +++ b/src/widget/form/genericchatform.h @@ -69,7 +69,6 @@ public slots: protected slots: void onChatContextMenuRequested(QPoint pos); - void onSaveLogClicked(); void onEmoteButtonClicked(); void onEmoteInsertRequested(QString str); void clearChatArea(bool); From 5ae111e7c4ba338fa777c6cdec67bac67fa9bc1d Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 2 Jan 2015 12:04:32 +0100 Subject: [PATCH 035/203] chatline: set row and col number --- src/chatlog/chatline.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index 69ae5c991..0ae8c8e61 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -134,6 +134,7 @@ void ChatLine::replaceContent(int col, ChatLineContent *lineContent) delete content[col]; content[col] = lineContent; + lineContent->setIndex(rowIndex, col); scene->addItem(content[col]); layout(width, pos); From 96789182cfde3a8e4ca42c67231e5d011d99dd8d Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 2 Jan 2015 13:04:40 +0100 Subject: [PATCH 036/203] chatlog: Don't accept drops --- src/chatlog/chatlog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index a6d08e6ae..be5fee9e5 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -58,6 +58,7 @@ ChatLog::ChatLog(QWidget* parent) setDragMode(QGraphicsView::NoDrag); setViewportUpdateMode(SmartViewportUpdate); //setRenderHint(QPainter::TextAntialiasing); + setAcceptDrops(false); const QColor selGraphColor = QColor(166,225,255); selGraphItem = scene->addRect(0,0,0,0,selGraphColor.darker(120),selGraphColor); From 2828a97d54bd21ea8df2dc61d172e9d24565e323 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 2 Jan 2015 13:04:59 +0100 Subject: [PATCH 037/203] styled chatlog, cleanup --- src/widget/form/chatform.cpp | 5 +++-- src/widget/form/genericchatform.cpp | 9 +-------- src/widget/form/genericchatform.h | 1 - ui/chatArea/chatArea.css | 4 ++-- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 060e5e737..e437635fd 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -75,8 +75,9 @@ ChatForm::ChatForm(Friend* chatFriend) connect(volButton, SIGNAL(clicked()), this, SLOT(onVolMuteToggle())); connect(Core::getInstance(), &Core::fileSendFailed, this, &ChatForm::onFileSendFailed); connect(this, SIGNAL(chatAreaCleared()), this, SLOT(clearReciepts())); - connect(nameLabel, &CroppingLabel::textChanged, this, [=](QString text, QString orig) - {if (text != orig) emit aliasChanged(text);} ); + connect(nameLabel, &CroppingLabel::textChanged, this, [=](QString text, QString orig) { + if (text != orig) emit aliasChanged(text); + } ); setAcceptDrops(true); } diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index 8fc54c439..8612b5c0e 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -145,10 +145,8 @@ GenericChatForm::GenericChatForm(QWidget *parent) : connect(emoteButton, SIGNAL(clicked()), this, SLOT(onEmoteButtonClicked())); connect(chatWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onChatContextMenuRequested(QPoint))); - connect(chatWidget, SIGNAL(onClick()), this, SLOT(onChatWidgetClicked())); - //chatWidget->document()->setDefaultStyleSheet(Style::getStylesheet(":ui/chatArea/innerStyle.css")); - //chatWidget->setStyleSheet(Style::getStylesheet(":/ui/chatArea/chatArea.css")); + chatWidget->setStyleSheet(Style::getStylesheet(":/ui/chatArea/chatArea.css")); headWidget->setStyleSheet(Style::getStylesheet(":/ui/chatArea/chatHead.css")); //ChatAction::setupFormat(); @@ -235,11 +233,6 @@ void GenericChatForm::onEmoteButtonClicked() } } -void GenericChatForm::onChatWidgetClicked() -{ - msgEdit->setFocus(); -} - void GenericChatForm::onEmoteInsertRequested(QString str) { // insert the emoticon diff --git a/src/widget/form/genericchatform.h b/src/widget/form/genericchatform.h index 37a63faee..a14e480d9 100644 --- a/src/widget/form/genericchatform.h +++ b/src/widget/form/genericchatform.h @@ -72,7 +72,6 @@ protected slots: void onEmoteButtonClicked(); void onEmoteInsertRequested(QString str); void clearChatArea(bool); - void onChatWidgetClicked(); protected: QString resolveToxID(const ToxID &id); diff --git a/ui/chatArea/chatArea.css b/ui/chatArea/chatArea.css index 9608af802..98530a142 100644 --- a/ui/chatArea/chatArea.css +++ b/ui/chatArea/chatArea.css @@ -4,7 +4,7 @@ QTextEdit color: back; } -QTextBrowser +QGraphicsView { - border: none; + border: none; } From 40cc14bd448d9a1352e424981c9a53593c1728cc Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 2 Jan 2015 20:07:45 +0100 Subject: [PATCH 038/203] respect time format --- src/chatlog/chatlog.cpp | 22 +++++++++++++--------- src/chatlog/chatmessage.cpp | 4 +++- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index be5fee9e5..5c41d51f6 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -26,6 +26,7 @@ #include "../misc/style.h" #include "../misc/smileypack.h" +#include "../misc/settings.h" #include #include @@ -35,6 +36,9 @@ #include #include +#define NAME_COL_WIDTH 75.0 +#define TIME_COL_WIDTH 85.0 + template T clamp(T x, T min, T max) { @@ -87,9 +91,9 @@ ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString &msg, txt = "
" + txt + "
"; ChatMessage* line = new ChatMessage(scene, msg); - line->addColumn(new Text(sender, self ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(75.0, ColumnFormat::FixedSize, ColumnFormat::Right)); + line->addColumn(new Text(sender, self ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); line->addColumn(new Text(txt, Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); - line->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(50.0, ColumnFormat::FixedSize, ColumnFormat::Right)); + line->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); insertChatline(line); return line; @@ -114,9 +118,9 @@ ChatMessage *ChatLog::addChatAction(const QString &sender, const QString &msg, c ChatMessage *ChatLog::addChatAction(const QString &sender, const QString &msg) { ChatMessage* line = new ChatMessage(scene, msg); - line->addColumn(new Text(""), ColumnFormat(75.0, ColumnFormat::FixedSize, ColumnFormat::Right)); + line->addColumn(new Text(""), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); line->addColumn(new Text("
*" + sender + " " + SmileyPack::getInstance().smileyfied(msg) + "
", Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); - line->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(50.0, ColumnFormat::FixedSize, ColumnFormat::Right)); + line->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); line->setAsAction(); insertChatline(line); @@ -126,9 +130,9 @@ ChatMessage *ChatLog::addChatAction(const QString &sender, const QString &msg) ChatMessage *ChatLog::addSystemMessage(const QString &msg, const QDateTime& timestamp) { ChatMessage* line = new ChatMessage(scene, msg); - line->addColumn(new Image(QSizeF(16, 16), ":/ui/chatArea/info.png"), ColumnFormat(75.0, ColumnFormat::FixedSize, ColumnFormat::Right)); + line->addColumn(new Image(QSizeF(16, 16), ":/ui/chatArea/info.png"), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); line->addColumn(new Text(msg, Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); - line->addColumn(new Text(timestamp.toString("hh:mm"), Style::getFont(Style::Big)), ColumnFormat(50.0, ColumnFormat::FixedSize, ColumnFormat::Right)); + line->addColumn(new Text(timestamp.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); insertChatline(line); return line; @@ -137,9 +141,9 @@ ChatMessage *ChatLog::addSystemMessage(const QString &msg, const QDateTime& time ChatMessage *ChatLog::addFileTransferMessage(const QString &sender, const ToxFile &file, const QDateTime& timestamp, bool self) { ChatMessage* line = new ChatMessage(scene, QString()); - line->addColumn(new Text(sender, self ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(75.0, ColumnFormat::FixedSize, ColumnFormat::Right)); + line->addColumn(new Text(sender, self ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); line->addColumn(new ChatLineContentProxy(new FileTransferWidget(0, file), 380, 0.6f), ColumnFormat(1.0, ColumnFormat::VariableSize)); - line->addColumn(new Text(timestamp.toString("hh:mm"), Style::getFont(Style::Big)), ColumnFormat(50.0, ColumnFormat::FixedSize, ColumnFormat::Right)); + line->addColumn(new Text(timestamp.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); insertChatline(line); return line; @@ -569,7 +573,7 @@ void ChatLog::checkVisibility() // set visibilty QList newVisibleLines; - for(auto itr = upperBound; itr <= lowerBound && itr != lines.end(); ++itr) + for(auto itr = upperBound; itr <= lowerBound && itr != lines.cend(); ++itr) { newVisibleLines.append(*itr); diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 57c38cef3..cd68e923f 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -18,6 +18,8 @@ #include "content/text.h" #include "content/spinner.h" +#include "src/misc/settings.h" + #include ChatMessage::ChatMessage(QGraphicsScene* scene, const QString& rawMessage) @@ -30,7 +32,7 @@ ChatMessage::ChatMessage(QGraphicsScene* scene, const QString& rawMessage) void ChatMessage::markAsSent(const QDateTime &time) { // remove the spinner and replace it by $time - replaceContent(2, new Text(time.toString("hh:mm"))); + replaceContent(2, new Text(time.toString(Settings::getInstance().getTimestampFormat()))); } QString ChatMessage::toString() const From b76e9a295d5cb366ba928afa3023760818d30cea Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 2 Jan 2015 20:29:39 +0100 Subject: [PATCH 039/203] disabled group joined/left messages Conflicts: src/widget/widget.cpp --- src/widget/widget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 256fedd4b..3068ff1db 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -989,7 +989,7 @@ void Widget::onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t Cha // g->addPeer(peernumber,name); g->regeneratePeerList(); - //g->chatForm->addSystemInfoMessage(tr("%1 has joined the chat").arg(name), "green"); + // g->getChatForm()->addSystemInfoMessage(tr("%1 has joined the chat").arg(name), "white", QDateTime::currentDateTime()); // we can't display these messages until irungentoo fixes peernumbers // https://github.com/irungentoo/toxcore/issues/1128 } @@ -997,7 +997,7 @@ void Widget::onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t Cha { // g->removePeer(peernumber); g->regeneratePeerList(); - //g->chatForm->addSystemInfoMessage(tr("%1 has left the chat").arg(name), "silver"); + // g->getChatForm()->addSystemInfoMessage(tr("%1 has left the chat").arg(name), "white", QDateTime::currentDateTime()); } else if (change == TOX_CHAT_CHANGE_PEER_NAME) // core overwrites old name before telling us it changed... g->updatePeer(peernumber,core->getGroupPeerName(groupnumber, peernumber)); From 1945bcc1f6259275acee28b91e39a64ab3547eea Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 2 Jan 2015 20:35:28 +0100 Subject: [PATCH 040/203] don't use DesignMetrics --- src/chatlog/content/text.cpp | 2 -- src/chatlog/customtextdocument.cpp | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 7660af746..ac968fa1e 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -202,8 +202,6 @@ void Text::ensureIntegrity() if(!doc) { doc = new CustomTextDocument(); - doc->setUndoRedoEnabled(false); - doc->setUseDesignMetrics(true); doc->setDefaultFont(defFont); if(!elide) diff --git a/src/chatlog/customtextdocument.cpp b/src/chatlog/customtextdocument.cpp index e75dd4225..fa1d213c7 100644 --- a/src/chatlog/customtextdocument.cpp +++ b/src/chatlog/customtextdocument.cpp @@ -25,6 +25,8 @@ CustomTextDocument::CustomTextDocument(QObject *parent) : QTextDocument(parent) { setDefaultStyleSheet(Style::getStylesheet(":ui/chatArea/innerStyle.css")); + setUndoRedoEnabled(false); + setUseDesignMetrics(false); } QVariant CustomTextDocument::loadResource(int type, const QUrl &name) From 2ee1363be532a4a49ead049a7df950bc4c0b11bd Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 2 Jan 2015 20:37:51 +0100 Subject: [PATCH 041/203] don't set cache mode --- src/chatlog/content/text.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index ac968fa1e..55525281a 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -40,7 +40,7 @@ Text::Text(const QString& txt, QFont font, bool enableElide) ensureIntegrity(); freeResources(); - setCacheMode(QGraphicsItem::DeviceCoordinateCache); + //setCacheMode(QGraphicsItem::DeviceCoordinateCache); } Text::~Text() From 64e01164766f0d9ef2a0540bc2913870a1431d13 Mon Sep 17 00:00:00 2001 From: apprb Date: Sat, 3 Jan 2015 00:45:26 +0600 Subject: [PATCH 042/203] honouring aliases in the loaded history Conflicts: src/widget/form/chatform.cpp --- src/widget/form/chatform.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index e437635fd..a4606a682 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -717,9 +717,17 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) } // Show each messages - ToxID id = ToxID::fromString(it.sender); - ChatMessage* msg = chatWidget->addChatMessage(Core::getInstance()->getPeerName(id), it.message, id.isMine(), false); - if (it.isSent || !id.isMine()) + ToxID msgSender = ToxID::fromString(it.sender); + + bool isAction = it.message.startsWith("/me "); + ChatMessage* msg; + QString authorStr = (msgSender.isMine() ? Core::getInstance()->getUsername() : resolveToxID(msgSender)); + if (!isAction) + msg = chatWidget->addChatMessage(authorStr, it.message, msgSender.isMine(), false); + else + msg = chatWidget->addChatAction(authorStr, it.message.right(it.message.length() - 4)); + + if (it.isSent || !msgSender.isMine()) { msg->markAsSent(msgDateTime); } @@ -727,7 +735,11 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) { if (processUndelivered) { - int rec = Core::getInstance()->sendMessage(f->getFriendID(), msg->toString()); + int rec; + if (!isAction) + rec = Core::getInstance()->sendMessage(f->getFriendID(), msg->toString()); + else + rec = Core::getInstance()->sendAction(f->getFriendID(), msg->toString()); registerReceipt(rec, it.id, msg); } } From d88aa965fa993f70afc541a885f977a1ef87be55 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 3 Jan 2015 13:13:12 +0100 Subject: [PATCH 043/203] fixup merge --- res.qrc | 1 - src/widget/form/genericchatform.cpp | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/res.qrc b/res.qrc index 73b1f34d8..2623438f5 100644 --- a/res.qrc +++ b/res.qrc @@ -220,7 +220,6 @@ ui/videoButton/videoButtonYellow.png ui/videoButton/videoButtonYellowHover.png ui/videoButton/videoButtonYellowPressed.png - ui/fileTransferWidget/fileTransferWidget.css ui/fileTransferInstance/red.css ui/fileTransferInstance/green.css ui/fileTransferInstance/grey.css diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index 8612b5c0e..495156f70 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -211,7 +211,7 @@ ChatMessage* GenericChatForm::addSelfMessage(const QString &message, bool isActi void GenericChatForm::addAlertMessage(const ToxID &author, QString message, QDateTime datetime) { QString authorStr = Core::getInstance()->getPeerName(author); - chatWidget->addChatMessage(author != previousId ? authorStr : QString(), message, author.isMine(), true); + chatWidget->addChatMessage(author != previousId ? authorStr : QString(), message, datetime, author.isMine(), true); previousId = author; } @@ -250,8 +250,11 @@ void GenericChatForm::focusInput() void GenericChatForm::addSystemInfoMessage(const QString &message, const QString &type, const QDateTime &datetime) { + //TODO: respect type previousId.clear(); chatWidget->addSystemMessage(message, datetime); + + Q_UNUSED(type) } void GenericChatForm::clearChatArea(bool notinform) From f3d5b4bb57f9f4139c4b8ab0c86774ca9b3ea9ef Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 3 Jan 2015 13:20:53 +0100 Subject: [PATCH 044/203] fixed anchors --- src/chatlog/content/text.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 55525281a..b8783066b 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -51,9 +51,11 @@ Text::~Text() void Text::setText(const QString& txt) { text = txt; - text.replace("\n", "
"); detectAnchors(); + + text.replace("\n", "
"); + ensureIntegrity(); freeResources(); } From d7f5068fbfa09f638e96fe2c79561dabf5155da9 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 3 Jan 2015 13:52:56 +0100 Subject: [PATCH 045/203] quoting support, toHtmlChars, fixes --- src/chatlog/chatlog.cpp | 5 ++--- src/chatlog/content/text.cpp | 25 ++++++++++++++++++++++--- src/chatlog/content/text.h | 1 + 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 5c41d51f6..ef877ea0a 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -25,7 +25,6 @@ #include "content/spinner.h" #include "../misc/style.h" -#include "../misc/smileypack.h" #include "../misc/settings.h" #include @@ -86,7 +85,7 @@ ChatLog::~ChatLog() ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString &msg, bool self, bool alert) { - QString txt = SmileyPack::getInstance().smileyfied(msg); + QString txt = msg; if(alert) txt = "
" + txt + "
"; @@ -119,7 +118,7 @@ ChatMessage *ChatLog::addChatAction(const QString &sender, const QString &msg) { ChatMessage* line = new ChatMessage(scene, msg); line->addColumn(new Text(""), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - line->addColumn(new Text("
*" + sender + " " + SmileyPack::getInstance().smileyfied(msg) + "
", Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); + line->addColumn(new Text("
*" + sender + " " + msg + "
", Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); line->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); line->setAsAction(); diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index b8783066b..c07a453cf 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -17,6 +17,7 @@ #include "text.h" #include "../customtextdocument.h" +#include "src/misc/smileypack.h" #include #include @@ -50,11 +51,10 @@ Text::~Text() void Text::setText(const QString& txt) { - text = txt; + text = SmileyPack::getInstance().smileyfied(toHtmlChars(txt)); detectAnchors(); - - text.replace("\n", "
"); + detectQuotes(); ensureIntegrity(); freeResources(); @@ -287,6 +287,25 @@ void Text::detectAnchors() } } +void Text::detectQuotes() +{ + // detect text quotes + QStringList messageLines = text.split("\n"); + QString quotedText; + for (int i=0;i"; + else + quotedText += messageLines[i]; + + if (i < messageLines.size() - 1) + quotedText += "
"; + } + + text = quotedText; +} + QString Text::toHtmlChars(const QString &str) { static QList> replaceList = {{"&","&"}, {">",">"}, {"<","<"}}; diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index 8ef17499b..ef1deee67 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -62,6 +62,7 @@ protected: int cursorFromPos(QPointF scenePos) const; void detectAnchors(); + void detectQuotes(); QString toHtmlChars(const QString& str); private: From 8a1ea18ed4662a18033bc434b6bb138402ff87a7 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 3 Jan 2015 14:08:04 +0100 Subject: [PATCH 046/203] fixed history --- src/widget/form/chatform.cpp | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index a4606a682..5bad99d99 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -61,7 +61,7 @@ ChatForm::ChatForm(Friend* chatFriend) headTextLayout->addStretch(); callDuration = new QLabel(); headTextLayout->addWidget(callDuration, 1, Qt::AlignCenter); - callDuration->hide(); + callDuration->hide(); menu.addAction(tr("Load History..."), this, SLOT(onLoadHistory())); @@ -199,7 +199,7 @@ void ChatForm::onFileRecvRequest(ToxFile file) ChatMessage* msg = chatWidget->addFileTransferMessage(name, file, QDateTime::currentDateTime(), false); if (!Settings::getInstance().getAutoAcceptDir(f->getToxID()).isEmpty() - || Settings::getInstance().getAutoSaveEnabled()) + || Settings::getInstance().getAutoSaveEnabled()) { FileTransferWidget* tfWidget = dynamic_cast(msg->getContent(1)); if(tfWidget) @@ -255,7 +255,7 @@ void ChatForm::onAvStart(int FriendId, int CallId, bool video) callId = CallId; callButton->disconnect(); videoButton->disconnect(); - + if (video) { callButton->setObjectName("grey"); @@ -419,7 +419,7 @@ void ChatForm::onAvEnding(int FriendId, int) connect(videoButton, SIGNAL(clicked()), this, SLOT(onVideoCallTriggered())); netcam->hide(); - + stopCounter(); } @@ -526,7 +526,7 @@ void ChatForm::onAvMediaChange(int FriendId, int CallId, bool video) void ChatForm::onAnswerCallTriggered() { qDebug() << "onAnswerCallTriggered"; - + audioInputFlag = true; audioOutputFlag = true; emit answerCall(callId); @@ -703,7 +703,6 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) std::swap(storedPrevId, previousId); QList historyMessages; - //TODO: possibly broken QDate lastDate(1,0,0); for (const auto &it : msgs) { @@ -720,12 +719,11 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) ToxID msgSender = ToxID::fromString(it.sender); bool isAction = it.message.startsWith("/me "); - ChatMessage* msg; - QString authorStr = (msgSender.isMine() ? Core::getInstance()->getUsername() : resolveToxID(msgSender)); - if (!isAction) - msg = chatWidget->addChatMessage(authorStr, it.message, msgSender.isMine(), false); - else - msg = chatWidget->addChatAction(authorStr, it.message.right(it.message.length() - 4)); + + ChatMessage* msg = addMessage(msgSender, + isAction ? it.message.right(it.message.length() - 4) : it.message, + isAction, QDateTime::currentDateTime(), + false); if (it.isSent || !msgSender.isMine()) { @@ -747,15 +745,15 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) } std::swap(storedPrevId, previousId); -// int savedSliderPos = chatWidget->verticalScrollBar()->maximum() - chatWidget->verticalScrollBar()->value(); + // int savedSliderPos = chatWidget->verticalScrollBar()->maximum() - chatWidget->verticalScrollBar()->value(); -// if (earliestMessage != nullptr) -// *earliestMessage = since; + // if (earliestMessage != nullptr) + // *earliestMessage = since; -// chatWidget->insertMessagesTop(historyMessages); + // chatWidget->insertMessagesTop(historyMessages); -// savedSliderPos = chatWidget->verticalScrollBar()->maximum() - savedSliderPos; -// chatWidget->verticalScrollBar()->setValue(savedSliderPos); + // savedSliderPos = chatWidget->verticalScrollBar()->maximum() - savedSliderPos; + // chatWidget->verticalScrollBar()->setValue(savedSliderPos); } void ChatForm::onLoadHistory() @@ -786,7 +784,7 @@ void ChatForm::stopCounter() if (timer) { addSystemInfoMessage(tr("Call with %1 ended. %2").arg(f->getDisplayedName(),secondsToDHMS(timeElapsed.elapsed()/1000)), - "white", QDateTime::currentDateTime()); + "white", QDateTime::currentDateTime()); timer->stop(); callDuration->setText(""); callDuration->hide(); From 2938702c1e166a9d778cbe5484c7edcf324549a8 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 3 Jan 2015 15:03:33 +0100 Subject: [PATCH 047/203] refactoring, fixes --- src/chatlog/chatlog.cpp | 52 ++++------------ src/chatlog/chatmessage.cpp | 115 ++++++++++++++++++++++++++++++++++- src/chatlog/chatmessage.h | 13 +++- src/chatlog/content/text.cpp | 63 +------------------ src/chatlog/content/text.h | 4 -- 5 files changed, 139 insertions(+), 108 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index ef877ea0a..0f4a5c4b0 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -18,14 +18,6 @@ #include "chatline.h" #include "chatmessage.h" #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/settings.h" #include #include @@ -35,9 +27,6 @@ #include #include -#define NAME_COL_WIDTH 75.0 -#define TIME_COL_WIDTH 85.0 - template T clamp(T x, T min, T max) { @@ -85,66 +74,49 @@ ChatLog::~ChatLog() ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString &msg, bool self, bool alert) { - QString txt = msg; - if(alert) - txt = "
" + txt + "
"; - - ChatMessage* line = new ChatMessage(scene, msg); - line->addColumn(new Text(sender, self ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - line->addColumn(new Text(txt, Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); - line->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - + ChatMessage* line = ChatMessage::createChatMessage(scene, sender, msg, false, alert, self); insertChatline(line); + return line; } ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString& msg, const QDateTime& timestamp, bool self, bool alert) { - ChatMessage* line = addChatMessage(sender, msg, self, alert); - line->markAsSent(timestamp); + ChatMessage* line = ChatMessage::createChatMessage(scene, sender, msg, false, alert, self, timestamp); + insertChatline(line); return line; } ChatMessage *ChatLog::addChatAction(const QString &sender, const QString &msg, const QDateTime ×tamp) { - ChatMessage* line = addChatAction(sender, msg); - line->markAsSent(timestamp); + ChatMessage* line = ChatMessage::createChatMessage(scene, sender, msg, true, false, false, timestamp); + insertChatline(line); return line; } ChatMessage *ChatLog::addChatAction(const QString &sender, const QString &msg) { - ChatMessage* line = new ChatMessage(scene, msg); - line->addColumn(new Text(""), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - line->addColumn(new Text("
*" + sender + " " + msg + "
", Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); - line->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - line->setAsAction(); - + ChatMessage* line = ChatMessage::createChatMessage(scene, sender, msg, true, false, false); insertChatline(line); + return line; } ChatMessage *ChatLog::addSystemMessage(const QString &msg, const QDateTime& timestamp) { - ChatMessage* line = new ChatMessage(scene, msg); - line->addColumn(new Image(QSizeF(16, 16), ":/ui/chatArea/info.png"), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - line->addColumn(new Text(msg, Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); - line->addColumn(new Text(timestamp.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - + ChatMessage* line = ChatMessage::createChatInfoMessage(scene, msg, "", timestamp); insertChatline(line); + return line; } ChatMessage *ChatLog::addFileTransferMessage(const QString &sender, const ToxFile &file, const QDateTime& timestamp, bool self) { - ChatMessage* line = new ChatMessage(scene, QString()); - line->addColumn(new Text(sender, self ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - line->addColumn(new ChatLineContentProxy(new FileTransferWidget(0, file), 380, 0.6f), ColumnFormat(1.0, ColumnFormat::VariableSize)); - line->addColumn(new Text(timestamp.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - + ChatMessage* line = ChatMessage::createFileTransferMessage(scene, sender, "", file, self, timestamp); insertChatline(line); + return line; } diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index cd68e923f..c75d6092a 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -15,12 +15,18 @@ */ #include "chatmessage.h" +#include "chatlinecontentproxy.h" #include "content/text.h" #include "content/spinner.h" +#include "content/filetransferwidget.h" +#include "content/image.h" #include "src/misc/settings.h" +#include "src/misc/smileypack.h" +#include "src/misc/style.h" -#include +#define NAME_COL_WIDTH 75.0 +#define TIME_COL_WIDTH 85.0 ChatMessage::ChatMessage(QGraphicsScene* scene, const QString& rawMessage) : ChatLine(scene) @@ -29,6 +35,52 @@ ChatMessage::ChatMessage(QGraphicsScene* scene, const QString& rawMessage) } +ChatMessage *ChatMessage::createChatMessage(QGraphicsScene *scene, const QString &sender, const QString &rawMessage, bool isAction, bool alert, bool isMe, const QDateTime &date) +{ + ChatMessage* msg = new ChatMessage(scene, rawMessage); + + QString text = detectQuotes(detectAnchors(SmileyPack::getInstance().smileyfied(toHtmlChars(rawMessage)))); + + if(isAction) + { + text = QString("
%1 %2
").arg(sender, text); + msg->setAsAction(); + } + else if(alert) + text = "
" + text + "
"; + + msg->addColumn(new Text(isAction ? "*" : sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + msg->addColumn(new Text(text, Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); + msg->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + + if(!date.isNull()) + msg->markAsSent(date); + + return msg; +} + +ChatMessage *ChatMessage::createChatInfoMessage(QGraphicsScene *scene, const QString &rawMessage, const QString &type, const QDateTime &date) +{ + ChatMessage* msg = new ChatMessage(scene, rawMessage); + + msg->addColumn(new Image(QSizeF(16, 16), ":/ui/chatArea/info.png"), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + msg->addColumn(new Text(rawMessage, Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); + msg->addColumn(new Text(date.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + + return msg; +} + +ChatMessage *ChatMessage::createFileTransferMessage(QGraphicsScene* scene, const QString& sender, const QString& rawMessage, ToxFile file, bool isMe, const QDateTime& date) +{ + ChatMessage* msg = new ChatMessage(scene, rawMessage); + + msg->addColumn(new Text(sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + msg->addColumn(new ChatLineContentProxy(new FileTransferWidget(0, file), 380, 0.6f), ColumnFormat(1.0, ColumnFormat::VariableSize)); + msg->addColumn(new Text(date.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + + return msg; +} + void ChatMessage::markAsSent(const QDateTime &time) { // remove the spinner and replace it by $time @@ -49,3 +101,64 @@ void ChatMessage::setAsAction() { action = true; } + +QString ChatMessage::detectAnchors(const QString &str) +{ + QString out = str; + + // detect urls + QRegExp exp("(?:\\b)(www\\.|http[s]?:\\/\\/|ftp:\\/\\/|tox:\\/\\/|tox:)\\S+"); + int offset = 0; + while ((offset = exp.indexIn(out, offset)) != -1) + { + QString url = exp.cap(); + + // If there's a trailing " it's a HTML attribute, e.g. a smiley img's title=":tox:" + if (url == "tox:\"") + { + offset += url.length(); + continue; + } + + // add scheme if not specified + if (exp.cap(1) == "www.") + url.prepend("http://"); + + QString htmledUrl = QString("%1").arg(url); + out.replace(offset, exp.cap().length(), htmledUrl); + + offset += htmledUrl.length(); + } + + return out; +} + +QString ChatMessage::detectQuotes(const QString& str) +{ + // detect text quotes + QStringList messageLines = str.split("\n"); + QString quotedText; + for (int i=0;i"; + else + quotedText += messageLines[i]; + + if (i < messageLines.size() - 1) + quotedText += "
"; + } + + return quotedText; +} + +QString ChatMessage::toHtmlChars(const QString &str) +{ + static QList> replaceList = {{"&","&"}, {">",">"}, {"<","<"}}; + QString res = str; + + for (auto &it : replaceList) + res = res.replace(it.first,it.second); + + return res; +} diff --git a/src/chatlog/chatmessage.h b/src/chatlog/chatmessage.h index 9e4b2a27e..86b28a91c 100644 --- a/src/chatlog/chatmessage.h +++ b/src/chatlog/chatmessage.h @@ -18,19 +18,30 @@ #define CHATMESSAGE_H #include "chatline.h" +#include "src/corestructs.h" +#include class QGraphicsScene; class ChatMessage : public ChatLine { public: - ChatMessage(QGraphicsScene* scene, const QString& rawMessage); + ChatMessage(QGraphicsScene* scene, const QString& rawMessage); + + static ChatMessage* createChatMessage(QGraphicsScene* scene, const QString& sender, const QString& rawMessage, bool isAction, bool alert, bool isMe, const QDateTime& date = QDateTime()); + static ChatMessage* createChatInfoMessage(QGraphicsScene* scene, const QString& rawMessage, const QString& type, const QDateTime& date); + static ChatMessage* createFileTransferMessage(QGraphicsScene* scene, const QString& sender, const QString& rawMessage, ToxFile file, bool isMe, const QDateTime& date); void markAsSent(const QDateTime& time); QString toString() const; bool isAction() const; void setAsAction(); +protected: + static QString detectAnchors(const QString& str); + static QString detectQuotes(const QString& str); + static QString toHtmlChars(const QString& str); + private: ChatLineContent* midColumn = nullptr; QString rawString; diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index c07a453cf..29493e50c 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -17,7 +17,6 @@ #include "text.h" #include "../customtextdocument.h" -#include "src/misc/smileypack.h" #include #include @@ -51,10 +50,7 @@ Text::~Text() void Text::setText(const QString& txt) { - text = SmileyPack::getInstance().smileyfied(toHtmlChars(txt)); - - detectAnchors(); - detectQuotes(); + text = txt; ensureIntegrity(); freeResources(); @@ -259,60 +255,3 @@ int Text::cursorFromPos(QPointF scenePos) const return -1; } - -void Text::detectAnchors() -{ - // detect urls - QRegExp exp("(?:\\b)(www\\.|http[s]?:\\/\\/|ftp:\\/\\/|tox:\\/\\/|tox:)\\S+"); - int offset = 0; - while ((offset = exp.indexIn(text, offset)) != -1) - { - QString url = exp.cap(); - - // If there's a trailing " it's a HTML attribute, e.g. a smiley img's title=":tox:" - if (url == "tox:\"") - { - offset += url.length(); - continue; - } - - // add scheme if not specified - if (exp.cap(1) == "www.") - url.prepend("http://"); - - QString htmledUrl = QString("%1").arg(url); - text.replace(offset, exp.cap().length(), htmledUrl); - - offset += htmledUrl.length(); - } -} - -void Text::detectQuotes() -{ - // detect text quotes - QStringList messageLines = text.split("\n"); - QString quotedText; - for (int i=0;i"; - else - quotedText += messageLines[i]; - - if (i < messageLines.size() - 1) - quotedText += "
"; - } - - text = quotedText; -} - -QString Text::toHtmlChars(const QString &str) -{ - static QList> replaceList = {{"&","&"}, {">",">"}, {"<","<"}}; - QString res = str; - - for (auto &it : replaceList) - res = res.replace(it.first,it.second); - - return res; -} diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index ef1deee67..7acc156cd 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -61,10 +61,6 @@ protected: int cursorFromPos(QPointF scenePos) const; - void detectAnchors(); - void detectQuotes(); - QString toHtmlChars(const QString& str); - private: CustomTextDocument* doc = nullptr; QString text; From a0a56e32a0fcf333dbf720d46dbf4378a352e7fa Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 3 Jan 2015 15:32:12 +0100 Subject: [PATCH 048/203] fix no visible line case --- src/chatlog/chatlog.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 0f4a5c4b0..f0c3bb744 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -192,15 +192,15 @@ void ChatLog::partialUpdate() { repos = false; if(!visibleLines.empty()) - { repos = layout(visibleLines.first()->getRowIndex(), visibleLines.last()->getRowIndex(), useableWidth()); - } checkVisibility(); } while(repos); - reposition(visibleLines.last()->getRowIndex(), lines.size()); + if(!visibleLines.empty()) + reposition(visibleLines.last()->getRowIndex(), lines.size()); + checkVisibility(); setViewportUpdateMode(oldUpdateMode); @@ -530,7 +530,14 @@ void ChatLog::checkVisibility() }); if(upperBound == lines.end()) - upperBound = lines.begin(); + { + //no lines visible + for(ChatLine* line : visibleLines) + line->visibilityChanged(false); + + visibleLines.clear(); + return; + } // find last visible row QList::const_iterator lowerBound; @@ -539,9 +546,6 @@ void ChatLog::checkVisibility() return lhs->boundingSceneRect().bottom() < rhs; }); - if(lowerBound == lines.end()) - lowerBound = lines.end(); - // set visibilty QList newVisibleLines; for(auto itr = upperBound; itr <= lowerBound && itr != lines.cend(); ++itr) From 698fcb70f00474a64502443600edbef02769941c Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 3 Jan 2015 19:05:38 +0100 Subject: [PATCH 049/203] check "use emoticons" --- src/chatlog/chatmessage.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index c75d6092a..c75411b11 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -39,7 +39,12 @@ ChatMessage *ChatMessage::createChatMessage(QGraphicsScene *scene, const QString { ChatMessage* msg = new ChatMessage(scene, rawMessage); - QString text = detectQuotes(detectAnchors(SmileyPack::getInstance().smileyfied(toHtmlChars(rawMessage)))); + QString text = toHtmlChars(rawMessage); + + if(Settings::getInstance().getUseEmoticons()) + text = SmileyPack::getInstance().smileyfied(text); + + text = detectQuotes(detectAnchors(text)); if(isAction) { From 99a230ccf58e94023671bf1ca4fe1dc8b6a88e0d Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 3 Jan 2015 19:06:10 +0100 Subject: [PATCH 050/203] cleanup --- src/chatlog/chatmessage.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index c75411b11..9bd4c831f 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -52,7 +52,9 @@ ChatMessage *ChatMessage::createChatMessage(QGraphicsScene *scene, const QString msg->setAsAction(); } else if(alert) + { text = "
" + text + "
"; + } msg->addColumn(new Text(isAction ? "*" : sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text(text, Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); From d04a79a599ee5c89ea88d8ceef3021d974ee3f29 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 3 Jan 2015 20:37:40 +0100 Subject: [PATCH 051/203] ChatLine: cell spacing --- src/chatlog/chatline.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index 0ae8c8e61..a1484401c 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -22,6 +22,8 @@ #include #include +#define CELL_SPACING 15 + ChatLine::ChatLine(QGraphicsScene* grScene) : scene(grScene) { @@ -148,7 +150,7 @@ void ChatLine::layout(qreal w, QPointF scenePos) width = w; pos = scenePos; - qreal fixedWidth = 0.0; + qreal fixedWidth = (content.size()-1) * CELL_SPACING; qreal varWidth = 0.0; // used for normalisation for(int i = 0; i < format.size(); ++i) @@ -183,6 +185,7 @@ void ChatLine::layout(qreal w, QPointF scenePos) // calculate horizontal alignment qreal xAlign = 0.0; + switch(format[i].hAlign) { case ColumnFormat::Right: @@ -198,7 +201,7 @@ void ChatLine::layout(qreal w, QPointF scenePos) // reposition content[i]->setPos(pos.x() + xOffset + xAlign, pos.y()); - xOffset += width; + xOffset += width + CELL_SPACING; } for(int i = 0; i < content.size(); ++i) From 64f7f7c45ebb34d1e553c87c5b27b84a708b5035 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 3 Jan 2015 20:38:06 +0100 Subject: [PATCH 052/203] use resolveToxID --- src/widget/form/genericchatform.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index 495156f70..58e593f85 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -186,7 +186,7 @@ void GenericChatForm::onChatContextMenuRequested(QPoint pos) ChatMessage* GenericChatForm::addMessage(const ToxID& author, const QString &message, bool isAction, const QDateTime &datetime, bool isSent) { - QString authorStr = (author.isMine() ? Core::getInstance()->getUsername() : Core::getInstance()->getPeerName(author)); + QString authorStr = author.isMine() ? Core::getInstance()->getUsername() : resolveToxID(author); ChatMessage* msg = nullptr; if(isAction) @@ -210,7 +210,7 @@ ChatMessage* GenericChatForm::addSelfMessage(const QString &message, bool isActi void GenericChatForm::addAlertMessage(const ToxID &author, QString message, QDateTime datetime) { - QString authorStr = Core::getInstance()->getPeerName(author); + QString authorStr = resolveToxID(author); chatWidget->addChatMessage(author != previousId ? authorStr : QString(), message, datetime, author.isMine(), true); previousId = author; From b3507152eb25775cbc9c631bca3e7eca9433d491 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 3 Jan 2015 21:19:28 +0100 Subject: [PATCH 053/203] fixed eliding (ie. invisible nicknames) --- src/chatlog/content/text.cpp | 21 +++++++++++++-------- src/chatlog/content/text.h | 1 + 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 29493e50c..dddbd74f2 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -51,6 +50,7 @@ Text::~Text() void Text::setText(const QString& txt) { text = txt; + dirty = true; ensureIntegrity(); freeResources(); @@ -65,10 +65,13 @@ void Text::setWidth(qreal w) if(elide) { - QFontMetrics metrics = QFontMetrics(QFont()); + QFontMetrics metrics = QFontMetrics(defFont); elidedText = metrics.elidedText(text, Qt::ElideRight, width); + dirty = true; } + size = idealSize(); + ensureIntegrity(); freeResources(); } @@ -168,6 +171,8 @@ void Text::visibilityChanged(bool visible) ensureIntegrity(); else freeResources(); + + update(); } qreal Text::getAscent() const @@ -197,7 +202,7 @@ QString Text::getText() const void Text::ensureIntegrity() { - if(!doc) + if(!doc || dirty) { doc = new CustomTextDocument(); doc->setDefaultFont(defFont); @@ -215,6 +220,7 @@ void Text::ensureIntegrity() } cursor = QTextCursor(doc); + dirty = false; } doc->setTextWidth(width); @@ -224,10 +230,9 @@ void Text::ensureIntegrity() vOffset = doc->firstBlock().layout()->lineAt(0).ascent(); if(size != idealSize()) - { prepareGeometryChange(); - size = idealSize(); - } + + size = idealSize(); } void Text::freeResources() @@ -243,9 +248,9 @@ void Text::freeResources() QSizeF Text::idealSize() { if(doc) - return QSizeF(doc->idealWidth(), doc->size().height()); + return QSizeF(qMin(doc->idealWidth(), width), doc->size().height()); - return QSizeF(); + return size; } int Text::cursorFromPos(QPointF scenePos) const diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index 7acc156cd..e21e664ab 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -69,6 +69,7 @@ private: QSizeF size; bool isVisible = false; bool elide = false; + bool dirty = false; QTextCursor cursor; qreal vOffset = 0.0; qreal width = 0.0; From f630583e59d767424a16237bd87b6603d51b7124 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 3 Jan 2015 21:19:52 +0100 Subject: [PATCH 054/203] cleanup --- src/chatlog/chatlog.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index f0c3bb744..0d550e1ed 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -48,7 +48,7 @@ ChatLog::ChatLog(QWidget* parent) setAlignment(Qt::AlignTop | Qt::AlignLeft); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setDragMode(QGraphicsView::NoDrag); - setViewportUpdateMode(SmartViewportUpdate); + setViewportUpdateMode(BoundingRectViewportUpdate); //setRenderHint(QPainter::TextAntialiasing); setAcceptDrops(false); @@ -522,6 +522,9 @@ void ChatLog::copySelectedText() const void ChatLog::checkVisibility() { + if(lines.empty()) + return; + // find first visible row QList::const_iterator upperBound; upperBound = std::upper_bound(lines.cbegin(), lines.cend(), getVisibleRect().top(), [](const qreal lhs, const ChatLine* rhs) @@ -529,26 +532,16 @@ void ChatLog::checkVisibility() return lhs < rhs->boundingSceneRect().bottom(); }); - if(upperBound == lines.end()) - { - //no lines visible - for(ChatLine* line : visibleLines) - line->visibilityChanged(false); - - visibleLines.clear(); - return; - } - // find last visible row QList::const_iterator lowerBound; lowerBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().bottom(), [](const ChatLine* lhs, const qreal rhs) { - return lhs->boundingSceneRect().bottom() < rhs; + return lhs->boundingSceneRect().top() < rhs; }); // set visibilty QList newVisibleLines; - for(auto itr = upperBound; itr <= lowerBound && itr != lines.cend(); ++itr) + for(auto itr = upperBound; itr != lowerBound; ++itr) { newVisibleLines.append(*itr); From ea467152aa152bd8c98cdfb06332a37f65e7e99f Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 4 Jan 2015 12:04:30 +0100 Subject: [PATCH 055/203] filetransferwidget: fixed pause button, ETA, font size, resource usage --- src/chatlog/content/filetransferwidget.cpp | 69 ++++++++++++---------- ui/fileTransferInstance/green.css | 1 + ui/fileTransferInstance/red.css | 1 + ui/fileTransferInstance/yellow.css | 1 + 4 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index d1f49ebd6..a89249d01 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -91,38 +91,44 @@ void FileTransferWidget::onFileTransferInfo(ToxFile file) fileInfo = file; - // update progress - qreal progress = static_cast(file.bytesSent) / static_cast(file.filesize); - ui->progressBar->setValue(static_cast(progress * 100.0)); - - // eta, speed - QTime now = QTime::currentTime(); - qreal deltaSecs = lastTick.msecsTo(now) / 1000.0; - - if(deltaSecs >= 1.0) + if(fileInfo.status == ToxFile::TRANSMITTING) { - qint64 deltaBytes = file.bytesSent - lastBytesSent; - qint64 bytesPerSec = static_cast(static_cast(deltaBytes) / deltaSecs); + // update progress + qreal progress = static_cast(file.bytesSent) / static_cast(file.filesize); + ui->progressBar->setValue(static_cast(progress * 100.0)); - if(bytesPerSec > 0) + // eta, speed + QTime now = QTime::currentTime(); + qreal deltaSecs = lastTick.msecsTo(now) / 1000.0; + + if(deltaSecs >= 1.0) { - QTime toGo(0,0,file.filesize / bytesPerSec); - ui->etaLabel->setText(toGo.toString("mm:ss")); - } - else - { - ui->etaLabel->setText("--:--"); - } + qint64 deltaBytes = file.bytesSent - lastBytesSent; + qint64 bytesPerSec = static_cast(static_cast(deltaBytes) / deltaSecs); - ui->progressLabel->setText(getHumanReadableSize(bytesPerSec) + "/s"); + if(bytesPerSec > 0) + { + QTime toGo = QTime(0,0).addSecs(file.filesize / bytesPerSec); + ui->etaLabel->setText(toGo.toString("mm:ss")); + } + else + { + ui->etaLabel->setText("--:--"); + } - lastTick = now; - lastBytesSent = file.bytesSent; + ui->progressLabel->setText(getHumanReadableSize(bytesPerSec) + "/s"); + + lastTick = now; + lastBytesSent = file.bytesSent; + } + } + else if(fileInfo.status == ToxFile::PAUSED) + { + ui->etaLabel->setText("--:--"); + ui->progressLabel->setText(getHumanReadableSize(0) + "/s"); } - setupButtons(); - - repaint(); + update(); } void FileTransferWidget::onFileTransferAccepted(ToxFile file) @@ -161,6 +167,9 @@ void FileTransferWidget::onFileTransferPaused(ToxFile file) fileInfo = file; + ui->etaLabel->setText("--:--"); + ui->progressLabel->setText(getHumanReadableSize(0) + "/s"); + setStyleSheet(Style::getStylesheet(":/ui/fileTransferInstance/grey.css")); Style::repolish(this); @@ -254,20 +263,20 @@ void FileTransferWidget::handleButton(QPushButton *btn) { if(btn->objectName() == "cancel") Core::getInstance()->cancelFileSend(fileInfo.friendId, fileInfo.fileNum); - if(btn->objectName() == "pause") + else if(btn->objectName() == "pause") Core::getInstance()->pauseResumeFileSend(fileInfo.friendId, fileInfo.fileNum); - if(btn->objectName() == "resume") + else if(btn->objectName() == "resume") Core::getInstance()->pauseResumeFileSend(fileInfo.friendId, fileInfo.fileNum); } else { if(btn->objectName() == "cancel") Core::getInstance()->cancelFileRecv(fileInfo.friendId, fileInfo.fileNum); - if(btn->objectName() == "pause") + else if(btn->objectName() == "pause") Core::getInstance()->pauseResumeFileRecv(fileInfo.friendId, fileInfo.fileNum); - if(btn->objectName() == "resume") + else if(btn->objectName() == "resume") Core::getInstance()->pauseResumeFileRecv(fileInfo.friendId, fileInfo.fileNum); - if(btn->objectName() == "accept") + else if(btn->objectName() == "accept") { QString path = QFileDialog::getSaveFileName(0, tr("Save a file","Title of the file saving dialog"), QDir::home().filePath(fileInfo.fileName)); acceptTransfer(path); diff --git a/ui/fileTransferInstance/green.css b/ui/fileTransferInstance/green.css index 2b89105bf..f7aa6464d 100644 --- a/ui/fileTransferInstance/green.css +++ b/ui/fileTransferInstance/green.css @@ -8,6 +8,7 @@ QFrame { QLabel { color:white; + font:@medium; } QPushButton { diff --git a/ui/fileTransferInstance/red.css b/ui/fileTransferInstance/red.css index 979849db4..a50c94a59 100644 --- a/ui/fileTransferInstance/red.css +++ b/ui/fileTransferInstance/red.css @@ -8,6 +8,7 @@ QFrame { QLabel { color:white; + font:@medium; } QPushButton { diff --git a/ui/fileTransferInstance/yellow.css b/ui/fileTransferInstance/yellow.css index a9bd670f2..a460e35ef 100644 --- a/ui/fileTransferInstance/yellow.css +++ b/ui/fileTransferInstance/yellow.css @@ -8,6 +8,7 @@ QFrame { QLabel { color:black; + font:@medium; } QPushButton { From 03ea61079bdebb5d07039034a0b11be9e5570054 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 4 Jan 2015 13:29:14 +0100 Subject: [PATCH 056/203] ChatLine/ChatMessage: use shared_ptr --- src/chatlog/chatline.cpp | 13 +++++- src/chatlog/chatline.h | 7 ++- src/chatlog/chatlog.cpp | 71 ++++++++++++++--------------- src/chatlog/chatlog.h | 23 +++++----- src/chatlog/chatmessage.cpp | 14 +++--- src/chatlog/chatmessage.h | 8 ++-- src/widget/form/chatform.cpp | 12 ++--- src/widget/form/chatform.h | 4 +- src/widget/form/genericchatform.cpp | 6 +-- src/widget/form/genericchatform.h | 4 +- 10 files changed, 91 insertions(+), 71 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index a1484401c..18231e244 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -34,7 +34,9 @@ ChatLine::~ChatLine() { for(ChatLineContent* c : content) { - scene->removeItem(c); + if(c->scene()) + scene->removeItem(c); + delete c; } } @@ -71,6 +73,15 @@ ChatLineContent *ChatLine::getContent(int col) const return nullptr; } +void ChatLine::removeFromScene() +{ + for(ChatLineContent* c : content) + { + if(c->scene()) + scene->removeItem(c); + } +} + void ChatLine::selectionCleared() { for(ChatLineContent* c : content) diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index a5cda1e4d..69450a9a7 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -17,7 +17,8 @@ #ifndef CHATLINE_H #define CHATLINE_H -#include +#include +#include class ChatLog; class ChatLineContent; @@ -54,6 +55,8 @@ using ColumnFormats = QVector; class ChatLine { public: + using Ptr = std::shared_ptr; + explicit ChatLine(QGraphicsScene* scene); virtual ~ChatLine(); @@ -76,6 +79,8 @@ public: bool isOverSelection(QPointF scenePos); + void removeFromScene(); + private: QPointF mapToContent(ChatLineContent* c, QPointF pos); void updateBBox(); diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 0d550e1ed..089a70eb1 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -15,7 +15,6 @@ */ #include "chatlog.h" -#include "chatline.h" #include "chatmessage.h" #include "chatlinecontent.h" @@ -68,54 +67,53 @@ ChatLog::ChatLog(QWidget* parent) ChatLog::~ChatLog() { - for(ChatLine* line : lines) - delete line; + } -ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString &msg, bool self, bool alert) +ChatMessage::Ptr ChatLog::addChatMessage(const QString& sender, const QString &msg, bool self, bool alert) { - ChatMessage* line = ChatMessage::createChatMessage(scene, sender, msg, false, alert, self); - insertChatline(line); + ChatMessage::Ptr line = ChatMessage::createChatMessage(scene, sender, msg, false, alert, self); + insertChatline(std::dynamic_pointer_cast(line)); return line; } -ChatMessage* ChatLog::addChatMessage(const QString& sender, const QString& msg, const QDateTime& timestamp, bool self, bool alert) +ChatMessage::Ptr ChatLog::addChatMessage(const QString& sender, const QString& msg, const QDateTime& timestamp, bool self, bool alert) { - ChatMessage* line = ChatMessage::createChatMessage(scene, sender, msg, false, alert, self, timestamp); - insertChatline(line); + ChatMessage::Ptr line = ChatMessage::createChatMessage(scene, sender, msg, false, alert, self, timestamp); + insertChatline(std::dynamic_pointer_cast(line)); return line; } -ChatMessage *ChatLog::addChatAction(const QString &sender, const QString &msg, const QDateTime ×tamp) +ChatMessage::Ptr ChatLog::addChatAction(const QString &sender, const QString &msg, const QDateTime ×tamp) { - ChatMessage* line = ChatMessage::createChatMessage(scene, sender, msg, true, false, false, timestamp); - insertChatline(line); + ChatMessage::Ptr line = ChatMessage::createChatMessage(scene, sender, msg, true, false, false, timestamp); + insertChatline(std::dynamic_pointer_cast(line)); return line; } -ChatMessage *ChatLog::addChatAction(const QString &sender, const QString &msg) +ChatMessage::Ptr ChatLog::addChatAction(const QString &sender, const QString &msg) { - ChatMessage* line = ChatMessage::createChatMessage(scene, sender, msg, true, false, false); - insertChatline(line); + ChatMessage::Ptr line = ChatMessage::createChatMessage(scene, sender, msg, true, false, false); + insertChatline(std::dynamic_pointer_cast(line)); return line; } -ChatMessage *ChatLog::addSystemMessage(const QString &msg, const QDateTime& timestamp) +ChatMessage::Ptr ChatLog::addSystemMessage(const QString &msg, const QDateTime& timestamp) { - ChatMessage* line = ChatMessage::createChatInfoMessage(scene, msg, "", timestamp); - insertChatline(line); + ChatMessage::Ptr line = ChatMessage::createChatInfoMessage(scene, msg, "", timestamp); + insertChatline(std::dynamic_pointer_cast(line)); return line; } -ChatMessage *ChatLog::addFileTransferMessage(const QString &sender, const ToxFile &file, const QDateTime& timestamp, bool self) +ChatMessage::Ptr ChatLog::addFileTransferMessage(const QString &sender, const ToxFile &file, const QDateTime& timestamp, bool self) { - ChatMessage* line = ChatMessage::createFileTransferMessage(scene, sender, "", file, self, timestamp); - insertChatline(line); + ChatMessage::Ptr line = ChatMessage::createFileTransferMessage(scene, sender, "", file, self, timestamp); + insertChatline(std::dynamic_pointer_cast(line)); return line; } @@ -159,7 +157,7 @@ bool ChatLog::layout(int start, int end, qreal width) bool needsReposition = false; for(int i = start; i < end; ++i) { - ChatLine* l = lines[i]; + ChatLine* l = lines[i].get(); qreal oldHeight = l->boundingSceneRect().height(); l->layout(width, QPointF(0.0, h)); @@ -352,7 +350,7 @@ void ChatLog::reposition(int start, int end) for(int i = start + 1; i < end; ++i) { - ChatLine* l = lines[i]; + ChatLine* l = lines[i].get(); l->layout(QPointF(0, h)); h += l->boundingSceneRect().height() + lineSpacing; } @@ -369,7 +367,7 @@ void ChatLog::repositionDownTo(int start, qreal end) for(int i = start + 1; i < lines.size(); ++i) { - ChatLine* l = lines[i]; + ChatLine* l = lines[i].get(); l->layout(QPointF(0, h)); h += l->boundingSceneRect().height() + lineSpacing; @@ -378,7 +376,7 @@ void ChatLog::repositionDownTo(int start, qreal end) } } -void ChatLog::insertChatline(ChatLine* l) +void ChatLog::insertChatline(ChatLine::Ptr l) { stickToBtm = stickToBottom(); @@ -442,7 +440,7 @@ QString ChatLog::toPlainText() const QString out; QString lastSender; - for(ChatLine* l : lines) + for(ChatLine::Ptr l : lines) { if(lastSender != l->content[0]->getText() && !l->content[0]->getText().isEmpty()) { @@ -502,13 +500,14 @@ void ChatLog::showContextMenu(const QPoint& globalPos, const QPointF& scenePos) void ChatLog::clear() { - visibleLines.clear(); clearSelection(); - for(ChatLine* line : lines) - delete line; + for(ChatLine::Ptr l : lines) + l->removeFromScene(); lines.clear(); + visibleLines.clear(); + updateSceneRect(); } @@ -526,21 +525,21 @@ void ChatLog::checkVisibility() return; // find first visible row - QList::const_iterator upperBound; - upperBound = std::upper_bound(lines.cbegin(), lines.cend(), getVisibleRect().top(), [](const qreal lhs, const ChatLine* rhs) + QList::const_iterator upperBound; + upperBound = std::upper_bound(lines.cbegin(), lines.cend(), getVisibleRect().top(), [](const qreal lhs, const ChatLine::Ptr rhs) { return lhs < rhs->boundingSceneRect().bottom(); }); // find last visible row - QList::const_iterator lowerBound; - lowerBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().bottom(), [](const ChatLine* lhs, const qreal rhs) + QList::const_iterator lowerBound; + lowerBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().bottom(), [](const ChatLine::Ptr lhs, const qreal rhs) { return lhs->boundingSceneRect().top() < rhs; }); // set visibilty - QList newVisibleLines; + QList newVisibleLines; for(auto itr = upperBound; itr != lowerBound; ++itr) { newVisibleLines.append(*itr); @@ -551,13 +550,13 @@ void ChatLog::checkVisibility() visibleLines.removeOne(*itr); } - for(ChatLine* line : visibleLines) + for(ChatLine::Ptr line : visibleLines) line->visibilityChanged(false); visibleLines = newVisibleLines; // assure order - std::sort(visibleLines.begin(), visibleLines.end(), [](const ChatLine* lhs, const ChatLine* rhs) + std::sort(visibleLines.begin(), visibleLines.end(), [](const ChatLine::Ptr lhs, const ChatLine::Ptr rhs) { return lhs->getRowIndex() < rhs->getRowIndex(); }); diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 714ec9963..9052b31a5 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -21,11 +21,12 @@ #include #include +#include "chatline.h" +#include "chatmessage.h" + class QGraphicsScene; class QGraphicsRectItem; -class ChatLine; class ChatLineContent; -class ChatMessage; class ToxFile; class ChatLog : public QGraphicsView @@ -35,15 +36,15 @@ public: explicit ChatLog(QWidget* parent = 0); virtual ~ChatLog(); - ChatMessage* addChatMessage(const QString& sender, const QString& msg, const QDateTime& timestamp, bool self, bool alert); - ChatMessage* addChatMessage(const QString& sender, const QString& msg, bool self, bool alert); - ChatMessage* addChatAction(const QString& sender, const QString& msg, const QDateTime& timestamp); - ChatMessage* addChatAction(const QString& sender, const QString& msg); + ChatMessage::Ptr addChatMessage(const QString& sender, const QString& msg, const QDateTime& timestamp, bool self, bool alert); + ChatMessage::Ptr addChatMessage(const QString& sender, const QString& msg, bool self, bool alert); + ChatMessage::Ptr addChatAction(const QString& sender, const QString& msg, const QDateTime& timestamp); + ChatMessage::Ptr addChatAction(const QString& sender, const QString& msg); - ChatMessage* addSystemMessage(const QString& msg, const QDateTime& timestamp); - ChatMessage* addFileTransferMessage(const QString& sender, const ToxFile& file, const QDateTime ×tamp, bool self); + ChatMessage::Ptr addSystemMessage(const QString& msg, const QDateTime& timestamp); + ChatMessage::Ptr addFileTransferMessage(const QString& sender, const ToxFile& file, const QDateTime ×tamp, bool self); - void insertChatline(ChatLine* l); + void insertChatline(ChatLine::Ptr l); void clearSelection(); void clear(); @@ -88,8 +89,8 @@ private: }; QGraphicsScene* scene = nullptr; - QList lines; - QList visibleLines; + QList lines; + QList visibleLines; bool multiLineInsert = false; bool stickToBtm = false; diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 9bd4c831f..748c59a3b 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -35,9 +35,9 @@ ChatMessage::ChatMessage(QGraphicsScene* scene, const QString& rawMessage) } -ChatMessage *ChatMessage::createChatMessage(QGraphicsScene *scene, const QString &sender, const QString &rawMessage, bool isAction, bool alert, bool isMe, const QDateTime &date) +ChatMessage::Ptr ChatMessage::createChatMessage(QGraphicsScene *scene, const QString &sender, const QString &rawMessage, bool isAction, bool alert, bool isMe, const QDateTime &date) { - ChatMessage* msg = new ChatMessage(scene, rawMessage); + ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage(scene, rawMessage)); QString text = toHtmlChars(rawMessage); @@ -66,20 +66,22 @@ ChatMessage *ChatMessage::createChatMessage(QGraphicsScene *scene, const QString return msg; } -ChatMessage *ChatMessage::createChatInfoMessage(QGraphicsScene *scene, const QString &rawMessage, const QString &type, const QDateTime &date) +ChatMessage::Ptr ChatMessage::createChatInfoMessage(QGraphicsScene *scene, const QString &rawMessage, const QString &type, const QDateTime &date) { - ChatMessage* msg = new ChatMessage(scene, rawMessage); + ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage(scene, rawMessage)); msg->addColumn(new Image(QSizeF(16, 16), ":/ui/chatArea/info.png"), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text(rawMessage, Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); msg->addColumn(new Text(date.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + Q_UNUSED(type) + return msg; } -ChatMessage *ChatMessage::createFileTransferMessage(QGraphicsScene* scene, const QString& sender, const QString& rawMessage, ToxFile file, bool isMe, const QDateTime& date) +ChatMessage::Ptr ChatMessage::createFileTransferMessage(QGraphicsScene* scene, const QString& sender, const QString& rawMessage, ToxFile file, bool isMe, const QDateTime& date) { - ChatMessage* msg = new ChatMessage(scene, rawMessage); + ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage(scene, rawMessage)); msg->addColumn(new Text(sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new ChatLineContentProxy(new FileTransferWidget(0, file), 380, 0.6f), ColumnFormat(1.0, ColumnFormat::VariableSize)); diff --git a/src/chatlog/chatmessage.h b/src/chatlog/chatmessage.h index 86b28a91c..651f305a7 100644 --- a/src/chatlog/chatmessage.h +++ b/src/chatlog/chatmessage.h @@ -26,11 +26,13 @@ class QGraphicsScene; class ChatMessage : public ChatLine { public: + using Ptr = std::shared_ptr; + ChatMessage(QGraphicsScene* scene, const QString& rawMessage); - static ChatMessage* createChatMessage(QGraphicsScene* scene, const QString& sender, const QString& rawMessage, bool isAction, bool alert, bool isMe, const QDateTime& date = QDateTime()); - static ChatMessage* createChatInfoMessage(QGraphicsScene* scene, const QString& rawMessage, const QString& type, const QDateTime& date); - static ChatMessage* createFileTransferMessage(QGraphicsScene* scene, const QString& sender, const QString& rawMessage, ToxFile file, bool isMe, const QDateTime& date); + static ChatMessage::Ptr createChatMessage(QGraphicsScene* scene, const QString& sender, const QString& rawMessage, bool isAction, bool alert, bool isMe, const QDateTime& date = QDateTime()); + static ChatMessage::Ptr createChatInfoMessage(QGraphicsScene* scene, const QString& rawMessage, const QString& type, const QDateTime& date); + static ChatMessage::Ptr createFileTransferMessage(QGraphicsScene* scene, const QString& sender, const QString& rawMessage, ToxFile file, bool isMe, const QDateTime& date); void markAsSent(const QDateTime& time); QString toString() const; diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 5bad99d99..030c374ed 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -118,7 +118,7 @@ void ChatForm::onSendTriggered() int id = HistoryKeeper::getInstance()->addChatEntry(f->getToxID().publicKey, qt_msg_hist, Core::getInstance()->getSelfId().publicKey, timestamp, status); - ChatMessage* ma = addSelfMessage(msg, isAction, timestamp, false); + ChatMessage::Ptr ma = addSelfMessage(msg, isAction, timestamp, false); int rec; if (isAction) @@ -197,7 +197,7 @@ void ChatForm::onFileRecvRequest(ToxFile file) previousId = friendId; } - ChatMessage* msg = chatWidget->addFileTransferMessage(name, file, QDateTime::currentDateTime(), false); + ChatMessage::Ptr msg = chatWidget->addFileTransferMessage(name, file, QDateTime::currentDateTime(), false); if (!Settings::getInstance().getAutoAcceptDir(f->getToxID()).isEmpty() || Settings::getInstance().getAutoSaveEnabled()) { @@ -701,7 +701,7 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) ToxID storedPrevId; std::swap(storedPrevId, previousId); - QList historyMessages; + QList historyMessages; QDate lastDate(1,0,0); for (const auto &it : msgs) @@ -720,7 +720,7 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) bool isAction = it.message.startsWith("/me "); - ChatMessage* msg = addMessage(msgSender, + ChatMessage::Ptr msg = addMessage(msgSender, isAction ? it.message.right(it.message.length() - 4) : it.message, isAction, QDateTime::currentDateTime(), false); @@ -821,7 +821,7 @@ QString ChatForm::secondsToDHMS(quint32 duration) return cD + res.sprintf("%dd%02dh %02dm %02ds", days, hours, minutes, seconds); } -void ChatForm::registerReceipt(int receipt, int messageID, ChatMessage* msg) +void ChatForm::registerReceipt(int receipt, int messageID, ChatMessage::Ptr msg) { receipts[receipt] = messageID; undeliveredMsgs[messageID] = msg; @@ -855,7 +855,7 @@ void ChatForm::deliverOfflineMsgs() if (!Settings::getInstance().getFauxOfflineMessaging()) return; - QMap msgs = undeliveredMsgs; + QMap msgs = undeliveredMsgs; clearReciepts(); for (auto iter = msgs.begin(); iter != msgs.end(); iter++) diff --git a/src/widget/form/chatform.h b/src/widget/form/chatform.h index a05b54ea7..e22ad213a 100644 --- a/src/widget/form/chatform.h +++ b/src/widget/form/chatform.h @@ -89,7 +89,7 @@ protected: // drag & drop void dragEnterEvent(QDragEnterEvent* ev); void dropEvent(QDropEvent* ev); - void registerReceipt(int receipt, int messageID, ChatMessage* msg); + void registerReceipt(int receipt, int messageID, ChatMessage::Ptr msg); private: Friend* f; @@ -105,7 +105,7 @@ private: void stopCounter(); QString secondsToDHMS(quint32 duration); QHash receipts; - QMap undeliveredMsgs; + QMap undeliveredMsgs; }; #endif // CHATFORM_H diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index 58e593f85..2e9a942a1 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -183,12 +183,12 @@ void GenericChatForm::onChatContextMenuRequested(QPoint pos) menu.exec(pos); } -ChatMessage* GenericChatForm::addMessage(const ToxID& author, const QString &message, bool isAction, +ChatMessage::Ptr GenericChatForm::addMessage(const ToxID& author, const QString &message, bool isAction, const QDateTime &datetime, bool isSent) { QString authorStr = author.isMine() ? Core::getInstance()->getUsername() : resolveToxID(author); - ChatMessage* msg = nullptr; + ChatMessage::Ptr msg; if(isAction) msg = chatWidget->addChatAction(authorStr, message); else @@ -203,7 +203,7 @@ ChatMessage* GenericChatForm::addMessage(const ToxID& author, const QString &mes return msg; } -ChatMessage* GenericChatForm::addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime, bool isSent) +ChatMessage::Ptr GenericChatForm::addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime, bool isSent) { return addMessage(Core::getInstance()->getSelfId(), message, isAction, datetime, isSent); } diff --git a/src/widget/form/genericchatform.h b/src/widget/form/genericchatform.h index a14e480d9..594d00208 100644 --- a/src/widget/form/genericchatform.h +++ b/src/widget/form/genericchatform.h @@ -50,8 +50,8 @@ public: virtual void setName(const QString &newName); virtual void show(Ui::MainWindow &ui); - ChatMessage* addMessage(const ToxID& author, const QString &message, bool isAction, const QDateTime &datetime, bool isSent); - ChatMessage* addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime, bool isSent); + ChatMessage::Ptr addMessage(const ToxID& author, const QString &message, bool isAction, const QDateTime &datetime, bool isSent); + ChatMessage::Ptr addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime, bool isSent); void addSystemInfoMessage(const QString &message, const QString &type, const QDateTime &datetime); void addAlertMessage(const ToxID& author, QString message, QDateTime datetime); From f4c6bc34521351d3200b6fd2c0f179aebe5fcbed Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 4 Jan 2015 13:33:11 +0100 Subject: [PATCH 057/203] cleanup --- src/widget/form/settings/generalform.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/widget/form/settings/generalform.cpp b/src/widget/form/settings/generalform.cpp index ac0234b1e..d3d80de9b 100644 --- a/src/widget/form/settings/generalform.cpp +++ b/src/widget/form/settings/generalform.cpp @@ -311,8 +311,6 @@ void GeneralForm::reloadSmiles() for (int i = 0; i < emoticons.size(); i++) smiles.push_front(emoticons.at(i).first()); - int pixSize = 30; - bodyUI->smile1->setPixmap(SmileyPack::getInstance().getAsPixmap(smiles[0])); bodyUI->smile2->setPixmap(SmileyPack::getInstance().getAsPixmap(smiles[1])); bodyUI->smile3->setPixmap(SmileyPack::getInstance().getAsPixmap(smiles[2])); From 64024c77a683d834c72f649753cd3f287ebacbce Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 4 Jan 2015 14:21:05 +0100 Subject: [PATCH 058/203] Moved the context menu to GenericChatForm --- src/chatlog/chatlog.cpp | 53 ++++++++--------------------- src/chatlog/chatlog.h | 2 +- src/widget/form/genericchatform.cpp | 47 +++++++++++++++++++------ src/widget/form/genericchatform.h | 2 ++ 4 files changed, 54 insertions(+), 50 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 089a70eb1..93ff2a1fc 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -21,10 +21,8 @@ #include #include #include -#include #include -#include -#include +#include template T clamp(T x, T min, T max) @@ -50,6 +48,7 @@ ChatLog::ChatLog(QWidget* parent) setViewportUpdateMode(BoundingRectViewportUpdate); //setRenderHint(QPainter::TextAntialiasing); setAcceptDrops(false); + setContextMenuPolicy(Qt::CustomContextMenu); const QColor selGraphColor = QColor(166,225,255); selGraphItem = scene->addRect(0,0,0,0,selGraphColor.darker(120),selGraphColor); @@ -228,14 +227,22 @@ void ChatLog::mousePressEvent(QMouseEvent* ev) { if(!isOverSelection(scenePos)) clearSelection(); - - showContextMenu(ev->globalPos(), scenePos); } } void ChatLog::mouseReleaseEvent(QMouseEvent* ev) { QGraphicsView::mouseReleaseEvent(ev); + + QPointF scenePos = mapToScene(ev->pos()); + + if(ev->button() == Qt::RightButton) + { + if(!isOverSelection(scenePos)) + clearSelection(); + + emit customContextMenuRequested(ev->pos()); + } } void ChatLog::mouseMoveEvent(QMouseEvent* ev) @@ -461,41 +468,9 @@ bool ChatLog::isEmpty() const return lines.isEmpty(); } -void ChatLog::showContextMenu(const QPoint& globalPos, const QPointF& scenePos) +bool ChatLog::hasTextToBeCopied() const { - QMenu menu; - - // populate - QAction* copyAction = menu.addAction(QIcon::fromTheme("edit-copy"), tr("Copy")); - menu.addSeparator(); - QAction* clearAction = menu.addAction(QIcon::fromTheme("edit-clear") ,tr("Clear chat log")); - QAction* saveAction = menu.addAction(QIcon::fromTheme("document-save") ,tr("Save chat log")); - - if(!isOverSelection(scenePos)) - copyAction->setDisabled(true); - - // show - QAction* action = menu.exec(globalPos); - - if(action == copyAction) - copySelectedText(); - - if(action == clearAction) - clear(); - - if(action == saveAction) - { - QString path = QFileDialog::getSaveFileName(0, tr("Save chat log")); - if (path.isEmpty()) - return; - - QFile file(path); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) - return; - - file.write(toPlainText().toUtf8()); - file.close(); - } + return selectionMode != None; } void ChatLog::clear() diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 9052b31a5..f2f293c7b 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -53,6 +53,7 @@ public: QString toPlainText() const; bool isEmpty() const; + bool hasTextToBeCopied() const; protected: QRect getVisibleRect() const; @@ -71,7 +72,6 @@ protected: void fullUpdate(); void checkVisibility(); void scrollToBottom(); - void showContextMenu(const QPoint& globalPos, const QPointF& scenePos); virtual void mousePressEvent(QMouseEvent* ev); virtual void mouseReleaseEvent(QMouseEvent* ev); diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index 2e9a942a1..ace5e0ff2 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -50,12 +50,12 @@ GenericChatForm::GenericChatForm(QWidget *parent) : avatar = new MaskablePixmapWidget(this, QSize(40,40), ":/img/avatar_mask.png"); QHBoxLayout *headLayout = new QHBoxLayout(), - *mainFootLayout = new QHBoxLayout(); + *mainFootLayout = new QHBoxLayout(); QVBoxLayout *mainLayout = new QVBoxLayout(), - *footButtonsSmall = new QVBoxLayout(), - *volMicLayout = new QVBoxLayout(); - headTextLayout = new QVBoxLayout(); + *footButtonsSmall = new QVBoxLayout(), + *volMicLayout = new QVBoxLayout(); + headTextLayout = new QVBoxLayout(); chatWidget = new ChatLog(this); @@ -79,7 +79,7 @@ GenericChatForm::GenericChatForm(QWidget *parent) : //volButton->setFixedSize(25,20); volButton->setToolTip(tr("Toggle speakers volume: RED is OFF")); micButton = new QPushButton(); - // micButton->setFixedSize(25,20); + // micButton->setFixedSize(25,20); micButton->setToolTip(tr("Toggle microphone: RED is OFF")); footButtonsSmall->setSpacing(2); @@ -122,7 +122,7 @@ GenericChatForm::GenericChatForm(QWidget *parent) : headTextLayout->addStretch(); headTextLayout->addWidget(nameLabel); - + volMicLayout->addWidget(micButton, Qt::AlignTop); volMicLayout->addSpacing(2); volMicLayout->addWidget(volButton, Qt::AlignBottom); @@ -143,13 +143,17 @@ GenericChatForm::GenericChatForm(QWidget *parent) : fileButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); emoteButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); - connect(emoteButton, SIGNAL(clicked()), this, SLOT(onEmoteButtonClicked())); - connect(chatWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onChatContextMenuRequested(QPoint))); + menu.addAction(QIcon::fromTheme("edit-copy"), tr("Copy"), this, SLOT(onCopyLogClicked())); + menu.addSeparator(); + menu.addAction(QIcon::fromTheme("document-save"), tr("Save chat log"), this, SLOT(onSaveLogClicked())); + menu.addAction(QIcon::fromTheme("edit-clear"), tr("Clear displayed messages"), this, SLOT(clearChatArea(bool))); + menu.addSeparator(); + + connect(emoteButton, &QPushButton::clicked, this, &GenericChatForm::onEmoteButtonClicked); + connect(chatWidget, &ChatLog::customContextMenuRequested, this, &GenericChatForm::onChatContextMenuRequested); chatWidget->setStyleSheet(Style::getStylesheet(":/ui/chatArea/chatArea.css")); headWidget->setStyleSheet(Style::getStylesheet(":/ui/chatArea/chatHead.css")); - - //ChatAction::setupFormat(); } bool GenericChatForm::isEmpty() @@ -180,6 +184,10 @@ void GenericChatForm::onChatContextMenuRequested(QPoint pos) { QWidget* sender = (QWidget*)QObject::sender(); pos = sender->mapToGlobal(pos); + + //copy action + menu.actions().first()->setEnabled(chatWidget->hasTextToBeCopied()); + menu.exec(pos); } @@ -243,6 +251,25 @@ void GenericChatForm::onEmoteInsertRequested(QString str) msgEdit->setFocus(); // refocus so that we can continue typing } +void GenericChatForm::onSaveLogClicked() +{ + QString path = QFileDialog::getSaveFileName(0, tr("Save chat log")); + if (path.isEmpty()) + return; + + QFile file(path); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) + return; + + file.write(chatWidget->toPlainText().toUtf8()); + file.close(); +} + +void GenericChatForm::onCopyLogClicked() +{ + chatWidget->copySelectedText(); +} + void GenericChatForm::focusInput() { msgEdit->setFocus(); diff --git a/src/widget/form/genericchatform.h b/src/widget/form/genericchatform.h index 594d00208..0e8caaa0d 100644 --- a/src/widget/form/genericchatform.h +++ b/src/widget/form/genericchatform.h @@ -71,6 +71,8 @@ protected slots: void onChatContextMenuRequested(QPoint pos); void onEmoteButtonClicked(); void onEmoteInsertRequested(QString str); + void onSaveLogClicked(); + void onCopyLogClicked(); void clearChatArea(bool); protected: From a74b9ce11cea45f3ad62a0e16ede8576fb12425d Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 4 Jan 2015 15:18:23 +0100 Subject: [PATCH 059/203] ChatLog: Autoscroll while selecting --- src/chatlog/chatlog.cpp | 35 +++++++++++++++++++++++++++++++++++ src/chatlog/chatlog.h | 12 ++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 93ff2a1fc..93a717f44 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -23,6 +23,7 @@ #include #include #include +#include template T clamp(T x, T min, T max) @@ -62,6 +63,12 @@ ChatLog::ChatLog(QWidget* parent) { copySelectedText(); }); + + selectionTimer = new QTimer(this); + selectionTimer->setInterval(1000/60); + selectionTimer->setSingleShot(false); + selectionTimer->start(); + connect(selectionTimer, &QTimer::timeout, this, &ChatLog::onSelectionTimerTimeout); } ChatLog::~ChatLog() @@ -243,6 +250,8 @@ void ChatLog::mouseReleaseEvent(QMouseEvent* ev) emit customContextMenuRequested(ev->pos()); } + + selectionScrollDir = NoDirection; } void ChatLog::mouseMoveEvent(QMouseEvent* ev) @@ -253,6 +262,15 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) if(ev->buttons() & Qt::LeftButton) { + //autoscroll + if(ev->pos().y() < 0) + selectionScrollDir = Up; + else if(ev->pos().y() > height()) + selectionScrollDir = Down; + else + selectionScrollDir = NoDirection; + + //select if(selectionMode == None && (clickPos - ev->pos()).manhattanLength() > QApplication::startDragDistance()) { QPointF sceneClickPos = mapToScene(clickPos.toPoint()); @@ -579,3 +597,20 @@ void ChatLog::updateMultiSelectionRect() selGraphItem->hide(); } } + +void ChatLog::onSelectionTimerTimeout() +{ + const int scrollSpeed = 10; + + switch(selectionScrollDir) + { + case Up: + verticalScrollBar()->setValue(verticalScrollBar()->value() - scrollSpeed); + break; + case Down: + verticalScrollBar()->setValue(verticalScrollBar()->value() + scrollSpeed); + break; + default: + break; + } +} diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index f2f293c7b..e6e89f595 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -26,6 +26,7 @@ class QGraphicsScene; class QGraphicsRectItem; +class QTimer; class ChatLineContent; class ToxFile; @@ -81,6 +82,9 @@ protected: void updateMultiSelectionRect(); +private slots: + void onSelectionTimerTimeout(); + private: enum SelectionMode { None, @@ -88,6 +92,12 @@ private: Multi, }; + enum AutoScrollDirection { + NoDirection, + Up, + Down, + }; + QGraphicsScene* scene = nullptr; QList lines; QList visibleLines; @@ -105,6 +115,8 @@ private: QPointF clickPos; QPointF lastPos; QGraphicsRectItem* selGraphItem = nullptr; + QTimer* selectionTimer = nullptr; + AutoScrollDirection selectionScrollDir = NoDirection; // actions QAction* copyAction = nullptr; From b09805f9bf29b4779bfbb1a28052816dbed24e64 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 4 Jan 2015 18:21:35 +0100 Subject: [PATCH 060/203] refactoring --- src/chatlog/chatline.cpp | 23 +++++++++---- src/chatlog/chatline.h | 8 ++--- src/chatlog/chatlog.cpp | 53 +++-------------------------- src/chatlog/chatlog.h | 9 ----- src/chatlog/chatmessage.cpp | 40 +++++++++++++++------- src/chatlog/chatmessage.h | 18 ++++++---- src/chatlog/content/text.cpp | 5 +-- src/chatlog/content/text.h | 3 +- src/widget/form/chatform.cpp | 22 ++++++------ src/widget/form/genericchatform.cpp | 35 +++++++++++++------ src/widget/form/genericchatform.h | 6 ++-- src/widget/widget.cpp | 6 ++-- 12 files changed, 112 insertions(+), 116 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index 18231e244..877a0466d 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -24,8 +24,7 @@ #define CELL_SPACING 15 -ChatLine::ChatLine(QGraphicsScene* grScene) - : scene(grScene) +ChatLine::ChatLine() { } @@ -35,7 +34,7 @@ ChatLine::~ChatLine() for(ChatLineContent* c : content) { if(c->scene()) - scene->removeItem(c); + c->scene()->removeItem(c); delete c; } @@ -78,10 +77,19 @@ void ChatLine::removeFromScene() for(ChatLineContent* c : content) { if(c->scene()) - scene->removeItem(c); + c->scene()->removeItem(c); } } +void ChatLine::addToScene(QGraphicsScene *scene) +{ + if(!scene) + return; + + for(ChatLineContent* c : content) + scene->addItem(c); +} + void ChatLine::selectionCleared() { for(ChatLineContent* c : content) @@ -133,7 +141,6 @@ void ChatLine::addColumn(ChatLineContent* item, ColumnFormat fmt) return; item->setChatLine(this); - scene->addItem(item); format << fmt; content << item; @@ -143,12 +150,14 @@ void ChatLine::replaceContent(int col, ChatLineContent *lineContent) { if(col >= 0 && col < content.size() && lineContent) { - scene->removeItem(content[col]); + QGraphicsScene* scene = content[col]->scene(); delete content[col]; content[col] = lineContent; lineContent->setIndex(rowIndex, col); - scene->addItem(content[col]); + + if(scene) + scene->addItem(content[col]); layout(width, pos); content[col]->visibilityChanged(isVisible); diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index 69450a9a7..2ddf89098 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -57,12 +57,11 @@ class ChatLine public: using Ptr = std::shared_ptr; - explicit ChatLine(QGraphicsScene* scene); + explicit ChatLine(); virtual ~ChatLine(); virtual QRectF boundingSceneRect() const; - void addColumn(ChatLineContent* item, ColumnFormat fmt); void replaceContent(int col, ChatLineContent* lineContent); void layout(qreal width, QPointF scenePos); @@ -80,9 +79,11 @@ public: bool isOverSelection(QPointF scenePos); void removeFromScene(); + void addToScene(QGraphicsScene* scene); -private: +protected: QPointF mapToContent(ChatLineContent* c, QPointF pos); + void addColumn(ChatLineContent* item, ColumnFormat fmt); void updateBBox(); friend class ChatLog; @@ -91,7 +92,6 @@ private: private: int rowIndex = -1; - QGraphicsScene* scene = nullptr; QVector content; // 3 columns QVector format; qreal width; diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 93a717f44..39da9b767 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -76,54 +76,6 @@ ChatLog::~ChatLog() } -ChatMessage::Ptr ChatLog::addChatMessage(const QString& sender, const QString &msg, bool self, bool alert) -{ - ChatMessage::Ptr line = ChatMessage::createChatMessage(scene, sender, msg, false, alert, self); - insertChatline(std::dynamic_pointer_cast(line)); - - return line; -} - -ChatMessage::Ptr ChatLog::addChatMessage(const QString& sender, const QString& msg, const QDateTime& timestamp, bool self, bool alert) -{ - ChatMessage::Ptr line = ChatMessage::createChatMessage(scene, sender, msg, false, alert, self, timestamp); - insertChatline(std::dynamic_pointer_cast(line)); - - return line; -} - -ChatMessage::Ptr ChatLog::addChatAction(const QString &sender, const QString &msg, const QDateTime ×tamp) -{ - ChatMessage::Ptr line = ChatMessage::createChatMessage(scene, sender, msg, true, false, false, timestamp); - insertChatline(std::dynamic_pointer_cast(line)); - - return line; -} - -ChatMessage::Ptr ChatLog::addChatAction(const QString &sender, const QString &msg) -{ - ChatMessage::Ptr line = ChatMessage::createChatMessage(scene, sender, msg, true, false, false); - insertChatline(std::dynamic_pointer_cast(line)); - - return line; -} - -ChatMessage::Ptr ChatLog::addSystemMessage(const QString &msg, const QDateTime& timestamp) -{ - ChatMessage::Ptr line = ChatMessage::createChatInfoMessage(scene, msg, "", timestamp); - insertChatline(std::dynamic_pointer_cast(line)); - - return line; -} - -ChatMessage::Ptr ChatLog::addFileTransferMessage(const QString &sender, const ToxFile &file, const QDateTime& timestamp, bool self) -{ - ChatMessage::Ptr line = ChatMessage::createFileTransferMessage(scene, sender, "", file, self, timestamp); - insertChatline(std::dynamic_pointer_cast(line)); - - return line; -} - void ChatLog::clearSelection() { for(int i=selFirstRow; i<=selLastRow && i= 0; ++i) @@ -403,6 +355,11 @@ void ChatLog::repositionDownTo(int start, qreal end) void ChatLog::insertChatline(ChatLine::Ptr l) { + if(!l.get()) + return; + + l->addToScene(scene); + stickToBtm = stickToBottom(); l->setRowIndex(lines.size()); diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index e6e89f595..796766cca 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -37,16 +37,7 @@ public: explicit ChatLog(QWidget* parent = 0); virtual ~ChatLog(); - ChatMessage::Ptr addChatMessage(const QString& sender, const QString& msg, const QDateTime& timestamp, bool self, bool alert); - ChatMessage::Ptr addChatMessage(const QString& sender, const QString& msg, bool self, bool alert); - ChatMessage::Ptr addChatAction(const QString& sender, const QString& msg, const QDateTime& timestamp); - ChatMessage::Ptr addChatAction(const QString& sender, const QString& msg); - - ChatMessage::Ptr addSystemMessage(const QString& msg, const QDateTime& timestamp); - ChatMessage::Ptr addFileTransferMessage(const QString& sender, const ToxFile& file, const QDateTime ×tamp, bool self); - void insertChatline(ChatLine::Ptr l); - void clearSelection(); void clear(); void copySelectedText() const; diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 748c59a3b..0a0e5b0bc 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -28,16 +28,14 @@ #define NAME_COL_WIDTH 75.0 #define TIME_COL_WIDTH 85.0 -ChatMessage::ChatMessage(QGraphicsScene* scene, const QString& rawMessage) - : ChatLine(scene) - , rawString(rawMessage) +ChatMessage::ChatMessage() { } -ChatMessage::Ptr ChatMessage::createChatMessage(QGraphicsScene *scene, const QString &sender, const QString &rawMessage, bool isAction, bool alert, bool isMe, const QDateTime &date) +ChatMessage::Ptr ChatMessage::createChatMessage(const QString &sender, const QString &rawMessage, bool isAction, bool alert, bool isMe, const QDateTime &date) { - ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage(scene, rawMessage)); + ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); QString text = toHtmlChars(rawMessage); @@ -57,7 +55,7 @@ ChatMessage::Ptr ChatMessage::createChatMessage(QGraphicsScene *scene, const QSt } msg->addColumn(new Text(isAction ? "*" : sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - msg->addColumn(new Text(text, Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); + msg->addColumn(new Text(text, Style::getFont(Style::Big), false, rawMessage), ColumnFormat(1.0, ColumnFormat::VariableSize)); msg->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); if(!date.isNull()) @@ -66,12 +64,12 @@ ChatMessage::Ptr ChatMessage::createChatMessage(QGraphicsScene *scene, const QSt return msg; } -ChatMessage::Ptr ChatMessage::createChatInfoMessage(QGraphicsScene *scene, const QString &rawMessage, const QString &type, const QDateTime &date) +ChatMessage::Ptr ChatMessage::createChatInfoMessage(const QString &rawMessage, SystemMessageType type, const QDateTime &date) { - ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage(scene, rawMessage)); + ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); msg->addColumn(new Image(QSizeF(16, 16), ":/ui/chatArea/info.png"), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - msg->addColumn(new Text(rawMessage, Style::getFont(Style::Big)), ColumnFormat(1.0, ColumnFormat::VariableSize)); + msg->addColumn(new Text(rawMessage, Style::getFont(Style::Big), false, rawMessage), ColumnFormat(1.0, ColumnFormat::VariableSize)); msg->addColumn(new Text(date.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); Q_UNUSED(type) @@ -79,9 +77,9 @@ ChatMessage::Ptr ChatMessage::createChatInfoMessage(QGraphicsScene *scene, const return msg; } -ChatMessage::Ptr ChatMessage::createFileTransferMessage(QGraphicsScene* scene, const QString& sender, const QString& rawMessage, ToxFile file, bool isMe, const QDateTime& date) +ChatMessage::Ptr ChatMessage::createFileTransferMessage(const QString& sender, ToxFile file, bool isMe, const QDateTime& date) { - ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage(scene, rawMessage)); + ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); msg->addColumn(new Text(sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new ChatLineContentProxy(new FileTransferWidget(0, file), 380, 0.6f), ColumnFormat(1.0, ColumnFormat::VariableSize)); @@ -98,7 +96,11 @@ void ChatMessage::markAsSent(const QDateTime &time) QString ChatMessage::toString() const { - return rawString; + ChatLineContent* c = getContent(1); + if(c) + return c->getText(); + + return QString(); } bool ChatMessage::isAction() const @@ -111,6 +113,20 @@ void ChatMessage::setAsAction() action = true; } +void ChatMessage::hideSender() +{ + ChatLineContent* c = getContent(0); + if(c) + c->hide(); +} + +void ChatMessage::hideDate() +{ + ChatLineContent* c = getContent(2); + if(c) + c->hide(); +} + QString ChatMessage::detectAnchors(const QString &str) { QString out = str; diff --git a/src/chatlog/chatmessage.h b/src/chatlog/chatmessage.h index 651f305a7..233ed19da 100644 --- a/src/chatlog/chatmessage.h +++ b/src/chatlog/chatmessage.h @@ -28,16 +28,24 @@ class ChatMessage : public ChatLine public: using Ptr = std::shared_ptr; - ChatMessage(QGraphicsScene* scene, const QString& rawMessage); + enum SystemMessageType + { + INFO, + ERROR, + }; - static ChatMessage::Ptr createChatMessage(QGraphicsScene* scene, const QString& sender, const QString& rawMessage, bool isAction, bool alert, bool isMe, const QDateTime& date = QDateTime()); - static ChatMessage::Ptr createChatInfoMessage(QGraphicsScene* scene, const QString& rawMessage, const QString& type, const QDateTime& date); - static ChatMessage::Ptr createFileTransferMessage(QGraphicsScene* scene, const QString& sender, const QString& rawMessage, ToxFile file, bool isMe, const QDateTime& date); + ChatMessage(); + + static ChatMessage::Ptr createChatMessage(const QString& sender, const QString& rawMessage, bool isAction, bool alert, bool isMe, const QDateTime& date = QDateTime()); + static ChatMessage::Ptr createChatInfoMessage(const QString& rawMessage, SystemMessageType type, const QDateTime& date); + static ChatMessage::Ptr createFileTransferMessage(const QString& sender, ToxFile file, bool isMe, const QDateTime& date); void markAsSent(const QDateTime& time); QString toString() const; bool isAction() const; void setAsAction(); + void hideSender(); + void hideDate(); protected: static QString detectAnchors(const QString& str); @@ -45,8 +53,6 @@ protected: static QString toHtmlChars(const QString& str); private: - ChatLineContent* midColumn = nullptr; - QString rawString; bool action = false; }; diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index dddbd74f2..c69f79550 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -29,10 +29,11 @@ #include #include -Text::Text(const QString& txt, QFont font, bool enableElide) +Text::Text(const QString& txt, QFont font, bool enableElide, const QString &rwText) : ChatLineContent() , elide(enableElide) , defFont(font) + , rawText(rwText) { setText(txt); setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton); @@ -197,7 +198,7 @@ void Text::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QString Text::getText() const { - return text; + return rawText; } void Text::ensureIntegrity() diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index e21e664ab..05c6cd017 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -27,7 +27,7 @@ class CustomTextDocument; class Text : public ChatLineContent { public: - Text(const QString& txt = "", QFont font = QFont(), bool enableElide = false); + Text(const QString& txt = "", QFont font = QFont(), bool enableElide = false, const QString& rawText = ""); virtual ~Text(); void setText(const QString& txt); @@ -64,6 +64,7 @@ protected: private: CustomTextDocument* doc = nullptr; QString text; + QString rawText; QString elidedText; QString selectedText; QSizeF size; diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 030c374ed..7cc9fd79b 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -40,6 +40,7 @@ #include "src/misc/cstring.h" #include "src/chatlog/chatmessage.h" #include "src/chatlog/content/filetransferwidget.h" +#include "src/chatlog/chatlog.h" ChatForm::ChatForm(Friend* chatFriend) : f(chatFriend) @@ -172,8 +173,7 @@ void ChatForm::startFileSend(ToxFile file) previousId = core->getSelfId(); } - - chatWidget->addFileTransferMessage(name, file, QDateTime::currentDateTime(), true); + insertChatMessage(ChatMessage::createFileTransferMessage(name, file, true, QDateTime::currentDateTime())); } void ChatForm::onFileRecvRequest(ToxFile file) @@ -197,7 +197,9 @@ void ChatForm::onFileRecvRequest(ToxFile file) previousId = friendId; } - ChatMessage::Ptr msg = chatWidget->addFileTransferMessage(name, file, QDateTime::currentDateTime(), false); + ChatMessage::Ptr msg = ChatMessage::createFileTransferMessage(name, file, false, QDateTime::currentDateTime()); + insertChatMessage(msg); + if (!Settings::getInstance().getAutoAcceptDir(f->getToxID()).isEmpty() || Settings::getInstance().getAutoSaveEnabled()) { @@ -233,7 +235,7 @@ void ChatForm::onAvInvite(int FriendId, int CallId, bool video) connect(callButton, SIGNAL(clicked()), this, SLOT(onAnswerCallTriggered())); } - chatWidget->addSystemMessage(tr("%1 calling").arg(f->getDisplayedName()), QDateTime::currentDateTime()); + insertChatMessage(ChatMessage::createChatInfoMessage(tr("%1 calling").arg(f->getDisplayedName()), ChatMessage::INFO, QDateTime::currentDateTime())); Widget* w = Widget::getInstance(); if (!w->isFriendWidgetCurActiveWidget(f)|| w->isMinimized() || !w->isActiveWindow()) @@ -304,7 +306,7 @@ void ChatForm::onAvCancel(int FriendId, int) netcam->hide(); - addSystemInfoMessage(tr("%1 stopped calling").arg(f->getDisplayedName()), "white", QDateTime::currentDateTime()); + addSystemInfoMessage(tr("%1 stopped calling").arg(f->getDisplayedName()), ChatMessage::INFO, QDateTime::currentDateTime()); } void ChatForm::onAvEnd(int FriendId, int) @@ -360,7 +362,7 @@ void ChatForm::onAvRinging(int FriendId, int CallId, bool video) connect(callButton, SIGNAL(clicked()), this, SLOT(onCancelCallTriggered())); } - addSystemInfoMessage(tr("Calling to %1").arg(f->getDisplayedName()), "white", QDateTime::currentDateTime()); + addSystemInfoMessage(tr("Calling to %1").arg(f->getDisplayedName()), ChatMessage::INFO, QDateTime::currentDateTime()); } void ChatForm::onAvStarting(int FriendId, int CallId, bool video) @@ -501,7 +503,7 @@ void ChatForm::onAvRejected(int FriendId, int) connect(callButton, SIGNAL(clicked()), this, SLOT(onCallTriggered())); connect(videoButton, SIGNAL(clicked()), this, SLOT(onVideoCallTriggered())); - chatWidget->addSystemMessage(tr("Call rejected"), QDateTime::currentDateTime()); + insertChatMessage(ChatMessage::createChatInfoMessage(tr("Call rejected"), ChatMessage::INFO, QDateTime::currentDateTime())); netcam->hide(); } @@ -640,7 +642,7 @@ void ChatForm::onFileSendFailed(int FriendId, const QString &fname) if (FriendId != f->getFriendID()) return; - addSystemInfoMessage(tr("Failed to send file \"%1\"").arg(fname), "red", QDateTime::currentDateTime()); + addSystemInfoMessage(tr("Failed to send file \"%1\"").arg(fname), ChatMessage::ERROR, QDateTime::currentDateTime()); } void ChatForm::onAvatarChange(int FriendId, const QPixmap &pic) @@ -712,7 +714,7 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) if (msgDate > lastDate) { lastDate = msgDate; - chatWidget->addSystemMessage(msgDate.toString(), QDateTime()); + insertChatMessage(ChatMessage::createChatInfoMessage(msgDate.toString(), ChatMessage::INFO, QDateTime::currentDateTime())); } // Show each messages @@ -784,7 +786,7 @@ void ChatForm::stopCounter() if (timer) { addSystemInfoMessage(tr("Call with %1 ended. %2").arg(f->getDisplayedName(),secondsToDHMS(timeElapsed.elapsed()/1000)), - "white", QDateTime::currentDateTime()); + ChatMessage::INFO, QDateTime::currentDateTime()); timer->stop(); callDuration->setText(""); callDuration->hide(); diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index ace5e0ff2..4d1c7623c 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -30,8 +30,7 @@ #include "src/group.h" #include "src/friendlist.h" #include "src/friend.h" -#include "src/chatlog/content/text.h" -#include "src/chatlog/chatmessage.h" +#include "src/chatlog/chatlog.h" GenericChatForm::GenericChatForm(QWidget *parent) : QWidget(parent), @@ -198,9 +197,17 @@ ChatMessage::Ptr GenericChatForm::addMessage(const ToxID& author, const QString ChatMessage::Ptr msg; if(isAction) - msg = chatWidget->addChatAction(authorStr, message); + { + msg = ChatMessage::createChatMessage(authorStr, message, true, false, false); + } else - msg = chatWidget->addChatMessage(author != previousId ? authorStr : QString(), message, author.isMine(), false); + { + msg = ChatMessage::createChatMessage(authorStr, message, false, false, author.isMine()); + if(author == previousId) + msg->hideSender(); + } + + insertChatMessage(msg); if(isSent) msg->markAsSent(datetime); @@ -219,7 +226,11 @@ ChatMessage::Ptr GenericChatForm::addSelfMessage(const QString &message, bool is void GenericChatForm::addAlertMessage(const ToxID &author, QString message, QDateTime datetime) { QString authorStr = resolveToxID(author); - chatWidget->addChatMessage(author != previousId ? authorStr : QString(), message, datetime, author.isMine(), true); + ChatMessage::Ptr msg = ChatMessage::createChatMessage(authorStr, message, false, true, author.isMine(), datetime); + insertChatMessage(msg); + + if(author == previousId) + msg->hideSender(); previousId = author; } @@ -275,13 +286,10 @@ void GenericChatForm::focusInput() msgEdit->setFocus(); } -void GenericChatForm::addSystemInfoMessage(const QString &message, const QString &type, const QDateTime &datetime) +void GenericChatForm::addSystemInfoMessage(const QString &message, ChatMessage::SystemMessageType type, const QDateTime &datetime) { - //TODO: respect type previousId.clear(); - chatWidget->addSystemMessage(message, datetime); - - Q_UNUSED(type) + insertChatMessage(ChatMessage::createChatInfoMessage(message, type, datetime)); } void GenericChatForm::clearChatArea(bool notinform) @@ -290,7 +298,7 @@ void GenericChatForm::clearChatArea(bool notinform) previousId = ToxID(); if (!notinform) - addSystemInfoMessage(tr("Cleared"), "white", QDateTime::currentDateTime()); + addSystemInfoMessage(tr("Cleared"), ChatMessage::INFO, QDateTime::currentDateTime()); if (earliestMessage) { @@ -318,3 +326,8 @@ QString GenericChatForm::resolveToxID(const ToxID &id) return QString(); } + +void GenericChatForm::insertChatMessage(ChatMessage::Ptr msg) +{ + chatWidget->insertChatline(std::dynamic_pointer_cast(msg)); +} diff --git a/src/widget/form/genericchatform.h b/src/widget/form/genericchatform.h index 0e8caaa0d..2ce36b48b 100644 --- a/src/widget/form/genericchatform.h +++ b/src/widget/form/genericchatform.h @@ -22,7 +22,7 @@ #include #include #include "src/corestructs.h" -#include "src/chatlog/chatlog.h" +#include "src/chatlog/chatmessage.h" // Spacing in px inserted when the author of the last message changes #define AUTHOR_CHANGE_SPACING 5 // why the hell is this a thing? surely the different font is enough? @@ -33,7 +33,6 @@ class QPushButton; class CroppingLabel; class ChatTextEdit; class ChatLog; -class ChatMessage; class MaskablePixmapWidget; struct ToxID; @@ -53,7 +52,7 @@ public: ChatMessage::Ptr addMessage(const ToxID& author, const QString &message, bool isAction, const QDateTime &datetime, bool isSent); ChatMessage::Ptr addSelfMessage(const QString &message, bool isAction, const QDateTime &datetime, bool isSent); - void addSystemInfoMessage(const QString &message, const QString &type, const QDateTime &datetime); + void addSystemInfoMessage(const QString &message, ChatMessage::SystemMessageType type, const QDateTime &datetime); void addAlertMessage(const ToxID& author, QString message, QDateTime datetime); bool isEmpty(); @@ -77,6 +76,7 @@ protected slots: protected: QString resolveToxID(const ToxID &id); + void insertChatMessage(ChatMessage::Ptr msg); ToxID previousId; QMenu menu; diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 3068ff1db..8e94a2593 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -749,7 +749,7 @@ void Widget::onFriendStatusChanged(int friendId, Status status) } if (isActualChange) f->getChatForm()->addSystemInfoMessage(tr("%1 is now %2", "e.g. \"Dubslow is now online\"").arg(f->getDisplayedName()).arg(fStatus), - "white", QDateTime::currentDateTime()); + ChatMessage::INFO, QDateTime::currentDateTime()); } if (isActualChange && status != Status::Offline) @@ -1011,7 +1011,7 @@ void Widget::onGroupTitleChanged(int groupnumber, const QString& author, const Q g->setName(title); if (!author.isEmpty()) - g->getChatForm()->addSystemInfoMessage(tr("%1 has set the title to %2").arg(author, title), "silver", QDateTime::currentDateTime()); + g->getChatForm()->addSystemInfoMessage(tr("%1 has set the title to %2").arg(author, title), ChatMessage::INFO, QDateTime::currentDateTime()); } void Widget::removeGroup(Group* g, bool fake) @@ -1162,7 +1162,7 @@ void Widget::onGroupSendResult(int groupId, const QString& message, int result) return; if (result == -1) - g->getChatForm()->addSystemInfoMessage(tr("Message failed to send"), "white", QDateTime::currentDateTime()); + g->getChatForm()->addSystemInfoMessage(tr("Message failed to send"), ChatMessage::INFO, QDateTime::currentDateTime()); } void Widget::getPassword(QString info, int passtype, uint8_t* salt) From 12a1fa15495329e4f563bd51dbd5475c04a87c22 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 4 Jan 2015 19:28:27 +0100 Subject: [PATCH 061/203] ChatLog: insertChatlineAtBottom, refactoring --- src/chatlog/chatlog.cpp | 27 ++++++++++++++++++++++++++- src/chatlog/chatlog.h | 3 ++- src/chatlog/content/text.cpp | 3 +-- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 39da9b767..1c0271992 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -353,7 +353,7 @@ void ChatLog::repositionDownTo(int start, qreal end) } } -void ChatLog::insertChatline(ChatLine::Ptr l) +void ChatLog::insertChatlineAtBottom(ChatLine::Ptr l) { if(!l.get()) return; @@ -365,6 +365,7 @@ void ChatLog::insertChatline(ChatLine::Ptr l) l->setRowIndex(lines.size()); lines.append(l); + //partial refresh layout(lines.last()->getRowIndex() - 1, lines.size(), useableWidth()); updateSceneRect(); @@ -374,6 +375,30 @@ void ChatLog::insertChatline(ChatLine::Ptr l) checkVisibility(); } +void ChatLog::insertChatlineOnTop(ChatLine::Ptr l) +{ + if(!l.get()) + return; + + //move all lines down by 1 + for(ChatLine::Ptr l : lines) + l->setRowIndex(l->getRowIndex() + 1); + + //add the new line + l->addToScene(scene); + l->setRowIndex(0); + lines.prepend(l); + + //full refresh is required + layout(0, lines.size(), useableWidth()); + updateSceneRect(); + + if(stickToBtm) + scrollToBottom(); + + checkVisibility(); +} + bool ChatLog::stickToBottom() { return verticalScrollBar()->value() == verticalScrollBar()->maximum(); diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 796766cca..2df5f60ea 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -37,7 +37,8 @@ public: explicit ChatLog(QWidget* parent = 0); virtual ~ChatLog(); - void insertChatline(ChatLine::Ptr l); + void insertChatlineAtBottom(ChatLine::Ptr l); + void insertChatlineOnTop(ChatLine::Ptr l); void clearSelection(); void clear(); void copySelectedText() const; diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index c69f79550..1b827aa60 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -30,10 +30,9 @@ #include Text::Text(const QString& txt, QFont font, bool enableElide, const QString &rwText) - : ChatLineContent() + : rawText(rwText) , elide(enableElide) , defFont(font) - , rawText(rwText) { setText(txt); setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton); From 6711fd6ee4a6fd2c40db4f89dff040b81025e3ec Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 4 Jan 2015 19:29:06 +0100 Subject: [PATCH 062/203] history fixes --- src/widget/form/chatform.cpp | 50 +++++++++++++++++------------ src/widget/form/genericchatform.cpp | 13 +++----- src/widget/form/genericchatform.h | 2 +- 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 7cc9fd79b..683a3d2c8 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -688,20 +688,22 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) if (since > now) return; - if (earliestMessage) + if (!earliestMessage.isNull()) { - if (*earliestMessage < since) + if (earliestMessage < since) return; - if (*earliestMessage < now) + if (earliestMessage < now) { - now = *earliestMessage; + now = earliestMessage; now = now.addMSecs(-1); } } auto msgs = HistoryKeeper::getInstance()->getChatHistory(HistoryKeeper::ctSingle, f->getToxID().publicKey, since, now); - ToxID storedPrevId; + ToxID storedPrevId = previousId; + ToxID prevId; + std::swap(storedPrevId, previousId); QList historyMessages; @@ -714,20 +716,26 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) if (msgDate > lastDate) { lastDate = msgDate; - insertChatMessage(ChatMessage::createChatInfoMessage(msgDate.toString(), ChatMessage::INFO, QDateTime::currentDateTime())); + historyMessages.prepend(ChatMessage::createChatInfoMessage(msgDate.toString(), ChatMessage::INFO, QDateTime::currentDateTime())); } // Show each messages - ToxID msgSender = ToxID::fromString(it.sender); - + ToxID authorId = ToxID::fromString(it.sender); + QString authorStr = authorId.isMine() ? Core::getInstance()->getUsername() : resolveToxID(authorId); bool isAction = it.message.startsWith("/me "); - ChatMessage::Ptr msg = addMessage(msgSender, - isAction ? it.message.right(it.message.length() - 4) : it.message, - isAction, QDateTime::currentDateTime(), - false); + ChatMessage::Ptr msg = ChatMessage::createChatMessage(authorStr, + isAction ? it.message.right(it.message.length() - 4) : it.message, + isAction, false, + authorId.isMine(), + QDateTime::currentDateTime()); - if (it.isSent || !msgSender.isMine()) + if(prevId == authorId) + msg->hideSender(); + + prevId = authorId; + + if (it.isSent || !authorId.isMine()) { msg->markAsSent(msgDateTime); } @@ -743,19 +751,19 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) registerReceipt(rec, it.id, msg); } } - historyMessages.append(msg); + historyMessages.prepend(msg); } - std::swap(storedPrevId, previousId); - // int savedSliderPos = chatWidget->verticalScrollBar()->maximum() - chatWidget->verticalScrollBar()->value(); + previousId = storedPrevId; + int savedSliderPos = chatWidget->verticalScrollBar()->maximum() - chatWidget->verticalScrollBar()->value(); - // if (earliestMessage != nullptr) - // *earliestMessage = since; + earliestMessage = since; - // chatWidget->insertMessagesTop(historyMessages); + for(ChatMessage::Ptr m : historyMessages) + chatWidget->insertChatlineOnTop(m); - // savedSliderPos = chatWidget->verticalScrollBar()->maximum() - savedSliderPos; - // chatWidget->verticalScrollBar()->setValue(savedSliderPos); + savedSliderPos = chatWidget->verticalScrollBar()->maximum() - savedSliderPos; + chatWidget->verticalScrollBar()->setValue(savedSliderPos); } void ChatForm::onLoadHistory() diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index 4d1c7623c..aa5b2b8dc 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -32,9 +32,8 @@ #include "src/friend.h" #include "src/chatlog/chatlog.h" -GenericChatForm::GenericChatForm(QWidget *parent) : - QWidget(parent), - earliestMessage(nullptr) +GenericChatForm::GenericChatForm(QWidget *parent) + : QWidget(parent) , audioInputFlag(false) , audioOutputFlag(false) { @@ -300,11 +299,7 @@ void GenericChatForm::clearChatArea(bool notinform) if (!notinform) addSystemInfoMessage(tr("Cleared"), ChatMessage::INFO, QDateTime::currentDateTime()); - if (earliestMessage) - { - delete earliestMessage; - earliestMessage = nullptr; - } + earliestMessage = QDateTime(); //null emit chatAreaCleared(); } @@ -329,5 +324,5 @@ QString GenericChatForm::resolveToxID(const ToxID &id) void GenericChatForm::insertChatMessage(ChatMessage::Ptr msg) { - chatWidget->insertChatline(std::dynamic_pointer_cast(msg)); + chatWidget->insertChatlineAtBottom(std::dynamic_pointer_cast(msg)); } diff --git a/src/widget/form/genericchatform.h b/src/widget/form/genericchatform.h index 2ce36b48b..b741ab6b0 100644 --- a/src/widget/form/genericchatform.h +++ b/src/widget/form/genericchatform.h @@ -89,7 +89,7 @@ protected: ChatTextEdit *msgEdit; QPushButton *sendButton; ChatLog *chatWidget; - QDateTime *earliestMessage; + QDateTime earliestMessage; bool audioInputFlag; bool audioOutputFlag; }; From 27e967b67eff3910ed5f008a8215eb617bb53af8 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 4 Jan 2015 19:58:14 +0100 Subject: [PATCH 063/203] cleanup --- src/chatlog/content/text.cpp | 2 -- src/widget/form/chatform.cpp | 1 - 2 files changed, 3 deletions(-) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 1b827aa60..7f7334ed2 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -70,8 +70,6 @@ void Text::setWidth(qreal w) dirty = true; } - size = idealSize(); - ensureIntegrity(); freeResources(); } diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 683a3d2c8..6f0880c7a 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -704,7 +704,6 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) ToxID storedPrevId = previousId; ToxID prevId; - std::swap(storedPrevId, previousId); QList historyMessages; QDate lastDate(1,0,0); From bc97948be7a8f02a64b900e8ac7b8ab1901f0e78 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 4 Jan 2015 20:24:56 +0100 Subject: [PATCH 064/203] changed output of ChatLog::toPlainText --- src/chatlog/chatlog.cpp | 11 +---------- src/chatlog/content/text.cpp | 3 +++ src/chatlog/content/text.h | 2 +- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 1c0271992..a6bb68c71 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -445,19 +445,10 @@ QString ChatLog::getSelectedText() const QString ChatLog::toPlainText() const { QString out; - QString lastSender; for(ChatLine::Ptr l : lines) { - if(lastSender != l->content[0]->getText() && !l->content[0]->getText().isEmpty()) - { - //author changed - out += l->content[0]->getText() + ":\n"; - lastSender = l->content[0]->getText(); - } - - out += l->content[1]->getText(); - out += "\n\n"; + out += QString("|%1 @%2|\n%3\n\n").arg(l->getContent(0)->getText(),l->getContent(2)->getText(),l->getContent(1)->getText()); } return out; diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 7f7334ed2..af7fb53e8 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -52,6 +52,9 @@ void Text::setText(const QString& txt) text = txt; dirty = true; + if(rawText.isEmpty()) + rawText = txt; + ensureIntegrity(); freeResources(); } diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index 05c6cd017..a99a9516e 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -27,7 +27,7 @@ class CustomTextDocument; class Text : public ChatLineContent { public: - Text(const QString& txt = "", QFont font = QFont(), bool enableElide = false, const QString& rawText = ""); + Text(const QString& txt = "", QFont font = QFont(), bool enableElide = false, const QString& rawText = QString()); virtual ~Text(); void setText(const QString& txt); From c7fe34c077c3d5d315203797459978cea01affc9 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 5 Jan 2015 10:02:41 +0100 Subject: [PATCH 065/203] history: require markAsSent --- src/widget/form/chatform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 6f0880c7a..21c591429 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -727,7 +727,7 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) isAction ? it.message.right(it.message.length() - 4) : it.message, isAction, false, authorId.isMine(), - QDateTime::currentDateTime()); + QDateTime()); if(prevId == authorId) msg->hideSender(); From 77fe3f725611d31260b18e8812ddb475c6ae73b5 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 5 Jan 2015 10:51:01 +0100 Subject: [PATCH 066/203] ChatLog::insertChatlineOnTop: overload taking a list --- src/chatlog/chatlog.cpp | 30 +++++++++++++++++++++++++++++- src/chatlog/chatlog.h | 1 + src/widget/form/chatform.cpp | 5 ++--- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index a6bb68c71..215750df6 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -399,6 +399,34 @@ void ChatLog::insertChatlineOnTop(ChatLine::Ptr l) checkVisibility(); } +void ChatLog::insertChatlineOnTop(const QList& newLines) +{ + if(newLines.isEmpty()) + return; + + //move all lines down by n + int n = newLines.size(); + for(ChatLine::Ptr l : lines) + l->setRowIndex(l->getRowIndex() + n); + + //add the new line + for(ChatLine::Ptr l : newLines) + { + l->addToScene(scene); + l->setRowIndex(--n); + lines.prepend(l); + } + + //full refresh is required + layout(0, lines.size(), useableWidth()); + updateSceneRect(); + + if(stickToBtm) + scrollToBottom(); + + checkVisibility(); +} + bool ChatLog::stickToBottom() { return verticalScrollBar()->value() == verticalScrollBar()->maximum(); @@ -521,7 +549,7 @@ void ChatLog::checkVisibility() visibleLines = newVisibleLines; - // assure order + // enforce order std::sort(visibleLines.begin(), visibleLines.end(), [](const ChatLine::Ptr lhs, const ChatLine::Ptr rhs) { return lhs->getRowIndex() < rhs->getRowIndex(); diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 2df5f60ea..a75da65e9 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -39,6 +39,7 @@ public: void insertChatlineAtBottom(ChatLine::Ptr l); void insertChatlineOnTop(ChatLine::Ptr l); + void insertChatlineOnTop(const QList& newLines); void clearSelection(); void clear(); void copySelectedText() const; diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 21c591429..c80b9d01c 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -704,7 +704,7 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) ToxID storedPrevId = previousId; ToxID prevId; - QList historyMessages; + QList historyMessages; QDate lastDate(1,0,0); for (const auto &it : msgs) @@ -758,8 +758,7 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) earliestMessage = since; - for(ChatMessage::Ptr m : historyMessages) - chatWidget->insertChatlineOnTop(m); + chatWidget->insertChatlineOnTop(historyMessages); savedSliderPos = chatWidget->verticalScrollBar()->maximum() - savedSliderPos; chatWidget->verticalScrollBar()->setValue(savedSliderPos); From 960ebecc4eb4add5c1237d1802f11a3f28f719bb Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 5 Jan 2015 10:59:56 +0100 Subject: [PATCH 067/203] hopefully less noticeably partial updates --- src/chatlog/chatlog.cpp | 21 ++++++++++++--------- src/chatlog/chatlog.h | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 215750df6..7cdf996e3 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -101,7 +101,7 @@ void ChatLog::updateSceneRect() setSceneRect(QRectF(-margins.left(), -margins.top(), useableWidth(), (lines.empty() ? 0.0 : lines.last()->boundingSceneRect().bottom()) + margins.bottom() + margins.top())); } -bool ChatLog::layout(int start, int end, qreal width) +qreal ChatLog::layout(int start, int end, qreal width) { //qDebug() << "layout " << start << end; if(lines.empty()) @@ -112,7 +112,7 @@ bool ChatLog::layout(int start, int end, qreal width) qreal h = lines[start]->boundingSceneRect().top(); - bool needsReposition = false; + qreal deltaRepos = 0.0; for(int i = start; i < end; ++i) { ChatLine* l = lines[i].get(); @@ -121,16 +121,16 @@ bool ChatLog::layout(int start, int end, qreal width) l->layout(width, QPointF(0.0, h)); if(oldHeight != l->boundingSceneRect().height()) - needsReposition = true; + deltaRepos += oldHeight - l->boundingSceneRect().height(); h += l->boundingSceneRect().height() + lineSpacing; } // move up - if(needsReposition) - reposition(end-1, end+10); + if(deltaRepos != 0) + reposition(end-1, lines.size()); - return needsReposition; + return deltaRepos; } void ChatLog::partialUpdate() @@ -143,16 +143,19 @@ void ChatLog::partialUpdate() auto oldUpdateMode = viewportUpdateMode(); setViewportUpdateMode(NoViewportUpdate); - bool repos; + qreal repos; do { - repos = false; + repos = 0; if(!visibleLines.empty()) + { repos = layout(visibleLines.first()->getRowIndex(), visibleLines.last()->getRowIndex(), useableWidth()); + verticalScrollBar()->setValue(verticalScrollBar()->value() - repos); + } checkVisibility(); } - while(repos); + while(repos != 0); if(!visibleLines.empty()) reposition(visibleLines.last()->getRowIndex(), lines.size()); diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index a75da65e9..e126df6e0 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -53,7 +53,7 @@ protected: QRect getVisibleRect() const; ChatLineContent* getContentFromPos(QPointF scenePos) const; - bool layout(int start, int end, qreal width); + qreal layout(int start, int end, qreal width); bool isOverSelection(QPointF scenePos); bool stickToBottom(); From 5399b40874f39b974b9dc14edf052dc3d3a745d1 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 5 Jan 2015 14:05:01 +0100 Subject: [PATCH 068/203] history: fixed regression --- src/widget/form/chatform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index c80b9d01c..a0440e976 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -729,7 +729,7 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) authorId.isMine(), QDateTime()); - if(prevId == authorId) + if(!isAction && prevId == authorId) msg->hideSender(); prevId = authorId; From 4f01f5ec0e11db2f7c9b541fe13be09fe5dab0de Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 5 Jan 2015 14:06:14 +0100 Subject: [PATCH 069/203] refactoring --- src/chatlog/chatline.cpp | 9 +++----- src/chatlog/chatline.h | 2 +- src/chatlog/chatlinecontent.cpp | 10 --------- src/chatlog/chatlinecontent.h | 5 ----- src/chatlog/chatlog.cpp | 37 ++++----------------------------- src/chatlog/chatlog.h | 5 ++--- src/chatlog/chatmessage.cpp | 2 +- src/chatlog/content/image.h | 12 +++++------ src/chatlog/content/spinner.h | 12 +++++------ src/chatlog/content/text.cpp | 1 - 10 files changed, 23 insertions(+), 72 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index 877a0466d..40f1944be 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -140,8 +140,6 @@ void ChatLine::addColumn(ChatLineContent* item, ColumnFormat fmt) if(!item) return; - item->setChatLine(this); - format << fmt; content << item; } @@ -239,14 +237,13 @@ void ChatLine::layout(qreal w, QPointF scenePos) updateBBox(); } -void ChatLine::layout(QPointF scenePos) +void ChatLine::moveBy(qreal deltaY) { // reposition only - QPointF offset = pos - scenePos; for(ChatLineContent* c : content) - c->setPos(c->pos() - offset); + c->moveBy(0, deltaY); - pos = scenePos; + pos.setY(pos.y() + deltaY); updateBBox(); } diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index 2ddf89098..82b81ee92 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -65,7 +65,7 @@ public: void replaceContent(int col, ChatLineContent* lineContent); void layout(qreal width, QPointF scenePos); - void layout(QPointF scenePos); + void moveBy(qreal deltaY); void selectionCleared(); void selectionCleared(int col); diff --git a/src/chatlog/chatlinecontent.cpp b/src/chatlog/chatlinecontent.cpp index 0250b3674..2dd5a9584 100644 --- a/src/chatlog/chatlinecontent.cpp +++ b/src/chatlog/chatlinecontent.cpp @@ -16,16 +16,6 @@ #include "chatlinecontent.h" -void ChatLineContent::setChatLine(ChatLine* chatline) -{ - line = chatline; -} - -ChatLine* ChatLineContent::getChatLine() const -{ - return line; -} - void ChatLineContent::setIndex(int r, int c) { row = r; diff --git a/src/chatlog/chatlinecontent.h b/src/chatlog/chatlinecontent.h index 4796ac511..9cb2a3db8 100644 --- a/src/chatlog/chatlinecontent.h +++ b/src/chatlog/chatlinecontent.h @@ -29,8 +29,6 @@ public: ChatLineContentType = QGraphicsItem::UserType + 1, }; - ChatLine* getChatLine() const; - int getColumn() const; int getRow() const; @@ -56,12 +54,9 @@ public: private: friend class ChatLine; - void setIndex(int row, int col); - void setChatLine(ChatLine* chatline); private: - ChatLine* line = nullptr; int row = -1; int col = -1; }; diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 7cdf996e3..6e2efa23d 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -126,10 +126,6 @@ qreal ChatLog::layout(int start, int end, qreal width) h += l->boundingSceneRect().height() + lineSpacing; } - // move up - if(deltaRepos != 0) - reposition(end-1, lines.size()); - return deltaRepos; } @@ -150,6 +146,7 @@ void ChatLog::partialUpdate() if(!visibleLines.empty()) { repos = layout(visibleLines.first()->getRowIndex(), visibleLines.last()->getRowIndex(), useableWidth()); + reposition(visibleLines.last()->getRowIndex()+1, lines.size(), -repos); verticalScrollBar()->setValue(verticalScrollBar()->value() - repos); } @@ -157,9 +154,6 @@ void ChatLog::partialUpdate() } while(repos != 0); - if(!visibleLines.empty()) - reposition(visibleLines.last()->getRowIndex(), lines.size()); - checkVisibility(); setViewportUpdateMode(oldUpdateMode); @@ -318,7 +312,7 @@ qreal ChatLog::useableWidth() return width() - verticalScrollBar()->sizeHint().width() - margins.right() - margins.left(); } -void ChatLog::reposition(int start, int end) +void ChatLog::reposition(int start, int end, qreal deltaY) { if(lines.isEmpty()) return; @@ -326,33 +320,10 @@ void ChatLog::reposition(int start, int end) start = clamp(start, 0, lines.size() - 1); end = clamp(end + 1, 0, lines.size()); - qreal h = lines[start]->boundingSceneRect().bottom() + lineSpacing; - - for(int i = start + 1; i < end; ++i) + for(int i = start; i < end; ++i) { ChatLine* l = lines[i].get(); - l->layout(QPointF(0, h)); - h += l->boundingSceneRect().height() + lineSpacing; - } -} - -void ChatLog::repositionDownTo(int start, qreal end) -{ - if(lines.isEmpty()) - return; - - start = clamp(start, 0, lines.size() - 1); - - qreal h = lines[start]->boundingSceneRect().bottom() + lineSpacing; - - for(int i = start + 1; i < lines.size(); ++i) - { - ChatLine* l = lines[i].get(); - l->layout(QPointF(0, h)); - h += l->boundingSceneRect().height() + lineSpacing; - - if(h > end) - break; + l->moveBy(deltaY); } } diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index e126df6e0..efca339ec 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -59,8 +59,7 @@ protected: qreal useableWidth(); - void reposition(int start, int end); - void repositionDownTo(int start, qreal end); + void reposition(int start, int end, qreal deltaY); void updateSceneRect(); void partialUpdate(); void fullUpdate(); @@ -116,7 +115,7 @@ private: // layout QMarginsF margins = QMarginsF(10.0,10.0,10.0,10.0); - qreal lineSpacing = 10.0f; + qreal lineSpacing = 5.0f; }; diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 0a0e5b0bc..0f0f54a61 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -26,7 +26,7 @@ #include "src/misc/style.h" #define NAME_COL_WIDTH 75.0 -#define TIME_COL_WIDTH 85.0 +#define TIME_COL_WIDTH 90.0 ChatMessage::ChatMessage() { diff --git a/src/chatlog/content/image.h b/src/chatlog/content/image.h index 471596f6d..020c00b29 100644 --- a/src/chatlog/content/image.h +++ b/src/chatlog/content/image.h @@ -19,16 +19,16 @@ #include "../chatlinecontent.h" -class Image : public QObject, public ChatLineContent +class Image : 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 getAscent() const; + virtual QRectF boundingRect() const override; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; + virtual void setWidth(qreal width) override; + virtual QRectF boundingSceneRect() const override; + virtual qreal getAscent() const override; private: QSizeF size; diff --git a/src/chatlog/content/spinner.h b/src/chatlog/content/spinner.h index 6ab2e4b07..d73079f71 100644 --- a/src/chatlog/content/spinner.h +++ b/src/chatlog/content/spinner.h @@ -28,12 +28,12 @@ class Spinner : public QObject, public ChatLineContent public: Spinner(QSizeF size); - virtual QRectF boundingRect() const; - virtual QRectF boundingSceneRect() const; - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - virtual void setWidth(qreal width); - virtual void visibilityChanged(bool visible); - virtual qreal getAscent() const; + virtual QRectF boundingRect() const override; + virtual QRectF boundingSceneRect() const override; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; + virtual void setWidth(qreal width) override; + virtual void visibilityChanged(bool visible) override; + virtual qreal getAscent() const override; private slots: void timeout(); diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index af7fb53e8..67dc1e070 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include Text::Text(const QString& txt, QFont font, bool enableElide, const QString &rwText) From f7be91c6d0168e321be476157725737133e1160d Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 6 Jan 2015 10:05:01 +0100 Subject: [PATCH 070/203] change previousId on action --- src/widget/form/genericchatform.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index aa5b2b8dc..77fd6171a 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -211,8 +211,7 @@ ChatMessage::Ptr GenericChatForm::addMessage(const ToxID& author, const QString if(isSent) msg->markAsSent(datetime); - if(!isAction) - previousId = author; + previousId = author; return msg; } From 82746dc050ac472b417e6ffa889bbedbfe7ec443 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 6 Jan 2015 10:27:03 +0100 Subject: [PATCH 071/203] fixed first message not getting displayed properly --- src/chatlog/chatlog.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 6e2efa23d..317c0c42f 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -107,10 +107,13 @@ qreal ChatLog::layout(int start, int end, qreal width) if(lines.empty()) return false; - start = clamp(start, 0, lines.size() - 1); - end = clamp(end + 1, 0, lines.size()); + qreal h = 0.0; - qreal h = lines[start]->boundingSceneRect().top(); + if(start - 1 >= 0) + h = lines[start - 1]->boundingSceneRect().bottom() + lineSpacing; + + start = clamp(start, 0, lines.size()); + end = clamp(end + 1, 0, lines.size()); qreal deltaRepos = 0.0; for(int i = start; i < end; ++i) @@ -340,7 +343,7 @@ void ChatLog::insertChatlineAtBottom(ChatLine::Ptr l) lines.append(l); //partial refresh - layout(lines.last()->getRowIndex() - 1, lines.size(), useableWidth()); + layout(lines.last()->getRowIndex(), lines.size(), useableWidth()); updateSceneRect(); if(stickToBtm) From af575c09e6612c93c3153e1dca64704bcf1c5563 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 6 Jan 2015 10:28:15 +0100 Subject: [PATCH 072/203] cache innerStyle as it gets used frequently --- src/chatlog/customtextdocument.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/chatlog/customtextdocument.cpp b/src/chatlog/customtextdocument.cpp index fa1d213c7..c1dd1b96c 100644 --- a/src/chatlog/customtextdocument.cpp +++ b/src/chatlog/customtextdocument.cpp @@ -24,7 +24,9 @@ CustomTextDocument::CustomTextDocument(QObject *parent) : QTextDocument(parent) { - setDefaultStyleSheet(Style::getStylesheet(":ui/chatArea/innerStyle.css")); + static QString css = Style::getStylesheet(":ui/chatArea/innerStyle.css"); + + setDefaultStyleSheet(css); setUndoRedoEnabled(false); setUseDesignMetrics(false); } From 9793ebd0943e0e577a0a7c21ba5983332b7f9a72 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 6 Jan 2015 10:37:07 +0100 Subject: [PATCH 073/203] renamed deltaRepos to deltaY --- src/chatlog/chatlog.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 317c0c42f..47e66acc2 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -115,7 +115,7 @@ qreal ChatLog::layout(int start, int end, qreal width) start = clamp(start, 0, lines.size()); end = clamp(end + 1, 0, lines.size()); - qreal deltaRepos = 0.0; + qreal deltaY = 0.0; for(int i = start; i < end; ++i) { ChatLine* l = lines[i].get(); @@ -124,12 +124,12 @@ qreal ChatLog::layout(int start, int end, qreal width) l->layout(width, QPointF(0.0, h)); if(oldHeight != l->boundingSceneRect().height()) - deltaRepos += oldHeight - l->boundingSceneRect().height(); + deltaY += oldHeight - l->boundingSceneRect().height(); h += l->boundingSceneRect().height() + lineSpacing; } - return deltaRepos; + return deltaY; } void ChatLog::partialUpdate() From e365b0eb2df9fe8df3c2f3c75dd0b3cb8ec3cb57 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 6 Jan 2015 13:58:42 +0100 Subject: [PATCH 074/203] FileTransferWidget: limit browse to pics and archives --- src/chatlog/content/filetransferwidget.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index a89249d01..70200d7da 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -189,9 +189,14 @@ void FileTransferWidget::onFileTransferFinished(ToxFile file) setupButtons(); hideWidgets(); - ui->bottomButton->show(); - ui->bottomButton->setIcon(QIcon(":/ui/fileTransferInstance/browse_path.png")); - ui->bottomButton->setObjectName("browse"); + static const QStringList openExtensions = { "png", "jpeg", "jpg", "gif", "zip", "rar" }; + + if(openExtensions.contains(QFileInfo(file.fileName).suffix())) + { + ui->bottomButton->setIcon(QIcon(":/ui/fileTransferInstance/browse_path.png")); + ui->bottomButton->setObjectName("browse"); + ui->bottomButton->show(); + } // preview if(fileInfo.direction == ToxFile::RECEIVING) From 39bc3d73ec231168de67d97b10e5847ca57a5135 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 6 Jan 2015 14:02:57 +0100 Subject: [PATCH 075/203] qrc: added missing browse_path.png --- res.qrc | 1 + 1 file changed, 1 insertion(+) diff --git a/res.qrc b/res.qrc index 2623438f5..5b4261b12 100644 --- a/res.qrc +++ b/res.qrc @@ -232,6 +232,7 @@ ui/fileTransferInstance/no_2x.png ui/fileTransferInstance/yes_2x.png ui/fileTransferInstance/arrow_white_2x.png + ui/fileTransferInstance/browse_path.png ui/volButton/volButton.png ui/volButton/volButtonHover.png ui/volButton/volButtonPressed.png From 5c684d95ddd152a5c96d104106a23c57ae615899 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 6 Jan 2015 14:13:31 +0100 Subject: [PATCH 076/203] cleanup --- res.qrc | 10 ---------- ui/fileTransferInstance/acceptFileButton.png | Bin 449 -> 0 bytes ui/fileTransferInstance/emptyLGreenFileButton.png | Bin 236 -> 0 bytes ui/fileTransferInstance/emptyLRedFileButton.png | Bin 229 -> 0 bytes ui/fileTransferInstance/emptyRGreenFileButton.png | Bin 216 -> 0 bytes ui/fileTransferInstance/emptyRRedFileButton.png | Bin 211 -> 0 bytes ui/fileTransferInstance/pauseFileButton.png | Bin 308 -> 0 bytes ui/fileTransferInstance/pauseGreyFileButton.png | Bin 244 -> 0 bytes ui/fileTransferInstance/resumeFileButton.png | Bin 403 -> 0 bytes ui/fileTransferInstance/sliverRTEdge.png | Bin 225 -> 0 bytes ui/fileTransferInstance/stopFileButton.png | Bin 516 -> 0 bytes 11 files changed, 10 deletions(-) delete mode 100644 ui/fileTransferInstance/acceptFileButton.png delete mode 100644 ui/fileTransferInstance/emptyLGreenFileButton.png delete mode 100644 ui/fileTransferInstance/emptyLRedFileButton.png delete mode 100644 ui/fileTransferInstance/emptyRGreenFileButton.png delete mode 100644 ui/fileTransferInstance/emptyRRedFileButton.png delete mode 100644 ui/fileTransferInstance/pauseFileButton.png delete mode 100644 ui/fileTransferInstance/pauseGreyFileButton.png delete mode 100644 ui/fileTransferInstance/resumeFileButton.png delete mode 100644 ui/fileTransferInstance/sliverRTEdge.png delete mode 100644 ui/fileTransferInstance/stopFileButton.png diff --git a/res.qrc b/res.qrc index 5b4261b12..18c61ce88 100644 --- a/res.qrc +++ b/res.qrc @@ -171,16 +171,6 @@ ui/fileButton/fileButtonHover.png ui/fileButton/fileButtonPressed.png ui/fileButton/fileButtonDisabled.png - ui/fileTransferInstance/acceptFileButton.png - ui/fileTransferInstance/emptyLGreenFileButton.png - ui/fileTransferInstance/emptyLRedFileButton.png - ui/fileTransferInstance/emptyRGreenFileButton.png - ui/fileTransferInstance/emptyRRedFileButton.png - ui/fileTransferInstance/pauseFileButton.png - ui/fileTransferInstance/pauseGreyFileButton.png - ui/fileTransferInstance/resumeFileButton.png - ui/fileTransferInstance/stopFileButton.png - ui/fileTransferInstance/sliverRTEdge.png ui/fileTransferWidget/fileTransferWidget.css ui/friendList/friendList.css ui/micButton/micButton.css diff --git a/ui/fileTransferInstance/acceptFileButton.png b/ui/fileTransferInstance/acceptFileButton.png deleted file mode 100644 index b072344edf21d190098126c8e8347f186f5f262a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 449 zcmV;y0Y3hTP)P000~a1^@s6lq3|;00006VoOIv00000 z008+zyMF)x010qNS#tmY4#WTe4#WYKD-Ig~000McNliru-U$Z|C^G9aUl#xX0ZvIo zK~zY`?bSa^LQxpU@$WT3(;<|=o2D&6b3=oJLPaJRK`)`9EqXKJ*5FHMDZ?d)f^zv&L)mjhH=6(l6`^&C6i zh;Bd=sdcKfdQFz>9wI9Td?;_MF0APWG?Cl#H4+lr%VAtL8JA54&<$v2(j6$=lvAXN zmo&cWV*^9`M1qu{-5>3-Xfs_J^-yv6^gEfbg9kvxZQd#Uu5 zOIH^hW<722eYwnua@}>(A*wOg*U!6g_0zRSbEF%SIaA`9GQAX-I8`P%F#Y_TaAYOF bO1!+ycHvuBznnVgTJ1 zgUqL=Tw2TWDZ2kUqp9TkU)S4$SLfKiTPi4#rSM$JBb-^#L!psH2uOsu?_=IC6#wbT RsW71J44$rjF6*2UngHzC;6))4jD?RFP_#DWt4Sth3etGEB3qcdvCjZYtnlj9-hgWxt{kzcC-4=%y`j! zWn~%nGXo&l5MV57Xkc(BDIwv;xdR6bDp%cYT5iC}Fwa=HPEqvKVxWZ#p00i_>zopr E01O&O8vp?DTRUC2bn0f4jy?%jfQT-!IQLm)4)*KP@8t#{IJW&Qq>v ztn54#c((hHpx3K;YIO}?crMKle$B(wsQr5W0uA|y^bO~>I34*=_y6scbUTI2>l2tf xcC{UGkSmEeC}pvw?c;4-CL;w_A%%KL|CwRNyPjyWeg=Am!PC{xWt~$(69A-VY`p*g diff --git a/ui/fileTransferInstance/pauseGreyFileButton.png b/ui/fileTransferInstance/pauseGreyFileButton.png deleted file mode 100644 index 4bf1efd12a9b8c85874542b7633c3f62ecc6d303..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 244 zcmeAS@N?(olHy`uVBq!ia0vp^l0YoO!2%@hbniq1DW)WEcNYeRRlUkaKptm-M`SSr z1K$x4W}K?cCk+&2FY)wsWxvPC&Zof{WwFf|DAeld;uvCa`swA}oDBvdtq<*!98SvJ zJe-&ld+ZwP9EGLTOUhdoOmLDG3=zqbV$Cn_>bLP*G;OK7ndBo+mC19a$lILOQFlFb z>{Id@gNi@Xbfz8n;KReVSG~7#>tFfF!TO9H)mz*VLp{btdDiA_KUF?hQAxvXtaO0CD&kP%b)jOzY&JEm3bFN^3r`vH@Ggtx348QSB+@Nlxj?&t z^OPti=e?fn%~N;CMotr4>pUZPilUe9#D({kG#?DQGfm~RN7*!kagqJ*610@bz7 z;AK{3R(?Ba0|!vFr^+aBTHu@#mYXb+B0obUDk3TiS0yT5|6pHVZ#<`_v?uZS;-QdAJ*{+^Xuy+{Px-$+wl0JT3fk`l;0NBDH48DRMq3;5^sDjQ9rzUe!hm6 zOoeV_asJDUz*i-#w@-Lmb8H8bL16GPc)I$ztaD0e0syeflDYr@ diff --git a/ui/fileTransferInstance/sliverRTEdge.png b/ui/fileTransferInstance/sliverRTEdge.png deleted file mode 100644 index dd363d10799f5c83d81844040df4367462483a93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 225 zcmeAS@N?(olHy`uVBq!ia0vp^l0YoO!3HF!sEAwuQfx`y?k)`fL2$v|<&%LToCO|{ z#S9F5M?jcysy3fAP>{XE)7O>#9v8Eaf!XHWTYz#5d7dtgAs)xyURWr2$U(&Q;^Y-e z1SaIjera?K=9uIZbbPzZa<+m6M$HcI*8RF}SD1EBKv2H4>TxIQ_n=eT_!n3CT0Cqs zRnpU)a6iqaEMrB*_5E=cJ-5sr-;!!9=6`a7d1jS@kf+K-7ZCC8gt!5(XwS7B3=e=d OGkCiCxvXP000~a1^@s6lq3|;00006VoOIv00000 z008+zyMF)x010qNS#tmY4#WTe4#WYKD-Ig~000McNliru-U$Z|C=0YU*B<}?0g*{W zK~zY`-PPYKgHasE@%QwYJww}wW;Wzvn_4Rp3MH+Kwv>BCDK}jEKe+UN(2^)zxL0b( z%@(=Q^wb{qoQ|vKF{y2A&%*cabUNpCetbH|A*GaCXX`YebRY{H0((H->}a8JCH3T)er04z2G2{!|AH3O-huA$ChRwEnC^v!+g8|#^1 zEwagoFII65r5Z9Dm}jzgny@Dd!1=?e1uP9L<97#eDJs{`S3gJYUv3F|qWIdnSqP;7 z2f8Sd45jhA1860UyF#|UotP_M2&M3~b(0=k!H@yX{ zZ;Xq_%E#qs;P+d9x_&#N|G%fc*bGGd^XXCm#(Sr1Mcx61ev48+qsgiO0000 Date: Tue, 6 Jan 2015 14:30:24 +0100 Subject: [PATCH 077/203] error symbol --- res.qrc | 1 + src/chatlog/chatmessage.cpp | 11 +- src/chatlog/content/image.cpp | 2 +- ui/chatArea/error.png | Bin 0 -> 765 bytes ui/chatArea/symbols.svg | 188 ++++++++++++++++++++++------------ 5 files changed, 132 insertions(+), 70 deletions(-) create mode 100644 ui/chatArea/error.png diff --git a/res.qrc b/res.qrc index 18c61ce88..0b461bf8e 100644 --- a/res.qrc +++ b/res.qrc @@ -150,6 +150,7 @@ ui/chatArea/innerStyle.css ui/chatArea/spinner.png ui/chatArea/info.png + ui/chatArea/error.png ui/chatArea/scrollBarDownArrow.png ui/chatArea/scrollBarDownArrowHover.png ui/chatArea/scrollBarDownArrowPressed.png diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 0f0f54a61..687c02803 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -68,12 +68,17 @@ ChatMessage::Ptr ChatMessage::createChatInfoMessage(const QString &rawMessage, S { ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); - msg->addColumn(new Image(QSizeF(16, 16), ":/ui/chatArea/info.png"), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + QString img; + switch(type) + { + case INFO: img = ":/ui/chatArea/info.png"; break; + case ERROR: img = ":/ui/chatArea/error.png"; break; + } + + msg->addColumn(new Image(QSizeF(16, 16), img), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text(rawMessage, Style::getFont(Style::Big), false, rawMessage), ColumnFormat(1.0, ColumnFormat::VariableSize)); msg->addColumn(new Text(date.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - Q_UNUSED(type) - return msg; } diff --git a/src/chatlog/content/image.cpp b/src/chatlog/content/image.cpp index 768a3418b..bbea866a7 100644 --- a/src/chatlog/content/image.cpp +++ b/src/chatlog/content/image.cpp @@ -41,8 +41,8 @@ qreal Image::getAscent() const 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->translate(-size.width() / 2.0, -size.height() / 2.0); painter->drawPixmap(0, 0, size.width(), size.height(), pmap); Q_UNUSED(option) diff --git a/ui/chatArea/error.png b/ui/chatArea/error.png new file mode 100644 index 0000000000000000000000000000000000000000..06686cd6cfc5de2f50d81aea41d1b75bd8c5aa4e GIT binary patch literal 765 zcmVK`OOB;V@#G=bSdav)y?8J-yZd_Cgs8FEjhghq9(HHG`MqUk zzWIidkVqttve_y6z6;5XzBOcRW2I0yL&5Dr*Q51@4F zI0sw#eDGichnb8==_AO6zD~O(RYmTsmP+M;3>KKStd+Y`G!dg5t1_WS9OpcGoilel4n8|ou@4{X#mwMG~o+RFCgG#FYbeyHFd_FJ$ zFx_mf4-F0gB+Hams;bNd|yNe{34x7+E_q1G2VZRtkkP0HZL`SSb|F3?xNm)KEof zAClUOurzD~ZKeT$Q^z@g)H}UBg{11K;~aDhY~}NT$ep3_$(?q^+{pv0rBYdBWeD&} zccpwI5sii6Hh|g_@@o;JqX!kGp@hpIfFz6=gXjNF&HangTPB85miIgh-V}=`R$6|H vH6gNMrR835;D5fFb!()T)4LImdp-XP`?O-fisap<00000NkvXXu0mjfRMJ^w literal 0 HcmV?d00001 diff --git a/ui/chatArea/symbols.svg b/ui/chatArea/symbols.svg index 45f26aec3..6d7e04692 100644 --- a/ui/chatArea/symbols.svg +++ b/ui/chatArea/symbols.svg @@ -7,10 +7,34 @@ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.2" width="744.09448" height="1052.3622" - id="svg2"> + id="svg2" + inkscape:version="0.48.5 r10040" + sodipodi:docname="symbols.svg"> + - - - ! - - - i - - - i - + id="g3864" + transform="translate(-19.999993,-14.285714)"> + + ! + + + i + + + i + + + i From 0a6bd853082435421773f5d8fe7a7acd8723950f Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 6 Jan 2015 14:58:50 +0100 Subject: [PATCH 078/203] speed up ChatLine::moveBy --- src/chatlog/chatline.cpp | 16 ++++++---------- src/chatlog/chatline.h | 1 - 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index 40f1944be..2b680da4e 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -121,13 +121,11 @@ int ChatLine::getColumnCount() void ChatLine::updateBBox() { - bbox = QRectF(); - bbox.setTop(pos.y()); - bbox.setLeft(pos.x()); + bbox.setHeight(0); bbox.setWidth(width); for(ChatLineContent* c : content) - bbox.setHeight(qMax(c->sceneBoundingRect().bottom() - pos.y(), bbox.height())); + bbox.setHeight(qMax(c->sceneBoundingRect().height(), bbox.height())); } QRectF ChatLine::boundingSceneRect() const @@ -157,7 +155,7 @@ void ChatLine::replaceContent(int col, ChatLineContent *lineContent) if(scene) scene->addItem(content[col]); - layout(width, pos); + layout(width, bbox.topLeft()); content[col]->visibilityChanged(isVisible); content[col]->update(); } @@ -166,7 +164,7 @@ void ChatLine::replaceContent(int col, ChatLineContent *lineContent) void ChatLine::layout(qreal w, QPointF scenePos) { width = w; - pos = scenePos; + bbox.setTopLeft(scenePos); qreal fixedWidth = (content.size()-1) * CELL_SPACING; qreal varWidth = 0.0; // used for normalisation @@ -217,7 +215,7 @@ void ChatLine::layout(qreal w, QPointF scenePos) } // reposition - content[i]->setPos(pos.x() + xOffset + xAlign, pos.y()); + content[i]->setPos(scenePos.x() + xOffset + xAlign, scenePos.y()); xOffset += width + CELL_SPACING; } @@ -243,7 +241,5 @@ void ChatLine::moveBy(qreal deltaY) for(ChatLineContent* c : content) c->moveBy(0, deltaY); - pos.setY(pos.y() + deltaY); - - updateBBox(); + bbox.moveTop(bbox.top() + deltaY); } diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index 82b81ee92..4763ba086 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -96,7 +96,6 @@ private: QVector format; qreal width; QRectF bbox; - QPointF pos; bool isVisible = false; }; From e2d7dd815bd566168ee56b7bb8f341dc32047d01 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 6 Jan 2015 15:10:37 +0100 Subject: [PATCH 079/203] [test] use std::vector rather than QVector might be faster because std::vector doesn't do implicit sharing --- src/chatlog/chatline.cpp | 20 ++++++++++---------- src/chatlog/chatline.h | 5 +++-- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index 2b680da4e..b95b0af0c 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -44,7 +44,7 @@ void ChatLine::setRowIndex(int idx) { rowIndex = idx; - for(int c = 0; c < content.size(); ++c) + for(int c = 0; c < static_cast(content.size()); ++c) content[c]->setIndex(rowIndex, c); } @@ -66,7 +66,7 @@ int ChatLine::getRowIndex() const ChatLineContent *ChatLine::getContent(int col) const { - if(col < content.size() && col >= 0) + if(col < static_cast(content.size()) && col >= 0) return content[col]; return nullptr; @@ -98,7 +98,7 @@ void ChatLine::selectionCleared() void ChatLine::selectionCleared(int col) { - if(col < content.size() && content[col]) + if(col < static_cast(content.size()) && content[col]) content[col]->selectionCleared(); } @@ -110,7 +110,7 @@ void ChatLine::selectAll() void ChatLine::selectAll(int col) { - if(col < content.size() && content[col]) + if(col < static_cast(content.size()) && content[col]) content[col]->selectAll(); } @@ -138,13 +138,13 @@ void ChatLine::addColumn(ChatLineContent* item, ColumnFormat fmt) if(!item) return; - format << fmt; - content << item; + format.push_back(fmt); + content.push_back(item); } void ChatLine::replaceContent(int col, ChatLineContent *lineContent) { - if(col >= 0 && col < content.size() && lineContent) + if(col >= 0 && col < static_cast(content.size()) && lineContent) { QGraphicsScene* scene = content[col]->scene(); delete content[col]; @@ -169,7 +169,7 @@ void ChatLine::layout(qreal w, QPointF scenePos) qreal fixedWidth = (content.size()-1) * CELL_SPACING; qreal varWidth = 0.0; // used for normalisation - for(int i = 0; i < format.size(); ++i) + for(int i = 0; i < static_cast(format.size()); ++i) { if(format[i].policy == ColumnFormat::FixedSize) fixedWidth += format[i].size; @@ -185,7 +185,7 @@ void ChatLine::layout(qreal w, QPointF scenePos) qreal maxVOffset = 0.0; qreal xOffset = 0.0; - for(int i = 0; i < content.size(); ++i) + for(int i = 0; i < static_cast(content.size()); ++i) { maxVOffset = qMax(maxVOffset, content[i]->getAscent()); @@ -220,7 +220,7 @@ void ChatLine::layout(qreal w, QPointF scenePos) xOffset += width + CELL_SPACING; } - for(int i = 0; i < content.size(); ++i) + for(int i = 0; i < static_cast(content.size()); ++i) { // calculate vertical alignment // vertical alignment may depend on width, so we do it in a second pass diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index 4763ba086..cf91ed7fb 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -19,6 +19,7 @@ #include #include +#include class ChatLog; class ChatLineContent; @@ -92,8 +93,8 @@ protected: private: int rowIndex = -1; - QVector content; // 3 columns - QVector format; + std::vector content; // 3 columns + std::vector format; qreal width; QRectF bbox; bool isVisible = false; From 6c6d0254fc32583f2802847adcc5579d14bb5943 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 6 Jan 2015 15:12:39 +0100 Subject: [PATCH 080/203] plain svg --- ui/chatArea/symbols.svg | 181 ++++++++++++++++------------------------ 1 file changed, 72 insertions(+), 109 deletions(-) diff --git a/ui/chatArea/symbols.svg b/ui/chatArea/symbols.svg index 6d7e04692..77a4c5ce8 100644 --- a/ui/chatArea/symbols.svg +++ b/ui/chatArea/symbols.svg @@ -7,34 +7,10 @@ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.2" width="744.09448" height="1052.3622" - id="svg2" - inkscape:version="0.48.5 r10040" - sodipodi:docname="symbols.svg"> - + id="svg2"> + transform="translate(-19.999993,-14.285714)" + id="g3864"> + style="fill:#c84e4e;fill-opacity:1;stroke:#000000;stroke-width:16;stroke-linejoin:round;stroke-opacity:1" /> ! + transform="translate(-18.571423,8.5714286)" + id="g3857"> - i - - - i - - + transform="matrix(0.72483708,0,0,0.72483708,16.345817,46.658532)" + id="path3764" + style="fill:#6bc260;fill-opacity:1;stroke:#1c1c1c;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" /> i + x="95.714287" + y="926.64789" + id="rect2992-2" + style="fill:#1c1c1c;fill-opacity:1" />i + + + i + + + i From b92d4f3d2f275b8c83765c9f1c5adca3df8c96d1 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 6 Jan 2015 15:38:05 +0100 Subject: [PATCH 081/203] [test] use BspTreeIndex (might be slower?) --- src/chatlog/chatlog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 47e66acc2..c90adead0 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -39,7 +39,7 @@ ChatLog::ChatLog(QWidget* parent) : QGraphicsView(parent) { scene = new QGraphicsScene(this); - scene->setItemIndexMethod(QGraphicsScene::NoIndex); + scene->setItemIndexMethod(QGraphicsScene::BspTreeIndex); setScene(scene); setInteractive(true); From 1bf08981212bc5c265669ed9efb5b77669177926 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 6 Jan 2015 17:47:57 +0100 Subject: [PATCH 082/203] optimized ChatLog::getContentFromPos --- src/chatlog/chatline.cpp | 11 +++++++++++ src/chatlog/chatline.h | 1 + src/chatlog/chatlog.cpp | 22 +++++++++++++++++++--- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index b95b0af0c..4bb68a913 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -72,6 +72,17 @@ ChatLineContent *ChatLine::getContent(int col) const return nullptr; } +ChatLineContent *ChatLine::getContent(QPointF scenePos) const +{ + for(ChatLineContent* c: content) + { + if(c->sceneBoundingRect().contains(scenePos)) + return c; + } + + return nullptr; +} + void ChatLine::removeFromScene() { for(ChatLineContent* c : content) diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index cf91ed7fb..936537253 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -76,6 +76,7 @@ public: int getColumnCount(); int getRowIndex() const; ChatLineContent* getContent(int col) const; + ChatLineContent* getContent(QPointF scenePos) const; bool isOverSelection(QPointF scenePos); diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index c90adead0..217c67496 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -284,10 +284,26 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) ChatLineContent* ChatLog::getContentFromPos(QPointF scenePos) const { - QGraphicsItem* item = scene->itemAt(scenePos, QTransform()); + if(lines.empty()) + return nullptr; - if(item && item->type() == ChatLineContent::ChatLineContentType) - return static_cast(item); + QList::const_iterator upperBound; + upperBound = std::upper_bound(lines.cbegin(), lines.cend(), scenePos.y(), [](const qreal lhs, const ChatLine::Ptr rhs) + { + return lhs < rhs->boundingSceneRect().bottom(); + }); + + QList::const_iterator lowerBound; + lowerBound = std::lower_bound(lines.cbegin(), lines.cend(), scenePos.y(), [](const ChatLine::Ptr lhs, const qreal rhs) + { + return lhs->boundingSceneRect().top() < rhs; + }); + + for(auto itr = upperBound; itr != lowerBound; ++itr) + { + if((*itr)->boundingSceneRect().contains(scenePos)) + return (*itr)->getContent(scenePos); + } return nullptr; } From 1274c213d0d83fe39d3115b81f7b88a53854a29c Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 6 Jan 2015 20:22:30 +0100 Subject: [PATCH 083/203] Revert "[test] use BspTreeIndex (might be slower?)" This reverts commit b92d4f3d2f275b8c83765c9f1c5adca3df8c96d1. --- src/chatlog/chatlog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 217c67496..bf5a5bdfc 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -39,7 +39,7 @@ ChatLog::ChatLog(QWidget* parent) : QGraphicsView(parent) { scene = new QGraphicsScene(this); - scene->setItemIndexMethod(QGraphicsScene::BspTreeIndex); + scene->setItemIndexMethod(QGraphicsScene::NoIndex); setScene(scene); setInteractive(true); From debe6903a3cd3dac8d59c58571d6dc477b635fee Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 7 Jan 2015 13:05:28 +0100 Subject: [PATCH 084/203] faster scrolling, more cheating --- src/chatlog/chatline.cpp | 6 ++++++ src/chatlog/chatlog.cpp | 17 ++++++++++++----- src/chatlog/chatlog.h | 3 ++- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index 4bb68a913..9f2c9d72f 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -174,6 +174,12 @@ void ChatLine::replaceContent(int col, ChatLineContent *lineContent) void ChatLine::layout(qreal w, QPointF scenePos) { + if(width == w) + { + moveBy(scenePos.y() - bbox.top()); + return; + } + width = w; bbox.setTopLeft(scenePos); diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index bf5a5bdfc..dae6e44df 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -69,6 +69,11 @@ ChatLog::ChatLog(QWidget* parent) selectionTimer->setSingleShot(false); selectionTimer->start(); connect(selectionTimer, &QTimer::timeout, this, &ChatLog::onSelectionTimerTimeout); + + refreshTimer = new QTimer(this); + refreshTimer->setSingleShot(true); + refreshTimer->setInterval(100); + connect(refreshTimer, &QTimer::timeout, this, [this] { partialUpdate(); }); } ChatLog::~ChatLog() @@ -287,13 +292,13 @@ ChatLineContent* ChatLog::getContentFromPos(QPointF scenePos) const if(lines.empty()) return nullptr; - QList::const_iterator upperBound; + QVector::const_iterator upperBound; upperBound = std::upper_bound(lines.cbegin(), lines.cend(), scenePos.y(), [](const qreal lhs, const ChatLine::Ptr rhs) { return lhs < rhs->boundingSceneRect().bottom(); }); - QList::const_iterator lowerBound; + QVector::const_iterator lowerBound; lowerBound = std::lower_bound(lines.cbegin(), lines.cend(), scenePos.y(), [](const ChatLine::Ptr lhs, const qreal rhs) { return lhs->boundingSceneRect().top() < rhs; @@ -512,14 +517,14 @@ void ChatLog::checkVisibility() return; // find first visible row - QList::const_iterator upperBound; + QVector::const_iterator upperBound; upperBound = std::upper_bound(lines.cbegin(), lines.cend(), getVisibleRect().top(), [](const qreal lhs, const ChatLine::Ptr rhs) { return lhs < rhs->boundingSceneRect().bottom(); }); // find last visible row - QList::const_iterator lowerBound; + QVector::const_iterator lowerBound; lowerBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().bottom(), [](const ChatLine::Ptr lhs, const qreal rhs) { return lhs->boundingSceneRect().top() < rhs; @@ -555,7 +560,9 @@ void ChatLog::checkVisibility() void ChatLog::scrollContentsBy(int dx, int dy) { QGraphicsView::scrollContentsBy(dx, dy); - partialUpdate(); + if(!refreshTimer->isActive()) + refreshTimer->start(); + checkVisibility(); } void ChatLog::resizeEvent(QResizeEvent* ev) diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index efca339ec..05f1903e4 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -91,7 +91,7 @@ private: }; QGraphicsScene* scene = nullptr; - QList lines; + QVector lines; QList visibleLines; bool multiLineInsert = false; @@ -108,6 +108,7 @@ private: QPointF lastPos; QGraphicsRectItem* selGraphItem = nullptr; QTimer* selectionTimer = nullptr; + QTimer* refreshTimer = nullptr; AutoScrollDirection selectionScrollDir = NoDirection; // actions From 0f52bf3f5cc7795e99c59202a38fbb5faa044132 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 7 Jan 2015 13:16:09 +0100 Subject: [PATCH 085/203] moved history loading to FriendWidget::setAsActiveChatroom() --- src/widget/friendwidget.cpp | 11 +++++++++++ src/widget/friendwidget.h | 1 + src/widget/widget.cpp | 3 --- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/widget/friendwidget.cpp b/src/widget/friendwidget.cpp index 7ceb47df0..9f7227a1c 100644 --- a/src/widget/friendwidget.cpp +++ b/src/widget/friendwidget.cpp @@ -40,6 +40,7 @@ FriendWidget::FriendWidget(int FriendId, QString id) : friendId(FriendId) , isDefaultAvatar{true} + , historyLoaded{false} { avatar->setPixmap(QPixmap(":img/contact.png"), Qt::transparent); statusPic.setPixmap(QPixmap(":img/status/dot_away.png")); @@ -126,6 +127,16 @@ void FriendWidget::setAsActiveChatroom() if (isDefaultAvatar) avatar->setPixmap(QPixmap(":img/contact_dark.png"), Qt::transparent); + + if(!historyLoaded) + { + Friend* f = FriendList::findFriend(friendId); + if (Settings::getInstance().getEnableLogging()) + { + f->getChatForm()->loadHistory(QDateTime::currentDateTime().addDays(-7), true); + historyLoaded = true; + } + } } void FriendWidget::setAsInactiveChatroom() diff --git a/src/widget/friendwidget.h b/src/widget/friendwidget.h index 0223149b2..920a89b34 100644 --- a/src/widget/friendwidget.h +++ b/src/widget/friendwidget.h @@ -54,6 +54,7 @@ protected: public: int friendId; bool isDefaultAvatar; + bool historyLoaded; QPoint dragStartPos; }; diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 8e94a2593..949024b29 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -663,9 +663,6 @@ void Widget::addFriend(int friendId, const QString &userId) QLayout* layout = contactListWidget->getFriendLayout(Status::Offline); layout->addWidget(newfriend->getFriendWidget()); - if (Settings::getInstance().getEnableLogging()) - newfriend->getChatForm()->loadHistory(QDateTime::currentDateTime().addDays(-7), true); - connect(newfriend->getFriendWidget(), SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), this, SLOT(onChatroomWidgetClicked(GenericChatroomWidget*))); connect(newfriend->getFriendWidget(), SIGNAL(removeFriend(int)), this, SLOT(removeFriend(int))); connect(newfriend->getFriendWidget(), SIGNAL(copyFriendIdToClipboard(int)), this, SLOT(copyFriendIdToClipboard(int))); From 39d2bbb3413d88eb9909cce09606125a3a05fbae Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 7 Jan 2015 15:03:02 +0100 Subject: [PATCH 086/203] towards better scrolling Experimental changes! Known bug: Scrolling gets extremly slow while the cursor is inside qTox's main window. Cause: Unknown. --- src/chatlog/chatline.cpp | 6 ----- src/chatlog/chatlog.cpp | 56 +++++++++++++++++++++++++++++++++++++--- src/chatlog/chatlog.h | 4 +++ 3 files changed, 57 insertions(+), 9 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index 9f2c9d72f..4bb68a913 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -174,12 +174,6 @@ void ChatLine::replaceContent(int col, ChatLineContent *lineContent) void ChatLine::layout(qreal w, QPointF scenePos) { - if(width == w) - { - moveBy(scenePos.y() - bbox.top()); - return; - } - width = w; bbox.setTopLeft(scenePos); diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index dae6e44df..568337ecd 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -72,8 +72,54 @@ ChatLog::ChatLog(QWidget* parent) refreshTimer = new QTimer(this); refreshTimer->setSingleShot(true); - refreshTimer->setInterval(100); + refreshTimer->setInterval(500); connect(refreshTimer, &QTimer::timeout, this, [this] { partialUpdate(); }); + + workerTimer = new QTimer(this); + workerTimer->setSingleShot(false); + workerTimer->setInterval(100); + connect(workerTimer, &QTimer::timeout, this, [this] { + const int stepSize = 200; + + workerDy += layout(lastWorkerIndex, lastWorkerIndex+stepSize, useableWidth()); + + qDebug() << "working... " << lastWorkerIndex << "/" << lines.size(); + + if(!visibleLines.isEmpty()) + { + int firstVisLineIndex = visibleLines.first()->getRowIndex(); + int delta = firstVisLineIndex - lastWorkerIndex; + if(delta > 0 && delta < stepSize) + { + //qDebug() << "delta " << delta << "fvl " << firstVisLineIndex; + lastWorkerIndex += delta+1; + + if(!stickToBottom()) + verticalScrollBar()->setValue(verticalScrollBar()->value() - workerDy); + + workerDy = 0.0; + checkVisibility(); + } + else + lastWorkerIndex += stepSize; + } + else + lastWorkerIndex += stepSize; + + if(lastWorkerIndex >= lines.size()) + { + workerTimer->stop(); + lastWorkerIndex = 0; + workerDy = 0.0; + + bool stb = stickToBottom(); + updateSceneRect(); + if(stb) + scrollToBottom(); + + qDebug() << "working... done!"; + } + }); } ChatLog::~ChatLog() @@ -108,7 +154,6 @@ void ChatLog::updateSceneRect() qreal ChatLog::layout(int start, int end, qreal width) { - //qDebug() << "layout " << start << end; if(lines.empty()) return false; @@ -154,7 +199,7 @@ void ChatLog::partialUpdate() if(!visibleLines.empty()) { repos = layout(visibleLines.first()->getRowIndex(), visibleLines.last()->getRowIndex(), useableWidth()); - reposition(visibleLines.last()->getRowIndex()+1, lines.size(), -repos); + reposition(visibleLines.last()->getRowIndex()+1, visibleLines.last()->getRowIndex()+10, -repos); verticalScrollBar()->setValue(verticalScrollBar()->value() - repos); } @@ -580,6 +625,11 @@ void ChatLog::resizeEvent(QResizeEvent* ev) scrollToBottom(); updateMultiSelectionRect(); + + qDebug() << "starting worker"; + lastWorkerIndex = 0; + workerDy = 0.0; + workerTimer->start(); } void ChatLog::updateMultiSelectionRect() diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 05f1903e4..067d4ebc2 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -109,8 +109,12 @@ private: QGraphicsRectItem* selGraphItem = nullptr; QTimer* selectionTimer = nullptr; QTimer* refreshTimer = nullptr; + QTimer* workerTimer = nullptr; AutoScrollDirection selectionScrollDir = NoDirection; + int lastWorkerIndex = 0; + qreal workerDy = 0; + // actions QAction* copyAction = nullptr; From d21a00e8d5f7db03ca8f1ecde54287f2d7189891 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 9 Jan 2015 15:48:58 +0100 Subject: [PATCH 087/203] cleanup --- src/chatlog/chatlog.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 568337ecd..af51f3182 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -70,11 +70,6 @@ ChatLog::ChatLog(QWidget* parent) selectionTimer->start(); connect(selectionTimer, &QTimer::timeout, this, &ChatLog::onSelectionTimerTimeout); - refreshTimer = new QTimer(this); - refreshTimer->setSingleShot(true); - refreshTimer->setInterval(500); - connect(refreshTimer, &QTimer::timeout, this, [this] { partialUpdate(); }); - workerTimer = new QTimer(this); workerTimer->setSingleShot(false); workerTimer->setInterval(100); @@ -605,8 +600,7 @@ void ChatLog::checkVisibility() void ChatLog::scrollContentsBy(int dx, int dy) { QGraphicsView::scrollContentsBy(dx, dy); - if(!refreshTimer->isActive()) - refreshTimer->start(); + partialUpdate(); checkVisibility(); } From ed65261e374e1701b819bb9e3808d6188fc91bc0 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 9 Jan 2015 15:50:13 +0100 Subject: [PATCH 088/203] Text: copy image keys --- src/chatlog/content/text.cpp | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 67dc1e070..0a591b27a 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -27,6 +27,7 @@ #include #include #include +#include Text::Text(const QString& txt, QFont font, bool enableElide, const QString &rwText) : rawText(rwText) @@ -83,7 +84,38 @@ void Text::selectionMouseMove(QPointF scenePos) if(cur >= 0) { cursor.setPosition(cur, QTextCursor::KeepAnchor); - selectedText = cursor.selectedText(); + selectedText.clear(); + + QTextBlock block = cursor.block(); + for(QTextBlock::Iterator itr = block.begin(); itr!=block.end(); ++itr) + { + int pos = itr.fragment().position(); //fragment position -> position of the first character in the fragment + + if(itr.fragment().charFormat().isImageFormat()) + { + QTextImageFormat imgFmt = itr.fragment().charFormat().toImageFormat(); + QString key = imgFmt.name(); //img key (eg. key::D for :D) + QString rune = key.mid(4); + + if(pos >= cursor.selectionStart() && pos < cursor.selectionEnd()) + { + selectedText += rune; + pos++; + } + } + else + { + text = itr.fragment().text(); + + for(QChar c : text) + { + if(pos >= cursor.selectionStart() && pos < cursor.selectionEnd()) + selectedText += c; + + pos++; + } + } + } } update(); From 95dca34865f1d0920a7a3645c12e818cbec6ce5a Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 9 Jan 2015 15:50:23 +0100 Subject: [PATCH 089/203] cleanup --- src/chatlog/chatlog.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 067d4ebc2..afd0e548b 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -108,7 +108,6 @@ private: QPointF lastPos; QGraphicsRectItem* selGraphItem = nullptr; QTimer* selectionTimer = nullptr; - QTimer* refreshTimer = nullptr; QTimer* workerTimer = nullptr; AutoScrollDirection selectionScrollDir = NoDirection; From 904627e50af63e287c95972bc5bb04b519ccc14a Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 10 Jan 2015 11:57:46 +0100 Subject: [PATCH 090/203] moved typing notifications to ChatLog --- res.qrc | 5 ++-- src/chatlog/chatline.cpp | 6 +++++ src/chatlog/chatline.h | 2 ++ src/chatlog/chatlog.cpp | 44 ++++++++++++++++++++++++++++++++++- src/chatlog/chatlog.h | 6 +++++ src/chatlog/chatmessage.cpp | 5 ++-- src/chatlog/chatmessage.h | 1 + src/widget/form/chatform.cpp | 22 +++++++----------- src/widget/form/chatform.h | 1 - ui/chatArea/innerStyle.css | 5 ++++ ui/chatArea/symbols.svg | 23 ++++++++++++++++++ ui/chatArea/typing.png | Bin 0 -> 580 bytes 12 files changed, 101 insertions(+), 19 deletions(-) create mode 100644 ui/chatArea/typing.png diff --git a/res.qrc b/res.qrc index d4a844ede..eff10c320 100644 --- a/res.qrc +++ b/res.qrc @@ -151,7 +151,7 @@ ui/chatArea/innerStyle.css ui/chatArea/spinner.png ui/chatArea/info.png - ui/chatArea/error.png + ui/chatArea/error.png ui/chatArea/scrollBarDownArrow.png ui/chatArea/scrollBarDownArrowHover.png ui/chatArea/scrollBarDownArrowPressed.png @@ -224,7 +224,7 @@ ui/fileTransferInstance/no_2x.png ui/fileTransferInstance/yes_2x.png ui/fileTransferInstance/arrow_white_2x.png - ui/fileTransferInstance/browse_path.png + ui/fileTransferInstance/browse_path.png ui/volButton/volButton.png ui/volButton/volButtonHover.png ui/volButton/volButtonPressed.png @@ -232,5 +232,6 @@ ui/window/applicationIcon.png ui/window/statusPanel.css ui/window/window.css + ui/chatArea/typing.png diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index 4bb68a913..801825c9e 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -101,6 +101,12 @@ void ChatLine::addToScene(QGraphicsScene *scene) scene->addItem(c); } +void ChatLine::setVisible(bool visible) +{ + for(ChatLineContent* c : content) + c->setVisible(visible); +} + void ChatLine::selectionCleared() { for(ChatLineContent* c : content) diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index 936537253..458e9c436 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -83,6 +83,8 @@ public: void removeFromScene(); void addToScene(QGraphicsScene* scene); + void setVisible(bool visible); + protected: QPointF mapToContent(ChatLineContent* c, QPointF pos); void addColumn(ChatLineContent* item, ColumnFormat fmt); diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index af51f3182..7df19da9e 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -144,7 +144,12 @@ QRect ChatLog::getVisibleRect() const void ChatLog::updateSceneRect() { - setSceneRect(QRectF(-margins.left(), -margins.top(), useableWidth(), (lines.empty() ? 0.0 : lines.last()->boundingSceneRect().bottom()) + margins.bottom() + margins.top())); + qreal bottom = (lines.empty() ? 0.0 : lines.last()->boundingSceneRect().bottom()); + + if(typingNotification.get() != nullptr) + bottom += typingNotification->boundingSceneRect().height() + lineSpacing; + + setSceneRect(QRectF(-margins.left(), -margins.top(), useableWidth(), bottom + margins.bottom() + margins.top())); } qreal ChatLog::layout(int start, int end, qreal width) @@ -530,6 +535,11 @@ bool ChatLog::hasTextToBeCopied() const return selectionMode != None; } +ChatLine::Ptr ChatLog::getTypingNotification() const +{ + return typingNotification; +} + void ChatLog::clear() { clearSelection(); @@ -551,6 +561,24 @@ void ChatLog::copySelectedText() const clipboard->setText(text); } +void ChatLog::setTypingNotification(ChatLine::Ptr notification) +{ + typingNotification = notification; + typingNotification->visibilityChanged(true); + typingNotification->setVisible(false); + typingNotification->addToScene(scene); + updateTypingNotification(); +} + +void ChatLog::setTypingNotificationVisible(bool visible) +{ + if(typingNotification.get() != nullptr) + { + typingNotification->setVisible(visible); + updateTypingNotification(); + } +} + void ChatLog::checkVisibility() { if(lines.empty()) @@ -643,6 +671,20 @@ void ChatLog::updateMultiSelectionRect() } } +void ChatLog::updateTypingNotification() +{ + ChatLine* notification = typingNotification.get(); + if(!notification) + return; + + qreal posY = 0.0; + + if(!lines.empty()) + posY = lines.last()->boundingSceneRect().bottom() + lineSpacing; + + notification->layout(useableWidth(), QPointF(0.0, posY)); +} + void ChatLog::onSelectionTimerTimeout() { const int scrollSpeed = 10; diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index afd0e548b..b00067174 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -43,12 +43,16 @@ public: void clearSelection(); void clear(); void copySelectedText() const; + void setTypingNotification(ChatLine::Ptr notification); + void setTypingNotificationVisible(bool visible); QString getSelectedText() const; QString toPlainText() const; bool isEmpty() const; bool hasTextToBeCopied() const; + ChatLine::Ptr getTypingNotification() const; + protected: QRect getVisibleRect() const; ChatLineContent* getContentFromPos(QPointF scenePos) const; @@ -73,6 +77,7 @@ protected: virtual void resizeEvent(QResizeEvent *ev); void updateMultiSelectionRect(); + void updateTypingNotification(); private slots: void onSelectionTimerTimeout(); @@ -93,6 +98,7 @@ private: QGraphicsScene* scene = nullptr; QVector lines; QList visibleLines; + ChatLine::Ptr typingNotification; bool multiLineInsert = false; bool stickToBtm = false; diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 687c02803..6f1a40023 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -71,8 +71,9 @@ ChatMessage::Ptr ChatMessage::createChatInfoMessage(const QString &rawMessage, S QString img; switch(type) { - case INFO: img = ":/ui/chatArea/info.png"; break; - case ERROR: img = ":/ui/chatArea/error.png"; break; + case INFO: img = ":/ui/chatArea/info.png"; break; + case ERROR: img = ":/ui/chatArea/error.png"; break; + case TYPING: img = ":/ui/chatArea/typing.png"; break; } msg->addColumn(new Image(QSizeF(16, 16), img), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); diff --git a/src/chatlog/chatmessage.h b/src/chatlog/chatmessage.h index 233ed19da..c03ed8991 100644 --- a/src/chatlog/chatmessage.h +++ b/src/chatlog/chatmessage.h @@ -32,6 +32,7 @@ public: { INFO, ERROR, + TYPING, }; ChatMessage(); diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 0874e696e..3d3349edb 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -40,6 +40,7 @@ #include "src/misc/cstring.h" #include "src/chatlog/chatmessage.h" #include "src/chatlog/content/filetransferwidget.h" +#include "src/chatlog/content/text.h" #include "src/chatlog/chatlog.h" ChatForm::ChatForm(Friend* chatFriend) @@ -55,18 +56,11 @@ ChatForm::ChatForm(Friend* chatFriend) statusMessageLabel->setFont(Style::getFont(Style::Medium)); statusMessageLabel->setMinimumHeight(Style::getFont(Style::Medium).pixelSize()); - isTypingLabel = new QLabel(); - QFont font = isTypingLabel->font(); - font.setItalic(true); - font.setPixelSize(8); - isTypingLabel->setFont(font); - - QVBoxLayout* mainLayout = dynamic_cast(layout()); - mainLayout->insertWidget(1, isTypingLabel); - netcam = new NetCamView(); timer = nullptr; + chatWidget->setTypingNotification(ChatMessage::createChatInfoMessage("", ChatMessage::TYPING, QDateTime())); + headTextLayout->addWidget(statusMessageLabel); headTextLayout->addStretch(); callDuration = new QLabel(); @@ -883,10 +877,12 @@ void ChatForm::dischargeReceipt(int receipt) void ChatForm::setFriendTyping(bool isTyping) { - if (isTyping) - isTypingLabel->setText(f->getDisplayedName() + " " + tr("is typing...")); - else - isTypingLabel->clear(); + chatWidget->setTypingNotificationVisible(isTyping); + + Text* text = dynamic_cast(chatWidget->getTypingNotification()->getContent(1)); + + if(text) + text->setText("
" + tr("%1 is typing...").arg(f->getDisplayedName()) + "
"); } void ChatForm::clearReciepts() diff --git a/src/widget/form/chatform.h b/src/widget/form/chatform.h index 031de32b7..18616b803 100644 --- a/src/widget/form/chatform.h +++ b/src/widget/form/chatform.h @@ -101,7 +101,6 @@ private: QLabel *callDuration; QTimer *timer; QElapsedTimer timeElapsed; - QLabel *isTypingLabel; QHash ftransWidgets; void startCounter(); diff --git a/ui/chatArea/innerStyle.css b/ui/chatArea/innerStyle.css index fcafe5b6a..cc67f1f7c 100644 --- a/ui/chatArea/innerStyle.css +++ b/ui/chatArea/innerStyle.css @@ -8,6 +8,11 @@ div.action { font: @big; } +div.typing { + color: @black; + font: @bigBold; +} + span.quote { color: #279419; } diff --git a/ui/chatArea/symbols.svg b/ui/chatArea/symbols.svg index 77a4c5ce8..2f98a2d74 100644 --- a/ui/chatArea/symbols.svg +++ b/ui/chatArea/symbols.svg @@ -110,4 +110,27 @@ style="fill:#1c1c1c;fill-opacity:1" />i + + + + + diff --git a/ui/chatArea/typing.png b/ui/chatArea/typing.png new file mode 100644 index 0000000000000000000000000000000000000000..8e0f08478c6abfdca4a5c77affa3cb9879ef3230 GIT binary patch literal 580 zcmV-K0=xZ*P)}6F9=qCfZ$6XOcY{{#oprXHS3Pt-B}MzvwP;@zt5aA zJCh>9P?1u4h;`hJh_ycwB4Ut%A(gJV zl+qkN;b2SZo0$SUlW{{k7%Z1w&b?Uk_azNHD_(PWoB{R|hl|4D6t*(p?iKG=yv_jo zhTTQsa5)1kaHTe{0N6ZMGr&GzW_)gmtz-!c8F|+uVypI~XV>7PG&u~vN zz&3E8C>+jYfCcU}YV-t_@IC|VGj=xV^wkiHIGK@mGa|k>zU{%aU8=)ln`>`P94<>Z zw~Rd*dDmj}HI31+YlrYdyK5^sdR;qr33Dwu>#B{pJ$k6Q^Qtava_v^GR_Dj`l+sar zRBb1l>Q1iWNJMPpX!X$$_c4ndBe3VHa~v$?f}!( Date: Sat, 10 Jan 2015 22:21:33 +0100 Subject: [PATCH 091/203] tweaks, colorize the blue * in /me --- src/chatlog/chatlog.cpp | 9 +++------ src/chatlog/chatmessage.cpp | 8 +++++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 7df19da9e..0c1d7e731 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -74,19 +74,16 @@ ChatLog::ChatLog(QWidget* parent) workerTimer->setSingleShot(false); workerTimer->setInterval(100); connect(workerTimer, &QTimer::timeout, this, [this] { - const int stepSize = 200; + const int stepSize = 400; workerDy += layout(lastWorkerIndex, lastWorkerIndex+stepSize, useableWidth()); - qDebug() << "working... " << lastWorkerIndex << "/" << lines.size(); - if(!visibleLines.isEmpty()) { int firstVisLineIndex = visibleLines.first()->getRowIndex(); int delta = firstVisLineIndex - lastWorkerIndex; if(delta > 0 && delta < stepSize) { - //qDebug() << "delta " << delta << "fvl " << firstVisLineIndex; lastWorkerIndex += delta+1; if(!stickToBottom()) @@ -96,7 +93,9 @@ ChatLog::ChatLog(QWidget* parent) checkVisibility(); } else + { lastWorkerIndex += stepSize; + } } else lastWorkerIndex += stepSize; @@ -111,8 +110,6 @@ ChatLog::ChatLog(QWidget* parent) updateSceneRect(); if(stb) scrollToBottom(); - - qDebug() << "working... done!"; } }); } diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 6f1a40023..822ee1d1e 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -25,7 +25,7 @@ #include "src/misc/smileypack.h" #include "src/misc/style.h" -#define NAME_COL_WIDTH 75.0 +#define NAME_COL_WIDTH 90.0 #define TIME_COL_WIDTH 90.0 ChatMessage::ChatMessage() @@ -39,9 +39,11 @@ ChatMessage::Ptr ChatMessage::createChatMessage(const QString &sender, const QSt QString text = toHtmlChars(rawMessage); + //smileys if(Settings::getInstance().getUseEmoticons()) text = SmileyPack::getInstance().smileyfied(text); + //quotes (green text) text = detectQuotes(detectAnchors(text)); if(isAction) @@ -54,7 +56,7 @@ ChatMessage::Ptr ChatMessage::createChatMessage(const QString &sender, const QSt text = "
" + text + "
"; } - msg->addColumn(new Text(isAction ? "*" : sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + msg->addColumn(new Text(isAction ? "
*
" : sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), isAction ? false : true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text(text, Style::getFont(Style::Big), false, rawMessage), ColumnFormat(1.0, ColumnFormat::VariableSize)); msg->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); @@ -77,7 +79,7 @@ ChatMessage::Ptr ChatMessage::createChatInfoMessage(const QString &rawMessage, S } msg->addColumn(new Image(QSizeF(16, 16), img), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - msg->addColumn(new Text(rawMessage, Style::getFont(Style::Big), false, rawMessage), ColumnFormat(1.0, ColumnFormat::VariableSize)); + msg->addColumn(new Text(rawMessage, Style::getFont(Style::Big), false, rawMessage), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Center)); msg->addColumn(new Text(date.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); return msg; From f574a435810428ca0bffeedc79d04d29e06df722 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 11 Jan 2015 11:57:33 +0100 Subject: [PATCH 092/203] FileTransferWidget: fixed autoaccept --- src/chatlog/chatlinecontentproxy.cpp | 5 +++ src/chatlog/chatlinecontentproxy.h | 2 + src/chatlog/content/filetransferwidget.cpp | 48 ++++++++++++++++++---- src/chatlog/content/filetransferwidget.h | 6 ++- src/widget/form/chatform.cpp | 12 ++++-- 5 files changed, 61 insertions(+), 12 deletions(-) diff --git a/src/chatlog/chatlinecontentproxy.cpp b/src/chatlog/chatlinecontentproxy.cpp index 0325763fc..129f6fe5b 100644 --- a/src/chatlog/chatlinecontentproxy.cpp +++ b/src/chatlog/chatlinecontentproxy.cpp @@ -47,6 +47,11 @@ qreal ChatLineContentProxy::getAscent() const return proxy->widget()->layout()->contentsMargins().top(); } +QWidget *ChatLineContentProxy::getWidget() const +{ + return proxy->widget(); +} + void ChatLineContentProxy::setWidth(qreal width) { proxy->widget()->setFixedWidth(qMax(static_cast(width*widthPercent), widthMin)); diff --git a/src/chatlog/chatlinecontentproxy.h b/src/chatlog/chatlinecontentproxy.h index da435fd91..b73fb126a 100644 --- a/src/chatlog/chatlinecontentproxy.h +++ b/src/chatlog/chatlinecontentproxy.h @@ -31,6 +31,8 @@ public: virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); virtual qreal getAscent() const; + QWidget* getWidget() const; + private: QGraphicsProxyWidget* proxy; int widthMin; diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index 70200d7da..553d68c23 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -22,8 +22,7 @@ #include #include -#include -#include +#include #include #include #include @@ -69,19 +68,54 @@ FileTransferWidget::~FileTransferWidget() delete ui; } -void FileTransferWidget::acceptTransfer(const QString &path) +void FileTransferWidget::autoAcceptTransfer(const QString &path) { - if(!QFileInfo(QDir(path).path()).isWritable()) + QString filepath; + int number = 0; + + QString suffix = QFileInfo(fileInfo.fileName).completeSuffix(); + QString base = QFileInfo(fileInfo.fileName).completeBaseName(); + + do + { + filepath = QString("%1/%2%3.%4").arg(path, base, number > 0 ? QString(" (%1)").arg(QString::number(number)) : QString(), suffix); + number++; + } + while(QFileInfo(filepath).exists()); + + if(!isFilePathWritable(filepath)) { QMessageBox::warning(0, 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")); - return; } - if(!path.isEmpty()) - Core::getInstance()->acceptFileRecvRequest(fileInfo.friendId, fileInfo.fileNum, path); + //everything ok! + Core::getInstance()->acceptFileRecvRequest(fileInfo.friendId, fileInfo.fileNum, filepath); +} + +void FileTransferWidget::acceptTransfer(const QString &filepath) +{ + //test if writable + if(isFilePathWritable(filepath)) + { + QMessageBox::warning(0, + 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")); + return; + } + + //everything ok! + Core::getInstance()->acceptFileRecvRequest(fileInfo.friendId, fileInfo.fileNum, filepath); +} + +bool FileTransferWidget::isFilePathWritable(const QString &filepath) +{ + QFile tmp(filepath); + bool writable = tmp.open(QIODevice::WriteOnly); + tmp.remove(); + return writable; } void FileTransferWidget::onFileTransferInfo(ToxFile file) diff --git a/src/chatlog/content/filetransferwidget.h b/src/chatlog/content/filetransferwidget.h index 90a3e2eee..34c0d7581 100644 --- a/src/chatlog/content/filetransferwidget.h +++ b/src/chatlog/content/filetransferwidget.h @@ -35,8 +35,7 @@ class FileTransferWidget : public QWidget public: explicit FileTransferWidget(QWidget *parent, ToxFile file); virtual ~FileTransferWidget(); - - void acceptTransfer(const QString& path); + void autoAcceptTransfer(const QString& path); protected slots: void onFileTransferInfo(ToxFile file); @@ -51,6 +50,9 @@ protected: void setupButtons(); void handleButton(QPushButton* btn); void showPreview(const QString& filename); + void acceptTransfer(const QString& filepath); + + bool isFilePathWritable(const QString& filepath); private slots: void on_topButton_clicked(); diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 3d3349edb..99b481170 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -40,6 +40,7 @@ #include "src/misc/cstring.h" #include "src/chatlog/chatmessage.h" #include "src/chatlog/content/filetransferwidget.h" +#include "src/chatlog/chatlinecontentproxy.h" #include "src/chatlog/content/text.h" #include "src/chatlog/chatlog.h" @@ -222,9 +223,14 @@ void ChatForm::onFileRecvRequest(ToxFile file) if (!Settings::getInstance().getAutoAcceptDir(f->getToxID()).isEmpty() || Settings::getInstance().getAutoSaveEnabled()) { - FileTransferWidget* tfWidget = dynamic_cast(msg->getContent(1)); - if(tfWidget) - tfWidget->acceptTransfer(Settings::getInstance().getAutoAcceptDir(f->getToxID())); + ChatLineContentProxy* proxy = dynamic_cast(msg->getContent(1)); + if(proxy) + { + FileTransferWidget* tfWidget = dynamic_cast(proxy->getWidget()); + + if(tfWidget) + tfWidget->autoAcceptTransfer(Settings::getInstance().getAutoAcceptDir(f->getToxID())); + } } } From 85568337e3cebc6ce867bceba43b62671fcab059 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 11 Jan 2015 11:58:50 +0100 Subject: [PATCH 093/203] cleanup --- qtox.pro | 2 - src/chatlog/chatlog.cpp | 1 - src/filetransferinstance.cpp | 507 ----------------------------------- src/filetransferinstance.h | 87 ------ src/widget/form/chatform.cpp | 1 - 5 files changed, 598 deletions(-) delete mode 100644 src/filetransferinstance.cpp delete mode 100644 src/filetransferinstance.h diff --git a/qtox.pro b/qtox.pro index d8c76f360..69a37c204 100644 --- a/qtox.pro +++ b/qtox.pro @@ -157,7 +157,6 @@ HEADERS += src/widget/form/addfriendform.h \ src/widget/friendlistwidget.h \ src/widget/genericchatroomwidget.h \ src/widget/form/genericchatform.h \ - src/filetransferinstance.h \ src/corestructs.h \ src/coredefines.h \ src/coreav.h \ @@ -229,7 +228,6 @@ SOURCES += \ src/coreav.cpp \ src/widget/genericchatroomwidget.cpp \ src/widget/form/genericchatform.cpp \ - src/filetransferinstance.cpp \ src/corestructs.cpp \ src/widget/maskablepixmapwidget.cpp \ src/video/cameraworker.cpp \ diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 0c1d7e731..15f62a806 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -645,7 +645,6 @@ void ChatLog::resizeEvent(QResizeEvent* ev) updateMultiSelectionRect(); - qDebug() << "starting worker"; lastWorkerIndex = 0; workerDy = 0.0; workerTimer->start(); diff --git a/src/filetransferinstance.cpp b/src/filetransferinstance.cpp deleted file mode 100644 index bf690cdd1..000000000 --- a/src/filetransferinstance.cpp +++ /dev/null @@ -1,507 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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 "core.h" -#include "misc/settings.h" -#include "misc/style.h" -#include "src/friendlist.h" -#include "src/friend.h" -#include -#include -#include -#include -#include -#include - -#define MAX_CONTENT_WIDTH 250 -#define MAX_PREVIEW_SIZE 25*1024*1024 - -uint FileTransferInstance::Idconter = 0; - -FileTransferInstance::FileTransferInstance(ToxFile File) - : lastBytesSent{0}, - fileNum{File.fileNum}, friendId{File.friendId}, direction{File.direction} -{ - id = Idconter++; - state = tsPending; - remotePaused = false; - lastUpdateTime = QDateTime::currentDateTime(); - - filename = File.fileName; - - // update this whenever you change the font in innerStyle.css - QFontMetrics fm(Style::getFont(Style::Small)); - - filenameElided = fm.elidedText(filename, Qt::ElideRight, MAX_CONTENT_WIDTH); - size = getHumanReadableSize(File.filesize); - contentPrefWidth = std::max(fm.width(filenameElided), fm.width(size)) + fm.leading(); - - speed = "0B/s"; - eta = "00:00"; - - if (File.direction == ToxFile::SENDING) - { - if (File.file->size() <= MAX_PREVIEW_SIZE) - { - QImage preview; - File.file->seek(0); - if (preview.loadFromData(File.file->readAll())) - { - pic = preview.scaled(100, 50, Qt::KeepAspectRatio, Qt::SmoothTransformation); - } - } - 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 now = QDateTime::currentDateTime(); - long recenttimediff = lastUpdateTime.msecsTo(now); - if (recenttimediff < 1000) //update every 1s - return; - - long timediff = effStartTime.msecsTo(now); - if (timediff <= 0) - return; - - long avgspeed = (BytesSent - previousBytesSent) / timediff * 1000; - long recentspeed = (BytesSent - lastBytesSent) / recenttimediff * 1000; - - speed = getHumanReadableSize(recentspeed)+"/s"; - size = getHumanReadableSize(Filesize); - totalBytes = Filesize; - - if (!avgspeed) - return; - int etaSecs = (Filesize - BytesSent) / avgspeed; - QTime etaTime(0,0); - etaTime = etaTime.addSecs(etaSecs); - eta = etaTime.toString("mm:ss"); - - lastBytesSent = BytesSent; - lastUpdateTime = now; - emit stateUpdated(); -} - -void FileTransferInstance::onFileTransferCancelled(int FriendId, int FileNum, ToxFile::FileDirection Direction) -{ - if (FileNum != fileNum || FriendId != friendId || Direction != direction) - return; - disconnect(Core::getInstance(),0,this,0); - state = tsCanceled; - - emit stateUpdated(); -} - -void FileTransferInstance::onFileTransferFinished(ToxFile File) -{ - if (File.fileNum != fileNum || File.friendId != friendId || File.direction != direction) - return; - disconnect(Core::getInstance(),0,this,0); - - if (File.direction == ToxFile::RECEIVING) - { - QImage preview; - QFile previewFile(File.filePath); - if (previewFile.open(QIODevice::ReadOnly) && previewFile.size() <= MAX_PREVIEW_SIZE) // Don't preview big (>25MiB) images - { - if (preview.loadFromData(previewFile.readAll())) - { - pic = preview.scaled(100, 50, Qt::KeepAspectRatio, Qt::SmoothTransformation); - } - previewFile.close(); - } - } - - state = tsFinished; - - emit stateUpdated(); -} - -void FileTransferInstance::onFileTransferAccepted(ToxFile File) -{ - if (File.fileNum != fileNum || File.friendId != friendId || File.direction != direction) - return; - - remotePaused = false; - state = tsProcessing; - effStartTime = QDateTime::currentDateTime(); - - emit stateUpdated(); -} - -void FileTransferInstance::onFileTransferRemotePausedUnpaused(ToxFile File, bool paused) -{ - if (File.fileNum != fileNum || File.friendId != friendId || File.direction != direction) - return; - - remotePaused = paused; - - emit stateUpdated(); -} - -void FileTransferInstance::onFileTransferPaused(int FriendId, int FileNum, ToxFile::FileDirection Direction) -{ - if (FileNum != fileNum || FriendId != friendId || Direction != direction) - return; - - state = tsPaused; - - emit stateUpdated(); -} - -void FileTransferInstance::cancelTransfer() -{ - Core::getInstance()->cancelFileSend(friendId, fileNum); - state = tsCanceled; - emit stateUpdated(); -} - -void FileTransferInstance::rejectRecvRequest() -{ - Core::getInstance()->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 = Settings::getInstance().getAutoAcceptDir(FriendList::findFriend(friendId)->getToxID()); - - if (path.isEmpty() && Settings::getInstance().getAutoSaveEnabled()) - path = Settings::getInstance().getGlobalAutoAcceptDir(); - - if (!path.isEmpty()) - { - QDir dir(path); - path = dir.filePath(filename); - QFileInfo info(path); - if (info.exists()) // emulate chrome - { - QString name = info.baseName(), ext = info.completeSuffix(); - int i = 0; - do - { - path = dir.filePath(name + QString(" (%1)").arg(++i) + "." + ext); - } - while (QFileInfo(path).exists()); - } - qDebug() << "File: auto saving to" << path; - } - else - { - while (true) - { - path = QFileDialog::getSaveFileName(0, tr("Save a file","Title of the file saving dialog"), QDir::home().filePath(filename)); - if (path.isEmpty()) - return; - else - { - if (isFileWritable(path)) - break; - else - QMessageBox::warning(0, - 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; - - Core::getInstance()->acceptFileRecvRequest(friendId, fileNum, path); - state = tsProcessing; - - effStartTime = QDateTime::currentDateTime(); - - emit stateUpdated(); -} - -void FileTransferInstance::pauseResumeRecv() -{ - if (!(state == tsProcessing || state == tsPaused)) - return; - - if (remotePaused) - return; - - Core::getInstance()->pauseResumeFileRecv(friendId, fileNum); - - if (state == tsPaused) - { - effStartTime = QDateTime::currentDateTime(); - previousBytesSent = lastBytesSent; - } - - emit stateUpdated(); -} - -void FileTransferInstance::pauseResumeSend() -{ - if (!(state == tsProcessing || state == tsPaused)) - return; - - if (remotePaused) - return; - - Core::getInstance()->pauseResumeFileSend(friendId, fileNum); - - if (state == tsPaused) - { - effStartTime = QDateTime::currentDateTime(); - previousBytesSent = lastBytesSent; - } - - emit stateUpdated(); -} - -QString FileTransferInstance::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 FileTransferInstance::getHtmlImage() -{ - - QString res; - if (state == tsPending || state == tsProcessing || state == tsPaused) - { - QImage leftBtnImg(":/ui/fileTransferInstance/stopFileButton.png"); - QImage rightBtnImg; - if (state == tsProcessing) - rightBtnImg = QImage(":/ui/fileTransferInstance/pauseFileButton.png"); - else if (state == tsPaused) - rightBtnImg = QImage(":/ui/fileTransferInstance/resumeFileButton.png"); - else - { - if (direction == ToxFile::SENDING) - rightBtnImg = QImage(":/ui/fileTransferInstance/pauseGreyFileButton.png"); - else - rightBtnImg = QImage(":/ui/fileTransferInstance/acceptFileButton.png"); - } - - if (remotePaused) - rightBtnImg = QImage(":/ui/fileTransferInstance/pauseGreyFileButton.png"); - - res = draw2ButtonsForm("silver", leftBtnImg, rightBtnImg); - } else if (state == tsBroken) - { - QImage leftBtnImg(":/ui/fileTransferInstance/stopFileButton.png"); - QImage rightBtnImg(":/ui/fileTransferInstance/pauseGreyFileButton.png"); - - res = draw2ButtonsForm("red", leftBtnImg, rightBtnImg); - } else if (state == tsCanceled) - { - res = drawButtonlessForm("red"); - } else if (state == tsFinished) - { - res = drawButtonlessForm("green"); - } - - return res; -} - -void FileTransferInstance::pressFromHtml(QString code) -{ - if (state == tsFinished || state == tsCanceled) - return; - - if (direction == ToxFile::SENDING) - { - if (code == "btnA") - cancelTransfer(); - else if (code == "btnB") - pauseResumeSend(); - } else { - if (code == "btnA") - rejectRecvRequest(); - else if (code == "btnB") - { - if (state == tsPending) - acceptRecvRequest(); - else - pauseResumeRecv(); - } - } -} - -QString FileTransferInstance::drawButtonlessForm(const QString &type) -{ - QString imgAStr; - QString imgBStr; - - if (type == "red") - { - imgAStr = ""; - imgBStr = ""; - } else { - imgAStr = ""; - imgBStr = ""; - } - - QString content = "

" + filenameElided + "

" + size + "

"; - - return wrapIntoForm(content, type, imgAStr, imgBStr); -} - -QString FileTransferInstance::insertMiniature(const QString &type) -{ - if (pic == QImage()) - return QString(); - - QString widgetId = QString::number(getId()); - - QString res; - res = "
\n"; - res += ""; - res += "
\n"; - res += "
\n"; - res += "
\n"; - return res; -} - -QString FileTransferInstance::draw2ButtonsForm(const QString &type, const QImage &imgA, const QImage &imgB) -{ - QString widgetId = QString::number(getId()); - QString imgAstr = ""; - QString imgBstr = ""; - - QString content; - QString progrBar = ""; - - content = "

" + filenameElided + "

"; - content += ""; - content += ""; - content += ""; - content += ""; - content += "
" + size + "" + speed + "" + tr("ETA") + ": " + eta + "
"; - content += progrBar; - content += "
"; - - return wrapIntoForm(content, type, imgAstr, imgBstr); -} - -QString FileTransferInstance::wrapIntoForm(const QString& content, const QString &type, const QString &imgAstr, const QString &imgBstr) -{ - QString w = QString::number(QImage(":/ui/fileTransferInstance/emptyLRedFileButton.png").size().width()); - QString imgLeftA, imgLeftB; - - if (type == "green") - { - imgLeftA = ""; - imgLeftB = ""; - } - - if (type == "silver") - { - imgLeftA = ""; - imgLeftB = ""; - } - - if (type == "red") - { - imgLeftA = ""; - imgLeftB = ""; - } - - QString res; - res = "\n"; - res += "\n"; - res += "\n"; - res += insertMiniature(type); - res += "\n"; - res += "\n"; - res += "\n"; - res += "\n"; - res += "
\n"; - res += "
" + imgLeftA + "
" + imgLeftB + "
\n"; - res += "
\n"; - res += "
"; - res += content; - res += "
\n"; - res += "
\n"; - res += "
\n"; - res += "
\n"; - res += "
" + imgAstr + "
" + imgBstr + "
\n"; - res += "
\n"; - - return res; -} - -QImage FileTransferInstance::drawProgressBarImg(const double &part, int w, int h) -{ - QImage progressBar(w, h, QImage::Format_Mono); - - QPainter qPainter(&progressBar); - qPainter.setBrush(Qt::NoBrush); - qPainter.setPen(Qt::black); - qPainter.drawRect(0, 0, w - 1, h - 1); - - qPainter.setBrush(Qt::SolidPattern); - qPainter.setPen(Qt::black); - qPainter.drawRect(1, 0, (w - 2) * (part), h - 1); - - return progressBar; -} - -void FileTransferInstance::onFileTransferBrokenUnbroken(ToxFile File, bool broken) -{ - if (File.fileNum != fileNum || File.friendId != friendId || File.direction != direction) - return; - - if (broken) - state = tsBroken; - else - state = tsProcessing; - - emit stateUpdated(); -} diff --git a/src/filetransferinstance.h b/src/filetransferinstance.h deleted file mode 100644 index 386e8bd01..000000000 --- a/src/filetransferinstance.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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 -#include -#include - -#include "corestructs.h" - -struct ToxFile; - -class FileTransferInstance : public QObject -{ - Q_OBJECT -public: - enum TransfState {tsPending, tsProcessing, tsPaused, tsFinished, tsCanceled, tsBroken}; - -public: - explicit FileTransferInstance(ToxFile File); - QString getHtmlImage(); - uint getId(){return id;} - TransfState getState() {return state;} - -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 onFileTransferAccepted(ToxFile File); - void onFileTransferPaused(int FriendId, int FileNum, ToxFile::FileDirection Direction); - void onFileTransferRemotePausedUnpaused(ToxFile File, bool paused); - void onFileTransferBrokenUnbroken(ToxFile File, bool broken); - 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); - QString QImage2base64(const QImage &img); - QString drawButtonlessForm(const QString &type); - QString draw2ButtonsForm(const QString &type, const QImage &imgA, const QImage &imgB); - QString insertMiniature(const QString &type); - QString wrapIntoForm(const QString &content, const QString &type, const QString &imgAstr, const QString &imgBstr); - QImage drawProgressBarImg(const double &part, int w, int h); - -private: - static uint Idconter; - uint id; - - TransfState state; - bool remotePaused; - QImage pic; - QString filename, size, speed, eta; - QString filenameElided; - QDateTime effStartTime, lastUpdateTime; - long long lastBytesSent, totalBytes, previousBytesSent = 0; // last var used for eta on resumes - int fileNum; - int friendId; - int contentPrefWidth; - QString savePath; - ToxFile::FileDirection direction; - QString stopFileButtonStylesheet, pauseFileButtonStylesheet, acceptFileButtonStylesheet; -}; - -#endif // FILETRANSFERINSTANCE_H diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 99b481170..44ffc4b81 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -28,7 +28,6 @@ #include "src/widget/form/loadhistorydialog.h" #include "src/friend.h" #include "src/widget/friendwidget.h" -#include "src/filetransferinstance.h" #include "src/widget/netcamview.h" #include "src/widget/tool/chattextedit.h" #include "src/core.h" From 62b4b831060413ca9387fcbcf608f2b1f65d2a8c Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 11 Jan 2015 12:04:35 +0100 Subject: [PATCH 094/203] tweaked FileTransferWidget min size --- src/chatlog/chatmessage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 822ee1d1e..4e55cea2d 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -90,7 +90,7 @@ ChatMessage::Ptr ChatMessage::createFileTransferMessage(const QString& sender, T ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); msg->addColumn(new Text(sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - msg->addColumn(new ChatLineContentProxy(new FileTransferWidget(0, file), 380, 0.6f), ColumnFormat(1.0, ColumnFormat::VariableSize)); + msg->addColumn(new ChatLineContentProxy(new FileTransferWidget(0, file), 350, 0.6f), ColumnFormat(1.0, ColumnFormat::VariableSize)); msg->addColumn(new Text(date.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); return msg; From 29fc6ab03fb09f322b53ca35e3e0fad9e53e9790 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 12 Jan 2015 16:03:47 +0100 Subject: [PATCH 095/203] FileTransferWidget: use baseName instead of completeBaseName + tweaked autoAccept --- src/chatlog/content/filetransferwidget.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index 553d68c23..6d087a018 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -74,7 +74,7 @@ void FileTransferWidget::autoAcceptTransfer(const QString &path) int number = 0; QString suffix = QFileInfo(fileInfo.fileName).completeSuffix(); - QString base = QFileInfo(fileInfo.fileName).completeBaseName(); + QString base = QFileInfo(fileInfo.fileName).baseName(); do { @@ -83,16 +83,12 @@ void FileTransferWidget::autoAcceptTransfer(const QString &path) } while(QFileInfo(filepath).exists()); - if(!isFilePathWritable(filepath)) - { - QMessageBox::warning(0, - 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")); - return; - } - - //everything ok! - Core::getInstance()->acceptFileRecvRequest(fileInfo.friendId, fileInfo.fileNum, filepath); + //Do not automatically accept the file-transfer if the path is not writable. + //The user can still accept it manually. + if(isFilePathWritable(filepath)) + Core::getInstance()->acceptFileRecvRequest(fileInfo.friendId, fileInfo.fileNum, filepath); + else + qDebug() << "Warning: Cannot write to " << filepath; } void FileTransferWidget::acceptTransfer(const QString &filepath) From fb0c372c81d1593b7ac138629dfc15243d0ca929 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 13 Jan 2015 23:59:38 +0100 Subject: [PATCH 096/203] cleanup --- src/chatlog/chatlog.cpp | 27 ++++++++++++++------------- src/chatlog/chatlog.h | 11 +++-------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 15f62a806..004b084ba 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -207,14 +207,12 @@ void ChatLog::partialUpdate() checkVisibility(); setViewportUpdateMode(oldUpdateMode); - updateSceneRect(); } void ChatLog::fullUpdate() { layout(0, lines.size(), useableWidth()); checkVisibility(); - updateSceneRect(); } void ChatLog::mousePressEvent(QMouseEvent* ev) @@ -292,10 +290,8 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) } } - if(selectionMode != None && ev->pos() != lastPos) + if(selectionMode != None) { - lastPos = ev->pos(); - ChatLineContent* content = getContentFromPos(scenePos); if(content) @@ -355,7 +351,7 @@ ChatLineContent* ChatLog::getContentFromPos(QPointF scenePos) const return nullptr; } -bool ChatLog::isOverSelection(QPointF scenePos) +bool ChatLog::isOverSelection(QPointF scenePos) const { if(selectionMode == Precise) { @@ -373,7 +369,7 @@ bool ChatLog::isOverSelection(QPointF scenePos) return false; } -qreal ChatLog::useableWidth() +qreal ChatLog::useableWidth() const { return width() - verticalScrollBar()->sizeHint().width() - margins.right() - margins.left(); } @@ -398,11 +394,11 @@ void ChatLog::insertChatlineAtBottom(ChatLine::Ptr l) if(!l.get()) return; - l->addToScene(scene); - - stickToBtm = stickToBottom(); + bool stickToBtm = stickToBottom(); + //insert l->setRowIndex(lines.size()); + l->addToScene(scene); lines.append(l); //partial refresh @@ -420,6 +416,8 @@ void ChatLog::insertChatlineOnTop(ChatLine::Ptr l) if(!l.get()) return; + bool stickToBtm = stickToBottom(); + //move all lines down by 1 for(ChatLine::Ptr l : lines) l->setRowIndex(l->getRowIndex() + 1); @@ -444,6 +442,8 @@ void ChatLog::insertChatlineOnTop(const QList& newLines) if(newLines.isEmpty()) return; + bool stickToBtm = stickToBottom(); + //move all lines down by n int n = newLines.size(); for(ChatLine::Ptr l : lines) @@ -467,16 +467,15 @@ void ChatLog::insertChatlineOnTop(const QList& newLines) checkVisibility(); } -bool ChatLog::stickToBottom() +bool ChatLog::stickToBottom() const { return verticalScrollBar()->value() == verticalScrollBar()->maximum(); } void ChatLog::scrollToBottom() { + updateSceneRect(); verticalScrollBar()->setValue(verticalScrollBar()->maximum()); - updateGeometry(); - checkVisibility(); } QString ChatLog::getSelectedText() const @@ -581,6 +580,8 @@ void ChatLog::checkVisibility() if(lines.empty()) return; + updateSceneRect(); + // find first visible row QVector::const_iterator upperBound; upperBound = std::upper_bound(lines.cbegin(), lines.cend(), getVisibleRect().top(), [](const qreal lhs, const ChatLine::Ptr rhs) diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index b00067174..f92a7a76d 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -58,10 +58,10 @@ protected: ChatLineContent* getContentFromPos(QPointF scenePos) const; qreal layout(int start, int end, qreal width); - bool isOverSelection(QPointF scenePos); - bool stickToBottom(); + bool isOverSelection(QPointF scenePos) const; + bool stickToBottom() const; - qreal useableWidth(); + qreal useableWidth() const; void reposition(int start, int end, qreal deltaY); void updateSceneRect(); @@ -100,10 +100,6 @@ private: QList visibleLines; ChatLine::Ptr typingNotification; - bool multiLineInsert = false; - bool stickToBtm = false; - int insertStartIndex = -1; - // selection int selClickedRow = -1; int selClickedCol = -1; @@ -111,7 +107,6 @@ private: int selLastRow = -1; SelectionMode selectionMode = None; QPointF clickPos; - QPointF lastPos; QGraphicsRectItem* selGraphItem = nullptr; QTimer* selectionTimer = nullptr; QTimer* workerTimer = nullptr; From bde32d2171ce18501e29df6c1cd7f60f259b485e Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 14 Jan 2015 10:34:52 +0100 Subject: [PATCH 097/203] cleanup --- src/chatlog/chatlog.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 004b084ba..38efd4e63 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -330,19 +330,20 @@ ChatLineContent* ChatLog::getContentFromPos(QPointF scenePos) const if(lines.empty()) return nullptr; - QVector::const_iterator upperBound; - upperBound = std::upper_bound(lines.cbegin(), lines.cend(), scenePos.y(), [](const qreal lhs, const ChatLine::Ptr rhs) + //the first visible line + auto lowerBound = std::upper_bound(lines.cbegin(), lines.cend(), scenePos.y(), [](const qreal lhs, const ChatLine::Ptr rhs) { return lhs < rhs->boundingSceneRect().bottom(); }); - QVector::const_iterator lowerBound; - lowerBound = std::lower_bound(lines.cbegin(), lines.cend(), scenePos.y(), [](const ChatLine::Ptr lhs, const qreal rhs) + //the last visible line + auto upperBound = std::lower_bound(lines.cbegin(), lines.cend(), scenePos.y(), [](const ChatLine::Ptr lhs, const qreal rhs) { return lhs->boundingSceneRect().top() < rhs; }); - for(auto itr = upperBound; itr != lowerBound; ++itr) + //find content + for(auto itr = lowerBound; itr != upperBound; ++itr) { if((*itr)->boundingSceneRect().contains(scenePos)) return (*itr)->getContent(scenePos); @@ -582,23 +583,21 @@ void ChatLog::checkVisibility() updateSceneRect(); - // find first visible row - QVector::const_iterator upperBound; - upperBound = std::upper_bound(lines.cbegin(), lines.cend(), getVisibleRect().top(), [](const qreal lhs, const ChatLine::Ptr rhs) + // find first visible line + auto lowerBound = std::upper_bound(lines.cbegin(), lines.cend(), getVisibleRect().top(), [](const qreal lhs, const ChatLine::Ptr rhs) { return lhs < rhs->boundingSceneRect().bottom(); }); - // find last visible row - QVector::const_iterator lowerBound; - lowerBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().bottom(), [](const ChatLine::Ptr lhs, const qreal rhs) + // find last visible line + auto upperBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().bottom(), [](const ChatLine::Ptr lhs, const qreal rhs) { return lhs->boundingSceneRect().top() < rhs; }); // set visibilty QList newVisibleLines; - for(auto itr = upperBound; itr != lowerBound; ++itr) + for(auto itr = lowerBound; itr != upperBound; ++itr) { newVisibleLines.append(*itr); @@ -608,6 +607,7 @@ void ChatLog::checkVisibility() visibleLines.removeOne(*itr); } + // these lines are no longer visible for(ChatLine::Ptr line : visibleLines) line->visibilityChanged(false); @@ -627,7 +627,6 @@ void ChatLog::scrollContentsBy(int dx, int dy) { QGraphicsView::scrollContentsBy(dx, dy); partialUpdate(); - checkVisibility(); } void ChatLog::resizeEvent(QResizeEvent* ev) From 4930b326415eddc32b977ad905f48b4b0b6958ee Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 14 Jan 2015 10:56:44 +0100 Subject: [PATCH 098/203] fixed chatlog not scrolling to bottom after resize --- src/chatlog/chatlog.cpp | 37 ++++++++++++++++++++++--------------- src/chatlog/chatlog.h | 4 +++- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 38efd4e63..092815b5e 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -76,17 +76,17 @@ ChatLog::ChatLog(QWidget* parent) connect(workerTimer, &QTimer::timeout, this, [this] { const int stepSize = 400; - workerDy += layout(lastWorkerIndex, lastWorkerIndex+stepSize, useableWidth()); + workerDy += layout(workerLastIndex, workerLastIndex+stepSize, useableWidth()); if(!visibleLines.isEmpty()) { int firstVisLineIndex = visibleLines.first()->getRowIndex(); - int delta = firstVisLineIndex - lastWorkerIndex; + int delta = firstVisLineIndex - workerLastIndex; if(delta > 0 && delta < stepSize) { - lastWorkerIndex += delta+1; + workerLastIndex += delta+1; - if(!stickToBottom()) + if(!workerStb) verticalScrollBar()->setValue(verticalScrollBar()->value() - workerDy); workerDy = 0.0; @@ -94,21 +94,19 @@ ChatLog::ChatLog(QWidget* parent) } else { - lastWorkerIndex += stepSize; + workerLastIndex += stepSize; } } else - lastWorkerIndex += stepSize; + workerLastIndex += stepSize; - if(lastWorkerIndex >= lines.size()) + if(workerLastIndex >= lines.size()) { workerTimer->stop(); - lastWorkerIndex = 0; + workerLastIndex = 0; workerDy = 0.0; - bool stb = stickToBottom(); - updateSceneRect(); - if(stb) + if(workerStb) scrollToBottom(); } }); @@ -186,6 +184,8 @@ void ChatLog::partialUpdate() if(visibleLines.empty()) return; + bool stb = stickToBottom(); + auto oldUpdateMode = viewportUpdateMode(); setViewportUpdateMode(NoViewportUpdate); @@ -207,6 +207,9 @@ void ChatLog::partialUpdate() checkVisibility(); setViewportUpdateMode(oldUpdateMode); + + if(stb) + scrollToBottom(); } void ChatLog::fullUpdate() @@ -631,6 +634,14 @@ void ChatLog::scrollContentsBy(int dx, int dy) void ChatLog::resizeEvent(QResizeEvent* ev) { + if(!workerTimer->isActive()) + { + workerStb = stickToBottom(); + workerLastIndex = 0; + workerDy = 0.0; + workerTimer->start(); + } + bool stb = stickToBottom(); QGraphicsView::resizeEvent(ev); @@ -644,10 +655,6 @@ void ChatLog::resizeEvent(QResizeEvent* ev) scrollToBottom(); updateMultiSelectionRect(); - - lastWorkerIndex = 0; - workerDy = 0.0; - workerTimer->start(); } void ChatLog::updateMultiSelectionRect() diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index f92a7a76d..ac4eec148 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -112,8 +112,10 @@ private: QTimer* workerTimer = nullptr; AutoScrollDirection selectionScrollDir = NoDirection; - int lastWorkerIndex = 0; + //worker vars + int workerLastIndex = 0; qreal workerDy = 0; + bool workerStb = false; // actions QAction* copyAction = nullptr; From 437282b80c621eeb3a8b1f8a3dd7e48cee7030a8 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 14 Jan 2015 11:27:52 +0100 Subject: [PATCH 099/203] Don't stick to bottom if the user scrolls while the worker is still running --- src/chatlog/chatlog.cpp | 23 +++++++++++++---------- src/chatlog/chatlog.h | 1 + 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 092815b5e..29b5ed153 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -106,7 +106,7 @@ ChatLog::ChatLog(QWidget* parent) workerLastIndex = 0; workerDy = 0.0; - if(workerStb) + if(stickToBottom()) scrollToBottom(); } }); @@ -134,17 +134,12 @@ void ChatLog::clearSelection() QRect ChatLog::getVisibleRect() const { - return mapToScene(viewport()->rect()).boundingRect().toRect(); + return mapToScene(calculateSceneRect().toRect()).boundingRect().toRect(); } void ChatLog::updateSceneRect() { - qreal bottom = (lines.empty() ? 0.0 : lines.last()->boundingSceneRect().bottom()); - - if(typingNotification.get() != nullptr) - bottom += typingNotification->boundingSceneRect().height() + lineSpacing; - - setSceneRect(QRectF(-margins.left(), -margins.top(), useableWidth(), bottom + margins.bottom() + margins.top())); + setSceneRect(calculateSceneRect()); } qreal ChatLog::layout(int start, int end, qreal width) @@ -584,8 +579,6 @@ void ChatLog::checkVisibility() if(lines.empty()) return; - updateSceneRect(); - // find first visible line auto lowerBound = std::upper_bound(lines.cbegin(), lines.cend(), getVisibleRect().top(), [](const qreal lhs, const ChatLine::Ptr rhs) { @@ -688,6 +681,16 @@ void ChatLog::updateTypingNotification() notification->layout(useableWidth(), QPointF(0.0, posY)); } +QRectF ChatLog::calculateSceneRect() const +{ + qreal bottom = (lines.empty() ? 0.0 : lines.last()->boundingSceneRect().bottom()); + + if(typingNotification.get() != nullptr) + bottom += typingNotification->boundingSceneRect().height() + lineSpacing; + + return QRectF(-margins.left(), -margins.top(), useableWidth(), bottom + margins.bottom() + margins.top()); +} + void ChatLog::onSelectionTimerTimeout() { const int scrollSpeed = 10; diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index ac4eec148..b86700800 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -54,6 +54,7 @@ public: ChatLine::Ptr getTypingNotification() const; protected: + QRectF calculateSceneRect() const; QRect getVisibleRect() const; ChatLineContent* getContentFromPos(QPointF scenePos) const; From 3be99ae663d5c4dc87c9af4263695b38b586961f Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 14 Jan 2015 18:22:42 +0100 Subject: [PATCH 100/203] comments --- src/chatlog/chatlog.cpp | 25 ++++++++++++++++--------- src/chatlog/chatlog.h | 1 - 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 29b5ed153..21400be49 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -38,24 +38,26 @@ T clamp(T x, T min, T max) ChatLog::ChatLog(QWidget* parent) : QGraphicsView(parent) { + // Create the scene scene = new QGraphicsScene(this); - scene->setItemIndexMethod(QGraphicsScene::NoIndex); + scene->setItemIndexMethod(QGraphicsScene::NoIndex); //Bsp-Tree is actually slower in this case setScene(scene); + // Cfg. setInteractive(true); setAlignment(Qt::AlignTop | Qt::AlignLeft); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setDragMode(QGraphicsView::NoDrag); setViewportUpdateMode(BoundingRectViewportUpdate); - //setRenderHint(QPainter::TextAntialiasing); setAcceptDrops(false); setContextMenuPolicy(Qt::CustomContextMenu); + // The selection rect for multi-line selection const QColor selGraphColor = QColor(166,225,255); selGraphItem = scene->addRect(0,0,0,0,selGraphColor.darker(120),selGraphColor); selGraphItem->setZValue(-10.0); //behind all items - // copy action + // copy action (ie. Ctrl+C) copyAction = new QAction(this); copyAction->setShortcut(QKeySequence::Copy); addAction(copyAction); @@ -64,12 +66,16 @@ ChatLog::ChatLog(QWidget* parent) copySelectedText(); }); + // This timer is used to scroll the view while the user is + // moving the mouse past the top/bottom edge of the widget while selecting. selectionTimer = new QTimer(this); selectionTimer->setInterval(1000/60); selectionTimer->setSingleShot(false); selectionTimer->start(); connect(selectionTimer, &QTimer::timeout, this, &ChatLog::onSelectionTimerTimeout); + // Background worker + // Updates the layout of all chat-lines after a resize workerTimer = new QTimer(this); workerTimer->setSingleShot(false); workerTimer->setInterval(100); @@ -112,14 +118,9 @@ ChatLog::ChatLog(QWidget* parent) }); } -ChatLog::~ChatLog() -{ - -} - void ChatLog::clearSelection() { - for(int i=selFirstRow; i<=selLastRow && i= 0; ++i) + for(int i=selFirstRow; i<=selLastRow; ++i) lines[i]->selectionCleared(); selFirstRow = -1; @@ -149,6 +150,8 @@ qreal ChatLog::layout(int start, int end, qreal width) qreal h = 0.0; + // Line at start-1 is considered to have the correct position. All following lines are + // positioned in respect to this line. if(start - 1 >= 0) h = lines[start - 1]->boundingSceneRect().bottom() + lineSpacing; @@ -184,6 +187,9 @@ void ChatLog::partialUpdate() auto oldUpdateMode = viewportUpdateMode(); setViewportUpdateMode(NoViewportUpdate); + // Resize all lines currently visible in the viewport. + // If this creates some whitespace underneath the last visible lines + // then move the following non visible lines up in order to fill the gap. qreal repos; do { @@ -328,6 +334,7 @@ ChatLineContent* ChatLog::getContentFromPos(QPointF scenePos) const if(lines.empty()) return nullptr; + //Much faster than QGraphicsScene::itemAt()! //the first visible line auto lowerBound = std::upper_bound(lines.cbegin(), lines.cend(), scenePos.y(), [](const qreal lhs, const ChatLine::Ptr rhs) { diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index b86700800..e4c32a900 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -35,7 +35,6 @@ class ChatLog : public QGraphicsView Q_OBJECT public: explicit ChatLog(QWidget* parent = 0); - virtual ~ChatLog(); void insertChatlineAtBottom(ChatLine::Ptr l); void insertChatlineOnTop(ChatLine::Ptr l); From 13746f5c38a369686ccf6919351cfe83d6d860ba Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 14 Jan 2015 19:43:52 +0100 Subject: [PATCH 101/203] More pleasant multi-line selection, refactoring --- src/chatlog/chatlog.cpp | 92 +++++++++++++++++++++++++++++------------ src/chatlog/chatlog.h | 4 +- 2 files changed, 68 insertions(+), 28 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 21400be49..912b4b662 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -35,6 +35,16 @@ T clamp(T x, T min, T max) return x; } +auto compareSmaller = [](const ChatLine::Ptr lhs, const qreal rhs) -> bool +{ + return lhs->boundingSceneRect().top() < rhs; +}; + +auto compareGreater = [](const qreal lhs, const ChatLine::Ptr rhs) -> bool +{ + return lhs < rhs->boundingSceneRect().bottom(); +}; + ChatLog::ChatLog(QWidget* parent) : QGraphicsView(parent) { @@ -120,6 +130,9 @@ ChatLog::ChatLog(QWidget* parent) void ChatLog::clearSelection() { + if(selectionMode == None) + return; + for(int i=selFirstRow; i<=selLastRow; ++i) lines[i]->selectionCleared(); @@ -275,6 +288,7 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) if(selectionMode == None && (clickPos - ev->pos()).manhattanLength() > QApplication::startDragDistance()) { QPointF sceneClickPos = mapToScene(clickPos.toPoint()); + ChatLine::Ptr line = findLineByYPos(scenePos.y()); ChatLineContent* content = getContentFromPos(sceneClickPos); if(content) @@ -292,23 +306,31 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) if(scene->mouseGrabberItem()) scene->mouseGrabberItem()->ungrabMouse(); } + else if(line.get()) + { + selClickedRow = line->getRowIndex(); + selFirstRow = selClickedRow; + selLastRow = selClickedRow; + + selectionMode = Multi; + } } if(selectionMode != None) { ChatLineContent* content = getContentFromPos(scenePos); + ChatLine::Ptr line = findLineByYPos(scenePos.y()); + + if(!content && !line.get()) + return; + + int row; if(content) { - int row = content->getRow(); + row = content->getRow(); int col = content->getColumn(); - if(row >= selClickedRow) - selLastRow = row; - - if(row <= selClickedRow) - selFirstRow = row; - if(row == selClickedRow && col == selClickedCol) { selectionMode = Precise; @@ -316,36 +338,48 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) content->selectionMouseMove(scenePos); selGraphItem->hide(); } - else + else if(col != selClickedCol) { selectionMode = Multi; lines[selClickedRow]->selectionCleared(); - - updateMultiSelectionRect(); } } + else if(line.get()) + { + row = line->getRowIndex(); + + if(row != selClickedRow) + { + selectionMode = Multi; + + lines[selClickedRow]->selectionCleared(); + } + + } + + if(row >= selClickedRow) + selLastRow = row; + + if(row <= selClickedRow) + selFirstRow = row; + + updateMultiSelectionRect(); } } } +//Much faster than QGraphicsScene::itemAt()! ChatLineContent* ChatLog::getContentFromPos(QPointF scenePos) const { if(lines.empty()) return nullptr; - //Much faster than QGraphicsScene::itemAt()! //the first visible line - auto lowerBound = std::upper_bound(lines.cbegin(), lines.cend(), scenePos.y(), [](const qreal lhs, const ChatLine::Ptr rhs) - { - return lhs < rhs->boundingSceneRect().bottom(); - }); + auto lowerBound = std::upper_bound(lines.cbegin(), lines.cend(), scenePos.y(), compareGreater); //the last visible line - auto upperBound = std::lower_bound(lines.cbegin(), lines.cend(), scenePos.y(), [](const ChatLine::Ptr lhs, const qreal rhs) - { - return lhs->boundingSceneRect().top() < rhs; - }); + auto upperBound = std::lower_bound(lines.cbegin(), lines.cend(), scenePos.y(), compareSmaller); //find content for(auto itr = lowerBound; itr != upperBound; ++itr) @@ -587,16 +621,10 @@ void ChatLog::checkVisibility() return; // find first visible line - auto lowerBound = std::upper_bound(lines.cbegin(), lines.cend(), getVisibleRect().top(), [](const qreal lhs, const ChatLine::Ptr rhs) - { - return lhs < rhs->boundingSceneRect().bottom(); - }); + auto lowerBound = std::upper_bound(lines.cbegin(), lines.cend(), getVisibleRect().top(), compareGreater); // find last visible line - auto upperBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().bottom(), [](const ChatLine::Ptr lhs, const qreal rhs) - { - return lhs->boundingSceneRect().top() < rhs; - }); + auto upperBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().bottom(), compareSmaller); // set visibilty QList newVisibleLines; @@ -688,6 +716,16 @@ void ChatLog::updateTypingNotification() notification->layout(useableWidth(), QPointF(0.0, posY)); } +ChatLine::Ptr ChatLog::findLineByYPos(qreal yPos) const +{ + auto lowerBound = std::upper_bound(lines.cbegin(), lines.cend(), yPos, compareGreater); + + if(lowerBound != lines.cend()) + return *lowerBound; + + return ChatLine::Ptr(); +} + QRectF ChatLog::calculateSceneRect() const { qreal bottom = (lines.empty() ? 0.0 : lines.last()->boundingSceneRect().bottom()); diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index e4c32a900..1c7cba68e 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -79,6 +79,8 @@ protected: void updateMultiSelectionRect(); void updateTypingNotification(); + ChatLine::Ptr findLineByYPos(qreal yPos) const; + private slots: void onSelectionTimerTimeout(); @@ -101,7 +103,7 @@ private: ChatLine::Ptr typingNotification; // selection - int selClickedRow = -1; + int selClickedRow = -1; //These 4 are only valid while selectionMode != None int selClickedCol = -1; int selFirstRow = -1; int selLastRow = -1; From 3478a5c7944a0623ed5bbecedd238c7561ef2b0a Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 14 Jan 2015 20:13:41 +0100 Subject: [PATCH 102/203] refactoring --- src/chatlog/chatlog.cpp | 19 ++++--------------- src/chatlog/chatlog.h | 3 +-- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 912b4b662..f1d690b8b 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -188,7 +188,7 @@ qreal ChatLog::layout(int start, int end, qreal width) return deltaY; } -void ChatLog::partialUpdate() +void ChatLog::updateVisibleLines() { checkVisibility(); @@ -226,12 +226,6 @@ void ChatLog::partialUpdate() scrollToBottom(); } -void ChatLog::fullUpdate() -{ - layout(0, lines.size(), useableWidth()); - checkVisibility(); -} - void ChatLog::mousePressEvent(QMouseEvent* ev) { QGraphicsView::mousePressEvent(ev); @@ -657,7 +651,7 @@ void ChatLog::checkVisibility() void ChatLog::scrollContentsBy(int dx, int dy) { QGraphicsView::scrollContentsBy(dx, dy); - partialUpdate(); + updateVisibleLines(); } void ChatLog::resizeEvent(QResizeEvent* ev) @@ -673,16 +667,11 @@ void ChatLog::resizeEvent(QResizeEvent* ev) bool stb = stickToBottom(); QGraphicsView::resizeEvent(ev); - - if(lines.count() > 300) - partialUpdate(); - else - fullUpdate(); + updateVisibleLines(); + updateMultiSelectionRect(); if(stb) scrollToBottom(); - - updateMultiSelectionRect(); } void ChatLog::updateMultiSelectionRect() diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 1c7cba68e..0d6ee5327 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -65,8 +65,7 @@ protected: void reposition(int start, int end, qreal deltaY); void updateSceneRect(); - void partialUpdate(); - void fullUpdate(); + void updateVisibleLines(); void checkVisibility(); void scrollToBottom(); From a0693c2fc9135d7f76aa461f4847844cc0577a63 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 14 Jan 2015 20:31:40 +0100 Subject: [PATCH 103/203] tweaked ChatLog::getSelectedText *Actions are copied as "*name action*" *SystemInfoMessages are not copied --- src/chatlog/chatlog.cpp | 9 +++++++-- src/chatlog/chatmessage.cpp | 6 +++--- src/chatlog/content/text.cpp | 3 --- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index f1d690b8b..e3968e9a4 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -524,8 +524,11 @@ QString ChatLog::getSelectedText() const QString out; QString lastSender; - for(int i=selFirstRow; i<=selLastRow && i>=0 && icontent[1]->getText().isEmpty()) + continue; + if(lastSender != lines[i]->content[0]->getText() && !lines[i]->content[0]->getText().isEmpty()) { //author changed @@ -534,7 +537,9 @@ QString ChatLog::getSelectedText() const } out += lines[i]->content[1]->getText(); - out += "\n\n"; + + if(i != selLastRow) + out += "\n"; } return out; diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 4e55cea2d..3a475ff59 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -56,8 +56,8 @@ ChatMessage::Ptr ChatMessage::createChatMessage(const QString &sender, const QSt text = "
" + text + "
"; } - msg->addColumn(new Text(isAction ? "
*
" : sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), isAction ? false : true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - msg->addColumn(new Text(text, Style::getFont(Style::Big), false, rawMessage), ColumnFormat(1.0, ColumnFormat::VariableSize)); + msg->addColumn(new Text(isAction ? "
*
" : sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), isAction ? false : true, sender), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + msg->addColumn(new Text(text, Style::getFont(Style::Big), false, isAction ? QString("*%1 %2*").arg(sender, rawMessage) : rawMessage), ColumnFormat(1.0, ColumnFormat::VariableSize)); msg->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); if(!date.isNull()) @@ -79,7 +79,7 @@ ChatMessage::Ptr ChatMessage::createChatInfoMessage(const QString &rawMessage, S } msg->addColumn(new Image(QSizeF(16, 16), img), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - msg->addColumn(new Text(rawMessage, Style::getFont(Style::Big), false, rawMessage), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Center)); + msg->addColumn(new Text(rawMessage, Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Center)); msg->addColumn(new Text(date.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); return msg; diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 0a591b27a..85fbec7fd 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -52,9 +52,6 @@ void Text::setText(const QString& txt) text = txt; dirty = true; - if(rawText.isEmpty()) - rawText = txt; - ensureIntegrity(); freeResources(); } From 1ae3999576f17bfa0800e7bd29cb32ad3fd95d20 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Thu, 15 Jan 2015 10:14:26 +0100 Subject: [PATCH 104/203] FileTransferWidget::acceptTransfer: Regression - check whether the path is NOT writable --- src/chatlog/content/filetransferwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index 6d087a018..32a6e706a 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -94,7 +94,7 @@ void FileTransferWidget::autoAcceptTransfer(const QString &path) void FileTransferWidget::acceptTransfer(const QString &filepath) { //test if writable - if(isFilePathWritable(filepath)) + if(!isFilePathWritable(filepath)) { QMessageBox::warning(0, tr("Location not writable","Title of permissions popup"), From b4fa8323af5e8834812e1a565067f1e87a4a7e90 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Thu, 15 Jan 2015 11:48:41 +0100 Subject: [PATCH 105/203] refactoring, reverted ChatLog::getVisibleRect --- src/chatlog/chatline.cpp | 15 ++++++++++++ src/chatlog/chatline.h | 5 ++++ src/chatlog/chatlog.cpp | 50 ++++++++++++---------------------------- src/chatlog/chatlog.h | 2 +- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index 801825c9e..b0a56adea 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -260,3 +260,18 @@ void ChatLine::moveBy(qreal deltaY) bbox.moveTop(bbox.top() + deltaY); } + +bool ChatLine::lessThanBSRectTop(const ChatLine::Ptr lhs, const qreal rhs) +{ + return lhs->boundingSceneRect().top() < rhs; +} + +bool ChatLine::lessThanBSRectBottom(const ChatLine::Ptr lhs, const qreal rhs) +{ + return lhs->boundingSceneRect().bottom() < rhs; +} + +bool ChatLine::lessThanRowIndex(const ChatLine::Ptr lhs, const ChatLine::Ptr rhs) +{ + return lhs->getRowIndex() < rhs->getRowIndex(); +} diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index 458e9c436..7514654cb 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -94,6 +94,11 @@ protected: void setRowIndex(int idx); void visibilityChanged(bool visible); + //comparators + static bool lessThanBSRectTop(const ChatLine::Ptr lhs, const qreal rhs); + static bool lessThanBSRectBottom(const ChatLine::Ptr lhs, const qreal rhs); + static bool lessThanRowIndex(const ChatLine::Ptr lhs, const ChatLine::Ptr rhs); + private: int rowIndex = -1; std::vector content; // 3 columns diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index e3968e9a4..b2d8239ad 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -35,16 +35,6 @@ T clamp(T x, T min, T max) return x; } -auto compareSmaller = [](const ChatLine::Ptr lhs, const qreal rhs) -> bool -{ - return lhs->boundingSceneRect().top() < rhs; -}; - -auto compareGreater = [](const qreal lhs, const ChatLine::Ptr rhs) -> bool -{ - return lhs < rhs->boundingSceneRect().bottom(); -}; - ChatLog::ChatLog(QWidget* parent) : QGraphicsView(parent) { @@ -71,7 +61,7 @@ ChatLog::ChatLog(QWidget* parent) copyAction = new QAction(this); copyAction->setShortcut(QKeySequence::Copy); addAction(copyAction); - connect(copyAction, &QAction::triggered, this, [ = ](bool) + connect(copyAction, &QAction::triggered, this, [this](bool) { copySelectedText(); }); @@ -148,7 +138,7 @@ void ChatLog::clearSelection() QRect ChatLog::getVisibleRect() const { - return mapToScene(calculateSceneRect().toRect()).boundingRect().toRect(); + return mapToScene(viewport()->rect()).boundingRect().toRect(); } void ChatLog::updateSceneRect() @@ -282,7 +272,7 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) if(selectionMode == None && (clickPos - ev->pos()).manhattanLength() > QApplication::startDragDistance()) { QPointF sceneClickPos = mapToScene(clickPos.toPoint()); - ChatLine::Ptr line = findLineByYPos(scenePos.y()); + ChatLine::Ptr line = findLineByPosY(scenePos.y()); ChatLineContent* content = getContentFromPos(sceneClickPos); if(content) @@ -313,7 +303,7 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) if(selectionMode != None) { ChatLineContent* content = getContentFromPos(scenePos); - ChatLine::Ptr line = findLineByYPos(scenePos.y()); + ChatLine::Ptr line = findLineByPosY(scenePos.y()); if(!content && !line.get()) return; @@ -369,18 +359,11 @@ ChatLineContent* ChatLog::getContentFromPos(QPointF scenePos) const if(lines.empty()) return nullptr; - //the first visible line - auto lowerBound = std::upper_bound(lines.cbegin(), lines.cend(), scenePos.y(), compareGreater); - - //the last visible line - auto upperBound = std::lower_bound(lines.cbegin(), lines.cend(), scenePos.y(), compareSmaller); + auto itr = std::lower_bound(lines.cbegin(), lines.cend(), scenePos.y(), ChatLine::lessThanBSRectBottom); //find content - for(auto itr = lowerBound; itr != upperBound; ++itr) - { - if((*itr)->boundingSceneRect().contains(scenePos)) - return (*itr)->getContent(scenePos); - } + if(itr != lines.cend() && (*itr)->boundingSceneRect().contains(scenePos)) + return (*itr)->getContent(scenePos); return nullptr; } @@ -620,10 +603,10 @@ void ChatLog::checkVisibility() return; // find first visible line - auto lowerBound = std::upper_bound(lines.cbegin(), lines.cend(), getVisibleRect().top(), compareGreater); + auto lowerBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().top(), ChatLine::lessThanBSRectBottom); // find last visible line - auto upperBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().bottom(), compareSmaller); + auto upperBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().bottom(), ChatLine::lessThanBSRectTop); // set visibilty QList newVisibleLines; @@ -644,13 +627,10 @@ void ChatLog::checkVisibility() visibleLines = newVisibleLines; // enforce order - std::sort(visibleLines.begin(), visibleLines.end(), [](const ChatLine::Ptr lhs, const ChatLine::Ptr rhs) - { - return lhs->getRowIndex() < rhs->getRowIndex(); - }); + std::sort(visibleLines.begin(), visibleLines.end(), ChatLine::lessThanRowIndex); //if(!visibleLines.empty()) - // qDebug() << "visible from " << visibleLines.first()->getRowIndex() << "to " << visibleLines.last()->getRowIndex() << " total " << visibleLines.size(); + // qDebug() << "visible from " << visibleLines.first()->getRowIndex() << "to " << visibleLines.last()->getRowIndex() << " total " << visibleLines.size(); } void ChatLog::scrollContentsBy(int dx, int dy) @@ -710,12 +690,12 @@ void ChatLog::updateTypingNotification() notification->layout(useableWidth(), QPointF(0.0, posY)); } -ChatLine::Ptr ChatLog::findLineByYPos(qreal yPos) const +ChatLine::Ptr ChatLog::findLineByPosY(qreal yPos) const { - auto lowerBound = std::upper_bound(lines.cbegin(), lines.cend(), yPos, compareGreater); + auto itr = std::lower_bound(lines.cbegin(), lines.cend(), yPos, ChatLine::lessThanBSRectBottom); - if(lowerBound != lines.cend()) - return *lowerBound; + if(itr != lines.cend()) + return *itr; return ChatLine::Ptr(); } diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 0d6ee5327..af031842f 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -78,7 +78,7 @@ protected: void updateMultiSelectionRect(); void updateTypingNotification(); - ChatLine::Ptr findLineByYPos(qreal yPos) const; + ChatLine::Ptr findLineByPosY(qreal yPos) const; private slots: void onSelectionTimerTimeout(); From e85ff582230516ff72b2c4c1bd7da0a9267a72be Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 17 Jan 2015 11:31:57 +0100 Subject: [PATCH 106/203] refactoring --- src/chatlog/chatlog.cpp | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index b2d8239ad..4f07c9ad7 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -433,25 +433,7 @@ void ChatLog::insertChatlineOnTop(ChatLine::Ptr l) if(!l.get()) return; - bool stickToBtm = stickToBottom(); - - //move all lines down by 1 - for(ChatLine::Ptr l : lines) - l->setRowIndex(l->getRowIndex() + 1); - - //add the new line - l->addToScene(scene); - l->setRowIndex(0); - lines.prepend(l); - - //full refresh is required - layout(0, lines.size(), useableWidth()); - updateSceneRect(); - - if(stickToBtm) - scrollToBottom(); - - checkVisibility(); + insertChatlineOnTop(QList() << l); } void ChatLog::insertChatlineOnTop(const QList& newLines) From ee902ee1b005d6f15e20c8db3e5d19cc76d38e8b Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 17 Jan 2015 11:35:09 +0100 Subject: [PATCH 107/203] don't forget to reposition the typingNotification on insertChatline* --- src/chatlog/chatlog.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 4f07c9ad7..148e241a6 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -426,6 +426,7 @@ void ChatLog::insertChatlineAtBottom(ChatLine::Ptr l) scrollToBottom(); checkVisibility(); + updateTypingNotification(); } void ChatLog::insertChatlineOnTop(ChatLine::Ptr l) @@ -464,6 +465,7 @@ void ChatLog::insertChatlineOnTop(const QList& newLines) scrollToBottom(); checkVisibility(); + updateTypingNotification(); } bool ChatLog::stickToBottom() const From 4d5470710a58d76fe9f24908d5758e620fbce2f6 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 17 Jan 2015 12:09:13 +0100 Subject: [PATCH 108/203] createChatInfoMessage: increase icon size from 16 to 20 px --- src/chatlog/chatmessage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 3a475ff59..aece1a4d8 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -78,7 +78,7 @@ ChatMessage::Ptr ChatMessage::createChatInfoMessage(const QString &rawMessage, S case TYPING: img = ":/ui/chatArea/typing.png"; break; } - msg->addColumn(new Image(QSizeF(16, 16), img), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + msg->addColumn(new Image(QSizeF(20, 20), img), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text(rawMessage, Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Center)); msg->addColumn(new Text(date.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); From b4f53944cc2b83ee98af4eae9f4fc023e856f750 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 17 Jan 2015 18:17:40 +0100 Subject: [PATCH 109/203] FileTransferWidget: calculate mean --- src/chatlog/content/filetransferwidget.cpp | 72 +++++++++++++--------- src/chatlog/content/filetransferwidget.h | 4 ++ 2 files changed, 46 insertions(+), 30 deletions(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index 32a6e706a..67444cedd 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -43,7 +43,7 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) ui->progressBar->setValue(0); ui->fileSizeLabel->setText(getHumanReadableSize(file.filesize)); ui->progressLabel->setText("0kiB/s"); - ui->etaLabel->setText("-:-"); + ui->etaLabel->setText(""); setStyleSheet(Style::getStylesheet(":/ui/fileTransferInstance/grey.css")); Style::repolish(this); @@ -116,7 +116,10 @@ bool FileTransferWidget::isFilePathWritable(const QString &filepath) void FileTransferWidget::onFileTransferInfo(ToxFile file) { - if(fileInfo != file) + QTime now = QTime::currentTime(); + qint64 dt = lastTick.msecsTo(now); //ms + + if(fileInfo != file || dt < 1000) return; fileInfo = file; @@ -127,37 +130,41 @@ void FileTransferWidget::onFileTransferInfo(ToxFile file) qreal progress = static_cast(file.bytesSent) / static_cast(file.filesize); ui->progressBar->setValue(static_cast(progress * 100.0)); - // eta, speed - QTime now = QTime::currentTime(); - qreal deltaSecs = lastTick.msecsTo(now) / 1000.0; + // ETA, speed + qreal deltaSecs = dt / 1000.0; - if(deltaSecs >= 1.0) + qint64 deltaBytes = qMax(file.bytesSent - lastBytesSent, qint64(0)); + qreal bytesPerSec = static_cast(static_cast(deltaBytes) / deltaSecs); + + // calculate mean + meanData[(meanIndex++) % FTW_MEAN_PERIODES] = bytesPerSec; + + qreal meanBytesPerSec = 0.0; + for(size_t i = 0; i < FTW_MEAN_PERIODES; ++i) + meanBytesPerSec += meanData[i]; + + meanBytesPerSec /= qMin(meanIndex, static_cast(FTW_MEAN_PERIODES)); + + // update UI + if(meanBytesPerSec > 0) { - qint64 deltaBytes = file.bytesSent - lastBytesSent; - qint64 bytesPerSec = static_cast(static_cast(deltaBytes) / deltaSecs); - - if(bytesPerSec > 0) - { - QTime toGo = QTime(0,0).addSecs(file.filesize / bytesPerSec); - ui->etaLabel->setText(toGo.toString("mm:ss")); - } - else - { - ui->etaLabel->setText("--:--"); - } - - ui->progressLabel->setText(getHumanReadableSize(bytesPerSec) + "/s"); - - lastTick = now; - lastBytesSent = file.bytesSent; + // ETA + QTime toGo = QTime(0,0).addSecs((file.filesize - file.bytesSent) / meanBytesPerSec); + ui->etaLabel->setText(toGo.toString("hh:mm:ss")); } - } - else if(fileInfo.status == ToxFile::PAUSED) - { - ui->etaLabel->setText("--:--"); - ui->progressLabel->setText(getHumanReadableSize(0) + "/s"); + else + { + ui->etaLabel->setText(""); + } + + ui->progressLabel->setText(getHumanReadableSize(meanBytesPerSec) + "/s"); + + lastBytesSent = file.bytesSent; } + lastTick = now; + + // trigger repaint update(); } @@ -197,9 +204,14 @@ void FileTransferWidget::onFileTransferPaused(ToxFile file) fileInfo = file; - ui->etaLabel->setText("--:--"); + ui->etaLabel->setText(""); ui->progressLabel->setText(getHumanReadableSize(0) + "/s"); + // reset mean + meanIndex = 0; + for(size_t i=0; i 0) 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]); + return QString().setNum(size / pow(1024, exp),'f', exp > 2 ? 2 : 0).append(suffix[exp]); } void FileTransferWidget::hideWidgets() diff --git a/src/chatlog/content/filetransferwidget.h b/src/chatlog/content/filetransferwidget.h index 34c0d7581..5d3b1336e 100644 --- a/src/chatlog/content/filetransferwidget.h +++ b/src/chatlog/content/filetransferwidget.h @@ -22,6 +22,8 @@ #include "../chatlinecontent.h" #include "../../corestructs.h" +#define FTW_MEAN_PERIODES 4 + namespace Ui { class FileTransferWidget; } @@ -64,6 +66,8 @@ private: QTime lastTick; qint64 lastBytesSent = 0; + qreal meanData[FTW_MEAN_PERIODES] = {0.0}; + size_t meanIndex = 0; }; #endif // FILETRANSFERWIDGET_H From 882d19d311ee6bf85d252181506fbb5880571138 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 18 Jan 2015 11:54:08 +0100 Subject: [PATCH 110/203] "%user is typing..." -> "%user ..." --- src/widget/form/chatform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 44ffc4b81..8e5138a4a 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -887,7 +887,7 @@ void ChatForm::setFriendTyping(bool isTyping) Text* text = dynamic_cast(chatWidget->getTypingNotification()->getContent(1)); if(text) - text->setText("
" + tr("%1 is typing...").arg(f->getDisplayedName()) + "
"); + text->setText("
" + QString("%1 ...").arg(f->getDisplayedName()) + "
"); } void ChatForm::clearReciepts() From 9df5200fc90c559e196335569f5a5192536edcb9 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 18 Jan 2015 12:15:02 +0100 Subject: [PATCH 111/203] update typing notification on resize --- src/chatlog/chatlog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 148e241a6..377a37c22 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -638,6 +638,7 @@ void ChatLog::resizeEvent(QResizeEvent* ev) QGraphicsView::resizeEvent(ev); updateVisibleLines(); updateMultiSelectionRect(); + updateTypingNotification(); if(stb) scrollToBottom(); From 16812633cb6353ed70c8ce5da7dadd4977e409b9 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 18 Jan 2015 12:17:21 +0100 Subject: [PATCH 112/203] extended spinner class --- src/chatlog/content/spinner.cpp | 7 ++++--- src/chatlog/content/spinner.h | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/chatlog/content/spinner.cpp b/src/chatlog/content/spinner.cpp index a07d933e2..7d912fdfb 100644 --- a/src/chatlog/content/spinner.cpp +++ b/src/chatlog/content/spinner.cpp @@ -19,10 +19,11 @@ #include #include -Spinner::Spinner(QSizeF Size) +Spinner::Spinner(const QString &img, QSizeF Size, qreal speed) : size(Size) + , rotSpeed(speed) { - pmap.load(":/ui/chatArea/spinner.png"); + pmap.load(img); timer.setInterval(33); // 30Hz timer.setSingleShot(false); @@ -77,6 +78,6 @@ qreal Spinner::getAscent() const void Spinner::timeout() { - rot += 8; + rot += rotSpeed; update(); } diff --git a/src/chatlog/content/spinner.h b/src/chatlog/content/spinner.h index d73079f71..894a10761 100644 --- a/src/chatlog/content/spinner.h +++ b/src/chatlog/content/spinner.h @@ -26,7 +26,7 @@ class Spinner : public QObject, public ChatLineContent { Q_OBJECT public: - Spinner(QSizeF size); + Spinner(const QString& img, QSizeF size, qreal speed); virtual QRectF boundingRect() const override; virtual QRectF boundingSceneRect() const override; @@ -41,7 +41,8 @@ private slots: private: QSizeF size; QPixmap pmap; - qreal rot; + qreal rot = 0.0; + qreal rotSpeed; QTimer timer; }; From 2914a9883c7167d31409e7e75ecb8403a54740ae Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 18 Jan 2015 12:20:13 +0100 Subject: [PATCH 113/203] ChatMessage::createTypingNotification, resized images to 18x18, new (spinning) notification icon --- src/chatlog/chatmessage.cpp | 14 ++++++-- src/chatlog/chatmessage.h | 1 + src/widget/form/chatform.cpp | 2 +- ui/chatArea/error.png | Bin 765 -> 510 bytes ui/chatArea/info.png | Bin 791 -> 511 bytes ui/chatArea/innerStyle.css | 4 +-- ui/chatArea/symbols.svg | 65 +++++++++++++++++++++++------------ ui/chatArea/typing.png | Bin 580 -> 613 bytes 8 files changed, 59 insertions(+), 27 deletions(-) diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index aece1a4d8..8d600cd5e 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -58,7 +58,7 @@ ChatMessage::Ptr ChatMessage::createChatMessage(const QString &sender, const QSt msg->addColumn(new Text(isAction ? "
*
" : sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), isAction ? false : true, sender), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text(text, Style::getFont(Style::Big), false, isAction ? QString("*%1 %2*").arg(sender, rawMessage) : rawMessage), ColumnFormat(1.0, ColumnFormat::VariableSize)); - msg->addColumn(new Spinner(QSizeF(16, 16)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + msg->addColumn(new Spinner(":/ui/chatArea/spinner.png", QSizeF(16, 16), 8.0), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); if(!date.isNull()) msg->markAsSent(date); @@ -78,7 +78,7 @@ ChatMessage::Ptr ChatMessage::createChatInfoMessage(const QString &rawMessage, S case TYPING: img = ":/ui/chatArea/typing.png"; break; } - msg->addColumn(new Image(QSizeF(20, 20), img), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + msg->addColumn(new Image(QSizeF(18, 18), img), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text(rawMessage, Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Center)); msg->addColumn(new Text(date.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); @@ -96,6 +96,16 @@ ChatMessage::Ptr ChatMessage::createFileTransferMessage(const QString& sender, T return msg; } +ChatMessage::Ptr ChatMessage::createTypingNotification() +{ + ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); + + msg->addColumn(new Spinner(":/ui/chatArea/typing.png", QSizeF(18, 18), 6.0), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + msg->addColumn(new Text("%1 ...", Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Left)); + + return msg; +} + void ChatMessage::markAsSent(const QDateTime &time) { // remove the spinner and replace it by $time diff --git a/src/chatlog/chatmessage.h b/src/chatlog/chatmessage.h index c03ed8991..2fba9e68b 100644 --- a/src/chatlog/chatmessage.h +++ b/src/chatlog/chatmessage.h @@ -40,6 +40,7 @@ public: static ChatMessage::Ptr createChatMessage(const QString& sender, const QString& rawMessage, bool isAction, bool alert, bool isMe, const QDateTime& date = QDateTime()); static ChatMessage::Ptr createChatInfoMessage(const QString& rawMessage, SystemMessageType type, const QDateTime& date); static ChatMessage::Ptr createFileTransferMessage(const QString& sender, ToxFile file, bool isMe, const QDateTime& date); + static ChatMessage::Ptr createTypingNotification(); void markAsSent(const QDateTime& time); QString toString() const; diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 8e5138a4a..805bf5c8a 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -59,7 +59,7 @@ ChatForm::ChatForm(Friend* chatFriend) netcam = new NetCamView(); timer = nullptr; - chatWidget->setTypingNotification(ChatMessage::createChatInfoMessage("", ChatMessage::TYPING, QDateTime())); + chatWidget->setTypingNotification(ChatMessage::createTypingNotification()); headTextLayout->addWidget(statusMessageLabel); headTextLayout->addStretch(); diff --git a/ui/chatArea/error.png b/ui/chatArea/error.png index 06686cd6cfc5de2f50d81aea41d1b75bd8c5aa4e..52f96da3f7358bcc0b2df77f109d3dc9c8d38d18 100644 GIT binary patch delta 461 zcmV;;0W$vm1^xpeiBL{Q4GJ0x0000DNk~Le0000I0000I2nGNE09MY9SCJta3jp5$ z007?s53OO2kwzzf0eeYAK~y-6t(3h=13?spzk9R02>yYErNk712pS?u=OaY0(AL(@ z(n3MR03WlHg(y1wk|=5C&Xr{E@sVy6agon6p_;b) zs#+?BVbcRh&cxZy*~$tAcp@&_Pu8xai)FaTgOlfnO`%@%YcW3>B6tnu+6tlVtG{)r! zG&Gr=))<^tsa9(%fU52S{XanZ$=Z(*DTZMak&3G_P-S^)ido$e@TMKaVH3>Bj&$K`OOB;V@#G=bSdav)y?8J-yZd_Cgs8FEjhghq9(HHG`MqUk zzWIidkVqttve_y6z6;5XzBOcRW2I0yL&5Np2m`F!wT1BaQ6N9iNTg}zR^B~?Z4td>gUfeajb-ek*|T}o?-z_)#nm9a3~eqApA zif!Qg=H`--$^d2_0`F2SB)vDq;z?fv5&Ro~iARFBbs3UxZ=1Mb;Mnsfeewrl{Q1}O zb9}DX@h1#_VMxrT)A%qy-!H6YrRDDFFx{;!V|L@f0pNG5g-hSZbr|9*2vEPijuSQ$ zF*@oPh*o>-1^2>QJTnFaU`b4lkH?Cmw04-ucwO(pUM`n<)oh+5-fDwNs{VAGrLBBE zFaR*!Y_1Ot4glmrl-N2`kVz8X3d5dH!la%701J|T^1O|>QMIcpysK7ww!NR5!{S7| z-79hfB+XGaJB9mm`yB;I53l>>9%ZvrmcH*M8FDtA#;3(a0Kk`e9hHlVfgRBIT?@$t z89T_3co}WEbSgD48~`A>rhl)el>ylp8J%nxSvxWVvbJGX3WYNOqcG7}DHP5OBt>P^ zP(^8fAClUOurzD~ZKeT$Q^z@g)H}UBg{11K;~aDhY~}NT$ep3_$(?q^+{pv0rBYdB zWeD&}ccpwI5sii6Hh|g_@@o;JqX!kGp@hpIfFz6=gXjNF&HangTPB85miIgh-V}=` zR$6|HH6gNMrR835;D5fFb!()T)4LImdp-XZ3;VQUz>4JErT_o{07*qoM6N<$f*UeU ATL1t6 diff --git a/ui/chatArea/info.png b/ui/chatArea/info.png index 47e7b0f3dbf28964c25b5f5d9fd9ace63babb1d3..67a1e255d257789b3d4ede7963a6eed54c61a32b 100644 GIT binary patch delta 462 zcmV;<0WtoU2LA&giBL{Q4GJ0x0000DNk~Le0000I0000I2nGNE09MY9SCJta3jp5$ z007?s53OO2kwzzf0eneBK~y-6t(4CzL{SvSKli@(5QS2jh19UI5SkH%l!XmzvtzQx z%97O7%wA2iC6@dL7K&s+GwJ;Sek9Q=3#l3VL4N#ka z^Mgo;DoECQD(4Os4txL|GJ!}YD&o1%JYIT4oI9X0^_ee@f^{xTPL9^jczdoezcYi~ zVtsQa7Gs5p-76a)xD(?#v)hx12-?;r+6iWd)#}M&T$FWf>UyvE_!YlC(PpC^qZms3 zJ{zSIMi#h#JAUB)?2(t-SCT7(^i0OgjY=nU_)bjdpX+6OefTH(69P%I*FQijC^jmh zps0~rsbM=(E9oFRZUZuIetQ2#1BgW$sQy8u8qC%sQV*bHO`Y1&bPaUU+|guUB^!p< z4olusIoBO)B^ui1_9mvbM!z`;LmL+U{~L+ow;$UT2NqbJKf)<~CjbBd07*qoM6N<$ Ef@S2%EdT%j delta 744 zcmV{I&hbH6QWLqhZ0eQ@L+*A zPg>wbFgzR4@YLB9x(H$?AxJO}LdYacsH+{?p>hy2CIq2WZtuNchiy97a&Mc?zOci1 z`~N?mxA*`5-tRA}N+l6QCe}tnULYNIM8W{JYSLta$?3j-xs+1bgyKhFYJJMywG;iK zdKVZ_Xe%wp4zQvk%dJjiHQEz(Y8DvZ7#T#(6QHB4>G8x7Z*sP4VW}#CvCZL-<=Km< z_ErckB1p_N&d{@)&r`ky9=y4KO@&uLq$c=L5~AFh>7L&zE0BY~1)5F?p3j~rw~8f> z35;zHhb-5BdXJAg|ML1PA76aJ&3K4`=13D=k8hM4mT)b%v+!}4!mE~NFZzK4{QiDG zdOw4E;Ntvp+5h&_&#*|2ahOAa>}vPF;DXHo>?6p3RXE@AGG57#dj6|$o@omr!*iekQS=tXjegq{Fr&684V=F+xMjMF8x^K-F-7O4(-;W2;vGAJ!OKHEB#H zcy0oJCKF7W>AtyCu9K;21a_wT=29lt!>!a?09a8}4S + @@ -46,7 +53,7 @@ id="flowPara2994">! + id="info"> i + id="error"> i + + + + + id="notification"> - - + d="m 494.05192,469.82629 a 2.5618966,2.5618966 0 1 1 -5.1238,0 2.5618966,2.5618966 0 1 1 5.1238,0 z" + transform="matrix(8.782556,0,0,8.782556,-3756.8812,-3871.6691)" + id="path3806-4" + style="fill:#6bc260;fill-opacity:1;stroke:none" /> + + diff --git a/ui/chatArea/typing.png b/ui/chatArea/typing.png index 8e0f08478c6abfdca4a5c77affa3cb9879ef3230..d103baa5bb4f1819b3fa5aebae9b380b2980bebc 100644 GIT binary patch delta 562 zcmV-20?qxz1my%FiBL{Q4GJ0x0000DNk~Le0000I0000I2nGNE09MY9SCJtb3Vr|p z0)7Gh>gy_zMks&cNklA$ty9=ezQgCn-ad9)n)Ph9uYv__OLuPR* zLJ$Y3e}fc3YCt+!p;M)WETw|@MTkf#6%{&!E+TC%Fm>5(}}49_W*;)u6lWLd+x*D`Ac_7rJQ)btZ)Z# zK*K;~rdDgp?#KBX#_$7}7H?UYJ6y#EShhPaM#E*lxkQa}Qbkw}-%hUxus zKmst~j9HRz_4z+2S5rpVo9t#L4_?ESOy*yT2%vf$p>muO0=U+A*Nu0(j{Z#2>Npa7 z{Q{s7$H_^YBqzWHznyyIj9o-%2f~g~R~c*!RDe!^Yg=mMB}KN2Ehkb&d)g}_%VBGqyRgnKyx8y|n~aC%TUT-*k1e5_z0m9Dvz z(i}eFU`y(onF2hMaYH*8ESFx+y;$@2B@H|)UUPVy0rnGzi^Aa)wld)E74KHO&H(#{ z-9_PWIRh+kr8chs*gRGDRd~S)YWC;rydDkOitM;U4*Y>M^>}{?+-FAM@a8EM8 zHgKRQ9L|4afCcU}YV-t_@IC|VGj=xV^wkiHIGK@mGa|k>zU{%aU8=)ln`>`P94<>Z zw~Rd*dDmj}HI31+YlrYdyK5^sdR;qr33Dwu>#B{pJ$k6Q^Qtava_v^GR_Dj`l+sar zRBb1l>Q1iWNJMPpX!X$$_c4ndBe3VHa~v$?f}vUShPa@vaq_kK3xE z-^8(L^m@4(rj+*KTtqyYMrSsqbhRU<$@ns@KvLC4AMq+8&Q2pR#HBhr{%g43PCV_v TNlnKL00000NkvXXu0mjfVbbk@ From 5429e50bd0c4454c2158d14014a0f87e27442208 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 18 Jan 2015 12:30:31 +0100 Subject: [PATCH 114/203] updated error/info.png --- ui/chatArea/error.png | Bin 510 -> 508 bytes ui/chatArea/info.png | Bin 511 -> 521 bytes ui/chatArea/symbols.svg | 33 ++++++++++++++++----------------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/ui/chatArea/error.png b/ui/chatArea/error.png index 52f96da3f7358bcc0b2df77f109d3dc9c8d38d18..e7ee3deeab5280785d48e8bb288ebc120f59fae0 100644 GIT binary patch delta 408 zcmV;J0cZaH1N;M!Zhv`6L_t(Ijjfb1OG053hM#lnUZD_biKf7Y9E=Jj`xS-_wYIkP z1BxWcenNX|4T}H5LJ<*%h61OCq9p?FMNiAk;(8t8_O9nW&v(vuzVnHh5vBXRy|h6N zkvsrqErE8S(RhyXOBnR9zrQ^mk8gm@$P=Kesz*DuS|<{8cYk=8SoOS9%+3I32IN~l zB9{Z#tsdOojsWJqBLU>%x7&cv(FlO~L<0E9$nJ1$3{t-gWR88YnDpq;T7@Cc>MSPV0~c$M?cdb7$s`m>DkJZEh|a z6cAYlz^pFNDAj6hSG}Y`_gh=}IF8SORp$=SQq|pJ7&e`ttACxH%t90$Vs-@hKR|}+ zBU0%EL3R7`asZ%1CxM)#ArCJv+&({(IshNDlZ7Zc{E{eX=gyU6@9~jt6mgNyGohNc z`>I+hhGEkKNY2FB&e_Te26!Sa+fUZ6$!)p3Xd+Lps<$}iZ7={}GLymoo@m%s&NC=D zUEsRg<)+u8{eSw(em2X-+?=z{prE67;!t^ho`YQOC;L+*S$AjsgA}v+*c7w63N*&$ z2sAXAoz@tfR;gBND}bu*0{uTg`pMdl5h;dY6OoFmGEilCYKmFk@m@tL!{Hs>S|@;D9szgY zqz*~t4g|sq4}gFga0zdKM8S_hie$@j8!2wViilERJ6gOq1-n3&p-7ff&OP_cxifP{ zR23UO9nX&-CZjM8AW%kw%0{+SxA7$|^zrP&Tj{V1j9GVpntwXvx2CqMR-xQ}&KVr` z7D1K(_X&{*KIoUmMRRR$cCQ1FiYlSV>R)sPzjXsZs>eY@qKXT$IymeB6z?2`<9v-f zY5iz(@c9&gck9!513izNsl(*f)OIxm5T41Sak|nk$QCC6=uUUpMs&m8H?nXvH=^Qv zx3RRNTwgW;@PCFpj3YK0qMcELn2faww158QuyD>{;hgqW`zacT$(ZP!B!R-XNh%V- z2$YkG2$T&PR1(|Kpkl)8)Dp$e^)XZK@vn7`N2NsHCK{M(70e&RWD+{SHHQpSHc~5$-1>?Is-*dkAdv5o8m55-% z+UZgpr4s^400l*)R?1KB-9WsGPCMx2&&pcjwM4UUIGWD4+j)HYAOiqs0&UkySFuyZ{ z-C})nCKh9biQOw3Ah;9bIQY+~oJ8lCqZhm_IMgxdN8mRt3q#DfDBT^5bWKEsg(R2-T(%jKxU?m%d z*A7eGQ#sciYb6@m=JqD0wno1>2}2te{{I_^; i + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;text-anchor:start;font-family:Cantarell;-inkscape-font-specification:Cantarell">i @@ -99,57 +99,56 @@ transform="translate(330.16534,365.19627)" id="error"> + style="fill:#c84e4e;fill-opacity:1;stroke:#1c1c1c;stroke-width:11.59739304;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" /> i + id="flowPara2994-4-4" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;text-anchor:start;font-family:Cantarell;-inkscape-font-specification:Cantarell">i From 44921db440f14b9ccc27cf7a5e0384cbe7bf8cf7 Mon Sep 17 00:00:00 2001 From: Dubslow Date: Sun, 18 Jan 2015 13:57:51 -0600 Subject: [PATCH 115/203] minor code cleanup --- src/chatlog/content/filetransferwidget.cpp | 9 +++++---- src/chatlog/content/filetransferwidget.h | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index 67444cedd..95e683d7a 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -137,13 +137,14 @@ void FileTransferWidget::onFileTransferInfo(ToxFile file) qreal bytesPerSec = static_cast(static_cast(deltaBytes) / deltaSecs); // calculate mean - meanData[(meanIndex++) % FTW_MEAN_PERIODES] = bytesPerSec; + meanData[meanIndex] = bytesPerSec; + meanIndex = (meanIndex + 1) % TRANSFER_ROLLING_AVG_COUNT; qreal meanBytesPerSec = 0.0; - for(size_t i = 0; i < FTW_MEAN_PERIODES; ++i) + for(size_t i = 0; i < TRANSFER_ROLLING_AVG_COUNT; ++i) meanBytesPerSec += meanData[i]; - meanBytesPerSec /= qMin(meanIndex, static_cast(FTW_MEAN_PERIODES)); + meanBytesPerSec /= qMin(static_cast(meanIndex), static_cast(TRANSFER_ROLLING_AVG_COUNT)); // update UI if(meanBytesPerSec > 0) @@ -209,7 +210,7 @@ void FileTransferWidget::onFileTransferPaused(ToxFile file) // reset mean meanIndex = 0; - for(size_t i=0; i Date: Mon, 19 Jan 2015 10:07:51 +0100 Subject: [PATCH 116/203] fixed potential null deref. & memory leak --- src/chatlog/content/text.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 85fbec7fd..038676ef0 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -217,6 +217,9 @@ void Text::mousePressEvent(QGraphicsSceneMouseEvent *event) void Text::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { + if(!doc) + return; + QString anchor = doc->documentLayout()->anchorAt(event->pos()); // open anchors in browser @@ -231,11 +234,15 @@ QString Text::getText() const void Text::ensureIntegrity() { - if(!doc || dirty) + if(!doc) { doc = new CustomTextDocument(); doc->setDefaultFont(defFont); + dirty = true; + } + if(dirty) + { if(!elide) { doc->setHtml(text); From 2c8e7c638d06fb464b0e3985fe46f1a5698836c3 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 19 Jan 2015 10:08:43 +0100 Subject: [PATCH 117/203] nice! --- src/chatlog/content/text.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 038676ef0..ffa8d837f 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -102,9 +102,7 @@ void Text::selectionMouseMove(QPointF scenePos) } else { - text = itr.fragment().text(); - - for(QChar c : text) + for(QChar c : itr.fragment().text()) { if(pos >= cursor.selectionStart() && pos < cursor.selectionEnd()) selectedText += c; From f17ffdc4914f5958efc0a7237c469825868752f2 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 19 Jan 2015 11:14:53 +0100 Subject: [PATCH 118/203] cleanup --- src/chatlog/content/text.cpp | 54 ++++++++++++++---------------------- src/chatlog/content/text.h | 6 ++-- 2 files changed, 24 insertions(+), 36 deletions(-) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index ffa8d837f..6ed845c5a 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -36,10 +36,6 @@ Text::Text(const QString& txt, QFont font, bool enableElide, const QString &rwTe { setText(txt); setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton); - - ensureIntegrity(); - freeResources(); - //setCacheMode(QGraphicsItem::DeviceCoordinateCache); } Text::~Text() @@ -52,8 +48,7 @@ void Text::setText(const QString& txt) text = txt; dirty = true; - ensureIntegrity(); - freeResources(); + regenerate(); } void Text::setWidth(qreal w) @@ -62,21 +57,19 @@ void Text::setWidth(qreal w) return; width = w; + dirty = true; if(elide) { QFontMetrics metrics = QFontMetrics(defFont); elidedText = metrics.elidedText(text, Qt::ElideRight, width); - dirty = true; } - ensureIntegrity(); - freeResources(); + regenerate(); } void Text::selectionMouseMove(QPointF scenePos) { - ensureIntegrity(); int cur = cursorFromPos(scenePos); if(cur >= 0) { @@ -118,29 +111,23 @@ void Text::selectionMouseMove(QPointF scenePos) void Text::selectionStarted(QPointF scenePos) { - ensureIntegrity(); int cur = cursorFromPos(scenePos); if(cur >= 0) cursor.setPosition(cur); - - selectedText.clear(); - selectedText.squeeze(); } void Text::selectionCleared() { - ensureIntegrity(); - cursor.setPosition(0); + cursor.clearSelection(); selectedText.clear(); selectedText.squeeze(); - freeResources(); update(); } void Text::selectAll() { - ensureIntegrity(); + regenerate(); cursor.select(QTextCursor::Document); selectedText = text; update(); @@ -194,17 +181,13 @@ void Text::visibilityChanged(bool visible) { isVisible = visible; - if(visible) - ensureIntegrity(); - else - freeResources(); - + regenerate(); update(); } qreal Text::getAscent() const { - return vOffset; + return ascent; } void Text::mousePressEvent(QGraphicsSceneMouseEvent *event) @@ -220,7 +203,7 @@ void Text::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QString anchor = doc->documentLayout()->anchorAt(event->pos()); - // open anchors in browser + // open anchor in browser if(!anchor.isEmpty()) QDesktopServices::openUrl(anchor); } @@ -230,7 +213,7 @@ QString Text::getText() const return rawText; } -void Text::ensureIntegrity() +void Text::regenerate() { if(!doc) { @@ -257,26 +240,31 @@ void Text::ensureIntegrity() dirty = false; } + // width & layout doc->setTextWidth(width); doc->documentLayout()->update(); + // update ascent if(doc->firstBlock().layout()->lineCount() > 0) - vOffset = doc->firstBlock().layout()->lineAt(0).ascent(); + ascent = doc->firstBlock().layout()->lineAt(0).ascent(); + // let the scene know about our change in size if(size != idealSize()) prepareGeometryChange(); + // get the new width and height size = idealSize(); + + // if we are not visible -> free mem + if(!isVisible && !cursor.hasSelection()) + freeResources(); } void Text::freeResources() { - if(doc && !isVisible && !cursor.hasSelection()) - { - delete doc; - doc = nullptr; - cursor = QTextCursor(); - } + delete doc; + doc = nullptr; + cursor = QTextCursor(); } QSizeF Text::idealSize() diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index a99a9516e..e56a0a0f3 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -55,10 +55,10 @@ public: protected: // dynamic resource management - void ensureIntegrity(); + void regenerate(); void freeResources(); - QSizeF idealSize(); + QSizeF idealSize(); int cursorFromPos(QPointF scenePos) const; private: @@ -72,7 +72,7 @@ private: bool elide = false; bool dirty = false; QTextCursor cursor; - qreal vOffset = 0.0; + qreal ascent = 0.0; qreal width = 0.0; QFont defFont; From 85764d59737c32163cc3d68a331276fe9db735c7 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 19 Jan 2015 15:04:11 +0100 Subject: [PATCH 119/203] Text: Do not rely on QTextCursor for selection --- src/chatlog/content/text.cpp | 53 ++++++++++++++++++++++++++++-------- src/chatlog/content/text.h | 6 +++- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 6ed845c5a..2c03bdc97 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -70,13 +70,16 @@ void Text::setWidth(qreal w) void Text::selectionMouseMove(QPointF scenePos) { + if(!doc) + return; + int cur = cursorFromPos(scenePos); if(cur >= 0) { - cursor.setPosition(cur, QTextCursor::KeepAnchor); + selectionEnd = cur; selectedText.clear(); - QTextBlock block = cursor.block(); + QTextBlock block = doc->firstBlock(); for(QTextBlock::Iterator itr = block.begin(); itr!=block.end(); ++itr) { int pos = itr.fragment().position(); //fragment position -> position of the first character in the fragment @@ -87,7 +90,7 @@ void Text::selectionMouseMove(QPointF scenePos) QString key = imgFmt.name(); //img key (eg. key::D for :D) QString rune = key.mid(4); - if(pos >= cursor.selectionStart() && pos < cursor.selectionEnd()) + if(pos >= getSelectionStart() && pos < getSelectionEnd()) { selectedText += rune; pos++; @@ -97,7 +100,7 @@ void Text::selectionMouseMove(QPointF scenePos) { for(QChar c : itr.fragment().text()) { - if(pos >= cursor.selectionStart() && pos < cursor.selectionEnd()) + if(pos >= getSelectionStart() && pos < getSelectionEnd()) selectedText += c; pos++; @@ -113,22 +116,28 @@ void Text::selectionStarted(QPointF scenePos) { int cur = cursorFromPos(scenePos); if(cur >= 0) - cursor.setPosition(cur); + { + selectionEnd = cur; + selectionAnchor = cur; + } } void Text::selectionCleared() { - cursor.clearSelection(); selectedText.clear(); selectedText.squeeze(); + // Do not reset selectionAnchor! + selectionEnd = -1; + update(); } void Text::selectAll() { regenerate(); - cursor.select(QTextCursor::Document); + selectionAnchor = 0; + selectionEnd = doc->toPlainText().size(); selectedText = text; update(); } @@ -136,7 +145,7 @@ void Text::selectAll() bool Text::isOverSelection(QPointF scenePos) const { int cur = cursorFromPos(scenePos); - if(cur >= 0 && cursor.selectionStart() < cur && cursor.selectionEnd() >= cur) + if(getSelectionStart() < cur && getSelectionEnd() >= cur) return true; return false; @@ -164,7 +173,14 @@ void Text::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWid // draw selection QAbstractTextDocumentLayout::PaintContext ctx; QAbstractTextDocumentLayout::Selection sel; - sel.cursor = cursor; + + if(hasSelection()) + { + sel.cursor = QTextCursor(doc); + sel.cursor.setPosition(getSelectionStart()); + sel.cursor.setPosition(getSelectionEnd(), QTextCursor::KeepAnchor); + } + sel.format.setBackground(QApplication::palette().color(QPalette::Highlight)); sel.format.setForeground(QApplication::palette().color(QPalette::HighlightedText)); ctx.selections.append(sel); @@ -236,7 +252,6 @@ void Text::regenerate() doc->setPlainText(elidedText); } - cursor = QTextCursor(doc); dirty = false; } @@ -256,7 +271,7 @@ void Text::regenerate() size = idealSize(); // if we are not visible -> free mem - if(!isVisible && !cursor.hasSelection()) + if(!isVisible) freeResources(); } @@ -264,7 +279,6 @@ void Text::freeResources() { delete doc; doc = nullptr; - cursor = QTextCursor(); } QSizeF Text::idealSize() @@ -282,3 +296,18 @@ int Text::cursorFromPos(QPointF scenePos) const return -1; } + +int Text::getSelectionEnd() const +{ + return qMax(selectionAnchor, selectionEnd); +} + +int Text::getSelectionStart() const +{ + return qMin(selectionAnchor, selectionEnd); +} + +bool Text::hasSelection() const +{ + return selectionEnd >= 0; +} diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index e56a0a0f3..8c3ef17e2 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -60,6 +60,9 @@ protected: QSizeF idealSize(); int cursorFromPos(QPointF scenePos) const; + int getSelectionEnd() const; + int getSelectionStart() const; + bool hasSelection() const; private: CustomTextDocument* doc = nullptr; @@ -71,7 +74,8 @@ private: bool isVisible = false; bool elide = false; bool dirty = false; - QTextCursor cursor; + int selectionEnd = -1; + int selectionAnchor = -1; qreal ascent = 0.0; qreal width = 0.0; QFont defFont; From a6e3fc671e4262475c6c9a6b23b8229b8b3697a1 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 19 Jan 2015 15:07:15 +0100 Subject: [PATCH 120/203] removed selectAll() --- src/chatlog/chatline.cpp | 12 ------------ src/chatlog/chatline.h | 2 -- src/chatlog/chatlinecontent.cpp | 4 ---- src/chatlog/chatlinecontent.h | 1 - src/chatlog/content/text.cpp | 9 --------- src/chatlog/content/text.h | 1 - 6 files changed, 29 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index b0a56adea..3ba80e0f5 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -119,18 +119,6 @@ void ChatLine::selectionCleared(int col) content[col]->selectionCleared(); } -void ChatLine::selectAll() -{ - for(ChatLineContent* c : content) - c->selectAll(); -} - -void ChatLine::selectAll(int col) -{ - if(col < static_cast(content.size()) && content[col]) - content[col]->selectAll(); -} - int ChatLine::getColumnCount() { return content.size(); diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index 7514654cb..e90f0cd4b 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -70,8 +70,6 @@ public: void selectionCleared(); void selectionCleared(int col); - void selectAll(); - void selectAll(int col); int getColumnCount(); int getRowIndex() const; diff --git a/src/chatlog/chatlinecontent.cpp b/src/chatlog/chatlinecontent.cpp index 2dd5a9584..237c9f229 100644 --- a/src/chatlog/chatlinecontent.cpp +++ b/src/chatlog/chatlinecontent.cpp @@ -51,10 +51,6 @@ void ChatLineContent::selectionCleared() { } -void ChatLineContent::selectAll() -{ -} - bool ChatLineContent::isOverSelection(QPointF) const { return false; diff --git a/src/chatlog/chatlinecontent.h b/src/chatlog/chatlinecontent.h index 9cb2a3db8..1dd77e55d 100644 --- a/src/chatlog/chatlinecontent.h +++ b/src/chatlog/chatlinecontent.h @@ -38,7 +38,6 @@ public: virtual void selectionMouseMove(QPointF scenePos); virtual void selectionStarted(QPointF scenePos); virtual void selectionCleared(); - virtual void selectAll(); virtual bool isOverSelection(QPointF scenePos) const; virtual QString getSelectedText() const; diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 2c03bdc97..9e5c87243 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -133,15 +133,6 @@ void Text::selectionCleared() update(); } -void Text::selectAll() -{ - regenerate(); - selectionAnchor = 0; - selectionEnd = doc->toPlainText().size(); - selectedText = text; - update(); -} - bool Text::isOverSelection(QPointF scenePos) const { int cur = cursorFromPos(scenePos); diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index 8c3ef17e2..7b838840f 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -37,7 +37,6 @@ public: virtual void selectionMouseMove(QPointF scenePos) override; virtual void selectionStarted(QPointF scenePos) override; virtual void selectionCleared() override; - virtual void selectAll() override; virtual bool isOverSelection(QPointF scenePos) const override; virtual QString getSelectedText() const override; From 34c7c7250b82e15abf451e13fc4357fd0a0cc0b8 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 19 Jan 2015 15:19:54 +0100 Subject: [PATCH 121/203] double-click selection --- src/chatlog/chatlinecontent.cpp | 6 ++++++ src/chatlog/chatlinecontent.h | 1 + src/chatlog/chatlog.cpp | 16 ++++++++++++++++ src/chatlog/chatlog.h | 1 + src/chatlog/content/text.cpp | 20 ++++++++++++++++++++ src/chatlog/content/text.h | 3 +++ 6 files changed, 47 insertions(+) diff --git a/src/chatlog/chatlinecontent.cpp b/src/chatlog/chatlinecontent.cpp index 237c9f229..9b163d4fd 100644 --- a/src/chatlog/chatlinecontent.cpp +++ b/src/chatlog/chatlinecontent.cpp @@ -49,6 +49,12 @@ void ChatLineContent::selectionStarted(QPointF) void ChatLineContent::selectionCleared() { + +} + +void ChatLineContent::selectionDoubleClick(QPointF) +{ + } bool ChatLineContent::isOverSelection(QPointF) const diff --git a/src/chatlog/chatlinecontent.h b/src/chatlog/chatlinecontent.h index 1dd77e55d..832b57e58 100644 --- a/src/chatlog/chatlinecontent.h +++ b/src/chatlog/chatlinecontent.h @@ -38,6 +38,7 @@ public: virtual void selectionMouseMove(QPointF scenePos); virtual void selectionStarted(QPointF scenePos); virtual void selectionCleared(); + virtual void selectionDoubleClick(QPointF scenePos); virtual bool isOverSelection(QPointF scenePos) const; virtual QString getSelectedText() const; diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 377a37c22..329dbeaa0 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -479,6 +479,22 @@ void ChatLog::scrollToBottom() verticalScrollBar()->setValue(verticalScrollBar()->maximum()); } +void ChatLog::mouseDoubleClickEvent(QMouseEvent *ev) +{ + QPointF scenePos = mapToScene(ev->pos()); + ChatLineContent* content = getContentFromPos(scenePos); + + if(content) + { + content->selectionDoubleClick(scenePos); + selClickedCol = content->getColumn(); + selClickedRow = content->getRow(); + selFirstRow = content->getRow(); + selLastRow = content->getRow(); + selectionMode = Precise; + } +} + QString ChatLog::getSelectedText() const { if(selectionMode == Precise) diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index af031842f..48296592c 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -69,6 +69,7 @@ protected: void checkVisibility(); void scrollToBottom(); + virtual void mouseDoubleClickEvent(QMouseEvent* ev); virtual void mousePressEvent(QMouseEvent* ev); virtual void mouseReleaseEvent(QMouseEvent* ev); virtual void mouseMoveEvent(QMouseEvent* ev); diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 9e5c87243..598fbef03 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -133,6 +133,26 @@ void Text::selectionCleared() update(); } +void Text::selectionDoubleClick(QPointF scenePos) +{ + if(!doc) + return; + + int cur = cursorFromPos(scenePos); + + if(cur >= 0) + { + QTextCursor cursor(doc); + cursor.setPosition(cur); + cursor.select(QTextCursor::WordUnderCursor); + + selectionAnchor = cursor.selectionStart(); + selectionEnd = cursor.selectionEnd(); + } + + update(); +} + bool Text::isOverSelection(QPointF scenePos) const { int cur = cursorFromPos(scenePos); diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index 7b838840f..1a231805a 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -27,6 +27,8 @@ class CustomTextDocument; class Text : public ChatLineContent { public: + // txt: may contain html code + // rawText: does not contain html code Text(const QString& txt = "", QFont font = QFont(), bool enableElide = false, const QString& rawText = QString()); virtual ~Text(); @@ -37,6 +39,7 @@ public: virtual void selectionMouseMove(QPointF scenePos) override; virtual void selectionStarted(QPointF scenePos) override; virtual void selectionCleared() override; + virtual void selectionDoubleClick(QPointF scenePos) override; virtual bool isOverSelection(QPointF scenePos) const override; virtual QString getSelectedText() const override; From b5b6ae99c0ad44bae982c28594bc24218f2308a7 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 19 Jan 2015 17:56:37 +0100 Subject: [PATCH 122/203] Text: extractSanitizedText, hookup double-click selection --- src/chatlog/content/text.cpp | 72 +++++++++++++++++++++--------------- src/chatlog/content/text.h | 1 + 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 598fbef03..828b4d88e 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -77,36 +77,7 @@ void Text::selectionMouseMove(QPointF scenePos) if(cur >= 0) { selectionEnd = cur; - selectedText.clear(); - - QTextBlock block = doc->firstBlock(); - for(QTextBlock::Iterator itr = block.begin(); itr!=block.end(); ++itr) - { - int pos = itr.fragment().position(); //fragment position -> position of the first character in the fragment - - if(itr.fragment().charFormat().isImageFormat()) - { - QTextImageFormat imgFmt = itr.fragment().charFormat().toImageFormat(); - QString key = imgFmt.name(); //img key (eg. key::D for :D) - QString rune = key.mid(4); - - if(pos >= getSelectionStart() && pos < getSelectionEnd()) - { - selectedText += rune; - pos++; - } - } - else - { - for(QChar c : itr.fragment().text()) - { - if(pos >= getSelectionStart() && pos < getSelectionEnd()) - selectedText += c; - - pos++; - } - } - } + selectedText = extractSanitizedText(getSelectionStart(), getSelectionEnd()); } update(); @@ -148,6 +119,8 @@ void Text::selectionDoubleClick(QPointF scenePos) selectionAnchor = cursor.selectionStart(); selectionEnd = cursor.selectionEnd(); + + selectedText = extractSanitizedText(getSelectionStart(), getSelectionEnd()); } update(); @@ -322,3 +295,42 @@ bool Text::hasSelection() const { return selectionEnd >= 0; } + +QString Text::extractSanitizedText(int from, int to) const +{ + if(!doc) + return ""; + + QString txt; + QTextBlock block = doc->firstBlock(); + + for(QTextBlock::Iterator itr = block.begin(); itr!=block.end(); ++itr) + { + int pos = itr.fragment().position(); //fragment position -> position of the first character in the fragment + + if(itr.fragment().charFormat().isImageFormat()) + { + QTextImageFormat imgFmt = itr.fragment().charFormat().toImageFormat(); + QString key = imgFmt.name(); //img key (eg. key::D for :D) + QString rune = key.mid(4); + + if(pos >= from && pos < to) + { + txt += rune; + pos++; + } + } + else + { + for(QChar c : itr.fragment().text()) + { + if(pos >= from && pos < to) + txt += c; + + pos++; + } + } + } + + return txt; +} diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index 1a231805a..f61711789 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -65,6 +65,7 @@ protected: int getSelectionEnd() const; int getSelectionStart() const; bool hasSelection() const; + QString extractSanitizedText(int from, int to) const; private: CustomTextDocument* doc = nullptr; From bb29536df1a75810c20cc9bc46e7d75e1e5faa4a Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 19 Jan 2015 19:04:19 +0100 Subject: [PATCH 123/203] NotificationIcon --- qtox.pro | 6 +- src/chatlog/chatmessage.cpp | 3 +- src/chatlog/content/notificationicon.cpp | 83 +++++++++++++++++++++++ src/chatlog/content/notificationicon.h | 52 ++++++++++++++ ui/chatArea/symbols.svg | 4 ++ ui/chatArea/typing.png | Bin 613 -> 302 bytes 6 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 src/chatlog/content/notificationicon.cpp create mode 100644 src/chatlog/content/notificationicon.h diff --git a/qtox.pro b/qtox.pro index 69a37c204..21edabc2d 100644 --- a/qtox.pro +++ b/qtox.pro @@ -191,7 +191,8 @@ HEADERS += src/widget/form/addfriendform.h \ src/chatlog/content/image.h \ src/chatlog/customtextdocument.h \ src/widget/form/settings/advancedform.h \ - src/audio.h + src/audio.h \ + src/chatlog/content/notificationicon.h SOURCES += \ src/widget/form/addfriendform.cpp \ @@ -260,7 +261,8 @@ SOURCES += \ src/chatlog/content/image.cpp \ src/chatlog/customtextdocument.cpp\ src/widget/form/settings/advancedform.cpp \ - src/audio.cpp + src/audio.cpp \ + src/chatlog/content/notificationicon.cpp contains(DEFINES, QTOX_FILTER_AUDIO) { HEADERS += src/audiofilterer.h diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 8d600cd5e..768b491d5 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -20,6 +20,7 @@ #include "content/spinner.h" #include "content/filetransferwidget.h" #include "content/image.h" +#include "content/notificationicon.h" #include "src/misc/settings.h" #include "src/misc/smileypack.h" @@ -100,7 +101,7 @@ ChatMessage::Ptr ChatMessage::createTypingNotification() { ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); - msg->addColumn(new Spinner(":/ui/chatArea/typing.png", QSizeF(18, 18), 6.0), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + msg->addColumn(new NotificationIcon(QSizeF(18, 18)), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text("%1 ...", Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Left)); return msg; diff --git a/src/chatlog/content/notificationicon.cpp b/src/chatlog/content/notificationicon.cpp new file mode 100644 index 000000000..b57caacde --- /dev/null +++ b/src/chatlog/content/notificationicon.cpp @@ -0,0 +1,83 @@ +/* + Copyright (C) 2015 by Project Tox + + 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 "notificationicon.h" + +#include +#include + +NotificationIcon::NotificationIcon(QSizeF Size) + : size(Size) +{ + pmap.load(":/ui/chatArea/typing.png"); + + updateTimer = new QTimer(this); + updateTimer->setInterval(1000/60); + updateTimer->setSingleShot(false); + + updateTimer->start(); + + connect(updateTimer, &QTimer::timeout, this, &NotificationIcon::updateGradient); +} + +QRectF NotificationIcon::boundingRect() const +{ + return QRectF(QPointF(-size.width() / 2.0, -size.height() / 2.0), size); +} + +void NotificationIcon::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + painter->setRenderHint(QPainter::SmoothPixmapTransform); + painter->translate(-size.width() / 2.0, -size.height() / 2.0); + + painter->fillRect(QRect(0, 0, size.width(), size.height()), grad); + painter->drawPixmap(0, 0, size.width(), size.height(), pmap); + + Q_UNUSED(option) + Q_UNUSED(widget) +} + +void NotificationIcon::setWidth(qreal width) +{ + Q_UNUSED(width) +} + +QRectF NotificationIcon::boundingSceneRect() const +{ + return QRectF(scenePos(), size); +} + +qreal NotificationIcon::getAscent() const +{ + return 3.0; +} + +void NotificationIcon::updateGradient() +{ + alpha += 0.005; + + if(alpha + dotWidth >= 1.0) + alpha = 0.0; + + grad = QLinearGradient(QPointF(-0.5*size.width(),0), QPointF(3.0/2.0*size.width(),0)); + grad.setColorAt(0, Qt::lightGray); + grad.setColorAt(qMax(0.0, alpha - dotWidth), Qt::lightGray); + grad.setColorAt(alpha, Qt::darkGray); + grad.setColorAt(qMin(1.0, alpha + dotWidth), Qt::lightGray); + grad.setColorAt(1, Qt::lightGray); + + update(); +} diff --git a/src/chatlog/content/notificationicon.h b/src/chatlog/content/notificationicon.h new file mode 100644 index 000000000..a68b87c5c --- /dev/null +++ b/src/chatlog/content/notificationicon.h @@ -0,0 +1,52 @@ +/* + Copyright (C) 2015 by Project Tox + + 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 NOTIFICATIONICON_H +#define NOTIFICATIONICON_H + +#include "../chatlinecontent.h" + +#include + +class QTimer; + +class NotificationIcon : public QObject, public ChatLineContent +{ + Q_OBJECT +public: + NotificationIcon(QSizeF size); + + virtual QRectF boundingRect() const override; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; + virtual void setWidth(qreal width) override; + virtual QRectF boundingSceneRect() const override; + virtual qreal getAscent() const override; + +private slots: + void updateGradient(); + +private: + QSizeF size; + QPixmap pmap; + QLinearGradient grad; + QTimer* updateTimer = nullptr; + + qreal dotWidth = 0.2; + qreal alpha = 0.0; + +}; + +#endif // NOTIFICATIONICON_H diff --git a/ui/chatArea/symbols.svg b/ui/chatArea/symbols.svg index 5cce80c76..2d56a1657 100644 --- a/ui/chatArea/symbols.svg +++ b/ui/chatArea/symbols.svg @@ -153,4 +153,8 @@ id="path3806-6-4" style="fill:#c84e4e;fill-opacity:1;stroke:none" /> + diff --git a/ui/chatArea/typing.png b/ui/chatArea/typing.png index d103baa5bb4f1819b3fa5aebae9b380b2980bebc..116bbc22c8ea9427f9e5e53bf19202dcd505ea5b 100644 GIT binary patch delta 251 zcmV5Zd(abx2c6a$ozx4fp<@ zd+vBSQB^|q^vlC*Cq8;1@Bl#JvyJ@oSNV6pL%f7UkL!m1W>;JMI?YCpgqqd->b}R%0`*hj5m5K|*=l}uKlskHe>A9ty@d?GN^YfhA*iZn zD@kH|uvHv?JKqbftzvO3iDP@dC#uTNq;S)TsRH)^gUGIWd2)O1!`}HzcS@z4c)zT0 z2XH{cKxL*@Ys&7&`5VUY1DF_kY)>`1JCN;^N;$m$3S@@3j&Uv<8Ou^Y0+5kNm(Paj z{c=D8FyV|@l5h3-KPXpIM%bI|W+o3_!<9_tUy2BOpdF!doDu@K)_B*Ace{@MOw#H& z5`6svpb^K(Nt`4nzy-gZdgP2 Date: Tue, 20 Jan 2015 10:31:50 +0100 Subject: [PATCH 124/203] renamed get/setRowIndex to get/setRow --- src/chatlog/chatline.cpp | 14 +++++++------- src/chatlog/chatline.h | 6 +++--- src/chatlog/chatlog.cpp | 18 +++++++++--------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index 3ba80e0f5..1c297f40e 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -40,12 +40,12 @@ ChatLine::~ChatLine() } } -void ChatLine::setRowIndex(int idx) +void ChatLine::setRow(int idx) { - rowIndex = idx; + row = idx; for(int c = 0; c < static_cast(content.size()); ++c) - content[c]->setIndex(rowIndex, c); + content[c]->setIndex(row, c); } void ChatLine::visibilityChanged(bool visible) @@ -59,9 +59,9 @@ void ChatLine::visibilityChanged(bool visible) isVisible = visible; } -int ChatLine::getRowIndex() const +int ChatLine::getRow() const { - return rowIndex; + return row; } ChatLineContent *ChatLine::getContent(int col) const @@ -155,7 +155,7 @@ void ChatLine::replaceContent(int col, ChatLineContent *lineContent) delete content[col]; content[col] = lineContent; - lineContent->setIndex(rowIndex, col); + lineContent->setIndex(row, col); if(scene) scene->addItem(content[col]); @@ -261,5 +261,5 @@ bool ChatLine::lessThanBSRectBottom(const ChatLine::Ptr lhs, const qreal rhs) bool ChatLine::lessThanRowIndex(const ChatLine::Ptr lhs, const ChatLine::Ptr rhs) { - return lhs->getRowIndex() < rhs->getRowIndex(); + return lhs->getRow() < rhs->getRow(); } diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index e90f0cd4b..964f00ef6 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -72,7 +72,7 @@ public: void selectionCleared(int col); int getColumnCount(); - int getRowIndex() const; + int getRow() const; ChatLineContent* getContent(int col) const; ChatLineContent* getContent(QPointF scenePos) const; @@ -89,7 +89,7 @@ protected: void updateBBox(); friend class ChatLog; - void setRowIndex(int idx); + void setRow(int idx); void visibilityChanged(bool visible); //comparators @@ -98,7 +98,7 @@ protected: static bool lessThanRowIndex(const ChatLine::Ptr lhs, const ChatLine::Ptr rhs); private: - int rowIndex = -1; + int row = -1; std::vector content; // 3 columns std::vector format; qreal width; diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 329dbeaa0..f7fdb25cc 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -86,7 +86,7 @@ ChatLog::ChatLog(QWidget* parent) if(!visibleLines.isEmpty()) { - int firstVisLineIndex = visibleLines.first()->getRowIndex(); + int firstVisLineIndex = visibleLines.first()->getRow(); int delta = firstVisLineIndex - workerLastIndex; if(delta > 0 && delta < stepSize) { @@ -199,8 +199,8 @@ void ChatLog::updateVisibleLines() repos = 0; if(!visibleLines.empty()) { - repos = layout(visibleLines.first()->getRowIndex(), visibleLines.last()->getRowIndex(), useableWidth()); - reposition(visibleLines.last()->getRowIndex()+1, visibleLines.last()->getRowIndex()+10, -repos); + repos = layout(visibleLines.first()->getRow(), visibleLines.last()->getRow(), useableWidth()); + reposition(visibleLines.last()->getRow()+1, visibleLines.last()->getRow()+10, -repos); verticalScrollBar()->setValue(verticalScrollBar()->value() - repos); } @@ -292,7 +292,7 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) } else if(line.get()) { - selClickedRow = line->getRowIndex(); + selClickedRow = line->getRow(); selFirstRow = selClickedRow; selLastRow = selClickedRow; @@ -331,7 +331,7 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) } else if(line.get()) { - row = line->getRowIndex(); + row = line->getRow(); if(row != selClickedRow) { @@ -414,12 +414,12 @@ void ChatLog::insertChatlineAtBottom(ChatLine::Ptr l) bool stickToBtm = stickToBottom(); //insert - l->setRowIndex(lines.size()); + l->setRow(lines.size()); l->addToScene(scene); lines.append(l); //partial refresh - layout(lines.last()->getRowIndex(), lines.size(), useableWidth()); + layout(lines.last()->getRow(), lines.size(), useableWidth()); updateSceneRect(); if(stickToBtm) @@ -447,13 +447,13 @@ void ChatLog::insertChatlineOnTop(const QList& newLines) //move all lines down by n int n = newLines.size(); for(ChatLine::Ptr l : lines) - l->setRowIndex(l->getRowIndex() + n); + l->setRow(l->getRow() + n); //add the new line for(ChatLine::Ptr l : newLines) { l->addToScene(scene); - l->setRowIndex(--n); + l->setRow(--n); lines.prepend(l); } From 13e0a8a2924f0030922b9c81a25d50d0f2e2c305 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 20 Jan 2015 10:44:05 +0100 Subject: [PATCH 125/203] cleanup --- src/chatlog/chatline.cpp | 8 ++------ src/chatlog/chatline.h | 28 ++++++++++++++-------------- src/chatlog/chatlog.cpp | 1 + src/chatlog/chatlog.h | 1 + 4 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index 1c297f40e..ccb644822 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -15,15 +15,11 @@ */ #include "chatline.h" -#include "chatlog.h" #include "chatlinecontent.h" -#include #include #include -#define CELL_SPACING 15 - ChatLine::ChatLine() { @@ -171,7 +167,7 @@ void ChatLine::layout(qreal w, QPointF scenePos) width = w; bbox.setTopLeft(scenePos); - qreal fixedWidth = (content.size()-1) * CELL_SPACING; + qreal fixedWidth = (content.size()-1) * cellSplacing; qreal varWidth = 0.0; // used for normalisation for(int i = 0; i < static_cast(format.size()); ++i) @@ -222,7 +218,7 @@ void ChatLine::layout(qreal w, QPointF scenePos) // reposition content[i]->setPos(scenePos.x() + xOffset + xAlign, scenePos.y()); - xOffset += width + CELL_SPACING; + xOffset += width + cellSplacing; } for(int i = 0; i < static_cast(content.size()); ++i) diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index 964f00ef6..514ff40b1 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -17,9 +17,10 @@ #ifndef CHATLINE_H #define CHATLINE_H -#include #include #include +#include +#include class ChatLog; class ChatLineContent; @@ -58,37 +59,35 @@ class ChatLine public: using Ptr = std::shared_ptr; - explicit ChatLine(); + ChatLine(); virtual ~ChatLine(); - virtual QRectF boundingSceneRect() const; + QRectF boundingSceneRect() const; void replaceContent(int col, ChatLineContent* lineContent); - void layout(qreal width, QPointF scenePos); void moveBy(qreal deltaY); - + void removeFromScene(); + void addToScene(QGraphicsScene* scene); + void setVisible(bool visible); void selectionCleared(); void selectionCleared(int col); int getColumnCount(); int getRow() const; + ChatLineContent* getContent(int col) const; ChatLineContent* getContent(QPointF scenePos) const; bool isOverSelection(QPointF scenePos); - void removeFromScene(); - void addToScene(QGraphicsScene* scene); - - void setVisible(bool visible); - protected: + friend class ChatLog; + QPointF mapToContent(ChatLineContent* c, QPointF pos); + void addColumn(ChatLineContent* item, ColumnFormat fmt); void updateBBox(); - - friend class ChatLog; void setRow(int idx); void visibilityChanged(bool visible); @@ -99,9 +98,10 @@ protected: private: int row = -1; - std::vector content; // 3 columns + std::vector content; std::vector format; - qreal width; + qreal width = 100.0; + qreal cellSplacing = 15.0; QRectF bbox; bool isVisible = false; diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index f7fdb25cc..a57a19898 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -24,6 +24,7 @@ #include #include #include +#include template T clamp(T x, T min, T max) diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 48296592c..ff7c67787 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -26,6 +26,7 @@ class QGraphicsScene; class QGraphicsRectItem; +class QMouseEvent; class QTimer; class ChatLineContent; class ToxFile; From 2fa2fc1df59d623a1c82a3c235218c90f038a725 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 20 Jan 2015 11:03:06 +0100 Subject: [PATCH 126/203] fix divide by zero --- src/chatlog/content/filetransferwidget.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index 95e683d7a..184a57d1c 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -137,14 +137,14 @@ void FileTransferWidget::onFileTransferInfo(ToxFile file) qreal bytesPerSec = static_cast(static_cast(deltaBytes) / deltaSecs); // calculate mean - meanData[meanIndex] = bytesPerSec; - meanIndex = (meanIndex + 1) % TRANSFER_ROLLING_AVG_COUNT; + meanIndex = meanIndex % TRANSFER_ROLLING_AVG_COUNT; + meanData[meanIndex++] = bytesPerSec; qreal meanBytesPerSec = 0.0; for(size_t i = 0; i < TRANSFER_ROLLING_AVG_COUNT; ++i) meanBytesPerSec += meanData[i]; - meanBytesPerSec /= qMin(static_cast(meanIndex), static_cast(TRANSFER_ROLLING_AVG_COUNT)); + meanBytesPerSec /= static_cast(TRANSFER_ROLLING_AVG_COUNT); // update UI if(meanBytesPerSec > 0) From d0bd6e9dcadc465816ba6b181fae36434b1d19d7 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 20 Jan 2015 11:08:40 +0100 Subject: [PATCH 127/203] show 2 decimals starting from MiB --- src/chatlog/content/filetransferwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index 184a57d1c..f52b18a26 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -256,7 +256,7 @@ QString FileTransferWidget::getHumanReadableSize(qint64 size) if (size > 0) exp = std::min( (int) (log(size) / log(1024)), (int) (sizeof(suffix) / sizeof(suffix[0]) - 1)); - return QString().setNum(size / pow(1024, exp),'f', exp > 2 ? 2 : 0).append(suffix[exp]); + return QString().setNum(size / pow(1024, exp),'f', exp > 1 ? 2 : 0).append(suffix[exp]); } void FileTransferWidget::hideWidgets() From ad392511667a7b3df8b4cca08f56363b64089c03 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 20 Jan 2015 11:51:34 +0100 Subject: [PATCH 128/203] typo --- src/chatlog/chatline.cpp | 4 ++-- src/chatlog/chatline.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index ccb644822..24a1c198e 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -167,7 +167,7 @@ void ChatLine::layout(qreal w, QPointF scenePos) width = w; bbox.setTopLeft(scenePos); - qreal fixedWidth = (content.size()-1) * cellSplacing; + qreal fixedWidth = (content.size()-1) * columnSpacing; qreal varWidth = 0.0; // used for normalisation for(int i = 0; i < static_cast(format.size()); ++i) @@ -218,7 +218,7 @@ void ChatLine::layout(qreal w, QPointF scenePos) // reposition content[i]->setPos(scenePos.x() + xOffset + xAlign, scenePos.y()); - xOffset += width + cellSplacing; + xOffset += width + columnSpacing; } for(int i = 0; i < static_cast(content.size()); ++i) diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index 514ff40b1..0f0a5add1 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -101,7 +101,7 @@ private: std::vector content; std::vector format; qreal width = 100.0; - qreal cellSplacing = 15.0; + qreal columnSpacing = 15.0; QRectF bbox; bool isVisible = false; From 9cb7ba06ed9ade244637f489940abe25a218faab Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 21 Jan 2015 15:58:43 +0100 Subject: [PATCH 129/203] cleanup --- src/chatlog/chatline.cpp | 6 ------ src/chatlog/chatline.h | 1 - 2 files changed, 7 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index 24a1c198e..fad71cfbb 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -109,12 +109,6 @@ void ChatLine::selectionCleared() c->selectionCleared(); } -void ChatLine::selectionCleared(int col) -{ - if(col < static_cast(content.size()) && content[col]) - content[col]->selectionCleared(); -} - int ChatLine::getColumnCount() { return content.size(); diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index 0f0a5add1..3813e2a52 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -71,7 +71,6 @@ public: void addToScene(QGraphicsScene* scene); void setVisible(bool visible); void selectionCleared(); - void selectionCleared(int col); int getColumnCount(); int getRow() const; From 6e05782fb79e593c082aada6aab026f39dd5e49b Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 25 Jan 2015 14:06:06 +0100 Subject: [PATCH 130/203] ChatLog: busy-screen during resize Gets rid of most ugly hacks --- src/chatlog/chatlog.cpp | 213 +++++++++++++--------------- src/chatlog/chatlog.h | 12 +- src/chatlog/chatmessage.cpp | 13 +- src/chatlog/chatmessage.h | 1 + src/widget/form/genericchatform.cpp | 1 + 5 files changed, 120 insertions(+), 120 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index a57a19898..c95fec078 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -40,6 +40,7 @@ ChatLog::ChatLog(QWidget* parent) : QGraphicsView(parent) { // Create the scene + busyScene = new QGraphicsScene(this); scene = new QGraphicsScene(this); scene->setItemIndexMethod(QGraphicsScene::NoIndex); //Bsp-Tree is actually slower in this case setScene(scene); @@ -80,43 +81,7 @@ ChatLog::ChatLog(QWidget* parent) workerTimer = new QTimer(this); workerTimer->setSingleShot(false); workerTimer->setInterval(100); - connect(workerTimer, &QTimer::timeout, this, [this] { - const int stepSize = 400; - - workerDy += layout(workerLastIndex, workerLastIndex+stepSize, useableWidth()); - - if(!visibleLines.isEmpty()) - { - int firstVisLineIndex = visibleLines.first()->getRow(); - int delta = firstVisLineIndex - workerLastIndex; - if(delta > 0 && delta < stepSize) - { - workerLastIndex += delta+1; - - if(!workerStb) - verticalScrollBar()->setValue(verticalScrollBar()->value() - workerDy); - - workerDy = 0.0; - checkVisibility(); - } - else - { - workerLastIndex += stepSize; - } - } - else - workerLastIndex += stepSize; - - if(workerLastIndex >= lines.size()) - { - workerTimer->stop(); - workerLastIndex = 0; - workerDy = 0.0; - - if(stickToBottom()) - scrollToBottom(); - } - }); + connect(workerTimer, &QTimer::timeout, this, &ChatLog::onWorkerTimeout); } void ChatLog::clearSelection() @@ -147,10 +112,10 @@ void ChatLog::updateSceneRect() setSceneRect(calculateSceneRect()); } -qreal ChatLog::layout(int start, int end, qreal width) +void ChatLog::layout(int start, int end, qreal width) { if(lines.empty()) - return false; + return; qreal h = 0.0; @@ -162,59 +127,13 @@ qreal ChatLog::layout(int start, int end, qreal width) start = clamp(start, 0, lines.size()); end = clamp(end + 1, 0, lines.size()); - qreal deltaY = 0.0; for(int i = start; i < end; ++i) { ChatLine* l = lines[i].get(); - qreal oldHeight = l->boundingSceneRect().height(); l->layout(width, QPointF(0.0, h)); - - if(oldHeight != l->boundingSceneRect().height()) - deltaY += oldHeight - l->boundingSceneRect().height(); - h += l->boundingSceneRect().height() + lineSpacing; } - - return deltaY; -} - -void ChatLog::updateVisibleLines() -{ - checkVisibility(); - - if(visibleLines.empty()) - return; - - bool stb = stickToBottom(); - - auto oldUpdateMode = viewportUpdateMode(); - setViewportUpdateMode(NoViewportUpdate); - - // Resize all lines currently visible in the viewport. - // If this creates some whitespace underneath the last visible lines - // then move the following non visible lines up in order to fill the gap. - qreal repos; - do - { - repos = 0; - if(!visibleLines.empty()) - { - repos = layout(visibleLines.first()->getRow(), visibleLines.last()->getRow(), useableWidth()); - reposition(visibleLines.last()->getRow()+1, visibleLines.last()->getRow()+10, -repos); - verticalScrollBar()->setValue(verticalScrollBar()->value() - repos); - } - - checkVisibility(); - } - while(repos != 0); - - checkVisibility(); - - setViewportUpdateMode(oldUpdateMode); - - if(stb) - scrollToBottom(); } void ChatLog::mousePressEvent(QMouseEvent* ev) @@ -443,14 +362,12 @@ void ChatLog::insertChatlineOnTop(const QList& newLines) if(newLines.isEmpty()) return; - bool stickToBtm = stickToBottom(); - - //move all lines down by n + // move all lines down by n int n = newLines.size(); for(ChatLine::Ptr l : lines) l->setRow(l->getRow() + n); - //add the new line + // add the new line for(ChatLine::Ptr l : newLines) { l->addToScene(scene); @@ -458,15 +375,8 @@ void ChatLog::insertChatlineOnTop(const QList& newLines) lines.prepend(l); } - //full refresh is required - layout(0, lines.size(), useableWidth()); - updateSceneRect(); - - if(stickToBtm) - scrollToBottom(); - - checkVisibility(); - updateTypingNotification(); + // redo layout + startResizeWorker(); } bool ChatLog::stickToBottom() const @@ -480,6 +390,27 @@ void ChatLog::scrollToBottom() verticalScrollBar()->setValue(verticalScrollBar()->maximum()); } +void ChatLog::startResizeWorker() +{ + // (re)start the worker + if(!workerTimer->isActive()) + { + // these values must not be reevaluated while the worker is running + workerStb = stickToBottom(); + + if(!visibleLines.empty()) + workerAnchorLine = visibleLines.first(); + } + + workerLastIndex = 0; + workerTimer->start(); + + // switch to busy scene displaying the busy notification + setScene(busyScene); + updateBusyNotification(); + verticalScrollBar()->hide(); +} + void ChatLog::mouseDoubleClickEvent(QMouseEvent *ev) { QPointF scenePos = mapToScene(ev->pos()); @@ -580,6 +511,16 @@ void ChatLog::copySelectedText() const clipboard->setText(text); } +void ChatLog::setBusyNotification(ChatLine::Ptr notification) +{ + if(!notification.get()) + return; + + busyNotification = notification; + busyNotification->addToScene(busyScene); + busyNotification->visibilityChanged(true); +} + void ChatLog::setTypingNotification(ChatLine::Ptr notification) { typingNotification = notification; @@ -591,13 +532,22 @@ void ChatLog::setTypingNotification(ChatLine::Ptr notification) void ChatLog::setTypingNotificationVisible(bool visible) { - if(typingNotification.get() != nullptr) + if(typingNotification.get()) { typingNotification->setVisible(visible); updateTypingNotification(); } } +void ChatLog::scrollToLine(ChatLine::Ptr line) +{ + if(!line.get()) + return; + + updateSceneRect(); + verticalScrollBar()->setValue(line->boundingSceneRect().top()); +} + void ChatLog::checkVisibility() { if(lines.empty()) @@ -637,28 +587,13 @@ void ChatLog::checkVisibility() void ChatLog::scrollContentsBy(int dx, int dy) { QGraphicsView::scrollContentsBy(dx, dy); - updateVisibleLines(); + checkVisibility(); } void ChatLog::resizeEvent(QResizeEvent* ev) { - if(!workerTimer->isActive()) - { - workerStb = stickToBottom(); - workerLastIndex = 0; - workerDy = 0.0; - workerTimer->start(); - } - - bool stb = stickToBottom(); - + startResizeWorker(); QGraphicsView::resizeEvent(ev); - updateVisibleLines(); - updateMultiSelectionRect(); - updateTypingNotification(); - - if(stb) - scrollToBottom(); } void ChatLog::updateMultiSelectionRect() @@ -692,6 +627,15 @@ void ChatLog::updateTypingNotification() notification->layout(useableWidth(), QPointF(0.0, posY)); } +void ChatLog::updateBusyNotification() +{ + if(busyNotification.get()) + { + //repoisition the busy notification (centered) + busyNotification->layout(useableWidth(), getVisibleRect().topLeft() + QPointF(0, getVisibleRect().height()/2.0)); + } +} + ChatLine::Ptr ChatLog::findLineByPosY(qreal yPos) const { auto itr = std::lower_bound(lines.cbegin(), lines.cend(), yPos, ChatLine::lessThanBSRectBottom); @@ -728,3 +672,40 @@ void ChatLog::onSelectionTimerTimeout() break; } } + +void ChatLog::onWorkerTimeout() +{ + // Fairly arbitrary but + // large values will make the UI unresponsive + const int stepSize = 400; + + layout(workerLastIndex, workerLastIndex+stepSize, useableWidth()); + workerLastIndex += stepSize; + + // done? + if(workerLastIndex >= lines.size()) + { + workerTimer->stop(); + + // switch back to the scene containing the chat messages + setScene(scene); + + // make sure everything gets updated + updateSceneRect(); + checkVisibility(); + updateTypingNotification(); + updateMultiSelectionRect(); + + // scroll + if(workerStb) + scrollToBottom(); + else + scrollToLine(workerAnchorLine); + + // don't keep a Ptr to the anchor line + workerAnchorLine = ChatLine::Ptr(); + + // hidden during busy screen + verticalScrollBar()->show(); + } +} diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index ff7c67787..def258450 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -43,8 +43,10 @@ public: void clearSelection(); void clear(); void copySelectedText() const; + void setBusyNotification(ChatLine::Ptr notification); void setTypingNotification(ChatLine::Ptr notification); void setTypingNotificationVisible(bool visible); + void scrollToLine(ChatLine::Ptr line); QString getSelectedText() const; QString toPlainText() const; @@ -58,7 +60,7 @@ protected: QRect getVisibleRect() const; ChatLineContent* getContentFromPos(QPointF scenePos) const; - qreal layout(int start, int end, qreal width); + void layout(int start, int end, qreal width); bool isOverSelection(QPointF scenePos) const; bool stickToBottom() const; @@ -66,9 +68,9 @@ protected: void reposition(int start, int end, qreal deltaY); void updateSceneRect(); - void updateVisibleLines(); void checkVisibility(); void scrollToBottom(); + void startResizeWorker(); virtual void mouseDoubleClickEvent(QMouseEvent* ev); virtual void mousePressEvent(QMouseEvent* ev); @@ -79,11 +81,13 @@ protected: void updateMultiSelectionRect(); void updateTypingNotification(); + void updateBusyNotification(); ChatLine::Ptr findLineByPosY(qreal yPos) const; private slots: void onSelectionTimerTimeout(); + void onWorkerTimeout(); private: enum SelectionMode { @@ -99,9 +103,11 @@ private: }; QGraphicsScene* scene = nullptr; + QGraphicsScene* busyScene = nullptr; QVector lines; QList visibleLines; ChatLine::Ptr typingNotification; + ChatLine::Ptr busyNotification; // selection int selClickedRow = -1; //These 4 are only valid while selectionMode != None @@ -117,8 +123,8 @@ private: //worker vars int workerLastIndex = 0; - qreal workerDy = 0; bool workerStb = false; + ChatLine::Ptr workerAnchorLine; // actions QAction* copyAction = nullptr; diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 768b491d5..c9d97dedd 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -101,8 +101,19 @@ ChatMessage::Ptr ChatMessage::createTypingNotification() { ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); + // Note: "[user]..." is just a placeholder. The actual text is set in ChatForm::setFriendTyping() msg->addColumn(new NotificationIcon(QSizeF(18, 18)), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - msg->addColumn(new Text("%1 ...", Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Left)); + msg->addColumn(new Text("[user]...", Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Left)); + + return msg; +} + +ChatMessage::Ptr ChatMessage::createBusyNotification() +{ + ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); + + // TODO: Bigger font + msg->addColumn(new Text(QObject::tr("Busy..."), Style::getFont(Style::ExtraBig), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Center)); return msg; } diff --git a/src/chatlog/chatmessage.h b/src/chatlog/chatmessage.h index 2fba9e68b..0cab27107 100644 --- a/src/chatlog/chatmessage.h +++ b/src/chatlog/chatmessage.h @@ -41,6 +41,7 @@ public: static ChatMessage::Ptr createChatInfoMessage(const QString& rawMessage, SystemMessageType type, const QDateTime& date); static ChatMessage::Ptr createFileTransferMessage(const QString& sender, ToxFile file, bool isMe, const QDateTime& date); static ChatMessage::Ptr createTypingNotification(); + static ChatMessage::Ptr createBusyNotification(); void markAsSent(const QDateTime& time); QString toString() const; diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index 77fd6171a..d63b40eaa 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -56,6 +56,7 @@ GenericChatForm::GenericChatForm(QWidget *parent) headTextLayout = new QVBoxLayout(); chatWidget = new ChatLog(this); + chatWidget->setBusyNotification(ChatMessage::createBusyNotification()); msgEdit = new ChatTextEdit(); From 6719ebebaecc352a866326b7139a02de7bc000c2 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 25 Jan 2015 14:34:36 +0100 Subject: [PATCH 131/203] Added Timestamp class, moved output generation while saving to GenericChatForm and changed the generated layout --- qtox.pro | 6 ++++-- src/chatlog/chatlog.cpp | 17 +++++---------- src/chatlog/chatlog.h | 2 +- src/chatlog/chatmessage.cpp | 7 +++--- src/chatlog/content/timestamp.cpp | 28 ++++++++++++++++++++++++ src/chatlog/content/timestamp.h | 33 +++++++++++++++++++++++++++++ src/widget/form/genericchatform.cpp | 21 +++++++++++++++++- 7 files changed, 95 insertions(+), 19 deletions(-) create mode 100644 src/chatlog/content/timestamp.cpp create mode 100644 src/chatlog/content/timestamp.h diff --git a/qtox.pro b/qtox.pro index 21edabc2d..11eb6817f 100644 --- a/qtox.pro +++ b/qtox.pro @@ -192,7 +192,8 @@ HEADERS += src/widget/form/addfriendform.h \ src/chatlog/customtextdocument.h \ src/widget/form/settings/advancedform.h \ src/audio.h \ - src/chatlog/content/notificationicon.h + src/chatlog/content/notificationicon.h \ + src/chatlog/content/timestamp.h SOURCES += \ src/widget/form/addfriendform.cpp \ @@ -262,7 +263,8 @@ SOURCES += \ src/chatlog/customtextdocument.cpp\ src/widget/form/settings/advancedform.cpp \ src/audio.cpp \ - src/chatlog/content/notificationicon.cpp + src/chatlog/content/notificationicon.cpp \ + src/chatlog/content/timestamp.cpp contains(DEFINES, QTOX_FILTER_AUDIO) { HEADERS += src/audiofilterer.h diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index c95fec078..4e1e9a88b 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -463,18 +463,6 @@ QString ChatLog::getSelectedText() const return QString(); } -QString ChatLog::toPlainText() const -{ - QString out; - - for(ChatLine::Ptr l : lines) - { - out += QString("|%1 @%2|\n%3\n\n").arg(l->getContent(0)->getText(),l->getContent(2)->getText(),l->getContent(1)->getText()); - } - - return out; -} - bool ChatLog::isEmpty() const { return lines.isEmpty(); @@ -490,6 +478,11 @@ ChatLine::Ptr ChatLog::getTypingNotification() const return typingNotification; } +QVector ChatLog::getLines() +{ + return lines; +} + void ChatLog::clear() { clearSelection(); diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index def258450..890a67acd 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -48,12 +48,12 @@ public: void setTypingNotificationVisible(bool visible); void scrollToLine(ChatLine::Ptr line); QString getSelectedText() const; - QString toPlainText() const; bool isEmpty() const; bool hasTextToBeCopied() const; ChatLine::Ptr getTypingNotification() const; + QVector getLines(); protected: QRectF calculateSceneRect() const; diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index c9d97dedd..7696b5524 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -17,6 +17,7 @@ #include "chatmessage.h" #include "chatlinecontentproxy.h" #include "content/text.h" +#include "content/timestamp.h" #include "content/spinner.h" #include "content/filetransferwidget.h" #include "content/image.h" @@ -81,7 +82,7 @@ ChatMessage::Ptr ChatMessage::createChatInfoMessage(const QString &rawMessage, S msg->addColumn(new Image(QSizeF(18, 18), img), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text(rawMessage, Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Center)); - msg->addColumn(new Text(date.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + msg->addColumn(new Timestamp(date, Settings::getInstance().getTimestampFormat(), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); return msg; } @@ -92,7 +93,7 @@ ChatMessage::Ptr ChatMessage::createFileTransferMessage(const QString& sender, T msg->addColumn(new Text(sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), true), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new ChatLineContentProxy(new FileTransferWidget(0, file), 350, 0.6f), ColumnFormat(1.0, ColumnFormat::VariableSize)); - msg->addColumn(new Text(date.toString(Settings::getInstance().getTimestampFormat()), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + msg->addColumn(new Timestamp(date, Settings::getInstance().getTimestampFormat(), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); return msg; } @@ -121,7 +122,7 @@ ChatMessage::Ptr ChatMessage::createBusyNotification() void ChatMessage::markAsSent(const QDateTime &time) { // remove the spinner and replace it by $time - replaceContent(2, new Text(time.toString(Settings::getInstance().getTimestampFormat()))); + replaceContent(2, new Timestamp(time, Settings::getInstance().getTimestampFormat(), Style::getFont(Style::Big))); } QString ChatMessage::toString() const diff --git a/src/chatlog/content/timestamp.cpp b/src/chatlog/content/timestamp.cpp new file mode 100644 index 000000000..c662e9e66 --- /dev/null +++ b/src/chatlog/content/timestamp.cpp @@ -0,0 +1,28 @@ +/* + Copyright (C) 2015 by Project Tox + + 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 "timestamp.h" + +Timestamp::Timestamp(const QDateTime &time, const QString &format, const QFont &font) + : Text(time.toString(format), font, false, time.toString(format)) +{ + this->time = time; +} + +QDateTime Timestamp::getTime() +{ + return time; +} diff --git a/src/chatlog/content/timestamp.h b/src/chatlog/content/timestamp.h new file mode 100644 index 000000000..696f2d31e --- /dev/null +++ b/src/chatlog/content/timestamp.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2015 by Project Tox + + 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 TIMESTAMP_H +#define TIMESTAMP_H + +#include +#include "text.h" + +class Timestamp : public Text +{ +public: + Timestamp(const QDateTime& time, const QString& format, const QFont& font); + QDateTime getTime(); + +private: + QDateTime time; +}; + +#endif // TIMESTAMP_H diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index d63b40eaa..7cc2d86f0 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -16,8 +16,11 @@ #include "genericchatform.h" #include "ui_mainwindow.h" + #include #include +#include + #include "src/misc/smileypack.h" #include "src/widget/emoticonswidget.h" #include "src/misc/style.h" @@ -31,6 +34,7 @@ #include "src/friendlist.h" #include "src/friend.h" #include "src/chatlog/chatlog.h" +#include "src/chatlog/content/timestamp.h" GenericChatForm::GenericChatForm(QWidget *parent) : QWidget(parent) @@ -271,7 +275,22 @@ void GenericChatForm::onSaveLogClicked() if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return; - file.write(chatWidget->toPlainText().toUtf8()); + QString plainText; + auto lines = chatWidget->getLines(); + for(ChatLine::Ptr l : lines) + { + Timestamp* rightCol = dynamic_cast(l->getContent(2)); + ChatLineContent* middleCol = l->getContent(1); + ChatLineContent* leftCol = l->getContent(0); + + QString timestamp = (!rightCol || rightCol->getTime().isNull()) ? tr("Not sent") : rightCol->getText(); + QString nick = leftCol->getText(); + QString msg = middleCol->getText(); + + plainText += QString("[%2] %1\n%3\n\n").arg(nick, timestamp, msg); + } + + file.write(plainText.toUtf8()); file.close(); } From cae965e750e3fcf1ca769a953996f791dff4f7dc Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 25 Jan 2015 15:53:13 +0100 Subject: [PATCH 132/203] ChatMessage::createChatInfoMessage: use toHtmlChars --- src/chatlog/chatmessage.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 7696b5524..be7a5f8bc 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -71,6 +71,7 @@ ChatMessage::Ptr ChatMessage::createChatMessage(const QString &sender, const QSt ChatMessage::Ptr ChatMessage::createChatInfoMessage(const QString &rawMessage, SystemMessageType type, const QDateTime &date) { ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); + QString text = toHtmlChars(rawMessage); QString img; switch(type) @@ -81,7 +82,7 @@ ChatMessage::Ptr ChatMessage::createChatInfoMessage(const QString &rawMessage, S } msg->addColumn(new Image(QSizeF(18, 18), img), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - msg->addColumn(new Text(rawMessage, Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Center)); + msg->addColumn(new Text(text, Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Center)); msg->addColumn(new Timestamp(date, Settings::getInstance().getTimestampFormat(), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); return msg; From a418ae3df60a5bdf120d575bf5f1dc12ad20cfe5 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 25 Jan 2015 15:59:44 +0100 Subject: [PATCH 133/203] use html
instead of ColumnFormat::Center --- src/chatlog/chatmessage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index be7a5f8bc..977abcc55 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -82,7 +82,7 @@ ChatMessage::Ptr ChatMessage::createChatInfoMessage(const QString &rawMessage, S } msg->addColumn(new Image(QSizeF(18, 18), img), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - msg->addColumn(new Text(text, Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Center)); + msg->addColumn(new Text("
" + text + "
", Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Left)); msg->addColumn(new Timestamp(date, Settings::getInstance().getTimestampFormat(), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); return msg; From 5be6caca68250720f4dbb826a6324801be0c98c1 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 26 Jan 2015 11:09:21 +0100 Subject: [PATCH 134/203] [HiDPI] ChatLog: replaced all .png by .svg, FTW custom paintEvent This does not enable HiDPI support! issue #975 --- qtox.pro | 3 + res.qrc | 27 ++-- src/chatlog/chatmessage.cpp | 8 +- src/chatlog/content/filetransferwidget.cpp | 59 ++++--- src/chatlog/content/filetransferwidget.h | 4 + src/chatlog/content/filetransferwidget.ui | 28 +++- src/chatlog/content/image.cpp | 4 +- src/chatlog/content/image.h | 4 +- src/chatlog/content/notificationicon.cpp | 4 +- src/chatlog/content/notificationicon.h | 3 +- src/chatlog/content/spinner.cpp | 4 +- src/chatlog/content/spinner.h | 3 +- ui/chatArea/error.png | Bin 508 -> 0 bytes ui/chatArea/error.svg | 62 +++++++ ui/chatArea/info.png | Bin 521 -> 0 bytes ui/chatArea/info.svg | 62 +++++++ ui/chatArea/spinner.png | Bin 1044 -> 0 bytes ui/chatArea/spinner.svg | 45 ++++++ ui/chatArea/symbols.svg | 110 +++++++++---- ui/chatArea/typing.png | Bin 302 -> 0 bytes ui/chatArea/typing.svg | 61 +++++++ ui/fileTransferInstance/arrow_white.svg | 23 +++ ui/fileTransferInstance/arrow_white_2x.png | Bin 214 -> 0 bytes ui/fileTransferInstance/background_green.png | Bin 495 -> 0 bytes ui/fileTransferInstance/background_grey.png | Bin 487 -> 0 bytes ui/fileTransferInstance/background_red.png | Bin 493 -> 0 bytes ui/fileTransferInstance/background_yellow.png | Bin 495 -> 0 bytes ui/fileTransferInstance/browse.svg | 153 +++++++++++------- ui/fileTransferInstance/browse_path.png | Bin 462 -> 0 bytes .../{red.css => filetransferWidget.css} | 13 +- ui/fileTransferInstance/green.css | 28 ---- ui/fileTransferInstance/grey.css | 28 ---- ui/fileTransferInstance/no.svg | 23 +++ ui/fileTransferInstance/no_2x.png | Bin 265 -> 0 bytes ui/fileTransferInstance/pause.svg | 33 ++++ ui/fileTransferInstance/pause_2x.png | Bin 129 -> 0 bytes ui/fileTransferInstance/yellow.css | 28 ---- ui/fileTransferInstance/yes.svg | 22 +++ ui/fileTransferInstance/yes_2x.png | Bin 267 -> 0 bytes 39 files changed, 608 insertions(+), 234 deletions(-) delete mode 100644 ui/chatArea/error.png create mode 100644 ui/chatArea/error.svg delete mode 100644 ui/chatArea/info.png create mode 100644 ui/chatArea/info.svg delete mode 100644 ui/chatArea/spinner.png create mode 100644 ui/chatArea/spinner.svg delete mode 100644 ui/chatArea/typing.png create mode 100644 ui/chatArea/typing.svg create mode 100644 ui/fileTransferInstance/arrow_white.svg delete mode 100644 ui/fileTransferInstance/arrow_white_2x.png delete mode 100644 ui/fileTransferInstance/background_green.png delete mode 100644 ui/fileTransferInstance/background_grey.png delete mode 100644 ui/fileTransferInstance/background_red.png delete mode 100644 ui/fileTransferInstance/background_yellow.png delete mode 100644 ui/fileTransferInstance/browse_path.png rename ui/fileTransferInstance/{red.css => filetransferWidget.css} (50%) delete mode 100644 ui/fileTransferInstance/green.css delete mode 100644 ui/fileTransferInstance/grey.css create mode 100644 ui/fileTransferInstance/no.svg delete mode 100644 ui/fileTransferInstance/no_2x.png create mode 100644 ui/fileTransferInstance/pause.svg delete mode 100644 ui/fileTransferInstance/pause_2x.png delete mode 100644 ui/fileTransferInstance/yellow.css create mode 100644 ui/fileTransferInstance/yes.svg delete mode 100644 ui/fileTransferInstance/yes_2x.png diff --git a/qtox.pro b/qtox.pro index 11eb6817f..b0187ff85 100644 --- a/qtox.pro +++ b/qtox.pro @@ -278,3 +278,6 @@ contains(DEFINES, QTOX_PLATFORM_EXT) { src/platform/timer_x11.cpp } +DISTFILES += \ + ui/fileTransferInstance/background_green.svg + diff --git a/res.qrc b/res.qrc index eff10c320..de2986aa8 100644 --- a/res.qrc +++ b/res.qrc @@ -149,9 +149,6 @@ ui/chatArea/chatArea.css ui/chatArea/chatHead.css ui/chatArea/innerStyle.css - ui/chatArea/spinner.png - ui/chatArea/info.png - ui/chatArea/error.png ui/chatArea/scrollBarDownArrow.png ui/chatArea/scrollBarDownArrowHover.png ui/chatArea/scrollBarDownArrowPressed.png @@ -212,19 +209,6 @@ ui/videoButton/videoButtonYellow.png ui/videoButton/videoButtonYellowHover.png ui/videoButton/videoButtonYellowPressed.png - ui/fileTransferInstance/red.css - ui/fileTransferInstance/green.css - ui/fileTransferInstance/grey.css - ui/fileTransferInstance/yellow.css - ui/fileTransferInstance/background_red.png - ui/fileTransferInstance/background_yellow.png - ui/fileTransferInstance/background_green.png - ui/fileTransferInstance/background_grey.png - ui/fileTransferInstance/pause_2x.png - ui/fileTransferInstance/no_2x.png - ui/fileTransferInstance/yes_2x.png - ui/fileTransferInstance/arrow_white_2x.png - ui/fileTransferInstance/browse_path.png ui/volButton/volButton.png ui/volButton/volButtonHover.png ui/volButton/volButtonPressed.png @@ -232,6 +216,15 @@ ui/window/applicationIcon.png ui/window/statusPanel.css ui/window/window.css - ui/chatArea/typing.png + ui/chatArea/info.svg + ui/chatArea/spinner.svg + ui/chatArea/typing.svg + ui/chatArea/error.svg + ui/fileTransferInstance/no.svg + ui/fileTransferInstance/pause.svg + ui/fileTransferInstance/yes.svg + ui/fileTransferInstance/arrow_white.svg + ui/fileTransferInstance/browse.svg + ui/fileTransferInstance/filetransferWidget.css diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 977abcc55..175157d90 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -60,7 +60,7 @@ ChatMessage::Ptr ChatMessage::createChatMessage(const QString &sender, const QSt msg->addColumn(new Text(isAction ? "
*
" : sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), isAction ? false : true, sender), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text(text, Style::getFont(Style::Big), false, isAction ? QString("*%1 %2*").arg(sender, rawMessage) : rawMessage), ColumnFormat(1.0, ColumnFormat::VariableSize)); - msg->addColumn(new Spinner(":/ui/chatArea/spinner.png", QSizeF(16, 16), 8.0), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + msg->addColumn(new Spinner(":/ui/chatArea/spinner.svg", QSizeF(16, 16), 8.0), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); if(!date.isNull()) msg->markAsSent(date); @@ -76,9 +76,9 @@ ChatMessage::Ptr ChatMessage::createChatInfoMessage(const QString &rawMessage, S QString img; switch(type) { - case INFO: img = ":/ui/chatArea/info.png"; break; - case ERROR: img = ":/ui/chatArea/error.png"; break; - case TYPING: img = ":/ui/chatArea/typing.png"; break; + case INFO: img = ":/ui/chatArea/info.svg"; break; + case ERROR: img = ":/ui/chatArea/error.svg"; break; + case TYPING: img = ":/ui/chatArea/typing.svg"; break; } msg->addColumn(new Image(QSizeF(18, 18), img), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index f52b18a26..4fc8b3c89 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) @@ -45,8 +46,7 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) ui->progressLabel->setText("0kiB/s"); ui->etaLabel->setText(""); - setStyleSheet(Style::getStylesheet(":/ui/fileTransferInstance/grey.css")); - Style::repolish(this); + setColor(Style::getColor(Style::LightGrey), false); connect(Core::getInstance(), &Core::fileTransferInfo, this, &FileTransferWidget::onFileTransferInfo); connect(Core::getInstance(), &Core::fileTransferAccepted, this, &FileTransferWidget::onFileTransferAccepted); @@ -60,7 +60,7 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) if(fileInfo.direction == ToxFile::SENDING) showPreview(fileInfo.filePath); - setFixedHeight(90); + setFixedHeight(80); } FileTransferWidget::~FileTransferWidget() @@ -106,6 +106,17 @@ void FileTransferWidget::acceptTransfer(const QString &filepath) Core::getInstance()->acceptFileRecvRequest(fileInfo.friendId, fileInfo.fileNum, filepath); } +void FileTransferWidget::setColor(const QColor &c, bool whiteFont) +{ + color = c; + setProperty("fontColor", whiteFont ? "white" : "black"); + + setStyleSheet(Style::getStylesheet(":/ui/fileTransferInstance/filetransferWidget.css")); + Style::repolish(this); + + update(); +} + bool FileTransferWidget::isFilePathWritable(const QString &filepath) { QFile tmp(filepath); @@ -114,6 +125,20 @@ bool FileTransferWidget::isFilePathWritable(const QString &filepath) return writable; } +void FileTransferWidget::paintEvent(QPaintEvent *) +{ + // required by Hi-DPI support as border-image doesn't work. + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + painter.setBrush(QBrush(color)); + painter.setPen(Qt::NoPen); + + qreal s = static_cast(geometry().height()) / static_cast(geometry().width()); + int r = 15; + + painter.drawRoundRect(geometry(), r * s, r); +} + void FileTransferWidget::onFileTransferInfo(ToxFile file) { QTime now = QTime::currentTime(); @@ -176,8 +201,7 @@ void FileTransferWidget::onFileTransferAccepted(ToxFile file) fileInfo = file; - setStyleSheet(Style::getStylesheet(":/ui/fileTransferInstance/yellow.css")); - Style::repolish(this); + setColor(Style::getColor(Style::Yellow), false); setupButtons(); } @@ -189,8 +213,7 @@ void FileTransferWidget::onFileTransferCancelled(ToxFile file) fileInfo = file; - setStyleSheet(Style::getStylesheet(":/ui/fileTransferInstance/red.css")); - Style::repolish(this); + setColor(Style::getColor(Style::Red), true); setupButtons(); hideWidgets(); @@ -213,8 +236,7 @@ void FileTransferWidget::onFileTransferPaused(ToxFile file) for(size_t i=0; ibottomButton->setIcon(QIcon(":/ui/fileTransferInstance/browse_path.png")); + ui->bottomButton->setIcon(QIcon(":/ui/fileTransferInstance/browse.svg")); ui->bottomButton->setObjectName("browse"); ui->bottomButton->show(); } @@ -273,32 +294,32 @@ void FileTransferWidget::setupButtons() switch(fileInfo.status) { case ToxFile::TRANSMITTING: - ui->topButton->setIcon(QIcon(":/ui/fileTransferInstance/no_2x.png")); + ui->topButton->setIcon(QIcon(":/ui/fileTransferInstance/no.svg")); ui->topButton->setObjectName("cancel"); - ui->bottomButton->setIcon(QIcon(":/ui/fileTransferInstance/pause_2x.png")); + ui->bottomButton->setIcon(QIcon(":/ui/fileTransferInstance/pause.svg")); ui->bottomButton->setObjectName("pause"); break; case ToxFile::PAUSED: - ui->topButton->setIcon(QIcon(":/ui/fileTransferInstance/no_2x.png")); + ui->topButton->setIcon(QIcon(":/ui/fileTransferInstance/no.svg")); ui->topButton->setObjectName("cancel"); - ui->bottomButton->setIcon(QIcon(":/ui/fileTransferInstance/arrow_white_2x.png")); + ui->bottomButton->setIcon(QIcon(":/ui/fileTransferInstance/arrow_white.svg")); ui->bottomButton->setObjectName("resume"); break; case ToxFile::STOPPED: case ToxFile::BROKEN: //TODO: ? - ui->topButton->setIcon(QIcon(":/ui/fileTransferInstance/no_2x.png")); + ui->topButton->setIcon(QIcon(":/ui/fileTransferInstance/no.svg")); ui->topButton->setObjectName("cancel"); if(fileInfo.direction == ToxFile::SENDING) { - ui->bottomButton->setIcon(QIcon(":/ui/fileTransferInstance/pause_2x.png")); + ui->bottomButton->setIcon(QIcon(":/ui/fileTransferInstance/pause.svg")); ui->bottomButton->setObjectName("pause"); } else { - ui->bottomButton->setIcon(QIcon(":/ui/fileTransferInstance/yes_2x.png")); + ui->bottomButton->setIcon(QIcon(":/ui/fileTransferInstance/yes.svg")); ui->bottomButton->setObjectName("accept"); } break; diff --git a/src/chatlog/content/filetransferwidget.h b/src/chatlog/content/filetransferwidget.h index 2777de809..3f00f281f 100644 --- a/src/chatlog/content/filetransferwidget.h +++ b/src/chatlog/content/filetransferwidget.h @@ -52,9 +52,12 @@ protected: void handleButton(QPushButton* btn); void showPreview(const QString& filename); void acceptTransfer(const QString& filepath); + void setColor(const QColor& c, bool whiteFont); bool isFilePathWritable(const QString& filepath); + virtual void paintEvent(QPaintEvent*); + private slots: void on_topButton_clicked(); void on_bottomButton_clicked(); @@ -64,6 +67,7 @@ private: ToxFile fileInfo; QTime lastTick; qint64 lastBytesSent = 0; + QColor color; static const uint8_t TRANSFER_ROLLING_AVG_COUNT = 4; uint8_t meanIndex = 0; diff --git a/src/chatlog/content/filetransferwidget.ui b/src/chatlog/content/filetransferwidget.ui index 868adf74e..eb4163cd8 100644 --- a/src/chatlog/content/filetransferwidget.ui +++ b/src/chatlog/content/filetransferwidget.ui @@ -14,6 +14,21 @@ Form + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + @@ -35,11 +50,20 @@ 0 - + 6 + + 5 + + + 5 + - 6 + 2 + + + 5 diff --git a/src/chatlog/content/image.cpp b/src/chatlog/content/image.cpp index bbea866a7..fb2a44d49 100644 --- a/src/chatlog/content/image.cpp +++ b/src/chatlog/content/image.cpp @@ -21,7 +21,7 @@ Image::Image(QSizeF Size, const QString& filename) : size(Size) { - pmap.load(filename); + icon.addFile(filename); } QRectF Image::boundingRect() const @@ -43,7 +43,7 @@ void Image::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWi { painter->setRenderHint(QPainter::SmoothPixmapTransform); painter->translate(-size.width() / 2.0, -size.height() / 2.0); - painter->drawPixmap(0, 0, size.width(), size.height(), pmap); + painter->drawPixmap(0, 0, size.width(), size.height(), icon.pixmap(size.toSize())); Q_UNUSED(option) Q_UNUSED(widget) diff --git a/src/chatlog/content/image.h b/src/chatlog/content/image.h index 020c00b29..6afe486bc 100644 --- a/src/chatlog/content/image.h +++ b/src/chatlog/content/image.h @@ -19,6 +19,8 @@ #include "../chatlinecontent.h" +#include + class Image : public ChatLineContent { public: @@ -32,7 +34,7 @@ public: private: QSizeF size; - QPixmap pmap; + QIcon icon; }; diff --git a/src/chatlog/content/notificationicon.cpp b/src/chatlog/content/notificationicon.cpp index b57caacde..5ca23099a 100644 --- a/src/chatlog/content/notificationicon.cpp +++ b/src/chatlog/content/notificationicon.cpp @@ -22,7 +22,7 @@ NotificationIcon::NotificationIcon(QSizeF Size) : size(Size) { - pmap.load(":/ui/chatArea/typing.png"); + icon.addFile(":/ui/chatArea/typing.svg"); updateTimer = new QTimer(this); updateTimer->setInterval(1000/60); @@ -44,7 +44,7 @@ void NotificationIcon::paint(QPainter *painter, const QStyleOptionGraphicsItem * painter->translate(-size.width() / 2.0, -size.height() / 2.0); painter->fillRect(QRect(0, 0, size.width(), size.height()), grad); - painter->drawPixmap(0, 0, size.width(), size.height(), pmap); + painter->drawPixmap(0, 0, size.width(), size.height(), icon.pixmap(size.toSize() * painter->device()->devicePixelRatio())); Q_UNUSED(option) Q_UNUSED(widget) diff --git a/src/chatlog/content/notificationicon.h b/src/chatlog/content/notificationicon.h index a68b87c5c..79ff083bd 100644 --- a/src/chatlog/content/notificationicon.h +++ b/src/chatlog/content/notificationicon.h @@ -20,6 +20,7 @@ #include "../chatlinecontent.h" #include +#include class QTimer; @@ -40,7 +41,7 @@ private slots: private: QSizeF size; - QPixmap pmap; + QIcon icon; QLinearGradient grad; QTimer* updateTimer = nullptr; diff --git a/src/chatlog/content/spinner.cpp b/src/chatlog/content/spinner.cpp index 7d912fdfb..e32bcf02c 100644 --- a/src/chatlog/content/spinner.cpp +++ b/src/chatlog/content/spinner.cpp @@ -23,7 +23,7 @@ Spinner::Spinner(const QString &img, QSizeF Size, qreal speed) : size(Size) , rotSpeed(speed) { - pmap.load(img); + icon.addFile(img); timer.setInterval(33); // 30Hz timer.setSingleShot(false); @@ -52,7 +52,7 @@ void Spinner::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, Q painter->translate(-size.width() / 2.0, -size.height() / 2.0); painter->setTransform(rotMat, true); painter->setRenderHint(QPainter::SmoothPixmapTransform); - painter->drawPixmap(0, 0, size.width(), size.height(), pmap); + painter->drawPixmap(0, 0, size.width(), size.height(), icon.pixmap(size.toSize() * painter->device()->devicePixelRatio())); Q_UNUSED(option) Q_UNUSED(widget) diff --git a/src/chatlog/content/spinner.h b/src/chatlog/content/spinner.h index 894a10761..e51401eb7 100644 --- a/src/chatlog/content/spinner.h +++ b/src/chatlog/content/spinner.h @@ -21,6 +21,7 @@ #include #include +#include class Spinner : public QObject, public ChatLineContent { @@ -40,7 +41,7 @@ private slots: private: QSizeF size; - QPixmap pmap; + QIcon icon; qreal rot = 0.0; qreal rotSpeed; QTimer timer; diff --git a/ui/chatArea/error.png b/ui/chatArea/error.png deleted file mode 100644 index e7ee3deeab5280785d48e8bb288ebc120f59fae0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 508 zcmVlJ`WWZ=40M9RM_ yb419dQe;!9FvLfsJaFCWg!%8^NLYXU*uDTLVW#*W$5?Ct0000 + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/ui/chatArea/info.png b/ui/chatArea/info.png deleted file mode 100644 index 07755967a3b5630592874e1458955a46883c5e67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 521 zcmV+k0`~ohP)zdP#1i}grfPfls32%Tz!H+}vh*DrXTD&&}yFiwqNS0I1J@?GHGjm2% z6&pSs&yOG`qc9F2P)38wMz&P9@g*+w@$AD}>97loS$BY%I^?&ewyRd5+;V+-9EIb2jXP=m zXmjxS6o7Z@(|7|tkDRH)KHUaR4Jd7hY8ls(1gP4r93bcRz=CE+iVd0$iRr@I#h{>4fog{(6xJfD!!3dO- ziU^bq8dMV7(V$|&?9>v-)HbrEx&cs!JmCL_h#&UeXKmr+{c=1afgf=7?H2$qU-e?# z_}%Er=FCnJ9%QX?(OkRD&V6W&Yv_O7XLS;VHd=W8ZzPU?{n-8hVRxIavd$lz00000 LNkvXXu0mjf0JYtC diff --git a/ui/chatArea/info.svg b/ui/chatArea/info.svg new file mode 100644 index 000000000..c6eb5b0e4 --- /dev/null +++ b/ui/chatArea/info.svg @@ -0,0 +1,62 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/ui/chatArea/spinner.png b/ui/chatArea/spinner.png deleted file mode 100644 index 22a1d8b2ee9eb49dbb9b1701ea73deabe642ab3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1044 zcmV+v1nc{WP)Gc$|L)Rbo4Kq{5Gtz0foh{!X*wkGNZBJ!4qWU|@pFKq*4GMU)o;^Hyj z72xJ3jO+EUs!o>6<>Rxnvr8=jjE;_OFPF<70Q=i8uGeqY+J4{nzi$d4l}g=FsZ>4# z?%4$Ms;+i)bnKg&n)<0Bfa|(90bc+QHYj#YM9!+}8Q?5%tE%>i$S$C-!MO!%?LOc4 zFE#=w0EZ(A6jk-5rKP3!3WdV8umsn2p9IE%MsQrJA`YGc zju>MuMa0+1^SooK`g%n8HDgR>9e{|4>$>x*x+~mV1o6V*JSZhOPx2it0RREzgJEAXaK0vWpTwtX;)dTFg z(Ew|$*z>$uRXtJ{4^;J$d_F(lu0cAT?pj`6J}Dx%*Y2z8l|&-3x3&|W2sz&&B6I0< zx~pA)QmOQ+i0lRKs$C*-Vq#*VvIfxG+xsDKKBUHdrBW$ssx_47dHt-6=6V%@H=%AE zyRLf}D1;Rgk-5&!&KD;qCyULPCzHwNL}Uht*T+=#jeI^oz5!qr;#1(Uh`N_VWH6V@ zos2Rb85!AWtvw1n8PF~K>FQH_4&2fJqE-EEt$o7x{V!`bov_SoHhT`(!^%x(GqemG zsyB}W05HZ}s8lKs18)PiO=AV#2X-1`PK6~jbv5%m?*Uak4jd%<`>uCZ{a8fCjWORe z%4-Uss-dBw-grEIsP1yQ4fvIs%c + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/ui/chatArea/symbols.svg b/ui/chatArea/symbols.svg index 2d56a1657..68ef8e4b6 100644 --- a/ui/chatArea/symbols.svg +++ b/ui/chatArea/symbols.svg @@ -7,10 +7,34 @@ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.2" width="744.09448" height="1052.3622" - id="svg2"> + id="svg2" + inkscape:version="0.48.5 r10040" + sodipodi:docname="symbols.svg"> + ! + id="info" + inkscape:export-xdpi="11.328032" + inkscape:export-ydpi="11.328032"> - i + + + + + @@ -97,25 +133,37 @@ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Aller;-inkscape-font-specification:Aller">i + id="error" + inkscape:export-xdpi="5.6643357" + inkscape:export-ydpi="5.6643357"> - i + + + + + gcyqV(DCY@~pSR(rZQ zhFJ8zy<(r`;e` zaN*D~d7d{l<=?j(2j{RBF1Fe(W#c2KR&ILJ{m9CM+e+esyZ1j?BODiy*rPA=q2~b0 z{U1j(ZtA?x^trY(?~&~4CS61Q8|)@;zjRM(|G!~*&o;KVWeJT^!8rv-q^l~<)=d6g sI!`_Q!ax5yrA5(u$|g=#3x6qoQ|w6AD?Wh_KxZ>}y85}Sb4q9e06xfV%>V!Z diff --git a/ui/chatArea/typing.svg b/ui/chatArea/typing.svg new file mode 100644 index 000000000..35c3e1d5b --- /dev/null +++ b/ui/chatArea/typing.svg @@ -0,0 +1,61 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/ui/fileTransferInstance/arrow_white.svg b/ui/fileTransferInstance/arrow_white.svg new file mode 100644 index 000000000..ee2e9fdcd --- /dev/null +++ b/ui/fileTransferInstance/arrow_white.svg @@ -0,0 +1,23 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/ui/fileTransferInstance/arrow_white_2x.png b/ui/fileTransferInstance/arrow_white_2x.png deleted file mode 100644 index 646dd5ad8f0eb32b03b0bec218dce78ccb119712..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 214 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CH!3HFy_x^nYq*#ibJVQ8upoSx*1IXtr@Q5r1 zsyPC}j8nDwq=AAJo-U3d8WX2p3gkWHAmDnDoohk^i;4oHriTNQ(1eB-FHOFJf*%>% za-=fK^FRH2ruJD)SeRdC!rCL#>%X5|1o(*Wj`E#?e}RcfD)Et8&+}31xA=`yQ%P zZd+#}pWrP~c&%XR&L>9uTdta~Y-Llp#TxLhx5%tV>z@BxLtNt=*sXF)LF_T-k2zORO~cYgooUkP zbSux?Z~m{*#?-?q!EGRxpmQLiVIxB_tAqNq+hxWy*b_qPu_~szqm}~02vOiTYm0vXE9NmA2DWo~s;J`5pB-vFc*);~9w(_a@h<|BT5v;C@a0 z=GCbB`|J35N^f6zy4rfK-)t3oZ@1Di?$m34 zKYiYlgI~8^JN(7;&e4SJUovZN`7#TyPxUBz9@S>g&SLcH>Fic(V5Bg3y85}Sb4q9e E0HL0>9RL6T diff --git a/ui/fileTransferInstance/background_red.png b/ui/fileTransferInstance/background_red.png deleted file mode 100644 index 0ac0429541c61f35fd217b8ec096f15925562cf6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 493 zcmeAS@N?(olHy`uVBq!ia0vp^-as6}!3HExojbJzNU;<xPHLSr@;v!@r;4SzrRvLTwe=G5I&Fz3HfF|6u2HL; zpLwAAn%d3vzyCdd`s+Zz_TE@KvHQ2*s-3((=dw-5_DNN4nYY$0k$X04o7T#BTi@tu zHqYN5tQT=+JjT?+D#2|amY{PWqG2OL@<0m&1c~cs-&(pPZ^gAO#h$TG*JduCv}AU5 z7yHGjuZw<^z4Lq*v-{oe!#_;#98cK3Wo7LvUuNa?sUDw>Z{^wlPRRJ@w$o(=z^GyH MboFyt=akR{07r_y#sB~S diff --git a/ui/fileTransferInstance/background_yellow.png b/ui/fileTransferInstance/background_yellow.png deleted file mode 100644 index 1ba362293bd38ab3f3d16d1175c498ded3a6e936..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 495 zcmeAS@N?(olHy`uVBq!ia0vp^-as6}!3HExojbJzNU;<lp#TxLhx5%tV>#wYiU|a^=`r2TnieE~TIrO+DW(~ZB0W@BR=8X`vyzkN z`Q*->#Yeoa)J|Ua`jYiK@zW}+RX(d+R#EMLKIh4lClgYPv&(M(JG$icE}8G$&sF3- z@3~2Rn6}mP+UB(HpGzteR=obD_kQyG_0v-)oi|**Q+U1V*PcroLOpHInC8RCAV8If-xN94VJ?{prO + width="12" + height="12" + id="svg2"> - + id="defs4"> + + + + + + + + + + + + + + + + @@ -48,39 +87,33 @@ - - - + transform="translate(0,-2092.7244)" + id="layer1"> + + + + + + + + diff --git a/ui/fileTransferInstance/browse_path.png b/ui/fileTransferInstance/browse_path.png deleted file mode 100644 index 5fe4251a61cced23c94f46cc7f40e85a5be13585..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 462 zcmV;<0WtoGP)X1^@s6FWx?200004b3#c}2nYxW zd^!M!40?wSrUy- zq9W0`0val%WPLR{63IqMVmp;k$fGc_^3NP|#!SSoI`e+~p7YK*IZ#vTZ*^PkuG^an z=u$WQuO0PA+mPPExKjseUt5r$>R}1wO@GvZDxb&zO#)-Z=LoP;toMPvVtpAA=bsrQ z1)X{~$!eY6t_Iv%y-h%szr8I`t==AW85rz{uSdjfN&OA*b~Z<4hUyTo*b)9m;>u1W zOhO$|r&Cv2ohUQR9$%dS{sPy)DR8fDsr|VIl@qDs>SLmIx6O&xfZjxIzL@qy<$``S z%x8nltZNK9smLF<1zG~061km-IBNwI5m&$*aP= + + +image/svg+xml \ No newline at end of file diff --git a/ui/fileTransferInstance/no_2x.png b/ui/fileTransferInstance/no_2x.png deleted file mode 100644 index 86c05eb5a378e1a9c6f906843e7fd7434076db6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 265 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE;=WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8)t)YnAr-ggT)oKKYQVu7@Q9`Fk%w&WM45wvB~7P{6QqKk zeDZkbKXtOnQm?(`mrPD--fY{dvpQw^hPAyjM7yNYjFVdQ&MBb@0D!(`cmMzZ diff --git a/ui/fileTransferInstance/pause.svg b/ui/fileTransferInstance/pause.svg new file mode 100644 index 000000000..b02c4dd53 --- /dev/null +++ b/ui/fileTransferInstance/pause.svg @@ -0,0 +1,33 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/ui/fileTransferInstance/pause_2x.png b/ui/fileTransferInstance/pause_2x.png deleted file mode 100644 index 6ee39a91e3cd34fe44f599dd3f7791f6aa733426..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRp!3HFQtmCqPlw^r(L`iUdT1k0gQ7VIDN`6wR zf@f}GdTLN=VoGJ<$y6JlB4tk($B>F!Nq_iRcxE(AWHfgOJa3V8U + + +image/svg+xml \ No newline at end of file diff --git a/ui/fileTransferInstance/yes_2x.png b/ui/fileTransferInstance/yes_2x.png deleted file mode 100644 index a4de224446c623e7d85d4f2b6eba5a98c90edb97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 267 zcmeAS@N?(olHy`uVBq!ia0vp^Qa~)i!3HEJJLv8MQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jiq?9%IEGZ*+H&P0Z?gdp%Y{vh${QSS_vV?nz2NAX5P0K2 zsfrJC)*X>}oxA*u_JSSkf;%T>U(uPh Date: Mon, 26 Jan 2015 14:06:05 +0100 Subject: [PATCH 135/203] cleanup previous commit --- qtox.pro | 4 ---- 1 file changed, 4 deletions(-) diff --git a/qtox.pro b/qtox.pro index b0187ff85..73c7720f0 100644 --- a/qtox.pro +++ b/qtox.pro @@ -277,7 +277,3 @@ contains(DEFINES, QTOX_PLATFORM_EXT) { src/platform/timer_win.cpp \ src/platform/timer_x11.cpp } - -DISTFILES += \ - ui/fileTransferInstance/background_green.svg - From bbd20496fd30b6b7b3e86cc7872d0d9c3ffdda66 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 26 Jan 2015 17:12:22 +0100 Subject: [PATCH 136/203] specify background brush --- src/chatlog/chatlog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 4e1e9a88b..dae98356b 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -53,6 +53,7 @@ ChatLog::ChatLog(QWidget* parent) setViewportUpdateMode(BoundingRectViewportUpdate); setAcceptDrops(false); setContextMenuPolicy(Qt::CustomContextMenu); + setBackgroundBrush(QBrush(Qt::white, Qt::SolidPattern)); // The selection rect for multi-line selection const QColor selGraphColor = QColor(166,225,255); From 0442db2baefa2ebc78853e7f8eba3c41c075e779 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 26 Jan 2015 19:01:18 +0100 Subject: [PATCH 137/203] reposition busy notification *after* resize --- src/chatlog/chatlog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index dae98356b..0c11a0af7 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -408,7 +408,6 @@ void ChatLog::startResizeWorker() // switch to busy scene displaying the busy notification setScene(busyScene); - updateBusyNotification(); verticalScrollBar()->hide(); } @@ -588,6 +587,8 @@ void ChatLog::resizeEvent(QResizeEvent* ev) { startResizeWorker(); QGraphicsView::resizeEvent(ev); + + updateBusyNotification(); } void ChatLog::updateMultiSelectionRect() From ecf15a6ca32b95d5d7cdf2c85e0ed401735727c3 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 26 Jan 2015 19:15:29 +0100 Subject: [PATCH 138/203] fix regression: chatlog didn't scroll to bottom on startup --- src/chatlog/chatlog.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 0c11a0af7..f3b595c3b 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -393,6 +393,9 @@ void ChatLog::scrollToBottom() void ChatLog::startResizeWorker() { + if(lines.empty()) + return; + // (re)start the worker if(!workerTimer->isActive()) { From a5587335071cb2828f8b98ea7b17d4aeaf29ff15 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 26 Jan 2015 19:32:33 +0100 Subject: [PATCH 139/203] ChatLog::selectAll, refactoring of actions (issue #808) --- src/chatlog/chatlog.cpp | 31 ++++++++++++++++++++++++----- src/chatlog/chatlog.h | 5 ++--- src/widget/form/genericchatform.cpp | 7 ++++++- src/widget/form/genericchatform.h | 1 + 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index f3b595c3b..5a7e80d7a 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -61,13 +61,20 @@ ChatLog::ChatLog(QWidget* parent) selGraphItem->setZValue(-10.0); //behind all items // copy action (ie. Ctrl+C) - copyAction = new QAction(this); + QAction* copyAction = new QAction(this); + copyAction->setIcon(QIcon::fromTheme("edit-copy")); + copyAction->setText(tr("Copy")); copyAction->setShortcut(QKeySequence::Copy); + connect(copyAction, &QAction::triggered, this, [this](bool) { copySelectedText(); }); addAction(copyAction); - connect(copyAction, &QAction::triggered, this, [this](bool) - { - copySelectedText(); - }); + + // select all action (ie. Ctrl+A) + QAction* selectAllAction = new QAction(this); + selectAllAction->setIcon(QIcon::fromTheme("edit-select-all")); + selectAllAction->setText(tr("Select all")); + selectAllAction->setShortcut(QKeySequence::SelectAll); + connect(selectAllAction, &QAction::triggered, this, [this](bool) { selectAll(); }); + addAction(selectAllAction); // This timer is used to scroll the view while the user is // moving the mouse past the top/bottom edge of the widget while selecting. @@ -544,6 +551,20 @@ void ChatLog::scrollToLine(ChatLine::Ptr line) verticalScrollBar()->setValue(line->boundingSceneRect().top()); } +void ChatLog::selectAll() +{ + if(lines.empty()) + return; + + clearSelection(); + + selectionMode = Multi; + selFirstRow = 0; + selLastRow = lines.size()-1; + + updateMultiSelectionRect(); +} + void ChatLog::checkVisibility() { if(lines.empty()) diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 890a67acd..4461d2b3c 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -47,6 +47,8 @@ public: void setTypingNotification(ChatLine::Ptr notification); void setTypingNotificationVisible(bool visible); void scrollToLine(ChatLine::Ptr line); + void selectAll(); + QString getSelectedText() const; bool isEmpty() const; @@ -126,9 +128,6 @@ private: bool workerStb = false; ChatLine::Ptr workerAnchorLine; - // actions - QAction* copyAction = nullptr; - // layout QMarginsF margins = QMarginsF(10.0,10.0,10.0,10.0); qreal lineSpacing = 5.0f; diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index 7cc2d86f0..5511df2e9 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -146,7 +146,7 @@ GenericChatForm::GenericChatForm(QWidget *parent) fileButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); emoteButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); - menu.addAction(QIcon::fromTheme("edit-copy"), tr("Copy"), this, SLOT(onCopyLogClicked())); + menu.addActions(chatWidget->actions()); menu.addSeparator(); menu.addAction(QIcon::fromTheme("document-save"), tr("Save chat log"), this, SLOT(onSaveLogClicked())); menu.addAction(QIcon::fromTheme("edit-clear"), tr("Clear displayed messages"), this, SLOT(clearChatArea(bool))); @@ -323,6 +323,11 @@ void GenericChatForm::clearChatArea(bool notinform) emit chatAreaCleared(); } +void GenericChatForm::onSelectAllClicked() +{ + chatWidget->selectAll(); +} + QString GenericChatForm::resolveToxID(const ToxID &id) { Friend *f = FriendList::findFriend(id); diff --git a/src/widget/form/genericchatform.h b/src/widget/form/genericchatform.h index b741ab6b0..73463af76 100644 --- a/src/widget/form/genericchatform.h +++ b/src/widget/form/genericchatform.h @@ -73,6 +73,7 @@ protected slots: void onSaveLogClicked(); void onCopyLogClicked(); void clearChatArea(bool); + void onSelectAllClicked(); protected: QString resolveToxID(const ToxID &id); From f509e07c45dfdea6b8509441b0589f3b8afcc6a1 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 26 Jan 2015 23:19:18 +0100 Subject: [PATCH 140/203] make use of EmojiFontPointSize (fix #1026) --- src/chatlog/customtextdocument.cpp | 6 +++++- src/misc/smileypack.cpp | 25 +++++++++--------------- src/misc/smileypack.h | 8 ++++---- src/widget/emoticonswidget.cpp | 2 +- src/widget/form/settings/generalform.cpp | 11 ++++++----- 5 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/chatlog/customtextdocument.cpp b/src/chatlog/customtextdocument.cpp index c1dd1b96c..b4a4507ad 100644 --- a/src/chatlog/customtextdocument.cpp +++ b/src/chatlog/customtextdocument.cpp @@ -15,6 +15,7 @@ */ #include "customtextdocument.h" +#include "../misc/settings.h" #include "../misc/smileypack.h" #include "../misc/style.h" @@ -34,7 +35,10 @@ CustomTextDocument::CustomTextDocument(QObject *parent) QVariant CustomTextDocument::loadResource(int type, const QUrl &name) { if (type == QTextDocument::ImageResource && name.scheme() == "key") - return SmileyPack::getInstance().getAsPixmap(name.fileName()); + { + QSize size = QSize(Settings::getInstance().getEmojiFontPointSize(),Settings::getInstance().getEmojiFontPointSize()); + return SmileyPack::getInstance().getAsIcon(name.fileName()).pixmap(size); + } return QTextDocument::loadResource(type, name); } diff --git a/src/misc/smileypack.cpp b/src/misc/smileypack.cpp index ac8e1115b..258b3ae9c 100644 --- a/src/misc/smileypack.cpp +++ b/src/misc/smileypack.cpp @@ -91,7 +91,7 @@ bool SmileyPack::load(const QString& filename) { // discard old data filenameTable.clear(); - pixmapCache.clear(); + iconCache.clear(); emoticons.clear(); path.clear(); @@ -135,7 +135,7 @@ bool SmileyPack::load(const QString& filename) cacheSmiley(file); // preload all smileys - if(!getCachedSmiley(emoticon).size().isEmpty()) + if(!getCachedSmiley(emoticon).isNull()) emoticonSet.push_back(emoticon); stringElement = stringElement.nextSibling().toElement(); @@ -183,28 +183,21 @@ QString SmileyPack::getAsRichText(const QString &key) return QString("").arg(key); } -QPixmap SmileyPack::getAsPixmap(const QString &key) +QIcon SmileyPack::getAsIcon(const QString &key) { return getCachedSmiley(key); } void SmileyPack::cacheSmiley(const QString &name) { - // The -1 is to avoid having the space for descenders under images move the text down - // We can't remove it because Qt doesn't support CSS display or vertical-align - //TODO: int fontHeight = QFontInfo(Style::getFont(Style::Big)).pixelSize() - 1; - QSize size(16, 16); QString filename = QDir(path).filePath(name); - QImage img(filename); - if (!img.isNull()) - { - QImage scaledImg = img.scaled(size, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); - pixmapCache.insert(name, QPixmap::fromImage(scaledImg)); - } + QIcon icon; + icon.addFile(filename); + iconCache.insert(name, icon); } -QPixmap SmileyPack::getCachedSmiley(const QString &key) +QIcon SmileyPack::getCachedSmiley(const QString &key) { // valid key? if (!filenameTable.contains(key)) @@ -212,11 +205,11 @@ QPixmap SmileyPack::getCachedSmiley(const QString &key) // cache it if needed QString file = filenameTable.value(key); - if (!pixmapCache.contains(file)) { + if (!iconCache.contains(file)) { cacheSmiley(file); } - return pixmapCache.value(file); + return iconCache.value(file); } void SmileyPack::onSmileyPackChanged() diff --git a/src/misc/smileypack.h b/src/misc/smileypack.h index b88c33503..bbe3ed46e 100644 --- a/src/misc/smileypack.h +++ b/src/misc/smileypack.h @@ -21,7 +21,7 @@ #include #include #include -#include +#include #define SMILEYPACK_SEARCH_PATHS \ { \ @@ -41,7 +41,7 @@ public: QString smileyfied(QString msg); QList getEmoticons() const; QString getAsRichText(const QString& key); - QPixmap getAsPixmap(const QString& key); + QIcon getAsIcon(const QString& key); private slots: void onSmileyPackChanged(); @@ -52,10 +52,10 @@ private: SmileyPack& operator=(const SmileyPack&) = delete; void cacheSmiley(const QString& name); - QPixmap getCachedSmiley(const QString& key); + QIcon getCachedSmiley(const QString& key); QHash filenameTable; // matches an emoticon to its corresponding smiley ie. ":)" -> "happy.png" - QHash pixmapCache; // (scaled) representation of a smiley ie. "happy.png" -> data + QHash iconCache; // representation of a smiley ie. "happy.png" -> data QList emoticons; // {{ ":)", ":-)" }, {":(", ...}, ... } QString path; // directory containing the cfg and image files }; diff --git a/src/widget/emoticonswidget.cpp b/src/widget/emoticonswidget.cpp index 55558945a..c067c5232 100644 --- a/src/widget/emoticonswidget.cpp +++ b/src/widget/emoticonswidget.cpp @@ -81,7 +81,7 @@ EmoticonsWidget::EmoticonsWidget(QWidget *parent) : for (const QStringList& set : emoticons) { QPushButton* button = new QPushButton; - button->setIcon(SmileyPack::getInstance().getAsPixmap(set[0])); + button->setIcon(SmileyPack::getInstance().getAsIcon(set[0]).pixmap(QSize(18,18))); button->setToolTip(set.join(" ")); button->setProperty("sequence", set[0]); button->setCursor(Qt::PointingHandCursor); diff --git a/src/widget/form/settings/generalform.cpp b/src/widget/form/settings/generalform.cpp index 732e00a00..726406fb9 100644 --- a/src/widget/form/settings/generalform.cpp +++ b/src/widget/form/settings/generalform.cpp @@ -311,11 +311,12 @@ void GeneralForm::reloadSmiles() for (int i = 0; i < emoticons.size(); i++) smiles.push_front(emoticons.at(i).first()); - bodyUI->smile1->setPixmap(SmileyPack::getInstance().getAsPixmap(smiles[0])); - bodyUI->smile2->setPixmap(SmileyPack::getInstance().getAsPixmap(smiles[1])); - bodyUI->smile3->setPixmap(SmileyPack::getInstance().getAsPixmap(smiles[2])); - bodyUI->smile4->setPixmap(SmileyPack::getInstance().getAsPixmap(smiles[3])); - bodyUI->smile5->setPixmap(SmileyPack::getInstance().getAsPixmap(smiles[4])); + const QSize size(18,18); + bodyUI->smile1->setPixmap(SmileyPack::getInstance().getAsIcon(smiles[0]).pixmap(size)); + bodyUI->smile2->setPixmap(SmileyPack::getInstance().getAsIcon(smiles[1]).pixmap(size)); + bodyUI->smile3->setPixmap(SmileyPack::getInstance().getAsIcon(smiles[2]).pixmap(size)); + bodyUI->smile4->setPixmap(SmileyPack::getInstance().getAsIcon(smiles[3]).pixmap(size)); + bodyUI->smile5->setPixmap(SmileyPack::getInstance().getAsIcon(smiles[4]).pixmap(size)); bodyUI->smile1->setToolTip(smiles[0]); bodyUI->smile2->setToolTip(smiles[1]); From 57485368cb33493bb73a698cf58505394b36ad3b Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 27 Jan 2015 09:58:08 +0100 Subject: [PATCH 141/203] fix showEvent calling centerOn --- src/chatlog/chatlog.cpp | 7 +++++++ src/chatlog/chatlog.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 5a7e80d7a..aa985e53b 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -728,3 +728,10 @@ void ChatLog::onWorkerTimeout() verticalScrollBar()->show(); } } + +void ChatLog::showEvent(QShowEvent *) +{ + // Empty. + // The default implementation calls centerOn - for some reason - causing + // the scrollbar to move. +} diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 4461d2b3c..611900fbc 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -80,6 +80,7 @@ protected: virtual void mouseMoveEvent(QMouseEvent* ev); virtual void scrollContentsBy(int dx, int dy); virtual void resizeEvent(QResizeEvent *ev); + virtual void showEvent(QShowEvent *); void updateMultiSelectionRect(); void updateTypingNotification(); From ce486eb1b3ba3675fe032bd78353b2afa2151d53 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 27 Jan 2015 10:49:18 +0100 Subject: [PATCH 142/203] FileTransferWidget: visual tweaks --- src/chatlog/content/filetransferwidget.cpp | 4 ++-- ui/fileTransferInstance/filetransferWidget.css | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index 4fc8b3c89..03d050db2 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -60,7 +60,7 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) if(fileInfo.direction == ToxFile::SENDING) showPreview(fileInfo.filePath); - setFixedHeight(80); + setFixedHeight(60); } FileTransferWidget::~FileTransferWidget() @@ -134,7 +134,7 @@ void FileTransferWidget::paintEvent(QPaintEvent *) painter.setPen(Qt::NoPen); qreal s = static_cast(geometry().height()) / static_cast(geometry().width()); - int r = 15; + int r = 20; painter.drawRoundRect(geometry(), r * s, r); } diff --git a/ui/fileTransferInstance/filetransferWidget.css b/ui/fileTransferInstance/filetransferWidget.css index 60ff2bcbe..6be989d4e 100644 --- a/ui/fileTransferInstance/filetransferWidget.css +++ b/ui/fileTransferInstance/filetransferWidget.css @@ -10,16 +10,16 @@ QPushButton { margin:0; + border: none; } QProgressBar { border: 2px solid black; - border-radius: 0px; - color: white; - background-color:white; + border-radius: 4px; + background-color: @mediumGrey; } QProgressBar::chunk { - background-color: black; - width: 20px; + background-color: @lightGrey; + width: 1px; } \ No newline at end of file From cfe4458d37d7efac51046d88ff3ba41e49c1b8ed Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 27 Jan 2015 10:52:23 +0100 Subject: [PATCH 143/203] Moved status messages back to the left --- src/chatlog/chatmessage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 175157d90..2c18a73e3 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -82,7 +82,7 @@ ChatMessage::Ptr ChatMessage::createChatInfoMessage(const QString &rawMessage, S } msg->addColumn(new Image(QSizeF(18, 18), img), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); - msg->addColumn(new Text("
" + text + "
", Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Left)); + msg->addColumn(new Text("" + text + "", Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Left)); msg->addColumn(new Timestamp(date, Settings::getInstance().getTimestampFormat(), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); return msg; From ebebde1b09b5d7761115af403e74541538816da7 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 27 Jan 2015 11:20:35 +0100 Subject: [PATCH 144/203] use QSize instead of QSizeF, cleanup --- src/chatlog/chatmessage.cpp | 4 ++-- src/chatlog/content/image.cpp | 4 ++-- src/chatlog/content/image.h | 4 ++-- src/chatlog/content/spinner.cpp | 4 ++-- src/chatlog/content/spinner.h | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 2c18a73e3..ffae7b151 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -60,7 +60,7 @@ ChatMessage::Ptr ChatMessage::createChatMessage(const QString &sender, const QSt msg->addColumn(new Text(isAction ? "
*
" : sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), isAction ? false : true, sender), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text(text, Style::getFont(Style::Big), false, isAction ? QString("*%1 %2*").arg(sender, rawMessage) : rawMessage), ColumnFormat(1.0, ColumnFormat::VariableSize)); - msg->addColumn(new Spinner(":/ui/chatArea/spinner.svg", QSizeF(16, 16), 8.0), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + msg->addColumn(new Spinner(":/ui/chatArea/spinner.svg", QSize(16, 16), 8.0), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); if(!date.isNull()) msg->markAsSent(date); @@ -81,7 +81,7 @@ ChatMessage::Ptr ChatMessage::createChatInfoMessage(const QString &rawMessage, S case TYPING: img = ":/ui/chatArea/typing.svg"; break; } - msg->addColumn(new Image(QSizeF(18, 18), img), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + msg->addColumn(new Image(QSize(18, 18), img), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text("" + text + "", Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Left)); msg->addColumn(new Timestamp(date, Settings::getInstance().getTimestampFormat(), Style::getFont(Style::Big)), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); diff --git a/src/chatlog/content/image.cpp b/src/chatlog/content/image.cpp index fb2a44d49..5ef26ae48 100644 --- a/src/chatlog/content/image.cpp +++ b/src/chatlog/content/image.cpp @@ -18,7 +18,7 @@ #include -Image::Image(QSizeF Size, const QString& filename) +Image::Image(QSize Size, const QString& filename) : size(Size) { icon.addFile(filename); @@ -43,7 +43,7 @@ void Image::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWi { painter->setRenderHint(QPainter::SmoothPixmapTransform); painter->translate(-size.width() / 2.0, -size.height() / 2.0); - painter->drawPixmap(0, 0, size.width(), size.height(), icon.pixmap(size.toSize())); + painter->drawPixmap(0, 0, icon.pixmap(size)); Q_UNUSED(option) Q_UNUSED(widget) diff --git a/src/chatlog/content/image.h b/src/chatlog/content/image.h index 6afe486bc..d98f8e037 100644 --- a/src/chatlog/content/image.h +++ b/src/chatlog/content/image.h @@ -24,7 +24,7 @@ class Image : public ChatLineContent { public: - Image(QSizeF size, const QString &filename); + Image(QSize size, const QString &filename); virtual QRectF boundingRect() const override; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; @@ -33,7 +33,7 @@ public: virtual qreal getAscent() const override; private: - QSizeF size; + QSize size; QIcon icon; }; diff --git a/src/chatlog/content/spinner.cpp b/src/chatlog/content/spinner.cpp index e32bcf02c..743627012 100644 --- a/src/chatlog/content/spinner.cpp +++ b/src/chatlog/content/spinner.cpp @@ -19,7 +19,7 @@ #include #include -Spinner::Spinner(const QString &img, QSizeF Size, qreal speed) +Spinner::Spinner(const QString &img, QSize Size, qreal speed) : size(Size) , rotSpeed(speed) { @@ -52,7 +52,7 @@ void Spinner::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, Q painter->translate(-size.width() / 2.0, -size.height() / 2.0); painter->setTransform(rotMat, true); painter->setRenderHint(QPainter::SmoothPixmapTransform); - painter->drawPixmap(0, 0, size.width(), size.height(), icon.pixmap(size.toSize() * painter->device()->devicePixelRatio())); + painter->drawPixmap(0, 0, icon.pixmap(size)); Q_UNUSED(option) Q_UNUSED(widget) diff --git a/src/chatlog/content/spinner.h b/src/chatlog/content/spinner.h index e51401eb7..a78d7683c 100644 --- a/src/chatlog/content/spinner.h +++ b/src/chatlog/content/spinner.h @@ -27,7 +27,7 @@ class Spinner : public QObject, public ChatLineContent { Q_OBJECT public: - Spinner(const QString& img, QSizeF size, qreal speed); + Spinner(const QString& img, QSize size, qreal speed); virtual QRectF boundingRect() const override; virtual QRectF boundingSceneRect() const override; @@ -40,7 +40,7 @@ private slots: void timeout(); private: - QSizeF size; + QSize size; QIcon icon; qreal rot = 0.0; qreal rotSpeed; From 7ec54c972c35961f8bdf4743df222358946d4f74 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 31 Jan 2015 17:32:41 +0100 Subject: [PATCH 145/203] set ChatLine::isVisible to true --- src/chatlog/chatline.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index 3813e2a52..b68af99df 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -102,7 +102,7 @@ private: qreal width = 100.0; qreal columnSpacing = 15.0; QRectF bbox; - bool isVisible = false; + bool isVisible = true; }; From 56686061591ebb713a3b62bd1115d833c59102ee Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 31 Jan 2015 17:39:25 +0100 Subject: [PATCH 146/203] Speed-up rendering --- src/chatlog/chatlog.cpp | 3 ++- src/chatlog/content/spinner.cpp | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index aa985e53b..593124785 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -42,7 +42,7 @@ ChatLog::ChatLog(QWidget* parent) // Create the scene busyScene = new QGraphicsScene(this); scene = new QGraphicsScene(this); - scene->setItemIndexMethod(QGraphicsScene::NoIndex); //Bsp-Tree is actually slower in this case + scene->setItemIndexMethod(QGraphicsScene::BspTreeIndex); setScene(scene); // Cfg. @@ -380,6 +380,7 @@ void ChatLog::insertChatlineOnTop(const QList& newLines) { l->addToScene(scene); l->setRow(--n); + l->visibilityChanged(false); lines.prepend(l); } diff --git a/src/chatlog/content/spinner.cpp b/src/chatlog/content/spinner.cpp index 743627012..15dc9229c 100644 --- a/src/chatlog/content/spinner.cpp +++ b/src/chatlog/content/spinner.cpp @@ -17,6 +17,7 @@ #include "spinner.h" #include +#include #include Spinner::Spinner(const QString &img, QSize Size, qreal speed) @@ -79,5 +80,7 @@ qreal Spinner::getAscent() const void Spinner::timeout() { rot += rotSpeed; - update(); + + if(scene()) + scene()->invalidate(sceneBoundingRect()); } From 6a50add547ed8f5ec3c38eb579b0187f7eb72b8a Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 31 Jan 2015 17:46:25 +0100 Subject: [PATCH 147/203] ChatLineContent: removed boundingSceneRect() --- src/chatlog/chatlinecontent.h | 1 - src/chatlog/content/image.cpp | 5 ----- src/chatlog/content/image.h | 1 - src/chatlog/content/notificationicon.cpp | 5 ----- src/chatlog/content/notificationicon.h | 1 - src/chatlog/content/spinner.cpp | 5 ----- src/chatlog/content/spinner.h | 1 - src/chatlog/content/text.cpp | 5 ----- src/chatlog/content/text.h | 1 - 9 files changed, 25 deletions(-) diff --git a/src/chatlog/chatlinecontent.h b/src/chatlog/chatlinecontent.h index 832b57e58..674182185 100644 --- a/src/chatlog/chatlinecontent.h +++ b/src/chatlog/chatlinecontent.h @@ -46,7 +46,6 @@ public: virtual qreal getAscent() const; - virtual QRectF boundingSceneRect() const = 0; virtual QRectF boundingRect() const = 0; virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) = 0; diff --git a/src/chatlog/content/image.cpp b/src/chatlog/content/image.cpp index 5ef26ae48..762999866 100644 --- a/src/chatlog/content/image.cpp +++ b/src/chatlog/content/image.cpp @@ -29,11 +29,6 @@ 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::getAscent() const { return 0.0; diff --git a/src/chatlog/content/image.h b/src/chatlog/content/image.h index d98f8e037..6c64e1006 100644 --- a/src/chatlog/content/image.h +++ b/src/chatlog/content/image.h @@ -29,7 +29,6 @@ public: virtual QRectF boundingRect() const override; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; virtual void setWidth(qreal width) override; - virtual QRectF boundingSceneRect() const override; virtual qreal getAscent() const override; private: diff --git a/src/chatlog/content/notificationicon.cpp b/src/chatlog/content/notificationicon.cpp index 5ca23099a..af58abb30 100644 --- a/src/chatlog/content/notificationicon.cpp +++ b/src/chatlog/content/notificationicon.cpp @@ -55,11 +55,6 @@ void NotificationIcon::setWidth(qreal width) Q_UNUSED(width) } -QRectF NotificationIcon::boundingSceneRect() const -{ - return QRectF(scenePos(), size); -} - qreal NotificationIcon::getAscent() const { return 3.0; diff --git a/src/chatlog/content/notificationicon.h b/src/chatlog/content/notificationicon.h index 79ff083bd..3075103f6 100644 --- a/src/chatlog/content/notificationicon.h +++ b/src/chatlog/content/notificationicon.h @@ -33,7 +33,6 @@ public: virtual QRectF boundingRect() const override; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; virtual void setWidth(qreal width) override; - virtual QRectF boundingSceneRect() const override; virtual qreal getAscent() const override; private slots: diff --git a/src/chatlog/content/spinner.cpp b/src/chatlog/content/spinner.cpp index 15dc9229c..54a9fc441 100644 --- a/src/chatlog/content/spinner.cpp +++ b/src/chatlog/content/spinner.cpp @@ -38,11 +38,6 @@ QRectF Spinner::boundingRect() const return QRectF(QPointF(-size.width() / 2.0, -size.height() / 2.0), size); } -QRectF Spinner::boundingSceneRect() const -{ - return QRectF(scenePos(), size); -} - void Spinner::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { QTransform rotMat; diff --git a/src/chatlog/content/spinner.h b/src/chatlog/content/spinner.h index a78d7683c..d90d12489 100644 --- a/src/chatlog/content/spinner.h +++ b/src/chatlog/content/spinner.h @@ -30,7 +30,6 @@ public: Spinner(const QString& img, QSize size, qreal speed); virtual QRectF boundingRect() const override; - virtual QRectF boundingSceneRect() const override; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; virtual void setWidth(qreal width) override; virtual void visibilityChanged(bool visible) override; diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 828b4d88e..6a98837e1 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -140,11 +140,6 @@ QString Text::getSelectedText() const return selectedText; } -QRectF Text::boundingSceneRect() const -{ - return QRectF(scenePos(), size); -} - QRectF Text::boundingRect() const { return QRectF(QPointF(0, 0), size); diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index f61711789..08f8ff5b5 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -43,7 +43,6 @@ public: virtual bool isOverSelection(QPointF scenePos) const override; virtual QString getSelectedText() const override; - virtual QRectF boundingSceneRect() const override; virtual QRectF boundingRect() const override; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; From 1d6f3858d9a5d713de2b5d8bff539a5eedbdb005 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 31 Jan 2015 17:49:19 +0100 Subject: [PATCH 148/203] renamed ChatLine::boundingSceneRect to ChatLine::sceneBoundingRect --- src/chatlog/chatline.cpp | 6 +++--- src/chatlog/chatline.h | 2 +- src/chatlog/chatlog.cpp | 18 +++++++++--------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index fad71cfbb..e7f506a81 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -123,7 +123,7 @@ void ChatLine::updateBBox() bbox.setHeight(qMax(c->sceneBoundingRect().height(), bbox.height())); } -QRectF ChatLine::boundingSceneRect() const +QRectF ChatLine::sceneBoundingRect() const { return bbox; } @@ -241,12 +241,12 @@ void ChatLine::moveBy(qreal deltaY) bool ChatLine::lessThanBSRectTop(const ChatLine::Ptr lhs, const qreal rhs) { - return lhs->boundingSceneRect().top() < rhs; + return lhs->sceneBoundingRect().top() < rhs; } bool ChatLine::lessThanBSRectBottom(const ChatLine::Ptr lhs, const qreal rhs) { - return lhs->boundingSceneRect().bottom() < rhs; + return lhs->sceneBoundingRect().bottom() < rhs; } bool ChatLine::lessThanRowIndex(const ChatLine::Ptr lhs, const ChatLine::Ptr rhs) diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index b68af99df..69a3ceb65 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -62,7 +62,7 @@ public: ChatLine(); virtual ~ChatLine(); - QRectF boundingSceneRect() const; + QRectF sceneBoundingRect() const; void replaceContent(int col, ChatLineContent* lineContent); void layout(qreal width, QPointF scenePos); diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 593124785..b188e1d0d 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -130,7 +130,7 @@ void ChatLog::layout(int start, int end, qreal width) // Line at start-1 is considered to have the correct position. All following lines are // positioned in respect to this line. if(start - 1 >= 0) - h = lines[start - 1]->boundingSceneRect().bottom() + lineSpacing; + h = lines[start - 1]->sceneBoundingRect().bottom() + lineSpacing; start = clamp(start, 0, lines.size()); end = clamp(end + 1, 0, lines.size()); @@ -140,7 +140,7 @@ void ChatLog::layout(int start, int end, qreal width) ChatLine* l = lines[i].get(); l->layout(width, QPointF(0.0, h)); - h += l->boundingSceneRect().height() + lineSpacing; + h += l->sceneBoundingRect().height() + lineSpacing; } } @@ -290,7 +290,7 @@ ChatLineContent* ChatLog::getContentFromPos(QPointF scenePos) const auto itr = std::lower_bound(lines.cbegin(), lines.cend(), scenePos.y(), ChatLine::lessThanBSRectBottom); //find content - if(itr != lines.cend() && (*itr)->boundingSceneRect().contains(scenePos)) + if(itr != lines.cend() && (*itr)->sceneBoundingRect().contains(scenePos)) return (*itr)->getContent(scenePos); return nullptr; @@ -549,7 +549,7 @@ void ChatLog::scrollToLine(ChatLine::Ptr line) return; updateSceneRect(); - verticalScrollBar()->setValue(line->boundingSceneRect().top()); + verticalScrollBar()->setValue(line->sceneBoundingRect().top()); } void ChatLog::selectAll() @@ -621,8 +621,8 @@ void ChatLog::updateMultiSelectionRect() if(selectionMode == Multi && selFirstRow >= 0 && selLastRow >= 0) { QRectF selBBox; - selBBox = selBBox.united(lines[selFirstRow]->boundingSceneRect()); - selBBox = selBBox.united(lines[selLastRow]->boundingSceneRect()); + selBBox = selBBox.united(lines[selFirstRow]->sceneBoundingRect()); + selBBox = selBBox.united(lines[selLastRow]->sceneBoundingRect()); selGraphItem->setRect(selBBox); selGraphItem->show(); @@ -642,7 +642,7 @@ void ChatLog::updateTypingNotification() qreal posY = 0.0; if(!lines.empty()) - posY = lines.last()->boundingSceneRect().bottom() + lineSpacing; + posY = lines.last()->sceneBoundingRect().bottom() + lineSpacing; notification->layout(useableWidth(), QPointF(0.0, posY)); } @@ -668,10 +668,10 @@ ChatLine::Ptr ChatLog::findLineByPosY(qreal yPos) const QRectF ChatLog::calculateSceneRect() const { - qreal bottom = (lines.empty() ? 0.0 : lines.last()->boundingSceneRect().bottom()); + qreal bottom = (lines.empty() ? 0.0 : lines.last()->sceneBoundingRect().bottom()); if(typingNotification.get() != nullptr) - bottom += typingNotification->boundingSceneRect().height() + lineSpacing; + bottom += typingNotification->sceneBoundingRect().height() + lineSpacing; return QRectF(-margins.left(), -margins.top(), useableWidth(), bottom + margins.bottom() + margins.top()); } From 2206db1406266871607d448700274d1c39f654bf Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 31 Jan 2015 17:50:35 +0100 Subject: [PATCH 149/203] comparators should be public --- src/chatlog/chatline.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index 69a3ceb65..6499ffc02 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -80,6 +80,11 @@ public: bool isOverSelection(QPointF scenePos); + //comparators + static bool lessThanBSRectTop(const ChatLine::Ptr lhs, const qreal rhs); + static bool lessThanBSRectBottom(const ChatLine::Ptr lhs, const qreal rhs); + static bool lessThanRowIndex(const ChatLine::Ptr lhs, const ChatLine::Ptr rhs); + protected: friend class ChatLog; @@ -90,11 +95,6 @@ protected: void setRow(int idx); void visibilityChanged(bool visible); - //comparators - static bool lessThanBSRectTop(const ChatLine::Ptr lhs, const qreal rhs); - static bool lessThanBSRectBottom(const ChatLine::Ptr lhs, const qreal rhs); - static bool lessThanRowIndex(const ChatLine::Ptr lhs, const ChatLine::Ptr rhs); - private: int row = -1; std::vector content; From 740d62ec4991206a2a2d9734325abcaa26e27385 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 31 Jan 2015 18:12:51 +0100 Subject: [PATCH 150/203] change ChatLine::isVisible to false, rename Text::isVisible to Text::keepInMemory --- src/chatlog/chatline.h | 2 +- src/chatlog/content/spinner.cpp | 1 - src/chatlog/content/text.cpp | 4 ++-- src/chatlog/content/text.h | 4 ++-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index 6499ffc02..842fb4b61 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -102,7 +102,7 @@ private: qreal width = 100.0; qreal columnSpacing = 15.0; QRectF bbox; - bool isVisible = true; + bool isVisible = false; }; diff --git a/src/chatlog/content/spinner.cpp b/src/chatlog/content/spinner.cpp index 54a9fc441..b05849006 100644 --- a/src/chatlog/content/spinner.cpp +++ b/src/chatlog/content/spinner.cpp @@ -28,7 +28,6 @@ Spinner::Spinner(const QString &img, QSize Size, qreal speed) timer.setInterval(33); // 30Hz timer.setSingleShot(false); - timer.start(); QObject::connect(&timer, &QTimer::timeout, this, &Spinner::timeout); } diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 6a98837e1..255ddb623 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -174,7 +174,7 @@ void Text::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWid void Text::visibilityChanged(bool visible) { - isVisible = visible; + keepInMemory = visible; regenerate(); update(); @@ -250,7 +250,7 @@ void Text::regenerate() size = idealSize(); // if we are not visible -> free mem - if(!isVisible) + if(!keepInMemory) freeResources(); } diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index 08f8ff5b5..63f0fe540 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -46,7 +46,7 @@ public: virtual QRectF boundingRect() const override; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; - virtual void visibilityChanged(bool isVisible) override; + virtual void visibilityChanged(bool keepInMemory) override; virtual qreal getAscent() const override; virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override; @@ -73,7 +73,7 @@ private: QString elidedText; QString selectedText; QSizeF size; - bool isVisible = false; + bool keepInMemory = false; bool elide = false; bool dirty = false; int selectionEnd = -1; From f288fe5c1ecee7764db24ab877038e959fbaddb1 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 31 Jan 2015 18:37:20 +0100 Subject: [PATCH 151/203] tweaks --- src/chatlog/chatlog.cpp | 4 ++-- src/chatlog/content/text.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index b188e1d0d..603c61e3a 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -88,7 +88,7 @@ ChatLog::ChatLog(QWidget* parent) // Updates the layout of all chat-lines after a resize workerTimer = new QTimer(this); workerTimer->setSingleShot(false); - workerTimer->setInterval(100); + workerTimer->setInterval(5); connect(workerTimer, &QTimer::timeout, this, &ChatLog::onWorkerTimeout); } @@ -697,7 +697,7 @@ void ChatLog::onWorkerTimeout() { // Fairly arbitrary but // large values will make the UI unresponsive - const int stepSize = 400; + const int stepSize = 50; layout(workerLastIndex, workerLastIndex+stepSize, useableWidth()); workerLastIndex += stepSize; diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 255ddb623..6883a4662 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -35,7 +35,7 @@ Text::Text(const QString& txt, QFont font, bool enableElide, const QString &rwTe , defFont(font) { setText(txt); - setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton); + setAcceptedMouseButtons(Qt::LeftButton); } Text::~Text() From f15b9da1e1eb0ffcdad0b83378eddb6e5bbdc684 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 31 Jan 2015 19:19:13 +0100 Subject: [PATCH 152/203] fix a render artifact --- src/chatlog/chatlog.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 603c61e3a..45c7c982b 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -624,6 +624,8 @@ void ChatLog::updateMultiSelectionRect() selBBox = selBBox.united(lines[selFirstRow]->sceneBoundingRect()); selBBox = selBBox.united(lines[selLastRow]->sceneBoundingRect()); + scene->invalidate(selGraphItem->sceneBoundingRect()); + selGraphItem->setRect(selBBox); selGraphItem->show(); } From 783caf932c66e685c5053bef28fbf9c1baae3bc6 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 31 Jan 2015 19:22:45 +0100 Subject: [PATCH 153/203] revert to "[user] is typing" --- src/widget/form/chatform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 805bf5c8a..cd13bc427 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -887,7 +887,7 @@ void ChatForm::setFriendTyping(bool isTyping) Text* text = dynamic_cast(chatWidget->getTypingNotification()->getContent(1)); if(text) - text->setText("
" + QString("%1 ...").arg(f->getDisplayedName()) + "
"); + text->setText("
" + QString("%1 is typing").arg(f->getDisplayedName()) + "
"); } void ChatForm::clearReciepts() From 53ba982203582124701bc44d386db18952565319 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 2 Feb 2015 11:01:01 +0100 Subject: [PATCH 154/203] optimizations and tweaks --- qtox.pro | 8 +++-- src/chatlog/chatlog.cpp | 13 +++---- src/chatlog/chatmessage.cpp | 2 +- src/chatlog/content/image.cpp | 5 +-- src/chatlog/content/image.h | 4 +-- src/chatlog/content/notificationicon.cpp | 17 +++++---- src/chatlog/content/notificationicon.h | 8 ++--- src/chatlog/content/spinner.cpp | 7 ++-- src/chatlog/content/spinner.h | 4 +-- src/chatlog/content/text.cpp | 40 ++++++++++----------- src/chatlog/content/text.h | 7 ++-- src/chatlog/documentcache.cpp | 44 ++++++++++++++++++++++++ src/chatlog/documentcache.h | 43 +++++++++++++++++++++++ src/chatlog/pixmapcache.cpp | 41 ++++++++++++++++++++++ src/chatlog/pixmapcache.h | 40 +++++++++++++++++++++ 15 files changed, 230 insertions(+), 53 deletions(-) create mode 100644 src/chatlog/documentcache.cpp create mode 100644 src/chatlog/documentcache.h create mode 100644 src/chatlog/pixmapcache.cpp create mode 100644 src/chatlog/pixmapcache.h diff --git a/qtox.pro b/qtox.pro index 73c7720f0..f1cdfb7ae 100644 --- a/qtox.pro +++ b/qtox.pro @@ -193,7 +193,9 @@ HEADERS += src/widget/form/addfriendform.h \ src/widget/form/settings/advancedform.h \ src/audio.h \ src/chatlog/content/notificationicon.h \ - src/chatlog/content/timestamp.h + src/chatlog/content/timestamp.h \ + src/chatlog/documentcache.h \ + src/chatlog/pixmapcache.h SOURCES += \ src/widget/form/addfriendform.cpp \ @@ -264,7 +266,9 @@ SOURCES += \ src/widget/form/settings/advancedform.cpp \ src/audio.cpp \ src/chatlog/content/notificationicon.cpp \ - src/chatlog/content/timestamp.cpp + src/chatlog/content/timestamp.cpp \ + src/chatlog/documentcache.cpp \ + src/chatlog/pixmapcache.cpp contains(DEFINES, QTOX_FILTER_AUDIO) { HEADERS += src/audiofilterer.h diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 45c7c982b..f1c665d9d 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -47,18 +47,18 @@ ChatLog::ChatLog(QWidget* parent) // Cfg. setInteractive(true); + setAcceptDrops(false); setAlignment(Qt::AlignTop | Qt::AlignLeft); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setDragMode(QGraphicsView::NoDrag); - setViewportUpdateMode(BoundingRectViewportUpdate); - setAcceptDrops(false); + setViewportUpdateMode(MinimalViewportUpdate); setContextMenuPolicy(Qt::CustomContextMenu); setBackgroundBrush(QBrush(Qt::white, Qt::SolidPattern)); // The selection rect for multi-line selection const QColor selGraphColor = QColor(166,225,255); selGraphItem = scene->addRect(0,0,0,0,selGraphColor.darker(120),selGraphColor); - selGraphItem->setZValue(-10.0); //behind all items + selGraphItem->setZValue(-1.0); // behind all other items // copy action (ie. Ctrl+C) QAction* copyAction = new QAction(this); @@ -79,7 +79,7 @@ ChatLog::ChatLog(QWidget* parent) // This timer is used to scroll the view while the user is // moving the mouse past the top/bottom edge of the widget while selecting. selectionTimer = new QTimer(this); - selectionTimer->setInterval(1000/60); + selectionTimer->setInterval(1000/30); selectionTimer->setSingleShot(false); selectionTimer->start(); connect(selectionTimer, &QTimer::timeout, this, &ChatLog::onSelectionTimerTimeout); @@ -575,7 +575,7 @@ void ChatLog::checkVisibility() auto lowerBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().top(), ChatLine::lessThanBSRectBottom); // find last visible line - auto upperBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().bottom(), ChatLine::lessThanBSRectTop); + auto upperBound = std::lower_bound(lowerBound, lines.cend(), getVisibleRect().bottom(), ChatLine::lessThanBSRectTop); // set visibilty QList newVisibleLines; @@ -624,7 +624,8 @@ void ChatLog::updateMultiSelectionRect() selBBox = selBBox.united(lines[selFirstRow]->sceneBoundingRect()); selBBox = selBBox.united(lines[selLastRow]->sceneBoundingRect()); - scene->invalidate(selGraphItem->sceneBoundingRect()); + if(selGraphItem->rect() != selBBox) + scene->invalidate(selGraphItem->rect()); selGraphItem->setRect(selBBox); selGraphItem->show(); diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index ffae7b151..67eacc72b 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -104,7 +104,7 @@ ChatMessage::Ptr ChatMessage::createTypingNotification() ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); // Note: "[user]..." is just a placeholder. The actual text is set in ChatForm::setFriendTyping() - msg->addColumn(new NotificationIcon(QSizeF(18, 18)), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + msg->addColumn(new NotificationIcon(QSize(18, 18)), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text("[user]...", Style::getFont(Style::Big), false, ""), ColumnFormat(1.0, ColumnFormat::VariableSize, ColumnFormat::Left)); return msg; diff --git a/src/chatlog/content/image.cpp b/src/chatlog/content/image.cpp index 762999866..699fbeab9 100644 --- a/src/chatlog/content/image.cpp +++ b/src/chatlog/content/image.cpp @@ -15,13 +15,14 @@ */ #include "image.h" +#include "../pixmapcache.h" #include Image::Image(QSize Size, const QString& filename) : size(Size) { - icon.addFile(filename); + pmap = PixmapCache::getInstance().get(filename, size); } QRectF Image::boundingRect() const @@ -38,7 +39,7 @@ void Image::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWi { painter->setRenderHint(QPainter::SmoothPixmapTransform); painter->translate(-size.width() / 2.0, -size.height() / 2.0); - painter->drawPixmap(0, 0, icon.pixmap(size)); + painter->drawPixmap(0, 0, pmap); Q_UNUSED(option) Q_UNUSED(widget) diff --git a/src/chatlog/content/image.h b/src/chatlog/content/image.h index 6c64e1006..d3aa3286d 100644 --- a/src/chatlog/content/image.h +++ b/src/chatlog/content/image.h @@ -19,7 +19,7 @@ #include "../chatlinecontent.h" -#include +#include class Image : public ChatLineContent { @@ -33,7 +33,7 @@ public: private: QSize size; - QIcon icon; + QPixmap pmap; }; diff --git a/src/chatlog/content/notificationicon.cpp b/src/chatlog/content/notificationicon.cpp index af58abb30..887247761 100644 --- a/src/chatlog/content/notificationicon.cpp +++ b/src/chatlog/content/notificationicon.cpp @@ -15,17 +15,19 @@ */ #include "notificationicon.h" +#include "../pixmapcache.h" #include #include +#include -NotificationIcon::NotificationIcon(QSizeF Size) +NotificationIcon::NotificationIcon(QSize Size) : size(Size) { - icon.addFile(":/ui/chatArea/typing.svg"); + pmap = PixmapCache::getInstance().get(":/ui/chatArea/typing.svg", size); updateTimer = new QTimer(this); - updateTimer->setInterval(1000/60); + updateTimer->setInterval(1000/30); updateTimer->setSingleShot(false); updateTimer->start(); @@ -44,7 +46,7 @@ void NotificationIcon::paint(QPainter *painter, const QStyleOptionGraphicsItem * painter->translate(-size.width() / 2.0, -size.height() / 2.0); painter->fillRect(QRect(0, 0, size.width(), size.height()), grad); - painter->drawPixmap(0, 0, size.width(), size.height(), icon.pixmap(size.toSize() * painter->device()->devicePixelRatio())); + painter->drawPixmap(0, 0, size.width(), size.height(), pmap); Q_UNUSED(option) Q_UNUSED(widget) @@ -62,7 +64,7 @@ qreal NotificationIcon::getAscent() const void NotificationIcon::updateGradient() { - alpha += 0.005; + alpha += 0.01; if(alpha + dotWidth >= 1.0) alpha = 0.0; @@ -70,9 +72,10 @@ void NotificationIcon::updateGradient() grad = QLinearGradient(QPointF(-0.5*size.width(),0), QPointF(3.0/2.0*size.width(),0)); grad.setColorAt(0, Qt::lightGray); grad.setColorAt(qMax(0.0, alpha - dotWidth), Qt::lightGray); - grad.setColorAt(alpha, Qt::darkGray); + grad.setColorAt(alpha, Qt::black); grad.setColorAt(qMin(1.0, alpha + dotWidth), Qt::lightGray); grad.setColorAt(1, Qt::lightGray); - update(); + if(scene()) + scene()->invalidate(sceneBoundingRect()); } diff --git a/src/chatlog/content/notificationicon.h b/src/chatlog/content/notificationicon.h index 3075103f6..6e4ca5d11 100644 --- a/src/chatlog/content/notificationicon.h +++ b/src/chatlog/content/notificationicon.h @@ -20,7 +20,7 @@ #include "../chatlinecontent.h" #include -#include +#include class QTimer; @@ -28,7 +28,7 @@ class NotificationIcon : public QObject, public ChatLineContent { Q_OBJECT public: - NotificationIcon(QSizeF size); + NotificationIcon(QSize size); virtual QRectF boundingRect() const override; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; @@ -39,8 +39,8 @@ private slots: void updateGradient(); private: - QSizeF size; - QIcon icon; + QSize size; + QPixmap pmap; QLinearGradient grad; QTimer* updateTimer = nullptr; diff --git a/src/chatlog/content/spinner.cpp b/src/chatlog/content/spinner.cpp index b05849006..262b4a35b 100644 --- a/src/chatlog/content/spinner.cpp +++ b/src/chatlog/content/spinner.cpp @@ -15,6 +15,7 @@ */ #include "spinner.h" +#include "../pixmapcache.h" #include #include @@ -24,9 +25,9 @@ Spinner::Spinner(const QString &img, QSize Size, qreal speed) : size(Size) , rotSpeed(speed) { - icon.addFile(img); + pmap = PixmapCache::getInstance().get(img, size); - timer.setInterval(33); // 30Hz + timer.setInterval(1000/30); // 30Hz timer.setSingleShot(false); QObject::connect(&timer, &QTimer::timeout, this, &Spinner::timeout); @@ -47,7 +48,7 @@ void Spinner::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, Q painter->translate(-size.width() / 2.0, -size.height() / 2.0); painter->setTransform(rotMat, true); painter->setRenderHint(QPainter::SmoothPixmapTransform); - painter->drawPixmap(0, 0, icon.pixmap(size)); + painter->drawPixmap(0, 0, pmap); Q_UNUSED(option) Q_UNUSED(widget) diff --git a/src/chatlog/content/spinner.h b/src/chatlog/content/spinner.h index d90d12489..45c3c4e16 100644 --- a/src/chatlog/content/spinner.h +++ b/src/chatlog/content/spinner.h @@ -21,7 +21,7 @@ #include #include -#include +#include class Spinner : public QObject, public ChatLineContent { @@ -40,7 +40,7 @@ private slots: private: QSize size; - QIcon icon; + QPixmap pmap; qreal rot = 0.0; qreal rotSpeed; QTimer timer; diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 6883a4662..ce58cf9f7 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -15,8 +15,7 @@ */ #include "text.h" - -#include "../customtextdocument.h" +#include "../documentcache.h" #include #include @@ -40,7 +39,8 @@ Text::Text(const QString& txt, QFont font, bool enableElide, const QString &rwTe Text::~Text() { - delete doc; + if(doc) + DocumentCache::getInstance().push(doc); } void Text::setText(const QString& txt) @@ -212,7 +212,7 @@ void Text::regenerate() { if(!doc) { - doc = new CustomTextDocument(); + doc = DocumentCache::getInstance().pop(); doc->setDefaultFont(defFont); dirty = true; } @@ -231,24 +231,24 @@ void Text::regenerate() doc->setPlainText(elidedText); } + // width & layout + doc->setTextWidth(width); + doc->documentLayout()->update(); + + // update ascent + if(doc->firstBlock().layout()->lineCount() > 0) + ascent = doc->firstBlock().layout()->lineAt(0).ascent(); + + // let the scene know about our change in size + if(size != idealSize()) + prepareGeometryChange(); + + // get the new width and height + size = idealSize(); + dirty = false; } - // width & layout - doc->setTextWidth(width); - doc->documentLayout()->update(); - - // update ascent - if(doc->firstBlock().layout()->lineCount() > 0) - ascent = doc->firstBlock().layout()->lineAt(0).ascent(); - - // let the scene know about our change in size - if(size != idealSize()) - prepareGeometryChange(); - - // get the new width and height - size = idealSize(); - // if we are not visible -> free mem if(!keepInMemory) freeResources(); @@ -256,7 +256,7 @@ void Text::regenerate() void Text::freeResources() { - delete doc; + DocumentCache::getInstance().push(doc); doc = nullptr; } diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index 63f0fe540..beaa1cecf 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -19,10 +19,9 @@ #include "../chatlinecontent.h" -#include -#include +#include -class CustomTextDocument; +class QTextDocument; class Text : public ChatLineContent { @@ -67,7 +66,7 @@ protected: QString extractSanitizedText(int from, int to) const; private: - CustomTextDocument* doc = nullptr; + QTextDocument* doc = nullptr; QString text; QString rawText; QString elidedText; diff --git a/src/chatlog/documentcache.cpp b/src/chatlog/documentcache.cpp new file mode 100644 index 000000000..32b25317e --- /dev/null +++ b/src/chatlog/documentcache.cpp @@ -0,0 +1,44 @@ +/* + Copyright (C) 2015 by Project Tox + + 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 "documentcache.h" +#include "customtextdocument.h" + +DocumentCache DocumentCache::instance; + +DocumentCache::~DocumentCache() +{ + while(!documents.isEmpty()) + delete documents.pop(); +} + +QTextDocument* DocumentCache::pop() +{ + if(documents.empty()) + documents.push(new CustomTextDocument); + + return documents.pop(); +} + +void DocumentCache::push(QTextDocument *doc) +{ + documents.push(doc); +} + +DocumentCache &DocumentCache::getInstance() +{ + return instance; +} diff --git a/src/chatlog/documentcache.h b/src/chatlog/documentcache.h new file mode 100644 index 000000000..7ff64f9d4 --- /dev/null +++ b/src/chatlog/documentcache.h @@ -0,0 +1,43 @@ +/* + Copyright (C) 2015 by Project Tox + + 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 DOCUMENTCACHE_H +#define DOCUMENTCACHE_H + +#include + +class QTextDocument; + +class DocumentCache +{ +public: + ~DocumentCache(); + static DocumentCache& getInstance(); + + QTextDocument* pop(); + void push(QTextDocument* doc); + +protected: + DocumentCache() {} + DocumentCache(DocumentCache&) = delete; + DocumentCache& operator=(const DocumentCache&) = delete; + +private: + QStack documents; + static DocumentCache instance; +}; + +#endif // DOCUMENTCACHE_H diff --git a/src/chatlog/pixmapcache.cpp b/src/chatlog/pixmapcache.cpp new file mode 100644 index 000000000..2541cd903 --- /dev/null +++ b/src/chatlog/pixmapcache.cpp @@ -0,0 +1,41 @@ +/* + Copyright (C) 2015 by Project Tox + + 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 "pixmapcache.h" + +PixmapCache PixmapCache::instance; + +QPixmap PixmapCache::get(const QString &filename, QSize size) +{ + auto itr = cache.find(filename); + + if(itr == cache.end()) + { + QIcon icon; + icon.addFile(filename); + + cache.insert(filename, icon); + return icon.pixmap(size); + } + + return itr.value().pixmap(size); +} + +PixmapCache &PixmapCache::getInstance() +{ + return instance; +} + diff --git a/src/chatlog/pixmapcache.h b/src/chatlog/pixmapcache.h new file mode 100644 index 000000000..6ff70b20c --- /dev/null +++ b/src/chatlog/pixmapcache.h @@ -0,0 +1,40 @@ +/* + Copyright (C) 2015 by Project Tox + + 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 ICONCACHE_H +#define ICONCACHE_H + +#include +#include +#include + +class PixmapCache +{ +public: + QPixmap get(const QString& filename, QSize size); + static PixmapCache& getInstance(); + +protected: + PixmapCache() {} + PixmapCache(PixmapCache&) = delete; + PixmapCache& operator=(const PixmapCache&) = delete; + +private: + QHash cache; + static PixmapCache instance; +}; + +#endif // ICONCACHE_H From e67db1575dcc7a3ef87da3a576f6601a7bd271cd Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 2 Feb 2015 14:50:06 +0100 Subject: [PATCH 155/203] fixup! Merge branch 'master' into chatlog_v3_1 --- src/chatlog/chatmessage.cpp | 2 +- src/widget/form/chatform.cpp | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 67eacc72b..a13199867 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -197,7 +197,7 @@ QString ChatMessage::detectQuotes(const QString& str) QString quotedText; for (int i=0;i"; else quotedText += messageLines[i]; diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index a3e0b598e..c37daae6d 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -26,7 +26,6 @@ #include "chatform.h" #include "src/core.h" #include "src/friend.h" -#include "src/filetransferinstance.h" #include "src/historykeeper.h" #include "src/misc/style.h" #include "src/misc/settings.h" @@ -34,16 +33,11 @@ #include "src/widget/callconfirmwidget.h" #include "src/widget/friendwidget.h" #include "src/widget/netcamview.h" -#include "src/widget/chatareawidget.h" #include "src/widget/form/loadhistorydialog.h" #include "src/widget/tool/chattextedit.h" -#include "src/widget/tool/chatactions/filetransferaction.h" #include "src/widget/widget.h" #include "src/widget/maskablepixmapwidget.h" #include "src/widget/croppinglabel.h" -#include "src/misc/style.h" -#include "src/misc/settings.h" -#include "src/misc/cstring.h" #include "src/chatlog/chatmessage.h" #include "src/chatlog/content/filetransferwidget.h" #include "src/chatlog/chatlinecontentproxy.h" From 39b2771b8dfb70c3e7b5438f8c00285b60f93ab8 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 2 Feb 2015 15:05:27 +0100 Subject: [PATCH 156/203] tweaked ChatLog::getSelectedText --- src/chatlog/chatlog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index f1c665d9d..0c636c4ee 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -458,7 +458,7 @@ QString ChatLog::getSelectedText() const if(lastSender != lines[i]->content[0]->getText() && !lines[i]->content[0]->getText().isEmpty()) { //author changed - out += lines[i]->content[0]->getText() + ":\n"; + out += QString(out.isEmpty() ? "%1:\n" : "\n%1:\n").arg(lines[i]->content[0]->getText()); lastSender = lines[i]->content[0]->getText(); } From 8d7a32f4ec014ebe2d723519a540ce0db6fc498f Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 2 Feb 2015 18:11:29 +0100 Subject: [PATCH 157/203] selection rect: change color on focus-in/out, action cleanup --- src/chatlog/chatlog.cpp | 24 ++++++++++++++++++++---- src/chatlog/chatlog.h | 8 ++++++-- src/widget/form/genericchatform.cpp | 3 --- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 0c636c4ee..3f1e96a50 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -56,15 +56,15 @@ ChatLog::ChatLog(QWidget* parent) setBackgroundBrush(QBrush(Qt::white, Qt::SolidPattern)); // The selection rect for multi-line selection - const QColor selGraphColor = QColor(166,225,255); - selGraphItem = scene->addRect(0,0,0,0,selGraphColor.darker(120),selGraphColor); + selGraphItem = scene->addRect(0,0,0,0,selectionRectColor.darker(120),selectionRectColor); selGraphItem->setZValue(-1.0); // behind all other items // copy action (ie. Ctrl+C) - QAction* copyAction = new QAction(this); + copyAction = new QAction(this); copyAction->setIcon(QIcon::fromTheme("edit-copy")); copyAction->setText(tr("Copy")); copyAction->setShortcut(QKeySequence::Copy); + copyAction->setEnabled(false); connect(copyAction, &QAction::triggered, this, [this](bool) { copySelectedText(); }); addAction(copyAction); @@ -106,6 +106,7 @@ void ChatLog::clearSelection() selClickedRow = -1; selectionMode = None; + copyAction->setEnabled(false); updateMultiSelectionRect(); } @@ -213,6 +214,7 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) content->selectionStarted(sceneClickPos); selectionMode = Precise; + copyAction->setEnabled(true); // ungrab mouse grabber if(scene->mouseGrabberItem()) @@ -225,6 +227,7 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) selLastRow = selClickedRow; selectionMode = Multi; + copyAction->setEnabled(true); } } @@ -563,6 +566,7 @@ void ChatLog::selectAll() selFirstRow = 0; selLastRow = lines.size()-1; + copyAction->setEnabled(true); updateMultiSelectionRect(); } @@ -733,9 +737,21 @@ void ChatLog::onWorkerTimeout() } } -void ChatLog::showEvent(QShowEvent *) +void ChatLog::showEvent(QShowEvent*) { // Empty. // The default implementation calls centerOn - for some reason - causing // the scrollbar to move. } + +void ChatLog::focusInEvent(QFocusEvent* ev) +{ + QGraphicsView::focusInEvent(ev); + selGraphItem->setBrush(QBrush(selectionRectColor)); +} + +void ChatLog::focusOutEvent(QFocusEvent* ev) +{ + QGraphicsView::focusOutEvent(ev); + selGraphItem->setBrush(QBrush(selectionRectColor.lighter(120))); +} diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 611900fbc..837049903 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -79,8 +79,10 @@ protected: virtual void mouseReleaseEvent(QMouseEvent* ev); virtual void mouseMoveEvent(QMouseEvent* ev); virtual void scrollContentsBy(int dx, int dy); - virtual void resizeEvent(QResizeEvent *ev); - virtual void showEvent(QShowEvent *); + virtual void resizeEvent(QResizeEvent* ev); + virtual void showEvent(QShowEvent*); + virtual void focusInEvent(QFocusEvent* ev); + virtual void focusOutEvent(QFocusEvent* ev); void updateMultiSelectionRect(); void updateTypingNotification(); @@ -105,6 +107,7 @@ private: Down, }; + QAction* copyAction = nullptr; QGraphicsScene* scene = nullptr; QGraphicsScene* busyScene = nullptr; QVector lines; @@ -117,6 +120,7 @@ private: int selClickedCol = -1; int selFirstRow = -1; int selLastRow = -1; + QColor selectionRectColor = QColor(166,225,255); SelectionMode selectionMode = None; QPointF clickPos; QGraphicsRectItem* selGraphItem = nullptr; diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index 77aba3d7e..de415fccd 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -200,9 +200,6 @@ void GenericChatForm::onChatContextMenuRequested(QPoint pos) QWidget* sender = (QWidget*)QObject::sender(); pos = sender->mapToGlobal(pos); - //copy action - menu.actions().first()->setEnabled(chatWidget->hasTextToBeCopied()); - menu.exec(pos); } From 5c01f1585bb10cffb8ca6032efb41097028eb15f Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 3 Feb 2015 10:33:46 +0100 Subject: [PATCH 158/203] change color for precise selection on focus-in/out --- src/chatlog/chatline.cpp | 6 ++++++ src/chatlog/chatline.h | 1 + src/chatlog/chatlinecontent.cpp | 5 +++++ src/chatlog/chatlinecontent.h | 1 + src/chatlog/chatlog.cpp | 18 ++++++++++++++++-- src/chatlog/chatlog.h | 2 +- src/chatlog/content/text.cpp | 11 +++++++++-- src/chatlog/content/text.h | 2 ++ 8 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index e7f506a81..4dff5f75e 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -109,6 +109,12 @@ void ChatLine::selectionCleared() c->selectionCleared(); } +void ChatLine::selectionFocusChanged(bool focusIn) +{ + for(ChatLineContent* c : content) + c->selectionFocusChanged(focusIn); +} + int ChatLine::getColumnCount() { return content.size(); diff --git a/src/chatlog/chatline.h b/src/chatlog/chatline.h index 842fb4b61..0f7405cff 100644 --- a/src/chatlog/chatline.h +++ b/src/chatlog/chatline.h @@ -71,6 +71,7 @@ public: void addToScene(QGraphicsScene* scene); void setVisible(bool visible); void selectionCleared(); + void selectionFocusChanged(bool focusIn); int getColumnCount(); int getRow() const; diff --git a/src/chatlog/chatlinecontent.cpp b/src/chatlog/chatlinecontent.cpp index 9b163d4fd..ad1ce2de0 100644 --- a/src/chatlog/chatlinecontent.cpp +++ b/src/chatlog/chatlinecontent.cpp @@ -57,6 +57,11 @@ void ChatLineContent::selectionDoubleClick(QPointF) } +void ChatLineContent::selectionFocusChanged(bool) +{ + +} + bool ChatLineContent::isOverSelection(QPointF) const { return false; diff --git a/src/chatlog/chatlinecontent.h b/src/chatlog/chatlinecontent.h index 674182185..49e21b611 100644 --- a/src/chatlog/chatlinecontent.h +++ b/src/chatlog/chatlinecontent.h @@ -39,6 +39,7 @@ public: virtual void selectionStarted(QPointF scenePos); virtual void selectionCleared(); virtual void selectionDoubleClick(QPointF scenePos); + virtual void selectionFocusChanged(bool focusIn); virtual bool isOverSelection(QPointF scenePos) const; virtual QString getSelectedText() const; diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 3f1e96a50..1cdc4fea3 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -747,11 +747,25 @@ void ChatLog::showEvent(QShowEvent*) void ChatLog::focusInEvent(QFocusEvent* ev) { QGraphicsView::focusInEvent(ev); - selGraphItem->setBrush(QBrush(selectionRectColor)); + + if(selectionMode != None) + { + selGraphItem->setBrush(QBrush(selectionRectColor)); + + for(int i=selFirstRow; i<=selLastRow; ++i) + lines[i]->selectionFocusChanged(true); + } } void ChatLog::focusOutEvent(QFocusEvent* ev) { QGraphicsView::focusOutEvent(ev); - selGraphItem->setBrush(QBrush(selectionRectColor.lighter(120))); + + if(selectionMode != None) + { + selGraphItem->setBrush(QBrush(selectionRectColor.lighter(120))); + + for(int i=selFirstRow; i<=selLastRow; ++i) + lines[i]->selectionFocusChanged(false); + } } diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 837049903..ffc1bf876 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -120,7 +120,7 @@ private: int selClickedCol = -1; int selFirstRow = -1; int selLastRow = -1; - QColor selectionRectColor = QColor(166,225,255); + QColor selectionRectColor = QColor::fromRgbF(0.23, 0.68, 0.91).lighter(150); SelectionMode selectionMode = None; QPointF clickPos; QGraphicsRectItem* selGraphItem = nullptr; diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index ce58cf9f7..6119f6100 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -126,6 +126,12 @@ void Text::selectionDoubleClick(QPointF scenePos) update(); } +void Text::selectionFocusChanged(bool focusIn) +{ + selectionHasFocus = focusIn; + update(); +} + bool Text::isOverSelection(QPointF scenePos) const { int cur = cursorFromPos(scenePos); @@ -160,8 +166,9 @@ void Text::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWid sel.cursor.setPosition(getSelectionEnd(), QTextCursor::KeepAnchor); } - sel.format.setBackground(QApplication::palette().color(QPalette::Highlight)); - sel.format.setForeground(QApplication::palette().color(QPalette::HighlightedText)); + const QColor selectionColor = QColor::fromRgbF(0.23, 0.68, 0.91); + sel.format.setBackground(selectionColor.lighter(selectionHasFocus ? 100 : 160)); + sel.format.setForeground(selectionHasFocus ? Qt::white : Qt::black); ctx.selections.append(sel); // draw text diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index beaa1cecf..1f15107ac 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -39,6 +39,7 @@ public: virtual void selectionStarted(QPointF scenePos) override; virtual void selectionCleared() override; virtual void selectionDoubleClick(QPointF scenePos) override; + virtual void selectionFocusChanged(bool focusIn) override; virtual bool isOverSelection(QPointF scenePos) const override; virtual QString getSelectedText() const override; @@ -75,6 +76,7 @@ private: bool keepInMemory = false; bool elide = false; bool dirty = false; + bool selectionHasFocus = true; int selectionEnd = -1; int selectionAnchor = -1; qreal ascent = 0.0; From 0af05929f723e15ab540c4276a665a68dba1b724 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 3 Feb 2015 16:15:51 +0100 Subject: [PATCH 159/203] fixup! Merge branch 'master' into chatlog_v3_1 --- src/widget/widget.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index 382b4af11..791eac075 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -696,9 +696,6 @@ void Widget::addFriend(int friendId, const QString &userId) QLayout* layout = contactListWidget->getFriendLayout(Status::Offline); layout->addWidget(newfriend->getFriendWidget()); - if (Settings::getInstance().getEnableLogging()) - newfriend->getChatForm()->loadHistory(QDateTime::currentDateTime().addDays(-7), true); - connect(settingsWidget, &SettingsWidget::compactToggled, newfriend->getFriendWidget(), &GenericChatroomWidget::onCompactChanged); connect(newfriend->getFriendWidget(), SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), this, SLOT(onChatroomWidgetClicked(GenericChatroomWidget*))); connect(newfriend->getFriendWidget(), SIGNAL(removeFriend(int)), this, SLOT(removeFriend(int))); From e4c52e6118760fec29054bd40b67ca449e5a8c7b Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 3 Feb 2015 16:17:37 +0100 Subject: [PATCH 160/203] use QPainter::setClipRect --- src/chatlog/content/image.cpp | 2 ++ src/chatlog/content/notificationicon.cpp | 2 ++ src/chatlog/content/spinner.cpp | 2 ++ src/chatlog/content/text.cpp | 2 ++ 4 files changed, 8 insertions(+) diff --git a/src/chatlog/content/image.cpp b/src/chatlog/content/image.cpp index 699fbeab9..14856afc3 100644 --- a/src/chatlog/content/image.cpp +++ b/src/chatlog/content/image.cpp @@ -37,6 +37,8 @@ qreal Image::getAscent() const void Image::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { + painter->setClipRect(boundingRect()); + painter->setRenderHint(QPainter::SmoothPixmapTransform); painter->translate(-size.width() / 2.0, -size.height() / 2.0); painter->drawPixmap(0, 0, pmap); diff --git a/src/chatlog/content/notificationicon.cpp b/src/chatlog/content/notificationicon.cpp index 887247761..e454fc721 100644 --- a/src/chatlog/content/notificationicon.cpp +++ b/src/chatlog/content/notificationicon.cpp @@ -42,6 +42,8 @@ QRectF NotificationIcon::boundingRect() const void NotificationIcon::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { + painter->setClipRect(boundingRect()); + painter->setRenderHint(QPainter::SmoothPixmapTransform); painter->translate(-size.width() / 2.0, -size.height() / 2.0); diff --git a/src/chatlog/content/spinner.cpp b/src/chatlog/content/spinner.cpp index 262b4a35b..cfa29fe93 100644 --- a/src/chatlog/content/spinner.cpp +++ b/src/chatlog/content/spinner.cpp @@ -40,6 +40,8 @@ QRectF Spinner::boundingRect() const void Spinner::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { + painter->setClipRect(boundingRect()); + QTransform rotMat; rotMat.translate(size.width() / 2.0, size.height() / 2.0); rotMat.rotate(rot); diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 6119f6100..838e84600 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -155,6 +155,8 @@ void Text::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWid { if(doc) { + painter->setClipRect(boundingRect()); + // draw selection QAbstractTextDocumentLayout::PaintContext ctx; QAbstractTextDocumentLayout::Selection sel; From bc21af4fa29a7c10445324484e290b9deb5f1dd1 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 3 Feb 2015 17:28:42 +0100 Subject: [PATCH 161/203] ChatLog: don't start the resize worker if the width doesn't change --- src/chatlog/chatlog.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 1cdc4fea3..d622e0834 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -614,9 +614,19 @@ void ChatLog::scrollContentsBy(int dx, int dy) void ChatLog::resizeEvent(QResizeEvent* ev) { - startResizeWorker(); + bool stb = stickToBottom(); + + if(ev->size().width() != ev->oldSize().width()) + { + startResizeWorker(); + stb = false; // let the resize worker handle it + } + QGraphicsView::resizeEvent(ev); + if(stb) + scrollToBottom(); + updateBusyNotification(); } From 7321127794cb3de8453b47b2255c91f5c9ad802a Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 3 Feb 2015 22:06:31 +0100 Subject: [PATCH 162/203] set the correct wrap mode --- src/chatlog/content/text.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 838e84600..fd7f2f0ef 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -229,16 +229,14 @@ void Text::regenerate() if(dirty) { if(!elide) - { doc->setHtml(text); - } else - { - QTextOption opt; - opt.setWrapMode(QTextOption::NoWrap); - doc->setDefaultTextOption(opt); doc->setPlainText(elidedText); - } + + // wrap mode + QTextOption opt; + opt.setWrapMode(elide ? QTextOption::NoWrap : QTextOption::WrapAtWordBoundaryOrAnywhere); + doc->setDefaultTextOption(opt); // width & layout doc->setTextWidth(width); From 09291bad52fb84fd716638fccdfda5a429562589 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 4 Feb 2015 09:40:23 +0100 Subject: [PATCH 163/203] fix crash on exit --- src/chatlog/documentcache.cpp | 6 +++--- src/chatlog/documentcache.h | 1 - src/chatlog/pixmapcache.cpp | 3 +-- src/chatlog/pixmapcache.h | 1 - 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/chatlog/documentcache.cpp b/src/chatlog/documentcache.cpp index 32b25317e..d78301fab 100644 --- a/src/chatlog/documentcache.cpp +++ b/src/chatlog/documentcache.cpp @@ -17,8 +17,6 @@ #include "documentcache.h" #include "customtextdocument.h" -DocumentCache DocumentCache::instance; - DocumentCache::~DocumentCache() { while(!documents.isEmpty()) @@ -35,10 +33,12 @@ QTextDocument* DocumentCache::pop() void DocumentCache::push(QTextDocument *doc) { - documents.push(doc); + if(doc) + documents.push(doc); } DocumentCache &DocumentCache::getInstance() { + static DocumentCache instance; return instance; } diff --git a/src/chatlog/documentcache.h b/src/chatlog/documentcache.h index 7ff64f9d4..f2ea962ce 100644 --- a/src/chatlog/documentcache.h +++ b/src/chatlog/documentcache.h @@ -37,7 +37,6 @@ protected: private: QStack documents; - static DocumentCache instance; }; #endif // DOCUMENTCACHE_H diff --git a/src/chatlog/pixmapcache.cpp b/src/chatlog/pixmapcache.cpp index 2541cd903..e2461704c 100644 --- a/src/chatlog/pixmapcache.cpp +++ b/src/chatlog/pixmapcache.cpp @@ -16,8 +16,6 @@ #include "pixmapcache.h" -PixmapCache PixmapCache::instance; - QPixmap PixmapCache::get(const QString &filename, QSize size) { auto itr = cache.find(filename); @@ -36,6 +34,7 @@ QPixmap PixmapCache::get(const QString &filename, QSize size) PixmapCache &PixmapCache::getInstance() { + static PixmapCache instance; return instance; } diff --git a/src/chatlog/pixmapcache.h b/src/chatlog/pixmapcache.h index 6ff70b20c..d6be4d341 100644 --- a/src/chatlog/pixmapcache.h +++ b/src/chatlog/pixmapcache.h @@ -34,7 +34,6 @@ protected: private: QHash cache; - static PixmapCache instance; }; #endif // ICONCACHE_H From 038a7fcd550d48920dba658c9ef64826b2f0d410 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 4 Feb 2015 14:50:03 +0100 Subject: [PATCH 164/203] add svg to CONFIG (link against the svg module) --- qtox.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qtox.pro b/qtox.pro index 026c8a247..02b3054e0 100644 --- a/qtox.pro +++ b/qtox.pro @@ -20,7 +20,7 @@ # See the COPYING file for more details. -QT += core gui network xml opengl sql +QT += core gui network xml opengl sql svg greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = qtox From 6cf3f9e1c20d4f37b4d3d0dbf599f00eb896803b Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 4 Feb 2015 15:36:26 +0100 Subject: [PATCH 165/203] fix bbox calculation --- src/chatlog/chatline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index 4dff5f75e..1059d63e6 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -126,7 +126,7 @@ void ChatLine::updateBBox() bbox.setWidth(width); for(ChatLineContent* c : content) - bbox.setHeight(qMax(c->sceneBoundingRect().height(), bbox.height())); + bbox.setHeight(qMax(c->sceneBoundingRect().top() - bbox.top() + c->sceneBoundingRect().height(), bbox.height())); } QRectF ChatLine::sceneBoundingRect() const From 633ca9c3ac4f845f7110d30e7436d67c8fe762fe Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 4 Feb 2015 15:36:45 +0100 Subject: [PATCH 166/203] cleanup --- src/chatlog/chatlinecontentproxy.cpp | 9 +++------ src/chatlog/chatlinecontentproxy.h | 1 - 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/chatlog/chatlinecontentproxy.cpp b/src/chatlog/chatlinecontentproxy.cpp index 129f6fe5b..6e33547b3 100644 --- a/src/chatlog/chatlinecontentproxy.cpp +++ b/src/chatlog/chatlinecontentproxy.cpp @@ -17,6 +17,7 @@ #include "chatlinecontentproxy.h" #include #include +#include #include ChatLineContentProxy::ChatLineContentProxy(QWidget* widget, int minWidth, float widthInPercent) @@ -32,19 +33,15 @@ QRectF ChatLineContentProxy::boundingRect() const return proxy->boundingRect(); } -QRectF ChatLineContentProxy::boundingSceneRect() const -{ - return proxy->boundingRect().translated(scenePos()); -} - void ChatLineContentProxy::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { + painter->setClipRect(boundingRect()); proxy->paint(painter, option, widget); } qreal ChatLineContentProxy::getAscent() const { - return proxy->widget()->layout()->contentsMargins().top(); + return 0; } QWidget *ChatLineContentProxy::getWidget() const diff --git a/src/chatlog/chatlinecontentproxy.h b/src/chatlog/chatlinecontentproxy.h index b73fb126a..c7c93209d 100644 --- a/src/chatlog/chatlinecontentproxy.h +++ b/src/chatlog/chatlinecontentproxy.h @@ -26,7 +26,6 @@ public: ChatLineContentProxy(QWidget* widget, int minWidth, float widthInPercent = 1.0f); virtual QRectF boundingRect() const; - virtual QRectF boundingSceneRect() const; virtual void setWidth(qreal width); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); virtual qreal getAscent() const; From 21eb9172d4d6bbd1cabf539eacfc6327569c6e02 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 4 Feb 2015 16:35:36 +0100 Subject: [PATCH 167/203] FTW: circular buttons [feedback wanted] --- ui/fileTransferInstance/arrow_white.svg | 23 +++-- ui/fileTransferInstance/browse.svg | 120 ++++++++++++++++++------ ui/fileTransferInstance/no.svg | 23 +++-- ui/fileTransferInstance/pause.svg | 42 +++++---- ui/fileTransferInstance/yes.svg | 37 +++++++- 5 files changed, 173 insertions(+), 72 deletions(-) diff --git a/ui/fileTransferInstance/arrow_white.svg b/ui/fileTransferInstance/arrow_white.svg index ee2e9fdcd..f7dae07c7 100644 --- a/ui/fileTransferInstance/arrow_white.svg +++ b/ui/fileTransferInstance/arrow_white.svg @@ -1,23 +1,26 @@ - - image/svg+xml \ No newline at end of file + transform="matrix(0,-0.67480649,0.67480649,0,3.9124861,8.4107462)" + points="7.145,0 3.572,6.187 0,0 " /> \ No newline at end of file diff --git a/ui/fileTransferInstance/browse.svg b/ui/fileTransferInstance/browse.svg index 4123ec52c..7196c237a 100644 --- a/ui/fileTransferInstance/browse.svg +++ b/ui/fileTransferInstance/browse.svg @@ -7,12 +7,78 @@ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" width="12" height="12" - id="svg2"> + id="svg2" + inkscape:version="0.91 r13725" + sodipodi:docname="browse.svg"> + + + + + + + + + +
+ - - - - - - - - + id="g7911" + style="stroke:#ffffff;stroke-opacity:1;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;fill:#ffffff"> + + + diff --git a/ui/fileTransferInstance/no.svg b/ui/fileTransferInstance/no.svg index a90227ea6..663714ba4 100644 --- a/ui/fileTransferInstance/no.svg +++ b/ui/fileTransferInstance/no.svg @@ -1,23 +1,26 @@ - - image/svg+xml \ No newline at end of file + transform="matrix(0.61738208,0,0,0.61359309,2.8865417,2.9053432)" + points="5.043,3.351 1.693,0.001 0,1.693 3.35,5.043 0,8.394 1.693,10.086 5.043,6.736 8.395,10.087 10.086,8.394 6.734,5.043 10.086,1.692 8.395,0 " /> \ No newline at end of file diff --git a/ui/fileTransferInstance/pause.svg b/ui/fileTransferInstance/pause.svg index b02c4dd53..c318c12d2 100644 --- a/ui/fileTransferInstance/pause.svg +++ b/ui/fileTransferInstance/pause.svg @@ -1,33 +1,37 @@ - - image/svg+xml \ No newline at end of file + y="0" + x="6.007" + height="9.3999996" + width="2.395" /> \ No newline at end of file diff --git a/ui/fileTransferInstance/yes.svg b/ui/fileTransferInstance/yes.svg index def828488..8ae23425c 100644 --- a/ui/fileTransferInstance/yes.svg +++ b/ui/fileTransferInstance/yes.svg @@ -7,16 +7,45 @@ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" width="12" height="12" viewBox="0 0 11.999999 12" id="Layer_1" - xml:space="preserve">image/svg+xml \ No newline at end of file + style="fill:none;stroke:#ffffff;stroke-width:1.43635464;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + inkscape:connector-curvature="0" /> \ No newline at end of file From 5e4e56778ba93e2048925a5b21e3d7a694b6ad4f Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 4 Feb 2015 17:21:56 +0100 Subject: [PATCH 168/203] FTW: color animation --- src/chatlog/content/filetransferwidget.cpp | 14 ++++++++++++-- src/chatlog/content/filetransferwidget.h | 4 +++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index 03d050db2..30697decf 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) @@ -46,6 +47,12 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) ui->progressLabel->setText("0kiB/s"); ui->etaLabel->setText(""); + colorAnimation = new QPropertyAnimation(this, "color"); + colorAnimation->setDuration(500); + colorAnimation->setEasingCurve(QEasingCurve::OutCubic); + connect(colorAnimation, &QPropertyAnimation::valueChanged, this, [this] { update(); }); + + setProperty("color", Style::getColor(Style::LightGrey)); setColor(Style::getColor(Style::LightGrey), false); connect(Core::getInstance(), &Core::fileTransferInfo, this, &FileTransferWidget::onFileTransferInfo); @@ -108,7 +115,10 @@ void FileTransferWidget::acceptTransfer(const QString &filepath) void FileTransferWidget::setColor(const QColor &c, bool whiteFont) { - color = c; + colorAnimation->setStartValue(property("color").value()); + colorAnimation->setEndValue(c); + colorAnimation->start(); + setProperty("fontColor", whiteFont ? "white" : "black"); setStyleSheet(Style::getStylesheet(":/ui/fileTransferInstance/filetransferWidget.css")); @@ -130,7 +140,7 @@ void FileTransferWidget::paintEvent(QPaintEvent *) // required by Hi-DPI support as border-image doesn't work. QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); - painter.setBrush(QBrush(color)); + painter.setBrush(QBrush(property("color").value())); painter.setPen(Qt::NoPen); qreal s = static_cast(geometry().height()) / static_cast(geometry().width()); diff --git a/src/chatlog/content/filetransferwidget.h b/src/chatlog/content/filetransferwidget.h index 3f00f281f..bf6abcfe6 100644 --- a/src/chatlog/content/filetransferwidget.h +++ b/src/chatlog/content/filetransferwidget.h @@ -19,6 +19,7 @@ #include #include + #include "../chatlinecontent.h" #include "../../corestructs.h" @@ -27,6 +28,7 @@ namespace Ui { class FileTransferWidget; } +class QPropertyAnimation; class QPushButton; class FileTransferWidget : public QWidget @@ -67,7 +69,7 @@ private: ToxFile fileInfo; QTime lastTick; qint64 lastBytesSent = 0; - QColor color; + QPropertyAnimation* colorAnimation = nullptr; static const uint8_t TRANSFER_ROLLING_AVG_COUNT = 4; uint8_t meanIndex = 0; From f5cf9677ae886e21eb17619a9b9f40c5d062bee5 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Thu, 5 Feb 2015 09:59:47 +0100 Subject: [PATCH 169/203] FTW: don't display "Location not writable" if path is empty --- src/chatlog/content/filetransferwidget.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index 30697decf..6bbb56af6 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -100,6 +100,9 @@ void FileTransferWidget::autoAcceptTransfer(const QString &path) void FileTransferWidget::acceptTransfer(const QString &filepath) { + if(filepath.isEmpty()) + return; + //test if writable if(!isFilePathWritable(filepath)) { From 1e2f801dfed2ad6a14bf71bcc943362e72b201c3 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Thu, 5 Feb 2015 10:13:37 +0100 Subject: [PATCH 170/203] Spinner: lowered rotational speed --- src/chatlog/chatmessage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index a13199867..50649b6cd 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -60,7 +60,7 @@ ChatMessage::Ptr ChatMessage::createChatMessage(const QString &sender, const QSt msg->addColumn(new Text(isAction ? "
*
" : sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), isAction ? false : true, sender), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text(text, Style::getFont(Style::Big), false, isAction ? QString("*%1 %2*").arg(sender, rawMessage) : rawMessage), ColumnFormat(1.0, ColumnFormat::VariableSize)); - msg->addColumn(new Spinner(":/ui/chatArea/spinner.svg", QSize(16, 16), 8.0), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + msg->addColumn(new Spinner(":/ui/chatArea/spinner.svg", QSize(16, 16), 4.0), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); if(!date.isNull()) msg->markAsSent(date); From c2ddc91d58e4270acdc1cfcc4557735b0c617d09 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 6 Feb 2015 12:21:13 +0100 Subject: [PATCH 171/203] faster, synchronized spinners --- src/chatlog/chatmessage.cpp | 2 +- src/chatlog/content/spinner.cpp | 5 ++--- src/chatlog/content/spinner.h | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/chatlog/chatmessage.cpp b/src/chatlog/chatmessage.cpp index 50649b6cd..4f4809fe7 100644 --- a/src/chatlog/chatmessage.cpp +++ b/src/chatlog/chatmessage.cpp @@ -60,7 +60,7 @@ ChatMessage::Ptr ChatMessage::createChatMessage(const QString &sender, const QSt msg->addColumn(new Text(isAction ? "
*
" : sender, isMe ? Style::getFont(Style::BigBold) : Style::getFont(Style::Big), isAction ? false : true, sender), ColumnFormat(NAME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); msg->addColumn(new Text(text, Style::getFont(Style::Big), false, isAction ? QString("*%1 %2*").arg(sender, rawMessage) : rawMessage), ColumnFormat(1.0, ColumnFormat::VariableSize)); - msg->addColumn(new Spinner(":/ui/chatArea/spinner.svg", QSize(16, 16), 4.0), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); + msg->addColumn(new Spinner(":/ui/chatArea/spinner.svg", QSize(16, 16), 360.0/1.6), ColumnFormat(TIME_COL_WIDTH, ColumnFormat::FixedSize, ColumnFormat::Right)); if(!date.isNull()) msg->markAsSent(date); diff --git a/src/chatlog/content/spinner.cpp b/src/chatlog/content/spinner.cpp index cfa29fe93..48152cb18 100644 --- a/src/chatlog/content/spinner.cpp +++ b/src/chatlog/content/spinner.cpp @@ -19,6 +19,7 @@ #include #include +#include #include Spinner::Spinner(const QString &img, QSize Size, qreal speed) @@ -44,7 +45,7 @@ void Spinner::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, Q QTransform rotMat; rotMat.translate(size.width() / 2.0, size.height() / 2.0); - rotMat.rotate(rot); + rotMat.rotate(QTime::currentTime().msecsSinceStartOfDay() / 1000.0 * rotSpeed); rotMat.translate(-size.width() / 2.0, -size.height() / 2.0); painter->translate(-size.width() / 2.0, -size.height() / 2.0); @@ -76,8 +77,6 @@ qreal Spinner::getAscent() const void Spinner::timeout() { - rot += rotSpeed; - if(scene()) scene()->invalidate(sceneBoundingRect()); } diff --git a/src/chatlog/content/spinner.h b/src/chatlog/content/spinner.h index 45c3c4e16..c35b5a4a4 100644 --- a/src/chatlog/content/spinner.h +++ b/src/chatlog/content/spinner.h @@ -41,7 +41,6 @@ private slots: private: QSize size; QPixmap pmap; - qreal rot = 0.0; qreal rotSpeed; QTimer timer; From 3c349e29adec7558cc89fb4290b277ced1467fa7 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 6 Feb 2015 13:35:29 +0100 Subject: [PATCH 172/203] cleanup --- src/chatlog/content/spinner.cpp | 9 +++------ ui/chatArea/spinner.svg | 26 ++++++++++++-------------- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/chatlog/content/spinner.cpp b/src/chatlog/content/spinner.cpp index 48152cb18..9f7901b48 100644 --- a/src/chatlog/content/spinner.cpp +++ b/src/chatlog/content/spinner.cpp @@ -43,13 +43,10 @@ void Spinner::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, Q { painter->setClipRect(boundingRect()); - QTransform rotMat; - rotMat.translate(size.width() / 2.0, size.height() / 2.0); - rotMat.rotate(QTime::currentTime().msecsSinceStartOfDay() / 1000.0 * rotSpeed); - rotMat.translate(-size.width() / 2.0, -size.height() / 2.0); + QTransform trans = QTransform().rotate(QTime::currentTime().msecsSinceStartOfDay() / 1000.0 * rotSpeed) + .translate(-size.width()/2.0, -size.height()/2.0); - painter->translate(-size.width() / 2.0, -size.height() / 2.0); - painter->setTransform(rotMat, true); + painter->setTransform(trans, true); painter->setRenderHint(QPainter::SmoothPixmapTransform); painter->drawPixmap(0, 0, pmap); diff --git a/ui/chatArea/spinner.svg b/ui/chatArea/spinner.svg index c5b6d1241..0887474b8 100644 --- a/ui/chatArea/spinner.svg +++ b/ui/chatArea/spinner.svg @@ -1,24 +1,22 @@ - - + width="18" + version="1.1"> + id="filter4418" + color-interpolation-filters="sRGB"> + stdDeviation="0.10811274" + id="feGaussianBlur4420" /> + id="layer1" + transform="translate(0.1875,-1034.3622)"> + transform="translate(0,1034.3622)" + d="M 9,1 C 4.581722,1 1,4.581722 1,9 c 0,4.418278 3.581722,8 8,8 3.600455,0 6.621126,-2.384809 7.625,-5.65625 l -2.09375,0 C 13.6204,13.49724 11.485281,15 9,15 5.6862916,15 3,12.313708 3,9 3,5.6862915 5.6862916,3 9,3 c 2.485281,0 4.6204,1.5027597 5.53125,3.65625 l 2.09375,0 C 15.621126,3.3848094 12.600455,1 9,1 Z" /> From f525fa83f3c08ee342fbf894f42ada771e9dc97c Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 6 Feb 2015 14:02:31 +0100 Subject: [PATCH 173/203] Spinner: fade in --- src/chatlog/content/spinner.cpp | 11 ++++++++++- src/chatlog/content/spinner.h | 4 ++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/chatlog/content/spinner.cpp b/src/chatlog/content/spinner.cpp index 9f7901b48..0f43a22b2 100644 --- a/src/chatlog/content/spinner.cpp +++ b/src/chatlog/content/spinner.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include Spinner::Spinner(const QString &img, QSize Size, qreal speed) @@ -31,6 +32,14 @@ Spinner::Spinner(const QString &img, QSize Size, qreal speed) timer.setInterval(1000/30); // 30Hz timer.setSingleShot(false); + blendAnimation = new QVariantAnimation(this); + blendAnimation->setStartValue(0.0); + blendAnimation->setEndValue(1.0); + blendAnimation->setDuration(350); + blendAnimation->setEasingCurve(QEasingCurve::InCubic); + blendAnimation->start(QAbstractAnimation::DeleteWhenStopped); + connect(blendAnimation, &QVariantAnimation::valueChanged, this, [this](const QVariant& val) { alpha = val.toDouble(); }); + QObject::connect(&timer, &QTimer::timeout, this, &Spinner::timeout); } @@ -45,7 +54,7 @@ void Spinner::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, Q QTransform trans = QTransform().rotate(QTime::currentTime().msecsSinceStartOfDay() / 1000.0 * rotSpeed) .translate(-size.width()/2.0, -size.height()/2.0); - + painter->setOpacity(alpha); painter->setTransform(trans, true); painter->setRenderHint(QPainter::SmoothPixmapTransform); painter->drawPixmap(0, 0, pmap); diff --git a/src/chatlog/content/spinner.h b/src/chatlog/content/spinner.h index c35b5a4a4..cdec722e1 100644 --- a/src/chatlog/content/spinner.h +++ b/src/chatlog/content/spinner.h @@ -23,6 +23,8 @@ #include #include +class QVariantAnimation; + class Spinner : public QObject, public ChatLineContent { Q_OBJECT @@ -43,6 +45,8 @@ private: QPixmap pmap; qreal rotSpeed; QTimer timer; + qreal alpha = 0.0; + QVariantAnimation* blendAnimation; }; From b9dcb3bd9b449da99bb9dfb9aeef4ada353be51b Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 6 Feb 2015 16:12:24 +0100 Subject: [PATCH 174/203] cleanup --- src/chatlog/content/text.cpp | 6 +++--- src/chatlog/documentcache.cpp | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index fd7f2f0ef..8d96280e9 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -222,12 +222,13 @@ void Text::regenerate() if(!doc) { doc = DocumentCache::getInstance().pop(); - doc->setDefaultFont(defFont); dirty = true; } if(dirty) { + doc->setDefaultFont(defFont); + if(!elide) doc->setHtml(text); else @@ -238,9 +239,8 @@ void Text::regenerate() opt.setWrapMode(elide ? QTextOption::NoWrap : QTextOption::WrapAtWordBoundaryOrAnywhere); doc->setDefaultTextOption(opt); - // width & layout + // width doc->setTextWidth(width); - doc->documentLayout()->update(); // update ascent if(doc->firstBlock().layout()->lineCount() > 0) diff --git a/src/chatlog/documentcache.cpp b/src/chatlog/documentcache.cpp index d78301fab..093fa7ece 100644 --- a/src/chatlog/documentcache.cpp +++ b/src/chatlog/documentcache.cpp @@ -34,7 +34,10 @@ QTextDocument* DocumentCache::pop() void DocumentCache::push(QTextDocument *doc) { if(doc) + { + doc->clear(); documents.push(doc); + } } DocumentCache &DocumentCache::getInstance() From 6b605fbdc3a3dfd253ad9e85b9a1038fe91aed34 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 7 Feb 2015 14:02:40 +0100 Subject: [PATCH 175/203] FTW: Replaced QPropertyAnimation by QVariantAnimation --- src/chatlog/content/filetransferwidget.cpp | 15 +++++++++------ src/chatlog/content/filetransferwidget.h | 5 +++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index 6bbb56af6..f6196ebf1 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) @@ -34,6 +34,7 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) , ui(new Ui::FileTransferWidget) , fileInfo(file) , lastTick(QTime::currentTime()) + , color(Style::getColor(Style::LightGrey)) { ui->setupUi(this); @@ -47,12 +48,14 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) ui->progressLabel->setText("0kiB/s"); ui->etaLabel->setText(""); - colorAnimation = new QPropertyAnimation(this, "color"); + colorAnimation = new QVariantAnimation(this); colorAnimation->setDuration(500); colorAnimation->setEasingCurve(QEasingCurve::OutCubic); - connect(colorAnimation, &QPropertyAnimation::valueChanged, this, [this] { update(); }); + connect(colorAnimation, &QVariantAnimation::valueChanged, this, [this](const QVariant& val) { + color = val.value(); + update(); + }); - setProperty("color", Style::getColor(Style::LightGrey)); setColor(Style::getColor(Style::LightGrey), false); connect(Core::getInstance(), &Core::fileTransferInfo, this, &FileTransferWidget::onFileTransferInfo); @@ -118,7 +121,7 @@ void FileTransferWidget::acceptTransfer(const QString &filepath) void FileTransferWidget::setColor(const QColor &c, bool whiteFont) { - colorAnimation->setStartValue(property("color").value()); + colorAnimation->setStartValue(color); colorAnimation->setEndValue(c); colorAnimation->start(); @@ -143,7 +146,7 @@ void FileTransferWidget::paintEvent(QPaintEvent *) // required by Hi-DPI support as border-image doesn't work. QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); - painter.setBrush(QBrush(property("color").value())); + painter.setBrush(QBrush(color)); painter.setPen(Qt::NoPen); qreal s = static_cast(geometry().height()) / static_cast(geometry().width()); diff --git a/src/chatlog/content/filetransferwidget.h b/src/chatlog/content/filetransferwidget.h index bf6abcfe6..395932355 100644 --- a/src/chatlog/content/filetransferwidget.h +++ b/src/chatlog/content/filetransferwidget.h @@ -28,7 +28,7 @@ namespace Ui { class FileTransferWidget; } -class QPropertyAnimation; +class QVariantAnimation; class QPushButton; class FileTransferWidget : public QWidget @@ -69,7 +69,8 @@ private: ToxFile fileInfo; QTime lastTick; qint64 lastBytesSent = 0; - QPropertyAnimation* colorAnimation = nullptr; + QVariantAnimation* colorAnimation = nullptr; + QColor color; static const uint8_t TRANSFER_ROLLING_AVG_COUNT = 4; uint8_t meanIndex = 0; From d008b53c6f2b668c23f100fbabea32a32cc9e6a7 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 7 Feb 2015 14:33:45 +0100 Subject: [PATCH 176/203] FTW: Use KeepAspectRatioByExpanding --- src/chatlog/content/filetransferwidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index f6196ebf1..3f8efea59 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -380,8 +380,8 @@ void FileTransferWidget::showPreview(const QString &filename) if(previewExtensions.contains(QFileInfo(filename).suffix())) { - //QPixmap pmap = QPixmap(filename).scaled(QSize(ui->previewLabel->maximumWidth(), maximumHeight()), Qt::KeepAspectRatio, Qt::SmoothTransformation); - QPixmap pmap = QPixmap(filename).scaledToWidth(ui->previewLabel->maximumWidth(), Qt::SmoothTransformation); + const int size = qMax(ui->previewLabel->width(), ui->previewLabel->height()); + QPixmap pmap = QPixmap(filename).scaled(QSize(size, size), Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); ui->previewLabel->setPixmap(pmap); ui->previewLabel->show(); } From a8acb05c52249ce55e9e8081e2ed3a55e4c34225 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 7 Feb 2015 14:38:12 +0100 Subject: [PATCH 177/203] FTW: Don't fire an animation if start- and endcolor are the same --- src/chatlog/content/filetransferwidget.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index 3f8efea59..2cf302a4d 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -121,9 +121,12 @@ void FileTransferWidget::acceptTransfer(const QString &filepath) void FileTransferWidget::setColor(const QColor &c, bool whiteFont) { - colorAnimation->setStartValue(color); - colorAnimation->setEndValue(c); - colorAnimation->start(); + if(c != color) + { + colorAnimation->setStartValue(color); + colorAnimation->setEndValue(c); + colorAnimation->start(); + } setProperty("fontColor", whiteFont ? "white" : "black"); From 887f0213230827fe3a050a0e9bff98909891f0a7 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 7 Feb 2015 14:38:56 +0100 Subject: [PATCH 178/203] FTW: Slightly increased height --- src/chatlog/content/filetransferwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index 2cf302a4d..f1179875d 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -70,7 +70,7 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) if(fileInfo.direction == ToxFile::SENDING) showPreview(fileInfo.filePath); - setFixedHeight(60); + setFixedHeight(64); } FileTransferWidget::~FileTransferWidget() From 719481b0409e28d45d3fbb643bd77d8609b37e61 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 7 Feb 2015 17:37:04 +0100 Subject: [PATCH 179/203] fix actions not triggering reliably + ctrl+insert shortcut on linux --- src/chatlog/chatlog.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index d622e0834..829b29aa9 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -25,6 +25,7 @@ #include #include #include +#include template T clamp(T x, T min, T max) @@ -65,15 +66,21 @@ ChatLog::ChatLog(QWidget* parent) copyAction->setText(tr("Copy")); copyAction->setShortcut(QKeySequence::Copy); copyAction->setEnabled(false); - connect(copyAction, &QAction::triggered, this, [this](bool) { copySelectedText(); }); + connect(copyAction, &QAction::triggered, this, [this]() { copySelectedText(); }); addAction(copyAction); +#ifdef Q_OS_LINUX + // Ctrl+Insert shortcut + QShortcut* copyCtrlInsShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Insert), this); + connect(copyCtrlInsShortcut, &QShortcut::activated, this, [this]() { copySelectedText(); }); +#endif + // select all action (ie. Ctrl+A) QAction* selectAllAction = new QAction(this); selectAllAction->setIcon(QIcon::fromTheme("edit-select-all")); selectAllAction->setText(tr("Select all")); selectAllAction->setShortcut(QKeySequence::SelectAll); - connect(selectAllAction, &QAction::triggered, this, [this](bool) { selectAll(); }); + connect(selectAllAction, &QAction::triggered, this, [this]() { selectAll(); }); addAction(selectAllAction); // This timer is used to scroll the view while the user is From 2ac86b58e0f5e74a7224e86f3830122f47ad3938 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 7 Feb 2015 17:39:56 +0100 Subject: [PATCH 180/203] do not change clipboard content if selected text is null --- src/chatlog/chatlog.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 829b29aa9..673f6cb4e 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -520,9 +520,10 @@ void ChatLog::clear() void ChatLog::copySelectedText() const { QString text = getSelectedText(); - QClipboard* clipboard = QApplication::clipboard(); - clipboard->setText(text); + + if(clipboard && !text.isNull()) + clipboard->setText(text); } void ChatLog::setBusyNotification(ChatLine::Ptr notification) From 794c23a81ac1046bee898cf1e72bd641eb2335c5 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 7 Feb 2015 18:49:38 +0100 Subject: [PATCH 181/203] Merge branch 'master' into chatlog_v3_1 --- src/offlinemsgengine.cpp | 7 +++---- src/offlinemsgengine.h | 7 ++++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/offlinemsgengine.cpp b/src/offlinemsgengine.cpp index bfb6bb04f..cdbbbb9e5 100644 --- a/src/offlinemsgengine.cpp +++ b/src/offlinemsgengine.cpp @@ -50,15 +50,14 @@ void OfflineMsgEngine::dischargeReceipt(int receipt) if (msgIt != undeliveredMsgs.end()) { HistoryKeeper::getInstance()->markAsSent(mID); - msgIt.value().msg->markAsSent(); - msgIt.value().msg->featureUpdate(); + msgIt.value().msg->markAsSent(QDateTime::currentDateTime()); undeliveredMsgs.erase(msgIt); } receipts.erase(it); } } -void OfflineMsgEngine::registerReceipt(int receipt, int messageID, MessageActionPtr msg, const QDateTime ×tamp) +void OfflineMsgEngine::registerReceipt(int receipt, int messageID, ChatMessage::Ptr msg, const QDateTime ×tamp) { QMutexLocker ml(&mutex); @@ -89,7 +88,7 @@ void OfflineMsgEngine::deliverOfflineMsgs() registerReceipt(iter.value().receipt, iter.key(), iter.value().msg, iter.value().timestamp); continue; } - QString messageText = iter.value().msg->getRawMessage(); + QString messageText = iter.value().msg->toString(); int rec; if (iter.value().msg->isAction()) rec = Core::getInstance()->sendAction(f->getFriendID(), messageText); diff --git a/src/offlinemsgengine.h b/src/offlinemsgengine.h index 46e7639da..f9175b851 100644 --- a/src/offlinemsgengine.h +++ b/src/offlinemsgengine.h @@ -21,7 +21,8 @@ #include #include #include -#include "src/widget/tool/chatactions/messageaction.h" +#include +#include "src/chatlog/chatmessage.h" struct Friend; class QTimer; @@ -34,7 +35,7 @@ public: virtual ~OfflineMsgEngine(); void dischargeReceipt(int receipt); - void registerReceipt(int receipt, int messageID, MessageActionPtr msg, const QDateTime ×tamp = QDateTime::currentDateTime()); + void registerReceipt(int receipt, int messageID, ChatMessage::Ptr msg, const QDateTime ×tamp = QDateTime::currentDateTime()); public slots: void deliverOfflineMsgs(); @@ -43,7 +44,7 @@ public slots: private: struct MsgPtr { - MessageActionPtr msg; + ChatMessage::Ptr msg; QDateTime timestamp; int receipt; }; From a2cf91cb364e786e6e252fbd957607ba7462f50f Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 7 Feb 2015 18:52:00 +0100 Subject: [PATCH 182/203] Text: documentLayout()->update() --- src/chatlog/content/text.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 8d96280e9..7073f2060 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -241,6 +241,7 @@ void Text::regenerate() // width doc->setTextWidth(width); + doc->documentLayout()->update(); // update ascent if(doc->firstBlock().layout()->lineCount() > 0) From 2dc79a80bcd2757b022e806c4607c71bb2578073 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 7 Feb 2015 22:40:24 +0100 Subject: [PATCH 183/203] add timestamp to copied text (issue #4) --- src/chatlog/chatlog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 673f6cb4e..979ba0c38 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -468,7 +468,7 @@ QString ChatLog::getSelectedText() const if(lastSender != lines[i]->content[0]->getText() && !lines[i]->content[0]->getText().isEmpty()) { //author changed - out += QString(out.isEmpty() ? "%1:\n" : "\n%1:\n").arg(lines[i]->content[0]->getText()); + out += QString(out.isEmpty() ? "[%2] %1:\n" : "\n[%2] %1:\n").arg(lines[i]->content[0]->getText(), lines[i]->content[2]->getText()); lastSender = lines[i]->content[0]->getText(); } From 624b73edc7d89c79d83bd46f4ca7d2e01cb50fe6 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 7 Feb 2015 22:55:42 +0100 Subject: [PATCH 184/203] clear previous id on action (issue #7) --- src/widget/form/genericchatform.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp index de415fccd..8c2fd3fb0 100644 --- a/src/widget/form/genericchatform.cpp +++ b/src/widget/form/genericchatform.cpp @@ -212,12 +212,15 @@ ChatMessage::Ptr GenericChatForm::addMessage(const ToxID& author, const QString if(isAction) { msg = ChatMessage::createChatMessage(authorStr, message, true, false, false); + previousId.clear(); } else { msg = ChatMessage::createChatMessage(authorStr, message, false, false, author.isMine()); if(author == previousId) msg->hideSender(); + + previousId = author; } insertChatMessage(msg); @@ -225,8 +228,6 @@ ChatMessage::Ptr GenericChatForm::addMessage(const ToxID& author, const QString if(isSent) msg->markAsSent(datetime); - previousId = author; - return msg; } From 5ec3a2db85dd1c69a21989fd096a3c154c4a567c Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 8 Feb 2015 10:11:55 +0100 Subject: [PATCH 185/203] Fix ownership problem (issue #8) --- src/chatlog/chatlog.cpp | 11 +++++++++++ src/chatlog/chatlog.h | 1 + 2 files changed, 12 insertions(+) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 979ba0c38..4d3698cac 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -99,6 +99,17 @@ ChatLog::ChatLog(QWidget* parent) connect(workerTimer, &QTimer::timeout, this, &ChatLog::onWorkerTimeout); } +ChatLog::~ChatLog() +{ + // Drop ownership of items of type ChatLineContentType + // as they are owned by ChatLine + for(QGraphicsItem* item : items()) + { + if(item->type() == ChatLineContent::ChatLineContentType) + scene->removeItem(item); + } +} + void ChatLog::clearSelection() { if(selectionMode == None) diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index ffc1bf876..0ab495e4d 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -36,6 +36,7 @@ class ChatLog : public QGraphicsView Q_OBJECT public: explicit ChatLog(QWidget* parent = 0); + virtual ~ChatLog(); void insertChatlineAtBottom(ChatLine::Ptr l); void insertChatlineOnTop(ChatLine::Ptr l); From e86b03b4f7a0efbc508f54a12e7cebd52c8a3b76 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 8 Feb 2015 10:32:52 +0100 Subject: [PATCH 186/203] add copy to selection buffer (middle mouse-button issue #6) --- src/chatlog/chatlog.cpp | 14 ++++++++++++-- src/chatlog/chatlog.h | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 4d3698cac..10e600490 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -180,6 +180,16 @@ void ChatLog::mousePressEvent(QMouseEvent* ev) if(!isOverSelection(scenePos)) clearSelection(); } + +#ifdef Q_OS_LINUX + if(ev->button() == Qt::MiddleButton) + { + copySelectedText(true); + + if(!isOverSelection(scenePos)) + clearSelection(); + } +#endif } void ChatLog::mouseReleaseEvent(QMouseEvent* ev) @@ -528,13 +538,13 @@ void ChatLog::clear() updateSceneRect(); } -void ChatLog::copySelectedText() const +void ChatLog::copySelectedText(bool toSelectionBuffer) const { QString text = getSelectedText(); QClipboard* clipboard = QApplication::clipboard(); if(clipboard && !text.isNull()) - clipboard->setText(text); + clipboard->setText(text, toSelectionBuffer ? QClipboard::Selection : QClipboard::Clipboard); } void ChatLog::setBusyNotification(ChatLine::Ptr notification) diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 0ab495e4d..e89c789de 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -43,7 +43,7 @@ public: void insertChatlineOnTop(const QList& newLines); void clearSelection(); void clear(); - void copySelectedText() const; + void copySelectedText(bool toSelectionBuffer = false) const; void setBusyNotification(ChatLine::Ptr notification); void setTypingNotification(ChatLine::Ptr notification); void setTypingNotificationVisible(bool visible); From 535757670b389a247f33204056f0ad5da5f63a55 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 8 Feb 2015 12:20:27 +0100 Subject: [PATCH 187/203] copy: handle pending messages --- src/chatlog/chatlog.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 10e600490..47a505a0b 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -489,7 +489,9 @@ QString ChatLog::getSelectedText() const if(lastSender != lines[i]->content[0]->getText() && !lines[i]->content[0]->getText().isEmpty()) { //author changed - out += QString(out.isEmpty() ? "[%2] %1:\n" : "\n[%2] %1:\n").arg(lines[i]->content[0]->getText(), lines[i]->content[2]->getText()); + QString timestamp = lines[i]->content[2]->getText().isEmpty() ? tr("pending") : lines[i]->content[2]->getText(); + QString msg = lines[i]->content[0]->getText(); + out += QString(out.isEmpty() ? "[%2] %1:\n" : "\n[%2] %1:\n").arg(msg, timestamp); lastSender = lines[i]->content[0]->getText(); } From 3f6e68db95cc3c7769c6f1733533778ee7d910c1 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 9 Feb 2015 17:45:48 +0100 Subject: [PATCH 188/203] tweaked layout calculation --- src/chatlog/chatline.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/chatlog/chatline.cpp b/src/chatlog/chatline.cpp index 1059d63e6..d3617b347 100644 --- a/src/chatlog/chatline.cpp +++ b/src/chatlog/chatline.cpp @@ -185,11 +185,11 @@ void ChatLine::layout(qreal w, QPointF scenePos) qreal maxVOffset = 0.0; qreal xOffset = 0.0; + qreal xPos[content.size()]; + for(int i = 0; i < static_cast(content.size()); ++i) { - maxVOffset = qMax(maxVOffset, content[i]->getAscent()); - // calculate the effective width of the current column qreal width; if(format[i].policy == ColumnFormat::FixedSize) @@ -216,21 +216,20 @@ void ChatLine::layout(qreal w, QPointF scenePos) } // reposition - content[i]->setPos(scenePos.x() + xOffset + xAlign, scenePos.y()); + xPos[i] = scenePos.x() + xOffset + xAlign; xOffset += width + columnSpacing; + maxVOffset = qMax(maxVOffset, content[i]->getAscent()); } for(int i = 0; i < static_cast(content.size()); ++i) { // calculate vertical alignment // vertical alignment may depend on width, so we do it in a second pass - qreal yOffset = 0.0; - - yOffset = maxVOffset - content[i]->getAscent(); + qreal yOffset = maxVOffset - content[i]->getAscent(); // reposition - content[i]->setPos(content[i]->pos().x(), content[i]->pos().y() + yOffset); + content[i]->setPos(xPos[i], scenePos.y() + yOffset); } updateBBox(); From 990a7f4734860362e1a3cdf171e1e59490d1dbac Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 9 Feb 2015 17:48:54 +0100 Subject: [PATCH 189/203] ownership (again) --- src/chatlog/chatlog.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 47a505a0b..750262ccf 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -101,13 +101,15 @@ ChatLog::ChatLog(QWidget* parent) ChatLog::~ChatLog() { - // Drop ownership of items of type ChatLineContentType - // as they are owned by ChatLine - for(QGraphicsItem* item : items()) - { - if(item->type() == ChatLineContent::ChatLineContentType) - scene->removeItem(item); - } + // Remove chatlines from scene + for(ChatLine::Ptr l : lines) + l->removeFromScene(); + + if(busyNotification) + busyNotification->removeFromScene(); + + if(typingNotification) + typingNotification->removeFromScene(); } void ChatLog::clearSelection() From 69fde0d8b0c97247644cea99f2afcc7d8c28f505 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 10 Feb 2015 14:30:49 +0100 Subject: [PATCH 190/203] refactoring --- src/chatlog/chatlog.cpp | 28 +++++++++++++++++++++------- src/chatlog/content/text.cpp | 2 -- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 750262ccf..428d523ec 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -403,20 +403,34 @@ void ChatLog::insertChatlineOnTop(const QList& newLines) if(newLines.isEmpty()) return; - // move all lines down by n - int n = newLines.size(); - for(ChatLine::Ptr l : lines) - l->setRow(l->getRow() + n); + QGraphicsScene::ItemIndexMethod oldIndexMeth = scene->itemIndexMethod(); + scene->setItemIndexMethod(QGraphicsScene::NoIndex); - // add the new line + // alloc space for old and new lines + QVector combLines; + combLines.reserve(newLines.size() + lines.size()); + + // add the new lines + int i = 0; for(ChatLine::Ptr l : newLines) { l->addToScene(scene); - l->setRow(--n); l->visibilityChanged(false); - lines.prepend(l); + l->setRow(i++); + combLines.push_back(l); } + // add the old lines + for(ChatLine::Ptr l : lines) + { + l->setRow(i++); + combLines.push_back(l); + } + + lines = combLines; + + scene->setItemIndexMethod(oldIndexMeth); + // redo layout startResizeWorker(); } diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 7073f2060..58002220e 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -47,8 +47,6 @@ void Text::setText(const QString& txt) { text = txt; dirty = true; - - regenerate(); } void Text::setWidth(qreal w) From 697460ca363b2e63075f735e4485d79c2f962a93 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 10 Feb 2015 14:36:53 +0100 Subject: [PATCH 191/203] revised issue #6 --- src/chatlog/chatlog.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 428d523ec..964845c5b 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -182,16 +182,6 @@ void ChatLog::mousePressEvent(QMouseEvent* ev) if(!isOverSelection(scenePos)) clearSelection(); } - -#ifdef Q_OS_LINUX - if(ev->button() == Qt::MiddleButton) - { - copySelectedText(true); - - if(!isOverSelection(scenePos)) - clearSelection(); - } -#endif } void ChatLog::mouseReleaseEvent(QMouseEvent* ev) @@ -312,6 +302,10 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) updateMultiSelectionRect(); } } + +#ifdef Q_OS_LINUX + copySelectedText(true); +#endif } //Much faster than QGraphicsScene::itemAt()! From 5f31921cf4bca0d3afa8df776cbdf6a9c6acd0fe Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 11 Feb 2015 16:32:42 +0100 Subject: [PATCH 192/203] fix issue #10 --- src/chatlog/chatlog.cpp | 24 +++++++++++++++--------- src/chatlog/chatlog.h | 3 +++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 964845c5b..460da96fc 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -97,6 +97,14 @@ ChatLog::ChatLog(QWidget* parent) workerTimer->setSingleShot(false); workerTimer->setInterval(5); connect(workerTimer, &QTimer::timeout, this, &ChatLog::onWorkerTimeout); + + // selection + connect(this, &ChatLog::selectionChanged, this, [this]() { + copyAction->setEnabled(hasTextToBeCopied()); +#ifdef Q_OS_LINUX + copySelectedText(true); +#endif + }); } ChatLog::~ChatLog() @@ -126,7 +134,7 @@ void ChatLog::clearSelection() selClickedRow = -1; selectionMode = None; - copyAction->setEnabled(false); + emit selectionChanged(); updateMultiSelectionRect(); } @@ -234,7 +242,6 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) content->selectionStarted(sceneClickPos); selectionMode = Precise; - copyAction->setEnabled(true); // ungrab mouse grabber if(scene->mouseGrabberItem()) @@ -247,7 +254,6 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) selLastRow = selClickedRow; selectionMode = Multi; - copyAction->setEnabled(true); } } @@ -301,11 +307,9 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) updateMultiSelectionRect(); } - } -#ifdef Q_OS_LINUX - copySelectedText(true); -#endif + emit selectionChanged(); + } } //Much faster than QGraphicsScene::itemAt()! @@ -476,6 +480,8 @@ void ChatLog::mouseDoubleClickEvent(QMouseEvent *ev) selFirstRow = content->getRow(); selLastRow = content->getRow(); selectionMode = Precise; + + emit selectionChanged(); } } @@ -607,7 +613,7 @@ void ChatLog::selectAll() selFirstRow = 0; selLastRow = lines.size()-1; - copyAction->setEnabled(true); + emit selectionChanged(); updateMultiSelectionRect(); } @@ -644,7 +650,7 @@ void ChatLog::checkVisibility() std::sort(visibleLines.begin(), visibleLines.end(), ChatLine::lessThanRowIndex); //if(!visibleLines.empty()) - // qDebug() << "visible from " << visibleLines.first()->getRowIndex() << "to " << visibleLines.last()->getRowIndex() << " total " << visibleLines.size(); + // qDebug() << "visible from " << visibleLines.first()->getRow() << "to " << visibleLines.last()->getRow() << " total " << visibleLines.size(); } void ChatLog::scrollContentsBy(int dx, int dy) diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index e89c789de..5fb95bc06 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -58,6 +58,9 @@ public: ChatLine::Ptr getTypingNotification() const; QVector getLines(); +signals: + void selectionChanged(); + protected: QRectF calculateSceneRect() const; QRect getVisibleRect() const; From 788d57c815c30ed51d8e4768767271ed3066a642 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 11 Feb 2015 16:37:02 +0100 Subject: [PATCH 193/203] copy/paste changed format (issue #11) --- src/chatlog/chatlog.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/chatlog/chatlog.cpp b/src/chatlog/chatlog.cpp index 460da96fc..f4b6e4af8 100644 --- a/src/chatlog/chatlog.cpp +++ b/src/chatlog/chatlog.cpp @@ -496,22 +496,16 @@ QString ChatLog::getSelectedText() const // build a nicely formatted message QString out; - QString lastSender; for(int i=selFirstRow; i<=selLastRow; ++i) { if(lines[i]->content[1]->getText().isEmpty()) continue; - if(lastSender != lines[i]->content[0]->getText() && !lines[i]->content[0]->getText().isEmpty()) - { - //author changed - QString timestamp = lines[i]->content[2]->getText().isEmpty() ? tr("pending") : lines[i]->content[2]->getText(); - QString msg = lines[i]->content[0]->getText(); - out += QString(out.isEmpty() ? "[%2] %1:\n" : "\n[%2] %1:\n").arg(msg, timestamp); - lastSender = lines[i]->content[0]->getText(); - } + QString timestamp = lines[i]->content[2]->getText().isEmpty() ? tr("pending") : lines[i]->content[2]->getText(); + QString author = lines[i]->content[0]->getText(); + QString msg = lines[i]->content[1]->getText(); - out += lines[i]->content[1]->getText(); + out += QString(out.isEmpty() ? "[%2] %1:\n%3" : "\n[%2] %1:\n%3").arg(author, timestamp, msg); if(i != selLastRow) out += "\n"; From 0b56916b9fec46ce88c2d74ca70241dc4ff9897d Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 11 Feb 2015 17:03:38 +0100 Subject: [PATCH 194/203] Text anchors: use PointingHandCursor --- src/chatlog/content/text.cpp | 11 +++++++++++ src/chatlog/content/text.h | 1 + 2 files changed, 12 insertions(+) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index 58002220e..cadf6b274 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -35,6 +35,7 @@ Text::Text(const QString& txt, QFont font, bool enableElide, const QString &rwTe { setText(txt); setAcceptedMouseButtons(Qt::LeftButton); + setAcceptHoverEvents(true); } Text::~Text() @@ -210,6 +211,16 @@ void Text::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QDesktopServices::openUrl(anchor); } +void Text::hoverMoveEvent(QGraphicsSceneHoverEvent *event) +{ + QString anchor = doc->documentLayout()->anchorAt(event->pos()); + + if(!anchor.isEmpty()) + setCursor(QCursor(Qt::PointingHandCursor)); + else + setCursor(QCursor()); +} + QString Text::getText() const { return rawText; diff --git a/src/chatlog/content/text.h b/src/chatlog/content/text.h index 1f15107ac..4fe23ad92 100644 --- a/src/chatlog/content/text.h +++ b/src/chatlog/content/text.h @@ -51,6 +51,7 @@ public: virtual qreal getAscent() const override; virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override; virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; + virtual void hoverMoveEvent(QGraphicsSceneHoverEvent* event) override; virtual QString getText() const override; From 7d2f515df93b801aef943652c10057e325ca277b Mon Sep 17 00:00:00 2001 From: krepa098 Date: Thu, 12 Feb 2015 09:02:49 +0100 Subject: [PATCH 195/203] fix crash in Text::hoverMoveEvent --- src/chatlog/content/text.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/chatlog/content/text.cpp b/src/chatlog/content/text.cpp index cadf6b274..a2009c646 100644 --- a/src/chatlog/content/text.cpp +++ b/src/chatlog/content/text.cpp @@ -213,6 +213,9 @@ void Text::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) void Text::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { + if(!doc) + return; + QString anchor = doc->documentLayout()->anchorAt(event->pos()); if(!anchor.isEmpty()) From f765daf98de361bb9dc64be7b56681fd8c6e66fd Mon Sep 17 00:00:00 2001 From: krepa098 Date: Thu, 12 Feb 2015 09:12:14 +0100 Subject: [PATCH 196/203] reverse history entries as they are no longer reversed in ChatLog::insertChatlineOnTop --- src/widget/form/chatform.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 3e431e182..c7e1faeef 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -776,7 +776,7 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) if (msgDate > lastDate) { lastDate = msgDate; - historyMessages.prepend(ChatMessage::createChatInfoMessage(msgDate.toString(), ChatMessage::INFO, QDateTime::currentDateTime())); + historyMessages.append(ChatMessage::createChatInfoMessage(msgDate.toString(), ChatMessage::INFO, QDateTime::currentDateTime())); } // Show each messages @@ -812,7 +812,7 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered) getOfflineMsgEngine()->registerReceipt(rec, it.id, msg); } } - historyMessages.prepend(msg); + historyMessages.append(msg); } previousId = storedPrevId; From 936a34faf177a3ff4caf2e32b3565bdd2c68a18f Mon Sep 17 00:00:00 2001 From: krepa098 Date: Thu, 12 Feb 2015 11:32:13 +0100 Subject: [PATCH 197/203] do not trigger repaint if invisible --- src/chatlog/content/notificationicon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/content/notificationicon.cpp b/src/chatlog/content/notificationicon.cpp index e454fc721..f91e72cae 100644 --- a/src/chatlog/content/notificationicon.cpp +++ b/src/chatlog/content/notificationicon.cpp @@ -78,6 +78,6 @@ void NotificationIcon::updateGradient() grad.setColorAt(qMin(1.0, alpha + dotWidth), Qt::lightGray); grad.setColorAt(1, Qt::lightGray); - if(scene()) + if(scene() && isVisible()) scene()->invalidate(sceneBoundingRect()); } From faaa147a835ab6aa75a2b0c262747cd95df55f5e Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 13 Feb 2015 16:46:59 +0100 Subject: [PATCH 198/203] mockup (WIP) --- src/chatlog/content/filetransferwidget.cpp | 43 +++++++++++++++------- src/chatlog/content/filetransferwidget.h | 5 ++- src/chatlog/content/filetransferwidget.ui | 42 ++++++++++++--------- 3 files changed, 56 insertions(+), 34 deletions(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index f1179875d..b5a308006 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -34,7 +34,8 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) , ui(new Ui::FileTransferWidget) , fileInfo(file) , lastTick(QTime::currentTime()) - , color(Style::getColor(Style::LightGrey)) + , backgroundColor(Style::getColor(Style::LightGrey)) + , buttonColor(Style::getColor(Style::Yellow)) { ui->setupUi(this); @@ -48,11 +49,11 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) ui->progressLabel->setText("0kiB/s"); ui->etaLabel->setText(""); - colorAnimation = new QVariantAnimation(this); - colorAnimation->setDuration(500); - colorAnimation->setEasingCurve(QEasingCurve::OutCubic); - connect(colorAnimation, &QVariantAnimation::valueChanged, this, [this](const QVariant& val) { - color = val.value(); + backgroundColorAnimation = new QVariantAnimation(this); + backgroundColorAnimation->setDuration(500); + backgroundColorAnimation->setEasingCurve(QEasingCurve::OutCubic); + connect(backgroundColorAnimation, &QVariantAnimation::valueChanged, this, [this](const QVariant& val) { + backgroundColor = val.value(); update(); }); @@ -121,11 +122,11 @@ void FileTransferWidget::acceptTransfer(const QString &filepath) void FileTransferWidget::setColor(const QColor &c, bool whiteFont) { - if(c != color) + if(c != backgroundColor) { - colorAnimation->setStartValue(color); - colorAnimation->setEndValue(c); - colorAnimation->start(); + backgroundColorAnimation->setStartValue(backgroundColor); + backgroundColorAnimation->setEndValue(c); + backgroundColorAnimation->start(); } setProperty("fontColor", whiteFont ? "white" : "black"); @@ -149,13 +150,27 @@ void FileTransferWidget::paintEvent(QPaintEvent *) // required by Hi-DPI support as border-image doesn't work. QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); - painter.setBrush(QBrush(color)); painter.setPen(Qt::NoPen); - qreal s = static_cast(geometry().height()) / static_cast(geometry().width()); - int r = 20; + qreal ratio = static_cast(geometry().height()) / static_cast(geometry().width()); + const int r = 20; + const int buttonFieldWidth = 34; + const int lineWidth = 2; - painter.drawRoundRect(geometry(), r * s, r); + // draw background + painter.setBrush(QBrush(backgroundColor)); + painter.setClipRect(QRect(0,0,width()-buttonFieldWidth,height())); + painter.drawRoundRect(geometry(), r * ratio, r); + + // draw button background (top) + painter.setBrush(QBrush(buttonColor)); + painter.setClipRect(QRect(width()-buttonFieldWidth+lineWidth,0,buttonFieldWidth,height()/2-lineWidth/2)); + painter.drawRoundRect(geometry(), r * ratio, r); + + // draw button background (bottom) + painter.setBrush(QBrush(buttonColor)); + painter.setClipRect(QRect(width()-buttonFieldWidth+lineWidth,height()/2+lineWidth/2,buttonFieldWidth,height()/2)); + painter.drawRoundRect(geometry(), r * ratio, r); } void FileTransferWidget::onFileTransferInfo(ToxFile file) diff --git a/src/chatlog/content/filetransferwidget.h b/src/chatlog/content/filetransferwidget.h index 395932355..614e3f4ec 100644 --- a/src/chatlog/content/filetransferwidget.h +++ b/src/chatlog/content/filetransferwidget.h @@ -69,8 +69,9 @@ private: ToxFile fileInfo; QTime lastTick; qint64 lastBytesSent = 0; - QVariantAnimation* colorAnimation = nullptr; - QColor color; + QVariantAnimation* backgroundColorAnimation = nullptr; + QColor backgroundColor; + QColor buttonColor; static const uint8_t TRANSFER_ROLLING_AVG_COUNT = 4; uint8_t meanIndex = 0; diff --git a/src/chatlog/content/filetransferwidget.ui b/src/chatlog/content/filetransferwidget.ui index eb4163cd8..f003a8c29 100644 --- a/src/chatlog/content/filetransferwidget.ui +++ b/src/chatlog/content/filetransferwidget.ui @@ -7,7 +7,7 @@ 0 0 532 - 90 + 238
@@ -79,6 +79,12 @@ 16777215 + + QFrame::Box + + + 2 + [preview] @@ -251,8 +257,8 @@ - 25 - 28 + 32 + 32 @@ -260,19 +266,6 @@
- - - - Qt::Vertical - - - - 20 - 92 - - - - @@ -286,8 +279,8 @@ - 25 - 28 + 32 + 32 @@ -295,6 +288,19 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + +
From 459e3f43bdf296c1a17b16b303ae016e29322aa1 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 13 Feb 2015 16:47:38 +0100 Subject: [PATCH 199/203] Revert "FTW: circular buttons [feedback wanted]" This reverts commit 21eb9172d4d6bbd1cabf539eacfc6327569c6e02. --- ui/fileTransferInstance/arrow_white.svg | 23 ++--- ui/fileTransferInstance/browse.svg | 120 ++++++------------------ ui/fileTransferInstance/no.svg | 23 ++--- ui/fileTransferInstance/pause.svg | 42 ++++----- ui/fileTransferInstance/yes.svg | 37 +------- 5 files changed, 72 insertions(+), 173 deletions(-) diff --git a/ui/fileTransferInstance/arrow_white.svg b/ui/fileTransferInstance/arrow_white.svg index f7dae07c7..ee2e9fdcd 100644 --- a/ui/fileTransferInstance/arrow_white.svg +++ b/ui/fileTransferInstance/arrow_white.svg @@ -1,26 +1,23 @@ + + image/svg+xml \ No newline at end of file + style="fill:#ffffff" /> \ No newline at end of file diff --git a/ui/fileTransferInstance/browse.svg b/ui/fileTransferInstance/browse.svg index 7196c237a..4123ec52c 100644 --- a/ui/fileTransferInstance/browse.svg +++ b/ui/fileTransferInstance/browse.svg @@ -7,78 +7,12 @@ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" width="12" height="12" - id="svg2" - inkscape:version="0.91 r13725" - sodipodi:docname="browse.svg"> - + id="svg2"> - - - - - - - - - - - - + transform="translate(0,-2092.7244)" + id="layer1"> + + + + + + + + - diff --git a/ui/fileTransferInstance/no.svg b/ui/fileTransferInstance/no.svg index 663714ba4..a90227ea6 100644 --- a/ui/fileTransferInstance/no.svg +++ b/ui/fileTransferInstance/no.svg @@ -1,26 +1,23 @@ + + image/svg+xml \ No newline at end of file + style="fill:#ffffff" /> \ No newline at end of file diff --git a/ui/fileTransferInstance/pause.svg b/ui/fileTransferInstance/pause.svg index c318c12d2..b02c4dd53 100644 --- a/ui/fileTransferInstance/pause.svg +++ b/ui/fileTransferInstance/pause.svg @@ -1,37 +1,33 @@ + + image/svg+xml \ No newline at end of file + x="6.007" + y="0" + id="rect7" + style="fill:#ffffff" /> \ No newline at end of file diff --git a/ui/fileTransferInstance/yes.svg b/ui/fileTransferInstance/yes.svg index 8ae23425c..def828488 100644 --- a/ui/fileTransferInstance/yes.svg +++ b/ui/fileTransferInstance/yes.svg @@ -7,45 +7,16 @@ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" width="12" height="12" viewBox="0 0 11.999999 12" id="Layer_1" - xml:space="preserve" - inkscape:version="0.91 r13725" - sodipodi:docname="yes.svg">image/svg+xml \ No newline at end of file + style="fill:none;stroke:#ffffff;stroke-width:1.91624641;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> \ No newline at end of file From 9499909f8baa7262aab3416ca9bc00d0fdbd30e5 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 14 Feb 2015 12:14:09 +0100 Subject: [PATCH 200/203] finished work on FTW hopefully --- src/chatlog/content/filetransferwidget.cpp | 83 +++- src/chatlog/content/filetransferwidget.h | 7 +- src/chatlog/content/filetransferwidget.ui | 462 +++++++++++------- ui/fileTransferInstance/browse.svg | 42 +- .../filetransferWidget.css | 14 +- ui/fileTransferInstance/no.svg | 31 +- ui/fileTransferInstance/pause.svg | 45 +- ui/fileTransferInstance/yes.svg | 32 +- 8 files changed, 489 insertions(+), 227 deletions(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index b5a308006..c3229e87f 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -57,7 +57,15 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) update(); }); - setColor(Style::getColor(Style::LightGrey), false); + buttonColorAnimation = new QVariantAnimation(this); + buttonColorAnimation->setDuration(500); + buttonColorAnimation->setEasingCurve(QEasingCurve::OutCubic); + connect(buttonColorAnimation, &QVariantAnimation::valueChanged, this, [this](const QVariant& val) { + buttonColor = val.value(); + update(); + }); + + setBackgroundColor(Style::getColor(Style::LightGrey), false); connect(Core::getInstance(), &Core::fileTransferInfo, this, &FileTransferWidget::onFileTransferInfo); connect(Core::getInstance(), &Core::fileTransferAccepted, this, &FileTransferWidget::onFileTransferAccepted); @@ -71,7 +79,7 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) if(fileInfo.direction == ToxFile::SENDING) showPreview(fileInfo.filePath); - setFixedHeight(64); + setFixedHeight(78); } FileTransferWidget::~FileTransferWidget() @@ -120,7 +128,7 @@ void FileTransferWidget::acceptTransfer(const QString &filepath) Core::getInstance()->acceptFileRecvRequest(fileInfo.friendId, fileInfo.fileNum, filepath); } -void FileTransferWidget::setColor(const QColor &c, bool whiteFont) +void FileTransferWidget::setBackgroundColor(const QColor &c, bool whiteFont) { if(c != backgroundColor) { @@ -137,7 +145,17 @@ void FileTransferWidget::setColor(const QColor &c, bool whiteFont) update(); } -bool FileTransferWidget::isFilePathWritable(const QString &filepath) +void FileTransferWidget::setButtonColor(const QColor &c) +{ + if(c != buttonColor) + { + buttonColorAnimation->setStartValue(buttonColor); + buttonColorAnimation->setEndValue(c); + buttonColorAnimation->start(); + } +} + +bool FileTransferWidget::isFilePathWritable(const QString &filepath) const { QFile tmp(filepath); bool writable = tmp.open(QIODevice::WriteOnly); @@ -145,6 +163,12 @@ bool FileTransferWidget::isFilePathWritable(const QString &filepath) return writable; } +bool FileTransferWidget::drawButtonAreaNeeded() const +{ + return (ui->bottomButton->isVisible() || ui->topButton->isVisible()) && + !(ui->topButton->isVisible() && ui->topButton->objectName() == "ok"); +} + void FileTransferWidget::paintEvent(QPaintEvent *) { // required by Hi-DPI support as border-image doesn't work. @@ -153,24 +177,28 @@ void FileTransferWidget::paintEvent(QPaintEvent *) painter.setPen(Qt::NoPen); qreal ratio = static_cast(geometry().height()) / static_cast(geometry().width()); - const int r = 20; + const int r = 24; const int buttonFieldWidth = 34; const int lineWidth = 2; // draw background + if(drawButtonAreaNeeded()) + painter.setClipRect(QRect(0,0,width()-buttonFieldWidth,height())); painter.setBrush(QBrush(backgroundColor)); - painter.setClipRect(QRect(0,0,width()-buttonFieldWidth,height())); painter.drawRoundRect(geometry(), r * ratio, r); - // draw button background (top) - painter.setBrush(QBrush(buttonColor)); - painter.setClipRect(QRect(width()-buttonFieldWidth+lineWidth,0,buttonFieldWidth,height()/2-lineWidth/2)); - painter.drawRoundRect(geometry(), r * ratio, r); + if(drawButtonAreaNeeded()) + { + // draw button background (top) + painter.setBrush(QBrush(buttonColor)); + painter.setClipRect(QRect(width()-buttonFieldWidth+lineWidth,0,buttonFieldWidth,height()/2-lineWidth/2)); + painter.drawRoundRect(geometry(), r * ratio, r); - // draw button background (bottom) - painter.setBrush(QBrush(buttonColor)); - painter.setClipRect(QRect(width()-buttonFieldWidth+lineWidth,height()/2+lineWidth/2,buttonFieldWidth,height()/2)); - painter.drawRoundRect(geometry(), r * ratio, r); + // draw button background (bottom) + painter.setBrush(QBrush(buttonColor)); + painter.setClipRect(QRect(width()-buttonFieldWidth+lineWidth,height()/2+lineWidth/2,buttonFieldWidth,height()/2)); + painter.drawRoundRect(geometry(), r * ratio, r); + } } void FileTransferWidget::onFileTransferInfo(ToxFile file) @@ -210,7 +238,8 @@ void FileTransferWidget::onFileTransferInfo(ToxFile file) { // ETA QTime toGo = QTime(0,0).addSecs((file.filesize - file.bytesSent) / meanBytesPerSec); - ui->etaLabel->setText(toGo.toString("hh:mm:ss")); + QString format = toGo.hour() > 0 ? "hh:mm:ss" : "mm:ss"; + ui->etaLabel->setText(toGo.toString(format)); } else { @@ -235,7 +264,7 @@ void FileTransferWidget::onFileTransferAccepted(ToxFile file) fileInfo = file; - setColor(Style::getColor(Style::Yellow), false); + setBackgroundColor(Style::getColor(Style::LightGrey), false); setupButtons(); } @@ -247,7 +276,7 @@ void FileTransferWidget::onFileTransferCancelled(ToxFile file) fileInfo = file; - setColor(Style::getColor(Style::Red), true); + setBackgroundColor(Style::getColor(Style::Red), true); setupButtons(); hideWidgets(); @@ -263,14 +292,14 @@ void FileTransferWidget::onFileTransferPaused(ToxFile file) fileInfo = file; ui->etaLabel->setText(""); - ui->progressLabel->setText(getHumanReadableSize(0) + "/s"); + ui->progressLabel->setText(tr("paused", "file transfer widget")); // reset mean meanIndex = 0; for(size_t i=0; ibottomButton->setIcon(QIcon(":/ui/fileTransferInstance/browse.svg")); - ui->bottomButton->setObjectName("browse"); - ui->bottomButton->show(); + ui->topButton->setIcon(QIcon(":/ui/fileTransferInstance/yes.svg")); + ui->topButton->setObjectName("ok"); + ui->topButton->show(); } // preview @@ -333,6 +362,9 @@ void FileTransferWidget::setupButtons() ui->bottomButton->setIcon(QIcon(":/ui/fileTransferInstance/pause.svg")); ui->bottomButton->setObjectName("pause"); + + setButtonColor(Style::getColor(Style::Green)); + break; case ToxFile::PAUSED: ui->topButton->setIcon(QIcon(":/ui/fileTransferInstance/no.svg")); @@ -340,6 +372,9 @@ void FileTransferWidget::setupButtons() ui->bottomButton->setIcon(QIcon(":/ui/fileTransferInstance/arrow_white.svg")); ui->bottomButton->setObjectName("resume"); + + setButtonColor(Style::getColor(Style::LightGrey)); + break; case ToxFile::STOPPED: case ToxFile::BROKEN: //TODO: ? @@ -386,7 +421,7 @@ void FileTransferWidget::handleButton(QPushButton *btn) } } - if(btn->objectName() == "browse") + if(btn->objectName() == "ok") { QDesktopServices::openUrl("file://" + fileInfo.filePath); } diff --git a/src/chatlog/content/filetransferwidget.h b/src/chatlog/content/filetransferwidget.h index 614e3f4ec..257afae4e 100644 --- a/src/chatlog/content/filetransferwidget.h +++ b/src/chatlog/content/filetransferwidget.h @@ -54,9 +54,11 @@ protected: void handleButton(QPushButton* btn); void showPreview(const QString& filename); void acceptTransfer(const QString& filepath); - void setColor(const QColor& c, bool whiteFont); + void setBackgroundColor(const QColor& c, bool whiteFont); + void setButtonColor(const QColor& c); - bool isFilePathWritable(const QString& filepath); + bool isFilePathWritable(const QString& filepath) const; + bool drawButtonAreaNeeded() const; virtual void paintEvent(QPaintEvent*); @@ -70,6 +72,7 @@ private: QTime lastTick; qint64 lastBytesSent = 0; QVariantAnimation* backgroundColorAnimation = nullptr; + QVariantAnimation* buttonColorAnimation = nullptr; QColor backgroundColor; QColor buttonColor; diff --git a/src/chatlog/content/filetransferwidget.ui b/src/chatlog/content/filetransferwidget.ui index f003a8c29..795db2540 100644 --- a/src/chatlog/content/filetransferwidget.ui +++ b/src/chatlog/content/filetransferwidget.ui @@ -6,14 +6,14 @@ 0 0 - 532 - 238 + 625 + 243 Form - + 0 @@ -49,54 +49,26 @@ 0 - + - 6 + 0 - 5 + 0 - 5 + 0 - 2 + 0 - 5 + 0 - - - - 80 - 0 - - - - - 80 - 16777215 - - - - QFrame::Box - - - 2 - - - [preview] - - - - - + - 6 - - - 0 + 10 6 @@ -104,115 +76,232 @@ 0 - - + + 6 + + + 0 + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + QLayout::SetDefaultConstraint + + + 6 + + + 0 + + + 6 + + + 0 + + + 6 + + + 3 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 10Mb + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + 0kb/s + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + ETA:10:10 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + 16777215 + 12 + + + + + + + 24 + + + Qt::Horizontal + + + false + + + + + + + + + + + 0 + 0 + + + + Filename + + + + + + + Qt::Vertical + + + + 1 + 20 + + + + + + + + Qt::Vertical + + + + 1 + 21 + + + + + + + + Qt::Vertical + + + QSizePolicy::Preferred + + + + 1 + 20 + + + + + + + + - + 0 0 - - Filename - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - 10Mb - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - 0kb/s - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - ETA:10:10 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - + - 16777215 - 10 + 60 + 60 - - + + + 60 + 60 + - - 24 + + QFrame::Box - - Qt::Horizontal + + 2 - - false - - - + + [preview] - - + + Qt::Vertical @@ -228,10 +317,7 @@ - - - 0 - + 0 @@ -244,58 +330,94 @@ 0 - - - - - 0 - 0 - - - - - - - - 32 - 32 - - - - true - - - - + + 0 + + - + 0 0 + + + 32 + 16777215 + + + + PointingHandCursor + + + + :/ui/fileTransferInstance/no.svg:/ui/fileTransferInstance/no.svg + 32 - 32 + 18 - - true - - + + + + + 0 + 0 + + + + + 32 + 16777215 + + + + PointingHandCursor + + + + + + + :/ui/fileTransferInstance/no.svg:/ui/fileTransferInstance/no.svg + + + + 32 + 18 + + + + + + + + Qt::Vertical + + + + 0 + 40 + + + + + Qt::Vertical - 20 + 0 40 @@ -316,6 +438,8 @@
src/widget/croppinglabel.h
- + + + diff --git a/ui/fileTransferInstance/browse.svg b/ui/fileTransferInstance/browse.svg index 4123ec52c..378802171 100644 --- a/ui/fileTransferInstance/browse.svg +++ b/ui/fileTransferInstance/browse.svg @@ -7,10 +7,34 @@ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" width="12" height="12" - id="svg2"> + id="svg2" + inkscape:version="0.91 r13725" + sodipodi:docname="browse.svg"> + image/svg+xml - + + style="fill:#ffffff;fill-opacity:1;stroke:none" + inkscape:connector-curvature="0" /> + style="fill:#ffffff;fill-opacity:1;stroke:none" + inkscape:connector-curvature="0" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;marker:none;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" + inkscape:connector-curvature="0" /> diff --git a/ui/fileTransferInstance/filetransferWidget.css b/ui/fileTransferInstance/filetransferWidget.css index 6be989d4e..3f1d5c5ea 100644 --- a/ui/fileTransferInstance/filetransferWidget.css +++ b/ui/fileTransferInstance/filetransferWidget.css @@ -1,21 +1,23 @@ [fontColor="white"] QLabel { color:white; - font:@medium; + font:@big; } [fontColor="black"] QLabel { - color:black; - font:@medium; + color:@mediumGrey; + font:@big; } QPushButton { margin:0; border: none; -} +} + + QProgressBar { - border: 2px solid black; - border-radius: 4px; + border: 2px solid @mediumGrey; + border-radius: 0px; background-color: @mediumGrey; } diff --git a/ui/fileTransferInstance/no.svg b/ui/fileTransferInstance/no.svg index a90227ea6..2ca1c5c1b 100644 --- a/ui/fileTransferInstance/no.svg +++ b/ui/fileTransferInstance/no.svg @@ -7,17 +7,40 @@ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" width="12" height="12" viewBox="0 0 11.999999 12" id="Layer_1" - xml:space="preserve">image/svg+xml \ No newline at end of file diff --git a/ui/fileTransferInstance/pause.svg b/ui/fileTransferInstance/pause.svg index b02c4dd53..6a203bd0b 100644 --- a/ui/fileTransferInstance/pause.svg +++ b/ui/fileTransferInstance/pause.svg @@ -7,27 +7,50 @@ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" width="12" height="12" viewBox="0 0 12.000001 12" id="Layer_1" - xml:space="preserve">image/svg+xml \ No newline at end of file diff --git a/ui/fileTransferInstance/yes.svg b/ui/fileTransferInstance/yes.svg index def828488..2d4c45ea4 100644 --- a/ui/fileTransferInstance/yes.svg +++ b/ui/fileTransferInstance/yes.svg @@ -7,16 +7,40 @@ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" width="12" height="12" viewBox="0 0 11.999999 12" id="Layer_1" - xml:space="preserve">image/svg+xml \ No newline at end of file + style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + inkscape:connector-curvature="0" /> \ No newline at end of file From 108d2725e660438e67d648ffd64350e48774fd21 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 14 Feb 2015 12:21:03 +0100 Subject: [PATCH 201/203] FTW: 1px spacing instead of 2px --- src/chatlog/content/filetransferwidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index c3229e87f..797012375 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -179,7 +179,7 @@ void FileTransferWidget::paintEvent(QPaintEvent *) qreal ratio = static_cast(geometry().height()) / static_cast(geometry().width()); const int r = 24; const int buttonFieldWidth = 34; - const int lineWidth = 2; + const int lineWidth = 1; // draw background if(drawButtonAreaNeeded()) @@ -191,7 +191,7 @@ void FileTransferWidget::paintEvent(QPaintEvent *) { // draw button background (top) painter.setBrush(QBrush(buttonColor)); - painter.setClipRect(QRect(width()-buttonFieldWidth+lineWidth,0,buttonFieldWidth,height()/2-lineWidth/2)); + painter.setClipRect(QRect(width()-buttonFieldWidth+lineWidth,0,buttonFieldWidth,height()/2-ceil(lineWidth/2.0))); painter.drawRoundRect(geometry(), r * ratio, r); // draw button background (bottom) From c800672ff2ae6b7bb8df84a09c79c357eabe0750 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 14 Feb 2015 12:29:42 +0100 Subject: [PATCH 202/203] display "unconfirmed" on new file transfer requests --- src/chatlog/content/filetransferwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatlog/content/filetransferwidget.cpp b/src/chatlog/content/filetransferwidget.cpp index 797012375..f66d621be 100644 --- a/src/chatlog/content/filetransferwidget.cpp +++ b/src/chatlog/content/filetransferwidget.cpp @@ -46,7 +46,7 @@ FileTransferWidget::FileTransferWidget(QWidget *parent, ToxFile file) ui->filenameLabel->setText(file.fileName); ui->progressBar->setValue(0); ui->fileSizeLabel->setText(getHumanReadableSize(file.filesize)); - ui->progressLabel->setText("0kiB/s"); + ui->progressLabel->setText(tr("unconfirmed", "file transfer widget")); ui->etaLabel->setText(""); backgroundColorAnimation = new QVariantAnimation(this); From 2fa34ac7e4250dbc35a0ed42f28c6662a4804762 Mon Sep 17 00:00:00 2001 From: Dubslow Date: Sun, 15 Feb 2015 04:53:26 -0600 Subject: [PATCH 203/203] Remove QMarginsF, reduce to Qt 5.2 --- src/chatlog/chatlog.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chatlog/chatlog.h b/src/chatlog/chatlog.h index 5fb95bc06..db6cf973a 100644 --- a/src/chatlog/chatlog.h +++ b/src/chatlog/chatlog.h @@ -19,7 +19,7 @@ #include #include -#include +#include #include "chatline.h" #include "chatmessage.h" @@ -138,7 +138,7 @@ private: ChatLine::Ptr workerAnchorLine; // layout - QMarginsF margins = QMarginsF(10.0,10.0,10.0,10.0); + QMargins margins = QMargins(10.0,10.0,10.0,10.0); qreal lineSpacing = 5.0f; };