From fd201c450bb48f79f79f7c0ee24a72907022ba79 Mon Sep 17 00:00:00 2001 From: stojce Date: Wed, 12 Mar 2014 23:02:21 +0100 Subject: [PATCH] Multiple destinations implementation --- interface/interface_en.ts | 8 +- interface/src/Menu.cpp | 112 ++++---------- interface/src/Menu.h | 1 + interface/src/location/LocationManager.cpp | 169 ++++++++++++++++++++- interface/src/location/LocationManager.h | 17 ++- 5 files changed, 214 insertions(+), 93 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index a8f78cd36e..20d7a74c09 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -113,18 +113,18 @@ Menu - + Open .ini config file - - + + Text files (*.ini) - + Save .ini config file diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 6845ab2064..a11692ad12 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -37,6 +37,7 @@ #include "InfoView.h" #include "ui/MetavoxelEditor.h" + Menu* Menu::_instance = NULL; Menu* Menu::getInstance() { @@ -79,7 +80,7 @@ Menu::Menu() : _loginAction(NULL) { Application *appInstance = Application::getInstance(); - + QMenu* fileMenu = addMenu("File"); #ifdef Q_OS_MAC @@ -860,67 +861,11 @@ void Menu::goToDomainDialog() { } void Menu::goToOrientation(QString orientation) { - - if (orientation.isEmpty()) { - return; - } - - QStringList orientationItems = orientation.split(QRegExp("_|,"), QString::SkipEmptyParts); - - const int NUMBER_OF_ORIENTATION_ITEMS = 4; - const int W_ITEM = 0; - const int X_ITEM = 1; - const int Y_ITEM = 2; - const int Z_ITEM = 3; - - if (orientationItems.size() == NUMBER_OF_ORIENTATION_ITEMS) { - - double w = replaceLastOccurrence('-', '.', orientationItems[W_ITEM].trimmed()).toDouble(); - double x = replaceLastOccurrence('-', '.', orientationItems[X_ITEM].trimmed()).toDouble(); - double y = replaceLastOccurrence('-', '.', orientationItems[Y_ITEM].trimmed()).toDouble(); - double z = replaceLastOccurrence('-', '.', orientationItems[Z_ITEM].trimmed()).toDouble(); - - glm::quat newAvatarOrientation(w, x, y, z); - - MyAvatar* myAvatar = Application::getInstance()->getAvatar(); - glm::quat avatarOrientation = myAvatar->getOrientation(); - if (newAvatarOrientation != avatarOrientation) { - myAvatar->setOrientation(newAvatarOrientation); - } - } + LocationManager::getInstance().goToDestination(orientation); } bool Menu::goToDestination(QString destination) { - - QStringList coordinateItems = destination.split(QRegExp("_|,"), QString::SkipEmptyParts); - - const int NUMBER_OF_COORDINATE_ITEMS = 3; - const int X_ITEM = 0; - const int Y_ITEM = 1; - const int Z_ITEM = 2; - if (coordinateItems.size() == NUMBER_OF_COORDINATE_ITEMS) { - - double x = replaceLastOccurrence('-', '.', coordinateItems[X_ITEM].trimmed()).toDouble(); - double y = replaceLastOccurrence('-', '.', coordinateItems[Y_ITEM].trimmed()).toDouble(); - double z = replaceLastOccurrence('-', '.', coordinateItems[Z_ITEM].trimmed()).toDouble(); - - glm::vec3 newAvatarPos(x, y, z); - - MyAvatar* myAvatar = Application::getInstance()->getAvatar(); - glm::vec3 avatarPos = myAvatar->getPosition(); - if (newAvatarPos != avatarPos) { - // send a node kill request, indicating to other clients that they should play the "disappeared" effect - MyAvatar::sendKillAvatar(); - - qDebug("Going To Location: %f, %f, %f...", x, y, z); - myAvatar->setPosition(newAvatarPos); - } - - return true; - } - - // no coordinates were parsed - return false; + return LocationManager::getInstance().goToDestination(destination); } void Menu::goTo() { @@ -935,25 +880,33 @@ void Menu::goTo() { int dialogReturn = gotoDialog.exec(); if (dialogReturn == QDialog::Accepted && !gotoDialog.textValue().isEmpty()) { - - destination = gotoDialog.textValue(); - - // go to coordinate destination or to Username - if (!goToDestination(destination)) { - JSONCallbackParameters callbackParams; - callbackParams.jsonCallbackReceiver = Application::getInstance()->getAvatar(); - callbackParams.jsonCallbackMethod = "goToLocationFromResponse"; - - // there's a username entered by the user, make a request to the data-server for the associated location - AccountManager::getInstance().authenticatedRequest("/api/v1/users/" + gotoDialog.textValue() + "/address", - QNetworkAccessManager::GetOperation, - callbackParams); - } + LocationManager* manager = new LocationManager(); + manager->goTo(gotoDialog.textValue()); + connect(manager, &LocationManager::multipleDestinationsFound, this, &Menu::multipleDestinationsDecision); } sendFakeEnterEvent(); } +void Menu::multipleDestinationsDecision(const QJsonObject& userData, const QJsonObject& placeData) { + QMessageBox msgBox; + msgBox.setText("Both user and location exists with same name"); + msgBox.setInformativeText("Where you wanna go?"); + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Open); + msgBox.button(QMessageBox::Ok)->setText("User"); + msgBox.button(QMessageBox::Open)->setText("Place"); + int userResponse = msgBox.exec(); + + if (userResponse == QMessageBox::Ok) { + Application::getInstance()->getAvatar()->goToLocationFromResponse(userData); + } else if (userResponse == QMessageBox::Open) { + Application::getInstance()->getAvatar()->goToLocationFromResponse(userData); + } + + LocationManager* manager = reinterpret_cast(sender()); + disconnect(manager, &LocationManager::multipleDestinationsFound, this, &Menu::multipleDestinationsDecision); +} + void Menu::goToLocation() { MyAvatar* myAvatar = Application::getInstance()->getAvatar(); glm::vec3 avatarPos = myAvatar->getPosition(); @@ -999,7 +952,7 @@ void Menu::nameLocation() { // check if user is logged in or show login dialog if not AccountManager& accountManager = AccountManager::getInstance(); - if (!accountManager.isLoggedIn() && 1 > 2) { + if (!accountManager.isLoggedIn()) { QMessageBox msgBox; msgBox.setText("We need to tie this location to your username."); msgBox.setInformativeText("Please login first, then try naming the location again."); @@ -1278,17 +1231,6 @@ void Menu::addAvatarCollisionSubMenu(QMenu* overMenu) { 0, true, avatar, SLOT(updateCollisionFlags())); } -QString Menu::replaceLastOccurrence(QChar search, QChar replace, QString string) { - int lastIndex; - lastIndex = string.lastIndexOf(search); - if (lastIndex > 0) { - lastIndex = string.lastIndexOf(search); - string.replace(lastIndex, 1, replace); - } - - return string; -} - QAction* Menu::getActionFromName(const QString& menuName, QMenu* menu) { QList menuActions; if (menu) { diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 6ff0d79662..d47c156aa8 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -149,6 +149,7 @@ private slots: void toggleChat(); void audioMuteToggled(); void namedLocationCreated(LocationManager::NamedLocationCreateResponse response, NamedLocation* location); + void multipleDestinationsDecision(const QJsonObject& userData, const QJsonObject& placeData); private: static Menu* _instance; diff --git a/interface/src/location/LocationManager.cpp b/interface/src/location/LocationManager.cpp index 0588c66818..61ed401766 100644 --- a/interface/src/location/LocationManager.cpp +++ b/interface/src/location/LocationManager.cpp @@ -7,12 +7,17 @@ // #include "LocationManager.h" +#include "Application.h" const QString GET_USER_ADDRESS = "/api/v1/users/%1/address"; const QString GET_PLACE_ADDRESS = "/api/v1/places/%1/address"; -const QString GET_ADDRESSES = "/api/v1/addresses/%1/address"; const QString POST_PLACE_CREATE = "/api/v1/places/"; + +LocationManager::LocationManager() : _userData(), _placeData() { + +}; + LocationManager& LocationManager::getInstance() { static LocationManager sharedInstance; return sharedInstance; @@ -23,7 +28,6 @@ void LocationManager::namedLocationDataReceived(const QJsonObject& data) { return; } - qDebug() << data; if (data.contains("status") && data["status"].toString() == "success") { NamedLocation* location = new NamedLocation(data["data"].toObject()); emit creationCompleted(LocationManager::Created, location); @@ -45,10 +49,169 @@ void LocationManager::createNamedLocation(NamedLocation* namedLocation) { callbackParams.errorCallbackReceiver = this; callbackParams.errorCallbackMethod = "errorDataReceived"; - qDebug() << namedLocation->toJsonString(); accountManager.authenticatedRequest(POST_PLACE_CREATE, QNetworkAccessManager::PostOperation, callbackParams, namedLocation->toJsonString().toUtf8()); } } +void LocationManager::goTo(QString destination) { + + if (destination.startsWith("@")) { + // remove '@' and go to user + goToUser(destination.remove(0, 1)); + return; + } + + if (destination.startsWith("#")) { + // remove '#' and go to named place + goToPlace(destination.remove(0, 1)); + return; + } + + // go to coordinate destination or to Username + if (!goToDestination(destination)) { + // reset data on local variables + _userData = QJsonObject(); + _placeData = QJsonObject(); + + JSONCallbackParameters callbackParams; + callbackParams.jsonCallbackReceiver = this; + callbackParams.jsonCallbackMethod = "goToUserFromResponse"; + AccountManager::getInstance().authenticatedRequest(GET_USER_ADDRESS.arg(destination), + QNetworkAccessManager::GetOperation, + callbackParams); + + callbackParams.jsonCallbackMethod = "goToLocationFromResponse"; + AccountManager::getInstance().authenticatedRequest(GET_PLACE_ADDRESS.arg(destination), + QNetworkAccessManager::GetOperation, + callbackParams); + } +} + +void LocationManager::goToUserFromResponse(const QJsonObject& jsonObject) { + _userData = jsonObject; + checkForMultipleDestinations(); +} + +void LocationManager::goToLocationFromResponse(const QJsonObject& jsonObject) { + _placeData = jsonObject; + checkForMultipleDestinations(); +} + +void LocationManager::checkForMultipleDestinations() { + if (!_userData.isEmpty() && !_placeData.isEmpty()) { + if (_userData.contains("status") && _userData["status"].toString() == "success" && + _placeData.contains("status") && _placeData["status"].toString() == "success") { + emit multipleDestinationsFound(_userData, _placeData); + return; + } + + if (_userData.contains("status") && _userData["status"].toString() == "success") { + Application::getInstance()->getAvatar()->goToLocationFromResponse(_userData); + return; + } + + if (_placeData.contains("status") && _placeData["status"].toString() == "success") { + Application::getInstance()->getAvatar()->goToLocationFromResponse(_placeData); + return; + } + + emit locationChanged(); + } +} + +void LocationManager::goToUser(QString userName) { + + JSONCallbackParameters callbackParams; + callbackParams.jsonCallbackReceiver = Application::getInstance()->getAvatar(); + callbackParams.jsonCallbackMethod = "goToLocationFromResponse"; + + AccountManager::getInstance().authenticatedRequest(GET_USER_ADDRESS.arg(userName), + QNetworkAccessManager::GetOperation, + callbackParams); +} + +void LocationManager::goToPlace(QString placeName) { + JSONCallbackParameters callbackParams; + callbackParams.jsonCallbackReceiver = Application::getInstance()->getAvatar(); + callbackParams.jsonCallbackMethod = "goToLocationFromResponse"; + + AccountManager::getInstance().authenticatedRequest(GET_PLACE_ADDRESS.arg(placeName), + QNetworkAccessManager::GetOperation, + callbackParams); +} + +void LocationManager::goToOrientation(QString orientation) { + if (orientation.isEmpty()) { + return; + } + + QStringList orientationItems = orientation.split(QRegExp("_|,"), QString::SkipEmptyParts); + + const int NUMBER_OF_ORIENTATION_ITEMS = 4; + const int W_ITEM = 0; + const int X_ITEM = 1; + const int Y_ITEM = 2; + const int Z_ITEM = 3; + + if (orientationItems.size() == NUMBER_OF_ORIENTATION_ITEMS) { + + double w = replaceLastOccurrence('-', '.', orientationItems[W_ITEM].trimmed()).toDouble(); + double x = replaceLastOccurrence('-', '.', orientationItems[X_ITEM].trimmed()).toDouble(); + double y = replaceLastOccurrence('-', '.', orientationItems[Y_ITEM].trimmed()).toDouble(); + double z = replaceLastOccurrence('-', '.', orientationItems[Z_ITEM].trimmed()).toDouble(); + + glm::quat newAvatarOrientation(w, x, y, z); + + MyAvatar* myAvatar = Application::getInstance()->getAvatar(); + glm::quat avatarOrientation = myAvatar->getOrientation(); + if (newAvatarOrientation != avatarOrientation) { + myAvatar->setOrientation(newAvatarOrientation); + } + } +} + +bool LocationManager::goToDestination(QString destination) { + + QStringList coordinateItems = destination.split(QRegExp("_|,"), QString::SkipEmptyParts); + + const int NUMBER_OF_COORDINATE_ITEMS = 3; + const int X_ITEM = 0; + const int Y_ITEM = 1; + const int Z_ITEM = 2; + if (coordinateItems.size() == NUMBER_OF_COORDINATE_ITEMS) { + + double x = replaceLastOccurrence('-', '.', coordinateItems[X_ITEM].trimmed()).toDouble(); + double y = replaceLastOccurrence('-', '.', coordinateItems[Y_ITEM].trimmed()).toDouble(); + double z = replaceLastOccurrence('-', '.', coordinateItems[Z_ITEM].trimmed()).toDouble(); + + glm::vec3 newAvatarPos(x, y, z); + + MyAvatar* myAvatar = Application::getInstance()->getAvatar(); + glm::vec3 avatarPos = myAvatar->getPosition(); + if (newAvatarPos != avatarPos) { + // send a node kill request, indicating to other clients that they should play the "disappeared" effect + MyAvatar::sendKillAvatar(); + + qDebug("Going To Location: %f, %f, %f...", x, y, z); + myAvatar->setPosition(newAvatarPos); + } + + return true; + } + + // no coordinates were parsed + return false; +} + +QString LocationManager::replaceLastOccurrence(QChar search, QChar replace, QString string) { + int lastIndex; + lastIndex = string.lastIndexOf(search); + if (lastIndex > 0) { + lastIndex = string.lastIndexOf(search); + string.replace(lastIndex, 1, replace); + } + + return string; +} diff --git a/interface/src/location/LocationManager.h b/interface/src/location/LocationManager.h index 4282d0e795..6d5beacae5 100644 --- a/interface/src/location/LocationManager.h +++ b/interface/src/location/LocationManager.h @@ -25,18 +25,33 @@ public: SystemError }; - LocationManager() { }; + LocationManager(); void createNamedLocation(NamedLocation* namedLocation); void goTo(QString destination); void goToUser(QString userName); + void goToPlace(QString placeName); + void goToOrientation(QString orientation); + bool goToDestination(QString destination); + +private: + QString replaceLastOccurrence(QChar search, QChar replace, QString string); + QJsonObject _userData; + QJsonObject _placeData; + + void checkForMultipleDestinations(); signals: void creationCompleted(LocationManager::NamedLocationCreateResponse response, NamedLocation* location); + void multipleDestinationsFound(const QJsonObject& userData, const QJsonObject& placeData); + void locationChanged(); private slots: void namedLocationDataReceived(const QJsonObject& data); void errorDataReceived(QNetworkReply::NetworkError error, const QString& message); + void goToLocationFromResponse(const QJsonObject& jsonObject); + void goToUserFromResponse(const QJsonObject& jsonObject); + }; #endif /* defined(__hifi__LocationManager__) */