1948 lines · 83.8 KB · C++
RawDownload
////  Menu.cpp//  interface/src////  Created by Stephen Birarda on 8/12/13.//  Copyright 2013 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 <cstdlib>  #include <QBoxLayout>#include <QColorDialog>#include <QDialogButtonBox>#include <QDoubleSpinBox>#include <QFileDialog>#include <QFormLayout>#include <QInputDialog>#include <QLineEdit>#include <QMainWindow>#include <QMenuBar>#include <QMessageBox>#include <QShortcut>#include <QSlider>#include <QUuid>#include <QHBoxLayout>#include <QDesktopServices> #include <AccountManager.h>#include <AddressManager.h>#include <XmppClient.h>#include <UUID.h>#include <UserActivityLogger.h> #include "Application.h"#include "AccountManager.h"#include "Menu.h"#include "scripting/LocationScriptingInterface.h"#include "scripting/MenuScriptingInterface.h"#include "Util.h"#include "ui/AnimationsDialog.h"#include "ui/AttachmentsDialog.h"#include "ui/InfoView.h"#include "ui/MetavoxelEditor.h"#include "ui/MetavoxelNetworkSimulator.h"#include "ui/ModelsBrowser.h"#include "ui/LoginDialog.h"#include "ui/NodeBounds.h"#include "devices/OculusManager.h"  Menu* Menu::_instance = NULL; Menu* Menu::getInstance() {    static QMutex menuInstanceMutex;     // lock the menu instance mutex to make sure we don't race and create two menus and crash    menuInstanceMutex.lock();     if (!_instance) {        qDebug("First call to Menu::getInstance() - initing menu.");         _instance = new Menu();    }     menuInstanceMutex.unlock();     return _instance;} const ViewFrustumOffset DEFAULT_FRUSTUM_OFFSET = {-135.0f, 0.0f, 0.0f, 25.0f, 0.0f};const float DEFAULT_FACESHIFT_EYE_DEFLECTION = 0.25f;const QString DEFAULT_FACESHIFT_HOSTNAME = "localhost";const float DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER = 1.0f;const int ONE_SECOND_OF_FRAMES = 60;const int FIVE_SECONDS_OF_FRAMES = 5 * ONE_SECOND_OF_FRAMES;const float MUTE_RADIUS = 50; const QString CONSOLE_TITLE = "Scripting Console";const float CONSOLE_WINDOW_OPACITY = 0.95f;const int CONSOLE_WIDTH = 800;const int CONSOLE_HEIGHT = 200; Menu::Menu() :    _actionHash(),    _receivedAudioStreamSettings(),    _bandwidthDialog(NULL),    _fieldOfView(DEFAULT_FIELD_OF_VIEW_DEGREES),    _realWorldFieldOfView(DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES),    _faceshiftEyeDeflection(DEFAULT_FACESHIFT_EYE_DEFLECTION),    _faceshiftHostname(DEFAULT_FACESHIFT_HOSTNAME),    _frustumDrawMode(FRUSTUM_DRAW_MODE_ALL),    _viewFrustumOffset(DEFAULT_FRUSTUM_OFFSET),    _jsConsole(NULL),    _octreeStatsDialog(NULL),    _lodToolsDialog(NULL),    _newLocationDialog(NULL),    _userLocationsDialog(NULL),#if defined(Q_OS_MAC) || defined(Q_OS_WIN)    _speechRecognizer(),#endif    _maxVoxels(DEFAULT_MAX_VOXELS_PER_SYSTEM),    _voxelSizeScale(DEFAULT_OCTREE_SIZE_SCALE),    _oculusUIAngularSize(DEFAULT_OCULUS_UI_ANGULAR_SIZE),    _sixenseReticleMoveSpeed(DEFAULT_SIXENSE_RETICLE_MOVE_SPEED),    _invertSixenseButtons(DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS),    _automaticAvatarLOD(true),    _avatarLODDecreaseFPS(DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS),    _avatarLODIncreaseFPS(ADJUST_LOD_UP_FPS),    _avatarLODDistanceMultiplier(DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER),    _boundaryLevelAdjust(0),    _maxVoxelPacketsPerSecond(DEFAULT_MAX_VOXEL_PPS),    _lastAdjust(usecTimestampNow()),    _lastAvatarDetailDrop(usecTimestampNow()),    _fpsAverage(FIVE_SECONDS_OF_FRAMES),    _fastFPSAverage(ONE_SECOND_OF_FRAMES),    _loginAction(NULL),    _preferencesDialog(NULL),    _loginDialog(NULL),    _hasLoginDialogDisplayed(false),    _snapshotsLocation(),    _scriptsLocation(),    _walletPrivateKey(),    _shouldRenderTableNeedsRebuilding(true){    Application *appInstance = Application::getInstance();     QMenu* fileMenu = addMenu("File"); #ifdef Q_OS_MAC    addActionToQMenuAndActionHash(fileMenu,                                  MenuOption::AboutApp,                                  0,                                  this,                                  SLOT(aboutApp()),                                  QAction::AboutRole);#endif     AccountManager& accountManager = AccountManager::getInstance();     _loginAction = addActionToQMenuAndActionHash(fileMenu, MenuOption::Logout);     // call our toggle login function now so the menu option is setup properly    toggleLoginMenuItem();     // connect to the appropriate signal of the AccountManager so that we can change the Login/Logout menu item    connect(&accountManager, &AccountManager::profileChanged, this, &Menu::toggleLoginMenuItem);    connect(&accountManager, &AccountManager::logoutComplete, this, &Menu::toggleLoginMenuItem);        // connect to signal of account manager so we can tell user when the user/place they looked at is offline    AddressManager& addressManager = AddressManager::getInstance();    connect(&addressManager, &AddressManager::lookupResultIsOffline, this, &Menu::displayAddressOfflineMessage);    connect(&addressManager, &AddressManager::lookupResultIsNotFound, this, &Menu::displayAddressNotFoundMessage);     addDisabledActionAndSeparator(fileMenu, "Scripts");    addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScript, Qt::CTRL | Qt::Key_O, appInstance, SLOT(loadDialog()));    addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScriptURL,                                    Qt::CTRL | Qt::SHIFT | Qt::Key_O, appInstance, SLOT(loadScriptURLDialog()));    addActionToQMenuAndActionHash(fileMenu, MenuOption::StopAllScripts, 0, appInstance, SLOT(stopAllScripts()));    addActionToQMenuAndActionHash(fileMenu, MenuOption::ReloadAllScripts, Qt::CTRL | Qt::Key_R,                                  appInstance, SLOT(reloadAllScripts()));    addActionToQMenuAndActionHash(fileMenu, MenuOption::RunningScripts, Qt::CTRL | Qt::Key_J,                                  appInstance, SLOT(toggleRunningScriptsWidget()));     addDisabledActionAndSeparator(fileMenu, "Go");    addActionToQMenuAndActionHash(fileMenu,                                  MenuOption::NameLocation,                                  Qt::CTRL | Qt::Key_N,                                  this,                                  SLOT(nameLocation()));    addActionToQMenuAndActionHash(fileMenu,                                  MenuOption::MyLocations,                                  Qt::CTRL | Qt::Key_K,                                  this,                                  SLOT(toggleLocationList()));    addActionToQMenuAndActionHash(fileMenu,                                  MenuOption::AddressBar,                                  Qt::Key_Enter,                                  this,                                  SLOT(toggleAddressBar()));     addDisabledActionAndSeparator(fileMenu, "Upload Avatar Model");    addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadHead, 0, Application::getInstance(), SLOT(uploadHead()));    addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadSkeleton, 0, Application::getInstance(), SLOT(uploadSkeleton()));    addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadAttachment, 0,        Application::getInstance(), SLOT(uploadAttachment()));    addDisabledActionAndSeparator(fileMenu, "Settings");    addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsImport, 0, this, SLOT(importSettings()));    addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsExport, 0, this, SLOT(exportSettings()));     addActionToQMenuAndActionHash(fileMenu,                                  MenuOption::Quit,                                  Qt::CTRL | Qt::Key_Q,                                  appInstance,                                  SLOT(quit()),                                  QAction::QuitRole);      QMenu* editMenu = addMenu("Edit");     QUndoStack* undoStack = Application::getInstance()->getUndoStack();    QAction* undoAction = undoStack->createUndoAction(editMenu);    undoAction->setShortcut(Qt::CTRL | Qt::Key_Z);    addActionToQMenuAndActionHash(editMenu, undoAction);     QAction* redoAction = undoStack->createRedoAction(editMenu);    redoAction->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_Z);    addActionToQMenuAndActionHash(editMenu, redoAction);     addActionToQMenuAndActionHash(editMenu,                                  MenuOption::Preferences,                                  Qt::CTRL | Qt::Key_Comma,                                  this,                                  SLOT(editPreferences()),                                  QAction::PreferencesRole);     addActionToQMenuAndActionHash(editMenu, MenuOption::Attachments, 0, this, SLOT(editAttachments()));    addActionToQMenuAndActionHash(editMenu, MenuOption::Animations, 0, this, SLOT(editAnimations()));     QMenu* toolsMenu = addMenu("Tools");    addActionToQMenuAndActionHash(toolsMenu, MenuOption::MetavoxelEditor, 0, this, SLOT(showMetavoxelEditor()));    addActionToQMenuAndActionHash(toolsMenu, MenuOption::ScriptEditor,  Qt::ALT | Qt::Key_S, this, SLOT(showScriptEditor())); #if defined(Q_OS_MAC) || defined(Q_OS_WIN)    QAction* speechRecognizerAction = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::ControlWithSpeech,            Qt::CTRL | Qt::SHIFT | Qt::Key_C, _speechRecognizer.getEnabled(), &_speechRecognizer, SLOT(setEnabled(bool)));    connect(&_speechRecognizer, SIGNAL(enabledUpdated(bool)), speechRecognizerAction, SLOT(setChecked(bool)));#endif #ifdef HAVE_QXMPP    _chatAction = addActionToQMenuAndActionHash(toolsMenu,                                                MenuOption::Chat,                                                Qt::Key_Backslash,                                                this,                                                SLOT(showChat()));     const QXmppClient& xmppClient = XmppClient::getInstance().getXMPPClient();    toggleChat();    connect(&xmppClient, &QXmppClient::connected, this, &Menu::toggleChat);    connect(&xmppClient, &QXmppClient::disconnected, this, &Menu::toggleChat);     QDir::setCurrent(Application::resourcesPath());    // init chat window to listen chat    _chatWindow = new ChatWindow(Application::getInstance()->getWindow());#endif     addActionToQMenuAndActionHash(toolsMenu,                                  MenuOption::Console,                                  Qt::CTRL | Qt::ALT | Qt::Key_J,                                  this,                                  SLOT(toggleConsole()));     addActionToQMenuAndActionHash(toolsMenu,                                  MenuOption::ResetSensors,                                  Qt::Key_Apostrophe,                                  appInstance,                                  SLOT(resetSensors()));     QMenu* avatarMenu = addMenu("Avatar");     QMenu* avatarSizeMenu = avatarMenu->addMenu("Size");    addActionToQMenuAndActionHash(avatarSizeMenu,                                  MenuOption::IncreaseAvatarSize,                                  Qt::Key_Plus,                                  appInstance->getAvatar(),                                  SLOT(increaseSize()));    addActionToQMenuAndActionHash(avatarSizeMenu,                                  MenuOption::DecreaseAvatarSize,                                  Qt::Key_Minus,                                  appInstance->getAvatar(),                                  SLOT(decreaseSize()));    addActionToQMenuAndActionHash(avatarSizeMenu,                                  MenuOption::ResetAvatarSize,                                  Qt::Key_Equal,                                  appInstance->getAvatar(),                                  SLOT(resetSize()));     QObject* avatar = appInstance->getAvatar();    addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::KeyboardMotorControl,             Qt::CTRL | Qt::SHIFT | Qt::Key_K, true, avatar, SLOT(updateMotionBehavior()));    addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::ScriptedMotorControl, 0, true,            avatar, SLOT(updateMotionBehavior()));    addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::ChatCircling, 0, false);    addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::NamesAboveHeads, 0, true);    addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::GlowWhenSpeaking, 0, true);    addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::BlueSpeechSphere, 0, true);    addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::ObeyEnvironmentalGravity, Qt::SHIFT | Qt::Key_G, false,            avatar, SLOT(updateMotionBehavior()));    addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::StandOnNearbyFloors, 0, true,            avatar, SLOT(updateMotionBehavior()));     QMenu* collisionsMenu = avatarMenu->addMenu("Collide With...");    addCheckableActionToQMenuAndActionHash(collisionsMenu, MenuOption::CollideAsRagdoll, 0, false,             avatar, SLOT(onToggleRagdoll()));    addCheckableActionToQMenuAndActionHash(collisionsMenu, MenuOption::CollideWithAvatars,            0, true, avatar, SLOT(updateCollisionGroups()));    addCheckableActionToQMenuAndActionHash(collisionsMenu, MenuOption::CollideWithVoxels,            0, false, avatar, SLOT(updateCollisionGroups()));    addCheckableActionToQMenuAndActionHash(collisionsMenu, MenuOption::CollideWithEnvironment,            0, false, avatar, SLOT(updateCollisionGroups()));     QMenu* viewMenu = addMenu("View"); #ifdef Q_OS_MAC    addCheckableActionToQMenuAndActionHash(viewMenu,                                           MenuOption::Fullscreen,                                           Qt::CTRL | Qt::META | Qt::Key_F,                                           false,                                           appInstance,                                           SLOT(setFullscreen(bool)));#else    addCheckableActionToQMenuAndActionHash(viewMenu,                                           MenuOption::Fullscreen,                                           Qt::CTRL | Qt::Key_F,                                           false,                                           appInstance,                                           SLOT(setFullscreen(bool)));#endif    addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, Qt::Key_P, true,                                            appInstance,SLOT(cameraMenuChanged()));    addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::SHIFT | Qt::Key_H, true);    addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H, false,                                            appInstance, SLOT(cameraMenuChanged()));    addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::UserInterface, Qt::Key_Slash, true);     addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::EnableVRMode, 0,                                           false,                                           appInstance,                                           SLOT(setEnableVRMode(bool)));     addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0,                                           false,                                           appInstance,                                           SLOT(setEnable3DTVMode(bool)));      QMenu* nodeBordersMenu = viewMenu->addMenu("Server Borders");    NodeBounds& nodeBounds = appInstance->getNodeBoundsDisplay();    addCheckableActionToQMenuAndActionHash(nodeBordersMenu, MenuOption::ShowBordersVoxelNodes,                                           Qt::CTRL | Qt::SHIFT | Qt::Key_1, false,                                           &nodeBounds, SLOT(setShowVoxelNodes(bool)));    addCheckableActionToQMenuAndActionHash(nodeBordersMenu, MenuOption::ShowBordersEntityNodes,                                           Qt::CTRL | Qt::SHIFT | Qt::Key_2, false,                                           &nodeBounds, SLOT(setShowEntityNodes(bool)));     addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::OffAxisProjection, 0, false);    addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::TurnWithHead, 0, false);    addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::MoveWithLean, 0, false);    addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HeadMouse, 0, false);      addDisabledActionAndSeparator(viewMenu, "Stats");    addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, Qt::Key_Percent);    addActionToQMenuAndActionHash(viewMenu, MenuOption::Log, Qt::CTRL | Qt::Key_L, appInstance, SLOT(toggleLogDialog()));    addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Bandwidth, 0, true);    addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0, this, SLOT(bandwidthDetails()));    addActionToQMenuAndActionHash(viewMenu, MenuOption::OctreeStats, 0, this, SLOT(octreeStatsDetails()));    addActionToQMenuAndActionHash(viewMenu, MenuOption::EditEntitiesHelp, 0, this, SLOT(showEditEntitiesHelp()));     QMenu* developerMenu = addMenu("Developer");     QMenu* renderOptionsMenu = developerMenu->addMenu("Render");    addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Atmosphere, Qt::SHIFT | Qt::Key_A, true);    addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Avatars, 0, true);    addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Metavoxels, 0, true);    addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Entities, 0, true);        QMenu* shadowMenu = renderOptionsMenu->addMenu("Shadows");    QActionGroup* shadowGroup = new QActionGroup(shadowMenu);    shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, "None", 0, true));    shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::SimpleShadows, 0, false));    shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::CascadedShadows, 0, false));     {        QMenu* framerateMenu = renderOptionsMenu->addMenu(MenuOption::RenderTargetFramerate);        QActionGroup* framerateGroup = new QActionGroup(framerateMenu);        framerateGroup->setExclusive(true);        framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerateUnlimited, 0, true));        framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerate60, 0, false));        framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerate50, 0, false));        framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerate40, 0, false));        framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerate30, 0, false)); #if defined(Q_OS_MAC)#else        QAction* vsyncAction = addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::RenderTargetFramerateVSyncOn, 0, true, this, SLOT(changeVSync()));#endif    }      QMenu* resolutionMenu = renderOptionsMenu->addMenu(MenuOption::RenderResolution);    QActionGroup* resolutionGroup = new QActionGroup(resolutionMenu);    resolutionGroup->setExclusive(true);    resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionOne, 0, true));    resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionTwoThird, 0, false));    resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionHalf, 0, false));    resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionThird, 0, false));    resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionQuarter, 0, false));     addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Stars, Qt::Key_Asterisk, true);    addCheckableActionToQMenuAndActionHash(renderOptionsMenu,                                           MenuOption::Voxels,                                           Qt::SHIFT | Qt::Key_V,                                           true,                                           appInstance,                                           SLOT(setRenderVoxels(bool)));    addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::EnableGlowEffect, 0, true);     addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Wireframe, Qt::ALT | Qt::Key_W, false);    addActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools()));     QMenu* avatarDebugMenu = developerMenu->addMenu("Avatar");#ifdef HAVE_FACESHIFT    addCheckableActionToQMenuAndActionHash(avatarDebugMenu,                                           MenuOption::Faceshift,                                           0,                                           true,                                           appInstance->getFaceshift(),                                           SLOT(setTCPEnabled(bool)));#endif#ifdef HAVE_VISAGE    addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::Visage, 0, false,            appInstance->getVisage(), SLOT(updateEnabled()));#endif     addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderSkeletonCollisionShapes);    addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderHeadCollisionShapes);    addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderBoundingCollisionShapes);    addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderLookAtVectors, 0, false);    addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderFocusIndicator, 0, false);        QMenu* entitiesDebugMenu = developerMenu->addMenu("Entities");    addCheckableActionToQMenuAndActionHash(entitiesDebugMenu, MenuOption::DisplayModelBounds, 0, false);    addCheckableActionToQMenuAndActionHash(entitiesDebugMenu, MenuOption::DisplayModelElementProxy, 0, false);    addCheckableActionToQMenuAndActionHash(entitiesDebugMenu, MenuOption::DisplayModelElementChildProxies, 0, false);    addCheckableActionToQMenuAndActionHash(entitiesDebugMenu, MenuOption::DisableLightEntities, 0, false);     QMenu* entityCullingMenu = entitiesDebugMenu->addMenu("Culling");    addCheckableActionToQMenuAndActionHash(entityCullingMenu, MenuOption::DontCullOutOfViewMeshParts, 0, false);    addCheckableActionToQMenuAndActionHash(entityCullingMenu, MenuOption::DontCullTooSmallMeshParts, 0, false);    addCheckableActionToQMenuAndActionHash(entityCullingMenu, MenuOption::DontReduceMaterialSwitches, 0, false);        QMenu* voxelOptionsMenu = developerMenu->addMenu("Voxels");    addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures);    addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion);    addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontFadeOnVoxelServerChanges);    addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DisableAutoAdjustLOD);        QMenu* metavoxelOptionsMenu = developerMenu->addMenu("Metavoxels");    addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::DisplayHermiteData, 0, false,        Application::getInstance()->getMetavoxels(), SLOT(refreshVoxelData()));    addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::RenderHeightfields, 0, true);    addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::RenderDualContourSurfaces, 0, true);    addActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::NetworkSimulator, 0, this,        SLOT(showMetavoxelNetworkSimulator()));        QMenu* handOptionsMenu = developerMenu->addMenu("Hands");    addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, false);    addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlternateIK, 0, false);    addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHands, 0, true);    addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false);    addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::ShowIKConstraints, 0, false);        QMenu* sixenseOptionsMenu = handOptionsMenu->addMenu("Sixense");#ifdef __APPLE__    addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu,                                           MenuOption::SixenseEnabled,                                           0, false,                                           this,                                           SLOT(toggleSixense(bool)));#endif    addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu,                                           MenuOption::FilterSixense,                                           0,                                           true,                                           &SixenseManager::getInstance(),                                           SLOT(setFilter(bool)));    addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu,                                           MenuOption::LowVelocityFilter,                                           0,                                           true,                                           appInstance,                                           SLOT(setLowVelocityFilter(bool)));    addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu, MenuOption::SixenseMouseInput, 0, true);    addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu, MenuOption::SixenseLasers, 0, false);     QMenu* leapOptionsMenu = handOptionsMenu->addMenu("Leap Motion");    addCheckableActionToQMenuAndActionHash(leapOptionsMenu, MenuOption::LeapMotionOnHMD, 0, false);     QMenu* networkMenu = developerMenu->addMenu("Network");    addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::DisableNackPackets, 0, false);    addCheckableActionToQMenuAndActionHash(networkMenu,                                           MenuOption::DisableActivityLogger,                                           0,                                           false,                                           &UserActivityLogger::getInstance(),                                           SLOT(disable(bool)));

Lines 1–500 of 1948.