merge upstream changes

actorid
cc9cii 11 years ago
parent d780364842
commit 1ab5948f19

@ -1,127 +1,127 @@
#ifndef CSM_WOLRD_COLUMNBASE_H #ifndef CSM_WOLRD_COLUMNBASE_H
#define CSM_WOLRD_COLUMNBASE_H #define CSM_WOLRD_COLUMNBASE_H
#include <string> #include <string>
#include <Qt> #include <Qt>
#include <QVariant> #include <QVariant>
#include "record.hpp" #include "record.hpp"
namespace CSMWorld namespace CSMWorld
{ {
struct ColumnBase struct ColumnBase
{ {
enum Roles enum Roles
{ {
Role_Flags = Qt::UserRole, Role_Flags = Qt::UserRole,
Role_Display = Qt::UserRole+1 Role_Display = Qt::UserRole+1
}; };
enum Flags enum Flags
{ {
Flag_Table = 1, // column should be displayed in table view Flag_Table = 1, // column should be displayed in table view
Flag_Dialogue = 2 // column should be displayed in dialogue view Flag_Dialogue = 2 // column should be displayed in dialogue view
}; };
enum Display enum Display
{ {
Display_None, //Do not use Display_None, //Do not use
Display_String, Display_String,
//CONCRETE TYPES STARTS HERE //CONCRETE TYPES STARTS HERE
Display_Skill, Display_Skill,
Display_Class, Display_Class,
Display_Faction, Display_Faction,
Display_Race, Display_Race,
Display_Sound, Display_Sound,
Display_Region, Display_Region,
Display_Birthsign, Display_Birthsign,
Display_Spell, Display_Spell,
Display_Cell, Display_Cell,
Display_Referenceable, Display_Referenceable,
Display_Activator, Display_Activator,
Display_Potion, Display_Potion,
Display_Apparatus, Display_Apparatus,
Display_Armor, Display_Armor,
Display_Book, Display_Book,
Display_Clothing, Display_Clothing,
Display_Container, Display_Container,
Display_Creature, Display_Creature,
Display_Door, Display_Door,
Display_Ingredient, Display_Ingredient,
Display_CreatureLevelledList, Display_CreatureLevelledList,
Display_ItemLevelledList, Display_ItemLevelledList,
Display_Light, Display_Light,
Display_Lockpick, Display_Lockpick,
Display_Miscellaneous, Display_Miscellaneous,
Display_Npc, Display_Npc,
Display_Probe, Display_Probe,
Display_Repair, Display_Repair,
Display_Static, Display_Static,
Display_Weapon, Display_Weapon,
Display_Reference, Display_Reference,
Display_Filter, Display_Filter,
Display_Topic, Display_Topic,
Display_Journal, Display_Journal,
Display_TopicInfo, Display_TopicInfo,
Display_JournalInfo, Display_JournalInfo,
Display_Scene, Display_Scene,
//CONCRETE TYPES ENDS HERE //CONCRETE TYPES ENDS HERE
Display_Integer, Display_Integer,
Display_Float, Display_Float,
Display_Var, Display_Var,
Display_GmstVarType, Display_GmstVarType,
Display_GlobalVarType, Display_GlobalVarType,
Display_Specialisation, Display_Specialisation,
Display_Attribute, Display_Attribute,
Display_Boolean, Display_Boolean,
Display_SpellType, Display_SpellType,
Display_Script, Display_Script,
Display_ApparatusType, Display_ApparatusType,
Display_ArmorType, Display_ArmorType,
Display_ClothingType, Display_ClothingType,
Display_CreatureType, Display_CreatureType,
Display_WeaponType, Display_WeaponType,
Display_RecordState, Display_RecordState,
Display_RefRecordType, Display_RefRecordType,
Display_DialogueType, Display_DialogueType,
Display_QuestStatusType, Display_QuestStatusType,
Display_Gender Display_Gender
}; };
int mColumnId; int mColumnId;
int mFlags; int mFlags;
Display mDisplayType; Display mDisplayType;
ColumnBase (int columnId, Display displayType, int flag); ColumnBase (int columnId, Display displayType, int flag);
virtual ~ColumnBase(); virtual ~ColumnBase();
virtual bool isEditable() const = 0; virtual bool isEditable() const = 0;
virtual bool isUserEditable() const; virtual bool isUserEditable() const;
///< Can this column be edited directly by the user? ///< Can this column be edited directly by the user?
virtual std::string getTitle() const; virtual std::string getTitle() const;
}; };
template<typename ESXRecordT> template<typename ESXRecordT>
struct Column : public ColumnBase struct Column : public ColumnBase
{ {
int mFlags; int mFlags;
Column (int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue) Column (int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue)
: ColumnBase (columnId, displayType, flags) {} : ColumnBase (columnId, displayType, flags) {}
virtual QVariant get (const Record<ESXRecordT>& record) const = 0; virtual QVariant get (const Record<ESXRecordT>& record) const = 0;
virtual void set (Record<ESXRecordT>& record, const QVariant& data) virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{ {
throw std::logic_error ("Column " + getTitle() + " is not editable"); throw std::logic_error ("Column " + getTitle() + " is not editable");
} }
}; };
} }
#endif #endif

