2 // C++ Implementation: settingssheet
7 // Author: Mike Taverne <mtaverne@engits.com>, (C) 2009
9 // Copyright: See COPYING file that comes with this distribution
13 #include <QMessageBox>
14 #include <QApplication>
16 #include "egvtkobject.h"
17 #include "settingssheet.h"
18 #include "vertexdelegate.h"
22 /* Here is how we we get QTextStreams that look like iostreams */
23 QTextStream
Qcin2(stdin
, QIODevice::ReadOnly
);
24 QTextStream
Qcout2(stdout
, QIODevice::WriteOnly
);
25 QTextStream
Qcerr2(stderr
, QIODevice::WriteOnly
);
27 SettingsSheet::SettingsSheet(QWidget
*parent
)
28 : QTableWidget(parent
)
33 SettingsSheet::~SettingsSheet()
37 Cell
*SettingsSheet::cell(int row
, int column
) const
39 return static_cast<Cell
*>(item(row
, column
));
42 bool SettingsSheet::readFile(const QString
&fileName
,int verbose
)
45 if (!file
.open(QIODevice::ReadOnly
)) {
46 QMessageBox::warning(this, tr("SettingsSheet"),
47 tr("Cannot read file %1:\n%2.")
49 .arg(file
.errorString()));
53 QDataStream
in(&file
);
54 in
.setVersion(QDataStream::Qt_4_1
);
58 if (magic
!= MagicNumber
) {
59 QMessageBox::warning(this, tr("SettingsSheet"),tr("The file is not a SettingsSheet file."));
68 /* cout<<"RowCount="<<RowCount<<endl;
69 cout<<"ColumnCount="<<ColumnCount<<endl;*/
71 if(ColumnCount
!=this->columnCount()) {
72 if(verbose
>0) QMessageBox::warning(this, tr("SettingsSheet"),tr("The file is not compatible with the number of boundary codes."));
80 QApplication::setOverrideCursor(Qt::WaitCursor
);
82 this->setRowCount(RowCount
);
83 this->clearContents();
85 // cout<<"===LOADING==="<<endl;
87 in
>> row
>> column
>> str
;
88 // Qcout2<<"row="<<row<<"column="<<column<<"str="<<str<<endl;
89 setFormula(row
, column
, str
);
91 // cout<<"===LOADING DONE==="<<endl;
93 QApplication::restoreOverrideCursor();
97 bool SettingsSheet::writeFile(const QString
&fileName
)
100 if (!file
.open(QIODevice::WriteOnly
)) {
101 QMessageBox::warning(this, tr("SettingsSheet"),
102 tr("Cannot write file %1:\n%2.")
103 .arg(file
.fileName())
104 .arg(file
.errorString()));
108 QDataStream
out(&file
);
109 out
.setVersion(QDataStream::Qt_4_1
);
111 out
<< quint32(MagicNumber
);
113 QApplication::setOverrideCursor(Qt::WaitCursor
);
114 int RowCount
=this->rowCount();
115 int ColumnCount
=this->columnCount();
118 // cout<<"===SAVING==="<<endl;
119 for (int row
= 0; row
< RowCount
; ++row
) {
120 for (int column
= 0; column
< ColumnCount
; ++column
) {
121 QString str
= formula(row
, column
);
122 out
<< quint16(row
) << quint16(column
) << str
;
123 // Qcout2 << quint16(row) <<" "<< quint16(column) <<" "<< str <<endl;
126 // cout<<"===SAVING DONE==="<<endl;
127 QApplication::restoreOverrideCursor();
131 void SettingsSheet::setFormula(int row
, int column
,
132 const QString
&formula
)
134 Cell
*c
= cell(row
, column
);
136 // Qcout2<<" (row,column)="<<"("<<row<<","<<column<<")"<<formula<<endl;
138 setItem(row
, column
, c
);
140 if(column
<this->columnCount()-3){
141 // cout<<" checkbox"<<endl;
142 TriStateTableWidgetItem
*newBC
= new TriStateTableWidgetItem();
143 newBC
->setFlags(Qt::ItemIsTristate
| Qt::ItemIsEnabled
| Qt::ItemIsUserCheckable
);
144 newBC
->setCheckState(int2CheckState(formula
.toInt()));
145 this->setItem(row
, column
, newBC
);
146 // Qcout2<<" (row,column)="<<"("<<row<<","<<column<<")"<<formula<<endl;
149 // cout<<" string"<<endl;
150 c
->setFormula(formula
);
154 QString
SettingsSheet::formula(int row
, int column
) const
156 int RowCount
=this->rowCount();
157 int ColumnCount
=this->columnCount();
158 Cell
*c
= cell(row
, column
);
160 if(column
<ColumnCount
-3){//checkbox
161 return QString::number(CheckState2int(c
->checkState()));
176 QTableWidgetItem
*Cell::clone() const
178 return new Cell(*this);
181 void Cell::setData(int role
, const QVariant
&value
)
183 QTableWidgetItem::setData(role
, value
);
184 if (role
== Qt::EditRole
)
188 QVariant
Cell::data(int role
) const
190 if (role
== Qt::DisplayRole
) {
191 if (value().isValid()) {
192 return value().toString();
196 } else if (role
== Qt::TextAlignmentRole
) {
197 if (value().type() == QVariant::String
) {
198 return int(Qt::AlignLeft
| Qt::AlignVCenter
);
200 return int(Qt::AlignRight
| Qt::AlignVCenter
);
203 return QTableWidgetItem::data(role
);
207 void Cell::setFormula(const QString
&formula
)
209 setData(Qt::EditRole
, formula
);
212 QString
Cell::formula() const
214 return data(Qt::EditRole
).toString();
217 void Cell::setDirty()
222 const QVariant Invalid
;
224 QVariant
Cell::value() const
227 cacheIsDirty
= false;
229 QString formulaStr
= formula();
230 if (formulaStr
.startsWith('\'')) {
231 cachedValue
= formulaStr
.mid(1);
232 } else if (formulaStr
.startsWith('=')) {
233 cachedValue
= Invalid
;
234 QString expr
= formulaStr
.mid(1);
235 expr
.replace(" ", "");
236 expr
.append(QChar::Null
);
239 cachedValue
= evalExpression(expr
, pos
);
240 if (expr
[pos
] != QChar::Null
)
241 cachedValue
= Invalid
;
244 double d
= formulaStr
.toDouble(&ok
);
248 cachedValue
= formulaStr
;
255 QVariant
Cell::evalExpression(const QString
&str
, int &pos
) const
257 QVariant result
= evalTerm(str
, pos
);
258 while (str
[pos
] != QChar::Null
) {
260 if (op
!= '+' && op
!= '-')
264 QVariant term
= evalTerm(str
, pos
);
265 if (result
.type() == QVariant::Double
266 && term
.type() == QVariant::Double
) {
268 result
= result
.toDouble() + term
.toDouble();
270 result
= result
.toDouble() - term
.toDouble();
279 QVariant
Cell::evalTerm(const QString
&str
, int &pos
) const
281 QVariant result
= evalFactor(str
, pos
);
282 while (str
[pos
] != QChar::Null
) {
284 if (op
!= '*' && op
!= '/')
288 QVariant factor
= evalFactor(str
, pos
);
289 if (result
.type() == QVariant::Double
290 && factor
.type() == QVariant::Double
) {
292 result
= result
.toDouble() * factor
.toDouble();
294 if (factor
.toDouble() == 0.0) {
297 result
= result
.toDouble() / factor
.toDouble();
307 QVariant
Cell::evalFactor(const QString
&str
, int &pos
) const
310 bool negative
= false;
312 if (str
[pos
] == '-') {
317 if (str
[pos
] == '(') {
319 result
= evalExpression(str
, pos
);
324 QRegExp
regExp("[A-Za-z][1-9][0-9]{0,2}");
327 while (str
[pos
].isLetterOrNumber() || str
[pos
] == '.') {
332 if (regExp
.exactMatch(token
)) {
333 int column
= token
[0].toUpper().unicode() - 'A';
334 int row
= token
.mid(1).toInt() - 1;
336 Cell
*c
= static_cast<Cell
*>(
337 tableWidget()->item(row
, column
));
345 result
= token
.toDouble(&ok
);
352 if (result
.type() == QVariant::Double
) {
353 result
= -result
.toDouble();