aaadceb by David King at 2010-01-19 1
/* Qlom is copyright Openismus GmbH, 2009
2
 *
3
 * This file is part of Qlom
4
 *
5
 * Qlom is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * Qlom is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with Qlom. If not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
#include "layout_delegates.h"
20
#include "utils.h"
21
22
#include <QRegExp>
23
#include <QStringList>
198616a by Michael Hasselmann at 2010-01-28 24
#include <QAbstractItemView>
25
#include <QPushButton>
826407d by Michael Hasselmann at 2010-01-29 26
#include <QSignalMapper>
aaadceb by David King at 2010-01-19 27
28
QlomFieldFormattingDelegate::QlomFieldFormattingDelegate(
29
    const Glom::FieldFormatting &formatting, const GlomSharedField details,
30
    QObject *parent)
31
    : QStyledItemDelegate(parent), theFormattingUsed(formatting),
32
    theFieldDetails(details)
33
{}
34
35
QlomFieldFormattingDelegate::~QlomFieldFormattingDelegate()
36
{}
37
38
void QlomFieldFormattingDelegate::paint(QPainter *painter,
39
    const QStyleOptionViewItem &option, const QModelIndex &index) const
40
{
41
    QStyleOptionViewItemV4 opt = option;
42
    initStyleOption(&opt, index);
43
44
    QColor::setAllowX11ColorNames(true);
45
    QColor fgColor = painter->pen().color();
46
    QString fgColorName =
47
        ustringToQstring(theFormattingUsed.get_text_format_color_foreground());
48
49
    if (!fgColorName.isEmpty())
50
        fgColor.setNamedColor(fgColorName);
51
52
    QColor bgColor = Qt::transparent;
53
    QString bgColorName =
54
        ustringToQstring(theFormattingUsed.get_text_format_color_background());
55
56
    if (!bgColorName.isEmpty())
57
        bgColor.setNamedColor(bgColorName);
58
59
    /* Tried to set fore- and background via setColor/setBrush and all roles
60
     * listed http://qt.nokia.com/doc/4.6/qpalette.html#ColorRole-enum,
61
     * highlight and text seem to be honored but not backround/base/window. I
62
     * am not too surprised though - we probably need to extend our model to
63
     * return the correct color per index using ItemDataRoles:
64
     * http://doc.trolltech.com/4.6/qt.html#ItemDataRole-enum */
65
    opt.palette.setColor(QPalette::Text, fgColor);
66
67
    // Still draw the background manually.
68
    painter->save();
69
    painter->setBrush(bgColor);
70
    painter->drawRect(opt.rect);
71
    painter->restore();
72
73
    // Forward the modified QStyleOptionViewItem to the parent.
74
    QStyledItemDelegate::paint(painter, opt, index);
75
}
76
77
QSize QlomFieldFormattingDelegate::sizeHint(const QStyleOptionViewItem &option,
78
    const QModelIndex &index) const
79
{
80
    return QStyledItemDelegate::sizeHint(option, index);
81
}
82
83
QlomLayoutItemFieldDelegate::QlomLayoutItemFieldDelegate(
84
    const Glom::FieldFormatting &formatting, const GlomSharedField details,
85
    QObject *parent)
86
    : QlomFieldFormattingDelegate(formatting, details, parent)
87
{}
88
89
QlomLayoutItemFieldDelegate::~QlomLayoutItemFieldDelegate()
90
{}
91
92
QString QlomLayoutItemFieldDelegate::displayText(const QVariant &value,
93
    const QLocale &locale) const
94
{
95
    switch(theFieldDetails->get_glom_type()) {
96
        case Glom::Field::TYPE_NUMERIC:
97
        {
98
            /* Check whether the display text was a double in its previous
99
             * life. If true, remove trailing zeroes and add thousand
100
             * separators (if requested). The Glom numeric type is treated as
101
             * doubles by the Sqlite backend. */
102
            bool conversionSucceeded = false;
103
            double numeric = value.toString().toDouble(&conversionSucceeded);
104
105
            if (conversionSucceeded)
106
                return applyNumericFormatting(numeric, locale);
107
        }
108
        break;
109
110
        case Glom::Field::TYPE_TEXT:
111
            return value.toString();
112
113
        // TODO: handle other display roles correctly.
114
        case Glom::Field::TYPE_INVALID:
115
        case Glom::Field::TYPE_DATE:
116
        case Glom::Field::TYPE_TIME:
117
        case Glom::Field::TYPE_BOOLEAN:
118
        case Glom::Field::TYPE_IMAGE:
119
            return value.toString();
120
121
        default:
122
            break;
123
    }
124
125
    return QString("(not implemented)");
126
}
127
128
QString QlomLayoutItemFieldDelegate::applyNumericFormatting(double numeric,
129
    const QLocale &locale) const
130
{
131
    Glom::NumericFormat numFormat = theFormattingUsed.m_numeric_format;
132
133
    QString currencyPrefix = QString();
134
    if (!numFormat.m_currency_symbol.empty())
135
    {
136
        // Add a whitespace for the currency prefix.
137
        currencyPrefix =
138
            QString("%1 ").arg(ustringToQstring(numFormat.m_currency_symbol));
139
    }
140
141
    QLocale myLocale = QLocale(locale);
142
143
    if(!numFormat.m_use_thousands_separator)
144
        myLocale.setNumberOptions(QLocale::OmitGroupSeparator);
145
    else
146
        myLocale.setNumberOptions(0); // Do not rely on defaults here.
147
148
    // TODO: check max precision in Glom source.
149
    int precision = (numFormat.m_decimal_places_restricted
150
        ? numFormat.m_decimal_places : numFormat.get_default_precision());
151
    /* 'g' trims trailing zeroes, although not documented in [1], whereas 'f'
152
       prints the decimal places instead of using mantisse + exponent.
153
       [1] http://doc.trolltech.com/4.6/qstring.html#argument-formats */
154
    char format = (numFormat.m_decimal_places_restricted ? 'f' : 'g');
155
156
    // This already removes trailing zeroes and also adds thousand separators.
157
    return QString("%1%2").arg(currencyPrefix)
158
        .arg(myLocale.toString(numeric, format, precision));
159
}
160
161
QlomLayoutItemTextDelegate::QlomLayoutItemTextDelegate(
162
    const Glom::FieldFormatting &formatting, const GlomSharedField details,
47c3fbd by Michael Hasselmann at 2010-01-27 163
    const QString &displayText, QObject *parent)
164
    : QlomFieldFormattingDelegate(formatting, details, parent),
165
      theDisplayText(displayText)
aaadceb by David King at 2010-01-19 166
{}
167
168
QlomLayoutItemTextDelegate::~QlomLayoutItemTextDelegate()
169
{}
47c3fbd by Michael Hasselmann at 2010-01-27 170
171
QString QlomLayoutItemTextDelegate::displayText(const QVariant &, const QLocale &) const
172
{
173
    return theDisplayText;
174
}
198616a by Michael Hasselmann at 2010-01-28 175
826407d by Michael Hasselmann at 2010-01-29 176
QlomModelIndexObject::QlomModelIndexObject(const QModelIndex &index, QObject *parent)
177
: QObject(parent),
178
  theIndex(index)
179
{}
180
181
QlomModelIndexObject::~QlomModelIndexObject()
182
{}
183
184
QModelIndex QlomModelIndexObject::index() const
185
{
186
    return theIndex;
187
}
188
189
198616a by Michael Hasselmann at 2010-01-28 190
d92761a by Michael Hasselmann at 2010-01-28 191
QlomButtonDelegate::QlomButtonDelegate(const QString &label, QObject *parent)
192
: QStyledItemDelegate(parent),
193
  theLabel(label)
198616a by Michael Hasselmann at 2010-01-28 194
{}
195
196
QlomButtonDelegate::~QlomButtonDelegate()
197
{}
198
826407d by Michael Hasselmann at 2010-01-29 199
void QlomButtonDelegate::paint(QPainter * /*painter*/, const QStyleOptionViewItem &, const QModelIndex &index) const
198616a by Michael Hasselmann at 2010-01-28 200
{
201
    QAbstractItemView *view = qobject_cast<QAbstractItemView *>(parent());
202
    if (view && !view->indexWidget(index)) {
826407d by Michael Hasselmann at 2010-01-29 203
        QPushButton *button = new QPushButton(theLabel, view);
204
205
        // Bind the index to the button's pressed signal.
206
        QSignalMapper *bindIndex = new QSignalMapper(button);
207
        bindIndex->setMapping(button, new QlomModelIndexObject(index, button));
208
        connect(button, SIGNAL(pressed()),
209
                bindIndex, SLOT(map()));
210
        connect(bindIndex, SIGNAL(mapped(QObject *)),
211
                this, SIGNAL(buttonPressed(QObject *)));
212
213
        view->setIndexWidget(index, button);
198616a by Michael Hasselmann at 2010-01-28 214
    }
215
}
216