forked from blue/squawk
a little bit of restyling, now the integration with transparent themes is supposed to be better
This commit is contained in:
parent
ff2c9831cf
commit
c793f56647
@ -466,7 +466,7 @@ void Core::Account::onPresenceReceived(const QXmppPresence& p_presence)
|
|||||||
case QXmppPresence::Available:{
|
case QXmppPresence::Available:{
|
||||||
QDateTime lastInteraction = p_presence.lastUserInteraction();
|
QDateTime lastInteraction = p_presence.lastUserInteraction();
|
||||||
if (!lastInteraction.isValid()) {
|
if (!lastInteraction.isValid()) {
|
||||||
lastInteraction = QDateTime::currentDateTime();
|
lastInteraction = QDateTime::currentDateTimeUtc();
|
||||||
}
|
}
|
||||||
emit addPresence(jid, resource, {
|
emit addPresence(jid, resource, {
|
||||||
{"lastActivity", lastInteraction},
|
{"lastActivity", lastInteraction},
|
||||||
@ -791,7 +791,7 @@ bool Core::Account::handleGroupMessage(const QXmppMessage& msg, bool outgoing, b
|
|||||||
emit changeMessage(jid, oId, cData);
|
emit changeMessage(jid, oId, cData);
|
||||||
} else {
|
} else {
|
||||||
cnt->appendMessageToArchive(sMsg);
|
cnt->appendMessageToArchive(sMsg);
|
||||||
QDateTime minAgo = QDateTime::currentDateTime().addSecs(-60);
|
QDateTime minAgo = QDateTime::currentDateTimeUtc().addSecs(-60);
|
||||||
if (sMsg.getTime() > minAgo) { //otherwise it's considered a delayed delivery, most probably MUC history receipt
|
if (sMsg.getTime() > minAgo) { //otherwise it's considered a delayed delivery, most probably MUC history receipt
|
||||||
emit message(sMsg);
|
emit message(sMsg);
|
||||||
} else {
|
} else {
|
||||||
|
@ -140,7 +140,7 @@ void Core::Conference::onRoomParticipantAdded(const QString& p_name)
|
|||||||
QXmppPresence pres = room->participantPresence(p_name);
|
QXmppPresence pres = room->participantPresence(p_name);
|
||||||
QDateTime lastInteraction = pres.lastUserInteraction();
|
QDateTime lastInteraction = pres.lastUserInteraction();
|
||||||
if (!lastInteraction.isValid()) {
|
if (!lastInteraction.isValid()) {
|
||||||
lastInteraction = QDateTime::currentDateTime();
|
lastInteraction = QDateTime::currentDateTimeUtc();
|
||||||
}
|
}
|
||||||
QXmppMucItem mi = pres.mucItem();
|
QXmppMucItem mi = pres.mucItem();
|
||||||
Archive::AvatarInfo info;
|
Archive::AvatarInfo info;
|
||||||
@ -181,7 +181,7 @@ void Core::Conference::onRoomParticipantChanged(const QString& p_name)
|
|||||||
QXmppPresence pres = room->participantPresence(p_name);
|
QXmppPresence pres = room->participantPresence(p_name);
|
||||||
QDateTime lastInteraction = pres.lastUserInteraction();
|
QDateTime lastInteraction = pres.lastUserInteraction();
|
||||||
if (!lastInteraction.isValid()) {
|
if (!lastInteraction.isValid()) {
|
||||||
lastInteraction = QDateTime::currentDateTime();
|
lastInteraction = QDateTime::currentDateTimeUtc();
|
||||||
}
|
}
|
||||||
QXmppMucItem mi = pres.mucItem();
|
QXmppMucItem mi = pres.mucItem();
|
||||||
handlePresence(pres);
|
handlePresence(pres);
|
||||||
|
@ -368,7 +368,7 @@ bool Shared::Message::change(const QMap<QString, QVariant>& data)
|
|||||||
if (dItr != data.end()) {
|
if (dItr != data.end()) {
|
||||||
correctionDate = dItr.value().toDateTime();
|
correctionDate = dItr.value().toDateTime();
|
||||||
} else {
|
} else {
|
||||||
correctionDate = QDateTime::currentDateTime(); //in case there is no information about time of this correction it's applied
|
correctionDate = QDateTime::currentDateTimeUtc(); //in case there is no information about time of this correction it's applied
|
||||||
}
|
}
|
||||||
if (!edited || lastModified < correctionDate) {
|
if (!edited || lastModified < correctionDate) {
|
||||||
originalMessage = body;
|
originalMessage = body;
|
||||||
@ -393,7 +393,7 @@ QString Shared::generateUUID()
|
|||||||
|
|
||||||
void Shared::Message::setCurrentTime()
|
void Shared::Message::setCurrentTime()
|
||||||
{
|
{
|
||||||
time = QDateTime::currentDateTime();
|
time = QDateTime::currentDateTimeUtc();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Shared::Message::getOutOfBandUrl() const
|
QString Shared::Message::getOutOfBandUrl() const
|
||||||
@ -457,7 +457,7 @@ Shared::VCard::VCard():
|
|||||||
birthday(),
|
birthday(),
|
||||||
photoType(Avatar::empty),
|
photoType(Avatar::empty),
|
||||||
photoPath(),
|
photoPath(),
|
||||||
receivingTime(QDateTime::currentDateTime()),
|
receivingTime(QDateTime::currentDateTimeUtc()),
|
||||||
emails(),
|
emails(),
|
||||||
phones(),
|
phones(),
|
||||||
addresses()
|
addresses()
|
||||||
|
@ -32,6 +32,7 @@ set(squawkUI_SRC
|
|||||||
utils/badge.cpp
|
utils/badge.cpp
|
||||||
utils/progress.cpp
|
utils/progress.cpp
|
||||||
utils/comboboxdelegate.cpp
|
utils/comboboxdelegate.cpp
|
||||||
|
utils/dropshadoweffect.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# Tell CMake to create the helloworld executable
|
# Tell CMake to create the helloworld executable
|
||||||
|
@ -277,7 +277,7 @@ void Models::Contact::addMessage(const Shared::Message& data)
|
|||||||
Presence* pr = new Presence({});
|
Presence* pr = new Presence({});
|
||||||
pr->setName(res);
|
pr->setName(res);
|
||||||
pr->setAvailability(Shared::invisible);
|
pr->setAvailability(Shared::invisible);
|
||||||
pr->setLastActivity(QDateTime::currentDateTime());
|
pr->setLastActivity(QDateTime::currentDateTimeUtc());
|
||||||
presences.insert(res, pr);
|
presences.insert(res, pr);
|
||||||
appendChild(pr);
|
appendChild(pr);
|
||||||
pr->addMessage(data);
|
pr->addMessage(data);
|
||||||
|
@ -59,6 +59,9 @@ Squawk::Squawk(QWidget *parent) :
|
|||||||
//m_ui->mainToolBar->addWidget(m_ui->comboBox);
|
//m_ui->mainToolBar->addWidget(m_ui->comboBox);
|
||||||
|
|
||||||
setWindowTitle(tr("Contact list"));
|
setWindowTitle(tr("Contact list"));
|
||||||
|
if (testAttribute(Qt::WA_TranslucentBackground)) {
|
||||||
|
m_ui->roster->viewport()->setAutoFillBackground(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Squawk::~Squawk() {
|
Squawk::~Squawk() {
|
||||||
|
701
ui/utils/dropshadoweffect.cpp
Normal file
701
ui/utils/dropshadoweffect.cpp
Normal file
@ -0,0 +1,701 @@
|
|||||||
|
/*
|
||||||
|
* Squawk messenger.
|
||||||
|
* Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
||||||
|
*
|
||||||
|
* This program is free 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
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dropshadoweffect.h"
|
||||||
|
#include "QtMath"
|
||||||
|
|
||||||
|
static const int tileSize = 32;
|
||||||
|
template <class T>
|
||||||
|
static
|
||||||
|
inline void qt_memrotate90_tiled(const T *src, int w, int h, int sstride, T *dest, int dstride)
|
||||||
|
{
|
||||||
|
sstride /= sizeof(T);
|
||||||
|
dstride /= sizeof(T);
|
||||||
|
const int pack = sizeof(quint32) / sizeof(T);
|
||||||
|
const int unaligned =
|
||||||
|
qMin(uint((quintptr(dest) & (sizeof(quint32)-1)) / sizeof(T)), uint(h));
|
||||||
|
const int restX = w % tileSize;
|
||||||
|
const int restY = (h - unaligned) % tileSize;
|
||||||
|
const int unoptimizedY = restY % pack;
|
||||||
|
const int numTilesX = w / tileSize + (restX > 0);
|
||||||
|
const int numTilesY = (h - unaligned) / tileSize + (restY >= pack);
|
||||||
|
for (int tx = 0; tx < numTilesX; ++tx) {
|
||||||
|
const int startx = w - tx * tileSize - 1;
|
||||||
|
const int stopx = qMax(startx - tileSize, 0);
|
||||||
|
if (unaligned) {
|
||||||
|
for (int x = startx; x >= stopx; --x) {
|
||||||
|
T *d = dest + (w - x - 1) * dstride;
|
||||||
|
for (int y = 0; y < unaligned; ++y) {
|
||||||
|
*d++ = src[y * sstride + x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int ty = 0; ty < numTilesY; ++ty) {
|
||||||
|
const int starty = ty * tileSize + unaligned;
|
||||||
|
const int stopy = qMin(starty + tileSize, h - unoptimizedY);
|
||||||
|
for (int x = startx; x >= stopx; --x) {
|
||||||
|
quint32 *d = reinterpret_cast<quint32*>(dest + (w - x - 1) * dstride + starty);
|
||||||
|
for (int y = starty; y < stopy; y += pack) {
|
||||||
|
quint32 c = src[y * sstride + x];
|
||||||
|
for (int i = 1; i < pack; ++i) {
|
||||||
|
const int shift = (sizeof(T) * 8 * i);
|
||||||
|
const T color = src[(y + i) * sstride + x];
|
||||||
|
c |= color << shift;
|
||||||
|
}
|
||||||
|
*d++ = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (unoptimizedY) {
|
||||||
|
const int starty = h - unoptimizedY;
|
||||||
|
for (int x = startx; x >= stopx; --x) {
|
||||||
|
T *d = dest + (w - x - 1) * dstride + starty;
|
||||||
|
for (int y = starty; y < h; ++y) {
|
||||||
|
*d++ = src[y * sstride + x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
static
|
||||||
|
inline void qt_memrotate90_tiled_unpacked(const T *src, int w, int h, int sstride, T *dest,
|
||||||
|
int dstride)
|
||||||
|
{
|
||||||
|
const int numTilesX = (w + tileSize - 1) / tileSize;
|
||||||
|
const int numTilesY = (h + tileSize - 1) / tileSize;
|
||||||
|
for (int tx = 0; tx < numTilesX; ++tx) {
|
||||||
|
const int startx = w - tx * tileSize - 1;
|
||||||
|
const int stopx = qMax(startx - tileSize, 0);
|
||||||
|
for (int ty = 0; ty < numTilesY; ++ty) {
|
||||||
|
const int starty = ty * tileSize;
|
||||||
|
const int stopy = qMin(starty + tileSize, h);
|
||||||
|
for (int x = startx; x >= stopx; --x) {
|
||||||
|
T *d = (T *)((char*)dest + (w - x - 1) * dstride) + starty;
|
||||||
|
const char *s = (const char*)(src + x) + starty * sstride;
|
||||||
|
for (int y = starty; y < stopy; ++y) {
|
||||||
|
*d++ = *(const T *)(s);
|
||||||
|
s += sstride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
static
|
||||||
|
inline void qt_memrotate270_tiled(const T *src, int w, int h, int sstride, T *dest, int dstride)
|
||||||
|
{
|
||||||
|
sstride /= sizeof(T);
|
||||||
|
dstride /= sizeof(T);
|
||||||
|
const int pack = sizeof(quint32) / sizeof(T);
|
||||||
|
const int unaligned =
|
||||||
|
qMin(uint((quintptr(dest) & (sizeof(quint32)-1)) / sizeof(T)), uint(h));
|
||||||
|
const int restX = w % tileSize;
|
||||||
|
const int restY = (h - unaligned) % tileSize;
|
||||||
|
const int unoptimizedY = restY % pack;
|
||||||
|
const int numTilesX = w / tileSize + (restX > 0);
|
||||||
|
const int numTilesY = (h - unaligned) / tileSize + (restY >= pack);
|
||||||
|
for (int tx = 0; tx < numTilesX; ++tx) {
|
||||||
|
const int startx = tx * tileSize;
|
||||||
|
const int stopx = qMin(startx + tileSize, w);
|
||||||
|
if (unaligned) {
|
||||||
|
for (int x = startx; x < stopx; ++x) {
|
||||||
|
T *d = dest + x * dstride;
|
||||||
|
for (int y = h - 1; y >= h - unaligned; --y) {
|
||||||
|
*d++ = src[y * sstride + x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int ty = 0; ty < numTilesY; ++ty) {
|
||||||
|
const int starty = h - 1 - unaligned - ty * tileSize;
|
||||||
|
const int stopy = qMax(starty - tileSize, unoptimizedY);
|
||||||
|
for (int x = startx; x < stopx; ++x) {
|
||||||
|
quint32 *d = reinterpret_cast<quint32*>(dest + x * dstride
|
||||||
|
+ h - 1 - starty);
|
||||||
|
for (int y = starty; y >= stopy; y -= pack) {
|
||||||
|
quint32 c = src[y * sstride + x];
|
||||||
|
for (int i = 1; i < pack; ++i) {
|
||||||
|
const int shift = (sizeof(T) * 8 * i);
|
||||||
|
const T color = src[(y - i) * sstride + x];
|
||||||
|
c |= color << shift;
|
||||||
|
}
|
||||||
|
*d++ = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (unoptimizedY) {
|
||||||
|
const int starty = unoptimizedY - 1;
|
||||||
|
for (int x = startx; x < stopx; ++x) {
|
||||||
|
T *d = dest + x * dstride + h - 1 - starty;
|
||||||
|
for (int y = starty; y >= 0; --y) {
|
||||||
|
*d++ = src[y * sstride + x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
static
|
||||||
|
inline void qt_memrotate270_tiled_unpacked(const T *src, int w, int h, int sstride, T *dest,
|
||||||
|
int dstride)
|
||||||
|
{
|
||||||
|
const int numTilesX = (w + tileSize - 1) / tileSize;
|
||||||
|
const int numTilesY = (h + tileSize - 1) / tileSize;
|
||||||
|
for (int tx = 0; tx < numTilesX; ++tx) {
|
||||||
|
const int startx = tx * tileSize;
|
||||||
|
const int stopx = qMin(startx + tileSize, w);
|
||||||
|
for (int ty = 0; ty < numTilesY; ++ty) {
|
||||||
|
const int starty = h - 1 - ty * tileSize;
|
||||||
|
const int stopy = qMax(starty - tileSize, 0);
|
||||||
|
for (int x = startx; x < stopx; ++x) {
|
||||||
|
T *d = (T*)((char*)dest + x * dstride) + h - 1 - starty;
|
||||||
|
const char *s = (const char*)(src + x) + starty * sstride;
|
||||||
|
for (int y = starty; y >= stopy; --y) {
|
||||||
|
*d++ = *(const T*)s;
|
||||||
|
s -= sstride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
static
|
||||||
|
inline void qt_memrotate90_template(const T *src, int srcWidth, int srcHeight, int srcStride,
|
||||||
|
T *dest, int dstStride)
|
||||||
|
{
|
||||||
|
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||||
|
// packed algorithm assumes little endian and that sizeof(quint32)/sizeof(T) is an integer
|
||||||
|
if (sizeof(quint32) % sizeof(T) == 0)
|
||||||
|
qt_memrotate90_tiled<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
qt_memrotate90_tiled_unpacked<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
|
||||||
|
}
|
||||||
|
template <>
|
||||||
|
inline void qt_memrotate90_template<quint32>(const quint32 *src, int w, int h, int sstride, quint32 *dest, int dstride)
|
||||||
|
{
|
||||||
|
// packed algorithm doesn't have any benefit for quint32
|
||||||
|
qt_memrotate90_tiled_unpacked(src, w, h, sstride, dest, dstride);
|
||||||
|
}
|
||||||
|
template <>
|
||||||
|
inline void qt_memrotate90_template<quint64>(const quint64 *src, int w, int h, int sstride, quint64 *dest, int dstride)
|
||||||
|
{
|
||||||
|
qt_memrotate90_tiled_unpacked(src, w, h, sstride, dest, dstride);
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
static
|
||||||
|
inline void qt_memrotate180_template(const T *src, int w, int h, int sstride, T *dest, int dstride)
|
||||||
|
{
|
||||||
|
const char *s = (const char*)(src) + (h - 1) * sstride;
|
||||||
|
for (int dy = 0; dy < h; ++dy) {
|
||||||
|
T *d = reinterpret_cast<T*>((char *)(dest) + dy * dstride);
|
||||||
|
src = reinterpret_cast<const T*>(s);
|
||||||
|
for (int dx = 0; dx < w; ++dx) {
|
||||||
|
d[dx] = src[w - 1 - dx];
|
||||||
|
}
|
||||||
|
s -= sstride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
static
|
||||||
|
inline void qt_memrotate270_template(const T *src, int srcWidth, int srcHeight, int srcStride,
|
||||||
|
T *dest, int dstStride)
|
||||||
|
{
|
||||||
|
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||||
|
// packed algorithm assumes little endian and that sizeof(quint32)/sizeof(T) is an integer
|
||||||
|
if (sizeof(quint32) % sizeof(T) == 0)
|
||||||
|
qt_memrotate270_tiled<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
qt_memrotate270_tiled_unpacked<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
|
||||||
|
}
|
||||||
|
template <>
|
||||||
|
inline void qt_memrotate270_template<quint32>(const quint32 *src, int w, int h, int sstride, quint32 *dest, int dstride)
|
||||||
|
{
|
||||||
|
// packed algorithm doesn't have any benefit for quint32
|
||||||
|
qt_memrotate270_tiled_unpacked(src, w, h, sstride, dest, dstride);
|
||||||
|
}
|
||||||
|
template <>
|
||||||
|
inline void qt_memrotate270_template<quint64>(const quint64 *src, int w, int h, int sstride, quint64 *dest, int dstride)
|
||||||
|
{
|
||||||
|
qt_memrotate270_tiled_unpacked(src, w, h, sstride, dest, dstride);
|
||||||
|
}
|
||||||
|
#define QT_IMPL_MEMROTATE(type) \
|
||||||
|
void qt_memrotate90(const type *src, int w, int h, int sstride, \
|
||||||
|
type *dest, int dstride) \
|
||||||
|
{ \
|
||||||
|
qt_memrotate90_template(src, w, h, sstride, dest, dstride); \
|
||||||
|
} \
|
||||||
|
void qt_memrotate180(const type *src, int w, int h, int sstride, \
|
||||||
|
type *dest, int dstride) \
|
||||||
|
{ \
|
||||||
|
qt_memrotate180_template(src, w, h, sstride, dest, dstride); \
|
||||||
|
} \
|
||||||
|
void qt_memrotate270(const type *src, int w, int h, int sstride, \
|
||||||
|
type *dest, int dstride) \
|
||||||
|
{ \
|
||||||
|
qt_memrotate270_template(src, w, h, sstride, dest, dstride); \
|
||||||
|
}
|
||||||
|
#define QT_IMPL_SIMPLE_MEMROTATE(type) \
|
||||||
|
void qt_memrotate90(const type *src, int w, int h, int sstride, \
|
||||||
|
type *dest, int dstride) \
|
||||||
|
{ \
|
||||||
|
qt_memrotate90_tiled_unpacked(src, w, h, sstride, dest, dstride); \
|
||||||
|
} \
|
||||||
|
void qt_memrotate180(const type *src, int w, int h, int sstride, \
|
||||||
|
type *dest, int dstride) \
|
||||||
|
{ \
|
||||||
|
qt_memrotate180_template(src, w, h, sstride, dest, dstride); \
|
||||||
|
} \
|
||||||
|
void qt_memrotate270(const type *src, int w, int h, int sstride, \
|
||||||
|
type *dest, int dstride) \
|
||||||
|
{ \
|
||||||
|
qt_memrotate270_tiled_unpacked(src, w, h, sstride, dest, dstride); \
|
||||||
|
}
|
||||||
|
QT_IMPL_MEMROTATE(quint64)
|
||||||
|
QT_IMPL_MEMROTATE(quint32)
|
||||||
|
QT_IMPL_MEMROTATE(quint16)
|
||||||
|
QT_IMPL_MEMROTATE(quint8)
|
||||||
|
void qt_memrotate90_8(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
|
||||||
|
{
|
||||||
|
qt_memrotate90(srcPixels, w, h, sbpl, destPixels, dbpl);
|
||||||
|
}
|
||||||
|
void qt_memrotate180_8(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
|
||||||
|
{
|
||||||
|
qt_memrotate180(srcPixels, w, h, sbpl, destPixels, dbpl);
|
||||||
|
}
|
||||||
|
void qt_memrotate270_8(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
|
||||||
|
{
|
||||||
|
qt_memrotate270(srcPixels, w, h, sbpl, destPixels, dbpl);
|
||||||
|
}
|
||||||
|
void qt_memrotate90_16(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
|
||||||
|
{
|
||||||
|
qt_memrotate90((const ushort *)srcPixels, w, h, sbpl, (ushort *)destPixels, dbpl);
|
||||||
|
}
|
||||||
|
void qt_memrotate180_16(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
|
||||||
|
{
|
||||||
|
qt_memrotate180((const ushort *)srcPixels, w, h, sbpl, (ushort *)destPixels, dbpl);
|
||||||
|
}
|
||||||
|
void qt_memrotate270_16(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
|
||||||
|
{
|
||||||
|
qt_memrotate270((const ushort *)srcPixels, w, h, sbpl, (ushort *)destPixels, dbpl);
|
||||||
|
}
|
||||||
|
void qt_memrotate90_32(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
|
||||||
|
{
|
||||||
|
qt_memrotate90((const uint *)srcPixels, w, h, sbpl, (uint *)destPixels, dbpl);
|
||||||
|
}
|
||||||
|
void qt_memrotate180_32(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
|
||||||
|
{
|
||||||
|
qt_memrotate180((const uint *)srcPixels, w, h, sbpl, (uint *)destPixels, dbpl);
|
||||||
|
}
|
||||||
|
void qt_memrotate270_32(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
|
||||||
|
{
|
||||||
|
qt_memrotate270((const uint *)srcPixels, w, h, sbpl, (uint *)destPixels, dbpl);
|
||||||
|
}
|
||||||
|
void qt_memrotate90_64(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
|
||||||
|
{
|
||||||
|
qt_memrotate90((const quint64 *)srcPixels, w, h, sbpl, (quint64 *)destPixels, dbpl);
|
||||||
|
}
|
||||||
|
void qt_memrotate180_64(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
|
||||||
|
{
|
||||||
|
qt_memrotate180((const quint64 *)srcPixels, w, h, sbpl, (quint64 *)destPixels, dbpl);
|
||||||
|
}
|
||||||
|
void qt_memrotate270_64(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
|
||||||
|
{
|
||||||
|
qt_memrotate270((const quint64 *)srcPixels, w, h, sbpl, (quint64 *)destPixels, dbpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define AVG(a,b) ( ((((a)^(b)) & 0xfefefefeUL) >> 1) + ((a)&(b)) )
|
||||||
|
#define AVG16(a,b) ( ((((a)^(b)) & 0xf7deUL) >> 1) + ((a)&(b)) )
|
||||||
|
const int alphaIndex = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3);
|
||||||
|
|
||||||
|
QImage qt_halfScaled(const QImage &source)
|
||||||
|
{
|
||||||
|
if (source.width() < 2 || source.height() < 2)
|
||||||
|
return QImage();
|
||||||
|
|
||||||
|
QImage srcImage = source;
|
||||||
|
|
||||||
|
if (source.format() == QImage::Format_Indexed8 || source.format() == QImage::Format_Grayscale8) {
|
||||||
|
// assumes grayscale
|
||||||
|
QImage dest(source.width() / 2, source.height() / 2, srcImage.format());
|
||||||
|
dest.setDevicePixelRatio(source.devicePixelRatioF());
|
||||||
|
|
||||||
|
const uchar *src = reinterpret_cast<const uchar*>(const_cast<const QImage &>(srcImage).bits());
|
||||||
|
qsizetype sx = srcImage.bytesPerLine();
|
||||||
|
qsizetype sx2 = sx << 1;
|
||||||
|
|
||||||
|
uchar *dst = reinterpret_cast<uchar*>(dest.bits());
|
||||||
|
qsizetype dx = dest.bytesPerLine();
|
||||||
|
int ww = dest.width();
|
||||||
|
int hh = dest.height();
|
||||||
|
|
||||||
|
for (int y = hh; y; --y, dst += dx, src += sx2) {
|
||||||
|
const uchar *p1 = src;
|
||||||
|
const uchar *p2 = src + sx;
|
||||||
|
uchar *q = dst;
|
||||||
|
for (int x = ww; x; --x, ++q, p1 += 2, p2 += 2)
|
||||||
|
*q = ((int(p1[0]) + int(p1[1]) + int(p2[0]) + int(p2[1])) + 2) >> 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
} else if (source.format() == QImage::Format_ARGB8565_Premultiplied) {
|
||||||
|
QImage dest(source.width() / 2, source.height() / 2, srcImage.format());
|
||||||
|
dest.setDevicePixelRatio(source.devicePixelRatioF());
|
||||||
|
|
||||||
|
const uchar *src = reinterpret_cast<const uchar*>(const_cast<const QImage &>(srcImage).bits());
|
||||||
|
qsizetype sx = srcImage.bytesPerLine();
|
||||||
|
qsizetype sx2 = sx << 1;
|
||||||
|
|
||||||
|
uchar *dst = reinterpret_cast<uchar*>(dest.bits());
|
||||||
|
qsizetype dx = dest.bytesPerLine();
|
||||||
|
int ww = dest.width();
|
||||||
|
int hh = dest.height();
|
||||||
|
|
||||||
|
for (int y = hh; y; --y, dst += dx, src += sx2) {
|
||||||
|
const uchar *p1 = src;
|
||||||
|
const uchar *p2 = src + sx;
|
||||||
|
uchar *q = dst;
|
||||||
|
for (int x = ww; x; --x, q += 3, p1 += 6, p2 += 6) {
|
||||||
|
// alpha
|
||||||
|
q[0] = AVG(AVG(p1[0], p1[3]), AVG(p2[0], p2[3]));
|
||||||
|
// rgb
|
||||||
|
const quint16 p16_1 = (p1[2] << 8) | p1[1];
|
||||||
|
const quint16 p16_2 = (p1[5] << 8) | p1[4];
|
||||||
|
const quint16 p16_3 = (p2[2] << 8) | p2[1];
|
||||||
|
const quint16 p16_4 = (p2[5] << 8) | p2[4];
|
||||||
|
const quint16 result = AVG16(AVG16(p16_1, p16_2), AVG16(p16_3, p16_4));
|
||||||
|
q[1] = result & 0xff;
|
||||||
|
q[2] = result >> 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
} else if (source.format() != QImage::Format_ARGB32_Premultiplied
|
||||||
|
&& source.format() != QImage::Format_RGB32)
|
||||||
|
{
|
||||||
|
srcImage = source.convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage dest(source.width() / 2, source.height() / 2, srcImage.format());
|
||||||
|
dest.setDevicePixelRatio(source.devicePixelRatioF());
|
||||||
|
|
||||||
|
const quint32 *src = reinterpret_cast<const quint32*>(const_cast<const QImage &>(srcImage).bits());
|
||||||
|
qsizetype sx = srcImage.bytesPerLine() >> 2;
|
||||||
|
qsizetype sx2 = sx << 1;
|
||||||
|
|
||||||
|
quint32 *dst = reinterpret_cast<quint32*>(dest.bits());
|
||||||
|
qsizetype dx = dest.bytesPerLine() >> 2;
|
||||||
|
int ww = dest.width();
|
||||||
|
int hh = dest.height();
|
||||||
|
|
||||||
|
for (int y = hh; y; --y, dst += dx, src += sx2) {
|
||||||
|
const quint32 *p1 = src;
|
||||||
|
const quint32 *p2 = src + sx;
|
||||||
|
quint32 *q = dst;
|
||||||
|
for (int x = ww; x; --x, q++, p1 += 2, p2 += 2)
|
||||||
|
*q = AVG(AVG(p1[0], p1[1]), AVG(p2[0], p2[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int shift>
|
||||||
|
inline int qt_static_shift(int value)
|
||||||
|
{
|
||||||
|
if (shift == 0)
|
||||||
|
return value;
|
||||||
|
else if (shift > 0)
|
||||||
|
return value << (uint(shift) & 0x1f);
|
||||||
|
else
|
||||||
|
return value >> (uint(-shift) & 0x1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int aprec, int zprec>
|
||||||
|
inline void qt_blurinner(uchar *bptr, int &zR, int &zG, int &zB, int &zA, int alpha)
|
||||||
|
{
|
||||||
|
QRgb *pixel = (QRgb *)bptr;
|
||||||
|
|
||||||
|
#define Z_MASK (0xff << zprec)
|
||||||
|
const int A_zprec = qt_static_shift<zprec - 24>(*pixel) & Z_MASK;
|
||||||
|
const int R_zprec = qt_static_shift<zprec - 16>(*pixel) & Z_MASK;
|
||||||
|
const int G_zprec = qt_static_shift<zprec - 8>(*pixel) & Z_MASK;
|
||||||
|
const int B_zprec = qt_static_shift<zprec>(*pixel) & Z_MASK;
|
||||||
|
#undef Z_MASK
|
||||||
|
|
||||||
|
const int zR_zprec = zR >> aprec;
|
||||||
|
const int zG_zprec = zG >> aprec;
|
||||||
|
const int zB_zprec = zB >> aprec;
|
||||||
|
const int zA_zprec = zA >> aprec;
|
||||||
|
|
||||||
|
zR += alpha * (R_zprec - zR_zprec);
|
||||||
|
zG += alpha * (G_zprec - zG_zprec);
|
||||||
|
zB += alpha * (B_zprec - zB_zprec);
|
||||||
|
zA += alpha * (A_zprec - zA_zprec);
|
||||||
|
|
||||||
|
#define ZA_MASK (0xff << (zprec + aprec))
|
||||||
|
*pixel =
|
||||||
|
qt_static_shift<24 - zprec - aprec>(zA & ZA_MASK)
|
||||||
|
| qt_static_shift<16 - zprec - aprec>(zR & ZA_MASK)
|
||||||
|
| qt_static_shift<8 - zprec - aprec>(zG & ZA_MASK)
|
||||||
|
| qt_static_shift<-zprec - aprec>(zB & ZA_MASK);
|
||||||
|
#undef ZA_MASK
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int aprec, int zprec>
|
||||||
|
inline void qt_blurinner_alphaOnly(uchar *bptr, int &z, int alpha)
|
||||||
|
{
|
||||||
|
const int A_zprec = int(*(bptr)) << zprec;
|
||||||
|
const int z_zprec = z >> aprec;
|
||||||
|
z += alpha * (A_zprec - z_zprec);
|
||||||
|
*(bptr) = z >> (zprec + aprec);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int aprec, int zprec, bool alphaOnly>
|
||||||
|
inline void qt_blurrow(QImage & im, int line, int alpha)
|
||||||
|
{
|
||||||
|
uchar *bptr = im.scanLine(line);
|
||||||
|
|
||||||
|
int zR = 0, zG = 0, zB = 0, zA = 0;
|
||||||
|
|
||||||
|
if (alphaOnly && im.format() != QImage::Format_Indexed8)
|
||||||
|
bptr += alphaIndex;
|
||||||
|
|
||||||
|
const int stride = im.depth() >> 3;
|
||||||
|
const int im_width = im.width();
|
||||||
|
for (int index = 0; index < im_width; ++index) {
|
||||||
|
if (alphaOnly)
|
||||||
|
qt_blurinner_alphaOnly<aprec, zprec>(bptr, zA, alpha);
|
||||||
|
else
|
||||||
|
qt_blurinner<aprec, zprec>(bptr, zR, zG, zB, zA, alpha);
|
||||||
|
bptr += stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
bptr -= stride;
|
||||||
|
|
||||||
|
for (int index = im_width - 2; index >= 0; --index) {
|
||||||
|
bptr -= stride;
|
||||||
|
if (alphaOnly)
|
||||||
|
qt_blurinner_alphaOnly<aprec, zprec>(bptr, zA, alpha);
|
||||||
|
else
|
||||||
|
qt_blurinner<aprec, zprec>(bptr, zR, zG, zB, zA, alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int aprec, int zprec, bool alphaOnly>
|
||||||
|
void expblur(QImage &img, qreal radius, bool improvedQuality = false, int transposed = 0)
|
||||||
|
{
|
||||||
|
// halve the radius if we're using two passes
|
||||||
|
if (improvedQuality)
|
||||||
|
radius *= qreal(0.5);
|
||||||
|
|
||||||
|
Q_ASSERT(img.format() == QImage::Format_ARGB32_Premultiplied
|
||||||
|
|| img.format() == QImage::Format_RGB32
|
||||||
|
|| img.format() == QImage::Format_Indexed8
|
||||||
|
|| img.format() == QImage::Format_Grayscale8);
|
||||||
|
|
||||||
|
// choose the alpha such that pixels at radius distance from a fully
|
||||||
|
// saturated pixel will have an alpha component of no greater than
|
||||||
|
// the cutOffIntensity
|
||||||
|
const qreal cutOffIntensity = 2;
|
||||||
|
int alpha = radius <= qreal(1e-5)
|
||||||
|
? ((1 << aprec)-1)
|
||||||
|
: qRound((1<<aprec)*(1 - qPow(cutOffIntensity * (1 / qreal(255)), 1 / radius)));
|
||||||
|
|
||||||
|
int img_height = img.height();
|
||||||
|
for (int row = 0; row < img_height; ++row) {
|
||||||
|
for (int i = 0; i <= int(improvedQuality); ++i)
|
||||||
|
qt_blurrow<aprec, zprec, alphaOnly>(img, row, alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage temp(img.height(), img.width(), img.format());
|
||||||
|
temp.setDevicePixelRatio(img.devicePixelRatioF());
|
||||||
|
if (transposed >= 0) {
|
||||||
|
if (img.depth() == 8) {
|
||||||
|
qt_memrotate270(reinterpret_cast<const quint8*>(img.bits()),
|
||||||
|
img.width(), img.height(), img.bytesPerLine(),
|
||||||
|
reinterpret_cast<quint8*>(temp.bits()),
|
||||||
|
temp.bytesPerLine());
|
||||||
|
} else {
|
||||||
|
qt_memrotate270(reinterpret_cast<const quint32*>(img.bits()),
|
||||||
|
img.width(), img.height(), img.bytesPerLine(),
|
||||||
|
reinterpret_cast<quint32*>(temp.bits()),
|
||||||
|
temp.bytesPerLine());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (img.depth() == 8) {
|
||||||
|
qt_memrotate90(reinterpret_cast<const quint8*>(img.bits()),
|
||||||
|
img.width(), img.height(), img.bytesPerLine(),
|
||||||
|
reinterpret_cast<quint8*>(temp.bits()),
|
||||||
|
temp.bytesPerLine());
|
||||||
|
} else {
|
||||||
|
qt_memrotate90(reinterpret_cast<const quint32*>(img.bits()),
|
||||||
|
img.width(), img.height(), img.bytesPerLine(),
|
||||||
|
reinterpret_cast<quint32*>(temp.bits()),
|
||||||
|
temp.bytesPerLine());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img_height = temp.height();
|
||||||
|
for (int row = 0; row < img_height; ++row) {
|
||||||
|
for (int i = 0; i <= int(improvedQuality); ++i)
|
||||||
|
qt_blurrow<aprec, zprec, alphaOnly>(temp, row, alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transposed == 0) {
|
||||||
|
if (img.depth() == 8) {
|
||||||
|
qt_memrotate90(reinterpret_cast<const quint8*>(temp.bits()),
|
||||||
|
temp.width(), temp.height(), temp.bytesPerLine(),
|
||||||
|
reinterpret_cast<quint8*>(img.bits()),
|
||||||
|
img.bytesPerLine());
|
||||||
|
} else {
|
||||||
|
qt_memrotate90(reinterpret_cast<const quint32*>(temp.bits()),
|
||||||
|
temp.width(), temp.height(), temp.bytesPerLine(),
|
||||||
|
reinterpret_cast<quint32*>(img.bits()),
|
||||||
|
img.bytesPerLine());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
img = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PixmapFilter::PixmapFilter(QObject* parent):QObject(parent) {}
|
||||||
|
PixmapFilter::~PixmapFilter(){}
|
||||||
|
QRectF PixmapFilter::boundingRectFor(const QRectF &rect) const {return rect;}
|
||||||
|
|
||||||
|
PixmapDropShadowFilter::PixmapDropShadowFilter(QObject *parent):
|
||||||
|
PixmapFilter(parent),
|
||||||
|
mColor(63, 63, 63, 180),
|
||||||
|
mRadius(1),
|
||||||
|
mThickness(2),
|
||||||
|
top(true),
|
||||||
|
right(true),
|
||||||
|
bottom(true),
|
||||||
|
left(true){}
|
||||||
|
|
||||||
|
PixmapDropShadowFilter::~PixmapDropShadowFilter() {}
|
||||||
|
qreal PixmapDropShadowFilter::blurRadius() const {return mRadius;}
|
||||||
|
void PixmapDropShadowFilter::setBlurRadius(qreal radius) {mRadius = radius;}
|
||||||
|
QColor PixmapDropShadowFilter::color() const {return mColor;}
|
||||||
|
void PixmapDropShadowFilter::setColor(const QColor &color) {mColor = color;}
|
||||||
|
qreal PixmapDropShadowFilter::thickness() const {return mThickness;}
|
||||||
|
void PixmapDropShadowFilter::setThickness(qreal thickness) {mThickness = thickness;}
|
||||||
|
void PixmapDropShadowFilter::setFrame(bool ptop, bool pright, bool pbottom, bool pleft)
|
||||||
|
{
|
||||||
|
top = ptop;
|
||||||
|
right = pright;
|
||||||
|
bottom = pbottom;
|
||||||
|
left = pleft;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DropShadowEffect::setThickness(qreal thickness)
|
||||||
|
{
|
||||||
|
if (filter.thickness() == thickness)
|
||||||
|
return;
|
||||||
|
|
||||||
|
filter.setThickness(thickness);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PixmapDropShadowFilter::draw(QPainter *p, const QPointF &pos, const QPixmap &px, const QRectF &src) const
|
||||||
|
{
|
||||||
|
if (px.isNull())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QImage tmp({px.width(), px.height() + int(mThickness)}, QImage::Format_ARGB32_Premultiplied);
|
||||||
|
tmp.setDevicePixelRatio(px.devicePixelRatioF());
|
||||||
|
tmp.fill(0);
|
||||||
|
QPainter tmpPainter(&tmp);
|
||||||
|
tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
|
if (top) {
|
||||||
|
QRectF shadow(0, 0, px.width(), mThickness);
|
||||||
|
tmpPainter.fillRect(shadow, mColor);
|
||||||
|
}
|
||||||
|
if (right) {
|
||||||
|
QRectF shadow(px.width() - mThickness, 0, mThickness, px.height());
|
||||||
|
tmpPainter.fillRect(shadow, mColor);
|
||||||
|
}
|
||||||
|
if (bottom) {
|
||||||
|
QRectF shadow(0, px.height() - mThickness, px.width(), mThickness * 2); //i have no idea why, but it leaves some unpainted stripe without some spare space
|
||||||
|
tmpPainter.fillRect(shadow, mColor);
|
||||||
|
}
|
||||||
|
if (left) {
|
||||||
|
QRectF shadow(0, 0, mThickness, px.height());
|
||||||
|
tmpPainter.fillRect(shadow, mColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
expblur<12, 10, false>(tmp, mRadius, false, 0);
|
||||||
|
tmpPainter.end();
|
||||||
|
|
||||||
|
// Draw the actual pixmap...
|
||||||
|
p->drawPixmap(pos, px, src);
|
||||||
|
|
||||||
|
// draw the blurred drop shadow...
|
||||||
|
p->drawImage(pos, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal DropShadowEffect::blurRadius() const {return filter.blurRadius();}
|
||||||
|
void DropShadowEffect::setBlurRadius(qreal blurRadius)
|
||||||
|
{
|
||||||
|
if (qFuzzyCompare(filter.blurRadius(), blurRadius))
|
||||||
|
return;
|
||||||
|
|
||||||
|
filter.setBlurRadius(blurRadius);
|
||||||
|
updateBoundingRect();
|
||||||
|
emit blurRadiusChanged(blurRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DropShadowEffect::setFrame(bool top, bool right, bool bottom, bool left)
|
||||||
|
{
|
||||||
|
filter.setFrame(top, right, bottom, left);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QColor DropShadowEffect::color() const {return filter.color();}
|
||||||
|
void DropShadowEffect::setColor(const QColor &color)
|
||||||
|
{
|
||||||
|
if (filter.color() == color)
|
||||||
|
return;
|
||||||
|
|
||||||
|
filter.setColor(color);
|
||||||
|
update();
|
||||||
|
emit colorChanged(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DropShadowEffect::draw(QPainter* painter)
|
||||||
|
{
|
||||||
|
if (filter.blurRadius() <= 0 && filter.thickness() == 0) {
|
||||||
|
drawSource(painter);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PixmapPadMode mode = PadToEffectiveBoundingRect;
|
||||||
|
|
||||||
|
// Draw pixmap in device coordinates to avoid pixmap scaling.
|
||||||
|
QPoint offset;
|
||||||
|
const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, mode);
|
||||||
|
if (pixmap.isNull())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QTransform restoreTransform = painter->worldTransform();
|
||||||
|
painter->setWorldTransform(QTransform());
|
||||||
|
filter.draw(painter, offset, pixmap);
|
||||||
|
painter->setWorldTransform(restoreTransform);
|
||||||
|
}
|
93
ui/utils/dropshadoweffect.h
Normal file
93
ui/utils/dropshadoweffect.h
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Squawk messenger.
|
||||||
|
* Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
||||||
|
*
|
||||||
|
* This program is free 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
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DROPSHADOWEFFECT_H
|
||||||
|
#define DROPSHADOWEFFECT_H
|
||||||
|
|
||||||
|
#include <QGraphicsEffect>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QPointF>
|
||||||
|
#include <QColor>
|
||||||
|
|
||||||
|
class PixmapFilter : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
PixmapFilter(QObject *parent = nullptr);
|
||||||
|
virtual ~PixmapFilter() = 0;
|
||||||
|
|
||||||
|
virtual QRectF boundingRectFor(const QRectF &rect) const;
|
||||||
|
virtual void draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF &srcRect = QRectF()) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PixmapDropShadowFilter : public PixmapFilter
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
PixmapDropShadowFilter(QObject *parent = nullptr);
|
||||||
|
~PixmapDropShadowFilter();
|
||||||
|
|
||||||
|
void draw(QPainter *p, const QPointF &pos, const QPixmap &px, const QRectF &src = QRectF()) const override;
|
||||||
|
|
||||||
|
qreal blurRadius() const;
|
||||||
|
void setBlurRadius(qreal radius);
|
||||||
|
|
||||||
|
QColor color() const;
|
||||||
|
void setColor(const QColor &color);
|
||||||
|
|
||||||
|
qreal thickness() const;
|
||||||
|
void setThickness(qreal thickness);
|
||||||
|
void setFrame(bool top, bool right, bool bottom, bool left);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QColor mColor;
|
||||||
|
qreal mRadius;
|
||||||
|
qreal mThickness;
|
||||||
|
bool top;
|
||||||
|
bool right;
|
||||||
|
bool bottom;
|
||||||
|
bool left;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DropShadowEffect : public QGraphicsEffect
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
qreal blurRadius() const;
|
||||||
|
QColor color() const;
|
||||||
|
void setFrame(bool top, bool right, bool bottom, bool left);
|
||||||
|
void setThickness(qreal thickness);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void blurRadiusChanged(qreal blurRadius);
|
||||||
|
void colorChanged(const QColor &color);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setBlurRadius(qreal blurRadius);
|
||||||
|
void setColor(const QColor &color);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void draw(QPainter * painter) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
PixmapDropShadowFilter filter;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DROPSHADOWEFFECT_H
|
@ -40,7 +40,6 @@ MessageLine::MessageLine(bool p_room, QWidget* parent):
|
|||||||
{
|
{
|
||||||
setContentsMargins(0, 0, 0, 0);
|
setContentsMargins(0, 0, 0, 0);
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
setBackgroundRole(QPalette::Base);
|
|
||||||
layout->setSpacing(0);
|
layout->setSpacing(0);
|
||||||
layout->addStretch();
|
layout->addStretch();
|
||||||
}
|
}
|
||||||
|
@ -18,13 +18,15 @@
|
|||||||
|
|
||||||
#include "conversation.h"
|
#include "conversation.h"
|
||||||
#include "ui_conversation.h"
|
#include "ui_conversation.h"
|
||||||
|
#include "ui/utils/dropshadoweffect.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QGraphicsDropShadowEffect>
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMimeDatabase>
|
#include <QMimeDatabase>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <QAbstractTextDocumentLayout>
|
||||||
|
|
||||||
Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, const QString pRes, QWidget* parent):
|
Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, const QString pRes, QWidget* parent):
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
@ -36,7 +38,6 @@ Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, c
|
|||||||
m_ui(new Ui::Conversation()),
|
m_ui(new Ui::Conversation()),
|
||||||
ker(),
|
ker(),
|
||||||
scrollResizeCatcher(),
|
scrollResizeCatcher(),
|
||||||
attachResizeCatcher(),
|
|
||||||
vis(),
|
vis(),
|
||||||
thread(),
|
thread(),
|
||||||
statusIcon(0),
|
statusIcon(0),
|
||||||
@ -54,15 +55,11 @@ Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, c
|
|||||||
filesLayout = new FlowLayout(m_ui->filesPanel, 0);
|
filesLayout = new FlowLayout(m_ui->filesPanel, 0);
|
||||||
m_ui->filesPanel->setLayout(filesLayout);
|
m_ui->filesPanel->setLayout(filesLayout);
|
||||||
|
|
||||||
m_ui->splitter->setSizes({300, 0});
|
|
||||||
m_ui->splitter->setStretchFactor(1, 0);
|
|
||||||
|
|
||||||
statusIcon = m_ui->statusIcon;
|
statusIcon = m_ui->statusIcon;
|
||||||
statusLabel = m_ui->statusLabel;
|
statusLabel = m_ui->statusLabel;
|
||||||
|
|
||||||
connect(&ker, &KeyEnterReceiver::enterPressed, this, &Conversation::onEnterPressed);
|
connect(&ker, &KeyEnterReceiver::enterPressed, this, &Conversation::onEnterPressed);
|
||||||
connect(&scrollResizeCatcher, &Resizer::resized, this, &Conversation::onScrollResize);
|
connect(&scrollResizeCatcher, &Resizer::resized, this, &Conversation::onScrollResize);
|
||||||
connect(&attachResizeCatcher, &Resizer::resized, this, &Conversation::onAttachResize);
|
|
||||||
connect(&vis, &VisibilityCatcher::shown, this, &Conversation::onScrollResize);
|
connect(&vis, &VisibilityCatcher::shown, this, &Conversation::onScrollResize);
|
||||||
connect(&vis, &VisibilityCatcher::hidden, this, &Conversation::onScrollResize);
|
connect(&vis, &VisibilityCatcher::hidden, this, &Conversation::onScrollResize);
|
||||||
connect(m_ui->sendButton, &QPushButton::clicked, this, &Conversation::onEnterPressed);
|
connect(m_ui->sendButton, &QPushButton::clicked, this, &Conversation::onEnterPressed);
|
||||||
@ -72,6 +69,8 @@ Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, c
|
|||||||
connect(line, &MessageLine::requestLocalFile, this, &Conversation::requestLocalFile);
|
connect(line, &MessageLine::requestLocalFile, this, &Conversation::requestLocalFile);
|
||||||
connect(m_ui->attachButton, &QPushButton::clicked, this, &Conversation::onAttach);
|
connect(m_ui->attachButton, &QPushButton::clicked, this, &Conversation::onAttach);
|
||||||
connect(m_ui->clearButton, &QPushButton::clicked, this, &Conversation::onClearButton);
|
connect(m_ui->clearButton, &QPushButton::clicked, this, &Conversation::onClearButton);
|
||||||
|
connect(m_ui->messageEditor->document()->documentLayout(), &QAbstractTextDocumentLayout::documentSizeChanged,
|
||||||
|
this, &Conversation::onTextEditDocSizeChanged);
|
||||||
|
|
||||||
m_ui->messageEditor->installEventFilter(&ker);
|
m_ui->messageEditor->installEventFilter(&ker);
|
||||||
|
|
||||||
@ -79,14 +78,13 @@ Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, c
|
|||||||
m_ui->scrollArea->setWidget(line);
|
m_ui->scrollArea->setWidget(line);
|
||||||
vs->installEventFilter(&vis);
|
vs->installEventFilter(&vis);
|
||||||
|
|
||||||
if (!tsb) {
|
if (testAttribute(Qt::WA_TranslucentBackground)) {
|
||||||
vs->setBackgroundRole(QPalette::Base);
|
m_ui->scrollArea->setAutoFillBackground(false);
|
||||||
vs->setAutoFillBackground(true);
|
m_ui->scrollArea->viewport()->setAutoFillBackground(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(vs, &QScrollBar::valueChanged, this, &Conversation::onSliderValueChanged);
|
connect(vs, &QScrollBar::valueChanged, this, &Conversation::onSliderValueChanged);
|
||||||
m_ui->scrollArea->installEventFilter(&scrollResizeCatcher);
|
m_ui->scrollArea->installEventFilter(&scrollResizeCatcher);
|
||||||
m_ui->filesPanel->installEventFilter(&attachResizeCatcher);
|
|
||||||
|
|
||||||
line->setMyAvatarPath(acc->getAvatarPath());
|
line->setMyAvatarPath(acc->getAvatarPath());
|
||||||
line->setMyName(acc->getName());
|
line->setMyName(acc->getName());
|
||||||
@ -100,26 +98,12 @@ Conversation::~Conversation()
|
|||||||
|
|
||||||
void Conversation::applyVisualEffects()
|
void Conversation::applyVisualEffects()
|
||||||
{
|
{
|
||||||
QGraphicsDropShadowEffect *e1 = new QGraphicsDropShadowEffect;
|
DropShadowEffect *e1 = new DropShadowEffect;
|
||||||
e1->setBlurRadius(10);
|
e1->setBlurRadius(10);
|
||||||
e1->setXOffset(0);
|
|
||||||
e1->setYOffset(-2);
|
|
||||||
e1->setColor(Qt::black);
|
e1->setColor(Qt::black);
|
||||||
m_ui->bl->setGraphicsEffect(e1);
|
e1->setThickness(1);
|
||||||
|
e1->setFrame(true, false, true, false);
|
||||||
QGraphicsDropShadowEffect *e2 = new QGraphicsDropShadowEffect;
|
m_ui->scrollArea->setGraphicsEffect(e1);
|
||||||
e2->setBlurRadius(7);
|
|
||||||
e2->setXOffset(0);
|
|
||||||
e2->setYOffset(2);
|
|
||||||
e2->setColor(Qt::black);
|
|
||||||
m_ui->ul->setGraphicsEffect(e2);
|
|
||||||
|
|
||||||
QGraphicsDropShadowEffect *e3 = new QGraphicsDropShadowEffect;
|
|
||||||
e3->setBlurRadius(10);
|
|
||||||
e3->setXOffset(0);
|
|
||||||
e3->setYOffset(2);
|
|
||||||
e3->setColor(Qt::black);
|
|
||||||
m_ui->ut->setGraphicsEffect(e3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Conversation::setName(const QString& name)
|
void Conversation::setName(const QString& name)
|
||||||
@ -404,21 +388,9 @@ void Conversation::setAvatar(const QString& path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Conversation::onAttachResize(const QSize& oldSize, const QSize& newSize)
|
void Conversation::onTextEditDocSizeChanged(const QSizeF& size)
|
||||||
{
|
{
|
||||||
int oh = oldSize.height();
|
m_ui->messageEditor->setMaximumHeight(int(size.height()));
|
||||||
int nh = newSize.height();
|
|
||||||
|
|
||||||
int d = oh - nh;
|
|
||||||
|
|
||||||
if (d != 0) {
|
|
||||||
QList<int> cs = m_ui->splitter->sizes();
|
|
||||||
cs.first() += d;
|
|
||||||
cs.last() -=d;
|
|
||||||
|
|
||||||
m_ui->splitter->setSizes(cs);
|
|
||||||
m_ui->scrollArea->verticalScrollBar()->setValue(m_ui->scrollArea->verticalScrollBar()->maximum());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -439,3 +411,4 @@ VisibilityCatcher::VisibilityCatcher(QWidget* parent):
|
|||||||
QObject(parent)
|
QObject(parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,9 +107,9 @@ protected slots:
|
|||||||
void onAttach();
|
void onAttach();
|
||||||
void onFileSelected();
|
void onFileSelected();
|
||||||
void onScrollResize();
|
void onScrollResize();
|
||||||
void onAttachResize(const QSize& oldSize, const QSize& newSize);
|
|
||||||
void onBadgeClose();
|
void onBadgeClose();
|
||||||
void onClearButton();
|
void onClearButton();
|
||||||
|
void onTextEditDocSizeChanged(const QSizeF& size);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const bool isMuc;
|
const bool isMuc;
|
||||||
@ -127,7 +127,6 @@ protected:
|
|||||||
QScopedPointer<Ui::Conversation> m_ui;
|
QScopedPointer<Ui::Conversation> m_ui;
|
||||||
KeyEnterReceiver ker;
|
KeyEnterReceiver ker;
|
||||||
Resizer scrollResizeCatcher;
|
Resizer scrollResizeCatcher;
|
||||||
Resizer attachResizeCatcher;
|
|
||||||
VisibilityCatcher vis;
|
VisibilityCatcher vis;
|
||||||
QString thread;
|
QString thread;
|
||||||
QLabel* statusIcon;
|
QLabel* statusIcon;
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>572</width>
|
<width>520</width>
|
||||||
<height>484</height>
|
<height>658</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QVBoxLayout" name="horizontalLayout">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
@ -27,321 +27,192 @@
|
|||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QSplitter" name="splitter">
|
<widget class="QWidget" name="widget" native="true">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShape">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<enum>QFrame::NoFrame</enum>
|
<property name="spacing">
|
||||||
</property>
|
<number>0</number>
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Plain</enum>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="childrenCollapsible">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="widget" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<property name="leftMargin">
|
||||||
<property name="spacing">
|
<number>0</number>
|
||||||
<number>0</number>
|
</property>
|
||||||
</property>
|
<property name="topMargin">
|
||||||
<property name="leftMargin">
|
<number>0</number>
|
||||||
<number>0</number>
|
</property>
|
||||||
</property>
|
<property name="rightMargin">
|
||||||
<property name="topMargin">
|
<number>0</number>
|
||||||
<number>0</number>
|
</property>
|
||||||
</property>
|
<property name="bottomMargin">
|
||||||
<property name="rightMargin">
|
<number>0</number>
|
||||||
<number>0</number>
|
</property>
|
||||||
</property>
|
<item>
|
||||||
<property name="bottomMargin">
|
<widget class="QWidget" name="widget_3" native="true">
|
||||||
<number>0</number>
|
<property name="maximumSize">
|
||||||
</property>
|
<size>
|
||||||
<item>
|
<width>16777215</width>
|
||||||
<widget class="QWidget" name="widget_3" native="true">
|
<height>100</height>
|
||||||
<property name="maximumSize">
|
</size>
|
||||||
<size>
|
</property>
|
||||||
<width>16777215</width>
|
<property name="autoFillBackground">
|
||||||
<height>100</height>
|
<bool>false</bool>
|
||||||
</size>
|
</property>
|
||||||
</property>
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
<property name="autoFillBackground">
|
<property name="leftMargin">
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="statusIcon">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>16777215</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="scaledContents">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="nameLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="statusLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="historyStatus">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="avatar">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>60</width>
|
|
||||||
<height>60</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="baseSize">
|
|
||||||
<size>
|
|
||||||
<width>50</width>
|
|
||||||
<height>50</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="scaledContents">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="margin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="ul" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>2</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="baseSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>2</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="autoFillBackground">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QScrollArea" name="scrollArea">
|
|
||||||
<property name="autoFillBackground">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::NoFrame</enum>
|
|
||||||
</property>
|
|
||||||
<property name="lineWidth">
|
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="midLineWidth">
|
<property name="topMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="horizontalScrollBarPolicy">
|
<property name="rightMargin">
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeAdjustPolicy">
|
<property name="bottomMargin">
|
||||||
<enum>QAbstractScrollArea::AdjustIgnored</enum>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="widgetResizable">
|
<item>
|
||||||
<bool>true</bool>
|
<widget class="QLabel" name="statusIcon">
|
||||||
</property>
|
<property name="minimumSize">
|
||||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
<size>
|
||||||
<property name="geometry">
|
<width>0</width>
|
||||||
<rect>
|
<height>0</height>
|
||||||
<x>0</x>
|
</size>
|
||||||
<y>0</y>
|
</property>
|
||||||
<width>572</width>
|
<property name="maximumSize">
|
||||||
<height>118</height>
|
<size>
|
||||||
</rect>
|
<width>16777215</width>
|
||||||
</property>
|
<height>16777215</height>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="topMargin">
|
<item>
|
||||||
<number>0</number>
|
<widget class="QLabel" name="nameLabel">
|
||||||
</property>
|
<property name="text">
|
||||||
<property name="rightMargin">
|
<string/>
|
||||||
<number>0</number>
|
</property>
|
||||||
</property>
|
</widget>
|
||||||
<property name="bottomMargin">
|
</item>
|
||||||
<number>0</number>
|
<item>
|
||||||
</property>
|
<widget class="QLabel" name="statusLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</item>
|
||||||
</widget>
|
<item>
|
||||||
</item>
|
<spacer name="horizontalSpacer_2">
|
||||||
<item>
|
<property name="orientation">
|
||||||
<widget class="QWidget" name="bl" native="true">
|
<enum>Qt::Horizontal</enum>
|
||||||
<property name="sizePolicy">
|
</property>
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
<property name="sizeHint" stdset="0">
|
||||||
<horstretch>0</horstretch>
|
<size>
|
||||||
<verstretch>0</verstretch>
|
<width>40</width>
|
||||||
</sizepolicy>
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="historyStatus">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="avatar">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>60</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="baseSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>50</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="margin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QScrollArea" name="scrollArea">
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="lineWidth">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="midLineWidth">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QAbstractScrollArea::AdjustIgnored</enum>
|
||||||
|
</property>
|
||||||
|
<property name="widgetResizable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>520</width>
|
||||||
|
<height>389</height>
|
||||||
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<size>
|
<property name="spacing">
|
||||||
<width>0</width>
|
<number>0</number>
|
||||||
<height>2</height>
|
</property>
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>16777215</width>
|
|
||||||
<height>2</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="baseSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>2</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="autoFillBackground">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
<zorder>scrollArea</zorder>
|
|
||||||
<zorder>bl</zorder>
|
|
||||||
<zorder>ul</zorder>
|
|
||||||
<zorder>widget_3</zorder>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="widget_2" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="autoFillBackground">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="panel" native="true">
|
|
||||||
<property name="autoFillBackground">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
@ -354,156 +225,213 @@
|
|||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="smilesButton">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset theme="smiley-shape">
|
|
||||||
<normaloff>.</normaloff>.</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="attachButton">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset theme="mail-attachment-symbolic">
|
|
||||||
<normaloff>.</normaloff>.</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="clearButton">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset theme="edit-clear-all">
|
|
||||||
<normaloff>.</normaloff>.</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="sendButton">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset theme="document-send">
|
|
||||||
<normaloff>.</normaloff>.</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</widget>
|
||||||
<item>
|
</item>
|
||||||
<widget class="QWidget" name="filesPanel" native="true">
|
</layout>
|
||||||
<property name="autoFillBackground">
|
<zorder>scrollArea</zorder>
|
||||||
<bool>true</bool>
|
<zorder>widget_3</zorder>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="widget_2" native="true">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetDefaultConstraint</enum>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="panel" native="true">
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="topMargin">
|
||||||
</item>
|
<number>0</number>
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="ut" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="rightMargin">
|
||||||
<size>
|
<number>0</number>
|
||||||
<width>0</width>
|
|
||||||
<height>2</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="maximumSize">
|
<property name="bottomMargin">
|
||||||
<size>
|
<number>0</number>
|
||||||
<width>16777215</width>
|
|
||||||
<height>2</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="baseSize">
|
<item>
|
||||||
<size>
|
<widget class="QPushButton" name="smilesButton">
|
||||||
<width>0</width>
|
<property name="text">
|
||||||
<height>2</height>
|
<string/>
|
||||||
</size>
|
</property>
|
||||||
</property>
|
<property name="icon">
|
||||||
<property name="autoFillBackground">
|
<iconset theme="smiley-shape">
|
||||||
<bool>true</bool>
|
<normaloff>.</normaloff>.</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="flat">
|
||||||
</item>
|
<bool>true</bool>
|
||||||
<item>
|
</property>
|
||||||
<widget class="QPlainTextEdit" name="messageEditor">
|
</widget>
|
||||||
<property name="sizePolicy">
|
</item>
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
<item>
|
||||||
<horstretch>0</horstretch>
|
<spacer name="horizontalSpacer">
|
||||||
<verstretch>0</verstretch>
|
<property name="orientation">
|
||||||
</sizepolicy>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>0</width>
|
<width>40</width>
|
||||||
<height>30</height>
|
<height>20</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="baseSize">
|
</spacer>
|
||||||
<size>
|
</item>
|
||||||
<width>0</width>
|
<item>
|
||||||
<height>30</height>
|
<widget class="QPushButton" name="attachButton">
|
||||||
</size>
|
<property name="text">
|
||||||
</property>
|
<string/>
|
||||||
<property name="frameShape">
|
</property>
|
||||||
<enum>QFrame::NoFrame</enum>
|
<property name="icon">
|
||||||
</property>
|
<iconset theme="mail-attachment-symbolic">
|
||||||
<property name="placeholderText">
|
<normaloff>.</normaloff>.</iconset>
|
||||||
<string>Type your message here...</string>
|
</property>
|
||||||
</property>
|
<property name="flat">
|
||||||
</widget>
|
<bool>true</bool>
|
||||||
</item>
|
</property>
|
||||||
</layout>
|
</widget>
|
||||||
<zorder>messageEditor</zorder>
|
</item>
|
||||||
<zorder>ut</zorder>
|
<item>
|
||||||
<zorder>filesPanel</zorder>
|
<widget class="QPushButton" name="clearButton">
|
||||||
<zorder>panel</zorder>
|
<property name="text">
|
||||||
</widget>
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="edit-clear-all">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="sendButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="document-send">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="filesPanel" native="true">
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTextEdit" name="messageEditor">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>30</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="baseSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>30</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QTextEdit {
|
||||||
|
background-color: transparent
|
||||||
|
}</string>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="verticalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QAbstractScrollArea::AdjustIgnored</enum>
|
||||||
|
</property>
|
||||||
|
<property name="html">
|
||||||
|
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
</style></head><body style=" font-family:'Liberation Sans'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="acceptRichText">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Type your message here...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
<zorder>messageEditor</zorder>
|
||||||
|
<zorder>filesPanel</zorder>
|
||||||
|
<zorder>panel</zorder>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
Loading…
Reference in New Issue
Block a user