1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-06-29 08:41:34 +00:00

Merge branch 'master' into autocalc

Conflicts:
	apps/opencs/CMakeLists.txt
	apps/opencs/model/world/columns.cpp
	apps/opencs/model/world/columns.hpp
	apps/opencs/model/world/data.hpp
	apps/opencs/view/world/dialoguesubview.cpp
This commit is contained in:
cc9cii 2015-06-27 07:46:36 +10:00
commit 2612a91f8d
38 changed files with 639 additions and 325 deletions

View file

@ -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 npcstats
idcompletionmanager npcstats metadata
)
opencs_hdrs_noqt (model/world

View file

@ -2282,9 +2282,6 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
if (mNew)
{
mData.setDescription ("");
mData.setAuthor ("");
if (mContentFiles.size()==1)
createBase();
}
@ -2369,9 +2366,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;
}

View file

@ -120,7 +120,7 @@ namespace CSMDoc
void save();
CSMWorld::UniversalId verify();
CSMWorld::UniversalId verify (const CSMWorld::UniversalId& reportId = CSMWorld::UniversalId());
CSMWorld::UniversalId newSearch();

View file

@ -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) +

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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()

View file

@ -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();

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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_SpellSrc, "From Race" },
{ ColumnId_SpellCost, "Cast Cost" },
{ ColumnId_SpellChance, "Cast Chance" },

View file

@ -302,9 +302,13 @@ namespace CSMWorld
ColumnId_WaterLevel = 273,
ColumnId_MapColor = 274,
ColumnId_SpellSrc = 275,
ColumnId_SpellCost = 276,
ColumnId_SpellChance = 277,
ColumnId_FileFormat = 275,
ColumnId_FileDescription = 276,
ColumnId_Author = 277,
ColumnId_SpellSrc = 278,
ColumnId_SpellCost = 279,
ColumnId_SpellChance = 280,
// Allocated to a separate value range, so we don't get a collision should we ever need
// to extend the number of use values.

View file

@ -544,6 +544,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);
@ -584,6 +592,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);
// for autocalc updates when gmst/race/class/skils tables change
CSMWorld::IdTable *gmsts =
@ -901,6 +910,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());
@ -945,9 +959,15 @@ 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();
}
@ -1201,26 +1221,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;

View file

@ -44,6 +44,7 @@
#include "infocollection.hpp"
#include "nestedinfocollection.hpp"
#include "pathgrid.hpp"
#include "metadata.hpp"
#ifndef Q_MOC_RUN
#include "subcellcollection.hpp"
#endif
@ -95,11 +96,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;
@ -245,6 +245,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.
///
@ -274,14 +276,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;
NpcStats* npcAutoCalculate (const ESM::NPC& npc) const;
NpcStats* getCachedNpcData (const std::string& id) const;

View file

@ -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

View file

@ -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();
}

View file

@ -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);
};
}

View 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);
}

View 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

View file

@ -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
};

View file

@ -131,6 +131,8 @@ namespace CSMWorld
Type_StartScripts,
Type_StartScript,
Type_Search,
Type_MetaDatas,
Type_MetaData,
Type_RunLog
};

View file

@ -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);

View file

@ -224,6 +224,8 @@ namespace CSVDoc
void addSearchSubView();
void addMetaDataSubView();
void toggleShowStatusBar (bool show);
void loadErrorLog();

View file

@ -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());
}
}
}

View file

@ -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();
};
}

View file

@ -74,8 +74,10 @@ 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));
}

View file

@ -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();
};
}

View file

@ -35,7 +35,7 @@ void CSVWidget::DropLineEdit::dropEvent(QDropEvent *event)
if (CSVWorld::DragDropUtils::canAcceptData(*event, mDropType))
{
CSMWorld::UniversalId id = CSVWorld::DragDropUtils::getAcceptedData(*event, mDropType);
setText(id.getId().c_str());
setText(QString::fromUtf8(id.getId().c_str()));
emit tableMimeDataDropped(id, CSVWorld::DragDropUtils::getTableMimeData(*event)->getDocumentPtr());
}
}

View file

@ -64,16 +64,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
@ -550,12 +558,38 @@ 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;
}
std::string CSVWorld::SimpleDialogueSubView::getCurrentId() const
{
return mCurrentId;
}
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),
@ -572,60 +606,8 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
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);
@ -641,98 +623,10 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
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);
}
void CSVWorld::DialogueSubView::prevId ()
{
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)
void CSVWorld::SimpleDialogueSubView::setEditLock (bool locked)
{
if (!mEditWidget) // hack to indicate that mCurrentId is no longer valid
return;
@ -751,7 +645,7 @@ 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));
@ -784,7 +678,7 @@ 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));
@ -799,45 +693,14 @@ void CSVWorld::DialogueSubView::rowsAboutToBeRemoved(const QModelIndex &parent,
}
}
void CSVWorld::DialogueSubView::requestFocus (const std::string& id)
void CSVWorld::SimpleDialogueSubView::requestFocus (const std::string& id)
{
changeCurrentId(id);
mEditWidget->remake(mTable->getModelIndex (id, 0).row());
}
void CSVWorld::DialogueSubView::cloneRequest ()
{
mBottom->cloneRequest(mCurrentId, static_cast<CSMWorld::UniversalId::Type>(mTable->data(mTable->getModelIndex(mCurrentId, 2)).toInt()));
}
void CSVWorld::DialogueSubView::showPreview ()
{
QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0));
if (currentIndex.isValid() &&
mTable->getFeatures() & CSMWorld::IdTable::Feature_Preview &&
currentIndex.row() < mTable->rowCount())
{
emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, mCurrentId), "");
}
}
void CSVWorld::DialogueSubView::viewRecord ()
{
QModelIndex currentIndex(mTable->getModelIndex (mCurrentId, 0));
if (currentIndex.isValid() &&
currentIndex.row() < mTable->rowCount())
{
std::pair<CSMWorld::UniversalId, std::string> params = mTable->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::SimpleDialogueSubView::changeCurrentId (const std::string& newId)
{
std::vector<std::string> selection;
mCurrentId = std::string(newId);
@ -846,26 +709,184 @@ void CSVWorld::DialogueSubView::changeCurrentId (const std::string& newId)
mCommandDispatcher.setSelection(selection);
}
void CSVWorld::DialogueSubView::refreshNpcDialogue (int type, const std::string& id)
CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id,
CSMDoc::Document& document, const CreatorFactoryBase& creatorFactory, bool sorting)
: SimpleDialogueSubView (id, document)
{
int typeColumn = mTable->findColumnIndex (CSMWorld::Columns::ColumnId_RecordType);
if (CSMWorld::UniversalId::Type_Npc
!= mTable->data(mTable->getModelIndex(mCurrentId, typeColumn), Qt::DisplayRole).toInt())
// bottom box
getMainLayout().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&)));
// buttons
QHBoxLayout *buttonsLayout = new QHBoxLayout;
QToolButton* prevButton = new QToolButton (this);
prevButton->setIcon(QIcon(":/go-previous.png"));
prevButton->setToolTip ("Switch to previous record");
QToolButton* nextButton = new QToolButton (this);
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 (this);
cloneButton->setIcon(QIcon(":/edit-clone.png"));
cloneButton->setToolTip ("Clone record");
QToolButton* addButton = new QToolButton (this);
addButton->setIcon(QIcon(":/add.png"));
addButton->setToolTip ("Add new record");
QToolButton* deleteButton = new QToolButton (this);
deleteButton->setIcon(QIcon(":/edit-delete.png"));
deleteButton->setToolTip ("Delete record");
QToolButton* revertButton = new QToolButton (this);
revertButton->setIcon(QIcon(":/edit-undo.png"));
revertButton->setToolTip ("Revert record");
if (getTable().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, SLOT(showPreview()));
}
if (getTable().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, 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()), &getCommandDispatcher(), SLOT(executeRevert()));
connect(deleteButton, SIGNAL(clicked()), &getCommandDispatcher(), SLOT(executeDelete()));
connect(addButton, SIGNAL(clicked()), mBottom, SLOT(createRequest()));
if(!mBottom->canCreateAndDelete())
{
cloneButton->setDisabled (true);
addButton->setDisabled (true);
deleteButton->setDisabled (true);
}
getMainLayout().addLayout (buttonsLayout);
}
void CSVWorld::DialogueSubView::cloneRequest()
{
mBottom->cloneRequest (getCurrentId(),
static_cast<CSMWorld::UniversalId::Type> (getTable().
data (getTable().getModelIndex(getCurrentId(), 2)).toInt()));
}
void CSVWorld::DialogueSubView::prevId()
{
int newRow = getTable().getModelIndex (getCurrentId(), 0).row() - 1;
if (newRow < 0)
{
return;
}
while (newRow >= 0)
{
QModelIndex newIndex (getTable().index(newRow, 0));
if (!newIndex.isValid())
{
return;
}
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State> (getTable().data (getTable().index (newRow, 1)).toInt());
if (!(state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased))
{
getEditWidget().remake (newRow);
setUniversalId(CSMWorld::UniversalId (static_cast<CSMWorld::UniversalId::Type> (getTable().data (getTable().index (newRow, 2)).toInt()),
getTable().data (getTable().index (newRow, 0)).toString().toUtf8().constData()));
changeCurrentId(std::string (getTable().data (getTable().index (newRow, 0)).toString().toUtf8().constData()));
getEditWidget().setDisabled (isLocked());
return;
}
--newRow;
}
}
void CSVWorld::DialogueSubView::nextId ()
{
int newRow = getTable().getModelIndex (getCurrentId(), 0).row() + 1;
if (newRow >= getTable().rowCount())
{
return;
}
int raceColumn = mTable->findColumnIndex (CSMWorld::Columns::ColumnId_Race);
int classColumn = mTable->findColumnIndex (CSMWorld::Columns::ColumnId_Class);
if ((type == 0/*FIXME*/ && id == "") // skill or gmst changed
|| (id == mTable->data(mTable->getModelIndex(mCurrentId, raceColumn),
Qt::DisplayRole).toString().toUtf8().constData()) // race
|| (id == mTable->data(mTable->getModelIndex(mCurrentId, classColumn),
Qt::DisplayRole).toString().toUtf8().constData())) // class
while (newRow < getTable().rowCount())
{
int y = mEditWidget->verticalScrollBar()->value();
mEditWidget->remake (mTable->getModelIndex(mCurrentId, 0).row());
mEditWidget->verticalScrollBar()->setValue(y);
QModelIndex newIndex (getTable().index(newRow, 0));
if (!newIndex.isValid())
{
return;
}
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State> (getTable().data (getTable().index (newRow, 1)).toInt());
if (!(state == CSMWorld::RecordBase::State_Deleted))
{
getEditWidget().remake(newRow);
setUniversalId(CSMWorld::UniversalId (static_cast<CSMWorld::UniversalId::Type> (getTable().data (getTable().index (newRow, 2)).toInt()),
getTable().data (getTable().index (newRow, 0)).toString().toUtf8().constData()));
changeCurrentId(std::string (getTable().data (getTable().index (newRow, 0)).toString().toUtf8().constData()));
getEditWidget().setDisabled (isLocked());
return;
}
++newRow;
}
}
void CSVWorld::DialogueSubView::showPreview ()
{
QModelIndex currentIndex (getTable().getModelIndex (getCurrentId(), 0));
if (currentIndex.isValid() &&
getTable().getFeatures() & CSMWorld::IdTable::Feature_Preview &&
currentIndex.row() < getTable().rowCount())
{
emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, getCurrentId()), "");
}
}
void CSVWorld::DialogueSubView::viewRecord ()
{
QModelIndex currentIndex (getTable().getModelIndex (getCurrentId(), 0));
if (currentIndex.isValid() &&
currentIndex.row() < getTable().rowCount())
{
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);
}
}

View file

@ -173,7 +173,7 @@ namespace CSVWorld
void remake(int row);
};
class DialogueSubView : public CSVDoc::SubView
class SimpleDialogueSubView : public CSVDoc::SubView
{
Q_OBJECT
@ -184,33 +184,32 @@ namespace CSVWorld
std::string mCurrentId;
bool mLocked;
const CSMDoc::Document& mDocument;
TableBottomBox* mBottom;
CSMWorld::CommandDispatcher mCommandDispatcher;
protected:
QVBoxLayout& getMainLayout();
CSMWorld::IdTable& getTable();
CSMWorld::CommandDispatcher& getCommandDispatcher();
std::string getCurrentId() const;
EditWidget& getEditWidget();
void changeCurrentId(const std::string& newCurrent);
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 prevId();
void showPreview();
void viewRecord();
void cloneRequest();
void dataChanged(const QModelIndex & index);
///\brief we need to care for deleting currently edited record
@ -220,6 +219,30 @@ namespace CSVWorld
void refreshNpcDialogue (int type, const std::string& id);
};
class DialogueSubView : public SimpleDialogueSubView
{
Q_OBJECT
TableBottomBox* mBottom;
public:
DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
const CreatorFactoryBase& creatorFactory, bool sorting = false);
private slots:
void cloneRequest();
void nextId();
void prevId();
void showPreview();
void viewRecord();
};
}
#endif

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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:

View file

@ -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>);
}

View file

@ -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);
}
}
}
}

View file

@ -233,6 +233,14 @@ 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);
@ -246,6 +254,14 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO
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);