mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 12:53:53 +00:00
Merge branch 'bottombar'
This commit is contained in:
commit
2e667f1d94
38 changed files with 1298 additions and 176 deletions
|
@ -57,13 +57,14 @@ opencs_hdrs_noqt (view/doc
|
||||||
|
|
||||||
|
|
||||||
opencs_units (view/world
|
opencs_units (view/world
|
||||||
table tablesubview scriptsubview util regionmapsubview
|
table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator
|
||||||
|
cellcreator referenceablecreator referencecreator
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (view/world
|
opencs_units_noqt (view/world
|
||||||
dialoguesubview subviews
|
dialoguesubview subviews
|
||||||
enumdelegate vartypedelegate recordstatusdelegate refidtypedelegate datadisplaydelegate
|
enumdelegate vartypedelegate recordstatusdelegate refidtypedelegate datadisplaydelegate
|
||||||
scripthighlighter
|
scripthighlighter idvalidator
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
#include "idtableproxymodel.hpp"
|
#include "idtable.hpp"
|
||||||
#include "idtable.hpp"
|
#include "idtable.hpp"
|
||||||
|
|
||||||
CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index,
|
CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index,
|
||||||
|
@ -25,15 +25,28 @@ void CSMWorld::ModifyCommand::undo()
|
||||||
mModel.setData (mIndex, mOld);
|
mModel.setData (mIndex, mOld);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::CreateCommand::CreateCommand (IdTableProxyModel& model, const std::string& id, QUndoCommand *parent)
|
CSMWorld::CreateCommand::CreateCommand (IdTable& model, const std::string& id, QUndoCommand *parent)
|
||||||
: QUndoCommand (parent), mModel (model), mId (id)
|
: QUndoCommand (parent), mModel (model), mId (id), mType (UniversalId::Type_None)
|
||||||
{
|
{
|
||||||
setText (("Create record " + id).c_str());
|
setText (("Create record " + id).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSMWorld::CreateCommand::addValue (int column, const QVariant& value)
|
||||||
|
{
|
||||||
|
mValues[column] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::CreateCommand::setType (UniversalId::Type type)
|
||||||
|
{
|
||||||
|
mType = type;
|
||||||
|
}
|
||||||
|
|
||||||
void CSMWorld::CreateCommand::redo()
|
void CSMWorld::CreateCommand::redo()
|
||||||
{
|
{
|
||||||
mModel.addRecord (mId);
|
mModel.addRecord (mId, mType);
|
||||||
|
|
||||||
|
for (std::map<int, QVariant>::const_iterator iter (mValues.begin()); iter!=mValues.end(); ++iter)
|
||||||
|
mModel.setData (mModel.getModelIndex (mId, iter->first), iter->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMWorld::CreateCommand::undo()
|
void CSMWorld::CreateCommand::undo()
|
||||||
|
|
|
@ -4,17 +4,20 @@
|
||||||
#include "record.hpp"
|
#include "record.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QUndoCommand>
|
#include <QUndoCommand>
|
||||||
#include <QModelIndex>
|
#include <QModelIndex>
|
||||||
|
|
||||||
|
#include "universalid.hpp"
|
||||||
|
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
class QAbstractItemModel;
|
class QAbstractItemModel;
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
class IdTableProxyModel;
|
class IdTable;
|
||||||
class IdTable;
|
class IdTable;
|
||||||
class RecordBase;
|
class RecordBase;
|
||||||
|
|
||||||
|
@ -37,12 +40,18 @@ namespace CSMWorld
|
||||||
|
|
||||||
class CreateCommand : public QUndoCommand
|
class CreateCommand : public QUndoCommand
|
||||||
{
|
{
|
||||||
IdTableProxyModel& mModel;
|
IdTable& mModel;
|
||||||
std::string mId;
|
std::string mId;
|
||||||
|
UniversalId::Type mType;
|
||||||
|
std::map<int, QVariant> mValues;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CreateCommand (IdTableProxyModel& model, const std::string& id, QUndoCommand *parent = 0);
|
CreateCommand (IdTable& model, const std::string& id, QUndoCommand *parent = 0);
|
||||||
|
|
||||||
|
void setType (UniversalId::Type type);
|
||||||
|
|
||||||
|
void addValue (int column, const QVariant& value);
|
||||||
|
|
||||||
virtual void redo();
|
virtual void redo();
|
||||||
|
|
||||||
|
|
|
@ -300,6 +300,16 @@ CSMWorld::RefIdCollection& CSMWorld::Data::getReferenceables()
|
||||||
return mReferenceables;
|
return mReferenceables;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CSMWorld::RefCollection& CSMWorld::Data::getReferences() const
|
||||||
|
{
|
||||||
|
return mRefs;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMWorld::RefCollection& CSMWorld::Data::getReferences()
|
||||||
|
{
|
||||||
|
return mRefs;
|
||||||
|
}
|
||||||
|
|
||||||
QAbstractItemModel *CSMWorld::Data::getTableModel (const UniversalId& id)
|
QAbstractItemModel *CSMWorld::Data::getTableModel (const UniversalId& id)
|
||||||
{
|
{
|
||||||
std::map<UniversalId::Type, QAbstractItemModel *>::iterator iter = mModelIndex.find (id.getType());
|
std::map<UniversalId::Type, QAbstractItemModel *>::iterator iter = mModelIndex.find (id.getType());
|
||||||
|
@ -394,4 +404,22 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base)
|
||||||
reader.skipRecord();
|
reader.skipRecord();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSMWorld::Data::hasId (const std::string& id) const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
getGlobals().searchId (id)!=-1 ||
|
||||||
|
getGmsts().searchId (id)!=-1 ||
|
||||||
|
getSkills().searchId (id)!=-1 ||
|
||||||
|
getClasses().searchId (id)!=-1 ||
|
||||||
|
getFactions().searchId (id)!=-1 ||
|
||||||
|
getRaces().searchId (id)!=-1 ||
|
||||||
|
getSounds().searchId (id)!=-1 ||
|
||||||
|
getScripts().searchId (id)!=-1 ||
|
||||||
|
getRegions().searchId (id)!=-1 ||
|
||||||
|
getBirthsigns().searchId (id)!=-1 ||
|
||||||
|
getSpells().searchId (id)!=-1 ||
|
||||||
|
getCells().searchId (id)!=-1 ||
|
||||||
|
getReferenceables().searchId (id)!=-1;
|
||||||
|
}
|
||||||
|
|
|
@ -112,6 +112,10 @@ namespace CSMWorld
|
||||||
|
|
||||||
RefIdCollection& getReferenceables();
|
RefIdCollection& getReferenceables();
|
||||||
|
|
||||||
|
const RefCollection& getReferences() const;
|
||||||
|
|
||||||
|
RefCollection& getReferences();
|
||||||
|
|
||||||
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.
|
||||||
///
|
///
|
||||||
|
@ -123,6 +127,8 @@ namespace CSMWorld
|
||||||
|
|
||||||
void loadFile (const boost::filesystem::path& path, bool base);
|
void loadFile (const boost::filesystem::path& path, bool base);
|
||||||
///< Merging content of a file into base or modified.
|
///< Merging content of a file into base or modified.
|
||||||
|
|
||||||
|
bool hasId (const std::string& id) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,13 +116,13 @@ QModelIndex CSMWorld::IdTable::parent (const QModelIndex& index) const
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMWorld::IdTable::addRecord (const std::string& id)
|
void CSMWorld::IdTable::addRecord (const std::string& id, UniversalId::Type type)
|
||||||
{
|
{
|
||||||
int index = mIdCollection->getAppendIndex();
|
int index = mIdCollection->getAppendIndex();
|
||||||
|
|
||||||
beginInsertRows (QModelIndex(), index, index);
|
beginInsertRows (QModelIndex(), index, index);
|
||||||
|
|
||||||
mIdCollection->appendBlankRecord (id);
|
mIdCollection->appendBlankRecord (id, type);
|
||||||
|
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
|
#include "universalid.hpp"
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
class CollectionBase;
|
class CollectionBase;
|
||||||
|
@ -44,7 +46,8 @@ namespace CSMWorld
|
||||||
|
|
||||||
virtual QModelIndex parent (const QModelIndex& index) const;
|
virtual QModelIndex parent (const QModelIndex& index) const;
|
||||||
|
|
||||||
void addRecord (const std::string& id);
|
void addRecord (const std::string& id, UniversalId::Type type = UniversalId::Type_None);
|
||||||
|
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||||
|
|
||||||
QModelIndex getModelIndex (const std::string& id, int column) const;
|
QModelIndex getModelIndex (const std::string& id, int column) const;
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,6 @@ CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent)
|
||||||
: QSortFilterProxyModel (parent)
|
: QSortFilterProxyModel (parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void CSMWorld::IdTableProxyModel::addRecord (const std::string& id)
|
|
||||||
{
|
|
||||||
dynamic_cast<IdTable&> (*sourceModel()).addRecord (id);
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex CSMWorld::IdTableProxyModel::getModelIndex (const std::string& id, int column) const
|
QModelIndex CSMWorld::IdTableProxyModel::getModelIndex (const std::string& id, int column) const
|
||||||
{
|
{
|
||||||
return mapFromSource (dynamic_cast<IdTable&> (*sourceModel()).getModelIndex (id, column));
|
return mapFromSource (dynamic_cast<IdTable&> (*sourceModel()).getModelIndex (id, column));
|
||||||
|
|
|
@ -15,8 +15,6 @@ namespace CSMWorld
|
||||||
|
|
||||||
IdTableProxyModel (QObject *parent = 0);
|
IdTableProxyModel (QObject *parent = 0);
|
||||||
|
|
||||||
virtual void addRecord (const std::string& id);
|
|
||||||
|
|
||||||
virtual QModelIndex getModelIndex (const std::string& id, int column) const;
|
virtual QModelIndex getModelIndex (const std::string& id, int column) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
|
||||||
while (cell2.getNextRef (reader, ref))
|
while (cell2.getNextRef (reader, ref))
|
||||||
{
|
{
|
||||||
/// \todo handle deleted and moved references
|
/// \todo handle deleted and moved references
|
||||||
std::ostringstream stream;
|
ref.load (reader, cell2, getNewId());
|
||||||
stream << "ref#" << mNextId++;
|
|
||||||
|
|
||||||
ref.load (reader, cell2, stream.str());
|
|
||||||
|
|
||||||
Record<CellRef> record2;
|
Record<CellRef> record2;
|
||||||
record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
|
record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
|
||||||
|
@ -34,4 +31,11 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
mCells.setRecord (cellIndex, cell);
|
mCells.setRecord (cellIndex, cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CSMWorld::RefCollection::getNewId()
|
||||||
|
{
|
||||||
|
std::ostringstream stream;
|
||||||
|
stream << "ref#" << mNextId++;
|
||||||
|
return stream.str();
|
||||||
}
|
}
|
|
@ -21,6 +21,8 @@ namespace CSMWorld
|
||||||
|
|
||||||
void load (ESM::ESMReader& reader, int cellIndex, bool base);
|
void load (ESM::ESMReader& reader, int cellIndex, bool base);
|
||||||
///< Load a sequence of references.
|
///< Load a sequence of references.
|
||||||
|
|
||||||
|
std::string getNewId();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,81 +12,82 @@ namespace
|
||||||
CSMWorld::UniversalId::Class mClass;
|
CSMWorld::UniversalId::Class mClass;
|
||||||
CSMWorld::UniversalId::Type mType;
|
CSMWorld::UniversalId::Type mType;
|
||||||
const char *mName;
|
const char *mName;
|
||||||
|
const char *mIcon;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const TypeData sNoArg[] =
|
static const TypeData sNoArg[] =
|
||||||
{
|
{
|
||||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, "empty" },
|
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, "empty", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Globals, "Global Variables" },
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Globals, "Global Variables", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Gmsts, "Game Settings" },
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Gmsts, "Game Settings", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Skills, "Skills" },
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Skills, "Skills", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Classes, "Classes" },
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Classes, "Classes", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Factions, "Factions" },
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Factions, "Factions", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Races, "Races" },
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Races, "Races", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Sounds, "Sounds" },
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Sounds, "Sounds", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Scripts, "Scripts" },
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Scripts, "Scripts", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Regions, "Regions" },
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Regions, "Regions", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Birthsigns, "Birthsigns" },
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Birthsigns, "Birthsigns", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Spells, "Spells" },
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Spells, "Spells", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Cells, "Cells" },
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Cells, "Cells", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Referenceables,
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Referenceables,
|
||||||
"Referenceables" },
|
"Referenceables", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_References,
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_References,
|
||||||
"References" },
|
"References", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_NonRecord, CSMWorld::UniversalId::Type_RegionMap,
|
{ CSMWorld::UniversalId::Class_NonRecord, CSMWorld::UniversalId::Type_RegionMap,
|
||||||
"Region Map" },
|
"Region Map", 0 },
|
||||||
|
|
||||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
|
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
||||||
};
|
};
|
||||||
|
|
||||||
static const TypeData sIdArg[] =
|
static const TypeData sIdArg[] =
|
||||||
{
|
{
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Class, "Class" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Class, "Class", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Faction, "Faction" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Faction, "Faction", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Race, "Race" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Race, "Race", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Sound, "Sound" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Sound, "Sound", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Script, "Script" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Script, "Script", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Region, "Region" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Region, "Region", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Birthsign, "Birthsign" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Birthsign, "Birthsign", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Spell, "Spell" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Spell, "Spell", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Referenceables" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Referenceables", 0 },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Activator, "Activator" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Activator, "Activator", ":./activator.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Potion, "Potion" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Potion, "Potion", ":./potion.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Apparatus, "Apparatus" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Apparatus, "Apparatus", ":./apparatus.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Armor, "Armor" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Armor, "Armor", ":./armor.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Book, "Book" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Book, "Book", ":./book.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Clothing, "Clothing" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Clothing, "Clothing", ":./clothing.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Container, "Container" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Container, "Container", ":./container.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Creature, "Creature" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Creature, "Creature", ":./creature.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Door, "Door" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Door, "Door", ":./door.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Ingredient, "Ingredient" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Ingredient, "Ingredient", ":./ingredient.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_CreatureLevelledList,
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_CreatureLevelledList,
|
||||||
"Creature Levelled List" },
|
"Creature Levelled List", ":./creature.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_ItemLevelledList,
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_ItemLevelledList,
|
||||||
"Item Levelled List" },
|
"Item Levelled List", ":./leveled-item.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Light, "Light" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Light, "Light", ":./light.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Lockpick, "Lockpick" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Lockpick, "Lockpick", ":./lockpick.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Miscellaneous,
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Miscellaneous,
|
||||||
"Miscellaneous" },
|
"Miscellaneous", ":./miscellaneous.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Npc, "NPC" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Npc, "NPC", ":./npc.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Probe, "Probe" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Probe, "Probe", ":./probe.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Repair, "Repair" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Repair, "Repair", ":./repair.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Static, "Static" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Static, "Static", ":./static.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Weapon, "Weapon" },
|
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Weapon, "Weapon", ":./weapon.png" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Reference, "Reference" },
|
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Reference, "Reference", 0 },
|
||||||
|
|
||||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
|
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
||||||
};
|
};
|
||||||
|
|
||||||
static const TypeData sIndexArg[] =
|
static const TypeData sIndexArg[] =
|
||||||
{
|
{
|
||||||
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results" },
|
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results", 0 },
|
||||||
|
|
||||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
|
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned int IDARG_SIZE = sizeof (sIdArg) / sizeof (TypeData);
|
static const unsigned int IDARG_SIZE = sizeof (sIdArg) / sizeof (TypeData);
|
||||||
|
@ -268,6 +269,28 @@ std::string CSMWorld::UniversalId::toString() const
|
||||||
return stream.str();
|
return stream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CSMWorld::UniversalId::getIcon() const
|
||||||
|
{
|
||||||
|
const TypeData *typeData = mArgumentType==ArgumentType_None ? sNoArg :
|
||||||
|
(mArgumentType==ArgumentType_Id ? sIdArg : sIndexArg);
|
||||||
|
|
||||||
|
for (int i=0; typeData[i].mName; ++i)
|
||||||
|
if (typeData[i].mType==mType)
|
||||||
|
return typeData[i].mIcon ? typeData[i].mIcon : "";
|
||||||
|
|
||||||
|
throw std::logic_error ("failed to retrieve UniversalId type icon");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<CSMWorld::UniversalId::Type> CSMWorld::UniversalId::listReferenceableTypes()
|
||||||
|
{
|
||||||
|
std::vector<CSMWorld::UniversalId::Type> list;
|
||||||
|
|
||||||
|
for (int i=0; sIdArg[i].mName; ++i)
|
||||||
|
if (sIdArg[i].mClass==Class_RefRecord)
|
||||||
|
list.push_back (sIdArg[i].mType);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<int, const char *> CSMWorld::UniversalId::getIdArgPair (unsigned int index)
|
std::pair<int, const char *> CSMWorld::UniversalId::getIdArgPair (unsigned int index)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
|
|
||||||
|
@ -14,13 +15,14 @@ namespace CSMWorld
|
||||||
|
|
||||||
enum Class
|
enum Class
|
||||||
{
|
{
|
||||||
Class_None = 0,
|
Class_None = 0,
|
||||||
Class_Record,
|
Class_Record,
|
||||||
Class_SubRecord,
|
Class_RefRecord, // referenceable record
|
||||||
Class_RecordList,
|
Class_SubRecord,
|
||||||
Class_Collection, // multiple types of records combined
|
Class_RecordList,
|
||||||
Class_Transient, // not part of the world data or the project data
|
Class_Collection, // multiple types of records combined
|
||||||
Class_NonRecord // record like data that is not part of the world
|
Class_Transient, // not part of the world data or the project data
|
||||||
|
Class_NonRecord // record like data that is not part of the world
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ArgumentType
|
enum ArgumentType
|
||||||
|
@ -126,6 +128,11 @@ namespace CSMWorld
|
||||||
|
|
||||||
std::string toString() const;
|
std::string toString() const;
|
||||||
|
|
||||||
|
std::string getIcon() const;
|
||||||
|
///< Will return an empty string, if no icon is available.
|
||||||
|
|
||||||
|
static std::vector<Type> listReferenceableTypes();
|
||||||
|
|
||||||
static std::pair<int, const char *> getIdArgPair (unsigned int index);
|
static std::pair<int, const char *> getIdArgPair (unsigned int index);
|
||||||
static unsigned int getIdArgSize ();
|
static unsigned int getIdArgSize ();
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
#include "subview.hpp"
|
#include "subview.hpp"
|
||||||
|
|
||||||
|
|
||||||
CSVDoc::SubView::SubView (const CSMWorld::UniversalId& id) : mUniversalId (id)
|
CSVDoc::SubView::SubView (const CSMWorld::UniversalId& id) : mUniversalId (id)
|
||||||
{
|
{
|
||||||
/// \todo add a button to the title bar that clones this sub view
|
/// \todo add a button to the title bar that clones this sub view
|
||||||
|
|
||||||
setWindowTitle (mUniversalId.toString().c_str());
|
setWindowTitle (mUniversalId.toString().c_str());
|
||||||
|
|
||||||
/// \todo remove (for testing only)
|
|
||||||
setMinimumWidth (100);
|
|
||||||
setMinimumHeight (60);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::UniversalId CSVDoc::SubView::getUniversalId() const
|
CSMWorld::UniversalId CSVDoc::SubView::getUniversalId() const
|
||||||
|
@ -20,3 +15,5 @@ CSMWorld::UniversalId CSVDoc::SubView::getUniversalId() const
|
||||||
void CSVDoc::SubView::updateEditorSetting (const QString &settingName, const QString &settingValue)
|
void CSVDoc::SubView::updateEditorSetting (const QString &settingName, const QString &settingValue)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVDoc::SubView::setStatusBar (bool show) {}
|
|
@ -37,6 +37,9 @@ namespace CSVDoc
|
||||||
virtual void setEditLock (bool locked) = 0;
|
virtual void setEditLock (bool locked) = 0;
|
||||||
virtual void updateEditorSetting (const QString &, const QString &);
|
virtual void updateEditorSetting (const QString &, const QString &);
|
||||||
|
|
||||||
|
virtual void setStatusBar (bool show);
|
||||||
|
///< Default implementation: ignored
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void focusId (const CSMWorld::UniversalId& universalId);
|
void focusId (const CSMWorld::UniversalId& universalId);
|
||||||
|
|
|
@ -22,28 +22,20 @@ namespace CSVDoc
|
||||||
return new SubViewT (id, document);
|
return new SubViewT (id, document);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class SubViewT>
|
|
||||||
class SubViewFactoryWithCreateFlag : public SubViewFactoryBase
|
template<class SubViewT, class CreatorFactoryT>
|
||||||
|
class SubViewFactoryWithCreator : public SubViewFactoryBase
|
||||||
{
|
{
|
||||||
bool mCreateAndDelete;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SubViewFactoryWithCreateFlag (bool createAndDelete);
|
|
||||||
|
|
||||||
virtual CSVDoc::SubView *makeSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
|
virtual CSVDoc::SubView *makeSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class SubViewT>
|
template<class SubViewT, class CreatorFactoryT>
|
||||||
SubViewFactoryWithCreateFlag<SubViewT>::SubViewFactoryWithCreateFlag (bool createAndDelete)
|
CSVDoc::SubView *SubViewFactoryWithCreator<SubViewT, CreatorFactoryT>::makeSubView (
|
||||||
: mCreateAndDelete (createAndDelete)
|
const CSMWorld::UniversalId& id, CSMDoc::Document& document)
|
||||||
{}
|
|
||||||
|
|
||||||
template<class SubViewT>
|
|
||||||
CSVDoc::SubView *SubViewFactoryWithCreateFlag<SubViewT>::makeSubView (const CSMWorld::UniversalId& id,
|
|
||||||
CSMDoc::Document& document)
|
|
||||||
{
|
{
|
||||||
return new SubViewT (id, document, mCreateAndDelete);
|
return new SubViewT (id, document, CreatorFactoryT());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,11 @@ void CSVDoc::View::setupViewMenu()
|
||||||
QAction *newWindow = new QAction (tr ("&New View"), this);
|
QAction *newWindow = new QAction (tr ("&New View"), this);
|
||||||
connect (newWindow, SIGNAL (triggered()), this, SLOT (newView()));
|
connect (newWindow, SIGNAL (triggered()), this, SLOT (newView()));
|
||||||
view->addAction (newWindow);
|
view->addAction (newWindow);
|
||||||
|
|
||||||
|
mShowStatusBar = new QAction (tr ("Show Status Bar"), this);
|
||||||
|
mShowStatusBar->setCheckable (true);
|
||||||
|
connect (mShowStatusBar, SIGNAL (toggled (bool)), this, SLOT (toggleShowStatusBar (bool)));
|
||||||
|
view->addAction (mShowStatusBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVDoc::View::setupWorldMenu()
|
void CSVDoc::View::setupWorldMenu()
|
||||||
|
@ -282,6 +287,9 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id)
|
||||||
/// \todo add an user setting to reuse sub views (on a per document basis or on a per top level view basis)
|
/// \todo add an user setting to reuse sub views (on a per document basis or on a per top level view basis)
|
||||||
|
|
||||||
SubView *view = mSubViewFactory.makeSubView (id, *mDocument);
|
SubView *view = mSubViewFactory.makeSubView (id, *mDocument);
|
||||||
|
|
||||||
|
view->setStatusBar (mShowStatusBar->isChecked());
|
||||||
|
|
||||||
mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view);
|
mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view);
|
||||||
|
|
||||||
connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&)), this,
|
connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&)), this,
|
||||||
|
@ -436,3 +444,12 @@ void CSVDoc::View::updateEditorSetting (const QString &settingName, const QStrin
|
||||||
else if (settingName == "Height")
|
else if (settingName == "Height")
|
||||||
resizeViewHeight (settingValue.toInt());
|
resizeViewHeight (settingValue.toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVDoc::View::toggleShowStatusBar (bool show)
|
||||||
|
{
|
||||||
|
foreach (QObject *view, mSubViewWindow.children())
|
||||||
|
{
|
||||||
|
if (CSVDoc::SubView *subView = dynamic_cast<CSVDoc::SubView *> (view))
|
||||||
|
subView->setStatusBar (show);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ namespace CSVDoc
|
||||||
QAction *mRedo;
|
QAction *mRedo;
|
||||||
QAction *mSave;
|
QAction *mSave;
|
||||||
QAction *mVerify;
|
QAction *mVerify;
|
||||||
|
QAction *mShowStatusBar;
|
||||||
std::vector<QAction *> mEditingActions;
|
std::vector<QAction *> mEditingActions;
|
||||||
Operations *mOperations;
|
Operations *mOperations;
|
||||||
SubViewFactoryManager mSubViewFactory;
|
SubViewFactoryManager mSubViewFactory;
|
||||||
|
@ -158,6 +159,8 @@ namespace CSVDoc
|
||||||
void addRegionMapSubView();
|
void addRegionMapSubView();
|
||||||
|
|
||||||
void showUserSettings();
|
void showUserSettings();
|
||||||
|
|
||||||
|
void toggleShowStatusBar (bool show);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
81
apps/opencs/view/world/cellcreator.cpp
Normal file
81
apps/opencs/view/world/cellcreator.cpp
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
|
||||||
|
#include "cellcreator.hpp"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
std::string CSVWorld::CellCreator::getId() const
|
||||||
|
{
|
||||||
|
if (mType->currentIndex()==0)
|
||||||
|
return GenericCreator::getId();
|
||||||
|
|
||||||
|
std::ostringstream stream;
|
||||||
|
|
||||||
|
stream << "#" << mX->value() << " " << mY->value();
|
||||||
|
|
||||||
|
return stream.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::CellCreator::CellCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||||
|
const CSMWorld::UniversalId& id)
|
||||||
|
: GenericCreator (data, undoStack, id)
|
||||||
|
{
|
||||||
|
mY = new QSpinBox (this);
|
||||||
|
mY->setVisible (false);
|
||||||
|
mY->setMinimum (std::numeric_limits<int>::min());
|
||||||
|
mY->setMaximum (std::numeric_limits<int>::max());
|
||||||
|
connect (mY, SIGNAL (valueChanged (int)), this, SLOT (valueChanged (int)));
|
||||||
|
insertAtBeginning (mY, true);
|
||||||
|
|
||||||
|
mYLabel = new QLabel ("Y", this);
|
||||||
|
mYLabel->setVisible (false);
|
||||||
|
insertAtBeginning (mYLabel, false);
|
||||||
|
|
||||||
|
mX = new QSpinBox (this);
|
||||||
|
mX->setVisible (false);
|
||||||
|
mX->setMinimum (std::numeric_limits<int>::min());
|
||||||
|
mX->setMaximum (std::numeric_limits<int>::max());
|
||||||
|
connect (mX, SIGNAL (valueChanged (int)), this, SLOT (valueChanged (int)));
|
||||||
|
insertAtBeginning (mX, true);
|
||||||
|
|
||||||
|
mXLabel = new QLabel ("X", this);
|
||||||
|
mXLabel->setVisible (false);
|
||||||
|
insertAtBeginning (mXLabel, false);
|
||||||
|
|
||||||
|
mType = new QComboBox (this);
|
||||||
|
|
||||||
|
mType->addItem ("Interior Cell");
|
||||||
|
mType->addItem ("Exterior Cell");
|
||||||
|
|
||||||
|
connect (mType, SIGNAL (currentIndexChanged (int)), this, SLOT (setType (int)));
|
||||||
|
|
||||||
|
insertAtBeginning (mType, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::CellCreator::reset()
|
||||||
|
{
|
||||||
|
mX->setValue (0);
|
||||||
|
mY->setValue (0);
|
||||||
|
mType->setCurrentIndex (0);
|
||||||
|
GenericCreator::reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::CellCreator::setType (int index)
|
||||||
|
{
|
||||||
|
setManualEditing (index==0);
|
||||||
|
mXLabel->setVisible (index==1);
|
||||||
|
mX->setVisible (index==1);
|
||||||
|
mYLabel->setVisible (index==1);
|
||||||
|
mY->setVisible (index==1);
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::CellCreator::valueChanged (int index)
|
||||||
|
{
|
||||||
|
update();
|
||||||
|
}
|
40
apps/opencs/view/world/cellcreator.hpp
Normal file
40
apps/opencs/view/world/cellcreator.hpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef CSV_WORLD_CELLCREATOR_H
|
||||||
|
#define CSV_WORLD_CELLCREATOR_H
|
||||||
|
|
||||||
|
class QLabel;
|
||||||
|
class QSpinBox;
|
||||||
|
class QComboBox;
|
||||||
|
|
||||||
|
#include "genericcreator.hpp"
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class CellCreator : public GenericCreator
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
QComboBox *mType;
|
||||||
|
QLabel *mXLabel;
|
||||||
|
QSpinBox *mX;
|
||||||
|
QLabel *mYLabel;
|
||||||
|
QSpinBox *mY;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual std::string getId() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CellCreator (CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id);
|
||||||
|
|
||||||
|
virtual void reset();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void setType (int index);
|
||||||
|
|
||||||
|
void valueChanged (int index);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
13
apps/opencs/view/world/creator.cpp
Normal file
13
apps/opencs/view/world/creator.cpp
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
#include "creator.hpp"
|
||||||
|
|
||||||
|
CSVWorld::Creator:: ~Creator() {}
|
||||||
|
|
||||||
|
CSVWorld::CreatorFactoryBase::~CreatorFactoryBase() {}
|
||||||
|
|
||||||
|
|
||||||
|
CSVWorld::Creator *CSVWorld::NullCreatorFactory::makeCreator (CSMWorld::Data& data,
|
||||||
|
QUndoStack& undoStack, const CSMWorld::UniversalId& id) const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
86
apps/opencs/view/world/creator.hpp
Normal file
86
apps/opencs/view/world/creator.hpp
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
#ifndef CSV_WORLD_CREATOR_H
|
||||||
|
#define CSV_WORLD_CREATOR_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class QUndoStack;
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class Data;
|
||||||
|
class UniversalId;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
/// \brief Record creator UI base class
|
||||||
|
class Creator : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~Creator();
|
||||||
|
|
||||||
|
virtual void reset() = 0;
|
||||||
|
|
||||||
|
virtual void setEditLock (bool locked) = 0;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void done();
|
||||||
|
|
||||||
|
void requestFocus (const std::string& id);
|
||||||
|
///< Request owner of this creator to focus the just created \a id. The owner may
|
||||||
|
/// ignore this request.
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \brief Base class for Creator factory
|
||||||
|
class CreatorFactoryBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~CreatorFactoryBase();
|
||||||
|
|
||||||
|
virtual Creator *makeCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||||
|
const CSMWorld::UniversalId& id) const = 0;
|
||||||
|
///< The ownership of the returned Creator is transferred to the caller.
|
||||||
|
///
|
||||||
|
/// \note The function can return a 0-pointer, which means no UI for creating/deleting
|
||||||
|
/// records should be provided.
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \brief Creator factory that does not produces any creator
|
||||||
|
class NullCreatorFactory : public CreatorFactoryBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual Creator *makeCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||||
|
const CSMWorld::UniversalId& id) const;
|
||||||
|
///< The ownership of the returned Creator is transferred to the caller.
|
||||||
|
///
|
||||||
|
/// \note The function always returns 0.
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class CreatorT>
|
||||||
|
class CreatorFactory : public CreatorFactoryBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual Creator *makeCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||||
|
const CSMWorld::UniversalId& id) const;
|
||||||
|
///< The ownership of the returned Creator is transferred to the caller.
|
||||||
|
///
|
||||||
|
/// \note The function can return a 0-pointer, which means no UI for creating/deleting
|
||||||
|
/// records should be provided.
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class CreatorT>
|
||||||
|
Creator *CreatorFactory<CreatorT>::makeCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||||
|
const CSMWorld::UniversalId& id) const
|
||||||
|
{
|
||||||
|
return new CreatorT (data, undoStack, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
135
apps/opencs/view/world/genericcreator.cpp
Normal file
135
apps/opencs/view/world/genericcreator.cpp
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
|
||||||
|
#include "genericcreator.hpp"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QUndoStack>
|
||||||
|
|
||||||
|
#include "../../model/world/commands.hpp"
|
||||||
|
#include "../../model/world/data.hpp"
|
||||||
|
#include "../../model/world/idtable.hpp"
|
||||||
|
|
||||||
|
#include "idvalidator.hpp"
|
||||||
|
|
||||||
|
void CSVWorld::GenericCreator::update()
|
||||||
|
{
|
||||||
|
mErrors = getErrors();
|
||||||
|
|
||||||
|
mCreate->setToolTip (QString::fromUtf8 (mErrors.c_str()));
|
||||||
|
mId->setToolTip (QString::fromUtf8 (mErrors.c_str()));
|
||||||
|
|
||||||
|
mCreate->setEnabled (mErrors.empty() && !mLocked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::GenericCreator::setManualEditing (bool enabled)
|
||||||
|
{
|
||||||
|
mId->setVisible (enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::GenericCreator::insertAtBeginning (QWidget *widget, bool stretched)
|
||||||
|
{
|
||||||
|
mLayout->insertWidget (0, widget, stretched ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::GenericCreator::insertBeforeButtons (QWidget *widget, bool stretched)
|
||||||
|
{
|
||||||
|
mLayout->insertWidget (mLayout->count()-2, widget, stretched ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CSVWorld::GenericCreator::getId() const
|
||||||
|
{
|
||||||
|
return mId->text().toUtf8().constData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::GenericCreator::configureCreateCommand (CSMWorld::CreateCommand& command) const {}
|
||||||
|
|
||||||
|
const CSMWorld::Data& CSVWorld::GenericCreator::getData() const
|
||||||
|
{
|
||||||
|
return mData;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMWorld::Data& CSVWorld::GenericCreator::getData()
|
||||||
|
{
|
||||||
|
return mData;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::GenericCreator::GenericCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||||
|
const CSMWorld::UniversalId& id)
|
||||||
|
: mData (data), mUndoStack (undoStack), mListId (id), mLocked (false)
|
||||||
|
{
|
||||||
|
mLayout = new QHBoxLayout;
|
||||||
|
mLayout->setContentsMargins (0, 0, 0, 0);
|
||||||
|
|
||||||
|
mId = new QLineEdit;
|
||||||
|
mId->setValidator (new IdValidator (this));
|
||||||
|
mLayout->addWidget (mId, 1);
|
||||||
|
|
||||||
|
mCreate = new QPushButton ("Create");
|
||||||
|
mLayout->addWidget (mCreate);
|
||||||
|
|
||||||
|
QPushButton *cancelButton = new QPushButton ("Cancel");
|
||||||
|
mLayout->addWidget (cancelButton);
|
||||||
|
|
||||||
|
setLayout (mLayout);
|
||||||
|
|
||||||
|
connect (cancelButton, SIGNAL (clicked (bool)), this, SIGNAL (done()));
|
||||||
|
connect (mCreate, SIGNAL (clicked (bool)), this, SLOT (create()));
|
||||||
|
|
||||||
|
connect (mId, SIGNAL (textChanged (const QString&)), this, SLOT (textChanged (const QString&)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::GenericCreator::setEditLock (bool locked)
|
||||||
|
{
|
||||||
|
mLocked = locked;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::GenericCreator::reset()
|
||||||
|
{
|
||||||
|
mId->setText ("");
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CSVWorld::GenericCreator::getErrors() const
|
||||||
|
{
|
||||||
|
std::string errors;
|
||||||
|
|
||||||
|
std::string id = getId();
|
||||||
|
|
||||||
|
if (id.empty())
|
||||||
|
{
|
||||||
|
errors = "Missing ID";
|
||||||
|
}
|
||||||
|
else if (mData.hasId (id))
|
||||||
|
{
|
||||||
|
errors = "ID is already in use";
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::GenericCreator::textChanged (const QString& text)
|
||||||
|
{
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::GenericCreator::create()
|
||||||
|
{
|
||||||
|
if (!mLocked)
|
||||||
|
{
|
||||||
|
std::string id = getId();
|
||||||
|
|
||||||
|
std::auto_ptr<CSMWorld::CreateCommand> command (new CSMWorld::CreateCommand (
|
||||||
|
dynamic_cast<CSMWorld::IdTable&> (*mData.getTableModel (mListId)), id));
|
||||||
|
|
||||||
|
configureCreateCommand (*command);
|
||||||
|
|
||||||
|
mUndoStack.push (command.release());
|
||||||
|
|
||||||
|
emit done();
|
||||||
|
emit requestFocus (id);
|
||||||
|
}
|
||||||
|
}
|
73
apps/opencs/view/world/genericcreator.hpp
Normal file
73
apps/opencs/view/world/genericcreator.hpp
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
#ifndef CSV_WORLD_GENERICCREATOR_H
|
||||||
|
#define CSV_WORLD_GENERICCREATOR_H
|
||||||
|
|
||||||
|
class QPushButton;
|
||||||
|
class QLineEdit;
|
||||||
|
class QHBoxLayout;
|
||||||
|
|
||||||
|
#include "creator.hpp"
|
||||||
|
|
||||||
|
#include "../../model/world/universalid.hpp"
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class CreateCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class GenericCreator : public Creator
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
CSMWorld::Data& mData;
|
||||||
|
QUndoStack& mUndoStack;
|
||||||
|
CSMWorld::UniversalId mListId;
|
||||||
|
QPushButton *mCreate;
|
||||||
|
QLineEdit *mId;
|
||||||
|
std::string mErrors;
|
||||||
|
QHBoxLayout *mLayout;
|
||||||
|
bool mLocked;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void update();
|
||||||
|
|
||||||
|
virtual void setManualEditing (bool enabled);
|
||||||
|
///< Enable/disable manual ID editing (enabled by default).
|
||||||
|
|
||||||
|
void insertAtBeginning (QWidget *widget, bool stretched);
|
||||||
|
|
||||||
|
void insertBeforeButtons (QWidget *widget, bool stretched);
|
||||||
|
|
||||||
|
virtual std::string getId() const;
|
||||||
|
|
||||||
|
virtual void configureCreateCommand (CSMWorld::CreateCommand& command) const;
|
||||||
|
|
||||||
|
const CSMWorld::Data& getData() const;
|
||||||
|
|
||||||
|
CSMWorld::Data& getData();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
GenericCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||||
|
const CSMWorld::UniversalId& id);
|
||||||
|
|
||||||
|
virtual void setEditLock (bool locked);
|
||||||
|
|
||||||
|
virtual void reset();
|
||||||
|
|
||||||
|
virtual std::string getErrors() const;
|
||||||
|
///< Return formatted error descriptions for the current state of the creator. if an empty
|
||||||
|
/// string is returned, there is no error.
|
||||||
|
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void textChanged (const QString& text);
|
||||||
|
|
||||||
|
void create();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
26
apps/opencs/view/world/idvalidator.cpp
Normal file
26
apps/opencs/view/world/idvalidator.cpp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
|
||||||
|
#include "idvalidator.hpp"
|
||||||
|
|
||||||
|
bool CSVWorld::IdValidator::isValid (const QChar& c, bool first) const
|
||||||
|
{
|
||||||
|
if (c.isLetter() || c=='_')
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!first && (c.isDigit() || c.isSpace()))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::IdValidator::IdValidator (QObject *parent) : QValidator (parent) {}
|
||||||
|
|
||||||
|
QValidator::State CSVWorld::IdValidator::validate (QString& input, int& pos) const
|
||||||
|
{
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
for (QString::const_iterator iter (input.begin()); iter!=input.end(); ++iter, first = false)
|
||||||
|
if (!isValid (*iter, first))
|
||||||
|
return QValidator::Invalid;
|
||||||
|
|
||||||
|
return QValidator::Acceptable;
|
||||||
|
}
|
23
apps/opencs/view/world/idvalidator.hpp
Normal file
23
apps/opencs/view/world/idvalidator.hpp
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef CSV_WORLD_IDVALIDATOR_H
|
||||||
|
#define CSV_WORLD_IDVALIDATOR_H
|
||||||
|
|
||||||
|
#include <QValidator>
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class IdValidator : public QValidator
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool isValid (const QChar& c, bool first) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
IdValidator (QObject *parent = 0);
|
||||||
|
|
||||||
|
virtual State validate (QString& input, int& pos) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
43
apps/opencs/view/world/referenceablecreator.cpp
Normal file
43
apps/opencs/view/world/referenceablecreator.cpp
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
|
||||||
|
#include "referenceablecreator.hpp"
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
#include "../../model/world/universalid.hpp"
|
||||||
|
#include "../../model/world/commands.hpp"
|
||||||
|
|
||||||
|
void CSVWorld::ReferenceableCreator::configureCreateCommand (CSMWorld::CreateCommand& command) const
|
||||||
|
{
|
||||||
|
command.setType (
|
||||||
|
static_cast<CSMWorld::UniversalId::Type> (mType->itemData (mType->currentIndex()).toInt()));
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::ReferenceableCreator::ReferenceableCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||||
|
const CSMWorld::UniversalId& id)
|
||||||
|
: GenericCreator (data, undoStack, id)
|
||||||
|
{
|
||||||
|
QLabel *label = new QLabel ("Type", this);
|
||||||
|
insertBeforeButtons (label, false);
|
||||||
|
|
||||||
|
std::vector<CSMWorld::UniversalId::Type> types = CSMWorld::UniversalId::listReferenceableTypes();
|
||||||
|
|
||||||
|
mType = new QComboBox (this);
|
||||||
|
|
||||||
|
for (std::vector<CSMWorld::UniversalId::Type>::const_iterator iter (types.begin());
|
||||||
|
iter!=types.end(); ++iter)
|
||||||
|
{
|
||||||
|
CSMWorld::UniversalId id (*iter, "");
|
||||||
|
|
||||||
|
mType->addItem (QIcon (id.getIcon().c_str()), id.getTypeName().c_str(),
|
||||||
|
static_cast<int> (id.getType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
insertBeforeButtons (mType, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::ReferenceableCreator::reset()
|
||||||
|
{
|
||||||
|
mType->setCurrentIndex (0);
|
||||||
|
GenericCreator::reset();
|
||||||
|
}
|
30
apps/opencs/view/world/referenceablecreator.hpp
Normal file
30
apps/opencs/view/world/referenceablecreator.hpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef CSV_WORLD_REFERENCEABLECREATOR_H
|
||||||
|
#define CSV_WORLD_REFERENCEABLECREATOR_H
|
||||||
|
|
||||||
|
class QComboBox;
|
||||||
|
|
||||||
|
#include "genericcreator.hpp"
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class ReferenceableCreator : public GenericCreator
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
QComboBox *mType;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
virtual void configureCreateCommand (CSMWorld::CreateCommand& command) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ReferenceableCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||||
|
const CSMWorld::UniversalId& id);
|
||||||
|
|
||||||
|
virtual void reset();
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
70
apps/opencs/view/world/referencecreator.cpp
Normal file
70
apps/opencs/view/world/referencecreator.cpp
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
|
||||||
|
#include "referencecreator.hpp"
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLineEdit>
|
||||||
|
|
||||||
|
#include "../../model/world/data.hpp"
|
||||||
|
#include "../../model/world/commands.hpp"
|
||||||
|
|
||||||
|
std::string CSVWorld::ReferenceCreator::getId() const
|
||||||
|
{
|
||||||
|
return mId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::ReferenceCreator::configureCreateCommand (CSMWorld::CreateCommand& command) const
|
||||||
|
{
|
||||||
|
/// \todo avoid using hard-coded column numbers
|
||||||
|
command.addValue (2, mCell->text());
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::ReferenceCreator::ReferenceCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||||
|
const CSMWorld::UniversalId& id)
|
||||||
|
: GenericCreator (data, undoStack, id)
|
||||||
|
{
|
||||||
|
QLabel *label = new QLabel ("Cell", this);
|
||||||
|
insertBeforeButtons (label, false);
|
||||||
|
|
||||||
|
mCell = new QLineEdit (this);
|
||||||
|
insertBeforeButtons (mCell, true);
|
||||||
|
|
||||||
|
setManualEditing (false);
|
||||||
|
|
||||||
|
connect (mCell, SIGNAL (textChanged (const QString&)), this, SLOT (cellChanged()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::ReferenceCreator::reset()
|
||||||
|
{
|
||||||
|
mCell->setText ("");
|
||||||
|
mId = getData().getReferences().getNewId();
|
||||||
|
GenericCreator::reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CSVWorld::ReferenceCreator::getErrors() const
|
||||||
|
{
|
||||||
|
std::string errors = GenericCreator::getErrors();
|
||||||
|
|
||||||
|
std::string cell = mCell->text().toUtf8().constData();
|
||||||
|
|
||||||
|
if (cell.empty())
|
||||||
|
{
|
||||||
|
if (!errors.empty())
|
||||||
|
errors += "<br>";
|
||||||
|
|
||||||
|
errors += "Missing Cell ID";
|
||||||
|
}
|
||||||
|
else if (getData().getCells().searchId (cell)==-1)
|
||||||
|
{
|
||||||
|
if (!errors.empty())
|
||||||
|
errors += "<br>";
|
||||||
|
|
||||||
|
errors += "Invalid Cell ID";
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::ReferenceCreator::cellChanged()
|
||||||
|
{
|
||||||
|
update();
|
||||||
|
}
|
40
apps/opencs/view/world/referencecreator.hpp
Normal file
40
apps/opencs/view/world/referencecreator.hpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef CSV_WORLD_REFERENCECREATOR_H
|
||||||
|
#define CSV_WORLD_REFERENCECREATOR_H
|
||||||
|
|
||||||
|
#include "genericcreator.hpp"
|
||||||
|
|
||||||
|
class QLineEdit;
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class ReferenceCreator : public GenericCreator
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
QLineEdit *mCell;
|
||||||
|
std::string mId;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
virtual std::string getId() const;
|
||||||
|
|
||||||
|
virtual void configureCreateCommand (CSMWorld::CreateCommand& command) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ReferenceCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||||
|
const CSMWorld::UniversalId& id);
|
||||||
|
|
||||||
|
virtual void reset();
|
||||||
|
|
||||||
|
virtual std::string getErrors() const;
|
||||||
|
///< Return formatted error descriptions for the current state of the creator. if an empty
|
||||||
|
/// string is returned, there is no error.
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void cellChanged();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -27,26 +27,15 @@ CSVWorld::RefIdTypeDelegateFactory::UidTypeList CSVWorld::RefIdTypeDelegateFacto
|
||||||
{
|
{
|
||||||
UidTypeList list;
|
UidTypeList list;
|
||||||
|
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_Activator, ":./activator.png"));
|
std::vector<CSMWorld::UniversalId::Type> types = CSMWorld::UniversalId::listReferenceableTypes();
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_Potion, ":./potion.png"));
|
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_Apparatus, ":./apparatus.png"));
|
for (std::vector<CSMWorld::UniversalId::Type>::const_iterator iter (types.begin());
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_Armor, ":./armor.png"));
|
iter!=types.end(); ++iter)
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_Book, ":./book.png"));
|
{
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_Clothing, ":./clothing.png"));
|
CSMWorld::UniversalId id (*iter, "");
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_Container, ":./container.png"));
|
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_Creature, ":./creature.png"));
|
list.push_back (std::make_pair (id.getType(), id.getIcon().c_str()));
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_Door, ":./door.png"));
|
}
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_Ingredient, ":./ingredient.png"));
|
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_CreatureLevelledList, ":./creature.png"));
|
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_ItemLevelledList, ":./item.png"));
|
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_Light, ":./light.png"));
|
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_Lockpick, ":./lockpick.png"));
|
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_Miscellaneous, ":./misc.png"));
|
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_Npc, ":./npc.png"));
|
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_Probe, ":./probe.png"));
|
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_Repair, ":./repair.png"));
|
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_Static, ":./static.png"));
|
|
||||||
list.push_back (std::make_pair (CSMWorld::UniversalId::Type_Weapon, ":./weapon.png"));
|
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,14 +7,20 @@
|
||||||
#include "dialoguesubview.hpp"
|
#include "dialoguesubview.hpp"
|
||||||
#include "scriptsubview.hpp"
|
#include "scriptsubview.hpp"
|
||||||
#include "regionmapsubview.hpp"
|
#include "regionmapsubview.hpp"
|
||||||
|
#include "genericcreator.hpp"
|
||||||
|
#include "cellcreator.hpp"
|
||||||
|
#include "referenceablecreator.hpp"
|
||||||
|
#include "referencecreator.hpp"
|
||||||
|
|
||||||
void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
||||||
{
|
{
|
||||||
|
// Regular record tables (including references which are actually sub-records, but are promoted
|
||||||
|
// to top-level records within the editor)
|
||||||
manager.add (CSMWorld::UniversalId::Type_Gmsts,
|
manager.add (CSMWorld::UniversalId::Type_Gmsts,
|
||||||
new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (false));
|
new CSVDoc::SubViewFactoryWithCreator<TableSubView, NullCreatorFactory>);
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Skills,
|
manager.add (CSMWorld::UniversalId::Type_Skills,
|
||||||
new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (false));
|
new CSVDoc::SubViewFactoryWithCreator<TableSubView, NullCreatorFactory>);
|
||||||
|
|
||||||
static const CSMWorld::UniversalId::Type sTableTypes[] =
|
static const CSMWorld::UniversalId::Type sTableTypes[] =
|
||||||
{
|
{
|
||||||
|
@ -27,20 +33,26 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
||||||
CSMWorld::UniversalId::Type_Regions,
|
CSMWorld::UniversalId::Type_Regions,
|
||||||
CSMWorld::UniversalId::Type_Birthsigns,
|
CSMWorld::UniversalId::Type_Birthsigns,
|
||||||
CSMWorld::UniversalId::Type_Spells,
|
CSMWorld::UniversalId::Type_Spells,
|
||||||
CSMWorld::UniversalId::Type_Cells,
|
|
||||||
CSMWorld::UniversalId::Type_Referenceables,
|
|
||||||
CSMWorld::UniversalId::Type_References,
|
|
||||||
|
|
||||||
CSMWorld::UniversalId::Type_None // end marker
|
CSMWorld::UniversalId::Type_None // end marker
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i=0; sTableTypes[i]!=CSMWorld::UniversalId::Type_None; ++i)
|
for (int i=0; sTableTypes[i]!=CSMWorld::UniversalId::Type_None; ++i)
|
||||||
manager.add (sTableTypes[i], new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (true));
|
manager.add (sTableTypes[i],
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<GenericCreator> >);
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Cells,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<CellCreator> >);
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Referenceables,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<ReferenceableCreator> >);
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_References,
|
||||||
|
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<ReferenceCreator> >);
|
||||||
|
|
||||||
|
// Subviews for editing/viewing individual records
|
||||||
manager.add (CSMWorld::UniversalId::Type_Script, new CSVDoc::SubViewFactory<ScriptSubView>);
|
manager.add (CSMWorld::UniversalId::Type_Script, new CSVDoc::SubViewFactory<ScriptSubView>);
|
||||||
|
|
||||||
|
// Other stuff (combined record tables)
|
||||||
manager.add (CSMWorld::UniversalId::Type_RegionMap, new CSVDoc::SubViewFactory<RegionMapSubView>);
|
manager.add (CSMWorld::UniversalId::Type_RegionMap, new CSVDoc::SubViewFactory<RegionMapSubView>);
|
||||||
|
|
||||||
// manager.add (CSMWorld::UniversalId::Type_Global,
|
|
||||||
// new CSVDoc::SubViewFactoryWithCreateFlag<DialogueSubView> (true));
|
|
||||||
}
|
}
|
|
@ -44,19 +44,30 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
||||||
|
|
||||||
std::vector<std::string> CSVWorld::Table::listRevertableSelectedIds() const
|
std::vector<std::string> CSVWorld::Table::listRevertableSelectedIds() const
|
||||||
{
|
{
|
||||||
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
/// \todo Do not use hardcoded column numbers
|
||||||
|
|
||||||
std::vector<std::string> revertableIds;
|
std::vector<std::string> revertableIds;
|
||||||
|
|
||||||
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end(); ++iter)
|
if (mProxyModel->columnCount()>0)
|
||||||
{
|
{
|
||||||
std::string id = mProxyModel->data (*iter).toString().toStdString();
|
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||||
|
|
||||||
CSMWorld::RecordBase::State state =
|
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end();
|
||||||
static_cast<CSMWorld::RecordBase::State> (mModel->data (mModel->getModelIndex (id, 1)).toInt());
|
++iter)
|
||||||
|
{
|
||||||
|
QModelIndex index = mProxyModel->mapToSource (mProxyModel->index (iter->row(), 0));
|
||||||
|
|
||||||
if (state!=CSMWorld::RecordBase::State_BaseOnly)
|
CSMWorld::RecordBase::State state =
|
||||||
revertableIds.push_back (id);
|
static_cast<CSMWorld::RecordBase::State> (
|
||||||
|
mModel->data (mModel->index (index.row(), 1)).toInt());
|
||||||
|
|
||||||
|
if (state!=CSMWorld::RecordBase::State_BaseOnly)
|
||||||
|
{
|
||||||
|
std::string id = mModel->data (mModel->index (index.row(), 0)).
|
||||||
|
toString().toUtf8().constData();
|
||||||
|
|
||||||
|
revertableIds.push_back (id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return revertableIds;
|
return revertableIds;
|
||||||
|
@ -64,19 +75,30 @@ std::vector<std::string> CSVWorld::Table::listRevertableSelectedIds() const
|
||||||
|
|
||||||
std::vector<std::string> CSVWorld::Table::listDeletableSelectedIds() const
|
std::vector<std::string> CSVWorld::Table::listDeletableSelectedIds() const
|
||||||
{
|
{
|
||||||
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
/// \todo Do not use hardcoded column numbers
|
||||||
|
|
||||||
std::vector<std::string> deletableIds;
|
std::vector<std::string> deletableIds;
|
||||||
|
|
||||||
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end(); ++iter)
|
if (mProxyModel->columnCount()>0)
|
||||||
{
|
{
|
||||||
std::string id = mProxyModel->data (*iter).toString().toStdString();
|
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||||
|
|
||||||
CSMWorld::RecordBase::State state =
|
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end();
|
||||||
static_cast<CSMWorld::RecordBase::State> (mModel->data (mModel->getModelIndex (id, 1)).toInt());
|
++iter)
|
||||||
|
{
|
||||||
|
QModelIndex index = mProxyModel->mapToSource (mProxyModel->index (iter->row(), 0));
|
||||||
|
|
||||||
if (state!=CSMWorld::RecordBase::State_Deleted)
|
CSMWorld::RecordBase::State state =
|
||||||
deletableIds.push_back (id);
|
static_cast<CSMWorld::RecordBase::State> (
|
||||||
|
mModel->data (mModel->index (index.row(), 1)).toInt());
|
||||||
|
|
||||||
|
if (state!=CSMWorld::RecordBase::State_Deleted)
|
||||||
|
{
|
||||||
|
std::string id = mModel->data (mModel->index (index.row(), 0)).
|
||||||
|
toString().toUtf8().constData();
|
||||||
|
|
||||||
|
deletableIds.push_back (id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return deletableIds;
|
return deletableIds;
|
||||||
|
@ -126,7 +148,7 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, Q
|
||||||
if (createAndDelete)
|
if (createAndDelete)
|
||||||
{
|
{
|
||||||
mCreateAction = new QAction (tr ("Add Record"), this);
|
mCreateAction = new QAction (tr ("Add Record"), this);
|
||||||
connect (mCreateAction, SIGNAL (triggered()), this, SLOT (createRecord()));
|
connect (mCreateAction, SIGNAL (triggered()), this, SIGNAL (createRequest()));
|
||||||
addAction (mCreateAction);
|
addAction (mCreateAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +159,17 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, Q
|
||||||
mDeleteAction = new QAction (tr ("Delete Record"), this);
|
mDeleteAction = new QAction (tr ("Delete Record"), this);
|
||||||
connect (mDeleteAction, SIGNAL (triggered()), this, SLOT (deleteRecord()));
|
connect (mDeleteAction, SIGNAL (triggered()), this, SLOT (deleteRecord()));
|
||||||
addAction (mDeleteAction);
|
addAction (mDeleteAction);
|
||||||
|
|
||||||
|
connect (mProxyModel, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
||||||
|
this, SLOT (tableSizeUpdate()));
|
||||||
|
|
||||||
|
/// \note This signal could instead be connected to a slot that filters out changes not affecting
|
||||||
|
/// the records status column (for permanence reasons)
|
||||||
|
connect (mProxyModel, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||||
|
this, SLOT (tableSizeUpdate()));
|
||||||
|
|
||||||
|
connect (selectionModel(), SIGNAL (selectionChanged (const QItemSelection&, const QItemSelection&)),
|
||||||
|
this, SLOT (selectionSizeUpdate ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWorld::Table::setEditLock (bool locked)
|
void CSVWorld::Table::setEditLock (bool locked)
|
||||||
|
@ -154,22 +187,6 @@ CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const
|
||||||
mProxyModel->data (mProxyModel->index (row, 0)).toString().toStdString());
|
mProxyModel->data (mProxyModel->index (row, 0)).toString().toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <sstream> /// \todo remove
|
|
||||||
void CSVWorld::Table::createRecord()
|
|
||||||
{
|
|
||||||
if (!mEditLock)
|
|
||||||
{
|
|
||||||
/// \todo ask the user for an ID instead.
|
|
||||||
static int index = 0;
|
|
||||||
|
|
||||||
std::ostringstream stream;
|
|
||||||
stream << "id" << index++;
|
|
||||||
|
|
||||||
mUndoStack.push (new CSMWorld::CreateCommand (*mProxyModel, stream.str()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSVWorld::Table::revertRecord()
|
void CSVWorld::Table::revertRecord()
|
||||||
{
|
{
|
||||||
if (!mEditLock)
|
if (!mEditLock)
|
||||||
|
@ -231,3 +248,46 @@ void CSVWorld::Table::updateEditorSetting (const QString &settingName, const QSt
|
||||||
updateEditorSetting (settingName, settingValue))
|
updateEditorSetting (settingName, settingValue))
|
||||||
emit dataChanged (mModel->index (0, i), mModel->index (mModel->rowCount()-1, i));
|
emit dataChanged (mModel->index (0, i), mModel->index (mModel->rowCount()-1, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVWorld::Table::tableSizeUpdate()
|
||||||
|
{
|
||||||
|
int size = 0;
|
||||||
|
int deleted = 0;
|
||||||
|
int modified = 0;
|
||||||
|
|
||||||
|
if (mModel->columnCount()>0)
|
||||||
|
{
|
||||||
|
int rows = mModel->rowCount();
|
||||||
|
|
||||||
|
for (int i=0; i<rows; ++i)
|
||||||
|
{
|
||||||
|
QModelIndex index = mProxyModel->mapToSource (mProxyModel->index (i, 0));
|
||||||
|
|
||||||
|
/// \todo Do not use hardcoded column numbers
|
||||||
|
int state = mModel->data (mModel->index (index.row(), 1)).toInt();
|
||||||
|
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case CSMWorld::RecordBase::State_BaseOnly: ++size; break;
|
||||||
|
case CSMWorld::RecordBase::State_Modified: ++size; ++modified; break;
|
||||||
|
case CSMWorld::RecordBase::State_ModifiedOnly: ++size; ++modified; break;
|
||||||
|
case CSMWorld::RecordBase:: State_Deleted: ++deleted; ++modified; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tableSizeChanged (size, deleted, modified);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::Table::selectionSizeUpdate()
|
||||||
|
{
|
||||||
|
selectionSizeChanged (selectionModel()->selectedRows().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::Table::requestFocus (const std::string& id)
|
||||||
|
{
|
||||||
|
QModelIndex index = mProxyModel->getModelIndex (id, 0);
|
||||||
|
|
||||||
|
if (index.isValid())
|
||||||
|
scrollTo (index, QAbstractItemView::PositionAtTop);
|
||||||
|
}
|
|
@ -60,15 +60,31 @@ namespace CSVWorld
|
||||||
|
|
||||||
void editRequest (int row);
|
void editRequest (int row);
|
||||||
|
|
||||||
private slots:
|
void selectionSizeChanged (int size);
|
||||||
|
|
||||||
void createRecord();
|
void tableSizeChanged (int size, int deleted, int modified);
|
||||||
|
///< \param size Number of not deleted records
|
||||||
|
/// \param deleted Number of deleted records
|
||||||
|
/// \param modified Number of added and modified records
|
||||||
|
|
||||||
|
void createRequest();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
void revertRecord();
|
void revertRecord();
|
||||||
|
|
||||||
void deleteRecord();
|
void deleteRecord();
|
||||||
|
|
||||||
void editRecord();
|
void editRecord();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void tableSizeUpdate();
|
||||||
|
|
||||||
|
void selectionSizeUpdate();
|
||||||
|
|
||||||
|
void requestFocus (const std::string& id);
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
156
apps/opencs/view/world/tablebottombox.cpp
Normal file
156
apps/opencs/view/world/tablebottombox.cpp
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
|
||||||
|
#include "tablebottombox.hpp"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <QStatusBar>
|
||||||
|
#include <QStackedLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
#include "creator.hpp"
|
||||||
|
|
||||||
|
void CSVWorld::TableBottomBox::updateStatus()
|
||||||
|
{
|
||||||
|
if (mShowStatusBar)
|
||||||
|
{
|
||||||
|
static const char *sLabels[4] = { "record", "deleted", "touched", "selected" };
|
||||||
|
static const char *sLabelsPlural[4] = { "records", "deleted", "touched", "selected" };
|
||||||
|
|
||||||
|
std::ostringstream stream;
|
||||||
|
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
for (int i=0; i<4; ++i)
|
||||||
|
{
|
||||||
|
if (mStatusCount[i]>0)
|
||||||
|
{
|
||||||
|
if (first)
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
stream << ", ";
|
||||||
|
|
||||||
|
stream
|
||||||
|
<< mStatusCount[i] << ' '
|
||||||
|
<< (mStatusCount[i]==1 ? sLabels[i] : sLabelsPlural[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mStatus->setText (QString::fromUtf8 (stream.str().c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFactory,
|
||||||
|
CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, QWidget *parent)
|
||||||
|
: QWidget (parent), mShowStatusBar (false), mCreating (false)
|
||||||
|
{
|
||||||
|
for (int i=0; i<4; ++i)
|
||||||
|
mStatusCount[i] = 0;
|
||||||
|
|
||||||
|
setVisible (false);
|
||||||
|
|
||||||
|
mLayout = new QStackedLayout;
|
||||||
|
mLayout->setContentsMargins (0, 0, 0, 0);
|
||||||
|
|
||||||
|
mStatus = new QLabel;
|
||||||
|
|
||||||
|
mStatusBar = new QStatusBar;
|
||||||
|
|
||||||
|
mStatusBar->addWidget (mStatus);
|
||||||
|
|
||||||
|
mLayout->addWidget (mStatusBar);
|
||||||
|
|
||||||
|
setLayout (mLayout);
|
||||||
|
|
||||||
|
mCreator = creatorFactory.makeCreator (data, undoStack, id);
|
||||||
|
|
||||||
|
mLayout->addWidget (mCreator);
|
||||||
|
|
||||||
|
connect (mCreator, SIGNAL (done()), this, SLOT (createRequestDone()));
|
||||||
|
|
||||||
|
connect (mCreator, SIGNAL (requestFocus (const std::string&)),
|
||||||
|
this, SIGNAL (requestFocus (const std::string&)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::TableBottomBox::setEditLock (bool locked)
|
||||||
|
{
|
||||||
|
if (mCreator)
|
||||||
|
mCreator->setEditLock (locked);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::TableBottomBox::~TableBottomBox()
|
||||||
|
{
|
||||||
|
delete mCreator;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::TableBottomBox::setStatusBar (bool show)
|
||||||
|
{
|
||||||
|
if (show!=mShowStatusBar)
|
||||||
|
{
|
||||||
|
setVisible (show || mCreating);
|
||||||
|
|
||||||
|
mShowStatusBar = show;
|
||||||
|
|
||||||
|
if (show)
|
||||||
|
updateStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVWorld::TableBottomBox::canCreateAndDelete() const
|
||||||
|
{
|
||||||
|
return mCreator;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::TableBottomBox::createRequestDone()
|
||||||
|
{
|
||||||
|
if (!mShowStatusBar)
|
||||||
|
setVisible (false);
|
||||||
|
else
|
||||||
|
updateStatus();
|
||||||
|
|
||||||
|
mLayout->setCurrentWidget (mStatusBar);
|
||||||
|
|
||||||
|
mCreating = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::TableBottomBox::selectionSizeChanged (int size)
|
||||||
|
{
|
||||||
|
if (mStatusCount[3]!=size)
|
||||||
|
{
|
||||||
|
mStatusCount[3] = size;
|
||||||
|
updateStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::TableBottomBox::tableSizeChanged (int size, int deleted, int modified)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (mStatusCount[0]!=size)
|
||||||
|
{
|
||||||
|
mStatusCount[0] = size;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mStatusCount[1]!=deleted)
|
||||||
|
{
|
||||||
|
mStatusCount[1] = deleted;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mStatusCount[2]!=modified)
|
||||||
|
{
|
||||||
|
mStatusCount[2] = modified;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
updateStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::TableBottomBox::createRequest()
|
||||||
|
{
|
||||||
|
mCreator->reset();
|
||||||
|
mLayout->setCurrentWidget (mCreator);
|
||||||
|
setVisible (true);
|
||||||
|
mCreating = true;
|
||||||
|
}
|
82
apps/opencs/view/world/tablebottombox.hpp
Normal file
82
apps/opencs/view/world/tablebottombox.hpp
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
#ifndef CSV_WORLD_BOTTOMBOX_H
|
||||||
|
#define CSV_WORLD_BOTTOMBOX_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class QLabel;
|
||||||
|
class QStackedLayout;
|
||||||
|
class QStatusBar;
|
||||||
|
class QUndoStack;
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class Data;
|
||||||
|
class UniversalId;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class CreatorFactoryBase;
|
||||||
|
class Creator;
|
||||||
|
|
||||||
|
class TableBottomBox : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
bool mShowStatusBar;
|
||||||
|
QLabel *mStatus;
|
||||||
|
QStatusBar *mStatusBar;
|
||||||
|
int mStatusCount[4];
|
||||||
|
Creator *mCreator;
|
||||||
|
bool mCreating;
|
||||||
|
QStackedLayout *mLayout;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// not implemented
|
||||||
|
TableBottomBox (const TableBottomBox&);
|
||||||
|
TableBottomBox& operator= (const TableBottomBox&);
|
||||||
|
|
||||||
|
void updateStatus();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TableBottomBox (const CreatorFactoryBase& creatorFactory, CSMWorld::Data& data,
|
||||||
|
QUndoStack& undoStack, const CSMWorld::UniversalId& id, QWidget *parent = 0);
|
||||||
|
|
||||||
|
virtual ~TableBottomBox();
|
||||||
|
|
||||||
|
void setEditLock (bool locked);
|
||||||
|
|
||||||
|
void setStatusBar (bool show);
|
||||||
|
|
||||||
|
bool canCreateAndDelete() const;
|
||||||
|
///< Is record creation and deletion supported?
|
||||||
|
///
|
||||||
|
/// \note The BotomBox does not partake in the deletion of records.
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void requestFocus (const std::string& id);
|
||||||
|
///< Request owner of this box to focus the just created \a id. The owner may
|
||||||
|
/// ignore this request.
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void createRequestDone();
|
||||||
|
///< \note This slot being called does not imply success.
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void selectionSizeChanged (int size);
|
||||||
|
|
||||||
|
void tableSizeChanged (int size, int deleted, int modified);
|
||||||
|
///< \param size Number of not deleted records
|
||||||
|
/// \param deleted Number of deleted records
|
||||||
|
/// \param modified Number of added and modified records
|
||||||
|
|
||||||
|
void createRequest();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,22 +1,55 @@
|
||||||
|
|
||||||
#include "tablesubview.hpp"
|
#include "tablesubview.hpp"
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
#include "../../model/doc/document.hpp"
|
#include "../../model/doc/document.hpp"
|
||||||
|
|
||||||
#include "table.hpp"
|
#include "table.hpp"
|
||||||
|
#include "tablebottombox.hpp"
|
||||||
|
#include "creator.hpp"
|
||||||
|
|
||||||
CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
|
CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
|
||||||
bool createAndDelete)
|
const CreatorFactoryBase& creatorFactory)
|
||||||
: SubView (id)
|
: SubView (id)
|
||||||
{
|
{
|
||||||
setWidget (mTable = new Table (id, document.getData(), document.getUndoStack(), createAndDelete));
|
QVBoxLayout *layout = new QVBoxLayout;
|
||||||
|
|
||||||
|
layout->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||||
|
|
||||||
|
layout->addWidget (mBottom =
|
||||||
|
new TableBottomBox (creatorFactory, document.getData(), document.getUndoStack(), id, this), 0);
|
||||||
|
|
||||||
|
layout->insertWidget (0, mTable =
|
||||||
|
new Table (id, document.getData(), document.getUndoStack(), mBottom->canCreateAndDelete()), 2);
|
||||||
|
|
||||||
|
QWidget *widget = new QWidget;
|
||||||
|
|
||||||
|
widget->setLayout (layout);
|
||||||
|
|
||||||
|
setWidget (widget);
|
||||||
|
|
||||||
connect (mTable, SIGNAL (editRequest (int)), this, SLOT (editRequest (int)));
|
connect (mTable, SIGNAL (editRequest (int)), this, SLOT (editRequest (int)));
|
||||||
|
|
||||||
|
connect (mTable, SIGNAL (selectionSizeChanged (int)),
|
||||||
|
mBottom, SLOT (selectionSizeChanged (int)));
|
||||||
|
connect (mTable, SIGNAL (tableSizeChanged (int, int, int)),
|
||||||
|
mBottom, SLOT (tableSizeChanged (int, int, int)));
|
||||||
|
|
||||||
|
mTable->tableSizeUpdate();
|
||||||
|
mTable->selectionSizeUpdate();
|
||||||
|
|
||||||
|
if (mBottom->canCreateAndDelete())
|
||||||
|
connect (mTable, SIGNAL (createRequest()), mBottom, SLOT (createRequest()));
|
||||||
|
|
||||||
|
connect (mBottom, SIGNAL (requestFocus (const std::string&)),
|
||||||
|
mTable, SLOT (requestFocus (const std::string&)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWorld::TableSubView::setEditLock (bool locked)
|
void CSVWorld::TableSubView::setEditLock (bool locked)
|
||||||
{
|
{
|
||||||
mTable->setEditLock (locked);
|
mTable->setEditLock (locked);
|
||||||
|
mBottom->setEditLock (locked);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWorld::TableSubView::editRequest (int row)
|
void CSVWorld::TableSubView::editRequest (int row)
|
||||||
|
@ -28,3 +61,8 @@ void CSVWorld::TableSubView::updateEditorSetting(const QString &settingName, con
|
||||||
{
|
{
|
||||||
mTable->updateEditorSetting(settingName, settingValue);
|
mTable->updateEditorSetting(settingName, settingValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVWorld::TableSubView::setStatusBar (bool show)
|
||||||
|
{
|
||||||
|
mBottom->setStatusBar (show);
|
||||||
|
}
|
|
@ -13,18 +13,26 @@ namespace CSMDoc
|
||||||
namespace CSVWorld
|
namespace CSVWorld
|
||||||
{
|
{
|
||||||
class Table;
|
class Table;
|
||||||
|
class TableBottomBox;
|
||||||
|
class CreatorFactoryBase;
|
||||||
|
|
||||||
class TableSubView : public CSVDoc::SubView
|
class TableSubView : public CSVDoc::SubView
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Table *mTable;
|
Table *mTable;
|
||||||
|
TableBottomBox *mBottom;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete);
|
TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
|
||||||
|
const CreatorFactoryBase& creatorFactory);
|
||||||
|
|
||||||
virtual void setEditLock (bool locked);
|
virtual void setEditLock (bool locked);
|
||||||
void updateEditorSetting (const QString &, const QString &);
|
|
||||||
|
virtual void updateEditorSetting (const QString& key, const QString& value);
|
||||||
|
|
||||||
|
virtual void setStatusBar (bool show);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue