Commit 2ed2412c authored by Thomas Zander's avatar Thomas Zander

Make the KoUnitDoubleSpinBox work again.

Cleanup the class by adding a d-pointer, removing all implementation in the header
file.  Merging 3 classes into one and removing some widgets that nobody used
anyway.
Renamed the file to the class name, and follow that rename in all classes.
I made the constructor with the many many arguments deprecated, according to
kde-wide policy of going with small constructors (enhances readability of code)
The validator() has plenty of room for improvement left, btw ;)

svn path=/trunk/koffice/; revision=685709
parent e0f5fd0e
......@@ -25,7 +25,7 @@
#include <kcolorcombo.h>
#include <kdebug.h>
#include "KoUnitWidgets.h"
#include "KoUnitDoubleSpinBox.h"
#include "KoColorSpaceRegistry.h"
#include "KoColorProfile.h"
#include "KoColorSpace.h"
......
......@@ -28,7 +28,7 @@
#include <klocale.h>
#include <kcolorcombo.h>
#include <KoUnitWidgets.h>
#include <KoUnitDoubleSpinBox.h>
#include <KoColorSpace.h>
#include "KoColorSpaceRegistry.h"
#include "KoColorProfile.h"
......
......@@ -35,7 +35,7 @@ set(koguiutils_LIB_SRCS
KoTemplateChooseDia.cpp
KoTemplateCreateDia.cpp
KoToolBox.cpp
KoUnitWidgets.cpp
KoUnitDoubleSpinBox.cpp
KoZoomAction.cpp
KoZoomController.cpp
KoZoomHandler.cpp
......@@ -105,7 +105,7 @@ install(
KoTabulator.h
KoTemplateChooseDia.h
KoTemplateCreateDia.h
KoUnitWidgets.h
KoUnitDoubleSpinBox.h
KoZoomAction.h
KoZoomController.h
KoZoomHandler.h
......
......@@ -144,7 +144,7 @@
<customwidget>
<class>KoUnitDoubleSpinBox</class>
<extends></extends>
<header location="local" >KoUnitWidgets.h</header>
<header location="local" >KoUnitDoubleSpinBox.h</header>
<sizehint>
<width>-1</width>
<height>-1</height>
......
......@@ -29,7 +29,7 @@
#include <QRadioButton>
#include <klocale.h>
#include <KoUnitWidgets.h>
#include <KoUnitDoubleSpinBox.h>
#include <kvbox.h>
......
......@@ -20,7 +20,7 @@
#include <KoPageLayoutColumns.h>
#include <KoPageLayoutDia.h>
#include <KoUnit.h>
#include <KoUnitWidgets.h>
#include <KoUnitDoubleSpinBox.h>
#include <QLabel>
#include <QLayout>
......
......@@ -27,7 +27,7 @@
#include "KoPageLayoutSize.h"
#include "KoPageLayoutHeader.h"
#include <KoUnit.h>
#include "KoUnitWidgets.h"
#include "KoUnitDoubleSpinBox.h"
#include <klocale.h>
#include <kiconloader.h>
......
......@@ -18,7 +18,7 @@
#include <KoPageLayoutHeader.h>
#include <KoPageLayoutHeader.moc>
#include <KoUnitWidgets.h>
#include <KoUnitDoubleSpinBox.h>
#include <QCheckBox>
#include <QHBoxLayout>
......
......@@ -19,7 +19,7 @@
#include "KoPageLayoutSize.h"
#include "KoPageLayoutDia.h"
#include "KoUnitWidgets.h"
#include "KoUnitDoubleSpinBox.h"
#include <KoUnit.h>
#include <klocale.h>
......
......@@ -126,7 +126,7 @@
<customwidget>
<class>KoUnitDoubleSpinBox</class>
<extends>QDoubleSpinBox</extends>
<header>KoUnitWidgets.h</header>
<header>KoUnitDoubleSpinBox.h</header>
</customwidget>
</customwidgets>
<resources/>
......
/* This file is part of the KDE project
Copyright (C) 2002, Rob Buis(buis@kde.org)
Copyright (C) 2004, Nicolas GOUTTE <goutte@kde.org>
Copyright (C) 2007, Thomas Zander <zander@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "KoUnitDoubleSpinBox.h"
#include <kdebug.h>
#include <KGlobal>
#include <KLocale>
class KoUnitDoubleSpinBox::Private {
public:
Private(double low, double up, double step)
: lowerInPoints(low),
upperInPoints(up),
stepInPoints(step),
unit(KoUnit(KoUnit::Point)),
precision(2)
{
}
double lowerInPoints; ///< lowest value in points
double upperInPoints; ///< highest value in points
double stepInPoints; ///< step in points
KoUnit unit;
unsigned int precision;
};
KoUnitDoubleSpinBox::KoUnitDoubleSpinBox( QWidget *parent)
: QDoubleSpinBox( parent ),
d( new Private(-9999, 9999, 1))
{
QDoubleSpinBox::setDecimals( 2 );
//setAcceptLocalizedNumbers( true );
setUnit( KoUnit(KoUnit::Point) );
connect(this, SIGNAL(valueChanged( double )), SLOT(privateValueChanged()));
}
// deprecated;
KoUnitDoubleSpinBox::KoUnitDoubleSpinBox( QWidget *parent,
double lower, double upper,
double step,
double value,
KoUnit unit,
unsigned int precision)
: QDoubleSpinBox( parent ),
d( new Private(lower, upper, step))
{
setMinimum(lower);
setMaximum(upper);
setSingleStep(step);
setValue(value);
setDecimals(precision);
d->unit = KoUnit(KoUnit::Point);
//setAcceptLocalizedNumbers( true );
setUnit( unit );
changeValue( value );
setLineStepPt( step );
connect(this, SIGNAL(valueChanged( double )), SLOT(privateValueChanged()));
}
QValidator::State KoUnitDoubleSpinBox::validate(QString &input, int &pos) const
{
kDebug(30004) << "KoUnitDoubleSpinBox::validate : " << input << " at " << pos << endl;
QRegExp regexp ("([ a-zA-Z]+)$"); // Letters or spaces at end
const int res = input.indexOf( regexp );
if ( res == -1 )
{
// Nothing like an unit? The user is probably editing the unit
kDebug(30004) << "Intermediate (no unit)" << endl;
return QValidator::Intermediate;
}
// ### TODO: are all the QString::trimmed really necessary?
const QString number ( input.left( res ).trimmed() );
const QString unitName ( regexp.cap( 1 ).trimmed().toLower() );
kDebug(30004) << "Split:" << number << ":" << unitName << ":" << endl;
const double value = valueFromText( number );
double newVal = 0.0;
if( value != NAN )
{
bool ok;
KoUnit unit = KoUnit::unit( unitName, &ok );
if ( ok )
newVal = unit.fromUserValue( value );
else
{
// Probably the user is trying to edit the unit
kDebug(30004) << "Intermediate (unknown unit)" << endl;
return QValidator::Intermediate;
}
}
else
{
kWarning(30004) << "Not a number: " << number << endl;
return QValidator::Invalid;
}
newVal = KoUnit::ptToUnit( newVal, d->unit );
//input = textFromValue( newVal ); // don't overwrite for now; the effect is not exactly what I expect...
return QValidator::Acceptable;
}
void KoUnitDoubleSpinBox::changeValue( double val )
{
QDoubleSpinBox::setValue( d->unit.toUserValue( val ) );
// TODO: emit valueChanged ONLY if the value was out-of-bounds
// This will allow the 'user' dialog to set a dirty bool and ensure
// a proper value is getting saved.
}
void KoUnitDoubleSpinBox::privateValueChanged() {
emit valueChangedPt( value () );
}
void KoUnitDoubleSpinBox::setUnit( KoUnit unit )
{
double oldvalue = d->unit.fromUserValue( QDoubleSpinBox::value() );
QDoubleSpinBox::setMinimum( unit.toUserValue( d->lowerInPoints ) );
QDoubleSpinBox::setMaximum( unit.toUserValue( d->upperInPoints ) );
QDoubleSpinBox::setSingleStep( unit.toUserValue( d->stepInPoints ) );
QDoubleSpinBox::setValue( KoUnit::ptToUnit( oldvalue, unit ) );
d->unit = unit;
setSuffix( KoUnit::unitName( unit ).prepend( ' ' ) );
}
double KoUnitDoubleSpinBox::value( ) const
{
return d->unit.fromUserValue( QDoubleSpinBox::value() );
}
void KoUnitDoubleSpinBox::setMinimum( double min )
{
d->lowerInPoints = min;
QDoubleSpinBox::setMinimum( d->unit.toUserValue( min ) );
}
void KoUnitDoubleSpinBox::setMaximum( double max )
{
d->upperInPoints = max;
QDoubleSpinBox::setMaximum( d->unit.toUserValue( max ) );
}
void KoUnitDoubleSpinBox::setLineStep( double step )
{
d->stepInPoints = KoUnit(KoUnit::Point).toUserValue(step);
QDoubleSpinBox::setSingleStep( step );
}
void KoUnitDoubleSpinBox::setLineStepPt( double step )
{
d->stepInPoints = step;
QDoubleSpinBox::setSingleStep( d->unit.toUserValue( step ) );
}
void KoUnitDoubleSpinBox::setMinMaxStep( double min, double max, double step )
{
setMinimum( min );
setMaximum( max );
setLineStepPt( step );
}
QString KoUnitDoubleSpinBox::textFromValue( double value ) const
{
//kDebug(30004) << "textFromValue: " << QString::number( value, 'f', 12 ) << " => " << num << endl;
//const QString num ( QString( "%1%2").arg( KGlobal::locale()->formatNumber( value, d->precision ), KoUnit::unitName( m_unit ) ) );
//const QString num ( QString( "%1").arg( KGlobal::locale()->formatNumber( value, d->precision )) );
return KGlobal::locale()->formatNumber( value, d->precision );
}
double KoUnitDoubleSpinBox::valueFromText( const QString& str ) const
{
QString str2( str );
/* KLocale::readNumber wants the thousand separator exactly at 1000.
But when editing, it might be anywhere. So we need to remove it. */
const QString sep( KGlobal::locale()->thousandsSeparator() );
if ( !sep.isEmpty() )
str2.remove( sep );
str2.remove( KoUnit::unitName( d->unit ) );
bool ok;
const double dbl = KGlobal::locale()->readNumber( str2, &ok );
if ( ok )
kDebug(30004) << "valueFromText:" << str << ": => :" << str2 << ": => " << QString::number( dbl, 'f', 12 ) << endl;
else
kWarning(30004) << "valueFromText error:" << str << ": => :" << str2 << ":" << endl;
return dbl;
}
#include "KoUnitDoubleSpinBox.moc"
/* This file is part of the KDE project
Copyright (C) 2002, Rob Buis(buis@kde.org)
Copyright (C) 2004, Nicolas GOUTTE <goutte@kde.org>
Copyright (C) 2007, Thomas Zander <zander@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
......@@ -18,89 +19,13 @@
* Boston, MA 02110-1301, USA.
*/
#ifndef __KOUNITWIDGETS_H__
#define __KOUNITWIDGETS_H__
#ifndef KOUNITDOUBLESPINBOX_H
#define KOUNITDOUBLESPINBOX_H
#include <knuminput.h>
#include <knumvalidator.h>
#include <klineedit.h>
#include <kcombobox.h>
#include <KoUnit.h>
#include <koguiutils_export.h>
//Added by qt3to4:
#include <QEvent>
// ----------------------------------------------------------------
// Support classes
class KoUnitDoubleBase;
// ### TODO: put it out of the public header file (if possible)
/**
* Validator for the unit widget classes
* \internal
* \since 1.4 (change of behavior)
*/
class KOGUIUTILS_EXPORT KoUnitDoubleValidator : public KDoubleValidator
{
public:
KoUnitDoubleValidator( KoUnitDoubleBase *base, QObject *parent, const char *name = 0 );
virtual QValidator::State validate( QString &, int & ) const;
private:
KoUnitDoubleBase *m_base;
};
/**
* Base for the unit widgets
* \since 1.4 (change of behavior)
*/
class KOGUIUTILS_EXPORT KoUnitDoubleBase
{
public:
KoUnitDoubleBase( KoUnit unit, unsigned int precision ) : m_unit( unit ), m_precision( precision ) {}
virtual ~KoUnitDoubleBase() {}
virtual void changeValue( double ) = 0;
virtual void setUnit( KoUnit ) = 0;
void setValueInUnit( double value, KoUnit unit )
{
changeValue( KoUnit::ptToUnit( unit.fromUserValue( value ), m_unit ) );
}
void setPrecision( unsigned int precision ) { m_precision = precision; }
protected:
friend class KoUnitDoubleValidator;
/**
* Transform the double in a nice text, using locale symbols
* @param value the number as double
* @return the resulting string
*/
QString getVisibleText( double value ) const;
/**
* Transfrom a string into a double, while taking care of locale specific symbols.
* @param str the string to transform into a number
* @param ok true, if the conversion was successful
* @return the value as double
*/
double toDouble( const QString& str, bool* ok ) const;
protected:
KoUnitDoubleValidator *m_validator;
KoUnit m_unit;
unsigned int m_precision;
};
// ----------------------------------------------------------------
// Widget classes
#include "koguiutils_export.h"
#include <KoUnit.h>
#include <QDoubleSpinBox>
/**
* Spin box for double precision numbers with unit display.
......@@ -111,11 +36,10 @@ protected:
* getting a value will not change the value due to conversions.
* The KoDocument class has a unit() method for consistent (document wide) configuration of the
* used unit.
* It is adviced to use a QDoubleSpinBox in QtDesigner and then use the context-menu item: 'Promote to Custom Widget' and use the values: 'classname=KoUnitDoubleSpinBox', 'headerfile=KoUnitWidgets.h'
* It is adviced to use a QDoubleSpinBox in QtDesigner and then use the context-menu item: 'Promote to Custom Widget' and use the values: 'classname=KoUnitDoubleSpinBox', 'headerfile=KoUnitDoubleSpinBox.h'
* This will generate code that uses this spinbox in the correct manner.
* \since 1.4 (change of behavior)
*/
class KOGUIUTILS_EXPORT KoUnitDoubleSpinBox : public KDoubleSpinBox, public KoUnitDoubleBase
class KOGUIUTILS_EXPORT KoUnitDoubleSpinBox : public QDoubleSpinBox
{
Q_OBJECT
public:
......@@ -125,9 +49,8 @@ public:
* This spinbox will have min and max borders of 10000 points and use
* the default unit of points.
* @param parent the parent widget
* @param name unused
*/
explicit KoUnitDoubleSpinBox( QWidget *parent = 0L, const char *name = 0L );
explicit KoUnitDoubleSpinBox( QWidget *parent = 0);
/**
* Create a new spinBox with specified range.
* Use this constructor to set the range, steps and value in points in one go. We don't advice
......@@ -139,10 +62,9 @@ public:
* @param value is the initial value, in points.
* @param unit the displaying unit
* @param precision the amount of digits after the separator. 2 means 0.00 will be shown.
* @param name unused
*/
KoUnitDoubleSpinBox( QWidget *parent, double lower, double upper, double step, double value = 0.0,
KoUnit unit = KoUnit(KoUnit::Point), unsigned int precision = 2, const char *name = 0 );
KDE_DEPRECATED KoUnitDoubleSpinBox( QWidget *parent, double lower, double upper, double step, double value = 0.0,
KoUnit unit = KoUnit(KoUnit::Point), unsigned int precision = 2);
/**
* Set the new value in points which will then be converted to the current unit for display
* @param newValue the new value
......@@ -172,112 +94,36 @@ public:
/// Set minimum, maximum value and the step size (all in points)
void setMinMaxStep( double min, double max, double step );
/// reimplemented from superclass, will forward to KoUnitDoubleValidator
virtual QValidator::State validate(QString &input, int &pos) const;
/**
* Transform the double in a nice text, using locale symbols
* @param value the number as double
* @return the resulting string
*/
virtual QString textFromValue( double value ) const;
/**
* Transfrom a string into a double, while taking care of locale specific symbols.
* @param str the string to transform into a number
* @param ok true, if the conversion was successful
* @return the value as double
*/
virtual double valueFromText( const QString& str ) const;
signals:
/// emitted like valueChanged in the parent, but this one emits the point value
void valueChangedPt( double );
private:
double m_lowerInPoints; ///< lowest value in points
double m_upperInPoints; ///< highest value in points
double m_stepInPoints; ///< step in points
class Private;
Private * const d;
private slots:
// exists to do emits for valueChangedPt
void privateValueChanged();
};
/**
* Line edit for double precision numbers with unit display
* \since 1.4 (change of behavior)
*/
class KOGUIUTILS_EXPORT KoUnitDoubleLineEdit : public KLineEdit, public KoUnitDoubleBase
{
Q_OBJECT
public:
explicit KoUnitDoubleLineEdit( QWidget *parent = 0L, const char *name = 0L );
KoUnitDoubleLineEdit( QWidget *parent, double lower, double upper, double value = 0.0, KoUnit unit = KoUnit(KoUnit::Point), unsigned int precision = 2, const char *name = 0 );
virtual void changeValue( double );
virtual void setUnit( KoUnit );
/// @return the current value, converted in points
double value( ) const;
protected:
bool eventFilter( QObject* obj, QEvent* ev );
private:
double m_value;
double m_lower;
double m_upper;
double m_lowerInPoints; ///< lowest value in points
double m_upperInPoints; ///< highest value in points
};
/**
* Combo box for double precision numbers with unit display
* \since 1.4 (change of behavior)
*/
class KOGUIUTILS_EXPORT KoUnitDoubleComboBox : public KComboBox, public KoUnitDoubleBase
{
Q_OBJECT
public:
explicit KoUnitDoubleComboBox( QWidget *parent = 0L, const char *name = 0L );
KoUnitDoubleComboBox( QWidget *parent, double lower, double upper, double value = 0.0, KoUnit unit = KoUnit(KoUnit::Point), unsigned int precision = 2, const char *name = 0 );
virtual void changeValue( double );
void updateValue( double );
virtual void setUnit( KoUnit );
/// @return the current value, converted in points
double value( ) const;
void insertItem( double, int index = -1 );
protected:
bool eventFilter( QObject* obj, QEvent* ev );
signals:
void valueChanged(double);
private slots:
void slotActivated( int );
protected:
double m_value;
double m_lower;
double m_upper;
double m_lowerInPoints; ///< lowest value in points
double m_upperInPoints; ///< highest value in points
};
/**
* Combo box (with spin control) for double precision numbers with unit display
* \since 1.4 (change of behavior)
*/
class KOGUIUTILS_EXPORT KoUnitDoubleSpinComboBox : public QWidget
{
Q_OBJECT
public:
explicit KoUnitDoubleSpinComboBox( QWidget *parent = 0L, const char *name = 0L );
KoUnitDoubleSpinComboBox( QWidget *parent, double lower, double upper, double step, double value = 0.0, KoUnit unit = KoUnit(KoUnit::Point), unsigned int precision = 2, const char *name = 0 );
void insertItem( double, int index = -1 );
void updateValue( double );
/// @return the current value, converted in points
double value( ) const;
signals:
void valueChanged(double);
private slots:
void slotUpClicked();
void slotDownClicked();
private:
KoUnitDoubleComboBox *m_combo;
double m_step;
};
#endif
This diff is collapsed.
......@@ -36,7 +36,7 @@
#include <kiconloader.h>
#include <klocale.h>
#include <KoUnitWidgets.h>
#include <KoUnitDoubleSpinBox.h>
#include <KoGlobal.h>
class KoLineWidthAction::KoLineWidthActionPrivate
......
......@@ -129,7 +129,7 @@
<customwidget>
<class>KoUnitDoubleSpinBox</class>
<extends>QDoubleSpinBox</extends>
<header>KoUnitWidgets.h</header>
<header>KoUnitDoubleSpinBox.h</header>
</customwidget>
</customwidgets>
<includes>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment