1
0
forked from blue/squawk

some work towards encryption

This commit is contained in:
Blue 2023-11-04 22:12:15 -03:00
parent 297e08ba41
commit a7d1a28f29
Signed by untrusted user: blue
GPG Key ID: 9B203B252A63EE38
21 changed files with 129 additions and 81 deletions

View File

@ -46,13 +46,6 @@ endif()
find_package(Boost COMPONENTS) find_package(Boost COMPONENTS)
target_include_directories(squawk PRIVATE ${Boost_INCLUDE_DIRS}) target_include_directories(squawk PRIVATE ${Boost_INCLUDE_DIRS})
target_include_directories(squawk PRIVATE ${Qt${QT_VERSION_MAJOR}_INCLUDE_DIRS})
target_include_directories(squawk PRIVATE ${Qt${QT_VERSION_MAJOR}Widgets_INCLUDE_DIRS})
target_include_directories(squawk PRIVATE ${Qt${QT_VERSION_MAJOR}DBus_INCLUDE_DIRS})
target_include_directories(squawk PRIVATE ${Qt${QT_VERSION_MAJOR}Gui_INCLUDE_DIRS})
target_include_directories(squawk PRIVATE ${Qt${QT_VERSION_MAJOR}Xml_INCLUDE_DIRS})
target_include_directories(squawk PRIVATE ${Qt${QT_VERSION_MAJOR}Network_INCLUDE_DIRS})
target_include_directories(squawk PRIVATE ${Qt${QT_VERSION_MAJOR}Core_INCLUDE_DIRS})
#OMEMO #OMEMO
if (WITH_OMEMO) if (WITH_OMEMO)

View File

@ -31,7 +31,6 @@ target_sources(squawk PRIVATE
target_include_directories(squawk PRIVATE ${LMDB_INCLUDE_DIRS}) target_include_directories(squawk PRIVATE ${LMDB_INCLUDE_DIRS})
add_subdirectory(handlers) add_subdirectory(handlers)
add_subdirectory(storage)
add_subdirectory(passwordStorageEngines) add_subdirectory(passwordStorageEngines)
add_subdirectory(components) add_subdirectory(components)
add_subdirectory(delayManager) add_subdirectory(delayManager)

View File

@ -669,6 +669,17 @@ void Core::Account::setRoomJoined(const QString& jid, bool joined) {
conf->setJoined(joined); conf->setJoined(joined);
} }
void Core::Account::setContactEncryption(const QString& jid, Shared::EncryptionProtocol value) {
Contact* cnt = rh->getContact(jid);
if (cnt == nullptr) {
qDebug() << "An attempt to set encryption to the non-existing contact" << jid << "of the account" << getName() << ", skipping";
return;
}
cnt->setEncryption(value);
}
void Core::Account::discoverInfo(const QString& address, const QString& node) { void Core::Account::discoverInfo(const QString& address, const QString& node) {
if (state == Shared::ConnectionState::connected) { if (state == Shared::ConnectionState::connected) {
dm->requestInfo(address, node); dm->requestInfo(address, node);

View File

@ -132,6 +132,7 @@ public:
void removeContactFromGroupRequest(const QString& jid, const QString& groupName); void removeContactFromGroupRequest(const QString& jid, const QString& groupName);
void renameContactRequest(const QString& jid, const QString& newName); void renameContactRequest(const QString& jid, const QString& newName);
void requestChangeMessage(const QString& jid, const QString& messageId, const QMap<QString, QVariant>& data); void requestChangeMessage(const QString& jid, const QString& messageId, const QMap<QString, QVariant>& data);
void setContactEncryption(const QString& jid, Shared::EncryptionProtocol value);
void setRoomJoined(const QString& jid, bool joined); void setRoomJoined(const QString& jid, bool joined);
void setRoomAutoJoin(const QString& jid, bool joined); void setRoomAutoJoin(const QString& jid, bool joined);

View File

@ -2,12 +2,14 @@ set(SOURCE_FILES
networkaccess.cpp networkaccess.cpp
clientcache.cpp clientcache.cpp
urlstorage.cpp urlstorage.cpp
archive.cpp
) )
set(HEADER_FILES set(HEADER_FILES
networkaccess.h networkaccess.h
clientcache.h clientcache.h
urlstorage.h urlstorage.h
archive.h
) )
target_sources(squawk PRIVATE target_sources(squawk PRIVATE

View File

@ -17,12 +17,11 @@
*/ */
#include "archive.h" #include "archive.h"
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <QStandardPaths>
#include <QDebug> #include <QDebug>
#include <QDataStream>
#include <QDir>
Core::Archive::Archive(const QString& account, const QString& p_jid, QObject* parent): Core::Archive::Archive(const QString& account, const QString& p_jid, QObject* parent):
QObject(parent), QObject(parent),
@ -262,23 +261,23 @@ void Core::Archive::setFromTheBeginning(bool is) {
stats->forceRecord("fromTheBeginning", is); stats->forceRecord("fromTheBeginning", is);
} }
bool Core::Archive::isEncryptionEnabled() const { Shared::EncryptionProtocol Core::Archive::encryption() const {
try { try {
return stats->getRecord("isEncryptionEnabled").toBool(); return stats->getRecord("encryption").value<Shared::EncryptionProtocol>();
} catch (const LMDBAL::NotFound& e) { } catch (const LMDBAL::NotFound& e) {
return false; return Shared::EncryptionProtocol::none;
} }
} }
bool Core::Archive::setEncryptionEnabled(bool is) { bool Core::Archive::setEncryption(Shared::EncryptionProtocol is) {
LMDBAL::WriteTransaction txn = db.beginTransaction(); LMDBAL::WriteTransaction txn = db.beginTransaction();
bool current = false; Shared::EncryptionProtocol current = Shared::EncryptionProtocol::none;
try { try {
current = stats->getRecord("isEncryptionEnabled", txn).toBool(); current = stats->getRecord("encryption", txn).value<Shared::EncryptionProtocol>();
} catch (const LMDBAL::NotFound& e) {} } catch (const LMDBAL::NotFound& e) {}
if (is != current) { if (is != current) {
stats->forceRecord("isEncryptionEnabled", is, txn); stats->forceRecord("encryption", static_cast<uint8_t>(is), txn);
txn.commit(); txn.commit();
return true; return true;
} }

View File

@ -23,7 +23,9 @@
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QMimeDatabase> #include <QMimeDatabase>
#include <QMimeType> #include <QMimeType>
#include <QDataStream>
#include "shared/enums.h"
#include "shared/message.h" #include "shared/message.h"
#include "shared/exception.h" #include "shared/exception.h"
#include <lmdb.h> #include <lmdb.h>
@ -60,8 +62,8 @@ public:
std::list<Shared::Message> getBefore(unsigned int count, const QString& id); std::list<Shared::Message> getBefore(unsigned int count, const QString& id);
bool isFromTheBeginning() const; bool isFromTheBeginning() const;
void setFromTheBeginning(bool is); void setFromTheBeginning(bool is);
bool isEncryptionEnabled() const; Shared::EncryptionProtocol encryption() const;
bool setEncryptionEnabled(bool is); //returns true if changed, false otherwise bool setEncryption(Shared::EncryptionProtocol value); //returns true if changed, false otherwise
bool setAvatar(const QByteArray& data, AvatarInfo& info, bool generated = false, const QString& resource = ""); bool setAvatar(const QByteArray& data, AvatarInfo& info, bool generated = false, const QString& resource = "");
AvatarInfo getAvatarInfo(const QString& resource = "") const; AvatarInfo getAvatarInfo(const QString& resource = "") const;
bool readAvatarInfo(AvatarInfo& target, const QString& resource = "") const; bool readAvatarInfo(AvatarInfo& target, const QString& resource = "") const;

View File

@ -225,7 +225,7 @@ void Core::RosterHandler::onContactGroupAdded(const QString& group) {
#if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 5, 0) #if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 5, 0)
{"trust", QVariant::fromValue(acc->th->getSummary(contact->jid))}, {"trust", QVariant::fromValue(acc->th->getSummary(contact->jid))},
#endif #endif
{"encryption", contact->isEncryptionEnabled()} {"encryption", QVariant::fromValue(contact->encryption())}
}); });
addToGroup(contact->jid, group); addToGroup(contact->jid, group);
emit acc->addContact(contact->jid, group, cData); emit acc->addContact(contact->jid, group, cData);
@ -246,9 +246,9 @@ void Core::RosterHandler::onContactNameChanged(const QString& cname) {
emit acc->changeContact(contact->jid, {{"name", cname}}); emit acc->changeContact(contact->jid, {{"name", cname}});
} }
void Core::RosterHandler::onContactEncryptionChanged(bool value) { void Core::RosterHandler::onContactEncryptionChanged(Shared::EncryptionProtocol value) {
RosterItem* contact = static_cast<RosterItem*>(sender()); RosterItem* contact = static_cast<RosterItem*>(sender());
emit acc->changeContact(contact->jid, {{"encryption", value}}); emit acc->changeContact(contact->jid, {{"encryption", QVariant::fromValue(value)}});
} }
void Core::RosterHandler::onContactSubscriptionStateChanged(Shared::SubscriptionState cstate) { void Core::RosterHandler::onContactSubscriptionStateChanged(Shared::SubscriptionState cstate) {
@ -328,7 +328,7 @@ Core::Contact * Core::RosterHandler::addOutOfRosterContact(const QString& jid) {
cnt->setSubscriptionState(Shared::SubscriptionState::unknown); cnt->setSubscriptionState(Shared::SubscriptionState::unknown);
emit acc->addContact(lcJid, "", QMap<QString, QVariant>({ emit acc->addContact(lcJid, "", QMap<QString, QVariant>({
{"state", QVariant::fromValue(Shared::SubscriptionState::unknown)}, {"state", QVariant::fromValue(Shared::SubscriptionState::unknown)},
{"encryption", false} {"encryption", QVariant::fromValue(Shared::EncryptionProtocol::none)}
})); }));
handleNewContact(cnt); handleNewContact(cnt);
return cnt; return cnt;
@ -361,9 +361,9 @@ void Core::RosterHandler::onRosterItemRemoved(const QString& bareJid) {
Contact* contact = itr->second; Contact* contact = itr->second;
contacts.erase(itr); contacts.erase(itr);
QSet<QString> cGroups = contact->getGroups(); QSet<QString> cGroups = contact->getGroups();
for (QSet<QString>::const_iterator itr = cGroups.begin(), end = cGroups.end(); itr != end; ++itr) { for (const QString& group : cGroups)
removeFromGroup(lcJid, *itr); removeFromGroup(lcJid, group);
}
emit acc->removeContact(lcJid); emit acc->removeContact(lcJid);
contact->deleteLater(); contact->deleteLater();

View File

@ -95,7 +95,7 @@ private slots:
void onContactNameChanged(const QString& name); void onContactNameChanged(const QString& name);
void onContactSubscriptionStateChanged(Shared::SubscriptionState state); void onContactSubscriptionStateChanged(Shared::SubscriptionState state);
void onContactAvatarChanged(Shared::Avatar, const QString& path); void onContactAvatarChanged(Shared::Avatar, const QString& path);
void onContactEncryptionChanged(bool value); void onContactEncryptionChanged(Shared::EncryptionProtocol value);
void onPepSupportedChanged(Shared::Support support); void onPepSupportedChanged(Shared::Support support);
private: private:

View File

@ -561,12 +561,12 @@ Shared::Message Core::RosterItem::getMessage(const QString& id) {
return archive->getElement(id); return archive->getElement(id);
} }
bool Core::RosterItem::isEncryptionEnabled() const { Shared::EncryptionProtocol Core::RosterItem::encryption() const {
return archive->isEncryptionEnabled(); return archive->encryption();
} }
void Core::RosterItem::enableEncryption(bool value) { void Core::RosterItem::setEncryption(Shared::EncryptionProtocol value) {
bool changed = archive->setEncryptionEnabled(value); bool changed = archive->setEncryption(value);
if (changed) if (changed)
emit encryptionChanged(value); emit encryptionChanged(value);
} }
@ -574,7 +574,7 @@ void Core::RosterItem::enableEncryption(bool value) {
QMap<QString, QVariant> Core::RosterItem::getInfo() const { QMap<QString, QVariant> Core::RosterItem::getInfo() const {
QMap<QString, QVariant> result({ QMap<QString, QVariant> result({
{"name", name}, {"name", name},
{"encryption", isEncryptionEnabled()}, {"encryption", QVariant::fromValue(encryption())},
}); });
Archive::AvatarInfo info; Archive::AvatarInfo info;
bool hasAvatar = readAvatarInfo(info); bool hasAvatar = readAvatarInfo(info);

View File

@ -34,7 +34,7 @@
#include "shared/enums.h" #include "shared/enums.h"
#include "shared/message.h" #include "shared/message.h"
#include "shared/vcard.h" #include "shared/vcard.h"
#include "storage/archive.h" #include "components/archive.h"
#include "adapterfunctions.h" #include "adapterfunctions.h"
namespace Core { namespace Core {
@ -62,8 +62,8 @@ public:
void setName(const QString& n); void setName(const QString& n);
QString getServer() const; QString getServer() const;
bool isMuc() const; bool isMuc() const;
bool isEncryptionEnabled() const; Shared::EncryptionProtocol encryption() const;
void enableEncryption(bool value = true); void setEncryption(Shared::EncryptionProtocol value);
void addMessageToArchive(const Shared::Message& msg); void addMessageToArchive(const Shared::Message& msg);
void correctMessageInArchive(const QString& originalId, const Shared::Message& msg); void correctMessageInArchive(const QString& originalId, const Shared::Message& msg);
@ -91,7 +91,7 @@ signals:
void needHistory(const QString& before, const QString& after, const QDateTime& afterTime = QDateTime()) const; void needHistory(const QString& before, const QString& after, const QDateTime& afterTime = QDateTime()) const;
void avatarChanged(Shared::Avatar, const QString& path) const; void avatarChanged(Shared::Avatar, const QString& path) const;
void requestVCard(const QString& jid) const; void requestVCard(const QString& jid) const;
void encryptionChanged(bool value) const; void encryptionChanged(Shared::EncryptionProtocol value) const;
public: public:
const QString jid; const QString jid;

View File

@ -590,6 +590,15 @@ void Core::Squawk::setRoomAutoJoin(const QString& account, const QString& jid, b
itr->second->setRoomAutoJoin(jid, joined); itr->second->setRoomAutoJoin(jid, joined);
} }
void Core::Squawk::setContactEncryption(const QString& account, const QString& jid, Shared::EncryptionProtocol value) {
AccountsMap::const_iterator itr = amap.find(account);
if (itr == amap.end()) {
qDebug() << "An attempt to set encryption to the contact" << jid << "of non existing account" << account << ", skipping";
return;
}
itr->second->setContactEncryption(jid, value);
}
void Core::Squawk::onAccountAddRoomPresence(const QString& jid, const QString& nick, const QMap<QString, QVariant>& data) { void Core::Squawk::onAccountAddRoomPresence(const QString& jid, const QString& nick, const QMap<QString, QVariant>& data) {
Account* acc = static_cast<Account*>(sender()); Account* acc = static_cast<Account*>(sender());
emit addRoomParticipant(acc->getName(), jid, nick, data); emit addRoomParticipant(acc->getName(), jid, nick, data);

View File

@ -116,6 +116,7 @@ public slots:
void removeContactRequest(const QString& account, const QString& jid); void removeContactRequest(const QString& account, const QString& jid);
void renameContactRequest(const QString& account, const QString& jid, const QString& newName); void renameContactRequest(const QString& account, const QString& jid, const QString& newName);
void addContactRequest(const QString& account, const QString& jid, const QString& name, const QSet<QString>& groups); void addContactRequest(const QString& account, const QString& jid, const QString& name, const QSet<QString>& groups);
void setContactEncryption(const QString& account, const QString& jid, Shared::EncryptionProtocol value);
void setRoomJoined(const QString& account, const QString& jid, bool joined); void setRoomJoined(const QString& account, const QString& jid, bool joined);
void setRoomAutoJoin(const QString& account, const QString& jid, bool joined); void setRoomAutoJoin(const QString& account, const QString& jid, bool joined);

View File

@ -1,4 +0,0 @@
target_sources(squawk PRIVATE
archive.cpp
archive.h
)

View File

@ -50,6 +50,7 @@ Application::Application(Core::Squawk* p_core):
connect(this, &Application::replaceMessage, core, &Core::Squawk::replaceMessage); connect(this, &Application::replaceMessage, core, &Core::Squawk::replaceMessage);
connect(this, &Application::sendMessage, core, &Core::Squawk::sendMessage); connect(this, &Application::sendMessage, core, &Core::Squawk::sendMessage);
connect(this, &Application::resendMessage, core, &Core::Squawk::resendMessage); connect(this, &Application::resendMessage, core, &Core::Squawk::resendMessage);
connect(this, &Application::setEncryption, core, &Core::Squawk::setContactEncryption);
connect(&roster, &Models::Roster::requestArchive, connect(&roster, &Models::Roster::requestArchive,
std::bind(&Core::Squawk::requestArchive, core, std::placeholders::_1, std::placeholders::_2, 20, std::placeholders::_3)); std::bind(&Core::Squawk::requestArchive, core, std::placeholders::_1, std::placeholders::_2, 20, std::placeholders::_3));
@ -526,6 +527,7 @@ void Application::subscribeConversation(Conversation* conv) {
connect(conv, &Conversation::sendMessage, this, &Application::onConversationMessage); connect(conv, &Conversation::sendMessage, this, &Application::onConversationMessage);
connect(conv, &Conversation::replaceMessage, this, &Application::onConversationReplaceMessage); connect(conv, &Conversation::replaceMessage, this, &Application::onConversationReplaceMessage);
connect(conv, &Conversation::resendMessage, this, &Application::onConversationResend); connect(conv, &Conversation::resendMessage, this, &Application::onConversationResend);
connect(conv, &Conversation::setEncryption, this, &Application::onConversationSetEncryption);
connect(conv, &Conversation::notifyableMessage, this, &Application::notify); connect(conv, &Conversation::notifyableMessage, this, &Application::notify);
} }
@ -586,6 +588,14 @@ void Application::onConversationReplaceMessage(const QString& originalId, const
emit replaceMessage(acc, originalId, msg); emit replaceMessage(acc, originalId, msg);
} }
void Application::onConversationSetEncryption(Shared::EncryptionProtocol value) {
Conversation* conv = static_cast<Conversation*>(sender());
QString acc = conv->getAccount();
QString jid = conv->getJid();
emit setEncryption(acc, jid, value);
}
void Application::onConversationResend(const QString& id) { void Application::onConversationResend(const QString& id) {
Conversation* conv = static_cast<Conversation*>(sender()); Conversation* conv = static_cast<Conversation*>(sender());
QString acc = conv->getAccount(); QString acc = conv->getAccount();

View File

@ -60,6 +60,7 @@ signals:
void setRoomAutoJoin(const QString& account, const QString& jid, bool joined); void setRoomAutoJoin(const QString& account, const QString& jid, bool joined);
void subscribeContact(const QString& account, const QString& jid, const QString& reason); void subscribeContact(const QString& account, const QString& jid, const QString& reason);
void unsubscribeContact(const QString& account, const QString& jid, const QString& reason); void unsubscribeContact(const QString& account, const QString& jid, const QString& reason);
void setEncryption(const QString& account, const QString& jid, Shared::EncryptionProtocol value);
void quitting(); void quitting();
void readyToQuit(); void readyToQuit();
@ -101,6 +102,7 @@ private slots:
void onItemExpanded(const QModelIndex& index); void onItemExpanded(const QModelIndex& index);
void onItemCollapsed(const QModelIndex& index); void onItemCollapsed(const QModelIndex& index);
void onAddedElement(const std::list<QString>& path); void onAddedElement(const std::list<QString>& path);
void onConversationSetEncryption(Shared::EncryptionProtocol value);
private: private:
void createMainWindow(); void createMainWindow();

View File

@ -36,6 +36,10 @@ Models::Contact::Contact(const Account* acc, const QString& p_jid ,const QMap<QS
itr = data.find("trust"); itr = data.find("trust");
if (itr != data.end()) if (itr != data.end())
setTrust(itr.value().value<Shared::TrustSummary>()); setTrust(itr.value().value<Shared::TrustSummary>());
itr = data.find("encryption");
if (itr != data.end())
setEncryption(itr.value().value<Shared::EncryptionProtocol>());
} }
Models::Contact::~Contact() {} Models::Contact::~Contact() {}
@ -71,7 +75,7 @@ void Models::Contact::setStatus(const QString& p_state) {
} }
int Models::Contact::columnCount() const { int Models::Contact::columnCount() const {
return 9; return 10;
} }
QVariant Models::Contact::data(int column) const { QVariant Models::Contact::data(int column) const {
@ -94,6 +98,8 @@ QVariant Models::Contact::data(int column) const {
return getAvatarPath(); return getAvatarPath();
case 8: case 8:
return QVariant::fromValue(getTrust()); return QVariant::fromValue(getTrust());
case 9:
return QVariant::fromValue(getEncryption());
default: default:
return QVariant(); return QVariant();
} }
@ -115,6 +121,8 @@ void Models::Contact::update(const QString& field, const QVariant& value) {
setState(value.toUInt()); setState(value.toUInt());
} else if (field == "trust") { } else if (field == "trust") {
setTrust(value.value<Shared::TrustSummary>()); setTrust(value.value<Shared::TrustSummary>());
} else if (field == "encryption") {
setEncryption(value.value<Shared::EncryptionProtocol>());
} else { } else {
Element::update(field, value); Element::update(field, value);
} }
@ -254,3 +262,18 @@ bool Models::Contact::hasKeys(Shared::EncryptionProtocol protocol) const {
return trust.hasKeys(protocol); return trust.hasKeys(protocol);
} }
void Models::Contact::setEncryption(Shared::EncryptionProtocol p_enc) {
if (encryption != p_enc) {
encryption = p_enc;
changed(9);
}
}
void Models::Contact::setEncryption(unsigned int p_enc) {
setEncryption(Shared::Global::fromInt<Shared::EncryptionProtocol>(p_enc));
}
Shared::EncryptionProtocol Models::Contact::getEncryption() const {
return encryption;
}

View File

@ -43,6 +43,7 @@ public:
Shared::Availability getAvailability() const; Shared::Availability getAvailability() const;
Shared::SubscriptionState getState() const; Shared::SubscriptionState getState() const;
Shared::EncryptionProtocol getEncryption() const;
QIcon getStatusIcon(bool big = false) const; QIcon getStatusIcon(bool big = false) const;
@ -78,6 +79,8 @@ protected:
void setState(unsigned int p_state); void setState(unsigned int p_state);
void setStatus(const QString& p_state); void setStatus(const QString& p_state);
void setTrust(const Shared::TrustSummary& p_trust); void setTrust(const Shared::TrustSummary& p_trust);
void setEncryption(Shared::EncryptionProtocol p_enc);
void setEncryption(unsigned int p_enc);
private: private:
Shared::Availability availability; Shared::Availability availability;

View File

@ -37,11 +37,11 @@ Squawk::Squawk(Models::Roster& p_rosterModel, QWidget *parent) :
m_ui->setupUi(this); m_ui->setupUi(this);
m_ui->roster->setModel(&rosterModel); m_ui->roster->setModel(&rosterModel);
m_ui->roster->setContextMenuPolicy(Qt::CustomContextMenu); m_ui->roster->setContextMenuPolicy(Qt::CustomContextMenu);
if (QApplication::style()->styleHint(QStyle::SH_ScrollBar_Transient) == 1) { if (QApplication::style()->styleHint(QStyle::SH_ScrollBar_Transient) == 1)
m_ui->roster->setColumnWidth(1, 52); m_ui->roster->setColumnWidth(1, 52);
} else { else
m_ui->roster->setColumnWidth(1, 26); m_ui->roster->setColumnWidth(1, 26);
}
m_ui->roster->setIconSize(QSize(20, 20)); m_ui->roster->setIconSize(QSize(20, 20));
m_ui->roster->header()->setStretchLastSection(false); m_ui->roster->header()->setStretchLastSection(false);
m_ui->roster->header()->setSectionResizeMode(0, QHeaderView::Stretch); m_ui->roster->header()->setSectionResizeMode(0, QHeaderView::Stretch);
@ -69,24 +69,24 @@ Squawk::Squawk(Models::Roster& p_rosterModel, QWidget *parent) :
connect(m_ui->actionAboutSquawk, &QAction::triggered, this, &Squawk::onAboutSquawkCalled); connect(m_ui->actionAboutSquawk, &QAction::triggered, this, &Squawk::onAboutSquawkCalled);
//m_ui->mainToolBar->addWidget(m_ui->comboBox); //m_ui->mainToolBar->addWidget(m_ui->comboBox);
if (testAttribute(Qt::WA_TranslucentBackground)) { if (testAttribute(Qt::WA_TranslucentBackground))
m_ui->roster->viewport()->setAutoFillBackground(false); m_ui->roster->viewport()->setAutoFillBackground(false);
}
QSettings settings; QSettings settings;
settings.beginGroup("ui"); settings.beginGroup("ui");
settings.beginGroup("window"); settings.beginGroup("window");
if (settings.contains("geometry")) { if (settings.contains("geometry"))
restoreGeometry(settings.value("geometry").toByteArray()); restoreGeometry(settings.value("geometry").toByteArray());
}
if (settings.contains("state")) { if (settings.contains("state"))
restoreState(settings.value("state").toByteArray()); restoreState(settings.value("state").toByteArray());
}
settings.endGroup(); settings.endGroup();
if (settings.contains("splitter")) { if (settings.contains("splitter"))
m_ui->splitter->restoreState(settings.value("splitter").toByteArray()); m_ui->splitter->restoreState(settings.value("splitter").toByteArray());
}
settings.endGroup(); settings.endGroup();
onAccountsChanged(); onAccountsChanged();
@ -181,8 +181,10 @@ void Squawk::onJoinConferenceAccepted() {
void Squawk::closeEvent(QCloseEvent* event) { void Squawk::closeEvent(QCloseEvent* event) {
if (accounts != nullptr) if (accounts != nullptr)
accounts->close(); accounts->close();
if (preferences != nullptr) if (preferences != nullptr)
preferences->close(); preferences->close();
if (about != nullptr) if (about != nullptr)
about->close(); about->close();
@ -221,9 +223,9 @@ void Squawk::stateChanged(Shared::Availability state) {
void Squawk::onRosterItemDoubleClicked(const QModelIndex& item) { void Squawk::onRosterItemDoubleClicked(const QModelIndex& item) {
if (item.isValid()) { if (item.isValid()) {
Models::Item* node = static_cast<Models::Item*>(item.internalPointer()); Models::Item* node = static_cast<Models::Item*>(item.internalPointer());
if (node->type == Models::Item::reference) { if (node->type == Models::Item::reference)
node = static_cast<Models::Reference*>(node)->dereference(); node = static_cast<Models::Reference*>(node)->dereference();
}
Models::Contact* contact = nullptr; Models::Contact* contact = nullptr;
Models::Room* room = nullptr; Models::Room* room = nullptr;
switch (node->type) { switch (node->type) {
@ -258,9 +260,9 @@ void Squawk::onRosterContextMenu(const QPoint& point) {
QModelIndex index = m_ui->roster->indexAt(point); QModelIndex index = m_ui->roster->indexAt(point);
if (index.isValid()) { if (index.isValid()) {
Models::Item* item = static_cast<Models::Item*>(index.internalPointer()); Models::Item* item = static_cast<Models::Item*>(index.internalPointer());
if (item->type == Models::Item::reference) { if (item->type == Models::Item::reference)
item = static_cast<Models::Reference*>(item)->dereference(); item = static_cast<Models::Reference*>(item)->dereference();
}
contextMenu->clear(); contextMenu->clear();
bool hasMenu = false; bool hasMenu = false;
bool active = item->getAccountConnectionState() == Shared::ConnectionState::connected; bool active = item->getAccountConnectionState() == Shared::ConnectionState::connected;
@ -320,9 +322,9 @@ void Squawk::onRosterContextMenu(const QPoint& point) {
QInputDialog* dialog = new QInputDialog(this); QInputDialog* dialog = new QInputDialog(this);
connect(dialog, &QDialog::accepted, [this, dialog, cntName, id]() { connect(dialog, &QDialog::accepted, [this, dialog, cntName, id]() {
QString newName = dialog->textValue(); QString newName = dialog->textValue();
if (newName != cntName) { if (newName != cntName)
emit renameContactRequest(id.account, id.name, newName); emit renameContactRequest(id.account, id.name, newName);
}
dialog->deleteLater(); dialog->deleteLater();
}); });
connect(dialog, &QDialog::rejected, dialog, &QObject::deleteLater); connect(dialog, &QDialog::rejected, dialog, &QObject::deleteLater);
@ -342,11 +344,10 @@ void Squawk::onRosterContextMenu(const QPoint& point) {
gr->setChecked(rosterModel.groupHasContact(id.account, groupName, id.name)); gr->setChecked(rosterModel.groupHasContact(id.account, groupName, id.name));
gr->setEnabled(active); gr->setEnabled(active);
connect(gr, &QAction::toggled, [this, groupName, id](bool checked) { connect(gr, &QAction::toggled, [this, groupName, id](bool checked) {
if (checked) { if (checked)
emit addContactToGroupRequest(id.account, id.name, groupName); emit addContactToGroupRequest(id.account, id.name, groupName);
} else { else
emit removeContactFromGroupRequest(id.account, id.name, groupName); emit removeContactFromGroupRequest(id.account, id.name, groupName);
}
}); });
} }
QAction* newGroup = groupsMenu->addAction(Shared::icon("group-new"), tr("New group")); QAction* newGroup = groupsMenu->addAction(Shared::icon("group-new"), tr("New group"));
@ -405,11 +406,10 @@ void Squawk::onRosterContextMenu(const QPoint& point) {
default: default:
break; break;
} }
if (hasMenu) { if (hasMenu)
contextMenu->popup(m_ui->roster->viewport()->mapToGlobal(point)); contextMenu->popup(m_ui->roster->viewport()->mapToGlobal(point));
} }
} }
}
void Squawk::responseInfo(const Shared::Info& info) { void Squawk::responseInfo(const Shared::Info& info) {
std::map<QString, UI::Info*>::const_iterator itr = infoWidgets.find(info.getAddressRef()); std::map<QString, UI::Info*>::const_iterator itr = infoWidgets.find(info.getAddressRef());
@ -515,9 +515,9 @@ void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIn
} }
if (hasContext && QGuiApplication::mouseButtons() & Qt::RightButton) { if (hasContext && QGuiApplication::mouseButtons() & Qt::RightButton) {
if (id != nullptr) { if (id != nullptr)
delete id; delete id;
}
needToRestore = true; needToRestore = true;
restoreSelection = previous; restoreSelection = previous;
return; return;
@ -538,20 +538,19 @@ void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIn
} }
Models::Account* acc = rosterModel.getAccount(id->account); Models::Account* acc = rosterModel.getAccount(id->account);
if (contact != nullptr) { if (contact != nullptr)
currentConversation = new Chat(acc, contact); currentConversation = new Chat(acc, contact);
} else if (room != nullptr) { else if (room != nullptr)
currentConversation = new Room(acc, room); currentConversation = new Room(acc, room);
}
if (!testAttribute(Qt::WA_TranslucentBackground)) { if (!testAttribute(Qt::WA_TranslucentBackground))
currentConversation->setFeedFrames(true, false, true, true); currentConversation->setFeedFrames(true, false, true, true);
}
emit openedConversation(); emit openedConversation();
if (res.size() > 0) { if (res.size() > 0)
currentConversation->setPalResource(res); currentConversation->setPalResource(res);
}
m_ui->splitter->insertWidget(1, currentConversation); m_ui->splitter->insertWidget(1, currentConversation);

View File

@ -23,6 +23,7 @@
#include <QScopedPointer> #include <QScopedPointer>
#include <QCloseEvent> #include <QCloseEvent>
#include <QSettings> #include <QSettings>
#include <QString>
#include <QInputDialog> #include <QInputDialog>
#include <deque> #include <deque>
@ -50,8 +51,7 @@ class Squawk;
class Application; class Application;
class Squawk : public QMainWindow class Squawk : public QMainWindow {
{
Q_OBJECT Q_OBJECT
friend class Application; friend class Application;
public: public:

View File

@ -46,13 +46,11 @@
#include "ui/widgets/messageline/feedview.h" #include "ui/widgets/messageline/feedview.h"
#include "ui/widgets/messageline/messagedelegate.h" #include "ui/widgets/messageline/messagedelegate.h"
namespace Ui namespace Ui {
{
class Conversation; class Conversation;
} }
class KeyEnterReceiver : public QObject class KeyEnterReceiver : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
KeyEnterReceiver(QObject* parent = 0); KeyEnterReceiver(QObject* parent = 0);
@ -65,8 +63,7 @@ signals:
void imagePasted(); void imagePasted();
}; };
class Conversation : public QWidget class Conversation : public QWidget {
{
Q_OBJECT Q_OBJECT
public: public:
Conversation(bool muc, Models::Account* acc, Models::Element* el, const QString pJid, const QString pRes, QWidget* parent = 0); Conversation(bool muc, Models::Account* acc, Models::Element* el, const QString pJid, const QString pRes, QWidget* parent = 0);
@ -91,6 +88,7 @@ signals:
void requestLocalFile(const QString& messageId, const QString& url); void requestLocalFile(const QString& messageId, const QString& url);
void downloadFile(const QString& messageId, const QString& url); void downloadFile(const QString& messageId, const QString& url);
void notifyableMessage(const QString& account, const Shared::Message& msg); void notifyableMessage(const QString& account, const Shared::Message& msg);
void setEncryption(Shared::EncryptionProtocol value);
protected: protected:
virtual void setName(const QString& name); virtual void setName(const QString& name);