demos/spreadsheet/spreadsheetitem.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
--- /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;
+}
+