mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 16:56:47 +00:00 
			
		
		
		
	Merge branch 'master' of https://github.com/OpenMW/openmw into osg
Conflicts: apps/opencs/CMakeLists.txt apps/opencs/model/doc/document.cpp apps/opencs/model/doc/document.hpp
This commit is contained in:
		
						commit
						e66e9916db
					
				
					 40 changed files with 570 additions and 44 deletions
				
			
		|  | @ -490,7 +490,7 @@ bool Launcher::MainDialog::writeSettings() | |||
|     // Game settings
 | ||||
|     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
 | ||||
|         QMessageBox msgBox; | ||||
|         msgBox.setWindowTitle(tr("Error writing OpenMW configuration file")); | ||||
|  | @ -503,10 +503,8 @@ bool Launcher::MainDialog::writeSettings() | |||
|                        return false; | ||||
|     } | ||||
| 
 | ||||
|     QTextStream stream(&file); | ||||
|     stream.setCodec(QTextCodec::codecForName("UTF-8")); | ||||
| 
 | ||||
|     mGameSettings.writeFile(stream); | ||||
|     mGameSettings.writeFileWithComments(file); | ||||
|     file.close(); | ||||
| 
 | ||||
|     // Graphics settings
 | ||||
|  | @ -525,6 +523,7 @@ bool Launcher::MainDialog::writeSettings() | |||
|                        return false; | ||||
|     } | ||||
| 
 | ||||
|     QTextStream stream(&file); | ||||
|     stream.setDevice(&file); | ||||
|     stream.setCodec(QTextCodec::codecForName("UTF-8")); | ||||
| 
 | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ opencs_units_noqt (model/world | |||
|     universalid record commands columnbase scriptcontext cell refidcollection | ||||
|     refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope | ||||
|     pathgrid landtexture land nestedtablewrapper nestedcollection nestedcoladapterimp nestedinfocollection | ||||
|     idcompletionmanager | ||||
|     ) | ||||
| 
 | ||||
| opencs_hdrs_noqt (model/world | ||||
|  | @ -68,12 +69,12 @@ opencs_units (view/world | |||
| 
 | ||||
| opencs_units_noqt (view/world | ||||
|     subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate | ||||
|     scripthighlighter idvalidator dialoguecreator | ||||
|     scripthighlighter idvalidator dialoguecreator idcompletiondelegate | ||||
|     ) | ||||
| 
 | ||||
| opencs_units (view/widget | ||||
|     scenetoolbar scenetool scenetoolmode pushbutton scenetooltoggle scenetoolrun modebutton | ||||
|     scenetooltoggle2 | ||||
|     scenetooltoggle2 completerpopup | ||||
|     ) | ||||
| 
 | ||||
| opencs_units (view/render | ||||
|  |  | |||
|  | @ -2256,7 +2256,7 @@ CSMDoc::Document::Document (const VFS::Manager* vfs, const Files::ConfigurationM | |||
|   mSavingOperation (*this, mProjectPath, encoding), | ||||
|   mSaving (&mSavingOperation), | ||||
|   mResDir(resDir), | ||||
|   mRunner (mProjectPath) | ||||
|   mRunner (mProjectPath), mIdCompletionManager(mData) | ||||
| { | ||||
|     if (mContentFiles.empty()) | ||||
|         throw std::runtime_error ("Empty content file sequence"); | ||||
|  | @ -2484,3 +2484,8 @@ void CSMDoc::Document::progress (int current, int max, int type) | |||
| { | ||||
|     emit progress (current, max, type, 1, this); | ||||
| } | ||||
| 
 | ||||
| CSMWorld::IdCompletionManager &CSMDoc::Document::getIdCompletionManager() | ||||
| { | ||||
|     return mIdCompletionManager; | ||||
| } | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ | |||
| #include <components/to_utf8/to_utf8.hpp> | ||||
| 
 | ||||
| #include "../world/data.hpp" | ||||
| #include "../world/idcompletionmanager.hpp" | ||||
| 
 | ||||
| #include "../tools/tools.hpp" | ||||
| 
 | ||||
|  | @ -68,6 +69,8 @@ namespace CSMDoc | |||
|             Blacklist mBlacklist; | ||||
|             Runner mRunner; | ||||
| 
 | ||||
|             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
 | ||||
|             // using other member variables.  Unfortunately this connection is cut only in the QObject destructor, which is way too late.
 | ||||
|             QUndoStack mUndoStack; | ||||
|  | @ -145,6 +148,8 @@ namespace CSMDoc | |||
| 
 | ||||
|             QTextDocument *getRunLog(); | ||||
| 
 | ||||
|             CSMWorld::IdCompletionManager &getIdCompletionManager(); | ||||
| 
 | ||||
|         signals: | ||||
| 
 | ||||
|             void stateChanged (int state, CSMDoc::Document *document); | ||||
|  |  | |||
|  | @ -65,6 +65,8 @@ bool CSMWorld::ColumnBase::isId (Display display) | |||
|         Display_JournalInfo, | ||||
|         Display_Scene, | ||||
|         Display_GlobalVariable, | ||||
|         Display_BodyPart, | ||||
|         Display_Enchantment, | ||||
|         Display_Script, | ||||
| 
 | ||||
|         Display_Mesh, | ||||
|  |  | |||
|  | @ -74,6 +74,8 @@ namespace CSMWorld | |||
|             Display_JournalInfo, | ||||
|             Display_Scene, | ||||
|             Display_GlobalVariable, | ||||
|             Display_BodyPart, | ||||
|             Display_Enchantment, | ||||
|             //CONCRETE TYPES ENDS HERE
 | ||||
| 
 | ||||
|             Display_Integer, | ||||
|  |  | |||
|  | @ -709,7 +709,7 @@ namespace CSMWorld | |||
|     struct SleepListColumn : public Column<ESXRecordT> | ||||
|     { | ||||
|         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 | ||||
|  | @ -735,7 +735,7 @@ namespace CSMWorld | |||
|     template<typename 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 | ||||
|         { | ||||
|  | @ -1269,7 +1269,7 @@ namespace CSMWorld | |||
|     template<typename 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 | ||||
|         { | ||||
|  | @ -1294,7 +1294,7 @@ namespace CSMWorld | |||
|     template<typename 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 | ||||
|         { | ||||
|  | @ -1497,7 +1497,10 @@ namespace CSMWorld | |||
|     template<typename 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 | ||||
|         { | ||||
|  | @ -1527,7 +1530,7 @@ namespace CSMWorld | |||
|     template<typename 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 | ||||
|         { | ||||
|  | @ -1830,7 +1833,7 @@ namespace CSMWorld | |||
|     template<typename 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 | ||||
|         { | ||||
|  | @ -2158,7 +2161,9 @@ namespace CSMWorld | |||
|     struct EffectTextureColumn : public Column<ESXRecordT> | ||||
|     { | ||||
|         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 || | ||||
|                 this->mColumnId==Columns::ColumnId_Particle); | ||||
|  |  | |||
|  | @ -115,7 +115,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc | |||
|     index = mFactions.getColumns()-1; | ||||
|     mFactions.addAdapter (std::make_pair(&mFactions.getColumn(index), new FactionReactionsAdapter ())); | ||||
|     mFactions.getNestableColumn(index)->addColumn( | ||||
|         new NestedChildColumn (Columns::ColumnId_Faction, ColumnBase::Display_String)); | ||||
|         new NestedChildColumn (Columns::ColumnId_Faction, ColumnBase::Display_Faction)); | ||||
|     mFactions.getNestableColumn(index)->addColumn( | ||||
|         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; | ||||
|     mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new SpellListAdapter<ESM::Race> ())); | ||||
|     mRaces.getNestableColumn(index)->addColumn( | ||||
|         new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_String)); | ||||
|         new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_Spell)); | ||||
|     // Race attributes
 | ||||
|     mRaces.addColumn (new NestedParentColumn<ESM::Race> (Columns::ColumnId_RaceAttributes)); | ||||
|     index = mRaces.getColumns()-1; | ||||
|  | @ -180,7 +180,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc | |||
|     index = mRegions.getColumns()-1; | ||||
|     mRegions.addAdapter (std::make_pair(&mRegions.getColumn(index), new RegionSoundListAdapter ())); | ||||
|     mRegions.getNestableColumn(index)->addColumn( | ||||
|         new NestedChildColumn (Columns::ColumnId_SoundName, ColumnBase::Display_String)); | ||||
|         new NestedChildColumn (Columns::ColumnId_SoundName, ColumnBase::Display_Sound)); | ||||
|     mRegions.getNestableColumn(index)->addColumn( | ||||
|         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), | ||||
|         new SpellListAdapter<ESM::BirthSign> ())); | ||||
|     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 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) | ||||
|         return QVariant(); | ||||
| 
 | ||||
|     if (role==ColumnBase::Role_Display) | ||||
|         return QVariant(mIdCollection->getColumn(index.column()).mDisplayType); | ||||
| 
 | ||||
|     if (role==ColumnBase::Role_ColumnId) | ||||
|         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 | ||||
| { | ||||
|     if (!index.isValid()) | ||||
|         return 0; | ||||
| 
 | ||||
|     Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; | ||||
| 
 | ||||
|     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) | ||||
|     const | ||||
| { | ||||
|  |  | |||
|  | @ -24,8 +24,6 @@ namespace CSMWorld | |||
| 
 | ||||
|             void updateColumnMap(); | ||||
| 
 | ||||
|             bool filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent) const; | ||||
| 
 | ||||
|         public: | ||||
| 
 | ||||
|             IdTableProxyModel (QObject *parent = 0); | ||||
|  | @ -39,6 +37,10 @@ namespace CSMWorld | |||
|         protected: | ||||
| 
 | ||||
|             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()) | ||||
|           return QVariant(); | ||||
| 
 | ||||
|     if ((role!=Qt::DisplayRole && role!=Qt::EditRole) || index.row() < 0 || index.column() < 0) | ||||
|         return QVariant(); | ||||
| 
 | ||||
|     if (index.internalId() != 0) | ||||
|     { | ||||
|         std::pair<int, int> parentAddress(unfoldIndexAddress(index.internalId())); | ||||
|         const NestableColumn *parentColumn = mNestedCollection->getNestableColumn(parentAddress.second); | ||||
| 
 | ||||
|         if (role == Qt::EditRole && | ||||
|             !mNestedCollection->getNestableColumn(parentAddress.second)->nestedColumn(index.column()).isEditable()) | ||||
|         { | ||||
|         if (role == ColumnBase::Role_Display) | ||||
|             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 mNestedCollection->getNestedData(parentAddress.first, | ||||
|                                             parentAddress.second, index.row(), index.column()); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (role==Qt::EditRole && !idCollection()->getColumn (index.column()).isEditable()) | ||||
|             return QVariant(); | ||||
| 
 | ||||
|         return idCollection()->getData (index.row(), index.column()); | ||||
|         return IdTable::data(index, role); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -79,6 +80,9 @@ QVariant CSMWorld::IdTree::nestedHeaderData(int section, int subSection, Qt::Ori | |||
|     if (role==ColumnBase::Role_Display) | ||||
|         return parentColumn->nestedColumn(subSection).mDisplayType; | ||||
| 
 | ||||
|     if (role==ColumnBase::Role_ColumnId) | ||||
|         return parentColumn->nestedColumn(subSection).mColumnId; | ||||
| 
 | ||||
|     return QVariant(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -99,7 +99,7 @@ CSMWorld::RefIdCollection::RefIdCollection() | |||
| 
 | ||||
|     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(); | ||||
|     mColumns.push_back (RefIdColumn (Columns::ColumnId_EnchantmentPoints, ColumnBase::Display_Integer)); | ||||
|     enchantableColumns.mEnchantmentPoints = &mColumns.back(); | ||||
|  | @ -135,7 +135,7 @@ CSMWorld::RefIdCollection::RefIdCollection() | |||
|             new NestedInventoryRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature))); | ||||
|     mNestedAdapters.push_back (std::make_pair(&mColumns.back(), inventoryMap)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String)); | ||||
|             new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_Referenceable)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer)); | ||||
| 
 | ||||
|  | @ -150,7 +150,7 @@ CSMWorld::RefIdCollection::RefIdCollection() | |||
|             new NestedSpellRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature))); | ||||
|     mNestedAdapters.push_back (std::make_pair(&mColumns.back(), spellsMap)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_String)); | ||||
|             new RefIdColumn (Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_Spell)); | ||||
| 
 | ||||
|     // Nested table
 | ||||
|     mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcDestinations, | ||||
|  | @ -163,7 +163,7 @@ CSMWorld::RefIdCollection::RefIdCollection() | |||
|             new NestedTravelRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature))); | ||||
|     mNestedAdapters.push_back (std::make_pair(&mColumns.back(), destMap)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_String)); | ||||
|             new RefIdColumn (Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_Cell)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float)); | ||||
|     mColumns.back().addColumn( | ||||
|  | @ -289,7 +289,7 @@ CSMWorld::RefIdCollection::RefIdCollection() | |||
|             new NestedInventoryRefIdAdapter<ESM::Container> (UniversalId::Type_Container))); | ||||
|     mNestedAdapters.push_back (std::make_pair(&mColumns.back(), contMap)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String)); | ||||
|             new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_Referenceable)); | ||||
|     mColumns.back().addColumn( | ||||
|             new RefIdColumn (Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer)); | ||||
| 
 | ||||
|  | @ -301,7 +301,7 @@ CSMWorld::RefIdCollection::RefIdCollection() | |||
|     creatureColumns.mSoul = &mColumns.back(); | ||||
|     mColumns.push_back (RefIdColumn (Columns::ColumnId_Scale, ColumnBase::Display_Float)); | ||||
|     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(); | ||||
|     mColumns.push_back ( | ||||
|         RefIdColumn (Columns::ColumnId_CombatState, ColumnBase::Display_Integer)); | ||||
|  | @ -409,10 +409,10 @@ CSMWorld::RefIdCollection::RefIdCollection() | |||
|     mColumns.push_back (RefIdColumn (Columns::ColumnId_Faction, ColumnBase::Display_Faction)); | ||||
|     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(); | ||||
| 
 | ||||
|     mColumns.push_back (RefIdColumn (Columns::ColumnId_Head, ColumnBase::Display_String)); | ||||
|     mColumns.push_back (RefIdColumn (Columns::ColumnId_Head, ColumnBase::Display_BodyPart)); | ||||
|     npcColumns.mHead = &mColumns.back(); | ||||
| 
 | ||||
|     mColumns.push_back (RefIdColumn (Columns::ColumnId_Female, ColumnBase::Display_Boolean)); | ||||
|  | @ -539,9 +539,9 @@ CSMWorld::RefIdCollection::RefIdCollection() | |||
|     mColumns.back().addColumn( | ||||
|         new RefIdColumn (Columns::ColumnId_PartRefType, CSMWorld::ColumnBase::Display_PartRefType)); | ||||
|     mColumns.back().addColumn( | ||||
|         new RefIdColumn (Columns::ColumnId_PartRefMale, CSMWorld::ColumnBase::Display_String)); | ||||
|         new RefIdColumn (Columns::ColumnId_PartRefMale, CSMWorld::ColumnBase::Display_BodyPart)); | ||||
|     mColumns.back().addColumn( | ||||
|         new RefIdColumn (Columns::ColumnId_PartRefFemale, CSMWorld::ColumnBase::Display_String)); | ||||
|         new RefIdColumn (Columns::ColumnId_PartRefFemale, CSMWorld::ColumnBase::Display_BodyPart)); | ||||
| 
 | ||||
|     LevListColumns levListColumns (baseColumns); | ||||
| 
 | ||||
|  | @ -556,7 +556,7 @@ CSMWorld::RefIdCollection::RefIdCollection() | |||
|         new NestedLevListRefIdAdapter<ESM::ItemLevList> (UniversalId::Type_ItemLevelledList))); | ||||
|     mNestedAdapters.push_back (std::make_pair(&mColumns.back(), levListMap)); | ||||
|     mColumns.back().addColumn( | ||||
|         new RefIdColumn (Columns::ColumnId_LevelledItemId, CSMWorld::ColumnBase::Display_String)); | ||||
|         new RefIdColumn (Columns::ColumnId_LevelledItemId, CSMWorld::ColumnBase::Display_Referenceable)); | ||||
|     mColumns.back().addColumn( | ||||
|         new RefIdColumn (Columns::ColumnId_LevelledItemLevel, CSMWorld::ColumnBase::Display_Integer)); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| 
 | ||||
| #include "viewmanager.hpp" | ||||
| 
 | ||||
| #include <vector> | ||||
| #include <map> | ||||
| 
 | ||||
| #include <QApplication> | ||||
|  | @ -10,12 +11,14 @@ | |||
| #include "../../model/doc/document.hpp" | ||||
| #include "../../model/world/columns.hpp" | ||||
| #include "../../model/world/universalid.hpp" | ||||
| #include "../../model/world/idcompletionmanager.hpp" | ||||
| 
 | ||||
| #include "../world/util.hpp" | ||||
| #include "../world/enumdelegate.hpp" | ||||
| #include "../world/vartypedelegate.hpp" | ||||
| #include "../world/recordstatusdelegate.hpp" | ||||
| #include "../world/idtypedelegate.hpp" | ||||
| #include "../world/idcompletiondelegate.hpp" | ||||
| 
 | ||||
| #include "../../model/settings/usersettings.hpp" | ||||
| 
 | ||||
|  | @ -60,6 +63,14 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) | |||
|     mDelegateFactories->add (CSMWorld::ColumnBase::Display_RefRecordType, | ||||
|         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 | ||||
|     { | ||||
|         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; | ||||
| } | ||||
| 
 | ||||
| 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, | ||||
|     const QModelIndex& index) const | ||||
| { | ||||
|  | @ -146,7 +152,17 @@ void CSVWorld::CommandDelegate::setModelData (QWidget *editor, QAbstractItemMode | |||
| QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem& option, | ||||
|     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, | ||||
|  |  | |||
|  | @ -124,6 +124,8 @@ namespace CSVWorld | |||
| 
 | ||||
|             CSMDoc::Document& getDocument() const; | ||||
| 
 | ||||
|             CSMWorld::ColumnBase::Display getDisplayTypeFromIndex(const QModelIndex &index) const; | ||||
| 
 | ||||
|             virtual void setModelDataImp (QWidget *editor, QAbstractItemModel *model, | ||||
|                 const QModelIndex& index) const; | ||||
| 
 | ||||
|  |  | |||
|  | @ -130,6 +130,7 @@ namespace MWGui | |||
|         mSortModel = new SortFilterItemModel(model); | ||||
|         mSortModel->setFilter(SortFilterItemModel::Filter_OnlyIngredients); | ||||
|         mItemView->setModel (mSortModel); | ||||
|         mItemView->resetScrollBars(); | ||||
| 
 | ||||
|         mNameEdit->setCaption(""); | ||||
| 
 | ||||
|  |  | |||
|  | @ -114,6 +114,7 @@ void CompanionWindow::openCompanion(const MWWorld::Ptr& npc) | |||
|     mModel = new CompanionItemModel(npc); | ||||
|     mSortModel = new SortFilterItemModel(mModel); | ||||
|     mItemView->setModel(mSortModel); | ||||
|     mItemView->resetScrollBars(); | ||||
| 
 | ||||
|     setTitle(npc.getClass().getName(npc)); | ||||
| } | ||||
|  |  | |||
|  | @ -151,6 +151,7 @@ namespace MWGui | |||
|         mSortModel = new SortFilterItemModel(mModel); | ||||
| 
 | ||||
|         mItemView->setModel (mSortModel); | ||||
|         mItemView->resetScrollBars(); | ||||
| 
 | ||||
|         MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton); | ||||
| 
 | ||||
|  |  | |||
|  | @ -39,6 +39,7 @@ namespace MWGui | |||
|         mModel = new InventoryItemModel(container); | ||||
|         mSortModel = new SortFilterItemModel(mModel); | ||||
|         mItemView->setModel(mSortModel); | ||||
|         mItemView->resetScrollBars(); | ||||
|     } | ||||
| 
 | ||||
|     void ItemSelectionDialog::setCategory(int category) | ||||
|  |  | |||
|  | @ -128,6 +128,11 @@ void ItemView::update() | |||
|     layoutWidgets(); | ||||
| } | ||||
| 
 | ||||
| void ItemView::resetScrollBars() | ||||
| { | ||||
|     mScrollView->setViewOffset(MyGUI::IntPoint(0, 0)); | ||||
| } | ||||
| 
 | ||||
| void ItemView::onSelectedItem(MyGUI::Widget *sender) | ||||
| { | ||||
|     ItemModel::ModelIndex index = (*sender->getUserData<std::pair<ItemModel::ModelIndex, ItemModel*> >()).first; | ||||
|  |  | |||
|  | @ -30,6 +30,8 @@ namespace MWGui | |||
| 
 | ||||
|         void update(); | ||||
| 
 | ||||
|         void resetScrollBars(); | ||||
| 
 | ||||
|     private: | ||||
|         virtual void initialiseOverride(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -114,6 +114,8 @@ void MerchantRepair::onMouseWheel(MyGUI::Widget* _sender, int _rel) | |||
| void MerchantRepair::open() | ||||
| { | ||||
|     center(); | ||||
|     // Reset scrollbars
 | ||||
|     mList->setViewOffset(MyGUI::IntPoint(0, 0)); | ||||
| } | ||||
| 
 | ||||
| void MerchantRepair::exit() | ||||
|  |  | |||
|  | @ -546,6 +546,7 @@ namespace MWGui | |||
|         WindowModal::open(); | ||||
| 
 | ||||
|         mMagicList->setModel(new SpellModel(MWBase::Environment::get().getWorld()->getPlayerPtr())); | ||||
|         mMagicList->resetScrollbars(); | ||||
|     } | ||||
| 
 | ||||
|     void MagicSelectionDialog::onModelIndexSelected(SpellModel::ModelIndex index) | ||||
|  |  | |||
|  | @ -44,6 +44,8 @@ Recharge::Recharge() | |||
| void Recharge::open() | ||||
| { | ||||
|     center(); | ||||
|     // Reset scrollbars
 | ||||
|     mView->setViewOffset(MyGUI::IntPoint(0, 0)); | ||||
| } | ||||
| 
 | ||||
| void Recharge::exit() | ||||
|  |  | |||
|  | @ -36,6 +36,8 @@ Repair::Repair() | |||
| void Repair::open() | ||||
| { | ||||
|     center(); | ||||
|     // Reset scrollbars
 | ||||
|     mRepairView->setViewOffset(MyGUI::IntPoint(0, 0)); | ||||
| } | ||||
| 
 | ||||
| void Repair::exit() | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
| #include <MyGUI_ListBox.h> | ||||
| #include <MyGUI_ScrollView.h> | ||||
| #include <MyGUI_Gui.h> | ||||
| #include <MyGUI_TabControl.h> | ||||
| 
 | ||||
| #include <boost/algorithm/string.hpp> | ||||
| #include <boost/math/common_factor_rt.hpp> | ||||
|  | @ -159,6 +160,7 @@ namespace MWGui | |||
| 
 | ||||
|         setTitle("#{sOptions}"); | ||||
| 
 | ||||
|         getWidget(mSettingsTab, "SettingsTab"); | ||||
|         getWidget(mOkButton, "OkButton"); | ||||
|         getWidget(mResolutionList, "ResolutionList"); | ||||
|         getWidget(mFullscreenButton, "FullscreenButton"); | ||||
|  | @ -196,6 +198,7 @@ namespace MWGui | |||
| 
 | ||||
|         mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &SettingsWindow::onWindowResize); | ||||
| 
 | ||||
|         mSettingsTab->eventTabChangeSelect += MyGUI::newDelegate(this, &SettingsWindow::onTabChanged); | ||||
|         mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked); | ||||
|         mTextureFilteringButton->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onTextureFilteringChanged); | ||||
|         mFPSButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onFpsToggled); | ||||
|  | @ -260,6 +263,11 @@ namespace MWGui | |||
|         mControllerSwitch->setStateSelected(false); | ||||
|     } | ||||
| 
 | ||||
|     void SettingsWindow::onTabChanged(MyGUI::TabControl* /*_sender*/, size_t /*index*/) | ||||
|     { | ||||
|         resetScrollbars(); | ||||
|     } | ||||
| 
 | ||||
|     void SettingsWindow::onOkButtonClicked(MyGUI::Widget* _sender) | ||||
|     { | ||||
|         exit(); | ||||
|  | @ -454,6 +462,7 @@ namespace MWGui | |||
|         mKeyboardSwitch->setStateSelected(true); | ||||
|         mControllerSwitch->setStateSelected(false); | ||||
|         updateControlsBox(); | ||||
|         resetScrollbars(); | ||||
|     } | ||||
| 
 | ||||
|     void SettingsWindow::onControllerSwitchClicked(MyGUI::Widget* _sender) | ||||
|  | @ -464,6 +473,7 @@ namespace MWGui | |||
|         mKeyboardSwitch->setStateSelected(false); | ||||
|         mControllerSwitch->setStateSelected(true); | ||||
|         updateControlsBox(); | ||||
|         resetScrollbars(); | ||||
|     } | ||||
| 
 | ||||
|     void SettingsWindow::updateControlsBox() | ||||
|  | @ -558,6 +568,7 @@ namespace MWGui | |||
|     void SettingsWindow::open() | ||||
|     { | ||||
|         updateControlsBox (); | ||||
|         resetScrollbars(); | ||||
|     } | ||||
| 
 | ||||
|     void SettingsWindow::exit() | ||||
|  | @ -569,4 +580,10 @@ namespace MWGui | |||
|     { | ||||
|         updateControlsBox(); | ||||
|     } | ||||
| 
 | ||||
|     void SettingsWindow::resetScrollbars() | ||||
|     { | ||||
|         mResolutionList->setScrollPosition(0); | ||||
|         mControlsBox->setViewOffset(MyGUI::IntPoint(0, 0)); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ namespace MWGui | |||
|             void updateControlsBox(); | ||||
| 
 | ||||
|     protected: | ||||
|             MyGUI::TabControl* mSettingsTab; | ||||
|             MyGUI::Button* mOkButton; | ||||
| 
 | ||||
|             // graphics
 | ||||
|  | @ -49,6 +50,7 @@ namespace MWGui | |||
|             MyGUI::Button* mControllerSwitch; | ||||
|             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 onFpsToggled(MyGUI::Widget* _sender); | ||||
|             void onTextureFilteringChanged(MyGUI::ComboBox* _sender, size_t pos); | ||||
|  | @ -72,6 +74,9 @@ namespace MWGui | |||
|             void apply(); | ||||
| 
 | ||||
|             void configureWidgets(MyGUI::Widget* widget); | ||||
|          | ||||
|         private: | ||||
|             void resetScrollbars(); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -550,6 +550,7 @@ namespace MWGui | |||
|             ++i; | ||||
|         } | ||||
|         mAvailableEffectsList->adjustSize (); | ||||
|         mAvailableEffectsList->scrollToTop(); | ||||
| 
 | ||||
|         for (std::vector<short>::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it) | ||||
|         { | ||||
|  |  | |||
|  | @ -311,4 +311,8 @@ namespace MWGui | |||
|             mScrollView->setViewOffset(MyGUI::IntPoint(0, static_cast<int>(mScrollView->getViewOffset().top + _rel*0.3f))); | ||||
|     } | ||||
| 
 | ||||
|     void SpellView::resetScrollbars() | ||||
|     { | ||||
|         mScrollView->setViewOffset(MyGUI::IntPoint(0, 0)); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -51,6 +51,8 @@ namespace MWGui | |||
|         virtual void setSize(const MyGUI::IntSize& _value); | ||||
|         virtual void setCoord(const MyGUI::IntCoord& _value); | ||||
| 
 | ||||
|         void resetScrollbars(); | ||||
| 
 | ||||
|     private: | ||||
|         MyGUI::ScrollView* mScrollView; | ||||
| 
 | ||||
|  |  | |||
|  | @ -136,6 +136,7 @@ namespace MWGui | |||
|         mTradeModel = new TradeItemModel(new ContainerItemModel(itemSources, worldItems), mPtr); | ||||
|         mSortModel = new SortFilterItemModel(mTradeModel); | ||||
|         mItemView->setModel (mSortModel); | ||||
|         mItemView->resetScrollBars(); | ||||
| 
 | ||||
|         updateLabels(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| #include "gamesettings.hpp" | ||||
| #include "launchersettings.hpp" | ||||
| 
 | ||||
| #include <QTextCodec> | ||||
| #include <QTextStream> | ||||
| #include <QDir> | ||||
| #include <QString> | ||||
|  | @ -173,6 +174,138 @@ bool Config::GameSettings::writeFile(QTextStream &stream) | |||
|     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 result = false; | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| #include <QTextStream> | ||||
| #include <QStringList> | ||||
| #include <QString> | ||||
| #include <QFile> | ||||
| #include <QMap> | ||||
| 
 | ||||
| #include <boost/filesystem/path.hpp> | ||||
|  | @ -66,6 +67,7 @@ namespace Config | |||
|         bool readUserFile(QTextStream &stream); | ||||
| 
 | ||||
|         bool writeFile(QTextStream &stream); | ||||
|         bool writeFileWithComments(QFile &file); | ||||
| 
 | ||||
|         void setContentList(const QStringList& fileNames); | ||||
|         QStringList getContentList() const; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue