forked from leichaojian/qt
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ab33bb6
commit 4a86ea0
Showing
30 changed files
with
2,574 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
#include "cell.h" | ||
|
||
Cell::Cell() | ||
{ | ||
//设置缓存为最新 | ||
setDirty(); | ||
} | ||
|
||
QTableWidgetItem *Cell::clone() const | ||
{ | ||
return new Cell(*this); | ||
} | ||
|
||
void Cell::setData(int role, const QVariant &value) | ||
{ | ||
//通过特定的模式(role)来显示数据(value) | ||
QTableWidgetItem::setData(role, value); | ||
//编辑模式(EditRole)下,单元格需要重新计算 | ||
if (role == Qt::EditRole) | ||
setDirty(); | ||
} | ||
|
||
QVariant Cell::data(int role) const | ||
{ | ||
//显示文本 | ||
if (role == Qt::DisplayRole) { | ||
if (value().isValid()) { | ||
return value().toString(); | ||
} else { | ||
return "####"; | ||
} | ||
} else if (role == Qt::TextAlignmentRole) { | ||
//返回一个对齐方式 | ||
if (value().type() == QVariant::String) { | ||
return int(Qt::AlignLeft | Qt::AlignVCenter); | ||
} else { | ||
return int(Qt::AlignRight | Qt::AlignVCenter); | ||
} | ||
} else { | ||
return QTableWidgetItem::data(role); | ||
} | ||
} | ||
|
||
void Cell::setFormula(const QString &formula) | ||
{ | ||
setData(Qt::EditRole, formula); | ||
} | ||
|
||
QString Cell::formula() const | ||
{ | ||
return data(Qt::EditRole).toString(); | ||
} | ||
|
||
void Cell::setDirty() | ||
{ | ||
cacheIsDirty = true; | ||
} | ||
|
||
const QVariant Invalid; | ||
|
||
//得到单元格的数据 | ||
QVariant Cell::value() const | ||
{ | ||
if (cacheIsDirty) { | ||
cacheIsDirty = false; | ||
|
||
QString formulaStr = formula(); | ||
//数据以单引号(')开头,则为字符串 | ||
if (formulaStr.startsWith('\'')) { | ||
cachedValue = formulaStr.mid(1); | ||
} else if (formulaStr.startsWith('=')) { | ||
cachedValue = Invalid; | ||
QString expr = formulaStr.mid(1); | ||
expr.replace(" ", ""); | ||
expr.append(QChar::Null); | ||
|
||
//为=号情况下,计算公式的值 | ||
int pos = 0; | ||
cachedValue = evalExpression(expr, pos); | ||
if (expr[pos] != QChar::Null) | ||
cachedValue = Invalid; | ||
} else { | ||
//否则,为double类型 | ||
bool ok; | ||
double d = formulaStr.toDouble(&ok); | ||
if (ok) { | ||
cachedValue = d; | ||
} else { | ||
cachedValue = formulaStr; | ||
} | ||
} | ||
} | ||
return cachedValue; | ||
} | ||
|
||
QVariant Cell::evalExpression(const QString &str, int &pos) const | ||
{ | ||
QVariant result = evalTerm(str, pos); | ||
while (str[pos] != QChar::Null) { | ||
QChar op = str[pos]; | ||
if (op != '+' && op != '-') | ||
return result; | ||
++pos; | ||
|
||
QVariant term = evalTerm(str, pos); | ||
if (result.type() == QVariant::Double | ||
&& term.type() == QVariant::Double) { | ||
if (op == '+') { | ||
result = result.toDouble() + term.toDouble(); | ||
} else { | ||
result = result.toDouble() - term.toDouble(); | ||
} | ||
} else { | ||
result = Invalid; | ||
} | ||
} | ||
return result; | ||
} | ||
|
||
QVariant Cell::evalTerm(const QString &str, int &pos) const | ||
{ | ||
QVariant result = evalFactor(str, pos); | ||
while (str[pos] != QChar::Null) { | ||
QChar op = str[pos]; | ||
if (op != '*' && op != '/') | ||
return result; | ||
++pos; | ||
|
||
QVariant factor = evalFactor(str, pos); | ||
if (result.type() == QVariant::Double | ||
&& factor.type() == QVariant::Double) { | ||
if (op == '*') { | ||
result = result.toDouble() * factor.toDouble(); | ||
} else { | ||
if (factor.toDouble() == 0.0) { | ||
result = Invalid; | ||
} else { | ||
result = result.toDouble() / factor.toDouble(); | ||
} | ||
} | ||
} else { | ||
result = Invalid; | ||
} | ||
} | ||
return result; | ||
} | ||
|
||
QVariant Cell::evalFactor(const QString &str, int &pos) const | ||
{ | ||
QVariant result; | ||
bool negative = false; | ||
|
||
if (str[pos] == '-') { | ||
negative = true; | ||
++pos; | ||
} | ||
|
||
if (str[pos] == '(') { | ||
++pos; | ||
result = evalExpression(str, pos); | ||
if (str[pos] != ')') | ||
result = Invalid; | ||
++pos; | ||
} else { | ||
QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}"); | ||
QString token; | ||
|
||
while (str[pos].isLetterOrNumber() || str[pos] == '.') { | ||
token += str[pos]; | ||
++pos; | ||
} | ||
|
||
if (regExp.exactMatch(token)) { | ||
int column = token[0].toUpper().unicode() - 'A'; | ||
int row = token.mid(1).toInt() - 1; | ||
|
||
Cell *c = static_cast<Cell *>( | ||
tableWidget()->item(row, column)); | ||
if (c) { | ||
result = c->value(); | ||
} else { | ||
result = 0.0; | ||
} | ||
} else { | ||
bool ok; | ||
result = token.toDouble(&ok); | ||
if (!ok) | ||
result = Invalid; | ||
} | ||
} | ||
|
||
if (negative) { | ||
if (result.type() == QVariant::Double) { | ||
result = -result.toDouble(); | ||
} else { | ||
result = Invalid; | ||
} | ||
} | ||
return result; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#ifndef CELL_H | ||
#define CELL_H | ||
|
||
#include <QTableWidgetItem> | ||
|
||
class Cell : public QTableWidgetItem | ||
{ | ||
public: | ||
Cell(); | ||
|
||
QTableWidgetItem *clone() const; | ||
void setData(int role, const QVariant &value); | ||
QVariant data(int role) const; | ||
void setFormula(const QString &formula); | ||
QString formula() const; | ||
void setDirty(); | ||
|
||
private: | ||
QVariant value() const; | ||
QVariant evalExpression(const QString &str, int &pos) const; | ||
QVariant evalTerm(const QString &str, int &pos) const; | ||
QVariant evalFactor(const QString &str, int &pos) const; | ||
|
||
mutable QVariant cachedValue; | ||
//如果缓存不是最新的,则cacheIsDirty=true | ||
mutable bool cacheIsDirty; | ||
}; | ||
|
||
#endif // CELL_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#include "finddialog.h" | ||
|
||
FindDialog::FindDialog(QWidget *parent) : | ||
QDialog(parent) | ||
{ | ||
label = new QLabel(tr("Find &what:")); | ||
lineEdit = new QLineEdit; | ||
label->setBuddy(lineEdit); | ||
|
||
caseCheckBox = new QCheckBox(tr("Match &case")); | ||
backwardCheckBox = new QCheckBox(tr("Search &backward")); | ||
|
||
findButton = new QPushButton(tr("&Find")); | ||
findButton->setDefault(true); | ||
findButton->setEnabled(false); | ||
|
||
closeButton = new QPushButton(tr("Close")); | ||
|
||
connect(lineEdit, SIGNAL(textChanged(const QString &)), | ||
this, SLOT(enableFindButton(const QString &))); | ||
connect(findButton, SIGNAL(clicked()), | ||
this, SLOT(findClicked())); | ||
connect(closeButton, SIGNAL(clicked()), | ||
this, SLOT(close())); | ||
|
||
QHBoxLayout *topLeftLayout = new QHBoxLayout; | ||
topLeftLayout->addWidget(label); | ||
topLeftLayout->addWidget(lineEdit); | ||
|
||
QVBoxLayout *leftLayout = new QVBoxLayout; | ||
leftLayout->addLayout(topLeftLayout); | ||
leftLayout->addWidget(caseCheckBox); | ||
leftLayout->addWidget(backwardCheckBox); | ||
|
||
QVBoxLayout *rightLayout = new QVBoxLayout; | ||
rightLayout->addWidget(findButton); | ||
rightLayout->addWidget(closeButton); | ||
rightLayout->addStretch(); | ||
|
||
QHBoxLayout *mainLayout = new QHBoxLayout; | ||
mainLayout->addLayout(leftLayout); | ||
mainLayout->addLayout(rightLayout); | ||
setLayout(mainLayout); | ||
|
||
setWindowTitle(tr("Find")); | ||
setFixedHeight(sizeHint().height()); | ||
} | ||
|
||
void FindDialog::findClicked() | ||
{ | ||
QString text = lineEdit->text(); | ||
Qt::CaseSensitivity cs = | ||
caseCheckBox->isChecked() ? Qt::CaseSensitive | ||
: Qt::CaseInsensitive; | ||
if (backwardCheckBox->isChecked()) { | ||
emit findPrevious(text, cs); | ||
} else { | ||
emit findNext(text, cs); | ||
} | ||
} | ||
|
||
void FindDialog::enableFindButton(const QString &text) | ||
{ | ||
findButton->setEnabled(!text.isEmpty()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#ifndef FINDDIALOG_H | ||
#define FINDDIALOG_H | ||
|
||
#include <QDialog> | ||
#include <QCheckBox> | ||
#include <QLabel> | ||
#include <QLineEdit> | ||
#include <QPushButton> | ||
#include <QHBoxLayout> | ||
|
||
class FindDialog : public QDialog | ||
{ | ||
Q_OBJECT | ||
public: | ||
explicit FindDialog(QWidget *parent = 0); | ||
|
||
signals: | ||
void findNext(const QString &str, Qt::CaseSensitivity cs); | ||
void findPrevious(const QString &str, Qt::CaseSensitivity cs); | ||
|
||
public slots: | ||
void findClicked(); | ||
void enableFindButton(const QString &text); | ||
|
||
private: | ||
QLabel *label; | ||
QLineEdit *lineEdit; | ||
QCheckBox *caseCheckBox; | ||
QCheckBox *backwardCheckBox; | ||
QPushButton *findButton; | ||
QPushButton *closeButton; | ||
}; | ||
|
||
#endif // FINDDIALOG_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#include <QtGui> | ||
|
||
#include "gotocelldialog.h" | ||
|
||
GoToCellDialog::GoToCellDialog(QWidget *parent) | ||
: QDialog(parent) | ||
{ | ||
setupUi(this); | ||
buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); | ||
|
||
QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}"); | ||
lineEdit->setValidator(new QRegExpValidator(regExp, this)); | ||
|
||
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); | ||
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); | ||
} | ||
|
||
void GoToCellDialog::on_lineEdit_textChanged() | ||
{ | ||
buttonBox->button(QDialogButtonBox::Ok)->setEnabled( | ||
lineEdit->hasAcceptableInput()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#ifndef GOTOCELLDIALOG_H | ||
#define GOTOCELLDIALOG_H | ||
|
||
#include <QDialog> | ||
#include <QPushButton> | ||
|
||
#include "ui_gotocelldialog.h" | ||
|
||
class GoToCellDialog : public QDialog, public Ui::GoToCellDialog | ||
{ | ||
Q_OBJECT | ||
|
||
public: | ||
GoToCellDialog(QWidget *parent = 0); | ||
|
||
private slots: | ||
void on_lineEdit_textChanged(); | ||
}; | ||
|
||
#endif |
Oops, something went wrong.