mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-03 13:45:34 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
c9a8d53240
24 changed files with 522 additions and 44 deletions
|
@ -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"));
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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>);
|
||||||
|
|
110
apps/opencs/model/world/idcompletionmanager.cpp
Normal file
110
apps/opencs/model/world/idcompletionmanager.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
41
apps/opencs/model/world/idcompletionmanager.hpp
Normal file
41
apps/opencs/model/world/idcompletionmanager.hpp
Normal 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
|
|
@ -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())
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
28
apps/opencs/view/widget/completerpopup.cpp
Normal file
28
apps/opencs/view/widget/completerpopup.cpp
Normal 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();
|
||||||
|
}
|
17
apps/opencs/view/widget/completerpopup.hpp
Normal file
17
apps/opencs/view/widget/completerpopup.hpp
Normal 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
|
39
apps/opencs/view/world/idcompletiondelegate.cpp
Normal file
39
apps/opencs/view/world/idcompletiondelegate.cpp
Normal 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);
|
||||||
|
}
|
36
apps/opencs/view/world/idcompletiondelegate.hpp
Normal file
36
apps/opencs/view/world/idcompletiondelegate.hpp
Normal 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
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue