-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathConfig.cpp
265 lines (230 loc) · 7.58 KB
/
Config.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
/*
Name : Config.cpp
Author : Charles N. Burns (charlesnburns|gmail|com / burnchar|isu|edu)
Date : August 2009
License : GPL3. See license.txt or www.gnu.org/licenses/gpl-3.0.txt
Requirements: Qt 4, data to parse, any spreadsheet program.
Notes : Best viewed with tab width 4.
Description : The Config class reads, rebuilds, and verifies the program's
XML configuration file. If no such file exists, it generates
a default file. This file stores all program settings and
stores the most recently used settings for all fields.
*/
#include "Config.h"
//! Constructor for Config class
Config::Config()
{
this->limitRows = DEFAULT_LIMIT_ROWS;
this->colCount = DEFAULT_COLUMN_COUNT;
this->boxOpen = DEFAULT_BOX_OPEN;
}
//! Attempts to read the configuration file
bool Config::xmlRead(const QString &fileURI, const QString &rootTagName)
{
bool retval = true;
QDomDocument doc;
QDomElement root;
QFile file(fileURI);
if(! file.open(QFile::ReadOnly | QFile::Text)) {
errorMessage = "Settings file doesn't seem to exist.";
retval = xmlWrite(fileURI);
if(retval == false) {
errorMessage = "Unable to read or create settings file: " + fileURI;
}
}
else {
int errorLine, errorColumn;
QString errorStr;
if(!doc.setContent(&file, &errorStr, &errorLine, &errorColumn)) {
errorMessage = QString(
"Cannot get settings from %1 because of a problem with line %2, column %3. The error message was: %4")
.arg(fileURI)
.arg(errorLine)
.arg(errorColumn)
.arg(errorStr);
retval = false;
}
else file.close();
}
if(! rootTagName.isEmpty()) {
this->rootElement = doc.documentElement();
if(rootElement.tagName() != rootTagName) {
retval = false;
}
}
return retval;
}
//! Looks at main XML tags, then calls the appropriate parsing function.
//! @returns true
bool Config::xmlParse()
{
bool retval = true;
QDomNode child = this->rootElement.firstChild();
QString tagName;
while(!child.isNull()) {
tagName = child.toElement().tagName();
if(tagName == "pathlist")
parsePathlistElement(child.toElement());
else if(tagName == "options")
parseOptionsElement(child.toElement());
else if(tagName == "columns")
parseColumnElement(child.toElement());
child = child.nextSibling();
}
return retval;
}
//! Parses the child nodes of <pathlist>, and extracts the file paths.
//! @see xmlParse()
void Config::parsePathlistElement(const QDomElement &element)
{
QString attrib;
QString tagName;
QDomNode child = element.firstChild();
attrib = element.attribute("type", "none");
if(attrib == "infile") {
while(!child.isNull()) {
tagName = child.toElement().tagName();
this->pathlistInfile.append(child.toElement().text().trimmed());
child = child.nextSibling();
}
}
else if(attrib == "outfile") {
while(!child.isNull()) {
tagName = child.toElement().tagName();
this->pathlistOutfile.append(child.toElement().text().trimmed());
child = child.nextSibling();
}
}
}
//! Parses the child nodes of <options>, gets program settings
//! @see xmlParse()
void Config::parseOptionsElement(const QDomElement &element)
{
QDomNode child = element.firstChild();
QString tagName, text;
while(!child.isNull()) {
tagName = child.toElement().tagName();
text = child.toElement().text().trimmed();
if(tagName == "openbox" && text == "checked") this->boxOpen = true;
else if(tagName == "columncount") {
int temp = text.toInt();
if(temp > 0 && temp <= 255) this->colCount = temp;
}
else if(tagName == "limitrows") this->limitRows = text;
child = child.nextSibling();
}
}
//! Parses the child nodes of <columns>, gets the name, etc. for all columns.
//! @see xmlParse()
void Config::parseColumnElement(const QDomElement &element)
{
QDomNode child = element.firstChild();
QString index, name, bytecount, counterbox;
while(!child.isNull()) {
index = child.toElement().attribute("index", "0");
name = child.toElement().attribute("name", "0");
bytecount = child.toElement().attribute("bytes", "1");
counterbox = child.toElement().attribute("counterbox", "0");
QDomNode colChild = child.firstChild();
QString innerTagName, innerText;
QStringList sl;
while(! colChild.isNull()) {
innerTagName = colChild.toElement().tagName();
if(innerTagName == "name")
sl.append(colChild.toElement().text().trimmed());
colChild = colChild.nextSibling();
}
colBytes.append(quint8(bytecount.toInt()));
if(counterbox == "checked") colBoxChecked.append(true);
else colBoxChecked.append(false);
colNames.append(sl);
child = child.nextSibling();
}
}
//! Writes the contents of Config data structures to a formatted XML file
//! @returns false if output fill cannot be opened, true otherwise
//! @see xmlRead()
bool Config::xmlWrite(const QString &fileURI)
{
bool retval = true;
QFile file(fileURI);
if(! file.open(QFile::WriteOnly | QFile::Text)) {
errorMessage = QString("Cannot write to file: %1").arg(fileURI);
retval = false;
}
else {
QXmlStreamWriter xml(&file);
xml.setAutoFormatting(true);
xml.setAutoFormattingIndent(-1); // -1: Use 1 tab for formatting
xml.writeStartDocument();
xml.writeStartElement(DEFAULT_START_ELEMENT);
xmlWriteInfilePaths(xml);
xmlWriteOutfilePaths(xml);
xmlWriteOptions(xml);
xmlWriteColumns(xml);
xml.writeEndDocument();
file.close();
}
return retval;
}
//! Writes the list of input file paths to the XML stream
//! @see xmlWrite()
void Config::xmlWriteInfilePaths(QXmlStreamWriter &xml)
{
xml.writeStartElement("pathlist");
xml.writeAttribute("type", "infile");
for(int counter = 0; counter < pathlistInfile.size(); ++counter) {
xml.writeTextElement("path", pathlistInfile.at(counter));
}
xml.writeEndElement();
}
//! Writes the list of output file paths to the XML stream
//! @see xmlWrite()
void Config::xmlWriteOutfilePaths(QXmlStreamWriter &xml)
{
xml.writeStartElement("pathlist");
xml.writeAttribute("type", "outfile");
for(int counter = 0; counter < pathlistOutfile.size(); ++counter) {
xml.writeTextElement("path", pathlistOutfile.at(counter));
}
xml.writeEndElement();
}
//! Writes the list of program options to the XML stream
//! @see xmlWrite()
void Config::xmlWriteOptions(QXmlStreamWriter &xml)
{
xml.writeStartElement("options");
xml.writeTextElement("openbox", boxOpen ? "checked" : "unchecked");
xml.writeTextElement("limitrows", limitRows);
xml.writeTextElement("columncount", QString::number(colCount));
xml.writeEndElement();
}
//! Writes the column data (name, # bytes, etc.) to XML stream.
//! @see xmlWrite()
void Config::xmlWriteColumns(QXmlStreamWriter &xml)
{
xml.writeStartElement("columns");
for(int counter = 0; counter < colNames.size(); ++counter) {
xml.writeStartElement("column");
xml.writeAttribute("index", QString::number(counter));
xml.writeAttribute("bytes", QString::number(colBytes.at(counter)));
xml.writeAttribute("counterbox",
colBoxChecked.at(counter) ? "checked" : "unchecked");
for(int names = 0; names < colNames.at(counter).size(); ++names) {
QString tmp = colNames.at(counter).at(names);
xml.writeTextElement("name", colNames.at(counter).at(names));
}
xml.writeEndElement();
}
xml.writeEndElement();
}
//! Clear out all data structures which store configuration information.
void Config::clear()
{
pathlistInfile.clear();
pathlistOutfile.clear();
limitRows.clear();
colNames.clear();
colBoxChecked.clear();
colBytes.clear();
}