mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-19 20:53:52 +00:00
Merge branch 'script'
This commit is contained in:
commit
5bfa691f14
18 changed files with 499 additions and 8 deletions
|
@ -22,7 +22,7 @@ opencs_units (model/world
|
||||||
|
|
||||||
|
|
||||||
opencs_units_noqt (model/world
|
opencs_units_noqt (model/world
|
||||||
universalid data record idcollection commands columnbase
|
universalid data record idcollection commands columnbase scriptcontext
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_hdrs_noqt (model/world
|
opencs_hdrs_noqt (model/world
|
||||||
|
@ -55,11 +55,11 @@ opencs_hdrs_noqt (view/doc
|
||||||
|
|
||||||
|
|
||||||
opencs_units (view/world
|
opencs_units (view/world
|
||||||
table tablesubview
|
table tablesubview scriptsubview
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (view/world
|
opencs_units_noqt (view/world
|
||||||
dialoguesubview util subviews enumdelegate vartypedelegate
|
dialoguesubview util subviews enumdelegate vartypedelegate scripthighlighter
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@ namespace CSMWorld
|
||||||
Display_Specialisation,
|
Display_Specialisation,
|
||||||
Display_Attribute,
|
Display_Attribute,
|
||||||
Display_Boolean,
|
Display_Boolean,
|
||||||
Display_SpellType
|
Display_SpellType,
|
||||||
|
Display_Script
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string mTitle;
|
std::string mTitle;
|
||||||
|
|
|
@ -723,6 +723,31 @@ namespace CSMWorld
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename ESXRecordT>
|
||||||
|
struct ScriptColumn : public Column<ESXRecordT>
|
||||||
|
{
|
||||||
|
ScriptColumn() : Column<ESXRecordT> ("Script", ColumnBase::Display_Script, 0) {}
|
||||||
|
|
||||||
|
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||||
|
{
|
||||||
|
return QString::fromUtf8 (record.get().mScriptText.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||||
|
{
|
||||||
|
ESXRecordT record2 = record.get();
|
||||||
|
|
||||||
|
record2.mScriptText = data.toString().toUtf8().constData();
|
||||||
|
|
||||||
|
record.setModified (record2);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool isEditable() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -33,11 +33,13 @@ CSMWorld::Data::Data()
|
||||||
mGmsts.addColumn (new StringIdColumn<ESM::GameSetting>);
|
mGmsts.addColumn (new StringIdColumn<ESM::GameSetting>);
|
||||||
mGmsts.addColumn (new RecordStateColumn<ESM::GameSetting>);
|
mGmsts.addColumn (new RecordStateColumn<ESM::GameSetting>);
|
||||||
mGmsts.addColumn (new FixedRecordTypeColumn<ESM::GameSetting> (UniversalId::Type_Gmst));
|
mGmsts.addColumn (new FixedRecordTypeColumn<ESM::GameSetting> (UniversalId::Type_Gmst));
|
||||||
|
mGmsts.addColumn (new FixedRecordTypeColumn<ESM::GameSetting> (UniversalId::Type_Gmst));
|
||||||
mGmsts.addColumn (new VarTypeColumn<ESM::GameSetting> (ColumnBase::Display_GmstVarType));
|
mGmsts.addColumn (new VarTypeColumn<ESM::GameSetting> (ColumnBase::Display_GmstVarType));
|
||||||
mGmsts.addColumn (new VarValueColumn<ESM::GameSetting>);
|
mGmsts.addColumn (new VarValueColumn<ESM::GameSetting>);
|
||||||
|
|
||||||
mSkills.addColumn (new StringIdColumn<ESM::Skill>);
|
mSkills.addColumn (new StringIdColumn<ESM::Skill>);
|
||||||
mSkills.addColumn (new RecordStateColumn<ESM::Skill>);
|
mSkills.addColumn (new RecordStateColumn<ESM::Skill>);
|
||||||
|
mSkills.addColumn (new FixedRecordTypeColumn<ESM::Skill> (UniversalId::Type_Skill));
|
||||||
mSkills.addColumn (new AttributeColumn<ESM::Skill>);
|
mSkills.addColumn (new AttributeColumn<ESM::Skill>);
|
||||||
mSkills.addColumn (new SpecialisationColumn<ESM::Skill>);
|
mSkills.addColumn (new SpecialisationColumn<ESM::Skill>);
|
||||||
for (int i=0; i<4; ++i)
|
for (int i=0; i<4; ++i)
|
||||||
|
@ -46,6 +48,7 @@ CSMWorld::Data::Data()
|
||||||
|
|
||||||
mClasses.addColumn (new StringIdColumn<ESM::Class>);
|
mClasses.addColumn (new StringIdColumn<ESM::Class>);
|
||||||
mClasses.addColumn (new RecordStateColumn<ESM::Class>);
|
mClasses.addColumn (new RecordStateColumn<ESM::Class>);
|
||||||
|
mClasses.addColumn (new FixedRecordTypeColumn<ESM::Class> (UniversalId::Type_Class));
|
||||||
mClasses.addColumn (new NameColumn<ESM::Class>);
|
mClasses.addColumn (new NameColumn<ESM::Class>);
|
||||||
mClasses.addColumn (new AttributesColumn<ESM::Class> (0));
|
mClasses.addColumn (new AttributesColumn<ESM::Class> (0));
|
||||||
mClasses.addColumn (new AttributesColumn<ESM::Class> (1));
|
mClasses.addColumn (new AttributesColumn<ESM::Class> (1));
|
||||||
|
@ -59,6 +62,7 @@ CSMWorld::Data::Data()
|
||||||
|
|
||||||
mFactions.addColumn (new StringIdColumn<ESM::Faction>);
|
mFactions.addColumn (new StringIdColumn<ESM::Faction>);
|
||||||
mFactions.addColumn (new RecordStateColumn<ESM::Faction>);
|
mFactions.addColumn (new RecordStateColumn<ESM::Faction>);
|
||||||
|
mFactions.addColumn (new FixedRecordTypeColumn<ESM::Faction> (UniversalId::Type_Faction));
|
||||||
mFactions.addColumn (new NameColumn<ESM::Faction>);
|
mFactions.addColumn (new NameColumn<ESM::Faction>);
|
||||||
mFactions.addColumn (new AttributesColumn<ESM::Faction> (0));
|
mFactions.addColumn (new AttributesColumn<ESM::Faction> (0));
|
||||||
mFactions.addColumn (new AttributesColumn<ESM::Faction> (1));
|
mFactions.addColumn (new AttributesColumn<ESM::Faction> (1));
|
||||||
|
@ -68,6 +72,7 @@ CSMWorld::Data::Data()
|
||||||
|
|
||||||
mRaces.addColumn (new StringIdColumn<ESM::Race>);
|
mRaces.addColumn (new StringIdColumn<ESM::Race>);
|
||||||
mRaces.addColumn (new RecordStateColumn<ESM::Race>);
|
mRaces.addColumn (new RecordStateColumn<ESM::Race>);
|
||||||
|
mRaces.addColumn (new FixedRecordTypeColumn<ESM::Race> (UniversalId::Type_Race));
|
||||||
mRaces.addColumn (new NameColumn<ESM::Race>);
|
mRaces.addColumn (new NameColumn<ESM::Race>);
|
||||||
mRaces.addColumn (new DescriptionColumn<ESM::Race>);
|
mRaces.addColumn (new DescriptionColumn<ESM::Race>);
|
||||||
mRaces.addColumn (new FlagColumn<ESM::Race> ("Playable", 0x1));
|
mRaces.addColumn (new FlagColumn<ESM::Race> ("Playable", 0x1));
|
||||||
|
@ -79,6 +84,7 @@ CSMWorld::Data::Data()
|
||||||
|
|
||||||
mSounds.addColumn (new StringIdColumn<ESM::Sound>);
|
mSounds.addColumn (new StringIdColumn<ESM::Sound>);
|
||||||
mSounds.addColumn (new RecordStateColumn<ESM::Sound>);
|
mSounds.addColumn (new RecordStateColumn<ESM::Sound>);
|
||||||
|
mSounds.addColumn (new FixedRecordTypeColumn<ESM::Sound> (UniversalId::Type_Sound));
|
||||||
mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_Volume));
|
mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_Volume));
|
||||||
mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_MinRange));
|
mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_MinRange));
|
||||||
mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_MaxRange));
|
mSounds.addColumn (new SoundParamColumn<ESM::Sound> (SoundParamColumn<ESM::Sound>::Type_MaxRange));
|
||||||
|
@ -86,21 +92,26 @@ CSMWorld::Data::Data()
|
||||||
|
|
||||||
mScripts.addColumn (new StringIdColumn<ESM::Script>);
|
mScripts.addColumn (new StringIdColumn<ESM::Script>);
|
||||||
mScripts.addColumn (new RecordStateColumn<ESM::Script>);
|
mScripts.addColumn (new RecordStateColumn<ESM::Script>);
|
||||||
|
mScripts.addColumn (new FixedRecordTypeColumn<ESM::Script> (UniversalId::Type_Script));
|
||||||
|
mScripts.addColumn (new ScriptColumn<ESM::Script>);
|
||||||
|
|
||||||
mRegions.addColumn (new StringIdColumn<ESM::Region>);
|
mRegions.addColumn (new StringIdColumn<ESM::Region>);
|
||||||
mRegions.addColumn (new RecordStateColumn<ESM::Region>);
|
mRegions.addColumn (new RecordStateColumn<ESM::Region>);
|
||||||
|
mRegions.addColumn (new FixedRecordTypeColumn<ESM::Region> (UniversalId::Type_Region));
|
||||||
mRegions.addColumn (new NameColumn<ESM::Region>);
|
mRegions.addColumn (new NameColumn<ESM::Region>);
|
||||||
mRegions.addColumn (new MapColourColumn<ESM::Region>);
|
mRegions.addColumn (new MapColourColumn<ESM::Region>);
|
||||||
mRegions.addColumn (new SleepListColumn<ESM::Region>);
|
mRegions.addColumn (new SleepListColumn<ESM::Region>);
|
||||||
|
|
||||||
mBirthsigns.addColumn (new StringIdColumn<ESM::BirthSign>);
|
mBirthsigns.addColumn (new StringIdColumn<ESM::BirthSign>);
|
||||||
mBirthsigns.addColumn (new RecordStateColumn<ESM::BirthSign>);
|
mBirthsigns.addColumn (new RecordStateColumn<ESM::BirthSign>);
|
||||||
|
mBirthsigns.addColumn (new FixedRecordTypeColumn<ESM::BirthSign> (UniversalId::Type_Birthsign));
|
||||||
mBirthsigns.addColumn (new NameColumn<ESM::BirthSign>);
|
mBirthsigns.addColumn (new NameColumn<ESM::BirthSign>);
|
||||||
mBirthsigns.addColumn (new TextureColumn<ESM::BirthSign>);
|
mBirthsigns.addColumn (new TextureColumn<ESM::BirthSign>);
|
||||||
mBirthsigns.addColumn (new DescriptionColumn<ESM::BirthSign>);
|
mBirthsigns.addColumn (new DescriptionColumn<ESM::BirthSign>);
|
||||||
|
|
||||||
mSpells.addColumn (new StringIdColumn<ESM::Spell>);
|
mSpells.addColumn (new StringIdColumn<ESM::Spell>);
|
||||||
mSpells.addColumn (new RecordStateColumn<ESM::Spell>);
|
mSpells.addColumn (new RecordStateColumn<ESM::Spell>);
|
||||||
|
mSpells.addColumn (new FixedRecordTypeColumn<ESM::Spell> (UniversalId::Type_Spell));
|
||||||
mSpells.addColumn (new NameColumn<ESM::Spell>);
|
mSpells.addColumn (new NameColumn<ESM::Spell>);
|
||||||
mSpells.addColumn (new SpellTypeColumn<ESM::Spell>);
|
mSpells.addColumn (new SpellTypeColumn<ESM::Spell>);
|
||||||
mSpells.addColumn (new CostColumn<ESM::Spell>);
|
mSpells.addColumn (new CostColumn<ESM::Spell>);
|
||||||
|
|
22
apps/opencs/model/world/scriptcontext.cpp
Normal file
22
apps/opencs/model/world/scriptcontext.cpp
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
#include "scriptcontext.hpp"
|
||||||
|
|
||||||
|
bool CSMWorld::ScriptContext::canDeclareLocals() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char CSMWorld::ScriptContext::getGlobalType (const std::string& name) const
|
||||||
|
{
|
||||||
|
return ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
char CSMWorld::ScriptContext::getMemberType (const std::string& name, const std::string& id) const
|
||||||
|
{
|
||||||
|
return ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMWorld::ScriptContext::isId (const std::string& name) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
26
apps/opencs/model/world/scriptcontext.hpp
Normal file
26
apps/opencs/model/world/scriptcontext.hpp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef CSM_WORLD_SCRIPTCONTEXT_H
|
||||||
|
#define CSM_WORLD_SCRIPTCONTEXT_H
|
||||||
|
|
||||||
|
#include <components/compiler/context.hpp>
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class ScriptContext : public Compiler::Context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual bool canDeclareLocals() const;
|
||||||
|
///< Is the compiler allowed to declare local variables?
|
||||||
|
|
||||||
|
virtual char getGlobalType (const std::string& name) const;
|
||||||
|
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
|
||||||
|
|
||||||
|
virtual char getMemberType (const std::string& name, const std::string& id) const;
|
||||||
|
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
|
||||||
|
|
||||||
|
virtual bool isId (const std::string& name) const;
|
||||||
|
///< Does \a name match an ID, that can be referenced?
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
118
apps/opencs/view/world/scripthighlighter.cpp
Normal file
118
apps/opencs/view/world/scripthighlighter.cpp
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
|
||||||
|
#include "scripthighlighter.hpp"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <components/compiler/scanner.hpp>
|
||||||
|
|
||||||
|
bool CSVWorld::ScriptHighlighter::parseInt (int value, const Compiler::TokenLoc& loc,
|
||||||
|
Compiler::Scanner& scanner)
|
||||||
|
{
|
||||||
|
highlight (loc, Type_Int);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVWorld::ScriptHighlighter::parseFloat (float value, const Compiler::TokenLoc& loc,
|
||||||
|
Compiler::Scanner& scanner)
|
||||||
|
{
|
||||||
|
highlight (loc, Type_Float);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVWorld::ScriptHighlighter::parseName (const std::string& name, const Compiler::TokenLoc& loc,
|
||||||
|
Compiler::Scanner& scanner)
|
||||||
|
{
|
||||||
|
highlight (loc, Type_Name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVWorld::ScriptHighlighter::parseKeyword (int keyword, const Compiler::TokenLoc& loc,
|
||||||
|
Compiler::Scanner& scanner)
|
||||||
|
{
|
||||||
|
highlight (loc, Type_Keyword);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVWorld::ScriptHighlighter::parseSpecial (int code, const Compiler::TokenLoc& loc,
|
||||||
|
Compiler::Scanner& scanner)
|
||||||
|
{
|
||||||
|
highlight (loc, Type_Special);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVWorld::ScriptHighlighter::parseComment (const std::string& comment,
|
||||||
|
const Compiler::TokenLoc& loc, Compiler::Scanner& scanner)
|
||||||
|
{
|
||||||
|
highlight (loc, Type_Comment);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::ScriptHighlighter::parseEOF (Compiler::Scanner& scanner)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CSVWorld::ScriptHighlighter::highlight (const Compiler::TokenLoc& loc, Type type)
|
||||||
|
{
|
||||||
|
int length = static_cast<int> (loc.mLiteral.size());
|
||||||
|
|
||||||
|
int index = loc.mColumn;
|
||||||
|
|
||||||
|
// compensate for bug in Compiler::Scanner (position of token is the character after the token)
|
||||||
|
index -= length;
|
||||||
|
|
||||||
|
setFormat (index, length, mScheme[type]);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::ScriptHighlighter::ScriptHighlighter (QTextDocument *parent)
|
||||||
|
: QSyntaxHighlighter (parent), Compiler::Parser (mErrorHandler, mContext)
|
||||||
|
{
|
||||||
|
/// \ŧodo replace this with user settings
|
||||||
|
{
|
||||||
|
QTextCharFormat format;
|
||||||
|
format.setForeground (Qt::darkMagenta);
|
||||||
|
mScheme.insert (std::make_pair (Type_Int, format));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
QTextCharFormat format;
|
||||||
|
format.setForeground (Qt::magenta);
|
||||||
|
mScheme.insert (std::make_pair (Type_Float, format));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
QTextCharFormat format;
|
||||||
|
format.setForeground (Qt::gray);
|
||||||
|
mScheme.insert (std::make_pair (Type_Name, format));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
QTextCharFormat format;
|
||||||
|
format.setForeground (Qt::red);
|
||||||
|
mScheme.insert (std::make_pair (Type_Keyword, format));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
QTextCharFormat format;
|
||||||
|
format.setForeground (Qt::darkYellow);
|
||||||
|
mScheme.insert (std::make_pair (Type_Special, format));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
QTextCharFormat format;
|
||||||
|
format.setForeground (Qt::green);
|
||||||
|
mScheme.insert (std::make_pair (Type_Comment, format));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::ScriptHighlighter::highlightBlock (const QString& text)
|
||||||
|
{
|
||||||
|
std::istringstream stream (text.toUtf8().constData());
|
||||||
|
|
||||||
|
Compiler::Scanner scanner (mErrorHandler, stream, mContext.getExtensions());
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
scanner.scan (*this);
|
||||||
|
}
|
||||||
|
catch (...) {} // ignore syntax errors
|
||||||
|
|
||||||
|
}
|
80
apps/opencs/view/world/scripthighlighter.hpp
Normal file
80
apps/opencs/view/world/scripthighlighter.hpp
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
#ifndef CSV_WORLD_SCRIPTHIGHLIGHTER_H
|
||||||
|
#define CSV_WORLD_SCRIPTHIGHLIGHTER_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include <QSyntaxHighlighter>
|
||||||
|
|
||||||
|
#include <components/compiler/nullerrorhandler.hpp>
|
||||||
|
#include <components/compiler/parser.hpp>
|
||||||
|
|
||||||
|
#include "../../model/world/scriptcontext.hpp"
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class ScriptHighlighter : public QSyntaxHighlighter, private Compiler::Parser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
Type_Int,
|
||||||
|
Type_Float,
|
||||||
|
Type_Name,
|
||||||
|
Type_Keyword,
|
||||||
|
Type_Special,
|
||||||
|
Type_Comment
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Compiler::NullErrorHandler mErrorHandler;
|
||||||
|
CSMWorld::ScriptContext mContext;
|
||||||
|
std::map<Type, QTextCharFormat> mScheme;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
virtual bool parseInt (int value, const Compiler::TokenLoc& loc,
|
||||||
|
Compiler::Scanner& scanner);
|
||||||
|
///< Handle an int token.
|
||||||
|
/// \return fetch another token?
|
||||||
|
|
||||||
|
virtual bool parseFloat (float value, const Compiler::TokenLoc& loc,
|
||||||
|
Compiler::Scanner& scanner);
|
||||||
|
///< Handle a float token.
|
||||||
|
/// \return fetch another token?
|
||||||
|
|
||||||
|
virtual bool parseName (const std::string& name,
|
||||||
|
const Compiler::TokenLoc& loc, Compiler::Scanner& scanner);
|
||||||
|
///< Handle a name token.
|
||||||
|
/// \return fetch another token?
|
||||||
|
|
||||||
|
virtual bool parseKeyword (int keyword, const Compiler::TokenLoc& loc,
|
||||||
|
Compiler::Scanner& scanner);
|
||||||
|
///< Handle a keyword token.
|
||||||
|
/// \return fetch another token?
|
||||||
|
|
||||||
|
virtual bool parseSpecial (int code, const Compiler::TokenLoc& loc,
|
||||||
|
Compiler::Scanner& scanner);
|
||||||
|
///< Handle a special character token.
|
||||||
|
/// \return fetch another token?
|
||||||
|
|
||||||
|
virtual bool parseComment (const std::string& comment, const Compiler::TokenLoc& loc,
|
||||||
|
Compiler::Scanner& scanner);
|
||||||
|
///< Handle comment token.
|
||||||
|
/// \return fetch another token?
|
||||||
|
|
||||||
|
virtual void parseEOF (Compiler::Scanner& scanner);
|
||||||
|
///< Handle EOF token.
|
||||||
|
|
||||||
|
void highlight (const Compiler::TokenLoc& loc, Type type);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ScriptHighlighter (QTextDocument *parent);
|
||||||
|
|
||||||
|
virtual void highlightBlock (const QString& text);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
99
apps/opencs/view/world/scriptsubview.cpp
Normal file
99
apps/opencs/view/world/scriptsubview.cpp
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
|
||||||
|
#include "scriptsubview.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include <QTextEdit>
|
||||||
|
|
||||||
|
#include "../../model/doc/document.hpp"
|
||||||
|
#include "../../model/world/universalid.hpp"
|
||||||
|
#include "../../model/world/data.hpp"
|
||||||
|
#include "../../model/world/columnbase.hpp"
|
||||||
|
#include "../../model/world/commands.hpp"
|
||||||
|
#include "../../model/world/idtable.hpp"
|
||||||
|
|
||||||
|
#include "scripthighlighter.hpp"
|
||||||
|
|
||||||
|
CSVWorld::ScriptSubView::ChangeLock::ChangeLock (ScriptSubView& view) : mView (view)
|
||||||
|
{
|
||||||
|
++mView.mChangeLocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::ScriptSubView::ChangeLock::~ChangeLock()
|
||||||
|
{
|
||||||
|
--mView.mChangeLocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
|
||||||
|
: SubView (id), mDocument (document), mColumn (-1), mChangeLocked (0)
|
||||||
|
{
|
||||||
|
setWidget (mEditor = new QTextEdit (this));
|
||||||
|
|
||||||
|
mEditor->setAcceptRichText (false);
|
||||||
|
mEditor->setLineWrapMode (QTextEdit::NoWrap);
|
||||||
|
mEditor->setTabStopWidth (4);
|
||||||
|
mEditor->setUndoRedoEnabled (false); // we use OpenCS-wide undo/redo instead
|
||||||
|
|
||||||
|
mModel = &dynamic_cast<CSMWorld::IdTable&> (
|
||||||
|
*document.getData().getTableModel (CSMWorld::UniversalId::Type_Scripts));
|
||||||
|
|
||||||
|
for (int i=0; i<mModel->columnCount(); ++i)
|
||||||
|
if (mModel->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display)==
|
||||||
|
CSMWorld::ColumnBase::Display_Script)
|
||||||
|
{
|
||||||
|
mColumn = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mColumn==-1)
|
||||||
|
throw std::logic_error ("Can't find script column");
|
||||||
|
|
||||||
|
mEditor->setPlainText (mModel->data (mModel->getModelIndex (id.getId(), mColumn)).toString());
|
||||||
|
|
||||||
|
connect (mEditor, SIGNAL (textChanged()), this, SLOT (textChanged()));
|
||||||
|
|
||||||
|
connect (mModel, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||||
|
this, SLOT (dataChanged (const QModelIndex&, const QModelIndex&)));
|
||||||
|
|
||||||
|
connect (mModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||||
|
this, SLOT (rowsAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||||
|
|
||||||
|
new ScriptHighlighter (mEditor->document());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::ScriptSubView::setEditLock (bool locked)
|
||||||
|
{
|
||||||
|
mEditor->setReadOnly (locked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::ScriptSubView::textChanged()
|
||||||
|
{
|
||||||
|
ChangeLock lock (*this);
|
||||||
|
|
||||||
|
mDocument.getUndoStack().push (new CSMWorld::ModifyCommand (*mModel,
|
||||||
|
mModel->getModelIndex (getUniversalId().getId(), mColumn), mEditor->toPlainText()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::ScriptSubView::dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight)
|
||||||
|
{
|
||||||
|
if (mChangeLocked)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn);
|
||||||
|
|
||||||
|
if (index.row()>=topLeft.row() && index.row()<=bottomRight.row() &&
|
||||||
|
index.column()>=topLeft.column() && index.column()<=bottomRight.column())
|
||||||
|
{
|
||||||
|
QTextCursor cursor = mEditor->textCursor();
|
||||||
|
mEditor->setPlainText (mModel->data (index).toString());
|
||||||
|
mEditor->setTextCursor (cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::ScriptSubView::rowsAboutToBeRemoved (const QModelIndex& parent, int start, int end)
|
||||||
|
{
|
||||||
|
QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn);
|
||||||
|
|
||||||
|
if (!parent.isValid() && index.row()>=start && index.row()<=end)
|
||||||
|
deleteLater();
|
||||||
|
}
|
62
apps/opencs/view/world/scriptsubview.hpp
Normal file
62
apps/opencs/view/world/scriptsubview.hpp
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#ifndef CSV_WORLD_SCRIPTSUBVIEW_H
|
||||||
|
#define CSV_WORLD_SCRIPTSUBVIEW_H
|
||||||
|
|
||||||
|
#include "../doc/subview.hpp"
|
||||||
|
|
||||||
|
class QTextEdit;
|
||||||
|
class QModelIndex;
|
||||||
|
|
||||||
|
namespace CSMDoc
|
||||||
|
{
|
||||||
|
class Document;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class IdTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class ScriptSubView : public CSVDoc::SubView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
QTextEdit *mEditor;
|
||||||
|
CSMDoc::Document& mDocument;
|
||||||
|
CSMWorld::IdTable *mModel;
|
||||||
|
int mColumn;
|
||||||
|
int mChangeLocked;
|
||||||
|
|
||||||
|
class ChangeLock
|
||||||
|
{
|
||||||
|
ScriptSubView& mView;
|
||||||
|
|
||||||
|
ChangeLock (const ChangeLock&);
|
||||||
|
ChangeLock& operator= (const ChangeLock&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ChangeLock (ScriptSubView& view);
|
||||||
|
~ChangeLock();
|
||||||
|
};
|
||||||
|
|
||||||
|
friend class ChangeLock;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
|
||||||
|
|
||||||
|
virtual void setEditLock (bool locked);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void textChanged();
|
||||||
|
|
||||||
|
void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
void rowsAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "tablesubview.hpp"
|
#include "tablesubview.hpp"
|
||||||
#include "dialoguesubview.hpp"
|
#include "dialoguesubview.hpp"
|
||||||
|
#include "scriptsubview.hpp"
|
||||||
|
|
||||||
void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
||||||
{
|
{
|
||||||
|
@ -32,6 +33,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
||||||
for (int i=0; sTableTypes[i]!=CSMWorld::UniversalId::Type_None; ++i)
|
for (int i=0; sTableTypes[i]!=CSMWorld::UniversalId::Type_None; ++i)
|
||||||
manager.add (sTableTypes[i], new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (true));
|
manager.add (sTableTypes[i], new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (true));
|
||||||
|
|
||||||
|
manager.add (CSMWorld::UniversalId::Type_Script, new CSVDoc::SubViewFactory<ScriptSubView>);
|
||||||
|
|
||||||
// manager.add (CSMWorld::UniversalId::Type_Global,
|
// manager.add (CSMWorld::UniversalId::Type_Global,
|
||||||
// new CSVDoc::SubViewFactoryWithCreateFlag<DialogueSubView> (true));
|
// new CSVDoc::SubViewFactoryWithCreateFlag<DialogueSubView> (true));
|
||||||
|
|
|
@ -21,6 +21,5 @@ void CSVWorld::TableSubView::setEditLock (bool locked)
|
||||||
|
|
||||||
void CSVWorld::TableSubView::rowActivated (const QModelIndex& index)
|
void CSVWorld::TableSubView::rowActivated (const QModelIndex& index)
|
||||||
{
|
{
|
||||||
/// \todo re-enable, after dialogue sub views have been fixed up
|
focusId (mTable->getUniversalId (index.row()));
|
||||||
// focusId (mTable->getUniversalId (index.row()));
|
|
||||||
}
|
}
|
|
@ -54,7 +54,7 @@ add_component_dir (files
|
||||||
add_component_dir (compiler
|
add_component_dir (compiler
|
||||||
context controlparser errorhandler exception exprparser extensions fileparser generator
|
context controlparser errorhandler exception exprparser extensions fileparser generator
|
||||||
lineparser literals locals output parser scanner scriptparser skipparser streamerrorhandler
|
lineparser literals locals output parser scanner scriptparser skipparser streamerrorhandler
|
||||||
stringparser tokenloc
|
stringparser tokenloc nullerrorhandler
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (interpreter
|
add_component_dir (interpreter
|
||||||
|
|
6
components/compiler/nullerrorhandler.cpp
Normal file
6
components/compiler/nullerrorhandler.cpp
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
#include "nullerrorhandler.hpp"
|
||||||
|
|
||||||
|
void Compiler::NullErrorHandler::report (const std::string& message, const TokenLoc& loc, Type type) {}
|
||||||
|
|
||||||
|
void Compiler::NullErrorHandler::report (const std::string& message, Type type) {}
|
21
components/compiler/nullerrorhandler.hpp
Normal file
21
components/compiler/nullerrorhandler.hpp
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
#ifndef COMPILER_NULLERRORHANDLER_H_INCLUDED
|
||||||
|
#define COMPILER_NULLERRORHANDLER_H_INCLUDED
|
||||||
|
|
||||||
|
#include "errorhandler.hpp"
|
||||||
|
|
||||||
|
namespace Compiler
|
||||||
|
{
|
||||||
|
/// \brief Error handler implementation: Ignore all error messages
|
||||||
|
|
||||||
|
class NullErrorHandler : public ErrorHandler
|
||||||
|
{
|
||||||
|
virtual void report (const std::string& message, const TokenLoc& loc, Type type);
|
||||||
|
///< Report error to the user.
|
||||||
|
|
||||||
|
virtual void report (const std::string& message, Type type);
|
||||||
|
///< Report a file related error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -148,6 +148,11 @@ namespace Compiler
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Parser::parseComment (const std::string& comment, const TokenLoc& loc, Scanner& scanner)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle an EOF token.
|
// Handle an EOF token.
|
||||||
//
|
//
|
||||||
// - Default-implementation: Report an error.
|
// - Default-implementation: Report an error.
|
||||||
|
|
|
@ -82,6 +82,13 @@ namespace Compiler
|
||||||
///
|
///
|
||||||
/// - Default-implementation: Report an error.
|
/// - Default-implementation: Report an error.
|
||||||
|
|
||||||
|
virtual bool parseComment (const std::string& comment, const TokenLoc& loc,
|
||||||
|
Scanner& scanner);
|
||||||
|
///< Handle comment token.
|
||||||
|
/// \return fetch another token?
|
||||||
|
///
|
||||||
|
/// - Default-implementation: ignored (and return true).
|
||||||
|
|
||||||
virtual void parseEOF (Scanner& scanner);
|
virtual void parseEOF (Scanner& scanner);
|
||||||
///< Handle EOF token.
|
///< Handle EOF token.
|
||||||
///
|
///
|
||||||
|
|
|
@ -88,6 +88,10 @@ namespace Compiler
|
||||||
}
|
}
|
||||||
else if (c==';')
|
else if (c==';')
|
||||||
{
|
{
|
||||||
|
std::string comment;
|
||||||
|
|
||||||
|
comment += c;
|
||||||
|
|
||||||
while (get (c))
|
while (get (c))
|
||||||
{
|
{
|
||||||
if (c=='\n')
|
if (c=='\n')
|
||||||
|
@ -95,11 +99,14 @@ namespace Compiler
|
||||||
putback (c);
|
putback (c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
comment += c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TokenLoc loc (mLoc);
|
||||||
mLoc.mLiteral.clear();
|
mLoc.mLiteral.clear();
|
||||||
|
|
||||||
return true;
|
return parser.parseComment (comment, loc, *this);
|
||||||
}
|
}
|
||||||
else if (isWhitespace (c))
|
else if (isWhitespace (c))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue