Merge branch 'master' into pathgrid-edit

This commit is contained in:
cc9cii 2015-06-07 20:15:58 +10:00
commit 92ab61f72f
54 changed files with 637 additions and 81 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

@ -27,6 +27,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
@ -69,12 +70,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

@ -8,16 +8,6 @@
#include "../world/subcellcollection.hpp" #include "../world/subcellcollection.hpp"
#include "../world/pathgrid.hpp" #include "../world/pathgrid.hpp"
namespace
{
struct Point
{
unsigned char mConnectionNum;
std::vector<int> mOtherIndex;
Point() : mConnectionNum(0), mOtherIndex(0) {}
};
}
CSMTools::PathgridCheckStage::PathgridCheckStage (const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids) CSMTools::PathgridCheckStage::PathgridCheckStage (const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids)
: mPathgrids (pathgrids) : mPathgrids (pathgrids)
{} {}
@ -44,7 +34,7 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message
else if (pathgrid.mData.mS2 > static_cast<int>(pathgrid.mPoints.size())) else if (pathgrid.mData.mS2 > static_cast<int>(pathgrid.mPoints.size()))
messages.push_back (std::make_pair (id, pathgrid.mId + " has more points than expected")); messages.push_back (std::make_pair (id, pathgrid.mId + " has more points than expected"));
std::vector<Point> pointList(pathgrid.mPoints.size()); std::vector<CSMTools::Point> pointList(pathgrid.mPoints.size());
std::vector<int> duplList; std::vector<int> duplList;
for (unsigned int i = 0; i < pathgrid.mEdges.size(); ++i) for (unsigned int i = 0; i < pathgrid.mEdges.size(); ++i)

View File

@ -14,17 +14,26 @@ namespace CSMWorld
namespace CSMTools namespace CSMTools
{ {
struct Point
{
unsigned char mConnectionNum;
std::vector<int> mOtherIndex;
Point() : mConnectionNum(0), mOtherIndex(0) {}
};
class PathgridCheckStage : public CSMDoc::Stage class PathgridCheckStage : public CSMDoc::Stage
{ {
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid, CSMWorld::IdAccessor<CSMWorld::Pathgrid> >& mPathgrids; const CSMWorld::SubCellCollection<CSMWorld::Pathgrid,
CSMWorld::IdAccessor<CSMWorld::Pathgrid> >& mPathgrids;
public: public:
PathgridCheckStage (const CSMWorld::SubCellCollection<CSMWorld::Pathgrid, CSMWorld::IdAccessor<CSMWorld::Pathgrid> >& pathgrids); PathgridCheckStage (const CSMWorld::SubCellCollection<CSMWorld::Pathgrid,
CSMWorld::IdAccessor<CSMWorld::Pathgrid> >& pathgrids);
virtual int setup(); virtual int setup();
virtual void perform (int stage, CSMDoc::Messages& messages); virtual void perform (int stage, CSMDoc::Messages& messages);
}; };
} }

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

@ -147,7 +147,7 @@ namespace MWClass
if (ptr.getCellRef().getTeleport()) if (ptr.getCellRef().getTeleport())
{ {
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTeleport (ptr.getCellRef().getDestCell(), ptr.getCellRef().getDoorDest())); boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTeleport (ptr.getCellRef().getDestCell(), ptr.getCellRef().getDoorDest(), true));
action->setSound(openSound); action->setSound(openSound);

View File

@ -130,6 +130,7 @@ namespace MWGui
mSortModel = new SortFilterItemModel(model); mSortModel = new SortFilterItemModel(model);
mSortModel->setFilter(SortFilterItemModel::Filter_OnlyIngredients); mSortModel->setFilter(SortFilterItemModel::Filter_OnlyIngredients);
mItemView->setModel (mSortModel); mItemView->setModel (mSortModel);
mItemView->resetScrollBars();
mNameEdit->setCaption(""); mNameEdit->setCaption("");

View File

@ -114,6 +114,7 @@ void CompanionWindow::open(const MWWorld::Ptr& npc)
mModel = new CompanionItemModel(npc); mModel = new CompanionItemModel(npc);
mSortModel = new SortFilterItemModel(mModel); mSortModel = new SortFilterItemModel(mModel);
mItemView->setModel(mSortModel); mItemView->setModel(mSortModel);
mItemView->resetScrollBars();
setTitle(npc.getClass().getName(npc)); setTitle(npc.getClass().getName(npc));
} }

View File

@ -151,6 +151,7 @@ namespace MWGui
mSortModel = new SortFilterItemModel(mModel); mSortModel = new SortFilterItemModel(mModel);
mItemView->setModel (mSortModel); mItemView->setModel (mSortModel);
mItemView->resetScrollBars();
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton); MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton);

View File

@ -291,7 +291,10 @@ namespace MWGui
MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu);
} }
else else
{
MWBase::Environment::get().getDialogueManager()->goodbyeSelected(); MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
mTopicsList->scrollToTop();
}
} }
void DialogueWindow::onWindowResize(MyGUI::Window* _sender) void DialogueWindow::onWindowResize(MyGUI::Window* _sender)

View File

@ -39,6 +39,7 @@ namespace MWGui
mModel = new InventoryItemModel(container); mModel = new InventoryItemModel(container);
mSortModel = new SortFilterItemModel(mModel); mSortModel = new SortFilterItemModel(mModel);
mItemView->setModel(mSortModel); mItemView->setModel(mSortModel);
mItemView->resetScrollBars();
} }
void ItemSelectionDialog::setCategory(int category) void ItemSelectionDialog::setCategory(int category)

View File

@ -128,6 +128,11 @@ void ItemView::update()
layoutWidgets(); layoutWidgets();
} }
void ItemView::resetScrollBars()
{
mScrollView->setViewOffset(MyGUI::IntPoint(0, 0));
}
void ItemView::onSelectedItem(MyGUI::Widget *sender) void ItemView::onSelectedItem(MyGUI::Widget *sender)
{ {
ItemModel::ModelIndex index = (*sender->getUserData<std::pair<ItemModel::ModelIndex, ItemModel*> >()).first; ItemModel::ModelIndex index = (*sender->getUserData<std::pair<ItemModel::ModelIndex, ItemModel*> >()).first;

View File

@ -30,6 +30,8 @@ namespace MWGui
void update(); void update();
void resetScrollBars();
private: private:
virtual void initialiseOverride(); virtual void initialiseOverride();

View File

@ -114,6 +114,8 @@ void MerchantRepair::onMouseWheel(MyGUI::Widget* _sender, int _rel)
void MerchantRepair::open() void MerchantRepair::open()
{ {
center(); center();
// Reset scrollbars
mList->setViewOffset(MyGUI::IntPoint(0, 0));
} }
void MerchantRepair::exit() void MerchantRepair::exit()

View File

@ -548,6 +548,7 @@ namespace MWGui
WindowModal::open(); WindowModal::open();
mMagicList->setModel(new SpellModel(MWBase::Environment::get().getWorld()->getPlayerPtr())); mMagicList->setModel(new SpellModel(MWBase::Environment::get().getWorld()->getPlayerPtr()));
mMagicList->resetScrollbars();
} }
void MagicSelectionDialog::onModelIndexSelected(SpellModel::ModelIndex index) void MagicSelectionDialog::onModelIndexSelected(SpellModel::ModelIndex index)

View File

@ -44,6 +44,8 @@ Recharge::Recharge()
void Recharge::open() void Recharge::open()
{ {
center(); center();
// Reset scrollbars
mView->setViewOffset(MyGUI::IntPoint(0, 0));
} }
void Recharge::exit() void Recharge::exit()

View File

@ -36,6 +36,8 @@ Repair::Repair()
void Repair::open() void Repair::open()
{ {
center(); center();
// Reset scrollbars
mRepairView->setViewOffset(MyGUI::IntPoint(0, 0));
} }
void Repair::exit() void Repair::exit()

View File

@ -8,6 +8,7 @@
#include <MyGUI_ListBox.h> #include <MyGUI_ListBox.h>
#include <MyGUI_ScrollView.h> #include <MyGUI_ScrollView.h>
#include <MyGUI_Gui.h> #include <MyGUI_Gui.h>
#include <MyGUI_TabControl.h>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/math/common_factor_rt.hpp> #include <boost/math/common_factor_rt.hpp>
@ -170,6 +171,7 @@ namespace MWGui
setTitle("#{sOptions}"); setTitle("#{sOptions}");
getWidget(mSettingsTab, "SettingsTab");
getWidget(mOkButton, "OkButton"); getWidget(mOkButton, "OkButton");
getWidget(mResolutionList, "ResolutionList"); getWidget(mResolutionList, "ResolutionList");
getWidget(mFullscreenButton, "FullscreenButton"); getWidget(mFullscreenButton, "FullscreenButton");
@ -208,6 +210,7 @@ namespace MWGui
mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &SettingsWindow::onWindowResize); mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &SettingsWindow::onWindowResize);
mSettingsTab->eventTabChangeSelect += MyGUI::newDelegate(this, &SettingsWindow::onTabChanged);
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked); mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked);
mShaderModeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShaderModeToggled); mShaderModeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShaderModeToggled);
mTextureFilteringButton->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onTextureFilteringChanged); mTextureFilteringButton->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onTextureFilteringChanged);
@ -275,6 +278,11 @@ namespace MWGui
mControllerSwitch->setStateSelected(false); mControllerSwitch->setStateSelected(false);
} }
void SettingsWindow::onTabChanged(MyGUI::TabControl* /*_sender*/, size_t /*index*/)
{
resetScrollbars();
}
void SettingsWindow::onOkButtonClicked(MyGUI::Widget* _sender) void SettingsWindow::onOkButtonClicked(MyGUI::Widget* _sender)
{ {
exit(); exit();
@ -480,6 +488,7 @@ namespace MWGui
mKeyboardSwitch->setStateSelected(true); mKeyboardSwitch->setStateSelected(true);
mControllerSwitch->setStateSelected(false); mControllerSwitch->setStateSelected(false);
updateControlsBox(); updateControlsBox();
resetScrollbars();
} }
void SettingsWindow::onControllerSwitchClicked(MyGUI::Widget* _sender) void SettingsWindow::onControllerSwitchClicked(MyGUI::Widget* _sender)
@ -490,6 +499,7 @@ namespace MWGui
mKeyboardSwitch->setStateSelected(false); mKeyboardSwitch->setStateSelected(false);
mControllerSwitch->setStateSelected(true); mControllerSwitch->setStateSelected(true);
updateControlsBox(); updateControlsBox();
resetScrollbars();
} }
void SettingsWindow::updateControlsBox() void SettingsWindow::updateControlsBox()
@ -584,6 +594,7 @@ namespace MWGui
void SettingsWindow::open() void SettingsWindow::open()
{ {
updateControlsBox (); updateControlsBox ();
resetScrollbars();
} }
void SettingsWindow::exit() void SettingsWindow::exit()
@ -595,4 +606,10 @@ namespace MWGui
{ {
updateControlsBox(); updateControlsBox();
} }
void SettingsWindow::resetScrollbars()
{
mResolutionList->setScrollPosition(0);
mControlsBox->setViewOffset(MyGUI::IntPoint(0, 0));
}
} }

View File

@ -22,6 +22,7 @@ namespace MWGui
void updateControlsBox(); void updateControlsBox();
protected: protected:
MyGUI::TabControl* mSettingsTab;
MyGUI::Button* mOkButton; MyGUI::Button* mOkButton;
// graphics // graphics
@ -50,6 +51,7 @@ namespace MWGui
MyGUI::Button* mControllerSwitch; MyGUI::Button* mControllerSwitch;
bool mKeyboardMode; //if true, setting up the keyboard. Otherwise, it's controller bool mKeyboardMode; //if true, setting up the keyboard. Otherwise, it's controller
void onTabChanged(MyGUI::TabControl* _sender, size_t index);
void onOkButtonClicked(MyGUI::Widget* _sender); void onOkButtonClicked(MyGUI::Widget* _sender);
void onFpsToggled(MyGUI::Widget* _sender); void onFpsToggled(MyGUI::Widget* _sender);
void onTextureFilteringChanged(MyGUI::ComboBox* _sender, size_t pos); void onTextureFilteringChanged(MyGUI::ComboBox* _sender, size_t pos);
@ -74,6 +76,9 @@ namespace MWGui
void apply(); void apply();
void configureWidgets(MyGUI::Widget* widget); void configureWidgets(MyGUI::Widget* widget);
private:
void resetScrollbars();
}; };
} }

View File

@ -551,6 +551,7 @@ namespace MWGui
++i; ++i;
} }
mAvailableEffectsList->adjustSize (); mAvailableEffectsList->adjustSize ();
mAvailableEffectsList->scrollToTop();
for (std::vector<short>::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it) for (std::vector<short>::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it)
{ {

View File

@ -311,4 +311,8 @@ namespace MWGui
mScrollView->setViewOffset(MyGUI::IntPoint(0, static_cast<int>(mScrollView->getViewOffset().top + _rel*0.3f))); mScrollView->setViewOffset(MyGUI::IntPoint(0, static_cast<int>(mScrollView->getViewOffset().top + _rel*0.3f)));
} }
void SpellView::resetScrollbars()
{
mScrollView->setViewOffset(MyGUI::IntPoint(0, 0));
}
} }

View File

@ -51,6 +51,8 @@ namespace MWGui
virtual void setSize(const MyGUI::IntSize& _value); virtual void setSize(const MyGUI::IntSize& _value);
virtual void setCoord(const MyGUI::IntCoord& _value); virtual void setCoord(const MyGUI::IntCoord& _value);
void resetScrollbars();
private: private:
MyGUI::ScrollView* mScrollView; MyGUI::ScrollView* mScrollView;

View File

@ -136,6 +136,7 @@ namespace MWGui
mTradeModel = new TradeItemModel(new ContainerItemModel(itemSources, worldItems), mPtr); mTradeModel = new TradeItemModel(new ContainerItemModel(itemSources, worldItems), mPtr);
mSortModel = new SortFilterItemModel(mTradeModel); mSortModel = new SortFilterItemModel(mTradeModel);
mItemView->setModel (mSortModel); mItemView->setModel (mSortModel);
mItemView->resetScrollBars();
updateLabels(); updateLabels();

View File

@ -183,7 +183,7 @@ namespace MWGui
MWBase::Environment::get().getDialogueManager()->goodbyeSelected(); MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
// Teleports any followers, too. // Teleports any followers, too.
MWWorld::ActionTeleport action(interior ? cellname : "", pos); MWWorld::ActionTeleport action(interior ? cellname : "", pos, true);
action.execute(player); action.execute(player);
MWBase::Environment::get().getWindowManager()->fadeScreenOut(0); MWBase::Environment::get().getWindowManager()->fadeScreenOut(0);

View File

@ -679,7 +679,7 @@ namespace MWMechanics
if (markedCell) if (markedCell)
{ {
MWWorld::ActionTeleport action(markedCell->isExterior() ? "" : markedCell->getCell()->mName, MWWorld::ActionTeleport action(markedCell->isExterior() ? "" : markedCell->getCell()->mName,
markedPosition); markedPosition, false);
action.execute(target); action.execute(target);
} }
} }

View File

@ -196,7 +196,11 @@ const NpcAnimation::PartBoneMap NpcAnimation::sPartList = createPartListMap();
NpcAnimation::~NpcAnimation() NpcAnimation::~NpcAnimation()
{ {
if (!mListenerDisabled) if (!mListenerDisabled
// No need to getInventoryStore() to reset, if none exists
// This is to avoid triggering the listener via ensureCustomData()->autoEquip()->fireEquipmentChanged()
// all from within this destructor. ouch!
&& mPtr.getRefData().getCustomData())
mPtr.getClass().getInventoryStore(mPtr).setListener(NULL, mPtr); mPtr.getClass().getInventoryStore(mPtr).setListener(NULL, mPtr);
} }

View File

@ -25,23 +25,26 @@ namespace
namespace MWWorld namespace MWWorld
{ {
ActionTeleport::ActionTeleport (const std::string& cellName, ActionTeleport::ActionTeleport (const std::string& cellName,
const ESM::Position& position) const ESM::Position& position, bool teleportFollowers)
: Action (true), mCellName (cellName), mPosition (position) : Action (true), mCellName (cellName), mPosition (position), mTeleportFollowers(teleportFollowers)
{ {
} }
void ActionTeleport::executeImp (const Ptr& actor) void ActionTeleport::executeImp (const Ptr& actor)
{ {
//find any NPC that is following the actor and teleport him too if (mTeleportFollowers)
std::set<MWWorld::Ptr> followers;
getFollowers(actor, followers);
for(std::set<MWWorld::Ptr>::iterator it = followers.begin();it != followers.end();++it)
{ {
MWWorld::Ptr follower = *it; //find any NPC that is following the actor and teleport him too
if (Ogre::Vector3(follower.getRefData().getPosition().pos).squaredDistance( std::set<MWWorld::Ptr> followers;
Ogre::Vector3( actor.getRefData().getPosition().pos)) getFollowers(actor, followers);
<= 800*800) for(std::set<MWWorld::Ptr>::iterator it = followers.begin();it != followers.end();++it)
teleport(*it); {
MWWorld::Ptr follower = *it;
if (Ogre::Vector3(follower.getRefData().getPosition().pos).squaredDistance(
Ogre::Vector3( actor.getRefData().getPosition().pos))
<= 800*800)
teleport(*it);
}
} }
teleport(actor); teleport(actor);

View File

@ -13,6 +13,7 @@ namespace MWWorld
{ {
std::string mCellName; std::string mCellName;
ESM::Position mPosition; ESM::Position mPosition;
bool mTeleportFollowers;
/// Teleports this actor and also teleports anyone following that actor. /// Teleports this actor and also teleports anyone following that actor.
virtual void executeImp (const Ptr& actor); virtual void executeImp (const Ptr& actor);
@ -22,8 +23,9 @@ namespace MWWorld
public: public:
ActionTeleport (const std::string& cellName, const ESM::Position& position); ActionTeleport (const std::string& cellName, const ESM::Position& position, bool teleportFollowers);
///< If cellName is empty, an exterior cell is assumed. ///< If cellName is empty, an exterior cell is assumed.
/// @param teleportFollowers Whether to teleport any following actors of the target actor as well.
}; };
} }

View File

@ -366,6 +366,19 @@ namespace MWWorld
inserted.first->second = scpt; inserted.first->second = scpt;
} }
template <>
inline void Store<ESM::StartScript>::load(ESM::ESMReader &esm, const std::string &id)
{
ESM::StartScript s;
s.load(esm);
s.mId = Misc::StringUtils::toLower(s.mId);
std::pair<typename Static::iterator, bool> inserted = mStatic.insert(std::make_pair(s.mId, s));
if (inserted.second)
mShared.push_back(&inserted.first->second);
else
inserted.first->second = s;
}
template <> template <>
class Store<ESM::LandTexture> : public StoreBase class Store<ESM::LandTexture> : public StoreBase
{ {

View File

@ -2919,7 +2919,7 @@ namespace MWWorld
if ( !closestMarker.mCell->isExterior() ) if ( !closestMarker.mCell->isExterior() )
cellName = closestMarker.mCell->getCell()->mName; cellName = closestMarker.mCell->getCell()->mName;
MWWorld::ActionTeleport action(cellName, closestMarker.getRefData().getPosition()); MWWorld::ActionTeleport action(cellName, closestMarker.getRefData().getPosition(), false);
action.execute(ptr); action.execute(ptr);
} }

View File

@ -531,7 +531,7 @@ namespace Compiler
extensions.registerInstruction("placeitemcell","ccffff",opcodePlaceItemCell); extensions.registerInstruction("placeitemcell","ccffff",opcodePlaceItemCell);
extensions.registerInstruction("placeitem","cffff",opcodePlaceItem); extensions.registerInstruction("placeitem","cffff",opcodePlaceItem);
extensions.registerInstruction("placeatpc","clfl",opcodePlaceAtPc); extensions.registerInstruction("placeatpc","clfl",opcodePlaceAtPc);
extensions.registerInstruction("placeatme","clfl",opcodePlaceAtMe,opcodePlaceAtMeExplicit); extensions.registerInstruction("placeatme","clflX",opcodePlaceAtMe,opcodePlaceAtMeExplicit);
extensions.registerInstruction("modscale","f",opcodeModScale,opcodeModScaleExplicit); extensions.registerInstruction("modscale","f",opcodeModScale,opcodeModScaleExplicit);
extensions.registerInstruction("rotate","cf",opcodeRotate,opcodeRotateExplicit); extensions.registerInstruction("rotate","cf",opcodeRotate,opcodeRotateExplicit);
extensions.registerInstruction("rotateworld","cf",opcodeRotateWorld,opcodeRotateWorldExplicit); extensions.registerInstruction("rotateworld","cf",opcodeRotateWorld,opcodeRotateWorldExplicit);

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;

View File

@ -48,7 +48,7 @@ namespace Gui
const int _scrollBarWidth = 20; // fetch this from skin? const int _scrollBarWidth = 20; // fetch this from skin?
const int scrollBarWidth = scrollbarShown ? _scrollBarWidth : 0; const int scrollBarWidth = scrollbarShown ? _scrollBarWidth : 0;
const int spacing = 3; const int spacing = 3;
size_t viewPosition = -mScrollView->getViewOffset().top; int viewPosition = -mScrollView->getViewOffset().top;
while (mScrollView->getChildCount()) while (mScrollView->getChildCount())
{ {
@ -99,10 +99,10 @@ namespace Gui
if (!scrollbarShown && mItemHeight > mClient->getSize().height) if (!scrollbarShown && mItemHeight > mClient->getSize().height)
redraw(true); redraw(true);
size_t viewRange = mScrollView->getCanvasSize().height; int viewRange = mScrollView->getCanvasSize().height;
if(viewPosition > viewRange) if(viewPosition > viewRange)
viewPosition = viewRange; viewPosition = viewRange;
mScrollView->setViewOffset(MyGUI::IntPoint(0, viewPosition * -1)); mScrollView->setViewOffset(MyGUI::IntPoint(0, -viewPosition));
} }
void MWList::setPropertyOverride(const std::string &_key, const std::string &_value) void MWList::setPropertyOverride(const std::string &_key, const std::string &_value)
@ -157,4 +157,8 @@ namespace Gui
return mScrollView->findWidget (getName() + "_item_" + name)->castType<MyGUI::Button>(); return mScrollView->findWidget (getName() + "_item_" + name)->castType<MyGUI::Button>();
} }
void MWList::scrollToTop()
{
mScrollView->setViewOffset(MyGUI::IntPoint(0, 0));
}
} }

View File

@ -46,6 +46,8 @@ namespace Gui
MyGUI::Button* getItemWidget(const std::string& name); MyGUI::Button* getItemWidget(const std::string& name);
///< get widget for an item name, useful to set up tooltip ///< get widget for an item name, useful to set up tooltip
void scrollToTop();
virtual void setPropertyOverride(const std::string& _key, const std::string& _value); virtual void setPropertyOverride(const std::string& _key, const std::string& _value);
protected: protected: