Merge pull request #4108 from ctrlaltdavid/20263

CR for Job #20263 - Create a "Bookmarks" capability
This commit is contained in:
Philip Rosedale 2015-01-15 10:30:41 -08:00
commit 048d190350
6 changed files with 260 additions and 1 deletions

View file

@ -257,6 +257,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
qDebug() << "[VERSION] Build sequence: " << qPrintable(applicationVersion());
_bookmarks = new Bookmarks(); // Before setting up the menu
// call Menu getInstance static method to set up the menu
_window->setMenuBar(Menu::getInstance());

View file

@ -38,6 +38,7 @@
#include <ViewFrustum.h>
#include "Audio.h"
#include "Bookmarks.h"
#include "Camera.h"
#include "DatagramProcessor.h"
#include "Environment.h"
@ -300,6 +301,8 @@ public:
QRect getDesirableApplicationGeometry();
RunningScriptsWidget* getRunningScriptsWidget() { return _runningScriptsWidget; }
Bookmarks* getBookmarks() const { return _bookmarks; }
signals:
/// Fired when we're simulating; allows external parties to hook in.
@ -576,6 +579,8 @@ private:
bool _isVSyncOn;
bool _aboutToQuit;
Bookmarks* _bookmarks;
};
#endif // hifi_Application_h

View file

@ -0,0 +1,73 @@
//
// Bookmarks.cpp
// interface/src
//
// Created by David Rowe on 13 Jan 2015.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <QFile>
#include <QJsonDocument>
#include <QStandardPaths>
#include "Bookmarks.h"
Bookmarks::Bookmarks() {
_bookmarksFilename = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + BOOKMARKS_FILENAME;
readFromFile();
}
void Bookmarks::insert(const QString& name, const QString& address) {
_bookmarks.insert(name, address);
if (contains(name)) {
qDebug() << "Added bookmark:" << name << "," << address;
persistToFile();
} else {
qWarning() << "Couldn't add bookmark: " << name << "," << address;
}
}
void Bookmarks::remove(const QString& name) {
_bookmarks.remove(name);
if (!contains(name)) {
qDebug() << "Deleted bookmark:" << name;
persistToFile();
} else {
qWarning() << "Couldn't delete bookmark:" << name;
}
}
bool Bookmarks::contains(const QString& name) const {
return _bookmarks.contains(name);
}
void Bookmarks::readFromFile() {
QFile loadFile(_bookmarksFilename);
if (!loadFile.open(QIODevice::ReadOnly)) {
qWarning("Couldn't open bookmarks file for reading");
return;
}
QByteArray data = loadFile.readAll();
QJsonDocument json(QJsonDocument::fromJson(data));
_bookmarks = json.object().toVariantMap();
}
void Bookmarks::persistToFile() {
QFile saveFile(_bookmarksFilename);
if (!saveFile.open(QIODevice::WriteOnly)) {
qWarning("Couldn't open bookmarks file for writing");
return;
}
QJsonDocument json(QJsonObject::fromVariantMap(_bookmarks));
QByteArray data = json.toJson();
saveFile.write(data);
}

41
interface/src/Bookmarks.h Normal file
View file

@ -0,0 +1,41 @@
//
// Bookmarks.h
// interface/src
//
// Created by David Rowe on 13 Jan 2015.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_Bookmarks_h
#define hifi_Bookmarks_h
#include <QJsonObject>
#include <QDebug>
#include <QMap>
#include <QObject>
class Bookmarks: public QObject {
Q_OBJECT
public:
Bookmarks();
void insert(const QString& name, const QString& address); // Overwrites any existing entry with same name.
void remove(const QString& name);
bool contains(const QString& name) const;
QVariantMap* getBookmarks() { return &_bookmarks; };
private:
QVariantMap _bookmarks; // { name: address, ... }
const QString BOOKMARKS_FILENAME = "bookmarks.json";
QString _bookmarksFilename;
void readFromFile();
void persistToFile();
};
#endif // hifi_Bookmarks_h

View file

@ -124,6 +124,15 @@ Menu::Menu() :
appInstance, SLOT(toggleRunningScriptsWidget()));
addDisabledActionAndSeparator(fileMenu, "Go");
addActionToQMenuAndActionHash(fileMenu, MenuOption::BookmarkLocation, 0,
this, SLOT(bookmarkLocation()));
_bookmarksMenu = fileMenu->addMenu(MenuOption::Bookmarks);
_bookmarksMenu->setEnabled(false);
_deleteBookmarksMenu = addActionToQMenuAndActionHash(fileMenu,
MenuOption::DeleteBookmark, 0,
this, SLOT(deleteBookmark()));
_deleteBookmarksMenu->setEnabled(false);
loadBookmarks();
addActionToQMenuAndActionHash(fileMenu,
MenuOption::NameLocation,
Qt::CTRL | Qt::Key_N,
@ -262,7 +271,7 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::ShiftHipsForIdleAnimations, 0, false,
avatar, SLOT(updateMotionBehavior()));
QMenu* collisionsMenu = avatarMenu->addMenu("Collide With...");
QMenu* collisionsMenu = avatarMenu->addMenu("Collide With");
addCheckableActionToQMenuAndActionHash(collisionsMenu, MenuOption::CollideAsRagdoll, 0, false,
avatar, SLOT(onToggleRagdoll()));
addCheckableActionToQMenuAndActionHash(collisionsMenu, MenuOption::CollideWithAvatars,
@ -1016,6 +1025,125 @@ void Menu::changeVSync() {
Application::getInstance()->setVSyncEnabled(isOptionChecked(MenuOption::RenderTargetFramerateVSyncOn));
}
void Menu::loadBookmarks() {
QVariantMap* bookmarks = Application::getInstance()->getBookmarks()->getBookmarks();
if (bookmarks->count() > 0) {
QMapIterator<QString, QVariant> i(*bookmarks);
while (i.hasNext()) {
i.next();
QString bookmarkName = i.key();
QString bookmarkAddress = i.value().toString();
QAction* teleportAction = new QAction(getMenu(MenuOption::Bookmarks));
teleportAction->setData(bookmarkAddress);
connect(teleportAction, SIGNAL(triggered()), this, SLOT(teleportToBookmark()));
addActionToQMenuAndActionHash(_bookmarksMenu, teleportAction, bookmarkName, 0, QAction::NoRole);
}
_bookmarksMenu->setEnabled(true);
_deleteBookmarksMenu->setEnabled(true);
}
}
void Menu::bookmarkLocation() {
QInputDialog bookmarkLocationDialog(Application::getInstance()->getWindow());
bookmarkLocationDialog.setWindowTitle("Bookmark Location");
bookmarkLocationDialog.setLabelText("Name:");
bookmarkLocationDialog.setInputMode(QInputDialog::TextInput);
bookmarkLocationDialog.resize(400, 200);
if (bookmarkLocationDialog.exec() == QDialog::Rejected) {
return;
}
QString bookmarkName = bookmarkLocationDialog.textValue().trimmed();
bookmarkName = bookmarkName.replace(QRegExp("(\r\n|[\r\n\t\v ])+"), " ");
if (bookmarkName.length() == 0) {
return;
}
auto addressManager = DependencyManager::get<AddressManager>();
QString bookmarkAddress = addressManager->currentAddress().toString();
Bookmarks* bookmarks = Application::getInstance()->getBookmarks();
if (bookmarks->contains(bookmarkName)) {
QMessageBox duplicateBookmarkMessage;
duplicateBookmarkMessage.setIcon(QMessageBox::Warning);
duplicateBookmarkMessage.setText("The bookmark name you entered already exists in your list.");
duplicateBookmarkMessage.setInformativeText("Would you like to overwrite it?");
duplicateBookmarkMessage.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
duplicateBookmarkMessage.setDefaultButton(QMessageBox::Yes);
if (duplicateBookmarkMessage.exec() == QMessageBox::No) {
return;
}
removeAction(_bookmarksMenu, bookmarkName);
}
QAction* teleportAction = new QAction(getMenu(MenuOption::Bookmarks));
teleportAction->setData(bookmarkAddress);
connect(teleportAction, SIGNAL(triggered()), this, SLOT(teleportToBookmark()));
QList<QAction*> menuItems = _bookmarksMenu->actions();
int position = 0;
while (position < menuItems.count() && bookmarkName > menuItems[position]->text()) {
position += 1;
}
addActionToQMenuAndActionHash(_bookmarksMenu, teleportAction, bookmarkName, 0,
QAction::NoRole, position);
bookmarks->insert(bookmarkName, bookmarkAddress); // Overwrites any item with the same bookmarkName.
_bookmarksMenu->setEnabled(true);
_deleteBookmarksMenu->setEnabled(true);
}
void Menu::teleportToBookmark() {
QAction *action = qobject_cast<QAction *>(sender());
QString address = action->data().toString();
DependencyManager::get<AddressManager>()->handleLookupString(address);
}
void Menu::deleteBookmark() {
QStringList bookmarkList;
QList<QAction*> menuItems = _bookmarksMenu->actions();
for (int i = 0; i < menuItems.count(); i += 1) {
bookmarkList.append(menuItems[i]->text());
}
QInputDialog deleteBookmarkDialog(Application::getInstance()->getWindow());
deleteBookmarkDialog.setWindowTitle("Delete Bookmark");
deleteBookmarkDialog.setLabelText("Select the bookmark to delete");
deleteBookmarkDialog.resize(400, 400);
deleteBookmarkDialog.setOption(QInputDialog::UseListViewForComboBoxItems);
deleteBookmarkDialog.setComboBoxItems(bookmarkList);
deleteBookmarkDialog.setOkButtonText("Delete");
if (deleteBookmarkDialog.exec() == QDialog::Rejected) {
return;
}
QString bookmarkName = deleteBookmarkDialog.textValue().trimmed();
if (bookmarkName.length() == 0) {
return;
}
removeAction(_bookmarksMenu, bookmarkName);
Bookmarks* bookmarks = Application::getInstance()->getBookmarks();
bookmarks->remove(bookmarkName);
if (_bookmarksMenu->actions().count() == 0) {
_bookmarksMenu->setEnabled(false);
_deleteBookmarksMenu->setEnabled(false);
}
}
void Menu::displayNameLocationResponse(const QString& errorString) {
if (!errorString.isEmpty()) {

View file

@ -200,6 +200,9 @@ private slots:
void editAttachments();
void editAnimations();
void changePrivateKey();
void bookmarkLocation();
void teleportToBookmark();
void deleteBookmark();
void nameLocation();
void toggleLocationList();
void hmdToolsClosed();
@ -308,6 +311,10 @@ private:
bool _shouldRenderTableNeedsRebuilding = true;
QMap<float, float> _shouldRenderTable;
void loadBookmarks();
QMenu* _bookmarksMenu;
QAction* _deleteBookmarksMenu;
};
namespace MenuOption {
@ -335,6 +342,8 @@ namespace MenuOption {
const QString Bandwidth = "Bandwidth Display";
const QString BandwidthDetails = "Bandwidth Details";
const QString BlueSpeechSphere = "Blue Sphere While Speaking";
const QString BookmarkLocation = "Bookmark Location";
const QString Bookmarks = "Bookmarks";
const QString CascadedShadows = "Cascaded";
const QString CachesSize = "Caches Size";
const QString Chat = "Chat...";
@ -345,6 +354,7 @@ namespace MenuOption {
const QString Collisions = "Collisions";
const QString Console = "Console...";
const QString ControlWithSpeech = "Control With Speech";
const QString DeleteBookmark = "Delete Bookmark...";
const QString DontRenderEntitiesAsScene = "Don't Render Entities as Scene";
const QString DontDoPrecisionPicking = "Don't Do Precision Picking";
const QString DecreaseAvatarSize = "Decrease Avatar Size";