#include "state.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "boolsetting.hpp" #include "coloursetting.hpp" #include "doublesetting.hpp" #include "intsetting.hpp" #include "modifiersetting.hpp" #include "shortcutsetting.hpp" #include "stringsetting.hpp" #include "values.hpp" CSMPrefs::State* CSMPrefs::State::sThis = nullptr; void CSMPrefs::State::declare() { declareCategory("Windows"); declareInt(mValues->mWindows.mDefaultWidth, "Default window width") .setTooltip("Newly opened top-level windows will open with this width.") .setMin(80); declareInt(mValues->mWindows.mDefaultHeight, "Default window height") .setTooltip("Newly opened top-level windows will open with this height.") .setMin(80); declareBool(mValues->mWindows.mShowStatusbar, "Show Status Bar") .setTooltip( "If a newly open top level window is showing status bars or not. " " Note that this does not affect existing windows."); declareBool(mValues->mWindows.mReuse, "Reuse Subviews") .setTooltip( "When a new subview is requested and a matching subview already " " exist, do not open a new subview and use the existing one instead."); declareInt(mValues->mWindows.mMaxSubviews, "Maximum number of subviews per top-level window") .setTooltip( "If the maximum number is reached and a new subview is opened " "it will be placed into a new top-level window.") .setRange(1, 256); declareBool(mValues->mWindows.mHideSubview, "Hide single subview") .setTooltip( "When a view contains only a single subview, hide the subview title " "bar and if this subview is closed also close the view (unless it is the last " "view for this document)"); declareInt(mValues->mWindows.mMinimumWidth, "Minimum subview width") .setTooltip("Minimum width of subviews.") .setRange(50, 10000); declareEnum(mValues->mWindows.mMainwindowScrollbar, "Horizontal scrollbar mode for main window."); #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) declareBool(mValues->mWindows.mGrowLimit, "Grow Limit Screen") .setTooltip( "When \"Grow then Scroll\" option is selected, the window size grows to" " the width of the virtual desktop. \nIf this option is selected the the window growth" "is limited to the current screen."); #endif declareCategory("Records"); declareEnum(mValues->mRecords.mStatusFormat, "Modification status display format"); declareEnum(mValues->mRecords.mTypeFormat, "ID type display format"); declareCategory("ID Tables"); declareEnum(mValues->mIdTables.mDouble, "Double Click"); declareEnum(mValues->mIdTables.mDoubleS, "Shift Double Click"); declareEnum(mValues->mIdTables.mDoubleC, "Control Double Click"); declareEnum(mValues->mIdTables.mDoubleSc, "Shift Control Double Click"); declareEnum(mValues->mIdTables.mJumpToAdded, "Action on adding or cloning a record"); declareBool( mValues->mIdTables.mExtendedConfig, "Manually specify affected record types for an extended delete/revert") .setTooltip( "Delete and revert commands have an extended form that also affects " "associated records.\n\n" "If this option is enabled, types of affected records are selected " "manually before a command execution.\nOtherwise, all associated " "records are deleted/reverted immediately."); declareBool(mValues->mIdTables.mSubviewNewWindow, "Open Record in new window") .setTooltip( "When editing a record, open the view in a new window," " rather than docked in the main view."); declareCategory("ID Dialogues"); declareBool(mValues->mIdDialogues.mToolbar, "Show toolbar"); declareCategory("Reports"); declareEnum(mValues->mReports.mDouble, "Double Click"); declareEnum(mValues->mReports.mDoubleS, "Shift Double Click"); declareEnum(mValues->mReports.mDoubleC, "Control Double Click"); declareEnum(mValues->mReports.mDoubleSc, "Shift Control Double Click"); declareBool(mValues->mReports.mIgnoreBaseRecords, "Ignore base records in verifier"); declareCategory("Search & Replace"); declareInt(mValues->mSearchAndReplace.mCharBefore, "Characters before search string") .setTooltip("Maximum number of character to display in search result before the searched text"); declareInt(mValues->mSearchAndReplace.mCharAfter, "Characters after search string") .setTooltip("Maximum number of character to display in search result after the searched text"); declareBool(mValues->mSearchAndReplace.mAutoDelete, "Delete row from result table after a successful replace"); declareCategory("Scripts"); declareBool(mValues->mScripts.mShowLinenum, "Show Line Numbers") .setTooltip( "Show line numbers to the left of the script editor window." "The current row and column numbers of the text cursor are shown at the bottom."); declareBool(mValues->mScripts.mWrapLines, "Wrap Lines") .setTooltip("Wrap lines longer than width of script editor."); declareBool(mValues->mScripts.mMonoFont, "Use monospace font"); declareInt(mValues->mScripts.mTabWidth, "Tab Width") .setTooltip("Number of characters for tab width") .setRange(1, 10); declareEnum(mValues->mScripts.mWarnings, "Warning Mode"); declareBool(mValues->mScripts.mToolbar, "Show toolbar"); declareInt(mValues->mScripts.mCompileDelay, "Delay between updating of source errors") .setTooltip("Delay in milliseconds") .setRange(0, 10000); declareInt(mValues->mScripts.mErrorHeight, "Initial height of the error panel").setRange(100, 10000); declareBool(mValues->mScripts.mHighlightOccurrences, "Highlight other occurrences of selected names"); declareColour(mValues->mScripts.mColourHighlight, "Colour of highlighted occurrences"); declareColour(mValues->mScripts.mColourInt, "Highlight Colour: Integer Literals"); declareColour(mValues->mScripts.mColourFloat, "Highlight Colour: Float Literals"); declareColour(mValues->mScripts.mColourName, "Highlight Colour: Names"); declareColour(mValues->mScripts.mColourKeyword, "Highlight Colour: Keywords"); declareColour(mValues->mScripts.mColourSpecial, "Highlight Colour: Special Characters"); declareColour(mValues->mScripts.mColourComment, "Highlight Colour: Comments"); declareColour(mValues->mScripts.mColourId, "Highlight Colour: IDs"); declareCategory("General Input"); declareBool(mValues->mGeneralInput.mCycle, "Cyclic next/previous") .setTooltip( "When using next/previous functions at the last/first item of a " "list go to the first/last item"); declareCategory("3D Scene Input"); declareDouble(mValues->mSceneInput.mNaviWheelFactor, "Camera Zoom Sensitivity").setRange(-100.0, 100.0); declareDouble(mValues->mSceneInput.mSNaviSensitivity, "Secondary Camera Movement Sensitivity") .setRange(-1000.0, 1000.0); declareDouble(mValues->mSceneInput.mPNaviFreeSensitivity, "Free Camera Sensitivity") .setPrecision(5) .setRange(0.0, 1.0); declareBool(mValues->mSceneInput.mPNaviFreeInvert, "Invert Free Camera Mouse Input"); declareDouble(mValues->mSceneInput.mNaviFreeLinSpeed, "Free Camera Linear Speed").setRange(1.0, 10000.0); declareDouble(mValues->mSceneInput.mNaviFreeRotSpeed, "Free Camera Rotational Speed").setRange(0.001, 6.28); declareDouble(mValues->mSceneInput.mNaviFreeSpeedMult, "Free Camera Speed Multiplier (from Modifier)") .setRange(0.001, 1000.0); declareDouble(mValues->mSceneInput.mPNaviOrbitSensitivity, "Orbit Camera Sensitivity") .setPrecision(5) .setRange(0.0, 1.0); declareBool(mValues->mSceneInput.mPNaviOrbitInvert, "Invert Orbit Camera Mouse Input"); declareDouble(mValues->mSceneInput.mNaviOrbitRotSpeed, "Orbital Camera Rotational Speed").setRange(0.001, 6.28); declareDouble(mValues->mSceneInput.mNaviOrbitSpeedMult, "Orbital Camera Speed Multiplier (from Modifier)") .setRange(0.001, 1000.0); declareBool(mValues->mSceneInput.mNaviOrbitConstRoll, "Keep camera roll constant for orbital camera"); declareBool(mValues->mSceneInput.mContextSelect, "Context Sensitive Selection"); declareDouble(mValues->mSceneInput.mDragFactor, "Mouse sensitivity during drag operations").setRange(0.001, 100.0); declareDouble(mValues->mSceneInput.mDragWheelFactor, "Mouse wheel sensitivity during drag operations") .setRange(0.001, 100.0); declareDouble(mValues->mSceneInput.mDragShiftFactor, "Shift-acceleration factor during drag operations") .setTooltip("Acceleration factor during drag operations while holding down shift") .setRange(0.001, 100.0); declareDouble(mValues->mSceneInput.mRotateFactor, "Free rotation factor").setPrecision(4).setRange(0.0001, 0.1); declareCategory("Rendering"); declareInt(mValues->mRendering.mFramerateLimit, "FPS limit") .setTooltip("Framerate limit in 3D preview windows. Zero value means \"unlimited\".") .setRange(0, 10000); declareInt(mValues->mRendering.mCameraFov, "Camera FOV").setRange(10, 170); declareBool(mValues->mRendering.mCameraOrtho, "Orthographic projection for camera"); declareInt(mValues->mRendering.mCameraOrthoSize, "Orthographic projection size parameter") .setTooltip("Size of the orthographic frustum, greater value will allow the camera to see more of the world.") .setRange(10, 10000); declareDouble(mValues->mRendering.mObjectMarkerAlpha, "Object Marker Transparency").setPrecision(2).setRange(0, 1); declareBool(mValues->mRendering.mSceneUseGradient, "Use Gradient Background"); declareColour(mValues->mRendering.mSceneDayBackgroundColour, "Day Background Colour"); declareColour(mValues->mRendering.mSceneDayGradientColour, "Day Gradient Colour") .setTooltip( "Sets the gradient color to use in conjunction with the day background color. Ignored if " "the gradient option is disabled."); declareColour(mValues->mRendering.mSceneBrightBackgroundColour, "Scene Bright Background Colour"); declareColour(mValues->mRendering.mSceneBrightGradientColour, "Scene Bright Gradient Colour") .setTooltip( "Sets the gradient color to use in conjunction with the bright background color. Ignored if " "the gradient option is disabled."); declareColour(mValues->mRendering.mSceneNightBackgroundColour, "Scene Night Background Colour"); declareColour(mValues->mRendering.mSceneNightGradientColour, "Scene Night Gradient Colour") .setTooltip( "Sets the gradient color to use in conjunction with the night background color. Ignored if " "the gradient option is disabled."); declareBool(mValues->mRendering.mSceneDayNightSwitchNodes, "Use Day/Night Switch Nodes"); declareCategory("Tooltips"); declareBool(mValues->mTooltips.mScene, "Show Tooltips in 3D scenes"); declareBool(mValues->mTooltips.mSceneHideBasic, "Hide basic 3D scenes tooltips"); declareInt(mValues->mTooltips.mSceneDelay, "Tooltip delay in milliseconds").setMin(1); declareCategory("3D Scene Editing"); declareDouble(mValues->mSceneEditing.mGridsnapMovement, "Grid snap size"); declareDouble(mValues->mSceneEditing.mGridsnapRotation, "Angle snap size"); declareDouble(mValues->mSceneEditing.mGridsnapScale, "Scale snap size"); declareInt(mValues->mSceneEditing.mDistance, "Drop Distance") .setTooltip( "If an instance drop can not be placed against another object at the " "insert point, it will be placed by this distance from the insert point instead"); declareEnum(mValues->mSceneEditing.mOutsideDrop, "Handling drops outside of cells"); declareEnum(mValues->mSceneEditing.mOutsideVisibleDrop, "Handling drops outside of visible cells"); declareEnum(mValues->mSceneEditing.mOutsideLandedit, "Handling terrain edit outside of cells") .setTooltip("Behavior of terrain editing, if land editing brush reaches an area without cell record."); declareEnum(mValues->mSceneEditing.mOutsideVisibleLandedit, "Handling terrain edit outside of visible cells") .setTooltip( "Behavior of terrain editing, if land editing brush reaches an area that is not currently visible."); declareInt(mValues->mSceneEditing.mTexturebrushMaximumsize, "Maximum texture brush size").setMin(1); declareInt(mValues->mSceneEditing.mShapebrushMaximumsize, "Maximum height edit brush size") .setTooltip("Setting for the slider range of brush size in terrain height editing.") .setMin(1); declareBool(mValues->mSceneEditing.mLandeditPostSmoothpainting, "Smooth land after painting height") .setTooltip("Raise and lower tools will leave bumpy finish without this option"); declareDouble(mValues->mSceneEditing.mLandeditPostSmoothstrength, "Smoothing strength (post-edit)") .setTooltip( "If smoothing land after painting height is used, this is the percentage of smooth applied afterwards. " "Negative values may be used to roughen instead of smooth.") .setMin(-1) .setMax(1); declareBool(mValues->mSceneEditing.mOpenListView, "Open displays list view") .setTooltip( "When opening a reference from the scene view, it will open the" " instance list view instead of the individual instance record view."); declareEnum(mValues->mSceneEditing.mPrimarySelectAction, "Action for primary select") .setTooltip( "Selection can be chosen between select only, add to selection, remove from selection and invert " "selection."); declareEnum(mValues->mSceneEditing.mSecondarySelectAction, "Action for secondary select") .setTooltip( "Selection can be chosen between select only, add to selection, remove from selection and invert " "selection."); declareCategory("Key Bindings"); declareSubcategory("Document"); declareShortcut("document-file-newgame", "New Game", QKeySequence(Qt::ControlModifier | Qt::Key_N)); declareShortcut("document-file-newaddon", "New Addon", QKeySequence()); declareShortcut("document-file-open", "Open", QKeySequence(Qt::ControlModifier | Qt::Key_O)); declareShortcut("document-file-save", "Save", QKeySequence(Qt::ControlModifier | Qt::Key_S)); declareShortcut("document-help-help", "Help", QKeySequence(Qt::Key_F1)); declareShortcut("document-help-tutorial", "Tutorial", QKeySequence()); declareShortcut("document-file-verify", "Verify", QKeySequence()); declareShortcut("document-file-merge", "Merge", QKeySequence()); declareShortcut("document-file-errorlog", "Open Load Error Log", QKeySequence()); declareShortcut("document-file-metadata", "Meta Data", QKeySequence()); declareShortcut("document-file-close", "Close Document", QKeySequence(Qt::ControlModifier | Qt::Key_W)); declareShortcut("document-file-exit", "Exit Application", QKeySequence(Qt::ControlModifier | Qt::Key_Q)); declareShortcut("document-edit-undo", "Undo", QKeySequence(Qt::ControlModifier | Qt::Key_Z)); declareShortcut("document-edit-redo", "Redo", QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_Z)); declareShortcut("document-edit-preferences", "Open Preferences", QKeySequence()); declareShortcut("document-edit-search", "Search", QKeySequence(Qt::ControlModifier | Qt::Key_F)); declareShortcut("document-view-newview", "New View", QKeySequence()); declareShortcut("document-view-statusbar", "Toggle Status Bar", QKeySequence()); declareShortcut("document-view-filters", "Open Filter List", QKeySequence()); declareShortcut("document-world-regions", "Open Region List", QKeySequence()); declareShortcut("document-world-cells", "Open Cell List", QKeySequence()); declareShortcut("document-world-referencables", "Open Object List", QKeySequence()); declareShortcut("document-world-references", "Open Instance List", QKeySequence()); declareShortcut("document-world-lands", "Open Lands List", QKeySequence()); declareShortcut("document-world-landtextures", "Open Land Textures List", QKeySequence()); declareShortcut("document-world-pathgrid", "Open Pathgrid List", QKeySequence()); declareShortcut("document-world-regionmap", "Open Region Map", QKeySequence()); declareShortcut("document-mechanics-globals", "Open Global List", QKeySequence()); declareShortcut("document-mechanics-gamesettings", "Open Game Settings", QKeySequence()); declareShortcut("document-mechanics-scripts", "Open Script List", QKeySequence()); declareShortcut("document-mechanics-spells", "Open Spell List", QKeySequence()); declareShortcut("document-mechanics-enchantments", "Open Enchantment List", QKeySequence()); declareShortcut("document-mechanics-magiceffects", "Open Magic Effect List", QKeySequence()); declareShortcut("document-mechanics-startscripts", "Open Start Script List", QKeySequence()); declareShortcut("document-character-skills", "Open Skill List", QKeySequence()); declareShortcut("document-character-classes", "Open Class List", QKeySequence()); declareShortcut("document-character-factions", "Open Faction List", QKeySequence()); declareShortcut("document-character-races", "Open Race List", QKeySequence()); declareShortcut("document-character-birthsigns", "Open Birthsign List", QKeySequence()); declareShortcut("document-character-topics", "Open Topic List", QKeySequence()); declareShortcut("document-character-journals", "Open Journal List", QKeySequence()); declareShortcut("document-character-topicinfos", "Open Topic Info List", QKeySequence()); declareShortcut("document-character-journalinfos", "Open Journal Info List", QKeySequence()); declareShortcut("document-character-bodyparts", "Open Body Part List", QKeySequence()); declareShortcut("document-assets-reload", "Reload Assets", QKeySequence(Qt::Key_F5)); declareShortcut("document-assets-sounds", "Open Sound Asset List", QKeySequence()); declareShortcut("document-assets-soundgens", "Open Sound Generator List", QKeySequence()); declareShortcut("document-assets-meshes", "Open Mesh Asset List", QKeySequence()); declareShortcut("document-assets-icons", "Open Icon Asset List", QKeySequence()); declareShortcut("document-assets-music", "Open Music Asset List", QKeySequence()); declareShortcut("document-assets-soundres", "Open Sound File List", QKeySequence()); declareShortcut("document-assets-textures", "Open Texture Asset List", QKeySequence()); declareShortcut("document-assets-videos", "Open Video Asset List", QKeySequence()); declareShortcut("document-debug-run", "Run Debug", QKeySequence()); declareShortcut("document-debug-shutdown", "Stop Debug", QKeySequence()); declareShortcut("document-debug-profiles", "Debug Profiles", QKeySequence()); declareShortcut("document-debug-runlog", "Open Run Log", QKeySequence()); declareSubcategory("Table"); declareShortcut("table-edit", "Edit Record", QKeySequence()); declareShortcut("table-add", "Add Row/Record", QKeySequence(Qt::ShiftModifier | Qt::Key_A)); declareShortcut("table-clone", "Clone Record", QKeySequence(Qt::ShiftModifier | Qt::Key_D)); declareShortcut("touch-record", "Touch Record", QKeySequence()); declareShortcut("table-revert", "Revert Record", QKeySequence()); declareShortcut("table-remove", "Remove Row/Record", QKeySequence(Qt::Key_Delete)); declareShortcut("table-moveup", "Move Record Up", QKeySequence()); declareShortcut("table-movedown", "Move Record Down", QKeySequence()); declareShortcut("table-view", "View Record", QKeySequence(Qt::ShiftModifier | Qt::Key_C)); declareShortcut("table-preview", "Preview Record", QKeySequence(Qt::ShiftModifier | Qt::Key_V)); declareShortcut("table-extendeddelete", "Extended Record Deletion", QKeySequence()); declareShortcut("table-extendedrevert", "Extended Record Revertion", QKeySequence()); declareSubcategory("Report Table"); declareShortcut("reporttable-show", "Show Report", QKeySequence()); declareShortcut("reporttable-remove", "Remove Report", QKeySequence(Qt::Key_Delete)); declareShortcut("reporttable-replace", "Replace Report", QKeySequence()); declareShortcut("reporttable-refresh", "Refresh Report", QKeySequence()); declareSubcategory("Scene"); declareShortcut("scene-navi-primary", "Camera Rotation From Mouse Movement", QKeySequence(Qt::LeftButton)); declareShortcut("scene-navi-secondary", "Camera Translation From Mouse Movement", QKeySequence(Qt::ControlModifier | (int)Qt::LeftButton)); declareShortcut("scene-open-primary", "Primary Open", QKeySequence(Qt::ShiftModifier | (int)Qt::LeftButton)); declareShortcut("scene-edit-primary", "Primary Edit", QKeySequence(Qt::RightButton)); declareShortcut("scene-edit-secondary", "Secondary Edit", QKeySequence(Qt::ControlModifier | (int)Qt::RightButton)); declareShortcut("scene-select-primary", "Primary Select", QKeySequence(Qt::MiddleButton)); declareShortcut( "scene-select-secondary", "Secondary Select", QKeySequence(Qt::ControlModifier | (int)Qt::MiddleButton)); declareShortcut( "scene-select-tertiary", "Tertiary Select", QKeySequence(Qt::ShiftModifier | (int)Qt::MiddleButton)); declareModifier(mValues->mKeyBindings.mSceneSpeedModifier, "Speed Modifier"); declareShortcut("scene-delete", "Delete Instance", QKeySequence(Qt::Key_Delete)); declareShortcut("scene-instance-drop-terrain", "Drop to terrain level", QKeySequence(Qt::Key_G)); declareShortcut("scene-instance-drop-collision", "Drop to collision", QKeySequence(Qt::Key_H)); declareShortcut("scene-instance-drop-terrain-separately", "Drop to terrain level separately", QKeySequence()); declareShortcut("scene-instance-drop-collision-separately", "Drop to collision separately", QKeySequence()); declareShortcut("scene-load-cam-cell", "Load Camera Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_5)); declareShortcut("scene-load-cam-eastcell", "Load East Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_6)); declareShortcut("scene-load-cam-northcell", "Load North Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_8)); declareShortcut("scene-load-cam-westcell", "Load West Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_4)); declareShortcut("scene-load-cam-southcell", "Load South Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_2)); declareShortcut("scene-edit-abort", "Abort", QKeySequence(Qt::Key_Escape)); declareShortcut("scene-focus-toolbar", "Toggle Toolbar Focus", QKeySequence(Qt::Key_T)); declareShortcut("scene-render-stats", "Debug Rendering Stats", QKeySequence(Qt::Key_F3)); declareShortcut("scene-duplicate", "Duplicate Instance", QKeySequence(Qt::ShiftModifier | Qt::Key_C)); declareShortcut("scene-clear-selection", "Clear Selection", QKeySequence(Qt::Key_Space)); declareShortcut("scene-unhide-all", "Unhide All Objects", QKeySequence(Qt::AltModifier | Qt::Key_H)); declareShortcut("scene-toggle-visibility", "Toggle Selection Visibility", QKeySequence(Qt::Key_H)); declareShortcut("scene-group-1", "Select Group 1", QKeySequence(Qt::Key_1)); declareShortcut("scene-save-1", "Save Group 1", QKeySequence(Qt::ControlModifier | Qt::Key_1)); declareShortcut("scene-group-2", "Select Group 2", QKeySequence(Qt::Key_2)); declareShortcut("scene-save-2", "Save Group 2", QKeySequence(Qt::ControlModifier | Qt::Key_2)); declareShortcut("scene-group-3", "Select Group 3", QKeySequence(Qt::Key_3)); declareShortcut("scene-save-3", "Save Group 3", QKeySequence(Qt::ControlModifier | Qt::Key_3)); declareShortcut("scene-group-4", "Select Group 4", QKeySequence(Qt::Key_4)); declareShortcut("scene-save-4", "Save Group 4", QKeySequence(Qt::ControlModifier | Qt::Key_4)); declareShortcut("scene-group-5", "Selection Group 5", QKeySequence(Qt::Key_5)); declareShortcut("scene-save-5", "Save Group 5", QKeySequence(Qt::ControlModifier | Qt::Key_5)); declareShortcut("scene-group-6", "Selection Group 6", QKeySequence(Qt::Key_6)); declareShortcut("scene-save-6", "Save Group 6", QKeySequence(Qt::ControlModifier | Qt::Key_6)); declareShortcut("scene-group-7", "Selection Group 7", QKeySequence(Qt::Key_7)); declareShortcut("scene-save-7", "Save Group 7", QKeySequence(Qt::ControlModifier | Qt::Key_7)); declareShortcut("scene-group-8", "Selection Group 8", QKeySequence(Qt::Key_8)); declareShortcut("scene-save-8", "Save Group 8", QKeySequence(Qt::ControlModifier | Qt::Key_8)); declareShortcut("scene-group-9", "Selection Group 9", QKeySequence(Qt::Key_9)); declareShortcut("scene-save-9", "Save Group 9", QKeySequence(Qt::ControlModifier | Qt::Key_9)); declareShortcut("scene-group-0", "Selection Group 10", QKeySequence(Qt::Key_0)); declareShortcut("scene-save-0", "Save Group 10", QKeySequence(Qt::ControlModifier | Qt::Key_0)); declareSubcategory("1st/Free Camera"); declareShortcut("free-forward", "Forward", QKeySequence(Qt::Key_W)); declareShortcut("free-backward", "Backward", QKeySequence(Qt::Key_S)); declareShortcut("free-left", "Left", QKeySequence(Qt::Key_A)); declareShortcut("free-right", "Right", QKeySequence(Qt::Key_D)); declareShortcut("free-roll-left", "Roll Left", QKeySequence(Qt::Key_Q)); declareShortcut("free-roll-right", "Roll Right", QKeySequence(Qt::Key_E)); declareShortcut("free-speed-mode", "Toggle Speed Mode", QKeySequence(Qt::Key_F)); declareSubcategory("Orbit Camera"); declareShortcut("orbit-up", "Up", QKeySequence(Qt::Key_W)); declareShortcut("orbit-down", "Down", QKeySequence(Qt::Key_S)); declareShortcut("orbit-left", "Left", QKeySequence(Qt::Key_A)); declareShortcut("orbit-right", "Right", QKeySequence(Qt::Key_D)); declareShortcut("orbit-roll-left", "Roll Left", QKeySequence(Qt::Key_Q)); declareShortcut("orbit-roll-right", "Roll Right", QKeySequence(Qt::Key_E)); declareShortcut("orbit-speed-mode", "Toggle Speed Mode", QKeySequence(Qt::Key_F)); declareShortcut("orbit-center-selection", "Center On Selected", QKeySequence(Qt::Key_C)); declareSubcategory("Script Editor"); declareShortcut("script-editor-comment", "Comment Selection", QKeySequence()); declareShortcut("script-editor-uncomment", "Uncomment Selection", QKeySequence()); declareCategory("Models"); declareString(mValues->mModels.mBaseanim, "base animations").setTooltip("3rd person base model with textkeys-data"); declareString(mValues->mModels.mBaseanimkna, "base animations, kna") .setTooltip("3rd person beast race base model with textkeys-data"); declareString(mValues->mModels.mBaseanimfemale, "base animations, female") .setTooltip("3rd person female base model with textkeys-data"); declareString(mValues->mModels.mWolfskin, "base animations, wolf").setTooltip("3rd person werewolf skin"); } void CSMPrefs::State::declareCategory(const std::string& key) { std::map::iterator iter = mCategories.find(key); if (iter != mCategories.end()) { mCurrentCategory = iter; } else { mCurrentCategory = mCategories.insert(std::make_pair(key, Category(this, key))).first; } } CSMPrefs::IntSetting& CSMPrefs::State::declareInt(Settings::SettingValue& value, const QString& label) { if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); CSMPrefs::IntSetting* setting = new CSMPrefs::IntSetting(&mCurrentCategory->second, &mMutex, value.mName, label, *mIndex); mCurrentCategory->second.addSetting(setting); return *setting; } CSMPrefs::DoubleSetting& CSMPrefs::State::declareDouble(Settings::SettingValue& value, const QString& label) { if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); CSMPrefs::DoubleSetting* setting = new CSMPrefs::DoubleSetting(&mCurrentCategory->second, &mMutex, value.mName, label, *mIndex); mCurrentCategory->second.addSetting(setting); return *setting; } CSMPrefs::BoolSetting& CSMPrefs::State::declareBool(Settings::SettingValue& value, const QString& label) { if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); CSMPrefs::BoolSetting* setting = new CSMPrefs::BoolSetting(&mCurrentCategory->second, &mMutex, value.mName, label, *mIndex); mCurrentCategory->second.addSetting(setting); return *setting; } CSMPrefs::EnumSetting& CSMPrefs::State::declareEnum(EnumSettingValue& value, const QString& label) { if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); CSMPrefs::EnumSetting* setting = new CSMPrefs::EnumSetting( &mCurrentCategory->second, &mMutex, value.getValue().mName, label, value.getEnumValues(), *mIndex); mCurrentCategory->second.addSetting(setting); return *setting; } CSMPrefs::ColourSetting& CSMPrefs::State::declareColour( Settings::SettingValue& value, const QString& label) { if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); CSMPrefs::ColourSetting* setting = new CSMPrefs::ColourSetting(&mCurrentCategory->second, &mMutex, value.mName, label, *mIndex); mCurrentCategory->second.addSetting(setting); return *setting; } CSMPrefs::ShortcutSetting& CSMPrefs::State::declareShortcut( const std::string& key, const QString& label, const QKeySequence& default_) { if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); // Setup with actual data QKeySequence sequence; getShortcutManager().convertFromString(mIndex->get(mCurrentCategory->second.getKey(), key), sequence); getShortcutManager().setSequence(key, sequence); CSMPrefs::ShortcutSetting* setting = new CSMPrefs::ShortcutSetting(&mCurrentCategory->second, &mMutex, key, label, *mIndex); mCurrentCategory->second.addSetting(setting); return *setting; } CSMPrefs::StringSetting& CSMPrefs::State::declareString( Settings::SettingValue& value, const QString& label) { if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); CSMPrefs::StringSetting* setting = new CSMPrefs::StringSetting(&mCurrentCategory->second, &mMutex, value.mName, label, *mIndex); mCurrentCategory->second.addSetting(setting); return *setting; } CSMPrefs::ModifierSetting& CSMPrefs::State::declareModifier( Settings::SettingValue& value, const QString& label) { if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); // Setup with actual data int modifier; getShortcutManager().convertFromString(value.get(), modifier); getShortcutManager().setModifier(value.mName, modifier); CSMPrefs::ModifierSetting* setting = new CSMPrefs::ModifierSetting(&mCurrentCategory->second, &mMutex, value.mName, label, *mIndex); mCurrentCategory->second.addSetting(setting); return *setting; } void CSMPrefs::State::declareSubcategory(const QString& label) { if (mCurrentCategory == mCategories.end()) throw std::logic_error("no category for setting"); mCurrentCategory->second.addSubcategory( new CSMPrefs::Subcategory(&mCurrentCategory->second, &mMutex, label, *mIndex)); } CSMPrefs::State::State(const Files::ConfigurationManager& configurationManager) : mConfigFile("openmw-cs.cfg") , mDefaultConfigFile("defaults-cs.bin") , mConfigurationManager(configurationManager) , mCurrentCategory(mCategories.end()) , mIndex(std::make_unique()) , mValues(std::make_unique(*mIndex)) { if (sThis) throw std::logic_error("An instance of CSMPRefs::State already exists"); sThis = this; declare(); } CSMPrefs::State::~State() { sThis = nullptr; } void CSMPrefs::State::save() { Settings::Manager::saveUser(mConfigurationManager.getUserConfigPath() / mConfigFile); } CSMPrefs::State::Iterator CSMPrefs::State::begin() { return mCategories.begin(); } CSMPrefs::State::Iterator CSMPrefs::State::end() { return mCategories.end(); } CSMPrefs::ShortcutManager& CSMPrefs::State::getShortcutManager() { return mShortcutManager; } CSMPrefs::Category& CSMPrefs::State::operator[](const std::string& key) { Iterator iter = mCategories.find(key); if (iter == mCategories.end()) throw std::logic_error("Invalid user settings category: " + key); return iter->second; } void CSMPrefs::State::update(const Setting& setting) { emit settingChanged(&setting); } CSMPrefs::State& CSMPrefs::State::get() { if (!sThis) throw std::logic_error("No instance of CSMPrefs::State"); return *sThis; } void CSMPrefs::State::resetCategory(const std::string& category) { Collection::iterator container = mCategories.find(category); if (container != mCategories.end()) { for (Setting* setting : container->second) { setting->reset(); update(*setting); } } } void CSMPrefs::State::resetAll() { for (Collection::iterator iter = mCategories.begin(); iter != mCategories.end(); ++iter) { resetCategory(iter->first); } } CSMPrefs::State& CSMPrefs::get() { return State::get(); }