forked from teamnwah/openmw-tes3coop
Merge branch 'master' of https://github.com/OpenMW/openmw into osg
Conflicts: apps/opencs/CMakeLists.txt
This commit is contained in:
commit
1956e2c988
59 changed files with 1118 additions and 525 deletions
|
@ -26,7 +26,7 @@ opencs_units_noqt (model/world
|
|||
universalid record commands columnbase scriptcontext cell refidcollection
|
||||
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope
|
||||
pathgrid landtexture land nestedtablewrapper nestedcollection nestedcoladapterimp nestedinfocollection
|
||||
idcompletionmanager
|
||||
idcompletionmanager metadata
|
||||
)
|
||||
|
||||
opencs_hdrs_noqt (model/world
|
||||
|
@ -64,18 +64,18 @@ opencs_units (view/world
|
|||
table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator
|
||||
cellcreator referenceablecreator referencecreator scenesubview
|
||||
infocreator scriptedit dialoguesubview previewsubview regionmap dragrecordtable nestedtable
|
||||
dialoguespinbox
|
||||
dialoguespinbox recordbuttonbar
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/world
|
||||
subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate
|
||||
scripthighlighter idvalidator dialoguecreator idcompletiondelegate
|
||||
colordelegate
|
||||
colordelegate dragdroputils
|
||||
)
|
||||
|
||||
opencs_units (view/widget
|
||||
scenetoolbar scenetool scenetoolmode pushbutton scenetooltoggle scenetoolrun modebutton
|
||||
scenetooltoggle2 completerpopup coloreditor colorpickerpopup
|
||||
scenetooltoggle2 completerpopup coloreditor colorpickerpopup droplineedit
|
||||
)
|
||||
|
||||
opencs_units (view/render
|
||||
|
|
|
@ -2280,9 +2280,6 @@ CSMDoc::Document::Document (const VFS::Manager* vfs, const Files::ConfigurationM
|
|||
|
||||
if (mNew)
|
||||
{
|
||||
mData.setDescription ("");
|
||||
mData.setAuthor ("");
|
||||
|
||||
if (mContentFiles.size()==1)
|
||||
createBase();
|
||||
}
|
||||
|
@ -2372,9 +2369,9 @@ void CSMDoc::Document::save()
|
|||
emit stateChanged (getState(), this);
|
||||
}
|
||||
|
||||
CSMWorld::UniversalId CSMDoc::Document::verify()
|
||||
CSMWorld::UniversalId CSMDoc::Document::verify (const CSMWorld::UniversalId& reportId)
|
||||
{
|
||||
CSMWorld::UniversalId id = mTools.runVerifier();
|
||||
CSMWorld::UniversalId id = mTools.runVerifier (reportId);
|
||||
emit stateChanged (getState(), this);
|
||||
return id;
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ namespace CSMDoc
|
|||
|
||||
void save();
|
||||
|
||||
CSMWorld::UniversalId verify();
|
||||
CSMWorld::UniversalId verify (const CSMWorld::UniversalId& reportId = CSMWorld::UniversalId());
|
||||
|
||||
CSMWorld::UniversalId newSearch();
|
||||
|
||||
|
|
|
@ -53,18 +53,16 @@ void CSMDoc::WriteHeaderStage::perform (int stage, Messages& messages)
|
|||
|
||||
mState.getWriter().clearMaster();
|
||||
|
||||
mState.getWriter().setFormat (0);
|
||||
|
||||
if (mSimple)
|
||||
{
|
||||
mState.getWriter().setAuthor ("");
|
||||
mState.getWriter().setDescription ("");
|
||||
mState.getWriter().setRecordCount (0);
|
||||
mState.getWriter().setFormat (ESM::Header::CurrentFormat);
|
||||
}
|
||||
else
|
||||
{
|
||||
mState.getWriter().setAuthor (mDocument.getData().getAuthor());
|
||||
mState.getWriter().setDescription (mDocument.getData().getDescription());
|
||||
mDocument.getData().getMetaData().save (mState.getWriter());
|
||||
mState.getWriter().setRecordCount (
|
||||
mDocument.getData().count (CSMWorld::RecordBase::State_Modified) +
|
||||
mDocument.getData().count (CSMWorld::RecordBase::State_ModifiedOnly) +
|
||||
|
|
|
@ -339,6 +339,14 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
|
|||
formatId->setToolTip ("(Default: Blue) Use one of the following formats:" + tooltip);
|
||||
}
|
||||
|
||||
declareSection ("general-input", "General Input");
|
||||
{
|
||||
Setting *cycle = createSetting (Type_CheckBox, "cycle", "Cyclic next/previous");
|
||||
cycle->setDefaultValue ("false");
|
||||
cycle->setToolTip ("When using next/previous functions at the last/first item of a "
|
||||
"list go to the first/last item");
|
||||
}
|
||||
|
||||
{
|
||||
/******************************************************************
|
||||
* There are three types of values:
|
||||
|
|
|
@ -30,9 +30,9 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message
|
|||
|
||||
// check the number of pathgrid points
|
||||
if (pathgrid.mData.mS2 > static_cast<int>(pathgrid.mPoints.size()))
|
||||
messages.push_back (std::make_pair (id, pathgrid.mId + " has less points than expected"));
|
||||
messages.add (id, pathgrid.mId + " has less points than expected", "", CSMDoc::Message::Severity_Error);
|
||||
else if (pathgrid.mData.mS2 > static_cast<int>(pathgrid.mPoints.size()))
|
||||
messages.push_back (std::make_pair (id, pathgrid.mId + " has more points than expected"));
|
||||
messages.add (id, pathgrid.mId + " has more points than expected", "", CSMDoc::Message::Severity_Error);
|
||||
|
||||
std::vector<CSMTools::Point> pointList(pathgrid.mPoints.size());
|
||||
std::vector<int> duplList;
|
||||
|
@ -51,7 +51,7 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message
|
|||
std::ostringstream ss;
|
||||
ss << "has a duplicate edge between points" << pathgrid.mEdges[i].mV0
|
||||
<< " and " << pathgrid.mEdges[i].mV1;
|
||||
messages.push_back (std::make_pair (id, pathgrid.mId + ss.str()));
|
||||
messages.add (id, pathgrid.mId + ss.str(), "", CSMDoc::Message::Severity_Error);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message
|
|||
{
|
||||
std::ostringstream ss;
|
||||
ss << " has an edge connecting a non-existent point " << pathgrid.mEdges[i].mV0;
|
||||
messages.push_back (std::make_pair (id, pathgrid.mId + ss.str()));
|
||||
messages.add (id, pathgrid.mId + ss.str(), "", CSMDoc::Message::Severity_Error);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,13 +75,13 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message
|
|||
{
|
||||
std::ostringstream ss;
|
||||
ss << " has has less edges than expected for point " << i;
|
||||
messages.push_back (std::make_pair (id, pathgrid.mId + ss.str()));
|
||||
messages.add (id, pathgrid.mId + ss.str(), "", CSMDoc::Message::Severity_Error);
|
||||
}
|
||||
else if (pathgrid.mPoints[i].mConnectionNum < pointList[i].mConnectionNum)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << " has has more edges than expected for point " << i;
|
||||
messages.push_back (std::make_pair (id, pathgrid.mId + ss.str()));
|
||||
messages.add (id, pathgrid.mId + ss.str(), "", CSMDoc::Message::Severity_Error);
|
||||
}
|
||||
|
||||
// check that edges are bidirectional
|
||||
|
@ -101,7 +101,7 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message
|
|||
{
|
||||
std::ostringstream ss;
|
||||
ss << " has a missing edge between points " << i << " and " << pointList[i].mOtherIndex[j];
|
||||
messages.push_back (std::make_pair (id, pathgrid.mId + ss.str()));
|
||||
messages.add (id, pathgrid.mId + ss.str(), "", CSMDoc::Message::Severity_Error);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,7 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message
|
|||
<< ") x=" << pathgrid.mPoints[i].mX
|
||||
<< ", y=" << pathgrid.mPoints[i].mY
|
||||
<< ", z=" << pathgrid.mPoints[i].mZ;
|
||||
messages.push_back (std::make_pair (id, pathgrid.mId + ss.str()));
|
||||
messages.add (id, pathgrid.mId + ss.str(), "", CSMDoc::Message::Severity_Warning);
|
||||
|
||||
duplList.push_back(i);
|
||||
break;
|
||||
|
@ -143,7 +143,7 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message
|
|||
<< ") x=" << pathgrid.mPoints[i].mX
|
||||
<< ", y=" << pathgrid.mPoints[i].mY
|
||||
<< ", z=" << pathgrid.mPoints[i].mZ;
|
||||
messages.push_back (std::make_pair (id, pathgrid.mId + ss.str()));
|
||||
messages.add (id, pathgrid.mId + ss.str(), "", CSMDoc::Message::Severity_Warning);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
|||
|
||||
void CSMTools::ScriptCheckStage::updateUserSetting (const QString& name, const QStringList& value)
|
||||
{
|
||||
if (name=="script-editor/warnings")
|
||||
if (name=="script-editor/warnings" && !value.isEmpty())
|
||||
{
|
||||
if (value.at (0)=="Ignore")
|
||||
mWarningMode = Mode_Ignore;
|
||||
|
|
|
@ -146,14 +146,19 @@ CSMTools::Tools::~Tools()
|
|||
delete iter->second;
|
||||
}
|
||||
|
||||
CSMWorld::UniversalId CSMTools::Tools::runVerifier()
|
||||
CSMWorld::UniversalId CSMTools::Tools::runVerifier (const CSMWorld::UniversalId& reportId)
|
||||
{
|
||||
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel));
|
||||
mActiveReports[CSMDoc::State_Verifying] = mNextReportNumber-1;
|
||||
int reportNumber = reportId.getType()==CSMWorld::UniversalId::Type_VerificationResults ?
|
||||
reportId.getIndex() : mNextReportNumber++;
|
||||
|
||||
if (mReports.find (reportNumber)==mReports.end())
|
||||
mReports.insert (std::make_pair (reportNumber, new ReportModel));
|
||||
|
||||
mActiveReports[CSMDoc::State_Verifying] = reportNumber;
|
||||
|
||||
getVerifier()->start();
|
||||
|
||||
return CSMWorld::UniversalId (CSMWorld::UniversalId::Type_VerificationResults, mNextReportNumber-1);
|
||||
return CSMWorld::UniversalId (CSMWorld::UniversalId::Type_VerificationResults, reportNumber);
|
||||
}
|
||||
|
||||
CSMWorld::UniversalId CSMTools::Tools::newSearch()
|
||||
|
|
|
@ -57,8 +57,11 @@ namespace CSMTools
|
|||
|
||||
virtual ~Tools();
|
||||
|
||||
CSMWorld::UniversalId runVerifier();
|
||||
///< \return ID of the report for this verification run
|
||||
/// \param reportId If a valid VerificationResults ID, run verifier for the
|
||||
/// specified report instead of creating a new one.
|
||||
///
|
||||
/// \return ID of the report for this verification run
|
||||
CSMWorld::UniversalId runVerifier (const CSMWorld::UniversalId& reportId = CSMWorld::UniversalId());
|
||||
|
||||
/// Return ID of the report for this search.
|
||||
CSMWorld::UniversalId newSearch();
|
||||
|
|
|
@ -100,7 +100,8 @@ bool CSMWorld::ColumnBase::isId (Display display)
|
|||
|
||||
bool CSMWorld::ColumnBase::isText (Display display)
|
||||
{
|
||||
return display==Display_String || display==Display_LongString;
|
||||
return display==Display_String || display==Display_LongString ||
|
||||
display==Display_String32 || display==Display_LongString256;
|
||||
}
|
||||
|
||||
bool CSMWorld::ColumnBase::isScript (Display display)
|
||||
|
|
|
@ -123,6 +123,8 @@ namespace CSMWorld
|
|||
Display_InfoCondVar,
|
||||
Display_InfoCondComp,
|
||||
Display_RaceSkill,
|
||||
Display_String32,
|
||||
Display_LongString256,
|
||||
|
||||
//top level columns that nest other columns
|
||||
Display_NestedHeader
|
||||
|
|
|
@ -2308,6 +2308,78 @@ namespace CSMWorld
|
|||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct FormatColumn : public Column<ESXRecordT>
|
||||
{
|
||||
FormatColumn()
|
||||
: Column<ESXRecordT> (Columns::ColumnId_FileFormat, ColumnBase::Display_Integer)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mFormat;
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct AuthorColumn : public Column<ESXRecordT>
|
||||
{
|
||||
AuthorColumn()
|
||||
: Column<ESXRecordT> (Columns::ColumnId_Author, ColumnBase::Display_String32)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return QString::fromUtf8 (record.get().mAuthor.c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mAuthor = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct FileDescriptionColumn : public Column<ESXRecordT>
|
||||
{
|
||||
FileDescriptionColumn()
|
||||
: Column<ESXRecordT> (Columns::ColumnId_FileDescription, ColumnBase::Display_LongString256)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return QString::fromUtf8 (record.get().mDescription.c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mDescription = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -311,6 +311,10 @@ namespace CSMWorld
|
|||
{ ColumnId_WaterLevel, "Water Level" },
|
||||
{ ColumnId_MapColor, "Map Color" },
|
||||
|
||||
{ ColumnId_FileFormat, "File Format" },
|
||||
{ ColumnId_FileDescription, "File Description" },
|
||||
{ ColumnId_Author, "Author" },
|
||||
|
||||
{ ColumnId_UseValue1, "Use value 1" },
|
||||
{ ColumnId_UseValue2, "Use value 2" },
|
||||
{ ColumnId_UseValue3, "Use value 3" },
|
||||
|
|
|
@ -302,6 +302,10 @@ namespace CSMWorld
|
|||
ColumnId_WaterLevel = 273,
|
||||
ColumnId_MapColor = 274,
|
||||
|
||||
ColumnId_FileFormat = 275,
|
||||
ColumnId_FileDescription = 276,
|
||||
ColumnId_Author = 277,
|
||||
|
||||
// Allocated to a separate value range, so we don't get a collision should we ever need
|
||||
// to extend the number of use values.
|
||||
ColumnId_UseValue1 = 0x10000,
|
||||
|
|
|
@ -475,6 +475,14 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
|
|||
mDebugProfiles.addColumn (new ScriptColumn<ESM::DebugProfile> (
|
||||
ScriptColumn<ESM::DebugProfile>::Type_Lines));
|
||||
|
||||
mMetaData.appendBlankRecord ("sys::meta");
|
||||
|
||||
mMetaData.addColumn (new StringIdColumn<MetaData> (true));
|
||||
mMetaData.addColumn (new RecordStateColumn<MetaData>);
|
||||
mMetaData.addColumn (new FormatColumn<MetaData>);
|
||||
mMetaData.addColumn (new AuthorColumn<MetaData>);
|
||||
mMetaData.addColumn (new FileDescriptionColumn<MetaData>);
|
||||
|
||||
addModel (new IdTable (&mGlobals), UniversalId::Type_Global);
|
||||
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmst);
|
||||
addModel (new IdTable (&mSkills), UniversalId::Type_Skill);
|
||||
|
@ -515,6 +523,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
|
|||
UniversalId::Type_Texture);
|
||||
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Videos)),
|
||||
UniversalId::Type_Video);
|
||||
addModel (new IdTable (&mMetaData), UniversalId::Type_MetaData);
|
||||
|
||||
mRefLoadCache.clear(); // clear here rather than startLoading() and continueLoading() for multiple content files
|
||||
}
|
||||
|
@ -813,6 +822,11 @@ const CSMWorld::Resources& CSMWorld::Data::getResources (const UniversalId& id)
|
|||
return mResourcesManager.get (id.getType());
|
||||
}
|
||||
|
||||
const CSMWorld::MetaData& CSMWorld::Data::getMetaData() const
|
||||
{
|
||||
return mMetaData.getRecord (0).get();
|
||||
}
|
||||
|
||||
QAbstractItemModel *CSMWorld::Data::getTableModel (const CSMWorld::UniversalId& id)
|
||||
{
|
||||
std::map<UniversalId::Type, QAbstractItemModel *>::iterator iter = mModelIndex.find (id.getType());
|
||||
|
@ -857,8 +871,14 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base
|
|||
mBase = base;
|
||||
mProject = project;
|
||||
|
||||
mAuthor = mReader->getAuthor();
|
||||
mDescription = mReader->getDesc();
|
||||
if (!mProject && !mBase)
|
||||
{
|
||||
MetaData metaData;
|
||||
metaData.mId = "sys::meta";
|
||||
metaData.load (*mReader);
|
||||
|
||||
mMetaData.setRecord (0, Record<MetaData> (RecordBase::State_ModifiedOnly, 0, &metaData));
|
||||
}
|
||||
|
||||
return mReader->getRecordCount();
|
||||
}
|
||||
|
@ -1113,26 +1133,6 @@ int CSMWorld::Data::count (RecordBase::State state) const
|
|||
count (state, mPathgrids);
|
||||
}
|
||||
|
||||
void CSMWorld::Data::setDescription (const std::string& description)
|
||||
{
|
||||
mDescription = description;
|
||||
}
|
||||
|
||||
std::string CSMWorld::Data::getDescription() const
|
||||
{
|
||||
return mDescription;
|
||||
}
|
||||
|
||||
void CSMWorld::Data::setAuthor (const std::string& author)
|
||||
{
|
||||
mAuthor = author;
|
||||
}
|
||||
|
||||
std::string CSMWorld::Data::getAuthor() const
|
||||
{
|
||||
return mAuthor;
|
||||
}
|
||||
|
||||
std::vector<std::string> CSMWorld::Data::getIds (bool listDeleted) const
|
||||
{
|
||||
std::vector<std::string> ids;
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "infocollection.hpp"
|
||||
#include "nestedinfocollection.hpp"
|
||||
#include "pathgrid.hpp"
|
||||
#include "metadata.hpp"
|
||||
#ifndef Q_MOC_RUN
|
||||
#include "subcellcollection.hpp"
|
||||
#endif
|
||||
|
@ -101,11 +102,10 @@ namespace CSMWorld
|
|||
RefIdCollection mReferenceables;
|
||||
RefCollection mRefs;
|
||||
IdCollection<ESM::Filter> mFilters;
|
||||
Collection<MetaData> mMetaData;
|
||||
const ResourcesManager& mResourcesManager;
|
||||
std::vector<QAbstractItemModel *> mModels;
|
||||
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;
|
||||
std::string mAuthor;
|
||||
std::string mDescription;
|
||||
ESM::ESMReader *mReader;
|
||||
const ESM::Dialogue *mDialogue; // last loaded dialogue
|
||||
bool mBase;
|
||||
|
@ -253,6 +253,8 @@ namespace CSMWorld
|
|||
/// Throws an exception, if \a id does not match a resources list.
|
||||
const Resources& getResources (const UniversalId& id) const;
|
||||
|
||||
const MetaData& getMetaData() const;
|
||||
|
||||
QAbstractItemModel *getTableModel (const UniversalId& id);
|
||||
///< If no table model is available for \a id, an exception is thrown.
|
||||
///
|
||||
|
@ -282,14 +284,6 @@ namespace CSMWorld
|
|||
int count (RecordBase::State state) const;
|
||||
///< Return number of top-level records with the given \a state.
|
||||
|
||||
void setDescription (const std::string& description);
|
||||
|
||||
std::string getDescription() const;
|
||||
|
||||
void setAuthor (const std::string& author);
|
||||
|
||||
std::string getAuthor() const;
|
||||
|
||||
signals:
|
||||
|
||||
void idListChanged();
|
||||
|
|
|
@ -97,7 +97,8 @@ bool CSMWorld::InfoCollection::reorderRows (int baseIndex, const std::vector<int
|
|||
return false;
|
||||
|
||||
// Check that topics match
|
||||
if (getRecord (baseIndex).get().mTopicId!=getRecord (lastIndex).get().mTopicId)
|
||||
if (!Misc::StringUtils::ciEqual(getRecord(baseIndex).get().mTopicId,
|
||||
getRecord(lastIndex).get().mTopicId))
|
||||
return false;
|
||||
|
||||
// reorder
|
||||
|
|
|
@ -1,12 +1,24 @@
|
|||
#include "infotableproxymodel.hpp"
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#include "idtablebase.hpp"
|
||||
#include "columns.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
QString toLower(const QString &str)
|
||||
{
|
||||
return QString::fromUtf8(Misc::StringUtils::lowerCase(str.toStdString()).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
CSMWorld::InfoTableProxyModel::InfoTableProxyModel(CSMWorld::UniversalId::Type type, QObject *parent)
|
||||
: IdTableProxyModel(parent),
|
||||
mType(type),
|
||||
mSourceModel(NULL)
|
||||
mSourceModel(NULL),
|
||||
mInfoColumnId(type == UniversalId::Type_TopicInfos ? Columns::ColumnId_Topic :
|
||||
Columns::ColumnId_Journal)
|
||||
{
|
||||
Q_ASSERT(type == UniversalId::Type_TopicInfos || type == UniversalId::Type_JournalInfos);
|
||||
}
|
||||
|
@ -15,44 +27,53 @@ void CSMWorld::InfoTableProxyModel::setSourceModel(QAbstractItemModel *sourceMod
|
|||
{
|
||||
IdTableProxyModel::setSourceModel(sourceModel);
|
||||
mSourceModel = dynamic_cast<IdTableBase *>(sourceModel);
|
||||
connect(mSourceModel,
|
||||
SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
|
||||
this,
|
||||
SLOT(modelDataChanged(const QModelIndex &, const QModelIndex &)));
|
||||
mFirstRowCache.clear();
|
||||
if (mSourceModel != NULL)
|
||||
{
|
||||
connect(mSourceModel,
|
||||
SIGNAL(rowsInserted(const QModelIndex &, int, int)),
|
||||
this,
|
||||
SLOT(modelRowsChanged(const QModelIndex &, int, int)));
|
||||
connect(mSourceModel,
|
||||
SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
|
||||
this,
|
||||
SLOT(modelRowsChanged(const QModelIndex &, int, int)));
|
||||
mFirstRowCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool CSMWorld::InfoTableProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||
{
|
||||
QModelIndex first = mSourceModel->index(getFirstInfoRow(left.row()), left.column());
|
||||
QModelIndex second = mSourceModel->index(getFirstInfoRow(right.row()), right.column());
|
||||
|
||||
// If both indexes are belonged to the same Topic/Journal, compare their original rows only
|
||||
if (first.row() == second.row())
|
||||
{
|
||||
return sortOrder() == Qt::AscendingOrder ? left.row() < right.row() : right.row() < left.row();
|
||||
}
|
||||
return IdTableProxyModel::lessThan(first, second);
|
||||
}
|
||||
|
||||
int CSMWorld::InfoTableProxyModel::getFirstInfoRow(int currentRow) const
|
||||
{
|
||||
Columns::ColumnId columnId = Columns::ColumnId_Topic;
|
||||
if (mType == UniversalId::Type_JournalInfos)
|
||||
{
|
||||
columnId = Columns::ColumnId_Journal;
|
||||
}
|
||||
|
||||
int column = mSourceModel->findColumnIndex(columnId);
|
||||
QString info = mSourceModel->data(mSourceModel->index(currentRow, column)).toString();
|
||||
int row = currentRow;
|
||||
int column = mSourceModel->findColumnIndex(mInfoColumnId);
|
||||
QString info = toLower(mSourceModel->data(mSourceModel->index(row, column)).toString());
|
||||
|
||||
if (mFirstRowCache.contains(info))
|
||||
{
|
||||
return mFirstRowCache[info];
|
||||
}
|
||||
|
||||
while (--currentRow >= 0 &&
|
||||
mSourceModel->data(mSourceModel->index(currentRow, column)) == info);
|
||||
while (--row >= 0 &&
|
||||
toLower(mSourceModel->data(mSourceModel->index(row, column)).toString()) == info);
|
||||
++row;
|
||||
|
||||
mFirstRowCache[info] = currentRow + 1;
|
||||
return currentRow + 1;
|
||||
mFirstRowCache[info] = row;
|
||||
return row;
|
||||
}
|
||||
|
||||
void CSMWorld::InfoTableProxyModel::modelDataChanged(const QModelIndex &/*topLeft*/, const QModelIndex &/*bottomRight*/)
|
||||
void CSMWorld::InfoTableProxyModel::modelRowsChanged(const QModelIndex &/*parent*/, int /*start*/, int /*end*/)
|
||||
{
|
||||
mFirstRowCache.clear();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <QHash>
|
||||
|
||||
#include "idtableproxymodel.hpp"
|
||||
#include "columns.hpp"
|
||||
#include "universalid.hpp"
|
||||
|
||||
namespace CSMWorld
|
||||
|
@ -16,6 +17,8 @@ namespace CSMWorld
|
|||
|
||||
UniversalId::Type mType;
|
||||
IdTableBase *mSourceModel;
|
||||
Columns::ColumnId mInfoColumnId;
|
||||
///< Contains ID for Topic or Journal ID
|
||||
|
||||
mutable QHash<QString, int> mFirstRowCache;
|
||||
|
||||
|
@ -31,7 +34,7 @@ namespace CSMWorld
|
|||
virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
|
||||
|
||||
private slots:
|
||||
void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
|
||||
void modelRowsChanged(const QModelIndex &parent, int start, int end);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
27
apps/opencs/model/world/metadata.cpp
Normal file
27
apps/opencs/model/world/metadata.cpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
|
||||
#include "metadata.hpp"
|
||||
|
||||
#include <components/esm/loadtes3.hpp>
|
||||
#include <components/esm/esmreader.hpp>
|
||||
#include <components/esm/esmwriter.hpp>
|
||||
|
||||
void CSMWorld::MetaData::blank()
|
||||
{
|
||||
mFormat = ESM::Header::CurrentFormat;
|
||||
mAuthor.clear();
|
||||
mDescription.clear();
|
||||
}
|
||||
|
||||
void CSMWorld::MetaData::load (ESM::ESMReader& esm)
|
||||
{
|
||||
mFormat = esm.getHeader().mFormat;
|
||||
mAuthor = esm.getHeader().mData.author.toString();
|
||||
mDescription = esm.getHeader().mData.desc.toString();
|
||||
}
|
||||
|
||||
void CSMWorld::MetaData::save (ESM::ESMWriter& esm) const
|
||||
{
|
||||
esm.setFormat (mFormat);
|
||||
esm.setAuthor (mAuthor);
|
||||
esm.setDescription (mDescription);
|
||||
}
|
29
apps/opencs/model/world/metadata.hpp
Normal file
29
apps/opencs/model/world/metadata.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef CSM_WOLRD_METADATA_H
|
||||
#define CSM_WOLRD_METADATA_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
class ESMReader;
|
||||
class ESMWriter;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
struct MetaData
|
||||
{
|
||||
std::string mId;
|
||||
|
||||
int mFormat;
|
||||
std::string mAuthor;
|
||||
std::string mDescription;
|
||||
|
||||
void blank();
|
||||
|
||||
void load (ESM::ESMReader& esm);
|
||||
void save (ESM::ESMWriter& esm) const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -192,4 +192,8 @@ void CSMWorld::NestedTableProxyModel::forwardDataChanged (const QModelIndex& top
|
|||
emit dataChanged(index(0,0),
|
||||
index(mMainModel->rowCount(parent)-1, mMainModel->columnCount(parent)-1));
|
||||
}
|
||||
else if (topLeft.parent() == parent && bottomRight.parent() == parent)
|
||||
{
|
||||
emit dataChanged(index(topLeft.row(), topLeft.column()), index(bottomRight.row(), bottomRight.column()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -264,6 +264,8 @@ namespace
|
|||
{ CSMWorld::UniversalId::Type_Texture, CSMWorld::ColumnBase::Display_Texture },
|
||||
{ CSMWorld::UniversalId::Type_Video, CSMWorld::ColumnBase::Display_Video },
|
||||
{ CSMWorld::UniversalId::Type_Global, CSMWorld::ColumnBase::Display_GlobalVariable },
|
||||
{ CSMWorld::UniversalId::Type_BodyPart, CSMWorld::ColumnBase::Display_BodyPart },
|
||||
{ CSMWorld::UniversalId::Type_Enchantment, CSMWorld::ColumnBase::Display_Enchantment },
|
||||
|
||||
{ CSMWorld::UniversalId::Type_None, CSMWorld::ColumnBase::Display_None } // end marker
|
||||
};
|
||||
|
|
|
@ -56,6 +56,7 @@ namespace
|
|||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_MagicEffects, "Magic Effects", 0 },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Pathgrids, "Pathgrids", 0 },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_StartScripts, "Start Scripts", 0 },
|
||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_MetaDatas, "Meta Data Table", 0 },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
||||
};
|
||||
|
@ -120,6 +121,7 @@ namespace
|
|||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_MagicEffect, "Magic Effect", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Pathgrid, "Pathgrid", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_StartScript, "Start Script", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_MetaData, "Meta Data", 0 },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
||||
};
|
||||
|
|
|
@ -131,6 +131,8 @@ namespace CSMWorld
|
|||
Type_StartScripts,
|
||||
Type_StartScript,
|
||||
Type_Search,
|
||||
Type_MetaDatas,
|
||||
Type_MetaData,
|
||||
Type_RunLog
|
||||
};
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ void CSVDoc::SubView::setUniversalId (const CSMWorld::UniversalId& id)
|
|||
{
|
||||
mUniversalId = id;
|
||||
setWindowTitle (QString::fromUtf8(mUniversalId.toString().c_str()));
|
||||
emit universalIdChanged (mUniversalId);
|
||||
}
|
||||
|
||||
void CSVDoc::SubView::closeEvent (QCloseEvent *event)
|
||||
|
|
|
@ -68,6 +68,8 @@ namespace CSVDoc
|
|||
|
||||
void updateSubViewIndicies (SubView *view = 0);
|
||||
|
||||
void universalIdChanged (const CSMWorld::UniversalId& universalId);
|
||||
|
||||
protected slots:
|
||||
|
||||
void closeRequest();
|
||||
|
|
|
@ -70,6 +70,10 @@ void CSVDoc::View::setupFileMenu()
|
|||
connect (loadErrors, SIGNAL (triggered()), this, SLOT (loadErrorLog()));
|
||||
file->addAction (loadErrors);
|
||||
|
||||
QAction *meta = new QAction (tr ("Meta Data"), this);
|
||||
connect (meta, SIGNAL (triggered()), this, SLOT (addMetaDataSubView()));
|
||||
file->addAction (meta);
|
||||
|
||||
QAction *close = new QAction (tr ("&Close"), this);
|
||||
connect (close, SIGNAL (triggered()), this, SLOT (close()));
|
||||
file->addAction(close);
|
||||
|
@ -813,6 +817,11 @@ void CSVDoc::View::addSearchSubView()
|
|||
addSubView (mDocument->newSearch());
|
||||
}
|
||||
|
||||
void CSVDoc::View::addMetaDataSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_MetaData, "sys::meta"));
|
||||
}
|
||||
|
||||
void CSVDoc::View::abortOperation (int type)
|
||||
{
|
||||
mDocument->abortOperation (type);
|
||||
|
|
|
@ -224,6 +224,8 @@ namespace CSVDoc
|
|||
|
||||
void addSearchSubView();
|
||||
|
||||
void addMetaDataSubView();
|
||||
|
||||
void toggleShowStatusBar (bool show);
|
||||
|
||||
void loadErrorLog();
|
||||
|
|
|
@ -4,12 +4,23 @@
|
|||
#include "reporttable.hpp"
|
||||
|
||||
CSVTools::ReportSubView::ReportSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
|
||||
: CSVDoc::SubView (id)
|
||||
: CSVDoc::SubView (id), mDocument (document), mRefreshState (0)
|
||||
{
|
||||
setWidget (mTable = new ReportTable (document, id, false, this));
|
||||
if (id.getType()==CSMWorld::UniversalId::Type_VerificationResults)
|
||||
mRefreshState = CSMDoc::State_Verifying;
|
||||
|
||||
setWidget (mTable = new ReportTable (document, id, false, mRefreshState, this));
|
||||
|
||||
connect (mTable, SIGNAL (editRequest (const CSMWorld::UniversalId&, const std::string&)),
|
||||
SIGNAL (focusId (const CSMWorld::UniversalId&, const std::string&)));
|
||||
|
||||
if (mRefreshState==CSMDoc::State_Verifying)
|
||||
{
|
||||
connect (mTable, SIGNAL (refreshRequest()), this, SLOT (refreshRequest()));
|
||||
|
||||
connect (&document, SIGNAL (stateChanged (int, CSMDoc::Document *)),
|
||||
mTable, SLOT (stateChanged (int, CSMDoc::Document *)));
|
||||
}
|
||||
}
|
||||
|
||||
void CSVTools::ReportSubView::setEditLock (bool locked)
|
||||
|
@ -21,3 +32,15 @@ void CSVTools::ReportSubView::updateUserSetting (const QString &name, const QStr
|
|||
{
|
||||
mTable->updateUserSetting (name, list);
|
||||
}
|
||||
|
||||
void CSVTools::ReportSubView::refreshRequest()
|
||||
{
|
||||
if (!(mDocument.getState() & mRefreshState))
|
||||
{
|
||||
if (mRefreshState==CSMDoc::State_Verifying)
|
||||
{
|
||||
mTable->clear();
|
||||
mDocument.verify (getUniversalId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ namespace CSVTools
|
|||
Q_OBJECT
|
||||
|
||||
ReportTable *mTable;
|
||||
CSMDoc::Document& mDocument;
|
||||
int mRefreshState;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -28,6 +30,10 @@ namespace CSVTools
|
|||
virtual void setEditLock (bool locked);
|
||||
|
||||
virtual void updateUserSetting (const QString &, const QStringList &);
|
||||
|
||||
private slots:
|
||||
|
||||
void refreshRequest();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -74,9 +74,11 @@ void CSVTools::ReportTable::contextMenuEvent (QContextMenuEvent *event)
|
|||
|
||||
if (found)
|
||||
menu.addAction (mReplaceAction);
|
||||
|
||||
}
|
||||
|
||||
if (mRefreshAction)
|
||||
menu.addAction (mRefreshAction);
|
||||
|
||||
menu.exec (event->globalPos());
|
||||
}
|
||||
|
||||
|
@ -134,8 +136,10 @@ void CSVTools::ReportTable::mouseDoubleClickEvent (QMouseEvent *event)
|
|||
}
|
||||
|
||||
CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
|
||||
const CSMWorld::UniversalId& id, bool richTextDescription, QWidget *parent)
|
||||
: CSVWorld::DragRecordTable (document, parent), mModel (document.getReport (id))
|
||||
const CSMWorld::UniversalId& id, bool richTextDescription, int refreshState,
|
||||
QWidget *parent)
|
||||
: CSVWorld::DragRecordTable (document, parent), mModel (document.getReport (id)),
|
||||
mRefreshAction (0), mRefreshState (refreshState)
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
horizontalHeader()->setSectionResizeMode (QHeaderView::Interactive);
|
||||
|
@ -171,6 +175,14 @@ CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
|
|||
connect (mReplaceAction, SIGNAL (triggered()), this, SIGNAL (replaceRequest()));
|
||||
addAction (mReplaceAction);
|
||||
|
||||
if (mRefreshState)
|
||||
{
|
||||
mRefreshAction = new QAction (tr ("Refresh"), this);
|
||||
mRefreshAction->setEnabled (!(mDocument.getState() & mRefreshState));
|
||||
connect (mRefreshAction, SIGNAL (triggered()), this, SIGNAL (refreshRequest()));
|
||||
addAction (mRefreshAction);
|
||||
}
|
||||
|
||||
mDoubleClickActions.insert (std::make_pair (Qt::NoModifier, Action_Edit));
|
||||
mDoubleClickActions.insert (std::make_pair (Qt::ShiftModifier, Action_Remove));
|
||||
mDoubleClickActions.insert (std::make_pair (Qt::ControlModifier, Action_EditAndRemove));
|
||||
|
@ -287,3 +299,9 @@ void CSVTools::ReportTable::clear()
|
|||
{
|
||||
mModel->clear();
|
||||
}
|
||||
|
||||
void CSVTools::ReportTable::stateChanged (int state, CSMDoc::Document *document)
|
||||
{
|
||||
if (mRefreshAction)
|
||||
mRefreshAction->setEnabled (!(state & mRefreshState));
|
||||
}
|
||||
|
|
|
@ -36,7 +36,9 @@ namespace CSVTools
|
|||
QAction *mShowAction;
|
||||
QAction *mRemoveAction;
|
||||
QAction *mReplaceAction;
|
||||
QAction *mRefreshAction;
|
||||
std::map<Qt::KeyboardModifiers, DoubleClickAction> mDoubleClickActions;
|
||||
int mRefreshState;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -49,8 +51,11 @@ namespace CSVTools
|
|||
public:
|
||||
|
||||
/// \param richTextDescription Use rich text in the description column.
|
||||
/// \param refreshState Document state to check for refresh function. If value is
|
||||
/// 0 no refresh function exists. If the document current has the specified state
|
||||
/// the refresh function is disabled.
|
||||
ReportTable (CSMDoc::Document& document, const CSMWorld::UniversalId& id,
|
||||
bool richTextDescription, QWidget *parent = 0);
|
||||
bool richTextDescription, int refreshState = 0, QWidget *parent = 0);
|
||||
|
||||
virtual std::vector<CSMWorld::UniversalId> getDraggedRecords() const;
|
||||
|
||||
|
@ -71,11 +76,17 @@ namespace CSVTools
|
|||
|
||||
void removeSelection();
|
||||
|
||||
public slots:
|
||||
|
||||
void stateChanged (int state, CSMDoc::Document *document);
|
||||
|
||||
signals:
|
||||
|
||||
void editRequest (const CSMWorld::UniversalId& id, const std::string& hint);
|
||||
|
||||
void replaceRequest();
|
||||
|
||||
void refreshRequest();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
41
apps/opencs/view/widget/droplineedit.cpp
Normal file
41
apps/opencs/view/widget/droplineedit.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
#include "droplineedit.hpp"
|
||||
|
||||
#include <QDropEvent>
|
||||
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
#include "../../model/world/universalid.hpp"
|
||||
|
||||
#include "../world/dragdroputils.hpp"
|
||||
|
||||
CSVWidget::DropLineEdit::DropLineEdit(CSMWorld::ColumnBase::Display type, QWidget *parent)
|
||||
: QLineEdit(parent),
|
||||
mDropType(type)
|
||||
{
|
||||
setAcceptDrops(true);
|
||||
}
|
||||
|
||||
void CSVWidget::DropLineEdit::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
if (CSVWorld::DragDropUtils::canAcceptData(*event, mDropType))
|
||||
{
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWidget::DropLineEdit::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
if (CSVWorld::DragDropUtils::canAcceptData(*event, mDropType))
|
||||
{
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWidget::DropLineEdit::dropEvent(QDropEvent *event)
|
||||
{
|
||||
if (CSVWorld::DragDropUtils::canAcceptData(*event, mDropType))
|
||||
{
|
||||
CSMWorld::UniversalId id = CSVWorld::DragDropUtils::getAcceptedData(*event, mDropType);
|
||||
setText(QString::fromUtf8(id.getId().c_str()));
|
||||
emit tableMimeDataDropped(id, CSVWorld::DragDropUtils::getTableMimeData(*event)->getDocumentPtr());
|
||||
}
|
||||
}
|
41
apps/opencs/view/widget/droplineedit.hpp
Normal file
41
apps/opencs/view/widget/droplineedit.hpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
#ifndef CSV_WIDGET_DROPLINEEDIT_HPP
|
||||
#define CSV_WIDGET_DROPLINEEDIT_HPP
|
||||
|
||||
#include <QLineEdit>
|
||||
|
||||
#include "../../model/world/columnbase.hpp"
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Document;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class TableMimeData;
|
||||
class UniversalId;
|
||||
}
|
||||
|
||||
namespace CSVWidget
|
||||
{
|
||||
class DropLineEdit : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
CSMWorld::ColumnBase::Display mDropType;
|
||||
///< The accepted Display type for this LineEdit.
|
||||
|
||||
public:
|
||||
DropLineEdit(CSMWorld::ColumnBase::Display type, QWidget *parent = 0);
|
||||
|
||||
protected:
|
||||
void dragEnterEvent(QDragEnterEvent *event);
|
||||
void dragMoveEvent(QDragMoveEvent *event);
|
||||
void dropEvent(QDropEvent *event);
|
||||
|
||||
signals:
|
||||
void tableMimeDataDropped(const CSMWorld::UniversalId &id, const CSMDoc::Document *document);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -17,8 +17,6 @@
|
|||
#include <QLineEdit>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QComboBox>
|
||||
#include <QPushButton>
|
||||
#include <QToolButton>
|
||||
#include <QHeaderView>
|
||||
#include <QScrollBar>
|
||||
|
||||
|
@ -34,11 +32,13 @@
|
|||
#include "../../model/doc/document.hpp"
|
||||
|
||||
#include "../widget/coloreditor.hpp"
|
||||
#include "../widget/droplineedit.hpp"
|
||||
|
||||
#include "recordstatusdelegate.hpp"
|
||||
#include "util.hpp"
|
||||
#include "tablebottombox.hpp"
|
||||
#include "nestedtable.hpp"
|
||||
#include "recordbuttonbar.hpp"
|
||||
/*
|
||||
==============================NotEditableSubDelegate==========================================
|
||||
*/
|
||||
|
@ -63,16 +63,24 @@ void CSVWorld::NotEditableSubDelegate::setEditorData (QWidget* editor, const QMo
|
|||
}
|
||||
}
|
||||
|
||||
CSMWorld::Columns::ColumnId columnId = static_cast<CSMWorld::Columns::ColumnId> (
|
||||
mTable->getColumnId (index.column()));
|
||||
|
||||
if (QVariant::String == v.type())
|
||||
{
|
||||
label->setText(v.toString());
|
||||
}
|
||||
else //else we are facing enums
|
||||
else if (CSMWorld::Columns::hasEnums (columnId))
|
||||
{
|
||||
int data = v.toInt();
|
||||
std::vector<std::string> enumNames (CSMWorld::Columns::getEnums (static_cast<CSMWorld::Columns::ColumnId> (mTable->getColumnId (index.column()))));
|
||||
std::vector<std::string> enumNames (CSMWorld::Columns::getEnums (columnId));
|
||||
|
||||
label->setText(QString::fromUtf8(enumNames.at(data).c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
label->setText (v.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::NotEditableSubDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
|
||||
|
@ -129,52 +137,6 @@ QWidget* CSVWorld::DialogueDelegateDispatcherProxy::getEditor() const
|
|||
return mEditor;
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std::vector<CSMWorld::UniversalId>& data, const CSMDoc::Document* document)
|
||||
{
|
||||
QLineEdit* lineEdit = qobject_cast<QLineEdit*>(mEditor);
|
||||
{
|
||||
if (!lineEdit || !mIndexWrapper.get())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < data.size(); ++i)
|
||||
{
|
||||
CSMWorld::UniversalId::Type type = data[i].getType();
|
||||
if (mDisplay == CSMWorld::ColumnBase::Display_Referenceable)
|
||||
{
|
||||
if (type == CSMWorld::UniversalId::Type_Activator
|
||||
|| type == CSMWorld::UniversalId::Type_Potion
|
||||
|| type == CSMWorld::UniversalId::Type_Apparatus
|
||||
|| type == CSMWorld::UniversalId::Type_Armor
|
||||
|| type == CSMWorld::UniversalId::Type_Book
|
||||
|| type == CSMWorld::UniversalId::Type_Clothing
|
||||
|| type == CSMWorld::UniversalId::Type_Container
|
||||
|| type == CSMWorld::UniversalId::Type_Creature
|
||||
|| type == CSMWorld::UniversalId::Type_Door
|
||||
|| type == CSMWorld::UniversalId::Type_Ingredient
|
||||
|| type == CSMWorld::UniversalId::Type_CreatureLevelledList
|
||||
|| type == CSMWorld::UniversalId::Type_ItemLevelledList
|
||||
|| type == CSMWorld::UniversalId::Type_Light
|
||||
|| type == CSMWorld::UniversalId::Type_Lockpick
|
||||
|| type == CSMWorld::UniversalId::Type_Miscellaneous
|
||||
|| type == CSMWorld::UniversalId::Type_Npc
|
||||
|| type == CSMWorld::UniversalId::Type_Probe
|
||||
|| type == CSMWorld::UniversalId::Type_Repair
|
||||
|| type == CSMWorld::UniversalId::Type_Static
|
||||
|| type == CSMWorld::UniversalId::Type_Weapon)
|
||||
{
|
||||
type = CSMWorld::UniversalId::Type_Referenceable;
|
||||
}
|
||||
}
|
||||
if (mDisplay == CSMWorld::TableMimeData::convertEnums(type))
|
||||
{
|
||||
emit tableMimeDataDropped(mEditor, mIndexWrapper->mIndex, data[i], document);
|
||||
emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================DialogueDelegateDispatcher==========================================
|
||||
*/
|
||||
|
@ -306,16 +268,12 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::
|
|||
|
||||
// NOTE: For each entry in CSVWorld::CommandDelegate::createEditor() a corresponding entry
|
||||
// is required here
|
||||
if (qobject_cast<DropLineEdit*>(editor))
|
||||
if (qobject_cast<CSVWidget::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*)));
|
||||
|
||||
connect(editor, SIGNAL(tableMimeDataDropped(const CSMWorld::UniversalId&, const CSMDoc::Document*)),
|
||||
proxy, SLOT(editorDataCommited()));
|
||||
}
|
||||
else if (qobject_cast<QCheckBox*>(editor))
|
||||
{
|
||||
|
@ -386,9 +344,6 @@ mCommandDispatcher (commandDispatcher),
|
|||
mDocument (document)
|
||||
{
|
||||
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)
|
||||
|
@ -600,17 +555,37 @@ void CSVWorld::EditWidget::remake(int row)
|
|||
this->setWidgetResizable(true);
|
||||
}
|
||||
|
||||
/*
|
||||
==============================DialogueSubView==========================================
|
||||
*/
|
||||
|
||||
CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
|
||||
const CreatorFactoryBase& creatorFactory, bool sorting) :
|
||||
QVBoxLayout& CSVWorld::SimpleDialogueSubView::getMainLayout()
|
||||
{
|
||||
return *mMainLayout;
|
||||
}
|
||||
|
||||
CSMWorld::IdTable& CSVWorld::SimpleDialogueSubView::getTable()
|
||||
{
|
||||
return *mTable;
|
||||
}
|
||||
|
||||
CSMWorld::CommandDispatcher& CSVWorld::SimpleDialogueSubView::getCommandDispatcher()
|
||||
{
|
||||
return mCommandDispatcher;
|
||||
}
|
||||
|
||||
CSVWorld::EditWidget& CSVWorld::SimpleDialogueSubView::getEditWidget()
|
||||
{
|
||||
return *mEditWidget;
|
||||
}
|
||||
|
||||
bool CSVWorld::SimpleDialogueSubView::isLocked() const
|
||||
{
|
||||
return mLocked;
|
||||
}
|
||||
|
||||
CSVWorld::SimpleDialogueSubView::SimpleDialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) :
|
||||
SubView (id),
|
||||
mEditWidget(0),
|
||||
mMainLayout(NULL),
|
||||
mTable(dynamic_cast<CSMWorld::IdTable*>(document.getData().getTableModel(id))),
|
||||
mUndoStack(document.getUndoStack()),
|
||||
mLocked(false),
|
||||
mDocument(document),
|
||||
mCommandDispatcher (document, CSMWorld::UniversalId::getParentType (id.getType()))
|
||||
|
@ -618,171 +593,29 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
|
|||
connect(mTable, SIGNAL(dataChanged (const QModelIndex&, const QModelIndex&)), this, SLOT(dataChanged(const QModelIndex&)));
|
||||
connect(mTable, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)), this, SLOT(rowsAboutToBeRemoved(const QModelIndex&, int, int)));
|
||||
|
||||
changeCurrentId(id.getId());
|
||||
updateCurrentId();
|
||||
|
||||
QWidget *mainWidget = new QWidget(this);
|
||||
|
||||
QHBoxLayout *buttonsLayout = new QHBoxLayout;
|
||||
QToolButton* prevButton = new QToolButton(mainWidget);
|
||||
prevButton->setIcon(QIcon(":/go-previous.png"));
|
||||
prevButton->setToolTip ("Switch to previous record");
|
||||
QToolButton* nextButton = new QToolButton(mainWidget);
|
||||
nextButton->setIcon(QIcon(":/go-next.png"));
|
||||
nextButton->setToolTip ("Switch to next record");
|
||||
buttonsLayout->addWidget(prevButton, 0);
|
||||
buttonsLayout->addWidget(nextButton, 1);
|
||||
buttonsLayout->addStretch(2);
|
||||
|
||||
QToolButton* cloneButton = new QToolButton(mainWidget);
|
||||
cloneButton->setIcon(QIcon(":/edit-clone.png"));
|
||||
cloneButton->setToolTip ("Clone record");
|
||||
QToolButton* addButton = new QToolButton(mainWidget);
|
||||
addButton->setIcon(QIcon(":/add.png"));
|
||||
addButton->setToolTip ("Add new record");
|
||||
QToolButton* deleteButton = new QToolButton(mainWidget);
|
||||
deleteButton->setIcon(QIcon(":/edit-delete.png"));
|
||||
deleteButton->setToolTip ("Delete record");
|
||||
QToolButton* revertButton = new QToolButton(mainWidget);
|
||||
revertButton->setIcon(QIcon(":/edit-undo.png"));
|
||||
revertButton->setToolTip ("Revert record");
|
||||
|
||||
if (mTable->getFeatures() & CSMWorld::IdTable::Feature_Preview)
|
||||
{
|
||||
QToolButton* previewButton = new QToolButton(mainWidget);
|
||||
previewButton->setIcon(QIcon(":/edit-preview.png"));
|
||||
previewButton->setToolTip ("Open a preview of this record");
|
||||
buttonsLayout->addWidget(previewButton);
|
||||
connect(previewButton, SIGNAL(clicked()), this, SLOT(showPreview()));
|
||||
}
|
||||
|
||||
if (mTable->getFeatures() & CSMWorld::IdTable::Feature_View)
|
||||
{
|
||||
QToolButton* viewButton = new QToolButton(mainWidget);
|
||||
viewButton->setIcon(QIcon(":/cell.png"));
|
||||
viewButton->setToolTip ("Open a scene view of the cell this record is located in");
|
||||
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()), &mCommandDispatcher, SLOT(executeRevert()));
|
||||
connect(deleteButton, SIGNAL(clicked()), &mCommandDispatcher, SLOT(executeDelete()));
|
||||
|
||||
mMainLayout = new QVBoxLayout(mainWidget);
|
||||
setWidget (mainWidget);
|
||||
|
||||
mEditWidget = new EditWidget(mainWidget,
|
||||
mTable->getModelIndex(mCurrentId, 0).row(), mTable, mCommandDispatcher, document, 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*)));
|
||||
mTable->getModelIndex(getUniversalId().getId(), 0).row(), mTable, mCommandDispatcher, document, false);
|
||||
|
||||
mMainLayout->addWidget(mEditWidget);
|
||||
mEditWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||
|
||||
mMainLayout->addWidget (mBottom = new TableBottomBox (creatorFactory, document, 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->getModelIndex (mCurrentId, 0));
|
||||
mMainLayout->addLayout (buttonsLayout);
|
||||
setWidget (mainWidget);
|
||||
dataChanged(mTable->getModelIndex (getUniversalId().getId(), 0));
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::prevId ()
|
||||
void CSVWorld::SimpleDialogueSubView::setEditLock (bool locked)
|
||||
{
|
||||
int newRow = mTable->getModelIndex(mCurrentId, 0).row() - 1;
|
||||
|
||||
if (newRow < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
while (newRow >= 0)
|
||||
{
|
||||
QModelIndex newIndex(mTable->index(newRow, 0));
|
||||
|
||||
if (!newIndex.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (newRow, 1)).toInt());
|
||||
if (!(state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased))
|
||||
{
|
||||
mEditWidget->remake(newRow);
|
||||
|
||||
setUniversalId(CSMWorld::UniversalId (static_cast<CSMWorld::UniversalId::Type> (mTable->data (mTable->index (newRow, 2)).toInt()),
|
||||
mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()));
|
||||
|
||||
changeCurrentId(std::string(mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()));
|
||||
|
||||
mEditWidget->setDisabled(mLocked);
|
||||
|
||||
return;
|
||||
}
|
||||
--newRow;
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::nextId ()
|
||||
{
|
||||
int newRow = mTable->getModelIndex(mCurrentId, 0).row() + 1;
|
||||
|
||||
if (newRow >= mTable->rowCount())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (newRow < mTable->rowCount())
|
||||
{
|
||||
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))
|
||||
{
|
||||
mEditWidget->remake(newRow);
|
||||
|
||||
setUniversalId(CSMWorld::UniversalId (static_cast<CSMWorld::UniversalId::Type> (mTable->data (mTable->index (newRow, 2)).toInt()),
|
||||
mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()));
|
||||
|
||||
changeCurrentId(std::string(mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()));
|
||||
|
||||
mEditWidget->setDisabled(mLocked);
|
||||
|
||||
return;
|
||||
}
|
||||
++newRow;
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::setEditLock (bool locked)
|
||||
{
|
||||
if (!mEditWidget) // hack to indicate that mCurrentId is no longer valid
|
||||
if (!mEditWidget) // hack to indicate that getUniversalId().getId() is no longer valid
|
||||
return;
|
||||
|
||||
mLocked = locked;
|
||||
QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0));
|
||||
QModelIndex currentIndex(mTable->getModelIndex(getUniversalId().getId(), 0));
|
||||
|
||||
if (currentIndex.isValid())
|
||||
{
|
||||
|
@ -795,9 +628,9 @@ void CSVWorld::DialogueSubView::setEditLock (bool locked)
|
|||
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::dataChanged (const QModelIndex & index)
|
||||
void CSVWorld::SimpleDialogueSubView::dataChanged (const QModelIndex & index)
|
||||
{
|
||||
QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0));
|
||||
QModelIndex currentIndex(mTable->getModelIndex(getUniversalId().getId(), 0));
|
||||
|
||||
if (currentIndex.isValid() &&
|
||||
(index.parent().isValid() ? index.parent().row() : index.row()) == currentIndex.row())
|
||||
|
@ -828,9 +661,9 @@ void CSVWorld::DialogueSubView::dataChanged (const QModelIndex & index)
|
|||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
|
||||
void CSVWorld::SimpleDialogueSubView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
|
||||
{
|
||||
QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0));
|
||||
QModelIndex currentIndex(mTable->getModelIndex(getUniversalId().getId(), 0));
|
||||
|
||||
if (currentIndex.isValid() && currentIndex.row() >= start && currentIndex.row() <= end)
|
||||
{
|
||||
|
@ -843,60 +676,106 @@ void CSVWorld::DialogueSubView::rowsAboutToBeRemoved(const QModelIndex &parent,
|
|||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::tableMimeDataDropped (QWidget* editor,
|
||||
const QModelIndex& index,
|
||||
const CSMWorld::UniversalId& id,
|
||||
const CSMDoc::Document* document)
|
||||
void CSVWorld::SimpleDialogueSubView::updateCurrentId()
|
||||
{
|
||||
if (document == &mDocument)
|
||||
{
|
||||
qobject_cast<DropLineEdit*>(editor)->setText(id.getId().c_str());
|
||||
}
|
||||
std::vector<std::string> selection;
|
||||
selection.push_back (getUniversalId().getId());
|
||||
mCommandDispatcher.setSelection(selection);
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::requestFocus (const std::string& id)
|
||||
{
|
||||
changeCurrentId(id);
|
||||
|
||||
mEditWidget->remake(mTable->getModelIndex (id, 0).row());
|
||||
CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id,
|
||||
CSMDoc::Document& document, const CreatorFactoryBase& creatorFactory, bool sorting)
|
||||
: SimpleDialogueSubView (id, document)
|
||||
{
|
||||
// bottom box
|
||||
mBottom = new TableBottomBox (creatorFactory, document, id, this);
|
||||
|
||||
mBottom->setSizePolicy (QSizePolicy::Ignored, QSizePolicy::Fixed);
|
||||
|
||||
connect (mBottom, SIGNAL (requestFocus (const std::string&)),
|
||||
this, SLOT (requestFocus (const std::string&)));
|
||||
|
||||
// button bar
|
||||
mButtons = new RecordButtonBar (id, getTable(), mBottom,
|
||||
&getCommandDispatcher(), this);
|
||||
|
||||
// layout
|
||||
getMainLayout().addWidget (mButtons);
|
||||
getMainLayout().addWidget (mBottom);
|
||||
|
||||
// connections
|
||||
connect (mButtons, SIGNAL (showPreview()), this, SLOT (showPreview()));
|
||||
connect (mButtons, SIGNAL (viewRecord()), this, SLOT (viewRecord()));
|
||||
connect (mButtons, SIGNAL (switchToRow (int)), this, SLOT (switchToRow (int)));
|
||||
|
||||
connect (this, SIGNAL (universalIdChanged (const CSMWorld::UniversalId&)),
|
||||
mButtons, SLOT (universalIdChanged (const CSMWorld::UniversalId&)));
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::cloneRequest ()
|
||||
void CSVWorld::DialogueSubView::setEditLock (bool locked)
|
||||
{
|
||||
mBottom->cloneRequest(mCurrentId, static_cast<CSMWorld::UniversalId::Type>(mTable->data(mTable->getModelIndex(mCurrentId, 2)).toInt()));
|
||||
SimpleDialogueSubView::setEditLock (locked);
|
||||
mButtons->setEditLock (locked);
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::updateUserSetting (const QString& name, const QStringList& value)
|
||||
{
|
||||
SimpleDialogueSubView::updateUserSetting (name, value);
|
||||
mButtons->updateUserSetting (name, value);
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::showPreview ()
|
||||
{
|
||||
QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0));
|
||||
QModelIndex currentIndex (getTable().getModelIndex (getUniversalId().getId(), 0));
|
||||
|
||||
if (currentIndex.isValid() &&
|
||||
mTable->getFeatures() & CSMWorld::IdTable::Feature_Preview &&
|
||||
currentIndex.row() < mTable->rowCount())
|
||||
getTable().getFeatures() & CSMWorld::IdTable::Feature_Preview &&
|
||||
currentIndex.row() < getTable().rowCount())
|
||||
{
|
||||
emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, mCurrentId), "");
|
||||
emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, getUniversalId().getId()), "");
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::viewRecord ()
|
||||
{
|
||||
QModelIndex currentIndex(mTable->getModelIndex (mCurrentId, 0));
|
||||
QModelIndex currentIndex (getTable().getModelIndex (getUniversalId().getId(), 0));
|
||||
|
||||
if (currentIndex.isValid() &&
|
||||
currentIndex.row() < mTable->rowCount())
|
||||
currentIndex.row() < getTable().rowCount())
|
||||
{
|
||||
std::pair<CSMWorld::UniversalId, std::string> params = mTable->view (currentIndex.row());
|
||||
std::pair<CSMWorld::UniversalId, std::string> params = getTable().view (currentIndex.row());
|
||||
|
||||
if (params.first.getType()!=CSMWorld::UniversalId::Type_None)
|
||||
emit focusId (params.first, params.second);
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::changeCurrentId (const std::string& newId)
|
||||
void CSVWorld::DialogueSubView::switchToRow (int row)
|
||||
{
|
||||
std::vector<std::string> selection;
|
||||
mCurrentId = std::string(newId);
|
||||
int idColumn = getTable().findColumnIndex (CSMWorld::Columns::ColumnId_Id);
|
||||
std::string id = getTable().data (getTable().index (row, idColumn)).toString().toUtf8().constData();
|
||||
|
||||
selection.push_back(mCurrentId);
|
||||
mCommandDispatcher.setSelection(selection);
|
||||
int typeColumn = getTable().findColumnIndex (CSMWorld::Columns::ColumnId_RecordType);
|
||||
CSMWorld::UniversalId::Type type = static_cast<CSMWorld::UniversalId::Type> (
|
||||
getTable().data (getTable().index (row, typeColumn)).toInt());
|
||||
|
||||
setUniversalId (CSMWorld::UniversalId (type, id));
|
||||
updateCurrentId();
|
||||
|
||||
getEditWidget().remake (row);
|
||||
|
||||
int stateColumn = getTable().findColumnIndex (CSMWorld::Columns::ColumnId_Modification);
|
||||
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State> (
|
||||
getTable().data (getTable().index (row, stateColumn)).toInt());
|
||||
|
||||
getEditWidget().setDisabled (isLocked() || state==CSMWorld::RecordBase::State_Deleted);
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::requestFocus (const std::string& id)
|
||||
{
|
||||
QModelIndex index = getTable().getModelIndex (id, 0);
|
||||
|
||||
if (index.isValid())
|
||||
switchToRow (index.row());
|
||||
}
|
||||
|
|
|
@ -86,18 +86,12 @@ namespace CSVWorld
|
|||
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
|
||||
|
@ -153,11 +147,6 @@ namespace CSVWorld
|
|||
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
|
||||
|
@ -182,61 +171,74 @@ namespace CSVWorld
|
|||
virtual ~EditWidget();
|
||||
|
||||
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
|
||||
class SimpleDialogueSubView : public CSVDoc::SubView
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
EditWidget* mEditWidget;
|
||||
QVBoxLayout* mMainLayout;
|
||||
CSMWorld::IdTable* mTable;
|
||||
QUndoStack& mUndoStack;
|
||||
std::string mCurrentId;
|
||||
bool mLocked;
|
||||
const CSMDoc::Document& mDocument;
|
||||
TableBottomBox* mBottom;
|
||||
CSMWorld::CommandDispatcher mCommandDispatcher;
|
||||
EditWidget* mEditWidget;
|
||||
QVBoxLayout* mMainLayout;
|
||||
CSMWorld::IdTable* mTable;
|
||||
bool mLocked;
|
||||
const CSMDoc::Document& mDocument;
|
||||
CSMWorld::CommandDispatcher mCommandDispatcher;
|
||||
|
||||
protected:
|
||||
|
||||
QVBoxLayout& getMainLayout();
|
||||
|
||||
CSMWorld::IdTable& getTable();
|
||||
|
||||
CSMWorld::CommandDispatcher& getCommandDispatcher();
|
||||
|
||||
EditWidget& getEditWidget();
|
||||
|
||||
void updateCurrentId();
|
||||
|
||||
bool isLocked() const;
|
||||
|
||||
public:
|
||||
|
||||
DialogueSubView (const CSMWorld::UniversalId& id,
|
||||
CSMDoc::Document& document,
|
||||
const CreatorFactoryBase& creatorFactory,
|
||||
bool sorting = false);
|
||||
SimpleDialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
|
||||
|
||||
virtual void setEditLock (bool locked);
|
||||
|
||||
private:
|
||||
void changeCurrentId(const std::string& newCurrent);
|
||||
|
||||
private slots:
|
||||
|
||||
void nextId();
|
||||
void dataChanged(const QModelIndex & index);
|
||||
///\brief we need to care for deleting currently edited record
|
||||
|
||||
void prevId();
|
||||
void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
|
||||
};
|
||||
|
||||
class RecordButtonBar;
|
||||
|
||||
class DialogueSubView : public SimpleDialogueSubView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
TableBottomBox* mBottom;
|
||||
RecordButtonBar *mButtons;
|
||||
|
||||
public:
|
||||
|
||||
DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
|
||||
const CreatorFactoryBase& creatorFactory, bool sorting = false);
|
||||
|
||||
virtual void setEditLock (bool locked);
|
||||
|
||||
virtual void updateUserSetting (const QString& name, const QStringList& value);
|
||||
|
||||
private slots:
|
||||
|
||||
void showPreview();
|
||||
|
||||
void viewRecord();
|
||||
|
||||
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 switchToRow (int row);
|
||||
|
||||
void requestFocus (const std::string& id);
|
||||
|
||||
void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
26
apps/opencs/view/world/dragdroputils.cpp
Normal file
26
apps/opencs/view/world/dragdroputils.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#include "dragdroputils.hpp"
|
||||
|
||||
#include <QDropEvent>
|
||||
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
|
||||
const CSMWorld::TableMimeData *CSVWorld::DragDropUtils::getTableMimeData(const QDropEvent &event)
|
||||
{
|
||||
return dynamic_cast<const CSMWorld::TableMimeData *>(event.mimeData());
|
||||
}
|
||||
|
||||
bool CSVWorld::DragDropUtils::canAcceptData(const QDropEvent &event, CSMWorld::ColumnBase::Display type)
|
||||
{
|
||||
const CSMWorld::TableMimeData *data = getTableMimeData(event);
|
||||
return data != NULL && data->holdsType(type);
|
||||
}
|
||||
|
||||
CSMWorld::UniversalId CSVWorld::DragDropUtils::getAcceptedData(const QDropEvent &event,
|
||||
CSMWorld::ColumnBase::Display type)
|
||||
{
|
||||
if (canAcceptData(event, type))
|
||||
{
|
||||
return getTableMimeData(event)->returnMatching(type);
|
||||
}
|
||||
return CSMWorld::UniversalId::Type_None;
|
||||
}
|
29
apps/opencs/view/world/dragdroputils.hpp
Normal file
29
apps/opencs/view/world/dragdroputils.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef CSV_WORLD_DRAGDROPUTILS_HPP
|
||||
#define CSV_WORLD_DRAGDROPUTILS_HPP
|
||||
|
||||
#include "../../model/world/columnbase.hpp"
|
||||
|
||||
class QDropEvent;
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class TableMimeData;
|
||||
class UniversalId;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
namespace DragDropUtils
|
||||
{
|
||||
const CSMWorld::TableMimeData *getTableMimeData(const QDropEvent &event);
|
||||
|
||||
bool canAcceptData(const QDropEvent &event, CSMWorld::ColumnBase::Display type);
|
||||
///< Checks whether the \a event contains a valid CSMWorld::TableMimeData that holds the \a type
|
||||
|
||||
CSMWorld::UniversalId getAcceptedData(const QDropEvent &event, CSMWorld::ColumnBase::Display type);
|
||||
///< Gets the accepted data from the \a event using the \a type
|
||||
///< \return Type_None if the \a event data doesn't holds the \a type
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,12 +1,24 @@
|
|||
#include "dragrecordtable.hpp"
|
||||
|
||||
#include <QDrag>
|
||||
#include <QDragEnterEvent>
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
#include "dragrecordtable.hpp"
|
||||
#include "../../model/world/commands.hpp"
|
||||
|
||||
#include "dragdroputils.hpp"
|
||||
|
||||
void CSVWorld::DragRecordTable::startDragFromTable (const CSVWorld::DragRecordTable& table)
|
||||
{
|
||||
CSMWorld::TableMimeData* mime = new CSMWorld::TableMimeData (table.getDraggedRecords(), mDocument);
|
||||
std::vector<CSMWorld::UniversalId> records = table.getDraggedRecords();
|
||||
if (records.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CSMWorld::TableMimeData* mime = new CSMWorld::TableMimeData (records, mDocument);
|
||||
|
||||
if (mime)
|
||||
{
|
||||
|
@ -21,7 +33,9 @@ CSVWorld::DragRecordTable::DragRecordTable (CSMDoc::Document& document, QWidget*
|
|||
QTableView(parent),
|
||||
mDocument(document),
|
||||
mEditLock(false)
|
||||
{}
|
||||
{
|
||||
setAcceptDrops(true);
|
||||
}
|
||||
|
||||
void CSVWorld::DragRecordTable::setEditLock (bool locked)
|
||||
{
|
||||
|
@ -35,5 +49,51 @@ void CSVWorld::DragRecordTable::dragEnterEvent(QDragEnterEvent *event)
|
|||
|
||||
void CSVWorld::DragRecordTable::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
event->accept();
|
||||
QModelIndex index = indexAt(event->pos());
|
||||
if (CSVWorld::DragDropUtils::canAcceptData(*event, getIndexDisplayType(index)))
|
||||
{
|
||||
if (index.flags() & Qt::ItemIsEditable)
|
||||
{
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DragRecordTable::dropEvent(QDropEvent *event)
|
||||
{
|
||||
QModelIndex index = indexAt(event->pos());
|
||||
CSMWorld::ColumnBase::Display display = getIndexDisplayType(index);
|
||||
if (CSVWorld::DragDropUtils::canAcceptData(*event, display))
|
||||
{
|
||||
const CSMWorld::TableMimeData *data = CSVWorld::DragDropUtils::getTableMimeData(*event);
|
||||
if (data->fromDocument(mDocument))
|
||||
{
|
||||
CSMWorld::UniversalId id = CSVWorld::DragDropUtils::getAcceptedData(*event, display);
|
||||
QVariant newIndexData = QString::fromUtf8(id.getId().c_str());
|
||||
QVariant oldIndexData = index.data(Qt::EditRole);
|
||||
if (newIndexData != oldIndexData)
|
||||
{
|
||||
mDocument.getUndoStack().push(new CSMWorld::ModifyCommand(*model(), index, newIndexData));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CSMWorld::ColumnBase::Display CSVWorld::DragRecordTable::getIndexDisplayType(const QModelIndex &index) const
|
||||
{
|
||||
Q_ASSERT(model() != NULL);
|
||||
|
||||
if (index.isValid())
|
||||
{
|
||||
QVariant display = model()->headerData(index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display);
|
||||
if (display.isValid())
|
||||
{
|
||||
return static_cast<CSMWorld::ColumnBase::Display>(display.toInt());
|
||||
}
|
||||
}
|
||||
return CSMWorld::ColumnBase::Display_None;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <QTableView>
|
||||
#include <QEvent>
|
||||
|
||||
#include "../../model/world/columnbase.hpp"
|
||||
|
||||
class QWidget;
|
||||
class QAction;
|
||||
|
||||
|
@ -38,6 +40,11 @@ namespace CSVWorld
|
|||
void dragEnterEvent(QDragEnterEvent *event);
|
||||
|
||||
void dragMoveEvent(QDragMoveEvent *event);
|
||||
|
||||
void dropEvent(QDropEvent *event);
|
||||
|
||||
private:
|
||||
CSMWorld::ColumnBase::Display getIndexDisplayType(const QModelIndex &index) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include "../../model/world/idcompletionmanager.hpp"
|
||||
|
||||
#include "../widget/droplineedit.hpp"
|
||||
|
||||
CSVWorld::IdCompletionDelegate::IdCompletionDelegate(CSMWorld::CommandDispatcher *dispatcher,
|
||||
CSMDoc::Document& document,
|
||||
QObject *parent)
|
||||
|
@ -26,7 +28,7 @@ QWidget *CSVWorld::IdCompletionDelegate::createEditor(QWidget *parent,
|
|||
}
|
||||
|
||||
CSMWorld::IdCompletionManager &completionManager = getDocument().getIdCompletionManager();
|
||||
DropLineEdit *editor = new DropLineEdit(parent);
|
||||
CSVWidget::DropLineEdit *editor = new CSVWidget::DropLineEdit(display, parent);
|
||||
editor->setCompleter(completionManager.getCompleter(display).get());
|
||||
return editor;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include <algorithm>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QUuid>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
@ -17,6 +16,8 @@
|
|||
#include "../../model/world/idtable.hpp"
|
||||
#include "../../model/world/idcompletionmanager.hpp"
|
||||
|
||||
#include "../widget/droplineedit.hpp"
|
||||
|
||||
std::string CSVWorld::InfoCreator::getId() const
|
||||
{
|
||||
std::string id = Misc::StringUtils::lowerCase (mTopic->text().toUtf8().constData());
|
||||
|
@ -48,12 +49,12 @@ CSVWorld::InfoCreator::InfoCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
|||
QLabel *label = new QLabel ("Topic", this);
|
||||
insertBeforeButtons (label, false);
|
||||
|
||||
mTopic = new QLineEdit (this);
|
||||
CSMWorld::ColumnBase::Display displayType = CSMWorld::ColumnBase::Display_Topic;
|
||||
if (getCollectionId().getType() == CSMWorld::UniversalId::Type_JournalInfos)
|
||||
{
|
||||
displayType = CSMWorld::ColumnBase::Display_Journal;
|
||||
}
|
||||
mTopic = new CSVWidget::DropLineEdit(displayType, this);
|
||||
mTopic->setCompleter(completionManager.getCompleter(displayType).get());
|
||||
insertBeforeButtons (mTopic, true);
|
||||
|
||||
|
|
|
@ -3,21 +3,24 @@
|
|||
|
||||
#include "genericcreator.hpp"
|
||||
|
||||
class QLineEdit;
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class InfoCollection;
|
||||
class IdCompletionManager;
|
||||
}
|
||||
|
||||
namespace CSVWidget
|
||||
{
|
||||
class DropLineEdit;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class InfoCreator : public GenericCreator
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QLineEdit *mTopic;
|
||||
CSVWidget::DropLineEdit *mTopic;
|
||||
|
||||
virtual std::string getId() const;
|
||||
|
||||
|
|
|
@ -14,8 +14,7 @@ CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document,
|
|||
CSMWorld::UniversalId id,
|
||||
CSMWorld::NestedTableProxyModel* model,
|
||||
QWidget* parent)
|
||||
: QTableView(parent),
|
||||
mUndoStack(document.getUndoStack()),
|
||||
: DragRecordTable(document, parent),
|
||||
mModel(model)
|
||||
{
|
||||
mDispatcher = new CSMWorld::CommandDispatcher (document, id, this);
|
||||
|
@ -47,8 +46,6 @@ CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document,
|
|||
|
||||
setModel(model);
|
||||
|
||||
setAcceptDrops(true);
|
||||
|
||||
mAddNewRowAction = new QAction (tr ("Add new row"), this);
|
||||
|
||||
connect(mAddNewRowAction, SIGNAL(triggered()),
|
||||
|
@ -60,12 +57,10 @@ CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document,
|
|||
this, SLOT(removeRowActionTriggered()));
|
||||
}
|
||||
|
||||
void CSVWorld::NestedTable::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
}
|
||||
|
||||
void CSVWorld::NestedTable::dragMoveEvent(QDragMoveEvent *event)
|
||||
std::vector<CSMWorld::UniversalId> CSVWorld::NestedTable::getDraggedRecords() const
|
||||
{
|
||||
// No drag support for nested tables
|
||||
return std::vector<CSMWorld::UniversalId>();
|
||||
}
|
||||
|
||||
void CSVWorld::NestedTable::contextMenuEvent (QContextMenuEvent *event)
|
||||
|
@ -84,16 +79,16 @@ void CSVWorld::NestedTable::contextMenuEvent (QContextMenuEvent *event)
|
|||
|
||||
void CSVWorld::NestedTable::removeRowActionTriggered()
|
||||
{
|
||||
mUndoStack.push(new CSMWorld::DeleteNestedCommand(*(mModel->model()),
|
||||
mModel->getParentId(),
|
||||
selectionModel()->selectedRows().begin()->row(),
|
||||
mModel->getParentColumn()));
|
||||
mDocument.getUndoStack().push(new CSMWorld::DeleteNestedCommand(*(mModel->model()),
|
||||
mModel->getParentId(),
|
||||
selectionModel()->selectedRows().begin()->row(),
|
||||
mModel->getParentColumn()));
|
||||
}
|
||||
|
||||
void CSVWorld::NestedTable::addNewRowActionTriggered()
|
||||
{
|
||||
mUndoStack.push(new CSMWorld::AddNestedCommand(*(mModel->model()),
|
||||
mModel->getParentId(),
|
||||
selectionModel()->selectedRows().size(),
|
||||
mModel->getParentColumn()));
|
||||
mDocument.getUndoStack().push(new CSMWorld::AddNestedCommand(*(mModel->model()),
|
||||
mModel->getParentId(),
|
||||
selectionModel()->selectedRows().size(),
|
||||
mModel->getParentColumn()));
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#ifndef CSV_WORLD_NESTEDTABLE_H
|
||||
#define CSV_WORLD_NESTEDTABLE_H
|
||||
|
||||
#include <QTableView>
|
||||
#include <QEvent>
|
||||
|
||||
class QUndoStack;
|
||||
#include "dragrecordtable.hpp"
|
||||
|
||||
class QAction;
|
||||
class QContextMenuEvent;
|
||||
|
||||
|
@ -22,13 +22,12 @@ namespace CSMDoc
|
|||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class NestedTable : public QTableView
|
||||
class NestedTable : public DragRecordTable
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QAction *mAddNewRowAction;
|
||||
QAction *mRemoveRowAction;
|
||||
QUndoStack& mUndoStack;
|
||||
CSMWorld::NestedTableProxyModel* mModel;
|
||||
CSMWorld::CommandDispatcher *mDispatcher;
|
||||
|
||||
|
@ -38,10 +37,7 @@ namespace CSVWorld
|
|||
CSMWorld::NestedTableProxyModel* model,
|
||||
QWidget* parent = NULL);
|
||||
|
||||
protected:
|
||||
void dragEnterEvent(QDragEnterEvent *event);
|
||||
|
||||
void dragMoveEvent(QDragMoveEvent *event);
|
||||
virtual std::vector<CSMWorld::UniversalId> getDraggedRecords() const;
|
||||
|
||||
private:
|
||||
void contextMenuEvent (QContextMenuEvent *event);
|
||||
|
|
207
apps/opencs/view/world/recordbuttonbar.cpp
Normal file
207
apps/opencs/view/world/recordbuttonbar.cpp
Normal file
|
@ -0,0 +1,207 @@
|
|||
|
||||
#include "recordbuttonbar.hpp"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QToolButton>
|
||||
|
||||
#include "../../model/world/idtable.hpp"
|
||||
#include "../../model/world/commanddispatcher.hpp"
|
||||
|
||||
#include "../../model/settings/usersettings.hpp"
|
||||
|
||||
#include "../world/tablebottombox.hpp"
|
||||
|
||||
void CSVWorld::RecordButtonBar::updateModificationButtons()
|
||||
{
|
||||
bool createAndDeleteDisabled = !mBottom || !mBottom->canCreateAndDelete() || mLocked;
|
||||
|
||||
mCloneButton->setDisabled (createAndDeleteDisabled);
|
||||
mAddButton->setDisabled (createAndDeleteDisabled);
|
||||
mDeleteButton->setDisabled (createAndDeleteDisabled);
|
||||
|
||||
bool commandDisabled = !mCommandDispatcher || mLocked;
|
||||
|
||||
mRevertButton->setDisabled (commandDisabled);
|
||||
mDeleteButton->setDisabled (commandDisabled);
|
||||
}
|
||||
|
||||
void CSVWorld::RecordButtonBar::updatePrevNextButtons()
|
||||
{
|
||||
int rows = mTable.rowCount();
|
||||
|
||||
if (rows<=1)
|
||||
{
|
||||
mPrevButton->setDisabled (true);
|
||||
mNextButton->setDisabled (true);
|
||||
}
|
||||
else if (CSMSettings::UserSettings::instance().settingValue ("general-input/cycle")=="true")
|
||||
{
|
||||
mPrevButton->setDisabled (false);
|
||||
mNextButton->setDisabled (false);
|
||||
}
|
||||
else
|
||||
{
|
||||
int row = mTable.getModelIndex (mId.getId(), 0).row();
|
||||
|
||||
mPrevButton->setDisabled (row<=0);
|
||||
mNextButton->setDisabled (row>=rows-1);
|
||||
}
|
||||
}
|
||||
|
||||
CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id,
|
||||
CSMWorld::IdTable& table, TableBottomBox *bottomBox,
|
||||
CSMWorld::CommandDispatcher *commandDispatcher, QWidget *parent)
|
||||
: QWidget (parent), mId (id), mTable (table), mBottom (bottomBox),
|
||||
mCommandDispatcher (commandDispatcher), mLocked (false)
|
||||
{
|
||||
QHBoxLayout *buttonsLayout = new QHBoxLayout;
|
||||
buttonsLayout->setContentsMargins (0, 0, 0, 0);
|
||||
|
||||
// left section
|
||||
mPrevButton = new QToolButton (this);
|
||||
mPrevButton->setIcon(QIcon(":/go-previous.png"));
|
||||
mPrevButton->setToolTip ("Switch to previous record");
|
||||
buttonsLayout->addWidget (mPrevButton, 0);
|
||||
|
||||
mNextButton = new QToolButton (this);
|
||||
mNextButton->setIcon(QIcon(":/go-next.png"));
|
||||
mNextButton->setToolTip ("Switch to next record");
|
||||
buttonsLayout->addWidget (mNextButton, 1);
|
||||
|
||||
buttonsLayout->addStretch(2);
|
||||
|
||||
// optional buttons of the right section
|
||||
if (mTable.getFeatures() & CSMWorld::IdTable::Feature_Preview)
|
||||
{
|
||||
QToolButton* previewButton = new QToolButton (this);
|
||||
previewButton->setIcon(QIcon(":/edit-preview.png"));
|
||||
previewButton->setToolTip ("Open a preview of this record");
|
||||
buttonsLayout->addWidget(previewButton);
|
||||
connect (previewButton, SIGNAL(clicked()), this, SIGNAL (showPreview()));
|
||||
}
|
||||
|
||||
if (mTable.getFeatures() & CSMWorld::IdTable::Feature_View)
|
||||
{
|
||||
QToolButton* viewButton = new QToolButton (this);
|
||||
viewButton->setIcon(QIcon(":/cell.png"));
|
||||
viewButton->setToolTip ("Open a scene view of the cell this record is located in");
|
||||
buttonsLayout->addWidget(viewButton);
|
||||
connect (viewButton, SIGNAL(clicked()), this, SIGNAL (viewRecord()));
|
||||
}
|
||||
|
||||
// right section
|
||||
mCloneButton = new QToolButton (this);
|
||||
mCloneButton->setIcon(QIcon(":/edit-clone.png"));
|
||||
mCloneButton->setToolTip ("Clone record");
|
||||
buttonsLayout->addWidget(mCloneButton);
|
||||
|
||||
mAddButton = new QToolButton (this);
|
||||
mAddButton->setIcon(QIcon(":/add.png"));
|
||||
mAddButton->setToolTip ("Add new record");
|
||||
buttonsLayout->addWidget(mAddButton);
|
||||
|
||||
mDeleteButton = new QToolButton (this);
|
||||
mDeleteButton->setIcon(QIcon(":/edit-delete.png"));
|
||||
mDeleteButton->setToolTip ("Delete record");
|
||||
buttonsLayout->addWidget(mDeleteButton);
|
||||
|
||||
mRevertButton = new QToolButton (this);
|
||||
mRevertButton->setIcon(QIcon(":/edit-undo.png"));
|
||||
mRevertButton->setToolTip ("Revert record");
|
||||
buttonsLayout->addWidget(mRevertButton);
|
||||
|
||||
setLayout (buttonsLayout);
|
||||
|
||||
// connections
|
||||
if(mBottom && mBottom->canCreateAndDelete())
|
||||
{
|
||||
connect (mAddButton, SIGNAL (clicked()), mBottom, SLOT (createRequest()));
|
||||
connect (mCloneButton, SIGNAL (clicked()), this, SLOT (cloneRequest()));
|
||||
}
|
||||
|
||||
connect (mNextButton, SIGNAL (clicked()), this, SLOT (nextId()));
|
||||
connect (mPrevButton, SIGNAL (clicked()), this, SLOT (prevId()));
|
||||
|
||||
if (mCommandDispatcher)
|
||||
{
|
||||
connect (mRevertButton, SIGNAL (clicked()), mCommandDispatcher, SLOT (executeRevert()));
|
||||
connect (mDeleteButton, SIGNAL (clicked()), mCommandDispatcher, SLOT (executeDelete()));
|
||||
}
|
||||
|
||||
connect (&mTable, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
||||
this, SLOT (rowNumberChanged (const QModelIndex&, int, int)));
|
||||
connect (&mTable, SIGNAL (rowsRemoved (const QModelIndex&, int, int)),
|
||||
this, SLOT (rowNumberChanged (const QModelIndex&, int, int)));
|
||||
|
||||
updateModificationButtons();
|
||||
updatePrevNextButtons();
|
||||
}
|
||||
|
||||
void CSVWorld::RecordButtonBar::setEditLock (bool locked)
|
||||
{
|
||||
mLocked = locked;
|
||||
updateModificationButtons();
|
||||
}
|
||||
|
||||
void CSVWorld::RecordButtonBar::updateUserSetting (const QString& name, const QStringList& value)
|
||||
{
|
||||
if (name=="general-input/cycle")
|
||||
updatePrevNextButtons();
|
||||
}
|
||||
|
||||
void CSVWorld::RecordButtonBar::universalIdChanged (const CSMWorld::UniversalId& id)
|
||||
{
|
||||
mId = id;
|
||||
updatePrevNextButtons();
|
||||
}
|
||||
|
||||
void CSVWorld::RecordButtonBar::cloneRequest()
|
||||
{
|
||||
if (mBottom)
|
||||
{
|
||||
int typeColumn = mTable.findColumnIndex (CSMWorld::Columns::ColumnId_RecordType);
|
||||
|
||||
QModelIndex typeIndex = mTable.getModelIndex (mId.getId(), typeColumn);
|
||||
CSMWorld::UniversalId::Type type = static_cast<CSMWorld::UniversalId::Type> (
|
||||
mTable.data (typeIndex).toInt());
|
||||
|
||||
mBottom->cloneRequest (mId.getId(), type);
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::RecordButtonBar::nextId()
|
||||
{
|
||||
int newRow = mTable.getModelIndex (mId.getId(), 0).row() + 1;
|
||||
|
||||
if (newRow >= mTable.rowCount())
|
||||
{
|
||||
if (CSMSettings::UserSettings::instance().settingValue ("general-input/cycle")
|
||||
=="true")
|
||||
newRow = 0;
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
emit switchToRow (newRow);
|
||||
}
|
||||
|
||||
void CSVWorld::RecordButtonBar::prevId()
|
||||
{
|
||||
int newRow = mTable.getModelIndex (mId.getId(), 0).row() - 1;
|
||||
|
||||
if (newRow < 0)
|
||||
{
|
||||
if (CSMSettings::UserSettings::instance().settingValue ("general-input/cycle")
|
||||
=="true")
|
||||
newRow = mTable.rowCount()-1;
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
emit switchToRow (newRow);
|
||||
}
|
||||
|
||||
void CSVWorld::RecordButtonBar::rowNumberChanged (const QModelIndex& parent, int start, int end)
|
||||
{
|
||||
updatePrevNextButtons();
|
||||
}
|
87
apps/opencs/view/world/recordbuttonbar.hpp
Normal file
87
apps/opencs/view/world/recordbuttonbar.hpp
Normal file
|
@ -0,0 +1,87 @@
|
|||
#ifndef CSV_WORLD_RECORDBUTTONBAR_H
|
||||
#define CSV_WORLD_RECORDBUTTONBAR_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "../../model/world/universalid.hpp"
|
||||
|
||||
class QToolButton;
|
||||
class QModelIndex;
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class IdTable;
|
||||
class CommandDispatcher;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class TableBottomBox;
|
||||
|
||||
/// \brief Button bar for use in dialogue-type subviews
|
||||
///
|
||||
/// Contains the following buttons:
|
||||
/// - next/prev
|
||||
/// - clone
|
||||
/// - add
|
||||
/// - delete
|
||||
/// - revert
|
||||
/// - preview (optional)
|
||||
/// - view (optional)
|
||||
class RecordButtonBar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
CSMWorld::UniversalId mId;
|
||||
CSMWorld::IdTable& mTable;
|
||||
TableBottomBox *mBottom;
|
||||
CSMWorld::CommandDispatcher *mCommandDispatcher;
|
||||
QToolButton *mPrevButton;
|
||||
QToolButton *mNextButton;
|
||||
QToolButton *mCloneButton;
|
||||
QToolButton *mAddButton;
|
||||
QToolButton *mDeleteButton;
|
||||
QToolButton *mRevertButton;
|
||||
bool mLocked;
|
||||
|
||||
private:
|
||||
|
||||
void updateModificationButtons();
|
||||
|
||||
void updatePrevNextButtons();
|
||||
|
||||
public:
|
||||
|
||||
RecordButtonBar (const CSMWorld::UniversalId& id,
|
||||
CSMWorld::IdTable& table, TableBottomBox *bottomBox = 0,
|
||||
CSMWorld::CommandDispatcher *commandDispatcher = 0, QWidget *parent = 0);
|
||||
|
||||
void setEditLock (bool locked);
|
||||
|
||||
void updateUserSetting (const QString& name, const QStringList& value);
|
||||
|
||||
public slots:
|
||||
|
||||
void universalIdChanged (const CSMWorld::UniversalId& id);
|
||||
|
||||
private slots:
|
||||
|
||||
void cloneRequest();
|
||||
|
||||
void nextId();
|
||||
|
||||
void prevId();
|
||||
|
||||
void rowNumberChanged (const QModelIndex& parent, int start, int end);
|
||||
|
||||
signals:
|
||||
|
||||
void showPreview();
|
||||
|
||||
void viewRecord();
|
||||
|
||||
void switchToRow (int row);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -2,7 +2,6 @@
|
|||
#include "referencecreator.hpp"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
||||
|
@ -12,6 +11,8 @@
|
|||
#include "../../model/world/idtable.hpp"
|
||||
#include "../../model/world/idcompletionmanager.hpp"
|
||||
|
||||
#include "../widget/droplineedit.hpp"
|
||||
|
||||
std::string CSVWorld::ReferenceCreator::getId() const
|
||||
{
|
||||
return mId;
|
||||
|
@ -80,7 +81,7 @@ CSVWorld::ReferenceCreator::ReferenceCreator (CSMWorld::Data& data, QUndoStack&
|
|||
QLabel *label = new QLabel ("Cell", this);
|
||||
insertBeforeButtons (label, false);
|
||||
|
||||
mCell = new QLineEdit (this);
|
||||
mCell = new CSVWidget::DropLineEdit(CSMWorld::ColumnBase::Display_Cell, this);
|
||||
mCell->setCompleter(completionManager.getCompleter(CSMWorld::ColumnBase::Display_Cell).get());
|
||||
insertBeforeButtons (mCell, true);
|
||||
|
||||
|
|
|
@ -3,13 +3,16 @@
|
|||
|
||||
#include "genericcreator.hpp"
|
||||
|
||||
class QLineEdit;
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class IdCompletionManager;
|
||||
}
|
||||
|
||||
namespace CSVWidget
|
||||
{
|
||||
class DropLineEdit;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
|
||||
|
@ -17,7 +20,7 @@ namespace CSVWorld
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
QLineEdit *mCell;
|
||||
CSVWidget::DropLineEdit *mCell;
|
||||
std::string mId;
|
||||
|
||||
private:
|
||||
|
|
|
@ -170,6 +170,9 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
|||
manager.add (CSMWorld::UniversalId::Type_Filter,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator, CSMWorld::Scope_Project | CSMWorld::Scope_Session> > (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_MetaData,
|
||||
new CSVDoc::SubViewFactory<SimpleDialogueSubView >);
|
||||
|
||||
//preview
|
||||
manager.add (CSMWorld::UniversalId::Type_Preview, new CSVDoc::SubViewFactory<PreviewSubView>);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <QString>
|
||||
#include <QtCore/qnamespace.h>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
||||
#include "../../model/world/data.hpp"
|
||||
|
@ -128,17 +130,24 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
|||
{
|
||||
int row = mProxyModel->mapToSource (
|
||||
mProxyModel->index (selectedRows.begin()->row(), 0)).row();
|
||||
QString curData = mModel->data(mModel->index(row, column)).toString();
|
||||
|
||||
if (row>0 && mModel->data (mModel->index (row, column))==
|
||||
mModel->data (mModel->index (row-1, column)))
|
||||
if (row > 0)
|
||||
{
|
||||
menu.addAction (mMoveUpAction);
|
||||
QString prevData = mModel->data(mModel->index(row - 1, column)).toString();
|
||||
if (Misc::StringUtils::ciEqual(curData.toStdString(), prevData.toStdString()))
|
||||
{
|
||||
menu.addAction(mMoveUpAction);
|
||||
}
|
||||
}
|
||||
|
||||
if (row<mModel->rowCount()-1 && mModel->data (mModel->index (row, column))==
|
||||
mModel->data (mModel->index (row+1, column)))
|
||||
if (row < mModel->rowCount() - 1)
|
||||
{
|
||||
menu.addAction (mMoveDownAction);
|
||||
QString nextData = mModel->data(mModel->index(row + 1, column)).toString();
|
||||
if (Misc::StringUtils::ciEqual(curData.toStdString(), nextData.toStdString()))
|
||||
{
|
||||
menu.addAction(mMoveDownAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -697,36 +706,6 @@ void CSVWorld::Table::mouseMoveEvent (QMouseEvent* event)
|
|||
}
|
||||
}
|
||||
|
||||
void CSVWorld::Table::dropEvent(QDropEvent *event)
|
||||
{
|
||||
QModelIndex index = indexAt (event->pos());
|
||||
|
||||
if (!index.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData());
|
||||
if (!mime) // May happen when non-records (e.g. plain text) are dragged and dropped
|
||||
return;
|
||||
|
||||
if (mime->fromDocument (mDocument))
|
||||
{
|
||||
CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display>
|
||||
(mModel->headerData (index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
|
||||
|
||||
if (mime->holdsType (display))
|
||||
{
|
||||
CSMWorld::UniversalId record (mime->returnMatching (display));
|
||||
|
||||
std::auto_ptr<CSMWorld::ModifyCommand> command (new CSMWorld::ModifyCommand
|
||||
(*mProxyModel, index, QVariant (QString::fromUtf8 (record.getId().c_str()))));
|
||||
|
||||
mDocument.getUndoStack().push (command.release());
|
||||
}
|
||||
} //TODO handle drops from different document
|
||||
}
|
||||
|
||||
std::vector<std::string> CSVWorld::Table::getColumnsWithDisplay(CSMWorld::ColumnBase::Display display) const
|
||||
{
|
||||
const int count = mModel->columnCount();
|
||||
|
|
|
@ -76,8 +76,6 @@ namespace CSVWorld
|
|||
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
|
||||
void dropEvent(QDropEvent *event);
|
||||
|
||||
protected:
|
||||
|
||||
virtual void mouseDoubleClickEvent (QMouseEvent *event);
|
||||
|
|
|
@ -17,7 +17,10 @@
|
|||
#include "../../model/world/commands.hpp"
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
#include "../../model/world/commanddispatcher.hpp"
|
||||
|
||||
#include "../widget/coloreditor.hpp"
|
||||
#include "../widget/droplineedit.hpp"
|
||||
|
||||
#include "dialoguespinbox.hpp"
|
||||
#include "scriptedit.hpp"
|
||||
|
||||
|
@ -229,33 +232,35 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO
|
|||
return edit;
|
||||
}
|
||||
|
||||
case CSMWorld::ColumnBase::Display_LongString256:
|
||||
{
|
||||
/// \todo implement size limit. QPlainTextEdit does not support a size limit.
|
||||
QPlainTextEdit *edit = new QPlainTextEdit(parent);
|
||||
edit->setUndoRedoEnabled (false);
|
||||
return edit;
|
||||
}
|
||||
|
||||
case CSMWorld::ColumnBase::Display_Boolean:
|
||||
|
||||
return new QCheckBox(parent);
|
||||
|
||||
case CSMWorld::ColumnBase::Display_String:
|
||||
case CSMWorld::ColumnBase::Display_Skill:
|
||||
case CSMWorld::ColumnBase::Display_Script:
|
||||
case CSMWorld::ColumnBase::Display_Race:
|
||||
case CSMWorld::ColumnBase::Display_Region:
|
||||
case CSMWorld::ColumnBase::Display_Class:
|
||||
case CSMWorld::ColumnBase::Display_Faction:
|
||||
case CSMWorld::ColumnBase::Display_Miscellaneous:
|
||||
case CSMWorld::ColumnBase::Display_Sound:
|
||||
case CSMWorld::ColumnBase::Display_Mesh:
|
||||
case CSMWorld::ColumnBase::Display_Icon:
|
||||
case CSMWorld::ColumnBase::Display_Music:
|
||||
case CSMWorld::ColumnBase::Display_SoundRes:
|
||||
case CSMWorld::ColumnBase::Display_Texture:
|
||||
case CSMWorld::ColumnBase::Display_Video:
|
||||
case CSMWorld::ColumnBase::Display_GlobalVariable:
|
||||
|
||||
return new DropLineEdit(parent);
|
||||
|
||||
case CSMWorld::ColumnBase::Display_ScriptLines:
|
||||
|
||||
return new ScriptEdit (mDocument, ScriptHighlighter::Mode_Console, parent);
|
||||
|
||||
case CSMWorld::ColumnBase::Display_String:
|
||||
// For other Display types (that represent record IDs) with drop support IdCompletionDelegate is used
|
||||
|
||||
return new CSVWidget::DropLineEdit(display, parent);
|
||||
|
||||
case CSMWorld::ColumnBase::Display_String32:
|
||||
{
|
||||
// For other Display types (that represent record IDs) with drop support IdCompletionDelegate is used
|
||||
CSVWidget::DropLineEdit *widget = new CSVWidget::DropLineEdit(display, parent);
|
||||
widget->setMaxLength (32);
|
||||
return widget;
|
||||
}
|
||||
|
||||
default:
|
||||
|
||||
return QStyledItemDelegate::createEditor (parent, option, index);
|
||||
|
@ -324,29 +329,3 @@ void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelInde
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
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()));
|
||||
if (!data) // May happen when non-records (e.g. plain text) are dragged and dropped
|
||||
return;
|
||||
|
||||
emit tableMimeDataDropped(data->getData(), data->getDocumentPtr());
|
||||
//WIP
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QLineEdit>
|
||||
|
||||
#include "../../model/world/columnbase.hpp"
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
@ -91,24 +90,6 @@ 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
|
||||
class CommandDelegate : public QStyledItemDelegate
|
||||
{
|
||||
|
|
|
@ -45,6 +45,8 @@ std::set<MWMechanics::EffectKey> MWMechanics::Alchemy::listEffects() const
|
|||
{
|
||||
const MWWorld::LiveCellRef<ESM::Ingredient> *ingredient = iter->get<ESM::Ingredient>();
|
||||
|
||||
std::set<EffectKey> seenEffects;
|
||||
|
||||
for (int i=0; i<4; ++i)
|
||||
if (ingredient->mBase->mData.mEffectID[i]!=-1)
|
||||
{
|
||||
|
@ -52,7 +54,8 @@ std::set<MWMechanics::EffectKey> MWMechanics::Alchemy::listEffects() const
|
|||
ingredient->mBase->mData.mEffectID[i], ingredient->mBase->mData.mSkills[i]!=-1 ?
|
||||
ingredient->mBase->mData.mSkills[i] : ingredient->mBase->mData.mAttributes[i]);
|
||||
|
||||
++effects[key];
|
||||
if (seenEffects.insert(key).second)
|
||||
++effects[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -461,7 +464,10 @@ MWMechanics::Alchemy::Result MWMechanics::Alchemy::create (const std::string& na
|
|||
return Result_NoName;
|
||||
|
||||
if (listEffects().empty())
|
||||
{
|
||||
removeIngredients();
|
||||
return Result_NoEffects;
|
||||
}
|
||||
|
||||
if (beginEffects() == endEffects())
|
||||
{
|
||||
|
|
|
@ -174,6 +174,15 @@ namespace ESM
|
|||
endRecord(name);
|
||||
}
|
||||
|
||||
void ESMWriter::writeFixedSizeString(const std::string &data, int size)
|
||||
{
|
||||
std::string string;
|
||||
if (!data.empty())
|
||||
string = mEncoder ? mEncoder->getLegacyEnc(data) : data;
|
||||
string.resize(size);
|
||||
write(string.c_str(), string.size());
|
||||
}
|
||||
|
||||
void ESMWriter::writeHString(const std::string& data)
|
||||
{
|
||||
if (data.size() == 0)
|
||||
|
|
|
@ -120,6 +120,7 @@ public:
|
|||
void startSubRecord(const std::string& name);
|
||||
void endRecord(const std::string& name);
|
||||
void endRecord(uint32_t name);
|
||||
void writeFixedSizeString(const std::string& data, int size);
|
||||
void writeHString(const std::string& data);
|
||||
void writeHCString(const std::string& data);
|
||||
void writeName(const std::string& data);
|
||||
|
|
|
@ -71,7 +71,13 @@ void ESM::Header::save (ESMWriter &esm)
|
|||
if (mFormat>0)
|
||||
esm.writeHNT ("FORM", mFormat);
|
||||
|
||||
esm.writeHNT ("HEDR", mData, 300);
|
||||
esm.startSubRecord("HEDR");
|
||||
esm.writeT(mData.version);
|
||||
esm.writeT(mData.type);
|
||||
esm.writeFixedSizeString(mData.author.toString(), 32);
|
||||
esm.writeFixedSizeString(mData.desc.toString(), 256);
|
||||
esm.writeT(mData.records);
|
||||
esm.endRecord("HEDR");
|
||||
|
||||
for (std::vector<Header::MasterData>::iterator iter = mMaster.begin();
|
||||
iter != mMaster.end(); ++iter)
|
||||
|
|
Loading…
Reference in a new issue