1 #include "scripterrortable.hpp"
2 
3 #include <QHeaderView>
4 
5 #include <components/compiler/tokenloc.hpp>
6 #include <components/compiler/scanner.hpp>
7 #include <components/compiler/fileparser.hpp>
8 #include <components/compiler/exception.hpp>
9 #include <components/compiler/extensions0.hpp>
10 
11 #include "../../model/doc/document.hpp"
12 
13 #include "../../model/prefs/state.hpp"
14 
report(const std::string & message,const Compiler::TokenLoc & loc,Type type)15 void CSVWorld::ScriptErrorTable::report (const std::string& message, const Compiler::TokenLoc& loc, Type type)
16 {
17     std::ostringstream stream;
18     stream << message << " (" << loc.mLiteral << ")";
19 
20     addMessage (stream.str(), type==Compiler::ErrorHandler::WarningMessage ?
21         CSMDoc::Message::Severity_Warning : CSMDoc::Message::Severity_Error,
22         loc.mLine, loc.mColumn-loc.mLiteral.length());
23 }
24 
report(const std::string & message,Type type)25 void CSVWorld::ScriptErrorTable::report (const std::string& message, Type type)
26 {
27     addMessage (message, type==Compiler::ErrorHandler::WarningMessage ?
28         CSMDoc::Message::Severity_Warning : CSMDoc::Message::Severity_Error);
29 }
30 
addMessage(const std::string & message,CSMDoc::Message::Severity severity,int line,int column)31 void CSVWorld::ScriptErrorTable::addMessage (const std::string& message,
32     CSMDoc::Message::Severity severity, int line, int column)
33 {
34     int row = rowCount();
35 
36     setRowCount (row+1);
37 
38     QTableWidgetItem *severityItem = new QTableWidgetItem (
39         QString::fromUtf8 (CSMDoc::Message::toString (severity).c_str()));
40     severityItem->setFlags (severityItem->flags() ^ Qt::ItemIsEditable);
41     setItem (row, 0, severityItem);
42 
43     if (line!=-1)
44     {
45         QTableWidgetItem *lineItem = new QTableWidgetItem;
46         lineItem->setData (Qt::DisplayRole, line+1);
47         lineItem->setFlags (lineItem->flags() ^ Qt::ItemIsEditable);
48         setItem (row, 1, lineItem);
49 
50         QTableWidgetItem *columnItem = new QTableWidgetItem;
51         columnItem->setData (Qt::DisplayRole, column);
52         columnItem->setFlags (columnItem->flags() ^ Qt::ItemIsEditable);
53         setItem (row, 3, columnItem);
54     }
55     else
56     {
57         QTableWidgetItem *lineItem = new QTableWidgetItem;
58         lineItem->setData (Qt::DisplayRole, "-");
59         lineItem->setFlags (lineItem->flags() ^ Qt::ItemIsEditable);
60         setItem (row, 1, lineItem);
61     }
62 
63     QTableWidgetItem *messageItem = new QTableWidgetItem (QString::fromUtf8 (message.c_str()));
64     messageItem->setFlags (messageItem->flags() ^ Qt::ItemIsEditable);
65     setItem (row, 2, messageItem);
66 }
67 
setWarningsMode(const std::string & value)68 void CSVWorld::ScriptErrorTable::setWarningsMode (const std::string& value)
69 {
70     if (value=="Ignore")
71         Compiler::ErrorHandler::setWarningsMode (0);
72     else if (value=="Normal")
73         Compiler::ErrorHandler::setWarningsMode (1);
74     else if (value=="Strict")
75         Compiler::ErrorHandler::setWarningsMode (2);
76 }
77 
ScriptErrorTable(const CSMDoc::Document & document,QWidget * parent)78 CSVWorld::ScriptErrorTable::ScriptErrorTable (const CSMDoc::Document& document, QWidget *parent)
79 : QTableWidget (parent), mContext (document.getData())
80 {
81     setColumnCount (4);
82 
83     QStringList headers;
84     headers << "Severity" << "Line" << "Description";
85     setHorizontalHeaderLabels (headers);
86     horizontalHeader()->setSectionResizeMode (0, QHeaderView::ResizeToContents);
87     horizontalHeader()->setSectionResizeMode (1, QHeaderView::ResizeToContents);
88     horizontalHeader()->setStretchLastSection (true);
89     verticalHeader()->hide();
90     setColumnHidden (3, true);
91 
92     setSelectionMode (QAbstractItemView::NoSelection);
93 
94     Compiler::registerExtensions (mExtensions);
95     mContext.setExtensions (&mExtensions);
96 
97     connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
98         this, SLOT (settingChanged (const CSMPrefs::Setting *)));
99     CSMPrefs::get()["Scripts"].update();
100 
101     connect (this, SIGNAL (cellClicked (int, int)), this, SLOT (cellClicked (int, int)));
102 }
103 
update(const std::string & source)104 void CSVWorld::ScriptErrorTable::update (const std::string& source)
105 {
106     clear();
107 
108     try
109     {
110         std::istringstream input (source);
111 
112         Compiler::Scanner scanner (*this, input, mContext.getExtensions());
113 
114         Compiler::FileParser parser (*this, mContext);
115 
116         scanner.scan (parser);
117     }
118     catch (const Compiler::SourceException&)
119     {
120         // error has already been reported via error handler
121     }
122     catch (const std::exception& error)
123     {
124         addMessage (error.what(), CSMDoc::Message::Severity_SeriousError);
125     }
126 }
127 
clear()128 void CSVWorld::ScriptErrorTable::clear()
129 {
130     setRowCount (0);
131 }
132 
clearLocals(const std::string & script)133 bool CSVWorld::ScriptErrorTable::clearLocals (const std::string& script)
134 {
135     return mContext.clearLocals (script);
136 }
137 
settingChanged(const CSMPrefs::Setting * setting)138 void CSVWorld::ScriptErrorTable::settingChanged (const CSMPrefs::Setting *setting)
139 {
140     if (*setting=="Scripts/warnings")
141         setWarningsMode (setting->toString());
142 }
143 
cellClicked(int row,int column)144 void CSVWorld::ScriptErrorTable::cellClicked (int row, int column)
145 {
146     if (item (row, 3))
147     {
148         int scriptLine = item (row, 1)->data (Qt::DisplayRole).toInt();
149         int scriptColumn = item (row, 3)->data (Qt::DisplayRole).toInt();
150         emit highlightError (scriptLine-1, scriptColumn);
151     }
152 }
153