encrypted messages now are displayed in the feed

This commit is contained in:
Blue 2023-11-06 20:57:08 -03:00
parent 637eb702a8
commit 0a530bfa93
Signed by: blue
GPG Key ID: 9B203B252A63EE38
34 changed files with 439 additions and 245 deletions

View File

@ -38,9 +38,9 @@ option(WITH_OMEMO "Build OMEMO support module" ON)
# Dependencies
## Qt
if (NOT DEFINED QT_VERSION_MAJOR)
find_package(QT NAMES Qt5 REQUIRED COMPONENTS Widgets DBus Gui Xml Network Core)
find_package(QT NAMES Qt6 Qt5 CONFIG REQUIRED COMPONENTS Widgets DBus Gui Xml Network Core)
else ()
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets DBus Gui Xml Network Core)
find_package(Qt${QT_VERSION_MAJOR} CONFIG REQUIRED COMPONENTS Widgets DBus Gui Xml Network Core)
endif()
find_package(Boost COMPONENTS)

View File

@ -117,9 +117,8 @@ bool Core::MessageHandler::handleChatMessage(const QXmppMessage& msg, bool outgo
qDebug() << "appending message" << sMsg.getId() << "to an out of roster contact";
}
if (sMsg.getOutgoing()) {
if (sMsg.getForwarded()) {
if (sMsg.getForwarded())
sMsg.setState(Shared::Message::State::sent);
}
} else {
sMsg.setState(Shared::Message::State::delivered);
}
@ -208,6 +207,12 @@ void Core::MessageHandler::initializeMessage(Shared::Message& target, const QXmp
target.setTo(source.to());
target.setBody(source.body());
target.setForwarded(forwarded);
#ifdef WITH_OMEMO
#if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 5, 0)
if (source.encryptionMethod() == QXmpp::EncryptionMethod::Omemo2)
target.setEncryption(Shared::EncryptionProtocol::omemo2);
#endif
#endif
if (guessing)
outgoing = target.getFromJid() == acc->getBareJid();

View File

@ -27,8 +27,7 @@
#include <Omemo/QXmppOmemoStorage.h>
#endif
int main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
qRegisterMetaType<Shared::Message>("Shared::Message");
qRegisterMetaType<Shared::MessageInfo>("Shared::MessageInfo");
qRegisterMetaType<Shared::VCard>("Shared::VCard");

View File

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
</defs>
<path style="fill:currentColor;fill-opacity:1;stroke:none"
d="M 11,3 C 8.784,3 7,4.784 7,7 l 0,4 -2,0 c 0,2.666667 0,5.333333 0,8 4,0 8,0 12,0 l 0,-8 c -0.666667,0 -1.333333,0 -2,0 L 15,7 C 15,4.784 13.216,3 11,3 m 0,1 c 1.662,0 3,1.561 3,3.5 L 14,11 8,11 8,7.5 C 8,5.561 9.338,4 11,4"
class="ColorScheme-Text"
/>
</svg>

After

Width:  |  Height:  |  Size: 558 B

View File

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
</defs>
<path
style="fill:currentColor;fill-opacity:1;stroke:none"
d="M 8,2 C 8,2 6.5,3.9931391 2,4.4931641 2,4.4931641 2,11.493575 8,14 14,11.493575 14,4.4931641 14,4.4931641 9.5,3.9931391 8,2 8,2 Z m 0,1.0327148 c 1.1902463,1.008525 2.90787,1.6813196 5.134277,2.0200196 C 13.013333,6.1366343 12.897371,6.9523225 12.617188,7.7407227 12.02837,9.3975477 11.341831,10.405496 10.726074,11.130371 9.7719035,12.253646 8.905394,12.708244 8,13.160644 7.094606,12.708244 6.2280961,12.253646 5.2739258,11.130371 4.658169,10.405496 3.97163,9.3975477 3.3828125,7.7407227 3.102629,6.9523225 2.9866669,6.1366343 2.8657227,5.0527344 5.0921299,4.7140344 6.8097538,4.0412398 8,3.0327148 Z M 8,3.9321289 C 6.6923817,4.8398539 5.2233869,5.2995548 3.7490234,5.6123046 4.4471579,9.5738045 5.9510862,11.267813 8,12.328613 10.048914,11.267813 11.552843,9.5738045 12.250977,5.6123046 10.776613,5.2995547 9.3076183,4.8398539 8,3.9321289 Z"
class="ColorScheme-Text"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
</defs>
<path
style="fill:currentColor;fill-opacity:1;stroke:none"
d="m11 3c-2.216 0-4 1.784-4 4v1h1v-.5c0-1.939 1.338-3.5 3-3.5 1.662 0 3 1.561 3 3.5v3.5h-5-1-1-1-1v1 7h1 10 1v-8h-1-1v-4c0-2.216-1.784-4-4-4m-5 9h10v6h-10v-6"
class="ColorScheme-Text"
/>
</svg>

After

Width:  |  Height:  |  Size: 491 B

View File

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
</defs>
<path style="fill:currentColor;fill-opacity:1;stroke:none"
d="M 8,2 C 6.3431375,2 5,3.3431372 5,5 l 0,3 -2,0 0,6 10,0 0,-6 -2,0 0,-3 C 11,3.3431372 9.6568625,2 8,2 Z m 0,1 c 1.1045695,0 2,0.8954305 2,2 L 10,8 6,8 6,5 C 6,3.8954305 6.8954305,3 8,3 Z"
class="ColorScheme-Text"
/>
</svg>

After

Width:  |  Height:  |  Size: 522 B

View File

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
</defs>
<path
style="fill:currentColor;fill-opacity:1;stroke:none"
d="M 8,2 C 8,2 6.5,3.9931391 2,4.4931641 2,4.4931641 2,11.493575 8,14 14,11.493575 14,4.4931641 14,4.4931641 9.5,3.9931391 8,2 8,2 Z m 0,1.0327148 c 1.1902463,1.008525 2.90787,1.6813196 5.134277,2.0200196 C 13.013333,6.1366343 12.897371,6.9523225 12.617188,7.7407227 12.02837,9.3975477 11.341831,10.405496 10.726074,11.130371 9.7719035,12.253646 8.905394,12.708244 8,13.160644 7.094606,12.708244 6.2280961,12.253646 5.2739258,11.130371 4.658169,10.405496 3.97163,9.3975477 3.3828125,7.7407227 3.102629,6.9523225 2.9866669,6.1366343 2.8657227,5.0527344 5.0921299,4.7140344 6.8097538,4.0412398 8,3.0327148 Z M 8,3.9321289 C 6.6923817,4.8398539 5.2233869,5.2995548 3.7490234,5.6123046 4.4471579,9.5738045 5.9510862,11.267813 8,12.328613 10.048914,11.267813 11.552843,9.5738045 12.250977,5.6123046 10.776613,5.2995547 9.3076183,4.8398539 8,3.9321289 Z"
class="ColorScheme-Text"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
</defs>
<path style="fill:currentColor;fill-opacity:1;stroke:none"
d="M 8 2 C 6.3431375 2 5 3.3431371 5 5 L 5 6 L 6 6 L 6 5 C 6 3.8954305 6.8954305 3 8 3 C 9.1045695 3 10 3.8954305 10 5 L 10 8 L 7 8 L 6 8 L 5 8 L 3 8 L 3 14 L 13 14 L 13 8 L 11 8 L 11 5 C 11 3.3431371 9.6568625 2 8 2 z M 4 9 L 12 9 L 12 13 L 4 13 L 4 9 z "
class="ColorScheme-Text"
/>
</svg>

After

Width:  |  Height:  |  Size: 588 B

View File

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#eff0f1;
}
</style>
</defs>
<path style="fill:currentColor;fill-opacity:1;stroke:none"
d="M 11,3 C 8.784,3 7,4.784 7,7 l 0,4 -2,0 c 0,2.666667 0,5.333333 0,8 4,0 8,0 12,0 l 0,-8 c -0.666667,0 -1.333333,0 -2,0 L 15,7 C 15,4.784 13.216,3 11,3 m 0,1 c 1.662,0 3,1.561 3,3.5 L 14,11 8,11 8,7.5 C 8,5.561 9.338,4 11,4"
class="ColorScheme-Text"
/>
</svg>

After

Width:  |  Height:  |  Size: 558 B

View File

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#eff0f1;
}
</style>
</defs>
<path
style="fill:currentColor;fill-opacity:1;stroke:none"
d="M 8,2 C 8,2 6.5,3.9931391 2,4.4931641 2,4.4931641 2,11.493575 8,14 14,11.493575 14,4.4931641 14,4.4931641 9.5,3.9931391 8,2 8,2 Z m 0,1.0327148 c 1.1902463,1.008525 2.90787,1.6813196 5.134277,2.0200196 C 13.013333,6.1366343 12.897371,6.9523225 12.617188,7.7407227 12.02837,9.3975477 11.341831,10.405496 10.726074,11.130371 9.7719035,12.253646 8.905394,12.708244 8,13.160644 7.094606,12.708244 6.2280961,12.253646 5.2739258,11.130371 4.658169,10.405496 3.97163,9.3975477 3.3828125,7.7407227 3.102629,6.9523225 2.9866669,6.1366343 2.8657227,5.0527344 5.0921299,4.7140344 6.8097538,4.0412398 8,3.0327148 Z M 8,3.9321289 C 6.6923817,4.8398539 5.2233869,5.2995548 3.7490234,5.6123046 4.4471579,9.5738045 5.9510862,11.267813 8,12.328613 10.048914,11.267813 11.552843,9.5738045 12.250977,5.6123046 10.776613,5.2995547 9.3076183,4.8398539 8,3.9321289 Z"
class="ColorScheme-Text"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#eff0f1;
}
</style>
</defs>
<path
style="fill:currentColor;fill-opacity:1;stroke:none"
d="m11 3c-2.216 0-4 1.784-4 4v1h1v-.5c0-1.939 1.338-3.5 3-3.5 1.662 0 3 1.561 3 3.5v3.5h-5-1-1-1-1v1 7h1 10 1v-8h-1-1v-4c0-2.216-1.784-4-4-4m-5 9h10v6h-10v-6"
class="ColorScheme-Text"
/>
</svg>

After

Width:  |  Height:  |  Size: 491 B

View File

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#eff0f1;
}
</style>
</defs>
<path style="fill:currentColor;fill-opacity:1;stroke:none"
d="M 8,2 C 6.3431375,2 5,3.3431372 5,5 l 0,3 -2,0 0,6 10,0 0,-6 -2,0 0,-3 C 11,3.3431372 9.6568625,2 8,2 Z m 0,1 c 1.1045695,0 2,0.8954305 2,2 L 10,8 6,8 6,5 C 6,3.8954305 6.8954305,3 8,3 Z"
class="ColorScheme-Text"
/>
</svg>

After

Width:  |  Height:  |  Size: 522 B

View File

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#eff0f1;
}
</style>
</defs>
<path
style="fill:currentColor;fill-opacity:1;stroke:none"
d="M 8,2 C 8,2 6.5,3.9931391 2,4.4931641 2,4.4931641 2,11.493575 8,14 14,11.493575 14,4.4931641 14,4.4931641 9.5,3.9931391 8,2 8,2 Z m 0,1.0327148 c 1.1902463,1.008525 2.90787,1.6813196 5.134277,2.0200196 C 13.013333,6.1366343 12.897371,6.9523225 12.617188,7.7407227 12.02837,9.3975477 11.341831,10.405496 10.726074,11.130371 9.7719035,12.253646 8.905394,12.708244 8,13.160644 7.094606,12.708244 6.2280961,12.253646 5.2739258,11.130371 4.658169,10.405496 3.97163,9.3975477 3.3828125,7.7407227 3.102629,6.9523225 2.9866669,6.1366343 2.8657227,5.0527344 5.0921299,4.7140344 6.8097538,4.0412398 8,3.0327148 Z M 8,3.9321289 C 6.6923817,4.8398539 5.2233869,5.2995548 3.7490234,5.6123046 4.4471579,9.5738045 5.9510862,11.267813 8,12.328613 10.048914,11.267813 11.552843,9.5738045 12.250977,5.6123046 10.776613,5.2995547 9.3076183,4.8398539 8,3.9321289 Z"
class="ColorScheme-Text"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#eff0f1;
}
</style>
</defs>
<path style="fill:currentColor;fill-opacity:1;stroke:none"
d="M 8 2 C 6.3431375 2 5 3.3431371 5 5 L 5 6 L 6 6 L 6 5 C 6 3.8954305 6.8954305 3 8 3 C 9.1045695 3 10 3.8954305 10 5 L 10 8 L 7 8 L 6 8 L 5 8 L 3 8 L 3 14 L 13 14 L 13 8 L 11 8 L 11 5 C 11 3.3431371 9.6568625 2 8 2 z M 4 9 L 12 9 L 12 13 L 4 13 L 4 9 z "
class="ColorScheme-Text"
/>
</svg>

After

Width:  |  Height:  |  Size: 588 B

View File

@ -42,6 +42,9 @@
<file>images/fallback/dark/big/add.svg</file>
<file>images/fallback/dark/big/folder.svg</file>
<file>images/fallback/dark/big/document-preview.svg</file>
<file>images/fallback/dark/big/shield.svg</file>
<file>images/fallback/dark/big/lock.svg</file>
<file>images/fallback/dark/big/unlock.svg</file>
<file>images/fallback/dark/small/absent.svg</file>
@ -84,6 +87,9 @@
<file>images/fallback/dark/small/add.svg</file>
<file>images/fallback/dark/small/folder.svg</file>
<file>images/fallback/dark/small/document-preview.svg</file>
<file>images/fallback/dark/small/shield.svg</file>
<file>images/fallback/dark/small/lock.svg</file>
<file>images/fallback/dark/small/unlock.svg</file>
<file>images/fallback/light/big/absent.svg</file>
@ -126,6 +132,9 @@
<file>images/fallback/light/big/add.svg</file>
<file>images/fallback/light/big/folder.svg</file>
<file>images/fallback/light/big/document-preview.svg</file>
<file>images/fallback/light/big/shield.svg</file>
<file>images/fallback/light/big/lock.svg</file>
<file>images/fallback/light/big/unlock.svg</file>
<file>images/fallback/light/small/absent.svg</file>
@ -168,5 +177,8 @@
<file>images/fallback/light/small/add.svg</file>
<file>images/fallback/light/small/folder.svg</file>
<file>images/fallback/light/small/document-preview.svg</file>
<file>images/fallback/light/small/shield.svg</file>
<file>images/fallback/light/small/lock.svg</file>
<file>images/fallback/light/small/unlock.svg</file>
</qresource>
</RCC>

View File

@ -16,8 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SHARED_ENUMS_H
#define SHARED_ENUMS_H
#pragma once
#include <deque>
@ -170,4 +169,3 @@ static const EncryptionProtocol EncryptionProtocolHighest = EncryptionProtocol::
static const EncryptionProtocol EncryptionProtocolLowest = EncryptionProtocol::omemo2;
}
#endif // SHARED_ENUMS_H

View File

@ -16,8 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef EXCEPTION_H
#define EXCEPTION_H
#pragma once
#include <stdexcept>
#include <string>
@ -36,5 +35,3 @@ namespace Utils
const char* what() const noexcept( true );
};
}
#endif // EXCEPTION_H

View File

@ -62,70 +62,78 @@ Shared::Global::ColorSchemeName Shared::Global::colorSchemeName = 0;
Shared::Global::CreatePalette Shared::Global::createPalette = 0;
#endif
Shared::Global::Global():
availability({
tr("Online", "Availability"),
tr("Away", "Availability"),
tr("Absent", "Availability"),
tr("Busy", "Availability"),
tr("Chatty", "Availability"),
tr("Invisible", "Availability"),
tr("Offline", "Availability")
QCoreApplication::translate("Global", "Online", "Availability"),
QCoreApplication::translate("Global", "Away", "Availability"),
QCoreApplication::translate("Global", "Absent", "Availability"),
QCoreApplication::translate("Global", "Busy", "Availability"),
QCoreApplication::translate("Global", "Chatty", "Availability"),
QCoreApplication::translate("Global", "Invisible", "Availability"),
QCoreApplication::translate("Global", "Offline", "Availability")
}),
connectionState({
tr("Disconnected", "ConnectionState"),
tr("Scheduled", "ConnectionState"),
tr("Connecting", "ConnectionState"),
tr("Connected", "ConnectionState"),
tr("Error", "ConnectionState")
QCoreApplication::translate("Global", "Disconnected", "ConnectionState"),
QCoreApplication::translate("Global", "Scheduled", "ConnectionState"),
QCoreApplication::translate("Global", "Connecting", "ConnectionState"),
QCoreApplication::translate("Global", "Connected", "ConnectionState"),
QCoreApplication::translate("Global", "Error", "ConnectionState")
}),
subscriptionState({
tr("None", "SubscriptionState"),
tr("From", "SubscriptionState"),
tr("To", "SubscriptionState"),
tr("Both", "SubscriptionState"),
tr("Unknown", "SubscriptionState")
QCoreApplication::translate("Global", "None", "SubscriptionState"),
QCoreApplication::translate("Global", "From", "SubscriptionState"),
QCoreApplication::translate("Global", "To", "SubscriptionState"),
QCoreApplication::translate("Global", "Both", "SubscriptionState"),
QCoreApplication::translate("Global", "Unknown", "SubscriptionState")
}),
affiliation({
tr("Unspecified", "Affiliation"),
tr("Outcast", "Affiliation"),
tr("Nobody", "Affiliation"),
tr("Member", "Affiliation"),
tr("Admin", "Affiliation"),
tr("Owner", "Affiliation")
QCoreApplication::translate("Global", "Unspecified", "Affiliation"),
QCoreApplication::translate("Global", "Outcast", "Affiliation"),
QCoreApplication::translate("Global", "Nobody", "Affiliation"),
QCoreApplication::translate("Global", "Member", "Affiliation"),
QCoreApplication::translate("Global", "Admin", "Affiliation"),
QCoreApplication::translate("Global", "Owner", "Affiliation")
}),
role({
tr("Unspecified", "Role"),
tr("Nobody", "Role"),
tr("Visitor", "Role"),
tr("Participant", "Role"),
tr("Moderator", "Role")
QCoreApplication::translate("Global", "Unspecified", "Role"),
QCoreApplication::translate("Global", "Nobody", "Role"),
QCoreApplication::translate("Global", "Visitor", "Role"),
QCoreApplication::translate("Global", "Participant", "Role"),
QCoreApplication::translate("Global", "Moderator", "Role")
}),
messageState({
tr("Pending", "MessageState"),
tr("Sent", "MessageState"),
tr("Delivered", "MessageState"),
tr("Error", "MessageState")
QCoreApplication::translate("Global", "Pending", "MessageState"),
QCoreApplication::translate("Global", "Sent", "MessageState"),
QCoreApplication::translate("Global", "Delivered", "MessageState"),
QCoreApplication::translate("Global", "Error", "MessageState")
}),
accountPassword({
tr("Plain", "AccountPassword"),
tr("Jammed", "AccountPassword"),
tr("Always Ask", "AccountPassword"),
tr("KWallet", "AccountPassword")
QCoreApplication::translate("Global", "Plain", "AccountPassword"),
QCoreApplication::translate("Global", "Jammed", "AccountPassword"),
QCoreApplication::translate("Global", "Always Ask", "AccountPassword"),
QCoreApplication::translate("Global", "KWallet", "AccountPassword")
}),
trustLevel({
tr("Undecided", "TrustLevel"),
tr("Automatically distrusted", "TrustLevel"),
tr("Manually distrusted", "TrustLevel"),
tr("Automatically trusted", "TrustLevel"),
tr("Manually trusted", "TrustLevel"),
tr("Authenticated", "TrustLevel")
QCoreApplication::translate("Global", "Undecided", "TrustLevel"),
QCoreApplication::translate("Global", "Automatically distrusted", "TrustLevel"),
QCoreApplication::translate("Global", "Manually distrusted", "TrustLevel"),
QCoreApplication::translate("Global", "Automatically trusted", "TrustLevel"),
QCoreApplication::translate("Global", "Manually trusted", "TrustLevel"),
QCoreApplication::translate("Global", "Authenticated", "TrustLevel")
}),
encryptionProtocols({
QCoreApplication::translate("Global", "None", "EncryptionProtocol"),
QCoreApplication::translate("Global", "OMEMO 0", "EncryptionProtocol"),
QCoreApplication::translate("Global", "OMEMO 1", "EncryptionProtocol"),
QCoreApplication::translate("Global", "OMEMO 2", "EncryptionProtocol")
}),
accountPasswordDescription({
tr("Your password is going to be stored in config file in plain text", "AccountPasswordDescription"),
tr("Your password is going to be stored in config file but jammed with constant encryption key you can find in program source code. It might look like encryption but it's not", "AccountPasswordDescription"),
tr("Squawk is going to query you for the password on every start of the program", "AccountPasswordDescription"),
tr("Your password is going to be stored in KDE wallet storage (KWallet). You're going to be queried for permissions", "AccountPasswordDescription")
QCoreApplication::translate("Global", "Your password is going to be stored in config file in plain text", "AccountPasswordDescription"),
QCoreApplication::translate("Global", "Your password is going to be stored in config file but jammed with constant encryption key you can find in program source code. It might look like encryption but it's not", "AccountPasswordDescription"),
QCoreApplication::translate("Global", "Squawk is going to query you for the password on every start of the program", "AccountPasswordDescription"),
QCoreApplication::translate("Global", "Your password is going to be stored in KDE wallet storage (KWallet). You're going to be queried for permissions", "AccountPasswordDescription")
}),
defaultSystemStyle(QApplication::style()->objectName()),
defaultSystemPalette(QApplication::palette()),
@ -262,6 +270,10 @@ QString Shared::Global::getName(Shared::TrustLevel tl) {
return instance->trustLevel[static_cast<int>(tl)];
}
QString Shared::Global::getName(EncryptionProtocol ep) {
return instance->encryptionProtocols[static_cast<int>(ep)];
}
void Shared::Global::setSupported(const QString& pluginName, bool support) {
std::map<QString, bool>::iterator itr = instance->pluginSupport.find(pluginName);
if (itr != instance->pluginSupport.end()) {

View File

@ -16,8 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SHARED_GLOBAL_H
#define SHARED_GLOBAL_H
#pragma once
#include "enums.h"
#include "message.h"
@ -48,7 +47,6 @@
namespace Shared {
class Global {
Q_DECLARE_TR_FUNCTIONS(Global)
public:
struct FileInfo {
enum class Preview {
@ -75,6 +73,7 @@ namespace Shared {
static QString getName(Message::State rl);
static QString getName(AccountPassword ap);
static QString getName(TrustLevel tl);
static QString getName(EncryptionProtocol ep);
static QString getDescription(AccountPassword ap);
@ -86,6 +85,7 @@ namespace Shared {
const std::deque<QString> messageState;
const std::deque<QString> accountPassword;
const std::deque<QString> trustLevel;
const std::deque<QString> encryptionProtocols;
const std::deque<QString> accountPasswordDescription;
@ -124,7 +124,7 @@ namespace Shared {
class EnumOutOfRange: public Utils::Exception {
public:
EnumOutOfRange(const std::string& p_name):Exception(), name(p_name) {}
std::string getMessage() const{
return "An attempt to get enum " + name + " from integer out of range of that enum";
}
@ -161,5 +161,3 @@ namespace Shared {
#endif
};
}
#endif // SHARED_GLOBAL_H

View File

@ -16,8 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SHARED_ICONS_H
#define SHARED_ICONS_H
#pragma once
#include <QIcon>
@ -175,8 +174,9 @@ static const std::map<QString, std::pair<QString, QString>> icons = {
{"unfavorite", {"draw-star", "unfavorite"}},
{"list-add", {"list-add", "add"}},
{"folder", {"folder", "folder"}},
{"document-preview", {"document-preview", "document-preview"}}
{"document-preview", {"document-preview", "document-preview"}},
{"secure", {"security-high", "shield"}},
{"lock", {"lock", "lock"}},
{"unlock", {"unlock", "unlock"}}
};
}
#endif // SHARED_ICONS_H

View File

@ -37,7 +37,8 @@ Shared::Message::Message(Shared::Message::Type p_type):
originalMessage(),
lastModified(),
stanzaId(),
attachPath()
attachPath(),
encryption(EncryptionProtocol::none)
{}
Shared::Message::Message():
@ -58,7 +59,8 @@ Shared::Message::Message():
originalMessage(),
lastModified(),
stanzaId(),
attachPath()
attachPath(),
encryption(EncryptionProtocol::none)
{}
QString Shared::Message::getBody() const {
@ -234,9 +236,8 @@ void Shared::Message::setType(Shared::Message::Type t) {
void Shared::Message::setState(Shared::Message::State p_state) {
state = p_state;
if (state != State::error) {
if (state != State::error)
errorText = "";
}
}
bool Shared::Message::serverStored() const {

View File

@ -16,8 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SHAPER_MESSAGE_H
#define SHAPER_MESSAGE_H
#pragma once
#include <QString>
#include <QDateTime>
@ -154,5 +153,3 @@ private:
};
}
#endif // SHAPER_MESSAGE_H

View File

@ -16,8 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PATHCHECK_H
#define PATHCHECK_H
#pragma once
#include <QString>
#include <QStandardPaths>
@ -40,5 +39,3 @@ QString squawkifyPath(QString path);
bool isSubdirectoryOfSettings(const QString& path);
}
#endif // PATHCHECK_H

View File

@ -16,8 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SHARED_UTILS_H
#define SHARED_UTILS_H
#pragma once
#include <QString>
#include <QStringList>
@ -76,5 +75,3 @@ enum class Hover {
anchor
};
}
#endif // SHARED_UTILS_H

View File

@ -24,12 +24,11 @@
#include "shared/icons.h"
#include "shared/global.h"
namespace Ui
{
namespace Ui {
class Chat;
}
class Chat : public Conversation
{
class Chat : public Conversation {
Q_OBJECT
public:
Chat(Models::Account* acc, Models::Contact* p_contact, QWidget* parent = 0);

View File

@ -120,6 +120,7 @@ Conversation::~Conversation() {
delete contextMenu;
element->feed->decrementObservers();
delete m_ui;
}
void Conversation::onAccountChanged(Models::Item* item, int row, int col) {

View File

@ -20,6 +20,7 @@
#define CONVERSATION_H
#include <QWidget>
#include <QObject>
#include <QScopedPointer>
#include <QMap>
#include <QMimeData>
@ -134,7 +135,7 @@ protected:
Models::Element* element;
QString palJid;
QString activePalResource;
QScopedPointer<Ui::Conversation> m_ui;
Ui::Conversation* m_ui;
KeyEnterReceiver ker;
QString thread;
QLabel* statusIcon;

View File

@ -14,5 +14,4 @@ set(HEADER_FILES
target_sources(squawk PRIVATE
${SOURCE_FILES}
${HEADER_FILES}
)

View File

@ -47,22 +47,23 @@ MessageDelegate::MessageDelegate(QObject* parent):
dateFont(Shared::Global::getInstance()->smallFont),
nickMetrics(Shared::Global::getInstance()->headerFontMetrics),
dateMetrics(Shared::Global::getInstance()->smallFontMetrics),
bodyRenderer(new QTextDocument()),
bodyRenderer(),
buttonHeight(0),
buttonWidth(0),
barHeight(0),
buttons(new std::map<QString, FeedButton*>()),
bars(new std::map<QString, QProgressBar*>()),
statusIcons(new std::map<QString, QLabel*>()),
pencilIcons(new std::map<QString, QLabel*>()),
previews(new std::map<QString, Preview*>()),
idsToKeep(new std::set<QString>()),
buttons(),
bars(),
statusIcons(),
pencilIcons(),
encryptionIcons(),
previews(),
idsToKeep(),
clearingWidgets(false),
currentId(""),
selection(0, 0)
{
bodyRenderer->setDocumentMargin(0);
bodyRenderer->setDefaultFont(bodyFont);
bodyRenderer.setDocumentMargin(0);
bodyRenderer.setDefaultFont(bodyFont);
QPushButton btn(QCoreApplication::translate("MessageLine", "Download"));
buttonHeight = btn.sizeHint().height();
@ -73,28 +74,23 @@ MessageDelegate::MessageDelegate(QObject* parent):
}
MessageDelegate::~MessageDelegate() {
for (const std::pair<const QString, FeedButton*>& pair: *buttons)
for (const std::pair<const QString, FeedButton*>& pair: buttons)
delete pair.second;
for (const std::pair<const QString, QProgressBar*>& pair: *bars)
for (const std::pair<const QString, QProgressBar*>& pair: bars)
delete pair.second;
for (const std::pair<const QString, QLabel*>& pair: *statusIcons)
for (const std::pair<const QString, QLabel*>& pair: statusIcons)
delete pair.second;
for (const std::pair<const QString, QLabel*>& pair: *pencilIcons)
for (const std::pair<const QString, QLabel*>& pair: pencilIcons)
delete pair.second;
for (const std::pair<const QString, QLabel*>& pair: encryptionIcons)
delete pair.second;
for (const std::pair<const QString, Preview*>& pair: *previews)
for (const std::pair<const QString, Preview*>& pair: previews)
delete pair.second;
delete statusIcons;
delete pencilIcons;
delete idsToKeep;
delete buttons;
delete bars;
delete previews;
delete bodyRenderer;
}
void MessageDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
@ -168,6 +164,7 @@ void MessageDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio
painter->setPen(q);
painter->drawText(opt.rect, opt.displayAlignment, dateString, &rect);
int currentY = opt.rect.y();
int statusOffset = statusIconSize;
if (data.sentByMe) {
QLabel* statusIcon = getStatusIcon(data);
@ -176,30 +173,43 @@ void MessageDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio
statusIcon->show();
opt.rect.adjust(0, statusIconSize + textMargin, 0, 0);
statusOffset = statusIconSize + margin;
}
if (data.correction.corrected) {
QLabel* pencilIcon = getPencilIcon(data);
pencilIcon->setParent(vp);
if (data.sentByMe)
pencilIcon->move(opt.rect.left() + statusIconSize + margin, currentY);
pencilIcon->move(opt.rect.left() + statusOffset, currentY);
else
pencilIcon->move(opt.rect.right() - statusIconSize - margin, currentY);
pencilIcon->move(opt.rect.right() - statusOffset, currentY);
pencilIcon->show();
statusOffset += statusIconSize + margin;
} else {
std::map<QString, QLabel*>::const_iterator itr = pencilIcons->find(data.id);
if (itr != pencilIcons->end()) {
std::map<QString, QLabel*>::const_iterator itr = pencilIcons.find(data.id);
if (itr != pencilIcons.end()) {
delete itr->second;
pencilIcons->erase(itr);
pencilIcons.erase(itr);
}
}
if (data.encryption != Shared::EncryptionProtocol::none) {
QLabel* shieldIcon = getEncryptionIcon(data);
shieldIcon->setParent(vp);
if (data.sentByMe)
shieldIcon->move(opt.rect.left() + statusOffset, currentY);
else
shieldIcon->move(opt.rect.right() - statusOffset, currentY);
shieldIcon->show();
statusOffset += statusIconSize + margin;
}
painter->restore();
if (clearingWidgets)
idsToKeep->insert(data.id);
idsToKeep.insert(data.id);
}
void MessageDelegate::paintBubble(const Models::FeedItem& data, QPainter* painter, const QStyleOptionViewItem& option) const {
@ -281,11 +291,11 @@ QSize MessageDelegate::sizeHint(const QStyleOptionViewItem& option, const QModel
Models::FeedItem data = qvariant_cast<Models::FeedItem>(vi);
QSize messageSize(0, 0);
if (data.text.size() > 0) {
bodyRenderer->setPlainText(data.text);
bodyRenderer->setTextWidth(messageRect.size().width());
bodyRenderer.setPlainText(data.text);
bodyRenderer.setTextWidth(messageRect.size().width());
QSizeF size = bodyRenderer->size();
size.setWidth(bodyRenderer->idealWidth());
QSizeF size = bodyRenderer.size();
size.setWidth(bodyRenderer.idealWidth());
messageSize = QSize(std::ceil(size.width()), std::ceil(size.height()));
messageSize.rheight() += textMargin;
}
@ -338,9 +348,12 @@ QSize MessageDelegate::sizeHint(const QStyleOptionViewItem& option, const QModel
messageSize.rheight() += dateSize.height() > statusIconSize ? dateSize.height() : statusIconSize;
int statusWidth = dateSize.width() + statusIconSize + margin;
if (data.correction.corrected) {
if (data.correction.corrected)
statusWidth += statusIconSize + margin;
}
if (data.encryption != Shared::EncryptionProtocol::none)
statusWidth += statusIconSize + margin;
messageSize.setWidth(std::max(statusWidth, messageSize.width()));
messageSize.rwidth() += 2 * bubbleMargin;
@ -399,10 +412,10 @@ QString MessageDelegate::getAnchor(const QPoint& point, const QModelIndex& index
if (localHint.contains(point)) {
QPoint translated = point - localHint.topLeft();
bodyRenderer->setHtml(Shared::processMessageBody(data.text));
bodyRenderer->setTextWidth(localHint.size().width());
bodyRenderer.setHtml(Shared::processMessageBody(data.text));
bodyRenderer.setTextWidth(localHint.size().width());
return bodyRenderer->documentLayout()->anchorAt(translated);
return bodyRenderer.documentLayout()->anchorAt(translated);
}
}
@ -424,13 +437,13 @@ QString MessageDelegate::leftDoubleClick(const QPoint& point, const QModelIndex&
if (localHint.contains(point)) {
QPoint translated = point - localHint.topLeft();
bodyRenderer->setHtml(Shared::processMessageBody(data.text));
bodyRenderer->setTextWidth(localHint.size().width());
bodyRenderer.setHtml(Shared::processMessageBody(data.text));
bodyRenderer.setTextWidth(localHint.size().width());
QAbstractTextDocumentLayout* lay = bodyRenderer->documentLayout();
QAbstractTextDocumentLayout* lay = bodyRenderer.documentLayout();
int position = lay->hitTest(translated, Qt::HitTestAccuracy::FuzzyHit);
QTextCursor cursor(bodyRenderer);
QTextCursor cursor(&bodyRenderer);
cursor.setPosition(position, QTextCursor::MoveAnchor);
cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
@ -456,10 +469,10 @@ Shared::Hover MessageDelegate::hoverType(const QPoint& point, const QModelIndex&
if (localHint.contains(point)) {
QPoint translated = point - localHint.topLeft();
bodyRenderer->setHtml(Shared::processMessageBody(data.text));
bodyRenderer->setTextWidth(localHint.size().width());
bodyRenderer.setHtml(Shared::processMessageBody(data.text));
bodyRenderer.setTextWidth(localHint.size().width());
QAbstractTextDocumentLayout* lay = bodyRenderer->documentLayout();
QAbstractTextDocumentLayout* lay = bodyRenderer.documentLayout();
QString anchor = lay->anchorAt(translated);
if (anchor.size() > 0) {
@ -489,15 +502,15 @@ QString MessageDelegate::mouseDrag(const QPoint& start, const QPoint& end, const
last.setY(std::max(last.y(), 0));
last.setY(std::min(last.y(), localHint.height()));
bodyRenderer->setHtml(Shared::processMessageBody(data.text));
bodyRenderer->setTextWidth(localHint.size().width());
selection.first = bodyRenderer->documentLayout()->hitTest(first, Qt::HitTestAccuracy::FuzzyHit);
selection.second = bodyRenderer->documentLayout()->hitTest(last, Qt::HitTestAccuracy::FuzzyHit);
bodyRenderer.setHtml(Shared::processMessageBody(data.text));
bodyRenderer.setTextWidth(localHint.size().width());
selection.first = bodyRenderer.documentLayout()->hitTest(first, Qt::HitTestAccuracy::FuzzyHit);
selection.second = bodyRenderer.documentLayout()->hitTest(last, Qt::HitTestAccuracy::FuzzyHit);
currentId = data.id;
if (selection.first != selection.second) {
QTextCursor cursor(bodyRenderer);
QTextCursor cursor(&bodyRenderer);
cursor.setPosition(selection.first, QTextCursor::MoveAnchor);
cursor.setPosition(selection.second, QTextCursor::KeepAnchor);
return cursor.selectedText();
@ -562,17 +575,17 @@ int MessageDelegate::paintBar(QProgressBar* bar, QPainter* painter, bool sentByM
int MessageDelegate::paintPreview(const Models::FeedItem& data, QPainter* painter, QStyleOptionViewItem& option) const {
Preview* preview = 0;
std::map<QString, Preview*>::iterator itr = previews->find(data.id);
std::map<QString, Preview*>::iterator itr = previews.find(data.id);
QSize size = option.rect.size();
QString path = Shared::resolvePath(data.attach.localPath);
if (itr != previews->end()) {
if (itr != previews.end()) {
preview = itr->second;
preview->actualize(path, size, option.rect.topLeft());
} else {
QWidget* vp = static_cast<QWidget*>(painter->device());
preview = new Preview(path, size, option.rect.topLeft(), vp);
previews->insert(std::make_pair(data.id, preview));
previews.insert(std::make_pair(data.id, preview));
}
if (!preview->isFileReachable()) //this is the situation when the file preview couldn't be painted because the file was moved
@ -585,15 +598,15 @@ int MessageDelegate::paintPreview(const Models::FeedItem& data, QPainter* painte
}
QPushButton * MessageDelegate::getButton(const Models::FeedItem& data) const {
std::map<QString, FeedButton*>::const_iterator itr = buttons->find(data.id);
std::map<QString, FeedButton*>::const_iterator itr = buttons.find(data.id);
FeedButton* result = 0;
if (itr != buttons->end()) {
if (itr != buttons.end()) {
result = itr->second;
} else {
std::map<QString, QProgressBar*>::const_iterator barItr = bars->find(data.id);
if (barItr != bars->end()) {
std::map<QString, QProgressBar*>::const_iterator barItr = bars.find(data.id);
if (barItr != bars.end()) {
delete barItr->second;
bars->erase(barItr);
bars.erase(barItr);
}
}
@ -601,7 +614,7 @@ QPushButton * MessageDelegate::getButton(const Models::FeedItem& data) const {
result = new FeedButton();
result->messageId = data.id;
result->setText(QCoreApplication::translate("MessageLine", "Download"));
buttons->insert(std::make_pair(data.id, result));
buttons.insert(std::make_pair(data.id, result));
connect(result, &QPushButton::clicked, this, &MessageDelegate::onButtonPushed);
}
@ -609,22 +622,22 @@ QPushButton * MessageDelegate::getButton(const Models::FeedItem& data) const {
}
QProgressBar * MessageDelegate::getBar(const Models::FeedItem& data) const {
std::map<QString, QProgressBar*>::const_iterator barItr = bars->find(data.id);
std::map<QString, QProgressBar*>::const_iterator barItr = bars.find(data.id);
QProgressBar* result = 0;
if (barItr != bars->end()) {
if (barItr != bars.end()) {
result = barItr->second;
} else {
std::map<QString, FeedButton*>::const_iterator itr = buttons->find(data.id);
if (itr != buttons->end()) {
std::map<QString, FeedButton*>::const_iterator itr = buttons.find(data.id);
if (itr != buttons.end()) {
delete itr->second;
buttons->erase(itr);
buttons.erase(itr);
}
}
if (result == 0) {
result = new QProgressBar();
result->setRange(0, 100);
bars->insert(std::make_pair(data.id, result));
bars.insert(std::make_pair(data.id, result));
}
result->setValue(data.attach.progress * 100);
@ -633,14 +646,14 @@ QProgressBar * MessageDelegate::getBar(const Models::FeedItem& data) const {
}
QLabel * MessageDelegate::getStatusIcon(const Models::FeedItem& data) const {
std::map<QString, QLabel*>::const_iterator itr = statusIcons->find(data.id);
std::map<QString, QLabel*>::const_iterator itr = statusIcons.find(data.id);
QLabel* result = 0;
if (itr != statusIcons->end()) {
if (itr != statusIcons.end()) {
result = itr->second;
} else {
result = new QLabel();
statusIcons->insert(std::make_pair(data.id, result));
statusIcons.insert(std::make_pair(data.id, result));
}
QIcon q(Shared::icon(Shared::messageStateThemeIcons[static_cast<uint8_t>(data.state)]));
@ -657,17 +670,17 @@ QLabel * MessageDelegate::getStatusIcon(const Models::FeedItem& data) const {
return result;
}
QLabel * MessageDelegate::getPencilIcon(const Models::FeedItem& data) const {
std::map<QString, QLabel*>::const_iterator itr = pencilIcons->find(data.id);
QLabel* MessageDelegate::getPencilIcon(const Models::FeedItem& data) const {
std::map<QString, QLabel*>::const_iterator itr = pencilIcons.find(data.id);
QLabel* result = 0;
if (itr != pencilIcons->end()) {
if (itr != pencilIcons.end()) {
result = itr->second;
} else {
result = new QLabel();
QIcon icon = Shared::icon("edit-rename");
result->setPixmap(icon.pixmap(statusIconSize));
pencilIcons->insert(std::make_pair(data.id, result));
pencilIcons.insert(std::make_pair(data.id, result));
}
result->setToolTip("Last time edited: " + data.correction.lastCorrection.toLocalTime().toString()
@ -676,30 +689,46 @@ QLabel * MessageDelegate::getPencilIcon(const Models::FeedItem& data) const {
return result;
}
QLabel* MessageDelegate::getEncryptionIcon(const Models::FeedItem& data) const {
std::map<QString, QLabel*>::const_iterator itr = encryptionIcons.find(data.id);
QLabel* result = 0;
if (itr != encryptionIcons.end()) {
result = itr->second;
} else {
result = new QLabel();
QIcon icon = Shared::icon("secure");
result->setPixmap(icon.pixmap(statusIconSize));
encryptionIcons.insert(std::make_pair(data.id, result));
result->setToolTip("Encrypted: " + Shared::Global::getName(data.encryption));
}
return result;
}
template <typename T>
void removeElements(std::map<QString, T*>* elements, std::set<QString>* idsToKeep) {
void removeElements(std::map<QString, T*>& elements, std::set<QString>& idsToKeep) {
std::set<QString> toRemove;
for (const std::pair<const QString, T*>& pair: *elements) {
if (idsToKeep->find(pair.first) == idsToKeep->end()) {
for (const std::pair<const QString, T*>& pair: elements) {
if (idsToKeep.find(pair.first) == idsToKeep.end()) {
delete pair.second;
toRemove.insert(pair.first);
}
}
for (const QString& key : toRemove) {
elements->erase(key);
}
for (const QString& key : toRemove)
elements.erase(key);
}
int MessageDelegate::paintBody(const Models::FeedItem& data, QPainter* painter, QStyleOptionViewItem& option) const
{
if (data.text.size() > 0) {
bodyRenderer->setHtml(Shared::processMessageBody(data.text));
bodyRenderer->setTextWidth(option.rect.size().width());
bodyRenderer.setHtml(Shared::processMessageBody(data.text));
bodyRenderer.setTextWidth(option.rect.size().width());
painter->save();
painter->translate(option.rect.topLeft());
if (data.id == currentId) {
QTextCursor cursor(bodyRenderer);
QTextCursor cursor(&bodyRenderer);
cursor.setPosition(selection.first, QTextCursor::MoveAnchor);
cursor.setPosition(selection.second, QTextCursor::KeepAnchor);
QTextCharFormat format = cursor.charFormat();
@ -708,10 +737,10 @@ int MessageDelegate::paintBody(const Models::FeedItem& data, QPainter* painter,
cursor.setCharFormat(format);
}
bodyRenderer->drawContents(painter);
bodyRenderer.drawContents(painter);
painter->restore();
QSize bodySize(std::ceil(bodyRenderer->idealWidth()), std::ceil(bodyRenderer->size().height()));
QSize bodySize(std::ceil(bodyRenderer.idealWidth()), std::ceil(bodyRenderer.size().height()));
option.rect.adjust(0, bodySize.height() + textMargin, 0, 0);
return bodySize.width();
@ -720,7 +749,7 @@ int MessageDelegate::paintBody(const Models::FeedItem& data, QPainter* painter,
}
void MessageDelegate::beginClearWidgets() {
idsToKeep->clear();
idsToKeep.clear();
clearingWidgets = true;
}
@ -730,9 +759,10 @@ void MessageDelegate::endClearWidgets() {
removeElements(bars, idsToKeep);
removeElements(statusIcons, idsToKeep);
removeElements(pencilIcons, idsToKeep);
removeElements(encryptionIcons, idsToKeep);
removeElements(previews, idsToKeep);
idsToKeep->clear();
idsToKeep.clear();
clearingWidgets = false;
}
}
@ -743,15 +773,15 @@ void MessageDelegate::onButtonPushed() const {
}
void MessageDelegate::clearHelperWidget(const Models::FeedItem& data) const {
std::map<QString, FeedButton*>::const_iterator itr = buttons->find(data.id);
if (itr != buttons->end()) {
std::map<QString, FeedButton*>::const_iterator itr = buttons.find(data.id);
if (itr != buttons.end()) {
delete itr->second;
buttons->erase(itr);
buttons.erase(itr);
} else {
std::map<QString, QProgressBar*>::const_iterator barItr = bars->find(data.id);
if (barItr != bars->end()) {
std::map<QString, QProgressBar*>::const_iterator barItr = bars.find(data.id);
if (barItr != bars.end()) {
delete barItr->second;
bars->erase(barItr);
bars.erase(barItr);
}
}
}

View File

@ -1,23 +1,22 @@
/*
* Squawk messenger.
* 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 MESSAGEDELEGATE_H
#define MESSAGEDELEGATE_H
#pragma once
#include <map>
#include <set>
@ -44,17 +43,16 @@ namespace Models {
struct FeedItem;
};
class MessageDelegate : public QStyledItemDelegate
{
class MessageDelegate : public QStyledItemDelegate {
Q_OBJECT
public:
MessageDelegate(QObject *parent = nullptr);
~MessageDelegate();
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override;
//void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const override;
bool editorEvent(QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index) override;
void endClearWidgets();
void beginClearWidgets();
@ -66,12 +64,12 @@ public:
static int avatarHeight;
static int margin;
signals:
void buttonPushed(const QString& messageId) const;
void invalidPath(const QString& messageId) const;
void openLink(const QString& href) const;
protected:
int paintButton(QPushButton* btn, QPainter* painter, bool sentByMe, QStyleOptionViewItem& option) const;
int paintBar(QProgressBar* bar, QPainter* painter, bool sentByMe, QStyleOptionViewItem& option) const;
@ -85,6 +83,7 @@ protected:
QProgressBar* getBar(const Models::FeedItem& data) const;
QLabel* getStatusIcon(const Models::FeedItem& data) const;
QLabel* getPencilIcon(const Models::FeedItem& data) const;
QLabel* getEncryptionIcon(const Models::FeedItem& data) const;
void clearHelperWidget(const Models::FeedItem& data) const;
bool needToDrawAvatar(const QModelIndex& index, const Models::FeedItem& data, const QStyleOptionViewItem& option) const;
@ -92,36 +91,35 @@ protected:
QRect getHoveredMessageBodyRect(const QModelIndex& index, const Models::FeedItem& data, const QRect& sizeHint) const;
QString getAnchor(const QPoint& point, const QModelIndex& index, const QRect& sizeHint) const;
protected slots:
void onButtonPushed() const;
private:
class FeedButton : public QPushButton {
public:
QString messageId;
};
const QFont& bodyFont;
const QFont& nickFont;
const QFont& dateFont;
const QFontMetrics& nickMetrics;
const QFontMetrics& dateMetrics;
QTextDocument* bodyRenderer;
mutable QTextDocument bodyRenderer;
int buttonHeight;
int buttonWidth;
int barHeight;
std::map<QString, FeedButton*>* buttons;
std::map<QString, QProgressBar*>* bars;
std::map<QString, QLabel*>* statusIcons;
std::map<QString, QLabel*>* pencilIcons;
std::map<QString, Preview*>* previews;
std::set<QString>* idsToKeep;
mutable std::map<QString, FeedButton*> buttons;
mutable std::map<QString, QProgressBar*> bars;
mutable std::map<QString, QLabel*> statusIcons;
mutable std::map<QString, QLabel*> pencilIcons;
mutable std::map<QString, QLabel*> encryptionIcons;
mutable std::map<QString, Preview*> previews;
mutable std::set<QString> idsToKeep;
bool clearingWidgets;
QString currentId;
std::pair<int, int> selection;
};
#endif // MESSAGEDELEGATE_H

View File

@ -29,6 +29,7 @@ const QHash<int, QByteArray> Models::MessageFeed::roles = {
{Sender, "sender"},
{Date, "date"},
{DeliveryState, "deliveryState"},
{Encryption, "encryption"},
{Correction, "correction"},
{SentByMe,"sentByMe"},
{Avatar, "avatar"},
@ -51,20 +52,16 @@ Models::MessageFeed::MessageFeed(const Element* ri, QObject* parent):
failedUploads(),
unreadMessages(new std::set<QString>()),
observersAmount(0)
{
}
{}
Models::MessageFeed::~MessageFeed()
{
Models::MessageFeed::~MessageFeed() {
delete unreadMessages;
for (Shared::Message* message : storage) {
for (Shared::Message* message : storage)
delete message;
}
}
void Models::MessageFeed::addMessage(const Shared::Message& msg)
{
void Models::MessageFeed::addMessage(const Shared::Message& msg) {
QString id = msg.getId();
StorageById::const_iterator itr = indexById.find(id);
if (itr != indexById.end()) {
@ -75,11 +72,11 @@ void Models::MessageFeed::addMessage(const Shared::Message& msg)
Shared::Message* copy = new Shared::Message(msg);
StorageByTime::const_iterator tItr = indexByTime.upper_bound(msg.getTime());
int position;
if (tItr == indexByTime.end()) {
if (tItr == indexByTime.end())
position = storage.size();
} else {
else
position = indexByTime.rank(tItr);
}
beginInsertRows(QModelIndex(), position, position);
storage.insert(copy);
endInsertRows();
@ -93,8 +90,7 @@ void Models::MessageFeed::addMessage(const Shared::Message& msg)
}
}
void Models::MessageFeed::changeMessage(const QString& id, const QMap<QString, QVariant>& data)
{
void Models::MessageFeed::changeMessage(const QString& id, const QMap<QString, QVariant>& data) {
StorageById::iterator itr = indexById.find(id);
if (itr == indexById.end()) {
qDebug() << "received a command to change a message, but the message couldn't be found, skipping";
@ -159,9 +155,8 @@ void Models::MessageFeed::changeMessage(const QString& id, const QMap<QString, Q
}
QVector<int> cr;
for (MessageRoles role : changeRoles) {
for (MessageRoles role : changeRoles)
cr.push_back(role);
}
emit dataChanged(index, index, cr);
@ -173,14 +168,15 @@ void Models::MessageFeed::changeMessage(const QString& id, const QMap<QString, Q
}
}
std::set<Models::MessageFeed::MessageRoles> Models::MessageFeed::detectChanges(const Shared::Message& msg, const QMap<QString, QVariant>& data) const
{
std::set<Models::MessageFeed::MessageRoles> Models::MessageFeed::detectChanges(
const Shared::Message& msg,
const QMap<QString, QVariant>& data
) const {
std::set<MessageRoles> roles;
Shared::Message::State state = msg.getState();
QMap<QString, QVariant>::const_iterator itr = data.find("state");
if (itr != data.end() && static_cast<Shared::Message::State>(itr.value().toUInt()) != state) {
if (itr != data.end() && static_cast<Shared::Message::State>(itr.value().toUInt()) != state)
roles.insert(MessageRoles::DeliveryState);
}
itr = data.find("outOfBandUrl");
bool att = false;
@ -255,9 +251,8 @@ QVariant Models::MessageFeed::data(const QModelIndex& index, int role) const {
case Qt::DisplayRole:
case Text: {
QString body = msg->getBody();
if (body != msg->getOutOfBandUrl()) {
if (body != msg->getOutOfBandUrl())
answer = body;
}
}
break;
case Sender:
@ -276,6 +271,9 @@ QVariant Models::MessageFeed::data(const QModelIndex& index, int role) const {
case DeliveryState:
answer = static_cast<unsigned int>(msg->getState());
break;
case Encryption:
answer = QVariant::fromValue(msg->getEncryption());
break;
case Correction:
answer.setValue(fillCorrection(*msg));;
break;
@ -318,13 +316,13 @@ QVariant Models::MessageFeed::data(const QModelIndex& index, int role) const {
item.sentByMe = sentByMe(*msg);
item.date = msg->getTime();
item.state = msg->getState();
item.encryption = msg->getEncryption();
item.error = msg->getErrorText();
item.correction = fillCorrection(*msg);
QString body = msg->getBody();
if (body != msg->getOutOfBandUrl()) {
if (body != msg->getOutOfBandUrl())
item.text = body;
}
item.avatar.clear();
if (item.sentByMe) {
@ -419,13 +417,11 @@ QModelIndex Models::MessageFeed::index(int row, int column, const QModelIndex& p
return QModelIndex();
StorageByTime::iterator itr = indexByTime.nth(row);
if (itr != indexByTime.end()) {
Shared::Message* msg = *itr;
return createIndex(row, column, msg);
} else {
if (itr == indexByTime.end())
return QModelIndex();
}
Shared::Message* msg = *itr;
return createIndex(row, column, msg);
}
QHash<int, QByteArray> Models::MessageFeed::roleNames() const {return roles;}

View File

@ -16,12 +16,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MESSAGEFEED_H
#define MESSAGEFEED_H
#pragma once
#include <QAbstractListModel>
#include <QDateTime>
#include <QString>
#include <QHash>
#include <set>
@ -100,6 +100,7 @@ public:
Sender,
Date,
DeliveryState,
Encryption,
Correction,
SentByMe,
Avatar,
@ -216,6 +217,7 @@ struct FeedItem {
Edition correction;
QDateTime date;
Shared::Message::State state;
Shared::EncryptionProtocol encryption;
Attachment attach;
};
};
@ -224,4 +226,4 @@ Q_DECLARE_METATYPE(Models::Attachment);
Q_DECLARE_METATYPE(Models::Edition);
Q_DECLARE_METATYPE(Models::FeedItem);
#endif // MESSAGEFEED_H
#pragma once

View File

@ -16,8 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PREVIEW_H
#define PREVIEW_H
#pragma once
#include <QWidget>
#include <QString>
@ -75,5 +74,3 @@ private:
bool fileReachable;
bool actualPreview;
};
#endif // PREVIEW_H