diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt
index f39e7d7e50..7126e8929f 100644
--- a/interface/CMakeLists.txt
+++ b/interface/CMakeLists.txt
@@ -48,7 +48,7 @@ configure_file(InterfaceVersion.h.in "${PROJECT_BINARY_DIR}/includes/InterfaceVe
# grab the implementation and header files from src dirs
file(GLOB INTERFACE_SRCS src/*.cpp src/*.h)
-foreach(SUBDIR avatar devices renderer ui starfield)
+foreach(SUBDIR avatar devices renderer ui starfield location)
file(GLOB_RECURSE SUBDIR_SRCS src/${SUBDIR}/*.cpp src/${SUBDIR}/*.h)
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${SUBDIR_SRCS}")
endforeach(SUBDIR)
diff --git a/interface/interface_en.ts b/interface/interface_en.ts
index 93ba47a3d3..75ada1910c 100644
--- a/interface/interface_en.ts
+++ b/interface/interface_en.ts
@@ -113,139 +113,22 @@
Menu
-
+
Open .ini config file
-
-
+
+
Text files (*.ini)
-
+
Save .ini config file
-
- PreferencesDialog
-
-
-
- Avatar
-
-
-
-
-
- <html><head/><body><p>Avatar display name <span style=" color:#909090;">(optional)</span></p></body></html>
-
-
-
-
-
- Not showing a name
-
-
-
-
-
- Head
-
-
-
-
-
- Body
-
-
-
-
-
- Advanced Tuning
-
-
-
-
-
- It's not recomended that you play with these settings unless you've looked into exactly what they do.
-
-
-
-
-
- <p>Avatar</p>
-
-
-
-
-
- Lean scale (applies to Faceshift users)
-
-
-
-
-
- Vertical field of view
-
-
-
-
-
- Avatar scale (default is 1.0)
-
-
-
-
-
- Pupil dillation
-
-
-
-
-
- Audio Jitter Buffer Samples (0 for automatic)
-
-
-
-
-
- Faceshift eye detection
-
-
-
-
-
- <html><head/><body><p>Voxels</p></body></html>
-
-
-
-
-
- Maximum voxels
-
-
-
-
-
- Max voxels sent each second
-
-
-
-
-
- Cancel
-
-
-
-
-
- Save all changes
-
-
-
QObject
diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp
index 6d61f439ba..dd43e511bd 100644
--- a/interface/src/Menu.cpp
+++ b/interface/src/Menu.cpp
@@ -19,6 +19,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -36,6 +37,7 @@
#include "InfoView.h"
#include "ui/MetavoxelEditor.h"
+
Menu* Menu::_instance = NULL;
Menu* Menu::getInstance() {
@@ -80,7 +82,7 @@ Menu::Menu() :
{
Application *appInstance = Application::getInstance();
-
+
QMenu* fileMenu = addMenu("File");
#ifdef Q_OS_MAC
@@ -118,13 +120,18 @@ Menu::Menu() :
addActionToQMenuAndActionHash(fileMenu,
MenuOption::GoToDomain,
Qt::CTRL | Qt::Key_D,
- this,
- SLOT(goToDomainDialog()));
+ this,
+ SLOT(goToDomainDialog()));
addActionToQMenuAndActionHash(fileMenu,
MenuOption::GoToLocation,
Qt::CTRL | Qt::SHIFT | Qt::Key_L,
- this,
- SLOT(goToLocation()));
+ this,
+ SLOT(goToLocation()));
+ addActionToQMenuAndActionHash(fileMenu,
+ MenuOption::NameLocation,
+ Qt::CTRL | Qt::Key_N,
+ this,
+ SLOT(nameLocation()));
addActionToQMenuAndActionHash(fileMenu,
MenuOption::GoTo,
Qt::Key_At,
@@ -423,6 +430,7 @@ void Menu::saveSettings(QSettings* settings) {
scanMenuBar(&saveAction, settings);
Application::getInstance()->getAvatar()->saveData(settings);
NodeList::getInstance()->saveData(settings);
+
}
void Menu::importSettings() {
@@ -734,67 +742,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() {
@@ -809,25 +761,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 = &LocationManager::getInstance();
+ 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();
@@ -850,6 +810,69 @@ void Menu::goToLocation() {
sendFakeEnterEvent();
}
+void Menu::namedLocationCreated(LocationManager::NamedLocationCreateResponse response) {
+
+ if (response == LocationManager::Created) {
+ return;
+ }
+
+ QMessageBox msgBox;
+ switch (response) {
+ case LocationManager::AlreadyExists:
+ msgBox.setText("That name has been already claimed, try something else.");
+ break;
+ default:
+ msgBox.setText("An unexpected error has occurred, please try again later.");
+ break;
+ }
+
+ msgBox.exec();
+}
+
+void Menu::nameLocation() {
+ // check if user is logged in or show login dialog if not
+
+ AccountManager& accountManager = AccountManager::getInstance();
+ 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.");
+ msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
+ msgBox.button(QMessageBox::Ok)->setText("Login");
+ if (msgBox.exec() == QMessageBox::Ok) {
+ loginForCurrentDomain();
+ }
+
+ return;
+ }
+
+ QInputDialog nameDialog(Application::getInstance()->getWindow());
+ nameDialog.setWindowTitle("Name this location");
+ nameDialog.setLabelText("Name this location, then share that name with others.\n"
+ "When they come here, they'll be in the same location and orientation\n"
+ "(wherever you are standing and looking now) as you.\n\n"
+ "Location name:");
+
+ nameDialog.setWindowFlags(Qt::Sheet);
+ nameDialog.resize((int) (nameDialog.parentWidget()->size().width() * 0.30), nameDialog.size().height());
+
+ if (nameDialog.exec() == QDialog::Accepted) {
+
+ QString locationName = nameDialog.textValue().trimmed();
+ if (locationName.isEmpty()) {
+ return;
+ }
+
+ MyAvatar* myAvatar = Application::getInstance()->getAvatar();
+ LocationManager* manager = new LocationManager();
+ connect(manager, &LocationManager::creationCompleted, this, &Menu::namedLocationCreated);
+ NamedLocation* location = new NamedLocation(locationName,
+ myAvatar->getPosition(), myAvatar->getOrientation(),
+ NodeList::getInstance()->getDomainInfo().getHostname());
+ manager->createNamedLocation(location);
+ }
+}
+
void Menu::pasteToVoxel() {
QInputDialog pasteToOctalCodeDialog(Application::getInstance()->getWindow());
pasteToOctalCodeDialog.setWindowTitle("Paste to Voxel");
@@ -1116,17 +1139,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 245411ef1e..060244089c 100644
--- a/interface/src/Menu.h
+++ b/interface/src/Menu.h
@@ -18,8 +18,9 @@
#include
#include
+#include "location/LocationManager.h"
#include "ui/PreferencesDialog.h"
-#include
+#include "ui/ChatWindow.h"
const float ADJUST_LOD_DOWN_FPS = 40.0;
const float ADJUST_LOD_UP_FPS = 55.0;
@@ -142,6 +143,7 @@ private slots:
void editPreferences();
void goToDomainDialog();
void goToLocation();
+ void nameLocation();
void bandwidthDetailsClosed();
void octreeStatsDetailsClosed();
void lodToolsClosed();
@@ -151,6 +153,8 @@ private slots:
void showChat();
void toggleChat();
void audioMuteToggled();
+ void namedLocationCreated(LocationManager::NamedLocationCreateResponse response);
+ void multipleDestinationsDecision(const QJsonObject& userData, const QJsonObject& placeData);
private:
static Menu* _instance;
@@ -253,6 +257,7 @@ namespace MenuOption {
const QString GlowMode = "Cycle Glow Mode";
const QString GoToDomain = "Go To Domain...";
const QString GoToLocation = "Go To Location...";
+ const QString NameLocation = "Name this location";
const QString GoTo = "Go To...";
const QString IncreaseAvatarSize = "Increase Avatar Size";
const QString IncreaseVoxelSize = "Increase Voxel Size";
diff --git a/interface/src/location/LocationManager.cpp b/interface/src/location/LocationManager.cpp
new file mode 100644
index 0000000000..b83094ba4c
--- /dev/null
+++ b/interface/src/location/LocationManager.cpp
@@ -0,0 +1,227 @@
+//
+// LocationManager.cpp
+// hifi
+//
+// Created by Stojce Slavkovski on 2/7/14.
+//
+//
+
+#include "Application.h"
+#include "LocationManager.h"
+
+const QString GET_USER_ADDRESS = "/api/v1/users/%1/address";
+const QString GET_PLACE_ADDRESS = "/api/v1/places/%1/address";
+const QString POST_PLACE_CREATE = "/api/v1/places/";
+
+
+LocationManager::LocationManager() : _userData(), _placeData() {
+
+};
+
+LocationManager& LocationManager::getInstance() {
+ static LocationManager sharedInstance;
+ return sharedInstance;
+}
+
+void LocationManager::namedLocationDataReceived(const QJsonObject& data) {
+ if (data.isEmpty()) {
+ return;
+ }
+
+ if (data.contains("status") && data["status"].toString() == "success") {
+ emit creationCompleted(LocationManager::Created);
+ } else {
+ emit creationCompleted(LocationManager::AlreadyExists);
+ }
+}
+
+void LocationManager::errorDataReceived(QNetworkReply::NetworkError error, const QString& message) {
+ emit creationCompleted(LocationManager::SystemError);
+}
+
+void LocationManager::createNamedLocation(NamedLocation* namedLocation) {
+ AccountManager& accountManager = AccountManager::getInstance();
+ if (accountManager.isLoggedIn()) {
+ JSONCallbackParameters callbackParams;
+ callbackParams.jsonCallbackReceiver = this;
+ callbackParams.jsonCallbackMethod = "namedLocationDataReceived";
+ callbackParams.errorCallbackReceiver = this;
+ callbackParams.errorCallbackMethod = "errorDataReceived";
+
+ 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();
+
+ destination = QString(QUrl::toPercentEncoding(destination));
+ 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";
+
+ userName = QString(QUrl::toPercentEncoding(userName));
+ 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";
+
+ placeName = QString(QUrl::toPercentEncoding(placeName));
+ AccountManager::getInstance().authenticatedRequest(GET_PLACE_ADDRESS.arg(placeName),
+ QNetworkAccessManager::GetOperation,
+ callbackParams);
+}
+
+void LocationManager::goToOrientation(QString orientation) {
+ if (orientation.isEmpty()) {
+ return;
+ }
+
+ QStringList orientationItems = orientation.remove(' ').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) {
+
+ // replace last occurrence of '_' with decimal point
+ replaceLastOccurrence('-', '.', orientationItems[W_ITEM]);
+ replaceLastOccurrence('-', '.', orientationItems[X_ITEM]);
+ replaceLastOccurrence('-', '.', orientationItems[Y_ITEM]);
+ replaceLastOccurrence('-', '.', orientationItems[Z_ITEM]);
+
+ double w = orientationItems[W_ITEM].toDouble();
+ double x = orientationItems[X_ITEM].toDouble();
+ double y = orientationItems[Y_ITEM].toDouble();
+ double z = orientationItems[Z_ITEM].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.remove(' ').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) {
+
+ // replace last occurrence of '_' with decimal point
+ replaceLastOccurrence('-', '.', coordinateItems[X_ITEM]);
+ replaceLastOccurrence('-', '.', coordinateItems[Y_ITEM]);
+ replaceLastOccurrence('-', '.', coordinateItems[Z_ITEM]);
+
+ double x = coordinateItems[X_ITEM].toDouble();
+ double y = coordinateItems[Y_ITEM].toDouble();
+ double z = coordinateItems[Z_ITEM].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;
+}
+
+void LocationManager::replaceLastOccurrence(const QChar search, const QChar replace, QString& string) {
+ int lastIndex;
+ lastIndex = string.lastIndexOf(search);
+ if (lastIndex > 0) {
+ lastIndex = string.lastIndexOf(search);
+ string.replace(lastIndex, 1, replace);
+ }
+}
diff --git a/interface/src/location/LocationManager.h b/interface/src/location/LocationManager.h
new file mode 100644
index 0000000000..a6bdaf66b4
--- /dev/null
+++ b/interface/src/location/LocationManager.h
@@ -0,0 +1,58 @@
+//
+// LocationManager.h
+// hifi
+//
+// Created by Stojce Slavkovski on 2/7/14.
+//
+//
+
+#ifndef __hifi__LocationManager__
+#define __hifi__LocationManager__
+
+#include
+
+#include "AccountManager.h"
+#include "NamedLocation.h"
+
+class LocationManager : public QObject {
+ Q_OBJECT
+
+public:
+ static LocationManager& getInstance();
+
+ enum NamedLocationCreateResponse {
+ Created,
+ AlreadyExists,
+ SystemError
+ };
+
+ 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:
+ QJsonObject _userData;
+ QJsonObject _placeData;
+
+ void replaceLastOccurrence(const QChar search, const QChar replace, QString& string);
+ void checkForMultipleDestinations();
+
+signals:
+ void creationCompleted(LocationManager::NamedLocationCreateResponse response);
+ 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__) */
diff --git a/interface/src/location/NamedLocation.cpp b/interface/src/location/NamedLocation.cpp
new file mode 100644
index 0000000000..c6daef4961
--- /dev/null
+++ b/interface/src/location/NamedLocation.cpp
@@ -0,0 +1,24 @@
+//
+// LocationManager.cpp
+// hifi
+//
+// Created by Stojce Slavkovski on 2/1/14.
+//
+//
+
+#include "NamedLocation.h"
+
+const QString JSON_FORMAT = "{\"address\":{\"position\":\"%1,%2,%3\","
+ "\"orientation\":\"%4,%5,%6,%7\",\"domain\":\"%8\"},\"name\":\"%9\"}";
+
+QString NamedLocation::toJsonString() {
+ return JSON_FORMAT.arg(QString::number(_location.x),
+ QString::number(_location.y),
+ QString::number(_location.z),
+ QString::number(_orientation.w),
+ QString::number(_orientation.x),
+ QString::number(_orientation.y),
+ QString::number(_orientation.z),
+ _domain,
+ _locationName);
+}
diff --git a/interface/src/location/NamedLocation.h b/interface/src/location/NamedLocation.h
new file mode 100644
index 0000000000..81af03b45e
--- /dev/null
+++ b/interface/src/location/NamedLocation.h
@@ -0,0 +1,58 @@
+//
+// NamedLocation.h
+// hifi
+//
+// Created by Stojce Slavkovski on 2/1/14.
+//
+//
+
+#ifndef __hifi__NamedLocation__
+#define __hifi__NamedLocation__
+
+#include
+#include
+#include
+
+#include
+
+class NamedLocation : public QObject {
+ Q_OBJECT
+
+public:
+ NamedLocation(QString locationName, glm::vec3 location, glm::quat orientation, QString domain) {
+ _locationName = locationName;
+ _location = location;
+ _orientation = orientation;
+ _domain = domain;
+ }
+
+ QString toJsonString();
+
+ bool isEmpty() { return _locationName.isNull() || _locationName.isEmpty(); }
+
+ void setLocationName(QString locationName) { _locationName = locationName; }
+ QString locationName() { return _locationName; }
+
+ void setLocation(glm::vec3 location) { _location = location; }
+ glm::vec3 location() { return _location; }
+
+ void setOrientation(glm::quat orentation) { _orientation = orentation; }
+ glm::quat orientation() { return _orientation; }
+
+ void setDomain(QString domain) { _domain = domain; }
+ QString domain() { return _domain; }
+
+signals:
+ void dataReceived(bool locationExists);
+
+private:
+
+ QString _locationName;
+ QString _createdBy;
+ glm::vec3 _location;
+ glm::quat _orientation;
+ QString _domain;
+
+};
+
+#endif /* defined(__hifi__NamedLocation__) */