@ -1,446 +1,446 @@
#include "tablemimedata.hpp" #include "tablemimedata.hpp"
#include <string> #include <string>
#include "universalid.hpp" #include "universalid.hpp"
#include "columnbase.hpp" #include "columnbase.hpp"
CSMWorld::TableMimeData::TableMimeData (UniversalId id, const CSMDoc::Document& document) : CSMWorld::TableMimeData::TableMimeData (UniversalId id, const CSMDoc::Document& document) :
mDocument(document) mDocument(document)
{ {
mUniversalId.push_back (id); mUniversalId.push_back (id);
mObjectsFormats << QString::fromStdString ("tabledata/" + id.getTypeName()); mObjectsFormats << QString::fromStdString ("tabledata/" + id.getTypeName());
} }
CSMWorld::TableMimeData::TableMimeData (std::vector< CSMWorld::UniversalId >& id, const CSMDoc::Document& document) : CSMWorld::TableMimeData::TableMimeData (std::vector< CSMWorld::UniversalId >& id, const CSMDoc::Document& document) :
mUniversalId (id), mDocument(document) mUniversalId (id), mDocument(document)
{ {
for (std::vector<UniversalId>::iterator it (mUniversalId.begin()); it != mUniversalId.end(); ++it) for (std::vector<UniversalId>::iterator it (mUniversalId.begin()); it != mUniversalId.end(); ++it)
{ {
mObjectsFormats << QString::fromStdString ("tabledata/" + it->getTypeName()); mObjectsFormats << QString::fromStdString ("tabledata/" + it->getTypeName());
} }
} }
QStringList CSMWorld::TableMimeData::formats() const QStringList CSMWorld::TableMimeData::formats() const
{ {
return mObjectsFormats; return mObjectsFormats;
} }
CSMWorld::TableMimeData::~TableMimeData() CSMWorld::TableMimeData::~TableMimeData()
{ {
} }
std::string CSMWorld::TableMimeData::getIcon() const std::string CSMWorld::TableMimeData::getIcon() const
{ {
if (mUniversalId.empty()) if (mUniversalId.empty())
{ {
throw ("TableMimeData holds no UniversalId"); throw ("TableMimeData holds no UniversalId");
} }
std::string tmpIcon; std::string tmpIcon;
bool firstIteration = true; bool firstIteration = true;
for (unsigned i = 0; i < mUniversalId.size(); ++i) for (unsigned i = 0; i < mUniversalId.size(); ++i)
{ {
if (firstIteration) if (firstIteration)
{ {
firstIteration = false; firstIteration = false;
tmpIcon = mUniversalId[i].getIcon(); tmpIcon = mUniversalId[i].getIcon();
continue; continue;
} }
if (tmpIcon != mUniversalId[i].getIcon()) if (tmpIcon != mUniversalId[i].getIcon())
{ {
return ":/multitype.png"; //icon stolen from gnome return ":/multitype.png"; //icon stolen from gnome
} }
tmpIcon = mUniversalId[i].getIcon(); tmpIcon = mUniversalId[i].getIcon();
} }
return mUniversalId.begin()->getIcon(); //All objects are of the same type; return mUniversalId.begin()->getIcon(); //All objects are of the same type;
} }
std::vector< CSMWorld::UniversalId > CSMWorld::TableMimeData::getData() const std::vector< CSMWorld::UniversalId > CSMWorld::TableMimeData::getData() const
{ {
return mUniversalId; return mUniversalId;
} }
bool CSMWorld::TableMimeData::holdsType (CSMWorld::UniversalId::Type type) const bool CSMWorld::TableMimeData::holdsType (CSMWorld::UniversalId::Type type) const
{ {
for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it) for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it)
{ {
if (it->getType() == type) if (it->getType() == type)
{ {
return true; return true;
} }
} }
return false; return false;
} }
bool CSMWorld::TableMimeData::holdsType (CSMWorld::ColumnBase::Display type) const bool CSMWorld::TableMimeData::holdsType (CSMWorld::ColumnBase::Display type) const
{ {
for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it) for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it)
{ {
if (it->getType() == convertEnums (type)) if (it->getType() == convertEnums (type))
{ {
return true; return true;
} }
} }
return false; return false;
} }
CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::UniversalId::Type type) const CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::UniversalId::Type type) const
{ {
for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it) for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it)
{ {
if (it->getType() == type) if (it->getType() == type)
{ {
return *it; return *it;
} }
} }
throw ("TableMimeData object does not hold object of the seeked type"); throw ("TableMimeData object does not hold object of the seeked type");
} }
CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::ColumnBase::Display type) const CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::ColumnBase::Display type) const
{ {
for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it) for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it)
{ {
if (it->getType() == convertEnums (type)) if (it->getType() == convertEnums (type))
{ {
return *it; return *it;
} }
} }
throw ("TableMimeData object does not hold object of the seeked type"); throw ("TableMimeData object does not hold object of the seeked type");
} }
bool CSMWorld::TableMimeData::fromDocument (const CSMDoc::Document& document) const bool CSMWorld::TableMimeData::fromDocument (const CSMDoc::Document& document) const
{ {
return &document == &mDocument; return &document == &mDocument;
} }
CSMWorld::UniversalId::Type CSMWorld::TableMimeData::convertEnums (CSMWorld::ColumnBase::Display type) CSMWorld::UniversalId::Type CSMWorld::TableMimeData::convertEnums (CSMWorld::ColumnBase::Display type)
{ {
switch (type) switch (type)
{ {
case CSMWorld::ColumnBase::Display_Race: case CSMWorld::ColumnBase::Display_Race:
return CSMWorld::UniversalId::Type_Race; return CSMWorld::UniversalId::Type_Race;
case CSMWorld::ColumnBase::Display_Skill: case CSMWorld::ColumnBase::Display_Skill:
return CSMWorld::UniversalId::Type_Skill; return CSMWorld::UniversalId::Type_Skill;
case CSMWorld::ColumnBase::Display_Class: case CSMWorld::ColumnBase::Display_Class:
return CSMWorld::UniversalId::Type_Class; return CSMWorld::UniversalId::Type_Class;
case CSMWorld::ColumnBase::Display_Faction: case CSMWorld::ColumnBase::Display_Faction:
return CSMWorld::UniversalId::Type_Faction; return CSMWorld::UniversalId::Type_Faction;
case CSMWorld::ColumnBase::Display_Sound: case CSMWorld::ColumnBase::Display_Sound:
return CSMWorld::UniversalId::Type_Sound; return CSMWorld::UniversalId::Type_Sound;
case CSMWorld::ColumnBase::Display_Region: case CSMWorld::ColumnBase::Display_Region:
return CSMWorld::UniversalId::Type_Region; return CSMWorld::UniversalId::Type_Region;
case CSMWorld::ColumnBase::Display_Birthsign: case CSMWorld::ColumnBase::Display_Birthsign:
return CSMWorld::UniversalId::Type_Birthsign; return CSMWorld::UniversalId::Type_Birthsign;
case CSMWorld::ColumnBase::Display_Spell: case CSMWorld::ColumnBase::Display_Spell:
return CSMWorld::UniversalId::Type_Spell; return CSMWorld::UniversalId::Type_Spell;
case CSMWorld::ColumnBase::Display_Cell: case CSMWorld::ColumnBase::Display_Cell:
return CSMWorld::UniversalId::Type_Cell; return CSMWorld::UniversalId::Type_Cell;
case CSMWorld::ColumnBase::Display_Referenceable: case CSMWorld::ColumnBase::Display_Referenceable:
return CSMWorld::UniversalId::Type_Referenceable; return CSMWorld::UniversalId::Type_Referenceable;
case CSMWorld::ColumnBase::Display_Activator: case CSMWorld::ColumnBase::Display_Activator:
return CSMWorld::UniversalId::Type_Activator; return CSMWorld::UniversalId::Type_Activator;
case CSMWorld::ColumnBase::Display_Potion: case CSMWorld::ColumnBase::Display_Potion:
return CSMWorld::UniversalId::Type_Potion; return CSMWorld::UniversalId::Type_Potion;
case CSMWorld::ColumnBase::Display_Apparatus: case CSMWorld::ColumnBase::Display_Apparatus:
return CSMWorld::UniversalId::Type_Apparatus; return CSMWorld::UniversalId::Type_Apparatus;
case CSMWorld::ColumnBase::Display_Armor: case CSMWorld::ColumnBase::Display_Armor:
return CSMWorld::UniversalId::Type_Armor; return CSMWorld::UniversalId::Type_Armor;
case CSMWorld::ColumnBase::Display_Book: case CSMWorld::ColumnBase::Display_Book:
return CSMWorld::UniversalId::Type_Book; return CSMWorld::UniversalId::Type_Book;
case CSMWorld::ColumnBase::Display_Clothing: case CSMWorld::ColumnBase::Display_Clothing:
return CSMWorld::UniversalId::Type_Clothing; return CSMWorld::UniversalId::Type_Clothing;
case CSMWorld::ColumnBase::Display_Container: case CSMWorld::ColumnBase::Display_Container:
return CSMWorld::UniversalId::Type_Container; return CSMWorld::UniversalId::Type_Container;
case CSMWorld::ColumnBase::Display_Creature: case CSMWorld::ColumnBase::Display_Creature:
return CSMWorld::UniversalId::Type_Creature; return CSMWorld::UniversalId::Type_Creature;
case CSMWorld::ColumnBase::Display_Door: case CSMWorld::ColumnBase::Display_Door:
return CSMWorld::UniversalId::Type_Door; return CSMWorld::UniversalId::Type_Door;
case CSMWorld::ColumnBase::Display_Ingredient: case CSMWorld::ColumnBase::Display_Ingredient:
return CSMWorld::UniversalId::Type_Ingredient; return CSMWorld::UniversalId::Type_Ingredient;
case CSMWorld::ColumnBase::Display_CreatureLevelledList: case CSMWorld::ColumnBase::Display_CreatureLevelledList:
return CSMWorld::UniversalId::Type_CreatureLevelledList; return CSMWorld::UniversalId::Type_CreatureLevelledList;
case CSMWorld::ColumnBase::Display_ItemLevelledList: case CSMWorld::ColumnBase::Display_ItemLevelledList:
return CSMWorld::UniversalId::Type_ItemLevelledList; return CSMWorld::UniversalId::Type_ItemLevelledList;
case CSMWorld::ColumnBase::Display_Light: case CSMWorld::ColumnBase::Display_Light:
return CSMWorld::UniversalId::Type_Light; return CSMWorld::UniversalId::Type_Light;
case CSMWorld::ColumnBase::Display_Lockpick: case CSMWorld::ColumnBase::Display_Lockpick:
return CSMWorld::UniversalId::Type_Lockpick; return CSMWorld::UniversalId::Type_Lockpick;
case CSMWorld::ColumnBase::Display_Miscellaneous: case CSMWorld::ColumnBase::Display_Miscellaneous:
return CSMWorld::UniversalId::Type_Miscellaneous; return CSMWorld::UniversalId::Type_Miscellaneous;
case CSMWorld::ColumnBase::Display_Npc: case CSMWorld::ColumnBase::Display_Npc:
return CSMWorld::UniversalId::Type_Npc; return CSMWorld::UniversalId::Type_Npc;
case CSMWorld::ColumnBase::Display_Probe: case CSMWorld::ColumnBase::Display_Probe:
return CSMWorld::UniversalId::Type_Probe; return CSMWorld::UniversalId::Type_Probe;
case CSMWorld::ColumnBase::Display_Repair: case CSMWorld::ColumnBase::Display_Repair:
return CSMWorld::UniversalId::Type_Repair; return CSMWorld::UniversalId::Type_Repair;
case CSMWorld::ColumnBase::Display_Static: case CSMWorld::ColumnBase::Display_Static:
return CSMWorld::UniversalId::Type_Static; return CSMWorld::UniversalId::Type_Static;
case CSMWorld::ColumnBase::Display_Weapon: case CSMWorld::ColumnBase::Display_Weapon:
return CSMWorld::UniversalId::Type_Weapon; return CSMWorld::UniversalId::Type_Weapon;
case CSMWorld::ColumnBase::Display_Reference: case CSMWorld::ColumnBase::Display_Reference:
return CSMWorld::UniversalId::Type_Reference; return CSMWorld::UniversalId::Type_Reference;
case CSMWorld::ColumnBase::Display_Filter: case CSMWorld::ColumnBase::Display_Filter:
return CSMWorld::UniversalId::Type_Filter; return CSMWorld::UniversalId::Type_Filter;
case CSMWorld::ColumnBase::Display_Topic: case CSMWorld::ColumnBase::Display_Topic:
return CSMWorld::UniversalId::Type_Topic; return CSMWorld::UniversalId::Type_Topic;
case CSMWorld::ColumnBase::Display_Journal: case CSMWorld::ColumnBase::Display_Journal:
return CSMWorld::UniversalId::Type_Journal; return CSMWorld::UniversalId::Type_Journal;
case CSMWorld::ColumnBase::Display_TopicInfo: case CSMWorld::ColumnBase::Display_TopicInfo:
return CSMWorld::UniversalId::Type_TopicInfo; return CSMWorld::UniversalId::Type_TopicInfo;
case CSMWorld::ColumnBase::Display_JournalInfo: case CSMWorld::ColumnBase::Display_JournalInfo:
return CSMWorld::UniversalId::Type_JournalInfo; return CSMWorld::UniversalId::Type_JournalInfo;
case CSMWorld::ColumnBase::Display_Scene: case CSMWorld::ColumnBase::Display_Scene:
return CSMWorld::UniversalId::Type_Scene; return CSMWorld::UniversalId::Type_Scene;
case CSMWorld::ColumnBase::Display_Script: case CSMWorld::ColumnBase::Display_Script:
return CSMWorld::UniversalId::Type_Script; return CSMWorld::UniversalId::Type_Script;
default: default:
return CSMWorld::UniversalId::Type_None; return CSMWorld::UniversalId::Type_None;
} }
} }
CSMWorld::ColumnBase::Display CSMWorld::TableMimeData::convertEnums (CSMWorld::UniversalId::Type type) CSMWorld::ColumnBase::Display CSMWorld::TableMimeData::convertEnums (CSMWorld::UniversalId::Type type)
{ {
switch (type) switch (type)
{ {
case CSMWorld::UniversalId::Type_Race: case CSMWorld::UniversalId::Type_Race:
return CSMWorld::ColumnBase::Display_Race; return CSMWorld::ColumnBase::Display_Race;
case CSMWorld::UniversalId::Type_Skill: case CSMWorld::UniversalId::Type_Skill:
return CSMWorld::ColumnBase::Display_Skill; return CSMWorld::ColumnBase::Display_Skill;
case CSMWorld::UniversalId::Type_Class: case CSMWorld::UniversalId::Type_Class:
return CSMWorld::ColumnBase::Display_Class; return CSMWorld::ColumnBase::Display_Class;
case CSMWorld::UniversalId::Type_Faction: case CSMWorld::UniversalId::Type_Faction:
return CSMWorld::ColumnBase::Display_Faction; return CSMWorld::ColumnBase::Display_Faction;
case CSMWorld::UniversalId::Type_Sound: case CSMWorld::UniversalId::Type_Sound:
return CSMWorld::ColumnBase::Display_Sound; return CSMWorld::ColumnBase::Display_Sound;
case CSMWorld::UniversalId::Type_Region: case CSMWorld::UniversalId::Type_Region:
return CSMWorld::ColumnBase::Display_Region; return CSMWorld::ColumnBase::Display_Region;
case CSMWorld::UniversalId::Type_Birthsign: case CSMWorld::UniversalId::Type_Birthsign:
return CSMWorld::ColumnBase::Display_Birthsign; return CSMWorld::ColumnBase::Display_Birthsign;
case CSMWorld::UniversalId::Type_Spell: case CSMWorld::UniversalId::Type_Spell:
return CSMWorld::ColumnBase::Display_Spell; return CSMWorld::ColumnBase::Display_Spell;
case CSMWorld::UniversalId::Type_Cell: case CSMWorld::UniversalId::Type_Cell:
return CSMWorld::ColumnBase::Display_Cell; return CSMWorld::ColumnBase::Display_Cell;
case CSMWorld::UniversalId::Type_Referenceable: case CSMWorld::UniversalId::Type_Referenceable:
return CSMWorld::ColumnBase::Display_Referenceable; return CSMWorld::ColumnBase::Display_Referenceable;
case CSMWorld::UniversalId::Type_Activator: case CSMWorld::UniversalId::Type_Activator:
return CSMWorld::ColumnBase::Display_Activator; return CSMWorld::ColumnBase::Display_Activator;
case CSMWorld::UniversalId::Type_Potion: case CSMWorld::UniversalId::Type_Potion:
return CSMWorld::ColumnBase::Display_Potion; return CSMWorld::ColumnBase::Display_Potion;
case CSMWorld::UniversalId::Type_Apparatus: case CSMWorld::UniversalId::Type_Apparatus:
return CSMWorld::ColumnBase::Display_Apparatus; return CSMWorld::ColumnBase::Display_Apparatus;
case CSMWorld::UniversalId::Type_Armor: case CSMWorld::UniversalId::Type_Armor:
return CSMWorld::ColumnBase::Display_Armor; return CSMWorld::ColumnBase::Display_Armor;
case CSMWorld::UniversalId::Type_Book: case CSMWorld::UniversalId::Type_Book:
return CSMWorld::ColumnBase::Display_Book; return CSMWorld::ColumnBase::Display_Book;
case CSMWorld::UniversalId::Type_Clothing: case CSMWorld::UniversalId::Type_Clothing:
return CSMWorld::ColumnBase::Display_Clothing; return CSMWorld::ColumnBase::Display_Clothing;
case CSMWorld::UniversalId::Type_Container: case CSMWorld::UniversalId::Type_Container:
return CSMWorld::ColumnBase::Display_Container; return CSMWorld::ColumnBase::Display_Container;
case CSMWorld::UniversalId::Type_Creature: case CSMWorld::UniversalId::Type_Creature:
return CSMWorld::ColumnBase::Display_Creature; return CSMWorld::ColumnBase::Display_Creature;
case CSMWorld::UniversalId::Type_Door: case CSMWorld::UniversalId::Type_Door:
return CSMWorld::ColumnBase::Display_Door; return CSMWorld::ColumnBase::Display_Door;
case CSMWorld::UniversalId::Type_Ingredient: case CSMWorld::UniversalId::Type_Ingredient:
return CSMWorld::ColumnBase::Display_Ingredient; return CSMWorld::ColumnBase::Display_Ingredient;
case CSMWorld::UniversalId::Type_CreatureLevelledList: case CSMWorld::UniversalId::Type_CreatureLevelledList:
return CSMWorld::ColumnBase::Display_CreatureLevelledList; return CSMWorld::ColumnBase::Display_CreatureLevelledList;
case CSMWorld::UniversalId::Type_ItemLevelledList: case CSMWorld::UniversalId::Type_ItemLevelledList:
return CSMWorld::ColumnBase::Display_ItemLevelledList; return CSMWorld::ColumnBase::Display_ItemLevelledList;
case CSMWorld::UniversalId::Type_Light: case CSMWorld::UniversalId::Type_Light:
return CSMWorld::ColumnBase::Display_Light; return CSMWorld::ColumnBase::Display_Light;
case CSMWorld::UniversalId::Type_Lockpick: case CSMWorld::UniversalId::Type_Lockpick:
return CSMWorld::ColumnBase::Display_Lockpick; return CSMWorld::ColumnBase::Display_Lockpick;
case CSMWorld::UniversalId::Type_Miscellaneous: case CSMWorld::UniversalId::Type_Miscellaneous:
return CSMWorld::ColumnBase::Display_Miscellaneous; return CSMWorld::ColumnBase::Display_Miscellaneous;
case CSMWorld::UniversalId::Type_Npc: case CSMWorld::UniversalId::Type_Npc:
return CSMWorld::ColumnBase::Display_Npc; return CSMWorld::ColumnBase::Display_Npc;
case CSMWorld::UniversalId::Type_Probe: case CSMWorld::UniversalId::Type_Probe:
return CSMWorld::ColumnBase::Display_Probe; return CSMWorld::ColumnBase::Display_Probe;
case CSMWorld::UniversalId::Type_Repair: case CSMWorld::UniversalId::Type_Repair:
return CSMWorld::ColumnBase::Display_Repair; return CSMWorld::ColumnBase::Display_Repair;
case CSMWorld::UniversalId::Type_Static: case CSMWorld::UniversalId::Type_Static:
return CSMWorld::ColumnBase::Display_Static; return CSMWorld::ColumnBase::Display_Static;
case CSMWorld::UniversalId::Type_Weapon: case CSMWorld::UniversalId::Type_Weapon:
return CSMWorld::ColumnBase::Display_Weapon; return CSMWorld::ColumnBase::Display_Weapon;
case CSMWorld::UniversalId::Type_Reference: case CSMWorld::UniversalId::Type_Reference:
return CSMWorld::ColumnBase::Display_Reference; return CSMWorld::ColumnBase::Display_Reference;
case CSMWorld::UniversalId::Type_Filter: case CSMWorld::UniversalId::Type_Filter:
return CSMWorld::ColumnBase::Display_Filter; return CSMWorld::ColumnBase::Display_Filter;
case CSMWorld::UniversalId::Type_Topic: case CSMWorld::UniversalId::Type_Topic:
return CSMWorld::ColumnBase::Display_Topic; return CSMWorld::ColumnBase::Display_Topic;
case CSMWorld::UniversalId::Type_Journal: case CSMWorld::UniversalId::Type_Journal:
return CSMWorld::ColumnBase::Display_Journal; return CSMWorld::ColumnBase::Display_Journal;
case CSMWorld::UniversalId::Type_TopicInfo: case CSMWorld::UniversalId::Type_TopicInfo:
return CSMWorld::ColumnBase::Display_TopicInfo; return CSMWorld::ColumnBase::Display_TopicInfo;
case CSMWorld::UniversalId::Type_JournalInfo: case CSMWorld::UniversalId::Type_JournalInfo:
return CSMWorld::ColumnBase::Display_JournalInfo; return CSMWorld::ColumnBase::Display_JournalInfo;
case CSMWorld::UniversalId::Type_Scene: case CSMWorld::UniversalId::Type_Scene:
return CSMWorld::ColumnBase::Display_Scene; return CSMWorld::ColumnBase::Display_Scene;
case CSMWorld::UniversalId::Type_Script: case CSMWorld::UniversalId::Type_Script:
return CSMWorld::ColumnBase::Display_Script; return CSMWorld::ColumnBase::Display_Script;
default: default:
return CSMWorld::ColumnBase::Display_None; return CSMWorld::ColumnBase::Display_None;
} }
} }

@ -1,63 +1,63 @@
#ifndef TABLEMIMEDATA_H #ifndef TABLEMIMEDATA_H
#define TABLEMIMEDATA_H #define TABLEMIMEDATA_H
#include <vector> #include <vector>
#include <QtCore/QMimeData> #include <QtCore/QMimeData>
#include <QStringList> #include <QStringList>
#include "universalid.hpp" #include "universalid.hpp"
#include "columnbase.hpp" #include "columnbase.hpp"
namespace CSMDoc namespace CSMDoc
{ {
class Document; class Document;
} }
namespace CSMWorld namespace CSMWorld
{ {
/// \brief Subclass of QmimeData, augmented to contain and transport UniversalIds. /// \brief Subclass of QmimeData, augmented to contain and transport UniversalIds.
/// ///
/// This class provides way to construct mimedata object holding the universalid copy /// This class provides way to construct mimedata object holding the universalid copy
/// Universalid is used in the majority of the tables to store type, id, argument types. /// Universalid is used in the majority of the tables to store type, id, argument types.
/// This way universalid grants a way to retrive record from the concrete table. /// This way universalid grants a way to retrive record from the concrete table.
/// Please note, that tablemimedata object can hold multiple universalIds in the vector. /// Please note, that tablemimedata object can hold multiple universalIds in the vector.
class TableMimeData : public QMimeData class TableMimeData : public QMimeData
{ {
public: public:
TableMimeData(UniversalId id, const CSMDoc::Document& document); TableMimeData(UniversalId id, const CSMDoc::Document& document);
TableMimeData(std::vector<UniversalId>& id, const CSMDoc::Document& document); TableMimeData(std::vector<UniversalId>& id, const CSMDoc::Document& document);
~TableMimeData(); ~TableMimeData();
virtual QStringList formats() const; virtual QStringList formats() const;
std::string getIcon() const; std::string getIcon() const;
std::vector<UniversalId> getData() const; std::vector<UniversalId> getData() const;
bool holdsType(UniversalId::Type type) const; bool holdsType(UniversalId::Type type) const;
bool holdsType(CSMWorld::ColumnBase::Display type) const; bool holdsType(CSMWorld::ColumnBase::Display type) const;
bool fromDocument(const CSMDoc::Document& document) const; bool fromDocument(const CSMDoc::Document& document) const;
UniversalId returnMatching(UniversalId::Type type) const; UniversalId returnMatching(UniversalId::Type type) const;
UniversalId returnMatching(CSMWorld::ColumnBase::Display type) const; UniversalId returnMatching(CSMWorld::ColumnBase::Display type) const;
static CSMWorld::UniversalId::Type convertEnums(CSMWorld::ColumnBase::Display type); static CSMWorld::UniversalId::Type convertEnums(CSMWorld::ColumnBase::Display type);
static CSMWorld::ColumnBase::Display convertEnums(CSMWorld::UniversalId::Type type); static CSMWorld::ColumnBase::Display convertEnums(CSMWorld::UniversalId::Type type);
private: private:
std::vector<UniversalId> mUniversalId; std::vector<UniversalId> mUniversalId;
QStringList mObjectsFormats; QStringList mObjectsFormats;
const CSMDoc::Document& mDocument; const CSMDoc::Document& mDocument;
}; };
} }
#endif // TABLEMIMEDATA_H #endif // TABLEMIMEDATA_H

@ -1,203 +1,203 @@
#include "editwidget.hpp" #include "editwidget.hpp"
#include <QAbstractItemModel> #include <QAbstractItemModel>
#include <QString> #include <QString>
#include <QApplication> #include <QApplication>
#include "../../model/world/data.hpp" #include "../../model/world/data.hpp"
CSVFilter::EditWidget::EditWidget (CSMWorld::Data& data, QWidget *parent) CSVFilter::EditWidget::EditWidget (CSMWorld::Data& data, QWidget *parent)
: QLineEdit (parent), mParser (data) : QLineEdit (parent), mParser (data)
{ {
mPalette = palette(); mPalette = palette();
connect (this, SIGNAL (textChanged (const QString&)), this, SLOT (textChanged (const QString&))); connect (this, SIGNAL (textChanged (const QString&)), this, SLOT (textChanged (const QString&)));
QAbstractItemModel *model = data.getTableModel (CSMWorld::UniversalId::Type_Filters); QAbstractItemModel *model = data.getTableModel (CSMWorld::UniversalId::Type_Filters);
connect (model, SIGNAL (dataChanged (const QModelIndex &, const QModelIndex&)), connect (model, SIGNAL (dataChanged (const QModelIndex &, const QModelIndex&)),
this, SLOT (filterDataChanged (const QModelIndex &, const QModelIndex&)), this, SLOT (filterDataChanged (const QModelIndex &, const QModelIndex&)),
Qt::QueuedConnection); Qt::QueuedConnection);
connect (model, SIGNAL (rowsRemoved (const QModelIndex&, int, int)), connect (model, SIGNAL (rowsRemoved (const QModelIndex&, int, int)),
this, SLOT (filterRowsRemoved (const QModelIndex&, int, int)), this, SLOT (filterRowsRemoved (const QModelIndex&, int, int)),
Qt::QueuedConnection); Qt::QueuedConnection);
connect (model, SIGNAL (rowsInserted (const QModelIndex&, int, int)), connect (model, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
this, SLOT (filterRowsInserted (const QModelIndex&, int, int)), this, SLOT (filterRowsInserted (const QModelIndex&, int, int)),
Qt::QueuedConnection); Qt::QueuedConnection);
} }
void CSVFilter::EditWidget::textChanged (const QString& text) void CSVFilter::EditWidget::textChanged (const QString& text)
{ {
if (mParser.parse (text.toUtf8().constData())) if (mParser.parse (text.toUtf8().constData()))
{ {
setPalette (mPalette); setPalette (mPalette);
emit filterChanged (mParser.getFilter()); emit filterChanged (mParser.getFilter());
} }
else else
{ {
QPalette palette (mPalette); QPalette palette (mPalette);
palette.setColor (QPalette::Text, Qt::red); palette.setColor (QPalette::Text, Qt::red);
setPalette (palette); setPalette (palette);
/// \todo improve error reporting; mark only the faulty part /// \todo improve error reporting; mark only the faulty part
} }
} }
void CSVFilter::EditWidget::filterDataChanged (const QModelIndex& topLeft, void CSVFilter::EditWidget::filterDataChanged (const QModelIndex& topLeft,
const QModelIndex& bottomRight) const QModelIndex& bottomRight)
{ {
textChanged (text()); textChanged (text());
} }
void CSVFilter::EditWidget::filterRowsRemoved (const QModelIndex& parent, int start, int end) void CSVFilter::EditWidget::filterRowsRemoved (const QModelIndex& parent, int start, int end)
{ {
textChanged (text()); textChanged (text());
} }
void CSVFilter::EditWidget::filterRowsInserted (const QModelIndex& parent, int start, int end) void CSVFilter::EditWidget::filterRowsInserted (const QModelIndex& parent, int start, int end)
{ {
textChanged (text()); textChanged (text());
} }
void CSVFilter::EditWidget::createFilterRequest (std::vector< std::pair< std::string, std::vector< std::string > > >& filterSource, void CSVFilter::EditWidget::createFilterRequest (std::vector< std::pair< std::string, std::vector< std::string > > >& filterSource,
Qt::DropAction action) Qt::DropAction action)
{ {
const unsigned count = filterSource.size(); const unsigned count = filterSource.size();
bool multipleElements = false; bool multipleElements = false;
switch (count) //setting multipleElements; switch (count) //setting multipleElements;
{ {
case 0: //empty case 0: //empty
return; //nothing to do here return; //nothing to do here
case 1: //only single case 1: //only single
multipleElements = false; multipleElements = false;
break; break;
default: default:
multipleElements = true; multipleElements = true;
break; break;
} }
Qt::KeyboardModifiers key = QApplication::keyboardModifiers(); Qt::KeyboardModifiers key = QApplication::keyboardModifiers();
QString oldContent (text()); QString oldContent (text());
bool replaceMode = false; bool replaceMode = false;
std::string orAnd; std::string orAnd;
switch (key) //setting replaceMode and string used to glue expressions switch (key) //setting replaceMode and string used to glue expressions
{ {
case Qt::ShiftModifier: case Qt::ShiftModifier:
orAnd = "!or("; orAnd = "!or(";
replaceMode = false; replaceMode = false;
break; break;
case Qt::ControlModifier: case Qt::ControlModifier:
orAnd = "!and("; orAnd = "!and(";
replaceMode = false; replaceMode = false;
break; break;
default: default:
replaceMode = true; replaceMode = true;
break; break;
} }
if (oldContent.isEmpty() || !oldContent.contains (QRegExp ("^!.*$", Qt::CaseInsensitive))) //if line edit is empty or it does not contain one shot filter go into replace mode if (oldContent.isEmpty() || !oldContent.contains (QRegExp ("^!.*$", Qt::CaseInsensitive))) //if line edit is empty or it does not contain one shot filter go into replace mode
{ {
replaceMode = true; replaceMode = true;
} }
if (!replaceMode) if (!replaceMode)
{ {
oldContent.remove ('!'); oldContent.remove ('!');
} }
std::stringstream ss; std::stringstream ss;
if (multipleElements) if (multipleElements)
{ {
if (replaceMode) if (replaceMode)
{ {
ss<<"!or("; ss<<"!or(";
} else { } else {
ss << orAnd << oldContent.toStdString() << ','; ss << orAnd << oldContent.toStdString() << ',';
} }
for (unsigned i = 0; i < count; ++i) for (unsigned i = 0; i < count; ++i)
{ {
ss<<generateFilter (filterSource[i]); ss<<generateFilter (filterSource[i]);
if (i+1 != count) if (i+1 != count)
{ {
ss<<", "; ss<<", ";
} }
} }
ss<<')'; ss<<')';
} else { } else {
if (!replaceMode) if (!replaceMode)
{ {
ss << orAnd << oldContent.toStdString() <<','; ss << orAnd << oldContent.toStdString() <<',';
} else { } else {
ss<<'!'; ss<<'!';
} }
ss << generateFilter (filterSource[0]); ss << generateFilter (filterSource[0]);
if (!replaceMode) if (!replaceMode)
{ {
ss<<')'; ss<<')';
} }
} }
if (ss.str().length() >4) if (ss.str().length() >4)
{ {
clear(); clear();
insert (QString::fromUtf8(ss.str().c_str())); insert (QString::fromUtf8(ss.str().c_str()));
} }
} }
std::string CSVFilter::EditWidget::generateFilter (std::pair< std::string, std::vector< std::string > >& seekedString) const std::string CSVFilter::EditWidget::generateFilter (std::pair< std::string, std::vector< std::string > >& seekedString) const
{ {
const unsigned columns = seekedString.second.size(); const unsigned columns = seekedString.second.size();
bool multipleColumns = false; bool multipleColumns = false;
switch (columns) switch (columns)
{ {
case 0: //empty case 0: //empty
return ""; //no column to filter return ""; //no column to filter
case 1: //one column to look for case 1: //one column to look for
multipleColumns = false; multipleColumns = false;
break; break;
default: default:
multipleColumns = true; multipleColumns = true;
break; break;
} }
std::stringstream ss; std::stringstream ss;
if (multipleColumns) if (multipleColumns)
{ {
ss<<"or("; ss<<"or(";
for (unsigned i = 0; i < columns; ++i) for (unsigned i = 0; i < columns; ++i)
{ {
ss<<"string("<<'"'<<seekedString.second[i]<<'"'<<','<<'"'<<seekedString.first<<'"'<<')'; ss<<"string("<<'"'<<seekedString.second[i]<<'"'<<','<<'"'<<seekedString.first<<'"'<<')';
if (i+1 != columns) if (i+1 != columns)
ss<<','; ss<<',';
} }
ss<<')'; ss<<')';
} else { } else {
ss<<"string"<<'('<<'"'<<seekedString.second[0]<<"\","<<'"'<<seekedString.first<<"\")"; ss<<"string"<<'('<<'"'<<seekedString.second[0]<<"\","<<'"'<<seekedString.first<<"\")";
} }
return ss.str(); return ss.str();
} }
void CSVFilter::EditWidget::useFilterRequest (const std::string& idOfFilter) void CSVFilter::EditWidget::useFilterRequest (const std::string& idOfFilter)
{ {
clear(); clear();
insert(QString::fromUtf8(idOfFilter.c_str())); insert(QString::fromUtf8(idOfFilter.c_str()));
} }

