mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-05 06:45:34 +00:00
Merge branch 'load'
This commit is contained in:
commit
5b9e90744e
23 changed files with 904 additions and 249 deletions
|
@ -5,11 +5,11 @@ opencs_units (. editor)
|
||||||
set (CMAKE_BUILD_TYPE DEBUG)
|
set (CMAKE_BUILD_TYPE DEBUG)
|
||||||
|
|
||||||
opencs_units (model/doc
|
opencs_units (model/doc
|
||||||
document operation saving
|
document operation saving documentmanager loader
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (model/doc
|
opencs_units_noqt (model/doc
|
||||||
documentmanager stage savingstate savingstages
|
stage savingstate savingstages
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_hdrs_noqt (model/doc
|
opencs_hdrs_noqt (model/doc
|
||||||
|
@ -44,7 +44,7 @@ opencs_units_noqt (model/tools
|
||||||
|
|
||||||
opencs_units (view/doc
|
opencs_units (view/doc
|
||||||
viewmanager view operations operation subview startup filedialog newgame
|
viewmanager view operations operation subview startup filedialog newgame
|
||||||
filewidget adjusterwidget
|
filewidget adjusterwidget loader
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,11 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
|
||||||
mNewGame.setLocalData (mLocal);
|
mNewGame.setLocalData (mLocal);
|
||||||
mFileDialog.setLocalData (mLocal);
|
mFileDialog.setLocalData (mLocal);
|
||||||
|
|
||||||
|
connect (&mDocumentManager, SIGNAL (documentAdded (CSMDoc::Document *)),
|
||||||
|
this, SLOT (documentAdded (CSMDoc::Document *)));
|
||||||
|
connect (&mDocumentManager, SIGNAL (lastDocumentDeleted()),
|
||||||
|
this, SLOT (lastDocumentDeleted()));
|
||||||
|
|
||||||
connect (&mViewManager, SIGNAL (newGameRequest ()), this, SLOT (createGame ()));
|
connect (&mViewManager, SIGNAL (newGameRequest ()), this, SLOT (createGame ()));
|
||||||
connect (&mViewManager, SIGNAL (newAddonRequest ()), this, SLOT (createAddon ()));
|
connect (&mViewManager, SIGNAL (newAddonRequest ()), this, SLOT (createAddon ()));
|
||||||
connect (&mViewManager, SIGNAL (loadDocumentRequest ()), this, SLOT (loadDocument ()));
|
connect (&mViewManager, SIGNAL (loadDocumentRequest ()), this, SLOT (loadDocument ()));
|
||||||
|
@ -158,9 +163,8 @@ void CS::Editor::openFiles (const boost::filesystem::path &savePath)
|
||||||
foreach (const QString &path, mFileDialog.selectedFilePaths())
|
foreach (const QString &path, mFileDialog.selectedFilePaths())
|
||||||
files.push_back(path.toUtf8().constData());
|
files.push_back(path.toUtf8().constData());
|
||||||
|
|
||||||
CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, false);
|
mDocumentManager.addDocument (files, savePath, false);
|
||||||
|
|
||||||
mViewManager.addView (document);
|
|
||||||
mFileDialog.hide();
|
mFileDialog.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,9 +178,8 @@ void CS::Editor::createNewFile (const boost::filesystem::path &savePath)
|
||||||
|
|
||||||
files.push_back(mFileDialog.filename().toUtf8().constData());
|
files.push_back(mFileDialog.filename().toUtf8().constData());
|
||||||
|
|
||||||
CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, true);
|
mDocumentManager.addDocument (files, savePath, true);
|
||||||
|
|
||||||
mViewManager.addView (document);
|
|
||||||
mFileDialog.hide();
|
mFileDialog.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,9 +189,7 @@ void CS::Editor::createNewGame (const boost::filesystem::path& file)
|
||||||
|
|
||||||
files.push_back (file);
|
files.push_back (file);
|
||||||
|
|
||||||
CSMDoc::Document *document = mDocumentManager.addDocument (files, file, true);
|
mDocumentManager.addDocument (files, file, true);
|
||||||
|
|
||||||
mViewManager.addView (document);
|
|
||||||
|
|
||||||
mNewGame.hide();
|
mNewGame.hide();
|
||||||
}
|
}
|
||||||
|
@ -295,3 +296,13 @@ std::auto_ptr<sh::Factory> CS::Editor::setupGraphics()
|
||||||
|
|
||||||
return factory;
|
return factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CS::Editor::documentAdded (CSMDoc::Document *document)
|
||||||
|
{
|
||||||
|
mViewManager.addView (document);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CS::Editor::lastDocumentDeleted()
|
||||||
|
{
|
||||||
|
exit (0);
|
||||||
|
}
|
||||||
|
|
|
@ -85,6 +85,10 @@ namespace CS
|
||||||
|
|
||||||
void showSettings();
|
void showSettings();
|
||||||
|
|
||||||
|
void documentAdded (CSMDoc::Document *document);
|
||||||
|
|
||||||
|
void lastDocumentDeleted();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
QString mIpcServerName;
|
QString mIpcServerName;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
@ -18,6 +19,8 @@
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE (std::string)
|
||||||
|
|
||||||
class Application : public QApplication
|
class Application : public QApplication
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -45,6 +48,7 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
Q_INIT_RESOURCE (resources);
|
Q_INIT_RESOURCE (resources);
|
||||||
|
|
||||||
|
qRegisterMetaType<std::string> ("std::string");
|
||||||
qRegisterMetaType<CSMWorld::UniversalId> ("CSMWorld::UniversalId");
|
qRegisterMetaType<CSMWorld::UniversalId> ("CSMWorld::UniversalId");
|
||||||
|
|
||||||
OgreInit::OgreInit ogreInit;
|
OgreInit::OgreInit ogreInit;
|
||||||
|
|
|
@ -8,23 +8,6 @@
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void CSMDoc::Document::load (const std::vector<boost::filesystem::path>::const_iterator& begin,
|
|
||||||
const std::vector<boost::filesystem::path>::const_iterator& end, bool lastAsModified)
|
|
||||||
{
|
|
||||||
assert (begin!=end);
|
|
||||||
|
|
||||||
std::vector<boost::filesystem::path>::const_iterator end2 (end);
|
|
||||||
|
|
||||||
if (lastAsModified)
|
|
||||||
--end2;
|
|
||||||
|
|
||||||
for (std::vector<boost::filesystem::path>::const_iterator iter (begin); iter!=end2; ++iter)
|
|
||||||
getData().loadFile (*iter, true, false);
|
|
||||||
|
|
||||||
if (lastAsModified)
|
|
||||||
getData().loadFile (*end2, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMDoc::Document::addGmsts()
|
void CSMDoc::Document::addGmsts()
|
||||||
{
|
{
|
||||||
static const char *gmstFloats[] =
|
static const char *gmstFloats[] =
|
||||||
|
@ -2219,64 +2202,40 @@ void CSMDoc::Document::createBase()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, const std::vector< boost::filesystem::path >& files, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, bool new_)
|
CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
|
||||||
: mSavePath (savePath), mContentFiles (files), mTools (mData), mResDir(resDir),
|
const std::vector< boost::filesystem::path >& files, bool new_,
|
||||||
|
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir)
|
||||||
|
: mSavePath (savePath), mContentFiles (files), mNew (new_), mTools (mData), mResDir(resDir),
|
||||||
mProjectPath ((configuration.getUserDataPath() / "projects") /
|
mProjectPath ((configuration.getUserDataPath() / "projects") /
|
||||||
(savePath.filename().string() + ".project")),
|
(savePath.filename().string() + ".project")),
|
||||||
mSaving (*this, mProjectPath)
|
mSaving (*this, mProjectPath)
|
||||||
{
|
{
|
||||||
if (files.empty())
|
if (mContentFiles.empty())
|
||||||
throw std::runtime_error ("Empty content file sequence");
|
throw std::runtime_error ("Empty content file sequence");
|
||||||
|
|
||||||
if (new_ && files.size()==1)
|
if (!boost::filesystem::exists (mProjectPath))
|
||||||
createBase();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::vector<boost::filesystem::path>::const_iterator end = files.end();
|
|
||||||
|
|
||||||
if (new_)
|
|
||||||
--end;
|
|
||||||
|
|
||||||
load (files.begin(), end, !new_);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new_)
|
|
||||||
{
|
|
||||||
mData.setDescription ("");
|
|
||||||
mData.setAuthor ("");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool filtersFound = false;
|
|
||||||
|
|
||||||
if (boost::filesystem::exists (mProjectPath))
|
|
||||||
{
|
|
||||||
filtersFound = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
boost::filesystem::path locCustomFiltersPath (configuration.getUserDataPath());
|
boost::filesystem::path locCustomFiltersPath (configuration.getUserDataPath());
|
||||||
locCustomFiltersPath /= "defaultfilters";
|
locCustomFiltersPath /= "defaultfilters";
|
||||||
|
|
||||||
if (boost::filesystem::exists(locCustomFiltersPath))
|
if (boost::filesystem::exists (locCustomFiltersPath))
|
||||||
{
|
{
|
||||||
boost::filesystem::copy_file (locCustomFiltersPath, mProjectPath);
|
boost::filesystem::copy_file (locCustomFiltersPath, mProjectPath);
|
||||||
filtersFound = true;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
boost::filesystem::path filters(mResDir);
|
boost::filesystem::copy_file (mResDir / "defaultfilters", mProjectPath);
|
||||||
filters /= "defaultfilters";
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (boost::filesystem::exists(filters))
|
if (mNew)
|
||||||
{
|
{
|
||||||
boost::filesystem::copy_file(filters, mProjectPath);
|
mData.setDescription ("");
|
||||||
filtersFound = true;
|
mData.setAuthor ("");
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filtersFound)
|
if (mContentFiles.size()==1)
|
||||||
getData().loadFile (mProjectPath, false, true);
|
createBase();
|
||||||
|
}
|
||||||
|
|
||||||
addOptionalGmsts();
|
addOptionalGmsts();
|
||||||
addOptionalGlobals();
|
addOptionalGlobals();
|
||||||
|
@ -2288,6 +2247,7 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, co
|
||||||
|
|
||||||
connect (&mSaving, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int)));
|
connect (&mSaving, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int)));
|
||||||
connect (&mSaving, SIGNAL (done (int)), this, SLOT (operationDone (int)));
|
connect (&mSaving, SIGNAL (done (int)), this, SLOT (operationDone (int)));
|
||||||
|
|
||||||
connect (
|
connect (
|
||||||
&mSaving, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)),
|
&mSaving, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)),
|
||||||
this, SLOT (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)));
|
this, SLOT (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)));
|
||||||
|
@ -2323,11 +2283,21 @@ const boost::filesystem::path& CSMDoc::Document::getSavePath() const
|
||||||
return mSavePath;
|
return mSavePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& CSMDoc::Document::getProjectPath() const
|
||||||
|
{
|
||||||
|
return mProjectPath;
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<boost::filesystem::path>& CSMDoc::Document::getContentFiles() const
|
const std::vector<boost::filesystem::path>& CSMDoc::Document::getContentFiles() const
|
||||||
{
|
{
|
||||||
return mContentFiles;
|
return mContentFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSMDoc::Document::isNew() const
|
||||||
|
{
|
||||||
|
return mNew;
|
||||||
|
}
|
||||||
|
|
||||||
void CSMDoc::Document::save()
|
void CSMDoc::Document::save()
|
||||||
{
|
{
|
||||||
if (mSaving.isRunning())
|
if (mSaving.isRunning())
|
||||||
|
|
|
@ -39,6 +39,7 @@ namespace CSMDoc
|
||||||
|
|
||||||
boost::filesystem::path mSavePath;
|
boost::filesystem::path mSavePath;
|
||||||
std::vector<boost::filesystem::path> mContentFiles;
|
std::vector<boost::filesystem::path> mContentFiles;
|
||||||
|
bool mNew;
|
||||||
CSMWorld::Data mData;
|
CSMWorld::Data mData;
|
||||||
CSMTools::Tools mTools;
|
CSMTools::Tools mTools;
|
||||||
boost::filesystem::path mProjectPath;
|
boost::filesystem::path mProjectPath;
|
||||||
|
@ -53,10 +54,6 @@ namespace CSMDoc
|
||||||
Document (const Document&);
|
Document (const Document&);
|
||||||
Document& operator= (const Document&);
|
Document& operator= (const Document&);
|
||||||
|
|
||||||
void load (const std::vector<boost::filesystem::path>::const_iterator& begin,
|
|
||||||
const std::vector<boost::filesystem::path>::const_iterator& end, bool lastAsModified);
|
|
||||||
///< \param lastAsModified Store the last file in Modified instead of merging it into Base.
|
|
||||||
|
|
||||||
void createBase();
|
void createBase();
|
||||||
|
|
||||||
void addGmsts();
|
void addGmsts();
|
||||||
|
@ -72,9 +69,8 @@ namespace CSMDoc
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Document (const Files::ConfigurationManager& configuration,
|
Document (const Files::ConfigurationManager& configuration,
|
||||||
const std::vector< boost::filesystem::path >& files,
|
const std::vector< boost::filesystem::path >& files, bool new_,
|
||||||
const boost::filesystem::path& savePath,
|
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir);
|
||||||
const boost::filesystem::path& resDir, bool new_);
|
|
||||||
|
|
||||||
~Document();
|
~Document();
|
||||||
|
|
||||||
|
@ -84,10 +80,15 @@ namespace CSMDoc
|
||||||
|
|
||||||
const boost::filesystem::path& getSavePath() const;
|
const boost::filesystem::path& getSavePath() const;
|
||||||
|
|
||||||
|
const boost::filesystem::path& getProjectPath() const;
|
||||||
|
|
||||||
const std::vector<boost::filesystem::path>& getContentFiles() const;
|
const std::vector<boost::filesystem::path>& getContentFiles() const;
|
||||||
///< \attention The last element in this collection is the file that is being edited,
|
///< \attention The last element in this collection is the file that is being edited,
|
||||||
/// but with its original path instead of the save path.
|
/// but with its original path instead of the save path.
|
||||||
|
|
||||||
|
bool isNew() const;
|
||||||
|
///< Is this a newly created content file?
|
||||||
|
|
||||||
void save();
|
void save();
|
||||||
|
|
||||||
CSMWorld::UniversalId verify();
|
CSMWorld::UniversalId verify();
|
||||||
|
|
|
@ -19,25 +19,49 @@ CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& con
|
||||||
|
|
||||||
if (!boost::filesystem::is_directory (projectPath))
|
if (!boost::filesystem::is_directory (projectPath))
|
||||||
boost::filesystem::create_directories (projectPath);
|
boost::filesystem::create_directories (projectPath);
|
||||||
|
|
||||||
|
mLoader.moveToThread (&mLoaderThread);
|
||||||
|
mLoaderThread.start();
|
||||||
|
|
||||||
|
connect (&mLoader, SIGNAL (documentLoaded (Document *)),
|
||||||
|
this, SLOT (documentLoaded (Document *)));
|
||||||
|
connect (&mLoader, SIGNAL (documentNotLoaded (Document *, const std::string&)),
|
||||||
|
this, SLOT (documentNotLoaded (Document *, const std::string&)));
|
||||||
|
connect (this, SIGNAL (loadRequest (CSMDoc::Document *)),
|
||||||
|
&mLoader, SLOT (loadDocument (CSMDoc::Document *)));
|
||||||
|
connect (&mLoader, SIGNAL (nextStage (CSMDoc::Document *, const std::string&, int)),
|
||||||
|
this, SIGNAL (nextStage (CSMDoc::Document *, const std::string&, int)));
|
||||||
|
connect (&mLoader, SIGNAL (nextRecord (CSMDoc::Document *)),
|
||||||
|
this, SIGNAL (nextRecord (CSMDoc::Document *)));
|
||||||
|
connect (this, SIGNAL (cancelLoading (CSMDoc::Document *)),
|
||||||
|
&mLoader, SLOT (abortLoading (CSMDoc::Document *)));
|
||||||
|
connect (&mLoader, SIGNAL (loadMessage (CSMDoc::Document *, const std::string&)),
|
||||||
|
this, SIGNAL (loadMessage (CSMDoc::Document *, const std::string&)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMDoc::DocumentManager::~DocumentManager()
|
CSMDoc::DocumentManager::~DocumentManager()
|
||||||
{
|
{
|
||||||
|
mLoaderThread.quit();
|
||||||
|
mLoader.hasThingsToDo().wakeAll();
|
||||||
|
mLoaderThread.wait();
|
||||||
|
|
||||||
for (std::vector<Document *>::iterator iter (mDocuments.begin()); iter!=mDocuments.end(); ++iter)
|
for (std::vector<Document *>::iterator iter (mDocuments.begin()); iter!=mDocuments.end(); ++iter)
|
||||||
delete *iter;
|
delete *iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMDoc::Document *CSMDoc::DocumentManager::addDocument (const std::vector<boost::filesystem::path>& files, const boost::filesystem::path& savePath,
|
void CSMDoc::DocumentManager::addDocument (const std::vector<boost::filesystem::path>& files, const boost::filesystem::path& savePath,
|
||||||
bool new_)
|
bool new_)
|
||||||
{
|
{
|
||||||
Document *document = new Document (mConfiguration, files, savePath, mResDir, new_);
|
Document *document = new Document (mConfiguration, files, new_, savePath, mResDir);
|
||||||
|
|
||||||
mDocuments.push_back (document);
|
mDocuments.push_back (document);
|
||||||
|
|
||||||
return document;
|
emit loadRequest (document);
|
||||||
|
|
||||||
|
mLoader.hasThingsToDo().wakeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSMDoc::DocumentManager::removeDocument (Document *document)
|
void CSMDoc::DocumentManager::removeDocument (CSMDoc::Document *document)
|
||||||
{
|
{
|
||||||
std::vector<Document *>::iterator iter = std::find (mDocuments.begin(), mDocuments.end(), document);
|
std::vector<Document *>::iterator iter = std::find (mDocuments.begin(), mDocuments.end(), document);
|
||||||
|
|
||||||
|
@ -47,10 +71,25 @@ bool CSMDoc::DocumentManager::removeDocument (Document *document)
|
||||||
mDocuments.erase (iter);
|
mDocuments.erase (iter);
|
||||||
delete document;
|
delete document;
|
||||||
|
|
||||||
return mDocuments.empty();
|
if (mDocuments.empty())
|
||||||
|
emit lastDocumentDeleted();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMDoc::DocumentManager::setResourceDir (const boost::filesystem::path& parResDir)
|
void CSMDoc::DocumentManager::setResourceDir (const boost::filesystem::path& parResDir)
|
||||||
{
|
{
|
||||||
mResDir = boost::filesystem::system_complete(parResDir);
|
mResDir = boost::filesystem::system_complete(parResDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSMDoc::DocumentManager::documentLoaded (Document *document)
|
||||||
|
{
|
||||||
|
emit documentAdded (document);
|
||||||
|
emit loadingStopped (document, true, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMDoc::DocumentManager::documentNotLoaded (Document *document, const std::string& error)
|
||||||
|
{
|
||||||
|
emit loadingStopped (document, false, error);
|
||||||
|
|
||||||
|
if (error.empty()) // do not remove the document yet, if we have an error
|
||||||
|
removeDocument (document);
|
||||||
|
}
|
|
@ -6,6 +6,11 @@
|
||||||
|
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
#include "loader.hpp"
|
||||||
|
|
||||||
namespace Files
|
namespace Files
|
||||||
{
|
{
|
||||||
class ConfigurationManager;
|
class ConfigurationManager;
|
||||||
|
@ -15,10 +20,14 @@ namespace CSMDoc
|
||||||
{
|
{
|
||||||
class Document;
|
class Document;
|
||||||
|
|
||||||
class DocumentManager
|
class DocumentManager : public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
std::vector<Document *> mDocuments;
|
std::vector<Document *> mDocuments;
|
||||||
const Files::ConfigurationManager& mConfiguration;
|
const Files::ConfigurationManager& mConfiguration;
|
||||||
|
QThread mLoaderThread;
|
||||||
|
Loader mLoader;
|
||||||
|
|
||||||
DocumentManager (const DocumentManager&);
|
DocumentManager (const DocumentManager&);
|
||||||
DocumentManager& operator= (const DocumentManager&);
|
DocumentManager& operator= (const DocumentManager&);
|
||||||
|
@ -29,20 +38,49 @@ namespace CSMDoc
|
||||||
|
|
||||||
~DocumentManager();
|
~DocumentManager();
|
||||||
|
|
||||||
Document *addDocument (const std::vector< boost::filesystem::path >& files,
|
void addDocument (const std::vector< boost::filesystem::path >& files,
|
||||||
const boost::filesystem::path& savePath,
|
const boost::filesystem::path& savePath, bool new_);
|
||||||
bool new_);
|
///< \param new_ Do not load the last content file in \a files and instead create in an
|
||||||
///< The ownership of the returned document is not transferred to the caller.
|
|
||||||
///
|
|
||||||
/// \param new_ Do not load the last content file in \a files and instead create in an
|
|
||||||
/// appropriate way.
|
/// appropriate way.
|
||||||
|
|
||||||
bool removeDocument (Document *document);
|
|
||||||
///< \return last document removed?
|
|
||||||
void setResourceDir (const boost::filesystem::path& parResDir);
|
void setResourceDir (const boost::filesystem::path& parResDir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
boost::filesystem::path mResDir;
|
boost::filesystem::path mResDir;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void documentLoaded (Document *document);
|
||||||
|
///< The ownership of \a document is not transferred.
|
||||||
|
|
||||||
|
void documentNotLoaded (Document *document, const std::string& error);
|
||||||
|
///< Document load has been interrupted either because of a call to abortLoading
|
||||||
|
/// or a problem during loading). In the former case error will be an empty string.
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void removeDocument (CSMDoc::Document *document);
|
||||||
|
///< Emits the lastDocumentDeleted signal, if applicable.
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void documentAdded (CSMDoc::Document *document);
|
||||||
|
|
||||||
|
void loadRequest (CSMDoc::Document *document);
|
||||||
|
|
||||||
|
void lastDocumentDeleted();
|
||||||
|
|
||||||
|
void loadingStopped (CSMDoc::Document *document, bool completed,
|
||||||
|
const std::string& error);
|
||||||
|
|
||||||
|
void nextStage (CSMDoc::Document *document, const std::string& name, int steps);
|
||||||
|
|
||||||
|
void nextRecord (CSMDoc::Document *document);
|
||||||
|
|
||||||
|
void cancelLoading (CSMDoc::Document *document);
|
||||||
|
|
||||||
|
void loadMessage (CSMDoc::Document *document, const std::string& message);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
130
apps/opencs/model/doc/loader.cpp
Normal file
130
apps/opencs/model/doc/loader.cpp
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
|
||||||
|
#include "loader.hpp"
|
||||||
|
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include "../tools/reportmodel.hpp"
|
||||||
|
|
||||||
|
#include "document.hpp"
|
||||||
|
#include "state.hpp"
|
||||||
|
|
||||||
|
CSMDoc::Loader::Stage::Stage() : mFile (0), mRecordsLeft (false) {}
|
||||||
|
|
||||||
|
|
||||||
|
CSMDoc::Loader::Loader()
|
||||||
|
{
|
||||||
|
QTimer *timer = new QTimer (this);
|
||||||
|
|
||||||
|
connect (timer, SIGNAL (timeout()), this, SLOT (load()));
|
||||||
|
timer->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
QWaitCondition& CSMDoc::Loader::hasThingsToDo()
|
||||||
|
{
|
||||||
|
return mThingsToDo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMDoc::Loader::load()
|
||||||
|
{
|
||||||
|
if (mDocuments.empty())
|
||||||
|
{
|
||||||
|
mMutex.lock();
|
||||||
|
mThingsToDo.wait (&mMutex);
|
||||||
|
mMutex.unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::pair<Document *, Stage> >::iterator iter = mDocuments.begin();
|
||||||
|
|
||||||
|
Document *document = iter->first;
|
||||||
|
|
||||||
|
int size = static_cast<int> (document->getContentFiles().size());
|
||||||
|
|
||||||
|
if (document->isNew())
|
||||||
|
--size;
|
||||||
|
|
||||||
|
bool done = false;
|
||||||
|
|
||||||
|
const int batchingSize = 100;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (iter->second.mRecordsLeft)
|
||||||
|
{
|
||||||
|
CSMDoc::Stage::Messages messages;
|
||||||
|
for (int i=0; i<batchingSize; ++i) // do not flood the system with update signals
|
||||||
|
if (document->getData().continueLoading (messages))
|
||||||
|
{
|
||||||
|
iter->second.mRecordsLeft = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMWorld::UniversalId log (CSMWorld::UniversalId::Type_LoadErrorLog, 0);
|
||||||
|
|
||||||
|
for (CSMDoc::Stage::Messages::const_iterator iter (messages.begin());
|
||||||
|
iter!=messages.end(); ++iter)
|
||||||
|
{
|
||||||
|
document->getReport (log)->add (iter->first, iter->second);
|
||||||
|
emit loadMessage (document, iter->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit nextRecord (document);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iter->second.mFile<size)
|
||||||
|
{
|
||||||
|
boost::filesystem::path path = document->getContentFiles()[iter->second.mFile];
|
||||||
|
|
||||||
|
int steps = document->getData().startLoading (path, iter->second.mFile<size-1, false);
|
||||||
|
iter->second.mRecordsLeft = true;
|
||||||
|
|
||||||
|
emit nextStage (document, path.filename().string(), steps/batchingSize);
|
||||||
|
}
|
||||||
|
else if (iter->second.mFile==size)
|
||||||
|
{
|
||||||
|
int steps = document->getData().startLoading (document->getProjectPath(), false, true);
|
||||||
|
iter->second.mRecordsLeft = true;
|
||||||
|
|
||||||
|
emit nextStage (document, "Project File", steps/batchingSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
++(iter->second.mFile);
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
mDocuments.erase (iter);
|
||||||
|
emit documentNotLoaded (document, e.what());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (done)
|
||||||
|
{
|
||||||
|
mDocuments.erase (iter);
|
||||||
|
emit documentLoaded (document);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMDoc::Loader::loadDocument (CSMDoc::Document *document)
|
||||||
|
{
|
||||||
|
mDocuments.push_back (std::make_pair (document, Stage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMDoc::Loader::abortLoading (CSMDoc::Document *document)
|
||||||
|
{
|
||||||
|
for (std::vector<std::pair<Document *, Stage> >::iterator iter = mDocuments.begin();
|
||||||
|
iter!=mDocuments.end(); ++iter)
|
||||||
|
{
|
||||||
|
if (iter->first==document)
|
||||||
|
{
|
||||||
|
mDocuments.erase (iter);
|
||||||
|
emit documentNotLoaded (document, "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
71
apps/opencs/model/doc/loader.hpp
Normal file
71
apps/opencs/model/doc/loader.hpp
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
#ifndef CSM_DOC_LOADER_H
|
||||||
|
#define CSM_DOC_LOADER_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QWaitCondition>
|
||||||
|
|
||||||
|
namespace CSMDoc
|
||||||
|
{
|
||||||
|
class Document;
|
||||||
|
|
||||||
|
class Loader : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
struct Stage
|
||||||
|
{
|
||||||
|
int mFile;
|
||||||
|
bool mRecordsLeft;
|
||||||
|
|
||||||
|
Stage();
|
||||||
|
};
|
||||||
|
|
||||||
|
QMutex mMutex;
|
||||||
|
QWaitCondition mThingsToDo;
|
||||||
|
std::vector<std::pair<Document *, Stage> > mDocuments;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Loader();
|
||||||
|
|
||||||
|
QWaitCondition& hasThingsToDo();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void load();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void loadDocument (CSMDoc::Document *document);
|
||||||
|
///< The ownership of \a document is not transferred.
|
||||||
|
|
||||||
|
void abortLoading (CSMDoc::Document *document);
|
||||||
|
///< Abort loading \a docuemnt (ignored if \a document has already finished being
|
||||||
|
/// loaded). Will result in a documentNotLoaded signal, once the Loader has finished
|
||||||
|
/// cleaning up.
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void documentLoaded (Document *document);
|
||||||
|
///< The ownership of \a document is not transferred.
|
||||||
|
|
||||||
|
void documentNotLoaded (Document *document, const std::string& error);
|
||||||
|
///< Document load has been interrupted either because of a call to abortLoading
|
||||||
|
/// or a problem during loading). In the former case error will be an empty string.
|
||||||
|
|
||||||
|
void nextStage (CSMDoc::Document *document, const std::string& name, int steps);
|
||||||
|
|
||||||
|
void nextRecord (CSMDoc::Document *document);
|
||||||
|
///< \note This signal is only given once per group of records. The group size is
|
||||||
|
/// approximately the total number of records divided by the steps value of the
|
||||||
|
/// previous nextStage signal.
|
||||||
|
|
||||||
|
void loadMessage (CSMDoc::Document *document, const std::string& message);
|
||||||
|
///< Non-critical load error or warning
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -12,7 +12,8 @@ namespace CSMDoc
|
||||||
State_Saving = 8,
|
State_Saving = 8,
|
||||||
State_Verifying = 16,
|
State_Verifying = 16,
|
||||||
State_Compiling = 32, // not implemented yet
|
State_Compiling = 32, // not implemented yet
|
||||||
State_Searching = 64 // not implemented yet
|
State_Searching = 64, // not implemented yet
|
||||||
|
State_Loading = 128 // pseudo-state; can not be encountered in a loaded document
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,13 +88,17 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier()
|
||||||
|
|
||||||
CSMTools::Tools::Tools (CSMWorld::Data& data) : mData (data), mVerifier (0), mNextReportNumber (0)
|
CSMTools::Tools::Tools (CSMWorld::Data& data) : mData (data), mVerifier (0), mNextReportNumber (0)
|
||||||
{
|
{
|
||||||
for (std::map<int, ReportModel *>::iterator iter (mReports.begin()); iter!=mReports.end(); ++iter)
|
// index 0: load error log
|
||||||
delete iter->second;
|
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel));
|
||||||
|
mActiveReports.insert (std::make_pair (CSMDoc::State_Loading, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMTools::Tools::~Tools()
|
CSMTools::Tools::~Tools()
|
||||||
{
|
{
|
||||||
delete mVerifier;
|
delete mVerifier;
|
||||||
|
|
||||||
|
for (std::map<int, ReportModel *>::iterator iter (mReports.begin()); iter!=mReports.end(); ++iter)
|
||||||
|
delete iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::UniversalId CSMTools::Tools::runVerifier()
|
CSMWorld::UniversalId CSMTools::Tools::runVerifier()
|
||||||
|
@ -133,7 +137,8 @@ int CSMTools::Tools::getRunningOperations() const
|
||||||
|
|
||||||
CSMTools::ReportModel *CSMTools::Tools::getReport (const CSMWorld::UniversalId& id)
|
CSMTools::ReportModel *CSMTools::Tools::getReport (const CSMWorld::UniversalId& id)
|
||||||
{
|
{
|
||||||
if (id.getType()!=CSMWorld::UniversalId::Type_VerificationResults)
|
if (id.getType()!=CSMWorld::UniversalId::Type_VerificationResults &&
|
||||||
|
id.getType()!=CSMWorld::UniversalId::Type_LoadErrorLog)
|
||||||
throw std::logic_error ("invalid request for report model: " + id.toString());
|
throw std::logic_error ("invalid request for report model: " + id.toString());
|
||||||
|
|
||||||
return mReports.at (id.getIndex());
|
return mReports.at (id.getIndex());
|
||||||
|
|
|
@ -55,7 +55,10 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec
|
||||||
return number;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::Data::Data() : mRefs (mCells)
|
CSMWorld::Data::Data()
|
||||||
|
/// \todo set encoding properly, once config implementation has been fixed.
|
||||||
|
: mEncoder (ToUTF8::calculateEncoding ("win1252")),
|
||||||
|
mRefs (mCells), mReader (0), mDialogue (0)
|
||||||
{
|
{
|
||||||
mGlobals.addColumn (new StringIdColumn<ESM::Global>);
|
mGlobals.addColumn (new StringIdColumn<ESM::Global>);
|
||||||
mGlobals.addColumn (new RecordStateColumn<ESM::Global>);
|
mGlobals.addColumn (new RecordStateColumn<ESM::Global>);
|
||||||
|
@ -260,6 +263,8 @@ CSMWorld::Data::~Data()
|
||||||
{
|
{
|
||||||
for (std::vector<QAbstractItemModel *>::iterator iter (mModels.begin()); iter!=mModels.end(); ++iter)
|
for (std::vector<QAbstractItemModel *>::iterator iter (mModels.begin()); iter!=mModels.end(); ++iter)
|
||||||
delete *iter;
|
delete *iter;
|
||||||
|
|
||||||
|
delete mReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CSMWorld::IdCollection<ESM::Global>& CSMWorld::Data::getGlobals() const
|
const CSMWorld::IdCollection<ESM::Global>& CSMWorld::Data::getGlobals() const
|
||||||
|
@ -481,87 +486,100 @@ void CSMWorld::Data::merge()
|
||||||
mGlobals.merge();
|
mGlobals.merge();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base, bool project)
|
int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base, bool project)
|
||||||
{
|
{
|
||||||
ESM::ESMReader reader;
|
delete mReader;
|
||||||
|
mReader = 0;
|
||||||
|
mDialogue = 0;
|
||||||
|
|
||||||
/// \todo set encoding properly, once config implementation has been fixed.
|
mReader = new ESM::ESMReader;
|
||||||
ToUTF8::Utf8Encoder encoder (ToUTF8::calculateEncoding ("win1252"));
|
mReader->setEncoder (&mEncoder);
|
||||||
reader.setEncoder (&encoder);
|
mReader->open (path.string());
|
||||||
|
|
||||||
reader.open (path.string());
|
mBase = base;
|
||||||
|
mProject = project;
|
||||||
|
|
||||||
const ESM::Dialogue *dialogue = 0;
|
mAuthor = mReader->getAuthor();
|
||||||
|
mDescription = mReader->getDesc();
|
||||||
|
|
||||||
mAuthor = reader.getAuthor();
|
return mReader->getRecordCount();
|
||||||
mDescription = reader.getDesc();
|
}
|
||||||
|
|
||||||
// Note: We do not need to send update signals here, because at this point the model is not connected
|
bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
|
||||||
// to any view.
|
{
|
||||||
while (reader.hasMoreRecs())
|
if (!mReader)
|
||||||
|
throw std::logic_error ("can't continue loading, because no load has been started");
|
||||||
|
|
||||||
|
if (!mReader->hasMoreRecs())
|
||||||
{
|
{
|
||||||
ESM::NAME n = reader.getRecName();
|
delete mReader;
|
||||||
reader.getRecHeader();
|
mReader = 0;
|
||||||
|
mDialogue = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESM::NAME n = mReader->getRecName();
|
||||||
|
mReader->getRecHeader();
|
||||||
|
|
||||||
switch (n.val)
|
switch (n.val)
|
||||||
{
|
{
|
||||||
case ESM::REC_GLOB: mGlobals.load (reader, base); break;
|
case ESM::REC_GLOB: mGlobals.load (*mReader, mBase); break;
|
||||||
case ESM::REC_GMST: mGmsts.load (reader, base); break;
|
case ESM::REC_GMST: mGmsts.load (*mReader, mBase); break;
|
||||||
case ESM::REC_SKIL: mSkills.load (reader, base); break;
|
case ESM::REC_SKIL: mSkills.load (*mReader, mBase); break;
|
||||||
case ESM::REC_CLAS: mClasses.load (reader, base); break;
|
case ESM::REC_CLAS: mClasses.load (*mReader, mBase); break;
|
||||||
case ESM::REC_FACT: mFactions.load (reader, base); break;
|
case ESM::REC_FACT: mFactions.load (*mReader, mBase); break;
|
||||||
case ESM::REC_RACE: mRaces.load (reader, base); break;
|
case ESM::REC_RACE: mRaces.load (*mReader, mBase); break;
|
||||||
case ESM::REC_SOUN: mSounds.load (reader, base); break;
|
case ESM::REC_SOUN: mSounds.load (*mReader, mBase); break;
|
||||||
case ESM::REC_SCPT: mScripts.load (reader, base); break;
|
case ESM::REC_SCPT: mScripts.load (*mReader, mBase); break;
|
||||||
case ESM::REC_REGN: mRegions.load (reader, base); break;
|
case ESM::REC_REGN: mRegions.load (*mReader, mBase); break;
|
||||||
case ESM::REC_BSGN: mBirthsigns.load (reader, base); break;
|
case ESM::REC_BSGN: mBirthsigns.load (*mReader, mBase); break;
|
||||||
case ESM::REC_SPEL: mSpells.load (reader, base); break;
|
case ESM::REC_SPEL: mSpells.load (*mReader, mBase); break;
|
||||||
|
|
||||||
case ESM::REC_CELL:
|
case ESM::REC_CELL:
|
||||||
mCells.load (reader, base);
|
mCells.load (*mReader, mBase);
|
||||||
mRefs.load (reader, mCells.getSize()-1, base);
|
mRefs.load (*mReader, mCells.getSize()-1, mBase);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ESM::REC_ACTI: mReferenceables.load (reader, base, UniversalId::Type_Activator); break;
|
case ESM::REC_ACTI: mReferenceables.load (*mReader, mBase, UniversalId::Type_Activator); break;
|
||||||
case ESM::REC_ALCH: mReferenceables.load (reader, base, UniversalId::Type_Potion); break;
|
case ESM::REC_ALCH: mReferenceables.load (*mReader, mBase, UniversalId::Type_Potion); break;
|
||||||
case ESM::REC_APPA: mReferenceables.load (reader, base, UniversalId::Type_Apparatus); break;
|
case ESM::REC_APPA: mReferenceables.load (*mReader, mBase, UniversalId::Type_Apparatus); break;
|
||||||
case ESM::REC_ARMO: mReferenceables.load (reader, base, UniversalId::Type_Armor); break;
|
case ESM::REC_ARMO: mReferenceables.load (*mReader, mBase, UniversalId::Type_Armor); break;
|
||||||
case ESM::REC_BOOK: mReferenceables.load (reader, base, UniversalId::Type_Book); break;
|
case ESM::REC_BOOK: mReferenceables.load (*mReader, mBase, UniversalId::Type_Book); break;
|
||||||
case ESM::REC_CLOT: mReferenceables.load (reader, base, UniversalId::Type_Clothing); break;
|
case ESM::REC_CLOT: mReferenceables.load (*mReader, mBase, UniversalId::Type_Clothing); break;
|
||||||
case ESM::REC_CONT: mReferenceables.load (reader, base, UniversalId::Type_Container); break;
|
case ESM::REC_CONT: mReferenceables.load (*mReader, mBase, UniversalId::Type_Container); break;
|
||||||
case ESM::REC_CREA: mReferenceables.load (reader, base, UniversalId::Type_Creature); break;
|
case ESM::REC_CREA: mReferenceables.load (*mReader, mBase, UniversalId::Type_Creature); break;
|
||||||
case ESM::REC_DOOR: mReferenceables.load (reader, base, UniversalId::Type_Door); break;
|
case ESM::REC_DOOR: mReferenceables.load (*mReader, mBase, UniversalId::Type_Door); break;
|
||||||
case ESM::REC_INGR: mReferenceables.load (reader, base, UniversalId::Type_Ingredient); break;
|
case ESM::REC_INGR: mReferenceables.load (*mReader, mBase, UniversalId::Type_Ingredient); break;
|
||||||
case ESM::REC_LEVC:
|
case ESM::REC_LEVC:
|
||||||
mReferenceables.load (reader, base, UniversalId::Type_CreatureLevelledList); break;
|
mReferenceables.load (*mReader, mBase, UniversalId::Type_CreatureLevelledList); break;
|
||||||
case ESM::REC_LEVI:
|
case ESM::REC_LEVI:
|
||||||
mReferenceables.load (reader, base, UniversalId::Type_ItemLevelledList); break;
|
mReferenceables.load (*mReader, mBase, UniversalId::Type_ItemLevelledList); break;
|
||||||
case ESM::REC_LIGH: mReferenceables.load (reader, base, UniversalId::Type_Light); break;
|
case ESM::REC_LIGH: mReferenceables.load (*mReader, mBase, UniversalId::Type_Light); break;
|
||||||
case ESM::REC_LOCK: mReferenceables.load (reader, base, UniversalId::Type_Lockpick); break;
|
case ESM::REC_LOCK: mReferenceables.load (*mReader, mBase, UniversalId::Type_Lockpick); break;
|
||||||
case ESM::REC_MISC:
|
case ESM::REC_MISC:
|
||||||
mReferenceables.load (reader, base, UniversalId::Type_Miscellaneous); break;
|
mReferenceables.load (*mReader, mBase, UniversalId::Type_Miscellaneous); break;
|
||||||
case ESM::REC_NPC_: mReferenceables.load (reader, base, UniversalId::Type_Npc); break;
|
case ESM::REC_NPC_: mReferenceables.load (*mReader, mBase, UniversalId::Type_Npc); break;
|
||||||
case ESM::REC_PROB: mReferenceables.load (reader, base, UniversalId::Type_Probe); break;
|
case ESM::REC_PROB: mReferenceables.load (*mReader, mBase, UniversalId::Type_Probe); break;
|
||||||
case ESM::REC_REPA: mReferenceables.load (reader, base, UniversalId::Type_Repair); break;
|
case ESM::REC_REPA: mReferenceables.load (*mReader, mBase, UniversalId::Type_Repair); break;
|
||||||
case ESM::REC_STAT: mReferenceables.load (reader, base, UniversalId::Type_Static); break;
|
case ESM::REC_STAT: mReferenceables.load (*mReader, mBase, UniversalId::Type_Static); break;
|
||||||
case ESM::REC_WEAP: mReferenceables.load (reader, base, UniversalId::Type_Weapon); break;
|
case ESM::REC_WEAP: mReferenceables.load (*mReader, mBase, UniversalId::Type_Weapon); break;
|
||||||
|
|
||||||
case ESM::REC_DIAL:
|
case ESM::REC_DIAL:
|
||||||
{
|
{
|
||||||
std::string id = reader.getHNOString ("NAME");
|
std::string id = mReader->getHNOString ("NAME");
|
||||||
|
|
||||||
ESM::Dialogue record;
|
ESM::Dialogue record;
|
||||||
record.mId = id;
|
record.mId = id;
|
||||||
record.load (reader);
|
record.load (*mReader);
|
||||||
|
|
||||||
if (record.mType==ESM::Dialogue::Journal)
|
if (record.mType==ESM::Dialogue::Journal)
|
||||||
{
|
{
|
||||||
mJournals.load (record, base);
|
mJournals.load (record, mBase);
|
||||||
dialogue = &mJournals.getRecord (id).get();
|
mDialogue = &mJournals.getRecord (id).get();
|
||||||
}
|
}
|
||||||
else if (record.mType==ESM::Dialogue::Deleted)
|
else if (record.mType==ESM::Dialogue::Deleted)
|
||||||
{
|
{
|
||||||
dialogue = 0; // record vector can be shuffled around which would make pointer
|
mDialogue = 0; // record vector can be shuffled around which would make pointer
|
||||||
// to record invalid
|
// to record invalid
|
||||||
|
|
||||||
if (mJournals.tryDelete (id))
|
if (mJournals.tryDelete (id))
|
||||||
|
@ -574,13 +592,14 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base, b
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/// \todo report deletion of non-existing record
|
messages.push_back (std::make_pair (UniversalId::Type_None,
|
||||||
|
"Trying to delete dialogue record " + id + " which does not exist"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mTopics.load (record, base);
|
mTopics.load (record, mBase);
|
||||||
dialogue = &mTopics.getRecord (id).get();
|
mDialogue = &mTopics.getRecord (id).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -588,26 +607,28 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base, b
|
||||||
|
|
||||||
case ESM::REC_INFO:
|
case ESM::REC_INFO:
|
||||||
{
|
{
|
||||||
if (!dialogue)
|
if (!mDialogue)
|
||||||
{
|
{
|
||||||
/// \todo INFO record without matching DIAL record -> report to user
|
messages.push_back (std::make_pair (UniversalId::Type_None,
|
||||||
reader.skipRecord();
|
"Found info record not following a dialogue record"));
|
||||||
|
|
||||||
|
mReader->skipRecord();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dialogue->mType==ESM::Dialogue::Journal)
|
if (mDialogue->mType==ESM::Dialogue::Journal)
|
||||||
mJournalInfos.load (reader, base, *dialogue);
|
mJournalInfos.load (*mReader, mBase, *mDialogue);
|
||||||
else
|
else
|
||||||
mTopicInfos.load (reader, base, *dialogue);
|
mTopicInfos.load (*mReader, mBase, *mDialogue);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ESM::REC_FILT:
|
case ESM::REC_FILT:
|
||||||
|
|
||||||
if (project)
|
if (mProject)
|
||||||
{
|
{
|
||||||
mFilters.load (reader, base);
|
mFilters.load (*mReader, mBase);
|
||||||
mFilters.setData (mFilters.getSize()-1,
|
mFilters.setData (mFilters.getSize()-1,
|
||||||
mFilters.findColumnIndex (CSMWorld::Columns::ColumnId_Scope),
|
mFilters.findColumnIndex (CSMWorld::Columns::ColumnId_Scope),
|
||||||
static_cast<int> (CSMFilter::Filter::Scope_Project));
|
static_cast<int> (CSMFilter::Filter::Scope_Project));
|
||||||
|
@ -618,11 +639,13 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base, b
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
/// \todo throw an exception instead, once all records are implemented
|
messages.push_back (std::make_pair (UniversalId::Type_None,
|
||||||
/// or maybe report error and continue?
|
"Unsupported record type: " + n.toString()));
|
||||||
reader.skipRecord();
|
|
||||||
}
|
mReader->skipRecord();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSMWorld::Data::hasId (const std::string& id) const
|
bool CSMWorld::Data::hasId (const std::string& id) const
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
|
|
||||||
#include "../filter/filter.hpp"
|
#include "../filter/filter.hpp"
|
||||||
|
|
||||||
|
#include "../doc/stage.hpp"
|
||||||
|
|
||||||
#include "idcollection.hpp"
|
#include "idcollection.hpp"
|
||||||
#include "universalid.hpp"
|
#include "universalid.hpp"
|
||||||
#include "cell.hpp"
|
#include "cell.hpp"
|
||||||
|
@ -33,12 +35,19 @@
|
||||||
|
|
||||||
class QAbstractItemModel;
|
class QAbstractItemModel;
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
class ESMReader;
|
||||||
|
struct Dialogue;
|
||||||
|
}
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
class Data : public QObject
|
class Data : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
ToUTF8::Utf8Encoder mEncoder;
|
||||||
IdCollection<ESM::Global> mGlobals;
|
IdCollection<ESM::Global> mGlobals;
|
||||||
IdCollection<ESM::GameSetting> mGmsts;
|
IdCollection<ESM::GameSetting> mGmsts;
|
||||||
IdCollection<ESM::Skill> mSkills;
|
IdCollection<ESM::Skill> mSkills;
|
||||||
|
@ -62,6 +71,10 @@ namespace CSMWorld
|
||||||
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;
|
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;
|
||||||
std::string mAuthor;
|
std::string mAuthor;
|
||||||
std::string mDescription;
|
std::string mDescription;
|
||||||
|
ESM::ESMReader *mReader;
|
||||||
|
const ESM::Dialogue *mDialogue; // last loaded dialogue
|
||||||
|
bool mBase;
|
||||||
|
bool mProject;
|
||||||
|
|
||||||
// not implemented
|
// not implemented
|
||||||
Data (const Data&);
|
Data (const Data&);
|
||||||
|
@ -167,10 +180,15 @@ namespace CSMWorld
|
||||||
void merge();
|
void merge();
|
||||||
///< Merge modified into base.
|
///< Merge modified into base.
|
||||||
|
|
||||||
void loadFile (const boost::filesystem::path& path, bool base, bool project);
|
int startLoading (const boost::filesystem::path& path, bool base, bool project);
|
||||||
///< Merging content of a file into base or modified.
|
///< Begin merging content of a file into base or modified.
|
||||||
///
|
///
|
||||||
/// \param project load project file instead of content file
|
/// \param project load project file instead of content file
|
||||||
|
///
|
||||||
|
///< \return estimated number of records
|
||||||
|
|
||||||
|
bool continueLoading (CSMDoc::Stage::Messages& messages);
|
||||||
|
///< \return Finished?
|
||||||
|
|
||||||
bool hasId (const std::string& id) const;
|
bool hasId (const std::string& id) const;
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace
|
||||||
|
|
||||||
static const TypeData sNoArg[] =
|
static const TypeData sNoArg[] =
|
||||||
{
|
{
|
||||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, "empty", 0 },
|
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, "-", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Globals, "Global Variables", 0 },
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Globals, "Global Variables", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Gmsts, "Game Settings", 0 },
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Gmsts, "Game Settings", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Skills, "Skills", 0 },
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Skills, "Skills", 0 },
|
||||||
|
@ -101,6 +101,7 @@ namespace
|
||||||
static const TypeData sIndexArg[] =
|
static const TypeData sIndexArg[] =
|
||||||
{
|
{
|
||||||
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results", 0 },
|
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results", 0 },
|
||||||
|
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_LoadErrorLog, "Load Error Log", 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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,10 +97,11 @@ namespace CSMWorld
|
||||||
Type_JournalInfos,
|
Type_JournalInfos,
|
||||||
Type_JournalInfo,
|
Type_JournalInfo,
|
||||||
Type_Scene,
|
Type_Scene,
|
||||||
Type_Preview
|
Type_Preview,
|
||||||
|
Type_LoadErrorLog
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { NumberOfTypes = Type_Scene+1 };
|
enum { NumberOfTypes = Type_LoadErrorLog+1 };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
193
apps/opencs/view/doc/loader.cpp
Normal file
193
apps/opencs/view/doc/loader.cpp
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
|
||||||
|
#include "loader.hpp"
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QProgressBar>
|
||||||
|
#include <QCursor>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QCloseEvent>
|
||||||
|
#include <QListWidget>
|
||||||
|
|
||||||
|
#include "../../model/doc/document.hpp"
|
||||||
|
|
||||||
|
void CSVDoc::LoadingDocument::closeEvent (QCloseEvent *event)
|
||||||
|
{
|
||||||
|
event->ignore();
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document)
|
||||||
|
: mDocument (document), mAborted (false), mMessages (0)
|
||||||
|
{
|
||||||
|
setWindowTitle (("Opening " + document->getSavePath().filename().string()).c_str());
|
||||||
|
|
||||||
|
setMinimumWidth (400);
|
||||||
|
|
||||||
|
mLayout = new QVBoxLayout (this);
|
||||||
|
|
||||||
|
// file progress
|
||||||
|
mFile = new QLabel (this);
|
||||||
|
|
||||||
|
mLayout->addWidget (mFile);
|
||||||
|
|
||||||
|
mFileProgress = new QProgressBar (this);
|
||||||
|
|
||||||
|
mLayout->addWidget (mFileProgress);
|
||||||
|
|
||||||
|
int size = static_cast<int> (document->getContentFiles().size())+1;
|
||||||
|
if (document->isNew())
|
||||||
|
--size;
|
||||||
|
|
||||||
|
mFileProgress->setMinimum (0);
|
||||||
|
mFileProgress->setMaximum (size);
|
||||||
|
mFileProgress->setTextVisible (true);
|
||||||
|
mFileProgress->setValue (0);
|
||||||
|
|
||||||
|
// record progress
|
||||||
|
mLayout->addWidget (new QLabel ("Records", this));
|
||||||
|
|
||||||
|
mRecordProgress = new QProgressBar (this);
|
||||||
|
|
||||||
|
mLayout->addWidget (mRecordProgress);
|
||||||
|
|
||||||
|
mRecordProgress->setMinimum (0);
|
||||||
|
mRecordProgress->setTextVisible (true);
|
||||||
|
mRecordProgress->setValue (0);
|
||||||
|
|
||||||
|
// error message
|
||||||
|
mError = new QLabel (this);
|
||||||
|
mError->setWordWrap (true);
|
||||||
|
|
||||||
|
mLayout->addWidget (mError);
|
||||||
|
|
||||||
|
// buttons
|
||||||
|
mButtons = new QDialogButtonBox (QDialogButtonBox::Cancel, Qt::Horizontal, this);
|
||||||
|
|
||||||
|
mLayout->addWidget (mButtons);
|
||||||
|
|
||||||
|
setLayout (mLayout);
|
||||||
|
|
||||||
|
move (QCursor::pos());
|
||||||
|
|
||||||
|
show();
|
||||||
|
|
||||||
|
connect (mButtons, SIGNAL (rejected()), this, SLOT (cancel()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVDoc::LoadingDocument::nextStage (const std::string& name, int steps)
|
||||||
|
{
|
||||||
|
mFile->setText (QString::fromUtf8 (("Loading: " + name).c_str()));
|
||||||
|
|
||||||
|
mFileProgress->setValue (mFileProgress->value()+1);
|
||||||
|
|
||||||
|
mRecordProgress->setValue (0);
|
||||||
|
mRecordProgress->setMaximum (steps>0 ? steps : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVDoc::LoadingDocument::nextRecord()
|
||||||
|
{
|
||||||
|
int value = mRecordProgress->value()+1;
|
||||||
|
|
||||||
|
if (value<=mRecordProgress->maximum())
|
||||||
|
mRecordProgress->setValue (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVDoc::LoadingDocument::abort (const std::string& error)
|
||||||
|
{
|
||||||
|
mAborted = true;
|
||||||
|
mError->setText (QString::fromUtf8 (("Loading failed: " + error).c_str()));
|
||||||
|
mButtons->setStandardButtons (QDialogButtonBox::Close);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVDoc::LoadingDocument::addMessage (const std::string& message)
|
||||||
|
{
|
||||||
|
if (!mMessages)
|
||||||
|
{
|
||||||
|
mMessages = new QListWidget (this);
|
||||||
|
mLayout->insertWidget (4, mMessages);
|
||||||
|
}
|
||||||
|
|
||||||
|
new QListWidgetItem (QString::fromUtf8 (message.c_str()), mMessages);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVDoc::LoadingDocument::cancel()
|
||||||
|
{
|
||||||
|
if (!mAborted)
|
||||||
|
emit cancel (mDocument);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
emit close (mDocument);
|
||||||
|
deleteLater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CSVDoc::Loader::Loader() {}
|
||||||
|
|
||||||
|
CSVDoc::Loader::~Loader()
|
||||||
|
{
|
||||||
|
for (std::map<CSMDoc::Document *, LoadingDocument *>::iterator iter (mDocuments.begin());
|
||||||
|
iter!=mDocuments.end(); ++iter)
|
||||||
|
delete iter->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVDoc::Loader::add (CSMDoc::Document *document)
|
||||||
|
{
|
||||||
|
LoadingDocument *loading = new LoadingDocument (document);
|
||||||
|
mDocuments.insert (std::make_pair (document, loading));
|
||||||
|
|
||||||
|
connect (loading, SIGNAL (cancel (CSMDoc::Document *)),
|
||||||
|
this, SIGNAL (cancel (CSMDoc::Document *)));
|
||||||
|
connect (loading, SIGNAL (close (CSMDoc::Document *)),
|
||||||
|
this, SIGNAL (close (CSMDoc::Document *)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVDoc::Loader::loadingStopped (CSMDoc::Document *document, bool completed,
|
||||||
|
const std::string& error)
|
||||||
|
{
|
||||||
|
std::map<CSMDoc::Document *, LoadingDocument *>::iterator iter = mDocuments.begin();
|
||||||
|
|
||||||
|
for (; iter!=mDocuments.end(); ++iter)
|
||||||
|
if (iter->first==document)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (iter==mDocuments.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (completed || error.empty())
|
||||||
|
{
|
||||||
|
delete iter->second;
|
||||||
|
mDocuments.erase (iter);
|
||||||
|
}
|
||||||
|
else if (!completed && !error.empty())
|
||||||
|
{
|
||||||
|
iter->second->abort (error);
|
||||||
|
// Leave the window open for now (wait for the user to close it)
|
||||||
|
mDocuments.erase (iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVDoc::Loader::nextStage (CSMDoc::Document *document, const std::string& name, int steps)
|
||||||
|
{
|
||||||
|
std::map<CSMDoc::Document *, LoadingDocument *>::iterator iter = mDocuments.find (document);
|
||||||
|
|
||||||
|
if (iter!=mDocuments.end())
|
||||||
|
iter->second->nextStage (name, steps);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVDoc::Loader::nextRecord (CSMDoc::Document *document)
|
||||||
|
{
|
||||||
|
std::map<CSMDoc::Document *, LoadingDocument *>::iterator iter = mDocuments.find (document);
|
||||||
|
|
||||||
|
if (iter!=mDocuments.end())
|
||||||
|
iter->second->nextRecord();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVDoc::Loader::loadMessage (CSMDoc::Document *document, const std::string& message)
|
||||||
|
{
|
||||||
|
std::map<CSMDoc::Document *, LoadingDocument *>::iterator iter = mDocuments.find (document);
|
||||||
|
|
||||||
|
if (iter!=mDocuments.end())
|
||||||
|
iter->second->addMessage (message);
|
||||||
|
}
|
99
apps/opencs/view/doc/loader.hpp
Normal file
99
apps/opencs/view/doc/loader.hpp
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
#ifndef CSV_DOC_LOADER_H
|
||||||
|
#define CSV_DOC_LOADER_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QSignalMapper>
|
||||||
|
|
||||||
|
class QLabel;
|
||||||
|
class QProgressBar;
|
||||||
|
class QDialogButtonBox;
|
||||||
|
class QListWidget;
|
||||||
|
class QVBoxLayout;
|
||||||
|
|
||||||
|
namespace CSMDoc
|
||||||
|
{
|
||||||
|
class Document;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVDoc
|
||||||
|
{
|
||||||
|
class LoadingDocument : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
CSMDoc::Document *mDocument;
|
||||||
|
QLabel *mFile;
|
||||||
|
QProgressBar *mFileProgress;
|
||||||
|
QProgressBar *mRecordProgress;
|
||||||
|
bool mAborted;
|
||||||
|
QDialogButtonBox *mButtons;
|
||||||
|
QLabel *mError;
|
||||||
|
QListWidget *mMessages;
|
||||||
|
QVBoxLayout *mLayout;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void closeEvent (QCloseEvent *event);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
LoadingDocument (CSMDoc::Document *document);
|
||||||
|
|
||||||
|
void nextStage (const std::string& name, int steps);
|
||||||
|
|
||||||
|
void nextRecord();
|
||||||
|
|
||||||
|
void abort (const std::string& error);
|
||||||
|
|
||||||
|
void addMessage (const std::string& message);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void cancel();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void cancel (CSMDoc::Document *document);
|
||||||
|
///< Stop loading process.
|
||||||
|
|
||||||
|
void close (CSMDoc::Document *document);
|
||||||
|
///< Close stopped loading process.
|
||||||
|
};
|
||||||
|
|
||||||
|
class Loader : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
std::map<CSMDoc::Document *, LoadingDocument *> mDocuments;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Loader();
|
||||||
|
|
||||||
|
virtual ~Loader();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void cancel (CSMDoc::Document *document);
|
||||||
|
|
||||||
|
void close (CSMDoc::Document *document);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void add (CSMDoc::Document *document);
|
||||||
|
|
||||||
|
void loadingStopped (CSMDoc::Document *document, bool completed,
|
||||||
|
const std::string& error);
|
||||||
|
|
||||||
|
void nextStage (CSMDoc::Document *document, const std::string& name, int steps);
|
||||||
|
|
||||||
|
void nextRecord (CSMDoc::Document *document);
|
||||||
|
|
||||||
|
void loadMessage (CSMDoc::Document *document, const std::string& message);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -10,9 +10,12 @@
|
||||||
#include <QtGui/QApplication>
|
#include <QtGui/QApplication>
|
||||||
|
|
||||||
#include "../../model/doc/document.hpp"
|
#include "../../model/doc/document.hpp"
|
||||||
#include "../world/subviews.hpp"
|
|
||||||
#include "../tools/subviews.hpp"
|
|
||||||
#include "../../model/settings/usersettings.hpp"
|
#include "../../model/settings/usersettings.hpp"
|
||||||
|
|
||||||
|
#include "../world/subviews.hpp"
|
||||||
|
|
||||||
|
#include "../tools/subviews.hpp"
|
||||||
|
|
||||||
#include "viewmanager.hpp"
|
#include "viewmanager.hpp"
|
||||||
#include "operations.hpp"
|
#include "operations.hpp"
|
||||||
#include "subview.hpp"
|
#include "subview.hpp"
|
||||||
|
@ -47,6 +50,10 @@ void CSVDoc::View::setupFileMenu()
|
||||||
connect (mVerify, SIGNAL (triggered()), this, SLOT (verify()));
|
connect (mVerify, SIGNAL (triggered()), this, SLOT (verify()));
|
||||||
file->addAction (mVerify);
|
file->addAction (mVerify);
|
||||||
|
|
||||||
|
QAction *loadErrors = new QAction (tr ("Load Error Log"), this);
|
||||||
|
connect (loadErrors, SIGNAL (triggered()), this, SLOT (loadErrorLog()));
|
||||||
|
file->addAction (loadErrors);
|
||||||
|
|
||||||
QAction *close = new QAction (tr ("&Close"), this);
|
QAction *close = new QAction (tr ("&Close"), this);
|
||||||
connect (close, SIGNAL (triggered()), this, SLOT (close()));
|
connect (close, SIGNAL (triggered()), this, SLOT (close()));
|
||||||
file->addAction(close);
|
file->addAction(close);
|
||||||
|
@ -502,3 +509,8 @@ void CSVDoc::View::toggleShowStatusBar (bool show)
|
||||||
subView->setStatusBar (show);
|
subView->setStatusBar (show);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVDoc::View::loadErrorLog()
|
||||||
|
{
|
||||||
|
addSubView (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_LoadErrorLog, 0));
|
||||||
|
}
|
||||||
|
|
|
@ -179,6 +179,8 @@ namespace CSVDoc
|
||||||
void addJournalInfosSubView();
|
void addJournalInfosSubView();
|
||||||
|
|
||||||
void toggleShowStatusBar (bool show);
|
void toggleShowStatusBar (bool show);
|
||||||
|
|
||||||
|
void loadErrorLog();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,33 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
|
||||||
for (std::size_t i=0; i<sizeof (sMapping)/sizeof (Mapping); ++i)
|
for (std::size_t i=0; i<sizeof (sMapping)/sizeof (Mapping); ++i)
|
||||||
mDelegateFactories->add (sMapping[i].mDisplay, new CSVWorld::EnumDelegateFactory (
|
mDelegateFactories->add (sMapping[i].mDisplay, new CSVWorld::EnumDelegateFactory (
|
||||||
CSMWorld::Columns::getEnums (sMapping[i].mColumnId), sMapping[i].mAllowNone));
|
CSMWorld::Columns::getEnums (sMapping[i].mColumnId), sMapping[i].mAllowNone));
|
||||||
|
|
||||||
|
connect (&mDocumentManager, SIGNAL (loadRequest (CSMDoc::Document *)),
|
||||||
|
&mLoader, SLOT (add (CSMDoc::Document *)));
|
||||||
|
|
||||||
|
connect (
|
||||||
|
&mDocumentManager, SIGNAL (loadingStopped (CSMDoc::Document *, bool, const std::string&)),
|
||||||
|
&mLoader, SLOT (loadingStopped (CSMDoc::Document *, bool, const std::string&)));
|
||||||
|
|
||||||
|
connect (
|
||||||
|
&mDocumentManager, SIGNAL (nextStage (CSMDoc::Document *, const std::string&, int)),
|
||||||
|
&mLoader, SLOT (nextStage (CSMDoc::Document *, const std::string&, int)));
|
||||||
|
|
||||||
|
connect (
|
||||||
|
&mDocumentManager, SIGNAL (nextRecord (CSMDoc::Document *)),
|
||||||
|
&mLoader, SLOT (nextRecord (CSMDoc::Document *)));
|
||||||
|
|
||||||
|
connect (
|
||||||
|
&mDocumentManager, SIGNAL (loadMessage (CSMDoc::Document *, const std::string&)),
|
||||||
|
&mLoader, SLOT (loadMessage (CSMDoc::Document *, const std::string&)));
|
||||||
|
|
||||||
|
connect (
|
||||||
|
&mLoader, SIGNAL (cancel (CSMDoc::Document *)),
|
||||||
|
&mDocumentManager, SIGNAL (cancelLoading (CSMDoc::Document *)));
|
||||||
|
|
||||||
|
connect (
|
||||||
|
&mLoader, SIGNAL (close (CSMDoc::Document *)),
|
||||||
|
&mDocumentManager, SLOT (removeDocument (CSMDoc::Document *)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVDoc::ViewManager::~ViewManager()
|
CSVDoc::ViewManager::~ViewManager()
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "loader.hpp"
|
||||||
|
|
||||||
namespace CSMDoc
|
namespace CSMDoc
|
||||||
{
|
{
|
||||||
class Document;
|
class Document;
|
||||||
|
@ -29,6 +31,7 @@ namespace CSVDoc
|
||||||
CSVWorld::CommandDelegateFactoryCollection *mDelegateFactories;
|
CSVWorld::CommandDelegateFactoryCollection *mDelegateFactories;
|
||||||
bool mExitOnSaveStateChange;
|
bool mExitOnSaveStateChange;
|
||||||
bool mUserWarned;
|
bool mUserWarned;
|
||||||
|
Loader mLoader;
|
||||||
|
|
||||||
// not implemented
|
// not implemented
|
||||||
ViewManager (const ViewManager&);
|
ViewManager (const ViewManager&);
|
||||||
|
|
|
@ -9,4 +9,6 @@ void CSVTools::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
||||||
{
|
{
|
||||||
manager.add (CSMWorld::UniversalId::Type_VerificationResults,
|
manager.add (CSMWorld::UniversalId::Type_VerificationResults,
|
||||||
new CSVDoc::SubViewFactory<ReportSubView>);
|
new CSVDoc::SubViewFactory<ReportSubView>);
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_LoadErrorLog,
|
||||||
|
new CSVDoc::SubViewFactory<ReportSubView>);
|
||||||
}
|
}
|
Loading…
Reference in a new issue