Merge remote-tracking branch 'sirherrbatka/Editor-Dialog'
@ -60,11 +60,12 @@ 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 worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
||||||
|
previewwidget
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (view/render
|
opencs_units_noqt (view/render
|
||||||
@ -72,8 +73,7 @@ opencs_units_noqt (view/render
|
|||||||
)
|
)
|
||||||
|
|
||||||
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
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -147,6 +147,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})
|
||||||
|
|
||||||
@ -187,6 +190,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,8 +9,13 @@
|
|||||||
#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/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"
|
||||||
|
|
||||||
@ -18,14 +23,17 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
|
|||||||
: mDocumentManager (mCfgMgr), mViewManager (mDocumentManager),
|
: mDocumentManager (mCfgMgr), mViewManager (mDocumentManager),
|
||||||
mIpcServerName ("org.openmw.OpenCS")
|
mIpcServerName ("org.openmw.OpenCS")
|
||||||
{
|
{
|
||||||
Files::PathContainer dataDirs = readConfig();
|
std::pair<Files::PathContainer, std::vector<std::string> > config = readConfig();
|
||||||
|
|
||||||
setupDataFiles (dataDirs);
|
setupDataFiles (config.first);
|
||||||
|
|
||||||
CSMSettings::UserSettings::instance().loadSettings ("opencs.cfg");
|
CSMSettings::UserSettings::instance().loadSettings ("opencs.cfg");
|
||||||
|
|
||||||
ogreInit.init ((mCfgMgr.getUserConfigPath() / "opencsOgre.log").string());
|
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);
|
||||||
|
|
||||||
@ -58,7 +66,7 @@ void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Files::PathContainer CS::Editor::readConfig()
|
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");
|
||||||
@ -68,13 +76,17 @@ Files::PathContainer CS::Editor::readConfig()
|
|||||||
("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 (variables["resources"].as<std::string>());
|
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()) {
|
||||||
@ -105,7 +117,7 @@ Files::PathContainer CS::Editor::readConfig()
|
|||||||
|
|
||||||
dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end());
|
dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end());
|
||||||
|
|
||||||
return dataDirs;
|
return std::make_pair (dataDirs, variables["fallback-archive"].as<std::vector<std::string> >());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CS::Editor::createGame()
|
void CS::Editor::createGame()
|
||||||
@ -216,6 +228,15 @@ int CS::Editor::run()
|
|||||||
if (mLocal.empty())
|
if (mLocal.empty())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
mStartup.show();
|
||||||
|
|
||||||
|
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"));
|
||||||
|
|
||||||
@ -233,9 +254,36 @@ int CS::Editor::run()
|
|||||||
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);
|
||||||
|
|
||||||
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,11 +1,15 @@
|
|||||||
#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
|
||||||
@ -41,12 +45,13 @@ 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 (const Files::PathContainer& dataDirs);
|
void setupDataFiles (const Files::PathContainer& dataDirs);
|
||||||
|
|
||||||
Files::PathContainer readConfig();
|
std::pair<Files::PathContainer, std::vector<std::string> > readConfig();
|
||||||
///< \return data paths
|
///< \return data paths
|
||||||
|
|
||||||
// not implemented
|
// not implemented
|
||||||
@ -63,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
|
||||||
@ -42,6 +44,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
OgreInit::OgreInit ogreInit;
|
OgreInit::OgreInit ogreInit;
|
||||||
|
|
||||||
|
std::auto_ptr<sh::Factory> shinyFactory;
|
||||||
|
|
||||||
Application application (argc, argv);
|
Application application (argc, argv);
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
@ -73,5 +77,7 @@ int main(int argc, char *argv[])
|
|||||||
// return 0;
|
// return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shinyFactory = editor.setupGraphics();
|
||||||
|
|
||||||
return editor.run();
|
return editor.run();
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
@ -202,7 +202,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,7 +834,7 @@ namespace CSMWorld
|
|||||||
|
|
||||||
virtual bool isUserEditable() const
|
virtual bool isUserEditable() const
|
||||||
{
|
{
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1114,7 +1114,7 @@ namespace CSMWorld
|
|||||||
|
|
||||||
virtual bool isUserEditable() const
|
virtual bool isUserEditable() const
|
||||||
{
|
{
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1380,7 +1380,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 +1560,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
|
||||||
{
|
{
|
||||||
|
@ -250,9 +250,9 @@ CSMWorld::Data::Data() : mRefs (mCells)
|
|||||||
addModel (new IdTable (&mTopicInfos, IdTable::Reordering_WithinTopic), UniversalId::Type_TopicInfos, UniversalId::Type_TopicInfo);
|
addModel (new IdTable (&mTopicInfos, IdTable::Reordering_WithinTopic), UniversalId::Type_TopicInfos, UniversalId::Type_TopicInfo);
|
||||||
addModel (new IdTable (&mJournalInfos, IdTable::Reordering_WithinTopic), UniversalId::Type_JournalInfos, UniversalId::Type_JournalInfo);
|
addModel (new IdTable (&mJournalInfos, IdTable::Reordering_WithinTopic), UniversalId::Type_JournalInfos, UniversalId::Type_JournalInfo);
|
||||||
addModel (new IdTable (&mCells, IdTable::Reordering_None, IdTable::Viewing_Id), 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, IdTable::Reordering_None, IdTable::Viewing_Cell), 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
#include "columnbase.hpp"
|
#include "columnbase.hpp"
|
||||||
|
|
||||||
CSMWorld::IdTable::IdTable (CollectionBase *idCollection, Reordering reordering,
|
CSMWorld::IdTable::IdTable (CollectionBase *idCollection, Reordering reordering,
|
||||||
Viewing viewing)
|
Viewing viewing, bool preview)
|
||||||
: mIdCollection (idCollection), mReordering (reordering), mViewing (viewing)
|
: mIdCollection (idCollection), mReordering (reordering), mViewing (viewing), mPreview (preview)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
CSMWorld::IdTable::~IdTable()
|
CSMWorld::IdTable::~IdTable()
|
||||||
@ -196,6 +196,11 @@ CSMWorld::IdTable::Viewing CSMWorld::IdTable::getViewing() const
|
|||||||
return mViewing;
|
return mViewing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSMWorld::IdTable::hasPreview() const
|
||||||
|
{
|
||||||
|
return mPreview;
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row) const
|
std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row) const
|
||||||
{
|
{
|
||||||
std::string id;
|
std::string id;
|
||||||
@ -231,3 +236,8 @@ std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row)
|
|||||||
|
|
||||||
return std::make_pair (UniversalId (UniversalId::Type_Scene, id), hint);
|
return std::make_pair (UniversalId (UniversalId::Type_Scene, id), hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CSMWorld::IdTable::getColumnId(int column) const
|
||||||
|
{
|
||||||
|
return mIdCollection->getColumn(column).getId();
|
||||||
|
}
|
@ -39,6 +39,7 @@ namespace CSMWorld
|
|||||||
CollectionBase *mIdCollection;
|
CollectionBase *mIdCollection;
|
||||||
Reordering mReordering;
|
Reordering mReordering;
|
||||||
Viewing mViewing;
|
Viewing mViewing;
|
||||||
|
bool mPreview;
|
||||||
|
|
||||||
// not implemented
|
// not implemented
|
||||||
IdTable (const IdTable&);
|
IdTable (const IdTable&);
|
||||||
@ -47,7 +48,7 @@ namespace CSMWorld
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
IdTable (CollectionBase *idCollection, Reordering reordering = Reordering_None,
|
IdTable (CollectionBase *idCollection, Reordering reordering = Reordering_None,
|
||||||
Viewing viewing = Viewing_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();
|
||||||
@ -100,9 +101,13 @@ namespace CSMWorld
|
|||||||
|
|
||||||
Viewing getViewing() const;
|
Viewing getViewing() const;
|
||||||
|
|
||||||
|
bool hasPreview() const;
|
||||||
|
|
||||||
std::pair<UniversalId, std::string> view (int row) const;
|
std::pair<UniversalId, std::string> view (int row) const;
|
||||||
///< Return the UniversalId and the hint for viewing \a row. If viewing is not
|
///< Return the UniversalId and the hint for viewing \a row. If viewing is not
|
||||||
/// supported by this table, return (UniversalId::Type_None, "").
|
/// supported by this table, return (UniversalId::Type_None, "").
|
||||||
|
|
||||||
|
int getColumnId(int column) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,3 +444,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;
|
||||||
|
}
|
@ -48,6 +48,8 @@ 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);
|
||||||
|
@ -92,6 +92,8 @@ namespace
|
|||||||
{ 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_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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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 };
|
||||||
|
@ -19,3 +19,9 @@ 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::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:
|
||||||
|
|
||||||
|
@ -316,8 +316,16 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
|
|||||||
|
|
||||||
/// \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())
|
if (!hint.empty())
|
||||||
view->useHint (hint);
|
view->useHint (hint);
|
||||||
|
|
||||||
|
72
apps/opencs/view/render/previewwidget.cpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
|
||||||
|
#include "previewwidget.hpp"
|
||||||
|
|
||||||
|
#include <OgreSceneManager.h>
|
||||||
|
|
||||||
|
#include "../../model/world/data.hpp"
|
||||||
|
|
||||||
|
void CSVRender::PreviewWidget::setup (const std::string& id)
|
||||||
|
{
|
||||||
|
setNavigation (&mOrbit);
|
||||||
|
|
||||||
|
int column = mData.getReferenceables().findColumnIndex (CSMWorld::Columns::ColumnId_Model);
|
||||||
|
|
||||||
|
int row = mData.getReferenceables().getIndex (id);
|
||||||
|
|
||||||
|
QVariant value = mData.getReferenceables().getData (row, column);
|
||||||
|
|
||||||
|
if (!value.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string model = value.toString().toUtf8().constData();
|
||||||
|
|
||||||
|
if (model.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
mNode = getSceneManager()->getRootSceneNode()->createChildSceneNode();
|
||||||
|
mNode->setPosition (Ogre::Vector3 (0, 0, 0));
|
||||||
|
|
||||||
|
mObject = NifOgre::Loader::createObjects (mNode, "Meshes\\" + model);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PreviewWidget::adjust (const std::string& id)
|
||||||
|
{
|
||||||
|
if (mNode)
|
||||||
|
{
|
||||||
|
int row = mData.getReferences().getIndex (id);
|
||||||
|
|
||||||
|
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 (const CSMWorld::Data& data,
|
||||||
|
const std::string& referenceableId, QWidget *parent)
|
||||||
|
: SceneWidget (parent), mData (data), mNode (0)
|
||||||
|
{
|
||||||
|
setup (referenceableId);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::PreviewWidget::PreviewWidget (const CSMWorld::Data& data,
|
||||||
|
const std::string& referenceableId, const std::string& referenceId, QWidget *parent)
|
||||||
|
: SceneWidget (parent), mData (data)
|
||||||
|
{
|
||||||
|
setup (referenceableId);
|
||||||
|
adjust (referenceId);
|
||||||
|
}
|
46
apps/opencs/view/render/previewwidget.hpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef OPENCS_VIEW_PREVIEWWIDGET_H
|
||||||
|
#define OPENCS_VIEW_PREVIEWWIDGET_H
|
||||||
|
|
||||||
|
#include <components/nifogre/ogrenifloader.hpp>
|
||||||
|
|
||||||
|
#include "scenewidget.hpp"
|
||||||
|
|
||||||
|
#include "navigationorbit.hpp"
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class PreviewWidget : public SceneWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
const CSMWorld::Data& mData;
|
||||||
|
CSVRender::NavigationOrbit mOrbit;
|
||||||
|
NifOgre::ObjectScenePtr mObject;
|
||||||
|
Ogre::SceneNode *mNode;
|
||||||
|
|
||||||
|
void setup (const std::string& id);
|
||||||
|
///< \param id ID of the referenceable to be viewed
|
||||||
|
|
||||||
|
void adjust (const std::string& id);
|
||||||
|
///< \param id ID of the reference to be viewed
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
PreviewWidget (const CSMWorld::Data& data, const std::string& referenceableId,
|
||||||
|
QWidget *parent = 0);
|
||||||
|
|
||||||
|
PreviewWidget (const CSMWorld::Data& data, const std::string& referenceableId,
|
||||||
|
const std::string& referenceId, QWidget *parent = 0);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void closeRequest();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -45,15 +45,10 @@ namespace CSVRender
|
|||||||
|
|
||||||
mCamera = mSceneMgr->createCamera("foo");
|
mCamera = mSceneMgr->createCamera("foo");
|
||||||
|
|
||||||
Ogre::Entity* ent = mSceneMgr->createEntity("cube", Ogre::SceneManager::PT_CUBE);
|
mCamera->setPosition(300,0,000);
|
||||||
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);
|
||||||
|
|
||||||
QTimer *timer = new QTimer (this);
|
QTimer *timer = new QTimer (this);
|
||||||
|
|
||||||
@ -118,6 +113,11 @@ namespace CSVRender
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ogre::SceneManager *SceneWidget::getSceneManager()
|
||||||
|
{
|
||||||
|
return mSceneMgr;
|
||||||
|
}
|
||||||
|
|
||||||
void SceneWidget::paintEvent(QPaintEvent* e)
|
void SceneWidget::paintEvent(QPaintEvent* e)
|
||||||
{
|
{
|
||||||
if (!mWindow)
|
if (!mWindow)
|
||||||
|
@ -34,6 +34,8 @@ namespace CSVRender
|
|||||||
void setNavigation (Navigation *navigation);
|
void setNavigation (Navigation *navigation);
|
||||||
///< \attention The ownership of \a navigation is not transferred to *this.
|
///< \attention The ownership of \a navigation is not transferred to *this.
|
||||||
|
|
||||||
|
Ogre::SceneManager *getSceneManager();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void paintEvent(QPaintEvent* e);
|
void paintEvent(QPaintEvent* e);
|
||||||
void resizeEvent(QResizeEvent* e);
|
void resizeEvent(QResizeEvent* e);
|
||||||
|
@ -1,11 +1,20 @@
|
|||||||
|
|
||||||
#include "worldspacewidget.hpp"
|
#include "worldspacewidget.hpp"
|
||||||
|
|
||||||
|
#include <OgreSceneNode.h>
|
||||||
|
#include <OgreSceneManager.h>
|
||||||
|
#include <OgreEntity.h>
|
||||||
|
|
||||||
#include "../world/scenetoolmode.hpp"
|
#include "../world/scenetoolmode.hpp"
|
||||||
|
|
||||||
CSVRender::WorldspaceWidget::WorldspaceWidget (QWidget *parent)
|
CSVRender::WorldspaceWidget::WorldspaceWidget (QWidget *parent)
|
||||||
: SceneWidget (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)
|
void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode)
|
||||||
{
|
{
|
||||||
|
@ -1,98 +1,663 @@
|
|||||||
|
|
||||||
#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 or !mIndexWrapper.get())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i < data.size(); ++i)
|
||||||
|
{
|
||||||
|
if (mDisplay == CSMWorld::TableMimeData::convertEnums(data[i].getType()))
|
||||||
|
{
|
||||||
|
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().toStdString()));
|
||||||
|
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().toStdString()));
|
||||||
|
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().toStdString()));
|
||||||
|
}
|
||||||
|
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().toStdString()));
|
||||||
|
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().toStdString(),
|
||||||
|
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().toStdString()), "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
52
apps/opencs/view/world/previewsubview.cpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
|
||||||
|
#include "previewsubview.hpp"
|
||||||
|
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
|
#include "../render/scenewidget.hpp"
|
||||||
|
|
||||||
|
#include "scenetoolbar.hpp"
|
||||||
|
|
||||||
|
#include "../render/previewwidget.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;
|
||||||
|
|
||||||
|
setWindowTitle (("Preview: Reference to " + referenceableId).c_str());
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
layout->addWidget (toolbar, 0);
|
||||||
|
|
||||||
|
layout->addWidget (mScene, 1);
|
||||||
|
|
||||||
|
QWidget *widget = new QWidget;
|
||||||
|
|
||||||
|
widget->setLayout (layout);
|
||||||
|
|
||||||
|
setWidget (widget);
|
||||||
|
|
||||||
|
connect (mScene, SIGNAL (closeRequest()), this, SLOT (closeRequest()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::PreviewSubView::setEditLock (bool locked) {}
|
||||||
|
|
||||||
|
void CSVWorld::PreviewSubView::closeRequest()
|
||||||
|
{
|
||||||
|
deleteLater();
|
||||||
|
}
|
36
apps/opencs/view/world/previewsubview.hpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#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();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -34,7 +34,7 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D
|
|||||||
|
|
||||||
SceneToolbar *toolbar = new SceneToolbar (48, this);
|
SceneToolbar *toolbar = new SceneToolbar (48, this);
|
||||||
|
|
||||||
if (id.getId()[0]=='#')
|
if (id.getId()=="sys::default")
|
||||||
mScene = new CSVRender::PagedWorldspaceWidget (this);
|
mScene = new CSVRender::PagedWorldspaceWidget (this);
|
||||||
else
|
else
|
||||||
mScene = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this);
|
mScene = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this);
|
||||||
|
@ -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>);
|
||||||
}
|
}
|
@ -39,18 +39,6 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
|||||||
|
|
||||||
if (mCreateAction)
|
if (mCreateAction)
|
||||||
menu.addAction(mCloneAction);
|
menu.addAction(mCloneAction);
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (!mDocument.getData().getCells().getRecord (id.getId()).isDeleted())
|
|
||||||
menu.addAction (mViewAction);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCreateAction)
|
if (mCreateAction)
|
||||||
@ -95,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());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,6 +259,10 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
|
|||||||
connect (mViewAction, SIGNAL (triggered()), this, SLOT (viewRecord()));
|
connect (mViewAction, SIGNAL (triggered()), this, SLOT (viewRecord()));
|
||||||
addAction (mViewAction);
|
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()));
|
||||||
|
|
||||||
@ -417,6 +431,18 @@ void CSVWorld::Table::viewRecord()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
@ -508,20 +534,7 @@ void CSVWorld::Table::mouseMoveEvent (QMouseEvent* event)
|
|||||||
|
|
||||||
drag->setMimeData (mime);
|
drag->setMimeData (mime);
|
||||||
drag->setPixmap (QString::fromStdString (mime->getIcon()));
|
drag->setPixmap (QString::fromStdString (mime->getIcon()));
|
||||||
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ namespace CSVWorld
|
|||||||
QAction *mMoveUpAction;
|
QAction *mMoveUpAction;
|
||||||
QAction *mMoveDownAction;
|
QAction *mMoveDownAction;
|
||||||
QAction *mViewAction;
|
QAction *mViewAction;
|
||||||
|
QAction *mPreviewAction;
|
||||||
CSMWorld::IdTableProxyModel *mProxyModel;
|
CSMWorld::IdTableProxyModel *mProxyModel;
|
||||||
CSMWorld::IdTable *mModel;
|
CSMWorld::IdTable *mModel;
|
||||||
bool mEditLock;
|
bool mEditLock;
|
||||||
@ -111,6 +112,8 @@ namespace CSVWorld
|
|||||||
|
|
||||||
void viewRecord();
|
void viewRecord();
|
||||||
|
|
||||||
|
void previewRecord();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void tableSizeUpdate();
|
void tableSizeUpdate();
|
||||||
|
@ -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) {}
|
||||||
|
@ -12,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>
|
||||||
@ -192,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.
|
||||||
|
|
||||||
@ -385,8 +341,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
|||||||
|
|
||||||
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
|
||||||
|
@ -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);
|
||||||
|
@ -15,7 +15,7 @@ add_component_dir (nifoverrides
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (bsa
|
add_component_dir (bsa
|
||||||
bsa_archive bsa_file
|
bsa_archive bsa_file resources
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (nif
|
add_component_dir (nif
|
||||||
|
53
components/bsa/resources.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
|
||||||
|
#include "resources.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <OgreResourceGroupManager.h>
|
||||||
|
#include <OgreStringConverter.h>
|
||||||
|
|
||||||
|
#include "bsa_archive.hpp"
|
||||||
|
|
||||||
|
void Bsa::registerResources (const Files::Collections& collections,
|
||||||
|
const std::vector<std::string>& archives, bool useLooseFiles, bool fsStrict)
|
||||||
|
{
|
||||||
|
const Files::PathContainer& dataDirs = collections.getPaths();
|
||||||
|
|
||||||
|
int i=0;
|
||||||
|
|
||||||
|
if (useLooseFiles)
|
||||||
|
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, fsStrict, groupName);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
i=0;
|
||||||
|
for (std::vector<std::string>::const_iterator archive = archives.begin(); archive != archives.end(); ++archive)
|
||||||
|
{
|
||||||
|
if (collections.doesExist(*archive))
|
||||||
|
{
|
||||||
|
// Last BSA has the highest priority
|
||||||
|
std::string groupName = "DataBSA" + Ogre::StringConverter::toString(archives.size()-i, 8, '0');
|
||||||
|
|
||||||
|
Ogre::ResourceGroupManager::getSingleton ().createResourceGroup (groupName);
|
||||||
|
|
||||||
|
const std::string archivePath = collections.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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
components/bsa/resources.hpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef BSA_BSA_RESOURCES_H
|
||||||
|
#define BSA_BSA_RESOURCES_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "../files/collections.hpp"
|
||||||
|
|
||||||
|
namespace Bsa
|
||||||
|
{
|
||||||
|
void registerResources (const Files::Collections& collections,
|
||||||
|
const std::vector<std::string>& archives, bool useLooseFiles, bool fsStrict);
|
||||||
|
///< Register resources directories and archives as OGRE resources groups
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
BIN
files/opencs/add.png
Normal file
After Width: | Height: | Size: 520 B |
BIN
files/opencs/edit-clone.png
Normal file
After Width: | Height: | Size: 472 B |
BIN
files/opencs/edit-delete.png
Normal file
After Width: | Height: | Size: 680 B |
BIN
files/opencs/edit-preview.png
Normal file
After Width: | Height: | Size: 525 B |
BIN
files/opencs/edit-undo.png
Normal file
After Width: | Height: | Size: 650 B |
BIN
files/opencs/go-next.png
Normal file
After Width: | Height: | Size: 676 B |
BIN
files/opencs/go-previous.png
Normal file
After Width: | Height: | Size: 655 B |
@ -57,6 +57,13 @@
|
|||||||
<file>static.png</file>
|
<file>static.png</file>
|
||||||
<file>weapon.png</file>
|
<file>weapon.png</file>
|
||||||
<file>multitype.png</file>
|
<file>multitype.png</file>
|
||||||
|
<file>go-next.png</file>
|
||||||
|
<file>go-previous.png</file>
|
||||||
|
<file>edit-delete.png</file>
|
||||||
|
<file>edit-undo.png</file>
|
||||||
|
<file>edit-preview.png</file>
|
||||||
|
<file>edit-clone.png</file>
|
||||||
|
<file>add.png</file>
|
||||||
<file alias="startup/create-addon">raster/startup/big/create-addon.png</file>
|
<file alias="startup/create-addon">raster/startup/big/create-addon.png</file>
|
||||||
<file alias="startup/create-game">raster/startup/big/new-game.png</file>
|
<file alias="startup/create-game">raster/startup/big/new-game.png</file>
|
||||||
<file alias="startup/edit-content">raster/startup/big/edit-content.png</file>
|
<file alias="startup/edit-content">raster/startup/big/edit-content.png</file>
|
||||||
|