From e4a2728ef8d5671bc2b7091010804e19e29ebbc6 Mon Sep 17 00:00:00 2001 From: blue Date: Mon, 20 Feb 2023 21:12:32 +0300 Subject: [PATCH] hopefully end of refactoring of vcard to Info widget --- core/account.cpp | 112 ++-- core/account.h | 7 +- core/conference.cpp | 2 +- core/handlers/rosterhandler.cpp | 4 +- core/handlers/vcardhandler.cpp | 53 +- core/squawk.cpp | 14 +- core/squawk.h | 7 +- main/application.cpp | 8 +- ui/squawk.cpp | 170 +++--- ui/squawk.h | 17 +- ui/widgets/CMakeLists.txt | 1 - ui/widgets/info/contactcontacts.cpp | 8 + ui/widgets/info/description.cpp | 17 + ui/widgets/info/description.h | 5 + ui/widgets/info/info.cpp | 58 +- ui/widgets/info/info.h | 14 +- ui/widgets/vcard/CMakeLists.txt | 5 - ui/widgets/vcard/vcard.cpp | 474 --------------- ui/widgets/vcard/vcard.h | 117 ---- ui/widgets/vcard/vcard.ui | 892 ---------------------------- 20 files changed, 268 insertions(+), 1717 deletions(-) delete mode 100644 ui/widgets/vcard/CMakeLists.txt delete mode 100644 ui/widgets/vcard/vcard.cpp delete mode 100644 ui/widgets/vcard/vcard.h delete mode 100644 ui/widgets/vcard/vcard.ui diff --git a/core/account.cpp b/core/account.cpp index bb3ebea..98862a4 100644 --- a/core/account.cpp +++ b/core/account.cpp @@ -138,8 +138,7 @@ Account::Account(const QString& p_login, const QString& p_server, const QString& } } -Account::~Account() -{ +Account::~Account() { if (reconnectScheduled) { reconnectScheduled = false; reconnectTimer->stop(); @@ -166,13 +165,10 @@ Account::~Account() delete cm; } -Shared::ConnectionState Core::Account::getState() const -{ - return state; -} +Shared::ConnectionState Core::Account::getState() const { + return state;} -void Core::Account::connect() -{ +void Core::Account::connect() { if (reconnectScheduled) { reconnectScheduled = false; reconnectTimer->stop(); @@ -194,16 +190,14 @@ void Core::Account::connect() } } -void Core::Account::onReconnectTimer() -{ +void Core::Account::onReconnectTimer() { if (reconnectScheduled) { reconnectScheduled = false; connect(); } } -void Core::Account::disconnect() -{ +void Core::Account::disconnect() { if (reconnectScheduled) { reconnectScheduled = false; reconnectTimer->stop(); @@ -219,8 +213,7 @@ void Core::Account::disconnect() } } -void Core::Account::onClientStateChange(QXmppClient::State st) -{ +void Core::Account::onClientStateChange(QXmppClient::State st) { switch (st) { case QXmppClient::ConnectedState: { if (state != Shared::ConnectionState::connected) { @@ -279,8 +272,7 @@ void Core::Account::onClientStateChange(QXmppClient::State st) } } -void Core::Account::reconnect() -{ +void Core::Account::reconnect() { if (!reconnectScheduled) { //TODO define behavior if It was connection or disconnecting if (state == Shared::ConnectionState::connected) { reconnectScheduled = true; @@ -292,8 +284,7 @@ void Core::Account::reconnect() } } -Shared::Availability Core::Account::getAvailability() const -{ +Shared::Availability Core::Account::getAvailability() const { if (state == Shared::ConnectionState::connected) { QXmppPresence::AvailableStatusType pres = presence.availableStatusType(); return static_cast(pres); //they are compatible; @@ -302,8 +293,7 @@ Shared::Availability Core::Account::getAvailability() const } } -void Core::Account::setAvailability(Shared::Availability avail) -{ +void Core::Account::setAvailability(Shared::Availability avail) { if (avail == Shared::Availability::offline) { disconnect(); //TODO not sure how to do here - changing state may cause connection or disconnection } else { @@ -323,23 +313,21 @@ void Core::Account::runDiscoveryService() { } -void Core::Account::onPresenceReceived(const QXmppPresence& p_presence) -{ +void Core::Account::onPresenceReceived(const QXmppPresence& p_presence) { QString id = p_presence.from(); QStringList comps = id.split("/"); QString jid = comps.front().toLower(); QString resource = comps.back(); if (jid == getBareJid()) { - if (resource == getResource()) { + if (resource == getResource()) emit availabilityChanged(static_cast(p_presence.availableStatusType())); - } + vh->handlePresenceOfMyAccountChange(p_presence); } else { RosterItem* item = rh->getRosterItem(jid); - if (item != 0) { + if (item != 0) item->handlePresence(p_presence); - } } switch (p_presence.type()) { @@ -382,8 +370,7 @@ void Core::Account::onPresenceReceived(const QXmppPresence& p_presence) } } -void Core::Account::onMamMessageReceived(const QString& queryId, const QXmppMessage& msg) -{ +void Core::Account::onMamMessageReceived(const QString& queryId, const QXmppMessage& msg) { if (msg.id().size() > 0 && (msg.body().size() > 0 || msg.outOfBandUrl().size() > 0)) { std::map::const_iterator itr = archiveQueries.find(queryId); if (itr != archiveQueries.end()) { @@ -395,17 +382,15 @@ void Core::Account::onMamMessageReceived(const QString& queryId, const QXmppMess sMsg.setState(Shared::Message::State::sent); QString oId = msg.replaceId(); - if (oId.size() > 0) { + if (oId.size() > 0) item->correctMessageInArchive(oId, sMsg); - } else { + else item->addMessageToArchive(sMsg); - } } } } -void Core::Account::requestArchive(const QString& jid, int count, const QString& before) -{ +void Core::Account::requestArchive(const QString& jid, int count, const QString& before) { qDebug() << "An archive request for " << jid << ", before " << before; RosterItem* contact = rh->getRosterItem(jid); @@ -423,8 +408,7 @@ void Core::Account::requestArchive(const QString& jid, int count, const QString& contact->requestHistory(count, before); } -void Core::Account::onContactNeedHistory(const QString& before, const QString& after, const QDateTime& at) -{ +void Core::Account::onContactNeedHistory(const QString& before, const QString& after, const QDateTime& at) { RosterItem* contact = static_cast(sender()); QString to; @@ -468,8 +452,7 @@ void Core::Account::onContactNeedHistory(const QString& before, const QString& a archiveQueries.insert(std::make_pair(q, contact->jid)); } -void Core::Account::onMamResultsReceived(const QString& queryId, const QXmppResultSetReply& resultSetReply, bool complete) -{ +void Core::Account::onMamResultsReceived(const QString& queryId, const QXmppResultSetReply& resultSetReply, bool complete) { std::map::const_iterator itr = archiveQueries.find(queryId); if (itr != archiveQueries.end()) { QString jid = itr->second; @@ -484,14 +467,12 @@ void Core::Account::onMamResultsReceived(const QString& queryId, const QXmppResu } } -void Core::Account::onMamLog(QXmppLogger::MessageType type, const QString& msg) -{ +void Core::Account::onMamLog(QXmppLogger::MessageType type, const QString& msg) { qDebug() << "MAM MESSAGE LOG::"; qDebug() << msg; } -void Core::Account::onClientError(QXmppClient::Error err) -{ +void Core::Account::onClientError(QXmppClient::Error err) { qDebug() << "Error"; QString errorText; QString errorType; @@ -601,22 +582,18 @@ void Core::Account::onClientError(QXmppClient::Error err) emit error(errorText); } -void Core::Account::subscribeToContact(const QString& jid, const QString& reason) -{ - if (state == Shared::ConnectionState::connected) { +void Core::Account::subscribeToContact(const QString& jid, const QString& reason) { + if (state == Shared::ConnectionState::connected) rm->subscribe(jid, reason); - } else { + else qDebug() << "An attempt to subscribe account " << name << " to contact " << jid << " but the account is not in the connected state, skipping"; - } } -void Core::Account::unsubscribeFromContact(const QString& jid, const QString& reason) -{ - if (state == Shared::ConnectionState::connected) { +void Core::Account::unsubscribeFromContact(const QString& jid, const QString& reason) { + if (state == Shared::ConnectionState::connected) rm->unsubscribe(jid, reason); - } else { + else qDebug() << "An attempt to unsubscribe account " << name << " from contact " << jid << " but the account is not in the connected state, skipping"; - } } void Core::Account::removeContactRequest(const QString& jid) { @@ -625,8 +602,7 @@ void Core::Account::removeContactRequest(const QString& jid) { void Core::Account::addContactRequest(const QString& jid, const QString& name, const QSet& groups) { rh->addContactRequest(jid, name, groups);} -void Core::Account::setRoomAutoJoin(const QString& jid, bool joined) -{ +void Core::Account::setRoomAutoJoin(const QString& jid, bool joined) { Conference* conf = rh->getConference(jid); if (conf == 0) { qDebug() << "An attempt to set auto join to the non existing room" << jid << "of the account" << getName() << ", skipping"; @@ -636,8 +612,7 @@ void Core::Account::setRoomAutoJoin(const QString& jid, bool joined) conf->setAutoJoin(joined); } -void Core::Account::setRoomJoined(const QString& jid, bool joined) -{ +void Core::Account::setRoomJoined(const QString& jid, bool joined) { Conference* conf = rh->getConference(jid); if (conf == 0) { qDebug() << "An attempt to set joined to the non existing room" << jid << "of the account" << getName() << ", skipping"; @@ -657,16 +632,14 @@ void Core::Account::discoverInfo(const QString& address, const QString& node) { } } -void Core::Account::setPepSupport(Shared::Support support) -{ +void Core::Account::setPepSupport(Shared::Support support) { if (support != pepSupport) { pepSupport = support; emit pepSupportChanged(pepSupport); } } -void Core::Account::handleDisconnection() -{ +void Core::Account::handleDisconnection() { setPepSupport(Shared::Support::unknown); cm->setCarbonsEnabled(false); rh->handleOffline(); @@ -674,14 +647,13 @@ void Core::Account::handleDisconnection() archiveQueries.clear(); } -void Core::Account::onContactHistoryResponse(const std::list& list, bool last) -{ +void Core::Account::onContactHistoryResponse(const std::list& list, bool last) { RosterItem* contact = static_cast(sender()); qDebug() << "Collected history for contact " << contact->jid << list.size() << "elements"; - if (last) { + if (last) qDebug() << "The response contains the first accounted message"; - } + emit responseArchive(contact->jid, list, last); } @@ -754,11 +726,17 @@ void Core::Account::resendMessage(const QString& jid, const QString& id) { void Core::Account::replaceMessage(const QString& originalId, const Shared::Message& data) { mh->sendMessage(data, false, originalId);} -void Core::Account::requestVCard(const QString& jid) { - vh->requestVCard(jid);} +void Core::Account::requestInfo(const QString& jid) { + //TODO switch case of what kind of entity this info request is about + //right now it could be only about myself or some contact + vh->requestVCard(jid); +} -void Core::Account::uploadVCard(const Shared::VCard& card) { - vh->uploadVCard(card);} +void Core::Account::updateInfo(const Shared::Info& info) { + //TODO switch case of what kind of entity this info update is about + //right now it could be only about myself + vh->uploadVCard(info.vcard); +} QString Core::Account::getAvatarPath() const { return vh->getAvatarPath();} diff --git a/core/account.h b/core/account.h index 393b6e6..598a06e 100644 --- a/core/account.h +++ b/core/account.h @@ -46,6 +46,7 @@ #include #include +#include #include "contact.h" #include "conference.h" #include @@ -126,7 +127,7 @@ public: void setRoomAutoJoin(const QString& jid, bool joined); void removeRoomRequest(const QString& jid); void addRoomRequest(const QString& jid, const QString& nick, const QString& password, bool autoJoin); - void uploadVCard(const Shared::VCard& card); + void updateInfo(const Shared::Info& info); void resendMessage(const QString& jid, const QString& id); void replaceMessage(const QString& originalId, const Shared::Message& data); void invalidatePassword(); @@ -137,7 +138,7 @@ public slots: void connect(); void disconnect(); void reconnect(); - void requestVCard(const QString& jid); + void requestInfo(const QString& jid); signals: void changed(const QMap& data); @@ -161,7 +162,7 @@ signals: void addRoomParticipant(const QString& jid, const QString& nickName, const QMap& data); void changeRoomParticipant(const QString& jid, const QString& nickName, const QMap& data); void removeRoomParticipant(const QString& jid, const QString& nickName); - void receivedVCard(const QString& jid, const Shared::VCard& card); + void infoReady(const Shared::Info& info); void uploadFile(const QFileInfo& file, const QUrl& set, const QUrl& get, QMap headers); void uploadFileError(const QString& jid, const QString& messageId, const QString& error); void needPassword(); diff --git a/core/conference.cpp b/core/conference.cpp index 55280e2..a984f41 100644 --- a/core/conference.cpp +++ b/core/conference.cpp @@ -170,7 +170,7 @@ void Core::Conference::onRoomParticipantAdded(const QString& p_name) } else { cData.insert("avatarState", static_cast(Shared::Avatar::empty)); cData.insert("avatarPath", ""); - requestVCard(p_name); + emit requestVCard(p_name); } emit addParticipant(resource, cData); diff --git a/core/handlers/rosterhandler.cpp b/core/handlers/rosterhandler.cpp index 8c65c63..0027514 100644 --- a/core/handlers/rosterhandler.cpp +++ b/core/handlers/rosterhandler.cpp @@ -156,7 +156,7 @@ void Core::RosterHandler::careAboutAvatar(Core::RosterItem* item, QMaprequestVCard(item->jid); + acc->vh->requestVCard(item->jid); } } @@ -197,7 +197,7 @@ void Core::RosterHandler::handleNewRosterItem(Core::RosterItem* contact) connect(contact, &RosterItem::historyResponse, this->acc, &Account::onContactHistoryResponse); connect(contact, &RosterItem::nameChanged, this, &RosterHandler::onContactNameChanged); connect(contact, &RosterItem::avatarChanged, this, &RosterHandler::onContactAvatarChanged); - connect(contact, &RosterItem::requestVCard, this->acc, &Account::requestVCard); + connect(contact, &RosterItem::requestVCard, this->acc->vh, &VCardHandler::requestVCard); } void Core::RosterHandler::handleNewContact(Core::Contact* contact) diff --git a/core/handlers/vcardhandler.cpp b/core/handlers/vcardhandler.cpp index bde0e64..c9e7170 100644 --- a/core/handlers/vcardhandler.cpp +++ b/core/handlers/vcardhandler.cpp @@ -80,9 +80,7 @@ void Core::VCardHandler::initialize() { } } - -void Core::VCardHandler::onVCardReceived(const QXmppVCardIq& card) -{ +void Core::VCardHandler::onVCardReceived(const QXmppVCardIq& card) { QString id = card.from(); QStringList comps = id.split("/"); QString jid = comps.front().toLower(); @@ -102,13 +100,13 @@ void Core::VCardHandler::onVCardReceived(const QXmppVCardIq& card) return; } - Shared::VCard vCard = item->handleResponseVCard(card, resource); + Shared::Info info(jid, Shared::EntryType::contact); + info.vcard = item->handleResponseVCard(card, resource); - emit acc->receivedVCard(jid, vCard); + emit acc->infoReady(info); } -void Core::VCardHandler::onOwnVCardReceived(const QXmppVCardIq& card) -{ +void Core::VCardHandler::onOwnVCardReceived(const QXmppVCardIq& card) { QByteArray ava = card.photo(); bool avaChanged = false; QString path = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/" + acc->name + "/"; @@ -189,32 +187,30 @@ void Core::VCardHandler::onOwnVCardReceived(const QXmppVCardIq& card) ownVCardRequestInProgress = false; - Shared::VCard vCard; - initializeVCard(vCard, card); + Shared::Info info(acc->getBareJid(), Shared::EntryType::contact, true); + initializeVCard(info.vcard, card); if (avatarType.size() > 0) { - vCard.setAvatarType(Shared::Avatar::valid); - vCard.setAvatarPath(path + "avatar." + avatarType); + info.vcard.setAvatarType(Shared::Avatar::valid); + info.vcard.setAvatarPath(path + "avatar." + avatarType); } else { - vCard.setAvatarType(Shared::Avatar::empty); + info.vcard.setAvatarType(Shared::Avatar::empty); } - emit acc->receivedVCard(acc->getBareJid(), vCard); + emit acc->infoReady(info); } -void Core::VCardHandler::handleOffline() -{ +void Core::VCardHandler::handleOffline() { pendingVCardRequests.clear(); - Shared::VCard vCard; //just to show, that there is now more pending request for (const QString& jid : pendingVCardRequests) { - emit acc->receivedVCard(jid, vCard); //need to show it better in the future, like with an error + Shared::Info info(jid, Shared::EntryType::contact); + emit acc->infoReady(info); //need to show it better in the future, like with an error } pendingVCardRequests.clear(); ownVCardRequestInProgress = false; } -void Core::VCardHandler::requestVCard(const QString& jid) -{ +void Core::VCardHandler::requestVCard(const QString& jid) { if (pendingVCardRequests.find(jid) == pendingVCardRequests.end()) { qDebug() << "requesting vCard" << jid; if (jid == acc->getBareJid()) { @@ -229,8 +225,7 @@ void Core::VCardHandler::requestVCard(const QString& jid) } } -void Core::VCardHandler::handlePresenceOfMyAccountChange(const QXmppPresence& p_presence) -{ +void Core::VCardHandler::handlePresenceOfMyAccountChange(const QXmppPresence& p_presence) { if (!ownVCardRequestInProgress) { switch (p_presence.vCardUpdateType()) { case QXmppPresence::VCardUpdateNone: //this presence has nothing to do with photo @@ -253,8 +248,7 @@ void Core::VCardHandler::handlePresenceOfMyAccountChange(const QXmppPresence& p_ } } -void Core::VCardHandler::uploadVCard(const Shared::VCard& card) -{ +void Core::VCardHandler::uploadVCard(const Shared::VCard& card) { QXmppVCardIq iq; initializeQXmppVCard(iq, card); @@ -283,11 +277,10 @@ void Core::VCardHandler::uploadVCard(const Shared::VCard& card) } else { if (avatarType.size() > 0) { QFile oA(oldPath); - if (!oA.open(QFile::ReadOnly)) { + if (!oA.open(QFile::ReadOnly)) qDebug() << "Couldn't read old avatar of account" << acc->name << ", uploading empty avatar"; - } else { + else data = oA.readAll(); - } } } @@ -303,11 +296,9 @@ void Core::VCardHandler::uploadVCard(const Shared::VCard& card) onOwnVCardReceived(iq); } -QString Core::VCardHandler::getAvatarPath() const -{ - if (avatarType.size() == 0) { +QString Core::VCardHandler::getAvatarPath() const { + if (avatarType.size() == 0) return ""; - } else { + else return QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/" + acc->name + "/" + "avatar." + avatarType; - } } diff --git a/core/squawk.cpp b/core/squawk.cpp index 6600fcb..33f2bf5 100644 --- a/core/squawk.cpp +++ b/core/squawk.cpp @@ -180,7 +180,7 @@ void Core::Squawk::addAccount( connect(acc, &Account::changeRoomParticipant, this, &Squawk::onAccountChangeRoomPresence); connect(acc, &Account::removeRoomParticipant, this, &Squawk::onAccountRemoveRoomPresence); - connect(acc, &Account::receivedVCard, this, &Squawk::responseVCard); + connect(acc, &Account::infoReady, this, &Squawk::responseInfo); connect(acc, &Account::uploadFileError, this, &Squawk::onAccountUploadFileError); @@ -717,24 +717,24 @@ void Core::Squawk::renameContactRequest(const QString& account, const QString& j itr->second->renameContactRequest(jid, newName); } -void Core::Squawk::requestVCard(const QString& account, const QString& jid) +void Core::Squawk::requestInfo(const QString& account, const QString& jid) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { - qDebug() << "An attempt to request" << jid << "vcard of non existing account" << account << ", skipping"; + qDebug() << "An attempt to request info about" << jid << "of non existing account" << account << ", skipping"; return; } - itr->second->requestVCard(jid); + itr->second->requestInfo(jid); } -void Core::Squawk::uploadVCard(const QString& account, const Shared::VCard& card) +void Core::Squawk::updateInfo(const QString& account, const Shared::Info& info) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { - qDebug() << "An attempt to upload vcard to non existing account" << account << ", skipping"; + qDebug() << "An attempt to update info to non existing account" << account << ", skipping"; return; } - itr->second->uploadVCard(card); + itr->second->updateInfo(info); } void Core::Squawk::readSettings() diff --git a/core/squawk.h b/core/squawk.h index da4aa7e..eebe917 100644 --- a/core/squawk.h +++ b/core/squawk.h @@ -31,6 +31,7 @@ #include "shared/enums.h" #include "shared/message.h" #include "shared/global.h" +#include "shared/info.h" #include "shared/clientinfo.h" #include "external/simpleCrypt/simplecrypt.h" @@ -87,7 +88,7 @@ signals: void fileDownloadComplete(const std::list msgs, const QString& path); void fileUploadComplete(const std::list msgs, const QString& url, const QString& path); - void responseVCard(const QString& jid, const Shared::VCard& card); + void responseInfo(const Shared::Info& info); void changeMessage(const QString& account, const QString& jid, const QString& id, const QMap& data); void requestPassword(const QString& account, bool authernticationError); @@ -123,8 +124,8 @@ public slots: void fileDownloadRequest(const QString& url); - void requestVCard(const QString& account, const QString& jid); - void uploadVCard(const QString& account, const Shared::VCard& card); + void requestInfo(const QString& account, const QString& jid); + void updateInfo(const QString& account, const Shared::Info& info); void responsePassword(const QString& account, const QString& password); void onLocalPathInvalid(const QString& path); void changeDownloadsPath(const QString& path); diff --git a/main/application.cpp b/main/application.cpp index 3942e53..edf9fd7 100644 --- a/main/application.cpp +++ b/main/application.cpp @@ -188,11 +188,11 @@ void Application::createMainWindow() connect(squawk, &Squawk::addContactToGroupRequest, core, &Core::Squawk::addContactToGroupRequest); connect(squawk, &Squawk::removeContactFromGroupRequest, core, &Core::Squawk::removeContactFromGroupRequest); connect(squawk, &Squawk::renameContactRequest, core, &Core::Squawk::renameContactRequest); - connect(squawk, &Squawk::requestVCard, core, &Core::Squawk::requestVCard); - connect(squawk, &Squawk::uploadVCard, core, &Core::Squawk::uploadVCard); + connect(squawk, &Squawk::requestInfo, core, &Core::Squawk::requestInfo); + connect(squawk, &Squawk::updateInfo, core, &Core::Squawk::updateInfo); connect(squawk, &Squawk::changeDownloadsPath, core, &Core::Squawk::changeDownloadsPath); - connect(core, &Core::Squawk::responseVCard, squawk, &Squawk::responseVCard); + connect(core, &Core::Squawk::responseInfo, squawk, &Squawk::responseInfo); dialogueQueue.setParentWidnow(squawk); squawk->stateChanged(availability); @@ -217,7 +217,7 @@ void Application::onSquawkClosing() dialogueQueue.setParentWidnow(nullptr); if (!nowQuitting) { - disconnect(core, &Core::Squawk::responseVCard, squawk, &Squawk::responseVCard); + disconnect(core, &Core::Squawk::responseInfo, squawk, &Squawk::responseInfo); } destroyingSquawk = true; diff --git a/ui/squawk.cpp b/ui/squawk.cpp index c086e10..9702357 100644 --- a/ui/squawk.cpp +++ b/ui/squawk.cpp @@ -29,7 +29,7 @@ Squawk::Squawk(Models::Roster& p_rosterModel, QWidget *parent) : about(nullptr), rosterModel(p_rosterModel), contextMenu(new QMenu()), - vCards(), + infoWidgets(), currentConversation(nullptr), restoreSelection(), needToRestore(false) @@ -96,8 +96,7 @@ Squawk::~Squawk() { delete contextMenu; } -void Squawk::onAccounts() -{ +void Squawk::onAccounts() { if (accounts == nullptr) { accounts = new Accounts(rosterModel.accountsModel); accounts->setAttribute(Qt::WA_DeleteOnClose); @@ -116,8 +115,7 @@ void Squawk::onAccounts() } } -void Squawk::onPreferences() -{ +void Squawk::onPreferences() { if (preferences == nullptr) { preferences = new Settings(); preferences->setAttribute(Qt::WA_DeleteOnClose); @@ -133,8 +131,7 @@ void Squawk::onPreferences() } } -void Squawk::onAccountsChanged() -{ +void Squawk::onAccountsChanged() { unsigned int size = rosterModel.accountsModel->activeSize(); if (size > 0) { m_ui->actionAddContact->setEnabled(true); @@ -145,8 +142,7 @@ void Squawk::onAccountsChanged() } } -void Squawk::onNewContact() -{ +void Squawk::onNewContact() { NewContact* nc = new NewContact(rosterModel.accountsModel, this); connect(nc, &NewContact::accepted, this, &Squawk::onNewContactAccepted); @@ -155,8 +151,7 @@ void Squawk::onNewContact() nc->exec(); } -void Squawk::onNewConference() -{ +void Squawk::onNewConference() { JoinConference* jc = new JoinConference(rosterModel.accountsModel, this); connect(jc, &JoinConference::accepted, this, &Squawk::onJoinConferenceAccepted); @@ -165,8 +160,7 @@ void Squawk::onNewConference() jc->exec(); } -void Squawk::onNewContactAccepted() -{ +void Squawk::onNewContactAccepted() { NewContact* nc = static_cast(sender()); NewContact::Data value = nc->value(); @@ -175,8 +169,7 @@ void Squawk::onNewContactAccepted() nc->deleteLater(); } -void Squawk::onJoinConferenceAccepted() -{ +void Squawk::onJoinConferenceAccepted() { JoinConference* jc = static_cast(sender()); JoinConference::Data value = jc->value(); @@ -185,23 +178,20 @@ void Squawk::onJoinConferenceAccepted() jc->deleteLater(); } -void Squawk::closeEvent(QCloseEvent* event) -{ - if (accounts != nullptr) { +void Squawk::closeEvent(QCloseEvent* event) { + if (accounts != nullptr) accounts->close(); - } - if (preferences != nullptr) { + if (preferences != nullptr) preferences->close(); - } - if (about != nullptr) { + if (about != nullptr) about->close(); - } + - for (std::map::const_iterator itr = vCards.begin(), end = vCards.end(); itr != end; ++itr) { - disconnect(itr->second, &VCard::destroyed, this, &Squawk::onVCardClosed); - itr->second->close(); + for (const std::pair& pair : infoWidgets) { + disconnect(pair.second, &UI::Info::destroyed, this, &Squawk::onInfoClosed); + pair.second->close(); } - vCards.clear(); + infoWidgets.clear(); writeSettings(); emit closing();; @@ -217,8 +207,7 @@ void Squawk::onPreferencesClosed() { void Squawk::onAboutSquawkClosed() { about = nullptr;} -void Squawk::onComboboxActivated(int index) -{ +void Squawk::onComboboxActivated(int index) { Shared::Availability av = Shared::Global::fromInt(index); emit changeState(av); } @@ -229,8 +218,7 @@ void Squawk::expand(const QModelIndex& index) { void Squawk::stateChanged(Shared::Availability state) { m_ui->comboBox->setCurrentIndex(static_cast(state));} -void Squawk::onRosterItemDoubleClicked(const QModelIndex& item) -{ +void Squawk::onRosterItemDoubleClicked(const QModelIndex& item) { if (item.isValid()) { Models::Item* node = static_cast(item.internalPointer()); if (node->type == Models::Item::reference) { @@ -258,8 +246,7 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item) } } -void Squawk::closeCurrentConversation() -{ +void Squawk::closeCurrentConversation() { if (currentConversation != nullptr) { currentConversation->deleteLater(); currentConversation = nullptr; @@ -267,8 +254,7 @@ void Squawk::closeCurrentConversation() } } -void Squawk::onRosterContextMenu(const QPoint& point) -{ +void Squawk::onRosterContextMenu(const QPoint& point) { QModelIndex index = m_ui->roster->indexAt(point); if (index.isValid()) { Models::Item* item = static_cast(index.internalPointer()); @@ -292,9 +278,9 @@ void Squawk::onRosterContextMenu(const QPoint& point) connect(con, &QAction::triggered, std::bind(&Squawk::connectAccount, this, name)); } - QAction* card = contextMenu->addAction(Shared::icon("user-properties"), tr("VCard")); - card->setEnabled(active); - connect(card, &QAction::triggered, std::bind(&Squawk::onActivateVCard, this, name, acc->getBareJid(), true)); + QAction* info = contextMenu->addAction(Shared::icon("user-properties"), tr("Info")); + info->setEnabled(active); + connect(info, &QAction::triggered, std::bind(&Squawk::onActivateInfo, this, name, acc->getBareJid())); QAction* remove = contextMenu->addAction(Shared::icon("edit-delete"), tr("Remove")); connect(remove, &QAction::triggered, std::bind(&Squawk::removeAccountRequest, this, name)); @@ -379,9 +365,9 @@ void Squawk::onRosterContextMenu(const QPoint& point) }); - QAction* card = contextMenu->addAction(Shared::icon("user-properties"), tr("VCard")); - card->setEnabled(active); - connect(card, &QAction::triggered, std::bind(&Squawk::onActivateVCard, this, id.account, id.name, false)); + QAction* info = contextMenu->addAction(Shared::icon("user-properties"), tr("Info")); + info->setEnabled(active); + connect(info, &QAction::triggered, std::bind(&Squawk::onActivateInfo, this, id.account, id.name)); QAction* remove = contextMenu->addAction(Shared::icon("edit-delete"), tr("Remove")); remove->setEnabled(active); @@ -425,65 +411,61 @@ void Squawk::onRosterContextMenu(const QPoint& point) } } -void Squawk::responseVCard(const QString& jid, const Shared::VCard& card) -{ - std::map::const_iterator itr = vCards.find(jid); - if (itr != vCards.end()) { - itr->second->setVCard(card); +void Squawk::responseInfo(const Shared::Info& info) { + std::map::const_iterator itr = infoWidgets.find(info.jid); + if (itr != infoWidgets.end()) { + itr->second->setData(info); itr->second->hideProgress(); } } -void Squawk::onVCardClosed() -{ - VCard* vCard = static_cast(sender()); +void Squawk::onInfoClosed() { + UI::Info* info = static_cast(sender()); - std::map::const_iterator itr = vCards.find(vCard->getJid()); - if (itr == vCards.end()) { - qDebug() << "VCard has been closed but can not be found among other opened vCards, application is most probably going to crash"; + std::map::const_iterator itr = infoWidgets.find(info->jid); + if (itr == infoWidgets.end()) { + qDebug() << "Info widget has been closed but can not be found among other opened vCards, application is most probably going to crash"; return; } - vCards.erase(itr); + infoWidgets.erase(itr); } -void Squawk::onActivateVCard(const QString& account, const QString& jid, bool edition) -{ - std::map::const_iterator itr = vCards.find(jid); - VCard* card; - if (itr != vCards.end()) { - card = itr->second; +void Squawk::onActivateInfo(const QString& account, const QString& jid) { + std::map::const_iterator itr = infoWidgets.find(jid); + UI::Info* info; + if (itr != infoWidgets.end()) { + info = itr->second; } else { - card = new VCard(jid, edition); - if (edition) { - card->setWindowTitle(tr("%1 account card").arg(account)); - } else { - card->setWindowTitle(tr("%1 contact card").arg(jid)); - } - card->setAttribute(Qt::WA_DeleteOnClose); - vCards.insert(std::make_pair(jid, card)); + info = new UI::Info(jid); + // TODO need to handle it somewhere else + // if (edition) { + // card->setWindowTitle(tr("%1 account card").arg(account)); + // } else { + // card->setWindowTitle(tr("%1 contact card").arg(jid)); + // } + info->setAttribute(Qt::WA_DeleteOnClose); + infoWidgets.insert(std::make_pair(jid, info)); - connect(card, &VCard::destroyed, this, &Squawk::onVCardClosed); - connect(card, &VCard::saveVCard, std::bind( &Squawk::onVCardSave, this, std::placeholders::_1, account)); + connect(info, &UI::Info::destroyed, this, &Squawk::onInfoClosed); + connect(info, &UI::Info::saveInfo, std::bind(&Squawk::onInfoSave, this, std::placeholders::_1, account)); } - card->show(); - card->raise(); - card->activateWindow(); - card->showProgress(tr("Downloading vCard")); + info->show(); + info->raise(); + info->activateWindow(); + info->showProgress(); - emit requestVCard(account, jid); + emit requestInfo(account, jid); } -void Squawk::onVCardSave(const Shared::VCard& card, const QString& account) -{ - VCard* widget = static_cast(sender()); - emit uploadVCard(account, card); +void Squawk::onInfoSave(const Shared::Info& info, const QString& account) { + UI::Info* widget = static_cast(sender()); + emit updateInfo(account, info); widget->deleteLater(); } -void Squawk::writeSettings() -{ +void Squawk::writeSettings() { QSettings settings; settings.beginGroup("ui"); settings.beginGroup("window"); @@ -495,8 +477,7 @@ void Squawk::writeSettings() settings.endGroup(); } -void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous) -{ +void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous) { if (restoreSelection.isValid() && restoreSelection == current) { restoreSelection = QModelIndex(); return; @@ -504,9 +485,9 @@ void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIn if (current.isValid()) { Models::Item* node = static_cast(current.internalPointer()); - if (node->type == Models::Item::reference) { + if (node->type == Models::Item::reference) node = static_cast(node)->dereference(); - } + Models::Contact* contact = nullptr; Models::Room* room = nullptr; QString res; @@ -550,9 +531,9 @@ void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIn if (id != nullptr) { if (currentConversation != nullptr) { if (currentConversation->getId() == *id) { - if (contact != nullptr) { + if (contact != nullptr) currentConversation->setPalResource(res); - } + return; } else { currentConversation->deleteLater(); @@ -588,16 +569,14 @@ void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIn } } -void Squawk::onContextAboutToHide() -{ +void Squawk::onContextAboutToHide() { if (needToRestore) { needToRestore = false; m_ui->roster->selectionModel()->setCurrentIndex(restoreSelection, QItemSelectionModel::ClearAndSelect); } } -void Squawk::onAboutSquawkCalled() -{ +void Squawk::onAboutSquawkCalled() { if (about == nullptr) { about = new About(); about->setAttribute(Qt::WA_DeleteOnClose); @@ -609,17 +588,14 @@ void Squawk::onAboutSquawkCalled() about->show(); } -Models::Roster::ElId Squawk::currentConversationId() const -{ - if (currentConversation == nullptr) { +Models::Roster::ElId Squawk::currentConversationId() const { + if (currentConversation == nullptr) return Models::Roster::ElId(); - } else { + else return Models::Roster::ElId(currentConversation->getAccount(), currentConversation->getJid()); - } } -void Squawk::select(QModelIndex index) -{ +void Squawk::select(QModelIndex index) { m_ui->roster->scrollTo(index, QAbstractItemView::EnsureVisible); m_ui->roster->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect); } diff --git a/ui/squawk.h b/ui/squawk.h index 84e94a8..4e1ca4b 100644 --- a/ui/squawk.h +++ b/ui/squawk.h @@ -36,12 +36,13 @@ #include "widgets/newcontact.h" #include "widgets/joinconference.h" #include "models/roster.h" -#include "widgets/vcard/vcard.h" +#include "widgets/info/info.h" #include "widgets/settings/settings.h" #include "widgets/about.h" #include "shared/shared.h" #include "shared/global.h" +#include "shared/info.h" namespace Ui { class Squawk; @@ -72,8 +73,8 @@ signals: void renameContactRequest(const QString& account, const QString& jid, const QString& newName); void addRoomRequest(const QString& account, const QString& jid, const QString& nick, const QString& password, bool autoJoin); void removeRoomRequest(const QString& account, const QString& jid); - void requestVCard(const QString& account, const QString& jid); - void uploadVCard(const QString& account, const Shared::VCard& card); + void requestInfo(const QString& account, const QString& jid); + void updateInfo(const QString& account, const Shared::Info& info); void changeDownloadsPath(const QString& path); void changeTray(bool enabled, bool hide); @@ -93,7 +94,7 @@ public: public slots: void writeSettings(); void stateChanged(Shared::Availability state); - void responseVCard(const QString& jid, const Shared::VCard& card); + void responseInfo(const Shared::Info& info); void select(QModelIndex index); private: @@ -104,7 +105,7 @@ private: About* about; Models::Roster& rosterModel; QMenu* contextMenu; - std::map vCards; + std::map infoWidgets; Conversation* currentConversation; QModelIndex restoreSelection; bool needToRestore; @@ -123,9 +124,9 @@ private slots: void onAccountsChanged(); void onAccountsClosed(); void onPreferencesClosed(); - void onVCardClosed(); - void onVCardSave(const Shared::VCard& card, const QString& account); - void onActivateVCard(const QString& account, const QString& jid, bool edition = false); + void onInfoClosed(); + void onInfoSave(const Shared::Info& info, const QString& account); + void onActivateInfo(const QString& account, const QString& jid); void onComboboxActivated(int index); void onRosterItemDoubleClicked(const QModelIndex& item); void onRosterContextMenu(const QPoint& point); diff --git a/ui/widgets/CMakeLists.txt b/ui/widgets/CMakeLists.txt index be77db2..2099db1 100644 --- a/ui/widgets/CMakeLists.txt +++ b/ui/widgets/CMakeLists.txt @@ -17,7 +17,6 @@ target_sources(squawk PRIVATE about.ui ) -add_subdirectory(vcard) add_subdirectory(info) add_subdirectory(messageline) add_subdirectory(settings) diff --git a/ui/widgets/info/contactcontacts.cpp b/ui/widgets/info/contactcontacts.cpp index 1196aa9..10615ed 100644 --- a/ui/widgets/info/contactcontacts.cpp +++ b/ui/widgets/info/contactcontacts.cpp @@ -236,3 +236,11 @@ void UI::ContactContacts::onCopyPhone() { QString UI::ContactContacts::title() const { return m_ui->contactHeading->text(); } + +void UI::ContactContacts::fillVCard(Shared::VCard& card) const { + card.setUrl(m_ui->url->text()); + + emails.getEmails(card.getEmails()); + phones.getPhones(card.getPhones()); +} + diff --git a/ui/widgets/info/description.cpp b/ui/widgets/info/description.cpp index 5132321..b2981ca 100644 --- a/ui/widgets/info/description.cpp +++ b/ui/widgets/info/description.cpp @@ -25,3 +25,20 @@ UI::Description::Description(QWidget* parent): } UI::Description::~Description() {} + +QString UI::Description::title() const { + return m_ui->descriptionHeading->text(); +} + +QString UI::Description::description() const { + return m_ui->description->toPlainText(); +} + +void UI::Description::setDescription(const QString& description) { + m_ui->description->setText(description); +} + +void UI::Description::setEditable(bool editable) { + m_ui->description->setReadOnly(!editable); +} + diff --git a/ui/widgets/info/description.h b/ui/widgets/info/description.h index 42b0900..dc823d0 100644 --- a/ui/widgets/info/description.h +++ b/ui/widgets/info/description.h @@ -32,6 +32,11 @@ public: Description(QWidget* parent = nullptr); ~Description(); + QString title() const; + QString description() const; + void setEditable(bool editable); + void setDescription(const QString& description); + private: QScopedPointer m_ui; }; diff --git a/ui/widgets/info/info.cpp b/ui/widgets/info/info.cpp index cbaffa8..f7d7a97 100644 --- a/ui/widgets/info/info.cpp +++ b/ui/widgets/info/info.cpp @@ -17,8 +17,9 @@ #include "info.h" #include "ui_info.h" -UI::Info::Info(QWidget* parent): +UI::Info::Info(const QString& p_jid, QWidget* parent): QWidget(parent), + jid(p_jid), m_ui(new Ui::Info()), contactGeneral(nullptr), contactContacts(nullptr), @@ -28,8 +29,10 @@ UI::Info::Info(QWidget* parent): progressLabel(new QLabel()) { m_ui->setupUi(this); + m_ui->buttonBox->hide(); initializeOverlay(); + initializeButtonBox(); } UI::Info::~Info() { @@ -50,11 +53,17 @@ void UI::Info::setData(const Shared::Info& info) { case Shared::EntryType::contact: initializeContactGeneral(info); initializeContactContacts(info); - initializeDescription(info.editable); + initializeDescription(info); break; default: break; } + + if (!info.editable) + m_ui->buttonBox->hide(); + else + m_ui->buttonBox->show(); + } void UI::Info::initializeOverlay() { @@ -80,9 +89,32 @@ void UI::Info::initializeOverlay() { overlay->hide(); } +void UI::Info::initializeButtonBox() { + connect(m_ui->buttonBox, &QDialogButtonBox::accepted, this, &UI::Info::onButtonBoxAccepted); + connect(m_ui->buttonBox, &QDialogButtonBox::rejected, this, &UI::Info::close); + + m_ui->buttonBox->hide(); +} + +void UI::Info::onButtonBoxAccepted() { + //TODO this is not good, since I don't exactly know what am I editing it's bad to assume there even going to be a vcard + Shared::Info info; + if (contactGeneral != nullptr) + contactGeneral->fillVCard(info.vcard); + if (contactContacts != nullptr) + contactContacts->fillVCard(info.vcard); + if (description != nullptr) + info.vcard.setDescription(description->description()); + + emit saveInfo(info); +} void UI::Info::showProgress(const QString& line) { - progressLabel->setText(line); + if (line.size() > 0) + progressLabel->setText(line); + else + progressLabel->setText(tr("Requesting information about %1").arg(jid)); + overlay->show(); progress->start(); } @@ -99,3 +131,23 @@ void UI::Info::initializeContactGeneral(const Shared::Info& info) { } contactGeneral->setVCard(info.jid, info.vcard, info.editable); } + +void UI::Info::initializeContactContacts(const Shared::Info& info) { + if (contactContacts == nullptr) { + contactContacts = new ContactContacts; + m_ui->tabWidget->addTab(contactContacts, contactContacts->title()); + } + contactContacts->setVCard(info.jid, info.vcard, info.editable); +} + +void UI::Info::initializeDescription(const Shared::Info& info) { + if (description == nullptr) { + description = new Description; + m_ui->tabWidget->addTab(description, description->title()); + } + + description->setDescription(info.vcard.getDescription()); + description->setEditable(info.editable); +} + + diff --git a/ui/widgets/info/info.h b/ui/widgets/info/info.h index 126a092..461242f 100644 --- a/ui/widgets/info/info.h +++ b/ui/widgets/info/info.h @@ -39,18 +39,28 @@ class Info; class Info : public QWidget { Q_OBJECT public: - Info(QWidget* parent = nullptr); + Info(const QString& jid, QWidget* parent = nullptr); ~Info(); void setData(const Shared::Info& info); void showProgress(const QString& = ""); void hideProgress(); +public: + QString jid; + +signals: + void saveInfo(const Shared::Info& info); + +private slots: + void onButtonBoxAccepted(); + private: void initializeContactGeneral(const Shared::Info& info); void initializeContactContacts(const Shared::Info& info); - void initializeDescription(bool editable); + void initializeDescription(const Shared::Info& info); void initializeOverlay(); + void initializeButtonBox(); private: QScopedPointer m_ui; diff --git a/ui/widgets/vcard/CMakeLists.txt b/ui/widgets/vcard/CMakeLists.txt deleted file mode 100644 index 5dca28d..0000000 --- a/ui/widgets/vcard/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -target_sources(squawk PRIVATE - vcard.cpp - vcard.h - vcard.ui - ) diff --git a/ui/widgets/vcard/vcard.cpp b/ui/widgets/vcard/vcard.cpp deleted file mode 100644 index d16aa83..0000000 --- a/ui/widgets/vcard/vcard.cpp +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Squawk messenger. - * Copyright (C) 2019 Yury Gubich - * - * 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 . - */ - -#include "vcard.h" -#include "ui_vcard.h" -#include "shared/icons.h" -#include - -#include - -const std::set VCard::supportedTypes = {"image/jpeg", "image/png"}; - -VCard::VCard(const QString& jid, bool edit, QWidget* parent): - QWidget(parent), - m_ui(new Ui::VCard()), - avatarButtonMargins(), - avatarMenu(nullptr), - editable(edit), - currentAvatarType(Shared::Avatar::empty), - currentAvatarPath(""), - progress(new Progress(100)), - progressLabel(new QLabel()), - overlay(new QWidget()), - contextMenu(new QMenu()), - emails(edit), - phones(edit), - roleDelegate(new ComboboxDelegate()), - phoneTypeDelegate(new ComboboxDelegate()) - -#ifdef WITH_OMEMO - ,omemo(new Omemo()) -#endif -{ - m_ui->setupUi(this); - m_ui->jabberID->setText(jid); - m_ui->jabberID->setReadOnly(true); - - initializeActions(); - initializeDelegates(); - initializeViews(); - initializeInteractiveElements(jid); - initializeOverlay(); -#ifdef WITH_OMEMO - initializeOmemo(); -#endif -} - -VCard::~VCard() { -#ifdef WITH_OMEMO - delete omemo; -#endif - if (editable) { - avatarMenu->deleteLater(); - } - - phoneTypeDelegate->deleteLater(); - roleDelegate->deleteLater(); - contextMenu->deleteLater(); -} - -void VCard::setVCard(const QString& jid, const Shared::VCard& card) { - m_ui->jabberID->setText(jid); - setVCard(card); -} - -void VCard::setVCard(const Shared::VCard& card) { - m_ui->fullName->setText(card.getFullName()); - m_ui->firstName->setText(card.getFirstName()); - m_ui->middleName->setText(card.getMiddleName()); - m_ui->lastName->setText(card.getLastName()); - m_ui->nickName->setText(card.getNickName()); - m_ui->birthday->setDate(card.getBirthday()); - m_ui->organizationName->setText(card.getOrgName()); - m_ui->organizationDepartment->setText(card.getOrgUnit()); - m_ui->organizationTitle->setText(card.getOrgTitle()); - m_ui->organizationRole->setText(card.getOrgRole()); - m_ui->description->setText(card.getDescription()); - m_ui->url->setText(card.getUrl()); - - QDateTime receivingTime = card.getReceivingTime(); - m_ui->receivingTimeLabel->setText(tr("Received %1 at %2").arg(receivingTime.date().toString()).arg(receivingTime.time().toString())); - currentAvatarType = card.getAvatarType(); - currentAvatarPath = card.getAvatarPath(); - - updateAvatar(); - - const std::deque& ems = card.getEmails(); - const std::deque& phs = card.getPhones(); - emails.setEmails(ems); - phones.setPhones(phs); -} - -QString VCard::getJid() const { - return m_ui->jabberID->text(); -} - -void VCard::onButtonBoxAccepted() { - Shared::VCard card; - card.setFullName(m_ui->fullName->text()); - card.setFirstName(m_ui->firstName->text()); - card.setMiddleName(m_ui->middleName->text()); - card.setLastName(m_ui->lastName->text()); - card.setNickName(m_ui->nickName->text()); - card.setBirthday(m_ui->birthday->date()); - card.setDescription(m_ui->description->toPlainText()); - card.setUrl(m_ui->url->text()); - card.setOrgName(m_ui->organizationName->text()); - card.setOrgUnit(m_ui->organizationDepartment->text()); - card.setOrgRole(m_ui->organizationRole->text()); - card.setOrgTitle(m_ui->organizationTitle->text()); - card.setAvatarPath(currentAvatarPath); - card.setAvatarType(currentAvatarType); - - emails.getEmails(card.getEmails()); - phones.getPhones(card.getPhones()); - - emit saveVCard(card); -} - -void VCard::onClearAvatar() { - currentAvatarType = Shared::Avatar::empty; - currentAvatarPath = ""; - - updateAvatar(); -} - -void VCard::onSetAvatar() { - QFileDialog* d = new QFileDialog(this, tr("Chose your new avatar")); - d->setFileMode(QFileDialog::ExistingFile); - d->setNameFilter(tr("Images (*.png *.jpg *.jpeg)")); - - connect(d, &QFileDialog::accepted, this, &VCard::onAvatarSelected); - connect(d, &QFileDialog::rejected, d, &QFileDialog::deleteLater); - - d->show(); -} - -void VCard::updateAvatar() { - int height = m_ui->personalForm->minimumSize().height() - avatarButtonMargins.height(); - switch (currentAvatarType) { - case Shared::Avatar::empty: - m_ui->avatarButton->setIcon(Shared::icon("user", true)); - m_ui->avatarButton->setIconSize(QSize(height, height)); - m_ui->actionClearAvatar->setEnabled(false); - break; - case Shared::Avatar::autocreated: - case Shared::Avatar::valid: - QPixmap pixmap(currentAvatarPath); - qreal h = pixmap.height(); - qreal w = pixmap.width(); - qreal aspectRatio = w / h; - m_ui->avatarButton->setIconSize(QSize(height * aspectRatio, height)); - m_ui->avatarButton->setIcon(QIcon(currentAvatarPath)); - m_ui->actionClearAvatar->setEnabled(true); - break; - } -} - -void VCard::onAvatarSelected() { - QFileDialog* d = static_cast(sender()); - QMimeDatabase db; - QString path = d->selectedFiles().front(); - QMimeType type = db.mimeTypeForFile(path); - d->deleteLater(); - - if (supportedTypes.find(type.name()) == supportedTypes.end()) { - qDebug() << "Selected for avatar file is not supported, skipping"; - } else { - QImage src(path); - QImage dst; - if (src.width() > 160 || src.height() > 160) { - dst = src.scaled(160, 160, Qt::KeepAspectRatio); - } - QString path = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/" + m_ui->jabberID->text() + ".temp." + type.preferredSuffix(); - QFile oldTemp(path); - if (oldTemp.exists()) { - if (!oldTemp.remove()) { - qDebug() << "Error removing old temp avatar" << path; - return; - } - } - bool success = dst.save(path); - if (success) { - currentAvatarPath = path; - currentAvatarType = Shared::Avatar::valid; - - updateAvatar(); - } else { - qDebug() << "couldn't save avatar" << path << ", skipping"; - } - } -} - -void VCard::showProgress(const QString& line) { - progressLabel->setText(line); - overlay->show(); - progress->start(); -} - -void VCard::hideProgress() { - overlay->hide(); - progress->stop(); -} - -void VCard::onContextMenu(const QPoint& point) { - contextMenu->clear(); - bool hasMenu = false; - QAbstractItemView* snd = static_cast(sender()); - if (snd == m_ui->emailsView) { - hasMenu = true; - if (editable) { - QAction* add = contextMenu->addAction(Shared::icon("list-add"), tr("Add email address")); - connect(add, &QAction::triggered, this, &VCard::onAddEmail); - - QItemSelectionModel* sm = m_ui->emailsView->selectionModel(); - int selectionSize = sm->selectedRows().size(); - - if (selectionSize > 0) { - if (selectionSize == 1) { - int row = sm->selectedRows().at(0).row(); - if (emails.isPreferred(row)) { - QAction* rev = contextMenu->addAction(Shared::icon("unfavorite"), tr("Unset this email as preferred")); - connect(rev, &QAction::triggered, std::bind(&Models::EMails::revertPreferred, &emails, row)); - } else { - QAction* rev = contextMenu->addAction(Shared::icon("favorite"), tr("Set this email as preferred")); - connect(rev, &QAction::triggered, std::bind(&Models::EMails::revertPreferred, &emails, row)); - } - } - - QAction* del = contextMenu->addAction(Shared::icon("edit-delete"), tr("Remove selected email addresses")); - connect(del, &QAction::triggered, this, &VCard::onRemoveEmail); - } - } - - QAction* cp = contextMenu->addAction(Shared::icon("edit-copy"), tr("Copy selected emails to clipboard")); - connect(cp, &QAction::triggered, this, &VCard::onCopyEmail); - } else if (snd == m_ui->phonesView) { - hasMenu = true; - if (editable) { - QAction* add = contextMenu->addAction(Shared::icon("list-add"), tr("Add phone number")); - connect(add, &QAction::triggered, this, &VCard::onAddPhone); - - QItemSelectionModel* sm = m_ui->phonesView->selectionModel(); - int selectionSize = sm->selectedRows().size(); - - if (selectionSize > 0) { - if (selectionSize == 1) { - int row = sm->selectedRows().at(0).row(); - if (phones.isPreferred(row)) { - QAction* rev = contextMenu->addAction(Shared::icon("view-media-favorite"), tr("Unset this phone as preferred")); - connect(rev, &QAction::triggered, std::bind(&Models::Phones::revertPreferred, &phones, row)); - } else { - QAction* rev = contextMenu->addAction(Shared::icon("favorite"), tr("Set this phone as preferred")); - connect(rev, &QAction::triggered, std::bind(&Models::Phones::revertPreferred, &phones, row)); - } - } - - QAction* del = contextMenu->addAction(Shared::icon("edit-delete"), tr("Remove selected phone numbers")); - connect(del, &QAction::triggered, this, &VCard::onRemovePhone); - } - } - - QAction* cp = contextMenu->addAction(Shared::icon("edit-copy"), tr("Copy selected phones to clipboard")); - connect(cp, &QAction::triggered, this, &VCard::onCopyPhone); - } - - if (hasMenu) { - contextMenu->popup(snd->viewport()->mapToGlobal(point)); - } -} - -void VCard::onAddEmail() { - QModelIndex index = emails.addNewEmptyLine(); - m_ui->emailsView->setCurrentIndex(index); - m_ui->emailsView->edit(index); -} - -void VCard::onAddAddress() {} -void VCard::onAddPhone() { - QModelIndex index = phones.addNewEmptyLine(); - m_ui->phonesView->setCurrentIndex(index); - m_ui->phonesView->edit(index); -} -void VCard::onRemoveAddress() {} -void VCard::onRemoveEmail() { - QItemSelection selection(m_ui->emailsView->selectionModel()->selection()); - - QList rows; - for (const QModelIndex& index : selection.indexes()) { - rows.append(index.row()); - } - - std::sort(rows.begin(), rows.end()); - - int prev = -1; - for (int i = rows.count() - 1; i >= 0; i -= 1) { - int current = rows[i]; - if (current != prev) { - emails.removeLines(current, 1); - prev = current; - } - } -} - -void VCard::onRemovePhone() { - QItemSelection selection(m_ui->phonesView->selectionModel()->selection()); - - QList rows; - for (const QModelIndex& index : selection.indexes()) { - rows.append(index.row()); - } - - std::sort(rows.begin(), rows.end()); - - int prev = -1; - for (int i = rows.count() - 1; i >= 0; i -= 1) { - int current = rows[i]; - if (current != prev) { - phones.removeLines(current, 1); - prev = current; - } - } -} - -void VCard::onCopyEmail() { - QList selection(m_ui->emailsView->selectionModel()->selectedRows()); - - QList addrs; - for (const QModelIndex& index : selection) { - addrs.push_back(emails.getEmail(index.row())); - } - - QString list = addrs.join("\n"); - - QClipboard* cb = QApplication::clipboard(); - cb->setText(list); -} - -void VCard::onCopyPhone() { - QList selection(m_ui->phonesView->selectionModel()->selectedRows()); - - QList phs; - for (const QModelIndex& index : selection) { - phs.push_back(phones.getPhone(index.row())); - } - - QString list = phs.join("\n"); - - QClipboard* cb = QApplication::clipboard(); - cb->setText(list); -} - -void VCard::initializeDelegates() { - roleDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Email::roleNames[0].toStdString().c_str())); - roleDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Email::roleNames[1].toStdString().c_str())); - roleDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Email::roleNames[2].toStdString().c_str())); - - phoneTypeDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Phone::typeNames[0].toStdString().c_str())); - phoneTypeDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Phone::typeNames[1].toStdString().c_str())); - phoneTypeDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Phone::typeNames[2].toStdString().c_str())); - phoneTypeDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Phone::typeNames[3].toStdString().c_str())); - phoneTypeDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Phone::typeNames[4].toStdString().c_str())); - phoneTypeDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Phone::typeNames[5].toStdString().c_str())); - phoneTypeDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Phone::typeNames[6].toStdString().c_str())); -} - -void VCard::initializeViews() { - m_ui->emailsView->setContextMenuPolicy(Qt::CustomContextMenu); - m_ui->emailsView->setModel(&emails); - m_ui->emailsView->setItemDelegateForColumn(1, roleDelegate); - m_ui->emailsView->setColumnWidth(2, 25); - m_ui->emailsView->horizontalHeader()->setStretchLastSection(false); - m_ui->emailsView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); - - m_ui->phonesView->setContextMenuPolicy(Qt::CustomContextMenu); - m_ui->phonesView->setModel(&phones); - m_ui->phonesView->setItemDelegateForColumn(1, roleDelegate); - m_ui->phonesView->setItemDelegateForColumn(2, phoneTypeDelegate); - m_ui->phonesView->setColumnWidth(3, 25); - m_ui->phonesView->horizontalHeader()->setStretchLastSection(false); - m_ui->phonesView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); - - connect(m_ui->phonesView, &QWidget::customContextMenuRequested, this, &VCard::onContextMenu); - connect(m_ui->emailsView, &QWidget::customContextMenuRequested, this, &VCard::onContextMenu); -} - -void VCard::initializeActions() { - QAction* setAvatar = m_ui->actionSetAvatar; - QAction* clearAvatar = m_ui->actionClearAvatar; - - connect(setAvatar, &QAction::triggered, this, &VCard::onSetAvatar); - connect(clearAvatar, &QAction::triggered, this, &VCard::onClearAvatar); - - setAvatar->setEnabled(true); - clearAvatar->setEnabled(false); -} - -void VCard::initializeInteractiveElements(const QString& jid) { - if (editable) { - avatarMenu = new QMenu(); - m_ui->avatarButton->setMenu(avatarMenu); - avatarMenu->addAction(m_ui->actionSetAvatar); - avatarMenu->addAction(m_ui->actionClearAvatar); - m_ui->title->setText(tr("Account %1 card").arg(jid)); - } else { - m_ui->buttonBox->hide(); - m_ui->fullName->setReadOnly(true); - m_ui->firstName->setReadOnly(true); - m_ui->middleName->setReadOnly(true); - m_ui->lastName->setReadOnly(true); - m_ui->nickName->setReadOnly(true); - m_ui->birthday->setReadOnly(true); - m_ui->organizationName->setReadOnly(true); - m_ui->organizationDepartment->setReadOnly(true); - m_ui->organizationTitle->setReadOnly(true); - m_ui->organizationRole->setReadOnly(true); - m_ui->description->setReadOnly(true); - m_ui->url->setReadOnly(true); - m_ui->title->setText(tr("Contact %1 card").arg(jid)); - } - - connect(m_ui->buttonBox, &QDialogButtonBox::accepted, this, &VCard::onButtonBoxAccepted); - connect(m_ui->buttonBox, &QDialogButtonBox::rejected, this, &VCard::close); - - avatarButtonMargins = m_ui->avatarButton->size(); - - int height = m_ui->personalForm->minimumSize().height() - avatarButtonMargins.height(); - m_ui->avatarButton->setIconSize(QSize(height, height)); -} - -void VCard::initializeOverlay() { - QGridLayout* gr = static_cast(layout()); - gr->addWidget(overlay, 0, 0, 4, 1); - QVBoxLayout* nl = new QVBoxLayout(); - QGraphicsOpacityEffect* opacity = new QGraphicsOpacityEffect(); - opacity->setOpacity(0.8); - overlay->setLayout(nl); - overlay->setBackgroundRole(QPalette::Base); - overlay->setAutoFillBackground(true); - overlay->setGraphicsEffect(opacity); - progressLabel->setAlignment(Qt::AlignCenter); - QFont pf = progressLabel->font(); - pf.setBold(true); - pf.setPointSize(26); - progressLabel->setFont(pf); - progressLabel->setWordWrap(true); - nl->addStretch(); - nl->addWidget(progress); - nl->addWidget(progressLabel); - nl->addStretch(); - overlay->hide(); -} - -#ifdef WITH_OMEMO -void VCard::initializeOmemo() { - m_ui->tabWidget->addTab(omemo, "OMEMO"); -} - -#endif diff --git a/ui/widgets/vcard/vcard.h b/ui/widgets/vcard/vcard.h deleted file mode 100644 index 7019797..0000000 --- a/ui/widgets/vcard/vcard.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Squawk messenger. - * Copyright (C) 2019 Yury Gubich - * - * 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 . - */ - -#ifndef VCARD_H -#define VCARD_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "shared/vcard.h" -#include "ui/models/info/emails.h" -#include "ui/models/info/phones.h" -#include "ui/utils/progress.h" -#include "ui/utils/comboboxdelegate.h" - -#ifdef WITH_OMEMO -#include "ui/widgets/info/omemo/omemo.h" -#endif - -namespace Ui -{ -class VCard; -} - -class VCard : public QWidget { - Q_OBJECT -public: - VCard(const QString& jid, bool edit = false, QWidget* parent = nullptr); - ~VCard(); - - void setVCard(const Shared::VCard& card); - void setVCard(const QString& jid, const Shared::VCard& card); - QString getJid() const; - void showProgress(const QString& = ""); - void hideProgress(); - -signals: - void saveVCard(const Shared::VCard& card); - -private slots: - void onButtonBoxAccepted(); - void onClearAvatar(); - void onSetAvatar(); - void onAvatarSelected(); - void onAddAddress(); - void onRemoveAddress(); - void onAddEmail(); - void onCopyEmail(); - void onRemoveEmail(); - void onAddPhone(); - void onCopyPhone(); - void onRemovePhone(); - void onContextMenu(const QPoint& point); - -private: - QScopedPointer m_ui; - QSize avatarButtonMargins; - QMenu* avatarMenu; - bool editable; - Shared::Avatar currentAvatarType; - QString currentAvatarPath; - Progress* progress; - QLabel* progressLabel; - QWidget* overlay; - QMenu* contextMenu; - Models::EMails emails; - Models::Phones phones; - ComboboxDelegate* roleDelegate; - ComboboxDelegate* phoneTypeDelegate; -#ifdef WITH_OMEMO - Omemo* omemo; -#endif - - static const std::set supportedTypes; - -private: - void updateAvatar(); - void initializeDelegates(); - void initializeViews(); - void initializeActions(); - void initializeInteractiveElements(const QString& jid); - void initializeOverlay(); -#ifdef WITH_OMEMO - void initializeOmemo(); -#endif -}; - -#endif // VCARD_H diff --git a/ui/widgets/vcard/vcard.ui b/ui/widgets/vcard/vcard.ui deleted file mode 100644 index 7e09257..0000000 --- a/ui/widgets/vcard/vcard.ui +++ /dev/null @@ -1,892 +0,0 @@ - - - VCard - - - true - - - - 0 - 0 - 578 - 748 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 6 - - - 6 - - - 6 - - - 6 - - - - - font: 16pt - - - Contact john@dow.org card - - - Qt::AlignCenter - - - - - - - font: italic 8pt; - - - Received 12.07.2007 at 17.35 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - true - - - Qt::TabFocus - - - QTabWidget::North - - - QTabWidget::Rounded - - - 1 - - - Qt::ElideNone - - - true - - - false - - - - General - - - - 0 - - - 6 - - - 0 - - - 0 - - - 6 - - - - - - 0 - 0 - - - - font: 600 16pt; - - - Organization - - - Qt::AlignCenter - - - - - - - QLayout::SetDefaultConstraint - - - Qt::AlignHCenter|Qt::AlignTop - - - - - - 200 - 0 - - - - - 350 - 16777215 - - - - - - - - - 200 - 0 - - - - - 350 - 16777215 - - - - - - - - Middle name - - - middleName - - - - - - - First name - - - firstName - - - - - - - Last name - - - lastName - - - - - - - - 200 - 0 - - - - - 350 - 16777215 - - - - - - - - Nick name - - - nickName - - - - - - - - 200 - 0 - - - - - 350 - 16777215 - - - - - - - - Birthday - - - birthday - - - - - - - - - - - - Qt::AlignHCenter|Qt::AlignTop - - - - - Organization name - - - organizationName - - - - - - - - 200 - 0 - - - - - 350 - 16777215 - - - - - - - - Unit / Department - - - organizationDepartment - - - - - - - - 200 - 0 - - - - - 350 - 16777215 - - - - - - - - Role / Profession - - - organizationRole - - - - - - - - 200 - 0 - - - - - 350 - 16777215 - - - - - - - - Job title - - - organizationTitle - - - - - - - - 200 - 0 - - - - - 350 - 16777215 - - - - - - - - - - Qt::Horizontal - - - - - - - - - - - - Full name - - - fullName - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Horizontal - - - - - - - font: 600 24pt ; - - - General - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - font: 600 16pt; - - - QFrame::NoFrame - - - QFrame::Plain - - - Personal information - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - - - - :/images/fallback/dark/big/user.svg:/images/fallback/dark/big/user.svg - - - - 0 - 0 - - - - QToolButton::InstantPopup - - - Qt::ToolButtonIconOnly - - - Qt::NoArrow - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - Contact - - - - 0 - - - 0 - - - 6 - - - 0 - - - 0 - - - - - font: 600 24pt ; - - - Contact - - - - - - - QFrame::NoFrame - - - QFrame::Plain - - - 0 - - - true - - - - - 0 - 0 - 545 - 544 - - - - - - - Qt::Horizontal - - - - - - - QAbstractItemView::ExtendedSelection - - - QAbstractItemView::SelectRows - - - false - - - false - - - false - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - font: 600 16pt; - - - Addresses - - - Qt::AlignCenter - - - - - - - QAbstractItemView::SelectRows - - - false - - - false - - - false - - - - - - - font: 600 16pt; - - - E-Mail addresses - - - Qt::AlignCenter - - - - - - - Qt::AlignHCenter|Qt::AlignTop - - - - - - 150 - 0 - - - - - 300 - 16777215 - - - - - - - - Jabber ID - - - jabberID - - - - - - - - 150 - 0 - - - - - 300 - 16777215 - - - - - - - - Web site - - - url - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - font: 600 16pt; - - - Phone numbers - - - Qt::AlignCenter - - - - - - - QAbstractItemView::SelectRows - - - false - - - false - - - false - - - - - - - - - - - - Description - - - - 0 - - - 6 - - - 0 - - - 0 - - - 6 - - - - - font: 600 24pt ; - - - Description - - - - - - - QFrame::StyledPanel - - - Qt::LinksAccessibleByMouse|Qt::TextEditable|Qt::TextEditorInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - - - - - QDialogButtonBox::Close|QDialogButtonBox::Save - - - false - - - - - - - - - - :/images/fallback/dark/big/edit-rename.svg:/images/fallback/dark/big/edit-rename.svg - - - Set avatar - - - - - - :/images/fallback/dark/big/clean.svg:/images/fallback/dark/big/clean.svg - - - Clear avatar - - - - - fullName - firstName - middleName - lastName - nickName - birthday - avatarButton - organizationName - organizationDepartment - organizationRole - organizationTitle - jabberID - url - description - - - - - -