Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'metacontacts' of git://github.com/magist3r/qutim into m…

…etacontacts
  • Loading branch information...
commit 6ebddef8df141d7987b9f47df07a370b002884c0 2 parents 159049b + aa5ab9f
@euroelessar euroelessar authored
View
2  core/src/corelayers/metacontacts/CMakeLists.txt
@@ -4,5 +4,5 @@ qutim_add_plugin( metacontacts
EXTENSION_CLASS Core::MetaContacts::Manager
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
DISPLAY_NAME "Simple MetaContacts"
- DESCRIPTION "Default qutIM MetaContacts implementation, very stupid one"
+ DESCRIPTION "Default qutIM MetaContacts implementation"
)
View
4 core/src/corelayers/metacontacts/manager.cpp
@@ -48,6 +48,10 @@ Manager::Manager() :
connect(this, SIGNAL(contactCreated(qutim_sdk_0_3::Contact*)), SLOT(onContactCreated(qutim_sdk_0_3::Contact*)));
QTimer::singleShot(0, this, SLOT(initActions()));
setContactsFactory(m_factory.data());
+ m_handler.reset(new MetaContactMessageHandler);
+ qutim_sdk_0_3::MessageHandler::registerHandler(m_handler.data(),
+ qutim_sdk_0_3::MessageHandler::HighPriority,
+ qutim_sdk_0_3::MessageHandler::HighPriority);
}
Manager::~Manager()
View
2  core/src/corelayers/metacontacts/manager.h
@@ -28,6 +28,7 @@
#include <qutim/metacontactmanager.h>
#include "metacontactimpl.h"
+#include "messagehandler.h"
namespace qutim_sdk_0_3 {
class RosterStorage;
@@ -62,6 +63,7 @@ private slots:
QScopedPointer<Factory> m_factory;
friend class Factory;
bool m_blockUpdate;
+ QScopedPointer <MetaContactMessageHandler> m_handler;
};
}
}
View
57 core/src/corelayers/metacontacts/mergedialog.cpp
@@ -3,6 +3,7 @@
** qutIM - instant messenger
**
** Copyright © 2011 Aleksey Sidorov <gorthauer87@yandex.ru>
+** Copyright © 2012 Sergei Lopatin <magist3r@gmail.com>
**
*****************************************************************************
**
@@ -36,9 +37,9 @@ using namespace qutim_sdk_0_3;
MergeDialog::MergeDialog(QWidget *parent) :
QDialog(parent),
- ui(new Ui::MergeDialog)
+ ui(new Ui::MergeDialog)
{
- ui->setupUi(this);
+ ui->setupUi(this);
ui->treeView->setModel(m_model = new Model(this));
ui->treeView->setItemDelegate(new ItemDelegate(this));
ui->treeView->expandAll();
@@ -47,15 +48,29 @@ MergeDialog::MergeDialog(QWidget *parent) :
m_model, SLOT(searchContacts(QString)));
connect(ui->treeView, SIGNAL(clicked(QModelIndex)),
m_model, SLOT(activated(QModelIndex)));
- connect(m_model, SIGNAL(addContactTriggered(qutim_sdk_0_3::Contact*)),
- this, SLOT(addContact(qutim_sdk_0_3::Contact*)));
- connect(m_model, SIGNAL(removeContactTriggered(qutim_sdk_0_3::Contact*)),
- this, SLOT(removeContact(qutim_sdk_0_3::Contact*)));
+ connect(ui->treeView, SIGNAL(clicked(QModelIndex)),
+ this, SLOT(onClicked()));
}
MergeDialog::~MergeDialog()
{
- delete ui;
+ delete ui;
+}
+
+void MergeDialog::accept()
+{
+ QList<Contact*> contacts = m_model->getContacts();
+ if(!(contacts.count() < 2)) {
+ MetaContactImpl *metaContact = m_model->metaContact();
+ if (!metaContact)
+ metaContact = static_cast<MetaContactImpl*>(MetaContactManager::instance()->createContact());
+
+ if (ui->nameEdit->text().size() != 0)
+ metaContact->setName(ui->nameEdit->text());
+ metaContact->addContacts(contacts, true);
+
+ }
+ QDialog::accept();
}
void MergeDialog::setMetaContact(MetaContactImpl* contact)
@@ -69,25 +84,6 @@ void MergeDialog::setMetaContact(MetaContactImpl* contact)
nameChanged(contact->name());
}
-void MergeDialog::addContact(qutim_sdk_0_3::Contact *contact)
-{
- MetaContactImpl *metaContact = m_model->metaContact();
- if (!metaContact) {
- metaContact = static_cast<MetaContactImpl*>(MetaContactManager::instance()->createContact());
- metaContact->addContact(contact);
- setMetaContact(metaContact);
- } else
- metaContact->addContact(contact);
-
-}
-
-void MergeDialog::removeContact(qutim_sdk_0_3::Contact *contact)
-{
- MetaContactImpl *metaContact = m_model->metaContact();
- Q_ASSERT(metaContact);
- metaContact->removeContact(contact);
-}
-
void MergeDialog::setName(const QString& name)
{
if(m_model->metaContact())
@@ -97,7 +93,7 @@ void MergeDialog::setName(const QString& name)
void MergeDialog::closeEvent(QCloseEvent *ev)
{
setName(ui->nameEdit->text());
- QWidget::closeEvent(ev);
+ QWidget::closeEvent(ev);
}
void MergeDialog::nameChanged(const QString& name)
@@ -106,6 +102,13 @@ void MergeDialog::nameChanged(const QString& name)
setWindowTitle(tr("%1 - qutIM").arg(name));
}
+void MergeDialog::onClicked()
+{
+ if(!(ui->searchField->text().size() == 0))
+ m_model->searchContacts(ui->searchField->text());
+ else if(!(ui->nameEdit->text().size() == 0))
+ m_model->searchContacts(ui->nameEdit->text());
+}
} // namespace MetaContacts
} // namespace Core
View
15 core/src/corelayers/metacontacts/mergedialog.h
@@ -3,6 +3,7 @@
** qutIM - instant messenger
**
** Copyright © 2011 Aleksey Sidorov <gorthauer87@yandex.ru>
+** Copyright © 2012 Sergei Lopatin <magist3r@gmail.com>
**
*****************************************************************************
**
@@ -41,26 +42,26 @@ class Model;
namespace Ui {
- class MergeDialog;
+ class MergeDialog;
}
class MetaContactImpl;
class MergeDialog : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
public:
explicit MergeDialog(QWidget *parent = 0);
- ~MergeDialog();
+ ~MergeDialog();
void setMetaContact(MetaContactImpl *contact);
protected:
- virtual void closeEvent(QCloseEvent* );
+ virtual void closeEvent(QCloseEvent* );
private slots:
- void addContact(qutim_sdk_0_3::Contact *);
- void removeContact(qutim_sdk_0_3::Contact *);
void setName(const QString &name);
void nameChanged(const QString &name);
+ void onClicked();
+ void accept();
private:
- Ui::MergeDialog *ui;
+ Ui::MergeDialog *ui;
Model *m_model;
};
View
8 core/src/corelayers/metacontacts/mergedialog.ui
@@ -77,12 +77,12 @@
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
- <x>186</x>
- <y>438</y>
+ <x>206</x>
+ <y>437</y>
</hint>
<hint type="destinationlabel">
- <x>186</x>
- <y>227</y>
+ <x>2</x>
+ <y>235</y>
</hint>
</hints>
</connection>
View
64 core/src/corelayers/metacontacts/messagehandler.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** qutIM - instant messenger
+**
+** Copyright © 2012 Ruslan Nigmatullin <euroelessar@yandex.ru>
+** Copyright © 2012 Sergei Lopatin <magist3r@gmail.com>
+**
+*****************************************************************************
+**
+** $QUTIM_BEGIN_LICENSE$
+** 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/.
+** $QUTIM_END_LICENSE$
+**
+****************************************************************************/
+
+#include "messagehandler.h"
+#include <qutim/debug.h>
+#include <qutim/metacontact.h>
+#include <qutim/account.h>
+#include <qutim/protocol.h>
+#include "metacontactimpl.h"
+
+using namespace qutim_sdk_0_3;
+
+namespace Core
+{
+namespace MetaContacts
+{
+MetaContactMessageHandler::MetaContactMessageHandler()
+{
+}
+
+MessageHandler::Result MetaContactMessageHandler::doHandle(qutim_sdk_0_3::Message &message, QString *reason)
+{
+ if (message.isIncoming()) {
+ if (MetaContactImpl *contact = qobject_cast<MetaContactImpl*>(message.chatUnit()->metaContact())) {
+ Contact *rawContact = 0;
+ ChatUnit *u = message.chatUnit();
+ while (u) {
+ if ((rawContact = qobject_cast<Contact*>(u)))
+ break;
+ u = u->upperUnit();
+ }
+ if (rawContact && contact->getActiveContact()->buddy() != rawContact)
+ contact->setActiveContact(rawContact);
+ }
+ }
+ return MetaContactMessageHandler::Accept;
+
+}
+
+}
+}
View
47 core/src/corelayers/metacontacts/messagehandler.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** qutIM - instant messenger
+**
+** Copyright © 2012 Ruslan Nigmatullin <euroelessar@yandex.ru>
+** Copyright © 2012 Sergei Lopatin <magist3r@gmail.com>
+**
+*****************************************************************************
+**
+** $QUTIM_BEGIN_LICENSE$
+** 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/.
+** $QUTIM_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef METACONTACTMESSAGEHANDLER_H
+#define METACONTACTMESSAGEHANDLER_H
+
+#include <qutim/messagehandler.h>
+
+namespace Core
+{
+namespace MetaContacts
+{
+class MetaContactMessageHandler : public qutim_sdk_0_3::MessageHandler
+{
+public:
+ MetaContactMessageHandler();
+protected:
+ virtual qutim_sdk_0_3::MessageHandler::Result doHandle(qutim_sdk_0_3::Message &message, QString *reason);
+};
+
+}
+}
+
+#endif // METACONTACTMESSAGEHANDLER_H
View
108 core/src/corelayers/metacontacts/metacontactimpl.cpp
@@ -3,6 +3,7 @@
** qutIM - instant messenger
**
** Copyright © 2011 Ruslan Nigmatullin <euroelessar@yandex.ru>
+** Copyright © 2012 Sergei Lopatin <magist3r@gmail.com>
**
*****************************************************************************
**
@@ -54,6 +55,7 @@ bool contactLessThan(Contact *a, Contact *b)
MetaContactImpl::MetaContactImpl(const QString &id) : m_id(id)
{
+ connect(ChatLayer::instance(),SIGNAL(sessionCreated(qutim_sdk_0_3::ChatSession*)), this, SLOT(onSessionCreated(qutim_sdk_0_3::ChatSession*)));
}
MetaContactImpl::~MetaContactImpl()
@@ -90,12 +92,7 @@ void MetaContactImpl::setTags(const QStringList &tags)
bool MetaContactImpl::sendMessage(const Message &message)
{
- //TODO implement logic
- for (int i = 0; i < m_contacts.size(); i++) {
- if (m_contacts.at(i)->sendMessage(message))
- return true;
- }
- return false;
+ return m_active_contact->sendMessage(message);
}
void MetaContactImpl::addContact(Contact* contact, bool update)
@@ -114,24 +111,24 @@ void MetaContactImpl::addContact(Contact* contact, bool update)
emit tagsChanged(m_tags, previous);
}
- int index = qUpperBound(m_contacts.begin(), m_contacts.end(), contact, contactLessThan)
- - m_contacts.begin();
- m_contacts.insert(index, contact);
+ m_contacts.append(contact);
MetaContact::addContact(contact);
connect(contact, SIGNAL(statusChanged(qutim_sdk_0_3::Status,qutim_sdk_0_3::Status)),
SLOT(onContactStatusChanged()));
connect(contact, SIGNAL(avatarChanged(QString)),
SLOT(setAvatar(QString)));
+ connect(contact, SIGNAL(chatStateChanged(qutim_sdk_0_3::ChatState,qutim_sdk_0_3::ChatState)),
+ this,SIGNAL(chatStateChanged(qutim_sdk_0_3::ChatState,qutim_sdk_0_3::ChatState)));
- if (index == 0)
- resetStatus();
- if (m_contacts.size() == 1 || m_name.isEmpty())
+ if (m_name.isEmpty())
resetName();
//setMenuOwner(contact); TODO, implement logic!
if(update)
RosterStorage::instance()->updateContact(this);
+ setActiveContact();
+ resetStatus();
}
void MetaContactImpl::addContact(Contact *contact)
@@ -180,7 +177,16 @@ void MetaContactImpl::resetStatus()
return;
}
Status previous = m_status;
- Status contactStatus = m_contacts.first()->status();
+ Status contactStatus = m_active_contact->status();
+ if (contactStatus.type() == Status::Offline) {
+ for(int i = 0; i < m_contacts.size(); i++) {
+ if (m_contacts.at(i)->status().type() != Status::Offline) {
+ contactStatus = m_contacts.at(i)->status();
+ break;
+ }
+
+ }
+ }
if (contactStatus.type() == m_status.type()
&& contactStatus.text() == m_status.text()) {
return;
@@ -193,10 +199,13 @@ void MetaContactImpl::resetStatus()
QHash<QString, QVariantHash> hash = m_contacts.at(i)->status().extendedInfos();
QHash<QString, QVariantHash>::const_iterator it = hash.constBegin();
QHash<QString, QVariantHash>::const_iterator endit = hash.constEnd();
+ const QString showInTooltip = QLatin1String("showInTooltip");
for (; it != endit; it++) {
if (!keys.contains(it.key())) {
keys << it.key();
- m_status.setExtendedInfo(it.key(), it.value());
+ QVariantHash data = it.value();
+ data.insert(showInTooltip, false);
+ m_status.setExtendedInfo(it.key(), data);
}
}
}
@@ -205,14 +214,7 @@ void MetaContactImpl::resetStatus()
void MetaContactImpl::onContactStatusChanged()
{
- Contact *contact = qobject_cast<Contact*>(sender());
- int oldIndex = m_contacts.indexOf(contact);
- int index = qUpperBound(m_contacts.begin(), m_contacts.end(), contact, contactLessThan)
- - m_contacts.begin();
- if (index != oldIndex && index != m_contacts.count())
- m_contacts.move(oldIndex, index);
- if (index == 0 || oldIndex == 0)
- resetStatus();
+ resetStatus();
}
void MetaContactImpl::setAvatar(const QString& path)
@@ -231,38 +233,42 @@ qutim_sdk_0_3::ChatUnitList MetaContactImpl::lowerUnits()
const qutim_sdk_0_3::ChatUnit* MetaContactImpl::getHistoryUnit() const
{
- //implement logic
- return m_contacts.first();
+ //TODO improve history
+ return m_active_contact;
}
bool MetaContactImpl::event(QEvent* ev)
{
if (ev->type() == ToolTipEvent::eventType()) {
- if (ev->type() == ToolTipEvent::eventType()) {
- ToolTipEvent *event = static_cast<ToolTipEvent*>(ev);
- if (event->generateLayout())
- Contact::event(ev);
- foreach (ChatUnit *contact, m_contacts) {
- ToolTipEvent contactEvent(false);
- qApp->sendEvent(contact, &contactEvent);
- QString text = contactEvent.html();
- if (!text.isEmpty())
- event->addHtml(QLatin1Literal("<br/><br/>") % text);
- }
- return true;
+ ToolTipEvent *event = static_cast<ToolTipEvent*>(ev);
+ if (event->generateLayout())
+ Contact::event(ev);
+ foreach (ChatUnit *contact, m_contacts) {
+ ToolTipEvent contactEvent(false);
+ qApp->sendEvent(contact, &contactEvent);
+ QString text = contactEvent.html();
+ if (!text.isEmpty())
+ event->addHtml(QLatin1Literal("<br/><br/>") % text);
}
+ return true;
} else if(ev->type() == ChatStateEvent::eventType()) {
ChatStateEvent *event = static_cast<ChatStateEvent*>(ev);
- //TODO implement logic
- qApp->sendEvent(m_contacts.first(),event);
+ qApp->sendEvent(m_active_contact,event);
}
return qutim_sdk_0_3::MetaContact::event(ev);
}
-void MetaContactImpl::addContacts(QList<Contact*> contacts)
+void MetaContactImpl::addContacts(QList<Contact*> contacts, bool remove)
{
- foreach(Contact *contact, contacts)
- addContact(contact,false);
+ bool update = false;
+ if(remove) {
+ m_contacts.clear();
+ update = true;
+ }
+
+ foreach(Contact *contact, contacts) {
+ addContact(contact,update);
+ }
}
void MetaContactImpl::setContactAvatar(const QString& path)
@@ -289,7 +295,27 @@ void MetaContactImpl::setContactTags(const QStringList& tags)
emit tagsChanged(m_tags,previous);
}
+void MetaContactImpl::setActiveContact(Contact* contact)
+{
+ if(contact) {
+ m_active_contact = contact;
+ return;
+ }
+ for (int i = 0; i < m_contacts.size(); i++) {
+ if (m_contacts.at(i)->status().type() != Status::Offline) {
+ m_active_contact = m_contacts.at(i);
+ return;
+ }
+ }
+ m_active_contact = m_contacts.at(0);
+}
+void MetaContactImpl::onSessionCreated(ChatSession *session)
+{
+ MetaContact *contact = qobject_cast<MetaContact*>(session->unit());
+ if(contact == this->metaContact())
+ setActiveContact();
+}
}
}
View
9 core/src/corelayers/metacontacts/metacontactimpl.h
@@ -3,6 +3,7 @@
** qutIM - instant messenger
**
** Copyright © 2011 Ruslan Nigmatullin <euroelessar@yandex.ru>
+** Copyright © 2012 Sergei Lopatin <magist3r@gmail.com>
**
*****************************************************************************
**
@@ -27,6 +28,8 @@
#define METACONTACTIMPL_H
#include <qutim/metacontact.h>
+#include <qutim/chatsession.h>
+
namespace Core
{
@@ -48,7 +51,7 @@ class MetaContactImpl : public qutim_sdk_0_3::MetaContact
virtual void setTags(const QStringList &tags);
virtual bool sendMessage(const qutim_sdk_0_3::Message &message);
virtual void addContact(Contact *contact);
- void addContacts(QList<Contact*> contacts);
+ void addContacts(QList<Contact*> contacts, bool remove = false);
virtual void removeContact(Contact *contact);
virtual qutim_sdk_0_3::ChatUnitList lowerUnits();
inline const QList<Contact*> &contacts() const { return m_contacts; }
@@ -56,6 +59,8 @@ class MetaContactImpl : public qutim_sdk_0_3::MetaContact
void setContactName(const QString &name);
void setContactAvatar(const QString &name);
void setContactTags(const QStringList &tags);
+ void setActiveContact(Contact* contact = 0);
+ Contact* getActiveContact() { return m_active_contact; }
public slots:
void setAvatar(const QString &path);
protected:
@@ -64,6 +69,7 @@ public slots:
void addContact(Contact* contact, bool update);
protected slots:
void onContactStatusChanged();
+ void onSessionCreated(qutim_sdk_0_3::ChatSession *session);
private:
virtual bool event(QEvent *ev);
QString m_id;
@@ -72,6 +78,7 @@ protected slots:
QStringList m_tags;
QList<Contact*> m_contacts;
QString m_lastAvatar;
+ Contact* m_active_contact;
};
}
}
View
20 core/src/corelayers/metacontacts/model.cpp
@@ -3,6 +3,7 @@
** qutIM - instant messenger
**
** Copyright © 2011 Aleksey Sidorov <gorthauer87@yandex.ru>
+** Copyright © 2012 Sergei Lopatin <magist3r@gmail.com>
**
*****************************************************************************
**
@@ -56,11 +57,12 @@ void Model::searchContacts(const QString& name)
if(name.isEmpty())
return;
+ QList<Contact*> contacts = getContacts();
foreach(Account *account,Account::all()) {
foreach(Contact *contact, account->findChildren<Contact*>()) {
if(!contact->title().contains(name,Qt::CaseInsensitive))
continue;
- if(m_metaContact && m_metaContact.data()->contacts().contains(contact))
+ if(contacts.contains(contact))
continue;
addContact(contact,m_searchRoot);
}
@@ -105,15 +107,21 @@ void Model::activated(const QModelIndex& index)
Contact *contact = item->data().value<Contact*>();
if(!contact)
return;
- if(item->parent() == m_metaRoot) {
- emit removeContactTriggered(contact);
- } else {
+ if(!(item->parent() == m_metaRoot))
addContact(contact,m_metaRoot);
- emit addContactTriggered(contact);
- }
+
item->parent()->removeRow(index.row());
}
+QList<Contact*> Model::getContacts() const
+{
+ QList<Contact*> contacts;
+ for(int i = 0; i != m_metaRoot->rowCount(); i++)
+ contacts.append(m_metaRoot->child(i)->data().value<Contact*>());
+
+ return contacts;
+}
+
} // namespace MetaContacts
} // namespace Core
View
4 core/src/corelayers/metacontacts/model.h
@@ -3,6 +3,7 @@
** qutIM - instant messenger
**
** Copyright © 2011 Aleksey Sidorov <gorthauer87@yandex.ru>
+** Copyright © 2012 Sergei Lopatin <magist3r@gmail.com>
**
*****************************************************************************
**
@@ -45,6 +46,7 @@ class Model : public QStandardItemModel
explicit Model(QObject *parent = 0);
void setMetaContact(MetaContactImpl*);
MetaContactImpl *metaContact() const;
+ QList<qutim_sdk_0_3::Contact*> getContacts() const;
public slots:
void searchContacts(const QString &name);
void activated(const QModelIndex &index);
@@ -54,7 +56,7 @@ public slots:
private:
void addContact(qutim_sdk_0_3::Contact *,QStandardItem *root);
QWeakPointer<MetaContactImpl> m_metaContact;
- QStandardItem *m_metaRoot;
+ QStandardItem *m_metaRoot;
QStandardItem *m_searchRoot;
};
View
6 core/src/corelayers/notificationfilter/notificationfilter.cpp
@@ -91,6 +91,8 @@ static QString toString(Notification::Type type, const QString &argument)
static inline ChatUnit *getUnitForSession(QObject *obj)
{
ChatUnit *unit = qobject_cast<ChatUnit*>(obj);
+ if (ChatUnit *contact = unit->metaContact())
+ unit = contact;
return unit ? unit->account()->getUnitForSession(unit) : 0;
}
@@ -227,7 +229,7 @@ void NotificationFilterImpl::notificationCreated(Notification *notification)
void NotificationFilterImpl::onOpenChatClicked(const NotificationRequest &request)
{
- ChatUnit *unit = qobject_cast<ChatUnit*>(request.object());
+ ChatUnit *unit = getUnitForSession(request.object());
if (!unit)
return;
ChatSession *session = ChatLayer::get(unit);
@@ -240,7 +242,7 @@ void NotificationFilterImpl::onIgnoreChatClicked(const NotificationRequest &requ
QVariant msgVar = request.property("message", QVariant());
if (msgVar.isNull())
return;
- ChatUnit *unit = qobject_cast<ChatUnit*>(request.object());
+ ChatUnit *unit = getUnitForSession(request.object());
if (!unit)
return;
ChatSession *session = ChatLayer::get(unit, false);
Please sign in to comment.
Something went wrong with that request. Please try again.