safePasswords #36
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
## Squawk 0.1.4 (UNRELEASED)
|
## Squawk 0.1.4 (UNRELEASED)
|
||||||
### New features
|
### New features
|
||||||
|
- message line now is in the same window with roster (new window dialog is still able to opened on double click)
|
||||||
- several ways to manage your account password:
|
- several ways to manage your account password:
|
||||||
- store it in plain text with the config (like it always was)
|
- store it in plain text with the config (like it always was)
|
||||||
- store it in config jammed (local hashing with the constant seed, not secure at all but might look like it is)
|
- store it in config jammed (local hashing with the constant seed, not secure at all but might look like it is)
|
||||||
|
@ -67,9 +67,6 @@ Here is the list of keys you can pass to configuration phase of `cmake ..`.
|
|||||||
- `SYSTEM_QXMPP` - `True` tries to link against `qxmpp` installed in the system, `False` builds bundled `qxmpp` library (default is `True`)
|
- `SYSTEM_QXMPP` - `True` tries to link against `qxmpp` installed in the system, `False` builds bundled `qxmpp` library (default is `True`)
|
||||||
- `WITH_KWALLET` - `True` builds the `KWallet` capability module if `KWallet` is installed and if not goes to `False`. `False` disables `KWallet` support (default is `True`)
|
- `WITH_KWALLET` - `True` builds the `KWallet` capability module if `KWallet` is installed and if not goes to `False`. `False` disables `KWallet` support (default is `True`)
|
||||||
|
|
||||||
|
|
||||||
Each key is supposed to be passed like that
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This project is licensed under the GPLv3 License - see the [LICENSE.md](LICENSE.md) file for details
|
This project is licensed under the GPLv3 License - see the [LICENSE.md](LICENSE.md) file for details
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
project(pse)
|
project(pse)
|
||||||
|
|
||||||
|
|
||||||
if (WITH_KWALLET)
|
if (WITH_KWALLET)
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
|
||||||
@ -36,7 +35,3 @@ if (WITH_KWALLET)
|
|||||||
|
|
||||||
install(TARGETS kwalletWrapper DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
install(TARGETS kwalletWrapper DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -386,6 +386,16 @@ bool Models::Roster::ElId::operator <(const Models::Roster::ElId& other) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Models::Roster::ElId::operator!=(const Models::Roster::ElId& other) const
|
||||||
|
{
|
||||||
|
return !(operator == (other));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Models::Roster::ElId::operator==(const Models::Roster::ElId& other) const
|
||||||
|
{
|
||||||
|
return (account == other.account) && (name == other.name);
|
||||||
|
}
|
||||||
|
|
||||||
void Models::Roster::onAccountDataChanged(const QModelIndex& tl, const QModelIndex& br, const QVector<int>& roles)
|
void Models::Roster::onAccountDataChanged(const QModelIndex& tl, const QModelIndex& br, const QVector<int>& roles)
|
||||||
{
|
{
|
||||||
if (tl.column() == 0) {
|
if (tl.column() == 0) {
|
||||||
|
@ -109,6 +109,8 @@ public:
|
|||||||
const QString name;
|
const QString name;
|
||||||
|
|
||||||
bool operator < (const ElId& other) const;
|
bool operator < (const ElId& other) const;
|
||||||
|
bool operator == (const ElId& other) const;
|
||||||
|
bool operator != (const ElId& other) const;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
212
ui/squawk.cpp
212
ui/squawk.cpp
@ -32,7 +32,8 @@ Squawk::Squawk(QWidget *parent) :
|
|||||||
requestedFiles(),
|
requestedFiles(),
|
||||||
vCards(),
|
vCards(),
|
||||||
requestedAccountsForPasswords(),
|
requestedAccountsForPasswords(),
|
||||||
prompt(0)
|
prompt(0),
|
||||||
|
currentConversation(0)
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
m_ui->roster->setModel(&rosterModel);
|
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::doubleClicked, this, &Squawk::onRosterItemDoubleClicked);
|
||||||
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(rosterModel.accountsModel, &Models::Accounts::sizeChanged, this, &Squawk::onAccountsSizeChanged);
|
connect(rosterModel.accountsModel, &Models::Accounts::sizeChanged, this, &Squawk::onAccountsSizeChanged);
|
||||||
//m_ui->mainToolBar->addWidget(m_ui->comboBox);
|
//m_ui->mainToolBar->addWidget(m_ui->comboBox);
|
||||||
@ -74,6 +76,10 @@ Squawk::Squawk(QWidget *parent) :
|
|||||||
restoreState(settings.value("state").toByteArray());
|
restoreState(settings.value("state").toByteArray());
|
||||||
}
|
}
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
|
if (settings.contains("splitter")) {
|
||||||
|
m_ui->splitter->restoreState(settings.value("splitter").toByteArray());
|
||||||
|
}
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,16 +350,7 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
|
|||||||
if (conv != 0) {
|
if (conv != 0) {
|
||||||
if (created) {
|
if (created) {
|
||||||
conv->setAttribute(Qt::WA_DeleteOnClose);
|
conv->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
subscribeConversation(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);
|
|
||||||
|
|
||||||
conversations.insert(std::make_pair(*id, conv));
|
conversations.insert(std::make_pair(*id, conv));
|
||||||
|
|
||||||
if (created) {
|
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());
|
Conversation* conv = static_cast<Conversation*>(sender());
|
||||||
Models::Roster::ElId id(conv->getAccount(), conv->getJid());
|
Models::Roster::ElId id(conv->getAccount(), conv->getJid());
|
||||||
Conversations::const_iterator itr = conversations.find(id);
|
Conversations::const_iterator itr = conversations.find(id);
|
||||||
if (itr == conversations.end()) {
|
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";
|
conversations.erase(itr);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (conv->isMuc) {
|
if (conv->isMuc) {
|
||||||
Room* room = static_cast<Room*>(conv);
|
Room* room = static_cast<Room*>(conv);
|
||||||
@ -397,7 +394,6 @@ void Squawk::onConversationClosed(QObject* parent)
|
|||||||
emit setRoomJoined(id.account, id.name, false);
|
emit setRoomJoined(id.account, id.name, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conversations.erase(itr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Squawk::onConversationDownloadFile(const QString& messageId, const QString& url)
|
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()) {
|
if (c != conversations.end()) {
|
||||||
c->second->responseFileProgress(messageId, value);
|
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()) {
|
if (c != conversations.end()) {
|
||||||
c->second->fileError(messageId, error);
|
c->second->fileError(messageId, error);
|
||||||
}
|
}
|
||||||
|
if (currentConversation != 0 && currentConversation->getId() == id) {
|
||||||
|
currentConversation->fileError(messageId, error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
requestedFiles.erase(itr);
|
requestedFiles.erase(itr);
|
||||||
}
|
}
|
||||||
@ -466,6 +468,9 @@ void Squawk::fileLocalPathResponse(const QString& messageId, const QString& path
|
|||||||
if (c != conversations.end()) {
|
if (c != conversations.end()) {
|
||||||
c->second->responseLocalFile(messageId, path);
|
c->second->responseLocalFile(messageId, path);
|
||||||
}
|
}
|
||||||
|
if (currentConversation != 0 && currentConversation->getId() == id) {
|
||||||
|
currentConversation->responseLocalFile(messageId, path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
requestedFiles.erase(itr);
|
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)
|
void Squawk::accountMessage(const QString& account, const Shared::Message& data)
|
||||||
{
|
{
|
||||||
const QString& from = data.getPenPalJid();
|
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()) {
|
if (itr != conversations.end()) {
|
||||||
Conversation* conv = itr->second;
|
Conversation* conv = itr->second;
|
||||||
conv->addMessage(data);
|
conv->addMessage(data);
|
||||||
QApplication::alert(conv);
|
QApplication::alert(conv);
|
||||||
if (conv->isMinimized()) {
|
if (!found && conv->isMinimized()) {
|
||||||
rosterModel.addMessage(account, data);
|
rosterModel.addMessage(account, data);
|
||||||
}
|
}
|
||||||
if (!conv->isVisible() && !data.getForwarded()) {
|
if (!conv->isVisible() && !data.getForwarded()) {
|
||||||
notify(account, data);
|
notify(account, data);
|
||||||
}
|
}
|
||||||
} else {
|
found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
rosterModel.addMessage(account, data);
|
rosterModel.addMessage(account, data);
|
||||||
if (!data.getForwarded()) {
|
if (!data.getForwarded()) {
|
||||||
QApplication::alert(this);
|
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)
|
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()) {
|
if (itr != conversations.end()) {
|
||||||
Conversation* conv = itr->second;
|
Conversation* conv = itr->second;
|
||||||
conv->changeMessage(id, data);
|
conv->changeMessage(id, data);
|
||||||
if (conv->isMinimized()) {
|
if (!found && conv->isMinimized()) {
|
||||||
rosterModel.changeMessage(account, jid, id, data);
|
rosterModel.changeMessage(account, jid, id, data);
|
||||||
}
|
}
|
||||||
} else {
|
found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
rosterModel.changeMessage(account, jid, id, data);
|
rosterModel.changeMessage(account, jid, id, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -559,13 +591,37 @@ void Squawk::onConversationMessage(const Shared::Message& msg)
|
|||||||
{
|
{
|
||||||
Conversation* conv = static_cast<Conversation*>(sender());
|
Conversation* conv = static_cast<Conversation*>(sender());
|
||||||
emit sendMessage(conv->getAccount(), msg);
|
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)
|
void Squawk::onConversationMessage(const Shared::Message& msg, const QString& path)
|
||||||
{
|
{
|
||||||
Conversation* conv = static_cast<Conversation*>(sender());
|
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;
|
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);
|
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);
|
Models::Roster::ElId id(account, jid);
|
||||||
|
|
||||||
|
if (currentConversation != 0 && currentConversation->getId() == id) {
|
||||||
|
currentConversation->responseArchive(list);
|
||||||
|
}
|
||||||
|
|
||||||
Conversations::const_iterator itr = conversations.find(id);
|
Conversations::const_iterator itr = conversations.find(id);
|
||||||
if (itr != conversations.end()) {
|
if (itr != conversations.end()) {
|
||||||
itr->second->responseArchive(list);
|
itr->second->responseArchive(list);
|
||||||
@ -603,6 +663,13 @@ void Squawk::removeAccount(const QString& account)
|
|||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentConversation != 0 && currentConversation->getAccount() == account) {
|
||||||
|
currentConversation->deleteLater();
|
||||||
|
currentConversation = 0;
|
||||||
|
m_ui->filler->show();
|
||||||
|
}
|
||||||
|
|
||||||
rosterModel.removeAccount(account);
|
rosterModel.removeAccount(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -761,7 +828,9 @@ void Squawk::onRosterContextMenu(const QPoint& point)
|
|||||||
unsub->setEnabled(active);
|
unsub->setEnabled(active);
|
||||||
connect(unsub, &QAction::triggered, [this, id]() {
|
connect(unsub, &QAction::triggered, [this, id]() {
|
||||||
emit setRoomAutoJoin(id.account, id.name, false);
|
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);
|
emit setRoomJoined(id.account, id.name, false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -770,7 +839,9 @@ void Squawk::onRosterContextMenu(const QPoint& point)
|
|||||||
unsub->setEnabled(active);
|
unsub->setEnabled(active);
|
||||||
connect(unsub, &QAction::triggered, [this, id]() {
|
connect(unsub, &QAction::triggered, [this, id]() {
|
||||||
emit setRoomAutoJoin(id.account, id.name, true);
|
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);
|
emit setRoomJoined(id.account, id.name, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -897,7 +968,6 @@ void Squawk::readSettings()
|
|||||||
} // need to fix that
|
} // need to fix that
|
||||||
settings.endArray();
|
settings.endArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -910,6 +980,8 @@ void Squawk::writeSettings()
|
|||||||
settings.setValue("state", saveState());
|
settings.setValue("state", saveState());
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.setValue("splitter", m_ui->splitter->saveState());
|
||||||
|
|
||||||
settings.setValue("availability", m_ui->comboBox->currentIndex());
|
settings.setValue("availability", m_ui->comboBox->currentIndex());
|
||||||
settings.beginWriteArray("connectedAccounts");
|
settings.beginWriteArray("connectedAccounts");
|
||||||
int size = rosterModel.accountsModel->rowCount(QModelIndex());
|
int size = rosterModel.accountsModel->rowCount(QModelIndex());
|
||||||
@ -1008,3 +1080,93 @@ void Squawk::onPasswordPromptRejected()
|
|||||||
emit responsePassword(requestedAccountsForPasswords.front(), prompt->textValue());
|
emit responsePassword(requestedAccountsForPasswords.front(), prompt->textValue());
|
||||||
onPasswordPromptDone();
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -124,6 +124,7 @@ private:
|
|||||||
std::map<QString, VCard*> vCards;
|
std::map<QString, VCard*> vCards;
|
||||||
std::deque<QString> requestedAccountsForPasswords;
|
std::deque<QString> requestedAccountsForPasswords;
|
||||||
QInputDialog* prompt;
|
QInputDialog* prompt;
|
||||||
|
Conversation* currentConversation;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent * event) override;
|
void closeEvent(QCloseEvent * event) override;
|
||||||
@ -153,10 +154,12 @@ private slots:
|
|||||||
void onItemCollepsed(const QModelIndex& index);
|
void onItemCollepsed(const QModelIndex& index);
|
||||||
void onPasswordPromptAccepted();
|
void onPasswordPromptAccepted();
|
||||||
void onPasswordPromptRejected();
|
void onPasswordPromptRejected();
|
||||||
|
void onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void checkNextAccountForPassword();
|
void checkNextAccountForPassword();
|
||||||
void onPasswordPromptDone();
|
void onPasswordPromptDone();
|
||||||
|
void subscribeConversation(Conversation* conv);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SQUAWK_H
|
#endif // SQUAWK_H
|
||||||
|
100
ui/squawk.ui
100
ui/squawk.ui
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>385</width>
|
<width>718</width>
|
||||||
<height>508</height>
|
<height>720</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<enum>Qt::ToolButtonFollowStyle</enum>
|
<enum>Qt::ToolButtonFollowStyle</enum>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralWidget">
|
<widget class="QWidget" name="centralWidget">
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
@ -30,20 +30,50 @@
|
|||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item row="0" column="0">
|
<item>
|
||||||
<widget class="QComboBox" name="comboBox">
|
<widget class="QSplitter" name="splitter">
|
||||||
<property name="editable">
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="handleWidth">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="childrenCollapsible">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentText">
|
<widget class="QWidget" name="widget" native="true">
|
||||||
<string/>
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="minimumSize">
|
||||||
<number>-1</number>
|
<size>
|
||||||
|
<width>200</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="maximumSize">
|
||||||
</item>
|
<size>
|
||||||
<item row="1" column="0">
|
<width>400</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item row="2" column="1">
|
||||||
<widget class="QTreeView" name="roster">
|
<widget class="QTreeView" name="roster">
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::NoFrame</enum>
|
<enum>QFrame::NoFrame</enum>
|
||||||
@ -68,6 +98,46 @@
|
|||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="comboBox">
|
||||||
|
<property name="editable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="currentText">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>-1</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="filler" native="true">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>2</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string><html><head/><body><p><span style=" font-size:26pt;">Please select a contact to start chatting</span></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenuBar" name="menuBar">
|
<widget class="QMenuBar" name="menuBar">
|
||||||
@ -75,8 +145,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>385</width>
|
<width>718</width>
|
||||||
<height>22</height>
|
<height>27</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QMenu" name="menuSettings">
|
<widget class="QMenu" name="menuSettings">
|
||||||
|
@ -427,6 +427,12 @@ void MessageLine::fileError(const QString& messageId, const QString& error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MessageLine::appendMessageWithUpload(const Shared::Message& msg, const QString& path)
|
void MessageLine::appendMessageWithUpload(const Shared::Message& msg, const QString& path)
|
||||||
|
{
|
||||||
|
appendMessageWithUploadNoSiganl(msg, path);
|
||||||
|
emit uploadFile(msg, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageLine::appendMessageWithUploadNoSiganl(const Shared::Message& msg, const QString& path)
|
||||||
{
|
{
|
||||||
message(msg, true);
|
message(msg, true);
|
||||||
QString id = msg.getId();
|
QString id = msg.getId();
|
||||||
@ -436,9 +442,9 @@ void MessageLine::appendMessageWithUpload(const Shared::Message& msg, const QStr
|
|||||||
ui->showComment(tr("Uploading..."));
|
ui->showComment(tr("Uploading..."));
|
||||||
uploading.insert(std::make_pair(id, ui));
|
uploading.insert(std::make_pair(id, ui));
|
||||||
uploadPaths.insert(std::make_pair(id, path));
|
uploadPaths.insert(std::make_pair(id, path));
|
||||||
emit uploadFile(msg, path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MessageLine::onUpload()
|
void MessageLine::onUpload()
|
||||||
{
|
{
|
||||||
//TODO retry
|
//TODO retry
|
||||||
|
@ -53,6 +53,7 @@ public:
|
|||||||
void fileError(const QString& messageId, const QString& error);
|
void fileError(const QString& messageId, const QString& error);
|
||||||
void fileProgress(const QString& messageId, qreal progress);
|
void fileProgress(const QString& messageId, qreal progress);
|
||||||
void appendMessageWithUpload(const Shared::Message& msg, const QString& path);
|
void appendMessageWithUpload(const Shared::Message& msg, const QString& path);
|
||||||
|
void appendMessageWithUploadNoSiganl(const Shared::Message& msg, const QString& path);
|
||||||
void removeMessage(const QString& messageId);
|
void removeMessage(const QString& messageId);
|
||||||
void setMyAvatarPath(const QString& p_path);
|
void setMyAvatarPath(const QString& p_path);
|
||||||
void setPalAvatar(const QString& jid, const QString& path);
|
void setPalAvatar(const QString& jid, const QString& path);
|
||||||
|
@ -210,6 +210,11 @@ void Conversation::onEnterPressed()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Conversation::appendMessageWithUpload(const Shared::Message& data, const QString& path)
|
||||||
|
{
|
||||||
|
line->appendMessageWithUploadNoSiganl(data, path);
|
||||||
|
}
|
||||||
|
|
||||||
void Conversation::onMessagesResize(int amount)
|
void Conversation::onMessagesResize(int amount)
|
||||||
{
|
{
|
||||||
manualSliderChange = true;
|
manualSliderChange = true;
|
||||||
@ -334,6 +339,11 @@ void Conversation::responseLocalFile(const QString& messageId, const QString& pa
|
|||||||
line->responseLocalFile(messageId, path);
|
line->responseLocalFile(messageId, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Models::Roster::ElId Conversation::getId() const
|
||||||
|
{
|
||||||
|
return {getAccount(), getJid()};
|
||||||
|
}
|
||||||
|
|
||||||
void Conversation::addAttachedFile(const QString& path)
|
void Conversation::addAttachedFile(const QString& path)
|
||||||
{
|
{
|
||||||
QMimeDatabase db;
|
QMimeDatabase db;
|
||||||
@ -397,6 +407,10 @@ void Conversation::onTextEditDocSizeChanged(const QSizeF& size)
|
|||||||
m_ui->messageEditor->setMaximumHeight(int(size.height()));
|
m_ui->messageEditor->setMaximumHeight(int(size.height()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Conversation::setFeedFrames(bool top, bool right, bool bottom, bool left)
|
||||||
|
{
|
||||||
|
static_cast<DropShadowEffect*>(m_ui->scrollArea->graphicsEffect())->setFrame(top, right, bottom, left);
|
||||||
|
}
|
||||||
|
|
||||||
bool VisibilityCatcher::eventFilter(QObject* obj, QEvent* event)
|
bool VisibilityCatcher::eventFilter(QObject* obj, QEvent* event)
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "shared/message.h"
|
#include "shared/message.h"
|
||||||
#include "order.h"
|
#include "order.h"
|
||||||
#include "ui/models/account.h"
|
#include "ui/models/account.h"
|
||||||
|
#include "ui/models/roster.h"
|
||||||
#include "ui/utils/messageline.h"
|
#include "ui/utils/messageline.h"
|
||||||
#include "ui/utils/resizer.h"
|
#include "ui/utils/resizer.h"
|
||||||
#include "ui/utils/flowlayout.h"
|
#include "ui/utils/flowlayout.h"
|
||||||
@ -72,6 +73,7 @@ public:
|
|||||||
QString getJid() const;
|
QString getJid() const;
|
||||||
QString getAccount() const;
|
QString getAccount() const;
|
||||||
QString getPalResource() const;
|
QString getPalResource() const;
|
||||||
|
Models::Roster::ElId getId() const;
|
||||||
virtual void addMessage(const Shared::Message& data);
|
virtual void addMessage(const Shared::Message& data);
|
||||||
|
|
||||||
void setPalResource(const QString& res);
|
void setPalResource(const QString& res);
|
||||||
@ -82,6 +84,8 @@ public:
|
|||||||
void responseFileProgress(const QString& messageId, qreal progress);
|
void responseFileProgress(const QString& messageId, qreal progress);
|
||||||
virtual void setAvatar(const QString& path);
|
virtual void setAvatar(const QString& path);
|
||||||
void changeMessage(const QString& id, const QMap<QString, QVariant>& data);
|
void changeMessage(const QString& id, const QMap<QString, QVariant>& data);
|
||||||
|
void setFeedFrames(bool top, bool right, bool bottom, bool left);
|
||||||
|
virtual void appendMessageWithUpload(const Shared::Message& data, const QString& path);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void sendMessage(const Shared::Message& message);
|
void sendMessage(const Shared::Message& message);
|
||||||
|
@ -10,6 +10,12 @@
|
|||||||
<height>658</height>
|
<height>658</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>2</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<layout class="QVBoxLayout" name="horizontalLayout">
|
<layout class="QVBoxLayout" name="horizontalLayout">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
@ -206,7 +212,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>520</width>
|
<width>520</width>
|
||||||
<height>389</height>
|
<height>392</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
Loading…
Reference in New Issue
Block a user