1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-03 16:45:34 +00:00

Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Stanislav Bas 2015-06-07 13:14:50 +03:00
commit c9a8d53240
24 changed files with 522 additions and 44 deletions

View file

@ -490,7 +490,7 @@ bool Launcher::MainDialog::writeSettings()
// Game settings // Game settings
QFile file(userPath + QString("openmw.cfg")); QFile file(userPath + QString("openmw.cfg"));
if (!file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) { if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
// File cannot be opened or created // File cannot be opened or created
QMessageBox msgBox; QMessageBox msgBox;
msgBox.setWindowTitle(tr("Error writing OpenMW configuration file")); msgBox.setWindowTitle(tr("Error writing OpenMW configuration file"));
@ -503,10 +503,8 @@ bool Launcher::MainDialog::writeSettings()
return false; return false;
} }
QTextStream stream(&file);
stream.setCodec(QTextCodec::codecForName("UTF-8"));
mGameSettings.writeFile(stream); mGameSettings.writeFileWithComments(file);
file.close(); file.close();
// Graphics settings // Graphics settings
@ -525,6 +523,7 @@ bool Launcher::MainDialog::writeSettings()
return false; return false;
} }
QTextStream stream(&file);
stream.setDevice(&file); stream.setDevice(&file);
stream.setCodec(QTextCodec::codecForName("UTF-8")); stream.setCodec(QTextCodec::codecForName("UTF-8"));

View file

@ -26,6 +26,7 @@ opencs_units_noqt (model/world
universalid record commands columnbase scriptcontext cell refidcollection universalid record commands columnbase scriptcontext cell refidcollection
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope
pathgrid landtexture land nestedtablewrapper nestedcollection nestedcoladapterimp nestedinfocollection pathgrid landtexture land nestedtablewrapper nestedcollection nestedcoladapterimp nestedinfocollection
idcompletionmanager
) )
opencs_hdrs_noqt (model/world opencs_hdrs_noqt (model/world
@ -68,12 +69,12 @@ opencs_units (view/world
opencs_units_noqt (view/world opencs_units_noqt (view/world
subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate
scripthighlighter idvalidator dialoguecreator physicssystem scripthighlighter idvalidator dialoguecreator physicssystem idcompletiondelegate
) )
opencs_units (view/widget opencs_units (view/widget
scenetoolbar scenetool scenetoolmode pushbutton scenetooltoggle scenetoolrun modebutton scenetoolbar scenetool scenetoolmode pushbutton scenetooltoggle scenetoolrun modebutton
scenetooltoggle2 scenetooltoggle2 completerpopup
) )
opencs_units (view/render opencs_units (view/render

View file

@ -2257,7 +2257,8 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
mSavingOperation (*this, mProjectPath, encoding), mSavingOperation (*this, mProjectPath, encoding),
mSaving (&mSavingOperation), mSaving (&mSavingOperation),
mResDir(resDir), mResDir(resDir),
mRunner (mProjectPath), mPhysics(boost::shared_ptr<CSVWorld::PhysicsSystem>()) mRunner (mProjectPath), mPhysics(boost::shared_ptr<CSVWorld::PhysicsSystem>()),
mIdCompletionManager(mData)
{ {
if (mContentFiles.empty()) if (mContentFiles.empty())
throw std::runtime_error ("Empty content file sequence"); throw std::runtime_error ("Empty content file sequence");
@ -2488,3 +2489,8 @@ boost::shared_ptr<CSVWorld::PhysicsSystem> CSMDoc::Document::getPhysics ()
return mPhysics; return mPhysics;
} }
CSMWorld::IdCompletionManager &CSMDoc::Document::getIdCompletionManager()
{
return mIdCompletionManager;
}

View file

@ -13,6 +13,7 @@
#include <components/to_utf8/to_utf8.hpp> #include <components/to_utf8/to_utf8.hpp>
#include "../world/data.hpp" #include "../world/data.hpp"
#include "../world/idcompletionmanager.hpp"
#include "../tools/tools.hpp" #include "../tools/tools.hpp"
@ -66,6 +67,7 @@ namespace CSMDoc
Blacklist mBlacklist; Blacklist mBlacklist;
Runner mRunner; Runner mRunner;
boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics; boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
CSMWorld::IdCompletionManager mIdCompletionManager;
// It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is // It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is
// using other member variables. Unfortunately this connection is cut only in the QObject destructor, which is way too late. // using other member variables. Unfortunately this connection is cut only in the QObject destructor, which is way too late.
@ -144,6 +146,8 @@ namespace CSMDoc
boost::shared_ptr<CSVWorld::PhysicsSystem> getPhysics(); boost::shared_ptr<CSVWorld::PhysicsSystem> getPhysics();
CSMWorld::IdCompletionManager &getIdCompletionManager();
signals: signals:
void stateChanged (int state, CSMDoc::Document *document); void stateChanged (int state, CSMDoc::Document *document);

View file

@ -65,6 +65,8 @@ bool CSMWorld::ColumnBase::isId (Display display)
Display_JournalInfo, Display_JournalInfo,
Display_Scene, Display_Scene,
Display_GlobalVariable, Display_GlobalVariable,
Display_BodyPart,
Display_Enchantment,
Display_Script, Display_Script,
Display_Mesh, Display_Mesh,

View file

@ -74,6 +74,8 @@ namespace CSMWorld
Display_JournalInfo, Display_JournalInfo,
Display_Scene, Display_Scene,
Display_GlobalVariable, Display_GlobalVariable,
Display_BodyPart,
Display_Enchantment,
//CONCRETE TYPES ENDS HERE //CONCRETE TYPES ENDS HERE
Display_Integer, Display_Integer,

View file

@ -709,7 +709,7 @@ namespace CSMWorld
struct SleepListColumn : public Column<ESXRecordT> struct SleepListColumn : public Column<ESXRecordT>
{ {
SleepListColumn() SleepListColumn()
: Column<ESXRecordT> (Columns::ColumnId_SleepEncounter, ColumnBase::Display_String) : Column<ESXRecordT> (Columns::ColumnId_SleepEncounter, ColumnBase::Display_CreatureLevelledList)
{} {}
virtual QVariant get (const Record<ESXRecordT>& record) const virtual QVariant get (const Record<ESXRecordT>& record) const
@ -735,7 +735,7 @@ namespace CSMWorld
template<typename ESXRecordT> template<typename ESXRecordT>
struct TextureColumn : public Column<ESXRecordT> struct TextureColumn : public Column<ESXRecordT>
{ {
TextureColumn() : Column<ESXRecordT> (Columns::ColumnId_Texture, ColumnBase::Display_String) {} TextureColumn() : Column<ESXRecordT> (Columns::ColumnId_Texture, ColumnBase::Display_Texture) {}
virtual QVariant get (const Record<ESXRecordT>& record) const virtual QVariant get (const Record<ESXRecordT>& record) const
{ {
@ -1269,7 +1269,7 @@ namespace CSMWorld
template<typename ESXRecordT> template<typename ESXRecordT>
struct TrapColumn : public Column<ESXRecordT> struct TrapColumn : public Column<ESXRecordT>
{ {
TrapColumn() : Column<ESXRecordT> (Columns::ColumnId_Trap, ColumnBase::Display_String) {} TrapColumn() : Column<ESXRecordT> (Columns::ColumnId_Trap, ColumnBase::Display_Spell) {}
virtual QVariant get (const Record<ESXRecordT>& record) const virtual QVariant get (const Record<ESXRecordT>& record) const
{ {
@ -1294,7 +1294,7 @@ namespace CSMWorld
template<typename ESXRecordT> template<typename ESXRecordT>
struct FilterColumn : public Column<ESXRecordT> struct FilterColumn : public Column<ESXRecordT>
{ {
FilterColumn() : Column<ESXRecordT> (Columns::ColumnId_Filter, ColumnBase::Display_String) {} FilterColumn() : Column<ESXRecordT> (Columns::ColumnId_Filter, ColumnBase::Display_Filter) {}
virtual QVariant get (const Record<ESXRecordT>& record) const virtual QVariant get (const Record<ESXRecordT>& record) const
{ {
@ -1497,7 +1497,10 @@ namespace CSMWorld
template<typename ESXRecordT> template<typename ESXRecordT>
struct TopicColumn : public Column<ESXRecordT> struct TopicColumn : public Column<ESXRecordT>
{ {
TopicColumn (bool journal) : Column<ESXRecordT> (journal ? Columns::ColumnId_Journal : Columns::ColumnId_Topic, ColumnBase::Display_String) {} TopicColumn (bool journal)
: Column<ESXRecordT> (journal ? Columns::ColumnId_Journal : Columns::ColumnId_Topic,
journal ? ColumnBase::Display_Journal : ColumnBase::Display_Topic)
{}
virtual QVariant get (const Record<ESXRecordT>& record) const virtual QVariant get (const Record<ESXRecordT>& record) const
{ {
@ -1527,7 +1530,7 @@ namespace CSMWorld
template<typename ESXRecordT> template<typename ESXRecordT>
struct ActorColumn : public Column<ESXRecordT> struct ActorColumn : public Column<ESXRecordT>
{ {
ActorColumn() : Column<ESXRecordT> (Columns::ColumnId_Actor, ColumnBase::Display_String) {} ActorColumn() : Column<ESXRecordT> (Columns::ColumnId_Actor, ColumnBase::Display_Npc) {}
virtual QVariant get (const Record<ESXRecordT>& record) const virtual QVariant get (const Record<ESXRecordT>& record) const
{ {
@ -1830,7 +1833,7 @@ namespace CSMWorld
template<typename ESXRecordT> template<typename ESXRecordT>
struct ModelColumn : public Column<ESXRecordT> struct ModelColumn : public Column<ESXRecordT>
{ {
ModelColumn() : Column<ESXRecordT> (Columns::ColumnId_Model, ColumnBase::Display_String) {} ModelColumn() : Column<ESXRecordT> (Columns::ColumnId_Model, ColumnBase::Display_Mesh) {}
virtual QVariant get (const Record<ESXRecordT>& record) const virtual QVariant get (const Record<ESXRecordT>& record) const
{ {
@ -2158,7 +2161,9 @@ namespace CSMWorld
struct EffectTextureColumn : public Column<ESXRecordT> struct EffectTextureColumn : public Column<ESXRecordT>
{ {
EffectTextureColumn (Columns::ColumnId columnId) EffectTextureColumn (Columns::ColumnId columnId)
: Column<ESXRecordT> (columnId, ColumnBase::Display_Texture) : Column<ESXRecordT> (columnId,
columnId == Columns::ColumnId_Particle ? ColumnBase::Display_Texture
: ColumnBase::Display_Icon)
{ {
assert (this->mColumnId==Columns::ColumnId_Icon || assert (this->mColumnId==Columns::ColumnId_Icon ||
this->mColumnId==Columns::ColumnId_Particle); this->mColumnId==Columns::ColumnId_Particle);

View file

@ -115,7 +115,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
index = mFactions.getColumns()-1; index = mFactions.getColumns()-1;
mFactions.addAdapter (std::make_pair(&mFactions.getColumn(index), new FactionReactionsAdapter ())); mFactions.addAdapter (std::make_pair(&mFactions.getColumn(index), new FactionReactionsAdapter ()));
mFactions.getNestableColumn(index)->addColumn( mFactions.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_Faction, ColumnBase::Display_String)); new NestedChildColumn (Columns::ColumnId_Faction, ColumnBase::Display_Faction));
mFactions.getNestableColumn(index)->addColumn( mFactions.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_FactionReaction, ColumnBase::Display_Integer)); new NestedChildColumn (Columns::ColumnId_FactionReaction, ColumnBase::Display_Integer));
@ -135,7 +135,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
index = mRaces.getColumns()-1; index = mRaces.getColumns()-1;
mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new SpellListAdapter<ESM::Race> ())); mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new SpellListAdapter<ESM::Race> ()));
mRaces.getNestableColumn(index)->addColumn( mRaces.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_String)); new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_Spell));
// Race attributes // Race attributes
mRaces.addColumn (new NestedParentColumn<ESM::Race> (Columns::ColumnId_RaceAttributes)); mRaces.addColumn (new NestedParentColumn<ESM::Race> (Columns::ColumnId_RaceAttributes));
index = mRaces.getColumns()-1; index = mRaces.getColumns()-1;
@ -180,7 +180,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
index = mRegions.getColumns()-1; index = mRegions.getColumns()-1;
mRegions.addAdapter (std::make_pair(&mRegions.getColumn(index), new RegionSoundListAdapter ())); mRegions.addAdapter (std::make_pair(&mRegions.getColumn(index), new RegionSoundListAdapter ()));
mRegions.getNestableColumn(index)->addColumn( mRegions.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_SoundName, ColumnBase::Display_String)); new NestedChildColumn (Columns::ColumnId_SoundName, ColumnBase::Display_Sound));
mRegions.getNestableColumn(index)->addColumn( mRegions.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_SoundChance, ColumnBase::Display_Integer)); new NestedChildColumn (Columns::ColumnId_SoundChance, ColumnBase::Display_Integer));
@ -196,7 +196,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
mBirthsigns.addAdapter (std::make_pair(&mBirthsigns.getColumn(index), mBirthsigns.addAdapter (std::make_pair(&mBirthsigns.getColumn(index),
new SpellListAdapter<ESM::BirthSign> ())); new SpellListAdapter<ESM::BirthSign> ()));
mBirthsigns.getNestableColumn(index)->addColumn( mBirthsigns.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_String)); new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_Spell));
mSpells.addColumn (new StringIdColumn<ESM::Spell>); mSpells.addColumn (new StringIdColumn<ESM::Spell>);
mSpells.addColumn (new RecordStateColumn<ESM::Spell>); mSpells.addColumn (new RecordStateColumn<ESM::Spell>);

View file

@ -0,0 +1,110 @@
#include "idcompletionmanager.hpp"
#include <boost/make_shared.hpp>
#include <QCompleter>
#include "../../view/widget/completerpopup.hpp"
#include "data.hpp"
#include "idtablebase.hpp"
namespace
{
std::map<CSMWorld::ColumnBase::Display, CSMWorld::UniversalId::Type> generateModelTypes()
{
std::map<CSMWorld::ColumnBase::Display, CSMWorld::UniversalId::Type> types;
types[CSMWorld::ColumnBase::Display_BodyPart ] = CSMWorld::UniversalId::Type_BodyPart;
types[CSMWorld::ColumnBase::Display_Cell ] = CSMWorld::UniversalId::Type_Cell;
types[CSMWorld::ColumnBase::Display_Class ] = CSMWorld::UniversalId::Type_Class;
types[CSMWorld::ColumnBase::Display_CreatureLevelledList] = CSMWorld::UniversalId::Type_Referenceable;
types[CSMWorld::ColumnBase::Display_Creature ] = CSMWorld::UniversalId::Type_Referenceable;
types[CSMWorld::ColumnBase::Display_Enchantment ] = CSMWorld::UniversalId::Type_Enchantment;
types[CSMWorld::ColumnBase::Display_Faction ] = CSMWorld::UniversalId::Type_Faction;
types[CSMWorld::ColumnBase::Display_GlobalVariable ] = CSMWorld::UniversalId::Type_Global;
types[CSMWorld::ColumnBase::Display_Icon ] = CSMWorld::UniversalId::Type_Icon;
types[CSMWorld::ColumnBase::Display_Mesh ] = CSMWorld::UniversalId::Type_Mesh;
types[CSMWorld::ColumnBase::Display_Miscellaneous ] = CSMWorld::UniversalId::Type_Referenceable;
types[CSMWorld::ColumnBase::Display_Npc ] = CSMWorld::UniversalId::Type_Referenceable;
types[CSMWorld::ColumnBase::Display_Race ] = CSMWorld::UniversalId::Type_Race;
types[CSMWorld::ColumnBase::Display_Region ] = CSMWorld::UniversalId::Type_Region;
types[CSMWorld::ColumnBase::Display_Referenceable ] = CSMWorld::UniversalId::Type_Referenceable;
types[CSMWorld::ColumnBase::Display_Script ] = CSMWorld::UniversalId::Type_Script;
types[CSMWorld::ColumnBase::Display_Skill ] = CSMWorld::UniversalId::Type_Skill;
types[CSMWorld::ColumnBase::Display_Sound ] = CSMWorld::UniversalId::Type_Sound;
types[CSMWorld::ColumnBase::Display_SoundRes ] = CSMWorld::UniversalId::Type_SoundRes;
types[CSMWorld::ColumnBase::Display_Spell ] = CSMWorld::UniversalId::Type_Spell;
types[CSMWorld::ColumnBase::Display_Static ] = CSMWorld::UniversalId::Type_Referenceable;
types[CSMWorld::ColumnBase::Display_Texture ] = CSMWorld::UniversalId::Type_Texture;
types[CSMWorld::ColumnBase::Display_Weapon ] = CSMWorld::UniversalId::Type_Referenceable;
return types;
}
typedef std::map<CSMWorld::ColumnBase::Display,
CSMWorld::UniversalId::Type>::const_iterator ModelTypeConstIterator;
}
const std::map<CSMWorld::ColumnBase::Display, CSMWorld::UniversalId::Type>
CSMWorld::IdCompletionManager::sCompleterModelTypes = generateModelTypes();
std::vector<CSMWorld::ColumnBase::Display> CSMWorld::IdCompletionManager::getDisplayTypes()
{
std::vector<CSMWorld::ColumnBase::Display> types;
ModelTypeConstIterator current = sCompleterModelTypes.begin();
ModelTypeConstIterator end = sCompleterModelTypes.end();
for (; current != end; ++current)
{
types.push_back(current->first);
}
return types;
}
CSMWorld::IdCompletionManager::IdCompletionManager(CSMWorld::Data &data)
{
generateCompleters(data);
}
bool CSMWorld::IdCompletionManager::hasCompleterFor(CSMWorld::ColumnBase::Display display) const
{
return mCompleters.find(display) != mCompleters.end();
}
boost::shared_ptr<QCompleter> CSMWorld::IdCompletionManager::getCompleter(CSMWorld::ColumnBase::Display display)
{
if (!hasCompleterFor(display))
{
throw std::logic_error("This column doesn't have an ID completer");
}
return mCompleters[display];
}
void CSMWorld::IdCompletionManager::generateCompleters(CSMWorld::Data &data)
{
ModelTypeConstIterator current = sCompleterModelTypes.begin();
ModelTypeConstIterator end = sCompleterModelTypes.end();
for (; current != end; ++current)
{
QAbstractItemModel *model = data.getTableModel(current->second);
CSMWorld::IdTableBase *table = dynamic_cast<CSMWorld::IdTableBase *>(model);
if (table != NULL)
{
int idColumn = table->searchColumnIndex(CSMWorld::Columns::ColumnId_Id);
if (idColumn != -1)
{
boost::shared_ptr<QCompleter> completer = boost::make_shared<QCompleter>(table);
completer->setCompletionColumn(idColumn);
// The completion role must be Qt::DisplayRole to get the ID values from the model
completer->setCompletionRole(Qt::DisplayRole);
completer->setCaseSensitivity(Qt::CaseInsensitive);
QAbstractItemView *popup = new CSVWidget::CompleterPopup();
completer->setPopup(popup); // The completer takes ownership of the popup
completer->setMaxVisibleItems(10);
mCompleters[current->first] = completer;
}
}
}
}

View file

@ -0,0 +1,41 @@
#ifndef CSM_WORLD_IDCOMPLETIONMANAGER_HPP
#define CSM_WORLD_IDCOMPLETIONMANAGER_HPP
#include <vector>
#include <map>
#include <boost/shared_ptr.hpp>
#include "columnbase.hpp"
#include "universalid.hpp"
class QCompleter;
namespace CSMWorld
{
class Data;
/// \brief Creates and stores all ID completers
class IdCompletionManager
{
static const std::map<ColumnBase::Display, UniversalId::Type> sCompleterModelTypes;
std::map<ColumnBase::Display, boost::shared_ptr<QCompleter> > mCompleters;
// Don't allow copying
IdCompletionManager(const IdCompletionManager &);
IdCompletionManager &operator = (const IdCompletionManager &);
void generateCompleters(Data &data);
public:
static std::vector<ColumnBase::Display> getDisplayTypes();
IdCompletionManager(Data &data);
bool hasCompleterFor(ColumnBase::Display display) const;
boost::shared_ptr<QCompleter> getCompleter(ColumnBase::Display display);
};
}
#endif

View file

@ -33,6 +33,9 @@ QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const
if (index.row() < 0 || index.column() < 0) if (index.row() < 0 || index.column() < 0)
return QVariant(); return QVariant();
if (role==ColumnBase::Role_Display)
return QVariant(mIdCollection->getColumn(index.column()).mDisplayType);
if (role==ColumnBase::Role_ColumnId) if (role==ColumnBase::Role_ColumnId)
return QVariant (getColumnId (index.column())); return QVariant (getColumnId (index.column()));
@ -84,6 +87,9 @@ bool CSMWorld::IdTable::setData (const QModelIndex &index, const QVariant &value
Qt::ItemFlags CSMWorld::IdTable::flags (const QModelIndex & index) const Qt::ItemFlags CSMWorld::IdTable::flags (const QModelIndex & index) const
{ {
if (!index.isValid())
return 0;
Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
if (mIdCollection->getColumn (index.column()).isUserEditable()) if (mIdCollection->getColumn (index.column()).isUserEditable())

View file

@ -21,6 +21,18 @@ void CSMWorld::IdTableProxyModel::updateColumnMap()
} }
} }
bool CSMWorld::IdTableProxyModel::filterAcceptsColumn (int sourceColumn, const QModelIndex& sourceParent)
const
{
int flags =
sourceModel()->headerData (sourceColumn, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt();
if (flags & CSMWorld::ColumnBase::Flag_Table)
return true;
else
return false;
}
bool CSMWorld::IdTableProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent) bool CSMWorld::IdTableProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent)
const const
{ {

View file

@ -24,8 +24,6 @@ namespace CSMWorld
void updateColumnMap(); void updateColumnMap();
bool filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent) const;
public: public:
IdTableProxyModel (QObject *parent = 0); IdTableProxyModel (QObject *parent = 0);
@ -39,6 +37,10 @@ namespace CSMWorld
protected: protected:
bool lessThan(const QModelIndex &left, const QModelIndex &right) const; bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
virtual bool filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent) const;
virtual bool filterAcceptsColumn (int sourceColumn, const QModelIndex& sourceParent) const;
}; };
} }

View file

@ -35,28 +35,29 @@ QVariant CSMWorld::IdTree::data (const QModelIndex & index, int role) const
if (!index.isValid()) if (!index.isValid())
return QVariant(); return QVariant();
if ((role!=Qt::DisplayRole && role!=Qt::EditRole) || index.row() < 0 || index.column() < 0)
return QVariant();
if (index.internalId() != 0) if (index.internalId() != 0)
{ {
std::pair<int, int> parentAddress(unfoldIndexAddress(index.internalId())); std::pair<int, int> parentAddress(unfoldIndexAddress(index.internalId()));
const NestableColumn *parentColumn = mNestedCollection->getNestableColumn(parentAddress.second);
if (role == Qt::EditRole && if (role == ColumnBase::Role_Display)
!mNestedCollection->getNestableColumn(parentAddress.second)->nestedColumn(index.column()).isEditable()) return parentColumn->nestedColumn(index.column()).mDisplayType;
{
if (role == ColumnBase::Role_ColumnId)
return parentColumn->nestedColumn(index.column()).mColumnId;
if (role == Qt::EditRole && !parentColumn->nestedColumn(index.column()).isEditable())
return QVariant();
if (role != Qt::DisplayRole && role != Qt::EditRole)
return QVariant(); return QVariant();
}
return mNestedCollection->getNestedData(parentAddress.first, return mNestedCollection->getNestedData(parentAddress.first,
parentAddress.second, index.row(), index.column()); parentAddress.second, index.row(), index.column());
} }
else else
{ {
if (role==Qt::EditRole && !idCollection()->getColumn (index.column()).isEditable()) return IdTable::data(index, role);
return QVariant();
return idCollection()->getData (index.row(), index.column());
} }
} }
@ -79,6 +80,9 @@ QVariant CSMWorld::IdTree::nestedHeaderData(int section, int subSection, Qt::Ori
if (role==ColumnBase::Role_Display) if (role==ColumnBase::Role_Display)
return parentColumn->nestedColumn(subSection).mDisplayType; return parentColumn->nestedColumn(subSection).mDisplayType;
if (role==ColumnBase::Role_ColumnId)
return parentColumn->nestedColumn(subSection).mColumnId;
return QVariant(); return QVariant();
} }

View file

@ -99,7 +99,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
EnchantableColumns enchantableColumns (inventoryColumns); EnchantableColumns enchantableColumns (inventoryColumns);
mColumns.push_back (RefIdColumn (Columns::ColumnId_Enchantment, ColumnBase::Display_String)); mColumns.push_back (RefIdColumn (Columns::ColumnId_Enchantment, ColumnBase::Display_Enchantment));
enchantableColumns.mEnchantment = &mColumns.back(); enchantableColumns.mEnchantment = &mColumns.back();
mColumns.push_back (RefIdColumn (Columns::ColumnId_EnchantmentPoints, ColumnBase::Display_Integer)); mColumns.push_back (RefIdColumn (Columns::ColumnId_EnchantmentPoints, ColumnBase::Display_Integer));
enchantableColumns.mEnchantmentPoints = &mColumns.back(); enchantableColumns.mEnchantmentPoints = &mColumns.back();
@ -135,7 +135,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
new NestedInventoryRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature))); new NestedInventoryRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature)));
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), inventoryMap)); mNestedAdapters.push_back (std::make_pair(&mColumns.back(), inventoryMap));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String)); new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_Referenceable));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer)); new RefIdColumn (Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer));
@ -150,7 +150,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
new NestedSpellRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature))); new NestedSpellRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature)));
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), spellsMap)); mNestedAdapters.push_back (std::make_pair(&mColumns.back(), spellsMap));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_String)); new RefIdColumn (Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_Spell));
// Nested table // Nested table
mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcDestinations, mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcDestinations,
@ -163,7 +163,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
new NestedTravelRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature))); new NestedTravelRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature)));
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), destMap)); mNestedAdapters.push_back (std::make_pair(&mColumns.back(), destMap));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_String)); new RefIdColumn (Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_Cell));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float)); new RefIdColumn (Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float));
mColumns.back().addColumn( mColumns.back().addColumn(
@ -289,7 +289,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
new NestedInventoryRefIdAdapter<ESM::Container> (UniversalId::Type_Container))); new NestedInventoryRefIdAdapter<ESM::Container> (UniversalId::Type_Container)));
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), contMap)); mNestedAdapters.push_back (std::make_pair(&mColumns.back(), contMap));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String)); new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_Referenceable));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer)); new RefIdColumn (Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer));
@ -301,7 +301,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
creatureColumns.mSoul = &mColumns.back(); creatureColumns.mSoul = &mColumns.back();
mColumns.push_back (RefIdColumn (Columns::ColumnId_Scale, ColumnBase::Display_Float)); mColumns.push_back (RefIdColumn (Columns::ColumnId_Scale, ColumnBase::Display_Float));
creatureColumns.mScale = &mColumns.back(); creatureColumns.mScale = &mColumns.back();
mColumns.push_back (RefIdColumn (Columns::ColumnId_OriginalCreature, ColumnBase::Display_String)); mColumns.push_back (RefIdColumn (Columns::ColumnId_OriginalCreature, ColumnBase::Display_Creature));
creatureColumns.mOriginal = &mColumns.back(); creatureColumns.mOriginal = &mColumns.back();
mColumns.push_back ( mColumns.push_back (
RefIdColumn (Columns::ColumnId_CombatState, ColumnBase::Display_Integer)); RefIdColumn (Columns::ColumnId_CombatState, ColumnBase::Display_Integer));
@ -409,10 +409,10 @@ CSMWorld::RefIdCollection::RefIdCollection()
mColumns.push_back (RefIdColumn (Columns::ColumnId_Faction, ColumnBase::Display_Faction)); mColumns.push_back (RefIdColumn (Columns::ColumnId_Faction, ColumnBase::Display_Faction));
npcColumns.mFaction = &mColumns.back(); npcColumns.mFaction = &mColumns.back();
mColumns.push_back (RefIdColumn (Columns::Columnid_Hair, ColumnBase::Display_String)); mColumns.push_back (RefIdColumn (Columns::Columnid_Hair, ColumnBase::Display_BodyPart));
npcColumns.mHair = &mColumns.back(); npcColumns.mHair = &mColumns.back();
mColumns.push_back (RefIdColumn (Columns::ColumnId_Head, ColumnBase::Display_String)); mColumns.push_back (RefIdColumn (Columns::ColumnId_Head, ColumnBase::Display_BodyPart));
npcColumns.mHead = &mColumns.back(); npcColumns.mHead = &mColumns.back();
mColumns.push_back (RefIdColumn (Columns::ColumnId_Female, ColumnBase::Display_Boolean)); mColumns.push_back (RefIdColumn (Columns::ColumnId_Female, ColumnBase::Display_Boolean));
@ -539,9 +539,9 @@ CSMWorld::RefIdCollection::RefIdCollection()
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_PartRefType, CSMWorld::ColumnBase::Display_PartRefType)); new RefIdColumn (Columns::ColumnId_PartRefType, CSMWorld::ColumnBase::Display_PartRefType));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_PartRefMale, CSMWorld::ColumnBase::Display_String)); new RefIdColumn (Columns::ColumnId_PartRefMale, CSMWorld::ColumnBase::Display_BodyPart));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_PartRefFemale, CSMWorld::ColumnBase::Display_String)); new RefIdColumn (Columns::ColumnId_PartRefFemale, CSMWorld::ColumnBase::Display_BodyPart));
LevListColumns levListColumns (baseColumns); LevListColumns levListColumns (baseColumns);
@ -556,7 +556,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
new NestedLevListRefIdAdapter<ESM::ItemLevList> (UniversalId::Type_ItemLevelledList))); new NestedLevListRefIdAdapter<ESM::ItemLevList> (UniversalId::Type_ItemLevelledList)));
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), levListMap)); mNestedAdapters.push_back (std::make_pair(&mColumns.back(), levListMap));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_LevelledItemId, CSMWorld::ColumnBase::Display_String)); new RefIdColumn (Columns::ColumnId_LevelledItemId, CSMWorld::ColumnBase::Display_Referenceable));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_LevelledItemLevel, CSMWorld::ColumnBase::Display_Integer)); new RefIdColumn (Columns::ColumnId_LevelledItemLevel, CSMWorld::ColumnBase::Display_Integer));