@ -1,57 +1,57 @@
#ifndef CSV_FILTER_EDITWIDGET_H #ifndef CSV_FILTER_EDITWIDGET_H
#define CSV_FILTER_EDITWIDGET_H #define CSV_FILTER_EDITWIDGET_H
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <QLineEdit> #include <QLineEdit>
#include <QPalette> #include <QPalette>
#include <qt4/QtCore/qnamespace.h> #include <qt4/QtCore/qnamespace.h>
#include "../../model/filter/parser.hpp" #include "../../model/filter/parser.hpp"
#include "../../model/filter/node.hpp" #include "../../model/filter/node.hpp"
class QModelIndex; class QModelIndex;
namespace CSMWorld namespace CSMWorld
{ {
class Data; class Data;
} }
namespace CSVFilter namespace CSVFilter
{ {
class EditWidget : public QLineEdit class EditWidget : public QLineEdit
{ {
Q_OBJECT Q_OBJECT
CSMFilter::Parser mParser; CSMFilter::Parser mParser;
QPalette mPalette; QPalette mPalette;
public: public:
EditWidget (CSMWorld::Data& data, QWidget *parent = 0); EditWidget (CSMWorld::Data& data, QWidget *parent = 0);
signals: signals:
void filterChanged (boost::shared_ptr<CSMFilter::Node> filter); void filterChanged (boost::shared_ptr<CSMFilter::Node> filter);
private: private:
std::string generateFilter(std::pair<std::string, std::vector<std::string> >& seekedString) const; std::string generateFilter(std::pair<std::string, std::vector<std::string> >& seekedString) const;
private slots: private slots:
void textChanged (const QString& text); void textChanged (const QString& text);
void filterDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); void filterDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
void filterRowsRemoved (const QModelIndex& parent, int start, int end); void filterRowsRemoved (const QModelIndex& parent, int start, int end);
void filterRowsInserted (const QModelIndex& parent, int start, int end); void filterRowsInserted (const QModelIndex& parent, int start, int end);
void createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >& filterSource, void createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >& filterSource,
Qt::DropAction action); Qt::DropAction action);
void useFilterRequest(const std::string& idOfFilter); void useFilterRequest(const std::string& idOfFilter);
}; };
} }
#endif #endif

@ -1,50 +1,50 @@
#include "filterbox.hpp" #include "filterbox.hpp"
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QDragEnterEvent> #include <QDragEnterEvent>
#include "recordfilterbox.hpp" #include "recordfilterbox.hpp"
#include <apps/opencs/model/world/tablemimedata.hpp> #include <apps/opencs/model/world/tablemimedata.hpp>
CSVFilter::FilterBox::FilterBox (CSMWorld::Data& data, QWidget *parent) CSVFilter::FilterBox::FilterBox (CSMWorld::Data& data, QWidget *parent)
: QWidget (parent) : QWidget (parent)
{ {
QHBoxLayout *layout = new QHBoxLayout (this); QHBoxLayout *layout = new QHBoxLayout (this);
layout->setContentsMargins (0, 0, 0, 0); layout->setContentsMargins (0, 0, 0, 0);
RecordFilterBox *recordFilterBox = new RecordFilterBox (data, this); RecordFilterBox *recordFilterBox = new RecordFilterBox (data, this);
layout->addWidget (recordFilterBox); layout->addWidget (recordFilterBox);
setLayout (layout); setLayout (layout);
connect (recordFilterBox, connect (recordFilterBox,
SIGNAL (filterChanged (boost::shared_ptr<CSMFilter::Node>)), SIGNAL (filterChanged (boost::shared_ptr<CSMFilter::Node>)),
this, SIGNAL (recordFilterChanged (boost::shared_ptr<CSMFilter::Node>))); this, SIGNAL (recordFilterChanged (boost::shared_ptr<CSMFilter::Node>)));
connect(this, SIGNAL(createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >&, Qt::DropAction)), connect(this, SIGNAL(createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >&, Qt::DropAction)),
recordFilterBox, SIGNAL(createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >&, Qt::DropAction))); recordFilterBox, SIGNAL(createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >&, Qt::DropAction)));
connect(this, SIGNAL(useFilterRequest(const std::string&)), recordFilterBox, SIGNAL(useFilterRequest(const std::string&))); connect(this, SIGNAL(useFilterRequest(const std::string&)), recordFilterBox, SIGNAL(useFilterRequest(const std::string&)));
setAcceptDrops(true); setAcceptDrops(true);
} }
void CSVFilter::FilterBox::dropEvent (QDropEvent* event) void CSVFilter::FilterBox::dropEvent (QDropEvent* event)
{ {
std::vector<CSMWorld::UniversalId> data = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData())->getData(); std::vector<CSMWorld::UniversalId> data = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData())->getData();
emit recordDropped(data, event->proposedAction()); emit recordDropped(data, event->proposedAction());
} }
void CSVFilter::FilterBox::dragEnterEvent (QDragEnterEvent* event) void CSVFilter::FilterBox::dragEnterEvent (QDragEnterEvent* event)
{ {
event->acceptProposedAction(); event->acceptProposedAction();
} }
void CSVFilter::FilterBox::dragMoveEvent (QDragMoveEvent* event) void CSVFilter::FilterBox::dragMoveEvent (QDragMoveEvent* event)
{ {
event->accept(); event->accept();
} }

@ -1,45 +1,45 @@
#ifndef CSV_FILTER_FILTERBOX_H #ifndef CSV_FILTER_FILTERBOX_H
#define CSV_FILTER_FILTERBOX_H #define CSV_FILTER_FILTERBOX_H
#include <vector> #include <vector>
#include <QWidget> #include <QWidget>
#include <qt4/QtCore/qnamespace.h> #include <qt4/QtCore/qnamespace.h>
#include "../../model/filter/node.hpp" #include "../../model/filter/node.hpp"
#include "../../model/world/universalid.hpp" #include "../../model/world/universalid.hpp"
namespace CSMWorld namespace CSMWorld
{ {
class Data; class Data;
} }
namespace CSVFilter namespace CSVFilter
{ {
class FilterBox : public QWidget class FilterBox : public QWidget
{ {
Q_OBJECT Q_OBJECT
void dragEnterEvent (QDragEnterEvent* event); void dragEnterEvent (QDragEnterEvent* event);
void dropEvent (QDropEvent* event); void dropEvent (QDropEvent* event);
void dragMoveEvent(QDragMoveEvent *event); void dragMoveEvent(QDragMoveEvent *event);
public: public:
FilterBox (CSMWorld::Data& data, QWidget *parent = 0); FilterBox (CSMWorld::Data& data, QWidget *parent = 0);
signals: signals:
void recordFilterChanged (boost::shared_ptr<CSMFilter::Node> filter); void recordFilterChanged (boost::shared_ptr<CSMFilter::Node> filter);
void recordDropped (std::vector<CSMWorld::UniversalId>& types, Qt::DropAction action); void recordDropped (std::vector<CSMWorld::UniversalId>& types, Qt::DropAction action);
void createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >& filterSource, void createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >& filterSource,
Qt::DropAction action); Qt::DropAction action);
void useFilterRequest(const std::string& idOfFilter); void useFilterRequest(const std::string& idOfFilter);
}; };
} }
#endif #endif

@ -1,32 +1,32 @@
#include "recordfilterbox.hpp" #include "recordfilterbox.hpp"
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QLabel> #include <QLabel>
#include "editwidget.hpp" #include "editwidget.hpp"
CSVFilter::RecordFilterBox::RecordFilterBox (CSMWorld::Data& data, QWidget *parent) CSVFilter::RecordFilterBox::RecordFilterBox (CSMWorld::Data& data, QWidget *parent)
: QWidget (parent) : QWidget (parent)
{ {
QHBoxLayout *layout = new QHBoxLayout (this); QHBoxLayout *layout = new QHBoxLayout (this);
layout->setContentsMargins (0, 0, 0, 0); layout->setContentsMargins (0, 0, 0, 0);
layout->addWidget (new QLabel ("Record Filter", this)); layout->addWidget (new QLabel ("Record Filter", this));
EditWidget *editWidget = new EditWidget (data, this); EditWidget *editWidget = new EditWidget (data, this);
layout->addWidget (editWidget); layout->addWidget (editWidget);
setLayout (layout); setLayout (layout);
connect ( connect (
editWidget, SIGNAL (filterChanged (boost::shared_ptr<CSMFilter::Node>)), editWidget, SIGNAL (filterChanged (boost::shared_ptr<CSMFilter::Node>)),
this, SIGNAL (filterChanged (boost::shared_ptr<CSMFilter::Node>))); this, SIGNAL (filterChanged (boost::shared_ptr<CSMFilter::Node>)));
connect(this, SIGNAL(createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >&, Qt::DropAction)), connect(this, SIGNAL(createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >&, Qt::DropAction)),
editWidget, SLOT(createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >&, Qt::DropAction))); editWidget, SLOT(createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >&, Qt::DropAction)));
connect(this, SIGNAL(useFilterRequest(const std::string&)), editWidget, SLOT(useFilterRequest(const std::string&))); connect(this, SIGNAL(useFilterRequest(const std::string&)), editWidget, SLOT(useFilterRequest(const std::string&)));
} }

@ -1,38 +1,38 @@
#ifndef CSV_FILTER_RECORDFILTERBOX_H #ifndef CSV_FILTER_RECORDFILTERBOX_H
#define CSV_FILTER_RECORDFILTERBOX_H #define CSV_FILTER_RECORDFILTERBOX_H
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <QWidget> #include <QWidget>
#include <qt4/QtCore/qnamespace.h> #include <qt4/QtCore/qnamespace.h>
#include <QHBoxLayout> #include <QHBoxLayout>
#include "../../model/filter/node.hpp" #include "../../model/filter/node.hpp"
namespace CSMWorld namespace CSMWorld
{ {
class Data; class Data;
} }
namespace CSVFilter namespace CSVFilter
{ {
class RecordFilterBox : public QWidget class RecordFilterBox : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
RecordFilterBox (CSMWorld::Data& data, QWidget *parent = 0); RecordFilterBox (CSMWorld::Data& data, QWidget *parent = 0);
signals: signals:
void filterChanged (boost::shared_ptr<CSMFilter::Node> filter); void filterChanged (boost::shared_ptr<CSMFilter::Node> filter);
void createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >& filterSource, void createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >& filterSource,
Qt::DropAction action); Qt::DropAction action);
void useFilterRequest(const std::string& idOfFilter); void useFilterRequest(const std::string& idOfFilter);
}; };
} }
#endif #endif

File diff suppressed because it is too large Load Diff

@ -1,127 +1,127 @@
#ifndef CSV_WORLD_TABLE_H #ifndef CSV_WORLD_TABLE_H
#define CSV_WORLD_TABLE_H #define CSV_WORLD_TABLE_H
#include <vector> #include <vector>
#include <string> #include <string>
#include <QTableView> #include <QTableView>
#include <QtGui/qevent.h> #include <QtGui/qevent.h>
#include "../../model/filter/node.hpp" #include "../../model/filter/node.hpp"
#include "../../model/world/columnbase.hpp" #include "../../model/world/columnbase.hpp"
namespace CSMDoc { namespace CSMDoc {
class Document; class Document;
} }
class QUndoStack; class QUndoStack;
class QAction; class QAction;
namespace CSMWorld namespace CSMWorld
{ {
class Data; class Data;
class UniversalId; class UniversalId;
class IdTableProxyModel; class IdTableProxyModel;
class IdTable; class IdTable;
} }
namespace CSVWorld namespace CSVWorld
{ {
class CommandDelegate; class CommandDelegate;
///< Table widget ///< Table widget
class Table : public QTableView class Table : public QTableView
{ {
Q_OBJECT Q_OBJECT
std::vector<CommandDelegate *> mDelegates; std::vector<CommandDelegate *> mDelegates;
QUndoStack& mUndoStack; QUndoStack& mUndoStack;
QAction *mEditAction; QAction *mEditAction;
QAction *mCreateAction; QAction *mCreateAction;
QAction *mCloneAction; QAction *mCloneAction;
QAction *mRevertAction; QAction *mRevertAction;
QAction *mDeleteAction; QAction *mDeleteAction;
QAction *mMoveUpAction; QAction *mMoveUpAction;
QAction *mMoveDownAction; QAction *mMoveDownAction;
CSMWorld::IdTableProxyModel *mProxyModel; CSMWorld::IdTableProxyModel *mProxyModel;
CSMWorld::IdTable *mModel; CSMWorld::IdTable *mModel;
bool mEditLock; bool mEditLock;
int mRecordStatusDisplay; int mRecordStatusDisplay;
/// \brief This variable is used exclusivly for checking if dropEvents came from the same document. Most likely you /// \brief This variable is used exclusivly for checking if dropEvents came from the same document. Most likely you
/// should NOT use it for anything else. /// should NOT use it for anything else.
const CSMDoc::Document& mDocument; const CSMDoc::Document& mDocument;
private: private:
void contextMenuEvent (QContextMenuEvent *event); void contextMenuEvent (QContextMenuEvent *event);
std::vector<std::string> listRevertableSelectedIds() const; std::vector<std::string> listRevertableSelectedIds() const;
std::vector<std::string> listDeletableSelectedIds() const; std::vector<std::string> listDeletableSelectedIds() const;
void mouseMoveEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event);
void dragEnterEvent(QDragEnterEvent *event); void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event); void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event); void dropEvent(QDropEvent *event);
public: public:
Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack, bool createAndDelete, Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack, bool createAndDelete,
bool sorting, const CSMDoc::Document& document); bool sorting, const CSMDoc::Document& document);
///< \param createAndDelete Allow creation and deletion of records. ///< \param createAndDelete Allow creation and deletion of records.
/// \param sorting Allow changing order of rows in the view via column headers. /// \param sorting Allow changing order of rows in the view via column headers.
void setEditLock (bool locked); void setEditLock (bool locked);
CSMWorld::UniversalId getUniversalId (int row) const; CSMWorld::UniversalId getUniversalId (int row) const;
void updateEditorSetting (const QString &settingName, const QString &settingValue); void updateEditorSetting (const QString &settingName, const QString &settingValue);
std::vector<std::string> getColumnsWithDisplay(CSMWorld::ColumnBase::Display display) const; std::vector<std::string> getColumnsWithDisplay(CSMWorld::ColumnBase::Display display) const;
signals: signals:
void editRequest (int row); void editRequest (int row);
void selectionSizeChanged (int size); void selectionSizeChanged (int size);
void tableSizeChanged (int size, int deleted, int modified); void tableSizeChanged (int size, int deleted, int modified);
///< \param size Number of not deleted records ///< \param size Number of not deleted records
/// \param deleted Number of deleted records /// \param deleted Number of deleted records
/// \param modified Number of added and modified records /// \param modified Number of added and modified records
void createRequest(); void createRequest();
void cloneRequest(const CSMWorld::UniversalId&); void cloneRequest(const CSMWorld::UniversalId&);
private slots: private slots:
void revertRecord(); void revertRecord();
void deleteRecord(); void deleteRecord();
void editRecord(); void editRecord();
void cloneRecord(); void cloneRecord();
void moveUpRecord(); void moveUpRecord();
void moveDownRecord(); void moveDownRecord();
public slots: public slots:
void tableSizeUpdate(); void tableSizeUpdate();
void selectionSizeUpdate(); void selectionSizeUpdate();
void requestFocus (const std::string& id); void requestFocus (const std::string& id);
void recordFilterChanged (boost::shared_ptr<CSMFilter::Node> filter); void recordFilterChanged (boost::shared_ptr<CSMFilter::Node> filter);
}; };
} }
#endif #endif

@ -1,132 +1,132 @@
#include "tablesubview.hpp" #include "tablesubview.hpp"
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QEvent> #include <QEvent>
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/world/tablemimedata.hpp" #include "../../model/world/tablemimedata.hpp"
#include "../filter/filterbox.hpp" #include "../filter/filterbox.hpp"
#include "table.hpp" #include "table.hpp"
#include "tablebottombox.hpp" #include "tablebottombox.hpp"
#include "creator.hpp" #include "creator.hpp"
CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
const CreatorFactoryBase& creatorFactory, bool sorting) const CreatorFactoryBase& creatorFactory, bool sorting)
: SubView (id) : SubView (id)
{ {
QVBoxLayout *layout = new QVBoxLayout; QVBoxLayout *layout = new QVBoxLayout;
layout->setContentsMargins (QMargins (0, 0, 0, 0)); layout->setContentsMargins (QMargins (0, 0, 0, 0));
layout->addWidget (mBottom = layout->addWidget (mBottom =
new TableBottomBox (creatorFactory, document.getData(), document.getUndoStack(), id, this), 0); new TableBottomBox (creatorFactory, document.getData(), document.getUndoStack(), id, this), 0);
layout->insertWidget (0, mTable = layout->insertWidget (0, mTable =
new Table (id, document.getData(), document.getUndoStack(), mBottom->canCreateAndDelete(), sorting, document), 2); new Table (id, document.getData(), document.getUndoStack(), mBottom->canCreateAndDelete(), sorting, document), 2);
CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this); CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this);
layout->insertWidget (0, filterBox); layout->insertWidget (0, filterBox);
QWidget *widget = new QWidget; QWidget *widget = new QWidget;
widget->setLayout (layout); widget->setLayout (layout);
setWidget (widget); 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)), connect (mTable, SIGNAL (selectionSizeChanged (int)),
mBottom, SLOT (selectionSizeChanged (int))); mBottom, SLOT (selectionSizeChanged (int)));
connect (mTable, SIGNAL (tableSizeChanged (int, int, int)), connect (mTable, SIGNAL (tableSizeChanged (int, int, int)),
mBottom, SLOT (tableSizeChanged (int, int, int))); mBottom, SLOT (tableSizeChanged (int, int, int)));
mTable->tableSizeUpdate(); mTable->tableSizeUpdate();
mTable->selectionSizeUpdate(); mTable->selectionSizeUpdate();
mTable->viewport()->installEventFilter(this); mTable->viewport()->installEventFilter(this);
mBottom->installEventFilter(this); mBottom->installEventFilter(this);
filterBox->installEventFilter(this); filterBox->installEventFilter(this);
if (mBottom->canCreateAndDelete()) if (mBottom->canCreateAndDelete())
{ {
connect (mTable, SIGNAL (createRequest()), mBottom, SLOT (createRequest())); connect (mTable, SIGNAL (createRequest()), mBottom, SLOT (createRequest()));
connect (mTable, SIGNAL (cloneRequest(const CSMWorld::UniversalId&)), this, connect (mTable, SIGNAL (cloneRequest(const CSMWorld::UniversalId&)), this,
SLOT(cloneRequest(const CSMWorld::UniversalId&))); SLOT(cloneRequest(const CSMWorld::UniversalId&)));
connect (this, SIGNAL(cloneRequest(const std::string&, const CSMWorld::UniversalId::Type)), connect (this, SIGNAL(cloneRequest(const std::string&, const CSMWorld::UniversalId::Type)),
mBottom, SLOT(cloneRequest(const std::string&, const CSMWorld::UniversalId::Type))); mBottom, SLOT(cloneRequest(const std::string&, const CSMWorld::UniversalId::Type)));
} }
connect (mBottom, SIGNAL (requestFocus (const std::string&)), connect (mBottom, SIGNAL (requestFocus (const std::string&)),
mTable, SLOT (requestFocus (const std::string&))); mTable, SLOT (requestFocus (const std::string&)));
connect (filterBox, connect (filterBox,
SIGNAL (recordFilterChanged (boost::shared_ptr<CSMFilter::Node>)), SIGNAL (recordFilterChanged (boost::shared_ptr<CSMFilter::Node>)),
mTable, SLOT (recordFilterChanged (boost::shared_ptr<CSMFilter::Node>))); mTable, SLOT (recordFilterChanged (boost::shared_ptr<CSMFilter::Node>)));
connect(filterBox, SIGNAL(recordDropped(std::vector<CSMWorld::UniversalId>&, Qt::DropAction)), connect(filterBox, SIGNAL(recordDropped(std::vector<CSMWorld::UniversalId>&, Qt::DropAction)),
this, SLOT(createFilterRequest(std::vector<CSMWorld::UniversalId>&, Qt::DropAction))); this, SLOT(createFilterRequest(std::vector<CSMWorld::UniversalId>&, Qt::DropAction)));
connect(this, SIGNAL(useFilterRequest(const std::string&)), filterBox, SIGNAL(useFilterRequest(const std::string&))); connect(this, SIGNAL(useFilterRequest(const std::string&)), filterBox, SIGNAL(useFilterRequest(const std::string&)));
connect(this, SIGNAL(createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >&, Qt::DropAction)), connect(this, SIGNAL(createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >&, Qt::DropAction)),
filterBox, SIGNAL(createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >&, Qt::DropAction))); filterBox, SIGNAL(createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >&, Qt::DropAction)));
} }
void CSVWorld::TableSubView::setEditLock (bool locked) void CSVWorld::TableSubView::setEditLock (bool locked)
{ {
mTable->setEditLock (locked); mTable->setEditLock (locked);
mBottom->setEditLock (locked); mBottom->setEditLock (locked);
} }
void CSVWorld::TableSubView::editRequest (int row) void CSVWorld::TableSubView::editRequest (int row)
{ {
focusId (mTable->getUniversalId (row)); focusId (mTable->getUniversalId (row));
} }
void CSVWorld::TableSubView::updateEditorSetting(const QString &settingName, const QString &settingValue) void CSVWorld::TableSubView::updateEditorSetting(const QString &settingName, const QString &settingValue)
{ {
mTable->updateEditorSetting(settingName, settingValue); mTable->updateEditorSetting(settingName, settingValue);
} }
void CSVWorld::TableSubView::setStatusBar (bool show) void CSVWorld::TableSubView::setStatusBar (bool show)
{ {
mBottom->setStatusBar (show); mBottom->setStatusBar (show);
} }
void CSVWorld::TableSubView::cloneRequest(const CSMWorld::UniversalId& toClone) void CSVWorld::TableSubView::cloneRequest(const CSMWorld::UniversalId& toClone)
{ {
emit cloneRequest(toClone.getId(), toClone.getType()); emit cloneRequest(toClone.getId(), toClone.getType());
} }
void CSVWorld::TableSubView::createFilterRequest (std::vector< CSMWorld::UniversalId>& types, Qt::DropAction action) void CSVWorld::TableSubView::createFilterRequest (std::vector< CSMWorld::UniversalId>& types, Qt::DropAction action)
{ {
std::vector<std::pair<std::string, std::vector<std::string> > > filterSource; std::vector<std::pair<std::string, std::vector<std::string> > > filterSource;
for (std::vector<CSMWorld::UniversalId>::iterator it = types.begin(); it != types.end(); ++it) for (std::vector<CSMWorld::UniversalId>::iterator it = types.begin(); it != types.end(); ++it)
{ {
std::pair<std::string, std::vector<std::string> > pair( //splited long line std::pair<std::string, std::vector<std::string> > pair( //splited long line
std::make_pair(it->getId(), mTable->getColumnsWithDisplay(CSMWorld::TableMimeData::convertEnums(it->getType())))); std::make_pair(it->getId(), mTable->getColumnsWithDisplay(CSMWorld::TableMimeData::convertEnums(it->getType()))));
filterSource.push_back(pair); filterSource.push_back(pair);
} }
emit createFilterRequest(filterSource, action); emit createFilterRequest(filterSource, action);
} }
bool CSVWorld::TableSubView::eventFilter (QObject* object, QEvent* event) bool CSVWorld::TableSubView::eventFilter (QObject* object, QEvent* event)
{ {
if (event->type() == QEvent::Drop) if (event->type() == QEvent::Drop)
{ {
QDropEvent* drop = dynamic_cast<QDropEvent*>(event); QDropEvent* drop = dynamic_cast<QDropEvent*>(event);
const CSMWorld::TableMimeData* data = dynamic_cast<const CSMWorld::TableMimeData*>(drop->mimeData()); const CSMWorld::TableMimeData* data = dynamic_cast<const CSMWorld::TableMimeData*>(drop->mimeData());
bool handled = data->holdsType(CSMWorld::UniversalId::Type_Filter); bool handled = data->holdsType(CSMWorld::UniversalId::Type_Filter);
if (handled) if (handled)
{ {
emit useFilterRequest(data->returnMatching(CSMWorld::UniversalId::Type_Filter).getId()); emit useFilterRequest(data->returnMatching(CSMWorld::UniversalId::Type_Filter).getId());
} }
return handled; return handled;
} }
return false; return false;
} }

@ -1,63 +1,63 @@
#ifndef CSV_WORLD_TABLESUBVIEW_H #ifndef CSV_WORLD_TABLESUBVIEW_H
#define CSV_WORLD_TABLESUBVIEW_H #define CSV_WORLD_TABLESUBVIEW_H
#include "../doc/subview.hpp" #include "../doc/subview.hpp"
#include <qt4/QtCore/qnamespace.h> #include <qt4/QtCore/qnamespace.h>
class QModelIndex; class QModelIndex;
namespace CSMWorld namespace CSMWorld
{ {
class IdTable; class IdTable;
} }
namespace CSMDoc namespace CSMDoc
{ {
class Document; class Document;
} }
namespace CSVWorld namespace CSVWorld
{ {
class Table; class Table;
class TableBottomBox; class TableBottomBox;
class CreatorFactoryBase; class CreatorFactoryBase;
class TableSubView : public CSVDoc::SubView class TableSubView : public CSVDoc::SubView
{ {
Q_OBJECT Q_OBJECT
Table *mTable; Table *mTable;
TableBottomBox *mBottom; TableBottomBox *mBottom;
public: public:
TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
const CreatorFactoryBase& creatorFactory, bool sorting); const CreatorFactoryBase& creatorFactory, bool sorting);
virtual void setEditLock (bool locked); virtual void setEditLock (bool locked);
virtual void updateEditorSetting (const QString& key, const QString& value); virtual void updateEditorSetting (const QString& key, const QString& value);
virtual void setStatusBar (bool show); virtual void setStatusBar (bool show);
protected: protected:
bool eventFilter(QObject* object, QEvent *event); bool eventFilter(QObject* object, QEvent *event);
signals: signals:
void cloneRequest(const std::string&, void cloneRequest(const std::string&,
const CSMWorld::UniversalId::Type); const CSMWorld::UniversalId::Type);
void createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >& filterSource, void createFilterRequest(std::vector<std::pair<std::string, std::vector<std::string> > >& filterSource,
Qt::DropAction action); Qt::DropAction action);
void useFilterRequest(const std::string& idOfFilter); void useFilterRequest(const std::string& idOfFilter);
private slots: private slots:
void editRequest (int row); void editRequest (int row);
void cloneRequest (const CSMWorld::UniversalId& toClone); void cloneRequest (const CSMWorld::UniversalId& toClone);
void createFilterRequest(std::vector< CSMWorld::UniversalId >& types, void createFilterRequest(std::vector< CSMWorld::UniversalId >& types,
Qt::DropAction action); Qt::DropAction action);
}; };
} }
#endif #endif

@ -1,352 +1,352 @@
#include "statemanagerimp.hpp" #include "statemanagerimp.hpp"
#include <components/esm/esmwriter.hpp> #include <components/esm/esmwriter.hpp>
#include <components/esm/esmreader.hpp> #include <components/esm/esmreader.hpp>
#include <components/esm/cellid.hpp> #include <components/esm/cellid.hpp>
#include <components/esm/loadcell.hpp> #include <components/esm/loadcell.hpp>
#include <components/misc/stringops.hpp> #include <components/misc/stringops.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include <OgreImage.h> #include <OgreImage.h>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/journal.hpp" #include "../mwbase/journal.hpp"
#include "../mwbase/dialoguemanager.hpp" #include "../mwbase/dialoguemanager.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/scriptmanager.hpp" #include "../mwbase/scriptmanager.hpp"
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
#include "../mwscript/globalscripts.hpp" #include "../mwscript/globalscripts.hpp"
void MWState::StateManager::cleanup (bool force) void MWState::StateManager::cleanup (bool force)
{ {
if (mState!=State_NoGame || force) if (mState!=State_NoGame || force)
{ {
MWBase::Environment::get().getSoundManager()->clear(); MWBase::Environment::get().getSoundManager()->clear();
MWBase::Environment::get().getDialogueManager()->clear(); MWBase::Environment::get().getDialogueManager()->clear();
MWBase::Environment::get().getJournal()->clear(); MWBase::Environment::get().getJournal()->clear();
MWBase::Environment::get().getScriptManager()->getGlobalScripts().clear(); MWBase::Environment::get().getScriptManager()->getGlobalScripts().clear();
MWBase::Environment::get().getWorld()->clear(); MWBase::Environment::get().getWorld()->clear();
MWBase::Environment::get().getWindowManager()->clear(); MWBase::Environment::get().getWindowManager()->clear();
mState = State_NoGame; mState = State_NoGame;
mCharacterManager.clearCurrentCharacter(); mCharacterManager.clearCurrentCharacter();
mTimePlayed = 0; mTimePlayed = 0;
} }
} }
std::map<int, int> MWState::StateManager::buildContentFileIndexMap (const ESM::ESMReader& reader) std::map<int, int> MWState::StateManager::buildContentFileIndexMap (const ESM::ESMReader& reader)
const const
{ {
const std::vector<std::string>& current = const std::vector<std::string>& current =
MWBase::Environment::get().getWorld()->getContentFiles(); MWBase::Environment::get().getWorld()->getContentFiles();
const std::vector<ESM::Header::MasterData>& prev = reader.getGameFiles(); const std::vector<ESM::Header::MasterData>& prev = reader.getGameFiles();
std::map<int, int> map; std::map<int, int> map;
for (int iPrev = 0; iPrev<static_cast<int> (prev.size()); ++iPrev) for (int iPrev = 0; iPrev<static_cast<int> (prev.size()); ++iPrev)
{ {
std::string id = Misc::StringUtils::lowerCase (prev[iPrev].name); std::string id = Misc::StringUtils::lowerCase (prev[iPrev].name);
for (int iCurrent = 0; iCurrent<static_cast<int> (current.size()); ++iCurrent) for (int iCurrent = 0; iCurrent<static_cast<int> (current.size()); ++iCurrent)
if (id==Misc::StringUtils::lowerCase (current[iCurrent])) if (id==Misc::StringUtils::lowerCase (current[iCurrent]))
{ {
map.insert (std::make_pair (iPrev, iCurrent)); map.insert (std::make_pair (iPrev, iCurrent));
break; break;
} }
} }
return map; return map;
} }
MWState::StateManager::StateManager (const boost::filesystem::path& saves, const std::string& game) MWState::StateManager::StateManager (const boost::filesystem::path& saves, const std::string& game)
: mQuitRequest (false), mAskLoadRecent(false), mState (State_NoGame), mCharacterManager (saves, game), mTimePlayed (0) : mQuitRequest (false), mAskLoadRecent(false), mState (State_NoGame), mCharacterManager (saves, game), mTimePlayed (0)
{ {
} }
void MWState::StateManager::requestQuit() void MWState::StateManager::requestQuit()
{ {
mQuitRequest = true; mQuitRequest = true;
} }
bool MWState::StateManager::hasQuitRequest() const bool MWState::StateManager::hasQuitRequest() const
{ {
return mQuitRequest; return mQuitRequest;
} }
void MWState::StateManager::askLoadRecent() void MWState::StateManager::askLoadRecent()
{ {
if (MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_MainMenu) if (MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_MainMenu)
return; return;
if( !mAskLoadRecent ) if( !mAskLoadRecent )
{ {
if(getCurrentCharacter()->begin() == getCurrentCharacter()->end() )//no saves if(getCurrentCharacter()->begin() == getCurrentCharacter()->end() )//no saves
{ {
MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu);
} }
else else
{ {
MWState::Slot lastSave = *getCurrentCharacter()->begin(); MWState::Slot lastSave = *getCurrentCharacter()->begin();
std::vector<std::string> buttons; std::vector<std::string> buttons;
buttons.push_back("#{sYes}"); buttons.push_back("#{sYes}");
buttons.push_back("#{sNo}"); buttons.push_back("#{sNo}");
std::string tag("%s"); std::string tag("%s");
std::string message = MWBase::Environment::get().getWindowManager()->getGameSettingString("sLoadLastSaveMsg", tag); std::string message = MWBase::Environment::get().getWindowManager()->getGameSettingString("sLoadLastSaveMsg", tag);
size_t pos = message.find(tag); size_t pos = message.find(tag);
message.replace(pos, tag.length(), lastSave.mProfile.mDescription); message.replace(pos, tag.length(), lastSave.mProfile.mDescription);
MWBase::Environment::get().getWindowManager()->messageBox(message, buttons); MWBase::Environment::get().getWindowManager()->messageBox(message, buttons);
mAskLoadRecent = true; mAskLoadRecent = true;
} }
} }
} }
MWState::StateManager::State MWState::StateManager::getState() const MWState::StateManager::State MWState::StateManager::getState() const
{ {
return mState; return mState;
} }
void MWState::StateManager::newGame (bool bypass) void MWState::StateManager::newGame (bool bypass)
{ {
cleanup(); cleanup();
if (!bypass) if (!bypass)
{ {
MWBase::Environment::get().getWorld()->startNewGame(); MWBase::Environment::get().getWorld()->startNewGame();
MWBase::Environment::get().getWindowManager()->setNewGame (true); MWBase::Environment::get().getWindowManager()->setNewGame (true);
} }
else else
MWBase::Environment::get().getWorld()->setGlobalInt ("chargenstate", -1); MWBase::Environment::get().getWorld()->setGlobalInt ("chargenstate", -1);
MWBase::Environment::get().getScriptManager()->getGlobalScripts().addStartup(); MWBase::Environment::get().getScriptManager()->getGlobalScripts().addStartup();
mState = State_Running; mState = State_Running;
} }
void MWState::StateManager::endGame() void MWState::StateManager::endGame()
{ {
mState = State_Ended; mState = State_Ended;
MWBase::Environment::get().getWorld()->useDeathCamera(); MWBase::Environment::get().getWorld()->useDeathCamera();
} }
void MWState::StateManager::saveGame (const std::string& description, const Slot *slot) void MWState::StateManager::saveGame (const std::string& description, const Slot *slot)
{ {
ESM::SavedGame profile; ESM::SavedGame profile;
MWBase::World& world = *MWBase::Environment::get().getWorld(); MWBase::World& world = *MWBase::Environment::get().getWorld();
MWWorld::Ptr player = world.getPlayer().getPlayer(); MWWorld::Ptr player = world.getPlayer().getPlayer();
profile.mContentFiles = world.getContentFiles(); profile.mContentFiles = world.getContentFiles();
profile.mPlayerName = player.getClass().getName (player); profile.mPlayerName = player.getClass().getName (player);
profile.mPlayerLevel = player.getClass().getNpcStats (player).getLevel(); profile.mPlayerLevel = player.getClass().getNpcStats (player).getLevel();
profile.mPlayerClass = player.get<ESM::NPC>()->mBase->mClass; profile.mPlayerClass = player.get<ESM::NPC>()->mBase->mClass;
profile.mPlayerCell = world.getCellName(); profile.mPlayerCell = world.getCellName();
profile.mInGameTime.mGameHour = world.getTimeStamp().getHour(); profile.mInGameTime.mGameHour = world.getTimeStamp().getHour();
profile.mInGameTime.mDay = world.getDay(); profile.mInGameTime.mDay = world.getDay();
profile.mInGameTime.mMonth = world.getMonth(); profile.mInGameTime.mMonth = world.getMonth();
profile.mInGameTime.mYear = world.getYear(); profile.mInGameTime.mYear = world.getYear();
profile.mTimePlayed = mTimePlayed; profile.mTimePlayed = mTimePlayed;
profile.mDescription = description; profile.mDescription = description;
int screenshotW = 259*2, screenshotH = 133*2; // *2 to get some nice antialiasing int screenshotW = 259*2, screenshotH = 133*2; // *2 to get some nice antialiasing
Ogre::Image screenshot; Ogre::Image screenshot;
world.screenshot(screenshot, screenshotW, screenshotH); world.screenshot(screenshot, screenshotW, screenshotH);
Ogre::DataStreamPtr encoded = screenshot.encode("jpg"); Ogre::DataStreamPtr encoded = screenshot.encode("jpg");
profile.mScreenshot.resize(encoded->size()); profile.mScreenshot.resize(encoded->size());
encoded->read(&profile.mScreenshot[0], encoded->size()); encoded->read(&profile.mScreenshot[0], encoded->size());
if (!slot) if (!slot)
slot = mCharacterManager.getCurrentCharacter()->createSlot (profile); slot = mCharacterManager.getCurrentCharacter()->createSlot (profile);
else else
slot = mCharacterManager.getCurrentCharacter()->updateSlot (slot, profile); slot = mCharacterManager.getCurrentCharacter()->updateSlot (slot, profile);
std::ofstream stream (slot->mPath.string().c_str(), std::ios::binary); std::ofstream stream (slot->mPath.string().c_str(), std::ios::binary);
ESM::ESMWriter writer; ESM::ESMWriter writer;
const std::vector<std::string>& current = const std::vector<std::string>& current =
MWBase::Environment::get().getWorld()->getContentFiles(); MWBase::Environment::get().getWorld()->getContentFiles();
for (std::vector<std::string>::const_iterator iter (current.begin()); iter!=current.end(); for (std::vector<std::string>::const_iterator iter (current.begin()); iter!=current.end();
++iter) ++iter)
writer.addMaster (*iter, 0); // not using the size information anyway -> use value of 0 writer.addMaster (*iter, 0); // not using the size information anyway -> use value of 0
writer.setFormat (ESM::Header::CurrentFormat); writer.setFormat (ESM::Header::CurrentFormat);
writer.setRecordCount ( writer.setRecordCount (
1 // saved game header 1 // saved game header
+MWBase::Environment::get().getJournal()->countSavedGameRecords() +MWBase::Environment::get().getJournal()->countSavedGameRecords()
+MWBase::Environment::get().getWorld()->countSavedGameRecords() +MWBase::Environment::get().getWorld()->countSavedGameRecords()
+MWBase::Environment::get().getScriptManager()->getGlobalScripts().countSavedGameRecords() +MWBase::Environment::get().getScriptManager()->getGlobalScripts().countSavedGameRecords()
+MWBase::Environment::get().getDialogueManager()->countSavedGameRecords() +MWBase::Environment::get().getDialogueManager()->countSavedGameRecords()
+1 // global map +1 // global map
); );
writer.save (stream); writer.save (stream);
writer.startRecord (ESM::REC_SAVE); writer.startRecord (ESM::REC_SAVE);
slot->mProfile.save (writer); slot->mProfile.save (writer);
writer.endRecord (ESM::REC_SAVE); writer.endRecord (ESM::REC_SAVE);
MWBase::Environment::get().getJournal()->write (writer); MWBase::Environment::get().getJournal()->write (writer);
MWBase::Environment::get().getDialogueManager()->write (writer); MWBase::Environment::get().getDialogueManager()->write (writer);
MWBase::Environment::get().getWorld()->write (writer); MWBase::Environment::get().getWorld()->write (writer);
MWBase::Environment::get().getScriptManager()->getGlobalScripts().write (writer); MWBase::Environment::get().getScriptManager()->getGlobalScripts().write (writer);
MWBase::Environment::get().getWindowManager()->write(writer); MWBase::Environment::get().getWindowManager()->write(writer);
writer.close(); writer.close();
Settings::Manager::setString ("character", "Saves", Settings::Manager::setString ("character", "Saves",
slot->mPath.parent_path().filename().string()); slot->mPath.parent_path().filename().string());
} }
void MWState::StateManager::loadGame (const Character *character, const Slot *slot) void MWState::StateManager::loadGame (const Character *character, const Slot *slot)
{ {
try try
{ {
cleanup(); cleanup();
mTimePlayed = slot->mProfile.mTimePlayed; mTimePlayed = slot->mProfile.mTimePlayed;
ESM::ESMReader reader; ESM::ESMReader reader;
reader.open (slot->mPath.string()); reader.open (slot->mPath.string());
std::map<int, int> contentFileMap = buildContentFileIndexMap (reader); std::map<int, int> contentFileMap = buildContentFileIndexMap (reader);
while (reader.hasMoreRecs()) while (reader.hasMoreRecs())
{ {
ESM::NAME n = reader.getRecName(); ESM::NAME n = reader.getRecName();
reader.getRecHeader(); reader.getRecHeader();
switch (n.val) switch (n.val)
{ {
case ESM::REC_SAVE: case ESM::REC_SAVE:
// don't need to read that here // don't need to read that here
reader.skipRecord(); reader.skipRecord();
break; break;
case ESM::REC_JOUR: case ESM::REC_JOUR:
case ESM::REC_QUES: case ESM::REC_QUES:
MWBase::Environment::get().getJournal()->readRecord (reader, n.val); MWBase::Environment::get().getJournal()->readRecord (reader, n.val);
break; break;
case ESM::REC_DIAS: case ESM::REC_DIAS:
MWBase::Environment::get().getDialogueManager()->readRecord (reader, n.val); MWBase::Environment::get().getDialogueManager()->readRecord (reader, n.val);
break; break;
case ESM::REC_ALCH: case ESM::REC_ALCH:
case ESM::REC_ARMO: case ESM::REC_ARMO:
case ESM::REC_BOOK: case ESM::REC_BOOK:
case ESM::REC_CLAS: case ESM::REC_CLAS:
case ESM::REC_CLOT: case ESM::REC_CLOT:
case ESM::REC_ENCH: case ESM::REC_ENCH:
case ESM::REC_NPC_: case ESM::REC_NPC_:
case ESM::REC_SPEL: case ESM::REC_SPEL:
case ESM::REC_WEAP: case ESM::REC_WEAP:
case ESM::REC_GLOB: case ESM::REC_GLOB:
case ESM::REC_PLAY: case ESM::REC_PLAY:
case ESM::REC_CSTA: case ESM::REC_CSTA:
MWBase::Environment::get().getWorld()->readRecord (reader, n.val, contentFileMap); MWBase::Environment::get().getWorld()->readRecord (reader, n.val, contentFileMap);
break; break;
case ESM::REC_GSCR: case ESM::REC_GSCR:
MWBase::Environment::get().getScriptManager()->getGlobalScripts().readRecord (reader, n.val); MWBase::Environment::get().getScriptManager()->getGlobalScripts().readRecord (reader, n.val);
break; break;
case ESM::REC_GMAP: case ESM::REC_GMAP:
MWBase::Environment::get().getWindowManager()->readRecord(reader, n.val); MWBase::Environment::get().getWindowManager()->readRecord(reader, n.val);
break; break;
default: default:
// ignore invalid records // ignore invalid records
/// \todo log error /// \todo log error
reader.skipRecord(); reader.skipRecord();
} }
} }
mCharacterManager.setCurrentCharacter(character); mCharacterManager.setCurrentCharacter(character);
mState = State_Running; mState = State_Running;
Settings::Manager::setString ("character", "Saves", Settings::Manager::setString ("character", "Saves",
slot->mPath.parent_path().filename().string()); slot->mPath.parent_path().filename().string());
MWBase::Environment::get().getWindowManager()->setNewGame(false); MWBase::Environment::get().getWindowManager()->setNewGame(false);
MWBase::Environment::get().getWorld()->setupPlayer(); MWBase::Environment::get().getWorld()->setupPlayer();
MWBase::Environment::get().getWorld()->renderPlayer(); MWBase::Environment::get().getWorld()->renderPlayer();
MWBase::Environment::get().getWindowManager()->updatePlayer(); MWBase::Environment::get().getWindowManager()->updatePlayer();
MWBase::Environment::get().getMechanicsManager()->playerLoaded(); MWBase::Environment::get().getMechanicsManager()->playerLoaded();
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
ESM::CellId cellId = ptr.getCell()->mCell->getCellId(); ESM::CellId cellId = ptr.getCell()->mCell->getCellId();
MWBase::Environment::get().getWorld()->changeToCell (cellId, ptr.getRefData().getPosition()); MWBase::Environment::get().getWorld()->changeToCell (cellId, ptr.getRefData().getPosition());
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
std::cerr << "failed to load saved game: " << e.what() << std::endl; std::cerr << "failed to load saved game: " << e.what() << std::endl;
cleanup (true); cleanup (true);
} }
} }
MWState::Character *MWState::StateManager::getCurrentCharacter (bool create) MWState::Character *MWState::StateManager::getCurrentCharacter (bool create)
{ {
return mCharacterManager.getCurrentCharacter (create); return mCharacterManager.getCurrentCharacter (create);
} }
MWState::StateManager::CharacterIterator MWState::StateManager::characterBegin() MWState::StateManager::CharacterIterator MWState::StateManager::characterBegin()
{ {
return mCharacterManager.begin(); return mCharacterManager.begin();
} }
MWState::StateManager::CharacterIterator MWState::StateManager::characterEnd() MWState::StateManager::CharacterIterator MWState::StateManager::characterEnd()
{ {
return mCharacterManager.end(); return mCharacterManager.end();
} }
void MWState::StateManager::update (float duration) void MWState::StateManager::update (float duration)
{ {
mTimePlayed += duration; mTimePlayed += duration;
// Note: It would be nicer to trigger this from InputManager, i.e. the very beginning of the frame update. // Note: It would be nicer to trigger this from InputManager, i.e. the very beginning of the frame update.
if (mAskLoadRecent) if (mAskLoadRecent)
{ {
int iButton = MWBase::Environment::get().getWindowManager()->readPressedButton(); int iButton = MWBase::Environment::get().getWindowManager()->readPressedButton();
if(iButton==0) if(iButton==0)
{ {
mAskLoadRecent = false; mAskLoadRecent = false;
//Load last saved game for current character //Load last saved game for current character
MWState::Character *curCharacter = getCurrentCharacter(); MWState::Character *curCharacter = getCurrentCharacter();
MWState::Slot lastSave = *curCharacter->begin(); MWState::Slot lastSave = *curCharacter->begin();
loadGame(curCharacter, &lastSave); loadGame(curCharacter, &lastSave);
} }
else if(iButton==1) else if(iButton==1)
{ {
mAskLoadRecent = false; mAskLoadRecent = false;
MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu);
} }
} }
} }

@ -1,203 +1,203 @@
#include "esmwriter.hpp" #include "esmwriter.hpp"
#include <cassert> #include <cassert>
#include <fstream> #include <fstream>
#include <stdexcept> #include <stdexcept>
namespace ESM namespace ESM
{ {
ESMWriter::ESMWriter() : mEncoder (0), mRecordCount (0), mCounting (true) {} ESMWriter::ESMWriter() : mEncoder (0), mRecordCount (0), mCounting (true) {}
unsigned int ESMWriter::getVersion() const unsigned int ESMWriter::getVersion() const
{ {
return mHeader.mData.version; return mHeader.mData.version;
} }
void ESMWriter::setVersion(unsigned int ver) void ESMWriter::setVersion(unsigned int ver)
{ {
mHeader.mData.version = ver; mHeader.mData.version = ver;
} }
void ESMWriter::setAuthor(const std::string& auth) void ESMWriter::setAuthor(const std::string& auth)
{ {
mHeader.mData.author.assign (auth); mHeader.mData.author.assign (auth);
} }
void ESMWriter::setDescription(const std::string& desc) void ESMWriter::setDescription(const std::string& desc)
{ {
mHeader.mData.desc.assign (desc); mHeader.mData.desc.assign (desc);
} }
void ESMWriter::setRecordCount (int count) void ESMWriter::setRecordCount (int count)
{ {
mHeader.mData.records = count; mHeader.mData.records = count;
} }
void ESMWriter::setFormat (int format) void ESMWriter::setFormat (int format)
{ {
mHeader.mFormat = format; mHeader.mFormat = format;
} }
void ESMWriter::clearMaster() void ESMWriter::clearMaster()
{ {
mHeader.mMaster.clear(); mHeader.mMaster.clear();
} }
void ESMWriter::addMaster(const std::string& name, uint64_t size) void ESMWriter::addMaster(const std::string& name, uint64_t size)
{ {
Header::MasterData d; Header::MasterData d;
d.name = name; d.name = name;
d.size = size; d.size = size;
mHeader.mMaster.push_back(d); mHeader.mMaster.push_back(d);
} }
void ESMWriter::save(std::ostream& file) void ESMWriter::save(std::ostream& file)
{ {
mRecordCount = 0; mRecordCount = 0;
mRecords.clear(); mRecords.clear();
mCounting = true; mCounting = true;
mStream = &file; mStream = &file;
startRecord("TES3", 0); startRecord("TES3", 0);
mHeader.save (*this); mHeader.save (*this);
endRecord("TES3"); endRecord("TES3");
} }
void ESMWriter::close() void ESMWriter::close()
{ {
if (!mRecords.empty()) if (!mRecords.empty())
throw std::runtime_error ("Unclosed record remaining"); throw std::runtime_error ("Unclosed record remaining");
} }
void ESMWriter::startRecord(const std::string& name, uint32_t flags) void ESMWriter::startRecord(const std::string& name, uint32_t flags)
{ {
mRecordCount++; mRecordCount++;
writeName(name); writeName(name);
RecordData rec; RecordData rec;
rec.name = name; rec.name = name;
rec.position = mStream->tellp(); rec.position = mStream->tellp();
rec.size = 0; rec.size = 0;
writeT<uint32_t>(0); // Size goes here writeT<uint32_t>(0); // Size goes here
writeT<uint32_t>(0); // Unused header? writeT<uint32_t>(0); // Unused header?
writeT(flags); writeT(flags);
mRecords.push_back(rec); mRecords.push_back(rec);
assert(mRecords.back().size == 0); assert(mRecords.back().size == 0);
} }
void ESMWriter::startRecord (uint32_t name, uint32_t flags) void ESMWriter::startRecord (uint32_t name, uint32_t flags)
{ {
std::string type; std::string type;
for (int i=0; i<4; ++i) for (int i=0; i<4; ++i)
/// \todo make endianess agnostic /// \todo make endianess agnostic
type += reinterpret_cast<const char *> (&name)[i]; type += reinterpret_cast<const char *> (&name)[i];
startRecord (type, flags); startRecord (type, flags);
} }
void ESMWriter::startSubRecord(const std::string& name) void ESMWriter::startSubRecord(const std::string& name)
{ {
writeName(name); writeName(name);
RecordData rec; RecordData rec;
rec.name = name; rec.name = name;
rec.position = mStream->tellp(); rec.position = mStream->tellp();
rec.size = 0; rec.size = 0;
writeT<uint32_t>(0); // Size goes here writeT<uint32_t>(0); // Size goes here
mRecords.push_back(rec); mRecords.push_back(rec);
assert(mRecords.back().size == 0); assert(mRecords.back().size == 0);
} }
void ESMWriter::endRecord(const std::string& name) void ESMWriter::endRecord(const std::string& name)
{ {
RecordData rec = mRecords.back(); RecordData rec = mRecords.back();
assert(rec.name == name); assert(rec.name == name);
mRecords.pop_back(); mRecords.pop_back();
mStream->seekp(rec.position); mStream->seekp(rec.position);
mCounting = false; mCounting = false;
write (reinterpret_cast<const char*> (&rec.size), sizeof(uint32_t)); write (reinterpret_cast<const char*> (&rec.size), sizeof(uint32_t));
mCounting = true; mCounting = true;
mStream->seekp(0, std::ios::end); mStream->seekp(0, std::ios::end);
} }
void ESMWriter::endRecord (uint32_t name) void ESMWriter::endRecord (uint32_t name)
{ {
std::string type; std::string type;
for (int i=0; i<4; ++i) for (int i=0; i<4; ++i)
/// \todo make endianess agnostic /// \todo make endianess agnostic
type += reinterpret_cast<const char *> (&name)[i]; type += reinterpret_cast<const char *> (&name)[i];
endRecord (type); endRecord (type);
} }
void ESMWriter::writeHNString(const std::string& name, const std::string& data) void ESMWriter::writeHNString(const std::string& name, const std::string& data)
{ {
startSubRecord(name); startSubRecord(name);
writeHString(data); writeHString(data);
endRecord(name); endRecord(name);
} }
void ESMWriter::writeHNString(const std::string& name, const std::string& data, size_t size) void ESMWriter::writeHNString(const std::string& name, const std::string& data, size_t size)
{ {
assert(data.size() <= size); assert(data.size() <= size);
startSubRecord(name); startSubRecord(name);
writeHString(data); writeHString(data);
if (data.size() < size) if (data.size() < size)
{ {
for (size_t i = data.size(); i < size; ++i) for (size_t i = data.size(); i < size; ++i)
write("\0",1); write("\0",1);
} }
endRecord(name); endRecord(name);
} }
void ESMWriter::writeHString(const std::string& data) void ESMWriter::writeHString(const std::string& data)
{ {
if (data.size() == 0) if (data.size() == 0)
write("\0", 1); write("\0", 1);
else else
{ {
// Convert to UTF8 and return // Convert to UTF8 and return
std::string string = mEncoder ? mEncoder->getLegacyEnc(data) : data; std::string string = mEncoder ? mEncoder->getLegacyEnc(data) : data;
write(string.c_str(), string.size()); write(string.c_str(), string.size());
} }
} }
void ESMWriter::writeHCString(const std::string& data) void ESMWriter::writeHCString(const std::string& data)
{ {
writeHString(data); writeHString(data);
if (data.size() > 0 && data[data.size()-1] != '\0') if (data.size() > 0 && data[data.size()-1] != '\0')
write("\0", 1); write("\0", 1);
} }
void ESMWriter::writeName(const std::string& name) void ESMWriter::writeName(const std::string& name)
{ {
assert((name.size() == 4 && name[3] != '\0')); assert((name.size() == 4 && name[3] != '\0'));
write(name.c_str(), name.size()); write(name.c_str(), name.size());
} }
void ESMWriter::write(const char* data, size_t size) void ESMWriter::write(const char* data, size_t size)
{ {
if (mCounting && !mRecords.empty()) if (mCounting && !mRecords.empty())
{ {
for (std::list<RecordData>::iterator it = mRecords.begin(); it != mRecords.end(); ++it) for (std::list<RecordData>::iterator it = mRecords.begin(); it != mRecords.end(); ++it)
it->size += size; it->size += size;
} }
mStream->write(data, size); mStream->write(data, size);
} }
void ESMWriter::setEncoder(ToUTF8::Utf8Encoder* encoder) void ESMWriter::setEncoder(ToUTF8::Utf8Encoder* encoder)
{ {
mEncoder = encoder; mEncoder = encoder;
} }
} }

@ -1,114 +1,114 @@
#ifndef OPENMW_ESM_WRITER_H #ifndef OPENMW_ESM_WRITER_H
#define OPENMW_ESM_WRITER_H #define OPENMW_ESM_WRITER_H
#include <iosfwd> #include <iosfwd>
#include <list> #include <list>
#include <components/to_utf8/to_utf8.hpp> #include <components/to_utf8/to_utf8.hpp>
#include "esmcommon.hpp" #include "esmcommon.hpp"
#include "loadtes3.hpp" #include "loadtes3.hpp"
namespace ESM { namespace ESM {
class ESMWriter class ESMWriter
{ {
struct RecordData struct RecordData
{ {
std::string name; std::string name;
std::streampos position; std::streampos position;
uint32_t size; uint32_t size;
}; };
public: public:
ESMWriter(); ESMWriter();
unsigned int getVersion() const; unsigned int getVersion() const;
void setVersion(unsigned int ver = 0x3fa66666); void setVersion(unsigned int ver = 0x3fa66666);
void setEncoder(ToUTF8::Utf8Encoder *encoding); void setEncoder(ToUTF8::Utf8Encoder *encoding);
void setAuthor(const std::string& author); void setAuthor(const std::string& author);
void setDescription(const std::string& desc); void setDescription(const std::string& desc);
void setRecordCount (int count); void setRecordCount (int count);
void setFormat (int format); void setFormat (int format);
void clearMaster(); void clearMaster();
void addMaster(const std::string& name, uint64_t size); void addMaster(const std::string& name, uint64_t size);
void save(std::ostream& file); void save(std::ostream& file);
///< Start saving a file by writing the TES3 header. ///< Start saving a file by writing the TES3 header.
void close(); void close();
///< \note Does not close the stream. ///< \note Does not close the stream.
void writeHNString(const std::string& name, const std::string& data); void writeHNString(const std::string& name, const std::string& data);
void writeHNString(const std::string& name, const std::string& data, size_t size); void writeHNString(const std::string& name, const std::string& data, size_t size);
void writeHNCString(const std::string& name, const std::string& data) void writeHNCString(const std::string& name, const std::string& data)
{ {
startSubRecord(name); startSubRecord(name);
writeHCString(data); writeHCString(data);
endRecord(name); endRecord(name);
} }
void writeHNOString(const std::string& name, const std::string& data) void writeHNOString(const std::string& name, const std::string& data)
{ {
if (!data.empty()) if (!data.empty())
writeHNString(name, data); writeHNString(name, data);
} }
void writeHNOCString(const std::string& name, const std::string& data) void writeHNOCString(const std::string& name, const std::string& data)
{ {
if (!data.empty()) if (!data.empty())
writeHNCString(name, data); writeHNCString(name, data);
} }
template<typename T> template<typename T>
void writeHNT(const std::string& name, const T& data) void writeHNT(const std::string& name, const T& data)
{ {
startSubRecord(name); startSubRecord(name);
writeT(data); writeT(data);
endRecord(name); endRecord(name);
} }
template<typename T> template<typename T>
void writeHNT(const std::string& name, const T& data, int size) void writeHNT(const std::string& name, const T& data, int size)
{ {
startSubRecord(name); startSubRecord(name);
writeT(data, size); writeT(data, size);
endRecord(name); endRecord(name);
} }
template<typename T> template<typename T>
void writeT(const T& data) void writeT(const T& data)
{ {
write((char*)&data, sizeof(T)); write((char*)&data, sizeof(T));
} }
template<typename T> template<typename T>
void writeT(const T& data, size_t size) void writeT(const T& data, size_t size)
{ {
write((char*)&data, size); write((char*)&data, size);
} }
void startRecord(const std::string& name, uint32_t flags = 0); void startRecord(const std::string& name, uint32_t flags = 0);
void startRecord(uint32_t name, uint32_t flags = 0); void startRecord(uint32_t name, uint32_t flags = 0);
void startSubRecord(const std::string& name); void startSubRecord(const std::string& name);
void endRecord(const std::string& name); void endRecord(const std::string& name);
void endRecord(uint32_t name); void endRecord(uint32_t name);
void writeHString(const std::string& data); void writeHString(const std::string& data);
void writeHCString(const std::string& data); void writeHCString(const std::string& data);
void writeName(const std::string& data); void writeName(const std::string& data);
void write(const char* data, size_t size); void write(const char* data, size_t size);
private: private:
std::list<RecordData> mRecords; std::list<RecordData> mRecords;
std::ostream* mStream; std::ostream* mStream;
std::streampos mHeaderPos; std::streampos mHeaderPos;
ToUTF8::Utf8Encoder* mEncoder; ToUTF8::Utf8Encoder* mEncoder;
int mRecordCount; int mRecordCount;
bool mCounting; bool mCounting;
Header mHeader; Header mHeader;
}; };
} }
#endif #endif

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save