QVariant SpreadSheetItem::computeFormula(const QString &formula, const QTableWidget *widget, const QTableWidgetItem *self) { // check if the s tring is actually a formula or not QStringList list = formula.split(' '); if (list.isEmpty() || !widget) return formula; // it is a normal string QString op = list.value(0).toLower(); int firstRow = -1; int firstCol = -1; int secondRow = -1; int secondCol = -1; if (list.count() > 1) decode_pos(list.value(1), &firstRow, &firstCol); if (list.count() > 2) decode_pos(list.value(2), &secondRow, &secondCol); const QTableWidgetItem *start = widget->item(firstRow, firstCol); const QTableWidgetItem *end = widget->item(secondRow, secondCol); int firstVal = start ? start->text().toInt() : 0; int secondVal = end ? end->text().toInt() : 0; QVariant result; if (op == "sum") { int sum = 0; for (int r = firstRow; r <= secondRow; ++r) { for (int c = firstCol; c <= secondCol; ++c) { const QTableWidgetItem *tableItem = widget->item(r, c); if (tableItem && tableItem != self) sum += tableItem->text().toInt(); } } result = sum; } else if (op == "+") { result = (firstVal + secondVal); } else if (op == "-") { result = (firstVal - secondVal); } else if (op == "*") { result = (firstVal * secondVal); } else if (op == "/") { if (secondVal == 0) result = QString("nan"); else result = (firstVal / secondVal); } else if (op == "=") { if (start) result = start->text(); } else { result = formula; } return result; }
void SpreadSheet::actionMath_helper(const QString &title, const QString &op) { QString cell1 = "C1"; QString cell2 = "C2"; QString out = "C3"; QTableWidgetItem *current = table->currentItem(); if (current) out = encode_pos(table->currentRow(), table->currentColumn()); if (runInputDialog(title, tr("Cell 1"), tr("Cell 2"), op, tr("Output to:"), &cell1, &cell2, &out)) { int row, col; decode_pos(out, &row, &col); table->item(row, col)->setText(tr("%1 %2 %3").arg(op, cell1, cell2)); } }
void SpreadSheet::actionSum() { int row_first = 0; int row_last = 0; int row_cur = 0; int col_first = 0; int col_last = 0; int col_cur = 0; QList<QTableWidgetItem*> selected = table->selectedItems(); if (!selected.isEmpty()) { QTableWidgetItem *first = selected.first(); QTableWidgetItem *last = selected.last(); row_first = table->row(first); row_last = table->row(last); col_first = table->column(first); col_last = table->column(last); } QTableWidgetItem *current = table->currentItem(); if (current) { row_cur = table->row(current); col_cur = table->column(current); } QString cell1 = encode_pos(row_first, col_first); QString cell2 = encode_pos(row_last, col_last); QString out = encode_pos(row_cur, col_cur); if (runInputDialog(tr("Sum cells"), tr("First cell:"), tr("Last cell:"), QString("%1").arg(QChar(0x03a3)), tr("Output to:"), &cell1, &cell2, &out)) { int row; int col; decode_pos(out, &row, &col); table->item(row, col)->setText(tr("sum %1 %2").arg(cell1, cell2)); } }
bool SpreadSheet::runInputDialog(const QString &title, const QString &c1Text, const QString &c2Text, const QString &opText, const QString &outText, QString *cell1, QString *cell2, QString *outCell) { QStringList rows, cols; for (int c = 0; c < table->columnCount(); ++c) cols << QChar('A' + c); for (int r = 0; r < table->rowCount(); ++r) rows << QString::number(1 + r); QDialog addDialog(this); addDialog.setWindowTitle(title); QGroupBox group(title, &addDialog); group.setMinimumSize(250, 100); QLabel cell1Label(c1Text, &group); QComboBox cell1RowInput(&group); int c1Row, c1Col; decode_pos(*cell1, &c1Row, &c1Col); cell1RowInput.addItems(rows); cell1RowInput.setCurrentIndex(c1Row); QComboBox cell1ColInput(&group); cell1ColInput.addItems(cols); cell1ColInput.setCurrentIndex(c1Col); QLabel operatorLabel(opText, &group); operatorLabel.setAlignment(Qt::AlignHCenter); QLabel cell2Label(c2Text, &group); QComboBox cell2RowInput(&group); int c2Row, c2Col; decode_pos(*cell2, &c2Row, &c2Col); cell2RowInput.addItems(rows); cell2RowInput.setCurrentIndex(c2Row); QComboBox cell2ColInput(&group); cell2ColInput.addItems(cols); cell2ColInput.setCurrentIndex(c2Col); QLabel equalsLabel("=", &group); equalsLabel.setAlignment(Qt::AlignHCenter); QLabel outLabel(outText, &group); QComboBox outRowInput(&group); int outRow, outCol; decode_pos(*outCell, &outRow, &outCol); outRowInput.addItems(rows); outRowInput.setCurrentIndex(outRow); QComboBox outColInput(&group); outColInput.addItems(cols); outColInput.setCurrentIndex(outCol); QPushButton cancelButton(tr("Cancel"), &addDialog); connect(&cancelButton, SIGNAL(clicked()), &addDialog, SLOT(reject())); QPushButton okButton(tr("OK"), &addDialog); okButton.setDefault(true); connect(&okButton, SIGNAL(clicked()), &addDialog, SLOT(accept())); QHBoxLayout *buttonsLayout = new QHBoxLayout; buttonsLayout->addStretch(1); buttonsLayout->addWidget(&okButton); buttonsLayout->addSpacing(10); buttonsLayout->addWidget(&cancelButton); QVBoxLayout *dialogLayout = new QVBoxLayout(&addDialog); dialogLayout->addWidget(&group); dialogLayout->addStretch(1); dialogLayout->addItem(buttonsLayout); QHBoxLayout *cell1Layout = new QHBoxLayout; cell1Layout->addWidget(&cell1Label); cell1Layout->addSpacing(10); cell1Layout->addWidget(&cell1ColInput); cell1Layout->addSpacing(10); cell1Layout->addWidget(&cell1RowInput); QHBoxLayout *cell2Layout = new QHBoxLayout; cell2Layout->addWidget(&cell2Label); cell2Layout->addSpacing(10); cell2Layout->addWidget(&cell2ColInput); cell2Layout->addSpacing(10); cell2Layout->addWidget(&cell2RowInput); QHBoxLayout *outLayout = new QHBoxLayout; outLayout->addWidget(&outLabel); outLayout->addSpacing(10); outLayout->addWidget(&outColInput); outLayout->addSpacing(10); outLayout->addWidget(&outRowInput); QVBoxLayout *vLayout = new QVBoxLayout(&group); vLayout->addItem(cell1Layout); vLayout->addWidget(&operatorLabel); vLayout->addItem(cell2Layout); vLayout->addWidget(&equalsLabel); vLayout->addStretch(1); vLayout->addItem(outLayout); if (addDialog.exec()) { *cell1 = cell1ColInput.currentText() + cell1RowInput.currentText(); *cell2 = cell2ColInput.currentText() + cell2RowInput.currentText(); *outCell = outColInput.currentText() + outRowInput.currentText(); return true; } return false; }