forked from blue/squawk
refactoring: UI squawk now belongs to a new class, it enables me doing trayed mode, when main window is destroyed
This commit is contained in:
parent
83cb220175
commit
721d3a1a89
@ -148,6 +148,7 @@ if(CMAKE_COMPILER_IS_GNUCXX)
|
|||||||
target_compile_options(squawk PRIVATE ${COMPILE_OPTIONS})
|
target_compile_options(squawk PRIVATE ${COMPILE_OPTIONS})
|
||||||
endif(CMAKE_COMPILER_IS_GNUCXX)
|
endif(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
|
|
||||||
|
add_subdirectory(main)
|
||||||
add_subdirectory(core)
|
add_subdirectory(core)
|
||||||
add_subdirectory(external/simpleCrypt)
|
add_subdirectory(external/simpleCrypt)
|
||||||
add_subdirectory(packaging)
|
add_subdirectory(packaging)
|
||||||
|
@ -12,7 +12,6 @@ target_sources(squawk PRIVATE
|
|||||||
conference.h
|
conference.h
|
||||||
contact.cpp
|
contact.cpp
|
||||||
contact.h
|
contact.h
|
||||||
main.cpp
|
|
||||||
networkaccess.cpp
|
networkaccess.cpp
|
||||||
networkaccess.h
|
networkaccess.h
|
||||||
rosteritem.cpp
|
rosteritem.cpp
|
||||||
|
201
core/main.cpp
201
core/main.cpp
@ -1,201 +0,0 @@
|
|||||||
/*
|
|
||||||
* Squawk messenger.
|
|
||||||
* Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "../shared/global.h"
|
|
||||||
#include "../shared/messageinfo.h"
|
|
||||||
#include "../shared/pathcheck.h"
|
|
||||||
#include "../ui/squawk.h"
|
|
||||||
#include "signalcatcher.h"
|
|
||||||
#include "squawk.h"
|
|
||||||
|
|
||||||
#include <QLibraryInfo>
|
|
||||||
#include <QSettings>
|
|
||||||
#include <QStandardPaths>
|
|
||||||
#include <QTranslator>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtCore/QThread>
|
|
||||||
#include <QtWidgets/QApplication>
|
|
||||||
#include <QDir>
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
qRegisterMetaType<Shared::Message>("Shared::Message");
|
|
||||||
qRegisterMetaType<Shared::MessageInfo>("Shared::MessageInfo");
|
|
||||||
qRegisterMetaType<Shared::VCard>("Shared::VCard");
|
|
||||||
qRegisterMetaType<std::list<Shared::Message>>("std::list<Shared::Message>");
|
|
||||||
qRegisterMetaType<std::list<Shared::MessageInfo>>("std::list<Shared::MessageInfo>");
|
|
||||||
qRegisterMetaType<QSet<QString>>("QSet<QString>");
|
|
||||||
qRegisterMetaType<Shared::ConnectionState>("Shared::ConnectionState");
|
|
||||||
qRegisterMetaType<Shared::Availability>("Shared::Availability");
|
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
|
||||||
SignalCatcher sc(&app);
|
|
||||||
|
|
||||||
QApplication::setApplicationName("squawk");
|
|
||||||
QApplication::setOrganizationName("macaw.me");
|
|
||||||
QApplication::setApplicationDisplayName("Squawk");
|
|
||||||
QApplication::setApplicationVersion("0.2.2");
|
|
||||||
|
|
||||||
QTranslator qtTranslator;
|
|
||||||
qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
|
|
||||||
app.installTranslator(&qtTranslator);
|
|
||||||
|
|
||||||
QTranslator myappTranslator;
|
|
||||||
QStringList shares = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
|
|
||||||
bool found = false;
|
|
||||||
for (QString share : shares) {
|
|
||||||
found = myappTranslator.load(QLocale(), QLatin1String("squawk"), ".", share + "/l10n");
|
|
||||||
if (found) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
myappTranslator.load(QLocale(), QLatin1String("squawk"), ".", QCoreApplication::applicationDirPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
app.installTranslator(&myappTranslator);
|
|
||||||
|
|
||||||
QIcon icon;
|
|
||||||
icon.addFile(":images/logo.svg", QSize(16, 16));
|
|
||||||
icon.addFile(":images/logo.svg", QSize(24, 24));
|
|
||||||
icon.addFile(":images/logo.svg", QSize(32, 32));
|
|
||||||
icon.addFile(":images/logo.svg", QSize(48, 48));
|
|
||||||
icon.addFile(":images/logo.svg", QSize(64, 64));
|
|
||||||
icon.addFile(":images/logo.svg", QSize(96, 96));
|
|
||||||
icon.addFile(":images/logo.svg", QSize(128, 128));
|
|
||||||
icon.addFile(":images/logo.svg", QSize(256, 256));
|
|
||||||
icon.addFile(":images/logo.svg", QSize(512, 512));
|
|
||||||
QApplication::setWindowIcon(icon);
|
|
||||||
|
|
||||||
new Shared::Global(); //translates enums
|
|
||||||
|
|
||||||
QSettings settings;
|
|
||||||
QVariant vs = settings.value("style");
|
|
||||||
if (vs.isValid()) {
|
|
||||||
QString style = vs.toString().toLower();
|
|
||||||
if (style != "system") {
|
|
||||||
Shared::Global::setStyle(style);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Shared::Global::supported("colorSchemeTools")) {
|
|
||||||
QVariant vt = settings.value("theme");
|
|
||||||
if (vt.isValid()) {
|
|
||||||
QString theme = vt.toString();
|
|
||||||
if (theme.toLower() != "system") {
|
|
||||||
Shared::Global::setTheme(theme);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QString path = Shared::downloadsPathCheck();
|
|
||||||
if (path.size() > 0) {
|
|
||||||
settings.setValue("downloadsPath", path);
|
|
||||||
} else {
|
|
||||||
qDebug() << "couldn't initialize directory for downloads, quitting";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Squawk w;
|
|
||||||
w.show();
|
|
||||||
|
|
||||||
Core::Squawk* squawk = new Core::Squawk();
|
|
||||||
QThread* coreThread = new QThread();
|
|
||||||
squawk->moveToThread(coreThread);
|
|
||||||
|
|
||||||
QObject::connect(&sc, &SignalCatcher::interrupt, &app, &QApplication::closeAllWindows);
|
|
||||||
|
|
||||||
QObject::connect(coreThread, &QThread::started, squawk, &Core::Squawk::start);
|
|
||||||
QObject::connect(&app, &QApplication::lastWindowClosed, squawk, &Core::Squawk::stop);
|
|
||||||
QObject::connect(&app, &QApplication::lastWindowClosed, &w, &Squawk::writeSettings);
|
|
||||||
//QObject::connect(&app, &QApplication::aboutToQuit, &w, &QMainWindow::close);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::quit, squawk, &Core::Squawk::deleteLater);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::quit, coreThread, &QThread::quit, Qt::QueuedConnection);
|
|
||||||
QObject::connect(coreThread, &QThread::finished, &app, &QApplication::quit, Qt::QueuedConnection);
|
|
||||||
|
|
||||||
QObject::connect(&w, &Squawk::newAccountRequest, squawk, &Core::Squawk::newAccountRequest);
|
|
||||||
QObject::connect(&w, &Squawk::modifyAccountRequest, squawk, &Core::Squawk::modifyAccountRequest);
|
|
||||||
QObject::connect(&w, &Squawk::removeAccountRequest, squawk, &Core::Squawk::removeAccountRequest);
|
|
||||||
QObject::connect(&w, &Squawk::connectAccount, squawk, &Core::Squawk::connectAccount);
|
|
||||||
QObject::connect(&w, &Squawk::disconnectAccount, squawk, &Core::Squawk::disconnectAccount);
|
|
||||||
QObject::connect(&w, &Squawk::changeState, squawk, &Core::Squawk::changeState);
|
|
||||||
QObject::connect(&w, &Squawk::sendMessage, squawk,&Core::Squawk::sendMessage);
|
|
||||||
QObject::connect(&w, &Squawk::replaceMessage, squawk,&Core::Squawk::replaceMessage);
|
|
||||||
QObject::connect(&w, &Squawk::resendMessage, squawk,&Core::Squawk::resendMessage);
|
|
||||||
QObject::connect(&w, &Squawk::requestArchive, squawk, &Core::Squawk::requestArchive);
|
|
||||||
QObject::connect(&w, &Squawk::subscribeContact, squawk, &Core::Squawk::subscribeContact);
|
|
||||||
QObject::connect(&w, &Squawk::unsubscribeContact, squawk, &Core::Squawk::unsubscribeContact);
|
|
||||||
QObject::connect(&w, &Squawk::addContactRequest, squawk, &Core::Squawk::addContactRequest);
|
|
||||||
QObject::connect(&w, &Squawk::removeContactRequest, squawk, &Core::Squawk::removeContactRequest);
|
|
||||||
QObject::connect(&w, &Squawk::setRoomJoined, squawk, &Core::Squawk::setRoomJoined);
|
|
||||||
QObject::connect(&w, &Squawk::setRoomAutoJoin, squawk, &Core::Squawk::setRoomAutoJoin);
|
|
||||||
QObject::connect(&w, &Squawk::removeRoomRequest, squawk, &Core::Squawk::removeRoomRequest);
|
|
||||||
QObject::connect(&w, &Squawk::addRoomRequest, squawk, &Core::Squawk::addRoomRequest);
|
|
||||||
QObject::connect(&w, &Squawk::fileDownloadRequest, squawk, &Core::Squawk::fileDownloadRequest);
|
|
||||||
QObject::connect(&w, &Squawk::addContactToGroupRequest, squawk, &Core::Squawk::addContactToGroupRequest);
|
|
||||||
QObject::connect(&w, &Squawk::removeContactFromGroupRequest, squawk, &Core::Squawk::removeContactFromGroupRequest);
|
|
||||||
QObject::connect(&w, &Squawk::renameContactRequest, squawk, &Core::Squawk::renameContactRequest);
|
|
||||||
QObject::connect(&w, &Squawk::requestVCard, squawk, &Core::Squawk::requestVCard);
|
|
||||||
QObject::connect(&w, &Squawk::uploadVCard, squawk, &Core::Squawk::uploadVCard);
|
|
||||||
QObject::connect(&w, &Squawk::responsePassword, squawk, &Core::Squawk::responsePassword);
|
|
||||||
QObject::connect(&w, &Squawk::localPathInvalid, squawk, &Core::Squawk::onLocalPathInvalid);
|
|
||||||
QObject::connect(&w, &Squawk::changeDownloadsPath, squawk, &Core::Squawk::changeDownloadsPath);
|
|
||||||
|
|
||||||
QObject::connect(squawk, &Core::Squawk::newAccount, &w, &Squawk::newAccount);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::addContact, &w, &Squawk::addContact);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::changeAccount, &w, &Squawk::changeAccount);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::removeAccount, &w, &Squawk::removeAccount);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::addGroup, &w, &Squawk::addGroup);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::removeGroup, &w, &Squawk::removeGroup);
|
|
||||||
QObject::connect(squawk, qOverload<const QString&, const QString&>(&Core::Squawk::removeContact),
|
|
||||||
&w, qOverload<const QString&, const QString&>(&Squawk::removeContact));
|
|
||||||
QObject::connect(squawk, qOverload<const QString&, const QString&, const QString&>(&Core::Squawk::removeContact),
|
|
||||||
&w, qOverload<const QString&, const QString&, const QString&>(&Squawk::removeContact));
|
|
||||||
QObject::connect(squawk, &Core::Squawk::changeContact, &w, &Squawk::changeContact);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::addPresence, &w, &Squawk::addPresence);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::removePresence, &w, &Squawk::removePresence);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::stateChanged, &w, &Squawk::stateChanged);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::accountMessage, &w, &Squawk::accountMessage);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::changeMessage, &w, &Squawk::changeMessage);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::responseArchive, &w, &Squawk::responseArchive);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::addRoom, &w, &Squawk::addRoom);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::changeRoom, &w, &Squawk::changeRoom);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::removeRoom, &w, &Squawk::removeRoom);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::addRoomParticipant, &w, &Squawk::addRoomParticipant);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::changeRoomParticipant, &w, &Squawk::changeRoomParticipant);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::removeRoomParticipant, &w, &Squawk::removeRoomParticipant);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::fileDownloadComplete, &w, &Squawk::fileDownloadComplete);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::fileUploadComplete, &w, &Squawk::fileUploadComplete);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::fileProgress, &w, &Squawk::fileProgress);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::fileError, &w, &Squawk::fileError);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::responseVCard, &w, &Squawk::responseVCard);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::requestPassword, &w, &Squawk::requestPassword);
|
|
||||||
QObject::connect(squawk, &Core::Squawk::ready, &w, &Squawk::readSettings);
|
|
||||||
|
|
||||||
coreThread->start();
|
|
||||||
int result = app.exec();
|
|
||||||
|
|
||||||
if (coreThread->isRunning()) {
|
|
||||||
//coreThread->wait();
|
|
||||||
//todo if I uncomment that, the app will not quit if it has reconnected at least once
|
|
||||||
//it feels like a symptom of something badly desinged in the core thread
|
|
||||||
//need to investigate;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
7
main/CMakeLists.txt
Normal file
7
main/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
target_sources(squawk PRIVATE
|
||||||
|
main.cpp
|
||||||
|
application.cpp
|
||||||
|
application.h
|
||||||
|
dialogqueue.cpp
|
||||||
|
dialogqueue.h
|
||||||
|
)
|
476
main/application.cpp
Normal file
476
main/application.cpp
Normal file
@ -0,0 +1,476 @@
|
|||||||
|
// Squawk messenger.
|
||||||
|
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "application.h"
|
||||||
|
|
||||||
|
Application::Application(Core::Squawk* p_core):
|
||||||
|
QObject(),
|
||||||
|
availability(Shared::Availability::offline),
|
||||||
|
core(p_core),
|
||||||
|
squawk(nullptr),
|
||||||
|
notifications("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", QDBusConnection::sessionBus()),
|
||||||
|
roster(),
|
||||||
|
conversations(),
|
||||||
|
dialogueQueue(roster),
|
||||||
|
nowQuitting(false),
|
||||||
|
destroyingSquawk(false)
|
||||||
|
{
|
||||||
|
connect(&roster, &Models::Roster::unnoticedMessage, this, &Application::notify);
|
||||||
|
|
||||||
|
|
||||||
|
//connecting myself to the backed
|
||||||
|
connect(this, &Application::changeState, core, &Core::Squawk::changeState);
|
||||||
|
connect(this, &Application::setRoomJoined, core, &Core::Squawk::setRoomJoined);
|
||||||
|
connect(this, &Application::setRoomAutoJoin, core, &Core::Squawk::setRoomAutoJoin);
|
||||||
|
connect(this, &Application::subscribeContact, core, &Core::Squawk::subscribeContact);
|
||||||
|
connect(this, &Application::unsubscribeContact, core, &Core::Squawk::unsubscribeContact);
|
||||||
|
connect(this, &Application::replaceMessage, core, &Core::Squawk::replaceMessage);
|
||||||
|
connect(this, &Application::sendMessage, core, &Core::Squawk::sendMessage);
|
||||||
|
connect(this, &Application::resendMessage, core, &Core::Squawk::resendMessage);
|
||||||
|
connect(&roster, &Models::Roster::requestArchive,
|
||||||
|
std::bind(&Core::Squawk::requestArchive, core, std::placeholders::_1, std::placeholders::_2, 20, std::placeholders::_3));
|
||||||
|
|
||||||
|
connect(&dialogueQueue, &DialogQueue::modifyAccountRequest, core, &Core::Squawk::modifyAccountRequest);
|
||||||
|
connect(&dialogueQueue, &DialogQueue::responsePassword, core, &Core::Squawk::responsePassword);
|
||||||
|
connect(&dialogueQueue, &DialogQueue::disconnectAccount, core, &Core::Squawk::disconnectAccount);
|
||||||
|
|
||||||
|
connect(&roster, &Models::Roster::fileDownloadRequest, core, &Core::Squawk::fileDownloadRequest);
|
||||||
|
connect(&roster, &Models::Roster::localPathInvalid, core, &Core::Squawk::onLocalPathInvalid);
|
||||||
|
|
||||||
|
|
||||||
|
//coonecting backend to myself
|
||||||
|
connect(core, &Core::Squawk::stateChanged, this, &Application::stateChanged);
|
||||||
|
|
||||||
|
connect(core, &Core::Squawk::accountMessage, &roster, &Models::Roster::addMessage);
|
||||||
|
connect(core, &Core::Squawk::responseArchive, &roster, &Models::Roster::responseArchive);
|
||||||
|
connect(core, &Core::Squawk::changeMessage, &roster, &Models::Roster::changeMessage);
|
||||||
|
|
||||||
|
connect(core, &Core::Squawk::newAccount, &roster, &Models::Roster::addAccount);
|
||||||
|
connect(core, &Core::Squawk::changeAccount, this, &Application::changeAccount);
|
||||||
|
connect(core, &Core::Squawk::removeAccount, this, &Application::removeAccount);
|
||||||
|
|
||||||
|
connect(core, &Core::Squawk::addContact, this, &Application::addContact);
|
||||||
|
connect(core, &Core::Squawk::addGroup, this, &Application::addGroup);
|
||||||
|
connect(core, &Core::Squawk::removeGroup, &roster, &Models::Roster::removeGroup);
|
||||||
|
connect(core, qOverload<const QString&, const QString&>(&Core::Squawk::removeContact),
|
||||||
|
&roster, qOverload<const QString&, const QString&>(&Models::Roster::removeContact));
|
||||||
|
connect(core, qOverload<const QString&, const QString&, const QString&>(&Core::Squawk::removeContact),
|
||||||
|
&roster, qOverload<const QString&, const QString&, const QString&>(&Models::Roster::removeContact));
|
||||||
|
connect(core, &Core::Squawk::changeContact, &roster, &Models::Roster::changeContact);
|
||||||
|
connect(core, &Core::Squawk::addPresence, &roster, &Models::Roster::addPresence);
|
||||||
|
connect(core, &Core::Squawk::removePresence, &roster, &Models::Roster::removePresence);
|
||||||
|
|
||||||
|
connect(core, &Core::Squawk::addRoom, &roster, &Models::Roster::addRoom);
|
||||||
|
connect(core, &Core::Squawk::changeRoom, &roster, &Models::Roster::changeRoom);
|
||||||
|
connect(core, &Core::Squawk::removeRoom, &roster, &Models::Roster::removeRoom);
|
||||||
|
connect(core, &Core::Squawk::addRoomParticipant, &roster, &Models::Roster::addRoomParticipant);
|
||||||
|
connect(core, &Core::Squawk::changeRoomParticipant, &roster, &Models::Roster::changeRoomParticipant);
|
||||||
|
connect(core, &Core::Squawk::removeRoomParticipant, &roster, &Models::Roster::removeRoomParticipant);
|
||||||
|
|
||||||
|
|
||||||
|
connect(core, &Core::Squawk::fileDownloadComplete, std::bind(&Models::Roster::fileComplete, &roster, std::placeholders::_1, false));
|
||||||
|
connect(core, &Core::Squawk::fileUploadComplete, std::bind(&Models::Roster::fileComplete, &roster, std::placeholders::_1, true));
|
||||||
|
connect(core, &Core::Squawk::fileProgress, &roster, &Models::Roster::fileProgress);
|
||||||
|
connect(core, &Core::Squawk::fileError, &roster, &Models::Roster::fileError);
|
||||||
|
|
||||||
|
connect(core, &Core::Squawk::requestPassword, this, &Application::requestPassword);
|
||||||
|
connect(core, &Core::Squawk::ready, this, &Application::readSettings);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Application::~Application() {}
|
||||||
|
|
||||||
|
void Application::quit()
|
||||||
|
{
|
||||||
|
if (!nowQuitting) {
|
||||||
|
nowQuitting = true;
|
||||||
|
emit quitting();
|
||||||
|
|
||||||
|
writeSettings();
|
||||||
|
for (Conversations::const_iterator itr = conversations.begin(), end = conversations.end(); itr != end; ++itr) {
|
||||||
|
disconnect(itr->second, &Conversation::destroyed, this, &Application::onConversationClosed);
|
||||||
|
itr->second->close();
|
||||||
|
}
|
||||||
|
conversations.clear();
|
||||||
|
dialogueQueue.quit();
|
||||||
|
|
||||||
|
if (squawk != nullptr) {
|
||||||
|
squawk->close();
|
||||||
|
}
|
||||||
|
if (!destroyingSquawk) {
|
||||||
|
checkForTheLastWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::checkForTheLastWindow()
|
||||||
|
{
|
||||||
|
if (QApplication::topLevelWidgets().size() > 0) {
|
||||||
|
emit readyToQuit();
|
||||||
|
} else {
|
||||||
|
connect(qApp, &QApplication::lastWindowClosed, this, &Application::readyToQuit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::createMainWindow()
|
||||||
|
{
|
||||||
|
if (squawk == nullptr) {
|
||||||
|
squawk = new Squawk(roster);
|
||||||
|
|
||||||
|
connect(squawk, &Squawk::notify, this, &Application::notify);
|
||||||
|
connect(squawk, &Squawk::changeSubscription, this, &Application::changeSubscription);
|
||||||
|
connect(squawk, &Squawk::openedConversation, this, &Application::onSquawkOpenedConversation);
|
||||||
|
connect(squawk, &Squawk::openConversation, this, &Application::openConversation);
|
||||||
|
connect(squawk, &Squawk::changeState, this, &Application::setState);
|
||||||
|
connect(squawk, &Squawk::closing, this, &Application::onSquawkClosing);
|
||||||
|
|
||||||
|
connect(squawk, &Squawk::modifyAccountRequest, core, &Core::Squawk::modifyAccountRequest);
|
||||||
|
connect(squawk, &Squawk::newAccountRequest, core, &Core::Squawk::newAccountRequest);
|
||||||
|
connect(squawk, &Squawk::removeAccountRequest, core, &Core::Squawk::removeAccountRequest);
|
||||||
|
connect(squawk, &Squawk::connectAccount, core, &Core::Squawk::connectAccount);
|
||||||
|
connect(squawk, &Squawk::disconnectAccount, core, &Core::Squawk::disconnectAccount);
|
||||||
|
|
||||||
|
connect(squawk, &Squawk::addContactRequest, core, &Core::Squawk::addContactRequest);
|
||||||
|
connect(squawk, &Squawk::removeContactRequest, core, &Core::Squawk::removeContactRequest);
|
||||||
|
connect(squawk, &Squawk::removeRoomRequest, core, &Core::Squawk::removeRoomRequest);
|
||||||
|
connect(squawk, &Squawk::addRoomRequest, core, &Core::Squawk::addRoomRequest);
|
||||||
|
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::changeDownloadsPath, core, &Core::Squawk::changeDownloadsPath);
|
||||||
|
|
||||||
|
connect(core, &Core::Squawk::responseVCard, squawk, &Squawk::responseVCard);
|
||||||
|
|
||||||
|
dialogueQueue.setParentWidnow(squawk);
|
||||||
|
squawk->stateChanged(availability);
|
||||||
|
squawk->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::onSquawkClosing()
|
||||||
|
{
|
||||||
|
dialogueQueue.setParentWidnow(nullptr);
|
||||||
|
|
||||||
|
disconnect(core, &Core::Squawk::responseVCard, squawk, &Squawk::responseVCard);
|
||||||
|
|
||||||
|
destroyingSquawk = true;
|
||||||
|
squawk->deleteLater();
|
||||||
|
squawk = nullptr;
|
||||||
|
|
||||||
|
//for now
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::onSquawkDestroyed() {
|
||||||
|
destroyingSquawk = false;
|
||||||
|
if (nowQuitting) {
|
||||||
|
checkForTheLastWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Application::notify(const QString& account, const Shared::Message& msg)
|
||||||
|
{
|
||||||
|
QString name = QString(roster.getContactName(account, msg.getPenPalJid()));
|
||||||
|
QString path = QString(roster.getContactIconPath(account, msg.getPenPalJid(), msg.getPenPalResource()));
|
||||||
|
QVariantList args;
|
||||||
|
args << QString();
|
||||||
|
|
||||||
|
args << qHash(msg.getId());
|
||||||
|
if (path.size() > 0) {
|
||||||
|
args << path;
|
||||||
|
} else {
|
||||||
|
args << QString("mail-message"); //TODO should here better be unknown user icon?
|
||||||
|
}
|
||||||
|
if (msg.getType() == Shared::Message::groupChat) {
|
||||||
|
args << msg.getFromResource() + " from " + name;
|
||||||
|
} else {
|
||||||
|
args << name;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString body(msg.getBody());
|
||||||
|
QString oob(msg.getOutOfBandUrl());
|
||||||
|
if (body == oob) {
|
||||||
|
body = tr("Attached file");
|
||||||
|
}
|
||||||
|
|
||||||
|
args << body;
|
||||||
|
args << QStringList();
|
||||||
|
args << QVariantMap({
|
||||||
|
{"desktop-entry", QString(QCoreApplication::applicationName())},
|
||||||
|
{"category", QString("message")},
|
||||||
|
// {"sound-file", "/path/to/macaw/squawk"},
|
||||||
|
{"sound-name", QString("message-new-instant")}
|
||||||
|
});
|
||||||
|
args << -1;
|
||||||
|
notifications.callWithArgumentList(QDBus::AutoDetect, "Notify", args);
|
||||||
|
|
||||||
|
if (squawk != nullptr) {
|
||||||
|
QApplication::alert(squawk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::setState(Shared::Availability p_availability)
|
||||||
|
{
|
||||||
|
if (availability != p_availability) {
|
||||||
|
availability = p_availability;
|
||||||
|
emit changeState(availability);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::stateChanged(Shared::Availability state)
|
||||||
|
{
|
||||||
|
availability = state;
|
||||||
|
if (squawk != nullptr) {
|
||||||
|
squawk->stateChanged(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::readSettings()
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
settings.beginGroup("ui");
|
||||||
|
int avail;
|
||||||
|
if (settings.contains("availability")) {
|
||||||
|
avail = settings.value("availability").toInt();
|
||||||
|
} else {
|
||||||
|
avail = static_cast<int>(Shared::Availability::online);
|
||||||
|
}
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
setState(Shared::Global::fromInt<Shared::Availability>(avail));
|
||||||
|
createMainWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::writeSettings()
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
settings.setValue("availability", static_cast<int>(availability));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::requestPassword(const QString& account, bool authenticationError) {
|
||||||
|
if (authenticationError) {
|
||||||
|
dialogueQueue.addAction(account, DialogQueue::askCredentials);
|
||||||
|
} else {
|
||||||
|
dialogueQueue.addAction(account, DialogQueue::askPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
void Application::onConversationClosed()
|
||||||
|
{
|
||||||
|
Conversation* conv = static_cast<Conversation*>(sender());
|
||||||
|
Models::Roster::ElId id(conv->getAccount(), conv->getJid());
|
||||||
|
Conversations::const_iterator itr = conversations.find(id);
|
||||||
|
if (itr != conversations.end()) {
|
||||||
|
conversations.erase(itr);
|
||||||
|
}
|
||||||
|
if (conv->isMuc) {
|
||||||
|
Room* room = static_cast<Room*>(conv);
|
||||||
|
if (!room->autoJoined()) {
|
||||||
|
emit setRoomJoined(id.account, id.name, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::changeSubscription(const Models::Roster::ElId& id, bool subscribe)
|
||||||
|
{
|
||||||
|
Models::Item::Type type = roster.getContactType(id);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case Models::Item::contact:
|
||||||
|
if (subscribe) {
|
||||||
|
emit subscribeContact(id.account, id.name, "");
|
||||||
|
} else {
|
||||||
|
emit unsubscribeContact(id.account, id.name, "");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Models::Item::room:
|
||||||
|
setRoomAutoJoin(id.account, id.name, subscribe);
|
||||||
|
if (!isConverstationOpened(id)) {
|
||||||
|
emit setRoomJoined(id.account, id.name, subscribe);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::subscribeConversation(Conversation* conv)
|
||||||
|
{
|
||||||
|
connect(conv, &Conversation::destroyed, this, &Application::onConversationClosed);
|
||||||
|
connect(conv, &Conversation::sendMessage, this, &Application::onConversationMessage);
|
||||||
|
connect(conv, &Conversation::replaceMessage, this, &Application::onConversationReplaceMessage);
|
||||||
|
connect(conv, &Conversation::resendMessage, this, &Application::onConversationResend);
|
||||||
|
connect(conv, &Conversation::notifyableMessage, this, &Application::notify);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::openConversation(const Models::Roster::ElId& id, const QString& resource)
|
||||||
|
{
|
||||||
|
Conversations::const_iterator itr = conversations.find(id);
|
||||||
|
Models::Account* acc = roster.getAccount(id.account);
|
||||||
|
Conversation* conv = nullptr;
|
||||||
|
bool created = false;
|
||||||
|
if (itr != conversations.end()) {
|
||||||
|
conv = itr->second;
|
||||||
|
} else {
|
||||||
|
Models::Element* el = roster.getElement(id);
|
||||||
|
if (el != NULL) {
|
||||||
|
if (el->type == Models::Item::room) {
|
||||||
|
created = true;
|
||||||
|
Models::Room* room = static_cast<Models::Room*>(el);
|
||||||
|
conv = new Room(acc, room);
|
||||||
|
if (!room->getJoined()) {
|
||||||
|
emit setRoomJoined(id.account, id.name, true);
|
||||||
|
}
|
||||||
|
} else if (el->type == Models::Item::contact) {
|
||||||
|
created = true;
|
||||||
|
conv = new Chat(acc, static_cast<Models::Contact*>(el));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conv != nullptr) {
|
||||||
|
if (created) {
|
||||||
|
conv->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
subscribeConversation(conv);
|
||||||
|
conversations.insert(std::make_pair(id, conv));
|
||||||
|
}
|
||||||
|
|
||||||
|
conv->show();
|
||||||
|
conv->raise();
|
||||||
|
conv->activateWindow();
|
||||||
|
|
||||||
|
if (resource.size() > 0) {
|
||||||
|
conv->setPalResource(resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::onConversationMessage(const Shared::Message& msg)
|
||||||
|
{
|
||||||
|
Conversation* conv = static_cast<Conversation*>(sender());
|
||||||
|
QString acc = conv->getAccount();
|
||||||
|
|
||||||
|
roster.addMessage(acc, msg);
|
||||||
|
emit sendMessage(acc, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::onConversationReplaceMessage(const QString& originalId, const Shared::Message& msg)
|
||||||
|
{
|
||||||
|
Conversation* conv = static_cast<Conversation*>(sender());
|
||||||
|
QString acc = conv->getAccount();
|
||||||
|
|
||||||
|
roster.changeMessage(acc, msg.getPenPalJid(), originalId, {
|
||||||
|
{"state", static_cast<uint>(Shared::Message::State::pending)}
|
||||||
|
});
|
||||||
|
emit replaceMessage(acc, originalId, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::onConversationResend(const QString& id)
|
||||||
|
{
|
||||||
|
Conversation* conv = static_cast<Conversation*>(sender());
|
||||||
|
QString acc = conv->getAccount();
|
||||||
|
QString jid = conv->getJid();
|
||||||
|
|
||||||
|
emit resendMessage(acc, jid, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::onSquawkOpenedConversation() {
|
||||||
|
subscribeConversation(squawk->currentConversation);
|
||||||
|
Models::Roster::ElId id = squawk->currentConversationId();
|
||||||
|
|
||||||
|
const Models::Element* el = roster.getElementConst(id);
|
||||||
|
if (el != NULL && el->isRoom() && !static_cast<const Models::Room*>(el)->getJoined()) {
|
||||||
|
emit setRoomJoined(id.account, id.name, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::removeAccount(const QString& account)
|
||||||
|
{
|
||||||
|
Conversations::const_iterator itr = conversations.begin();
|
||||||
|
while (itr != conversations.end()) {
|
||||||
|
if (itr->first.account == account) {
|
||||||
|
Conversations::const_iterator lItr = itr;
|
||||||
|
++itr;
|
||||||
|
Conversation* conv = lItr->second;
|
||||||
|
disconnect(conv, &Conversation::destroyed, this, &Application::onConversationClosed);
|
||||||
|
conv->close();
|
||||||
|
conversations.erase(lItr);
|
||||||
|
} else {
|
||||||
|
++itr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (squawk != nullptr && squawk->currentConversationId().account == account) {
|
||||||
|
squawk->closeCurrentConversation();
|
||||||
|
}
|
||||||
|
|
||||||
|
roster.removeAccount(account);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::changeAccount(const QString& account, const QMap<QString, QVariant>& data)
|
||||||
|
{
|
||||||
|
for (QMap<QString, QVariant>::const_iterator itr = data.begin(), end = data.end(); itr != end; ++itr) {
|
||||||
|
QString attr = itr.key();
|
||||||
|
roster.updateAccount(account, attr, *itr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::addContact(const QString& account, const QString& jid, const QString& group, const QMap<QString, QVariant>& data)
|
||||||
|
{
|
||||||
|
roster.addContact(account, jid, group, data);
|
||||||
|
|
||||||
|
if (squawk != nullptr) {
|
||||||
|
QSettings settings;
|
||||||
|
settings.beginGroup("ui");
|
||||||
|
settings.beginGroup("roster");
|
||||||
|
settings.beginGroup(account);
|
||||||
|
if (settings.value("expanded", false).toBool()) {
|
||||||
|
QModelIndex ind = roster.getAccountIndex(account);
|
||||||
|
squawk->expand(ind);
|
||||||
|
}
|
||||||
|
settings.endGroup();
|
||||||
|
settings.endGroup();
|
||||||
|
settings.endGroup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::addGroup(const QString& account, const QString& name)
|
||||||
|
{
|
||||||
|
roster.addGroup(account, name);
|
||||||
|
|
||||||
|
if (squawk != nullptr) {
|
||||||
|
QSettings settings;
|
||||||
|
settings.beginGroup("ui");
|
||||||
|
settings.beginGroup("roster");
|
||||||
|
settings.beginGroup(account);
|
||||||
|
if (settings.value("expanded", false).toBool()) {
|
||||||
|
QModelIndex ind = roster.getAccountIndex(account);
|
||||||
|
squawk->expand(ind);
|
||||||
|
if (settings.value(name + "/expanded", false).toBool()) {
|
||||||
|
squawk->expand(roster.getGroupIndex(account, name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
settings.endGroup();
|
||||||
|
settings.endGroup();
|
||||||
|
settings.endGroup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Application::isConverstationOpened(const Models::Roster::ElId& id) const {
|
||||||
|
return (conversations.count(id) > 0) || (squawk != nullptr && squawk->currentConversationId() == id);}
|
111
main/application.h
Normal file
111
main/application.h
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
// Squawk messenger.
|
||||||
|
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef APPLICATION_H
|
||||||
|
#define APPLICATION_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QDBusInterface>
|
||||||
|
|
||||||
|
#include "dialogqueue.h"
|
||||||
|
#include "core/squawk.h"
|
||||||
|
|
||||||
|
#include "ui/squawk.h"
|
||||||
|
#include "ui/models/roster.h"
|
||||||
|
#include "ui/widgets/conversation.h"
|
||||||
|
|
||||||
|
#include "shared/message.h"
|
||||||
|
#include "shared/enums.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo write docs
|
||||||
|
*/
|
||||||
|
class Application : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
Application(Core::Squawk* core);
|
||||||
|
~Application();
|
||||||
|
|
||||||
|
bool isConverstationOpened(const Models::Roster::ElId& id) const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void sendMessage(const QString& account, const Shared::Message& data);
|
||||||
|
void replaceMessage(const QString& account, const QString& originalId, const Shared::Message& data);
|
||||||
|
void resendMessage(const QString& account, const QString& jid, const QString& id);
|
||||||
|
|
||||||
|
void changeState(Shared::Availability state);
|
||||||
|
|
||||||
|
void setRoomJoined(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 unsubscribeContact(const QString& account, const QString& jid, const QString& reason);
|
||||||
|
|
||||||
|
void quitting();
|
||||||
|
void readyToQuit();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void readSettings();
|
||||||
|
void quit();
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void notify(const QString& account, const Shared::Message& msg);
|
||||||
|
void setState(Shared::Availability availability);
|
||||||
|
|
||||||
|
void changeAccount(const QString& account, const QMap<QString, QVariant>& data);
|
||||||
|
void removeAccount(const QString& account);
|
||||||
|
void openConversation(const Models::Roster::ElId& id, const QString& resource = "");
|
||||||
|
|
||||||
|
void addGroup(const QString& account, const QString& name);
|
||||||
|
void addContact(const QString& account, const QString& jid, const QString& group, const QMap<QString, QVariant>& data);
|
||||||
|
|
||||||
|
void requestPassword(const QString& account, bool authenticationError);
|
||||||
|
|
||||||
|
void writeSettings();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onConversationClosed();
|
||||||
|
void changeSubscription(const Models::Roster::ElId& id, bool subscribe);
|
||||||
|
void onSquawkOpenedConversation();
|
||||||
|
void onConversationMessage(const Shared::Message& msg);
|
||||||
|
void onConversationReplaceMessage(const QString& originalId, const Shared::Message& msg);
|
||||||
|
void onConversationResend(const QString& id);
|
||||||
|
void stateChanged(Shared::Availability state);
|
||||||
|
void onSquawkClosing();
|
||||||
|
void onSquawkDestroyed();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void createMainWindow();
|
||||||
|
void subscribeConversation(Conversation* conv);
|
||||||
|
void checkForTheLastWindow();
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::map<Models::Roster::ElId, Conversation*> Conversations;
|
||||||
|
|
||||||
|
Shared::Availability availability;
|
||||||
|
Core::Squawk* core;
|
||||||
|
Squawk* squawk;
|
||||||
|
QDBusInterface notifications;
|
||||||
|
Models::Roster roster;
|
||||||
|
Conversations conversations;
|
||||||
|
DialogQueue dialogueQueue;
|
||||||
|
bool nowQuitting;
|
||||||
|
bool destroyingSquawk;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // APPLICATION_H
|
@ -15,10 +15,9 @@
|
|||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include "dialogqueue.h"
|
#include "dialogqueue.h"
|
||||||
#include "squawk.h"
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
DialogQueue::DialogQueue(Squawk* p_squawk):
|
DialogQueue::DialogQueue(const Models::Roster& p_roster):
|
||||||
QObject(),
|
QObject(),
|
||||||
currentSource(),
|
currentSource(),
|
||||||
currentAction(none),
|
currentAction(none),
|
||||||
@ -26,7 +25,8 @@ DialogQueue::DialogQueue(Squawk* p_squawk):
|
|||||||
collection(queue.get<0>()),
|
collection(queue.get<0>()),
|
||||||
sequence(queue.get<1>()),
|
sequence(queue.get<1>()),
|
||||||
prompt(nullptr),
|
prompt(nullptr),
|
||||||
squawk(p_squawk)
|
parent(nullptr),
|
||||||
|
roster(p_roster)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +34,19 @@ DialogQueue::~DialogQueue()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogQueue::quit()
|
||||||
|
{
|
||||||
|
queue.clear();
|
||||||
|
if (currentAction != none) {
|
||||||
|
actionDone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogQueue::setParentWidnow(QMainWindow* p_parent)
|
||||||
|
{
|
||||||
|
parent = p_parent;
|
||||||
|
}
|
||||||
|
|
||||||
bool DialogQueue::addAction(const QString& source, DialogQueue::Action action)
|
bool DialogQueue::addAction(const QString& source, DialogQueue::Action action)
|
||||||
{
|
{
|
||||||
if (action == none) {
|
if (action == none) {
|
||||||
@ -77,7 +90,7 @@ void DialogQueue::performNextAction()
|
|||||||
actionDone();
|
actionDone();
|
||||||
break;
|
break;
|
||||||
case askPassword: {
|
case askPassword: {
|
||||||
QInputDialog* dialog = new QInputDialog(squawk);
|
QInputDialog* dialog = new QInputDialog(parent);
|
||||||
prompt = dialog;
|
prompt = dialog;
|
||||||
connect(dialog, &QDialog::accepted, this, &DialogQueue::onPropmtAccepted);
|
connect(dialog, &QDialog::accepted, this, &DialogQueue::onPropmtAccepted);
|
||||||
connect(dialog, &QDialog::rejected, this, &DialogQueue::onPropmtRejected);
|
connect(dialog, &QDialog::rejected, this, &DialogQueue::onPropmtRejected);
|
||||||
@ -90,11 +103,11 @@ void DialogQueue::performNextAction()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case askCredentials: {
|
case askCredentials: {
|
||||||
CredentialsPrompt* dialog = new CredentialsPrompt(squawk);
|
CredentialsPrompt* dialog = new CredentialsPrompt(parent);
|
||||||
prompt = dialog;
|
prompt = dialog;
|
||||||
connect(dialog, &QDialog::accepted, this, &DialogQueue::onPropmtAccepted);
|
connect(dialog, &QDialog::accepted, this, &DialogQueue::onPropmtAccepted);
|
||||||
connect(dialog, &QDialog::rejected, this, &DialogQueue::onPropmtRejected);
|
connect(dialog, &QDialog::rejected, this, &DialogQueue::onPropmtRejected);
|
||||||
Models::Account* acc = squawk->rosterModel.getAccount(currentSource);
|
const Models::Account* acc = roster.getAccountConst(currentSource);
|
||||||
dialog->setAccount(currentSource);
|
dialog->setAccount(currentSource);
|
||||||
dialog->setLogin(acc->getLogin());
|
dialog->setLogin(acc->getLogin());
|
||||||
dialog->setPassword(acc->getPassword());
|
dialog->setPassword(acc->getPassword());
|
||||||
@ -111,12 +124,12 @@ void DialogQueue::onPropmtAccepted()
|
|||||||
break;
|
break;
|
||||||
case askPassword: {
|
case askPassword: {
|
||||||
QInputDialog* dialog = static_cast<QInputDialog*>(prompt);
|
QInputDialog* dialog = static_cast<QInputDialog*>(prompt);
|
||||||
emit squawk->responsePassword(currentSource, dialog->textValue());
|
emit responsePassword(currentSource, dialog->textValue());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case askCredentials: {
|
case askCredentials: {
|
||||||
CredentialsPrompt* dialog = static_cast<CredentialsPrompt*>(prompt);
|
CredentialsPrompt* dialog = static_cast<CredentialsPrompt*>(prompt);
|
||||||
emit squawk->modifyAccountRequest(currentSource, {
|
emit modifyAccountRequest(currentSource, {
|
||||||
{"login", dialog->getLogin()},
|
{"login", dialog->getLogin()},
|
||||||
{"password", dialog->getPassword()}
|
{"password", dialog->getPassword()}
|
||||||
});
|
});
|
||||||
@ -133,7 +146,7 @@ void DialogQueue::onPropmtRejected()
|
|||||||
break;
|
break;
|
||||||
case askPassword:
|
case askPassword:
|
||||||
case askCredentials:
|
case askCredentials:
|
||||||
emit squawk->disconnectAccount(currentSource);
|
emit disconnectAccount(currentSource);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
actionDone();
|
actionDone();
|
@ -19,14 +19,14 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
|
#include <QMainWindow>
|
||||||
|
|
||||||
#include <boost/multi_index_container.hpp>
|
#include <boost/multi_index_container.hpp>
|
||||||
#include <boost/multi_index/ordered_index.hpp>
|
#include <boost/multi_index/ordered_index.hpp>
|
||||||
#include <boost/multi_index/sequenced_index.hpp>
|
#include <boost/multi_index/sequenced_index.hpp>
|
||||||
|
|
||||||
#include <ui/widgets/accounts/credentialsprompt.h>
|
#include <ui/widgets/accounts/credentialsprompt.h>
|
||||||
|
#include <ui/models/roster.h>
|
||||||
class Squawk;
|
|
||||||
|
|
||||||
class DialogQueue : public QObject
|
class DialogQueue : public QObject
|
||||||
{
|
{
|
||||||
@ -38,12 +38,21 @@ public:
|
|||||||
askCredentials
|
askCredentials
|
||||||
};
|
};
|
||||||
|
|
||||||
DialogQueue(Squawk* squawk);
|
DialogQueue(const Models::Roster& roster);
|
||||||
~DialogQueue();
|
~DialogQueue();
|
||||||
|
|
||||||
bool addAction(const QString& source, Action action);
|
bool addAction(const QString& source, Action action);
|
||||||
bool cancelAction(const QString& source, Action action);
|
bool cancelAction(const QString& source, Action action);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void modifyAccountRequest(const QString&, const QMap<QString, QVariant>&);
|
||||||
|
void responsePassword(const QString& account, const QString& password);
|
||||||
|
void disconnectAccount(const QString&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
void setParentWidnow(QMainWindow* parent);
|
||||||
|
void quit();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void performNextAction();
|
void performNextAction();
|
||||||
void actionDone();
|
void actionDone();
|
||||||
@ -85,7 +94,8 @@ private:
|
|||||||
Sequence& sequence;
|
Sequence& sequence;
|
||||||
|
|
||||||
QDialog* prompt;
|
QDialog* prompt;
|
||||||
Squawk* squawk;
|
QMainWindow* parent;
|
||||||
|
const Models::Roster& roster;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DIALOGQUEUE_H
|
#endif // DIALOGQUEUE_H
|
139
main/main.cpp
Normal file
139
main/main.cpp
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* Squawk messenger.
|
||||||
|
* Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shared/global.h"
|
||||||
|
#include "shared/messageinfo.h"
|
||||||
|
#include "shared/pathcheck.h"
|
||||||
|
#include "main/application.h"
|
||||||
|
#include "core/signalcatcher.h"
|
||||||
|
#include "core/squawk.h"
|
||||||
|
|
||||||
|
#include <QLibraryInfo>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
#include <QTranslator>
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtCore/QThread>
|
||||||
|
#include <QtWidgets/QApplication>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
qRegisterMetaType<Shared::Message>("Shared::Message");
|
||||||
|
qRegisterMetaType<Shared::MessageInfo>("Shared::MessageInfo");
|
||||||
|
qRegisterMetaType<Shared::VCard>("Shared::VCard");
|
||||||
|
qRegisterMetaType<std::list<Shared::Message>>("std::list<Shared::Message>");
|
||||||
|
qRegisterMetaType<std::list<Shared::MessageInfo>>("std::list<Shared::MessageInfo>");
|
||||||
|
qRegisterMetaType<QSet<QString>>("QSet<QString>");
|
||||||
|
qRegisterMetaType<Shared::ConnectionState>("Shared::ConnectionState");
|
||||||
|
qRegisterMetaType<Shared::Availability>("Shared::Availability");
|
||||||
|
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
SignalCatcher sc(&app);
|
||||||
|
|
||||||
|
QApplication::setApplicationName("squawk");
|
||||||
|
QApplication::setOrganizationName("macaw.me");
|
||||||
|
QApplication::setApplicationDisplayName("Squawk");
|
||||||
|
QApplication::setApplicationVersion("0.2.2");
|
||||||
|
|
||||||
|
QTranslator qtTranslator;
|
||||||
|
qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
|
||||||
|
app.installTranslator(&qtTranslator);
|
||||||
|
|
||||||
|
QTranslator myappTranslator;
|
||||||
|
QStringList shares = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
|
||||||
|
bool found = false;
|
||||||
|
for (QString share : shares) {
|
||||||
|
found = myappTranslator.load(QLocale(), QLatin1String("squawk"), ".", share + "/l10n");
|
||||||
|
if (found) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
myappTranslator.load(QLocale(), QLatin1String("squawk"), ".", QCoreApplication::applicationDirPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
app.installTranslator(&myappTranslator);
|
||||||
|
|
||||||
|
QIcon icon;
|
||||||
|
icon.addFile(":images/logo.svg", QSize(16, 16));
|
||||||
|
icon.addFile(":images/logo.svg", QSize(24, 24));
|
||||||
|
icon.addFile(":images/logo.svg", QSize(32, 32));
|
||||||
|
icon.addFile(":images/logo.svg", QSize(48, 48));
|
||||||
|
icon.addFile(":images/logo.svg", QSize(64, 64));
|
||||||
|
icon.addFile(":images/logo.svg", QSize(96, 96));
|
||||||
|
icon.addFile(":images/logo.svg", QSize(128, 128));
|
||||||
|
icon.addFile(":images/logo.svg", QSize(256, 256));
|
||||||
|
icon.addFile(":images/logo.svg", QSize(512, 512));
|
||||||
|
QApplication::setWindowIcon(icon);
|
||||||
|
|
||||||
|
new Shared::Global(); //translates enums
|
||||||
|
|
||||||
|
QSettings settings;
|
||||||
|
QVariant vs = settings.value("style");
|
||||||
|
if (vs.isValid()) {
|
||||||
|
QString style = vs.toString().toLower();
|
||||||
|
if (style != "system") {
|
||||||
|
Shared::Global::setStyle(style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Shared::Global::supported("colorSchemeTools")) {
|
||||||
|
QVariant vt = settings.value("theme");
|
||||||
|
if (vt.isValid()) {
|
||||||
|
QString theme = vt.toString();
|
||||||
|
if (theme.toLower() != "system") {
|
||||||
|
Shared::Global::setTheme(theme);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QString path = Shared::downloadsPathCheck();
|
||||||
|
if (path.size() > 0) {
|
||||||
|
settings.setValue("downloadsPath", path);
|
||||||
|
} else {
|
||||||
|
qDebug() << "couldn't initialize directory for downloads, quitting";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Core::Squawk* squawk = new Core::Squawk();
|
||||||
|
QThread* coreThread = new QThread();
|
||||||
|
squawk->moveToThread(coreThread);
|
||||||
|
|
||||||
|
Application application(squawk);
|
||||||
|
|
||||||
|
QObject::connect(&sc, &SignalCatcher::interrupt, &application, &Application::quit);
|
||||||
|
|
||||||
|
QObject::connect(coreThread, &QThread::started, squawk, &Core::Squawk::start);
|
||||||
|
QObject::connect(&application, &Application::quitting, squawk, &Core::Squawk::stop);
|
||||||
|
//QObject::connect(&app, &QApplication::aboutToQuit, &w, &QMainWindow::close);
|
||||||
|
QObject::connect(squawk, &Core::Squawk::quit, squawk, &Core::Squawk::deleteLater);
|
||||||
|
QObject::connect(squawk, &Core::Squawk::destroyed, coreThread, &QThread::quit, Qt::QueuedConnection);
|
||||||
|
QObject::connect(coreThread, &QThread::finished, &app, &QApplication::quit, Qt::QueuedConnection);
|
||||||
|
|
||||||
|
coreThread->start();
|
||||||
|
int result = app.exec();
|
||||||
|
|
||||||
|
if (coreThread->isRunning()) {
|
||||||
|
//coreThread->wait();
|
||||||
|
//todo if I uncomment that, the app will not quit if it has reconnected at least once
|
||||||
|
//it feels like a symptom of something badly desinged in the core thread
|
||||||
|
//need to investigate;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
@ -95,8 +95,6 @@ Shared::Global::Global():
|
|||||||
}),
|
}),
|
||||||
defaultSystemStyle(QApplication::style()->objectName()),
|
defaultSystemStyle(QApplication::style()->objectName()),
|
||||||
defaultSystemPalette(QApplication::palette()),
|
defaultSystemPalette(QApplication::palette()),
|
||||||
rosterModel(new Models::Roster()),
|
|
||||||
dbus("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", QDBusConnection::sessionBus()),
|
|
||||||
pluginSupport({
|
pluginSupport({
|
||||||
{"KWallet", false},
|
{"KWallet", false},
|
||||||
{"openFileManagerWindowJob", false},
|
{"openFileManagerWindowJob", false},
|
||||||
@ -352,44 +350,6 @@ void Shared::Global::setStyle(const QString& style)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shared::Global::notify(const QString& account, const Shared::Message& msg)
|
|
||||||
{
|
|
||||||
QString name = QString(instance->rosterModel->getContactName(account, msg.getPenPalJid()));
|
|
||||||
QString path = QString(instance->rosterModel->getContactIconPath(account, msg.getPenPalJid(), msg.getPenPalResource()));
|
|
||||||
QVariantList args;
|
|
||||||
args << QString();
|
|
||||||
|
|
||||||
args << qHash(msg.getId());
|
|
||||||
if (path.size() > 0) {
|
|
||||||
args << path;
|
|
||||||
} else {
|
|
||||||
args << QString("mail-message"); //TODO should here better be unknown user icon?
|
|
||||||
}
|
|
||||||
if (msg.getType() == Shared::Message::groupChat) {
|
|
||||||
args << msg.getFromResource() + " from " + name;
|
|
||||||
} else {
|
|
||||||
args << name;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString body(msg.getBody());
|
|
||||||
QString oob(msg.getOutOfBandUrl());
|
|
||||||
if (body == oob) {
|
|
||||||
body = tr("Attached file");
|
|
||||||
}
|
|
||||||
|
|
||||||
args << body;
|
|
||||||
args << QStringList();
|
|
||||||
args << QVariantMap({
|
|
||||||
{"desktop-entry", QString(QCoreApplication::applicationName())},
|
|
||||||
{"category", QString("message")},
|
|
||||||
// {"sound-file", "/path/to/macaw/squawk"},
|
|
||||||
{"sound-name", QString("message-new-instant")}
|
|
||||||
});
|
|
||||||
args << -1;
|
|
||||||
instance->dbus.callWithArgumentList(QDBus::AutoDetect, "Notify", args);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define FROM_INT_INPL(Enum) \
|
#define FROM_INT_INPL(Enum) \
|
||||||
template<> \
|
template<> \
|
||||||
Enum Shared::Global::fromInt(int src) \
|
Enum Shared::Global::fromInt(int src) \
|
||||||
|
@ -42,18 +42,11 @@
|
|||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QDBusInterface>
|
|
||||||
|
|
||||||
class Squawk;
|
|
||||||
namespace Models {
|
|
||||||
class Roster;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Shared {
|
namespace Shared {
|
||||||
|
|
||||||
class Global {
|
class Global {
|
||||||
Q_DECLARE_TR_FUNCTIONS(Global)
|
Q_DECLARE_TR_FUNCTIONS(Global)
|
||||||
friend class ::Squawk;
|
|
||||||
public:
|
public:
|
||||||
struct FileInfo {
|
struct FileInfo {
|
||||||
enum class Preview {
|
enum class Preview {
|
||||||
@ -71,8 +64,6 @@ namespace Shared {
|
|||||||
|
|
||||||
Global();
|
Global();
|
||||||
|
|
||||||
static void notify(const QString& account, const Shared::Message& msg);
|
|
||||||
|
|
||||||
static Global* getInstance();
|
static Global* getInstance();
|
||||||
static QString getName(Availability av);
|
static QString getName(Availability av);
|
||||||
static QString getName(ConnectionState cs);
|
static QString getName(ConnectionState cs);
|
||||||
@ -130,8 +121,6 @@ namespace Shared {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static Global* instance;
|
static Global* instance;
|
||||||
Models::Roster* rosterModel;
|
|
||||||
QDBusInterface dbus;
|
|
||||||
|
|
||||||
std::map<QString, bool> pluginSupport;
|
std::map<QString, bool> pluginSupport;
|
||||||
std::map<QString, FileInfo> fileCache;
|
std::map<QString, FileInfo> fileCache;
|
||||||
|
@ -2,8 +2,6 @@ target_sources(squawk PRIVATE
|
|||||||
squawk.cpp
|
squawk.cpp
|
||||||
squawk.h
|
squawk.h
|
||||||
squawk.ui
|
squawk.ui
|
||||||
dialogqueue.cpp
|
|
||||||
dialogqueue.h
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(models)
|
add_subdirectory(models)
|
||||||
|
@ -927,11 +927,29 @@ QString Models::Roster::getContactIconPath(const QString& account, const QString
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
Models::Account * Models::Roster::getAccount(const QString& name)
|
Models::Account * Models::Roster::getAccount(const QString& name) {
|
||||||
|
return const_cast<Models::Account*>(getAccountConst(name));}
|
||||||
|
|
||||||
|
const Models::Account * Models::Roster::getAccountConst(const QString& name) const {
|
||||||
|
return accounts.at(name);}
|
||||||
|
|
||||||
|
const Models::Element * Models::Roster::getElementConst(const Models::Roster::ElId& id) const
|
||||||
{
|
{
|
||||||
return accounts.find(name)->second;
|
std::map<ElId, Contact*>::const_iterator cItr = contacts.find(id);
|
||||||
|
|
||||||
|
if (cItr != contacts.end()) {
|
||||||
|
return cItr->second;
|
||||||
|
} else {
|
||||||
|
std::map<ElId, Room*>::const_iterator rItr = rooms.find(id);
|
||||||
|
if (rItr != rooms.end()) {
|
||||||
|
return rItr->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QModelIndex Models::Roster::getAccountIndex(const QString& name)
|
QModelIndex Models::Roster::getAccountIndex(const QString& name)
|
||||||
{
|
{
|
||||||
std::map<QString, Account*>::const_iterator itr = accounts.find(name);
|
std::map<QString, Account*>::const_iterator itr = accounts.find(name);
|
||||||
@ -1005,20 +1023,20 @@ void Models::Roster::fileError(const std::list<Shared::MessageInfo>& msgs, const
|
|||||||
|
|
||||||
Models::Element * Models::Roster::getElement(const Models::Roster::ElId& id)
|
Models::Element * Models::Roster::getElement(const Models::Roster::ElId& id)
|
||||||
{
|
{
|
||||||
std::map<ElId, Contact*>::iterator cItr = contacts.find(id);
|
return const_cast<Models::Element*>(getElementConst(id));
|
||||||
|
|
||||||
if (cItr != contacts.end()) {
|
|
||||||
return cItr->second;
|
|
||||||
} else {
|
|
||||||
std::map<ElId, Room*>::iterator rItr = rooms.find(id);
|
|
||||||
if (rItr != rooms.end()) {
|
|
||||||
return rItr->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Models::Item::Type Models::Roster::getContactType(const Models::Roster::ElId& id) const
|
||||||
|
{
|
||||||
|
const Models::Element* el = getElementConst(id);
|
||||||
|
if (el == NULL) {
|
||||||
|
return Item::root;
|
||||||
|
}
|
||||||
|
|
||||||
|
return el->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Models::Roster::onAccountReconnected()
|
void Models::Roster::onAccountReconnected()
|
||||||
{
|
{
|
||||||
Account* acc = static_cast<Account*>(sender());
|
Account* acc = static_cast<Account*>(sender());
|
||||||
|
@ -46,6 +46,7 @@ public:
|
|||||||
Roster(QObject* parent = 0);
|
Roster(QObject* parent = 0);
|
||||||
~Roster();
|
~Roster();
|
||||||
|
|
||||||
|
public slots:
|
||||||
void addAccount(const QMap<QString, QVariant> &data);
|
void addAccount(const QMap<QString, QVariant> &data);
|
||||||
void updateAccount(const QString& account, const QString& field, const QVariant& value);
|
void updateAccount(const QString& account, const QString& field, const QVariant& value);
|
||||||
void removeAccount(const QString& account);
|
void removeAccount(const QString& account);
|
||||||
@ -65,7 +66,12 @@ public:
|
|||||||
void addRoomParticipant(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
|
void addRoomParticipant(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
|
||||||
void changeRoomParticipant(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
|
void changeRoomParticipant(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
|
||||||
void removeRoomParticipant(const QString& account, const QString& jid, const QString& name);
|
void removeRoomParticipant(const QString& account, const QString& jid, const QString& name);
|
||||||
|
|
||||||
|
public:
|
||||||
QString getContactName(const QString& account, const QString& jid) const;
|
QString getContactName(const QString& account, const QString& jid) const;
|
||||||
|
Item::Type getContactType(const Models::Roster::ElId& id) const;
|
||||||
|
const Element* getElementConst(const ElId& id) const;
|
||||||
|
Element* getElement(const ElId& id);
|
||||||
|
|
||||||
QVariant data ( const QModelIndex& index, int role ) const override;
|
QVariant data ( const QModelIndex& index, int role ) const override;
|
||||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||||
@ -79,6 +85,7 @@ public:
|
|||||||
bool groupHasContact(const QString& account, const QString& group, const QString& contactJID) const;
|
bool groupHasContact(const QString& account, const QString& group, const QString& contactJID) const;
|
||||||
QString getContactIconPath(const QString& account, const QString& jid, const QString& resource) const;
|
QString getContactIconPath(const QString& account, const QString& jid, const QString& resource) const;
|
||||||
Account* getAccount(const QString& name);
|
Account* getAccount(const QString& name);
|
||||||
|
const Account* getAccountConst(const QString& name) const;
|
||||||
QModelIndex getAccountIndex(const QString& name);
|
QModelIndex getAccountIndex(const QString& name);
|
||||||
QModelIndex getGroupIndex(const QString& account, const QString& name);
|
QModelIndex getGroupIndex(const QString& account, const QString& name);
|
||||||
void responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list, bool last);
|
void responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list, bool last);
|
||||||
@ -95,9 +102,6 @@ signals:
|
|||||||
void unnoticedMessage(const QString& account, const Shared::Message& msg);
|
void unnoticedMessage(const QString& account, const Shared::Message& msg);
|
||||||
void localPathInvalid(const QString& path);
|
void localPathInvalid(const QString& path);
|
||||||
|
|
||||||
private:
|
|
||||||
Element* getElement(const ElId& id);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onAccountDataChanged(const QModelIndex& tl, const QModelIndex& br, const QVector<int>& roles);
|
void onAccountDataChanged(const QModelIndex& tl, const QModelIndex& br, const QVector<int>& roles);
|
||||||
void onAccountReconnected();
|
void onAccountReconnected();
|
||||||
|
509
ui/squawk.cpp
509
ui/squawk.cpp
@ -21,15 +21,13 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
|
||||||
Squawk::Squawk(QWidget *parent) :
|
Squawk::Squawk(Models::Roster& p_rosterModel, QWidget *parent) :
|
||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
m_ui(new Ui::Squawk),
|
m_ui(new Ui::Squawk),
|
||||||
accounts(nullptr),
|
accounts(nullptr),
|
||||||
preferences(nullptr),
|
preferences(nullptr),
|
||||||
about(nullptr),
|
about(nullptr),
|
||||||
dialogueQueue(this),
|
rosterModel(p_rosterModel),
|
||||||
rosterModel(*(Shared::Global::getInstance()->rosterModel)),
|
|
||||||
conversations(),
|
|
||||||
contextMenu(new QMenu()),
|
contextMenu(new QMenu()),
|
||||||
vCards(),
|
vCards(),
|
||||||
currentConversation(nullptr),
|
currentConversation(nullptr),
|
||||||
@ -64,12 +62,8 @@ Squawk::Squawk(QWidget *parent) :
|
|||||||
connect(m_ui->roster, &QTreeView::customContextMenuRequested, this, &Squawk::onRosterContextMenu);
|
connect(m_ui->roster, &QTreeView::customContextMenuRequested, this, &Squawk::onRosterContextMenu);
|
||||||
connect(m_ui->roster, &QTreeView::collapsed, this, &Squawk::onItemCollepsed);
|
connect(m_ui->roster, &QTreeView::collapsed, this, &Squawk::onItemCollepsed);
|
||||||
connect(m_ui->roster->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &Squawk::onRosterSelectionChanged);
|
connect(m_ui->roster->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &Squawk::onRosterSelectionChanged);
|
||||||
connect(&rosterModel, &Models::Roster::unnoticedMessage, this, &Squawk::onUnnoticedMessage);
|
|
||||||
|
|
||||||
connect(rosterModel.accountsModel, &Models::Accounts::sizeChanged, this, &Squawk::onAccountsSizeChanged);
|
connect(rosterModel.accountsModel, &Models::Accounts::sizeChanged, this, &Squawk::onAccountsSizeChanged);
|
||||||
connect(&rosterModel, &Models::Roster::requestArchive, this, &Squawk::onRequestArchive);
|
|
||||||
connect(&rosterModel, &Models::Roster::fileDownloadRequest, this, &Squawk::fileDownloadRequest);
|
|
||||||
connect(&rosterModel, &Models::Roster::localPathInvalid, this, &Squawk::localPathInvalid);
|
|
||||||
connect(contextMenu, &QMenu::aboutToHide, this, &Squawk::onContextAboutToHide);
|
connect(contextMenu, &QMenu::aboutToHide, this, &Squawk::onContextAboutToHide);
|
||||||
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);
|
||||||
@ -199,36 +193,25 @@ void Squawk::closeEvent(QCloseEvent* event)
|
|||||||
about->close();
|
about->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Conversations::const_iterator itr = conversations.begin(), end = conversations.end(); itr != end; ++itr) {
|
|
||||||
disconnect(itr->second, &Conversation::destroyed, this, &Squawk::onConversationClosed);
|
|
||||||
itr->second->close();
|
|
||||||
}
|
|
||||||
conversations.clear();
|
|
||||||
|
|
||||||
for (std::map<QString, VCard*>::const_iterator itr = vCards.begin(), end = vCards.end(); itr != end; ++itr) {
|
for (std::map<QString, VCard*>::const_iterator itr = vCards.begin(), end = vCards.end(); itr != end; ++itr) {
|
||||||
disconnect(itr->second, &VCard::destroyed, this, &Squawk::onVCardClosed);
|
disconnect(itr->second, &VCard::destroyed, this, &Squawk::onVCardClosed);
|
||||||
itr->second->close();
|
itr->second->close();
|
||||||
}
|
}
|
||||||
vCards.clear();
|
vCards.clear();
|
||||||
|
writeSettings();
|
||||||
|
emit closing();;
|
||||||
|
|
||||||
QMainWindow::closeEvent(event);
|
QMainWindow::closeEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Squawk::onAccountsClosed() {
|
||||||
|
accounts = nullptr;}
|
||||||
|
|
||||||
void Squawk::onAccountsClosed()
|
void Squawk::onPreferencesClosed() {
|
||||||
{
|
preferences = nullptr;}
|
||||||
accounts = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::onPreferencesClosed()
|
void Squawk::onAboutSquawkClosed() {
|
||||||
{
|
about = nullptr;}
|
||||||
preferences = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::newAccount(const QMap<QString, QVariant>& account)
|
|
||||||
{
|
|
||||||
rosterModel.addAccount(account);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::onComboboxActivated(int index)
|
void Squawk::onComboboxActivated(int index)
|
||||||
{
|
{
|
||||||
@ -236,85 +219,11 @@ void Squawk::onComboboxActivated(int index)
|
|||||||
emit changeState(av);
|
emit changeState(av);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Squawk::changeAccount(const QString& account, const QMap<QString, QVariant>& data)
|
void Squawk::expand(const QModelIndex& index) {
|
||||||
{
|
m_ui->roster->expand(index);}
|
||||||
for (QMap<QString, QVariant>::const_iterator itr = data.begin(), end = data.end(); itr != end; ++itr) {
|
|
||||||
QString attr = itr.key();
|
|
||||||
rosterModel.updateAccount(account, attr, *itr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::addContact(const QString& account, const QString& jid, const QString& group, const QMap<QString, QVariant>& data)
|
void Squawk::stateChanged(Shared::Availability state) {
|
||||||
{
|
m_ui->comboBox->setCurrentIndex(static_cast<int>(state));}
|
||||||
rosterModel.addContact(account, jid, group, data);
|
|
||||||
|
|
||||||
QSettings settings;
|
|
||||||
settings.beginGroup("ui");
|
|
||||||
settings.beginGroup("roster");
|
|
||||||
settings.beginGroup(account);
|
|
||||||
if (settings.value("expanded", false).toBool()) {
|
|
||||||
QModelIndex ind = rosterModel.getAccountIndex(account);
|
|
||||||
m_ui->roster->expand(ind);
|
|
||||||
}
|
|
||||||
settings.endGroup();
|
|
||||||
settings.endGroup();
|
|
||||||
settings.endGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::addGroup(const QString& account, const QString& name)
|
|
||||||
{
|
|
||||||
rosterModel.addGroup(account, name);
|
|
||||||
|
|
||||||
QSettings settings;
|
|
||||||
settings.beginGroup("ui");
|
|
||||||
settings.beginGroup("roster");
|
|
||||||
settings.beginGroup(account);
|
|
||||||
if (settings.value("expanded", false).toBool()) {
|
|
||||||
QModelIndex ind = rosterModel.getAccountIndex(account);
|
|
||||||
m_ui->roster->expand(ind);
|
|
||||||
if (settings.value(name + "/expanded", false).toBool()) {
|
|
||||||
m_ui->roster->expand(rosterModel.getGroupIndex(account, name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
settings.endGroup();
|
|
||||||
settings.endGroup();
|
|
||||||
settings.endGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::removeGroup(const QString& account, const QString& name)
|
|
||||||
{
|
|
||||||
rosterModel.removeGroup(account, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::changeContact(const QString& account, const QString& jid, const QMap<QString, QVariant>& data)
|
|
||||||
{
|
|
||||||
rosterModel.changeContact(account, jid, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::removeContact(const QString& account, const QString& jid)
|
|
||||||
{
|
|
||||||
rosterModel.removeContact(account, jid);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::removeContact(const QString& account, const QString& jid, const QString& group)
|
|
||||||
{
|
|
||||||
rosterModel.removeContact(account, jid, group);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::addPresence(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data)
|
|
||||||
{
|
|
||||||
rosterModel.addPresence(account, jid, name, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::removePresence(const QString& account, const QString& jid, const QString& name)
|
|
||||||
{
|
|
||||||
rosterModel.removePresence(account, jid, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::stateChanged(Shared::Availability state)
|
|
||||||
{
|
|
||||||
m_ui->comboBox->setCurrentIndex(static_cast<int>(state));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
|
void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
|
||||||
{
|
{
|
||||||
@ -325,186 +234,33 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
|
|||||||
}
|
}
|
||||||
Models::Contact* contact = nullptr;
|
Models::Contact* contact = nullptr;
|
||||||
Models::Room* room = nullptr;
|
Models::Room* room = nullptr;
|
||||||
QString res;
|
|
||||||
Models::Roster::ElId* id = nullptr;
|
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case Models::Item::contact:
|
case Models::Item::contact:
|
||||||
contact = static_cast<Models::Contact*>(node);
|
contact = static_cast<Models::Contact*>(node);
|
||||||
id = new Models::Roster::ElId(contact->getAccountName(), contact->getJid());
|
emit openConversation(Models::Roster::ElId(contact->getAccountName(), contact->getJid()));
|
||||||
break;
|
break;
|
||||||
case Models::Item::presence:
|
case Models::Item::presence:
|
||||||
contact = static_cast<Models::Contact*>(node->parentItem());
|
contact = static_cast<Models::Contact*>(node->parentItem());
|
||||||
id = new Models::Roster::ElId(contact->getAccountName(), contact->getJid());
|
emit openConversation(Models::Roster::ElId(contact->getAccountName(), contact->getJid()), node->getName());
|
||||||
res = node->getName();
|
|
||||||
break;
|
break;
|
||||||
case Models::Item::room:
|
case Models::Item::room:
|
||||||
room = static_cast<Models::Room*>(node);
|
room = static_cast<Models::Room*>(node);
|
||||||
id = new Models::Roster::ElId(room->getAccountName(), room->getJid());
|
emit openConversation(Models::Roster::ElId(room->getAccountName(), room->getJid()));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
m_ui->roster->expand(item);
|
m_ui->roster->expand(item);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id != nullptr) {
|
|
||||||
Conversations::const_iterator itr = conversations.find(*id);
|
|
||||||
Models::Account* acc = rosterModel.getAccount(id->account);
|
|
||||||
Conversation* conv = nullptr;
|
|
||||||
bool created = false;
|
|
||||||
if (itr != conversations.end()) {
|
|
||||||
conv = itr->second;
|
|
||||||
} else if (contact != nullptr) {
|
|
||||||
created = true;
|
|
||||||
conv = new Chat(acc, contact);
|
|
||||||
} else if (room != nullptr) {
|
|
||||||
created = true;
|
|
||||||
conv = new Room(acc, room);
|
|
||||||
|
|
||||||
if (!room->getJoined()) {
|
|
||||||
emit setRoomJoined(id->account, id->name, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conv != nullptr) {
|
|
||||||
if (created) {
|
|
||||||
conv->setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
subscribeConversation(conv);
|
|
||||||
conversations.insert(std::make_pair(*id, conv));
|
|
||||||
}
|
|
||||||
|
|
||||||
conv->show();
|
|
||||||
conv->raise();
|
|
||||||
conv->activateWindow();
|
|
||||||
|
|
||||||
if (res.size() > 0) {
|
|
||||||
conv->setPalResource(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete id;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Squawk::onConversationClosed(QObject* parent)
|
void Squawk::closeCurrentConversation()
|
||||||
{
|
{
|
||||||
Conversation* conv = static_cast<Conversation*>(sender());
|
if (currentConversation != nullptr) {
|
||||||
Models::Roster::ElId id(conv->getAccount(), conv->getJid());
|
|
||||||
Conversations::const_iterator itr = conversations.find(id);
|
|
||||||
if (itr != conversations.end()) {
|
|
||||||
conversations.erase(itr);
|
|
||||||
}
|
|
||||||
if (conv->isMuc) {
|
|
||||||
Room* room = static_cast<Room*>(conv);
|
|
||||||
if (!room->autoJoined()) {
|
|
||||||
emit setRoomJoined(id.account, id.name, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::fileProgress(const std::list<Shared::MessageInfo> msgs, qreal value, bool up)
|
|
||||||
{
|
|
||||||
rosterModel.fileProgress(msgs, value, up);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::fileDownloadComplete(const std::list<Shared::MessageInfo> msgs, const QString& path)
|
|
||||||
{
|
|
||||||
rosterModel.fileComplete(msgs, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::fileError(const std::list<Shared::MessageInfo> msgs, const QString& error, bool up)
|
|
||||||
{
|
|
||||||
rosterModel.fileError(msgs, error, up);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::fileUploadComplete(const std::list<Shared::MessageInfo> msgs, const QString& url, const QString& path)
|
|
||||||
{
|
|
||||||
rosterModel.fileComplete(msgs, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::accountMessage(const QString& account, const Shared::Message& data)
|
|
||||||
{
|
|
||||||
rosterModel.addMessage(account, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::onUnnoticedMessage(const QString& account, const Shared::Message& msg)
|
|
||||||
{
|
|
||||||
notify(account, msg); //Telegram does this way - notifies even if the app is visible
|
|
||||||
QApplication::alert(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data)
|
|
||||||
{
|
|
||||||
rosterModel.changeMessage(account, jid, id, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::notify(const QString& account, const Shared::Message& msg)
|
|
||||||
{
|
|
||||||
Shared::Global::notify(account, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::onConversationMessage(const Shared::Message& msg)
|
|
||||||
{
|
|
||||||
Conversation* conv = static_cast<Conversation*>(sender());
|
|
||||||
QString acc = conv->getAccount();
|
|
||||||
|
|
||||||
rosterModel.addMessage(acc, msg);
|
|
||||||
emit sendMessage(acc, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::onConversationReplaceMessage(const QString& originalId, const Shared::Message& msg)
|
|
||||||
{
|
|
||||||
Conversation* conv = static_cast<Conversation*>(sender());
|
|
||||||
QString acc = conv->getAccount();
|
|
||||||
|
|
||||||
rosterModel.changeMessage(acc, msg.getPenPalJid(), originalId, {
|
|
||||||
{"state", static_cast<uint>(Shared::Message::State::pending)}
|
|
||||||
});
|
|
||||||
emit replaceMessage(acc, originalId, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::onConversationResend(const QString& id)
|
|
||||||
{
|
|
||||||
Conversation* conv = static_cast<Conversation*>(sender());
|
|
||||||
QString acc = conv->getAccount();
|
|
||||||
QString jid = conv->getJid();
|
|
||||||
|
|
||||||
emit resendMessage(acc, jid, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::onRequestArchive(const QString& account, const QString& jid, const QString& before)
|
|
||||||
{
|
|
||||||
emit requestArchive(account, jid, 20, before); //TODO amount as a settings value
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list, bool last)
|
|
||||||
{
|
|
||||||
rosterModel.responseArchive(account, jid, list, last);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::removeAccount(const QString& account)
|
|
||||||
{
|
|
||||||
Conversations::const_iterator itr = conversations.begin();
|
|
||||||
while (itr != conversations.end()) {
|
|
||||||
if (itr->first.account == account) {
|
|
||||||
Conversations::const_iterator lItr = itr;
|
|
||||||
++itr;
|
|
||||||
Conversation* conv = lItr->second;
|
|
||||||
disconnect(conv, &Conversation::destroyed, this, &Squawk::onConversationClosed);
|
|
||||||
conv->close();
|
|
||||||
conversations.erase(lItr);
|
|
||||||
} else {
|
|
||||||
++itr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentConversation != nullptr && currentConversation->getAccount() == account) {
|
|
||||||
currentConversation->deleteLater();
|
currentConversation->deleteLater();
|
||||||
currentConversation = nullptr;
|
currentConversation = nullptr;
|
||||||
m_ui->filler->show();
|
m_ui->filler->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
rosterModel.removeAccount(account);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Squawk::onRosterContextMenu(const QPoint& point)
|
void Squawk::onRosterContextMenu(const QPoint& point)
|
||||||
@ -542,13 +298,13 @@ void Squawk::onRosterContextMenu(const QPoint& point)
|
|||||||
break;
|
break;
|
||||||
case Models::Item::contact: {
|
case Models::Item::contact: {
|
||||||
Models::Contact* cnt = static_cast<Models::Contact*>(item);
|
Models::Contact* cnt = static_cast<Models::Contact*>(item);
|
||||||
|
Models::Roster::ElId id(cnt->getAccountName(), cnt->getJid());
|
||||||
|
QString cntName = cnt->getName();
|
||||||
hasMenu = true;
|
hasMenu = true;
|
||||||
|
|
||||||
QAction* dialog = contextMenu->addAction(Shared::icon("mail-message"), tr("Open dialog"));
|
QAction* dialog = contextMenu->addAction(Shared::icon("mail-message"), tr("Open dialog"));
|
||||||
dialog->setEnabled(active);
|
dialog->setEnabled(active);
|
||||||
connect(dialog, &QAction::triggered, [this, index]() {
|
connect(dialog, &QAction::triggered, std::bind(&Squawk::onRosterItemDoubleClicked, this, index));
|
||||||
onRosterItemDoubleClicked(index);
|
|
||||||
});
|
|
||||||
|
|
||||||
Shared::SubscriptionState state = cnt->getState();
|
Shared::SubscriptionState state = cnt->getState();
|
||||||
switch (state) {
|
switch (state) {
|
||||||
@ -556,9 +312,7 @@ void Squawk::onRosterContextMenu(const QPoint& point)
|
|||||||
case Shared::SubscriptionState::to: {
|
case Shared::SubscriptionState::to: {
|
||||||
QAction* unsub = contextMenu->addAction(Shared::icon("news-unsubscribe"), tr("Unsubscribe"));
|
QAction* unsub = contextMenu->addAction(Shared::icon("news-unsubscribe"), tr("Unsubscribe"));
|
||||||
unsub->setEnabled(active);
|
unsub->setEnabled(active);
|
||||||
connect(unsub, &QAction::triggered, [this, cnt]() {
|
connect(unsub, &QAction::triggered, std::bind(&Squawk::changeSubscription, this, id, false));
|
||||||
emit unsubscribeContact(cnt->getAccountName(), cnt->getJid(), "");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Shared::SubscriptionState::from:
|
case Shared::SubscriptionState::from:
|
||||||
@ -566,75 +320,68 @@ void Squawk::onRosterContextMenu(const QPoint& point)
|
|||||||
case Shared::SubscriptionState::none: {
|
case Shared::SubscriptionState::none: {
|
||||||
QAction* sub = contextMenu->addAction(Shared::icon("news-subscribe"), tr("Subscribe"));
|
QAction* sub = contextMenu->addAction(Shared::icon("news-subscribe"), tr("Subscribe"));
|
||||||
sub->setEnabled(active);
|
sub->setEnabled(active);
|
||||||
connect(sub, &QAction::triggered, [this, cnt]() {
|
connect(sub, &QAction::triggered, std::bind(&Squawk::changeSubscription, this, id, true));
|
||||||
emit subscribeContact(cnt->getAccountName(), cnt->getJid(), "");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QString accName = cnt->getAccountName();
|
|
||||||
QString cntJID = cnt->getJid();
|
|
||||||
QString cntName = cnt->getName();
|
|
||||||
|
|
||||||
QAction* rename = contextMenu->addAction(Shared::icon("edit-rename"), tr("Rename"));
|
QAction* rename = contextMenu->addAction(Shared::icon("edit-rename"), tr("Rename"));
|
||||||
rename->setEnabled(active);
|
rename->setEnabled(active);
|
||||||
connect(rename, &QAction::triggered, [this, cntName, accName, cntJID]() {
|
connect(rename, &QAction::triggered, [this, cntName, id]() {
|
||||||
QInputDialog* dialog = new QInputDialog(this);
|
QInputDialog* dialog = new QInputDialog(this);
|
||||||
connect(dialog, &QDialog::accepted, [this, dialog, cntName, accName, cntJID]() {
|
connect(dialog, &QDialog::accepted, [this, dialog, cntName, id]() {
|
||||||
QString newName = dialog->textValue();
|
QString newName = dialog->textValue();
|
||||||
if (newName != cntName) {
|
if (newName != cntName) {
|
||||||
emit renameContactRequest(accName, cntJID, 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);
|
||||||
dialog->setInputMode(QInputDialog::TextInput);
|
dialog->setInputMode(QInputDialog::TextInput);
|
||||||
dialog->setLabelText(tr("Input new name for %1\nor leave it empty for the contact \nto be displayed as %1").arg(cntJID));
|
dialog->setLabelText(tr("Input new name for %1\nor leave it empty for the contact \nto be displayed as %1").arg(id.name));
|
||||||
dialog->setWindowTitle(tr("Renaming %1").arg(cntJID));
|
dialog->setWindowTitle(tr("Renaming %1").arg(id.name));
|
||||||
dialog->setTextValue(cntName);
|
dialog->setTextValue(cntName);
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
QMenu* groupsMenu = contextMenu->addMenu(Shared::icon("group"), tr("Groups"));
|
QMenu* groupsMenu = contextMenu->addMenu(Shared::icon("group"), tr("Groups"));
|
||||||
std::deque<QString> groupList = rosterModel.groupList(accName);
|
std::deque<QString> groupList = rosterModel.groupList(id.account);
|
||||||
for (QString groupName : groupList) {
|
for (QString groupName : groupList) {
|
||||||
QAction* gr = groupsMenu->addAction(groupName);
|
QAction* gr = groupsMenu->addAction(groupName);
|
||||||
gr->setCheckable(true);
|
gr->setCheckable(true);
|
||||||
gr->setChecked(rosterModel.groupHasContact(accName, groupName, cntJID));
|
gr->setChecked(rosterModel.groupHasContact(id.account, groupName, id.name));
|
||||||
gr->setEnabled(active);
|
gr->setEnabled(active);
|
||||||
connect(gr, &QAction::toggled, [this, accName, groupName, cntJID](bool checked) {
|
connect(gr, &QAction::toggled, [this, groupName, id](bool checked) {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
emit addContactToGroupRequest(accName, cntJID, groupName);
|
emit addContactToGroupRequest(id.account, id.name, groupName);
|
||||||
} else {
|
} else {
|
||||||
emit removeContactFromGroupRequest(accName, cntJID, 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"));
|
||||||
newGroup->setEnabled(active);
|
newGroup->setEnabled(active);
|
||||||
connect(newGroup, &QAction::triggered, [this, accName, cntJID]() {
|
connect(newGroup, &QAction::triggered, [this, id]() {
|
||||||
QInputDialog* dialog = new QInputDialog(this);
|
QInputDialog* dialog = new QInputDialog(this);
|
||||||
connect(dialog, &QDialog::accepted, [this, dialog, accName, cntJID]() {
|
connect(dialog, &QDialog::accepted, [this, dialog, id]() {
|
||||||
emit addContactToGroupRequest(accName, cntJID, dialog->textValue());
|
emit addContactToGroupRequest(id.account, id.name, dialog->textValue());
|
||||||
dialog->deleteLater();
|
dialog->deleteLater();
|
||||||
});
|
});
|
||||||
connect(dialog, &QDialog::rejected, dialog, &QObject::deleteLater);
|
connect(dialog, &QDialog::rejected, dialog, &QObject::deleteLater);
|
||||||
dialog->setInputMode(QInputDialog::TextInput);
|
dialog->setInputMode(QInputDialog::TextInput);
|
||||||
dialog->setLabelText(tr("New group name"));
|
dialog->setLabelText(tr("New group name"));
|
||||||
dialog->setWindowTitle(tr("Add %1 to a new group").arg(cntJID));
|
dialog->setWindowTitle(tr("Add %1 to a new group").arg(id.name));
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
QAction* card = contextMenu->addAction(Shared::icon("user-properties"), tr("VCard"));
|
QAction* card = contextMenu->addAction(Shared::icon("user-properties"), tr("VCard"));
|
||||||
card->setEnabled(active);
|
card->setEnabled(active);
|
||||||
connect(card, &QAction::triggered, std::bind(&Squawk::onActivateVCard, this, accName, cnt->getJid(), false));
|
connect(card, &QAction::triggered, std::bind(&Squawk::onActivateVCard, this, id.account, id.name, false));
|
||||||
|
|
||||||
QAction* remove = contextMenu->addAction(Shared::icon("edit-delete"), tr("Remove"));
|
QAction* remove = contextMenu->addAction(Shared::icon("edit-delete"), tr("Remove"));
|
||||||
remove->setEnabled(active);
|
remove->setEnabled(active);
|
||||||
connect(remove, &QAction::triggered, [this, cnt]() {
|
connect(remove, &QAction::triggered, std::bind(&Squawk::removeContactRequest, this, id.account, id.name));
|
||||||
emit removeContactRequest(cnt->getAccountName(), cnt->getJid());
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -653,32 +400,16 @@ void Squawk::onRosterContextMenu(const QPoint& point)
|
|||||||
if (room->getAutoJoin()) {
|
if (room->getAutoJoin()) {
|
||||||
QAction* unsub = contextMenu->addAction(Shared::icon("news-unsubscribe"), tr("Unsubscribe"));
|
QAction* unsub = contextMenu->addAction(Shared::icon("news-unsubscribe"), tr("Unsubscribe"));
|
||||||
unsub->setEnabled(active);
|
unsub->setEnabled(active);
|
||||||
connect(unsub, &QAction::triggered, [this, id]() {
|
connect(unsub, &QAction::triggered, std::bind(&Squawk::changeSubscription, this, id, false));
|
||||||
emit setRoomAutoJoin(id.account, id.name, false);
|
|
||||||
if (conversations.find(id) == conversations.end()
|
|
||||||
&& (currentConversation == nullptr || currentConversation->getId() != id)
|
|
||||||
) { //to leave the room if it's not opened in a conversation window
|
|
||||||
emit setRoomJoined(id.account, id.name, false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
QAction* unsub = contextMenu->addAction(Shared::icon("news-subscribe"), tr("Subscribe"));
|
QAction* sub = contextMenu->addAction(Shared::icon("news-subscribe"), tr("Subscribe"));
|
||||||
unsub->setEnabled(active);
|
sub->setEnabled(active);
|
||||||
connect(unsub, &QAction::triggered, [this, id]() {
|
connect(sub, &QAction::triggered, std::bind(&Squawk::changeSubscription, this, id, true));
|
||||||
emit setRoomAutoJoin(id.account, id.name, true);
|
|
||||||
if (conversations.find(id) == conversations.end()
|
|
||||||
&& (currentConversation == nullptr || currentConversation->getId() != id)
|
|
||||||
) { //to join the room if it's not already joined
|
|
||||||
emit setRoomJoined(id.account, id.name, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QAction* remove = contextMenu->addAction(Shared::icon("edit-delete"), tr("Remove"));
|
QAction* remove = contextMenu->addAction(Shared::icon("edit-delete"), tr("Remove"));
|
||||||
remove->setEnabled(active);
|
remove->setEnabled(active);
|
||||||
connect(remove, &QAction::triggered, [this, id]() {
|
connect(remove, &QAction::triggered, std::bind(&Squawk::removeRoomRequest, this, id.account, id.name));
|
||||||
emit removeRoomRequest(id.account, id.name);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -690,36 +421,6 @@ void Squawk::onRosterContextMenu(const QPoint& point)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Squawk::addRoom(const QString& account, const QString jid, const QMap<QString, QVariant>& data)
|
|
||||||
{
|
|
||||||
rosterModel.addRoom(account, jid, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::changeRoom(const QString& account, const QString jid, const QMap<QString, QVariant>& data)
|
|
||||||
{
|
|
||||||
rosterModel.changeRoom(account, jid, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::removeRoom(const QString& account, const QString jid)
|
|
||||||
{
|
|
||||||
rosterModel.removeRoom(account, jid);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::addRoomParticipant(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data)
|
|
||||||
{
|
|
||||||
rosterModel.addRoomParticipant(account, jid, name, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::changeRoomParticipant(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data)
|
|
||||||
{
|
|
||||||
rosterModel.changeRoomParticipant(account, jid, name, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::removeRoomParticipant(const QString& account, const QString& jid, const QString& name)
|
|
||||||
{
|
|
||||||
rosterModel.removeRoomParticipant(account, jid, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::responseVCard(const QString& jid, const Shared::VCard& card)
|
void Squawk::responseVCard(const QString& jid, const Shared::VCard& card)
|
||||||
{
|
{
|
||||||
std::map<QString, VCard*>::const_iterator itr = vCards.find(jid);
|
std::map<QString, VCard*>::const_iterator itr = vCards.find(jid);
|
||||||
@ -777,61 +478,40 @@ void Squawk::onVCardSave(const Shared::VCard& card, const QString& account)
|
|||||||
widget->deleteLater();
|
widget->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Squawk::readSettings()
|
|
||||||
{
|
|
||||||
QSettings settings;
|
|
||||||
settings.beginGroup("ui");
|
|
||||||
int avail;
|
|
||||||
if (settings.contains("availability")) {
|
|
||||||
avail = settings.value("availability").toInt();
|
|
||||||
} else {
|
|
||||||
avail = static_cast<int>(Shared::Availability::online);
|
|
||||||
}
|
|
||||||
settings.endGroup();
|
|
||||||
m_ui->comboBox->setCurrentIndex(avail);
|
|
||||||
|
|
||||||
emit changeState(Shared::Global::fromInt<Shared::Availability>(avail));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::writeSettings()
|
void Squawk::writeSettings()
|
||||||
{
|
{
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
settings.beginGroup("ui");
|
settings.beginGroup("ui");
|
||||||
settings.beginGroup("window");
|
settings.beginGroup("window");
|
||||||
settings.setValue("geometry", saveGeometry());
|
settings.setValue("geometry", saveGeometry());
|
||||||
settings.setValue("state", saveState());
|
settings.setValue("state", saveState());
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
settings.setValue("splitter", m_ui->splitter->saveState());
|
settings.setValue("splitter", m_ui->splitter->saveState());
|
||||||
|
settings.remove("roster");
|
||||||
settings.setValue("availability", m_ui->comboBox->currentIndex());
|
settings.beginGroup("roster");
|
||||||
|
int size = rosterModel.accountsModel->rowCount(QModelIndex());
|
||||||
settings.remove("roster");
|
for (int i = 0; i < size; ++i) {
|
||||||
settings.beginGroup("roster");
|
QModelIndex acc = rosterModel.index(i, 0, QModelIndex());
|
||||||
int size = rosterModel.accountsModel->rowCount(QModelIndex());
|
Models::Account* account = rosterModel.accountsModel->getAccount(i);
|
||||||
for (int i = 0; i < size; ++i) {
|
QString accName = account->getName();
|
||||||
QModelIndex acc = rosterModel.index(i, 0, QModelIndex());
|
settings.beginGroup(accName);
|
||||||
Models::Account* account = rosterModel.accountsModel->getAccount(i);
|
|
||||||
QString accName = account->getName();
|
settings.setValue("expanded", m_ui->roster->isExpanded(acc));
|
||||||
settings.beginGroup(accName);
|
std::deque<QString> groups = rosterModel.groupList(accName);
|
||||||
|
for (const QString& groupName : groups) {
|
||||||
settings.setValue("expanded", m_ui->roster->isExpanded(acc));
|
settings.beginGroup(groupName);
|
||||||
std::deque<QString> groups = rosterModel.groupList(accName);
|
QModelIndex gIndex = rosterModel.getGroupIndex(accName, groupName);
|
||||||
for (const QString& groupName : groups) {
|
settings.setValue("expanded", m_ui->roster->isExpanded(gIndex));
|
||||||
settings.beginGroup(groupName);
|
settings.endGroup();
|
||||||
QModelIndex gIndex = rosterModel.getGroupIndex(accName, groupName);
|
}
|
||||||
settings.setValue("expanded", m_ui->roster->isExpanded(gIndex));
|
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
}
|
|
||||||
settings.endGroup();
|
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
settings.sync();
|
settings.sync();
|
||||||
|
|
||||||
qDebug() << "Saved settings";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Squawk::onItemCollepsed(const QModelIndex& index)
|
void Squawk::onItemCollepsed(const QModelIndex& index)
|
||||||
@ -853,24 +533,6 @@ void Squawk::onItemCollepsed(const QModelIndex& index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Squawk::requestPassword(const QString& account, bool authenticationError) {
|
|
||||||
if (authenticationError) {
|
|
||||||
dialogueQueue.addAction(account, DialogQueue::askCredentials);
|
|
||||||
} else {
|
|
||||||
dialogueQueue.addAction(account, DialogQueue::askPassword);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::subscribeConversation(Conversation* conv)
|
|
||||||
{
|
|
||||||
connect(conv, &Conversation::destroyed, this, &Squawk::onConversationClosed);
|
|
||||||
connect(conv, &Conversation::sendMessage, this, &Squawk::onConversationMessage);
|
|
||||||
connect(conv, &Conversation::replaceMessage, this, &Squawk::onConversationReplaceMessage);
|
|
||||||
connect(conv, &Conversation::resendMessage, this, &Squawk::onConversationResend);
|
|
||||||
connect(conv, &Conversation::notifyableMessage, this, &Squawk::notify);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous)
|
void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous)
|
||||||
{
|
{
|
||||||
if (restoreSelection.isValid() && restoreSelection == current) {
|
if (restoreSelection.isValid() && restoreSelection == current) {
|
||||||
@ -942,16 +604,12 @@ void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIn
|
|||||||
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 (!room->getJoined()) {
|
|
||||||
emit setRoomJoined(id->account, id->name, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!testAttribute(Qt::WA_TranslucentBackground)) {
|
if (!testAttribute(Qt::WA_TranslucentBackground)) {
|
||||||
currentConversation->setFeedFrames(true, false, true, true);
|
currentConversation->setFeedFrames(true, false, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribeConversation(currentConversation);
|
emit openedConversation();
|
||||||
|
|
||||||
if (res.size() > 0) {
|
if (res.size() > 0) {
|
||||||
currentConversation->setPalResource(res);
|
currentConversation->setPalResource(res);
|
||||||
@ -961,18 +619,10 @@ void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIn
|
|||||||
|
|
||||||
delete id;
|
delete id;
|
||||||
} else {
|
} else {
|
||||||
if (currentConversation != nullptr) {
|
closeCurrentConversation();
|
||||||
currentConversation->deleteLater();
|
|
||||||
currentConversation = nullptr;
|
|
||||||
m_ui->filler->show();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (currentConversation != nullptr) {
|
closeCurrentConversation();
|
||||||
currentConversation->deleteLater();
|
|
||||||
currentConversation = nullptr;
|
|
||||||
m_ui->filler->show();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -997,7 +647,12 @@ void Squawk::onAboutSquawkCalled()
|
|||||||
about->show();
|
about->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Squawk::onAboutSquawkClosed()
|
Models::Roster::ElId Squawk::currentConversationId() const
|
||||||
{
|
{
|
||||||
about = nullptr;
|
if (currentConversation == nullptr) {
|
||||||
|
return Models::Roster::ElId();
|
||||||
|
} else {
|
||||||
|
return Models::Roster::ElId(currentConversation->getAccount(), currentConversation->getJid());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
74
ui/squawk.h
74
ui/squawk.h
@ -39,7 +39,6 @@
|
|||||||
#include "widgets/vcard/vcard.h"
|
#include "widgets/vcard/vcard.h"
|
||||||
#include "widgets/settings/settings.h"
|
#include "widgets/settings/settings.h"
|
||||||
#include "widgets/about.h"
|
#include "widgets/about.h"
|
||||||
#include "dialogqueue.h"
|
|
||||||
|
|
||||||
#include "shared/shared.h"
|
#include "shared/shared.h"
|
||||||
#include "shared/global.h"
|
#include "shared/global.h"
|
||||||
@ -48,84 +47,57 @@ namespace Ui {
|
|||||||
class Squawk;
|
class Squawk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Application;
|
||||||
|
|
||||||
class Squawk : public QMainWindow
|
class Squawk : public QMainWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
friend class DialogQueue;
|
friend class Application;
|
||||||
public:
|
public:
|
||||||
explicit Squawk(QWidget *parent = nullptr);
|
explicit Squawk(Models::Roster& rosterModel, QWidget *parent = nullptr);
|
||||||
~Squawk() override;
|
~Squawk() override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void closing();
|
||||||
void newAccountRequest(const QMap<QString, QVariant>&);
|
void newAccountRequest(const QMap<QString, QVariant>&);
|
||||||
void modifyAccountRequest(const QString&, const QMap<QString, QVariant>&);
|
|
||||||
void removeAccountRequest(const QString&);
|
void removeAccountRequest(const QString&);
|
||||||
void connectAccount(const QString&);
|
void connectAccount(const QString&);
|
||||||
void disconnectAccount(const QString&);
|
void disconnectAccount(const QString&);
|
||||||
void changeState(Shared::Availability state);
|
void changeState(Shared::Availability state);
|
||||||
void sendMessage(const QString& account, const Shared::Message& data);
|
|
||||||
void replaceMessage(const QString& account, const QString& originalId, const Shared::Message& data);
|
|
||||||
void resendMessage(const QString& account, const QString& jid, const QString& id);
|
|
||||||
void requestArchive(const QString& account, const QString& jid, int count, const QString& before);
|
|
||||||
void subscribeContact(const QString& account, const QString& jid, const QString& reason);
|
|
||||||
void unsubscribeContact(const QString& account, const QString& jid, const QString& reason);
|
|
||||||
void removeContactRequest(const QString& account, const QString& jid);
|
void removeContactRequest(const QString& account, const QString& jid);
|
||||||
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 addContactToGroupRequest(const QString& account, const QString& jid, const QString& groupName);
|
void addContactToGroupRequest(const QString& account, const QString& jid, const QString& groupName);
|
||||||
void removeContactFromGroupRequest(const QString& account, const QString& jid, const QString& groupName);
|
void removeContactFromGroupRequest(const QString& account, const QString& jid, const QString& groupName);
|
||||||
void renameContactRequest(const QString& account, const QString& jid, const QString& newName);
|
void renameContactRequest(const QString& account, const QString& jid, const QString& newName);
|
||||||
void setRoomJoined(const QString& account, const QString& jid, bool joined);
|
|
||||||
void setRoomAutoJoin(const QString& account, const QString& jid, bool joined);
|
|
||||||
void addRoomRequest(const QString& account, const QString& jid, const QString& nick, const QString& password, bool autoJoin);
|
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 removeRoomRequest(const QString& account, const QString& jid);
|
||||||
void fileDownloadRequest(const QString& url);
|
|
||||||
void requestVCard(const QString& account, const QString& jid);
|
void requestVCard(const QString& account, const QString& jid);
|
||||||
void uploadVCard(const QString& account, const Shared::VCard& card);
|
void uploadVCard(const QString& account, const Shared::VCard& card);
|
||||||
void responsePassword(const QString& account, const QString& password);
|
|
||||||
void localPathInvalid(const QString& path);
|
|
||||||
void changeDownloadsPath(const QString& path);
|
void changeDownloadsPath(const QString& path);
|
||||||
|
|
||||||
|
void notify(const QString& account, const Shared::Message& msg);
|
||||||
|
void changeSubscription(const Models::Roster::ElId& id, bool subscribe);
|
||||||
|
void openedConversation();
|
||||||
|
void openConversation(const Models::Roster::ElId& id, const QString& resource = "");
|
||||||
|
|
||||||
|
void modifyAccountRequest(const QString&, const QMap<QString, QVariant>&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Models::Roster::ElId currentConversationId() const;
|
||||||
|
void closeCurrentConversation();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void writeSettings();
|
void writeSettings();
|
||||||
void readSettings();
|
|
||||||
void newAccount(const QMap<QString, QVariant>& account);
|
|
||||||
void changeAccount(const QString& account, const QMap<QString, QVariant>& data);
|
|
||||||
void removeAccount(const QString& account);
|
|
||||||
void addGroup(const QString& account, const QString& name);
|
|
||||||
void removeGroup(const QString& account, const QString& name);
|
|
||||||
void addContact(const QString& account, const QString& jid, const QString& group, const QMap<QString, QVariant>& data);
|
|
||||||
void removeContact(const QString& account, const QString& jid, const QString& group);
|
|
||||||
void removeContact(const QString& account, const QString& jid);
|
|
||||||
void changeContact(const QString& account, const QString& jid, const QMap<QString, QVariant>& data);
|
|
||||||
void addPresence(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
|
|
||||||
void removePresence(const QString& account, const QString& jid, const QString& name);
|
|
||||||
void stateChanged(Shared::Availability state);
|
void stateChanged(Shared::Availability state);
|
||||||
void accountMessage(const QString& account, const Shared::Message& data);
|
|
||||||
void responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list, bool last);
|
|
||||||
void addRoom(const QString& account, const QString jid, const QMap<QString, QVariant>& data);
|
|
||||||
void changeRoom(const QString& account, const QString jid, const QMap<QString, QVariant>& data);
|
|
||||||
void removeRoom(const QString& account, const QString jid);
|
|
||||||
void addRoomParticipant(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
|
|
||||||
void changeRoomParticipant(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
|
|
||||||
void removeRoomParticipant(const QString& account, const QString& jid, const QString& name);
|
|
||||||
void fileError(const std::list<Shared::MessageInfo> msgs, const QString& error, bool up);
|
|
||||||
void fileProgress(const std::list<Shared::MessageInfo> msgs, qreal value, bool up);
|
|
||||||
void fileDownloadComplete(const std::list<Shared::MessageInfo> msgs, const QString& path);
|
|
||||||
void fileUploadComplete(const std::list<Shared::MessageInfo> msgs, const QString& url, const QString& path);
|
|
||||||
void responseVCard(const QString& jid, const Shared::VCard& card);
|
void responseVCard(const QString& jid, const Shared::VCard& card);
|
||||||
void changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data);
|
|
||||||
void requestPassword(const QString& account, bool authenticationError);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<Models::Roster::ElId, Conversation*> Conversations;
|
|
||||||
QScopedPointer<Ui::Squawk> m_ui;
|
QScopedPointer<Ui::Squawk> m_ui;
|
||||||
|
|
||||||
Accounts* accounts;
|
Accounts* accounts;
|
||||||
Settings* preferences;
|
Settings* preferences;
|
||||||
About* about;
|
About* about;
|
||||||
DialogQueue dialogueQueue;
|
|
||||||
Models::Roster& rosterModel;
|
Models::Roster& rosterModel;
|
||||||
Conversations conversations;
|
|
||||||
QMenu* contextMenu;
|
QMenu* contextMenu;
|
||||||
std::map<QString, VCard*> vCards;
|
std::map<QString, VCard*> vCards;
|
||||||
Conversation* currentConversation;
|
Conversation* currentConversation;
|
||||||
@ -134,9 +106,7 @@ private:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent * event) override;
|
void closeEvent(QCloseEvent * event) override;
|
||||||
|
void expand(const QModelIndex& index);
|
||||||
protected slots:
|
|
||||||
void notify(const QString& account, const Shared::Message& msg);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onAccounts();
|
void onAccounts();
|
||||||
@ -148,27 +118,17 @@ private slots:
|
|||||||
void onAccountsSizeChanged(unsigned int size);
|
void onAccountsSizeChanged(unsigned int size);
|
||||||
void onAccountsClosed();
|
void onAccountsClosed();
|
||||||
void onPreferencesClosed();
|
void onPreferencesClosed();
|
||||||
void onConversationClosed(QObject* parent = 0);
|
|
||||||
void onVCardClosed();
|
void onVCardClosed();
|
||||||
void onVCardSave(const Shared::VCard& card, const QString& account);
|
void onVCardSave(const Shared::VCard& card, const QString& account);
|
||||||
void onActivateVCard(const QString& account, const QString& jid, bool edition = false);
|
void onActivateVCard(const QString& account, const QString& jid, bool edition = false);
|
||||||
void onComboboxActivated(int index);
|
void onComboboxActivated(int index);
|
||||||
void onRosterItemDoubleClicked(const QModelIndex& item);
|
void onRosterItemDoubleClicked(const QModelIndex& item);
|
||||||
void onConversationMessage(const Shared::Message& msg);
|
|
||||||
void onConversationReplaceMessage(const QString& originalId, const Shared::Message& msg);
|
|
||||||
void onConversationResend(const QString& id);
|
|
||||||
void onRequestArchive(const QString& account, const QString& jid, const QString& before);
|
|
||||||
void onRosterContextMenu(const QPoint& point);
|
void onRosterContextMenu(const QPoint& point);
|
||||||
void onItemCollepsed(const QModelIndex& index);
|
void onItemCollepsed(const QModelIndex& index);
|
||||||
void onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous);
|
void onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous);
|
||||||
void onContextAboutToHide();
|
void onContextAboutToHide();
|
||||||
void onAboutSquawkCalled();
|
void onAboutSquawkCalled();
|
||||||
void onAboutSquawkClosed();
|
void onAboutSquawkClosed();
|
||||||
|
|
||||||
void onUnnoticedMessage(const QString& account, const Shared::Message& msg);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void subscribeConversation(Conversation* conv);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SQUAWK_H
|
#endif // SQUAWK_H
|
||||||
|
Loading…
Reference in New Issue
Block a user