forked from blue/squawk
single window mode
This commit is contained in:
parent
b95028e33e
commit
a77dfd191a
13 changed files with 345 additions and 74 deletions
212
ui/squawk.cpp
212
ui/squawk.cpp
|
@ -32,7 +32,8 @@ Squawk::Squawk(QWidget *parent) :
|
|||
requestedFiles(),
|
||||
vCards(),
|
||||
requestedAccountsForPasswords(),
|
||||
prompt(0)
|
||||
prompt(0),
|
||||
currentConversation(0)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_ui->roster->setModel(&rosterModel);
|
||||
|
@ -55,6 +56,7 @@ Squawk::Squawk(QWidget *parent) :
|
|||
connect(m_ui->roster, &QTreeView::doubleClicked, this, &Squawk::onRosterItemDoubleClicked);
|
||||
connect(m_ui->roster, &QTreeView::customContextMenuRequested, this, &Squawk::onRosterContextMenu);
|
||||
connect(m_ui->roster, &QTreeView::collapsed, this, &Squawk::onItemCollepsed);
|
||||
connect(m_ui->roster->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &Squawk::onRosterSelectionChanged);
|
||||
|
||||
connect(rosterModel.accountsModel, &Models::Accounts::sizeChanged, this, &Squawk::onAccountsSizeChanged);
|
||||
//m_ui->mainToolBar->addWidget(m_ui->comboBox);
|
||||
|
@ -74,6 +76,10 @@ Squawk::Squawk(QWidget *parent) :
|
|||
restoreState(settings.value("state").toByteArray());
|
||||
}
|
||||
settings.endGroup();
|
||||
|
||||
if (settings.contains("splitter")) {
|
||||
m_ui->splitter->restoreState(settings.value("splitter").toByteArray());
|
||||
}
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
|
@ -344,16 +350,7 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
|
|||
if (conv != 0) {
|
||||
if (created) {
|
||||
conv->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
connect(conv, &Conversation::destroyed, this, &Squawk::onConversationClosed);
|
||||
connect(conv, qOverload<const Shared::Message&>(&Conversation::sendMessage), this, qOverload<const Shared::Message&>(&Squawk::onConversationMessage));
|
||||
connect(conv, qOverload<const Shared::Message&, const QString&>(&Conversation::sendMessage),
|
||||
this, qOverload<const Shared::Message&, const QString&>(&Squawk::onConversationMessage));
|
||||
connect(conv, &Conversation::requestArchive, this, &Squawk::onConversationRequestArchive);
|
||||
connect(conv, &Conversation::requestLocalFile, this, &Squawk::onConversationRequestLocalFile);
|
||||
connect(conv, &Conversation::downloadFile, this, &Squawk::onConversationDownloadFile);
|
||||
connect(conv, &Conversation::shown, this, &Squawk::onConversationShown);
|
||||
|
||||
subscribeConversation(conv);
|
||||
conversations.insert(std::make_pair(*id, conv));
|
||||
|
||||
if (created) {
|
||||
|
@ -372,6 +369,7 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
|
|||
}
|
||||
}
|
||||
|
||||
delete id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -387,9 +385,8 @@ void Squawk::onConversationClosed(QObject* parent)
|
|||
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()) {
|
||||
qDebug() << "Conversation has been closed but can not be found among other opened conversations, application is most probably going to crash";
|
||||
return;
|
||||
if (itr != conversations.end()) {
|
||||
conversations.erase(itr);
|
||||
}
|
||||
if (conv->isMuc) {
|
||||
Room* room = static_cast<Room*>(conv);
|
||||
|
@ -397,7 +394,6 @@ void Squawk::onConversationClosed(QObject* parent)
|
|||
emit setRoomJoined(id.account, id.name, false);
|
||||
}
|
||||
}
|
||||
conversations.erase(itr);
|
||||
}
|
||||
|
||||
void Squawk::onConversationDownloadFile(const QString& messageId, const QString& url)
|
||||
|
@ -429,6 +425,9 @@ void Squawk::fileProgress(const QString& messageId, qreal value)
|
|||
if (c != conversations.end()) {
|
||||
c->second->responseFileProgress(messageId, value);
|
||||
}
|
||||
if (currentConversation != 0 && currentConversation->getId() == id) {
|
||||
currentConversation->responseFileProgress(messageId, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -447,6 +446,9 @@ void Squawk::fileError(const QString& messageId, const QString& error)
|
|||
if (c != conversations.end()) {
|
||||
c->second->fileError(messageId, error);
|
||||
}
|
||||
if (currentConversation != 0 && currentConversation->getId() == id) {
|
||||
currentConversation->fileError(messageId, error);
|
||||
}
|
||||
}
|
||||
requestedFiles.erase(itr);
|
||||
}
|
||||
|
@ -466,6 +468,9 @@ void Squawk::fileLocalPathResponse(const QString& messageId, const QString& path
|
|||
if (c != conversations.end()) {
|
||||
c->second->responseLocalFile(messageId, path);
|
||||
}
|
||||
if (currentConversation != 0 && currentConversation->getId() == id) {
|
||||
currentConversation->responseLocalFile(messageId, path);
|
||||
}
|
||||
}
|
||||
|
||||
requestedFiles.erase(itr);
|
||||
|
@ -490,18 +495,33 @@ void Squawk::onConversationRequestLocalFile(const QString& messageId, const QStr
|
|||
void Squawk::accountMessage(const QString& account, const Shared::Message& data)
|
||||
{
|
||||
const QString& from = data.getPenPalJid();
|
||||
Conversations::iterator itr = conversations.find({account, from});
|
||||
Models::Roster::ElId id({account, from});
|
||||
Conversations::iterator itr = conversations.find(id);
|
||||
bool found = false;
|
||||
|
||||
if (currentConversation != 0 && currentConversation->getId() == id) {
|
||||
currentConversation->addMessage(data);
|
||||
QApplication::alert(this);
|
||||
if (!isVisible() && !data.getForwarded()) {
|
||||
notify(account, data);
|
||||
}
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (itr != conversations.end()) {
|
||||
Conversation* conv = itr->second;
|
||||
conv->addMessage(data);
|
||||
QApplication::alert(conv);
|
||||
if (conv->isMinimized()) {
|
||||
if (!found && conv->isMinimized()) {
|
||||
rosterModel.addMessage(account, data);
|
||||
}
|
||||
if (!conv->isVisible() && !data.getForwarded()) {
|
||||
notify(account, data);
|
||||
}
|
||||
} else {
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
rosterModel.addMessage(account, data);
|
||||
if (!data.getForwarded()) {
|
||||
QApplication::alert(this);
|
||||
|
@ -512,14 +532,26 @@ void Squawk::accountMessage(const QString& account, const Shared::Message& data)
|
|||
|
||||
void Squawk::changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data)
|
||||
{
|
||||
Conversations::iterator itr = conversations.find({account, jid});
|
||||
Models::Roster::ElId eid({account, jid});
|
||||
bool found = false;
|
||||
|
||||
if (currentConversation != 0 && currentConversation->getId() == eid) {
|
||||
currentConversation->changeMessage(id, data);
|
||||
QApplication::alert(this);
|
||||
found = true;
|
||||
}
|
||||
|
||||
Conversations::iterator itr = conversations.find(eid);
|
||||
if (itr != conversations.end()) {
|
||||
Conversation* conv = itr->second;
|
||||
conv->changeMessage(id, data);
|
||||
if (conv->isMinimized()) {
|
||||
if (!found && conv->isMinimized()) {
|
||||
rosterModel.changeMessage(account, jid, id, data);
|
||||
}
|
||||
} else {
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
rosterModel.changeMessage(account, jid, id, data);
|
||||
}
|
||||
}
|
||||
|
@ -559,13 +591,37 @@ void Squawk::onConversationMessage(const Shared::Message& msg)
|
|||
{
|
||||
Conversation* conv = static_cast<Conversation*>(sender());
|
||||
emit sendMessage(conv->getAccount(), msg);
|
||||
Models::Roster::ElId id = conv->getId();
|
||||
|
||||
if (currentConversation != 0 && currentConversation->getId() == id) {
|
||||
if (conv == currentConversation) {
|
||||
Conversations::iterator itr = conversations.find(id);
|
||||
if (itr != conversations.end()) {
|
||||
itr->second->addMessage(msg);
|
||||
}
|
||||
} else {
|
||||
currentConversation->addMessage(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Squawk::onConversationMessage(const Shared::Message& msg, const QString& path)
|
||||
{
|
||||
Conversation* conv = static_cast<Conversation*>(sender());
|
||||
Models::Roster::ElId id = conv->getId();
|
||||
std::map<QString, std::set<Models::Roster::ElId>>::iterator itr = requestedFiles.insert(std::make_pair(msg.getId(), std::set<Models::Roster::ElId>())).first;
|
||||
itr->second.insert(Models::Roster::ElId(conv->getAccount(), conv->getJid()));
|
||||
itr->second.insert(id);
|
||||
|
||||
if (currentConversation != 0 && currentConversation->getId() == id) {
|
||||
if (conv == currentConversation) {
|
||||
Conversations::iterator itr = conversations.find(id);
|
||||
if (itr != conversations.end()) {
|
||||
itr->second->appendMessageWithUpload(msg, path);
|
||||
}
|
||||
} else {
|
||||
currentConversation->appendMessageWithUpload(msg, path);
|
||||
}
|
||||
}
|
||||
|
||||
emit sendMessage(conv->getAccount(), msg, path);
|
||||
}
|
||||
|
@ -580,6 +636,10 @@ void Squawk::responseArchive(const QString& account, const QString& jid, const s
|
|||
{
|
||||
Models::Roster::ElId id(account, jid);
|
||||
|
||||
if (currentConversation != 0 && currentConversation->getId() == id) {
|
||||
currentConversation->responseArchive(list);
|
||||
}
|
||||
|
||||
Conversations::const_iterator itr = conversations.find(id);
|
||||
if (itr != conversations.end()) {
|
||||
itr->second->responseArchive(list);
|
||||
|
@ -603,6 +663,13 @@ void Squawk::removeAccount(const QString& account)
|
|||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentConversation != 0 && currentConversation->getAccount() == account) {
|
||||
currentConversation->deleteLater();
|
||||
currentConversation = 0;
|
||||
m_ui->filler->show();
|
||||
}
|
||||
|
||||
rosterModel.removeAccount(account);
|
||||
}
|
||||
|
||||
|
@ -761,7 +828,9 @@ void Squawk::onRosterContextMenu(const QPoint& point)
|
|||
unsub->setEnabled(active);
|
||||
connect(unsub, &QAction::triggered, [this, id]() {
|
||||
emit setRoomAutoJoin(id.account, id.name, false);
|
||||
if (conversations.find(id) == conversations.end()) { //to leave the room if it's not opened in a conversation window
|
||||
if (conversations.find(id) == conversations.end()
|
||||
&& (currentConversation == 0 || currentConversation->getId() != id)
|
||||
) { //to leave the room if it's not opened in a conversation window
|
||||
emit setRoomJoined(id.account, id.name, false);
|
||||
}
|
||||
});
|
||||
|
@ -770,7 +839,9 @@ void Squawk::onRosterContextMenu(const QPoint& point)
|
|||
unsub->setEnabled(active);
|
||||
connect(unsub, &QAction::triggered, [this, id]() {
|
||||
emit setRoomAutoJoin(id.account, id.name, true);
|
||||
if (conversations.find(id) == conversations.end()) { //to join the room if it's not already joined
|
||||
if (conversations.find(id) == conversations.end()
|
||||
&& (currentConversation == 0 || currentConversation->getId() != id)
|
||||
) { //to join the room if it's not already joined
|
||||
emit setRoomJoined(id.account, id.name, true);
|
||||
}
|
||||
});
|
||||
|
@ -897,7 +968,6 @@ void Squawk::readSettings()
|
|||
} // need to fix that
|
||||
settings.endArray();
|
||||
}
|
||||
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
|
@ -910,6 +980,8 @@ void Squawk::writeSettings()
|
|||
settings.setValue("state", saveState());
|
||||
settings.endGroup();
|
||||
|
||||
settings.setValue("splitter", m_ui->splitter->saveState());
|
||||
|
||||
settings.setValue("availability", m_ui->comboBox->currentIndex());
|
||||
settings.beginWriteArray("connectedAccounts");
|
||||
int size = rosterModel.accountsModel->rowCount(QModelIndex());
|
||||
|
@ -1008,3 +1080,93 @@ void Squawk::onPasswordPromptRejected()
|
|||
emit responsePassword(requestedAccountsForPasswords.front(), prompt->textValue());
|
||||
onPasswordPromptDone();
|
||||
}
|
||||
|
||||
void Squawk::subscribeConversation(Conversation* conv)
|
||||
{
|
||||
connect(conv, &Conversation::destroyed, this, &Squawk::onConversationClosed);
|
||||
connect(conv, qOverload<const Shared::Message&>(&Conversation::sendMessage), this, qOverload<const Shared::Message&>(&Squawk::onConversationMessage));
|
||||
connect(conv, qOverload<const Shared::Message&, const QString&>(&Conversation::sendMessage),
|
||||
this, qOverload<const Shared::Message&, const QString&>(&Squawk::onConversationMessage));
|
||||
connect(conv, &Conversation::requestArchive, this, &Squawk::onConversationRequestArchive);
|
||||
connect(conv, &Conversation::requestLocalFile, this, &Squawk::onConversationRequestLocalFile);
|
||||
connect(conv, &Conversation::downloadFile, this, &Squawk::onConversationDownloadFile);
|
||||
connect(conv, &Conversation::shown, this, &Squawk::onConversationShown);
|
||||
}
|
||||
|
||||
void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous)
|
||||
{
|
||||
if (current.isValid()) {
|
||||
Models::Item* node = static_cast<Models::Item*>(current.internalPointer());
|
||||
Models::Contact* contact = 0;
|
||||
Models::Room* room = 0;
|
||||
QString res;
|
||||
Models::Roster::ElId* id = 0;
|
||||
switch (node->type) {
|
||||
case Models::Item::contact:
|
||||
contact = static_cast<Models::Contact*>(node);
|
||||
id = new Models::Roster::ElId(contact->getAccountName(), contact->getJid());
|
||||
break;
|
||||
case Models::Item::presence:
|
||||
contact = static_cast<Models::Contact*>(node->parentItem());
|
||||
id = new Models::Roster::ElId(contact->getAccountName(), contact->getJid());
|
||||
res = node->getName();
|
||||
break;
|
||||
case Models::Item::room:
|
||||
room = static_cast<Models::Room*>(node);
|
||||
id = new Models::Roster::ElId(room->getAccountName(), room->getJid());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (id != 0) {
|
||||
if (currentConversation != 0) {
|
||||
if (currentConversation->getJid() == id->name) {
|
||||
if (contact != 0) {
|
||||
currentConversation->setPalResource(res);
|
||||
}
|
||||
} else {
|
||||
currentConversation->deleteLater();
|
||||
}
|
||||
} else {
|
||||
m_ui->filler->hide();
|
||||
}
|
||||
|
||||
Models::Account* acc = rosterModel.getAccount(id->account);
|
||||
Models::Contact::Messages deque;
|
||||
if (contact != 0) {
|
||||
currentConversation = new Chat(acc, contact);
|
||||
contact->getMessages(deque);
|
||||
} else if (room != 0) {
|
||||
currentConversation = new Room(acc, room);
|
||||
room->getMessages(deque);
|
||||
|
||||
if (!room->getJoined()) {
|
||||
emit setRoomJoined(id->account, id->name, true);
|
||||
}
|
||||
}
|
||||
if (!testAttribute(Qt::WA_TranslucentBackground)) {
|
||||
currentConversation->setFeedFrames(true, false, true, true);
|
||||
}
|
||||
|
||||
subscribeConversation(currentConversation);
|
||||
for (Models::Contact::Messages::const_iterator itr = deque.begin(), end = deque.end(); itr != end; ++itr) {
|
||||
currentConversation->addMessage(*itr);
|
||||
}
|
||||
|
||||
if (res.size() > 0) {
|
||||
currentConversation->setPalResource(res);
|
||||
}
|
||||
|
||||
m_ui->splitter->insertWidget(1, currentConversation);
|
||||
|
||||
delete id;
|
||||
} else {
|
||||
if (currentConversation != 0) {
|
||||
currentConversation->deleteLater();
|
||||
currentConversation = 0;
|
||||
m_ui->filler->show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue