00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "koUnitWidgets.moc"
00022
#include <kglobal.h>
00023
#include <klocale.h>
00024
#include <kdebug.h>
00025
#include <qpushbutton.h>
00026
#include <qlayout.h>
00027
00028
#include <koUnit.h>
00029
00030
00031
static KoUnit::Unit getUnit(
const QString &_unitName,
bool* ok )
00032 {
00033
if ( ok )
00034 *ok =
true;
00035
if ( _unitName == QString::fromLatin1(
"mm" ) )
return KoUnit::U_MM;
00036
if ( _unitName == QString::fromLatin1(
"cm" ) )
return KoUnit::U_CM;
00037
if ( _unitName == QString::fromLatin1(
"dm" ) )
return KoUnit::U_DM;
00038
if ( _unitName == QString::fromLatin1(
"in" )
00039 || _unitName == QString::fromLatin1(
"inch") )
return KoUnit::U_INCH;
00040
if ( _unitName == QString::fromLatin1(
"pi" ) )
return KoUnit::U_PI;
00041
if ( _unitName == QString::fromLatin1(
"dd" ) )
return KoUnit::U_DD;
00042
if ( _unitName == QString::fromLatin1(
"cc" ) )
return KoUnit::U_CC;
00043
if ( _unitName == QString::fromLatin1(
"pt" ) )
return KoUnit::U_PT;
00044
if ( ok )
00045 *ok =
false;
00046
return KoUnit::U_PT;
00047 }
00048
00049
00050
static double getUserValue(
double value, KoUnit::Unit unit )
00051 {
00052
switch ( unit ) {
00053
case KoUnit::U_MM:
00054
return MM_TO_POINT( value );
00055
case KoUnit::U_CM:
00056
return CM_TO_POINT( value );
00057
case KoUnit::U_DM:
00058
return DM_TO_POINT( value );
00059
case KoUnit::U_INCH:
00060
return INCH_TO_POINT( value );
00061
case KoUnit::U_PI:
00062
return PI_TO_POINT( value );
00063
case KoUnit::U_DD:
00064
return DD_TO_POINT( value );
00065
case KoUnit::U_CC:
00066
return CC_TO_POINT( value );
00067
case KoUnit::U_PT:
00068
default:
00069
return value;
00070 }
00071 }
00072
00073
00074 KoUnitDoubleValidator::KoUnitDoubleValidator( KoUnitDoubleBase *base,
QObject *parent,
const char *name )
00075 : KDoubleValidator( parent, name ), m_base( base )
00076 {
00077 }
00078
00079 QValidator::State
00080 KoUnitDoubleValidator::validate(
QString &s,
int &pos )
const
00081
{
00082
00083 kdDebug(30004) <<
"KoUnitDoubleValidator::validate : " << s <<
" at " << pos << endl;
00084 QValidator::State result = Acceptable;
00085
00086
QRegExp regexp (
"([ a-zA-Z]+)$");
00087
const int res = regexp.search( s );
00088
00089
if ( res == -1 )
00090 {
00091
00092 kdDebug(30004) <<
"Intermediate (no unit)" << endl;
00093
return Intermediate;
00094 }
00095
00096
00097
const QString number ( s.left( res ).stripWhiteSpace() );
00098
const QString unitName ( regexp.cap( 1 ).stripWhiteSpace().lower() );
00099
00100 kdDebug(30004) <<
"Split:" << number <<
":" << unitName <<
":" << endl;
00101
00102
bool ok =
false;
00103
const double value = KoUnitDoubleBase::toDouble( number, &ok );
00104
double newVal = 0.0;
00105
if( ok )
00106 {
00107 KoUnit::Unit
unit = getUnit( unitName, &ok );
00108
if ( ok )
00109 newVal = getUserValue( value, unit );
00110
else
00111 {
00112
00113 kdDebug(30004) <<
"Intermediate (unknown unit)" << endl;
00114
return Intermediate;
00115 }
00116 }
00117
else
00118 {
00119 kdWarning(30004) <<
"Not a number: " << number << endl;
00120
return Invalid;
00121 }
00122
00123 newVal =
KoUnit::ptToUnit( newVal, m_base->m_unit );
00124
00125 m_base->changeValue( newVal );
00126 s = m_base->getVisibleText( newVal );
00127
00128
return result;
00129 }
00130
00131
QString KoUnitDoubleBase::getVisibleText(
double value )
const
00132
{
00133
#if QT_VERSION > 0x030102
00134
const QString num (
QString(
"%1%2").arg( KGlobal::locale()->formatNumber( value, m_precision ), KoUnit::unitName( m_unit ) ) );
00135
#else
00136
const QString num (
QString(
"%1%2").arg( KGlobal::locale()->formatNumber( value, m_precision ) ).arg( KoUnit::unitName( m_unit ) ) );
00137
#endif
00138
00139 kdDebug(30004) <<
"getVisibleText: " << QString::number( value,
'f', 12 ) <<
" => " << num << endl;
00140
return num;
00141 }
00142
00143
double KoUnitDoubleBase::toDouble(
const QString& str,
bool* ok )
00144 {
00145
QString str2( str );
00146
00147
00148
const QString sep( KGlobal::locale()->thousandsSeparator() );
00149
if ( !sep.isEmpty() )
00150 str2.remove( sep );
00151
const double dbl = KGlobal::locale()->readNumber( str2, ok );
00152
if ( ok )
00153 kdDebug(30004) <<
"toDouble:" << str <<
": => :" << str2 <<
": => " << QString::number( dbl,
'f', 12 ) << endl;
00154
else
00155 kdWarning(30004) <<
"toDouble error:" << str <<
": => :" << str2 <<
":" << endl;
00156
return dbl;
00157 }
00158
00159 KoUnitDoubleSpinBox::KoUnitDoubleSpinBox(
QWidget *parent,
double lower,
double upper,
double step,
double value, KoUnit::Unit unit,
unsigned int precision,
const char *name )
00160 : KDoubleSpinBox( lower, upper, step, value, precision, parent, name ), KoUnitDoubleBase( unit, precision )
00161 {
00162 m_validator =
new KoUnitDoubleValidator(
this,
this );
00163 QSpinBox::setValidator( m_validator );
00164 setAcceptLocalizedNumbers(
true );
00165 setUnit( unit );
00166 }
00167
00168
void
00169 KoUnitDoubleSpinBox::changeValue(
double val )
00170 {
00171 KDoubleSpinBox::setValue( val );
00172 }
00173
00174
void
00175 KoUnitDoubleSpinBox::setUnit( KoUnit::Unit unit )
00176 {
00177
double oldvalue =
KoUnit::ptFromUnit( value(), m_unit );
00178 setMinValue( KoUnit::ptToUnit( KoUnit::ptFromUnit( minValue(), m_unit ), unit ) );
00179 setMaxValue( KoUnit::ptToUnit( KoUnit::ptFromUnit( maxValue(), m_unit ), unit ) );
00180 KDoubleSpinBox::setValue( KoUnit::ptToUnit( oldvalue, unit ) );
00181 m_unit = unit;
00182 setSuffix( KoUnit::unitName( unit ) );
00183 }
00184
00185
00186 KoUnitDoubleLineEdit::KoUnitDoubleLineEdit(
QWidget *parent,
double lower,
double upper,
double value, KoUnit::Unit unit,
unsigned int precision,
const char *name )
00187 : KLineEdit( parent, name ), KoUnitDoubleBase( unit, precision ), m_value( value ), m_lower( lower ), m_upper( upper )
00188 {
00189 setAlignment( Qt::AlignRight );
00190 m_validator =
new KoUnitDoubleValidator(
this,
this );
00191 setValidator( m_validator );
00192 changeValue( value );
00193 }
00194
00195
void
00196 KoUnitDoubleLineEdit::changeValue(
double value )
00197 {
00198 m_value = value < m_lower ? m_lower : ( value > m_upper ? m_upper : value );
00199 setText( getVisibleText( m_value ) );
00200 }
00201
00202
void
00203 KoUnitDoubleLineEdit::setUnit( KoUnit::Unit unit )
00204 {
00205 KoUnit::Unit old = m_unit;
00206 m_unit = unit;
00207 m_lower =
KoUnit::ptToUnit( KoUnit::ptFromUnit( m_lower, old ), unit );
00208 m_upper =
KoUnit::ptToUnit( KoUnit::ptFromUnit( m_upper, old ), unit );
00209 changeValue( KoUnit::ptToUnit( KoUnit::ptFromUnit( m_value, old ), unit ) );
00210 }
00211
00212
bool
00213 KoUnitDoubleLineEdit::eventFilter(
QObject* o,
QEvent* ev )
00214 {
00215
if( ev->type() == QEvent::FocusOut || ev->type() == QEvent::Leave || ev->type() == QEvent::Hide )
00216 {
00217
bool ok;
00218
const double value = KoUnitDoubleBase::toDouble( text(), &ok );
00219 changeValue( value );
00220
return false;
00221 }
00222
else
00223
return QLineEdit::eventFilter( o, ev );
00224 }
00225
00226
00227
00228 KoUnitDoubleComboBox::KoUnitDoubleComboBox(
QWidget *parent,
double lower,
double upper,
double value, KoUnit::Unit unit,
unsigned int precision,
const char *name )
00229 : KComboBox( true, parent, name ), KoUnitDoubleBase( unit, precision ), m_value( value ), m_lower( lower ), m_upper( upper )
00230 {
00231 lineEdit()->setAlignment( Qt::AlignRight );
00232 m_validator =
new KoUnitDoubleValidator(
this,
this );
00233 lineEdit()->setValidator( m_validator );
00234 changeValue( value );
00235 connect(
this, SIGNAL( activated(
int ) ),
this, SLOT( slotActivated(
int ) ) );
00236 }
00237
00238
void
00239 KoUnitDoubleComboBox::changeValue(
double value )
00240 {
00241
QString oldLabel = lineEdit()->text();
00242 updateValue( value );
00243
if( lineEdit()->text() != oldLabel )
00244 emit valueChanged( m_value );
00245 }
00246
00247
void
00248 KoUnitDoubleComboBox::updateValue(
double value )
00249 {
00250 m_value = value < m_lower ? m_lower : ( value > m_upper ? m_upper : value );
00251 lineEdit()->setText( getVisibleText( m_value ) );
00252 }
00253
00254
void
00255 KoUnitDoubleComboBox::insertItem(
double value,
int index )
00256 {
00257 KComboBox::insertItem( getVisibleText( value ), index );
00258 }
00259
00260
void
00261 KoUnitDoubleComboBox::slotActivated(
int index )
00262 {
00263
double oldvalue = m_value;
00264
bool ok;
00265
const double value = KoUnitDoubleBase::toDouble( text( index ), &ok );
00266 m_value = value < m_lower ? m_lower : ( value > m_upper ? m_upper : value );
00267
if( m_value != oldvalue )
00268 emit valueChanged( m_value );
00269 }
00270
00271
void
00272 KoUnitDoubleComboBox::setUnit( KoUnit::Unit unit )
00273 {
00274 KoUnit::Unit old = m_unit;
00275 m_unit = unit;
00276 m_lower =
KoUnit::ptToUnit( KoUnit::ptFromUnit( m_lower, old ), unit );
00277 m_upper =
KoUnit::ptToUnit( KoUnit::ptFromUnit( m_upper, old ), unit );
00278 changeValue( KoUnit::ptToUnit( getUserValue( m_value, old ), unit ) );
00279 }
00280
00281
bool
00282 KoUnitDoubleComboBox::eventFilter(
QObject* o,
QEvent* ev )
00283 {
00284
if( ev->type() == QEvent::FocusOut || ev->type() == QEvent::Leave || ev->type() == QEvent::Hide )
00285 {
00286
bool ok;
00287
const double value = KoUnitDoubleBase::toDouble( lineEdit()->text(), &ok );
00288 changeValue( value );
00289
return false;
00290 }
00291
else
00292
return QComboBox::eventFilter( o, ev );
00293 }
00294
00295 KoUnitDoubleSpinComboBox::KoUnitDoubleSpinComboBox(
QWidget *parent,
double lower,
double upper,
double step,
double value, KoUnit::Unit unit,
unsigned int precision,
const char *name )
00296 :
QWidget( parent ), m_step( step )
00297 {
00298
QGridLayout *layout =
new QGridLayout(
this, 2, 3 );
00299
00300
QPushButton *up =
new QPushButton(
"+",
this );
00301
00302 up->setMaximumHeight( 15 );
00303 up->setMaximumWidth( 15 );
00304 layout->addWidget( up, 0, 0 );
00305 connect( up, SIGNAL( clicked() ),
this, SLOT( slotUpClicked() ) );
00306
00307 QPushButton *down =
new QPushButton(
"-",
this );
00308 down->setMaximumHeight( 15 );
00309 down->setMaximumWidth( 15 );
00310 layout->addWidget( down, 1, 0 );
00311 connect( down, SIGNAL( clicked() ),
this, SLOT( slotDownClicked() ) );
00312
00313 m_combo =
new KoUnitDoubleComboBox(
this, lower, upper, value, unit, precision, name );
00314 connect( m_combo, SIGNAL( valueChanged(
double ) ),
this, SIGNAL( valueChanged(
double ) ) );
00315 layout->addMultiCellWidget( m_combo, 0, 1, 2, 2 );
00316 }
00317
00318
void
00319 KoUnitDoubleSpinComboBox::slotUpClicked()
00320 {
00321 m_combo->changeValue( m_combo->value() + m_step );
00322 }
00323
00324
void
00325 KoUnitDoubleSpinComboBox::slotDownClicked()
00326 {
00327 m_combo->changeValue( m_combo->value() - m_step );
00328 }
00329
00330
void
00331 KoUnitDoubleSpinComboBox::insertItem(
double value,
int index )
00332 {
00333 m_combo->insertItem( value, index );
00334 }
00335
00336
void
00337 KoUnitDoubleSpinComboBox::updateValue(
double value )
00338 {
00339 m_combo->updateValue( value );
00340 }
00341
00342
double
00343 KoUnitDoubleSpinComboBox::value()
const
00344
{
00345
return m_combo->value();
00346 }
00347