lib

spinbox.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
00003    Copyright (C) 2004  Alexander Dymo <cloudtemple@mskat.net>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "spinbox.h"
00022 
00023 #include "property.h"
00024 
00025 #include <qlayout.h>
00026 #include <qobjectlist.h>
00027 #include <qvariant.h>
00028 #include <qpainter.h>
00029 #include <qlineedit.h>
00030 
00031 #include <kglobal.h>
00032 #include <klocale.h>
00033 
00034 using namespace KoProperty;
00035 
00036 IntSpinBox::IntSpinBox(int lower, int upper, int step, int value, int base, IntEdit *parent, const char *name)
00037 : KIntSpinBox(lower, upper, step, value, base, parent, name)
00038 {
00039     editor()->setAlignment(Qt::AlignLeft);
00040     installEventFilter(editor());
00041     installEventFilter(this);
00042     QObjectList *spinwidgets = queryList( "QSpinWidget", 0, false, true );
00043     QSpinWidget* spin = static_cast<QSpinWidget*>(spinwidgets->first());
00044     if (spin)
00045         spin->installEventFilter(this);
00046     delete spinwidgets;
00047 }
00048 
00049 void IntSpinBox::setValue(const QVariant &value)
00050 {
00051     if (dynamic_cast<IntEdit*>(parentWidget()) && dynamic_cast<IntEdit*>(parentWidget())->isReadOnly())
00052         return;
00053     if (value.isNull())
00054         editor()->clear();
00055     else
00056         KIntSpinBox::setValue(value.toInt());
00057 }
00058 
00059 bool
00060 IntSpinBox::eventFilter(QObject *o, QEvent *e)
00061 {
00062     if(o == editor())
00063     {
00064         if(e->type() == QEvent::KeyPress)
00065         {
00066             QKeyEvent* ev = static_cast<QKeyEvent*>(e);
00067             if((ev->key()==Key_Up || ev->key()==Key_Down) && ev->state() !=ControlButton)
00068             {
00069                 parentWidget()->eventFilter(o, e);
00070                 return true;
00071             }
00072         }
00073     }
00074     if ((o == editor() || o == this || o->parent() == this) 
00075         && e->type() == QEvent::Wheel && static_cast<IntEdit*>(parentWidget())->isReadOnly())
00076     {
00077         return true; //avoid value changes for read-only widget
00078     }
00079 
00080     return KIntSpinBox::eventFilter(o, e);
00081 }
00082 
00083 
00085 
00086 IntEdit::IntEdit(Property *property, QWidget *parent, const char *name)
00087  : Widget(property, parent, name)
00088 {
00089     QVariant minVal( property ? property->option("min") : 0 );
00090     QVariant maxVal( property ? property->option("max") : QVariant() );
00091     QVariant minValueText( property ? property->option("minValueText") : QVariant() );
00092     if (minVal.isNull())
00093         minVal = 0;
00094     if (maxVal.isNull())
00095         maxVal = INT_MAX;
00096 
00097     m_edit = new IntSpinBox(minVal.toInt(), maxVal.toInt(), 1, 0, 10, this);
00098     if (!minValueText.isNull())
00099         m_edit->setSpecialValueText(minValueText.toString());
00100     m_edit->setMinimumHeight(5);
00101     setEditor(m_edit);
00102 
00103     setLeavesTheSpaceForRevertButton(true);
00104     setFocusWidget(m_edit);
00105     connect(m_edit, SIGNAL(valueChanged(int)), this, SLOT(slotValueChanged(int)));
00106 }
00107 
00108 IntEdit::~IntEdit()
00109 {}
00110 
00111 QVariant
00112 IntEdit::value() const
00113 {
00114     if (m_edit->cleanText().isEmpty())
00115         return QVariant();
00116     return m_edit->value();
00117 }
00118 
00119 void
00120 IntEdit::setValue(const QVariant &value, bool emitChange)
00121 {
00122     m_edit->blockSignals(true);
00123     m_edit->setValue(value);
00124     updateSpinWidgets();
00125     m_edit->blockSignals(false);
00126     if (emitChange)
00127         emit valueChanged(this);
00128 }
00129 
00130 void
00131 IntEdit::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value)
00132 {
00133     QString valueText = value.toString();
00134     if (property() && property()->hasOptions()) {
00135         //replace min value with minValueText if defined
00136         QVariant minValue( property()->option("min") );
00137         QVariant minValueText( property()->option("minValueText") );
00138         if (!minValue.isNull() && !minValueText.isNull() && minValue.toInt() == value.toInt()) {
00139             valueText = minValueText.toString();
00140         }
00141     }
00142 
00143     Widget::drawViewer(p, cg, r, valueText);
00144 //  p->eraseRect(r);
00145 //  p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, valueText);
00146 }
00147 
00148 void
00149 IntEdit::slotValueChanged(int)
00150 {
00151     emit valueChanged(this);
00152 }
00153 
00154 void
00155 IntEdit::updateSpinWidgets()
00156 {
00157     QObjectList *spinwidgets = queryList( "QSpinWidget", 0, false, true );
00158     QSpinWidget* spin = static_cast<QSpinWidget*>(spinwidgets->first());
00159     if (spin) {
00160         spin->setUpEnabled(!isReadOnly());
00161         spin->setDownEnabled(!isReadOnly());
00162     }
00163     delete spinwidgets;
00164 }
00165 
00166 void
00167 IntEdit::setReadOnlyInternal(bool readOnly)
00168 {
00169     //disable editor and spin widget
00170     m_edit->editor()->setReadOnly(readOnly);
00171     updateSpinWidgets();
00172     if (readOnly)
00173         setLeavesTheSpaceForRevertButton(false);
00174 }
00175 
00178 
00179 DoubleSpinBox::DoubleSpinBox (double lower, double upper, double step, double value, int precision, DoubleEdit *parent)
00180 : KDoubleSpinBox(lower, upper, step, value, precision, parent)
00181 {
00182     editor()->setAlignment(Qt::AlignLeft);
00183     installEventFilter(editor());
00184     installEventFilter(this);
00185     QObjectList *spinwidgets = queryList( "QSpinWidget", 0, false, true );
00186     QSpinWidget* spin = static_cast<QSpinWidget*>(spinwidgets->first());
00187     if (spin)
00188         spin->installEventFilter(this);
00189     delete spinwidgets;
00190 }
00191 
00192 bool
00193 DoubleSpinBox::eventFilter(QObject *o, QEvent *e)
00194 {
00195     if(o == editor())
00196     {
00197         if(e->type() == QEvent::KeyPress)
00198         {
00199             QKeyEvent* ev = static_cast<QKeyEvent*>(e);
00200             if((ev->key()==Key_Up || ev->key()==Key_Down) && ev->state()!=ControlButton)
00201             {
00202                 parentWidget()->eventFilter(o, e);
00203                 return true;
00204             }
00205         }
00206     }
00207     if ((o == editor() || o == this || o->parent() == this) 
00208         && e->type() == QEvent::Wheel && static_cast<IntEdit*>(parentWidget())->isReadOnly())
00209     {
00210         return true; //avoid value changes for read-only widget
00211     }
00212 
00213     return KDoubleSpinBox::eventFilter(o, e);
00214 }
00215 
00216 
00217 void DoubleSpinBox::setValue( const QVariant& value )
00218 {
00219     if (dynamic_cast<DoubleEdit*>(parentWidget()) && dynamic_cast<DoubleEdit*>(parentWidget())->isReadOnly())
00220         return;
00221     if (value.isNull())
00222         editor()->clear();
00223     else
00224         KDoubleSpinBox::setValue(value.toDouble());
00225 }
00226 
00228 
00229 DoubleEdit::DoubleEdit(Property *property, QWidget *parent, const char *name)
00230  : Widget(property, parent, name)
00231 {
00232     QVariant minVal( property ? property->option("min") : 0 );
00233     QVariant maxVal( property ? property->option("max") : QVariant() );
00234     QVariant step( property ? property->option("step") : QVariant());
00235     QVariant precision( property ? property->option("precision") : QVariant());
00236     QVariant minValueText( property ? property->option("minValueText") : QVariant() );
00237     if (minVal.isNull())
00238         minVal = 0;
00239     if (maxVal.isNull())
00240         maxVal = (double)(INT_MAX/100);
00241     if(step.isNull())
00242         step = 0.1;
00243     if(precision.isNull())
00244         precision = 2;
00245 
00246     m_edit = new DoubleSpinBox(minVal.toDouble(), maxVal.toDouble(), step.toDouble(),
00247          0, precision.toInt(), this);
00248     if (!minValueText.isNull())
00249         m_edit->setSpecialValueText(minValueText.toString());
00250     m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
00251     m_edit->setMinimumHeight(5);
00252     setEditor(m_edit);
00253 
00254     setLeavesTheSpaceForRevertButton(true);
00255     setFocusWidget(m_edit);
00256     connect(m_edit, SIGNAL(valueChanged(double)), this, SLOT(slotValueChanged(double)));
00257 }
00258 
00259 DoubleEdit::~DoubleEdit()
00260 {}
00261 
00262 QVariant
00263 DoubleEdit::value() const
00264 {
00265     if (m_edit->cleanText().isEmpty())
00266         return QVariant();
00267     return m_edit->value();
00268 }
00269 
00270 void
00271 DoubleEdit::setValue(const QVariant &value, bool emitChange)
00272 {
00273     m_edit->blockSignals(true);
00274     m_edit->setValue(value);
00275     updateSpinWidgets();
00276     m_edit->blockSignals(false);
00277     if (emitChange)
00278         emit valueChanged(this);
00279 }
00280 
00281 void
00282 DoubleEdit::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value)
00283 {
00284     QString valueText;
00285     if (property() && property()->hasOptions()) {
00286         //replace min value with minValueText if defined
00287         QVariant minValue( property()->option("min") );
00288         QVariant minValueText( property()->option("minValueText") );
00289         if (!minValue.isNull() && !minValueText.isNull() && minValue.toString().toDouble() == value.toString().toDouble()) {
00290             valueText = minValueText.toString();
00291         }
00292     }
00293     if (valueText.isEmpty())
00294         valueText = QString(value.toString()).replace('.', KGlobal::locale()->decimalSymbol());
00295 
00296     Widget::drawViewer(p, cg, r, valueText);
00297 //  p->eraseRect(r);
00298 //  p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, valueText);
00299 }
00300 
00301 void
00302 DoubleEdit::slotValueChanged(double)
00303 {
00304     emit valueChanged(this);
00305 }
00306 
00307 void
00308 DoubleEdit::updateSpinWidgets()
00309 {
00310     QObjectList *spinwidgets = queryList( "QSpinWidget", 0, false, true );
00311     QSpinWidget* spin = static_cast<QSpinWidget*>(spinwidgets->first());
00312     if (spin) {
00313         spin->setUpEnabled(!isReadOnly());
00314         spin->setDownEnabled(!isReadOnly());
00315     }
00316     delete spinwidgets;
00317 }
00318 
00319 void
00320 DoubleEdit::setReadOnlyInternal(bool readOnly)
00321 {
00322     //disable editor and spin widget
00323     m_edit->editor()->setReadOnly(readOnly);
00324     updateSpinWidgets();
00325     if (readOnly)
00326         setLeavesTheSpaceForRevertButton(false);
00327 }
00328 
00329 #include "spinbox.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys