forked from mirror/openmw-tes3mp
merge upstream changes
parent
d780364842
commit
1ab5948f19
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
|
@ -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()));
|
||||
}
|
||||
|
||||
|
@ -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 <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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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 <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
|
||||
|
||||
|
@ -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&)));
|
||||
}
|
||||
|
@ -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 <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);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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;
|
||||
}
|
@ -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 <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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue