| /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */ |
| /* |
| * Copyright (c) 2013, Regents of the University of California |
| * Yingdi Yu |
| * |
| * BSD license, See the LICENSE file for more information |
| * |
| * Author: Yingdi Yu <yingdi@cs.ucla.edu> |
| * Qiuhan Ding <qiuhanding@cs.ucla.edu> |
| */ |
| |
| #include <QApplication> |
| #include <QMessageBox> |
| #include <QDir> |
| #include <QTimer> |
| #include "controller.hpp" |
| |
| #ifndef Q_MOC_RUN |
| #include <boost/filesystem.hpp> |
| #include <boost/lexical_cast.hpp> |
| #include <ndn-cxx/util/random.hpp> |
| #include "cryptopp.hpp" |
| #include "logging.h" |
| #include "conf.hpp" |
| #include "endorse-info.hpp" |
| #endif |
| |
| INIT_LOGGER("chronochat.Controller"); |
| |
| Q_DECLARE_METATYPE(ndn::Name) |
| Q_DECLARE_METATYPE(ndn::security::Certificate) |
| Q_DECLARE_METATYPE(chronochat::EndorseInfo) |
| Q_DECLARE_METATYPE(ndn::Interest) |
| Q_DECLARE_METATYPE(size_t) |
| Q_DECLARE_METATYPE(chronochat::ChatroomInfo) |
| Q_DECLARE_METATYPE(chronochat::Invitation) |
| Q_DECLARE_METATYPE(std::string) |
| Q_DECLARE_METATYPE(ndn::Name::Component) |
| |
| namespace chronochat { |
| |
| using std::string; |
| |
| // constructor & destructor |
| Controller::Controller(QWidget* parent) |
| : QDialog(parent) |
| , m_localPrefixDetected(false) |
| , m_isInConnectionDetection(false) |
| , m_settingDialog(new SettingDialog(this)) |
| , m_startChatDialog(new StartChatDialog(this)) |
| , m_profileEditor(new ProfileEditor(this)) |
| , m_invitationDialog(new InvitationDialog(this)) |
| , m_invitationRequestDialog(new InvitationRequestDialog(this)) |
| , m_contactPanel(new ContactPanel(this)) |
| , m_browseContactDialog(new BrowseContactDialog(this)) |
| , m_addContactPanel(new AddContactPanel(this)) |
| , m_discoveryPanel(new DiscoveryPanel(this)) |
| { |
| qRegisterMetaType<ndn::Name>("ndn.Name"); |
| qRegisterMetaType<ndn::security::Certificate>("ndn.security.v2.Certificate"); |
| qRegisterMetaType<chronochat::EndorseInfo>("EndorseInfo"); |
| qRegisterMetaType<ndn::Interest>("ndn.Interest"); |
| qRegisterMetaType<size_t>("size_t"); |
| qRegisterMetaType<chronochat::ChatroomInfo>("chronochat.Chatroom"); |
| qRegisterMetaType<chronochat::Invitation>("chronochat.Invitation"); |
| qRegisterMetaType<std::string>("std.string"); |
| qRegisterMetaType<ndn::Name::Component>("ndn.Component"); |
| |
| |
| // Connection to ContactManager |
| connect(m_backend.getContactManager(), SIGNAL(warning(const QString&)), |
| this, SLOT(onWarning(const QString&))); |
| connect(this, SIGNAL(refreshBrowseContact()), |
| m_backend.getContactManager(), SLOT(onRefreshBrowseContact())); |
| connect(m_backend.getContactManager(), SIGNAL(contactInfoFetchFailed(const QString&)), |
| this, SLOT(onWarning(const QString&))); |
| |
| // Connection to SettingDialog |
| connect(this, SIGNAL(identityUpdated(const QString&)), |
| m_settingDialog, SLOT(onIdentityUpdated(const QString&))); |
| connect(m_settingDialog, SIGNAL(identityUpdated(const QString&)), |
| this, SLOT(onIdentityUpdated(const QString&))); |
| connect(m_settingDialog, SIGNAL(nickUpdated(const QString&)), |
| this, SLOT(onNickUpdated(const QString&))); |
| connect(m_settingDialog, SIGNAL(prefixUpdated(const QString&)), |
| this, SLOT(onLocalPrefixConfigured(const QString&))); |
| |
| // Connection to ProfileEditor |
| connect(this, SIGNAL(closeDBModule()), |
| m_profileEditor, SLOT(onCloseDBModule())); |
| connect(this, SIGNAL(identityUpdated(const QString&)), |
| m_profileEditor, SLOT(onIdentityUpdated(const QString&))); |
| connect(m_profileEditor, SIGNAL(updateProfile()), |
| m_backend.getContactManager(), SLOT(onUpdateProfile())); |
| |
| // Connection to StartChatDialog |
| connect(m_startChatDialog, SIGNAL(startChatroom(const QString&, bool)), |
| this, SLOT(onStartChatroom(const QString&, bool))); |
| |
| // Connection to InvitationDialog |
| connect(m_invitationDialog, SIGNAL(invitationResponded(const ndn::Name&, bool)), |
| &m_backend, SLOT(onInvitationResponded(const ndn::Name&, bool))); |
| |
| // Connection to InvitationRequestDialog |
| connect(m_invitationRequestDialog, SIGNAL(invitationRequestResponded(const ndn::Name&, bool)), |
| &m_backend, SLOT(onInvitationRequestResponded(const ndn::Name&, bool))); |
| |
| // Connection to AddContactPanel |
| connect(m_addContactPanel, SIGNAL(fetchInfo(const QString&)), |
| m_backend.getContactManager(), SLOT(onFetchContactInfo(const QString&))); |
| connect(m_addContactPanel, SIGNAL(addContact(const QString&)), |
| m_backend.getContactManager(), SLOT(onAddFetchedContact(const QString&))); |
| connect(m_backend.getContactManager(), |
| SIGNAL(contactEndorseInfoReady(const EndorseInfo&)), |
| m_addContactPanel, |
| SLOT(onContactEndorseInfoReady(const EndorseInfo&))); |
| |
| // Connection to BrowseContactDialog |
| connect(m_browseContactDialog, SIGNAL(directAddClicked()), |
| this, SLOT(onDirectAdd())); |
| connect(m_browseContactDialog, SIGNAL(fetchIdCert(const QString&)), |
| m_backend.getContactManager(), SLOT(onFetchIdCert(const QString&))); |
| connect(m_browseContactDialog, SIGNAL(addContact(const QString&)), |
| m_backend.getContactManager(), SLOT(onAddFetchedContactIdCert(const QString&))); |
| connect(m_backend.getContactManager(), SIGNAL(idCertNameListReady(const QStringList&)), |
| m_browseContactDialog, SLOT(onIdCertNameListReady(const QStringList&))); |
| connect(m_backend.getContactManager(), SIGNAL(nameListReady(const QStringList&)), |
| m_browseContactDialog, SLOT(onNameListReady(const QStringList&))); |
| connect(m_backend.getContactManager(), SIGNAL(idCertReady(const ndn::security::Certificate&)), |
| m_browseContactDialog, SLOT(onIdCertReady(const ndn::security::Certificate&))); |
| |
| // Connection to ContactPanel |
| connect(m_contactPanel, SIGNAL(waitForContactList()), |
| m_backend.getContactManager(), SLOT(onWaitForContactList())); |
| connect(m_contactPanel, SIGNAL(waitForContactInfo(const QString&)), |
| m_backend.getContactManager(), SLOT(onWaitForContactInfo(const QString&))); |
| connect(m_contactPanel, SIGNAL(removeContact(const QString&)), |
| m_backend.getContactManager(), SLOT(onRemoveContact(const QString&))); |
| connect(m_contactPanel, SIGNAL(updateAlias(const QString&, const QString&)), |
| m_backend.getContactManager(), SLOT(onUpdateAlias(const QString&, const QString&))); |
| connect(m_contactPanel, SIGNAL(updateIsIntroducer(const QString&, bool)), |
| m_backend.getContactManager(), SLOT(onUpdateIsIntroducer(const QString&, bool))); |
| connect(m_contactPanel, SIGNAL(updateEndorseCertificate(const QString&)), |
| m_backend.getContactManager(), SLOT(onUpdateEndorseCertificate(const QString&))); |
| connect(m_contactPanel, SIGNAL(warning(const QString&)), |
| this, SLOT(onWarning(const QString&))); |
| connect(this, SIGNAL(closeDBModule()), |
| m_contactPanel, SLOT(onCloseDBModule())); |
| connect(this, SIGNAL(identityUpdated(const QString&)), |
| m_contactPanel, SLOT(onIdentityUpdated(const QString&))); |
| connect(m_backend.getContactManager(), SIGNAL(contactAliasListReady(const QStringList&)), |
| m_contactPanel, SLOT(onContactAliasListReady(const QStringList&))); |
| connect(m_backend.getContactManager(), SIGNAL(contactIdListReady(const QStringList&)), |
| m_contactPanel, SLOT(onContactIdListReady(const QStringList&))); |
| connect(m_backend.getContactManager(), SIGNAL(contactInfoReady(const QString&, const QString&, |
| const QString&, bool)), |
| m_contactPanel, SLOT(onContactInfoReady(const QString&, const QString&, |
| const QString&, bool))); |
| |
| // Connection to backend thread |
| connect(&m_backend, SIGNAL(nfdError()), |
| this, SLOT(onNfdError())); |
| connect(this, SIGNAL(nfdReconnect()), |
| &m_backend, SLOT(onNfdReconnect())); |
| connect(this, SIGNAL(shutdownBackend()), |
| &m_backend, SLOT(shutdown())); |
| connect(this, SIGNAL(updateLocalPrefix()), |
| &m_backend, SLOT(onUpdateLocalPrefixAction())); |
| connect(this, SIGNAL(identityUpdated(const QString&)), |
| &m_backend, SLOT(onIdentityChanged(const QString&))); |
| connect(this, SIGNAL(addChatroom(QString)), |
| &m_backend, SLOT(addChatroom(QString))); |
| connect(this, SIGNAL(removeChatroom(QString)), |
| &m_backend, SLOT(removeChatroom(QString))); |
| |
| // Thread notifications: |
| // on local prefix udpated: |
| connect(&m_backend, SIGNAL(localPrefixUpdated(const QString&)), |
| this, SLOT(onLocalPrefixUpdated(const QString&))); |
| connect(&m_backend, SIGNAL(localPrefixUpdated(const QString&)), |
| m_settingDialog, SLOT(onLocalPrefixUpdated(const QString&))); |
| |
| // on invitation validated: |
| connect(&m_backend, SIGNAL(invitationValidated(QString, QString, ndn::Name)), |
| m_invitationDialog, SLOT(onInvitationReceived(QString, QString, ndn::Name))); |
| connect(&m_backend, SIGNAL(startChatroom(const QString&, bool)), |
| this, SLOT(onStartChatroom(const QString&, bool))); |
| |
| // on invitation request received |
| connect(&m_backend, SIGNAL(invitationRequestReceived(QString, QString, ndn::Name)), |
| m_invitationRequestDialog, SLOT(onInvitationRequestReceived(QString, QString, |
| ndn::Name))); |
| |
| // on invitation accepted: |
| connect(&m_backend, SIGNAL(startChatroomOnInvitation(chronochat::Invitation, bool)), |
| this, SLOT(onStartChatroom2(chronochat::Invitation, bool))); |
| |
| m_backend.start(); |
| |
| initialize(); |
| |
| m_chatroomDiscoveryBackend |
| = new ChatroomDiscoveryBackend(m_localPrefix, |
| m_identity, |
| this); |
| |
| // connect to chatroom discovery back end |
| connect(&m_backend, SIGNAL(localPrefixUpdated(const QString&)), |
| m_chatroomDiscoveryBackend, SLOT(updateRoutingPrefix(const QString&))); |
| connect(this, SIGNAL(localPrefixConfigured(const QString&)), |
| m_chatroomDiscoveryBackend, SLOT(updateRoutingPrefix(const QString&))); |
| connect(m_chatroomDiscoveryBackend, SIGNAL(chatroomInfoRequest(std::string, bool)), |
| this, SLOT(onChatroomInfoRequest(std::string, bool))); |
| connect(this, SIGNAL(respondChatroomInfoRequest(ChatroomInfo, bool)), |
| m_chatroomDiscoveryBackend, SLOT(onRespondChatroomInfoRequest(ChatroomInfo, bool))); |
| connect(this, SIGNAL(shutdownDiscoveryBackend()), |
| m_chatroomDiscoveryBackend, SLOT(shutdown())); |
| connect(this, SIGNAL(identityUpdated(const QString&)), |
| m_chatroomDiscoveryBackend, SLOT(onIdentityUpdated(const QString&))); |
| connect(this, SIGNAL(nfdReconnect()), |
| m_chatroomDiscoveryBackend, SLOT(onNfdReconnect())); |
| connect(m_chatroomDiscoveryBackend, SIGNAL(nfdError()), |
| this, SLOT(onNfdError())); |
| |
| // connect chatroom discovery back end with front end |
| connect(m_discoveryPanel, SIGNAL(waitForChatroomInfo(const QString&)), |
| m_chatroomDiscoveryBackend, SLOT(onWaitForChatroomInfo(const QString&))); |
| connect(m_discoveryPanel, SIGNAL(warning(const QString&)), |
| this, SLOT(onWarning(const QString&))); |
| connect(this, SIGNAL(identityUpdated(const QString&)), |
| m_discoveryPanel, SLOT(onIdentityUpdated(const QString&))); |
| connect(m_chatroomDiscoveryBackend, SIGNAL(chatroomListReady(const QStringList&)), |
| m_discoveryPanel, SLOT(onChatroomListReady(const QStringList&))); |
| connect(m_chatroomDiscoveryBackend, SIGNAL(chatroomInfoReady(const ChatroomInfo&, bool)), |
| m_discoveryPanel, SLOT(onChatroomInfoReady(const ChatroomInfo&, bool))); |
| connect(m_discoveryPanel, SIGNAL(startChatroom(const QString&, bool)), |
| this, SLOT(onStartChatroom(const QString&, bool))); |
| connect(m_discoveryPanel, SIGNAL(sendInvitationRequest(const QString&, const QString&)), |
| &m_backend, SLOT(onSendInvitationRequest(const QString&, const QString&))); |
| connect(&m_backend, SIGNAL(invitationRequestResult(const std::string&)), |
| m_discoveryPanel, SLOT(onInvitationRequestResult(const std::string&))); |
| |
| m_chatroomDiscoveryBackend->start(); |
| |
| createTrayIcon(); |
| |
| emit updateLocalPrefix(); |
| } |
| |
| Controller::~Controller() |
| { |
| saveConf(); |
| } |
| |
| // public methods |
| |
| |
| // private methods |
| string |
| Controller::getDBName() |
| { |
| string dbName("chronos-"); |
| |
| std::stringstream ss; |
| { |
| using namespace CryptoPP; |
| |
| SHA256 hash; |
| StringSource(m_identity.wireEncode().wire(), m_identity.wireEncode().size(), true, |
| new HashFilter(hash, new HexEncoder(new FileSink(ss), false))); |
| } |
| dbName.append(ss.str()).append(".db"); |
| |
| return dbName; |
| } |
| |
| void |
| Controller::openDB() |
| { |
| m_db = QSqlDatabase::addDatabase("QSQLITE"); |
| QString path = (QDir::home().path()); |
| path.append(QDir::separator()) |
| .append(".chronos") |
| .append(QDir::separator()) |
| .append(getDBName().c_str()); |
| m_db.setDatabaseName(path); |
| |
| m_db.open(); |
| |
| // bool ok = m_db.open(); |
| // _LOG_DEBUG("DB opened: " << std::boolalpha << ok ); |
| } |
| |
| void |
| Controller::initialize() |
| { |
| loadConf(); |
| |
| openDB(); |
| |
| emit identityUpdated(QString(m_identity.toUri().c_str())); |
| } |
| |
| void |
| Controller::loadConf() |
| { |
| namespace fs = boost::filesystem; |
| |
| fs::path chronosDir = fs::path(getenv("HOME")) / ".chronos"; |
| fs::create_directories (chronosDir); |
| |
| std::ifstream is((chronosDir / "config").c_str ()); |
| Conf conf; |
| Block confBlock; |
| try { |
| confBlock = ndn::Block::fromStream(is); |
| conf.wireDecode(confBlock); |
| m_identity.clear(); |
| m_identity.append(conf.getIdentity()); |
| if (conf.getNick().length() != 0) |
| m_nick = conf.getNick(); |
| else |
| m_nick = m_identity.get(-1).toUri(); |
| } |
| catch (tlv::Error&) { |
| try { |
| ndn::KeyChain keyChain; |
| m_identity = keyChain.getPib().getDefaultIdentity().getName(); |
| } |
| catch (ndn::security::pib::Pib::Error&) { |
| m_identity.clear(); |
| m_identity.append("chronochat-tmp-identity") |
| .append(getRandomString()); |
| } |
| m_nick = m_identity.get(-1).toUri(); |
| } |
| } |
| |
| void |
| Controller::saveConf() |
| { |
| namespace fs = boost::filesystem; |
| |
| fs::path chronosDir = fs::path(getenv("HOME")) / ".chronos"; |
| fs::create_directories (chronosDir); |
| |
| std::ofstream os((chronosDir / "config").c_str ()); |
| Conf conf; |
| conf.setIdentity(m_identity); |
| if (!m_nick.empty()) |
| conf.setNick(m_nick); |
| Block confWire = conf.wireEncode(); |
| os.write(reinterpret_cast<const char*>(confWire.wire()), confWire.size()); |
| |
| os.close(); |
| } |
| |
| void |
| Controller::createActions() |
| { |
| m_startChatroom = new QAction(tr("Start new chat"), this); |
| connect(m_startChatroom, SIGNAL(triggered()), this, SLOT(onStartChatAction())); |
| |
| m_settingsAction = new QAction(tr("Settings"), this); |
| connect(m_settingsAction, SIGNAL(triggered()), this, SLOT(onSettingsAction())); |
| |
| m_editProfileAction = new QAction(tr("Edit profile"), this); |
| connect(m_editProfileAction, SIGNAL(triggered()), this, SLOT(onProfileEditorAction())); |
| |
| m_contactListAction = new QAction(tr("Contact List"), this); |
| connect(m_contactListAction, SIGNAL(triggered()), this, SLOT(onContactListAction())); |
| |
| m_addContactAction = new QAction(tr("Add contact"), this); |
| connect(m_addContactAction, SIGNAL(triggered()), this, SLOT(onAddContactAction())); |
| |
| m_chatroomDiscoveryAction = new QAction(tr("Chatroom Discovery"), this); |
| connect(m_chatroomDiscoveryAction, SIGNAL(triggered()), this, SLOT(onChatroomDiscoveryAction())); |
| |
| m_updateLocalPrefixAction = new QAction(tr("Update local prefix"), this); |
| connect(m_updateLocalPrefixAction, SIGNAL(triggered()), |
| &m_backend, SLOT(onUpdateLocalPrefixAction())); |
| |
| m_minimizeAction = new QAction(tr("Mi&nimize"), this); |
| connect(m_minimizeAction, SIGNAL(triggered()), this, SLOT(onMinimizeAction())); |
| |
| m_quitAction = new QAction(tr("Quit"), this); |
| connect(m_quitAction, SIGNAL(triggered()), this, SLOT(onQuitAction())); |
| |
| } |
| |
| void |
| Controller::createTrayIcon() |
| { |
| createActions(); |
| |
| m_trayIconMenu = new QMenu(this); |
| m_trayIconMenu->addAction(m_startChatroom); |
| m_trayIconMenu->addAction(m_chatroomDiscoveryAction); |
| |
| m_trayIconMenu->addSeparator(); |
| m_trayIconMenu->addAction(m_settingsAction); |
| m_trayIconMenu->addAction(m_editProfileAction); |
| m_trayIconMenu->addSeparator(); |
| m_trayIconMenu->addAction(m_contactListAction); |
| m_trayIconMenu->addAction(m_addContactAction); |
| m_trayIconMenu->addSeparator(); |
| m_trayIconMenu->addAction(m_updateLocalPrefixAction); |
| m_trayIconMenu->addSeparator(); |
| m_trayIconMenu->addAction(m_minimizeAction); |
| m_closeMenu = m_trayIconMenu->addMenu("Close chatroom"); |
| m_closeMenu->setEnabled(false); |
| m_trayIconMenu->addSeparator(); |
| m_trayIconMenu->addAction(m_quitAction); |
| |
| m_trayIcon = new QSystemTrayIcon(this); |
| m_trayIcon->setContextMenu(m_trayIconMenu); |
| |
| m_trayIcon->setIcon(QIcon(":/images/icon_small.png")); |
| m_trayIcon->setToolTip("ChronoChat System Tray Icon"); |
| m_trayIcon->setVisible(true); |
| } |
| |
| void |
| Controller::updateMenu() |
| { |
| m_trayIconMenu->clear(); |
| QMenu* menu = m_trayIconMenu; |
| |
| menu->addAction(m_startChatroom); |
| menu->addAction(m_chatroomDiscoveryAction); |
| |
| menu->addSeparator(); |
| menu->addAction(m_settingsAction); |
| menu->addAction(m_editProfileAction); |
| menu->addSeparator(); |
| menu->addAction(m_contactListAction); |
| menu->addAction(m_addContactAction); |
| menu->addSeparator(); |
| { |
| ChatActionList::const_iterator it = m_chatActionList.begin(); |
| ChatActionList::const_iterator end = m_chatActionList.end(); |
| if (it != end) { |
| for (; it != end; it++) |
| menu->addAction(it->second); |
| menu->addSeparator(); |
| } |
| } |
| menu->addAction(m_updateLocalPrefixAction); |
| menu->addSeparator(); |
| menu->addAction(m_minimizeAction); |
| m_closeMenu = menu->addMenu("Close chatroom"); |
| { |
| ChatActionList::const_iterator it = m_closeActionList.begin(); |
| ChatActionList::const_iterator end = m_closeActionList.end(); |
| if (it == end) |
| m_closeMenu->setEnabled(false); |
| else |
| for (; it != end; it++) |
| m_closeMenu->addAction(it->second); |
| } |
| menu->addSeparator(); |
| menu->addAction(m_quitAction); |
| } |
| |
| string |
| Controller::getRandomString() |
| { |
| uint32_t r = ndn::random::generateWord32(); |
| std::stringstream ss; |
| { |
| using namespace CryptoPP; |
| StringSource(reinterpret_cast<uint8_t*>(&r), 4, true, |
| new HexEncoder(new FileSink(ss), false)); |
| |
| } |
| // for (int i = 0; i < 8; i++) |
| // { |
| // uint32_t t = r & mask; |
| // if (t < 10) |
| // ss << static_cast<char>(t + 0x30); |
| // else |
| // ss << static_cast<char>(t + 0x57); |
| // r = r >> 4; |
| // } |
| |
| return ss.str(); |
| } |
| |
| void |
| Controller::addChatDialog(const QString& chatroomName, ChatDialog* chatDialog) |
| { |
| m_chatDialogList[chatroomName.toStdString()] = chatDialog; |
| connect(chatDialog, SIGNAL(closeChatDialog(const QString&)), |
| this, SLOT(onRemoveChatDialog(const QString&))); |
| connect(chatDialog, SIGNAL(showChatMessage(const QString&, const QString&, const QString&)), |
| this, SLOT(onShowChatMessage(const QString&, const QString&, const QString&))); |
| connect(chatDialog, SIGNAL(resetIcon()), |
| this, SLOT(onResetIcon())); |
| connect(&m_backend, SIGNAL(localPrefixUpdated(const QString&)), |
| chatDialog->getBackend(), SLOT(updateRoutingPrefix(const QString&))); |
| connect(this, SIGNAL(localPrefixConfigured(const QString&)), |
| chatDialog->getBackend(), SLOT(updateRoutingPrefix(const QString&))); |
| connect(this, SIGNAL(nfdReconnect()), |
| chatDialog->getBackend(), SLOT(onNfdReconnect())); |
| |
| // connect chat dialog with discovery backend |
| connect(chatDialog->getBackend(), SIGNAL(nfdError()), |
| this, SLOT(onNfdError())); |
| connect(chatDialog->getBackend(), SIGNAL(newChatroomForDiscovery(ndn::Name::Component)), |
| m_chatroomDiscoveryBackend, SLOT(onNewChatroomForDiscovery(ndn::Name::Component))); |
| connect(chatDialog->getBackend(), SIGNAL(addInRoster(ndn::Name, ndn::Name::Component)), |
| m_chatroomDiscoveryBackend, SLOT(onAddInRoster(ndn::Name, ndn::Name::Component))); |
| connect(chatDialog->getBackend(), SIGNAL(eraseInRoster(ndn::Name, ndn::Name::Component)), |
| m_chatroomDiscoveryBackend, SLOT(onEraseInRoster(ndn::Name, ndn::Name::Component))); |
| |
| |
| QAction* chatAction = new QAction(chatroomName, this); |
| m_chatActionList[chatroomName.toStdString()] = chatAction; |
| connect(chatAction, SIGNAL(triggered()), |
| chatDialog, SLOT(onShow())); |
| |
| QAction* closeAction = new QAction(chatroomName, this); |
| m_closeActionList[chatroomName.toStdString()] = closeAction; |
| connect(closeAction, SIGNAL(triggered()), |
| chatDialog, SLOT(shutdown())); |
| |
| updateMenu(); |
| } |
| |
| void |
| Controller::updateDiscoveryList(const ChatroomInfo& info, bool isAdd) |
| { |
| emit discoverChatroomChanged(info, isAdd); |
| } |
| |
| void |
| Controller::onIdentityUpdated(const QString& identity) |
| { |
| while (!m_chatDialogList.empty()) { |
| ChatDialogList::const_iterator it = m_chatDialogList.begin(); |
| it->second->shutdown(); |
| } |
| |
| emit closeDBModule(); |
| |
| Name identityName(identity.toStdString()); |
| m_identity = identityName; |
| |
| QTimer::singleShot(500, this, SLOT(onIdentityUpdatedContinued())); |
| } |
| |
| void |
| Controller::onIdentityUpdatedContinued() |
| { |
| QString connection = m_db.connectionName(); |
| // _LOG_DEBUG("connection name: " << connection.toStdString()); |
| QSqlDatabase::removeDatabase(connection); |
| m_db.close(); |
| |
| openDB(); |
| |
| emit identityUpdated(QString(m_identity.toUri().c_str())); |
| } |
| |
| void |
| Controller::onNickUpdated(const QString& nick) |
| { |
| m_nick = nick.toStdString(); |
| } |
| |
| void |
| Controller::onLocalPrefixUpdated(const QString& localPrefix) |
| { |
| QString privateLocalPrefix("/private/local"); |
| |
| if (privateLocalPrefix != localPrefix) |
| m_localPrefixDetected = true; |
| else |
| m_localPrefixDetected = false; |
| |
| m_localPrefix = Name(localPrefix.toStdString()); |
| } |
| |
| void |
| Controller::onLocalPrefixConfigured(const QString& prefix) |
| { |
| if (!m_localPrefixDetected) { |
| m_localPrefix = Name(prefix.toStdString()); |
| emit localPrefixConfigured(prefix); |
| } |
| } |
| |
| void |
| Controller::onStartChatAction() |
| { |
| string chatroom = "chatroom-" + getRandomString(); |
| |
| m_startChatDialog->setChatroom(chatroom); |
| m_startChatDialog->show(); |
| m_startChatDialog->raise(); |
| } |
| |
| void |
| Controller::onSettingsAction() |
| { |
| m_settingDialog->setNick(QString(m_nick.c_str())); |
| m_settingDialog->show(); |
| m_settingDialog->raise(); |
| } |
| |
| void |
| Controller::onProfileEditorAction() |
| { |
| m_profileEditor->resetPanel(); |
| m_profileEditor->show(); |
| m_profileEditor->raise(); |
| } |
| |
| void |
| Controller::onAddContactAction() |
| { |
| emit refreshBrowseContact(); |
| m_browseContactDialog->show(); |
| m_browseContactDialog->raise(); |
| } |
| |
| void |
| Controller::onContactListAction() |
| { |
| m_contactPanel->show(); |
| m_contactPanel->raise(); |
| } |
| |
| void |
| Controller::onChatroomDiscoveryAction() |
| { |
| m_discoveryPanel->show(); |
| m_discoveryPanel->raise(); |
| } |
| |
| void |
| Controller::onDirectAdd() |
| { |
| m_addContactPanel->show(); |
| m_addContactPanel->raise(); |
| } |
| |
| void |
| Controller::onMinimizeAction() |
| { |
| m_settingDialog->hide(); |
| m_startChatDialog->hide(); |
| m_profileEditor->hide(); |
| m_invitationDialog->hide(); |
| m_addContactPanel->hide(); |
| m_discoveryPanel->hide(); |
| |
| ChatDialogList::iterator it = m_chatDialogList.begin(); |
| ChatDialogList::iterator end = m_chatDialogList.end(); |
| for (; it != end; it++) |
| it->second->hide(); |
| } |
| |
| void |
| Controller::onQuitAction() |
| { |
| while (!m_chatDialogList.empty()) { |
| ChatDialogList::const_iterator it = m_chatDialogList.begin(); |
| it->second->shutdown(); |
| } |
| |
| delete m_settingDialog; |
| delete m_startChatDialog; |
| delete m_profileEditor; |
| delete m_invitationDialog; |
| delete m_browseContactDialog; |
| delete m_addContactPanel; |
| delete m_discoveryPanel; |
| if (m_chatroomDiscoveryBackend->isRunning()) { |
| emit shutdownDiscoveryBackend(); |
| m_chatroomDiscoveryBackend->wait(); |
| } |
| delete m_chatroomDiscoveryBackend; |
| |
| if (m_backend.isRunning()) { |
| emit shutdownBackend(); |
| m_backend.wait(); |
| } |
| |
| if (m_nfdConnectionChecker != nullptr && m_nfdConnectionChecker->isRunning()) { |
| emit shutdownNfdChecker(); |
| m_nfdConnectionChecker->wait(); |
| } |
| |
| QApplication::quit(); |
| } |
| |
| void |
| Controller::onStartChatroom(const QString& chatroomName, bool secured) |
| { |
| Name chatroomPrefix; |
| chatroomPrefix.append("ndn") |
| .append("broadcast") |
| .append("ChronoChat") |
| .append("Chatroom") |
| .append(chatroomName.toStdString()); |
| |
| // check if the chatroom exists |
| if (m_chatDialogList.find(chatroomName.toStdString()) != m_chatDialogList.end()) { |
| QMessageBox::information(this, tr("ChronoChat"), |
| tr("You are creating an existing chatroom." |
| "You can check it in the context memu.")); |
| return; |
| } |
| |
| // TODO: We should create a chatroom specific key/cert |
| //(which should be created in the first half of this method |
| //, but let's use the default one for now. |
| Name chatPrefix; |
| chatPrefix.append(m_identity).append("CHRONOCHAT-CHATDATA").append(chatroomName.toStdString()); |
| |
| ChatDialog* chatDialog |
| = new ChatDialog(chatroomPrefix, |
| chatPrefix, |
| m_localPrefix, |
| chatroomName.toStdString(), |
| m_nick, |
| true, |
| m_identity, |
| this); |
| |
| addChatDialog(chatroomName, chatDialog); |
| chatDialog->show(); |
| |
| emit addChatroom(chatroomName); |
| } |
| |
| void |
| Controller::onStartChatroom2(chronochat::Invitation invitation, bool secured) |
| { |
| QString chatroomName = QString::fromStdString(invitation.getChatroom()); |
| onStartChatroom(chatroomName, secured); |
| |
| ChatDialogList::iterator it = m_chatDialogList.find(chatroomName.toStdString()); |
| |
| BOOST_ASSERT(it != m_chatDialogList.end()); |
| it->second->addSyncAnchor(invitation); |
| } |
| |
| |
| void |
| Controller::onShowChatMessage(const QString& chatroomName, const QString& from, const QString& data) |
| { |
| m_trayIcon->showMessage(QString("Chatroom %1 has a new message").arg(chatroomName), |
| QString("<%1>: %2").arg(from).arg(data), |
| QSystemTrayIcon::Information, 20000); |
| m_trayIcon->setIcon(QIcon(":/images/note.png")); |
| } |
| |
| void |
| Controller::onResetIcon() |
| { |
| m_trayIcon->setIcon(QIcon(":/images/icon_small.png")); |
| } |
| |
| void |
| Controller::onRemoveChatDialog(const QString& chatroomName) |
| { |
| emit removeChatroom(chatroomName); |
| |
| ChatDialogList::iterator it = m_chatDialogList.find(chatroomName.toStdString()); |
| if (it != m_chatDialogList.end()) { |
| ChatDialog* deletedChat = it->second; |
| if (deletedChat) |
| delete deletedChat; |
| |
| m_chatDialogList.erase(it); |
| |
| QAction* chatAction = m_chatActionList[chatroomName.toStdString()]; |
| QAction* closeAction = m_closeActionList[chatroomName.toStdString()]; |
| if (chatAction) |
| delete chatAction; |
| if (closeAction) |
| delete closeAction; |
| |
| m_chatActionList.erase(chatroomName.toStdString()); |
| m_closeActionList.erase(chatroomName.toStdString()); |
| |
| updateMenu(); |
| } |
| } |
| |
| void |
| Controller::onWarning(const QString& msg) |
| { |
| QMessageBox::information(this, tr("ChronoChat"), msg); |
| } |
| |
| void |
| Controller::onNfdError() |
| { |
| if (m_isInConnectionDetection) |
| return; |
| // begin a thread |
| |
| m_isInConnectionDetection = true; |
| m_nfdConnectionChecker = new NfdConnectionChecker(this); |
| |
| connect(m_nfdConnectionChecker, SIGNAL(nfdConnected()), |
| this, SLOT(onNfdReconnect())); |
| connect(this, SIGNAL(shutdownNfdChecker()), |
| m_nfdConnectionChecker, SLOT(shutdown())); |
| |
| m_nfdConnectionChecker->start(); |
| QMessageBox::information(this, tr("ChronoChat"), "Nfd is not running"); |
| } |
| |
| void |
| Controller::onNfdReconnect() |
| { |
| if (m_nfdConnectionChecker != nullptr && m_nfdConnectionChecker->isRunning()) { |
| m_nfdConnectionChecker->wait(); |
| } |
| delete m_nfdConnectionChecker; |
| m_nfdConnectionChecker = nullptr; |
| m_isInConnectionDetection = false; |
| emit nfdReconnect(); |
| } |
| |
| void |
| Controller::onChatroomInfoRequest(std::string chatroomName, bool isManager) |
| { |
| auto it = m_chatDialogList.find(chatroomName); |
| if (it != m_chatDialogList.end()) |
| emit respondChatroomInfoRequest(it->second->getChatroomInfo(), isManager); |
| } |
| |
| } // namespace chronochat |
| |
| #if WAF |
| #include "controller.moc" |
| // #include "controller.cpp.moc" |
| #endif |