View file

@ -1,6 +1,7 @@
#include "viewmanager.hpp" #include "viewmanager.hpp"
#include <vector>
#include <map> #include <map>
#include <QApplication> #include <QApplication>
@ -10,12 +11,14 @@
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/world/columns.hpp" #include "../../model/world/columns.hpp"
#include "../../model/world/universalid.hpp" #include "../../model/world/universalid.hpp"
#include "../../model/world/idcompletionmanager.hpp"
#include "../world/util.hpp" #include "../world/util.hpp"
#include "../world/enumdelegate.hpp" #include "../world/enumdelegate.hpp"
#include "../world/vartypedelegate.hpp" #include "../world/vartypedelegate.hpp"
#include "../world/recordstatusdelegate.hpp" #include "../world/recordstatusdelegate.hpp"
#include "../world/idtypedelegate.hpp" #include "../world/idtypedelegate.hpp"
#include "../world/idcompletiondelegate.hpp"
#include "../../model/settings/usersettings.hpp" #include "../../model/settings/usersettings.hpp"
@ -60,6 +63,14 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
mDelegateFactories->add (CSMWorld::ColumnBase::Display_RefRecordType, mDelegateFactories->add (CSMWorld::ColumnBase::Display_RefRecordType,
new CSVWorld::IdTypeDelegateFactory()); new CSVWorld::IdTypeDelegateFactory());
std::vector<CSMWorld::ColumnBase::Display> idCompletionColumns = CSMWorld::IdCompletionManager::getDisplayTypes();
for (std::vector<CSMWorld::ColumnBase::Display>::const_iterator current = idCompletionColumns.begin();
current != idCompletionColumns.end();
++current)
{
mDelegateFactories->add(*current, new CSVWorld::IdCompletionDelegateFactory());
}
struct Mapping struct Mapping
{ {
CSMWorld::ColumnBase::Display mDisplay; CSMWorld::ColumnBase::Display mDisplay;

View file

@ -0,0 +1,28 @@
#include "completerpopup.hpp"
CSVWidget::CompleterPopup::CompleterPopup(QWidget *parent)
: QListView(parent)
{
setEditTriggers(QAbstractItemView::NoEditTriggers);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setSelectionBehavior(QAbstractItemView::SelectRows);
setSelectionMode(QAbstractItemView::SingleSelection);
}
int CSVWidget::CompleterPopup::sizeHintForRow(int row) const
{
if (model() == NULL)
{
return -1;
}
if (row < 0 || row >= model()->rowCount())
{
return -1;
}
ensurePolished();
QModelIndex index = model()->index(row, modelColumn());
QStyleOptionViewItem option = viewOptions();
QAbstractItemDelegate *delegate = itemDelegate(index);
return delegate->sizeHint(option, index).height();
}

View file

@ -0,0 +1,17 @@
#ifndef CSV_WIDGET_COMPLETERPOPUP_HPP
#define CSV_WIDGET_COMPLETERPOPUP_HPP
#include <QListView>
namespace CSVWidget
{
class CompleterPopup : public QListView
{
public:
CompleterPopup(QWidget *parent = 0);
virtual int sizeHintForRow(int row) const;
};
}
#endif

View file

@ -0,0 +1,39 @@
#include "idcompletiondelegate.hpp"
#include "../../model/world/idcompletionmanager.hpp"
CSVWorld::IdCompletionDelegate::IdCompletionDelegate(CSMWorld::CommandDispatcher *dispatcher,
CSMDoc::Document& document,
QObject *parent)
: CommandDelegate(dispatcher, document, parent)
{}
QWidget *CSVWorld::IdCompletionDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
return createEditor(parent, option, index, getDisplayTypeFromIndex(index));
}
QWidget *CSVWorld::IdCompletionDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index,
CSMWorld::ColumnBase::Display display) const
{
if (!index.data(Qt::EditRole).isValid() && !index.data(Qt::DisplayRole).isValid())
{
return NULL;
}
CSMWorld::IdCompletionManager &completionManager = getDocument().getIdCompletionManager();
DropLineEdit *editor = new DropLineEdit(parent);
editor->setCompleter(completionManager.getCompleter(display).get());
return editor;
}
CSVWorld::CommandDelegate *CSVWorld::IdCompletionDelegateFactory::makeDelegate(CSMWorld::CommandDispatcher *dispatcher,
CSMDoc::Document& document,
QObject *parent) const
{
return new IdCompletionDelegate(dispatcher, document, parent);
}

View file

@ -0,0 +1,36 @@
#ifndef CSV_WORLD_IDCOMPLETIONDELEGATE_HPP
#define CSV_WORLD_IDCOMPLETIONDELEGATE_HPP
#include "util.hpp"
namespace CSVWorld
{
/// \brief Enables the Id completion for a column
class IdCompletionDelegate : public CommandDelegate
{
public:
IdCompletionDelegate(CSMWorld::CommandDispatcher *dispatcher,
CSMDoc::Document& document,
QObject *parent);
virtual QWidget *createEditor (QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const;
virtual QWidget *createEditor (QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index,
CSMWorld::ColumnBase::Display display) const;
};
class IdCompletionDelegateFactory : public CommandDelegateFactory
{
public:
virtual CommandDelegate *makeDelegate(CSMWorld::CommandDispatcher *dispatcher,
CSMDoc::Document& document,
QObject *parent) const;
///< The ownership of the returned CommandDelegate is transferred to the caller.
};
}
#endif

View file

@ -111,6 +111,12 @@ CSMDoc::Document& CSVWorld::CommandDelegate::getDocument() const
return mDocument; return mDocument;
} }
CSMWorld::ColumnBase::Display CSVWorld::CommandDelegate::getDisplayTypeFromIndex(const QModelIndex &index) const
{
int rawDisplay = index.data(CSMWorld::ColumnBase::Role_Display).toInt();
return static_cast<CSMWorld::ColumnBase::Display>(rawDisplay);
}
void CSVWorld::CommandDelegate::setModelDataImp (QWidget *editor, QAbstractItemModel *model, void CSVWorld::CommandDelegate::setModelDataImp (QWidget *editor, QAbstractItemModel *model,
const QModelIndex& index) const const QModelIndex& index) const
{ {
@ -146,7 +152,17 @@ void CSVWorld::CommandDelegate::setModelData (QWidget *editor, QAbstractItemMode
QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem& option, QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem& option,
const QModelIndex& index) const const QModelIndex& index) const
{ {
return createEditor (parent, option, index, CSMWorld::ColumnBase::Display_None); CSMWorld::ColumnBase::Display display = getDisplayTypeFromIndex(index);
// This createEditor() method is called implicitly from tables.
// For boolean values in tables use the default editor (combobox).
// Checkboxes is looking ugly in the table view.
// TODO: Find a better solution?
if (display == CSMWorld::ColumnBase::Display_Boolean)
{
return QStyledItemDelegate::createEditor(parent, option, index);
}
return createEditor (parent, option, index, display);
} }
QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem& option, QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem& option,

View file

@ -124,6 +124,8 @@ namespace CSVWorld
CSMDoc::Document& getDocument() const; CSMDoc::Document& getDocument() const;
CSMWorld::ColumnBase::Display getDisplayTypeFromIndex(const QModelIndex &index) const;
virtual void setModelDataImp (QWidget *editor, QAbstractItemModel *model, virtual void setModelDataImp (QWidget *editor, QAbstractItemModel *model,
const QModelIndex& index) const; const QModelIndex& index) const;

View file

@ -1,6 +1,7 @@
#include "gamesettings.hpp" #include "gamesettings.hpp"
#include "launchersettings.hpp" #include "launchersettings.hpp"
#include <QTextCodec>
#include <QTextStream> #include <QTextStream>
#include <QDir> #include <QDir>
#include <QString> #include <QString>
@ -173,6 +174,138 @@ bool Config::GameSettings::writeFile(QTextStream &stream)
return true; return true;
} }
// Policy:
//
// - Always ignore a line beginning with '#' or empty lines
//
// - If a line in file exists with matching key and first part of value (before ',',
// '\n', etc) also matches, then replace the line with that of mUserSettings.
// - else remove line (TODO: maybe replace the line with '#' in front instead?)
//
// - If there is no corresponding line in file, add at the end
//
bool Config::GameSettings::writeFileWithComments(QFile &file)
{
QTextStream stream(&file);
stream.setCodec(QTextCodec::codecForName("UTF-8"));
// slurp
std::vector<QString> fileCopy;
QString line = stream.readLine();
while (!line.isNull())
{
fileCopy.push_back(line);
line = stream.readLine();
}
stream.seek(0);
// empty file, no comments to keep
if (fileCopy.empty())
return writeFile(stream);
// Temp copy of settings to save, but with the keys appended with the first part of the value
//
// ATTENTION!
//
// A hack to avoid looping through each line, makes use of the fact that fallbacks values
// are comma separated.
QMap<QString, QString> userSettingsCopy;
QRegExp settingRegex("^([^=]+)\\s*=\\s*([^,]+)(.*)$");
QString settingLine;
QMap<QString, QString>::const_iterator settingsIter = mUserSettings.begin();
for (; settingsIter != mUserSettings.end(); ++settingsIter)
{
settingLine = settingsIter.key()+"="+settingsIter.value();
if (settingRegex.indexIn(settingLine) != -1)
{
userSettingsCopy[settingRegex.cap(1)+"="+settingRegex.cap(2)] =
(settingRegex.captureCount() < 3) ? "" : settingRegex.cap(3);
}
}
QString keyVal;
for (std::vector<QString>::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter)
{
// skip empty or comment lines
if ((*iter).isEmpty() || (*iter).contains(QRegExp("^\\s*#")))
continue;
// look for a key in the line
if (settingRegex.indexIn(*iter) == -1 || settingRegex.captureCount() < 2)
{
// no key or first part of value found in line, replace with a null string which
// will be remved later
*iter = QString();
continue;
}
// look for a matching key in user settings
keyVal = settingRegex.cap(1)+"="+settingRegex.cap(2);
QMap<QString, QString>::iterator it = userSettingsCopy.find(keyVal);
if (it == userSettingsCopy.end())
{
// no such key+valStart, replace with a null string which will be remved later
*iter = QString();
}
else
{
*iter = QString(it.key()+it.value());
userSettingsCopy.erase(it);
}
}
// write the new config file
QString key;
QString value;
for (std::vector<QString>::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter)
{
if ((*iter).isNull())
continue;
// Below is based on readFile() code, if that changes corresponding change may be
// required (for example duplicates may be inserted if the rules don't match)
if ((*iter).isEmpty() || (*iter).contains(QRegExp("^\\s*#")))
{
stream << *iter << "\n";
continue;
}
if (settingRegex.indexIn(*iter) == -1 || settingRegex.captureCount() < 2)
continue;
// Quote paths with spaces
key = settingRegex.cap(1);
value = settingRegex.cap(2)+settingRegex.cap(3);
if (key == QLatin1String("data")
|| key == QLatin1String("data-local")
|| key == QLatin1String("resources"))
{
if (value.contains(QChar(' ')))
{
value.remove(QChar('\"')); // Remove quotes
stream << key << "=\"" << value << "\"\n";
continue;
}
}
stream << key << "=" << value << "\n";
}
if (!userSettingsCopy.empty())
{
stream << "# new entries" << "\n";
QMap<QString, QString>::const_iterator it = userSettingsCopy.begin();
for (; it != userSettingsCopy.end(); ++it)
{
stream << it.key() << it.value() << "\n";
}
}
file.resize(file.pos());
return true;
}
bool Config::GameSettings::hasMaster() bool Config::GameSettings::hasMaster()
{ {
bool result = false; bool result = false;

View file

@ -4,6 +4,7 @@
#include <QTextStream> #include <QTextStream>
#include <QStringList> #include <QStringList>
#include <QString> #include <QString>
#include <QFile>
#include <QMap> #include <QMap>
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
@ -66,6 +67,7 @@ namespace Config
bool readUserFile(QTextStream &stream); bool readUserFile(QTextStream &stream);
bool writeFile(QTextStream &stream); bool writeFile(QTextStream &stream);
bool writeFileWithComments(QFile &file);
void setContentList(const QStringList& fileNames); void setContentList(const QStringList& fileNames);
QStringList getContentList() const; QStringList getContentList() const;