forked from mirror/openmw-tes3mp
Merge branch 'master' into appveyor
This commit is contained in:
commit
93e100f210
671 changed files with 20928 additions and 17441 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -5,7 +5,7 @@ CMakeCache.txt
|
||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
Makefile
|
Makefile
|
||||||
makefile
|
makefile
|
||||||
build
|
build*
|
||||||
prebuilt
|
prebuilt
|
||||||
|
|
||||||
## doxygen
|
## doxygen
|
||||||
|
|
|
@ -40,8 +40,8 @@ script:
|
||||||
- cd ./build
|
- cd ./build
|
||||||
- if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then ${ANALYZE}make -j2; fi
|
- if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then ${ANALYZE}make -j2; fi
|
||||||
- if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi
|
- if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi
|
||||||
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi
|
- if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi
|
||||||
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then cd .. && ./CI/check_tabs.sh; fi
|
- if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then cd .. && ./CI/check_tabs.sh; fi
|
||||||
notifications:
|
notifications:
|
||||||
recipients:
|
recipients:
|
||||||
- corrmage+travis-ci@gmail.com
|
- corrmage+travis-ci@gmail.com
|
||||||
|
|
|
@ -13,6 +13,7 @@ Programmers
|
||||||
Marc Zinnschlag (Zini) - Lead Programmer/Project Manager
|
Marc Zinnschlag (Zini) - Lead Programmer/Project Manager
|
||||||
|
|
||||||
Adam Hogan (aurix)
|
Adam Hogan (aurix)
|
||||||
|
Aesylwinn
|
||||||
Aleksandar Jovanov
|
Aleksandar Jovanov
|
||||||
Alex Haddad (rainChu)
|
Alex Haddad (rainChu)
|
||||||
Alex McKibben (WeirdSexy)
|
Alex McKibben (WeirdSexy)
|
||||||
|
@ -47,6 +48,7 @@ Programmers
|
||||||
Gašper Sedej
|
Gašper Sedej
|
||||||
gugus/gus
|
gugus/gus
|
||||||
Hallfaer Tuilinn
|
Hallfaer Tuilinn
|
||||||
|
hristoast
|
||||||
Internecine
|
Internecine
|
||||||
Jacob Essex (Yacoby)
|
Jacob Essex (Yacoby)
|
||||||
Jannik Heller (scrawl)
|
Jannik Heller (scrawl)
|
||||||
|
@ -55,6 +57,7 @@ Programmers
|
||||||
Jeffrey Haines (Jyby)
|
Jeffrey Haines (Jyby)
|
||||||
Jengerer
|
Jengerer
|
||||||
Jiří Kuneš (kunesj)
|
Jiří Kuneš (kunesj)
|
||||||
|
Joe Wilkerson (neuralroberts)
|
||||||
Joel Graff (graffy)
|
Joel Graff (graffy)
|
||||||
John Blomberg (fstp)
|
John Blomberg (fstp)
|
||||||
Jordan Ayers
|
Jordan Ayers
|
||||||
|
@ -74,6 +77,7 @@ Programmers
|
||||||
Marco Melletti (mellotanica)
|
Marco Melletti (mellotanica)
|
||||||
Marco Schulze
|
Marco Schulze
|
||||||
Mateusz Kołaczek (PL_kolek)
|
Mateusz Kołaczek (PL_kolek)
|
||||||
|
Mateusz Malisz (malice)
|
||||||
megaton
|
megaton
|
||||||
Michael Hogan (Xethik)
|
Michael Hogan (Xethik)
|
||||||
Michael Mc Donnell
|
Michael Mc Donnell
|
||||||
|
@ -88,10 +92,12 @@ Programmers
|
||||||
Nikolay Kasyanov (corristo)
|
Nikolay Kasyanov (corristo)
|
||||||
nobrakal
|
nobrakal
|
||||||
Nolan Poe (nopoe)
|
Nolan Poe (nopoe)
|
||||||
|
Paul Cercueil (pcercuei)
|
||||||
Paul McElroy (Greendogo)
|
Paul McElroy (Greendogo)
|
||||||
Pieter van der Kloet (pvdk)
|
Pieter van der Kloet (pvdk)
|
||||||
pkubik
|
pkubik
|
||||||
Radu-Marius Popovici (rpopovici)
|
Radu-Marius Popovici (rpopovici)
|
||||||
|
rcutmore
|
||||||
rdimesio
|
rdimesio
|
||||||
riothamus
|
riothamus
|
||||||
Robert MacGregor (Ragora)
|
Robert MacGregor (Ragora)
|
||||||
|
|
229
CHANGELOG.md
229
CHANGELOG.md
|
@ -1,3 +1,232 @@
|
||||||
|
0.37.0
|
||||||
|
------
|
||||||
|
|
||||||
|
Bug #385: Light emitting objects have a too short distance of activation
|
||||||
|
Bug #455: Animation doesn't resize creature's bounding box
|
||||||
|
Bug #602: Only collision model is updated when modifying objects trough console
|
||||||
|
Bug #639: Sky horizon at nighttime
|
||||||
|
Bug #672: incorrect trajectory of the moons
|
||||||
|
Bug #814: incorrect NPC width
|
||||||
|
Bug #827: Inaccurate raycasting for dead actors
|
||||||
|
Bug #996: Can see underwater clearly when at right height/angle
|
||||||
|
Bug #1317: Erene Llenim in Seyda Neen does not walk around
|
||||||
|
Bug #1330: Cliff racers fail to hit the player
|
||||||
|
Bug #1366: Combat AI can't aim down (in order to hit small creatures)
|
||||||
|
Bug #1511: View distance while under water is much too short
|
||||||
|
Bug #1563: Terrain positioned incorrectly and appears to vibrate in far-out cells
|
||||||
|
Bug #1612: First person models clip through walls
|
||||||
|
Bug #1647: Crash switching from full screen to windows mode - D3D9
|
||||||
|
Bug #1650: No textures with directx on windows
|
||||||
|
Bug #1730: Scripts names starting with digit(s) fail to compile
|
||||||
|
Bug #1738: Socucius Ergalla's greetings are doubled during the tutorial
|
||||||
|
Bug #1784: First person weapons always in the same position
|
||||||
|
Bug #1813: Underwater flora lighting up entire area.
|
||||||
|
Bug #1871: Handle controller extrapolation flags
|
||||||
|
Bug #1921: Footstep frequency and velocity do not immediately update when speed attribute changes
|
||||||
|
Bug #2001: OpenMW crashes on start with OpenGL 1.4 drivers
|
||||||
|
Bug #2014: Antialiasing setting does nothing on Linux
|
||||||
|
Bug #2037: Some enemies attack the air when spotting the player
|
||||||
|
Bug #2052: NIF rotation matrices including scales are not supported
|
||||||
|
Bug #2062: Crank in Old Mournhold: Forgotten Sewer turns about the wrong axis
|
||||||
|
Bug #2111: Raindrops in front of fire look wrong
|
||||||
|
Bug #2140: [OpenGL] Water effects, flames and parts of creatures solid black when observed through brazier flame
|
||||||
|
Bug #2147: Trueflame and Hopesfire flame effects not properly aligned with blade
|
||||||
|
Bug #2148: Verminous fabricants have little coloured box beneath their feet
|
||||||
|
Bug #2149: Sparks in Clockwork City should bounce off the floor
|
||||||
|
Bug #2151: Clockwork City dicer trap doesn't activate when you're too close
|
||||||
|
Bug #2186: Mini map contains scrambled pixels that cause the mini map to flicker
|
||||||
|
Bug #2187: NIF file with more than 255 NiBillboardNodes does not load
|
||||||
|
Bug #2191: Editor: Crash when trying to view cell in render view in OpenCS
|
||||||
|
Bug #2270: Objects flicker transparently
|
||||||
|
Bug #2280: Latest 32bit windows build of openmw runns out of vram
|
||||||
|
Bug #2281: NPCs don't scream when they die
|
||||||
|
Bug #2286: Jumping animation restarts when equipping mid-air
|
||||||
|
Bug #2287: Weapon idle animation stops when turning
|
||||||
|
Bug #2355: Light spell doesn't work in 1st person view
|
||||||
|
Bug #2362: Lantern glas opaque to flame effect from certain viewing angles
|
||||||
|
Bug #2364: Light spells are not as bright as in Morrowind
|
||||||
|
Bug #2383: Remove the alpha testing override list
|
||||||
|
Bug #2436: Crash on entering cell "Tower of Tel Fyr, Hall of Fyr"
|
||||||
|
Bug #2457: Player followers should not report crimes
|
||||||
|
Bug #2458: crash in some fighting situations
|
||||||
|
Bug #2464: Hiding an emitter node should make that emitter stop firing particles
|
||||||
|
Bug #2466: Can't load a save created with OpenMW-0.35.0-win64
|
||||||
|
Bug #2468: music from title screen continues after loading savegame
|
||||||
|
Bug #2494: Map not consistent between saves
|
||||||
|
Bug #2504: Dialog scroll should always start at the top
|
||||||
|
Bug #2506: Editor: Undo/Redo shortcuts do not work in script editor
|
||||||
|
Bug #2513: Mannequins in mods appear as dead bodies
|
||||||
|
Bug #2524: Editor: TopicInfo "custom" condition section is missing
|
||||||
|
Bug #2540: Editor: search and verification result table can not be sorted by clicking on the column names
|
||||||
|
Bug #2543: Editor: there is a problem with spell effects
|
||||||
|
Bug #2544: Editor fails to save NPC information correctly.
|
||||||
|
Bug #2545: Editor: delete record in Objects (referenceables) table messes up data
|
||||||
|
Bug #2546: Editor: race base attributes and skill boni are not displayed, thus not editable
|
||||||
|
Bug #2547: Editor: some NPC data is not displayed, thus not editable
|
||||||
|
Bug #2551: Editor: missing data in cell definition
|
||||||
|
Bug #2553: Editor: value filter does not work for float values
|
||||||
|
Bug #2555: Editor: undo leaves the record status as Modified
|
||||||
|
Bug #2559: Make Detect Enchantment marks appear on top of the player arrow
|
||||||
|
Bug #2563: position consoling npc doesn't work without cell reload
|
||||||
|
Bug #2564: Editor: Closing a subview from code does not clean up properly and will lead to crash on opening the next subview
|
||||||
|
Bug #2568: Editor: Setting default window size is ignored
|
||||||
|
Bug #2569: Editor: saving from an esp to omwaddon file results in data loss for TopicInfo
|
||||||
|
Bug #2575: Editor: Deleted record (with Added (ModifiedOnly) status) remains in the Dialog SubView
|
||||||
|
Bug #2576: Editor: Editor doesn't scroll to a newly opened subview, when ScrollBar Only mode is active
|
||||||
|
Bug #2578: Editor: changing Level or Reputation of an NPC crashes the editor
|
||||||
|
Bug #2579: Editor: filters not updated when adding or cloning records
|
||||||
|
Bug #2580: Editor: omwaddon makes OpenMW crash
|
||||||
|
Bug #2581: Editor: focus problems in edit subviews single- and multiline input fields
|
||||||
|
Bug #2582: Editor: object verifier should check for non-existing scripts being referenced
|
||||||
|
Bug #2583: Editor: applying filter to TopicInfo on mods that have added dialouge makes the Editor crash
|
||||||
|
Bug #2586: Editor: some dialogue only editable items do not refresh after undo
|
||||||
|
Bug #2588: Editor: Cancel button exits program
|
||||||
|
Bug #2589: Editor: Regions table - mapcolor does not change correctly
|
||||||
|
Bug #2591: Placeatme - spurious 5th parameter raises error
|
||||||
|
Bug #2593: COC command prints multiple times when GUI is hidden
|
||||||
|
Bug #2598: Editor: scene view of instances has to be zoomed out to displaying something - center camera instance please
|
||||||
|
Bug #2607: water behind an invisible NPC becomes invisible as well
|
||||||
|
Bug #2611: Editor: Sort problem in Objects table when few nested rows are added
|
||||||
|
Bug #2621: crash when a creature has no model
|
||||||
|
Bug #2624: Editor: missing columns in tables
|
||||||
|
Bug #2627: Character sheet doesn't properly update when backing out of CharGen
|
||||||
|
Bug #2642: Editor: endif without if - is not reported as error when "verify" was executed
|
||||||
|
Bug #2644: Editor: rebuild the list of available content files when opening the open/new dialogues
|
||||||
|
Bug #2656: OpenMW & OpenMW-CS: setting "Flies" flag for ghosts has no effect
|
||||||
|
Bug #2659: OpenMW & OpenMW-CS: savegame load fail due to script attached to NPCs
|
||||||
|
Bug #2668: Editor: reputation value in the input field is not stored
|
||||||
|
Bug #2696: Horkers use land idle animations under water
|
||||||
|
Bug #2705: Editor: Sort by Record Type (Objects table) is incorrect
|
||||||
|
Bug #2711: Map notes on an exterior cell that shows up with a map marker on the world map do not show up in the tooltip for that cell's marker on the world map
|
||||||
|
Bug #2714: Editor: Can't reorder rows with the same topic in different letter case
|
||||||
|
Bug #2720: Head tracking for creatures not implemented
|
||||||
|
Bug #2722: Alchemy should only include effects shared by at least 2 ingredients
|
||||||
|
Bug #2723: "ori" console command is not working
|
||||||
|
Bug #2726: Ashlanders in front of Ghostgate start wandering around
|
||||||
|
Bug #2727: ESM writer does not handle encoding when saving the TES3 header
|
||||||
|
Bug #2728: Editor: Incorrect position of an added row in Info tables
|
||||||
|
Bug #2731: Editor: Deleting a record triggers a Qt warning
|
||||||
|
Bug #2733: Editor: Undo doesn't restore the Modified status of a record when a nested data is changed
|
||||||
|
Bug #2734: Editor: The Search doesn't work
|
||||||
|
Bug #2738: Additive moon blending
|
||||||
|
Bug #2746: NIF node names should be case insensitive
|
||||||
|
Bug #2752: Fog depth/density not handled correctly
|
||||||
|
Bug #2753: Editor: line edit in dialogue subview tables shows after a single click
|
||||||
|
Bug #2755: Combat AI changes target too frequently
|
||||||
|
Bug #2761: Can't attack during block animations
|
||||||
|
Bug #2764: Player doesn't raise arm in 3rd person for weathertype 9
|
||||||
|
Bug #2768: Current screen resolution not selected in options when starting OpenMW
|
||||||
|
Bug #2773: Editor: Deleted scripts are editable
|
||||||
|
Bug #2776: ordinators still think I'm wearing their helm even though Khajiit and argonians can't
|
||||||
|
Bug #2779: Slider bars continue to move if you don't release mouse button
|
||||||
|
Bug #2781: sleep interruption is a little off (is this an added feature?)
|
||||||
|
Bug #2782: erroneously able to ready weapon/magic (+sheathe weapon/magic) while paralyzed
|
||||||
|
Bug #2785: Editor: Incorrect GMSTs for newly created omwgame files
|
||||||
|
Bug #2786: Kwama Queen head is inverted under OpenMW
|
||||||
|
Bug #2788: additem and removeitem incorrect gold behavior
|
||||||
|
Bug #2790: --start doesn't trace down
|
||||||
|
Bug #2791: Editor: Listed attributes and skill should not be based on number of NPC objects.
|
||||||
|
Bug #2792: glitched merchantile/infinite free items
|
||||||
|
Bug #2794: Need to ignore quotes in names of script function
|
||||||
|
Bug #2797: Editor: Crash when removing the first row in a nested table
|
||||||
|
Bug #2800: Show an error message when S3TC support is missing
|
||||||
|
Bug #2811: Targetted Open spell effect persists.
|
||||||
|
Bug #2819: Editor: bodypart's race filter not displayed correctly
|
||||||
|
Bug #2820: Editor: table sorting is inverted
|
||||||
|
Bug #2821: Editor: undo/redo command labels are incorrect
|
||||||
|
Bug #2826: locking beds that have been locked via magic psuedo-freezes the game
|
||||||
|
Bug #2830: Script compiler does not accept IDs as instruction/functions arguments if the ID is also a keyword
|
||||||
|
Bug #2832: Cell names are not localized on the world map
|
||||||
|
Bug #2833: [cosmetic] Players swimming at water's surface are slightly too low.
|
||||||
|
Bug #2840: Save/load menu is not entirely localized
|
||||||
|
Bug #2853: [exploit/bug] disintegrate weapon incorrectly applying to lockpicks, probes. creates unbreakable lockpicks
|
||||||
|
Bug #2855: Mouse wheel in journal is not disabled by "Options" panel.
|
||||||
|
Bug #2856: Heart of Lorkhan doesn't visually respond to attacks
|
||||||
|
Bug #2863: Inventory highlights wrong category after load
|
||||||
|
Bug #2864: Illuminated Order 1.0c Bug – The teleport amulet is not placed in the PC inventory.
|
||||||
|
Bug #2866: Editor: use checkbox instead of combobox for boolean values
|
||||||
|
Bug #2875: special cases of fSleepRandMod not behaving properly.
|
||||||
|
Bug #2878: Editor: Verify reports "creature has non-positive level" but there is no level setting
|
||||||
|
Bug #2879: Editor: entered value of field "Buys *" is not saved for a creature
|
||||||
|
Bug #2880: OpenMW & OpenMW-CS: having a scale value of 0.000 makes the game laggy
|
||||||
|
Bug #2882: Freeze when entering cell "Guild of Fighters (Ald'ruhn)" after dropping some items inside
|
||||||
|
Bug #2883: game not playable if mod providing a spell is removed but the list of known spells still contains it
|
||||||
|
Bug #2884: NPC chats about wrong player race
|
||||||
|
Bug #2886: Adding custom races breaks existing numbering of PcRace
|
||||||
|
Bug #2888: Editor: value entered in "AI Wander Idle" is not kept
|
||||||
|
Bug #2889: Editor: creatures made with the CS (not cloned) are always dead
|
||||||
|
Bug #2890: Editor: can't make NPC say a specific "Hello" voice-dialouge
|
||||||
|
Bug #2893: Editor: making a creature use textual dialogue doesn't work.
|
||||||
|
Bug #2901: Editor: gold for trading can not be set for creatures
|
||||||
|
Bug #2907: looking from uderwater part of the PC that is below the surface looks like it would be above the water
|
||||||
|
Bug #2914: Magicka not recalculated on character generation
|
||||||
|
Bug #2915: When paralyzed, you can still enter and exit sneak
|
||||||
|
Bug #2917: chameleon does not work for creatures
|
||||||
|
Bug #2927: Editor: in the automatic script checker local variable caches are not invalidated/updated on modifications of other scripts
|
||||||
|
Bug #2930: Editor: AIWander Idle can not be set for a creature
|
||||||
|
Bug #2932: Editor: you can add rows to "Creature Attack" but you can not enter values
|
||||||
|
Bug #2938: Editor: Can't add a start script.
|
||||||
|
Bug #2944: Spell chance for power to show as 0 on hud when used
|
||||||
|
Bug #2953: Editor: rightclick in an empty place in the menu bar shows an unnamed checkbox
|
||||||
|
Bug #2956: Editor: freezes while editing Filter
|
||||||
|
Bug #2959: space character in field enchantment (of an amulet) prevents rendering of surroundings
|
||||||
|
Bug #2962: OpenMW: Assertion `it != invStore.end()' failed
|
||||||
|
Bug #2964: Recursive script execution can corrupt script runtime data
|
||||||
|
Bug #2973: Editor: placing a chest in the game world and activating it heavily blurrs the character portrait
|
||||||
|
Bug #2978: Editor: Cannot edit alchemy ingredient properties
|
||||||
|
Bug #2980: Editor: Attribute and Skill can be selected for spells that do not require these parameters, leading to non-functional spells
|
||||||
|
Bug #2990: Compiling a script with warning mode 2 and enabled error downgrading leads to infinite recursion
|
||||||
|
Bug #2992: [Mod: Great House Dagoth] Killing Dagoth Gares freezes the game
|
||||||
|
Bug #3007: PlaceItem takes radians instead of degrees + angle reliability
|
||||||
|
Feature #706: Editor: Script Editor enhancements
|
||||||
|
Feature #872: Editor: Colour values in tables
|
||||||
|
Feature #880: Editor: ID auto-complete
|
||||||
|
Feature #928: Editor: Partial sorting in info tables
|
||||||
|
Feature #942: Editor: Dialogue for editing/viewing content file meta information
|
||||||
|
Feature #1057: NiStencilProperty
|
||||||
|
Feature #1278: Editor: Mouse picking in worldspace widget
|
||||||
|
Feature #1280: Editor: Cell border arrows
|
||||||
|
Feature #1401: Editor: Cloning enhancements
|
||||||
|
Feature #1463: Editor: Fine grained configuration of extended revert/delete commands
|
||||||
|
Feature #1591: Editor: Make fields in creation bar drop targets where applicable
|
||||||
|
Feature #1998: Editor: Magic effect record verifier
|
||||||
|
Feature #1999: Editor Sound Gen record verifier
|
||||||
|
Feature #2000: Editor: Pathgrid record verifier
|
||||||
|
Feature #2528: Game Time Tracker
|
||||||
|
Feature #2534: Editor: global search does not auomatically focus the search input field
|
||||||
|
Feature #2535: OpenMW: allow comments in openmw.cfg
|
||||||
|
Feature #2541: Editor: provide a go to the very bottom button for TopicInfo and JournalInfo
|
||||||
|
Feature #2549: Editor: add a horizontal slider to scroll between opened tables
|
||||||
|
Feature #2558: Editor: provide a shortcut for closing the subview that has the focus
|
||||||
|
Feature #2565: Editor: add context menu for dialogue sub view fields with an item matching "Edit 'x'" from the table subview context menu
|
||||||
|
Feature #2585: Editor: Ignore mouse wheel input for numeric values unless the respective widget has the focus
|
||||||
|
Feature #2620: Editor: make the verify-view refreshable
|
||||||
|
Feature #2622: Editor: Make double click behaviour in result tables configurable (see ID tables)
|
||||||
|
Feature #2717: Editor: Add severity column to report tables
|
||||||
|
Feature #2729: Editor: Various dialogue button bar improvements
|
||||||
|
Feature #2739: Profiling overlay
|
||||||
|
Feature #2740: Resource manager optimizations
|
||||||
|
Feature #2741: Make NIF files into proper resources
|
||||||
|
Feature #2742: Use the skinning data in NIF files as-is
|
||||||
|
Feature #2743: Small feature culling
|
||||||
|
Feature #2744: Configurable near clip distance
|
||||||
|
Feature #2745: GUI scaling option
|
||||||
|
Feature #2747: Support anonymous textures
|
||||||
|
Feature #2749: Loading screen optimizations
|
||||||
|
Feature #2751: Character preview optimization
|
||||||
|
Feature #2804: Editor: Merge Tool
|
||||||
|
Feature #2818: Editor: allow copying a record ID to the clipboard
|
||||||
|
Feature #2946: Editor: add script line number in results of search
|
||||||
|
Feature #2963: Editor: Mouse button bindings in 3D scene
|
||||||
|
Feature #2983: Sun Glare fader
|
||||||
|
Feature #2999: Scaling of journal and books
|
||||||
|
Task #2665: Support building with Qt5
|
||||||
|
Task #2725: Editor: Remove Display_YesNo
|
||||||
|
Task #2730: Replace hardcoded column numbers in SimpleDialogueSubView/DialogueSubView
|
||||||
|
Task #2750: Bullet shape instancing optimization
|
||||||
|
Task #2793: Replace grid size setting with half grid size setting
|
||||||
|
Task #3003: Support FFMPEG 2.9 (Debian request)
|
||||||
|
|
||||||
0.36.1
|
0.36.1
|
||||||
------
|
------
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ echo "yes" | sudo apt-add-repository ppa:boost-latest/ppa
|
||||||
sudo apt-get update -qq
|
sudo apt-get update -qq
|
||||||
sudo apt-get install -qq libgtest-dev google-mock
|
sudo apt-get install -qq libgtest-dev google-mock
|
||||||
sudo apt-get install -qq libboost-filesystem1.55-dev libboost-program-options1.55-dev libboost-system1.55-dev libboost-thread1.55-dev
|
sudo apt-get install -qq libboost-filesystem1.55-dev libboost-program-options1.55-dev libboost-system1.55-dev libboost-thread1.55-dev
|
||||||
sudo apt-get install -qq libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavresample-dev
|
sudo apt-get install -qq ffmpeg libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev
|
||||||
sudo apt-get install -qq libbullet-dev libopenscenegraph-dev libmygui-dev libsdl2-dev libunshield-dev libtinyxml-dev libopenal-dev libqt4-dev
|
sudo apt-get install -qq libbullet-dev libopenscenegraph-dev libmygui-dev libsdl2-dev libunshield-dev libtinyxml-dev libopenal-dev libqt4-dev
|
||||||
sudo apt-get install -qq cmake-data #workaround for broken osgqt cmake script in ubuntu 12.04
|
sudo apt-get install -qq cmake-data #workaround for broken osgqt cmake script in ubuntu 12.04
|
||||||
if [ "${ANALYZE}" ]; then sudo apt-get install -qq clang-3.6; fi
|
if [ "${ANALYZE}" ]; then sudo apt-get install -qq clang-3.6; fi
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
OUTPUT=$(grep -nRP '\t' --include=\*.{cpp,hpp,c,h} apps components)
|
OUTPUT=$(grep -nRP '\t' --include=\*.{cpp,hpp,c,h} --exclude=ui_\* apps components)
|
||||||
|
|
||||||
if [[ $OUTPUT ]] ; then
|
if [[ $OUTPUT ]] ; then
|
||||||
echo "Error: Tab characters found!"
|
echo "Error: Tab characters found!"
|
||||||
|
|
167
CMakeLists.txt
167
CMakeLists.txt
|
@ -3,8 +3,9 @@ project(OpenMW)
|
||||||
# If the user doesn't supply a CMAKE_BUILD_TYPE via command line, choose one for them.
|
# If the user doesn't supply a CMAKE_BUILD_TYPE via command line, choose one for them.
|
||||||
IF(NOT CMAKE_BUILD_TYPE)
|
IF(NOT CMAKE_BUILD_TYPE)
|
||||||
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
|
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
|
||||||
"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel."
|
"Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel."
|
||||||
FORCE)
|
FORCE)
|
||||||
|
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS None Debug Release RelWithDebInfo MinSizeRel)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
|
@ -15,12 +16,17 @@ endif (APPLE)
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
|
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
|
||||||
|
|
||||||
|
if (ANDROID)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH ${OPENMW_DEPENDENCIES_DIR} "${CMAKE_FIND_ROOT_PATH}")
|
||||||
|
set (OSG_PLUGINS_DIR CACHE STRING "")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Version
|
# Version
|
||||||
message(STATUS "Configuring OpenMW...")
|
message(STATUS "Configuring OpenMW...")
|
||||||
|
|
||||||
set(OPENMW_VERSION_MAJOR 0)
|
set(OPENMW_VERSION_MAJOR 0)
|
||||||
set(OPENMW_VERSION_MINOR 36)
|
set(OPENMW_VERSION_MINOR 37)
|
||||||
set(OPENMW_VERSION_RELEASE 1)
|
set(OPENMW_VERSION_RELEASE 0)
|
||||||
|
|
||||||
set(OPENMW_VERSION_COMMITHASH "")
|
set(OPENMW_VERSION_COMMITHASH "")
|
||||||
set(OPENMW_VERSION_TAGHASH "")
|
set(OPENMW_VERSION_TAGHASH "")
|
||||||
|
@ -45,10 +51,6 @@ endif(EXISTS ${PROJECT_SOURCE_DIR}/.git)
|
||||||
# Macros
|
# Macros
|
||||||
include(OpenMWMacros)
|
include(OpenMWMacros)
|
||||||
|
|
||||||
if (ANDROID)
|
|
||||||
set(CMAKE_FIND_ROOT_PATH ${OPENMW_DEPENDENCIES_DIR} "${CMAKE_FIND_ROOT_PATH}")
|
|
||||||
endif (ANDROID)
|
|
||||||
|
|
||||||
# doxygen main page
|
# doxygen main page
|
||||||
|
|
||||||
configure_file ("${OpenMW_SOURCE_DIR}/docs/mainpage.hpp.cmake" "${OpenMW_BINARY_DIR}/docs/mainpage.hpp")
|
configure_file ("${OpenMW_SOURCE_DIR}/docs/mainpage.hpp.cmake" "${OpenMW_BINARY_DIR}/docs/mainpage.hpp")
|
||||||
|
@ -83,13 +85,28 @@ if (MSVC)
|
||||||
option(OPENMW_LTO_BUILD "Build OpenMW with Link-Time Optimization (Needs ~2GB of RAM)" OFF)
|
option(OPENMW_LTO_BUILD "Build OpenMW with Link-Time Optimization (Needs ~2GB of RAM)" OFF)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Location of morrowind data files
|
# Set up common paths
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
set(MORROWIND_DATA_FILES "./data" CACHE PATH "location of Morrowind data files")
|
set(MORROWIND_DATA_FILES "./data" CACHE PATH "location of Morrowind data files")
|
||||||
set(OPENMW_RESOURCE_FILES "./resources" CACHE PATH "location of OpenMW resources files")
|
set(OPENMW_RESOURCE_FILES "./resources" CACHE PATH "location of OpenMW resources files")
|
||||||
elseif(UNIX)
|
elseif(UNIX)
|
||||||
set(MORROWIND_DATA_FILES "${CMAKE_INSTALL_PREFIX}/share/games/openmw/data/" CACHE PATH "location of Morrowind data files")
|
# Paths
|
||||||
set(OPENMW_RESOURCE_FILES "${CMAKE_INSTALL_PREFIX}/share/games/openmw/resources/" CACHE PATH "location of OpenMW resources files")
|
SET(BINDIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Where to install binaries")
|
||||||
|
SET(LIBDIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE PATH "Where to install libraries")
|
||||||
|
SET(DATAROOTDIR "${CMAKE_INSTALL_PREFIX}/share" CACHE PATH "Sets the root of data directories to a non-default location")
|
||||||
|
SET(GLOBAL_DATA_PATH "${DATAROOTDIR}/games/" CACHE PATH "Set data path prefix")
|
||||||
|
SET(DATADIR "${GLOBAL_DATA_PATH}/openmw" CACHE PATH "Sets the openmw data directories to a non-default location")
|
||||||
|
SET(ICONDIR "${DATAROOTDIR}/pixmaps" CACHE PATH "Set icon dir")
|
||||||
|
SET(LICDIR "${DATAROOTDIR}/licenses/openmw" CACHE PATH "Sets the openmw license directory to a non-default location.")
|
||||||
|
IF("${CMAKE_INSTALL_PREFIX}" STREQUAL "/usr")
|
||||||
|
SET(GLOBAL_CONFIG_PATH "/etc/" CACHE PATH "Set config dir prefix")
|
||||||
|
ELSE()
|
||||||
|
SET(GLOBAL_CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/etc/" CACHE PATH "Set config dir prefix")
|
||||||
|
ENDIF()
|
||||||
|
SET(SYSCONFDIR "${GLOBAL_CONFIG_PATH}/openmw" CACHE PATH "Set config dir")
|
||||||
|
|
||||||
|
set(MORROWIND_DATA_FILES "${DATADIR}/data" CACHE PATH "location of Morrowind data files")
|
||||||
|
set(OPENMW_RESOURCE_FILES "${DATADIR}/resources" CACHE PATH "location of OpenMW resources files")
|
||||||
else()
|
else()
|
||||||
set(MORROWIND_DATA_FILES "data" CACHE PATH "location of Morrowind data files")
|
set(MORROWIND_DATA_FILES "data" CACHE PATH "location of Morrowind data files")
|
||||||
set(OPENMW_RESOURCE_FILES "resources" CACHE PATH "location of OpenMW resources files")
|
set(OPENMW_RESOURCE_FILES "resources" CACHE PATH "location of OpenMW resources files")
|
||||||
|
@ -107,27 +124,14 @@ unset(FFMPEG_LIBRARIES CACHE)
|
||||||
|
|
||||||
find_package(FFmpeg REQUIRED)
|
find_package(FFmpeg REQUIRED)
|
||||||
|
|
||||||
set (FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${SWSCALE_LIBRARY})
|
set (FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${SWSCALE_LIBRARY} ${SWRESAMPLE_LIBRARIES})
|
||||||
|
|
||||||
if ( NOT AVCODEC_FOUND OR NOT AVFORMAT_FOUND OR NOT AVUTIL_FOUND OR NOT SWSCALE_FOUND )
|
if ( NOT AVCODEC_FOUND OR NOT AVFORMAT_FOUND OR NOT AVUTIL_FOUND OR NOT SWSCALE_FOUND OR NOT SWRESAMPLE_FOUND)
|
||||||
message(FATAL_ERROR "FFmpeg component required, but not found!")
|
message(FATAL_ERROR "FFmpeg component required, but not found!")
|
||||||
endif()
|
endif()
|
||||||
set(SOUND_INPUT_INCLUDES ${FFMPEG_INCLUDE_DIRS})
|
|
||||||
if( SWRESAMPLE_FOUND )
|
|
||||||
add_definitions(-DHAVE_LIBSWRESAMPLE)
|
|
||||||
set (FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${SWRESAMPLE_LIBRARIES})
|
|
||||||
else()
|
|
||||||
if( AVRESAMPLE_FOUND )
|
|
||||||
set (FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${AVRESAMPLE_LIBRARIES})
|
|
||||||
else()
|
|
||||||
message(FATAL_ERROR "Install either libswresample (FFmpeg) or libavresample (Libav).")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
# Required for building the FFmpeg headers
|
# Required for building the FFmpeg headers
|
||||||
add_definitions(-D__STDC_CONSTANT_MACROS)
|
add_definitions(-D__STDC_CONSTANT_MACROS)
|
||||||
|
|
||||||
set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES})
|
|
||||||
|
|
||||||
# TinyXML
|
# TinyXML
|
||||||
option(USE_SYSTEM_TINYXML "Use system TinyXML library instead of internal." OFF)
|
option(USE_SYSTEM_TINYXML "Use system TinyXML library instead of internal." OFF)
|
||||||
if(USE_SYSTEM_TINYXML)
|
if(USE_SYSTEM_TINYXML)
|
||||||
|
@ -157,20 +161,38 @@ if (WIN32)
|
||||||
add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN)
|
add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Dependencies
|
if (ANDROID)
|
||||||
|
set(OPENGL_ES TRUE CACHE BOOL "enable opengl es support for android" FORCE)
|
||||||
|
endif (ANDROID)
|
||||||
|
|
||||||
set(DESIRED_QT_VERSION 4 CACHE STRING "The QT version OpenMW should use (4 or 5)")
|
option(OPENGL_ES "enable opengl es support" FALSE )
|
||||||
message(STATUS "Using Qt${DESIRED_QT_VERSION}")
|
|
||||||
|
|
||||||
if (DESIRED_QT_VERSION MATCHES 4)
|
if (OPENGL_ES)
|
||||||
find_package(Qt4 REQUIRED COMPONENTS QtCore QtGui QtNetwork QtOpenGL)
|
add_definitions(-DOPENGL_ES)
|
||||||
|
endif(OPENGL_ES)
|
||||||
|
|
||||||
|
if (NOT BUILD_LAUNCHER AND NOT BUILD_OPENCS AND NOT BUILD_WIZARD)
|
||||||
|
set(USE_QT FALSE)
|
||||||
else()
|
else()
|
||||||
find_package(Qt5Widgets REQUIRED)
|
set(USE_QT TRUE)
|
||||||
find_package(Qt5Core REQUIRED)
|
endif()
|
||||||
find_package(Qt5Network REQUIRED)
|
|
||||||
find_package(Qt5OpenGL REQUIRED)
|
# Dependencies
|
||||||
|
if (USE_QT)
|
||||||
|
set(DESIRED_QT_VERSION 4 CACHE STRING "The QT version OpenMW should use (4 or 5)")
|
||||||
|
set_property(CACHE DESIRED_QT_VERSION PROPERTY STRINGS 4 5)
|
||||||
|
message(STATUS "Using Qt${DESIRED_QT_VERSION}")
|
||||||
|
|
||||||
|
if (DESIRED_QT_VERSION MATCHES 4)
|
||||||
|
find_package(Qt4 REQUIRED COMPONENTS QtCore QtGui QtNetwork QtOpenGL)
|
||||||
|
else()
|
||||||
|
find_package(Qt5Widgets REQUIRED)
|
||||||
|
find_package(Qt5Core REQUIRED)
|
||||||
|
find_package(Qt5Network REQUIRED)
|
||||||
|
find_package(Qt5OpenGL REQUIRED)
|
||||||
# Instruct CMake to run moc automatically when needed.
|
# Instruct CMake to run moc automatically when needed.
|
||||||
#set(CMAKE_AUTOMOC ON)
|
#set(CMAKE_AUTOMOC ON)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Fix for not visible pthreads functions for linker with glibc 2.15
|
# Fix for not visible pthreads functions for linker with glibc 2.15
|
||||||
|
@ -202,7 +224,12 @@ IF(BOOST_STATIC)
|
||||||
set(Boost_USE_STATIC_LIBS ON)
|
set(Boost_USE_STATIC_LIBS ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(OpenSceneGraph 3.2.0 REQUIRED osgDB osgViewer osgText osgGA osgAnimation osgParticle osgQt osgUtil osgFX)
|
if (USE_QT)
|
||||||
|
set (OSG_QT osgQt)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(OpenSceneGraph 3.2.0 REQUIRED osgDB osgViewer osgText osgGA osgAnimation osgParticle ${OSG_QT} osgUtil osgFX)
|
||||||
|
|
||||||
include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS})
|
include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS})
|
||||||
|
|
||||||
if(OSG_STATIC)
|
if(OSG_STATIC)
|
||||||
|
@ -308,8 +335,7 @@ if (APPLE)
|
||||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${APP_BUNDLE_DIR}/Contents/MacOS")
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${APP_BUNDLE_DIR}/Contents/MacOS")
|
||||||
|
|
||||||
if (OPENMW_OSX_DEPLOYMENT)
|
if (OPENMW_OSX_DEPLOYMENT)
|
||||||
SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
|
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||||
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
|
|
||||||
endif()
|
endif()
|
||||||
else (APPLE)
|
else (APPLE)
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${OpenMW_BINARY_DIR}")
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${OpenMW_BINARY_DIR}")
|
||||||
|
@ -327,8 +353,8 @@ configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
|
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
|
||||||
"${OpenMW_BINARY_DIR}/openmw.cfg.install")
|
"${OpenMW_BINARY_DIR}/openmw.cfg.install")
|
||||||
|
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/opencs.ini
|
configure_file(${OpenMW_SOURCE_DIR}/files/openmw-cs.cfg
|
||||||
"${OpenMW_BINARY_DIR}/opencs.ini")
|
"${OpenMW_BINARY_DIR}/openmw-cs.cfg")
|
||||||
|
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/opencs/defaultfilters
|
configure_file(${OpenMW_SOURCE_DIR}/files/opencs/defaultfilters
|
||||||
"${OpenMW_BINARY_DIR}/resources/defaultfilters" COPYONLY)
|
"${OpenMW_BINARY_DIR}/resources/defaultfilters" COPYONLY)
|
||||||
|
@ -375,21 +401,7 @@ elseif (MSVC)
|
||||||
endif (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
endif (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
||||||
|
|
||||||
IF(NOT WIN32 AND NOT APPLE)
|
IF(NOT WIN32 AND NOT APPLE)
|
||||||
# Linux building
|
# Linux installation
|
||||||
# Paths
|
|
||||||
SET(BINDIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Where to install binaries")
|
|
||||||
SET(LIBDIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE PATH "Where to install libraries")
|
|
||||||
SET(DATAROOTDIR "${CMAKE_INSTALL_PREFIX}/share" CACHE PATH "Sets the root of data directories to a non-default location")
|
|
||||||
SET(GLOBAL_DATA_PATH "${DATAROOTDIR}/games/" CACHE PATH "Set data path prefix")
|
|
||||||
SET(DATADIR "${GLOBAL_DATA_PATH}/openmw" CACHE PATH "Sets the openmw data directories to a non-default location")
|
|
||||||
SET(ICONDIR "${DATAROOTDIR}/pixmaps" CACHE PATH "Set icon dir")
|
|
||||||
SET(LICDIR "${DATAROOTDIR}/licenses/openmw" CACHE PATH "Sets the openmw license directory to a non-default location.")
|
|
||||||
IF("${CMAKE_INSTALL_PREFIX}" STREQUAL "/usr")
|
|
||||||
SET(GLOBAL_CONFIG_PATH "/etc/" CACHE PATH "Set config dir prefix")
|
|
||||||
ELSE()
|
|
||||||
SET(GLOBAL_CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/etc/" CACHE PATH "Set config dir prefix")
|
|
||||||
ENDIF()
|
|
||||||
SET(SYSCONFDIR "${GLOBAL_CONFIG_PATH}/openmw" CACHE PATH "Set config dir")
|
|
||||||
|
|
||||||
# Install binaries
|
# Install binaries
|
||||||
IF(BUILD_OPENMW)
|
IF(BUILD_OPENMW)
|
||||||
|
@ -442,7 +454,7 @@ IF(NOT WIN32 AND NOT APPLE)
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
|
||||||
|
|
||||||
IF(BUILD_OPENCS)
|
IF(BUILD_OPENCS)
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.ini" DESTINATION "${SYSCONFDIR}" COMPONENT "opencs")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw-cs.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "opencs")
|
||||||
ENDIF(BUILD_OPENCS)
|
ENDIF(BUILD_OPENCS)
|
||||||
|
|
||||||
# Install resources
|
# Install resources
|
||||||
|
@ -475,7 +487,7 @@ if(WIN32)
|
||||||
ENDIF(BUILD_ESSIMPORTER)
|
ENDIF(BUILD_ESSIMPORTER)
|
||||||
IF(BUILD_OPENCS)
|
IF(BUILD_OPENCS)
|
||||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-cs.exe" DESTINATION ".")
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-cs.exe" DESTINATION ".")
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.ini" DESTINATION ".")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw-cs.cfg" DESTINATION ".")
|
||||||
ENDIF(BUILD_OPENCS)
|
ENDIF(BUILD_OPENCS)
|
||||||
IF(BUILD_WIZARD)
|
IF(BUILD_WIZARD)
|
||||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-wizard.exe" DESTINATION ".")
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-wizard.exe" DESTINATION ".")
|
||||||
|
@ -721,6 +733,18 @@ endif()
|
||||||
|
|
||||||
# Apple bundling
|
# Apple bundling
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
|
get_property(QT_COCOA_PLUGIN_PATH TARGET Qt5::QCocoaIntegrationPlugin PROPERTY LOCATION_RELEASE)
|
||||||
|
get_filename_component(QT_COCOA_PLUGIN_DIR "${QT_COCOA_PLUGIN_PATH}" DIRECTORY)
|
||||||
|
get_filename_component(QT_COCOA_PLUGIN_GROUP "${QT_COCOA_PLUGIN_DIR}" NAME)
|
||||||
|
get_filename_component(QT_COCOA_PLUGIN_NAME "${QT_COCOA_PLUGIN_PATH}" NAME)
|
||||||
|
configure_file("${QT_COCOA_PLUGIN_PATH}" "${APP_BUNDLE_DIR}/Contents/MacOS/${QT_COCOA_PLUGIN_GROUP}/${QT_COCOA_PLUGIN_NAME}" COPYONLY)
|
||||||
|
|
||||||
|
if (BUILD_OPENCS)
|
||||||
|
get_property(OPENCS_BUNDLE_NAME_TMP TARGET openmw-cs PROPERTY OUTPUT_NAME)
|
||||||
|
set(OPENCS_BUNDLE_NAME "${OPENCS_BUNDLE_NAME_TMP}.app")
|
||||||
|
configure_file("${QT_COCOA_PLUGIN_PATH}" "${OPENCS_BUNDLE_NAME}/Contents/MacOS/${QT_COCOA_PLUGIN_GROUP}/${QT_COCOA_PLUGIN_NAME}" COPYONLY)
|
||||||
|
endif ()
|
||||||
|
|
||||||
set(INSTALL_SUBDIR OpenMW)
|
set(INSTALL_SUBDIR OpenMW)
|
||||||
|
|
||||||
install(DIRECTORY "${APP_BUNDLE_DIR}" USE_SOURCE_PERMISSIONS DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
install(DIRECTORY "${APP_BUNDLE_DIR}" USE_SOURCE_PERMISSIONS DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
|
@ -728,7 +752,7 @@ if (APPLE)
|
||||||
install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
install(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
install(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
install(FILES "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
install(FILES "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
install(FILES "${OpenMW_BINARY_DIR}/opencs.ini" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
install(FILES "${OpenMW_BINARY_DIR}/openmw-cs.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
|
|
||||||
set(CPACK_GENERATOR "DragNDrop")
|
set(CPACK_GENERATOR "DragNDrop")
|
||||||
set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
|
set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
|
||||||
|
@ -736,22 +760,22 @@ if (APPLE)
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINOR})
|
set(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINOR})
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE})
|
set(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE})
|
||||||
|
|
||||||
set(OPENMW_APP "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}")
|
set(INSTALLED_OPENMW_APP "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}")
|
||||||
|
set(INSTALLED_OPENCS_APP "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${OPENCS_BUNDLE_NAME}")
|
||||||
set(OPENCS_BUNDLE_NAME "OpenMW-CS.app")
|
|
||||||
set(OPENCS_APP "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${OPENCS_BUNDLE_NAME}")
|
|
||||||
|
|
||||||
install(CODE "
|
install(CODE "
|
||||||
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
|
||||||
include(BundleUtilitiesWithRPath)
|
include(BundleUtilities)
|
||||||
|
cmake_minimum_required(VERSION 3.1)
|
||||||
" COMPONENT Runtime)
|
" COMPONENT Runtime)
|
||||||
|
|
||||||
set(ABSOLUTE_PLUGINS "")
|
set(ABSOLUTE_PLUGINS "")
|
||||||
set(USED_OSG_PLUGINS
|
set(USED_OSG_PLUGINS
|
||||||
osgdb_tga
|
|
||||||
osgdb_dds
|
osgdb_dds
|
||||||
osgdb_imageio
|
osgdb_jpeg
|
||||||
|
osgdb_png
|
||||||
|
osgdb_tga
|
||||||
)
|
)
|
||||||
|
|
||||||
foreach (PLUGIN_NAME ${USED_OSG_PLUGINS})
|
foreach (PLUGIN_NAME ${USED_OSG_PLUGINS})
|
||||||
|
@ -759,12 +783,12 @@ if (APPLE)
|
||||||
set(ABSOLUTE_PLUGINS ${PLUGIN_ABS} ${ABSOLUTE_PLUGINS})
|
set(ABSOLUTE_PLUGINS ${PLUGIN_ABS} ${ABSOLUTE_PLUGINS})
|
||||||
endforeach ()
|
endforeach ()
|
||||||
|
|
||||||
get_filename_component(PLUGIN_PREFIX_DIR "${OSG_PLUGIN_LIB_SEARCH_PATH}" NAME)
|
get_filename_component(OSG_PLUGIN_PREFIX_DIR "${OSG_PLUGIN_LIB_SEARCH_PATH}" NAME)
|
||||||
|
|
||||||
# installs used plugins in bundle at given path (bundle_path must be relative to ${CMAKE_INSTALL_PREFIX})
|
# installs used plugins in bundle at given path (bundle_path must be relative to ${CMAKE_INSTALL_PREFIX})
|
||||||
# and returns list of install paths for all installed plugins
|
# and returns list of install paths for all installed plugins
|
||||||
function (install_plugins_for_bundle bundle_path plugins_var)
|
function (install_plugins_for_bundle bundle_path plugins_var)
|
||||||
set(RELATIVE_PLUGIN_INSTALL_BASE "${bundle_path}/Contents/PlugIns/${PLUGIN_PREFIX_DIR}")
|
set(RELATIVE_PLUGIN_INSTALL_BASE "${bundle_path}/Contents/PlugIns/${OSG_PLUGIN_PREFIX_DIR}")
|
||||||
|
|
||||||
set(PLUGINS "")
|
set(PLUGINS "")
|
||||||
set(PLUGIN_INSTALL_BASE "\${CMAKE_INSTALL_PREFIX}/${RELATIVE_PLUGIN_INSTALL_BASE}")
|
set(PLUGIN_INSTALL_BASE "\${CMAKE_INSTALL_PREFIX}/${RELATIVE_PLUGIN_INSTALL_BASE}")
|
||||||
|
@ -787,19 +811,20 @@ if (APPLE)
|
||||||
install_plugins_for_bundle("${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}" PLUGINS)
|
install_plugins_for_bundle("${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}" PLUGINS)
|
||||||
install_plugins_for_bundle("${INSTALL_SUBDIR}/${OPENCS_BUNDLE_NAME}" OPENCS_PLUGINS)
|
install_plugins_for_bundle("${INSTALL_SUBDIR}/${OPENCS_BUNDLE_NAME}" OPENCS_PLUGINS)
|
||||||
|
|
||||||
set(DIRS "${CMAKE_PREFIX_PATH}/lib")
|
set(PLUGINS ${PLUGINS} "${INSTALLED_OPENMW_APP}/Contents/MacOS/${QT_COCOA_PLUGIN_GROUP}/${QT_COCOA_PLUGIN_NAME}")
|
||||||
|
set(OPENCS_PLUGINS ${OPENCS_PLUGINS} "${INSTALLED_OPENCS_APP}/Contents/MacOS/${QT_COCOA_PLUGIN_GROUP}/${QT_COCOA_PLUGIN_NAME}")
|
||||||
|
|
||||||
install(CODE "
|
install(CODE "
|
||||||
function(gp_item_default_embedded_path_override item default_embedded_path_var)
|
function(gp_item_default_embedded_path_override item default_embedded_path_var)
|
||||||
if (\${item} MATCHES ${PLUGIN_PREFIX_DIR})
|
if (\${item} MATCHES ${OSG_PLUGIN_PREFIX_DIR})
|
||||||
set(path \"@executable_path/../PlugIns/${PLUGIN_PREFIX_DIR}\")
|
set(path \"@executable_path/../PlugIns/${OSG_PLUGIN_PREFIX_DIR}\")
|
||||||
set(\${default_embedded_path_var} \"\${path}\" PARENT_SCOPE)
|
set(\${default_embedded_path_var} \"\${path}\" PARENT_SCOPE)
|
||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
cmake_policy(SET CMP0009 OLD)
|
cmake_policy(SET CMP0009 OLD)
|
||||||
fixup_bundle(\"${OPENMW_APP}\" \"${PLUGINS}\" \"${DIRS}\")
|
fixup_bundle(\"${INSTALLED_OPENMW_APP}\" \"${PLUGINS}\" \"\")
|
||||||
fixup_bundle(\"${OPENCS_APP}\" \"${OPENCS_PLUGINS}\" \"${DIRS}\")
|
fixup_bundle(\"${INSTALLED_OPENCS_APP}\" \"${OPENCS_PLUGINS}\" \"\")
|
||||||
" COMPONENT Runtime)
|
" COMPONENT Runtime)
|
||||||
include(CPack)
|
include(CPack)
|
||||||
endif (APPLE)
|
endif (APPLE)
|
||||||
|
|
|
@ -7,7 +7,7 @@ OpenMW is a recreation of the engine for the popular role-playing game Morrowind
|
||||||
|
|
||||||
OpenMW also comes with OpenMW-CS, a replacement for Morrowind's TES Construction Set.
|
OpenMW also comes with OpenMW-CS, a replacement for Morrowind's TES Construction Set.
|
||||||
|
|
||||||
* Version: 0.36.1
|
* Version: 0.37.0
|
||||||
* License: GPL (see docs/license/GPL3.txt for more information)
|
* License: GPL (see docs/license/GPL3.txt for more information)
|
||||||
* Website: http://www.openmw.org
|
* Website: http://www.openmw.org
|
||||||
* IRC: #openmw on irc.freenode.net
|
* IRC: #openmw on irc.freenode.net
|
||||||
|
|
|
@ -27,7 +27,8 @@ struct ESMData
|
||||||
std::vector<ESM::Header::MasterData> masters;
|
std::vector<ESM::Header::MasterData> masters;
|
||||||
|
|
||||||
std::deque<EsmTool::RecordBase *> mRecords;
|
std::deque<EsmTool::RecordBase *> mRecords;
|
||||||
std::map<ESM::Cell *, std::deque<ESM::CellRef> > mCellRefs;
|
// Value: (Reference, Deleted flag)
|
||||||
|
std::map<ESM::Cell *, std::deque<std::pair<ESM::CellRef, bool> > > mCellRefs;
|
||||||
std::map<int, int> mRecordStats;
|
std::map<int, int> mRecordStats;
|
||||||
|
|
||||||
static const std::set<int> sLabeledRec;
|
static const std::set<int> sLabeledRec;
|
||||||
|
@ -255,7 +256,7 @@ void loadCell(ESM::Cell &cell, ESM::ESMReader &esm, Arguments& info)
|
||||||
while(cell.getNextRef(esm, ref, deleted))
|
while(cell.getNextRef(esm, ref, deleted))
|
||||||
{
|
{
|
||||||
if (save) {
|
if (save) {
|
||||||
info.data.mCellRefs[&cell].push_back(ref);
|
info.data.mCellRefs[&cell].push_back(std::make_pair(ref, deleted));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(quiet) continue;
|
if(quiet) continue;
|
||||||
|
@ -352,30 +353,9 @@ int load(Arguments& info)
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
esm.getRecHeader(flags);
|
esm.getRecHeader(flags);
|
||||||
|
|
||||||
// Is the user interested in this record type?
|
|
||||||
bool interested = true;
|
|
||||||
if (!info.types.empty())
|
|
||||||
{
|
|
||||||
std::vector<std::string>::iterator match;
|
|
||||||
match = std::find(info.types.begin(), info.types.end(),
|
|
||||||
n.toString());
|
|
||||||
if (match == info.types.end()) interested = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string id = esm.getHNOString("NAME");
|
|
||||||
if (id.empty())
|
|
||||||
id = esm.getHNOString("INAM");
|
|
||||||
|
|
||||||
if (!info.name.empty() && !Misc::StringUtils::ciEqual(info.name, id))
|
|
||||||
interested = false;
|
|
||||||
|
|
||||||
if(!quiet && interested)
|
|
||||||
std::cout << "\nRecord: " << n.toString()
|
|
||||||
<< " '" << id << "'\n";
|
|
||||||
|
|
||||||
EsmTool::RecordBase *record = EsmTool::RecordBase::create(n);
|
EsmTool::RecordBase *record = EsmTool::RecordBase::create(n);
|
||||||
|
if (record == 0)
|
||||||
if (record == 0) {
|
{
|
||||||
if (std::find(skipped.begin(), skipped.end(), n.val) == skipped.end())
|
if (std::find(skipped.begin(), skipped.end(), n.val) == skipped.end())
|
||||||
{
|
{
|
||||||
std::cout << "Skipping " << n.toString() << " records." << std::endl;
|
std::cout << "Skipping " << n.toString() << " records." << std::endl;
|
||||||
|
@ -385,28 +365,46 @@ int load(Arguments& info)
|
||||||
esm.skipRecord();
|
esm.skipRecord();
|
||||||
if (quiet) break;
|
if (quiet) break;
|
||||||
std::cout << " Skipping\n";
|
std::cout << " Skipping\n";
|
||||||
} else {
|
|
||||||
if (record->getType().val == ESM::REC_GMST) {
|
|
||||||
// preset id for GameSetting record
|
|
||||||
record->cast<ESM::GameSetting>()->get().mId = id;
|
|
||||||
}
|
|
||||||
record->setId(id);
|
|
||||||
record->setFlags((int) flags);
|
|
||||||
record->setPrintPlain(info.plain_given);
|
|
||||||
record->load(esm);
|
|
||||||
if (!quiet && interested) record->print();
|
|
||||||
|
|
||||||
if (record->getType().val == ESM::REC_CELL && loadCells && interested) {
|
continue;
|
||||||
loadCell(record->cast<ESM::Cell>()->get(), esm, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (save) {
|
|
||||||
info.data.mRecords.push_back(record);
|
|
||||||
} else {
|
|
||||||
delete record;
|
|
||||||
}
|
|
||||||
++info.data.mRecordStats[n.val];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
record->setFlags(static_cast<int>(flags));
|
||||||
|
record->setPrintPlain(info.plain_given);
|
||||||
|
record->load(esm);
|
||||||
|
|
||||||
|
// Is the user interested in this record type?
|
||||||
|
bool interested = true;
|
||||||
|
if (!info.types.empty())
|
||||||
|
{
|
||||||
|
std::vector<std::string>::iterator match;
|
||||||
|
match = std::find(info.types.begin(), info.types.end(), n.toString());
|
||||||
|
if (match == info.types.end()) interested = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!info.name.empty() && !Misc::StringUtils::ciEqual(info.name, record->getId()))
|
||||||
|
interested = false;
|
||||||
|
|
||||||
|
if(!quiet && interested)
|
||||||
|
{
|
||||||
|
std::cout << "\nRecord: " << n.toString() << " '" << record->getId() << "'\n";
|
||||||
|
record->print();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (record->getType().val == ESM::REC_CELL && loadCells && interested)
|
||||||
|
{
|
||||||
|
loadCell(record->cast<ESM::Cell>()->get(), esm, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (save)
|
||||||
|
{
|
||||||
|
info.data.mRecords.push_back(record);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete record;
|
||||||
|
}
|
||||||
|
++info.data.mRecordStats[n.val];
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch(std::exception &e) {
|
} catch(std::exception &e) {
|
||||||
|
@ -493,28 +491,19 @@ int clone(Arguments& info)
|
||||||
for (Records::iterator it = records.begin(); it != records.end() && i > 0; ++it)
|
for (Records::iterator it = records.begin(); it != records.end() && i > 0; ++it)
|
||||||
{
|
{
|
||||||
EsmTool::RecordBase *record = *it;
|
EsmTool::RecordBase *record = *it;
|
||||||
|
|
||||||
name.val = record->getType().val;
|
name.val = record->getType().val;
|
||||||
|
|
||||||
esm.startRecord(name.toString(), record->getFlags());
|
esm.startRecord(name.toString(), record->getFlags());
|
||||||
|
|
||||||
// TODO wrap this with std::set
|
|
||||||
if (ESMData::sLabeledRec.count(name.val) > 0) {
|
|
||||||
esm.writeHNCString("NAME", record->getId());
|
|
||||||
} else {
|
|
||||||
esm.writeHNOString("NAME", record->getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
record->save(esm);
|
record->save(esm);
|
||||||
|
|
||||||
if (name.val == ESM::REC_CELL) {
|
if (name.val == ESM::REC_CELL) {
|
||||||
ESM::Cell *ptr = &record->cast<ESM::Cell>()->get();
|
ESM::Cell *ptr = &record->cast<ESM::Cell>()->get();
|
||||||
if (!info.data.mCellRefs[ptr].empty()) {
|
if (!info.data.mCellRefs[ptr].empty()) {
|
||||||
typedef std::deque<ESM::CellRef> RefList;
|
typedef std::deque<std::pair<ESM::CellRef, bool> > RefList;
|
||||||
RefList &refs = info.data.mCellRefs[ptr];
|
RefList &refs = info.data.mCellRefs[ptr];
|
||||||
for (RefList::iterator refIt = refs.begin(); refIt != refs.end(); ++refIt)
|
for (RefList::iterator refIt = refs.begin(); refIt != refs.end(); ++refIt)
|
||||||
{
|
{
|
||||||
refIt->save(esm);
|
refIt->first.save(esm, refIt->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -405,6 +405,7 @@ void Record<ESM::Activator>::print()
|
||||||
std::cout << " Name: " << mData.mName << std::endl;
|
std::cout << " Name: " << mData.mName << std::endl;
|
||||||
std::cout << " Model: " << mData.mModel << std::endl;
|
std::cout << " Model: " << mData.mModel << std::endl;
|
||||||
std::cout << " Script: " << mData.mScript << std::endl;
|
std::cout << " Script: " << mData.mScript << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -419,6 +420,7 @@ void Record<ESM::Potion>::print()
|
||||||
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
||||||
std::cout << " AutoCalc: " << mData.mData.mAutoCalc << std::endl;
|
std::cout << " AutoCalc: " << mData.mData.mAutoCalc << std::endl;
|
||||||
printEffectList(mData.mEffects);
|
printEffectList(mData.mEffects);
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -447,6 +449,7 @@ void Record<ESM::Armor>::print()
|
||||||
if (pit->mFemale != "")
|
if (pit->mFemale != "")
|
||||||
std::cout << " Female Name: " << pit->mFemale << std::endl;
|
std::cout << " Female Name: " << pit->mFemale << std::endl;
|
||||||
}
|
}
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -461,6 +464,7 @@ void Record<ESM::Apparatus>::print()
|
||||||
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
|
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
|
||||||
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
||||||
std::cout << " Quality: " << mData.mData.mQuality << std::endl;
|
std::cout << " Quality: " << mData.mData.mQuality << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -474,6 +478,7 @@ void Record<ESM::BodyPart>::print()
|
||||||
std::cout << " Part: " << meshPartLabel(mData.mData.mPart)
|
std::cout << " Part: " << meshPartLabel(mData.mData.mPart)
|
||||||
<< " (" << (int)mData.mData.mPart << ")" << std::endl;
|
<< " (" << (int)mData.mData.mPart << ")" << std::endl;
|
||||||
std::cout << " Vampire: " << (int)mData.mData.mVampire << std::endl;
|
std::cout << " Vampire: " << (int)mData.mData.mVampire << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -502,6 +507,7 @@ void Record<ESM::Book>::print()
|
||||||
{
|
{
|
||||||
std::cout << " Text: [skipped]" << std::endl;
|
std::cout << " Text: [skipped]" << std::endl;
|
||||||
}
|
}
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -513,6 +519,7 @@ void Record<ESM::BirthSign>::print()
|
||||||
std::vector<std::string>::iterator pit;
|
std::vector<std::string>::iterator pit;
|
||||||
for (pit = mData.mPowers.mList.begin(); pit != mData.mPowers.mList.end(); ++pit)
|
for (pit = mData.mPowers.mList.begin(); pit != mData.mPowers.mList.end(); ++pit)
|
||||||
std::cout << " Power: " << *pit << std::endl;
|
std::cout << " Power: " << *pit << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -541,6 +548,7 @@ void Record<ESM::Cell>::print()
|
||||||
std::cout << " Map Color: " << boost::format("0x%08X") % mData.mMapColor << std::endl;
|
std::cout << " Map Color: " << boost::format("0x%08X") % mData.mMapColor << std::endl;
|
||||||
std::cout << " Water Level Int: " << mData.mWaterInt << std::endl;
|
std::cout << " Water Level Int: " << mData.mWaterInt << std::endl;
|
||||||
std::cout << " RefId counter: " << mData.mRefNumCounter << std::endl;
|
std::cout << " RefId counter: " << mData.mRefNumCounter << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,6 +571,7 @@ void Record<ESM::Class>::print()
|
||||||
for (int i = 0; i != 5; i++)
|
for (int i = 0; i != 5; i++)
|
||||||
std::cout << " Major Skill: " << skillLabel(mData.mData.mSkills[i][1])
|
std::cout << " Major Skill: " << skillLabel(mData.mData.mSkills[i][1])
|
||||||
<< " (" << mData.mData.mSkills[i][1] << ")" << std::endl;
|
<< " (" << mData.mData.mSkills[i][1] << ")" << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -589,6 +598,7 @@ void Record<ESM::Clothing>::print()
|
||||||
if (pit->mFemale != "")
|
if (pit->mFemale != "")
|
||||||
std::cout << " Female Name: " << pit->mFemale << std::endl;
|
std::cout << " Female Name: " << pit->mFemale << std::endl;
|
||||||
}
|
}
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -604,6 +614,7 @@ void Record<ESM::Container>::print()
|
||||||
for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); ++cit)
|
for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); ++cit)
|
||||||
std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount
|
std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount
|
||||||
<< " Item: " << cit->mItem.toString() << std::endl;
|
<< " Item: " << cit->mItem.toString() << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -670,6 +681,7 @@ void Record<ESM::Creature>::print()
|
||||||
std::vector<ESM::AIPackage>::iterator pit;
|
std::vector<ESM::AIPackage>::iterator pit;
|
||||||
for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); ++pit)
|
for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); ++pit)
|
||||||
printAIPackage(*pit);
|
printAIPackage(*pit);
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -677,6 +689,7 @@ void Record<ESM::Dialogue>::print()
|
||||||
{
|
{
|
||||||
std::cout << " Type: " << dialogTypeLabel(mData.mType)
|
std::cout << " Type: " << dialogTypeLabel(mData.mType)
|
||||||
<< " (" << (int)mData.mType << ")" << std::endl;
|
<< " (" << (int)mData.mType << ")" << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
// Sadly, there are no DialInfos, because the loader dumps as it
|
// Sadly, there are no DialInfos, because the loader dumps as it
|
||||||
// loads, rather than loading and then dumping. :-( Anyone mind if
|
// loads, rather than loading and then dumping. :-( Anyone mind if
|
||||||
// I change this?
|
// I change this?
|
||||||
|
@ -693,6 +706,7 @@ void Record<ESM::Door>::print()
|
||||||
std::cout << " Script: " << mData.mScript << std::endl;
|
std::cout << " Script: " << mData.mScript << std::endl;
|
||||||
std::cout << " OpenSound: " << mData.mOpenSound << std::endl;
|
std::cout << " OpenSound: " << mData.mOpenSound << std::endl;
|
||||||
std::cout << " CloseSound: " << mData.mCloseSound << std::endl;
|
std::cout << " CloseSound: " << mData.mCloseSound << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -704,6 +718,7 @@ void Record<ESM::Enchantment>::print()
|
||||||
std::cout << " Charge: " << mData.mData.mCharge << std::endl;
|
std::cout << " Charge: " << mData.mData.mCharge << std::endl;
|
||||||
std::cout << " AutoCalc: " << mData.mData.mAutocalc << std::endl;
|
std::cout << " AutoCalc: " << mData.mData.mAutocalc << std::endl;
|
||||||
printEffectList(mData.mEffects);
|
printEffectList(mData.mEffects);
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -737,12 +752,14 @@ void Record<ESM::Faction>::print()
|
||||||
std::map<std::string, int>::iterator rit;
|
std::map<std::string, int>::iterator rit;
|
||||||
for (rit = mData.mReactions.begin(); rit != mData.mReactions.end(); ++rit)
|
for (rit = mData.mReactions.begin(); rit != mData.mReactions.end(); ++rit)
|
||||||
std::cout << " Reaction: " << rit->second << " = " << rit->first << std::endl;
|
std::cout << " Reaction: " << rit->second << " = " << rit->first << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void Record<ESM::Global>::print()
|
void Record<ESM::Global>::print()
|
||||||
{
|
{
|
||||||
std::cout << " " << mData.mValue << std::endl;
|
std::cout << " " << mData.mValue << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -809,6 +826,7 @@ void Record<ESM::DialInfo>::print()
|
||||||
std::cout << " Result Script: [skipped]" << std::endl;
|
std::cout << " Result Script: [skipped]" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -832,6 +850,7 @@ void Record<ESM::Ingredient>::print()
|
||||||
std::cout << " Attribute: " << attributeLabel(mData.mData.mAttributes[i])
|
std::cout << " Attribute: " << attributeLabel(mData.mData.mAttributes[i])
|
||||||
<< " (" << mData.mData.mAttributes[i] << ")" << std::endl;
|
<< " (" << mData.mData.mAttributes[i] << ")" << std::endl;
|
||||||
}
|
}
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -848,6 +867,8 @@ void Record<ESM::Land>::print()
|
||||||
std::cout << " Unknown1: " << data->mUnk1 << std::endl;
|
std::cout << " Unknown1: " << data->mUnk1 << std::endl;
|
||||||
std::cout << " Unknown2: " << data->mUnk2 << std::endl;
|
std::cout << " Unknown2: " << data->mUnk2 << std::endl;
|
||||||
}
|
}
|
||||||
|
mData.unloadData();
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -860,6 +881,7 @@ void Record<ESM::CreatureLevList>::print()
|
||||||
for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit)
|
for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit)
|
||||||
std::cout << " Creature: Level: " << iit->mLevel
|
std::cout << " Creature: Level: " << iit->mLevel
|
||||||
<< " Creature: " << iit->mId << std::endl;
|
<< " Creature: " << iit->mId << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -872,6 +894,7 @@ void Record<ESM::ItemLevList>::print()
|
||||||
for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit)
|
for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit)
|
||||||
std::cout << " Inventory: Level: " << iit->mLevel
|
std::cout << " Inventory: Level: " << iit->mLevel
|
||||||
<< " Item: " << iit->mId << std::endl;
|
<< " Item: " << iit->mId << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -892,6 +915,7 @@ void Record<ESM::Light>::print()
|
||||||
std::cout << " Duration: " << mData.mData.mTime << std::endl;
|
std::cout << " Duration: " << mData.mData.mTime << std::endl;
|
||||||
std::cout << " Radius: " << mData.mData.mRadius << std::endl;
|
std::cout << " Radius: " << mData.mData.mRadius << std::endl;
|
||||||
std::cout << " Color: " << mData.mData.mColor << std::endl;
|
std::cout << " Color: " << mData.mData.mColor << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -906,6 +930,7 @@ void Record<ESM::Lockpick>::print()
|
||||||
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
||||||
std::cout << " Quality: " << mData.mData.mQuality << std::endl;
|
std::cout << " Quality: " << mData.mData.mQuality << std::endl;
|
||||||
std::cout << " Uses: " << mData.mData.mUses << std::endl;
|
std::cout << " Uses: " << mData.mData.mUses << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -920,6 +945,7 @@ void Record<ESM::Probe>::print()
|
||||||
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
||||||
std::cout << " Quality: " << mData.mData.mQuality << std::endl;
|
std::cout << " Quality: " << mData.mData.mQuality << std::endl;
|
||||||
std::cout << " Uses: " << mData.mData.mUses << std::endl;
|
std::cout << " Uses: " << mData.mData.mUses << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -934,6 +960,7 @@ void Record<ESM::Repair>::print()
|
||||||
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
||||||
std::cout << " Quality: " << mData.mData.mQuality << std::endl;
|
std::cout << " Quality: " << mData.mData.mQuality << std::endl;
|
||||||
std::cout << " Uses: " << mData.mData.mUses << std::endl;
|
std::cout << " Uses: " << mData.mData.mUses << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -942,6 +969,7 @@ void Record<ESM::LandTexture>::print()
|
||||||
std::cout << " Id: " << mData.mId << std::endl;
|
std::cout << " Id: " << mData.mId << std::endl;
|
||||||
std::cout << " Index: " << mData.mIndex << std::endl;
|
std::cout << " Index: " << mData.mIndex << std::endl;
|
||||||
std::cout << " Texture: " << mData.mTexture << std::endl;
|
std::cout << " Texture: " << mData.mTexture << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -992,6 +1020,7 @@ void Record<ESM::Miscellaneous>::print()
|
||||||
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
|
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
|
||||||
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
||||||
std::cout << " Is Key: " << mData.mData.mIsKey << std::endl;
|
std::cout << " Is Key: " << mData.mData.mIsKey << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -1077,6 +1106,8 @@ void Record<ESM::NPC>::print()
|
||||||
std::vector<ESM::AIPackage>::iterator pit;
|
std::vector<ESM::AIPackage>::iterator pit;
|
||||||
for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); ++pit)
|
for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); ++pit)
|
||||||
printAIPackage(*pit);
|
printAIPackage(*pit);
|
||||||
|
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -1111,6 +1142,8 @@ void Record<ESM::Pathgrid>::print()
|
||||||
std::cout << " BAD POINT IN EDGE!" << std::endl;
|
std::cout << " BAD POINT IN EDGE!" << std::endl;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -1151,6 +1184,8 @@ void Record<ESM::Race>::print()
|
||||||
std::vector<std::string>::iterator sit;
|
std::vector<std::string>::iterator sit;
|
||||||
for (sit = mData.mPowers.mList.begin(); sit != mData.mPowers.mList.end(); ++sit)
|
for (sit = mData.mPowers.mList.begin(); sit != mData.mPowers.mList.end(); ++sit)
|
||||||
std::cout << " Power: " << *sit << std::endl;
|
std::cout << " Power: " << *sit << std::endl;
|
||||||
|
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -1210,6 +1245,8 @@ void Record<ESM::Script>::print()
|
||||||
{
|
{
|
||||||
std::cout << " Script: [skipped]" << std::endl;
|
std::cout << " Script: [skipped]" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -1233,6 +1270,7 @@ void Record<ESM::SoundGenerator>::print()
|
||||||
std::cout << " Sound: " << mData.mSound << std::endl;
|
std::cout << " Sound: " << mData.mSound << std::endl;
|
||||||
std::cout << " Type: " << soundTypeLabel(mData.mType)
|
std::cout << " Type: " << soundTypeLabel(mData.mType)
|
||||||
<< " (" << mData.mType << ")" << std::endl;
|
<< " (" << mData.mType << ")" << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -1243,6 +1281,7 @@ void Record<ESM::Sound>::print()
|
||||||
if (mData.mData.mMinRange != 0 && mData.mData.mMaxRange != 0)
|
if (mData.mData.mMinRange != 0 && mData.mData.mMaxRange != 0)
|
||||||
std::cout << " Range: " << (int)mData.mData.mMinRange << " - "
|
std::cout << " Range: " << (int)mData.mData.mMinRange << " - "
|
||||||
<< (int)mData.mData.mMaxRange << std::endl;
|
<< (int)mData.mData.mMaxRange << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -1254,13 +1293,15 @@ void Record<ESM::Spell>::print()
|
||||||
std::cout << " Flags: " << spellFlags(mData.mData.mFlags) << std::endl;
|
std::cout << " Flags: " << spellFlags(mData.mData.mFlags) << std::endl;
|
||||||
std::cout << " Cost: " << mData.mData.mCost << std::endl;
|
std::cout << " Cost: " << mData.mData.mCost << std::endl;
|
||||||
printEffectList(mData.mEffects);
|
printEffectList(mData.mEffects);
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void Record<ESM::StartScript>::print()
|
void Record<ESM::StartScript>::print()
|
||||||
{
|
{
|
||||||
std::cout << "Start Script: " << mData.mId << std::endl;
|
std::cout << " Start Script: " << mData.mId << std::endl;
|
||||||
std::cout << "Start Data: " << mData.mData << std::endl;
|
std::cout << " Start Data: " << mData.mData << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -1301,6 +1342,37 @@ void Record<ESM::Weapon>::print()
|
||||||
if (mData.mData.mThrust[0] != 0 && mData.mData.mThrust[1] != 0)
|
if (mData.mData.mThrust[0] != 0 && mData.mData.mThrust[1] != 0)
|
||||||
std::cout << " Thrust: " << (int)mData.mData.mThrust[0] << "-"
|
std::cout << " Thrust: " << (int)mData.mData.mThrust[0] << "-"
|
||||||
<< (int)mData.mData.mThrust[1] << std::endl;
|
<< (int)mData.mData.mThrust[1] << std::endl;
|
||||||
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
std::string Record<ESM::Cell>::getId() const
|
||||||
|
{
|
||||||
|
return mData.mName;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
std::string Record<ESM::Land>::getId() const
|
||||||
|
{
|
||||||
|
return ""; // No ID for Land record
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
std::string Record<ESM::MagicEffect>::getId() const
|
||||||
|
{
|
||||||
|
return ""; // No ID for MagicEffect record
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
std::string Record<ESM::Pathgrid>::getId() const
|
||||||
|
{
|
||||||
|
return ""; // No ID for Pathgrid record
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
std::string Record<ESM::Skill>::getId() const
|
||||||
|
{
|
||||||
|
return ""; // No ID for Skill record
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace
|
} // end namespace
|
||||||
|
|
|
@ -32,13 +32,7 @@ namespace EsmTool
|
||||||
|
|
||||||
virtual ~RecordBase() {}
|
virtual ~RecordBase() {}
|
||||||
|
|
||||||
const std::string &getId() const {
|
virtual std::string getId() const = 0;
|
||||||
return mId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setId(const std::string &id) {
|
|
||||||
mId = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t getFlags() const {
|
uint32_t getFlags() const {
|
||||||
return mFlags;
|
return mFlags;
|
||||||
|
@ -73,23 +67,38 @@ namespace EsmTool
|
||||||
class Record : public RecordBase
|
class Record : public RecordBase
|
||||||
{
|
{
|
||||||
T mData;
|
T mData;
|
||||||
|
bool mIsDeleted;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Record()
|
||||||
|
: mIsDeleted(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::string getId() const {
|
||||||
|
return mData.mId;
|
||||||
|
}
|
||||||
|
|
||||||
T &get() {
|
T &get() {
|
||||||
return mData;
|
return mData;
|
||||||
}
|
}
|
||||||
|
|
||||||
void save(ESM::ESMWriter &esm) {
|
void save(ESM::ESMWriter &esm) {
|
||||||
mData.save(esm);
|
mData.save(esm, mIsDeleted);
|
||||||
}
|
}
|
||||||
|
|
||||||
void load(ESM::ESMReader &esm) {
|
void load(ESM::ESMReader &esm) {
|
||||||
mData.load(esm);
|
mData.load(esm, mIsDeleted);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print();
|
void print();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<> std::string Record<ESM::Cell>::getId() const;
|
||||||
|
template<> std::string Record<ESM::Land>::getId() const;
|
||||||
|
template<> std::string Record<ESM::MagicEffect>::getId() const;
|
||||||
|
template<> std::string Record<ESM::Pathgrid>::getId() const;
|
||||||
|
template<> std::string Record<ESM::Skill>::getId() const;
|
||||||
|
|
||||||
template<> void Record<ESM::Activator>::print();
|
template<> void Record<ESM::Activator>::print();
|
||||||
template<> void Record<ESM::Potion>::print();
|
template<> void Record<ESM::Potion>::print();
|
||||||
template<> void Record<ESM::Armor>::print();
|
template<> void Record<ESM::Armor>::print();
|
||||||
|
|
|
@ -158,9 +158,9 @@ namespace ESSImport
|
||||||
void ConvertCell::read(ESM::ESMReader &esm)
|
void ConvertCell::read(ESM::ESMReader &esm)
|
||||||
{
|
{
|
||||||
ESM::Cell cell;
|
ESM::Cell cell;
|
||||||
std::string id = esm.getHNString("NAME");
|
bool isDeleted = false;
|
||||||
cell.mName = id;
|
|
||||||
cell.load(esm, false);
|
cell.load(esm, isDeleted, false);
|
||||||
|
|
||||||
// I wonder what 0x40 does?
|
// I wonder what 0x40 does?
|
||||||
if (cell.isExterior() && cell.mData.mFlags & 0x20)
|
if (cell.isExterior() && cell.mData.mFlags & 0x20)
|
||||||
|
@ -169,7 +169,7 @@ namespace ESSImport
|
||||||
}
|
}
|
||||||
|
|
||||||
// note if the player is in a nameless exterior cell, we will assign the cellId later based on player position
|
// note if the player is in a nameless exterior cell, we will assign the cellId later based on player position
|
||||||
if (id == mContext->mPlayerCellName)
|
if (cell.mName == mContext->mPlayerCellName)
|
||||||
{
|
{
|
||||||
mContext->mPlayer.mCellId = cell.getCellId();
|
mContext->mPlayer.mCellId = cell.getCellId();
|
||||||
}
|
}
|
||||||
|
@ -277,7 +277,7 @@ namespace ESSImport
|
||||||
if (cell.isExterior())
|
if (cell.isExterior())
|
||||||
mExtCells[std::make_pair(cell.mData.mX, cell.mData.mY)] = newcell;
|
mExtCells[std::make_pair(cell.mData.mX, cell.mData.mY)] = newcell;
|
||||||
else
|
else
|
||||||
mIntCells[id] = newcell;
|
mIntCells[cell.mName] = newcell;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConvertCell::writeCell(const Cell &cell, ESM::ESMWriter& esm)
|
void ConvertCell::writeCell(const Cell &cell, ESM::ESMWriter& esm)
|
||||||
|
|
|
@ -54,6 +54,8 @@ public:
|
||||||
|
|
||||||
void setContext(Context& context) { mContext = &context; }
|
void setContext(Context& context) { mContext = &context; }
|
||||||
|
|
||||||
|
/// @note The load method of ESM records accept the deleted flag as a parameter.
|
||||||
|
/// I don't know can the DELE sub-record appear in saved games, so the deleted flag will be ignored.
|
||||||
virtual void read(ESM::ESMReader& esm)
|
virtual void read(ESM::ESMReader& esm)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -78,10 +80,11 @@ public:
|
||||||
|
|
||||||
virtual void read(ESM::ESMReader& esm)
|
virtual void read(ESM::ESMReader& esm)
|
||||||
{
|
{
|
||||||
std::string id = esm.getHNString("NAME");
|
|
||||||
T record;
|
T record;
|
||||||
record.load(esm);
|
bool isDeleted = false;
|
||||||
mRecords[id] = record;
|
|
||||||
|
record.load(esm, isDeleted);
|
||||||
|
mRecords[record.mId] = record;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void write(ESM::ESMWriter& esm)
|
virtual void write(ESM::ESMWriter& esm)
|
||||||
|
@ -89,7 +92,6 @@ public:
|
||||||
for (typename std::map<std::string, T>::const_iterator it = mRecords.begin(); it != mRecords.end(); ++it)
|
for (typename std::map<std::string, T>::const_iterator it = mRecords.begin(); it != mRecords.end(); ++it)
|
||||||
{
|
{
|
||||||
esm.startRecord(T::sRecordId);
|
esm.startRecord(T::sRecordId);
|
||||||
esm.writeHNString("NAME", it->first);
|
|
||||||
it->second.save(esm);
|
it->second.save(esm);
|
||||||
esm.endRecord(T::sRecordId);
|
esm.endRecord(T::sRecordId);
|
||||||
}
|
}
|
||||||
|
@ -105,14 +107,15 @@ public:
|
||||||
virtual void read(ESM::ESMReader &esm)
|
virtual void read(ESM::ESMReader &esm)
|
||||||
{
|
{
|
||||||
ESM::NPC npc;
|
ESM::NPC npc;
|
||||||
std::string id = esm.getHNString("NAME");
|
bool isDeleted = false;
|
||||||
npc.load(esm);
|
|
||||||
if (id != "player")
|
npc.load(esm, isDeleted);
|
||||||
|
if (npc.mId != "player")
|
||||||
{
|
{
|
||||||
// Handles changes to the NPC struct, but since there is no index here
|
// Handles changes to the NPC struct, but since there is no index here
|
||||||
// it will apply to ALL instances of the class. seems to be the reason for the
|
// it will apply to ALL instances of the class. seems to be the reason for the
|
||||||
// "feature" in MW where changing AI settings of one guard will change it for all guards of that refID.
|
// "feature" in MW where changing AI settings of one guard will change it for all guards of that refID.
|
||||||
mContext->mNpcs[Misc::StringUtils::lowerCase(id)] = npc;
|
mContext->mNpcs[Misc::StringUtils::lowerCase(npc.mId)] = npc;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -142,9 +145,10 @@ public:
|
||||||
{
|
{
|
||||||
// See comment in ConvertNPC
|
// See comment in ConvertNPC
|
||||||
ESM::Creature creature;
|
ESM::Creature creature;
|
||||||
std::string id = esm.getHNString("NAME");
|
bool isDeleted = false;
|
||||||
creature.load(esm);
|
|
||||||
mContext->mCreatures[Misc::StringUtils::lowerCase(id)] = creature;
|
creature.load(esm, isDeleted);
|
||||||
|
mContext->mCreatures[Misc::StringUtils::lowerCase(creature.mId)] = creature;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -157,18 +161,19 @@ class ConvertGlobal : public DefaultConverter<ESM::Global>
|
||||||
public:
|
public:
|
||||||
virtual void read(ESM::ESMReader &esm)
|
virtual void read(ESM::ESMReader &esm)
|
||||||
{
|
{
|
||||||
std::string id = esm.getHNString("NAME");
|
|
||||||
ESM::Global global;
|
ESM::Global global;
|
||||||
global.load(esm);
|
bool isDeleted = false;
|
||||||
if (Misc::StringUtils::ciEqual(id, "gamehour"))
|
|
||||||
|
global.load(esm, isDeleted);
|
||||||
|
if (Misc::StringUtils::ciEqual(global.mId, "gamehour"))
|
||||||
mContext->mHour = global.mValue.getFloat();
|
mContext->mHour = global.mValue.getFloat();
|
||||||
if (Misc::StringUtils::ciEqual(id, "day"))
|
if (Misc::StringUtils::ciEqual(global.mId, "day"))
|
||||||
mContext->mDay = global.mValue.getInteger();
|
mContext->mDay = global.mValue.getInteger();
|
||||||
if (Misc::StringUtils::ciEqual(id, "month"))
|
if (Misc::StringUtils::ciEqual(global.mId, "month"))
|
||||||
mContext->mMonth = global.mValue.getInteger();
|
mContext->mMonth = global.mValue.getInteger();
|
||||||
if (Misc::StringUtils::ciEqual(id, "year"))
|
if (Misc::StringUtils::ciEqual(global.mId, "year"))
|
||||||
mContext->mYear = global.mValue.getInteger();
|
mContext->mYear = global.mValue.getInteger();
|
||||||
mRecords[id] = global;
|
mRecords[global.mId] = global;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -177,14 +182,14 @@ class ConvertClass : public DefaultConverter<ESM::Class>
|
||||||
public:
|
public:
|
||||||
virtual void read(ESM::ESMReader &esm)
|
virtual void read(ESM::ESMReader &esm)
|
||||||
{
|
{
|
||||||
std::string id = esm.getHNString("NAME");
|
|
||||||
ESM::Class class_;
|
ESM::Class class_;
|
||||||
class_.load(esm);
|
bool isDeleted = false;
|
||||||
|
|
||||||
if (id == "NEWCLASSID_CHARGEN")
|
class_.load(esm, isDeleted);
|
||||||
|
if (class_.mId == "NEWCLASSID_CHARGEN")
|
||||||
mContext->mCustomPlayerClassName = class_.mName;
|
mContext->mCustomPlayerClassName = class_.mName;
|
||||||
|
|
||||||
mRecords[id] = class_;
|
mRecords[class_.mId] = class_;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -193,13 +198,14 @@ class ConvertBook : public DefaultConverter<ESM::Book>
|
||||||
public:
|
public:
|
||||||
virtual void read(ESM::ESMReader &esm)
|
virtual void read(ESM::ESMReader &esm)
|
||||||
{
|
{
|
||||||
std::string id = esm.getHNString("NAME");
|
|
||||||
ESM::Book book;
|
ESM::Book book;
|
||||||
book.load(esm);
|
bool isDeleted = false;
|
||||||
if (book.mData.mSkillID == -1)
|
|
||||||
mContext->mPlayer.mObject.mNpcStats.mUsedIds.push_back(Misc::StringUtils::lowerCase(id));
|
|
||||||
|
|
||||||
mRecords[id] = book;
|
book.load(esm, isDeleted);
|
||||||
|
if (book.mData.mSkillID == -1)
|
||||||
|
mContext->mPlayer.mObject.mNpcStats.mUsedIds.push_back(Misc::StringUtils::lowerCase(book.mId));
|
||||||
|
|
||||||
|
mRecords[book.mId] = book;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -371,11 +377,12 @@ class ConvertFACT : public Converter
|
||||||
public:
|
public:
|
||||||
virtual void read(ESM::ESMReader& esm)
|
virtual void read(ESM::ESMReader& esm)
|
||||||
{
|
{
|
||||||
std::string id = esm.getHNString("NAME");
|
|
||||||
ESM::Faction faction;
|
ESM::Faction faction;
|
||||||
faction.load(esm);
|
bool isDeleted = false;
|
||||||
|
|
||||||
|
faction.load(esm, isDeleted);
|
||||||
|
std::string id = Misc::StringUtils::lowerCase(faction.mId);
|
||||||
|
|
||||||
Misc::StringUtils::toLower(id);
|
|
||||||
for (std::map<std::string, int>::const_iterator it = faction.mReactions.begin(); it != faction.mReactions.end(); ++it)
|
for (std::map<std::string, int>::const_iterator it = faction.mReactions.begin(); it != faction.mReactions.end(); ++it)
|
||||||
{
|
{
|
||||||
std::string faction2 = Misc::StringUtils::lowerCase(it->first);
|
std::string faction2 = Misc::StringUtils::lowerCase(it->first);
|
||||||
|
@ -391,7 +398,7 @@ public:
|
||||||
virtual void read(ESM::ESMReader &esm)
|
virtual void read(ESM::ESMReader &esm)
|
||||||
{
|
{
|
||||||
std::string itemid = esm.getHNString("NAME");
|
std::string itemid = esm.getHNString("NAME");
|
||||||
Misc::StringUtils::toLower(itemid);
|
Misc::StringUtils::lowerCaseInPlace(itemid);
|
||||||
|
|
||||||
while (esm.isNextSub("FNAM") || esm.isNextSub("ONAM"))
|
while (esm.isNextSub("FNAM") || esm.isNextSub("ONAM"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,7 +32,8 @@ namespace ESSImport
|
||||||
if (esm.isNextSub("MNAM"))
|
if (esm.isNextSub("MNAM"))
|
||||||
esm.skipHSub();
|
esm.skipHSub();
|
||||||
|
|
||||||
ESM::CellRef::loadData(esm);
|
bool isDeleted = false;
|
||||||
|
ESM::CellRef::loadData(esm, isDeleted);
|
||||||
|
|
||||||
mHasACDT = false;
|
mHasACDT = false;
|
||||||
if (esm.isNextSub("ACDT"))
|
if (esm.isNextSub("ACDT"))
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace
|
||||||
*(image->data(x,y)+2) = *it++;
|
*(image->data(x,y)+2) = *it++;
|
||||||
*(image->data(x,y)+1) = *it++;
|
*(image->data(x,y)+1) = *it++;
|
||||||
*image->data(x,y) = *it++;
|
*image->data(x,y) = *it++;
|
||||||
it++; // skip alpha
|
++it; // skip alpha
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +394,7 @@ namespace ESSImport
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.startRecord(ESM::REC_NPC_);
|
writer.startRecord(ESM::REC_NPC_);
|
||||||
writer.writeHNString("NAME", "player");
|
context.mPlayerBase.mId = "player";
|
||||||
context.mPlayerBase.save(writer);
|
context.mPlayerBase.save(writer);
|
||||||
writer.endRecord(ESM::REC_NPC_);
|
writer.endRecord(ESM::REC_NPC_);
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,8 @@ namespace ESSImport
|
||||||
item.mSCRI.load(esm);
|
item.mSCRI.load(esm);
|
||||||
|
|
||||||
// for XSOL and XCHG seen so far, but probably others too
|
// for XSOL and XCHG seen so far, but probably others too
|
||||||
item.ESM::CellRef::loadData(esm);
|
bool isDeleted = false;
|
||||||
|
item.ESM::CellRef::loadData(esm, isDeleted);
|
||||||
|
|
||||||
int charge=-1;
|
int charge=-1;
|
||||||
esm.getHNOT(charge, "XHLT");
|
esm.getHNOT(charge, "XHLT");
|
||||||
|
|
|
@ -7,8 +7,6 @@ set(LAUNCHER
|
||||||
textslotmsgbox.cpp
|
textslotmsgbox.cpp
|
||||||
settingspage.cpp
|
settingspage.cpp
|
||||||
|
|
||||||
settings/graphicssettings.cpp
|
|
||||||
|
|
||||||
utils/profilescombobox.cpp
|
utils/profilescombobox.cpp
|
||||||
utils/textinputdialog.cpp
|
utils/textinputdialog.cpp
|
||||||
utils/lineedit.cpp
|
utils/lineedit.cpp
|
||||||
|
@ -24,8 +22,6 @@ set(LAUNCHER_HEADER
|
||||||
textslotmsgbox.hpp
|
textslotmsgbox.hpp
|
||||||
settingspage.hpp
|
settingspage.hpp
|
||||||
|
|
||||||
settings/graphicssettings.hpp
|
|
||||||
|
|
||||||
utils/profilescombobox.hpp
|
utils/profilescombobox.hpp
|
||||||
utils/textinputdialog.hpp
|
utils/textinputdialog.hpp
|
||||||
utils/lineedit.hpp
|
utils/lineedit.hpp
|
||||||
|
|
|
@ -75,7 +75,7 @@ bool Launcher::DataFilesPage::loadSettings()
|
||||||
QStringList profiles = mLauncherSettings.getContentLists();
|
QStringList profiles = mLauncherSettings.getContentLists();
|
||||||
QString currentProfile = mLauncherSettings.getCurrentContentListName();
|
QString currentProfile = mLauncherSettings.getCurrentContentListName();
|
||||||
|
|
||||||
qDebug() << "current profile is: " << currentProfile;
|
qDebug() << "The current profile is: " << currentProfile;
|
||||||
|
|
||||||
foreach (const QString &item, profiles)
|
foreach (const QString &item, profiles)
|
||||||
addProfile (item, false);
|
addProfile (item, false);
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#include <components/contentselector/model/naturalsort.hpp>
|
#include <components/contentselector/model/naturalsort.hpp>
|
||||||
|
|
||||||
#include "settings/graphicssettings.hpp"
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
QString getAspect(int x, int y)
|
QString getAspect(int x, int y)
|
||||||
{
|
{
|
||||||
|
@ -32,10 +32,10 @@ QString getAspect(int x, int y)
|
||||||
return QString(QString::number(xaspect) + ":" + QString::number(yaspect));
|
return QString(QString::number(xaspect) + ":" + QString::number(yaspect));
|
||||||
}
|
}
|
||||||
|
|
||||||
Launcher::GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSetting, QWidget *parent)
|
Launcher::GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, Settings::Manager &engineSettings, QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, mCfgMgr(cfg)
|
, mCfgMgr(cfg)
|
||||||
, mGraphicsSettings(graphicsSetting)
|
, mEngineSettings(engineSettings)
|
||||||
{
|
{
|
||||||
setObjectName ("GraphicsPage");
|
setObjectName ("GraphicsPage");
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
@ -80,25 +80,26 @@ bool Launcher::GraphicsPage::loadSettings()
|
||||||
if (!setupSDL())
|
if (!setupSDL())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mGraphicsSettings.value(QString("Video/vsync")) == QLatin1String("true"))
|
if (mEngineSettings.getBool("vsync", "Video"))
|
||||||
vSyncCheckBox->setCheckState(Qt::Checked);
|
vSyncCheckBox->setCheckState(Qt::Checked);
|
||||||
|
|
||||||
if (mGraphicsSettings.value(QString("Video/fullscreen")) == QLatin1String("true"))
|
if (mEngineSettings.getBool("fullscreen", "Video"))
|
||||||
fullScreenCheckBox->setCheckState(Qt::Checked);
|
fullScreenCheckBox->setCheckState(Qt::Checked);
|
||||||
|
|
||||||
if (mGraphicsSettings.value(QString("Video/window border")) == QLatin1String("true"))
|
if (mEngineSettings.getBool("window border", "Video"))
|
||||||
windowBorderCheckBox->setCheckState(Qt::Checked);
|
windowBorderCheckBox->setCheckState(Qt::Checked);
|
||||||
|
|
||||||
int aaIndex = antiAliasingComboBox->findText(mGraphicsSettings.value(QString("Video/antialiasing")));
|
// aaValue is the actual value (0, 1, 2, 4, 8, 16)
|
||||||
|
int aaValue = mEngineSettings.getInt("antialiasing", "Video");
|
||||||
|
// aaIndex is the index into the allowed values in the pull down.
|
||||||
|
int aaIndex = antiAliasingComboBox->findText(QString::number(aaValue));
|
||||||
if (aaIndex != -1)
|
if (aaIndex != -1)
|
||||||
antiAliasingComboBox->setCurrentIndex(aaIndex);
|
antiAliasingComboBox->setCurrentIndex(aaIndex);
|
||||||
|
|
||||||
QString width = mGraphicsSettings.value(QString("Video/resolution x"));
|
int width = mEngineSettings.getInt("resolution x", "Video");
|
||||||
QString height = mGraphicsSettings.value(QString("Video/resolution y"));
|
int height = mEngineSettings.getInt("resolution y", "Video");
|
||||||
QString resolution = width + QString(" x ") + height;
|
QString resolution = QString::number(width) + QString(" x ") + QString::number(height);
|
||||||
QString screen = mGraphicsSettings.value(QString("Video/screen"));
|
screenComboBox->setCurrentIndex(mEngineSettings.getInt("screen", "Video"));
|
||||||
|
|
||||||
screenComboBox->setCurrentIndex(screen.toInt());
|
|
||||||
|
|
||||||
int resIndex = resolutionComboBox->findText(resolution, Qt::MatchStartsWith);
|
int resIndex = resolutionComboBox->findText(resolution, Qt::MatchStartsWith);
|
||||||
|
|
||||||
|
@ -107,9 +108,8 @@ bool Launcher::GraphicsPage::loadSettings()
|
||||||
resolutionComboBox->setCurrentIndex(resIndex);
|
resolutionComboBox->setCurrentIndex(resIndex);
|
||||||
} else {
|
} else {
|
||||||
customRadioButton->toggle();
|
customRadioButton->toggle();
|
||||||
customWidthSpinBox->setValue(width.toInt());
|
customWidthSpinBox->setValue(width);
|
||||||
customHeightSpinBox->setValue(height.toInt());
|
customHeightSpinBox->setValue(height);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -117,31 +117,46 @@ bool Launcher::GraphicsPage::loadSettings()
|
||||||
|
|
||||||
void Launcher::GraphicsPage::saveSettings()
|
void Launcher::GraphicsPage::saveSettings()
|
||||||
{
|
{
|
||||||
vSyncCheckBox->checkState() ? mGraphicsSettings.setValue(QString("Video/vsync"), QString("true"))
|
// Ensure we only set the new settings if they changed. This is to avoid cluttering the
|
||||||
: mGraphicsSettings.setValue(QString("Video/vsync"), QString("false"));
|
// user settings file (which by definition should only contain settings the user has touched)
|
||||||
|
bool cVSync = vSyncCheckBox->checkState();
|
||||||
|
if (cVSync != mEngineSettings.getBool("vsync", "Video"))
|
||||||
|
mEngineSettings.setBool("vsync", "Video", cVSync);
|
||||||
|
|
||||||
fullScreenCheckBox->checkState() ? mGraphicsSettings.setValue(QString("Video/fullscreen"), QString("true"))
|
bool cFullScreen = fullScreenCheckBox->checkState();
|
||||||
: mGraphicsSettings.setValue(QString("Video/fullscreen"), QString("false"));
|
if (cFullScreen != mEngineSettings.getBool("fullscreen", "Video"))
|
||||||
|
mEngineSettings.setBool("fullscreen", "Video", cFullScreen);
|
||||||
|
|
||||||
windowBorderCheckBox->checkState() ? mGraphicsSettings.setValue(QString("Video/window border"), QString("true"))
|
bool cWindowBorder = windowBorderCheckBox->checkState();
|
||||||
: mGraphicsSettings.setValue(QString("Video/window border"), QString("false"));
|
if (cWindowBorder != mEngineSettings.getBool("window border", "Video"))
|
||||||
|
mEngineSettings.setBool("window border", "Video", cWindowBorder);
|
||||||
mGraphicsSettings.setValue(QString("Video/antialiasing"), antiAliasingComboBox->currentText());
|
|
||||||
|
|
||||||
|
int cAAValue = antiAliasingComboBox->currentText().toInt();
|
||||||
|
if (cAAValue != mEngineSettings.getInt("antialiasing", "Video"))
|
||||||
|
mEngineSettings.setInt("antialiasing", "Video", cAAValue);
|
||||||
|
|
||||||
|
int cWidth = 0;
|
||||||
|
int cHeight = 0;
|
||||||
if (standardRadioButton->isChecked()) {
|
if (standardRadioButton->isChecked()) {
|
||||||
QRegExp resolutionRe(QString("(\\d+) x (\\d+).*"));
|
QRegExp resolutionRe(QString("(\\d+) x (\\d+).*"));
|
||||||
|
|
||||||
if (resolutionRe.exactMatch(resolutionComboBox->currentText().simplified())) {
|
if (resolutionRe.exactMatch(resolutionComboBox->currentText().simplified())) {
|
||||||
mGraphicsSettings.setValue(QString("Video/resolution x"), resolutionRe.cap(1));
|
cWidth = resolutionRe.cap(1).toInt();
|
||||||
mGraphicsSettings.setValue(QString("Video/resolution y"), resolutionRe.cap(2));
|
cHeight = resolutionRe.cap(2).toInt();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mGraphicsSettings.setValue(QString("Video/resolution x"), QString::number(customWidthSpinBox->value()));
|
cWidth = customWidthSpinBox->value();
|
||||||
mGraphicsSettings.setValue(QString("Video/resolution y"), QString::number(customHeightSpinBox->value()));
|
cHeight = customHeightSpinBox->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
mGraphicsSettings.setValue(QString("Video/screen"), QString::number(screenComboBox->currentIndex()));
|
if (cWidth != mEngineSettings.getInt("resolution x", "Video"))
|
||||||
|
mEngineSettings.setInt("resolution x", "Video", cWidth);
|
||||||
|
|
||||||
|
if (cHeight != mEngineSettings.getInt("resolution y", "Video"))
|
||||||
|
mEngineSettings.setInt("resolution y", "Video", cHeight);
|
||||||
|
|
||||||
|
int cScreen = screenComboBox->currentIndex();
|
||||||
|
if (cScreen != mEngineSettings.getInt("screen", "Video"))
|
||||||
|
mEngineSettings.setInt("screen", "Video", cScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList Launcher::GraphicsPage::getAvailableResolutions(int screen)
|
QStringList Launcher::GraphicsPage::getAvailableResolutions(int screen)
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#include "ui_graphicspage.h"
|
#include "ui_graphicspage.h"
|
||||||
|
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
namespace Files { struct ConfigurationManager; }
|
namespace Files { struct ConfigurationManager; }
|
||||||
|
|
||||||
namespace Launcher
|
namespace Launcher
|
||||||
|
@ -16,7 +18,7 @@ namespace Launcher
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSettings, QWidget *parent = 0);
|
GraphicsPage(Files::ConfigurationManager &cfg, Settings::Manager &engineSettings, QWidget *parent = 0);
|
||||||
|
|
||||||
void saveSettings();
|
void saveSettings();
|
||||||
bool loadSettings();
|
bool loadSettings();
|
||||||
|
@ -30,7 +32,7 @@ namespace Launcher
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Files::ConfigurationManager &mCfgMgr;
|
Files::ConfigurationManager &mCfgMgr;
|
||||||
GraphicsSettings &mGraphicsSettings;
|
Settings::Manager &mEngineSettings;
|
||||||
|
|
||||||
QStringList getAvailableResolutions(int screen);
|
QStringList getAvailableResolutions(int screen);
|
||||||
QRect getMaximumResolution();
|
QRect getMaximumResolution();
|
||||||
|
|
|
@ -41,15 +41,6 @@ int main(int argc, char *argv[])
|
||||||
dir.cdUp();
|
dir.cdUp();
|
||||||
dir.cdUp();
|
dir.cdUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
// force Qt to load only LOCAL plugins, don't touch system Qt installation
|
|
||||||
QDir pluginsPath(QCoreApplication::applicationDirPath());
|
|
||||||
pluginsPath.cdUp();
|
|
||||||
pluginsPath.cd("Plugins");
|
|
||||||
|
|
||||||
QStringList libraryPaths;
|
|
||||||
libraryPaths << pluginsPath.path() << QCoreApplication::applicationDirPath();
|
|
||||||
app.setLibraryPaths(libraryPaths);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QDir::setCurrent(dir.absolutePath());
|
QDir::setCurrent(dir.absolutePath());
|
||||||
|
@ -60,10 +51,6 @@ int main(int argc, char *argv[])
|
||||||
if (result == Launcher::FirstRunDialogResultFailure)
|
if (result == Launcher::FirstRunDialogResultFailure)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// if (!mainWin.setup()) {
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (result == Launcher::FirstRunDialogResultContinue)
|
if (result == Launcher::FirstRunDialogResultContinue)
|
||||||
mainWin.show();
|
mainWin.show();
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,15 @@
|
||||||
|
|
||||||
using namespace Process;
|
using namespace Process;
|
||||||
|
|
||||||
|
void cfgError(const QString& title, const QString& msg) {
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setWindowTitle(title);
|
||||||
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
msgBox.setText(msg);
|
||||||
|
msgBox.exec();
|
||||||
|
}
|
||||||
|
|
||||||
Launcher::MainDialog::MainDialog(QWidget *parent)
|
Launcher::MainDialog::MainDialog(QWidget *parent)
|
||||||
: QMainWindow(parent), mGameSettings (mCfgMgr)
|
: QMainWindow(parent), mGameSettings (mCfgMgr)
|
||||||
{
|
{
|
||||||
|
@ -105,7 +114,7 @@ void Launcher::MainDialog::createPages()
|
||||||
{
|
{
|
||||||
mPlayPage = new PlayPage(this);
|
mPlayPage = new PlayPage(this);
|
||||||
mDataFilesPage = new DataFilesPage(mCfgMgr, mGameSettings, mLauncherSettings, this);
|
mDataFilesPage = new DataFilesPage(mCfgMgr, mGameSettings, mLauncherSettings, this);
|
||||||
mGraphicsPage = new GraphicsPage(mCfgMgr, mGraphicsSettings, this);
|
mGraphicsPage = new GraphicsPage(mCfgMgr, mEngineSettings, this);
|
||||||
mSettingsPage = new SettingsPage(mCfgMgr, mGameSettings, mLauncherSettings, this);
|
mSettingsPage = new SettingsPage(mCfgMgr, mGameSettings, mLauncherSettings, this);
|
||||||
|
|
||||||
// Set the combobox of the play page to imitate the combobox on the datafilespage
|
// Set the combobox of the play page to imitate the combobox on the datafilespage
|
||||||
|
@ -248,6 +257,8 @@ void Launcher::MainDialog::changePage(QListWidgetItem *current, QListWidgetItem
|
||||||
|
|
||||||
bool Launcher::MainDialog::setupLauncherSettings()
|
bool Launcher::MainDialog::setupLauncherSettings()
|
||||||
{
|
{
|
||||||
|
mLauncherSettings.clear();
|
||||||
|
|
||||||
mLauncherSettings.setMultiValueEnabled(true);
|
mLauncherSettings.setMultiValueEnabled(true);
|
||||||
|
|
||||||
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str());
|
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str());
|
||||||
|
@ -257,18 +268,14 @@ bool Launcher::MainDialog::setupLauncherSettings()
|
||||||
paths.append(userPath + QString(Config::LauncherSettings::sLauncherConfigFileName));
|
paths.append(userPath + QString(Config::LauncherSettings::sLauncherConfigFileName));
|
||||||
|
|
||||||
foreach (const QString &path, paths) {
|
foreach (const QString &path, paths) {
|
||||||
qDebug() << "Loading config file:" << qPrintable(path);
|
qDebug() << "Loading config file:" << path.toUtf8().constData();
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
QMessageBox msgBox;
|
cfgError(tr("Error opening OpenMW configuration file"),
|
||||||
msgBox.setWindowTitle(tr("Error opening OpenMW configuration file"));
|
tr("<br><b>Could not open %0 for reading</b><br><br> \
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
Please make sure you have the right permissions \
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
and try again.<br>").arg(file.fileName()));
|
||||||
msgBox.setText(tr("<br><b>Could not open %0 for reading</b><br><br> \
|
|
||||||
Please make sure you have the right permissions \
|
|
||||||
and try again.<br>").arg(file.fileName()));
|
|
||||||
msgBox.exec();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
QTextStream stream(&file);
|
QTextStream stream(&file);
|
||||||
|
@ -284,6 +291,8 @@ bool Launcher::MainDialog::setupLauncherSettings()
|
||||||
|
|
||||||
bool Launcher::MainDialog::setupGameSettings()
|
bool Launcher::MainDialog::setupGameSettings()
|
||||||
{
|
{
|
||||||
|
mGameSettings.clear();
|
||||||
|
|
||||||
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str());
|
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str());
|
||||||
QString globalPath = QString::fromUtf8(mCfgMgr.getGlobalPath().string().c_str());
|
QString globalPath = QString::fromUtf8(mCfgMgr.getGlobalPath().string().c_str());
|
||||||
|
|
||||||
|
@ -292,18 +301,14 @@ bool Launcher::MainDialog::setupGameSettings()
|
||||||
QString path = userPath + QLatin1String("openmw.cfg");
|
QString path = userPath + QLatin1String("openmw.cfg");
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
|
|
||||||
qDebug() << "Loading config file:" << qPrintable(path);
|
qDebug() << "Loading config file:" << path.toUtf8().constData();
|
||||||
|
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
QMessageBox msgBox;
|
cfgError(tr("Error opening OpenMW configuration file"),
|
||||||
msgBox.setWindowTitle(tr("Error opening OpenMW configuration file"));
|
tr("<br><b>Could not open %0 for reading</b><br><br> \
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
Please make sure you have the right permissions \
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
and try again.<br>").arg(file.fileName()));
|
||||||
msgBox.setText(tr("<br><b>Could not open %0 for reading</b><br><br> \
|
|
||||||
Please make sure you have the right permissions \
|
|
||||||
and try again.<br>").arg(file.fileName()));
|
|
||||||
msgBox.exec();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
QTextStream stream(&file);
|
QTextStream stream(&file);
|
||||||
|
@ -319,19 +324,15 @@ bool Launcher::MainDialog::setupGameSettings()
|
||||||
paths.append(userPath + QString("openmw.cfg"));
|
paths.append(userPath + QString("openmw.cfg"));
|
||||||
|
|
||||||
foreach (const QString &path, paths) {
|
foreach (const QString &path, paths) {
|
||||||
qDebug() << "Loading config file:" << qPrintable(path);
|
qDebug() << "Loading config file:" << path.toUtf8().constData();
|
||||||
|
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
QMessageBox msgBox;
|
cfgError(tr("Error opening OpenMW configuration file"),
|
||||||
msgBox.setWindowTitle(tr("Error opening OpenMW configuration file"));
|
tr("<br><b>Could not open %0 for reading</b><br><br> \
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
Please make sure you have the right permissions \
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
and try again.<br>").arg(file.fileName()));
|
||||||
msgBox.setText(tr("<br><b>Could not open %0 for reading</b><br><br> \
|
|
||||||
Please make sure you have the right permissions \
|
|
||||||
and try again.<br>").arg(file.fileName()));
|
|
||||||
msgBox.exec();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
QTextStream stream(&file);
|
QTextStream stream(&file);
|
||||||
|
@ -383,53 +384,54 @@ bool Launcher::MainDialog::setupGameSettings()
|
||||||
|
|
||||||
bool Launcher::MainDialog::setupGraphicsSettings()
|
bool Launcher::MainDialog::setupGraphicsSettings()
|
||||||
{
|
{
|
||||||
mGraphicsSettings.setMultiValueEnabled(false);
|
// This method is almost a copy of OMW::Engine::loadSettings(). They should definitely
|
||||||
|
// remain consistent, and possibly be merged into a shared component. At the very least
|
||||||
|
// the filenames should be in the CfgMgr component.
|
||||||
|
|
||||||
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str());
|
// Ensure to clear previous settings in case we had already loaded settings.
|
||||||
QString globalPath = QString::fromUtf8(mCfgMgr.getGlobalPath().string().c_str());
|
mEngineSettings.clear();
|
||||||
|
|
||||||
QFile localDefault(QString("settings-default.cfg"));
|
// Create the settings manager and load default settings file
|
||||||
QFile globalDefault(globalPath + QString("settings-default.cfg"));
|
const std::string localDefault = (mCfgMgr.getLocalPath() / "settings-default.cfg").string();
|
||||||
|
const std::string globalDefault = (mCfgMgr.getGlobalPath() / "settings-default.cfg").string();
|
||||||
|
std::string defaultPath;
|
||||||
|
|
||||||
if (!localDefault.exists() && !globalDefault.exists()) {
|
// Prefer the settings-default.cfg in the current directory.
|
||||||
QMessageBox msgBox;
|
if (boost::filesystem::exists(localDefault))
|
||||||
msgBox.setWindowTitle(tr("Error reading OpenMW configuration file"));
|
defaultPath = localDefault;
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
else if (boost::filesystem::exists(globalDefault))
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
defaultPath = globalDefault;
|
||||||
msgBox.setText(tr("<br><b>Could not find settings-default.cfg</b><br><br> \
|
// Something's very wrong if we can't find the file at all.
|
||||||
The problem may be due to an incomplete installation of OpenMW.<br> \
|
else {
|
||||||
Reinstalling OpenMW may resolve the problem."));
|
cfgError(tr("Error reading OpenMW configuration file"),
|
||||||
msgBox.exec();
|
tr("<br><b>Could not find settings-default.cfg</b><br><br> \
|
||||||
|
The problem may be due to an incomplete installation of OpenMW.<br> \
|
||||||
|
Reinstalling OpenMW may resolve the problem."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load the default settings, report any parsing errors.
|
||||||
|
try {
|
||||||
|
mEngineSettings.loadDefault(defaultPath);
|
||||||
|
}
|
||||||
|
catch (std::exception& e) {
|
||||||
|
std::string msg = std::string("<br><b>Error reading settings-default.cfg</b><br><br>") + e.what();
|
||||||
|
cfgError(tr("Error reading OpenMW configuration file"), tr(msg.c_str()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QStringList paths;
|
// Load user settings if they exist
|
||||||
paths.append(globalPath + QString("settings-default.cfg"));
|
const std::string userPath = (mCfgMgr.getUserConfigPath() / "settings.cfg").string();
|
||||||
paths.append(QString("settings-default.cfg"));
|
// User settings are not required to exist, so if they don't we're done.
|
||||||
paths.append(userPath + QString("settings.cfg"));
|
if (!boost::filesystem::exists(userPath)) return true;
|
||||||
|
|
||||||
foreach (const QString &path, paths) {
|
try {
|
||||||
qDebug() << "Loading config file:" << qPrintable(path);
|
mEngineSettings.loadUser(userPath);
|
||||||
QFile file(path);
|
}
|
||||||
if (file.exists()) {
|
catch (std::exception& e) {
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
std::string msg = std::string("<br><b>Error reading settings.cfg</b><br><br>") + e.what();
|
||||||
QMessageBox msgBox;
|
cfgError(tr("Error reading OpenMW configuration file"), tr(msg.c_str()));
|
||||||
msgBox.setWindowTitle(tr("Error opening OpenMW configuration file"));
|
return false;
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
||||||
msgBox.setText(tr("<br><b>Could not open %0 for reading</b><br><br> \
|
|
||||||
Please make sure you have the right permissions \
|
|
||||||
and try again.<br>").arg(file.fileName()));
|
|
||||||
msgBox.exec();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
QTextStream stream(&file);
|
|
||||||
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
|
||||||
|
|
||||||
mGraphicsSettings.readFile(stream);
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -478,15 +480,11 @@ bool Launcher::MainDialog::writeSettings()
|
||||||
|
|
||||||
if (!dir.exists()) {
|
if (!dir.exists()) {
|
||||||
if (!dir.mkpath(userPath)) {
|
if (!dir.mkpath(userPath)) {
|
||||||
QMessageBox msgBox;
|
cfgError(tr("Error creating OpenMW configuration directory"),
|
||||||
msgBox.setWindowTitle(tr("Error creating OpenMW configuration directory"));
|
tr("<br><b>Could not create %0</b><br><br> \
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
Please make sure you have the right permissions \
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
and try again.<br>").arg(userPath));
|
||||||
msgBox.setText(tr("<br><b>Could not create %0</b><br><br> \
|
return false;
|
||||||
Please make sure you have the right permissions \
|
|
||||||
and try again.<br>").arg(userPath));
|
|
||||||
msgBox.exec();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,15 +493,11 @@ bool Launcher::MainDialog::writeSettings()
|
||||||
|
|
||||||
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
||||||
// File cannot be opened or created
|
// File cannot be opened or created
|
||||||
QMessageBox msgBox;
|
cfgError(tr("Error writing OpenMW configuration file"),
|
||||||
msgBox.setWindowTitle(tr("Error writing OpenMW configuration file"));
|
tr("<br><b>Could not open or create %0 for writing</b><br><br> \
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
Please make sure you have the right permissions \
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
and try again.<br>").arg(file.fileName()));
|
||||||
msgBox.setText(tr("<br><b>Could not open or create %0 for writing</b><br><br> \
|
return false;
|
||||||
Please make sure you have the right permissions \
|
|
||||||
and try again.<br>").arg(file.fileName()));
|
|
||||||
msgBox.exec();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -511,44 +505,30 @@ bool Launcher::MainDialog::writeSettings()
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
// Graphics settings
|
// Graphics settings
|
||||||
file.setFileName(userPath + QString("settings.cfg"));
|
const std::string settingsPath = (mCfgMgr.getUserConfigPath() / "settings.cfg").string();
|
||||||
|
try {
|
||||||
if (!file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) {
|
mEngineSettings.saveUser(settingsPath);
|
||||||
// File cannot be opened or created
|
}
|
||||||
QMessageBox msgBox;
|
catch (std::exception& e) {
|
||||||
msgBox.setWindowTitle(tr("Error writing OpenMW configuration file"));
|
std::string msg = "<br><b>Error writing settings.cfg</b><br><br>" +
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
settingsPath + "<br><br>" + e.what();
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
cfgError(tr("Error writing user settings file"), tr(msg.c_str()));
|
||||||
msgBox.setText(tr("<br><b>Could not open or create %0 for writing</b><br><br> \
|
return false;
|
||||||
Please make sure you have the right permissions \
|
|
||||||
and try again.<br>").arg(file.fileName()));
|
|
||||||
msgBox.exec();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QTextStream stream(&file);
|
|
||||||
stream.setDevice(&file);
|
|
||||||
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
|
||||||
|
|
||||||
mGraphicsSettings.writeFile(stream);
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
// Launcher settings
|
// Launcher settings
|
||||||
file.setFileName(userPath + QString(Config::LauncherSettings::sLauncherConfigFileName));
|
file.setFileName(userPath + QString(Config::LauncherSettings::sLauncherConfigFileName));
|
||||||
|
|
||||||
if (!file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) {
|
if (!file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) {
|
||||||
// File cannot be opened or created
|
// File cannot be opened or created
|
||||||
QMessageBox msgBox;
|
cfgError(tr("Error writing Launcher configuration file"),
|
||||||
msgBox.setWindowTitle(tr("Error writing Launcher configuration file"));
|
tr("<br><b>Could not open or create %0 for writing</b><br><br> \
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
Please make sure you have the right permissions \
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
and try again.<br>").arg(file.fileName()));
|
||||||
msgBox.setText(tr("<br><b>Could not open or create %0 for writing</b><br><br> \
|
return false;
|
||||||
Please make sure you have the right permissions \
|
|
||||||
and try again.<br>").arg(file.fileName()));
|
|
||||||
msgBox.exec();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QTextStream stream(&file);
|
||||||
stream.setDevice(&file);
|
stream.setDevice(&file);
|
||||||
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include <components/config/gamesettings.hpp>
|
#include <components/config/gamesettings.hpp>
|
||||||
#include <components/config/launchersettings.hpp>
|
#include <components/config/launchersettings.hpp>
|
||||||
|
|
||||||
#include "settings/graphicssettings.hpp"
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include "ui_mainwindow.h"
|
#include "ui_mainwindow.h"
|
||||||
|
|
||||||
|
@ -50,7 +50,6 @@ namespace Launcher
|
||||||
explicit MainDialog(QWidget *parent = 0);
|
explicit MainDialog(QWidget *parent = 0);
|
||||||
~MainDialog();
|
~MainDialog();
|
||||||
|
|
||||||
bool setup();
|
|
||||||
FirstRunDialogResult showFirstRunDialog();
|
FirstRunDialogResult showFirstRunDialog();
|
||||||
|
|
||||||
bool reloadSettings();
|
bool reloadSettings();
|
||||||
|
@ -65,6 +64,8 @@ namespace Launcher
|
||||||
void wizardFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
void wizardFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool setup();
|
||||||
|
|
||||||
void createIcons();
|
void createIcons();
|
||||||
void createPages();
|
void createPages();
|
||||||
|
|
||||||
|
@ -93,7 +94,7 @@ namespace Launcher
|
||||||
Files::ConfigurationManager mCfgMgr;
|
Files::ConfigurationManager mCfgMgr;
|
||||||
|
|
||||||
Config::GameSettings mGameSettings;
|
Config::GameSettings mGameSettings;
|
||||||
GraphicsSettings mGraphicsSettings;
|
Settings::Manager mEngineSettings;
|
||||||
Config::LauncherSettings mLauncherSettings;
|
Config::LauncherSettings mLauncherSettings;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,20 +2,11 @@
|
||||||
|
|
||||||
#include <QListView>
|
#include <QListView>
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
|
||||||
#include <QPlastiqueStyle>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Launcher::PlayPage::PlayPage(QWidget *parent) : QWidget(parent)
|
Launcher::PlayPage::PlayPage(QWidget *parent) : QWidget(parent)
|
||||||
{
|
{
|
||||||
setObjectName ("PlayPage");
|
setObjectName ("PlayPage");
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
|
||||||
// Hacks to get the stylesheet look properly
|
|
||||||
#ifdef Q_OS_MAC
|
|
||||||
QPlastiqueStyle *style = new QPlastiqueStyle;
|
|
||||||
profilesComboBox->setStyle(style);
|
|
||||||
#endif
|
|
||||||
profilesComboBox->setView(new QListView());
|
profilesComboBox->setView(new QListView());
|
||||||
|
|
||||||
connect(profilesComboBox, SIGNAL(activated(int)), this, SIGNAL (signalProfileChanged(int)));
|
connect(profilesComboBox, SIGNAL(activated(int)), this, SIGNAL (signalProfileChanged(int)));
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
#include "graphicssettings.hpp"
|
|
||||||
|
|
||||||
#include <QTextStream>
|
|
||||||
#include <QString>
|
|
||||||
#include <QRegExp>
|
|
||||||
#include <QMap>
|
|
||||||
|
|
||||||
Launcher::GraphicsSettings::GraphicsSettings()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Launcher::GraphicsSettings::~GraphicsSettings()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Launcher::GraphicsSettings::writeFile(QTextStream &stream)
|
|
||||||
{
|
|
||||||
QString sectionPrefix;
|
|
||||||
QRegExp sectionRe("([^/]+)/(.+)$");
|
|
||||||
QMap<QString, QString> settings = SettingsBase::getSettings();
|
|
||||||
|
|
||||||
QMapIterator<QString, QString> i(settings);
|
|
||||||
while (i.hasNext()) {
|
|
||||||
i.next();
|
|
||||||
|
|
||||||
QString prefix;
|
|
||||||
QString key;
|
|
||||||
|
|
||||||
if (sectionRe.exactMatch(i.key())) {
|
|
||||||
prefix = sectionRe.cap(1);
|
|
||||||
key = sectionRe.cap(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sectionPrefix != prefix) {
|
|
||||||
sectionPrefix = prefix;
|
|
||||||
stream << "\n[" << prefix << "]\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
stream << key << " = " << i.value() << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
#ifndef GRAPHICSSETTINGS_HPP
|
|
||||||
#define GRAPHICSSETTINGS_HPP
|
|
||||||
|
|
||||||
#include <components/config/settingsbase.hpp>
|
|
||||||
|
|
||||||
namespace Launcher
|
|
||||||
{
|
|
||||||
class GraphicsSettings : public Config::SettingsBase<QMap<QString, QString> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GraphicsSettings();
|
|
||||||
~GraphicsSettings();
|
|
||||||
|
|
||||||
bool writeFile(QTextStream &stream);
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif // GRAPHICSSETTINGS_HPP
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "importer.hpp"
|
#include "importer.hpp"
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
@ -20,7 +21,6 @@ MwIniImporter::MwIniImporter()
|
||||||
{
|
{
|
||||||
const char *map[][2] =
|
const char *map[][2] =
|
||||||
{
|
{
|
||||||
{ "fps", "General:Show FPS" },
|
|
||||||
{ "no-sound", "General:Disable Audio" },
|
{ "no-sound", "General:Disable Audio" },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
@ -639,6 +639,9 @@ MwIniImporter::MwIniImporter()
|
||||||
"Blood:Texture Name 1",
|
"Blood:Texture Name 1",
|
||||||
"Blood:Texture Name 2",
|
"Blood:Texture Name 2",
|
||||||
|
|
||||||
|
// werewolf (Bloodmoon)
|
||||||
|
"General:Werewolf FOV",
|
||||||
|
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -847,7 +850,7 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini, co
|
||||||
|
|
||||||
for(std::vector<std::string>::const_iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) {
|
for(std::vector<std::string>::const_iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) {
|
||||||
std::string filetype(entry->substr(entry->length()-3));
|
std::string filetype(entry->substr(entry->length()-3));
|
||||||
Misc::StringUtils::toLower(filetype);
|
Misc::StringUtils::lowerCaseInPlace(filetype);
|
||||||
|
|
||||||
if(filetype.compare("esm") == 0 || filetype.compare("esp") == 0) {
|
if(filetype.compare("esm") == 0 || filetype.compare("esp") == 0) {
|
||||||
boost::filesystem::path filepath(gameFilesDir);
|
boost::filesystem::path filepath(gameFilesDir);
|
||||||
|
@ -895,8 +898,13 @@ std::time_t MwIniImporter::lastWriteTime(const boost::filesystem::path& filename
|
||||||
boost::filesystem::path resolved = filename;
|
boost::filesystem::path resolved = filename;
|
||||||
#endif
|
#endif
|
||||||
writeTime = boost::filesystem::last_write_time(resolved);
|
writeTime = boost::filesystem::last_write_time(resolved);
|
||||||
std::cout << "content file: " << resolved << " timestamp = (" << writeTime <<
|
|
||||||
") " << asctime(localtime(&writeTime)) << std::endl;
|
// print timestamp
|
||||||
|
const int size=1024;
|
||||||
|
char timeStrBuffer[size];
|
||||||
|
if (std::strftime(timeStrBuffer, size, "%x %X", localtime(&writeTime)) > 0)
|
||||||
|
std::cout << "content file: " << resolved << " timestamp = (" << writeTime <<
|
||||||
|
") " << timeStrBuffer << std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,7 +26,7 @@ opencs_units_noqt (model/world
|
||||||
universalid record commands columnbase columnimp scriptcontext cell refidcollection
|
universalid record commands columnbase columnimp scriptcontext cell refidcollection
|
||||||
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope
|
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope
|
||||||
pathgrid landtexture land nestedtablewrapper nestedcollection nestedcoladapterimp nestedinfocollection
|
pathgrid landtexture land nestedtablewrapper nestedcollection nestedcoladapterimp nestedinfocollection
|
||||||
idcompletionmanager metadata
|
idcompletionmanager metadata defaultgmsts
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_hdrs_noqt (model/world
|
opencs_hdrs_noqt (model/world
|
||||||
|
@ -42,7 +42,7 @@ opencs_units_noqt (model/tools
|
||||||
mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck
|
mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck
|
||||||
birthsigncheck spellcheck referencecheck referenceablecheck scriptcheck bodypartcheck
|
birthsigncheck spellcheck referencecheck referenceablecheck scriptcheck bodypartcheck
|
||||||
startscriptcheck search searchoperation searchstage pathgridcheck soundgencheck magiceffectcheck
|
startscriptcheck search searchoperation searchstage pathgridcheck soundgencheck magiceffectcheck
|
||||||
mergestages
|
mergestages gmstcheck
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_hdrs_noqt (model/tools
|
opencs_hdrs_noqt (model/tools
|
||||||
|
@ -94,7 +94,7 @@ opencs_units_noqt (view/render
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_hdrs_noqt (view/render
|
opencs_hdrs_noqt (view/render
|
||||||
elements
|
mask
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,31 +106,16 @@ opencs_units_noqt (view/tools
|
||||||
subviews
|
subviews
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units (view/settings
|
opencs_units (view/prefs
|
||||||
settingwindow
|
dialogue pagebase page
|
||||||
dialog
|
|
||||||
page
|
|
||||||
view
|
|
||||||
booleanview
|
|
||||||
textview
|
|
||||||
listview
|
|
||||||
rangeview
|
|
||||||
resizeablestackedwidget
|
|
||||||
spinbox
|
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (view/settings
|
opencs_units (model/prefs
|
||||||
frame
|
state setting intsetting doublesetting boolsetting enumsetting coloursetting
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units (model/settings
|
opencs_units_noqt (model/prefs
|
||||||
usersettings
|
category
|
||||||
setting
|
|
||||||
connector
|
|
||||||
)
|
|
||||||
|
|
||||||
opencs_hdrs_noqt (model/settings
|
|
||||||
support
|
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (model/filter
|
opencs_units_noqt (model/filter
|
||||||
|
@ -205,7 +190,13 @@ if(APPLE)
|
||||||
endif(APPLE)
|
endif(APPLE)
|
||||||
|
|
||||||
target_link_libraries(openmw-cs
|
target_link_libraries(openmw-cs
|
||||||
${OPENSCENEGRAPH_LIBRARIES}
|
${OSG_LIBRARIES}
|
||||||
|
${OPENTHREADS_LIBRARIES}
|
||||||
|
${OSGUTIL_LIBRARIES}
|
||||||
|
${OSGVIEWER_LIBRARIES}
|
||||||
|
${OSGGA_LIBRARIES}
|
||||||
|
${OSGFX_LIBRARIES}
|
||||||
|
${OSGQT_LIBRARIES}
|
||||||
${Boost_SYSTEM_LIBRARY}
|
${Boost_SYSTEM_LIBRARY}
|
||||||
${Boost_FILESYSTEM_LIBRARY}
|
${Boost_FILESYSTEM_LIBRARY}
|
||||||
${Boost_PROGRAM_OPTIONS_LIBRARY}
|
${Boost_PROGRAM_OPTIONS_LIBRARY}
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#include <components/vfs/manager.hpp>
|
#include <components/vfs/manager.hpp>
|
||||||
#include <components/vfs/registerarchives.hpp>
|
#include <components/vfs/registerarchives.hpp>
|
||||||
|
|
||||||
|
#include <components/fallback/validate.hpp>
|
||||||
|
|
||||||
#include <components/nifosg/nifloader.hpp>
|
#include <components/nifosg/nifloader.hpp>
|
||||||
|
|
||||||
#include "model/doc/document.hpp"
|
#include "model/doc/document.hpp"
|
||||||
|
@ -17,8 +19,10 @@
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
using namespace Fallback;
|
||||||
|
|
||||||
CS::Editor::Editor ()
|
CS::Editor::Editor ()
|
||||||
: mUserSettings (mCfgMgr), mDocumentManager (mCfgMgr),
|
: mSettingsState (mCfgMgr), mDocumentManager (mCfgMgr),
|
||||||
mViewManager (mDocumentManager), mPid(""),
|
mViewManager (mDocumentManager), mPid(""),
|
||||||
mLock(), mMerge (mDocumentManager),
|
mLock(), mMerge (mDocumentManager),
|
||||||
mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL)
|
mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL)
|
||||||
|
@ -27,9 +31,6 @@ CS::Editor::Editor ()
|
||||||
|
|
||||||
setupDataFiles (config.first);
|
setupDataFiles (config.first);
|
||||||
|
|
||||||
CSMSettings::UserSettings::instance().loadSettings ("opencs.ini");
|
|
||||||
mSettings.setModel (CSMSettings::UserSettings::instance());
|
|
||||||
|
|
||||||
NifOsg::Loader::setShowMarkers(true);
|
NifOsg::Loader::setShowMarkers(true);
|
||||||
|
|
||||||
mVFS.reset(new VFS::Manager(mFsStrict));
|
mVFS.reset(new VFS::Manager(mFsStrict));
|
||||||
|
@ -103,6 +104,8 @@ std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfi
|
||||||
("resources", boost::program_options::value<std::string>()->default_value("resources"))
|
("resources", boost::program_options::value<std::string>()->default_value("resources"))
|
||||||
("fallback-archive", boost::program_options::value<std::vector<std::string> >()->
|
("fallback-archive", boost::program_options::value<std::vector<std::string> >()->
|
||||||
default_value(std::vector<std::string>(), "fallback-archive")->multitoken())
|
default_value(std::vector<std::string>(), "fallback-archive")->multitoken())
|
||||||
|
("fallback", boost::program_options::value<FallbackMap>()->default_value(FallbackMap(), "")
|
||||||
|
->multitoken()->composing(), "fallback values")
|
||||||
("script-blacklist", boost::program_options::value<std::vector<std::string> >()->default_value(std::vector<std::string>(), "")
|
("script-blacklist", boost::program_options::value<std::vector<std::string> >()->default_value(std::vector<std::string>(), "")
|
||||||
->multitoken(), "exclude specified script from the verifier (if the use of the blacklist is enabled)")
|
->multitoken(), "exclude specified script from the verifier (if the use of the blacklist is enabled)")
|
||||||
("script-blacklist-use", boost::program_options::value<bool>()->implicit_value(true)
|
("script-blacklist-use", boost::program_options::value<bool>()->implicit_value(true)
|
||||||
|
@ -117,6 +120,8 @@ std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfi
|
||||||
|
|
||||||
mDocumentManager.setResourceDir (mResources = variables["resources"].as<std::string>());
|
mDocumentManager.setResourceDir (mResources = variables["resources"].as<std::string>());
|
||||||
|
|
||||||
|
mDocumentManager.setFallbackMap (variables["fallback"].as<FallbackMap>().mMap);
|
||||||
|
|
||||||
if (variables["script-blacklist-use"].as<bool>())
|
if (variables["script-blacklist-use"].as<bool>())
|
||||||
mDocumentManager.setBlacklistedScripts (
|
mDocumentManager.setBlacklistedScripts (
|
||||||
variables["script-blacklist"].as<std::vector<std::string> >());
|
variables["script-blacklist"].as<std::vector<std::string> >());
|
||||||
|
|
|
@ -17,15 +17,16 @@
|
||||||
|
|
||||||
#include <components/files/multidircollection.hpp>
|
#include <components/files/multidircollection.hpp>
|
||||||
|
|
||||||
#include "model/settings/usersettings.hpp"
|
|
||||||
#include "model/doc/documentmanager.hpp"
|
#include "model/doc/documentmanager.hpp"
|
||||||
|
|
||||||
|
#include "model/prefs/state.hpp"
|
||||||
|
|
||||||
#include "view/doc/viewmanager.hpp"
|
#include "view/doc/viewmanager.hpp"
|
||||||
#include "view/doc/startup.hpp"
|
#include "view/doc/startup.hpp"
|
||||||
#include "view/doc/filedialog.hpp"
|
#include "view/doc/filedialog.hpp"
|
||||||
#include "view/doc/newgame.hpp"
|
#include "view/doc/newgame.hpp"
|
||||||
|
|
||||||
#include "view/settings/dialog.hpp"
|
#include "view/prefs/dialogue.hpp"
|
||||||
|
|
||||||
#include "view/tools/merge.hpp"
|
#include "view/tools/merge.hpp"
|
||||||
|
|
||||||
|
@ -49,12 +50,12 @@ namespace CS
|
||||||
std::auto_ptr<VFS::Manager> mVFS;
|
std::auto_ptr<VFS::Manager> mVFS;
|
||||||
|
|
||||||
Files::ConfigurationManager mCfgMgr;
|
Files::ConfigurationManager mCfgMgr;
|
||||||
CSMSettings::UserSettings mUserSettings;
|
CSMPrefs::State mSettingsState;
|
||||||
CSMDoc::DocumentManager mDocumentManager;
|
CSMDoc::DocumentManager mDocumentManager;
|
||||||
CSVDoc::ViewManager mViewManager;
|
CSVDoc::ViewManager mViewManager;
|
||||||
CSVDoc::StartupDialogue mStartup;
|
CSVDoc::StartupDialogue mStartup;
|
||||||
CSVDoc::NewGameDialogue mNewGame;
|
CSVDoc::NewGameDialogue mNewGame;
|
||||||
CSVSettings::Dialog mSettings;
|
CSVPrefs::Dialogue mSettings;
|
||||||
CSVDoc::FileDialog mFileDialog;
|
CSVDoc::FileDialog mFileDialog;
|
||||||
boost::filesystem::path mLocal;
|
boost::filesystem::path mLocal;
|
||||||
boost::filesystem::path mResources;
|
boost::filesystem::path mResources;
|
||||||
|
|
|
@ -43,6 +43,10 @@ class Application : public QApplication
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
setenv("OSG_GL_TEXTURE_STORAGE", "OFF", 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// To allow background thread drawing in OSG
|
// To allow background thread drawing in OSG
|
||||||
|
@ -64,15 +68,6 @@ int main(int argc, char *argv[])
|
||||||
dir.cdUp();
|
dir.cdUp();
|
||||||
}
|
}
|
||||||
QDir::setCurrent(dir.absolutePath());
|
QDir::setCurrent(dir.absolutePath());
|
||||||
|
|
||||||
// force Qt to load only LOCAL plugins, don't touch system Qt installation
|
|
||||||
QDir pluginsPath(QCoreApplication::applicationDirPath());
|
|
||||||
pluginsPath.cdUp();
|
|
||||||
pluginsPath.cd("Plugins");
|
|
||||||
|
|
||||||
QStringList libraryPaths;
|
|
||||||
libraryPaths << pluginsPath.path() << QCoreApplication::applicationDirPath();
|
|
||||||
application.setLibraryPaths(libraryPaths);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
application.setWindowIcon (QIcon (":./openmw-cs.png"));
|
application.setWindowIcon (QIcon (":./openmw-cs.png"));
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -25,9 +25,13 @@
|
||||||
|
|
||||||
class QAbstractItemModel;
|
class QAbstractItemModel;
|
||||||
|
|
||||||
|
namespace Fallback
|
||||||
|
{
|
||||||
|
class Map;
|
||||||
|
}
|
||||||
|
|
||||||
namespace VFS
|
namespace VFS
|
||||||
{
|
{
|
||||||
|
|
||||||
class Manager;
|
class Manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +70,7 @@ namespace CSMDoc
|
||||||
Saving mSavingOperation;
|
Saving mSavingOperation;
|
||||||
OperationHolder mSaving;
|
OperationHolder mSaving;
|
||||||
boost::filesystem::path mResDir;
|
boost::filesystem::path mResDir;
|
||||||
|
const Fallback::Map* mFallbackMap;
|
||||||
Blacklist mBlacklist;
|
Blacklist mBlacklist;
|
||||||
Runner mRunner;
|
Runner mRunner;
|
||||||
bool mDirty;
|
bool mDirty;
|
||||||
|
@ -101,6 +106,7 @@ namespace CSMDoc
|
||||||
Document (const VFS::Manager* vfs, const Files::ConfigurationManager& configuration,
|
Document (const VFS::Manager* vfs, const Files::ConfigurationManager& configuration,
|
||||||
const std::vector< boost::filesystem::path >& files, bool new_,
|
const std::vector< boost::filesystem::path >& files, bool new_,
|
||||||
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir,
|
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir,
|
||||||
|
const Fallback::Map* fallback,
|
||||||
ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager,
|
ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager,
|
||||||
const std::vector<std::string>& blacklistedScripts);
|
const std::vector<std::string>& blacklistedScripts);
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ CSMDoc::Document *CSMDoc::DocumentManager::makeDocument (
|
||||||
const std::vector< boost::filesystem::path >& files,
|
const std::vector< boost::filesystem::path >& files,
|
||||||
const boost::filesystem::path& savePath, bool new_)
|
const boost::filesystem::path& savePath, bool new_)
|
||||||
{
|
{
|
||||||
return new Document (mVFS, mConfiguration, files, new_, savePath, mResDir, mEncoding, mResourcesManager, mBlacklistedScripts);
|
return new Document (mVFS, mConfiguration, files, new_, savePath, mResDir, &mFallbackMap, mEncoding, mResourcesManager, mBlacklistedScripts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMDoc::DocumentManager::insertDocument (CSMDoc::Document *document)
|
void CSMDoc::DocumentManager::insertDocument (CSMDoc::Document *document)
|
||||||
|
@ -100,6 +100,11 @@ void CSMDoc::DocumentManager::setResourceDir (const boost::filesystem::path& par
|
||||||
mResDir = boost::filesystem::system_complete(parResDir);
|
mResDir = boost::filesystem::system_complete(parResDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSMDoc::DocumentManager::setFallbackMap(const std::map<std::string, std::string>& fallbackMap)
|
||||||
|
{
|
||||||
|
mFallbackMap = Fallback::Map(fallbackMap);
|
||||||
|
}
|
||||||
|
|
||||||
void CSMDoc::DocumentManager::setEncoding (ToUTF8::FromType encoding)
|
void CSMDoc::DocumentManager::setEncoding (ToUTF8::FromType encoding)
|
||||||
{
|
{
|
||||||
mEncoding = encoding;
|
mEncoding = encoding;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
#include <components/to_utf8/to_utf8.hpp>
|
#include <components/to_utf8/to_utf8.hpp>
|
||||||
|
#include <components/fallback/fallback.hpp>
|
||||||
|
|
||||||
#include "../world/resourcesmanager.hpp"
|
#include "../world/resourcesmanager.hpp"
|
||||||
|
|
||||||
|
@ -67,6 +68,8 @@ namespace CSMDoc
|
||||||
|
|
||||||
void setResourceDir (const boost::filesystem::path& parResDir);
|
void setResourceDir (const boost::filesystem::path& parResDir);
|
||||||
|
|
||||||
|
void setFallbackMap (const std::map<std::string, std::string>& fallbackMap);
|
||||||
|
|
||||||
void setEncoding (ToUTF8::FromType encoding);
|
void setEncoding (ToUTF8::FromType encoding);
|
||||||
|
|
||||||
void setBlacklistedScripts (const std::vector<std::string>& scriptIds);
|
void setBlacklistedScripts (const std::vector<std::string>& scriptIds);
|
||||||
|
@ -78,6 +81,7 @@ namespace CSMDoc
|
||||||
private:
|
private:
|
||||||
|
|
||||||
boost::filesystem::path mResDir;
|
boost::filesystem::path mResDir;
|
||||||
|
Fallback::Map mFallbackMap;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
|
|
|
@ -45,13 +45,12 @@ void CSMDoc::Loader::load()
|
||||||
|
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
|
||||||
const int batchingSize = 50;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (iter->second.mRecordsLeft)
|
if (iter->second.mRecordsLeft)
|
||||||
{
|
{
|
||||||
Messages messages (Message::Severity_Error);
|
Messages messages (Message::Severity_Error);
|
||||||
|
const int batchingSize = 50;
|
||||||
for (int i=0; i<batchingSize; ++i) // do not flood the system with update signals
|
for (int i=0; i<batchingSize; ++i) // do not flood the system with update signals
|
||||||
if (document->getData().continueLoading (messages))
|
if (document->getData().continueLoading (messages))
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include "../world/universalid.hpp"
|
#include "../world/universalid.hpp"
|
||||||
#include "../settings/usersettings.hpp"
|
|
||||||
|
|
||||||
#include "state.hpp"
|
#include "state.hpp"
|
||||||
#include "stage.hpp"
|
#include "stage.hpp"
|
||||||
|
@ -23,9 +22,6 @@ void CSMDoc::Operation::prepareStages()
|
||||||
{
|
{
|
||||||
iter->second = iter->first->setup();
|
iter->second = iter->first->setup();
|
||||||
mTotalSteps += iter->second;
|
mTotalSteps += iter->second;
|
||||||
|
|
||||||
for (std::map<QString, QStringList>::const_iterator iter2 (mSettings.begin()); iter2!=mSettings.end(); ++iter2)
|
|
||||||
iter->first->updateUserSetting (iter2->first, iter2->second);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,14 +60,6 @@ void CSMDoc::Operation::appendStage (Stage *stage)
|
||||||
mStages.push_back (std::make_pair (stage, 0));
|
mStages.push_back (std::make_pair (stage, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMDoc::Operation::configureSettings (const std::vector<QString>& settings)
|
|
||||||
{
|
|
||||||
for (std::vector<QString>::const_iterator iter (settings.begin()); iter!=settings.end(); ++iter)
|
|
||||||
{
|
|
||||||
mSettings.insert (std::make_pair (*iter, CSMSettings::UserSettings::instance().definitions (*iter)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMDoc::Operation::setDefaultSeverity (Message::Severity severity)
|
void CSMDoc::Operation::setDefaultSeverity (Message::Severity severity)
|
||||||
{
|
{
|
||||||
mDefaultSeverity = severity;
|
mDefaultSeverity = severity;
|
||||||
|
@ -101,14 +89,6 @@ void CSMDoc::Operation::abort()
|
||||||
mCurrentStage = mStages.end();
|
mCurrentStage = mStages.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMDoc::Operation::updateUserSetting (const QString& name, const QStringList& value)
|
|
||||||
{
|
|
||||||
std::map<QString, QStringList>::iterator iter = mSettings.find (name);
|
|
||||||
|
|
||||||
if (iter!=mSettings.end())
|
|
||||||
iter->second = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMDoc::Operation::executeStage()
|
void CSMDoc::Operation::executeStage()
|
||||||
{
|
{
|
||||||
if (!mPrepared)
|
if (!mPrepared)
|
||||||
|
|
|
@ -34,7 +34,6 @@ namespace CSMDoc
|
||||||
bool mError;
|
bool mError;
|
||||||
bool mConnected;
|
bool mConnected;
|
||||||
QTimer *mTimer;
|
QTimer *mTimer;
|
||||||
std::map<QString, QStringList> mSettings;
|
|
||||||
bool mPrepared;
|
bool mPrepared;
|
||||||
Message::Severity mDefaultSeverity;
|
Message::Severity mDefaultSeverity;
|
||||||
|
|
||||||
|
@ -53,11 +52,6 @@ namespace CSMDoc
|
||||||
///
|
///
|
||||||
/// \attention Do no call this function while this Operation is running.
|
/// \attention Do no call this function while this Operation is running.
|
||||||
|
|
||||||
/// Specify settings to be passed on to stages.
|
|
||||||
///
|
|
||||||
/// \attention Do no call this function while this Operation is running.
|
|
||||||
void configureSettings (const std::vector<QString>& settings);
|
|
||||||
|
|
||||||
/// \attention Do no call this function while this Operation is running.
|
/// \attention Do no call this function while this Operation is running.
|
||||||
void setDefaultSeverity (Message::Severity severity);
|
void setDefaultSeverity (Message::Severity severity);
|
||||||
|
|
||||||
|
@ -77,8 +71,6 @@ namespace CSMDoc
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
void updateUserSetting (const QString& name, const QStringList& value);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void executeStage();
|
void executeStage();
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include "operationholder.hpp"
|
#include "operationholder.hpp"
|
||||||
|
|
||||||
#include "../settings/usersettings.hpp"
|
|
||||||
|
|
||||||
#include "operation.hpp"
|
#include "operation.hpp"
|
||||||
|
|
||||||
CSMDoc::OperationHolder::OperationHolder (Operation *operation) : mRunning (false)
|
CSMDoc::OperationHolder::OperationHolder (Operation *operation) : mRunning (false)
|
||||||
|
@ -30,9 +28,6 @@ void CSMDoc::OperationHolder::setOperation (Operation *operation)
|
||||||
connect (this, SIGNAL (abortSignal()), mOperation, SLOT (abort()));
|
connect (this, SIGNAL (abortSignal()), mOperation, SLOT (abort()));
|
||||||
|
|
||||||
connect (&mThread, SIGNAL (started()), mOperation, SLOT (run()));
|
connect (&mThread, SIGNAL (started()), mOperation, SLOT (run()));
|
||||||
|
|
||||||
connect (&CSMSettings::UserSettings::instance(), SIGNAL (userSettingUpdated (const QString&, const QStringList&)),
|
|
||||||
mOperation, SLOT (updateUserSetting (const QString&, const QStringList&)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSMDoc::OperationHolder::isRunning() const
|
bool CSMDoc::OperationHolder::isRunning() const
|
||||||
|
|
|
@ -99,84 +99,77 @@ int CSMDoc::WriteDialogueCollectionStage::setup()
|
||||||
|
|
||||||
void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& messages)
|
void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& messages)
|
||||||
{
|
{
|
||||||
|
ESM::ESMWriter& writer = mState.getWriter();
|
||||||
const CSMWorld::Record<ESM::Dialogue>& topic = mTopics.getRecord (stage);
|
const CSMWorld::Record<ESM::Dialogue>& topic = mTopics.getRecord (stage);
|
||||||
|
|
||||||
CSMWorld::RecordBase::State state = topic.mState;
|
if (topic.mState == CSMWorld::RecordBase::State_Deleted)
|
||||||
|
|
||||||
if (state==CSMWorld::RecordBase::State_Deleted)
|
|
||||||
{
|
{
|
||||||
// if the topic is deleted, we do not need to bother with INFO records.
|
// if the topic is deleted, we do not need to bother with INFO records.
|
||||||
|
ESM::Dialogue dialogue = topic.get();
|
||||||
/// \todo wrote record with delete flag
|
writer.startRecord(dialogue.sRecordId);
|
||||||
|
dialogue.save(writer, true);
|
||||||
|
writer.endRecord(dialogue.sRecordId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test, if we need to save anything associated info records.
|
// Test, if we need to save anything associated info records.
|
||||||
bool infoModified = false;
|
bool infoModified = false;
|
||||||
|
|
||||||
CSMWorld::InfoCollection::Range range = mInfos.getTopicRange (topic.get().mId);
|
CSMWorld::InfoCollection::Range range = mInfos.getTopicRange (topic.get().mId);
|
||||||
|
|
||||||
for (CSMWorld::InfoCollection::RecordConstIterator iter (range.first); iter!=range.second; ++iter)
|
for (CSMWorld::InfoCollection::RecordConstIterator iter (range.first); iter!=range.second; ++iter)
|
||||||
{
|
{
|
||||||
CSMWorld::RecordBase::State state = iter->mState;
|
if (iter->isModified() || iter->mState == CSMWorld::RecordBase::State_Deleted)
|
||||||
|
|
||||||
if (state==CSMWorld::RecordBase::State_Modified ||
|
|
||||||
state==CSMWorld::RecordBase::State_ModifiedOnly ||
|
|
||||||
state==CSMWorld::RecordBase::State_Deleted)
|
|
||||||
{
|
{
|
||||||
infoModified = true;
|
infoModified = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state==CSMWorld::RecordBase::State_Modified ||
|
if (topic.isModified() || infoModified)
|
||||||
state==CSMWorld::RecordBase::State_ModifiedOnly ||
|
|
||||||
infoModified)
|
|
||||||
{
|
{
|
||||||
mState.getWriter().startRecord (topic.mModified.sRecordId);
|
if (infoModified && topic.mState != CSMWorld::RecordBase::State_Modified
|
||||||
mState.getWriter().writeHNCString ("NAME", topic.mModified.mId);
|
&& topic.mState != CSMWorld::RecordBase::State_ModifiedOnly)
|
||||||
topic.mModified.save (mState.getWriter());
|
{
|
||||||
mState.getWriter().endRecord (topic.mModified.sRecordId);
|
mState.getWriter().startRecord (topic.mBase.sRecordId);
|
||||||
|
topic.mBase.save (mState.getWriter(), topic.mState == CSMWorld::RecordBase::State_Deleted);
|
||||||
|
mState.getWriter().endRecord (topic.mBase.sRecordId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mState.getWriter().startRecord (topic.mModified.sRecordId);
|
||||||
|
topic.mModified.save (mState.getWriter(), topic.mState == CSMWorld::RecordBase::State_Deleted);
|
||||||
|
mState.getWriter().endRecord (topic.mModified.sRecordId);
|
||||||
|
}
|
||||||
|
|
||||||
// write modified selected info records
|
// write modified selected info records
|
||||||
for (CSMWorld::InfoCollection::RecordConstIterator iter (range.first); iter!=range.second;
|
for (CSMWorld::InfoCollection::RecordConstIterator iter (range.first); iter!=range.second; ++iter)
|
||||||
++iter)
|
|
||||||
{
|
{
|
||||||
CSMWorld::RecordBase::State state = iter->mState;
|
if (iter->isModified() || iter->mState == CSMWorld::RecordBase::State_Deleted)
|
||||||
|
|
||||||
if (state==CSMWorld::RecordBase::State_Deleted)
|
|
||||||
{
|
|
||||||
/// \todo wrote record with delete flag
|
|
||||||
}
|
|
||||||
else if (state==CSMWorld::RecordBase::State_Modified ||
|
|
||||||
state==CSMWorld::RecordBase::State_ModifiedOnly)
|
|
||||||
{
|
{
|
||||||
ESM::DialInfo info = iter->get();
|
ESM::DialInfo info = iter->get();
|
||||||
info.mId = info.mId.substr (info.mId.find_last_of ('#')+1);
|
info.mId = info.mId.substr (info.mId.find_last_of ('#')+1);
|
||||||
|
|
||||||
|
info.mPrev = "";
|
||||||
if (iter!=range.first)
|
if (iter!=range.first)
|
||||||
{
|
{
|
||||||
CSMWorld::InfoCollection::RecordConstIterator prev = iter;
|
CSMWorld::InfoCollection::RecordConstIterator prev = iter;
|
||||||
--prev;
|
--prev;
|
||||||
|
|
||||||
info.mPrev =
|
info.mPrev = prev->get().mId.substr (prev->get().mId.find_last_of ('#')+1);
|
||||||
prev->mModified.mId.substr (prev->mModified.mId.find_last_of ('#')+1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::InfoCollection::RecordConstIterator next = iter;
|
CSMWorld::InfoCollection::RecordConstIterator next = iter;
|
||||||
++next;
|
++next;
|
||||||
|
|
||||||
|
info.mNext = "";
|
||||||
if (next!=range.second)
|
if (next!=range.second)
|
||||||
{
|
{
|
||||||
info.mNext =
|
info.mNext = next->get().mId.substr (next->get().mId.find_last_of ('#')+1);
|
||||||
next->mModified.mId.substr (next->mModified.mId.find_last_of ('#')+1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mState.getWriter().startRecord (info.sRecordId);
|
writer.startRecord (info.sRecordId);
|
||||||
mState.getWriter().writeHNCString ("INAM", info.mId);
|
info.save (writer, iter->mState == CSMWorld::RecordBase::State_Deleted);
|
||||||
info.save (mState.getWriter());
|
writer.endRecord (info.sRecordId);
|
||||||
mState.getWriter().endRecord (info.sRecordId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,9 +217,7 @@ void CSMDoc::CollectionReferencesStage::perform (int stage, Messages& messages)
|
||||||
const CSMWorld::Record<CSMWorld::CellRef>& record =
|
const CSMWorld::Record<CSMWorld::CellRef>& record =
|
||||||
mDocument.getData().getReferences().getRecord (i);
|
mDocument.getData().getReferences().getRecord (i);
|
||||||
|
|
||||||
if (record.mState==CSMWorld::RecordBase::State_Deleted ||
|
if (record.isModified() || record.mState == CSMWorld::RecordBase::State_Deleted)
|
||||||
record.mState==CSMWorld::RecordBase::State_Modified ||
|
|
||||||
record.mState==CSMWorld::RecordBase::State_ModifiedOnly)
|
|
||||||
{
|
{
|
||||||
std::string cellId = record.get().mOriginalCell.empty() ?
|
std::string cellId = record.get().mOriginalCell.empty() ?
|
||||||
record.get().mCell : record.get().mOriginalCell;
|
record.get().mCell : record.get().mOriginalCell;
|
||||||
|
@ -268,36 +259,34 @@ int CSMDoc::WriteCellCollectionStage::setup()
|
||||||
|
|
||||||
void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
|
void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<CSMWorld::Cell>& cell =
|
ESM::ESMWriter& writer = mState.getWriter();
|
||||||
mDocument.getData().getCells().getRecord (stage);
|
const CSMWorld::Record<CSMWorld::Cell>& cell = mDocument.getData().getCells().getRecord (stage);
|
||||||
|
|
||||||
std::map<std::string, std::deque<int> >::const_iterator references =
|
std::map<std::string, std::deque<int> >::const_iterator references =
|
||||||
mState.getSubRecords().find (Misc::StringUtils::lowerCase (cell.get().mId));
|
mState.getSubRecords().find (Misc::StringUtils::lowerCase (cell.get().mId));
|
||||||
|
|
||||||
if (cell.mState==CSMWorld::RecordBase::State_Modified ||
|
if (cell.isModified() ||
|
||||||
cell.mState==CSMWorld::RecordBase::State_ModifiedOnly ||
|
cell.mState == CSMWorld::RecordBase::State_Deleted ||
|
||||||
references!=mState.getSubRecords().end())
|
references!=mState.getSubRecords().end())
|
||||||
{
|
{
|
||||||
bool interior = cell.get().mId.substr (0, 1)!="#";
|
CSMWorld::Cell cellRecord = cell.get();
|
||||||
|
bool interior = cellRecord.mId.substr (0, 1)!="#";
|
||||||
|
|
||||||
// write cell data
|
// write cell data
|
||||||
mState.getWriter().startRecord (cell.mModified.sRecordId);
|
writer.startRecord (cellRecord.sRecordId);
|
||||||
|
|
||||||
mState.getWriter().writeHNOCString ("NAME", cell.get().mName);
|
|
||||||
|
|
||||||
ESM::Cell cell2 = cell.get();
|
|
||||||
|
|
||||||
if (interior)
|
if (interior)
|
||||||
cell2.mData.mFlags |= ESM::Cell::Interior;
|
cellRecord.mData.mFlags |= ESM::Cell::Interior;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cell2.mData.mFlags &= ~ESM::Cell::Interior;
|
cellRecord.mData.mFlags &= ~ESM::Cell::Interior;
|
||||||
|
|
||||||
std::istringstream stream (cell.get().mId.c_str());
|
std::istringstream stream (cellRecord.mId.c_str());
|
||||||
char ignore;
|
char ignore;
|
||||||
stream >> ignore >> cell2.mData.mX >> cell2.mData.mY;
|
stream >> ignore >> cellRecord.mData.mX >> cellRecord.mData.mY;
|
||||||
}
|
}
|
||||||
cell2.save (mState.getWriter());
|
|
||||||
|
cellRecord.save (writer, cell.mState == CSMWorld::RecordBase::State_Deleted);
|
||||||
|
|
||||||
// write references
|
// write references
|
||||||
if (references!=mState.getSubRecords().end())
|
if (references!=mState.getSubRecords().end())
|
||||||
|
@ -308,24 +297,25 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
|
||||||
const CSMWorld::Record<CSMWorld::CellRef>& ref =
|
const CSMWorld::Record<CSMWorld::CellRef>& ref =
|
||||||
mDocument.getData().getReferences().getRecord (*iter);
|
mDocument.getData().getReferences().getRecord (*iter);
|
||||||
|
|
||||||
if (ref.mState==CSMWorld::RecordBase::State_Modified ||
|
if (ref.isModified() || ref.mState == CSMWorld::RecordBase::State_Deleted)
|
||||||
ref.mState==CSMWorld::RecordBase::State_ModifiedOnly)
|
|
||||||
{
|
{
|
||||||
|
CSMWorld::CellRef refRecord = ref.get();
|
||||||
|
|
||||||
// recalculate the ref's cell location
|
// recalculate the ref's cell location
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
if (!interior)
|
if (!interior)
|
||||||
{
|
{
|
||||||
std::pair<int, int> index = ref.get().getCellIndex();
|
std::pair<int, int> index = refRecord.getCellIndex();
|
||||||
stream << "#" << index.first << " " << index.second;
|
stream << "#" << index.first << " " << index.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
// An empty mOriginalCell is meant to indicate that it is the same as
|
// An empty mOriginalCell is meant to indicate that it is the same as
|
||||||
// the current cell. It is possible that a moved ref is moved again.
|
// the current cell. It is possible that a moved ref is moved again.
|
||||||
if ((ref.get().mOriginalCell.empty() ? ref.get().mCell : ref.get().mOriginalCell)
|
if ((refRecord.mOriginalCell.empty() ? refRecord.mCell : refRecord.mOriginalCell)
|
||||||
!= stream.str() && !interior)
|
!= stream.str() && !interior)
|
||||||
{
|
{
|
||||||
ESM::MovedCellRef moved;
|
ESM::MovedCellRef moved;
|
||||||
moved.mRefNum = ref.get().mRefNum;
|
moved.mRefNum = refRecord.mRefNum;
|
||||||
|
|
||||||
// Need to fill mTarget with the ref's new position.
|
// Need to fill mTarget with the ref's new position.
|
||||||
std::istringstream istream (stream.str().c_str());
|
std::istringstream istream (stream.str().c_str());
|
||||||
|
@ -333,24 +323,16 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
|
||||||
char ignore;
|
char ignore;
|
||||||
istream >> ignore >> moved.mTarget[0] >> moved.mTarget[1];
|
istream >> ignore >> moved.mTarget[0] >> moved.mTarget[1];
|
||||||
|
|
||||||
ref.get().mRefNum.save (mState.getWriter(), false, "MVRF");
|
refRecord.mRefNum.save (writer, false, "MVRF");
|
||||||
mState.getWriter().writeHNT ("CNDT", moved.mTarget, 8);
|
writer.writeHNT ("CNDT", moved.mTarget, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
ref.get().save (mState.getWriter());
|
refRecord.save (writer, false, false, ref.mState == CSMWorld::RecordBase::State_Deleted);
|
||||||
}
|
|
||||||
else if (ref.mState==CSMWorld::RecordBase::State_Deleted)
|
|
||||||
{
|
|
||||||
/// \todo write record with delete flag
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mState.getWriter().endRecord (cell.mModified.sRecordId);
|
writer.endRecord (cellRecord.sRecordId);
|
||||||
}
|
|
||||||
else if (cell.mState==CSMWorld::RecordBase::State_Deleted)
|
|
||||||
{
|
|
||||||
/// \todo write record with delete flag
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,11 +349,11 @@ int CSMDoc::WritePathgridCollectionStage::setup()
|
||||||
|
|
||||||
void CSMDoc::WritePathgridCollectionStage::perform (int stage, Messages& messages)
|
void CSMDoc::WritePathgridCollectionStage::perform (int stage, Messages& messages)
|
||||||
{
|
{
|
||||||
|
ESM::ESMWriter& writer = mState.getWriter();
|
||||||
const CSMWorld::Record<CSMWorld::Pathgrid>& pathgrid =
|
const CSMWorld::Record<CSMWorld::Pathgrid>& pathgrid =
|
||||||
mDocument.getData().getPathgrids().getRecord (stage);
|
mDocument.getData().getPathgrids().getRecord (stage);
|
||||||
|
|
||||||
if (pathgrid.mState==CSMWorld::RecordBase::State_Modified ||
|
if (pathgrid.isModified() || pathgrid.mState == CSMWorld::RecordBase::State_Deleted)
|
||||||
pathgrid.mState==CSMWorld::RecordBase::State_ModifiedOnly)
|
|
||||||
{
|
{
|
||||||
CSMWorld::Pathgrid record = pathgrid.get();
|
CSMWorld::Pathgrid record = pathgrid.get();
|
||||||
|
|
||||||
|
@ -384,15 +366,9 @@ void CSMDoc::WritePathgridCollectionStage::perform (int stage, Messages& message
|
||||||
else
|
else
|
||||||
record.mCell = record.mId;
|
record.mCell = record.mId;
|
||||||
|
|
||||||
mState.getWriter().startRecord (record.sRecordId);
|
writer.startRecord (record.sRecordId);
|
||||||
|
record.save (writer, pathgrid.mState == CSMWorld::RecordBase::State_Deleted);
|
||||||
record.save (mState.getWriter());
|
writer.endRecord (record.sRecordId);
|
||||||
|
|
||||||
mState.getWriter().endRecord (record.sRecordId);
|
|
||||||
}
|
|
||||||
else if (pathgrid.mState==CSMWorld::RecordBase::State_Deleted)
|
|
||||||
{
|
|
||||||
/// \todo write record with delete flag
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,26 +385,16 @@ int CSMDoc::WriteLandCollectionStage::setup()
|
||||||
|
|
||||||
void CSMDoc::WriteLandCollectionStage::perform (int stage, Messages& messages)
|
void CSMDoc::WriteLandCollectionStage::perform (int stage, Messages& messages)
|
||||||
{
|
{
|
||||||
|
ESM::ESMWriter& writer = mState.getWriter();
|
||||||
const CSMWorld::Record<CSMWorld::Land>& land =
|
const CSMWorld::Record<CSMWorld::Land>& land =
|
||||||
mDocument.getData().getLand().getRecord (stage);
|
mDocument.getData().getLand().getRecord (stage);
|
||||||
|
|
||||||
if (land.mState==CSMWorld::RecordBase::State_Modified ||
|
if (land.isModified() || land.mState == CSMWorld::RecordBase::State_Deleted)
|
||||||
land.mState==CSMWorld::RecordBase::State_ModifiedOnly)
|
|
||||||
{
|
{
|
||||||
const CSMWorld::Land& record = land.get();
|
CSMWorld::Land record = land.get();
|
||||||
|
writer.startRecord (record.sRecordId);
|
||||||
mState.getWriter().startRecord (record.sRecordId);
|
record.save (writer, land.mState == CSMWorld::RecordBase::State_Deleted);
|
||||||
|
writer.endRecord (record.sRecordId);
|
||||||
record.save (mState.getWriter());
|
|
||||||
|
|
||||||
if (const ESM::Land::LandData *data = record.getLandData (record.mDataTypes))
|
|
||||||
data->save (mState.getWriter());
|
|
||||||
|
|
||||||
mState.getWriter().endRecord (record.sRecordId);
|
|
||||||
}
|
|
||||||
else if (land.mState==CSMWorld::RecordBase::State_Deleted)
|
|
||||||
{
|
|
||||||
/// \todo write record with delete flag
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,25 +411,16 @@ int CSMDoc::WriteLandTextureCollectionStage::setup()
|
||||||
|
|
||||||
void CSMDoc::WriteLandTextureCollectionStage::perform (int stage, Messages& messages)
|
void CSMDoc::WriteLandTextureCollectionStage::perform (int stage, Messages& messages)
|
||||||
{
|
{
|
||||||
|
ESM::ESMWriter& writer = mState.getWriter();
|
||||||
const CSMWorld::Record<CSMWorld::LandTexture>& landTexture =
|
const CSMWorld::Record<CSMWorld::LandTexture>& landTexture =
|
||||||
mDocument.getData().getLandTextures().getRecord (stage);
|
mDocument.getData().getLandTextures().getRecord (stage);
|
||||||
|
|
||||||
if (landTexture.mState==CSMWorld::RecordBase::State_Modified ||
|
if (landTexture.isModified() || landTexture.mState == CSMWorld::RecordBase::State_Deleted)
|
||||||
landTexture.mState==CSMWorld::RecordBase::State_ModifiedOnly)
|
|
||||||
{
|
{
|
||||||
CSMWorld::LandTexture record = landTexture.get();
|
CSMWorld::LandTexture record = landTexture.get();
|
||||||
|
writer.startRecord (record.sRecordId);
|
||||||
mState.getWriter().startRecord (record.sRecordId);
|
record.save (writer, landTexture.mState == CSMWorld::RecordBase::State_Deleted);
|
||||||
|
writer.endRecord (record.sRecordId);
|
||||||
mState.getWriter().writeHNString("NAME", record.mId);
|
|
||||||
|
|
||||||
record.save (mState.getWriter());
|
|
||||||
|
|
||||||
mState.getWriter().endRecord (record.sRecordId);
|
|
||||||
}
|
|
||||||
else if (landTexture.mState==CSMWorld::RecordBase::State_Deleted)
|
|
||||||
{
|
|
||||||
/// \todo write record with delete flag
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,26 +100,17 @@ namespace CSMDoc
|
||||||
if (CSMWorld::getScopeFromId (mCollection.getRecord (stage).get().mId)!=mScope)
|
if (CSMWorld::getScopeFromId (mCollection.getRecord (stage).get().mId)!=mScope)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ESM::ESMWriter& writer = mState.getWriter();
|
||||||
CSMWorld::RecordBase::State state = mCollection.getRecord (stage).mState;
|
CSMWorld::RecordBase::State state = mCollection.getRecord (stage).mState;
|
||||||
|
typename CollectionT::ESXRecord record = mCollection.getRecord (stage).get();
|
||||||
|
|
||||||
if (state==CSMWorld::RecordBase::State_Modified ||
|
if (state == CSMWorld::RecordBase::State_Modified ||
|
||||||
state==CSMWorld::RecordBase::State_ModifiedOnly)
|
state == CSMWorld::RecordBase::State_ModifiedOnly ||
|
||||||
|
state == CSMWorld::RecordBase::State_Deleted)
|
||||||
{
|
{
|
||||||
// FIXME: A quick Workaround to support records which should not write
|
writer.startRecord (record.sRecordId);
|
||||||
// NAME, including SKIL, MGEF and SCPT. If there are many more
|
record.save (writer, state == CSMWorld::RecordBase::State_Deleted);
|
||||||
// idcollection records that doesn't use NAME then a more generic
|
writer.endRecord (record.sRecordId);
|
||||||
// solution may be required.
|
|
||||||
uint32_t name = mCollection.getRecord (stage).mModified.sRecordId;
|
|
||||||
mState.getWriter().startRecord (name);
|
|
||||||
|
|
||||||
if(name != ESM::REC_SKIL && name != ESM::REC_MGEF && name != ESM::REC_SCPT)
|
|
||||||
mState.getWriter().writeHNCString ("NAME", mCollection.getId (stage));
|
|
||||||
mCollection.getRecord (stage).mModified.save (mState.getWriter());
|
|
||||||
mState.getWriter().endRecord (mCollection.getRecord (stage).mModified.sRecordId);
|
|
||||||
}
|
|
||||||
else if (state==CSMWorld::RecordBase::State_Deleted)
|
|
||||||
{
|
|
||||||
/// \todo write record with delete flag
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#include "stage.hpp"
|
#include "stage.hpp"
|
||||||
|
|
||||||
CSMDoc::Stage::~Stage() {}
|
CSMDoc::Stage::~Stage() {}
|
||||||
|
|
||||||
void CSMDoc::Stage::updateUserSetting (const QString& name, const QStringList& value) {}
|
|
||||||
|
|
|
@ -23,11 +23,7 @@ namespace CSMDoc
|
||||||
|
|
||||||
virtual void perform (int stage, Messages& messages) = 0;
|
virtual void perform (int stage, Messages& messages) = 0;
|
||||||
///< Messages resulting from this stage will be appended to \a messages.
|
///< Messages resulting from this stage will be appended to \a messages.
|
||||||
|
|
||||||
/// Default-implementation: ignore
|
|
||||||
virtual void updateUserSetting (const QString& name, const QStringList& value);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
47
apps/opencs/model/prefs/boolsetting.cpp
Normal file
47
apps/opencs/model/prefs/boolsetting.cpp
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
|
||||||
|
#include "boolsetting.hpp"
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QMutexLocker>
|
||||||
|
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
|
#include "category.hpp"
|
||||||
|
#include "state.hpp"
|
||||||
|
|
||||||
|
CSMPrefs::BoolSetting::BoolSetting (Category *parent, Settings::Manager *values,
|
||||||
|
QMutex *mutex, const std::string& key, const std::string& label, bool default_)
|
||||||
|
: Setting (parent, values, mutex, key, label), mDefault (default_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CSMPrefs::BoolSetting& CSMPrefs::BoolSetting::setTooltip (const std::string& tooltip)
|
||||||
|
{
|
||||||
|
mTooltip = tooltip;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<QWidget *, QWidget *> CSMPrefs::BoolSetting::makeWidgets (QWidget *parent)
|
||||||
|
{
|
||||||
|
QCheckBox *widget = new QCheckBox (QString::fromUtf8 (getLabel().c_str()), parent);
|
||||||
|
widget->setCheckState (mDefault ? Qt::Checked : Qt::Unchecked);
|
||||||
|
|
||||||
|
if (!mTooltip.empty())
|
||||||
|
{
|
||||||
|
QString tooltip = QString::fromUtf8 (mTooltip.c_str());
|
||||||
|
widget->setToolTip (tooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
connect (widget, SIGNAL (stateChanged (int)), this, SLOT (valueChanged (int)));
|
||||||
|
|
||||||
|
return std::make_pair (static_cast<QWidget *> (0), widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMPrefs::BoolSetting::valueChanged (int value)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
QMutexLocker lock (getMutex());
|
||||||
|
getValues().setBool (getKey(), getParent()->getKey(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
getParent()->getState()->update (*this);
|
||||||
|
}
|
31
apps/opencs/model/prefs/boolsetting.hpp
Normal file
31
apps/opencs/model/prefs/boolsetting.hpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef CSM_PREFS_BOOLSETTING_H
|
||||||
|
#define CSM_PREFS_BOOLSETTING_H
|
||||||
|
|
||||||
|
#include "setting.hpp"
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
class BoolSetting : public Setting
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
std::string mTooltip;
|
||||||
|
bool mDefault;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
BoolSetting (Category *parent, Settings::Manager *values,
|
||||||
|
QMutex *mutex, const std::string& key, const std::string& label, bool default_);
|
||||||
|
|
||||||
|
BoolSetting& setTooltip (const std::string& tooltip);
|
||||||
|
|
||||||
|
/// Return label, input widget.
|
||||||
|
virtual std::pair<QWidget *, QWidget *> makeWidgets (QWidget *parent);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void valueChanged (int value);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
51
apps/opencs/model/prefs/category.cpp
Normal file
51
apps/opencs/model/prefs/category.cpp
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
|
||||||
|
#include "category.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include "setting.hpp"
|
||||||
|
#include "state.hpp"
|
||||||
|
|
||||||
|
CSMPrefs::Category::Category (State *parent, const std::string& key)
|
||||||
|
: mParent (parent), mKey (key)
|
||||||
|
{}
|
||||||
|
|
||||||
|
const std::string& CSMPrefs::Category::getKey() const
|
||||||
|
{
|
||||||
|
return mKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::State *CSMPrefs::Category::getState() const
|
||||||
|
{
|
||||||
|
return mParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMPrefs::Category::addSetting (Setting *setting)
|
||||||
|
{
|
||||||
|
mSettings.push_back (setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::Category::Iterator CSMPrefs::Category::begin()
|
||||||
|
{
|
||||||
|
return mSettings.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::Category::Iterator CSMPrefs::Category::end()
|
||||||
|
{
|
||||||
|
return mSettings.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::Setting& CSMPrefs::Category::operator[] (const std::string& key)
|
||||||
|
{
|
||||||
|
for (Iterator iter = mSettings.begin(); iter!=mSettings.end(); ++iter)
|
||||||
|
if ((*iter)->getKey()==key)
|
||||||
|
return **iter;
|
||||||
|
|
||||||
|
throw std::logic_error ("Invalid user setting: " + key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMPrefs::Category::update()
|
||||||
|
{
|
||||||
|
for (Iterator iter = mSettings.begin(); iter!=mSettings.end(); ++iter)
|
||||||
|
mParent->update (**iter);
|
||||||
|
}
|
45
apps/opencs/model/prefs/category.hpp
Normal file
45
apps/opencs/model/prefs/category.hpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef CSM_PREFS_CATEGORY_H
|
||||||
|
#define CSM_PREFS_CATEGORY_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
class State;
|
||||||
|
class Setting;
|
||||||
|
|
||||||
|
class Category
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef std::vector<Setting *> Container;
|
||||||
|
typedef Container::iterator Iterator;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
State *mParent;
|
||||||
|
std::string mKey;
|
||||||
|
Container mSettings;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Category (State *parent, const std::string& key);
|
||||||
|
|
||||||
|
const std::string& getKey() const;
|
||||||
|
|
||||||
|
State *getState() const;
|
||||||
|
|
||||||
|
void addSetting (Setting *setting);
|
||||||
|
|
||||||
|
Iterator begin();
|
||||||
|
|
||||||
|
Iterator end();
|
||||||
|
|
||||||
|
Setting& operator[] (const std::string& key);
|
||||||
|
|
||||||
|
void update();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
52
apps/opencs/model/prefs/coloursetting.cpp
Normal file
52
apps/opencs/model/prefs/coloursetting.cpp
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
|
||||||
|
#include "coloursetting.hpp"
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QMutexLocker>
|
||||||
|
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
|
#include "../../view/widget/coloreditor.hpp"
|
||||||
|
|
||||||
|
#include "category.hpp"
|
||||||
|
#include "state.hpp"
|
||||||
|
|
||||||
|
CSMPrefs::ColourSetting::ColourSetting (Category *parent, Settings::Manager *values,
|
||||||
|
QMutex *mutex, const std::string& key, const std::string& label, QColor default_)
|
||||||
|
: Setting (parent, values, mutex, key, label), mDefault (default_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CSMPrefs::ColourSetting& CSMPrefs::ColourSetting::setTooltip (const std::string& tooltip)
|
||||||
|
{
|
||||||
|
mTooltip = tooltip;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<QWidget *, QWidget *> CSMPrefs::ColourSetting::makeWidgets (QWidget *parent)
|
||||||
|
{
|
||||||
|
QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent);
|
||||||
|
|
||||||
|
CSVWidget::ColorEditor *widget = new CSVWidget::ColorEditor (mDefault, parent);
|
||||||
|
|
||||||
|
if (!mTooltip.empty())
|
||||||
|
{
|
||||||
|
QString tooltip = QString::fromUtf8 (mTooltip.c_str());
|
||||||
|
label->setToolTip (tooltip);
|
||||||
|
widget->setToolTip (tooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
connect (widget, SIGNAL (pickingFinished()), this, SLOT (valueChanged()));
|
||||||
|
|
||||||
|
return std::make_pair (label, widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMPrefs::ColourSetting::valueChanged()
|
||||||
|
{
|
||||||
|
CSVWidget::ColorEditor& widget = dynamic_cast<CSVWidget::ColorEditor&> (*sender());
|
||||||
|
{
|
||||||
|
QMutexLocker lock (getMutex());
|
||||||
|
getValues().setString (getKey(), getParent()->getKey(), widget.color().name().toUtf8().data());
|
||||||
|
}
|
||||||
|
|
||||||
|
getParent()->getState()->update (*this);
|
||||||
|
}
|
34
apps/opencs/model/prefs/coloursetting.hpp
Normal file
34
apps/opencs/model/prefs/coloursetting.hpp
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef CSM_PREFS_COLOURSETTING_H
|
||||||
|
#define CSM_PREFS_COLOURSETTING_H
|
||||||
|
|
||||||
|
#include "setting.hpp"
|
||||||
|
|
||||||
|
#include <QColor>
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
class ColourSetting : public Setting
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
std::string mTooltip;
|
||||||
|
QColor mDefault;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ColourSetting (Category *parent, Settings::Manager *values,
|
||||||
|
QMutex *mutex, const std::string& key, const std::string& label,
|
||||||
|
QColor default_);
|
||||||
|
|
||||||
|
ColourSetting& setTooltip (const std::string& tooltip);
|
||||||
|
|
||||||
|
/// Return label, input widget.
|
||||||
|
virtual std::pair<QWidget *, QWidget *> makeWidgets (QWidget *parent);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void valueChanged();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
75
apps/opencs/model/prefs/doublesetting.cpp
Normal file
75
apps/opencs/model/prefs/doublesetting.cpp
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
|
||||||
|
#include "doublesetting.hpp"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
#include <QMutexLocker>
|
||||||
|
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
|
#include "category.hpp"
|
||||||
|
#include "state.hpp"
|
||||||
|
|
||||||
|
CSMPrefs::DoubleSetting::DoubleSetting (Category *parent, Settings::Manager *values,
|
||||||
|
QMutex *mutex, const std::string& key, const std::string& label, double default_)
|
||||||
|
: Setting (parent, values, mutex, key, label),
|
||||||
|
mMin (0), mMax (std::numeric_limits<double>::max()),
|
||||||
|
mDefault (default_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setRange (double min, double max)
|
||||||
|
{
|
||||||
|
mMin = min;
|
||||||
|
mMax = max;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setMin (double min)
|
||||||
|
{
|
||||||
|
mMin = min;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setMax (double max)
|
||||||
|
{
|
||||||
|
mMax = max;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setTooltip (const std::string& tooltip)
|
||||||
|
{
|
||||||
|
mTooltip = tooltip;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<QWidget *, QWidget *> CSMPrefs::DoubleSetting::makeWidgets (QWidget *parent)
|
||||||
|
{
|
||||||
|
QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent);
|
||||||
|
|
||||||
|
QDoubleSpinBox *widget = new QDoubleSpinBox (parent);
|
||||||
|
widget->setRange (mMin, mMax);
|
||||||
|
widget->setValue (mDefault);
|
||||||
|
|
||||||
|
if (!mTooltip.empty())
|
||||||
|
{
|
||||||
|
QString tooltip = QString::fromUtf8 (mTooltip.c_str());
|
||||||
|
label->setToolTip (tooltip);
|
||||||
|
widget->setToolTip (tooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
connect (widget, SIGNAL (valueChanged (double)), this, SLOT (valueChanged (double)));
|
||||||
|
|
||||||
|
return std::make_pair (label, widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMPrefs::DoubleSetting::valueChanged (double value)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
QMutexLocker lock (getMutex());
|
||||||
|
getValues().setFloat (getKey(), getParent()->getKey(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
getParent()->getState()->update (*this);
|
||||||
|
}
|
41
apps/opencs/model/prefs/doublesetting.hpp
Normal file
41
apps/opencs/model/prefs/doublesetting.hpp
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#ifndef CSM_PREFS_DOUBLESETTING_H
|
||||||
|
#define CSM_PREFS_DOUBLESETTING_H
|
||||||
|
|
||||||
|
#include "setting.hpp"
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
class DoubleSetting : public Setting
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
double mMin;
|
||||||
|
double mMax;
|
||||||
|
std::string mTooltip;
|
||||||
|
double mDefault;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DoubleSetting (Category *parent, Settings::Manager *values,
|
||||||
|
QMutex *mutex, const std::string& key, const std::string& label,
|
||||||
|
double default_);
|
||||||
|
|
||||||
|
// defaults to [0, std::numeric_limits<double>::max()]
|
||||||
|
DoubleSetting& setRange (double min, double max);
|
||||||
|
|
||||||
|
DoubleSetting& setMin (double min);
|
||||||
|
|
||||||
|
DoubleSetting& setMax (double max);
|
||||||
|
|
||||||
|
DoubleSetting& setTooltip (const std::string& tooltip);
|
||||||
|
|
||||||
|
/// Return label, input widget.
|
||||||
|
virtual std::pair<QWidget *, QWidget *> makeWidgets (QWidget *parent);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void valueChanged (double value);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
112
apps/opencs/model/prefs/enumsetting.cpp
Normal file
112
apps/opencs/model/prefs/enumsetting.cpp
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
|
||||||
|
#include "enumsetting.hpp"
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QMutexLocker>
|
||||||
|
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
|
#include "category.hpp"
|
||||||
|
#include "state.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
CSMPrefs::EnumValue::EnumValue (const std::string& value, const std::string& tooltip)
|
||||||
|
: mValue (value), mTooltip (tooltip)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CSMPrefs::EnumValue::EnumValue (const char *value)
|
||||||
|
: mValue (value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
CSMPrefs::EnumValues& CSMPrefs::EnumValues::add (const EnumValues& values)
|
||||||
|
{
|
||||||
|
mValues.insert (mValues.end(), values.mValues.begin(), values.mValues.end());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::EnumValues& CSMPrefs::EnumValues::add (const EnumValue& value)
|
||||||
|
{
|
||||||
|
mValues.push_back (value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::EnumValues& CSMPrefs::EnumValues::add (const std::string& value, const std::string& tooltip)
|
||||||
|
{
|
||||||
|
mValues.push_back (EnumValue (value, tooltip));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CSMPrefs::EnumSetting::EnumSetting (Category *parent, Settings::Manager *values,
|
||||||
|
QMutex *mutex, const std::string& key, const std::string& label, const EnumValue& default_)
|
||||||
|
: Setting (parent, values, mutex, key, label), mDefault (default_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::setTooltip (const std::string& tooltip)
|
||||||
|
{
|
||||||
|
mTooltip = tooltip;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::addValues (const EnumValues& values)
|
||||||
|
{
|
||||||
|
mValues.add (values);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::addValue (const EnumValue& value)
|
||||||
|
{
|
||||||
|
mValues.add (value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::addValue (const std::string& value, const std::string& tooltip)
|
||||||
|
{
|
||||||
|
mValues.add (value, tooltip);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<QWidget *, QWidget *> CSMPrefs::EnumSetting::makeWidgets (QWidget *parent)
|
||||||
|
{
|
||||||
|
QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent);
|
||||||
|
|
||||||
|
QComboBox *widget = new QComboBox (parent);
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
for (int i=0; i<static_cast<int> (mValues.mValues.size()); ++i)
|
||||||
|
{
|
||||||
|
if (mDefault.mValue==mValues.mValues[i].mValue)
|
||||||
|
index = i;
|
||||||
|
|
||||||
|
widget->addItem (QString::fromUtf8 (mValues.mValues[i].mValue.c_str()));
|
||||||
|
|
||||||
|
if (!mValues.mValues[i].mTooltip.empty())
|
||||||
|
widget->setItemData (i, QString::fromUtf8 (mValues.mValues[i].mTooltip.c_str()),
|
||||||
|
Qt::ToolTipRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
widget->setCurrentIndex (index);
|
||||||
|
|
||||||
|
if (!mTooltip.empty())
|
||||||
|
{
|
||||||
|
QString tooltip = QString::fromUtf8 (mTooltip.c_str());
|
||||||
|
label->setToolTip (tooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
connect (widget, SIGNAL (currentIndexChanged (int)), this, SLOT (valueChanged (int)));
|
||||||
|
|
||||||
|
return std::make_pair (label, widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMPrefs::EnumSetting::valueChanged (int value)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
QMutexLocker lock (getMutex());
|
||||||
|
getValues().setString (getKey(), getParent()->getKey(), mValues.mValues.at (value).mValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
getParent()->getState()->update (*this);
|
||||||
|
}
|
62
apps/opencs/model/prefs/enumsetting.hpp
Normal file
62
apps/opencs/model/prefs/enumsetting.hpp
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#ifndef CSM_PREFS_ENUMSETTING_H
|
||||||
|
#define CSM_PREFS_ENUMSETTING_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "setting.hpp"
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
struct EnumValue
|
||||||
|
{
|
||||||
|
std::string mValue;
|
||||||
|
std::string mTooltip;
|
||||||
|
|
||||||
|
EnumValue (const std::string& value, const std::string& tooltip = "");
|
||||||
|
|
||||||
|
EnumValue (const char *value);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EnumValues
|
||||||
|
{
|
||||||
|
std::vector<EnumValue> mValues;
|
||||||
|
|
||||||
|
EnumValues& add (const EnumValues& values);
|
||||||
|
|
||||||
|
EnumValues& add (const EnumValue& value);
|
||||||
|
|
||||||
|
EnumValues& add (const std::string& value, const std::string& tooltip);
|
||||||
|
};
|
||||||
|
|
||||||
|
class EnumSetting : public Setting
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
std::string mTooltip;
|
||||||
|
EnumValue mDefault;
|
||||||
|
EnumValues mValues;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
EnumSetting (Category *parent, Settings::Manager *values,
|
||||||
|
QMutex *mutex, const std::string& key, const std::string& label,
|
||||||
|
const EnumValue& default_);
|
||||||
|
|
||||||
|
EnumSetting& setTooltip (const std::string& tooltip);
|
||||||
|
|
||||||
|
EnumSetting& addValues (const EnumValues& values);
|
||||||
|
|
||||||
|
EnumSetting& addValue (const EnumValue& value);
|
||||||
|
|
||||||
|
EnumSetting& addValue (const std::string& value, const std::string& tooltip);
|
||||||
|
|
||||||
|
/// Return label, input widget.
|
||||||
|
virtual std::pair<QWidget *, QWidget *> makeWidgets (QWidget *parent);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void valueChanged (int value);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
74
apps/opencs/model/prefs/intsetting.cpp
Normal file
74
apps/opencs/model/prefs/intsetting.cpp
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
|
||||||
|
#include "intsetting.hpp"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QMutexLocker>
|
||||||
|
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
|
#include "category.hpp"
|
||||||
|
#include "state.hpp"
|
||||||
|
|
||||||
|
CSMPrefs::IntSetting::IntSetting (Category *parent, Settings::Manager *values,
|
||||||
|
QMutex *mutex, const std::string& key, const std::string& label, int default_)
|
||||||
|
: Setting (parent, values, mutex, key, label), mMin (0), mMax (std::numeric_limits<int>::max()),
|
||||||
|
mDefault (default_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CSMPrefs::IntSetting& CSMPrefs::IntSetting::setRange (int min, int max)
|
||||||
|
{
|
||||||
|
mMin = min;
|
||||||
|
mMax = max;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::IntSetting& CSMPrefs::IntSetting::setMin (int min)
|
||||||
|
{
|
||||||
|
mMin = min;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::IntSetting& CSMPrefs::IntSetting::setMax (int max)
|
||||||
|
{
|
||||||
|
mMax = max;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::IntSetting& CSMPrefs::IntSetting::setTooltip (const std::string& tooltip)
|
||||||
|
{
|
||||||
|
mTooltip = tooltip;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<QWidget *, QWidget *> CSMPrefs::IntSetting::makeWidgets (QWidget *parent)
|
||||||
|
{
|
||||||
|
QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent);
|
||||||
|
|
||||||
|
QSpinBox *widget = new QSpinBox (parent);
|
||||||
|
widget->setRange (mMin, mMax);
|
||||||
|
widget->setValue (mDefault);
|
||||||
|
|
||||||
|
if (!mTooltip.empty())
|
||||||
|
{
|
||||||
|
QString tooltip = QString::fromUtf8 (mTooltip.c_str());
|
||||||
|
label->setToolTip (tooltip);
|
||||||
|
widget->setToolTip (tooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
connect (widget, SIGNAL (valueChanged (int)), this, SLOT (valueChanged (int)));
|
||||||
|
|
||||||
|
return std::make_pair (label, widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMPrefs::IntSetting::valueChanged (int value)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
QMutexLocker lock (getMutex());
|
||||||
|
getValues().setInt (getKey(), getParent()->getKey(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
getParent()->getState()->update (*this);
|
||||||
|
}
|
40
apps/opencs/model/prefs/intsetting.hpp
Normal file
40
apps/opencs/model/prefs/intsetting.hpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef CSM_PREFS_INTSETTING_H
|
||||||
|
#define CSM_PREFS_INTSETTING_H
|
||||||
|
|
||||||
|
#include "setting.hpp"
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
class IntSetting : public Setting
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
int mMin;
|
||||||
|
int mMax;
|
||||||
|
std::string mTooltip;
|
||||||
|
int mDefault;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
IntSetting (Category *parent, Settings::Manager *values,
|
||||||
|
QMutex *mutex, const std::string& key, const std::string& label, int default_);
|
||||||
|
|
||||||
|
// defaults to [0, std::numeric_limits<int>::max()]
|
||||||
|
IntSetting& setRange (int min, int max);
|
||||||
|
|
||||||
|
IntSetting& setMin (int min);
|
||||||
|
|
||||||
|
IntSetting& setMax (int max);
|
||||||
|
|
||||||
|
IntSetting& setTooltip (const std::string& tooltip);
|
||||||
|
|
||||||
|
/// Return label, input widget.
|
||||||
|
virtual std::pair<QWidget *, QWidget *> makeWidgets (QWidget *parent);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void valueChanged (int value);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
97
apps/opencs/model/prefs/setting.cpp
Normal file
97
apps/opencs/model/prefs/setting.cpp
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
|
||||||
|
#include "setting.hpp"
|
||||||
|
|
||||||
|
#include <QColor>
|
||||||
|
#include <QMutexLocker>
|
||||||
|
|
||||||
|
#include "category.hpp"
|
||||||
|
#include "state.hpp"
|
||||||
|
|
||||||
|
Settings::Manager& CSMPrefs::Setting::getValues()
|
||||||
|
{
|
||||||
|
return *mValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMutex *CSMPrefs::Setting::getMutex()
|
||||||
|
{
|
||||||
|
return mMutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::Setting::Setting (Category *parent, Settings::Manager *values, QMutex *mutex,
|
||||||
|
const std::string& key, const std::string& label)
|
||||||
|
: QObject (parent->getState()), mParent (parent), mValues (values), mMutex (mutex), mKey (key),
|
||||||
|
mLabel (label)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CSMPrefs::Setting:: ~Setting() {}
|
||||||
|
|
||||||
|
std::pair<QWidget *, QWidget *> CSMPrefs::Setting::makeWidgets (QWidget *parent)
|
||||||
|
{
|
||||||
|
return std::pair<QWidget *, QWidget *> (0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const CSMPrefs::Category *CSMPrefs::Setting::getParent() const
|
||||||
|
{
|
||||||
|
return mParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& CSMPrefs::Setting::getKey() const
|
||||||
|
{
|
||||||
|
return mKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& CSMPrefs::Setting::getLabel() const
|
||||||
|
{
|
||||||
|
return mLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSMPrefs::Setting::toInt() const
|
||||||
|
{
|
||||||
|
QMutexLocker lock (mMutex);
|
||||||
|
return mValues->getInt (mKey, mParent->getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
double CSMPrefs::Setting::toDouble() const
|
||||||
|
{
|
||||||
|
QMutexLocker lock (mMutex);
|
||||||
|
return mValues->getFloat (mKey, mParent->getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CSMPrefs::Setting::toString() const
|
||||||
|
{
|
||||||
|
QMutexLocker lock (mMutex);
|
||||||
|
return mValues->getString (mKey, mParent->getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMPrefs::Setting::isTrue() const
|
||||||
|
{
|
||||||
|
QMutexLocker lock (mMutex);
|
||||||
|
return mValues->getBool (mKey, mParent->getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor CSMPrefs::Setting::toColor() const
|
||||||
|
{
|
||||||
|
// toString() handles lock
|
||||||
|
return QColor (QString::fromUtf8 (toString().c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMPrefs::operator== (const Setting& setting, const std::string& key)
|
||||||
|
{
|
||||||
|
std::string fullKey = setting.getParent()->getKey() + "/" + setting.getKey();
|
||||||
|
return fullKey==key;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMPrefs::operator== (const std::string& key, const Setting& setting)
|
||||||
|
{
|
||||||
|
return setting==key;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMPrefs::operator!= (const Setting& setting, const std::string& key)
|
||||||
|
{
|
||||||
|
return !(setting==key);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMPrefs::operator!= (const std::string& key, const Setting& setting)
|
||||||
|
{
|
||||||
|
return !(key==setting);
|
||||||
|
}
|
74
apps/opencs/model/prefs/setting.hpp
Normal file
74
apps/opencs/model/prefs/setting.hpp
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
#ifndef CSM_PREFS_SETTING_H
|
||||||
|
#define CSM_PREFS_SETTING_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class QWidget;
|
||||||
|
class QColor;
|
||||||
|
class QMutex;
|
||||||
|
|
||||||
|
namespace Settings
|
||||||
|
{
|
||||||
|
class Manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
class Category;
|
||||||
|
|
||||||
|
class Setting : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Category *mParent;
|
||||||
|
Settings::Manager *mValues;
|
||||||
|
QMutex *mMutex;
|
||||||
|
std::string mKey;
|
||||||
|
std::string mLabel;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
Settings::Manager& getValues();
|
||||||
|
|
||||||
|
QMutex *getMutex();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Setting (Category *parent, Settings::Manager *values, QMutex *mutex, const std::string& key, const std::string& label);
|
||||||
|
|
||||||
|
virtual ~Setting();
|
||||||
|
|
||||||
|
/// Return label, input widget.
|
||||||
|
///
|
||||||
|
/// \note first can be a 0-pointer, which means that the label is part of the input
|
||||||
|
/// widget.
|
||||||
|
virtual std::pair<QWidget *, QWidget *> makeWidgets (QWidget *parent);
|
||||||
|
|
||||||
|
const Category *getParent() const;
|
||||||
|
|
||||||
|
const std::string& getKey() const;
|
||||||
|
|
||||||
|
const std::string& getLabel() const;
|
||||||
|
|
||||||
|
int toInt() const;
|
||||||
|
|
||||||
|
double toDouble() const;
|
||||||
|
|
||||||
|
std::string toString() const;
|
||||||
|
|
||||||
|
bool isTrue() const;
|
||||||
|
|
||||||
|
QColor toColor() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// note: fullKeys have the format categoryKey/settingKey
|
||||||
|
bool operator== (const Setting& setting, const std::string& fullKey);
|
||||||
|
bool operator== (const std::string& fullKey, const Setting& setting);
|
||||||
|
bool operator!= (const Setting& setting, const std::string& fullKey);
|
||||||
|
bool operator!= (const std::string& fullKey, const Setting& setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
410
apps/opencs/model/prefs/state.cpp
Normal file
410
apps/opencs/model/prefs/state.cpp
Normal file
|
@ -0,0 +1,410 @@
|
||||||
|
|
||||||
|
#include "state.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "intsetting.hpp"
|
||||||
|
#include "doublesetting.hpp"
|
||||||
|
#include "boolsetting.hpp"
|
||||||
|
#include "coloursetting.hpp"
|
||||||
|
|
||||||
|
CSMPrefs::State *CSMPrefs::State::sThis = 0;
|
||||||
|
|
||||||
|
void CSMPrefs::State::load()
|
||||||
|
{
|
||||||
|
// default settings file
|
||||||
|
boost::filesystem::path local = mConfigurationManager.getLocalPath() / mConfigFile;
|
||||||
|
boost::filesystem::path global = mConfigurationManager.getGlobalPath() / mConfigFile;
|
||||||
|
|
||||||
|
if (boost::filesystem::exists (local))
|
||||||
|
mSettings.loadDefault (local.string());
|
||||||
|
else if (boost::filesystem::exists (global))
|
||||||
|
mSettings.loadDefault (global.string());
|
||||||
|
else
|
||||||
|
throw std::runtime_error ("No default settings file found! Make sure the file \"openmw-cs.cfg\" was properly installed.");
|
||||||
|
|
||||||
|
// user settings file
|
||||||
|
boost::filesystem::path user = mConfigurationManager.getUserConfigPath() / mConfigFile;
|
||||||
|
|
||||||
|
if (boost::filesystem::exists (user))
|
||||||
|
mSettings.loadUser (user.string());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMPrefs::State::declare()
|
||||||
|
{
|
||||||
|
declareCategory ("Windows");
|
||||||
|
declareInt ("default-width", "Default window width", 800).
|
||||||
|
setTooltip ("Newly opened top-level windows will open with this width.").
|
||||||
|
setMin (80);
|
||||||
|
declareInt ("default-height", "Default window height", 600).
|
||||||
|
setTooltip ("Newly opened top-level windows will open with this height.").
|
||||||
|
setMin (80);
|
||||||
|
declareBool ("show-statusbar", "Show Status Bar", true).
|
||||||
|
setTooltip ("If a newly open top level window is showing status bars or not. "
|
||||||
|
" Note that this does not affect existing windows.");
|
||||||
|
declareSeparator();
|
||||||
|
declareBool ("reuse", "Reuse Subviews", true).
|
||||||
|
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 ("max-subviews", "Maximum number of subviews per top-level window", 256).
|
||||||
|
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 ("hide-subview", "Hide single subview", false).
|
||||||
|
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 ("minimum-width", "Minimum subview width", 325).
|
||||||
|
setTooltip ("Minimum width of subviews.").
|
||||||
|
setRange (50, 10000);
|
||||||
|
declareSeparator();
|
||||||
|
EnumValue scrollbarOnly ("Scrollbar Only", "Simple addition of scrollbars, the view window "
|
||||||
|
"does not grow automatically.");
|
||||||
|
declareEnum ("mainwindow-scrollbar", "Horizontal scrollbar mode for main window.", scrollbarOnly).
|
||||||
|
addValue (scrollbarOnly).
|
||||||
|
addValue ("Grow Only", "The view window grows as subviews are added. No scrollbars.").
|
||||||
|
addValue ("Grow then Scroll", "The view window grows. The scrollbar appears once it cannot grow any further.");
|
||||||
|
declareBool ("grow-limit", "Grow Limit Screen", false).
|
||||||
|
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.");
|
||||||
|
|
||||||
|
declareCategory ("Records");
|
||||||
|
EnumValue iconAndText ("Icon and Text");
|
||||||
|
EnumValues recordValues;
|
||||||
|
recordValues.add (iconAndText).add ("Icon Only").add ("Text Only");
|
||||||
|
declareEnum ("status-format", "Modification status display format", iconAndText).
|
||||||
|
addValues (recordValues);
|
||||||
|
declareEnum ("type-format", "ID type display format", iconAndText).
|
||||||
|
addValues (recordValues);
|
||||||
|
|
||||||
|
declareCategory ("ID Tables");
|
||||||
|
EnumValue inPlaceEdit ("Edit in Place", "Edit the clicked cell");
|
||||||
|
EnumValue editRecord ("Edit Record", "Open a dialogue subview for the clicked record");
|
||||||
|
EnumValue view ("View", "Open a scene subview for the clicked record (not available everywhere)");
|
||||||
|
EnumValue editRecordAndClose ("Edit Record and Close");
|
||||||
|
EnumValues doubleClickValues;
|
||||||
|
doubleClickValues.add (inPlaceEdit).add (editRecord).add (view).add ("Revert").
|
||||||
|
add ("Delete").add (editRecordAndClose).
|
||||||
|
add ("View and Close", "Open a scene subview for the clicked record and close the table subview");
|
||||||
|
declareEnum ("double", "Double Click", inPlaceEdit).addValues (doubleClickValues);
|
||||||
|
declareEnum ("double-s", "Shift Double Click", editRecord).addValues (doubleClickValues);
|
||||||
|
declareEnum ("double-c", "Control Double Click", view).addValues (doubleClickValues);
|
||||||
|
declareEnum ("double-sc", "Shift Control Double Click", editRecordAndClose).addValues (doubleClickValues);
|
||||||
|
declareSeparator();
|
||||||
|
EnumValue jumpAndSelect ("Jump and Select", "Scroll new record into view and make it the selection");
|
||||||
|
declareEnum ("jump-to-added", "Action on adding or cloning a record", jumpAndSelect).
|
||||||
|
addValue (jumpAndSelect).
|
||||||
|
addValue ("Jump Only", "Scroll new record into view").
|
||||||
|
addValue ("No Jump", "No special action");
|
||||||
|
declareBool ("extended-config",
|
||||||
|
"Manually specify affected record types for an extended delete/revert", false).
|
||||||
|
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.");
|
||||||
|
|
||||||
|
declareCategory ("ID Dialogues");
|
||||||
|
declareBool ("toolbar", "Show toolbar", true);
|
||||||
|
|
||||||
|
declareCategory ("Reports");
|
||||||
|
EnumValue actionNone ("None");
|
||||||
|
EnumValue actionEdit ("Edit", "Open a table or dialogue suitable for addressing the listed report");
|
||||||
|
EnumValue actionRemove ("Remove", "Remove the report from the report table");
|
||||||
|
EnumValue actionEditAndRemove ("Edit And Remove", "Open a table or dialogue suitable for addressing the listed report, then remove the report from the report table");
|
||||||
|
EnumValues reportValues;
|
||||||
|
reportValues.add (actionNone).add (actionEdit).add (actionRemove).add (actionEditAndRemove);
|
||||||
|
declareEnum ("double", "Double Click", actionEdit).addValues (reportValues);
|
||||||
|
declareEnum ("double-s", "Shift Double Click", actionRemove).addValues (reportValues);
|
||||||
|
declareEnum ("double-c", "Control Double Click", actionEditAndRemove).addValues (reportValues);
|
||||||
|
declareEnum ("double-sc", "Shift Control Double Click", actionNone).addValues (reportValues);
|
||||||
|
|
||||||
|
declareCategory ("Search & Replace");
|
||||||
|
declareInt ("char-before", "Characters before search string", 10).
|
||||||
|
setTooltip ("Maximum number of character to display in search result before the searched text");
|
||||||
|
declareInt ("char-after", "Characters after search string", 10).
|
||||||
|
setTooltip ("Maximum number of character to display in search result after the searched text");
|
||||||
|
declareBool ("auto-delete", "Delete row from result table after a successful replace", true);
|
||||||
|
|
||||||
|
declareCategory ("Scripts");
|
||||||
|
declareBool ("show-linenum", "Show Line Numbers", true).
|
||||||
|
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 ("mono-font", "Use monospace font", true);
|
||||||
|
EnumValue warningsNormal ("Normal", "Report warnings as warning");
|
||||||
|
declareEnum ("warnings", "Warning Mode", warningsNormal).
|
||||||
|
addValue ("Ignore", "Do not report warning").
|
||||||
|
addValue (warningsNormal).
|
||||||
|
addValue ("Strcit", "Promote warning to an error");
|
||||||
|
declareBool ("toolbar", "Show toolbar", true);
|
||||||
|
declareInt ("compile-delay", "Delay between updating of source errors", 100).
|
||||||
|
setTooltip ("Delay in milliseconds").
|
||||||
|
setRange (0, 10000);
|
||||||
|
declareInt ("error-height", "Initial height of the error panel", 100).
|
||||||
|
setRange (100, 10000);
|
||||||
|
declareSeparator();
|
||||||
|
declareColour ("colour-int", "Highlight Colour: Integer Literals", QColor ("darkmagenta"));
|
||||||
|
declareColour ("colour-float", "Highlight Colour: Float Literals", QColor ("magenta"));
|
||||||
|
declareColour ("colour-name", "Highlight Colour: Names", QColor ("grey"));
|
||||||
|
declareColour ("colour-keyword", "Highlight Colour: Keywords", QColor ("red"));
|
||||||
|
declareColour ("colour-special", "Highlight Colour: Special Characters", QColor ("darkorange"));
|
||||||
|
declareColour ("colour-comment", "Highlight Colour: Comments", QColor ("green"));
|
||||||
|
declareColour ("colour-id", "Highlight Colour: IDs", QColor ("blue"));
|
||||||
|
|
||||||
|
declareCategory ("General Input");
|
||||||
|
declareBool ("cycle", "Cyclic next/previous", false).
|
||||||
|
setTooltip ("When using next/previous functions at the last/first item of a "
|
||||||
|
"list go to the first/last item");
|
||||||
|
|
||||||
|
declareCategory ("3D Scene Input");
|
||||||
|
EnumValue left ("Left Mouse-Button");
|
||||||
|
EnumValue cLeft ("Ctrl-Left Mouse-Button");
|
||||||
|
EnumValue right ("Right Mouse-Button");
|
||||||
|
EnumValue cRight ("Ctrl-Right Mouse-Button");
|
||||||
|
EnumValue middle ("Middle Mouse-Button");
|
||||||
|
EnumValue cMiddle ("Ctrl-Middle Mouse-Button");
|
||||||
|
EnumValues inputButtons;
|
||||||
|
inputButtons.add (left).add (cLeft).add (right).add (cRight).add (middle).add (cMiddle);
|
||||||
|
declareEnum ("p-navi", "Primary Camera Navigation Button", left).addValues (inputButtons);
|
||||||
|
declareEnum ("s-navi", "Secondary Camera Navigation Button", cLeft).addValues (inputButtons);
|
||||||
|
declareEnum ("p-edit", "Primary Editing Button", right).addValues (inputButtons);
|
||||||
|
declareEnum ("s-edit", "Secondary Editing Button", cRight).addValues (inputButtons);
|
||||||
|
declareEnum ("p-select", "Primary Selection Button", middle).addValues (inputButtons);
|
||||||
|
declareEnum ("s-select", "Secondary Selection Button", cMiddle).addValues (inputButtons);
|
||||||
|
declareSeparator();
|
||||||
|
declareBool ("context-select", "Context Sensitive Selection", false);
|
||||||
|
declareDouble ("drag-factor", "Mouse sensitivity during drag operations", 1.0).
|
||||||
|
setRange (0.001, 100.0);
|
||||||
|
declareDouble ("drag-wheel-factor", "Mouse wheel sensitivity during drag operations", 1.0).
|
||||||
|
setRange (0.001, 100.0);
|
||||||
|
declareDouble ("drag-shift-factor",
|
||||||
|
"Shift-acceleration factor during drag operations", 4.0).
|
||||||
|
setTooltip ("Acceleration factor during drag operations while holding down shift").
|
||||||
|
setRange (0.001, 100.0);
|
||||||
|
|
||||||
|
declareCategory ("Tooltips");
|
||||||
|
declareBool ("scene", "Show Tooltips in 3D scenes", true);
|
||||||
|
declareBool ("scene-hide-basic", "Hide basic 3D scenes tooltips", false);
|
||||||
|
declareInt ("scene-delay", "Tooltip delay in milliseconds", 500).
|
||||||
|
setMin (1);
|
||||||
|
|
||||||
|
EnumValue createAndInsert ("Create cell and insert");
|
||||||
|
EnumValue showAndInsert ("Show cell and insert");
|
||||||
|
EnumValue dontInsert ("Discard");
|
||||||
|
EnumValue insertAnyway ("Insert anyway");
|
||||||
|
EnumValues insertOutsideCell;
|
||||||
|
insertOutsideCell.add (createAndInsert).add (dontInsert).add (insertAnyway);
|
||||||
|
EnumValues insertOutsideVisibleCell;
|
||||||
|
insertOutsideVisibleCell.add (showAndInsert).add (dontInsert).add (insertAnyway);
|
||||||
|
|
||||||
|
declareCategory ("Scene Drops");
|
||||||
|
declareInt ("distance", "Drop Distance", 50).
|
||||||
|
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 ("outside-drop", "Handling drops outside of cells", createAndInsert).
|
||||||
|
addValues (insertOutsideCell);
|
||||||
|
declareEnum ("outside-visible-drop", "Handling drops outside of visible cells", showAndInsert).
|
||||||
|
addValues (insertOutsideVisibleCell);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMPrefs::State::declareCategory (const std::string& key)
|
||||||
|
{
|
||||||
|
std::map<std::string, Category>::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 (const std::string& key,
|
||||||
|
const std::string& label, int default_)
|
||||||
|
{
|
||||||
|
if (mCurrentCategory==mCategories.end())
|
||||||
|
throw std::logic_error ("no category for setting");
|
||||||
|
|
||||||
|
std::ostringstream stream;
|
||||||
|
stream << default_;
|
||||||
|
setDefault (key, stream.str());
|
||||||
|
|
||||||
|
default_ = mSettings.getInt (key, mCurrentCategory->second.getKey());
|
||||||
|
|
||||||
|
CSMPrefs::IntSetting *setting =
|
||||||
|
new CSMPrefs::IntSetting (&mCurrentCategory->second, &mSettings, &mMutex, key, label,
|
||||||
|
default_);
|
||||||
|
|
||||||
|
mCurrentCategory->second.addSetting (setting);
|
||||||
|
|
||||||
|
return *setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::DoubleSetting& CSMPrefs::State::declareDouble (const std::string& key,
|
||||||
|
const std::string& label, double default_)
|
||||||
|
{
|
||||||
|
if (mCurrentCategory==mCategories.end())
|
||||||
|
throw std::logic_error ("no category for setting");
|
||||||
|
|
||||||
|
std::ostringstream stream;
|
||||||
|
stream << default_;
|
||||||
|
setDefault (key, stream.str());
|
||||||
|
|
||||||
|
default_ = mSettings.getFloat (key, mCurrentCategory->second.getKey());
|
||||||
|
|
||||||
|
CSMPrefs::DoubleSetting *setting =
|
||||||
|
new CSMPrefs::DoubleSetting (&mCurrentCategory->second, &mSettings, &mMutex,
|
||||||
|
key, label, default_);
|
||||||
|
|
||||||
|
mCurrentCategory->second.addSetting (setting);
|
||||||
|
|
||||||
|
return *setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::BoolSetting& CSMPrefs::State::declareBool (const std::string& key,
|
||||||
|
const std::string& label, bool default_)
|
||||||
|
{
|
||||||
|
if (mCurrentCategory==mCategories.end())
|
||||||
|
throw std::logic_error ("no category for setting");
|
||||||
|
|
||||||
|
setDefault (key, default_ ? "true" : "false");
|
||||||
|
|
||||||
|
default_ = mSettings.getBool (key, mCurrentCategory->second.getKey());
|
||||||
|
|
||||||
|
CSMPrefs::BoolSetting *setting =
|
||||||
|
new CSMPrefs::BoolSetting (&mCurrentCategory->second, &mSettings, &mMutex, key, label,
|
||||||
|
default_);
|
||||||
|
|
||||||
|
mCurrentCategory->second.addSetting (setting);
|
||||||
|
|
||||||
|
return *setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::EnumSetting& CSMPrefs::State::declareEnum (const std::string& key,
|
||||||
|
const std::string& label, EnumValue default_)
|
||||||
|
{
|
||||||
|
if (mCurrentCategory==mCategories.end())
|
||||||
|
throw std::logic_error ("no category for setting");
|
||||||
|
|
||||||
|
setDefault (key, default_.mValue);
|
||||||
|
|
||||||
|
default_.mValue = mSettings.getString (key, mCurrentCategory->second.getKey());
|
||||||
|
|
||||||
|
CSMPrefs::EnumSetting *setting =
|
||||||
|
new CSMPrefs::EnumSetting (&mCurrentCategory->second, &mSettings, &mMutex, key, label,
|
||||||
|
default_);
|
||||||
|
|
||||||
|
mCurrentCategory->second.addSetting (setting);
|
||||||
|
|
||||||
|
return *setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::ColourSetting& CSMPrefs::State::declareColour (const std::string& key,
|
||||||
|
const std::string& label, QColor default_)
|
||||||
|
{
|
||||||
|
if (mCurrentCategory==mCategories.end())
|
||||||
|
throw std::logic_error ("no category for setting");
|
||||||
|
|
||||||
|
setDefault (key, default_.name().toUtf8().data());
|
||||||
|
|
||||||
|
default_.setNamedColor (QString::fromUtf8 (mSettings.getString (key, mCurrentCategory->second.getKey()).c_str()));
|
||||||
|
|
||||||
|
CSMPrefs::ColourSetting *setting =
|
||||||
|
new CSMPrefs::ColourSetting (&mCurrentCategory->second, &mSettings, &mMutex, key, label,
|
||||||
|
default_);
|
||||||
|
|
||||||
|
mCurrentCategory->second.addSetting (setting);
|
||||||
|
|
||||||
|
return *setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMPrefs::State::declareSeparator()
|
||||||
|
{
|
||||||
|
if (mCurrentCategory==mCategories.end())
|
||||||
|
throw std::logic_error ("no category for setting");
|
||||||
|
|
||||||
|
CSMPrefs::Setting *setting =
|
||||||
|
new CSMPrefs::Setting (&mCurrentCategory->second, &mSettings, &mMutex, "", "");
|
||||||
|
|
||||||
|
mCurrentCategory->second.addSetting (setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMPrefs::State::setDefault (const std::string& key, const std::string& default_)
|
||||||
|
{
|
||||||
|
Settings::CategorySetting fullKey (mCurrentCategory->second.getKey(), key);
|
||||||
|
|
||||||
|
Settings::CategorySettingValueMap::iterator iter =
|
||||||
|
mSettings.mDefaultSettings.find (fullKey);
|
||||||
|
|
||||||
|
if (iter==mSettings.mDefaultSettings.end())
|
||||||
|
mSettings.mDefaultSettings.insert (std::make_pair (fullKey, default_));
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::State::State (const Files::ConfigurationManager& configurationManager)
|
||||||
|
: mConfigFile ("openmw-cs.cfg"), mConfigurationManager (configurationManager),
|
||||||
|
mCurrentCategory (mCategories.end())
|
||||||
|
{
|
||||||
|
if (sThis)
|
||||||
|
throw std::logic_error ("An instance of CSMPRefs::State already exists");
|
||||||
|
|
||||||
|
load();
|
||||||
|
declare();
|
||||||
|
|
||||||
|
sThis = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::State::~State()
|
||||||
|
{
|
||||||
|
sThis = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMPrefs::State::save()
|
||||||
|
{
|
||||||
|
boost::filesystem::path user = mConfigurationManager.getUserConfigPath() / mConfigFile;
|
||||||
|
mSettings.saveUser (user.string());
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::State::Iterator CSMPrefs::State::begin()
|
||||||
|
{
|
||||||
|
return mCategories.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::State::Iterator CSMPrefs::State::end()
|
||||||
|
{
|
||||||
|
return mCategories.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CSMPrefs::State& CSMPrefs::get()
|
||||||
|
{
|
||||||
|
return State::get();
|
||||||
|
}
|
105
apps/opencs/model/prefs/state.hpp
Normal file
105
apps/opencs/model/prefs/state.hpp
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
#ifndef CSV_PREFS_STATE_H
|
||||||
|
#define CSM_PREFS_STATE_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
|
#ifndef Q_MOC_RUN
|
||||||
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
|
#include "category.hpp"
|
||||||
|
#include "setting.hpp"
|
||||||
|
#include "enumsetting.hpp"
|
||||||
|
|
||||||
|
class QColor;
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
class IntSetting;
|
||||||
|
class DoubleSetting;
|
||||||
|
class BoolSetting;
|
||||||
|
class ColourSetting;
|
||||||
|
|
||||||
|
/// \brief User settings state
|
||||||
|
///
|
||||||
|
/// \note Access to the user settings is thread-safe once all declarations and loading has
|
||||||
|
/// been completed.
|
||||||
|
class State : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
static State *sThis;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef std::map<std::string, Category> Collection;
|
||||||
|
typedef Collection::iterator Iterator;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
const std::string mConfigFile;
|
||||||
|
const Files::ConfigurationManager& mConfigurationManager;
|
||||||
|
Settings::Manager mSettings;
|
||||||
|
Collection mCategories;
|
||||||
|
Iterator mCurrentCategory;
|
||||||
|
QMutex mMutex;
|
||||||
|
|
||||||
|
// not implemented
|
||||||
|
State (const State&);
|
||||||
|
State& operator= (const State&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void load();
|
||||||
|
|
||||||
|
void declare();
|
||||||
|
|
||||||
|
void declareCategory (const std::string& key);
|
||||||
|
|
||||||
|
IntSetting& declareInt (const std::string& key, const std::string& label, int default_);
|
||||||
|
DoubleSetting& declareDouble (const std::string& key, const std::string& label, double default_);
|
||||||
|
|
||||||
|
BoolSetting& declareBool (const std::string& key, const std::string& label, bool default_);
|
||||||
|
|
||||||
|
EnumSetting& declareEnum (const std::string& key, const std::string& label, EnumValue default_);
|
||||||
|
|
||||||
|
ColourSetting& declareColour (const std::string& key, const std::string& label, QColor default_);
|
||||||
|
|
||||||
|
void declareSeparator();
|
||||||
|
|
||||||
|
void setDefault (const std::string& key, const std::string& default_);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
State (const Files::ConfigurationManager& configurationManager);
|
||||||
|
|
||||||
|
~State();
|
||||||
|
|
||||||
|
void save();
|
||||||
|
|
||||||
|
Iterator begin();
|
||||||
|
|
||||||
|
Iterator end();
|
||||||
|
|
||||||
|
Category& operator[](const std::string& key);
|
||||||
|
|
||||||
|
void update (const Setting& setting);
|
||||||
|
|
||||||
|
static State& get();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void settingChanged (const CSMPrefs::Setting *setting);
|
||||||
|
};
|
||||||
|
|
||||||
|
// convenience function
|
||||||
|
State& get();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,128 +0,0 @@
|
||||||
#include "connector.hpp"
|
|
||||||
#include "../../view/settings/view.hpp"
|
|
||||||
#include "../../view/settings/page.hpp"
|
|
||||||
|
|
||||||
CSMSettings::Connector::Connector(CSVSettings::View *master,
|
|
||||||
QObject *parent)
|
|
||||||
: QObject(parent), mMasterView (master)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void CSMSettings::Connector::addSlaveView (CSVSettings::View *view,
|
|
||||||
QList <QStringList> &masterProxyValues)
|
|
||||||
{
|
|
||||||
mSlaveViews.append (view);
|
|
||||||
|
|
||||||
mProxyListMap[view->viewKey()].append (masterProxyValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
QList <QStringList> CSMSettings::Connector::getSlaveViewValues() const
|
|
||||||
{
|
|
||||||
QList <QStringList> list;
|
|
||||||
|
|
||||||
foreach (const CSVSettings::View *view, mSlaveViews)
|
|
||||||
list.append (view->selectedValues());
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSMSettings::Connector::proxyListsMatch (
|
|
||||||
const QList <QStringList> &list1,
|
|
||||||
const QList <QStringList> &list2) const
|
|
||||||
{
|
|
||||||
bool success = true;
|
|
||||||
|
|
||||||
for (int i = 0; i < list1.size(); i++)
|
|
||||||
{
|
|
||||||
success = stringListsMatch (list1.at(i), list2.at(i));
|
|
||||||
|
|
||||||
if (!success)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Connector::slotUpdateMaster() const
|
|
||||||
{
|
|
||||||
//list of the current values for each slave.
|
|
||||||
QList <QStringList> slaveValueList = getSlaveViewValues();
|
|
||||||
|
|
||||||
int masterColumn = -1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A row in the master view is one of the values in the
|
|
||||||
* master view's data model. This corresponds directly to the number of
|
|
||||||
* values in a proxy list contained in the ProxyListMap member.
|
|
||||||
* Thus, we iterate each "column" in the master proxy list
|
|
||||||
* (one for each vlaue in the master. Each column represents
|
|
||||||
* one master value's corresponding list of slave values. We examine
|
|
||||||
* each master value's list, comparing it to the current slave value list,
|
|
||||||
* stopping when we find a match using proxyListsMatch().
|
|
||||||
*
|
|
||||||
* If no match is found, clear the master view's value
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (int i = 0; i < mMasterView->rowCount(); i++)
|
|
||||||
{
|
|
||||||
QList <QStringList> proxyValueList;
|
|
||||||
|
|
||||||
foreach (const QString &settingKey, mProxyListMap.keys())
|
|
||||||
{
|
|
||||||
// append the proxy value list stored in the i'th column
|
|
||||||
// for each setting key. A setting key is the id of the setting
|
|
||||||
// in page.name format.
|
|
||||||
proxyValueList.append (mProxyListMap.value(settingKey).at(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (proxyListsMatch (slaveValueList, proxyValueList))
|
|
||||||
{
|
|
||||||
masterColumn = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString masterValue = mMasterView->value (masterColumn);
|
|
||||||
|
|
||||||
mMasterView->setSelectedValue (masterValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Connector::slotUpdateSlaves() const
|
|
||||||
{
|
|
||||||
int row = mMasterView->currentIndex();
|
|
||||||
|
|
||||||
if (row == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//iterate the proxy lists for the chosen master index
|
|
||||||
//and pass the list to each slave for updating
|
|
||||||
for (int i = 0; i < mSlaveViews.size(); i++)
|
|
||||||
{
|
|
||||||
QList <QStringList> proxyList =
|
|
||||||
mProxyListMap.value(mSlaveViews.at(i)->viewKey());
|
|
||||||
|
|
||||||
mSlaveViews.at(i)->setSelectedValues (proxyList.at(row));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSMSettings::Connector::stringListsMatch (
|
|
||||||
const QStringList &list1,
|
|
||||||
const QStringList &list2) const
|
|
||||||
{
|
|
||||||
//returns a "sloppy" match, verifying that each list contains all the same
|
|
||||||
//items, though not necessarily in the same order.
|
|
||||||
|
|
||||||
if (list1.size() != list2.size())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
QStringList tempList(list2);
|
|
||||||
|
|
||||||
//iterate each value in the list, removing one occurrence of the value in
|
|
||||||
//the other list. If no corresponding value is found, test fails
|
|
||||||
foreach (const QString &value, list1)
|
|
||||||
{
|
|
||||||
if (!tempList.contains(value))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
tempList.removeOne(value);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
|
@ -1,67 +0,0 @@
|
||||||
#ifndef CSMSETTINGS_CONNECTOR_HPP
|
|
||||||
#define CSMSETTINGS_CONNECTOR_HPP
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QList>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QStringList>
|
|
||||||
|
|
||||||
#include "support.hpp"
|
|
||||||
|
|
||||||
namespace CSVSettings {
|
|
||||||
class View;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace CSMSettings {
|
|
||||||
|
|
||||||
class Connector : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
CSVSettings::View *mMasterView;
|
|
||||||
|
|
||||||
///map using the view pointer as a key to it's index value
|
|
||||||
QList <CSVSettings::View *> mSlaveViews;
|
|
||||||
|
|
||||||
///list of proxy values for each master value.
|
|
||||||
///value list order is indexed to the master value index.
|
|
||||||
QMap < QString, QList <QStringList> > mProxyListMap;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit Connector(CSVSettings::View *master,
|
|
||||||
QObject *parent = 0);
|
|
||||||
|
|
||||||
///Set the view which acts as a proxy for other setting views
|
|
||||||
void setMasterView (CSVSettings::View *view);
|
|
||||||
|
|
||||||
///Add a view to be updated / update to the master
|
|
||||||
void addSlaveView (CSVSettings::View *view,
|
|
||||||
QList <QStringList> &masterProxyValues);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
///loosely matches lists of proxy values across registered slaves
|
|
||||||
///against a proxy value list for a given master value
|
|
||||||
bool proxyListsMatch (const QList <QStringList> &list1,
|
|
||||||
const QList <QStringList> &list2) const;
|
|
||||||
|
|
||||||
///loosely matches two string lists
|
|
||||||
bool stringListsMatch (const QStringList &list1,
|
|
||||||
const QStringList &list2) const;
|
|
||||||
|
|
||||||
///retrieves current values of registered slave views
|
|
||||||
QList <QStringList> getSlaveViewValues() const;
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
|
|
||||||
///updates slave views with proxy values associated with current
|
|
||||||
///master value
|
|
||||||
void slotUpdateSlaves() const;
|
|
||||||
|
|
||||||
///updates master value associated with the currently selected
|
|
||||||
///slave values, if applicable.
|
|
||||||
void slotUpdateMaster() const;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CSMSETTINGS_CONNECTOR_HPP
|
|
|
@ -1,414 +0,0 @@
|
||||||
#include "setting.hpp"
|
|
||||||
#include "support.hpp"
|
|
||||||
|
|
||||||
CSMSettings::Setting::Setting(SettingType typ, const QString &settingName,
|
|
||||||
const QString &pageName, const QString& label)
|
|
||||||
: mIsEditorSetting (true)
|
|
||||||
{
|
|
||||||
buildDefaultSetting();
|
|
||||||
|
|
||||||
int settingType = static_cast <int> (typ);
|
|
||||||
|
|
||||||
//even-numbered setting types are multi-valued
|
|
||||||
if ((settingType % 2) == 0)
|
|
||||||
setProperty (Property_IsMultiValue, QVariant(true).toString());
|
|
||||||
|
|
||||||
//view type is related to setting type by an order of magnitude
|
|
||||||
setProperty (Property_SettingType, QVariant (settingType).toString());
|
|
||||||
setProperty (Property_Page, pageName);
|
|
||||||
setProperty (Property_Name, settingName);
|
|
||||||
setProperty (Property_Label, label.isEmpty() ? settingName : label);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::buildDefaultSetting()
|
|
||||||
{
|
|
||||||
int arrLen = sizeof(sPropertyDefaults) / sizeof (*sPropertyDefaults);
|
|
||||||
|
|
||||||
for (int i = 0; i < arrLen; i++)
|
|
||||||
{
|
|
||||||
QStringList propertyList;
|
|
||||||
|
|
||||||
if (i <Property_DefaultValues)
|
|
||||||
propertyList.append (sPropertyDefaults[i]);
|
|
||||||
|
|
||||||
mProperties.append (propertyList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::addProxy (const Setting *setting,
|
|
||||||
const QStringList &vals)
|
|
||||||
{
|
|
||||||
if (serializable())
|
|
||||||
setSerializable (false);
|
|
||||||
|
|
||||||
QList <QStringList> list;
|
|
||||||
|
|
||||||
foreach (const QString &val, vals)
|
|
||||||
list << (QStringList() << val);
|
|
||||||
|
|
||||||
mProxies [setting->page() + '/' + setting->name()] = list;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::addProxy (const Setting *setting,
|
|
||||||
const QList <QStringList> &list)
|
|
||||||
{
|
|
||||||
if (serializable())
|
|
||||||
setProperty (Property_Serializable, false);
|
|
||||||
|
|
||||||
mProxies [setting->page() + '/' + setting->name()] = list;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setColumnSpan (int value)
|
|
||||||
{
|
|
||||||
setProperty (Property_ColumnSpan, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CSMSettings::Setting::columnSpan() const
|
|
||||||
{
|
|
||||||
return property (Property_ColumnSpan).at(0).toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setDeclaredValues (QStringList list)
|
|
||||||
{
|
|
||||||
setProperty (Property_DeclaredValues, list);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList CSMSettings::Setting::declaredValues() const
|
|
||||||
{
|
|
||||||
return property (Property_DeclaredValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList CSMSettings::Setting::property (SettingProperty prop) const
|
|
||||||
{
|
|
||||||
if (prop >= mProperties.size())
|
|
||||||
return QStringList();
|
|
||||||
|
|
||||||
return mProperties.at(prop);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setDefaultValue (int value)
|
|
||||||
{
|
|
||||||
setDefaultValues (QStringList() << QVariant (value).toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setDefaultValue (double value)
|
|
||||||
{
|
|
||||||
setDefaultValues (QStringList() << QVariant (value).toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setDefaultValue (const QString &value)
|
|
||||||
{
|
|
||||||
setDefaultValues (QStringList() << value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setDefaultValues (const QStringList &values)
|
|
||||||
{
|
|
||||||
setProperty (Property_DefaultValues, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList CSMSettings::Setting::defaultValues() const
|
|
||||||
{
|
|
||||||
return property (Property_DefaultValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setDelimiter (const QString &value)
|
|
||||||
{
|
|
||||||
setProperty (Property_Delimiter, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CSMSettings::Setting::delimiter() const
|
|
||||||
{
|
|
||||||
return property (Property_Delimiter).at(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setEditorSetting(bool state)
|
|
||||||
{
|
|
||||||
mIsEditorSetting = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSMSettings::Setting::isEditorSetting() const
|
|
||||||
{
|
|
||||||
return mIsEditorSetting;
|
|
||||||
}
|
|
||||||
void CSMSettings::Setting::setIsMultiLine (bool state)
|
|
||||||
{
|
|
||||||
setProperty (Property_IsMultiLine, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSMSettings::Setting::isMultiLine() const
|
|
||||||
{
|
|
||||||
return (property (Property_IsMultiLine).at(0) == "true");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setIsMultiValue (bool state)
|
|
||||||
{
|
|
||||||
setProperty (Property_IsMultiValue, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSMSettings::Setting::isMultiValue() const
|
|
||||||
{
|
|
||||||
return (property (Property_IsMultiValue).at(0) == "true");
|
|
||||||
}
|
|
||||||
|
|
||||||
const CSMSettings::ProxyValueMap &CSMSettings::Setting::proxyLists() const
|
|
||||||
{
|
|
||||||
return mProxies;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setSerializable (bool state)
|
|
||||||
{
|
|
||||||
setProperty (Property_Serializable, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSMSettings::Setting::serializable() const
|
|
||||||
{
|
|
||||||
return (property (Property_Serializable).at(0) == "true");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setSpecialValueText(const QString &text)
|
|
||||||
{
|
|
||||||
setProperty (Property_SpecialValueText, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CSMSettings::Setting::specialValueText() const
|
|
||||||
{
|
|
||||||
return property (Property_SpecialValueText).at(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setName (const QString &value)
|
|
||||||
{
|
|
||||||
setProperty (Property_Name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CSMSettings::Setting::name() const
|
|
||||||
{
|
|
||||||
return property (Property_Name).at(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setPage (const QString &value)
|
|
||||||
{
|
|
||||||
setProperty (Property_Page, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CSMSettings::Setting::page() const
|
|
||||||
{
|
|
||||||
return property (Property_Page).at(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setStyleSheet (const QString &value)
|
|
||||||
{
|
|
||||||
setProperty (Property_StyleSheet, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CSMSettings::Setting::styleSheet() const
|
|
||||||
{
|
|
||||||
return property (Property_StyleSheet).at(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setPrefix (const QString &value)
|
|
||||||
{
|
|
||||||
setProperty (Property_Prefix, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CSMSettings::Setting::prefix() const
|
|
||||||
{
|
|
||||||
return property (Property_Prefix).at(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setRowSpan (const int value)
|
|
||||||
{
|
|
||||||
setProperty (Property_RowSpan, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CSMSettings::Setting::rowSpan () const
|
|
||||||
{
|
|
||||||
return property (Property_RowSpan).at(0).toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setSingleStep (int value)
|
|
||||||
{
|
|
||||||
setProperty (Property_SingleStep, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setSingleStep (double value)
|
|
||||||
{
|
|
||||||
setProperty (Property_SingleStep, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CSMSettings::Setting::singleStep() const
|
|
||||||
{
|
|
||||||
return property (Property_SingleStep).at(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setSuffix (const QString &value)
|
|
||||||
{
|
|
||||||
setProperty (Property_Suffix, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CSMSettings::Setting::suffix() const
|
|
||||||
{
|
|
||||||
return property (Property_Suffix).at(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setTickInterval (int value)
|
|
||||||
{
|
|
||||||
setProperty (Property_TickInterval, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CSMSettings::Setting::tickInterval () const
|
|
||||||
{
|
|
||||||
return property (Property_TickInterval).at(0).toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setTicksAbove (bool state)
|
|
||||||
{
|
|
||||||
setProperty (Property_TicksAbove, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSMSettings::Setting::ticksAbove() const
|
|
||||||
{
|
|
||||||
return (property (Property_TicksAbove).at(0) == "true");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setTicksBelow (bool state)
|
|
||||||
{
|
|
||||||
setProperty (Property_TicksBelow, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSMSettings::Setting::ticksBelow() const
|
|
||||||
{
|
|
||||||
return (property (Property_TicksBelow).at(0) == "true");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setType (int settingType)
|
|
||||||
{
|
|
||||||
setProperty (Property_SettingType, settingType);
|
|
||||||
}
|
|
||||||
|
|
||||||
CSMSettings::SettingType CSMSettings::Setting::type() const
|
|
||||||
{
|
|
||||||
return static_cast <CSMSettings::SettingType> ( property (
|
|
||||||
Property_SettingType).at(0).toInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setRange (int min, int max)
|
|
||||||
{
|
|
||||||
setProperty (Property_Minimum, min);
|
|
||||||
setProperty (Property_Maximum, max);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setRange (double min, double max)
|
|
||||||
{
|
|
||||||
setProperty (Property_Minimum, min);
|
|
||||||
setProperty (Property_Maximum, max);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CSMSettings::Setting::maximum() const
|
|
||||||
{
|
|
||||||
return property (Property_Maximum).at(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CSMSettings::Setting::minimum() const
|
|
||||||
{
|
|
||||||
return property (Property_Minimum).at(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
CSVSettings::ViewType CSMSettings::Setting::viewType() const
|
|
||||||
{
|
|
||||||
return static_cast <CSVSettings::ViewType> ( property (
|
|
||||||
Property_SettingType).at(0).toInt() / 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setViewColumn (int value)
|
|
||||||
{
|
|
||||||
setProperty (Property_ViewColumn, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CSMSettings::Setting::viewColumn() const
|
|
||||||
{
|
|
||||||
return property (Property_ViewColumn).at(0).toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setViewLocation (int row, int column)
|
|
||||||
{
|
|
||||||
setViewRow (row);
|
|
||||||
setViewColumn (column);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setViewRow (int value)
|
|
||||||
{
|
|
||||||
setProperty (Property_ViewRow, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CSMSettings::Setting::viewRow() const
|
|
||||||
{
|
|
||||||
return property (Property_ViewRow).at(0).toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setWidgetWidth (int value)
|
|
||||||
{
|
|
||||||
setProperty (Property_WidgetWidth, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CSMSettings::Setting::widgetWidth() const
|
|
||||||
{
|
|
||||||
return property (Property_WidgetWidth).at(0).toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setWrapping (bool state)
|
|
||||||
{
|
|
||||||
setProperty (Property_Wrapping, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSMSettings::Setting::wrapping() const
|
|
||||||
{
|
|
||||||
return (property (Property_Wrapping).at(0) == "true");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setLabel (const QString& label)
|
|
||||||
{
|
|
||||||
setProperty (Property_Label, label);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CSMSettings::Setting::getLabel() const
|
|
||||||
{
|
|
||||||
return property (Property_Label).at (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setToolTip (const QString& toolTip)
|
|
||||||
{
|
|
||||||
setProperty (Property_ToolTip, toolTip);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CSMSettings::Setting::getToolTip() const
|
|
||||||
{
|
|
||||||
return property (Property_ToolTip).at (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setProperty (SettingProperty prop, bool value)
|
|
||||||
{
|
|
||||||
setProperty (prop, QStringList() << QVariant (value).toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setProperty (SettingProperty prop, int value)
|
|
||||||
{
|
|
||||||
setProperty (prop, QStringList() << QVariant (value).toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setProperty (SettingProperty prop, double value)
|
|
||||||
{
|
|
||||||
setProperty (prop, QStringList() << QVariant (value).toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setProperty (SettingProperty prop,
|
|
||||||
const QString &value)
|
|
||||||
{
|
|
||||||
setProperty (prop, QStringList() << value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::Setting::setProperty (SettingProperty prop,
|
|
||||||
const QStringList &value)
|
|
||||||
{
|
|
||||||
if (prop < mProperties.size())
|
|
||||||
mProperties.replace (prop, value);
|
|
||||||
}
|
|
|
@ -1,159 +0,0 @@
|
||||||
#ifndef CSMSETTINGS_SETTING_HPP
|
|
||||||
#define CSMSETTINGS_SETTING_HPP
|
|
||||||
|
|
||||||
#include <QStringList>
|
|
||||||
#include <QMap>
|
|
||||||
#include "support.hpp"
|
|
||||||
|
|
||||||
namespace CSMSettings
|
|
||||||
{
|
|
||||||
//QString is the setting id in the form of "page/name"
|
|
||||||
//QList is a list of stringlists of proxy values.
|
|
||||||
//Order is important! Proxy stringlists are matched against
|
|
||||||
//master values by their position in the QList.
|
|
||||||
typedef QMap <QString, QList <QStringList> > ProxyValueMap;
|
|
||||||
|
|
||||||
///Setting class is the interface for the User Settings. It contains
|
|
||||||
///a great deal of boiler plate to provide the core API functions, as
|
|
||||||
///well as the property() functions which use enumeration to be iterable.
|
|
||||||
///This makes the Setting class capable of being manipulated by script.
|
|
||||||
///See CSMSettings::support.hpp for enumerations / string values.
|
|
||||||
class Setting
|
|
||||||
{
|
|
||||||
QList <QStringList> mProperties;
|
|
||||||
QStringList mDefaults;
|
|
||||||
|
|
||||||
bool mIsEditorSetting;
|
|
||||||
|
|
||||||
ProxyValueMap mProxies;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Setting(SettingType typ, const QString &settingName,
|
|
||||||
const QString &pageName, const QString& label = "");
|
|
||||||
|
|
||||||
void addProxy (const Setting *setting, const QStringList &vals);
|
|
||||||
void addProxy (const Setting *setting, const QList <QStringList> &list);
|
|
||||||
|
|
||||||
const QList <QStringList> &properties() const { return mProperties; }
|
|
||||||
const ProxyValueMap &proxies() const { return mProxies; }
|
|
||||||
|
|
||||||
void setColumnSpan (int value);
|
|
||||||
int columnSpan() const;
|
|
||||||
|
|
||||||
void setDeclaredValues (QStringList list);
|
|
||||||
QStringList declaredValues() const;
|
|
||||||
|
|
||||||
void setDefaultValue (int value);
|
|
||||||
void setDefaultValue (double value);
|
|
||||||
void setDefaultValue (const QString &value);
|
|
||||||
|
|
||||||
void setDefaultValues (const QStringList &values);
|
|
||||||
QStringList defaultValues() const;
|
|
||||||
|
|
||||||
void setDelimiter (const QString &value);
|
|
||||||
QString delimiter() const;
|
|
||||||
|
|
||||||
void setEditorSetting (bool state);
|
|
||||||
bool isEditorSetting() const;
|
|
||||||
|
|
||||||
void setIsMultiLine (bool state);
|
|
||||||
bool isMultiLine() const;
|
|
||||||
|
|
||||||
void setIsMultiValue (bool state);
|
|
||||||
bool isMultiValue() const;
|
|
||||||
|
|
||||||
void setMask (const QString &value);
|
|
||||||
QString mask() const;
|
|
||||||
|
|
||||||
void setRange (int min, int max);
|
|
||||||
void setRange (double min, double max);
|
|
||||||
|
|
||||||
QString maximum() const;
|
|
||||||
|
|
||||||
QString minimum() const;
|
|
||||||
|
|
||||||
void setName (const QString &value);
|
|
||||||
QString name() const;
|
|
||||||
|
|
||||||
void setPage (const QString &value);
|
|
||||||
QString page() const;
|
|
||||||
|
|
||||||
void setStyleSheet (const QString &value);
|
|
||||||
QString styleSheet() const;
|
|
||||||
|
|
||||||
void setPrefix (const QString &value);
|
|
||||||
QString prefix() const;
|
|
||||||
|
|
||||||
void setRowSpan (const int value);
|
|
||||||
int rowSpan() const;
|
|
||||||
|
|
||||||
const ProxyValueMap &proxyLists() const;
|
|
||||||
|
|
||||||
void setSerializable (bool state);
|
|
||||||
bool serializable() const;
|
|
||||||
|
|
||||||
void setSpecialValueText (const QString &text);
|
|
||||||
QString specialValueText() const;
|
|
||||||
|
|
||||||
void setSingleStep (int value);
|
|
||||||
void setSingleStep (double value);
|
|
||||||
QString singleStep() const;
|
|
||||||
|
|
||||||
void setSuffix (const QString &value);
|
|
||||||
QString suffix() const;
|
|
||||||
|
|
||||||
void setTickInterval (int value);
|
|
||||||
int tickInterval() const;
|
|
||||||
|
|
||||||
void setTicksAbove (bool state);
|
|
||||||
bool ticksAbove() const;
|
|
||||||
|
|
||||||
void setTicksBelow (bool state);
|
|
||||||
bool ticksBelow() const;
|
|
||||||
|
|
||||||
void setViewColumn (int value);
|
|
||||||
int viewColumn() const;
|
|
||||||
|
|
||||||
void setViewLocation (int row = -1, int column = -1);
|
|
||||||
|
|
||||||
void setViewRow (int value);
|
|
||||||
int viewRow() const;
|
|
||||||
|
|
||||||
void setType (int settingType);
|
|
||||||
CSMSettings::SettingType type() const;
|
|
||||||
|
|
||||||
CSVSettings::ViewType viewType() const;
|
|
||||||
|
|
||||||
void setWrapping (bool state);
|
|
||||||
bool wrapping() const;
|
|
||||||
|
|
||||||
void setWidgetWidth (int value);
|
|
||||||
int widgetWidth() const;
|
|
||||||
|
|
||||||
/// This is the text the user gets to see.
|
|
||||||
void setLabel (const QString& label);
|
|
||||||
QString getLabel() const;
|
|
||||||
|
|
||||||
void setToolTip (const QString& toolTip);
|
|
||||||
QString getToolTip() const;
|
|
||||||
|
|
||||||
///returns the specified property value
|
|
||||||
QStringList property (SettingProperty prop) const;
|
|
||||||
|
|
||||||
///boilerplate code to convert setting values of common types
|
|
||||||
void setProperty (SettingProperty prop, bool value);
|
|
||||||
void setProperty (SettingProperty prop, int value);
|
|
||||||
void setProperty (SettingProperty prop, double value);
|
|
||||||
void setProperty (SettingProperty prop, const QString &value);
|
|
||||||
void setProperty (SettingProperty prop, const QStringList &value);
|
|
||||||
|
|
||||||
void addProxy (Setting* setting,
|
|
||||||
QMap <QString, QStringList> &proxyMap);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void buildDefaultSetting();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CSMSETTINGS_SETTING_HPP
|
|
|
@ -1,149 +0,0 @@
|
||||||
#ifndef SETTING_SUPPORT_HPP
|
|
||||||
#define SETTING_SUPPORT_HPP
|
|
||||||
|
|
||||||
#include <Qt>
|
|
||||||
#include <QPair>
|
|
||||||
#include <QList>
|
|
||||||
#include <QVariant>
|
|
||||||
#include <QStringList>
|
|
||||||
|
|
||||||
//Enums
|
|
||||||
namespace CSMSettings
|
|
||||||
{
|
|
||||||
///Enumerated properties for scripting
|
|
||||||
enum SettingProperty
|
|
||||||
{
|
|
||||||
Property_Name = 0,
|
|
||||||
Property_Page = 1,
|
|
||||||
Property_SettingType = 2,
|
|
||||||
Property_IsMultiValue = 3,
|
|
||||||
Property_IsMultiLine = 4,
|
|
||||||
Property_WidgetWidth = 5,
|
|
||||||
Property_ViewRow = 6,
|
|
||||||
Property_ViewColumn = 7,
|
|
||||||
Property_Delimiter = 8,
|
|
||||||
Property_Serializable = 9,
|
|
||||||
Property_ColumnSpan = 10,
|
|
||||||
Property_RowSpan = 11,
|
|
||||||
Property_Minimum = 12,
|
|
||||||
Property_Maximum = 13,
|
|
||||||
Property_SpecialValueText = 14,
|
|
||||||
Property_Prefix = 15,
|
|
||||||
Property_Suffix = 16,
|
|
||||||
Property_SingleStep = 17,
|
|
||||||
Property_Wrapping = 18,
|
|
||||||
Property_TickInterval = 19,
|
|
||||||
Property_TicksAbove = 20,
|
|
||||||
Property_TicksBelow = 21,
|
|
||||||
Property_StyleSheet = 22,
|
|
||||||
Property_Label = 23,
|
|
||||||
Property_ToolTip = 24,
|
|
||||||
|
|
||||||
//Stringlists should always be the last items
|
|
||||||
Property_DefaultValues = 25,
|
|
||||||
Property_DeclaredValues = 26,
|
|
||||||
Property_DefinedValues = 27,
|
|
||||||
Property_Proxies = 28
|
|
||||||
};
|
|
||||||
|
|
||||||
///Basic setting widget types.
|
|
||||||
enum SettingType
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* 0 - 9 - Boolean widgets
|
|
||||||
* 10-19 - List widgets
|
|
||||||
* 21-29 - Range widgets
|
|
||||||
* 31-39 - Text widgets
|
|
||||||
*
|
|
||||||
* Each range corresponds to a View_Type enum by a factor of 10.
|
|
||||||
*
|
|
||||||
* Even-numbered values are single-value widgets
|
|
||||||
* Odd-numbered values are multi-valued widgets
|
|
||||||
*/
|
|
||||||
|
|
||||||
Type_CheckBox = 0,
|
|
||||||
Type_RadioButton = 1,
|
|
||||||
Type_ListView = 10,
|
|
||||||
Type_ComboBox = 11,
|
|
||||||
Type_SpinBox = 21,
|
|
||||||
Type_DoubleSpinBox = 23,
|
|
||||||
Type_Slider = 25,
|
|
||||||
Type_Dial = 27,
|
|
||||||
Type_TextArea = 30,
|
|
||||||
Type_LineEdit = 31,
|
|
||||||
Type_Undefined = 40
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace CSVSettings
|
|
||||||
{
|
|
||||||
///Categorical view types which encompass the setting widget types
|
|
||||||
enum ViewType
|
|
||||||
{
|
|
||||||
ViewType_Boolean = 0,
|
|
||||||
ViewType_List = 1,
|
|
||||||
ViewType_Range = 2,
|
|
||||||
ViewType_Text = 3,
|
|
||||||
ViewType_Undefined = 4
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
namespace CSMSettings
|
|
||||||
{
|
|
||||||
///used to construct default settings in the Setting class
|
|
||||||
struct PropertyDefaultValues
|
|
||||||
{
|
|
||||||
int id;
|
|
||||||
QString name;
|
|
||||||
QVariant value;
|
|
||||||
};
|
|
||||||
|
|
||||||
///strings which correspond to setting values. These strings represent
|
|
||||||
///the script language keywords which would be used to declare setting
|
|
||||||
///views for 3rd party addons
|
|
||||||
const QString sPropertyNames[] =
|
|
||||||
{
|
|
||||||
"name", "page", "setting_type", "is_multi_value",
|
|
||||||
"is_multi_line", "widget_width", "view_row", "view_column", "delimiter",
|
|
||||||
"is_serializable","column_span", "row_span", "minimum", "maximum",
|
|
||||||
"special_value_text", "prefix", "suffix", "single_step", "wrapping",
|
|
||||||
"tick_interval", "ticks_above", "ticks_below", "stylesheet",
|
|
||||||
"defaults", "declarations", "definitions", "proxies"
|
|
||||||
};
|
|
||||||
|
|
||||||
///Default values for a setting. Used in setting creation.
|
|
||||||
const QString sPropertyDefaults[] =
|
|
||||||
{
|
|
||||||
"", //name
|
|
||||||
"", //page
|
|
||||||
"40", //setting type
|
|
||||||
"false", //multivalue
|
|
||||||
"false", //multiline
|
|
||||||
"7", //widget width
|
|
||||||
"-1", //view row
|
|
||||||
"-1", //view column
|
|
||||||
",", //delimiter
|
|
||||||
"true", //serialized
|
|
||||||
"1", //column span
|
|
||||||
"1", //row span
|
|
||||||
"0", //value range
|
|
||||||
"0", //value minimum
|
|
||||||
"0", //value maximum
|
|
||||||
"", //special text
|
|
||||||
"", //prefix
|
|
||||||
"", //suffix
|
|
||||||
"false", //wrapping
|
|
||||||
"1", //tick interval
|
|
||||||
"false", //ticks above
|
|
||||||
"true", //ticks below
|
|
||||||
"", //StyleSheet
|
|
||||||
"", //default values
|
|
||||||
"", //declared values
|
|
||||||
"", //defined values
|
|
||||||
"" //proxy values
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // VIEW_SUPPORT_HPP
|
|
|
@ -1,801 +0,0 @@
|
||||||
#include "usersettings.hpp"
|
|
||||||
|
|
||||||
#include <QSettings>
|
|
||||||
#include <QFile>
|
|
||||||
|
|
||||||
#include <components/files/configurationmanager.hpp>
|
|
||||||
#include <components/settings/settings.hpp>
|
|
||||||
#include <boost/version.hpp>
|
|
||||||
|
|
||||||
#include "setting.hpp"
|
|
||||||
#include "support.hpp"
|
|
||||||
#include <QTextCodec>
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Workaround for problems with whitespaces in paths in older versions of Boost library
|
|
||||||
*/
|
|
||||||
#if (BOOST_VERSION <= 104600)
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline boost::filesystem::path lexical_cast<boost::filesystem::path, std::string>(const std::string& arg)
|
|
||||||
{
|
|
||||||
return boost::filesystem::path(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* namespace boost */
|
|
||||||
#endif /* (BOOST_VERSION <= 104600) */
|
|
||||||
|
|
||||||
CSMSettings::UserSettings *CSMSettings::UserSettings::sUserSettingsInstance = 0;
|
|
||||||
|
|
||||||
CSMSettings::UserSettings::UserSettings (const Files::ConfigurationManager& configurationManager)
|
|
||||||
: mCfgMgr (configurationManager)
|
|
||||||
, mSettingDefinitions(NULL)
|
|
||||||
{
|
|
||||||
assert(!sUserSettingsInstance);
|
|
||||||
sUserSettingsInstance = this;
|
|
||||||
|
|
||||||
buildSettingModelDefaults();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::UserSettings::buildSettingModelDefaults()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
declareSection ("3d-render", "3D Rendering");
|
|
||||||
{
|
|
||||||
Setting *farClipDist = createSetting (Type_DoubleSpinBox, "far-clip-distance", "Far clipping distance");
|
|
||||||
farClipDist->setDefaultValue (300000);
|
|
||||||
farClipDist->setRange (0, 1000000);
|
|
||||||
farClipDist->setToolTip ("The maximum distance objects are still rendered at.");
|
|
||||||
|
|
||||||
QString defaultValue = "None";
|
|
||||||
Setting *antialiasing = createSetting (Type_ComboBox, "antialiasing", "Antialiasing");
|
|
||||||
antialiasing->setDeclaredValues (QStringList()
|
|
||||||
<< defaultValue << "MSAA 2" << "MSAA 4" << "MSAA 8" << "MSAA 16");
|
|
||||||
antialiasing->setDefaultValue (defaultValue);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
declareSection ("scene-input", "Scene Input");
|
|
||||||
{
|
|
||||||
Setting *fastFactor = createSetting (Type_SpinBox, "fast-factor",
|
|
||||||
"Fast movement factor");
|
|
||||||
fastFactor->setDefaultValue (4);
|
|
||||||
fastFactor->setRange (1, 100);
|
|
||||||
fastFactor->setToolTip (
|
|
||||||
"Factor by which movement is speed up while the shift key is held down.");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
declareSection ("window", "Window");
|
|
||||||
{
|
|
||||||
Setting *preDefined = createSetting (Type_ComboBox, "pre-defined",
|
|
||||||
"Default window size");
|
|
||||||
preDefined->setEditorSetting (false);
|
|
||||||
preDefined->setDeclaredValues (
|
|
||||||
QStringList() << "640 x 480" << "800 x 600" << "1024 x 768" << "1440 x 900");
|
|
||||||
preDefined->setViewLocation (1, 1);
|
|
||||||
preDefined->setColumnSpan (2);
|
|
||||||
preDefined->setToolTip ("Newly opened top-level windows will open with this size "
|
|
||||||
"(picked from a list of pre-defined values)");
|
|
||||||
|
|
||||||
Setting *width = createSetting (Type_LineEdit, "default-width",
|
|
||||||
"Default window width");
|
|
||||||
width->setDefaultValues (QStringList() << "1024");
|
|
||||||
width->setViewLocation (2, 1);
|
|
||||||
width->setColumnSpan (1);
|
|
||||||
width->setToolTip ("Newly opened top-level windows will open with this width.");
|
|
||||||
preDefined->addProxy (width, QStringList() << "640" << "800" << "1024" << "1440");
|
|
||||||
|
|
||||||
Setting *height = createSetting (Type_LineEdit, "default-height",
|
|
||||||
"Default window height");
|
|
||||||
height->setDefaultValues (QStringList() << "768");
|
|
||||||
height->setViewLocation (2, 2);
|
|
||||||
height->setColumnSpan (1);
|
|
||||||
height->setToolTip ("Newly opened top-level windows will open with this height.");
|
|
||||||
preDefined->addProxy (height, QStringList() << "480" << "600" << "768" << "900");
|
|
||||||
|
|
||||||
Setting *reuse = createSetting (Type_CheckBox, "reuse", "Reuse Subviews");
|
|
||||||
reuse->setDefaultValue ("true");
|
|
||||||
reuse->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.");
|
|
||||||
|
|
||||||
Setting *statusBar = createSetting (Type_CheckBox, "show-statusbar", "Show Status Bar");
|
|
||||||
statusBar->setDefaultValue ("true");
|
|
||||||
statusBar->setToolTip ("If a newly open top level window is showing status bars or not. "
|
|
||||||
" Note that this does not affect existing windows.");
|
|
||||||
|
|
||||||
Setting *maxSubView = createSetting (Type_SpinBox, "max-subviews",
|
|
||||||
"Maximum number of subviews per top-level window");
|
|
||||||
maxSubView->setDefaultValue (256);
|
|
||||||
maxSubView->setRange (1, 256);
|
|
||||||
maxSubView->setToolTip ("If the maximum number is reached and a new subview is opened "
|
|
||||||
"it will be placed into a new top-level window.");
|
|
||||||
|
|
||||||
Setting *hide = createSetting (Type_CheckBox, "hide-subview", "Hide single subview");
|
|
||||||
hide->setDefaultValue ("false");
|
|
||||||
hide->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)");
|
|
||||||
|
|
||||||
Setting *minWidth = createSetting (Type_SpinBox, "minimum-width",
|
|
||||||
"Minimum subview width");
|
|
||||||
minWidth->setDefaultValue (325);
|
|
||||||
minWidth->setRange (50, 10000);
|
|
||||||
minWidth->setToolTip ("Minimum width of subviews.");
|
|
||||||
|
|
||||||
QString defaultScroll = "Scrollbar Only";
|
|
||||||
QStringList scrollValues = QStringList() << defaultScroll << "Grow Only" << "Grow then Scroll";
|
|
||||||
|
|
||||||
Setting *mainwinScroll = createSetting (Type_RadioButton, "mainwindow-scrollbar",
|
|
||||||
"Add a horizontal scrollbar to the main view window.");
|
|
||||||
mainwinScroll->setDefaultValue (defaultScroll);
|
|
||||||
mainwinScroll->setDeclaredValues (scrollValues);
|
|
||||||
mainwinScroll->setToolTip ("Scrollbar Only: Simple addition of scrollbars, the view window does not grow"
|
|
||||||
" automatically.\n"
|
|
||||||
"Grow Only: Original Editor behaviour. The view window grows as subviews are added. No scrollbars.\n"
|
|
||||||
"Grow then Scroll: The view window grows. The scrollbar appears once it cannot grow any further.");
|
|
||||||
|
|
||||||
Setting *grow = createSetting (Type_CheckBox, "grow-limit", "Grow Limit Screen");
|
|
||||||
grow->setDefaultValue ("false");
|
|
||||||
grow->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.");
|
|
||||||
}
|
|
||||||
|
|
||||||
declareSection ("records", "Records");
|
|
||||||
{
|
|
||||||
QString defaultValue = "Icon and Text";
|
|
||||||
QStringList values = QStringList() << defaultValue << "Icon Only" << "Text Only";
|
|
||||||
|
|
||||||
Setting *rsd = createSetting (Type_RadioButton, "status-format",
|
|
||||||
"Modification status display format");
|
|
||||||
rsd->setDefaultValue (defaultValue);
|
|
||||||
rsd->setDeclaredValues (values);
|
|
||||||
|
|
||||||
Setting *ritd = createSetting (Type_RadioButton, "type-format",
|
|
||||||
"ID type display format");
|
|
||||||
ritd->setDefaultValue (defaultValue);
|
|
||||||
ritd->setDeclaredValues (values);
|
|
||||||
}
|
|
||||||
|
|
||||||
declareSection ("table-input", "ID Tables");
|
|
||||||
{
|
|
||||||
QString inPlaceEdit ("Edit in Place");
|
|
||||||
QString editRecord ("Edit Record");
|
|
||||||
QString view ("View");
|
|
||||||
QString editRecordAndClose ("Edit Record and Close");
|
|
||||||
|
|
||||||
QStringList values;
|
|
||||||
values
|
|
||||||
<< "None" << inPlaceEdit << editRecord << view << "Revert" << "Delete"
|
|
||||||
<< editRecordAndClose << "View and Close";
|
|
||||||
|
|
||||||
QString toolTip = "<ul>"
|
|
||||||
"<li>None</li>"
|
|
||||||
"<li>Edit in Place: Edit the clicked cell</li>"
|
|
||||||
"<li>Edit Record: Open a dialogue subview for the clicked record</li>"
|
|
||||||
"<li>View: Open a scene subview for the clicked record (not available everywhere)</li>"
|
|
||||||
"<li>Revert: Revert record</li>"
|
|
||||||
"<li>Delete: Delete recordy</li>"
|
|
||||||
"<li>Edit Record and Close: Open a dialogue subview for the clicked record and close the table subview</li>"
|
|
||||||
"<li>View And Close: Open a scene subview for the clicked record and close the table subview</li>"
|
|
||||||
"</ul>";
|
|
||||||
|
|
||||||
Setting *doubleClick = createSetting (Type_ComboBox, "double", "Double Click");
|
|
||||||
doubleClick->setDeclaredValues (values);
|
|
||||||
doubleClick->setDefaultValue (inPlaceEdit);
|
|
||||||
doubleClick->setToolTip ("Action on double click in table:<p>" + toolTip);
|
|
||||||
|
|
||||||
Setting *shiftDoubleClick = createSetting (Type_ComboBox, "double-s",
|
|
||||||
"Shift Double Click");
|
|
||||||
shiftDoubleClick->setDeclaredValues (values);
|
|
||||||
shiftDoubleClick->setDefaultValue (editRecord);
|
|
||||||
shiftDoubleClick->setToolTip ("Action on shift double click in table:<p>" + toolTip);
|
|
||||||
|
|
||||||
Setting *ctrlDoubleClick = createSetting (Type_ComboBox, "double-c",
|
|
||||||
"Control Double Click");
|
|
||||||
ctrlDoubleClick->setDeclaredValues (values);
|
|
||||||
ctrlDoubleClick->setDefaultValue (view);
|
|
||||||
ctrlDoubleClick->setToolTip ("Action on control double click in table:<p>" + toolTip);
|
|
||||||
|
|
||||||
Setting *shiftCtrlDoubleClick = createSetting (Type_ComboBox, "double-sc",
|
|
||||||
"Shift Control Double Click");
|
|
||||||
shiftCtrlDoubleClick->setDeclaredValues (values);
|
|
||||||
shiftCtrlDoubleClick->setDefaultValue (editRecordAndClose);
|
|
||||||
shiftCtrlDoubleClick->setToolTip ("Action on shift control double click in table:<p>" + toolTip);
|
|
||||||
|
|
||||||
QString defaultValue = "Jump and Select";
|
|
||||||
QStringList jumpValues = QStringList() << defaultValue << "Jump Only" << "No Jump";
|
|
||||||
|
|
||||||
Setting *jumpToAdded = createSetting (Type_RadioButton, "jump-to-added",
|
|
||||||
"Jump to the added or cloned record.");
|
|
||||||
jumpToAdded->setDefaultValue (defaultValue);
|
|
||||||
jumpToAdded->setDeclaredValues (jumpValues);
|
|
||||||
|
|
||||||
Setting *extendedConfig = createSetting (Type_CheckBox, "extended-config",
|
|
||||||
"Manually specify affected record types for an extended delete/revert");
|
|
||||||
extendedConfig->setDefaultValue("false");
|
|
||||||
extendedConfig->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.");
|
|
||||||
}
|
|
||||||
|
|
||||||
declareSection ("dialogues", "ID Dialogues");
|
|
||||||
{
|
|
||||||
Setting *toolbar = createSetting (Type_CheckBox, "toolbar", "Show toolbar");
|
|
||||||
toolbar->setDefaultValue ("true");
|
|
||||||
}
|
|
||||||
|
|
||||||
declareSection ("report-input", "Reports");
|
|
||||||
{
|
|
||||||
QString none ("None");
|
|
||||||
QString edit ("Edit");
|
|
||||||
QString remove ("Remove");
|
|
||||||
QString editAndRemove ("Edit And Remove");
|
|
||||||
|
|
||||||
QStringList values;
|
|
||||||
values << none << edit << remove << editAndRemove;
|
|
||||||
|
|
||||||
QString toolTip = "<ul>"
|
|
||||||
"<li>None</li>"
|
|
||||||
"<li>Edit: Open a table or dialogue suitable for addressing the listed report</li>"
|
|
||||||
"<li>Remove: Remove the report from the report table</li>"
|
|
||||||
"<li>Edit and Remove: Open a table or dialogue suitable for addressing the listed report, then remove the report from the report table</li>"
|
|
||||||
"</ul>";
|
|
||||||
|
|
||||||
Setting *doubleClick = createSetting (Type_ComboBox, "double", "Double Click");
|
|
||||||
doubleClick->setDeclaredValues (values);
|
|
||||||
doubleClick->setDefaultValue (edit);
|
|
||||||
doubleClick->setToolTip ("Action on double click in report table:<p>" + toolTip);
|
|
||||||
|
|
||||||
Setting *shiftDoubleClick = createSetting (Type_ComboBox, "double-s",
|
|
||||||
"Shift Double Click");
|
|
||||||
shiftDoubleClick->setDeclaredValues (values);
|
|
||||||
shiftDoubleClick->setDefaultValue (remove);
|
|
||||||
shiftDoubleClick->setToolTip ("Action on shift double click in report table:<p>" + toolTip);
|
|
||||||
|
|
||||||
Setting *ctrlDoubleClick = createSetting (Type_ComboBox, "double-c",
|
|
||||||
"Control Double Click");
|
|
||||||
ctrlDoubleClick->setDeclaredValues (values);
|
|
||||||
ctrlDoubleClick->setDefaultValue (editAndRemove);
|
|
||||||
ctrlDoubleClick->setToolTip ("Action on control double click in report table:<p>" + toolTip);
|
|
||||||
|
|
||||||
Setting *shiftCtrlDoubleClick = createSetting (Type_ComboBox, "double-sc",
|
|
||||||
"Shift Control Double Click");
|
|
||||||
shiftCtrlDoubleClick->setDeclaredValues (values);
|
|
||||||
shiftCtrlDoubleClick->setDefaultValue (none);
|
|
||||||
shiftCtrlDoubleClick->setToolTip ("Action on shift control double click in report table:<p>" + toolTip);
|
|
||||||
}
|
|
||||||
|
|
||||||
declareSection ("search", "Search & Replace");
|
|
||||||
{
|
|
||||||
Setting *before = createSetting (Type_SpinBox, "char-before",
|
|
||||||
"Characters before search string");
|
|
||||||
before->setDefaultValue (10);
|
|
||||||
before->setRange (0, 1000);
|
|
||||||
before->setToolTip ("Maximum number of character to display in search result before the searched text");
|
|
||||||
|
|
||||||
Setting *after = createSetting (Type_SpinBox, "char-after",
|
|
||||||
"Characters after search string");
|
|
||||||
after->setDefaultValue (10);
|
|
||||||
after->setRange (0, 1000);
|
|
||||||
after->setToolTip ("Maximum number of character to display in search result after the searched text");
|
|
||||||
|
|
||||||
Setting *autoDelete = createSetting (Type_CheckBox, "auto-delete", "Delete row from result table after a successful replace");
|
|
||||||
autoDelete->setDefaultValue ("true");
|
|
||||||
}
|
|
||||||
|
|
||||||
declareSection ("script-editor", "Scripts");
|
|
||||||
{
|
|
||||||
Setting *lineNum = createSetting (Type_CheckBox, "show-linenum", "Show Line Numbers");
|
|
||||||
lineNum->setDefaultValue ("true");
|
|
||||||
lineNum->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.");
|
|
||||||
|
|
||||||
Setting *monoFont = createSetting (Type_CheckBox, "mono-font", "Use monospace font");
|
|
||||||
monoFont->setDefaultValue ("true");
|
|
||||||
monoFont->setToolTip ("Whether to use monospaced fonts on script edit subview.");
|
|
||||||
|
|
||||||
QString tooltip =
|
|
||||||
"\n#RGB (each of R, G, and B is a single hex digit)"
|
|
||||||
"\n#RRGGBB"
|
|
||||||
"\n#RRRGGGBBB"
|
|
||||||
"\n#RRRRGGGGBBBB"
|
|
||||||
"\nA name from the list of colors defined in the list of SVG color keyword names."
|
|
||||||
"\nX11 color names may also work.";
|
|
||||||
|
|
||||||
QString modeNormal ("Normal");
|
|
||||||
|
|
||||||
QStringList modes;
|
|
||||||
modes << "Ignore" << modeNormal << "Strict";
|
|
||||||
|
|
||||||
Setting *warnings = createSetting (Type_ComboBox, "warnings",
|
|
||||||
"Warning Mode");
|
|
||||||
warnings->setDeclaredValues (modes);
|
|
||||||
warnings->setDefaultValue (modeNormal);
|
|
||||||
warnings->setToolTip ("<ul>How to handle warning messages during compilation:<p>"
|
|
||||||
"<li>Ignore: Do not report warning</li>"
|
|
||||||
"<li>Normal: Report warning as a warning</li>"
|
|
||||||
"<li>Strict: Promote warning to an error</li>"
|
|
||||||
"</ul>");
|
|
||||||
|
|
||||||
Setting *toolbar = createSetting (Type_CheckBox, "toolbar", "Show toolbar");
|
|
||||||
toolbar->setDefaultValue ("true");
|
|
||||||
|
|
||||||
Setting *delay = createSetting (Type_SpinBox, "compile-delay",
|
|
||||||
"Delay between updating of source errors");
|
|
||||||
delay->setDefaultValue (100);
|
|
||||||
delay->setRange (0, 10000);
|
|
||||||
delay->setToolTip ("Delay in milliseconds");
|
|
||||||
|
|
||||||
Setting *formatInt = createSetting (Type_LineEdit, "colour-int", "Highlight Colour: Int");
|
|
||||||
formatInt->setDefaultValues (QStringList() << "Dark magenta");
|
|
||||||
formatInt->setToolTip ("(Default: Green) Use one of the following formats:" + tooltip);
|
|
||||||
|
|
||||||
Setting *formatFloat = createSetting (Type_LineEdit, "colour-float", "Highlight Colour: Float");
|
|
||||||
formatFloat->setDefaultValues (QStringList() << "Magenta");
|
|
||||||
formatFloat->setToolTip ("(Default: Magenta) Use one of the following formats:" + tooltip);
|
|
||||||
|
|
||||||
Setting *formatName = createSetting (Type_LineEdit, "colour-name", "Highlight Colour: Name");
|
|
||||||
formatName->setDefaultValues (QStringList() << "Gray");
|
|
||||||
formatName->setToolTip ("(Default: Gray) Use one of the following formats:" + tooltip);
|
|
||||||
|
|
||||||
Setting *formatKeyword = createSetting (Type_LineEdit, "colour-keyword", "Highlight Colour: Keyword");
|
|
||||||
formatKeyword->setDefaultValues (QStringList() << "Red");
|
|
||||||
formatKeyword->setToolTip ("(Default: Red) Use one of the following formats:" + tooltip);
|
|
||||||
|
|
||||||
Setting *formatSpecial = createSetting (Type_LineEdit, "colour-special", "Highlight Colour: Special");
|
|
||||||
formatSpecial->setDefaultValues (QStringList() << "Dark yellow");
|
|
||||||
formatSpecial->setToolTip ("(Default: Dark yellow) Use one of the following formats:" + tooltip);
|
|
||||||
|
|
||||||
Setting *formatComment = createSetting (Type_LineEdit, "colour-comment", "Highlight Colour: Comment");
|
|
||||||
formatComment->setDefaultValues (QStringList() << "Green");
|
|
||||||
formatComment->setToolTip ("(Default: Green) Use one of the following formats:" + tooltip);
|
|
||||||
|
|
||||||
Setting *formatId = createSetting (Type_LineEdit, "colour-id", "Highlight Colour: Id");
|
|
||||||
formatId->setDefaultValues (QStringList() << "Blue");
|
|
||||||
formatId->setToolTip ("(Default: Blue) Use one of the following formats:" + tooltip);
|
|
||||||
}
|
|
||||||
|
|
||||||
declareSection ("general-input", "General Input");
|
|
||||||
{
|
|
||||||
Setting *cycle = createSetting (Type_CheckBox, "cycle", "Cyclic next/previous");
|
|
||||||
cycle->setDefaultValue ("false");
|
|
||||||
cycle->setToolTip ("When using next/previous functions at the last/first item of a "
|
|
||||||
"list go to the first/last item");
|
|
||||||
}
|
|
||||||
|
|
||||||
declareSection ("scene-input", "3D Scene Input");
|
|
||||||
{
|
|
||||||
QString left ("Left Mouse-Button");
|
|
||||||
QString cLeft ("Ctrl-Left Mouse-Button");
|
|
||||||
QString right ("Right Mouse-Button");
|
|
||||||
QString cRight ("Ctrl-Right Mouse-Button");
|
|
||||||
QString middle ("Middle Mouse-Button");
|
|
||||||
QString cMiddle ("Ctrl-Middle Mouse-Button");
|
|
||||||
|
|
||||||
QStringList values;
|
|
||||||
values << left << cLeft << right << cRight << middle << cMiddle;
|
|
||||||
|
|
||||||
Setting *primaryNavigation = createSetting (Type_ComboBox, "p-navi", "Primary Camera Navigation Button");
|
|
||||||
primaryNavigation->setDeclaredValues (values);
|
|
||||||
primaryNavigation->setDefaultValue (left);
|
|
||||||
|
|
||||||
Setting *secondaryNavigation = createSetting (Type_ComboBox, "s-navi", "Secondary Camera Navigation Button");
|
|
||||||
secondaryNavigation->setDeclaredValues (values);
|
|
||||||
secondaryNavigation->setDefaultValue (cLeft);
|
|
||||||
|
|
||||||
Setting *primaryEditing = createSetting (Type_ComboBox, "p-edit", "Primary Editing Button");
|
|
||||||
primaryEditing->setDeclaredValues (values);
|
|
||||||
primaryEditing->setDefaultValue (right);
|
|
||||||
|
|
||||||
Setting *secondaryEditing = createSetting (Type_ComboBox, "s-edit", "Secondary Editing Button");
|
|
||||||
secondaryEditing->setDeclaredValues (values);
|
|
||||||
secondaryEditing->setDefaultValue (cRight);
|
|
||||||
|
|
||||||
Setting *selection = createSetting (Type_ComboBox, "select", "Selection Button");
|
|
||||||
selection->setDeclaredValues (values);
|
|
||||||
selection->setDefaultValue (middle);
|
|
||||||
|
|
||||||
Setting *contextSensitive = createSetting (Type_CheckBox, "context-select", "Context Sensitive Selection");
|
|
||||||
contextSensitive->setDefaultValue ("false");
|
|
||||||
|
|
||||||
Setting *dragMouseSensitivity = createSetting (Type_DoubleSpinBox, "drag-factor",
|
|
||||||
"Mouse sensitivity during drag operations");
|
|
||||||
dragMouseSensitivity->setDefaultValue (1.0);
|
|
||||||
dragMouseSensitivity->setRange (0.001, 100.0);
|
|
||||||
|
|
||||||
Setting *dragWheelSensitivity = createSetting (Type_DoubleSpinBox, "drag-wheel-factor",
|
|
||||||
"Mouse wheel sensitivity during drag operations");
|
|
||||||
dragWheelSensitivity->setDefaultValue (1.0);
|
|
||||||
dragWheelSensitivity->setRange (0.001, 100.0);
|
|
||||||
|
|
||||||
Setting *dragShiftFactor = createSetting (Type_DoubleSpinBox, "drag-shift-factor",
|
|
||||||
"Acceleration factor during drag operations while holding down shift");
|
|
||||||
dragShiftFactor->setDefaultValue (4.0);
|
|
||||||
dragShiftFactor->setRange (0.001, 100.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
/******************************************************************
|
|
||||||
* There are three types of values:
|
|
||||||
*
|
|
||||||
* Declared values
|
|
||||||
*
|
|
||||||
* Pre-determined values, typically for
|
|
||||||
* combobox drop downs and boolean (radiobutton / checkbox) labels.
|
|
||||||
* These values represent the total possible list of values that
|
|
||||||
* may define a setting. No other values are allowed.
|
|
||||||
*
|
|
||||||
* Defined values
|
|
||||||
*
|
|
||||||
* Values which represent the actual, current value of
|
|
||||||
* a setting. For settings with declared values, this must be one
|
|
||||||
* or several declared values, as appropriate.
|
|
||||||
*
|
|
||||||
* Proxy values
|
|
||||||
* Values the proxy master updates the proxy slave when
|
|
||||||
* it's own definition is set / changed. These are definitions for
|
|
||||||
* proxy slave settings, but must match any declared values the
|
|
||||||
* proxy slave has, if any.
|
|
||||||
*******************************************************************/
|
|
||||||
/*
|
|
||||||
//create setting objects, specifying the basic widget type,
|
|
||||||
//the page name, and the view name
|
|
||||||
|
|
||||||
Setting *masterBoolean = createSetting (Type_RadioButton, section,
|
|
||||||
"Master Proxy");
|
|
||||||
|
|
||||||
Setting *slaveBoolean = createSetting (Type_CheckBox, section,
|
|
||||||
"Proxy Checkboxes");
|
|
||||||
|
|
||||||
Setting *slaveSingleText = createSetting (Type_LineEdit, section,
|
|
||||||
"Proxy TextBox 1");
|
|
||||||
|
|
||||||
Setting *slaveMultiText = createSetting (Type_LineEdit, section,
|
|
||||||
"ProxyTextBox 2");
|
|
||||||
|
|
||||||
Setting *slaveAlphaSpinbox = createSetting (Type_SpinBox, section,
|
|
||||||
"Alpha Spinbox");
|
|
||||||
|
|
||||||
Setting *slaveIntegerSpinbox = createSetting (Type_SpinBox, section,
|
|
||||||
"Int Spinbox");
|
|
||||||
|
|
||||||
Setting *slaveDoubleSpinbox = createSetting (Type_DoubleSpinBox,
|
|
||||||
section, "Double Spinbox");
|
|
||||||
|
|
||||||
Setting *slaveSlider = createSetting (Type_Slider, section, "Slider");
|
|
||||||
|
|
||||||
Setting *slaveDial = createSetting (Type_Dial, section, "Dial");
|
|
||||||
|
|
||||||
//set declared values for selected views
|
|
||||||
masterBoolean->setDeclaredValues (QStringList()
|
|
||||||
<< "Profile One" << "Profile Two"
|
|
||||||
<< "Profile Three" << "Profile Four");
|
|
||||||
|
|
||||||
slaveBoolean->setDeclaredValues (QStringList()
|
|
||||||
<< "One" << "Two" << "Three" << "Four" << "Five");
|
|
||||||
|
|
||||||
slaveAlphaSpinbox->setDeclaredValues (QStringList()
|
|
||||||
<< "One" << "Two" << "Three" << "Four");
|
|
||||||
|
|
||||||
|
|
||||||
masterBoolean->addProxy (slaveBoolean, QList <QStringList>()
|
|
||||||
<< (QStringList() << "One" << "Three")
|
|
||||||
<< (QStringList() << "One" << "Three")
|
|
||||||
<< (QStringList() << "One" << "Three" << "Five")
|
|
||||||
<< (QStringList() << "Two" << "Four")
|
|
||||||
);
|
|
||||||
|
|
||||||
masterBoolean->addProxy (slaveSingleText, QList <QStringList>()
|
|
||||||
<< (QStringList() << "Text A")
|
|
||||||
<< (QStringList() << "Text B")
|
|
||||||
<< (QStringList() << "Text A")
|
|
||||||
<< (QStringList() << "Text C")
|
|
||||||
);
|
|
||||||
|
|
||||||
masterBoolean->addProxy (slaveMultiText, QList <QStringList>()
|
|
||||||
<< (QStringList() << "One" << "Three")
|
|
||||||
<< (QStringList() << "One" << "Three")
|
|
||||||
<< (QStringList() << "One" << "Three" << "Five")
|
|
||||||
<< (QStringList() << "Two" << "Four")
|
|
||||||
);
|
|
||||||
|
|
||||||
masterBoolean->addProxy (slaveAlphaSpinbox, QList <QStringList>()
|
|
||||||
<< (QStringList() << "Four")
|
|
||||||
<< (QStringList() << "Three")
|
|
||||||
<< (QStringList() << "Two")
|
|
||||||
<< (QStringList() << "One"));
|
|
||||||
|
|
||||||
masterBoolean->addProxy (slaveIntegerSpinbox, QList <QStringList> ()
|
|
||||||
<< (QStringList() << "0")
|
|
||||||
<< (QStringList() << "7")
|
|
||||||
<< (QStringList() << "14")
|
|
||||||
<< (QStringList() << "21"));
|
|
||||||
|
|
||||||
masterBoolean->addProxy (slaveDoubleSpinbox, QList <QStringList> ()
|
|
||||||
<< (QStringList() << "0.17")
|
|
||||||
<< (QStringList() << "0.34")
|
|
||||||
<< (QStringList() << "0.51")
|
|
||||||
<< (QStringList() << "0.68"));
|
|
||||||
|
|
||||||
masterBoolean->addProxy (slaveSlider, QList <QStringList> ()
|
|
||||||
<< (QStringList() << "25")
|
|
||||||
<< (QStringList() << "50")
|
|
||||||
<< (QStringList() << "75")
|
|
||||||
<< (QStringList() << "100")
|
|
||||||
);
|
|
||||||
|
|
||||||
masterBoolean->addProxy (slaveDial, QList <QStringList> ()
|
|
||||||
<< (QStringList() << "25")
|
|
||||||
<< (QStringList() << "50")
|
|
||||||
<< (QStringList() << "75")
|
|
||||||
<< (QStringList() << "100")
|
|
||||||
);
|
|
||||||
|
|
||||||
//settings with proxies are not serialized by default
|
|
||||||
//other settings non-serialized for demo purposes
|
|
||||||
slaveBoolean->setSerializable (false);
|
|
||||||
slaveSingleText->setSerializable (false);
|
|
||||||
slaveMultiText->setSerializable (false);
|
|
||||||
slaveAlphaSpinbox->setSerializable (false);
|
|
||||||
slaveIntegerSpinbox->setSerializable (false);
|
|
||||||
slaveDoubleSpinbox->setSerializable (false);
|
|
||||||
slaveSlider->setSerializable (false);
|
|
||||||
slaveDial->setSerializable (false);
|
|
||||||
|
|
||||||
slaveBoolean->setDefaultValues (QStringList()
|
|
||||||
<< "One" << "Three" << "Five");
|
|
||||||
|
|
||||||
slaveSingleText->setDefaultValue ("Text A");
|
|
||||||
|
|
||||||
slaveMultiText->setDefaultValues (QStringList()
|
|
||||||
<< "One" << "Three" << "Five");
|
|
||||||
|
|
||||||
slaveSingleText->setWidgetWidth (24);
|
|
||||||
slaveMultiText->setWidgetWidth (24);
|
|
||||||
|
|
||||||
slaveAlphaSpinbox->setDefaultValue ("Two");
|
|
||||||
slaveAlphaSpinbox->setWidgetWidth (20);
|
|
||||||
//slaveAlphaSpinbox->setPrefix ("No. ");
|
|
||||||
//slaveAlphaSpinbox->setSuffix ("!");
|
|
||||||
slaveAlphaSpinbox->setWrapping (true);
|
|
||||||
|
|
||||||
slaveIntegerSpinbox->setDefaultValue (14);
|
|
||||||
slaveIntegerSpinbox->setMinimum (0);
|
|
||||||
slaveIntegerSpinbox->setMaximum (58);
|
|
||||||
slaveIntegerSpinbox->setPrefix ("$");
|
|
||||||
slaveIntegerSpinbox->setSuffix (".00");
|
|
||||||
slaveIntegerSpinbox->setWidgetWidth (10);
|
|
||||||
slaveIntegerSpinbox->setSpecialValueText ("Nothing!");
|
|
||||||
|
|
||||||
slaveDoubleSpinbox->setDefaultValue (0.51);
|
|
||||||
slaveDoubleSpinbox->setSingleStep(0.17);
|
|
||||||
slaveDoubleSpinbox->setMaximum(4.0);
|
|
||||||
|
|
||||||
slaveSlider->setMinimum (0);
|
|
||||||
slaveSlider->setMaximum (100);
|
|
||||||
slaveSlider->setDefaultValue (75);
|
|
||||||
slaveSlider->setWidgetWidth (100);
|
|
||||||
slaveSlider->setTicksAbove (true);
|
|
||||||
slaveSlider->setTickInterval (25);
|
|
||||||
|
|
||||||
slaveDial->setMinimum (0);
|
|
||||||
slaveDial->setMaximum (100);
|
|
||||||
slaveDial->setSingleStep (5);
|
|
||||||
slaveDial->setDefaultValue (75);
|
|
||||||
slaveDial->setTickInterval (25);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CSMSettings::UserSettings::~UserSettings()
|
|
||||||
{
|
|
||||||
sUserSettingsInstance = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::UserSettings::loadSettings (const QString &fileName)
|
|
||||||
{
|
|
||||||
QString userFilePath = QString::fromUtf8
|
|
||||||
(mCfgMgr.getUserConfigPath().string().c_str());
|
|
||||||
|
|
||||||
QString globalFilePath = QString::fromUtf8
|
|
||||||
(mCfgMgr.getGlobalPath().string().c_str());
|
|
||||||
|
|
||||||
QString otherFilePath = globalFilePath;
|
|
||||||
|
|
||||||
//test for local only if global fails (uninstalled copy)
|
|
||||||
if (!QFile (globalFilePath + fileName).exists())
|
|
||||||
{
|
|
||||||
//if global is invalid, use the local path
|
|
||||||
otherFilePath = QString::fromUtf8
|
|
||||||
(mCfgMgr.getLocalPath().string().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
QSettings::setPath
|
|
||||||
(QSettings::IniFormat, QSettings::UserScope, userFilePath);
|
|
||||||
|
|
||||||
QSettings::setPath
|
|
||||||
(QSettings::IniFormat, QSettings::SystemScope, otherFilePath);
|
|
||||||
|
|
||||||
mSettingDefinitions = new QSettings
|
|
||||||
(QSettings::IniFormat, QSettings::UserScope, "opencs", QString(), this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the key is not found create one with a default value
|
|
||||||
QString CSMSettings::UserSettings::setting(const QString &viewKey, const QString &value)
|
|
||||||
{
|
|
||||||
if(mSettingDefinitions->contains(viewKey))
|
|
||||||
return settingValue(viewKey);
|
|
||||||
else if(value != QString())
|
|
||||||
{
|
|
||||||
mSettingDefinitions->setValue (viewKey, QStringList() << value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSMSettings::UserSettings::hasSettingDefinitions (const QString &viewKey) const
|
|
||||||
{
|
|
||||||
return (mSettingDefinitions->contains (viewKey));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::UserSettings::setDefinitions
|
|
||||||
(const QString &key, const QStringList &list)
|
|
||||||
{
|
|
||||||
mSettingDefinitions->setValue (key, list);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::UserSettings::saveDefinitions() const
|
|
||||||
{
|
|
||||||
mSettingDefinitions->sync();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CSMSettings::UserSettings::settingValue (const QString &settingKey)
|
|
||||||
{
|
|
||||||
QStringList defs;
|
|
||||||
|
|
||||||
if (!mSettingDefinitions->contains (settingKey))
|
|
||||||
return QString();
|
|
||||||
|
|
||||||
defs = mSettingDefinitions->value (settingKey).toStringList();
|
|
||||||
|
|
||||||
if (defs.isEmpty())
|
|
||||||
return QString();
|
|
||||||
|
|
||||||
return defs.at(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
CSMSettings::UserSettings& CSMSettings::UserSettings::instance()
|
|
||||||
{
|
|
||||||
assert(sUserSettingsInstance);
|
|
||||||
return *sUserSettingsInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::UserSettings::updateUserSetting(const QString &settingKey,
|
|
||||||
const QStringList &list)
|
|
||||||
{
|
|
||||||
mSettingDefinitions->setValue (settingKey ,list);
|
|
||||||
|
|
||||||
emit userSettingUpdated (settingKey, list);
|
|
||||||
}
|
|
||||||
|
|
||||||
CSMSettings::Setting *CSMSettings::UserSettings::findSetting
|
|
||||||
(const QString &pageName, const QString &settingName)
|
|
||||||
{
|
|
||||||
foreach (Setting *setting, mSettings)
|
|
||||||
{
|
|
||||||
if (setting->name() == settingName)
|
|
||||||
{
|
|
||||||
if (setting->page() == pageName)
|
|
||||||
return setting;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::UserSettings::removeSetting
|
|
||||||
(const QString &pageName, const QString &settingName)
|
|
||||||
{
|
|
||||||
if (mSettings.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QList <Setting *>::iterator removeIterator = mSettings.begin();
|
|
||||||
|
|
||||||
while (removeIterator != mSettings.end())
|
|
||||||
{
|
|
||||||
if ((*removeIterator)->name() == settingName)
|
|
||||||
{
|
|
||||||
if ((*removeIterator)->page() == pageName)
|
|
||||||
{
|
|
||||||
mSettings.erase (removeIterator);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
removeIterator++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CSMSettings::SettingPageMap CSMSettings::UserSettings::settingPageMap() const
|
|
||||||
{
|
|
||||||
SettingPageMap pageMap;
|
|
||||||
|
|
||||||
foreach (Setting *setting, mSettings)
|
|
||||||
{
|
|
||||||
SettingPageMap::iterator iter = pageMap.find (setting->page());
|
|
||||||
|
|
||||||
if (iter==pageMap.end())
|
|
||||||
{
|
|
||||||
QPair<QString, QList <Setting *> > value;
|
|
||||||
|
|
||||||
std::map<QString, QString>::const_iterator iter2 =
|
|
||||||
mSectionLabels.find (setting->page());
|
|
||||||
|
|
||||||
value.first = iter2!=mSectionLabels.end() ? iter2->second : "";
|
|
||||||
|
|
||||||
iter = pageMap.insert (setting->page(), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
iter->second.append (setting);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pageMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
CSMSettings::Setting *CSMSettings::UserSettings::createSetting
|
|
||||||
(CSMSettings::SettingType type, const QString &name, const QString& label)
|
|
||||||
{
|
|
||||||
Setting *setting = new Setting (type, name, mSection, label);
|
|
||||||
|
|
||||||
// set useful defaults
|
|
||||||
int row = 1;
|
|
||||||
|
|
||||||
if (!mSettings.empty())
|
|
||||||
row = mSettings.back()->viewRow()+1;
|
|
||||||
|
|
||||||
setting->setViewLocation (row, 1);
|
|
||||||
|
|
||||||
setting->setColumnSpan (3);
|
|
||||||
|
|
||||||
int width = 10;
|
|
||||||
|
|
||||||
if (type==Type_CheckBox)
|
|
||||||
width = 40;
|
|
||||||
|
|
||||||
setting->setWidgetWidth (width);
|
|
||||||
|
|
||||||
if (type==Type_CheckBox)
|
|
||||||
setting->setStyleSheet ("QGroupBox { border: 0px; }");
|
|
||||||
|
|
||||||
if (type==Type_CheckBox)
|
|
||||||
setting->setDeclaredValues(QStringList() << "true" << "false");
|
|
||||||
|
|
||||||
if (type==Type_CheckBox)
|
|
||||||
setting->setSpecialValueText (setting->getLabel());
|
|
||||||
|
|
||||||
//add declaration to the model
|
|
||||||
mSettings.append (setting);
|
|
||||||
|
|
||||||
return setting;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMSettings::UserSettings::declareSection (const QString& page, const QString& label)
|
|
||||||
{
|
|
||||||
mSection = page;
|
|
||||||
mSectionLabels[page] = label;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList CSMSettings::UserSettings::definitions (const QString &viewKey) const
|
|
||||||
{
|
|
||||||
if (mSettingDefinitions->contains (viewKey))
|
|
||||||
return mSettingDefinitions->value (viewKey).toStringList();
|
|
||||||
|
|
||||||
return QStringList();
|
|
||||||
}
|
|
|
@ -1,107 +0,0 @@
|
||||||
#ifndef USERSETTINGS_HPP
|
|
||||||
#define USERSETTINGS_HPP
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include <QList>
|
|
||||||
#include <QStringList>
|
|
||||||
#include <QString>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QPair>
|
|
||||||
|
|
||||||
#include <boost/filesystem/path.hpp>
|
|
||||||
#include "support.hpp"
|
|
||||||
|
|
||||||
#ifndef Q_MOC_RUN
|
|
||||||
#include <components/files/configurationmanager.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Files { typedef std::vector<boost::filesystem::path> PathContainer;
|
|
||||||
struct ConfigurationManager;}
|
|
||||||
|
|
||||||
class QFile;
|
|
||||||
class QSettings;
|
|
||||||
|
|
||||||
namespace CSMSettings {
|
|
||||||
|
|
||||||
class Setting;
|
|
||||||
typedef QMap <QString, QPair<QString, QList <Setting *> > > SettingPageMap;
|
|
||||||
|
|
||||||
class UserSettings: public QObject
|
|
||||||
{
|
|
||||||
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
static UserSettings *sUserSettingsInstance;
|
|
||||||
const Files::ConfigurationManager& mCfgMgr;
|
|
||||||
|
|
||||||
QSettings *mSettingDefinitions;
|
|
||||||
QList <Setting *> mSettings;
|
|
||||||
QString mSection;
|
|
||||||
std::map<QString, QString> mSectionLabels;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// Singleton implementation
|
|
||||||
static UserSettings& instance();
|
|
||||||
|
|
||||||
UserSettings (const Files::ConfigurationManager& configurationManager);
|
|
||||||
~UserSettings();
|
|
||||||
|
|
||||||
UserSettings (UserSettings const &); //not implemented
|
|
||||||
UserSettings& operator= (UserSettings const &); //not implemented
|
|
||||||
|
|
||||||
/// Retrieves the settings file at all three levels (global, local and user).
|
|
||||||
void loadSettings (const QString &fileName);
|
|
||||||
|
|
||||||
/// Updates QSettings and syncs with the ini file
|
|
||||||
void setDefinitions (const QString &key, const QStringList &defs);
|
|
||||||
|
|
||||||
QString settingValue (const QString &settingKey);
|
|
||||||
|
|
||||||
///retrieve a setting object from a given page and setting name
|
|
||||||
Setting *findSetting
|
|
||||||
(const QString &pageName, const QString &settingName = QString());
|
|
||||||
|
|
||||||
///remove a setting from the list
|
|
||||||
void removeSetting
|
|
||||||
(const QString &pageName, const QString &settingName);
|
|
||||||
|
|
||||||
///Retrieve a map of the settings, keyed by page name
|
|
||||||
SettingPageMap settingPageMap() const;
|
|
||||||
|
|
||||||
///Returns a string list of defined vlaues for the specified setting
|
|
||||||
///in "page/name" format.
|
|
||||||
QStringList definitions (const QString &viewKey) const;
|
|
||||||
|
|
||||||
///Test to indicate whether or not a setting has any definitions
|
|
||||||
bool hasSettingDefinitions (const QString &viewKey) const;
|
|
||||||
|
|
||||||
///Save any unsaved changes in the QSettings object
|
|
||||||
void saveDefinitions() const;
|
|
||||||
|
|
||||||
QString setting(const QString &viewKey, const QString &value = QString());
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void buildSettingModelDefaults();
|
|
||||||
|
|
||||||
///add a new setting to the model and return it
|
|
||||||
Setting *createSetting (CSMSettings::SettingType type, const QString &name,
|
|
||||||
const QString& label);
|
|
||||||
|
|
||||||
/// Set the section for createSetting calls.
|
|
||||||
///
|
|
||||||
/// Sections can be declared multiple times.
|
|
||||||
void declareSection (const QString& page, const QString& label);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
|
|
||||||
void userSettingUpdated (const QString &, const QStringList &);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
|
|
||||||
void updateUserSetting (const QString &, const QStringList &);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif // USERSETTINGS_HPP
|
|
123
apps/opencs/model/tools/gmstcheck.cpp
Normal file
123
apps/opencs/model/tools/gmstcheck.cpp
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
#include "gmstcheck.hpp"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "../world/defaultgmsts.hpp"
|
||||||
|
|
||||||
|
CSMTools::GmstCheckStage::GmstCheckStage(const CSMWorld::IdCollection<ESM::GameSetting>& gameSettings)
|
||||||
|
: mGameSettings(gameSettings)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int CSMTools::GmstCheckStage::setup()
|
||||||
|
{
|
||||||
|
return mGameSettings.getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::GmstCheckStage::perform(int stage, CSMDoc::Messages& messages)
|
||||||
|
{
|
||||||
|
const CSMWorld::Record<ESM::GameSetting>& record = mGameSettings.getRecord (stage);
|
||||||
|
|
||||||
|
if (record.isDeleted())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const ESM::GameSetting& gmst = record.get();
|
||||||
|
|
||||||
|
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Gmst, gmst.mId);
|
||||||
|
|
||||||
|
// Test for empty string
|
||||||
|
if (gmst.mValue.getType() == ESM::VT_String && gmst.mValue.getString().empty())
|
||||||
|
messages.add(id, gmst.mId + " is an empty string", "", CSMDoc::Message::Severity_Warning);
|
||||||
|
|
||||||
|
// Checking type and limits
|
||||||
|
// optimization - compare it to lists based on naming convention (f-float,i-int,s-string)
|
||||||
|
if (gmst.mId[0] == 'f')
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < CSMWorld::DefaultGmsts::FloatCount; ++i)
|
||||||
|
{
|
||||||
|
if (gmst.mId == CSMWorld::DefaultGmsts::Floats[i])
|
||||||
|
{
|
||||||
|
if (gmst.mValue.getType() != ESM::VT_Float)
|
||||||
|
{
|
||||||
|
std::ostringstream stream;
|
||||||
|
stream << "Expected float type for " << gmst.mId << " but found "
|
||||||
|
<< varTypeToString(gmst.mValue.getType()) << " type";
|
||||||
|
|
||||||
|
messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gmst.mValue.getFloat() < CSMWorld::DefaultGmsts::FloatLimits[i*2])
|
||||||
|
messages.add(id, gmst.mId + " is less than the suggested range", "",
|
||||||
|
CSMDoc::Message::Severity_Warning);
|
||||||
|
|
||||||
|
if (gmst.mValue.getFloat() > CSMWorld::DefaultGmsts::FloatLimits[i*2+1])
|
||||||
|
messages.add(id, gmst.mId + " is more than the suggested range", "",
|
||||||
|
CSMDoc::Message::Severity_Warning);
|
||||||
|
|
||||||
|
break; // for loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (gmst.mId[0] == 'i')
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < CSMWorld::DefaultGmsts::IntCount; ++i)
|
||||||
|
{
|
||||||
|
if (gmst.mId == CSMWorld::DefaultGmsts::Ints[i])
|
||||||
|
{
|
||||||
|
if (gmst.mValue.getType() != ESM::VT_Int)
|
||||||
|
{
|
||||||
|
std::ostringstream stream;
|
||||||
|
stream << "Expected int type for " << gmst.mId << " but found "
|
||||||
|
<< varTypeToString(gmst.mValue.getType()) << " type";
|
||||||
|
|
||||||
|
messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gmst.mValue.getInteger() < CSMWorld::DefaultGmsts::IntLimits[i*2])
|
||||||
|
messages.add(id, gmst.mId + " is less than the suggested range", "",
|
||||||
|
CSMDoc::Message::Severity_Warning);
|
||||||
|
|
||||||
|
if (gmst.mValue.getInteger() > CSMWorld::DefaultGmsts::IntLimits[i*2+1])
|
||||||
|
messages.add(id, gmst.mId + " is more than the suggested range", "",
|
||||||
|
CSMDoc::Message::Severity_Warning);
|
||||||
|
|
||||||
|
break; // for loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (gmst.mId[0] == 's')
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < CSMWorld::DefaultGmsts::StringCount; ++i)
|
||||||
|
{
|
||||||
|
if (gmst.mId == CSMWorld::DefaultGmsts::Strings[i])
|
||||||
|
{
|
||||||
|
ESM::VarType type = gmst.mValue.getType();
|
||||||
|
|
||||||
|
if (type != ESM::VT_String && type != ESM::VT_None)
|
||||||
|
{
|
||||||
|
std::ostringstream stream;
|
||||||
|
stream << "Expected string or none type for " << gmst.mId << " but found "
|
||||||
|
<< varTypeToString(gmst.mValue.getType()) << " type";
|
||||||
|
|
||||||
|
messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
break; // for loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CSMTools::GmstCheckStage::varTypeToString(ESM::VarType type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case ESM::VT_Unknown: return "unknown";
|
||||||
|
case ESM::VT_None: return "none";
|
||||||
|
case ESM::VT_Short: return "short";
|
||||||
|
case ESM::VT_Int: return "int";
|
||||||
|
case ESM::VT_Long: return "long";
|
||||||
|
case ESM::VT_Float: return "float";
|
||||||
|
case ESM::VT_String: return "string";
|
||||||
|
default: return "unhandled";
|
||||||
|
}
|
||||||
|
}
|
34
apps/opencs/model/tools/gmstcheck.hpp
Normal file
34
apps/opencs/model/tools/gmstcheck.hpp
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef CSM_TOOLS_GMSTCHECK_H
|
||||||
|
#define CSM_TOOLS_GMSTCHECK_H
|
||||||
|
|
||||||
|
#include <components/esm/loadgmst.hpp>
|
||||||
|
|
||||||
|
#include "../world/idcollection.hpp"
|
||||||
|
|
||||||
|
#include "../doc/stage.hpp"
|
||||||
|
|
||||||
|
namespace CSMTools
|
||||||
|
{
|
||||||
|
/// \brief VerifyStage: make sure that GMSTs are alright
|
||||||
|
class GmstCheckStage : public CSMDoc::Stage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
GmstCheckStage(const CSMWorld::IdCollection<ESM::GameSetting>& gameSettings);
|
||||||
|
|
||||||
|
virtual int setup();
|
||||||
|
///< \return number of steps
|
||||||
|
|
||||||
|
virtual void perform(int stage, CSMDoc::Messages& messages);
|
||||||
|
///< Messages resulting from this stage will be appended to \a messages
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
const CSMWorld::IdCollection<ESM::GameSetting>& mGameSettings;
|
||||||
|
|
||||||
|
std::string varTypeToString(ESM::VarType);
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
void addMessageIfNotEmpty(CSMDoc::Messages &messages, const CSMWorld::UniversalId &id, const std::string text)
|
void addMessageIfNotEmpty(CSMDoc::Messages &messages, const CSMWorld::UniversalId &id, const std::string& text)
|
||||||
{
|
{
|
||||||
if (!text.empty())
|
if (!text.empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -398,6 +398,9 @@ void CSMTools::ReferenceableCheckStage::containerCheck(
|
||||||
if (container.mName.empty())
|
if (container.mName.empty())
|
||||||
messages.push_back (std::make_pair (id, container.mId + " has an empty name"));
|
messages.push_back (std::make_pair (id, container.mId + " has an empty name"));
|
||||||
|
|
||||||
|
//checking contained items
|
||||||
|
inventoryListCheck(container.mInventory.mList, messages, id.toString());
|
||||||
|
|
||||||
// Check that mentioned scripts exist
|
// Check that mentioned scripts exist
|
||||||
scriptCheck<ESM::Container>(container, messages, id.toString());
|
scriptCheck<ESM::Container>(container, messages, id.toString());
|
||||||
}
|
}
|
||||||
|
@ -468,6 +471,12 @@ void CSMTools::ReferenceableCheckStage::creatureCheck (
|
||||||
if (creature.mData.mGold < 0) //It seems that this is for gold in merchant creatures
|
if (creature.mData.mGold < 0) //It seems that this is for gold in merchant creatures
|
||||||
messages.push_back (std::make_pair (id, creature.mId + " has negative gold "));
|
messages.push_back (std::make_pair (id, creature.mId + " has negative gold "));
|
||||||
|
|
||||||
|
if (creature.mScale == 0)
|
||||||
|
messages.push_back (std::make_pair (id, creature.mId + " has zero scale value"));
|
||||||
|
|
||||||
|
// Check inventory
|
||||||
|
inventoryListCheck(creature.mInventory.mList, messages, id.toString());
|
||||||
|
|
||||||
// Check that mentioned scripts exist
|
// Check that mentioned scripts exist
|
||||||
scriptCheck<ESM::Creature>(creature, messages, id.toString());
|
scriptCheck<ESM::Creature>(creature, messages, id.toString());
|
||||||
}
|
}
|
||||||
|
@ -739,6 +748,9 @@ void CSMTools::ReferenceableCheckStage::npcCheck (
|
||||||
|
|
||||||
//TODO: reputation, Disposition, rank, everything else
|
//TODO: reputation, Disposition, rank, everything else
|
||||||
|
|
||||||
|
// Check inventory
|
||||||
|
inventoryListCheck(npc.mInventory.mList, messages, id.toString());
|
||||||
|
|
||||||
// Check that mentioned scripts exist
|
// Check that mentioned scripts exist
|
||||||
scriptCheck<ESM::NPC>(npc, messages, id.toString());
|
scriptCheck<ESM::NPC>(npc, messages, id.toString());
|
||||||
}
|
}
|
||||||
|
@ -888,6 +900,45 @@ void CSMTools::ReferenceableCheckStage::finalCheck (CSMDoc::Messages& messages)
|
||||||
"There is no player record"));
|
"There is no player record"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSMTools::ReferenceableCheckStage::inventoryListCheck(
|
||||||
|
const std::vector<ESM::ContItem>& itemList,
|
||||||
|
CSMDoc::Messages& messages,
|
||||||
|
const std::string& id)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < itemList.size(); ++i)
|
||||||
|
{
|
||||||
|
std::string itemName = itemList[i].mItem.toString();
|
||||||
|
CSMWorld::RefIdData::LocalIndex localIndex = mReferencables.searchId(itemName);
|
||||||
|
|
||||||
|
if (localIndex.first == -1)
|
||||||
|
messages.push_back (std::make_pair (id,
|
||||||
|
id + " contains non-existing item (" + itemName + ")"));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Needs to accomodate Containers, Creatures, and NPCs
|
||||||
|
switch (localIndex.second)
|
||||||
|
{
|
||||||
|
case CSMWorld::UniversalId::Type_Potion:
|
||||||
|
case CSMWorld::UniversalId::Type_Apparatus:
|
||||||
|
case CSMWorld::UniversalId::Type_Armor:
|
||||||
|
case CSMWorld::UniversalId::Type_Book:
|
||||||
|
case CSMWorld::UniversalId::Type_Clothing:
|
||||||
|
case CSMWorld::UniversalId::Type_Ingredient:
|
||||||
|
case CSMWorld::UniversalId::Type_Light:
|
||||||
|
case CSMWorld::UniversalId::Type_Lockpick:
|
||||||
|
case CSMWorld::UniversalId::Type_Miscellaneous:
|
||||||
|
case CSMWorld::UniversalId::Type_Probe:
|
||||||
|
case CSMWorld::UniversalId::Type_Repair:
|
||||||
|
case CSMWorld::UniversalId::Type_Weapon:
|
||||||
|
case CSMWorld::UniversalId::Type_ItemLevelledList:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
messages.push_back (std::make_pair(id,
|
||||||
|
id + " contains item of invalid type (" + itemName + ")"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Templates begins here
|
//Templates begins here
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,9 @@ namespace CSMTools
|
||||||
//FINAL CHECK
|
//FINAL CHECK
|
||||||
void finalCheck (CSMDoc::Messages& messages);
|
void finalCheck (CSMDoc::Messages& messages);
|
||||||
|
|
||||||
//TEMPLATE CHECKS
|
//Convenience functions
|
||||||
|
void inventoryListCheck(const std::vector<ESM::ContItem>& itemList, CSMDoc::Messages& messages, const std::string& id);
|
||||||
|
|
||||||
template<typename ITEM> void inventoryItemCheck(const ITEM& someItem,
|
template<typename ITEM> void inventoryItemCheck(const ITEM& someItem,
|
||||||
CSMDoc::Messages& messages,
|
CSMDoc::Messages& messages,
|
||||||
const std::string& someID,
|
const std::string& someID,
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
#include "../world/data.hpp"
|
#include "../world/data.hpp"
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
CSMDoc::Message::Severity CSMTools::ScriptCheckStage::getSeverity (Type type)
|
CSMDoc::Message::Severity CSMTools::ScriptCheckStage::getSeverity (Type type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
|
@ -62,6 +64,15 @@ CSMTools::ScriptCheckStage::ScriptCheckStage (const CSMDoc::Document& document)
|
||||||
|
|
||||||
int CSMTools::ScriptCheckStage::setup()
|
int CSMTools::ScriptCheckStage::setup()
|
||||||
{
|
{
|
||||||
|
std::string warnings = CSMPrefs::get()["Scripts"]["warnings"].toString();
|
||||||
|
|
||||||
|
if (warnings=="Ignore")
|
||||||
|
mWarningMode = Mode_Ignore;
|
||||||
|
else if (warnings=="Normal")
|
||||||
|
mWarningMode = Mode_Normal;
|
||||||
|
else if (warnings=="Strict")
|
||||||
|
mWarningMode = Mode_Strict;
|
||||||
|
|
||||||
mContext.clear();
|
mContext.clear();
|
||||||
mMessages = 0;
|
mMessages = 0;
|
||||||
mId.clear();
|
mId.clear();
|
||||||
|
@ -116,16 +127,3 @@ void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
|
|
||||||
mMessages = 0;
|
mMessages = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::ScriptCheckStage::updateUserSetting (const QString& name, const QStringList& value)
|
|
||||||
{
|
|
||||||
if (name=="script-editor/warnings" && !value.isEmpty())
|
|
||||||
{
|
|
||||||
if (value.at (0)=="Ignore")
|
|
||||||
mWarningMode = Mode_Ignore;
|
|
||||||
else if (value.at (0)=="Normal")
|
|
||||||
mWarningMode = Mode_Normal;
|
|
||||||
else if (value.at (0)=="Strict")
|
|
||||||
mWarningMode = Mode_Strict;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -50,8 +50,6 @@ namespace CSMTools
|
||||||
|
|
||||||
virtual void perform (int stage, CSMDoc::Messages& messages);
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
///< Messages resulting from this tage will be appended to \a messages.
|
///< Messages resulting from this tage will be appended to \a messages.
|
||||||
|
|
||||||
virtual void updateUserSetting (const QString& name, const QStringList& value);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,24 +120,25 @@ QString CSMTools::Search::flatten (const QString& text) const
|
||||||
return flat;
|
return flat;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMTools::Search::Search() : mType (Type_None), mPaddingBefore (10), mPaddingAfter (10) {}
|
CSMTools::Search::Search() : mType (Type_None), mValue (0), mIdColumn (0), mTypeColumn (0),
|
||||||
|
mPaddingBefore (10), mPaddingAfter (10) {}
|
||||||
|
|
||||||
CSMTools::Search::Search (Type type, const std::string& value)
|
CSMTools::Search::Search (Type type, const std::string& value)
|
||||||
: mType (type), mText (value), mPaddingBefore (10), mPaddingAfter (10)
|
: mType (type), mText (value), mValue (0), mIdColumn (0), mTypeColumn (0), mPaddingBefore (10), mPaddingAfter (10)
|
||||||
{
|
{
|
||||||
if (type!=Type_Text && type!=Type_Id)
|
if (type!=Type_Text && type!=Type_Id)
|
||||||
throw std::logic_error ("Invalid search parameter (string)");
|
throw std::logic_error ("Invalid search parameter (string)");
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMTools::Search::Search (Type type, const QRegExp& value)
|
CSMTools::Search::Search (Type type, const QRegExp& value)
|
||||||
: mType (type), mRegExp (value), mPaddingBefore (10), mPaddingAfter (10)
|
: mType (type), mRegExp (value), mValue (0), mIdColumn (0), mTypeColumn (0), mPaddingBefore (10), mPaddingAfter (10)
|
||||||
{
|
{
|
||||||
if (type!=Type_TextRegEx && type!=Type_IdRegEx)
|
if (type!=Type_TextRegEx && type!=Type_IdRegEx)
|
||||||
throw std::logic_error ("Invalid search parameter (RegExp)");
|
throw std::logic_error ("Invalid search parameter (RegExp)");
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMTools::Search::Search (Type type, int value)
|
CSMTools::Search::Search (Type type, int value)
|
||||||
: mType (type), mValue (value), mPaddingBefore (10), mPaddingAfter (10)
|
: mType (type), mValue (value), mIdColumn (0), mTypeColumn (0), mPaddingBefore (10), mPaddingAfter (10)
|
||||||
{
|
{
|
||||||
if (type!=Type_RecordState)
|
if (type!=Type_RecordState)
|
||||||
throw std::logic_error ("invalid search parameter (int)");
|
throw std::logic_error ("invalid search parameter (int)");
|
||||||
|
|
|
@ -26,7 +26,7 @@ void CSMTools::SoundGenCheckStage::perform(int stage, CSMDoc::Messages &messages
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ESM::SoundGenerator soundGen = record.get();
|
const ESM::SoundGenerator& soundGen = record.get();
|
||||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_SoundGen, soundGen.mId);
|
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_SoundGen, soundGen.mId);
|
||||||
|
|
||||||
if (!soundGen.mCreature.empty())
|
if (!soundGen.mCreature.empty())
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "soundgencheck.hpp"
|
#include "soundgencheck.hpp"
|
||||||
#include "magiceffectcheck.hpp"
|
#include "magiceffectcheck.hpp"
|
||||||
#include "mergeoperation.hpp"
|
#include "mergeoperation.hpp"
|
||||||
|
#include "gmstcheck.hpp"
|
||||||
|
|
||||||
CSMDoc::OperationHolder *CSMTools::Tools::get (int type)
|
CSMDoc::OperationHolder *CSMTools::Tools::get (int type)
|
||||||
{
|
{
|
||||||
|
@ -53,11 +54,6 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier()
|
||||||
{
|
{
|
||||||
mVerifierOperation = new CSMDoc::Operation (CSMDoc::State_Verifying, false);
|
mVerifierOperation = new CSMDoc::Operation (CSMDoc::State_Verifying, false);
|
||||||
|
|
||||||
std::vector<QString> settings;
|
|
||||||
settings.push_back ("script-editor/warnings");
|
|
||||||
|
|
||||||
mVerifierOperation->configureSettings (settings);
|
|
||||||
|
|
||||||
connect (&mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
|
connect (&mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
|
||||||
connect (&mVerifier, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool)));
|
connect (&mVerifier, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool)));
|
||||||
connect (&mVerifier, SIGNAL (reportMessage (const CSMDoc::Message&, int)),
|
connect (&mVerifier, SIGNAL (reportMessage (const CSMDoc::Message&, int)),
|
||||||
|
@ -116,6 +112,8 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier()
|
||||||
mData.getResources (CSMWorld::UniversalId::Type_Icons),
|
mData.getResources (CSMWorld::UniversalId::Type_Icons),
|
||||||
mData.getResources (CSMWorld::UniversalId::Type_Textures)));
|
mData.getResources (CSMWorld::UniversalId::Type_Textures)));
|
||||||
|
|
||||||
|
mVerifierOperation->appendStage (new GmstCheckStage (mData.getGmsts()));
|
||||||
|
|
||||||
mVerifier.setOperation (mVerifierOperation);
|
mVerifier.setOperation (mVerifierOperation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,18 +2,15 @@
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
void CSMWorld::Cell::load (ESM::ESMReader &esm)
|
void CSMWorld::Cell::load (ESM::ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
mName = mId;
|
ESM::Cell::load (esm, isDeleted, false);
|
||||||
|
|
||||||
ESM::Cell::load (esm, false);
|
mId = mName;
|
||||||
|
if (isExterior())
|
||||||
if (!(mData.mFlags & Interior))
|
|
||||||
{
|
{
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
|
|
||||||
stream << "#" << mData.mX << " " << mData.mY;
|
stream << "#" << mData.mX << " " << mData.mY;
|
||||||
|
|
||||||
mId = stream.str();
|
mId = stream.str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace CSMWorld
|
||||||
{
|
{
|
||||||
std::string mId;
|
std::string mId;
|
||||||
|
|
||||||
void load (ESM::ESMReader &esm);
|
void load (ESM::ESMReader &esm, bool &isDeleted);
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,12 @@ namespace CSMWorld
|
||||||
template<typename ESXRecordT, typename IdAccessorT = IdAccessor<ESXRecordT> >
|
template<typename ESXRecordT, typename IdAccessorT = IdAccessor<ESXRecordT> >
|
||||||
class Collection : public CollectionBase
|
class Collection : public CollectionBase
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef ESXRecordT ESXRecord;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
std::vector<Record<ESXRecordT> > mRecords;
|
std::vector<Record<ESXRecordT> > mRecords;
|
||||||
std::map<std::string, int> mIndex;
|
std::map<std::string, int> mIndex;
|
||||||
std::vector<Column<ESXRecordT> *> mColumns;
|
std::vector<Column<ESXRecordT> *> mColumns;
|
||||||
|
|
|
@ -86,6 +86,10 @@ bool CSMWorld::ColumnBase::isId (Display display)
|
||||||
Display_InfoCondVar,
|
Display_InfoCondVar,
|
||||||
Display_InfoCondComp,
|
Display_InfoCondComp,
|
||||||
|
|
||||||
|
Display_EffectSkill,
|
||||||
|
Display_EffectAttribute,
|
||||||
|
Display_IngredEffectId,
|
||||||
|
|
||||||
Display_None
|
Display_None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,13 @@ namespace CSMWorld
|
||||||
{
|
{
|
||||||
struct ColumnBase
|
struct ColumnBase
|
||||||
{
|
{
|
||||||
|
enum TableEditModes
|
||||||
|
{
|
||||||
|
TableEdit_None, // no editing
|
||||||
|
TableEdit_Full, // edit cells and add/remove rows
|
||||||
|
TableEdit_FixedRows // edit cells only
|
||||||
|
};
|
||||||
|
|
||||||
enum Roles
|
enum Roles
|
||||||
{
|
{
|
||||||
Role_Flags = Qt::UserRole,
|
Role_Flags = Qt::UserRole,
|
||||||
|
@ -124,6 +131,10 @@ namespace CSMWorld
|
||||||
Display_String32,
|
Display_String32,
|
||||||
Display_LongString256,
|
Display_LongString256,
|
||||||
|
|
||||||
|
Display_EffectSkill, // must display at least one, unlike Display_Skill
|
||||||
|
Display_EffectAttribute, // must display at least one, unlike Display_Attribute
|
||||||
|
Display_IngredEffectId, // display none allowed, unlike Display_EffectId
|
||||||
|
|
||||||
//top level columns that nest other columns
|
//top level columns that nest other columns
|
||||||
Display_NestedHeader
|
Display_NestedHeader
|
||||||
};
|
};
|
||||||
|
@ -186,8 +197,8 @@ namespace CSMWorld
|
||||||
template<typename ESXRecordT>
|
template<typename ESXRecordT>
|
||||||
struct NestedParentColumn : public Column<ESXRecordT>
|
struct NestedParentColumn : public Column<ESXRecordT>
|
||||||
{
|
{
|
||||||
NestedParentColumn (int id, int flags = ColumnBase::Flag_Dialogue) : Column<ESXRecordT> (id,
|
NestedParentColumn (int id, int flags = ColumnBase::Flag_Dialogue, bool fixedRows = false)
|
||||||
ColumnBase::Display_NestedHeader, flags)
|
: Column<ESXRecordT> (id, ColumnBase::Display_NestedHeader, flags), mFixedRows(fixedRows)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||||
|
@ -198,13 +209,20 @@ namespace CSMWorld
|
||||||
|
|
||||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||||
{
|
{
|
||||||
return true; // required by IdTree::hasChildren()
|
// by default editable; also see IdTree::hasChildren()
|
||||||
|
if (mFixedRows)
|
||||||
|
return QVariant::fromValue(ColumnBase::TableEdit_FixedRows);
|
||||||
|
else
|
||||||
|
return QVariant::fromValue(ColumnBase::TableEdit_Full);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool isEditable() const
|
virtual bool isEditable() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool mFixedRows;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NestedChildColumn : public NestableColumn
|
struct NestedChildColumn : public NestableColumn
|
||||||
|
@ -219,4 +237,6 @@ namespace CSMWorld
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(CSMWorld::ColumnBase::TableEditModes)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -93,7 +93,7 @@ void CSMWorld::CommandDispatcher::setEditLock (bool locked)
|
||||||
void CSMWorld::CommandDispatcher::setSelection (const std::vector<std::string>& selection)
|
void CSMWorld::CommandDispatcher::setSelection (const std::vector<std::string>& selection)
|
||||||
{
|
{
|
||||||
mSelection = selection;
|
mSelection = selection;
|
||||||
std::for_each (mSelection.begin(), mSelection.end(), Misc::StringUtils::toLower);
|
std::for_each (mSelection.begin(), mSelection.end(), Misc::StringUtils::lowerCaseInPlace);
|
||||||
std::sort (mSelection.begin(), mSelection.end());
|
std::sort (mSelection.begin(), mSelection.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,9 +59,10 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec
|
||||||
return number;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager)
|
CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager, const Fallback::Map* fallback)
|
||||||
: mEncoder (encoding), mPathgrids (mCells), mRefs (mCells),
|
: mEncoder (encoding), mPathgrids (mCells), mRefs (mCells),
|
||||||
mResourcesManager (resourcesManager), mReader (0), mDialogue (0), mReaderIndex(0), mResourceSystem(new Resource::ResourceSystem(resourcesManager.getVFS()))
|
mResourcesManager (resourcesManager), mFallbackMap(fallback),
|
||||||
|
mReader (0), mDialogue (0), mReaderIndex(0), mResourceSystem(new Resource::ResourceSystem(resourcesManager.getVFS()))
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
|
@ -136,7 +137,8 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
|
||||||
mRaces.getNestableColumn(index)->addColumn(
|
mRaces.getNestableColumn(index)->addColumn(
|
||||||
new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_Spell));
|
new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_Spell));
|
||||||
// Race attributes
|
// Race attributes
|
||||||
mRaces.addColumn (new NestedParentColumn<ESM::Race> (Columns::ColumnId_RaceAttributes));
|
mRaces.addColumn (new NestedParentColumn<ESM::Race> (Columns::ColumnId_RaceAttributes,
|
||||||
|
ColumnBase::Flag_Dialogue, true)); // fixed rows table
|
||||||
index = mRaces.getColumns()-1;
|
index = mRaces.getColumns()-1;
|
||||||
mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new RaceAttributeAdapter()));
|
mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new RaceAttributeAdapter()));
|
||||||
mRaces.getNestableColumn(index)->addColumn(
|
mRaces.getNestableColumn(index)->addColumn(
|
||||||
|
@ -147,7 +149,8 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
|
||||||
mRaces.getNestableColumn(index)->addColumn(
|
mRaces.getNestableColumn(index)->addColumn(
|
||||||
new NestedChildColumn (Columns::ColumnId_Female, ColumnBase::Display_Integer));
|
new NestedChildColumn (Columns::ColumnId_Female, ColumnBase::Display_Integer));
|
||||||
// Race skill bonus
|
// Race skill bonus
|
||||||
mRaces.addColumn (new NestedParentColumn<ESM::Race> (Columns::ColumnId_RaceSkillBonus));
|
mRaces.addColumn (new NestedParentColumn<ESM::Race> (Columns::ColumnId_RaceSkillBonus,
|
||||||
|
ColumnBase::Flag_Dialogue, true)); // fixed rows table
|
||||||
index = mRaces.getColumns()-1;
|
index = mRaces.getColumns()-1;
|
||||||
mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new RaceSkillsBonusAdapter()));
|
mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new RaceSkillsBonusAdapter()));
|
||||||
mRaces.getNestableColumn(index)->addColumn(
|
mRaces.getNestableColumn(index)->addColumn(
|
||||||
|
@ -213,9 +216,9 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
|
||||||
mSpells.getNestableColumn(index)->addColumn(
|
mSpells.getNestableColumn(index)->addColumn(
|
||||||
new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_EffectId));
|
new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_EffectId));
|
||||||
mSpells.getNestableColumn(index)->addColumn(
|
mSpells.getNestableColumn(index)->addColumn(
|
||||||
new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_SkillId));
|
new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_EffectSkill));
|
||||||
mSpells.getNestableColumn(index)->addColumn(
|
mSpells.getNestableColumn(index)->addColumn(
|
||||||
new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute));
|
new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_EffectAttribute));
|
||||||
mSpells.getNestableColumn(index)->addColumn(
|
mSpells.getNestableColumn(index)->addColumn(
|
||||||
new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange));
|
new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange));
|
||||||
mSpells.getNestableColumn(index)->addColumn(
|
mSpells.getNestableColumn(index)->addColumn(
|
||||||
|
@ -329,9 +332,9 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
|
||||||
mEnchantments.getNestableColumn(index)->addColumn(
|
mEnchantments.getNestableColumn(index)->addColumn(
|
||||||
new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_EffectId));
|
new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_EffectId));
|
||||||
mEnchantments.getNestableColumn(index)->addColumn(
|
mEnchantments.getNestableColumn(index)->addColumn(
|
||||||
new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_SkillId));
|
new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_EffectSkill));
|
||||||
mEnchantments.getNestableColumn(index)->addColumn(
|
mEnchantments.getNestableColumn(index)->addColumn(
|
||||||
new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute));
|
new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_EffectAttribute));
|
||||||
mEnchantments.getNestableColumn(index)->addColumn(
|
mEnchantments.getNestableColumn(index)->addColumn(
|
||||||
new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange));
|
new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange));
|
||||||
mEnchantments.getNestableColumn(index)->addColumn(
|
mEnchantments.getNestableColumn(index)->addColumn(
|
||||||
|
@ -1008,41 +1011,43 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
|
||||||
|
|
||||||
case ESM::REC_DIAL:
|
case ESM::REC_DIAL:
|
||||||
{
|
{
|
||||||
std::string id = mReader->getHNOString ("NAME");
|
|
||||||
|
|
||||||
ESM::Dialogue record;
|
ESM::Dialogue record;
|
||||||
record.mId = id;
|
bool isDeleted = false;
|
||||||
record.load (*mReader);
|
|
||||||
|
|
||||||
if (record.mType==ESM::Dialogue::Journal)
|
record.load (*mReader, isDeleted);
|
||||||
{
|
|
||||||
mJournals.load (record, mBase);
|
|
||||||
mDialogue = &mJournals.getRecord (id).get();
|
|
||||||
}
|
|
||||||
else if (record.mType==ESM::Dialogue::Deleted)
|
|
||||||
{
|
|
||||||
mDialogue = 0; // record vector can be shuffled around which would make pointer
|
|
||||||
// to record invalid
|
|
||||||
|
|
||||||
if (mJournals.tryDelete (id))
|
if (isDeleted)
|
||||||
|
{
|
||||||
|
// record vector can be shuffled around which would make pointer to record invalid
|
||||||
|
mDialogue = 0;
|
||||||
|
|
||||||
|
if (mJournals.tryDelete (record.mId))
|
||||||
{
|
{
|
||||||
/// \todo handle info records
|
mJournalInfos.removeDialogueInfos(record.mId);
|
||||||
}
|
}
|
||||||
else if (mTopics.tryDelete (id))
|
else if (mTopics.tryDelete (record.mId))
|
||||||
{
|
{
|
||||||
/// \todo handle info records
|
mTopicInfos.removeDialogueInfos(record.mId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
messages.add (UniversalId::Type_None,
|
messages.add (UniversalId::Type_None,
|
||||||
"Trying to delete dialogue record " + id + " which does not exist",
|
"Trying to delete dialogue record " + record.mId + " which does not exist",
|
||||||
"", CSMDoc::Message::Severity_Warning);
|
"", CSMDoc::Message::Severity_Warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mTopics.load (record, mBase);
|
if (record.mType == ESM::Dialogue::Journal)
|
||||||
mDialogue = &mTopics.getRecord (id).get();
|
{
|
||||||
|
mJournals.load (record, mBase);
|
||||||
|
mDialogue = &mJournals.getRecord (record.mId).get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mTopics.load (record, mBase);
|
||||||
|
mDialogue = &mTopics.getRecord (record.mId).get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1197,3 +1202,8 @@ const VFS::Manager* CSMWorld::Data::getVFS() const
|
||||||
{
|
{
|
||||||
return mResourcesManager.getVFS();
|
return mResourcesManager.getVFS();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Fallback::Map* CSMWorld::Data::getFallbackMap() const
|
||||||
|
{
|
||||||
|
return mFallbackMap;
|
||||||
|
}
|
||||||
|
|
|
@ -58,6 +58,11 @@ namespace VFS
|
||||||
class Manager;
|
class Manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Fallback
|
||||||
|
{
|
||||||
|
class Map;
|
||||||
|
}
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
class ESMReader;
|
class ESMReader;
|
||||||
|
@ -104,6 +109,7 @@ namespace CSMWorld
|
||||||
IdCollection<ESM::Filter> mFilters;
|
IdCollection<ESM::Filter> mFilters;
|
||||||
Collection<MetaData> mMetaData;
|
Collection<MetaData> mMetaData;
|
||||||
const ResourcesManager& mResourcesManager;
|
const ResourcesManager& mResourcesManager;
|
||||||
|
const Fallback::Map* mFallbackMap;
|
||||||
std::vector<QAbstractItemModel *> mModels;
|
std::vector<QAbstractItemModel *> mModels;
|
||||||
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;
|
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;
|
||||||
ESM::ESMReader *mReader;
|
ESM::ESMReader *mReader;
|
||||||
|
@ -132,12 +138,14 @@ namespace CSMWorld
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager);
|
Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager, const Fallback::Map* fallback);
|
||||||
|
|
||||||
virtual ~Data();
|
virtual ~Data();
|
||||||
|
|
||||||
const VFS::Manager* getVFS() const;
|
const VFS::Manager* getVFS() const;
|
||||||
|
|
||||||
|
const Fallback::Map* getFallbackMap() const;
|
||||||
|
|
||||||
boost::shared_ptr<Resource::ResourceSystem> getResourceSystem();
|
boost::shared_ptr<Resource::ResourceSystem> getResourceSystem();
|
||||||
|
|
||||||
boost::shared_ptr<const Resource::ResourceSystem> getResourceSystem() const;
|
boost::shared_ptr<const Resource::ResourceSystem> getResourceSystem() const;
|
||||||
|
|
2336
apps/opencs/model/world/defaultgmsts.cpp
Normal file
2336
apps/opencs/model/world/defaultgmsts.cpp
Normal file
File diff suppressed because it is too large
Load diff
34
apps/opencs/model/world/defaultgmsts.hpp
Normal file
34
apps/opencs/model/world/defaultgmsts.hpp
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef CSM_WORLD_DEFAULTGMSTS_H
|
||||||
|
#define CSM_WORLD_DEFAULTGMSTS_H
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace CSMWorld {
|
||||||
|
namespace DefaultGmsts {
|
||||||
|
|
||||||
|
const size_t FloatCount = 258;
|
||||||
|
const size_t IntCount = 89;
|
||||||
|
const size_t StringCount = 1174;
|
||||||
|
|
||||||
|
const size_t OptionalFloatCount = 42;
|
||||||
|
const size_t OptionalIntCount = 4;
|
||||||
|
const size_t OptionalStringCount = 26;
|
||||||
|
|
||||||
|
extern const char* Floats[];
|
||||||
|
extern const char * Ints[];
|
||||||
|
extern const char * Strings[];
|
||||||
|
|
||||||
|
extern const char * OptionalFloats[];
|
||||||
|
extern const char * OptionalInts[];
|
||||||
|
extern const char * OptionalStrings[];
|
||||||
|
|
||||||
|
extern const float FloatsDefaultValues[];
|
||||||
|
extern const int IntsDefaultValues[];
|
||||||
|
|
||||||
|
extern const float FloatLimits[];
|
||||||
|
extern const int IntLimits[];
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -11,7 +11,7 @@ namespace CSMWorld
|
||||||
template<typename ESXRecordT, typename IdAccessorT = IdAccessor<ESXRecordT> >
|
template<typename ESXRecordT, typename IdAccessorT = IdAccessor<ESXRecordT> >
|
||||||
class IdCollection : public Collection<ESXRecordT, IdAccessorT>
|
class IdCollection : public Collection<ESXRecordT, IdAccessorT>
|
||||||
{
|
{
|
||||||
virtual void loadRecord (ESXRecordT& record, ESM::ESMReader& reader);
|
virtual void loadRecord (ESXRecordT& record, ESM::ESMReader& reader, bool& isDeleted);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -33,77 +33,46 @@ namespace CSMWorld
|
||||||
|
|
||||||
template<typename ESXRecordT, typename IdAccessorT>
|
template<typename ESXRecordT, typename IdAccessorT>
|
||||||
void IdCollection<ESXRecordT, IdAccessorT>::loadRecord (ESXRecordT& record,
|
void IdCollection<ESXRecordT, IdAccessorT>::loadRecord (ESXRecordT& record,
|
||||||
ESM::ESMReader& reader)
|
ESM::ESMReader& reader,
|
||||||
|
bool& isDeleted)
|
||||||
{
|
{
|
||||||
record.load (reader);
|
record.load (reader, isDeleted);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ESXRecordT, typename IdAccessorT>
|
template<typename ESXRecordT, typename IdAccessorT>
|
||||||
int IdCollection<ESXRecordT, IdAccessorT>::load (ESM::ESMReader& reader, bool base)
|
int IdCollection<ESXRecordT, IdAccessorT>::load (ESM::ESMReader& reader, bool base)
|
||||||
{
|
{
|
||||||
std::string id = reader.getHNOString ("NAME");
|
ESXRecordT record;
|
||||||
|
bool isDeleted = false;
|
||||||
|
|
||||||
if (reader.isNextSub ("DELE"))
|
loadRecord (record, reader, isDeleted);
|
||||||
|
|
||||||
|
std::string id = IdAccessorT().getId (record);
|
||||||
|
int index = this->searchId (id);
|
||||||
|
|
||||||
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
int index = Collection<ESXRecordT, IdAccessorT>::searchId (id);
|
|
||||||
|
|
||||||
reader.skipRecord();
|
|
||||||
|
|
||||||
if (index==-1)
|
if (index==-1)
|
||||||
{
|
{
|
||||||
// deleting a record that does not exist
|
// deleting a record that does not exist
|
||||||
|
|
||||||
// ignore it for now
|
// ignore it for now
|
||||||
|
|
||||||
/// \todo report the problem to the user
|
/// \todo report the problem to the user
|
||||||
}
|
return -1;
|
||||||
else if (base)
|
|
||||||
{
|
|
||||||
Collection<ESXRecordT, IdAccessorT>::removeRows (index, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Record<ESXRecordT> record = Collection<ESXRecordT, IdAccessorT>::getRecord (index);
|
|
||||||
record.mState = RecordBase::State_Deleted;
|
|
||||||
this->setRecord (index, record);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
if (base)
|
||||||
|
{
|
||||||
|
this->removeRows (index, 1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Record<ESXRecordT> baseRecord = this->getRecord (index);
|
||||||
|
baseRecord.mState = RecordBase::State_Deleted;
|
||||||
|
this->setRecord (index, baseRecord);
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ESXRecordT record;
|
|
||||||
|
|
||||||
// Sometimes id (i.e. NAME of the cell) may be different to the id we stored
|
return load (record, base, index);
|
||||||
// earlier. e.g. NAME == "Vivec, Arena" but id == "#-4 11". Sometime NAME is
|
|
||||||
// missing altogether for scripts or cells.
|
|
||||||
//
|
|
||||||
// In such cases the returned index will be -1. We then try updating the
|
|
||||||
// IdAccessor's id manually (e.g. set mId of the record to "Vivec, Arena")
|
|
||||||
// and try getting the index once more after loading the record. The mId of the
|
|
||||||
// record would have changed to "#-4 11" after the load, and searchId() should find
|
|
||||||
// it (if this is a modify)
|
|
||||||
int index = this->searchId (id);
|
|
||||||
|
|
||||||
if (index==-1)
|
|
||||||
IdAccessorT().getId (record) = id;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
record = this->getRecord (index).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
loadRecord (record, reader);
|
|
||||||
|
|
||||||
if (index==-1)
|
|
||||||
{
|
|
||||||
std::string newId = IdAccessorT().getId(record);
|
|
||||||
int newIndex = this->searchId(newId);
|
|
||||||
if (newIndex != -1 && id != newId)
|
|
||||||
index = newIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
return load (record, base, index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ESXRecordT, typename IdAccessorT>
|
template<typename ESXRecordT, typename IdAccessorT>
|
||||||
|
|
|
@ -106,21 +106,20 @@ bool CSMWorld::InfoCollection::reorderRows (int baseIndex, const std::vector<int
|
||||||
|
|
||||||
void CSMWorld::InfoCollection::load (ESM::ESMReader& reader, bool base, const ESM::Dialogue& dialogue)
|
void CSMWorld::InfoCollection::load (ESM::ESMReader& reader, bool base, const ESM::Dialogue& dialogue)
|
||||||
{
|
{
|
||||||
std::string id = Misc::StringUtils::lowerCase (dialogue.mId) + "#" +
|
Info info;
|
||||||
reader.getHNOString ("INAM");
|
bool isDeleted = false;
|
||||||
|
|
||||||
if (reader.isNextSub ("DELE"))
|
info.load (reader, isDeleted);
|
||||||
|
std::string id = Misc::StringUtils::lowerCase (dialogue.mId) + "#" + info.mId;
|
||||||
|
|
||||||
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
int index = searchId (id);
|
int index = searchId (id);
|
||||||
|
|
||||||
reader.skipRecord();
|
|
||||||
|
|
||||||
if (index==-1)
|
if (index==-1)
|
||||||
{
|
{
|
||||||
// deleting a record that does not exist
|
// deleting a record that does not exist
|
||||||
|
|
||||||
// ignore it for now
|
// ignore it for now
|
||||||
|
|
||||||
/// \todo report the problem to the user
|
/// \todo report the problem to the user
|
||||||
}
|
}
|
||||||
else if (base)
|
else if (base)
|
||||||
|
@ -136,12 +135,9 @@ void CSMWorld::InfoCollection::load (ESM::ESMReader& reader, bool base, const ES
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Info record;
|
info.mTopicId = dialogue.mId;
|
||||||
record.mTopicId = dialogue.mId;
|
info.mId = id;
|
||||||
record.mId = id;
|
load (info, base);
|
||||||
record.load (reader);
|
|
||||||
|
|
||||||
load (record, base);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,3 +189,39 @@ CSMWorld::InfoCollection::Range CSMWorld::InfoCollection::getTopicRange (const s
|
||||||
|
|
||||||
return Range (begin, end);
|
return Range (begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSMWorld::InfoCollection::removeDialogueInfos(const std::string& dialogueId)
|
||||||
|
{
|
||||||
|
std::string id = Misc::StringUtils::lowerCase(dialogueId);
|
||||||
|
std::vector<int> erasedRecords;
|
||||||
|
|
||||||
|
std::map<std::string, int>::const_iterator current = getIdMap().lower_bound(id);
|
||||||
|
std::map<std::string, int>::const_iterator end = getIdMap().end();
|
||||||
|
for (; current != end; ++current)
|
||||||
|
{
|
||||||
|
Record<Info> record = getRecord(current->second);
|
||||||
|
|
||||||
|
if (Misc::StringUtils::ciEqual(dialogueId, record.get().mTopicId))
|
||||||
|
{
|
||||||
|
if (record.mState == RecordBase::State_ModifiedOnly)
|
||||||
|
{
|
||||||
|
erasedRecords.push_back(current->second);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
record.mState = RecordBase::State_Deleted;
|
||||||
|
setRecord(current->second, record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!erasedRecords.empty())
|
||||||
|
{
|
||||||
|
removeRows(erasedRecords.back(), 1);
|
||||||
|
erasedRecords.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -44,6 +44,8 @@ namespace CSMWorld
|
||||||
Range getTopicRange (const std::string& topic) const;
|
Range getTopicRange (const std::string& topic) const;
|
||||||
///< Return iterators that point to the beginning and past the end of the range for
|
///< Return iterators that point to the beginning and past the end of the range for
|
||||||
/// the given topic.
|
/// the given topic.
|
||||||
|
|
||||||
|
void removeDialogueInfos(const std::string& dialogueId);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,12 @@
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
void Land::load(ESM::ESMReader &esm)
|
void Land::load(ESM::ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
ESM::Land::load(esm);
|
ESM::Land::load(esm, isDeleted);
|
||||||
|
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
stream << "#" << mX << " " << mY;
|
stream << "#" << mX << " " << mY;
|
||||||
|
|
||||||
mId = stream.str();
|
mId = stream.str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,13 +10,12 @@ namespace CSMWorld
|
||||||
/// \brief Wrapper for Land record. Encodes X and Y cell index in the ID.
|
/// \brief Wrapper for Land record. Encodes X and Y cell index in the ID.
|
||||||
///
|
///
|
||||||
/// \todo Add worldspace support to the Land record.
|
/// \todo Add worldspace support to the Land record.
|
||||||
/// \todo Add a proper copy constructor (currently worked around using shared_ptr)
|
|
||||||
struct Land : public ESM::Land
|
struct Land : public ESM::Land
|
||||||
{
|
{
|
||||||
std::string mId;
|
std::string mId;
|
||||||
|
|
||||||
/// Loads the metadata and ID
|
/// Loads the metadata and ID
|
||||||
void load (ESM::ESMReader &esm);
|
void load (ESM::ESMReader &esm, bool &isDeleted);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,9 @@
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
|
void LandTexture::load(ESM::ESMReader &esm, bool &isDeleted)
|
||||||
void LandTexture::load(ESM::ESMReader &esm)
|
|
||||||
{
|
{
|
||||||
ESM::LandTexture::load(esm);
|
ESM::LandTexture::load(esm, isDeleted);
|
||||||
|
|
||||||
mPluginIndex = esm.getIndex();
|
mPluginIndex = esm.getIndex();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace CSMWorld
|
||||||
{
|
{
|
||||||
int mPluginIndex;
|
int mPluginIndex;
|
||||||
|
|
||||||
void load (ESM::ESMReader &esm);
|
void load (ESM::ESMReader &esm, bool &isDeleted);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -277,7 +277,7 @@ namespace CSMWorld
|
||||||
// WARNING: Assumed that the table view has the same order as std::map
|
// WARNING: Assumed that the table view has the same order as std::map
|
||||||
std::map<std::string, int>::iterator iter = reactions.begin();
|
std::map<std::string, int>::iterator iter = reactions.begin();
|
||||||
for(int i = 0; i < rowToRemove; ++i)
|
for(int i = 0; i < rowToRemove; ++i)
|
||||||
iter++;
|
++iter;
|
||||||
reactions.erase(iter);
|
reactions.erase(iter);
|
||||||
|
|
||||||
record.setModified (faction);
|
record.setModified (faction);
|
||||||
|
@ -314,7 +314,7 @@ namespace CSMWorld
|
||||||
// WARNING: Assumed that the table view has the same order as std::map
|
// WARNING: Assumed that the table view has the same order as std::map
|
||||||
std::map<std::string, int>::const_iterator iter = reactions.begin();
|
std::map<std::string, int>::const_iterator iter = reactions.begin();
|
||||||
for(int i = 0; i < subRowIndex; ++i)
|
for(int i = 0; i < subRowIndex; ++i)
|
||||||
iter++;
|
++iter;
|
||||||
switch (subColIndex)
|
switch (subColIndex)
|
||||||
{
|
{
|
||||||
case 0: return QString((*iter).first.c_str());
|
case 0: return QString((*iter).first.c_str());
|
||||||
|
@ -337,7 +337,7 @@ namespace CSMWorld
|
||||||
// WARNING: Assumed that the table view has the same order as std::map
|
// WARNING: Assumed that the table view has the same order as std::map
|
||||||
std::map<std::string, int>::iterator iter = reactions.begin();
|
std::map<std::string, int>::iterator iter = reactions.begin();
|
||||||
for(int i = 0; i < subRowIndex; ++i)
|
for(int i = 0; i < subRowIndex; ++i)
|
||||||
iter++;
|
++iter;
|
||||||
|
|
||||||
std::string factionId = (*iter).first;
|
std::string factionId = (*iter).first;
|
||||||
int reaction = (*iter).second;
|
int reaction = (*iter).second;
|
||||||
|
@ -606,7 +606,7 @@ namespace CSMWorld
|
||||||
funcMap["09"] = "PC Fatigue";
|
funcMap["09"] = "PC Fatigue";
|
||||||
funcMap["10"] = "PC Strength";
|
funcMap["10"] = "PC Strength";
|
||||||
funcMap["11"] = "PC Block";
|
funcMap["11"] = "PC Block";
|
||||||
funcMap["12"] = "PC Armoror";
|
funcMap["12"] = "PC Armorer";
|
||||||
funcMap["13"] = "PC Medium Armor";
|
funcMap["13"] = "PC Medium Armor";
|
||||||
funcMap["14"] = "PC Heavy Armor";
|
funcMap["14"] = "PC Heavy Armor";
|
||||||
funcMap["15"] = "PC Blunt Weapon";
|
funcMap["15"] = "PC Blunt Weapon";
|
||||||
|
|
|
@ -317,8 +317,34 @@ namespace CSMWorld
|
||||||
else
|
else
|
||||||
throw std::runtime_error("Magic effects ID unexpected value");
|
throw std::runtime_error("Magic effects ID unexpected value");
|
||||||
}
|
}
|
||||||
case 1: return effect.mSkill;
|
case 1:
|
||||||
case 2: return effect.mAttribute;
|
{
|
||||||
|
switch (effect.mEffectID)
|
||||||
|
{
|
||||||
|
case ESM::MagicEffect::DrainSkill:
|
||||||
|
case ESM::MagicEffect::DamageSkill:
|
||||||
|
case ESM::MagicEffect::RestoreSkill:
|
||||||
|
case ESM::MagicEffect::FortifySkill:
|
||||||
|
case ESM::MagicEffect::AbsorbSkill:
|
||||||
|
return effect.mSkill;
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
switch (effect.mEffectID)
|
||||||
|
{
|
||||||
|
case ESM::MagicEffect::DrainAttribute:
|
||||||
|
case ESM::MagicEffect::DamageAttribute:
|
||||||
|
case ESM::MagicEffect::RestoreAttribute:
|
||||||
|
case ESM::MagicEffect::FortifyAttribute:
|
||||||
|
case ESM::MagicEffect::AbsorbAttribute:
|
||||||
|
return effect.mAttribute;
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
if (effect.mRange >=0 && effect.mRange <=2)
|
if (effect.mRange >=0 && effect.mRange <=2)
|
||||||
|
|
|
@ -4,33 +4,28 @@
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
void CSMWorld::Pathgrid::load (ESM::ESMReader &esm, const IdCollection<Cell>& cells)
|
void CSMWorld::Pathgrid::load (ESM::ESMReader &esm, bool &isDeleted, const IdCollection<Cell>& cells)
|
||||||
{
|
{
|
||||||
load (esm);
|
load (esm, isDeleted);
|
||||||
|
|
||||||
// correct ID
|
// correct ID
|
||||||
if (!mId.empty() && mId[0]!='#' && cells.searchId (mId)==-1)
|
if (!mId.empty() && mId[0]!='#' && cells.searchId (mId)==-1)
|
||||||
{
|
{
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
|
|
||||||
stream << "#" << mData.mX << " " << mData.mY;
|
stream << "#" << mData.mX << " " << mData.mY;
|
||||||
|
|
||||||
mId = stream.str();
|
mId = stream.str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMWorld::Pathgrid::load (ESM::ESMReader &esm)
|
void CSMWorld::Pathgrid::load (ESM::ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
ESM::Pathgrid::load (esm);
|
ESM::Pathgrid::load (esm, isDeleted);
|
||||||
|
|
||||||
|
mId = mCell;
|
||||||
if (mCell.empty())
|
if (mCell.empty())
|
||||||
{
|
{
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
|
|
||||||
stream << "#" << mData.mX << " " << mData.mY;
|
stream << "#" << mData.mX << " " << mData.mY;
|
||||||
|
|
||||||
mId = stream.str();
|
mId = stream.str();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
mId = mCell;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,8 @@ namespace CSMWorld
|
||||||
{
|
{
|
||||||
std::string mId;
|
std::string mId;
|
||||||
|
|
||||||
void load (ESM::ESMReader &esm, const IdCollection<Cell>& cells);
|
void load (ESM::ESMReader &esm, bool &isDeleted, const IdCollection<Cell>& cells);
|
||||||
|
void load (ESM::ESMReader &esm, bool &isDeleted);
|
||||||
void load (ESM::ESMReader &esm);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,12 +19,11 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
|
||||||
Cell& cell2 = base ? cell.mBase : cell.mModified;
|
Cell& cell2 = base ? cell.mBase : cell.mModified;
|
||||||
|
|
||||||
CellRef ref;
|
CellRef ref;
|
||||||
|
|
||||||
bool deleted = false;
|
|
||||||
ESM::MovedCellRef mref;
|
ESM::MovedCellRef mref;
|
||||||
|
bool isDeleted = false;
|
||||||
|
|
||||||
// hack to initialise mindex
|
// hack to initialise mindex
|
||||||
while (!(mref.mRefNum.mIndex = 0) && ESM::Cell::getNextRef(reader, ref, deleted, true, &mref))
|
while (!(mref.mRefNum.mIndex = 0) && ESM::Cell::getNextRef(reader, ref, isDeleted, true, &mref))
|
||||||
{
|
{
|
||||||
// Keep mOriginalCell empty when in modified (as an indicator that the
|
// Keep mOriginalCell empty when in modified (as an indicator that the
|
||||||
// original cell will always be equal the current cell).
|
// original cell will always be equal the current cell).
|
||||||
|
@ -49,17 +48,6 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
|
||||||
// https://forum.openmw.org/viewtopic.php?f=6&t=577&start=30
|
// https://forum.openmw.org/viewtopic.php?f=6&t=577&start=30
|
||||||
ref.mOriginalCell = cell2.mId;
|
ref.mOriginalCell = cell2.mId;
|
||||||
|
|
||||||
if (deleted)
|
|
||||||
{
|
|
||||||
// FIXME: how to mark the record deleted?
|
|
||||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Cell,
|
|
||||||
mCells.getId (cellIndex));
|
|
||||||
|
|
||||||
messages.add (id, "Moved reference "+ref.mRefID+" is in DELE state");
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// It is not always possibe to ignore moved references sub-record and
|
// It is not always possibe to ignore moved references sub-record and
|
||||||
// calculate from coordinates. Some mods may place the ref in positions
|
// calculate from coordinates. Some mods may place the ref in positions
|
||||||
// outside normal bounds, resulting in non sensical cell id's. This often
|
// outside normal bounds, resulting in non sensical cell id's. This often
|
||||||
|
@ -91,7 +79,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
if (iter==cache.end())
|
if (iter==cache.end())
|
||||||
{
|
{
|
||||||
|
@ -99,7 +87,6 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
|
||||||
mCells.getId (cellIndex));
|
mCells.getId (cellIndex));
|
||||||
|
|
||||||
messages.add (id, "Attempt to delete a non-existing reference");
|
messages.add (id, "Attempt to delete a non-existing reference");
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +94,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
|
||||||
|
|
||||||
Record<CellRef> record = getRecord (index);
|
Record<CellRef> record = getRecord (index);
|
||||||
|
|
||||||
if (record.mState==RecordBase::State_BaseOnly)
|
if (base)
|
||||||
{
|
{
|
||||||
removeRows (index, 1);
|
removeRows (index, 1);
|
||||||
cache.erase (iter);
|
cache.erase (iter);
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <components/esm/loadcont.hpp>
|
#include <components/esm/loadcont.hpp>
|
||||||
|
#include <components/esm/loadmgef.hpp>
|
||||||
|
|
||||||
#include "nestedtablewrapper.hpp"
|
#include "nestedtablewrapper.hpp"
|
||||||
|
|
||||||
CSMWorld::PotionColumns::PotionColumns (const InventoryColumns& columns)
|
CSMWorld::PotionColumns::PotionColumns (const InventoryColumns& columns)
|
||||||
|
@ -25,8 +27,9 @@ QVariant CSMWorld::PotionRefIdAdapter::getData (const RefIdColumn *column, const
|
||||||
if (column==mAutoCalc)
|
if (column==mAutoCalc)
|
||||||
return record.get().mData.mAutoCalc!=0;
|
return record.get().mData.mAutoCalc!=0;
|
||||||
|
|
||||||
|
// to show nested tables in dialogue subview, see IdTree::hasChildren()
|
||||||
if (column==mColumns.mEffects)
|
if (column==mColumns.mEffects)
|
||||||
return true; // to show nested tables in dialogue subview, see IdTree::hasChildren()
|
return QVariant::fromValue(ColumnBase::TableEdit_Full);
|
||||||
|
|
||||||
return InventoryRefIdAdapter<ESM::Potion>::getData (column, data, index);
|
return InventoryRefIdAdapter<ESM::Potion>::getData (column, data, index);
|
||||||
}
|
}
|
||||||
|
@ -52,6 +55,156 @@ void CSMWorld::PotionRefIdAdapter::setData (const RefIdColumn *column, RefIdData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CSMWorld::IngredientColumns::IngredientColumns (const InventoryColumns& columns)
|
||||||
|
: InventoryColumns (columns) {}
|
||||||
|
|
||||||
|
CSMWorld::IngredientRefIdAdapter::IngredientRefIdAdapter (const IngredientColumns& columns)
|
||||||
|
: InventoryRefIdAdapter<ESM::Ingredient> (UniversalId::Type_Ingredient, columns),
|
||||||
|
mColumns(columns)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QVariant CSMWorld::IngredientRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data,
|
||||||
|
int index) const
|
||||||
|
{
|
||||||
|
if (column==mColumns.mEffects)
|
||||||
|
return QVariant::fromValue(ColumnBase::TableEdit_FixedRows);
|
||||||
|
|
||||||
|
return InventoryRefIdAdapter<ESM::Ingredient>::getData (column, data, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::IngredientRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||||
|
const QVariant& value) const
|
||||||
|
{
|
||||||
|
InventoryRefIdAdapter<ESM::Ingredient>::setData (column, data, index, value);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CSMWorld::IngredEffectRefIdAdapter::IngredEffectRefIdAdapter()
|
||||||
|
: mType(UniversalId::Type_Ingredient)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CSMWorld::IngredEffectRefIdAdapter::~IngredEffectRefIdAdapter()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CSMWorld::IngredEffectRefIdAdapter::addNestedRow (const RefIdColumn *column,
|
||||||
|
RefIdData& data, int index, int position) const
|
||||||
|
{
|
||||||
|
// Do nothing, this table cannot be changed by the user
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::IngredEffectRefIdAdapter::removeNestedRow (const RefIdColumn *column,
|
||||||
|
RefIdData& data, int index, int rowToRemove) const
|
||||||
|
{
|
||||||
|
// Do nothing, this table cannot be changed by the user
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::IngredEffectRefIdAdapter::setNestedTable (const RefIdColumn* column,
|
||||||
|
RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const
|
||||||
|
{
|
||||||
|
Record<ESM::Ingredient>& record =
|
||||||
|
static_cast<Record<ESM::Ingredient>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
|
||||||
|
ESM::Ingredient ingredient = record.get();
|
||||||
|
|
||||||
|
ingredient.mData =
|
||||||
|
static_cast<const NestedTableWrapper<std::vector<typename ESM::Ingredient::IRDTstruct> >&>(nestedTable).mNestedTable.at(0);
|
||||||
|
|
||||||
|
record.setModified (ingredient);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMWorld::NestedTableWrapperBase* CSMWorld::IngredEffectRefIdAdapter::nestedTable (const RefIdColumn* column,
|
||||||
|
const RefIdData& data, int index) const
|
||||||
|
{
|
||||||
|
const Record<ESM::Ingredient>& record =
|
||||||
|
static_cast<const Record<ESM::Ingredient>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
|
||||||
|
|
||||||
|
// return the whole struct
|
||||||
|
std::vector<typename ESM::Ingredient::IRDTstruct> wrap;
|
||||||
|
wrap.push_back(record.get().mData);
|
||||||
|
|
||||||
|
// deleted by dtor of NestedTableStoring
|
||||||
|
return new NestedTableWrapper<std::vector<typename ESM::Ingredient::IRDTstruct> >(wrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant CSMWorld::IngredEffectRefIdAdapter::getNestedData (const RefIdColumn *column,
|
||||||
|
const RefIdData& data, int index, int subRowIndex, int subColIndex) const
|
||||||
|
{
|
||||||
|
const Record<ESM::Ingredient>& record =
|
||||||
|
static_cast<const Record<ESM::Ingredient>&> (data.getRecord (RefIdData::LocalIndex (index, mType)));
|
||||||
|
|
||||||
|
if (subRowIndex < 0 || subRowIndex >= 4)
|
||||||
|
throw std::runtime_error ("index out of range");
|
||||||
|
|
||||||
|
switch (subColIndex)
|
||||||
|
{
|
||||||
|
case 0: return record.get().mData.mEffectID[subRowIndex];
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
switch (record.get().mData.mEffectID[subRowIndex])
|
||||||
|
{
|
||||||
|
case ESM::MagicEffect::DrainSkill:
|
||||||
|
case ESM::MagicEffect::DamageSkill:
|
||||||
|
case ESM::MagicEffect::RestoreSkill:
|
||||||
|
case ESM::MagicEffect::FortifySkill:
|
||||||
|
case ESM::MagicEffect::AbsorbSkill:
|
||||||
|
return record.get().mData.mSkills[subRowIndex];
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
switch (record.get().mData.mEffectID[subRowIndex])
|
||||||
|
{
|
||||||
|
case ESM::MagicEffect::DrainAttribute:
|
||||||
|
case ESM::MagicEffect::DamageAttribute:
|
||||||
|
case ESM::MagicEffect::RestoreAttribute:
|
||||||
|
case ESM::MagicEffect::FortifyAttribute:
|
||||||
|
case ESM::MagicEffect::AbsorbAttribute:
|
||||||
|
return record.get().mData.mAttributes[subRowIndex];
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Trying to access non-existing column in the nested table!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::IngredEffectRefIdAdapter::setNestedData (const RefIdColumn *column,
|
||||||
|
RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const
|
||||||
|
{
|
||||||
|
Record<ESM::Ingredient>& record =
|
||||||
|
static_cast<Record<ESM::Ingredient>&> (data.getRecord (RefIdData::LocalIndex (row, mType)));
|
||||||
|
ESM::Ingredient ingredient = record.get();
|
||||||
|
|
||||||
|
if (subRowIndex < 0 || subRowIndex >= 4)
|
||||||
|
throw std::runtime_error ("index out of range");
|
||||||
|
|
||||||
|
switch(subColIndex)
|
||||||
|
{
|
||||||
|
case 0: ingredient.mData.mEffectID[subRowIndex] = value.toInt(); break;
|
||||||
|
case 1: ingredient.mData.mSkills[subRowIndex] = value.toInt(); break;
|
||||||
|
case 2: ingredient.mData.mAttributes[subRowIndex] = value.toInt(); break;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Trying to access non-existing column in the nested table!");
|
||||||
|
}
|
||||||
|
|
||||||
|
record.setModified (ingredient);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSMWorld::IngredEffectRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const
|
||||||
|
{
|
||||||
|
return 3; // effect, skill, attribute
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSMWorld::IngredEffectRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const
|
||||||
|
{
|
||||||
|
return 4; // up to 4 effects
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
CSMWorld::ApparatusRefIdAdapter::ApparatusRefIdAdapter (const InventoryColumns& columns,
|
CSMWorld::ApparatusRefIdAdapter::ApparatusRefIdAdapter (const InventoryColumns& columns,
|
||||||
const RefIdColumn *type, const RefIdColumn *quality)
|
const RefIdColumn *type, const RefIdColumn *quality)
|
||||||
: InventoryRefIdAdapter<ESM::Apparatus> (UniversalId::Type_Apparatus, columns),
|
: InventoryRefIdAdapter<ESM::Apparatus> (UniversalId::Type_Apparatus, columns),
|
||||||
|
@ -118,7 +271,7 @@ QVariant CSMWorld::ArmorRefIdAdapter::getData (const RefIdColumn *column,
|
||||||
return record.get().mData.mArmor;
|
return record.get().mData.mArmor;
|
||||||
|
|
||||||
if (column==mPartRef)
|
if (column==mPartRef)
|
||||||
return true; // to show nested tables in dialogue subview, see IdTree::hasChildren()
|
return QVariant::fromValue(ColumnBase::TableEdit_Full);
|
||||||
|
|
||||||
return EnchantableRefIdAdapter<ESM::Armor>::getData (column, data, index);
|
return EnchantableRefIdAdapter<ESM::Armor>::getData (column, data, index);
|
||||||
}
|
}
|
||||||
|
@ -206,7 +359,7 @@ QVariant CSMWorld::ClothingRefIdAdapter::getData (const RefIdColumn *column,
|
||||||
return record.get().mData.mType;
|
return record.get().mData.mType;
|
||||||
|
|
||||||
if (column==mPartRef)
|
if (column==mPartRef)
|
||||||
return true; // to show nested tables in dialogue subview, see IdTree::hasChildren()
|
return QVariant::fromValue(ColumnBase::TableEdit_Full);
|
||||||
|
|
||||||
return EnchantableRefIdAdapter<ESM::Clothing>::getData (column, data, index);
|
return EnchantableRefIdAdapter<ESM::Clothing>::getData (column, data, index);
|
||||||
}
|
}
|
||||||
|
@ -254,7 +407,7 @@ QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column,
|
||||||
return (record.get().mFlags & ESM::Container::Respawn)!=0;
|
return (record.get().mFlags & ESM::Container::Respawn)!=0;
|
||||||
|
|
||||||
if (column==mContent)
|
if (column==mContent)
|
||||||
return true; // Required to show nested tables in dialogue subview
|
return QVariant::fromValue(ColumnBase::TableEdit_Full);
|
||||||
|
|
||||||
return NameRefIdAdapter<ESM::Container>::getData (column, data, index);
|
return NameRefIdAdapter<ESM::Container>::getData (column, data, index);
|
||||||
}
|
}
|
||||||
|
@ -323,13 +476,13 @@ QVariant CSMWorld::CreatureRefIdAdapter::getData (const RefIdColumn *column, con
|
||||||
return QString::fromUtf8 (record.get().mOriginal.c_str());
|
return QString::fromUtf8 (record.get().mOriginal.c_str());
|
||||||
|
|
||||||
if (column==mColumns.mAttributes)
|
if (column==mColumns.mAttributes)
|
||||||
return true; // Required to show nested tables in dialogue subview
|
return QVariant::fromValue(ColumnBase::TableEdit_FixedRows);
|
||||||
|
|
||||||
if (column==mColumns.mAttacks)
|
if (column==mColumns.mAttacks)
|
||||||
return true; // Required to show nested tables in dialogue subview
|
return QVariant::fromValue(ColumnBase::TableEdit_FixedRows);
|
||||||
|
|
||||||
if (column==mColumns.mMisc)
|
if (column==mColumns.mMisc)
|
||||||
return true; // Required to show nested items in dialogue subview
|
return QVariant::fromValue(ColumnBase::TableEdit_Full);
|
||||||
|
|
||||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||||
mColumns.mFlags.find (column);
|
mColumns.mFlags.find (column);
|
||||||
|
@ -569,13 +722,13 @@ QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const Re
|
||||||
if (column==mColumns.mAttributes || column==mColumns.mSkills)
|
if (column==mColumns.mAttributes || column==mColumns.mSkills)
|
||||||
{
|
{
|
||||||
if ((record.get().mFlags & ESM::NPC::Autocalc) != 0)
|
if ((record.get().mFlags & ESM::NPC::Autocalc) != 0)
|
||||||
return QVariant(QVariant::UserType);
|
return QVariant::fromValue(ColumnBase::TableEdit_None);
|
||||||
else
|
else
|
||||||
return true;
|
return QVariant::fromValue(ColumnBase::TableEdit_FixedRows);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (column==mColumns.mMisc)
|
if (column==mColumns.mMisc)
|
||||||
return true;
|
return QVariant::fromValue(ColumnBase::TableEdit_Full);
|
||||||
|
|
||||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||||
mColumns.mFlags.find (column);
|
mColumns.mFlags.find (column);
|
||||||
|
@ -1000,7 +1153,7 @@ QVariant CSMWorld::CreatureAttributesRefIdAdapter::getNestedData (const RefIdCol
|
||||||
const Record<ESM::Creature>& record =
|
const Record<ESM::Creature>& record =
|
||||||
static_cast<const Record<ESM::Creature>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature)));
|
static_cast<const Record<ESM::Creature>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature)));
|
||||||
|
|
||||||
const ESM::Creature creature = record.get();
|
const ESM::Creature& creature = record.get();
|
||||||
|
|
||||||
if (subColIndex == 0)
|
if (subColIndex == 0)
|
||||||
return subRowIndex;
|
return subRowIndex;
|
||||||
|
@ -1106,7 +1259,7 @@ QVariant CSMWorld::CreatureAttackRefIdAdapter::getNestedData (const RefIdColumn
|
||||||
const Record<ESM::Creature>& record =
|
const Record<ESM::Creature>& record =
|
||||||
static_cast<const Record<ESM::Creature>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature)));
|
static_cast<const Record<ESM::Creature>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature)));
|
||||||
|
|
||||||
const ESM::Creature creature = record.get();
|
const ESM::Creature& creature = record.get();
|
||||||
|
|
||||||
if (subRowIndex < 0 || subRowIndex > 2 || subColIndex < 0 || subColIndex > 2)
|
if (subRowIndex < 0 || subRowIndex > 2 || subColIndex < 0 || subColIndex > 2)
|
||||||
throw std::runtime_error ("index out of range");
|
throw std::runtime_error ("index out of range");
|
||||||
|
@ -1184,7 +1337,7 @@ QVariant CSMWorld::CreatureMiscRefIdAdapter::getNestedData (const RefIdColumn *c
|
||||||
const Record<ESM::Creature>& record =
|
const Record<ESM::Creature>& record =
|
||||||
static_cast<const Record<ESM::Creature>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature)));
|
static_cast<const Record<ESM::Creature>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature)));
|
||||||
|
|
||||||
const ESM::Creature creature = record.get();
|
const ESM::Creature& creature = record.get();
|
||||||
|
|
||||||
switch (subColIndex)
|
switch (subColIndex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <components/esm/loadnpc.hpp>
|
#include <components/esm/loadnpc.hpp>
|
||||||
#include <components/esm/loadcrea.hpp>
|
#include <components/esm/loadcrea.hpp>
|
||||||
|
|
||||||
|
#include "columnbase.hpp"
|
||||||
#include "record.hpp"
|
#include "record.hpp"
|
||||||
#include "refiddata.hpp"
|
#include "refiddata.hpp"
|
||||||
#include "universalid.hpp"
|
#include "universalid.hpp"
|
||||||
|
@ -340,6 +341,66 @@ namespace CSMWorld
|
||||||
///< If the data type does not match an exception is thrown.
|
///< If the data type does not match an exception is thrown.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct IngredientColumns : public InventoryColumns
|
||||||
|
{
|
||||||
|
const RefIdColumn *mEffects;
|
||||||
|
|
||||||
|
IngredientColumns (const InventoryColumns& columns);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IngredientRefIdAdapter : public InventoryRefIdAdapter<ESM::Ingredient>
|
||||||
|
{
|
||||||
|
IngredientColumns mColumns;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
IngredientRefIdAdapter (const IngredientColumns& columns);
|
||||||
|
|
||||||
|
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
|
||||||
|
const;
|
||||||
|
|
||||||
|
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
|
||||||
|
const QVariant& value) const;
|
||||||
|
///< If the data type does not match an exception is thrown.
|
||||||
|
};
|
||||||
|
|
||||||
|
class IngredEffectRefIdAdapter : public NestedRefIdAdapterBase
|
||||||
|
{
|
||||||
|
UniversalId::Type mType;
|
||||||
|
|
||||||
|
// not implemented
|
||||||
|
IngredEffectRefIdAdapter (const IngredEffectRefIdAdapter&);
|
||||||
|
IngredEffectRefIdAdapter& operator= (const IngredEffectRefIdAdapter&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
IngredEffectRefIdAdapter();
|
||||||
|
|
||||||
|
virtual ~IngredEffectRefIdAdapter();
|
||||||
|
|
||||||
|
virtual void addNestedRow (const RefIdColumn *column,
|
||||||
|
RefIdData& data, int index, int position) const;
|
||||||
|
|
||||||
|
virtual void removeNestedRow (const RefIdColumn *column,
|
||||||
|
RefIdData& data, int index, int rowToRemove) const;
|
||||||
|
|
||||||
|
virtual void setNestedTable (const RefIdColumn* column,
|
||||||
|
RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const;
|
||||||
|
|
||||||
|
virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column,
|
||||||
|
const RefIdData& data, int index) const;
|
||||||
|
|
||||||
|
virtual QVariant getNestedData (const RefIdColumn *column,
|
||||||
|
const RefIdData& data, int index, int subRowIndex, int subColIndex) const;
|
||||||
|
|
||||||
|
virtual void setNestedData (const RefIdColumn *column,
|
||||||
|
RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const;
|
||||||
|
|
||||||
|
virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const;
|
||||||
|
|
||||||
|
virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const;
|
||||||
|
};
|
||||||
|
|
||||||
struct EnchantableColumns : public InventoryColumns
|
struct EnchantableColumns : public InventoryColumns
|
||||||
{
|
{
|
||||||
const RefIdColumn *mEnchantment;
|
const RefIdColumn *mEnchantment;
|
||||||
|
@ -536,16 +597,16 @@ namespace CSMWorld
|
||||||
return record.get().mAiData.mAlarm;
|
return record.get().mAiData.mAlarm;
|
||||||
|
|
||||||
if (column==mActors.mInventory)
|
if (column==mActors.mInventory)
|
||||||
return true; // to show nested tables in dialogue subview, see IdTree::hasChildren()
|
return QVariant::fromValue(ColumnBase::TableEdit_Full);
|
||||||
|
|
||||||
if (column==mActors.mSpells)
|
if (column==mActors.mSpells)
|
||||||
return true; // to show nested tables in dialogue subview, see IdTree::hasChildren()
|
return QVariant::fromValue(ColumnBase::TableEdit_Full);
|
||||||
|
|
||||||
if (column==mActors.mDestinations)
|
if (column==mActors.mDestinations)
|
||||||
return true; // to show nested tables in dialogue subview, see IdTree::hasChildren()
|
return QVariant::fromValue(ColumnBase::TableEdit_Full);
|
||||||
|
|
||||||
if (column==mActors.mAiPackages)
|
if (column==mActors.mAiPackages)
|
||||||
return true; // to show nested tables in dialogue subview, see IdTree::hasChildren()
|
return QVariant::fromValue(ColumnBase::TableEdit_Full);
|
||||||
|
|
||||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||||
mActors.mServices.find (column);
|
mActors.mServices.find (column);
|
||||||
|
@ -2020,7 +2081,7 @@ namespace CSMWorld
|
||||||
int index) const
|
int index) const
|
||||||
{
|
{
|
||||||
if (column==mLevList.mLevList || column == mLevList.mNestedListLevList)
|
if (column==mLevList.mLevList || column == mLevList.mNestedListLevList)
|
||||||
return true; // to show nested tables in dialogue subview, see IdTree::hasChildren()
|
return QVariant::fromValue(ColumnBase::TableEdit_Full);
|
||||||
|
|
||||||
return BaseRefIdAdapter<RecordT>::getData (column, data, index);
|
return BaseRefIdAdapter<RecordT>::getData (column, data, index);
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue