1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-19 22:53:50 +00:00

Merge branch 'meta'

This commit is contained in:
Marc Zinnschlag 2015-06-26 18:37:39 +02:00
commit 2dada1a162
24 changed files with 493 additions and 254 deletions

View file

@ -26,7 +26,7 @@ opencs_units_noqt (model/world
universalid record commands columnbase scriptcontext cell refidcollection universalid record commands columnbase scriptcontext cell refidcollection
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope
pathgrid landtexture land nestedtablewrapper nestedcollection nestedcoladapterimp nestedinfocollection pathgrid landtexture land nestedtablewrapper nestedcollection nestedcoladapterimp nestedinfocollection
idcompletionmanager idcompletionmanager metadata
) )
opencs_hdrs_noqt (model/world opencs_hdrs_noqt (model/world

View file

@ -2282,9 +2282,6 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
if (mNew) if (mNew)
{ {
mData.setDescription ("");
mData.setAuthor ("");
if (mContentFiles.size()==1) if (mContentFiles.size()==1)
createBase(); createBase();
} }

View file

@ -53,18 +53,16 @@ void CSMDoc::WriteHeaderStage::perform (int stage, Messages& messages)
mState.getWriter().clearMaster(); mState.getWriter().clearMaster();
mState.getWriter().setFormat (0);
if (mSimple) if (mSimple)
{ {
mState.getWriter().setAuthor (""); mState.getWriter().setAuthor ("");
mState.getWriter().setDescription (""); mState.getWriter().setDescription ("");
mState.getWriter().setRecordCount (0); mState.getWriter().setRecordCount (0);
mState.getWriter().setFormat (ESM::Header::CurrentFormat);
} }
else else
{ {
mState.getWriter().setAuthor (mDocument.getData().getAuthor()); mDocument.getData().getMetaData().save (mState.getWriter());
mState.getWriter().setDescription (mDocument.getData().getDescription());
mState.getWriter().setRecordCount ( mState.getWriter().setRecordCount (
mDocument.getData().count (CSMWorld::RecordBase::State_Modified) + mDocument.getData().count (CSMWorld::RecordBase::State_Modified) +
mDocument.getData().count (CSMWorld::RecordBase::State_ModifiedOnly) + mDocument.getData().count (CSMWorld::RecordBase::State_ModifiedOnly) +

View file

@ -100,7 +100,8 @@ bool CSMWorld::ColumnBase::isId (Display display)
bool CSMWorld::ColumnBase::isText (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) bool CSMWorld::ColumnBase::isScript (Display display)

View file

@ -123,6 +123,8 @@ namespace CSMWorld
Display_InfoCondVar, Display_InfoCondVar,
Display_InfoCondComp, Display_InfoCondComp,
Display_RaceSkill, Display_RaceSkill,
Display_String32,
Display_LongString256,
//top level columns that nest other columns //top level columns that nest other columns
Display_NestedHeader Display_NestedHeader

View file

@ -2308,6 +2308,78 @@ namespace CSMWorld
return true; 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 #endif

View file

@ -311,6 +311,10 @@ namespace CSMWorld
{ ColumnId_WaterLevel, "Water Level" }, { ColumnId_WaterLevel, "Water Level" },
{ ColumnId_MapColor, "Map Color" }, { ColumnId_MapColor, "Map Color" },
{ ColumnId_FileFormat, "File Format" },
{ ColumnId_FileDescription, "File Description" },
{ ColumnId_Author, "Author" },
{ ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue1, "Use value 1" },
{ ColumnId_UseValue2, "Use value 2" }, { ColumnId_UseValue2, "Use value 2" },
{ ColumnId_UseValue3, "Use value 3" }, { ColumnId_UseValue3, "Use value 3" },

View file

@ -302,6 +302,10 @@ namespace CSMWorld
ColumnId_WaterLevel = 273, ColumnId_WaterLevel = 273,
ColumnId_MapColor = 274, 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 // Allocated to a separate value range, so we don't get a collision should we ever need
// to extend the number of use values. // to extend the number of use values.
ColumnId_UseValue1 = 0x10000, ColumnId_UseValue1 = 0x10000,

View file

@ -475,6 +475,14 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
mDebugProfiles.addColumn (new ScriptColumn<ESM::DebugProfile> ( mDebugProfiles.addColumn (new ScriptColumn<ESM::DebugProfile> (
ScriptColumn<ESM::DebugProfile>::Type_Lines)); 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 (&mGlobals), UniversalId::Type_Global);
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmst); addModel (new IdTable (&mGmsts), UniversalId::Type_Gmst);
addModel (new IdTable (&mSkills), UniversalId::Type_Skill); addModel (new IdTable (&mSkills), UniversalId::Type_Skill);
@ -515,6 +523,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
UniversalId::Type_Texture); UniversalId::Type_Texture);
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Videos)), addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Videos)),
UniversalId::Type_Video); UniversalId::Type_Video);
addModel (new IdTable (&mMetaData), UniversalId::Type_MetaData);
mRefLoadCache.clear(); // clear here rather than startLoading() and continueLoading() for multiple content files mRefLoadCache.clear(); // clear here rather than startLoading() and continueLoading() for multiple content files
} }
@ -803,6 +812,11 @@ const CSMWorld::Resources& CSMWorld::Data::getResources (const UniversalId& id)
return mResourcesManager.get (id.getType()); 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) QAbstractItemModel *CSMWorld::Data::getTableModel (const CSMWorld::UniversalId& id)
{ {
std::map<UniversalId::Type, QAbstractItemModel *>::iterator iter = mModelIndex.find (id.getType()); std::map<UniversalId::Type, QAbstractItemModel *>::iterator iter = mModelIndex.find (id.getType());
@ -847,8 +861,14 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base
mBase = base; mBase = base;
mProject = project; mProject = project;
mAuthor = mReader->getAuthor(); if (!mProject && !mBase)
mDescription = mReader->getDesc(); {
MetaData metaData;
metaData.mId = "sys::meta";
metaData.load (*mReader);
mMetaData.setRecord (0, Record<MetaData> (RecordBase::State_ModifiedOnly, 0, &metaData));
}
return mReader->getRecordCount(); return mReader->getRecordCount();
} }
@ -1103,26 +1123,6 @@ int CSMWorld::Data::count (RecordBase::State state) const
count (state, mPathgrids); 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> CSMWorld::Data::getIds (bool listDeleted) const
{ {
std::vector<std::string> ids; std::vector<std::string> ids;

View file

@ -44,6 +44,7 @@
#include "infocollection.hpp" #include "infocollection.hpp"
#include "nestedinfocollection.hpp" #include "nestedinfocollection.hpp"
#include "pathgrid.hpp" #include "pathgrid.hpp"
#include "metadata.hpp"
#ifndef Q_MOC_RUN #ifndef Q_MOC_RUN
#include "subcellcollection.hpp" #include "subcellcollection.hpp"
#endif #endif
@ -94,11 +95,10 @@ namespace CSMWorld
RefIdCollection mReferenceables; RefIdCollection mReferenceables;
RefCollection mRefs; RefCollection mRefs;
IdCollection<ESM::Filter> mFilters; IdCollection<ESM::Filter> mFilters;
Collection<MetaData> mMetaData;
const ResourcesManager& mResourcesManager; const ResourcesManager& mResourcesManager;
std::vector<QAbstractItemModel *> mModels; std::vector<QAbstractItemModel *> mModels;
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex; std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;
std::string mAuthor;
std::string mDescription;
ESM::ESMReader *mReader; ESM::ESMReader *mReader;
const ESM::Dialogue *mDialogue; // last loaded dialogue const ESM::Dialogue *mDialogue; // last loaded dialogue
bool mBase; bool mBase;
@ -238,6 +238,8 @@ namespace CSMWorld
/// Throws an exception, if \a id does not match a resources list. /// Throws an exception, if \a id does not match a resources list.
const Resources& getResources (const UniversalId& id) const; const Resources& getResources (const UniversalId& id) const;
const MetaData& getMetaData() const;
QAbstractItemModel *getTableModel (const UniversalId& id); QAbstractItemModel *getTableModel (const UniversalId& id);
///< If no table model is available for \a id, an exception is thrown. ///< If no table model is available for \a id, an exception is thrown.
/// ///
@ -267,14 +269,6 @@ namespace CSMWorld
int count (RecordBase::State state) const; int count (RecordBase::State state) const;
///< Return number of top-level records with the given \a state. ///< 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: signals:
void idListChanged(); void idListChanged();

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_MagicEffects, "Magic Effects", 0 },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Pathgrids, "Pathgrids", 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_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 { 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_MagicEffect, "Magic Effect", 0 },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Pathgrid, "Pathgrid", 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_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 { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
}; };

View file

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

View file

@ -70,6 +70,10 @@ void CSVDoc::View::setupFileMenu()
connect (loadErrors, SIGNAL (triggered()), this, SLOT (loadErrorLog())); connect (loadErrors, SIGNAL (triggered()), this, SLOT (loadErrorLog()));
file->addAction (loadErrors); 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); QAction *close = new QAction (tr ("&Close"), this);
connect (close, SIGNAL (triggered()), this, SLOT (close())); connect (close, SIGNAL (triggered()), this, SLOT (close()));
file->addAction(close); file->addAction(close);
@ -813,6 +817,11 @@ void CSVDoc::View::addSearchSubView()
addSubView (mDocument->newSearch()); addSubView (mDocument->newSearch());
} }
void CSVDoc::View::addMetaDataSubView()
{
addSubView (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_MetaData, "sys::meta"));
}
void CSVDoc::View::abortOperation (int type) void CSVDoc::View::abortOperation (int type)
{ {
mDocument->abortOperation (type); mDocument->abortOperation (type);

View file

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

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()) if (QVariant::String == v.type())
{ {
label->setText(v.toString()); label->setText(v.toString());
} }
else //else we are facing enums else if (CSMWorld::Columns::hasEnums (columnId))
{ {
int data = v.toInt(); 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())); 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 void CSVWorld::NotEditableSubDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
@ -548,12 +556,38 @@ void CSVWorld::EditWidget::remake(int row)
this->setWidgetResizable(true); this->setWidgetResizable(true);
} }
/*
==============================DialogueSubView==========================================
*/
CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, QVBoxLayout& CSVWorld::SimpleDialogueSubView::getMainLayout()
const CreatorFactoryBase& creatorFactory, bool sorting) : {
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), SubView (id),
mEditWidget(0), mEditWidget(0),
mMainLayout(NULL), mMainLayout(NULL),
@ -570,60 +604,8 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
QWidget *mainWidget = new QWidget(this); 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); mMainLayout = new QVBoxLayout(mainWidget);
setWidget (mainWidget);
mEditWidget = new EditWidget(mainWidget, mEditWidget = new EditWidget(mainWidget,
mTable->getModelIndex(mCurrentId, 0).row(), mTable, mCommandDispatcher, document, false); mTable->getModelIndex(mCurrentId, 0).row(), mTable, mCommandDispatcher, document, false);
@ -631,98 +613,10 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
mMainLayout->addWidget(mEditWidget); mMainLayout->addWidget(mEditWidget);
mEditWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); 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)); dataChanged(mTable->getModelIndex (mCurrentId, 0));
mMainLayout->addLayout (buttonsLayout);
setWidget (mainWidget);
} }
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 mCurrentId is no longer valid
return; return;
@ -741,7 +635,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)); QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0));
@ -774,7 +668,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)); QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0));
@ -789,45 +683,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); changeCurrentId(id);
mEditWidget->remake(mTable->getModelIndex (id, 0).row()); mEditWidget->remake(mTable->getModelIndex (id, 0).row());
} }
void CSVWorld::DialogueSubView::cloneRequest () void CSVWorld::SimpleDialogueSubView::changeCurrentId (const std::string& newId)
{
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)
{ {
std::vector<std::string> selection; std::vector<std::string> selection;
mCurrentId = std::string(newId); mCurrentId = std::string(newId);
@ -835,3 +698,186 @@ void CSVWorld::DialogueSubView::changeCurrentId (const std::string& newId)
selection.push_back(mCurrentId); selection.push_back(mCurrentId);
mCommandDispatcher.setSelection(selection); mCommandDispatcher.setSelection(selection);
} }
CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id,
CSMDoc::Document& document, const CreatorFactoryBase& creatorFactory, bool sorting)
: SimpleDialogueSubView (id, document)
{
// 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;
}
while (newRow < getTable().rowCount())
{
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); void remake(int row);
}; };
class DialogueSubView : public CSVDoc::SubView class SimpleDialogueSubView : public CSVDoc::SubView
{ {
Q_OBJECT Q_OBJECT
@ -184,33 +184,32 @@ namespace CSVWorld
std::string mCurrentId; std::string mCurrentId;
bool mLocked; bool mLocked;
const CSMDoc::Document& mDocument; const CSMDoc::Document& mDocument;
TableBottomBox* mBottom;
CSMWorld::CommandDispatcher mCommandDispatcher; 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: public:
DialogueSubView (const CSMWorld::UniversalId& id, SimpleDialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
CSMDoc::Document& document,
const CreatorFactoryBase& creatorFactory,
bool sorting = false);
virtual void setEditLock (bool locked); virtual void setEditLock (bool locked);
private:
void changeCurrentId(const std::string& newCurrent);
private slots: private slots:
void nextId();
void prevId();
void showPreview();
void viewRecord();
void cloneRequest();
void dataChanged(const QModelIndex & index); void dataChanged(const QModelIndex & index);
///\brief we need to care for deleting currently edited record ///\brief we need to care for deleting currently edited record
@ -218,6 +217,30 @@ namespace CSVWorld
void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
}; };
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 #endif

View file

@ -4,7 +4,6 @@
#include <algorithm> #include <algorithm>
#include <QLabel> #include <QLabel>
#include <QLineEdit>
#include <QUuid> #include <QUuid>
#include <components/misc/stringops.hpp> #include <components/misc/stringops.hpp>
@ -17,6 +16,8 @@
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/world/idcompletionmanager.hpp" #include "../../model/world/idcompletionmanager.hpp"
#include "../widget/droplineedit.hpp"
std::string CSVWorld::InfoCreator::getId() const std::string CSVWorld::InfoCreator::getId() const
{ {
std::string id = Misc::StringUtils::lowerCase (mTopic->text().toUtf8().constData()); 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); QLabel *label = new QLabel ("Topic", this);
insertBeforeButtons (label, false); insertBeforeButtons (label, false);
mTopic = new QLineEdit (this);
CSMWorld::ColumnBase::Display displayType = CSMWorld::ColumnBase::Display_Topic; CSMWorld::ColumnBase::Display displayType = CSMWorld::ColumnBase::Display_Topic;
if (getCollectionId().getType() == CSMWorld::UniversalId::Type_JournalInfos) if (getCollectionId().getType() == CSMWorld::UniversalId::Type_JournalInfos)
{ {
displayType = CSMWorld::ColumnBase::Display_Journal; displayType = CSMWorld::ColumnBase::Display_Journal;
} }
mTopic = new CSVWidget::DropLineEdit(displayType, this);
mTopic->setCompleter(completionManager.getCompleter(displayType).get()); mTopic->setCompleter(completionManager.getCompleter(displayType).get());
insertBeforeButtons (mTopic, true); insertBeforeButtons (mTopic, true);

View file

@ -3,21 +3,24 @@
#include "genericcreator.hpp" #include "genericcreator.hpp"
class QLineEdit;
namespace CSMWorld namespace CSMWorld
{ {
class InfoCollection; class InfoCollection;
class IdCompletionManager; class IdCompletionManager;
} }
namespace CSVWidget
{
class DropLineEdit;
}
namespace CSVWorld namespace CSVWorld
{ {
class InfoCreator : public GenericCreator class InfoCreator : public GenericCreator
{ {
Q_OBJECT Q_OBJECT
QLineEdit *mTopic; CSVWidget::DropLineEdit *mTopic;
virtual std::string getId() const; virtual std::string getId() const;

View file

@ -2,7 +2,6 @@
#include "referencecreator.hpp" #include "referencecreator.hpp"
#include <QLabel> #include <QLabel>
#include <QLineEdit>
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
@ -12,6 +11,8 @@
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/world/idcompletionmanager.hpp" #include "../../model/world/idcompletionmanager.hpp"
#include "../widget/droplineedit.hpp"
std::string CSVWorld::ReferenceCreator::getId() const std::string CSVWorld::ReferenceCreator::getId() const
{ {
return mId; return mId;
@ -80,7 +81,7 @@ CSVWorld::ReferenceCreator::ReferenceCreator (CSMWorld::Data& data, QUndoStack&
QLabel *label = new QLabel ("Cell", this); QLabel *label = new QLabel ("Cell", this);
insertBeforeButtons (label, false); 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()); mCell->setCompleter(completionManager.getCompleter(CSMWorld::ColumnBase::Display_Cell).get());
insertBeforeButtons (mCell, true); insertBeforeButtons (mCell, true);

View file

@ -3,13 +3,16 @@
#include "genericcreator.hpp" #include "genericcreator.hpp"
class QLineEdit;
namespace CSMWorld namespace CSMWorld
{ {
class IdCompletionManager; class IdCompletionManager;
} }
namespace CSVWidget
{
class DropLineEdit;
}
namespace CSVWorld namespace CSVWorld
{ {
@ -17,7 +20,7 @@ namespace CSVWorld
{ {
Q_OBJECT Q_OBJECT
QLineEdit *mCell; CSVWidget::DropLineEdit *mCell;
std::string mId; std::string mId;
private: private:

View file

@ -170,6 +170,9 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
manager.add (CSMWorld::UniversalId::Type_Filter, manager.add (CSMWorld::UniversalId::Type_Filter,
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator, CSMWorld::Scope_Project | CSMWorld::Scope_Session> > (false)); new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator, CSMWorld::Scope_Project | CSMWorld::Scope_Session> > (false));
manager.add (CSMWorld::UniversalId::Type_MetaData,
new CSVDoc::SubViewFactory<SimpleDialogueSubView >);
//preview //preview
manager.add (CSMWorld::UniversalId::Type_Preview, new CSVDoc::SubViewFactory<PreviewSubView>); manager.add (CSMWorld::UniversalId::Type_Preview, new CSVDoc::SubViewFactory<PreviewSubView>);
} }

View file

@ -232,6 +232,14 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO
return edit; 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: case CSMWorld::ColumnBase::Display_Boolean:
return new QCheckBox(parent); return new QCheckBox(parent);
@ -245,6 +253,14 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO
return new CSVWidget::DropLineEdit(display, parent); 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: default:
return QStyledItemDelegate::createEditor (parent, option, index); return QStyledItemDelegate::createEditor (parent, option, index);