diff -r 000000000000 -r 1918ee327afb demos/spreadsheet/spreadsheetitem.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demos/spreadsheet/spreadsheetitem.cpp Mon Jan 11 14:00:40 2010 +0000 @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "spreadsheetitem.h" + +SpreadSheetItem::SpreadSheetItem() + : QTableWidgetItem(), isResolving(false) +{ +} + +SpreadSheetItem::SpreadSheetItem(const QString &text) + : QTableWidgetItem(text), isResolving(false) +{ +} + +QTableWidgetItem *SpreadSheetItem::clone() const +{ + SpreadSheetItem *item = new SpreadSheetItem(); + *item = *this; + return item; +} + +QVariant SpreadSheetItem::data(int role) const +{ + if (role == Qt::EditRole || role == Qt::StatusTipRole) + return formula(); + + if (role == Qt::DisplayRole) + return display(); + + QString t = display().toString(); + bool isNumber = false; + int number = t.toInt(&isNumber); + + if (role == Qt::TextColorRole) { + if (!isNumber) + return qVariantFromValue(QColor(Qt::black)); + else if (number < 0) + return qVariantFromValue(QColor(Qt::red)); + return qVariantFromValue(QColor(Qt::blue)); + } + + if (role == Qt::TextAlignmentRole) + if (!t.isEmpty() && (t.at(0).isNumber() || t.at(0) == '-')) + return (int)(Qt::AlignRight | Qt::AlignVCenter); + + return QTableWidgetItem::data(role); + } + +void SpreadSheetItem::setData(int role, const QVariant &value) +{ + QTableWidgetItem::setData(role, value); + if (tableWidget()) + tableWidget()->viewport()->update(); +} + +QVariant SpreadSheetItem::display() const +{ + // avoid circular dependencies + if (isResolving) + return QVariant(); + + isResolving = true; + QVariant result = computeFormula(formula(), tableWidget(), this); + isResolving = false; + return result; +} + +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; +} +