mirror of https://github.com/OpenMW/openmw.git
commit
2e6a8e1b18
@ -0,0 +1,19 @@
|
||||
set(NIFTEST
|
||||
niftest.cpp
|
||||
)
|
||||
source_group(components\\nif\\tests FILES ${NIFTEST})
|
||||
|
||||
# Main executable
|
||||
add_executable(niftest
|
||||
${NIFTEST}
|
||||
)
|
||||
|
||||
target_link_libraries(niftest
|
||||
${Boost_FILESYSTEM_LIBRARY}
|
||||
components
|
||||
)
|
||||
|
||||
if (BUILD_WITH_CODE_COVERAGE)
|
||||
add_definitions (--coverage)
|
||||
target_link_libraries(niftest gcov)
|
||||
endif()
|
@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
#Script to test all nif files (both loose, and in BSA archives) in data files directory
|
||||
|
||||
#The user input as an absolute path
|
||||
DATAFILESDIR="`readlink -m "$1"`"
|
||||
#Program used to test
|
||||
TEST_PROG="`pwd`/niftest"
|
||||
|
||||
#Make sure our files don't bother anyone
|
||||
NIFTEST_TMP_DIR="/tmp/niftest_$RANDOM/"
|
||||
mkdir "$NIFTEST_TMP_DIR"
|
||||
cd "$NIFTEST_TMP_DIR"
|
||||
|
||||
find "$DATAFILESDIR" -iname *bsa > nifs.txt
|
||||
find "$DATAFILESDIR" -iname *nif >> nifs.txt
|
||||
|
||||
sed -e 's/.*/\"&\"/' nifs.txt > quoted_nifs.txt
|
||||
|
||||
xargs --arg-file=quoted_nifs.txt "$TEST_PROG" 2>&1 | tee nif_out.txt
|
||||
# xargs --arg-file=quoted_nifs.txt "$TEST_PROG" 2> nif_out.txt >/dev/null
|
||||
|
||||
echo "List of bad NIF Files:"
|
||||
cat nif_out.txt|grep File:|cut -d ' ' -f 2-
|
||||
|
||||
rm nifs.txt
|
||||
rm quoted_nifs.txt
|
||||
rm nif_out.txt
|
||||
rmdir "$NIFTEST_TMP_DIR"
|
@ -0,0 +1,87 @@
|
||||
///Program to test .nif files both on the FileSystem and in BSA archives.
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <components/nif/niffile.hpp>
|
||||
#include <components/files/constrainedfilestream.hpp>
|
||||
#include <components/vfs/manager.hpp>
|
||||
#include <components/vfs/bsaarchive.hpp>
|
||||
|
||||
|
||||
///See if the file has the named extension
|
||||
bool hasExtension(std::string filename, std::string extensionToFind)
|
||||
{
|
||||
std::string extension = filename.substr(filename.find_last_of(".")+1);
|
||||
|
||||
//Convert strings to lower case for comparison
|
||||
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
|
||||
std::transform(extensionToFind.begin(), extensionToFind.end(), extensionToFind.begin(), ::tolower);
|
||||
|
||||
if(extension == extensionToFind)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
///See if the file has the "nif" extension.
|
||||
bool isNIF(std::string filename)
|
||||
{
|
||||
return hasExtension(filename,"nif");
|
||||
}
|
||||
///See if the file has the "bsa" extension.
|
||||
bool isBSA(std::string filename)
|
||||
{
|
||||
return hasExtension(filename,"bsa");
|
||||
}
|
||||
|
||||
///Check all the nif files in the given BSA archive
|
||||
void readBSA(std::string filename)
|
||||
{
|
||||
VFS::Manager myManager(false);
|
||||
myManager.addArchive(new VFS::BsaArchive(filename));
|
||||
myManager.buildIndex();
|
||||
|
||||
std::map<std::string, VFS::File*> files=myManager.getIndex();
|
||||
for(std::map<std::string, VFS::File*>::const_iterator it=files.begin(); it!=files.end(); ++it)
|
||||
{
|
||||
std::string name = it->first;
|
||||
if(isNIF(name))
|
||||
{
|
||||
// std::cout << "Decoding: " << name << std::endl;
|
||||
Nif::NIFFile temp_nif(myManager.get(name),name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
std::cout << "Reading Files" << std::endl;
|
||||
for(int i = 1; i<argc;i++)
|
||||
{
|
||||
std::string name = argv[i];
|
||||
|
||||
try{
|
||||
if(isNIF(name))
|
||||
{
|
||||
//std::cout << "Decoding: " << name << std::endl;
|
||||
Nif::NIFFile temp_nif(Files::openConstrainedFileStream(name.c_str()),name);
|
||||
}
|
||||
else if(isBSA(name))
|
||||
{
|
||||
std::cout << "Reading BSA File: " << name << std::endl;
|
||||
readBSA(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "ERROR: \"" << name << "\" is not a nif or bsa file!" << std::endl;
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cerr << "ERROR, an exception has occurred: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,239 @@
|
||||
#include "extendedcommandconfigurator.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QGroupBox>
|
||||
#include <QCheckBox>
|
||||
#include <QLabel>
|
||||
#include <QLayout>
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
||||
#include "../../model/world/commanddispatcher.hpp"
|
||||
#include "../../model/world/data.hpp"
|
||||
|
||||
CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Document &document,
|
||||
const CSMWorld::UniversalId &id,
|
||||
QWidget *parent)
|
||||
: QWidget(parent),
|
||||
mNumUsedCheckBoxes(0),
|
||||
mNumChecked(0),
|
||||
mMode(Mode_None),
|
||||
mData(document.getData()),
|
||||
mEditLock(false)
|
||||
{
|
||||
mCommandDispatcher = new CSMWorld::CommandDispatcher(document, id, this);
|
||||
|
||||
connect(&mData, SIGNAL(idListChanged()), this, SLOT(dataIdListChanged()));
|
||||
|
||||
mPerformButton = new QPushButton(this);
|
||||
mPerformButton->setDefault(true);
|
||||
mPerformButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
connect(mPerformButton, SIGNAL(clicked(bool)), this, SLOT(performExtendedCommand()));
|
||||
|
||||
mCancelButton = new QPushButton("Cancel", this);
|
||||
mCancelButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
connect(mCancelButton, SIGNAL(clicked(bool)), this, SIGNAL(done()));
|
||||
|
||||
mTypeGroup = new QGroupBox(this);
|
||||
|
||||
QGridLayout *groupLayout = new QGridLayout(mTypeGroup);
|
||||
groupLayout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
mTypeGroup->setLayout(groupLayout);
|
||||
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout(this);
|
||||
mainLayout->setSizeConstraint(QLayout::SetNoConstraint);
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
mainLayout->addWidget(mTypeGroup);
|
||||
mainLayout->addWidget(mPerformButton);
|
||||
mainLayout->addWidget(mCancelButton);
|
||||
}
|
||||
|
||||
void CSVWorld::ExtendedCommandConfigurator::configure(CSVWorld::ExtendedCommandConfigurator::Mode mode,
|
||||
const std::vector<std::string> &selectedIds)
|
||||
{
|
||||
mMode = mode;
|
||||
if (mMode != Mode_None)
|
||||
{
|
||||
mPerformButton->setText((mMode == Mode_Delete) ? "Extended Delete" : "Extended Revert");
|
||||
mSelectedIds = selectedIds;
|
||||
mCommandDispatcher->setSelection(mSelectedIds);
|
||||
|
||||
setupCheckBoxes(mCommandDispatcher->getExtendedTypes());
|
||||
setupGroupLayout();
|
||||
lockWidgets(mEditLock);
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::ExtendedCommandConfigurator::setEditLock(bool locked)
|
||||
{
|
||||
if (mEditLock != locked)
|
||||
{
|
||||
mEditLock = locked;
|
||||
lockWidgets(mEditLock);
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::ExtendedCommandConfigurator::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
setupGroupLayout();
|
||||
}
|
||||
|
||||
void CSVWorld::ExtendedCommandConfigurator::setupGroupLayout()
|
||||
{
|
||||
if (mMode == Mode_None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int groupWidth = mTypeGroup->geometry().width();
|
||||
QGridLayout *layout = qobject_cast<QGridLayout *>(mTypeGroup->layout());
|
||||
|
||||
// Find the optimal number of rows to place the checkboxes within the available space
|
||||
int divider = 1;
|
||||
do
|
||||
{
|
||||
while (layout->itemAt(0) != NULL)
|
||||
{
|
||||
layout->removeItem(layout->itemAt(0));
|
||||
}
|
||||
|
||||
int counter = 0;
|
||||
int itemsPerRow = mNumUsedCheckBoxes / divider;
|
||||
CheckBoxMap::const_iterator current = mTypeCheckBoxes.begin();
|
||||
CheckBoxMap::const_iterator end = mTypeCheckBoxes.end();
|
||||
for (; current != end; ++current)
|
||||
{
|
||||
if (counter < mNumUsedCheckBoxes)
|
||||
{
|
||||
int row = counter / itemsPerRow;
|
||||
int column = counter - (counter / itemsPerRow) * itemsPerRow;
|
||||
layout->addWidget(current->first, row, column);
|
||||
}
|
||||
++counter;
|
||||
}
|
||||
divider *= 2;
|
||||
}
|
||||
while (groupWidth < mTypeGroup->sizeHint().width() && divider <= mNumUsedCheckBoxes);
|
||||
}
|
||||
|
||||
void CSVWorld::ExtendedCommandConfigurator::setupCheckBoxes(const std::vector<CSMWorld::UniversalId> &types)
|
||||
{
|
||||
// Make sure that we have enough checkboxes
|
||||
int numTypes = static_cast<int>(types.size());
|
||||
int numCheckBoxes = static_cast<int>(mTypeCheckBoxes.size());
|
||||
if (numTypes > numCheckBoxes)
|
||||
{
|
||||
for (int i = numTypes - numCheckBoxes; i > 0; --i)
|
||||
{
|
||||
QCheckBox *checkBox = new QCheckBox(mTypeGroup);
|
||||
connect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(checkBoxStateChanged(int)));
|
||||
mTypeCheckBoxes.insert(std::make_pair(checkBox, CSMWorld::UniversalId::Type_None));
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the checkboxes
|
||||
int counter = 0;
|
||||
CheckBoxMap::iterator current = mTypeCheckBoxes.begin();
|
||||
CheckBoxMap::iterator end = mTypeCheckBoxes.end();
|
||||
for (; current != end; ++current)
|
||||
{
|
||||
if (counter < numTypes)
|
||||
{
|
||||
CSMWorld::UniversalId type = types[counter];
|
||||
current->first->setText(QString::fromUtf8(type.getTypeName().c_str()));
|
||||
current->first->setChecked(true);
|
||||
current->second = type;
|
||||
++counter;
|
||||
}
|
||||
else
|
||||
{
|
||||
current->first->hide();
|
||||
}
|
||||
}
|
||||
mNumChecked = mNumUsedCheckBoxes = numTypes;
|
||||
}
|
||||
|
||||
void CSVWorld::ExtendedCommandConfigurator::lockWidgets(bool locked)
|
||||
{
|
||||
mPerformButton->setEnabled(!mEditLock && mNumChecked > 0);
|
||||
|
||||
CheckBoxMap::const_iterator current = mTypeCheckBoxes.begin();
|
||||
CheckBoxMap::const_iterator end = mTypeCheckBoxes.end();
|
||||
for (int i = 0; current != end && i < mNumUsedCheckBoxes; ++current, ++i)
|
||||
{
|
||||
current->first->setEnabled(!mEditLock);
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::ExtendedCommandConfigurator::performExtendedCommand()
|
||||
{
|
||||
std::vector<CSMWorld::UniversalId> types;
|
||||
|
||||
CheckBoxMap::const_iterator current = mTypeCheckBoxes.begin();
|
||||
CheckBoxMap::const_iterator end = mTypeCheckBoxes.end();
|
||||
for (; current != end; ++current)
|
||||
{
|
||||
if (current->first->isChecked())
|
||||
{
|
||||
types.push_back(current->second);
|
||||
}
|
||||
}
|
||||
|
||||
mCommandDispatcher->setExtendedTypes(types);
|
||||
if (mMode == Mode_Delete)
|
||||
{
|
||||
mCommandDispatcher->executeExtendedDelete();
|
||||
}
|
||||
else
|
||||
{
|
||||
mCommandDispatcher->executeExtendedRevert();
|
||||
}
|
||||
emit done();
|
||||
}
|
||||
|
||||
void CSVWorld::ExtendedCommandConfigurator::checkBoxStateChanged(int state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case Qt::Unchecked:
|
||||
--mNumChecked;
|
||||
break;
|
||||
case Qt::Checked:
|
||||
++mNumChecked;
|
||||
break;
|
||||
case Qt::PartiallyChecked: // Not used
|
||||
break;
|
||||
}
|
||||
|
||||
mPerformButton->setEnabled(mNumChecked > 0);
|
||||
}
|
||||
|
||||
void CSVWorld::ExtendedCommandConfigurator::dataIdListChanged()
|
||||
{
|
||||
bool idsRemoved = false;
|
||||
for (int i = 0; i < static_cast<int>(mSelectedIds.size()); ++i)
|
||||
{
|
||||
if (!mData.hasId(mSelectedIds[i]))
|
||||
{
|
||||
std::swap(mSelectedIds[i], mSelectedIds.back());
|
||||
mSelectedIds.pop_back();
|
||||
idsRemoved = true;
|
||||
--i;
|
||||
}
|
||||
}
|
||||
|
||||
// If all selected IDs were removed, cancel the configurator
|
||||
if (mSelectedIds.empty())
|
||||
{
|
||||
emit done();
|
||||
return;
|
||||
}
|
||||
|
||||
if (idsRemoved)
|
||||
{
|
||||
mCommandDispatcher->setSelection(mSelectedIds);
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
#ifndef CSVWORLD_EXTENDEDCOMMANDCONFIGURATOR_HPP
|
||||
#define CSVWORLD_EXTENDEDCOMMANDCONFIGURATOR_HPP
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "../../model/world/universalid.hpp"
|
||||
|
||||
class QPushButton;
|
||||
class QGroupBox;
|
||||
class QCheckBox;
|
||||
class QLabel;
|
||||
class QHBoxLayout;
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Document;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class CommandDispatcher;
|
||||
class Data;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class ExtendedCommandConfigurator : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Mode { Mode_None, Mode_Delete, Mode_Revert };
|
||||
|
||||
private:
|
||||
typedef std::map<QCheckBox *, CSMWorld::UniversalId> CheckBoxMap;
|
||||
|
||||
QPushButton *mPerformButton;
|
||||
QPushButton *mCancelButton;
|
||||
QGroupBox *mTypeGroup;
|
||||
CheckBoxMap mTypeCheckBoxes;
|
||||
int mNumUsedCheckBoxes;
|
||||
int mNumChecked;
|
||||
|
||||
Mode mMode;
|
||||
CSMWorld::CommandDispatcher *mCommandDispatcher;
|
||||
CSMWorld::Data &mData;
|
||||
std::vector<std::string> mSelectedIds;
|
||||
|
||||
bool mEditLock;
|
||||
|
||||
void setupGroupLayout();
|
||||
void setupCheckBoxes(const std::vector<CSMWorld::UniversalId> &types);
|
||||
void lockWidgets(bool locked);
|
||||
|
||||
public:
|
||||
ExtendedCommandConfigurator(CSMDoc::Document &document,
|
||||
const CSMWorld::UniversalId &id,
|
||||
QWidget *parent = 0);
|
||||
|
||||
void configure(Mode mode, const std::vector<std::string> &selectedIds);
|
||||
void setEditLock(bool locked);
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent *event);
|
||||
|
||||
private slots:
|
||||
void performExtendedCommand();
|
||||
void checkBoxStateChanged(int state);
|
||||
void dataIdListChanged();
|
||||
|
||||
signals:
|
||||
void done();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,143 @@
|
||||
|
||||
#include "scripterrortable.hpp"
|
||||
|
||||
#include <QHeaderView>
|
||||
|
||||
#include <components/compiler/tokenloc.hpp>
|
||||
#include <components/compiler/scanner.hpp>
|
||||
#include <components/compiler/fileparser.hpp>
|
||||
#include <components/compiler/exception.hpp>
|
||||
#include <components/compiler/extensions0.hpp>
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
#include "../../model/settings/usersettings.hpp"
|
||||
|
||||
void CSVWorld::ScriptErrorTable::report (const std::string& message, const Compiler::TokenLoc& loc, Type type)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << message << " (" << loc.mLiteral << ")";
|
||||
|
||||
addMessage (stream.str(), type==Compiler::ErrorHandler::WarningMessage ?
|
||||
CSMDoc::Message::Severity_Warning : CSMDoc::Message::Severity_Error,
|
||||
loc.mLine, loc.mColumn-loc.mLiteral.length());
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptErrorTable::report (const std::string& message, Type type)
|
||||
{
|
||||
addMessage (message, type==Compiler::ErrorHandler::WarningMessage ?
|
||||
CSMDoc::Message::Severity_Warning : CSMDoc::Message::Severity_Error);
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptErrorTable::addMessage (const std::string& message,
|
||||
CSMDoc::Message::Severity severity, int line, int column)
|
||||
{
|
||||
int row = rowCount();
|
||||
|
||||
setRowCount (row+1);
|
||||
|
||||
QTableWidgetItem *severityItem = new QTableWidgetItem (
|
||||
QString::fromUtf8 (CSMDoc::Message::toString (severity).c_str()));
|
||||
severityItem->setFlags (severityItem->flags() ^ Qt::ItemIsEditable);
|
||||
setItem (row, 0, severityItem);
|
||||
|
||||
if (line!=-1)
|
||||
{
|
||||
QTableWidgetItem *lineItem = new QTableWidgetItem;
|
||||
lineItem->setData (Qt::DisplayRole, line+1);
|
||||
lineItem->setFlags (lineItem->flags() ^ Qt::ItemIsEditable);
|
||||
setItem (row, 1, lineItem);
|
||||
|
||||
QTableWidgetItem *columnItem = new QTableWidgetItem;
|
||||
columnItem->setData (Qt::DisplayRole, column);
|
||||
columnItem->setFlags (columnItem->flags() ^ Qt::ItemIsEditable);
|
||||
setItem (row, 3, columnItem);
|
||||
}
|
||||
|
||||
QTableWidgetItem *messageItem = new QTableWidgetItem (QString::fromUtf8 (message.c_str()));
|
||||
messageItem->setFlags (messageItem->flags() ^ Qt::ItemIsEditable);
|
||||
setItem (row, 2, messageItem);
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptErrorTable::setWarningsMode (const QString& value)
|
||||
{
|
||||
if (value=="Ignore")
|
||||
Compiler::ErrorHandler::setWarningsMode (0);
|
||||
else if (value=="Normal")
|
||||
Compiler::ErrorHandler::setWarningsMode (1);
|
||||
else if (value=="Strict")
|
||||
Compiler::ErrorHandler::setWarningsMode (2);
|
||||
}
|
||||
|
||||
CSVWorld::ScriptErrorTable::ScriptErrorTable (const CSMDoc::Document& document, QWidget *parent)
|
||||
: QTableWidget (parent), mContext (document.getData())
|
||||
{
|
||||
setColumnCount (4);
|
||||
|
||||
QStringList headers;
|
||||
headers << "Severity" << "Line" << "Description";
|
||||
setHorizontalHeaderLabels (headers);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
horizontalHeader()->setSectionResizeMode (0, QHeaderView::ResizeToContents);
|
||||
horizontalHeader()->setSectionResizeMode (1, QHeaderView::ResizeToContents);
|
||||
#else
|
||||
horizontalHeader()->setResizeMode (0, QHeaderView::ResizeToContents);
|
||||
horizontalHeader()->setResizeMode (1, QHeaderView::ResizeToContents);
|
||||
#endif
|
||||
horizontalHeader()->setStretchLastSection (true);
|
||||
verticalHeader()->hide();
|
||||
setColumnHidden (3, true);
|
||||
|
||||
setSelectionMode (QAbstractItemView::NoSelection);
|
||||
|
||||
Compiler::registerExtensions (mExtensions);
|
||||
mContext.setExtensions (&mExtensions);
|
||||
|
||||
setWarningsMode (CSMSettings::UserSettings::instance().settingValue ("script-editor/warnings"));
|
||||
|
||||
connect (this, SIGNAL (cellClicked (int, int)), this, SLOT (cellClicked (int, int)));
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptErrorTable::updateUserSetting (const QString& name, const QStringList& value)
|
||||
{
|
||||
if (name=="script-editor/warnings" && !value.isEmpty())
|
||||
setWarningsMode (value.at (0));
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptErrorTable::update (const std::string& source)
|
||||
{
|
||||
clear();
|
||||
|
||||
try
|
||||
{
|
||||
std::istringstream input (source);
|
||||
|
||||
Compiler::Scanner scanner (*this, input, mContext.getExtensions());
|
||||
|
||||
Compiler::FileParser parser (*this, mContext);
|
||||
|
||||
scanner.scan (parser);
|
||||
}
|
||||
catch (const Compiler::SourceException&)
|
||||
{
|
||||
// error has already been reported via error handler
|
||||
}
|
||||
catch (const std::exception& error)
|
||||
{
|
||||
addMessage (error.what(), CSMDoc::Message::Severity_SeriousError);
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptErrorTable::clear()
|
||||
{
|
||||
setRowCount (0);
|
||||
}
|
||||
|
||||
void CSVWorld::ScriptErrorTable::cellClicked (int row, int column)
|
||||
{
|
||||
if (item (row, 1))
|
||||
{
|
||||
int scriptLine = item (row, 1)->data (Qt::DisplayRole).toInt();
|
||||
int scriptColumn = item (row, 3)->data (Qt::DisplayRole).toInt();
|
||||
emit highlightError (scriptLine-1, scriptColumn);
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
#ifndef CSV_WORLD_SCRIPTERRORTABLE_H
|
||||
#define CSV_WORLD_SCRIPTERRORTABLE_H
|
||||
|
||||
#include <QTableWidget>
|
||||
|
||||
#include <components/compiler/errorhandler.hpp>
|
||||
#include <components/compiler/extensions.hpp>
|
||||
|
||||
#include "../../model/world/scriptcontext.hpp"
|
||||
#include "../../model/doc/messages.hpp"
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Document;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class ScriptErrorTable : public QTableWidget, private Compiler::ErrorHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Compiler::Extensions mExtensions;
|
||||
CSMWorld::ScriptContext mContext;
|
||||
|
||||
virtual void report (const std::string& message, const Compiler::TokenLoc& loc, Type type);
|
||||
///< Report error to the user.
|
||||
|
||||
virtual void report (const std::string& message, Type type);
|
||||
///< Report a file related error
|
||||
|
||||
void addMessage (const std::string& message, CSMDoc::Message::Severity severity,
|
||||
int line = -1, int column = -1);
|
||||
|
||||
void setWarningsMode (const QString& value);
|
||||
|
||||
public:
|
||||
|
||||
ScriptErrorTable (const CSMDoc::Document& document, QWidget *parent = 0);
|
||||
|
||||
void updateUserSetting (const QString& name, const QStringList& value);
|
||||
|
||||
void update (const std::string& source);
|
||||
|
||||
void clear();
|
||||
|
||||
private slots:
|
||||
|
||||
void cellClicked (int row, int column);
|
||||
|
||||
signals:
|
||||
|
||||
void highlightError (int line, int column);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,49 @@
|
||||
#include "tableeditidaction.hpp"
|
||||
|
||||
#include <QTableView>
|
||||
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
|
||||
CSVWorld::TableEditIdAction::CellData CSVWorld::TableEditIdAction::getCellData(int row, int column) const
|
||||
{
|
||||
QModelIndex index = mTable.model()->index(row, column);
|
||||
if (index.isValid())
|
||||
{
|
||||
QVariant display = mTable.model()->data(index, CSMWorld::ColumnBase::Role_Display);
|
||||
QString value = mTable.model()->data(index).toString();
|
||||
return std::make_pair(static_cast<CSMWorld::ColumnBase::Display>(display.toInt()), value);
|
||||
}
|
||||
return std::make_pair(CSMWorld::ColumnBase::Display_None, "");
|
||||
}
|
||||
|
||||
CSVWorld::TableEditIdAction::TableEditIdAction(const QTableView &table, QWidget *parent)
|
||||
: QAction(parent),
|
||||
mTable(table),
|
||||
mCurrentId(CSMWorld::UniversalId::Type_None)
|
||||
{}
|
||||
|
||||
void CSVWorld::TableEditIdAction::setCell(int row, int column)
|
||||
{
|
||||
CellData data = getCellData(row, column);
|
||||
CSMWorld::UniversalId::Type idType = CSMWorld::TableMimeData::convertEnums(data.first);
|
||||
|
||||
if (idType != CSMWorld::UniversalId::Type_None)
|
||||
{
|
||||
mCurrentId = CSMWorld::UniversalId(idType, data.second.toUtf8().constData());
|
||||
setText("Edit '" + data.second + "'");
|
||||
}
|
||||
}
|
||||
|
||||
CSMWorld::UniversalId CSVWorld::TableEditIdAction::getCurrentId() const
|
||||
{
|
||||
return mCurrentId;
|
||||
}
|
||||
|
||||
bool CSVWorld::TableEditIdAction::isValidIdCell(int row, int column) const
|
||||
{
|
||||
CellData data = getCellData(row, column);
|
||||
CSMWorld::UniversalId::Type idType = CSMWorld::TableMimeData::convertEnums(data.first);
|
||||
return CSMWorld::ColumnBase::isId(data.first) &&
|
||||
idType != CSMWorld::UniversalId::Type_None &&
|
||||
!data.second.isEmpty();
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
#ifndef CSVWORLD_TABLEEDITIDACTION_HPP
|
||||
#define CSVWORLD_TABLEEDITIDACTION_HPP
|
||||
|
||||
#include <QAction>
|
||||
|
||||
#include "../../model/world/columnbase.hpp"
|
||||
#include "../../model/world/universalid.hpp"
|
||||
|
||||
class QTableView;
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class TableEditIdAction : public QAction
|
||||
{
|
||||
const QTableView &mTable;
|
||||
CSMWorld::UniversalId mCurrentId;
|
||||
|
||||
typedef std::pair<CSMWorld::ColumnBase::Display, QString> CellData;
|
||||
CellData getCellData(int row, int column) const;
|
||||
|
||||
public:
|
||||
TableEditIdAction(const QTableView &table, QWidget *parent = 0);
|
||||
|
||||
void setCell(int row, int column);
|
||||
|
||||
CSMWorld::UniversalId getCurrentId() const;
|
||||
bool isValidIdCell(int row, int column) const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue