~ubuntu-branches/ubuntu/precise/koffice/precise

« back to all changes in this revision

Viewing changes to kexi/plugins/forms/widgets/kexidblineedit.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2010-09-21 15:36:35 UTC
  • mfrom: (1.4.1 upstream) (60.2.11 maverick)
  • Revision ID: james.westby@ubuntu.com-20100921153635-6tejqkiro2u21ydi
Tags: 1:2.2.2-0ubuntu3
Add kubuntu_03_fix-crash-on-closing-sqlite-connection-2.2.2.diff and
kubuntu_04_support-large-memo-values-for-msaccess-2.2.2.diff as
recommended by upstream http://kexi-
project.org/wiki/wikiview/index.php@Kexi2.2_Patches.html#sqlite_stab
ility

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* This file is part of the KDE project
 
2
   Copyright (C) 2005 Cedric Pasteur <cedric.pasteur@free.fr>
 
3
   Copyright (C) 2004-2009 Jarosław Staniek <staniek@kde.org>
 
4
 
 
5
   This program is free software; you can redistribute it and/or
 
6
   modify it under the terms of the GNU Library General Public
 
7
   License as published by the Free Software Foundation; either
 
8
   version 2 of the License, or (at your option) any later version.
 
9
 
 
10
   This program 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 GNU
 
13
   Library General Public License for more details.
 
14
 
 
15
   You should have received a copy of the GNU Library General Public License
 
16
   along with this program; see the file COPYING.  If not, write to
 
17
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
18
 * Boston, MA 02110-1301, USA.
 
19
*/
 
20
 
 
21
#include "kexidblineedit.h"
 
22
#include "kexidbautofield.h"
 
23
 
 
24
#include <KDebug>
 
25
#include <KNumInput>
 
26
#include <KDateTable>
 
27
#include <KIconEffect>
 
28
 
 
29
#include <QMenu>
 
30
#include <QPainter>
 
31
#include <QEvent>
 
32
#include <QPaintEvent>
 
33
#include <QStyle>
 
34
#include <QStyleOption>
 
35
 
 
36
#include <kexiutils/utils.h>
 
37
#include <kexiutils/styleproxy.h>
 
38
#include <kexidb/queryschema.h>
 
39
#include <kexidb/fieldvalidator.h>
 
40
#include <kexiutils/utils.h>
 
41
 
 
42
//! @todo reenable as an app aption
 
43
//#define USE_KLineEdit_setReadOnly
 
44
 
 
45
//! @internal A validator used for read only flag to disable editing
 
46
class KexiDBLineEdit_ReadOnlyValidator : public QValidator
 
47
{
 
48
public:
 
49
    KexiDBLineEdit_ReadOnlyValidator(QObject * parent)
 
50
            : QValidator(parent) {
 
51
    }
 
52
    ~KexiDBLineEdit_ReadOnlyValidator() {}
 
53
    virtual State validate(QString &, int &) const {
 
54
        return Invalid;
 
55
    }
 
56
};
 
57
 
 
58
//-----
 
59
 
 
60
//! A style proxy overriding KexiDBLineEdit style
 
61
class KexiDBLineEditStyle : public KexiUtils::StyleProxy
 
62
{
 
63
public:
 
64
    KexiDBLineEditStyle(QStyle* parentStyle) : KexiUtils::StyleProxy(parentStyle), indent(0)
 
65
    {
 
66
    }
 
67
 
 
68
    void setIndent(int indent) {
 
69
        this->indent = indent;
 
70
    }
 
71
 
 
72
    QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
 
73
    {
 
74
        const KFormDesigner::FormWidgetInterface *formWidget = dynamic_cast<const KFormDesigner::FormWidgetInterface*>(widget);
 
75
        if (formWidget->designMode()) {
 
76
            const KexiFormDataItemInterface *dataItemIface = dynamic_cast<const KexiFormDataItemInterface*>(widget);
 
77
            if (dataItemIface && !dataItemIface->dataSource().isEmpty() && !formWidget->editingMode()) {
 
78
                if (element == SE_LineEditContents) {
 
79
                    QRect rect = KexiUtils::StyleProxy::subElementRect(SE_LineEditContents, option, widget);
 
80
                    if (option->direction == Qt::LeftToRight)
 
81
                        return rect.adjusted(indent, 0, 0, 0);
 
82
                    else
 
83
                        return rect.adjusted(0, 0, -indent, 0);
 
84
                }
 
85
            }
 
86
        }
 
87
        return KexiUtils::StyleProxy::subElementRect(element, option, widget);
 
88
    }
 
89
    int indent;
 
90
};
 
91
 
 
92
//-----
 
93
 
 
94
KexiDBLineEdit::KexiDBLineEdit(QWidget *parent)
 
95
        : KLineEdit(parent)
 
96
        , KexiDBTextWidgetInterface()
 
97
        , KexiFormDataItemInterface()
 
98
        , m_readWriteValidator(0)
 
99
        , m_menuExtender(this, this)
 
100
        , m_internalReadOnly(false)
 
101
        , m_slotTextChanged_enabled(true)
 
102
{
 
103
#ifdef USE_KLineEdit_setReadOnly
 
104
//! @todo reenable as an app aption
 
105
    QPalette p(widget->palette());
 
106
    p.setColor(KexiFormUtils::lighterGrayBackgroundColor(palette()));
 
107
    widget->setPalette(p);
 
108
#endif
 
109
 
 
110
    QFont tmpFont;
 
111
    tmpFont.setPointSize(KGlobalSettings::smallestReadableFont().pointSize());
 
112
    setMinimumHeight(QFontMetrics(tmpFont).height() + 6);
 
113
    connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged(const QString&)));
 
114
 
 
115
    KexiDBLineEditStyle *ks = new KexiDBLineEditStyle(style());
 
116
    ks->setParent(this);
 
117
    ks->setIndent(KexiFormUtils::dataSourceTagIcon().width());
 
118
    setStyle( ks );
 
119
}
 
120
 
 
121
KexiDBLineEdit::~KexiDBLineEdit()
 
122
{
 
123
}
 
124
 
 
125
/*
 
126
void FormWidgetInterface::setDesignMode(bool design)
 
127
{
 
128
    FormWidgetInterface::setDesignMode(design);
 
129
    setCursor(design ? QCursor(Qt::ArrowCursor) : QCursor());
 
130
}*/
 
131
 
 
132
void KexiDBLineEdit::setInvalidState(const QString& displayText)
 
133
{
 
134
    KLineEdit::setReadOnly(true);
 
135
//! @todo move this to KexiDataItemInterface::setInvalidStateInternal() ?
 
136
    if (focusPolicy() & Qt::TabFocus)
 
137
        setFocusPolicy(Qt::ClickFocus);
 
138
    setText(displayText);
 
139
}
 
140
 
 
141
void KexiDBLineEdit::setValueInternal(const QVariant& add, bool removeOld)
 
142
{
 
143
    m_slotTextChanged_enabled = false;
 
144
    setText( m_textFormatter.valueToText(removeOld ? QVariant() : m_origValue, add.toString()) );
 
145
    setCursorPosition(0); //ok?
 
146
    m_slotTextChanged_enabled = true;
 
147
}
 
148
 
 
149
QVariant KexiDBLineEdit::value()
 
150
{
 
151
    return m_textFormatter.textToValue( text() );
 
152
}
 
153
 
 
154
void KexiDBLineEdit::slotTextChanged(const QString&)
 
155
{
 
156
    if (!m_slotTextChanged_enabled)
 
157
        return;
 
158
    signalValueChanged();
 
159
}
 
160
 
 
161
bool KexiDBLineEdit::valueIsNull()
 
162
{
 
163
    return valueIsEmpty(); //ok??? text().isNull();
 
164
}
 
165
 
 
166
bool KexiDBLineEdit::valueIsEmpty()
 
167
{
 
168
    return m_textFormatter.valueIsEmpty( text() );
 
169
}
 
170
 
 
171
bool KexiDBLineEdit::valueIsValid()
 
172
{
 
173
    return m_textFormatter.valueIsValid( text() );
 
174
}
 
175
 
 
176
bool KexiDBLineEdit::isReadOnly() const
 
177
{
 
178
    return m_internalReadOnly;
 
179
}
 
180
 
 
181
void KexiDBLineEdit::setReadOnly(bool readOnly)
 
182
{
 
183
#ifdef USE_KLineEdit_setReadOnly
 
184
//! @todo reenable as an app aption
 
185
    return KLineEdit::setReadOnly(readOnly);
 
186
#else
 
187
    m_internalReadOnly = readOnly;
 
188
    if (m_internalReadOnly) {
 
189
        if (m_readWriteValidator)
 
190
            disconnect(m_readWriteValidator, SIGNAL(destroyed(QObject*)),
 
191
                       this, SLOT(slotReadWriteValidatorDestroyed(QObject*)));
 
192
        m_readWriteValidator = validator();
 
193
        if (m_readWriteValidator)
 
194
            connect(m_readWriteValidator, SIGNAL(destroyed(QObject*)),
 
195
                    this, SLOT(slotReadWriteValidatorDestroyed(QObject*)));
 
196
        if (!m_readOnlyValidator)
 
197
            m_readOnlyValidator = new KexiDBLineEdit_ReadOnlyValidator(this);
 
198
        setValidator(m_readOnlyValidator);
 
199
    } else {
 
200
        //revert to r/w validator
 
201
        setValidator(m_readWriteValidator);
 
202
    }
 
203
    m_menuExtender.updatePopupMenuActions();
 
204
#endif
 
205
}
 
206
 
 
207
void KexiDBLineEdit::slotReadWriteValidatorDestroyed(QObject*)
 
208
{
 
209
    m_readWriteValidator = 0;
 
210
}
 
211
 
 
212
QMenu * KexiDBLineEdit::createPopupMenu()
 
213
{
 
214
    QMenu *contextMenu = KLineEdit::createStandardContextMenu();
 
215
    m_menuExtender.createTitle(contextMenu);
 
216
    return contextMenu;
 
217
}
 
218
 
 
219
 
 
220
QWidget* KexiDBLineEdit::widget()
 
221
{
 
222
    return this;
 
223
}
 
224
 
 
225
bool KexiDBLineEdit::cursorAtStart()
 
226
{
 
227
    return cursorPosition() == 0;
 
228
}
 
229
 
 
230
bool KexiDBLineEdit::cursorAtEnd()
 
231
{
 
232
    return cursorPosition() == (int)text().length();
 
233
}
 
234
 
 
235
void KexiDBLineEdit::clear()
 
236
{
 
237
    if (!m_internalReadOnly)
 
238
        KLineEdit::clear();
 
239
}
 
240
 
 
241
void KexiDBLineEdit::setColumnInfo(KexiDB::QueryColumnInfo* cinfo)
 
242
{
 
243
    KexiFormDataItemInterface::setColumnInfo(cinfo);
 
244
    m_textFormatter.setField( cinfo ? cinfo->field : 0 );
 
245
 
 
246
    if (!cinfo)
 
247
        return;
 
248
 
 
249
//! @todo handle input mask (via QLineEdit::setInputMask()) using a special KexiDB::FieldInputMask class
 
250
    setValidator(new KexiDB::FieldValidator(*cinfo->field, this));
 
251
 
 
252
    const QString inputMask(m_textFormatter.inputMask());
 
253
    if (!inputMask.isEmpty())
 
254
        setInputMask(inputMask);
 
255
 
 
256
    KexiDBTextWidgetInterface::setColumnInfo(cinfo, this);
 
257
}
 
258
 
 
259
/*todo
 
260
void KexiDBLineEdit::paint( QPainter *p )
 
261
{
 
262
  KexiDBTextWidgetInterface::paint( this, &p, text().isEmpty(), alignment(), hasFocus() );
 
263
}*/
 
264
 
 
265
void KexiDBLineEdit::paintEvent(QPaintEvent *pe)
 
266
{
 
267
    KLineEdit::paintEvent(pe);
 
268
    KFormDesigner::FormWidgetInterface *formWidget = dynamic_cast<KFormDesigner::FormWidgetInterface*>(this);
 
269
    if (formWidget->designMode()) {
 
270
        KexiFormDataItemInterface *dataItemIface = dynamic_cast<KexiFormDataItemInterface*>(this);
 
271
        if (dataItemIface && !dataItemIface->dataSource().isEmpty() && !formWidget->editingMode()) {
 
272
            // draw "data source tag" icon
 
273
            QPainter p(this);
 
274
            QStyleOptionFrameV2 option;
 
275
            initStyleOption(&option);
 
276
            
 
277
            int leftMargin, topMargin, rightMargin, bottomMargin;
 
278
            getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin);
 
279
            QRect r( style()->subElementRect(QStyle::SE_LineEditContents, &option, this) );
 
280
            r.setX(r.x() + leftMargin);
 
281
            r.setY(r.y() + topMargin);
 
282
            r.setRight(r.right() - rightMargin);
 
283
            r.setBottom(r.bottom() - bottomMargin);
 
284
            QPixmap dataSourceTagIcon;
 
285
            int x;
 
286
            if (layoutDirection() == Qt::LeftToRight) {
 
287
                dataSourceTagIcon = KexiFormUtils::dataSourceTagIcon();
 
288
                x = r.left() - dataSourceTagIcon.width() + 2;
 
289
            }
 
290
            else {
 
291
                dataSourceTagIcon = KexiFormUtils::dataSourceRTLTagIcon();
 
292
                x = r.right() - 2;
 
293
            }
 
294
            p.drawPixmap(
 
295
                x, r.top() + (r.height() - dataSourceTagIcon.height()) / 2,
 
296
                dataSourceTagIcon
 
297
            );
 
298
        }
 
299
    }
 
300
}
 
301
 
 
302
bool KexiDBLineEdit::event(QEvent * e)
 
303
{
 
304
    const bool ret = KLineEdit::event(e);
 
305
    KexiDBTextWidgetInterface::event(e, this, text().isEmpty());
 
306
    if (e->type() == QEvent::FocusOut) {
 
307
        QFocusEvent *fe = static_cast<QFocusEvent *>(e);
 
308
        if (fe->reason() == Qt::TabFocusReason || fe->reason() == Qt::BacktabFocusReason) {
 
309
            //display aligned to left after loosing the focus (only if this is tab/backtab event)
 
310
//! @todo add option to set cursor at the beginning
 
311
            setCursorPosition(0); //ok?
 
312
        }
 
313
    }
 
314
    return ret;
 
315
}
 
316
 
 
317
bool KexiDBLineEdit::appendStretchRequired(KexiDBAutoField* autoField) const
 
318
{
 
319
    return KexiDBAutoField::Top == autoField->labelPosition();
 
320
}
 
321
 
 
322
void KexiDBLineEdit::handleAction(const QString& actionName)
 
323
{
 
324
    if (actionName == "edit_copy") {
 
325
        copy();
 
326
    } else if (actionName == "edit_paste") {
 
327
        paste();
 
328
    } else if (actionName == "edit_cut") {
 
329
        cut();
 
330
    }
 
331
    //! @todo ?
 
332
}
 
333
 
 
334
void KexiDBLineEdit::setDisplayDefaultValue(QWidget *widget, bool displayDefaultValue)
 
335
{
 
336
    KexiFormDataItemInterface::setDisplayDefaultValue(widget, displayDefaultValue);
 
337
    // initialize display parameters for default / entered value
 
338
    KexiDisplayUtils::DisplayParameters * const params = displayDefaultValue
 
339
        ? m_displayParametersForDefaultValue : m_displayParametersForEnteredValue;
 
340
    setFont(params->font);
 
341
    QPalette pal(palette());
 
342
    pal.setColor(QPalette::Active, QColorGroup::Text, params->textColor);
 
343
    setPalette(pal);
 
344
}
 
345
 
 
346
void KexiDBLineEdit::undo()
 
347
{
 
348
    cancelEditor();
 
349
}
 
350
 
 
351
void KexiDBLineEdit::moveCursorToEnd()
 
352
{
 
353
    KLineEdit::end(false/*!mark*/);
 
354
}
 
355
 
 
356
void KexiDBLineEdit::moveCursorToStart()
 
357
{
 
358
    KLineEdit::home(false/*!mark*/);
 
359
}
 
360
 
 
361
void KexiDBLineEdit::selectAll()
 
362
{
 
363
    KLineEdit::selectAll();
 
364
}
 
365
 
 
366
bool KexiDBLineEdit::keyPressed(QKeyEvent *ke)
 
367
{
 
368
    Q_UNUSED(ke);
 
369
    return false;
 
370
}
 
371
 
 
372
void KexiDBLineEdit::updateTextForDataSource()
 
373
{
 
374
    if (!designMode())
 
375
        return;
 
376
    setText(dataSource());
 
377
}
 
378
 
 
379
void KexiDBLineEdit::setDataSource(const QString &ds)
 
380
{
 
381
    KexiFormDataItemInterface::setDataSource(ds);
 
382
    updateTextForDataSource();
 
383
}
 
384
 
 
385
void KexiDBLineEdit::setDataSourcePartClass(const QString &partClass)
 
386
{
 
387
    KexiFormDataItemInterface::setDataSourcePartClass(partClass);
 
388
    updateTextForDataSource();
 
389
}
 
390
 
 
391
#include "kexidblineedit.moc"