mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 21:53:51 +00:00
Merge branch 'master' of https://github.com/OpenMW/openmw.git into AIFix2
Conflicts: apps/openmw/mwmechanics/aifollow.cpp
This commit is contained in:
commit
bee057346b
320 changed files with 8438 additions and 3115 deletions
|
@ -12,7 +12,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
|
||||||
message(STATUS "Configuring OpenMW...")
|
message(STATUS "Configuring OpenMW...")
|
||||||
|
|
||||||
set(OPENMW_VERSION_MAJOR 0)
|
set(OPENMW_VERSION_MAJOR 0)
|
||||||
set(OPENMW_VERSION_MINOR 28)
|
set(OPENMW_VERSION_MINOR 29)
|
||||||
set(OPENMW_VERSION_RELEASE 0)
|
set(OPENMW_VERSION_RELEASE 0)
|
||||||
|
|
||||||
set(OPENMW_VERSION_COMMITHASH "")
|
set(OPENMW_VERSION_COMMITHASH "")
|
||||||
|
@ -73,6 +73,8 @@ option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binarie
|
||||||
option(BOOST_STATIC "Link static build of Boost into the binaries" FALSE)
|
option(BOOST_STATIC "Link static build of Boost into the binaries" FALSE)
|
||||||
option(SDL2_STATIC "Link static build of SDL into the binaries" FALSE)
|
option(SDL2_STATIC "Link static build of SDL into the binaries" FALSE)
|
||||||
|
|
||||||
|
option(OPENMW_UNITY_BUILD "Use fewer compilation units to speed up compile time" FALSE)
|
||||||
|
|
||||||
# Apps and tools
|
# Apps and tools
|
||||||
option(BUILD_BSATOOL "build BSA extractor" OFF)
|
option(BUILD_BSATOOL "build BSA extractor" OFF)
|
||||||
option(BUILD_ESMTOOL "build ESM inspector" ON)
|
option(BUILD_ESMTOOL "build ESM inspector" ON)
|
||||||
|
@ -130,6 +132,7 @@ set(OENGINE_OGRE
|
||||||
|
|
||||||
set(OENGINE_GUI
|
set(OENGINE_GUI
|
||||||
${LIBDIR}/openengine/gui/manager.cpp
|
${LIBDIR}/openengine/gui/manager.cpp
|
||||||
|
${LIBDIR}/openengine/gui/layout.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(OENGINE_BULLET
|
set(OENGINE_BULLET
|
||||||
|
@ -238,6 +241,14 @@ if (UNIX AND NOT APPLE)
|
||||||
find_package (Threads)
|
find_package (Threads)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Look for stdint.h
|
||||||
|
include(CheckIncludeFile)
|
||||||
|
check_include_file(stdint.h HAVE_STDINT_H)
|
||||||
|
if(NOT HAVE_STDINT_H)
|
||||||
|
unset(HAVE_STDINT_H CACHE)
|
||||||
|
message(FATAL_ERROR "stdint.h was not found" )
|
||||||
|
endif()
|
||||||
|
|
||||||
include (CheckIncludeFileCXX)
|
include (CheckIncludeFileCXX)
|
||||||
check_include_file_cxx(unordered_map HAVE_UNORDERED_MAP)
|
check_include_file_cxx(unordered_map HAVE_UNORDERED_MAP)
|
||||||
if (HAVE_UNORDERED_MAP)
|
if (HAVE_UNORDERED_MAP)
|
||||||
|
@ -455,7 +466,6 @@ if(WIN32)
|
||||||
INSTALL(FILES
|
INSTALL(FILES
|
||||||
"${OpenMW_SOURCE_DIR}/readme.txt"
|
"${OpenMW_SOURCE_DIR}/readme.txt"
|
||||||
"${OpenMW_SOURCE_DIR}/GPL3.txt"
|
"${OpenMW_SOURCE_DIR}/GPL3.txt"
|
||||||
"${OpenMW_SOURCE_DIR}/OFL.txt"
|
|
||||||
"${OpenMW_SOURCE_DIR}/DejaVu Font License.txt"
|
"${OpenMW_SOURCE_DIR}/DejaVu Font License.txt"
|
||||||
"${OpenMW_BINARY_DIR}/settings-default.cfg"
|
"${OpenMW_BINARY_DIR}/settings-default.cfg"
|
||||||
"${OpenMW_BINARY_DIR}/transparency-overrides.cfg"
|
"${OpenMW_BINARY_DIR}/transparency-overrides.cfg"
|
||||||
|
|
93
OFL.txt
93
OFL.txt
|
@ -1,93 +0,0 @@
|
||||||
Copyright (c) 2010, 2011 Georg Duffner (http://www.georgduffner.at)
|
|
||||||
|
|
||||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
||||||
This license is copied below, and is also available with a FAQ at:
|
|
||||||
http://scripts.sil.org/OFL
|
|
||||||
|
|
||||||
|
|
||||||
-----------------------------------------------------------
|
|
||||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
||||||
-----------------------------------------------------------
|
|
||||||
|
|
||||||
PREAMBLE
|
|
||||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
||||||
development of collaborative font projects, to support the font creation
|
|
||||||
efforts of academic and linguistic communities, and to provide a free and
|
|
||||||
open framework in which fonts may be shared and improved in partnership
|
|
||||||
with others.
|
|
||||||
|
|
||||||
The OFL allows the licensed fonts to be used, studied, modified and
|
|
||||||
redistributed freely as long as they are not sold by themselves. The
|
|
||||||
fonts, including any derivative works, can be bundled, embedded,
|
|
||||||
redistributed and/or sold with any software provided that any reserved
|
|
||||||
names are not used by derivative works. The fonts and derivatives,
|
|
||||||
however, cannot be released under any other type of license. The
|
|
||||||
requirement for fonts to remain under this license does not apply
|
|
||||||
to any document created using the fonts or their derivatives.
|
|
||||||
|
|
||||||
DEFINITIONS
|
|
||||||
"Font Software" refers to the set of files released by the Copyright
|
|
||||||
Holder(s) under this license and clearly marked as such. This may
|
|
||||||
include source files, build scripts and documentation.
|
|
||||||
|
|
||||||
"Reserved Font Name" refers to any names specified as such after the
|
|
||||||
copyright statement(s).
|
|
||||||
|
|
||||||
"Original Version" refers to the collection of Font Software components as
|
|
||||||
distributed by the Copyright Holder(s).
|
|
||||||
|
|
||||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
||||||
or substituting -- in part or in whole -- any of the components of the
|
|
||||||
Original Version, by changing formats or by porting the Font Software to a
|
|
||||||
new environment.
|
|
||||||
|
|
||||||
"Author" refers to any designer, engineer, programmer, technical
|
|
||||||
writer or other person who contributed to the Font Software.
|
|
||||||
|
|
||||||
PERMISSION & CONDITIONS
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
||||||
redistribute, and sell modified and unmodified copies of the Font
|
|
||||||
Software, subject to the following conditions:
|
|
||||||
|
|
||||||
1) Neither the Font Software nor any of its individual components,
|
|
||||||
in Original or Modified Versions, may be sold by itself.
|
|
||||||
|
|
||||||
2) Original or Modified Versions of the Font Software may be bundled,
|
|
||||||
redistributed and/or sold with any software, provided that each copy
|
|
||||||
contains the above copyright notice and this license. These can be
|
|
||||||
included either as stand-alone text files, human-readable headers or
|
|
||||||
in the appropriate machine-readable metadata fields within text or
|
|
||||||
binary files as long as those fields can be easily viewed by the user.
|
|
||||||
|
|
||||||
3) No Modified Version of the Font Software may use the Reserved Font
|
|
||||||
Name(s) unless explicit written permission is granted by the corresponding
|
|
||||||
Copyright Holder. This restriction only applies to the primary font name as
|
|
||||||
presented to the users.
|
|
||||||
|
|
||||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
||||||
Software shall not be used to promote, endorse or advertise any
|
|
||||||
Modified Version, except to acknowledge the contribution(s) of the
|
|
||||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
||||||
permission.
|
|
||||||
|
|
||||||
5) The Font Software, modified or unmodified, in part or in whole,
|
|
||||||
must be distributed entirely under this license, and must not be
|
|
||||||
distributed under any other license. The requirement for fonts to
|
|
||||||
remain under this license does not apply to any document created
|
|
||||||
using the Font Software.
|
|
||||||
|
|
||||||
TERMINATION
|
|
||||||
This license becomes null and void if any of the above conditions are
|
|
||||||
not met.
|
|
||||||
|
|
||||||
DISCLAIMER
|
|
||||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
||||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
||||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
||||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
||||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
|
@ -60,16 +60,21 @@ opencs_hdrs_noqt (view/doc
|
||||||
opencs_units (view/world
|
opencs_units (view/world
|
||||||
table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator
|
table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator
|
||||||
cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool
|
cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool
|
||||||
scenetoolmode infocreator scriptedit
|
scenetoolmode infocreator scriptedit dialoguesubview previewsubview
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units (view/render
|
opencs_units (view/render
|
||||||
scenewidget
|
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
||||||
|
previewwidget
|
||||||
|
)
|
||||||
|
|
||||||
|
opencs_units_noqt (view/render
|
||||||
|
navigation navigation1st navigationfree navigationorbit lighting lightingday lightingnight
|
||||||
|
lightingbright
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (view/world
|
opencs_units_noqt (view/world
|
||||||
dialoguesubview subviews
|
subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate
|
||||||
enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate
|
|
||||||
scripthighlighter idvalidator dialoguecreator
|
scripthighlighter idvalidator dialoguecreator
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -143,6 +148,9 @@ if(WIN32)
|
||||||
set(QT_USE_QTMAIN TRUE)
|
set(QT_USE_QTMAIN TRUE)
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
|
set(BOOST_COMPONENTS system filesystem program_options thread wave)
|
||||||
|
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
||||||
|
|
||||||
find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED)
|
find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED)
|
||||||
include(${QT_USE_FILE})
|
include(${QT_USE_FILE})
|
||||||
|
|
||||||
|
@ -183,6 +191,8 @@ if(APPLE)
|
||||||
endif(APPLE)
|
endif(APPLE)
|
||||||
|
|
||||||
target_link_libraries(opencs
|
target_link_libraries(opencs
|
||||||
|
${OGRE_LIBRARIES}
|
||||||
|
${SHINY_LIBRARIES}
|
||||||
${Boost_LIBRARIES}
|
${Boost_LIBRARIES}
|
||||||
${QT_LIBRARIES}
|
${QT_LIBRARIES}
|
||||||
components
|
components
|
||||||
|
|
|
@ -9,15 +9,30 @@
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
#include <OgreRenderWindow.h>
|
#include <OgreRenderWindow.h>
|
||||||
|
|
||||||
|
#include <extern/shiny/Main/Factory.hpp>
|
||||||
|
#include <extern/shiny/Platforms/Ogre/OgrePlatform.hpp>
|
||||||
|
|
||||||
|
#include <components/ogreinit/ogreinit.hpp>
|
||||||
|
|
||||||
|
#include <components/bsa/resources.hpp>
|
||||||
|
|
||||||
#include "model/doc/document.hpp"
|
#include "model/doc/document.hpp"
|
||||||
#include "model/world/data.hpp"
|
#include "model/world/data.hpp"
|
||||||
|
|
||||||
CS::Editor::Editor()
|
CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
|
||||||
: mDocumentManager (mCfgMgr), mViewManager (mDocumentManager)
|
: mDocumentManager (mCfgMgr), mViewManager (mDocumentManager),
|
||||||
|
mIpcServerName ("org.openmw.OpenCS")
|
||||||
{
|
{
|
||||||
mIpcServerName = "org.openmw.OpenCS";
|
std::pair<Files::PathContainer, std::vector<std::string> > config = readConfig();
|
||||||
|
|
||||||
setupDataFiles();
|
setupDataFiles (config.first);
|
||||||
|
|
||||||
|
CSMSettings::UserSettings::instance().loadSettings ("opencs.cfg");
|
||||||
|
|
||||||
|
ogreInit.init ((mCfgMgr.getUserConfigPath() / "opencsOgre.log").string());
|
||||||
|
|
||||||
|
Bsa::registerResources (Files::Collections (config.first, !mFsStrict), config.second, true,
|
||||||
|
mFsStrict);
|
||||||
|
|
||||||
mNewGame.setLocalData (mLocal);
|
mNewGame.setLocalData (mLocal);
|
||||||
mFileDialog.setLocalData (mLocal);
|
mFileDialog.setLocalData (mLocal);
|
||||||
|
@ -42,7 +57,16 @@ CS::Editor::Editor()
|
||||||
this, SLOT (createNewGame (const boost::filesystem::path&)));
|
this, SLOT (createNewGame (const boost::filesystem::path&)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CS::Editor::setupDataFiles()
|
void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs)
|
||||||
|
{
|
||||||
|
for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter)
|
||||||
|
{
|
||||||
|
QString path = QString::fromUtf8 (iter->string().c_str());
|
||||||
|
mFileDialog.addFiles(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfig()
|
||||||
{
|
{
|
||||||
boost::program_options::variables_map variables;
|
boost::program_options::variables_map variables;
|
||||||
boost::program_options::options_description desc("Syntax: opencs <options>\nAllowed options");
|
boost::program_options::options_description desc("Syntax: opencs <options>\nAllowed options");
|
||||||
|
@ -52,12 +76,18 @@ void CS::Editor::setupDataFiles()
|
||||||
("data-local", boost::program_options::value<std::string>()->default_value(""))
|
("data-local", boost::program_options::value<std::string>()->default_value(""))
|
||||||
("fs-strict", boost::program_options::value<bool>()->implicit_value(true)->default_value(false))
|
("fs-strict", boost::program_options::value<bool>()->implicit_value(true)->default_value(false))
|
||||||
("encoding", boost::program_options::value<std::string>()->default_value("win1252"))
|
("encoding", boost::program_options::value<std::string>()->default_value("win1252"))
|
||||||
("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> >()->
|
||||||
|
default_value(std::vector<std::string>(), "fallback-archive")->multitoken());
|
||||||
|
|
||||||
boost::program_options::notify(variables);
|
boost::program_options::notify(variables);
|
||||||
|
|
||||||
mCfgMgr.readConfiguration(variables, desc);
|
mCfgMgr.readConfiguration(variables, desc);
|
||||||
|
|
||||||
|
mDocumentManager.setResourceDir (mResources = variables["resources"].as<std::string>());
|
||||||
|
|
||||||
|
mFsStrict = variables["fs-strict"].as<bool>();
|
||||||
|
|
||||||
Files::PathContainer dataDirs, dataLocal;
|
Files::PathContainer dataDirs, dataLocal;
|
||||||
if (!variables["data"].empty()) {
|
if (!variables["data"].empty()) {
|
||||||
dataDirs = Files::PathContainer(variables["data"].as<Files::PathContainer>());
|
dataDirs = Files::PathContainer(variables["data"].as<Files::PathContainer>());
|
||||||
|
@ -83,23 +113,11 @@ void CS::Editor::setupDataFiles()
|
||||||
messageBox.exec();
|
messageBox.exec();
|
||||||
|
|
||||||
QApplication::exit (1);
|
QApplication::exit (1);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end());
|
dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end());
|
||||||
|
|
||||||
mDocumentManager.setResourceDir (variables["resources"].as<std::string>());
|
return std::make_pair (dataDirs, variables["fallback-archive"].as<std::vector<std::string> >());
|
||||||
|
|
||||||
for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter)
|
|
||||||
{
|
|
||||||
|
|
||||||
QString path = QString::fromStdString(iter->string());
|
|
||||||
mFileDialog.addFiles(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
//load the settings into the userSettings instance.
|
|
||||||
const QString settingFileName = "opencs.cfg";
|
|
||||||
CSMSettings::UserSettings::instance().loadSettings(settingFileName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CS::Editor::createGame()
|
void CS::Editor::createGame()
|
||||||
|
@ -130,7 +148,7 @@ void CS::Editor::openFiles (const boost::filesystem::path &savePath)
|
||||||
std::vector<boost::filesystem::path> files;
|
std::vector<boost::filesystem::path> files;
|
||||||
|
|
||||||
foreach (const QString &path, mFileDialog.selectedFilePaths())
|
foreach (const QString &path, mFileDialog.selectedFilePaths())
|
||||||
files.push_back(path.toStdString());
|
files.push_back(path.toUtf8().constData());
|
||||||
|
|
||||||
CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, false);
|
CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, false);
|
||||||
|
|
||||||
|
@ -143,10 +161,10 @@ void CS::Editor::createNewFile (const boost::filesystem::path &savePath)
|
||||||
std::vector<boost::filesystem::path> files;
|
std::vector<boost::filesystem::path> files;
|
||||||
|
|
||||||
foreach (const QString &path, mFileDialog.selectedFilePaths()) {
|
foreach (const QString &path, mFileDialog.selectedFilePaths()) {
|
||||||
files.push_back(path.toStdString());
|
files.push_back(path.toUtf8().constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
files.push_back(mFileDialog.filename().toStdString());
|
files.push_back(mFileDialog.filename().toUtf8().constData());
|
||||||
|
|
||||||
CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, true);
|
CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, true);
|
||||||
|
|
||||||
|
@ -210,8 +228,15 @@ int CS::Editor::run()
|
||||||
if (mLocal.empty())
|
if (mLocal.empty())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// temporarily disable OGRE-integration (need to fix path problem first)
|
mStartup.show();
|
||||||
#if 0
|
|
||||||
|
QApplication::setQuitOnLastWindowClosed (true);
|
||||||
|
|
||||||
|
return QApplication::exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::auto_ptr<sh::Factory> CS::Editor::setupGraphics()
|
||||||
|
{
|
||||||
// TODO: setting
|
// TODO: setting
|
||||||
Ogre::Root::getSingleton().setRenderSystem(Ogre::Root::getSingleton().getRenderSystemByName("OpenGL Rendering Subsystem"));
|
Ogre::Root::getSingleton().setRenderSystem(Ogre::Root::getSingleton().getRenderSystemByName("OpenGL Rendering Subsystem"));
|
||||||
|
|
||||||
|
@ -228,11 +253,37 @@ int CS::Editor::run()
|
||||||
#endif
|
#endif
|
||||||
Ogre::RenderWindow* hiddenWindow = Ogre::Root::getSingleton().createRenderWindow("InactiveHidden", 1, 1, false, ¶ms);
|
Ogre::RenderWindow* hiddenWindow = Ogre::Root::getSingleton().createRenderWindow("InactiveHidden", 1, 1, false, ¶ms);
|
||||||
hiddenWindow->setActive(false);
|
hiddenWindow->setActive(false);
|
||||||
#endif
|
|
||||||
|
|
||||||
mStartup.show();
|
sh::OgrePlatform* platform =
|
||||||
|
new sh::OgrePlatform ("General", (mResources / "materials").string());
|
||||||
|
|
||||||
QApplication::setQuitOnLastWindowClosed (true);
|
if (!boost::filesystem::exists (mCfgMgr.getCachePath()))
|
||||||
|
boost::filesystem::create_directories (mCfgMgr.getCachePath());
|
||||||
|
|
||||||
return QApplication::exec();
|
platform->setCacheFolder (mCfgMgr.getCachePath().string());
|
||||||
|
|
||||||
|
std::auto_ptr<sh::Factory> factory (new sh::Factory (platform));
|
||||||
|
|
||||||
|
factory->setCurrentLanguage (sh::Language_GLSL); /// \todo make this configurable
|
||||||
|
factory->setWriteSourceCache (true);
|
||||||
|
factory->setReadSourceCache (true);
|
||||||
|
factory->setReadMicrocodeCache (true);
|
||||||
|
factory->setWriteMicrocodeCache (true);
|
||||||
|
|
||||||
|
factory->loadAllFiles();
|
||||||
|
|
||||||
|
sh::Factory::getInstance().setGlobalSetting ("fog", "true");
|
||||||
|
|
||||||
|
sh::Factory::getInstance().setGlobalSetting ("shadows", "false");
|
||||||
|
sh::Factory::getInstance().setGlobalSetting ("shadows_pssm", "false");
|
||||||
|
|
||||||
|
sh::Factory::getInstance ().setGlobalSetting ("render_refraction", "false");
|
||||||
|
|
||||||
|
sh::Factory::getInstance ().setGlobalSetting ("viewproj_fix", "false");
|
||||||
|
|
||||||
|
sh::Factory::getInstance ().setGlobalSetting ("num_lights", "8");
|
||||||
|
|
||||||
|
/// \todo add more configurable shiny settings
|
||||||
|
|
||||||
|
return factory;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
#ifndef CS_EDITOR_H
|
#ifndef CS_EDITOR_H
|
||||||
#define CS_EDITOR_H
|
#define CS_EDITOR_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QLocalServer>
|
#include <QLocalServer>
|
||||||
#include <QLocalSocket>
|
#include <QLocalSocket>
|
||||||
|
|
||||||
|
#include <extern/shiny/Main/Factory.hpp>
|
||||||
|
|
||||||
#ifndef Q_MOC_RUN
|
#ifndef Q_MOC_RUN
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <components/files/multidircollection.hpp>
|
||||||
|
|
||||||
#include "model/settings/usersettings.hpp"
|
#include "model/settings/usersettings.hpp"
|
||||||
#include "model/doc/documentmanager.hpp"
|
#include "model/doc/documentmanager.hpp"
|
||||||
|
|
||||||
|
@ -20,6 +26,11 @@
|
||||||
|
|
||||||
#include "view/settings/usersettingsdialog.hpp"
|
#include "view/settings/usersettingsdialog.hpp"
|
||||||
|
|
||||||
|
namespace OgreInit
|
||||||
|
{
|
||||||
|
class OgreInit;
|
||||||
|
}
|
||||||
|
|
||||||
namespace CS
|
namespace CS
|
||||||
{
|
{
|
||||||
class Editor : public QObject
|
class Editor : public QObject
|
||||||
|
@ -34,10 +45,14 @@ namespace CS
|
||||||
CSVDoc::NewGameDialogue mNewGame;
|
CSVDoc::NewGameDialogue mNewGame;
|
||||||
CSVSettings::UserSettingsDialog mSettings;
|
CSVSettings::UserSettingsDialog mSettings;
|
||||||
CSVDoc::FileDialog mFileDialog;
|
CSVDoc::FileDialog mFileDialog;
|
||||||
|
|
||||||
boost::filesystem::path mLocal;
|
boost::filesystem::path mLocal;
|
||||||
|
boost::filesystem::path mResources;
|
||||||
|
bool mFsStrict;
|
||||||
|
|
||||||
void setupDataFiles();
|
void setupDataFiles (const Files::PathContainer& dataDirs);
|
||||||
|
|
||||||
|
std::pair<Files::PathContainer, std::vector<std::string> > readConfig();
|
||||||
|
///< \return data paths
|
||||||
|
|
||||||
// not implemented
|
// not implemented
|
||||||
Editor (const Editor&);
|
Editor (const Editor&);
|
||||||
|
@ -45,7 +60,7 @@ namespace CS
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Editor();
|
Editor (OgreInit::OgreInit& ogreInit);
|
||||||
|
|
||||||
bool makeIPCServer();
|
bool makeIPCServer();
|
||||||
void connectToIPCServer();
|
void connectToIPCServer();
|
||||||
|
@ -53,6 +68,9 @@ namespace CS
|
||||||
int run();
|
int run();
|
||||||
///< \return error status
|
///< \return error status
|
||||||
|
|
||||||
|
std::auto_ptr<sh::Factory> setupGraphics();
|
||||||
|
///< The returned factory must persist at least as long as *this.
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void createGame();
|
void createGame();
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
|
||||||
|
#include <extern/shiny/Main/Factory.hpp>
|
||||||
|
|
||||||
#include <components/ogreinit/ogreinit.hpp>
|
#include <components/ogreinit/ogreinit.hpp>
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
|
@ -40,15 +42,11 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
Q_INIT_RESOURCE (resources);
|
Q_INIT_RESOURCE (resources);
|
||||||
|
|
||||||
// TODO: Ogre startup shouldn't be here, but it currently has to:
|
|
||||||
// SceneWidget destructor will delete the created render window, which would be called _after_ Root has shut down :(
|
|
||||||
|
|
||||||
Application mApplication (argc, argv);
|
|
||||||
// temporarily disable OGRE-integration (need to fix path problem first)
|
|
||||||
#if 0
|
|
||||||
OgreInit::OgreInit ogreInit;
|
OgreInit::OgreInit ogreInit;
|
||||||
ogreInit.init("./opencsOgre.log"); // TODO log path?
|
|
||||||
#endif
|
std::auto_ptr<sh::Factory> shinyFactory;
|
||||||
|
|
||||||
|
Application application (argc, argv);
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
QDir dir(QCoreApplication::applicationDirPath());
|
QDir dir(QCoreApplication::applicationDirPath());
|
||||||
|
@ -66,12 +64,12 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
QStringList libraryPaths;
|
QStringList libraryPaths;
|
||||||
libraryPaths << pluginsPath.path() << QCoreApplication::applicationDirPath();
|
libraryPaths << pluginsPath.path() << QCoreApplication::applicationDirPath();
|
||||||
mApplication.setLibraryPaths(libraryPaths);
|
application.setLibraryPaths(libraryPaths);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mApplication.setWindowIcon (QIcon (":./opencs.png"));
|
application.setWindowIcon (QIcon (":./opencs.png"));
|
||||||
|
|
||||||
CS::Editor editor;
|
CS::Editor editor (ogreInit);
|
||||||
|
|
||||||
if(!editor.makeIPCServer())
|
if(!editor.makeIPCServer())
|
||||||
{
|
{
|
||||||
|
@ -79,5 +77,7 @@ int main(int argc, char *argv[])
|
||||||
// return 0;
|
// return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shinyFactory = editor.setupGraphics();
|
||||||
|
|
||||||
return editor.run();
|
return editor.run();
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,6 +143,6 @@ void CSMTools::Tools::verifierMessage (const QString& message, int type)
|
||||||
std::map<int, int>::iterator iter = mActiveReports.find (type);
|
std::map<int, int>::iterator iter = mActiveReports.find (type);
|
||||||
|
|
||||||
if (iter!=mActiveReports.end())
|
if (iter!=mActiveReports.end())
|
||||||
mReports[iter->second]->add (message.toStdString());
|
mReports[iter->second]->add (message.toUtf8().constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -448,7 +448,8 @@ namespace CSMWorld
|
||||||
template<typename ESXRecordT, typename IdAccessorT>
|
template<typename ESXRecordT, typename IdAccessorT>
|
||||||
void Collection<ESXRecordT, IdAccessorT>::setRecord (int index, const Record<ESXRecordT>& record)
|
void Collection<ESXRecordT, IdAccessorT>::setRecord (int index, const Record<ESXRecordT>& record)
|
||||||
{
|
{
|
||||||
if (IdAccessorT().getId (mRecords.at (index).get())!=IdAccessorT().getId (record.get()))
|
if (Misc::StringUtils::lowerCase (IdAccessorT().getId (mRecords.at (index).get()))!=
|
||||||
|
Misc::StringUtils::lowerCase (IdAccessorT().getId (record.get())))
|
||||||
throw std::runtime_error ("attempt to change the ID of a record");
|
throw std::runtime_error ("attempt to change the ID of a record");
|
||||||
|
|
||||||
mRecords.at (index) = record;
|
mRecords.at (index) = record;
|
||||||
|
|
|
@ -18,3 +18,8 @@ std::string CSMWorld::ColumnBase::getTitle() const
|
||||||
{
|
{
|
||||||
return Columns::getName (static_cast<Columns::ColumnId> (mColumnId));
|
return Columns::getName (static_cast<Columns::ColumnId> (mColumnId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CSMWorld::ColumnBase::getId() const
|
||||||
|
{
|
||||||
|
return mColumnId;
|
||||||
|
}
|
|
@ -28,6 +28,7 @@ namespace CSMWorld
|
||||||
{
|
{
|
||||||
Display_None, //Do not use
|
Display_None, //Do not use
|
||||||
Display_String,
|
Display_String,
|
||||||
|
Display_LongString,
|
||||||
|
|
||||||
//CONCRETE TYPES STARTS HERE
|
//CONCRETE TYPES STARTS HERE
|
||||||
Display_Skill,
|
Display_Skill,
|
||||||
|
@ -105,6 +106,8 @@ namespace CSMWorld
|
||||||
///< Can this column be edited directly by the user?
|
///< Can this column be edited directly by the user?
|
||||||
|
|
||||||
virtual std::string getTitle() const;
|
virtual std::string getTitle() const;
|
||||||
|
|
||||||
|
virtual int getId() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename ESXRecordT>
|
template<typename ESXRecordT>
|
||||||
|
|
|
@ -37,7 +37,6 @@ namespace CSMWorld
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \note Shares ID with IdColumn. A table can not have both.
|
|
||||||
template<typename ESXRecordT>
|
template<typename ESXRecordT>
|
||||||
struct StringIdColumn : public Column<ESXRecordT>
|
struct StringIdColumn : public Column<ESXRecordT>
|
||||||
{
|
{
|
||||||
|
@ -202,7 +201,7 @@ namespace CSMWorld
|
||||||
struct DescriptionColumn : public Column<ESXRecordT>
|
struct DescriptionColumn : public Column<ESXRecordT>
|
||||||
{
|
{
|
||||||
DescriptionColumn()
|
DescriptionColumn()
|
||||||
: Column<ESXRecordT> (Columns::ColumnId_Description, ColumnBase::Display_String)
|
: Column<ESXRecordT> (Columns::ColumnId_Description, ColumnBase::Display_LongString)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||||
|
@ -834,15 +833,15 @@ namespace CSMWorld
|
||||||
|
|
||||||
virtual bool isUserEditable() const
|
virtual bool isUserEditable() const
|
||||||
{
|
{
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \note Shares ID with StringIdColumn. A table can not have both.
|
|
||||||
template<typename ESXRecordT>
|
template<typename ESXRecordT>
|
||||||
struct IdColumn : public Column<ESXRecordT>
|
struct IdColumn : public Column<ESXRecordT>
|
||||||
{
|
{
|
||||||
IdColumn() : Column<ESXRecordT> (Columns::ColumnId_Id, ColumnBase::Display_String) {}
|
IdColumn() : Column<ESXRecordT> (Columns::ColumnId_ReferenceableId,
|
||||||
|
ColumnBase::Display_Referenceable) {}
|
||||||
|
|
||||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||||
{
|
{
|
||||||
|
@ -1114,7 +1113,7 @@ namespace CSMWorld
|
||||||
|
|
||||||
virtual bool isUserEditable() const
|
virtual bool isUserEditable() const
|
||||||
{
|
{
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1380,7 +1379,7 @@ namespace CSMWorld
|
||||||
template<typename ESXRecordT>
|
template<typename ESXRecordT>
|
||||||
struct QuestDescriptionColumn : public Column<ESXRecordT>
|
struct QuestDescriptionColumn : public Column<ESXRecordT>
|
||||||
{
|
{
|
||||||
QuestDescriptionColumn() : Column<ESXRecordT> (Columns::ColumnId_QuestDescription, ColumnBase::Display_String) {}
|
QuestDescriptionColumn() : Column<ESXRecordT> (Columns::ColumnId_QuestDescription, ColumnBase::Display_LongString) {}
|
||||||
|
|
||||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||||
{
|
{
|
||||||
|
@ -1560,7 +1559,7 @@ namespace CSMWorld
|
||||||
template<typename ESXRecordT>
|
template<typename ESXRecordT>
|
||||||
struct ResponseColumn : public Column<ESXRecordT>
|
struct ResponseColumn : public Column<ESXRecordT>
|
||||||
{
|
{
|
||||||
ResponseColumn() : Column<ESXRecordT> (Columns::ColumnId_Response, ColumnBase::Display_String) {}
|
ResponseColumn() : Column<ESXRecordT> (Columns::ColumnId_Response, ColumnBase::Display_LongString) {}
|
||||||
|
|
||||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -172,7 +172,8 @@ namespace CSMWorld
|
||||||
{ ColumnId_Rank, "Rank" },
|
{ ColumnId_Rank, "Rank" },
|
||||||
{ ColumnId_Gender, "Gender" },
|
{ ColumnId_Gender, "Gender" },
|
||||||
{ ColumnId_PcRank, "PC Rank" },
|
{ ColumnId_PcRank, "PC Rank" },
|
||||||
{ ColumnId_Scope, "Scope", },
|
{ ColumnId_Scope, "Scope" },
|
||||||
|
{ ColumnId_ReferenceableId, "Referenceable ID" },
|
||||||
|
|
||||||
{ ColumnId_UseValue1, "Use value 1" },
|
{ ColumnId_UseValue1, "Use value 1" },
|
||||||
{ ColumnId_UseValue2, "Use value 2" },
|
{ ColumnId_UseValue2, "Use value 2" },
|
||||||
|
|
|
@ -166,6 +166,7 @@ namespace CSMWorld
|
||||||
ColumnId_Gender = 153,
|
ColumnId_Gender = 153,
|
||||||
ColumnId_PcRank = 154,
|
ColumnId_PcRank = 154,
|
||||||
ColumnId_Scope = 155,
|
ColumnId_Scope = 155,
|
||||||
|
ColumnId_ReferenceableId = 156,
|
||||||
|
|
||||||
// Allocated to a separate value range, so we don't get a collision should we ever need
|
// Allocated to a separate value range, so we don't get a collision should we ever need
|
||||||
// to extend the number of use values.
|
// to extend the number of use values.
|
||||||
|
|
|
@ -247,12 +247,12 @@ CSMWorld::Data::Data() : mRefs (mCells)
|
||||||
addModel (new IdTable (&mSpells), UniversalId::Type_Spells, UniversalId::Type_Spell);
|
addModel (new IdTable (&mSpells), UniversalId::Type_Spells, UniversalId::Type_Spell);
|
||||||
addModel (new IdTable (&mTopics), UniversalId::Type_Topics, UniversalId::Type_Topic);
|
addModel (new IdTable (&mTopics), UniversalId::Type_Topics, UniversalId::Type_Topic);
|
||||||
addModel (new IdTable (&mJournals), UniversalId::Type_Journals, UniversalId::Type_Journal);
|
addModel (new IdTable (&mJournals), UniversalId::Type_Journals, UniversalId::Type_Journal);
|
||||||
addModel (new IdTable (&mTopicInfos), UniversalId::Type_TopicInfos, UniversalId::Type_TopicInfo);
|
addModel (new IdTable (&mTopicInfos, IdTable::Reordering_WithinTopic), UniversalId::Type_TopicInfos, UniversalId::Type_TopicInfo);
|
||||||
addModel (new IdTable (&mJournalInfos), UniversalId::Type_JournalInfos, UniversalId::Type_JournalInfo);
|
addModel (new IdTable (&mJournalInfos, IdTable::Reordering_WithinTopic), UniversalId::Type_JournalInfos, UniversalId::Type_JournalInfo);
|
||||||
addModel (new IdTable (&mCells), UniversalId::Type_Cells, UniversalId::Type_Cell);
|
addModel (new IdTable (&mCells, IdTable::Reordering_None, IdTable::Viewing_Id), UniversalId::Type_Cells, UniversalId::Type_Cell);
|
||||||
addModel (new IdTable (&mReferenceables), UniversalId::Type_Referenceables,
|
addModel (new IdTable (&mReferenceables, IdTable::Reordering_None, IdTable::Viewing_None, true),
|
||||||
UniversalId::Type_Referenceable);
|
UniversalId::Type_Referenceables, UniversalId::Type_Referenceable);
|
||||||
addModel (new IdTable (&mRefs), UniversalId::Type_References, UniversalId::Type_Reference, false);
|
addModel (new IdTable (&mRefs, IdTable::Reordering_None, IdTable::Viewing_Cell, true), UniversalId::Type_References, UniversalId::Type_Reference, false);
|
||||||
addModel (new IdTable (&mFilters), UniversalId::Type_Filters, UniversalId::Type_Filter, false);
|
addModel (new IdTable (&mFilters), UniversalId::Type_Filters, UniversalId::Type_Filter, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,9 @@
|
||||||
#include "collectionbase.hpp"
|
#include "collectionbase.hpp"
|
||||||
#include "columnbase.hpp"
|
#include "columnbase.hpp"
|
||||||
|
|
||||||
CSMWorld::IdTable::IdTable (CollectionBase *idCollection, Reordering reordering)
|
CSMWorld::IdTable::IdTable (CollectionBase *idCollection, Reordering reordering,
|
||||||
: mIdCollection (idCollection), mReordering (reordering)
|
Viewing viewing, bool preview)
|
||||||
|
: mIdCollection (idCollection), mReordering (reordering), mViewing (viewing), mPreview (preview)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
CSMWorld::IdTable::~IdTable()
|
CSMWorld::IdTable::~IdTable()
|
||||||
|
@ -189,3 +190,54 @@ CSMWorld::IdTable::Reordering CSMWorld::IdTable::getReordering() const
|
||||||
{
|
{
|
||||||
return mReordering;
|
return mReordering;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSMWorld::IdTable::Viewing CSMWorld::IdTable::getViewing() const
|
||||||
|
{
|
||||||
|
return mViewing;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMWorld::IdTable::hasPreview() const
|
||||||
|
{
|
||||||
|
return mPreview;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row) const
|
||||||
|
{
|
||||||
|
std::string id;
|
||||||
|
std::string hint;
|
||||||
|
|
||||||
|
if (mViewing==Viewing_Cell)
|
||||||
|
{
|
||||||
|
int cellColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Cell);
|
||||||
|
int idColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Id);
|
||||||
|
|
||||||
|
if (cellColumn!=-1 && idColumn!=-1)
|
||||||
|
{
|
||||||
|
id = mIdCollection->getData (row, cellColumn).toString().toUtf8().constData();
|
||||||
|
hint = "r:" + std::string (mIdCollection->getData (row, idColumn).toString().toUtf8().constData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mViewing==Viewing_Id)
|
||||||
|
{
|
||||||
|
int column = mIdCollection->searchColumnIndex (Columns::ColumnId_Id);
|
||||||
|
|
||||||
|
if (column!=-1)
|
||||||
|
{
|
||||||
|
id = mIdCollection->getData (row, column).toString().toUtf8().constData();
|
||||||
|
hint = "c:" + id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id.empty())
|
||||||
|
return std::make_pair (UniversalId::Type_None, "");
|
||||||
|
|
||||||
|
if (id[0]=='#')
|
||||||
|
id = "sys::default";
|
||||||
|
|
||||||
|
return std::make_pair (UniversalId (UniversalId::Type_Scene, id), hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSMWorld::IdTable::getColumnId(int column) const
|
||||||
|
{
|
||||||
|
return mIdCollection->getColumn(column).getId();
|
||||||
|
}
|
|
@ -25,10 +25,21 @@ namespace CSMWorld
|
||||||
Reordering_WithinTopic
|
Reordering_WithinTopic
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum Viewing
|
||||||
|
{
|
||||||
|
Viewing_None,
|
||||||
|
Viewing_Id, // use ID column to generate view request (ID is transformed into
|
||||||
|
// worldspace and original ID is passed as hint with c: prefix)
|
||||||
|
Viewing_Cell // use cell column to generate view request (cell ID is transformed
|
||||||
|
// into worldspace and record ID is passed as hint with r: prefix)
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
CollectionBase *mIdCollection;
|
CollectionBase *mIdCollection;
|
||||||
Reordering mReordering;
|
Reordering mReordering;
|
||||||
|
Viewing mViewing;
|
||||||
|
bool mPreview;
|
||||||
|
|
||||||
// not implemented
|
// not implemented
|
||||||
IdTable (const IdTable&);
|
IdTable (const IdTable&);
|
||||||
|
@ -36,7 +47,8 @@ namespace CSMWorld
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
IdTable (CollectionBase *idCollection, Reordering reordering = Reordering_WithinTopic);
|
IdTable (CollectionBase *idCollection, Reordering reordering = Reordering_None,
|
||||||
|
Viewing viewing = Viewing_None, bool preview = false);
|
||||||
///< The ownership of \a idCollection is not transferred.
|
///< The ownership of \a idCollection is not transferred.
|
||||||
|
|
||||||
virtual ~IdTable();
|
virtual ~IdTable();
|
||||||
|
@ -86,6 +98,16 @@ namespace CSMWorld
|
||||||
/// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex).
|
/// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex).
|
||||||
|
|
||||||
Reordering getReordering() const;
|
Reordering getReordering() const;
|
||||||
|
|
||||||
|
Viewing getViewing() const;
|
||||||
|
|
||||||
|
bool hasPreview() const;
|
||||||
|
|
||||||
|
std::pair<UniversalId, std::string> view (int row) const;
|
||||||
|
///< Return the UniversalId and the hint for viewing \a row. If viewing is not
|
||||||
|
/// supported by this table, return (UniversalId::Type_None, "").
|
||||||
|
|
||||||
|
int getColumnId(int column) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ CSMWorld::TableMimeData::TableMimeData (UniversalId id, const CSMDoc::Document&
|
||||||
mDocument(document)
|
mDocument(document)
|
||||||
{
|
{
|
||||||
mUniversalId.push_back (id);
|
mUniversalId.push_back (id);
|
||||||
mObjectsFormats << QString::fromStdString ("tabledata/" + id.getTypeName());
|
mObjectsFormats << QString::fromUtf8 (("tabledata/" + id.getTypeName()).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::TableMimeData::TableMimeData (std::vector< CSMWorld::UniversalId >& id, const CSMDoc::Document& document) :
|
CSMWorld::TableMimeData::TableMimeData (std::vector< CSMWorld::UniversalId >& id, const CSMDoc::Document& document) :
|
||||||
|
@ -16,7 +16,7 @@ CSMWorld::TableMimeData::TableMimeData (std::vector< CSMWorld::UniversalId >& id
|
||||||
{
|
{
|
||||||
for (std::vector<UniversalId>::iterator it (mUniversalId.begin()); it != mUniversalId.end(); ++it)
|
for (std::vector<UniversalId>::iterator it (mUniversalId.begin()); it != mUniversalId.end(); ++it)
|
||||||
{
|
{
|
||||||
mObjectsFormats << QString::fromStdString ("tabledata/" + it->getTypeName());
|
mObjectsFormats << QString::fromUtf8 (("tabledata/" + it->getTypeName()).c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,55 +64,138 @@ std::vector< CSMWorld::UniversalId > CSMWorld::TableMimeData::getData() const
|
||||||
return mUniversalId;
|
return mUniversalId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSMWorld::TableMimeData::isReferencable(CSMWorld::ColumnBase::Display type) const
|
||||||
|
{
|
||||||
|
return ( type == CSMWorld::ColumnBase::Display_Activator
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_Potion
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_Apparatus
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_Armor
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_Book
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_Clothing
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_Container
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_Creature
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_Door
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_Ingredient
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_CreatureLevelledList
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_ItemLevelledList
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_Light
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_Lockpick
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_Miscellaneous
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_Npc
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_Probe
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_Repair
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_Static
|
||||||
|
|| type == CSMWorld::ColumnBase::Display_Weapon);
|
||||||
|
}
|
||||||
|
bool CSMWorld::TableMimeData::isReferencable(CSMWorld::UniversalId::Type type) const
|
||||||
|
{
|
||||||
|
return ( type == CSMWorld::UniversalId::Type_Activator
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Potion
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Apparatus
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Armor
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Book
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Clothing
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Container
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Creature
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Door
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Ingredient
|
||||||
|
|| type == CSMWorld::UniversalId::Type_CreatureLevelledList
|
||||||
|
|| type == CSMWorld::UniversalId::Type_ItemLevelledList
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Light
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Lockpick
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Miscellaneous
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Npc
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Probe
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Repair
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Static
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Weapon);
|
||||||
|
}
|
||||||
|
|
||||||
bool CSMWorld::TableMimeData::holdsType (CSMWorld::UniversalId::Type type) const
|
bool CSMWorld::TableMimeData::holdsType (CSMWorld::UniversalId::Type type) const
|
||||||
{
|
{
|
||||||
|
bool referencable = (type == CSMWorld::UniversalId::Type_Referenceable);
|
||||||
for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it)
|
for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it)
|
||||||
{
|
{
|
||||||
|
if (referencable)
|
||||||
|
{
|
||||||
|
if (isReferencable(it->getType()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (it->getType() == type)
|
if (it->getType() == type)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSMWorld::TableMimeData::holdsType (CSMWorld::ColumnBase::Display type) const
|
bool CSMWorld::TableMimeData::holdsType (CSMWorld::ColumnBase::Display type) const
|
||||||
{
|
{
|
||||||
|
bool referencable = (type == CSMWorld::ColumnBase::Display_Referenceable);
|
||||||
for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it)
|
for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it)
|
||||||
{
|
{
|
||||||
|
if (referencable)
|
||||||
|
{
|
||||||
|
if (isReferencable(it->getType()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (it->getType() == convertEnums (type))
|
if (it->getType() == convertEnums (type))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::UniversalId::Type type) const
|
CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::UniversalId::Type type) const
|
||||||
{
|
{
|
||||||
|
bool referencable = (type == CSMWorld::UniversalId::Type_Referenceable);
|
||||||
for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it)
|
for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it)
|
||||||
|
{
|
||||||
|
if (referencable)
|
||||||
|
{
|
||||||
|
if (isReferencable(it->getType()))
|
||||||
|
{
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
} else
|
||||||
{
|
{
|
||||||
if (it->getType() == type)
|
if (it->getType() == type)
|
||||||
{
|
{
|
||||||
return *it;
|
return *it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
throw ("TableMimeData object does not hold object of the seeked type");
|
throw ("TableMimeData object does not hold object of the seeked type");
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::ColumnBase::Display type) const
|
CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::ColumnBase::Display type) const
|
||||||
{
|
{
|
||||||
|
bool referencable = (type == CSMWorld::ColumnBase::Display_Referenceable);
|
||||||
for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it)
|
for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it)
|
||||||
{
|
{
|
||||||
|
if (referencable)
|
||||||
|
{
|
||||||
|
if (isReferencable(it->getType()))
|
||||||
|
{
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (it->getType() == convertEnums (type))
|
if (it->getType() == convertEnums (type))
|
||||||
{
|
{
|
||||||
return *it;
|
return *it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
throw ("TableMimeData object does not hold object of the seeked type");
|
throw ("TableMimeData object does not hold object of the seeked type");
|
||||||
}
|
}
|
||||||
|
@ -444,3 +527,8 @@ CSMWorld::ColumnBase::Display CSMWorld::TableMimeData::convertEnums (CSMWorld::U
|
||||||
return CSMWorld::ColumnBase::Display_None;
|
return CSMWorld::ColumnBase::Display_None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CSMDoc::Document* CSMWorld::TableMimeData::getDocumentPtr() const
|
||||||
|
{
|
||||||
|
return &mDocument;
|
||||||
|
}
|
|
@ -27,6 +27,9 @@ namespace CSMWorld
|
||||||
|
|
||||||
class TableMimeData : public QMimeData
|
class TableMimeData : public QMimeData
|
||||||
{
|
{
|
||||||
|
std::vector<UniversalId> mUniversalId;
|
||||||
|
QStringList mObjectsFormats;
|
||||||
|
const CSMDoc::Document& mDocument;
|
||||||
public:
|
public:
|
||||||
TableMimeData(UniversalId id, const CSMDoc::Document& document);
|
TableMimeData(UniversalId id, const CSMDoc::Document& document);
|
||||||
|
|
||||||
|
@ -48,15 +51,16 @@ namespace CSMWorld
|
||||||
|
|
||||||
UniversalId returnMatching(UniversalId::Type type) const;
|
UniversalId returnMatching(UniversalId::Type type) const;
|
||||||
|
|
||||||
|
const CSMDoc::Document* getDocumentPtr() const;
|
||||||
|
|
||||||
UniversalId returnMatching(CSMWorld::ColumnBase::Display type) const;
|
UniversalId returnMatching(CSMWorld::ColumnBase::Display type) const;
|
||||||
|
|
||||||
static CSMWorld::UniversalId::Type convertEnums(CSMWorld::ColumnBase::Display type);
|
static CSMWorld::UniversalId::Type convertEnums(CSMWorld::ColumnBase::Display type);
|
||||||
static CSMWorld::ColumnBase::Display convertEnums(CSMWorld::UniversalId::Type type);
|
static CSMWorld::ColumnBase::Display convertEnums(CSMWorld::UniversalId::Type type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<UniversalId> mUniversalId;
|
bool isReferencable(CSMWorld::UniversalId::Type type) const;
|
||||||
QStringList mObjectsFormats;
|
bool isReferencable(CSMWorld::ColumnBase::Display type) const;
|
||||||
const CSMDoc::Document& mDocument;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,14 +90,16 @@ namespace
|
||||||
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Weapon, "Weapon", ":./weapon.png" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Weapon, "Weapon", ":./weapon.png" },
|
||||||
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Reference, "Reference", 0 },
|
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Reference, "Reference", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Filter, "Filter", ":./filter.png" },
|
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Filter, "Filter", ":./filter.png" },
|
||||||
|
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 },
|
||||||
|
|
||||||
|
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Preview, "Preview", 0 },
|
||||||
|
|
||||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
||||||
};
|
};
|
||||||
|
|
||||||
static const TypeData sIndexArg[] =
|
static const TypeData sIndexArg[] =
|
||||||
{
|
{
|
||||||
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results", 0 },
|
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 },
|
|
||||||
|
|
||||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,8 @@ namespace CSMWorld
|
||||||
Type_TopicInfo,
|
Type_TopicInfo,
|
||||||
Type_JournalInfos,
|
Type_JournalInfos,
|
||||||
Type_JournalInfo,
|
Type_JournalInfo,
|
||||||
Type_Scene
|
Type_Scene,
|
||||||
|
Type_Preview
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { NumberOfTypes = Type_Scene+1 };
|
enum { NumberOfTypes = Type_Scene+1 };
|
||||||
|
|
|
@ -40,7 +40,7 @@ OpenDialog::OpenDialog(QWidget * parent) : QDialog(parent)
|
||||||
mCfgMgr.processPaths(mDataLocal);
|
mCfgMgr.processPaths(mDataLocal);
|
||||||
|
|
||||||
// Set the charset for reading the esm/esp files
|
// Set the charset for reading the esm/esp files
|
||||||
QString encoding = QString::fromStdString(variables["encoding"].as<std::string>());
|
QString encoding = QString::fromUtf8 (variables["encoding"].as<std::string>().c_str());
|
||||||
|
|
||||||
Files::PathContainer dataDirs;
|
Files::PathContainer dataDirs;
|
||||||
dataDirs.insert(dataDirs.end(), mDataDirs.begin(), mDataDirs.end());
|
dataDirs.insert(dataDirs.end(), mDataDirs.begin(), mDataDirs.end());
|
||||||
|
|
|
@ -4,7 +4,7 @@ CSVDoc::SubView::SubView (const CSMWorld::UniversalId& id) : mUniversalId (id)
|
||||||
{
|
{
|
||||||
/// \todo add a button to the title bar that clones this sub view
|
/// \todo add a button to the title bar that clones this sub view
|
||||||
|
|
||||||
setWindowTitle (mUniversalId.toString().c_str());
|
setWindowTitle (QString::fromUtf8 (mUniversalId.toString().c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::UniversalId CSVDoc::SubView::getUniversalId() const
|
CSMWorld::UniversalId CSVDoc::SubView::getUniversalId() const
|
||||||
|
@ -17,3 +17,11 @@ void CSVDoc::SubView::updateEditorSetting (const QString &settingName, const QSt
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVDoc::SubView::setStatusBar (bool show) {}
|
void CSVDoc::SubView::setStatusBar (bool show) {}
|
||||||
|
|
||||||
|
void CSVDoc::SubView::useHint (const std::string& hint) {}
|
||||||
|
|
||||||
|
void CSVDoc::SubView::setUniversalId (const CSMWorld::UniversalId& id)
|
||||||
|
{
|
||||||
|
mUniversalId = id;
|
||||||
|
setWindowTitle (mUniversalId.toString().c_str());
|
||||||
|
}
|
|
@ -27,6 +27,8 @@ namespace CSVDoc
|
||||||
// not implemented
|
// not implemented
|
||||||
SubView (const SubView&);
|
SubView (const SubView&);
|
||||||
SubView& operator= (SubView&);
|
SubView& operator= (SubView&);
|
||||||
|
protected:
|
||||||
|
void setUniversalId(const CSMWorld::UniversalId& id);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -40,9 +42,12 @@ namespace CSVDoc
|
||||||
virtual void setStatusBar (bool show);
|
virtual void setStatusBar (bool show);
|
||||||
///< Default implementation: ignored
|
///< Default implementation: ignored
|
||||||
|
|
||||||
|
virtual void useHint (const std::string& hint);
|
||||||
|
///< Default implementation: ignored
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void focusId (const CSMWorld::UniversalId& universalId);
|
void focusId (const CSMWorld::UniversalId& universalId, const std::string& hint);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,10 +115,6 @@ void CSVDoc::View::setupWorldMenu()
|
||||||
|
|
||||||
world->addSeparator(); // items that don't represent single record lists follow here
|
world->addSeparator(); // items that don't represent single record lists follow here
|
||||||
|
|
||||||
QAction *scene = new QAction (tr ("Scene"), this);
|
|
||||||
connect (scene, SIGNAL (triggered()), this, SLOT (addSceneSubView()));
|
|
||||||
world->addAction (scene);
|
|
||||||
|
|
||||||
QAction *regionMap = new QAction (tr ("Region Map"), this);
|
QAction *regionMap = new QAction (tr ("Region Map"), this);
|
||||||
connect (regionMap, SIGNAL (triggered()), this, SLOT (addRegionMapSubView()));
|
connect (regionMap, SIGNAL (triggered()), this, SLOT (addRegionMapSubView()));
|
||||||
world->addAction (regionMap);
|
world->addAction (regionMap);
|
||||||
|
@ -310,7 +306,7 @@ void CSVDoc::View::updateProgress (int current, int max, int type, int threads)
|
||||||
mOperations->setProgress (current, max, type, threads);
|
mOperations->setProgress (current, max, type, threads);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id)
|
void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::string& hint)
|
||||||
{
|
{
|
||||||
/// \todo add an user setting for limiting the number of sub views per top level view. Automatically open a new top level view if this
|
/// \todo add an user setting for limiting the number of sub views per top level view. Automatically open a new top level view if this
|
||||||
/// number is exceeded
|
/// number is exceeded
|
||||||
|
@ -320,14 +316,25 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id)
|
||||||
|
|
||||||
/// \todo add an user setting to reuse sub views (on a per document basis or on a per top level view basis)
|
/// \todo add an user setting to reuse sub views (on a per document basis or on a per top level view basis)
|
||||||
|
|
||||||
SubView *view = mSubViewFactory.makeSubView (id, *mDocument);
|
const std::vector<CSMWorld::UniversalId::Type> referenceables(CSMWorld::UniversalId::listReferenceableTypes());
|
||||||
|
SubView *view = NULL;
|
||||||
|
if(std::find(referenceables.begin(), referenceables.end(), id.getType()) != referenceables.end())
|
||||||
|
{
|
||||||
|
view = mSubViewFactory.makeSubView (CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Referenceable, id.getId()), *mDocument);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
view = mSubViewFactory.makeSubView (id, *mDocument);
|
||||||
|
}
|
||||||
|
assert(view);
|
||||||
|
if (!hint.empty())
|
||||||
|
view->useHint (hint);
|
||||||
|
|
||||||
view->setStatusBar (mShowStatusBar->isChecked());
|
view->setStatusBar (mShowStatusBar->isChecked());
|
||||||
|
|
||||||
mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view);
|
mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view);
|
||||||
|
|
||||||
connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&)), this,
|
connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&, const std::string&)), this,
|
||||||
SLOT (addSubView (const CSMWorld::UniversalId&)));
|
SLOT (addSubView (const CSMWorld::UniversalId&, const std::string&)));
|
||||||
|
|
||||||
CSMSettings::UserSettings::instance().updateSettings("Display Format");
|
CSMSettings::UserSettings::instance().updateSettings("Display Format");
|
||||||
|
|
||||||
|
@ -429,11 +436,6 @@ void CSVDoc::View::addFiltersSubView()
|
||||||
addSubView (CSMWorld::UniversalId::Type_Filters);
|
addSubView (CSMWorld::UniversalId::Type_Filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVDoc::View::addSceneSubView()
|
|
||||||
{
|
|
||||||
addSubView (CSMWorld::UniversalId::Type_Scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSVDoc::View::addTopicsSubView()
|
void CSVDoc::View::addTopicsSubView()
|
||||||
{
|
{
|
||||||
addSubView (CSMWorld::UniversalId::Type_Topics);
|
addSubView (CSMWorld::UniversalId::Type_Topics);
|
||||||
|
|
|
@ -120,7 +120,9 @@ namespace CSVDoc
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void addSubView (const CSMWorld::UniversalId& id);
|
void addSubView (const CSMWorld::UniversalId& id, const std::string& hint = "");
|
||||||
|
///< \param hint Suggested view point (e.g. coordinates in a 3D scene or a line number
|
||||||
|
/// in a script).
|
||||||
|
|
||||||
void abortOperation (int type);
|
void abortOperation (int type);
|
||||||
|
|
||||||
|
@ -166,8 +168,6 @@ namespace CSVDoc
|
||||||
|
|
||||||
void addFiltersSubView();
|
void addFiltersSubView();
|
||||||
|
|
||||||
void addSceneSubView();
|
|
||||||
|
|
||||||
void addTopicsSubView();
|
void addTopicsSubView();
|
||||||
|
|
||||||
void addJournalsSubView();
|
void addJournalsSubView();
|
||||||
|
|
|
@ -120,7 +120,7 @@ void CSVFilter::EditWidget::createFilterRequest (std::vector< std::pair< std::st
|
||||||
{
|
{
|
||||||
ss<<"!or(";
|
ss<<"!or(";
|
||||||
} else {
|
} else {
|
||||||
ss << orAnd << oldContent.toStdString() << ',';
|
ss << orAnd << oldContent.toUtf8().constData() << ',';
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < count; ++i)
|
for (unsigned i = 0; i < count; ++i)
|
||||||
|
@ -137,7 +137,7 @@ void CSVFilter::EditWidget::createFilterRequest (std::vector< std::pair< std::st
|
||||||
} else {
|
} else {
|
||||||
if (!replaceMode)
|
if (!replaceMode)
|
||||||
{
|
{
|
||||||
ss << orAnd << oldContent.toStdString() <<',';
|
ss << orAnd << oldContent.toUtf8().constData() <<',';
|
||||||
} else {
|
} else {
|
||||||
ss<<'!';
|
ss<<'!';
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QPalette>
|
#include <QPalette>
|
||||||
#include <qt4/QtCore/qnamespace.h>
|
#include <QtCore/qnamespace.h>
|
||||||
|
|
||||||
#include "../../model/filter/parser.hpp"
|
#include "../../model/filter/parser.hpp"
|
||||||
#include "../../model/filter/node.hpp"
|
#include "../../model/filter/node.hpp"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <qt4/QtCore/qnamespace.h>
|
#include <QtCore/qnamespace.h>
|
||||||
|
|
||||||
#include "../../model/filter/node.hpp"
|
#include "../../model/filter/node.hpp"
|
||||||
#include "../../model/world/universalid.hpp"
|
#include "../../model/world/universalid.hpp"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <qt4/QtCore/qnamespace.h>
|
#include <QtCore/qnamespace.h>
|
||||||
|
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
|
|
4
apps/opencs/view/render/lighting.cpp
Normal file
4
apps/opencs/view/render/lighting.cpp
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
#include "lighting.hpp"
|
||||||
|
|
||||||
|
CSVRender::Lighting::~Lighting() {}
|
27
apps/opencs/view/render/lighting.hpp
Normal file
27
apps/opencs/view/render/lighting.hpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef OPENCS_VIEW_LIGHTING_H
|
||||||
|
#define OPENCS_VIEW_LIGHTING_H
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class SceneManager;
|
||||||
|
class ColourValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class Lighting
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~Lighting();
|
||||||
|
|
||||||
|
virtual void activate (Ogre::SceneManager *sceneManager,
|
||||||
|
const Ogre::ColourValue *defaultAmbient = 0) = 0;
|
||||||
|
|
||||||
|
virtual void deactivate() = 0;
|
||||||
|
|
||||||
|
virtual void setDefaultAmbient (const Ogre::ColourValue& colour) = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
30
apps/opencs/view/render/lightingbright.cpp
Normal file
30
apps/opencs/view/render/lightingbright.cpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
|
||||||
|
#include "lightingbright.hpp"
|
||||||
|
|
||||||
|
#include <OgreSceneManager.h>
|
||||||
|
|
||||||
|
CSVRender::LightingBright::LightingBright() : mSceneManager (0), mLight (0) {}
|
||||||
|
|
||||||
|
void CSVRender::LightingBright::activate (Ogre::SceneManager *sceneManager,
|
||||||
|
const Ogre::ColourValue *defaultAmbient)
|
||||||
|
{
|
||||||
|
mSceneManager = sceneManager;
|
||||||
|
|
||||||
|
mSceneManager->setAmbientLight (Ogre::ColourValue (1.0, 1.0, 1.0, 1));
|
||||||
|
|
||||||
|
mLight = mSceneManager->createLight();
|
||||||
|
mLight->setType (Ogre::Light::LT_DIRECTIONAL);
|
||||||
|
mLight->setDirection (Ogre::Vector3 (0, 0, -1));
|
||||||
|
mLight->setDiffuseColour (Ogre::ColourValue (1.0, 1.0, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::LightingBright::deactivate()
|
||||||
|
{
|
||||||
|
if (mLight)
|
||||||
|
{
|
||||||
|
mSceneManager->destroyLight (mLight);
|
||||||
|
mLight = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::LightingBright::setDefaultAmbient (const Ogre::ColourValue& colour) {}
|
31
apps/opencs/view/render/lightingbright.hpp
Normal file
31
apps/opencs/view/render/lightingbright.hpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef OPENCS_VIEW_LIGHTING_BRIGHT_H
|
||||||
|
#define OPENCS_VIEW_LIGHTING_BRIGHT_H
|
||||||
|
|
||||||
|
#include "lighting.hpp"
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class Light;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class LightingBright : public Lighting
|
||||||
|
{
|
||||||
|
Ogre::SceneManager *mSceneManager;
|
||||||
|
Ogre::Light *mLight;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
LightingBright();
|
||||||
|
|
||||||
|
virtual void activate (Ogre::SceneManager *sceneManager,
|
||||||
|
const Ogre::ColourValue *defaultAmbient = 0);
|
||||||
|
|
||||||
|
virtual void deactivate();
|
||||||
|
|
||||||
|
virtual void setDefaultAmbient (const Ogre::ColourValue& colour);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
36
apps/opencs/view/render/lightingday.cpp
Normal file
36
apps/opencs/view/render/lightingday.cpp
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
|
||||||
|
#include "lightingday.hpp"
|
||||||
|
|
||||||
|
#include <OgreSceneManager.h>
|
||||||
|
|
||||||
|
CSVRender::LightingDay::LightingDay() : mSceneManager (0), mLight (0) {}
|
||||||
|
|
||||||
|
void CSVRender::LightingDay::activate (Ogre::SceneManager *sceneManager,
|
||||||
|
const Ogre::ColourValue *defaultAmbient)
|
||||||
|
{
|
||||||
|
mSceneManager = sceneManager;
|
||||||
|
|
||||||
|
if (defaultAmbient)
|
||||||
|
mSceneManager->setAmbientLight (*defaultAmbient);
|
||||||
|
else
|
||||||
|
mSceneManager->setAmbientLight (Ogre::ColourValue (0.7, 0.7, 0.7, 1));
|
||||||
|
|
||||||
|
mLight = mSceneManager->createLight();
|
||||||
|
mLight->setType (Ogre::Light::LT_DIRECTIONAL);
|
||||||
|
mLight->setDirection (Ogre::Vector3 (0, 0, -1));
|
||||||
|
mLight->setDiffuseColour (Ogre::ColourValue (1, 1, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::LightingDay::deactivate()
|
||||||
|
{
|
||||||
|
if (mLight)
|
||||||
|
{
|
||||||
|
mSceneManager->destroyLight (mLight);
|
||||||
|
mLight = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::LightingDay::setDefaultAmbient (const Ogre::ColourValue& colour)
|
||||||
|
{
|
||||||
|
mSceneManager->setAmbientLight (colour);
|
||||||
|
}
|
31
apps/opencs/view/render/lightingday.hpp
Normal file
31
apps/opencs/view/render/lightingday.hpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef OPENCS_VIEW_LIGHTING_DAY_H
|
||||||
|
#define OPENCS_VIEW_LIGHTING_DAY_H
|
||||||
|
|
||||||
|
#include "lighting.hpp"
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class Light;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class LightingDay : public Lighting
|
||||||
|
{
|
||||||
|
Ogre::SceneManager *mSceneManager;
|
||||||
|
Ogre::Light *mLight;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
LightingDay();
|
||||||
|
|
||||||
|
virtual void activate (Ogre::SceneManager *sceneManager,
|
||||||
|
const Ogre::ColourValue *defaultAmbient = 0);
|
||||||
|
|
||||||
|
virtual void deactivate();
|
||||||
|
|
||||||
|
virtual void setDefaultAmbient (const Ogre::ColourValue& colour);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
36
apps/opencs/view/render/lightingnight.cpp
Normal file
36
apps/opencs/view/render/lightingnight.cpp
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
|
||||||
|
#include "lightingnight.hpp"
|
||||||
|
|
||||||
|
#include <OgreSceneManager.h>
|
||||||
|
|
||||||
|
CSVRender::LightingNight::LightingNight() : mSceneManager (0), mLight (0) {}
|
||||||
|
|
||||||
|
void CSVRender::LightingNight::activate (Ogre::SceneManager *sceneManager,
|
||||||
|
const Ogre::ColourValue *defaultAmbient)
|
||||||
|
{
|
||||||
|
mSceneManager = sceneManager;
|
||||||
|
|
||||||
|
if (defaultAmbient)
|
||||||
|
mSceneManager->setAmbientLight (*defaultAmbient);
|
||||||
|
else
|
||||||
|
mSceneManager->setAmbientLight (Ogre::ColourValue (0.2, 0.2, 0.2, 1));
|
||||||
|
|
||||||
|
mLight = mSceneManager->createLight();
|
||||||
|
mLight->setType (Ogre::Light::LT_DIRECTIONAL);
|
||||||
|
mLight->setDirection (Ogre::Vector3 (0, 0, -1));
|
||||||
|
mLight->setDiffuseColour (Ogre::ColourValue (0.2, 0.2, 0.2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::LightingNight::deactivate()
|
||||||
|
{
|
||||||
|
if (mLight)
|
||||||
|
{
|
||||||
|
mSceneManager->destroyLight (mLight);
|
||||||
|
mLight = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::LightingNight::setDefaultAmbient (const Ogre::ColourValue& colour)
|
||||||
|
{
|
||||||
|
mSceneManager->setAmbientLight (colour);
|
||||||
|
}
|
31
apps/opencs/view/render/lightingnight.hpp
Normal file
31
apps/opencs/view/render/lightingnight.hpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef OPENCS_VIEW_LIGHTING_NIGHT_H
|
||||||
|
#define OPENCS_VIEW_LIGHTING_NIGHT_H
|
||||||
|
|
||||||
|
#include "lighting.hpp"
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class Light;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class LightingNight : public Lighting
|
||||||
|
{
|
||||||
|
Ogre::SceneManager *mSceneManager;
|
||||||
|
Ogre::Light *mLight;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
LightingNight();
|
||||||
|
|
||||||
|
virtual void activate (Ogre::SceneManager *sceneManager,
|
||||||
|
const Ogre::ColourValue *defaultAmbient = 0);
|
||||||
|
|
||||||
|
virtual void deactivate();
|
||||||
|
|
||||||
|
virtual void setDefaultAmbient (const Ogre::ColourValue& colour);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
19
apps/opencs/view/render/navigation.cpp
Normal file
19
apps/opencs/view/render/navigation.cpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
|
||||||
|
#include "navigation.hpp"
|
||||||
|
|
||||||
|
float CSVRender::Navigation::getFactor (bool mouse) const
|
||||||
|
{
|
||||||
|
float factor = mFastModeFactor;
|
||||||
|
|
||||||
|
if (mouse)
|
||||||
|
factor /= 2; /// \todo make this configurable
|
||||||
|
|
||||||
|
return factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::Navigation::~Navigation() {}
|
||||||
|
|
||||||
|
void CSVRender::Navigation::setFastModeFactor (float factor)
|
||||||
|
{
|
||||||
|
mFastModeFactor = factor;
|
||||||
|
}
|
46
apps/opencs/view/render/navigation.hpp
Normal file
46
apps/opencs/view/render/navigation.hpp
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef OPENCS_VIEW_NAVIGATION_H
|
||||||
|
#define OPENCS_VIEW_NAVIGATION_H
|
||||||
|
|
||||||
|
class QPoint;
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class Camera;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class Navigation
|
||||||
|
{
|
||||||
|
float mFastModeFactor;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
float getFactor (bool mouse) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~Navigation();
|
||||||
|
|
||||||
|
void setFastModeFactor (float factor);
|
||||||
|
///< Set currently applying fast mode factor.
|
||||||
|
|
||||||
|
virtual bool activate (Ogre::Camera *camera) = 0;
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool wheelMoved (int delta) = 0;
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool mouseMoved (const QPoint& delta, int mode) = 0;
|
||||||
|
///< \param mode: 0: default mouse key, 1: default mouse key and modifier key 1
|
||||||
|
/// \return Update required?
|
||||||
|
|
||||||
|
virtual bool handleMovementKeys (int vertical, int horizontal) = 0;
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool handleRollKeys (int delta) = 0;
|
||||||
|
///< \return Update required?
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
85
apps/opencs/view/render/navigation1st.cpp
Normal file
85
apps/opencs/view/render/navigation1st.cpp
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
|
||||||
|
#include "navigation1st.hpp"
|
||||||
|
|
||||||
|
#include <OgreCamera.h>
|
||||||
|
|
||||||
|
#include <QPoint>
|
||||||
|
|
||||||
|
CSVRender::Navigation1st::Navigation1st() : mCamera (0) {}
|
||||||
|
|
||||||
|
bool CSVRender::Navigation1st::activate (Ogre::Camera *camera)
|
||||||
|
{
|
||||||
|
mCamera = camera;
|
||||||
|
mCamera->setFixedYawAxis (true, Ogre::Vector3::UNIT_Z);
|
||||||
|
|
||||||
|
Ogre::Radian pitch = mCamera->getOrientation().getPitch();
|
||||||
|
|
||||||
|
Ogre::Radian limit (Ogre::Math::PI/2-0.5);
|
||||||
|
|
||||||
|
if (pitch>limit)
|
||||||
|
mCamera->pitch (-(pitch-limit));
|
||||||
|
else if (pitch<-limit)
|
||||||
|
mCamera->pitch (pitch-limit);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Navigation1st::wheelMoved (int delta)
|
||||||
|
{
|
||||||
|
mCamera->move (getFactor (true) * mCamera->getDirection() * delta);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Navigation1st::mouseMoved (const QPoint& delta, int mode)
|
||||||
|
{
|
||||||
|
if (mode==0)
|
||||||
|
{
|
||||||
|
// turn camera
|
||||||
|
if (delta.x())
|
||||||
|
mCamera->yaw (Ogre::Degree (getFactor (true) * delta.x()));
|
||||||
|
|
||||||
|
if (delta.y())
|
||||||
|
{
|
||||||
|
Ogre::Radian oldPitch = mCamera->getOrientation().getPitch();
|
||||||
|
float deltaPitch = getFactor (true) * delta.y();
|
||||||
|
Ogre::Radian newPitch = oldPitch + Ogre::Degree (deltaPitch);
|
||||||
|
|
||||||
|
Ogre::Radian limit (Ogre::Math::PI/2-0.5);
|
||||||
|
|
||||||
|
if ((deltaPitch>0 && newPitch<limit) || (deltaPitch<0 && newPitch>-limit))
|
||||||
|
mCamera->pitch (Ogre::Degree (deltaPitch));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (mode==1)
|
||||||
|
{
|
||||||
|
// pan camera
|
||||||
|
if (delta.x())
|
||||||
|
mCamera->move (getFactor (true) * mCamera->getDerivedRight() * delta.x());
|
||||||
|
|
||||||
|
if (delta.y())
|
||||||
|
mCamera->move (getFactor (true) * -mCamera->getDerivedUp() * delta.y());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Navigation1st::handleMovementKeys (int vertical, int horizontal)
|
||||||
|
{
|
||||||
|
if (vertical)
|
||||||
|
mCamera->move (getFactor (false) * mCamera->getDirection() * vertical);
|
||||||
|
|
||||||
|
if (horizontal)
|
||||||
|
mCamera->move (getFactor (true) * mCamera->getDerivedRight() * horizontal);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Navigation1st::handleRollKeys (int delta)
|
||||||
|
{
|
||||||
|
// we don't roll this way in 1st person mode
|
||||||
|
return false;
|
||||||
|
}
|
35
apps/opencs/view/render/navigation1st.hpp
Normal file
35
apps/opencs/view/render/navigation1st.hpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef OPENCS_VIEW_NAVIGATION1ST_H
|
||||||
|
#define OPENCS_VIEW_NAVIGATION1ST_H
|
||||||
|
|
||||||
|
#include "navigation.hpp"
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
/// \brief First person-like camera controls
|
||||||
|
class Navigation1st : public Navigation
|
||||||
|
{
|
||||||
|
Ogre::Camera *mCamera;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Navigation1st();
|
||||||
|
|
||||||
|
virtual bool activate (Ogre::Camera *camera);
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool wheelMoved (int delta);
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool mouseMoved (const QPoint& delta, int mode);
|
||||||
|
///< \param mode: 0: default mouse key, 1: default mouse key and modifier key 1
|
||||||
|
/// \return Update required?
|
||||||
|
|
||||||
|
virtual bool handleMovementKeys (int vertical, int horizontal);
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool handleRollKeys (int delta);
|
||||||
|
///< \return Update required?
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
66
apps/opencs/view/render/navigationfree.cpp
Normal file
66
apps/opencs/view/render/navigationfree.cpp
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
|
||||||
|
#include "navigationfree.hpp"
|
||||||
|
|
||||||
|
#include <OgreCamera.h>
|
||||||
|
|
||||||
|
#include <QPoint>
|
||||||
|
|
||||||
|
CSVRender::NavigationFree::NavigationFree() : mCamera (0) {}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationFree::activate (Ogre::Camera *camera)
|
||||||
|
{
|
||||||
|
mCamera = camera;
|
||||||
|
mCamera->setFixedYawAxis (false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationFree::wheelMoved (int delta)
|
||||||
|
{
|
||||||
|
mCamera->move (getFactor (true) * mCamera->getDirection() * delta);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationFree::mouseMoved (const QPoint& delta, int mode)
|
||||||
|
{
|
||||||
|
if (mode==0)
|
||||||
|
{
|
||||||
|
// turn camera
|
||||||
|
if (delta.x())
|
||||||
|
mCamera->yaw (Ogre::Degree (getFactor (true) * delta.x()));
|
||||||
|
|
||||||
|
if (delta.y())
|
||||||
|
mCamera->pitch (Ogre::Degree (getFactor (true) * delta.y()));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (mode==1)
|
||||||
|
{
|
||||||
|
// pan camera
|
||||||
|
if (delta.x())
|
||||||
|
mCamera->move (getFactor (true) * mCamera->getDerivedRight() * delta.x());
|
||||||
|
|
||||||
|
if (delta.y())
|
||||||
|
mCamera->move (getFactor (true) * -mCamera->getDerivedUp() * delta.y());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationFree::handleMovementKeys (int vertical, int horizontal)
|
||||||
|
{
|
||||||
|
if (vertical)
|
||||||
|
mCamera->move (getFactor (false) * mCamera->getDerivedUp() * vertical);
|
||||||
|
|
||||||
|
if (horizontal)
|
||||||
|
mCamera->move (getFactor (true) * mCamera->getDerivedRight() * horizontal);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationFree::handleRollKeys (int delta)
|
||||||
|
{
|
||||||
|
mCamera->roll (Ogre::Degree (getFactor (false) * delta));
|
||||||
|
return true;
|
||||||
|
}
|
35
apps/opencs/view/render/navigationfree.hpp
Normal file
35
apps/opencs/view/render/navigationfree.hpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef OPENCS_VIEW_NAVIGATIONFREE_H
|
||||||
|
#define OPENCS_VIEW_NAVIGATIONFREE_H
|
||||||
|
|
||||||
|
#include "navigation.hpp"
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
/// \brief Free camera controls
|
||||||
|
class NavigationFree : public Navigation
|
||||||
|
{
|
||||||
|
Ogre::Camera *mCamera;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
NavigationFree();
|
||||||
|
|
||||||
|
virtual bool activate (Ogre::Camera *camera);
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool wheelMoved (int delta);
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool mouseMoved (const QPoint& delta, int mode);
|
||||||
|
///< \param mode: 0: default mouse key, 1: default mouse key and modifier key 1
|
||||||
|
/// \return Update required?
|
||||||
|
|
||||||
|
virtual bool handleMovementKeys (int vertical, int horizontal);
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool handleRollKeys (int delta);
|
||||||
|
///< \return Update required?
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
100
apps/opencs/view/render/navigationorbit.cpp
Normal file
100
apps/opencs/view/render/navigationorbit.cpp
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
|
||||||
|
#include "navigationorbit.hpp"
|
||||||
|
|
||||||
|
#include <OgreCamera.h>
|
||||||
|
|
||||||
|
#include <QPoint>
|
||||||
|
|
||||||
|
void CSVRender::NavigationOrbit::rotateCamera (const Ogre::Vector3& diff)
|
||||||
|
{
|
||||||
|
Ogre::Vector3 pos = mCamera->getPosition();
|
||||||
|
|
||||||
|
float distance = (pos-mCentre).length();
|
||||||
|
|
||||||
|
Ogre::Vector3 direction = (pos+diff)-mCentre;
|
||||||
|
direction.normalise();
|
||||||
|
|
||||||
|
mCamera->setPosition (mCentre + direction*distance);
|
||||||
|
mCamera->lookAt (mCentre);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::NavigationOrbit::NavigationOrbit() : mCamera (0), mCentre (0, 0, 0), mDistance (100)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationOrbit::activate (Ogre::Camera *camera)
|
||||||
|
{
|
||||||
|
mCamera = camera;
|
||||||
|
mCamera->setFixedYawAxis (false);
|
||||||
|
|
||||||
|
if ((mCamera->getPosition()-mCentre).length()<mDistance)
|
||||||
|
{
|
||||||
|
// move camera out of the centre area
|
||||||
|
Ogre::Vector3 direction = mCentre-mCamera->getPosition();
|
||||||
|
direction.normalise();
|
||||||
|
|
||||||
|
if (direction.length()==0)
|
||||||
|
direction = Ogre::Vector3 (1, 0, 0);
|
||||||
|
|
||||||
|
mCamera->setPosition (mCentre - direction * mDistance);
|
||||||
|
}
|
||||||
|
|
||||||
|
mCamera->lookAt (mCentre);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationOrbit::wheelMoved (int delta)
|
||||||
|
{
|
||||||
|
Ogre::Vector3 diff = getFactor (true) * mCamera->getDirection() * delta;
|
||||||
|
|
||||||
|
Ogre::Vector3 pos = mCamera->getPosition();
|
||||||
|
|
||||||
|
if (delta>0 && diff.length()>=(pos-mCentre).length()-mDistance)
|
||||||
|
{
|
||||||
|
pos = mCentre-(mCamera->getDirection() * mDistance);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pos += diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
mCamera->setPosition (pos);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationOrbit::mouseMoved (const QPoint& delta, int mode)
|
||||||
|
{
|
||||||
|
Ogre::Vector3 diff =
|
||||||
|
getFactor (true) * -mCamera->getDerivedRight() * delta.x()
|
||||||
|
+ getFactor (true) * mCamera->getDerivedUp() * delta.y();
|
||||||
|
|
||||||
|
if (mode==0)
|
||||||
|
{
|
||||||
|
rotateCamera (diff);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (mode==1)
|
||||||
|
{
|
||||||
|
mCamera->move (diff);
|
||||||
|
mCentre += diff;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationOrbit::handleMovementKeys (int vertical, int horizontal)
|
||||||
|
{
|
||||||
|
rotateCamera (
|
||||||
|
- getFactor (false) * -mCamera->getDerivedRight() * horizontal
|
||||||
|
+ getFactor (false) * mCamera->getDerivedUp() * vertical);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationOrbit::handleRollKeys (int delta)
|
||||||
|
{
|
||||||
|
mCamera->roll (Ogre::Degree (getFactor (false) * delta));
|
||||||
|
return true;
|
||||||
|
}
|
42
apps/opencs/view/render/navigationorbit.hpp
Normal file
42
apps/opencs/view/render/navigationorbit.hpp
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#ifndef OPENCS_VIEW_NAVIGATIONORBIT_H
|
||||||
|
#define OPENCS_VIEW_NAVIGATIONORBIT_H
|
||||||
|
|
||||||
|
#include "navigation.hpp"
|
||||||
|
|
||||||
|
#include <OgreVector3.h>
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
/// \brief Orbiting camera controls
|
||||||
|
class NavigationOrbit : public Navigation
|
||||||
|
{
|
||||||
|
Ogre::Camera *mCamera;
|
||||||
|
Ogre::Vector3 mCentre;
|
||||||
|
int mDistance;
|
||||||
|
|
||||||
|
void rotateCamera (const Ogre::Vector3& diff);
|
||||||
|
///< Rotate camera around centre.
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
NavigationOrbit();
|
||||||
|
|
||||||
|
virtual bool activate (Ogre::Camera *camera);
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool wheelMoved (int delta);
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool mouseMoved (const QPoint& delta, int mode);
|
||||||
|
///< \param mode: 0: default mouse key, 1: default mouse key and modifier key 1
|
||||||
|
/// \return Update required?
|
||||||
|
|
||||||
|
virtual bool handleMovementKeys (int vertical, int horizontal);
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool handleRollKeys (int delta);
|
||||||
|
///< \return Update required?
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
6
apps/opencs/view/render/pagedworldspacewidget.cpp
Normal file
6
apps/opencs/view/render/pagedworldspacewidget.cpp
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
#include "pagedworldspacewidget.hpp"
|
||||||
|
|
||||||
|
CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget *parent)
|
||||||
|
: WorldspaceWidget (parent)
|
||||||
|
{}
|
18
apps/opencs/view/render/pagedworldspacewidget.hpp
Normal file
18
apps/opencs/view/render/pagedworldspacewidget.hpp
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef OPENCS_VIEW_PAGEDWORLDSPACEWIDGET_H
|
||||||
|
#define OPENCS_VIEW_PAGEDWORLDSPACEWIDGET_H
|
||||||
|
|
||||||
|
#include "worldspacewidget.hpp"
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class PagedWorldspaceWidget : public WorldspaceWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
PagedWorldspaceWidget (QWidget *parent);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
201
apps/opencs/view/render/previewwidget.cpp
Normal file
201
apps/opencs/view/render/previewwidget.cpp
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
|
||||||
|
#include "previewwidget.hpp"
|
||||||
|
|
||||||
|
#include <OgreSceneManager.h>
|
||||||
|
#include <OgreSceneNode.h>
|
||||||
|
|
||||||
|
#include "../../model/world/data.hpp"
|
||||||
|
#include "../../model/world/idtable.hpp"
|
||||||
|
|
||||||
|
void CSVRender::PreviewWidget::setup()
|
||||||
|
{
|
||||||
|
setNavigation (&mOrbit);
|
||||||
|
|
||||||
|
mNode = getSceneManager()->getRootSceneNode()->createChildSceneNode();
|
||||||
|
mNode->setPosition (Ogre::Vector3 (0, 0, 0));
|
||||||
|
|
||||||
|
setModel();
|
||||||
|
|
||||||
|
QAbstractItemModel *referenceables =
|
||||||
|
mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables);
|
||||||
|
|
||||||
|
connect (referenceables, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||||
|
this, SLOT (ReferenceableDataChanged (const QModelIndex&, const QModelIndex&)));
|
||||||
|
connect (referenceables, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||||
|
this, SLOT (ReferenceableAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PreviewWidget::setModel()
|
||||||
|
{
|
||||||
|
if (mNode)
|
||||||
|
{
|
||||||
|
mObject.setNull();
|
||||||
|
|
||||||
|
if (mReferenceableId.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int column =
|
||||||
|
mData.getReferenceables().findColumnIndex (CSMWorld::Columns::ColumnId_Model);
|
||||||
|
|
||||||
|
int row = mData.getReferenceables().searchId (mReferenceableId);
|
||||||
|
|
||||||
|
if (row==-1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QVariant value = mData.getReferenceables().getData (row, column);
|
||||||
|
|
||||||
|
if (!value.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string model = value.toString().toUtf8().constData();
|
||||||
|
|
||||||
|
if (model.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
mObject = NifOgre::Loader::createObjects (mNode, "Meshes\\" + model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PreviewWidget::adjust()
|
||||||
|
{
|
||||||
|
if (mNode)
|
||||||
|
{
|
||||||
|
int row = mData.getReferences().getIndex (mReferenceId);
|
||||||
|
|
||||||
|
float scale = mData.getReferences().getData (row, mData.getReferences().
|
||||||
|
findColumnIndex (CSMWorld::Columns::ColumnId_Scale)).toFloat();
|
||||||
|
float rotX = mData.getReferences().getData (row, mData.getReferences().
|
||||||
|
findColumnIndex (CSMWorld::Columns::ColumnId_PositionXRot)).toFloat();
|
||||||
|
float rotY = mData.getReferences().getData (row, mData.getReferences().
|
||||||
|
findColumnIndex (CSMWorld::Columns::ColumnId_PositionYRot)).toFloat();
|
||||||
|
float rotZ = mData.getReferences().getData (row, mData.getReferences().
|
||||||
|
findColumnIndex (CSMWorld::Columns::ColumnId_PositionZRot)).toFloat();
|
||||||
|
|
||||||
|
mNode->setScale (scale, scale, scale);
|
||||||
|
|
||||||
|
Ogre::Quaternion xr (Ogre::Radian(-rotX), Ogre::Vector3::UNIT_X);
|
||||||
|
|
||||||
|
Ogre::Quaternion yr (Ogre::Radian(-rotY), Ogre::Vector3::UNIT_Y);
|
||||||
|
|
||||||
|
Ogre::Quaternion zr (Ogre::Radian(-rotZ), Ogre::Vector3::UNIT_Z);
|
||||||
|
|
||||||
|
mNode->setOrientation (xr*yr*zr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data,
|
||||||
|
const std::string& referenceableId, QWidget *parent)
|
||||||
|
: SceneWidget (parent), mData (data), mNode (0), mReferenceableId (referenceableId)
|
||||||
|
{
|
||||||
|
setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data,
|
||||||
|
const std::string& referenceableId, const std::string& referenceId, QWidget *parent)
|
||||||
|
: SceneWidget (parent), mData (data), mReferenceableId (referenceableId),
|
||||||
|
mReferenceId (referenceId)
|
||||||
|
{
|
||||||
|
setup();
|
||||||
|
|
||||||
|
adjust();
|
||||||
|
|
||||||
|
QAbstractItemModel *references =
|
||||||
|
mData.getTableModel (CSMWorld::UniversalId::Type_References);
|
||||||
|
|
||||||
|
connect (references, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||||
|
this, SLOT (ReferenceDataChanged (const QModelIndex&, const QModelIndex&)));
|
||||||
|
connect (references, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||||
|
this, SLOT (ReferenceAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PreviewWidget::ReferenceableDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight)
|
||||||
|
{
|
||||||
|
if (mReferenceableId.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
CSMWorld::IdTable& referenceables = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
|
*mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables));
|
||||||
|
|
||||||
|
QModelIndex index = referenceables.getModelIndex (mReferenceableId, 0);
|
||||||
|
|
||||||
|
if (index.row()>=topLeft.row() && index.row()<=bottomRight.row())
|
||||||
|
{
|
||||||
|
/// \todo possible optimisation; check columns and only update if relevant columns have
|
||||||
|
/// changed
|
||||||
|
setModel();
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PreviewWidget::ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start,
|
||||||
|
int end)
|
||||||
|
{
|
||||||
|
if (mReferenceableId.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
CSMWorld::IdTable& referenceables = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
|
*mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables));
|
||||||
|
|
||||||
|
QModelIndex index = referenceables.getModelIndex (mReferenceableId, 0);
|
||||||
|
|
||||||
|
if (index.row()>=start && index.row()<=end)
|
||||||
|
{
|
||||||
|
if (mReferenceId.empty())
|
||||||
|
{
|
||||||
|
// this is a preview for a referenceble
|
||||||
|
emit closeRequest();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// this is a preview for a reference
|
||||||
|
mObject.setNull();
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PreviewWidget::ReferenceDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight)
|
||||||
|
{
|
||||||
|
if (mReferenceId.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
|
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||||
|
|
||||||
|
int columnIndex = references.findColumnIndex (CSMWorld::Columns::ColumnId_ReferenceableId);
|
||||||
|
|
||||||
|
QModelIndex index = references.getModelIndex (mReferenceId, columnIndex);
|
||||||
|
|
||||||
|
if (index.row()>=topLeft.row() && index.row()<=bottomRight.row())
|
||||||
|
{
|
||||||
|
/// \todo possible optimisation; check columns and only update if relevant columns have
|
||||||
|
/// changed
|
||||||
|
adjust();
|
||||||
|
|
||||||
|
if (index.column()>=topLeft.column() && index.column()<=bottomRight.row())
|
||||||
|
{
|
||||||
|
mReferenceableId = references.data (index).toString().toUtf8().constData();
|
||||||
|
emit referenceableIdChanged (mReferenceableId);
|
||||||
|
setModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PreviewWidget::ReferenceAboutToBeRemoved (const QModelIndex& parent, int start,
|
||||||
|
int end)
|
||||||
|
{
|
||||||
|
if (mReferenceId.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
|
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||||
|
|
||||||
|
QModelIndex index = references.getModelIndex (mReferenceId, 0);
|
||||||
|
|
||||||
|
if (index.row()>=start && index.row()<=end)
|
||||||
|
emit closeRequest();
|
||||||
|
}
|
64
apps/opencs/view/render/previewwidget.hpp
Normal file
64
apps/opencs/view/render/previewwidget.hpp
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
#ifndef OPENCS_VIEW_PREVIEWWIDGET_H
|
||||||
|
#define OPENCS_VIEW_PREVIEWWIDGET_H
|
||||||
|
|
||||||
|
#include <components/nifogre/ogrenifloader.hpp>
|
||||||
|
|
||||||
|
#include "scenewidget.hpp"
|
||||||
|
|
||||||
|
#include "navigationorbit.hpp"
|
||||||
|
|
||||||
|
class QModelIndex;
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class PreviewWidget : public SceneWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
CSMWorld::Data& mData;
|
||||||
|
CSVRender::NavigationOrbit mOrbit;
|
||||||
|
NifOgre::ObjectScenePtr mObject;
|
||||||
|
Ogre::SceneNode *mNode;
|
||||||
|
std::string mReferenceId;
|
||||||
|
std::string mReferenceableId;
|
||||||
|
|
||||||
|
void setup();
|
||||||
|
|
||||||
|
void setModel();
|
||||||
|
|
||||||
|
void adjust();
|
||||||
|
///< Adjust referenceable preview according to the reference
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId,
|
||||||
|
QWidget *parent = 0);
|
||||||
|
|
||||||
|
PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId,
|
||||||
|
const std::string& referenceId, QWidget *parent = 0);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void closeRequest();
|
||||||
|
|
||||||
|
void referenceableIdChanged (const std::string& id);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void ReferenceableDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
void ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
|
void ReferenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
void ReferenceAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -2,48 +2,79 @@
|
||||||
|
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
#include <QResizeEvent>
|
#include <QResizeEvent>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
#include <OgreRenderWindow.h>
|
#include <OgreRenderWindow.h>
|
||||||
#include <OgreEntity.h>
|
#include <OgreEntity.h>
|
||||||
#include <OgreCamera.h>
|
#include <OgreCamera.h>
|
||||||
|
#include <OgreSceneNode.h>
|
||||||
|
#include <OgreViewport.h>
|
||||||
|
|
||||||
|
#include "../world/scenetoolmode.hpp"
|
||||||
|
|
||||||
|
#include "navigation.hpp"
|
||||||
|
#include "lighting.hpp"
|
||||||
|
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
{
|
{
|
||||||
|
|
||||||
SceneWidget::SceneWidget(QWidget *parent)
|
SceneWidget::SceneWidget(QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, mWindow(NULL)
|
, mWindow(NULL)
|
||||||
, mCamera(NULL)
|
, mCamera(NULL)
|
||||||
, mSceneMgr(NULL)
|
, mSceneMgr(NULL), mNavigation (0), mLighting (0), mUpdate (false)
|
||||||
|
, mKeyForward (false), mKeyBackward (false), mKeyLeft (false), mKeyRight (false)
|
||||||
|
, mKeyRollLeft (false), mKeyRollRight (false)
|
||||||
|
, mFast (false), mDragging (false), mMod1 (false)
|
||||||
|
, mFastFactor (4) /// \todo make this configurable
|
||||||
|
, mDefaultAmbient (0, 0, 0, 0), mHasDefaultAmbient (false)
|
||||||
{
|
{
|
||||||
setAttribute(Qt::WA_PaintOnScreen);
|
setAttribute(Qt::WA_PaintOnScreen);
|
||||||
setAttribute(Qt::WA_NoSystemBackground);
|
setAttribute(Qt::WA_NoSystemBackground);
|
||||||
|
|
||||||
|
setFocusPolicy (Qt::StrongFocus);
|
||||||
|
|
||||||
mSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC);
|
mSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC);
|
||||||
|
|
||||||
// Throw in a random color just to make sure multiple scenes work
|
mSceneMgr->setAmbientLight (Ogre::ColourValue (0,0,0,1));
|
||||||
Ogre::Real r = Ogre::Math::RangeRandom(0, 1);
|
|
||||||
Ogre::Real g = Ogre::Math::RangeRandom(0, 1);
|
|
||||||
Ogre::Real b = Ogre::Math::RangeRandom(0, 1);
|
|
||||||
mSceneMgr->setAmbientLight(Ogre::ColourValue(r,g,b,1));
|
|
||||||
|
|
||||||
Ogre::Light* l = mSceneMgr->createLight();
|
|
||||||
l->setType (Ogre::Light::LT_DIRECTIONAL);
|
|
||||||
l->setDirection (Ogre::Vector3(-0.4, -0.7, 0.3));
|
|
||||||
l->setDiffuseColour (Ogre::ColourValue(0.7,0.7,0.7));
|
|
||||||
|
|
||||||
mCamera = mSceneMgr->createCamera("foo");
|
mCamera = mSceneMgr->createCamera("foo");
|
||||||
|
|
||||||
Ogre::Entity* ent = mSceneMgr->createEntity("cube", Ogre::SceneManager::PT_CUBE);
|
mCamera->setPosition (300, 0, 0);
|
||||||
ent->setMaterialName("BaseWhite");
|
|
||||||
|
|
||||||
mSceneMgr->getRootSceneNode()->attachObject(ent);
|
|
||||||
|
|
||||||
mCamera->setPosition(300,300,300);
|
|
||||||
mCamera->lookAt (0, 0, 0);
|
mCamera->lookAt (0, 0, 0);
|
||||||
mCamera->setNearClipDistance (0.1);
|
mCamera->setNearClipDistance (0.1);
|
||||||
mCamera->setFarClipDistance(3000);
|
mCamera->setFarClipDistance (30000);
|
||||||
|
mCamera->roll (Ogre::Degree (90));
|
||||||
|
|
||||||
|
setLighting (&mLightingDay);
|
||||||
|
|
||||||
|
QTimer *timer = new QTimer (this);
|
||||||
|
|
||||||
|
connect (timer, SIGNAL (timeout()), this, SLOT (update()));
|
||||||
|
timer->start (20); /// \todo make this configurable
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::SceneToolMode *SceneWidget::makeLightingSelector (CSVWorld::SceneToolbar *parent)
|
||||||
|
{
|
||||||
|
CSVWorld::SceneToolMode *tool = new CSVWorld::SceneToolMode (parent);
|
||||||
|
|
||||||
|
tool->addButton (":door.png", "day"); /// \todo replace icons
|
||||||
|
tool->addButton (":GMST.png", "night");
|
||||||
|
tool->addButton (":Info.png", "bright");
|
||||||
|
|
||||||
|
connect (tool, SIGNAL (modeChanged (const std::string&)),
|
||||||
|
this, SLOT (selectLightingMode (const std::string&)));
|
||||||
|
|
||||||
|
return tool;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneWidget::setDefaultAmbient (const Ogre::ColourValue& colour)
|
||||||
|
{
|
||||||
|
mDefaultAmbient = colour;
|
||||||
|
mHasDefaultAmbient = true;
|
||||||
|
|
||||||
|
if (mLighting)
|
||||||
|
mLighting->setDefaultAmbient (colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneWidget::updateOgreWindow()
|
void SceneWidget::updateOgreWindow()
|
||||||
|
@ -81,7 +112,31 @@ namespace CSVRender
|
||||||
|
|
||||||
SceneWidget::~SceneWidget()
|
SceneWidget::~SceneWidget()
|
||||||
{
|
{
|
||||||
|
if (mWindow)
|
||||||
Ogre::Root::getSingleton().destroyRenderTarget (mWindow);
|
Ogre::Root::getSingleton().destroyRenderTarget (mWindow);
|
||||||
|
|
||||||
|
if (mSceneMgr)
|
||||||
|
Ogre::Root::getSingleton().destroySceneManager (mSceneMgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneWidget::setNavigation (Navigation *navigation)
|
||||||
|
{
|
||||||
|
if ((mNavigation = navigation))
|
||||||
|
{
|
||||||
|
mNavigation->setFastModeFactor (mFast ? mFastFactor : 1);
|
||||||
|
if (mNavigation->activate (mCamera))
|
||||||
|
mUpdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ogre::SceneManager *SceneWidget::getSceneManager()
|
||||||
|
{
|
||||||
|
return mSceneMgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneWidget::flagAsModified()
|
||||||
|
{
|
||||||
|
mUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneWidget::paintEvent(QPaintEvent* e)
|
void SceneWidget::paintEvent(QPaintEvent* e)
|
||||||
|
@ -93,7 +148,6 @@ namespace CSVRender
|
||||||
e->accept();
|
e->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QPaintEngine* SceneWidget::paintEngine() const
|
QPaintEngine* SceneWidget::paintEngine() const
|
||||||
{
|
{
|
||||||
// We don't want another paint engine to get in the way.
|
// We don't want another paint engine to get in the way.
|
||||||
|
@ -130,4 +184,170 @@ namespace CSVRender
|
||||||
return QWidget::event(e);
|
return QWidget::event(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SceneWidget::keyPressEvent (QKeyEvent *event)
|
||||||
|
{
|
||||||
|
switch (event->key())
|
||||||
|
{
|
||||||
|
case Qt::Key_W: mKeyForward = true; break;
|
||||||
|
case Qt::Key_S: mKeyBackward = true; break;
|
||||||
|
case Qt::Key_A: mKeyLeft = true; break;
|
||||||
|
case Qt::Key_D: mKeyRight = true; break;
|
||||||
|
case Qt::Key_Q: mKeyRollLeft = true; break;
|
||||||
|
case Qt::Key_E: mKeyRollRight = true; break;
|
||||||
|
case Qt::Key_Control: mMod1 = true; break;
|
||||||
|
|
||||||
|
case Qt::Key_Shift:
|
||||||
|
|
||||||
|
mFast = true;
|
||||||
|
|
||||||
|
if (mNavigation)
|
||||||
|
mNavigation->setFastModeFactor (mFastFactor);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: QWidget::keyPressEvent (event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneWidget::keyReleaseEvent (QKeyEvent *event)
|
||||||
|
{
|
||||||
|
switch (event->key())
|
||||||
|
{
|
||||||
|
case Qt::Key_W: mKeyForward = false; break;
|
||||||
|
case Qt::Key_S: mKeyBackward = false; break;
|
||||||
|
case Qt::Key_A: mKeyLeft = false; break;
|
||||||
|
case Qt::Key_D: mKeyRight = false; break;
|
||||||
|
case Qt::Key_Q: mKeyRollLeft = false; break;
|
||||||
|
case Qt::Key_E: mKeyRollRight = false; break;
|
||||||
|
case Qt::Key_Control: mMod1 = false; break;
|
||||||
|
|
||||||
|
case Qt::Key_Shift:
|
||||||
|
|
||||||
|
mFast = false;
|
||||||
|
|
||||||
|
if (mNavigation)
|
||||||
|
mNavigation->setFastModeFactor (1);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: QWidget::keyReleaseEvent (event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneWidget::wheelEvent (QWheelEvent *event)
|
||||||
|
{
|
||||||
|
if (mNavigation)
|
||||||
|
if (event->delta())
|
||||||
|
if (mNavigation->wheelMoved (event->delta()))
|
||||||
|
mUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneWidget::leaveEvent (QEvent *event)
|
||||||
|
{
|
||||||
|
mDragging = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneWidget::mouseMoveEvent (QMouseEvent *event)
|
||||||
|
{
|
||||||
|
if (event->buttons() & Qt::LeftButton)
|
||||||
|
{
|
||||||
|
if (mDragging)
|
||||||
|
{
|
||||||
|
QPoint diff = mOldPos-event->pos();
|
||||||
|
mOldPos = event->pos();
|
||||||
|
|
||||||
|
if (mNavigation)
|
||||||
|
if (mNavigation->mouseMoved (diff, mMod1 ? 1 : 0))
|
||||||
|
mUpdate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mDragging = true;
|
||||||
|
mOldPos = event->pos();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneWidget::mouseReleaseEvent (QMouseEvent *event)
|
||||||
|
{
|
||||||
|
if (!(event->buttons() & Qt::LeftButton))
|
||||||
|
mDragging = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneWidget::focusOutEvent (QFocusEvent *event)
|
||||||
|
{
|
||||||
|
mKeyForward = false;
|
||||||
|
mKeyBackward = false;
|
||||||
|
mKeyLeft = false;
|
||||||
|
mKeyRight = false;
|
||||||
|
mFast = false;
|
||||||
|
mMod1 = false;
|
||||||
|
|
||||||
|
QWidget::focusOutEvent (event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneWidget::update()
|
||||||
|
{
|
||||||
|
if (mNavigation)
|
||||||
|
{
|
||||||
|
int horizontal = 0;
|
||||||
|
int vertical = 0;
|
||||||
|
|
||||||
|
if (mKeyForward && !mKeyBackward)
|
||||||
|
vertical = 1;
|
||||||
|
else if (!mKeyForward && mKeyBackward)
|
||||||
|
vertical = -1;
|
||||||
|
|
||||||
|
if (mKeyLeft && !mKeyRight)
|
||||||
|
horizontal = -1;
|
||||||
|
else if (!mKeyLeft && mKeyRight)
|
||||||
|
horizontal = 1;
|
||||||
|
|
||||||
|
if (horizontal || vertical)
|
||||||
|
if (mNavigation->handleMovementKeys (vertical, horizontal))
|
||||||
|
mUpdate = true;
|
||||||
|
|
||||||
|
int roll = 0;
|
||||||
|
|
||||||
|
if (mKeyRollLeft && !mKeyRollRight)
|
||||||
|
roll = 1;
|
||||||
|
else if (!mKeyRollLeft && mKeyRollRight)
|
||||||
|
roll = -1;
|
||||||
|
|
||||||
|
if (roll)
|
||||||
|
if (mNavigation->handleRollKeys (roll))
|
||||||
|
mUpdate = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mUpdate)
|
||||||
|
{
|
||||||
|
mUpdate = false;
|
||||||
|
mWindow->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int SceneWidget::getFastFactor() const
|
||||||
|
{
|
||||||
|
return mFast ? mFastFactor : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneWidget::setLighting (Lighting *lighting)
|
||||||
|
{
|
||||||
|
if (mLighting)
|
||||||
|
mLighting->deactivate();
|
||||||
|
|
||||||
|
mLighting = lighting;
|
||||||
|
mLighting->activate (mSceneMgr, mHasDefaultAmbient ? &mDefaultAmbient : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneWidget::selectLightingMode (const std::string& mode)
|
||||||
|
{
|
||||||
|
if (mode=="day")
|
||||||
|
setLighting (&mLightingDay);
|
||||||
|
else if (mode=="night")
|
||||||
|
setLighting (&mLightingNight);
|
||||||
|
else if (mode=="bright")
|
||||||
|
setLighting (&mLightingBright);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,12 @@
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include <OgreColourValue.h>
|
||||||
|
|
||||||
|
#include "lightingday.hpp"
|
||||||
|
#include "lightingnight.hpp"
|
||||||
|
#include "lightingbright.hpp"
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
class Camera;
|
class Camera;
|
||||||
|
@ -10,31 +16,100 @@ namespace Ogre
|
||||||
class RenderWindow;
|
class RenderWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class SceneToolMode;
|
||||||
|
class SceneToolbar;
|
||||||
|
}
|
||||||
|
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
{
|
{
|
||||||
|
class Navigation;
|
||||||
|
class Lighting;
|
||||||
|
|
||||||
class SceneWidget : public QWidget
|
class SceneWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SceneWidget(QWidget *parent);
|
SceneWidget(QWidget *parent);
|
||||||
virtual ~SceneWidget(void);
|
virtual ~SceneWidget();
|
||||||
|
|
||||||
QPaintEngine* paintEngine() const;
|
QPaintEngine* paintEngine() const;
|
||||||
|
|
||||||
|
CSVWorld::SceneToolMode *makeLightingSelector (CSVWorld::SceneToolbar *parent);
|
||||||
|
///< \attention The created tool is not added to the toolbar (via addTool). Doing that
|
||||||
|
/// is the responsibility of the calling function.
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void setNavigation (Navigation *navigation);
|
||||||
|
///< \attention The ownership of \a navigation is not transferred to *this.
|
||||||
|
|
||||||
|
Ogre::SceneManager *getSceneManager();
|
||||||
|
|
||||||
|
void flagAsModified();
|
||||||
|
|
||||||
|
void setDefaultAmbient (const Ogre::ColourValue& colour);
|
||||||
|
///< \note The actual ambient colour may differ based on lighting settings.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void paintEvent(QPaintEvent* e);
|
void paintEvent(QPaintEvent* e);
|
||||||
void resizeEvent(QResizeEvent* e);
|
void resizeEvent(QResizeEvent* e);
|
||||||
bool event(QEvent* e);
|
bool event(QEvent* e);
|
||||||
|
|
||||||
|
void keyPressEvent (QKeyEvent *event);
|
||||||
|
|
||||||
|
void keyReleaseEvent (QKeyEvent *event);
|
||||||
|
|
||||||
|
void focusOutEvent (QFocusEvent *event);
|
||||||
|
|
||||||
|
void wheelEvent (QWheelEvent *event);
|
||||||
|
|
||||||
|
void leaveEvent (QEvent *event);
|
||||||
|
|
||||||
|
void mouseMoveEvent (QMouseEvent *event);
|
||||||
|
|
||||||
|
void mouseReleaseEvent (QMouseEvent *event);
|
||||||
|
|
||||||
void updateOgreWindow();
|
void updateOgreWindow();
|
||||||
|
|
||||||
|
int getFastFactor() const;
|
||||||
|
|
||||||
|
void setLighting (Lighting *lighting);
|
||||||
|
///< \attention The ownership of \a lighting is not transferred to *this.
|
||||||
|
|
||||||
Ogre::Camera* mCamera;
|
Ogre::Camera* mCamera;
|
||||||
Ogre::SceneManager* mSceneMgr;
|
Ogre::SceneManager* mSceneMgr;
|
||||||
Ogre::RenderWindow* mWindow;
|
Ogre::RenderWindow* mWindow;
|
||||||
};
|
|
||||||
|
|
||||||
|
Navigation *mNavigation;
|
||||||
|
Lighting *mLighting;
|
||||||
|
bool mUpdate;
|
||||||
|
bool mKeyForward;
|
||||||
|
bool mKeyBackward;
|
||||||
|
bool mKeyLeft;
|
||||||
|
bool mKeyRight;
|
||||||
|
bool mKeyRollLeft;
|
||||||
|
bool mKeyRollRight;
|
||||||
|
bool mFast;
|
||||||
|
bool mDragging;
|
||||||
|
bool mMod1;
|
||||||
|
QPoint mOldPos;
|
||||||
|
int mFastFactor;
|
||||||
|
Ogre::ColourValue mDefaultAmbient;
|
||||||
|
bool mHasDefaultAmbient;
|
||||||
|
LightingDay mLightingDay;
|
||||||
|
LightingNight mLightingNight;
|
||||||
|
LightingBright mLightingBright;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void update();
|
||||||
|
|
||||||
|
void selectLightingMode (const std::string& mode);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
66
apps/opencs/view/render/unpagedworldspacewidget.cpp
Normal file
66
apps/opencs/view/render/unpagedworldspacewidget.cpp
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
|
||||||
|
#include "unpagedworldspacewidget.hpp"
|
||||||
|
|
||||||
|
#include <OgreColourValue.h>
|
||||||
|
|
||||||
|
#include "../../model/doc/document.hpp"
|
||||||
|
|
||||||
|
#include "../../model/world/data.hpp"
|
||||||
|
#include "../../model/world/idtable.hpp"
|
||||||
|
|
||||||
|
void CSVRender::UnpagedWorldspaceWidget::update()
|
||||||
|
{
|
||||||
|
const CSMWorld::Record<CSMWorld::Cell>& record =
|
||||||
|
dynamic_cast<const CSMWorld::Record<CSMWorld::Cell>&> (mCellsModel->getRecord (mCellId));
|
||||||
|
|
||||||
|
Ogre::ColourValue colour;
|
||||||
|
colour.setAsABGR (record.get().mAmbi.mAmbient);
|
||||||
|
setDefaultAmbient (colour);
|
||||||
|
|
||||||
|
/// \todo deal with mSunlight and mFog/mForDensity
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& cellId,
|
||||||
|
CSMDoc::Document& document, QWidget *parent)
|
||||||
|
: WorldspaceWidget (parent), mCellId (cellId)
|
||||||
|
{
|
||||||
|
mCellsModel = &dynamic_cast<CSMWorld::IdTable&> (
|
||||||
|
*document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells));
|
||||||
|
|
||||||
|
connect (mCellsModel, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||||
|
this, SLOT (cellDataChanged (const QModelIndex&, const QModelIndex&)));
|
||||||
|
connect (mCellsModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||||
|
this, SLOT (cellRowsAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight)
|
||||||
|
{
|
||||||
|
int index = mCellsModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification);
|
||||||
|
QModelIndex cellIndex = mCellsModel->getModelIndex (mCellId, index);
|
||||||
|
|
||||||
|
if (cellIndex.row()>=topLeft.row() && cellIndex.row()<=bottomRight.row())
|
||||||
|
{
|
||||||
|
if (mCellsModel->data (cellIndex).toInt()==CSMWorld::RecordBase::State_Deleted)
|
||||||
|
{
|
||||||
|
emit closeRequest();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/// \todo possible optimisation: check columns and update only if relevant columns have
|
||||||
|
/// changed
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::UnpagedWorldspaceWidget::cellRowsAboutToBeRemoved (const QModelIndex& parent,
|
||||||
|
int start, int end)
|
||||||
|
{
|
||||||
|
QModelIndex cellIndex = mCellsModel->getModelIndex (mCellId, 0);
|
||||||
|
|
||||||
|
if (cellIndex.row()>=start && cellIndex.row()<=end)
|
||||||
|
emit closeRequest();
|
||||||
|
}
|
44
apps/opencs/view/render/unpagedworldspacewidget.hpp
Normal file
44
apps/opencs/view/render/unpagedworldspacewidget.hpp
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#ifndef OPENCS_VIEW_UNPAGEDWORLDSPACEWIDGET_H
|
||||||
|
#define OPENCS_VIEW_UNPAGEDWORLDSPACEWIDGET_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "worldspacewidget.hpp"
|
||||||
|
|
||||||
|
class QModelIndex;
|
||||||
|
|
||||||
|
namespace CSMDoc
|
||||||
|
{
|
||||||
|
class Document;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class IdTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class UnpagedWorldspaceWidget : public WorldspaceWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
std::string mCellId;
|
||||||
|
CSMWorld::IdTable *mCellsModel;
|
||||||
|
|
||||||
|
void update();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document,
|
||||||
|
QWidget *parent);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
void cellRowsAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
47
apps/opencs/view/render/worldspacewidget.cpp
Normal file
47
apps/opencs/view/render/worldspacewidget.cpp
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
|
||||||
|
#include "worldspacewidget.hpp"
|
||||||
|
|
||||||
|
#include <OgreSceneNode.h>
|
||||||
|
#include <OgreSceneManager.h>
|
||||||
|
#include <OgreEntity.h>
|
||||||
|
|
||||||
|
#include "../world/scenetoolmode.hpp"
|
||||||
|
|
||||||
|
CSVRender::WorldspaceWidget::WorldspaceWidget (QWidget *parent)
|
||||||
|
: SceneWidget (parent)
|
||||||
|
{
|
||||||
|
Ogre::Entity* ent = getSceneManager()->createEntity("cube", Ogre::SceneManager::PT_CUBE);
|
||||||
|
ent->setMaterialName("BaseWhite");
|
||||||
|
|
||||||
|
getSceneManager()->getRootSceneNode()->attachObject(ent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode)
|
||||||
|
{
|
||||||
|
if (mode=="1st")
|
||||||
|
setNavigation (&m1st);
|
||||||
|
else if (mode=="free")
|
||||||
|
setNavigation (&mFree);
|
||||||
|
else if (mode=="orbit")
|
||||||
|
setNavigation (&mOrbit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::WorldspaceWidget::selectDefaultNavigationMode()
|
||||||
|
{
|
||||||
|
setNavigation (&m1st);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector (
|
||||||
|
CSVWorld::SceneToolbar *parent)
|
||||||
|
{
|
||||||
|
CSVWorld::SceneToolMode *tool = new CSVWorld::SceneToolMode (parent);
|
||||||
|
|
||||||
|
tool->addButton (":door.png", "1st"); /// \todo replace icons
|
||||||
|
tool->addButton (":GMST.png", "free");
|
||||||
|
tool->addButton (":Info.png", "orbit");
|
||||||
|
|
||||||
|
connect (tool, SIGNAL (modeChanged (const std::string&)),
|
||||||
|
this, SLOT (selectNavigationMode (const std::string&)));
|
||||||
|
|
||||||
|
return tool;
|
||||||
|
}
|
46
apps/opencs/view/render/worldspacewidget.hpp
Normal file
46
apps/opencs/view/render/worldspacewidget.hpp
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef OPENCS_VIEW_WORLDSPACEWIDGET_H
|
||||||
|
#define OPENCS_VIEW_WORLDSPACEWIDGET_H
|
||||||
|
|
||||||
|
#include "scenewidget.hpp"
|
||||||
|
|
||||||
|
#include "navigation1st.hpp"
|
||||||
|
#include "navigationfree.hpp"
|
||||||
|
#include "navigationorbit.hpp"
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class SceneToolMode;
|
||||||
|
class SceneToolbar;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class WorldspaceWidget : public SceneWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
CSVRender::Navigation1st m1st;
|
||||||
|
CSVRender::NavigationFree mFree;
|
||||||
|
CSVRender::NavigationOrbit mOrbit;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
WorldspaceWidget (QWidget *parent = 0);
|
||||||
|
|
||||||
|
CSVWorld::SceneToolMode *makeNavigationSelector (CSVWorld::SceneToolbar *parent);
|
||||||
|
///< \attention The created tool is not added to the toolbar (via addTool). Doing that
|
||||||
|
/// is the responsibility of the calling function.
|
||||||
|
|
||||||
|
void selectDefaultNavigationMode();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void selectNavigationMode (const std::string& mode);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void closeRequest();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -40,5 +40,5 @@ void CSVTools::ReportSubView::updateEditorSetting (const QString& key, const QSt
|
||||||
|
|
||||||
void CSVTools::ReportSubView::show (const QModelIndex& index)
|
void CSVTools::ReportSubView::show (const QModelIndex& index)
|
||||||
{
|
{
|
||||||
focusId (mModel->getUniversalId (index.row()));
|
focusId (mModel->getUniversalId (index.row()), "");
|
||||||
}
|
}
|
|
@ -1,98 +1,689 @@
|
||||||
|
|
||||||
#include "dialoguesubview.hpp"
|
#include "dialoguesubview.hpp"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QSize>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
#include <QDoubleSpinBox>
|
#include <QDoubleSpinBox>
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
|
#include <QEvent>
|
||||||
#include <QDataWidgetMapper>
|
#include <QDataWidgetMapper>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QToolButton>
|
||||||
|
|
||||||
#include "../../model/world/columnbase.hpp"
|
#include "../../model/world/columnbase.hpp"
|
||||||
#include "../../model/world/idtable.hpp"
|
#include "../../model/world/idtable.hpp"
|
||||||
|
#include "../../model/world/columns.hpp"
|
||||||
|
#include "../../model/world/record.hpp"
|
||||||
|
#include "../../model/world/tablemimedata.hpp"
|
||||||
|
#include "../../model/doc/document.hpp"
|
||||||
|
#include "../../model/world/commands.hpp"
|
||||||
|
|
||||||
CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
|
#include "recordstatusdelegate.hpp"
|
||||||
bool createAndDelete)
|
#include "util.hpp"
|
||||||
: SubView (id)
|
#include "tablebottombox.hpp"
|
||||||
|
/*
|
||||||
|
==============================NotEditableSubDelegate==========================================
|
||||||
|
*/
|
||||||
|
CSVWorld::NotEditableSubDelegate::NotEditableSubDelegate(const CSMWorld::IdTable* table, QObject * parent) :
|
||||||
|
QAbstractItemDelegate(parent),
|
||||||
|
mTable(table)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CSVWorld::NotEditableSubDelegate::setEditorData (QLabel* editor, const QModelIndex& index) const
|
||||||
{
|
{
|
||||||
QWidget *widget = new QWidget (this);
|
QVariant v = index.data(Qt::EditRole);
|
||||||
|
if (!v.isValid())
|
||||||
|
{
|
||||||
|
v = index.data(Qt::DisplayRole);
|
||||||
|
if (!v.isValid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setWidget (widget);
|
if (QVariant::String == v.type())
|
||||||
|
{
|
||||||
|
editor->setText(v.toString());
|
||||||
|
} else //else we are facing enums
|
||||||
|
{
|
||||||
|
int data = v.toInt();
|
||||||
|
std::vector<std::string> enumNames (CSMWorld::Columns::getEnums (static_cast<CSMWorld::Columns::ColumnId> (mTable->getColumnId (index.column()))));
|
||||||
|
editor->setText(QString::fromUtf8(enumNames.at(data).c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QGridLayout *layout = new QGridLayout;
|
void CSVWorld::NotEditableSubDelegate::setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const
|
||||||
|
{
|
||||||
|
//not editable widgets will not save model data
|
||||||
|
}
|
||||||
|
|
||||||
widget->setLayout (layout);
|
void CSVWorld::NotEditableSubDelegate::paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
//does nothing
|
||||||
|
}
|
||||||
|
|
||||||
QAbstractItemModel *model = document.getData().getTableModel (id);
|
QSize CSVWorld::NotEditableSubDelegate::sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
return QSize();
|
||||||
|
}
|
||||||
|
|
||||||
int columns = model->columnCount();
|
QWidget* CSVWorld::NotEditableSubDelegate::createEditor (QWidget *parent,
|
||||||
|
const QStyleOptionViewItem& option,
|
||||||
|
const QModelIndex& index,
|
||||||
|
CSMWorld::ColumnBase::Display display) const
|
||||||
|
{
|
||||||
|
return new QLabel(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==============================DialogueDelegateDispatcherProxy==========================================
|
||||||
|
*/
|
||||||
|
CSVWorld::DialogueDelegateDispatcherProxy::refWrapper::refWrapper(const QModelIndex& index) :
|
||||||
|
mIndex(index)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CSVWorld::DialogueDelegateDispatcherProxy::DialogueDelegateDispatcherProxy(QWidget* editor, CSMWorld::ColumnBase::Display display) :
|
||||||
|
mEditor(editor),
|
||||||
|
mDisplay(display),
|
||||||
|
mIndexWrapper(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueDelegateDispatcherProxy::editorDataCommited()
|
||||||
|
{
|
||||||
|
if (mIndexWrapper.get())
|
||||||
|
{
|
||||||
|
emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueDelegateDispatcherProxy::setIndex(const QModelIndex& index)
|
||||||
|
{
|
||||||
|
mIndexWrapper.reset(new refWrapper(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* CSVWorld::DialogueDelegateDispatcherProxy::getEditor() const
|
||||||
|
{
|
||||||
|
return mEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std::vector<CSMWorld::UniversalId>& data, const CSMDoc::Document* document)
|
||||||
|
{
|
||||||
|
QLineEdit* lineEdit = qobject_cast<QLineEdit*>(mEditor);
|
||||||
|
{
|
||||||
|
if (!lineEdit || !mIndexWrapper.get())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i < data.size(); ++i)
|
||||||
|
{
|
||||||
|
CSMWorld::UniversalId::Type type = data[i].getType();
|
||||||
|
if (mDisplay == CSMWorld::ColumnBase::Display_Referenceable)
|
||||||
|
{
|
||||||
|
if ( type == CSMWorld::UniversalId::Type_Activator
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Potion
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Apparatus
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Armor
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Book
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Clothing
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Container
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Creature
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Door
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Ingredient
|
||||||
|
|| type == CSMWorld::UniversalId::Type_CreatureLevelledList
|
||||||
|
|| type == CSMWorld::UniversalId::Type_ItemLevelledList
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Light
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Lockpick
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Miscellaneous
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Npc
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Probe
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Repair
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Static
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Weapon)
|
||||||
|
{
|
||||||
|
type = CSMWorld::UniversalId::Type_Referenceable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mDisplay == CSMWorld::TableMimeData::convertEnums(type))
|
||||||
|
{
|
||||||
|
emit tableMimeDataDropped(mEditor, mIndexWrapper->mIndex, data[i], document);
|
||||||
|
emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
==============================DialogueDelegateDispatcher==========================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, QUndoStack& undoStack) :
|
||||||
|
mParent(parent),
|
||||||
|
mTable(table),
|
||||||
|
mUndoStack(undoStack),
|
||||||
|
mNotEditableDelegate(table, parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::CommandDelegate* CSVWorld::DialogueDelegateDispatcher::makeDelegate(CSMWorld::ColumnBase::Display display)
|
||||||
|
{
|
||||||
|
CommandDelegate *delegate = NULL;
|
||||||
|
std::map<int, CommandDelegate*>::const_iterator delegateIt(mDelegates.find(display));
|
||||||
|
if (delegateIt == mDelegates.end())
|
||||||
|
{
|
||||||
|
delegate = CommandDelegateFactoryCollection::get().makeDelegate (
|
||||||
|
display, mUndoStack, mParent);
|
||||||
|
mDelegates.insert(std::make_pair<int, CommandDelegate*>(display, delegate));
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
delegate = delegateIt->second;
|
||||||
|
}
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueDelegateDispatcher::editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display)
|
||||||
|
{
|
||||||
|
setModelData(editor, mTable, index, display);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueDelegateDispatcher::setEditorData (QWidget* editor, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display>
|
||||||
|
(mTable->headerData (index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
|
||||||
|
|
||||||
|
QLabel* label = qobject_cast<QLabel*>(editor);
|
||||||
|
if(label)
|
||||||
|
{
|
||||||
|
mNotEditableDelegate.setEditorData(label, index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<int, CommandDelegate*>::const_iterator delegateIt(mDelegates.find(display));
|
||||||
|
if (delegateIt != mDelegates.end())
|
||||||
|
{
|
||||||
|
delegateIt->second->setEditorData(editor, index, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < mProxys.size(); ++i)
|
||||||
|
{
|
||||||
|
if (mProxys[i]->getEditor() == editor)
|
||||||
|
{
|
||||||
|
mProxys[i]->setIndex(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const
|
||||||
|
{
|
||||||
|
std::map<int, CommandDelegate*>::const_iterator delegateIt(mDelegates.find(display));
|
||||||
|
if (delegateIt != mDelegates.end())
|
||||||
|
{
|
||||||
|
delegateIt->second->setModelData(editor, model, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueDelegateDispatcher::paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
//Does nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize CSVWorld::DialogueDelegateDispatcher::sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
return QSize(); //silencing warning, otherwise does nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index)
|
||||||
|
{
|
||||||
|
QVariant variant = index.data();
|
||||||
|
if (!variant.isValid())
|
||||||
|
{
|
||||||
|
variant = index.data(Qt::DisplayRole);
|
||||||
|
if (!variant.isValid())
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* editor = NULL;
|
||||||
|
if (! (mTable->flags (index) & Qt::ItemIsEditable))
|
||||||
|
{
|
||||||
|
return mNotEditableDelegate.createEditor(qobject_cast<QWidget*>(mParent), QStyleOptionViewItem(), index, display);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<int, CommandDelegate*>::iterator delegateIt(mDelegates.find(display));
|
||||||
|
if (delegateIt != mDelegates.end())
|
||||||
|
{
|
||||||
|
editor = delegateIt->second->createEditor(qobject_cast<QWidget*>(mParent), QStyleOptionViewItem(), index, display);
|
||||||
|
DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display);
|
||||||
|
|
||||||
|
bool skip = false;
|
||||||
|
if (qobject_cast<DropLineEdit*>(editor))
|
||||||
|
{
|
||||||
|
connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited()));
|
||||||
|
connect(editor, SIGNAL(tableMimeDataDropped(const std::vector<CSMWorld::UniversalId>&, const CSMDoc::Document*)),
|
||||||
|
proxy, SLOT(tableMimeDataDropped(const std::vector<CSMWorld::UniversalId>&, const CSMDoc::Document*)));
|
||||||
|
connect(proxy, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)),
|
||||||
|
this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)));
|
||||||
|
skip = true;
|
||||||
|
}
|
||||||
|
if(!skip && qobject_cast<QCheckBox*>(editor))
|
||||||
|
{
|
||||||
|
connect(editor, SIGNAL(stateChanged(int)), proxy, SLOT(editorDataCommited()));
|
||||||
|
skip = true;
|
||||||
|
}
|
||||||
|
if(!skip && qobject_cast<QPlainTextEdit*>(editor))
|
||||||
|
{
|
||||||
|
connect(editor, SIGNAL(textChanged()), proxy, SLOT(editorDataCommited()));
|
||||||
|
skip = true;
|
||||||
|
}
|
||||||
|
if(!skip && qobject_cast<QComboBox*>(editor))
|
||||||
|
{
|
||||||
|
connect(editor, SIGNAL(currentIndexChanged (int)), proxy, SLOT(editorDataCommited()));
|
||||||
|
skip = true;
|
||||||
|
}
|
||||||
|
if(!skip && qobject_cast<QAbstractSpinBox*>(editor))
|
||||||
|
{
|
||||||
|
connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited()));
|
||||||
|
skip = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)), this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)));
|
||||||
|
mProxys.push_back(proxy); //deleted in the destructor
|
||||||
|
}
|
||||||
|
return editor;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::DialogueDelegateDispatcher::~DialogueDelegateDispatcher()
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < mProxys.size(); ++i)
|
||||||
|
{
|
||||||
|
delete mProxys[i]; //unique_ptr could be handy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============================================================EditWidget=====================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
CSVWorld::EditWidget::EditWidget(QWidget *parent, int row, CSMWorld::IdTable* table, QUndoStack& undoStack, bool createAndDelete) :
|
||||||
|
mDispatcher(this, table, undoStack),
|
||||||
|
QScrollArea(parent),
|
||||||
|
mWidgetMapper(NULL),
|
||||||
|
mMainWidget(NULL),
|
||||||
|
mUndoStack(undoStack),
|
||||||
|
mTable(table)
|
||||||
|
{
|
||||||
|
remake (row);
|
||||||
|
connect(&mDispatcher, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::EditWidget::remake(int row)
|
||||||
|
{
|
||||||
|
if (mMainWidget)
|
||||||
|
{
|
||||||
|
delete mMainWidget;
|
||||||
|
}
|
||||||
|
mMainWidget = new QWidget (this);
|
||||||
|
|
||||||
|
//not sure if widget mapper can handle deleting the widgets that were mapped
|
||||||
|
if (mWidgetMapper)
|
||||||
|
{
|
||||||
|
delete mWidgetMapper;
|
||||||
|
}
|
||||||
mWidgetMapper = new QDataWidgetMapper (this);
|
mWidgetMapper = new QDataWidgetMapper (this);
|
||||||
mWidgetMapper->setModel (model);
|
mWidgetMapper->setModel(mTable);
|
||||||
|
mWidgetMapper->setItemDelegate(&mDispatcher);
|
||||||
|
|
||||||
|
QFrame* line = new QFrame(mMainWidget);
|
||||||
|
line->setObjectName(QString::fromUtf8("line"));
|
||||||
|
line->setGeometry(QRect(320, 150, 118, 3));
|
||||||
|
line->setFrameShape(QFrame::HLine);
|
||||||
|
line->setFrameShadow(QFrame::Sunken);
|
||||||
|
|
||||||
|
QVBoxLayout *mainLayout = new QVBoxLayout(mMainWidget);
|
||||||
|
QGridLayout *unlockedLayout = new QGridLayout();
|
||||||
|
QGridLayout *lockedLayout = new QGridLayout();
|
||||||
|
mainLayout->addLayout(lockedLayout, 0);
|
||||||
|
mainLayout->addWidget(line, 1);
|
||||||
|
mainLayout->addLayout(unlockedLayout, 2);
|
||||||
|
mainLayout->addStretch(1);
|
||||||
|
|
||||||
|
int unlocked = 0;
|
||||||
|
int locked = 0;
|
||||||
|
const int columns = mTable->columnCount();
|
||||||
for (int i=0; i<columns; ++i)
|
for (int i=0; i<columns; ++i)
|
||||||
{
|
{
|
||||||
int flags = model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt();
|
int flags = mTable->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt();
|
||||||
|
|
||||||
if (flags & CSMWorld::ColumnBase::Flag_Dialogue)
|
if (flags & CSMWorld::ColumnBase::Flag_Dialogue)
|
||||||
{
|
{
|
||||||
layout->addWidget (new QLabel (model->headerData (i, Qt::Horizontal).toString()), i, 0);
|
|
||||||
|
|
||||||
CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display>
|
CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display>
|
||||||
(model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
|
(mTable->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
|
||||||
|
|
||||||
QWidget *widget = 0;
|
mDispatcher.makeDelegate(display);
|
||||||
|
QWidget *editor = mDispatcher.makeEditor(display, (mTable->index (row, i)));
|
||||||
|
|
||||||
if (model->flags (model->index (0, i)) & Qt::ItemIsEditable)
|
if (editor)
|
||||||
{
|
{
|
||||||
switch (display)
|
mWidgetMapper->addMapping (editor, i);
|
||||||
|
QLabel* label = new QLabel(mTable->headerData (i, Qt::Horizontal).toString(), mMainWidget);
|
||||||
|
label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
|
editor->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||||
|
if (! (mTable->flags (mTable->index (row, i)) & Qt::ItemIsEditable))
|
||||||
{
|
{
|
||||||
case CSMWorld::ColumnBase::Display_String:
|
lockedLayout->addWidget (label, locked, 0);
|
||||||
|
lockedLayout->addWidget (editor, locked, 1);
|
||||||
layout->addWidget (widget = new QLineEdit, i, 1);
|
++locked;
|
||||||
break;
|
} else
|
||||||
|
|
||||||
case CSMWorld::ColumnBase::Display_Integer:
|
|
||||||
|
|
||||||
/// \todo configure widget properly (range)
|
|
||||||
layout->addWidget (widget = new QSpinBox, i, 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CSMWorld::ColumnBase::Display_Float:
|
|
||||||
|
|
||||||
/// \todo configure widget properly (range, format?)
|
|
||||||
layout->addWidget (widget = new QDoubleSpinBox, i, 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: break; // silence warnings for other times for now
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
switch (display)
|
unlockedLayout->addWidget (label, unlocked, 0);
|
||||||
|
unlockedLayout->addWidget (editor, unlocked, 1);
|
||||||
|
++unlocked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mWidgetMapper->setCurrentModelIndex(mTable->index(row, 0));
|
||||||
|
|
||||||
|
this->setMinimumWidth(325); //TODO find better way to set the width or make it customizable
|
||||||
|
this->setWidget(mMainWidget);
|
||||||
|
this->setWidgetResizable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==============================DialogueSubView==========================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
|
||||||
|
const CreatorFactoryBase& creatorFactory, bool sorting) :
|
||||||
|
|
||||||
|
SubView (id),
|
||||||
|
mEditWidget(0),
|
||||||
|
mMainLayout(NULL),
|
||||||
|
mUndoStack(document.getUndoStack()),
|
||||||
|
mTable(dynamic_cast<CSMWorld::IdTable*>(document.getData().getTableModel(id))),
|
||||||
|
mRow (-1),
|
||||||
|
mLocked(false),
|
||||||
|
mDocument(document)
|
||||||
|
|
||||||
{
|
{
|
||||||
case CSMWorld::ColumnBase::Display_String:
|
connect(mTable, SIGNAL(dataChanged (const QModelIndex&, const QModelIndex&)), this, SLOT(dataChanged(const QModelIndex&)));
|
||||||
case CSMWorld::ColumnBase::Display_Integer:
|
mRow = mTable->getModelIndex (id.getId(), 0).row();
|
||||||
case CSMWorld::ColumnBase::Display_Float:
|
QWidget *mainWidget = new QWidget(this);
|
||||||
|
|
||||||
layout->addWidget (widget = new QLabel, i, 1);
|
QHBoxLayout *buttonsLayout = new QHBoxLayout;
|
||||||
break;
|
QToolButton* prevButton = new QToolButton(mainWidget);
|
||||||
|
prevButton->setIcon(QIcon(":/go-previous.png"));
|
||||||
|
QToolButton* nextButton = new QToolButton(mainWidget);
|
||||||
|
nextButton->setIcon(QIcon(":/go-next.png"));
|
||||||
|
buttonsLayout->addWidget(prevButton, 0);
|
||||||
|
buttonsLayout->addWidget(nextButton, 1);
|
||||||
|
buttonsLayout->addStretch(2);
|
||||||
|
|
||||||
default: break; // silence warnings for other times for now
|
QToolButton* cloneButton = new QToolButton(mainWidget);
|
||||||
|
cloneButton->setIcon(QIcon(":/edit-clone.png"));
|
||||||
|
QToolButton* addButton = new QToolButton(mainWidget);
|
||||||
|
addButton->setIcon(QIcon(":/add.png"));
|
||||||
|
QToolButton* deleteButton = new QToolButton(mainWidget);
|
||||||
|
deleteButton->setIcon(QIcon(":/edit-delete.png"));
|
||||||
|
QToolButton* revertButton = new QToolButton(mainWidget);
|
||||||
|
revertButton->setIcon(QIcon(":/edit-undo.png"));
|
||||||
|
|
||||||
|
if (mTable->hasPreview())
|
||||||
|
{
|
||||||
|
QToolButton* previewButton = new QToolButton(mainWidget);
|
||||||
|
previewButton->setIcon(QIcon(":/edit-preview.png"));
|
||||||
|
buttonsLayout->addWidget(previewButton);
|
||||||
|
connect(previewButton, SIGNAL(clicked()), this, SLOT(showPreview()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTable->getViewing()!=CSMWorld::IdTable::Viewing_None)
|
||||||
|
{
|
||||||
|
QToolButton* viewButton = new QToolButton(mainWidget);
|
||||||
|
viewButton->setIcon(QIcon(":/cell.png"));
|
||||||
|
buttonsLayout->addWidget(viewButton);
|
||||||
|
connect(viewButton, SIGNAL(clicked()), this, SLOT(viewRecord()));
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonsLayout->addWidget(cloneButton);
|
||||||
|
buttonsLayout->addWidget(addButton);
|
||||||
|
buttonsLayout->addWidget(deleteButton);
|
||||||
|
buttonsLayout->addWidget(revertButton);
|
||||||
|
|
||||||
|
connect(nextButton, SIGNAL(clicked()), this, SLOT(nextId()));
|
||||||
|
connect(prevButton, SIGNAL(clicked()), this, SLOT(prevId()));
|
||||||
|
connect(cloneButton, SIGNAL(clicked()), this, SLOT(cloneRequest()));
|
||||||
|
connect(revertButton, SIGNAL(clicked()), this, SLOT(revertRecord()));
|
||||||
|
connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteRecord()));
|
||||||
|
|
||||||
|
mMainLayout = new QVBoxLayout(mainWidget);
|
||||||
|
|
||||||
|
mEditWidget = new EditWidget(mainWidget, mRow, mTable, mUndoStack, false);
|
||||||
|
connect(mEditWidget, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)),
|
||||||
|
this, SLOT(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)));
|
||||||
|
|
||||||
|
mMainLayout->addWidget(mEditWidget);
|
||||||
|
mEditWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||||
|
|
||||||
|
mMainLayout->addWidget (mBottom =
|
||||||
|
new TableBottomBox (creatorFactory, document.getData(), document.getUndoStack(), id, this));
|
||||||
|
|
||||||
|
mBottom->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
|
||||||
|
connect(mBottom, SIGNAL(requestFocus(const std::string&)), this, SLOT(requestFocus(const std::string&)));
|
||||||
|
connect(addButton, SIGNAL(clicked()), mBottom, SLOT(createRequest()));
|
||||||
|
|
||||||
|
if(!mBottom->canCreateAndDelete())
|
||||||
|
{
|
||||||
|
cloneButton->setDisabled(true);
|
||||||
|
addButton->setDisabled(true);
|
||||||
|
deleteButton->setDisabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
dataChanged(mTable->index(mRow, 0));
|
||||||
|
mMainLayout->addLayout(buttonsLayout);
|
||||||
|
setWidget(mainWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueSubView::prevId()
|
||||||
|
{
|
||||||
|
int newRow = mRow - 1;
|
||||||
|
if (newRow < 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (newRow >= 0)
|
||||||
|
{
|
||||||
|
QModelIndex newIndex(mTable->index(newRow, 0));
|
||||||
|
|
||||||
|
if (!newIndex.isValid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (newRow, 1)).toInt());
|
||||||
|
if (!(state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased))
|
||||||
|
{
|
||||||
|
mEditWidget->remake(newRow);
|
||||||
|
setUniversalId(CSMWorld::UniversalId (static_cast<CSMWorld::UniversalId::Type> (mTable->data (mTable->index (newRow, 2)).toInt()),
|
||||||
|
mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()));
|
||||||
|
mRow = newRow;
|
||||||
|
mEditWidget->setDisabled(mLocked);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
--newRow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (widget)
|
void CSVWorld::DialogueSubView::nextId()
|
||||||
mWidgetMapper->addMapping (widget, i);
|
{
|
||||||
}
|
int newRow = mRow + 1;
|
||||||
|
|
||||||
|
if (newRow >= mTable->rowCount())
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mWidgetMapper->setCurrentModelIndex (
|
while (newRow < mTable->rowCount())
|
||||||
dynamic_cast<CSMWorld::IdTable&> (*model).getModelIndex (id.getId(), 0));
|
{
|
||||||
|
QModelIndex newIndex(mTable->index(newRow, 0));
|
||||||
|
|
||||||
|
if (!newIndex.isValid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (newRow, 1)).toInt());
|
||||||
|
if (!(state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased))
|
||||||
|
{
|
||||||
|
mEditWidget->remake(newRow);
|
||||||
|
setUniversalId(CSMWorld::UniversalId (static_cast<CSMWorld::UniversalId::Type> (mTable->data (mTable->index (newRow, 2)).toInt()),
|
||||||
|
mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()));
|
||||||
|
mRow = newRow;
|
||||||
|
mEditWidget->setDisabled(mLocked);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
++newRow;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWorld::DialogueSubView::setEditLock (bool locked)
|
void CSVWorld::DialogueSubView::setEditLock (bool locked)
|
||||||
{
|
{
|
||||||
|
mLocked = locked;
|
||||||
|
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (mRow, 1)).toInt());
|
||||||
|
if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased)
|
||||||
|
{
|
||||||
|
mEditWidget->setDisabled(true);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
mEditWidget->setDisabled(mLocked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueSubView::dataChanged(const QModelIndex & index)
|
||||||
|
{
|
||||||
|
if (index.row() == mRow)
|
||||||
|
{
|
||||||
|
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (mRow, 1)).toInt());
|
||||||
|
if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased)
|
||||||
|
{
|
||||||
|
mEditWidget->setDisabled(true);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
mEditWidget->setDisabled(mLocked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueSubView::tableMimeDataDropped(QWidget* editor,
|
||||||
|
const QModelIndex& index,
|
||||||
|
const CSMWorld::UniversalId& id,
|
||||||
|
const CSMDoc::Document* document)
|
||||||
|
{
|
||||||
|
if (document == &mDocument)
|
||||||
|
{
|
||||||
|
qobject_cast<DropLineEdit*>(editor)->setText(id.getId().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueSubView::revertRecord()
|
||||||
|
{
|
||||||
|
int rows = mTable->rowCount();
|
||||||
|
if (!mLocked && mTable->columnCount() > 0 && mRow < mTable->rowCount() )
|
||||||
|
{
|
||||||
|
CSMWorld::RecordBase::State state =
|
||||||
|
static_cast<CSMWorld::RecordBase::State> (mTable->data (mTable->index (mRow, 1)).toInt());
|
||||||
|
|
||||||
|
if (state!=CSMWorld::RecordBase::State_BaseOnly)
|
||||||
|
{
|
||||||
|
mUndoStack.push(new CSMWorld::RevertCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData()));
|
||||||
|
}
|
||||||
|
if (rows != mTable->rowCount())
|
||||||
|
{
|
||||||
|
if (mTable->rowCount() == 0)
|
||||||
|
{
|
||||||
|
mEditWidget->setDisabled(true); //closing the editor is other option
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mRow >= mTable->rowCount())
|
||||||
|
{
|
||||||
|
prevId();
|
||||||
|
} else {
|
||||||
|
dataChanged(mTable->index(mRow, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueSubView::deleteRecord()
|
||||||
|
{
|
||||||
|
int rows = mTable->rowCount();
|
||||||
|
|
||||||
|
//easier than disabling the button
|
||||||
|
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (mRow, 1)).toInt());
|
||||||
|
bool deledetedOrErased = (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased);
|
||||||
|
|
||||||
|
if (!mLocked &&
|
||||||
|
mTable->columnCount() > 0 &&
|
||||||
|
!deledetedOrErased &&
|
||||||
|
mRow < rows &&
|
||||||
|
mBottom->canCreateAndDelete())
|
||||||
|
{
|
||||||
|
mUndoStack.push(new CSMWorld::DeleteCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData()));
|
||||||
|
if (rows != mTable->rowCount())
|
||||||
|
{
|
||||||
|
if (mTable->rowCount() == 0)
|
||||||
|
{
|
||||||
|
mEditWidget->setDisabled(true); //closing the editor is other option
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mRow >= mTable->rowCount())
|
||||||
|
{
|
||||||
|
prevId();
|
||||||
|
} else {
|
||||||
|
dataChanged(mTable->index(mRow, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueSubView::requestFocus (const std::string& id)
|
||||||
|
{
|
||||||
|
mRow = mTable->getModelIndex (id, 0).row();
|
||||||
|
mEditWidget->remake(mRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueSubView::cloneRequest ()
|
||||||
|
{
|
||||||
|
mBottom->cloneRequest(mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData(),
|
||||||
|
static_cast<CSMWorld::UniversalId::Type>(mTable->data(mTable->index(mRow, 2)).toInt()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueSubView::showPreview ()
|
||||||
|
{
|
||||||
|
if (mTable->hasPreview() && mRow < mTable->rowCount())
|
||||||
|
{
|
||||||
|
emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData()), "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueSubView::viewRecord()
|
||||||
|
{
|
||||||
|
if (mRow < mTable->rowCount())
|
||||||
|
{
|
||||||
|
std::pair<CSMWorld::UniversalId, std::string> params = mTable->view (mRow);
|
||||||
|
|
||||||
|
if (params.first.getType()!=CSMWorld::UniversalId::Type_None)
|
||||||
|
emit focusId (params.first, params.second);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,9 +1,25 @@
|
||||||
#ifndef CSV_WORLD_DIALOGUESUBVIEW_H
|
#ifndef CSV_WORLD_DIALOGUESUBVIEW_H
|
||||||
#define CSV_WORLD_DIALOGUESUBVIEW_H
|
#define CSV_WORLD_DIALOGUESUBVIEW_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <QAbstractItemDelegate>
|
||||||
|
#include <QScrollArea>
|
||||||
|
|
||||||
#include "../doc/subview.hpp"
|
#include "../doc/subview.hpp"
|
||||||
|
#include "../../model/world/columnbase.hpp"
|
||||||
|
|
||||||
class QDataWidgetMapper;
|
class QDataWidgetMapper;
|
||||||
|
class QSize;
|
||||||
|
class QEvent;
|
||||||
|
class QLabel;
|
||||||
|
class QVBoxLayout;
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class IdTable;
|
||||||
|
}
|
||||||
|
|
||||||
namespace CSMDoc
|
namespace CSMDoc
|
||||||
{
|
{
|
||||||
|
@ -12,15 +28,181 @@ namespace CSMDoc
|
||||||
|
|
||||||
namespace CSVWorld
|
namespace CSVWorld
|
||||||
{
|
{
|
||||||
class DialogueSubView : public CSVDoc::SubView
|
class CommandDelegate;
|
||||||
|
class CreatorFactoryBase;
|
||||||
|
class TableBottomBox;
|
||||||
|
|
||||||
|
class NotEditableSubDelegate : public QAbstractItemDelegate
|
||||||
{
|
{
|
||||||
|
const CSMWorld::IdTable* mTable;
|
||||||
|
public:
|
||||||
|
NotEditableSubDelegate(const CSMWorld::IdTable* table, QObject * parent = 0);
|
||||||
|
|
||||||
|
virtual void setEditorData (QLabel* editor, const QModelIndex& index) const;
|
||||||
|
|
||||||
|
virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const;
|
||||||
|
|
||||||
|
virtual void paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||||
|
///< does nothing
|
||||||
|
|
||||||
|
virtual QSize sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||||
|
///< does nothing
|
||||||
|
|
||||||
|
virtual QWidget *createEditor (QWidget *parent,
|
||||||
|
const QStyleOptionViewItem& option,
|
||||||
|
const QModelIndex& index,
|
||||||
|
CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
//this can't be nested into the DialogueDelegateDispatcher, because it needs to emit signals
|
||||||
|
class DialogueDelegateDispatcherProxy : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
class refWrapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
refWrapper(const QModelIndex& index);
|
||||||
|
|
||||||
|
const QModelIndex& mIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
QWidget* mEditor;
|
||||||
|
|
||||||
|
CSMWorld::ColumnBase::Display mDisplay;
|
||||||
|
|
||||||
|
std::auto_ptr<refWrapper> mIndexWrapper;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DialogueDelegateDispatcherProxy(QWidget* editor, CSMWorld::ColumnBase::Display display);
|
||||||
|
QWidget* getEditor() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void editorDataCommited();
|
||||||
|
void setIndex(const QModelIndex& index);
|
||||||
|
void tableMimeDataDropped(const std::vector<CSMWorld::UniversalId>& data, const CSMDoc::Document* document);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display);
|
||||||
|
|
||||||
|
void tableMimeDataDropped(QWidget* editor, const QModelIndex& index,
|
||||||
|
const CSMWorld::UniversalId& id,
|
||||||
|
const CSMDoc::Document* document);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class DialogueDelegateDispatcher : public QAbstractItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
std::map<int, CommandDelegate*> mDelegates;
|
||||||
|
|
||||||
|
QObject* mParent;
|
||||||
|
|
||||||
|
CSMWorld::IdTable* mTable;
|
||||||
|
|
||||||
|
QUndoStack& mUndoStack;
|
||||||
|
|
||||||
|
NotEditableSubDelegate mNotEditableDelegate;
|
||||||
|
|
||||||
|
std::vector<DialogueDelegateDispatcherProxy*> mProxys; //once we move to the C++11 we should use unique_ptr
|
||||||
|
|
||||||
|
public:
|
||||||
|
DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, QUndoStack& undoStack);
|
||||||
|
|
||||||
|
~DialogueDelegateDispatcher();
|
||||||
|
|
||||||
|
CSVWorld::CommandDelegate* makeDelegate(CSMWorld::ColumnBase::Display display);
|
||||||
|
|
||||||
|
QWidget* makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index);
|
||||||
|
///< will return null if delegate is not present, parent of the widget is same as for dispatcher itself
|
||||||
|
|
||||||
|
virtual void setEditorData (QWidget* editor, const QModelIndex& index) const;
|
||||||
|
|
||||||
|
virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const;
|
||||||
|
|
||||||
|
virtual void paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||||
|
///< does nothing
|
||||||
|
|
||||||
|
virtual QSize sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||||
|
///< does nothing
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void tableMimeDataDropped(QWidget* editor, const QModelIndex& index,
|
||||||
|
const CSMWorld::UniversalId& id,
|
||||||
|
const CSMDoc::Document* document);
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class EditWidget : public QScrollArea
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
QDataWidgetMapper *mWidgetMapper;
|
QDataWidgetMapper *mWidgetMapper;
|
||||||
|
DialogueDelegateDispatcher mDispatcher;
|
||||||
|
QWidget* mMainWidget;
|
||||||
|
CSMWorld::IdTable* mTable;
|
||||||
|
QUndoStack& mUndoStack;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete);
|
EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table, QUndoStack& undoStack, bool createAndDelete = false);
|
||||||
|
|
||||||
|
void remake(int row);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void tableMimeDataDropped(QWidget* editor, const QModelIndex& index,
|
||||||
|
const CSMWorld::UniversalId& id,
|
||||||
|
const CSMDoc::Document* document);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DialogueSubView : public CSVDoc::SubView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
EditWidget* mEditWidget;
|
||||||
|
QVBoxLayout* mMainLayout;
|
||||||
|
CSMWorld::IdTable* mTable;
|
||||||
|
QUndoStack& mUndoStack;
|
||||||
|
int mRow;
|
||||||
|
bool mLocked;
|
||||||
|
const CSMDoc::Document& mDocument;
|
||||||
|
TableBottomBox* mBottom;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DialogueSubView (const CSMWorld::UniversalId& id,
|
||||||
|
CSMDoc::Document& document,
|
||||||
|
const CreatorFactoryBase& creatorFactory,
|
||||||
|
bool sorting = false);
|
||||||
|
|
||||||
virtual void setEditLock (bool locked);
|
virtual void setEditLock (bool locked);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void nextId();
|
||||||
|
|
||||||
|
void prevId();
|
||||||
|
|
||||||
|
void showPreview();
|
||||||
|
|
||||||
|
void viewRecord();
|
||||||
|
|
||||||
|
void revertRecord();
|
||||||
|
|
||||||
|
void deleteRecord();
|
||||||
|
|
||||||
|
void cloneRequest();
|
||||||
|
|
||||||
|
void dataChanged(const QModelIndex & index);
|
||||||
|
///\brief we need to care for deleting currently edited record
|
||||||
|
|
||||||
|
void tableMimeDataDropped(QWidget* editor, const QModelIndex& index,
|
||||||
|
const CSMWorld::UniversalId& id,
|
||||||
|
const CSMDoc::Document* document);
|
||||||
|
|
||||||
|
void requestFocus (const std::string& id);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,10 +41,18 @@ CSVWorld::EnumDelegate::EnumDelegate (const std::vector<std::pair<int, QString>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option,
|
QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent,
|
||||||
|
const QStyleOptionViewItem& option,
|
||||||
const QModelIndex& index) const
|
const QModelIndex& index) const
|
||||||
{
|
{
|
||||||
if (!index.data().isValid())
|
return createEditor(parent, option, index, CSMWorld::ColumnBase::Display_None);
|
||||||
|
//overloading virtual functions is HARD
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option,
|
||||||
|
const QModelIndex& index, CSMWorld::ColumnBase::Display display) const
|
||||||
|
{
|
||||||
|
if (!index.data(Qt::EditRole).isValid() && !index.data(Qt::DisplayRole).isValid())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
QComboBox *comboBox = new QComboBox (parent);
|
QComboBox *comboBox = new QComboBox (parent);
|
||||||
|
@ -56,11 +64,22 @@ QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptio
|
||||||
return comboBox;
|
return comboBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWorld::EnumDelegate::setEditorData (QWidget *editor, const QModelIndex& index) const
|
void CSVWorld::EnumDelegate::setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay) const
|
||||||
{
|
{
|
||||||
if (QComboBox *comboBox = dynamic_cast<QComboBox *> (editor))
|
if (QComboBox *comboBox = dynamic_cast<QComboBox *> (editor))
|
||||||
{
|
{
|
||||||
int value = index.data (Qt::EditRole).toInt();
|
QVariant data = index.data (Qt::EditRole);
|
||||||
|
|
||||||
|
if (tryDisplay && !data.isValid())
|
||||||
|
{
|
||||||
|
data = index.data (Qt::DisplayRole);
|
||||||
|
if (!data.isValid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int value = data.toInt();
|
||||||
|
|
||||||
std::size_t size = mValues.size();
|
std::size_t size = mValues.size();
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
#include <components/esm/defs.hpp>
|
#include <components/esm/defs.hpp>
|
||||||
|
|
||||||
|
@ -31,10 +32,16 @@ namespace CSVWorld
|
||||||
EnumDelegate (const std::vector<std::pair<int, QString> >& values,
|
EnumDelegate (const std::vector<std::pair<int, QString> >& values,
|
||||||
QUndoStack& undoStack, QObject *parent);
|
QUndoStack& undoStack, QObject *parent);
|
||||||
|
|
||||||
virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem& option,
|
virtual QWidget *createEditor(QWidget *parent,
|
||||||
|
const QStyleOptionViewItem& option,
|
||||||
const QModelIndex& index) const;
|
const QModelIndex& index) const;
|
||||||
|
|
||||||
virtual void setEditorData (QWidget *editor, const QModelIndex& index) const;
|
virtual QWidget *createEditor(QWidget *parent,
|
||||||
|
const QStyleOptionViewItem& option,
|
||||||
|
const QModelIndex& index,
|
||||||
|
CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None) const;
|
||||||
|
|
||||||
|
virtual void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay = false) const;
|
||||||
|
|
||||||
virtual void paint (QPainter *painter, const QStyleOptionViewItem& option,
|
virtual void paint (QPainter *painter, const QStyleOptionViewItem& option,
|
||||||
const QModelIndex& index) const;
|
const QModelIndex& index) const;
|
||||||
|
|
64
apps/opencs/view/world/previewsubview.cpp
Normal file
64
apps/opencs/view/world/previewsubview.cpp
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
|
||||||
|
#include "previewsubview.hpp"
|
||||||
|
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
|
#include "../render/previewwidget.hpp"
|
||||||
|
|
||||||
|
#include "scenetoolbar.hpp"
|
||||||
|
#include "scenetoolmode.hpp"
|
||||||
|
|
||||||
|
CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
|
||||||
|
: SubView (id)
|
||||||
|
{
|
||||||
|
QHBoxLayout *layout = new QHBoxLayout;
|
||||||
|
|
||||||
|
layout->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||||
|
|
||||||
|
if (document.getData().getReferenceables().searchId (id.getId())==-1)
|
||||||
|
{
|
||||||
|
std::string referenceableId =
|
||||||
|
document.getData().getReferences().getRecord (id.getId()).get().mRefID;
|
||||||
|
|
||||||
|
referenceableIdChanged (referenceableId);
|
||||||
|
|
||||||
|
mScene =
|
||||||
|
new CSVRender::PreviewWidget (document.getData(), referenceableId, id.getId(), this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mScene = new CSVRender::PreviewWidget (document.getData(), id.getId(), this);
|
||||||
|
|
||||||
|
SceneToolbar *toolbar = new SceneToolbar (48, this);
|
||||||
|
|
||||||
|
SceneToolMode *lightingTool = mScene->makeLightingSelector (toolbar);
|
||||||
|
toolbar->addTool (lightingTool);
|
||||||
|
|
||||||
|
layout->addWidget (toolbar, 0);
|
||||||
|
|
||||||
|
layout->addWidget (mScene, 1);
|
||||||
|
|
||||||
|
QWidget *widget = new QWidget;
|
||||||
|
|
||||||
|
widget->setLayout (layout);
|
||||||
|
|
||||||
|
setWidget (widget);
|
||||||
|
|
||||||
|
connect (mScene, SIGNAL (closeRequest()), this, SLOT (closeRequest()));
|
||||||
|
connect (mScene, SIGNAL (referenceableIdChanged (const std::string&)),
|
||||||
|
this, SLOT (referenceableIdChanged (const std::string&)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::PreviewSubView::setEditLock (bool locked) {}
|
||||||
|
|
||||||
|
void CSVWorld::PreviewSubView::closeRequest()
|
||||||
|
{
|
||||||
|
deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::PreviewSubView::referenceableIdChanged (const std::string& id)
|
||||||
|
{
|
||||||
|
if (id.empty())
|
||||||
|
setWindowTitle ("Preview: Reference to <nothing>");
|
||||||
|
else
|
||||||
|
setWindowTitle (("Preview: Reference to " + id).c_str());
|
||||||
|
}
|
38
apps/opencs/view/world/previewsubview.hpp
Normal file
38
apps/opencs/view/world/previewsubview.hpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef CSV_WORLD_PREVIEWSUBVIEW_H
|
||||||
|
#define CSV_WORLD_PREVIEWSUBVIEW_H
|
||||||
|
|
||||||
|
#include "../doc/subview.hpp"
|
||||||
|
|
||||||
|
namespace CSMDoc
|
||||||
|
{
|
||||||
|
class Document;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class PreviewWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class PreviewSubView : public CSVDoc::SubView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
CSVRender::PreviewWidget *mScene;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
PreviewSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
|
||||||
|
|
||||||
|
virtual void setEditLock (bool locked);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void closeRequest();
|
||||||
|
|
||||||
|
void referenceableIdChanged (const std::string& id);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -9,7 +9,8 @@
|
||||||
|
|
||||||
#include "../filter/filterbox.hpp"
|
#include "../filter/filterbox.hpp"
|
||||||
|
|
||||||
#include "../render/scenewidget.hpp"
|
#include "../render/pagedworldspacewidget.hpp"
|
||||||
|
#include "../render/unpagedworldspacewidget.hpp"
|
||||||
|
|
||||||
#include "tablebottombox.hpp"
|
#include "tablebottombox.hpp"
|
||||||
#include "creator.hpp"
|
#include "creator.hpp"
|
||||||
|
@ -32,37 +33,23 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D
|
||||||
layout2->setContentsMargins (QMargins (0, 0, 0, 0));
|
layout2->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||||
|
|
||||||
SceneToolbar *toolbar = new SceneToolbar (48, this);
|
SceneToolbar *toolbar = new SceneToolbar (48, this);
|
||||||
// test
|
|
||||||
SceneToolMode *tool = new SceneToolMode (toolbar);
|
if (id.getId()=="sys::default")
|
||||||
tool->addButton (":door.png", "a");
|
mScene = new CSVRender::PagedWorldspaceWidget (this);
|
||||||
tool->addButton (":GMST.png", "b");
|
else
|
||||||
tool->addButton (":Info.png", "c");
|
mScene = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this);
|
||||||
toolbar->addTool (tool);
|
|
||||||
toolbar->addTool (new SceneToolMode (toolbar));
|
SceneToolMode *navigationTool = mScene->makeNavigationSelector (toolbar);
|
||||||
toolbar->addTool (new SceneToolMode (toolbar));
|
toolbar->addTool (navigationTool);
|
||||||
toolbar->addTool (new SceneToolMode (toolbar));
|
|
||||||
|
SceneToolMode *lightingTool = mScene->makeLightingSelector (toolbar);
|
||||||
|
toolbar->addTool (lightingTool);
|
||||||
|
|
||||||
layout2->addWidget (toolbar, 0);
|
layout2->addWidget (toolbar, 0);
|
||||||
|
|
||||||
// temporarily disable OGRE-integration (need to fix path problem first)
|
layout2->addWidget (mScene, 1);
|
||||||
#if 0
|
|
||||||
CSVRender::SceneWidget* sceneWidget = new CSVRender::SceneWidget(this);
|
|
||||||
|
|
||||||
layout2->addWidget (sceneWidget, 1);
|
|
||||||
|
|
||||||
layout->insertLayout (0, layout2, 1);
|
layout->insertLayout (0, layout2, 1);
|
||||||
#endif
|
|
||||||
/// \todo replace with rendering widget
|
|
||||||
QPalette palette2 (palette());
|
|
||||||
palette2.setColor (QPalette::Background, Qt::white);
|
|
||||||
QLabel *placeholder = new QLabel ("Here goes the 3D scene", this);
|
|
||||||
placeholder->setAutoFillBackground (true);
|
|
||||||
placeholder->setPalette (palette2);
|
|
||||||
placeholder->setAlignment (Qt::AlignHCenter);
|
|
||||||
|
|
||||||
layout2->addWidget (placeholder, 1);
|
|
||||||
|
|
||||||
layout->insertLayout (0, layout2, 1);
|
|
||||||
|
|
||||||
|
|
||||||
CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this);
|
CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this);
|
||||||
|
|
||||||
|
@ -73,6 +60,10 @@ toolbar->addTool (new SceneToolMode (toolbar));
|
||||||
widget->setLayout (layout);
|
widget->setLayout (layout);
|
||||||
|
|
||||||
setWidget (widget);
|
setWidget (widget);
|
||||||
|
|
||||||
|
mScene->selectDefaultNavigationMode();
|
||||||
|
|
||||||
|
connect (mScene, SIGNAL (closeRequest()), this, SLOT (closeRequest()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWorld::SceneSubView::setEditLock (bool locked)
|
void CSVWorld::SceneSubView::setEditLock (bool locked)
|
||||||
|
@ -91,3 +82,8 @@ void CSVWorld::SceneSubView::setStatusBar (bool show)
|
||||||
{
|
{
|
||||||
mBottom->setStatusBar (show);
|
mBottom->setStatusBar (show);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVWorld::SceneSubView::closeRequest()
|
||||||
|
{
|
||||||
|
deleteLater();
|
||||||
|
}
|
|
@ -10,6 +10,11 @@ namespace CSMDoc
|
||||||
class Document;
|
class Document;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class WorldspaceWidget;
|
||||||
|
}
|
||||||
|
|
||||||
namespace CSVWorld
|
namespace CSVWorld
|
||||||
{
|
{
|
||||||
class Table;
|
class Table;
|
||||||
|
@ -21,6 +26,7 @@ namespace CSVWorld
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
TableBottomBox *mBottom;
|
TableBottomBox *mBottom;
|
||||||
|
CSVRender::WorldspaceWidget *mScene;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -31,6 +37,10 @@ namespace CSVWorld
|
||||||
virtual void updateEditorSetting (const QString& key, const QString& value);
|
virtual void updateEditorSetting (const QString& key, const QString& value);
|
||||||
|
|
||||||
virtual void setStatusBar (bool show);
|
virtual void setStatusBar (bool show);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void closeRequest();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,9 +71,9 @@ void CSVWorld::ScriptEdit::dropEvent (QDropEvent* event)
|
||||||
{
|
{
|
||||||
if (stringNeedsQuote(it->getId()))
|
if (stringNeedsQuote(it->getId()))
|
||||||
{
|
{
|
||||||
insertPlainText(QString::fromStdString ('"' + it->getId() + '"'));
|
insertPlainText(QString::fromUtf8 (('"' + it->getId() + '"').c_str()));
|
||||||
} else {
|
} else {
|
||||||
insertPlainText(QString::fromStdString (it->getId()));
|
insertPlainText(QString::fromUtf8 (it->getId().c_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ void CSVWorld::ScriptEdit::dropEvent (QDropEvent* event)
|
||||||
|
|
||||||
bool CSVWorld::ScriptEdit::stringNeedsQuote (const std::string& id) const
|
bool CSVWorld::ScriptEdit::stringNeedsQuote (const std::string& id) const
|
||||||
{
|
{
|
||||||
const QString string(QString::fromStdString(id)); //<regex> is only for c++11, so let's use qregexp for now.
|
const QString string(QString::fromUtf8(id.c_str())); //<regex> is only for c++11, so let's use qregexp for now.
|
||||||
//I'm not quite sure when do we need to put quotes. To be safe we will use quotes for anything other than…
|
//I'm not quite sure when do we need to put quotes. To be safe we will use quotes for anything other than…
|
||||||
return !(string.contains(mWhiteListQoutes));
|
return !(string.contains(mWhiteListQoutes));
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "scenesubview.hpp"
|
#include "scenesubview.hpp"
|
||||||
#include "dialoguecreator.hpp"
|
#include "dialoguecreator.hpp"
|
||||||
#include "infocreator.hpp"
|
#include "infocreator.hpp"
|
||||||
|
#include "previewsubview.hpp"
|
||||||
|
|
||||||
void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
||||||
{
|
{
|
||||||
|
@ -78,4 +79,62 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
||||||
CreatorFactory<CSVFilter::FilterCreator> >);
|
CreatorFactory<CSVFilter::FilterCreator> >);
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory<SceneSubView>);
|
manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory<SceneSubView>);
|
||||||
|
|
||||||
|
//edit subviews
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Region,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Spell,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Referenceable,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<ReferenceableCreator> > (false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Birthsign,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Global,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Gmst,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Race,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Class,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Reference,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<ReferenceCreator> > (false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Cell,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<CellCreator> > (false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Filter,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Sound,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Faction,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Skill,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_JournalInfo,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<InfoCreator> > (false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_TopicInfo,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<InfoCreator> >(false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Topic,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, TopicCreatorFactory> (false));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Journal,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, JournalCreatorFactory> (false));
|
||||||
|
|
||||||
|
//preview
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Preview, new CSVDoc::SubViewFactory<PreviewSubView>);
|
||||||
}
|
}
|
|
@ -2,7 +2,6 @@
|
||||||
#include "table.hpp"
|
#include "table.hpp"
|
||||||
|
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
@ -10,6 +9,8 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QtCore/qnamespace.h>
|
#include <QtCore/qnamespace.h>
|
||||||
|
|
||||||
|
#include "../../model/doc/document.hpp"
|
||||||
|
|
||||||
#include "../../model/world/data.hpp"
|
#include "../../model/world/data.hpp"
|
||||||
#include "../../model/world/commands.hpp"
|
#include "../../model/world/commands.hpp"
|
||||||
#include "../../model/world/idtableproxymodel.hpp"
|
#include "../../model/world/idtableproxymodel.hpp"
|
||||||
|
@ -35,6 +36,7 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
||||||
if (selectedRows.size()==1)
|
if (selectedRows.size()==1)
|
||||||
{
|
{
|
||||||
menu.addAction (mEditAction);
|
menu.addAction (mEditAction);
|
||||||
|
|
||||||
if (mCreateAction)
|
if (mCreateAction)
|
||||||
menu.addAction(mCloneAction);
|
menu.addAction(mCloneAction);
|
||||||
}
|
}
|
||||||
|
@ -81,6 +83,28 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selectedRows.size()==1)
|
||||||
|
{
|
||||||
|
if (mModel->getViewing()!=CSMWorld::IdTable::Viewing_None)
|
||||||
|
{
|
||||||
|
int row = selectedRows.begin()->row();
|
||||||
|
|
||||||
|
row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row();
|
||||||
|
|
||||||
|
CSMWorld::UniversalId id = mModel->view (row).first;
|
||||||
|
|
||||||
|
int index = mDocument.getData().getCells().searchId (id.getId());
|
||||||
|
// index==-1: the ID references a worldspace instead of a cell (ignore for now and go
|
||||||
|
// ahead)
|
||||||
|
|
||||||
|
if (index==-1 || !mDocument.getData().getCells().getRecord (index).isDeleted())
|
||||||
|
menu.addAction (mViewAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mModel->hasPreview())
|
||||||
|
menu.addAction (mPreviewAction);
|
||||||
|
}
|
||||||
|
|
||||||
menu.exec (event->globalPos());
|
menu.exec (event->globalPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,11 +186,12 @@ std::vector<std::string> CSVWorld::Table::listDeletableSelectedIds() const
|
||||||
return deletableIds;
|
return deletableIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack,
|
CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
|
||||||
bool createAndDelete, bool sorting, const CSMDoc::Document& document)
|
bool createAndDelete, bool sorting, CSMDoc::Document& document)
|
||||||
: mUndoStack (undoStack), mCreateAction (0), mCloneAction(0), mEditLock (false), mRecordStatusDisplay (0), mDocument(document)
|
: mCreateAction (0), mCloneAction(0), mEditLock (false), mRecordStatusDisplay (0),
|
||||||
|
mDocument (document)
|
||||||
{
|
{
|
||||||
mModel = &dynamic_cast<CSMWorld::IdTable&> (*data.getTableModel (id));
|
mModel = &dynamic_cast<CSMWorld::IdTable&> (*mDocument.getData().getTableModel (id));
|
||||||
|
|
||||||
mProxyModel = new CSMWorld::IdTableProxyModel (this);
|
mProxyModel = new CSMWorld::IdTableProxyModel (this);
|
||||||
mProxyModel->setSourceModel (mModel);
|
mProxyModel->setSourceModel (mModel);
|
||||||
|
@ -190,7 +215,7 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, Q
|
||||||
mModel->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
|
mModel->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
|
||||||
|
|
||||||
CommandDelegate *delegate = CommandDelegateFactoryCollection::get().makeDelegate (display,
|
CommandDelegate *delegate = CommandDelegateFactoryCollection::get().makeDelegate (display,
|
||||||
undoStack, this);
|
mDocument.getUndoStack(), this);
|
||||||
|
|
||||||
mDelegates.push_back (delegate);
|
mDelegates.push_back (delegate);
|
||||||
setItemDelegateForColumn (i, delegate);
|
setItemDelegateForColumn (i, delegate);
|
||||||
|
@ -230,6 +255,14 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, Q
|
||||||
connect (mMoveDownAction, SIGNAL (triggered()), this, SLOT (moveDownRecord()));
|
connect (mMoveDownAction, SIGNAL (triggered()), this, SLOT (moveDownRecord()));
|
||||||
addAction (mMoveDownAction);
|
addAction (mMoveDownAction);
|
||||||
|
|
||||||
|
mViewAction = new QAction (tr ("View"), this);
|
||||||
|
connect (mViewAction, SIGNAL (triggered()), this, SLOT (viewRecord()));
|
||||||
|
addAction (mViewAction);
|
||||||
|
|
||||||
|
mPreviewAction = new QAction (tr ("Preview"), this);
|
||||||
|
connect (mPreviewAction, SIGNAL (triggered()), this, SLOT (previewRecord()));
|
||||||
|
addAction (mPreviewAction);
|
||||||
|
|
||||||
connect (mProxyModel, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
connect (mProxyModel, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
||||||
this, SLOT (tableSizeUpdate()));
|
this, SLOT (tableSizeUpdate()));
|
||||||
|
|
||||||
|
@ -256,7 +289,7 @@ CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const
|
||||||
{
|
{
|
||||||
return CSMWorld::UniversalId (
|
return CSMWorld::UniversalId (
|
||||||
static_cast<CSMWorld::UniversalId::Type> (mProxyModel->data (mProxyModel->index (row, 2)).toInt()),
|
static_cast<CSMWorld::UniversalId::Type> (mProxyModel->data (mProxyModel->index (row, 2)).toInt()),
|
||||||
mProxyModel->data (mProxyModel->index (row, 0)).toString().toStdString());
|
mProxyModel->data (mProxyModel->index (row, 0)).toString().toUtf8().constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWorld::Table::revertRecord()
|
void CSVWorld::Table::revertRecord()
|
||||||
|
@ -268,13 +301,13 @@ void CSVWorld::Table::revertRecord()
|
||||||
if (revertableIds.size()>0)
|
if (revertableIds.size()>0)
|
||||||
{
|
{
|
||||||
if (revertableIds.size()>1)
|
if (revertableIds.size()>1)
|
||||||
mUndoStack.beginMacro (tr ("Revert multiple records"));
|
mDocument.getUndoStack().beginMacro (tr ("Revert multiple records"));
|
||||||
|
|
||||||
for (std::vector<std::string>::const_iterator iter (revertableIds.begin()); iter!=revertableIds.end(); ++iter)
|
for (std::vector<std::string>::const_iterator iter (revertableIds.begin()); iter!=revertableIds.end(); ++iter)
|
||||||
mUndoStack.push (new CSMWorld::RevertCommand (*mModel, *iter));
|
mDocument.getUndoStack().push (new CSMWorld::RevertCommand (*mModel, *iter));
|
||||||
|
|
||||||
if (revertableIds.size()>1)
|
if (revertableIds.size()>1)
|
||||||
mUndoStack.endMacro();
|
mDocument.getUndoStack().endMacro();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -288,13 +321,13 @@ void CSVWorld::Table::deleteRecord()
|
||||||
if (deletableIds.size()>0)
|
if (deletableIds.size()>0)
|
||||||
{
|
{
|
||||||
if (deletableIds.size()>1)
|
if (deletableIds.size()>1)
|
||||||
mUndoStack.beginMacro (tr ("Delete multiple records"));
|
mDocument.getUndoStack().beginMacro (tr ("Delete multiple records"));
|
||||||
|
|
||||||
for (std::vector<std::string>::const_iterator iter (deletableIds.begin()); iter!=deletableIds.end(); ++iter)
|
for (std::vector<std::string>::const_iterator iter (deletableIds.begin()); iter!=deletableIds.end(); ++iter)
|
||||||
mUndoStack.push (new CSMWorld::DeleteCommand (*mModel, *iter));
|
mDocument.getUndoStack().push (new CSMWorld::DeleteCommand (*mModel, *iter));
|
||||||
|
|
||||||
if (deletableIds.size()>1)
|
if (deletableIds.size()>1)
|
||||||
mUndoStack.endMacro();
|
mDocument.getUndoStack().endMacro();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,7 +339,7 @@ void CSVWorld::Table::editRecord()
|
||||||
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||||
|
|
||||||
if (selectedRows.size()==1)
|
if (selectedRows.size()==1)
|
||||||
emit editRequest (selectedRows.begin()->row());
|
emit editRequest (getUniversalId (selectedRows.begin()->row()), "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,7 +380,7 @@ void CSVWorld::Table::moveUpRecord()
|
||||||
for (int i=1; i<row2-row; ++i)
|
for (int i=1; i<row2-row; ++i)
|
||||||
newOrder[i] = i;
|
newOrder[i] = i;
|
||||||
|
|
||||||
mUndoStack.push (new CSMWorld::ReorderRowsCommand (*mModel, row, newOrder));
|
mDocument.getUndoStack().push (new CSMWorld::ReorderRowsCommand (*mModel, row, newOrder));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -376,11 +409,40 @@ void CSVWorld::Table::moveDownRecord()
|
||||||
for (int i=1; i<row2-row; ++i)
|
for (int i=1; i<row2-row; ++i)
|
||||||
newOrder[i] = i;
|
newOrder[i] = i;
|
||||||
|
|
||||||
mUndoStack.push (new CSMWorld::ReorderRowsCommand (*mModel, row, newOrder));
|
mDocument.getUndoStack().push (new CSMWorld::ReorderRowsCommand (*mModel, row, newOrder));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVWorld::Table::viewRecord()
|
||||||
|
{
|
||||||
|
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||||
|
|
||||||
|
if (selectedRows.size()==1)
|
||||||
|
{
|
||||||
|
int row = selectedRows.begin()->row();
|
||||||
|
|
||||||
|
row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row();
|
||||||
|
|
||||||
|
std::pair<CSMWorld::UniversalId, std::string> params = mModel->view (row);
|
||||||
|
|
||||||
|
if (params.first.getType()!=CSMWorld::UniversalId::Type_None)
|
||||||
|
emit editRequest (params.first, params.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::Table::previewRecord()
|
||||||
|
{
|
||||||
|
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||||
|
|
||||||
|
if (selectedRows.size()==1)
|
||||||
|
{
|
||||||
|
std::string id = getUniversalId (selectedRows.begin()->row()).getId();
|
||||||
|
|
||||||
|
emit editRequest (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Preview, id) , "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CSVWorld::Table::updateEditorSetting (const QString &settingName, const QString &settingValue)
|
void CSVWorld::Table::updateEditorSetting (const QString &settingName, const QString &settingValue)
|
||||||
{
|
{
|
||||||
int columns = mModel->columnCount();
|
int columns = mModel->columnCount();
|
||||||
|
@ -471,21 +533,8 @@ void CSVWorld::Table::mouseMoveEvent (QMouseEvent* event)
|
||||||
}
|
}
|
||||||
|
|
||||||
drag->setMimeData (mime);
|
drag->setMimeData (mime);
|
||||||
drag->setPixmap (QString::fromStdString (mime->getIcon()));
|
drag->setPixmap (QString::fromUtf8 (mime->getIcon().c_str()));
|
||||||
|
drag->exec(Qt::CopyAction);
|
||||||
Qt::DropActions action = Qt::IgnoreAction;
|
|
||||||
switch (QApplication::keyboardModifiers())
|
|
||||||
{
|
|
||||||
case Qt::ControlModifier:
|
|
||||||
action = Qt::CopyAction;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::ShiftModifier:
|
|
||||||
action = Qt::MoveAction;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
drag->exec(action);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -517,7 +566,7 @@ void CSVWorld::Table::dropEvent(QDropEvent *event)
|
||||||
std::auto_ptr<CSMWorld::ModifyCommand> command (new CSMWorld::ModifyCommand
|
std::auto_ptr<CSMWorld::ModifyCommand> command (new CSMWorld::ModifyCommand
|
||||||
(*mProxyModel, index, QVariant (QString::fromUtf8 (record.getId().c_str()))));
|
(*mProxyModel, index, QVariant (QString::fromUtf8 (record.getId().c_str()))));
|
||||||
|
|
||||||
mUndoStack.push (command.release());
|
mDocument.getUndoStack().push (command.release());
|
||||||
}
|
}
|
||||||
} //TODO handle drops from different document
|
} //TODO handle drops from different document
|
||||||
}
|
}
|
||||||
|
@ -539,7 +588,7 @@ std::vector<std::string> CSVWorld::Table::getColumnsWithDisplay(CSMWorld::Column
|
||||||
|
|
||||||
if (display == columndisplay)
|
if (display == columndisplay)
|
||||||
{
|
{
|
||||||
titles.push_back(mModel->headerData (i, Qt::Horizontal).toString().toStdString());
|
titles.push_back(mModel->headerData (i, Qt::Horizontal).toString().toUtf8().constData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return titles;
|
return titles;
|
||||||
|
|
|
@ -10,13 +10,14 @@
|
||||||
#include "../../model/filter/node.hpp"
|
#include "../../model/filter/node.hpp"
|
||||||
#include "../../model/world/columnbase.hpp"
|
#include "../../model/world/columnbase.hpp"
|
||||||
|
|
||||||
namespace CSMDoc {
|
|
||||||
class Document;
|
|
||||||
}
|
|
||||||
|
|
||||||
class QUndoStack;
|
class QUndoStack;
|
||||||
class QAction;
|
class QAction;
|
||||||
|
|
||||||
|
namespace CSMDoc
|
||||||
|
{
|
||||||
|
class Document;
|
||||||
|
}
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
class Data;
|
class Data;
|
||||||
|
@ -35,7 +36,6 @@ namespace CSVWorld
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
std::vector<CommandDelegate *> mDelegates;
|
std::vector<CommandDelegate *> mDelegates;
|
||||||
QUndoStack& mUndoStack;
|
|
||||||
QAction *mEditAction;
|
QAction *mEditAction;
|
||||||
QAction *mCreateAction;
|
QAction *mCreateAction;
|
||||||
QAction *mCloneAction;
|
QAction *mCloneAction;
|
||||||
|
@ -43,14 +43,13 @@ namespace CSVWorld
|
||||||
QAction *mDeleteAction;
|
QAction *mDeleteAction;
|
||||||
QAction *mMoveUpAction;
|
QAction *mMoveUpAction;
|
||||||
QAction *mMoveDownAction;
|
QAction *mMoveDownAction;
|
||||||
|
QAction *mViewAction;
|
||||||
|
QAction *mPreviewAction;
|
||||||
CSMWorld::IdTableProxyModel *mProxyModel;
|
CSMWorld::IdTableProxyModel *mProxyModel;
|
||||||
CSMWorld::IdTable *mModel;
|
CSMWorld::IdTable *mModel;
|
||||||
bool mEditLock;
|
bool mEditLock;
|
||||||
int mRecordStatusDisplay;
|
int mRecordStatusDisplay;
|
||||||
|
CSMDoc::Document& mDocument;
|
||||||
/// \brief This variable is used exclusivly for checking if dropEvents came from the same document. Most likely you
|
|
||||||
/// should NOT use it for anything else.
|
|
||||||
const CSMDoc::Document& mDocument;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -70,9 +69,8 @@ namespace CSVWorld
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack, bool createAndDelete,
|
Table (const CSMWorld::UniversalId& id, bool createAndDelete,
|
||||||
bool sorting, const CSMDoc::Document& document);
|
bool sorting, CSMDoc::Document& document);
|
||||||
|
|
||||||
///< \param createAndDelete Allow creation and deletion of records.
|
///< \param createAndDelete Allow creation and deletion of records.
|
||||||
/// \param sorting Allow changing order of rows in the view via column headers.
|
/// \param sorting Allow changing order of rows in the view via column headers.
|
||||||
|
|
||||||
|
@ -86,7 +84,7 @@ namespace CSVWorld
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void editRequest (int row);
|
void editRequest (const CSMWorld::UniversalId& id, const std::string& hint);
|
||||||
|
|
||||||
void selectionSizeChanged (int size);
|
void selectionSizeChanged (int size);
|
||||||
|
|
||||||
|
@ -112,6 +110,10 @@ namespace CSVWorld
|
||||||
|
|
||||||
void moveDownRecord();
|
void moveDownRecord();
|
||||||
|
|
||||||
|
void viewRecord();
|
||||||
|
|
||||||
|
void previewRecord();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void tableSizeUpdate();
|
void tableSizeUpdate();
|
||||||
|
|
|
@ -24,7 +24,7 @@ CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::D
|
||||||
new TableBottomBox (creatorFactory, document.getData(), document.getUndoStack(), id, this), 0);
|
new TableBottomBox (creatorFactory, document.getData(), document.getUndoStack(), id, this), 0);
|
||||||
|
|
||||||
layout->insertWidget (0, mTable =
|
layout->insertWidget (0, mTable =
|
||||||
new Table (id, document.getData(), document.getUndoStack(), mBottom->canCreateAndDelete(), sorting, document), 2);
|
new Table (id, mBottom->canCreateAndDelete(), sorting, document), 2);
|
||||||
|
|
||||||
CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this);
|
CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this);
|
||||||
|
|
||||||
|
@ -36,7 +36,8 @@ CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::D
|
||||||
|
|
||||||
setWidget (widget);
|
setWidget (widget);
|
||||||
|
|
||||||
connect (mTable, SIGNAL (editRequest (int)), this, SLOT (editRequest (int)));
|
connect (mTable, SIGNAL (editRequest (const CSMWorld::UniversalId&, const std::string&)),
|
||||||
|
this, SLOT (editRequest (const CSMWorld::UniversalId&, const std::string&)));
|
||||||
|
|
||||||
connect (mTable, SIGNAL (selectionSizeChanged (int)),
|
connect (mTable, SIGNAL (selectionSizeChanged (int)),
|
||||||
mBottom, SLOT (selectionSizeChanged (int)));
|
mBottom, SLOT (selectionSizeChanged (int)));
|
||||||
|
@ -81,9 +82,9 @@ void CSVWorld::TableSubView::setEditLock (bool locked)
|
||||||
mBottom->setEditLock (locked);
|
mBottom->setEditLock (locked);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWorld::TableSubView::editRequest (int row)
|
void CSVWorld::TableSubView::editRequest (const CSMWorld::UniversalId& id, const std::string& hint)
|
||||||
{
|
{
|
||||||
focusId (mTable->getUniversalId (row));
|
focusId (id, hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWorld::TableSubView::updateEditorSetting(const QString &settingName, const QString &settingValue)
|
void CSVWorld::TableSubView::updateEditorSetting(const QString &settingName, const QString &settingValue)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "../doc/subview.hpp"
|
#include "../doc/subview.hpp"
|
||||||
|
|
||||||
#include <qt4/QtCore/qnamespace.h>
|
#include <QtCore/qnamespace.h>
|
||||||
|
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ namespace CSVWorld
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void editRequest (int row);
|
void editRequest (const CSMWorld::UniversalId& id, const std::string& hint);
|
||||||
void cloneRequest (const CSMWorld::UniversalId& toClone);
|
void cloneRequest (const CSMWorld::UniversalId& toClone);
|
||||||
void createFilterRequest(std::vector< CSMWorld::UniversalId >& types,
|
void createFilterRequest(std::vector< CSMWorld::UniversalId >& types,
|
||||||
Qt::DropAction action);
|
Qt::DropAction action);
|
||||||
|
|
|
@ -4,8 +4,18 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include <QUndoStack>
|
#include <QUndoStack>
|
||||||
|
#include <QMetaProperty>
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
#include <QEvent>
|
||||||
|
|
||||||
#include "../../model/world/commands.hpp"
|
#include "../../model/world/commands.hpp"
|
||||||
|
#include "../../model/world/tablemimedata.hpp"
|
||||||
|
|
||||||
CSVWorld::NastyTableModelHack::NastyTableModelHack (QAbstractItemModel& model)
|
CSVWorld::NastyTableModelHack::NastyTableModelHack (QAbstractItemModel& model)
|
||||||
: mModel (model)
|
: mModel (model)
|
||||||
|
@ -117,10 +127,56 @@ void CSVWorld::CommandDelegate::setModelData (QWidget *editor, QAbstractItemMode
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem& option,
|
QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem& option,
|
||||||
const QModelIndex& index) const
|
const QModelIndex& index, CSMWorld::ColumnBase::Display display) const
|
||||||
|
{
|
||||||
|
QVariant variant = index.data();
|
||||||
|
if (!variant.isValid())
|
||||||
|
{
|
||||||
|
variant = index.data(Qt::DisplayRole);
|
||||||
|
if (!variant.isValid())
|
||||||
{
|
{
|
||||||
if (!index.data().isValid())
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (display != CSMWorld::ColumnBase::Display_None)
|
||||||
|
{
|
||||||
|
if (variant.type() == QVariant::Color)
|
||||||
|
{
|
||||||
|
return new QLineEdit(parent);
|
||||||
|
}
|
||||||
|
if (display == CSMWorld::ColumnBase::Display_Integer)
|
||||||
|
{
|
||||||
|
return new QSpinBox(parent);
|
||||||
|
}
|
||||||
|
if (display == CSMWorld::ColumnBase::Display_Var)
|
||||||
|
{
|
||||||
|
return new QLineEdit(parent);
|
||||||
|
}
|
||||||
|
if (display == CSMWorld::ColumnBase::Display_Float)
|
||||||
|
{
|
||||||
|
return new QDoubleSpinBox(parent);
|
||||||
|
}
|
||||||
|
if (display == CSMWorld::ColumnBase::Display_LongString)
|
||||||
|
{
|
||||||
|
return new QTextEdit(parent);
|
||||||
|
}
|
||||||
|
if (display == CSMWorld::ColumnBase::Display_String ||
|
||||||
|
display == CSMWorld::ColumnBase::Display_Skill ||
|
||||||
|
display == CSMWorld::ColumnBase::Display_Script ||
|
||||||
|
display == CSMWorld::ColumnBase::Display_Race ||
|
||||||
|
display == CSMWorld::ColumnBase::Display_Class ||
|
||||||
|
display == CSMWorld::ColumnBase::Display_Faction ||
|
||||||
|
display == CSMWorld::ColumnBase::Display_Miscellaneous ||
|
||||||
|
display == CSMWorld::ColumnBase::Display_Sound)
|
||||||
|
{
|
||||||
|
return new DropLineEdit(parent);
|
||||||
|
}
|
||||||
|
if (display == CSMWorld::ColumnBase::Display_Boolean)
|
||||||
|
{
|
||||||
|
return new QCheckBox(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return QStyledItemDelegate::createEditor (parent, option, index);
|
return QStyledItemDelegate::createEditor (parent, option, index);
|
||||||
}
|
}
|
||||||
|
@ -141,3 +197,66 @@ bool CSVWorld::CommandDelegate::updateEditorSetting (const QString &settingName,
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay) const
|
||||||
|
{
|
||||||
|
QVariant v = index.data(Qt::EditRole);
|
||||||
|
if (tryDisplay)
|
||||||
|
{
|
||||||
|
if (!v.isValid())
|
||||||
|
{
|
||||||
|
v = index.data(Qt::DisplayRole);
|
||||||
|
if (!v.isValid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QPlainTextEdit* plainTextEdit = qobject_cast<QPlainTextEdit*>(editor);
|
||||||
|
if(plainTextEdit) //for some reason it is easier to brake the loop here
|
||||||
|
{
|
||||||
|
if(plainTextEdit->toPlainText() == v.toString())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray n = editor->metaObject()->userProperty().name();
|
||||||
|
|
||||||
|
if (n == "dateTime") {
|
||||||
|
if (editor->inherits("QTimeEdit"))
|
||||||
|
n = "time";
|
||||||
|
else if (editor->inherits("QDateEdit"))
|
||||||
|
n = "date";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!n.isEmpty()) {
|
||||||
|
if (!v.isValid())
|
||||||
|
v = QVariant(editor->property(n).userType(), (const void *)0);
|
||||||
|
editor->setProperty(n, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::DropLineEdit::DropLineEdit(QWidget* parent) :
|
||||||
|
QLineEdit(parent)
|
||||||
|
{
|
||||||
|
setAcceptDrops(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DropLineEdit::dragEnterEvent(QDragEnterEvent *event)
|
||||||
|
{
|
||||||
|
event->acceptProposedAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DropLineEdit::dragMoveEvent(QDragMoveEvent *event)
|
||||||
|
{
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DropLineEdit::dropEvent(QDropEvent *event)
|
||||||
|
{
|
||||||
|
const CSMWorld::TableMimeData* data(dynamic_cast<const CSMWorld::TableMimeData*>(event->mimeData()));
|
||||||
|
emit tableMimeDataDropped(data->getData(), data->getDocumentPtr());
|
||||||
|
//WIP
|
||||||
|
}
|
|
@ -5,11 +5,19 @@
|
||||||
|
|
||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
#include <QStyledItemDelegate>
|
#include <QStyledItemDelegate>
|
||||||
|
#include <QLineEdit>
|
||||||
|
|
||||||
#include "../../model/world/columnbase.hpp"
|
#include "../../model/world/columnbase.hpp"
|
||||||
|
#include "../../model/doc/document.hpp"
|
||||||
|
|
||||||
class QUndoStack;
|
class QUndoStack;
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class TableMimeData;
|
||||||
|
class UniversalId;
|
||||||
|
}
|
||||||
|
|
||||||
namespace CSVWorld
|
namespace CSVWorld
|
||||||
{
|
{
|
||||||
///< \brief Getting the data out of an editor widget
|
///< \brief Getting the data out of an editor widget
|
||||||
|
@ -79,6 +87,24 @@ namespace CSVWorld
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DropLineEdit : public QLineEdit
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
DropLineEdit(QWidget *parent);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void dragEnterEvent(QDragEnterEvent *event);
|
||||||
|
|
||||||
|
void dragMoveEvent(QDragMoveEvent *event);
|
||||||
|
|
||||||
|
void dropEvent(QDropEvent *event);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void tableMimeDataDropped(const std::vector<CSMWorld::UniversalId>& data, const CSMDoc::Document* document);
|
||||||
|
};
|
||||||
|
|
||||||
///< \brief Use commands instead of manipulating the model directly
|
///< \brief Use commands instead of manipulating the model directly
|
||||||
class CommandDelegate : public QStyledItemDelegate
|
class CommandDelegate : public QStyledItemDelegate
|
||||||
{
|
{
|
||||||
|
@ -101,8 +127,10 @@ namespace CSVWorld
|
||||||
virtual void setModelData (QWidget *editor, QAbstractItemModel *model,
|
virtual void setModelData (QWidget *editor, QAbstractItemModel *model,
|
||||||
const QModelIndex& index) const;
|
const QModelIndex& index) const;
|
||||||
|
|
||||||
virtual QWidget *createEditor (QWidget *parent, const QStyleOptionViewItem& option,
|
virtual QWidget *createEditor (QWidget *parent,
|
||||||
const QModelIndex& index) const;
|
const QStyleOptionViewItem& option,
|
||||||
|
const QModelIndex& index,
|
||||||
|
CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None) const;
|
||||||
|
|
||||||
void setEditLock (bool locked);
|
void setEditLock (bool locked);
|
||||||
|
|
||||||
|
@ -111,6 +139,9 @@ namespace CSVWorld
|
||||||
virtual bool updateEditorSetting (const QString &settingName, const QString &settingValue);
|
virtual bool updateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||||
///< \return Does column require update?
|
///< \return Does column require update?
|
||||||
|
|
||||||
|
virtual void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay = false) const;
|
||||||
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
virtual void slotUpdateEditorSetting (const QString &settingName, const QString &settingValue) {}
|
virtual void slotUpdateEditorSetting (const QString &settingName, const QString &settingValue) {}
|
||||||
|
|
|
@ -15,7 +15,7 @@ add_openmw_dir (mwrender
|
||||||
renderingmanager debugging sky camera animation npcanimation creatureanimation activatoranimation
|
renderingmanager debugging sky camera animation npcanimation creatureanimation activatoranimation
|
||||||
actors objects renderinginterface localmap occlusionquery water shadows
|
actors objects renderinginterface localmap occlusionquery water shadows
|
||||||
characterpreview globalmap videoplayer ripplesimulation refraction
|
characterpreview globalmap videoplayer ripplesimulation refraction
|
||||||
terrainstorage renderconst effectmanager
|
terrainstorage renderconst effectmanager weaponanimation
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwinput
|
add_openmw_dir (mwinput
|
||||||
|
@ -33,7 +33,7 @@ add_openmw_dir (mwgui
|
||||||
merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks
|
merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks
|
||||||
keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
|
keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
|
||||||
tradeitemmodel companionitemmodel pickpocketitemmodel fontloader controllers savegamedialog
|
tradeitemmodel companionitemmodel pickpocketitemmodel fontloader controllers savegamedialog
|
||||||
recharge
|
recharge mode videowidget
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwdialogue
|
add_openmw_dir (mwdialogue
|
||||||
|
@ -44,7 +44,7 @@ add_openmw_dir (mwscript
|
||||||
locals scriptmanagerimp compilercontext interpretercontext cellextensions miscextensions
|
locals scriptmanagerimp compilercontext interpretercontext cellextensions miscextensions
|
||||||
guiextensions soundextensions skyextensions statsextensions containerextensions
|
guiextensions soundextensions skyextensions statsextensions containerextensions
|
||||||
aiextensions controlextensions extensions globalscripts ref dialogueextensions
|
aiextensions controlextensions extensions globalscripts ref dialogueextensions
|
||||||
animationextensions transformationextensions consoleextensions userextensions locals
|
animationextensions transformationextensions consoleextensions userextensions
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwsound
|
add_openmw_dir (mwsound
|
||||||
|
@ -57,7 +57,7 @@ add_openmw_dir (mwworld
|
||||||
cells localscripts customdata weather inventorystore ptr actionopen actionread
|
cells localscripts customdata weather inventorystore ptr actionopen actionread
|
||||||
actionequip timestamp actionalchemy cellstore actionapply actioneat
|
actionequip timestamp actionalchemy cellstore actionapply actioneat
|
||||||
esmstore store recordcmp fallback actionrepair actionsoulgem livecellref actiondoor
|
esmstore store recordcmp fallback actionrepair actionsoulgem livecellref actiondoor
|
||||||
contentloader esmloader omwloader actiontrap
|
contentloader esmloader omwloader actiontrap cellreflist
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwclass
|
add_openmw_dir (mwclass
|
||||||
|
@ -159,3 +159,10 @@ if (BUILD_WITH_CODE_COVERAGE)
|
||||||
add_definitions (--coverage)
|
add_definitions (--coverage)
|
||||||
target_link_libraries(openmw gcov)
|
target_link_libraries(openmw gcov)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
# Debug version needs increased number of sections beyond 2^16
|
||||||
|
if (CMAKE_CL_64)
|
||||||
|
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj")
|
||||||
|
endif (CMAKE_CL_64)
|
||||||
|
endif (MSVC)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "engine.hpp"
|
#include "engine.hpp"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
#include <OgreRenderWindow.h>
|
#include <OgreRenderWindow.h>
|
||||||
|
@ -11,7 +12,7 @@
|
||||||
|
|
||||||
#include <components/compiler/extensions0.hpp>
|
#include <components/compiler/extensions0.hpp>
|
||||||
|
|
||||||
#include <components/bsa/bsa_archive.hpp>
|
#include <components/bsa/resources.hpp>
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
#include <components/translation/translation.hpp>
|
#include <components/translation/translation.hpp>
|
||||||
#include <components/nif/niffile.hpp>
|
#include <components/nif/niffile.hpp>
|
||||||
|
@ -191,50 +192,6 @@ OMW::Engine::~Engine()
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load BSA files
|
|
||||||
|
|
||||||
void OMW::Engine::loadBSA()
|
|
||||||
{
|
|
||||||
// We use separate resource groups to handle location priority.
|
|
||||||
const Files::PathContainer& dataDirs = mFileCollections.getPaths();
|
|
||||||
|
|
||||||
int i=0;
|
|
||||||
for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter)
|
|
||||||
{
|
|
||||||
// Last data dir has the highest priority
|
|
||||||
std::string groupName = "Data" + Ogre::StringConverter::toString(dataDirs.size()-i, 8, '0');
|
|
||||||
Ogre::ResourceGroupManager::getSingleton ().createResourceGroup (groupName);
|
|
||||||
|
|
||||||
std::string dataDirectory = iter->string();
|
|
||||||
std::cout << "Data dir " << dataDirectory << std::endl;
|
|
||||||
Bsa::addDir(dataDirectory, mFSStrict, groupName);
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
i=0;
|
|
||||||
for (std::vector<std::string>::const_iterator archive = mArchives.begin(); archive != mArchives.end(); ++archive)
|
|
||||||
{
|
|
||||||
if (mFileCollections.doesExist(*archive))
|
|
||||||
{
|
|
||||||
// Last BSA has the highest priority
|
|
||||||
std::string groupName = "DataBSA" + Ogre::StringConverter::toString(mArchives.size()-i, 8, '0');
|
|
||||||
|
|
||||||
Ogre::ResourceGroupManager::getSingleton ().createResourceGroup (groupName);
|
|
||||||
|
|
||||||
const std::string archivePath = mFileCollections.getPath(*archive).string();
|
|
||||||
std::cout << "Adding BSA archive " << archivePath << std::endl;
|
|
||||||
Bsa::addBSA(archivePath, groupName);
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::stringstream message;
|
|
||||||
message << "Archive '" << *archive << "' not found";
|
|
||||||
throw std::runtime_error(message.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add resources directory
|
// add resources directory
|
||||||
// \note This function works recursively.
|
// \note This function works recursively.
|
||||||
|
|
||||||
|
@ -382,10 +339,12 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||||
std::string aa = settings.getString("antialiasing", "Video");
|
std::string aa = settings.getString("antialiasing", "Video");
|
||||||
windowSettings.fsaa = (aa.substr(0, 4) == "MSAA") ? aa.substr(5, aa.size()-5) : "0";
|
windowSettings.fsaa = (aa.substr(0, 4) == "MSAA") ? aa.substr(5, aa.size()-5) : "0";
|
||||||
|
|
||||||
|
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS,
|
||||||
|
settings.getBool("minimize on focus loss", "Video") ? "1" : "0");
|
||||||
|
|
||||||
mOgre->createWindow("OpenMW", windowSettings);
|
mOgre->createWindow("OpenMW", windowSettings);
|
||||||
|
|
||||||
loadBSA();
|
Bsa::registerResources (mFileCollections, mArchives, true, mFSStrict);
|
||||||
|
|
||||||
|
|
||||||
// Create input and UI first to set up a bootstrapping environment for
|
// Create input and UI first to set up a bootstrapping environment for
|
||||||
// showing a loading screen and keeping the window responsive while doing so
|
// showing a loading screen and keeping the window responsive while doing so
|
||||||
|
@ -400,10 +359,20 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||||
mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage, mEncoding);
|
mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage, mEncoding);
|
||||||
mEnvironment.setWindowManager (window);
|
mEnvironment.setWindowManager (window);
|
||||||
|
|
||||||
|
// Create sound system
|
||||||
|
mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound));
|
||||||
|
|
||||||
|
if (!mSkipMenu)
|
||||||
|
{
|
||||||
|
std::string logo = mFallbackMap["Movies_Company_Logo"];
|
||||||
|
if (!logo.empty())
|
||||||
|
window->playVideo(logo, 1);
|
||||||
|
}
|
||||||
|
|
||||||
// Create the world
|
// Create the world
|
||||||
mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mContentFiles,
|
mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mContentFiles,
|
||||||
mResDir, mCfgMgr.getCachePath(), mEncoder, mFallbackMap,
|
mResDir, mCfgMgr.getCachePath(), mEncoder, mFallbackMap,
|
||||||
mActivationDistanceOverride));
|
mActivationDistanceOverride, mCellName));
|
||||||
MWBase::Environment::get().getWorld()->setupPlayer();
|
MWBase::Environment::get().getWorld()->setupPlayer();
|
||||||
input->setPlayer(&mEnvironment.getWorld()->getPlayer());
|
input->setPlayer(&mEnvironment.getWorld()->getPlayer());
|
||||||
|
|
||||||
|
@ -417,9 +386,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||||
|
|
||||||
Compiler::registerExtensions (mExtensions);
|
Compiler::registerExtensions (mExtensions);
|
||||||
|
|
||||||
// Create sound system
|
|
||||||
mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound));
|
|
||||||
|
|
||||||
// Create script system
|
// Create script system
|
||||||
mScriptContext = new MWScript::CompilerContext (MWScript::CompilerContext::Type_Full);
|
mScriptContext = new MWScript::CompilerContext (MWScript::CompilerContext::Type_Full);
|
||||||
mScriptContext->setExtensions (&mExtensions);
|
mScriptContext->setExtensions (&mExtensions);
|
||||||
|
@ -439,31 +405,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||||
mechanics->buildPlayer();
|
mechanics->buildPlayer();
|
||||||
window->updatePlayer();
|
window->updatePlayer();
|
||||||
|
|
||||||
// load cell
|
|
||||||
ESM::Position pos;
|
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
|
||||||
|
|
||||||
if (!mCellName.empty())
|
|
||||||
{
|
|
||||||
if (world->findExteriorPosition(mCellName, pos)) {
|
|
||||||
world->changeToExteriorCell (pos);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
world->findInteriorPosition(mCellName, pos);
|
|
||||||
world->changeToInteriorCell (mCellName, pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pos.pos[0] = pos.pos[1] = pos.pos[2] = 0;
|
|
||||||
pos.rot[0] = pos.rot[1] = pos.pos[2] = 0;
|
|
||||||
world->changeToExteriorCell (pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ogre::FrameEvent event;
|
|
||||||
event.timeSinceLastEvent = 0;
|
|
||||||
event.timeSinceLastFrame = 0;
|
|
||||||
frameRenderingQueued(event);
|
|
||||||
mOgre->getRoot()->addFrameListener (this);
|
mOgre->getRoot()->addFrameListener (this);
|
||||||
|
|
||||||
// scripts
|
// scripts
|
||||||
|
@ -501,15 +442,27 @@ void OMW::Engine::go()
|
||||||
// Play some good 'ol tunes
|
// Play some good 'ol tunes
|
||||||
MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Explore"));
|
MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Explore"));
|
||||||
|
|
||||||
if (!mStartupScript.empty())
|
|
||||||
MWBase::Environment::get().getWindowManager()->executeInConsole (mStartupScript);
|
|
||||||
|
|
||||||
// start in main menu
|
// start in main menu
|
||||||
if (!mSkipMenu)
|
if (!mSkipMenu)
|
||||||
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu);
|
MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Is there an ini setting for this filename or something?
|
||||||
|
MWBase::Environment::get().getSoundManager()->streamMusic("Special/morrowind title.mp3");
|
||||||
|
|
||||||
|
std::string logo = mFallbackMap["Movies_Morrowind_Logo"];
|
||||||
|
if (!logo.empty())
|
||||||
|
MWBase::Environment::get().getWindowManager()->playVideo(logo, true);
|
||||||
|
}
|
||||||
|
catch (...) {}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
MWBase::Environment::get().getStateManager()->newGame (true);
|
MWBase::Environment::get().getStateManager()->newGame (true);
|
||||||
|
|
||||||
|
if (!mStartupScript.empty())
|
||||||
|
MWBase::Environment::get().getWindowManager()->executeInConsole (mStartupScript);
|
||||||
|
|
||||||
// Start the main rendering loop
|
// Start the main rendering loop
|
||||||
while (!mEnvironment.get().getStateManager()->hasQuitRequest())
|
while (!mEnvironment.get().getStateManager()->hasQuitRequest())
|
||||||
Ogre::Root::getSingleton().renderOneFrame();
|
Ogre::Root::getSingleton().renderOneFrame();
|
||||||
|
|
|
@ -101,9 +101,6 @@ namespace OMW
|
||||||
/// add a .zip resource
|
/// add a .zip resource
|
||||||
void addZipResource (const boost::filesystem::path& path);
|
void addZipResource (const boost::filesystem::path& path);
|
||||||
|
|
||||||
/// Load BSA files
|
|
||||||
void loadBSA();
|
|
||||||
|
|
||||||
void executeLocalScripts();
|
void executeLocalScripts();
|
||||||
|
|
||||||
virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt);
|
virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <libs/platform/stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,9 +20,12 @@ namespace MWBase
|
||||||
|
|
||||||
InputManager() {}
|
InputManager() {}
|
||||||
|
|
||||||
|
/// Clear all savegame-specific data
|
||||||
|
virtual void clear() = 0;
|
||||||
|
|
||||||
virtual ~InputManager() {}
|
virtual ~InputManager() {}
|
||||||
|
|
||||||
virtual void update(float dt, bool loading) = 0;
|
virtual void update(float dt, bool disableControls, bool disableEvents=false) = 0;
|
||||||
|
|
||||||
virtual void changeInputMode(bool guiMode) = 0;
|
virtual void changeInputMode(bool guiMode) = 0;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <libs/platform/stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "../mwdialogue/journalentry.hpp"
|
#include "../mwdialogue/journalentry.hpp"
|
||||||
#include "../mwdialogue/topic.hpp"
|
#include "../mwdialogue/topic.hpp"
|
||||||
|
|
|
@ -156,7 +156,7 @@ namespace MWBase
|
||||||
/// paused we may want to do it manually (after equipping permanent enchantment)
|
/// paused we may want to do it manually (after equipping permanent enchantment)
|
||||||
virtual void updateMagicEffects (const MWWorld::Ptr& ptr) = 0;
|
virtual void updateMagicEffects (const MWWorld::Ptr& ptr) = 0;
|
||||||
|
|
||||||
virtual void toggleAI() = 0;
|
virtual bool toggleAI() = 0;
|
||||||
virtual bool isAIActive() = 0;
|
virtual bool isAIActive() = 0;
|
||||||
|
|
||||||
virtual void getObjectsInRange (const Ogre::Vector3& position, float radius, std::vector<MWWorld::Ptr>& objects) = 0;
|
virtual void getObjectsInRange (const Ogre::Vector3& position, float radius, std::vector<MWWorld::Ptr>& objects) = 0;
|
||||||
|
|
|
@ -96,6 +96,10 @@ namespace MWBase
|
||||||
*/
|
*/
|
||||||
virtual void update() = 0;
|
virtual void update() = 0;
|
||||||
|
|
||||||
|
/// @note This method will block until the video finishes playing
|
||||||
|
/// (and will continually update the window while doing so)
|
||||||
|
virtual void playVideo(const std::string& name, bool allowSkipping) = 0;
|
||||||
|
|
||||||
virtual void setNewGame(bool newgame) = 0;
|
virtual void setNewGame(bool newgame) = 0;
|
||||||
|
|
||||||
virtual void pushGuiMode (MWGui::GuiMode mode) = 0;
|
virtual void pushGuiMode (MWGui::GuiMode mode) = 0;
|
||||||
|
|
|
@ -39,6 +39,12 @@ namespace ESM
|
||||||
struct Spell;
|
struct Spell;
|
||||||
struct NPC;
|
struct NPC;
|
||||||
struct CellId;
|
struct CellId;
|
||||||
|
struct Armor;
|
||||||
|
struct Weapon;
|
||||||
|
struct Clothing;
|
||||||
|
struct Enchantment;
|
||||||
|
struct Book;
|
||||||
|
struct EffectList;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
|
@ -95,7 +101,8 @@ namespace MWBase
|
||||||
|
|
||||||
virtual ~World() {}
|
virtual ~World() {}
|
||||||
|
|
||||||
virtual void startNewGame() = 0;
|
virtual void startNewGame (bool bypass) = 0;
|
||||||
|
///< \param bypass Bypass regular game start.
|
||||||
|
|
||||||
virtual void clear() = 0;
|
virtual void clear() = 0;
|
||||||
|
|
||||||
|
@ -268,7 +275,7 @@ namespace MWBase
|
||||||
virtual void moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0;
|
virtual void moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0;
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
moveObject(const MWWorld::Ptr &ptr, MWWorld::CellStore &newCell, float x, float y, float z) = 0;
|
moveObject(const MWWorld::Ptr &ptr, MWWorld::CellStore* newCell, float x, float y, float z) = 0;
|
||||||
|
|
||||||
virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0;
|
virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0;
|
||||||
|
|
||||||
|
@ -276,7 +283,7 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void localRotateObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0;
|
virtual void localRotateObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0;
|
||||||
|
|
||||||
virtual MWWorld::Ptr safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos) = 0;
|
virtual MWWorld::Ptr safePlaceObject(const MWWorld::Ptr& ptr, MWWorld::CellStore* cell, ESM::Position pos) = 0;
|
||||||
///< place an object in a "safe" location (ie not in the void, etc).
|
///< place an object in a "safe" location (ie not in the void, etc).
|
||||||
|
|
||||||
virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false)
|
virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false)
|
||||||
|
@ -413,8 +420,6 @@ namespace MWBase
|
||||||
virtual MWRender::Animation* getAnimation(const MWWorld::Ptr &ptr) = 0;
|
virtual MWRender::Animation* getAnimation(const MWWorld::Ptr &ptr) = 0;
|
||||||
|
|
||||||
/// \todo this does not belong here
|
/// \todo this does not belong here
|
||||||
virtual void playVideo(const std::string& name, bool allowSkipping) = 0;
|
|
||||||
virtual void stopVideo() = 0;
|
|
||||||
virtual void frameStarted (float dt, bool paused) = 0;
|
virtual void frameStarted (float dt, bool paused) = 0;
|
||||||
virtual void screenshot (Ogre::Image& image, int w, int h) = 0;
|
virtual void screenshot (Ogre::Image& image, int w, int h) = 0;
|
||||||
|
|
||||||
|
@ -458,8 +463,10 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void castSpell (const MWWorld::Ptr& actor) = 0;
|
virtual void castSpell (const MWWorld::Ptr& actor) = 0;
|
||||||
|
|
||||||
virtual void launchProjectile (const std::string& id, bool stack, const ESM::EffectList& effects,
|
virtual void launchMagicBolt (const std::string& id, bool stack, const ESM::EffectList& effects,
|
||||||
const MWWorld::Ptr& actor, const std::string& sourceName) = 0;
|
const MWWorld::Ptr& actor, const std::string& sourceName) = 0;
|
||||||
|
virtual void launchProjectile (MWWorld::Ptr actor, MWWorld::Ptr projectile,
|
||||||
|
const Ogre::Vector3& worldPos, const Ogre::Quaternion& orient, MWWorld::Ptr bow, float speed) = 0;
|
||||||
|
|
||||||
virtual const std::vector<std::string>& getContentFiles() const = 0;
|
virtual const std::vector<std::string>& getContentFiles() const = 0;
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,6 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Activator> *ref =
|
MWWorld::LiveCellRef<ESM::Activator> *ref =
|
||||||
ptr.get<ESM::Activator>();
|
ptr.get<ESM::Activator>();
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mActivators.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.get<ESM::Activator>().insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,7 +148,7 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Apparatus> *ref =
|
MWWorld::LiveCellRef<ESM::Apparatus> *ref =
|
||||||
ptr.get<ESM::Apparatus>();
|
ptr.get<ESM::Apparatus>();
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mAppas.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.get<ESM::Apparatus>().insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Apparatus::canSell (const MWWorld::Ptr& item, int npcServices) const
|
bool Apparatus::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
|
|
@ -363,7 +363,7 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Armor> *ref =
|
MWWorld::LiveCellRef<ESM::Armor> *ref =
|
||||||
ptr.get<ESM::Armor>();
|
ptr.get<ESM::Armor>();
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mArmors.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.get<ESM::Armor>().insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Armor::getEnchantmentPoints (const MWWorld::Ptr& ptr) const
|
int Armor::getEnchantmentPoints (const MWWorld::Ptr& ptr) const
|
||||||
|
|
|
@ -186,7 +186,7 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Book> *ref =
|
MWWorld::LiveCellRef<ESM::Book> *ref =
|
||||||
ptr.get<ESM::Book>();
|
ptr.get<ESM::Book>();
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mBooks.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.get<ESM::Book>().insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Book::getEnchantmentPoints (const MWWorld::Ptr& ptr) const
|
int Book::getEnchantmentPoints (const MWWorld::Ptr& ptr) const
|
||||||
|
|
|
@ -276,7 +276,7 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Clothing> *ref =
|
MWWorld::LiveCellRef<ESM::Clothing> *ref =
|
||||||
ptr.get<ESM::Clothing>();
|
ptr.get<ESM::Clothing>();
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mClothes.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.get<ESM::Clothing>().insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Clothing::getEnchantmentPoints (const MWWorld::Ptr& ptr) const
|
int Clothing::getEnchantmentPoints (const MWWorld::Ptr& ptr) const
|
||||||
|
|
|
@ -28,16 +28,16 @@
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
struct CustomData : public MWWorld::CustomData
|
struct ContainerCustomData : public MWWorld::CustomData
|
||||||
{
|
{
|
||||||
MWWorld::ContainerStore mContainerStore;
|
MWWorld::ContainerStore mContainerStore;
|
||||||
|
|
||||||
virtual MWWorld::CustomData *clone() const;
|
virtual MWWorld::CustomData *clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
MWWorld::CustomData *CustomData::clone() const
|
MWWorld::CustomData *ContainerCustomData::clone() const
|
||||||
{
|
{
|
||||||
return new CustomData (*this);
|
return new ContainerCustomData (*this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
if (!ptr.getRefData().getCustomData())
|
if (!ptr.getRefData().getCustomData())
|
||||||
{
|
{
|
||||||
std::auto_ptr<CustomData> data (new CustomData);
|
std::auto_ptr<ContainerCustomData> data (new ContainerCustomData);
|
||||||
|
|
||||||
MWWorld::LiveCellRef<ESM::Container> *ref =
|
MWWorld::LiveCellRef<ESM::Container> *ref =
|
||||||
ptr.get<ESM::Container>();
|
ptr.get<ESM::Container>();
|
||||||
|
@ -174,7 +174,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
||||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mContainerStore;
|
return dynamic_cast<ContainerCustomData&> (*ptr.getRefData().getCustomData()).mContainerStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Container::getScript (const MWWorld::Ptr& ptr) const
|
std::string Container::getScript (const MWWorld::Ptr& ptr) const
|
||||||
|
@ -257,7 +257,7 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Container> *ref =
|
MWWorld::LiveCellRef<ESM::Container> *ref =
|
||||||
ptr.get<ESM::Container>();
|
ptr.get<ESM::Container>();
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mContainers.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.get<ESM::Container>().insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state)
|
void Container::readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state)
|
||||||
|
@ -267,7 +267,7 @@ namespace MWClass
|
||||||
|
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
||||||
dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mContainerStore.
|
dynamic_cast<ContainerCustomData&> (*ptr.getRefData().getCustomData()).mContainerStore.
|
||||||
readState (state2.mInventory);
|
readState (state2.mInventory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ namespace MWClass
|
||||||
|
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
||||||
dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mContainerStore.
|
dynamic_cast<ContainerCustomData&> (*ptr.getRefData().getCustomData()).mContainerStore.
|
||||||
writeState (state2.mInventory);
|
writeState (state2.mInventory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "../mwmechanics/creaturestats.hpp"
|
#include "../mwmechanics/creaturestats.hpp"
|
||||||
#include "../mwmechanics/magiceffects.hpp"
|
#include "../mwmechanics/magiceffects.hpp"
|
||||||
#include "../mwmechanics/movement.hpp"
|
#include "../mwmechanics/movement.hpp"
|
||||||
|
#include "../mwmechanics/disease.hpp"
|
||||||
#include "../mwmechanics/spellcasting.hpp"
|
#include "../mwmechanics/spellcasting.hpp"
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
@ -22,6 +23,7 @@
|
||||||
#include "../mwworld/customdata.hpp"
|
#include "../mwworld/customdata.hpp"
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
#include "../mwworld/physicssystem.hpp"
|
#include "../mwworld/physicssystem.hpp"
|
||||||
|
#include "../mwworld/cellstore.hpp"
|
||||||
|
|
||||||
#include "../mwrender/renderinginterface.hpp"
|
#include "../mwrender/renderinginterface.hpp"
|
||||||
#include "../mwrender/actors.hpp"
|
#include "../mwrender/actors.hpp"
|
||||||
|
@ -35,7 +37,7 @@
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
struct CustomData : public MWWorld::CustomData
|
struct CreatureCustomData : public MWWorld::CustomData
|
||||||
{
|
{
|
||||||
MWMechanics::CreatureStats mCreatureStats;
|
MWMechanics::CreatureStats mCreatureStats;
|
||||||
MWWorld::ContainerStore* mContainerStore; // may be InventoryStore for some creatures
|
MWWorld::ContainerStore* mContainerStore; // may be InventoryStore for some creatures
|
||||||
|
@ -43,13 +45,13 @@ namespace
|
||||||
|
|
||||||
virtual MWWorld::CustomData *clone() const;
|
virtual MWWorld::CustomData *clone() const;
|
||||||
|
|
||||||
CustomData() : mContainerStore(0) {}
|
CreatureCustomData() : mContainerStore(0) {}
|
||||||
virtual ~CustomData() { delete mContainerStore; }
|
virtual ~CreatureCustomData() { delete mContainerStore; }
|
||||||
};
|
};
|
||||||
|
|
||||||
MWWorld::CustomData *CustomData::clone() const
|
MWWorld::CustomData *CreatureCustomData::clone() const
|
||||||
{
|
{
|
||||||
CustomData* cloned = new CustomData (*this);
|
CreatureCustomData* cloned = new CreatureCustomData (*this);
|
||||||
cloned->mContainerStore = mContainerStore->clone();
|
cloned->mContainerStore = mContainerStore->clone();
|
||||||
return cloned;
|
return cloned;
|
||||||
}
|
}
|
||||||
|
@ -61,7 +63,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
if (!ptr.getRefData().getCustomData())
|
if (!ptr.getRefData().getCustomData())
|
||||||
{
|
{
|
||||||
std::auto_ptr<CustomData> data (new CustomData);
|
std::auto_ptr<CreatureCustomData> data (new CreatureCustomData);
|
||||||
|
|
||||||
static bool inited = false;
|
static bool inited = false;
|
||||||
if(!inited)
|
if(!inited)
|
||||||
|
@ -121,16 +123,17 @@ namespace MWClass
|
||||||
else
|
else
|
||||||
data->mContainerStore = new MWWorld::ContainerStore();
|
data->mContainerStore = new MWWorld::ContainerStore();
|
||||||
|
|
||||||
|
// Relates to NPC gold reset delay
|
||||||
|
data->mCreatureStats.setTradeTime(MWWorld::TimeStamp(0.0, 0));
|
||||||
|
|
||||||
|
data->mCreatureStats.setGoldPool(ref->mBase->mData.mGold);
|
||||||
|
|
||||||
// store
|
// store
|
||||||
ptr.getRefData().setCustomData(data.release());
|
ptr.getRefData().setCustomData(data.release());
|
||||||
|
|
||||||
getContainerStore(ptr).fill(ref->mBase->mInventory, getId(ptr), "",
|
getContainerStore(ptr).fill(ref->mBase->mInventory, getId(ptr), "",
|
||||||
MWBase::Environment::get().getWorld()->getStore());
|
MWBase::Environment::get().getWorld()->getStore());
|
||||||
|
|
||||||
// TODO: this is not quite correct, in vanilla the merchant's gold pool is not available in his inventory.
|
|
||||||
// (except for gold you gave him)
|
|
||||||
getContainerStore(ptr).add(MWWorld::ContainerStore::sGoldId, ref->mBase->mData.mGold, ptr);
|
|
||||||
|
|
||||||
if (ref->mBase->mFlags & ESM::Creature::Weapon)
|
if (ref->mBase->mFlags & ESM::Creature::Weapon)
|
||||||
getInventoryStore(ptr).autoEquip(ptr);
|
getInventoryStore(ptr).autoEquip(ptr);
|
||||||
}
|
}
|
||||||
|
@ -190,7 +193,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
||||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mCreatureStats;
|
return dynamic_cast<CreatureCustomData&> (*ptr.getRefData().getCustomData()).mCreatureStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -242,15 +245,7 @@ namespace MWClass
|
||||||
|
|
||||||
Ogre::Vector3 hitPosition = result.second;
|
Ogre::Vector3 hitPosition = result.second;
|
||||||
|
|
||||||
MWMechanics::CreatureStats &otherstats = victim.getClass().getCreatureStats(victim);
|
float hitchance = MWMechanics::getHitChance(ptr, victim, ref->mBase->mData.mCombat);
|
||||||
const MWMechanics::MagicEffects &mageffects = stats.getMagicEffects();
|
|
||||||
float hitchance = ref->mBase->mData.mCombat +
|
|
||||||
(stats.getAttribute(ESM::Attribute::Agility).getModified() / 5.0f) +
|
|
||||||
(stats.getAttribute(ESM::Attribute::Luck).getModified() / 10.0f);
|
|
||||||
hitchance *= stats.getFatigueTerm();
|
|
||||||
hitchance += mageffects.get(ESM::MagicEffect::FortifyAttack).mMagnitude -
|
|
||||||
mageffects.get(ESM::MagicEffect::Blind).mMagnitude;
|
|
||||||
hitchance -= otherstats.getEvasion();
|
|
||||||
|
|
||||||
if((::rand()/(RAND_MAX+1.0)) > hitchance/100.0f)
|
if((::rand()/(RAND_MAX+1.0)) > hitchance/100.0f)
|
||||||
{
|
{
|
||||||
|
@ -333,6 +328,8 @@ namespace MWClass
|
||||||
if (damage > 0)
|
if (damage > 0)
|
||||||
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition);
|
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition);
|
||||||
|
|
||||||
|
MWMechanics::diseaseContact(victim, ptr);
|
||||||
|
|
||||||
victim.getClass().onHit(victim, damage, true, weapon, ptr, true);
|
victim.getClass().onHit(victim, damage, true, weapon, ptr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,7 +457,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
||||||
return *dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mContainerStore;
|
return *dynamic_cast<CreatureCustomData&> (*ptr.getRefData().getCustomData()).mContainerStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::InventoryStore& Creature::getInventoryStore(const MWWorld::Ptr &ptr) const
|
MWWorld::InventoryStore& Creature::getInventoryStore(const MWWorld::Ptr &ptr) const
|
||||||
|
@ -529,7 +526,7 @@ namespace MWClass
|
||||||
float moveSpeed;
|
float moveSpeed;
|
||||||
if(normalizedEncumbrance >= 1.0f)
|
if(normalizedEncumbrance >= 1.0f)
|
||||||
moveSpeed = 0.0f;
|
moveSpeed = 0.0f;
|
||||||
else if(isFlying(ptr) || (mageffects.get(ESM::MagicEffect::Levitate).mMagnitude > 0 &&
|
else if(canFly(ptr) || (mageffects.get(ESM::MagicEffect::Levitate).mMagnitude > 0 &&
|
||||||
world->isLevitationEnabled()))
|
world->isLevitationEnabled()))
|
||||||
{
|
{
|
||||||
float flySpeed = 0.01f*(stats.getAttribute(ESM::Attribute::Speed).getModified() +
|
float flySpeed = 0.01f*(stats.getAttribute(ESM::Attribute::Speed).getModified() +
|
||||||
|
@ -563,7 +560,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
||||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mMovement;
|
return dynamic_cast<CreatureCustomData&> (*ptr.getRefData().getCustomData()).mMovement;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ogre::Vector3 Creature::getMovementVector (const MWWorld::Ptr& ptr) const
|
Ogre::Vector3 Creature::getMovementVector (const MWWorld::Ptr& ptr) const
|
||||||
|
@ -679,10 +676,18 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Creature> *ref =
|
MWWorld::LiveCellRef<ESM::Creature> *ref =
|
||||||
ptr.get<ESM::Creature>();
|
ptr.get<ESM::Creature>();
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mCreatures.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.get<ESM::Creature>().insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Creature::isFlying(const MWWorld::Ptr &ptr) const
|
bool Creature::isBipedal(const MWWorld::Ptr &ptr) const
|
||||||
|
{
|
||||||
|
MWWorld::LiveCellRef<ESM::Creature> *ref =
|
||||||
|
ptr.get<ESM::Creature>();
|
||||||
|
|
||||||
|
return ref->mBase->mFlags & ESM::Creature::Bipedal;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Creature::canFly(const MWWorld::Ptr &ptr) const
|
||||||
{
|
{
|
||||||
MWWorld::LiveCellRef<ESM::Creature> *ref =
|
MWWorld::LiveCellRef<ESM::Creature> *ref =
|
||||||
ptr.get<ESM::Creature>();
|
ptr.get<ESM::Creature>();
|
||||||
|
@ -690,6 +695,22 @@ namespace MWClass
|
||||||
return ref->mBase->mFlags & ESM::Creature::Flies;
|
return ref->mBase->mFlags & ESM::Creature::Flies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Creature::canSwim(const MWWorld::Ptr &ptr) const
|
||||||
|
{
|
||||||
|
MWWorld::LiveCellRef<ESM::Creature> *ref =
|
||||||
|
ptr.get<ESM::Creature>();
|
||||||
|
|
||||||
|
return ref->mBase->mFlags & ESM::Creature::Swims;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Creature::canWalk(const MWWorld::Ptr &ptr) const
|
||||||
|
{
|
||||||
|
MWWorld::LiveCellRef<ESM::Creature> *ref =
|
||||||
|
ptr.get<ESM::Creature>();
|
||||||
|
|
||||||
|
return ref->mBase->mFlags & ESM::Creature::Walks;
|
||||||
|
}
|
||||||
|
|
||||||
int Creature::getSndGenTypeFromName(const MWWorld::Ptr &ptr, const std::string &name)
|
int Creature::getSndGenTypeFromName(const MWWorld::Ptr &ptr, const std::string &name)
|
||||||
{
|
{
|
||||||
if(name == "left")
|
if(name == "left")
|
||||||
|
@ -766,7 +787,7 @@ namespace MWClass
|
||||||
|
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
||||||
CustomData& customData = dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData());
|
CreatureCustomData& customData = dynamic_cast<CreatureCustomData&> (*ptr.getRefData().getCustomData());
|
||||||
|
|
||||||
customData.mContainerStore->readState (state2.mInventory);
|
customData.mContainerStore->readState (state2.mInventory);
|
||||||
customData.mCreatureStats.readState (state2.mCreatureStats);
|
customData.mCreatureStats.readState (state2.mCreatureStats);
|
||||||
|
@ -780,12 +801,17 @@ namespace MWClass
|
||||||
|
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
||||||
CustomData& customData = dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData());
|
CreatureCustomData& customData = dynamic_cast<CreatureCustomData&> (*ptr.getRefData().getCustomData());
|
||||||
|
|
||||||
customData.mContainerStore->writeState (state2.mInventory);
|
customData.mContainerStore->writeState (state2.mInventory);
|
||||||
customData.mCreatureStats.writeState (state2.mCreatureStats);
|
customData.mCreatureStats.writeState (state2.mCreatureStats);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Creature::getBaseGold(const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return ptr.get<ESM::Creature>()->mBase->mData.mGold;
|
||||||
|
}
|
||||||
|
|
||||||
const ESM::GameSetting* Creature::fMinWalkSpeedCreature;
|
const ESM::GameSetting* Creature::fMinWalkSpeedCreature;
|
||||||
const ESM::GameSetting* Creature::fMaxWalkSpeedCreature;
|
const ESM::GameSetting* Creature::fMaxWalkSpeedCreature;
|
||||||
const ESM::GameSetting *Creature::fEncumberedMoveEffect;
|
const ESM::GameSetting *Creature::fEncumberedMoveEffect;
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
struct GameSetting;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
class Creature : public MWWorld::Class
|
class Creature : public MWWorld::Class
|
||||||
|
@ -119,7 +124,10 @@ namespace MWClass
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool isFlying (const MWWorld::Ptr &ptr) const;
|
virtual bool isBipedal (const MWWorld::Ptr &ptr) const;
|
||||||
|
virtual bool canFly (const MWWorld::Ptr &ptr) const;
|
||||||
|
virtual bool canSwim (const MWWorld::Ptr &ptr) const;
|
||||||
|
virtual bool canWalk (const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
virtual int getSkill(const MWWorld::Ptr &ptr, int skill) const;
|
virtual int getSkill(const MWWorld::Ptr &ptr, int skill) const;
|
||||||
|
|
||||||
|
@ -133,6 +141,8 @@ namespace MWClass
|
||||||
virtual void writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state)
|
virtual void writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state)
|
||||||
const;
|
const;
|
||||||
///< Write additional state from \a ptr into \a state.
|
///< Write additional state from \a ptr into \a state.
|
||||||
|
|
||||||
|
virtual int getBaseGold(const MWWorld::Ptr& ptr) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,15 +9,15 @@
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
struct CustomData : public MWWorld::CustomData
|
struct CreatureLevListCustomData : public MWWorld::CustomData
|
||||||
{
|
{
|
||||||
// TODO: save the creature we spawned here
|
// TODO: save the creature we spawned here
|
||||||
virtual MWWorld::CustomData *clone() const;
|
virtual MWWorld::CustomData *clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
MWWorld::CustomData *CustomData::clone() const
|
MWWorld::CustomData *CreatureLevListCustomData::clone() const
|
||||||
{
|
{
|
||||||
return new CustomData (*this);
|
return new CreatureLevListCustomData (*this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
if (!ptr.getRefData().getCustomData())
|
if (!ptr.getRefData().getCustomData())
|
||||||
{
|
{
|
||||||
std::auto_ptr<CustomData> data (new CustomData);
|
std::auto_ptr<CreatureLevListCustomData> data (new CreatureLevListCustomData);
|
||||||
|
|
||||||
MWWorld::LiveCellRef<ESM::CreatureLevList> *ref =
|
MWWorld::LiveCellRef<ESM::CreatureLevList> *ref =
|
||||||
ptr.get<ESM::CreatureLevList>();
|
ptr.get<ESM::CreatureLevList>();
|
||||||
|
@ -57,7 +57,7 @@ namespace MWClass
|
||||||
MWWorld::ManualRef ref(store, id);
|
MWWorld::ManualRef ref(store, id);
|
||||||
ref.getPtr().getCellRef().mPos = ptr.getCellRef().mPos;
|
ref.getPtr().getCellRef().mPos = ptr.getCellRef().mPos;
|
||||||
// TODO: hold on to this for respawn purposes later
|
// TODO: hold on to this for respawn purposes later
|
||||||
MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(), *ptr.getCell() , ptr.getCellRef().mPos);
|
MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(), ptr.getCell() , ptr.getCellRef().mPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr.getRefData().setCustomData(data.release());
|
ptr.getRefData().setCustomData(data.release());
|
||||||
|
|
|
@ -258,6 +258,6 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Door> *ref =
|
MWWorld::LiveCellRef<ESM::Door> *ref =
|
||||||
ptr.get<ESM::Door>();
|
ptr.get<ESM::Door>();
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mDoors.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.get<ESM::Door>().insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef GAME_MWCLASS_DOOR_H
|
#ifndef GAME_MWCLASS_DOOR_H
|
||||||
#define GAME_MWCLASS_DOOR_H
|
#define GAME_MWCLASS_DOOR_H
|
||||||
|
|
||||||
|
#include <components/esm/loaddoor.hpp>
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
|
|
|
@ -189,7 +189,7 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
|
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
|
||||||
ptr.get<ESM::Ingredient>();
|
ptr.get<ESM::Ingredient>();
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mIngreds.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.get<ESM::Ingredient>().insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Ingredient::canSell (const MWWorld::Ptr& item, int npcServices) const
|
bool Ingredient::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
|
|
@ -26,12 +26,12 @@
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
struct CustomData : public MWWorld::CustomData
|
struct LightCustomData : public MWWorld::CustomData
|
||||||
{
|
{
|
||||||
float mTime;
|
float mTime;
|
||||||
///< Time remaining
|
///< Time remaining
|
||||||
|
|
||||||
CustomData(MWWorld::Ptr ptr)
|
LightCustomData(MWWorld::Ptr ptr)
|
||||||
{
|
{
|
||||||
MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
|
MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
|
||||||
mTime = ref->mBase->mData.mTime;
|
mTime = ref->mBase->mData.mTime;
|
||||||
|
@ -40,7 +40,7 @@ namespace
|
||||||
|
|
||||||
virtual MWWorld::CustomData *clone() const
|
virtual MWWorld::CustomData *clone() const
|
||||||
{
|
{
|
||||||
return new CustomData (*this);
|
return new LightCustomData (*this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
ensureCustomData(ptr);
|
ensureCustomData(ptr);
|
||||||
|
|
||||||
float &timeRemaining = dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mTime;
|
float &timeRemaining = dynamic_cast<LightCustomData&> (*ptr.getRefData().getCustomData()).mTime;
|
||||||
timeRemaining = duration;
|
timeRemaining = duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
ensureCustomData(ptr);
|
ensureCustomData(ptr);
|
||||||
|
|
||||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mTime;
|
return dynamic_cast<LightCustomData&> (*ptr.getRefData().getCustomData()).mTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::Ptr
|
MWWorld::Ptr
|
||||||
|
@ -227,13 +227,13 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Light> *ref =
|
MWWorld::LiveCellRef<ESM::Light> *ref =
|
||||||
ptr.get<ESM::Light>();
|
ptr.get<ESM::Light>();
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mLights.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.get<ESM::Light>().insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Light::ensureCustomData (const MWWorld::Ptr& ptr) const
|
void Light::ensureCustomData (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
if (!ptr.getRefData().getCustomData())
|
if (!ptr.getRefData().getCustomData())
|
||||||
ptr.getRefData().setCustomData(new CustomData(ptr));
|
ptr.getRefData().setCustomData(new LightCustomData(ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Light::canSell (const MWWorld::Ptr& item, int npcServices) const
|
bool Light::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
@ -278,7 +278,7 @@ namespace MWClass
|
||||||
|
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
||||||
dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mTime = state2.mTime;
|
dynamic_cast<LightCustomData&> (*ptr.getRefData().getCustomData()).mTime = state2.mTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Light::writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state)
|
void Light::writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state)
|
||||||
|
@ -288,6 +288,6 @@ namespace MWClass
|
||||||
|
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
||||||
state2.mTime = dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mTime;
|
state2.mTime = dynamic_cast<LightCustomData&> (*ptr.getRefData().getCustomData()).mTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,7 +169,7 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Lockpick> *ref =
|
MWWorld::LiveCellRef<ESM::Lockpick> *ref =
|
||||||
ptr.get<ESM::Lockpick>();
|
ptr.get<ESM::Lockpick>();
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mLockpicks.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.get<ESM::Lockpick>().insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Lockpick::canSell (const MWWorld::Ptr& item, int npcServices) const
|
bool Lockpick::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
|
|
@ -218,13 +218,13 @@ namespace MWClass
|
||||||
MWWorld::ManualRef newRef(store, base);
|
MWWorld::ManualRef newRef(store, base);
|
||||||
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
|
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
|
||||||
newRef.getPtr().get<ESM::Miscellaneous>();
|
newRef.getPtr().get<ESM::Miscellaneous>();
|
||||||
newPtr = MWWorld::Ptr(&cell.mMiscItems.insert(*ref), &cell);
|
newPtr = MWWorld::Ptr(&cell.get<ESM::Miscellaneous>().insert(*ref), &cell);
|
||||||
newPtr.getCellRef().mGoldValue = goldAmount;
|
newPtr.getCellRef().mGoldValue = goldAmount;
|
||||||
newPtr.getRefData().setCount(1);
|
newPtr.getRefData().setCount(1);
|
||||||
} else {
|
} else {
|
||||||
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
|
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
|
||||||
ptr.get<ESM::Miscellaneous>();
|
ptr.get<ESM::Miscellaneous>();
|
||||||
newPtr = MWWorld::Ptr(&cell.mMiscItems.insert(*ref), &cell);
|
newPtr = MWWorld::Ptr(&cell.get<ESM::Miscellaneous>().insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
return newPtr;
|
return newPtr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "../mwworld/inventorystore.hpp"
|
#include "../mwworld/inventorystore.hpp"
|
||||||
#include "../mwworld/customdata.hpp"
|
#include "../mwworld/customdata.hpp"
|
||||||
#include "../mwworld/physicssystem.hpp"
|
#include "../mwworld/physicssystem.hpp"
|
||||||
|
#include "../mwworld/cellstore.hpp"
|
||||||
|
|
||||||
#include "../mwrender/actors.hpp"
|
#include "../mwrender/actors.hpp"
|
||||||
#include "../mwrender/renderinginterface.hpp"
|
#include "../mwrender/renderinginterface.hpp"
|
||||||
|
@ -38,7 +39,7 @@
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
struct CustomData : public MWWorld::CustomData
|
struct NpcCustomData : public MWWorld::CustomData
|
||||||
{
|
{
|
||||||
MWMechanics::NpcStats mNpcStats;
|
MWMechanics::NpcStats mNpcStats;
|
||||||
MWMechanics::Movement mMovement;
|
MWMechanics::Movement mMovement;
|
||||||
|
@ -47,9 +48,9 @@ namespace
|
||||||
virtual MWWorld::CustomData *clone() const;
|
virtual MWWorld::CustomData *clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
MWWorld::CustomData *CustomData::clone() const
|
MWWorld::CustomData *NpcCustomData::clone() const
|
||||||
{
|
{
|
||||||
return new CustomData (*this);
|
return new NpcCustomData (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void autoCalculateAttributes (const ESM::NPC* npc, MWMechanics::CreatureStats& creatureStats)
|
void autoCalculateAttributes (const ESM::NPC* npc, MWMechanics::CreatureStats& creatureStats)
|
||||||
|
@ -261,7 +262,7 @@ namespace MWClass
|
||||||
}
|
}
|
||||||
if (!ptr.getRefData().getCustomData())
|
if (!ptr.getRefData().getCustomData())
|
||||||
{
|
{
|
||||||
std::auto_ptr<CustomData> data(new CustomData);
|
std::auto_ptr<NpcCustomData> data(new NpcCustomData);
|
||||||
|
|
||||||
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
|
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
|
||||||
|
|
||||||
|
@ -356,13 +357,14 @@ namespace MWClass
|
||||||
data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr), "",
|
data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr), "",
|
||||||
MWBase::Environment::get().getWorld()->getStore());
|
MWBase::Environment::get().getWorld()->getStore());
|
||||||
|
|
||||||
|
// Relates to NPC gold reset delay
|
||||||
|
data->mNpcStats.setTradeTime(MWWorld::TimeStamp(0.0, 0));
|
||||||
|
|
||||||
|
data->mNpcStats.setGoldPool(gold);
|
||||||
|
|
||||||
// store
|
// store
|
||||||
ptr.getRefData().setCustomData (data.release());
|
ptr.getRefData().setCustomData (data.release());
|
||||||
|
|
||||||
// TODO: this is not quite correct, in vanilla the merchant's gold pool is not available in his inventory.
|
|
||||||
// (except for gold you gave him)
|
|
||||||
getContainerStore(ptr).add(MWWorld::ContainerStore::sGoldId, gold, ptr);
|
|
||||||
|
|
||||||
getInventoryStore(ptr).autoEquip(ptr);
|
getInventoryStore(ptr).autoEquip(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -435,14 +437,14 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
||||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mNpcStats;
|
return dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData()).mNpcStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
MWMechanics::NpcStats& Npc::getNpcStats (const MWWorld::Ptr& ptr) const
|
MWMechanics::NpcStats& Npc::getNpcStats (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
||||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mNpcStats;
|
return dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData()).mNpcStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -497,15 +499,7 @@ namespace MWClass
|
||||||
if(!weapon.isEmpty())
|
if(!weapon.isEmpty())
|
||||||
weapskill = get(weapon).getEquipmentSkill(weapon);
|
weapskill = get(weapon).getEquipmentSkill(weapon);
|
||||||
|
|
||||||
MWMechanics::NpcStats &stats = getNpcStats(ptr);
|
float hitchance = MWMechanics::getHitChance(ptr, victim, ptr.getClass().getSkill(ptr, weapskill));
|
||||||
const MWMechanics::MagicEffects &mageffects = stats.getMagicEffects();
|
|
||||||
float hitchance = stats.getSkill(weapskill).getModified() +
|
|
||||||
(stats.getAttribute(ESM::Attribute::Agility).getModified() / 5.0f) +
|
|
||||||
(stats.getAttribute(ESM::Attribute::Luck).getModified() / 10.0f);
|
|
||||||
hitchance *= stats.getFatigueTerm();
|
|
||||||
hitchance += mageffects.get(ESM::MagicEffect::FortifyAttack).mMagnitude -
|
|
||||||
mageffects.get(ESM::MagicEffect::Blind).mMagnitude;
|
|
||||||
hitchance -= otherstats.getEvasion();
|
|
||||||
|
|
||||||
if((::rand()/(RAND_MAX+1.0)) > hitchance/100.0f)
|
if((::rand()/(RAND_MAX+1.0)) > hitchance/100.0f)
|
||||||
{
|
{
|
||||||
|
@ -515,6 +509,7 @@ namespace MWClass
|
||||||
|
|
||||||
bool healthdmg;
|
bool healthdmg;
|
||||||
float damage = 0.0f;
|
float damage = 0.0f;
|
||||||
|
MWMechanics::NpcStats &stats = getNpcStats(ptr);
|
||||||
if(!weapon.isEmpty())
|
if(!weapon.isEmpty())
|
||||||
{
|
{
|
||||||
const bool weaphashealth = get(weapon).hasItemHealth(weapon);
|
const bool weaphashealth = get(weapon).hasItemHealth(weapon);
|
||||||
|
@ -614,6 +609,8 @@ namespace MWClass
|
||||||
if (healthdmg && damage > 0)
|
if (healthdmg && damage > 0)
|
||||||
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition);
|
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition);
|
||||||
|
|
||||||
|
MWMechanics::diseaseContact(victim, ptr);
|
||||||
|
|
||||||
othercls.onHit(victim, damage, healthdmg, weapon, ptr, true);
|
othercls.onHit(victim, damage, healthdmg, weapon, ptr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,9 +644,6 @@ namespace MWClass
|
||||||
ptr.getRefData().getLocals().setVarByInt(script, "onpchitme", 1);
|
ptr.getRefData().getLocals().setVarByInt(script, "onpchitme", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!attacker.isEmpty())
|
|
||||||
MWMechanics::diseaseContact(ptr, attacker);
|
|
||||||
|
|
||||||
if (damage > 0.0f && !object.isEmpty())
|
if (damage > 0.0f && !object.isEmpty())
|
||||||
MWMechanics::resistNormalWeapon(ptr, attacker, object, damage);
|
MWMechanics::resistNormalWeapon(ptr, attacker, object, damage);
|
||||||
|
|
||||||
|
@ -680,12 +674,7 @@ namespace MWClass
|
||||||
else
|
else
|
||||||
getCreatureStats(ptr).setHitRecovery(true); // Is this supposed to always occur?
|
getCreatureStats(ptr).setHitRecovery(true); // Is this supposed to always occur?
|
||||||
|
|
||||||
if(object.isEmpty())
|
|
||||||
{
|
|
||||||
if(ishealth)
|
if(ishealth)
|
||||||
damage /= std::min(1.0f + getArmorRating(ptr)/std::max(1.0f, damage), 4.0f);
|
|
||||||
}
|
|
||||||
else if(ishealth)
|
|
||||||
{
|
{
|
||||||
// Hit percentages:
|
// Hit percentages:
|
||||||
// cuirass = 30%
|
// cuirass = 30%
|
||||||
|
@ -831,7 +820,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
||||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mInventoryStore;
|
return dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData()).mInventoryStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::InventoryStore& Npc::getInventoryStore (const MWWorld::Ptr& ptr)
|
MWWorld::InventoryStore& Npc::getInventoryStore (const MWWorld::Ptr& ptr)
|
||||||
|
@ -839,7 +828,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
||||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mInventoryStore;
|
return dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData()).mInventoryStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Npc::getScript (const MWWorld::Ptr& ptr) const
|
std::string Npc::getScript (const MWWorld::Ptr& ptr) const
|
||||||
|
@ -853,7 +842,7 @@ namespace MWClass
|
||||||
float Npc::getSpeed(const MWWorld::Ptr& ptr) const
|
float Npc::getSpeed(const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
const CustomData *npcdata = static_cast<const CustomData*>(ptr.getRefData().getCustomData());
|
const NpcCustomData *npcdata = static_cast<const NpcCustomData*>(ptr.getRefData().getCustomData());
|
||||||
const MWMechanics::MagicEffects &mageffects = npcdata->mNpcStats.getMagicEffects();
|
const MWMechanics::MagicEffects &mageffects = npcdata->mNpcStats.getMagicEffects();
|
||||||
|
|
||||||
const float normalizedEncumbrance = Npc::getEncumbrance(ptr) / Npc::getCapacity(ptr);
|
const float normalizedEncumbrance = Npc::getEncumbrance(ptr) / Npc::getCapacity(ptr);
|
||||||
|
@ -908,7 +897,7 @@ namespace MWClass
|
||||||
|
|
||||||
float Npc::getJump(const MWWorld::Ptr &ptr) const
|
float Npc::getJump(const MWWorld::Ptr &ptr) const
|
||||||
{
|
{
|
||||||
const CustomData *npcdata = static_cast<const CustomData*>(ptr.getRefData().getCustomData());
|
const NpcCustomData *npcdata = static_cast<const NpcCustomData*>(ptr.getRefData().getCustomData());
|
||||||
const MWMechanics::MagicEffects &mageffects = npcdata->mNpcStats.getMagicEffects();
|
const MWMechanics::MagicEffects &mageffects = npcdata->mNpcStats.getMagicEffects();
|
||||||
const float encumbranceTerm = fJumpEncumbranceBase->getFloat() +
|
const float encumbranceTerm = fJumpEncumbranceBase->getFloat() +
|
||||||
fJumpEncumbranceMultiplier->getFloat() *
|
fJumpEncumbranceMultiplier->getFloat() *
|
||||||
|
@ -947,7 +936,7 @@ namespace MWClass
|
||||||
if (fallHeight >= fallDistanceMin)
|
if (fallHeight >= fallDistanceMin)
|
||||||
{
|
{
|
||||||
const float acrobaticsSkill = MWWorld::Class::get(ptr).getNpcStats (ptr).getSkill(ESM::Skill::Acrobatics).getModified();
|
const float acrobaticsSkill = MWWorld::Class::get(ptr).getNpcStats (ptr).getSkill(ESM::Skill::Acrobatics).getModified();
|
||||||
const CustomData *npcdata = static_cast<const CustomData*>(ptr.getRefData().getCustomData());
|
const NpcCustomData *npcdata = static_cast<const NpcCustomData*>(ptr.getRefData().getCustomData());
|
||||||
const float jumpSpellBonus = npcdata->mNpcStats.getMagicEffects().get(ESM::MagicEffect::Jump).mMagnitude;
|
const float jumpSpellBonus = npcdata->mNpcStats.getMagicEffects().get(ESM::MagicEffect::Jump).mMagnitude;
|
||||||
const float fallAcroBase = gmst.find("fFallAcroBase")->getFloat();
|
const float fallAcroBase = gmst.find("fFallAcroBase")->getFloat();
|
||||||
const float fallAcroMult = gmst.find("fFallAcroMult")->getFloat();
|
const float fallAcroMult = gmst.find("fFallAcroMult")->getFloat();
|
||||||
|
@ -972,7 +961,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
||||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mMovement;
|
return dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData()).mMovement;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ogre::Vector3 Npc::getMovementVector (const MWWorld::Ptr& ptr) const
|
Ogre::Vector3 Npc::getMovementVector (const MWWorld::Ptr& ptr) const
|
||||||
|
@ -1252,7 +1241,7 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::NPC> *ref =
|
MWWorld::LiveCellRef<ESM::NPC> *ref =
|
||||||
ptr.get<ESM::NPC>();
|
ptr.get<ESM::NPC>();
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mNpcs.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.get<ESM::NPC>().insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Npc::getSkill(const MWWorld::Ptr& ptr, int skill) const
|
int Npc::getSkill(const MWWorld::Ptr& ptr, int skill) const
|
||||||
|
@ -1278,7 +1267,7 @@ namespace MWClass
|
||||||
|
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
||||||
CustomData& customData = dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData());
|
NpcCustomData& customData = dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData());
|
||||||
|
|
||||||
customData.mInventoryStore.readState (state2.mInventory);
|
customData.mInventoryStore.readState (state2.mInventory);
|
||||||
customData.mNpcStats.readState (state2.mNpcStats);
|
customData.mNpcStats.readState (state2.mNpcStats);
|
||||||
|
@ -1292,13 +1281,22 @@ namespace MWClass
|
||||||
|
|
||||||
ensureCustomData (ptr);
|
ensureCustomData (ptr);
|
||||||
|
|
||||||
CustomData& customData = dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData());
|
NpcCustomData& customData = dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData());
|
||||||
|
|
||||||
customData.mInventoryStore.writeState (state2.mInventory);
|
customData.mInventoryStore.writeState (state2.mInventory);
|
||||||
customData.mNpcStats.writeState (state2.mNpcStats);
|
customData.mNpcStats.writeState (state2.mNpcStats);
|
||||||
static_cast<const MWMechanics::CreatureStats&> (customData.mNpcStats).writeState (state2.mCreatureStats);
|
static_cast<const MWMechanics::CreatureStats&> (customData.mNpcStats).writeState (state2.mCreatureStats);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Npc::getBaseGold(const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
|
||||||
|
if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
|
||||||
|
return ref->mBase->mNpdt52.mGold;
|
||||||
|
else
|
||||||
|
return ref->mBase->mNpdt12.mGold;
|
||||||
|
}
|
||||||
|
|
||||||
const ESM::GameSetting *Npc::fMinWalkSpeed;
|
const ESM::GameSetting *Npc::fMinWalkSpeed;
|
||||||
const ESM::GameSetting *Npc::fMaxWalkSpeed;
|
const ESM::GameSetting *Npc::fMaxWalkSpeed;
|
||||||
const ESM::GameSetting *Npc::fEncumberedMoveEffect;
|
const ESM::GameSetting *Npc::fEncumberedMoveEffect;
|
||||||
|
|
|
@ -166,6 +166,8 @@ namespace MWClass
|
||||||
virtual void writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state)
|
virtual void writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state)
|
||||||
const;
|
const;
|
||||||
///< Write additional state from \a ptr into \a state.
|
///< Write additional state from \a ptr into \a state.
|
||||||
|
|
||||||
|
virtual int getBaseGold(const MWWorld::Ptr& ptr) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -185,7 +185,7 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Potion> *ref =
|
MWWorld::LiveCellRef<ESM::Potion> *ref =
|
||||||
ptr.get<ESM::Potion>();
|
ptr.get<ESM::Potion>();
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mPotions.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.get<ESM::Potion>().insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Potion::canSell (const MWWorld::Ptr& item, int npcServices) const
|
bool Potion::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
|
|
@ -168,7 +168,7 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Probe> *ref =
|
MWWorld::LiveCellRef<ESM::Probe> *ref =
|
||||||
ptr.get<ESM::Probe>();
|
ptr.get<ESM::Probe>();
|
||||||
|
|
||||||
return MWWorld::Ptr(&cell.mProbes.insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.get<ESM::Probe>().insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Probe::canSell (const MWWorld::Ptr& item, int npcServices) const
|
bool Probe::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue