forked from blue/squawk
0.2.0 finalization
This commit is contained in:
parent
8a2658e4fc
commit
4d3ba6b11f
13
CHANGELOG.md
13
CHANGELOG.md
@ -1,19 +1,28 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## Squawk 0.2.0 (Unreleased)
|
## Squawk 0.2.0 (Jan 10, 2022)
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
- carbon copies switches on again after reconnection
|
- carbon copies switches on again after reconnection
|
||||||
- requesting the history of the current chat after reconnection
|
- requesting the history of the current chat after reconnection
|
||||||
- global availability (in drop down list) gets restored after reconnection
|
- global availability (in drop down list) gets restored after reconnection
|
||||||
- status icon in active chat changes when presence of the pen pal changes
|
- status icon in active chat changes when presence of the pen pal changes
|
||||||
- infinite progress when open the dialogue with something that has no history to show
|
- infinite progress when open the dialogue with something that has no history to show
|
||||||
|
- fallback icons for buttons, when no supported theme is installed (shunf4)
|
||||||
|
- better handling messages with no id (shunf4)
|
||||||
|
- removed dependency: uuid, now it's on Qt (shunf4)
|
||||||
|
- better requesting latest history (shunf4)
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
- slightly reduced the traffic on the startup by not requesting history of all MUCs
|
- slightly reduced the traffic on the startup by not requesting history of all MUCs
|
||||||
- completely rewritten message feed, now it works way faster
|
- completely rewritten message feed, now it works way faster and looks cooler
|
||||||
- OPTIONAL RUNTIME dependency: "KIO Widgets" that is supposed to allow you to open a file in your default file manager
|
- OPTIONAL RUNTIME dependency: "KIO Widgets" that is supposed to allow you to open a file in your default file manager
|
||||||
- show in folder now is supposed to try it's best to show file in folder, even you don't have KIO installed
|
- show in folder now is supposed to try it's best to show file in folder, even you don't have KIO installed
|
||||||
- once uploaded local files don't get second time uploaded - the remote URL is reused
|
- once uploaded local files don't get second time uploaded - the remote URL is reused
|
||||||
|
- way better compilation time (vae)
|
||||||
|
|
||||||
|
### New features
|
||||||
|
- pasting images from clipboard to attachment (shunf4)
|
||||||
|
- possible compilation for windows and macOS (shunf4)
|
||||||
|
|
||||||
## Squawk 0.1.5 (Jul 29, 2020)
|
## Squawk 0.1.5 (Jul 29, 2020)
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
[![AUR version](https://img.shields.io/aur/version/squawk?style=flat-square)](https://aur.archlinux.org/packages/squawk/)
|
[![AUR version](https://img.shields.io/aur/version/squawk?style=flat-square)](https://aur.archlinux.org/packages/squawk/)
|
||||||
[![Liberapay patrons](https://img.shields.io/liberapay/patrons/macaw.me?logo=liberapay&style=flat-square)](https://liberapay.com/macaw.me)
|
[![Liberapay patrons](https://img.shields.io/liberapay/patrons/macaw.me?logo=liberapay&style=flat-square)](https://liberapay.com/macaw.me)
|
||||||
|
|
||||||
![Squawk screenshot](https://macaw.me/images/squawk/0.1.4.png)
|
![Squawk screenshot](https://macaw.me/images/squawk/0.2.0.png)
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
- QT 5.12 *(lower versions might work but it wasn't tested)*
|
- QT 5.12 *(lower versions might work but it wasn't tested)*
|
||||||
- lmdb
|
- lmdb
|
||||||
- CMake 3.0 or higher
|
- CMake 3.3 or higher
|
||||||
- qxmpp 1.1.0 or higher
|
- qxmpp 1.1.0 or higher
|
||||||
- KDE Frameworks: kwallet (optional)
|
- KDE Frameworks: kwallet (optional)
|
||||||
- KDE Frameworks: KIO (optional)
|
- KDE Frameworks: KIO (optional)
|
||||||
|
@ -54,7 +54,7 @@ int main(int argc, char *argv[])
|
|||||||
#endif
|
#endif
|
||||||
QApplication::setApplicationName("squawk");
|
QApplication::setApplicationName("squawk");
|
||||||
QApplication::setApplicationDisplayName("Squawk");
|
QApplication::setApplicationDisplayName("Squawk");
|
||||||
QApplication::setApplicationVersion("0.1.5");
|
QApplication::setApplicationVersion("0.2.0");
|
||||||
|
|
||||||
QTranslator qtTranslator;
|
QTranslator qtTranslator;
|
||||||
qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
|
qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Maintainer: Yury Gubich <blue@macaw.me>
|
# Maintainer: Yury Gubich <blue@macaw.me>
|
||||||
pkgname=squawk
|
pkgname=squawk
|
||||||
pkgver=0.1.5
|
pkgver=0.2.0
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="An XMPP desktop messenger, written on pure c++ (qt)"
|
pkgdesc="An XMPP desktop messenger, written on pure c++ (qt)"
|
||||||
arch=('i686' 'x86_64')
|
arch=('i686' 'x86_64')
|
||||||
@ -11,7 +11,7 @@ makedepends=('cmake>=3.3' 'imagemagick' 'qt5-tools')
|
|||||||
optdepends=('kwallet: secure password storage (requires rebuild)')
|
optdepends=('kwallet: secure password storage (requires rebuild)')
|
||||||
|
|
||||||
source=("$pkgname-$pkgver.tar.gz")
|
source=("$pkgname-$pkgver.tar.gz")
|
||||||
sha256sums=('e1a4c88be9f0481d2aa21078faf42fd0e9d66b490b6d8af82827d441cb58df25')
|
sha256sums=('8e93d3dbe1fc35cfecb7783af409c6a264244d11609b2241d4fe77d43d068419')
|
||||||
build() {
|
build() {
|
||||||
cd "$srcdir/squawk"
|
cd "$srcdir/squawk"
|
||||||
cmake . -D CMAKE_INSTALL_PREFIX=/usr -D CMAKE_BUILD_TYPE=Release
|
cmake . -D CMAKE_INSTALL_PREFIX=/usr -D CMAKE_BUILD_TYPE=Release
|
||||||
|
@ -144,7 +144,7 @@ Shared::Global::FileInfo Shared::Global::getFileInfo(const QString& path)
|
|||||||
size = defaultIconFileInfoHeight;
|
size = defaultIconFileInfoHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
itr = instance->fileCache.insert(std::make_pair(path, FileInfo({info.fileName(), size, type, p}))).first;
|
itr = instance->fileCache.insert(std::make_pair(path, FileInfo({info.absoluteFilePath(), info.fileName(), size, type, p}))).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
return itr->second;
|
return itr->second;
|
||||||
|
@ -55,6 +55,7 @@ namespace Shared {
|
|||||||
animation
|
animation
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QString path;
|
||||||
QString name;
|
QString name;
|
||||||
QSize size;
|
QSize size;
|
||||||
QMimeType mime;
|
QMimeType mime;
|
||||||
|
@ -43,6 +43,7 @@ FeedView::FeedView(QWidget* parent):
|
|||||||
QAbstractItemView(parent),
|
QAbstractItemView(parent),
|
||||||
hints(),
|
hints(),
|
||||||
vo(0),
|
vo(0),
|
||||||
|
elementMargin(0),
|
||||||
specialDelegate(false),
|
specialDelegate(false),
|
||||||
specialModel(false),
|
specialModel(false),
|
||||||
clearWidgetsMode(false),
|
clearWidgetsMode(false),
|
||||||
@ -106,7 +107,7 @@ QRect FeedView::visualRect(const QModelIndex& index) const
|
|||||||
} else {
|
} else {
|
||||||
const Hint& hint = hints.at(row);
|
const Hint& hint = hints.at(row);
|
||||||
const QWidget* vp = viewport();
|
const QWidget* vp = viewport();
|
||||||
return QRect(0, vp->height() - hint.height - hint.offset + vo, vp->width(), hint.height);
|
return QRect(hint.x, vp->height() - hint.height - hint.offset + vo, hint.width, hint.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +199,7 @@ void FeedView::updateGeometries()
|
|||||||
option.rect.setWidth(layoutBounds.width());
|
option.rect.setWidth(layoutBounds.width());
|
||||||
|
|
||||||
hints.clear();
|
hints.clear();
|
||||||
uint32_t previousOffset = 0;
|
uint32_t previousOffset = elementMargin;
|
||||||
QDateTime lastDate;
|
QDateTime lastDate;
|
||||||
for (int i = 0, size = m->rowCount(); i < size; ++i) {
|
for (int i = 0, size = m->rowCount(); i < size; ++i) {
|
||||||
QModelIndex index = m->index(i, 0, rootIndex());
|
QModelIndex index = m->index(i, 0, rootIndex());
|
||||||
@ -206,19 +207,32 @@ void FeedView::updateGeometries()
|
|||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
if (currentDate.daysTo(lastDate) > 0) {
|
if (currentDate.daysTo(lastDate) > 0) {
|
||||||
previousOffset += dividerMetrics.height() + dateDeviderMargin * 2;
|
previousOffset += dividerMetrics.height() + dateDeviderMargin * 2;
|
||||||
|
} else {
|
||||||
|
previousOffset += elementMargin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastDate = currentDate;
|
lastDate = currentDate;
|
||||||
int height = itemDelegate(index)->sizeHint(option, index).height();
|
QSize messageSize = itemDelegate(index)->sizeHint(option, index);
|
||||||
|
uint32_t offsetX(0);
|
||||||
|
if (specialDelegate) {
|
||||||
|
if (index.data(Models::MessageFeed::SentByMe).toBool()) {
|
||||||
|
offsetX = layoutBounds.width() - messageSize.width() - MessageDelegate::avatarHeight - MessageDelegate::margin * 2;
|
||||||
|
} else {
|
||||||
|
offsetX = MessageDelegate::avatarHeight + MessageDelegate::margin * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hints.emplace_back(Hint({
|
hints.emplace_back(Hint({
|
||||||
false,
|
false,
|
||||||
previousOffset,
|
previousOffset,
|
||||||
static_cast<uint32_t>(height)
|
static_cast<uint32_t>(messageSize.height()),
|
||||||
|
static_cast<uint32_t>(messageSize.width()),
|
||||||
|
offsetX
|
||||||
}));
|
}));
|
||||||
previousOffset += height;
|
previousOffset += messageSize.height();
|
||||||
}
|
}
|
||||||
|
|
||||||
int totalHeight = previousOffset - layoutBounds.height();
|
int totalHeight = previousOffset - layoutBounds.height() + dividerMetrics.height() + dateDeviderMargin * 2;
|
||||||
if (modelState != Models::MessageFeed::complete) {
|
if (modelState != Models::MessageFeed::complete) {
|
||||||
totalHeight += progressSize;
|
totalHeight += progressSize;
|
||||||
}
|
}
|
||||||
@ -240,7 +254,7 @@ void FeedView::updateGeometries()
|
|||||||
|
|
||||||
bool FeedView::tryToCalculateGeometriesWithNoScrollbars(const QStyleOptionViewItem& option, const QAbstractItemModel* m, uint32_t totalHeight)
|
bool FeedView::tryToCalculateGeometriesWithNoScrollbars(const QStyleOptionViewItem& option, const QAbstractItemModel* m, uint32_t totalHeight)
|
||||||
{
|
{
|
||||||
uint32_t previousOffset = 0;
|
uint32_t previousOffset = elementMargin;
|
||||||
bool success = true;
|
bool success = true;
|
||||||
QDateTime lastDate;
|
QDateTime lastDate;
|
||||||
for (int i = 0, size = m->rowCount(); i < size; ++i) {
|
for (int i = 0, size = m->rowCount(); i < size; ++i) {
|
||||||
@ -249,21 +263,39 @@ bool FeedView::tryToCalculateGeometriesWithNoScrollbars(const QStyleOptionViewIt
|
|||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
if (currentDate.daysTo(lastDate) > 0) {
|
if (currentDate.daysTo(lastDate) > 0) {
|
||||||
previousOffset += dateDeviderMargin * 2 + dividerMetrics.height();
|
previousOffset += dateDeviderMargin * 2 + dividerMetrics.height();
|
||||||
|
} else {
|
||||||
|
previousOffset += elementMargin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastDate = currentDate;
|
lastDate = currentDate;
|
||||||
int height = itemDelegate(index)->sizeHint(option, index).height();
|
QSize messageSize = itemDelegate(index)->sizeHint(option, index);
|
||||||
|
|
||||||
if (previousOffset + height > totalHeight) {
|
if (previousOffset + messageSize.height() + elementMargin > totalHeight) {
|
||||||
success = false;
|
success = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t offsetX(0);
|
||||||
|
if (specialDelegate) {
|
||||||
|
if (index.data(Models::MessageFeed::SentByMe).toBool()) {
|
||||||
|
offsetX = option.rect.width() - messageSize.width() - MessageDelegate::avatarHeight - MessageDelegate::margin * 2;
|
||||||
|
} else {
|
||||||
|
offsetX = MessageDelegate::avatarHeight + MessageDelegate::margin * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
hints.emplace_back(Hint({
|
hints.emplace_back(Hint({
|
||||||
false,
|
false,
|
||||||
previousOffset,
|
previousOffset,
|
||||||
static_cast<uint32_t>(height)
|
static_cast<uint32_t>(messageSize.height()),
|
||||||
|
static_cast<uint32_t>(messageSize.width()),
|
||||||
|
offsetX
|
||||||
}));
|
}));
|
||||||
previousOffset += height;
|
previousOffset += messageSize.height();
|
||||||
|
}
|
||||||
|
|
||||||
|
previousOffset += dateDeviderMargin * 2 + dividerMetrics.height();
|
||||||
|
if (previousOffset > totalHeight) {
|
||||||
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
@ -336,7 +368,7 @@ void FeedView::paintEvent(QPaintEvent* event)
|
|||||||
lastDate = currentDate;
|
lastDate = currentDate;
|
||||||
}
|
}
|
||||||
if (!lastDate.isNull() && inZone) { //if after drawing all messages there is still space
|
if (!lastDate.isNull() && inZone) { //if after drawing all messages there is still space
|
||||||
drawDateDevider(option.rect.bottom(), lastDate, painter);
|
drawDateDevider(option.rect.top() - dateDeviderMargin * 2 - dividerMetrics.height(), lastDate, painter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clearWidgetsMode && specialDelegate) {
|
if (clearWidgetsMode && specialDelegate) {
|
||||||
@ -423,10 +455,12 @@ void FeedView::setItemDelegate(QAbstractItemDelegate* delegate)
|
|||||||
MessageDelegate* del = dynamic_cast<MessageDelegate*>(delegate);
|
MessageDelegate* del = dynamic_cast<MessageDelegate*>(delegate);
|
||||||
if (del) {
|
if (del) {
|
||||||
specialDelegate = true;
|
specialDelegate = true;
|
||||||
|
elementMargin = MessageDelegate::margin;
|
||||||
connect(del, &MessageDelegate::buttonPushed, this, &FeedView::onMessageButtonPushed);
|
connect(del, &MessageDelegate::buttonPushed, this, &FeedView::onMessageButtonPushed);
|
||||||
connect(del, &MessageDelegate::invalidPath, this, &FeedView::onMessageInvalidPath);
|
connect(del, &MessageDelegate::invalidPath, this, &FeedView::onMessageInvalidPath);
|
||||||
} else {
|
} else {
|
||||||
specialDelegate = false;
|
specialDelegate = false;
|
||||||
|
elementMargin = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,9 +80,12 @@ private:
|
|||||||
bool dirty;
|
bool dirty;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t x;
|
||||||
};
|
};
|
||||||
std::deque<Hint> hints;
|
std::deque<Hint> hints;
|
||||||
int vo;
|
int vo;
|
||||||
|
int elementMargin;
|
||||||
bool specialDelegate;
|
bool specialDelegate;
|
||||||
bool specialModel;
|
bool specialModel;
|
||||||
bool clearWidgetsMode;
|
bool clearWidgetsMode;
|
||||||
|
@ -26,8 +26,8 @@
|
|||||||
#include "messagedelegate.h"
|
#include "messagedelegate.h"
|
||||||
#include "messagefeed.h"
|
#include "messagefeed.h"
|
||||||
|
|
||||||
constexpr int avatarHeight = 50;
|
int MessageDelegate::avatarHeight(50);
|
||||||
constexpr int margin = 6;
|
int MessageDelegate::margin(6);
|
||||||
constexpr int textMargin = 2;
|
constexpr int textMargin = 2;
|
||||||
constexpr int statusIconSize = 16;
|
constexpr int statusIconSize = 16;
|
||||||
constexpr float nickFontMultiplier = 1.1;
|
constexpr float nickFontMultiplier = 1.1;
|
||||||
@ -45,6 +45,7 @@ MessageDelegate::MessageDelegate(QObject* parent):
|
|||||||
nickMetrics(nickFont),
|
nickMetrics(nickFont),
|
||||||
dateMetrics(dateFont),
|
dateMetrics(dateFont),
|
||||||
buttonHeight(0),
|
buttonHeight(0),
|
||||||
|
buttonWidth(0),
|
||||||
barHeight(0),
|
barHeight(0),
|
||||||
buttons(new std::map<QString, FeedButton*>()),
|
buttons(new std::map<QString, FeedButton*>()),
|
||||||
bars(new std::map<QString, QProgressBar*>()),
|
bars(new std::map<QString, QProgressBar*>()),
|
||||||
@ -55,8 +56,9 @@ MessageDelegate::MessageDelegate(QObject* parent):
|
|||||||
idsToKeep(new std::set<QString>()),
|
idsToKeep(new std::set<QString>()),
|
||||||
clearingWidgets(false)
|
clearingWidgets(false)
|
||||||
{
|
{
|
||||||
QPushButton btn;
|
QPushButton btn(QCoreApplication::translate("MessageLine", "Download"));
|
||||||
buttonHeight = btn.sizeHint().height();
|
buttonHeight = btn.sizeHint().height();
|
||||||
|
buttonWidth = btn.sizeHint().width();
|
||||||
|
|
||||||
QProgressBar bar;
|
QProgressBar bar;
|
||||||
barHeight = bar.sizeHint().height();
|
barHeight = bar.sizeHint().height();
|
||||||
@ -107,141 +109,79 @@ void MessageDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio
|
|||||||
painter->save();
|
painter->save();
|
||||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||||
|
|
||||||
// if (option.state & QStyle::State_MouseOver) {
|
paintBubble(data, painter, option);
|
||||||
// painter->fillRect(option.rect, option.palette.brush(QPalette::Inactive, QPalette::Highlight));
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
bool ntds = needToDrawSender(index, data);
|
bool ntds = needToDrawSender(index, data);
|
||||||
if (ntds || option.rect.y() < 1) {
|
if (ntds || option.rect.y() < 1) {
|
||||||
paintAvatar(data, index, option, painter);
|
paintAvatar(data, index, option, painter);
|
||||||
}
|
}
|
||||||
|
|
||||||
QStyleOptionViewItem opt = option;
|
QStyleOptionViewItem opt = option;
|
||||||
QRect messageRect = option.rect.adjusted(margin, margin / 2, -(avatarHeight + 2 * margin), -margin / 2);
|
opt.rect = option.rect.adjusted(bubbleMargin, bubbleMargin, -bubbleMargin, -bubbleMargin / 2);
|
||||||
if (!data.sentByMe) {
|
if (!data.sentByMe) {
|
||||||
opt.displayAlignment = Qt::AlignLeft | Qt::AlignTop;
|
opt.displayAlignment = Qt::AlignLeft | Qt::AlignTop;
|
||||||
messageRect.adjust(avatarHeight + margin, 0, avatarHeight + margin, 0);
|
|
||||||
} else {
|
} else {
|
||||||
opt.displayAlignment = Qt::AlignRight | Qt::AlignTop;
|
opt.displayAlignment = Qt::AlignRight | Qt::AlignTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint bubbleBegin = messageRect.topLeft();
|
|
||||||
messageRect.adjust(bubbleMargin, bubbleMargin, -bubbleMargin, -bubbleMargin / 2);
|
|
||||||
opt.rect = messageRect;
|
|
||||||
|
|
||||||
QSize messageSize(0, 0);
|
|
||||||
QSize bodySize(0, 0);
|
QSize bodySize(0, 0);
|
||||||
if (data.text.size() > 0) {
|
if (data.text.size() > 0) {
|
||||||
messageSize = bodyMetrics.boundingRect(messageRect, Qt::TextWordWrap, data.text).size();
|
bodySize = bodyMetrics.boundingRect(opt.rect, Qt::TextWordWrap, data.text).size();
|
||||||
bodySize = messageSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
messageSize.rheight() += dateMetrics.height();
|
|
||||||
QString dateString = data.date.toLocalTime().toString("hh:mm");
|
|
||||||
|
|
||||||
if (messageSize.width() < opt.rect.width()) {
|
|
||||||
if (ntds) {
|
|
||||||
QSize senderSize = nickMetrics.boundingRect(messageRect, 0, data.sender).size();
|
|
||||||
if (senderSize.width() > messageSize.width()) {
|
|
||||||
messageSize.setWidth(senderSize.width());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QSize dateSize = dateMetrics.boundingRect(messageRect, 0, dateString).size();
|
|
||||||
int addition = 0;
|
|
||||||
|
|
||||||
if (data.correction.corrected) {
|
|
||||||
addition += margin + statusIconSize;
|
|
||||||
}
|
|
||||||
if (data.sentByMe) {
|
|
||||||
addition += margin + statusIconSize;
|
|
||||||
}
|
|
||||||
if (dateSize.width() + addition > messageSize.width()) {
|
|
||||||
messageSize.setWidth(dateSize.width() + addition);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
messageSize.setWidth(opt.rect.width());
|
|
||||||
}
|
|
||||||
|
|
||||||
painter->save();
|
|
||||||
|
|
||||||
int storedY = opt.rect.y();
|
|
||||||
if (ntds) {
|
|
||||||
opt.rect.adjust(0, nickMetrics.lineSpacing() + textMargin, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int attWidth(0);
|
|
||||||
switch (data.attach.state) {
|
|
||||||
case Models::none:
|
|
||||||
clearHelperWidget(data); //i can't imagine the situation where it's gonna be needed
|
|
||||||
break; //but it's a possible performance problem
|
|
||||||
case Models::uploading:
|
|
||||||
attWidth = std::max(paintPreview(data, painter, opt), attWidth);
|
|
||||||
[[fallthrough]];
|
|
||||||
case Models::downloading:
|
|
||||||
messageSize.setWidth(opt.rect.width());
|
|
||||||
messageSize.rheight() += barHeight + textMargin + opt.rect.y() - storedY;
|
|
||||||
paintBubble(data, painter, messageSize, opt, bubbleBegin);
|
|
||||||
attWidth = std::max(paintBar(getBar(data), painter, data.sentByMe, opt), attWidth);
|
|
||||||
break;
|
|
||||||
case Models::remote:
|
|
||||||
attWidth = std::max(paintButton(getButton(data), painter, data.sentByMe, opt), attWidth);
|
|
||||||
break;
|
|
||||||
case Models::ready:
|
|
||||||
case Models::local:
|
|
||||||
clearHelperWidget(data);
|
|
||||||
attWidth = std::max(paintPreview(data, painter, opt), attWidth);
|
|
||||||
break;
|
|
||||||
case Models::errorDownload: {
|
|
||||||
attWidth = std::max(paintButton(getButton(data), painter, data.sentByMe, opt), attWidth);
|
|
||||||
attWidth = std::max(paintComment(data, painter, opt), attWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case Models::errorUpload:{
|
|
||||||
clearHelperWidget(data);
|
|
||||||
attWidth = std::max(paintPreview(data, painter, opt), attWidth);
|
|
||||||
attWidth = std::max(paintComment(data, painter, opt), attWidth);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
painter->restore();
|
|
||||||
if (data.attach.state != Models::uploading && data.attach.state != Models::downloading) {
|
|
||||||
messageSize.rheight() += opt.rect.y() - storedY;
|
|
||||||
messageSize.setWidth(std::max(attWidth, messageSize.width()));
|
|
||||||
paintBubble(data, painter, messageSize, opt, bubbleBegin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect rect;
|
QRect rect;
|
||||||
if (ntds) {
|
if (ntds) {
|
||||||
painter->setFont(nickFont);
|
painter->setFont(nickFont);
|
||||||
int storedY2 = opt.rect.y();
|
|
||||||
opt.rect.setY(storedY);
|
|
||||||
painter->drawText(opt.rect, opt.displayAlignment, data.sender, &rect);
|
painter->drawText(opt.rect, opt.displayAlignment, data.sender, &rect);
|
||||||
opt.rect.setY(storedY2);
|
opt.rect.adjust(0, nickMetrics.lineSpacing() + textMargin, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
painter->save();
|
||||||
|
switch (data.attach.state) {
|
||||||
|
case Models::none:
|
||||||
|
clearHelperWidget(data); //i can't imagine the situation where it's gonna be needed
|
||||||
|
break; //but it's a possible performance problem
|
||||||
|
case Models::uploading:
|
||||||
|
paintPreview(data, painter, opt);
|
||||||
|
[[fallthrough]];
|
||||||
|
case Models::downloading:
|
||||||
|
paintBar(getBar(data), painter, data.sentByMe, opt);
|
||||||
|
break;
|
||||||
|
case Models::remote:
|
||||||
|
paintButton(getButton(data), painter, data.sentByMe, opt);
|
||||||
|
break;
|
||||||
|
case Models::ready:
|
||||||
|
case Models::local:
|
||||||
|
clearHelperWidget(data);
|
||||||
|
paintPreview(data, painter, opt);
|
||||||
|
break;
|
||||||
|
case Models::errorDownload: {
|
||||||
|
paintButton(getButton(data), painter, data.sentByMe, opt);
|
||||||
|
paintComment(data, painter, opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case Models::errorUpload:{
|
||||||
|
clearHelperWidget(data);
|
||||||
|
paintPreview(data, painter, opt);
|
||||||
|
paintComment(data, painter, opt);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
painter->restore();
|
||||||
|
|
||||||
int messageLeft = INT16_MAX;
|
|
||||||
int messageRight = opt.rect.x() + messageSize.width();
|
|
||||||
QWidget* vp = static_cast<QWidget*>(painter->device());
|
QWidget* vp = static_cast<QWidget*>(painter->device());
|
||||||
if (data.text.size() > 0) {
|
if (data.text.size() > 0) {
|
||||||
QLabel* body = getBody(data);
|
QLabel* body = getBody(data);
|
||||||
body->setParent(vp);
|
body->setParent(vp);
|
||||||
body->setMaximumWidth(bodySize.width());
|
body->setMinimumSize(bodySize);
|
||||||
body->setMinimumWidth(bodySize.width());
|
body->setMaximumSize(bodySize);
|
||||||
body->setMinimumHeight(bodySize.height());
|
body->move(opt.rect.left(), opt.rect.y());
|
||||||
body->setMaximumHeight(bodySize.height());
|
|
||||||
body->setAlignment(opt.displayAlignment);
|
|
||||||
messageLeft = opt.rect.x();
|
|
||||||
if (data.sentByMe) {
|
|
||||||
messageLeft = opt.rect.topRight().x() - bodySize.width();
|
|
||||||
}
|
|
||||||
body->move(messageLeft, opt.rect.y());
|
|
||||||
body->show();
|
body->show();
|
||||||
opt.rect.adjust(0, bodySize.height() + textMargin, 0, 0);
|
opt.rect.adjust(0, bodySize.height() + textMargin, 0, 0);
|
||||||
}
|
}
|
||||||
painter->setFont(dateFont);
|
painter->setFont(dateFont);
|
||||||
QColor q = painter->pen().color();
|
QColor q = painter->pen().color();
|
||||||
|
QString dateString = data.date.toLocalTime().toString("hh:mm");
|
||||||
q.setAlpha(180);
|
q.setAlpha(180);
|
||||||
painter->setPen(q);
|
painter->setPen(q);
|
||||||
painter->drawText(opt.rect, opt.displayAlignment, dateString, &rect);
|
painter->drawText(opt.rect, opt.displayAlignment, dateString, &rect);
|
||||||
@ -250,7 +190,7 @@ void MessageDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio
|
|||||||
QLabel* statusIcon = getStatusIcon(data);
|
QLabel* statusIcon = getStatusIcon(data);
|
||||||
|
|
||||||
statusIcon->setParent(vp);
|
statusIcon->setParent(vp);
|
||||||
statusIcon->move(opt.rect.topRight().x() - messageSize.width(), currentY);
|
statusIcon->move(opt.rect.left(), currentY);
|
||||||
statusIcon->show();
|
statusIcon->show();
|
||||||
|
|
||||||
opt.rect.adjust(0, statusIconSize + textMargin, 0, 0);
|
opt.rect.adjust(0, statusIconSize + textMargin, 0, 0);
|
||||||
@ -261,9 +201,9 @@ void MessageDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio
|
|||||||
|
|
||||||
pencilIcon->setParent(vp);
|
pencilIcon->setParent(vp);
|
||||||
if (data.sentByMe) {
|
if (data.sentByMe) {
|
||||||
pencilIcon->move(opt.rect.topRight().x() - messageSize.width() + statusIconSize + margin, currentY);
|
pencilIcon->move(opt.rect.left() + statusIconSize + margin, currentY);
|
||||||
} else {
|
} else {
|
||||||
pencilIcon->move(messageRight - statusIconSize - margin, currentY);
|
pencilIcon->move(opt.rect.right() - statusIconSize - margin, currentY);
|
||||||
}
|
}
|
||||||
pencilIcon->show();
|
pencilIcon->show();
|
||||||
} else {
|
} else {
|
||||||
@ -281,19 +221,16 @@ void MessageDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageDelegate::paintBubble(const Models::FeedItem& data, QPainter* painter, const QSize& messageSize, QStyleOptionViewItem& option, QPoint bubbleBegin) const
|
void MessageDelegate::paintBubble(const Models::FeedItem& data, QPainter* painter, const QStyleOptionViewItem& option) const
|
||||||
{
|
{
|
||||||
painter->save();
|
painter->save();
|
||||||
if (data.sentByMe) {
|
if (data.sentByMe) {
|
||||||
bubbleBegin.setX(option.rect.topRight().x() - messageSize.width() - bubbleMargin);
|
|
||||||
painter->setBrush(option.palette.brush(QPalette::Inactive, QPalette::Highlight));
|
painter->setBrush(option.palette.brush(QPalette::Inactive, QPalette::Highlight));
|
||||||
} else {
|
} else {
|
||||||
painter->setBrush(option.palette.brush(QPalette::Window));
|
painter->setBrush(option.palette.brush(QPalette::Window));
|
||||||
}
|
}
|
||||||
QSize bubbleAddition(2 * bubbleMargin, 1.5 * bubbleMargin);
|
|
||||||
QRect bubble(bubbleBegin, messageSize + bubbleAddition);
|
|
||||||
painter->setPen(Qt::NoPen);
|
painter->setPen(Qt::NoPen);
|
||||||
painter->drawRoundedRect(bubble, bubbleBorderRadius, bubbleBorderRadius);
|
painter->drawRoundedRect(option.rect, bubbleBorderRadius, bubbleBorderRadius);
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,7 +267,7 @@ void MessageDelegate::paintAvatar(const Models::FeedItem& data, const QModelInde
|
|||||||
int ax;
|
int ax;
|
||||||
|
|
||||||
if (data.sentByMe) {
|
if (data.sentByMe) {
|
||||||
ax = option.rect.width() - avatarHeight - margin;
|
ax = option.rect.x() + option.rect.width() + margin;
|
||||||
} else {
|
} else {
|
||||||
ax = margin;
|
ax = margin;
|
||||||
}
|
}
|
||||||
@ -381,36 +318,51 @@ QSize MessageDelegate::sizeHint(const QStyleOptionViewItem& option, const QModel
|
|||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case Models::downloading:
|
case Models::downloading:
|
||||||
messageSize.rheight() += barHeight + textMargin;
|
messageSize.rheight() += barHeight + textMargin;
|
||||||
|
messageSize.setWidth(messageRect.width());
|
||||||
break;
|
break;
|
||||||
case Models::remote:
|
case Models::remote:
|
||||||
messageSize.rheight() += buttonHeight + textMargin;
|
messageSize.rheight() += buttonHeight + textMargin;
|
||||||
|
messageSize.setWidth(std::max(messageSize.width(), buttonWidth));
|
||||||
break;
|
break;
|
||||||
case Models::ready:
|
case Models::ready:
|
||||||
case Models::local:
|
case Models::local: {
|
||||||
messageSize.rheight() += Preview::calculateAttachSize(data.attach.localPath, messageRect).height() + textMargin;
|
QSize aSize = Preview::calculateAttachSize(data.attach.localPath, messageRect);
|
||||||
|
messageSize.rheight() += aSize.height() + textMargin;
|
||||||
|
messageSize.setWidth(std::max(messageSize.width(), aSize.width()));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Models::errorDownload:
|
case Models::errorDownload: {
|
||||||
messageSize.rheight() += buttonHeight + textMargin;
|
QSize commentSize = dateMetrics.boundingRect(messageRect, Qt::TextWordWrap, data.attach.error).size();
|
||||||
messageSize.rheight() += dateMetrics.boundingRect(messageRect, Qt::TextWordWrap, data.attach.error).size().height() + textMargin;
|
messageSize.rheight() += commentSize.height() + buttonHeight + textMargin * 2;
|
||||||
|
messageSize.setWidth(std::max(messageSize.width(), std::max(commentSize.width(), buttonWidth)));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Models::errorUpload:
|
case Models::errorUpload: {
|
||||||
messageSize.rheight() += Preview::calculateAttachSize(data.attach.localPath, messageRect).height() + textMargin;
|
QSize aSize = Preview::calculateAttachSize(data.attach.localPath, messageRect);
|
||||||
messageSize.rheight() += dateMetrics.boundingRect(messageRect, Qt::TextWordWrap, data.attach.error).size().height() + textMargin;
|
QSize commentSize = dateMetrics.boundingRect(messageRect, Qt::TextWordWrap, data.attach.error).size();
|
||||||
|
messageSize.rheight() += aSize.height() + commentSize.height() + textMargin * 2;
|
||||||
|
messageSize.setWidth(std::max(messageSize.width(), std::max(commentSize.width(), aSize.width())));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needToDrawSender(index, data)) {
|
if (needToDrawSender(index, data)) {
|
||||||
messageSize.rheight() += nickMetrics.lineSpacing() + textMargin;
|
QSize senderSize = nickMetrics.boundingRect(messageRect, 0, data.sender).size();
|
||||||
|
messageSize.rheight() += senderSize.height() + textMargin;
|
||||||
|
messageSize.setWidth(std::max(senderSize.width(), messageSize.width()));
|
||||||
}
|
}
|
||||||
|
|
||||||
messageSize.rheight() += bubbleMargin + bubbleMargin / 2;
|
QString dateString = data.date.toLocalTime().toString("hh:mm");
|
||||||
messageSize.rheight() += dateMetrics.height() > statusIconSize ? dateMetrics.height() : statusIconSize;
|
QSize dateSize = dateMetrics.boundingRect(messageRect, 0, dateString).size();
|
||||||
|
messageSize.rheight() += bubbleMargin * 1.5;
|
||||||
// if (messageSize.height() < avatarHeight) {
|
messageSize.rheight() += dateSize.height() > statusIconSize ? dateSize.height() : statusIconSize;
|
||||||
// messageSize.setHeight(avatarHeight);
|
|
||||||
// }
|
int statusWidth = dateSize.width() + statusIconSize + margin;
|
||||||
|
if (data.correction.corrected) {
|
||||||
messageSize.rheight() += margin;
|
statusWidth += statusIconSize + margin;
|
||||||
|
}
|
||||||
|
messageSize.setWidth(std::max(statusWidth, messageSize.width()));
|
||||||
|
messageSize.rwidth() += 2 * bubbleMargin;
|
||||||
|
|
||||||
return messageSize;
|
return messageSize;
|
||||||
}
|
}
|
||||||
@ -508,7 +460,7 @@ int MessageDelegate::paintPreview(const Models::FeedItem& data, QPainter* painte
|
|||||||
preview->actualize(data.attach.localPath, size, option.rect.topLeft());
|
preview->actualize(data.attach.localPath, size, option.rect.topLeft());
|
||||||
} else {
|
} else {
|
||||||
QWidget* vp = static_cast<QWidget*>(painter->device());
|
QWidget* vp = static_cast<QWidget*>(painter->device());
|
||||||
preview = new Preview(data.attach.localPath, size, option.rect.topLeft(), data.sentByMe, vp);
|
preview = new Preview(data.attach.localPath, size, option.rect.topLeft(), vp);
|
||||||
previews->insert(std::make_pair(data.id, preview));
|
previews->insert(std::make_pair(data.id, preview));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +55,9 @@ public:
|
|||||||
bool editorEvent(QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index) override;
|
bool editorEvent(QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index) override;
|
||||||
void endClearWidgets();
|
void endClearWidgets();
|
||||||
void beginClearWidgets();
|
void beginClearWidgets();
|
||||||
|
|
||||||
|
static int avatarHeight;
|
||||||
|
static int margin;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void buttonPushed(const QString& messageId) const;
|
void buttonPushed(const QString& messageId) const;
|
||||||
@ -66,7 +69,7 @@ protected:
|
|||||||
int paintPreview(const Models::FeedItem& data, QPainter* painter, QStyleOptionViewItem& option) const;
|
int paintPreview(const Models::FeedItem& data, QPainter* painter, QStyleOptionViewItem& option) const;
|
||||||
int paintComment(const Models::FeedItem& data, QPainter* painter, QStyleOptionViewItem& option) const;
|
int paintComment(const Models::FeedItem& data, QPainter* painter, QStyleOptionViewItem& option) const;
|
||||||
void paintAvatar(const Models::FeedItem& data, const QModelIndex& index, const QStyleOptionViewItem& option, QPainter* painter) const;
|
void paintAvatar(const Models::FeedItem& data, const QModelIndex& index, const QStyleOptionViewItem& option, QPainter* painter) const;
|
||||||
void paintBubble(const Models::FeedItem& data, QPainter* painter, const QSize& messageSize, QStyleOptionViewItem& option, QPoint bubbleBegin) const;
|
void paintBubble(const Models::FeedItem& data, QPainter* painter, const QStyleOptionViewItem& option) const;
|
||||||
QPushButton* getButton(const Models::FeedItem& data) const;
|
QPushButton* getButton(const Models::FeedItem& data) const;
|
||||||
QProgressBar* getBar(const Models::FeedItem& data) const;
|
QProgressBar* getBar(const Models::FeedItem& data) const;
|
||||||
QLabel* getStatusIcon(const Models::FeedItem& data) const;
|
QLabel* getStatusIcon(const Models::FeedItem& data) const;
|
||||||
@ -94,6 +97,7 @@ private:
|
|||||||
QFontMetrics dateMetrics;
|
QFontMetrics dateMetrics;
|
||||||
|
|
||||||
int buttonHeight;
|
int buttonHeight;
|
||||||
|
int buttonWidth;
|
||||||
int barHeight;
|
int barHeight;
|
||||||
|
|
||||||
std::map<QString, FeedButton*>* buttons;
|
std::map<QString, FeedButton*>* buttons;
|
||||||
|
@ -25,9 +25,8 @@ constexpr int maxAttachmentHeight = 500;
|
|||||||
QFont Preview::font;
|
QFont Preview::font;
|
||||||
QFontMetrics Preview::metrics(Preview::font);
|
QFontMetrics Preview::metrics(Preview::font);
|
||||||
|
|
||||||
Preview::Preview(const QString& pPath, const QSize& pMaxSize, const QPoint& pos, bool pRight, QWidget* pParent):
|
Preview::Preview(const QString& pPath, const QSize& pMaxSize, const QPoint& pos, QWidget* pParent):
|
||||||
info(Shared::Global::getFileInfo(pPath)),
|
info(Shared::Global::getFileInfo(pPath)),
|
||||||
path(pPath),
|
|
||||||
maxSize(pMaxSize),
|
maxSize(pMaxSize),
|
||||||
actualSize(constrainAttachSize(info.size, maxSize)),
|
actualSize(constrainAttachSize(info.size, maxSize)),
|
||||||
cachedLabelSize(0, 0),
|
cachedLabelSize(0, 0),
|
||||||
@ -37,8 +36,7 @@ Preview::Preview(const QString& pPath, const QSize& pMaxSize, const QPoint& pos,
|
|||||||
parent(pParent),
|
parent(pParent),
|
||||||
movie(0),
|
movie(0),
|
||||||
fileReachable(true),
|
fileReachable(true),
|
||||||
actualPreview(false),
|
actualPreview(false)
|
||||||
right(pRight)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
initializeElements();
|
initializeElements();
|
||||||
@ -104,9 +102,6 @@ void Preview::actualize(const QString& newPath, const QSize& newSize, const QPoi
|
|||||||
}
|
}
|
||||||
} else if (maxSizeChanged) {
|
} else if (maxSizeChanged) {
|
||||||
applyNewMaxSize();
|
applyNewMaxSize();
|
||||||
if (right) {
|
|
||||||
positionChanged = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (positionChanged || !actualPreview) {
|
if (positionChanged || !actualPreview) {
|
||||||
positionElements();
|
positionElements();
|
||||||
@ -135,9 +130,6 @@ void Preview::setSize(const QSize& newSize)
|
|||||||
}
|
}
|
||||||
if (maxSizeChanged || !actualPreview) {
|
if (maxSizeChanged || !actualPreview) {
|
||||||
applyNewMaxSize();
|
applyNewMaxSize();
|
||||||
if (right) {
|
|
||||||
positionElements();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,7 +138,7 @@ void Preview::applyNewSize()
|
|||||||
{
|
{
|
||||||
switch (info.preview) {
|
switch (info.preview) {
|
||||||
case Shared::Global::FileInfo::Preview::picture: {
|
case Shared::Global::FileInfo::Preview::picture: {
|
||||||
QImageReader img(path);
|
QImageReader img(info.path);
|
||||||
if (!img.canRead()) {
|
if (!img.canRead()) {
|
||||||
delete widget;
|
delete widget;
|
||||||
fileReachable = false;
|
fileReachable = false;
|
||||||
@ -216,9 +208,8 @@ void Preview::setPosition(const QPoint& newPoint)
|
|||||||
|
|
||||||
bool Preview::setPath(const QString& newPath)
|
bool Preview::setPath(const QString& newPath)
|
||||||
{
|
{
|
||||||
if (path != newPath) {
|
if (info.path != newPath) {
|
||||||
path = newPath;
|
info = Shared::Global::getFileInfo(newPath);
|
||||||
info = Shared::Global::getFileInfo(path);
|
|
||||||
actualSize = constrainAttachSize(info.size, maxSize);
|
actualSize = constrainAttachSize(info.size, maxSize);
|
||||||
clean();
|
clean();
|
||||||
initializeElements();
|
initializeElements();
|
||||||
@ -235,7 +226,7 @@ void Preview::initializeElements()
|
|||||||
{
|
{
|
||||||
switch (info.preview) {
|
switch (info.preview) {
|
||||||
case Shared::Global::FileInfo::Preview::picture: {
|
case Shared::Global::FileInfo::Preview::picture: {
|
||||||
QImageReader img(path);
|
QImageReader img(info.path);
|
||||||
if (!img.canRead()) {
|
if (!img.canRead()) {
|
||||||
fileReachable = false;
|
fileReachable = false;
|
||||||
} else {
|
} else {
|
||||||
@ -248,7 +239,7 @@ void Preview::initializeElements()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Shared::Global::FileInfo::Preview::animation:{
|
case Shared::Global::FileInfo::Preview::animation:{
|
||||||
movie = new QMovie(path);
|
movie = new QMovie(info.path);
|
||||||
QObject::connect(movie, &QMovie::error,
|
QObject::connect(movie, &QMovie::error,
|
||||||
std::bind(&Preview::handleQMovieError, this, std::placeholders::_1)
|
std::bind(&Preview::handleQMovieError, this, std::placeholders::_1)
|
||||||
);
|
);
|
||||||
@ -289,9 +280,6 @@ void Preview::initializeElements()
|
|||||||
void Preview::positionElements()
|
void Preview::positionElements()
|
||||||
{
|
{
|
||||||
int start = position.x();
|
int start = position.x();
|
||||||
if (right) {
|
|
||||||
start += maxSize.width() - size().width();
|
|
||||||
}
|
|
||||||
widget->move(start, position.y());
|
widget->move(start, position.y());
|
||||||
if (!actualPreview) {
|
if (!actualPreview) {
|
||||||
int x = start + actualSize.width() + margin;
|
int x = start + actualSize.width() + margin;
|
||||||
@ -300,11 +288,36 @@ void Preview::positionElements()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Preview::canVisualize(const Shared::Global::FileInfo& info)
|
||||||
|
{
|
||||||
|
switch (info.preview) {
|
||||||
|
case Shared::Global::FileInfo::Preview::picture: {
|
||||||
|
QImageReader img(info.path);
|
||||||
|
return img.canRead();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Shared::Global::FileInfo::Preview::animation:{
|
||||||
|
QMovie movie(info.path);
|
||||||
|
return movie.isValid();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QSize Preview::calculateAttachSize(const QString& path, const QRect& bounds)
|
QSize Preview::calculateAttachSize(const QString& path, const QRect& bounds)
|
||||||
{
|
{
|
||||||
Shared::Global::FileInfo info = Shared::Global::getFileInfo(path);
|
Shared::Global::FileInfo info = Shared::Global::getFileInfo(path);
|
||||||
|
QSize constrained = constrainAttachSize(info.size, bounds.size());
|
||||||
return constrainAttachSize(info.size, bounds.size());
|
if (!canVisualize(info)) {
|
||||||
|
int maxLabelWidth = bounds.width() - info.size.width() - margin;
|
||||||
|
QString elidedName = metrics.elidedText(info.name, Qt::ElideMiddle, maxLabelWidth);
|
||||||
|
int labelWidth = metrics.boundingRect(elidedName).size().width();
|
||||||
|
constrained.rwidth() += margin + labelWidth;
|
||||||
|
}
|
||||||
|
return constrained;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize Preview::constrainAttachSize(QSize src, QSize bounds)
|
QSize Preview::constrainAttachSize(QSize src, QSize bounds)
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
*/
|
*/
|
||||||
class Preview {
|
class Preview {
|
||||||
public:
|
public:
|
||||||
Preview(const QString& pPath, const QSize& pMaxSize, const QPoint& pos, bool pRight, QWidget* parent);
|
Preview(const QString& pPath, const QSize& pMaxSize, const QPoint& pos, QWidget* parent);
|
||||||
~Preview();
|
~Preview();
|
||||||
|
|
||||||
void actualize(const QString& newPath, const QSize& newSize, const QPoint& newPoint);
|
void actualize(const QString& newPath, const QSize& newSize, const QPoint& newPoint);
|
||||||
@ -51,6 +51,7 @@ public:
|
|||||||
static void initializeFont(const QFont& newFont);
|
static void initializeFont(const QFont& newFont);
|
||||||
static QSize constrainAttachSize(QSize src, QSize bounds);
|
static QSize constrainAttachSize(QSize src, QSize bounds);
|
||||||
static QSize calculateAttachSize(const QString& path, const QRect& bounds);
|
static QSize calculateAttachSize(const QString& path, const QRect& bounds);
|
||||||
|
static bool canVisualize(const Shared::Global::FileInfo& info);
|
||||||
static QFont font;
|
static QFont font;
|
||||||
static QFontMetrics metrics;
|
static QFontMetrics metrics;
|
||||||
|
|
||||||
@ -64,7 +65,6 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Shared::Global::FileInfo info;
|
Shared::Global::FileInfo info;
|
||||||
QString path;
|
|
||||||
QSize maxSize;
|
QSize maxSize;
|
||||||
QSize actualSize;
|
QSize actualSize;
|
||||||
QSize cachedLabelSize;
|
QSize cachedLabelSize;
|
||||||
@ -75,7 +75,6 @@ private:
|
|||||||
QMovie* movie;
|
QMovie* movie;
|
||||||
bool fileReachable;
|
bool fileReachable;
|
||||||
bool actualPreview;
|
bool actualPreview;
|
||||||
bool right;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PREVIEW_H
|
#endif // PREVIEW_H
|
||||||
|
Loading…
Reference in New Issue
Block a user