1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-25 15:35:23 +00:00

cleanup the mess...

This commit is contained in:
cc9cii 2014-02-27 23:59:23 +11:00
parent 1ab5948f19
commit 2421f23c2f
20 changed files with 3571 additions and 3557 deletions

View File

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

View File

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

View File

@ -1,63 +1,63 @@
#ifndef TABLEMIMEDATA_H
#define TABLEMIMEDATA_H
#include <vector>
#include <QtCore/QMimeData>
#include <QStringList>
#include "universalid.hpp"
#include "columnbase.hpp"
namespace CSMDoc
{
class Document;
}
namespace CSMWorld
{
/// \brief Subclass of QmimeData, augmented to contain and transport UniversalIds.
///
/// 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.
/// 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.
class TableMimeData : public QMimeData
{
public:
TableMimeData(UniversalId id, const CSMDoc::Document& document);
TableMimeData(std::vector<UniversalId>& id, const CSMDoc::Document& document);
~TableMimeData();
virtual QStringList formats() const;
std::string getIcon() const;
std::vector<UniversalId> getData() const;
bool holdsType(UniversalId::Type type) const;
bool holdsType(CSMWorld::ColumnBase::Display type) const;
bool fromDocument(const CSMDoc::Document& document) const;
UniversalId returnMatching(UniversalId::Type type) const;
UniversalId returnMatching(CSMWorld::ColumnBase::Display type) const;
static CSMWorld::UniversalId::Type convertEnums(CSMWorld::ColumnBase::Display type);
static CSMWorld::ColumnBase::Display convertEnums(CSMWorld::UniversalId::Type type);
private:
std::vector<UniversalId> mUniversalId;
QStringList mObjectsFormats;
const CSMDoc::Document& mDocument;
};
}
#ifndef TABLEMIMEDATA_H
#define TABLEMIMEDATA_H
#include <vector>
#include <QtCore/QMimeData>
#include <QStringList>
#include "universalid.hpp"
#include "columnbase.hpp"
namespace CSMDoc
{
class Document;
}
namespace CSMWorld
{
/// \brief Subclass of QmimeData, augmented to contain and transport UniversalIds.
///
/// 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.
/// 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.
class TableMimeData : public QMimeData
{
public:
TableMimeData(UniversalId id, const CSMDoc::Document& document);
TableMimeData(std::vector<UniversalId>& id, const CSMDoc::Document& document);
~TableMimeData();
virtual QStringList formats() const;
std::string getIcon() const;
std::vector<UniversalId> getData() const;
bool holdsType(UniversalId::Type type) const;
bool holdsType(CSMWorld::ColumnBase::Display type) const;
bool fromDocument(const CSMDoc::Document& document) const;
UniversalId returnMatching(UniversalId::Type type) const;
UniversalId returnMatching(CSMWorld::ColumnBase::Display type) const;
static CSMWorld::UniversalId::Type convertEnums(CSMWorld::ColumnBase::Display type);
static CSMWorld::ColumnBase::Display convertEnums(CSMWorld::UniversalId::Type type);
private:
std::vector<UniversalId> mUniversalId;
QStringList mObjectsFormats;
const CSMDoc::Document& mDocument;
};
}
#endif // TABLEMIMEDATA_H

View File

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

View File

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

View File

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

View File

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

View File

@ -1,32 +1,32 @@
#include "recordfilterbox.hpp"
#include <QHBoxLayout>
#include <QLabel>
#include "editwidget.hpp"
CSVFilter::RecordFilterBox::RecordFilterBox (CSMWorld::Data& data, QWidget *parent)
: QWidget (parent)
{
QHBoxLayout *layout = new QHBoxLayout (this);
layout->setContentsMargins (0, 0, 0, 0);
layout->addWidget (new QLabel ("Record Filter", this));
EditWidget *editWidget = new EditWidget (data, this);
layout->addWidget (editWidget);
setLayout (layout);
connect (
editWidget, 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)),
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&)));
}
#include "recordfilterbox.hpp"
#include <QHBoxLayout>
#include <QLabel>
#include "editwidget.hpp"
CSVFilter::RecordFilterBox::RecordFilterBox (CSMWorld::Data& data, QWidget *parent)
: QWidget (parent)
{
QHBoxLayout *layout = new QHBoxLayout (this);
layout->setContentsMargins (0, 0, 0, 0);
layout->addWidget (new QLabel ("Record Filter", this));
EditWidget *editWidget = new EditWidget (data, this);
layout->addWidget (editWidget);
setLayout (layout);
connect (
editWidget, 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)),
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&)));
}

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

@ -240,17 +240,21 @@ namespace MWMechanics
//target is at far distance: build path to target OR follow target (if previously actor had reached it once)
mFollowTarget = false;
buildNewPath(actor);
buildNewPath(actor); //may fail to build a path, check before use
//delete visited path node
mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2]);
//try shortcut
if(vDir.length() < mPathFinder.getDistToNext(pos.pos[0],pos.pos[1],pos.pos[2]) && MWBase::Environment::get().getWorld()->getLOS(actor, mTarget))
mTargetAngle = Ogre::Radian( Ogre::Math::ACos(vDir.y / vDir.length()) * sgn(Ogre::Math::ASin(vDir.x / vDir.length())) ).valueDegrees();
else
mTargetAngle = mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]);
mRotate = true;
//if no new path leave mTargetAngle unchanged
if(!mPathFinder.getPath().empty())
{
//try shortcut
if(vDir.length() < mPathFinder.getDistToNext(pos.pos[0],pos.pos[1],pos.pos[2]) && MWBase::Environment::get().getWorld()->getLOS(actor, mTarget))
mTargetAngle = Ogre::Radian( Ogre::Math::ACos(vDir.y / vDir.length()) * sgn(Ogre::Math::ASin(vDir.x / vDir.length())) ).valueDegrees();
else
mTargetAngle = mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]);
mRotate = true;
}
mMovement.mPosition[1] = 1;
mReadyToAttack = false;
@ -300,9 +304,13 @@ namespace MWMechanics
dest.mZ = mTarget.getRefData().getPosition().pos[2];
Ogre::Vector3 newPathTarget = Ogre::Vector3(dest.mX, dest.mY, dest.mZ);
ESM::Pathgrid::Point lastPt = mPathFinder.getPath().back();
Ogre::Vector3 currPathTarget(lastPt.mX, lastPt.mY, lastPt.mZ);
float dist = Ogre::Math::Abs((newPathTarget - currPathTarget).length());
float dist = -1; //hack to indicate first time, to construct a new path
if(!mPathFinder.getPath().empty())
{
ESM::Pathgrid::Point lastPt = mPathFinder.getPath().back();
Ogre::Vector3 currPathTarget(lastPt.mX, lastPt.mY, lastPt.mZ);
dist = Ogre::Math::Abs((newPathTarget - currPathTarget).length());
}
float targetPosThreshold;
bool isOutside = actor.getCell()->mCell->isExterior();
@ -311,7 +319,7 @@ namespace MWMechanics
else
targetPosThreshold = 100;
if(dist > targetPosThreshold)
if((dist < 0) || (dist > targetPosThreshold))
{
//construct new path only if target has moved away more than on <targetPosThreshold>
ESM::Position pos = actor.getRefData().getPosition();
@ -332,8 +340,11 @@ namespace MWMechanics
//maybe here is a mistake (?): PathFinder::getPathSize() returns number of grid points in the path,
//not the actual path length. Here we should know if the new path is actually more effective.
//if(pathFinder2.getPathSize() < mPathFinder.getPathSize())
newPathFinder.syncStart(mPathFinder.getPath());
mPathFinder = newPathFinder;
if(!mPathFinder.getPath().empty())
{
newPathFinder.syncStart(mPathFinder.getPath());
mPathFinder = newPathFinder;
}
}
}
}

View File

@ -391,6 +391,8 @@ namespace MWMechanics
void PathFinder::syncStart(const std::list<ESM::Pathgrid::Point> &path)
{
if (mPath.size() < 2)
return; //nothing to pop
std::list<ESM::Pathgrid::Point>::const_iterator oldStart = path.begin();
std::list<ESM::Pathgrid::Point>::iterator iter = ++mPath.begin();

View File

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

View File

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

View File

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

View File

@ -20,6 +20,7 @@ Artem Kotsynyak (greye)
athile
Britt Mathis (galdor557)
BrotherBrick
cc9cii
Chris Robinson (KittyCat)
Cory F. Cohen (cfcohen)
Cris Mihalache (Mirceam)

1902
readme.txt

File diff suppressed because it is too large Load Diff